GithubHelp home page GithubHelp logo

apidevtools / swagger-cli Goto Github PK

View Code? Open in Web Editor NEW
515.0 14.0 70.0 432 KB

Swagger 2.0 and OpenAPI 3.0 command-line tool

Home Page: https://apitools.dev/swagger-cli

License: MIT License

JavaScript 100.00%
swagger open-api json-schema parser validator validation nodejs javascript cli

swagger-cli's Introduction

Swagger/OpenAPI CLI

npm License Buy us a tree

⚠️ Swagger CLI has been deprecated, due to the maintenance burnden of trying to keep up with expectations of a huge userbase with little to no pull requests or support. Redocly CLI covers all of the same functionality, and has more advanced linting with custom rules, and we highly recommend using that instead. They have conveniently provided a migration guide for existing Swagger CLI users. Read the review of Redocly CLI from APIs You Won't Hate.

Features

  • Validate Swagger/OpenAPI files in JSON or YAML format
  • Supports multi-file API definitions via $ref pointers
  • Bundle multiple Swagger/OpenAPI files into one combined file

Related Projects

Installation

Install using npm:

npm install -g @apidevtools/swagger-cli

Usage

swagger-cli <command> [options] <file>

Commands:
    validate                Validates an API definition in Swagger 2.0 or OpenAPI 3.0 format

    bundle                  Bundles a multi-file API definition into a single file

Options:
    -h, --help              Show help for any command
    -v, --version           Output the CLI version number
    -d, --debug [filter]    Show debug output, optionally filtered (e.g. "*", "swagger:*", etc.)

Validate an API

The swagger-cli validate command will validate your Swagger/OpenAPI definition against the Swagger 2.0 schema or OpenAPI 3.0 Schema. It also performs additional validations against the specification, which will catch some things that aren't covered by the schema, such as duplicate parameters, invalid MIME types, etc.

The command will exit with a non-zero code if the API is invalid.

swagger-cli validate [options] <file>

Options:
    --no-schema             Do NOT validate against the Swagger/OpenAPI JSON schema

    --no-spec               Do NOT validate against the Swagger/OpenAPI specification

Git pre-commit hook

There is a useful Python tool called pre-commit that can be used to execute a wide suite of pre-commit checks. The swagger-cli validate command can be integrated as part of a git pre-commit hook by adding the following configuration to the repos entry of an existing .pre-commit-config.yaml file.

-   repo: https://github.com/APIDevTools/swagger-cli
    rev: v2.2.1
    hooks:
    - id: swagger-validation
      args: ["validate", "<path to root swagger>"]

The intention is to point to single root swagger that references multiple swagger definitions. The above hook will execute the swagger-cli validation against the root swagger anytime that a file matching the pattern .*swagger.*\.(json|yaml|yml) is modified. Any failures in this validation will prevent the git commit from being processed.

Combine Multiple Files

The Swagger and OpenAPI specs allows you to split your API definition across multiple files using $ref pointers to reference each file. You can use the swagger-cli bundle command to combine all of those referenced files into a single file, which is useful for distribution or interoperation with other tools.

By default, the swagger-cli bundle command tries to keep the output file size as small as possible, by only embedding each referenced file once. If the same file is referenced multiple times, then any subsequent references are simply modified to point to the single inlined copy of the file. If you want to produce a bundled file without any $ref pointers, then add the --dereference option. This will result in a larger file size, since multiple references to the same file will result in that file being embedded multiple times.

If you don't specify the --outfile option, then the bundled API will be written to stdout, which means you can pipe it to other commands.

The result of this method by default is written as JSON. It can be changed to YAML with the --type option, by passing the yaml value.

swagger-cli bundle [options] <file>

Options:
    -o, --outfile <file>        The output file

    -r, --dereference           Fully dereference all $ref pointers

    -f, --format <spaces>       Formats the output using the given number of spaces
                                (the default is 2 spaces)

    -t, --type <filetype>       Defines the output file type. The valid values are: json, yaml
                                (the default is JSON)

    -w, --wrap <column>         Set the line length for YAML strings
                                (the default is no wrapping)

Contributing

I welcome any contributions, enhancements, and bug-fixes. Open an issue on GitHub and submit a pull request.

Building/Testing

To build/test the project locally on your computer:

  1. Clone this repo
    git clone https://github.com/APIDevTools/swagger-cli.git

  2. Install dependencies
    npm install

  3. Run the tests
    npm test

