@redocly/openapi-core 1.0.0-beta.116 → 1.0.0-beta.118

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 (49) hide show
  1. package/lib/bundle.d.ts +1 -1
  2. package/lib/config/config-resolvers.js +13 -8
  3. package/lib/decorators/common/media-type-examples-override.d.ts +2 -0
  4. package/lib/decorators/common/media-type-examples-override.js +53 -0
  5. package/lib/decorators/oas3/index.d.ts +1 -0
  6. package/lib/decorators/oas3/index.js +2 -0
  7. package/lib/index.d.ts +2 -2
  8. package/lib/index.js +3 -1
  9. package/lib/resolve.js +3 -0
  10. package/lib/rules/common/assertions/asserts.js +10 -2
  11. package/lib/rules/common/assertions/utils.js +12 -6
  12. package/lib/rules/common/spec.js +7 -4
  13. package/lib/rules/oas3/spec-components-invalid-map-name.js +26 -5
  14. package/lib/types/index.d.ts +1 -0
  15. package/lib/types/index.js +7 -1
  16. package/lib/types/oas2.js +16 -11
  17. package/lib/types/oas3.js +28 -11
  18. package/lib/types/oas3_1.js +6 -0
  19. package/lib/types/redocly-yaml.js +1 -0
  20. package/lib/utils.d.ts +1 -0
  21. package/lib/utils.js +6 -1
  22. package/lib/visitors.d.ts +3 -1
  23. package/lib/visitors.js +4 -0
  24. package/lib/walk.js +8 -0
  25. package/package.json +1 -1
  26. package/src/__tests__/__snapshots__/bundle.test.ts.snap +10 -0
  27. package/src/config/config-resolvers.ts +12 -8
  28. package/src/decorators/__tests__/media-type-examples-override.test.ts +665 -0
  29. package/src/decorators/__tests__/resources/request.yaml +3 -0
  30. package/src/decorators/__tests__/resources/response.yaml +3 -0
  31. package/src/decorators/common/media-type-examples-override.ts +79 -0
  32. package/src/decorators/oas3/index.ts +2 -0
  33. package/src/index.ts +2 -1
  34. package/src/resolve.ts +4 -1
  35. package/src/rules/common/assertions/__tests__/asserts.test.ts +89 -19
  36. package/src/rules/common/assertions/asserts.ts +10 -1
  37. package/src/rules/common/assertions/utils.ts +15 -6
  38. package/src/rules/common/spec.ts +8 -5
  39. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +88 -0
  40. package/src/rules/oas3/spec-components-invalid-map-name.ts +26 -5
  41. package/src/types/index.ts +9 -0
  42. package/src/types/oas2.ts +16 -12
  43. package/src/types/oas3.ts +28 -12
  44. package/src/types/oas3_1.ts +6 -0
  45. package/src/types/redocly-yaml.ts +1 -0
  46. package/src/utils.ts +5 -0
  47. package/src/visitors.ts +7 -1
  48. package/src/walk.ts +15 -1
  49. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,79 @@
