UNPKG

@codemask-labs/node-config

Version:
124 lines 5.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getConfigInstance = exports.registerConfigTransformTranslations = exports.registerConfigTransformOptions = exports.registerConfigDefaults = void 0; const class_transformer_1 = require("class-transformer"); const class_validator_1 = require("class-validator"); const dotenv_1 = require("dotenv"); const ramda_1 = require("ramda"); const exceptions_1 = require("../exceptions"); const utils_1 = require("../utils"); const constants_1 = require("./constants"); const registerConfigDefaults = (base) => { if (!constants_1.registry.has(base)) { const dependencies = Reflect.getMetadata('design:paramtypes', base) || []; constants_1.registry.set(base, { base, dependencies, resolvedDependencies: dependencies.map(() => null), propertyNameTranslations: {}, instance: null }); } }; exports.registerConfigDefaults = registerConfigDefaults; const registerConfigTransformOptions = (base, transformOptions) => { const current = constants_1.registry.get(base); if (!current) { throw new Error(`Failed to find registered config. Make sure to decorate a class with @Config()!`); } constants_1.registry.set(base, { ...current, transformOptions }); }; exports.registerConfigTransformOptions = registerConfigTransformOptions; const registerConfigTransformTranslations = (base, propertyName, environmentPropertyName) => { const current = constants_1.registry.get(base); if (!current) { throw new Error(`Failed to find registered config. Make sure to decorate a class with @Config()!`); } constants_1.registry.set(base, { ...current, propertyNameTranslations: { ...current?.propertyNameTranslations, [propertyName]: environmentPropertyName } }); }; exports.registerConfigTransformTranslations = registerConfigTransformTranslations; const getConfigInstance = (base, transformOptions) => { const registeredDependency = constants_1.registry.get(base); if (!registeredDependency) { throw new Error(`Failed to find registered config. Make sure to decorate a class with @Config()!`); } if (registeredDependency.instance) { return registeredDependency.instance; } const resolvedDependencies = registeredDependency.resolvedDependencies.map((instance, index) => { const dependency = registeredDependency.dependencies.at(index); if (!dependency) { throw new Error(`Failed to resolve dependency for [${base.name}] at index: ${index}`); } return instance ?? (0, exports.getConfigInstance)(dependency); }); const { parsed: environmentVariables = {} } = (0, dotenv_1.configDotenv)({ override: false, path: process.env.DOTENV_CONFIG_PATH }); const storage = (0, class_validator_1.getMetadataStorage)(); const metadatas = storage.getTargetValidationMetadatas(base, base.name, false, false); const transformedProperties = metadatas.reduce((acc, { propertyName, target }) => { if (acc[propertyName]) { return acc; } const prototype = typeof target === 'function' ? target.prototype : {}; const environmentPropertyName = registeredDependency.propertyNameTranslations[propertyName]; const key = environmentPropertyName || propertyName; const value = environmentVariables[key] || process.env[key]; const type = Reflect.getMetadata('design:type', prototype, propertyName); return { ...acc, [propertyName]: (0, ramda_1.isNotNil)(value) ? (0, utils_1.toValueByType)(type, value) : value }; }, {}); const descriptors = Object.getOwnPropertyDescriptors(base.prototype); const descriptorNames = Object.keys(descriptors).filter(name => name !== 'constructor'); const unreferencedMethods = descriptorNames.reduce((result, name) => { const descriptor = descriptors[name]; return { ...result, [name]: (...args) => descriptor.value.apply(instance, args) }; }, {}); class ConfigConstructorWrapper extends base { static name = base.name; constructor(...unusedArgs) { super(...resolvedDependencies); } } Object.assign(ConfigConstructorWrapper.prototype, unreferencedMethods); const instance = (0, class_transformer_1.plainToInstance)(ConfigConstructorWrapper, transformedProperties, { exposeDefaultValues: true, enableImplicitConversion: true, ...transformOptions }); const validationErrors = (0, class_validator_1.validateSync)(instance, { forbidUnknownValues: false, validationError: { target: true, value: true } }); if (validationErrors.length) { throw new exceptions_1.ValidationException(base.name, validationErrors); } const config = { ...registeredDependency, resolvedDependencies, instance }; constants_1.registry.set(base, config); return config.instance; }; exports.getConfigInstance = getConfigInstance; //# sourceMappingURL=utils.js.map