UNPKG

@buka/nestjs-config

Version:
225 lines (224 loc) 11.5 kB
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "ramda", "@nestjs/common", "class-transformer", "class-validator", "object-path", "./config-loader/dotenv-loader.js", "./config-loader/process-env-loader.js", "./config.module-definition.js", "./constants.js", "./utils/object-keys-to-camel-case.js", "./utils/to-camel-case.js", "./utils/deep-merge-all.js", "util", "./configuration-registry.js"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigModule = void 0; const R = __importStar(require("ramda")); const common_1 = require("@nestjs/common"); const class_transformer_1 = require("class-transformer"); const class_validator_1 = require("class-validator"); const object_path_1 = __importDefault(require("object-path")); const dotenv_loader_js_1 = require("./config-loader/dotenv-loader.js"); const process_env_loader_js_1 = require("./config-loader/process-env-loader.js"); const config_module_definition_js_1 = require("./config.module-definition.js"); const constants_js_1 = require("./constants.js"); const object_keys_to_camel_case_js_1 = require("./utils/object-keys-to-camel-case.js"); const to_camel_case_js_1 = require("./utils/to-camel-case.js"); const deep_merge_all_js_1 = require("./utils/deep-merge-all.js"); const util_1 = require("util"); const configuration_registry_js_1 = require("./configuration-registry.js"); let ConfigModule = class ConfigModule extends config_module_definition_js_1.ConfigurableModuleClass { static config = null; static providers = new Map(); static async createConfigProvider(options, config, configProvider) { const ConfigProviderClass = configProvider.target; if (this.providers.has(ConfigProviderClass)) return this.providers.get(ConfigProviderClass); const path = (0, to_camel_case_js_1.toCamelCase)(configProvider.path); const subConfig = object_path_1.default.get(config, path); const instance = new ConfigProviderClass(); function set(property, value) { if (value !== undefined) instance[property] = value; } const properties = R.uniq([ ...Object.getOwnPropertyNames(instance), ...configuration_registry_js_1.ConfigurationRegistry.getProperties(instance), ]); for (const property of properties) { const ck = configuration_registry_js_1.ConfigurationRegistry.getConfigKey(ConfigProviderClass, property); if (ck.ignore) continue; if (ck.configKey) { const value = object_path_1.default.get(config, ck.configKey); set(property, value); } if (typeof ck.propertyKey === 'symbol') continue; set(property, subConfig && subConfig[(0, to_camel_case_js_1.toCamelCase)(ck.propertyKey)]); } const result = (0, class_transformer_1.instanceToInstance)(instance); const errors = await (0, class_validator_1.validate)(result); if (errors.length) { const message = errors .map((error) => { let message = `An instance of ${ConfigProviderClass.name} has failed the validation:\n`; for (const constraint in error.constraints) { message += ` - Property: \`${error.property}\`\n`; message += ` Value: ${JSON.stringify(error.value)}\n`; message += ` Constraint: ${constraint}\n`; message += ` Expect: ${error.constraints[constraint]}\n`; } return message; }) .join('\n'); common_1.Logger.error(message, '@buka/nestjs-config'); throw new Error(message); } if (options.debug) { common_1.Logger.debug(`${ConfigProviderClass.name} initialized${constants_js_1.RESET_COLOR}\n${(0, util_1.inspect)(result, false, null, true)}`, '@buka/nestjs-config'); } this.providers.set(ConfigProviderClass, result); return result; } static async loadConfig(options = {}) { if (this.config !== null) return this.config; const configLoaders = (options.loaders || [(0, process_env_loader_js_1.processEnvLoader)(), '.env']) .map((c) => (typeof c === 'string' ? (0, dotenv_loader_js_1.dotenvLoader)(c) : c)); const configs = await Promise.all(configLoaders.map((loader) => loader(options))); const config = (0, object_keys_to_camel_case_js_1.objectKeysToCamelCase)((0, deep_merge_all_js_1.deepMergeAll)(configs)); this.config = config; return config; } static createConfigProviderFactory(configProvider) { return { provide: configProvider.target, inject: [config_module_definition_js_1.MODULE_OPTIONS_TOKEN, constants_js_1.MODULE_LOADED_CONFIG_TOKEN], useFactory: (options, config) => { const provider = this.providers.get(configProvider.target); if (provider) return provider; return this.createConfigProvider(options, config, configProvider); }, }; } static createLoadedConfigProviderFactory() { return { provide: constants_js_1.MODULE_LOADED_CONFIG_TOKEN, inject: [config_module_definition_js_1.MODULE_OPTIONS_TOKEN], useFactory: async (options) => this.loadConfig(options), }; } /** * Load config and provider before registering the module */ static async preload(options = {}) { const config = await this.loadConfig(options); const configProviders = configuration_registry_js_1.ConfigurationRegistry.getProviders(); await Promise.all(configProviders.map((provider) => this.createConfigProvider(options, config, provider))); } /** * Get the loaded config */ static get(ConfigProviderClass) { return this.providers.get(ConfigProviderClass); } static async getOrFail(ConfigProviderClass) { const config = await this.get(ConfigProviderClass); if (!config) { throw new Error(`[@buka/nestjs-config] ${ConfigProviderClass.name} Not Founded`); } return config; } static register(options) { const configProviders = configuration_registry_js_1.ConfigurationRegistry.getProviders(); const dynamicModule = super.register(options); dynamicModule.providers = [ ...(dynamicModule.providers || []), this.createLoadedConfigProviderFactory(), ...configProviders.map((provider) => this.createConfigProviderFactory(provider)), ]; dynamicModule.exports = [ ...(dynamicModule.exports || []), ...configProviders.map((provider) => provider.target), ]; return dynamicModule; } static registerAsync(options) { const configProviders = configuration_registry_js_1.ConfigurationRegistry.getProviders(); const dynamicModule = super.registerAsync(options); dynamicModule.providers = [ ...(dynamicModule.providers || []), this.createLoadedConfigProviderFactory(), ...configProviders.map((provider) => this.createConfigProviderFactory(provider)), ]; dynamicModule.exports = [ ...(dynamicModule.exports || []), ...configProviders.map((provider) => provider.target), ]; return dynamicModule; } static inject(provider, module, moduleAsyncOptionsOrFactory, optionsFactory) { let moduleAsyncOptions = undefined; let useFactory = (config) => config; if (typeof moduleAsyncOptionsOrFactory === 'function') { useFactory = moduleAsyncOptionsOrFactory; } else if (typeof moduleAsyncOptionsOrFactory === 'object') { moduleAsyncOptions = moduleAsyncOptionsOrFactory; } if (typeof optionsFactory === 'function') { useFactory = optionsFactory; } if ('registerAsync' in module && module.registerAsync) { return module.registerAsync({ ...moduleAsyncOptions, inject: [provider], useFactory, }); } if ('forRootAsync' in module && module.forRootAsync) { return module.forRootAsync({ ...moduleAsyncOptions, inject: [provider], useFactory, }); } throw new TypeError('Invalid module'); } }; exports.ConfigModule = ConfigModule; exports.ConfigModule = ConfigModule = __decorate([ (0, common_1.Module)({}) ], ConfigModule); });