@redocly/openapi-core 1.0.0-beta.64 → 1.0.0-beta.68

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 (81) hide show
  1. package/__tests__/__snapshots__/bundle.test.ts.snap +126 -0
  2. package/__tests__/bundle.test.ts +53 -1
  3. package/__tests__/fixtures/refs/definitions.yaml +3 -0
  4. package/__tests__/fixtures/refs/external-request-body.yaml +13 -0
  5. package/__tests__/fixtures/refs/externalref.yaml +35 -0
  6. package/__tests__/fixtures/refs/hosted.yaml +35 -0
  7. package/__tests__/fixtures/refs/rename.yaml +1 -0
  8. package/__tests__/fixtures/refs/requestBody.yaml +9 -0
  9. package/__tests__/fixtures/refs/simple.yaml +1 -0
  10. package/__tests__/fixtures/refs/vendor.schema.yaml +20 -0
  11. package/lib/bundle.js +16 -4
  12. package/lib/config/all.js +9 -1
  13. package/lib/config/config.js +1 -1
  14. package/lib/config/minimal.js +1 -0
  15. package/lib/config/recommended.js +1 -0
  16. package/lib/index.d.ts +1 -1
  17. package/lib/index.js +2 -1
  18. package/lib/ref-utils.js +1 -2
  19. package/lib/rules/builtin.d.ts +6 -0
  20. package/lib/rules/common/info-description-override.d.ts +2 -0
  21. package/lib/rules/common/info-description-override.js +24 -0
  22. package/lib/rules/common/info-license-url.js +1 -0
  23. package/lib/rules/common/no-http-verbs-in-paths.d.ts +2 -0
  24. package/lib/rules/common/no-http-verbs-in-paths.js +33 -0
  25. package/lib/rules/common/operation-4xx-response.d.ts +2 -0
  26. package/lib/rules/common/operation-4xx-response.js +17 -0
  27. package/lib/rules/common/operation-description-override.d.ts +2 -0
  28. package/lib/rules/common/operation-description-override.js +29 -0
  29. package/lib/rules/common/path-excludes-patterns.d.ts +2 -0
  30. package/lib/rules/common/path-excludes-patterns.js +22 -0
  31. package/lib/rules/common/path-segment-plural.d.ts +2 -0
  32. package/lib/rules/common/path-segment-plural.js +32 -0
  33. package/lib/rules/common/tag-description-override.d.ts +2 -0
  34. package/lib/rules/common/tag-description-override.js +25 -0
  35. package/lib/rules/oas2/index.d.ts +9 -0
  36. package/lib/rules/oas2/index.js +18 -0
  37. package/lib/rules/oas2/request-mime-type.d.ts +2 -0
  38. package/lib/rules/oas2/request-mime-type.js +17 -0
  39. package/lib/rules/oas2/response-mime-type.d.ts +2 -0
  40. package/lib/rules/oas2/response-mime-type.js +17 -0
  41. package/lib/rules/oas3/index.d.ts +3 -0
  42. package/lib/rules/oas3/index.js +19 -1
  43. package/lib/rules/oas3/no-server-trailing-slash.js +1 -1
  44. package/lib/rules/oas3/request-mime-type.d.ts +2 -0
  45. package/lib/rules/oas3/request-mime-type.js +31 -0
  46. package/lib/rules/oas3/response-mime-type.d.ts +2 -0
  47. package/lib/rules/oas3/response-mime-type.js +31 -0
  48. package/lib/types/oas3_1.js +6 -0
  49. package/lib/utils.d.ts +11 -0
  50. package/lib/utils.js +69 -1
  51. package/package.json +4 -2
  52. package/src/__tests__/utils.test.ts +19 -1
  53. package/src/bundle.ts +26 -6
  54. package/src/config/all.ts +9 -1
  55. package/src/config/config.ts +2 -2
  56. package/src/config/minimal.ts +1 -0
  57. package/src/config/recommended.ts +1 -0
  58. package/src/index.ts +1 -1
  59. package/src/ref-utils.ts +1 -3
  60. package/src/rules/common/__tests__/info-license.test.ts +1 -1
  61. package/src/rules/common/__tests__/operation-4xx-response.test.ts +108 -0
  62. package/src/rules/common/info-description-override.ts +24 -0
  63. package/src/rules/common/info-license-url.ts +1 -0
  64. package/src/rules/common/no-http-verbs-in-paths.ts +36 -0
  65. package/src/rules/common/operation-4xx-response.ts +17 -0
  66. package/src/rules/common/operation-description-override.ts +30 -0
  67. package/src/rules/common/path-excludes-patterns.ts +23 -0
  68. package/src/rules/common/path-segment-plural.ts +31 -0
  69. package/src/rules/common/tag-description-override.ts +25 -0
  70. package/src/rules/oas2/index.ts +18 -0
  71. package/src/rules/oas2/request-mime-type.ts +17 -0
  72. package/src/rules/oas2/response-mime-type.ts +17 -0
  73. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +19 -0
  74. package/src/rules/oas3/index.ts +20 -3
  75. package/src/rules/oas3/no-server-trailing-slash.ts +1 -1
  76. package/src/rules/oas3/request-mime-type.ts +31 -0
  77. package/src/rules/oas3/response-mime-type.ts +31 -0
  78. package/src/rules/utils.ts +1 -1
  79. package/src/types/oas3_1.ts +7 -0
  80. package/src/utils.ts +79 -0
  81. package/tsconfig.tsbuildinfo +1 -1