1
+ import { Oas3Decorator } from '../../visitors';
2
+ import { Oas3Operation, Oas3RequestBody, Oas3Response } from '../../typings/openapi';
3
+ import { yamlAndJsonSyncReader } from '../../utils';
4
+ import { isRef } from '../../ref-utils';
5
+ import { ResolveFn, UserContext } from '../../walk';
6
+
7
+ export const MediaTypeExamplesOverride: Oas3Decorator = ({ operationIds }) => {
8
+ return {
9
+ Operation: {
10
+ enter(operation: Oas3Operation, ctx: UserContext) {
11
+ const operationId = operation.operationId;
12
+
13
+ if (!operationId) {
14
+ return;
15
+ }
16
+
17
+ const properties = operationIds[operationId];
18
+
19
+ if (!properties) {
20
+ return;
21
+ }
22
+
23
+ if (properties.responses && operation.responses) {
24
+ for (const responseCode of Object.keys(properties.responses)) {
25
+ const resolvedResponse = checkAndResolveRef<Oas3Response>(
26
+ operation.responses[responseCode],
27
+ ctx.resolve
28
+ );
29
+
30
+ if (!resolvedResponse) {
31
+ continue;
32
+ }
33
+
34
+ resolvedResponse.content = resolvedResponse.content ? resolvedResponse.content : {};
35
+
36
+ Object.keys(properties.responses[responseCode]).forEach((mimeType) => {
37
+ resolvedResponse.content![mimeType] = {
38
+ ...resolvedResponse.content![mimeType],
39
+ examples: yamlAndJsonSyncReader(properties.responses[responseCode][mimeType]),
40
+ };
41
+ });
42
+
43
+ operation.responses[responseCode] = resolvedResponse;
44
+ }
45
+ }
46
+
47
+ if (properties.request && operation.requestBody) {
48
+ const resolvedRequest = checkAndResolveRef<Oas3RequestBody>(
49
+ operation.requestBody,
50
+ ctx.resolve
51
+ );
52
+
53
+ if (!resolvedRequest) {
54
+ return;
55
+ }
56
+
57
+ resolvedRequest.content = resolvedRequest.content ? resolvedRequest.content : {};
58
+
59
+ Object.keys(properties.request).forEach((mimeType) => {
60
+ resolvedRequest.content[mimeType] = {
61
+ ...resolvedRequest.content[mimeType],
62
+ examples: yamlAndJsonSyncReader(properties.request[mimeType]),
63
+ };
64
+ });
65
+ operation.requestBody = resolvedRequest;
66
+ }
67
+ },
68
+ },
69
+ };
70
+ };
71
+
72
+ function checkAndResolveRef<T>(node: any, resolver: ResolveFn): T | undefined {
73
+ if (!isRef(node)) {
74
+ return node;
75
+ }
76
+
77
+ const resolved = resolver<T>(node);
78
+ return resolved.error ? undefined : JSON.parse(JSON.stringify(resolved.node));
79
+ }
@@ -6,6 +6,7 @@ import { InfoDescriptionOverride } from '../common/info-description-override';
6
6
  import { RemoveXInternal } from '../common/remove-x-internal';
7
7
  import { FilterIn } from '../common/filters/filter-in';
8
8
  import { FilterOut } from '../common/filters/filter-out';
9
+ import { MediaTypeExamplesOverride } from '../common/media-type-examples-override';
9
10
 
