GithubHelp home page GithubHelp logo

redocly / redocly-cli Goto Github PK

View Code? Open in Web Editor NEW
860.0 27.0 129.0 24.94 MB

⚒️ Redocly CLI makes OpenAPI easy. Lint/validate to any standard, generate beautiful docs, and more.

Home Page: https://redocly.com/docs/cli/

License: MIT License

JavaScript 16.95% TypeScript 82.69% Handlebars 0.09% Dockerfile 0.08% HTML 0.04% PHP 0.01% Shell 0.14%
openapi-cli openapi openapi3 openapi31 redoc redocly api-governance cicd linter swagger2

redocly-cli's Introduction

Redocly CLI

@Redocly CLI is your all-in-one OpenAPI utility. It builds, manages, improves, and quality-checks your OpenAPI descriptions, all of which comes in handy for various phases of the API Lifecycle. Create your own rulesets to make API governance easy, and publish beautiful API reference documentation. Supports OpenAPI 3.1, 3.0 and OpenAPI 2.0 (legacy Swagger).

build and test npm (scoped) NPM

OpenAPI CLI toolset

Usage

Node

npx @redocly/cli lint path-to-root-file.yaml

Alternatively, install it globally with npm:

npm install @redocly/cli -g

Then you can use it as redocly [command] [options], for example:

redocly lint path-to-root-file.yaml

The minimum required versions of Node.js and NPM are 14.19.0 and 7.0.0 respectively.

Docker

To give the Docker container access to the OpenAPI description files, you need to mount the containing directory as a volume. Assuming the API description is rooted in the current working directory, you need the following command:

docker run --rm -v $PWD:/spec redocly/cli lint path-to-root-file.yaml

To build and run with a local image, run the following from the project root:

docker build -t redocly/cli .
docker run --rm -v $PWD:/spec redocly/cli lint path-to-root-file.yaml

Common tasks

Generate API reference documentation

Redocly CLI is a great way to render API reference documentation. It uses open source Redoc to build your documentation. Use a command like this:

redocly build-docs openapi.yaml

Your API reference docs are in redoc-static.html by default. You can customize this in many ways. Read the main docs for more information.

💡 Redocly also has hosted API reference docs, a (commercial) alternative to Redoc. Both Redoc and Redocly API reference docs can be worked on locally using the preview-docs command.

Bundle multiple OpenAPI documents

Having one massive OpenAPI description can be annoying, so most people split them up into multiple documents via $ref, only to later find out some tools don't support $ref or don't support multiple documents. Redocly CLI to the rescue! It has a bundle command you can use to recombine all of those documents back into one single document. The bundled output that Redocly CLI provides is clean, tidy, and looks like a human made it.

Automate API guidelines with Linting

Check that your API matches the expected API guidelines by using the lint command. API guidelines are an important piece of API governance. They help to keep APIs consistent by enforcing the same standards and naming conventions, and they can also guide API teams through potential security hazards and other pitfalls. Automating API guidelines means you can keep APIs consistent and secure throughout their lifecycle. Even better, you can shape the design of the API before it even exists by combining API linting with a design-first API workflow.

Our API linter is designed for speed on even large documents, and it's easy to run locally, in CI, or anywhere you need it. It's also designed for humans, with meaningful error messages to help you get your API right every time.

Try it like this:

redocly lint openapi.yaml

Configure the rules as you wish. Other API Linters use complicated identifiers like JSONPath, but Redocly makes life easy with simple expressions that understand the OpenAPI structure. You can either use the built-in rules to mix-and-match your ideal API guidelines, or break out the tools to build your own.

Format the output in whatever way you need. The stylish output is as good as it sounds, but if you need JSON or Checkstyle outputs to integrate with other tools, the lint command can output those too.

Multiple files supported so you don't need to bundle your API description to lint it; just point Redocly CLI at the "entry point" (e.g.: openapi.yaml) and it handles the rest.

Learn more about API standards and configuring Redocly rules.

Transform an OpenAPI description

If your OpenAPI description isn't everything you hoped it would be, enhance it with the Redocly decorators feature. This allows you to:

  • Publish reference docs with a subset of endpoints for public use
  • Improve the docs by adding examples and descriptions
  • Adapt an existing OpenAPI description, and replace details like URLs for use on staging platforms

Data collection

This tool collects data to help Redocly improve our products and services. You can opt out by setting the REDOCLY_TELEMETRY environment variable to off.