@@ -99,3 +99,129 @@ components:
99
99
  name: shared-a
100
100
 
101
101
  `;
102
+
103
+ exports[`bundle should not place referened schema inline when component in question is not of type "schemas" 1`] = `
104
+ openapi: 3.0.0
105
+ paths:
106
+ /pet:
107
+ post:
108
+ requestBody:
109
+ content:
110
+ application/json:
111
+ schema:
112
+ $ref: '#/components/schemas/requestBody'
113
+ components:
114
+ schemas:
115
+ requestBody:
116
+ content:
117
+ application/json:
118
+ schema:
119
+ type: object
120
+ properties:
121
+ a:
122
+ type: string
123
+ b:
124
+ type: number
125
+
126
+ `;
127
+
128
+ exports[`bundle should place referenced schema inline when referenced schema name resolves to original schema name 1`] = `
129
+ openapi: 3.1.0
130
+ info:
131
+ title: My API
132
+ description: It ain't so wonderful, but at least it's mine.
133
+ version: '1.0'
134
+ contact:
135
+ email: me@theintenet.com
136
+ name: me
137
+ paths:
138
+ /test:
139
+ get:
140
+ summary: test
141
+ responses:
142
+ '200':
143
+ description: test
144
+ content:
145
+ application/json:
146
+ schema:
147
+ $ref: '#/components/schemas/vendor'
148
+ components:
149
+ schemas:
150
+ vendor:
151
+ title: vendor
152
+ type: object
153
+ description: Vendors
154
+ properties:
155
+ key:
156
+ type: string
157
+ description: System-assigned key for the vendor.
158
+ readOnly: true
159
+ id:
160
+ type: string
161
+ description: >
162
+ Unique identifier of the vendor.
163
+
164
+ You must specify a unique vendor ID when creating a vendor unless
165
+ document sequencing is configured, in which case the ID is
166
+ auto-generated.
167
+ name:
168
+ type: string
169
+ description: Name of the vendor.
170
+ isOneTimeUse:
171
+ type: boolean
172
+ description: One-time use
173
+ default: false
174
+ myvendor:
175
+ $ref: '#/components/schemas/vendor'
176
+ simple:
177
+ type: string
178
+ A:
179
+ type: string
180
+ test:
181
+ $ref: '#/components/schemas/rename-2'
182
+ rename:
183
+ type: string
184
+ rename-2:
185
+ type: number
186
+
187
+ `;
188
+
189
+ exports[`bundle should pull hosted schema 1`] = `
190
+ openapi: 3.0.3
191
+ info:
192
+ title: bugtest
193
+ version: '1.0'
194
+ description: Demo
195
+ license:
196
+ name: DEMO
197
+ url: https://demo.com
198
+ servers:
199
+ - url: http://demo.com/api
200
+ paths:
201
+ /customer:
202
+ summary: Customer scope
203
+ get:
204
+ summary: Get demo no refs
205
+ operationId: GetCustomer
206
+ description: Returns Demo No Refs
207
+ responses:
208
+ '200':
209
+ description: Demo No Refs
210
+ content:
211
+ application/json:
212
+ schema:
213
+ $ref: '#/components/schemas/Customer'
214
+ components:
215
+ schemas:
216
+ Customer:
217
+ type: object
218
+ properties:
219
+ customerName:
220
+ type: string
221
+ accounts:
222
+ type: array
223
+ items:
224
+ $ref: '#/components/schemas/someexternal'
225
+ someexternal: External schema content
226
+
227
+ `;
@@ -10,7 +10,7 @@ import { BaseResolver } from '../src/resolve';
10
10
  describe('bundle', () => {
11
11
  expect.addSnapshotSerializer(yamlSerializer);
12
12
 
13
- const testDocument = parseYamlToDocument(
13
+ const testDocument = parseYamlToDocument(
14
14
  outdent`
