@redocly/openapi-core 1.8.2 → 1.9.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/CHANGELOG.md +10 -0
- package/lib/config/all.js +1 -0
- package/lib/config/minimal.js +1 -0
- package/lib/config/recommended-strict.js +1 -0
- package/lib/config/recommended.js +1 -0
- package/lib/ref-utils.js +3 -3
- package/lib/rules/common/no-required-schema-properties-undefined.d.ts +2 -0
- package/lib/rules/common/no-required-schema-properties-undefined.js +37 -0
- package/lib/rules/oas2/index.js +2 -0
- package/lib/rules/oas3/index.js +2 -0
- package/lib/types/redocly-yaml.d.ts +1 -1
- package/lib/types/redocly-yaml.js +1 -0
- package/package.json +1 -1
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +2 -0
- package/src/config/all.ts +1 -0
- package/src/config/minimal.ts +1 -0
- package/src/config/recommended-strict.ts +1 -0
- package/src/config/recommended.ts +1 -0
- package/src/ref-utils.ts +3 -3
- package/src/rules/common/__tests__/no-required-schema-properties-undefined.test.ts +550 -0
- package/src/rules/common/no-required-schema-properties-undefined.ts +53 -0
- package/src/rules/oas2/index.ts +2 -0
- package/src/rules/oas3/index.ts +2 -0
- package/src/types/redocly-yaml.ts +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @redocly/openapi-core
|
|
2
2
|
|
|
3
|
+
## 1.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added new `no-required-schema-properties-undefined` rule to check if each required schema property is defined.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Fixed an issue where `$ref`s ending in `#` (instead of `#/`) would break the application.
|
|
12
|
+
|
|
3
13
|
## 1.8.2
|
|
4
14
|
|
|
5
15
|
## 1.8.1
|
package/lib/config/all.js
CHANGED
|
@@ -43,6 +43,7 @@ const all = {
|
|
|
43
43
|
'path-params-defined': 'error',
|
|
44
44
|
'required-string-property-missing-min-length': 'error',
|
|
45
45
|
'response-contains-header': 'error',
|
|
46
|
+
'no-required-schema-properties-undefined': 'error',
|
|
46
47
|
},
|
|
47
48
|
oas2Rules: {
|
|
48
49
|
'boolean-parameter-prefixes': 'error',
|
package/lib/config/minimal.js
CHANGED
|
@@ -40,6 +40,7 @@ const recommendedStrict = {
|
|
|
40
40
|
'required-string-property-missing-min-length': 'off',
|
|
41
41
|
'response-contains-header': 'off',
|
|
42
42
|
'scalar-property-missing-example': 'off',
|
|
43
|
+
'no-required-schema-properties-undefined': 'off',
|
|
43
44
|
},
|
|
44
45
|
oas2Rules: {
|
|
45
46
|
'boolean-parameter-prefixes': 'off',
|
|
@@ -40,6 +40,7 @@ const recommended = {
|
|
|
40
40
|
'required-string-property-missing-min-length': 'off',
|
|
41
41
|
'response-contains-header': 'off',
|
|
42
42
|
'scalar-property-missing-example': 'off',
|
|
43
|
+
'no-required-schema-properties-undefined': 'off',
|
|
43
44
|
},
|
|
44
45
|
oas2Rules: {
|
|
45
46
|
'boolean-parameter-prefixes': 'off',
|
package/lib/ref-utils.js
CHANGED
|
@@ -39,15 +39,15 @@ function escapePointer(fragment) {
|
|
|
39
39
|
}
|
|
40
40
|
exports.escapePointer = escapePointer;
|
|
41
41
|
function parseRef(ref) {
|
|
42
|
-
const [uri, pointer] = ref.split('
|
|
42
|
+
const [uri, pointer = ''] = ref.split('#');
|
|
43
43
|
return {
|
|
44
44
|
uri: uri || null,
|
|
45
|
-
pointer: pointer
|
|
45
|
+
pointer: parsePointer(pointer),
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
exports.parseRef = parseRef;
|
|
49
49
|
function parsePointer(pointer) {
|
|
50
|
-
return pointer.
|
|
50
|
+
return pointer.split('/').map(unescapePointer).filter(utils_1.isTruthy);
|
|
51
51
|
}
|
|
52
52
|
exports.parsePointer = parsePointer;
|
|
53
53
|
function pointerBaseName(pointer) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoRequiredSchemaPropertiesUndefined = void 0;
|
|
4
|
+
const ref_utils_1 = require("../../ref-utils");
|
|
5
|
+
const NoRequiredSchemaPropertiesUndefined = () => {
|
|
6
|
+
return {
|
|
7
|
+
Schema: {
|
|
8
|
+
enter(schema, { location, report, resolve }) {
|
|
9
|
+
if (!schema.required)
|
|
10
|
+
return;
|
|
11
|
+
const visitedSchemas = new Set();
|
|
12
|
+
const elevateProperties = (schema) => {
|
|
13
|
+
var _a, _b, _c, _d;
|
|
14
|
+
// Check if the schema has been visited before processing it
|
|
15
|
+
if (visitedSchemas.has(schema)) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
visitedSchemas.add(schema);
|
|
19
|
+
if ((0, ref_utils_1.isRef)(schema)) {
|
|
20
|
+
return elevateProperties(resolve(schema).node);
|
|
21
|
+
}
|
|
22
|
+
return Object.assign({}, schema.properties, ...((_b = (_a = schema.allOf) === null || _a === void 0 ? void 0 : _a.map(elevateProperties)) !== null && _b !== void 0 ? _b : []), ...((_d = (_c = schema.anyOf) === null || _c === void 0 ? void 0 : _c.map(elevateProperties)) !== null && _d !== void 0 ? _d : []));
|
|
23
|
+
};
|
|
24
|
+
const allProperties = elevateProperties(schema);
|
|
25
|
+
for (const [i, requiredProperty] of schema.required.entries()) {
|
|
26
|
+
if (!allProperties || allProperties[requiredProperty] === undefined) {
|
|
27
|
+
report({
|
|
28
|
+
message: `Required property '${requiredProperty}' is undefined.`,
|
|
29
|
+
location: location.child(['required', i]),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
exports.NoRequiredSchemaPropertiesUndefined = NoRequiredSchemaPropertiesUndefined;
|
package/lib/rules/oas2/index.js
CHANGED
|
@@ -43,6 +43,7 @@ const response_contains_property_1 = require("./response-contains-property");
|
|
|
43
43
|
const scalar_property_missing_example_1 = require("../common/scalar-property-missing-example");
|
|
44
44
|
const required_string_property_missing_min_length_1 = require("../common/required-string-property-missing-min-length");
|
|
45
45
|
const spec_strict_refs_1 = require("../common/spec-strict-refs");
|
|
46
|
+
const no_required_schema_properties_undefined_1 = require("../common/no-required-schema-properties-undefined");
|
|
46
47
|
exports.rules = {
|
|
47
48
|
spec: spec_1.Spec,
|
|
48
49
|
'no-invalid-schema-examples': no_invalid_schema_examples_1.NoInvalidSchemaExamples,
|
|
@@ -87,5 +88,6 @@ exports.rules = {
|
|
|
87
88
|
'scalar-property-missing-example': scalar_property_missing_example_1.ScalarPropertyMissingExample,
|
|
88
89
|
'required-string-property-missing-min-length': required_string_property_missing_min_length_1.RequiredStringPropertyMissingMinLength,
|
|
89
90
|
'spec-strict-refs': spec_strict_refs_1.SpecStrictRefs,
|
|
91
|
+
'no-required-schema-properties-undefined': no_required_schema_properties_undefined_1.NoRequiredSchemaPropertiesUndefined,
|
|
90
92
|
};
|
|
91
93
|
exports.preprocessors = {};
|
package/lib/rules/oas3/index.js
CHANGED
|
@@ -55,6 +55,7 @@ const required_string_property_missing_min_length_1 = require("../common/require
|
|
|
55
55
|
const spec_strict_refs_1 = require("../common/spec-strict-refs");
|
|
56
56
|
const component_name_unique_1 = require("./component-name-unique");
|
|
57
57
|
const array_parameter_serialization_1 = require("./array-parameter-serialization");
|
|
58
|
+
const no_required_schema_properties_undefined_1 = require("../common/no-required-schema-properties-undefined");
|
|
58
59
|
exports.rules = {
|
|
59
60
|
spec: spec_1.Spec,
|
|
60
61
|
'info-contact': info_contact_1.InfoContact,
|
|
@@ -111,5 +112,6 @@ exports.rules = {
|
|
|
111
112
|
'spec-strict-refs': spec_strict_refs_1.SpecStrictRefs,
|
|
112
113
|
'component-name-unique': component_name_unique_1.ComponentNameUnique,
|
|
113
114
|
'array-parameter-serialization': array_parameter_serialization_1.ArrayParameterSerialization,
|
|
115
|
+
'no-required-schema-properties-undefined': no_required_schema_properties_undefined_1.NoRequiredSchemaPropertiesUndefined,
|
|
114
116
|
};
|
|
115
117
|
exports.preprocessors = {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NodeType } from '.';
|
|
2
2
|
declare const builtInCommonRules: readonly ["spec", "info-contact", "operation-operationId", "tag-description", "tags-alphabetical"];
|
|
3
3
|
export type BuiltInCommonRuleId = typeof builtInCommonRules[number];
|
|
4
|
-
declare const builtInCommonOASRules: readonly ["info-license-url", "info-license", "no-ambiguous-paths", "no-enum-type-mismatch", "no-http-verbs-in-paths", "no-identical-paths", "no-invalid-parameter-examples", "no-invalid-schema-examples", "no-path-trailing-slash", "operation-2xx-response", "operation-4xx-response", "operation-description", "operation-operationId-unique", "operation-operationId-url-safe", "operation-parameters-unique", "operation-singular-tag", "operation-summary", "operation-tag-defined", "parameter-description", "path-declaration-must-exist", "path-excludes-patterns", "path-http-verbs-order", "path-not-include-query", "path-params-defined", "path-parameters-defined", "path-segment-plural", "paths-kebab-case", "required-string-property-missing-min-length", "response-contains-header", "scalar-property-missing-example", "security-defined", "spec-strict-refs", "no-unresolved-refs"];
|
|
4
|
+
declare const builtInCommonOASRules: readonly ["info-license-url", "info-license", "no-ambiguous-paths", "no-enum-type-mismatch", "no-http-verbs-in-paths", "no-identical-paths", "no-invalid-parameter-examples", "no-invalid-schema-examples", "no-path-trailing-slash", "operation-2xx-response", "operation-4xx-response", "operation-description", "operation-operationId-unique", "operation-operationId-url-safe", "operation-parameters-unique", "operation-singular-tag", "operation-summary", "operation-tag-defined", "parameter-description", "path-declaration-must-exist", "path-excludes-patterns", "path-http-verbs-order", "path-not-include-query", "path-params-defined", "path-parameters-defined", "path-segment-plural", "paths-kebab-case", "required-string-property-missing-min-length", "response-contains-header", "scalar-property-missing-example", "security-defined", "spec-strict-refs", "no-unresolved-refs", "no-required-schema-properties-undefined"];
|
|
5
5
|
export type BuiltInCommonOASRuleId = typeof builtInCommonOASRules[number];
|
|
6
6
|
declare const builtInOAS2Rules: readonly ["boolean-parameter-prefixes", "request-mime-type", "response-contains-property", "response-mime-type"];
|
|
7
7
|
export type BuiltInOAS2RuleId = typeof builtInOAS2Rules[number];
|
package/package.json
CHANGED
|
@@ -74,6 +74,7 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1
|
|
|
74
74
|
"no-invalid-parameter-examples": "off",
|
|
75
75
|
"no-invalid-schema-examples": "off",
|
|
76
76
|
"no-path-trailing-slash": "error",
|
|
77
|
+
"no-required-schema-properties-undefined": "off",
|
|
77
78
|
"no-unresolved-refs": "error",
|
|
78
79
|
"operation-2xx-response": "warn",
|
|
79
80
|
"operation-4xx-response": "error",
|
|
@@ -198,6 +199,7 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w
|
|
|
198
199
|
"no-invalid-parameter-examples": "off",
|
|
199
200
|
"no-invalid-schema-examples": "off",
|
|
200
201
|
"no-path-trailing-slash": "error",
|
|
202
|
+
"no-required-schema-properties-undefined": "off",
|
|
201
203
|
"no-unresolved-refs": "error",
|
|
202
204
|
"operation-2xx-response": "error",
|
|
203
205
|
"operation-4xx-response": "off",
|
package/src/config/all.ts
CHANGED
|
@@ -43,6 +43,7 @@ const all: PluginStyleguideConfig<'built-in'> = {
|
|
|
43
43
|
'path-params-defined': 'error',
|
|
44
44
|
'required-string-property-missing-min-length': 'error',
|
|
45
45
|
'response-contains-header': 'error',
|
|
46
|
+
'no-required-schema-properties-undefined': 'error',
|
|
46
47
|
},
|
|
47
48
|
oas2Rules: {
|
|
48
49
|
'boolean-parameter-prefixes': 'error',
|
package/src/config/minimal.ts
CHANGED
|
@@ -40,6 +40,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
|
|
|
40
40
|
'response-contains-header': 'off',
|
|
41
41
|
'path-segment-plural': 'off',
|
|
42
42
|
'scalar-property-missing-example': 'off',
|
|
43
|
+
'no-required-schema-properties-undefined': 'off',
|
|
43
44
|
},
|
|
44
45
|
oas2Rules: {
|
|
45
46
|
'boolean-parameter-prefixes': 'off',
|
|
@@ -40,6 +40,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
|
|
|
40
40
|
'required-string-property-missing-min-length': 'off',
|
|
41
41
|
'response-contains-header': 'off',
|
|
42
42
|
'scalar-property-missing-example': 'off',
|
|
43
|
+
'no-required-schema-properties-undefined': 'off',
|
|
43
44
|
},
|
|
44
45
|
oas2Rules: {
|
|
45
46
|
'boolean-parameter-prefixes': 'off',
|
|
@@ -40,6 +40,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
|
|
|
40
40
|
'required-string-property-missing-min-length': 'off',
|
|
41
41
|
'response-contains-header': 'off',
|
|
42
42
|
'scalar-property-missing-example': 'off',
|
|
43
|
+
'no-required-schema-properties-undefined': 'off',
|
|
43
44
|
},
|
|
44
45
|
oas2Rules: {
|
|
45
46
|
'boolean-parameter-prefixes': 'off',
|
package/src/ref-utils.ts
CHANGED
|
@@ -43,15 +43,15 @@ export function escapePointer<T extends string | number>(fragment: T): T {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export function parseRef(ref: string): { uri: string | null; pointer: string[] } {
|
|
46
|
-
const [uri, pointer] = ref.split('
|
|
46
|
+
const [uri, pointer = ''] = ref.split('#');
|
|
47
47
|
return {
|
|
48
48
|
uri: uri || null,
|
|
49
|
-
pointer: pointer
|
|
49
|
+
pointer: parsePointer(pointer),
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function parsePointer(pointer: string) {
|
|
54
|
-
return pointer.
|
|
54
|
+
return pointer.split('/').map(unescapePointer).filter(isTruthy);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export function pointerBaseName(pointer: string) {
|