diff --git a/.gitignore b/.gitignore index 8357805..58191a8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .serverless data/*.mmdb node_modules -package-lock.json \ No newline at end of file +package-lock.json +yarn-error.log diff --git a/README.md b/README.md index 447a569..527931c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ Use AWS Lambda and [MaxMind GeoLite](http://dev.maxmind.com/geoip/geoip2/geolite2/) to query for locations of IP addresses. You can invoke the function or use API Gateway to send an HTTP request with the IP address to lookup. +## Why +Since FreeGeoIP has deprecated their [free api](https://github.com/apilayer/freegeoip#readme), we decided to implement this in lambda. + +```bash +curl \ +-H "Content-Type: application/json" \ +https://geoip.scw.video/ip/172.217.8.206 +``` + +Feel free to utilize our api endpoint hosted by [security-camera-warehouse.com](https://www.security-camera-warehouse.com/) ## Install ```bash @@ -22,6 +32,18 @@ Download the [GeoLite2 City](http://dev.maxmind.com/geoip/geoip2/geolite2/) data ## Deploy +### Dependencies +[serverless-domain-manager](https://securitycw.atlassian.net/wiki/spaces/DEV/pages/32571396/Serverless#Serverless-Serverless-domain-manager) +[serverless-aws-documentation](https://securitycw.atlassian.net/wiki/spaces/DEV/pages/32571396/Serverless#Serverless-Serverless-aws-documentation) + +Run +```bash +serverless create-domain +``` +Wait 40 minutes for domain to create if it's new + +### yarn deploy + ```bash $ > yarn deploy @@ -33,6 +55,7 @@ endpoints: ## Usage + ### Invoke ```bash @@ -57,4 +80,9 @@ $ > sls invoke -f lookup --data '{ "ip": "8.8.8.8" }' $ > curl https://randomid.execute-api.us-east-1.amazonaws.com/dev/ip/8.8.8.8 {"continent":{"code":"NA","geoname_id":6255149,"names":{"de":"Nordamerika","en":"North America", … +``` + +### Remove Domain with +```bash +serverless delete_domain ``` \ No newline at end of file diff --git a/models/awsError.yml b/models/awsError.yml new file mode 100644 index 0000000..1defaec --- /dev/null +++ b/models/awsError.yml @@ -0,0 +1,10 @@ +name: "awsError" +description: "an aws internal server error, usually with status code 502 (bad gateway)" +contentType: "application/json" +schema: + type: object + properties: + message: + type: string + required: + - message \ No newline at end of file diff --git a/models/city.yml b/models/city.yml new file mode 100644 index 0000000..7259fe3 --- /dev/null +++ b/models/city.yml @@ -0,0 +1,13 @@ +name: "city" +description: "a city object returned from api" +##contentType: "application/json" +schema: + type: object + properties: + confidence: + type: integer + format: int32 + geoname_id: + type: integer + format: int32 + names: ${file(models/names.yml):schema} \ No newline at end of file diff --git a/models/continent.yml b/models/continent.yml new file mode 100644 index 0000000..c88fabf --- /dev/null +++ b/models/continent.yml @@ -0,0 +1,12 @@ +name: "continent" +description: "a continent object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + code: + type: string + geoname_id: + type: integer + format: int32 + names: ${file(models/names.yml):schema} \ No newline at end of file diff --git a/models/country.yml b/models/country.yml new file mode 100644 index 0000000..d7924f6 --- /dev/null +++ b/models/country.yml @@ -0,0 +1,15 @@ +name: "country" +description: "a country object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + confidence: + type: integer + format: int32 + geoname_id: + type: integer + format: int32 + iso_code: + type: string + names: ${file(models/names.yml):schema} \ No newline at end of file diff --git a/models/ip.yml b/models/ip.yml new file mode 100644 index 0000000..19c3bc7 --- /dev/null +++ b/models/ip.yml @@ -0,0 +1,29 @@ +name: "ip" +description: "a ip object returned from api at /ip/{ip}" +contentType: "application/json" +schema: + type: object + properties: + city: ${file(models/city.yml):schema} + continent: ${file(models/continent.yml):schema} + country: ${file(models/country.yml):schema} + location: ${file(models/location.yml):schema} + postal: ${file(models/postal.yml):schema} + registered_country: ${file(models/registered_country.yml):schema} + represented_country: ${file(models/represented_country.yml):schema} + subdivisions: + type: array + items: ${file(models/subdivisions.yml):schema} + traits: ${file(models/traits.yml):schema} + maxmind: ${file(models/maxmind.yml):schema} + required: + - city + - continent + - country + - location + - postal + - registered_country + - represented_country + - subdivisions + - traits + - maxmind \ No newline at end of file diff --git a/models/ipResponse.yml b/models/ipResponse.yml new file mode 100644 index 0000000..56172be --- /dev/null +++ b/models/ipResponse.yml @@ -0,0 +1,6 @@ +name: ipResponse +description: "default ip response" +contentType: "application/json" +schema: + type: object + properties: ${file(models/ip.yml):schema.properties} \ No newline at end of file diff --git a/models/location.yml b/models/location.yml new file mode 100644 index 0000000..0df9c6a --- /dev/null +++ b/models/location.yml @@ -0,0 +1,26 @@ +name: "location" +description: "a location object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + accuracy_radius: + type: integer + format: int32 + average_income: + type: integer + format: int64 + latitude: + type: integer + format: int64 + longitude: + type: integer + format: int64 + metro_code: + type: integer + format: int32 + population_density: + type: integer + format: int32 + time_zone: + type: string \ No newline at end of file diff --git a/models/maxmind.yml b/models/maxmind.yml new file mode 100644 index 0000000..b6098ac --- /dev/null +++ b/models/maxmind.yml @@ -0,0 +1,9 @@ +name: "maxmind" +description: "a maxmind object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + queries_remaining: + type: integer + format: int64 \ No newline at end of file diff --git a/models/names.yml b/models/names.yml new file mode 100644 index 0000000..92eb63e --- /dev/null +++ b/models/names.yml @@ -0,0 +1,22 @@ +name: "names" +description: "a names object with localized names" +#contentType: "application/json" +schema: + type: object + properties: + de: + type: string + en: + type: string + es: + type: string + fr: + type: string + ja: + type: string + pt-BR: + type: string + ru: + type: string + zh-CN: + type: string \ No newline at end of file diff --git a/models/postal.yml b/models/postal.yml new file mode 100644 index 0000000..2af029a --- /dev/null +++ b/models/postal.yml @@ -0,0 +1,11 @@ +name: "postal" +description: "a postal object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + code: + type: string + confidence: + type: integer + format: int64 \ No newline at end of file diff --git a/models/registered_country.yml b/models/registered_country.yml new file mode 100644 index 0000000..56e3b7e --- /dev/null +++ b/models/registered_country.yml @@ -0,0 +1,12 @@ +name: "registered_country" +description: "a registered_country object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + geoname_id: + type: integer + format: int64 + iso_code: + type: string + names: ${file(models/names.yml):schema} \ No newline at end of file diff --git a/models/represented_country.yml b/models/represented_country.yml new file mode 100644 index 0000000..0804da2 --- /dev/null +++ b/models/represented_country.yml @@ -0,0 +1,11 @@ +name: "represented_country" +description: "a represented_country object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + iso_code: + type: string + names: ${file(models/names.yml):schema} + type: + type: string \ No newline at end of file diff --git a/models/subdivisions.yml b/models/subdivisions.yml new file mode 100644 index 0000000..284f226 --- /dev/null +++ b/models/subdivisions.yml @@ -0,0 +1,15 @@ +name: "subdivisions" +description: "a subdivisions object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + confidence: + type: integer + format: int32 + geoname_id: + type: integer + format: int64 + iso_code: + type: string + names: ${file(models/names.yml):schema} \ No newline at end of file diff --git a/models/traits.yml b/models/traits.yml new file mode 100644 index 0000000..2adc87e --- /dev/null +++ b/models/traits.yml @@ -0,0 +1,25 @@ +name: "traits" +description: "a traits object returned from api" +#contentType: "application/json" +schema: + type: object + properties: + autonomous_system_number: + type: integer + format: int64 + autonomous_system_organization: + type: string + domain: + type: string + is_anonymous_proxy: + type: boolean + is_satellite_provider: + type: boolean + isp: + type: string + ip_address: + type: string + organization: + type: string + user_type: + type: string \ No newline at end of file diff --git a/package.json b/package.json index 51729b7..aa10d60 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "mmdb-reader": "^1.1.0" }, "devDependencies": { - "serverless": "^1.24.0" + "serverless": "^1.24.0", + "serverless-aws-documentation": "^1.0.1", + "serverless-domain-manager": "^2.3.6" } } diff --git a/serverless.yml b/serverless.yml index de883b0..9fa89f5 100644 --- a/serverless.yml +++ b/serverless.yml @@ -3,9 +3,10 @@ service: serverless-geoip provider: name: aws runtime: nodejs6.10 - memorySize: 256 + memorySize: 512 timeout: 30 region: us-east-1 + stage: prod package: exclude: @@ -17,22 +18,70 @@ package: - yarn.lock - package.json - package-lock.json + - swagger/** + - node_modules/aws-sdk/** functions: lookup: handler: src/lookup.run events: - - http: - method: GET - path: /ip/{ip} + - http: + path: ip/{ip} + method: get integration: lambda + cors: true + #private: true request: parameters: paths: ip: true - template: - application/json: '{ "ip" : "$input.params(''ip'')" }' response: headers: Content-Type: "'application/json'" - template: $input.json('$') \ No newline at end of file + template: $input.json('$') + documentation: + summary: "pass in an ip address and return an ip object with location information on the ip address" + pathParams: + - + name: "ip" + description: "public ip address you want to return geoip data on" + required: true + schema: + type: string + methodResponses: + - + statusCode: "200" + responseBody: + description: "an ip address object" + responseModels: + "application/json": "ipResponse" + - + statusCode: "502" + responseModels: + "application/json": "awsError" +plugins: + - serverless-domain-manager + - serverless-aws-documentation + +custom: + customDomain: + domainName: geoip.scw.video + stage: prod + basePath: + certificateName: '*.scw.video' + createRoute53Record: true + endpointType: 'edge' + documentation: + api: + info: + version: '1' + summary: 'geolite geoip api' + description: ' endpoint for internal geoip lookups' + resources: + - + path: "ip/{ip}" + description: "path used to query information on an ip address" + models: + - ${file(models/ip.yml)} + - ${file(models/ipResponse.yml)} + - ${file(models/awsError.yml)} diff --git a/src/log.js b/src/log.js new file mode 100644 index 0000000..063cf01 --- /dev/null +++ b/src/log.js @@ -0,0 +1,22 @@ +"use strict"; + + +// NOTE: Replace this with a logger suitable for production, +// such as Winston or Bunyan. However, to use those loggers +// with CloudWatch, you'll need to install the CloudWatch Logs +// agent on your EC2 instances. + +exports.info = (msg) => { + + console.log(`[${new Date().toLocaleString('en-US')}] [INFO] ${msg}`); +} + +exports.warn = (msg) => { + + console.log(`[${new Date().toLocaleString('en-US')}] [WARN] ${msg}`); +} + +exports.error = (msg) => { + + console.log(`[${new Date().toLocaleString('en-US')}] [ERROR] ${msg}`); +} \ No newline at end of file diff --git a/src/lookup.js b/src/lookup.js index 2f9879f..3f596d5 100644 --- a/src/lookup.js +++ b/src/lookup.js @@ -1,13 +1,14 @@ const Reader = require('mmdb-reader') +const log = require('./log') const run = (event, ctx, callback) => { - if (!event || !event.ip) { + if (!event || !event.path.ip) { callback( new Error('Invalid event data, requires IP address') ) } else { Reader.open(__dirname + '/../data/GeoLite2-City.mmdb', - (error, reader) => callback(error, !error && reader.lookup(event.ip)) + (error, reader) => callback(error, !error && reader.lookup(event.path.ip)) ) } } diff --git a/swagger.yml b/swagger.yml new file mode 100644 index 0000000..6c8761e --- /dev/null +++ b/swagger.yml @@ -0,0 +1,145 @@ +--- +swagger: "2.0" +info: + description: " endpoint for internal geoip lookups" + version: "2018-04-12T00:06:32Z" + title: "prod-serverless-geoip" +host: "geoip.scw.video" +schemes: +- "https" +paths: + /ip/{ip}: + get: + summary: "pass in an ip address string and return an ip object with location\ + \ information on the ip address" + consumes: + - "application/json" + - "application/x-www-form-urlencoded" + produces: + - "application/json" + parameters: + - name: "ip" + in: "path" + description: "ip address string" + required: true + type: "string" + - in: "body" + name: "ipRequest" + description: "body containing ip address string, {\"ip\": \"8.8.8.8\"} or\ + \ ip/8.8.8.8" + required: true + schema: + $ref: "#/definitions/ipRequest" + responses: + 200: + description: "200 response" + schema: + $ref: "#/definitions/ipResponse" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 422: + description: "422 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 400: + description: "400 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 500: + description: "500 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 401: + description: "401 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 502: + description: "502 response" + schema: + $ref: "#/definitions/awsError" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 403: + description: "403 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 404: + description: "404 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 504: + description: "504 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + options: + consumes: + - "application/json" + produces: + - "application/json" + responses: + 200: + description: "200 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Access-Control-Allow-Methods: + type: "string" + Access-Control-Allow-Credentials: + type: "string" + Access-Control-Allow-Headers: + type: "string" +definitions: + ipRequest: + type: "object" + required: + - "text" + properties: + text: + type: "string" + format: "string" + description: "a simple request model for ip/{ip}" + ipResponse: + type: "object" + required: + - "text" + properties: + text: + type: "string" + format: "string" + description: "default ip response" + awsError: + type: "object" + required: + - "message" + properties: + message: + type: "string" + description: "an aws internal server error, usually with status code 502 (bad\ + \ gateway)" diff --git a/swagger/README.md b/swagger/README.md new file mode 100644 index 0000000..4c894e8 --- /dev/null +++ b/swagger/README.md @@ -0,0 +1 @@ +# Skeleton project for Swagger diff --git a/swagger/api/controllers/README.md b/swagger/api/controllers/README.md new file mode 100644 index 0000000..ddb3f64 --- /dev/null +++ b/swagger/api/controllers/README.md @@ -0,0 +1 @@ +Place your controllers in this directory. diff --git a/swagger/api/controllers/hello_world.js b/swagger/api/controllers/hello_world.js new file mode 100644 index 0000000..2e17de7 --- /dev/null +++ b/swagger/api/controllers/hello_world.js @@ -0,0 +1,44 @@ +'use strict'; +/* + 'use strict' is not required but helpful for turning syntactical errors into true errors in the program flow + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode +*/ + +/* + Modules make it possible to import JavaScript files into your application. Modules are imported + using 'require' statements that give you a reference to the module. + + It is a good idea to list the modules that your application depends on in the package.json in the project root + */ +var util = require('util'); + +/* + Once you 'require' a module you can reference the things that it exports. These are defined in module.exports. + + For a controller in a127 (which this is) you should export the functions referenced in your Swagger document by name. + + Either: + - The HTTP Verb of the corresponding operation (get, put, post, delete, etc) + - Or the operationId associated with the operation in your Swagger document + + In the starter/skeleton project the 'get' operation on the '/hello' path has an operationId named 'hello'. Here, + we specify that in the exports of this module that 'hello' maps to the function named 'hello' + */ +module.exports = { + hello: hello +}; + +/* + Functions in a127 controllers used for operations should take two parameters: + + Param 1: a handle to the request object + Param 2: a handle to the response object + */ +function hello(req, res) { + // variables defined in the Swagger document can be referenced using req.swagger.params.{parameter_name} + var name = req.swagger.params.name.value || 'stranger'; + var hello = util.format('Hello, %s!', name); + + // this sends back a JSON response which is a single string + res.json(hello); +} diff --git a/swagger/api/helpers/README.md b/swagger/api/helpers/README.md new file mode 100644 index 0000000..36a598f --- /dev/null +++ b/swagger/api/helpers/README.md @@ -0,0 +1 @@ +Place helper files in this directory. diff --git a/swagger/api/mocks/README.md b/swagger/api/mocks/README.md new file mode 100644 index 0000000..51416ce --- /dev/null +++ b/swagger/api/mocks/README.md @@ -0,0 +1 @@ +Place controllers for mock mode in this directory. diff --git a/swagger/api/swagger/swagger.yaml b/swagger/api/swagger/swagger.yaml new file mode 100644 index 0000000..6c8761e --- /dev/null +++ b/swagger/api/swagger/swagger.yaml @@ -0,0 +1,145 @@ +--- +swagger: "2.0" +info: + description: " endpoint for internal geoip lookups" + version: "2018-04-12T00:06:32Z" + title: "prod-serverless-geoip" +host: "geoip.scw.video" +schemes: +- "https" +paths: + /ip/{ip}: + get: + summary: "pass in an ip address string and return an ip object with location\ + \ information on the ip address" + consumes: + - "application/json" + - "application/x-www-form-urlencoded" + produces: + - "application/json" + parameters: + - name: "ip" + in: "path" + description: "ip address string" + required: true + type: "string" + - in: "body" + name: "ipRequest" + description: "body containing ip address string, {\"ip\": \"8.8.8.8\"} or\ + \ ip/8.8.8.8" + required: true + schema: + $ref: "#/definitions/ipRequest" + responses: + 200: + description: "200 response" + schema: + $ref: "#/definitions/ipResponse" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 422: + description: "422 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 400: + description: "400 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 500: + description: "500 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 401: + description: "401 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 502: + description: "502 response" + schema: + $ref: "#/definitions/awsError" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 403: + description: "403 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 404: + description: "404 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + 504: + description: "504 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Content-Type: + type: "string" + options: + consumes: + - "application/json" + produces: + - "application/json" + responses: + 200: + description: "200 response" + headers: + Access-Control-Allow-Origin: + type: "string" + Access-Control-Allow-Methods: + type: "string" + Access-Control-Allow-Credentials: + type: "string" + Access-Control-Allow-Headers: + type: "string" +definitions: + ipRequest: + type: "object" + required: + - "text" + properties: + text: + type: "string" + format: "string" + description: "a simple request model for ip/{ip}" + ipResponse: + type: "object" + required: + - "text" + properties: + text: + type: "string" + format: "string" + description: "default ip response" + awsError: + type: "object" + required: + - "message" + properties: + message: + type: "string" + description: "an aws internal server error, usually with status code 502 (bad\ + \ gateway)" diff --git a/swagger/app.js b/swagger/app.js new file mode 100644 index 0000000..f4c29ab --- /dev/null +++ b/swagger/app.js @@ -0,0 +1,23 @@ +'use strict'; + +var SwaggerExpress = require('swagger-express-mw'); +var app = require('express')(); +module.exports = app; // for testing + +var config = { + appRoot: __dirname // required config +}; + +SwaggerExpress.create(config, function(err, swaggerExpress) { + if (err) { throw err; } + + // install middleware + swaggerExpress.register(app); + + var port = process.env.PORT || 10010; + app.listen(port); + + if (swaggerExpress.runner.swagger.paths['/hello']) { + console.log('try this:\ncurl http://127.0.0.1:' + port + '/hello?name=Scott'); + } +}); diff --git a/swagger/config/README.md b/swagger/config/README.md new file mode 100644 index 0000000..d0535bd --- /dev/null +++ b/swagger/config/README.md @@ -0,0 +1 @@ +Place configuration files in this directory. diff --git a/swagger/config/default.yaml b/swagger/config/default.yaml new file mode 100644 index 0000000..cbe55eb --- /dev/null +++ b/swagger/config/default.yaml @@ -0,0 +1,37 @@ +# swagger configuration file + +# values in the swagger hash are system configuration for swagger-node +swagger: + + fittingsDirs: [ api/fittings ] + defaultPipe: null + swaggerControllerPipe: swagger_controllers # defines the standard processing pipe for controllers + + # values defined in the bagpipes key are the bagpipes pipes and fittings definitions + # (see https://github.com/apigee-127/bagpipes) + bagpipes: + + _router: + name: swagger_router + mockMode: false + mockControllersDirs: [ api/mocks ] + controllersDirs: [ api/controllers ] + + _swagger_validate: + name: swagger_validator + validateResponse: true + + # pipe for all swagger-node controllers + swagger_controllers: + - onError: json_error_handler + - cors + - swagger_security + - _swagger_validate + - express_compatibility + - _router + + # pipe to serve swagger (endpoint is in swagger.yaml) + swagger_raw: + name: swagger_raw + +# any other values in this file are just loaded into the config for application access... diff --git a/swagger/package.json b/swagger/package.json new file mode 100644 index 0000000..98e49fe --- /dev/null +++ b/swagger/package.json @@ -0,0 +1,22 @@ +{ + "name": "serverless-geoip", + "version": "0.0.1", + "private": true, + "description": "New Swagger API Project", + "keywords": [], + "author": "", + "license": "", + "main": "app.js", + "dependencies": { + "express": "^4.12.3", + "swagger-express-mw": "^0.1.0" + }, + "devDependencies": { + "should": "^7.1.0", + "supertest": "^1.0.0" + }, + "scripts": { + "start": "node app.js", + "test": "swagger project test" + } +} diff --git a/swagger/serverless-geoip/.gitignore b/swagger/serverless-geoip/.gitignore new file mode 100644 index 0000000..65f91cd --- /dev/null +++ b/swagger/serverless-geoip/.gitignore @@ -0,0 +1,34 @@ +# IDE files +.idea + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules + +# Users Environment Variables +.lock-wscript + +# Runtime configuration for swagger app +config/runtime.yaml diff --git a/swagger/test/api/controllers/README.md b/swagger/test/api/controllers/README.md new file mode 100644 index 0000000..16437ee --- /dev/null +++ b/swagger/test/api/controllers/README.md @@ -0,0 +1 @@ +Place your controller tests in this directory. diff --git a/swagger/test/api/controllers/hello_world.js b/swagger/test/api/controllers/hello_world.js new file mode 100644 index 0000000..38f8093 --- /dev/null +++ b/swagger/test/api/controllers/hello_world.js @@ -0,0 +1,48 @@ +var should = require('should'); +var request = require('supertest'); +var server = require('../../../app'); + +describe('controllers', function() { + + describe('hello_world', function() { + + describe('GET /hello', function() { + + it('should return a default string', function(done) { + + request(server) + .get('/hello') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function(err, res) { + should.not.exist(err); + + res.body.should.eql('Hello, stranger!'); + + done(); + }); + }); + + it('should accept a name parameter', function(done) { + + request(server) + .get('/hello') + .query({ name: 'Scott'}) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function(err, res) { + should.not.exist(err); + + res.body.should.eql('Hello, Scott!'); + + done(); + }); + }); + + }); + + }); + +}); diff --git a/swagger/test/api/helpers/README.md b/swagger/test/api/helpers/README.md new file mode 100644 index 0000000..8528f1b --- /dev/null +++ b/swagger/test/api/helpers/README.md @@ -0,0 +1 @@ +Place your helper tests in this directory. diff --git a/yarn.lock b/yarn.lock index 704c9ea..e44bc5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,9 +43,9 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: color-convert "^1.9.0" @@ -108,8 +108,8 @@ are-we-there-yet@~1.1.2: readable-stream "^2.0.6" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" @@ -128,8 +128,8 @@ async@^1.5.2: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" async@^2.0.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" dependencies: lodash "^4.14.0" @@ -137,13 +137,13 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sdk@^2.75.0: - version "2.142.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.142.0.tgz#efdf69d2be3132aa51d4e7abb2c28fe42771e3ec" +aws-sdk@^2.177.0, aws-sdk@^2.75.0: + version "2.224.1" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.224.1.tgz#82fe93e10b3e818f315c35ce8667cdc8db94a0b3" dependencies: buffer "4.9.1" - crypto-browserify "1.0.9" - events "^1.1.1" + events "1.1.1" + ieee754 "1.1.8" jmespath "0.15.0" querystring "0.2.0" sax "1.2.1" @@ -161,26 +161,27 @@ base64-js@0.0.8: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" base64-js@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + version "1.2.3" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801" big-integer@^1.5.4: - version "1.6.25" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.25.tgz#1de45a9f57542ac20121c682f8d642220a34e823" + version "1.6.28" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.28.tgz#8cef0fda3ccde8759c2c66efcfacc35aea658283" bl@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" dependencies: - readable-stream "^2.0.5" + readable-stream "^2.3.5" + safe-buffer "^5.1.1" bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" boxen@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.2.2.tgz#3f1d4032c30ffea9d4b02c322eaf2ea741dcbce5" + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" dependencies: ansi-align "^2.0.0" camelcase "^4.0.0" @@ -188,11 +189,11 @@ boxen@^1.2.1: cli-boxes "^1.0.0" string-width "^2.0.0" term-size "^1.2.0" - widest-line "^1.0.0" + widest-line "^2.0.0" brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -201,6 +202,10 @@ buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" +buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + buffer@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" @@ -245,16 +250,16 @@ chalk@^1.0.0: supports-color "^2.0.0" chalk@^2.0.0, chalk@^2.0.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" dependencies: - ansi-styles "^3.1.0" + ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" - supports-color "^4.0.0" + supports-color "^5.3.0" -ci-info@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a" +ci-info@^1.0.0, ci-info@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" cli-boxes@^1.0.0: version "1.0.0" @@ -275,8 +280,8 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" color-convert@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" dependencies: color-name "^1.1.1" @@ -284,15 +289,15 @@ color-name@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -combined-stream@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" +combined-stream@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" dependencies: delayed-stream "~1.0.0" commander@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" commander@~2.8.1: version "2.8.1" @@ -318,9 +323,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" concat-stream@^1.4.7: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: + buffer-from "^1.0.0" inherits "^2.0.3" readable-stream "^2.2.2" typedarray "^0.0.6" @@ -333,8 +339,8 @@ config-chain@^1.1.11: proto-list "~1.2.1" configstore@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -380,10 +386,6 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -crypto-browserify@1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" - crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" @@ -489,8 +491,8 @@ encoding@^0.1.11: iconv-lite "~0.4.13" end-of-stream@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" dependencies: once "^1.4.0" @@ -502,7 +504,7 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -events@^1.1.1: +events@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -534,6 +536,10 @@ external-editor@^1.1.0: spawn-sync "^1.0.15" tmp "^0.0.29" +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + fd-slicer@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" @@ -572,20 +578,20 @@ filenamify@^2.0.0: trim-repeated "^1.0.0" filesize@^3.3.0: - version "3.5.11" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee" + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" form-data@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: asynckit "^0.4.0" - combined-stream "^1.0.5" + combined-stream "1.0.6" mime-types "^2.1.12" formidable@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" + version "1.2.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" fs-extra@^0.26.7: version "0.26.7" @@ -644,8 +650,8 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: path-is-absolute "^1.0.0" global-dirs@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.0.tgz#10d34039e0df04272e262cf24224f7209434df4f" + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" dependencies: ini "^1.3.4" @@ -684,8 +690,8 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2 resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" graphlib@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.1.tgz#42352c52ba2f4d035cb566eb91f7395f76ebc951" + version "2.1.5" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.5.tgz#6afe1afcc5148555ec799e499056795bd6938c87" dependencies: lodash "^4.11.1" @@ -694,8 +700,8 @@ graphql-anywhere@^3.0.1: resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-3.1.0.tgz#3ea0d8e8646b5cee68035016a9a7557c15c21e96" graphql-tag@^2.0.0, graphql-tag@^2.4.0, graphql-tag@^2.4.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.5.0.tgz#b43bfd8b5babcd2c205ad680c03e98b238934e0f" + version "2.8.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.8.0.tgz#52cdea07a842154ec11a2e840c11b977f9b835ce" graphql@^0.10.0, graphql@^0.10.1, graphql@^0.10.3: version "0.10.5" @@ -709,13 +715,13 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" has-symbol-support-x@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz#66ec2e377e0c7d7ccedb07a3a84d77510ff1bc4c" + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" has-to-string-tag-x@^1.2.0: version "1.4.1" @@ -728,8 +734,8 @@ has-unicode@^2.0.0: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" hashlru@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.2.0.tgz#793a58943f902aea578177d7b0335f13f2694b71" + version "2.2.1" + resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.2.1.tgz#10f2099a0d7c05a40f2beaf5c1d39cf2f7dabf36" https-proxy-agent@^1.0.0: version "1.0.0" @@ -740,13 +746,19 @@ https-proxy-agent@^1.0.0: extend "3" iconv-lite@~0.4.13: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + version "0.4.21" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" + dependencies: + safer-buffer "^2.1.0" -ieee754@^1.1.4: +ieee754@1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" +ieee754@^1.1.4: + version "1.1.11" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -767,8 +779,8 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" ini@^1.3.4, ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" inquirer@^1.0.2: version "1.2.3" @@ -789,6 +801,12 @@ inquirer@^1.0.2: strip-ansi "^3.0.0" through "^2.3.6" +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + is-docker@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1" @@ -827,8 +845,8 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" dependencies: path-is-inside "^1.0.1" @@ -875,8 +893,8 @@ isurl@^1.0.0-alpha5: is-object "^1.0.1" iterall@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9" + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" jmespath@0.15.0: version "0.15.0" @@ -887,12 +905,16 @@ js-tokens@^3.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" js-yaml@^3.6.1, js-yaml@^3.8.3: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" dependencies: argparse "^1.0.7" esprima "^4.0.0" +json-cycle@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/json-cycle/-/json-cycle-1.3.0.tgz#c4f6f7d926c2979012cba173b06f9cae9e866d3f" + json-refs@^2.1.5: version "2.1.7" resolved "https://registry.yarnpkg.com/json-refs/-/json-refs-2.1.7.tgz#b9eb01fe29f5ea3e92878f15aea10ad38b5acf89" @@ -938,8 +960,8 @@ lazystream@^1.0.0: readable-stream "^2.0.5" lodash-es@^4.2.1: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" + version "4.17.8" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.8.tgz#6fa8c8c5d337481df0bdf1c0d899d42473121e45" lodash.difference@^4.5.0: version "4.5.0" @@ -962,8 +984,8 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" lodash@^4.0.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.8.0: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" loose-envify@^1.1.0: version "1.3.1" @@ -972,12 +994,12 @@ loose-envify@^1.1.0: js-tokens "^3.0.0" lowercase-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -987,8 +1009,8 @@ lsmod@1.0.0: resolved "https://registry.yarnpkg.com/lsmod/-/lsmod-1.0.0.tgz#9a00f76dca36eb23fa05350afe1b585d4299e64b" make-dir@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" + version "1.2.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b" dependencies: pify "^3.0.0" @@ -996,19 +1018,19 @@ methods@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" mime-types@^2.1.12: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: - mime-db "~1.30.0" + mime-db "~1.33.0" mime@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" minimatch@^3.0.4: version "3.0.4" @@ -1038,8 +1060,8 @@ mmdb-reader@^1.1.0: hashlru "^2.0.0" moment@^2.13.0: - version "2.19.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.1.tgz#56da1a2d1cbf01d38b7e1afc31c10bcfa1929167" + version "2.22.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.0.tgz#7921ade01017dd45186e7fee5f424f0b8663a730" ms@2.0.0: version "2.0.0" @@ -1061,8 +1083,8 @@ node-fetch@^1.0.1, node-fetch@^1.6.0: is-stream "^1.0.1" node-forge@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" + version "0.7.5" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" normalize-path@^2.0.0: version "2.1.1" @@ -1099,6 +1121,10 @@ object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-hash@^1.1.7, object-hash@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2" + once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1107,11 +1133,11 @@ once@^1.3.0, once@^1.4.0: onetime@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" opn@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" + version "5.3.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" dependencies: is-wsl "^1.1.0" @@ -1181,9 +1207,13 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +promise-queue@^2.2.3: + version "2.2.5" + resolved "https://registry.yarnpkg.com/promise-queue/-/promise-queue-2.2.5.tgz#2f6f5f7c0f6d08109e967659c79b88a9ed5e93b4" proto-list@~1.2.1: version "1.2.4" @@ -1228,24 +1258,24 @@ raven@^1.2.1: uuid "3.0.0" rc@^1.0.1, rc@^1.1.6: - version "1.2.2" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077" + version "1.2.6" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092" dependencies: deep-extend "~0.4.0" ini "~1.3.0" minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" isarray "~1.0.0" - process-nextick-args "~1.0.6" + process-nextick-args "~2.0.0" safe-buffer "~5.1.1" - string_decoder "~1.0.3" + string_decoder "~1.1.1" util-deprecate "~1.0.1" redux@^3.4.0: @@ -1258,8 +1288,8 @@ redux@^3.4.0: symbol-observable "^1.0.3" registry-auth-token@^3.0.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -1305,10 +1335,14 @@ rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" -safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + sax@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -1334,16 +1368,29 @@ semver-regex@^1.0.0: resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" semver@^5.0.3, semver@^5.1.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" semver@~5.0.1: version "5.0.3" resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" +serverless-aws-documentation@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/serverless-aws-documentation/-/serverless-aws-documentation-1.0.1.tgz#316d3602654e97997587464ea7965f69afe04979" + dependencies: + object-hash "^1.1.7" + +serverless-domain-manager@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/serverless-domain-manager/-/serverless-domain-manager-2.3.6.tgz#4ad0b51b27ed1bd69fe5a95ce7d53225d7a24c44" + dependencies: + aws-sdk "^2.177.0" + chalk "^2.0.1" + serverless@^1.24.0: - version "1.24.0" - resolved "https://registry.yarnpkg.com/serverless/-/serverless-1.24.0.tgz#67dad5f03a5511d635893337a3e8c1490cb8b257" + version "1.26.1" + resolved "https://registry.yarnpkg.com/serverless/-/serverless-1.26.1.tgz#20037b28ce36ab381d36929081f36b249d126542" dependencies: "@serverless/fdk" "^0.5.1" apollo-client "^1.9.2" @@ -1354,6 +1401,7 @@ serverless@^1.24.0: chalk "^2.0.0" ci-info "^1.1.1" download "^5.0.2" + fast-levenshtein "^2.0.6" filesize "^3.3.0" fs-extra "^0.26.7" get-stdin "^5.0.1" @@ -1364,6 +1412,7 @@ serverless@^1.24.0: https-proxy-agent "^1.0.0" is-docker "^1.1.0" js-yaml "^3.6.1" + json-cycle "^1.3.0" json-refs "^2.1.5" jwt-decode "^2.2.0" lodash "^4.13.1" @@ -1371,13 +1420,14 @@ serverless@^1.24.0: moment "^2.13.0" node-fetch "^1.6.0" node-forge "^0.7.1" + object-hash "^1.2.0" opn "^5.0.0" + promise-queue "^2.2.3" raven "^1.2.1" rc "^1.1.6" replaceall "^0.1.6" semver "^5.0.3" semver-regex "^1.0.0" - shelljs "^0.6.0" tabtab "^2.2.2" update-notifier "^2.2.0" uuid "^2.0.2" @@ -1394,10 +1444,6 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shelljs@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -1429,16 +1475,16 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0: +string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" dependencies: safe-buffer "~5.1.0" @@ -1469,14 +1515,14 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" strip-outer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.0.tgz#aac0ba60d2e90c5d4f275fd8869fd9a2d310ffb8" + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" dependencies: escape-string-regexp "^1.0.2" superagent@^3.6.3: - version "3.8.0" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.0.tgz#87e3ed536c8860c08c7c7d1225da9a80cab064c6" + version "3.8.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403" dependencies: component-emitter "^1.2.0" cookiejar "^2.1.0" @@ -1493,15 +1539,15 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" +supports-color@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" dependencies: - has-flag "^2.0.0" + has-flag "^3.0.0" symbol-observable@^1.0.2, symbol-observable@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" tabtab@^2.2.2: version "2.2.2" @@ -1517,8 +1563,8 @@ tabtab@^2.2.2: object-assign "^4.1.0" tar-stream@^1.5.0, tar-stream@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016" + version "1.5.5" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" dependencies: bl "^1.0.0" end-of-stream "^1.0.0" @@ -1579,13 +1625,14 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" update-notifier@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.3.0.tgz#4e8827a6bb915140ab093559d7014e3ebb837451" + version "2.4.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.4.0.tgz#f9b4c700fbfd4ec12c811587258777d563d8c866" dependencies: boxen "^1.2.1" chalk "^2.0.1" configstore "^3.0.0" import-lazy "^2.1.0" + is-ci "^1.0.10" is-installed-globally "^0.1.0" is-npm "^1.0.0" latest-version "^3.0.0" @@ -1605,8 +1652,8 @@ url-parse-lax@^1.0.0: prepend-http "^1.0.1" url-parse@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" + version "1.3.0" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.3.0.tgz#04a06c420d22beb9804f7ada2d57ad13160a4258" dependencies: querystringify "~1.0.0" requires-port "~1.0.0" @@ -1643,8 +1690,8 @@ walkdir@^0.0.11: resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" whatwg-fetch@>=0.10.0, whatwg-fetch@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" which@^1.2.9: version "1.3.0" @@ -1652,11 +1699,11 @@ which@^1.2.9: dependencies: isexe "^2.0.0" -widest-line@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" dependencies: - string-width "^1.0.1" + string-width "^2.1.1" wrappy@1: version "1.0.2"