UNPKG

lemon-core

Version:
194 lines 8.12 kB
"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 }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GeneralWEBController = exports.GeneralController = void 0; /** * general.controller.ts * - common pattern controller for `/{type}` * * * @author Steve Jung <steve@lemoncloud.io> * @date 2019-12-16 initial version * @date 2020-01-06 support `GeneralWEBController` w/ `asNextIdentityAccess()` * * @copyright (C) lemoncloud.io 2019 - All Rights Reserved. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const engine_1 = require("../engine/"); const test_helper_1 = require("../common/test-helper"); const aws_1 = __importDefault(require("../cores/aws/")); const config_1 = __importDefault(require("../cores/config/")); const protocol_1 = __importDefault(require("../cores/protocol/")); /** * class: `GeneralController`. * - As WebController, routes by path `/hello/{id}/action` to method function like `getHelloAction` */ class GeneralController { /** * default constructor() */ constructor(type) { /** * name of this resource. */ this.hello = () => `general-controller:${this.type()}`; /** * type of api-endpoint. */ this.type = () => `${this.TYPE}`; this.TYPE = `${type || ''}`; } /** * decode to target `next-handler` * - use pattern `<mode><type?><cmd?>` */ decode(mode, id, cmd) { const funcName = this.asFuncName(mode, this.type(), cmd); const handler = this[funcName]; const find1 = typeof handler == 'function' ? handler : null; if (!find1) { const funcName = this.asFuncNameByDo(mode, this.type(), cmd); const handler = this[funcName]; const find2 = typeof handler == 'function' ? handler : null; return find2; } return find1; } /** * translate to camel styled method name from mode + cmd * ex: GET /0/hi -> getHelloHi * ex: GET /0/say-me -> getHelloSayMe */ asFuncName(mode, type, cmd) { const upper1st = (s) => (s && s.length > 0 ? s[0].toUpperCase() + s.substring(1) : s); const camelCased = (s) => s.replace(/-([a-z])/g, g => g[1].toUpperCase()); type = camelCased(upper1st(`${type || ''}`)); mode = `${mode || 'do'}`.toLowerCase(); cmd = camelCased(upper1st(`${cmd || ''}`.toLowerCase())); return `${mode}${type}${cmd}`.replace(/-/g, '_'); } /** * translate to camel styled function name like `doGetHello()` * * ex: GET / -> doList * ex: GET /0/hi -> doGetHi * ex: POST /0/say-me -> doPostSayMe */ asFuncNameByDo(mode, type, cmd) { const upper1st = (s) => (s && s.length > 0 ? s[0].toUpperCase() + s.substring(1) : s); const camelCased = (s) => s.replace(/-([a-z])/g, g => g[1].toUpperCase()); mode = `${mode || type || 'get'}`.toLowerCase(); mode = camelCased(upper1st(`${mode || ''}`)); cmd = camelCased(upper1st(`${cmd || ''}`.toLowerCase())); return `do${mode}${cmd}`.replace(/-/g, '_'); } } exports.GeneralController = GeneralController; /** * class: `GeneralWEBController` * - support additional helper functions for web-controller. */ class GeneralWEBController extends GeneralController { /** * default constructor() * * @param type type of this controller. * @param base the base controller to bypass. */ constructor(type, base) { super(type); /** * name of this resource. */ this.hello = () => `general-web-controller:${this.type()}${this.base ? '/' + this.base.hello() : ''}`; /** * translate to `NextIdentityAccess` from origin NextContext * - use `api://lemon-accounts-api/oauth/0/pack-context` via protocol. * * @param context the requested NextContext */ this.asNextIdentityAccess = (context) => __awaiter(this, void 0, void 0, function* () { //! ignore if .identity is already populated. if (context && context.identity) { const $old = context.identity; if ($old.Site !== undefined) return $old; } //! call service via protocol // const proto: ProtocolService = $cores.protocol.service; const proto = protocol_1.default.service; //TODO - use env to configure `lemon-accounts-api` service @200106 const param = proto.fromURL(context, 'api://lemon-accounts-api/oauth/0/pack-context', {}, {}); const result = yield proto.execute(param); const res = result; //! overwrite the origin context with this identity. if (context) context.identity = res; //! returns; return res; }); /** * notify self-service's event message via SNS * - config `env.EVENT_RELAY_SNS` as SNS endpoint. * * @returns message-id */ this.doNotifyServiceEvent = (context, type, id, state, $param, endpoint) => __awaiter(this, void 0, void 0, function* () { endpoint = endpoint || engine_1.$U.env('EVENT_RELAY_SNS', ''); id = `${id || ''}`; type = `${type || ''}`; state = `${state || ''}`; const config = config_1.default.config; const $proto = protocol_1.default.service; const subject = `event://${config.getService()}-${config.getStage()}`; const { service, param } = ((asUrl) => { if (asUrl) { // So far, can not reach this line const uri = $proto.myProtocolURI(context, type, id); const [a, b] = uri.split('#', 2); const service = `${a}${$param ? '?' : ''}${$param ? engine_1.$U.qs.stringify($param) : ''}#${b}`; return { service, param: undefined }; } else { const service = $proto.myProtocolURI(context, type, id); return { service, param: $param }; } })(0 ? true : false); const message = { type, id, state, service, param }; if (endpoint === '#') return engine_1.$U.json({ endpoint, subject, message }); if (!endpoint) return `ignored`; //! publish to sns endpoint. return aws_1.default.sns.publish(endpoint, subject, message).catch(test_helper_1.GETERR); }); this.base = base; } /** * decode func from self to base. */ decode(mode, id, cmd) { //! find handler from self const ret = super.decode(mode, id, cmd); //! if not found, then find via base. if (!ret && this.base) { const handler = this.base.decode(mode, id, cmd); const builder = (thiz, func) => (i, p, b, c) => func.call(thiz, i, p, b, c); return typeof handler == 'function' ? builder(this.base, handler) : null; } return ret; } } exports.GeneralWEBController = GeneralWEBController; //# sourceMappingURL=general-controller.js.map