@redocly/openapi-core 1.0.2 → 1.2.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/bundle.d.ts +2 -2
  3. package/lib/bundle.js +24 -22
  4. package/lib/config/builtIn.js +4 -0
  5. package/lib/config/config-resolvers.js +19 -6
  6. package/lib/config/config.d.ts +9 -9
  7. package/lib/config/config.js +32 -17
  8. package/lib/config/rules.d.ts +2 -2
  9. package/lib/config/types.d.ts +9 -3
  10. package/lib/format/codeframes.d.ts +1 -1
  11. package/lib/index.d.ts +1 -1
  12. package/lib/index.js +7 -6
  13. package/lib/lint.js +10 -16
  14. package/lib/oas-types.d.ts +16 -10
  15. package/lib/oas-types.js +52 -26
  16. package/lib/rules/async2/channels-kebab-case.d.ts +2 -0
  17. package/lib/rules/async2/channels-kebab-case.js +19 -0
  18. package/lib/rules/async2/index.d.ts +12 -0
  19. package/lib/rules/async2/index.js +22 -0
  20. package/lib/rules/async2/no-channel-trailing-slash.d.ts +2 -0
  21. package/lib/rules/async2/no-channel-trailing-slash.js +16 -0
  22. package/lib/rules/common/no-path-trailing-slash.js +2 -2
  23. package/lib/rules/common/scalar-property-missing-example.js +1 -1
  24. package/lib/rules/common/spec.d.ts +2 -2
  25. package/lib/rules/common/spec.js +3 -3
  26. package/lib/rules/common/tags-alphabetical.js +5 -2
  27. package/lib/rules/oas2/index.js +1 -1
  28. package/lib/rules/oas2/remove-unused-components.js +4 -1
  29. package/lib/rules/oas3/index.js +1 -1
  30. package/lib/rules/oas3/remove-unused-components.js +4 -1
  31. package/lib/rules/utils.d.ts +1 -1
  32. package/lib/types/asyncapi.d.ts +2 -0
  33. package/lib/types/asyncapi.js +1027 -0
  34. package/lib/types/portal-config-schema.d.ts +2533 -0
  35. package/lib/types/portal-config-schema.js +304 -0
  36. package/lib/types/redocly-yaml.js +26 -20
  37. package/lib/types/{config-external-schemas.d.ts → theme-config.d.ts} +140 -575
  38. package/lib/types/{config-external-schemas.js → theme-config.js} +55 -261
  39. package/lib/typings/asyncapi.d.ts +21 -0
  40. package/lib/typings/asyncapi.js +2 -0
  41. package/lib/visitors.d.ts +12 -0
  42. package/lib/walk.d.ts +3 -3
  43. package/package.json +3 -2
  44. package/src/__tests__/lint.test.ts +38 -6
  45. package/src/bundle.ts +27 -28
  46. package/src/config/__tests__/__snapshots__/config.test.ts.snap +24 -0
  47. package/src/config/__tests__/config.test.ts +15 -4
  48. package/src/config/builtIn.ts +4 -0
  49. package/src/config/config-resolvers.ts +25 -6
  50. package/src/config/config.ts +51 -27
  51. package/src/config/rules.ts +2 -2
  52. package/src/config/types.ts +14 -4
  53. package/src/index.ts +7 -1
  54. package/src/lint.ts +13 -22
  55. package/src/oas-types.ts +59 -21
  56. package/src/rules/async2/__tests__/channels-kebab-case.test.ts +141 -0
  57. package/src/rules/async2/__tests__/no-channel-trailing-slash.test.ts +97 -0
  58. package/src/rules/async2/channels-kebab-case.ts +18 -0
  59. package/src/rules/async2/index.ts +22 -0
  60. package/src/rules/async2/no-channel-trailing-slash.ts +15 -0
  61. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +41 -0
  62. package/src/rules/common/__tests__/tags-alphabetical.test.ts +58 -0
  63. package/src/rules/common/no-path-trailing-slash.ts +2 -2
  64. package/src/rules/common/scalar-property-missing-example.ts +2 -2
  65. package/src/rules/common/spec.ts +2 -2
  66. package/src/rules/common/tags-alphabetical.ts +8 -4
  67. package/src/rules/oas2/__tests__/remove-unused-components.test.ts +155 -0
  68. package/src/rules/oas2/index.ts +2 -2
  69. package/src/rules/oas2/remove-unused-components.ts +6 -1
  70. package/src/rules/oas3/__tests__/remove-unused-components.test.ts +171 -0
  71. package/src/rules/oas3/index.ts +2 -2
  72. package/src/rules/oas3/remove-unused-components.ts +6 -1
  73. package/src/types/asyncapi.ts +1136 -0
  74. package/src/types/portal-config-schema.ts +343 -0
  75. package/src/types/redocly-yaml.ts +23 -34
  76. package/src/types/{config-external-schemas.ts → theme-config.ts} +60 -294
  77. package/src/typings/asyncapi.ts +26 -0
  78. package/src/visitors.ts +22 -0
  79. package/src/walk.ts +3 -3
  80. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,155 @@
