@redocly/openapi-core 1.18.0 → 1.19.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 (151) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/lib/benchmark/benches/lint-with-many-rules.bench.js +2 -2
  3. package/lib/benchmark/benches/lint-with-nested-rule.bench.js +2 -2
  4. package/lib/benchmark/benches/lint-with-no-rules.bench.js +2 -2
  5. package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +2 -2
  6. package/lib/benchmark/benches/lint-with-top-level-rule.bench.js +2 -2
  7. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -2
  8. package/lib/benchmark/benches/resolve-with-no-external.bench.js +2 -2
  9. package/lib/benchmark/utils.js +7 -4
  10. package/lib/bundle.d.ts +3 -3
  11. package/lib/bundle.js +128 -122
  12. package/lib/config/all.js +9 -0
  13. package/lib/config/builtIn.js +7 -1
  14. package/lib/config/config-resolvers.js +179 -138
  15. package/lib/config/config.d.ts +2 -2
  16. package/lib/config/config.js +53 -34
  17. package/lib/config/load.d.ts +1 -2
  18. package/lib/config/load.js +105 -117
  19. package/lib/config/minimal.js +9 -0
  20. package/lib/config/recommended-strict.js +9 -0
  21. package/lib/config/recommended.js +9 -0
  22. package/lib/config/rules.d.ts +3 -3
  23. package/lib/config/rules.js +1 -2
  24. package/lib/config/types.d.ts +9 -3
  25. package/lib/config/utils.js +70 -49
  26. package/lib/decorators/async3/index.d.ts +1 -0
  27. package/lib/decorators/async3/index.js +4 -0
  28. package/lib/decorators/common/filters/filter-helper.js +2 -3
  29. package/lib/decorators/common/filters/filter-in.js +1 -1
  30. package/lib/decorators/common/filters/filter-out.js +1 -1
  31. package/lib/decorators/common/info-override.js +1 -12
  32. package/lib/decorators/common/media-type-examples-override.js +8 -2
  33. package/lib/decorators/common/remove-x-internal.js +4 -5
  34. package/lib/decorators/oas2/remove-unused-components.js +1 -2
  35. package/lib/decorators/oas3/remove-unused-components.js +1 -2
  36. package/lib/env.d.ts +0 -1
  37. package/lib/env.js +1 -1
  38. package/lib/format/codeframes.js +10 -8
  39. package/lib/format/format.js +23 -15
  40. package/lib/index.d.ts +2 -1
  41. package/lib/index.js +6 -4
  42. package/lib/js-yaml/index.js +1 -1
  43. package/lib/lint.d.ts +2 -0
  44. package/lib/lint.js +92 -99
  45. package/lib/oas-types.d.ts +9 -5
  46. package/lib/oas-types.js +22 -12
  47. package/lib/redocly/domains.js +6 -6
  48. package/lib/redocly/index.js +60 -73
  49. package/lib/redocly/registry-api.js +64 -82
  50. package/lib/ref-utils.js +13 -13
  51. package/lib/resolve.js +186 -205
  52. package/lib/rules/ajv.js +10 -8
  53. package/lib/rules/async3/channels-kebab-case.d.ts +2 -0
  54. package/lib/rules/async3/channels-kebab-case.js +19 -0
  55. package/lib/rules/async3/index.d.ts +3 -0
  56. package/lib/rules/async3/index.js +22 -0
  57. package/lib/rules/async3/no-channel-trailing-slash.d.ts +2 -0
  58. package/lib/rules/async3/no-channel-trailing-slash.js +16 -0
  59. package/lib/rules/common/assertions/asserts.js +5 -5
  60. package/lib/rules/common/assertions/index.d.ts +5 -4
  61. package/lib/rules/common/assertions/utils.js +43 -28
  62. package/lib/rules/common/no-invalid-parameter-examples.js +1 -2
  63. package/lib/rules/common/no-invalid-schema-examples.js +1 -2
  64. package/lib/rules/common/no-required-schema-properties-undefined.js +1 -2
  65. package/lib/rules/common/operation-tag-defined.js +1 -2
  66. package/lib/rules/common/path-http-verbs-order.js +1 -1
  67. package/lib/rules/common/path-segment-plural.js +2 -1
  68. package/lib/rules/common/required-string-property-missing-min-length.js +2 -2
  69. package/lib/rules/common/response-contains-header.js +2 -2
  70. package/lib/rules/common/security-defined.js +3 -7
  71. package/lib/rules/common/spec.d.ts +2 -2
  72. package/lib/rules/common/spec.js +6 -7
  73. package/lib/rules/no-unresolved-refs.js +3 -4
  74. package/lib/rules/oas2/response-contains-property.js +1 -2
  75. package/lib/rules/oas3/array-parameter-serialization.js +1 -2
  76. package/lib/rules/oas3/component-name-unique.js +2 -4
  77. package/lib/rules/oas3/no-invalid-media-type-examples.js +1 -2
  78. package/lib/rules/oas3/no-server-variables-empty-enum.js +1 -2
  79. package/lib/rules/oas3/no-undefined-server-variable.js +2 -3
  80. package/lib/rules/oas3/no-unused-components.js +1 -2
  81. package/lib/rules/oas3/response-contains-property.js +1 -2
  82. package/lib/rules/utils.js +14 -12
  83. package/lib/types/arazzo.d.ts +1299 -73
  84. package/lib/types/arazzo.js +41 -36
  85. package/lib/types/asyncapi2.d.ts +17 -0
  86. package/lib/types/{asyncapi.js → asyncapi2.js} +71 -93
  87. package/lib/types/asyncapi3.d.ts +2 -0
  88. package/lib/types/asyncapi3.js +347 -0
  89. package/lib/types/index.js +19 -10
  90. package/lib/types/json-schema-adapter.js +4 -18
  91. package/lib/types/oas2.js +6 -6
  92. package/lib/types/oas3.js +10 -10
  93. package/lib/types/oas3_1.js +15 -9
  94. package/lib/types/redocly-yaml.d.ts +3 -1
  95. package/lib/types/redocly-yaml.js +131 -35
  96. package/lib/typings/arazzo.d.ts +28 -1
  97. package/lib/typings/asyncapi3.d.ts +53 -0
  98. package/lib/typings/asyncapi3.js +2 -0
  99. package/lib/utils.d.ts +12 -7
  100. package/lib/utils.js +91 -77
  101. package/lib/visitors.d.ts +11 -0
  102. package/lib/visitors.js +21 -8
  103. package/lib/walk.js +30 -23
  104. package/package.json +3 -3
  105. package/src/__tests__/bundle.test.ts +142 -0
  106. package/src/__tests__/lint.test.ts +0 -50
  107. package/src/bundle.ts +19 -6
  108. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +22 -0
  109. package/src/config/__tests__/__snapshots__/config.test.ts.snap +24 -0
  110. package/src/config/__tests__/config.test.ts +11 -0
  111. package/src/config/all.ts +9 -0
  112. package/src/config/builtIn.ts +6 -0
  113. package/src/config/config-resolvers.ts +15 -2
  114. package/src/config/config.ts +24 -5
  115. package/src/config/load.ts +1 -2
  116. package/src/config/minimal.ts +9 -0
  117. package/src/config/recommended-strict.ts +9 -0
  118. package/src/config/recommended.ts +9 -0
  119. package/src/config/rules.ts +12 -4
  120. package/src/config/types.ts +15 -2
  121. package/src/config/utils.ts +15 -0
  122. package/src/decorators/async3/index.ts +1 -0
  123. package/src/decorators/common/remove-x-internal.ts +2 -2
  124. package/src/index.ts +2 -1
  125. package/src/lint.ts +26 -3
  126. package/src/oas-types.ts +31 -13
  127. package/src/rules/arazzo/index.ts +1 -1
  128. package/src/rules/async2/index.ts +5 -5
  129. package/src/rules/async3/__tests__/channels-kebab-case.test.ts +141 -0
  130. package/src/rules/async3/__tests__/no-channel-trailing-slash.test.ts +96 -0
  131. package/src/rules/async3/channels-kebab-case.ts +19 -0
  132. package/src/rules/async3/index.ts +23 -0
  133. package/src/rules/async3/no-channel-trailing-slash.ts +16 -0
  134. package/src/rules/common/__tests__/spec.test.ts +47 -0
  135. package/src/rules/common/assertions/index.ts +13 -4
  136. package/src/rules/common/no-invalid-schema-examples.ts +3 -2
  137. package/src/rules/common/path-segment-plural.ts +3 -2
  138. package/src/rules/common/spec.ts +2 -2
  139. package/src/rules/oas2/index.ts +4 -4
  140. package/src/rules/oas3/index.ts +39 -37
  141. package/src/types/arazzo.ts +28 -23
  142. package/src/types/{asyncapi.ts → asyncapi2.ts} +58 -76
  143. package/src/types/asyncapi3.ts +381 -0
  144. package/src/types/oas3_1.ts +3 -2
  145. package/src/types/redocly-yaml.ts +14 -0
  146. package/src/typings/arazzo.ts +41 -1
  147. package/src/typings/asyncapi3.ts +61 -0
  148. package/src/utils.ts +46 -11
  149. package/src/visitors.ts +18 -0
  150. package/tsconfig.tsbuildinfo +1 -1
  151. package/lib/types/asyncapi.d.ts +0 -2
