diff --git a/CHANGELOG.md b/CHANGELOG.md index 09cb6882..f6497673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # 0.2.0(08.01.2017) ## Breaking Changes -The service name is added to the statemachin prefix. +The service name is added to the statemachine prefix. This is because there is a possibility of conflict with the state machine deployed from another service without the service name. A state machine created with version 0.1 is not inherited. Please recreate it. @@ -18,4 +18,4 @@ A state machine created with version 0.1 is not inherited. Please recreate it. Accidentally release(#1) # 0.1.1(29.12.2016) -First Release \ No newline at end of file +First Release diff --git a/README.md b/README.md index a062d74e..25a7ef08 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,53 @@ stepFunctions: definition: ``` +#### Share API Gateway and API Resources + +You can [share the same API Gateway](https://serverless.com/framework/docs/providers/aws/events/apigateway/#share-api-gateway-and-api-resources) between multiple projects by referencing its REST API ID and Root Resource ID in serverless.yml as follows: + +```yml +service: service-name +provider: + name: aws + apiGateway: + # REST API resource ID. Default is generated by the framework + restApiId: xxxxxxxxxx + # Root resource, represent as / path + restApiRootResourceId: xxxxxxxxxx + +functions: + ... +``` +If your application has many nested paths, you might also want to break them out into smaller services. + +However, Cloudformation will throw an error if we try to generate an existing path resource. To avoid that, we reference the resource ID: + +```yml +service: service-a +provider: + apiGateway: + restApiId: xxxxxxxxxx + restApiRootResourceId: xxxxxxxxxx + # List of existing resources that were created in the REST API. This is required or the stack will be conflicted + restApiResources: + /users: xxxxxxxxxx + +functions: + ... +``` + +Now we can define endpoints using existing API Gateway ressources + +```yml +stepFunctions: + stateMachines: + hello: + events: + - http: + path: users/create + method: POST +``` + #### Enabling CORS To set CORS configurations for your HTTP endpoints, simply modify your event configurations as follows: @@ -210,6 +257,21 @@ stepFunctions: Configuring the cors property sets Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Methods,Access-Control-Allow-Credentials headers in the CORS preflight response. +To enable the Access-Control-Max-Age preflight response header, set the maxAge property in the cors object: + +```yml +stepFunctions: + stateMachines: + SfnApiGateway: + events: + - http: + path: /playground/start + method: post + cors: + origin: '*' + maxAge: 86400 +``` + #### Customizing request body mapping templates The plugin generates default body mapping templates for `application/json` and `application/x-www-form-urlencoded` content types. If you'd like to add more content types or customize the default ones, you can do so by including them in `serverless.yml`: diff --git a/lib/deploy/events/apiGateway/cors.js b/lib/deploy/events/apiGateway/cors.js index 9e1b0898..f8a70679 100644 --- a/lib/deploy/events/apiGateway/cors.js +++ b/lib/deploy/events/apiGateway/cors.js @@ -12,6 +12,7 @@ module.exports = { const corsMethodLogicalId = this.provider.naming .getMethodLogicalId(resourceName, 'options'); + // TODO remove once "origins" config is deprecated let origin = config.origin; if (config.origins && config.origins.length) { origin = config.origins.join(','); @@ -24,6 +25,16 @@ module.exports = { 'Access-Control-Allow-Credentials': `'${config.allowCredentials}'`, }; + // Enable CORS Max Age usage if set + if (_.has(config, 'maxAge')) { + if (_.isInteger(config.maxAge) && config.maxAge > 0) { + preflightHeaders['Access-Control-Max-Age'] = `'${config.maxAge}'`; + } else { + const errorMessage = 'maxAge should be an integer over 0'; + throw new this.serverless.classes.Error(errorMessage); + } + } + if (_.includes(config.methods, 'ANY')) { preflightHeaders['Access-Control-Allow-Methods'] = preflightHeaders['Access-Control-Allow-Methods'] @@ -43,10 +54,11 @@ module.exports = { RequestTemplates: { 'application/json': '{statusCode:200}', }, + ContentHandling: 'CONVERT_TO_TEXT', IntegrationResponses: this.generateCorsIntegrationResponses(preflightHeaders), }, ResourceId: resourceRef, - RestApiId: { Ref: this.apiGatewayRestApiLogicalId }, + RestApiId: this.provider.getApiGatewayRestApiId(), }, }, }); diff --git a/lib/deploy/events/apiGateway/cors.test.js b/lib/deploy/events/apiGateway/cors.test.js index 87c84991..8ecc9558 100644 --- a/lib/deploy/events/apiGateway/cors.test.js +++ b/lib/deploy/events/apiGateway/cors.test.js @@ -5,63 +5,83 @@ const Serverless = require('serverless/lib/Serverless'); const AwsProvider = require('serverless/lib/plugins/aws/provider/awsProvider'); const ServerlessStepFunctions = require('./../../../index'); -describe('#methods()', () => { +describe('#compileCors()', () => { let serverless; - let serverlessStepFunctions; + let awsCompileApigEvents; beforeEach(() => { - serverless = new Serverless(); - serverless.setProvider('aws', new AwsProvider(serverless)); - serverless.service.provider.compiledCloudFormationTemplate = { - Resources: {}, - }; - const options = { stage: 'dev', region: 'us-east-1', }; - serverlessStepFunctions = new ServerlessStepFunctions(serverless, options); - serverlessStepFunctions.serverless.service.stepFunctions = { - stateMachines: { - first: {}, + serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless, options)); + serverless.service.service = 'first-service'; + serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; + serverless.service.environment = { + stages: { + dev: { + regions: { + 'us-east-1': { + vars: { + IamRoleLambdaExecution: + 'arn:aws:iam::12345678:role/service-dev-IamRoleLambdaExecution-FOO12345678', + }, + }, + }, + }, }, }; - serverlessStepFunctions.apiGatewayResourceLogicalIds = { - 'users/create': 'ApiGatewayResourceUsersCreate', - 'users/list': 'ApiGatewayResourceUsersList', - 'users/update': 'ApiGatewayResourceUsersUpdate', - 'users/delete': 'ApiGatewayResourceUsersDelete', - 'users/any': 'ApiGatewayResourceUsersAny', - }; - serverlessStepFunctions.apiGatewayResourceNames = { - 'users/create': 'UsersCreate', - 'users/list': 'UsersList', - 'users/update': 'UsersUpdate', - 'users/delete': 'UsersDelete', - 'users/any': 'UsersAny', + awsCompileApigEvents = new ServerlessStepFunctions(serverless, options); + awsCompileApigEvents.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'; + awsCompileApigEvents.apiGatewayResources = { + 'users/create': { + name: 'UsersCreate', + resourceLogicalId: 'ApiGatewayResourceUsersCreate', + }, + + 'users/list': { + name: 'UsersList', + resourceLogicalId: 'ApiGatewayResourceUsersList', + }, + 'users/update': { + name: 'UsersUpdate', + resourceLogicalId: 'ApiGatewayResourceUsersUpdate', + }, + 'users/delete': { + name: 'UsersDelete', + resourceLogicalId: 'ApiGatewayResourceUsersDelete', + }, + 'users/any': { + name: 'UsersAny', + resourceLogicalId: 'ApiGatewayResourceUsersAny', + }, }; - serverlessStepFunctions.pluginhttpValidated = {}; + awsCompileApigEvents.pluginhttpValidated = {}; }); it('should create preflight method for CORS enabled resource', () => { - serverlessStepFunctions.pluginhttpValidated.corsPreflight = { + awsCompileApigEvents.pluginhttpValidated.corsPreflight = { 'users/update': { origin: 'http://example.com', headers: ['*'], methods: ['OPTIONS', 'PUT'], allowCredentials: false, + maxAge: 86400, }, 'users/create': { origins: ['*', 'http://example.com'], headers: ['*'], methods: ['OPTIONS', 'POST'], allowCredentials: true, + maxAge: 86400, }, 'users/delete': { origins: ['*'], headers: ['CustomHeaderA', 'CustomHeaderB'], methods: ['OPTIONS', 'DELETE'], allowCredentials: false, + maxAge: 86400, }, 'users/any': { origins: ['http://example.com'], @@ -70,115 +90,166 @@ describe('#methods()', () => { allowCredentials: false, }, }; - return serverlessStepFunctions.compileCors().then(() => { + return awsCompileApigEvents.compileCors().then(() => { // users/create expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersCreateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Origin'] ).to.equal('\'*,http://example.com\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersCreateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Headers'] ).to.equal('\'*\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersCreateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Methods'] ).to.equal('\'OPTIONS,POST\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersCreateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Credentials'] ).to.equal('\'true\''); + expect( + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayMethodUsersCreateOptions + .Properties.Integration.IntegrationResponses[0] + .ResponseParameters['method.response.header.Access-Control-Max-Age'] + ).to.equal('\'86400\''); + // users/update expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersUpdateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Origin'] ).to.equal('\'http://example.com\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersUpdateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Methods'] ).to.equal('\'OPTIONS,PUT\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersUpdateOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Credentials'] ).to.equal('\'false\''); + expect( + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayMethodUsersUpdateOptions + .Properties.Integration.IntegrationResponses[0] + .ResponseParameters['method.response.header.Access-Control-Max-Age'] + ).to.equal('\'86400\''); + // users/delete expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersDeleteOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Origin'] ).to.equal('\'*\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersDeleteOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Headers'] ).to.equal('\'CustomHeaderA,CustomHeaderB\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersDeleteOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Methods'] ).to.equal('\'OPTIONS,DELETE\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersDeleteOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Credentials'] ).to.equal('\'false\''); + expect( + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayMethodUsersDeleteOptions + .Properties.Integration.IntegrationResponses[0] + .ResponseParameters['method.response.header.Access-Control-Max-Age'] + ).to.equal('\'86400\''); + // users/any expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersAnyOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Origin'] ).to.equal('\'http://example.com\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersAnyOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Headers'] ).to.equal('\'*\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersAnyOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Methods'] ).to.equal('\'OPTIONS,DELETE,GET,HEAD,PATCH,POST,PUT\''); expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + awsCompileApigEvents.serverless.service.provider.compiledCloudFormationTemplate .Resources.ApiGatewayMethodUsersAnyOptions .Properties.Integration.IntegrationResponses[0] .ResponseParameters['method.response.header.Access-Control-Allow-Credentials'] ).to.equal('\'false\''); }); }); + + it('should throw error if maxAge is not an integer greater than 0', () => { + awsCompileApigEvents.pluginhttpValidated.corsPreflight = { + 'users/update': { + origin: 'http://example.com', + headers: ['*'], + methods: ['OPTIONS', 'PUT'], + allowCredentials: false, + maxAge: -1, + }, + }; + + expect(() => awsCompileApigEvents.compileCors()) + .to.throw(Error, 'maxAge should be an integer over 0'); + }); + + it('should throw error if maxAge is not an integer', () => { + awsCompileApigEvents.pluginhttpValidated.corsPreflight = { + 'users/update': { + origin: 'http://example.com', + headers: ['*'], + methods: ['OPTIONS', 'PUT'], + allowCredentials: false, + maxAge: 'five', + }, + }; + + expect(() => awsCompileApigEvents.compileCors()) + .to.throw(Error, 'maxAge should be an integer over 0'); + }); }); diff --git a/lib/deploy/events/apiGateway/deployment.js b/lib/deploy/events/apiGateway/deployment.js index cca055d0..af233bd4 100644 --- a/lib/deploy/events/apiGateway/deployment.js +++ b/lib/deploy/events/apiGateway/deployment.js @@ -12,7 +12,7 @@ module.exports = { [this.apiGatewayDeploymentLogicalId]: { Type: 'AWS::ApiGateway::Deployment', Properties: { - RestApiId: { Ref: this.apiGatewayRestApiLogicalId }, + RestApiId: this.provider.getApiGatewayRestApiId(), StageName: this.options.stage, }, DependsOn: this.apiGatewayMethodLogicalIds, @@ -26,7 +26,7 @@ module.exports = { 'Fn::Join': ['', [ 'https://', - { Ref: this.apiGatewayRestApiLogicalId }, + this.provider.getApiGatewayRestApiId(), `.execute-api.${this.options.region}.amazonaws.com/${this.options.stage}`, ], ], diff --git a/lib/deploy/events/apiGateway/methods.js b/lib/deploy/events/apiGateway/methods.js index f16b7c12..3072c666 100644 --- a/lib/deploy/events/apiGateway/methods.js +++ b/lib/deploy/events/apiGateway/methods.js @@ -20,7 +20,7 @@ module.exports = { AuthorizationType: 'NONE', ApiKeyRequired: Boolean(event.http.private), ResourceId: resourceId, - RestApiId: { Ref: this.apiGatewayRestApiLogicalId }, + RestApiId: this.provider.getApiGatewayRestApiId(), }, }; diff --git a/lib/deploy/events/apiGateway/methods.test.js b/lib/deploy/events/apiGateway/methods.test.js index 329aed09..dd588039 100644 --- a/lib/deploy/events/apiGateway/methods.test.js +++ b/lib/deploy/events/apiGateway/methods.test.js @@ -10,17 +10,19 @@ describe('#methods()', () => { let serverlessStepFunctions; beforeEach(() => { + const options = { + stage: 'dev', + region: 'us-east-1', + }; + serverless = new Serverless(); serverless.setProvider('aws', new AwsProvider(serverless)); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {}, }; - const options = { - stage: 'dev', - region: 'us-east-1', - }; serverlessStepFunctions = new ServerlessStepFunctions(serverless, options); + serverlessStepFunctions.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'; serverlessStepFunctions.serverless.service.stepFunctions = { stateMachines: { first: {}, @@ -51,6 +53,19 @@ describe('#methods()', () => { }, ], }; + + serverlessStepFunctions.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'; + serverlessStepFunctions.apiGatewayResources = { + 'foo/bar1': { + name: 'First', + resourceLogicalId: 'ApiGatewayResourceFirst', + }, + + 'foo/bar2': { + name: 'Second', + resourceLogicalId: 'ApiGatewayResourceSecond', + }, + }; }); describe('#compileMethods()', () => { @@ -58,7 +73,7 @@ describe('#methods()', () => { .compileMethods().then(() => { expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate .Resources) - .to.have.property('ApiGatewayMethodapiGatewayResourceNamesFirstPost'); + .to.have.property('ApiGatewayMethodFirstPost'); }) ); @@ -68,9 +83,9 @@ describe('#methods()', () => { const resources = serverlessStepFunctions .serverless.service.provider.compiledCloudFormationTemplate.Resources; - expect(resources.ApiGatewayMethodapiGatewayResourceNamesFirstPost + expect(resources.ApiGatewayMethodFirstPost .Properties.ApiKeyRequired).to.eql(false); - expect(resources.ApiGatewayMethodapiGatewayResourceNamesSecondPost + expect(resources.ApiGatewayMethodSecondPost .Properties.ApiKeyRequired).to.eql(true); }) ); diff --git a/lib/deploy/events/apiGateway/resources.js b/lib/deploy/events/apiGateway/resources.js index 653971a8..b76a2367 100644 --- a/lib/deploy/events/apiGateway/resources.js +++ b/lib/deploy/events/apiGateway/resources.js @@ -6,65 +6,247 @@ const _ = require('lodash'); module.exports = { compileResources() { - const resourcePaths = this.getResourcePaths(); - - this.apiGatewayResourceNames = {}; - this.apiGatewayResourceLogicalIds = {}; + this.apiGatewayResources = this.getResourcePaths(); + // ['users', 'users/create', 'users/create/something'] + _.keys(this.apiGatewayResources).forEach((path) => { + const resource = this.apiGatewayResources[path]; + if (resource.resourceId) { + return; + } - resourcePaths.forEach(path => { - const pathArray = path.split('/'); - const resourceName = this.provider.naming.normalizePath(path); - const resourceLogicalId = this.provider.naming.getResourceLogicalId(path); - const pathPart = pathArray.pop(); - const parentPath = pathArray.join('/'); - const parentRef = this.getResourceId(parentPath); + resource.resourceLogicalId = this.provider.naming.getResourceLogicalId(path); + resource.resourceId = { Ref: resource.resourceLogicalId }; - this.apiGatewayResourceNames[path] = resourceName; - this.apiGatewayResourceLogicalIds[path] = resourceLogicalId; + const parentRef = resource.parent + ? resource.parent.resourceId : this.getResourceId(); _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, { - [resourceLogicalId]: { + [resource.resourceLogicalId]: { Type: 'AWS::ApiGateway::Resource', Properties: { ParentId: parentRef, - PathPart: pathPart, - RestApiId: { Ref: this.apiGatewayRestApiLogicalId }, + PathPart: resource.pathPart, + RestApiId: this.provider.getApiGatewayRestApiId(), }, }, }); }); + return BbPromise.resolve(); }, + combineResourceTrees(trees) { + const self = this; + + function getNodePaths(result, node) { + const r = result; + r[node.path] = node; + if (!node.name) { + r[node.path].name = self.provider.naming.normalizePath(node.path); + } + + node.children.forEach((child) => getNodePaths(result, child)); + } + + return _.reduce(trees, (result, tree) => { + getNodePaths(result, tree); + return result; + }, {}); + }, + getResourcePaths() { - const paths = _.reduce(this.pluginhttpValidated.events, (resourcePaths, event) => { - let path = event.http.path; + const trees = []; + const predefinedResourceNodes = []; + const methodNodes = []; + const predefinedResources = this.provider.getApiGatewayPredefinedResources(); + + + function cutBranch(node) { + if (!node.parent) { + return; + } + + const n = node; + if (node.parent.children.length <= 1) { + n.parent.children = []; + } else { + n.parent.children = node.parent.children.filter((c) => c.path !== n.path); + n.parent.isCut = true; + } + n.parent = null; + } - while (path !== '') { - if (resourcePaths.indexOf(path) === -1) { - resourcePaths.push(path); + // organize all resource paths into N-ary tree + function applyResource(resource, isMethod) { + let root; + let parent; + let currentPath; + const path = resource.path.replace(/^\//, '').replace(/\/$/, ''); + const pathParts = path.split('/'); + + function applyNodeResource(node, parts, index) { + const n = node; + if (index === parts.length - 1) { + n.name = resource.name; + if (resource.resourceId) { + n.resourceId = resource.resourceId; + if (_.every(predefinedResourceNodes, (iter) => iter.path !== n.path)) { + predefinedResourceNodes.push(node); + } + } + if (isMethod && !node.hasMethod) { + n.hasMethod = true; + if (_.every(methodNodes, (iter) => iter.path !== n.path)) { + methodNodes.push(node); + } + } + } + + parent = node; + } + + pathParts.forEach((pathPart, index) => { + currentPath = currentPath ? `${currentPath}/${pathPart}` : pathPart; + root = root || _.find(trees, (node) => node.path === currentPath); + parent = parent || root; + + let node; + if (parent) { + if (parent.path === currentPath) { + applyNodeResource(parent, pathParts, index); + return; + } else if (parent.children.length > 0) { + node = _.find(parent.children, (n) => n.path === currentPath); + if (node) { + applyNodeResource(node, pathParts, index); + return; + } + } + } + + node = { + path: currentPath, + pathPart, + parent, + + level: index, + children: [], + }; + + if (parent) { + parent.children.push(node); + } + + if (!root) { + root = node; + trees.push(root); } - const splittedPath = path.split('/'); - splittedPath.pop(); - path = splittedPath.join('/'); + applyNodeResource(node, pathParts, index); + }); + } + + predefinedResources.forEach(applyResource); + this.pluginhttpValidated.events.forEach((event) => { + if (event.http.path) { + applyResource(event.http, true); } - return resourcePaths; - }, []); - return _.sortBy(paths, path => path.split('/').length); + }); + + // if predefinedResources array is empty, return all paths + if (predefinedResourceNodes.length === 0) { + return this.combineResourceTrees(trees); + } + + // if all methods have resource ID already, no need to validate resource trees + if (_.every(this.pluginhttpValidated.events, (event) => + _.some(predefinedResourceNodes, (node) => + node.path === event.http.path))) { + return _.reduce(predefinedResources, (resourceMap, resource) => { + const r = resourceMap; + r[resource.path] = resource; + + if (!resource.name) { + r[resource.path].name = this.provider.naming.normalizePath(resource.path); + } + return r; + }, {}); + } + + // cut resource branches from trees + const sortedResourceNodes = _.sortBy(predefinedResourceNodes, + node => node.level); + const validatedTrees = []; + + for (let i = sortedResourceNodes.length - 1; i >= 0; i--) { + const node = sortedResourceNodes[i]; + let parent = node; + + while (parent && parent.parent) { + if (parent.parent.hasMethod && !parent.parent.resourceId) { + throw new Error(`Resource ID for path ${parent.parent.path} is required`); + } + + if (parent.parent.resourceId || parent.parent.children.length > 1) { + cutBranch(parent); + break; + } + + parent = parent.parent; + } + } + + // get branches that begin from root resource + methodNodes.forEach((node) => { + let iter = node; + while (iter) { + if (iter.resourceId) { + cutBranch(iter); + if (_.every(validatedTrees, (t) => t.path !== node.path)) { + validatedTrees.push(iter); + } + + break; + } + + if (iter.isCut || (!iter.parent && iter.level > 0)) { + throw new Error(`Resource ID for path ${iter.path} is required`); + } + + if (!iter.parent) { + validatedTrees.push(iter); + break; + } + + iter = iter.parent; + } + }); + + return this.combineResourceTrees(validatedTrees); }, getResourceId(path) { - if (path === '') { - return { 'Fn::GetAtt': [this.apiGatewayRestApiLogicalId, 'RootResourceId'] }; + if (!path) { + return this.provider.getApiGatewayRestApiRootResourceId(); + } + + if (!this.apiGatewayResources || !this.apiGatewayResources[path]) { + throw new Error(`Can not find API Gateway resource from path ${path}`); } - return { Ref: this.apiGatewayResourceLogicalIds[path] }; + + if (!this.apiGatewayResources[path].resourceId + && this.apiGatewayResources[path].resourceLogicalId) { + this.apiGatewayResources[path].resourceId = + { Ref: this.apiGatewayResources[path].resourceLogicalId }; + } + return this.apiGatewayResources[path].resourceId; }, getResourceName(path) { - if (path === '') { + if (path === '' || !this.apiGatewayResources) { return ''; } - return this.apiGatewayResourceNames[path]; + + return this.apiGatewayResources[path].name; }, }; diff --git a/lib/deploy/events/apiGateway/resources.test.js b/lib/deploy/events/apiGateway/resources.test.js index 14daebc8..c23145c0 100644 --- a/lib/deploy/events/apiGateway/resources.test.js +++ b/lib/deploy/events/apiGateway/resources.test.js @@ -70,15 +70,15 @@ describe('#compileResources()', () => { }, }, ]; - expect(serverlessStepFunctions.getResourcePaths()).to.deep.equal([ + expect(Object.keys(serverlessStepFunctions.getResourcePaths())).to.deep.equal([ 'foo', - 'bar', 'foo/bar', + 'bar', 'bar/-', 'bar/foo', 'bar/{id}', - 'bar/{foo_id}', 'bar/{id}/foobar', + 'bar/{foo_id}', 'bar/{foo_id}/foobar', ]); }); @@ -160,12 +160,16 @@ describe('#compileResources()', () => { }, ]; return serverlessStepFunctions.compileResources().then(() => { - expect(serverlessStepFunctions.apiGatewayResourceLogicalIds).to.deep.equal({ + const expectedResourceLogicalIds = { baz: 'ApiGatewayResourceBaz', 'baz/foo': 'ApiGatewayResourceBazFoo', foo: 'ApiGatewayResourceFoo', 'foo/{foo_id}': 'ApiGatewayResourceFooFooidVar', 'foo/{foo_id}/bar': 'ApiGatewayResourceFooFooidVarBar', + }; + Object.keys(expectedResourceLogicalIds).forEach((path) => { + expect(serverlessStepFunctions.apiGatewayResources[path].resourceLogicalId) + .equal(expectedResourceLogicalIds[path]); }); }); }); @@ -186,10 +190,14 @@ describe('#compileResources()', () => { }, ]; return serverlessStepFunctions.compileResources().then(() => { - expect(serverlessStepFunctions.apiGatewayResourceLogicalIds).to.deep.equal({ + const expectedResourceLogicalIds = { foo: 'ApiGatewayResourceFoo', 'foo/bar': 'ApiGatewayResourceFooBar', 'foo/{bar}': 'ApiGatewayResourceFooBarVar', + }; + Object.keys(expectedResourceLogicalIds).forEach((path) => { + expect(serverlessStepFunctions.apiGatewayResources[path].resourceLogicalId) + .equal(expectedResourceLogicalIds[path]); }); }); }); @@ -243,10 +251,286 @@ describe('#compileResources()', () => { }); }); - describe('#getResourceName()', () => { - it('should return empty if empty string gives to argument', () => { - expect(serverlessStepFunctions.getResourceName('')) - .to.equal(''); + it('should create child resources only if there are predefined parent resources', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: 'z5d4qh4oqi', + restApiResources: { + '/foo': 'axcybf2i39', + '/users': 'zxcvbnmasd', + '/users/friends': 'fcasdoojp1', + '/groups': 'iuoyiusduo', + }, + }; + + serverlessStepFunctions.pluginhttpValidated.events = [ + { + http: { + path: 'foo/bar', + method: 'GET', + }, + }, + { + http: { + path: 'foo/bar', + method: 'POST', + }, + }, + { + http: { + path: 'foo/bar', + method: 'DELETE', + }, + }, + { + http: { + path: 'bar/-', + method: 'GET', + }, + }, + { + http: { + path: 'bar/foo', + method: 'GET', + }, + }, + { + http: { + path: 'bar/{id}/foobar', + method: 'GET', + }, + }, + { + http: { + path: 'bar/{id}', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends/comments', + method: 'GET', + }, + }, + { + http: { + path: 'users/me/posts', + method: 'GET', + }, + }, + { + http: { + path: 'groups/categories', + method: 'GET', + }, + }, + ]; + return serverlessStepFunctions.compileResources().then(() => { + try { + serverlessStepFunctions.getResourceId('users/{userId}'); + throw new Error('Expected API Gateway resource not found error, got success'); + } catch (e) { + expect(e.message).to.equal('Can not find API Gateway resource from path users/{userId}'); + } + + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceFoo).to.equal(undefined); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceBar.Properties.RestApiId) + .to.equal('6fyzt1pfpk'); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceBar.Properties.ParentId) + .to.equal('z5d4qh4oqi'); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceFooBar.Properties.ParentId) + .to.equal('axcybf2i39'); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceBarIdVar.Properties.ParentId.Ref) + .to.equal('ApiGatewayResourceBar'); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceUsersMePosts).not.equal(undefined); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceUsersFriendsComments.Properties.ParentId) + .to.equal('fcasdoojp1'); + }); + }); + + it('should not create any child resources if all resources exists', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: 'z5d4qh4oqi', + restApiResources: { + foo: 'axcybf2i39', + users: 'zxcvbnmasd', + 'users/friends': 'fcasdoojp1', + 'users/is/this/a/long/path': 'sadvgpoujk', + }, + }; + + serverlessStepFunctions.pluginhttpValidated.events = [ + { + http: { + path: 'foo', + method: 'GET', + }, + }, + { + http: { + path: 'users', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends', + method: 'GET', + }, + }, + { + http: { + path: 'users/is/this/a/long/path', + method: 'GET', + }, + }, + ]; + + return serverlessStepFunctions.compileResources().then(() => { + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceFoo).to.equal(undefined); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceUsers).to.equal(undefined); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceUsersFriends).to.equal(undefined); + expect(serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate + .Resources.ApiGatewayResourceUsersIsThis).to.equal(undefined); + }); + }); + + it('should throw error if parent of existing resources is required', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: 'z5d4qh4oqi', + restApiResources: { + 'users/friends': 'fcasdoojp1', + }, + }; + + serverlessStepFunctions.pluginhttpValidated.events = [ + { + http: { + path: 'users', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends/{friendId}', + method: 'GET', + }, + }, + ]; + + expect(() => serverlessStepFunctions.compileResources()) + .to.throw(Error, 'Resource ID for path users is required'); + }); + + it('should throw error if API root resourceId of existing resource is required', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: '', + restApiResources: { + 'users/friends': 'fcasdoojp1', + }, + }; + + serverlessStepFunctions.pluginhttpValidated.events = [ + { + http: { + path: 'users/test/{id}', + method: 'GET', + }, + }, + ]; + + expect(() => serverlessStepFunctions.compileResources()) + .to.throw(Error, 'Resource ID for path users is required'); + }); + + it('should named all method paths if all resources are predefined', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: 'z5d4qh4oqi', + restApiResources: { + 'users/{id}': 'fcasdoojp1', + 'users/friends': 'fcasdoojp1', + 'users/friends/{id}': 'fcasdoojp1', + }, + }; + + serverlessStepFunctions.pluginhttpValidated.events = [ + { + http: { + path: '/users/{id}', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends', + method: 'POST', + }, + }, + { + http: { + path: 'users/friends', + method: 'DELETE', + }, + }, + { + http: { + path: 'users/friends/{id}', + method: 'GET', + }, + }, + { + http: { + path: 'users/friends/{id}', + method: 'POST', + }, + }, + ]; + + return serverlessStepFunctions.compileResources().then(() => { + expect(Object.keys(serverlessStepFunctions.serverless + .service.provider.compiledCloudFormationTemplate + .Resources).every((k) => ['ApiGatewayMethodundefinedGet', + 'ApiGatewayMethodundefinedPost'].indexOf(k) === -1)) + .to.equal(true); }); }); + + it('should return empty string if path is empty', () => { + expect(serverlessStepFunctions.getResourceName('')).to.equal(''); + }); + + it('should return empty string if no resources', () => { + expect(serverlessStepFunctions.getResourceName('users/friends')).to.equal(''); + }); + + it('should return resource name for given path', () => { + serverlessStepFunctions.apiGatewayResources = { + 'users/create': { + name: 'UsersCreate', + resourceLogicalId: 'ApiGatewayResourceUsersCreate', + }, + }; + + expect(serverlessStepFunctions.getResourceName('users/create')).to.equal('UsersCreate'); + }); }); diff --git a/lib/deploy/events/apiGateway/restApi.js b/lib/deploy/events/apiGateway/restApi.js index 9d180d05..d0cfb52a 100644 --- a/lib/deploy/events/apiGateway/restApi.js +++ b/lib/deploy/events/apiGateway/restApi.js @@ -5,17 +5,55 @@ const BbPromise = require('bluebird'); module.exports = { compileRestApi() { + if (this.serverless.service.provider.apiGateway && + this.serverless.service.provider.apiGateway.restApiId) { + return BbPromise.resolve(); + } + this.apiGatewayRestApiLogicalId = this.provider.naming.getRestApiLogicalId(); + let endpointType = 'EDGE'; + + if (this.serverless.service.provider.endpointType) { + const validEndpointTypes = ['REGIONAL', 'EDGE', 'PRIVATE']; + endpointType = this.serverless.service.provider.endpointType; + + if (typeof endpointType !== 'string') { + throw new this.serverless.classes.Error('endpointType must be a string'); + } + + + if (!_.includes(validEndpointTypes, endpointType.toUpperCase())) { + const message = 'endpointType must be one of "REGIONAL" or "EDGE" or "PRIVATE". ' + + `You provided ${endpointType}.`; + throw new this.serverless.classes.Error(message); + } + endpointType = endpointType.toUpperCase(); + } + _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, { [this.apiGatewayRestApiLogicalId]: { Type: 'AWS::ApiGateway::RestApi', Properties: { Name: this.provider.naming.getApiGatewayName(), + EndpointConfiguration: { + Types: [endpointType], + }, }, }, }); + if (!_.isEmpty(this.serverless.service.provider.resourcePolicy)) { + const policy = { + Version: '2012-10-17', + Statement: this.serverless.service.provider.resourcePolicy, + }; + _.merge(this.serverless.service.provider.compiledCloudFormationTemplate + .Resources[this.apiGatewayRestApiLogicalId].Properties, { + Policy: policy, + }); + } + return BbPromise.resolve(); }, }; diff --git a/lib/deploy/events/apiGateway/restApi.test.js b/lib/deploy/events/apiGateway/restApi.test.js index ef5a38a7..cfe48054 100644 --- a/lib/deploy/events/apiGateway/restApi.test.js +++ b/lib/deploy/events/apiGateway/restApi.test.js @@ -15,27 +15,128 @@ describe('#compileRestApi()', () => { Type: 'AWS::ApiGateway::RestApi', Properties: { Name: 'dev-new-service', + EndpointConfiguration: { + Types: ['EDGE'], + }, + }, + }, + }, + }; + + const serviceResourcesAwsResourcesObjectWithResourcePolicyMock = { + Resources: { + ApiGatewayRestApi: { + Type: 'AWS::ApiGateway::RestApi', + Properties: { + Name: 'dev-new-service', + EndpointConfiguration: { + Types: ['EDGE'], + }, + Policy: { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Allow', + Principal: '*', + Action: 'execute-api:Invoke', + Resource: ['execute-api:/*/*/*'], + Condition: { + IpAddress: { + 'aws:SourceIp': ['123.123.123.123'], + }, + }, + }, + ], + }, }, }, }, }; beforeEach(() => { + const options = { + stage: 'dev', + region: 'us-east-1', + }; serverless = new Serverless(); - serverless.setProvider('aws', new AwsProvider(serverless)); + serverless.setProvider('aws', new AwsProvider(serverless, options)); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; - serverless.service.service = 'new-service'; - serverlessStepFunctions = new ServerlessStepFunctions(serverless); + serverlessStepFunctions = new ServerlessStepFunctions(serverless, options); + serverlessStepFunctions.serverless.service.service = 'new-service'; + serverlessStepFunctions.serverless.service.functions = { + first: { + events: [ + { + http: { + path: 'foo/bar', + method: 'POST', + }, + }, + ], + }, + }; }); - it('should create a REST API resource', () => serverlessStepFunctions - .compileRestApi().then(() => { - expect( - serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate - .Resources - ).to.deep.equal( - serviceResourcesAwsResourcesObjectMock.Resources - ); - }) - ); + it('should create a REST API resource', () => + serverlessStepFunctions.compileRestApi().then(() => { + expect(serverlessStepFunctions.serverless.service + .provider.compiledCloudFormationTemplate.Resources).to.deep.equal( + serviceResourcesAwsResourcesObjectMock.Resources + ); + })); + + it('should create a REST API resource with resource policy', () => { + serverlessStepFunctions.serverless.service.provider.resourcePolicy = [ + { + Effect: 'Allow', + Principal: '*', + Action: 'execute-api:Invoke', + Resource: ['execute-api:/*/*/*'], + Condition: { + IpAddress: { + 'aws:SourceIp': ['123.123.123.123'], + }, + }, + }, + ]; + return serverlessStepFunctions.compileRestApi().then(() => { + expect(serverlessStepFunctions.serverless.service.provider + .compiledCloudFormationTemplate.Resources).to.deep.equal( + serviceResourcesAwsResourcesObjectWithResourcePolicyMock.Resources + ); + }); + }); + + it('should ignore REST API resource creation if there is predefined restApi config', () => { + serverlessStepFunctions.serverless.service.provider.apiGateway = { + restApiId: '6fyzt1pfpk', + restApiRootResourceId: 'z5d4qh4oqi', + }; + return serverlessStepFunctions.compileRestApi().then(() => { + expect(serverlessStepFunctions.serverless.service.provider + .compiledCloudFormationTemplate.Resources).to.deep.equal( + {} + ); + }); + }); + + it('throw error if endpointType property is not a string', () => { + serverlessStepFunctions.serverless.service.provider.endpointType = ['EDGE']; + expect(() => serverlessStepFunctions.compileRestApi()).to.throw(Error); + }); + + it('should compile if endpointType property is REGIONAL', () => { + serverlessStepFunctions.serverless.service.provider.endpointType = 'REGIONAL'; + expect(() => serverlessStepFunctions.compileRestApi()).to.not.throw(Error); + }); + + it('should compile if endpointType property is PRIVATE', () => { + serverlessStepFunctions.serverless.service.provider.endpointType = 'PRIVATE'; + expect(() => serverlessStepFunctions.compileRestApi()).to.not.throw(Error); + }); + + it('throw error if endpointType property is not EDGE or REGIONAL', () => { + serverlessStepFunctions.serverless.service.provider.endpointType = 'Testing'; + expect(() => serverlessStepFunctions.compileRestApi()).to.throw('endpointType must be one of'); + }); }); diff --git a/lib/deploy/events/apiGateway/validate.js b/lib/deploy/events/apiGateway/validate.js index f659d9ce..1fb43def 100644 --- a/lib/deploy/events/apiGateway/validate.js +++ b/lib/deploy/events/apiGateway/validate.js @@ -26,6 +26,11 @@ module.exports = { cors.origin = http.cors.origin || '*'; cors.allowCredentials = cors.allowCredentials || http.cors.allowCredentials; + // when merging, last one defined wins + if (_.has(http.cors, 'maxAge')) { + cors.maxAge = http.cors.maxAge; + } + corsPreflight[http.path] = cors; } diff --git a/lib/deploy/events/apiGateway/validate.test.js b/lib/deploy/events/apiGateway/validate.test.js index 01462087..5e9edf2f 100644 --- a/lib/deploy/events/apiGateway/validate.test.js +++ b/lib/deploy/events/apiGateway/validate.test.js @@ -413,4 +413,29 @@ describe('#httpValidate()', () => { expect(validated.events).to.be.an('Array').with.length(1); expect(validated.events[0].http.cors.methods).to.deep.equal(['POST', 'OPTIONS']); }); + + it('should set cors Access-Control-Max-Age headers', () => { + serverlessStepFunctions.serverless.service.stepFunctions = { + stateMachines: { + first: { + events: [ + { + http: { + method: 'POST', + path: '/foo/bar', + cors: { + origin: '*', + maxAge: 86400, + }, + }, + }, + ], + }, + }, + }; + + const validated = serverlessStepFunctions.httpValidate(); + expect(validated.events[0].http.cors.origin).to.equal('*'); + expect(validated.events[0].http.cors.maxAge).to.equal(86400); + }); }); diff --git a/package-lock.json b/package-lock.json index 6eabfbfb..2262e10b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "serverless-step-functions", - "version": "1.5.0", + "version": "1.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -12,15 +12,85 @@ "requires": { "isomorphic-fetch": "2.2.1", "ramda": "0.24.1", - "url-parse": "1.3.0" + "url-parse": "1.4.1" } }, - "@types/graphql": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.10.2.tgz", - "integrity": "sha512-Ayw0w+kr8vYd8DToiMXjcHxXv1ljWbqX2mnLwXDxkBgog3vywGriC0JZ+npsuohKs3+E88M8OOtobo4g0X3SIA==", + "@serverless/platform-sdk": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@serverless/platform-sdk/-/platform-sdk-0.1.5.tgz", + "integrity": "sha512-d61v7iSAqvNlT+9TBZnsJwmSmVtu6MERwa+IUTHj46RwICPYsup3dB0U4jy3mhTAk1XtQ+EWuUOSTZdck2aD8w==", "dev": true, - "optional": true + "requires": { + "babel-polyfill": "6.26.0", + "bluebird": "3.5.1", + "body-parser": "1.18.3", + "chalk": "2.4.1", + "cors": "2.8.4", + "express": "4.16.3", + "is-docker": "1.1.0", + "is-wsl": "1.1.0", + "isomorphic-fetch": "2.2.1", + "node-fetch": "2.1.2", + "opn": "5.3.0", + "querystring": "0.2.0", + "ramda": "0.25.0", + "source-map-support": "0.5.6" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.2" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", + "dev": true + }, + "ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } }, "abbrev": { "version": "1.0.9", @@ -28,6 +98,33 @@ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "2.1.18", + "negotiator": "0.6.1" + }, + "dependencies": { + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "1.33.0" + } + } + } + }, "acorn": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", @@ -52,21 +149,12 @@ } }, "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", - "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "extend": "3.0.1", - "semver": "5.0.3" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "dev": true - } + "es6-promisify": "5.0.0" } }, "ajv": { @@ -166,33 +254,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "apollo-client": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-1.9.3.tgz", - "integrity": "sha512-JABKKbqvcw8DJm3YUkEmyx1SK74i+/DesEtAtyocJi10LLmeMQYQFpg8W3BG1tZsYEQ3owEmPbsdNGTly+VOQg==", - "dev": true, - "requires": { - "@types/graphql": "0.10.2", - "apollo-link-core": "0.5.4", - "graphql": "0.10.5", - "graphql-anywhere": "3.1.0", - "graphql-tag": "2.8.0", - "redux": "3.7.2", - "symbol-observable": "1.2.0", - "whatwg-fetch": "2.0.4" - } - }, - "apollo-link-core": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/apollo-link-core/-/apollo-link-core-0.5.4.tgz", - "integrity": "sha512-OxL0Kjizb0eS2ObldDqJEs/tFN9xI9RZuTJcaszgGy+xudoPXhIMCHMr7hGZhy0mK+U+BbBULZJw4YQU4J0ODQ==", - "dev": true, - "requires": { - "graphql": "0.10.5", - "graphql-tag": "2.8.0", - "zen-observable-ts": "0.4.4" - } - }, "archiver": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz", @@ -200,23 +261,31 @@ "dev": true, "requires": { "archiver-utils": "1.3.0", - "async": "2.6.0", + "async": "2.6.1", "buffer-crc32": "0.2.13", "glob": "7.1.2", "lodash": "4.17.4", "readable-stream": "2.2.11", - "tar-stream": "1.5.5", + "tar-stream": "1.6.1", "walkdir": "0.0.11", "zip-stream": "1.2.0" }, "dependencies": { "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "4.17.4" + "lodash": "4.17.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + } } } } @@ -236,9 +305,9 @@ } }, "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "requires": { "delegates": "1.0.0", @@ -254,6 +323,12 @@ "sprintf-js": "1.0.3" } }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -354,6 +429,35 @@ "js-tokens": "3.0.1" } }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "regenerator-runtime": "0.10.5" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -382,7 +486,7 @@ "dev": true, "requires": { "readable-stream": "2.3.6", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" }, "dependencies": { "process-nextick-args": { @@ -401,15 +505,15 @@ "inherits": "2.0.3", "isarray": "1.0.0", "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "string_decoder": { @@ -418,7 +522,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } } } @@ -428,6 +532,35 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "boom": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", @@ -445,7 +578,7 @@ "requires": { "ansi-align": "2.0.0", "camelcase": "4.1.0", - "chalk": "2.3.2", + "chalk": "2.4.1", "cli-boxes": "1.0.0", "string-width": "2.1.1", "term-size": "1.2.0", @@ -464,7 +597,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.2" } }, "camelcase": { @@ -474,14 +607,14 @@ "dev": true }, "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -516,9 +649,9 @@ } }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -551,18 +684,52 @@ "ieee754": "1.1.8" } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "1.1.0", + "buffer-fill": "1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -607,17 +774,6 @@ "isurl": "1.0.0", "tunnel-agent": "0.6.0", "url-to-options": "1.0.1" - }, - "dependencies": { - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - } } }, "center-align": { @@ -721,18 +877,18 @@ "dev": true }, "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "1.1.1" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", "dev": true }, "combined-stream": { @@ -745,9 +901,9 @@ } }, "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, "requires": { "graceful-readlink": "1.0.1" @@ -806,7 +962,7 @@ "requires": { "dot-prop": "4.2.0", "graceful-fs": "4.1.11", - "make-dir": "1.2.0", + "make-dir": "1.3.0", "unique-string": "1.0.0", "write-file-atomic": "2.3.0", "xdg-basedir": "3.0.0" @@ -818,16 +974,40 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", "dev": true }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, "cookiejar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", - "integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -836,6 +1016,16 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "vary": "1.1.2" + } + }, "coveralls": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", @@ -880,7 +1070,7 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.2", + "lru-cache": "4.1.3", "shebang-command": "1.2.0", "which": "1.2.14" } @@ -967,7 +1157,7 @@ "decompress-targz": "4.1.1", "decompress-unzip": "4.0.1", "graceful-fs": "4.1.11", - "make-dir": "1.2.0", + "make-dir": "1.3.0", "pify": "2.3.0", "strip-dirs": "2.1.0" } @@ -980,7 +1170,7 @@ "requires": { "file-type": "5.2.0", "is-stream": "1.1.0", - "tar-stream": "1.5.5" + "tar-stream": "1.6.1" } }, "decompress-tarbz2": { @@ -1024,7 +1214,7 @@ "file-type": "3.9.0", "get-stream": "2.3.1", "pify": "2.3.0", - "yauzl": "2.9.1" + "yauzl": "2.10.0" }, "dependencies": { "file-type": { @@ -1063,9 +1253,9 @@ } }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "deep-is": { @@ -1111,6 +1301,18 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -1144,7 +1346,7 @@ "requires": { "caw": "2.0.1", "decompress": "4.2.0", - "filenamify": "2.0.0", + "filenamify": "2.1.0", "get-stream": "3.0.0", "got": "6.7.1", "mkdirp": "0.5.1", @@ -1167,13 +1369,25 @@ "jsbn": "0.1.1" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, "requires": { - "iconv-lite": "0.4.21" + "iconv-lite": "0.4.23" } }, "end-of-stream": { @@ -1243,6 +1457,21 @@ "event-emitter": "0.3.5" } }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "4.2.4" + } + }, "es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -1278,6 +1507,12 @@ "es6-symbol": "3.1.1" } }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1512,6 +1747,12 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", @@ -1549,6 +1790,135 @@ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", "dev": true }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "dev": true, + "requires": { + "accepts": "1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.3", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "1.4.0", + "type-is": "1.6.16", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -1591,9 +1961,9 @@ "dev": true }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "1.2.0" @@ -1632,9 +2002,9 @@ "dev": true }, "filenamify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.0.0.tgz", - "integrity": "sha1-vRYiYsC26Uv7zc8Zo7uzdk94VpU=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", "dev": true, "requires": { "filename-reserved-regex": "2.0.0", @@ -1648,6 +2018,38 @@ "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", "dev": true }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -1708,6 +2110,24 @@ "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", "dev": true }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-extra": { "version": "0.26.7", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", @@ -1874,27 +2294,6 @@ "lodash": "4.17.4" } }, - "graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "dev": true, - "requires": { - "iterall": "1.2.2" - } - }, - "graphql-anywhere": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/graphql-anywhere/-/graphql-anywhere-3.1.0.tgz", - "integrity": "sha1-PqDY6GRrXO5oA1AWqadVfBXCHpY=", - "dev": true - }, - "graphql-tag": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.8.0.tgz", - "integrity": "sha1-Us3qB6hCFU7BGi6EDBG5d/m4Nc4=", - "dev": true - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -2022,6 +2421,18 @@ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", "dev": true }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.5.0" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2034,20 +2445,30 @@ } }, "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "2.1.1", - "debug": "2.6.8", - "extend": "3.0.1" + "agent-base": "4.2.1", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "iconv-lite": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { "safer-buffer": "2.1.2" @@ -2125,6 +2546,12 @@ "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", "dev": true }, + "ipaddr.js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", + "dev": true + }, "is-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", @@ -2393,12 +2820,6 @@ "is-object": "1.0.1" } }, - "iterall": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", - "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==", - "dev": true - }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", @@ -2439,15 +2860,21 @@ "integrity": "sha1-uesB/in16j6Sh48VrqEK04taz4k=", "dev": true, "requires": { - "commander": "2.9.0", + "commander": "2.16.0", "graphlib": "2.1.5", - "js-yaml": "3.11.0", + "js-yaml": "3.12.0", "native-promise-only": "0.8.1", "path-loader": "1.0.4", "slash": "1.0.0", "uri-js": "3.0.2" }, "dependencies": { + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "dev": true + }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", @@ -2455,9 +2882,9 @@ "dev": true }, "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "dev": true, "requires": { "argparse": "1.0.9", @@ -2602,12 +3029,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, - "lodash-es": { - "version": "4.17.8", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.8.tgz", - "integrity": "sha512-I9mjAxengFAleSThFhhAhvba6fsO0hunb9/0sQ6qQihSZsJRBofv2rYH58WXaOb/O++eUmYpCLywSQ22GfU+sA==", - "dev": true - }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", @@ -2680,15 +3101,6 @@ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "3.0.1" - } - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -2696,9 +3108,9 @@ "dev": true }, "lru-cache": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", - "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "dev": true, "requires": { "pseudomap": "1.0.2", @@ -2712,9 +3124,9 @@ "dev": true }, "make-dir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", - "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { "pify": "3.0.0" @@ -2728,6 +3140,18 @@ } } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -2735,9 +3159,9 @@ "dev": true }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true }, "mime-db": { @@ -2845,9 +3269,9 @@ "dev": true }, "moment": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.0.tgz", - "integrity": "sha512-1muXCh8jb1N/gHRbn9VDUBr0GYb8A/aVcHlII9QSB68a50spqEVLIGN6KVmCOnSvJrUhC0edGgKU5ofnGXdYdg==", + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", "dev": true }, "ms": { @@ -2874,6 +3298,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -2884,12 +3314,6 @@ "is-stream": "1.1.0" } }, - "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", - "dev": true - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -2942,7 +3366,7 @@ "dev": true, "requires": { "ansi": "0.3.1", - "are-we-there-yet": "1.1.4", + "are-we-there-yet": "1.1.5", "gauge": "1.2.7" } }, @@ -2987,6 +3411,15 @@ "object-keys": "1.0.11" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3085,6 +3518,12 @@ "semver": "5.5.0" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -3119,7 +3558,7 @@ "dev": true, "requires": { "native-promise-only": "0.8.1", - "superagent": "3.8.2" + "superagent": "3.8.3" } }, "path-parse": { @@ -3128,6 +3567,12 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -3221,6 +3666,16 @@ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", "dev": true }, + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "dev": true, + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.6.0" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -3244,9 +3699,9 @@ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "querystringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", - "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", + "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", "dev": true }, "ramda": { @@ -3255,6 +3710,12 @@ "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", "dev": true }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, "raven": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/raven/-/raven-1.2.1.tgz", @@ -3276,13 +3737,25 @@ } } }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, "rc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", - "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "deep-extend": "0.4.2", + "deep-extend": "0.6.0", "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" @@ -3323,17 +3796,11 @@ "resolve": "1.3.3" } }, - "redux": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", - "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", - "dev": true, - "requires": { - "lodash": "4.17.4", - "lodash-es": "4.17.8", - "loose-envify": "1.3.1", - "symbol-observable": "1.2.0" - } + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true }, "registry-auth-token": { "version": "3.3.2", @@ -3341,7 +3808,7 @@ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.6", + "rc": "1.2.8", "safe-buffer": "5.0.1" } }, @@ -3351,7 +3818,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.6" + "rc": "1.2.8" } }, "remove-trailing-separator": { @@ -3542,17 +4009,6 @@ "dev": true, "requires": { "commander": "2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - } } }, "semver": { @@ -3576,19 +4032,69 @@ "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", "dev": true }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.3", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.2" + } + }, "serverless": { - "version": "1.26.1", - "resolved": "https://registry.npmjs.org/serverless/-/serverless-1.26.1.tgz", - "integrity": "sha1-IAN7KM42qzgdNpKQgfNrJJ0SZUI=", + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/serverless/-/serverless-1.28.0.tgz", + "integrity": "sha1-h5OvoK39RbA5a/Ey4w6/gL8efuY=", "dev": true, "requires": { "@serverless/fdk": "0.5.1", - "apollo-client": "1.9.3", + "@serverless/platform-sdk": "0.1.5", "archiver": "1.3.0", "async": "1.5.2", - "aws-sdk": "2.223.1", + "aws-sdk": "2.272.1", "bluebird": "3.5.0", - "chalk": "2.3.2", + "chalk": "2.4.1", "ci-info": "1.1.3", "download": "5.0.3", "fast-levenshtein": "2.0.6", @@ -3597,9 +4103,7 @@ "get-stdin": "5.0.1", "globby": "6.1.0", "graceful-fs": "4.1.11", - "graphql": "0.10.5", - "graphql-tag": "2.8.0", - "https-proxy-agent": "1.0.0", + "https-proxy-agent": "2.2.1", "is-docker": "1.1.0", "js-yaml": "3.6.1", "json-cycle": "1.3.0", @@ -3607,19 +4111,17 @@ "jwt-decode": "2.2.0", "lodash": "4.17.4", "minimist": "1.2.0", - "moment": "2.22.0", + "moment": "2.22.2", "node-fetch": "1.7.3", - "node-forge": "0.7.5", "object-hash": "1.3.0", - "opn": "5.3.0", "promise-queue": "2.2.5", "raven": "1.2.1", - "rc": "1.2.6", + "rc": "1.2.8", "replaceall": "0.1.6", "semver": "5.5.0", "semver-regex": "1.0.0", "tabtab": "2.2.2", - "update-notifier": "2.4.0", + "update-notifier": "2.5.0", "uuid": "2.0.3", "write-file-atomic": "2.3.0", "yaml-ast-parser": "0.0.34" @@ -3631,13 +4133,13 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.2" } }, "aws-sdk": { - "version": "2.223.1", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.223.1.tgz", - "integrity": "sha1-smS/ZAfXx0FS8ItKj9qKrTqEuqQ=", + "version": "2.272.1", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.272.1.tgz", + "integrity": "sha512-txUTnpFUoC7feZYYaKBAfuNO3v8YVkiNj90fHc4R7NfTsA8TY7r8eKi7kOa3gmwZ4LtkOHw/r3ibq+eGt8cjuQ==", "dev": true, "requires": { "buffer": "4.9.1", @@ -3648,8 +4150,7 @@ "sax": "1.2.1", "url": "0.10.3", "uuid": "3.1.0", - "xml2js": "0.4.17", - "xmlbuilder": "4.2.1" + "xml2js": "0.4.17" }, "dependencies": { "uuid": { @@ -3672,14 +4173,14 @@ } }, "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "supports-color": "5.4.0" } }, "globby": { @@ -3702,9 +4203,9 @@ "dev": true }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -3718,6 +4219,12 @@ } } }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -3793,6 +4300,24 @@ "amdefine": "1.0.1" } }, + "source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "1.1.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "spawn-sync": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", @@ -3831,14 +4356,11 @@ "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=", "dev": true }, - "string_decoder": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", - "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true }, "string-width": { "version": "1.0.2", @@ -3851,6 +4373,15 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -3902,32 +4433,23 @@ } }, "superagent": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.2.tgz", - "integrity": "sha512-gVH4QfYHcY3P0f/BZzavLreHW3T1v7hG9B+hpMQotGQqurOvhv87GcMCd6LWySmBuf+BDR44TQd0aISjVHLeNQ==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", "dev": true, "requires": { "component-emitter": "1.2.1", - "cookiejar": "2.1.1", + "cookiejar": "2.1.2", "debug": "3.1.0", "extend": "3.0.1", "form-data": "2.3.2", "formidable": "1.2.1", "methods": "1.1.2", - "mime": "1.6.0", - "qs": "6.5.1", - "readable-stream": "2.2.11" + "mime": "1.4.1", + "qs": "6.5.2", + "readable-stream": "2.3.6" }, "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -3937,22 +4459,41 @@ "ms": "2.0.0" } }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.15" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } } } }, @@ -3961,12 +4502,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", @@ -4055,15 +4590,56 @@ } }, "tar-stream": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", - "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", + "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", "dev": true, "requires": { "bl": "1.2.2", + "buffer-alloc": "1.2.0", "end-of-stream": "1.4.1", - "readable-stream": "2.2.11", + "fs-constants": "1.0.0", + "readable-stream": "2.3.6", + "to-buffer": "1.1.1", "xtend": "4.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + } } }, "term-size": { @@ -4102,6 +4678,12 @@ "os-tmpdir": "1.0.2" } }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, "tough-cookie": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", @@ -4165,6 +4747,33 @@ "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", "dev": true }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + }, + "dependencies": { + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "1.33.0" + } + } + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -4237,6 +4846,12 @@ "crypto-random-string": "1.0.0" } }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "unzip-response": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", @@ -4244,13 +4859,13 @@ "dev": true }, "update-notifier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.4.0.tgz", - "integrity": "sha1-+bTHAPv9TsEsgRWHJYd31WPYyGY=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { "boxen": "1.3.0", - "chalk": "2.3.2", + "chalk": "2.4.1", "configstore": "3.1.2", "import-lazy": "2.1.0", "is-ci": "1.1.0", @@ -4267,18 +4882,18 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "1.9.2" } }, "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -4288,9 +4903,9 @@ "dev": true }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -4304,13 +4919,13 @@ "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", "dev": true, "requires": { - "punycode": "2.1.0" + "punycode": "2.1.1" }, "dependencies": { "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true } } @@ -4325,12 +4940,12 @@ } }, "url-parse": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.3.0.tgz", - "integrity": "sha512-zPvPA3T7P6M+0iNsgX+iAcAz4GshKrowtQBHHc/28tVsBc8jK7VRCNX+2GEcoE6zDB6XqXhcyiUWPVZY6C70Cg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.1.tgz", + "integrity": "sha512-x95Td74QcvICAA0+qERaVkRpTGKyBHHYdwL2LXZm5t/gBtCB9KQSO/0zQgSTYEV1p0WcvSg79TLNPSvd5IDJMQ==", "dev": true, "requires": { - "querystringify": "1.0.0", + "querystringify": "2.0.0", "requires-port": "1.0.0" } }, @@ -4381,11 +4996,23 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "uuid": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=" }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -4554,21 +5181,15 @@ } }, "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" + "fd-slicer": "1.1.0" } }, - "zen-observable-ts": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.4.4.tgz", - "integrity": "sha512-SNVY1sWWhoe7FwFmHpD9ERi+7Mhhj3+JdS0BGy2UxLIg7cY+3zQbyZauQCI6DN6YK4uoKNaIm3S7Qkqi1Lr+Fw==", - "dev": true - }, "zip-stream": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", diff --git a/package.json b/package.json index a4959efc..0cc3abc9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "istanbul": "^0.4.4", "mocha": "^5.2.0", "mocha-lcov-reporter": "^1.2.0", - "serverless": "^1.26.1", + "serverless": "^1.27.3", "sinon": "^1.17.5" }, "dependencies": {