@redocly/openapi-core 0.0.0-snapshot.1737554067
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/README.md +268 -0
- package/lib/benchmark/benches/lint-with-many-rules.bench.d.ts +4 -0
- package/lib/benchmark/benches/lint-with-many-rules.bench.js +38 -0
- package/lib/benchmark/benches/lint-with-nested-rule.bench.d.ts +4 -0
- package/lib/benchmark/benches/lint-with-nested-rule.bench.js +44 -0
- package/lib/benchmark/benches/lint-with-no-rules.bench.d.ts +4 -0
- package/lib/benchmark/benches/lint-with-no-rules.bench.js +25 -0
- package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.d.ts +4 -0
- package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +37 -0
- package/lib/benchmark/benches/lint-with-top-level-rule.bench.d.ts +4 -0
- package/lib/benchmark/benches/lint-with-top-level-rule.bench.js +36 -0
- package/lib/benchmark/benches/recommended-oas3.bench.d.ts +3 -0
- package/lib/benchmark/benches/recommended-oas3.bench.js +21 -0
- package/lib/benchmark/benches/resolve-with-no-external.bench.d.ts +3 -0
- package/lib/benchmark/benches/resolve-with-no-external.bench.js +22 -0
- package/lib/benchmark/utils.d.ts +6 -0
- package/lib/benchmark/utils.js +34 -0
- package/lib/bundle.d.ts +50 -0
- package/lib/bundle.js +385 -0
- package/lib/config/all.d.ts +3 -0
- package/lib/config/all.js +227 -0
- package/lib/config/builtIn.d.ts +3 -0
- package/lib/config/builtIn.js +53 -0
- package/lib/config/config-resolvers.d.ts +30 -0
- package/lib/config/config-resolvers.js +447 -0
- package/lib/config/config.d.ts +53 -0
- package/lib/config/config.js +320 -0
- package/lib/config/index.d.ts +7 -0
- package/lib/config/index.js +23 -0
- package/lib/config/load.d.ts +38 -0
- package/lib/config/load.js +140 -0
- package/lib/config/minimal.d.ts +3 -0
- package/lib/config/minimal.js +203 -0
- package/lib/config/recommended-strict.d.ts +3 -0
- package/lib/config/recommended-strict.js +203 -0
- package/lib/config/recommended.d.ts +3 -0
- package/lib/config/recommended.js +203 -0
- package/lib/config/rules.d.ts +10 -0
- package/lib/config/rules.js +37 -0
- package/lib/config/spec.d.ts +3 -0
- package/lib/config/spec.js +29 -0
- package/lib/config/types.d.ts +189 -0
- package/lib/config/types.js +2 -0
- package/lib/config/utils.d.ts +19 -0
- package/lib/config/utils.js +308 -0
- package/lib/decorators/arazzo/index.d.ts +1 -0
- package/lib/decorators/arazzo/index.js +4 -0
- package/lib/decorators/async2/index.d.ts +1 -0
- package/lib/decorators/async2/index.js +4 -0
- package/lib/decorators/async3/index.d.ts +1 -0
- package/lib/decorators/async3/index.js +4 -0
- package/lib/decorators/common/filters/filter-helper.d.ts +3 -0
- package/lib/decorators/common/filters/filter-helper.js +66 -0
- package/lib/decorators/common/filters/filter-in.d.ts +2 -0
- package/lib/decorators/common/filters/filter-in.js +17 -0
- package/lib/decorators/common/filters/filter-out.d.ts +2 -0
- package/lib/decorators/common/filters/filter-out.js +17 -0
- package/lib/decorators/common/info-description-override.d.ts +2 -0
- package/lib/decorators/common/info-description-override.js +24 -0
- package/lib/decorators/common/info-override.d.ts +2 -0
- package/lib/decorators/common/info-override.js +17 -0
- package/lib/decorators/common/media-type-examples-override.d.ts +2 -0
- package/lib/decorators/common/media-type-examples-override.js +59 -0
- package/lib/decorators/common/operation-description-override.d.ts +2 -0
- package/lib/decorators/common/operation-description-override.js +29 -0
- package/lib/decorators/common/registry-dependencies.d.ts +2 -0
- package/lib/decorators/common/registry-dependencies.js +24 -0
- package/lib/decorators/common/remove-x-internal.d.ts +2 -0
- package/lib/decorators/common/remove-x-internal.js +69 -0
- package/lib/decorators/common/tag-description-override.d.ts +2 -0
- package/lib/decorators/common/tag-description-override.js +25 -0
- package/lib/decorators/oas2/index.d.ts +11 -0
- package/lib/decorators/oas2/index.js +21 -0
- package/lib/decorators/oas2/remove-unused-components.d.ts +2 -0
- package/lib/decorators/oas2/remove-unused-components.js +89 -0
- package/lib/decorators/oas3/index.d.ts +12 -0
- package/lib/decorators/oas3/index.js +23 -0
- package/lib/decorators/oas3/remove-unused-components.d.ts +2 -0
- package/lib/decorators/oas3/remove-unused-components.js +100 -0
- package/lib/env.d.ts +2 -0
- package/lib/env.js +7 -0
- package/lib/format/codeframes.d.ts +22 -0
- package/lib/format/codeframes.js +185 -0
- package/lib/format/format.d.ts +20 -0
- package/lib/format/format.js +365 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +98 -0
- package/lib/js-yaml/index.d.ts +3 -0
- package/lib/js-yaml/index.js +15 -0
- package/lib/lint.d.ts +32 -0
- package/lib/lint.js +118 -0
- package/lib/logger.d.ts +10 -0
- package/lib/logger.js +31 -0
- package/lib/oas-types.d.ts +36 -0
- package/lib/oas-types.js +92 -0
- package/lib/output.d.ts +3 -0
- package/lib/output.js +9 -0
- package/lib/redocly/domains.d.ts +14 -0
- package/lib/redocly/domains.js +41 -0
- package/lib/redocly/index.d.ts +30 -0
- package/lib/redocly/index.js +131 -0
- package/lib/redocly/redocly-client-types.d.ts +8 -0
- package/lib/redocly/redocly-client-types.js +2 -0
- package/lib/redocly/registry-api-types.d.ts +29 -0
- package/lib/redocly/registry-api-types.js +2 -0
- package/lib/redocly/registry-api.d.ts +17 -0
- package/lib/redocly/registry-api.js +96 -0
- package/lib/ref-utils.d.ts +27 -0
- package/lib/ref-utils.js +85 -0
- package/lib/resolve.d.ts +66 -0
- package/lib/resolve.js +342 -0
- package/lib/rules/ajv.d.ts +10 -0
- package/lib/rules/ajv.js +82 -0
- package/lib/rules/arazzo/criteria-unique.d.ts +2 -0
- package/lib/rules/arazzo/criteria-unique.js +71 -0
- package/lib/rules/arazzo/index.d.ts +3 -0
- package/lib/rules/arazzo/index.js +36 -0
- package/lib/rules/arazzo/parameters-unique.d.ts +2 -0
- package/lib/rules/arazzo/parameters-unique.js +32 -0
- package/lib/rules/arazzo/requestBody-replacements-unique.d.ts +2 -0
- package/lib/rules/arazzo/requestBody-replacements-unique.js +28 -0
- package/lib/rules/arazzo/sourceDescription-type.d.ts +2 -0
- package/lib/rules/arazzo/sourceDescription-type.js +22 -0
- package/lib/rules/arazzo/sourceDescriptions-name-unique.d.ts +2 -0
- package/lib/rules/arazzo/sourceDescriptions-name-unique.js +24 -0
- package/lib/rules/arazzo/sourceDescriptions-not-empty.d.ts +2 -0
- package/lib/rules/arazzo/sourceDescriptions-not-empty.js +18 -0
- package/lib/rules/arazzo/step-onFailure-unique.d.ts +2 -0
- package/lib/rules/arazzo/step-onFailure-unique.js +32 -0
- package/lib/rules/arazzo/step-onSuccess-unique.d.ts +2 -0
- package/lib/rules/arazzo/step-onSuccess-unique.js +32 -0
- package/lib/rules/arazzo/stepId-unique.d.ts +2 -0
- package/lib/rules/arazzo/stepId-unique.js +26 -0
- package/lib/rules/arazzo/workflow-dependsOn.d.ts +2 -0
- package/lib/rules/arazzo/workflow-dependsOn.js +56 -0
- package/lib/rules/arazzo/workflowId-unique.d.ts +2 -0
- package/lib/rules/arazzo/workflowId-unique.js +22 -0
- package/lib/rules/async2/channels-kebab-case.d.ts +2 -0
- package/lib/rules/async2/channels-kebab-case.js +19 -0
- package/lib/rules/async2/index.d.ts +3 -0
- package/lib/rules/async2/index.js +27 -0
- package/lib/rules/async2/no-channel-trailing-slash.d.ts +2 -0
- package/lib/rules/async2/no-channel-trailing-slash.js +16 -0
- package/lib/rules/async3/channels-kebab-case.d.ts +2 -0
- package/lib/rules/async3/channels-kebab-case.js +19 -0
- package/lib/rules/async3/index.d.ts +3 -0
- package/lib/rules/async3/index.js +27 -0
- package/lib/rules/async3/no-channel-trailing-slash.d.ts +2 -0
- package/lib/rules/async3/no-channel-trailing-slash.js +16 -0
- package/lib/rules/common/assertions/asserts.d.ts +30 -0
- package/lib/rules/common/assertions/asserts.js +281 -0
- package/lib/rules/common/assertions/index.d.ts +27 -0
- package/lib/rules/common/assertions/index.js +24 -0
- package/lib/rules/common/assertions/utils.d.ts +28 -0
- package/lib/rules/common/assertions/utils.js +226 -0
- package/lib/rules/common/info-contact.d.ts +2 -0
- package/lib/rules/common/info-contact.js +17 -0
- package/lib/rules/common/info-license-strict.d.ts +2 -0
- package/lib/rules/common/info-license-strict.js +26 -0
- package/lib/rules/common/info-license-url.d.ts +2 -0
- package/lib/rules/common/info-license-url.js +12 -0
- package/lib/rules/common/info-license.d.ts +2 -0
- package/lib/rules/common/info-license.js +17 -0
- package/lib/rules/common/no-ambiguous-paths.d.ts +2 -0
- package/lib/rules/common/no-ambiguous-paths.js +45 -0
- package/lib/rules/common/no-enum-type-mismatch.d.ts +2 -0
- package/lib/rules/common/no-enum-type-mismatch.js +41 -0
- package/lib/rules/common/no-http-verbs-in-paths.d.ts +2 -0
- package/lib/rules/common/no-http-verbs-in-paths.js +33 -0
- package/lib/rules/common/no-identical-paths.d.ts +2 -0
- package/lib/rules/common/no-identical-paths.js +24 -0
- package/lib/rules/common/no-invalid-parameter-examples.d.ts +1 -0
- package/lib/rules/common/no-invalid-parameter-examples.js +24 -0
- package/lib/rules/common/no-invalid-schema-examples.d.ts +1 -0
- package/lib/rules/common/no-invalid-schema-examples.js +22 -0
- package/lib/rules/common/no-path-trailing-slash.d.ts +2 -0
- package/lib/rules/common/no-path-trailing-slash.js +16 -0
- package/lib/rules/common/no-required-schema-properties-undefined.d.ts +2 -0
- package/lib/rules/common/no-required-schema-properties-undefined.js +36 -0
- package/lib/rules/common/operation-2xx-response.d.ts +2 -0
- package/lib/rules/common/operation-2xx-response.js +23 -0
- package/lib/rules/common/operation-4xx-response.d.ts +2 -0
- package/lib/rules/common/operation-4xx-response.js +23 -0
- package/lib/rules/common/operation-description.d.ts +2 -0
- package/lib/rules/common/operation-description.js +12 -0
- package/lib/rules/common/operation-operationId-unique.d.ts +2 -0
- package/lib/rules/common/operation-operationId-unique.js +20 -0
- package/lib/rules/common/operation-operationId-url-safe.d.ts +2 -0
- package/lib/rules/common/operation-operationId-url-safe.js +18 -0
- package/lib/rules/common/operation-operationId.d.ts +2 -0
- package/lib/rules/common/operation-operationId.js +16 -0
- package/lib/rules/common/operation-parameters-unique.d.ts +2 -0
- package/lib/rules/common/operation-parameters-unique.js +40 -0
- package/lib/rules/common/operation-singular-tag.d.ts +2 -0
- package/lib/rules/common/operation-singular-tag.js +16 -0
- package/lib/rules/common/operation-summary.d.ts +2 -0
- package/lib/rules/common/operation-summary.js +12 -0
- package/lib/rules/common/operation-tag-defined.d.ts +2 -0
- package/lib/rules/common/operation-tag-defined.js +24 -0
- package/lib/rules/common/parameter-description.d.ts +2 -0
- package/lib/rules/common/parameter-description.js +22 -0
- package/lib/rules/common/path-declaration-must-exist.d.ts +2 -0
- package/lib/rules/common/path-declaration-must-exist.js +16 -0
- package/lib/rules/common/path-excludes-patterns.d.ts +2 -0
- package/lib/rules/common/path-excludes-patterns.js +22 -0
- package/lib/rules/common/path-http-verbs-order.d.ts +2 -0
- package/lib/rules/common/path-http-verbs-order.js +26 -0
- package/lib/rules/common/path-not-include-query.d.ts +2 -0
- package/lib/rules/common/path-not-include-query.js +18 -0
- package/lib/rules/common/path-params-defined.d.ts +2 -0
- package/lib/rules/common/path-params-defined.js +58 -0
- package/lib/rules/common/path-segment-plural.d.ts +2 -0
- package/lib/rules/common/path-segment-plural.js +33 -0
- package/lib/rules/common/paths-kebab-case.d.ts +2 -0
- package/lib/rules/common/paths-kebab-case.js +20 -0
- package/lib/rules/common/required-string-property-missing-min-length.d.ts +2 -0
- package/lib/rules/common/required-string-property-missing-min-length.js +37 -0
- package/lib/rules/common/response-contains-header.d.ts +2 -0
- package/lib/rules/common/response-contains-header.js +29 -0
- package/lib/rules/common/scalar-property-missing-example.d.ts +2 -0
- package/lib/rules/common/scalar-property-missing-example.js +42 -0
- package/lib/rules/common/security-defined.d.ts +2 -0
- package/lib/rules/common/security-defined.js +65 -0
- package/lib/rules/common/spec-strict-refs.d.ts +2 -0
- package/lib/rules/common/spec-strict-refs.js +30 -0
- package/lib/rules/common/struct.d.ts +2 -0
- package/lib/rules/common/struct.js +158 -0
- package/lib/rules/common/tag-description.d.ts +2 -0
- package/lib/rules/common/tag-description.js +12 -0
- package/lib/rules/common/tags-alphabetical.d.ts +2 -0
- package/lib/rules/common/tags-alphabetical.js +23 -0
- package/lib/rules/no-unresolved-refs.d.ts +5 -0
- package/lib/rules/no-unresolved-refs.js +46 -0
- package/lib/rules/oas2/boolean-parameter-prefixes.d.ts +5 -0
- package/lib/rules/oas2/boolean-parameter-prefixes.js +22 -0
- package/lib/rules/oas2/index.d.ts +3 -0
- package/lib/rules/oas2/index.js +98 -0
- package/lib/rules/oas2/request-mime-type.d.ts +2 -0
- package/lib/rules/oas2/request-mime-type.js +17 -0
- package/lib/rules/oas2/response-contains-property.d.ts +2 -0
- package/lib/rules/oas2/response-contains-property.js +37 -0
- package/lib/rules/oas2/response-mime-type.d.ts +2 -0
- package/lib/rules/oas2/response-mime-type.js +17 -0
- package/lib/rules/oas3/array-parameter-serialization.d.ts +5 -0
- package/lib/rules/oas3/array-parameter-serialization.js +29 -0
- package/lib/rules/oas3/boolean-parameter-prefixes.d.ts +5 -0
- package/lib/rules/oas3/boolean-parameter-prefixes.js +24 -0
- package/lib/rules/oas3/component-name-unique.d.ts +2 -0
- package/lib/rules/oas3/component-name-unique.js +133 -0
- package/lib/rules/oas3/index.d.ts +3 -0
- package/lib/rules/oas3/index.js +122 -0
- package/lib/rules/oas3/no-empty-servers.d.ts +2 -0
- package/lib/rules/oas3/no-empty-servers.js +23 -0
- package/lib/rules/oas3/no-example-value-and-externalValue.d.ts +2 -0
- package/lib/rules/oas3/no-example-value-and-externalValue.js +16 -0
- package/lib/rules/oas3/no-invalid-media-type-examples.d.ts +2 -0
- package/lib/rules/oas3/no-invalid-media-type-examples.js +39 -0
- package/lib/rules/oas3/no-server-example.com.d.ts +2 -0
- package/lib/rules/oas3/no-server-example.com.js +18 -0
- package/lib/rules/oas3/no-server-trailing-slash.d.ts +2 -0
- package/lib/rules/oas3/no-server-trailing-slash.js +18 -0
- package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +2 -0
- package/lib/rules/oas3/no-server-variables-empty-enum.js +66 -0
- package/lib/rules/oas3/no-undefined-server-variable.d.ts +2 -0
- package/lib/rules/oas3/no-undefined-server-variable.js +31 -0
- package/lib/rules/oas3/no-unused-components.d.ts +2 -0
- package/lib/rules/oas3/no-unused-components.js +73 -0
- package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.d.ts +5 -0
- package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.js +36 -0
- package/lib/rules/oas3/request-mime-type.d.ts +2 -0
- package/lib/rules/oas3/request-mime-type.js +31 -0
- package/lib/rules/oas3/response-contains-property.d.ts +2 -0
- package/lib/rules/oas3/response-contains-property.js +39 -0
- package/lib/rules/oas3/response-mime-type.d.ts +2 -0
- package/lib/rules/oas3/response-mime-type.js +31 -0
- package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +2 -0
- package/lib/rules/oas3/spec-components-invalid-map-name.js +62 -0
- package/lib/rules/other/stats.d.ts +41 -0
- package/lib/rules/other/stats.js +75 -0
- package/lib/rules/spot/no-criteria-xpath.d.ts +2 -0
- package/lib/rules/spot/no-criteria-xpath.js +21 -0
- package/lib/rules/spot/spot-supported-versions.d.ts +2 -0
- package/lib/rules/spot/spot-supported-versions.js +21 -0
- package/lib/rules/utils.d.ts +22 -0
- package/lib/rules/utils.js +183 -0
- package/lib/types/arazzo.d.ts +2 -0
- package/lib/types/arazzo.js +311 -0
- package/lib/types/asyncapi2.d.ts +17 -0
- package/lib/types/asyncapi2.js +1008 -0
- package/lib/types/asyncapi3.d.ts +2 -0
- package/lib/types/asyncapi3.js +347 -0
- package/lib/types/index.d.ts +57 -0
- package/lib/types/index.js +94 -0
- package/lib/types/json-schema-adapter.d.ts +3 -0
- package/lib/types/json-schema-adapter.js +159 -0
- package/lib/types/oas2.d.ts +3 -0
- package/lib/types/oas2.js +456 -0
- package/lib/types/oas3.d.ts +7 -0
- package/lib/types/oas3.js +554 -0
- package/lib/types/oas3_1.d.ts +6 -0
- package/lib/types/oas3_1.js +285 -0
- package/lib/types/redocly-yaml.d.ts +26 -0
- package/lib/types/redocly-yaml.js +1126 -0
- package/lib/typings/arazzo.d.ts +131 -0
- package/lib/typings/arazzo.js +5 -0
- package/lib/typings/asyncapi.d.ts +21 -0
- package/lib/typings/asyncapi.js +2 -0
- package/lib/typings/asyncapi3.d.ts +53 -0
- package/lib/typings/asyncapi3.js +2 -0
- package/lib/typings/common.d.ts +8 -0
- package/lib/typings/common.js +2 -0
- package/lib/typings/openapi.d.ts +355 -0
- package/lib/typings/openapi.js +2 -0
- package/lib/typings/swagger.d.ts +217 -0
- package/lib/typings/swagger.js +2 -0
- package/lib/utils.d.ts +70 -0
- package/lib/utils.js +301 -0
- package/lib/visitors.d.ts +229 -0
- package/lib/visitors.js +176 -0
- package/lib/walk.d.ts +78 -0
- package/lib/walk.js +290 -0
- package/package.json +59 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.asserts = exports.runOnValuesSet = exports.runOnKeysSet = void 0;
|
|
4
|
+
exports.buildAssertCustomFunction = buildAssertCustomFunction;
|
|
5
|
+
const utils_1 = require("../../../utils");
|
|
6
|
+
const utils_2 = require("./utils");
|
|
7
|
+
exports.runOnKeysSet = new Set([
|
|
8
|
+
'mutuallyExclusive',
|
|
9
|
+
'mutuallyRequired',
|
|
10
|
+
'enum',
|
|
11
|
+
'pattern',
|
|
12
|
+
'notPattern',
|
|
13
|
+
'minLength',
|
|
14
|
+
'maxLength',
|
|
15
|
+
'casing',
|
|
16
|
+
'sortOrder',
|
|
17
|
+
'disallowed',
|
|
18
|
+
'required',
|
|
19
|
+
'requireAny',
|
|
20
|
+
'ref',
|
|
21
|
+
'const',
|
|
22
|
+
'defined', // In case if `property` for assertions is not added
|
|
23
|
+
]);
|
|
24
|
+
exports.runOnValuesSet = new Set([
|
|
25
|
+
'pattern',
|
|
26
|
+
'notPattern',
|
|
27
|
+
'enum',
|
|
28
|
+
'defined',
|
|
29
|
+
'undefined',
|
|
30
|
+
'nonEmpty',
|
|
31
|
+
'minLength',
|
|
32
|
+
'maxLength',
|
|
33
|
+
'casing',
|
|
34
|
+
'sortOrder',
|
|
35
|
+
'ref',
|
|
36
|
+
'const',
|
|
37
|
+
]);
|
|
38
|
+
exports.asserts = {
|
|
39
|
+
pattern: (value, condition, { baseLocation, rawValue }) => {
|
|
40
|
+
if (typeof value === 'undefined' || (0, utils_1.isPlainObject)(value))
|
|
41
|
+
return []; // property doesn't exist or is an object, no need to lint it with this assert
|
|
42
|
+
const values = Array.isArray(value) ? value : [value];
|
|
43
|
+
const regex = (0, utils_2.regexFromString)(condition);
|
|
44
|
+
return values
|
|
45
|
+
.map((_val) => !regex?.test(_val) && {
|
|
46
|
+
message: `"${_val}" should match a regex ${condition}`,
|
|
47
|
+
location: (0, utils_1.isString)(value)
|
|
48
|
+
? baseLocation
|
|
49
|
+
: (0, utils_1.isPlainObject)(rawValue)
|
|
50
|
+
? baseLocation.child(_val).key()
|
|
51
|
+
: baseLocation.key(),
|
|
52
|
+
})
|
|
53
|
+
.filter(utils_1.isTruthy);
|
|
54
|
+
},
|
|
55
|
+
notPattern: (value, condition, { baseLocation, rawValue }) => {
|
|
56
|
+
if (typeof value === 'undefined' || (0, utils_1.isPlainObject)(value))
|
|
57
|
+
return []; // property doesn't exist or is an object, no need to lint it with this assert
|
|
58
|
+
const values = Array.isArray(value) ? value : [value];
|
|
59
|
+
const regex = (0, utils_2.regexFromString)(condition);
|
|
60
|
+
return values
|
|
61
|
+
.map((_val) => regex?.test(_val) && {
|
|
62
|
+
message: `"${_val}" should not match a regex ${condition}`,
|
|
63
|
+
location: (0, utils_1.isString)(value)
|
|
64
|
+
? baseLocation
|
|
65
|
+
: (0, utils_1.isPlainObject)(rawValue)
|
|
66
|
+
? baseLocation.child(_val).key()
|
|
67
|
+
: baseLocation.key(),
|
|
68
|
+
})
|
|
69
|
+
.filter(utils_1.isTruthy);
|
|
70
|
+
},
|
|
71
|
+
enum: (value, condition, { baseLocation }) => {
|
|
72
|
+
if (typeof value === 'undefined' || (0, utils_1.isPlainObject)(value))
|
|
73
|
+
return []; // property doesn't exist or is an object, no need to lint it with this assert
|
|
74
|
+
const values = Array.isArray(value) ? value : [value];
|
|
75
|
+
return values
|
|
76
|
+
.map((_val) => !condition.includes(_val) && {
|
|
77
|
+
message: `"${_val}" should be one of the predefined values`,
|
|
78
|
+
location: (0, utils_1.isString)(value) ? baseLocation : baseLocation.child(_val).key(),
|
|
79
|
+
})
|
|
80
|
+
.filter(utils_1.isTruthy);
|
|
81
|
+
},
|
|
82
|
+
defined: (value, condition = true, { baseLocation }) => {
|
|
83
|
+
const isDefined = typeof value !== 'undefined';
|
|
84
|
+
const isValid = condition ? isDefined : !isDefined;
|
|
85
|
+
return isValid
|
|
86
|
+
? []
|
|
87
|
+
: [
|
|
88
|
+
{
|
|
89
|
+
message: condition ? `Should be defined` : 'Should be not defined',
|
|
90
|
+
location: baseLocation,
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
},
|
|
94
|
+
required: (value, keys, { baseLocation }) => {
|
|
95
|
+
return keys
|
|
96
|
+
.map((requiredKey) => !value.includes(requiredKey) && {
|
|
97
|
+
message: `${requiredKey} is required`,
|
|
98
|
+
location: baseLocation.key(),
|
|
99
|
+
})
|
|
100
|
+
.filter(utils_1.isTruthy);
|
|
101
|
+
},
|
|
102
|
+
disallowed: (value, condition, { baseLocation }) => {
|
|
103
|
+
if (typeof value === 'undefined' || (0, utils_1.isPlainObject)(value))
|
|
104
|
+
return []; // property doesn't exist or is an object, no need to lint it with this assert
|
|
105
|
+
const values = Array.isArray(value) ? value : [value];
|
|
106
|
+
return values
|
|
107
|
+
.map((_val) => condition.includes(_val) && {
|
|
108
|
+
message: `"${_val}" is disallowed`,
|
|
109
|
+
location: (0, utils_1.isString)(value) ? baseLocation : baseLocation.child(_val).key(),
|
|
110
|
+
})
|
|
111
|
+
.filter(utils_1.isTruthy);
|
|
112
|
+
},
|
|
113
|
+
const: (value, condition, { baseLocation }) => {
|
|
114
|
+
if (typeof value === 'undefined')
|
|
115
|
+
return [];
|
|
116
|
+
if (Array.isArray(value)) {
|
|
117
|
+
return value
|
|
118
|
+
.map((_val) => condition !== _val && {
|
|
119
|
+
message: `"${_val}" should be equal ${condition} `,
|
|
120
|
+
location: (0, utils_1.isString)(value) ? baseLocation : baseLocation.child(_val).key(),
|
|
121
|
+
})
|
|
122
|
+
.filter(utils_1.isTruthy);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return value !== condition
|
|
126
|
+
? [
|
|
127
|
+
{
|
|
128
|
+
message: `${value} should be equal ${condition}`,
|
|
129
|
+
location: baseLocation,
|
|
130
|
+
},
|
|
131
|
+
]
|
|
132
|
+
: [];
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
undefined: (value, condition = true, { baseLocation }) => {
|
|
136
|
+
const isUndefined = typeof value === 'undefined';
|
|
137
|
+
const isValid = condition ? isUndefined : !isUndefined;
|
|
138
|
+
return isValid
|
|
139
|
+
? []
|
|
140
|
+
: [
|
|
141
|
+
{
|
|
142
|
+
message: condition ? `Should not be defined` : 'Should be defined',
|
|
143
|
+
location: baseLocation,
|
|
144
|
+
},
|
|
145
|
+
];
|
|
146
|
+
},
|
|
147
|
+
nonEmpty: (value, condition = true, { baseLocation }) => {
|
|
148
|
+
const isEmpty = typeof value === 'undefined' || value === null || value === '';
|
|
149
|
+
const isValid = condition ? !isEmpty : isEmpty;
|
|
150
|
+
return isValid
|
|
151
|
+
? []
|
|
152
|
+
: [
|
|
153
|
+
{
|
|
154
|
+
message: condition ? `Should not be empty` : 'Should be empty',
|
|
155
|
+
location: baseLocation,
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
},
|
|
159
|
+
minLength: (value, condition, { baseLocation }) => {
|
|
160
|
+
if (typeof value === 'undefined' || value.length >= condition)
|
|
161
|
+
return []; // property doesn't exist, no need to lint it with this assert
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
message: `Should have at least ${condition} characters`,
|
|
165
|
+
location: baseLocation,
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
},
|
|
169
|
+
maxLength: (value, condition, { baseLocation }) => {
|
|
170
|
+
if (typeof value === 'undefined' || value.length <= condition)
|
|
171
|
+
return []; // property doesn't exist, no need to lint it with this assert
|
|
172
|
+
return [
|
|
173
|
+
{
|
|
174
|
+
message: `Should have at most ${condition} characters`,
|
|
175
|
+
location: baseLocation,
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
},
|
|
179
|
+
casing: (value, condition, { baseLocation }) => {
|
|
180
|
+
if (typeof value === 'undefined' || (0, utils_1.isPlainObject)(value))
|
|
181
|
+
return []; // property doesn't exist or is an object, no need to lint it with this assert
|
|
182
|
+
const values = Array.isArray(value) ? value : [value];
|
|
183
|
+
const casingRegexes = {
|
|
184
|
+
camelCase: /^[a-z][a-zA-Z0-9]*$/g,
|
|
185
|
+
'kebab-case': /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/g,
|
|
186
|
+
snake_case: /^([a-z][a-z0-9]*)(_[a-z0-9]+)*$/g,
|
|
187
|
+
PascalCase: /^[A-Z][a-zA-Z0-9]+$/g,
|
|
188
|
+
MACRO_CASE: /^([A-Z][A-Z0-9]*)(_[A-Z0-9]+)*$/g,
|
|
189
|
+
'COBOL-CASE': /^([A-Z][A-Z0-9]*)(-[A-Z0-9]+)*$/g,
|
|
190
|
+
flatcase: /^[a-z][a-z0-9]+$/g,
|
|
191
|
+
};
|
|
192
|
+
return values
|
|
193
|
+
.map((_val) => !_val.match(casingRegexes[condition]) && {
|
|
194
|
+
message: `"${_val}" should use ${condition}`,
|
|
195
|
+
location: (0, utils_1.isString)(value) ? baseLocation : baseLocation.child(_val).key(),
|
|
196
|
+
})
|
|
197
|
+
.filter(utils_1.isTruthy);
|
|
198
|
+
},
|
|
199
|
+
sortOrder: (value, condition, { baseLocation }) => {
|
|
200
|
+
const direction = condition.direction || condition;
|
|
201
|
+
const property = condition.property;
|
|
202
|
+
if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'object' && !property) {
|
|
203
|
+
return [
|
|
204
|
+
{
|
|
205
|
+
message: `Please define a property to sort objects by`,
|
|
206
|
+
location: baseLocation,
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
}
|
|
210
|
+
if (typeof value === 'undefined' || (0, utils_2.isOrdered)(value, condition))
|
|
211
|
+
return [];
|
|
212
|
+
return [
|
|
213
|
+
{
|
|
214
|
+
message: `Should be sorted in ${direction === 'asc' ? 'an ascending' : 'a descending'} order${property ? ` by property ${property}` : ''}`,
|
|
215
|
+
location: baseLocation,
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
},
|
|
219
|
+
mutuallyExclusive: (value, condition, { baseLocation }) => {
|
|
220
|
+
if ((0, utils_2.getIntersectionLength)(value, condition) < 2)
|
|
221
|
+
return [];
|
|
222
|
+
return [
|
|
223
|
+
{
|
|
224
|
+
message: `${condition.join(', ')} keys should be mutually exclusive`,
|
|
225
|
+
location: baseLocation.key(),
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
},
|
|
229
|
+
mutuallyRequired: (value, condition, { baseLocation }) => {
|
|
230
|
+
const isValid = (0, utils_2.getIntersectionLength)(value, condition) > 0
|
|
231
|
+
? (0, utils_2.getIntersectionLength)(value, condition) === condition.length
|
|
232
|
+
: true;
|
|
233
|
+
return isValid
|
|
234
|
+
? []
|
|
235
|
+
: [
|
|
236
|
+
{
|
|
237
|
+
message: `Properties ${condition.join(', ')} are mutually required`,
|
|
238
|
+
location: baseLocation.key(),
|
|
239
|
+
},
|
|
240
|
+
];
|
|
241
|
+
},
|
|
242
|
+
requireAny: (value, condition, { baseLocation }) => {
|
|
243
|
+
return (0, utils_2.getIntersectionLength)(value, condition) >= 1
|
|
244
|
+
? []
|
|
245
|
+
: [
|
|
246
|
+
{
|
|
247
|
+
message: `Should have any of ${condition.join(', ')}`,
|
|
248
|
+
location: baseLocation.key(),
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
},
|
|
252
|
+
ref: (_value, condition, { baseLocation, rawValue }) => {
|
|
253
|
+
if (typeof rawValue === 'undefined')
|
|
254
|
+
return []; // property doesn't exist, no need to lint it with this assert
|
|
255
|
+
const hasRef = rawValue.hasOwnProperty('$ref');
|
|
256
|
+
if (typeof condition === 'boolean') {
|
|
257
|
+
const isValid = condition ? hasRef : !hasRef;
|
|
258
|
+
return isValid
|
|
259
|
+
? []
|
|
260
|
+
: [
|
|
261
|
+
{
|
|
262
|
+
message: condition ? `should use $ref` : 'should not use $ref',
|
|
263
|
+
location: hasRef ? baseLocation : baseLocation.key(),
|
|
264
|
+
},
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
const regex = (0, utils_2.regexFromString)(condition);
|
|
268
|
+
const isValid = hasRef && regex?.test(rawValue['$ref']);
|
|
269
|
+
return isValid
|
|
270
|
+
? []
|
|
271
|
+
: [
|
|
272
|
+
{
|
|
273
|
+
message: `$ref value should match ${condition}`,
|
|
274
|
+
location: hasRef ? baseLocation : baseLocation.key(),
|
|
275
|
+
},
|
|
276
|
+
];
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
function buildAssertCustomFunction(fn) {
|
|
280
|
+
return (value, options, ctx) => fn.call(null, value, options, ctx);
|
|
281
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { asserts, AssertionFn } from './asserts';
|
|
2
|
+
import type { Arazzo1Visitor, Async2Visitor, Async3Visitor, Oas2Visitor, Oas3Visitor } from '../../../visitors';
|
|
3
|
+
import type { RuleSeverity } from '../../../config';
|
|
4
|
+
export type AssertionLocators = {
|
|
5
|
+
filterInParentKeys?: (string | number)[];
|
|
6
|
+
filterOutParentKeys?: (string | number)[];
|
|
7
|
+
matchParentKeys?: string;
|
|
8
|
+
};
|
|
9
|
+
export type AssertionDefinition = {
|
|
10
|
+
subject: {
|
|
11
|
+
type: string;
|
|
12
|
+
property?: string | string[];
|
|
13
|
+
} & AssertionLocators;
|
|
14
|
+
assertions: {
|
|
15
|
+
[name in keyof typeof asserts]?: AssertionFn;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export type RawAssertion = AssertionDefinition & {
|
|
19
|
+
where?: AssertionDefinition[];
|
|
20
|
+
message?: string;
|
|
21
|
+
suggest?: string[];
|
|
22
|
+
severity?: RuleSeverity;
|
|
23
|
+
};
|
|
24
|
+
export type Assertion = RawAssertion & {
|
|
25
|
+
assertionId: string;
|
|
26
|
+
};
|
|
27
|
+
export declare const Assertions: (opts: Record<string, Assertion>) => (Oas3Visitor | Oas2Visitor | Async2Visitor | Async3Visitor | Arazzo1Visitor)[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Assertions = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const utils_2 = require("../../../utils");
|
|
6
|
+
const Assertions = (opts) => {
|
|
7
|
+
const visitors = [];
|
|
8
|
+
// As 'Assertions' has an array of asserts,
|
|
9
|
+
// that array spreads into an 'opts' object on init rules phase here
|
|
10
|
+
// https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/config/config.ts#L311
|
|
11
|
+
// that is why we need to iterate through 'opts' values;
|
|
12
|
+
// before - filter only object 'opts' values
|
|
13
|
+
const assertions = Object.values(opts).filter((opt) => typeof opt === 'object' && opt !== null);
|
|
14
|
+
for (const [_, assertion] of assertions.entries()) {
|
|
15
|
+
if (!(0, utils_2.isString)(assertion.subject.type)) {
|
|
16
|
+
throw new Error(`${assertion.assertionId}: 'type' (String) is required`);
|
|
17
|
+
}
|
|
18
|
+
const subjectVisitor = (0, utils_1.buildSubjectVisitor)(assertion.assertionId, assertion);
|
|
19
|
+
const visitorObject = (0, utils_1.buildVisitorObject)(assertion, subjectVisitor);
|
|
20
|
+
visitors.push(visitorObject);
|
|
21
|
+
}
|
|
22
|
+
return visitors;
|
|
23
|
+
};
|
|
24
|
+
exports.Assertions = Assertions;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Asserts } from './asserts';
|
|
2
|
+
import type { AssertionContext, AssertResult } from '../../../config';
|
|
3
|
+
import type { Assertion, AssertionDefinition } from '.';
|
|
4
|
+
import type { Oas2Visitor, Oas3Visitor, VisitFunction } from '../../../visitors';
|
|
5
|
+
export type OrderDirection = 'asc' | 'desc';
|
|
6
|
+
export type OrderOptions = {
|
|
7
|
+
direction: OrderDirection;
|
|
8
|
+
property: string;
|
|
9
|
+
};
|
|
10
|
+
export type AssertToApply = {
|
|
11
|
+
name: keyof Asserts;
|
|
12
|
+
conditions: any;
|
|
13
|
+
runsOnKeys: boolean;
|
|
14
|
+
runsOnValues: boolean;
|
|
15
|
+
};
|
|
16
|
+
type RunAssertionParams = {
|
|
17
|
+
ctx: AssertionContext;
|
|
18
|
+
assert: AssertToApply;
|
|
19
|
+
assertionProperty?: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function getAssertsToApply(assertion: AssertionDefinition): AssertToApply[];
|
|
22
|
+
export declare function buildVisitorObject(assertion: Assertion, subjectVisitor: VisitFunction<any>): Oas2Visitor | Oas3Visitor;
|
|
23
|
+
export declare function buildSubjectVisitor(assertId: string, assertion: Assertion): VisitFunction<any>;
|
|
24
|
+
export declare function getIntersectionLength(keys: string[], properties: string[]): number;
|
|
25
|
+
export declare function isOrdered(value: any[], options: OrderOptions | OrderDirection): boolean;
|
|
26
|
+
export declare function runAssertion({ assert, ctx, assertionProperty, }: RunAssertionParams): AssertResult[];
|
|
27
|
+
export declare function regexFromString(input: string): RegExp | null;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAssertsToApply = getAssertsToApply;
|
|
4
|
+
exports.buildVisitorObject = buildVisitorObject;
|
|
5
|
+
exports.buildSubjectVisitor = buildSubjectVisitor;
|
|
6
|
+
exports.getIntersectionLength = getIntersectionLength;
|
|
7
|
+
exports.isOrdered = isOrdered;
|
|
8
|
+
exports.runAssertion = runAssertion;
|
|
9
|
+
exports.regexFromString = regexFromString;
|
|
10
|
+
const asserts_1 = require("./asserts");
|
|
11
|
+
const logger_1 = require("../../../logger");
|
|
12
|
+
const ref_utils_1 = require("../../../ref-utils");
|
|
13
|
+
const utils_1 = require("../../../utils");
|
|
14
|
+
const assertionMessageTemplates = {
|
|
15
|
+
problems: '{{problems}}',
|
|
16
|
+
};
|
|
17
|
+
function getPredicatesFromLocators(locators) {
|
|
18
|
+
const { filterInParentKeys, filterOutParentKeys, matchParentKeys } = locators;
|
|
19
|
+
const keyMatcher = matchParentKeys && regexFromString(matchParentKeys);
|
|
20
|
+
const matchKeysPredicate = keyMatcher && ((key) => keyMatcher.test(key.toString()));
|
|
21
|
+
const filterInPredicate = Array.isArray(filterInParentKeys) &&
|
|
22
|
+
((key) => filterInParentKeys.includes(key.toString()));
|
|
23
|
+
const filterOutPredicate = Array.isArray(filterOutParentKeys) &&
|
|
24
|
+
((key) => !filterOutParentKeys.includes(key.toString()));
|
|
25
|
+
return [matchKeysPredicate, filterInPredicate, filterOutPredicate].filter(utils_1.isTruthy);
|
|
26
|
+
}
|
|
27
|
+
function getAssertsToApply(assertion) {
|
|
28
|
+
const assertsToApply = (0, utils_1.keysOf)(asserts_1.asserts)
|
|
29
|
+
.filter((assertName) => assertion.assertions[assertName] !== undefined)
|
|
30
|
+
.map((assertName) => {
|
|
31
|
+
return {
|
|
32
|
+
name: assertName,
|
|
33
|
+
conditions: assertion.assertions[assertName],
|
|
34
|
+
runsOnKeys: asserts_1.runOnKeysSet.has(assertName),
|
|
35
|
+
runsOnValues: asserts_1.runOnValuesSet.has(assertName),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
const shouldRunOnKeys = assertsToApply.find((assert) => assert.runsOnKeys && !assert.runsOnValues);
|
|
39
|
+
const shouldRunOnValues = assertsToApply.find((assert) => assert.runsOnValues && !assert.runsOnKeys);
|
|
40
|
+
if (shouldRunOnValues && !assertion.subject.property) {
|
|
41
|
+
throw new Error(`The '${shouldRunOnValues.name}' assertion can't be used on all keys. Please provide a single property.`);
|
|
42
|
+
}
|
|
43
|
+
if (shouldRunOnKeys && assertion.subject.property) {
|
|
44
|
+
throw new Error(`The '${shouldRunOnKeys.name}' assertion can't be used on properties. Please remove the 'property' key.`);
|
|
45
|
+
}
|
|
46
|
+
return assertsToApply;
|
|
47
|
+
}
|
|
48
|
+
function getAssertionProperties({ subject }) {
|
|
49
|
+
return (Array.isArray(subject.property) ? subject.property : [subject?.property]).filter(Boolean);
|
|
50
|
+
}
|
|
51
|
+
function applyAssertions(assertionDefinition, asserts, ctx) {
|
|
52
|
+
const properties = getAssertionProperties(assertionDefinition);
|
|
53
|
+
const assertResults = [];
|
|
54
|
+
for (const assert of asserts) {
|
|
55
|
+
if (properties.length) {
|
|
56
|
+
for (const property of properties) {
|
|
57
|
+
assertResults.push(runAssertion({
|
|
58
|
+
assert,
|
|
59
|
+
ctx,
|
|
60
|
+
assertionProperty: property,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
assertResults.push(runAssertion({
|
|
66
|
+
assert,
|
|
67
|
+
ctx,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return assertResults.flat();
|
|
72
|
+
}
|
|
73
|
+
function buildVisitorObject(assertion, subjectVisitor) {
|
|
74
|
+
const targetVisitorLocatorPredicates = getPredicatesFromLocators(assertion.subject);
|
|
75
|
+
const targetVisitorSkipFunction = targetVisitorLocatorPredicates.length
|
|
76
|
+
? (_, key) => !targetVisitorLocatorPredicates.every((predicate) => predicate(key))
|
|
77
|
+
: undefined;
|
|
78
|
+
const targetVisitor = {
|
|
79
|
+
[assertion.subject.type]: {
|
|
80
|
+
enter: subjectVisitor,
|
|
81
|
+
...(targetVisitorSkipFunction && { skip: targetVisitorSkipFunction }),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
if (!Array.isArray(assertion.where)) {
|
|
85
|
+
return targetVisitor;
|
|
86
|
+
}
|
|
87
|
+
let currentVisitorLevel = {};
|
|
88
|
+
const visitor = currentVisitorLevel;
|
|
89
|
+
const context = assertion.where;
|
|
90
|
+
for (let index = 0; index < context.length; index++) {
|
|
91
|
+
const assertionDefinitionNode = context[index];
|
|
92
|
+
if (!(0, utils_1.isString)(assertionDefinitionNode.subject?.type)) {
|
|
93
|
+
throw new Error(`${assertion.assertionId} -> where -> [${index}]: 'type' (String) is required`);
|
|
94
|
+
}
|
|
95
|
+
const locatorPredicates = getPredicatesFromLocators(assertionDefinitionNode.subject);
|
|
96
|
+
const assertsToApply = getAssertsToApply(assertionDefinitionNode);
|
|
97
|
+
const skipFunction = (node, key, ctx) => !locatorPredicates.every((predicate) => predicate(key)) ||
|
|
98
|
+
!!applyAssertions(assertionDefinitionNode, assertsToApply, { ...ctx, node }).length;
|
|
99
|
+
const nodeVisitor = {
|
|
100
|
+
...((locatorPredicates.length || assertsToApply.length) && { skip: skipFunction }),
|
|
101
|
+
};
|
|
102
|
+
if (assertionDefinitionNode.subject.type === assertion.subject.type &&
|
|
103
|
+
index === context.length - 1) {
|
|
104
|
+
// We have to merge the visitors if the last node inside the `where` is the same as the subject.
|
|
105
|
+
targetVisitor[assertion.subject.type] = {
|
|
106
|
+
enter: subjectVisitor,
|
|
107
|
+
...((nodeVisitor.skip && { skip: nodeVisitor.skip }) ||
|
|
108
|
+
(targetVisitorSkipFunction && {
|
|
109
|
+
skip: (node, key, ctx // We may have locators defined on assertion level and on where level for the same node type
|
|
110
|
+
) => !!(nodeVisitor.skip?.(node, key, ctx) || targetVisitorSkipFunction?.(node, key)),
|
|
111
|
+
})),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
currentVisitorLevel = currentVisitorLevel[assertionDefinitionNode.subject?.type] =
|
|
116
|
+
nodeVisitor;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
currentVisitorLevel[assertion.subject.type] = targetVisitor[assertion.subject.type];
|
|
120
|
+
return visitor;
|
|
121
|
+
}
|
|
122
|
+
function buildSubjectVisitor(assertId, assertion) {
|
|
123
|
+
return (node, ctx) => {
|
|
124
|
+
const properties = getAssertionProperties(assertion);
|
|
125
|
+
const defaultMessage = `${logger_1.colorize.blue(assertId)} failed because the ${logger_1.colorize.blue(assertion.subject.type)} ${logger_1.colorize.blue(properties.join(', '))} didn't meet the assertions: ${assertionMessageTemplates.problems}`.replace(/ +/g, ' ');
|
|
126
|
+
const problems = applyAssertions(assertion, getAssertsToApply(assertion), {
|
|
127
|
+
...ctx,
|
|
128
|
+
node,
|
|
129
|
+
});
|
|
130
|
+
if (problems.length) {
|
|
131
|
+
for (const problemGroup of groupProblemsByPointer(problems)) {
|
|
132
|
+
const message = assertion.message || defaultMessage;
|
|
133
|
+
const problemMessage = getProblemsMessage(problemGroup);
|
|
134
|
+
ctx.report({
|
|
135
|
+
message: message.replace(assertionMessageTemplates.problems, problemMessage),
|
|
136
|
+
location: getProblemsLocation(problemGroup) || ctx.location,
|
|
137
|
+
forceSeverity: assertion.severity || 'error',
|
|
138
|
+
suggest: assertion.suggest || [],
|
|
139
|
+
ruleId: assertId,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function groupProblemsByPointer(problems) {
|
|
146
|
+
const groups = {};
|
|
147
|
+
for (const problem of problems) {
|
|
148
|
+
if (!problem.location)
|
|
149
|
+
continue;
|
|
150
|
+
const pointer = problem.location.pointer;
|
|
151
|
+
groups[pointer] = groups[pointer] || [];
|
|
152
|
+
groups[pointer].push(problem);
|
|
153
|
+
}
|
|
154
|
+
return Object.values(groups);
|
|
155
|
+
}
|
|
156
|
+
function getProblemsLocation(problems) {
|
|
157
|
+
return problems.length ? problems[0].location : undefined;
|
|
158
|
+
}
|
|
159
|
+
function getProblemsMessage(problems) {
|
|
160
|
+
return problems.length === 1
|
|
161
|
+
? problems[0].message ?? ''
|
|
162
|
+
: problems.map((problem) => `\n- ${problem.message ?? ''}`).join('');
|
|
163
|
+
}
|
|
164
|
+
function getIntersectionLength(keys, properties) {
|
|
165
|
+
const props = new Set(properties);
|
|
166
|
+
let count = 0;
|
|
167
|
+
for (const key of keys) {
|
|
168
|
+
if (props.has(key)) {
|
|
169
|
+
count++;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return count;
|
|
173
|
+
}
|
|
174
|
+
function isOrdered(value, options) {
|
|
175
|
+
const direction = options.direction || options;
|
|
176
|
+
const property = options.property;
|
|
177
|
+
for (let i = 1; i < value.length; i++) {
|
|
178
|
+
let currValue = value[i];
|
|
179
|
+
let prevVal = value[i - 1];
|
|
180
|
+
if (property) {
|
|
181
|
+
const currPropValue = value[i][property];
|
|
182
|
+
const prevPropValue = value[i - 1][property];
|
|
183
|
+
if (!currPropValue || !prevPropValue) {
|
|
184
|
+
return false; // property doesn't exist, so collection is not ordered
|
|
185
|
+
}
|
|
186
|
+
currValue = currPropValue;
|
|
187
|
+
prevVal = prevPropValue;
|
|
188
|
+
}
|
|
189
|
+
if (typeof currValue === 'string' && typeof prevVal === 'string') {
|
|
190
|
+
currValue = currValue.toLowerCase();
|
|
191
|
+
prevVal = prevVal.toLowerCase();
|
|
192
|
+
}
|
|
193
|
+
const result = direction === 'asc' ? currValue >= prevVal : currValue <= prevVal;
|
|
194
|
+
if (!result) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
function runAssertion({ assert, ctx, assertionProperty, }) {
|
|
201
|
+
const currentLocation = assert.name === 'ref' ? ctx.rawLocation : ctx.location;
|
|
202
|
+
if (assertionProperty) {
|
|
203
|
+
const values = (0, ref_utils_1.isRef)(ctx.node[assertionProperty])
|
|
204
|
+
? ctx.resolve(ctx.node[assertionProperty])?.node
|
|
205
|
+
: ctx.node[assertionProperty];
|
|
206
|
+
const rawValues = ctx.rawNode[assertionProperty];
|
|
207
|
+
const location = currentLocation.child(assertionProperty);
|
|
208
|
+
return asserts_1.asserts[assert.name](values, assert.conditions, {
|
|
209
|
+
...ctx,
|
|
210
|
+
baseLocation: location,
|
|
211
|
+
rawValue: rawValues,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const value = Array.isArray(ctx.node) ? ctx.node : Object.keys(ctx.node);
|
|
216
|
+
return asserts_1.asserts[assert.name](value, assert.conditions, {
|
|
217
|
+
...ctx,
|
|
218
|
+
rawValue: ctx.rawNode,
|
|
219
|
+
baseLocation: currentLocation,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function regexFromString(input) {
|
|
224
|
+
const matches = input.match(/^\/(.*)\/(.*)|(.*)/);
|
|
225
|
+
return matches && new RegExp(matches[1] || matches[3], matches[2]);
|
|
226
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InfoContact = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const InfoContact = () => {
|
|
6
|
+
return {
|
|
7
|
+
Info(info, { report, location }) {
|
|
8
|
+
if (!info.contact) {
|
|
9
|
+
report({
|
|
10
|
+
message: (0, utils_1.missingRequiredField)('Info', 'contact'),
|
|
11
|
+
location: location.child('contact').key(),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.InfoContact = InfoContact;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InfoLicenseStrict = void 0;
|
|
4
|
+
const oas_types_1 = require("../../oas-types");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const InfoLicenseStrict = () => {
|
|
7
|
+
let specVersion;
|
|
8
|
+
return {
|
|
9
|
+
Root: {
|
|
10
|
+
enter(root) {
|
|
11
|
+
specVersion = (0, oas_types_1.detectSpec)(root);
|
|
12
|
+
},
|
|
13
|
+
License: {
|
|
14
|
+
leave(license, ctx) {
|
|
15
|
+
if (specVersion === 'oas3_1') {
|
|
16
|
+
(0, utils_1.validateOneOfDefinedAndNonEmpty)(['url', 'identifier'], license, ctx);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
(0, utils_1.validateDefinedAndNonEmpty)('url', license, ctx);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.InfoLicenseStrict = InfoLicenseStrict;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InfoLicenseUrl = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const InfoLicenseUrl = () => {
|
|
6
|
+
return {
|
|
7
|
+
License(license, ctx) {
|
|
8
|
+
(0, utils_1.validateDefinedAndNonEmpty)('url', license, ctx);
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
exports.InfoLicenseUrl = InfoLicenseUrl;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InfoLicense = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const InfoLicense = () => {
|
|
6
|
+
return {
|
|
7
|
+
Info(info, { report }) {
|
|
8
|
+
if (!info.license) {
|
|
9
|
+
report({
|
|
10
|
+
message: (0, utils_1.missingRequiredField)('Info', 'license'),
|
|
11
|
+
location: { reportOnKey: true },
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.InfoLicense = InfoLicense;
|