@@ -61,7 +61,7 @@ const ChannelBindings: NodeType = {
61
61
  additionalProperties: { type: 'object' },
62
62
  };
63
63
 
64
- const Tag: NodeType = {
64
+ export const Tag: NodeType = {
65
65
  properties: {
66
66
  name: { type: 'string' },
67
67
  description: { type: 'string' },
@@ -70,7 +70,7 @@ const Tag: NodeType = {
70
70
  required: ['name'],
71
71
  };
72
72
 
73
- const ExternalDocs: NodeType = {
73
+ export const ExternalDocs: NodeType = {
74
74
  properties: {
75
75
  description: { type: 'string' },
76
76
  url: { type: 'string' },
@@ -126,13 +126,13 @@ const Server: NodeType = {
126
126
  required: ['url', 'protocol'],
127
127
  };
128
128
 
129
- const ServerMap: NodeType = {
129
+ export const ServerMap: NodeType = {
130
130
  properties: {},
131
131
  additionalProperties: (_value: any, key: string) =>
132
132
  key.match(/^[A-Za-z0-9_\-]+$/) ? 'Server' : undefined,
133
133
  };
134
134
 
135
- const ServerVariable: NodeType = {
135
+ export const ServerVariable: NodeType = {
136
136
  properties: {
137
137
  enum: {
138
138
  type: 'array',
@@ -160,7 +160,7 @@ const Info: NodeType = {
160
160
  required: ['title', 'version'],
161
161
  };
162
162
 
163
- const Contact: NodeType = {
163
+ export const Contact: NodeType = {
164
164
  properties: {
165
165
  name: { type: 'string' },
166
166
  url: { type: 'string' },
@@ -168,7 +168,7 @@ const Contact: NodeType = {
168
168
  },
169
169
  };
170
170
 
171
- const License: NodeType = {
171
+ export const License: NodeType = {
172
172
  properties: {
173
173
  name: { type: 'string' },
174
174
  url: { type: 'string' },
@@ -184,7 +184,7 @@ const Parameter: NodeType = {
184
184
  },
185
185
  };
186
186
 
187
- const CorrelationId: NodeType = {
187
+ export const CorrelationId: NodeType = {
188
188
  properties: {
189
189
  description: { type: 'string' },
190
190
  location: { type: 'string' },
@@ -208,7 +208,7 @@ const Message: NodeType = {
208
208
  tags: 'TagList',
209
209
  externalDocs: 'ExternalDocs',
210
210
  bindings: 'MessageBindings',
211
- // examples: 'MessageExampleList', // TODO: add support for message examples
211
+ examples: 'MessageExampleList',
212
212
  traits: 'MessageTraitList',
213
213
  },
214
214
  additionalProperties: {},
@@ -301,7 +301,7 @@ const MessageTrait: NodeType = {
301
301
  tags: 'TagList',
302
302
  externalDocs: 'ExternalDocs',
303
303
  bindings: 'MessageBindings',
304
- // examples: 'MessageExampleList', // TODO: support examples for message traits
304
+ examples: 'MessageExampleList',
305
305
  },
306
306
  additionalProperties: {},
307
307
  };
@@ -322,7 +322,7 @@ const Operation: NodeType = {
322
322
  required: [],
323
323
  };
324
324
 
325
- const MessageExample: NodeType = {
325
+ export const MessageExample: NodeType = {
326
326
  properties: {
327
327
  payload: { isExample: true },
328
328
  summary: { type: 'string' },
@@ -331,14 +331,11 @@ const MessageExample: NodeType = {
331
331
  },
332
332
  };
333
333
 
334
- const Schema: NodeType = {
334
+ export const Schema: NodeType = {
335
335
  properties: {
336
336
  $id: { type: 'string' },
337
- id: { type: 'string' },
338
337
  $schema: { type: 'string' },
339
338
  definitions: 'NamedSchemas',
340
- $defs: 'NamedSchemas',
341
- $vocabulary: { type: 'string' },
342
339
  externalDocs: 'ExternalDocs',
343
340
  discriminator: 'Discriminator',
344
341
  myArbitraryKeyword: { type: 'boolean' },
@@ -359,16 +356,14 @@ const Schema: NodeType = {
359
356
  required: { type: 'array', items: { type: 'string' } },
360
357
  enum: { type: 'array' },
361
358
  type: (value: any) => {
362
- if (Array.isArray(value)) {
363
- return {
364
- type: 'array',
365
- items: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] },
366
- };
367
- } else {
368
- return {
369
- enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'],
370
- };
371
- }
359
+ return Array.isArray(value)
360
+ ? {
361
+ type: 'array',
362
+ items: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'] },
363
+ }
364
+ : {
365
+ enum: ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'],
366
+ };
372
367
  },
373
368
  allOf: listOf('Schema'),
374
369
  anyOf: listOf('Schema'),
@@ -377,35 +372,12 @@ const Schema: NodeType = {
377
372
  if: 'Schema',
378
373
  then: 'Schema',
379
374
  else: 'Schema',
380
- dependentSchemas: listOf('Schema'),
381
- prefixItems: listOf('Schema'),
382
375
  contains: 'Schema',
383
- minContains: { type: 'integer', minimum: 0 },
384
- maxContains: { type: 'integer', minimum: 0 },
385
376
  patternProperties: { type: 'object' },
386
377
  propertyNames: 'Schema',
387
- unevaluatedItems: (value: unknown) => {
388
- if (typeof value === 'boolean') {
389
- return { type: 'boolean' };
390
- } else {
391
- return 'Schema';
392
- }
393
- },
394
- unevaluatedProperties: (value: unknown) => {
395
- if (typeof value === 'boolean') {
396
- return { type: 'boolean' };
397
- } else {
398
- return 'Schema';
399
- }
400
- },
401
- summary: { type: 'string' },
402
378
  properties: 'SchemaProperties',
403
379
  items: (value: any) => {
404
- if (typeof value === 'boolean') {
405
- return { type: 'boolean' };
406
- } else {
407
- return 'Schema';
408
- }
380
+ return Array.isArray(value) ? listOf('Schema') : 'Schema';
409
381
  },
410
382
  additionalProperties: (value: any) => {
411
383
  return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
@@ -417,27 +389,26 @@ const Schema: NodeType = {
417
389
  default: null,
418
390
  readOnly: { type: 'boolean' },
419
391
  writeOnly: { type: 'boolean' },
420
- // xml: 'Xml',
421
392
  examples: { type: 'array' },
422
393
  example: { isExample: true },
423
394
  deprecated: { type: 'boolean' },
424
395
  const: null,
425
396
  $comment: { type: 'string' },
426
- dependencies: { type: 'object' }, // TODO
397
+ additionalItems: (value: any) => {
398
+ return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
399
+ },
400
+ dependencies: 'Dependencies',
427
401
  },
428
402
  };
429
403
 
430
- const SchemaProperties: NodeType = {
404
+ export const SchemaProperties: NodeType = {
431
405
  properties: {},
432
406
  additionalProperties: (value: any) => {
433
- if (typeof value === 'boolean') {
434
- return { type: 'boolean' };
435
- }
436
- return 'Schema';
407
+ return typeof value === 'boolean' ? { type: 'boolean' } : 'Schema';
437
408
  },
438
409
  };
439
410
 
440
- const DiscriminatorMapping: NodeType = {
411
+ export const DiscriminatorMapping: NodeType = {
441
412
  properties: {},
442
413
  additionalProperties: (value: any) => {
443
414
  if (isMappingRef(value)) {
@@ -448,7 +419,7 @@ const DiscriminatorMapping: NodeType = {
448
419
  },
449
420
  };
450
421
 
451
- const Discriminator: NodeType = {
422
+ export const Discriminator: NodeType = {
452
423
  properties: {
453
424
  propertyName: { type: 'string' },
454
425
  mapping: 'DiscriminatorMapping',
@@ -464,7 +435,6 @@ const Components: NodeType = {
464
435
  correlationIds: 'NamedCorrelationIds',
465
436
  messageTraits: 'NamedMessageTraits',
466
437
  operationTraits: 'NamedOperationTraits',
467
- streamHeaders: 'NamedStreamHeaders',
468
438
  securitySchemes: 'NamedSecuritySchemes',
469
439
  servers: 'ServerMap',
470
440
  serverVariables: 'ServerVariablesMap',
@@ -513,7 +483,7 @@ const AuthorizationCode: NodeType = {
513
483
  required: ['authorizationUrl', 'tokenUrl', 'scopes'],
514
484
  };
515
485
 
516
- const SecuritySchemeFlows: NodeType = {
486
+ export const SecuritySchemeFlows: NodeType = {
517
487
  properties: {
518
488
  implicit: 'ImplicitFlow',
519
489
  password: 'PasswordFlow',
@@ -584,6 +554,13 @@ const SecurityScheme: NodeType = {
584
554
  extensionsPrefix: 'x-',
585
555
  };
586
556
 
557
+ export const Dependencies: NodeType = {
558
+ properties: {},
559
+ additionalProperties: (value: any) => {
560
+ return Array.isArray(value) ? { type: 'array', items: { type: 'string' } } : 'Schema';
561
+ },
562
+ };
563
+
587
564
  // --- Per-protocol node types
588
565
 
589
566
  // http
@@ -1009,22 +986,7 @@ OperationBindings.properties.mercure = MercureOperationBinding;
1009
986
  // pulsar
1010
987
 
1011
988
  // --- End per-protocol node types
1012
-
1013
- export const AsyncApi2Types: Record<string, NodeType> = {
1014
- Root,
1015
- Tag,
1016
- TagList: listOf('Tag'),
1017
- ServerMap,
1018
- ExternalDocs,
1019
- Server,
1020
- ServerVariable,
1021
- ServerVariablesMap: mapOf('ServerVariable'),
1022
- SecurityRequirement,
1023
- SecurityRequirementList: listOf('SecurityRequirement'),
1024
- Info,
1025
- Contact,
1026
- License,
1027
-
989
+ export const AsyncApi2Bindings: Record<string, NodeType> = {
1028
990
  HttpServerBinding,
1029
991
  HttpChannelBinding,
1030
992
  HttpMessageBinding,
@@ -1100,6 +1062,25 @@ export const AsyncApi2Types: Record<string, NodeType> = {
1100
1062
 
1101
1063
  ServerBindings,
1102
1064
  ChannelBindings,
1065
+ MessageBindings,
1066
+ OperationBindings,
1067
+ };
1068
+
1069
+ export const AsyncApi2Types: Record<string, NodeType> = {
1070
+ ...AsyncApi2Bindings,
1071
+ Root,
1072
+ Tag,
1073
+ TagList: listOf('Tag'),
1074
+ ServerMap,
1075
+ ExternalDocs,
1076
+ Server,
1077
+ ServerVariable,
1078
+ ServerVariablesMap: mapOf('ServerVariable'),
1079
+ SecurityRequirement,
1080
+ SecurityRequirementList: listOf('SecurityRequirement'),
1081
+ Info,
1082
+ Contact,
1083
+ License,
1103
1084
  ChannelMap,
1104
1085
  Channel,
1105
1086
  Parameter,
@@ -1118,7 +1099,6 @@ export const AsyncApi2Types: Record<string, NodeType> = {
1118
1099
  NamedParameters: mapOf('Parameter'),
1119
1100
  NamedSecuritySchemes: mapOf('SecurityScheme'),
1120
1101
  NamedCorrelationIds: mapOf('CorrelationId'),
1121
- NamedStreamHeaders: mapOf('StreamHeader'),
1122
1102
  ImplicitFlow,
1123
1103
  PasswordFlow,
1124
1104
  ClientCredentials,
@@ -1132,5 +1112,7 @@ export const AsyncApi2Types: Record<string, NodeType> = {
1132
1112
  OperationTraitList: listOf('OperationTrait'),
1133
1113
  MessageTrait,
1134
1114
  MessageTraitList: listOf('MessageTrait'),
1115
+ MessageExampleList: listOf('MessageExample'),
1135
1116
  CorrelationId,
1117
+ Dependencies,
1136
1118
  };
@@ -0,0 +1,381 @@
1
+ import { NodeType, listOf, mapOf } from '.';
2
+ import {
3
+ AsyncApi2Bindings,
4
+ Schema,
5
+ Dependencies,
6
+ Discriminator,
7
+ DiscriminatorMapping,
8
+ SchemaProperties,
9
+ CorrelationId,
10
+ Tag,
11
+ ServerMap,
12
+ ExternalDocs,
13
+ SecuritySchemeFlows,
14
+ ServerVariable,
15
+ Contact,
16
+ License,
17
+ MessageExample,
18
+ } from './asyncapi2';
19
+
20
+ const Root: NodeType = {
21
+ properties: {
22
+ asyncapi: { type: 'string', enum: ['3.0.0'] },
23
+ info: 'Info',
24
+ id: { type: 'string' },
25
+ servers: 'ServerMap',
26
+ channels: 'NamedChannels',
27
+ components: 'Components',
28
+ operations: 'NamedOperations',
29
+ defaultContentType: { type: 'string' },
30
+ },
31
+ required: ['asyncapi', 'info'],
32
+ };
33
+
34
+ const Channel: NodeType = {
35
+ properties: {
36
+ address: { type: 'string' },
37
+ messages: 'NamedMessages',
38
+ title: { type: 'string' },
39
+ summary: { type: 'string' },
40
+ description: { type: 'string' },
41
+ servers: 'ServerList',
42
+ parameters: 'ParametersMap',
43
+ bindings: 'ChannelBindings',
44
+ tags: 'TagList',
45
+ externalDocs: 'ExternalDocs',
46
+ },
47
+ };
48
+
49
+ const Server: NodeType = {
50
+ properties: {
51
+ host: { type: 'string' },
52
+ pathname: { type: 'string' },
53
+ protocol: { type: 'string' },
54
+ protocolVersion: { type: 'string' },
55
+ description: { type: 'string' },
56
+ variables: 'ServerVariablesMap',
57
+ security: 'SecuritySchemeList',
58
+ bindings: 'ServerBindings',
59
+ externalDocs: 'ExternalDocs',
60
+ tags: 'TagList',
61
+ },
62
+ required: ['host', 'protocol'],
63
+ };
64
+
65
+ const Info: NodeType = {
66
+ properties: {
67
+ title: { type: 'string' },
68
+ version: { type: 'string' },
69
+ description: { type: 'string' },
70
+ termsOfService: { type: 'string' },
71
+ contact: 'Contact',
72
+ license: 'License',
73
+ tags: 'TagList',
74
+ externalDocs: 'ExternalDocs',
75
+ },
76
+ required: ['title', 'version'],
77
+ };
78
+
79
+ const Parameter: NodeType = {
80
+ properties: {
81
+ description: { type: 'string' },
82
+ enum: { type: 'array', items: { type: 'string' } },
83
+ default: { type: 'string' },
84
+ examples: { type: 'array', items: { type: 'string' } },
85
+ location: { type: 'string' },
86
+ },
87
+ };
88
+
89
+ const Message: NodeType = {
90
+ properties: {
91
+ headers: 'Schema',
92
+ payload: (value: Record<string, unknown>) => {
93
+ if (!!value && value?.['schemaFormat']) {
94
+ return {
95
+ properties: {
96
+ schema: 'Schema',
97
+ schemaFormat: { type: 'string' },
98
+ },
99
+ required: ['schema', 'schemaFormat'],
100
+ };
101
+ } else {
102
+ return 'Schema';
103
+ }
104
+ },
105
+ correlationId: 'CorrelationId',
106
+
107
+ contentType: { type: 'string' },
108
+ name: { type: 'string' },
109
+ title: { type: 'string' },
110
+ summary: { type: 'string' },
111
+ description: { type: 'string' },
112
+ tags: 'TagList',
113
+ externalDocs: 'ExternalDocs',
114
+ bindings: 'MessageBindings',
115
+ examples: 'MessageExampleList',
116
+ traits: 'MessageTraitList',
117
+ },
118
+ additionalProperties: {},
119
+ };
120
+
121
+ const OperationTrait: NodeType = {
122
+ properties: {
123
+ tags: 'TagList',
124
+ title: { type: 'string' },
125
+ summary: { type: 'string' },
126
+ description: { type: 'string' },
127
+ externalDocs: 'ExternalDocs',
128
+ security: 'SecuritySchemeList',
129
+
130
+ bindings: 'OperationBindings',
131
+ },
132
+ required: [],
133
+ };
134
+
135
+ const MessageTrait: NodeType = {
136
+ properties: {
137
+ headers: (value: unknown) => {
138
+ if (typeof value === 'function' || (typeof value === 'object' && !!value)) {
139
+ return {
140
+ properties: {
141
+ schema: 'Schema',
142
+ schemaFormat: { type: 'string' },
143
+ },
144
+ };
145
+ } else {
146
+ return 'Schema';
147
+ }
148
+ },
149
+ correlationId: 'CorrelationId',
150
+
151
+ contentType: { type: 'string' },
152
+ name: { type: 'string' },
153
+ title: { type: 'string' },
154
+ summary: { type: 'string' },
155
+ description: { type: 'string' },
156
+ tags: 'TagList',
157
+ externalDocs: 'ExternalDocs',
158
+ bindings: 'MessageBindings',
159
+ examples: 'MessageExampleList',
160
+ },
161
+ additionalProperties: {},
162
+ };
163
+
164
+ const Operation: NodeType = {
165
+ properties: {
166
+ action: { type: 'string', enum: ['send', 'receive'] },
167
+ channel: 'Channel',
168
+ title: { type: 'string' },
169
+ tags: 'TagList',
170
+ summary: { type: 'string' },
171
+ description: { type: 'string' },
172
+ externalDocs: 'ExternalDocs',
173
+ operationId: { type: 'string' },
174
+ security: 'SecuritySchemeList',
175
+
176
+ bindings: 'OperationBindings',
177
+ traits: 'OperationTraitList',
178
+ messages: 'MessageList',
179
+ reply: 'OperationReply',
180
+ },
181
+ required: ['action', 'channel'],
182
+ };
183
+
184
+ const OperationReply: NodeType = {
185
+ properties: {
186
+ channel: 'Channel',
187
+ messages: 'MessageList',
188
+ address: 'OperationReplyAddress',
189
+ },
190
+ };
191
+
192
+ const OperationReplyAddress: NodeType = {
193
+ properties: {
194
+ location: { type: 'string' },
195
+ description: { type: 'string' },
196
+ },
197
+ required: ['location'],
198
+ };
199
+
200
+ const Components: NodeType = {
201
+ properties: {
202
+ messages: 'NamedMessages',
203
+ parameters: 'NamedParameters',
204
+ schemas: 'NamedSchemas',
205
+ replies: 'NamedOperationReplies',
206
+ replyAddresses: 'NamedOperationRelyAddresses',
207
+ correlationIds: 'NamedCorrelationIds',
208
+ messageTraits: 'NamedMessageTraits',
209
+ operationTraits: 'NamedOperationTraits',
210
+ tags: 'NamedTags',
211
+ externalDocs: 'NamedExternalDocs',
212
+ securitySchemes: 'NamedSecuritySchemes',
213
+ servers: 'ServerMap',
214
+ serverVariables: 'ServerVariablesMap',
215
+ channels: 'NamedChannels',
216
+ operations: 'NamedOperations',
217
+ serverBindings: 'ServerBindings',
218
+ channelBindings: 'ChannelBindings',
219
+ operationBindings: 'OperationBindings',
220
+ messageBindings: 'MessageBindings',
221
+ },
222
+ };
223
+
224
+ const ImplicitFlow: NodeType = {
225
+ properties: {
226
+ refreshUrl: { type: 'string' },
227
+ availableScopes: { type: 'object', additionalProperties: { type: 'string' } },
228
+ authorizationUrl: { type: 'string' },
229
+ },
230
+ required: ['authorizationUrl', 'availableScopes'],
231
+ };
232
+
233
+ const PasswordFlow: NodeType = {
234
+ properties: {
235
+ refreshUrl: { type: 'string' },
236
+ availableScopes: { type: 'object', additionalProperties: { type: 'string' } },
237
+ tokenUrl: { type: 'string' },
238
+ },
239
+ required: ['tokenUrl', 'availableScopes'],
240
+ };
241
+
242
+ const ClientCredentials: NodeType = {
243
+ properties: {
244
+ refreshUrl: { type: 'string' },
245
+ availableScopes: { type: 'object', additionalProperties: { type: 'string' } },
246
+ tokenUrl: { type: 'string' },
247
+ },
248
+ required: ['tokenUrl', 'availableScopes'],
249
+ };
250
+
251
+ const AuthorizationCode: NodeType = {
252
+ properties: {
253
+ refreshUrl: { type: 'string' },
254
+ authorizationUrl: { type: 'string' },
255
+ availableScopes: { type: 'object', additionalProperties: { type: 'string' } },
256
+ tokenUrl: { type: 'string' },
257
+ },
258
+ required: ['authorizationUrl', 'tokenUrl', 'availableScopes'],
259
+ };
260
+
261
+ const SecurityScheme: NodeType = {
262
+ properties: {
263
+ type: {
264
+ enum: [
265
+ 'userPassword',
266
+ 'apiKey',
267
+ 'X509',
268
+ 'symmetricEncryption',
269
+ 'asymmetricEncryption',
270
+ 'httpApiKey',
271
+ 'http',
272
+ 'oauth2',
273
+ 'openIdConnect',
274
+ 'plain',
275
+ 'scramSha256',
276
+ 'scramSha512',
277
+ 'gssapi',
278
+ ],
279
+ },
280
+ description: { type: 'string' },
281
+ name: { type: 'string' },
282
+ in: { type: 'string', enum: ['query', 'header', 'cookie', 'user', 'password'] },
283
+ scheme: { type: 'string' },
284
+ bearerFormat: { type: 'string' },
285
+ flows: 'SecuritySchemeFlows',
286
+ openIdConnectUrl: { type: 'string' },
287
+ scopes: { type: 'array', items: { type: 'string' } },
288
+ },
289
+ required(value) {
290
+ switch (value?.type) {
291
+ case 'apiKey':
292
+ return ['type', 'in'];
293
+ case 'httpApiKey':
294
+ return ['type', 'name', 'in'];
295
+ case 'http':
296
+ return ['type', 'scheme'];
297
+ case 'oauth2':
298
+ return ['type', 'flows'];
299
+ case 'openIdConnect':
300
+ return ['type', 'openIdConnectUrl'];
301
+ default:
302
+ return ['type'];
303
+ }
304
+ },
305
+ allowed(value) {
306
+ switch (value?.type) {
307
+ case 'apiKey':
308
+ return ['type', 'in', 'description'];
309
+ case 'httpApiKey':
310
+ return ['type', 'name', 'in', 'description'];
311
+ case 'http':
312
+ return ['type', 'scheme', 'bearerFormat', 'description'];
313
+ case 'oauth2':
314
+ return ['type', 'flows', 'description', 'scopes'];
315
+ case 'openIdConnect':
316
+ return ['type', 'openIdConnectUrl', 'description', 'scopes'];
317
+ default:
318
+ return ['type', 'description'];
319
+ }
320
+ },
321
+ extensionsPrefix: 'x-',
322
+ };
323
+
324
+ export const AsyncApi3Types: Record<string, NodeType> = {
325
+ // from asyncapi2
326
+ ...AsyncApi2Bindings,
327
+ CorrelationId,
328
+ SecuritySchemeFlows,
329
+ ServerVariable,
330
+ Contact,
331
+ License,
332
+ MessageExample,
333
+ Tag,
334
+ Dependencies,
335
+ Schema,
336
+ Discriminator,
337
+ DiscriminatorMapping,
338
+ SchemaProperties,
339
+ ServerMap,
340
+ ExternalDocs,
341
+ Root,
342
+
343
+ Channel,
344
+ Parameter,
345
+ Info,
346
+ Server,
347
+ MessageTrait,
348
+ Operation,
349
+ OperationReply,
350
+ OperationReplyAddress,
351
+ Components,
352
+ ImplicitFlow,
353
+ PasswordFlow,
354
+ ClientCredentials,
355
+ AuthorizationCode,
356
+ SecurityScheme,
357
+ Message,
358
+ OperationTrait,
359
+ ServerVariablesMap: mapOf('ServerVariable'),
360
+ NamedTags: mapOf('Tag'),
361
+ NamedExternalDocs: mapOf('ExternalDocs'),
362
+ NamedChannels: mapOf('Channel'),
363
+ ParametersMap: mapOf('Parameter'),
364
+ NamedOperations: mapOf('Operation'),
365
+ NamedOperationReplies: mapOf('OperationReply'),
366
+ NamedOperationRelyAddresses: mapOf('OperationReplyAddress'),
367
+ NamedSchemas: mapOf('Schema'),
368
+ NamedMessages: mapOf('Message'),
369
+ NamedMessageTraits: mapOf('MessageTrait'),
370
+ NamedOperationTraits: mapOf('OperationTrait'),
371
+ NamedParameters: mapOf('Parameter'),
372
+ NamedSecuritySchemes: mapOf('SecurityScheme'),
373
+ NamedCorrelationIds: mapOf('CorrelationId'),
374
+ ServerList: listOf('Server'),
375
+ SecuritySchemeList: listOf('SecurityScheme'),
376
+ MessageList: listOf('Message'),
377
+ OperationTraitList: listOf('OperationTrait'),
378
+ MessageTraitList: listOf('MessageTrait'),
379
+ MessageExampleList: listOf('MessageExample'),
380
+ TagList: listOf('Tag'),
381
+ };
@@ -133,13 +133,13 @@ const Schema: NodeType = {
133
133
  if: 'Schema',
134
134
  then: 'Schema',
135
135
  else: 'Schema',
136
- dependentSchemas: listOf('Schema'),
136
+ dependentSchemas: mapOf('Schema'),
137
137
  dependentRequired: 'DependentRequired',
138
138
  prefixItems: listOf('Schema'),
139
139
  contains: 'Schema',
140
140
  minContains: { type: 'integer', minimum: 0 },
141
141
  maxContains: { type: 'integer', minimum: 0 },
142
- patternProperties: { type: 'object' },
142
+ patternProperties: 'PatternProperties',
143
143
  propertyNames: 'Schema',
144
144
  unevaluatedItems: (value: unknown) => {
145
145
  if (typeof value === 'boolean') {
@@ -278,6 +278,7 @@ export const Oas3_1Types: Record<Oas3_1NodeType, NodeType> = {
278
278
  Root,
279
279
  Schema,
280
280
  SchemaProperties,
281
+ PatternProperties: SchemaProperties,
281
282
  License,
282
283
  Components,
283
284
  NamedPathItems: mapOf('PathItem'),