You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					241 lines
				
				4.9 KiB
			
		
		
			
		
	
	
					241 lines
				
				4.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								# env-schema
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[](https://www.npmjs.com/package/env-schema)
							 | 
						||
| 
								 | 
							
								[](https://snyk.io/test/github/fastify/env-schema)
							 | 
						||
| 
								 | 
							
								[](https://coveralls.io/github/fastify/env-schema?branch=master)
							 | 
						||
| 
								 | 
							
								[](https://standardjs.com/)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Utility to check environment variables using [JSON schema](https://json-schema.org/), [Ajv](http://npm.im/ajv), and
							 | 
						||
| 
								 | 
							
								[dotenv](http://npm.im/dotenv).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Install
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm install --save env-schema
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Usage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const envSchema = require('env-schema')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schema = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: [ 'PORT' ],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    PORT: {
							 | 
						||
| 
								 | 
							
								      type: 'number',
							 | 
						||
| 
								 | 
							
								      default: 3000
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: schema,
							 | 
						||
| 
								 | 
							
								  data: data, // optional, default: process.env
							 | 
						||
| 
								 | 
							
								  dotenv: true // load .env if it is there, default: false
							 | 
						||
| 
								 | 
							
								  // or you can pass DotenvConfigOptions
							 | 
						||
| 
								 | 
							
								  // dotenv: {
							 | 
						||
| 
								 | 
							
								  //   path: '/custom/path/to/.env'
							 | 
						||
| 
								 | 
							
								  // }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								console.log(config)
							 | 
						||
| 
								 | 
							
								// output: { PORT: 3000 }
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								see [DotenvConfigOptions](https://github.com/motdotla/dotenv#options)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Custom ajv instance
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Optionally, the user can supply their own ajv instance:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const envSchema = require('env-schema')
							 | 
						||
| 
								 | 
							
								const Ajv = require('ajv')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schema = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: [ 'PORT' ],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    PORT: {
							 | 
						||
| 
								 | 
							
								      type: 'number',
							 | 
						||
| 
								 | 
							
								      default: 3000
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: schema,
							 | 
						||
| 
								 | 
							
								  data: data,
							 | 
						||
| 
								 | 
							
								  dotenv: true,
							 | 
						||
| 
								 | 
							
								  ajv: new Ajv({
							 | 
						||
| 
								 | 
							
								    allErrors: true,
							 | 
						||
| 
								 | 
							
								    removeAdditional: true,
							 | 
						||
| 
								 | 
							
								    useDefaults: true,
							 | 
						||
| 
								 | 
							
								    coerceTypes: true,
							 | 
						||
| 
								 | 
							
								    allowUnionTypes: true
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								console.log(config)
							 | 
						||
| 
								 | 
							
								// output: { PORT: 3000 }
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is possible to enhance the default ajv instance providing the `customOptions` function parameter.
							 | 
						||
| 
								 | 
							
								This example shows how to use the `format` keyword in your schemas.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: schema,
							 | 
						||
| 
								 | 
							
								  data: data,
							 | 
						||
| 
								 | 
							
								  dotenv: true,
							 | 
						||
| 
								 | 
							
								  ajv: {
							 | 
						||
| 
								 | 
							
								    customOptions (ajvInstance) {
							 | 
						||
| 
								 | 
							
								      require('ajv-formats')(ajvInstance)
							 | 
						||
| 
								 | 
							
								      return ajvInstance
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that it is mandatory returning the ajv instance.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Fluent-Schema API
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is also possible to use [fluent-json-schema](http://npm.im/fluent-json-schema):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const envSchema = require('env-schema')
							 | 
						||
| 
								 | 
							
								const S = require('fluent-json-schema')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: S.object().prop('port', S.number().default(3000).required()),
							 | 
						||
| 
								 | 
							
								  data: data, // optional, default: process.env
							 | 
						||
| 
								 | 
							
								  dotenv: true, // load .env if it is there, default: false
							 | 
						||
| 
								 | 
							
								  expandEnv: true, // use dotenv-expand, default: false
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								console.log(config)
							 | 
						||
| 
								 | 
							
								// output: { PORT: 3000 }
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**NB** Support for additional properties in the schema is disabled for this plugin, with the `additionalProperties` flag set to `false` internally.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Custom keywords
							 | 
						||
| 
								 | 
							
								This library supports the following Ajv custom keywords:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### `separator`
							 | 
						||
| 
								 | 
							
								Type: `string`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Applies to type: `string`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								When present, the provided schema value will be split on this value.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Example:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const envSchema = require('env-schema')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schema = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: [ 'ALLOWED_HOSTS' ],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    ALLOWED_HOSTS: {
							 | 
						||
| 
								 | 
							
								      type: 'string',
							 | 
						||
| 
								 | 
							
								      separator: ','
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const data = {
							 | 
						||
| 
								 | 
							
								  ALLOWED_HOSTS: '127.0.0.1,0.0.0.0'
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: schema,
							 | 
						||
| 
								 | 
							
								  data: data, // optional, default: process.env
							 | 
						||
| 
								 | 
							
								  dotenv: true // load .env if it is there, default: false
							 | 
						||
| 
								 | 
							
								}) 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// config.data => ['127.0.0.1', '0.0.0.0']
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The ajv keyword definition objects can be accessed through the property `keywords` on the `envSchema` function:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const envSchema = require('env-schema')
							 | 
						||
| 
								 | 
							
								const Ajv = require('ajv')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schema = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    names: {
							 | 
						||
| 
								 | 
							
								      type: 'string',
							 | 
						||
| 
								 | 
							
								      separator: ','
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema({
							 | 
						||
| 
								 | 
							
								  schema: schema,
							 | 
						||
| 
								 | 
							
								  data: data,
							 | 
						||
| 
								 | 
							
								  dotenv: true,
							 | 
						||
| 
								 | 
							
								  ajv: new Ajv({
							 | 
						||
| 
								 | 
							
								    allErrors: true,
							 | 
						||
| 
								 | 
							
								    removeAdditional: true,
							 | 
						||
| 
								 | 
							
								    useDefaults: true,
							 | 
						||
| 
								 | 
							
								    coerceTypes: true,
							 | 
						||
| 
								 | 
							
								    allowUnionTypes: true,
							 | 
						||
| 
								 | 
							
								    keywords: [envSchema.keywords.separator]
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								console.log(config)
							 | 
						||
| 
								 | 
							
								// output: { names: ['foo', 'bar'] }
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### TypeScript
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can specify the type of your `config`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```ts
							 | 
						||
| 
								 | 
							
								import envSchema from 'env-schema';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								interface Env {
							 | 
						||
| 
								 | 
							
								  PORT: number;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schema = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: [ 'PORT' ],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    PORT: {
							 | 
						||
| 
								 | 
							
								      type: 'number',
							 | 
						||
| 
								 | 
							
								      default: 3000
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const config = envSchema<Env>({
							 | 
						||
| 
								 | 
							
								  schema,
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If no type is specified the `config` will have the `EnvSchemaData` type.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```ts
							 | 
						||
| 
								 | 
							
								export type EnvSchemaData = {
							 | 
						||
| 
								 | 
							
								  [key: string]: unknown;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Acknowledgements
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Kindly sponsored by [Mia Platform](https://www.mia-platform.eu/) and
							 | 
						||
| 
								 | 
							
								[NearForm](https://nearform.com).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## License
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MIT
							 |