UNPKG

lemon-core

Version:
190 lines 6.95 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MyConfigService = exports.marshal = void 0; /** * file: `cores/config-service.ts` * - Asynchronized creation of config. * * **Use Case** * 1. clone the predefined environment variables. * 2. decrypt the encrypted string with `kms.service`, and save it. * * **NOTE** * - Only via ConfigService, app could use the decrypted string. * * * @author Steve Jung <steve@lemoncloud.io> * @date 2019-06-04 initial version. * @date 2019-11-06 added `getStage()` * * @copyright (C) lemoncloud.io 2019 - All Rights Reserved. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const engine_1 = require("../../engine/"); const NS = engine_1.$U.NS('CFGS', 'red'); // NAMESPACE TO BE PRINTED. const shared_1 = require("../../tools/shared"); /** * marshaler: convert object to dotted list. * * @param obj json object * @param name current name * @param list result list * @param filter filter function. */ const marshal = (obj, filter, name = '', list = [], thiz, attr) => { if (!filter) throw new Error('filter is required!'); thiz = thiz === undefined ? obj : thiz; if (obj && typeof obj == 'object') { if (!Array.isArray(obj)) { return Object.keys(obj).reduce((L, key) => { const val = obj[key]; return (0, exports.marshal)(val, filter, name ? `${name}.${key}` : `${key}`, L, obj, key); }, list); } else { return obj.reduce((L, val, index) => { return (0, exports.marshal)(val, filter, name ? `${name}.${index}` : `${index}`, L, obj, index); }, list); } } else { const line = filter(name, obj, thiz, attr); if (line !== undefined && line !== null) list.push(line); } return list; }; exports.marshal = marshal; /** * class: `MyConfigService` * - sample for asynchronized factory. */ class MyConfigService { /** * DO NOT craete directly. (use async `ConfigService.factory()`) */ constructor(base, kms) { /** * internal cached config settings. */ this.envConfig = {}; /** * hello */ this.hello = () => `config-service`; //! loading service's package.json this._package = null; (0, engine_1._log)(NS, `ConfigService()...`); this.base = base; this.kms = kms; } /** * read all configuration setting */ all() { return Object.assign({}, this.envConfig); } /** * read config value (or all config settings) * 1. read via internal cache. * 2. if missed, then read via process.env. * * @param key config-name. */ get(key) { const ret = this.envConfig[key]; const $env = this.$env || {}; const val = ret === undefined ? $env[key] : ret; return val === undefined ? undefined : `${val}`; } loadPackage() { if (!this._package) { try { this._package = (shared_1.loadJsonSync && (0, shared_1.loadJsonSync)('package.json')) || {}; } catch (e) { (0, engine_1._err)(NS, `! err to load package.json =`, e); } } return this._package || {}; } getService() { const $pack = this.loadPackage(); return `${($pack && $pack.name) || ''}`; } getVersion() { const $pack = this.loadPackage(); return `${($pack && $pack.version) || ''}`; } /** * read current stage condition */ getStage() { const stage = `${this.get('STAGE') || this.get('stage') || ''}`.toLowerCase(); if (stage == 'develop' || stage == 'development' || stage == 'dev') return 'dev'; if (stage == 'production' || stage == 'product' || stage == 'prod') return 'prod'; return 'local'; } /** * load & decrypt the environ. * - only if string starts with '*' */ init() { return __awaiter(this, void 0, void 0, function* () { // const _log = console.log; // _log(NS, `init()...`); const base = this.base; const $env = base || process.env || {}; this.$env = $env; // save as default environ. //! check if encrypted like `*XX+XyXxX==` (must start with '*') const isEncrypted = (val) => { return val && typeof val == 'string' && /^\*[A-Za-z0-9_\/=\+]+$/.test(val); }; //! convert to { key, val } const filter = (key, val) => { return { key, val }; }; const list = (0, exports.marshal)($env, filter); //! decrypts if is encrypted. const list2 = yield Promise.all(list.map(({ key, val }) => __awaiter(this, void 0, void 0, function* () { if (isEncrypted(val) && this.kms) { const encrypted = `${val}`.substring(1); const val2 = yield this.kms.decrypt(encrypted).catch((e) => { (0, engine_1._log)(NS, `ERR@${key} =`, e); return `ERROR - ${e.message || engine_1.$U.json(e)}`; }); (0, engine_1._log)(NS, `> config[${key}] :=`, val2.substring(0, 12), val2.length > 12 ? '...' : ''); return { key, val: val2 }; } return { key, val }; }))); // _log(NS, `! list2 =`, list2); //! convert envConfig value. this.envConfig = list2.reduce((M, item) => { const { key, val } = item; if (key) M[key] = `${val}`; // convert all to string. return M; }, {}); // _log(NS, '>> envConfig=', this.envConfig); // _log(NS, '>> envOrigin=', this.$env); (0, engine_1._inf)(NS, '>> inited... config.len=', list2.length); //! returns this. return this; }); } } exports.MyConfigService = MyConfigService; //# sourceMappingURL=config-service.js.map