15
15
  openapi: 3.0.0
16
16
  paths:
@@ -77,4 +77,56 @@ describe('bundle', () => {
77
77
  expect(problems).toHaveLength(0);
78
78
  expect(res.parsed).toMatchSnapshot();
79
79
  });
80
+
81
+ it('should place referenced schema inline when referenced schema name resolves to original schema name', async () => {
82
+ const { bundle: res, problems } = await bundle({
83
+ config: new Config({}),
84
+ ref: path.join(__dirname, 'fixtures/refs/externalref.yaml'),
85
+ });
86
+
87
+ expect(problems).toHaveLength(0);
88
+ expect(res.parsed).toMatchSnapshot();
89
+ });
90
+
91
+ it('should not place referened schema inline when component in question is not of type "schemas"', async () => {
92
+ const { bundle: res, problems } = await bundle({
93
+ config: new Config({}),
94
+ ref: path.join(__dirname, 'fixtures/refs/external-request-body.yaml'),
95
+ });
96
+
97
+ expect(problems).toHaveLength(0);
98
+ expect(res.parsed).toMatchSnapshot();
99
+ });
100
+
101
+ it('should pull hosted schema', async () => {
102
+ const fetchMock = jest.fn(
103
+ () => Promise.resolve({
104
+ ok: true,
105
+ text: () => 'External schema content',
106
+ headers: {
107
+ get: () => ''
108
+ }
109
+ })
110
+ );
111
+
112
+ const { bundle: res, problems } = await bundle({
113
+ config: new Config({}),
114
+ externalRefResolver: new BaseResolver({
115
+ http: {
116
+ customFetch: fetchMock,
117
+ headers: []
118
+ }
119
+ }),
120
+ ref: path.join(__dirname, 'fixtures/refs/hosted.yaml')
121
+ });
122
+
123
+ expect(problems).toHaveLength(0);
124
+ expect(fetchMock).toHaveBeenCalledWith(
125
+ "https://someexternal.schema",
126
+ {
127
+ headers: {}
128
+ }
129
+ );
130
+ expect(res.parsed).toMatchSnapshot();
131
+ })
80
132
  });