More resources

Read the detailed docs.

Credits

Thanks to graphql-js and eslint for inspiration of the API description traversal approach and to Swagger, Spectral, and OAS-Kit for inspiring the recommended ruleset.

Development

Contributions are welcome! All the information you need is in CONTRIBUTING.md.

redocly-cli's People

Contributors

adamaltman avatar alexvarchuk avatar andrii-tarusin avatar andriyl avatar antonkozachuk avatar bandantonio avatar dependabot[bot] avatar dmitryanansky avatar github-actions[bot] avatar hcloward avatar igorkarpiuk avatar iosypov avatar ivana-isadora avatar jacobator avatar jeremyfiel avatar jodywinter avatar knidarkness avatar leocete avatar lornajane avatar malis42 avatar marshevskyy avatar ohorbachevskyi avatar oprysk avatar roman-sainchuk avatar romanhotsiy avatar slavikbez avatar smoliyy avatar tatomyr avatar volodymyr-rutskyi avatar yarokon avatar

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redocly-cli's Issues

[Feature] ability to skip the given endpoints when bundling (preferably by regex)

It'd be great to be able to (automatically) skip endpoints considered private when bundling for i.e. public APIs

Let's say there are /status or /healthcheck endpoints used by monitoring tools and they are not really important from the API docs' standpoint.

On the other hand they might be quite important, so having one OpenAPI definition one could generate two bundles:

  • one for the public docs,
  • the other for internal docs (or other scenarios if building more sophisticated setup using the OpenAPI definition as a single source of truth)

Even better if this could be part of the .redocly.yaml file specified as regex rule(s)

throw new Error("Can't load yaml file");

I can certainly understand from this error message that the openapi-cli tool doesn't like something in my YAML file, but it would help a whole lot if it gave me some additional clue about what the problem is. Here is the entire error message:

    throw new Error("Can't load yaml file");
    ^

Error: Can't load yaml file
    at bundleToFile (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/dist/bundle.js:32:11)
    at /Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/dist/cli/index.js:70:55
    at Array.forEach (<anonymous>)
    at Command.<anonymous> (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/dist/cli/index.js:67:17)
    at Command.listener (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/node_modules/commander/index.js:291:8)
    at Command.emit (events.js:200:13)
    at Command.parseArgs (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/node_modules/commander/index.js:672:12)
    at Command.parse (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/node_modules/commander/index.js:459:21)
    at cli (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/dist/cli/index.js:112:22)
    at Object.<anonymous> (/Users/v139708/.nvm/versions/node/v12.4.0/lib/node_modules/@redocly/openapi-cli/dist/index.js:45:20)

After getting this error, all I can do is guess as to what the problem is. My input YAML file (attached as a text file) is a bunch of $ref lines and some comments and not much more.

Rewrite the core engine using typescript

We should rewrite openapi-cli with these considerations:

  1. Use typescript (because it is consistent with our other projects and it is less error-prone).
  2. Have a robust test suite.
  3. Maintain same or better than current performance.
  4. Improve and document the custom rules API.

Internal loader error in latest npm install

version used: @redocly/[email protected]
npm version: [email protected]
Installation method: npm install -g @redocly/openapi-cli [as per README]

Error during validate:

$ openapi validate openapi.yaml 

internal/modules/cjs/loader.js:1033
  throw err;
  ^

Error: Cannot find module 'outdent'
Require stack:
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/redocly/index.js
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/common/registry-dependencies.js
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/oas3/index.js
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/builtin.js
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/config/config.js
- /usr/local/lib/node_modules/@redocly/openapi-cli/lib/cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1030:15)
    at Function.Module._load (internal/modules/cjs/loader.js:899:27)
    at Module.require (internal/modules/cjs/loader.js:1090:19)
    at require (internal/modules/cjs/helpers.js:75:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/@redocly/openapi-cli/lib/redocly/index.js:18:19)
    at Module._compile (internal/modules/cjs/loader.js:1201:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1221:10)
    at Module.load (internal/modules/cjs/loader.js:1050:32)
    at Function.Module._load (internal/modules/cjs/loader.js:938:14)
    at Module.require (internal/modules/cjs/loader.js:1090:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/redocly/index.js',
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/common/registry-dependencies.js',
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/oas3/index.js',
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/rules/builtin.js',
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/config/config.js',
    '/usr/local/lib/node_modules/@redocly/openapi-cli/lib/cli.js'
  ]
}

