@redocly/openapi-core 1.0.0-beta.105 → 1.0.0-beta.106
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 +4 -4
- package/__tests__/utils.ts +5 -5
- package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
- package/lib/benchmark/utils.d.ts +2 -2
- package/lib/benchmark/utils.js +2 -2
- package/lib/bundle.d.ts +2 -2
- package/lib/bundle.js +2 -2
- package/lib/config/all.d.ts +2 -2
- package/lib/config/all.js +1 -1
- package/lib/config/builtIn.d.ts +2 -2
- package/lib/config/builtIn.js +2 -2
- package/lib/config/config-resolvers.d.ts +5 -5
- package/lib/config/config-resolvers.js +39 -36
- package/lib/config/config.d.ts +5 -5
- package/lib/config/config.js +4 -4
- package/lib/config/load.js +4 -4
- package/lib/config/minimal.d.ts +2 -2
- package/lib/config/minimal.js +1 -1
- package/lib/config/recommended.d.ts +2 -2
- package/lib/config/recommended.js +1 -1
- package/lib/config/rules.d.ts +2 -2
- package/lib/config/rules.js +1 -1
- package/lib/config/types.d.ts +23 -19
- package/lib/config/utils.d.ts +5 -5
- package/lib/config/utils.js +43 -26
- package/lib/decorators/common/remove-x-internal.js +2 -2
- package/lib/format/format.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/js-yaml/index.js +1 -6
- package/lib/lint.d.ts +2 -2
- package/lib/lint.js +16 -6
- package/lib/redocly/registry-api.d.ts +1 -1
- package/lib/redocly/registry-api.js +2 -2
- package/lib/rules/common/info-license-url.d.ts +1 -1
- package/lib/rules/common/info-license-url.js +5 -10
- package/lib/rules/common/info-license.d.ts +2 -0
- package/lib/rules/common/info-license.js +17 -0
- package/lib/rules/common/no-enum-type-mismatch.js +1 -3
- package/lib/rules/common/operation-operationId.js +1 -1
- package/lib/rules/common/path-not-include-query.js +1 -1
- package/lib/rules/common/paths-kebab-case.js +4 -1
- package/lib/rules/common/spec.js +1 -1
- package/lib/rules/oas2/index.js +4 -4
- package/lib/rules/oas2/remove-unused-components.js +3 -3
- package/lib/rules/oas3/index.js +4 -4
- package/lib/rules/oas3/no-empty-servers.js +1 -1
- package/lib/rules/oas3/remove-unused-components.js +2 -2
- package/lib/rules/other/stats.js +43 -14
- package/lib/rules/utils.d.ts +1 -1
- package/lib/rules/utils.js +4 -1
- package/lib/types/index.d.ts +2 -2
- package/lib/types/redocly-yaml.js +8 -7
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
- package/src/__tests__/bundle.test.ts +68 -34
- package/src/__tests__/codeframes.test.ts +13 -14
- package/src/__tests__/js-yaml.test.ts +6 -4
- package/src/__tests__/lint.test.ts +74 -6
- package/src/__tests__/login.test.ts +2 -2
- package/src/__tests__/normalizeVisitors.test.ts +4 -4
- package/src/__tests__/ref-utils.test.ts +13 -13
- package/src/__tests__/resolve-http.test.ts +1 -1
- package/src/__tests__/resolve.test.ts +14 -11
- package/src/__tests__/walk.test.ts +48 -56
- package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
- package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
- package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
- package/src/benchmark/benchmark.js +9 -5
- package/src/benchmark/utils.ts +5 -5
- package/src/bundle.ts +18 -17
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +1 -1
- package/src/config/__tests__/config-resolvers.test.ts +123 -121
- package/src/config/__tests__/config.test.ts +76 -76
- package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
- package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
- package/src/config/__tests__/resolve-plugins.test.ts +3 -3
- package/src/config/__tests__/utils.test.ts +83 -0
- package/src/config/all.ts +3 -4
- package/src/config/builtIn.ts +5 -5
- package/src/config/config-resolvers.ts +122 -83
- package/src/config/config.ts +5 -5
- package/src/config/load.ts +6 -6
- package/src/config/minimal.ts +3 -3
- package/src/config/recommended.ts +3 -3
- package/src/config/rules.ts +6 -6
- package/src/config/types.ts +28 -19
- package/src/config/utils.ts +70 -50
- package/src/decorators/__tests__/filter-out.test.ts +8 -4
- package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
- package/src/decorators/common/filters/filter-helper.ts +1 -1
- package/src/decorators/common/info-description-override.ts +1 -1
- package/src/decorators/common/operation-description-override.ts +1 -1
- package/src/decorators/common/remove-x-internal.ts +4 -4
- package/src/decorators/common/tag-description-override.ts +1 -1
- package/src/format/codeframes.ts +4 -4
- package/src/format/format.ts +10 -10
- package/src/index.ts +2 -3
- package/src/js-yaml/index.ts +3 -8
- package/src/lint.ts +22 -18
- package/src/oas-types.ts +1 -6
- package/src/redocly/__tests__/redocly-client.test.ts +25 -19
- package/src/redocly/index.ts +6 -4
- package/src/redocly/registry-api.ts +6 -6
- package/src/ref-utils.ts +2 -2
- package/src/resolve.ts +7 -4
- package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
- package/src/rules/__tests__/utils.test.ts +122 -0
- package/src/rules/ajv.ts +3 -4
- package/src/rules/common/__tests__/info-description.test.ts +3 -3
- package/src/rules/common/__tests__/info-license.test.ts +2 -2
- package/src/rules/common/__tests__/license-url.test.ts +2 -2
- package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
- package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
- package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
- package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
- package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
- package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
- package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
- package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
- package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
- package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
- package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
- package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
- package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
- package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
- package/src/rules/common/__tests__/spec.test.ts +2 -2
- package/src/rules/common/__tests__/tag-description.test.ts +2 -2
- package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
- package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
- package/src/rules/common/assertions/index.ts +6 -6
- package/src/rules/common/info-license-url.ts +4 -9
- package/src/rules/common/info-license.ts +15 -0
- package/src/rules/common/no-ambiguous-paths.ts +1 -1
- package/src/rules/common/no-enum-type-mismatch.ts +12 -9
- package/src/rules/common/no-invalid-parameter-examples.ts +2 -2
- package/src/rules/common/no-invalid-schema-examples.ts +1 -1
- package/src/rules/common/operation-operationId.ts +1 -1
- package/src/rules/common/operation-parameters-unique.ts +2 -2
- package/src/rules/common/path-not-include-query.ts +1 -1
- package/src/rules/common/path-params-defined.ts +1 -1
- package/src/rules/common/paths-kebab-case.ts +4 -1
- package/src/rules/common/scalar-property-missing-example.ts +1 -1
- package/src/rules/common/spec.ts +10 -7
- package/src/rules/no-unresolved-refs.ts +1 -1
- package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
- package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
- package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
- package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
- package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
- package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
- package/src/rules/oas2/index.ts +3 -3
- package/src/rules/oas2/remove-unused-components.ts +13 -8
- package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
- package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
- package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
- package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
- package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
- package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
- package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
- package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
- package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
- package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
- package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
- package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
- package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
- package/src/rules/oas3/index.ts +3 -3
- package/src/rules/oas3/no-empty-servers.ts +1 -1
- package/src/rules/oas3/no-invalid-media-type-examples.ts +12 -4
- package/src/rules/oas3/no-servers-empty-enum.ts +9 -10
- package/src/rules/oas3/remove-unused-components.ts +18 -7
- package/src/rules/other/stats.ts +46 -17
- package/src/rules/utils.ts +5 -3
- package/src/types/index.ts +5 -5
- package/src/types/redocly-yaml.ts +8 -7
- package/src/typings/common.ts +9 -1
- package/src/typings/openapi.ts +1 -1
- package/src/visitors.ts +4 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/common/license-url.d.ts +0 -2
- package/lib/rules/common/license-url.js +0 -12
- package/src/rules/common/license-url.ts +0 -10
package/src/config/utils.ts
CHANGED
|
@@ -4,12 +4,13 @@ import { Config } from './config';
|
|
|
4
4
|
|
|
5
5
|
import type {
|
|
6
6
|
Api,
|
|
7
|
-
|
|
7
|
+
DeprecatedInApi,
|
|
8
|
+
DeprecatedInRawConfig,
|
|
8
9
|
Plugin,
|
|
9
10
|
RawConfig,
|
|
10
11
|
RawResolveConfig,
|
|
11
12
|
ResolveConfig,
|
|
12
|
-
|
|
13
|
+
ResolvedStyleguideConfig,
|
|
13
14
|
RulesFields,
|
|
14
15
|
} from './types';
|
|
15
16
|
|
|
@@ -23,15 +24,27 @@ export function parsePresetName(presetName: string): { pluginId: string; configN
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export function transformApiDefinitionsToApis(
|
|
26
|
-
apiDefinitions
|
|
27
|
-
): Record<string, Api> {
|
|
28
|
-
|
|
27
|
+
apiDefinitions?: DeprecatedInRawConfig['apiDefinitions']
|
|
28
|
+
): Record<string, Api> | undefined {
|
|
29
|
+
if (!apiDefinitions) return undefined;
|
|
30
|
+
const apis: Record<string, Api> = {};
|
|
29
31
|
for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
|
|
30
32
|
apis[apiName] = { root: apiPath };
|
|
31
33
|
}
|
|
32
34
|
return apis;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
function transformApis(
|
|
38
|
+
legacyApis?: Record<string, Api & DeprecatedInApi>
|
|
39
|
+
): Record<string, Api> | undefined {
|
|
40
|
+
if (!legacyApis) return undefined;
|
|
41
|
+
const apis: Record<string, Api> = {};
|
|
42
|
+
for (const [apiName, { lint, ...apiContent }] of Object.entries(legacyApis)) {
|
|
43
|
+
apis[apiName] = { styleguide: lint, ...apiContent };
|
|
44
|
+
}
|
|
45
|
+
return apis;
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
export function prefixRules<T extends Record<string, any>>(rules: T, prefix: string) {
|
|
36
49
|
if (!prefix) return rules;
|
|
37
50
|
|
|
@@ -43,9 +56,9 @@ export function prefixRules<T extends Record<string, any>>(rules: T, prefix: str
|
|
|
43
56
|
return res;
|
|
44
57
|
}
|
|
45
58
|
|
|
46
|
-
export function mergeExtends(rulesConfList:
|
|
47
|
-
const result: Omit<
|
|
48
|
-
Required<Pick<
|
|
59
|
+
export function mergeExtends(rulesConfList: ResolvedStyleguideConfig[]) {
|
|
60
|
+
const result: Omit<ResolvedStyleguideConfig, RulesFields> &
|
|
61
|
+
Required<Pick<ResolvedStyleguideConfig, RulesFields>> = {
|
|
49
62
|
rules: {},
|
|
50
63
|
oas2Rules: {},
|
|
51
64
|
oas3_0Rules: {},
|
|
@@ -69,11 +82,7 @@ export function mergeExtends(rulesConfList: ResolvedLintConfig[]) {
|
|
|
69
82
|
for (let rulesConf of rulesConfList) {
|
|
70
83
|
if (rulesConf.extends) {
|
|
71
84
|
throw new Error(
|
|
72
|
-
|
|
73
|
-
rulesConf,
|
|
74
|
-
null,
|
|
75
|
-
2,
|
|
76
|
-
)}.`,
|
|
85
|
+
`'extends' is not supported in shared configs yet: ${JSON.stringify(rulesConf, null, 2)}.`
|
|
77
86
|
);
|
|
78
87
|
}
|
|
79
88
|
|
|
@@ -109,75 +118,88 @@ export function mergeExtends(rulesConfList: ResolvedLintConfig[]) {
|
|
|
109
118
|
return result;
|
|
110
119
|
}
|
|
111
120
|
|
|
112
|
-
export function getMergedConfig(config: Config,
|
|
121
|
+
export function getMergedConfig(config: Config, apiName?: string): Config {
|
|
113
122
|
const extendPaths = [
|
|
114
|
-
...Object.values(config.apis).map((api) => api?.
|
|
115
|
-
config.rawConfig?.
|
|
123
|
+
...Object.values(config.apis).map((api) => api?.styleguide?.extendPaths),
|
|
124
|
+
config.rawConfig?.styleguide?.extendPaths,
|
|
116
125
|
]
|
|
117
126
|
.flat()
|
|
118
127
|
.filter(Boolean) as string[];
|
|
119
128
|
|
|
120
129
|
const pluginPaths = [
|
|
121
|
-
...Object.values(config.apis).map((api) => api?.
|
|
122
|
-
config.rawConfig?.
|
|
130
|
+
...Object.values(config.apis).map((api) => api?.styleguide?.pluginPaths),
|
|
131
|
+
config.rawConfig?.styleguide?.pluginPaths,
|
|
123
132
|
]
|
|
124
133
|
.flat()
|
|
125
134
|
.filter(Boolean) as string[];
|
|
126
135
|
|
|
127
|
-
return
|
|
136
|
+
return apiName
|
|
128
137
|
? new Config(
|
|
129
138
|
{
|
|
130
139
|
...config.rawConfig,
|
|
131
|
-
|
|
132
|
-
...(config.apis[
|
|
133
|
-
? config.apis[
|
|
134
|
-
: config.rawConfig.
|
|
140
|
+
styleguide: {
|
|
141
|
+
...(config.apis[apiName]
|
|
142
|
+
? config.apis[apiName].styleguide
|
|
143
|
+
: config.rawConfig.styleguide),
|
|
135
144
|
extendPaths,
|
|
136
145
|
pluginPaths,
|
|
137
146
|
},
|
|
138
147
|
'features.openapi': {
|
|
139
148
|
...config['features.openapi'],
|
|
140
|
-
...config.apis[
|
|
149
|
+
...config.apis[apiName]?.['features.openapi'],
|
|
141
150
|
},
|
|
142
151
|
'features.mockServer': {
|
|
143
152
|
...config['features.mockServer'],
|
|
144
|
-
...config.apis[
|
|
153
|
+
...config.apis[apiName]?.['features.mockServer'],
|
|
145
154
|
},
|
|
146
155
|
// TODO: merge everything else here
|
|
147
156
|
},
|
|
148
|
-
config.configFile
|
|
157
|
+
config.configFile
|
|
149
158
|
)
|
|
150
159
|
: config;
|
|
151
160
|
}
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
const { apiDefinitions, referenceDocs, ...rest } = rawConfig as DeprecatedRawConfig & RawConfig;
|
|
164
|
-
if (apiDefinitions) {
|
|
165
|
-
process.stderr.write(
|
|
166
|
-
`The ${yellow('apiDefinitions')} field is deprecated. Use ${green(
|
|
167
|
-
'apis',
|
|
168
|
-
)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`,
|
|
162
|
+
function checkForDeprecatedFields(
|
|
163
|
+
deprecatedField: keyof DeprecatedInRawConfig,
|
|
164
|
+
updatedField: keyof RawConfig,
|
|
165
|
+
rawConfig: DeprecatedInRawConfig & RawConfig
|
|
166
|
+
): void {
|
|
167
|
+
const isDeprecatedFieldInApis =
|
|
168
|
+
rawConfig.apis &&
|
|
169
|
+
Object.values(rawConfig.apis).some(
|
|
170
|
+
(api: Api & DeprecatedInApi & DeprecatedInRawConfig) => api[deprecatedField]
|
|
169
171
|
);
|
|
172
|
+
|
|
173
|
+
if (rawConfig[deprecatedField] && rawConfig[updatedField]) {
|
|
174
|
+
throw new Error(`Do not use '${deprecatedField}' field. Use '${updatedField}' instead.\n`);
|
|
170
175
|
}
|
|
171
|
-
|
|
176
|
+
|
|
177
|
+
if (rawConfig[deprecatedField] || isDeprecatedFieldInApis) {
|
|
172
178
|
process.stderr.write(
|
|
173
|
-
`The ${yellow(
|
|
174
|
-
|
|
175
|
-
)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n
|
|
179
|
+
`The ${yellow(deprecatedField)} field is deprecated. Use ${green(
|
|
180
|
+
updatedField
|
|
181
|
+
)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`
|
|
176
182
|
);
|
|
177
183
|
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function transformConfig(rawConfig: DeprecatedInRawConfig & RawConfig): RawConfig {
|
|
187
|
+
const migratedFields: [keyof DeprecatedInRawConfig, keyof RawConfig][] = [
|
|
188
|
+
['apiDefinitions', 'apis'],
|
|
189
|
+
['referenceDocs', 'features.openapi'],
|
|
190
|
+
['lint', 'styleguide'], // TODO: update docs
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
for (const [deprecatedField, updatedField] of migratedFields) {
|
|
194
|
+
checkForDeprecatedFields(deprecatedField, updatedField, rawConfig);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const { apis, apiDefinitions, referenceDocs, lint, ...rest } = rawConfig;
|
|
198
|
+
|
|
178
199
|
return {
|
|
179
200
|
'features.openapi': referenceDocs,
|
|
180
|
-
apis: transformApiDefinitionsToApis(apiDefinitions),
|
|
201
|
+
apis: transformApis(apis) || transformApiDefinitionsToApis(apiDefinitions),
|
|
202
|
+
styleguide: lint,
|
|
181
203
|
...rest,
|
|
182
204
|
};
|
|
183
205
|
}
|
|
@@ -199,9 +221,7 @@ export function getUniquePlugins(plugins: Plugin[]): Plugin[] {
|
|
|
199
221
|
results.push(p);
|
|
200
222
|
seen.add(p.id);
|
|
201
223
|
} else if (p.id) {
|
|
202
|
-
process.stderr.write(
|
|
203
|
-
`Duplicate plugin id "${yellow(p.id)}".\n`,
|
|
204
|
-
);
|
|
224
|
+
process.stderr.write(`Duplicate plugin id "${yellow(p.id)}".\n`);
|
|
205
225
|
}
|
|
206
226
|
}
|
|
207
227
|
return results;
|
|
@@ -27,7 +27,8 @@ describe('oas3 filter-out', () => {
|
|
|
27
27
|
callbacks:
|
|
28
28
|
x-access: protected
|
|
29
29
|
orderInProgress:
|
|
30
|
-
x-internal: true`
|
|
30
|
+
x-internal: true`
|
|
31
|
+
);
|
|
31
32
|
|
|
32
33
|
it('should remove /pet path and y parameter', async () => {
|
|
33
34
|
const testDocument = parseYamlToDocument(
|
|
@@ -132,7 +133,8 @@ describe('oas3 filter-out', () => {
|
|
|
132
133
|
type: object
|
|
133
134
|
components: {}
|
|
134
135
|
|
|
135
|
-
`
|
|
136
|
+
`
|
|
137
|
+
);
|
|
136
138
|
const { bundle: res } = await bundleDocument({
|
|
137
139
|
document: testDoc,
|
|
138
140
|
externalRefResolver: new BaseResolver(),
|
|
@@ -185,7 +187,8 @@ describe('oas3 filter-out', () => {
|
|
|
185
187
|
x:
|
|
186
188
|
name: x
|
|
187
189
|
|
|
188
|
-
`
|
|
190
|
+
`
|
|
191
|
+
);
|
|
189
192
|
const { bundle: res } = await bundleDocument({
|
|
190
193
|
document: testDocument,
|
|
191
194
|
externalRefResolver: new BaseResolver(),
|
|
@@ -236,7 +239,8 @@ describe('oas3 filter-out', () => {
|
|
|
236
239
|
x:
|
|
237
240
|
name: x
|
|
238
241
|
|
|
239
|
-
`
|
|
242
|
+
`
|
|
243
|
+
);
|
|
240
244
|
const { bundle: res } = await bundleDocument({
|
|
241
245
|
document: testDocument,
|
|
242
246
|
externalRefResolver: new BaseResolver(),
|
|
@@ -18,7 +18,7 @@ describe('oas3 remove-x-internal', () => {
|
|
|
18
18
|
parameters:
|
|
19
19
|
x:
|
|
20
20
|
name: x
|
|
21
|
-
|
|
21
|
+
`
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
it('should use `internalFlagProperty` option to remove internal paths', async () => {
|
|
@@ -87,7 +87,7 @@ describe('oas3 remove-x-internal', () => {
|
|
|
87
87
|
name: x
|
|
88
88
|
y:
|
|
89
89
|
name: y
|
|
90
|
-
|
|
90
|
+
`
|
|
91
91
|
);
|
|
92
92
|
const { bundle: res } = await bundleDocument({
|
|
93
93
|
document: testDoc,
|
|
@@ -160,7 +160,7 @@ describe('oas3 remove-x-internal', () => {
|
|
|
160
160
|
servers:
|
|
161
161
|
- url: //callback-url.path-level/v1
|
|
162
162
|
description: Path level server
|
|
163
|
-
|
|
163
|
+
`
|
|
164
164
|
);
|
|
165
165
|
const { bundle: res } = await bundleDocument({
|
|
166
166
|
document: testDoc,
|
|
@@ -234,7 +234,7 @@ describe('oas3 remove-x-internal', () => {
|
|
|
234
234
|
schema:
|
|
235
235
|
type: string
|
|
236
236
|
x-internal: true
|
|
237
|
-
|
|
237
|
+
`
|
|
238
238
|
);
|
|
239
239
|
const { bundle: res } = await bundleDocument({
|
|
240
240
|
document: testDoc,
|
|
@@ -297,7 +297,7 @@ describe('oas2 remove-x-internal', () => {
|
|
|
297
297
|
'200':
|
|
298
298
|
x-internal: true
|
|
299
299
|
description: List of recent media entries.
|
|
300
|
-
|
|
300
|
+
`
|
|
301
301
|
);
|
|
302
302
|
const { bundle: res } = await bundleDocument({
|
|
303
303
|
document: testDoc,
|
|
@@ -8,7 +8,7 @@ export const InfoDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ filePat
|
|
|
8
8
|
leave(info, { report, location }: UserContext) {
|
|
9
9
|
if (!filePath)
|
|
10
10
|
throw new Error(
|
|
11
|
-
`Parameter "filePath" is not provided for "info-description-override" rule
|
|
11
|
+
`Parameter "filePath" is not provided for "info-description-override" rule`
|
|
12
12
|
);
|
|
13
13
|
try {
|
|
14
14
|
info.description = readFileAsStringSync(filePath);
|
|
@@ -11,7 +11,7 @@ export const OperationDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ op
|
|
|
11
11
|
if (!operation.operationId) return;
|
|
12
12
|
if (!operationIds)
|
|
13
13
|
throw new Error(
|
|
14
|
-
`Parameter "operationIds" is not provided for "operation-description-override" rule
|
|
14
|
+
`Parameter "operationIds" is not provided for "operation-description-override" rule`
|
|
15
15
|
);
|
|
16
16
|
const operationId = operation.operationId;
|
|
17
17
|
if (operationIds[operationId]) {
|
|
@@ -8,7 +8,7 @@ export const TagDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ tagNames
|
|
|
8
8
|
leave(tag, { report }: UserContext) {
|
|
9
9
|
if (!tagNames)
|
|
10
10
|
throw new Error(
|
|
11
|
-
`Parameter "tagNames" is not provided for "tag-description-override" rule
|
|
11
|
+
`Parameter "tagNames" is not provided for "tag-description-override" rule`
|
|
12
12
|
);
|
|
13
13
|
if (tagNames[tag.name]) {
|
|
14
14
|
try {
|
package/src/format/codeframes.ts
CHANGED
|
@@ -63,7 +63,7 @@ export function getCodeframe(location: LineColLocationObject, color: boolean) {
|
|
|
63
63
|
line: string,
|
|
64
64
|
startIdx: number = -1,
|
|
65
65
|
endIdx: number = +Infinity,
|
|
66
|
-
variant = gray
|
|
66
|
+
variant = gray
|
|
67
67
|
) {
|
|
68
68
|
if (!color) return line;
|
|
69
69
|
if (!line) return line;
|
|
@@ -84,14 +84,14 @@ function printPrefixedLines(lines: [string, string][]): string {
|
|
|
84
84
|
|
|
85
85
|
const padLen = Math.max(...existingLines.map(([prefix]) => prefix.length));
|
|
86
86
|
const dedentLen = Math.min(
|
|
87
|
-
...existingLines.map(([_, line]) => (line === '' ? Infinity : padSize(line)))
|
|
87
|
+
...existingLines.map(([_, line]) => (line === '' ? Infinity : padSize(line)))
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
return existingLines
|
|
91
91
|
.map(
|
|
92
92
|
([prefix, line]) =>
|
|
93
93
|
gray(leftPad(padLen, prefix) + ' |') +
|
|
94
|
-
(line ? ' ' + limitLineLength(line.substring(dedentLen)) : '')
|
|
94
|
+
(line ? ' ' + limitLineLength(line.substring(dedentLen)) : '')
|
|
95
95
|
)
|
|
96
96
|
.join('\n');
|
|
97
97
|
}
|
|
@@ -146,7 +146,7 @@ export function getLineColLocation(location: LocationObject): LineColLocationObj
|
|
|
146
146
|
function positionsToLoc(
|
|
147
147
|
source: string,
|
|
148
148
|
startPos: number,
|
|
149
|
-
endPos: number
|
|
149
|
+
endPos: number
|
|
150
150
|
): { start: Loc; end: Loc } {
|
|
151
151
|
let currentLine = 1;
|
|
152
152
|
let currentCol = 1;
|
package/src/format/format.ts
CHANGED
|
@@ -14,7 +14,7 @@ const coreVersion = require('../../package.json').version;
|
|
|
14
14
|
|
|
15
15
|
import { NormalizedProblem, ProblemSeverity, LineColLocationObject, LocationObject } from '../walk';
|
|
16
16
|
import { getCodeframe, getLineColLocation } from './codeframes';
|
|
17
|
-
import { env } from
|
|
17
|
+
import { env } from '../config';
|
|
18
18
|
|
|
19
19
|
export type Totals = {
|
|
20
20
|
errors: number;
|
|
@@ -84,7 +84,7 @@ export function formatProblems(
|
|
|
84
84
|
color?: boolean;
|
|
85
85
|
totals: Totals;
|
|
86
86
|
version: string;
|
|
87
|
-
}
|
|
87
|
+
}
|
|
88
88
|
) {
|
|
89
89
|
const {
|
|
90
90
|
maxProblems = 100,
|
|
@@ -120,7 +120,7 @@ export function formatProblems(
|
|
|
120
120
|
case 'stylish': {
|
|
121
121
|
const groupedByFile = groupByFiles(problems);
|
|
122
122
|
for (const [file, { ruleIdPad, locationPad: positionPad, fileProblems }] of Object.entries(
|
|
123
|
-
groupedByFile
|
|
123
|
+
groupedByFile
|
|
124
124
|
)) {
|
|
125
125
|
process.stderr.write(`${blue(path.relative(cwd, file))}:\n`);
|
|
126
126
|
|
|
@@ -156,8 +156,8 @@ export function formatProblems(
|
|
|
156
156
|
if (totalProblems - ignoredProblems > maxProblems) {
|
|
157
157
|
process.stderr.write(
|
|
158
158
|
`< ... ${totalProblems - maxProblems} more problems hidden > ${gray(
|
|
159
|
-
'increase with `--max-problems N`'
|
|
160
|
-
)}\n
|
|
159
|
+
'increase with `--max-problems N`'
|
|
160
|
+
)}\n`
|
|
161
161
|
);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -243,12 +243,12 @@ export function formatProblems(
|
|
|
243
243
|
function formatStylish(problem: OnlyLineColProblem, locationPad: number, ruleIdPad: number) {
|
|
244
244
|
const color = COLORS[problem.severity];
|
|
245
245
|
if (!SEVERITY_NAMES[problem.severity]) {
|
|
246
|
-
return 'Error not found severity. Please check your config file. Allowed values:
|
|
246
|
+
return 'Error not found severity. Please check your config file. Allowed values: `warn,error,off`';
|
|
247
247
|
}
|
|
248
248
|
const severityName = color(SEVERITY_NAMES[problem.severity].toLowerCase().padEnd(7));
|
|
249
249
|
const { start } = problem.location[0];
|
|
250
250
|
return ` ${`${start.line}:${start.col}`.padEnd(
|
|
251
|
-
locationPad
|
|
251
|
+
locationPad
|
|
252
252
|
)} ${severityName} ${problem.ruleId.padEnd(ruleIdPad)} ${problem.message}`;
|
|
253
253
|
}
|
|
254
254
|
|
|
@@ -258,7 +258,7 @@ export function formatProblems(
|
|
|
258
258
|
const message = xmlEscape(problem.message);
|
|
259
259
|
const source = xmlEscape(problem.ruleId);
|
|
260
260
|
process.stdout.write(
|
|
261
|
-
`<error line="${line}" column="${col}" severity="${severity}" message="${message}" source="${source}" />\n
|
|
261
|
+
`<error line="${line}" column="${col}" severity="${severity}" message="${message}" source="${source}" />\n`
|
|
262
262
|
);
|
|
263
263
|
}
|
|
264
264
|
}
|
|
@@ -307,12 +307,12 @@ const groupByFiles = (problems: NormalizedProblem[]) => {
|
|
|
307
307
|
fileGroups[absoluteRef].fileProblems.push(mappedProblem);
|
|
308
308
|
fileGroups[absoluteRef].ruleIdPad = Math.max(
|
|
309
309
|
problem.ruleId.length,
|
|
310
|
-
fileGroups[absoluteRef].ruleIdPad
|
|
310
|
+
fileGroups[absoluteRef].ruleIdPad
|
|
311
311
|
);
|
|
312
312
|
|
|
313
313
|
fileGroups[absoluteRef].locationPad = Math.max(
|
|
314
314
|
Math.max(...mappedProblem.location.map((loc) => `${loc.start.line}:${loc.start.col}`.length)),
|
|
315
|
-
fileGroups[absoluteRef].locationPad
|
|
315
|
+
fileGroups[absoluteRef].locationPad
|
|
316
316
|
);
|
|
317
317
|
}
|
|
318
318
|
|
package/src/index.ts
CHANGED
|
@@ -23,7 +23,7 @@ export { Stats } from './rules/other/stats';
|
|
|
23
23
|
|
|
24
24
|
export {
|
|
25
25
|
Config,
|
|
26
|
-
|
|
26
|
+
StyleguideConfig,
|
|
27
27
|
RawConfig,
|
|
28
28
|
IGNORE_FILE,
|
|
29
29
|
Region,
|
|
@@ -33,10 +33,9 @@ export {
|
|
|
33
33
|
getConfig,
|
|
34
34
|
findConfig,
|
|
35
35
|
CONFIG_FILE_NAMES,
|
|
36
|
-
RuleSeverity
|
|
36
|
+
RuleSeverity,
|
|
37
37
|
} from './config';
|
|
38
38
|
|
|
39
|
-
|
|
40
39
|
export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
|
|
41
40
|
|
|
42
41
|
export {
|
package/src/js-yaml/index.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
// TODO: add a type for "types" https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/js-yaml/index.d.ts
|
|
2
2
|
// @ts-ignore
|
|
3
|
-
import { JSON_SCHEMA, types, LoadOptions, DumpOptions, load, dump
|
|
3
|
+
import { JSON_SCHEMA, types, LoadOptions, DumpOptions, load, dump } from 'js-yaml';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = JSON_SCHEMA.extend({
|
|
6
6
|
implicit: [types.merge],
|
|
7
|
-
explicit: [
|
|
8
|
-
types.binary,
|
|
9
|
-
types.omap,
|
|
10
|
-
types.pairs,
|
|
11
|
-
types.set,
|
|
12
|
-
],
|
|
7
|
+
explicit: [types.binary, types.omap, types.pairs, types.set],
|
|
13
8
|
});
|
|
14
9
|
|
|
15
10
|
export const parseYaml = (str: string, opts?: LoadOptions): unknown =>
|
|
16
|
-
load(str, {schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts});
|
|
11
|
+
load(str, { schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts });
|
|
17
12
|
|
|
18
13
|
export const stringifyYaml = (obj: any, opts?: DumpOptions): string => dump(obj, opts);
|
package/src/lint.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { BaseResolver, resolveDocument, Document, makeDocumentFromString } from './resolve';
|
|
2
|
-
import {
|
|
3
|
-
normalizeVisitors,
|
|
4
|
-
} from './visitors';
|
|
2
|
+
import { normalizeVisitors } from './visitors';
|
|
5
3
|
import { Oas3_1Types } from './types/oas3_1';
|
|
6
4
|
import { Oas3Types } from './types/oas3';
|
|
7
5
|
import { Oas2Types } from './types/oas2';
|
|
8
6
|
import { NodeType } from './types';
|
|
9
7
|
import { ProblemSeverity, WalkContext, walkDocument } from './walk';
|
|
10
|
-
import {
|
|
8
|
+
import { StyleguideConfig, Config, initRules, defaultPlugin, resolvePlugins } from './config';
|
|
11
9
|
import { normalizeTypes } from './types';
|
|
12
10
|
import { releaseAjvInstance } from './rules/ajv';
|
|
13
11
|
import { detectOpenAPI, Oas3RuleSet, OasMajorVersion, OasVersion, openAPIMajor } from './oas-types';
|
|
14
12
|
import { ConfigTypes } from './types/redocly-yaml';
|
|
15
13
|
import { OasSpec } from './rules/common/spec';
|
|
16
14
|
|
|
17
|
-
|
|
18
15
|
export async function lint(opts: {
|
|
19
16
|
ref: string;
|
|
20
17
|
config: Config;
|
|
@@ -27,7 +24,7 @@ export async function lint(opts: {
|
|
|
27
24
|
document,
|
|
28
25
|
...opts,
|
|
29
26
|
externalRefResolver,
|
|
30
|
-
config: opts.config.
|
|
27
|
+
config: opts.config.styleguide,
|
|
31
28
|
});
|
|
32
29
|
}
|
|
33
30
|
|
|
@@ -44,13 +41,13 @@ export async function lintFromString(opts: {
|
|
|
44
41
|
document,
|
|
45
42
|
...opts,
|
|
46
43
|
externalRefResolver,
|
|
47
|
-
config: opts.config.
|
|
44
|
+
config: opts.config.styleguide,
|
|
48
45
|
});
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
export async function lintDocument(opts: {
|
|
52
49
|
document: Document;
|
|
53
|
-
config:
|
|
50
|
+
config: StyleguideConfig;
|
|
54
51
|
customTypes?: Record<string, NodeType>;
|
|
55
52
|
externalRefResolver: BaseResolver;
|
|
56
53
|
}) {
|
|
@@ -62,10 +59,14 @@ export async function lintDocument(opts: {
|
|
|
62
59
|
const rules = config.getRulesForOasVersion(oasMajorVersion);
|
|
63
60
|
const types = normalizeTypes(
|
|
64
61
|
config.extendTypes(
|
|
65
|
-
customTypes ?? oasMajorVersion === OasMajorVersion.Version3
|
|
66
|
-
|
|
62
|
+
customTypes ?? oasMajorVersion === OasMajorVersion.Version3
|
|
63
|
+
? oasVersion === OasVersion.Version3_1
|
|
64
|
+
? Oas3_1Types
|
|
65
|
+
: Oas3Types
|
|
66
|
+
: Oas2Types,
|
|
67
|
+
oasVersion
|
|
67
68
|
),
|
|
68
|
-
config
|
|
69
|
+
config
|
|
69
70
|
);
|
|
70
71
|
|
|
71
72
|
const ctx: WalkContext = {
|
|
@@ -80,7 +81,7 @@ export async function lintDocument(opts: {
|
|
|
80
81
|
const resolvedRefMap = await resolveDocument({
|
|
81
82
|
rootDocument: document,
|
|
82
83
|
rootType: types.DefinitionRoot,
|
|
83
|
-
externalRefResolver
|
|
84
|
+
externalRefResolver,
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
walkDocument({
|
|
@@ -93,10 +94,7 @@ export async function lintDocument(opts: {
|
|
|
93
94
|
return ctx.problems.map((problem) => config.addProblemToIgnore(problem));
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
export async function lintConfig(opts: {
|
|
97
|
-
document: Document
|
|
98
|
-
severity?: ProblemSeverity
|
|
99
|
-
}) {
|
|
97
|
+
export async function lintConfig(opts: { document: Document; severity?: ProblemSeverity }) {
|
|
100
98
|
const { document, severity } = opts;
|
|
101
99
|
|
|
102
100
|
const ctx: WalkContext = {
|
|
@@ -105,13 +103,19 @@ export async function lintConfig(opts: {
|
|
|
105
103
|
visitorsData: {},
|
|
106
104
|
};
|
|
107
105
|
const plugins = resolvePlugins([defaultPlugin]);
|
|
108
|
-
const config = new
|
|
106
|
+
const config = new StyleguideConfig({
|
|
109
107
|
plugins,
|
|
110
108
|
rules: { spec: 'error' },
|
|
111
109
|
});
|
|
112
110
|
|
|
113
111
|
const types = normalizeTypes(ConfigTypes, config);
|
|
114
|
-
const rules = [
|
|
112
|
+
const rules = [
|
|
113
|
+
{
|
|
114
|
+
severity: severity || 'error',
|
|
115
|
+
ruleId: 'configuration spec',
|
|
116
|
+
visitor: OasSpec({ severity: 'error' }),
|
|
117
|
+
},
|
|
118
|
+
];
|
|
115
119
|
const normalizedVisitors = normalizeVisitors(rules, types);
|
|
116
120
|
|
|
117
121
|
walkDocument({
|
package/src/oas-types.ts
CHANGED