@@ -0,0 +1,3 @@
1
+ $defs:
2
+ A:
3
+ type: string
@@ -0,0 +1,13 @@
1
+ openapi: 3.0.0
2
+ paths:
3
+ /pet:
4
+ post:
5
+ requestBody:
6
+ content:
7
+ application/json:
8
+ schema:
9
+ $ref: ./requestBody.yaml
10
+ components:
11
+ schemas:
12
+ requestBody:
13
+ $ref: ./requestBody.yaml
@@ -0,0 +1,35 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: My API
4
+ description: It ain't so wonderful, but at least it's mine.
5
+ version: '1.0'
6
+ contact:
7
+ email: me@theintenet.com
8
+ name: me
9
+ paths:
10
+ /test:
11
+ get:
12
+ summary: 'test'
13
+ responses:
14
+ 200:
15
+ description: test
16
+ content:
17
+ application/json:
18
+ schema:
19
+ $ref: ./vendor.schema.yaml
20
+ components:
21
+ schemas:
22
+ vendor:
23
+ $ref: ./vendor.schema.yaml
24
+ myvendor:
25
+ $ref: ./vendor.schema.yaml
26
+ simple:
27
+ $ref: ./simple.yaml
28
+ A:
29
+ $ref: ./definitions.yaml#/$defs/A
30
+ test:
31
+ $ref: ./rename.yaml
32
+ rename:
33
+ type: string
34
+ rename-2:
35
+ $ref: ./rename.yaml
@@ -0,0 +1,35 @@
1
+ openapi: "3.0.3"
2
+ info:
3
+ title: bugtest
4
+ version: "1.0"
5
+ description: Demo
6
+ license:
7
+ name: DEMO
8
+ url: https://demo.com
9
+ servers:
10
+ - url: http://demo.com/api
11
+ paths:
12
+ /customer:
13
+ summary: "Customer scope"
14
+ get:
15
+ summary: "Get demo no refs"
16
+ operationId: GetCustomer
17
+ description: "Returns Demo No Refs"
18
+ responses:
19
+ 200:
20
+ description: Demo No Refs
21
+ content:
22
+ application/json:
23
+ schema:
24
+ $ref: "#/components/schemas/Customer"
25
+ components:
26
+ schemas:
27
+ Customer:
28
+ type: object
29
+ properties:
30
+ customerName:
31
+ type: string
32
+ accounts:
33
+ type: array
34
+ items:
35
+ $ref: "https://someexternal.schema"
@@ -0,0 +1 @@
1
+ type: number
@@ -0,0 +1,9 @@
1
+ content:
2
+ application/json:
3
+ schema:
4
+ type: object
5
+ properties:
6
+ a:
7
+ type: string
8
+ b:
9
+ type: number
@@ -0,0 +1 @@
1
+ type: string
@@ -0,0 +1,20 @@
1
+ title: vendor
2
+ type: object
3
+ description: Vendors
4
+ properties:
5
+ key:
6
+ type: string
7
+ description: System-assigned key for the vendor.
8
+ readOnly: true
9
+ id:
10
+ type: string
11
+ description: |
12
+ Unique identifier of the vendor.
13
+ You must specify a unique vendor ID when creating a vendor unless document sequencing is configured, in which case the ID is auto-generated.
14
+ name:
15
+ type: string
16
+ description: Name of the vendor.
17
+ isOneTimeUse:
18
+ type: boolean
19
+ description: One-time use
20
+ default: false
package/lib/bundle.js CHANGED
@@ -49,7 +49,11 @@ function bundleDocument(opts) {
49
49
  const oasVersion = oas_types_1.detectOpenAPI(document.parsed);
50
50
  const oasMajorVersion = oas_types_1.openAPIMajor(oasVersion);
51
51
  const rules = config.getRulesForOasVersion(oasMajorVersion);
52
- const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3) ? (oasVersion === OasVersion.Version3_1 ? oas3_1_1.Oas3_1Types : oas3_1.Oas3Types) : oas2_1.Oas2Types, oasVersion), config);
52
+ const types = types_1.normalizeTypes(config.extendTypes((customTypes !== null && customTypes !== void 0 ? customTypes : oasMajorVersion === oas_types_1.OasMajorVersion.Version3)
53
+ ? oasVersion === OasVersion.Version3_1
54
+ ? oas3_1_1.Oas3_1Types
55
+ : oas3_1.Oas3Types
56
+ : oas2_1.Oas2Types, oasVersion), config);
53
57
  const preprocessors = rules_1.initRules(rules, config, 'preprocessors', oasVersion);
54
58
  const decorators = rules_1.initRules(rules, config, 'decorators', oasVersion);
55
59
  const ctx = {
@@ -210,6 +214,14 @@ function makeBundleVisitor(version, dereference, rootDocument) {
210
214
  return `#/${componentType}/${name}`;
211
215
  }
212
216
  }
