lemon-core
Version:
Lemon Serverless Micro-Service Platform
684 lines • 30.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MocksAPIService = exports.createHttpWebProxy = exports.APIService = exports.APIProxyClient = void 0;
/**
* `api-service.ts`
* - common external rest-api service.
* - support http-proxy with backbone to overcome VPC restriction.
*
*
* @author Steve Jung <steve@lemoncloud.io>
* @date 2019-05-23 initial version
* @date 2019-12-03 refactoring for `lemon-core#2.0.0`
*
* @copyright (C) lemoncloud.io 2019 - All Rights Reserved.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const engine_1 = require("../../engine/");
const shared_1 = require("../../tools/shared");
const test_helper_1 = require("../../common/test-helper");
const fs_1 = __importDefault(require("fs"));
const NS = engine_1.$U.NS('APIS', 'green'); // NAMESPACE TO BE PRINTED.
/**
* class: `APIProxyClient`
* - proxed APIServiceClient
*/
class APIProxyClient {
constructor(service) {
this.hello = () => this.service.hello();
this.service = service;
}
doGet(id, cmd, param, body, hash) {
return this.service.doGet(id, cmd, param, body, hash);
}
doPut(id, cmd, param, body, hash) {
return this.service.doPut(id, cmd, param, body, hash);
}
doPost(id, cmd, param, body, hash) {
return this.service.doPost(id, cmd, param, body, hash);
}
doPatch(id, cmd, param, body, hash) {
return this.service.doPatch(id, cmd, param, body, hash);
}
doDelete(id, cmd, param, body, hash) {
return this.service.doDelete(id, cmd, param, body, hash);
}
}
exports.APIProxyClient = APIProxyClient;
/**
* class: `APIService`
* - use internal http-proxy service due to restriction internet-face in VPC lambda.
*/
class APIService {
/**
* create API service.
*
* ```js
* // basic
* const api = new API('web', 'http://localhost:8081', {});
* api.doGet('');
*
* // via python
* const api = new API('residents', 'http://localhost:8113', {});
* api.doGet('123'); // http GET :8113/residents/123
*
* // proxy server
* const api = new API('web', 'http://localhost:8081', {}, null, proxy);
* api.doGet('');
* ```
*
* @param type type in endpoint
* @param endpoint base endpoint (support ONLY http, https)
* @param headers common headers.
* @param client real api-client to use (or use proxy, or create default)
* @param proxy proxy-service to use if there is no client (or use backbone server)
*/
constructor(type, endpoint, headers, client, proxy) {
//* relay hello.
this.hello = () => `api-service:${this.client.hello()}`;
if (!endpoint)
throw new Error('@endpoint (url) is required');
if (!endpoint.startsWith('http://') && !endpoint.startsWith('https://'))
throw new Error(` (url) is not valid http-url:${endpoint}`);
this.type = type;
this.endpoint = endpoint;
this.headers = headers;
if (client) {
this.client = client;
}
else if (proxy) {
this.client = APIService.buildClient(this.type, this.endpoint, this.headers, null, proxy);
}
else {
//* use default `env.BACKBONE_API` to detect proxy-server.
const BACKBONE = engine_1.$engine.environ('BACKBONE_API', 'http://localhost:8081');
this.client = APIService.buildClient(this.type, this.endpoint, this.headers, BACKBONE);
}
}
/**
* helper to make http client
*
* @param backbone backbone address like 'http://localhost:8081'
*/
static buildClient(type, endpoint, headers, backbone, proxy) {
(0, engine_1._log)(NS, `buildClient(${type || ''})...`);
if (!endpoint)
throw new Error('@endpoint (url) is required');
const host = `${endpoint || ''}`.split('/')[2];
//* if using backbone, need host+path for full-url. or need only `type` + `id/cmd` pair for direct http agent.
const base = !proxy && backbone ? `${endpoint || ''}` : undefined;
//* make the default proxy-client if not in.
if (proxy) {
proxy = proxy;
}
else if (backbone) {
//* use web-proxy configuration.
const NAME = `WEB:${host}-${type || ''}`;
const encoder = (name, path) => encodeURIComponent(path);
const relayHeaderKey = 'x-lemon-';
const resultKey = 'result';
//* use default backbone's web-proxy service.
proxy = (0, exports.createHttpWebProxy)(NAME, `${backbone}/web`, headers, encoder, relayHeaderKey, resultKey);
}
else {
//* use direct web request.. (only read `type` + `id/cmd` later)
const NAME = `API:${host}-${type || ''}`;
proxy = (0, exports.createHttpWebProxy)(NAME, endpoint, headers, (n, s) => s, '');
}
/**
* create internal client to translate of full url path with `host`+`path`
*/
return new APIService.ProxyServiceClient(proxy, base, type);
}
/**
* make a client for sub-typed endpoint.
* @param type sub-type path.
*/
buildSubTypeClient(type, useRecord, folder) {
const client = new APIService.SubTypeClient(this, type);
return useRecord ? new APIService.APIServiceClientRecorder(client, `${this.endpoint}/${type}`, folder) : client;
}
/**
* make api recorder of this service.
* @param folder base folder (default `./logs`)
*/
buildRecorder(folder) {
return new APIService.APIServiceClientRecorder(this, this.endpoint, folder);
}
/**
* GET HOST/PATH?$param
*/
doGet(id, cmd, $param, $body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.client.doGet(id, cmd, $param, $body, hash);
});
}
/**
* PUT HOST/PATH?$param
*/
doPut(id, cmd, $param, $body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.client.doPut(id, cmd, $param, $body, hash);
});
}
/**
* POST HOST/PATH?$param
*/
doPost(id, cmd, $param, $body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.client.doPost(id, cmd, $param, $body, hash);
});
}
/**
* PATCH HOST/PATH?$param
*/
doPatch(id, cmd, $param, $body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.client.doPatch(id, cmd, $param, $body, hash);
});
}
/**
* DELETE HOST/PATH?$param
*/
doDelete(id, cmd, $param, $body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.client.doDelete(id, cmd, $param, $body, hash);
});
}
}
exports.APIService = APIService;
/**
* class: `TypedEndpoint`
* - by using common proxy, extends endpoint by type.
* - endpoint := base+'/'+type.
*/
APIService.ProxyServiceClient = class {
constructor(proxy, base, type) {
this.asPath = (id, cmd) => {
const type = this.type;
const _isNa = (a) => a === undefined || a === null;
return ('' +
(_isNa(type) ? '' : '/' + encodeURIComponent(type)) +
(_isNa(type) || _isNa(id) ? '' : '/' + encodeURIComponent(id)) +
(_isNa(type) || _isNa(id) || _isNa(cmd) ? '' : '/' + encodeURI(cmd)) + //NOTE - cmd could have additional '/' char.
'');
};
this.asPath2 = (id, cmd) => {
const _isNa = (a) => a === undefined || a === null;
return ('' +
(_isNa(id) ? '' : encodeURIComponent(id)) +
(_isNa(id) || _isNa(cmd) ? '' : '/' + encodeURI(cmd)) + //NOTE - cmd could have additional '/' char.
'');
};
this.asHostPath = (id, cmd) => {
let host = this.base ? this.base : this.type;
let path = this.base ? this.asPath(id, cmd) : this.asPath2(id, cmd);
if (this.base) {
const url = (!host.startsWith('http') ? 'http://' : '') + `${host}${path || ''}`;
const $url = url_1.default.parse(url);
host = `${$url.protocol || 'http'}//${$url.hostname}`;
path = `${$url.path}`;
// console.info(`! asHostPath(${id}, ${cmd})@1 => `, { host, path });
}
else {
// console.info(`! asHostPath(${id}, ${cmd})@2 => `, { host, path });
}
return { host, path };
};
this.hello = () => `api-client:${this.proxy.hello()}`;
this.proxy = proxy;
this.base = base;
this.type = type;
}
doGet(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const { host, path } = this.asHostPath(id, cmd);
return this.proxy.doProxy('GET', host, path, param, body, null, hash);
});
}
doPut(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const { host, path } = this.asHostPath(id, cmd);
return this.proxy.doProxy('PUT', host, path, param, body, null, hash);
});
}
doPost(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const { host, path } = this.asHostPath(id, cmd);
return this.proxy.doProxy('POST', host, path, param, body, null, hash);
});
}
doPatch(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const { host, path } = this.asHostPath(id, cmd);
return this.proxy.doProxy('PATCH', host, path, param, body, null, hash);
});
}
doDelete(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const { host, path } = this.asHostPath(id, cmd);
return this.proxy.doProxy('DELETE', host, path, param, body, null, hash);
});
}
};
/**
* use sub-typed endpoint.
* - extends as endpoint := parent.endpoint + '/' + type
*/
APIService.SubTypeClient = class {
constructor(parent, type) {
this.hello = () => `sub-typed:${this.parent.hello()}`;
this.asCmd = (id, cmd) => {
if (id === undefined || id === null)
return '';
if (id != encodeURI(id))
throw new Error(` (string) is not valid format.`);
return cmd !== undefined && cmd !== null ? `${id || ''}/${cmd}` : `${id || ''}`;
};
this.parent = parent;
this.type = `${type || ''}`;
}
doGet(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.parent.doGet(this.type, this.asCmd(id, cmd), param, body, hash);
});
}
doPut(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.parent.doPut(this.type, this.asCmd(id, cmd), param, body, hash);
});
}
doPost(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.parent.doPost(this.type, this.asCmd(id, cmd), param, body, hash);
});
}
doPatch(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.parent.doPatch(this.type, this.asCmd(id, cmd), param, body, hash);
});
}
doDelete(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.parent.doDelete(this.type, this.asCmd(id, cmd), param, body, hash);
});
}
};
/**
* recorder of api-http-proxy client.
*/
APIService.ApiHttpProxyRecorder = (_a = class {
constructor(target, folder) {
this.hello = () => `recorder:${this.target.hello()}`;
this.target = target;
this.folder = `${folder || './logs'}`;
}
doProxy(method, host, path, param, body, context, hash) {
return __awaiter(this, void 0, void 0, function* () {
const endpoint = host.startsWith('http://') || host.startsWith('https://') ? `${host}${path}` : `http://${host}${path}`;
const index = APIService.ApiHttpProxyRecorder.next++;
const load = { method, endpoint, param, body, context };
return this.target
.doProxy(method, host, path, param, body, context, hash)
.then((data) => ({ index, load, data, error: null }))
.catch((error) => ({ index, load, data: null, error }))
.then(({ index, load, data, error }) => {
const baseDir = (() => {
// eslint-disable-next-line prettier/prettier
const ts = engine_1.$U.ts().substring(0, '1999-01-01'.length).replace(/\-/ig, '');
const fn = `${this.folder}/R${ts}`;
if (index <= 1 && !fs_1.default.existsSync(`${this.folder}`))
fs_1.default.mkdirSync(`${this.folder}`);
if (index <= 1 && !fs_1.default.existsSync(fn))
fs_1.default.mkdirSync(fn);
return fn;
})();
// eslint-disable-next-line prettier/prettier
const message = error instanceof Error ? `${error.message}` : typeof error != 'object' ? `${error}` : error ? JSON.stringify(error) : '';
const fn = (n) => {
const [S, s] = ['00000', `${n}`];
return n > 0 ? `${S.substring(s.length)}${s}` : s.startsWith('-') ? `N${s.substring(1)}` : s;
};
const file = `${baseDir}/P${fn(index)}.json`;
fs_1.default.writeFileSync(file, JSON.stringify({ param: load, data, error: message }, null, ' '), 'utf8');
if (error)
throw error;
else
return data;
});
});
}
},
_a.next = 1,
_a);
/**
* recorder of api-service client.
*/
APIService.APIServiceClientRecorder = (_b = class {
constructor(target, endpoint, folder) {
this.hello = () => `recorder:${this.target.hello()}`;
this.target = target;
this.endpoint = `${endpoint || ''}`;
this.folder = `${folder || './logs'}`;
}
doRecord(method, id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
const index = APIService.APIServiceClientRecorder.next++;
const load = { method, endpoint: `${this.endpoint || ''}`, id, cmd, param, body };
const call = (method) => __awaiter(this, void 0, void 0, function* () {
if (method == 'GET')
return this.target.doGet(id, cmd, param, body, hash);
if (method == 'PUT')
return this.target.doPut(id, cmd, param, body, hash);
if (method == 'POST')
return this.target.doPost(id, cmd, param, body, hash);
if (method == 'PATCH')
return this.target.doPatch(id, cmd, param, body, hash);
if (method == 'DELETE')
return this.target.doDelete(id, cmd, param, body, hash);
throw new Error(` is not valid. method:${method}`);
});
return call(method)
.then((data) => ({ index, load, data, error: null }))
.catch((error) => ({ index, load, data: null, error }))
.then(({ index, load, data, error }) => {
const baseDir = (() => {
// eslint-disable-next-line prettier/prettier
const ts = engine_1.$U.ts().substring(0, '1999-01-01'.length).replace(/\-/ig, '');
const fn = `${this.folder}/R${ts}`;
if (index <= 1 && !fs_1.default.existsSync(`${this.folder}`))
fs_1.default.mkdirSync(`${this.folder}`);
if (index <= 1 && !fs_1.default.existsSync(fn))
fs_1.default.mkdirSync(fn);
return fn;
})();
// eslint-disable-next-line prettier/prettier
const message = error instanceof Error ? `${error.message}` : typeof error != 'object' ? `${error}` : error ? JSON.stringify(error) : '';
const fn = (n) => {
const [S, s] = ['00000', `${n}`];
return n > 0 ? `${S.substring(s.length)}${s}` : s.startsWith('-') ? `N${s.substring(1)}` : s;
};
const file = `${baseDir}/D${fn(index)}.json`;
fs_1.default.writeFileSync(file, JSON.stringify({ param: load, data, error: message }, null, ' '), 'utf8');
if (error)
throw error;
else
return data;
});
});
}
doGet(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.doRecord('GET', id, cmd, param, body, hash);
});
}
doPut(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.doRecord('PUT', id, cmd, param, body, hash);
});
}
doPost(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.doRecord('POST', id, cmd, param, body, hash);
});
}
doPatch(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.doRecord('PATCH', id, cmd, param, body, hash);
});
}
doDelete(id, cmd, param, body, hash) {
return __awaiter(this, void 0, void 0, function* () {
return this.doRecord('DELETE', id, cmd, param, body, hash);
});
}
},
_b.next = 1,
_b);
/** ********************************************************************************************************************
* BODY IMPLEMENTATION.
** ********************************************************************************************************************/
const url_1 = __importDefault(require("url"));
const request_1 = __importDefault(require("request"));
const query_string_1 = __importDefault(require("query-string"));
/**
* create http-web-proxy agent which using endpoint as proxy server.
*
* # as cases.
* as proxy agent: GET <endpoint>/<host?>/<path?>
* as direct agent: GET <endpoint>/<id?>/<cmd?>
*
* @param name client-name
* @param endpoint service url (or backbone proxy-url)
* @param headers headers
* @param encoder path encoder (default encodeURIComponent)
* @param relayHeaderKey relay-key in headers for proxy.
* @param resultKey resultKey in response
*/
const createHttpWebProxy = (name, endpoint, headers, encoder, relayHeaderKey, resultKey) => {
if (!endpoint)
throw new Error('@endpoint (url) is required!');
const NS = engine_1.$U.NS(`X${name}`, 'magenta'); // NAMESPACE TO BE PRINTED.
encoder = encoder !== undefined ? encoder : (name, path) => path;
relayHeaderKey = relayHeaderKey || '';
/**
* class: `ApiHttpProxy`
* - http proxy client via backbone's web.
*/
return new (class {
constructor() {
this.hello = () => `http-web-proxy:${name}`;
}
doProxy(method, path1, path2, $param, $body, ctx) {
// const _log = console.info;
if (!method)
throw new Error('@method is required!');
(0, engine_1._log)(NS, `doProxy(${method})..`);
const _isNa = (a) => a === undefined || a === null;
(0, engine_1._log)(NS, '> endpoint =', endpoint);
_isNa(path1) && (0, engine_1._log)(NS, `> host(id) =`, typeof path1, path1);
_isNa(path2) && (0, engine_1._log)(NS, `> path(cmd) =`, typeof path2, path2);
//* prepare request parameters
// eslint-disable-next-line prettier/prettier
const query_string = _isNa($param) ? '' : (typeof $param == 'object' ? query_string_1.default.stringify($param) : `${$param}`);
const url = endpoint +
(_isNa(path1) ? '' : `/${encoder('host', path1)}`) +
(_isNa(path1) && _isNa(path2) ? '' : `/${encoder('path', path2)}`) +
(!query_string ? '' : '?' + query_string);
const request = request_1.default;
const options = {
method,
uri: url,
headers: {},
body: $body === null ? undefined : $body,
json: typeof $body === 'string' ? false : true,
};
//* relay HEADERS to `WEB-API`
if (headers) {
options.headers = Object.keys(headers).reduce((H, key) => {
const val = headers[key];
const name = `${relayHeaderKey}${key}`;
const text = `${val}`;
H[name] = text;
return H;
}, options.headers);
}
(0, engine_1._log)(NS, ' url :=', options.method, url);
(0, engine_1._log)(NS, '*', options.method, url, options.json ? 'json' : 'plain');
(0, engine_1._log)(NS, '> options =', engine_1.$U.json(options));
//* returns promise
return new Promise((resolve, reject) => {
//* start request..
request(options, function (error, response, body) {
error && (0, engine_1._err)(NS, '>>>>> requested! err=', error);
if (error)
return reject(error instanceof Error ? error : new Error((0, test_helper_1.GETERR)(error)));
//* detecte trouble.
const statusCode = response.statusCode;
const statusMessage = response.statusMessage;
//* if not in success
if (statusCode !== 200 && statusCode !== 201) {
const msg = body ? (0, test_helper_1.GETERR)(body) : `${statusMessage || ''}`;
if (statusCode === 400 || statusCode === 404) {
const title = `${(statusCode == 404 ? '' : statusMessage) || 'NOT FOUND'}`.toUpperCase();
const message = msg.startsWith('404 NOT FOUND') ? msg : `${statusCode} ${title} - ${msg}`;
return reject(new Error(message));
}
statusMessage && (0, engine_1._log)(NS, `> statusMessage[${statusCode}] =`, statusMessage);
body && (0, engine_1._log)(NS, `> body[${statusCode}] =`, engine_1.$U.json(body));
return reject(new Error(`${statusCode} ${statusMessage || 'FAILURE'} - ${msg}`));
}
//* try to parse body.
try {
if (body && typeof body == 'string' && body.startsWith('{') && body.endsWith('}')) {
body = JSON.parse(body);
}
else if (body && typeof body == 'string' && body.startsWith('[') && body.endsWith(']')) {
body = JSON.parse(body);
}
}
catch (e) {
(0, engine_1._err)(NS, '!WARN! parse(body) =', e instanceof Error ? e : engine_1.$U.json(e));
}
//* ok! successed.
resolve(body);
});
}).then((res) => {
if (resultKey && res && res[resultKey] !== undefined)
return res[resultKey];
return res;
});
}
})();
};
exports.createHttpWebProxy = createHttpWebProxy;
/** ********************************************************************************************************************
* MOCKS API-SERVICE
** ********************************************************************************************************************/
/**
* class: `MocksAPIService`
* - use <mock>.json file in `./data/mocks/` instead of real http request.
* - it redirect to url like `endpoint/type/id/cmd`
*
* ```ts
* // json format
* {
* param: { // input format
* method: string;
* endpoint: string;
* id?: string;
* cmd?: string;
* },
* data: { // response data
* ...
* },
* error?: string; // in case of error.
* }
* ```
*/
class MocksAPIService {
constructor(type, endpoint) {
this.asPath = (id, cmd) => {
const _isNa = (a) => a === undefined || a === null;
return (_isNa(id) ? '' : encodeURIComponent(id)) + (_isNa(id) || !cmd ? '' : '/' + encodeURI(cmd));
};
this.na = (a, x, y) => (a === undefined || a === null ? x : y);
this.hello = () => `mocks-api-service:${this.endpoint}${this.na(this.type, '', '/')}${this.type || ''}`;
this.type = type;
this.endpoint = endpoint;
}
loadSync() {
if (this.$map)
return;
const PATH = './data/mocks/';
const files = fs_1.default.readdirSync(PATH);
// console.log(NS, '> files =', files);
const $map = files
.sort()
.map(file => ({ file, json: (0, shared_1.loadJsonSync)(`${PATH}${file}`) }))
.reduce((M, F) => {
const file = F.file || '';
const data = F.json;
const param = data.param || {};
const { method, endpoint: endpoint0, id, cmd, param: $qs } = param;
const has = (a) => a !== undefined && a !== null;
const [endpoint, hash] = `${endpoint0}`.split('#', 2);
const qs = $qs ? engine_1.$U.qs.stringify($qs) : '';
const url = `${endpoint}` + (has(id) ? `/${id}` : '') + (has(id) && has(cmd) ? `/${cmd}` : '');
const key = `${method} ${url}`;
const key2 = qs ? `${key}${key.indexOf('?') > 0 ? '&' : '?'}${qs}` : key;
const key3 = hash ? `${key2}${hash ? '#' : ''}${hash || ''}` : key2;
// if (file.indexOf('#') > 0) console.info(`! file[${file}] =`, key3);
//* save by file & key.
M[file] = data;
M[key3] = data;
return M;
}, {});
// console.log(NS, '> $map =', $map);
this.$map = $map;
}
doProxy(method, type, path, param, body, ctx, hash) {
return __awaiter(this, void 0, void 0, function* () {
// console.info(`! mocks.proxy(${method},${type},${path})...`);
this.loadSync();
const file = path && path.endsWith('.json') ? path.split('/').pop() : '';
// eslint-disable-next-line prettier/prettier
const key = `${method} ${this.endpoint}${this.na(type, '', '/')}${type || ''}${!path || path.startsWith('/') ? '' : '/'}${path || ''}`;
const qs = param ? engine_1.$U.qs.stringify(param) : '';
const key2 = qs ? `${key}${path.indexOf('?') > 0 ? '&' : '?'}${qs}` : key;
const key3 = hash ? `${key2}${hash.startsWith('#') ? '' : '#'}${hash}` : key2;
// if (param) console.info('!key[] =', [key3, key2, key]);
// if (hash) console.info(`! hash[${hash}].keys =`, [key3, key2, key]);
const data = this.$map[file] || this.$map[key3] || this.$map[key2] || this.$map[key];
if (!data)
throw new Error(`404 NOT FOUND - ${key3}`);
const err = data.error;
if (err && typeof err == 'string') {
if (err.startsWith('{') && err.endsWith('}'))
throw JSON.parse(err);
else
throw new Error(err);
}
else if (err) {
throw err;
}
//* returns data.
return data.data ? JSON.parse(engine_1.$U.json(data.data)) : data.data;
});
}
doGet(id, cmd, param, body, hash) {
const path = this.asPath(id, cmd); // use mocks.type infor
return this.doProxy('GET', this.type, path, param, body, null, hash);
}
doPut(id, cmd, param, body, hash) {
const path = this.asPath(id, cmd); // use mocks.type infor
return this.doProxy('PUT', this.type, path, param, body, null, hash);
}
doPost(id, cmd, param, body, hash) {
const path = this.asPath(id, cmd); // use mocks.type infor
return this.doProxy('POST', this.type, path, param, body, null, hash);
}
doPatch(id, cmd, param, body, hash) {
const path = this.asPath(id, cmd); // use mocks.type infor
return this.doProxy('PATCH', this.type, path, param, body, null, hash);
}
doDelete(id, cmd, param, body, hash) {
const path = this.asPath(id, cmd); // use mocks.type infor
return this.doProxy('DELETE', this.type, path, param, body, null, hash);
}
}
exports.MocksAPIService = MocksAPIService;
//# sourceMappingURL=api-service.js.map