Could you please suggest a workaround or fix this ASAP??

External references to schemas do not count towards schema being in use

Not entirely sure if this is a bug or a quirk in the specification but, when referencing a schema from an external file that has been "sourced" by another ref, that schema is still classified as being unused, i.e. no-unused-schemas

The schema has been and can be successfully resolved since removing that schema definition causes a resolve-ref error

It feels as if no-unused-schemas is only checking for local uses.

(running swagger-cli validate on the same structure causes no errors, but I prefer the output of openapi over swagger-cli)

Example where the reference to index.yaml#/components/schemas/Test from TestPath.yaml can be resolved but the schema is still not classified as "in-use" by the validator :

index.yaml:

openapi: 3.0.0
info:
  title: 'API'
  version: 1.0.0
  contact:
    name: 'Contact Name'
    email: '[email protected]'
  license:
    name: 'MIT License'
    url: 'https://opensource.org/licenses/MIT'
servers:
  -
    url: 'http://localhost:3000'
paths:
  '/test':
    $ref: './TestPath.yaml'
components:
  schemas:
    Test:
      $ref: './Test.yaml'

Test.yaml:

properties:
  id:
    type: string
    format: uuid

TestPath.yaml:

get:
  summary: 'Test'
  description: 'Test'
  operationId: getTest
  responses:
    '200':
      description: 'Successfully fetched test'
      content:
        application/json:
          schema:
            $ref: './index.yaml#/components/schemas/Test'

docs: linting section

Thanks for this very cool tool 🎉

I am trying to set up custom linting rules and I found it a bit confusing, and I would like to provide feedback on the docs.

About the string-matcher property:

  • It does not seem to be published on https://docs.redoc.ly
  • I did not understand where to find the possible values for the on field, or how to compose the value.

On the website:

  • The https://docs.redoc.ly/cli/configuration/reference-docs/index.md link leads to a 404.

I'd be happy to send out a PR to update once we get answers here 🙂

Redocly API reference docs preview watermark blocks search input field

When using https://github.com/Redocly/openapi-cli to login to redoc.ly using an API key so that the preview server has access to paid features, the Redocly API reference docs preview watermark blocks a user from clicking into the search box on the top left.

Steps To Reproduce

  1. login to redocly: openapi registry:login <YOUR_API_KEY>
  2. start a preview server: openapi preview-docs
  3. Open preview in browser
  4. Note that Redocly API reference docs preview watermark is in upper right hand corner
    image
  5. Attempt to click into Search input field
  6. Note that you can't.

My current janky hack to remove the watermark so that the search works in preview

  1. Hide the watermark after redocly loads
    setTimeout(function(){
        [].slice.call(document.querySelectorAll("a"))
            .filter(a => a.textContent.match("Redocly API reference docs"))
            .forEach(a => {
                a.parentElement.style.display = 'none'
            })
    }, 2000);

The encoding object should map properties

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#media-type-object

encoding Map[string, Encoding Object] A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded.

However, I have an example where the encoding object is used properly and I receive an error complaining that the property's key is not allowed in that object.

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#encoding-object-example

From my own example, it was defining the encoding for a property in the schema.

The field 'file' is not allowed in OpenAPIEncoding. Use "x-" prefix or custom types to override this behavior.

Did you mean: style ?

Error was generated by no-extra-fields rule.

Here is a simplified version of that definition:

required: true
content:
  multipart/form-data:
    schema:
      type: object
      required:
        - file
        - type
      properties:
          type: 
            type: string
            enum:
              - foo
          file:
            type: string
            format: binary
    encoding:
      file:
        contentType: image/gif, image/jpg, image/jpeg, image/png, image/bmp, image/tiff, application/pdf, image/heic

Unable to reference by API definition alias with preview-docs

These work:

openapi preview-docs openapi/core.yaml

openapi validate core

This does not work:

openapi preview-docs core

.redocly.yaml file contents start:

apiDefinitions:
  core: openapi/core.yaml

Version 0.11.0.

Here is the output when. I try openapi preview-docs core

openapi preview-docs core

  🔎  Preview server running at http://127.0.0.1:8080

Bundling...

