api-core
Version:
Model-based dynamic multi-level APIs for any provider, plus multiple consumption channels
108 lines (87 loc) • 4.29 kB
text/typescript
import {ApiEdgeQueryContext} from "./ApiEdgeQueryContext";
import {ApiEdgeQueryResponse} from "./ApiEdgeQueryResponse";
import {ApiEdgeSchema} from "./ApiEdgeSchema";
import {ApiEdge, ApiEdgeDefinition} from "./ApiEdgeDefinition";
import {SchemaTypeMapper} from "./utils/SchemaTypeMapper";
import {ApiEdgeMethod} from "./ApiEdgeMethod";
import {ApiQueryScope} from "../query/ApiQuery";
import {Api} from "../Api";
export abstract class ExternalApiProvider {
protected metadata: any;
protected api: Api;
protected constructor(metadata: any, api: Api) {
this.metadata = metadata;
this.api = api;
}
abstract getEntry: (context: ApiEdgeQueryContext) => Promise<ApiEdgeQueryResponse>;
abstract listEntries: (context: ApiEdgeQueryContext) => Promise<ApiEdgeQueryResponse>;
abstract createEntry: (context: ApiEdgeQueryContext, entryFields: any) => Promise<ApiEdgeQueryResponse>;
abstract updateEntry: (context: ApiEdgeQueryContext, entryFields: any) => Promise<ApiEdgeQueryResponse>;
abstract patchEntry: (context: ApiEdgeQueryContext, entryFields: any) => Promise<ApiEdgeQueryResponse>;
abstract removeEntry: (context: ApiEdgeQueryContext, entryFields: any) => Promise<ApiEdgeQueryResponse>;
abstract exists: (context: ApiEdgeQueryContext) => Promise<ApiEdgeQueryResponse>;
abstract callMethod: (scope: ApiQueryScope) => Promise<ApiEdgeQueryResponse>;
protected abstract prepare(): Promise<void>;
async edge(): Promise<ApiEdgeDefinition> {
await this.prepare();
return new ExternalApiEdge(this.metadata, this.api, this)
}
}
export class ExternalApiEdge extends ApiEdge {
constructor(metadata: any, api: Api, provider?: ExternalApiProvider) {
super();
this.api = api;
this.name = metadata.name;
this.pluralName = metadata.pluralName;
this.idField = metadata.idField;
const publicSchema: { [key: string]: string } = {};
metadata.fields.forEach((field: string) => publicSchema[field] = '=');
this.schema = new ApiEdgeSchema(
publicSchema,
metadata.typings
? SchemaTypeMapper.importSchema(metadata.typings)
: null
);
const callMethod = provider ? provider.callMethod : async () => new ApiEdgeQueryResponse(null);
for(let { name, scope, type, parameters } of metadata.methods) {
this.methods.push(
new ApiEdgeMethod(name, callMethod, scope, type, parameters, false)
)
}
this.allowGet = metadata.allowGet;
this.allowList = metadata.allowList;
this.allowCreate = metadata.allowCreate;
this.allowUpdate = metadata.allowUpdate;
this.allowPatch = metadata.allowPatch;
this.allowRemove = metadata.allowRemove;
this.allowExists = false; //metadata.allowExists;
this.external = true;
this.url = metadata.url;
if(provider)
this.provider = provider;
}
url: string;
provider: ExternalApiProvider;
api: Api;
getEntry = (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return this.provider.getEntry(context)
};
listEntries = async (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return this.provider.listEntries(context)
};
createEntry = async (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return this.provider.createEntry(context, body)
};
updateEntry = async (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return this.provider.updateEntry(context, body)
};
patchEntry = async (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return this.provider.patchEntry(context, body)
};
removeEntry = async (context: ApiEdgeQueryContext, body: any): Promise<ApiEdgeQueryResponse> => {
return this.provider.removeEntry(context, body)
};
exists = async (context: ApiEdgeQueryContext): Promise<ApiEdgeQueryResponse> => {
return this.provider.exists(context)
};
}