Skip to content

Commit

Permalink
feat(rulesets): improve oas3.1 schema
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Jan 12, 2024
1 parent e6c5ab9 commit c8124e1
Show file tree
Hide file tree
Showing 16 changed files with 587 additions and 119 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"lint": "yarn prelint && 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/ruleset/meta/*.json packages/rulesets/src/{asyncapi,oas}/schemas/*.json docs/**/*.md README.md",
"lint.prettier": "prettier --ignore-path .eslintignore --ignore-unknown --check packages/core/src/ruleset/meta/*.json packages/rulesets/src/{asyncapi,oas}/schemas/**/*.json docs/**/*.md README.md",
"pretest": "yarn workspaces foreach run pretest",
"test": "yarn pretest && yarn test.karma && yarn test.jest",
"pretest.harness": "ts-node -T test-harness/scripts/generate-tests.ts",
Expand Down Expand Up @@ -138,7 +138,7 @@
"packages/core/src/ruleset/meta/*.json": [
"prettier --ignore-path .eslintignore --write"
],
"packages/rulesets/src/{asyncapi,oas}/schemas/*.json": [
"packages/rulesets/src/{asyncapi,oas}/schemas/**/*.json": [
"prettier --ignore-path .eslintignore --write"
]
},
Expand Down
1 change: 1 addition & 0 deletions packages/rulesets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@stoplight/path": "^1.3.2",
"@stoplight/spectral-parsers": "*",
"@stoplight/spectral-ref-resolver": "*",
"ajv-merge-patch": "^5.0.1",
"gzip-size": "^6.0.0",
"immer": "^9.0.6",
"terser": "^5.26.0"
Expand Down
4 changes: 3 additions & 1 deletion packages/rulesets/scripts/compile-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { sync } from 'gzip-size';
const cwd = path.join(__dirname, '../src');