License

Swagger CLI is 100% free and open-source, under the MIT license. Use it however you want.

This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

Big Thanks To

Thanks to these awesome companies for their support of Open Source developers ❤

Travis CI SauceLabs Coveralls

swagger-cli's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger-cli's Issues

Duplicate properties not detected by validate

Hello,

I have found what I think may be an issue where the validation of the json is accepted but swagger-ui will detect an duplicate-key error

Platform:

  • OSX
  • swagger-cli version 2.2.1
# swagger-cli validate swagger_incorrect.json                                                                                                                                                                      
swagger_incorrect.json is valid

This is my file with duplicate keys in definitions (I have stripped down a lot of the file where the issue appeared and even removed the paths using the definition.

{
    "swagger": "2.0",
    "info": {
      "title": "blah",
      "version": "2018-05-07"
    },
    "paths": {
    },
    "definitions": {
      "data-post": {
        "type": "object",
        "properties": {
          "blah": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dup_prop": {
                  "type": "string"
                },
                "dup_prop": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }

Loading this in swagger-ui gives me the error (can add screenshot if needed):

Errors
 
Parser error on line 23
duplicated mapping key

According to my understanding/reading of the OpenAPI / Swagger specification this is indeed invalid.
Let me know if more information is needed.

Allow `parameters` to be null

Some of our API methods take no parameters, and we used to have this as:

parameters:

in a YAML file. After using swagger-cli to validate we were forced to write this:

parameters: []

Is this mandatory or this a tool specific behaviour? If the latter, can it be changed to be a bit more permissive?

Console exit status is 0 on error

I'm integrating swagger-cli into a custom build script for our application. The problem that I've run into is that our build fails if any of the commands it runs returns a non-zero exist status. However, when swagger-cli finds an error in the swagger spec file, it still sets a 0 exit status, which doesn't fail our build. By convention, all command line scripts return 0 on success and non-zero on error so that shell scripts which invoke them can determine if they completed successfully or not. I would ask that you add support for this convention as it would make it considerably more useful from the command line.

For the time being, I've implemented an ugly ugly hack where I capture the complete output of the command and fail the build if the output of the validator contains the word "error".

incorrect line numbers reported by validator when dupes are found

Given the following yml:

swagger: '2.0'

definitions:
  Delivery:
    properties:
      deliveryId:
        type: string

  FeedbackMessage:
    properties:
      consumerEmail:
        type: string
      feedbackMessage:
        type: string

  Delivery:
    properties:
      deliveryId:
        type: string

validator will give incorrect line number for found duplicate entries:

~/tt$ swagger validate test.yaml 
SyntaxError: Error parsing "/home/d/tt/test.yaml" 
duplicated mapping key at line 20, column 1:

    ^
    at Function.ono [as syntax] (/usr/lib/node_modules/swagger-cli/node_modules/ono/lib/index.js:67:20)
    at parse (/usr/lib/node_modules/swagger-cli/node_modules/json-schema-ref-parser/lib/parse.js:47:17)
    at /usr/lib/node_modules/swagger-cli/node_modules/json-schema-ref-parser/lib/read.js:70:23
    at lib$es6$promise$$internal$$tryCatch (/usr/lib/node_modules/swagger-cli/node_modules/es6-promise/dist/es6-promise.js:326:16)
    at lib$es6$promise$$internal$$invokeCallback (/usr/lib/node_modules/swagger-cli/node_modules/es6-promise/dist/es6-promise.js:338:17)
    at lib$es6$promise$$internal$$publish (/usr/lib/node_modules/swagger-cli/node_modules/es6-promise/dist/es6-promise.js:309:11)
    at lib$es6$promise$asap$$flush (/usr/lib/node_modules/swagger-cli/node_modules/es6-promise/dist/es6-promise.js:120:9)
    at process._tickCallback (node.js:415:13) 

YAMLException: duplicated mapping key at line 20, column 1:

    ^
    at generateError (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:162:10)
    at throwError (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:168:9)
    at storeMappingPair (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:305:7)
    at readBlockMapping (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1065:9)
    at composeNode (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1326:12)
    at readBlockMapping (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1056:11)
    at composeNode (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1326:12)
    at readDocument (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1488:3)
    at loadDocuments (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1544:5)
    at load (/usr/lib/node_modules/swagger-cli/node_modules/js-yaml/lib/js-yaml/loader.js:1561:19)

Validate does not detect missing field in required

Running with the validate command does not detect the case where the required field for a schema refers to a field that does not exist.

I had a model that looked like this.

components:
   schemas:
      Audit:
         properties:
             createDate:
                 type: string
         required: [ createDate ]

The schema was valid. I then changed the name of a property but forgot to rename the field in the required list and it validated successfully anyway.

components:
   schemas:
      Audit:
         properties:
             createDateTime:
                 type: string
         required: [ createDate ]

Token does not exist error

swagger-cli validate (v4.0.4) is reporting

Token "Resource" does not exist.

I'm not sure why.

Our OpenAPI 3.0.3 document is very long; I think the relevant sections are

...
  "components": {
    "schemas": {
      "Foo": {
        "title": "Foo",
        "description": "A foo.",
        "type": "object",
        "properties": {
          "entry": {
            "description": "An entry.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "resource": {
                  "description": "The Resource for the entry.",
                  "$ref": "https://hl7.org/fhir/R4/fhir.schema.json#/definitions/Resource"
                },
...

Is an external URL $ref not supported, or is there something I'm doing wrong?

The error message doesn't include a line number, so it's difficult to be sure.

Thank you!

Cannot bundle top-level $ref

Hi,

it looks like swagger-cli cannot bundle a top-level $ref even if it points to a valid Swagger file:

$ swagger validate http://petstore.swagger.io/v2/swagger.json
http://petstore.swagger.io/v2/swagger.json is valid
$ cat test.yaml
$ref: http://petstore.swagger.io/v2/swagger.json
$ swagger bundle test.yaml
SyntaxError: test.yaml is not a valid Swagger API definition
    at Function.ono [as syntax] (...\npm\node_modules\swagger-cli\node_modules\ono\lib\index.js:61:20)
    at ...\npm\node_modules\swagger-cli\node_modules\swagger-parser\lib\index.js:75:19

Thanks and keep up the good work 👍

Feature: find/replace values during bundle

A nice to have feature would be the ability to find and replace values during the bundling process. The one that comes up the most frequently is the application's "host" parameter. E.g. it is handy to replace the given value while working on a dev environment. This could be as lightweight as a command-line option (e.g. --host dev.mysite.com), or it could go as far as to look to environment variables to replace any number of strings.

Community usage and support

Hey @BigstickCarpet, I wanted to say thanks for this publishing this project.

We have been using it for years to validate and bundle dozens of yaml files into our various OpenAPI/Swagger specifications.

It still works great and we would love to see it continue to evolve and support the upcoming specification changes.

I haven't looked since last fall, but I have not found other tools that do quite the same thing.

cc @alexvolsh

Validation against an object

I am creating a client side application to validate the open api contract . How can i do it , it doesn't read file from a url neither it has option to take an object

[chore]: configure pre-commit hook

pre-commit hooks can come in handy while in the Dev workflow. The lint script can be made to execute automatically before making a commit (and staging updated files).

How to bundle OAS documentation from multiple Java projects?

Hi, I have two java projects. One where I define my data transfer object (DTO class), let us call this project solver. And another java project, let us call this solver service, where I define my endpoints and so on. I do contract first and generate code based on documentation, so I guess I have to write documentation for payload (DTO) in solver project and documentation for endpoints in solver service project. But how do I bundle these two files into one OAS documentation?

swagger-cli v2.2.2 loses support for RHEL 5

Probably more as an FYI than an issue that will get fixed (as RHEL 5 has been out production support since 2017 ish)

On all my RHEL/OEL/Centos 5 boxes when using v2.2.2 I get the below error

SwaggerParser.prototype.parse = async function (path, api, options, callback) {
                                      ^^^^^^^^

SyntaxError: Unexpected token function
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:549:28)
    at Object.Module._extensions..js (module.js:586:10)
    at Module.load (module.js:494:32)
    at tryModuleLoad (module.js:453:12)
    at Function.Module._load (module.js:445:3)
    at Module.require (module.js:504:17)
    at require (internal/module.js:20:19)
    at Object.validate (/root/code/swagger-api/myoffers/node_modules/swagger-cli/lib/validate.js:22:23)

If I downgrade to version 2.2.1 it works again for me on all RHEL/OEL/Centos 5 boxes I've tested.
Might also be worth noting that my Centos 7 boxes happily accept v2.2.2

Cheers

Feature: Consider resolving references if they are relative from the main file

So if the main file references a file which in turn references another file the reference should not be from root.

root.yaml, first/ref.yaml, second/ref.yaml

first/ref.yaml can reference schema 'A' as follows:

Reference Resolution Strategy Supported In
'../second/ref.yaml#/components/schemas/A' Relative from file itself js parsers/ json-ref
'./second/ref.yaml#/components/schemas/B' Relative from root file java parser/swagger-parser

Would request considering support both. If not as a feature could there be a simple way to support both

Validate taking a really long time - could be recursion related?

I have a User schema model that references itself with createdByUser/updatedByUser, and pretty much all models have createdByUser/updatedByUser. The validate function works but it's taking longer and longer (over an hour) the bigger my API is getting. I'm suspecting recursion to be the issue. I'm guessing there's a fixed limit to recursion as it doesn't go into an endless loop and eventually passes - where could I take a look at that code I'd like to make it an option variable if possible.

How to bundle paths?

Hi, we have several api specs that we would like to bundle into one spec. We're trying to follow the example from the spec.
In a file all.yaml:

paths:
  /users:
    $ref: '../resources/users.yaml'
  /users/{userId}:
    $ref: '../resources/users-by-id.yaml'

When I then run swagger-cli bundle all.yaml, it inlines the other yaml files 1:1 (starting with the line openapi: 3.0.0). Other things we tried:

  • use $ref: '../resources/users.yaml#/paths --> inlines paths, but nested under /users
  • modify the users.yaml to only contain a list of paths --> similar output as previous

How can we correctly bundle all paths?
Note that bundling schemas/models works though. It's just paths that don't work

[Question] External reference with https://xxx/common.yaml

I have a schema file test.yaml with an external reference with https://xxx/common.yaml
And I could use curl or web browser to directly access https://xxx/common.yaml.
However, when I tried to use swagger-cli to validate the test.yaml, it shows me

Error downloading https://xxx/common.yaml
unable to verify the first certificate

Is there a way for swagger-cli to specify the certificate? So it could download the external schema successfully?

Validate null value in enums

Incorrect YAML

EnumObject:
  type: string
  enum:
    - NULL
    - ITEM1
    - ITEM2

Correct YAML

EnumObject:
  type: string
  enum:
    - 'NULL'
    - ITEM1
    - ITEM2

Issue: There are warnings if using the incorrect YAML in SwaggerHub, but swagger-cli said the document is valid.

Warnings from SwaggerHub: enum value should conform to its schema's type

Expect result: Same warning as SwaggerHub.

Does swagger-cli work as wrapper?

I read changelog.

The "swagger-cli" NPM package is now just a wrapper around the scoped "@apidevtools/swagger-cli" package

But I cannot install swagger-cli by npm install swagger-cli.
I got 404.

Is this right?

swagger serve

Hi @BigstickCarpet,
Thanks for this great project. I just wanted to ask if you know roughly when swagger serve might become available for use?

Thanks a lot,

Jamie

Examples (plural form) are not allowed, contrary to what the JSON schema spec says

In the JSON schema spec, it says that to annotate an instance with examples, we can use the "examples" property which must be an array https://json-schema.org/latest/json-schema-validation.html#rfc.section.10.4

However, validating a simple OpenAPI 3 document like this one:

openapi: 3.0.0
info:
  description: Foobar
  version: "1.0.0"
  title: Foobar
paths:
  '/foobar':
    get:
      responses:
        '200':
          description: this is a description
          content:
            application/json:
              schema:
                type: string
                examples: ["aaaa"]

fails with:

Swagger schema validation failed. 
  Data does not match any schemas from 'oneOf' at #/paths//foobar/get/responses/200
    Data does not match any schemas from 'oneOf' at #/paths//foobar/get/responses/200/content/application/json/schema                                                                                           
      Additional properties not allowed: examples at #/content/application/json/schema
      Missing required property: $ref at #/content/application/json/schema
    Missing required property: $ref at #/paths//foobar/get/responses/200
 
JSON_OBJECT_VALIDATION_FAILED

Keep in mind that I'm not talking about the OpenAPI 3 spec itself, but about the description of inputs and outputs of endpoints using JSON schema.

Replacing examples: ["aaaa"] with example: "aaaa" makes it work, but then the output description is not a valid JSON schema and other tools that respect the spec fail to interpret it.

I realize that this might not be the best place to report this problem. If that's the case, can somebody redirect me to the correct repo? Thanks!

Can't not bundle in Travis CI

I try to bundle doc in travis but it's not success, Seems, it was a js error
Note, build folder existed

This is error

$ swagger-cli bundle -o build/swagger.bundle.yaml -t yaml swagger.yaml
Cannot read property 'mkdir' of undefined

This is .travis.yml

language: node_js

node_js:
  - 8

before_install:
  - npm install swagger-cli
  - export PATH=$(npm bin):$PATH

script:
  - swagger-cli validate swagger.yaml

after_success:
  - swagger-cli bundle -o build/swagger.bundle.yaml -t yaml swagger.yaml

deploy:
  provider: pages
  skip_cleanup: true
  github_token: $GH_TOKEN
  local_dir: build
  on:
    branch: master

"404: '@apidevtools/swagger-cli@latest' is not in the npm registry" when installing package

I don't know what really went wrong but npm seems unable to find the swagger-cli package in the registry. This is the error log I get when I run npm install -g @apidevtools/swagger-cli

npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@apidevtools%2fswagger-cli - Not found
npm ERR! 404
npm ERR! 404  '@apidevtools/swagger-cli@latest' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/idoko/.npm/_logs/2020-08-06T09_12_34_106Z-debug.log

And it happens both on my dev machine and Github Actions.

Feature Request: Adding the ability to include multiple api files to the command arguments

Hi, currently the validate command can only validate one file. I currently work on a project that has multiple files I want to validate all of them. I could create a bash script that runs this command multiple times, but I think something like this would be awesome:

swagger-cli validate file1.yml file2.yml ... file3.yml

Not sure if this is feasible for the project, so feel free to give me feedback. I am willing to make a pull request to implement this.

Bundle command broken on version 3.0.0

Hello guys!

At @Moovone we use swagger-cli (very useful) in a Docker container context, with the following simplest configuration:

FROM node:8.9-alpine

RUN npm install -g swagger-cli

ENTRYPOINT ["swagger-cli"]

So every time you post a new version, we retest our swagger spec with it, and this time we found that something not worked correctly!

Command execution
This image illustrate how we use swagger-cli

With the new version 3.0.0 a new error has appeared Cannot read property 'mkdir' of undefined

Do you now why? We didn't change anything on our side

Flag for skipping OpenAPI Extensions

Hi.

I am using some OpenAPI extensions prefixed with x- and I am getting error, when validating swagger yaml:

Swagger schema validation failed.
  Additional properties not allowed: operationOd at #/paths//auth-admin/login/post

JSON_OBJECT_VALIDATION_FAILED

Best regards.

more helpful output?

Is there a way to produce more helpful output from the validate command? When I run it against my swagger configuration, this output . . .

Data does not match any schemas from 'oneOf' at #/parameters/RequestID
  Missing required property: schema at #/parameters/RequestID
  Data does not match any schemas from 'oneOf' at #/parameters/RequestID
    Additional properties not allowed: example at #/
    Additional properties not allowed: example at #/
    Additional properties not allowed: example at #/
    Missing required property: required at #/

. . . is pretty cryptic. Apparently, all of those messages are just to tell me that I have included an invalid field example in the RequestId parameter definition. Is there some way to parse this to convey that more clearly? Thanks!

Error resolving token when using dereference flag

Thanks for your work on this library.

I'm running into a weird issue.

Here's my setup:

index.yaml

swagger: '2.0'

info:
  version: "1.0.0"
  title: "Test"
paths:
  /apiversion:
    get:
      tags:
        - Version
      security: []
      description: |
        This is a dedicated endpoint for determining the API version the unit adheres to.

        * This endpoint will always exist.
        * This endpoint will not require authentication.
      responses:
        200:
          description: Successful response
          schema:
            $ref: '#/definitions/ApiVersionInfo'
  $ref: 'separate.yaml#/paths'
definitions:
  ApiVersionInfo:
    type: object
    properties:
      apiVersion:
        type: string

separate.yaml

paths:
  /test:
    get:
      description: |
        Test Edpoint
      summary: |
        Test Edpoint
      responses:
        200:
          description: Successful response
          schema:
            $ref: '#/definitions/TestEndpointGet'
definitions:
  TestEndpointGet:
    type: object
    properties:
      test:
        type: integer

When I run the following command it appears to generate the correct file:
npx swagger-cli bundle -t yaml -o test.yaml index.yaml

But when I add the dereference flag:
npx swagger-cli bundle -t yaml -o test.yaml -r index.yaml

I get the following output:

Error resolving $ref pointer "...separate.yaml#/definitions/ApiVersionInfo". 
Token "ApiVersionInfo" does not exist.

package.json missing build script

Per Contributing section of README.md npm run build, build is not present in package.json:

scripts": {
    "lint": "eslint bin lib test --fix",
    "test": "mocha && npm run lint",
    "upgrade": "npm-check -u",
    "bump": "bump --prompt --tag --push --all",
    "release": "npm run upgrade && npm test && npm run bump && npm publish"
  }

Possible mismatch of desired command in README?

External references are not all resolved before local references

Hi guys, thanks for your great work on this project.

I noticed that a scenario such as the one shown here fails as this CLI seems to resolve references top to bottom rather than resolving external file references first and then local references second.

fots ~ > test $ tree
.
├── definitions
│   ├── User.yaml
│   └── index.yaml
├── index.yaml
├── info
│   └── index.yaml
└── paths
    ├── bar.yaml
    ├── foo.yaml
    └── index.yaml

3 directories, 7 files
fots ~ > test $ swagger-cli validate index.yaml 
Error resolving $ref pointer "/Users/fots/test/paths/bar.yaml#/definitions/User". 
Token "definitions" does not exist.

The reason this happens is that once the CLI reaches the bar path, it sees:

get:
  responses:
    200:
      description: OK
      schema:
        $ref: '#/definitions/User'

And it attempts to resolve local ref #/definitions/User' prior to referencing the external definition files.

Any help would be greatly appreciated 😄
Fotis

swagger-cli bundle -t yaml results in invalid example.

When bundling a spec that has references to examples in json files some numbers that should appear as string are written as number.

fi.
the spec

                      properties:
                        branchCode:
                          maxLength: 11
                          type: string
                          description: 'Code to identify a branch, e.g. ABA or BIC'

my example json

{
   "branchCode": "0123456789"
}

the example in the bundled yaml

   brancheCode: 0123456789

Current workaround, bundle as json, convert to yaml using yamljs v0.3.0

swagger-cli bundle -t json -o openapi.json
json2yaml -s -d 99 openapi.json

Should `bundle` run `validate` first?

I've been working with OpenAPI 3 for the last couple of months, and swagger-cli is an important part of our toolchain.

Our toolchain (like several I've seen) currently runs validate first, followed by a status check, then a bundle if the validate was OK.

bundle currently works fine against a lot of invalid OpenAPI definitions because it doesn't validate first.

To me it would make sense for bundle to also validate, and not attempt to bundle if the file fails validation. I'd also suggest having a --ignore-validation-failures mode too.

It seems wrong to have a tool which produces broken output when provided with a broken input which it already has a way of validating.

I'd love to hear feedback on if this has been thought about / discussed before.

Thanks!

I think a $ref under example should be left untouched during bundling

Per OAI/OpenAPI-Specification#666 (and the spec) you can't use a $ref under an example.

I however did do that (not realizing it wasn't correct) and "it worked". However, when I went to reference my example a second time I ended up with an example that looked like this

image

I could not figure out why it worked the first time and then didn't work the second time.

Well we are using multiple files for our schema and using this tool to bundle everything together. The bundler sees the $ref under example and treats it like any other $ref. The first time it sees the $ref it gets "inlined" and the other instances of $ref to the same file get updated $ref links.

I think the bundler should leave any $ref under an example alone. (unless the tool is attempting to make $ref under an example just "work", in which case more work would be needed at the example sites.)

Note: I wasn't using components, but even when I did update my files to use components correctly, it just makes the problem slightly worse. In this case the reference file gets inlined into components as you'd expect and then every other referencing site ends up with something like the screenshot above.

Circular reference is considered an error

When you have a yaml model that reference itself, the validate function consider it an error, which is not. It is completely supported by tools like swagger-editor and swagger-codegen.

I'm using the latest release on npm (1.0.1).

To reproduce, use the petstore and add this in the definition part:

MenuItemDescription:
  type: string
  description: "List of all menu item descriptions"
  enum:
    - Choice1
    - Choice2
    - Choice3
MenuItem:
  type: object
  description: "Item in a menu"
  required:
    - description
    - childMenuItems
  properties:
    description:
      $ref: "#/definitions/MenuItemDescription"
    childMenuItems:
      type: array
      items:
        $ref: "#/definitions/MenuItem"

The error is as follow:

Swagger schema validation failed.
  Expected type object but found type string at #/definitions/$ref

JSON_OBJECT_VALIDATION_FAILED

Thanks!

Git pre-commit hook integration

It would be very useful to integration the validation functionality with the git pre-commit hook. I am currently working on a Go micro-service project spanning several teams. One such micro-service provides a central API (to the outside world) for all other services. As such, a large API contract is necessary. Given the support of multi-file API definitions, this is the only validation tool I could find that met my requirements.

Validation errors are not useful for larger APIs

I might be missing some option but when I run the validate command on a larger API (2K lines) I only get a single error at a time even though there are multiple errors in the YAML. Additionally it just gives me the error message with line information so I have to find it myself. Example

paths:
   /blah
      post:
         requestBody:
            content:
               application/json:
                  schema:
                     $ref: '#/components/schemas/myData'

components:
   schemas:
      MyData:
         type: string               

Here the error is that the $ref is using camel case name for schema while the schema itself is using Pascal cased. Imagine that this schema name is being used in multiple places and there are several different schema types that have this same problem.

When I run the validate command all I get is this:

Token "myData" does not exist.

To fix this I have to search for all the places it is wrong and fix them. Then I have to run validate again to find that I have done this with other schemas as well.

It would be nice if the validation tool shows me the location in the YAML where the error was detected and it tries to find all errors and doesn't just stop on the first one.

bundling anyOf schema's

When I try to bundle a set of schemas in a path using "anyOf" or "oneOf", the schemas are invalid. Tried adding a unique name for each of the schemas and adding/removing indentation, however this still didn't allow this usage to be bundled in to the flat file. Instead I have re-structured the output bundled file manually and move the schemas under components: schemas: and then manually create the $ref's for each of the schemas. I'm not sure if I added something to the schema file at the beginning, if this would then render correctly perhaps?

Current output when bundled:

paths:
  /workflow/request:
    post:
      summary: Workflow Trigger
      description: Triggers one of the many workflows.
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - retrieve:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Associated asset ID used for tracking or filenames.
                      operation:
                        type: string
                        description: Used to look up variables within the sub workflow.
                    required:
                      - id
                      - operation
                - transfer:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Associated asset ID used for tracking or filenames.
                      operation:
                        type: string
                        description: Used to look up variables within the sub workflow.
                    required:
                      - id
                      - operation
                - list:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Associated asset ID used for tracking or filenames.
                      operation:
                        type: string
                        description: Used to look up variables within the sub workflow.
                    required:
                      - id
                      - operation
                - find:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Associated asset ID used for tracking or filenames.
                      operation:
                        type: string
                        description: Used to look up variables within the sub workflow.
                    required:
                      - id
                      - operation
                - copy:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Associated asset ID used for tracking or filenames.
                      operation:
                        type: string
                        description: Used to look up variables within the sub workflow.
                    required:
                      - id
                      - operation
      responses:
        '200':
          description: OK
  

Working bundle:

/workflow/request:
    post:
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/retrieve"
                - $ref: "#/components/schemas/delete"
                - $ref: "#/components/schemas/create"
                - $ref: "#/components/schemas/transfer"
                - $ref: "#/components/schemas/upload"
                - $ref: "#/components/schemas/list"
                - $ref: "#/components/schemas/find"
                - $ref: "#/components/schemas/difference"
                - $ref: "#/components/schemas/copy"

components:
     schemas:
      retrieve:
        type: object
        properties:
          id:
            type: string
            description: Associated asset ID used for tracking or filenames.
          operation:
            type: string
            description: Used to look up variables within the sub workflow.
        required:
          - id
          - operation
      transfer:
        type: object
        properties:
          id:
            type: string
            description: Associated asset ID used for tracking or filenames.
          operation:
            type: string
            description: Used to look up variables within the sub workflow.
        required:
          - id
          - operation
      list:
        type: object
        properties:
          id:
            type: string
            description: Associated asset ID used for tracking or filenames.
          operation:
            type: string
            description: Used to look up variables within the sub workflow.
        required:
          - id
          - operation
      find:
        type: object
        properties:
          id:
            type: string
            description: Associated asset ID used for tracking or filenames.
          operation:
            type: string
            description: Used to look up variables within the sub workflow.
        required:
          - id
          - operation
      copy:
        type: object
        properties:
          id:
            type: string
            description: Associated asset ID used for tracking or filenames.
          operation:
            type: string
            description: Used to look up variables within the sub workflow.
        required:
          - id
          - operation

Parameter allows $ref to satisfy type

swagger-cli allows $ref in parameters, and does not throw error on missing type if the $ref contains one. The spec seems to leave some room for interpretation, but it does not seem to allow $ref in this context, and on the other hand requires type there.

FWIW https://github.com/zalando/intellij-swagger takes it the other (seemingly more correct IMHO) approach: it requires type and disallows $ref.

I lean towards thinking the approach of swagger-cli is not correct, because in other places in the spec where $ref is ok, it is also explicitly documented.

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object

I think this example should raise two errors for the parameter:

  • missing type
  • $ref not allowed
swagger: '2.0'
info:
  version: 1.0.0
  title: A very simple API

paths:
  /foo:
    get:
      parameters:
        - in: query
          name: bar
          required: false
          $ref: "#/definitions/mytype"
      responses:
        "200":
          description: "OK"

definitions:
  mytype:
    type: string
    maxLength: 1

Bundle: option to keep all refs but turn them into internal refs

The bundle command's current behaviour breaks the code generation in my current project.

Currently, with no special option, the bundle command inlines all $refs it finds on the first encounter, and then makes a reference to that local inline upon any subsequent encounter of the same reference.

For this example input:

main.yaml

swagger: '2.0'
info:
  version: 0.0.0
paths:
  /test1:
    get:
      parameters:
        - $ref: "./parameters.yaml#/parameters/param"
  /test2:
    get:
      parameters:
        - $ref: "./parameters.yaml#/parameters/param"

parameters.yaml

parameters:
  param:
    in: query
    name: myParam
    description: some demo parameter
    type: string
    pattern: '^[a-zA-Z]+$'
    required: true

The output I get from npx swagger-cli bundle main.yaml is the following:

swagger: '2.0'
info:
  version: 0.0.0
paths:
  /test1:
    get:
      parameters:
        - in: query
          name: myParam
          description: some demo parameter
          type: string
          pattern: '^[a-zA-Z]+$'
          required: true
  /test2:
    get:
      parameters:
        - $ref: '#/paths/~1test1/get/parameters/0'

When things get complicated, it can yield references like this:

$ref: '#/paths/~1analytics-ui/post/parameters/3/schema/items/properties/data/properties/page/properties/attributes'

And during code generation, this may turn into class names as long as this path, which is far from ideal.

It would be nice to have an option (e.g. --no-dereference) to preserve any reference, and simply bring the referenced declarations to the bundled file, but in a separate place within the file. This means that every reference will simply become a local declaration, but point to the same path.

Here is the output I would expect using this option on the same sample input that I provided:

bundle.yaml

swagger: '2.0'
info:
  version: 0.0.0
paths:
  /test1:
    get:
      parameters:
        - $ref: "#/parameters/param"
  /test2:
    get:
      parameters:
        - $ref: "#/parameters/param"

parameters:
  param:
    in: query
    name: myParam
    description: some demo parameter
    type: string
    pattern: '^[a-zA-Z]+$'
    required: true

Is there a way to achieve this currently?

Dereferencing caches last used `$ref`

Hey there,

I am experiencing a strange issue when using dereferencing.

Having two files:

foo.yaml

openapi: "3.0.0"
info: {}
paths:
  /foo/bar:
    get:
      responses:
        200:
          description: OK

bar.yaml

openapi: 3.0.0
info: {}
paths:
  /foo/bar:
    get:
      $ref: 'foo.yaml#/paths/~1foo~1bar/get'
      tags:
        - foo
        - bar
      parameters:
        - in: query
          required: true
          name: "foo"
          schema:
            $ref: '#/components/parameters/QueryParameterFoo'

components:
  parameters:
    QueryParameterFoo:
      type: string

When using swagger-cli bundle bar.yaml --dereference, I get the following error:

Error resolving $ref pointer "foo.yaml#/components/parameters/QueryParameterFoo". 
Token "components" does not exist.

The error is correct, the file foo.yaml does not have the parameter QueryParameterFoo within components/parameters, but I've never referenced that 🤷‍♂️

So what I assume is, that the dereferencing somehow thinks, that it has to look within foo.yaml when passing to the next $ref.

I am on v2.3.5 - gonna re-check on v4.

Update

When updating to v4.0.4, the error message is less verbose but ends up with the same problem:
Token "components" does not exist.

Am I using the $ref wrong or is this supposed to be a bug?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.