(node:22124) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'core'
    at Object.openSync (fs.js:462:3)
    at Object.readFileSync (fs.js:364:35)
    at bundle (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/bundle.js:59:27)
    at updateBundle (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/cli/index.js:180:36)
    at Immediate.<anonymous> (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/cli/index.js:202:22)
    at processImmediate (internal/timers.js:456:21)
(node:22124) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:22124) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

  👀  Watching core and all related resources for changes
GET /: 100.058ms
GET /hot.js: 3.156ms
GET /simplewebsocket.min.js: 10.634ms
(node:22124) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 2)
(node:22124) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'core'
    at Object.openSync (fs.js:462:3)
    at Object.readFileSync (fs.js:364:35)
    at bundle (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/bundle.js:59:27)
    at updateBundle (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/cli/index.js:180:36)
    at Immediate.<anonymous> (/Users/adam/.config/yarn/global/node_modules/@redocly/openapi-cli/dist/cli/index.js:202:22)
    at processImmediate (internal/timers.js:456:21)
(node:22124) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
GET /favicon.ico: 1.058ms

Reproduce here: https://github.com/Rebilly/api-definitions (public repo)

preview-docs command does not read entrypoint from config file

Since version 1.0.0-beta.1, it seems that the preview-docs command does no longer attempt to check the configuration file (.redocly.yaml) for where the specification is located.
That means that the entrypoint parameter for the command is now required, even if the configuration file exists and has a path to the specification defined in the apiDefinitions sections.

In the older versions (0.x.x), the command used to check the config file and use the path from there if it exists, so specifying the entrypoint parameter was then not needed.
It's also now inconsistent with the other commands (lint and bundle), since these do use the path from the config file.

Use custom config file when bundling

At the moment openapi bundle always uses .redocly.yaml as configuration source while openapi validate allows users to use custom config file via --config option. Would it be possible to add --config option to bundle operation as well?

For example use case imagine that you want to build API Gateway from bundled output, but you also want to host bundled output as HTML documentation. The spec defines security properties which you want to be visible in your HTML documentation, but you don't want them in the spec uploaded to API Gateway because you don't want to use API Gateway's security model.

The security property can be stripped out of the output via a transformer, but you would like to apply that transformer only when bundling for API Gateway. This would be possible if bundle supported custom config files.

Workaround

One workaround for this that I can imagine of is to put your custom .redocly.yaml into a folder, e.g. api-gateway/.redocly.yaml and then running openapi bundle from there. But as described above that validate already supports custom configs, I think it would be reasonable that bundle would do that as well.

openapi-cli validate just crashes during validation

$ npx @redocly/openapi-cli validate https://raw.githubusercontent.com/Ark-kun/pipelines/ba5aede77e5745922a714ec60920dc504197a8b3/sdk/python/kfp/components/structures/components.json_schema.json
npx: installed 73 in 5.813s
Will validate from URL
(node:249586) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'path' of undefined
    at Object.onEnter (/usr/local/home/foo/.npm/_npx/249586/lib/node_modules/@redocly/openapi-cli/dist/visitors/rules/structural/noRefSiblings.js:25:35)
    at runRuleOnRuleset (/usr/local/home/foo/.npm/_npx/249586/lib/node_modules/@redocly/openapi-cli/dist/traverse.js:166:137)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:249586) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:249586) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Incorrect duplicate path parameters detected

From the OpenAPI spec:

A list of parameters that are applicable for this operation. If a parameter is already defined at the Path Item, the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters.
--

It says: "The list MUST NOT include duplicated parameters."

However, right before that it says: "If a parameter is already defined at the Path Item, the new definition will override it but can never remove it."

So I gather something like this should be okay:

parameters:
  - name: adam
     in: path
     required: true
     description: Version A description
     schema:
       type: string

post:
  operationId: myExample
  parameters:
    - name: adam
       in: path
       required: true
       description: Version B description
       schema:
         type: string
# etc....
get:
# etc...

Confused about "Reference does not exist" errors when using bundle option

My root file uses $ref to include all of the various OAS components, like this:

components:
  schemas: 
    $ref: ./schemas.yaml
  parameters:
    $ref: ./parameters.yaml
  securitySchemes: 
    $ref: ./securitySchemes.yaml
  responses:
    $ref: ./responses.yaml
  requestBodies:
    $ref: ./requestBodies.yaml
  examples: 
    $ref: ./examples.yaml

When I run openapi to bundle the files into a single file, it complains about unresolved references, like this:

