diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..8788e13 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,19 @@ +* **I'm submitting a ...** + - [ ] bug report + - [ ] feature request + - [ ] support request + + +* **What is the current behavior?** + + + +* **What is the expected behavior?** + + + +* **What is the motivation / use case for changing the behavior?** + + + +* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..4030f6f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +Fixes # + +## Proposed Changes + + - + - + - diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8636cdc --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# SSHFS +._* diff --git a/.spectral.yml b/.spectral.yml new file mode 100644 index 0000000..43fcaa6 --- /dev/null +++ b/.spectral.yml @@ -0,0 +1,300 @@ +extends: ["spectral:oas"] +rules: + + # --------------------------------------------------------------------------- + # General OAS rules + # --------------------------------------------------------------------------- + + operation-operationId: false + operation-tags: false + operation-2xx-response: error + + adidas-paths-kebab-case: + description: All YAML/JSON paths MUST follow kebab-case + severity: warn + recommended: true + message: "{{property}} is not kebab-case: {{error}}" + given: $.paths[*]~ + then: + function: pattern + functionOptions: + match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces + + adidas-path-parameters-camelCase-alphanumeric: + description: Path parameters MUST follow camelCase + severity: warn + recommended: true + message: "{{property}} path parameter is not camelCase: {{error}}" + given: $..parameters[?(@.in == 'path')].name + then: + function: pattern + functionOptions: + match: "^[a-z][a-zA-Z0-9]+$" + + adidas-definitions-camelCase-alphanumeric: + description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. + severity: error + recommended: true + message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`." + given: $.definitions[*]~ + then: + function: pattern + functionOptions: + match: "/^[a-z$_]{1}[A-Z09$_]*/" + + adidas-properties-camelCase-alphanumeric: + description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. + severity: error + recommended: true + message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`." + given: $.definitions..properties[*]~ + then: + function: pattern + functionOptions: + match: "/^[a-z$_]{1}[A-Z09$_]*/" + + adidas-request-GET-no-body: + description: "A 'GET' request MUST NOT accept a 'body` parameter" + severity: error + given: $.paths..get.parameters..in + then: + function: pattern + functionOptions: + notMatch: "/^body$/" + + adidas-headers-no-x-headers: + description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)." + severity: warn + given: "$..parameters[?(@.in == 'header')].name" + message: "HTTP headers SHOULD NOT include 'X-' prefix." + recommended: true + type: style + then: + function: pattern + functionOptions: + notMatch: "/^(x|X)-/" + + adidas-headers-hyphenated-pascal-case: + description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation + severity: error + given: "$..parameters[?(@.in == 'header')].name" + message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation" + recommended: true + type: style + then: + function: pattern + functionOptions: + match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/" + + # --------------------------------------------------------------------------- + # Only OAS2 rules + # --------------------------------------------------------------------------- + + adidas-oas2-protocol-https-only: + description: "ALL requests MUST go through `https` protocol only" + formats: + - oas2 + recommended: true + severity: error + type: "style" + message: "Schemes MUST be https and no other value is allowed." + given: $ + then: + field: schemes + function: schema + functionOptions: + schema: + type: array + items: + type: string + enum: ["https"] + maxItems: 1 + + adidas-oas2-request-support-json: + description: Every request SHOULD support `application/json` media type + formats: + - oas2 + severity: warn + message: "{{description}}: {{error}}" + recommended: true + given: "$..consumes" + then: + function: schema + functionOptions: + schema: + type: array + contains: + type: string + enum: + - application/json + + adidas-oas2-example-exists-in-parameters: + description: All models MUST have a valid example. + severity: error + recommended: true + formats: + - oas2 + message: "{{ property }} MUST have a valid example." + given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]" + then: + function: truthy + + # example-exists-in-definitions: + # description: All models MUST have a valid example. + # severity: error + # recommended: true + # formats: + # - oas2 + # message: "{{ property }} MUST have a valid example." + # given: "$..definitions..[?(!@.example || !@..$ref)]" + # then: + # function: falsy + # "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example && ( @.type || @.format || @.$ref ))]" + + adidas-oas2-response-success-hal: # schemes and/or produces + description: "All success responses MUST be of media type `application/hal+json`" + severity: error + given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)] + recommended: true + type: "style" + formats: + - oas2 + message: "Response documents MUST follow application/hal+json: {{error}}" + then: + field: schema + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/HAL.yaml" + + adidas-oas2-response-error-problem: # schemas and/or produces + description: All error responses MUST be of media type `application/problem+json` + severity: error + formats: + - oas2 + given: $.paths..responses[?( @property >= 400 && @property < 600 )] + recommended: true + type: "style" + message: "Error response document MUST follow application/problem+json: {{error}}" + then: + field: schema.example + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/ProblemDetail.yaml" + + # --------------------------------------------------------------------------- + # Only OAS3 rules + # --------------------------------------------------------------------------- + + adidas-oas3-request-support-json: + description: Every request MUST support `application/json` media type + formats: + - oas3 + recommended: true + severity: error + message: "{{description}}: {{error}}" + given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^ + then: + function: falsy + + adidas-oas3-valid-example-in-parameters: + description: Examples must be valid against their defined schema. + message: "{{error}}" + recommended: true + formats: + - oas3 + severity: 0 + type: validation + given: "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example + && ( @.type || @.format || @.$ref ))]" + then: + function: schemaPath + functionOptions: + field: example + schemaPath: "$" + + adidas-oas3-valid-example-in-definitions: + description: Examples must be valid against their defined schema. + message: "{{error}}" + recommended: true + formats: + - oas3 + severity: 0 + type: validation + given: "$..definitions..[?(@property !== 'properties' && @.example && (@.type || + @.format || @.$ref))]" + then: + function: schemaPath + functionOptions: + field: example + schemaPath: "$" + + adidas-oas3-protocol-https-only: # checks how does the servers array values start + description: "ALL requests MUST go through `https` protocol only" + formats: + - oas3 + recommended: true + severity: error + message: "Servers MUST be https and no other protocol is allowed." + given: $.servers..url + then: + function: pattern + functionOptions: + match: "/^https:/" + + adidas-oas3-response-success-hal: + description: "All success responses MUST be of media type `application/hal+json`" + severity: error + given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)].content[*]~ + recommended: true + # type: "style" + formats: + - oas3 + message: "Response documents MUST be of application/hal+json media type: {{error}}" + then: + function: enumeration + functionOptions: + values: + - application/hal+json + + adidas-oas3-response-success-hal-body: # schemes and/or produces + description: "All success responses MUST follow `application/hal+json` schema" + severity: error + given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")] + recommended: true + type: "style" + formats: + - oas3 + message: "Response documents MUST follow application/hal+json schema: {{error}}" + then: + field: schema + function: schema + functionOptions: + schema: + $ref: "./supermodel/adidas/api/HAL.yaml" + + + # --------------------------------------------------------------------------- + # Not implemented + # --------------------------------------------------------------------------- + + # --------------------------------------------------------------------------- + # Other rules which are redundant or not feasible + # --------------------------------------------------------------------------- + + # fields-date-iso8601: + # description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html) + # severity: error + # fields-language-iso639: + # description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html) + # severity: error + # fields-country-iso3166: + # description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + # severity: error + # fields-currency-iso4217: + # description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217) + # severity: error + # response-303-async-link-header: + # description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header + # severity: hint diff --git a/README.md b/README.md index 0429e50..a4ab124 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ description: Guidelines for the API design and development at adidas ![adidas logo](https://adidas-group.gitbooks.io/api-guidelines/content/assets/adidas-logo.svg) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + [Read online at GitBook](https://adidas.gitbook.io/api-guidelines/) ### Motivation @@ -39,9 +41,27 @@ The CAPITALIZED words throughout these guidelines have a special meaning: Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details. +### Validating your API Guidelines against OpenAPI Specification + +In the `ruleset.md` file you can find a digest of API Guidelines rules which you can validating your API description documents with. If you are using OpenAPI Specification as the API description format you can also leverage the `.spectral.yaml` ruleset to automatically verify your specification compliance using [Spectral](github.com/stoplightio/spectral). + +To install Spectral you will need Node.js and a package manager (npm or yarn). + +``` +npm install -g @stoplight/spectral + +# OR + +yarn global add @stoplight/spectral +``` + +Once installed, to verify your OAS file with spectral execute `spectral lint -r /.spectral.yaml` where `/.spectral.yaml` indicated the location `.spectral.yaml` file. + +For further documentation on Spectral refer to their [documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/README.md). + ### Questions & Comments -_Please contact_ [_Zdenek.Nemec@externals.adidas-group.com_](mailto:Zdenek.Nemec@externals.adidas-group.com) _in the case of questions._ +_Please contact_ [_Zdenek.Nemec@externals.adidas-group.com_](mailto:Zdenek.Nemec@externals.adidas-group.com), [_andrzej.jarzyna@adidas.com_](mailto:andrzej.jarzyna@adidas.com) or [_samir.amzani@adidas.com_](mailto:samir.amzani@adidas.com) _in case of questions._ ## Intended Use Cases diff --git a/SUMMARY.md b/SUMMARY.md index 8da6e68..d1d03b5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -19,43 +19,41 @@ * [Introduction](rest-api-guidelines/rest.md) * [Core Principles](rest-api-guidelines/core-principles/README.md) * [OpenAPI Specification](rest-api-guidelines/core-principles/openapi-specification.md) - * [API Design Platform](rest-api-guidelines/core-principles/apiary.md) + * [API Design Platform](rest-api-guidelines/core-principles/design-platform.md) * [Design Maturity](rest-api-guidelines/core-principles/design-maturity.md) * [Testing](rest-api-guidelines/core-principles/testing.md) -* [Functionality](rest-api-guidelines/functionality/README.md) - * [Protocol](rest-api-guidelines/functionality/protocol/README.md) - * [HTTP](rest-api-guidelines/functionality/protocol/http.md) - * [TLS](rest-api-guidelines/functionality/protocol/tls.md) - * [Separate Concerns](rest-api-guidelines/functionality/protocol/separate-concerns.md) - * [Request Methods](rest-api-guidelines/functionality/protocol/use-appropriate-methods.md) - * [Status Codes](rest-api-guidelines/functionality/protocol/use-appropriate-status-codes.md) - * [Message](rest-api-guidelines/functionality/message/README.md) - * [Message Formats](rest-api-guidelines/functionality/message/message-formats.md) - * [Content Negotiation](rest-api-guidelines/functionality/message/content-negotiation.md) - * [HAL](rest-api-guidelines/functionality/message/hal.md) - * [Problem Detail](rest-api-guidelines/functionality/message/error-reporting.md) - * [Foreign Key Relations](rest-api-guidelines/functionality/message/foreign-key-relations.md) - * [Application](rest-api-guidelines/functionality/application/README.md) - * [Corporate Data Model](rest-api-guidelines/functionality/application/harmonize-data.md) - * [Common Data Types](rest-api-guidelines/functionality/application/common-data-types.md) -* [Quality](rest-api-guidelines/quality/README.md) - * [Execution](rest-api-guidelines/quality/execution/README.md) - * [Pagination](rest-api-guidelines/quality/execution/pagination.md) - * [Asynchronous Tasks](rest-api-guidelines/quality/execution/asynchronous-tasks.md) - * [Batch Operations](rest-api-guidelines/quality/execution/batch-operations.md) - * [Search Requests](rest-api-guidelines/quality/execution/search-requests.md) - * [Query Requests with Large Inputs](rest-api-guidelines/quality/execution/query-requests-with-large-inputs.md) - * [Choosing Fields and Embedded Resources](rest-api-guidelines/quality/execution/choosing-fields-and-embedded-resoruces.md) - * [Localization](rest-api-guidelines/quality/execution/localization.md) - * [Rate Limiting](rest-api-guidelines/quality/execution/rate-limiting.md) - * [Caching](rest-api-guidelines/quality/execution/caching.md) - * [Testing Enviroments](rest-api-guidelines/quality/execution/testing-enviroments.md) - * [Evolution](rest-api-guidelines/quality/evolution/README.md) - * [Naming Conventions](rest-api-guidelines/quality/evolution/naming-conventions.md) - * [Reserved Identifiers](rest-api-guidelines/quality/evolution/reserved-identifiers.md) - * [URI Structure](rest-api-guidelines/quality/evolution/uri-structure.md) - * [Changes and Versioning](rest-api-guidelines/quality/evolution/versioning.md) - * [Phasing out Old Versions](rest-api-guidelines/quality/evolution/phasing-out-old-versions.md) +* [Protocol](rest-api-guidelines/protocol/README.md) + * [HTTP](rest-api-guidelines/protocol/http.md) + * [TLS](rest-api-guidelines/protocol/tls.md) + * [Separate Concerns](rest-api-guidelines/protocol/separate-concerns.md) + * [Request Methods](rest-api-guidelines/protocol/use-appropriate-methods.md) + * [Status Codes](rest-api-guidelines/protocol/use-appropriate-status-codes.md) +* [Message](rest-api-guidelines/message/README.md) + * [Message Formats](rest-api-guidelines/message/message-formats.md) + * [Content Negotiation](rest-api-guidelines/message/content-negotiation.md) + * [HAL](rest-api-guidelines/message/hal.md) + * [Problem Detail](rest-api-guidelines/message/error-reporting.md) + * [Foreign Key Relations](rest-api-guidelines/message/foreign-key-relations.md) +* [Application](rest-api-guidelines/application/README.md) + * [Corporate Data Model](rest-api-guidelines/application/harmonize-data.md) + * [Common Data Types](rest-api-guidelines/application/common-data-types.md) +* [Execution](rest-api-guidelines/execution/README.md) + * [Pagination](rest-api-guidelines/execution/pagination.md) + * [Asynchronous Tasks](rest-api-guidelines/execution/asynchronous-tasks.md) + * [Batch Operations](rest-api-guidelines/execution/batch-operations.md) + * [Search Requests](rest-api-guidelines/execution/search-requests.md) + * [Query Requests with Large Inputs](rest-api-guidelines/execution/query-requests-with-large-inputs.md) + * [Choosing Fields and Embedded Resources](rest-api-guidelines/execution/choosing-fields-and-embedded-resoruces.md) + * [Localization](rest-api-guidelines/execution/localization.md) + * [Rate Limiting](rest-api-guidelines/execution/rate-limiting.md) + * [Caching](rest-api-guidelines/execution/caching.md) + * [Testing Enviroments](rest-api-guidelines/execution/testing-enviroments.md) +* [Evolution](rest-api-guidelines/evolution/README.md) + * [Naming Conventions](rest-api-guidelines/evolution/naming-conventions.md) + * [Reserved Identifiers](rest-api-guidelines/evolution/reserved-identifiers.md) + * [URI Structure](rest-api-guidelines/evolution/uri-structure.md) + * [Changes and Versioning](rest-api-guidelines/evolution/versioning.md) + * [Phasing out Old Versions](rest-api-guidelines/evolution/phasing-out-old-versions.md) * [Guides](rest-api-guidelines/guides/README.md) * [API Testing CI Environment](rest-api-guidelines/guides/api-testing-ci-environment.md) * [Complete API Development](rest-api-guidelines/guides/complete-api-development.md) diff --git a/acknowledgements.md b/acknowledgements.md index 76f2b3a..a6cb646 100644 --- a/acknowledgements.md +++ b/acknowledgements.md @@ -13,5 +13,5 @@ This work is partly based on the work of many talented individuals and exception * [Facebook Graph API Team](https://developers.facebook.com/docs/graph-api/) * [Subbu Allamaraju: RESTFul Web Services Cookbook](http://shop.oreilly.com/product/9780596801694.do) * [Paolo De Lucia](https://www.linkedin.com/in/paolodelucia/) - - +* [Jakub Rożek](https://github.com/P0lip) +* [Phil Sturgeon](https://github.com/philsturgeon) diff --git a/examples/invalid/api-with-examples.oas3.yaml b/examples/invalid/api-with-examples.oas3.yaml new file mode 100644 index 0000000..227fa44 --- /dev/null +++ b/examples/invalid/api-with-examples.oas3.yaml @@ -0,0 +1,167 @@ +openapi: "3.0.0" +info: + title: Simple API overview + version: 2.0.0 +paths: + /: + get: + operationId: listVersionsv2 + summary: List API versions + responses: + '200': + description: |- + 200 response + content: + application/json: + examples: + foo: + value: { + "versions": [ + { + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z", + "id": "v2.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v2/", + "rel": "self" + } + ] + }, + { + "status": "EXPERIMENTAL", + "updated": "2013-07-23T11:33:21Z", + "id": "v3.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v3/", + "rel": "self" + } + ] + } + ] + } + '300': + description: |- + 300 response + content: + application/json: + examples: + foo: + value: | + { + "versions": [ + { + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z", + "id": "v2.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v2/", + "rel": "self" + } + ] + }, + { + "status": "EXPERIMENTAL", + "updated": "2013-07-23T11:33:21Z", + "id": "v3.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v3/", + "rel": "self" + } + ] + } + ] + } + /v2: + get: + operationId: getVersionDetailsv2 + summary: Show API version details + responses: + '200': + description: |- + 200 response + content: + application/json: + examples: + foo: + value: { + "version": { + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z", + "media-types": [ + { + "base": "application/xml", + "type": "application/vnd.openstack.compute+xml;version=2" + }, + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2" + } + ], + "id": "v2.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v2/", + "rel": "self" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf", + "type": "application/pdf", + "rel": "describedby" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "type": "application/vnd.sun.wadl+xml", + "rel": "describedby" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "type": "application/vnd.sun.wadl+xml", + "rel": "describedby" + } + ] + } + } + '203': + description: |- + 203 response + content: + application/json: + examples: + foo: + value: { + "version": { + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z", + "media-types": [ + { + "base": "application/xml", + "type": "application/vnd.openstack.compute+xml;version=2" + }, + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2" + } + ], + "id": "v2.0", + "links": [ + { + "href": "http://23.253.228.211:8774/v2/", + "rel": "self" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf", + "type": "application/pdf", + "rel": "describedby" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "type": "application/vnd.sun.wadl+xml", + "rel": "describedby" + } + ] + } + } diff --git a/examples/invalid/link-example.oas3.yaml b/examples/invalid/link-example.oas3.yaml new file mode 100644 index 0000000..14dc00a --- /dev/null +++ b/examples/invalid/link-example.oas3.yaml @@ -0,0 +1,203 @@ +openapi: 3.0.0 +info: + title: Link Example + version: 1.0.0 +paths: + /2.0/users/{username}: + get: + operationId: getUserByName + parameters: + - name: username + in: path + required: true + schema: + type: string + responses: + '200': + description: The User + content: + application/json: + schema: + $ref: '#/components/schemas/user' + links: + userRepositories: + $ref: '#/components/links/UserRepositories' + /2.0/repositories/{username}: + get: + operationId: getRepositoriesByOwner + parameters: + - name: username + in: path + required: true + schema: + type: string + responses: + '200': + description: repositories owned by the supplied user + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/repository' + links: + userRepository: + $ref: '#/components/links/UserRepository' + /2.0/repositories/{username}/{slug}: + get: + operationId: getRepository + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + responses: + '200': + description: The repository + content: + application/json: + schema: + $ref: '#/components/schemas/repository' + links: + repositoryPullRequests: + $ref: '#/components/links/RepositoryPullRequests' + /2.0/repositories/{username}/{slug}/pullrequests: + get: + operationId: getPullRequestsByRepository + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + - name: state + in: query + schema: + type: string + enum: + - open + - merged + - declined + responses: + '200': + description: an array of pull request objects + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/pullrequest' + /2.0/repositories/{username}/{slug}/pullrequests/{pid}: + get: + operationId: getPullRequestsById + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + - name: pid + in: path + required: true + schema: + type: string + responses: + '200': + description: a pull request object + content: + application/json: + schema: + $ref: '#/components/schemas/pullrequest' + links: + pullRequestMerge: + $ref: '#/components/links/PullRequestMerge' + /2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge: + post: + operationId: mergePullRequest + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + - name: pid + in: path + required: true + schema: + type: string + responses: + '204': + description: the PR was successfully merged +components: + links: + UserRepositories: + # returns array of '#/components/schemas/repository' + operationId: getRepositoriesByOwner + parameters: + username: $response.body#/username + UserRepository: + # returns '#/components/schemas/repository' + operationId: getRepository + parameters: + username: $response.body#/owner/username + slug: $response.body#/slug + RepositoryPullRequests: + # returns '#/components/schemas/pullrequest' + operationId: getPullRequestsByRepository + parameters: + username: $response.body#/owner/username + slug: $response.body#/slug + PullRequestMerge: + # executes /2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge + operationId: mergePullRequest + parameters: + username: $response.body#/author/username + slug: $response.body#/repository/slug + pid: $response.body#/id + schemas: + user: + type: object + properties: + username: + type: string + uuid: + type: string + repository: + type: object + properties: + slug: + type: string + owner: + $ref: '#/components/schemas/user' + pullrequest: + type: object + properties: + id: + type: integer + title: + type: string + repository: + $ref: '#/components/schemas/repository' + author: + $ref: '#/components/schemas/user' \ No newline at end of file diff --git a/examples/invalid/petstore-expanded.oas3.yaml b/examples/invalid/petstore-expanded.oas3.yaml new file mode 100644 index 0000000..ceb7f0b --- /dev/null +++ b/examples/invalid/petstore-expanded.oas3.yaml @@ -0,0 +1,158 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +servers: + - url: http://petstore.swagger.io/api +paths: + /pets: + get: + description: | + Returns all pets from the system that the user has access to + Nam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia. + + Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. + operationId: findPets + parameters: + - name: tags + in: query + description: tags to filter by + required: false + style: form + schema: + type: array + items: + type: string + - name: limit + in: query + description: maximum number of results to return + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: pet response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + description: Creates a new pet in the store. Duplicates are allowed + operationId: addPet + requestBody: + description: Pet to add to the store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NewPet' + responses: + '200': + description: pet response + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /pets/{id}: + get: + description: Returns a user based on a single ID, if the user does not have access to the pet + operationId: find pet by id + parameters: + - name: id + in: path + description: ID of pet to fetch + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: pet response + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + description: deletes a single pet based on the ID supplied + operationId: deletePet + parameters: + - name: id + in: path + description: ID of pet to delete + required: true + schema: + type: integer + format: int64 + responses: + '204': + description: pet deleted + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Pet: + allOf: + - $ref: '#/components/schemas/NewPet' + - type: object + required: + - id + properties: + id: + type: integer + format: int64 + + NewPet: + type: object + required: + - name + properties: + name: + type: string + tag: + type: string + + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/examples/valid/demo-orderapi-v3.oas2.yaml b/examples/valid/demo-orderapi-v3.oas2.yaml new file mode 100644 index 0000000..3c99ffb --- /dev/null +++ b/examples/valid/demo-orderapi-v3.oas2.yaml @@ -0,0 +1,365 @@ +swagger: '2.0' +info: + version: '3.0.0' + title: '[Demo] Orders API' + contact: + name: Z + email: "z@goodapi.co" + description: | + Sample API conforming to [adidas API Guidelines](https://adidas.gitbook.io/api-guidelines/). + +produces: + - application/hal+json # Representation message format + - application/problem+json # Error message format + +schemes: + - https + +host: "example.com" + +securityDefinitions: + 'API Key': + type: apiKey + in: header + name: x-api-key + +security: + - "API Key": [] + +paths: + /: + x-summary: API Root + + get: + summary: Retrieve API Root + description: The API Root contains the initial set of link relations. + responses: + 200: + description: The root of the API + schema: + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHAL' + example: + _links: + self: + href: / + orders: + href: /orders + + /orders: + x-summary: List of Orders + + get: + summary: Retrieve List of Orders + description: Retrieves a list of orders with pagination. + parameters: + - $ref: '#/parameters/offset' + - $ref: '#/parameters/limit' + responses: + 200: + description: The list of Orders + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrders' + + post: + summary: Create a New Order + description: Creates a new order. + consumes: + - application/json + parameters: + - name: Order + in: body + description: Order to be created + required: true + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder' + responses: + 201: + description: Newly created order + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder' + + /orders/{orderId}: + x-summary: Order + + parameters: + - name: orderId + in: path + description: Id of the Order + required: true + type: string + x-example: '1234' + + get: + summary: Retrieve Order + description: Retrieves an order with specified fields. + parameters: + - $ref: '#/parameters/fields' + responses: + 200: + description: A particular Order + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder' + 404: + description: The request Order wasn't found + headers: + Content-Type: + type: string + default: application/problem+json + schema: + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiProblemDetail' + example: + title: 'Not Found' + detail: 'Cannot find the requested order' + status: 404 + instance: '/orders/1234' + + patch: + summary: Update Order + description: Does a partial update of an order. + consumes: + - application/json + parameters: + - name: Order + in: body + description: Partial order update + required: true + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrderPatch' + responses: + 200: + description: The Order was updated + schema: + $ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder' + + delete: + summary: Delete Order + description: Deletes an order without returning its instance. + produces: [] + responses: + 204: + description: The Order was deleted + +parameters: + # adidas API guidelines: Pagination + offset: + name: offset + in: query + description: Number of results to skip from the start of the list + required: false + type: string + default: '0' + x-example: '10' + + # adidas API guidelines: Pagination + limit: + name: limit + in: query + description: The maximum number of reusults to return + required: false + type: string + default: '10' + x-example: '5' + + # adidas API guidelines: Sparse fieldset + fields: + name: fields + in: query + description: Comma-separated list of fields to include in the response + required: false + type: array + items: + type: string + collectionFormat: csv + x-example: + - articleNumber + - modelNumber + + # adidas API guidelines: Sparse fieldset + embedded: + name: embedded + in: query + description: Comma-separated list of resource (relations) to embed in the response + required: false + type: array + items: + type: string + collectionFormat: csv + x-example: + - prices + - assets + +# DO NOT EDIT +# This definitions section is automatically generated by supermodel.io +# +# http://supermodel.io +# https://github.com/supermodel/supermodel-cli +definitions: + supermodelIoAdidasExamplesOrderApiOrder: + title: Order HAL Representation + type: object + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHAL' + - $ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder' + example: + _links: + self: + href: /orders/1234 + edit: + href: /orders/1234 + delete: + href: /orders/1234 + profile: + href: 'https://adidas-group.com/gdm/OMS' + orderNumber: 1234 + itemCount: 42 + status: pending + supermodelIoAdidasExamplesOrderApiOrderPatch: + title: OrderPatch + description: OrderPatch model description + type: object + allOf: + - $ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder' + example: + status: cancelled + orderNumber: 1 + itemCount: 2 + supermodelIoAdidasExamplesOrderApiOrders: + title: Collection of Orders HAL Representation + type: object + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHAL' + example: + _links: + self: + href: /orders + create: + href: /orders + next: + href: /orders?offset=5&limit=5 + first: + href: /orders?offset=0&limit=5 + last: + href: /orders?offset=40&limit=5 + _embedded: + order: + - _links: + self: + href: /orders/1234 + edit: + href: /orders/1234 + delete: + href: /orders/1234 + profile: + href: 'https://adidas-group.com/gdm/OMS' + orderNumber: 1234 + itemCount: 42 + status: pending + supermodelIoAdidasExamplesOrderApiProblemDetail: + title: Problem Detail + type: object + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiProblemDetail' + supermodelIoAdidasApiHAL: + title: HAL + description: >- + JSON Hypertext Application Language. Definition of [HAL message + format](https://tools.ietf.org/html/draft-kelly-json-hal-08) + type: object + properties: + _links: + type: object + additionalProperties: + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject' + - type: array + items: + $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject' + properties: + curies: + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalCuriesLink' + - type: array + items: + $ref: >- + #/definitions/supermodelIoAdidasApiHALDefinitionsHalCuriesLink + _embedded: + type: object + additionalProperties: + allOf: + - $ref: '#/definitions/supermodelIoAdidasApiHAL' + - type: array + items: + $ref: '#/definitions/supermodelIoAdidasApiHAL' + supermodelIoAdidasApiHALDefinitionsHalLinkObject: + title: HAL Link Object + type: object + properties: + href: + type: string + templated: + type: boolean + type: + type: string + deprecation: + type: string + name: + type: string + profile: + type: string + title: + type: string + hreflang: + type: string + required: + - href + supermodelIoAdidasApiHALDefinitionsHalCuriesLink: + title: HAL Curies Link + allOf: + - type: object + properties: + templated: + enum: + - true + required: + - templated + - $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject' + supermodelIoAdidasExamplesOrderOrder: + title: Order + type: object + description: Order model description + properties: + orderNumber: + type: number + itemCount: + type: number + status: + type: string + required: + - orderNumber + - itemCount + example: + orderNumber: 42 + itemCount: 3 + status: pending + supermodelIoAdidasApiProblemDetail: + title: Problem Details for HTTP APIs + description: >- + Definition of [RFC7807](https://tools.ietf.org/html/rfc7807) problem + detail + type: object + properties: + type: + type: string + title: + type: string + status: + type: number + detail: + type: string + instance: + type: string + required: + - title + - detail diff --git a/general-guidelines/contract.md b/general-guidelines/contract.md index f960c23..af27af0 100644 --- a/general-guidelines/contract.md +++ b/general-guidelines/contract.md @@ -2,5 +2,5 @@ Approved API Design, represented by its API Description or schema, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. -Any change to an API **MUST** be accompanied by a related update to the contract \(API Design\). +An update to the corresponding contract \(API Design\) **MUST** be implemented and approved before any change to an API **MUST**. diff --git a/general-guidelines/json.md b/general-guidelines/json.md index d2baa25..2c07784 100644 --- a/general-guidelines/json.md +++ b/general-guidelines/json.md @@ -2,7 +2,7 @@ Any JSON-based message **MUST** conform to the following rules: -1. All JSON field names **MUST** follow the [Naming Conventions ](../rest-api-guidelines/quality/evolution/naming-conventions.md)\(`camelCase`, American English, etc.\) +1. All JSON field names **MUST** follow the [Naming Conventions ](../rest-api-guidelines/evolution/naming-conventions.md)\(`camelCase`, American English, etc.\) 2. Field names **MUST** be ASCII alpha num characters, underscore \(`_`\) or dollar sign \(`$`\) 3. Boolean fields **MUST NOT** be of `null` value 4. Fields with `null` value **SHOULD** be omitted diff --git a/general-guidelines/validating-api-descriptions.md b/general-guidelines/validating-api-descriptions.md new file mode 100644 index 0000000..d8857ad --- /dev/null +++ b/general-guidelines/validating-api-descriptions.md @@ -0,0 +1,105 @@ +# Validating API Description + +If you want to follow adidas API design guidelines for REST APIs you MAY validate your OAS file using [Spectral](https://github.com/stoplightio/spectral) and the adidas ruleset file. + +## Installing Spectral + +To install Spectral you will need Node.js and a package manager (npm or yarn). + +``` +npm install -g @stoplight/spectral + +# OR + +yarn global add @stoplight/spectral +``` + +### Docker + +Spectral is also available as a Docker image, which can be handy for all sorts of things, like if you're contributing code to Spectral, want to integrate it into your CI build. + +``` +docker run --rm -it stoplight/spectral lint "${url}" +``` + +If the file you want to lint is on your computer, you'll need to mount the directory where the file resides as a volume + +``` +docker run --rm -it -v $(pwd):/tmp stoplight/spectral lint "/tmp/file.yaml" +``` + +## Using Spectral + +Once installed Spectral, you can validate an OAS file (in YAML or JSON format) according to a given set of rules. Spectral has a predefined set of rules validating OpenAPI 2.x (Swagger) and OpenAPI 3.x files. + +Spectral comes with a CLI and can be run from your command line: + +``` +spectral lint +``` + +For more details about how to utilize Spectral CLI you can check the CLI built-in help: + +``` +spectral lint -h +``` + +or go to the official [Spectral documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/cli.md). + +Spectral can also be used from within JavaScript. For details on how to accomplish this, please refer to the [documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/javascript.md). + +## Validating with Adidas API Guidelines + +To check whether your API Specification complies with Adidas API Guidelines you will need the `.spectral.yaml` file from this repository ([here](https://github.com/adidas/api-guidelines/blob/master/.spectral.yml)). + +``` +spectral lint -r /.spectral.yaml +``` + +### Validation problems + +Spectral defines 4 levels of problem severity: + +1. error - the specification either does not pass standard YAML/JSON structure validation, standard OAS2/OAS3 validation or is not compliant with core adidas guidelines. +2. warning - the specification lacks certain important validation check (e.g. `hosts` for OAS2) which are not required, but you should be cautious about them. +3. information - there are some best practices which you did not implement in your specification and should consider doing so. +4. hint - you should be aware that there are some additional best practices which you can consider implementing in your specification. + +Currently any problem of severity of error or warning will cause a failure status code of `1`. This means that any `error` or `warning` in your specification will prevent your CI/CD pipeline from succeeding. During design process you may want to ignore certain warnings, such as the runtime information (e.g. `hosts` or `servers`). In order to do that you can add a `--skip-rule` flag: + +``` +spectral lint my-api-spec.yaml --skip-rule=adidas-oas3-protocol-https-only +``` + +## Spectral rules list + +The documentation on Spectral general OAS and specific rules for OAS2 and OAS3 can be found here: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md. + +Adidas specific rules are listed below: + +### Adidas general rules + +* `adidas-paths-camelCase` - All YAML/JSON paths MUST follow camelCase. +* `adidas-definitions-camelCase-alphanumeric` - All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. +* `adidas-properties-camelCase-alphanumeric` - All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`. +* `adidas-request-GET-no-body` - A 'GET' request MUST NOT accept a 'body` parameter. +* `adidas-uri-template-cannot-dash` - The 'URI' template (RFC 6570 - https://tools.ietf.org/html/rfc6570) cannot contain a '-' character. +* `adidas-headers-no-x-headers` - All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648). +* `adidas-headers-hyphenated-pascal-case` - All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation. + +### Adidas OAS2/Swagger rules + +* `adidas-oas2-protocol-https-only` - ALL requests MUST go through `https` protocol only. +* `adidas-oas2-request-support-json` - Every request SHOULD support `application/json` media type. +* `adidas-oas2-example-exists-in-parameters` - All models MUST have a valid example. +* `adidas-oas2-response-success-hal` - All success responses MUST be of media type `application/hal+json`. +* `adidas-oas2-response-error-problem` - All error responses MUST be of media type `application/problem+json`. + +### Adidas OAS3 rules + +* `adidas-oas3-request-support-json` - Every request MUST support `application/json` media type. +* `adidas-oas3-valid-example-in-parameters` - Examples must be valid against their defined schema. +* `adidas-oas3-valid-example-in-definitions` - Examples must be valid against their defined schema. +* `adidas-oas3-protocol-https-only` - ALL requests MUST go through `https` protocol only. +* `adidas-oas3-response-success-hal` - All success responses MUST be of media type `application/hal+json`. +* `adidas-oas3-response-success-hal-body` - All success responses MUST follow `application/hal+json` schema. diff --git a/package.json b/package.json new file mode 100644 index 0000000..5a14fbf --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "api-guidelines", + "version": "1.0.0", + "description": "adidas API guidelines", + "repository": "git@github.com:adidas/api-guidelines.git", + "author": "software.engineering@adidas.com", + "license": "MIT", + "private": true, + "dependencies": { + "@stoplight/spectral": "^5.3.0", + "@supermodel/cli": "^0.46.29" + }, + "scripts": { + "build-examples": "supermodel schema oas2 supermodel/adidas/examples/order/api/ -o examples/demo-orderapi-v3.oas2.yaml", + "test": "spectral lint examples/valid/*" + } +} diff --git a/rest-api-guidelines/functionality/application/README.md b/rest-api-guidelines/application/README.md similarity index 55% rename from rest-api-guidelines/functionality/application/README.md rename to rest-api-guidelines/application/README.md index 059d50f..245e74a 100644 --- a/rest-api-guidelines/functionality/application/README.md +++ b/rest-api-guidelines/application/README.md @@ -2,5 +2,5 @@ Every API **SHOULD** use company terms for resource names, relation names and representation message field names. -Also, every API **MUST** follow the [naming conventions](../../quality/evolution/naming-conventions.md). +Also, every API **MUST** follow the [naming conventions](../evolution/naming-conventions.md). diff --git a/rest-api-guidelines/functionality/application/common-data-types.md b/rest-api-guidelines/application/common-data-types.md similarity index 100% rename from rest-api-guidelines/functionality/application/common-data-types.md rename to rest-api-guidelines/application/common-data-types.md diff --git a/rest-api-guidelines/functionality/application/harmonize-data.md b/rest-api-guidelines/application/harmonize-data.md similarity index 100% rename from rest-api-guidelines/functionality/application/harmonize-data.md rename to rest-api-guidelines/application/harmonize-data.md diff --git a/rest-api-guidelines/core-principles/apiary.md b/rest-api-guidelines/core-principles/apiary.md deleted file mode 100644 index bb5c57d..0000000 --- a/rest-api-guidelines/core-principles/apiary.md +++ /dev/null @@ -1,12 +0,0 @@ -# API Design Platform - -1. [Apiary](https://apiary.io/) is the primary platform supporting [API first approach](../../general-guidelines/api-first.md). Apiary **MUST** be used during API Design. -2. Every API description **MUST** be stored in [Apiary](https://apiary.io/) under the ADIDAS team. -3. Apiary **MUST** be the **single source of truth** to learn about existing APIs within the organization. - -> NOTE: Apiary supports API-first approach in multiple ways: -> a. Validates API description for correctness and automatically generates API documentation to drive the discussion between stakeholders. \(No more emails with API description flying between stakeholders\) -> -> NOTE: The synchronization between the version control system and adidas [API Description platform](apiary.md) -> should be automated using CI/CD framework. - diff --git a/rest-api-guidelines/core-principles/design-platform.md b/rest-api-guidelines/core-principles/design-platform.md new file mode 100644 index 0000000..9a26715 --- /dev/null +++ b/rest-api-guidelines/core-principles/design-platform.md @@ -0,0 +1,12 @@ +# API Design Platform + +1. [SwaggerHub](https://swagger.io/tools/swaggerhub/) is the primary platform supporting [API first approach](../../general-guidelines/api-first.md). SwaggerHub **SHOULD** be used during API Design. +2. Every API description **MUST** be stored in [SwaggerHub](https://design.api.3stripes.io/) under the adidas team. +3. SwaggerHub **MUST** be the **single source of truth** to learn about existing APIs within the organization. + +> NOTE: SwaggerHub supports API-first approach in multiple ways: +> For example, it validates API description for correctness and automatically generates API documentation to drive the discussion between stakeholders. \(No more emails with API description flying between stakeholders\) +> +> NOTE: The synchronization between the version control system and adidas API Design platform +> should be automated (e.g. using CI/CD framework or the Design Platform capabilities). + diff --git a/rest-api-guidelines/core-principles/openapi-specification.md b/rest-api-guidelines/core-principles/openapi-specification.md index ee09779..f820c39 100644 --- a/rest-api-guidelines/core-principles/openapi-specification.md +++ b/rest-api-guidelines/core-principles/openapi-specification.md @@ -2,7 +2,7 @@ Every API **MUST** be described using an API description format. The API description format used MUST be the [OpenAPI Specification \(formerly known as Swagger Specification\) version 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md). -Every API description **MUST** be published in adidas [API design platform](apiary.md) and it **SHOULD** be stored in version control system \(Bitbucket, GitHub\) in the same repository as the API implementation. +Every API description **MUST** be published in adidas [API design platform](design-platform.md) and it **SHOULD** be stored in version control system \(Bitbucket, GitHub\) in the same repository as the API implementation. ## Language diff --git a/rest-api-guidelines/core-principles/testing.md b/rest-api-guidelines/core-principles/testing.md index b9b0e65..631e1c2 100644 --- a/rest-api-guidelines/core-principles/testing.md +++ b/rest-api-guidelines/core-principles/testing.md @@ -1,6 +1,18 @@ # Testing -Every API description \(contract\) using HTTP\(S\) protocol **MUST** be tested against its API implementation. The tests **MUST** be executed using the [Dredd testing framework](https://github.com/apiaryio/dredd). The Dredd **MUST** [report the test results to Apiary](https://help.apiary.io/tools/automated-testing/testing-reporter/). +## DREDD + +Every API description \(contract\) using HTTP\(S\) protocol **MUST** be tested against its API implementation. The tests **MUST** be executed using the [Dredd testing framework](https://github.com/apiaryio/dredd). In addition to local runs, the tests **SHOULD** be an integral part the API implementation's CI/CD pipeline. The CI/CD pipeline **SHOULD** be configured to run the test whenever there is a change to either API description \(contract\) or its implementation. +## PACT + +Every adidas **CORE** API **MUST** be tested additionally applying Consumer Driven Contract Testing principles. The tests **MUST** be executed using the [PACT contract testing tool](https://docs.pact.io/). PACT tests **MUST** use adidas [PACT-Broker](http://pact.ati.adidas.com/) to store results and evidences. + +In addition to local runs, PACT tests **SHOULD** be an integral part of the API implementation's CI/CD pipeline. The CI/CD pipeline **SHOULD** be configured to run the test whenever there is a change to either API description \(contract\) or its implementation. + +Using Consumer Driven Contract Testing with PACT is *not mandatory* for adidas **NON-CORE** APIs, but strongly recommended due to the advantages this approach brings. It will be also a proof of our Software Engineering practices maturity. + +More information, guides and seeds about how to use PACT can be found on (internal link)[adidas Consumer Driven Contract Testing guide](https://tools.adidas-group.com/confluence/display/DSBP/adidas+Consumer+Driven+Contract+Testing+guide) page. + diff --git a/rest-api-guidelines/quality/evolution/README.md b/rest-api-guidelines/evolution/README.md similarity index 100% rename from rest-api-guidelines/quality/evolution/README.md rename to rest-api-guidelines/evolution/README.md diff --git a/rest-api-guidelines/quality/evolution/naming-conventions.md b/rest-api-guidelines/evolution/naming-conventions.md similarity index 100% rename from rest-api-guidelines/quality/evolution/naming-conventions.md rename to rest-api-guidelines/evolution/naming-conventions.md diff --git a/rest-api-guidelines/quality/evolution/phasing-out-old-versions.md b/rest-api-guidelines/evolution/phasing-out-old-versions.md similarity index 100% rename from rest-api-guidelines/quality/evolution/phasing-out-old-versions.md rename to rest-api-guidelines/evolution/phasing-out-old-versions.md diff --git a/rest-api-guidelines/quality/evolution/reserved-identifiers.md b/rest-api-guidelines/evolution/reserved-identifiers.md similarity index 80% rename from rest-api-guidelines/quality/evolution/reserved-identifiers.md rename to rest-api-guidelines/evolution/reserved-identifiers.md index 113ad49..20a832d 100644 --- a/rest-api-guidelines/quality/evolution/reserved-identifiers.md +++ b/rest-api-guidelines/evolution/reserved-identifiers.md @@ -4,8 +4,8 @@ The list of all reserved identifiers or identifiers with special meaning. ## Representation Format Fields -* `_links` - [HAL](../../functionality/message/hal.md) -* `_embedded` - [HAL](../../functionality/message/hal.md) +* `_links` - [HAL](../message/hal.md) +* `_embedded` - [HAL](../message/hal.md) ## Query Parameters diff --git a/rest-api-guidelines/quality/evolution/uri-structure.md b/rest-api-guidelines/evolution/uri-structure.md similarity index 100% rename from rest-api-guidelines/quality/evolution/uri-structure.md rename to rest-api-guidelines/evolution/uri-structure.md diff --git a/rest-api-guidelines/quality/evolution/versioning.md b/rest-api-guidelines/evolution/versioning.md similarity index 82% rename from rest-api-guidelines/quality/evolution/versioning.md rename to rest-api-guidelines/evolution/versioning.md index 9ec3262..3d4c4cd 100644 --- a/rest-api-guidelines/quality/evolution/versioning.md +++ b/rest-api-guidelines/evolution/versioning.md @@ -13,7 +13,7 @@ Any change to: 4. **Relation** with other resources \(e.g Links\) 5. **Representation format** \(e.g. HTTP request and response bodies\) -**MUST** follow the [**Rules for Extending**](../../../general-guidelines/rules-for-extending.md). +**MUST** follow the [**Rules for Extending**](../../general-guidelines/rules-for-extending.md). ## Identifier Stability \(No URI Versioning\) @@ -29,7 +29,7 @@ Adding a new action to existing resource with identifier `/greeting` doesn't cha ## Backward-incompatible Changes -A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](../../../general-guidelines/rules-for-extending.md) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved. +A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](../../general-guidelines/rules-for-extending.md) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved. A change to _representation format_ **SHOULD NOT** result into a new resource variant. @@ -41,7 +41,7 @@ Currently, optional URI Query Parameter `first` on an existing resource `/greeti > A representation format is the serialization format \(media type\) used in request and response bodies, and typically it represents a resource or its part, possibly with additional hypermedia controls. -If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](../../functionality/message/content-negotiation.md). +If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](../message/content-negotiation.md). If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/). @@ -87,13 +87,6 @@ info: Has MAJOR version 2, MINOR version 1 and PATCH version 3. -#### Demo - -API description \(OAS2\) files demonstrating a proposal of an backward-incompatible change turned into a backward compatible change are available at [Bitbucket \(diff\) ](https://bitbucket.org/apidesigner/demo-versioning-api/pull-requests/1/add-name-parameter/diff)and documented in Apiary: - -* [Production version](https://demoversioningproduction.docs.apiary.io/#) as being consumed by clients -* [Development version](https://demoversioningdevelopment.docs.apiary.io/#) proposing a backward incompatible change - #### Recommended Reading * [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution) diff --git a/rest-api-guidelines/quality/execution/README.md b/rest-api-guidelines/execution/README.md similarity index 100% rename from rest-api-guidelines/quality/execution/README.md rename to rest-api-guidelines/execution/README.md diff --git a/rest-api-guidelines/execution/asynchronous-tasks.md b/rest-api-guidelines/execution/asynchronous-tasks.md new file mode 100644 index 0000000..8df4f8a --- /dev/null +++ b/rest-api-guidelines/execution/asynchronous-tasks.md @@ -0,0 +1,105 @@ +# Asynchronous Tasks + +If an API operation is asynchronous, but a client could track its progress, the response to such an asynchronous operation **MUST** return, in the case of success, the **202 Accepted** status code together with an `application/hal+json` representation of a new **task-tracking resource**. + +## Task Tracking Resource + +The task-tracking resource **SHOULD** convey the information about the status of an asynchronous task. + +Retrieval of such a resource using the HTTP GET Request Method **SHOULD** be designed as follows: + +1. Task is Still Processing + + Return **200 OK** and representation of the current status. + +2. Task Successfully Completed + + Return **303 See Other** together with [HTTP Location Header](https://tools.ietf.org/html/rfc7231#section-7.1.2) with URI or a outcome resource. + +3. Task Failed + + Return **200 OK** and `application/problem+json` with the problem detail information on the task has failed. + +## Design Note + +The asynchronous operation task-tracking resource can be either **polled** by client or the client might initially provide a **callback** to be executed when the operation finishes. + +In the case of callback, the API and its client MUST agree on what HTTP method and request format is used for the callback invitation. If built within adidas, the "client" API is also the subject of the adidas API guidelines. + +### Example + +1. **Initiate the asynchronous task** + + ``` + POST /feeds/tasks/ HTTP/1.1 + Content-Type: application/json + ... + + HTTP/1.1 202 Accepted + Content-Type: application/hal+json + Retry-After: 60 + + { + "_links": { + "self": { "href": "/feeds/tasks/1" } + }, + "message": "Your task to generate feed has been accepted. Try query for result after 60 seconds.", + "retryAfter": 60 + } + ``` + +1. **Poll the task status: In progress** + + ``` + GET /feeds/tasks/1 HTTP/1.1 + ... + + HTTP/1.1 200 Ok + Content-Type: application/hal+json + Retry-After: 30 + + { + "_links": { + "self": { "href": "/feeds/tasks/1" } + }, + "message": "Your feed is being generated. Try query for result after 30 seconds.", + "retryAfter": 30 + } + ``` + +1. **Poll the task status: Finished** + + ``` + GET /feeds/tasks/1 HTTP/1.1 + ... + + HTTP/1.1 303 See Other + Location: /feeds/1 + Content-Location: /feeds/tasks/1 + Content-Type: application/hal+json + + { + "_links": { + "self": { "href": "/feeds/tasks/1" }, + "feed": { "href": "/feeds/1" } + }, + "message": "Your feed is ready." + } + ``` + +1. **Poll the task status: Failure** + + ``` + GET /feeds/tasks/1 HTTP/1.1 + ... + + HTTP/1.1 200 OK + Content-Type: application/problem+json + + { + "title": "Wrong input parameters", + "detail: "Missing required input parameter XYZ.", + "status": 400 + } + ``` + diff --git a/rest-api-guidelines/quality/execution/batch-operations.md b/rest-api-guidelines/execution/batch-operations.md similarity index 96% rename from rest-api-guidelines/quality/execution/batch-operations.md rename to rest-api-guidelines/execution/batch-operations.md index 0ec37a5..c433c65 100644 --- a/rest-api-guidelines/quality/execution/batch-operations.md +++ b/rest-api-guidelines/execution/batch-operations.md @@ -70,7 +70,7 @@ However, in such an operation has to be provided such a non-atomic bulk operatio 1. Non-atomic bulk operation **MUST** return a success status code \(e.g. **200 OK**\) only if every and all sub-operation succeeded. 2. If any single one sub-operation fails the whole non-atomic bulk operation **MUST** return the respective **4xx** or **5xx** status code. -3. In the case of a failure the response **MUST** contain the [problem detail](../../functionality/message/message-formats.md#error-response-format) information about every sub-operation that has failed. +3. In the case of a failure the response **MUST** contain the [problem detail](../message/message-formats.md#error-response-format) information about every sub-operation that has failed. 4. **The client MUST be aware that the operation is non-atomic and the even the operation might have failed some sub-operations were processed successfully.** ### Example diff --git a/rest-api-guidelines/quality/execution/caching.md b/rest-api-guidelines/execution/caching.md similarity index 100% rename from rest-api-guidelines/quality/execution/caching.md rename to rest-api-guidelines/execution/caching.md diff --git a/rest-api-guidelines/quality/execution/choosing-fields-and-embedded-resoruces.md b/rest-api-guidelines/execution/choosing-fields-and-embedded-resoruces.md similarity index 100% rename from rest-api-guidelines/quality/execution/choosing-fields-and-embedded-resoruces.md rename to rest-api-guidelines/execution/choosing-fields-and-embedded-resoruces.md diff --git a/rest-api-guidelines/quality/execution/localization.md b/rest-api-guidelines/execution/localization.md similarity index 100% rename from rest-api-guidelines/quality/execution/localization.md rename to rest-api-guidelines/execution/localization.md diff --git a/rest-api-guidelines/quality/execution/pagination.md b/rest-api-guidelines/execution/pagination.md similarity index 96% rename from rest-api-guidelines/quality/execution/pagination.md rename to rest-api-guidelines/execution/pagination.md index 693d8a1..e149bfc 100644 --- a/rest-api-guidelines/quality/execution/pagination.md +++ b/rest-api-guidelines/execution/pagination.md @@ -15,7 +15,7 @@ The Collection of Orders using the collection navigation link and `offset` and ` "first": { "href": "/orders?limit=10" }, "last": { "href": "/orders?offset=900&limit=10" } }, - "total_count": 910, + "totalCount": 910, "_embedded": { "order": [ { ... }, diff --git a/rest-api-guidelines/quality/execution/query-requests-with-large-inputs.md b/rest-api-guidelines/execution/query-requests-with-large-inputs.md similarity index 100% rename from rest-api-guidelines/quality/execution/query-requests-with-large-inputs.md rename to rest-api-guidelines/execution/query-requests-with-large-inputs.md diff --git a/rest-api-guidelines/quality/execution/rate-limiting.md b/rest-api-guidelines/execution/rate-limiting.md similarity index 100% rename from rest-api-guidelines/quality/execution/rate-limiting.md rename to rest-api-guidelines/execution/rate-limiting.md diff --git a/rest-api-guidelines/quality/execution/search-requests.md b/rest-api-guidelines/execution/search-requests.md similarity index 100% rename from rest-api-guidelines/quality/execution/search-requests.md rename to rest-api-guidelines/execution/search-requests.md diff --git a/rest-api-guidelines/quality/execution/testing-enviroments.md b/rest-api-guidelines/execution/testing-enviroments.md similarity index 100% rename from rest-api-guidelines/quality/execution/testing-enviroments.md rename to rest-api-guidelines/execution/testing-enviroments.md diff --git a/rest-api-guidelines/functionality/README.md b/rest-api-guidelines/functionality/README.md deleted file mode 100644 index e10f223..0000000 --- a/rest-api-guidelines/functionality/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Functionality - - - diff --git a/rest-api-guidelines/functionality/message/HAL-snippet-full-OpenApi3.yaml b/rest-api-guidelines/functionality/message/HAL-snippet-full-OpenApi3.yaml new file mode 100644 index 0000000..bb79aec --- /dev/null +++ b/rest-api-guidelines/functionality/message/HAL-snippet-full-OpenApi3.yaml @@ -0,0 +1,81 @@ +openapi: 3.0.0 +info: + title: HAL + description: 'HAL snippet for OAS3' + contact: + name: Andrzej Jarzyna + url: https://github.com/jerzyn + email: andrzej.jarzyna@adidas.com + version: '1.0.0' +servers: +- url: http://{defaultHost} + variables: + defaultHost: + default: www.example.com +paths: {} +components: + schemas: + HALLinkObject: + title: HALLinkObject + required: + - href + type: object + properties: + href: + type: string + templated: + type: boolean + type: + type: string + deprecation: + type: string + name: + type: string + profile: + type: string + title: + type: string + hreflang: + type: string + HALCuriesLink: + title: HALCuriesLink + required: + - templated + - href + type: object + properties: + templated: + type: string + example: True + href: + type: string + type: + type: string + deprecation: + type: string + name: + type: string + profile: + type: string + title: + type: string + hreflang: + type: string + HAL: + title: HAL + type: object + properties: + _links: + $ref: '#/components/schemas/Links' + _embedded: + type: object + additionalProperties: + $ref: '#/components/schemas/HAL' + description: JSON Hypertext Application Language. Definition of [HAL message format](https://tools.ietf.org/html/draft-kelly-json-hal-08) + Links: + title: Links + type: object + properties: + curies: + $ref: '#/components/schemas/HALCuriesLink' +tags: [] diff --git a/rest-api-guidelines/functionality/message/HAL-snippet.yaml b/rest-api-guidelines/functionality/message/HAL-snippet.yaml new file mode 100644 index 0000000..c3eebe3 --- /dev/null +++ b/rest-api-guidelines/functionality/message/HAL-snippet.yaml @@ -0,0 +1,74 @@ +swagger: "2.0" +info: + title: HAL + description: HAL snippet for OAS2 + version: 1.0.0 +host: api.example.com +basePath: /v1 +schemes: + - https +paths: {} +definitions: + HalLinkObject: + title: HAL Link Object + type: object + properties: + href: + type: string + templated: + type: boolean + type: + type: string + deprecation: + type: string + name: + type: string + profile: + type: string + title: + type: string + hreflang: + type: string + required: + - href + HalCuriesLink: + title: HAL Curies Link + allOf: + - type: object + properties: + templated: + enum: + - true + required: + - templated + - $ref: '#/definitions/HalLinkObject' + HAL: + title: HAL + description: >- + JSON Hypertext Application Language. Definition of [HAL message + format](https://tools.ietf.org/html/draft-kelly-json-hal-08) + type: object + properties: + _links: + type: object + additionalProperties: + allOf: + - $ref: '#/definitions/HalLinkObject' + - type: array + items: + $ref: '#/definitions/HalLinkObject' + properties: + curies: + allOf: + - $ref: '#/definitions/HalCuriesLink' + - type: array + items: + $ref: '#/definitions/HalCuriesLink' + _embedded: + type: object + additionalProperties: + allOf: + - $ref: '#/definitions/HAL' + - type: array + items: + $ref: '#/definitions/HAL' \ No newline at end of file diff --git a/rest-api-guidelines/guides/README.md b/rest-api-guidelines/guides/README.md index a77d3e0..bfd1380 100644 --- a/rest-api-guidelines/guides/README.md +++ b/rest-api-guidelines/guides/README.md @@ -1,11 +1,9 @@ # Guides -API-related guides: +## API-related guides * [API Design Process](https://tools.adidas-group.com/confluence/display/EA/API+Design+Process) * Migration of Legacy Services \(SOAP\) * API Testing with Dredd * Continuous Integration / Deployment / Delivery -* [Apiary](https://help.apiary.io/api_101/understanding-apiary/) * API Management - diff --git a/rest-api-guidelines/guides/api-testing-ci-environment.md b/rest-api-guidelines/guides/api-testing-ci-environment.md index c91e5a4..55cfc4c 100644 --- a/rest-api-guidelines/guides/api-testing-ci-environment.md +++ b/rest-api-guidelines/guides/api-testing-ci-environment.md @@ -10,14 +10,7 @@ The following must be available in the CI environment before testing: ```text $ node -v - v7.5.0 - ``` - -2. **Ruby** runtime MUST be available in the CI environment: - - ```text - $ ruby -v - ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16] + v12.16.0 ``` 3. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment: @@ -28,55 +21,22 @@ The following must be available in the CI environment before testing: ```text $ dredd --version - dredd v2.2.5 (Darwin 16.4.0; x64) + dredd v13.0.1 ``` -4. [**Apiary CLI Tool**](https://help.apiary.io/tools/apiary-cli) MUST be installed globally in the CI environment: - - ```text - $ gem install apiaryio - ``` - - ```text - $ apiary version - 0.8.0 - ``` - -5. **Apiary API Key** MUST be set in the CI Environment environment variables: - - ```text - $ export APIARY_API_KEY=xyz - ``` - - To obtain an Apiary API key, head to [https://login.apiary.io/tokens](https://login.apiary.io/tokens) \(NOTE: You will need the "ALL" Scope\) - ## Testing an API ### Test Run Prerequisites To test an API within the CI environment provisioned as mentioned in the environment prerequisites, you will need the following: -1. The name \(subdomain\) of API project at Apiary +1. A `swagger.yaml` file with the description of API being tested - ```text - $ export APIARY_API_NAME=bomapi3 - ``` + The OpenAPI Specifciation file should be fetched from [API Design Platform](design-plaform.md). In the case of SwaggerHub API Design Platform, the file can be fetched manually or via their API. Refer to [Integrating with the SwaggerHub API](https://swagger.io/blog/api-development/integrating-with-the-swaggerhub-api/), for details how to use SwaggerHub API. - > See [How to find the Apiary API name](https://help.apiary.io/faq/find-api-name/) for more details. + Alternativelly this can also be a remote file e.g. SwaggerHub URL, if the API is public its OAS file and reachable from the testing host. -2. A `swagger.yaml` file with the description of API being tested - - To fetch the swagger.yaml file from Apiary run the following command before the test: - - ```text - $ apiary fetch --api-name=$APIARY_API_NAME --output="swagger.yaml" - ``` - - The swagger document for Apiary project `bomapi3` was saved as local file `./swagger.yaml`. - - > See [Fetching Published Documentation](https://help.apiary.io/tools/apiary-cli/#fetching-published-documentation). - -3. The host \(address\) of the service being tested +2. The host \(address\) of the service being tested ```text $ export API_HOST=http://deheremap7336.emea.adsint.biz:8004` @@ -84,10 +44,10 @@ To test an API within the CI environment provisioned as mentioned in the environ ### Running the Test -With all of the above \(`APIARY_API_KEY`, `APIARY_API_NAME`, `API_HOST`, set up and `swagger.yaml` file present in the current directory\), run: +Run: ```text -$ dredd swagger.yaml $API_HOST -r apiary +$ dredd swagger.yaml $API_HOST ``` > See [Dredd Command-line Interface](https://dredd.readthedocs.io/en/latest/usage-cli/). @@ -98,5 +58,4 @@ The Dredd will perform the tests and exits usually if the tests have passed. You $ echo $? ``` -Everything else but `0` should break the build. The test results will be visible in the CLI \(log\) as well as in Apiary. - +Everything else but `0` should break the build. The test results will be visible in the CLI \(log\) diff --git a/rest-api-guidelines/guides/complete-api-development.md b/rest-api-guidelines/guides/complete-api-development.md index 63ac3b4..0636947 100644 --- a/rest-api-guidelines/guides/complete-api-development.md +++ b/rest-api-guidelines/guides/complete-api-development.md @@ -1,5 +1,7 @@ # Complete API Development +> NOTE: The content of this file is outdated, refering to previous technologies used at adidas. It is kept for reference until its refresh + 1. **Design the API** 1. Analyze business requirements 2. Identify affordances diff --git a/rest-api-guidelines/functionality/message/README.md b/rest-api-guidelines/message/README.md similarity index 100% rename from rest-api-guidelines/functionality/message/README.md rename to rest-api-guidelines/message/README.md diff --git a/rest-api-guidelines/functionality/message/content-negotiation.md b/rest-api-guidelines/message/content-negotiation.md similarity index 100% rename from rest-api-guidelines/functionality/message/content-negotiation.md rename to rest-api-guidelines/message/content-negotiation.md diff --git a/rest-api-guidelines/functionality/message/error-reporting.md b/rest-api-guidelines/message/error-reporting.md similarity index 81% rename from rest-api-guidelines/functionality/message/error-reporting.md rename to rest-api-guidelines/message/error-reporting.md index d854444..707eced 100644 --- a/rest-api-guidelines/functionality/message/error-reporting.md +++ b/rest-api-guidelines/message/error-reporting.md @@ -4,7 +4,7 @@ The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) \(Problem Problem Detail is intended for use with the HTTP status codes 4xx and 5xx. Problem Detail **MUST NOT** be used with 2xx status code responses. -At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. +At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. `title` value **SHOULD NOT** change from occurrence to occurence of the problem, except for purposes of localization (e.g., using proactive content negotiation) [read more](https://tools.ietf.org/html/rfc7807#section-3.1) ### Example @@ -15,6 +15,8 @@ At the minimum, any Problem Detail response **MUST** have the `title` and `detai } ``` +> NOTE: `title` and `detail` fields **SHOULD NOT** be parsed to determine the nature of the error. Instead `type` **MUST** be used. + ## Optional Fields It **SHOULD** has the `type` field with the identifier of the error, besides it **MAY** have the `instance` field with the URI of the resource in question. If the Problem Detail response has the `status` field it **MUST** have the same value as HTTP Status code from of the response. @@ -39,7 +41,7 @@ If needed, the Problem Detail **MAY** include additional fields, refer to [RFC78 When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred. -These additional errors **MUST** be under the `errors` and **MUST** follow the Problem Detail structure. +These additional errors **MUST** be under the `errors` collection and **MUST** follow the Problem Detail structure. ### Example @@ -122,5 +124,8 @@ A Problem Detail response **MUST NOT** contain a program stack trace or server l ## Working with Problem Detail -There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) \(Java\). +An API description **MAY** list all the error codes with which the API responds. The error responses **SHOULD** describre the error object model schema. It is **RECOMMENDED** to include examples of a possible error response. The error description and/or error example **MAY** list all the types of errors returned for a given error code. +## External resources + +There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) \(Java\). diff --git a/rest-api-guidelines/functionality/message/foreign-key-relations.md b/rest-api-guidelines/message/foreign-key-relations.md similarity index 100% rename from rest-api-guidelines/functionality/message/foreign-key-relations.md rename to rest-api-guidelines/message/foreign-key-relations.md diff --git a/rest-api-guidelines/functionality/message/hal.md b/rest-api-guidelines/message/hal.md similarity index 85% rename from rest-api-guidelines/functionality/message/hal.md rename to rest-api-guidelines/message/hal.md index f280038..11a2569 100644 --- a/rest-api-guidelines/functionality/message/hal.md +++ b/rest-api-guidelines/message/hal.md @@ -8,6 +8,12 @@ The [`application/hal+json`](http://stateless.co/hal_specification.html) \(HAL\) This document is an informal introduction to the HAL media type. For more details see [HAL - Hypertext Application Language Specification](http://stateless.co/hal_specification.html). +## HAL Document Object Model + +HAL document follow the object model defined in JSON-schema [here](https://supermodel.io/adidas/api/HAL). + +YAML code snippets are provided for [OpenAPI Specification 2.0/Swagger](https://github.com/adidas/api-guidelines/tree/4a033eb0cf8ec582102c09c1eb5ba1fa8a5597d9/rest-api-guidelines/functionality/message/HAL-snippet.yaml) and [OpenAPI Specification 3.x](https://github.com/adidas/api-guidelines/tree/4a033eb0cf8ec582102c09c1eb5ba1fa8a5597d9/rest-api-guidelines/functionality/message/HAL-snippet-full-OpenApi3.yaml). + ## Simple Document Example The simplest Hal document looks like an empty JSON \(it is an empty JSON!\): @@ -113,6 +119,8 @@ Some APIs using HAL: Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries). +For working with HAL and Node.js using [HALson npm package](https://www.npmjs.com/package/halson) is suggested. + ### Spring Framework Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) and [examples](https://github.com/spring-guides/gs-rest-hateoas). diff --git a/rest-api-guidelines/functionality/message/message-formats.md b/rest-api-guidelines/message/message-formats.md similarity index 100% rename from rest-api-guidelines/functionality/message/message-formats.md rename to rest-api-guidelines/message/message-formats.md diff --git a/rest-api-guidelines/miscellaneous.md b/rest-api-guidelines/miscellaneous.md index 2b98096..c135d69 100644 --- a/rest-api-guidelines/miscellaneous.md +++ b/rest-api-guidelines/miscellaneous.md @@ -2,4 +2,9 @@ * [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3) * [Deprecating "X-"](https://tools.ietf.org/html/rfc6648) +* [Collection of standards and specifications for HTTP/REST APIs](http://standards.rest) +* [Official list of HTTP Message Headers](https://www.iana.org/assignments/message-headers/message-headers.xhtml) +## Tools documentation + +* [SwaggerHub Documentation](https://app.swaggerhub.com/help/index) diff --git a/rest-api-guidelines/functionality/protocol/README.md b/rest-api-guidelines/protocol/README.md similarity index 100% rename from rest-api-guidelines/functionality/protocol/README.md rename to rest-api-guidelines/protocol/README.md diff --git a/rest-api-guidelines/functionality/protocol/http.md b/rest-api-guidelines/protocol/http.md similarity index 90% rename from rest-api-guidelines/functionality/protocol/http.md rename to rest-api-guidelines/protocol/http.md index 85b68d7..364565f 100644 --- a/rest-api-guidelines/functionality/protocol/http.md +++ b/rest-api-guidelines/protocol/http.md @@ -10,7 +10,7 @@ Once you are familiar with the **HTTP message structure** learn about the **HTTP Each HTTP request method, status code, and header have its semantics defined, and every API **MUST** strictly adhere to it. -Follow the [Robustness Principle](../../../general-guidelines/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others. +Follow the [Robustness Principle](../../general-guidelines/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others. ## Know HTTP diff --git a/rest-api-guidelines/functionality/protocol/separate-concerns.md b/rest-api-guidelines/protocol/separate-concerns.md similarity index 100% rename from rest-api-guidelines/functionality/protocol/separate-concerns.md rename to rest-api-guidelines/protocol/separate-concerns.md diff --git a/rest-api-guidelines/functionality/protocol/tls.md b/rest-api-guidelines/protocol/tls.md similarity index 100% rename from rest-api-guidelines/functionality/protocol/tls.md rename to rest-api-guidelines/protocol/tls.md diff --git a/rest-api-guidelines/functionality/protocol/use-appropriate-methods.md b/rest-api-guidelines/protocol/use-appropriate-methods.md similarity index 100% rename from rest-api-guidelines/functionality/protocol/use-appropriate-methods.md rename to rest-api-guidelines/protocol/use-appropriate-methods.md diff --git a/rest-api-guidelines/functionality/protocol/use-appropriate-status-codes.md b/rest-api-guidelines/protocol/use-appropriate-status-codes.md similarity index 100% rename from rest-api-guidelines/functionality/protocol/use-appropriate-status-codes.md rename to rest-api-guidelines/protocol/use-appropriate-status-codes.md diff --git a/rest-api-guidelines/quality/README.md b/rest-api-guidelines/quality/README.md deleted file mode 100644 index dab3552..0000000 --- a/rest-api-guidelines/quality/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Quality - - - diff --git a/rest-api-guidelines/quality/execution/asynchronous-tasks.md b/rest-api-guidelines/quality/execution/asynchronous-tasks.md deleted file mode 100644 index 234ef73..0000000 --- a/rest-api-guidelines/quality/execution/asynchronous-tasks.md +++ /dev/null @@ -1,28 +0,0 @@ -# Asynchronous Tasks - -If an API operation is asynchronous, but a client could track its progress, the response to such an asynchronous operation **MUST** return, in the case of success, the **202 Accepted** status code together with an `application/hal+json` representation of a new **task-tracking resource**. - -## Task Tracking Resource - -The task-tracking resource **SHOULD** convey the information about the status of an asynchronous task. - -Retrieval of such a resource using the HTTP GET Request Method **SHOULD** be designed as follows: - -1. Task is Still Processing - - Return **200 OK** and representation of the current status. - -2. Task Successfully Completed - - Return **303 See Other** together with [HTTP Location Header](https://tools.ietf.org/html/rfc7231#section-7.1.2) with URI or a outcome resource. - -3. Task Failed - - Return **200 OK** and `application/problem+json` with the problem detail information on the task has failed. - -## Design Note - -The asynchronous operation task-tracking resource can be either **polled** by client or the client might initially provide a **callback** to be executed when the operation finishes. - -In the case of callback, the API and its client MUST agree on what HTTP method and request format is used for the callback invitation. If built within adidas, the "client" API is also the subject of the adidas API guidelines. - diff --git a/rest-api-guidelines/rest.md b/rest-api-guidelines/rest.md index a16c1c0..716f023 100644 --- a/rest-api-guidelines/rest.md +++ b/rest-api-guidelines/rest.md @@ -2,7 +2,7 @@ ## adidas REST API Guidelines -The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. **These Guidelines has to be followed in addition to the adidas** [**General API Guidelines.**](../general-guidelines/general-guidelines.md) +Adidas REST API Guidelines define standards and guidelines for building REST APIs at adidas. **These Guidelines have to be followed in addition to the Adidas** [**General API Guidelines.**](../general-guidelines/general-guidelines.md) The REST API Guidelines are further split into the following parts: @@ -11,26 +11,26 @@ The REST API Guidelines are further split into the following parts: REST API Guidelines Core Principles defines the rules that **MUST** be followed at throughout the full API lifecycle. * **Functionality Guidelines** - * \*\*\*\*[**Protocol level**](functionality/protocol/)\*\*\*\* + * \*\*\*\*[**Protocol level**](protocol/)\*\*\*\* Protocol guidelines define the protocols used within the organization. - * \*\*\*\*[**Message level**](functionality/message/)\*\*\*\* + * \*\*\*\*[**Message level**](message/)\*\*\*\* The Message guidelines define the structure and semantics of messages used to exchange information. - * \*\*\*\*[**Application level**](functionality/application/) + * \*\*\*\*[**Application level**](application/) The Application guidelines define the definition and use of application-specific semantics. * **Quality Guidelines** Evolution and Execution guidelines define the rules for achieving the desired architectural qualities of systems. - * \*\*\*\*[**Evolution**](quality/evolution/)\*\*\*\* + * \*\*\*\*[**Evolution**](evolution/)\*\*\*\* Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - * \*\*\*\*[**Execution**](quality/execution/)\*\*\*\* + * \*\*\*\*[**Execution**](execution/)\*\*\*\* Execution qualities governance, such as security and usability. diff --git a/rest/examples.md b/rest/examples.md index c46b5c1..c481b51 100644 --- a/rest/examples.md +++ b/rest/examples.md @@ -1,20 +1,3 @@ # Examples -Sample APIs following the guidelines are available at [adidas-group GitHub](https://github.com/adidas-group). The samples include the following: - - -### [Simple API](https://github.com/adidas-group/demo-simple-api) -Very simple API including implementation, testing, and full CI/CD lifecycle. - -### [Approval API](https://github.com/adidas-group/demo-approval-api) -Real-world API with state transition, API key client app authentication, exposed via API management. - -### [Orders API](https://github.com/adidas-group/demo-orders-api) -Sample API used as the template for newly created projects at Apiary. - -### [Appointment Service](https://github.com/adidas-group/demo-appointment-service) -Demo API, including implementation and testing used during training. - -### [Complex Search Parameters](https://github.com/adidas-group/demo-complex-search) -Sample API showcasing description of complex query parameter rules. - +Sample APIs following the guidelines are available at in the [examples repository folder](https://github.com/adidas/api-guidelines/tree/master/examples). diff --git a/rest/execution/authentication.md b/rest/execution/authentication.md index f042197..05bf868 100644 --- a/rest/execution/authentication.md +++ b/rest/execution/authentication.md @@ -22,4 +22,3 @@ Adidas-API-Key: 9kfapap6612jkfd3ja9323q Host: adidas.api.mashery.com ``` -> NOTE: See more details in the [[Demo] Approval API](http://docs.demoapprovalapi.apiary.io) example. diff --git a/ruleset.md b/ruleset.md new file mode 100644 index 0000000..1a98bc2 --- /dev/null +++ b/ruleset.md @@ -0,0 +1,23 @@ +# Adidas API Guidelines Ruleset + +- all JSON fields MUST follow `camelCase` +- field names MUST be ASCII alphanumeric characters or `_` or `$` +- collection/array fields MUST have names in plural +- all requests go through `https` protocol +- every API operation MUST have at least one `2xx` response +- `GET` request MUST NOT accept a `body` parameter +- all success responses MUST be of media type `application/hal+json` +- all error responses MUST be of media type `application/problem+json` +- every request SHOULD support `application/json` media type +- `application/hal+json` follows https://supermodel.io/adidas/api/HAL `JSON-Schema` +- `application/problem+json` messages MUST include `title` and `detail` fields +- `application/problem+json` messages SHOULD include `type` field +- date and time MUST follow `ISO 8601` standard: https://www.iso.org/iso-8601-date-and-time-format.html +- language codes MUST follow `ISO 639` standard: https://www.iso.org/iso-639-language-codes.html +- country codes MUST follow `ISO 3166 alpha-2` standard: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 +- currency codes MUST follow `ISO 4217` standard: https://en.wikipedia.org/wiki/ISO_4217 +- `202` response code is used after creating an asynchronous process request +- a successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header +- `URI` template ([RFC 6570](https://tools.ietf.org/html/rfc6570)) cannot contain a `-` character +- `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation +- `HTTP` headers SHOULD NOT include [`X-` headers](2). All non-standard headers are named without the `X-` prefix. diff --git a/supermodel/.super b/supermodel/.super new file mode 100644 index 0000000..c2653d5 --- /dev/null +++ b/supermodel/.super @@ -0,0 +1,3 @@ +{ + "host": "https://supermodel.io" +} \ No newline at end of file diff --git a/supermodel/adidas/api/HAL.yaml b/supermodel/adidas/api/HAL.yaml new file mode 100644 index 0000000..5cc17d4 --- /dev/null +++ b/supermodel/adidas/api/HAL.yaml @@ -0,0 +1,63 @@ +$id: http://supermodel.io/adidas/api/HAL +$schema: http://json-schema.org/draft-07/schema# +title: HAL +description: JSON Hypertext Application Language. Definition of [HAL message format](https://tools.ietf.org/html/draft-kelly-json-hal-08) +type: object +properties: + _links: + type: object + additionalProperties: + anyOf: + - $ref: '#/definitions/halLinkObject' + - type: array + items: + - $ref: '#/definitions/halLinkObject' + properties: + curies: + anyOf: + - $ref: '#/definitions/halCuriesLink' + - type: array + items: + - $ref: '#/definitions/halCuriesLink' + _embedded: + type: object + additionalProperties: + anyOf: + - $ref: '#' + - type: array + items: + - $ref: '#' +definitions: + halLinkObject: + title: HAL Link Object + type: object + properties: + href: + type: string + templated: + type: boolean + type: + type: string + deprecation: + type: string + name: + type: string + profile: + type: string + title: + type: string + hreflang: + type: string + required: + - href + halCuriesLink: + title: HAL Curies Link + allOf: + - type: object + properties: + templated: + enum: + - true + required: + - templated + - $ref: '#/definitions/halLinkObject' \ No newline at end of file diff --git a/supermodel/adidas/api/ProblemDetail.yaml b/supermodel/adidas/api/ProblemDetail.yaml new file mode 100644 index 0000000..a4e0788 --- /dev/null +++ b/supermodel/adidas/api/ProblemDetail.yaml @@ -0,0 +1,19 @@ +$id: http://supermodel.io/adidas/api/ProblemDetail +$schema: http://json-schema.org/draft-07/schema# +title: Problem Details for HTTP APIs +description: Definition of [RFC7807](https://tools.ietf.org/html/rfc7807) problem detail +type: object +properties: + type: + type: string + title: + type: string + status: + type: number + detail: + type: string + instance: + type: string +required: + - title + - detail \ No newline at end of file diff --git a/supermodel/adidas/examples/order/Order.yaml b/supermodel/adidas/examples/order/Order.yaml new file mode 100644 index 0000000..e6cbaad --- /dev/null +++ b/supermodel/adidas/examples/order/Order.yaml @@ -0,0 +1,22 @@ +$id: http://supermodel.io/adidas/examples/order/Order +$schema: http://json-schema.org/draft-07/schema# + +title: Order +type: object +description: Order model description + +properties: + orderNumber: + type: number + itemCount: + type: number + status: + type: string +required: + - orderNumber + - itemCount +examples: +- orderNumber: 42 + itemCount: 3 + status: pending + \ No newline at end of file diff --git a/supermodel/adidas/examples/order/api/Order.yaml b/supermodel/adidas/examples/order/api/Order.yaml new file mode 100644 index 0000000..34c1f54 --- /dev/null +++ b/supermodel/adidas/examples/order/api/Order.yaml @@ -0,0 +1,23 @@ +$id: http://supermodel.io/adidas/examples/order/api/Order +$schema: http://json-schema.org/draft-07/schema# + +title: Order HAL Representation +type: object + +allOf: + - $ref: http://supermodel.io/adidas/api/HAL + - $ref: http://supermodel.io/adidas/examples/order/Order + +examples: +- _links: + self: + href: /orders/1234 + edit: + href: /orders/1234 + delete: + href: /orders/1234 + profile: + href: https://adidas-group.com/gdm/OMS + orderNumber: 1234 + itemCount: 42 + status: pending \ No newline at end of file diff --git a/supermodel/adidas/examples/order/api/OrderPatch.yaml b/supermodel/adidas/examples/order/api/OrderPatch.yaml new file mode 100644 index 0000000..bd93686 --- /dev/null +++ b/supermodel/adidas/examples/order/api/OrderPatch.yaml @@ -0,0 +1,14 @@ +$id: http://supermodel.io/adidas/examples/order/api/OrderPatch +$schema: http://json-schema.org/draft-07/schema# + +title: OrderPatch +description: OrderPatch model description +type: object + +allOf: + - $ref: 'http://supermodel.io/adidas/examples/order/Order' + +examples: +- status: cancelled + orderNumber: 1 + itemCount: 2 \ No newline at end of file diff --git a/supermodel/adidas/examples/order/api/Orders.yaml b/supermodel/adidas/examples/order/api/Orders.yaml new file mode 100644 index 0000000..e102b4e --- /dev/null +++ b/supermodel/adidas/examples/order/api/Orders.yaml @@ -0,0 +1,36 @@ +$id: http://supermodel.io/adidas/examples/order/api/Orders +$schema: http://json-schema.org/draft-07/schema# + +title: Collection of Orders HAL Representation +type: object + +allOf: + - $ref: http://supermodel.io/adidas/api/HAL + +examples: +- _links: + self: + href: /orders + create: + href: /orders + next: + href: /orders?offset=5&limit=5 + first: + href: /orders?offset=0&limit=5 + last: + href: /orders?offset=40&limit=5 + + _embedded: + order: + - _links: + self: + href: /orders/1234 + edit: + href: /orders/1234 + delete: + href: /orders/1234 + profile: + href: https://adidas-group.com/gdm/OMS + orderNumber: 1234 + itemCount: 42 + status: pending \ No newline at end of file diff --git a/supermodel/adidas/examples/order/api/ProblemDetail.yaml b/supermodel/adidas/examples/order/api/ProblemDetail.yaml new file mode 100644 index 0000000..b8e0fba --- /dev/null +++ b/supermodel/adidas/examples/order/api/ProblemDetail.yaml @@ -0,0 +1,9 @@ +$id: http://supermodel.io/adidas/examples/order/api/ProblemDetail +$schema: http://json-schema.org/draft-07/schema# + +title: Problem Detail +type: object + +allOf: + - $ref: http://supermodel.io/adidas/api/ProblemDetail + diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..3ff9eb1 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1625 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/runtime@^7.0.0": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b" + integrity sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw== + dependencies: + regenerator-runtime "^0.13.2" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@stoplight/json-ref-resolver@^2.2.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@stoplight/json-ref-resolver/-/json-ref-resolver-2.4.1.tgz#db54b0771226611e1beb2e908493903139f2a4a8" + integrity sha512-y9G0BybShiJ/1NaPPG1BPelL2zI8/0rKXRtUpD2JBHEb72L9n4Bin85+MfrHYoHeJxojDpewsJA3FVRnUVL1dw== + dependencies: + "@stoplight/json" "^3.1.2" + "@stoplight/path" "^1.3.0" + "@stoplight/types" "^11.0.0" + "@types/urijs" "1.x.x" + dependency-graph "~0.8.0" + fast-memoize "^2.5.1" + immer "^3.2.0" + lodash "^4.17.15" + tslib "^1.10.0" + urijs "~1.19.1" + +"@stoplight/json@^3.1.1", "@stoplight/json@^3.1.2": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@stoplight/json/-/json-3.2.1.tgz#cbc8080f4a55744beb89668d058e48ba52da141b" + integrity sha512-RnXApQlP6GEUHIK8JRianStXTc4dHARpNP8VVGL/BbctTTlA3BO+Z1eILu35JdqvMG5sw6Og3TkQyQ85w6sSoA== + dependencies: + "@stoplight/types" "^11.1.1" + jsonc-parser "~2.2.0" + lodash "^4.17.15" + safe-stable-stringify "^1.1" + +"@stoplight/path@^1.2.0", "@stoplight/path@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@stoplight/path/-/path-1.3.0.tgz#da2282352a4eb23c09d5106b9d1650d30a9ca2ad" + integrity sha512-t74/MHMgmFVMQhdQ/2Q766GryNTIW8McH8+vB25oeoBhYKTOrJ/wPDt+OCxIWHPUlcSi2fTWa4FKQ8qgmP2jVA== + +"@stoplight/spectral@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@stoplight/spectral/-/spectral-4.2.0.tgz#e095f93b44ecdd7ca11d15f513efa5f49822f83e" + integrity sha512-td5vZ0W8cGMpElG0UcdzFrqbEuJR81D9oPLCJoEEXsN5a8k2HGNkMxVJ5alC31wxahKTDzVmVIkBacJW+DzKRQ== + dependencies: + "@stoplight/json" "^3.1.1" + "@stoplight/json-ref-resolver" "^2.2.0" + "@stoplight/path" "^1.2.0" + "@stoplight/types" "^11.0.0" + "@stoplight/yaml" "^3.1.0" + abort-controller "^3.0.0" + ajv "^6.7" + ajv-oai "^1.1.1" + better-ajv-errors "^0.6.7" + chalk "^2.4.2" + deprecated-decorator "^0.1.6" + fast-glob "^3.0.4" + jsonpath-plus "~1.0" + lodash ">=4.17.5" + nanoid "^2.0.3" + node-fetch "^2.6" + proxy-agent "^3.1.0" + strip-ansi "^5.2" + text-table "^0.2" + tslib "^1.10.0" + typescript-json-schema "~0.40" + yargs "^14.0.0" + +"@stoplight/types@^11.0.0", "@stoplight/types@^11.1.1": + version "11.3.0" + resolved "https://registry.yarnpkg.com/@stoplight/types/-/types-11.3.0.tgz#23d40cbf2c3c85e5612038b5cf0c003f82809318" + integrity sha512-m6N4Bv2O2bYJOXdIwtpLtfQY/3zHUgRuHx2D8ERydX8WE40nKoLqh4wN6nvRcSeGwxjhi0Q0KUAZIe9UsYj6fQ== + dependencies: + "@types/json-schema" "^7.0.3" + +"@stoplight/yaml-ast-parser@0.0.44": + version "0.0.44" + resolved "https://registry.yarnpkg.com/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.44.tgz#ed3c962564283e9983f7895a6effc3994286df5e" + integrity sha512-PdY8p2Ufgtorf4d2DbKMfknILMa8KwuyyMMR/2lgK1mLaU8F5PKWYc+h9hIzC+ar0bh7m9h2rINo32m7ADfVyA== + +"@stoplight/yaml@^3.1.0": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@stoplight/yaml/-/yaml-3.3.2.tgz#001049ed4a8733fca43cc60efe6bcd046abef210" + integrity sha512-KfrEsl3bA8mtoIklVvS4Hg8OrOYYtqi+K0IsQ7lJbZLVaUA4wMwDGwz85a6YWeo1OuVe8tumM6OynrFIjFutNA== + dependencies: + "@stoplight/types" "^11.1.1" + "@stoplight/yaml-ast-parser" "0.0.44" + lodash "^4.17.15" + +"@supermodel/cli@^0.46.29": + version "0.46.29" + resolved "https://registry.yarnpkg.com/@supermodel/cli/-/cli-0.46.29.tgz#0389032ae6f286060ddae640436378878b2f0583" + integrity sha512-xqkFcPTlFjNBxfaNk9/tZaV1ShNsk7XudCAAA4abBOQvwZ6HcsCWonupr2zLTb+TKrkDCTui3riglxV3AW7o7A== + dependencies: + "@supermodel/file" "^0.5.3" + "@supermodel/lib" "^0.4.23" + ajv "^6.1.1" + auth0-js "9.13.2" + casex "3.0.0" + commander "^2.14.1" + dotenv "5.0.1" + glob "7.1.3" + graphql "0.13.2" + inquirer "5.2.0" + isomorphic-fetch "2.2.1" + js-yaml "^3.10.0" + node-fetch "2.1.2" + rimraf "2.6.2" + +"@supermodel/file@^0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@supermodel/file/-/file-0.5.3.tgz#adcadaef4d244c92968f248c0269569ab26c5d48" + integrity sha512-2AnjbsY24bvzQjlOSmqPn2SDLL9vstzKfNjFJSBv911a7AzCxceVy7c2w7zQpjiuBrFsM2jS3cKL4Qhk2Kdh5A== + dependencies: + js-yaml "^3.11.0" + node-fetch "^2.2.0" + +"@supermodel/lib@^0.4.23": + version "0.4.23" + resolved "https://registry.yarnpkg.com/@supermodel/lib/-/lib-0.4.23.tgz#ec8161747eaf6387b2e57b8c97313b855bd11716" + integrity sha512-FtEdiNq95GeUHpRt1rJa4zuYmspgyAjqP6GWka3gAJpZknBtd1FmFJPBAgHJGOvSonIRN7dm27m9rZgSO2vvYg== + dependencies: + ajv "^6.4.0" + casex "3.0.0" + graphql "14.1.1" + js-yaml "^3.11.0" + jsonpointer "4.0.1" + url "0.11.0" + +"@types/json-schema@^7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" + integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== + +"@types/urijs@1.x.x": + version "1.19.4" + resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.4.tgz#29c4a694d4842d7f95e359a26223fc1865f1ab13" + integrity sha512-uHUvuLfy4YkRHL4UH8J8oRsINhdEHd9ymag7KJZVT94CjAmY1njoUzhazJsZjwfy+IpWKQKGVyXCwzhZvg73Fg== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +ajv-oai@^1.1.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ajv-oai/-/ajv-oai-1.1.5.tgz#f6a3ffa6a84ee90234a296ef733e9e18c875365e" + integrity sha512-JSBfA99K9cI22qJ8rwCyJ7J15iEMFOeHL8LqH+PL47HzeN7YZc7ZazQNg9eLO6TuPLBCfkiuMNLulKTGMzp25w== + dependencies: + decimal.js "^10.2.0" + +ajv@^6.1.1, ajv@^6.4.0, ajv@^6.7: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +ast-types@0.x.x: + version "0.13.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" + integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +auth0-js@9.13.2: + version "9.13.2" + resolved "https://registry.yarnpkg.com/auth0-js/-/auth0-js-9.13.2.tgz#78ea02d28a0a8c5ee4eb27c229563227071451d0" + integrity sha512-gWlf+X3XhCT9JboYpGviflv0pHcaHFPGtkLXiebyJohHDKddiu2rZkezp9kZHEoXqxhtNqgWuuaXkcla5JtnXg== + dependencies: + base64-js "^1.3.0" + idtoken-verifier "^2.0.2" + js-cookie "^2.2.0" + qs "^6.7.0" + superagent "^3.8.3" + url-join "^4.0.1" + winchan "^0.2.2" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +better-ajv-errors@^0.6.7: + version "0.6.7" + resolved "https://registry.yarnpkg.com/better-ajv-errors/-/better-ajv-errors-0.6.7.tgz#b5344af1ce10f434fe02fc4390a5a9c811e470d1" + integrity sha512-PYgt/sCzR4aGpyNy5+ViSQ77ognMnWq7745zM+/flYO4/Yisdtp9wDQW2IKCyVYPUxQt3E/b5GBSwfhd1LPdlg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/runtime" "^7.0.0" + chalk "^2.4.1" + core-js "^3.2.1" + json-to-ast "^2.0.3" + jsonpointer "^4.0.1" + leven "^3.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +casex@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/casex/-/casex-3.0.0.tgz#97104bfa93d6535cf4608f32aa80ba87d351b427" + integrity sha512-fBWw2Hur76NRY92xwgWKV2LoVc423HgxY625Tou+iG1SiZX3aNLT9oMgGz8FuStKv9kjpGxMeG5Kb9ybNnci3w== + +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-error-fragment@0.0.230: + version "0.0.230" + resolved "https://registry.yarnpkg.com/code-error-fragment/-/code-error-fragment-0.0.230.tgz#d736d75c832445342eca1d1fedbf17d9618b14d7" + integrity sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +combined-stream@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.14.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +component-emitter@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +cookiejar@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +core-js@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.4.2.tgz#ee2b1a60b50388d8ddcda8cdb44a92c7a9ea76df" + integrity sha512-bUTfqFWtNKWp73oNIfRkqwYZJeNT3lstzZcAkhhiuvDraRSgOH1/+F9ZklbpR4zpdKuo4cpXN8tKP7s61yjX+g== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +crypto-js@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" + integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== + +data-uri-to-buffer@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" + integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== + +debug@2: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decimal.js@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" + integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +degenerator@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" + integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= + dependencies: + ast-types "0.x.x" + escodegen "1.x.x" + esprima "3.x.x" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +dependency-graph@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.8.0.tgz#2da2d35ed852ecc24a5d6c17788ba57c3708755b" + integrity sha512-DCvzSq2UiMsuLnj/9AL484ummEgLtZIcRS7YvtO38QnpX3vqh9nJ8P+zhu8Ja+SmLrBHO2iDbva20jq38qvBkQ== + +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= + +dotenv@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" + integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +es6-promise@^4.0.3, es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.x.x: + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@3.x.x, esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-glob@^3.0.4: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.0.tgz#77375a7e3e6f6fc9b18f061cddd28b8d1eec75ae" + integrity sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-memoize@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.1.tgz#c3519241e80552ce395e1a32dcdde8d1fd680f5d" + integrity sha512-xdmw296PCL01tMOXx9mdJSmWY29jQgxyuZdq0rEHMu+Tpe1eOEtCycoG6chzlcrWsNgpZP7oL8RiQr7+G6Bl6g== + +fastq@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" + integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA== + dependencies: + reusify "^1.0.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-uri-to-path@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +form-data@^2.3.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formidable@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" + integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +ftp@~0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-uri@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.4.tgz#d4937ab819e218d4cb5ae18e4f5962bef169cc6a" + integrity sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q== + dependencies: + data-uri-to-buffer "1" + debug "2" + extend "~3.0.2" + file-uri-to-path "1" + ftp "~0.3.10" + readable-stream "2" + +glob-parent@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + dependencies: + is-glob "^4.0.1" + +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5, glob@~7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +graphql@0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== + dependencies: + iterall "^1.2.1" + +graphql@14.1.1: + version "14.1.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.1.1.tgz#d5d77df4b19ef41538d7215d1e7a28834619fac0" + integrity sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q== + dependencies: + iterall "^1.2.2" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +http-errors@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +https-proxy-agent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81" + integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +idtoken-verifier@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/idtoken-verifier/-/idtoken-verifier-2.0.2.tgz#7fd1c64c435abf07e92f137e7ac538a758fdc399" + integrity sha512-9UN83SKT9dtN3d7vNz3EMTqoaJi3D02Zg5XMqF6+bLrGL+Akbx4oj4SEWsgXtLF6cy46XrUcVzokFY+SWO+/MA== + dependencies: + base64-js "^1.3.0" + crypto-js "^3.2.1" + es6-promise "^4.2.8" + jsbn "^1.1.0" + unfetch "^4.1.0" + url-join "^4.0.1" + +immer@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-3.3.0.tgz#ee7cf3a248d5dd2d4eedfbe7dfc1e9be8c72041d" + integrity sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inquirer@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" + integrity sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.1.0" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^5.5.2" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +ip@1.1.5, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isomorphic-fetch@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +iterall@^1.2.1, iterall@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== + +js-cookie@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.10.0, js-yaml@^3.11.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-to-ast@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json-to-ast/-/json-to-ast-2.1.0.tgz#041a9fcd03c0845036acb670d29f425cea4faaf9" + integrity sha512-W9Lq347r8tA1DfMvAGn9QNcgYm4Wm7Yc+k8e6vezpMnRT+NHbtlxgNBXRVjXe9YM6eTn6+p/MKOlV/aABJcSnQ== + dependencies: + code-error-fragment "0.0.230" + grapheme-splitter "^1.0.4" + +jsonc-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.0.tgz#f206f87f9d49d644b7502052c04e82dd6392e9ef" + integrity sha512-4fLQxW1j/5fWj6p78vAlAafoCKtuBm6ghv+Ij5W2DrDx0qE+ZdEl2c6Ko1mgJNF5ftX1iEWQQ4Ap7+3GlhjkOA== + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpath-plus@~1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-1.0.0.tgz#78fa5c4ae62968476268d505d9f78c65469d0e7c" + integrity sha512-CXQJ/tsgFogKYBuCRmnlChIw66JBXp8kAkT+R4mSB2cuzCSBi88lx2A+vHvo27RY4Wtj5xVVGu2/2O7NwZ79mg== + +jsonpointer@4.0.1, jsonpointer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash@>=4.17.5, lodash@^4.17.15, lodash@^4.3.0: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +merge2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +methods@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +mime-db@1.43.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-types@^2.1.12: + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + dependencies: + mime-db "1.43.0" + +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nanoid@^2.0.3: + version "2.1.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.7.tgz#d775e3e7c6470bbaaae3da9a647a80e228e0abf7" + integrity sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ== + +netmask@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= + +node-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^2.2.0, node-fetch@^2.6: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pac-proxy-agent@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz#115b1e58f92576cac2eba718593ca7b0e37de2ad" + integrity sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ== + dependencies: + agent-base "^4.2.0" + debug "^4.1.1" + get-uri "^2.0.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^3.0.0" + pac-resolver "^3.0.0" + raw-body "^2.2.0" + socks-proxy-agent "^4.0.1" + +pac-resolver@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26" + integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== + dependencies: + co "^4.6.0" + degenerator "^1.0.4" + ip "^1.1.5" + netmask "^1.0.6" + thunkify "^2.1.2" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +picomatch@^2.0.5: + version "2.1.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.1.1.tgz#ecdfbea7704adb5fe6fb47f9866c4c0e15e905c5" + integrity sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-agent@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.1.tgz#7e04e06bf36afa624a1540be247b47c970bd3014" + integrity sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw== + dependencies: + agent-base "^4.2.0" + debug "4" + http-proxy-agent "^2.1.0" + https-proxy-agent "^3.0.0" + lru-cache "^5.1.1" + pac-proxy-agent "^3.0.1" + proxy-from-env "^1.0.0" + socks-proxy-agent "^4.0.1" + +proxy-from-env@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@^6.5.1, qs@^6.7.0: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +raw-body@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +regenerator-runtime@^0.13.2: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +reusify@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +rxjs@^5.5.2: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== + dependencies: + symbol-observable "1.0.1" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-stable-stringify@^1.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.0.tgz#f712b600f8f775444ccc66e8f31d250e43fdfe01" + integrity sha512-8h+96qSufNQrydRPzbHms38VftQQSRGbqUkaIMWUBWN4/N8sLNALIALa8KmFcQ8P/a9uzMkA+KY04Rj5WQiXPA== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + +socks-proxy-agent@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== + dependencies: + agent-base "~4.2.1" + socks "~2.3.2" + +socks@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" + integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== + dependencies: + ip "1.1.5" + smart-buffer "^4.1.0" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +superagent@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" + integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.2.0" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.3.5" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= + +text-table@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunkify@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" + integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tslib@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +typescript-json-schema@~0.40: + version "0.40.0" + resolved "https://registry.yarnpkg.com/typescript-json-schema/-/typescript-json-schema-0.40.0.tgz#4815092e5acf1662a94aa140924809ff5922da7c" + integrity sha512-C8D3Ca6+1x3caWOR+u45Shn3KqkRZi5M3+E8ePpEmYMqOh3xhhLdq+39pqT0Bf8+fCgAmpTFSJMT6Xwqbm0Tkw== + dependencies: + "@types/json-schema" "^7.0.3" + glob "~7.1.4" + json-stable-stringify "^1.0.1" + typescript "^3.5.3" + yargs "^14.0.0" + +typescript@^3.5.3: + version "3.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb" + integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ== + +unfetch@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.1.0.tgz#6ec2dd0de887e58a4dee83a050ded80ffc4137db" + integrity sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg== + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urijs@~1.19.1: + version "1.19.2" + resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.2.tgz#f9be09f00c4c5134b7cb3cf475c1dd394526265a" + integrity sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w== + +url-join@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + +url@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +whatwg-fetch@>=0.10.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +winchan@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/winchan/-/winchan-0.2.2.tgz#6766917b88e5e1cb75f455ffc7cc13f51e5c834e" + integrity sha512-pvN+IFAbRP74n/6mc6phNyCH8oVkzXsto4KCHPJ2AScniAnA1AmeLI03I2BzjePpaClGSI4GUMowzsD3qz5PRQ== + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" + integrity sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^14.0.0: + version "14.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" + integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== + dependencies: + cliui "^5.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^15.0.0"