@coko/server
Version:
Reusable server for use by Coko's projects
103 lines • 3.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const get_1 = __importDefault(require("lodash/get"));
const has_1 = __importDefault(require("lodash/has"));
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
const mergeWith_1 = __importDefault(require("lodash/mergeWith"));
const zod_1 = require("zod");
const filesystem_1 = require("../utils/filesystem");
const defaultConfig_1 = __importDefault(require("./defaultConfig"));
const configSchema_1 = require("./configSchema");
const errors_1 = require("./errors");
const logger_1 = __importDefault(require("../logger"));
function arrayCustomizer(objValue, srcValue) {
if (Array.isArray(objValue) && Array.isArray(srcValue)) {
return objValue.concat(srcValue);
}
return undefined;
}
function extractOptions(schema, parent = []) {
if (!schema.keyof)
return [];
const paths = [];
let keys = schema.keyof().options;
if (parent)
keys = keys.map(k => [...parent, k].join('.'));
paths.push(...keys);
for (const key of Object.keys(schema.shape)) {
const item = schema.shape[key];
if (item.keyof) {
paths.push(...extractOptions(item, [...parent, key]));
}
else if (item.def?.innerType?.keyof) {
paths.push(...extractOptions(item.def.innerType, [...parent, key]));
}
else if (item.type === 'union') {
item.options.forEach(option => {
paths.push(...extractOptions(option, [...parent, key]));
});
}
}
return paths.sort();
}
class Config {
#values;
#allowedKeys;
constructor() {
this.#values = defaultConfig_1.default;
}
async init(overrideValues) {
let providedSchema = zod_1.z.object({});
const providedSchemaFile = await (0, filesystem_1.readConfigurationFile)('configSchema');
if (!providedSchemaFile) {
logger_1.default.warn('No config schema file');
}
else {
providedSchema = providedSchemaFile.default;
}
const schema = zod_1.z.strictObject({
...configSchema_1.ConfigSchema.shape,
...providedSchema.shape,
});
let providedConfig = {};
const providedConfigFile = await (0, filesystem_1.readConfigurationFile)('config');
if (!providedConfigFile) {
logger_1.default.warn('No config file found');
}
else {
providedConfig = providedConfigFile.default;
}
this.#values = (0, mergeWith_1.default)({}, defaultConfig_1.default, providedConfig, overrideValues, arrayCustomizer);
this.validate(schema);
this.#allowedKeys = extractOptions(schema);
Object.freeze(this);
}
reset() {
this.#values = defaultConfig_1.default;
}
get values() {
return Object.freeze(this.#values);
}
get(key) {
if (!this.#allowedKeys.includes(key)) {
throw new errors_1.ConfigUnknownPropertyError(key);
}
return (0, get_1.default)(this.#values, key);
}
has(key) {
return (0, has_1.default)(this.#values, key) && !(0, isEmpty_1.default)((0, get_1.default)(this.#values, key));
}
validate(schema) {
try {
schema.parse(this.#values);
}
catch (e) {
throw new errors_1.ConfigSchemaError(e);
}
}
}
exports.default = Config;
//# sourceMappingURL=ConfigConstructor.js.map