Git Product home page Git Product logo

openapi-validator's Introduction

Build Status npm-version semantic-release Gitter Commitizen friendly CLA assistant

OpenAPI Validator

The IBM OpenAPI Validator lets you validate OpenAPI 3.0.x and OpenAPI 3.1.x documents for compliance with the OpenAPI specifications, as well as IBM-defined best practices.

Prerequisites

  • Node 16.0.0+
  • NPM 8.3.0+

Table of contents

Getting Started

The validator analyzes your API definition and reports any problems within. The validator is highly customizable, and supports OpenAPI 3.0.x and 3.1.x documents. The tool also supports a number of rules from Spectral. You can easily extend the tool with custom rules to meet your specific needs and ensure compliance to your standards.

Get started by installing the tool, then run the tool on your API definition.

Ruleset

By default, the validator will use the IBM Cloud Validation Ruleset (npm package @ibm-cloud/openapi-ruleset). However, if the validator detects the presence of any of the standard Spectral ruleset files (spectral.yaml, spectral.yml, spectral.json, or spectral.js) in the current directory (from which the validator is being run) or in any containing directory within the file system, then that ruleset file will be used instead. To explicitly specify an alternate ruleset, you can use the -r/--ruleset option (or the ruleset configuration property) to specify the name of your custom ruleset file.

If one of the standard Spectral ruleset files are present and you'd like to force the use of the IBM Cloud Validation Ruleset instead, you can use -r default or --ruleset default (or set the ruleset configuration property to the value 'default').

Details about these options are provided below in the Usage section.

Customization

You can modify the behavior of the validator for your project to meet your preferred standards. See the customization documentation for more information.

Installation

There are three ways to install the validator: using NPM, downloading a platform-specific binary, or building from source.

Install with NPM (recommended)

npm install -g ibm-openapi-validator

The -g flag installs the tool globally so that the validator can be run from anywhere in the file system. Alternatively, you can pass no flag or the --save-dev flag to add the validator as a dependency to your project and run it from your NPM scripts or JavaScript code.

Download an executable binary

Platform-specific binary files are packaged with each release for MacOS, Linux, and Windows. See the releases page to download the executable for your platform. These do not depend on Node.JS being installed.

Build from source

  1. Clone or download this repository
  2. Navigate to the root directory of this project.
  3. Install the dependencies using npm install
  4. Build the command line tool by running npm run link.

If you installed the validator using npm install -g ibm-openapi-validator, you will need to run npm uninstall -g ibm-openapi-validator before running npm run link.

Build platform-specific binaries

It is also possible to build platform specific binaries from the source code by running npm run pkg in the project root directory. The binaries (lint-openapi-macos, lint-openapi-linux, lint-openapi-windows.exe) will be in the project's packages/validator/bin directory.

Container image

Run the validator with the container image by mounting your API definition.

If it is named openapi.yaml in the current directory, then run:

docker run \
  --rm --tty \
  --volume "$PWD:/data:ro" \
  ibmdevxsdk/openapi-validator:latest \
    openapi.yaml

You should replace latest with a specific tagged version to avoid any surprises when new releases are published.

Flag and argument syntax is the same as described in Usage, but file paths are relative to /data.

To use a custom ruleset named ruleset.yaml in the current directory, run:

docker run \
  --rm --tty \
  --volume "$PWD:/data:ro" \
  ibmdevxsdk/openapi-validator:latest \
    --ruleset ruleset.yaml \
    openapi.yaml

Building your own

If the existing image doesn't suit your needs, you could extend it and build your own.

For example, to build a validator image with your own custom ruleset package installed, make a Dockerfile like this:

FROM ibmdevxsdk/openapi-validator:latest
RUN npm install -g ${your-ruleset-pkg-here}

Usage

Command Syntax

Usage: lint-openapi [options] [file...]

Run the validator on one or more OpenAPI 3.x documents

Options:
  -c, --config <file>            use configuration stored in <file> (*.json, *.yaml, *.js)
  -e, --errors-only              include only errors in the output and skip warnings (default is false)
  -i, --ignore <file>            avoid validating <file> (e.g. -i /dir1/ignore-file1.json --ignore /dir2/ignore-file2.yaml ...) (default is []) (default: [])
  -j, --json                     produce JSON output (default is text)
  -l, --log-level <loglevel>     set the log level for one or more loggers (e.g. -l root=info -l ibm-schema-description-exists=debug ...)  (default: [])
  -n, --no-colors                disable colorizing of the output (default is false)
  -r, --ruleset <file>           use Spectral ruleset contained in `<file>` ("default" forces use of default IBM Cloud Validation Ruleset)
  -s, --summary-only             include only the summary information and skip individual errors and warnings (default is false)
  -w, --warnings-limit <number>  set warnings limit to <number> (default is -1)
  --version                      output the version number
  -h, --help                     display help for command

where [file...] is a space-separated list containing the filenames of one or more OpenAPI 3.x documents to be validated. The validator supports OpenAPI documents in either JSON or YAML format, using these supported file extensions:

.json
.yaml
.yml

Assuming your command shell supports the use of wildcards, you can use wildcards when specifying the names of files to be validated. For example, to run the validator on all .yaml files contained in the /my/apis directory, you could use this command:

