@redocly/openapi-core 1.0.0-beta.102 → 1.0.0-beta.105

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 (62) hide show
  1. package/__tests__/utils.ts +3 -1
  2. package/lib/config/config.d.ts +4 -3
  3. package/lib/config/config.js +23 -16
  4. package/lib/config/load.d.ts +1 -1
  5. package/lib/config/load.js +15 -3
  6. package/lib/config/rules.d.ts +1 -1
  7. package/lib/config/types.d.ts +4 -2
  8. package/lib/decorators/common/filters/filter-helper.d.ts +3 -0
  9. package/lib/decorators/common/filters/filter-helper.js +67 -0
  10. package/lib/decorators/common/filters/filter-in.d.ts +2 -0
  11. package/lib/decorators/common/filters/filter-in.js +17 -0
  12. package/lib/decorators/common/filters/filter-out.d.ts +2 -0
  13. package/lib/decorators/common/filters/filter-out.js +17 -0
  14. package/lib/decorators/oas2/index.d.ts +2 -0
  15. package/lib/decorators/oas2/index.js +5 -1
  16. package/lib/decorators/oas3/index.d.ts +2 -0
  17. package/lib/decorators/oas3/index.js +5 -1
  18. package/lib/index.d.ts +2 -2
  19. package/lib/index.js +2 -1
  20. package/lib/lint.d.ts +2 -0
  21. package/lib/lint.js +2 -2
  22. package/lib/redocly/registry-api-types.d.ts +2 -0
  23. package/lib/redocly/registry-api.d.ts +1 -1
  24. package/lib/redocly/registry-api.js +3 -1
  25. package/lib/rules/ajv.d.ts +1 -1
  26. package/lib/rules/ajv.js +1 -1
  27. package/lib/rules/common/assertions/asserts.d.ts +6 -1
  28. package/lib/rules/common/assertions/asserts.js +81 -51
  29. package/lib/rules/common/assertions/utils.d.ts +2 -1
  30. package/lib/rules/common/assertions/utils.js +27 -8
  31. package/lib/types/redocly-yaml.js +317 -27
  32. package/lib/utils.d.ts +5 -3
  33. package/lib/utils.js +15 -2
  34. package/lib/walk.d.ts +4 -14
  35. package/lib/walk.js +35 -26
  36. package/package.json +3 -2
  37. package/src/__tests__/fixtures/.redocly.lint-ignore.yaml +5 -0
  38. package/src/__tests__/lint.test.ts +70 -10
  39. package/src/__tests__/utils.test.ts +42 -1
  40. package/src/config/__tests__/load.test.ts +8 -2
  41. package/src/config/config.ts +31 -27
  42. package/src/config/load.ts +29 -9
  43. package/src/config/types.ts +6 -5
  44. package/src/decorators/__tests__/filter-in.test.ts +310 -0
  45. package/src/decorators/__tests__/filter-out.test.ts +331 -0
  46. package/src/decorators/common/filters/filter-helper.ts +72 -0
  47. package/src/decorators/common/filters/filter-in.ts +18 -0
  48. package/src/decorators/common/filters/filter-out.ts +18 -0
  49. package/src/decorators/oas2/index.ts +5 -1
  50. package/src/decorators/oas3/index.ts +5 -1
  51. package/src/index.ts +2 -1
  52. package/src/lint.ts +4 -3
  53. package/src/redocly/registry-api-types.ts +2 -0
  54. package/src/redocly/registry-api.ts +4 -0
  55. package/src/rules/ajv.ts +4 -4
  56. package/src/rules/common/assertions/__tests__/asserts.test.ts +149 -146
  57. package/src/rules/common/assertions/asserts.ts +97 -52
  58. package/src/rules/common/assertions/utils.ts +41 -16
  59. package/src/types/redocly-yaml.ts +322 -34
  60. package/src/utils.ts +28 -15
  61. package/src/walk.ts +59 -47
  62. package/tsconfig.tsbuildinfo +1 -1
