Skip to content

Commit

Permalink
prepare sxc.data and sxc.query
Browse files Browse the repository at this point in the history
  • Loading branch information
iJungleboy committed Dec 4, 2021
1 parent 6b14ff1 commit a8519dd
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 146 deletions.
4 changes: 3 additions & 1 deletion projects/$2sxc/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
"typescript.tsdk": "node_modules\\typescript\\lib",
"editor.tabSize": 2,
"editor.detectIndentation": false
}
30 changes: 30 additions & 0 deletions projects/$2sxc/src/sxc-instance/data/sxc-data-query-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SxcInstance } from "..";
import { SxcWebApi } from "../web-api/sxc-web-api";

/**
* Base class doing common checks
*/
export class SxcDataQueryBase {
protected readonly webApi: SxcWebApi;
/**
* Creates an instance of SxcData.
* @param {SxcInstance} sxc
* @param {string} name the content-type name
* @memberof SxcData
*/
constructor(
sxc: SxcInstance,
readonly name: string,
nameInError: string
) {
this.webApi = sxc.webApi;

// Fail early if something is wrong
nameInError += ' name ';
if (name == null) throw nameInError + 'is empty';
if (name.indexOf("/") != -1 || name.indexOf("\\") != -1) throw nameInError + 'has slashes - not allowed';
if (name.indexOf("?") != -1) throw nameInError + 'has "?" - not allowed';
}

}

75 changes: 60 additions & 15 deletions projects/$2sxc/src/sxc-instance/data/sxc-data.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,68 @@
import { SxcInstance } from "..";
import { SxcWebApi } from "../web-api/sxc-web-api";
import { SxcDataQueryBase } from './sxc-data-query-base';

export class SxcData {
private readonly webApi: SxcWebApi;

constructor(
private readonly sxc: SxcInstance,
readonly contentType: string
) {
this.webApi = sxc.webApi;
/**
* Instance Data accessor to get (and in future create/update) data items/entities
*/
export class SxcData<T = unknown> extends SxcDataQueryBase {
/**
* Creates an instance of SxcData.
* @param {SxcInstance} sxc
* @param {string} name the content-type name
* @memberof SxcData
*/
constructor(sxc: SxcInstance, readonly name: string) {
super(sxc, name, 'ContentType');
}

if (contentType == null) throw "contentType is empty";
if (contentType.indexOf("/") != -1 || contentType.indexOf("\\") != -1)
throw "contentType has slashes - not allowed";
/**
* Get all items of this type.
*/
getAll(): Promise<T[]> {
return this.getInternal<T[]>();
}

get<T = any>(ids?: string | number, params?: string | Record<string, any>): Promise<T> {
let path = "app/auto/content/" + this.contentType;
if (ids && (typeof ids === 'string' || typeof ids === 'number')) path += "/" + ids;

/**
* Get the specific item with the ID. It will return null if not found
*/
getOne(id: number): Promise<T> | null {
return this.getInternal<T>(id);
};

// Future
private getMany(criteria: Record<string, unknown>, fields: Array<string>): Promise<T[]> {
throw 'not implemented - probably v13.5 or something';
}


/**
* Get all or one data entity from the backend
* @param id optional id as number or string - if not provided, will get all
* @param params optional parameters - ATM not usefuly but we plan to support more filters etc.
* @returns an array with 1 or n entities in the simple JSON format
*/
private getInternal<TCall>(id?: string | number, params?: string | Record<string, unknown>): Promise<TCall> {
let path = "app/auto/content/" + this.name;
if (id && (typeof id === 'string' || typeof id === 'number')) path += "/" + id;
return this.webApi.fetchJson(this.webApi.url(path, params));
}

// TODO: @SPM create
// - Create a type for the `metadataFor` attribute
// - implement create
// - capture various null-cases
// - if `metadataFor` is specified, add attribute `for` the the object before sending (that should work)

create(values: Record<string, unknown>): Promise<Record<string, unknown>>;

create(values: Record<string, unknown>, metadataFor?: any): Promise<Record<string, unknown>> {
return null;
}

// TODO: @SPM update
update(id: number, values: Record<string, unknown>): Promise<Record<string, unknown>> {
return null;
}
}

63 changes: 63 additions & 0 deletions projects/$2sxc/src/sxc-instance/data/sxc-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { SxcInstance } from "..";
import { SxcDataQueryBase } from './sxc-data-query-base';

/**
* Instance Data accessor to get (and in future create/update) data items/entities
*/
export class SxcQuery extends SxcDataQueryBase {

constructor(sxc: SxcInstance, readonly name: string) {
super(sxc, name, 'Query');
}

/**
* Retrieve the entire query with all streams
*
* @template T
* @returns {Promise<T>} containing a object with stream-names and items in the streams.
* @memberof SxcQuery
*/
getAll<T = unknown>(): Promise<T> {
return this.getInternal<T>();
}

/**
* Get just one stream, returning an array of items in that stream
*
* @template T
* @param {string} stream
* @returns {Promise<T[]>} containing an array of items - or empty if stream not found or nothing returned
* @memberof SxcQuery
*/
getStream<T = unknown>(stream: string): Promise<T[]> {
if (stream.indexOf(',') !== -1) throw "parameter 'stream' can only contain one stream name for 'getStream'";
return this.getInternal<unknown>(stream).then((data) => {
if (data == null || !data.hasOwnProperty(stream)) return [];
return (data as any)[stream] as T[];
})
}

/**
* Get a query but only the selected streams.
*
* @template T
* @param {string} streams
* @returns {Promise<T>} containing a object with stream-names and items in the streams.
* @memberof SxcQuery
*/
getStreams<T = unknown>(streams: string): Promise<T> {
return this.getInternal<T>(streams);
}

/**
* Get all or one data entity from the backend
* @param id optional id as number or string - if not provided, will get all
* @param params optional parameters - ATM not usefuly but we plan to support more filters etc.
* @returns an array with 1 or n entities in the simple JSON format
*/
private getInternal<T = unknown>(streams?: string, params?: string | Record<string, any>): Promise<T> {
let path = "app/auto/query/" + this.name;
if (streams && (typeof streams === 'string')) path += "?stream=" + streams;
return this.webApi.fetchJson(this.webApi.url(path, params));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export class SxcInstanceWithInternals extends SxcInstance {
super(id, cbid, $2sxc, ctx);

// Help cach error on call of old code
// Background: From v3 to v12 data had a unusualy system for retrieving data belonging to the module
// We believe it's almost never used, but the TimelineJs App always used it, and we believe
// 2-3 other examples may have as well.
// Now in v13 sxc.data is used to get any kind of data,
// and we want to make sure that old code will show a warning helping people fix this
// All the old code would have started with sxc.data.on('load', ...) so this is where we give them the error
(this.data as any).on = () => {
throw 'Warning Obsolete Feature on 2sxc JS: the .data has been obsolete for a long time and is repurposed. \n'
+ 'If you are calling .data.on(...) you are running very old code. \n'
Expand Down
Loading

0 comments on commit a8519dd

Please sign in to comment.