lemon-core
Version:
Lemon Serverless Micro-Service Platform
190 lines • 6.95 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());
});
};
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
;