lemon-core
Version:
Lemon Serverless Micro-Service Platform
194 lines • 8.12 kB
JavaScript
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
;