api-core
Version:
Model-based dynamic multi-level APIs for any provider, plus multiple consumption channels
123 lines (104 loc) • 4.97 kB
text/typescript
import {ApiEdge} from "../../../src/edge/ApiEdgeDefinition";
import {ApiEdgeQueryFilter, ApiEdgeQueryFilterType} from "../../../src/edge/ApiEdgeQueryFilter";
import {ApiEdgeQueryContext} from "../../../src/edge/ApiEdgeQueryContext";
import {ApiEdgeQueryResponse} from "../../../src/edge/ApiEdgeQueryResponse";
import {ApiEdgeError} from "../../../src/query/ApiEdgeError";
export class Model {
id: string;
constructor(obj: any) {
this.id = obj.id;
}
}
export class ModelEdge<ModelType extends Model> extends ApiEdge {
name = "entry";
pluralName = "entries";
idField = "id";
fields = []; //TODO
provider: ModelType[] = [];
protected createModel: (obj: any) => ModelType;
methods = [];
relations = [];
inspect = () => `/${this.pluralName}`;
private applyMapping(item: any, fields: string[]): any {
if(!fields.length) return item;
let output: any = {};
Object.keys(item).filter(key => fields.indexOf(key) != -1).forEach(key => output[key] = item[key]);
return output
}
private static applyFilter(item: any, filter: ApiEdgeQueryFilter): boolean {
switch(filter.type) {
case ApiEdgeQueryFilterType.Equals:
return item[filter.field] === filter.value;
case ApiEdgeQueryFilterType.NotEquals:
return item[filter.field] !== filter.value;
case ApiEdgeQueryFilterType.GreaterThan:
return item[filter.field] > filter.value;
case ApiEdgeQueryFilterType.GreaterThanOrEquals:
return item[filter.field] >= filter.value;
case ApiEdgeQueryFilterType.LowerThan:
return item[filter.field] < filter.value;
case ApiEdgeQueryFilterType.LowerThanOrEquals:
return item[filter.field] <= filter.value;
default:
return false;
}
}
private applyFilters(item: any, filters: ApiEdgeQueryFilter[]): boolean {
if(!filters.length) return true;
return filters.every(filter => ModelEdge.applyFilter(item, filter))
}
getEntry = (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve, reject) => {
let entry = this.provider.find((s: any) => s.id === context.id && this.applyFilters(s, context.filters));
if(entry) resolve(new ApiEdgeQueryResponse(this.applyMapping(entry, context.fields)));
else reject(new ApiEdgeError(404, "Not Found"));
})
};
listEntries = (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve) => {
resolve(new ApiEdgeQueryResponse(
this.provider
.filter(item => this.applyFilters(item, context.filters))
.map(entry => this.applyMapping(entry, context.fields))))
})
};
createEntry = (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve) => {
let entry = this.createModel(body);
this.provider.push(entry);
resolve(new ApiEdgeQueryResponse(this.applyMapping(entry, context.fields)))
})
};
updateEntry = (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve, reject) => {
this.getEntry(context).then(() => {
body.id = context.id;
resolve(new ApiEdgeQueryResponse(this.applyMapping(body, context.fields)))
}).catch(reject)
})
};
patchEntry = (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve, reject) => {
this.getEntry(context).then((resp: any) => {
let entry: any = resp.data;
Object.keys(body).forEach((key: any) => entry[key] = body[key]);
resolve(new ApiEdgeQueryResponse(this.applyMapping(entry, context.fields)))
}).catch(reject)
})
};
removeEntry = (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve, reject) => {
this.getEntry(context).then((entry : any) => {
this.provider.splice(this.provider.indexOf(entry), 1);
resolve(new ApiEdgeQueryResponse(entry))
}).catch(reject);
})
};
exists = (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return new Promise<ApiEdgeQueryResponse>((resolve) => {
let entry = this.provider.find((s: any) => s.id === context.id);
if(entry) resolve(new ApiEdgeQueryResponse(true));
else resolve(new ApiEdgeQueryResponse(false));
})
}
}