const schemas = [
'oas/schemas/json-schema-draft-04.json',
'oas/schemas/json-schema/draft-04.json',
'oas/schemas/json-schema/draft-2020-12/index.json',
'oas/schemas/json-schema/draft-2020-12/validation.json',
'oas/schemas/oas/v2.0.json',
'oas/schemas/oas/v3.0.json',
'oas/schemas/oas/v3.1/dialect.schema.json',
Expand Down
289 changes: 243 additions & 46 deletions packages/rulesets/src/oas/__tests__/oas3-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,52 +150,6 @@ testRule('oas3-schema', [
],
},

{
name: 'oas3.1: paths is not required',
document: {
openapi: '3.1.0',
info: {
title: 'Example jsonSchemaDialect error',
version: '1.0.0',
},
webhooks: {},
},
errors: [],
},

{
name: 'oas3.1: uri template as server url',
document: {
openapi: '3.1.0',
info: {
title: 'Server URL may have variables',
version: '1.0.0',
},
webhooks: {},
// https://spec.openapis.org/oas/v3.1.0#server-object-example
servers: [
{
url: 'https://{username}.gigantic-server.com:{port}/{basePath}',
description: 'The production API server',
variables: {
username: {
default: 'demo',
description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',
},
port: {
enum: ['8443', '443'],
default: '8443',
},
basePath: {
default: 'v2',
},
},
},
],
},
errors: [],
},

{
name: 'oas3.0: validate parameters',
document: {
Expand Down Expand Up @@ -319,6 +273,7 @@ testRule('oas3-schema', [
},
],
},

{
name: 'oas3.0: validate responses',
document: {
Expand Down Expand Up @@ -383,4 +338,246 @@ testRule('oas3-schema', [
},
],
},

{
name: 'oas3.0: validate schemas',
document: {
openapi: '3.0.3',
info: {
title: 'our-api',
version: '1.0',
},
paths: {
'/config': {
parameters: [
{
schema: null,
name: 'id',
in: 'query',
required: false,
description: 'Id of an existing config.',
},
],
get: {
summary: 'Get User Info by User ID',
operationId: 'get-users-settings',
responses: {
'200': {
description: 'Settings for User Found',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
key: {
type: 'string,',
},
value: {
type: 'string',
},
},
required: ['key', 'value'],
},
},
},
},
},
},
},
},
components: {
schemas: {
Schema: {
type: 'object',
additionalProperties: {
type: 'int',
},
},
Schema_2: {
type: 'object',
additionalProperties: 'invalid',
},
},
},
},
errors: [
{
message: '"schema" property must be object.',
path: ['paths', '/config', 'parameters', '0', 'schema'],
severity: DiagnosticSeverity.Error,
},
{
message:
'"type" property must be equal to one of the allowed values: "array", "boolean", "integer", "number", "object", "string". Did you mean "string"?.',
path: [
'paths',
'/config',
'get',
'responses',
'200',
'content',
'application/json',
'schema',
'properties',
'key',
'type',
],
},
{
message:
'"type" property must be equal to one of the allowed values: "array", "boolean", "integer", "number", "object", "string". Did you mean "integer"?.',
path: ['components', 'schemas', 'Schema', 'additionalProperties', 'type'],
severity: DiagnosticSeverity.Error,
},
{
message: '"additionalProperties" property must be a valid Schema Object.',
path: ['components', 'schemas', 'Schema_2', 'additionalProperties'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'oas3.1: paths is not required',
document: {
openapi: '3.1.0',
info: {
title: 'Example jsonSchemaDialect error',
version: '1.0.0',
},
webhooks: {},
},
errors: [],
},

{
name: 'oas3.1: validate schemas',
document: {
openapi: '3.1.0',
info: {
title: 'our-api',
version: '1.0',
},
paths: {
'/config': {
parameters: [
{
schema: null,
name: 'id',
in: 'query',
required: false,
description: 'Id of an existing config.',
},
],
get: {
summary: 'Get User Info by User ID',
operationId: 'get-users-settings',
responses: {
'200': {
description: 'Settings for User Found',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
key: {
type: 'string,',
},
value: {
type: 'string',
},
},
required: ['key', 'value'],
},
},
},
},
},
},
},
},
components: {
schemas: {
Schema: {
type: 'object',
additionalProperties: {
type: 'int',
},
},
Schema_2: {
type: 'object',
additionalProperties: 'invalid',
},
},
},
},
errors: [
{
message: '"schema" property must be a valid Schema Object.',
path: ['paths', '/config', 'parameters', '0', 'schema'],
severity: DiagnosticSeverity.Error,
},
{
message:
'"type" property must be equal to one of the allowed values: "array", "boolean", "integer", "null", "number", "object", "string". Did you mean "string"?.',
path: [
'paths',
'/config',
'get',
'responses',
'200',
'content',
'application/json',
'schema',
'properties',
'key',
'type',
],
},
{
message:
'"type" property must be equal to one of the allowed values: "array", "boolean", "integer", "null", "number", "object", "string". Did you mean "integer"?.',
path: ['components', 'schemas', 'Schema', 'additionalProperties', 'type'],
severity: DiagnosticSeverity.Error,
},
{
message: '"additionalProperties" property must be a valid Schema Object.',
path: ['components', 'schemas', 'Schema_2', 'additionalProperties'],
severity: DiagnosticSeverity.Error,
},
],
},

{
name: 'oas3.1: uri template as server url',
document: {
openapi: '3.1.0',
info: {
title: 'Server URL may have variables',
version: '1.0.0',
},
webhooks: {},
// https://spec.openapis.org/oas/v3.1.0#server-object-example
servers: [
{
url: 'https://{username}.gigantic-server.com:{port}/{basePath}',
description: 'The production API server',
variables: {
username: {
default: 'demo',
description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',
},
port: {
enum: ['8443', '443'],
default: '8443',
},
basePath: {
default: 'v2',
},
},
},
],
},
errors: [],
},
]);
Loading

0 comments on commit c8124e1

Please sign in to comment.