@@ -1,13 +1,125 @@
1
1
  import { NodeType, listOf } from '.';
2
- import { omitObjectProps, pickObjectProps } from '../utils';
2
+ import { omitObjectProps, pickObjectProps, isCustomRuleId } from '../utils';
3
+ const builtInRulesList = [
4
+ 'spec',
5
+ 'info-description',
6
+ 'info-contact',
7
+ 'info-license',
8
+ 'info-license-url',
9
+ 'operation-2xx-response',
10
+ 'operation-4xx-response',
11
+ 'assertions',
12
+ 'operation-operationId-unique',
13
+ 'operation-parameters-unique',
14
+ 'path-parameters-defined',
15
+ 'operation-tag-defined',
16
+ 'no-example-value-and-externalValue',
17
+ 'no-enum-type-mismatch',
18
+ 'no-path-trailing-slash',
19
+ 'no-empty-servers',
20
+ 'path-declaration-must-exist',
21
+ 'operation-operationId-url-safe',
22
+ 'operation-operationId',
23
+ 'operation-summary',
24
+ 'tags-alphabetical',
25
+ 'no-server-example.com',
26
+ 'no-server-trailing-slash',
27
+ 'tag-description',
28
+ 'operation-description',
29
+ 'no-unused-components',
30
+ 'path-not-include-query',
31
+ 'path-params-defined',
32
+ 'parameter-description',
33
+ 'operation-singular-tag',
34
+ 'operation-security-defined',
35
+ 'no-unresolved-refs',
36
+ 'paths-kebab-case',
37
+ 'boolean-parameter-prefixes',
38
+ 'path-http-verbs-order',
39
+ 'no-invalid-media-type-examples',
40
+ 'no-identical-paths',
41
+ 'no-ambiguous-paths',
42
+ 'no-undefined-server-variable',
43
+ 'no-servers-empty-enum',
44
+ 'no-http-verbs-in-paths',
45
+ 'path-excludes-patterns',
46
+ 'request-mime-type',
47
+ 'response-mime-type',
48
+ 'path-segment-plural',
49
+ 'no-invalid-schema-examples',
50
+ 'no-invalid-parameter-examples',
51
+ 'response-contains-header',
52
+ 'response-contains-property',
53
+ 'scalar-property-missing-example',
54
+ ];
55
+ const nodeTypesList = [
56
+ 'DefinitionRoot',
57
+ 'Tag',
58
+ 'ExternalDocs',
59
+ 'Server',
60
+ 'ServerVariable',
61
+ 'SecurityRequirement',
62
+ 'Info',
63
+ 'Contact',
64
+ 'License',
65
+ 'PathMap',
66
+ 'PathItem',
67
+ 'Parameter',
68
+ 'Operation',
69
+ 'Callback',
70
+ 'RequestBody',
71
+ 'MediaTypeMap',
72
+ 'MediaType',
73
+ 'Example',
74
+ 'Encoding',
75
+ 'Header',
76
+ 'ResponsesMap',
77
+ 'Response',
78
+ 'Link',
79
+ 'Schema',
80
+ 'Xml',
81
+ 'SchemaProperties',
82
+ 'DiscriminatorMapping',
83
+ 'Discriminator',
84
+ 'Components',
85
+ 'NamedSchemas',
86
+ 'NamedResponses',
87
+ 'NamedParameters',
88
+ 'NamedExamples',
89
+ 'NamedRequestBodies',
90
+ 'NamedHeaders',
91
+ 'NamedSecuritySchemes',
92
+ 'NamedLinks',
93
+ 'NamedCallbacks',
94
+ 'ImplicitFlow',
95
+ 'PasswordFlow',
96
+ 'ClientCredentials',
97
+ 'AuthorizationCode',
98
+ 'SecuritySchemeFlows',
99
+ 'SecurityScheme',
100
+ 'XCodeSample',
101
+ 'WebhooksMap',
102
+ ];
3
103
 