[1] NetSense_API_v3.yaml:1029:11 at #/paths/['/login']/get/responses/default/$ref
Reference does not exist.

1027|                 $ref: '#/components/schemas/UserAuthorization'
1028|         default:
1029|           $ref: '#/components/responses/400-ErrorResponse2'
1030| 
1031|   /logout:
1032|     get:

Error was generated by resolve-ref rule.

In this case, 400-ErrorResponse2 DOES exist in the responses.yaml file, so if openapi bundled the files together, the reference would be valid.

Am I doing something wrong? The equivalent commands in speccy and swagger-cli both work fine.

(v0.12.16) Validation failing with operation-2xx-response incorrectly

Given the below YAML the command npx openapi validate src/test/openapi.yaml throws this warning:

[1] src/test/openapi.yaml:8:3 at #/components/responses
Operation must have at least one 2xx response.
---
openapi: 3.0.3
info:
  title: Testing API
  version: 1.0.0

components:
  responses:
    RPCSuccessMessage:
      description: Halo whirl'd.
      content:
        application/json:
          schema:
            type: object

paths:
  /:
    post:
      operationId: successfulJsonResponse
      responses:
        200:
          $ref: "#/components/responses/RPCSuccessMessage"
      tags:
        - Testing

tags:
  - name: Testing

From my reading of the OpenAPI spec,

  • #/components is a Components Object
  • #/components/responses is a Map[string, Response Object | Reference Object]

The warning makes it seem like #/components/responses is being treated as a Responses Object instead of as the correct Map[string, Response Object | Reference Object].

Illegal operation on a directory

If someone accidentally made a $ref that points to a directory instead of a file, it will result in an unfriendly error.

(node:30324) UnhandledPromiseRejectionWarning: Error: EISDIR: illegal operation on a directory, read
    at Object.readSync (fs.js:564:3)
    at tryReadSync (fs.js:353:20)
    at Object.readFileSync (fs.js:390:19)
    at resolve (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/resolver.js:88:28)
    at resolveNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/resolver.js:231:28)
    at onNodeEnter (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:92:35)
    at traverseNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:112:29)
    at traverseChildren (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:49:33)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async traverseNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:140:30)
(node:30324) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:30324) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

htmlTemplate option in .redocly.yaml file is ignored when using "preview-docs"

Hi, when trying to insert some images into rendered preview I found out that htmlTemlate parameter can't be passed nether through .redocly.yaml nor command line parameters:

https://github.com/Redocly/openapi-cli/blob/989d6e3b6ccbba2d6779e544abc1780cc6df14ad/src/cli/index.js#L223-L229

( htmlTemplate parameter is never passed to startPreviewServer call )

Thus when I insert image link into a description, preview server tries to find it inside node_modules/@redocly/openapi-cli/dist/preview-docs/ instead of a folder where my custom html template is located.

My question is: what is a correct way to insert images into locally rendered preview? Thank you.

Bundling mutliple spec files at once (microservices)

Hi, first of all, awesome job on putting this together. It's really quite useful and interesting.

In your documentation you state: "You can bundle your OpenAPI 3 definition into a single file (this may be important for certain tools that lack multifile support)."

What I'm wondering about specifically is support for bundling multiple files. If you're developing in the cloud native paradigm, then having multiple (micro)services is the default. In this scenario, it would be really useful to have

  1. Some way to support multiple files. I'm thinking the ability to input a folder path of spec files (already with the right name): e.g. openapi bundlemany --output <output/path> <input/path> would be a convenient way here.
  2. Assuming step 1 is handled somehow, it would be great if it was added to the documentation section so that people in the future will have easy and convenient access to it.

Thank you guys so much for developing this. Hope this is somewhat useful.

Bad validation for examples

I'm creating examples as shown here.

components:
  ...
  examples:
    Markets:
      usd:
        eur: true
        btc: true
        xrp: true
        ltc: true
      btc:
        usd: true
        eur: true
        xrp: true
        ltc: true
  ...

Then I'm running npx @redocly/openapi-cli validate spec.yml and got error:

image

Output fewer newlines when validation is successful

⚠️ Very minor issue alert! ⚠️

The output below has a lot of extra newlines. I can see why those newlines would be helpful in cases where there are many errors per schema, but when there are no errors it looks a bit spacious:

