### Install @stoplight/spectral-ref-resolver Source: https://github.com/stoplightio/spectral/blob/develop/packages/ref-resolver/README.md Install the package using npm or yarn. ```bash npm install --save @stoplight/spectral-ref-resolver ``` ```bash yarn add @stoplight/spectral-ref-resolver ``` -------------------------------- ### Install Spectral CLI with npm Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Use this command to globally install the Spectral CLI client using npm. ```bash npm install -g @stoplight/spectral-cli ``` -------------------------------- ### Install Spectral CLI with Yarn Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Use this command to globally install the Spectral CLI client using Yarn. ```bash yarn global add @stoplight/spectral-cli ``` -------------------------------- ### Install Spectral Dependencies Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4f-js-rulesets.md Install the necessary Spectral packages using npm. These are not strictly required but are used in the example for common rules and format targeting. ```bash npm install --save @stoplight/spectral-functions npm install --save @stoplight/spectral-formats ``` -------------------------------- ### Install Spectral Javascript API with Yarn Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Use this command to globally install the Spectral Javascript API using Yarn. ```bash yarn global add @stoplight/spectral-core ``` -------------------------------- ### AsyncAPI Tag Description Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Provides examples of how to add descriptive text to tags for better clarity. ```yaml tags: - name: "Aardvark" description: Funny-nosed pig-head raccoon. - name: "Badger" description: Angry short-legged omnivores. ``` ```yaml tags: - name: Invoice Items description: | Giant long explanation about what this business concept is, because other people _might_ not have a clue! ``` -------------------------------- ### AsyncAPI v3 Channel Servers - Bad Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md This example demonstrates an incorrect way to reference server definitions for channels, where the reference does not match an existing server. ```yaml asyncapi: "3.0.0" info: title: Awesome API description: A very well-defined API version: "1.0" servers: production: url: "stoplight.io" protocol: "https" channels: hello: servers: - $ref: #/servers/development ``` -------------------------------- ### AsyncAPI v3 Server Host - Good Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Server host should not have a trailing slash. This example shows a correctly formatted server host. ```yaml servers: - host: mqtt://example.com ``` -------------------------------- ### Install Spectral Javascript API with npm Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Use this command to globally install the Spectral Javascript API using npm. ```bash npm install -g @stoplight/spectral-core ``` -------------------------------- ### Lint Document with Inline Ruleset (JavaScript) Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/3-javascript.md This example demonstrates how to lint a YAML document from a string using an inline ruleset. Ensure you have `@stoplight/spectral-core`, `@stoplight/spectral-parsers`, and `@stoplight/spectral-functions` installed. ```javascript import spectralCore from "@stoplight/spectral-core"; const { Spectral, Document } = spectralCore; import Parsers from "@stoplight/spectral-parsers"; // make sure to install the package if you intend to use default parsers! import { truthy } from "@stoplight/spectral-functions"; // this has to be installed as well // this will be our API specification document const myDocument = new Document( `--- responses: '200': description: ''`, Parsers.Yaml, "/my-file", ); const spectral = new Spectral(); spectral.setRuleset({ // this will be our ruleset rules: { "no-empty-description": { given: "$..description", message: "Description must not be empty", then: { function: truthy, }, }, }, }); // we lint our document using the ruleset we passed to the Spectral object spectral.run(myDocument).then(console.log); ``` -------------------------------- ### AsyncAPI v3 Channel Servers - Good Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Channel servers must be defined in the `servers` object. This example shows the correct way to reference a server definition. ```yaml asyncapi: "3.0.0" info: title: Awesome API description: A very well-defined API version: "1.0" servers: production: url: "stoplight.io" protocol: "https" channels: hello: servers: - $ref: #/servers/production ``` -------------------------------- ### Real Test Case Example Source: https://github.com/stoplightio/spectral/blob/develop/test-harness/README.md An example of a complete test case, including a sample OpenAPI document and the command to lint it, along with expected output. ```text ====test==== scenario-example ====document==== openapi: 3.0.2 servers: - url: "localhost" info: title: "my api" description: "An example" contact: name: "Stoplight" version: "1.0" paths: /todos: get: tags: - "example" description: "Example endpoint" operationId: getTodos responses: 200: description: Get Todo Items content: 'application/json': example: hello ====command==== {bin} lint {document} ====stdout==== OpenAPI 3.x detected {document} 2:6 warning some-rule This rule is complaining about something. ✖ 1 problems (1 error, 0 warning, 0 infos, 0 hints) ``` -------------------------------- ### Install Spectral CLI Source: https://github.com/stoplightio/spectral/blob/develop/packages/cli/README.md Install the Spectral CLI globally using npm or yarn. This command makes the `spectral` executable available in your terminal. ```bash npm install -g @stoplight/spectral-cli ``` ```bash yarn global add @stoplight/spectral-cli ``` -------------------------------- ### Install Spectral using standalone binaries Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Installs Spectral using a shell script, suitable for environments without Node.js. Note that binaries do not autoupdate. ```bash curl -L https://raw.github.com/stoplightio/spectral/master/scripts/install.sh | sh ``` -------------------------------- ### Array Items Definition Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Demonstrates the requirement for an 'items' field in schemas with 'type: array'. The 'Good Example' correctly defines nested array items, while the 'Bad Example' omits it. ```yaml TheGoodModel: type: object properties: favoriteColorSets: type: array items: type: array items: {} ``` ```yaml TheBadModel: type: object properties: favoriteColorSets: type: array items: type: array ``` -------------------------------- ### Validating Media Examples in OpenAPI v2 Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Ensures that example values provided for media types match the type defined in the schema. Incorrect types or extra properties in examples will cause errors. ```yaml schemas: Pet: title: Pet type: object properties: id: type: integer name: type: string petType: type: string required: - id - name - petType ``` ```yaml paths: '/pet/{petId}': get: ... responses: '200': description: Pet Found schema: $ref: '#/definitions/Pet' examples: Get Pet Bubbles: id: 123 name: 'Bubbles' petType: 'dog' ``` ```yaml paths: '/pet/{petId}': get: ... responses: '200': description: Pet Found schema: $ref: '#/definitions/Pet' examples: Get Pet Bubbles: id: 123 name: 'Bubbles' petType: 123 ``` -------------------------------- ### Run Spectral in Browser (JavaScript) Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/3-javascript.md This example shows how to configure and run Spectral in a browser environment. It simulates file system access using a mock `fs` object and loads a ruleset from a string. ```javascript import { Spectral } from "@stoplight/spectral-core"; import { bundleAndLoadRuleset } from "@stoplight/spectral-ruleset-bundler/with-loader"; // create a ruleset that extends the spectral:oas ruleset const myRuleset = `extends: spectral:oas rules: {}`; // try to load an external ruleset const fs = { promises: { async readFile(filepath) { if (filepath === "/.spectral.yaml") { return myRuleset; } throw new Error(`Could not read ${filepath}`); }, }, }; const spectral = new Spectral(); s.setRuleset(await bundleAndLoadRuleset("/.spectral.yaml", { fs, fetch })); ``` -------------------------------- ### AsyncAPI v3 Tags Alphabetical Order - Bad Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md This example shows tags that are not in alphabetical order, which is not recommended for AsyncAPI v3 documents. ```yaml info: tags: - name: "Badger" - name: "Aardvark" ``` -------------------------------- ### Test Case with Custom Asset Example Source: https://github.com/stoplightio/spectral/blob/develop/test-harness/README.md Demonstrates using custom assets, such as a ruleset, within a test case. The asset is referenced in the command and its content is defined separately. ```text ====test==== assets real-life example ====document==== openapi: 3.0.0 info: version: 1.0.0 title: Stoplight paths: {} ====asset:ruleset==== extends: spectral:oas rules: oas3-api-servers: error ====command==== {bin} lint {document} -r {asset:ruleset} ====status==== 1 ====stdout==== OpenAPI 3.x detected {document} 1:1 error oas3-api-servers OpenAPI `servers` must be present and non-empty array. 1:1 warning openapi-tags OpenAPI object should have non-empty `tags` array. 2:6 warning info-contact Info object should contain `contact` object. 2:6 warning info-description OpenAPI object info `description` must be present and non-empty string. ✖ 4 problems (1 error, 3 warnings, 0 infos, 0 hints) ``` -------------------------------- ### AsyncAPI v3 Server Host - Bad Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Server host should not have a trailing slash. These examples show incorrectly formatted server hosts with trailing slashes. ```yaml servers: - host: mqtt://example.com/ - host: mqtt://example.com/broker/ ``` -------------------------------- ### Message Examples Validation Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md All `examples` within a message object must conform to the schemas defined for `payload` and `headers`. The bad example shows incorrect data types, while the good example demonstrates valid payload and headers. ```yaml asyncapi: "2.0.0" info: title: Bad API version: "1.0.0" components: messages: someMessage: payload: type: string headers: type: object examples: - payload: 2137 headers: someHeader ``` ```yaml asyncapi: "2.0.0" info: title: Good API version: "1.0.0" components: messages: someMessage: payload: type: string headers: type: object examples: - payload: foobar headers: someHeader: someValue ``` -------------------------------- ### Create HTTP and File Resolver with Proxy Agent Source: https://github.com/stoplightio/spectral/blob/develop/packages/ref-resolver/README.md Example usage of the ref resolver with proxy-agent for handling environment variables like PROXY. ```javascript import { createHttpAndFileResolver, Resolver } from '@stoplight/spectral-ref-resolver'; import ProxyAgent from import('proxy-agent'); module.exports = createHttpAndFileResolver({ agent: new ProxyAgent(process.env.PROXY) }); ``` -------------------------------- ### AsyncAPI Payload Examples Validation Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Validates that values in the examples array for a payload conform to the payload's schema. ```yaml payload: type: object properties: value: type: integer required: - value examples: - value: 13 - value: 17 ``` ```yaml payload: type: object properties: value: type: integer required: - value examples: - value: nope! # Wrong type - notGoodEither: 17 # Missing required property ``` -------------------------------- ### Load External Ruleset and Document (JavaScript) Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/3-javascript.md This example shows how to load an OpenAPI specification from a file and a YAML ruleset from an external file. It requires Node.js file system modules and `@stoplight/spectral-ruleset-bundler/with-loader`. Ensure `openapi.yaml` and `.spectral.yaml` exist in the project root. ```javascript import * as fs from "node:fs"; import { fileURLToPath } from "node:url"; import * as path from "node:path"; import { join } from "path"; import { bundleAndLoadRuleset } from "@stoplight/spectral-ruleset-bundler/with-loader"; import Parsers from "@stoplight/spectral-parsers"; // make sure to install the package if you intend to use default parsers! import spectralCore from "@stoplight/spectral-core"; const { Spectral, Document } = spectralCore; import spectralRuntime from "@stoplight/spectral-runtime"; const { fetch } = spectralRuntime; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const myDocument = new Document( // load an API specification file from your project's root directory. You can use the openapi.yaml example from here: https://github.com/stoplightio/Public-APIs/blob/master/reference/plaid/openapi.yaml fs.readFileSync(join(__dirname, "openapi.yaml"), "utf-8").trim(), Parsers.Yaml, "openapi.yaml", ); const spectral = new Spectral(); // load a ruleset file from your project's root directory. const rulesetFilepath = path.join(__dirname, ".spectral.yaml"); spectral.setRuleset(await bundleAndLoadRuleset(rulesetFilepath, { fs, fetch })); spectral.run(myDocument).then(console.log); ``` -------------------------------- ### Define a Custom Rule with Documentation URL Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4-custom-rulesets.md This example shows how to define a custom rule `no-http-basic` with a description, severity, and a specific `documentationUrl`. If a violation occurs, users will be directed to the provided URL for more information. ```yaml rules: no-http-basic: description: "Consider a more secure alternative to HTTP Basic." message: "HTTP Basic is a pretty insecure way to pass credentials around, please consider an alternative." severity: error given: $.components.securitySchemes[*] then: field: scheme function: pattern functionOptions: notMatch: basic ``` -------------------------------- ### Valid Schema Example in OpenAPI 3.0 Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Ensures that examples provided within Schema objects are valid against their defined schema. This is recommended for accurate data representation. ```yaml schemas: Pet: title: Pet type: object properties: id: type: integer example: 123 name: type: string example: Bubbles petType: type: string example: dog required: - id - name - petType ``` ```yaml schemas: Pet: title: Pet type: object properties: id: type: integer example: 123 name: type: string example: Bubbles petType: type: string example: 123 required: - name - petType ``` -------------------------------- ### Configure Parser Options Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4-custom-rulesets.md This example illustrates how to configure `parserOptions` within a ruleset to control the severity of duplicate keys and incompatible values. Note that `parserOptions` are not inherited by extended rulesets. ```yaml extends: spectral:oas parserOptions: duplicateKeys: warn # error is the default value incompatibleValues: off # error is the default value ``` -------------------------------- ### Function Options Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/5-custom-functions.md Demonstrates how to pass options to a custom function via the `functionOptions` property in a ruleset. The 'operation-id-kebab-case' rule uses the 'pattern' function with a 'match' option. ```yaml operation-id-kebab-case: given: "$..operationId" then: function: pattern functionOptions: # this object is passed down as options to the custom function match: ^[a-z][a-z0-9\-]*$ ``` -------------------------------- ### Legacy Spectral Ruleset (YAML) Source: https://github.com/stoplightio/spectral/blob/develop/packages/ruleset-migrator/README.md Example of a ruleset defined in the legacy YAML format. ```yaml # .spectral.yaml extends: spectral:oas formats: [oas2, json-schema-loose] rules: oas3-schema: warning valid-type: message: Type must be valid given: $..type then: function: pattern functionOptions: mustMatch: ^(string|number)$ ``` -------------------------------- ### AsyncAPI v3 Tags Uniqueness - Bad Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md This example demonstrates duplicate tag names, which is not allowed in AsyncAPI v3 documents. ```yaml info: tags: - name: "Badger" - name: "Badger" ``` -------------------------------- ### Migrate Spectral Core run() to Document API Source: https://github.com/stoplightio/spectral/blob/develop/docs/migration-guides/6.0.md Update your code to use the `Document` class instead of passing `documentUri` to `run`. This example shows how to instantiate `Document` with content, parser, and URI. ```typescript import { Document, Spectral } from "@stoplight/spectral-core"; import { Json as JsonParser } from "@stoplight/spectral-parsers"; import * as path from "@stoplight/path"; const s = new Spectral(); const doc = new Document( `{ "street": null }`, JsonParser, path.join(__dirname, "street-doc.json"), ); await spectral.run(doc); ``` -------------------------------- ### Configure GitLab CI for Spectral Docker image Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Example GitLab CI configuration to use the Spectral Docker image for validation. Sets the entrypoint to an empty string. ```yaml stages: - validate validate_open-api: stage: validate image: name: stoplight/spectral entrypoint: [""] script: - spectral lint file.yaml ``` -------------------------------- ### Migrated Spectral Ruleset (CommonJS) Source: https://github.com/stoplightio/spectral/blob/develop/packages/ruleset-migrator/README.md Example of a ruleset converted to the CommonJS JavaScript format. ```javascript // .spectral.js (CommonJS) const { oas: oas } = require("@stoplight/spectral-rulesets"); const { oas2: oas2, jsonSchemaLoose: jsonSchemaLoose } = require("@stoplight/spectral-formats"); const { pattern: pattern } = require("@stoplight/spectral-functions"); module.exports = { extends: oas, formats: [oas2, jsonSchemaLoose], rules: { "oas3-schema": "warning", "valid-type": { message: "Type must be valid", given: "$..type", then: { function: pattern, functionOptions: { mustMatch: "^(string|number)$", }, }, }, }, }; ``` -------------------------------- ### AsyncAPI v3 Tags Alphabetical Order - Good Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md AsyncAPI object should have alphabetical `tags` sorted by the `name` property for better readability and consistency. ```yaml info: tags: - name: "Aardvark" - name: "Badger" ``` -------------------------------- ### Migrated Spectral Ruleset (ES Module) Source: https://github.com/stoplightio/spectral/blob/develop/packages/ruleset-migrator/README.md Example of a ruleset converted to the ES Module JavaScript format. ```javascript // .spectral.js (ES Module) import { oas } from "@stoplight/spectral-rulesets"; import { oas2, jsonSchemaLoose } from "@stoplight/spectral-formats"; import { pattern } from "@stoplight/spectral-functions"; export default { extends: oas, formats: [oas2, jsonSchemaLoose], rules: { "oas3-schema": "warning", "valid-type": { message: "Type must be valid", given: "$..type", then: { function: pattern, functionOptions: { mustMatch: "^(string|number)$", }, }, }, }, }; ``` -------------------------------- ### JSON Formatter Output Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/2-cli.md This is an example of the JSON output format produced by Spectral when using the `-f json --quiet` flags. It details rule violations with code, path, message, severity, range, and source. ```json [ { "code": "invalid-response", "path": ["paths", "/users/{id}", "get", "responses", "200"], "message": "The '200' response should include a schema definition.", "severity": 2, "range": { "start": { "line": 32, "character": 12 }, "end": { "line": 35, "character": 14 } }, "source": "/Users/johndoe/projects/api-definition/openapi.yaml" } ] ``` -------------------------------- ### Lint a single file Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/2-cli.md Use this command to lint a single API document file. Ensure Spectral is installed and you have a ruleset available. ```bash spectral lint petstore.yaml ``` -------------------------------- ### Channel Server Reference Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Channel servers must be defined in the top-level `servers` object. The example shows a bad practice of referencing an undefined server and a good practice of referencing a defined one. ```yaml asyncapi: "2.0.0" info: title: Awesome API description: A very well-defined API version: "1.0" servers: production: url: "stoplight.io" protocol: "https" channels: hello: servers: - development ``` ```yaml asyncapi: "2.0.0" info: title: Awesome API description: A very well-defined API version: "1.0" servers: production: url: "stoplight.io" protocol: "https" channels: hello: servers: - production ``` -------------------------------- ### Custom File Resolver for Symlinks Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/8-tips-and-tricks.md Implement a custom file resolver to handle symlinked files during $ref resolution. This example uses Node.js 'fs' and '@stoplight/path' to resolve symlinks. ```javascript // my-resolver.js "use strict"; const fs = require("fs"); const path = require("@stoplight/path"); const { Resolver } = require("@stoplight/spectral-ref-resolver"); module.exports = new Resolver({ resolvers: { file: { async resolve(uri) { let ref = uri.href(); try { ref = path.join(path.dirname(ref), await fs.promises.readlink(ref, "utf8")); } catch (e) { if (e.code === "EINVAL") { // not a symlink } else { throw e; } } return fs.promises.readFile(ref, "utf8"); }, }, }, }); ``` -------------------------------- ### Basic Override Configuration Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4d-overrides.md Apply overrides to specific formats, files, and individual rules. This example targets JSON Schema Draft 7 files and customizes the 'valid-number-validation' rule. ```yaml overrides: formats: - json-schema-draft7 files: - schemas/**/*.draft7.json rules: valid-number-validation: given: - $..exclusiveMinimum - $..exclusiveMaximum then: function: schema functionOptions: type: number ``` -------------------------------- ### Extend Built-in Rulesets Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/3-rulesets.md Create a new ruleset file that extends Spectral's built-in OpenAPI, AsyncAPI, and Arazzo rulesets. This is a quick way to start linting with a comprehensive set of predefined rules. ```bash echo 'extends: ["spectral:oas", "spectral:asyncapi", "spectral:arazzo"]' > .spectral.yaml ``` -------------------------------- ### Ensure Arazzo Info Description Presence Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/arazzo-rules.md Requires the Arazzo object's info 'description' field to be present and non-empty. This field is crucial for providing detailed information, such as getting started guides and workflow explanations, to improve the consumer experience. ```yaml arazzo: 1.0.0 info: title: BNPL Workflow Description version: 1.0.0 description: | ## Overview This workflow guides the process of applying for a loan at checkout using a "Buy Now, Pay Later" (BNPL) platform. It orchestrates a series of API interactions to ensure a seamless and efficient loan application process, integrating multiple services across different API providers. ### Key Features - **Multi-step Loan Application:** The workflow includes multiple steps to check product eligibility, retrieve terms and conditions, create customer profiles, initiate the loan, and finalize the payment plan. - **Dynamic Decision Making:** Based on the API responses, the workflow adapts the flow, for example, skipping customer creation if the customer is already registered or ending the workflow if no eligible products are found. - **User-Centric:** The workflow handles both existing and new customers, providing a flexible approach to customer onboarding and loan authorization. ``` -------------------------------- ### Configure Ruleset for Async Forbidden Words Function Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/5-custom-functions.md Set up a ruleset to utilize the asynchronous 'dictionary' custom function. This example applies the rule to both the 'title' and 'description' fields within the 'info' object. ```yaml functions: - dictionary rules: no-evil-words: message: "{{error}}" given: - "$.info.title" - "$.info.description" then: function: "dictionary" ``` -------------------------------- ### Multiple 'then' Conditions for a Rule Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4a-rules.md This example shows how to define multiple 'then' conditions within a single rule. Each condition checks for a specific property ('name', 'url', 'email') using the 'truthy' function, ensuring the Contact object has all required fields. ```yaml contact-properties: description: Contact object must have "name", "url", and "email". given: $.info.contact severity: warn then: - field: name function: truthy - field: url function: truthy - field: email function: truthy ``` -------------------------------- ### Typed Enum Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Ensures enum values match the specified type. The 'Good Example' shows correct integer enums, while the 'Bad Example' includes a string in an integer enum. ```yaml TheGoodModel: type: object properties: number_of_connectors: type: integer description: The number of extension points. enum: - 1 - 2 - 4 - 8 ``` ```yaml TheBadModel: type: object properties: number_of_connectors: type: integer description: The number of extension points. enum: - 1 - 2 - "a string!" - 8 ``` -------------------------------- ### Run Tests and Build Binary Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Execute project tests and build the binary for the Spectral CLI. Ensure all tests pass after making changes. ```bash yarn test ``` ```bash yarn workspace @stoplight/spectral-cli build.binary && yarn test.harness ``` -------------------------------- ### Create Spectral JavaScript File Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4f-js-rulesets.md Create the main JavaScript file that will contain your Spectral ruleset. ```bash touch spectral.js ``` -------------------------------- ### AsyncAPI v2 Info License with URL Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Recommends including a 'url' for the 'license' object in AsyncAPI v2 to provide a link to the full license text. ```yaml asyncapi: "2.0.0" info: license: name: MIT url: https://www.tldrlegal.com/l/mit ``` -------------------------------- ### Validating Example Values in OpenAPI v3 Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Ensures that requestBody or response examples use either `value` or `externalValue`, but not both. Using both can lead to ambiguity and errors. ```yaml paths: /pet: put: operationId: "replace-pet" requestBody: content: "application/json": examples: foo: summary: A foo example value: { "foo": "bar" } externalValue: "http://example.org/foo.json" # marp! no, can only have one or the other ``` -------------------------------- ### Create JavaScript Ruleset Folder Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4f-js-rulesets.md Use these terminal commands to set up the directory structure for your JavaScript ruleset. ```bash mkdir style-guide cd style-guide ``` -------------------------------- ### Load and Bundle Spectral Ruleset Source: https://github.com/stoplightio/spectral/blob/develop/packages/ruleset-bundler/README.md Use `bundleAndLoadRuleset` to load and bundle a Spectral ruleset file. Ensure necessary modules like `fs`, `path`, and `fetch` are provided. ```javascript // spectral.mjs import * as fs from "node:fs"; import { fileURLToPath } from "node:url"; import * as path from "node:path"; import { Spectral } from "@stoplight/spectral-core"; import { bundleAndLoadRuleset } from "@stoplight/spectral-ruleset-bundler/with-loader"; import { fetch } from "@stoplight/spectral-runtime"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const s = new Spectral(); s.setRuleset(await bundleAndLoadRuleset(path.join(__dirname, ".spectral.yaml"), { fs, fetch })); // lint as usual ``` -------------------------------- ### Unique Operation IDs Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md The `operationId` field must be unique across all operations, excluding those defined in components. The bad example shows duplicate `operationId` values, while the good example demonstrates unique IDs. ```yaml channels: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: publish: operationId: turn smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: publish: operationId: turn ``` ```yaml channels: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: publish: operationId: turnOn smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: publish: operationId: turnOff ``` -------------------------------- ### Unique Message IDs Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md The `messageId` field must be unique across all messages, excluding those defined in components. The bad example shows duplicate `messageId` values, while the good example demonstrates unique IDs. ```yaml channels: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: publish: message: messageId: turnMessage smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: publish: message: messageId: turnMessage ``` ```yaml channels: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: publish: message: messageId: turnOnMessage smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: publish: message: messageId: turnOffMessage ``` -------------------------------- ### Run Harness Tests Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Execute harness tests, which are critical and must pass for PR merges. Ensure the code is built beforehand using `yarn build` and `yarn workspace @stoplight/spectral-cli build.binary` if necessary. ```bash # make sure to build the code beforehand if you haven't done it. To do so execute yarn build && yarn workspace @stoplight/spectral-cli build.binary yarn test.harness ``` -------------------------------- ### Extend npm Package Ruleset Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/7-sharing-rulesets.md Reference an installed npm package as a Spectral ruleset in your configuration. ```yaml extends: - example-spectral-ruleset ``` -------------------------------- ### Run All Tests Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Execute all tests in the project, covering both Node.js and browser environments. This is the primary command for verifying code correctness. ```bash yarn test ``` -------------------------------- ### Lint file using Spectral Docker image Source: https://github.com/stoplightio/spectral/blob/develop/docs/getting-started/2-installation.md Runs Spectral linting on a file within a Docker container. Mount the current directory as a volume and specify the ruleset and file paths. ```bash # make sure to update the value of `--ruleset` according to the actual location of your ruleset docker run --rm -it -v $(pwd):/tmp stoplight/spectral lint --ruleset "/tmp/.spectral.js" "/tmp/file.yaml" ``` -------------------------------- ### Run Spectral CLI Locally Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Execute the Spectral CLI from your local build to lint an OpenAPI specification file using a specified ruleset. ```bash node ./packages/cli/dist/index.js lint [openapi_spec_file] --ruleset /path/to/ruleset.yaml ``` -------------------------------- ### Extend npm Package via CDN Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/7-sharing-rulesets.md Use a CDN like unpkg.com to reference an npm package ruleset without local installation. ```yaml extends: - "https://unpkg.com/example-spectral-ruleset@0.2.0" ``` -------------------------------- ### Run All Linters Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Execute all configured linters to check code quality across the project. This command ensures adherence to project-wide linting standards. ```bash yarn lint ``` -------------------------------- ### Extend and Override Rules Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4b-extends.md Combine `extends` with the `rules` property to override existing rules or add new ones. This example overrides the `tag-description` rule. ```yaml extends: spectral:oas rules: tag-description: description: Please provide a description for each tag. given: $.tags[*] then: field: description function: truthy ``` -------------------------------- ### Add Descriptions to AsyncAPI Tags Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Tags alone are not very descriptive. Provide a `description` for each tag to offer more context. This is particularly useful for business objects. ```yaml info: tags: - name: "Aardvark" description: Funny-nosed pig-head raccoon. - name: "Badger" description: Angry short-legged omnivores. ``` ```yaml info: tags: - name: Invoice Items description: | Giant long explanation about what this business concept is, because other people _might_ not have a clue! ``` -------------------------------- ### Server URL Formatting in OpenAPI v3 Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Ensures server URLs do not have a trailing slash to prevent issues when joining with paths. Both examples show valid formats. ```yaml servers: - url: https://example.com - url: https://example.com/api ``` ```yaml servers: - url: https://example.com/ - url: https://example.com/api/ ``` -------------------------------- ### Change Rule Severity Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4b-extends.md Easily change the severity of a rule from an extended ruleset by specifying the new severity level directly. This example changes `operation-success-response` to `warn`. ```yaml extends: spectral:oas rules: operation-success-response: warn ``` -------------------------------- ### Run Selected Tests with Jest CLI Options Source: https://github.com/stoplightio/spectral/blob/develop/test-harness/README.md Execute specific tests by providing paths to the test-harness command. This leverages Jest's CLI options for flexible test selection. ```bash yarn test.harness test-harness/tests/require-module ``` -------------------------------- ### Lint with Remote Ruleset via CLI Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/7-sharing-rulesets.md Use the Spectral CLI to lint a target with a ruleset specified by a URL. ```shell spectral lint -r https://example.com/some-ruleset.yml ``` -------------------------------- ### Load JavaScript Ruleset (JavaScript) Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/3-javascript.md This snippet demonstrates how to load a custom ruleset written in JavaScript. The ruleset is imported as a module, and then applied to the Spectral instance. ```javascript import { Spectral } from "@stoplight/spectral-core"; import ruleset from "./my-javascript-ruleset"; const spectral = new Spectral(); spectral.setRuleset(ruleset); ``` -------------------------------- ### Load Ruleset from HTTP URL Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/7-sharing-rulesets.md Reference a ruleset hosted on an HTTP server directly in your configuration. ```yaml extends: - https://example.com/company-ruleset.yaml ``` -------------------------------- ### Override Caveat: Extended Rulesets (extends) Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4d-overrides.md Illustrates how to use JS rulesets to inherit overrides when extended rulesets do not support them directly. This example shows 'rulesetB' inheriting overrides from 'rulesetA'. ```javascript import rulesetA from './ruleset'; export default { extends: rulesetA, overrides: rulesetA.overrides, }; ``` -------------------------------- ### CircleCI Configuration for Spectral Linting Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/8-continuous-integration.md Configure a CircleCI job to run Spectral linting on your OpenAPI specification. This example uses the JUnit format for test results, which can be displayed in the CI interface. ```yaml version: 2.1 orbs: node: circleci/node@4.1 jobs: lint: docker: - image: cimg/node:15.1 steps: # Checkout the code as the first step. - checkout # Create a folder for results to live in - run: "[ -d lint-results ] || mkdir lint-results" - run: name: Run Spectral Lint command: npx @stoplight/spectral-cli lint openapi.yaml -o lint-results/junit.xml -f junit - store_test_results: path: lint-results workflows: sample: jobs: - lint ``` -------------------------------- ### Configuring Servers in OpenAPI v3 Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md Specifies the base URLs for API operations. It's recommended to include production, staging, and development servers for comprehensive access. ```yaml servers: - url: https://example.com/api description: Production server - url: https://staging.example.com/api description: Staging server - url: http://localhost:3001 description: Development server ``` -------------------------------- ### Outputting Each Format to Stdout Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/2-cli.md To output each specified format to stdout, use the '' filename for each format's respective `-o` flag. ```bash spectral lint "specs/**/*.yaml" -f text -f stylish -o.text "" -o.stylish "" ``` -------------------------------- ### Generate OpenAPI Spec and Lint with Spectral Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/1-workflows.md Use this command when following a code-first workflow and your API description documents are embedded as comments or annotations within your code. It first generates an OpenAPI JSON file using go-swagger and then lints the generated file with Spectral. ```bash swagger generate spec -o ./tmp/openapi.json && spectral lint ./tmp/openapi.json ``` -------------------------------- ### AsyncAPI v2 Info License Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Requires the 'license' key within the 'info' object for AsyncAPI v2 documents, encouraging the specification of an API license. ```yaml asyncapi: "2.0.0" info: license: name: MIT ``` -------------------------------- ### Lint files using glob syntax Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/2-cli.md Use glob patterns to match and lint multiple files that conform to a specific naming convention or directory structure. ```bash spectral lint ./reference/**/*.oas*.{json,yml,yaml} ``` -------------------------------- ### Custom $ref Resolver Example Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/2-cli.md This JavaScript code defines a custom JSON $ref resolver using the @stoplight/json-ref-resolver library. It exports a new Resolver instance, allowing customization of how $ref pointers are resolved. ```javascript const { Resolver } = require("@stoplight/json-ref-resolver"); module.exports = new Resolver({ resolvers: { // pass any resolver for the protocol you need }, }); ``` -------------------------------- ### Test Case Template Source: https://github.com/stoplightio/spectral/blob/develop/test-harness/README.md Use this template to define new test cases. It includes sections for test description, document content, command to execute, expected stdout, and optional stderr or status code. ```text ====test==== Test text, can be multi line. ====document==== some JSON/YAML document ====command==== {bin} lint --foo {document} --bar ====stdout==== expected output ====stderr==== optional/alternative to stdout for expected errors ====status==== (optional) expected exit code (`0` or `1`) ``` -------------------------------- ### Override with Encoded JSON Pointer Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/4d-overrides.md Example demonstrating an override targeting a specific parameter within a file path using an encoded JSON Pointer. Special characters like '/' are encoded as '~1'. ```yaml overrides: - files: - "legacy/**/*.oas.json#/paths/~1Pets~1%7BpetId%7D/get/parameters/0" rules: some-inherited-rule: "off" ``` -------------------------------- ### Serve Mocked Assets for Tests Source: https://github.com/stoplightio/spectral/blob/develop/CONTRIBUTING.md Mock HTTP requests and file system reads within tests using `serveAssets`. This utility is compatible with both Karma and Jest test runners and is useful for setting up test environments. ```typescript import { serveAssets } from '@stoplight/spectral-test-utils'; import * as path from '@stoplight/path'; const cwd = '/tmp/some-fake-path'; serveAssets({ 'https://library.com/defs.json': { components: { schemas: { ExternalHttp: { type: 'number', }, }, }, }, [path.join(cwd, 'file.json')]: { openapi: '3.1.0', info: { title: 'Test file', }, paths: {}, }, }) ``` -------------------------------- ### Use Custom Resolver with Spectral JavaScript Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/3-javascript.md Implement a custom JSON reference resolver for Spectral to handle additional protocols or adjust resolution logic. This example resolves file refs relative to the current working directory. ```javascript const path = require("path"); const fs = require("fs"); const { Spectral } = require("@stoplight/spectral-cli"); const { Resolver } = require("@stoplight/json-ref-resolver"); const customFileResolver = new Resolver({ resolvers: { file: { resolve: ref => { return new Promise((resolve, reject) => { const basePath = process.cwd(); const refPath = ref.path(); fs.readFile(path.join(basePath, refPath), "utf8", (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); }, }, }, }); const spectral = new Spectral({ resolver: customFileResolver }); // ... load document // ... lint document - $refs and rules will be requested using the proxy ``` -------------------------------- ### Load Ruleset from GitHub Raw URL Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/7-sharing-rulesets.md Include rulesets hosted on GitHub by using their raw content URLs. ```yaml # why not give this one a try! 🥳 extends: - https://raw.githubusercontent.com/openapi-contrib/style-guides/master/apisyouwonthate.yml ``` -------------------------------- ### Implement Async Custom Function for Forbidden Words Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/5-custom-functions.md Develop an asynchronous custom function that fetches a list of forbidden words from an external service and checks if the input contains any of them. This example uses `fetch` and caches the dictionary to avoid repeated requests. ```javascript const CACHE_KEY = "dictionary"; let dictionary; export default async function (input) { if (!dictionary) { const res = await fetch("https://dictionary.com/evil"); if (res.ok) { dictionary = await res.json(); } else { // you can either re-try or just throw an error } } if (dictionary.includes(input)) { return [{ message: `\`${input}\` is a forbidden word.` }]; } } ``` -------------------------------- ### Using Custom Resolver with Spectral CLI Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/8-tips-and-tricks.md Instruct the Spectral CLI to use a custom resolver by specifying the resolver file path. ```bash spectral lint --resolver my-resolver.js my-document ``` -------------------------------- ### Configure Husky Git Hooks for Spectral Linting Source: https://github.com/stoplightio/spectral/blob/develop/docs/guides/1-workflows.md Set up pre-commit and pre-push Git hooks using Husky to automatically lint your API reference files before committing or pushing. This ensures that all API description files adhere to your ruleset. ```json // package.json { "husky": { "hooks": { "pre-commit": "spectral lint ./reference/**/*.{json,yml,yaml}", "pre-push": "spectral lint ./reference/**/*.{json,yml,yaml}", "...": "..." } } } ``` -------------------------------- ### AsyncAPI v2 Info Description Source: https://github.com/stoplightio/spectral/blob/develop/docs/reference/asyncapi-rules.md Mandates the presence of a non-empty 'description' in the 'info' object for AsyncAPI v2 documents, allowing for detailed API explanations. ```yaml asyncapi: "2.0.0" info: version: "1.0.0" title: Descriptive API description: >+ Some description about the general point of this API, and why it exists when another similar but different API also exists. ```