4
104
  const ConfigRoot: NodeType = {
5
105
  properties: {
6
106
  organization: { type: 'string' },
7
107
  apis: 'ConfigApis',
108
+ apiDefinitions: {
109
+ type: 'object',
110
+ properties: {},
111
+ additionalProperties: { properties: { type: 'string' } },
112
+ }, // deprecated
8
113
  lint: 'RootConfigLint',
9
114
  'features.openapi': 'ConfigReferenceDocs',
115
+ referenceDocs: 'ConfigReferenceDocs', // deprecated
10
116
  'features.mockServer': 'ConfigMockServer',
117
+ region: { enum: ['us', 'eu'] },
118
+ resolve: {
119
+ properties: {
120
+ http: 'ConfigHTTP',
121
+ },
122
+ },
11
123
  },
12
124
  };
13
125
 
@@ -19,9 +131,17 @@ const ConfigApis: NodeType = {
19
131
  const ConfigApisProperties: NodeType = {
20
132
  properties: {
21
133
  root: { type: 'string' },
134
+ labels: {
135
+ type: 'array',
136
+ items: {
137
+ type: 'string',
138
+ },
139
+ },
22
140
  lint: 'ConfigLint',
23
141
  'features.openapi': 'ConfigReferenceDocs',
142
+ 'features.mockServer': 'ConfigMockServer',
24
143
  },
144
+ required: ['root'],
25
145
  };
26
146
 
27
147
  const ConfigHTTP: NodeType = {
@@ -44,10 +164,10 @@ const ConfigLint: NodeType = {
44
164
  },
45
165
  },
46
166
  doNotResolveExamples: { type: 'boolean' },
47
- rules: { type: 'object' },
48
- oas2Rules: { type: 'object' },
49
- oas3_0Rules: { type: 'object' },
50
- oas3_1Rules: { type: 'object' },
167
+ rules: 'Rules',
168
+ oas2Rules: 'Rules',
169
+ oas3_0Rules: 'Rules',
170
+ oas3_1Rules: 'Rules',
51
171
  preprocessors: { type: 'object' },
52
172
  oas2Preprocessors: { type: 'object' },
53
173
  oas3_0Preprocessors: { type: 'object' },
@@ -56,11 +176,6 @@ const ConfigLint: NodeType = {
56
176
  oas2Decorators: { type: 'object' },
57
177
  oas3_0Decorators: { type: 'object' },
58
178
  oas3_1Decorators: { type: 'object' },
59
- resolve: {
60
- properties: {
61
- http: 'ConfigHTTP',
62
- },
63
- },
64
179
  },
65
180
  };
66
181
 
@@ -74,11 +189,111 @@ const RootConfigLint: NodeType = {
74
189
  },
75
190
  };
76
191
 
