Gathering detailed insights and metrics for omniconfig.js
Gathering detailed insights and metrics for omniconfig.js
Gathering detailed insights and metrics for omniconfig.js
Gathering detailed insights and metrics for omniconfig.js
npm install omniconfig.js
Typescript
Module System
Node Version
NPM Version
TypeScript (99.77%)
Shell (0.21%)
JavaScript (0.02%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
3 Stars
72 Commits
1 Forks
1 Watchers
1 Branches
1 Contributors
Updated on Aug 07, 2024
Latest Version
1.2.0
Package Id
omniconfig.js@1.2.0
Unpacked Size
159.89 kB
Size
35.32 kB
File Count
115
NPM Version
9.8.1
Node Version
20.4.0
Published on
Aug 09, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
OmniConfig is a universal runtime configuration loader and validator.
Define schema and configuration sources. Use merged and valid configuration object for your application.
Key features:
Load and merge configuration (in order) from .env
, .env.local
and process.env
.
Use APP_
prefix for environment variables. Validate merged object using Yup.
1import * as yup from 'yup' 2import OmniConfig from 'omniconfig.js' 3 4const schema = yup.object({ 5 debug: yup.boolean().default(false), 6 7 db: yup.object({ 8 host: yup.string().required(), 9 port: yup.number().min(0).default(5432), 10 user: yup.string().required(), 11 pass: yup.string() 12 }) 13}) 14 15const config = OmniConfig 16 .withYup(schema) 17 .useEnvironmentVariables({ 18 processEnv: true, 19 envMapper: { prefix: 'APP_' }, 20 dotEnv: '.env[.local]', 21 }) 22 .resolveSync() 23 24console.log(config)
Get normalized and merged config object - like this:
1{ 2 debug: true, 3 db: { 4 host: 'localhost', 5 port: 5432, 6 user: 'some_user', 7 pass: 'foo' 8 }, 9}
...or meaningful error messages:
Missing value:
Configuration error: db.user is a required field The value can be defined in: - .env as APP_DB_USER - .env.local as APP_DB_USER - Environment variables as APP_DB_USER
Invalid value:
Configuration error: db.port must be greater than or equal to 0 The causing value is defined in .env.local as APP_DB_PORT
Check full code of this example.
You can find more examples in examples directory.
.withModel(model?: Model): OmniConfig
.useLoader(loader: Loader): OmniConfig
.useOptionalLoader(loader: Loader): OmniConfig
.withYup(schema: yup.ObjectSchema, options?: yup.ValidateOptions): OmniConfig
.withJsonSchema(schema: ajv.JSONSchemaType, options?: ajv.Options, context?: ajv.DataValidationCxt): OmniConfig
.withJTDSchema(schema: ajv.JDTSchema, options?: ajv.JTDOptions, context?: ajv.DataValidationCxt): OmniConfig
.useEnvironmentVariables(options?: OmniConfigEnvOptions): OmniConfig
.useJsonFiles(templateOrOptions: string | ConfigFileVariantFn | OmniConfigFileOptions): OmniConfig
.useYamlFiles(template: string | ConfigFileVariantFn | OmniConfigFileOptions): OmniConfig
.useJsFiles(template: string | ConfigFileVariantFn): OmniConfig
.resolve(options?: OmniConfigResolveOptions): Promise<Config>
.resolveSync(options?: OmniConfigResolveOptions): Config
1npm i omniconfig.js --save # this library 2 3npm i dotenv --save # optional .env file support 4npm i js-yaml --save # optional YAML file support 5npm i yup --save # optional Yup support 6npm i ajv --save # optional JSON schema and JDT schema support 7npm i chalk@^4.1.2 --save # optional error message coloring
or
1yarn add omniconfig.js # this library 2 3yarn add dotenv # optional .env file support 4yarn add js-yaml # optional YAML file support 5yarn add yup # optional Yup support 6yarn add ajv # optional JSON schema and JDT schema support 7yarn add chalk@^4.1.2 # optional error message coloring
High level class with builder-like API.
1import { OmniConfig } from 'omniconfig.js' 2 3const config = new OmniConfig() 4 .withModel(/*...*/) 5 .useLoader(/*...*/) 6 .useLoader(/*...*/) 7 // ...
Ready-to-use instance if also exported using a default export.
1import OmniConfig from 'omniconfig.js' 2 3const config = OmniConfig 4 .withModel(/*...*/) 5 .useLoader(/*...*/) 6 .useLoader(/*...*/) 7 // ...
.withModel(model?: Model): OmniConfig
Set model to validate configuration against. If model is not set, validation will not be performed. You can use one of built-in models like YupModel or AjvModel or create a custom one. Check the Model interface for the details.
.useLoader(loader: Loader): OmniConfig
Adds new loader to the end of loader list. Values loaded with it overwrite the previously loaded values.
Built-in loaders:
.useOptionalLoader(loader: Loader): OmniConfig
Adds new optional loader to the end of loader list. Values loaded with it overwrite the previously loaded values.
.withYup(schema: yup.ObjectSchema, options?: yup.ValidateOptions): OmniConfig
Required dependency: Yup
Sets Yup object schema as a validation model. Dynamic schemas are not supported.
1import * as yup from 'yup' 2import OmniConfig from 'omniconfig.js' 3 4const schema = yup.object({ 5 debug: yup.boolean().default(false), 6 7 db: yup.object({ 8 host: yup.string().required(), 9 port: yup.number().min(0).default(5432), 10 user: yup.string().required(), 11 pass: yup.string() 12 }) 13}) 14 15const config = OmniConfig 16 .withYup(schema) 17 // ...
.withJsonSchema(schema: ajv.JSONSchemaType, options?: ajv.Options, context?: ajv.DataValidationCxt): OmniConfig
Required dependency: Ajv
Sets JSON schema as a validation model. Using following default options for Ajv:
1{ 2 coerceTypes: true, 3 useDefaults: true, 4 removeAdditional: true, 5}
Example that uses Ajv default JSON schema version:
1import OmniConfig from 'omniconfig.js' 2 3interface Config { 4 debug: boolean 5 db: { 6 host: string 7 port: number 8 user: string 9 pass?: string 10 } 11} 12 13const config = OmniConfig 14 .withJsonSchema<Config>({ 15 type: 'object', 16 required: ['db'], 17 18 properties: { 19 debug: { 20 type: 'boolean', 21 default: false, 22 }, 23 24 db: { 25 type: 'object', 26 required: ['host', 'user', 'port'], 27 28 properties: { 29 host: { type: 'string' }, 30 port: { type: 'number', default: 5432 }, 31 user: { type: 'string' }, 32 pass: { type: 'string', nullable: true }, 33 } 34 } 35 } 36 })
You can also customize Ajv behaviour (change schema, add keywords, etc...):
1import Ajv from 'ajv' 2import OmniConfig from 'omniconfig.js' 3import { AjvModel } from './ajvModel' 4 5const ajv = new Ajv({ 6 // your options 7}) 8 9ajv.addSchema(/*...*/) 10ajv.addFormat(/*...*/) 11ajv.addKeyword(/*...*/) 12 13const customFn = ajv.compile({ 14 // your schema 15}) 16 17const config = OmniConfig 18 .withModel(new AjvModel({ fn: customFn }))
.withJTDSchema(schema: ajv.JDTSchema, options?: ajv.JTDOptions, context?: ajv.DataValidationCxt): OmniConfig
Required dependency: Ajv
Sets JTD schema as a validation model.
.useValue(value: object, sourceOrFrameIndex?: string | number): OmniConfig
Loads configuration from a static value.
The library will attempt to determine file name and line number where this method is called using a stack trace.
You can specify number of stack frames to skip (e.g. if you can some additional facade) or specify the source name as a string.
1import OmniConfig from 'omniconfig.js' 2 3const config = OmniConfig 4 //... 5 .useValue({ 6 myOption: 'myValue', 7 8 some: { 9 nested: { 10 value: true, 11 } 12 } 13 }) 14//...
.useEnvironmentVariables(options?: OmniConfigEnvOptions): OmniConfig
Loads configuration from environment variables and optionally .env files.
Default options:
1{ 2 processEnv: true, 3 4 // MetadataBasedEnvMapperOptions 5 envMapper: { 6 prefix: '', 7 separator: '_', 8 wordSeparator: '_', 9 } 10}
processEnv: boolean = true
Enables (default) or disables loading configuration from process environment variables (`process.env). When enables, this loader is always added after .env files, so process environment variables always overwrite variables from .env files.
1import OmniConfig from 'omniconfig.js' 2 3const config = OmniConfig 4 //... 5 .useEnvironmentVariables({ processEnv: true }) // same as .useEnvironmentVariables() 6 //...
dotEnv: true | string | ConfigFileVariantFn
Required dependency: dotenv
Enable loading of .env files. Supports following value:
true
- load only .env
file from current working directorystring
- file name template for .env files (syntax)ConfigFileVariantFn
- function returns path to file for given context1import OmniConfig from 'omniconfig.js'
2
3const config = OmniConfig
4 //...
5 .useEnvironmentVariables({
6 dotenv: '.env[.local]'
7 // dotenv: true
8 // dotenv: ({ local, dist, nodeEnv }) => local ? '.env.very-custom-local-name' : `.env`
9 })
10//...
envMapper: EnvMapper | Partial<MetadataBasedEnvMapperOptions>
Accepts environment variable mapper instance or options for MetadataBasedEnvMapper.
By default, MetadataBasedEnvMapper is used. This mapper leverages metadata generated from the model (both Yup and Ajv support it) to map environment variables to configuration object keys. This approach allows to use same separator for configuration levels and camelcase names.
1import * as yup from 'yup' 2import OmniConfig from 'omniconfig.js' 3 4const schema = yup.object({ 5 db: yup.object({ 6 host: yup.string().required(), 7 // ... 8 }), 9 10 someService: yup.object({ 11 nestedSection: yup.object({ 12 option: yup.number(), 13 }) 14 }), 15}) 16 17 18const config = OmniConfig 19 20 // Reads following environment variables names and maps to the above schema: 21 // - DB_HOST 22 // - SOME_SERVICE_NESTED_SECTION_OPTION 23 24 .useEnvironmentVariables({ 25 envMapper: { 26 prefix: '', // defaults 27 separator: '_', 28 wordSeparator: '_', 29 } 30 }) 31 //... 32 33const config2 = OmniConfig 34 35 // Reads following environment variables names and maps to the above schema: 36 // - APP__DB__HOST 37 // - APP__SOME_SERVICE__NESTED_SECTION__OPTION 38 39 .useEnvironmentVariables({ 40 envMapper: { 41 prefix: 'APP__', 42 separator: '__', 43 wordSeparator: '_', 44 } 45 }) 46 //...
Alternatively, you can use mappers that does not rely on the metadata (so you can use dynamic schemas):
.useJsonFiles(templateOrOptions: string | ConfigFileVariantFn | OmniConfigFileOptions): OmniConfig
Loads configuration from JSON files.
template: string | ConfigFileVariantFn
As the template, you can pass:
string
- file name template for JSON files (syntax)ConfigFileVariantFn
- function returns path to file for given contextsection?: string | string[]
Optional section of file to load. Useful to load options from a key of package.json
.
Section can be provided as:
string
- dot separated list of properties (like foo.bar
to load property bar
that is nested in property foo
)string[]
- where each element represents property (like ['foo', 'bar']
to load property bar
that is nested in property foo
)1import OmniConfig from 'omniconfig.js'
2
3const config = OmniConfig
4 //...
5
6 // load JSON files with NODE_ENV based variants and dist variants
7 .useJsonFiles('config/app[.node_env].json[.dist]')
8
9 // load JSON files returned by a custom function
10 .useJsonFiles({
11 template: ({ local, dist, nodeEnv }) => local ? 'very-custom-local-name.json' : 'app.json',
12 })
13
14 // load configuration from `custom.myApp` in `package.json`
15 .useJsonFiles({
16 template: 'package.json',
17 section: 'custom.myApp', // same as ['custom', 'myApp']
18 })
19 //...
.useYamlFiles(template: string | ConfigFileVariantFn | OmniConfigFileOptions): OmniConfig
Required dependency: js-yaml
Loads configuration from YAML files.
template: string | ConfigFileVariantFn
As the template, you can pass:
string
- file name template for YAML files (syntax)ConfigFileVariantFn
- function returns path to file for given contextsection?: string | string[]
Optional section of file to load. Useful to load options from a nested property of the file.
Section can be provided as:
string
- dot separated list of properties (like foo.bar
to load property bar
that is nested in property foo
)string[]
- where each element represents property (like ['foo', 'bar']
to load property bar
that is nested in property foo
)1import OmniConfig from 'omniconfig.js'
2
3const config = OmniConfig
4 //...
5
6 // load YAML files with NODE_ENV based variants and dist variants
7 .useYamlFiles('config/app[.node_env].yml[.dist]')
8
9 // load YAML files returned by a custom function
10 .useYamlFiles({
11 template: ({ local, dist, nodeEnv }) => local ? 'very-custom-local-name.yml' : 'app.yml',
12 })
13
14 // load options from `someKey` of `app.yml` file
15 .useYamlFiles({
16 template: 'app.yml',
17 section: 'someKey' // same as ['someKey']
18 })
19 //...
.useJsFiles(template: string | ConfigFileVariantFn): OmniConfig
Loads configuration from JavaScript files.
As the template, you can pass:
string
- file name template for JS files (syntax)ConfigFileVariantFn
- function returns path to file for given contextJS file path should be absolute or relative to the current working directory.
1import OmniConfig from 'omniconfig.js' 2 3const config = OmniConfig 4 //... 5 .useJsFiles('config/app[.node_env].js[.dist]') 6 //.useJsFiles(({ local, dist, nodeEnv }) => local ? 'very-custom-local-name.js' : 'app.js') 7 //...
.resolve(options?: OmniConfigResolveOptions): Promise<Config>
Asynchronously loads, merges, and validates configuration object. Optionally prints a formatted error message in the console.
logger: OmniConfigResolveErrorLogger
Logger instance used to print error messages.
Default: console
formatter: ErrorFormatter
Instance of error formatter that formats validation error before it is passed to the logger.
Default: ChalkErrorFormatter
if chalk
is available, otherwise: TextErrorFormatter
exitCode: number
Exit code. If provided, will be passed to process.exit()
.
Otherwise, process.exit()
will not be called.
Default: undefined
.resolveSync(options?: OmniConfigResolveOptions): Config
Synchronously loads, merges, and validates configuration object. Optionally prints a formatted error message in the console.
See .resolve()
for options reference.
File name templates allows to customize source file name, location and variants that should be loaded.
Templates support following placeholders:
[local]
- for local file variant (loaded AFTER the main file)[dist]
- for dist file variant (loaded BEFORE the main file)[node_env]
- environment-specific file variant (basing on process.env.NODE_ENV
variable)Additionally, you can add an arbitrary character after [
or before ]
that should be inserted in the final name.
Examples:
template .env
loads:
.env
template .env[.local]
loads:
.env
.env.local
template app.json[.dist]
loads:
app.json.dist
app.json
template app[.node_env].json
loads:
app.json
app.development.json
(if NODE_ENV=development
)template config/[node_env.]app[.local].yml
loads:
config/app.yml
config/app.local.yml
config/development.app.yml
(if NODE_ENV=development
)config/development.app.local.yml
(if NODE_ENV=development
)No vulnerabilities found.
No security vulnerabilities found.