> openapi validate openapi/*.yml



openapi/api.github.com.yml results. Errors: 0, warnings: 0
    

openapi/ghe-2.15.yml results. Errors: 0, warnings: 0


openapi/ghe-2.16.yml results. Errors: 0, warnings: 0


openapi/ghe-2.17.yml results. Errors: 0, warnings: 0


openapi/ghe-2.18.yml results. Errors: 0, warnings: 0
Total results. Errors: 0, warnings: 0

Identically named rules get overwritten.

If a user accidentally gives a custom rule a name that already exists then it gets overwritten and never runs. A note in the docs or a warning message would be helpful.

Validation fails with operation-2xx-response on callbacks

Repro steps:

  1. npm install @redocly/openapi-cli
  2. ./node_modules/.bin/openapi validate https://raw.githubusercontent.com/Redocly/redoc/master/demo/openapi.yaml

The output includes the following, even though the subscribe endpoint does define a 201 response:

[6] https:/raw.githubusercontent.com/Redocly/redoc/master/demo/openapi.yaml:493:5 at #/paths/['/store/subscribe']/post
Operation must have at least one 2xx response.

491|           description: Order not found
492|   /store/subscribe:
493|     post:
494|       tags:
495|         - store

Warning was generated by operation-2xx-response rule.

Code snippets in error messages sometimes are too big

Take for example missing version field in the definition like below:

openapi: 3.0.1
info:
  title: Some API
  description: "very long single-line description spanning multiple lines if wrapped. All the newlines are encoded \n directly here ......
# ....

If you validate this file it will produce:

[1] index.yaml:2:1 at #/info/version
The field 'version' must be present on this level.

2| info:
3|   title: Some API
4|   description: "very long single-line description spanning multiple lines if wrapped. All the newlines are encoded \n directly here .....

Description line is not stripped and when wrapped by terminal takes too much vertical space while not being useful.

Additional idea may be to not output the whole level on this level-errors , just a few first fields instead.

Provide a way to enforce file names

Currently, you can only create visitors for a node type. We would like to be able specify a visitor for a file.

An example would be if I would like to enforce that all the schemas in a file need to be in alphabetical order.

Currently, to add rules for a specific file I have to specify a random OpenAPISchema type definition in a rule, check that the context.filePath is in the file that I expect, and then apply my validation rules.

Suggestion to improve the readme description

The description of openapi-cli talks about "bundling" and that the "startingPoint" is the "root document," but it doesn't say anywhere how the multiple files are at all related. I assume that the root file is supposed to have $ref references to other files, but the readme doesn't say that and there is no example shown. An example and just a little more explanation would go a long way on this.

license is not a required property of the info object

The license key is not required in the info object:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields-1

If the license key is present, then the name field is required:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#licenseObject

I received an error about a missing license key.

So, I believe this is wrong: https://github.com/Redocly/openapi-cli/blob/dc803862f13c829f2452c3d17c044bbf438efc62/src/visitors/rules/semantic/licenseRequired.js

I think this should be configurable by the user, if they wish to require that, but it is not required by way of the spec. It feels awkward to have this be the default behavior.

Reference from external reference is broken

When I'm trying to use a reference like

$ref: "https://rebilly.github.io/api-standards/schema/json-schema-draft-04/problem-details/documented-problem.json"

Which contains another

{
    "$ref": "blank-problem.json"
}

The blank-problem.json reference should resolve to https://rebilly.github.io/api-standards/schema/json-schema-draft-04/problem-details/blank-problem.json, but it fails to resolve.
According to debugger XRH is sent with blank-problem.json as url

[Feature] Split / de-bundle OpenAPI spec to directory structure

First thank you for this tool, the multi file notions conforms very well with our API documentation methodology, and the tool seems very well done!

Wondering if there is a thought to add a capability to split an existing spec (single yaml/json file) into this structure.

Two use cases I can see for this:

  1. Existing project looking to move from a single file to multi file structure - this would be a great migration path.
  2. Many teams work with one of the many editors out there which support only the single file method - this would allow a path back from editor work (i.e. bundle->edit->debundle->review->commit)

One thing is that I didn't see in the openapi spec any definition on how a bundle looks like - the spec does say that splitting is OK, but not how. (for example we chose originally to split, and every file had to have the required openapi header info to make the file parsable on it's own.

Cannot access 'watcher' before initialization. error

Trying the latest beta version 1.0.0-beta.2 to preview docs is not working :sadface:

~> npx @redocly/openapi-cli --version
1.0.0-beta.2
~> npx @redocly/openapi-cli preview-docs server/api/api.yaml
Using Redoc community edition.
Login with openapi-cli login or use an enterprise license key to preview with the premium docs.


  🔎  Preview server running at http://127.0.0.1:8080
(node:54683) UnhandledPromiseRejectionWarning: TypeError: Non-string provided as watch path: server/api/api.yaml,
    at unifyPaths (/Users/alifarooq/.npm/_npx/54683/lib/node_modules/@redocly/openapi-cli/node_modules/chokidar/index.js:94:11)
    at FSWatcher.add (/Users/alifarooq/.npm/_npx/54683/lib/node_modules/@redocly/openapi-cli/node_modules/chokidar/index.js:395:15)
    at Object.watch (/Users/alifarooq/.npm/_npx/54683/lib/node_modules/@redocly/openapi-cli/node_modules/chokidar/index.js:936:11)
    at Object.<anonymous> (/Users/alifarooq/.npm/_npx/54683/lib/node_modules/@redocly/openapi-cli/lib/cli/preview-docs.js:72:35)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/alifarooq/.npm/_npx/54683/lib/node_modules/@redocly/openapi-cli/lib/cli/preview-docs.js:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:54683) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:54683) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Bundling...

Something went wrong when processing server/api/api.yaml:

  - Cannot access 'watcher' before initialization.

Version 0.12.16 work fine without any issues.

npx @redocly/[email protected] preview-docs server/api/api.yaml

Schemas only referenced in additionalProperties tags are flagged as unused

Bug with the rule: no-unused-schemas

Schemas that are only referenced within an additionalProperties tag are flagged as being unused.

Steps to reproduce:

  1. Create a schema.
  2. Create only one $ref usage within another schema's additional properties tag.
  3. Try to validate with the no-unused-schemas rule on.

URLs should be able to contain relative references

Currently if a URL does not start with https:// or http:// a validation error is thrown saying:

[1] v1/auth/newcustomer.oas3.yml:72:9 at #/paths/['/auth/newcustomer']/post/externalDocs/url
url must be a valid URL

70|         Must have a valid appToken for the request to be processed.
71|       externalDocs:
72|         url: "./API/flows/NewCustomer-Flow.html"
73|         description: New Customer Message Flow
74|       requestBody:

Error was generated by oas3-schema/external-docs rule.

But it is valid for externalDocs and License URL's to have relative references.
See:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#relativeReferences
https://swagger.io/docs/specification/api-host-and-base-path/

resolve-ref Reference does not exist for paths that contain ~1

If i put ~1 in an external reference, i am getting resolve-ref errors.
The file does exist at the path, and other validators validate against this construct OK.

Reference does not exist.

109| 
110|   /v1/adapter/claim:
111|     $ref: "v1/adapter/claim.oas3.yml#/paths/~1adapter~1claim"

Error was generated by resolve-ref rule.```

Crashing with cannot read property of undefined

I crashed the validate command and received this message: UnhandledPromiseRejectionWarning: TypeError: Cannot read property '122' of undefined at getCodeFrameForLocation.

(node:27337) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '122' of undefined at getCodeFrameForLocation (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/yaml/index.js:108:15) at createYAMLParseError (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/error/index.js:50:48) at resolve (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/resolver.js:93:57) at resolveNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/resolver.js:231:28) at onNodeEnter (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:92:35) at traverseNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:112:29) at traverseChildren (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:49:33) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async traverseNode (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:140:30) at async traverseChildren (/Users/adam/Projects/Rebilly/api-definitions/node_modules/@redocly/openapi-cli/dist/traverse.js:72:24) (node:27337) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2) (node:27337) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I probably violated the OAS3 spec, but I am not sure where... The error doesn't help me pinpoint the issue and actually crashes which prevents the rest of the validation from occurring.

Access my broken definition here: Rebilly/api-definitions#35 (it would be alias "users" and "combined").

no-path-trailing-slash shows error for `/`

[2] issue-145.yaml:17:5 at #/paths/~1

`/` should not have a trailing slash.

15 | paths:
16 |   /:
17 |     post:
   |     ^^^^^
18 |       operationId: successfulJsonResponse
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 … |       < 5 more lines >
24 |
   | ^
25 | tags:
26 |   - name: Testing

Error was generated by the no-path-trailing-slash rule.

Unknown escape sequence when trying to validate yaml file in a directory path

I used create-openapi-repo to create a brand new repo.
Then I ran $ npm start

This tries to validate the openapi/openapi.yaml file and the openapi-cli validate failed to resolve the escape character of the path separator. Is this a Windows issue? How do I solve this?

Thanks!

Env:  On Windows using Git Bash
$ node -v
v12.16.1
$ npm -v
6.14.3

$ openapi validate openapi/openapi.yaml

C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:173
  throw generateError(state, message);
  ^
YAMLException: unknown escape sequence at line 3, column 18:
      main: "openapi\openapi.yaml"
                     ^
    at generateError (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:167:10)
    at throwError (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:173:9)
    at readDoubleQuotedScalar (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:646:9)
    at composeNode (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1365:13)
    at readBlockMapping (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1089:11)
    at composeNode (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1359:12)
    at readBlockMapping (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1089:11)
    at composeNode (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1359:12)
    at readDocument (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1519:3)
    at loadDocuments (C:\Users\qhvu\AppData\Roaming\npm\node_modules\@redocly\openapi-cli\node_modules\js-yaml\lib\js-yaml\loader.js:1575:5) {
  name: 'YAMLException',
  reason: 'unknown escape sequence',
  mark: Mark {
    name: null,
    buffer: '# See https://docs.redoc.ly/cli/configuration/ for more information.\r\n' +
      'apiDefinitions:\r\n' +
      '  main: "openapi\\openapi.yaml"\r\n' +
      'lint:\r\n' +
      '  rules:\r\n' +
      '    no-unused-schemas: warning\r\n' +
      'referenceDocs:\r\n' +
      '  htmlTemplate: ./docs/index.html\r\n' +
      '  theme:\r\n' +
      '    colors:\r\n' +
      '      primary:\r\n' +
      '        main: "#32329f"\n' +
      '\u0000',
    position: 104,
    line: 2,
    column: 17
  },
  message: 'unknown escape sequence at line 3, column 18:\n' +
    '      main: "openapi\\openapi.yaml"\n' +
    '                     ^'
}

[Feature] Specification extensions support for Components Object

As specified in OpenAPI Specification / Components Object - This object MAY be extended with Specification Extensions

I'm having issues with those Specification Extensions, it's always best to use an example to present what is wrong - I have two files and I'm trying to create a bundle using the main file as a root document.

Main OAS3 file (main.openapi.yml):

openapi: 3.0.2
servers:
  - url: 'http://localhost'
    description: server
info:
  version: 1.0.0
  title: Example API
  contact:
    email: [email protected]
  description: Example

tags:
  - name: sample

paths:
  '/sample':
    get:
      operationId: getSample
      summary: Sample
      description: Sample
      tags:
        - sample
      responses:
        '200':
          $ref: './components.openapi.yml#/components/responses/Default200Response'
      x-some:
        $ref: './components.openapi.yml#/components/x-some-ref/whatever'

Components / Responses OAS3 file (components.openapi.yml):

openapi: 3.0.2
servers:
  - url: 'http://localhost'
    description: server
info:
  version: 0.0.1
  title: Components fragment
  contact:
    email: [email protected]
  description: Components fragment

tags:
  - name: specExt

paths: {}

components:
  responses:
    Default200Response:
      description: Sample
  x-some-ref:
    whatever:
      key: value

When I'm creating a bundle with:

openapi bundle --output bundled.openapi.yml --ext yml main.openapi.yml

it parses perfectly the OAS3 fixed fields like components/responses references but fails parsing specification extensions (x-some-ref) references - it is just copied as-is.

The output file (bundled.openapi.yml):

openapi: 3.0.2
servers:
  - url: 'http://localhost'
    description: server
info:
  version: 1.0.0
  title: Example API
  contact:
    email: [email protected]
  description: Example
tags:
  - name: sample
paths:
  /sample:
    get:
      operationId: getSample
      summary: Sample
      description: Sample
      tags:
        - sample
      responses:
        '200':
          $ref: '#/components/responses/Default200Response'
      x-some:
        $ref: './components.openapi.yml#/components/x-some-ref/whatever'
components:
  responses:
    Default200Response:
      description: Sample

First of all, as specified in the OAS3 specs:

The extensions may or may not be supported by the available tooling

So these are optional, but It'd be extremely nice to have it parsed and supported.

Not an issue, more like a feature request.

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.