@amritk/lint 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI.md +55 -0
- package/dist/core/document.js +12 -10
- package/dist/core/formats.js +10 -13
- package/dist/core/glob.js +96 -118
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +30 -11
- package/dist/core/jsonpath.js +487 -561
- package/dist/core/lint.js +78 -85
- package/dist/core/plugin.js +21 -29
- package/dist/core/pointers.js +107 -151
- package/dist/core/ruleset.js +0 -0
- package/dist/core/runner.js +214 -272
- package/dist/core/types.js +4 -1
- package/dist/core/validate-ruleset.js +98 -112
- package/dist/fix/apply.d.ts +1 -1
- package/dist/fix/apply.js +58 -96
- package/dist/fix/index.js +7 -2
- package/dist/fix/plugin.js +15 -20
- package/dist/fix/types.d.ts +1 -1
- package/dist/functions/alphabetical.d.ts +1 -1
- package/dist/functions/alphabetical.js +39 -50
- package/dist/functions/casing.d.ts +1 -1
- package/dist/functions/casing.js +39 -45
- package/dist/functions/defined.d.ts +1 -1
- package/dist/functions/defined.js +7 -5
- package/dist/functions/enumeration.d.ts +1 -1
- package/dist/functions/enumeration.js +15 -25
- package/dist/functions/falsy.d.ts +1 -1
- package/dist/functions/falsy.js +7 -5
- package/dist/functions/index.d.ts +1 -1
- package/dist/functions/index.js +60 -44
- package/dist/functions/length.d.ts +1 -1
- package/dist/functions/length.js +22 -32
- package/dist/functions/or.d.ts +1 -1
- package/dist/functions/or.js +18 -24
- package/dist/functions/pattern.d.ts +1 -1
- package/dist/functions/pattern.js +39 -49
- package/dist/functions/schema.d.ts +1 -1
- package/dist/functions/schema.js +93 -119
- package/dist/functions/truthy.d.ts +1 -1
- package/dist/functions/truthy.js +7 -5
- package/dist/functions/typed-enum.d.ts +1 -1
- package/dist/functions/typed-enum.js +33 -36
- package/dist/functions/undefined.d.ts +1 -1
- package/dist/functions/undefined.js +7 -8
- package/dist/functions/unreferenced-reusable-object.d.ts +1 -1
- package/dist/functions/unreferenced-reusable-object.js +35 -47
- package/dist/functions/xor.d.ts +1 -1
- package/dist/functions/xor.js +13 -16
- package/dist/index.d.ts +17 -4
- package/dist/index.js +149 -164
- package/dist/parsers/edit-model.js +316 -444
- package/dist/parsers/index.d.ts +1 -1
- package/dist/parsers/index.js +23 -19
- package/dist/parsers/json.js +39 -37
- package/dist/parsers/lines.js +23 -26
- package/dist/parsers/types.js +9 -7
- package/dist/parsers/yaml.js +137 -204
- package/dist/rules/openapi/fixers.js +166 -221
- package/dist/rules/openapi/formats.js +26 -27
- package/dist/rules/openapi/functions/example-validation.d.ts +1 -1
- package/dist/rules/openapi/functions/example-validation.js +98 -138
- package/dist/rules/openapi/functions/helpers.js +8 -10
- package/dist/rules/openapi/functions/index.d.ts +1 -1
- package/dist/rules/openapi/functions/index.js +98 -72
- package/dist/rules/openapi/functions/oas-additional-operations.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-additional-operations.js +16 -22
- package/dist/rules/openapi/functions/oas-discriminator.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-discriminator.js +24 -22
- package/dist/rules/openapi/functions/oas-example-external-value.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-example-external-value.js +13 -21
- package/dist/rules/openapi/functions/oas-example-value.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-example-value.js +24 -27
- package/dist/rules/openapi/functions/oas-mutually-exclusive.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-mutually-exclusive.js +15 -19
- package/dist/rules/openapi/functions/oas-no-nullable.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-no-nullable.js +13 -21
- package/dist/rules/openapi/functions/oas-op-form-data-consume-check.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-op-form-data-consume-check.js +21 -19
- package/dist/rules/openapi/functions/oas-op-id-unique.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-op-id-unique.js +27 -27
- package/dist/rules/openapi/functions/oas-op-params.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-op-params.js +36 -42
- package/dist/rules/openapi/functions/oas-op-security-defined.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-op-security-defined.js +40 -39
- package/dist/rules/openapi/functions/oas-op-success-response.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-op-success-response.js +11 -13
- package/dist/rules/openapi/functions/oas-path-param.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-path-param.js +75 -96
- package/dist/rules/openapi/functions/oas-schema-example-deprecated.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-schema-example-deprecated.js +33 -40
- package/dist/rules/openapi/functions/oas-schema.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-schema.js +9 -14
- package/dist/rules/openapi/functions/oas-server-name-unique.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-server-name-unique.js +21 -19
- package/dist/rules/openapi/functions/oas-server-variables.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-server-variables.js +45 -49
- package/dist/rules/openapi/functions/oas-tag-defined.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-tag-defined.js +20 -20
- package/dist/rules/openapi/functions/oas-tag-kind.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-tag-kind.js +16 -16
- package/dist/rules/openapi/functions/oas-tag-parent-defined.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-tag-parent-defined.js +40 -43
- package/dist/rules/openapi/functions/oas-tags-unique.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-tags-unique.js +18 -16
- package/dist/rules/openapi/functions/oas-unused-component.d.ts +1 -1
- package/dist/rules/openapi/functions/oas-unused-component.js +48 -58
- package/dist/rules/openapi/functions/ref-siblings.d.ts +1 -1
- package/dist/rules/openapi/functions/ref-siblings.js +13 -11
- package/dist/rules/openapi/index.d.ts +2 -1
- package/dist/rules/openapi/index.js +99 -117
- package/dist/rules/openapi/oas.d.ts +1 -1
- package/dist/rules/openapi/oas.js +524 -536
- package/dist/rules/openapi/schemas/index.js +17 -33
- package/dist/rules/openapi/schemas/oas20.json +1 -1592
- package/dist/rules/openapi/schemas/oas30.json +1 -1651
- package/dist/rules/openapi/schemas/oas31.json +1 -1412
- package/dist/rules/openapi/schemas/oas32.json +1 -1684
- package/package.json +11 -6
|
@@ -1,106 +1,85 @@
|
|
|
1
|
-
import { isObject, OPERATION_METHODS } from
|
|
2
|
-
// Path template parameters, e.g. `{id}`. Matches Spectral's grammar so matrix
|
|
3
|
-
// (`{;id}`), optional (`{id?}`), and explode (`{id*}`) markers are stripped off
|
|
4
|
-
// the captured name before comparison.
|
|
1
|
+
import { isObject, OPERATION_METHODS } from "./helpers.js";
|
|
5
2
|
const PATH_TEMPLATE = /(\{;?\??[a-zA-Z0-9_-]+\*?\})/g;
|
|
6
|
-
const namedPathParam = (param) => param[
|
|
7
|
-
/**
|
|
8
|
-
* Records a single `in: path` definition, emitting Spectral's `required: true`
|
|
9
|
-
* and duplicate-definition findings. Returns the parameter name when it is the
|
|
10
|
-
* first definition seen (so the caller registers it as usable), else undefined.
|
|
11
|
-
*/
|
|
3
|
+
const namedPathParam = (param) => param["in"] === "path" && typeof param["name"] === "string" ? param["name"] : void 0;
|
|
12
4
|
const recordPathParam = (param, definitionPath, seen, results) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
const name = namedPathParam(param);
|
|
6
|
+
if (name === void 0)
|
|
7
|
+
return void 0;
|
|
8
|
+
if (param["required"] !== true) {
|
|
9
|
+
results.push({
|
|
10
|
+
message: `Path parameter "${name}" must have a "required" property that is set to "true"`,
|
|
11
|
+
path: definitionPath
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (name in seen) {
|
|
15
|
+
results.push({ message: `Path parameter "${name}" must not be defined multiple times`, path: definitionPath });
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
return name;
|
|
19
|
+
};
|
|
20
|
+
const oasPathParam = (paths, _options, context) => {
|
|
21
|
+
if (!isObject(paths))
|
|
22
|
+
return [];
|
|
23
|
+
const results = [];
|
|
24
|
+
for (const [path, item] of Object.entries(paths)) {
|
|
25
|
+
if (!isObject(item))
|
|
26
|
+
continue;
|
|
27
|
+
const templates = [];
|
|
28
|
+
for (const match of path.matchAll(PATH_TEMPLATE)) {
|
|
29
|
+
const name = match[0].replace(/[{}?*;]/g, "");
|
|
30
|
+
if (templates.includes(name)) {
|
|
17
31
|
results.push({
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
message: `Path "${path}" must not use parameter "{${name}}" more than once`,
|
|
33
|
+
path: [...context.path, path]
|
|
20
34
|
});
|
|
35
|
+
} else {
|
|
36
|
+
templates.push(name);
|
|
37
|
+
}
|
|
21
38
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
39
|
+
const topParams = {};
|
|
40
|
+
if (Array.isArray(item["parameters"])) {
|
|
41
|
+
item["parameters"].forEach((param, index) => {
|
|
42
|
+
if (!isObject(param))
|
|
43
|
+
return;
|
|
44
|
+
const definitionPath = [...context.path, path, "parameters", index];
|
|
45
|
+
const name = recordPathParam(param, definitionPath, topParams, results);
|
|
46
|
+
if (name !== void 0)
|
|
47
|
+
topParams[name] = definitionPath;
|
|
48
|
+
});
|
|
25
49
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!
|
|
44
|
-
|
|
45
|
-
// (d) Templates declared in the path key, deduplicated (a repeat is an error).
|
|
46
|
-
const templates = [];
|
|
47
|
-
for (const match of path.matchAll(PATH_TEMPLATE)) {
|
|
48
|
-
const name = match[0].replace(/[{}?*;]/g, '');
|
|
49
|
-
if (templates.includes(name)) {
|
|
50
|
-
results.push({
|
|
51
|
-
message: `Path "${path}" must not use parameter "{${name}}" more than once`,
|
|
52
|
-
path: [...context.path, path],
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
templates.push(name);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Path Item level parameters apply to every operation on the path.
|
|
60
|
-
const topParams = {};
|
|
61
|
-
if (Array.isArray(item['parameters'])) {
|
|
62
|
-
item['parameters'].forEach((param, index) => {
|
|
63
|
-
if (!isObject(param))
|
|
64
|
-
return;
|
|
65
|
-
const definitionPath = [...context.path, path, 'parameters', index];
|
|
66
|
-
const name = recordPathParam(param, definitionPath, topParams, results);
|
|
67
|
-
if (name !== undefined)
|
|
68
|
-
topParams[name] = definitionPath;
|
|
69
|
-
});
|
|
50
|
+
for (const [method, operation] of Object.entries(item)) {
|
|
51
|
+
if (method === "parameters" || !OPERATION_METHODS.has(method) || !isObject(operation))
|
|
52
|
+
continue;
|
|
53
|
+
const operationPath = [...context.path, path, method];
|
|
54
|
+
const operationParams = {};
|
|
55
|
+
if (Array.isArray(operation["parameters"])) {
|
|
56
|
+
operation["parameters"].forEach((param, index) => {
|
|
57
|
+
if (!isObject(param))
|
|
58
|
+
return;
|
|
59
|
+
const definitionPath = [...operationPath, "parameters", index];
|
|
60
|
+
const name = recordPathParam(param, definitionPath, operationParams, results);
|
|
61
|
+
if (name !== void 0)
|
|
62
|
+
operationParams[name] = definitionPath;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const defined = { ...topParams, ...operationParams };
|
|
66
|
+
for (const [name, definitionPath] of Object.entries(defined)) {
|
|
67
|
+
if (definitionPath && !templates.includes(name)) {
|
|
68
|
+
results.push({ message: `Parameter "${name}" must be used in path "${path}"`, path: definitionPath });
|
|
70
69
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
operation['parameters'].forEach((param, index) => {
|
|
79
|
-
if (!isObject(param))
|
|
80
|
-
return;
|
|
81
|
-
const definitionPath = [...operationPath, 'parameters', index];
|
|
82
|
-
const name = recordPathParam(param, definitionPath, operationParams, results);
|
|
83
|
-
if (name !== undefined)
|
|
84
|
-
operationParams[name] = definitionPath;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
const defined = { ...topParams, ...operationParams };
|
|
88
|
-
// (b) Every defined `in: path` parameter must appear in the path template.
|
|
89
|
-
for (const [name, definitionPath] of Object.entries(defined)) {
|
|
90
|
-
if (definitionPath && !templates.includes(name)) {
|
|
91
|
-
results.push({ message: `Parameter "${name}" must be used in path "${path}"`, path: definitionPath });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// (a) Every `{template}` must have a matching definition on the operation.
|
|
95
|
-
for (const name of templates) {
|
|
96
|
-
if (!(name in defined)) {
|
|
97
|
-
results.push({
|
|
98
|
-
message: `Operation must define path parameter "{${name}}" as expected by path "${path}"`,
|
|
99
|
-
path: operationPath,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
70
|
+
}
|
|
71
|
+
for (const name of templates) {
|
|
72
|
+
if (!(name in defined)) {
|
|
73
|
+
results.push({
|
|
74
|
+
message: `Operation must define path parameter "{${name}}" as expected by path "${path}"`,
|
|
75
|
+
path: operationPath
|
|
76
|
+
});
|
|
103
77
|
}
|
|
78
|
+
}
|
|
104
79
|
}
|
|
105
|
-
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
};
|
|
83
|
+
export {
|
|
84
|
+
oasPathParam
|
|
106
85
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Flags a Schema Object's singular `example`, deprecated in OpenAPI 3.1 (JSON
|
|
4
4
|
* Schema 2020-12) in favor of the `examples` array. Targets the parent of an
|
|
@@ -1,42 +1,35 @@
|
|
|
1
|
-
import { isObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'prefixItems',
|
|
18
|
-
'$ref',
|
|
1
|
+
import { isObject } from "./helpers.js";
|
|
2
|
+
const SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
3
|
+
"type",
|
|
4
|
+
"properties",
|
|
5
|
+
"items",
|
|
6
|
+
"allOf",
|
|
7
|
+
"anyOf",
|
|
8
|
+
"oneOf",
|
|
9
|
+
"not",
|
|
10
|
+
"enum",
|
|
11
|
+
"format",
|
|
12
|
+
"required",
|
|
13
|
+
"additionalProperties",
|
|
14
|
+
"patternProperties",
|
|
15
|
+
"prefixItems",
|
|
16
|
+
"$ref"
|
|
19
17
|
]);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
message: 'Schema "example" is deprecated in OpenAPI 3.1; use "examples" instead.',
|
|
39
|
-
path: [...context.path, 'example'],
|
|
40
|
-
},
|
|
41
|
-
];
|
|
18
|
+
const oasSchemaExampleDeprecated = (input, _options, context) => {
|
|
19
|
+
if (!isObject(input) || input["example"] === void 0)
|
|
20
|
+
return [];
|
|
21
|
+
if ("schema" in input)
|
|
22
|
+
return [];
|
|
23
|
+
const looksLikeSchema = Object.keys(input).some((key) => SCHEMA_KEYWORDS.has(key));
|
|
24
|
+
if (!looksLikeSchema)
|
|
25
|
+
return [];
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
message: 'Schema "example" is deprecated in OpenAPI 3.1; use "examples" instead.',
|
|
29
|
+
path: [...context.path, "example"]
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
};
|
|
33
|
+
export {
|
|
34
|
+
oasSchemaExampleDeprecated
|
|
42
35
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
import { type OasVersion } from '../schemas/index.js';
|
|
3
3
|
/** Options for {@link oasSchema}: which OpenAPI version's meta-schema to validate against. */
|
|
4
4
|
export type IOasSchemaOptions = {
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { schema as schemaFunction } from
|
|
2
|
-
import { loadOasSchema } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export const oasSchema = (input, options, context) => {
|
|
12
|
-
if (!options?.version)
|
|
13
|
-
return [];
|
|
14
|
-
return schemaFunction(input, { schema: loadOasSchema(options.version) }, context);
|
|
1
|
+
import { schema as schemaFunction } from "../../../functions/index.js";
|
|
2
|
+
import { loadOasSchema } from "../schemas/index.js";
|
|
3
|
+
const oasSchema = (input, options, context) => {
|
|
4
|
+
if (!options?.version)
|
|
5
|
+
return [];
|
|
6
|
+
return schemaFunction(input, { schema: loadOasSchema(options.version) }, context);
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
oasSchema
|
|
15
10
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
/** Flags duplicate OpenAPI 3.2 Server Object `name` values across the servers array. */
|
|
3
3
|
export declare const oasServerNameUnique: RulesetFunction;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { isObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import { isObject } from "./helpers.js";
|
|
2
|
+
const oasServerNameUnique = (servers, _options, context) => {
|
|
3
|
+
if (!Array.isArray(servers))
|
|
4
|
+
return [];
|
|
5
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6
|
+
const results = [];
|
|
7
|
+
servers.forEach((server, index) => {
|
|
8
|
+
if (!isObject(server) || typeof server["name"] !== "string")
|
|
9
|
+
return;
|
|
10
|
+
if (seen.has(server["name"])) {
|
|
11
|
+
results.push({
|
|
12
|
+
message: `Server name "${server["name"]}" must be unique`,
|
|
13
|
+
path: [...context.path, index, "name"]
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
seen.add(server["name"]);
|
|
17
|
+
});
|
|
18
|
+
return results;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
oasServerNameUnique
|
|
20
22
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Validates a Server Object's `variables`, mirroring Spectral's `serverVariables`:
|
|
4
4
|
* every `{template}` in the URL must have a matching variable and vice versa, and
|
|
@@ -1,52 +1,48 @@
|
|
|
1
|
-
import { isObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!
|
|
10
|
-
|
|
11
|
-
const templates = [...server['url'].matchAll(/\{([^}]+)\}/g)].map((m) => m[1]);
|
|
12
|
-
const variables = isObject(server['variables']) ? server['variables'] : {};
|
|
13
|
-
const results = [];
|
|
14
|
-
for (const template of templates) {
|
|
15
|
-
if (!(template in variables)) {
|
|
16
|
-
results.push({ message: `Server variable "${template}" is not defined`, path: [...context.path, 'variables'] });
|
|
17
|
-
}
|
|
1
|
+
import { isObject } from "./helpers.js";
|
|
2
|
+
const oasServerVariables = (server, _options, context) => {
|
|
3
|
+
if (!isObject(server) || typeof server["url"] !== "string")
|
|
4
|
+
return [];
|
|
5
|
+
const templates = [...server["url"].matchAll(/\{([^}]+)\}/g)].map((m) => m[1]);
|
|
6
|
+
const variables = isObject(server["variables"]) ? server["variables"] : {};
|
|
7
|
+
const results = [];
|
|
8
|
+
for (const template of templates) {
|
|
9
|
+
if (!(template in variables)) {
|
|
10
|
+
results.push({ message: `Server variable "${template}" is not defined`, path: [...context.path, "variables"] });
|
|
18
11
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!isObject(variable))
|
|
27
|
-
continue;
|
|
28
|
-
const hasDefault = variable['default'] !== undefined;
|
|
29
|
-
if (!hasDefault) {
|
|
30
|
-
results.push({
|
|
31
|
-
message: `Server variable "${name}" has a missing default`,
|
|
32
|
-
path: [...context.path, 'variables', name],
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
if ('enum' in variable) {
|
|
36
|
-
const enumValues = Array.isArray(variable['enum']) ? variable['enum'] : [];
|
|
37
|
-
if (enumValues.length === 0) {
|
|
38
|
-
results.push({
|
|
39
|
-
message: `Server variable "${name}" has an empty enum`,
|
|
40
|
-
path: [...context.path, 'variables', name, 'enum'],
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else if (hasDefault && !enumValues.includes(variable['default'])) {
|
|
44
|
-
results.push({
|
|
45
|
-
message: `Server variable "${name}" has a default not listed in the enum`,
|
|
46
|
-
path: [...context.path, 'variables', name, 'default'],
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
12
|
+
}
|
|
13
|
+
for (const [name, variable] of Object.entries(variables)) {
|
|
14
|
+
if (!templates.includes(name)) {
|
|
15
|
+
results.push({
|
|
16
|
+
message: `Server variable "${name}" is not used in the URL`,
|
|
17
|
+
path: [...context.path, "variables", name]
|
|
18
|
+
});
|
|
50
19
|
}
|
|
51
|
-
|
|
20
|
+
if (!isObject(variable))
|
|
21
|
+
continue;
|
|
22
|
+
const hasDefault = variable["default"] !== void 0;
|
|
23
|
+
if (!hasDefault) {
|
|
24
|
+
results.push({
|
|
25
|
+
message: `Server variable "${name}" has a missing default`,
|
|
26
|
+
path: [...context.path, "variables", name]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if ("enum" in variable) {
|
|
30
|
+
const enumValues = Array.isArray(variable["enum"]) ? variable["enum"] : [];
|
|
31
|
+
if (enumValues.length === 0) {
|
|
32
|
+
results.push({
|
|
33
|
+
message: `Server variable "${name}" has an empty enum`,
|
|
34
|
+
path: [...context.path, "variables", name, "enum"]
|
|
35
|
+
});
|
|
36
|
+
} else if (hasDefault && !enumValues.includes(variable["default"])) {
|
|
37
|
+
results.push({
|
|
38
|
+
message: `Server variable "${name}" has a default not listed in the enum`,
|
|
39
|
+
path: [...context.path, "variables", name, "default"]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return results;
|
|
45
|
+
};
|
|
46
|
+
export {
|
|
47
|
+
oasServerVariables
|
|
52
48
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { isObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { isObject } from "./helpers.js";
|
|
2
|
+
const oasTagDefined = (input, _options, context) => {
|
|
3
|
+
const root = context.document.data;
|
|
4
|
+
if (!isObject(root) || !isObject(input))
|
|
5
|
+
return [];
|
|
6
|
+
const globalTags = new Set((Array.isArray(root["tags"]) ? root["tags"] : []).map((tag) => isObject(tag) ? tag["name"] : void 0).filter((name) => typeof name === "string"));
|
|
7
|
+
const tags = Array.isArray(input["tags"]) ? input["tags"] : [];
|
|
8
|
+
const results = [];
|
|
9
|
+
tags.forEach((tag, index) => {
|
|
10
|
+
if (typeof tag === "string" && !globalTags.has(tag)) {
|
|
11
|
+
results.push({
|
|
12
|
+
message: `Operation tag "${tag}" is not defined in the global tags`,
|
|
13
|
+
path: [...context.path, "tags", index]
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return results;
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
oasTagDefined
|
|
21
21
|
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { isObject } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { isObject } from "./helpers.js";
|
|
2
|
+
const REGISTERED_TAG_KINDS = /* @__PURE__ */ new Set(["nav", "badge", "audience"]);
|
|
3
|
+
const oasTagKind = (tag, _options, context) => {
|
|
4
|
+
if (!isObject(tag) || typeof tag["kind"] !== "string")
|
|
5
|
+
return [];
|
|
6
|
+
if (REGISTERED_TAG_KINDS.has(tag["kind"]))
|
|
7
|
+
return [];
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
message: `Tag kind "${tag["kind"]}" is not a registered value (${[...REGISTERED_TAG_KINDS].join(", ")})`,
|
|
11
|
+
path: [...context.path, "kind"]
|
|
12
|
+
}
|
|
13
|
+
];
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
oasTagKind
|
|
17
17
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Validates the OpenAPI 3.2 Tag Object `parent` hierarchy: every `parent` must
|
|
4
4
|
* name a tag that exists in the top-level `tags` list, a tag must not be its own
|