192
+ const Rules: NodeType = {
193
+ properties: {},
194
+ additionalProperties: (value: unknown, key: string) => {
195
+ if (key.startsWith('assert/')) {
196
+ return 'Assert';
197
+ } else if (builtInRulesList.includes(key) || isCustomRuleId(key)) {
198
+ if (typeof value === 'string') {
199
+ return { enum: ['error', 'warn', 'off'] };
200
+ } else {
201
+ return 'ObjectRule';
202
+ }
203
+ }
204
+ // Otherwise is considered as invalid
205
+ return;
206
+ },
207
+ };
208
+
209
+ const ObjectRule: NodeType = {
210
+ properties: {
211
+ severity: { enum: ['error', 'warn', 'off'] },
212
+ },
213
+ additionalProperties: {},
214
+ required: ['severity'],
215
+ };
216
+
217
+ const Assert: NodeType = {
218
+ properties: {
219
+ subject: (value: unknown) => {
220
+ if (Array.isArray(value)) {
221
+ return { type: 'array', items: { enum: nodeTypesList } };
222
+ } else {
223
+ return { enum: nodeTypesList };
224
+ }
225
+ },
226
+ property: (value: unknown) => {
227
+ if (Array.isArray(value)) {
228
+ return { type: 'array', items: { type: 'string' } };
229
+ } else if (value === null) {
230
+ return null;
231
+ } else {
232
+ return { type: 'string' };
233
+ }
234
+ },
235
+ context: listOf('Context'),
236
+ message: { type: 'string' },
237
+ suggest: { type: 'array', items: { type: 'string' } },
238
+ severity: { enum: ['error', 'warn', 'off'] },
239
+ enum: { type: 'array', items: { type: 'string' } },
240
+ pattern: { type: 'string' },
241
+ casing: {
242
+ enum: [
243
+ 'camelCase',
244
+ 'kebab-case',
245
+ 'snake_case',
246
+ 'PascalCase',
247
+ 'MACRO_CASE',
248
+ 'COBOL-CASE',
249
+ 'flatcase',
250
+ ],
251
+ },
252
+ mutuallyExclusive: { type: 'array', items: { type: 'string' } },
253
+ mutuallyRequired: { type: 'array', items: { type: 'string' } },
254
+ required: { type: 'array', items: { type: 'string' } },
255
+ requireAny: { type: 'array', items: { type: 'string' } },
256
+ disallowed: { type: 'array', items: { type: 'string' } },
257
+ defined: { type: 'boolean' },
258
+ undefined: { type: 'boolean' },
259
+ nonEmpty: { type: 'boolean' },
260
+ minLength: { type: 'integer' },
261
+ maxLength: { type: 'integer' },
262
+ ref: (value: string | boolean) =>
263
+ typeof value === 'string' ? { type: 'string' } : { type: 'boolean' },
264
+ },
265
+ required: ['subject'],
266
+ };
267
+
268
+ const Context: NodeType = {
269
+ properties: {
270
+ type: { enum: nodeTypesList },
271
+ matchParentKeys: { type: 'array', items: { type: 'string' } },
272
+ excludeParentKeys: { type: 'array', items: { type: 'string' } },
273
+ },
274
+ required: ['type'],
275
+ };
276
+
77
277
  const ConfigLanguage: NodeType = {
78
278
  properties: {
79
279
  label: { type: 'string' },
80
- lang: { type: 'string' },
280
+ lang: {
281
+ enum: [
282
+ 'curl',
283
+ 'C#',
284
+ 'Go',
285
+ 'Java',
286
+ 'Java8+Apache',
287
+ 'JavaScript',
288
+ 'Node.js',
289
+ 'PHP',
290
+ 'Python',
291
+ 'R',
292
+ 'Ruby',
293
+ ],
294
+ },
81
295
  },
296
+ required: ['lang'],
82
297
  };
83
298
 
