From 671ebbad5dc1de959efcca43c41c6dba5d6da296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Mon, 28 Oct 2019 13:19:00 +0100 Subject: [PATCH 1/3] feat: remove addRules and addFunctions --- docs/getting-started/rulesets.md | 1 + docs/guides/javascript.md | 137 ------------------------------- src/spectral.ts | 21 +---- 3 files changed, 2 insertions(+), 157 deletions(-) diff --git a/docs/getting-started/rulesets.md b/docs/getting-started/rulesets.md index 9052e852f..05e16188b 100644 --- a/docs/getting-started/rulesets.md +++ b/docs/getting-started/rulesets.md @@ -18,6 +18,7 @@ rules: function: truthy ``` +Spectral has a built-in set of functions which you can reference in your rules. This example uses the `truthy` to create a rule that checks that the value is true. The example above adds a single rule that checks that tags objects have a description property defined. Running `spectral lint` on the following object with the ruleset above will result in an error being reported, since the tag does not have a description: diff --git a/docs/guides/javascript.md b/docs/guides/javascript.md index 0dbf49b6e..955870cda 100644 --- a/docs/guides/javascript.md +++ b/docs/guides/javascript.md @@ -180,143 +180,6 @@ The OpenAPI rules are opinionated. There might be some rules that you prefer to ## Advanced -### Creating a custom rule - -Spectral has a built-in set of functions which you can reference in your rules. This example uses the `RuleFunction.PATTERN` to create a rule that checks that all property values are in snake case. - -```javascript -const { Spectral } = require('@stoplight/spectral'); - -const spectral = new Spectral(); - -spectral.addRules({ - snake_case: { - description: 'Checks for snake case pattern', - - // evaluate every property - given: '$..*', - - then: { - function: 'pattern', - functionOptions: { - match: '^[a-z]+[a-z0-9_]*[a-z0-9]+$', - }, - }, - }, -}); - -// run! -spectral.run({name: 'helloWorld',}).then(results => { - console.log(results); -}); -``` - -[Try it out!](https://repl.it/@ChrisMiaskowski/spectral-pattern-example) - -```bash -[ - { - "code": "snake_case", - "message": "Checks for snake case pattern", - "path": [ - "name" - ], - "severity": 1, - "range": { - "start": { - "line": 1, - "character": 10 - }, - "end": { - "line": 1, - "character": 22 - } - } - } -] -``` - -### Creating a custom function - -Sometimes the built-in functions don't cover your use case. This example creates a custom function, `customNotThatFunction`, and then uses it within a rule, `openapi_not_swagger`. The custom function checks that you are not using a specific string (e.g., "Swagger") and suggests what to use instead (e.g., "OpenAPI"). - -```javascript -const { Spectral } = require('@stoplight/spectral'); - -// custom function -const customNotThatFunction = (targetValue, options) => { - const { match, suggestion } = options; - - if (targetValue && targetValue.match(new RegExp(match))) { - // return the single error - return [ - { - message: `Use ${suggestion} instead of ${match}!`, - }, - ]; - } -}; - -const spectral = new Spectral(); - -spectral.addFunctions({ - notThat: customNotThatFunction, -}); - -spectral.addRules({ - openapi_not_swagger: { - description: 'Checks for use of Swagger, and suggests OpenAPI.', - - // check every property - given: '$..*', - - then: { - // reference the function we added! - function: 'notThat', - - // pass it the options it needs - functionOptions: { - match: 'Swagger', - suggestion: 'OpenAPI', - }, - }, - }, -}); - -// run! -spectral.run({description: 'Swagger is pretty cool!',}).then(results => { - console.log(JSON.stringify(results, null, 4)); -}); -``` - -[Try it out!](https://repl.it/@ChrisMiaskowski/spectral-custom-function-example) - -```bash -# Outputs a single result since we are using the term `Swagger` in our object -[ - { - "code": "openapi_not_swagger", - "message": "Checks for use of Swagger, and suggests OpenAPI.", - "path": [ - "description" - ], - "severity": 1, - "range": { - "start": { - "line": 1, - "character": 17 - }, - "end": { - "line": 1, - "character": 42 - } - } - } -] -``` - -For more information on creating rules, read about [rulesets](../getting-started/rulesets.md). - ### Creating a custom format Spectral supports two core formats: `oas2` and `oas3`. Using `registerFormat` you can add support for autodetecting other formats. You might want to do this for a ruleset which is run against multiple major versions of description format like RAML v0.8 and v1.0. diff --git a/src/spectral.ts b/src/spectral.ts index 38ebdc821..02572dacb 100644 --- a/src/spectral.ts +++ b/src/spectral.ts @@ -13,7 +13,6 @@ import { parseWithPointers as parseYAMLWithPointers, YamlParserResult, } from '@stoplight/yaml'; -import deprecated from 'deprecated-decorator'; import { merge, set } from 'lodash'; import { STATIC_ASSETS } from './assets'; @@ -132,33 +131,15 @@ export class Spectral { return (await this.runWithResolved(target, opts)).results; } - @deprecated('loadRuleset', '4.1') - public addFunctions(functions: FunctionCollection) { - this._addFunctions(functions); - } - - public _addFunctions(functions: FunctionCollection) { - Object.assign(this.functions, functions); - } - public setFunctions(functions: FunctionCollection) { empty(this.functions); - this._addFunctions({ ...defaultFunctions, ...functions }); - } - - @deprecated('loadRuleset', '4.1') - public addRules(rules: RuleCollection) { - this._addRules(rules); + Object.assign(this.functions, { ...defaultFunctions, ...functions }); } public setRules(rules: RuleCollection) { empty(this.rules); - this._addRules({ ...rules }); - } - - private _addRules(rules: RuleCollection) { for (const name in rules) { if (!rules.hasOwnProperty(name)) continue; const rule = rules[name]; From b56fb6c77a098254001227dd159318baeb0f9495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Mon, 28 Oct 2019 13:31:24 +0100 Subject: [PATCH 2/3] chore: remove entry points --- docs/migration-guides/5.0.md | 51 ++++++++++++++++++++++++++++++++++++ src/rulesets/oas/index.ts | 21 --------------- src/rulesets/oas2/index.ts | 8 ------ src/rulesets/oas3/index.ts | 8 ------ 4 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 docs/migration-guides/5.0.md delete mode 100644 src/rulesets/oas/index.ts delete mode 100644 src/rulesets/oas2/index.ts delete mode 100644 src/rulesets/oas3/index.ts diff --git a/docs/migration-guides/5.0.md b/docs/migration-guides/5.0.md new file mode 100644 index 000000000..f354dd3b2 --- /dev/null +++ b/docs/migration-guides/5.0.md @@ -0,0 +1,51 @@ +# Spectral v4 to v5 Migration Guide + +Our docs have been updated, so you can always refer to them. To make the transition less painful, +this migration guide covers the most notable changes. + +### I use Spectral programmatically via API... + +1. addFunctions and addRules have been removed + +We strongly encourage everyone to write rulesets, therefore the new preferred way to load a ruleset is via `loadRuleset`. + +**Spectral v4**: + +```js +const { oas3Functions, rules: oas3Rules } = require('@stoplight/spectral/dist/rulesets/oas3'); + +const spectral = new Spectral(); +spectral.addFunctions(oas3Functions); +spectral.addFunctions(oas3Rules); +spectral.run(myOpenApiDocument) + .then(results => { + console.log('here are the results', results); + }); +``` + +**Spectral v5**: + +```js +const { Spectral } = require('@stoplight/spectral'); + +const spectral = new Spectral(); +spectral.loadRuleset('spectral:oas') + .then(() => spectral.run(myOpenApiDocument)) + .then(results => { + console.log('here are the results', results); + }); +``` + +Alternatively, if your ruleset is stored in a plain JSON file, you can also consider using `setRuleset`, as follows + +```js +const { Spectral } = require('@stoplight/spectral'); +const ruleset = require('./my-ruleset.json'); + +const spectral = new Spectral(); +spectral.setRuleset(ruleset); +spectral.run(myOpenApiDocument) + .then(results => { + console.log('here are the results', results); + }); +``` diff --git a/src/rulesets/oas/index.ts b/src/rulesets/oas/index.ts deleted file mode 100644 index aeb7f2495..000000000 --- a/src/rulesets/oas/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { FunctionCollection } from '../../types'; -import { readRuleset } from '../reader'; - -export const commonOasFunctions = (): FunctionCollection => { - console.warn('This is deprecated. Use loadRuleset method instead'); - return { - oasPathParam: require('./functions/oasPathParam').oasPathParam, - oasOp2xxResponse: require('./functions/oasOp2xxResponse').oasOp2xxResponse, - oasOpSecurityDefined: require('./functions/oasOpSecurityDefined').oasOpSecurityDefined, // used in oas2/oas3 differently see their rulesets for details - oasOpIdUnique: require('./functions/oasOpIdUnique').oasOpIdUnique, - oasOpFormDataConsumeCheck: require('./functions/oasOpFormDataConsumeCheck').oasOpFormDataConsumeCheck, - oasOpParams: require('./functions/oasOpParams').oasOpParams, - oasTagDefined: require('./functions/oasTagDefined').oasTagDefined, - refSiblings: require('./functions/refSiblings').refSiblings, - }; -}; - -export const rules = async () => { - console.warn('This is deprecated. Use loadRuleset method instead'); - return (await readRuleset(require.resolve('./index.json'))).rules; -}; diff --git a/src/rulesets/oas2/index.ts b/src/rulesets/oas2/index.ts deleted file mode 100644 index 63c90f877..000000000 --- a/src/rulesets/oas2/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { readRuleset } from '../reader'; - -export { commonOasFunctions as oas2Functions } from '../oas'; - -export const rules = async () => { - console.warn('This is deprecated. Use loadRuleset method instead'); - return (await readRuleset(require.resolve('./index.json'))).rules; -}; diff --git a/src/rulesets/oas3/index.ts b/src/rulesets/oas3/index.ts deleted file mode 100644 index 30f7de450..000000000 --- a/src/rulesets/oas3/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { readRuleset } from '../reader'; - -export { commonOasFunctions as oas3Functions } from '../oas'; - -export const rules = async () => { - console.warn('This is deprecated. Use loadRuleset method instead'); - return (await readRuleset(require.resolve('./index.json'))).rules; -}; From 4331b600c7a32e15bf73a6e51ed34813884586ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Tue, 29 Oct 2019 00:52:39 +0100 Subject: [PATCH 3/3] docs: improve --- docs/getting-started/rulesets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/rulesets.md b/docs/getting-started/rulesets.md index 05e16188b..aa2b6ac59 100644 --- a/docs/getting-started/rulesets.md +++ b/docs/getting-started/rulesets.md @@ -18,7 +18,7 @@ rules: function: truthy ``` -Spectral has a built-in set of functions which you can reference in your rules. This example uses the `truthy` to create a rule that checks that the value is true. +Spectral has a built-in set of functions such as `truthy` or `pattern`, which you can reference in your rules. The example above adds a single rule that checks that tags objects have a description property defined. Running `spectral lint` on the following object with the ruleset above will result in an error being reported, since the tag does not have a description: