@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,248 +1,193 @@
|
|
|
1
|
-
/** Reads the value at `path` in the parsed document, or `undefined` if absent. */
|
|
2
1
|
const getAtPath = (data, path) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
let current = data;
|
|
3
|
+
for (const segment of path) {
|
|
4
|
+
if (current == null || typeof current !== "object")
|
|
5
|
+
return void 0;
|
|
6
|
+
current = current[segment];
|
|
7
|
+
}
|
|
8
|
+
return current;
|
|
10
9
|
};
|
|
11
|
-
const isObject = (value) => value != null && typeof value ===
|
|
12
|
-
const stripTrailingSlash = (value) => value.replace(/\/+$/,
|
|
13
|
-
/**
|
|
14
|
-
* A deterministic, order-independent serialization used as an equality key. Plain
|
|
15
|
-
* `JSON.stringify` is sensitive to object key order (`{a,b}` vs `{b,a}`), so two
|
|
16
|
-
* deeply-equal enum entries could be seen as different and left un-deduplicated —
|
|
17
|
-
* disagreeing with the `duplicated-entry-in-enum` rule (which compares by value)
|
|
18
|
-
* and preventing `--fix` from converging. Sorting keys recursively fixes that.
|
|
19
|
-
*/
|
|
10
|
+
const isObject = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
11
|
+
const stripTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
20
12
|
const canonicalKey = (value) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
return JSON.stringify(value) ?? 'null';
|
|
13
|
+
if (Array.isArray(value))
|
|
14
|
+
return `[${value.map(canonicalKey).join(",")}]`;
|
|
15
|
+
if (value !== null && typeof value === "object") {
|
|
16
|
+
const entries = Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalKey(value[key])}`);
|
|
17
|
+
return `{${entries.join(",")}}`;
|
|
18
|
+
}
|
|
19
|
+
return JSON.stringify(value) ?? "null";
|
|
30
20
|
};
|
|
31
|
-
/**
|
|
32
|
-
* `oas2-host-trailing-slash` / `oas3-server-trailing-slash`: drop the trailing
|
|
33
|
-
* slash from a string value (host or server URL).
|
|
34
|
-
*/
|
|
35
21
|
const trailingSlashValue = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
22
|
+
safe: true,
|
|
23
|
+
fix: ({ diagnostic, data }) => {
|
|
24
|
+
const value = getAtPath(data, diagnostic.path);
|
|
25
|
+
if (typeof value !== "string")
|
|
26
|
+
return void 0;
|
|
27
|
+
const stripped = stripTrailingSlash(value);
|
|
28
|
+
if (stripped === value || stripped === "")
|
|
29
|
+
return void 0;
|
|
30
|
+
return { op: "setValue", path: diagnostic.path, value: stripped };
|
|
31
|
+
}
|
|
46
32
|
};
|
|
47
|
-
/** `path-keys-no-trailing-slash`: rename a `paths` key to drop its trailing slash. */
|
|
48
33
|
const pathKeyTrailingSlash = {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return undefined;
|
|
63
|
-
return { op: 'renameProperty', path: diagnostic.path, newKey: stripped };
|
|
64
|
-
},
|
|
34
|
+
safe: true,
|
|
35
|
+
fix: ({ diagnostic, data }) => {
|
|
36
|
+
const key = diagnostic.path[diagnostic.path.length - 1];
|
|
37
|
+
if (typeof key !== "string")
|
|
38
|
+
return void 0;
|
|
39
|
+
const stripped = stripTrailingSlash(key);
|
|
40
|
+
if (stripped === key || stripped === "")
|
|
41
|
+
return void 0;
|
|
42
|
+
const paths = getAtPath(data, diagnostic.path.slice(0, -1));
|
|
43
|
+
if (isObject(paths) && stripped in paths)
|
|
44
|
+
return void 0;
|
|
45
|
+
return { op: "renameProperty", path: diagnostic.path, newKey: stripped };
|
|
46
|
+
}
|
|
65
47
|
};
|
|
66
|
-
/** `no-$ref-siblings`: delete the sibling key that sits next to a `$ref`. */
|
|
67
48
|
const refSibling = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
49
|
+
safe: true,
|
|
50
|
+
fix: ({ diagnostic }) => {
|
|
51
|
+
if (diagnostic.path.length === 0)
|
|
52
|
+
return void 0;
|
|
53
|
+
return { op: "removeProperty", path: diagnostic.path };
|
|
54
|
+
}
|
|
74
55
|
};
|
|
75
|
-
/** `duplicated-entry-in-enum`: remove the later copies of each repeated enum value. */
|
|
76
56
|
const duplicatedEnum = {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
57
|
+
safe: true,
|
|
58
|
+
fix: ({ diagnostic, data }) => {
|
|
59
|
+
const array = getAtPath(data, diagnostic.path);
|
|
60
|
+
if (!Array.isArray(array))
|
|
61
|
+
return void 0;
|
|
62
|
+
const seen = /* @__PURE__ */ new Set();
|
|
63
|
+
const duplicates = [];
|
|
64
|
+
array.forEach((item, index) => {
|
|
65
|
+
const key = canonicalKey(item);
|
|
66
|
+
if (seen.has(key))
|
|
67
|
+
duplicates.push(index);
|
|
68
|
+
else
|
|
69
|
+
seen.add(key);
|
|
70
|
+
});
|
|
71
|
+
if (duplicates.length === 0)
|
|
72
|
+
return void 0;
|
|
73
|
+
return { op: "removeItems", path: diagnostic.path, indices: duplicates };
|
|
74
|
+
}
|
|
95
75
|
};
|
|
96
|
-
// Mirror the `alphabetical` built-in's comparator exactly so that sorting here
|
|
97
|
-
// produces an order the rule considers sorted — otherwise `--fix` could reorder
|
|
98
|
-
// into a sequence the rule still flags and never converge.
|
|
99
76
|
const compareAlphabetical = (a, b) => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
77
|
+
if (typeof a === "number" && typeof b === "number")
|
|
78
|
+
return a - b;
|
|
79
|
+
return String(a).localeCompare(String(b));
|
|
103
80
|
};
|
|
104
|
-
/** `openapi-tags-alphabetical`: reorder the top-level `tags` array by `name`. */
|
|
105
81
|
const tagsAlphabetical = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
82
|
+
safe: true,
|
|
83
|
+
fix: ({ diagnostic, data }) => {
|
|
84
|
+
const arrayPath = diagnostic.path.slice(0, -1);
|
|
85
|
+
const array = getAtPath(data, arrayPath);
|
|
86
|
+
if (!Array.isArray(array))
|
|
87
|
+
return void 0;
|
|
88
|
+
const nameOf = (item) => item != null && typeof item === "object" ? item["name"] : item;
|
|
89
|
+
const order = array.map((_, index) => index).sort((a, b) => compareAlphabetical(nameOf(array[a]), nameOf(array[b])));
|
|
90
|
+
if (order.every((value, index) => value === index))
|
|
91
|
+
return void 0;
|
|
92
|
+
return { op: "reorderArray", path: arrayPath, order };
|
|
93
|
+
}
|
|
119
94
|
};
|
|
120
|
-
/** `path-not-include-query`: drop the `?query` portion from a `paths` key. */
|
|
121
95
|
const pathKeyQueryString = {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
},
|
|
96
|
+
safe: true,
|
|
97
|
+
fix: ({ diagnostic, data }) => {
|
|
98
|
+
const key = diagnostic.path[diagnostic.path.length - 1];
|
|
99
|
+
if (typeof key !== "string")
|
|
100
|
+
return void 0;
|
|
101
|
+
const stripped = key.replace(/\?.*$/, "");
|
|
102
|
+
if (stripped === key || stripped === "")
|
|
103
|
+
return void 0;
|
|
104
|
+
const paths = getAtPath(data, diagnostic.path.slice(0, -1));
|
|
105
|
+
if (isObject(paths) && stripped in paths)
|
|
106
|
+
return void 0;
|
|
107
|
+
return { op: "renameProperty", path: diagnostic.path, newKey: stripped };
|
|
108
|
+
}
|
|
136
109
|
};
|
|
137
|
-
/** `openapi-tags-uniqueness`: remove the later copies of each repeated tag name. */
|
|
138
110
|
const tagsUnique = {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
},
|
|
111
|
+
safe: true,
|
|
112
|
+
fix: ({ diagnostic, data }) => {
|
|
113
|
+
const arrayPath = diagnostic.path.slice(0, -2);
|
|
114
|
+
const array = getAtPath(data, arrayPath);
|
|
115
|
+
if (!Array.isArray(array))
|
|
116
|
+
return void 0;
|
|
117
|
+
const seen = /* @__PURE__ */ new Set();
|
|
118
|
+
const duplicates = [];
|
|
119
|
+
array.forEach((tag, index) => {
|
|
120
|
+
const name = isObject(tag) ? tag["name"] : void 0;
|
|
121
|
+
if (typeof name !== "string")
|
|
122
|
+
return;
|
|
123
|
+
if (seen.has(name))
|
|
124
|
+
duplicates.push(index);
|
|
125
|
+
else
|
|
126
|
+
seen.add(name);
|
|
127
|
+
});
|
|
128
|
+
if (duplicates.length === 0)
|
|
129
|
+
return void 0;
|
|
130
|
+
return { op: "removeItems", path: arrayPath, indices: duplicates };
|
|
131
|
+
}
|
|
161
132
|
};
|
|
162
|
-
/**
|
|
163
|
-
* `oas3-unused-component` / `oas2-unused-definition`: delete the unreferenced
|
|
164
|
-
* component. Marked unsafe because a component can be referenced from another
|
|
165
|
-
* document or resolved dynamically, so removing it may not be semantics-preserving
|
|
166
|
-
* — it only applies under `--fix-unsafe`.
|
|
167
|
-
*/
|
|
168
133
|
const unusedComponent = {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
134
|
+
safe: false,
|
|
135
|
+
fix: ({ diagnostic }) => {
|
|
136
|
+
if (diagnostic.path.length === 0)
|
|
137
|
+
return void 0;
|
|
138
|
+
return { op: "removeProperty", path: diagnostic.path };
|
|
139
|
+
}
|
|
175
140
|
};
|
|
176
|
-
/**
|
|
177
|
-
* `oas3_1-no-nullable`: migrate the 3.0-era `nullable` keyword to its OpenAPI
|
|
178
|
-
* 3.1 (JSON Schema 2020-12) equivalent. `nullable: false` is the schema default,
|
|
179
|
-
* so it is simply dropped; `nullable: true` folds a `"null"` member into the
|
|
180
|
-
* sibling `type` before the keyword is removed. Marked unsafe because it rewrites
|
|
181
|
-
* the schema's `type`, so it only applies under `--fix-unsafe`.
|
|
182
|
-
*/
|
|
183
141
|
const noNullable = {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// `null` is already allowed — removing the keyword is enough.
|
|
201
|
-
return remove;
|
|
202
|
-
},
|
|
142
|
+
safe: false,
|
|
143
|
+
fix: ({ diagnostic, data }) => {
|
|
144
|
+
const value = getAtPath(data, diagnostic.path);
|
|
145
|
+
const remove = { op: "removeProperty", path: diagnostic.path };
|
|
146
|
+
if (value !== true)
|
|
147
|
+
return remove;
|
|
148
|
+
const typePath = [...diagnostic.path.slice(0, -1), "type"];
|
|
149
|
+
const type = getAtPath(data, typePath);
|
|
150
|
+
if (typeof type === "string" && type !== "null") {
|
|
151
|
+
return [{ op: "setValue", path: typePath, value: [type, "null"] }, remove];
|
|
152
|
+
}
|
|
153
|
+
if (Array.isArray(type) && !type.includes("null")) {
|
|
154
|
+
return [{ op: "insertItem", path: typePath, value: "null" }, remove];
|
|
155
|
+
}
|
|
156
|
+
return remove;
|
|
157
|
+
}
|
|
203
158
|
};
|
|
204
|
-
/**
|
|
205
|
-
* `oas3_1-schema-example-deprecated`: migrate a Schema Object's singular
|
|
206
|
-
* `example` to the JSON Schema 2020-12 `examples` array (`example: X` →
|
|
207
|
-
* `examples: [X]`). Safe and mechanical, but skipped when an `examples` array is
|
|
208
|
-
* already present so an existing one is never clobbered. The finding points at
|
|
209
|
-
* the `example` key, whose parent is the schema.
|
|
210
|
-
*/
|
|
211
159
|
const schemaExampleDeprecated = {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
160
|
+
safe: true,
|
|
161
|
+
fix: ({ diagnostic, data }) => {
|
|
162
|
+
const schemaPath = diagnostic.path.slice(0, -1);
|
|
163
|
+
const schema = getAtPath(data, schemaPath);
|
|
164
|
+
if (!isObject(schema) || !("example" in schema))
|
|
165
|
+
return void 0;
|
|
166
|
+
if ("examples" in schema)
|
|
167
|
+
return void 0;
|
|
168
|
+
return [
|
|
169
|
+
// `insertProperty` (not `setValue`) because `examples` is a new key: an
|
|
170
|
+
// op whose path doesn't already resolve is a no-op, and only
|
|
171
|
+
// `insertProperty` adds a missing key to the existing schema object.
|
|
172
|
+
{ op: "insertProperty", path: schemaPath, key: "examples", value: [schema["example"]] },
|
|
173
|
+
{ op: "removeProperty", path: diagnostic.path }
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const oasFixers = {
|
|
178
|
+
"oas2-host-trailing-slash": trailingSlashValue,
|
|
179
|
+
"oas3-server-trailing-slash": trailingSlashValue,
|
|
180
|
+
"path-keys-no-trailing-slash": pathKeyTrailingSlash,
|
|
181
|
+
"path-not-include-query": pathKeyQueryString,
|
|
182
|
+
"no-$ref-siblings": refSibling,
|
|
183
|
+
"duplicated-entry-in-enum": duplicatedEnum,
|
|
184
|
+
"openapi-tags-alphabetical": tagsAlphabetical,
|
|
185
|
+
"openapi-tags-uniqueness": tagsUnique,
|
|
186
|
+
"oas3-unused-component": unusedComponent,
|
|
187
|
+
"oas2-unused-definition": unusedComponent,
|
|
188
|
+
"oas3_1-no-nullable": noNullable,
|
|
189
|
+
"oas3_1-schema-example-deprecated": schemaExampleDeprecated
|
|
229
190
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
* code. Pass these to `@amritk/lint`'s `fixDocument` (as its `fixers`), or wrap
|
|
233
|
-
* them with `createFixPlugin` for a lower-level plugin.
|
|
234
|
-
*/
|
|
235
|
-
export const oasFixers = {
|
|
236
|
-
'oas2-host-trailing-slash': trailingSlashValue,
|
|
237
|
-
'oas3-server-trailing-slash': trailingSlashValue,
|
|
238
|
-
'path-keys-no-trailing-slash': pathKeyTrailingSlash,
|
|
239
|
-
'path-not-include-query': pathKeyQueryString,
|
|
240
|
-
'no-$ref-siblings': refSibling,
|
|
241
|
-
'duplicated-entry-in-enum': duplicatedEnum,
|
|
242
|
-
'openapi-tags-alphabetical': tagsAlphabetical,
|
|
243
|
-
'openapi-tags-uniqueness': tagsUnique,
|
|
244
|
-
'oas3-unused-component': unusedComponent,
|
|
245
|
-
'oas2-unused-definition': unusedComponent,
|
|
246
|
-
'oas3_1-no-nullable': noNullable,
|
|
247
|
-
'oas3_1-schema-example-deprecated': schemaExampleDeprecated,
|
|
191
|
+
export {
|
|
192
|
+
oasFixers
|
|
248
193
|
};
|
|
@@ -1,30 +1,29 @@
|
|
|
1
|
-
const isObject = (value) => typeof value ===
|
|
2
|
-
const openapiVersion = (document) => isObject(document) && typeof document[
|
|
3
|
-
// Minor versions are matched with an anchored `3.N` followed by a `.` or the
|
|
4
|
-
// end of string, so a future `3.10.x` is not mistaken for `3.1.x` — a plain
|
|
5
|
-
// `startsWith('3.1')` prefix check would misclassify `3.10.0` as OpenAPI 3.1.
|
|
1
|
+
const isObject = (value) => typeof value === "object" && value !== null;
|
|
2
|
+
const openapiVersion = (document) => isObject(document) && typeof document["openapi"] === "string" ? document["openapi"] : void 0;
|
|
6
3
|
const matchesMinor = (document, minor) => {
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const version = openapiVersion(document);
|
|
5
|
+
return version !== void 0 && new RegExp(`^3\\.${minor}(\\.|$)`).test(version);
|
|
9
6
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
const oas2 = (document) => isObject(document) && document["swagger"] === "2.0";
|
|
8
|
+
const oas3 = (document) => /^3\.\d/.test(openapiVersion(document) ?? "");
|
|
9
|
+
const oas3_0 = (document) => matchesMinor(document, 0);
|
|
10
|
+
const oas3_1 = (document) => matchesMinor(document, 1);
|
|
11
|
+
const oas3_2 = (document) => matchesMinor(document, 2);
|
|
12
|
+
const oasFormats = {
|
|
13
|
+
oas2,
|
|
14
|
+
oas3,
|
|
15
|
+
"oas3.0": oas3_0,
|
|
16
|
+
oas3_0,
|
|
17
|
+
"oas3.1": oas3_1,
|
|
18
|
+
oas3_1,
|
|
19
|
+
"oas3.2": oas3_2,
|
|
20
|
+
oas3_2
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
oas2,
|
|
24
|
+
oas3,
|
|
25
|
+
oas3_0,
|
|
26
|
+
oas3_1,
|
|
27
|
+
oas3_2,
|
|
28
|
+
oasFormats
|
|
30
29
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RulesetFunction } from '../../../core/
|
|
1
|
+
import type { RulesetFunction } from '../../../core/types.js';
|
|
2
2
|
/** Options selecting the OpenAPI major version an example rule runs against. */
|
|
3
3
|
export type IOasExampleOptions = {
|
|
4
4
|
/** 2 for OpenAPI 2.0 (Swagger), 3 for OpenAPI 3.x. Defaults to 3. */
|