Skip to content

Commit

Permalink
Merge 615ea23 into 004d80e
Browse files Browse the repository at this point in the history
  • Loading branch information
Eomm committed Nov 7, 2021
2 parents 004d80e + 615ea23 commit 436ae60
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 9 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ console.log(config)

see [DotenvConfigOptions](https://github.com/motdotla/dotenv#options)

### Custom ajv instance

Optionally, the user can supply their own ajv instance:

```js
Expand Down Expand Up @@ -81,6 +83,27 @@ 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
Expand Down
35 changes: 26 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,7 @@ const optsSchema = {
}
}

const sharedAjvInstance = new Ajv({
allErrors: true,
removeAdditional: true,
useDefaults: true,
coerceTypes: true,
allowUnionTypes: true,
keywords: [separator]
})
const sharedAjvInstance = getDefaultInstance()

const optsSchemaValidator = sharedAjvInstance.compile(optsSchema)

Expand Down Expand Up @@ -93,7 +86,7 @@ function loadAndValidateEnvironment (_opts) {
const merge = {}
data.forEach(d => Object.assign(merge, d))

const ajv = opts.ajv == null ? sharedAjvInstance : opts.ajv
const ajv = chooseAjvInstance(sharedAjvInstance, opts.ajv)

const valid = ajv.validate(schema, merge)
if (!valid) {
Expand All @@ -105,6 +98,30 @@ function loadAndValidateEnvironment (_opts) {
return merge
}

function chooseAjvInstance (defaultInstance, ajvOpts) {
if (!ajvOpts) {
return defaultInstance
} else if (typeof ajvOpts === 'object' && typeof ajvOpts.customOptions === 'function') {
const ajv = ajvOpts.customOptions(getDefaultInstance())
if (!ajv) {
throw new Error('customOptions function must return an instance of Ajv')
}
return ajv
}
return ajvOpts
}

function getDefaultInstance () {
return new Ajv({
allErrors: true,
removeAdditional: true,
useDefaults: true,
coerceTypes: true,
allowUnionTypes: true,
keywords: [separator]
})
}

module.exports = loadAndValidateEnvironment
module.exports.default = loadAndValidateEnvironment
module.exports.envSchema = loadAndValidateEnvironment
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"homepage": "https://github.com/fastify/env-schema#readme",
"devDependencies": {
"ajv-formats": "^2.1.1",
"fluent-json-schema": "^3.0.0",
"pre-commit": "^1.2.2",
"snazzy": "^9.0.0",
Expand Down
48 changes: 48 additions & 0 deletions test/custom-ajv.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,51 @@ const strictValidator = new Ajv({
makeTest(t, options, testConf.isOk, testConf.confExpected, testConf.errorMessage)
})
})

t.test('ajv enhancement', t => {
t.plan(2)
const testCase = {
schema: {
type: 'object',
required: ['MONGODB_URL'],
properties: {
MONGODB_URL: {
type: 'string',
format: 'uri'
}
}
},
data: [{ PORT: 3333 }, { MONGODB_URL: 'mongodb://localhost/pippo' }],
isOk: true,
confExpected: {
MONGODB_URL: 'mongodb://localhost/pippo'
}
}

t.test('return', t => {
const options = {
schema: testCase.schema,
data: testCase.data,
ajv: {
customOptions (ajvInstance) {
require('ajv-formats')(ajvInstance)
return ajvInstance
}
}
}
makeTest(t, options, testCase.isOk, testCase.confExpected)
})

t.test('no return', t => {
const options = {
schema: testCase.schema,
data: testCase.data,
ajv: {
customOptions (ajvInstance) {
// do nothing
}
}
}
makeTest(t, options, false, undefined, 'customOptions function must return an instance of Ajv')
})
})

0 comments on commit 436ae60

Please sign in to comment.