From 59f85fac8c8117d72ea0c1faec4d5c3e97c62721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20D=C3=ADaz?= Date: Fri, 4 May 2018 11:47:28 -0600 Subject: [PATCH] Reindenting. (#17) I normally prefer tabs for everything, it's nice to have the ability to set to whatever your preferred width is. Since this project uses a lot of yaml stuff I've had to indent those tests with spaces, for consistency's sake I've decided to use spaces everywhere. --- .prettierrc | 3 +- src/__mocks__/beau-dynamic-values.js | 12 +- src/__mocks__/beau-modifiers.js | 28 +-- src/__mocks__/request-promise-native.js | 30 +-- src/__mocks__/requireg.js | 2 +- src/__tests__/config.spec.js | 78 ++++---- src/__tests__/request.spec.js | 120 ++++++------ src/__tests__/requestCache.spec.js | 142 +++++++-------- src/__tests__/requestList.spec.js | 118 ++++++------ src/beau.js | 8 +- src/config.js | 138 +++++++------- src/plugins.js | 130 ++++++------- src/request.js | 232 ++++++++++++------------ src/requestCache.js | 64 +++---- src/requestList.js | 84 ++++----- src/schema.js | 122 ++++++------- src/shared.js | 100 +++++----- 17 files changed, 706 insertions(+), 705 deletions(-) diff --git a/.prettierrc b/.prettierrc index bec9904..e6bb537 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,7 @@ printWidth: 80 +tabWidth: 4 singleQuote: true -useTabs: true +useTabs: false trailingComma: none bracketSpacing: true jsxBracketSameLine: true diff --git a/src/__mocks__/beau-dynamic-values.js b/src/__mocks__/beau-dynamic-values.js index 2462e19..04d9c31 100644 --- a/src/__mocks__/beau-dynamic-values.js +++ b/src/__mocks__/beau-dynamic-values.js @@ -1,11 +1,11 @@ class DynamicValues { - constructor(registry, settings = {}) { - registry.defineDynamicValue('add', this.add); - } + constructor(registry, settings = {}) { + registry.defineDynamicValue('add', this.add); + } - add(x, y) { - return x + y; - } + add(x, y) { + return x + y; + } } module.exports = DynamicValues; diff --git a/src/__mocks__/beau-modifiers.js b/src/__mocks__/beau-modifiers.js index 007a27c..4cbdd2e 100644 --- a/src/__mocks__/beau-modifiers.js +++ b/src/__mocks__/beau-modifiers.js @@ -1,20 +1,20 @@ class Modifiers { - constructor(registry, settings = {}) { - registry.addPreRequestModifier(this.preRequest); - registry.addPostRequestModifier(this.postRequest); - } + constructor(registry, settings = {}) { + registry.addPreRequestModifier(this.preRequest); + registry.addPostRequestModifier(this.postRequest); + } - preRequest(request, orig) { - request.headers = request.headers || {}; - request.headers.preRequestModifier = true; - return request; - } + preRequest(request, orig) { + request.headers = request.headers || {}; + request.headers.preRequestModifier = true; + return request; + } - postRequest(response, orig) { - response.body = 'Hello World'; - response.response.body = 'Hello World'; - return response; - } + postRequest(response, orig) { + response.body = 'Hello World'; + response.response.body = 'Hello World'; + return response; + } } module.exports = Modifiers; diff --git a/src/__mocks__/request-promise-native.js b/src/__mocks__/request-promise-native.js index 520b6ce..aa51a00 100644 --- a/src/__mocks__/request-promise-native.js +++ b/src/__mocks__/request-promise-native.js @@ -1,20 +1,20 @@ function Request(request) { - if (Request.fail) { - throw new Error(); - } + if (Request.fail) { + throw new Error(); + } - return { - request: { - headers: request.headers, - body: request.body, - uri: { - href: `${request.baseUrl}${request.uri}` - } - }, - statusCode: 200, - headers: [], - body: '{"hello": "world"}' - }; + return { + request: { + headers: request.headers, + body: request.body, + uri: { + href: `${request.baseUrl}${request.uri}` + } + }, + statusCode: 200, + headers: [], + body: '{"hello": "world"}' + }; } Request.fail = false; diff --git a/src/__mocks__/requireg.js b/src/__mocks__/requireg.js index b5225a5..c31f69d 100644 --- a/src/__mocks__/requireg.js +++ b/src/__mocks__/requireg.js @@ -1,3 +1,3 @@ module.exports = function(name) { - return require(name); + return require(name); }; diff --git a/src/__tests__/config.spec.js b/src/__tests__/config.spec.js index 6e4d52f..cd437f6 100644 --- a/src/__tests__/config.spec.js +++ b/src/__tests__/config.spec.js @@ -2,21 +2,21 @@ const yaml = require('js-yaml'); const Config = require('../config'); describe('Config', () => { - it('should load valid config keys', () => { - const doc = yaml.safeLoad(` + it('should load valid config keys', () => { + const doc = yaml.safeLoad(` version: 1 endpoint: http://martianwabbit.com shouldntBeAdded: true `); - const config = new Config(doc); - expect(config.ENDPOINT).toBe(doc.endpoint); - expect(config.VERSION).toBe(doc.version); - expect(config.shouldntBeAdded).toBeUndefined(); - }); + const config = new Config(doc); + expect(config.ENDPOINT).toBe(doc.endpoint); + expect(config.VERSION).toBe(doc.version); + expect(config.shouldntBeAdded).toBeUndefined(); + }); - it('should load requests', () => { - const doc = yaml.safeLoad(` + it('should load requests', () => { + const doc = yaml.safeLoad(` endpoint: http://example.com GET /profile: get-profile @@ -28,12 +28,12 @@ describe('Config', () => { hello: world `); - const config = new Config(doc); - expect(Object.keys(config.REQUESTS).length).toBe(4); - }); + const config = new Config(doc); + expect(Object.keys(config.REQUESTS).length).toBe(4); + }); - it('should set up defaults for all requests', () => { - const doc = yaml.safeLoad(` + it('should set up defaults for all requests', () => { + const doc = yaml.safeLoad(` version: 1 endpoint: 'http://jsonplaceholder.typicode.com' @@ -48,16 +48,16 @@ describe('Config', () => { hello: world `); - const config = new Config(doc); + const config = new Config(doc); - expect(config).toMatchSnapshot(); - Object.values(config.REQUESTS).forEach(r => { - expect(r.HEADERS.authentication).toMatch('hello'); + expect(config).toMatchSnapshot(); + Object.values(config.REQUESTS).forEach(r => { + expect(r.HEADERS.authentication).toMatch('hello'); + }); }); - }); - it('should load multiple hosts', () => { - const doc = yaml.safeLoad(` + it('should load multiple hosts', () => { + const doc = yaml.safeLoad(` endpoint: http://example.org defaults: @@ -95,13 +95,13 @@ describe('Config', () => { GET /posts: posts `); - let config = new Config(doc); + let config = new Config(doc); - expect(config).toMatchSnapshot(); - }); + expect(config).toMatchSnapshot(); + }); - it('should namespace all aliases within an host', () => { - const doc = yaml.safeLoad(` + it('should namespace all aliases within an host', () => { + const doc = yaml.safeLoad(` hosts: - host: test1 endpoint: http://example.com @@ -111,14 +111,14 @@ describe('Config', () => { GET /posts: posts `); - let config = new Config(doc); + let config = new Config(doc); - expect(config.REQUESTS[0].ALIAS).toBe('test1:posts'); - expect(config.REQUESTS[1].ALIAS).toBe('test2:posts'); - }); + expect(config.REQUESTS[0].ALIAS).toBe('test1:posts'); + expect(config.REQUESTS[1].ALIAS).toBe('test2:posts'); + }); - it(`should throw if host doesn't have a host key`, () => { - const doc = yaml.safeLoad(` + it(`should throw if host doesn't have a host key`, () => { + const doc = yaml.safeLoad(` hosts: - endpoint: http://example.com GET /posts: posts @@ -128,11 +128,11 @@ describe('Config', () => { GET /posts: posts `); - expect(() => new Config(doc)).toThrow(); - }); + expect(() => new Config(doc)).toThrow(); + }); - it(`should merge host settings with global settings`, () => { - const doc = yaml.safeLoad(` + it(`should merge host settings with global settings`, () => { + const doc = yaml.safeLoad(` defaults: headers: hello: 1 @@ -150,7 +150,7 @@ describe('Config', () => { GET /posts: posts `); - let config = new Config(doc); - expect(config.REQUESTS[0].HEADERS.hello).toBe(1); - }); + let config = new Config(doc); + expect(config.REQUESTS[0].HEADERS.hello).toBe(1); + }); }); diff --git a/src/__tests__/request.spec.js b/src/__tests__/request.spec.js index 652b54c..79eeac1 100644 --- a/src/__tests__/request.spec.js +++ b/src/__tests__/request.spec.js @@ -4,74 +4,74 @@ const RequestList = require('../requestList'); const requestPromiseNativeMock = require('request-promise-native'); describe('Request', () => { - let cache; - let validRequestConfig; - let invalidRequestConfig; - let request; - let requestWithoutDependencies; + let cache; + let validRequestConfig; + let invalidRequestConfig; + let request; + let requestWithoutDependencies; - beforeEach(() => { - validRequestConfig = { - request: 'POST /user', - endpoint: 'http://martianwabbit.com', - alias: 'update', - params: { - userId: '$profile.UserId' - }, - headers: { - authentication: 'BEARER $session.token' - }, - payload: { - username: 'seich' - } - }; + beforeEach(() => { + validRequestConfig = { + request: 'POST /user', + endpoint: 'http://martianwabbit.com', + alias: 'update', + params: { + userId: '$profile.UserId' + }, + headers: { + authentication: 'BEARER $session.token' + }, + payload: { + username: 'seich' + } + }; - invalidRequestConfig = { - request: `POST /session`, - endpoint: 'http://martianwabbit.com' - }; + invalidRequestConfig = { + request: `POST /session`, + endpoint: 'http://martianwabbit.com' + }; - cache = new RequestCache(); - cache.add('session', { token: 'abc123' }); - cache.add('profile', { UserId: 14 }); + cache = new RequestCache(); + cache.add('session', { token: 'abc123' }); + cache.add('profile', { UserId: 14 }); - request = new Request(validRequestConfig); - requestWithoutDependencies = new Request({ - endpoint: 'http://martianwabbit.com', - request: 'GET /user', - alias: 'show' - }); + request = new Request(validRequestConfig); + requestWithoutDependencies = new Request({ + endpoint: 'http://martianwabbit.com', + request: 'GET /user', + alias: 'show' + }); - requestPromiseNativeMock.fail = false; - }); + requestPromiseNativeMock.fail = false; + }); - it('should load up the given request', () => { - expect(request.VERB).toBe('POST'); - expect(request.ENDPOINT).toBe(validRequestConfig.endpoint); - expect(request.HEADERS).toBeDefined(); - expect(request.PAYLOAD).toBeDefined(); - expect(request.PARAMS).toBeDefined(); - }); + it('should load up the given request', () => { + expect(request.VERB).toBe('POST'); + expect(request.ENDPOINT).toBe(validRequestConfig.endpoint); + expect(request.HEADERS).toBeDefined(); + expect(request.PAYLOAD).toBeDefined(); + expect(request.PARAMS).toBeDefined(); + }); - it('should throw if a given request is invalid', () => { - expect(() => new Request(invalidRequestConfig)).toThrow(); - }); + it('should throw if a given request is invalid', () => { + expect(() => new Request(invalidRequestConfig)).toThrow(); + }); - it('should list all of its dependencies', () => { - expect(request.DEPENDENCIES.size).toBe(2); - expect(request.DEPENDENCIES).toContain('session'); - expect(request.DEPENDENCIES).toContain('profile'); - }); + it('should list all of its dependencies', () => { + expect(request.DEPENDENCIES.size).toBe(2); + expect(request.DEPENDENCIES).toContain('session'); + expect(request.DEPENDENCIES).toContain('profile'); + }); - it('should execute a request', async () => { - await expect(request.exec(cache)).resolves.toMatchSnapshot(); - await expect( - requestWithoutDependencies.exec() - ).resolves.toMatchSnapshot(); - }); + it('should execute a request', async () => { + await expect(request.exec(cache)).resolves.toMatchSnapshot(); + await expect( + requestWithoutDependencies.exec() + ).resolves.toMatchSnapshot(); + }); - it('should throw if the request fails', async () => { - requestPromiseNativeMock.fail = true; - await expect(requestWithoutDependencies.exec()).rejects.toThrow(Error); - }); + it('should throw if the request fails', async () => { + requestPromiseNativeMock.fail = true; + await expect(requestWithoutDependencies.exec()).rejects.toThrow(Error); + }); }); diff --git a/src/__tests__/requestCache.spec.js b/src/__tests__/requestCache.spec.js index dd989f9..ed6350b 100644 --- a/src/__tests__/requestCache.spec.js +++ b/src/__tests__/requestCache.spec.js @@ -1,89 +1,89 @@ const RequestCache = require('../requestCache'); describe('Request Cache', () => { - let cache; + let cache; - beforeEach(() => { - cache = new RequestCache(); + beforeEach(() => { + cache = new RequestCache(); - cache.add('session', { - hello: 'World' - }); + cache.add('session', { + hello: 'World' + }); - cache.add('array', [ - { - id: 1, - name: 'Sergio' - }, - { - id: 2, - name: 'Angela' - } - ]); - }); + cache.add('array', [ + { + id: 1, + name: 'Sergio' + }, + { + id: 2, + name: 'Angela' + } + ]); + }); - it('should add keys to the cache', () => { - expect(cache.$cache.session.hello).toBe('World'); - }); + it('should add keys to the cache', () => { + expect(cache.$cache.session.hello).toBe('World'); + }); - describe('get', () => { - it('should be able to find key values with a given path', () => { - expect(cache.get('session.hello')).toBe('World'); - }); + describe('get', () => { + it('should be able to find key values with a given path', () => { + expect(cache.get('session.hello')).toBe('World'); + }); - it('should throw when given an invalid path', () => { - expect(() => cache.get('$session.world')).toThrow(); - }); - }); + it('should throw when given an invalid path', () => { + expect(() => cache.get('$session.world')).toThrow(); + }); + }); - describe('parse', () => { - it("should transform variables in strings using it's cache", () => { - expect(cache.parse('Hello $session.hello')).toBe('Hello World'); - }); + describe('parse', () => { + it("should transform variables in strings using it's cache", () => { + expect(cache.parse('Hello $session.hello')).toBe('Hello World'); + }); - it('should go transform variables in all values when given an object', () => { - let parsed = cache.parse({ - hello: 'hello $session.hello', - earth: '$session.hello' - }); - expect(parsed.hello).toBe('hello World'); - expect(parsed.earth).toBe('World'); - }); + it('should go transform variables in all values when given an object', () => { + let parsed = cache.parse({ + hello: 'hello $session.hello', + earth: '$session.hello' + }); + expect(parsed.hello).toBe('hello World'); + expect(parsed.earth).toBe('World'); + }); - it('should return every non-string value as-is', () => { - let parsed = cache.parse({ - number: 1, - nulled: null, - truthy: false, - hello: '$session.hello' - }); - expect(parsed.number).toBe(1); - expect(parsed.nulled).toBeNull(); - expect(parsed.truthy).toBe(false); - expect(parsed.hello).toBe('World'); - }); + it('should return every non-string value as-is', () => { + let parsed = cache.parse({ + number: 1, + nulled: null, + truthy: false, + hello: '$session.hello' + }); + expect(parsed.number).toBe(1); + expect(parsed.nulled).toBeNull(); + expect(parsed.truthy).toBe(false); + expect(parsed.hello).toBe('World'); + }); - it('should parse arrays as well', () => { - let parsed = cache.parse({ hello: '$array.0.name' }); - expect(parsed.hello).toBe('Sergio'); - }); + it('should parse arrays as well', () => { + let parsed = cache.parse({ hello: '$array.0.name' }); + expect(parsed.hello).toBe('Sergio'); + }); - it('should return an object when given an undefined value', () => { - expect(Object.keys(cache.parse(undefined)).length).toBe(0); - }); + it('should return an object when given an undefined value', () => { + expect(Object.keys(cache.parse(undefined)).length).toBe(0); + }); - it('should parse any value other than undefined', () => { - expect(cache.parse('Hello $session.hello')).toBe('Hello World'); - }); + it('should parse any value other than undefined', () => { + expect(cache.parse('Hello $session.hello')).toBe('Hello World'); + }); - it('should return null when passed null', () => { - expect(cache.parse(null)).toBe(null); - }); + it('should return null when passed null', () => { + expect(cache.parse(null)).toBe(null); + }); - it(`shouldn't replace escaped variables`, () => { - expect(cache.parse(`\\$session.hello is $session.hello`)).toBe( - `$session.hello is World` - ); - }); - }); + it(`shouldn't replace escaped variables`, () => { + expect(cache.parse(`\\$session.hello is $session.hello`)).toBe( + `$session.hello is World` + ); + }); + }); }); diff --git a/src/__tests__/requestList.spec.js b/src/__tests__/requestList.spec.js index 4a8e50a..fc9c450 100644 --- a/src/__tests__/requestList.spec.js +++ b/src/__tests__/requestList.spec.js @@ -3,76 +3,76 @@ const RequestList = require('../requestList'); const requestPromiseNativeMock = require('request-promise-native'); describe('RequestList', () => { - const endpoint = 'http://martianwabbit.com'; + const endpoint = 'http://martianwabbit.com'; - let env = { - environmental: true - }; + let env = { + environmental: true + }; - const doc = { - ENDPOINT: endpoint, - ENVIRONMENT: env, - 'GET /post': { alias: 'get-posts' }, - 'POST /user': { - alias: 'user', - payload: { - name: 'Sergio', - lastname: 'Diaz' - } - } - }; + const doc = { + ENDPOINT: endpoint, + ENVIRONMENT: env, + 'GET /post': { alias: 'get-posts' }, + 'POST /user': { + alias: 'user', + payload: { + name: 'Sergio', + lastname: 'Diaz' + } + } + }; - let requests; - beforeEach(() => { - requestPromiseNativeMock.fail = false; + let requests; + beforeEach(() => { + requestPromiseNativeMock.fail = false; - let config = new Config(doc); - requests = new RequestList(config); - }); + let config = new Config(doc); + requests = new RequestList(config); + }); - it('should allow an empty request list', () => { - requests = new RequestList(); - expect(requests.list.length).toBe(0); - }); + it('should allow an empty request list', () => { + requests = new RequestList(); + expect(requests.list.length).toBe(0); + }); - it('should load valid requests', () => { - expect(requests.list.length).toBe(2); - }); + it('should load valid requests', () => { + expect(requests.list.length).toBe(2); + }); - it('should fetch dependencies', async () => { - await expect( - requests.fetchDependencies(['get-posts']) - ).resolves.toMatchSnapshot(); - }); + it('should fetch dependencies', async () => { + await expect( + requests.fetchDependencies(['get-posts']) + ).resolves.toMatchSnapshot(); + }); - it('should execute requests by alias.', async () => { - await expect(requests.execByAlias('user')).resolves.toMatchSnapshot(); - }); + it('should execute requests by alias.', async () => { + await expect(requests.execByAlias('user')).resolves.toMatchSnapshot(); + }); - it('should fail if the request fails', async () => { - requestPromiseNativeMock.fail = true; - await expect(requests.execByAlias('user')).rejects.toThrow(); - }); + it('should fail if the request fails', async () => { + requestPromiseNativeMock.fail = true; + await expect(requests.execByAlias('user')).rejects.toThrow(); + }); - it('should return a cached result if available', async () => { - const obj = { test: true }; - requests.cache.add('test', obj); - await expect(requests.execByAlias('test')).resolves.toBe(obj); - }); + it('should return a cached result if available', async () => { + const obj = { test: true }; + requests.cache.add('test', obj); + await expect(requests.execByAlias('test')).resolves.toBe(obj); + }); - it('should fail if the alias is not found', async () => { - await expect(requests.execByAlias('notAnAlias')).rejects.toThrow(); - }); + it('should fail if the alias is not found', async () => { + await expect(requests.execByAlias('notAnAlias')).rejects.toThrow(); + }); - it(`should fail if a given request doesn't have an alias`, () => { - let config = new Config({ - 'GET /hello': { - headers: { - hello: 1 - } - } - }); + it(`should fail if a given request doesn't have an alias`, () => { + let config = new Config({ + 'GET /hello': { + headers: { + hello: 1 + } + } + }); - expect(() => new RequestList(config, config)).toThrow(); - }); + expect(() => new RequestList(config, config)).toThrow(); + }); }); diff --git a/src/beau.js b/src/beau.js index a49d3ac..f734940 100644 --- a/src/beau.js +++ b/src/beau.js @@ -2,10 +2,10 @@ const RequestList = require('./requestList'); const Config = require('./config'); class Beau { - constructor(doc, env = {}) { - this.config = new Config(doc, env); - this.requests = new RequestList(this.config); - } + constructor(doc, env = {}) { + this.config = new Config(doc, env); + this.requests = new RequestList(this.config); + } } module.exports = Beau; diff --git a/src/config.js b/src/config.js index 6b4709e..4fda987 100644 --- a/src/config.js +++ b/src/config.js @@ -3,96 +3,96 @@ const { requestRegex, UpperCaseKeys } = require('./shared'); const Plugins = require('./plugins'); class Config { - constructor(doc, env = {}) { - this.defaultConfigValues = { - VERSION: 1, - ENDPOINT: '', - PLUGINS: [], - DEFAULTS: {}, - ENVIRONMENT: {}, - HOSTS: [], - COOKIEJAR: false - }; + constructor(doc, env = {}) { + this.defaultConfigValues = { + VERSION: 1, + ENDPOINT: '', + PLUGINS: [], + DEFAULTS: {}, + ENVIRONMENT: {}, + HOSTS: [], + COOKIEJAR: false + }; - this.configKeys = Object.keys(this.defaultConfigValues); - this.doc = doc; + this.configKeys = Object.keys(this.defaultConfigValues); + this.doc = doc; - let config = this.loadConfig(doc); - this.configKeys.forEach(k => { - this[k] = config[k] || this.defaultConfigValues[k]; - }); + let config = this.loadConfig(doc); + this.configKeys.forEach(k => { + this[k] = config[k] || this.defaultConfigValues[k]; + }); - this.ENVIRONMENT = deepMerge(this.ENVIRONMENT, env); + this.ENVIRONMENT = deepMerge(this.ENVIRONMENT, env); - this.REQUESTS = []; + this.REQUESTS = []; - this.loadRequests(doc, { - DEFAULTS: this.DEFAULTS, - ENDPOINT: this.ENDPOINT - }); + this.loadRequests(doc, { + DEFAULTS: this.DEFAULTS, + ENDPOINT: this.ENDPOINT + }); - this.loadHosts(this.HOSTS, config); + this.loadHosts(this.HOSTS, config); - this.PLUGINS = new Plugins(this.PLUGINS); - } + this.PLUGINS = new Plugins(this.PLUGINS); + } - loadHosts(hosts, rootConfig) { - hosts.forEach(host => { - if (typeof host.host === 'undefined') { - throw new Error(`Host doesn't indicate it's host name.`); - } + loadHosts(hosts, rootConfig) { + hosts.forEach(host => { + if (typeof host.host === 'undefined') { + throw new Error(`Host doesn't indicate it's host name.`); + } - let config = deepMerge( - this.defaultConfigValues, - this.loadConfig(host) - ); + let config = deepMerge( + this.defaultConfigValues, + this.loadConfig(host) + ); - config.DEFAULTS = deepMerge(rootConfig.DEFAULTS, config.DEFAULTS); + config.DEFAULTS = deepMerge(rootConfig.DEFAULTS, config.DEFAULTS); - this.loadRequests(host, { - DEFAULTS: config.DEFAULTS, - ENDPOINT: config.ENDPOINT, - NAMESPACE: host.host - }); - }); - } + this.loadRequests(host, { + DEFAULTS: config.DEFAULTS, + ENDPOINT: config.ENDPOINT, + NAMESPACE: host.host + }); + }); + } - loadRequests(host, settings) { - let requests = Object.keys(host) - .filter(key => requestRegex.test(key)) - .map(key => { - let requestDefinitionIsString = typeof host[key] === 'string'; - let originalRequest = requestDefinitionIsString - ? { ALIAS: host[key] } - : host[key]; + loadRequests(host, settings) { + let requests = Object.keys(host) + .filter(key => requestRegex.test(key)) + .map(key => { + let requestDefinitionIsString = typeof host[key] === 'string'; + let originalRequest = requestDefinitionIsString + ? { ALIAS: host[key] } + : host[key]; - let request = UpperCaseKeys(originalRequest); + let request = UpperCaseKeys(originalRequest); - if (settings.NAMESPACE) { - request.ALIAS = `${settings.NAMESPACE}:${request.ALIAS}`; - } + if (settings.NAMESPACE) { + request.ALIAS = `${settings.NAMESPACE}:${request.ALIAS}`; + } - request.REQUEST = key; - request.COOKIEJAR = this.COOKIEJAR; - request.ENDPOINT = settings.ENDPOINT; + request.REQUEST = key; + request.COOKIEJAR = this.COOKIEJAR; + request.ENDPOINT = settings.ENDPOINT; - let defaults = UpperCaseKeys(settings.DEFAULTS); + let defaults = UpperCaseKeys(settings.DEFAULTS); - return deepMerge(defaults, request); - }); + return deepMerge(defaults, request); + }); - this.REQUESTS = this.REQUESTS.concat(requests); - } + this.REQUESTS = this.REQUESTS.concat(requests); + } - loadConfig(host) { - let config = {}; + loadConfig(host) { + let config = {}; - Object.keys(host) - .filter(k => this.configKeys.includes(k.toUpperCase())) - .forEach(k => (config[k.toUpperCase()] = host[k])); + Object.keys(host) + .filter(k => this.configKeys.includes(k.toUpperCase())) + .forEach(k => (config[k.toUpperCase()] = host[k])); - return config; - } + return config; + } } module.exports = Config; diff --git a/src/plugins.js b/src/plugins.js index 243ca32..108a113 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -5,91 +5,91 @@ const { toKebabCase, dynamicValueRegex, replaceInObject } = require('./shared'); const isPlainObject = require('is-plain-object'); class Plugins { - constructor(plugins = []) { - this.registry = { - preRequestModifiers: [], - postRequestModifiers: [], - dynamicValues: [] - }; + constructor(plugins = []) { + this.registry = { + preRequestModifiers: [], + postRequestModifiers: [], + dynamicValues: [] + }; - this.context = {}; + this.context = {}; - plugins.forEach(plugin => this.loadPlugin(plugin)); - } + plugins.forEach(plugin => this.loadPlugin(plugin)); + } - loadPlugin(plugin) { - let name = plugin; - let settings = {}; + loadPlugin(plugin) { + let name = plugin; + let settings = {}; - if (typeof plugin === 'object') { - let keys = Object.keys(plugin); + if (typeof plugin === 'object') { + let keys = Object.keys(plugin); - if (keys.length !== 1) { - throw new Error(`Plugin items should contain only one key.`); - } + if (keys.length !== 1) { + throw new Error(`Plugin items should contain only one key.`); + } - name = keys[0]; - settings = plugin[name]; - } + name = keys[0]; + settings = plugin[name]; + } - plugin = requireg(`beau-${toKebabCase(name)}`); - new plugin(this, settings); - } + plugin = requireg(`beau-${toKebabCase(name)}`); + new plugin(this, settings); + } - executeModifier(modifier, obj, orig) { - let result = deepmerge({}, obj, { isMergeableObject: isPlainObject }); + executeModifier(modifier, obj, orig) { + let result = deepmerge({}, obj, { isMergeableObject: isPlainObject }); - this.registry[modifier].forEach( - modifier => (result = modifier(result, orig)) - ); + this.registry[modifier].forEach( + modifier => (result = modifier(result, orig)) + ); - return result; - } + return result; + } - replaceDynamicValues(obj) { - return replaceInObject(obj, val => { - let valIsEmpty = val.trim().length === 0; + replaceDynamicValues(obj) { + return replaceInObject(obj, val => { + let valIsEmpty = val.trim().length === 0; - if (valIsEmpty) { - return val; - } + if (valIsEmpty) { + return val; + } - try { - let onlyHasDynamic = - val.replace(dynamicValueRegex, '').trim() === ''; + try { + let onlyHasDynamic = + val.replace(dynamicValueRegex, '').trim() === ''; - if (onlyHasDynamic) { - let call; - val.replace(dynamicValueRegex, (match, c) => { - call = c; - }); + if (onlyHasDynamic) { + let call; + val.replace(dynamicValueRegex, (match, c) => { + call = c; + }); - return vm.runInContext(call, this.context); - } + return vm.runInContext(call, this.context); + } - return val.replace(dynamicValueRegex, (match, call) => { - return vm.runInContext(call, this.context); - }); - } catch (e) { - throw new Error(`DynamicValue: ` + e); - } - }); - } + return val.replace(dynamicValueRegex, (match, call) => { + return vm.runInContext(call, this.context); + }); + } catch (e) { + throw new Error(`DynamicValue: ` + e); + } + }); + } - addPreRequestModifier(modifier) { - this.registry.preRequestModifiers.push(modifier); - } + addPreRequestModifier(modifier) { + this.registry.preRequestModifiers.push(modifier); + } - addPostRequestModifier(modifier) { - this.registry.postRequestModifiers.push(modifier); - } + addPostRequestModifier(modifier) { + this.registry.postRequestModifiers.push(modifier); + } - defineDynamicValue(name, fn) { - this.registry.dynamicValues.push({ name, fn }); - this.context[name] = fn; + defineDynamicValue(name, fn) { + this.registry.dynamicValues.push({ name, fn }); + this.context[name] = fn; - vm.createContext(this.context); - } + vm.createContext(this.context); + } } module.exports = Plugins; diff --git a/src/request.js b/src/request.js index 203dd30..2c07777 100644 --- a/src/request.js +++ b/src/request.js @@ -4,149 +4,149 @@ const RequestCache = require('./requestCache'); const Plugins = require('./plugins'); const { - httpVerbs, - requestRegex, - replacementRegex, - UpperCaseKeys, - removeOptionalKeys + httpVerbs, + requestRegex, + replacementRegex, + UpperCaseKeys, + removeOptionalKeys } = require('./shared'); class Request { - constructor(req, plugins = new Plugins()) { - this.originalRequest = req; - this.plugins = plugins; + constructor(req, plugins = new Plugins()) { + this.originalRequest = req; + this.plugins = plugins; - this.loadCofiguration( - [ - 'REQUEST', - 'ENDPOINT', - 'HEADERS', - 'PAYLOAD', - 'PARAMS', - 'FORM', - 'ALIAS', - 'COOKIEJAR', - 'FORMDATA' - ], - req - ); + this.loadCofiguration( + [ + 'REQUEST', + 'ENDPOINT', + 'HEADERS', + 'PAYLOAD', + 'PARAMS', + 'FORM', + 'ALIAS', + 'COOKIEJAR', + 'FORMDATA' + ], + req + ); - if (!this.ALIAS) { - throw new Error(`${this.REQUEST} is missing an alias.`); - } + if (!this.ALIAS) { + throw new Error(`${this.REQUEST} is missing an alias.`); + } - const { VERB, PATH } = this.parseRequest(this.REQUEST); + const { VERB, PATH } = this.parseRequest(this.REQUEST); - this.VERB = VERB; - this.PATH = PATH; + this.VERB = VERB; + this.PATH = PATH; - this.DEPENDENCIES = this.findDependencies(req); - } + this.DEPENDENCIES = this.findDependencies(req); + } - loadCofiguration(keys, obj) { - obj = UpperCaseKeys(obj); - keys.forEach(k => { - this[k] = obj[k]; - }); - } + loadCofiguration(keys, obj) { + obj = UpperCaseKeys(obj); + keys.forEach(k => { + this[k] = obj[k]; + }); + } - parseRequest(request) { - const parts = request.match(requestRegex); + parseRequest(request) { + const parts = request.match(requestRegex); - return { - VERB: parts[1], - PATH: parts[2] - }; - } + return { + VERB: parts[1], + PATH: parts[2] + }; + } - findDependencies(request, set = new Set()) { - let type = typeof request; + findDependencies(request, set = new Set()) { + let type = typeof request; - if (type === 'object') { - Object.keys(request) - .filter(key => key !== 'ALIAS') - .forEach(key => { - set = this.findDependencies(request[key], set); - }); - } else if (type === 'string') { - const matches = []; - request.replace( - replacementRegex, - (match, g1) => !match.startsWith('\\') && matches.push(g1) - ); + if (type === 'object') { + Object.keys(request) + .filter(key => key !== 'ALIAS') + .forEach(key => { + set = this.findDependencies(request[key], set); + }); + } else if (type === 'string') { + const matches = []; + request.replace( + replacementRegex, + (match, g1) => !match.startsWith('\\') && matches.push(g1) + ); - const deps = matches.map(m => m.split('.')[0]); + const deps = matches.map(m => m.split('.')[0]); - return new Set([...set, ...deps]); - } + return new Set([...set, ...deps]); + } - return set; - } + return set; + } - async exec(cache = new RequestCache()) { - let settings = cache.parse({ - baseUrl: this.ENDPOINT, - uri: this.PATH, - method: this.VERB, - jar: this.COOKIEJAR, + async exec(cache = new RequestCache()) { + let settings = cache.parse({ + baseUrl: this.ENDPOINT, + uri: this.PATH, + method: this.VERB, + jar: this.COOKIEJAR, - headers: this.HEADERS, - qs: this.PARAMS, - body: this.PAYLOAD, - form: this.FORM, - formData: this.FORMDATA, + headers: this.HEADERS, + qs: this.PARAMS, + body: this.PAYLOAD, + form: this.FORM, + formData: this.FORMDATA, - json: true, - simple: false, - resolveWithFullResponse: true - }); + json: true, + simple: false, + resolveWithFullResponse: true + }); - settings = removeOptionalKeys(settings, [ - 'headers', - 'qs', - 'body', - 'form', - 'formData' - ]); + settings = removeOptionalKeys(settings, [ + 'headers', + 'qs', + 'body', + 'form', + 'formData' + ]); - settings = this.plugins.replaceDynamicValues(settings); + settings = this.plugins.replaceDynamicValues(settings); - settings = this.plugins.executeModifier( - 'preRequestModifiers', - settings, - this.originalRequest - ); + settings = this.plugins.executeModifier( + 'preRequestModifiers', + settings, + this.originalRequest + ); - try { - const response = await request(settings); + try { + const response = await request(settings); - let results = { - request: { - headers: response.request.headers, - body: response.request.body, - endpoint: response.request.uri.href - }, - response: { - status: response.statusCode, - headers: response.headers, - body: response.body - }, - body: response.body - }; + let results = { + request: { + headers: response.request.headers, + body: response.request.body, + endpoint: response.request.uri.href + }, + response: { + status: response.statusCode, + headers: response.headers, + body: response.body + }, + body: response.body + }; - results = this.plugins.executeModifier( - 'postRequestModifiers', - results, - this.originalRequest - ); + results = this.plugins.executeModifier( + 'postRequestModifiers', + results, + this.originalRequest + ); - cache.add(this.ALIAS, results); + cache.add(this.ALIAS, results); - return results; - } catch ({ error }) { - throw new Error(`Request Error: ` + error); - } - } + return results; + } catch ({ error }) { + throw new Error(`Request Error: ` + error); + } + } } module.exports = Request; diff --git a/src/requestCache.js b/src/requestCache.js index 9a5cef7..da10d4e 100644 --- a/src/requestCache.js +++ b/src/requestCache.js @@ -1,46 +1,46 @@ const { replacementRegex, replaceInObject } = require('./shared'); class RequestCache { - constructor() { - this.$cache = {}; - } + constructor() { + this.$cache = {}; + } - exists(key) { - return typeof this.$cache[key] !== 'undefined'; - } + exists(key) { + return typeof this.$cache[key] !== 'undefined'; + } - add(key, value) { - this.$cache[key] = value; - } + add(key, value) { + this.$cache[key] = value; + } - get(path) { - let result = this.$cache; - path.split('.').forEach(part => { - if (result[part] === undefined) { - throw new Error(`${path} not found in cache.`); - } + get(path) { + let result = this.$cache; + path.split('.').forEach(part => { + if (result[part] === undefined) { + throw new Error(`${path} not found in cache.`); + } - result = result[part]; - }); + result = result[part]; + }); - return result; - } + return result; + } - parse(item) { - if (item === null) { - return null; - } + parse(item) { + if (item === null) { + return null; + } - return replaceInObject(item, item => { - return item.replace(replacementRegex, (match, key) => { - if (match.startsWith('\\')) { - return match.replace('\\$', '$'); - } + return replaceInObject(item, item => { + return item.replace(replacementRegex, (match, key) => { + if (match.startsWith('\\')) { + return match.replace('\\$', '$'); + } - return this.get(key); - }); - }); - } + return this.get(key); + }); + }); + } } module.exports = RequestCache; diff --git a/src/requestList.js b/src/requestList.js index 0c09f76..eb0ddec 100644 --- a/src/requestList.js +++ b/src/requestList.js @@ -3,58 +3,58 @@ const RequestCache = require('./requestCache'); const httpVerbs = require('./shared').httpVerbs; class RequestList { - constructor(config = { REQUESTS: [] }) { - this.config = config; - this.REQUESTS = config.REQUESTS; + constructor(config = { REQUESTS: [] }) { + this.config = config; + this.REQUESTS = config.REQUESTS; - this.list = this.loadRequests(); - this.cache = new RequestCache(); + this.list = this.loadRequests(); + this.cache = new RequestCache(); - this.cache.add(`env`, this.config.ENVIRONMENT); - } + this.cache.add(`env`, this.config.ENVIRONMENT); + } - async execByAlias(alias) { - if (this.cache.exists(alias)) { - return this.cache.get(alias); - } + async execByAlias(alias) { + if (this.cache.exists(alias)) { + return this.cache.get(alias); + } - const request = this.list.find(r => r.ALIAS === alias); + const request = this.list.find(r => r.ALIAS === alias); - if (typeof request === 'undefined') { - throw new Error(`${alias} not found among the requests.`); - } + if (typeof request === 'undefined') { + throw new Error(`${alias} not found among the requests.`); + } - try { - await this.fetchDependencies(Array.from(request.DEPENDENCIES)); - return await request.exec(this.cache); - } catch (reason) { - throw new Error( - `Request: ${request.VERB} ${ - request.ENDPOINT - } FAILED. \n${reason}` - ); - } - } + try { + await this.fetchDependencies(Array.from(request.DEPENDENCIES)); + return await request.exec(this.cache); + } catch (reason) { + throw new Error( + `Request: ${request.VERB} ${ + request.ENDPOINT + } FAILED. \n${reason}` + ); + } + } - async fetchDependencies(dependencies) { - dependencies = dependencies.map(d => this.execByAlias(d)); - await Promise.all(dependencies); + async fetchDependencies(dependencies) { + dependencies = dependencies.map(d => this.execByAlias(d)); + await Promise.all(dependencies); - return this.cache; - } + return this.cache; + } - loadRequests() { - let requests = []; - this.REQUESTS.forEach(request => { - try { - requests.push(new Request(request, this.config.PLUGINS)); - } catch (e) { - throw new Error(`${request.request} was ignored: ${e}`); - } - }); + loadRequests() { + let requests = []; + this.REQUESTS.forEach(request => { + try { + requests.push(new Request(request, this.config.PLUGINS)); + } catch (e) { + throw new Error(`${request.request} was ignored: ${e}`); + } + }); - return requests; - } + return requests; + } } module.exports = RequestList; diff --git a/src/schema.js b/src/schema.js index 1a6b933..2ad67fd 100644 --- a/src/schema.js +++ b/src/schema.js @@ -2,78 +2,78 @@ const Joi = require('joi'); const { requestRegex } = require('./shared.js'); const pluginSchema = [ - Joi.string(), - Joi.object() - .keys(null) - .max(1) + Joi.string(), + Joi.object() + .keys(null) + .max(1) ]; 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(), - FORMDATA: Joi.object().keys(null) - }) - .without('FORM', ['PAYLOAD', 'FORMDATA']) - .without('PAYLOAD', ['FORM', 'FORMDATA']) - .without('FORMDATA', ['FORM', 'PAYLOAD']) - .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.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(), + FORMDATA: Joi.object().keys(null) + }) + .without('FORM', ['PAYLOAD', 'FORMDATA']) + .without('PAYLOAD', ['FORM', 'FORMDATA']) + .without('FORMDATA', ['FORM', 'PAYLOAD']) + .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() + 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 }); + .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(pluginSchema), - 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 }); + .keys({ + VERSION: Joi.number().integer(), + ENDPOINT: Joi.string().uri(), + PLUGINS: Joi.array().items(pluginSchema), + 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 = async function(config) { - try { - let results = await Joi.validate(config, schema, { - allowUnknown: true - }); - return { valid: true }; - } catch ({ name, details }) { - return { - valid: false, - message: `${name}: \n ${details - .map(d => d.message + ' @ ' + d.path) - .join(' \n ')}` - }; - } + try { + let results = await Joi.validate(config, schema, { + allowUnknown: true + }); + return { valid: true }; + } catch ({ name, details }) { + return { + valid: false, + message: `${name}: \n ${details + .map(d => d.message + ' @ ' + d.path) + .join(' \n ')}` + }; + } }; module.exports = { schema, validate }; diff --git a/src/shared.js b/src/shared.js index dfccd67..1d1f86d 100644 --- a/src/shared.js +++ b/src/shared.js @@ -1,13 +1,13 @@ const httpVerbs = [ - 'GET', - 'HEAD', - 'POST', - 'PUT', - 'DELETE', - 'CONNECT', - 'OPTIONS', - 'TRACE', - 'PATCH' + 'GET', + 'HEAD', + 'POST', + 'PUT', + 'DELETE', + 'CONNECT', + 'OPTIONS', + 'TRACE', + 'PATCH' ]; const requestRegex = new RegExp(`(${httpVerbs.join('|')})\\s(.*)`, 'i'); @@ -15,65 +15,65 @@ const replacementRegex = /(?:\\?)\$([a-zA-Z\.\d\-\_\/\\\:]+)/g; const dynamicValueRegex = /\$\[(\w+\((?:.|[\n\r])+?\))\]/g; const UpperCaseKeys = function(obj) { - let result = {}; - Object.keys(obj).forEach(k => (result[k.toUpperCase()] = obj[k])); - return result; + let result = {}; + Object.keys(obj).forEach(k => (result[k.toUpperCase()] = obj[k])); + return result; }; const removeOptionalKeys = function(obj, optionalValues) { - let result = {}; + let result = {}; - Object.keys(obj).forEach(key => { - if ( - optionalValues.includes(key) && - (Object.keys(obj[key]).length === 0 && - obj[key].constructor === Object) - ) { - return; - } + Object.keys(obj).forEach(key => { + if ( + optionalValues.includes(key) && + (Object.keys(obj[key]).length === 0 && + obj[key].constructor === Object) + ) { + return; + } - result[key] = obj[key]; - }); + result[key] = obj[key]; + }); - return result; + return result; }; const toKebabCase = function(str) { - return str - .trim() - .replace(/([a-z])([A-Z])/g, '$1-$2') - .replace(/\s+/g, '-') - .toLowerCase(); + return str + .trim() + .replace(/([a-z])([A-Z])/g, '$1-$2') + .replace(/\s+/g, '-') + .toLowerCase(); }; const replaceInObject = function(obj, fn) { - if (obj === null) { - return null; - } + if (obj === null) { + return null; + } - let type = typeof obj; + let type = typeof obj; - if (type === 'undefined') { - return {}; - } + if (type === 'undefined') { + return {}; + } - if (type === 'string') { - return fn(obj); - } + if (type === 'string') { + return fn(obj); + } - if (type === 'object') { - Object.keys(obj).forEach(k => (obj[k] = replaceInObject(obj[k], fn))); - } + if (type === 'object') { + Object.keys(obj).forEach(k => (obj[k] = replaceInObject(obj[k], fn))); + } - return obj; + return obj; }; module.exports = { - requestRegex, - replacementRegex, - dynamicValueRegex, - UpperCaseKeys, - removeOptionalKeys, - toKebabCase, - replaceInObject + requestRegex, + replacementRegex, + dynamicValueRegex, + UpperCaseKeys, + removeOptionalKeys, + toKebabCase, + replaceInObject };