lint-openapi /my/apis/*.yaml

Note that the -i/--ignore option can be particularly useful when using wildcards because it allows you to skip the validation of specific files which might otherwise be included in a validation run. For example, to validate all .yaml files in the /my/apis directory, except for /my/apis/broken-api.yaml use the command:

lint-openapi /my/apis/*.yaml -i /my/apis/broken-api.yaml

Configuration

In addition to command-line options, the validator supports the use of a configuration file containing options as well. A configuration file can be in JSON, YAML or Javascript format, using these supported extensions: .json, .yaml, .yml, and .js. Its structure must comply with this JSON schema.

You can specify the name of your configuration file with the -c/--config option. Here's an example:

lint-openapi -c my-config.yaml my-api.json

where my-config.yaml might contain the following:

errorsOnly: true
limits:
  warnings: 25
outputFormat: 'json'
summaryOnly: true

This would be equivalent to this command:

lint-openapi --errors-only --warnings-limit=25 --json --summary-only my-api.json

When using both a configuration file and various command-line options, be aware that the options specified via the command-line will take precendence and override any corresponding properties specified in the configuration file.

Configuration Properties

This section provides information about each of the properties that are supported within a configuration file.

colorizeOutput
Description Default
The colorizeOutput configuration property corresponds to the -n/--no-colors command-line option. If set to true, then the validator will colorize its output. true
Examples:
.yaml/.yml .json .js
colorizeOutput: false
{
  "colorizeOutput": false
}
module.exports = {
  colorizeOutput: false
};
errorsOnly
Description Default
The errorsOnly configuration property corresponds to the -e/--errors-only command-line option. If set to true, the validator will include only errors in its output, while messages of severity warning, info or hint will be skipped. false
Examples:
.yaml/.yml .json .js
errorsOnly: true
{
  "errorsOnly": true
}
module.exports = {
  errorsOnly: true
};
files
Description Default
The files configuration property corresponds to positional command-line arguments (i.e. [file...]). You can set this property to the names of the OpenAPI documents to be validated. If any filenames are also entered as positional arguments on the command-line, they will override any values specified in this configuration property. [](empty list)
Examples:
.yaml/.yml .json .js
files:
  - file1.json
  - file2.yaml
{
  "files": [
    "file1.json",
    "file2.yaml"
  ]
}
module.exports = {
  files: [
    'file1.json',
    'file2.yaml'
  ]
};
ignoreFiles
Description Default
The ignoreFiles configuration property corresponds to the -i/--ignore command-line option. Set this property to the fully-qualified filenames of OpenAPI documents to be excluded from validation. This property can be particularly useful when using wildcards for specifying the OpenAPI documents to be validated, because it allows you to skip the validation of specific files which might otherwise be included in a validation run. For example, to validate all .yaml files in the /my/apis directory, except for /my/apis/broken-api.yaml use the command:
    lint-openapi /my/apis/*.yaml --ignore /my/apis/broken-api.yaml
[](empty list)
Examples:
.yaml/.yml .json .js
ignoreFiles:
  - /my/apis/file1.yml
{
  "ignoreFiles": [
    "/my/apis/file1.yml"
  ]
}
module.exports = {
  ignoreFiles: [
    '/my/apis/file1.yml'
  ]
};
limits
Description Default
The limits configuration property corresponds to the -w/--warnings-limit command-line option. Use this property to set the warnings limit. When validating an OpenAPI document, the validator will compare the number of warnings it encounters with the warnings limit. If the number of warnings exceeds the limit, then an error will be logged and the validator will return exitCode 1, similar to if actual errors were found. If the warnings limit is set to a negative number, then no warnings limit check will be performed by the validator. { warnings: -1 }(warnings limit check disabled)
Examples:
.yaml/.yml .json .js
limits:
  warnings: 25
{
  "limits": {
    "warnings": 25
  }
}
module.exports = {
  limits: {
    warnings: 25
  }
};
logLevels
Description Default
The logLevels property is an object that specifies the logging level (error, warn, info, or debug) associated with each logger within the validator. It corresponds to the -l/--log-level command-line option. { root: 'info' }
Examples:
.yaml/.yml .json .js
logLevels:
  root: error
  ibm-schema-description-exists: debug
{
  "logLevels": {
    "root": "error",
    "ibm-schema-description-exists": "debug"
  }
}
module.exports = {
  logLevels: {
    root: 'error',
    'ibm-schema-description-exists': 'debug'
  }
};
outputFormat
Description Default
You can set the outputFormat configuration property to either text or json to indicate the type of output you want the validator to produce. This property corresponds to the -j/--json command-line option. text
Examples:
.yaml/.yml .json .js
outputFormat: json
{
  "outputFormat": "json"
}
module.exports = {
  outputFormat: 'json'
};
ruleset
Description Default
You can use the ruleset configuration property to specify a custom ruleset to be used by the validator. This corresponds to the -r/--ruleset command-line option.

By default, the validator will look for the standard Spectral ruleset files (.spectral.yaml, .spectral.yml, .spectral.json, or .spectral.js) in the current working directory and its parent directories within the filesystem. If none are found, then the IBM Cloud Validation Ruleset will be used.

If you want to force the use of the IBM Cloud Validation Ruleset even if one of the standard Spectral ruleset files are present, you can specify 'default' for the ruleset configuration property.

null, which implies that a standard Spectral ruleset file will be used (if present), otherwise the IBM Cloud Validation Ruleset will be used.
Examples:
.yaml/.yml .json .js
ruleset: my-custom-rules.yaml
{
  "ruleset": "my-custom-rules.yaml"
}
module.exports = {
  ruleset: 'my-custom-rules.yaml'
};
summaryOnly
Description Default
The summaryOnly configuration property corresponds to the -s/--summary-only command-line option. If set to true, the validator will include only the summary section in its output. false
Examples:
.yaml/.yml .json .js
summaryOnly: true
{
  "summaryOnly": true
}
module.exports = {
  summaryOnly: true
};

Validator Output

The validator can produce output in either text or JSON format. The default is text output, and this can be controlled with the -j/--json command-line option or outputFormat configuration property.

Text

Here is an example of text output:

IBM OpenAPI Validator (validator: 0.97.5; ruleset: 0.45.5), @Copyright IBM Corporation 2017, 2023.

Validation Results for /my/directory/my-api.yaml:

Errors:

  Message :   Path contains two or more consecutive path parameter references: /v1/clouds/{cloud_id}/{region_id}
  Rule    :   ibm-no-consecutive-path-parameter-segments
  Path    :   paths./v1/clouds/{cloud_id}/{region_id}
  Line    :   332

Warnings:

  Message :   Operation summaries should not have a trailing period
  Rule    :   ibm-summary-sentence-style
  Path    :   paths./v1/clouds.post.summary
  Line    :   46

  Message :   Operation summaries should not have a trailing period
  Rule    :   ibm-summary-sentence-style
  Path    :   paths./v1/clouds.get.summary
  Line    :   93

Summary:

  Total number of errors   : 1
  Total number of warnings : 2

  Errors:
   1 (100%) : Path contains two or more consecutive path parameter references

  Warnings:
   2 (100%) : Operation summaries should not have a trailing period

As you can see, any errors detected by the validator are listed first, then warnings, and finally a summary section. The -s/--summary-only command-line option or the summaryOnly configuration property can be used to request that only the summary is display. Also, the -e/--errors-only option or errorsOnly configuration property can be used to cause the validator to display only errors in the output.

JSON

When displaying JSON output, the validator will produce a JSON object which complies with this JSON schema. Here is an example of JSON output:

{
  "error": {
    "results": [
      {
        "message": "Path contains two or more consecutive path parameter references: /v1/clouds/{cloud_id}/{region_id}",
        "path": [
          "paths",
          "/v1/clouds/{cloud_id}/{region_id}"
        ],
        "rule": "ibm-consecutive-path-segments",
        "line": 332
      }
    ],
    "summary": {
      "total": 1,
      "entries": [
        {
          "generalizedMessage": "Path contains two or more consecutive path parameter references",
          "count": 1,
          "percentage": 100
        }
      ]
    }
  },
  "warning": {
    "results": [
      {
        "message": "Operation summaries should not have a trailing period",
        "path": [
          "paths",
          "/v1/clouds",
          "post",
          "summary"
        ],
        "rule": "ibm-summary-sentence-style",
        "line": 46
      },
      {
        "message": "Operation summaries should not have a trailing period",
        "path": [
          "paths",
          "/v1/clouds",
          "get",
          "summary"
        ],
        "rule": "ibm-summary-sentence-style",
        "line": 93
      }
    ],
    "summary": {
      "total": 2,
      "entries": [
        {
          "generalizedMessage": "Operation summaries should not have a trailing period",
          "count": 2,
          "percentage": 100
        }
      ]
    }
  },
  "info": {
    "results": [],
    "summary": {
      "total": 0,
      "entries": []
    }
  },
  "hint": {
    "results": [],
    "summary": {
      "total": 0,
      "entries": []
    }
  },
  "hasResults": true
}

The JSON output is also affected by the -s/--summary-only and -e/--errors-only options as well as the summaryOnly and errorsOnly configuration properties.

Logging

The validator uses a logger for displaying messages on the console. The core validator uses a single logger named root, while each of the rules contained in the IBM Cloud Validation Ruleset uses their own unique logger whose name will match the rule's id (e.g. ibm-accept-header, ibm-schema-description-exists, etc.).

Each logger has a logging level associated with it: error, warn, info, and debug. Each of these levels implicitly includes the levels that precede it in the list. For example, if you set the logging level of a logger to info, then all messages of type info, warn, and error will be displayed, but debug messages will not.

To set the level of the root logger to info, you could use this option: --log-level root=info.

To set the level of the logger used by the ibm-accept-header rule to debug, you could use this option: -l ibm-accept-header=debug.

You can also use a glob-like value for a logger name to set the level on multiple loggers. For example, to set the level for all loggers whose name starts with ibm-property, try this: -l ibm-property*=debug.

Enabling debug logging for a specific rule might be useful in a situation where the rule is reporting violations which seem to be inexplicable. In this case, additional debug information might be helpful in determining why the violations are occurring, and could possibly lead to a solution. For example, suppose the ibm-pagination-style rule is reporting several violations, but yet at first glance it's not obvious why these violations are occurring. To enable debug logging for this rule, use a command like this:

lint_openapi -l ibm-pagination-style=debug my-new-api.yaml

The default log level for the root logger is info, while the default log level for rule-specific loggers is warn.

Contributing

See CONTRIBUTING.

License

This project is licensed under Apache 2.0. Full license text is available in LICENSE.

openapi-validator's People

Contributors

andras-csanyi avatar aspear avatar barrett-schonefeld avatar buptliuhs avatar croomes avatar cswen avatar dependabot[bot] avatar distortedsignal avatar dpopp07 avatar gopijaganthan avatar hudlow avatar inverse avatar jfoclpf avatar johnstarich avatar jorge-ibm avatar jormaechea avatar kant avatar meem avatar mhamann avatar olafur-palsson avatar padamstx avatar presto21 avatar pyrooka avatar richienb avatar rmkeezer avatar saltedcaramelcoffee avatar samerjaser96 avatar semantic-release-bot avatar vherrin avatar vmarkovtsev 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

openapi-validator's Issues

`type+format` errors issued for `oneOf` elements in inline property schema objects

When using an identical Schema Object by $ref or inline for a property the inline case produces type+format warnings, but the $ref case (correctly I think) does not.

See attached testoneof.yaml.zip

It contains a /ref path and an /inline path - each of which uses the same body schema of an object containing a test property. The test property's schema is defined either inline or via a $ref, but is otherwise identical using oneOf.

Unzip and run
lint-openapi testoneof.yaml

errors

  Message :   Property type+format is not well-defined.
  Path    :   paths./inline.post.requestBody.content.application/json.schema.properties.test.type
  Line    :   57

Even though the /ref path case uses an identical schema object (by reference) it does not produce the error observed in the /inline path case.

Problem finding configuration file passed in explicitly

It appears that the implementation of findUp that is used to find/validate the configuration file cannot be passed path information as a part of the file name. Doing so results in redudantly prepending the path to the returned file path. As a result the --config option does not work as implemented unless the path passed in only has a file name and is located in the current directory.

PR with fix coming.

Config unused_tag is confusing

Shouldn't be it undefined_tag? Because that's what that config checks:

Flag a tag that is in operations and not listed inย tagsย on the top level.

IMO, unused_tag could be a new rule that performs the following check:

Flag a tag that is listed inย tagsย on the top level, but not used by any operation.

What do you think? I know it's a breaking change, but you're still in v0.x.x..

Multiple scheme security requirement should be allowed

function validateSecurityObject({ security, path }) {
security.forEach(schemeObject => {
// each object in this array should only have one key - the name of the scheme
const schemeNames = Object.keys(schemeObject);
const schemeName = schemeNames[0];
// if there is more than one key, they will be ignored. the structural validator should
// catch these but in case the spec changes in later versions of swagger,
// a non-configurable warning should be printed to alert the user
if (schemeNames.length > 1) {
result.warning.push({
path,
message:
'The validator expects only 1 key-value pair for each object in a security array.'
});
}

According to the standard:

Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.

You're checking that each Security Requirement Object contains only one scheme, and setting a non-configurable warning.

I suggest one of the following:
a) Remove this validation, because is non-standard.
b) Make it configurable so user can decide what to do with it.

Thanks.

PD: Are you reviewing PRs?

UPDATE
This should be also be fixed, because it only labels the first one as used.

// each object in this array should only have one key - the name of the scheme
const name = Object.keys(scheme)[0];

operationIds validation incorrectly handling sub-resources

Issue Type: bug

Validator Version: v0.17.0

Issue: When I have a sub-resource in my spec (example path /resource/{resource-id}/sub-resource) the validator does not validate the operationId correctly. In this case I would expect a POST /resource/{resource-id}/sub-resource to allow an operationId of create_resource_sub_resource (or similar), but the validator raises a warning unless the operationId starts with update (which is technically not correct as this is a create of a child-resource).

There is a similar problem with listing sub-resources (validator requires operationId to start with get and won't allow list).

The following yaml should duplicate the problem:

components:
  parameters:
    resource_id:
      description: The resource identifier
      in: path
      name: resource_id
      required: true
      schema:
        type: string
paths:
  /resource/{resource_id}/child_resource:
    post:
      description: Create a child resource.
      operationId: create_resources_child_resource
      parameters:
      - $ref: '#/components/parameters/resource_id'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChildResource'
        description: The child resource template
        required: true
      responses:
        "201":
          description: Created
      summary: Add child resource to a resource
      tags:
      - Child Resource
components:
  schemas:
    ChildResource:
      properties:
        name:
          description: Name of child resource
          type: string
          example: My Child Resource
      required:
      - name
      description: The template for the child resource
      type: object
      title: ChildResource

Validate Response status codes to be 3 digit

HTTP status codes are supposed to be 3 digit and and it gets through the validator

i.e

        "responses": {
          "0": {
            "description": "Response on failure.",
            "schema": {
              "$ref": "#/definitions/ErrorReturnObject"
            }
          },

autorest validates to
"Parsing error(s): Property '0' has not been defined and the schema does not allow additional properties. Path 'paths['/plans'].post.responses.0',

Unable to turn up "schema $refs must follow this format" warning to error

Am running v0.12.2 installed inside a Node 12.4 Docker container.

I'm getting a very helpful warning which looks like this:

  Message :   schema $refs must follow this format: *#/components/schemas*
  Path    :   paths./packages/{p_id}/clone.post.responses.200.content.application/json.schema.$ref
  Line    :   245

statistics

  Total number of errors   : 0
  Total number of warnings : 1

  warnings
   1 (100%) : schema $refs must follow this format

This warning has been very helpful because it helped me debug why a build with our testing team was failing. In order to get this check done early before builds go to our testing team, I'd like to turn this warning up to error - but I can't find the config for that.

From the code, it looks like this is raised by the walker, but when I set the config of walker to all errors:

     "walker": {
       "no_empty_descriptions": "error",
      "has_circular_references": "error",
      "$ref_siblings": "error",
      "duplicate_sibling_description": "error"
     }

... then a warning is still returned.

Is there a way to turn this up to error?

type+format error on allowable combination (format: uuid)

Because the validator allows only the formats that are listed in the specification table, it produces an error for some that are usable. For example, "format": "uuid".

However, format is an open value, so you can use any formats, even not those defined by the OpenAPI Specification, such as:
โ€ขย email
โ€ขย uuid
โ€ขย uri
โ€ขย hostname
โ€ขย ipv4
โ€ขย ipv6
and others

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
https://swagger.io/docs/specification/data-models/data-types/

error

Message :   Property type+format is not well-defined.
Path    :   definitions.ErrorResponse.properties.trace.type

source

"trace": {
  "type": "string",
  "format": "uuid",
  "description": "A unique identifier of the request."
}

The trace use case is from our API Implementation Handbook about errors.

Add optional reporting of failing validation

lint-openapi has a "--print_validator_modules" which prints the name of the module that contains the failing validation, but this information is of limited value because the information is an implementation detail that is invisible to a user of the tool from the command line. It would be nice to have another option that resulted in printing the actual name of the config option that resulted in the validation failure so that users can understand what config option controls that result.

Today I see this for example:

$ lint-openapi ./api-validator-openapi-2x.yml
warnings
  Message :   Response schemas should be defined with a named ref.
  Path    :   paths./validation-jobs/{job_id}/junit.get.responses.200.schema
  Line    :   176

It would be ideal to have something like this:

$ lint-openapi  --print_validator_name ./api-validator-openapi-2x.yml
warnings
  Message  :  Response schemas should be defined with a named ref.
  Validator  :  inline_response_schema
  Path         :  paths./validation-jobs/{job_id}/junit.get.responses.200.schema
  Line          :  176

(sorry about the alignment above, dang markdown and non-fixed-width font)

It is true that the messages are directly correlated to the message, but the only way to do this now that I see is building a map of messages to the validator config names, which seems like a fragile and non scalable way to do it.

I am happy to help with implementation by submitting a PR.

Validator errors with `Cannot read property '$ref' of undefined` where PathItem's $ref has a requestBody property

A little more exotic one this time, but this one I believe is explicitly legal in the spec.

The below terminates with:

[Error] There was a problem with a validator.
Cannot read property '$ref' of undefined

yarp.yaml

---
openapi: 3.0.2
info:
  version: 0.0.1
  title: yarp
  contact:
    name: yeah
    email: [email protected]

paths:
  /yarp:
    post:
      $ref: yarp-post.yaml

yarp-post.yaml

---
operationId: yarp
summary: yarp
requestBody:
  description: yarp
  required: true
  content:
    application/json:
      schema:
        type: object
        properties:
          herp:
            type: string
responses:
  '200':
    application/json:
      description: yarp

This behavior can be turned on and off by omitting the requestBody.

Add build of native binaries for Linux, Mac, and Windows to remove node requirement for clients

I was looking at the awesome Spectral JSON validator project https://github.com/stoplightio/spectral, and noticed that their build creates native binaries for Linux, Mac, and Windows. These native binaries can then be used for validation on the respective client machines without requiring users to install node.js. This seems like it could enable more widespread usability of lint-openapi.

It appears that they use yarn to do their building and that there is a simple npm script that creates these binaries. (pasted below) Seems like adding this would not be difficult...

"scripts": {
...
"build.binary": "yarn build && yarn build.manifest && cp yarn.lock dist && cd dist && yarn && pkg . --out-path ./bin",

Unable to set default value to null

Hi,

First off, I love the linting capabilities of this project, it is so much more valuable than just straight spec validation to ensure consistent API conventions and encourage strong documentation within the spec.

My project uses null values to indicate a property has never been configured and many properties default to null if not set.

When I run validation on my schema file I'm getting errors like:

Message : Null values are not allowed for any property.
Path : components.schemas.ConnectId.properties.profile_picture.default
Line : 234

That property is defined in my schema as

profile_picture:
type: string
nullable: true
default: null
description: "A base64 encoded image string for the user's avatar"

I went looking for a linter option to change the behavior and found null values are just globally considered errors and there is no option to allow null as a default value. See https://github.com/IBM/openapi-validator/blob/master/src/plugins/validation/2and3/semantic-validators/walker-ibm.js#L51

Based on this clarification of the nullable keyword in OAS 3.0.3 I believe my use case is valid.
https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/003_Clarify-Nullable.md#is-null-allowed-as-the-default-value-of-a-nullable-schema-see-2057

Seemingly unreasonable lower_snake_case case convention on component properties

The component section the the APIdoc describes either what the request payload looks like or what the response payload looks like.

Different team defines the payload properties differently. As in our pipeline, the payload properties always follow Camel case convention.
So they look like the followings:

{
	"eventListener": "manual-listener"
}

or

{
  "name": "TekPip4",
  "type": "tekton",
  "resourceGroupId": "19c29990ffe42ce260f5a5cb64f54169",
  "toolchainId": "d7d315d7-38f2-4301-ac51-ec188e5b6475",
  "toolchainCRN": "crn:v1:staging:public:toolchain:us-south:a/0ba224679d6c697f9baee5e14ade83ac:d7d315d7-38f2-4301-ac51-ec188e5b6475::",
  "updated_at": "2020-01-03T14:52:21.122Z",
  "id": "8af11040-4388-482a-993d-520ab10d2393",
  "inputs": [
    {
      "scmSource": {
        "path": "ascode",
        "url": "https://github.com/SidneyJiang/SimleTestWithMocha.git",
        "type": "GitHub",
        "branch": "master",
        "hookId": 155859355
      },
      "type": "scm",
      "serviceInstanceId": "0c215516-82d8-4d86-a431-a444d2c58f9d",
      "pipelineDefinitionStatus": {
        "state": "updated"
      },
      "shardDefinitionId": "ba558579-e853-4fd6-8fa5-4961d79cb168"
    }
  ],
  "envProperties": [
    {
      "name": "asd",
      "value": "asdasd",
      "type": "TEXT"
    }
  ]
}

As a result, when we use validator to validate our apidoc: https://dev.console.test.cloud.ibm.com/devops/pipelines/tekton/apispec/openapi.yaml?env_id=ibm:ys1:us-south
it complains pipelineRunId, envProperties violates lower_snake_case rule.

However, I think the property is totally legit.

Please provide a property to retrieve validated document model

The output of the validator only returns errors and warnings but does not return the document model. This could be particularly useful if the document had external references which needed to be resolved.

Would it be possible to expose a property which returns the final and possibly exploded validated document model?

Cannot read property 'type' of null when linting OpenAPI files

I'm the same guy from this issue, this is a problem with a different Open API file.


My team is changing over to Open API 3.0 documentation from RAML, and I'm trying to build up a linter from this tool. Our API is (fairly) complex and our data structures are deeply nested. I recently ran into an issue where one of our *.json files couldn't be linted because of a type deref on a null.

Local information

Installed via npm with the -g flag.

In the directory that I'm linting:

> lint-openapi -v
0.28.0

The call that makes the error happen, and output:

> # Source filename on following line changed to protect the guilty.
> lint-openapi --debug openapi_2.json

[Error] There was a problem with a validator.
Cannot read property 'type' of null

TypeError: Cannot read property 'type' of null
    at arrayOctetSequences (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:38:20)
    at findOctetSequencePaths (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:22:34)
    at /usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:67:14
    at Array.forEach (<anonymous>)
    at objectOctetSequences (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:53:35)
    at findOctetSequencePaths (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:24:34)
    at /usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:67:14
    at Array.forEach (<anonymous>)
    at objectOctetSequences (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:53:35)
    at findOctetSequencePaths (/usr/local/lib/node_modules/ibm-openapi-validator/src/plugins/utils/findOctetSequencePaths.js:24:34)

I feel like this is pretty hard to debug because the file splay of our API documentation means that I'm not entirely sure where this error is being hit. Would it be possible to print the name of the file (or, even better, the name of the object/path of the object) that procs the error?

Add explicit control of case convention for paths and schema

Hi! This tool is awesome, and it would be really nice to have explicit control over case conventions for paths, and then schema objects and enums. As it is, the only control over this is the global boolean "snake_case_only" which is only useful for one convention (presumably IBMs). In my company (VMware) we have many APIs that come from different products that all have their own ways of handing paths for example, one lower_camel_case, another lower_snake_case.

I propose (and have already implemented!) a couple of small backwards compatible additions:

  1. in the paths section, add a new config option "paths_case_convention" that allows explict control. The .defaultsForValidator.js changes to:
    'paths': {
    'missing_path_parameter': 'error',
    'snake_case_only': 'warning',
    'paths_case_convention': ['off', 'lower_snake_case']
    },
    The idea here is that a user could set snake_case_only to off, and then use paths_case_convention in a similar manner to the existing param_name_case_convention to explicitly control the selection for paths.

  2. Add two additional options in the spirit of the change above for the schemas section:
    'schemas': {
    ...
    'property_case_convention': [ 'off', 'lower_snake_case'],
    'enum_case_convention': [ 'off', 'lower_snake_case']
    },
    This allows you to have one convention for properties of objects (e.g. lower_snake_case), and then a separate convention for enums (e.g. upper_snake_case, 'MY_ENUM_VALUE')

This fixes #38 btw.

  1. Add additional case convention values upper_snake_case and upper_dash_case (note that my company uses upper_snake_case for enums. We don't use upper_dash_case, but while I was touching the code I figured I might as well add it so that all cases were covered)

I already have this implemented in a fork. I am implementing tests right now. I would be very happy to submit a pull request for it if you are open.

thanks,
Aaron Spear, VMware

Required value for `openapi` or `swagger` is not checked for existence or value

Context

In version 3 of OpenAPI, the field openapi is required in the root object as per the spec: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields

In version 2, the field swagger is required as per the spec: https://swagger.io/specification/v2/#fixed-fields

However, the validator does not check that these fields are provided, nor does it check their values.

The examples below are running v0.17.0 inside a Node 13.7 docker container.

When not provided

Current behaviour

Given the following specification, which contains neither swagger nor openapi:

info:
  description: Test
  version: "1"
  title: Test
paths:
  '/things':
    post:
      summary: Create things
      operationId: create_things
      produces:
        - application/json

Validator falls back to assuming that this is v2 (which is why produces is required to avoid generating a warning) - and the output is:

openapi.yaml passed the validator

Expected behaviour

Validator should fail because neither swagger nor openapi fields are specified in the root object. It would probably be simplest if validation just stopped at this point, rather than making any assumptions about the version that was desired.

When a bad value is provided

Current behaviour

The value provided for swagger and openapi are not checked. This means that strange configurations pass validation. The following pass with no warnings or errors:

Providing both values:

swagger: 4
openapi: 5
info:
  description: Test
  version: "1"
  title: Test
paths:
  '/things':
    post:
      summary: Create things
      operationId: create_things

Providing objects:

swagger:
  is_good: true
openapi:
  is_better: Maybe
info:
  description: Test
  version: "1"
  title: Test
paths:
  '/things':
    post:
      summary: Create things
      operationId: create_things
      produces:
        - things

Expected behaviour

My understanding of the specs is that the openapi.yaml file's root object must contain one of:

  • swagger: 2.0 (because spec says: """The value MUST be "2.0".""") or
  • openapi: 3.0.0 or
  • openapi: 3.0.1 or
  • openapi: 3.0.2

Any other variation should raise an error and halt validation.

This might be a little strict in terms of the possible values for openapi, but it certainly should not allow anything that does not look like a semver string since the spec says "An OpenAPI document compatible with OAS 3.. contains a required openapi field which designates the semantic version of the OAS that it uses."

Path with dot: Cannot read property '$ref' of undefined

VERSION

ibm-openapi-validator: 0.9.1

SUMMARY

Validator fails with Cannot read property '$ref' of undefined on path with dot and requestBody like:

  /dot.name:
    post:
      summary: Summary
      requestBody:
        content:
STACK TRACE
TypeError: Cannot read property '$ref' of undefined
    at each (C:\example\node_modules\ibm-openapi-validator\src\plugins\validation\oas3\semantic-validators\operations.js:62:69)
    at C:\example\node_modules\lodash\_createBaseFor.js:17:11
    at baseForOwn (C:\example\node_modules\lodash\_baseForOwn.js:13:20)
    at C:\example\node_modules\lodash\_createBaseEach.js:17:14
    at forEach (C:\example\node_modules\lodash\forEach.js:38:10)
    at each (C:\example\node_modules\ibm-openapi-validator\src\plugins\validation\oas3\semantic-validators\operations.js:26:5)
    at C:\example\node_modules\lodash\_createBaseFor.js:17:11
    at baseForOwn (C:\example\node_modules\lodash\_baseForOwn.js:13:20)
    at C:\example\node_modules\lodash\_createBaseEach.js:17:14
    at forEach (C:\example\node_modules\lodash\forEach.js:38:10)
STEPS TO REPRODUCE
  1. Create example.yaml
openapi: 3.0.0

paths:

  /dot.name:
    post:
      summary: Summary
      requestBody:
        content:
          application/json:
            schema:
              type: integer
      responses:
        default:
          description: nop
  1. Launch validator
$ lint-openapi example.yaml

[Warning] No .validaterc file found. The validator will run in default mode.
To configure the validator, create a .validaterc file.

[Error] There was a problem with a validator.
Cannot read property '$ref' of undefined
Expected result

ibm-openapi-validator will not fail.

Additional info

If remove the dot from the path, the validator will successfully complete.

Validator blows up with message `thing.parameters.map is not a function` when "allOf" appears as the first child of a parameters block

Using lint-openapi version 0.13.3

When an allOf appears (apparently illegally) as the first child of a parameters block on a path operation, rather than failing with a useful error message, it exits with:

[Error] There was a problem with a validator.
thing.parameters.map is not a function

A yaml file that (minimally?) reproduces the issue is here:

herp.yaml

---
openapi: 3.0.0
info:
  version: 0.0.1
  title: herp
  contact:
    name: yeah
    email: [email protected]

paths:
  /derp:
    get:
      parameters:
        allOf:
          - name: grog
            type: string
          - name: fnord
            type: string
      description: herp
      responses:
        "200":
          description: response

It would be preferable that it would fail with a message reflecting that the usage was unexpected or illegal.

Invalid error 'Null values are not allowed for any property' message.

walker-ibm returns 'Null values are not allowed for any property' for the following property definition:

SomeNullableProperty:
  type: string
  nullable: true
  default: null

The intentions is to give explicit default value for the nullable property. Nullable properties are supported in OpenApi 3.0.

src/plugins/validation/2and3/semantic-validators/walker-ibm.js line 51 says:

check for and flag null values - they are not allowed by the spec and are likely mistakes
which seems to not be quite correct.

Ability to manually specify a path to a configuration file

Right now the default behavior of lint-openapi is to search in the working directory for .validaterc and then search in parent folders. It would be convenient for automation use cases to be able to specify a particular config file explicitly, e.g.

lint-openapi --config=/path/to/my-config.json /path/to/swagger.json

In this use case .validaterc would be completely ignored and only the specified file would be loaded.

I have a PR ready to go with this implemented, but am having trouble with getting the tests to work. There seems to be an issue with the config being loaded in the context of the cli tests...

Validator fails unexpressively when $ref appears in invalid location

Using lint-openapi version 0.13.3

When a ref appears as a direct child of either the paths element or a given path in the paths element (two illegal positions) rather than failing with a useful error message, it exits with:

[Error] There was a problem with a validator.
Cannot read property '$ref' of undefined

Minimal reproduction pair here:

derp.yaml

---
openapi: 3.0.0
info:
  version: 0.0.1
  title: derp
  contact:
    name: yeah
    email: [email protected]

paths:
  /derp:
    post:
      $ref: yarp.yaml#/derp-post

yarp.yaml

---
derp-post:
  operationId: derp
  summary: derp
  requestBody:
    description: derp
    content:
      application/json:
        schema:
          type: object
  responses:
    '200':
      description: derp

It would be more helpful if it failed with a message reflecting that the location was illegal, though I understand these edge cases are really hard to catch. ๐Ÿ˜ƒ

File unexpectedly passes validation - should complain about arrays in response

Am running v0.12.0 installed inside a Node 12.4 Docker container.

Given the following openapi v3 spec:

openapi: 3.0.0
info:
  description: Test arrays returned
  version: '0'
  title: Things service
servers:
  - url: 'https://example.com/test'
paths:
  '/things':
    post:
      summary: Do things
      operationId: do_things
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingsArray'
components:
  schemas:
    ThingsArray:
      description: List of empty Things
      type: array
      items:
        type: object

This defines the response of POST /things to be an array of empty objects.

Current behaviour

The file above passes the validator with all operations post, put, patch, delete, head, options, and trace - it only fails when 'get' is used.

It also passes when imaginary operations are used: look, shut, open.

Expected behaviour

The file above should fail with:

errors

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./things.post.responses.200.content.application/json.schema
  Line    :   18

statistics

  Total number of errors   : 1
  Total number of warnings : 0

  errors
   1 (100%) : Arrays MUST NOT be returned as the top-level structure in a response body.

This should also happen for all other operations - real or created.

Validator doesn't handle some schema object properties

Hello,

I am using this wonderful validator to check my openapi 3.0 files, but I have a little issue.

When the validator finds a response schema object, it forces it to be followed by a named ref, and this is fine.

But per openpi 3.0 spec, one schema could be any kind of a list, oneOf, and that's exactly my use case. The validator is throwing me an error about that, but it's a valid thing to do.

So, with the following example:

components:
  responses:
    Test:
      description: Just a test
      content:
        'application/json':
          schema:
            oneOf:
              - $ref: "#/components/schemas/Status"
              - $ref: "#/components/schemas/Error"
          examples:
            ok:
              summary: No conflicts
              value: {"status": "OK"}
            error:
              summary: Conflicts
              value: {"error": "Houston! Help!"}

I would expect the validator to be able to handle it, but right now it throws: Response schemas should be defined with a named ref.

If someone needs more info about this, please don't mind to ask.

Regards.

The rules for operation_id should allow for hyphens.

if (opKey === 'get' && !operationId.match(/^list[a-zA-Z0-9_]+/m)) {

The operation id check allows "\w", except for the prefix, but some openapi editors use hyphenated joins by default. For example, spotlight studio.

For strict validation, all valid checks should be Error, but if you want to include a hyphen, there is no other way than to invalidate operation_id.

Maximum call stack size exceeded

My team is changing over to Open API 3.0 documentation from RAML, and I'm trying to build up a linter from this tool. Our API is (fairly) complex and our data structures are deeply nested. I recently ran into an issue where one of our *.json files couldn't be linted because of a limit on the size of the callstack.

Local information

Installed via npm with the -g flag.

In the directory that I'm linting:

> lint-openapi -v
0.28.0

The call that makes the error happen, and output:

> # Source filename on following line changed to protect the guilty.
> lint-openapi --debug openapi.json

[Error] There is a problem with the Swagger.
Maximum call stack size exceeded

RangeError: Maximum call stack size exceeded
    at RegExp.exec (<anonymous>)
    at Url.parse (url.js:257:31)
    at urlParse (url.js:150:13)
    at Object.urlResolve [as resolve] (url.js:660:10)
    at dereference$Ref (/usr/local/lib/node_modules/ibm-openapi-validator/node_modules/json-schema-ref-parser/lib/dereference.js:99:22)
    at /usr/local/lib/node_modules/ibm-openapi-validator/node_modules/json-schema-ref-parser/lib/dereference.js:59:26
    at Array.forEach (<anonymous>)
    at crawl (/usr/local/lib/node_modules/ibm-openapi-validator/node_modules/json-schema-ref-parser/lib/dereference.js:52:24)
    at dereference$Ref (/usr/local/lib/node_modules/ibm-openapi-validator/node_modules/json-schema-ref-parser/lib/dereference.js:113:24)
    at /usr/local/lib/node_modules/ibm-openapi-validator/node_modules/json-schema-ref-parser/lib/dereference.js:59:26

I'm not totally sure how to debug this - do you have any advice? I'm more than happy to post my .validaterc file, but since the source is not open, I'm a little hesitant to provide the source files that are being used here.

Error when property is named "parameters"

One of the models in my API definition has a property named parameters:

        "parameters": {
          "type": "object",
          "description": "A map of key/value pairs to be provided to the action.",
          "additionalProperties": {}
        }

The validator gives me these errors:

  Message :   Parameter objects must have a `description` field.
  Path    :   definitions.DialogNodeAction.properties.parameters.additionalProperties
  Line    :   11254

  Message :   Parameter type+format is not well-defined.
  Path    :   definitions.DialogNodeAction.properties.parameters.additionalProperties
  Line    :   11254

The errors go away if I change the name of the property to something other than parameters. It seems to be assuming that anything named parameters is an OpenAPI parameters object, when in this case it is just an ordinary property that happens to be named parameters.

Support extensible async plug-in validations (outside of the code base)

I would like to be able to add my custom rules validations outside of the code base. Right the only option is to add it to the code base and modify the .defaultsForValidator.js I also need to use async functions from third party libraries in my custom validations (such as the wordpos library). This is not possible without the design supporting async validators.

Request for a higher order error for bad "type"

Am running v0.15.2 installed inside a Node 13.2.0 alpine Docker container.

Given the following openapi v3 spec:

openapi: 3.0.0
info:
  description: Test types
  version: '0'
  title: Thing service serves things
servers:
  - url: 'https://example.com/test'
paths:
  '/thing':
    get:
      summary: Get thing
      operationId: get_thing
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                type: object
                properties:
                  thing:
                    type: thing

There is a problem on the last line type: thing.

Current behaviour

When editing this file in the latest Swagger editor at http://editor.swagger.io/ the following error is shown:

Screenshot from 2019-11-26 12-44-55

And the validator does return an error, which is good. This is the error returned:

errors

  Message :   Property type+format is not well-defined.
  Path    :   paths./things.get.responses.200.content.application/json.schema.properties.things.type
  Line    :   23

There are two problems with this current behaviour of the validator:

  1. In this case, format has not been defined, so it's a confusing error message. My guess is that there is no value we could add for format that would fix this error.

  2. The real error which is that the type of thing is invalid is not being returned, so the validator is not helping the user "get back on track".

Desired behaviour

Would it be possible to generate a new higher order error? In this case something that matches what the swagger editor returns?

errors

  Message :   Property type is not equal to one of the allowed values.
  Path    :   paths./things.get.responses.200.content.application/json.schema.properties.things.type
  Line    :   23

I think that would be helpful because it seems to me that the root cause of the problem is that the type is not one of the allowed values: "array, boolean, integer, number, object, string", rather than there being an issue with format, which is unspecified in this example.

Having a new type error would mean more control available in the config file because type+format errors could be tuned down for files that are using custom format such as "uuid", without stomping on important type errors like this one.

Problem following references when run outside of the root definition directory

Running from outside the root OpenAPI definition's directory can cause a failure to follow relative file references. For example, this fails:

/projects/api $ lint-openapi definition/root.yaml

[Error] There is a problem with the Swagger.
Error opening file "/projects/api/pets.yaml"

(Fails to find pets.yaml because the file is in /projects/api/definition/)

Even when this succeeds:

/projects/api $ cd definition/
/projects/api/definition $ lint-openapi root.yaml

Official OpenAPI specification examples fail validation?

When I run the files from the official OpenAPI Specification 3.0 examples through the validator, using the following command:

lint-openapi -d -e file.yaml

I would expect the validator to not return any errors. However, all of them except for api-with-examples.yml return errors. I mean sure, there could be errors in there as well, but from a few spot checks I did I couldn't explicitly find violations of the specification in the examples. How is this possible, am I doing something wrong, or is there something I'm missing?

The following errors are returned when using version 0.28.0:

callback-example.yml:

  Message :   Parameter names must follow case convention: lower_snake_case
  Path    :   paths./streams.post.parameters.0
  Line    :   10

  Message :   Schema of type string should use one of the following formats: byte, binary, date, date-time, password.
  Path    :   paths./streams.post.parameters.0.schema.type
  Line    :   17

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   paths./streams.post.responses.201.content.application/json.schema.properties.subscriptionId
  Line    :   30

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   paths./streams.post.callbacks.onData.{$request.query.callbackUrl}/data.post.requestBody.content.application/json.schema.properties.userData
  Line    :   51

link-example.yml:

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./2.0/repositories/{username}.get.responses.200.content.application/json.schema
  Line    :   5

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests.get.responses.200.content.application/json.schema
  Line    :   5

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/users/{username}.get.parameters.0
  Line    :   10

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}.get.parameters.0
  Line    :   29

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}.get.parameters.0
  Line    :   50

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}.get.parameters.1
  Line    :   55

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests.get.parameters.0
  Line    :   74

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests.get.parameters.1
  Line    :   79

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests.get.parameters.2
  Line    :   84

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}.get.parameters.0
  Line    :   105

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}.get.parameters.1
  Line    :   110

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}.get.parameters.2
  Line    :   115

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge.post.parameters.0
  Line    :   134

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge.post.parameters.1
  Line    :   139

  Message :   Parameter objects must have a `description` field.
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge.post.parameters.2
  Line    :   144

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/users/{username}
  Line    :   6

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/repositories/{username}
  Line    :   25

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/repositories/{username}/{slug}
  Line    :   46

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests
  Line    :   70

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}
  Line    :   101

  Message :   Path segments must follow case convention: lower_snake_case
  Path    :   paths./2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge
  Line    :   130

petstore.yml:

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./pets.get.responses.200.content.application/json.schema
  Line    :   34

  Message :   Parameter names must follow case convention: lower_snake_case
  Path    :   paths./pets/{petId}.get.parameters.0
  Line    :   63

petstore-expanded.yml:

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./pets.get.responses.200.content.application/json.schema
  Line    :   47

uspto.yml:

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./{dataset}/{version}/records.post.responses.200.content.application/json.schema
  Line    :   147

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiKey
  Line    :   197

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiVersionNumber
  Line    :   200

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiUrl
  Line    :   203

  Message :   Property names must follow case convention: lower_snake_case
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiDocumentationUrl
  Line    :   207

  Message :   Schema of type string should use one of the following formats: byte, binary, date, date-time, password.
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiUrl.type
  Line    :   204

  Message :   Schema of type string should use one of the following formats: byte, binary, date, date-time, password.
  Path    :   components.schemas.dataSetList.properties.apis.items.properties.apiDocumentationUrl.type
  Line    :   208

File unexpectedly passes validation - should complain about arrays in response or undefined type

Am running v0.13.3 installed inside a Node 12.4 Docker container.

Given the following openapi v3 spec:

openapi: 3.0.0
info:
  description: Test arrays returned
  version: '0'
  title: Things service
servers:
  - url: 'https://example.com/test'
paths:
  '/things':
    post:
      summary: Do things
      operationId: do_things
      responses:
        '200':
          description: OK.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingsArray'
components:
  schemas:
    ThingsArray:
      description: List of empty Things
      items:
        type: object

This example file is very closely related to the example in #71 - but I've removed the type: array specification from ThingsArray. This is a little bit of a grey area I guess since the openapi file is not explicit about the type of ThingsArray, however, the Swagger Editor renders this as an Array and gives an example JSON of:

[
  {}
]

Current behaviour

The file above passes the validator.

Expected behaviour

The file above should fail with something - I can see one of two options, but would be generally happy as long as some kind of error or warning is returned for this case.

Treat it as an array

Assume that ThingsArray which has unspecified 'type' is an array and give the error:

errors

  Message :   Arrays MUST NOT be returned as the top-level structure in a response body.
  Path    :   paths./things.post.responses.200.content.application/json.schema
  Line    :   18

Complain about missing type

Add a warning that indicates that 'type' has not been provided:

warnings

  Message :   Property type not provided.
  Path    :   components.schemas.ThingsArray.items.type
  Line    :   25

Unexpected $ref warning when a definition is declared and used once

Validator v0.17.0 with the following v3 OpenAPI specification:

openapi: 3.0.0
info:
  description: Pancakes are the best!
  version: 1.33.7
  title: Pancakes API
paths:
  /pancakes:
    get:
      operationId: list_pancakes
      summary: Returns all pancakes.
      description: For pancakes...
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  name:
                    description: The name of the pancake.
                    type: string

I see the following warning:

warnings

  Message :   Response schemas should be defined with a named ref.
  Path    :   paths./pancakes.get.responses.200.content.application/json.schema
  Line    :   17

statistics

  Total number of errors   : 0
  Total number of warnings : 1

  warnings
   1 (100%) : Response schemas should be defined with a named ref.

I'm trying to understand whether this is a valid warning, as based on the "Using $ref" documentation:

it is common to have some features which you use across several of API resources. In that case, you can create a snippet for such elements in order to use them multiple times when you need it.

it seems that $ref was introduced to follow DRY principle, however in this case I can't see the validity of this being a warning as the definition is declared and used only once.

Probably, the desired behaviour would be to check for duplicated definitions before raising the named ref warning.

Add optional reporting of results in json to allow scripting the tool

Adding a new option to the command line tool that allows printing the results directly in json would be nice for use cases where someone wants to script calling lint-open api from another tool. Something like "lint-openapi --json ./path/to/swagger.json"

I have this implemented already and will submit a PR for it.

Allow upper case acronyms in camel case validator

We are using openapi-validator on an api that conforms to the Kubernetes API conventions.

The lower_camel_case validator is close but it doesn't allow acronyms such as UserID or IPAddress to be capitalised, so this convention fails:

All letters in the acronym should have the same case, using the appropriate case for the situation. For example, at the beginning of a field name, the acronym should be all lowercase, such as "httpGet". Where used as a constant, all letters should be uppercase, such as "TCP" or "UDP".

This could be solved in a few of ways:

  1. Amend regexes for upper_camel_case and lower_camel_case, but this affects current users who might not want this:
diff --git a/src/plugins/utils/caseConventionCheck.js b/src/plugins/utils/caseConventionCheck.js
index 927cabb..b92d087 100644
--- a/src/plugins/utils/caseConventionCheck.js
+++ b/src/plugins/utils/caseConventionCheck.js
@@ -7,8 +7,8 @@
 
 const lowerSnakeCase = /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;
 const upperSnakeCase = /^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$/;
-const upperCamelCase = /^[A-Z][a-z0-9]+([A-Z][a-z0-9]+)*$/;
-const lowerCamelCase = /^[a-z][a-z0-9]*([A-Z][a-z0-9]+)*$/;
+const upperCamelCase = /^[A-Z]+[a-z0-9]+([A-Z]+[a-z0-9]*)*$/;
+const lowerCamelCase = /^[a-z][a-z0-9]*([A-Z]+[a-z0-9]*)*$/;
 const lowerDashCase = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
 const upperDashCase = /^[A-Z][A-Z0-9]*(-[A-Z0-9]+)*$/;
  1. Add additional validators for the less restrictive format, e.g. upper_camel_case_loose and lower_camel_case_loose.
  2. Decide this is too specialized and not something you want to cater for.

I can submit a PR for option 1 or 2 based on preference.

securityScheme import: Cannot read property 'toLowerCase' of undefined

VERSION

ibm-openapi-validator: 0.5.0

SUMMARY

Validator fails with Cannot read property 'toLowerCase' of undefined on securityScheme import like:

components:
  securitySchemes:
    securitySchemaN1:
      $ref: 'base.yaml#/components/securitySchemes/securitySchemaN1'
STACK TRACE
TypeError: Cannot read property 'toLowerCase' of undefined
    at each (C:\example\node_modules\ibm-openapi-validator\src\plugins\validation\2and3\semantic-validators\security-definitions-ibm.js:31:21)
    at C:\example\node_modules\lodash\_createBaseFor.js:17:11
    at baseForOwn (C:\example\node_modules\lodash\_baseForOwn.js:13:20)
    at C:\example\node_modules\lodash\_createBaseEach.js:17:14
    at forEach (C:\example\node_modules\lodash\forEach.js:38:10)
    at Object.module.exports.validate (C:\example\node_modules\ibm-openapi-validator\src\plugins\validation\2and3\semantic-validators\security-definitions-ibm.js:23:3)
    at Object.keys.forEach.key (C:\example\node_modules\ibm-openapi-validator\src\cli-validator\utils\validator.js:70:40)
    at Array.forEach (<anonymous>)
    at validateSwagger (C:\example\node_modules\ibm-openapi-validator\src\cli-validator\utils\validator.js:69:30)
    at processInput (C:\example\node_modules\ibm-openapi-validator\src\cli-validator\runValidator.js:211:17)
STEPS TO REPRODUCE
  1. Create base.yaml
components:
  securitySchemes:
    securitySchemaN1:
      description: example description
      type: apiKey
      in: cookie
      name: userAuthCookie
  1. Create main.yaml
openapi: 3.0.0

paths: {}

components:

  securitySchemes:
    securitySchemaN1:
      $ref: 'base.yaml#/components/securitySchemes/securitySchemaN1'
  1. Launch validator
$ lint-openapi main.yaml
[Warning] No .validaterc file found. The validator will run in default mode.
To configure the validator, create a .validaterc file.

[Error] There was a problem with a validator.
Cannot read property 'toLowerCase' of undefined
Expected result

ibm-openapi-validator will use the securityScheme definition inside main.yml without Error.

References

Per openapi 3.0 specification schema the securitySchemes items can be a reference:

      securitySchemes:
        type: object
        patternProperties:
          '^[a-zA-Z0-9\.\-_]+$':
            oneOf:
              - $ref: '#/definitions/Reference'
              - $ref: '#/definitions/SecurityScheme'

Bug: A path parameter under root node AND under the method node leads to crash / internal error

Code:

/xs/{xId}: parameters: - $ref: '#/components/parameters/xIdParameter' patch: description: Updates an x. summary: Update x {xId} tags: - xs parameters: - $ref: '#/components/parameters/xIdParameter' operationId: updatex x-eov-operation-handler: routes/xs responses: 200: description: Successful response 401: description: Unauthorized request delete: description: Deletes x {xId} summary: Delete x {xId} tags: - xs security: - BearerJwtSchema: [] operationId: deletex x-eov-operation-handler: routes/xs responses: 200: description: Successful response 401: description: Unauthorized request

leads to

[Error] There was a problem with a validator. Cannot read property 'findIndex' of undefined

Issues with `$ref` format checking

I've found a few problems with the way the validator tool checks $ref usage using version 0.2.1.
I've created and attached a set of example files in example.zip which demonstrates the problems, unzip and run for vi.yaml.

  1. The checking does not apply consistently across all types - in my example vi.yaml errors are given only for headers, parameters and responses despite the blacklist including requestBodies which I reference in the same way.
  2. The format checking is applied to $ref usages within the components object itself, which doesn't make sense because it encourages a spec writer to create a circular reference.
  3. The restrictions on the $ref format in OpenAPI v3 are invalid anyway. I sought clarification on this in OAI/OpenAPI-Specification#1679 - though the spec has not been updated yet (as of v3.0.2).

Based on point 3 I think removing the $ref format checks entirely for OpenAPI v3 could be a good solution.
Another option would be to workaround by adding an option to disable the walker's $ref checks, similarly to how many of the other checks can be flagged on and off.

I'd be happy to try and do a PR for either of those options if it suits, just let me know.

Even if I did that though I think further may be needed to address point 1 to get complete spec checking - I haven't looked into why the validator doesn't behave the same way for all the $refs and whether it is missing validating part of the tree.

PR#127 not handling $ref for non-204 statutes

Seems like #127 is not handling correctly responses that references a response in the components node, so it is throwing invalid warnings.

Example:

paths:
  /authenticate:
    post:
      operationId: create_user_session
      tags:
        - Authentication
      summary: Creates a new user session
      description: Creates a new user session
      security:
        - JWT: []
      responses:
        '200':
          $ref: "#/components/responses/test"
components:
  responses:
    test:
      description: Just a test
      content:
        'application/json': ...

Configurable operationId naming convention

#124 adds linting naming conventions for operationId, but apparently, there is no option to disable it, or change which verbs are in convention, e.g. in my case I would like to use search verb instead of list when GET endpoint has parameters, since in my API, it's always a search operation.

openapi-validator version: 0.24.0

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.