1
+ import { outdent } from 'outdent';
2
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
3
+ import { bundleDocument } from '../../../bundle';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('oas2 remove-unused-components', () => {
7
+ it('should remove unused components', async () => {
8
+ const document = parseYamlToDocument(
9
+ outdent`
10
+ swagger: '2.0'
11
+ paths:
12
+ /pets:
13
+ get:
14
+ produces:
15
+ - application/json
16
+ parameters: []
17
+ responses:
18
+ '200':
19
+ schema:
20
+ $ref: '#/definitions/Used'
21
+ operationId: listPets
22
+ summary: List all pets
23
+ definitions:
24
+ Unused:
25
+ enum:
26
+ - 1
27
+ - 2
28
+ type: integer
29
+ Used:
30
+ properties:
31
+ link:
32
+ type: string
33
+ type: object
34
+ `,
35
+ 'foobar.yaml'
36
+ );
37
+
38
+ const results = await bundleDocument({
39
+ externalRefResolver: new BaseResolver(),
40
+ document,
41
+ config: await makeConfig({}),
42
+ removeUnusedComponents: true,
43
+ });
44
+
45
+ expect(results.bundle.parsed).toEqual({
46
+ swagger: '2.0',
47
+ definitions: {
48
+ Used: {
49
+ properties: {
50
+ link: { type: 'string' },
51
+ },
52
+ type: 'object',
53
+ },
54
+ },
55
+ paths: {
56
+ '/pets': {
57
+ get: {
58
+ produces: ['application/json'],
59
+ parameters: [],
60
+ summary: 'List all pets',
61
+ operationId: 'listPets',
62
+ responses: {
63
+ '200': {
64
+ schema: {
65
+ $ref: '#/definitions/Used',
66
+ },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ },
72
+ });
73
+ });
74
+
75
+ it('should not remove components used child reference', async () => {
76
+ const document = parseYamlToDocument(
77
+ outdent`
78
+ swagger: '2.0'
79
+ paths:
80
+ /pets:
81
+ get:
82
+ produces:
83
+ - application/json
84
+ parameters: []
85
+ responses:
86
+ '200':
87
+ schema:
88
+ $ref: '#/definitions/Used'
89
+ operationId: listPets
90
+ summary: List all pets
91
+ definitions:
92
+ InnerUsed:
93
+ properties:
94
+ link:
95
+ type: string
96
+ type: object
97
+ Unused:
98
+ enum:
99
+ - 1
100
+ - 2
101
+ type: integer
102
+ Used:
103
+ properties:
104
+ link:
105
+ $ref: '#/definitions/InnerUsed/properties/link'
106
+ type: object
107
+ `,
108
+ 'foobar.yaml'
109
+ );
110
+
111
+ const results = await bundleDocument({
112
+ externalRefResolver: new BaseResolver(),
113
+ document,
114
+ config: await makeConfig({}),
115
+ removeUnusedComponents: true,
116
+ });
117
+
118
+ expect(results.bundle.parsed).toEqual({
119
+ swagger: '2.0',
120
+ definitions: {
121
+ InnerUsed: {
122
+ properties: {
123
+ link: {
124
+ type: 'string',
125
+ },
126
+ },
127
+ type: 'object',
128
+ },
129
+ Used: {
130
+ properties: {
131
+ link: { $ref: '#/definitions/InnerUsed/properties/link' },
132
+ },
133
+ type: 'object',
134
+ },
135
+ },
136
+ paths: {
137
+ '/pets': {
138
+ get: {
139
+ produces: ['application/json'],
140
+ parameters: [],
141
+ summary: 'List all pets',
142
+ operationId: 'listPets',
143
+ responses: {
144
+ '200': {
145
+ schema: {
146
+ $ref: '#/definitions/Used',
147
+ },
148
+ },
149
+ },
150
+ },
151
+ },
152
+ },
153
+ });
154
+ });
155
+ });
@@ -1,5 +1,5 @@
1
1
  import { Oas2Rule } from '../../visitors';
2
- import { OasSpec } from '../common/spec';
2
+ import { Spec } from '../common/spec';
3
3
  import { NoInvalidSchemaExamples } from '../common/no-invalid-schema-examples';
4
4
  import { NoInvalidParameterExamples } from '../common/no-invalid-parameter-examples';
5
5
  import { InfoContact } from '../common/info-contact';
@@ -43,7 +43,7 @@ import { RequiredStringPropertyMissingMinLength } from '../common/required-strin
43
43
  import { SpecStrictRefs } from '../common/spec-strict-refs';
44
44
 
45
45
  export const rules = {
46
- spec: OasSpec as Oas2Rule,
46
+ spec: Spec as Oas2Rule,
47
47
  'no-invalid-schema-examples': NoInvalidSchemaExamples,
48
48
  'no-invalid-parameter-examples': NoInvalidParameterExamples,
49
49
  'info-contact': InfoContact as Oas2Rule,
@@ -27,7 +27,12 @@ export const RemoveUnusedComponents: Oas2Rule = () => {
27
27
  if (['Schema', 'Parameter', 'Response', 'SecurityScheme'].includes(type.name)) {
28
28
  const resolvedRef = resolve(ref);
29
29
  if (!resolvedRef.location) return;
30
- components.set(resolvedRef.location.absolutePointer, {
30
+
31
+ const [fileLocation, localPointer] = resolvedRef.location.absolutePointer.split('#', 2);
32
+ const componentLevelLocalPointer = localPointer.split('/').slice(0, 3).join('/');
33
+ const pointer = `${fileLocation}#${componentLevelLocalPointer}`;
34
+
35
+ components.set(pointer, {
31
36
  used: true,
32
37
  name: key.toString(),
33
38
  });
@@ -0,0 +1,171 @@
1
+ import { outdent } from 'outdent';
2
+ import { parseYamlToDocument, makeConfig } from '../../../../__tests__/utils';
3
+ import { bundleDocument } from '../../../bundle';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('oas3 remove-unused-components', () => {
7
+ it('should remove unused components', async () => {
8
+ const document = parseYamlToDocument(
9
+ outdent`
10
+ openapi: "3.0.0"
11
+ paths:
12
+ /pets:
13
+ get:
14
+ summary: List all pets
15
+ operationId: listPets
16
+ parameters:
17
+ - $ref: '#/components/parameters/used'
18
+ components:
19
+ parameters:
20
+ used:
21
+ name: used
22
+ unused:
23
+ name: unused
24
+ responses:
25
+ unused: {}
26
+ examples:
27
+ unused: {}
28
+ requestBodies:
29
+ unused: {}
30
+ headers:
31
+ unused: {}
32
+ schemas:
33
+ Unused:
34
+ type: integer
35
+ enum:
36
+ - 1
37
+ - 2
38
+ `,
39
+ 'foobar.yaml'
40
+ );
41
+
42
+ const results = await bundleDocument({
43
+ externalRefResolver: new BaseResolver(),
44
+ document,
45
+ config: await makeConfig({}),
46
+ removeUnusedComponents: true,
47
+ });
48
+
49
+ expect(results.bundle.parsed).toEqual({
50
+ openapi: '3.0.0',
51
+ paths: {
52
+ '/pets': {
53
+ get: {
54
+ summary: 'List all pets',
55
+ operationId: 'listPets',
56
+ parameters: [
57
+ {
58
+ $ref: '#/components/parameters/used',
59
+ },
60
+ ],
61
+ },
62
+ },
63
+ },
64
+ components: {
65
+ parameters: {
66
+ used: {
67
+ name: 'used',
68
+ },
69
+ },
70
+ },
71
+ });
72
+ });
73
+
74
+ it('should not remove components used child reference', async () => {
75
+ const document = parseYamlToDocument(
76
+ outdent`
77
+ openapi: "3.0.0"
78
+ paths:
79
+ /pets:
80
+ get:
81
+ summary: List all pets
82
+ operationId: listPets
83
+ responses:
84
+ '200':
85
+ content:
86
+ application/json:
87
+ schema:
88
+ $ref: '#/components/schemas/Used'
89
+ components:
90
+ parameters:
91
+ unused:
92
+ name: unused
93
+ responses:
94
+ unused: {}
95
+ examples:
96
+ unused: {}
97
+ requestBodies:
98
+ unused: {}
99
+ headers:
100
+ unused: {}
101
+ schemas:
102
+ InnerUsed:
103
+ type: object
104
+ properties:
105
+ link:
106
+ type: string
107
+ Used:
108
+ type: object
109
+ properties:
110
+ link:
111
+ $ref: '#/components/schemas/InnerUsed/properties/link'
112
+ Unused:
113
+ type: integer
114
+ enum:
115
+ - 1
116
+ - 2
117
+ `,
118
+ 'foobar.yaml'
119
+ );
120
+
121
+ const results = await bundleDocument({
122
+ externalRefResolver: new BaseResolver(),
123
+ document,
124
+ config: await makeConfig({}),
125
+ removeUnusedComponents: true,
126
+ });
127
+
128
+ expect(results.bundle.parsed).toEqual({
129
+ openapi: '3.0.0',
130
+ paths: {
131
+ '/pets': {
132
+ get: {
133
+ summary: 'List all pets',
134
+ operationId: 'listPets',
135
+ responses: {
136
+ '200': {
137
+ content: {
138
+ 'application/json': {
139
+ schema: {
140
+ $ref: '#/components/schemas/Used',
141
+ },
142
+ },
143
+ },
144
+ },
145
+ },
146
+ },
147
+ },
148
+ },
149
+ components: {
150
+ schemas: {
151
+ InnerUsed: {
152
+ type: 'object',
153
+ properties: {
154
+ link: {
155
+ type: 'string',
156
+ },
157
+ },
158
+ },
159
+ Used: {
160
+ type: 'object',
161
+ properties: {
162
+ link: {
163
+ $ref: '#/components/schemas/InnerUsed/properties/link',
164
+ },
165
+ },
166
+ },
167
+ },
168
+ },
169
+ });
170
+ });
171
+ });
@@ -1,5 +1,5 @@
1
1
  import { Oas3RuleSet } from '../../oas-types';
2
- import { OasSpec } from '../common/spec';
2
+ import { Spec } from '../common/spec';
3
3
  import { Operation2xxResponse } from '../common/operation-2xx-response';
4
4
  import { Operation4xxResponse } from '../common/operation-4xx-response';
5
5
  import { Assertions } from '../common/assertions';
@@ -54,7 +54,7 @@ import { SpecStrictRefs } from '../common/spec-strict-refs';
54
54
  import { ComponentNameUnique } from './component-name-unique';
55
55
 
56
56
  export const rules = {
57
- spec: OasSpec,
57
+ spec: Spec,
58
58
  'info-contact': InfoContact,
59
59
  'info-license': InfoLicense,
60
60
  'info-license-url': InfoLicenseUrl,
@@ -31,7 +31,12 @@ export const RemoveUnusedComponents: Oas3Rule = () => {
31
31
  ) {
32
32
  const resolvedRef = resolve(ref);
33
33
  if (!resolvedRef.location) return;
34
- components.set(resolvedRef.location.absolutePointer, {
34
+
35
+ const [fileLocation, localPointer] = resolvedRef.location.absolutePointer.split('#', 2);
36
+ const componentLevelLocalPointer = localPointer.split('/').slice(0, 4).join('/');
37
+ const pointer = `${fileLocation}#${componentLevelLocalPointer}`;
38
+
39
+ components.set(pointer, {
35
40
  used: true,
36
41
  name: key.toString(),
37
42
  });