217
+ function isEqualOrEqualRef(node, target, ctx) {
218
+ var _a;
219
+ if (ref_utils_1.isRef(node) &&
220
+ ((_a = ctx.resolve(node).location) === null || _a === void 0 ? void 0 : _a.absolutePointer) === target.location.absolutePointer) {
221
+ return true;
222
+ }
223
+ return isEqual(node, target.node);
224
+ }
213
225
  function getComponentName(target, componentType, ctx) {
214
226
  const [fileRef, pointer] = [target.location.source.absoluteRef, target.location.pointer];
215
227
  const componentsGroup = components[componentType];
@@ -219,17 +231,17 @@ function makeBundleVisitor(version, dereference, rootDocument) {
219
231
  name = refParts.pop() + (name ? `-${name}` : '');
220
232
  if (!componentsGroup ||
221
233
  !componentsGroup[name] ||
222
- isEqual(componentsGroup[name], target.node)) {
234
+ isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
223
235
  return name;
224
236
  }
225
237
  }
226
238
  name = ref_utils_1.refBaseName(fileRef) + (name ? `_${name}` : '');
227
- if (!componentsGroup[name] || isEqual(componentsGroup[name], target.node)) {
239
+ if (!componentsGroup[name] || isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
228
240
  return name;
229
241
  }
230
242
  const prevName = name;
231
243
  let serialId = 2;
232
- while (componentsGroup[name] && !isEqual(componentsGroup[name], target.node)) {
244
+ while (componentsGroup[name] && !isEqualOrEqualRef(componentsGroup[name], target, ctx)) {
233
245
  name = `${prevName}-${serialId}`;
234
246
  serialId++;
235
247
  }
package/lib/config/all.js CHANGED
@@ -12,11 +12,13 @@ exports.default = {
12
12
  'no-identical-paths': 'error',
13
13
  'no-ambiguous-paths': 'error',
14
14
  'no-path-trailing-slash': 'error',
15
+ 'path-segment-plural': 'error',
15
16
  'path-declaration-must-exist': 'error',
16
17
  'path-not-include-query': 'error',
17
18
  'path-parameters-defined': 'error',
18
19
  'operation-description': 'error',
19
20
  'operation-2xx-response': 'error',
21
+ 'operation-4xx-response': 'error',
20
22
  'operation-operationId': 'error',
21
23
  'operation-summary': 'error',
22
24
  'operation-operationId-unique': 'error',
@@ -29,6 +31,12 @@ exports.default = {
29
31
  'no-enum-type-mismatch': 'error',
30
32
  'boolean-parameter-prefixes': 'error',
31
33
  'paths-kebab-case': 'error',
34
+ 'no-http-verbs-in-paths': 'error',
35
+ 'path-excludes-patterns': {
36
+ severity: 'error',
37
+ patterns: [],
38
+ },
39
+ 'request-mime-type': 'error',
32
40
  spec: 'error',
33
41
  },
34
42
  oas3_0Rules: {
@@ -49,5 +57,5 @@ exports.default = {
49
57
  'no-unused-components': 'error',
50
58
  'no-undefined-server-variable': 'error',
51
59
  'no-servers-empty-enum': 'error',
52
- }
60
+ },
53
61
  };
@@ -73,7 +73,7 @@ class LintConfig {
73
73
  const ignoreFile = path.join(dir, exports.IGNORE_FILE);
74
74
  const mapped = {};
75
75
  for (const absFileName of Object.keys(this.ignore)) {
76
- const ignoredRules = (mapped[path.relative(dir, absFileName)] = this.ignore[absFileName]);
76
+ const ignoredRules = (mapped[utils_1.slash(path.relative(dir, absFileName))] = this.ignore[absFileName]);
77
77
  for (const ruleId of Object.keys(ignoredRules)) {
78
78
  ignoredRules[ruleId] = Array.from(ignoredRules[ruleId]);
79
79
  }
@@ -17,6 +17,7 @@ exports.default = {
17
17
  'path-parameters-defined': 'warn',
18
18
  'operation-description': 'off',
19
19
  'operation-2xx-response': 'warn',
20
+ 'operation-4xx-response': 'off',
20
21
  'operation-operationId': 'warn',
21
22
  'operation-summary': 'warn',
22
23
  'operation-operationId-unique': 'warn',
@@ -17,6 +17,7 @@ exports.default = {
17
17
  'path-parameters-defined': 'error',
18
18
  'operation-description': 'off',
19
19
  'operation-2xx-response': 'warn',
20
+ 'operation-4xx-response': 'warn',
20
21
  'operation-operationId': 'warn',
21
22
  'operation-summary': 'error',
22
23
  'operation-operationId-unique': 'error',
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { BundleOutputFormat, readFileFromUrl } from './utils';
1
+ export { BundleOutputFormat, readFileFromUrl, slash } from './utils';
2
2
  export { Oas3_1Types } from './types/oas3_1';
3
3
  export { Oas3Types } from './types/oas3';
4
4
  export { Oas2Types } from './types/oas2';
package/lib/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.RedoclyClient = exports.loadConfig = exports.IGNORE_FILE = exports.LintConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.readFileFromUrl = void 0;
3
+ exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.RedoclyClient = exports.loadConfig = exports.IGNORE_FILE = exports.LintConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.slash = exports.readFileFromUrl = void 0;
4
4
  var utils_1 = require("./utils");
5
5
  Object.defineProperty(exports, "readFileFromUrl", { enumerable: true, get: function () { return utils_1.readFileFromUrl; } });
6
+ Object.defineProperty(exports, "slash", { enumerable: true, get: function () { return utils_1.slash; } });
6
7
  var oas3_1_1 = require("./types/oas3_1");
7
8
  Object.defineProperty(exports, "Oas3_1Types", { enumerable: true, get: function () { return oas3_1_1.Oas3_1Types; } });
8
9
  var oas3_1 = require("./types/oas3");
package/lib/ref-utils.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isMappingRef = exports.isAbsoluteUrl = exports.refBaseName = exports.pointerBaseName = exports.parsePointer = exports.parseRef = exports.escapePointer = exports.unescapePointer = exports.Location = exports.isRef = exports.joinPointer = void 0;
4
- const path_1 = require("path");
5
4
  function joinPointer(base, key) {
6
5
  if (base === '')
7
6
  base = '#/';
@@ -56,7 +55,7 @@ function pointerBaseName(pointer) {
56
55
  }
57
56
  exports.pointerBaseName = pointerBaseName;
58
57
  function refBaseName(ref) {
59
- const parts = ref.split(path_1.sep);
58
+ const parts = ref.split(/[\/\\]/); // split by '\' and '/'
60
59
  return parts[parts.length - 1].split('.')[0];
61
60
  }
62
61
  exports.refBaseName = refBaseName;
@@ -7,8 +7,14 @@ export declare const preprocessors: {
7
7
  export declare const decorators: {
8
8
  oas3: {
9
9
  'registry-dependencies': import("../visitors").Oas3Decorator;
10
+ 'operation-description-override': import("../visitors").Oas3Decorator;
11
+ 'tag-description-override': import("../visitors").Oas3Decorator;
12
+ 'info-description-override': import("../visitors").Oas3Decorator;
10
13
  };
11
14
  oas2: {
12
15
  'registry-dependencies': import("../visitors").Oas2Decorator;
16
+ 'operation-description-override': import("../visitors").Oas2Decorator;
17
+ 'tag-description-override': import("../visitors").Oas2Decorator;
18
+ 'info-description-override': import("../visitors").Oas2Decorator;
13
19
  };
14
20
  };
@@ -0,0 +1,2 @@
1
+ import { Oas3Decorator, Oas2Decorator } from '../../visitors';
2
+ export declare const InfoDescriptionOverride: Oas3Decorator | Oas2Decorator;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InfoDescriptionOverride = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const InfoDescriptionOverride = ({ filePath }) => {
6
+ return {
7
+ Info: {
8
+ leave(info, { report, location }) {
9
+ if (!filePath)
10
+ throw new Error(`Parameter "filePath" is not provided for "info-description-override" rule`);
11
+ try {
12
+ info.description = utils_1.readFileAsStringSync(filePath);
13
+ }
14
+ catch (e) {
15
+ report({
16
+ message: `Failed to read markdown override file for "info.description".\n${e.message}`,
17
+ location: location.child('description'),
18
+ });
19
+ }
20
+ },
21
+ },
22
+ };
23
+ };
24
+ exports.InfoDescriptionOverride = InfoDescriptionOverride;
@@ -8,6 +8,7 @@ const InfoLicense = () => {
8
8
  if (!info.license) {
9
9
  report({
10
10
  message: utils_1.missingRequiredField('Info', 'license'),
11
+ location: { reportOnKey: true }
11
12
  });
12
13
  }
13
14
  },
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const NoHttpVerbsInPaths: Oas3Rule | Oas2Rule;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoHttpVerbsInPaths = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const httpMethods = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace'];
6
+ const NoHttpVerbsInPaths = ({ splitIntoWords }) => {
7
+ return {
8
+ PathItem(_path, { key, report, location }) {
9
+ const pathKey = key.toString();
10
+ if (!pathKey.startsWith('/'))
11
+ return;
12
+ const pathSegments = pathKey.split('/');
13
+ for (const pathSegment of pathSegments) {
14
+ if (!pathSegment || utils_1.isPathParameter(pathSegment))
15
+ continue;
16
+ const isHttpMethodIncluded = (method) => {
17
+ return splitIntoWords
18
+ ? utils_1.splitCamelCaseIntoWords(pathSegment).has(method)
19
+ : pathSegment.toLocaleLowerCase().includes(method);
20
+ };
21
+ for (const method of httpMethods) {
22
+ if (isHttpMethodIncluded(method)) {
23
+ report({
24
+ message: `path \`${pathKey}\` should not contain http verb ${method}`,
25
+ location: location.key(),
26
+ });
27
+ }
28
+ }
29
+ }
30
+ },
31
+ };
32
+ };
33
+ exports.NoHttpVerbsInPaths = NoHttpVerbsInPaths;
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const Operation4xxResponse: Oas3Rule | Oas2Rule;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Operation4xxResponse = void 0;
4
+ const Operation4xxResponse = () => {
5
+ return {
6
+ ResponsesMap(responses, { report }) {
7
+ const codes = Object.keys(responses);
8
+ if (!codes.some((code) => /4[Xx0-9]{2}/.test(code))) {
9
+ report({
10
+ message: 'Operation must have at least one `4xx` response.',
11
+ location: { reportOnKey: true },
12
+ });
13
+ }
14
+ },
15
+ };
16
+ };
17
+ exports.Operation4xxResponse = Operation4xxResponse;
@@ -0,0 +1,2 @@
1
+ import { Oas3Decorator, Oas2Decorator } from '../../visitors';
2
+ export declare const OperationDescriptionOverride: Oas3Decorator | Oas2Decorator;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OperationDescriptionOverride = void 0;
4
+ const utils_1 = require("../../utils");
5
+ const OperationDescriptionOverride = ({ operationIds }) => {
6
+ return {
7
+ Operation: {
8
+ leave(operation, { report, location }) {
9
+ if (!operation.operationId)
10
+ return;
11
+ if (!operationIds)
12
+ throw new Error(`Parameter "operationIds" is not provided for "operation-description-override" rule`);
13
+ const operationId = operation.operationId;
14
+ if (operationIds[operationId]) {
15
+ try {
16
+ operation.description = utils_1.readFileAsStringSync(operationIds[operationId]);
17
+ }
18
+ catch (e) {
19
+ report({
20
+ message: `Failed to read markdown override file for operation "${operationId}".\n${e.message}`,
21
+ location: location.child('operationId').key(),
22
+ });
23
+ }
24
+ }
25
+ },
26
+ },
27
+ };
28
+ };
29
+ exports.OperationDescriptionOverride = OperationDescriptionOverride;
@@ -0,0 +1,2 @@
1
+ import { Oas2Rule, Oas3Rule } from '../../visitors';
2
+ export declare const PathExcludesPatterns: Oas3Rule | Oas2Rule;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathExcludesPatterns = void 0;
4
+ const PathExcludesPatterns = ({ patterns }) => {
5
+ return {
6
+ PathItem(_path, { report, key, location }) {
7
+ if (!patterns)
8
+ throw new Error(`Parameter "patterns" is not provided for "path-excludes-patterns" rule`);
9
+ const pathKey = key.toString();
10
+ if (pathKey.startsWith('/')) {
11
+ const matches = patterns.filter((pattern) => pathKey.match(pattern));
12
+ for (const match of matches) {
13
+ report({
14
+ message: `path \`${pathKey}\` should not match regex pattern: \`${match}\``,
15
+ location: location.key(),
16
+ });
17
+ }
18
+ }
19
+ },
20
+ };
21
+ };
22
+ exports.PathExcludesPatterns = PathExcludesPatterns;
@@ -0,0 +1,2 @@
1
+ import { Oas3Rule, Oas2Rule } from '../../visitors';
2
+ export declare const PathSegmentPlural: Oas3Rule | Oas2Rule;