@redocly/openapi-core 1.8.2 → 1.9.1
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.
- package/CHANGELOG.md +16 -0
- package/lib/bundle.d.ts +1 -1
- package/lib/config/all.js +1 -0
- package/lib/config/minimal.js +1 -0
- package/lib/config/recommended-strict.js +1 -0
- package/lib/config/recommended.js +1 -0
- package/lib/lint.d.ts +1 -0
- package/lib/lint.js +1 -1
- package/lib/oas-types.d.ts +1 -1
- package/lib/ref-utils.js +4 -4
- package/lib/resolve.js +9 -1
- package/lib/rules/common/no-required-schema-properties-undefined.d.ts +2 -0
- package/lib/rules/common/no-required-schema-properties-undefined.js +37 -0
- package/lib/rules/oas2/index.js +2 -0
- package/lib/rules/oas3/index.js +2 -0
- package/lib/types/index.d.ts +7 -7
- package/lib/types/json-schema-adapter.d.ts +3 -0
- package/lib/types/json-schema-adapter.js +173 -0
- package/lib/types/oas2.d.ts +3 -2
- package/lib/types/oas3.d.ts +3 -2
- package/lib/types/oas3_1.d.ts +3 -2
- package/lib/types/portal-config-schema.d.ts +5261 -52
- package/lib/types/portal-config-schema.js +71 -55
- package/lib/types/redocly-yaml.d.ts +14 -2
- package/lib/types/redocly-yaml.js +102 -39
- package/lib/types/theme-config.d.ts +819 -36
- package/lib/types/theme-config.js +67 -29
- package/lib/utils.d.ts +2 -2
- package/lib/visitors.js +1 -1
- package/lib/walk.js +7 -1
- package/package.json +1 -1
- package/src/__tests__/lint.test.ts +1218 -36
- package/src/__tests__/ref-utils.test.ts +22 -0
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +2 -0
- package/src/config/__tests__/load.test.ts +13 -13
- package/src/config/all.ts +1 -0
- package/src/config/minimal.ts +1 -0
- package/src/config/recommended-strict.ts +1 -0
- package/src/config/recommended.ts +1 -0
- package/src/decorators/oas2/remove-unused-components.ts +3 -2
- package/src/decorators/oas3/remove-unused-components.ts +3 -2
- package/src/lint.ts +2 -1
- package/src/ref-utils.ts +4 -4
- package/src/resolve.ts +13 -1
- package/src/rules/common/__tests__/no-required-schema-properties-undefined.test.ts +550 -0
- package/src/rules/common/no-required-schema-properties-undefined.ts +53 -0
- package/src/rules/oas2/index.ts +2 -0
- package/src/rules/oas3/index.ts +2 -0
- package/src/types/index.ts +7 -12
- package/src/types/json-schema-adapter.ts +217 -0
- package/src/types/oas2.ts +5 -2
- package/src/types/oas3.ts +6 -2
- package/src/types/oas3_1.ts +5 -2
- package/src/types/portal-config-schema.ts +111 -61
- package/src/types/redocly-yaml.ts +119 -43
- package/src/types/theme-config.ts +125 -27
- package/src/utils.ts +2 -2
- package/src/visitors.ts +1 -1
- package/src/walk.ts +7 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { rootRedoclyConfigSchema
|
|
2
|
-
import {
|
|
3
|
-
import { NodeType, listOf } from '.';
|
|
1
|
+
import { rootRedoclyConfigSchema } from './portal-config-schema';
|
|
2
|
+
import { listOf } from '.';
|
|
4
3
|
import { omitObjectProps, pickObjectProps, isCustomRuleId } from '../utils';
|
|
5
|
-
import {
|
|
4
|
+
import { getNodeTypesFromJSONSchema } from './json-schema-adapter';
|
|
5
|
+
|
|
6
|
+
import type { NodeType } from '.';
|
|
7
|
+
import type { JSONSchema } from 'json-schema-to-ts';
|
|
6
8
|
|
|
7
9
|
const builtInCommonRules = [
|
|
8
10
|
'spec',
|
|
@@ -48,6 +50,7 @@ const builtInCommonOASRules = [
|
|
|
48
50
|
'security-defined',
|
|
49
51
|
'spec-strict-refs',
|
|
50
52
|
'no-unresolved-refs',
|
|
53
|
+
'no-required-schema-properties-undefined',
|
|
51
54
|
] as const;
|
|
52
55
|
|
|
53
56
|
export type BuiltInCommonOASRuleId = typeof builtInCommonOASRules[number];
|
|
@@ -96,8 +99,49 @@ const builtInRules = [
|
|
|
96
99
|
|
|
97
100
|
type BuiltInRuleId = typeof builtInRules[number];
|
|
98
101
|
|
|
99
|
-
const
|
|
100
|
-
'
|
|
102
|
+
const oas2NodeTypesList = [
|
|
103
|
+
'Root',
|
|
104
|
+
'Tag',
|
|
105
|
+
'TagList',
|
|
106
|
+
'ExternalDocs',
|
|
107
|
+
'SecurityRequirement',
|
|
108
|
+
'SecurityRequirementList',
|
|
109
|
+
'Info',
|
|
110
|
+
'Contact',
|
|
111
|
+
'License',
|
|
112
|
+
'Paths',
|
|
113
|
+
'PathItem',
|
|
114
|
+
'Parameter',
|
|
115
|
+
'ParameterList',
|
|
116
|
+
'ParameterItems',
|
|
117
|
+
'Operation',
|
|
118
|
+
'Example',
|
|
119
|
+
'ExamplesMap',
|
|
120
|
+
'Examples',
|
|
121
|
+
'Header',
|
|
122
|
+
'Responses',
|
|
123
|
+
'Response',
|
|
124
|
+
'Schema',
|
|
125
|
+
'Xml',
|
|
126
|
+
'SchemaProperties',
|
|
127
|
+
'NamedSchemas',
|
|
128
|
+
'NamedResponses',
|
|
129
|
+
'NamedParameters',
|
|
130
|
+
'NamedSecuritySchemes',
|
|
131
|
+
'SecurityScheme',
|
|
132
|
+
'TagGroup',
|
|
133
|
+
'TagGroups',
|
|
134
|
+
'EnumDescriptions',
|
|
135
|
+
'Logo',
|
|
136
|
+
'XCodeSample',
|
|
137
|
+
'XCodeSampleList',
|
|
138
|
+
'XServer',
|
|
139
|
+
'XServerList',
|
|
140
|
+
] as const;
|
|
141
|
+
|
|
142
|
+
export type Oas2NodeType = typeof oas2NodeTypesList[number];
|
|
143
|
+
|
|
144
|
+
const oas3NodeTypesList = [
|
|
101
145
|
'Root',
|
|
102
146
|
'Tag',
|
|
103
147
|
'TagList',
|
|
@@ -152,12 +196,33 @@ const nodeTypesList = [
|
|
|
152
196
|
'AuthorizationCode',
|
|
153
197
|
'OAuth2Flows',
|
|
154
198
|
'SecurityScheme',
|
|
199
|
+
'TagGroup',
|
|
200
|
+
'TagGroups',
|
|
201
|
+
'EnumDescriptions',
|
|
202
|
+
'Logo',
|
|
155
203
|
'XCodeSample',
|
|
156
204
|
'XCodeSampleList',
|
|
205
|
+
'XUsePkce',
|
|
157
206
|
'WebhooksMap',
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
];
|
|
207
|
+
] as const;
|
|
208
|
+
|
|
209
|
+
export type Oas3NodeType = typeof oas3NodeTypesList[number];
|
|
210
|
+
|
|
211
|
+
const oas3_1NodeTypesList = [
|
|
212
|
+
'Root',
|
|
213
|
+
'Schema',
|
|
214
|
+
'SchemaProperties',
|
|
215
|
+
'Info',
|
|
216
|
+
'License',
|
|
217
|
+
'Components',
|
|
218
|
+
'NamedPathItems',
|
|
219
|
+
'SecurityScheme',
|
|
220
|
+
'Operation',
|
|
221
|
+
] as const;
|
|
222
|
+
|
|
223
|
+
export type Oas3_1NodeType = typeof oas3_1NodeTypesList[number];
|
|
224
|
+
|
|
225
|
+
const asyncNodeTypesList = ['Message'] as const;
|
|
161
226
|
|
|
162
227
|
const ConfigStyleguide: NodeType = {
|
|
163
228
|
properties: {
|
|
@@ -185,22 +250,13 @@ const ConfigStyleguide: NodeType = {
|
|
|
185
250
|
},
|
|
186
251
|
};
|
|
187
252
|
|
|
188
|
-
const
|
|
253
|
+
const createConfigRoot = (nodeTypes: Record<string, NodeType>): NodeType => ({
|
|
254
|
+
...nodeTypes.rootRedoclyConfigSchema,
|
|
189
255
|
properties: {
|
|
190
|
-
|
|
191
|
-
type: 'array',
|
|
192
|
-
items: { type: 'string' },
|
|
193
|
-
},
|
|
256
|
+
...nodeTypes.rootRedoclyConfigSchema.properties,
|
|
194
257
|
...ConfigStyleguide.properties,
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const ConfigRoot: NodeType = {
|
|
199
|
-
properties: {
|
|
200
|
-
...rootRedoclyConfigSchema.properties,
|
|
201
|
-
...RootConfigStyleguide.properties,
|
|
202
|
-
apis: 'ConfigApis',
|
|
203
|
-
theme: 'ConfigRootTheme',
|
|
258
|
+
apis: 'ConfigApis', // Override apis with internal format
|
|
259
|
+
theme: 'ConfigRootTheme', // Override theme with internal format
|
|
204
260
|
'features.openapi': 'ConfigReferenceDocs', // deprecated
|
|
205
261
|
'features.mockServer': 'ConfigMockServer', // deprecated
|
|
206
262
|
organization: { type: 'string' },
|
|
@@ -219,17 +275,17 @@ const ConfigRoot: NodeType = {
|
|
|
219
275
|
},
|
|
220
276
|
},
|
|
221
277
|
},
|
|
222
|
-
};
|
|
278
|
+
});
|
|
223
279
|
|
|
224
280
|
const ConfigApis: NodeType = {
|
|
225
281
|
properties: {},
|
|
226
282
|
additionalProperties: 'ConfigApisProperties',
|
|
227
283
|
};
|
|
228
284
|
|
|
229
|
-
const
|
|
285
|
+
const createConfigApisProperties = (nodeTypes: Record<string, NodeType>): NodeType => ({
|
|
286
|
+
...nodeTypes['rootRedoclyConfigSchema.apis_additionalProperties'],
|
|
230
287
|
properties: {
|
|
231
|
-
...
|
|
232
|
-
root: { type: 'string' },
|
|
288
|
+
...nodeTypes['rootRedoclyConfigSchema.apis_additionalProperties']?.properties,
|
|
233
289
|
labels: {
|
|
234
290
|
type: 'array',
|
|
235
291
|
items: {
|
|
@@ -239,7 +295,6 @@ const ConfigApisProperties: NodeType = {
|
|
|
239
295
|
...ConfigStyleguide.properties,
|
|
240
296
|
'features.openapi': 'ConfigReferenceDocs', // deprecated
|
|
241
297
|
'features.mockServer': 'ConfigMockServer', // deprecated
|
|
242
|
-
theme: 'ConfigRootTheme',
|
|
243
298
|
files: {
|
|
244
299
|
type: 'array',
|
|
245
300
|
items: {
|
|
@@ -247,8 +302,7 @@ const ConfigApisProperties: NodeType = {
|
|
|
247
302
|
},
|
|
248
303
|
},
|
|
249
304
|
},
|
|
250
|
-
|
|
251
|
-
};
|
|
305
|
+
});
|
|
252
306
|
|
|
253
307
|
const ConfigHTTP: NodeType = {
|
|
254
308
|
properties: {
|
|
@@ -261,13 +315,13 @@ const ConfigHTTP: NodeType = {
|
|
|
261
315
|
},
|
|
262
316
|
};
|
|
263
317
|
|
|
264
|
-
const
|
|
318
|
+
const createConfigRootTheme = (nodeTypes: Record<string, NodeType>): NodeType => ({
|
|
319
|
+
...nodeTypes['rootRedoclyConfigSchema.theme'],
|
|
265
320
|
properties: {
|
|
266
|
-
...
|
|
267
|
-
openapi: 'ConfigReferenceDocs',
|
|
268
|
-
mockServer: 'ConfigMockServer',
|
|
321
|
+
...nodeTypes['rootRedoclyConfigSchema.theme']?.properties,
|
|
322
|
+
openapi: 'ConfigReferenceDocs', // Override theme.openapi with internal format
|
|
269
323
|
},
|
|
270
|
-
};
|
|
324
|
+
});
|
|
271
325
|
|
|
272
326
|
const Rules: NodeType = {
|
|
273
327
|
properties: {},
|
|
@@ -301,7 +355,18 @@ const ObjectRule: NodeType = {
|
|
|
301
355
|
|
|
302
356
|
const AssertionDefinitionSubject: NodeType = {
|
|
303
357
|
properties: {
|
|
304
|
-
type: {
|
|
358
|
+
type: {
|
|
359
|
+
enum: [
|
|
360
|
+
...new Set([
|
|
361
|
+
'any',
|
|
362
|
+
...oas2NodeTypesList,
|
|
363
|
+
...oas3NodeTypesList,
|
|
364
|
+
...oas3_1NodeTypesList,
|
|
365
|
+
...asyncNodeTypesList,
|
|
366
|
+
'SpecExtension',
|
|
367
|
+
]),
|
|
368
|
+
],
|
|
369
|
+
},
|
|
305
370
|
property: (value: unknown) => {
|
|
306
371
|
if (Array.isArray(value)) {
|
|
307
372
|
return { type: 'array', items: { type: 'string' } };
|
|
@@ -862,8 +927,9 @@ const GenerateCodeSamples: NodeType = {
|
|
|
862
927
|
};
|
|
863
928
|
|
|
864
929
|
const ConfigReferenceDocs: NodeType = {
|
|
930
|
+
// TODO: partially invalid @Viacheslav
|
|
865
931
|
properties: {
|
|
866
|
-
theme: 'ConfigTheme',
|
|
932
|
+
theme: 'ConfigTheme', // TODO: deprecated @Viacheslav
|
|
867
933
|
corsProxyUrl: { type: 'string' },
|
|
868
934
|
ctrlFHijack: { type: 'boolean' },
|
|
869
935
|
defaultSampleLanguage: { type: 'string' },
|
|
@@ -994,12 +1060,22 @@ const ConfigMockServer: NodeType = {
|
|
|
994
1060
|
},
|
|
995
1061
|
};
|
|
996
1062
|
|
|
997
|
-
export const
|
|
1063
|
+
export const createConfigTypes = (extraSchemas: JSONSchema) => {
|
|
1064
|
+
// Create types based on external schemas
|
|
1065
|
+
const nodeTypes = getNodeTypesFromJSONSchema('rootRedoclyConfigSchema', extraSchemas);
|
|
1066
|
+
|
|
1067
|
+
return {
|
|
1068
|
+
...CoreConfigTypes,
|
|
1069
|
+
ConfigRoot: createConfigRoot(nodeTypes),
|
|
1070
|
+
ConfigApisProperties: createConfigApisProperties(nodeTypes),
|
|
1071
|
+
ConfigRootTheme: createConfigRootTheme(nodeTypes),
|
|
1072
|
+
...nodeTypes,
|
|
1073
|
+
};
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
const CoreConfigTypes: Record<string, NodeType> = {
|
|
998
1077
|
Assert,
|
|
999
|
-
ConfigRoot,
|
|
1000
1078
|
ConfigApis,
|
|
1001
|
-
ConfigApisProperties,
|
|
1002
|
-
RootConfigStyleguide,
|
|
1003
1079
|
ConfigStyleguide,
|
|
1004
1080
|
ConfigReferenceDocs,
|
|
1005
1081
|
ConfigMockServer,
|
|
@@ -1009,7 +1085,6 @@ export const ConfigTypes: Record<string, NodeType> = {
|
|
|
1009
1085
|
ConfigSidebarLinks,
|
|
1010
1086
|
CommonConfigSidebarLinks,
|
|
1011
1087
|
ConfigTheme,
|
|
1012
|
-
ConfigRootTheme,
|
|
1013
1088
|
AssertDefinition,
|
|
1014
1089
|
ThemeColors,
|
|
1015
1090
|
CommonThemeColors,
|
|
@@ -1059,5 +1134,6 @@ export const ConfigTypes: Record<string, NodeType> = {
|
|
|
1059
1134
|
Typography,
|
|
1060
1135
|
AssertionDefinitionAssertions,
|
|
1061
1136
|
AssertionDefinitionSubject,
|
|
1062
|
-
...PortalConfigNodeTypes,
|
|
1063
1137
|
};
|
|
1138
|
+
|
|
1139
|
+
export const ConfigTypes: Record<string, NodeType> = createConfigTypes(rootRedoclyConfigSchema);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { FromSchema } from 'json-schema-to-ts';
|
|
2
|
+
|
|
1
3
|
const logoConfigSchema = {
|
|
2
4
|
type: 'object',
|
|
3
5
|
properties: {
|
|
@@ -68,6 +70,11 @@ const markdownConfigSchema = {
|
|
|
68
70
|
items: { type: 'string' },
|
|
69
71
|
default: ['image', 'links'],
|
|
70
72
|
},
|
|
73
|
+
partialsFolders: {
|
|
74
|
+
type: 'array',
|
|
75
|
+
items: { type: 'string' },
|
|
76
|
+
default: ['_partials'],
|
|
77
|
+
},
|
|
71
78
|
lastUpdatedBlock: {
|
|
72
79
|
type: 'object',
|
|
73
80
|
properties: {
|
|
@@ -76,7 +83,7 @@ const markdownConfigSchema = {
|
|
|
76
83
|
enum: ['timeago', 'iso', 'long', 'short'],
|
|
77
84
|
default: 'timeago',
|
|
78
85
|
},
|
|
79
|
-
locale: { type: 'string'
|
|
86
|
+
locale: { type: 'string' },
|
|
80
87
|
...hideConfigSchema.properties,
|
|
81
88
|
},
|
|
82
89
|
additionalProperties: false,
|
|
@@ -187,6 +194,21 @@ const gtmAnalyticsConfigSchema = {
|
|
|
187
194
|
required: ['trackingId'],
|
|
188
195
|
} as const;
|
|
189
196
|
|
|
197
|
+
const productGoogleAnalyticsConfigSchema = {
|
|
198
|
+
type: 'object',
|
|
199
|
+
properties: {
|
|
200
|
+
includeInDevelopment: { type: 'boolean' },
|
|
201
|
+
trackingId: { type: 'string' },
|
|
202
|
+
|
|
203
|
+
conversionId: { type: 'string' },
|
|
204
|
+
floodlightId: { type: 'string' },
|
|
205
|
+
optimizeId: { type: 'string' },
|
|
206
|
+
exclude: { type: 'array', items: { type: 'string' } },
|
|
207
|
+
},
|
|
208
|
+
additionalProperties: false,
|
|
209
|
+
required: ['trackingId'],
|
|
210
|
+
} as const;
|
|
211
|
+
|
|
190
212
|
const googleAnalyticsConfigSchema = {
|
|
191
213
|
type: 'object',
|
|
192
214
|
properties: {
|
|
@@ -203,6 +225,12 @@ const googleAnalyticsConfigSchema = {
|
|
|
203
225
|
optimizeId: { type: 'string' },
|
|
204
226
|
anonymizeIp: { type: 'boolean' },
|
|
205
227
|
cookieExpires: { type: 'number' },
|
|
228
|
+
|
|
229
|
+
// All enabled tracking configs
|
|
230
|
+
trackers: {
|
|
231
|
+
type: 'object',
|
|
232
|
+
additionalProperties: productGoogleAnalyticsConfigSchema,
|
|
233
|
+
},
|
|
206
234
|
},
|
|
207
235
|
additionalProperties: false,
|
|
208
236
|
required: ['trackingId'],
|
|
@@ -224,6 +252,7 @@ const navItemSchema = {
|
|
|
224
252
|
properties: {
|
|
225
253
|
page: { type: 'string' },
|
|
226
254
|
directory: { type: 'string' },
|
|
255
|
+
disconnect: { type: 'boolean', default: false },
|
|
227
256
|
group: { type: 'string' },
|
|
228
257
|
label: { type: 'string' },
|
|
229
258
|
separator: { type: 'string' },
|
|
@@ -264,7 +293,7 @@ const productConfigSchema = {
|
|
|
264
293
|
folder: { type: 'string' },
|
|
265
294
|
},
|
|
266
295
|
additionalProperties: false,
|
|
267
|
-
required: ['name', '
|
|
296
|
+
required: ['name', 'folder'],
|
|
268
297
|
} as const;
|
|
269
298
|
|
|
270
299
|
const suggestedPageSchema = {
|
|
@@ -287,6 +316,7 @@ const catalogFilterSchema = {
|
|
|
287
316
|
titleTranslationKey: { type: 'string' },
|
|
288
317
|
property: { type: 'string' },
|
|
289
318
|
parentFilter: { type: 'string' },
|
|
319
|
+
valuesMapping: { type: 'object', additionalProperties: { type: 'string' } },
|
|
290
320
|
missingCategoryName: { type: 'string' },
|
|
291
321
|
missingCategoryNameTranslationKey: { type: 'string' },
|
|
292
322
|
options: { type: 'array', items: { type: 'string' } },
|
|
@@ -296,9 +326,9 @@ const catalogFilterSchema = {
|
|
|
296
326
|
const scorecardConfigSchema = {
|
|
297
327
|
type: 'object',
|
|
298
328
|
additionalProperties: true,
|
|
299
|
-
required: [
|
|
329
|
+
required: [],
|
|
300
330
|
properties: {
|
|
301
|
-
|
|
331
|
+
ignoreNonCompliant: { type: 'boolean', default: false },
|
|
302
332
|
teamMetadataProperty: {
|
|
303
333
|
type: 'object',
|
|
304
334
|
properties: {
|
|
@@ -314,11 +344,12 @@ const scorecardConfigSchema = {
|
|
|
314
344
|
required: ['name'],
|
|
315
345
|
properties: {
|
|
316
346
|
name: { type: 'string' },
|
|
347
|
+
color: { type: 'string' },
|
|
317
348
|
extends: { type: 'array', items: { type: 'string' } },
|
|
318
349
|
rules: {
|
|
319
350
|
type: 'object',
|
|
320
351
|
additionalProperties: {
|
|
321
|
-
type:
|
|
352
|
+
oneOf: [{ type: 'string' }, { type: 'object' }],
|
|
322
353
|
},
|
|
323
354
|
},
|
|
324
355
|
},
|
|
@@ -420,12 +451,6 @@ export const themeConfigSchema = {
|
|
|
420
451
|
},
|
|
421
452
|
additionalProperties: false,
|
|
422
453
|
},
|
|
423
|
-
seo: {
|
|
424
|
-
type: 'object',
|
|
425
|
-
properties: {
|
|
426
|
-
title: { type: 'string' },
|
|
427
|
-
},
|
|
428
|
-
},
|
|
429
454
|
scripts: {
|
|
430
455
|
type: 'object',
|
|
431
456
|
properties: {
|
|
@@ -444,7 +469,7 @@ export const themeConfigSchema = {
|
|
|
444
469
|
},
|
|
445
470
|
type: {
|
|
446
471
|
type: 'string',
|
|
447
|
-
enum: ['rating', 'sentiment', 'comment', 'reasons'],
|
|
472
|
+
enum: ['rating', 'sentiment', 'comment', 'reasons', 'mood', 'scale'],
|
|
448
473
|
default: 'sentiment',
|
|
449
474
|
},
|
|
450
475
|
settings: {
|
|
@@ -452,15 +477,27 @@ export const themeConfigSchema = {
|
|
|
452
477
|
properties: {
|
|
453
478
|
label: { type: 'string' },
|
|
454
479
|
submitText: { type: 'string' },
|
|
455
|
-
max: { type: 'number' },
|
|
456
480
|
buttonText: { type: 'string' },
|
|
457
|
-
|
|
481
|
+
component: {
|
|
482
|
+
type: 'string',
|
|
483
|
+
enum: ['radio', 'checkbox'],
|
|
484
|
+
default: 'checkbox',
|
|
485
|
+
},
|
|
458
486
|
items: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
487
|
+
leftScaleLabel: { type: 'string' },
|
|
488
|
+
rightScaleLabel: { type: 'string' },
|
|
459
489
|
reasons: {
|
|
460
490
|
type: 'object',
|
|
461
491
|
properties: {
|
|
462
|
-
|
|
463
|
-
|
|
492
|
+
hide: {
|
|
493
|
+
type: 'boolean',
|
|
494
|
+
default: false,
|
|
495
|
+
},
|
|
496
|
+
component: {
|
|
497
|
+
type: 'string',
|
|
498
|
+
enum: ['radio', 'checkbox'],
|
|
499
|
+
default: 'checkbox',
|
|
500
|
+
},
|
|
464
501
|
label: { type: 'string' },
|
|
465
502
|
items: { type: 'array', items: { type: 'string' } },
|
|
466
503
|
},
|
|
@@ -469,10 +506,16 @@ export const themeConfigSchema = {
|
|
|
469
506
|
comment: {
|
|
470
507
|
type: 'object',
|
|
471
508
|
properties: {
|
|
472
|
-
|
|
509
|
+
hide: {
|
|
510
|
+
type: 'boolean',
|
|
511
|
+
default: false,
|
|
512
|
+
},
|
|
473
513
|
label: { type: 'string' },
|
|
474
514
|
likeLabel: { type: 'string' },
|
|
475
515
|
dislikeLabel: { type: 'string' },
|
|
516
|
+
satisfiedLabel: { type: 'string' },
|
|
517
|
+
neutralLabel: { type: 'string' },
|
|
518
|
+
dissatisfiedLabel: { type: 'string' },
|
|
476
519
|
},
|
|
477
520
|
additionalProperties: false,
|
|
478
521
|
},
|
|
@@ -525,7 +568,7 @@ export const themeConfigSchema = {
|
|
|
525
568
|
nextButton: {
|
|
526
569
|
type: 'object',
|
|
527
570
|
properties: {
|
|
528
|
-
text: { type: 'string', default: 'Next to {label}' },
|
|
571
|
+
text: { type: 'string', default: 'Next to {{label}}' },
|
|
529
572
|
...hideConfigSchema.properties,
|
|
530
573
|
},
|
|
531
574
|
additionalProperties: false,
|
|
@@ -534,7 +577,7 @@ export const themeConfigSchema = {
|
|
|
534
577
|
previousButton: {
|
|
535
578
|
type: 'object',
|
|
536
579
|
properties: {
|
|
537
|
-
text: { type: 'string', default: 'Back to {label}' },
|
|
580
|
+
text: { type: 'string', default: 'Back to {{label}}' },
|
|
538
581
|
...hideConfigSchema.properties,
|
|
539
582
|
},
|
|
540
583
|
additionalProperties: false,
|
|
@@ -547,7 +590,7 @@ export const themeConfigSchema = {
|
|
|
547
590
|
codeSnippet: {
|
|
548
591
|
type: 'object',
|
|
549
592
|
properties: {
|
|
550
|
-
|
|
593
|
+
elementFormat: { type: 'string', default: 'icon' },
|
|
551
594
|
copy: {
|
|
552
595
|
type: 'object',
|
|
553
596
|
properties: {
|
|
@@ -559,10 +602,13 @@ export const themeConfigSchema = {
|
|
|
559
602
|
report: {
|
|
560
603
|
type: 'object',
|
|
561
604
|
properties: {
|
|
605
|
+
tooltipText: { type: 'string' },
|
|
606
|
+
buttonText: { type: 'string' },
|
|
607
|
+
label: { type: 'string' },
|
|
562
608
|
...hideConfigSchema.properties,
|
|
563
609
|
},
|
|
564
610
|
additionalProperties: false,
|
|
565
|
-
default: { hide:
|
|
611
|
+
default: { hide: false },
|
|
566
612
|
},
|
|
567
613
|
expand: {
|
|
568
614
|
type: 'object',
|
|
@@ -585,7 +631,7 @@ export const themeConfigSchema = {
|
|
|
585
631
|
default: {},
|
|
586
632
|
},
|
|
587
633
|
markdown: markdownConfigSchema,
|
|
588
|
-
openapi: { type: 'object', additionalProperties: true },
|
|
634
|
+
openapi: { type: 'object', additionalProperties: true }, // TODO: put the real schema here @Viacheslav
|
|
589
635
|
graphql: { type: 'object', additionalProperties: true },
|
|
590
636
|
analytics: {
|
|
591
637
|
type: 'object',
|
|
@@ -671,13 +717,65 @@ export const productThemeOverrideSchema = {
|
|
|
671
717
|
search: themeConfigSchema.properties.search,
|
|
672
718
|
codeSnippet: themeConfigSchema.properties.codeSnippet,
|
|
673
719
|
breadcrumbs: themeConfigSchema.properties.breadcrumbs,
|
|
720
|
+
analytics: {
|
|
721
|
+
type: 'object',
|
|
722
|
+
properties: {
|
|
723
|
+
ga: productGoogleAnalyticsConfigSchema,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
674
726
|
},
|
|
675
727
|
additionalProperties: true,
|
|
676
728
|
default: {},
|
|
677
729
|
} as const;
|
|
678
730
|
|
|
679
|
-
export
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
731
|
+
export type ThemeConfig = FromSchema<typeof themeConfigSchema>;
|
|
732
|
+
|
|
733
|
+
// TODO: cannot export as it relies on external types
|
|
734
|
+
// export type ThemeUIConfig = ThemeConfig & {
|
|
735
|
+
// auth?: {
|
|
736
|
+
// // used by portal dev login emulator
|
|
737
|
+
// idpsInfo?: {
|
|
738
|
+
// idpId: string;
|
|
739
|
+
// type: string; // AuthProviderType
|
|
740
|
+
// title: string | undefined;
|
|
741
|
+
// }[];
|
|
742
|
+
// devLogin?: boolean;
|
|
743
|
+
// loginUrls?: Record<string, string>;
|
|
744
|
+
// };
|
|
745
|
+
// search?: {
|
|
746
|
+
// shortcuts?: string[];
|
|
747
|
+
// suggestedPages?: any[];
|
|
748
|
+
// };
|
|
749
|
+
// breadcrumbs?: {
|
|
750
|
+
// prefixItems?: ResolvedNavLinkItem[];
|
|
751
|
+
// };
|
|
752
|
+
// products?: {
|
|
753
|
+
// [key: string]: ProductUiConfig;
|
|
754
|
+
// };
|
|
755
|
+
// };
|
|
756
|
+
|
|
757
|
+
export type ProductConfig = FromSchema<typeof productConfigSchema>;
|
|
758
|
+
|
|
759
|
+
export type ProductGoogleAnalyticsConfig = FromSchema<typeof productGoogleAnalyticsConfigSchema>;
|
|
760
|
+
// TODO: cannot export as it relies on external types
|
|
761
|
+
// export type ProductThemeOverrideConfig = Pick<
|
|
762
|
+
// ThemeUIConfig,
|
|
763
|
+
// 'logo' | 'navbar' | 'footer' | 'sidebar' | 'search' | 'codeSnippet' | 'breadcrumbs'
|
|
764
|
+
// > & { analytics?: { ga?: ProductGoogleAnalyticsConfig } };
|
|
765
|
+
// export type ProductUiConfig = ProductConfig & {
|
|
766
|
+
// slug: string;
|
|
767
|
+
// link: string;
|
|
768
|
+
// [REDOCLY_TEAMS_RBAC]?: { [key: string]: string };
|
|
769
|
+
// themeOverride?: ProductThemeOverrideConfig;
|
|
770
|
+
// };
|
|
771
|
+
|
|
772
|
+
export type MarkdownConfig = FromSchema<typeof markdownConfigSchema>;
|
|
773
|
+
|
|
774
|
+
export type AmplitudeAnalyticsConfig = FromSchema<typeof amplitudeAnalyticsConfigSchema>;
|
|
775
|
+
export type RudderstackAnalyticsConfig = FromSchema<typeof rudderstackAnalyticsConfigSchema>;
|
|
776
|
+
export type SegmentAnalyticsConfig = FromSchema<typeof segmentAnalyticsConfigSchema>;
|
|
777
|
+
export type GtmAnalyticsConfig = FromSchema<typeof gtmAnalyticsConfigSchema>;
|
|
778
|
+
export type GoogleAnalyticsConfig = FromSchema<typeof googleAnalyticsConfigSchema>;
|
|
779
|
+
export type CatalogConfig = FromSchema<typeof catalogSchema>;
|
|
780
|
+
export type CatalogFilterConfig = FromSchema<typeof catalogFilterSchema>;
|
|
781
|
+
export type ScorecardConfig = FromSchema<typeof scorecardConfigSchema>;
|
package/src/utils.ts
CHANGED
|
@@ -37,11 +37,11 @@ export function isDefined<T>(x: T | undefined): x is T {
|
|
|
37
37
|
return x !== undefined;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export function isPlainObject(value: any): value is
|
|
40
|
+
export function isPlainObject(value: any): value is Record<string, unknown> {
|
|
41
41
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export function isEmptyObject(value: any): value is
|
|
44
|
+
export function isEmptyObject(value: any): value is Record<string, unknown> {
|
|
45
45
|
return isPlainObject(value) && Object.keys(value).length === 0;
|
|
46
46
|
}
|
|
47
47
|
|
package/src/visitors.ts
CHANGED
|
@@ -359,7 +359,7 @@ export function normalizeVisitors<T extends BaseVisitor>(
|
|
|
359
359
|
possibleChildren.add(from.additionalProperties);
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
|
-
if (from.items) {
|
|
362
|
+
if (from.items && typeof from.items !== 'function') {
|
|
363
363
|
if (from.items === to) {
|
|
364
364
|
addWeakFromStack(ruleConf, stack);
|
|
365
365
|
} else if (from.items.name !== undefined) {
|
package/src/walk.ts
CHANGED
|
@@ -271,8 +271,14 @@ export function walkDocument<T extends BaseVisitor>(opts: {
|
|
|
271
271
|
if (Array.isArray(resolvedNode)) {
|
|
272
272
|
const itemsType = type.items;
|
|
273
273
|
if (itemsType !== undefined) {
|
|
274
|
+
const isTypeAFunction = typeof itemsType === 'function';
|
|
274
275
|
for (let i = 0; i < resolvedNode.length; i++) {
|
|
275
|
-
|
|
276
|
+
const itemType = isTypeAFunction
|
|
277
|
+
? itemsType(resolvedNode[i], resolvedLocation.child([i]).absolutePointer)
|
|
278
|
+
: itemsType;
|
|
279
|
+
if (isNamedType(itemType)) {
|
|
280
|
+
walkNode(resolvedNode[i], itemType, resolvedLocation.child([i]), resolvedNode, i);
|
|
281
|
+
}
|
|
276
282
|
}
|
|
277
283
|
}
|
|
278
284
|
} else if (typeof resolvedNode === 'object' && resolvedNode !== null) {
|