Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feat/cli/rich-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Mar 3, 2022
2 parents 2b5b9c3 + a3ba1a9 commit d77d987
Show file tree
Hide file tree
Showing 41 changed files with 1,392 additions and 1,735 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/__fixtures__/**
/test-harness/**/*.yaml
/packages/*/dist
/packages/*/CHANGELOG.md
Empty file added __karma__/perf_hooks.js
Empty file.
2 changes: 1 addition & 1 deletion __karma__/process.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default undefined;
export const on = Function();
49 changes: 32 additions & 17 deletions docs/guides/4-custom-rulesets.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,38 +402,53 @@ Rulesets can then reference aliases in the [given](#given) keyword, either in fu

Previously Spectral supported exceptions, which were limited in their ability to target particular rules on specific files or parts of files, or changing parts of a rule. Overrides is the much more powerful version of exceptions, with the ability to customize ruleset usage for different files and projects without having to duplicate any rules.

Overrides can be used to:
Overrides can be used to apply rulesets on:

- Override rulesets to apply on particular files/folders `files: ['schemas/**/*.draft7.json']`
- Override rulesets to apply on particular JSONPath's `files: ['**#/components/schemas/Item']`
- Override rulesets to apply on particular formats `formats: [jsonSchemaDraft7]`
- Particular formats `formats: [jsonSchemaDraft7]`
- Particular files/folders `files: ['schemas/**/*.draft7.json']`
- Particular elements of files `files: ['**#/components/schemas/Item']`
- Override particular rules

**Example**

```yaml
overrides:
formats:
- json-schema-draft7
files:
- schemas/**/*.draft7.json
rules:
valid-number-validation:
given:
- $..exclusiveMinimum
- $..exclusiveMaximum
then:
function: schema
functionOptions:
type: number
```

To apply an override to particular elements of files, combine a glob for a filepath
with a [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) after the anchor, i.e.:

```yaml
overrides:
- files:
- schemas/**/*.draft7.json
formats:
- json-schema-draft7
- "legacy/**/*.oas.json#/paths"
rules:
valid-number-validation:
given:
- $..exclusiveMinimum
- $..exclusiveMaximum
then:
function: schema
functionOptions:
type: number
some-inherited-rule: "off"
```

One can also combine a glob for a filepath with a JSONPath after the anchor, i.e.:
JSON Pointers have a different syntax than JSON Paths used in the `given` component of a rule.
In JSON Pointers, path components are prefixed with a "/" and then concatenated to form the pointer.
Since "/" has a special meaning in JSON pointer, it must be encoded as "~1" when it appears in a component, and "~" must be encoded as "~0".

You can test JSON Pointer expressions in the [JSON Query online evaluator](https://www.jsonquerytool.com/) by choosing "JSONPointer" as the Transform.

```yaml
overrides:
- files:
- "legacy/**/*.oas.json#/paths"
- "legacy/**/*.oas.json#/paths/~1Pets~1{petId}/get/parameters/0"
rules:
some-inherited-rule: "off"
```
Expand Down
3 changes: 2 additions & 1 deletion karma.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = (config: Config): void => {
files: ['./__karma__/jest.ts', 'packages/*/src/**/*.ts'],

// list of files / patterns to exclude
exclude: ['packages/cli/**', '**/*.jest.test.ts'],
exclude: ['packages/cli/**', 'packages/ruleset-bundler/src/plugins/commonjs.ts', '**/*.jest.test.ts'],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
Expand All @@ -41,6 +41,7 @@ module.exports = (config: Config): void => {
'node-fetch': require.resolve('./__karma__/fetch'),
fs: require.resolve('./__karma__/fs'),
process: require.resolve('./__karma__/process'),
perf_hooks: require.resolve('./__karma__/perf_hooks'),
fsevents: require.resolve('./__karma__/fsevents'),
},
},
Expand Down
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@
"lint": "yarn lint.prettier && yarn lint.eslint",
"lint.fix": "yarn lint.prettier --write && yarn lint.eslint --fix",
"lint.eslint": "eslint --cache --cache-location .cache/.eslintcache --ext=.js,.mjs,.ts packages test-harness",
"lint.prettier": "prettier --ignore-path .eslintignore --ignore-unknown --check packages/core/src/meta/*.json packages/rulesets/src/{asyncapi,oas}/schemas/*.json packages/*/CHANGELOG.md docs/**/*.md README.md",
"lint.prettier": "prettier --ignore-path .eslintignore --ignore-unknown --check packages/core/src/meta/*.json packages/rulesets/src/{asyncapi,oas}/schemas/*.json docs/**/*.md README.md",
"pretest": "yarn workspace @stoplight/spectral-ruleset-migrator pretest",
"test": "yarn pretest && yarn test.karma && yarn test.jest",
"test.harness": "jest -c ./test-harness/jest.config.js",
"test.jest": "jest --silent --cacheDirectory=.cache/.jest",
"test.karma": "karma start",
"prepare": "husky install",
"prerelease": "patch-package",
"release": "yarn prerelease && HUSKY=0 yarn workspaces foreach run release"
"release": "yarn prerelease && yarn workspaces foreach run release"
},
"workspaces": {
"packages": [
Expand Down Expand Up @@ -100,7 +100,7 @@
"node-powershell": "^4.0.0",
"patch-package": "^6.4.7",
"prettier": "^2.4.1",
"semantic-release": "^19.0.2",
"semantic-release": "^18.0.1",
"semantic-release-monorepo": "^7.0.5",
"ts-jest": "^27.0.7",
"ts-node": "^10.4.0",
Expand All @@ -110,9 +110,6 @@
"*.{ts,js}": [
"eslint --fix --cache --cache-location .cache/.eslintcache"
],
"packages/*/CHANGELOG.md": [
"prettier --write"
],
"docs/**/*.md": [
"prettier --ignore-path .eslintignore --write"
],
Expand Down
6 changes: 6 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# [@stoplight/spectral-core-v1.10.2](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-core-v1.10.1...@stoplight/spectral-core-v1.10.2) (2022-02-24)

### Bug Fixes

- bump nimma from 0.1.7 to 0.1.8 ([#2058](https://github.com/stoplightio/spectral/issues/2058)) ([fb756f2](https://github.com/stoplightio/spectral/commit/fb756f2e582e533d79c1ac3ed5cef2e8f8b1b299))

# [@stoplight/spectral-core-v1.10.1](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-core-v1.10.0...@stoplight/spectral-core-v1.10.1) (2022-02-14)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/spectral-core",
"version": "1.10.1",
"version": "1.10.2",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"sideEffects": false,
Expand Down
6 changes: 6 additions & 0 deletions packages/formats/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# [@stoplight/spectral-formats-v1.1.0](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-formats-v1.0.2...@stoplight/spectral-formats-v1.1.0) (2022-02-24)

### Features

- support 2.1.0, 2.2.0, 2.3.0 AsyncAPI versions ([#2067](https://github.com/stoplightio/spectral/issues/2067)) ([b0b008d](https://github.com/stoplightio/spectral/commit/b0b008d65794df177dbfe7d9589c90d541c2794d))

# [@stoplight/spectral-formats-v1.0.2](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-formats-v1.0.1...@stoplight/spectral-formats-v1.0.2) (2021-12-30)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/formats/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/spectral-formats",
"version": "1.0.2",
"version": "1.1.0",
"sideEffects": false,
"homepage": "https://github.com/stoplightio/spectral",
"bugs": "https://github.com/stoplightio/spectral/issues",
Expand Down
61 changes: 54 additions & 7 deletions packages/formats/src/__tests__/asyncapi.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { asyncApi2 } from '../asyncapi';
import { aas2, aas2_0, aas2_1, aas2_2, aas2_3 } from '../asyncapi';

describe('AsyncApi format', () => {
describe('AsyncApi 2.{minor}.{patch}', () => {
it.each([['2.0.17'], ['2.9.0'], ['2.9.3']])('recognizes %s version correctly', (version: string) => {
expect(asyncApi2({ asyncapi: version }, null)).toBe(true);
});
describe('AsyncAPI format', () => {
describe('AsyncAPI 2.x', () => {
it.each(['2.0.0', '2.1.0', '2.2.0', '2.3.0', '2.0.17', '2.1.37', '2.9.0', '2.9.3'])(
'recognizes %s version correctly',
version => {
expect(aas2({ asyncapi: version }, null)).toBe(true);
},
);

const testCases = [
{ asyncapi: '3.0' },
Expand All @@ -15,6 +18,7 @@ describe('AsyncApi format', () => {
{ asyncapi: '2.0.01' },
{ asyncapi: '1.0' },
{ asyncapi: 2 },
{ asyncapi: null },
{ openapi: '4.0' },
{ openapi: '2.0' },
{ openapi: null },
Expand All @@ -25,7 +29,50 @@ describe('AsyncApi format', () => {
];

it.each(testCases)('does not recognize invalid document %o', document => {
expect(asyncApi2(document, null)).toBe(false);
expect(aas2(document, null)).toBe(false);
});
});

describe('AsyncAPI 2.0', () => {
it.each(['2.0.0', '2.0.3'])('recognizes %s version correctly', version => {
expect(aas2_0({ asyncapi: version }, null)).toBe(true);
});

it.each(['2', '2.0', '2.1.0', '2.1.3'])('does not recognize %s version', version => {
expect(aas2_0({ asyncapi: version }, null)).toBe(false);
});
});

describe('AsyncAPI 2.1', () => {
it.each(['2.1.0', '2.1.37'])('recognizes %s version correctly', version => {
expect(aas2_1({ asyncapi: version }, null)).toBe(true);
});

it.each(['2', '2.1', '2.0.0', '2.2.0', '2.2.3'])('does not recognize %s version', version => {
expect(aas2_1({ asyncapi: version }, null)).toBe(false);
});
});

describe('AsyncAPI 2.2', () => {
it.each(['2.2.0', '2.2.3'])('recognizes %s version correctly', version => {
expect(aas2_2({ asyncapi: version }, null)).toBe(true);
});

it.each(['2', '2.2', '2.0.0', '2.1.0', '2.1.37', '2.3.0', '2.3.3'])('does not recognize %s version', version => {
expect(aas2_2({ asyncapi: version }, null)).toBe(false);
});
});

describe('AsyncAPI 2.3', () => {
it.each(['2.3.0', '2.3.3'])('recognizes %s version correctly', version => {
expect(aas2_3({ asyncapi: version }, null)).toBe(true);
});

it.each(['2', '2.3', '2.0.0', '2.1.0', '2.1.37', '2.2.0', '2.4.0', '2.4.3'])(
'does not recognize %s version',
version => {
expect(aas2_3({ asyncapi: version }, null)).toBe(false);
},
);
});
});
40 changes: 26 additions & 14 deletions packages/formats/src/asyncapi.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import type { Format } from '@stoplight/spectral-core';
import { isPlainObject } from '@stoplight/json';

type MaybeAsyncApi2 = Partial<{ asyncapi: unknown }>;
type MaybeAAS2 = { asyncapi: unknown } & Record<string, unknown>;

const bearsAStringPropertyNamed = (document: unknown, propertyName: string): boolean => {
return isPlainObject(document) && propertyName in document && typeof document[propertyName] === 'string';
};
const aas2Regex = /^2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/;
const aas2_0Regex = /^2\.0(?:\.[0-9]*)?$/;
const aas2_1Regex = /^2\.1(?:\.[0-9]*)?$/;
const aas2_2Regex = /^2\.2(?:\.[0-9]*)?$/;
const aas2_3Regex = /^2\.3(?:\.[0-9]*)?$/;

const version2Regex = /^2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/;
const isAas2 = (document: unknown): document is { asyncapi: string } & Record<string, unknown> =>
isPlainObject(document) && 'asyncapi' in document && aas2Regex.test(String((document as MaybeAAS2).asyncapi));

export const asyncApi2: Format = document => {
if (!bearsAStringPropertyNamed(document, 'asyncapi')) {
return false;
}
export const aas2: Format = isAas2;
aas2.displayName = 'AsyncAPI 2.x';

const version = String((document as MaybeAsyncApi2).asyncapi);
// for backward compatibility
export const asyncApi2 = aas2;
export const asyncapi2 = aas2;

return version2Regex.test(version);
};
export const aas2_0: Format = (document: unknown): boolean =>
isAas2(document) && aas2_0Regex.test(String((document as MaybeAAS2).asyncapi));
aas2_0.displayName = 'AsyncAPI 2.0.x';

asyncApi2.displayName = 'AsyncAPI 2.x';
export const aas2_1: Format = (document: unknown): boolean =>
isAas2(document) && aas2_1Regex.test(String((document as MaybeAAS2).asyncapi));
aas2_1.displayName = 'AsyncAPI 2.1.x';

export { asyncApi2 as asyncapi2 };
export const aas2_2: Format = (document: unknown): boolean =>
isAas2(document) && aas2_2Regex.test(String((document as MaybeAAS2).asyncapi));
aas2_2.displayName = 'AsyncAPI 2.2.x';

export const aas2_3: Format = (document: unknown): boolean =>
isAas2(document) && aas2_3Regex.test(String((document as MaybeAAS2).asyncapi));
aas2_3.displayName = 'AsyncAPI 2.3.x';
7 changes: 7 additions & 0 deletions packages/functions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [@stoplight/spectral-functions-v1.5.2](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-functions-v1.5.1...@stoplight/spectral-functions-v1.5.2) (2022-02-28)


### Bug Fixes

* **functions:** __importDefault undefined ([609ecb1](https://github.com/stoplightio/spectral/commit/609ecb1b23f354459f96687f27f911e915cb6ab3))

# [@stoplight/spectral-functions-v1.5.1](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-functions-v1.5.0...@stoplight/spectral-functions-v1.5.1) (2021-12-29)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/functions/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/spectral-functions",
"version": "1.5.1",
"version": "1.5.2",
"sideEffects": false,
"homepage": "https://github.com/stoplightio/spectral",
"bugs": "https://github.com/stoplightio/spectral/issues",
Expand Down
50 changes: 38 additions & 12 deletions packages/functions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
export { default as alphabetical, Options as AlphabeticalOptions } from './alphabetical';
export { default as casing, Options as CasingOptions } from './casing';
export { default as defined } from './defined';
export { default as enumeration, Options as EnumerationOptions } from './enumeration';
export { default as falsy } from './falsy';
export { default as length, Options as LengthOptions } from './length';
export { default as pattern, Options as PatternOptions } from './pattern';
export { default as schema, Options as SchemaOptions } from './schema';
export { default as truthy } from './truthy';
export { default as undefined } from './undefined';
export {
import { default as alphabetical, Options as AlphabeticalOptions } from './alphabetical';
import { default as casing, Options as CasingOptions } from './casing';
import { default as defined } from './defined';
import { default as enumeration, Options as EnumerationOptions } from './enumeration';
import { default as falsy } from './falsy';
import { default as length, Options as LengthOptions } from './length';
import { default as pattern, Options as PatternOptions } from './pattern';
import { default as schema, Options as SchemaOptions } from './schema';
import { default as truthy } from './truthy';
import { default as undefined } from './undefined';
import {
default as unreferencedReusableObject,
Options as UnreferencedReusableObjectOptions,
} from './unreferencedReusableObject';
export { default as xor, Options as XorOptions } from './xor';
import { default as xor, Options as XorOptions } from './xor';

export {
alphabetical,
casing,
defined,
enumeration,
falsy,
length,
pattern,
schema,
truthy,
undefined,
unreferencedReusableObject,
xor,
};

export type {
AlphabeticalOptions,
CasingOptions,
EnumerationOptions,
LengthOptions,
PatternOptions,
SchemaOptions,
UnreferencedReusableObjectOptions,
XorOptions,
};
21 changes: 21 additions & 0 deletions packages/ruleset-bundler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# [@stoplight/spectral-ruleset-bundler-v1.2.1](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-ruleset-bundler-v1.2.0...@stoplight/spectral-ruleset-bundler-v1.2.1) (2022-02-28)


### Bug Fixes

* **ruleset-bundler:** __importDefault undefined ([874a80e](https://github.com/stoplightio/spectral/commit/874a80e9d8e36d96bfbb467e340aab337227bfa7))

# [@stoplight/spectral-ruleset-bundler-v1.2.0](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-ruleset-bundler-v1.1.1...@stoplight/spectral-ruleset-bundler-v1.2.0) (2022-02-25)


### Bug Fixes

* **ruleset-bundler:** builtins plugin should create a new instance for each module ([b06903c](https://github.com/stoplightio/spectral/commit/b06903ce71f556809b06a21ce3a299625b3760e0))
* **ruleset-bundler:** virtualFs plugin incompatible with commonjs plugin ([a48381b](https://github.com/stoplightio/spectral/commit/a48381bdf86c7c9015dd67daa8bda767ea727376))


### Features

* **ruleset-bundler:** expose commonjs plugin ([91a4b80](https://github.com/stoplightio/spectral/commit/91a4b807dc1e9b7ed700b6645eff711cfa1d5bef))
* **ruleset-bundler:** plugins should be easy to override ([0263bf0](https://github.com/stoplightio/spectral/commit/0263bf0234b11d6bb17b7b7feef6ba5716cc8f01))

# [@stoplight/spectral-ruleset-bundler-v1.1.1](https://github.com/stoplightio/spectral/compare/@stoplight/spectral-ruleset-bundler-v1.1.0...@stoplight/spectral-ruleset-bundler-v1.1.1) (2021-12-30)

### Bug Fixes
Expand Down
Loading

0 comments on commit d77d987

Please sign in to comment.