diff --git a/examples/httpbin.yml b/examples/httpbin.yml new file mode 100644 index 0000000..136c934 --- /dev/null +++ b/examples/httpbin.yml @@ -0,0 +1,19 @@ +version: 1 +endpoint: https://httpbin.org/ + +cookiejar: true + +GET /anything: + alias: anything + form: + name: David + params: + hello: World + +GET /cookies/set: + alias: set-cookies + params: + hello: World + +GET /status/418: + alias: teapot diff --git a/package-lock.json b/package-lock.json index 80589f4..4751112 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3435,6 +3435,21 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isemail": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.2.tgz", + "integrity": "sha512-zfRhJn9rFSGhzU5tGZqepRSAj3+g6oTOHxMGGriWNJZzyLPUK8H7VHpqKntegnW8KLyGA9zwuNaCoopl40LTpg==", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4288,6 +4303,23 @@ "merge-stream": "1.0.1" } }, + "joi": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.2.0.tgz", + "integrity": "sha512-VUzQwyCrmT2lIpxBCYq26dcK9veCQzDh84gQnCtaxCa8ePohX8JZVVsIb+E66kCUUcIvzeIpifa6eZuzqTZ3NA==", + "requires": { + "hoek": "5.0.3", + "isemail": "3.1.2", + "topo": "3.0.0" + }, + "dependencies": { + "hoek": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.3.tgz", + "integrity": "sha512-Bmr56pxML1c9kU+NS51SMFkiVQAb+9uFfXwyqR2tn4w2FPvmPt65eZ9aCcEfRXd9G74HkZnILC6p967pED4aiw==" + } + } + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -6819,6 +6851,21 @@ } } }, + "topo": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz", + "integrity": "sha512-Tlu1fGlR90iCdIPURqPiufqAlCZYzLjHYVVbcFWDMcX7+tK8hdZWAfsMrD/pBul9jqHHwFjNdf1WaxA9vTRRhw==", + "requires": { + "hoek": "5.0.3" + }, + "dependencies": { + "hoek": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.3.tgz", + "integrity": "sha512-Bmr56pxML1c9kU+NS51SMFkiVQAb+9uFfXwyqR2tn4w2FPvmPt65eZ9aCcEfRXd9G74HkZnILC6p967pED4aiw==" + } + } + }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", diff --git a/package.json b/package.json index 789ea7a..ccf5e1e 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "commander": "^2.15.1", "deepmerge": "^2.1.0", "dotenv": "^5.0.1", + "joi": "^13.2.0", "js-yaml": "^3.11.0", "jsome": "^2.5.0", "request": "^2.85.0", diff --git a/src/__tests__/__snapshots__/beau.spec.js.snap b/src/__tests__/__snapshots__/beau.spec.js.snap index 285efc8..668cae8 100644 --- a/src/__tests__/__snapshots__/beau.spec.js.snap +++ b/src/__tests__/__snapshots__/beau.spec.js.snap @@ -3,7 +3,6 @@ exports[`Beau's config Loader. should create a request list 1`] = ` Beau { "config": Config { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object { "headers": Object { @@ -45,7 +44,6 @@ Beau { "VERSION": 1, "configKeys": Array [ "VERSION", - "CACHE", "ENDPOINT", "PLUGINS", "DEFAULTS", @@ -54,7 +52,6 @@ Beau { "COOKIEJAR", ], "defaultConfigValues": Object { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object {}, "ENDPOINT": "", @@ -108,7 +105,6 @@ Beau { }, }, "config": Config { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object { "headers": Object { @@ -150,7 +146,6 @@ Beau { "VERSION": 1, "configKeys": Array [ "VERSION", - "CACHE", "ENDPOINT", "PLUGINS", "DEFAULTS", @@ -159,7 +154,6 @@ Beau { "COOKIEJAR", ], "defaultConfigValues": Object { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object {}, "ENDPOINT": "", diff --git a/src/__tests__/__snapshots__/config.spec.js.snap b/src/__tests__/__snapshots__/config.spec.js.snap index ea7c058..0cf6434 100644 --- a/src/__tests__/__snapshots__/config.spec.js.snap +++ b/src/__tests__/__snapshots__/config.spec.js.snap @@ -2,7 +2,6 @@ exports[`Config should load multiple hosts 1`] = ` Config { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object { "HEADERS": Object { @@ -113,7 +112,6 @@ Config { "VERSION": 1, "configKeys": Array [ "VERSION", - "CACHE", "ENDPOINT", "PLUGINS", "DEFAULTS", @@ -122,7 +120,6 @@ Config { "COOKIEJAR", ], "defaultConfigValues": Object { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object {}, "ENDPOINT": "", @@ -176,7 +173,6 @@ Config { exports[`Config should set up defaults for all requests 1`] = ` Config { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object { "HEADERS": Object { @@ -218,7 +214,6 @@ Config { "VERSION": 1, "configKeys": Array [ "VERSION", - "CACHE", "ENDPOINT", "PLUGINS", "DEFAULTS", @@ -227,7 +222,6 @@ Config { "COOKIEJAR", ], "defaultConfigValues": Object { - "CACHE": false, "COOKIEJAR": false, "DEFAULTS": Object {}, "ENDPOINT": "", diff --git a/src/__tests__/config.spec.js b/src/__tests__/config.spec.js index 921c923..6e4d52f 100644 --- a/src/__tests__/config.spec.js +++ b/src/__tests__/config.spec.js @@ -6,13 +6,11 @@ describe('Config', () => { const doc = yaml.safeLoad(` version: 1 endpoint: http://martianwabbit.com - cache: false shouldntBeAdded: true `); const config = new Config(doc); expect(config.ENDPOINT).toBe(doc.endpoint); - expect(config.CACHE).toBe(doc.cache); expect(config.VERSION).toBe(doc.version); expect(config.shouldntBeAdded).toBeUndefined(); }); diff --git a/src/config.js b/src/config.js index 0d9ee3f..6b4709e 100644 --- a/src/config.js +++ b/src/config.js @@ -6,7 +6,6 @@ class Config { constructor(doc, env = {}) { this.defaultConfigValues = { VERSION: 1, - CACHE: false, ENDPOINT: '', PLUGINS: [], DEFAULTS: {}, diff --git a/src/schema.js b/src/schema.js new file mode 100644 index 0000000..cdd7967 --- /dev/null +++ b/src/schema.js @@ -0,0 +1,56 @@ +const Joi = require('joi'); +const { requestRegex } = require('./shared.js'); + +const requestSchema = [ + Joi.object() + .keys({ + HEADERS: Joi.object().keys(null), + PAYLOAD: [Joi.object().keys(null), Joi.string()], + PARAMS: Joi.object().keys(null), + FORM: Joi.object().keys(null), + ALIAS: Joi.string().required() + }) + .rename(/headers/i, 'HEADERS', { override: true }) + .rename(/payload/i, 'PAYLOAD', { override: true }) + .rename(/params/i, 'PARAMS', { override: true }) + .rename(/form/i, 'FORM', { override: true }) + .rename(/alias/i, 'ALIAS', { override: true }), + + Joi.string() +]; + +const hostSchema = Joi.object() + .keys({ + HOST: Joi.string().required(), + ENDPOINT: Joi.string(), + DEFAULTS: Joi.object().keys(null) + }) + .pattern(requestRegex, requestSchema) + .rename(/host/i, 'HOST', { override: true }) + .rename(/defaults/i, 'DEFAULTS', { override: true }) + .rename(/endpoint/i, 'ENDPOINT', { override: true }); + +const schema = Joi.object() + .keys({ + VERSION: Joi.number().integer(), + ENDPOINT: Joi.string().uri(), + PLUGINS: Joi.array().items([Joi.string(), Joi.object().keys(null)]), + DEFAULTS: Joi.object(), + ENVIRONMENT: Joi.object(), + HOSTS: Joi.array().items(hostSchema), + COOKIEJAR: Joi.boolean() + }) + .pattern(requestRegex, requestSchema) + .rename(/version/i, 'VERSION', { override: true }) + .rename(/endpoint/i, 'ENDPOINT', { override: true }) + .rename(/hosts/i, 'HOSTS', { override: true }) + .rename(/plugins/i, 'PLUGINS', { override: true }) + .rename(/defaults/i, 'DEFAULTS', { override: true }) + .rename(/environment/i, 'ENVIRONMENT', { override: true }) + .rename(/cookiejar/i, 'COOKIEJAR', { override: true }); + +const validate = function(config) { + return Joi.validate(config, schema, { allowUnknown: true }); +}; + +module.exports = { schema, validate };