@redocly/openapi-core 1.0.0-beta.78 → 1.0.0-beta.82
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/__tests__/utils.ts +11 -1
- package/lib/bundle.js +18 -7
- package/lib/config/builtIn.js +18 -4
- package/lib/{rules → decorators}/common/info-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/info-description-override.js +0 -0
- package/lib/{rules → decorators}/common/operation-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/operation-description-override.js +0 -0
- package/lib/{rules → decorators}/common/registry-dependencies.d.ts +0 -0
- package/lib/{rules → decorators}/common/registry-dependencies.js +0 -0
- package/lib/{rules → decorators}/common/remove-x-internal.d.ts +0 -0
- package/lib/{rules → decorators}/common/remove-x-internal.js +20 -2
- package/lib/{rules → decorators}/common/tag-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/tag-description-override.js +0 -0
- package/lib/decorators/oas2/index.d.ts +8 -0
- package/lib/decorators/oas2/index.js +15 -0
- package/lib/decorators/oas3/index.d.ts +8 -0
- package/lib/decorators/oas3/index.js +15 -0
- package/lib/js-yaml/index.js +1 -1
- package/lib/resolve.d.ts +1 -0
- package/lib/resolve.js +7 -3
- package/lib/rules/common/operation-security-defined.js +1 -4
- package/lib/rules/common/spec.js +18 -3
- package/lib/rules/oas2/index.d.ts +1 -8
- package/lib/rules/oas2/index.js +1 -13
- package/lib/rules/oas2/remove-unused-components.js +11 -9
- package/lib/rules/oas3/index.d.ts +0 -8
- package/lib/rules/oas3/index.js +1 -13
- package/lib/rules/oas3/no-invalid-media-type-examples.js +12 -11
- package/lib/rules/oas3/remove-unused-components.js +11 -9
- package/lib/types/index.d.ts +4 -0
- package/lib/types/oas2.js +42 -35
- package/lib/types/oas3.js +68 -139
- package/lib/types/oas3_1.js +52 -49
- package/lib/utils.js +1 -1
- package/lib/walk.js +1 -1
- package/package.json +1 -1
- package/src/__tests__/js-yaml.test.ts +29 -5
- package/src/__tests__/lint.test.ts +1 -3
- package/src/bundle.ts +21 -8
- package/src/config/builtIn.ts +20 -7
- package/src/{rules/__tests__/hide-internals.test.ts → decorators/__tests__/remove-x-internal.test.ts} +124 -42
- package/src/{rules → decorators}/common/info-description-override.ts +0 -0
- package/src/{rules → decorators}/common/operation-description-override.ts +0 -0
- package/src/{rules → decorators}/common/registry-dependencies.ts +0 -0
- package/src/{rules → decorators}/common/remove-x-internal.ts +20 -3
- package/src/{rules → decorators}/common/tag-description-override.ts +0 -0
- package/src/decorators/oas2/index.ts +14 -0
- package/src/decorators/oas3/index.ts +14 -0
- package/src/js-yaml/index.ts +1 -2
- package/src/redocly/registry-api.ts +4 -1
- package/src/resolve.ts +6 -6
- package/src/rules/__tests__/no-unresolved-refs.test.ts +1 -4
- package/src/rules/common/__tests__/info-description.test.ts +1 -3
- package/src/rules/common/__tests__/info-license.test.ts +1 -2
- package/src/rules/common/__tests__/license-url.test.ts +1 -2
- package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -2
- package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +1 -2
- package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -2
- package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +1 -2
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +1 -2
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +1 -2
- package/src/rules/common/__tests__/operation-operationId-unique.test.ts +1 -2
- package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -2
- package/src/rules/common/__tests__/operation-parameters-unique.test.ts +1 -2
- package/src/rules/common/__tests__/operation-security-defined.test.ts +1 -2
- package/src/rules/common/__tests__/operation-singular-tag.test.ts +1 -2
- package/src/rules/common/__tests__/path-http-verbs-order.test.ts +1 -2
- package/src/rules/common/__tests__/path-not-include-query.test.ts +1 -2
- package/src/rules/common/__tests__/path-params-defined.test.ts +1 -2
- package/src/rules/common/__tests__/paths-kebab-case.test.ts +1 -2
- package/src/rules/common/__tests__/tag-description.test.ts +1 -2
- package/src/rules/common/__tests__/tags-alphabetical.test.ts +1 -2
- package/src/rules/common/operation-security-defined.ts +4 -5
- package/src/rules/common/spec.ts +18 -0
- package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +1 -2
- package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +1 -2
- package/src/rules/oas2/index.ts +1 -13
- package/src/rules/oas2/remove-unused-components.ts +12 -10
- package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-server-example.com.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -2
- package/src/rules/oas3/index.ts +0 -14
- package/src/rules/oas3/no-invalid-media-type-examples.ts +17 -21
- package/src/rules/oas3/remove-unused-components.ts +12 -10
- package/src/types/index.ts +4 -0
- package/src/types/oas2.ts +42 -40
- package/src/types/oas3.ts +68 -141
- package/src/types/oas3_1.ts +51 -50
- package/src/utils.ts +1 -1
- package/src/walk.ts +2 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/builtin.d.ts +0 -22
- package/lib/rules/builtin.js +0 -17
- package/src/rules/__tests__/config.ts +0 -11
- package/src/rules/builtin.ts +0 -18
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { outdent } from 'outdent';
|
|
1
2
|
import { parseYaml, stringifyYaml } from '../js-yaml';
|
|
2
3
|
|
|
3
4
|
const yaml = `
|
|
@@ -7,7 +8,8 @@ const yaml = `
|
|
|
7
8
|
number: 1000
|
|
8
9
|
decimal: 12.34
|
|
9
10
|
boolean: true
|
|
10
|
-
|
|
11
|
+
dateWithoutQuotes: 2020-01-01
|
|
12
|
+
dateWithQuotes: '2020-01-01'
|
|
11
13
|
array:
|
|
12
14
|
- 1
|
|
13
15
|
- 2
|
|
@@ -16,6 +18,16 @@ const yaml = `
|
|
|
16
18
|
key2: 2
|
|
17
19
|
`;
|
|
18
20
|
|
|
21
|
+
const yamlToDump = outdent`
|
|
22
|
+
date: '2022-01-21T11:29:56.694Z'
|
|
23
|
+
dateWithoutQuotes: 2020-01-01
|
|
24
|
+
dateWithQuotes: '2020-01-01'
|
|
25
|
+
dateImplicit: !!str 2020-01-01
|
|
26
|
+
string: test
|
|
27
|
+
stringWithQuotes: 'test'
|
|
28
|
+
stringWithDoubleQuotes: "test"
|
|
29
|
+
`;
|
|
30
|
+
|
|
19
31
|
const jsObject = {
|
|
20
32
|
emptyValue: null,
|
|
21
33
|
'spaces in keys': 'spaces in keys',
|
|
@@ -23,7 +35,8 @@ const jsObject = {
|
|
|
23
35
|
number: 1000,
|
|
24
36
|
decimal: 12.34,
|
|
25
37
|
boolean: true,
|
|
26
|
-
|
|
38
|
+
dateWithoutQuotes: '2020-01-01',
|
|
39
|
+
dateWithQuotes: '2020-01-01',
|
|
27
40
|
array: [1, 2],
|
|
28
41
|
object: { key1: 1, key2: 2 },
|
|
29
42
|
};
|
|
@@ -33,14 +46,25 @@ describe('js-yaml', () => {
|
|
|
33
46
|
expect(parseYaml(yaml)).toEqual(jsObject);
|
|
34
47
|
});
|
|
35
48
|
|
|
49
|
+
test('should correctly dump date and string', () => {
|
|
50
|
+
expect(stringifyYaml(parseYaml(yamlToDump))).toMatchInlineSnapshot(
|
|
51
|
+
`
|
|
52
|
+
"date: '2022-01-21T11:29:56.694Z'
|
|
53
|
+
dateWithoutQuotes: '2020-01-01'
|
|
54
|
+
dateWithQuotes: '2020-01-01'
|
|
55
|
+
dateImplicit: '2020-01-01'
|
|
56
|
+
string: test
|
|
57
|
+
stringWithQuotes: test
|
|
58
|
+
stringWithDoubleQuotes: test
|
|
59
|
+
"
|
|
60
|
+
`);
|
|
61
|
+
});
|
|
62
|
+
|
|
36
63
|
test('parse and stringify', () => {
|
|
37
64
|
expect(parseYaml(stringifyYaml(jsObject))).toEqual(jsObject);
|
|
38
65
|
});
|
|
39
66
|
|
|
40
67
|
test('should throw an error for unsupported types', () => {
|
|
41
|
-
expect(() => stringifyYaml({ date: new Date() }))
|
|
42
|
-
.toThrow('unacceptable kind of an object to dump [object Date]');
|
|
43
|
-
|
|
44
68
|
expect(() => stringifyYaml({ foo: () => {} }))
|
|
45
69
|
.toThrow('unacceptable kind of an object to dump [object Function]');
|
|
46
70
|
});
|
|
@@ -3,9 +3,7 @@ import { outdent } from 'outdent';
|
|
|
3
3
|
import { lintFromString, lintConfig, lintDocument } from '../lint';
|
|
4
4
|
import { BaseResolver } from '../resolve';
|
|
5
5
|
import { loadConfig } from '../config/load';
|
|
6
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../__tests__/utils';
|
|
7
|
-
// todo create general utils for tests and move this config.
|
|
8
|
-
import { makeConfig } from '../rules/__tests__/config';
|
|
6
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../__tests__/utils';
|
|
9
7
|
|
|
10
8
|
describe('lint', () => {
|
|
11
9
|
it('lintFromString should work', async () => {
|
package/src/bundle.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import isEqual = require('lodash.isequal');
|
|
2
|
-
import { BaseResolver, resolveDocument, Document } from './resolve';
|
|
2
|
+
import { BaseResolver, resolveDocument, Document, ResolvedRefMap, makeRefId } from './resolve';
|
|
3
3
|
import { Oas3Rule, normalizeVisitors, Oas3Visitor, Oas2Visitor } from './visitors';
|
|
4
4
|
import { Oas3Types } from './types/oas3';
|
|
5
5
|
import { Oas2Types } from './types/oas2';
|
|
@@ -115,25 +115,25 @@ export async function bundleDocument(opts: {
|
|
|
115
115
|
})
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
const resolvedRefMap = await resolveDocument({
|
|
119
|
+
rootDocument: document,
|
|
120
|
+
rootType: types.DefinitionRoot,
|
|
121
|
+
externalRefResolver,
|
|
122
|
+
});
|
|
123
|
+
|
|
118
124
|
const bundleVisitor = normalizeVisitors(
|
|
119
125
|
[
|
|
120
126
|
...preprocessors,
|
|
121
127
|
{
|
|
122
128
|
severity: 'error',
|
|
123
129
|
ruleId: 'bundler',
|
|
124
|
-
visitor: makeBundleVisitor(oasMajorVersion, dereference, skipRedoclyRegistryRefs, document),
|
|
130
|
+
visitor: makeBundleVisitor(oasMajorVersion, dereference, skipRedoclyRegistryRefs, document, resolvedRefMap),
|
|
125
131
|
},
|
|
126
132
|
...decorators,
|
|
127
133
|
],
|
|
128
134
|
types,
|
|
129
135
|
);
|
|
130
136
|
|
|
131
|
-
const resolvedRefMap = await resolveDocument({
|
|
132
|
-
rootDocument: document,
|
|
133
|
-
rootType: types.DefinitionRoot,
|
|
134
|
-
externalRefResolver,
|
|
135
|
-
});
|
|
136
|
-
|
|
137
137
|
walkDocument({
|
|
138
138
|
document,
|
|
139
139
|
rootType: types.DefinitionRoot as NormalizedNodeType,
|
|
@@ -198,6 +198,7 @@ function makeBundleVisitor(
|
|
|
198
198
|
dereference: boolean,
|
|
199
199
|
skipRedoclyRegistryRefs: boolean,
|
|
200
200
|
rootDocument: Document,
|
|
201
|
+
resolvedRefMap: ResolvedRefMap
|
|
201
202
|
) {
|
|
202
203
|
let components: Record<string, Record<string, any>>;
|
|
203
204
|
|
|
@@ -230,6 +231,7 @@ function makeBundleVisitor(
|
|
|
230
231
|
replaceRef(node, resolved, ctx);
|
|
231
232
|
} else {
|
|
232
233
|
node.$ref = saveComponent(componentType, resolved, ctx);
|
|
234
|
+
resolveBundledComponent(node, resolved, ctx);
|
|
233
235
|
}
|
|
234
236
|
}
|
|
235
237
|
},
|
|
@@ -267,6 +269,17 @@ function makeBundleVisitor(
|
|
|
267
269
|
};
|
|
268
270
|
}
|
|
269
271
|
|
|
272
|
+
function resolveBundledComponent(node: OasRef, resolved: ResolveResult<any>, ctx: UserContext) {
|
|
273
|
+
const newRefId = makeRefId(ctx.location.source.absoluteRef, node.$ref)
|
|
274
|
+
resolvedRefMap.set(newRefId, {
|
|
275
|
+
document: rootDocument,
|
|
276
|
+
isRemote: false,
|
|
277
|
+
node: resolved.node,
|
|
278
|
+
nodePointer: node.$ref,
|
|
279
|
+
resolved: true,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
270
283
|
function replaceRef(ref: OasRef, resolved: ResolveResult<any>, ctx: UserContext) {
|
|
271
284
|
if (!isPlainObject(resolved.node)) {
|
|
272
285
|
ctx.parent[ctx.key] = resolved.node;
|
package/src/config/builtIn.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import recommended from './recommended';
|
|
2
2
|
import all from './all';
|
|
3
3
|
import minimal from './minimal';
|
|
4
|
-
import { LintRawConfig, Plugin } from './config';
|
|
5
|
-
|
|
6
|
-
import
|
|
4
|
+
import { CustomRulesConfig, LintRawConfig, Plugin } from './config';
|
|
5
|
+
import { rules as oas3Rules } from '../rules/oas3';
|
|
6
|
+
import { rules as oas2Rules } from '../rules/oas2';
|
|
7
|
+
import { preprocessors as oas3Preprocessors } from '../rules/oas3';
|
|
8
|
+
import { preprocessors as oas2Preprocessors } from '../rules/oas2';
|
|
9
|
+
import { decorators as oas3Decorators } from '../decorators/oas3';
|
|
10
|
+
import { decorators as oas2Decorators } from '../decorators/oas2';
|
|
7
11
|
|
|
8
12
|
export const builtInConfigs: Record<string, LintRawConfig> = {
|
|
9
13
|
recommended,
|
|
@@ -16,8 +20,17 @@ export const builtInConfigs: Record<string, LintRawConfig> = {
|
|
|
16
20
|
|
|
17
21
|
export const defaultPlugin: Plugin = {
|
|
18
22
|
id: '', // default plugin doesn't have id
|
|
19
|
-
rules:
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
rules: {
|
|
24
|
+
oas3: oas3Rules,
|
|
25
|
+
oas2: oas2Rules,
|
|
26
|
+
} as CustomRulesConfig,
|
|
27
|
+
preprocessors: {
|
|
28
|
+
oas3: oas3Preprocessors,
|
|
29
|
+
oas2: oas2Preprocessors,
|
|
30
|
+
},
|
|
31
|
+
decorators: {
|
|
32
|
+
oas3: oas3Decorators,
|
|
33
|
+
oas2: oas2Decorators,
|
|
34
|
+
},
|
|
22
35
|
configs: builtInConfigs,
|
|
23
|
-
}
|
|
36
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
|
-
import { bundleDocument } from '../../bundle'
|
|
2
|
+
import { bundleDocument } from '../../bundle';
|
|
3
3
|
import { BaseResolver } from '../../resolve';
|
|
4
|
-
import { parseYamlToDocument, yamlSerializer } from '../../../__tests__/utils';
|
|
5
|
-
import { makeConfig } from './config';
|
|
4
|
+
import { parseYamlToDocument, yamlSerializer, makeConfig } from '../../../__tests__/utils';
|
|
6
5
|
|
|
7
6
|
describe('oas3 remove-x-internal', () => {
|
|
8
7
|
expect.addSnapshotSerializer(yamlSerializer);
|
|
@@ -19,23 +18,23 @@ describe('oas3 remove-x-internal', () => {
|
|
|
19
18
|
parameters:
|
|
20
19
|
x:
|
|
21
20
|
name: x
|
|
22
|
-
|
|
21
|
+
`,
|
|
22
|
+
);
|
|
23
23
|
|
|
24
24
|
it('should use `internalFlagProperty` option to remove internal paths', async () => {
|
|
25
25
|
const { bundle: res } = await bundleDocument({
|
|
26
26
|
document: testDocument,
|
|
27
27
|
externalRefResolver: new BaseResolver(),
|
|
28
|
-
config: makeConfig({}, { 'remove-x-internal': {
|
|
28
|
+
config: makeConfig({}, { 'remove-x-internal': { internalFlagProperty: 'removeit' } }),
|
|
29
29
|
});
|
|
30
|
-
expect(res.parsed).toMatchInlineSnapshot(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
name: x
|
|
30
|
+
expect(res.parsed).toMatchInlineSnapshot(`
|
|
31
|
+
openapi: 3.0.0
|
|
32
|
+
components:
|
|
33
|
+
parameters:
|
|
34
|
+
x:
|
|
35
|
+
name: x
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
`);
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
it('should clean types: Server, Operation, Parameter, PathItem, Example', async () => {
|
|
@@ -88,14 +87,14 @@ describe('oas3 remove-x-internal', () => {
|
|
|
88
87
|
name: x
|
|
89
88
|
y:
|
|
90
89
|
name: y
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
|
|
90
|
+
`,
|
|
91
|
+
);
|
|
92
|
+
const { bundle: res } = await bundleDocument({
|
|
93
|
+
document: testDoc,
|
|
94
|
+
externalRefResolver: new BaseResolver(),
|
|
95
|
+
config: makeConfig({}, { 'remove-x-internal': 'on' }),
|
|
96
|
+
});
|
|
97
|
+
expect(res.parsed).toMatchInlineSnapshot(`
|
|
99
98
|
openapi: 3.1.0
|
|
100
99
|
paths:
|
|
101
100
|
/pet:
|
|
@@ -115,8 +114,7 @@ describe('oas3 remove-x-internal', () => {
|
|
|
115
114
|
'y':
|
|
116
115
|
name: 'y'
|
|
117
116
|
|
|
118
|
-
`
|
|
119
|
-
);
|
|
117
|
+
`);
|
|
120
118
|
});
|
|
121
119
|
|
|
122
120
|
it('should clean types: Schema, Response, RequestBody, MediaType, Callback', async () => {
|
|
@@ -162,14 +160,15 @@ describe('oas3 remove-x-internal', () => {
|
|
|
162
160
|
servers:
|
|
163
161
|
- url: //callback-url.path-level/v1
|
|
164
162
|
description: Path level server
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
|
|
163
|
+
`,
|
|
164
|
+
);
|
|
165
|
+
const { bundle: res } = await bundleDocument({
|
|
166
|
+
document: testDoc,
|
|
167
|
+
externalRefResolver: new BaseResolver(),
|
|
168
|
+
config: makeConfig({}, { 'remove-x-internal': 'on' }),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(res.parsed).toMatchInlineSnapshot(`
|
|
173
172
|
openapi: 3.1.0
|
|
174
173
|
paths:
|
|
175
174
|
/pet:
|
|
@@ -185,6 +184,90 @@ describe('oas3 remove-x-internal', () => {
|
|
|
185
184
|
|
|
186
185
|
`);
|
|
187
186
|
});
|
|
187
|
+
|
|
188
|
+
it('should remove refs', async () => {
|
|
189
|
+
const testDoc = parseYamlToDocument(
|
|
190
|
+
outdent`
|
|
191
|
+
openapi: 3.0.1
|
|
192
|
+
info:
|
|
193
|
+
version: 1.0.0
|
|
194
|
+
title: Test API
|
|
195
|
+
paths:
|
|
196
|
+
/test1:
|
|
197
|
+
get:
|
|
198
|
+
parameters:
|
|
199
|
+
- $ref: '#/components/parameters/Internal'
|
|
200
|
+
- in: query
|
|
201
|
+
name: inline
|
|
202
|
+
schema:
|
|
203
|
+
type: string
|
|
204
|
+
- in: query
|
|
205
|
+
name: inline-internal
|
|
206
|
+
schema:
|
|
207
|
+
type: string
|
|
208
|
+
x-internal: true
|
|
209
|
+
/test2:
|
|
210
|
+
get:
|
|
211
|
+
parameters:
|
|
212
|
+
- $ref: '#/components/parameters/Public'
|
|
213
|
+
- $ref: '#/components/parameters/Internal'
|
|
214
|
+
requestBody:
|
|
215
|
+
$ref: '#/components/requestBodies/Public'
|
|
216
|
+
components:
|
|
217
|
+
requestBodies:
|
|
218
|
+
Public:
|
|
219
|
+
content:
|
|
220
|
+
application/json:
|
|
221
|
+
schema:
|
|
222
|
+
type: string
|
|
223
|
+
required: true
|
|
224
|
+
x-internal: true
|
|
225
|
+
parameters:
|
|
226
|
+
Public:
|
|
227
|
+
in: path
|
|
228
|
+
name: product_id
|
|
229
|
+
schema:
|
|
230
|
+
type: string
|
|
231
|
+
Internal:
|
|
232
|
+
in: header
|
|
233
|
+
name: X-Vendor
|
|
234
|
+
schema:
|
|
235
|
+
type: string
|
|
236
|
+
x-internal: true
|
|
237
|
+
`,
|
|
238
|
+
);
|
|
239
|
+
const { bundle: res } = await bundleDocument({
|
|
240
|
+
document: testDoc,
|
|
241
|
+
externalRefResolver: new BaseResolver(),
|
|
242
|
+
config: makeConfig({}, { 'remove-x-internal': 'on' }),
|
|
243
|
+
});
|
|
244
|
+
expect(res.parsed).toMatchInlineSnapshot(`
|
|
245
|
+
openapi: 3.0.1
|
|
246
|
+
info:
|
|
247
|
+
version: 1.0.0
|
|
248
|
+
title: Test API
|
|
249
|
+
paths:
|
|
250
|
+
/test1:
|
|
251
|
+
get:
|
|
252
|
+
parameters:
|
|
253
|
+
- in: query
|
|
254
|
+
name: inline
|
|
255
|
+
schema:
|
|
256
|
+
type: string
|
|
257
|
+
/test2:
|
|
258
|
+
get:
|
|
259
|
+
parameters:
|
|
260
|
+
- $ref: '#/components/parameters/Public'
|
|
261
|
+
components:
|
|
262
|
+
parameters:
|
|
263
|
+
Public:
|
|
264
|
+
in: path
|
|
265
|
+
name: product_id
|
|
266
|
+
schema:
|
|
267
|
+
type: string
|
|
268
|
+
|
|
269
|
+
`);
|
|
270
|
+
});
|
|
188
271
|
});
|
|
189
272
|
|
|
190
273
|
describe('oas2 remove-x-internal', () => {
|
|
@@ -214,21 +297,20 @@ describe('oas2 remove-x-internal', () => {
|
|
|
214
297
|
'200':
|
|
215
298
|
x-internal: true
|
|
216
299
|
description: List of recent media entries.
|
|
217
|
-
|
|
300
|
+
`,
|
|
301
|
+
);
|
|
218
302
|
const { bundle: res } = await bundleDocument({
|
|
219
303
|
document: testDoc,
|
|
220
304
|
externalRefResolver: new BaseResolver(),
|
|
221
|
-
config: makeConfig({}, { 'remove-x-internal': 'on' })
|
|
305
|
+
config: makeConfig({}, { 'remove-x-internal': 'on' }),
|
|
222
306
|
});
|
|
223
|
-
expect(res.parsed).toMatchInlineSnapshot(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
get: {}
|
|
307
|
+
expect(res.parsed).toMatchInlineSnapshot(`
|
|
308
|
+
swagger: '2.0'
|
|
309
|
+
host: api.instagram.com
|
|
310
|
+
paths:
|
|
311
|
+
/geographies/{geo-id}/media/recent:
|
|
312
|
+
get: {}
|
|
230
313
|
|
|
231
|
-
|
|
232
|
-
);
|
|
314
|
+
`);
|
|
233
315
|
});
|
|
234
316
|
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Oas3Decorator, Oas2Decorator } from '../../visitors';
|
|
2
2
|
import { isEmptyArray, isEmptyObject, isPlainObject } from '../../utils';
|
|
3
3
|
import { UserContext } from '../../walk';
|
|
4
|
+
import { isRef } from '../../ref-utils';
|
|
4
5
|
|
|
5
6
|
const DEFAULT_INTERNAL_PROPERTY_NAME = 'x-internal';
|
|
6
7
|
|
|
@@ -12,7 +13,15 @@ export const RemoveXInternal: Oas3Decorator | Oas2Decorator = ({ internalFlagPro
|
|
|
12
13
|
let didDelete = false;
|
|
13
14
|
if (Array.isArray(node)) {
|
|
14
15
|
for (let i = 0; i < node.length; i++) {
|
|
15
|
-
if (node[i]
|
|
16
|
+
if (isRef(node[i])) {
|
|
17
|
+
const resolved = ctx.resolve(node[i]);
|
|
18
|
+
if (resolved.node?.[hiddenTag]) {
|
|
19
|
+
node.splice(i, 1);
|
|
20
|
+
didDelete = true;
|
|
21
|
+
i--;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (node[i]?.[hiddenTag]) {
|
|
16
25
|
node.splice(i, 1);
|
|
17
26
|
didDelete = true;
|
|
18
27
|
i--;
|
|
@@ -20,8 +29,16 @@ export const RemoveXInternal: Oas3Decorator | Oas2Decorator = ({ internalFlagPro
|
|
|
20
29
|
}
|
|
21
30
|
} else if (isPlainObject(node)) {
|
|
22
31
|
for (const key of Object.keys(node)) {
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
node = node as any;
|
|
33
|
+
if (isRef(node[key])) {
|
|
34
|
+
const resolved = ctx.resolve(node[key]);
|
|
35
|
+
if (resolved.node?.[hiddenTag]) {
|
|
36
|
+
delete node[key];
|
|
37
|
+
didDelete = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (node[key]?.[hiddenTag]) {
|
|
41
|
+
delete node[key];
|
|
25
42
|
didDelete = true;
|
|
26
43
|
}
|
|
27
44
|
}
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Oas2Decorator } from '../../visitors';
|
|
2
|
+
import { RegistryDependencies } from '../common/registry-dependencies';
|
|
3
|
+
import { OperationDescriptionOverride } from '../common/operation-description-override';
|
|
4
|
+
import { TagDescriptionOverride } from '../common/tag-description-override';
|
|
5
|
+
import { InfoDescriptionOverride } from '../common/info-description-override';
|
|
6
|
+
import { RemoveXInternal } from '../common/remove-x-internal';
|
|
7
|
+
|
|
8
|
+
export const decorators = {
|
|
9
|
+
'registry-dependencies': RegistryDependencies as Oas2Decorator,
|
|
10
|
+
'operation-description-override': OperationDescriptionOverride as Oas2Decorator,
|
|
11
|
+
'tag-description-override': TagDescriptionOverride as Oas2Decorator,
|
|
12
|
+
'info-description-override': InfoDescriptionOverride as Oas2Decorator,
|
|
13
|
+
'remove-x-internal': RemoveXInternal as Oas2Decorator
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Oas3Decorator } from '../../visitors';
|
|
2
|
+
import { RegistryDependencies } from '../common/registry-dependencies';
|
|
3
|
+
import { OperationDescriptionOverride } from '../common/operation-description-override';
|
|
4
|
+
import { TagDescriptionOverride } from '../common/tag-description-override';
|
|
5
|
+
import { InfoDescriptionOverride } from '../common/info-description-override';
|
|
6
|
+
import { RemoveXInternal } from '../common/remove-x-internal';
|
|
7
|
+
|
|
8
|
+
export const decorators = {
|
|
9
|
+
'registry-dependencies': RegistryDependencies as Oas3Decorator,
|
|
10
|
+
'operation-description-override': OperationDescriptionOverride as Oas3Decorator,
|
|
11
|
+
'tag-description-override': TagDescriptionOverride as Oas3Decorator,
|
|
12
|
+
'info-description-override': InfoDescriptionOverride as Oas3Decorator,
|
|
13
|
+
'remove-x-internal': RemoveXInternal as Oas3Decorator
|
|
14
|
+
};
|
package/src/js-yaml/index.ts
CHANGED
|
@@ -15,5 +15,4 @@ const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = JSON_SCHEMA.extend({
|
|
|
15
15
|
export const parseYaml = (str: string, opts?: LoadOptions): unknown =>
|
|
16
16
|
load(str, {schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts});
|
|
17
17
|
|
|
18
|
-
export const stringifyYaml = (obj: any, opts?: DumpOptions): string =>
|
|
19
|
-
dump(obj, {schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts});
|
|
18
|
+
export const stringifyYaml = (obj: any, opts?: DumpOptions): string => dump(obj, opts);
|
|
@@ -23,7 +23,10 @@ export class RegistryApi {
|
|
|
23
23
|
private async request(path = '', options: RequestInit = {}, region?: Region) {
|
|
24
24
|
const headers = Object.assign({}, options.headers || {}, { 'x-redocly-cli-version': version });
|
|
25
25
|
if (!headers.hasOwnProperty('authorization')) { throw new Error('Unauthorized'); }
|
|
26
|
-
const response = await fetch(
|
|
26
|
+
const response = await fetch(
|
|
27
|
+
`${this.getBaseUrl(region)}${path}`,
|
|
28
|
+
Object.assign({}, options, { headers }),
|
|
29
|
+
);
|
|
27
30
|
if (response.status === 401) { throw new Error('Unauthorized'); }
|
|
28
31
|
if (response.status === 404) {
|
|
29
32
|
const body: RegistryApiTypes.NotFoundProblemResponse = await response.json();
|
package/src/resolve.ts
CHANGED
|
@@ -74,6 +74,10 @@ export type Document = {
|
|
|
74
74
|
parsed: any;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
export function makeRefId(absoluteRef: string, pointer: string) {
|
|
78
|
+
return absoluteRef + '::' + pointer;
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
export function makeDocumentFromString(sourceString: string, absoluteRef: string) {
|
|
78
82
|
const source = new Source(absoluteRef, sourceString);
|
|
79
83
|
try {
|
|
@@ -323,10 +327,8 @@ export async function resolveDocument(opts: {
|
|
|
323
327
|
document: undefined,
|
|
324
328
|
error: error,
|
|
325
329
|
};
|
|
326
|
-
|
|
327
|
-
const refId = document.source.absoluteRef + '::' + ref.$ref;
|
|
330
|
+
const refId = makeRefId(document.source.absoluteRef, ref.$ref);
|
|
328
331
|
resolvedRefMap.set(refId, resolvedRef);
|
|
329
|
-
|
|
330
332
|
return resolvedRef;
|
|
331
333
|
}
|
|
332
334
|
|
|
@@ -367,13 +369,11 @@ export async function resolveDocument(opts: {
|
|
|
367
369
|
|
|
368
370
|
resolvedRef.node = target;
|
|
369
371
|
resolvedRef.document = targetDoc;
|
|
370
|
-
const refId = document.source.absoluteRef
|
|
371
|
-
|
|
372
|
+
const refId = makeRefId(document.source.absoluteRef, ref.$ref);
|
|
372
373
|
if (resolvedRef.document && isRef(target)) {
|
|
373
374
|
resolvedRef = await followRef(resolvedRef.document, target, pushRef(refStack, target));
|
|
374
375
|
}
|
|
375
376
|
resolvedRefMap.set(refId, resolvedRef);
|
|
376
|
-
|
|
377
377
|
return { ...resolvedRef };
|
|
378
378
|
}
|
|
379
379
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import path = require('path');
|
|
2
2
|
import { outdent } from 'outdent';
|
|
3
|
-
|
|
4
3
|
import { lintDocument } from '../../lint';
|
|
5
4
|
import { BaseResolver } from '../../resolve';
|
|
6
|
-
|
|
7
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../__tests__/utils';
|
|
8
|
-
import { makeConfig } from './config';
|
|
5
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../__tests__/utils';
|
|
9
6
|
|
|
10
7
|
describe('oas3 boolean-parameter-prefixes', () => {
|
|
11
8
|
it('should report on unresolved $ref', async () => {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
4
4
|
import { BaseResolver } from '../../../resolve';
|
|
5
5
|
|
|
6
|
-
import { makeConfig } from '../../__tests__/config';
|
|
7
|
-
|
|
8
6
|
describe('Oas3 info-description', () => {
|
|
9
7
|
it('should report on info with no description', async () => {
|
|
10
8
|
const document = parseYamlToDocument(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('Oas3 info-license', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('Oas3 license-url', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('no-ambiguous-paths', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('Oas3 typed enum', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('no-identical-paths', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('no-path-trailing-slash', () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { outdent } from 'outdent';
|
|
2
2
|
import { lintDocument } from '../../../lint';
|
|
3
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils';
|
|
4
|
-
import { makeConfig } from '../../__tests__/config';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
5
4
|
import { BaseResolver } from '../../../resolve';
|
|
6
5
|
|
|
7
6
|
describe('Oas3 operation-2xx-response', () => {
|