84
299
  const ConfigLabels: NodeType = {
@@ -102,11 +317,18 @@ const ConfigLabels: NodeType = {
102
317
 
103
318
  const ConfigSidebarLinks: NodeType = {
104
319
  properties: {
105
- placement: { type: 'string' },
320
+ beforeInfo: listOf('CommonConfigSidebarLinks'),
321
+ end: listOf('CommonConfigSidebarLinks'),
322
+ },
323
+ };
324
+
325
+ const CommonConfigSidebarLinks: NodeType = {
326
+ properties: {
106
327
  label: { type: 'string' },
107
328
  link: { type: 'string' },
108
329
  target: { type: 'string' },
109
330
  },
331
+ required: ['label', 'link'],
110
332
  };
111
333
 
112
334
  const CommonThemeColors: NodeType = {
@@ -147,7 +369,7 @@ const HttpColors: NodeType = {
147
369
 
148
370
  const ResponseColors: NodeType = {
149
371
  properties: {
150
- errors: 'CommonColorProps',
372
+ error: 'CommonColorProps',
151
373
  info: 'CommonColorProps',
152
374
  redirect: 'CommonColorProps',
153
375
  success: 'CommonColorProps',
@@ -242,12 +464,15 @@ const HttpBadgesConfig: NodeType = {
242
464
  const LabelControls: NodeType = {
243
465
  properties: {
244
466
  top: { type: 'string' },
467
+ width: { type: 'string' },
468
+ height: { type: 'string' },
245
469
  },
246
470
  };
247
471
 
248
472
  const Panels: NodeType = {
249
473
  properties: {
250
474
  borderRadius: { type: 'string' },
475
+ backgroundColor: { type: 'string' },
251
476
  },
252
477
  };
253
478
 
@@ -285,6 +510,7 @@ const StackedConfig: NodeType = {
285
510
  const ThreePanelConfig: NodeType = {
286
511
  properties: {
287
512
  maxWidth: 'Breakpoints',
513
+ middlePanelMaxWidth: 'Breakpoints',
288
514
  },
289
515
  };
290
516
 
@@ -378,7 +604,18 @@ const CodeConfig: NodeType = {
378
604
  ...FontConfig.properties,
379
605
  backgroundColor: { type: 'string' },
380
606
  color: { type: 'string' },
381
- wordBreak: { type: 'string' },
607
+ wordBreak: {
608
+ enum: [
609
+ 'break-all',
610
+ 'break-word',
611
+ 'keep-all',
612
+ 'normal',
613
+ 'revert',
614
+ 'unset',
615
+ 'inherit',
616
+ 'initial',
617
+ ],
618
+ },
382
619
  wrap: { type: 'boolean' },
383
620
  },
384
621
  };
@@ -413,7 +650,7 @@ const Typography: NodeType = {
413
650
  links: 'LinksConfig',
414
651
  optimizeSpeed: { type: 'boolean' },
415
652
  rightPanelHeading: 'Heading',
416
- smoothing: { type: 'string' },
653
+ smoothing: { enum: ['auto', 'none', 'antialiased', 'subpixel-antialiased', 'grayscale'] },
417
654
  },
418
655
  };
419
656
 
@@ -440,6 +677,13 @@ const Logo: NodeType = {
440
677
  },
441
678
  };
442
679
 
680
+ const Fab: NodeType = {
681
+ properties: {
682
+ backgroundColor: { type: 'string' },
683
+ color: { type: 'string' },
684
+ },
685
+ };
686
+
443
687
  const ButtonOverrides: NodeType = {
444
688
  properties: {
445
689
  custom: { type: 'string' },
@@ -484,6 +728,7 @@ const ConfigTheme: NodeType = {
484
728
  components: 'Components',
485
729
  layout: 'Layout',
486
730
  logo: 'Logo',
731
+ fab: 'Fab',
487
732
  overrides: 'Overrides',
488
733
  rightPanel: 'RightPanel',
489
734
  schema: 'Schema',
@@ -491,8 +736,8 @@ const ConfigTheme: NodeType = {
491
736
  sidebar: 'Sidebar',
492
737
  spacing: 'ThemeSpacing',
493
738
  typography: 'Typography',
494
- links: { properties: { color: { type: 'string' } } },
495
- codeSample: { properties: { backgroundColor: { type: 'string' } } },
739
+ links: { properties: { color: { type: 'string' } } }, // deprecated
740
+ codeSample: { properties: { backgroundColor: { type: 'string' } } }, // deprecated
496
741
  },
497
742
  };
498
743
 
@@ -501,6 +746,7 @@ const GenerateCodeSamples: NodeType = {
501
746
  skipOptionalParameters: { type: 'boolean' },
502
747
  languages: listOf('ConfigLanguage'),
503
748
  },
749
+ required: ['languages'],
504
750
  };
505
751
 
506
752
  const ConfigReferenceDocs: NodeType = {
@@ -515,8 +761,8 @@ const ConfigReferenceDocs: NodeType = {
515
761
  downloadDefinitionUrl: { type: 'string' },
516
762
  expandDefaultServerVariables: { type: 'boolean' },
517
763
  enumSkipQuotes: { type: 'boolean' },
518
- expandDefaultRequest: { type: 'boolean'},
519
- expandDefaultResponse: { type: 'boolean'},
764
+ expandDefaultRequest: { type: 'boolean' },
765
+ expandDefaultResponse: { type: 'boolean' },
520
766
  expandResponses: { type: 'string' },
521
767
  expandSingleSchemaField: { type: 'boolean' },
522
768
  generateCodeSamples: 'GenerateCodeSamples',
@@ -527,43 +773,77 @@ const ConfigReferenceDocs: NodeType = {
527
773
  hideLoading: { type: 'boolean' },
528
774
  hideLogo: { type: 'boolean' },
529
775
  hideRequestPayloadSample: { type: 'boolean' },
776
+ hideRightPanel: { type: 'boolean' },
530
777
  hideSchemaPattern: { type: 'boolean' },
531
778
  hideSchemaTitles: { type: 'boolean' },
532
779
  hideSingleRequestSampleTab: { type: 'boolean' },
780
+ hideSecuritySection: { type: 'boolean' },
533
781
  hideTryItPanel: { type: 'boolean' },
534
782
  hideFab: { type: 'boolean' },
535
- hideOneOfDescription: { type: 'boolean'},
783
+ hideOneOfDescription: { type: 'boolean' },
536
784
  htmlTemplate: { type: 'string' },
537
- jsonSampleExpandLevel: { type: 'string' },
785
+ jsonSampleExpandLevel: (value: unknown) => {
786
+ if (typeof value === 'number') {
787
+ return { type: 'number', minimum: 1 };
788
+ } else {
789
+ return { type: 'string' };
790
+ }
791
+ },
538
792
  labels: 'ConfigLabels',
539
- layout: { type: 'string' },
793
+ layout: { enum: ['stacked', 'three-panel'] },
540
794
  maxDisplayedEnumValues: { type: 'number' },
541
795
  menuToggle: { type: 'boolean' },
542
796
  nativeScrollbars: { type: 'boolean' },
543
- noAutoAuth: { type: 'boolean' },
797
+ noAutoAuth: { type: 'boolean' }, // deprecated
544
798
  oAuth2RedirectURI: { type: 'string' },
545
799
  onDeepLinkClick: { type: 'object' },
546
800
  onlyRequiredInSamples: { type: 'boolean' },
547
- pagination: { type: 'string' },
801
+ pagination: { enum: ['none', 'section', 'item'] },
548
802
  pathInMiddlePanel: { type: 'boolean' },
549
- payloadSampleIdx: { type: 'number' },
803
+ payloadSampleIdx: { type: 'number', minimum: 0 },
550
804
  requestInterceptor: { type: 'object' },
551
805
  requiredPropsFirst: { type: 'boolean' },
552
806
  routingBasePath: { type: 'string' },
807
+ routingStrategy: { type: 'string' }, // deprecated
553
808
  samplesTabsMaxCount: { type: 'number' },
554
- schemaExpansionLevel: { type: 'string' },
809
+ schemaExpansionLevel: (value: unknown) => {
810
+ if (typeof value === 'number') {
811
+ return { type: 'number', minimum: 0 };
812
+ } else {
813
+ return { type: 'string' };
814
+ }
815
+ },
555
816
  schemaDefinitionsTagName: { type: 'string' },
556
- minCharacterLengthToInitSearch: { type: 'number' },
557
- maxResponseHeadersToShowInTryIt: {type: 'number'},
558
- scrollYOffset: { type: 'string' },
817
+ minCharacterLengthToInitSearch: { type: 'number', minimum: 1 },
818
+ maxResponseHeadersToShowInTryIt: { type: 'number', minimum: 0 },
819
+ scrollYOffset: (value: unknown) => {
820
+ if (typeof value === 'number') {
821
+ return { type: 'number' };
822
+ } else {
823
+ return { type: 'string' };
824
+ }
825
+ },
559
826
  searchAutoExpand: { type: 'boolean' },
560
- searchFieldLevelBoost: { type: 'number' },
561
- searchMode: { type: 'string' },
827
+ searchFieldLevelBoost: { type: 'number', minimum: 0 },
828
+ searchMaxDepth: { type: 'number', minimum: 1 },
829
+ searchMode: { enum: ['default', 'path-only'] },
562
830
  searchOperationTitleBoost: { type: 'number' },
563
831
  searchTagTitleBoost: { type: 'number' },
832
+ sendXUserAgentInTryIt: { type: 'boolean' },
564
833
  showChangeLayoutButton: { type: 'boolean' },
565
- showConsole: { type: 'boolean' },
566
- showExtensions: { type: 'boolean' },
834
+ showConsole: { type: 'boolean' }, // deprecated
835
+ showExtensions: (value: unknown) => {
836
+ if (typeof value === 'boolean') {
837
+ return { type: 'boolean' };
838
+ } else {
839
+ return {
840
+ type: 'array',
841
+ items: {
842
+ type: 'string',
843
+ },
844
+ };
845
+ }
846
+ },
567
847
  showNextButton: { type: 'boolean' },
568
848
  showRightPanelToggle: { type: 'boolean' },
569
849
  showSecuritySchemeType: { type: 'boolean' },
@@ -571,12 +851,14 @@ const ConfigReferenceDocs: NodeType = {
571
851
  showObjectSchemaExamples: { type: 'boolean' },
572
852
  disableTryItRequestUrlEncoding: { type: 'boolean' },
573
853
  sidebarLinks: 'ConfigSidebarLinks',
574
- sideNavStyle: { type: 'string' },
854
+ sideNavStyle: { enum: ['summary-only', 'path-first', 'id-only'] },
575
855
  simpleOneOfTypeLabel: { type: 'boolean' },
576
856
  sortEnumValuesAlphabetically: { type: 'boolean' },
577
857
  sortOperationsAlphabetically: { type: 'boolean' },
578
858
  sortPropsAlphabetically: { type: 'boolean' },
579
859
  sortTagsAlphabetically: { type: 'boolean' },
860
+ suppressWarnings: { type: 'boolean' }, // deprecated
861
+ unstable_externalDescription: { type: 'boolean' }, // deprecated
580
862
  unstable_ignoreMimeParameters: { type: 'boolean' },
581
863
  untrustedDefinition: { type: 'boolean' },
582
864
  },
@@ -591,6 +873,7 @@ const ConfigMockServer: NodeType = {
591
873
  };
592
874
 
593
875
  export const ConfigTypes: Record<string, NodeType> = {
876
+ Assert,
594
877
  ConfigRoot,
595
878
  ConfigApis,
596
879
  ConfigApisProperties,
@@ -602,7 +885,9 @@ export const ConfigTypes: Record<string, NodeType> = {
602
885
  ConfigLanguage,
603
886
  ConfigLabels,
604
887
  ConfigSidebarLinks,
888
+ CommonConfigSidebarLinks,
605
889
  ConfigTheme,
890
+ Context,
606
891
  ThemeColors,
607
892
  CommonThemeColors,
608
893
  BorderThemeColors,
@@ -633,9 +918,12 @@ export const ConfigTypes: Record<string, NodeType> = {
633
918
  TokenProps,
634
919
  CodeBlock,
635
920
  Logo,
921
+ Fab,
636
922
  ButtonOverrides,
637
923
  Overrides,
924
+ ObjectRule,
638
925
  RightPanel,
926
+ Rules,
639
927
  Shape,
640
928
  ThemeSpacing,
641
929
  GenerateCodeSamples,
package/src/utils.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as fs from 'fs';
2
+ import { extname } from 'path';
2
3
  import * as minimatch from 'minimatch';
3
4
  import fetch from 'node-fetch';
4
5
  import * as pluralize from 'pluralize';
5
6
  import { parseYaml } from './js-yaml';
6
7
  import { UserContext } from './walk';
7
- import type { HttpResolveConfig } from './config';
8
- import { env } from "./config";
8
+ import { HttpResolveConfig } from './config';
9
+ import { env } from './config';
9
10
 
10
11
  export { parseYaml, stringifyYaml } from './js-yaml';
11
12
 
@@ -26,9 +27,9 @@ export function popStack<T, P extends Stack<T>>(head: P) {
26
27
 
27
28
  export type BundleOutputFormat = 'json' | 'yml' | 'yaml';
28
29
 
29
- export async function loadYaml(filename: string) {
30
+ export async function loadYaml<T>(filename: string): Promise<T> {
30
31
  const contents = await fs.promises.readFile(filename, 'utf-8');
31
- return parseYaml(contents);
32
+ return parseYaml(contents) as T;
32
33
  }
33
34
 
34
35
  export function notUndefined<T>(x: T | undefined): x is T {
@@ -77,16 +78,16 @@ function match(url: string, pattern: string) {
77
78
 
78
79
  export function pickObjectProps<T extends Record<string, unknown>>(
79
80
  object: T,
80
- keys: Array<string>,
81
+ keys: Array<string>
81
82
  ): T {
82
83
  return Object.fromEntries(
83
- keys.filter((key: string) => key in object).map((key: string) => [key, object[key]]),
84
+ keys.filter((key: string) => key in object).map((key: string) => [key, object[key]])
84
85
  ) as T;
85
86
  }
86
87
 
87
88
  export function omitObjectProps<T extends Record<string, unknown>>(
88
89
  object: T,
89
- keys: Array<string>,
90
+ keys: Array<string>
90
91
  ): T {
91
92
  return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))) as T;
92
93
  }
@@ -106,7 +107,7 @@ export function splitCamelCaseIntoWords(str: string) {
106
107
  export function validateMimeType(
107
108
  { type, value }: any,
108
109
  { report, location }: UserContext,
109
- allowedValues: string[],
110
+ allowedValues: string[]
110
111
  ) {
111
112
  const ruleType = type === 'consumes' ? 'request' : 'response';
112
113
  if (!allowedValues)
@@ -126,7 +127,7 @@ export function validateMimeType(
126
127
  export function validateMimeTypeOAS3(
127
128
  { type, value }: any,
128
129
  { report, location }: UserContext,
129
- allowedValues: string[],
130
+ allowedValues: string[]
130
131
  ) {
131
132
  const ruleType = type === 'consumes' ? 'request' : 'response';
132
133
  if (!allowedValues)
@@ -155,14 +156,13 @@ export function isPathParameter(pathSegment: string) {
155
156
  return pathSegment.startsWith('{') && pathSegment.endsWith('}');
156
157
  }
157
158
 
158
-
159
159
  /**
160
160
  * Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
161
161
  */
162
- export function slash(path: string): string {
163
- const isExtendedLengthPath = /^\\\\\?\\/.test(path)
162
+ export function slash(path: string): string {
163
+ const isExtendedLengthPath = /^\\\\\?\\/.test(path);
164
164
  if (isExtendedLengthPath) {
165
- return path
165
+ return path;
166
166
  }
167
167
 
168
168
  return path.replace(/\\/g, '/');
@@ -189,5 +189,18 @@ export function assignExisting<T>(target: Record<string, T>, obj: Record<string,
189
189
  }
190
190
  }
191
191
 
192
- export const getMatchingStatusCodeRange = (code: number | string): string =>
193
- `${code}`.replace(/^(\d)\d\d$/, (_, firstDigit) => `${firstDigit}XX`);
192
+ export function getMatchingStatusCodeRange(code: number | string): string {
193
+ return `${code}`.replace(/^(\d)\d\d$/, (_, firstDigit) => `${firstDigit}XX`);
194
+ }
195
+
196
+ export function isCustomRuleId(id: string) {
197
+ return id.includes('/');
198
+ }
199
+
200
+ export function doesYamlFileExist(filePath: string): boolean {
201
+ return (
202
+ (extname(filePath) === '.yaml' || extname(filePath) === '.yml') &&
203
+ fs.hasOwnProperty('existsSync') &&
204
+ fs.existsSync(filePath)
205
+ );
206
+ }