10
11
  export const decorators = {
11
12
  'registry-dependencies': RegistryDependencies as Oas3Decorator,
@@ -15,4 +16,5 @@ export const decorators = {
15
16
  'remove-x-internal': RemoveXInternal as Oas3Decorator,
16
17
  'filter-in': FilterIn as Oas3Decorator,
17
18
  'filter-out': FilterOut as Oas3Decorator,
19
+ 'media-type-examples-override': MediaTypeExamplesOverride as Oas3Decorator,
18
20
  };
package/src/index.ts CHANGED
@@ -36,6 +36,7 @@ export {
36
36
  CONFIG_FILE_NAMES,
37
37
  RuleSeverity,
38
38
  createConfig,
39
+ ResolvedApi,
39
40
  } from './config';
40
41
 
41
42
  export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
@@ -50,7 +51,7 @@ export {
50
51
  makeDocumentFromString,
51
52
  } from './resolve';
52
53
  export { parseYaml, stringifyYaml } from './js-yaml';
53
- export { unescapePointer, isRef } from './ref-utils';
54
+ export { unescapePointer, isRef, isAbsoluteUrl } from './ref-utils';
54
55
  export { detectOpenAPI, OasMajorVersion, openAPIMajor, OasVersion } from './oas-types';
55
56
  export { normalizeVisitors } from './visitors';
56
57
 
package/src/resolve.ts CHANGED
@@ -3,7 +3,7 @@ import * as path from 'path';
3
3
  import { OasRef } from './typings/openapi';
4
4
  import { isRef, joinPointer, escapePointer, parseRef, isAbsoluteUrl, isAnchor } from './ref-utils';
5
5
  import type { YAMLNode, LoadOptions } from 'yaml-ast-parser';
6
- import { NormalizedNodeType, isNamedType } from './types';
6
+ import { NormalizedNodeType, isNamedType, SpecExtension } from './types';
7
7
  import { readFileFromUrl, parseYaml, nextTick } from './utils';
8
8
  import { ResolveConfig } from './config/types';
9
9
 
@@ -276,6 +276,9 @@ export async function resolveDocument(opts: {
276
276
  if (propType === undefined) propType = type.additionalProperties;
277
277
  if (typeof propType === 'function') propType = propType(propValue, propName);
278
278
  if (propType === undefined) propType = unknownType;
279
+ if (type.extensionsPrefix && propName.startsWith(type.extensionsPrefix)) {
280
+ propType = SpecExtension;
281
+ }
279
282
 
280
283
  if (!isNamedType(propType) && propType?.directResolveAs) {
281
284
  propType = propType.directResolveAs;
@@ -549,21 +549,25 @@ describe('oas3 assertions', () => {
549
549
  });
550
550
  });
551
551
 
552
- describe.skip('sortOrder', () => {
552
+ describe('sortOrder', () => {
553
553
  it('value should be ordered in ASC direction', () => {
554
554
  expect(asserts.sortOrder(['example', 'foo', 'test'], 'asc', baseLocation)).toEqual([]);
555
555
  expect(
556
556
  asserts.sortOrder(['example', 'foo', 'test'], { direction: 'asc' }, baseLocation)
557
557
  ).toEqual([]);
558
558
  expect(asserts.sortOrder(['example'], 'asc', baseLocation)).toEqual([]);
559
- expect(asserts.sortOrder(['example', 'test', 'foo'], 'asc', baseLocation)).toEqual({
560
- isValid: false,
561
- location: baseLocation,
562
- });
563
- expect(asserts.sortOrder(['example', 'foo', 'test'], 'desc', baseLocation)).toEqual({
564
- isValid: false,
565
- location: baseLocation,
566
- });
559
+ expect(asserts.sortOrder(['example', 'test', 'foo'], 'asc', baseLocation)).toEqual([
560
+ {
561
+ message: 'Should be sorted in an ascending order',
562
+ location: baseLocation,
563
+ },
564
+ ]);
565
+ expect(asserts.sortOrder(['example', 'foo', 'test'], 'desc', baseLocation)).toEqual([
566
+ {
567
+ message: 'Should be sorted in a descending order',
568
+ location: baseLocation,
569
+ },
570
+ ]);
567
571
  expect(
568
572
  asserts.sortOrder(
569
573
  [{ name: 'bar' }, { name: 'baz' }, { name: 'foo' }],
@@ -577,7 +581,12 @@ describe('oas3 assertions', () => {
577
581
  { direction: 'desc', property: 'name' },
578
582
  baseLocation
579
583
  )
580
- ).toEqual({ isValid: false, location: baseLocation });
584
+ ).toEqual([
585
+ {
586
+ message: 'Should be sorted in a descending order by property name',
587
+ location: baseLocation,
588
+ },
589
+ ]);
581
590
  });
582
591
  it('value should be ordered in DESC direction', () => {
583
592
  expect(asserts.sortOrder(['test', 'foo', 'example'], 'desc', baseLocation)).toEqual([]);
@@ -585,14 +594,18 @@ describe('oas3 assertions', () => {
585
594
  asserts.sortOrder(['test', 'foo', 'example'], { direction: 'desc' }, baseLocation)
586
595
  ).toEqual([]);
587
596
  expect(asserts.sortOrder(['example'], 'desc', baseLocation)).toEqual([]);
588
- expect(asserts.sortOrder(['example', 'test', 'foo'], 'desc', baseLocation)).toEqual({
589
- isValid: false,
590
- location: baseLocation,
591
- });
592
- expect(asserts.sortOrder(['test', 'foo', 'example'], 'asc', baseLocation)).toEqual({
593
- isValid: false,
594
- location: baseLocation,
595
- });
597
+ expect(asserts.sortOrder(['example', 'test', 'foo'], 'desc', baseLocation)).toEqual([
598
+ {
599
+ message: 'Should be sorted in a descending order',
600
+ location: baseLocation,
601
+ },
602
+ ]);
603
+ expect(asserts.sortOrder(['test', 'foo', 'example'], 'asc', baseLocation)).toEqual([
604
+ {
605
+ message: 'Should be sorted in an ascending order',
606
+ location: baseLocation,
607
+ },
608
+ ]);
596
609
  expect(
597
610
  asserts.sortOrder(
598
611
  [{ name: 'foo' }, { name: 'baz' }, { name: 'bar' }],
@@ -606,7 +619,64 @@ describe('oas3 assertions', () => {
606
619
  { direction: 'asc', property: 'name' },
607
620
  baseLocation
608
621
  )
609
- ).toEqual({ isValid: false, location: baseLocation });
622
+ ).toEqual([
623
+ {
624
+ message: 'Should be sorted in an ascending order by property name',
625
+ location: baseLocation,
626
+ },
627
+ ]);
628
+ });
629
+ it('should not order objects without property defined', () => {
630
+ expect(
631
+ asserts.sortOrder(
632
+ [
633
+ { name: 'bar', id: 1 },
634
+ { name: 'baz', id: 2 },
635
+ { name: 'foo', id: 3 },
636
+ ],
637
+ { direction: 'desc' },
638
+ baseLocation
639
+ )
640
+ ).toEqual([
641
+ {
642
+ message: 'Please define a property to sort objects by',
643
+ location: baseLocation,
644
+ },
645
+ ]);
646
+ expect(
647
+ asserts.sortOrder(
648
+ [
649
+ { name: 'bar', id: 1 },
650
+ { name: 'baz', id: 2 },
651
+ { name: 'foo', id: 3 },
652
+ ],
653
+ { direction: 'asc' },
654
+ baseLocation
655
+ )
656
+ ).toEqual([
657
+ {
658
+ message: 'Please define a property to sort objects by',
659
+ location: baseLocation,
660
+ },
661
+ ]);
662
+ });
663
+ it('should ignore string value casing while ordering', () => {
664
+ expect(asserts.sortOrder(['Example', 'foo', 'Test'], 'asc', baseLocation)).toEqual([]);
665
+ expect(asserts.sortOrder(['Test', 'foo', 'Example'], 'desc', baseLocation)).toEqual([]);
666
+ expect(
667
+ asserts.sortOrder(
668
+ [{ name: 'bar' }, { name: 'Baz' }, { name: 'Foo' }],
669
+ { direction: 'asc', property: 'name' },
670
+ baseLocation
671
+ )
672
+ ).toEqual([]);
673
+ expect(
674
+ asserts.sortOrder(
675
+ [{ name: 'Foo' }, { name: 'baz' }, { name: 'Bar' }],
676
+ { direction: 'desc', property: 'name' },
677
+ baseLocation
678
+ )
679
+ ).toEqual([]);
610
680
  });
611
681
  });
612
682
 
@@ -239,9 +239,18 @@ export const asserts: Asserts = {
239
239
  condition: OrderOptions | OrderDirection,
240
240
  baseLocation: Location
241
241
  ) => {
242
- if (typeof value === 'undefined' || isOrdered(value, condition)) return [];
243
242
  const direction = (condition as OrderOptions).direction || (condition as OrderDirection);
244
243
  const property = (condition as OrderOptions).property;
244
+ if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'object' && !property) {
245
+ return [
246
+ {
247
+ message: `Please define a property to sort objects by`,
248
+ location: baseLocation,
249
+ },
250
+ ];
251
+ }
252
+ if (typeof value === 'undefined' || isOrdered(value, condition)) return [];
253
+
245
254
  return [
246
255
  {
247
256
  message: `Should be sorted in ${
@@ -118,11 +118,11 @@ function applyAssertions(
118
118
  );
119
119
  }
120
120
  } else {
121
- const value = assert.name === 'ref' ? rawNode : Object.keys(node);
121
+ const value = Array.isArray(node) ? node : Object.keys(node);
122
122
  assertResults.push(
123
123
  runAssertion({
124
- values: Object.keys(node),
125
- rawValues: value,
124
+ values: value,
125
+ rawValues: rawNode,
126
126
  assert,
127
127
  location: currentLocation,
128
128
  })
@@ -288,11 +288,20 @@ export function isOrdered(value: any[], options: OrderOptions | OrderDirection):
288
288
  let prevVal = value[i - 1];
289
289
 
290
290
  if (property) {
291
- if (!value[i][property] || !value[i - 1][property]) {
291
+ const currPropValue = value[i][property];
292
+ const prevPropValue = value[i - 1][property];
293
+
294
+ if (!currPropValue || !prevPropValue) {
292
295
  return false; // property doesn't exist, so collection is not ordered
293
296
  }
294
- currValue = value[i][property];
295
- prevVal = value[i - 1][property];
297
+
298
+ currValue = currPropValue;
299
+ prevVal = prevPropValue;
300
+ }
301
+
302
+ if (typeof currValue === 'string' && typeof prevVal === 'string') {
303
+ currValue = currValue.toLowerCase();
304
+ prevVal = prevVal.toLowerCase();
296
305
  }
297
306
 
298
307
  const result = direction === 'asc' ? currValue >= prevVal : currValue <= prevVal;
@@ -1,5 +1,5 @@
1
1
  import type { Oas3Rule, Oas2Rule } from '../../visitors';
2
- import { isNamedType } from '../../types';
2
+ import { isNamedType, SpecExtension } from '../../types';
3
3
  import { oasTypeOf, matchesJsonSchemaType, getSuggest, validateSchemaEnumType } from '../utils';
4
4
  import { isRef } from '../../ref-utils';
5
5
  import { isPlainObject } from '../../utils';
@@ -24,10 +24,13 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
24
24
  }
25
25
  return;
26
26
  } else if (nodeType !== 'object') {
27
- report({
28
- message: `Expected type \`${type.name}\` (object) but got \`${nodeType}\``,
29
- from: refLocation,
30
- });
27
+ if (type !== SpecExtension) {
28
+ // do not validate unknown extensions structure
29
+ report({
30
+ message: `Expected type \`${type.name}\` (object) but got \`${nodeType}\``,
31
+ from: refLocation,
32
+ });
33
+ }
31
34
  ignoreNextVisitorsOnNode();
32
35
  return;
33
36
  }
@@ -214,4 +214,92 @@ describe('Oas3 spec-components-invalid-map-name', () => {
214
214
 
215
215
  expect(results).toMatchInlineSnapshot(`Array []`);
216
216
  });
217
+
218
+ it('should report about invalid keys inside nested examples', async () => {
219
+ const document = parseYamlToDocument(outdent`
220
+ openapi: 3.0.0
221
+ info:
222
+ version: 3.0.0
223
+ components:
224
+ parameters:
225
+ my Param:
226
+ name: param
227
+ description: param
228
+ in: path
229
+ examples:
230
+ invalid identifier:
231
+ description: 'Some description'
232
+ value: 21
233
+ `);
234
+ const results = await lintDocument({
235
+ externalRefResolver: new BaseResolver(),
236
+ document,
237
+ config: await makeConfig({
238
+ 'spec-components-invalid-map-name': 'error',
239
+ }),
240
+ });
241
+
242
+ expect(results).toMatchInlineSnapshot(`
243
+ Array [
244
+ Object {
245
+ "location": Array [
246
+ Object {
247
+ "pointer": "#/components/parameters/my Param",
248
+ "reportOnKey": true,
249
+ "source": Source {
250
+ "absoluteRef": "",
251
+ "body": "openapi: 3.0.0
252
+ info:
253
+ version: 3.0.0
254
+ components:
255
+ parameters:
256
+ my Param:
257
+ name: param
258
+ description: param
259
+ in: path
260
+ examples:
261
+ invalid identifier:
262
+ description: 'Some description'
263
+ value: 21 ",
264
+ "mimeType": undefined,
265
+ },
266
+ },
267
+ ],
268
+ "message": "The map key in parameters \\"my Param\\" does not match the regular expression \\"^[a-zA-Z0-9\\\\.\\\\-_]+$\\"",
269
+ "ruleId": "spec-components-invalid-map-name",
270
+ "severity": "error",
271
+ "suggest": Array [],
272
+ },
273
+ Object {
274
+ "location": Array [
275
+ Object {
276
+ "pointer": "#/components/parameters/my Param/examples/invalid identifier",
277
+ "reportOnKey": true,
278
+ "source": Source {
279
+ "absoluteRef": "",
280
+ "body": "openapi: 3.0.0
281
+ info:
282
+ version: 3.0.0
283
+ components:
284
+ parameters:
285
+ my Param:
286
+ name: param
287
+ description: param
288
+ in: path
289
+ examples:
290
+ invalid identifier:
291
+ description: 'Some description'
292
+ value: 21 ",
293
+ "mimeType": undefined,
294
+ },
295
+ },
296
+ ],
297
+ "message": "The map key in examples \\"invalid identifier\\" does not match the regular expression \\"^[a-zA-Z0-9\\\\.\\\\-_]+$\\"",
298
+ "ruleId": "spec-components-invalid-map-name",
299
+ "severity": "error",
300
+ "suggest": Array [],
301
+ },
302
+ ]
303
+ `);
304
+ });
217
305
  });
@@ -20,34 +20,55 @@ export const SpecComponentsInvalidMapName: Oas3Rule = () => {
20
20
  }
21
21
 
22
22
  return {
23
- Components: {
23
+ NamedSchemas: {
24
+ Schema(_node, { key, report, location }: UserContext) {
25
+ validateKey(key, report, location, 'schemas');
26
+ },
27
+ },
28
+ NamedParameters: {
24
29
  Parameter(_node, { key, report, location }: UserContext) {
25
30
  validateKey(key, report, location, 'parameters');
26
31
  },
32
+ },
33
+ NamedResponses: {
27
34
  Response(_node, { key, report, location }: UserContext) {
28
35
  validateKey(key, report, location, 'responses');
29
36
  },
30
- Schema(_node, { key, report, location }: UserContext) {
31
- validateKey(key, report, location, 'schemas');
32
- },
37
+ },
38
+ NamedExamples: {
33
39
  Example(_node, { key, report, location }: UserContext) {
34
40
  validateKey(key, report, location, 'examples');
35
41
  },
42
+ },
43
+ NamedRequestBodies: {
36
44
  RequestBody(_node, { key, report, location }: UserContext) {
37
45
  validateKey(key, report, location, 'requestBodies');
38
46
  },
47
+ },
48
+ NamedHeaders: {
39
49
  Header(_node, { key, report, location }: UserContext) {
40
50
  validateKey(key, report, location, 'headers');
41
51
  },
52
+ },
53
+ NamedSecuritySchemes: {
42
54
  SecurityScheme(_node, { key, report, location }: UserContext) {
43
- validateKey(key, report, location, 'securitySchemas');
55
+ validateKey(key, report, location, 'securitySchemes');
44
56
  },
57
+ },
58
+ NamedLinks: {
45
59
  Link(_node, { key, report, location }: UserContext) {
46
60
  validateKey(key, report, location, 'links');
47
61
  },
62
+ },
63
+ NamedCallbacks: {
48
64
  Callback(_node, { key, report, location }: UserContext) {
49
65
  validateKey(key, report, location, 'callbacks');
50
66
  },
51
67
  },
68
+ ExampleMap: {
69
+ Example(_node, { key, report, location }: UserContext) {
70
+ validateKey(key, report, location, 'examples');
71
+ },
72
+ },
52
73
  };
53
74
  };
@@ -63,6 +63,11 @@ export function mapOf(typeName: string) {
63
63
  };
64
64
  }
65
65
 
66
+ export const SpecExtension: NormalizedNodeType = {
67
+ name: 'SpecExtension',
68
+ properties: {},
69
+ };
70
+
66
71
  export function normalizeTypes(
67
72
  types: Record<string, NodeType>,
68
73
  options: { doNotResolveExamples?: boolean } = {}
@@ -79,6 +84,10 @@ export function normalizeTypes(
79
84
  for (const type of Object.values(normalizedTypes)) {
80
85
  normalizeType(type);
81
86
  }
87
+
88
+ // all type trees have a SpecExtension type by default
89
+ normalizedTypes['SpecExtension'] = SpecExtension;
90
+
82
91
  return normalizedTypes;
83
92
 
84
93
  function normalizeType(type: NormalizedNodeType) {
package/src/types/oas2.ts CHANGED
@@ -24,6 +24,7 @@ const Root: NodeType = {
24
24
  'x-ignoredHeaderParameters': { type: 'array', items: { type: 'string' } },
25
25
  },
26
26
  required: ['swagger', 'paths', 'info'],
27
+ extensionsPrefix: 'x-',
27
28
  };
28
29
 
29
30
  const Info: NodeType = {
@@ -37,6 +38,7 @@ const Info: NodeType = {
37
38
  'x-logo': 'Logo',
38
39
  },
39
40
  required: ['title', 'version'],
41
+ extensionsPrefix: 'x-',
40
42
  };
41
43
 
42
44
  const Logo: NodeType = {
@@ -46,6 +48,7 @@ const Logo: NodeType = {
46
48
  backgroundColor: { type: 'string' },
47
49
  href: { type: 'string' },
48
50
  },
51
+ extensionsPrefix: 'x-',
49
52
  };
50
53
 
51
54
  const Contact: NodeType = {
@@ -54,6 +57,7 @@ const Contact: NodeType = {
54
57
  url: { type: 'string' },
55
58
  email: { type: 'string' },
56
59
  },
60
+ extensionsPrefix: 'x-',
57
61
  };
58
62
 
59
63
  const License: NodeType = {
@@ -62,6 +66,7 @@ const License: NodeType = {
62
66
  url: { type: 'string' },
63
67
  },
64
68
  required: ['name'],
69
+ extensionsPrefix: 'x-',
65
70
  };
66
71
 
67
72
  const Paths: NodeType = {
@@ -83,6 +88,7 @@ const PathItem: NodeType = {
83
88
  head: 'Operation',
84
89
  patch: 'Operation',
85
90
  },
91
+ extensionsPrefix: 'x-',
86
92
  };
87
93
 
88
94
  const Operation: NodeType = {
@@ -102,9 +108,9 @@ const Operation: NodeType = {
102
108
  'x-codeSamples': 'XCodeSampleList',
103
109
  'x-code-samples': 'XCodeSampleList', // deprecated
104
110
  'x-hideTryItPanel': { type: 'boolean' },
105
- 'x-meta': 'XMetaList',
106
111
  },
107
112
  required: ['responses'],
113
+ extensionsPrefix: 'x-',
108
114
  };
109
115
 
110
116
  const XCodeSample: NodeType = {
@@ -129,6 +135,7 @@ const ExternalDocs: NodeType = {
129
135
  url: { type: 'string' },
130
136
  },
131
137
  required: ['url'],
138
+ extensionsPrefix: 'x-',
132
139
  };
133
140
 
134
141
  const Parameter: NodeType = {
@@ -173,6 +180,7 @@ const Parameter: NodeType = {
173
180
  }
174
181
  }
175
182
  },
183
+ extensionsPrefix: 'x-',
176
184
  };
177
185
 
178
186
  const ParameterItems: NodeType = {
@@ -202,6 +210,7 @@ const ParameterItems: NodeType = {
202
210
  return ['type'];
203
211
  }
204
212
  },
213
+ extensionsPrefix: 'x-',
205
214
  };
206
215
 
207
216
  const Responses: NodeType = {
@@ -221,6 +230,7 @@ const Response: NodeType = {
221
230
  'x-summary': { type: 'string' },
222
231
  },
223
232
  required: ['description'],
233
+ extensionsPrefix: 'x-',
224
234
  };
225
235
 
226
236
  const Examples: NodeType = {
@@ -256,6 +266,7 @@ const Header: NodeType = {
256
266
  return ['type'];
257
267
  }
258
268
  },
269
+ extensionsPrefix: 'x-',
259
270
  };
260
271
 
261
272
  const Tag: NodeType = {
@@ -267,6 +278,7 @@ const Tag: NodeType = {
267
278
  'x-displayName': { type: 'string' },
268
279
  },
269
280
  required: ['name'],
281
+ extensionsPrefix: 'x-',
270
282
  };
271
283
 
272
284
  const TagGroup: NodeType = {
@@ -329,6 +341,7 @@ const Schema: NodeType = {
329
341
  'x-explicitMappingOnly': { type: 'boolean' },
330
342
  'x-enumDescriptions': 'EnumDescriptions',
331
343
  },
344
+ extensionsPrefix: 'x-',
332
345
  };
333
346
 
334
347
  const EnumDescriptions: NodeType = {
@@ -349,6 +362,7 @@ const Xml: NodeType = {
349
362
  attribute: { type: 'boolean' },
350
363
  wrapped: { type: 'boolean' },
351
364
  },
365
+ extensionsPrefix: 'x-',
352
366
  };
353
367
 
354
368
  const SecurityScheme: NodeType = {
@@ -420,15 +434,7 @@ const Example: NodeType = {
420
434
  description: { type: 'string' },
421
435
  externalValue: { type: 'string' },
422
436
  },
423
- };
424
-
425
- const XMeta: NodeType = {
426
- properties: {
427
- title: { type: 'string' },
428
- description: { type: 'string' },
429
- keywords: { type: 'string' },
430
- image: { type: 'string' },
431
- },
437
+ extensionsPrefix: 'x-',
432
438
  };
433
439
 
434
440
  export const Oas2Types: Record<string, NodeType> = {
@@ -467,8 +473,6 @@ export const Oas2Types: Record<string, NodeType> = {
467
473
  SecurityScheme,
468
474
  XCodeSample,
469
475
  XCodeSampleList: listOf('XCodeSample'),
470
- XMeta,
471
- XMetaList: listOf('XMeta'),
472
476
  XServerList: listOf('XServer'),
473
477
  XServer,
474
478
  };