UNPKG

baqend

Version:

Baqend JavaScript SDK

175 lines (151 loc) 5.9 kB
import * as message from '../message'; import { StatusCode } from '../connector'; import type { EntityManagerFactory } from '../EntityManagerFactory'; import type { Metamodel, ManagedType } from '../metamodel'; import { Validator } from './Validator'; /** * Representation of a Code which runs on Baqend. */ export class Code { metamodel: Metamodel; entityManagerFactory: EntityManagerFactory; /** * @param metamodel * @param entityManagerFactory */ constructor(metamodel: Metamodel, entityManagerFactory: EntityManagerFactory) { this.metamodel = metamodel; this.entityManagerFactory = entityManagerFactory; } /** * Converts the given function to a string * @param fn The JavaScript function to serialize * @return The serialized function */ functionToString(fn: Function): string { if (!fn) { return ''; } let str = fn.toString(); str = str.substring(str.indexOf('{') + 1, str.lastIndexOf('}')); if (str.charAt(0) === '\n') { str = str.substring(1); } if (str.charAt(str.length - 1) === '\n') { str = str.substring(0, str.length - 1); } return str; } /** * Converts the given string to a module wrapper function * @param signature The expected parameters of the function * @param code The JavaScript function to deserialize * @return The deserialized function */ stringToFunction(signature: string[], code: string): Function { // eslint-disable-next-line @typescript-eslint/no-implied-eval return new Function(signature as any /* typings are incorrect here */, code); // eslint-disable-line no-new-func } /** * Loads a list of all available modules without handlers * * @return */ loadModules(): Promise<string[]> { const msg = new message.GetAllModules(); return this.entityManagerFactory.send(msg) .then((response) => response.entity); } /** * Loads Baqend code which will be identified by the given bucket and code type * * @param type The entity type for the handler or the Name of the * Baqend code * @param codeType The type of the code * @param asFunction set it to <code>true</code>, to parse the code as a function and return it * instead of a string * @return The code as parsed function */ loadCode(type: ManagedType<any> | string, codeType: string, asFunction: true): Promise<Function>; /** * Loads Baqend code which will be identified by the given bucket and code type * * @param type The entity type for the handler or the Name of the * Baqend code * @param codeType The type of the code * @param asFunction set it to <code>true</code>, to parse the code as a function and return it * instead of a string * @return The code as string */ loadCode(type: ManagedType<any> | string, codeType: string, asFunction?: false): Promise<string>; loadCode(type: ManagedType<any> | string, codeType: string, asFunction = false): Promise<Function | string | null> { const bucket = typeof type === 'string' ? type : type.name; const msg = new message.GetBaqendCode(bucket, codeType) .responseType('text'); return this.entityManagerFactory.send(msg) .then((response) => this.parseCode(bucket, codeType, asFunction, response.entity), (e) => { if (e.status === StatusCode.OBJECT_NOT_FOUND) { return null; } throw e; }); } /** * Saves Baqend code which will be identified by the given bucket and code type * * @param type The entity type for the handler or the Name of the * Baqend code * @param codeType The type of the code * @param fn Baqend code as a string * @return The stored code as a string */ saveCode(type: ManagedType<any> | string, codeType: string, fn: string): Promise<string>; /** * Saves Baqend code which will be identified by the given bucket and code type * * @param type The entity type for the handler or the Name of the * Baqend code * @param codeType The type of the code * @param fn Baqend code as a function * @return The stored code as a parsed function */ saveCode(type: ManagedType<any> | string, codeType: string, fn: Function): Promise<Function>; saveCode(type: ManagedType<any> | string, codeType: string, fn: Function | string): Promise<Function | string> { const bucket = typeof type === 'string' ? type : type.name; const msg = new message.SetBaqendCode(bucket, codeType) .entity(fn instanceof Function ? this.functionToString(fn) : fn, 'text') .responseType('text'); return this.entityManagerFactory.send(msg) .then((response) => this.parseCode(bucket, codeType, fn instanceof Function, response.entity)!); } /** * Deletes Baqend code identified by the given bucket and code type * * @param type The entity type for the handler or the Name of the * Baqend code * @param codeType The type of the code * @return succeed if the code was deleted */ deleteCode(type: ManagedType<any> | string, codeType: string): Promise<any> { const bucket = typeof type === 'string' ? type : type.name; const msg = new message.DeleteBaqendCode(bucket, codeType); return this.entityManagerFactory.send(msg) .then(() => this.parseCode(bucket, codeType, false, null)); } /** * @param bucket * @param codeType * @param [asFunction=false] * @param code * @return * @private */ parseCode(bucket: string, codeType: string, asFunction: boolean, code: string | null): string | null | Function { if (codeType === 'validate') { const type = this.metamodel.entity(bucket)!; type.validationCode = code === null ? null : Validator.compile(type, code); return asFunction ? type.validationCode : code; } return code && asFunction ? this.stringToFunction(['module', 'exports'], code) : code; } }