@redocly/openapi-core 1.0.0-beta.63 → 1.0.0-beta.67
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/__tests__/lint.test.ts +17 -0
- package/lib/config/all.js +9 -1
- package/lib/config/config.js +1 -1
- package/lib/config/minimal.js +1 -0
- package/lib/config/recommended.js +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -1
- package/lib/oas-types.js +3 -0
- package/lib/rules/builtin.d.ts +6 -0
- package/lib/rules/common/info-description-override.d.ts +2 -0
- package/lib/rules/common/info-description-override.js +24 -0
- package/lib/rules/common/info-license-url.js +1 -0
- package/lib/rules/common/no-http-verbs-in-paths.d.ts +2 -0
- package/lib/rules/common/no-http-verbs-in-paths.js +33 -0
- package/lib/rules/common/operation-4xx-response.d.ts +2 -0
- package/lib/rules/common/operation-4xx-response.js +17 -0
- package/lib/rules/common/operation-description-override.d.ts +2 -0
- package/lib/rules/common/operation-description-override.js +29 -0
- package/lib/rules/common/path-excludes-patterns.d.ts +2 -0
- package/lib/rules/common/path-excludes-patterns.js +22 -0
- package/lib/rules/common/path-segment-plural.d.ts +2 -0
- package/lib/rules/common/path-segment-plural.js +32 -0
- package/lib/rules/common/tag-description-override.d.ts +2 -0
- package/lib/rules/common/tag-description-override.js +25 -0
- package/lib/rules/oas2/index.d.ts +9 -0
- package/lib/rules/oas2/index.js +18 -0
- package/lib/rules/oas2/request-mime-type.d.ts +2 -0
- package/lib/rules/oas2/request-mime-type.js +17 -0
- package/lib/rules/oas2/response-mime-type.d.ts +2 -0
- package/lib/rules/oas2/response-mime-type.js +17 -0
- package/lib/rules/oas3/index.d.ts +3 -0
- package/lib/rules/oas3/index.js +19 -1
- package/lib/rules/oas3/request-mime-type.d.ts +2 -0
- package/lib/rules/oas3/request-mime-type.js +31 -0
- package/lib/rules/oas3/response-mime-type.d.ts +2 -0
- package/lib/rules/oas3/response-mime-type.js +31 -0
- package/lib/types/oas3_1.js +6 -0
- package/lib/types/redocly-yaml.js +332 -21
- package/lib/utils.d.ts +13 -0
- package/lib/utils.js +77 -1
- package/package.json +4 -2
- package/src/__tests__/lint.test.ts +13 -0
- package/src/__tests__/utils.test.ts +74 -0
- package/src/config/all.ts +9 -1
- package/src/config/config.ts +2 -2
- package/src/config/minimal.ts +1 -0
- package/src/config/recommended.ts +1 -0
- package/src/index.ts +1 -1
- package/src/oas-types.ts +4 -0
- package/src/rules/common/__tests__/info-license.test.ts +1 -1
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +108 -0
- package/src/rules/common/info-description-override.ts +24 -0
- package/src/rules/common/info-license-url.ts +1 -0
- package/src/rules/common/no-http-verbs-in-paths.ts +36 -0
- package/src/rules/common/operation-4xx-response.ts +17 -0
- package/src/rules/common/operation-description-override.ts +30 -0
- package/src/rules/common/path-excludes-patterns.ts +23 -0
- package/src/rules/common/path-segment-plural.ts +31 -0
- package/src/rules/common/tag-description-override.ts +25 -0
- package/src/rules/oas2/index.ts +18 -0
- package/src/rules/oas2/request-mime-type.ts +17 -0
- package/src/rules/oas2/response-mime-type.ts +17 -0
- package/src/rules/oas3/index.ts +20 -3
- package/src/rules/oas3/request-mime-type.ts +31 -0
- package/src/rules/oas3/response-mime-type.ts +31 -0
- package/src/rules/utils.ts +1 -1
- package/src/types/oas3_1.ts +7 -0
- package/src/types/redocly-yaml.ts +434 -22
- package/src/utils.ts +95 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConfigTypes = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
5
6
|
const ConfigRoot = {
|
|
6
7
|
properties: {
|
|
7
8
|
apiDefinitions: {
|
|
8
9
|
type: 'object',
|
|
9
10
|
properties: {},
|
|
10
|
-
additionalProperties: { properties: { type: 'string' } }
|
|
11
|
+
additionalProperties: { properties: { type: 'string' } },
|
|
11
12
|
},
|
|
12
13
|
lint: 'ConfigLint',
|
|
13
14
|
referenceDocs: 'ConfigReferenceDocs',
|
|
@@ -87,25 +88,297 @@ const ConfigSidebarLinks = {
|
|
|
87
88
|
target: { type: 'string' },
|
|
88
89
|
},
|
|
89
90
|
};
|
|
91
|
+
const CommonThemeColors = {
|
|
92
|
+
properties: {
|
|
93
|
+
main: { type: 'string' },
|
|
94
|
+
light: { type: 'string' },
|
|
95
|
+
dark: { type: 'string' },
|
|
96
|
+
contrastText: { type: 'string' },
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const CommonColorProps = {
|
|
100
|
+
properties: {
|
|
101
|
+
backgroundColor: { type: 'string' },
|
|
102
|
+
borderColor: { type: 'string' },
|
|
103
|
+
color: { type: 'string' },
|
|
104
|
+
tabTextColor: { type: 'string' },
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const BorderThemeColors = {
|
|
108
|
+
properties: utils_1.pickObjectProps(CommonThemeColors.properties, ['light', 'dark']),
|
|
109
|
+
};
|
|
110
|
+
const HttpColors = {
|
|
111
|
+
properties: {
|
|
112
|
+
basic: { type: 'string' },
|
|
113
|
+
delete: { type: 'string' },
|
|
114
|
+
get: { type: 'string' },
|
|
115
|
+
head: { type: 'string' },
|
|
116
|
+
link: { type: 'string' },
|
|
117
|
+
options: { type: 'string' },
|
|
118
|
+
patch: { type: 'string' },
|
|
119
|
+
post: { type: 'string' },
|
|
120
|
+
put: { type: 'string' },
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
const ResponseColors = {
|
|
124
|
+
properties: {
|
|
125
|
+
errors: 'CommonColorProps',
|
|
126
|
+
info: 'CommonColorProps',
|
|
127
|
+
redirect: 'CommonColorProps',
|
|
128
|
+
success: 'CommonColorProps',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
const SecondaryColors = {
|
|
132
|
+
properties: utils_1.omitObjectProps(CommonThemeColors.properties, ['dark']),
|
|
133
|
+
};
|
|
134
|
+
const TextThemeColors = {
|
|
135
|
+
properties: {
|
|
136
|
+
primary: { type: 'string' },
|
|
137
|
+
secondary: { type: 'string' },
|
|
138
|
+
light: { type: 'string' },
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
const ThemeColors = {
|
|
142
|
+
properties: {
|
|
143
|
+
accent: 'CommonThemeColors',
|
|
144
|
+
border: 'BorderThemeColors',
|
|
145
|
+
error: 'CommonThemeColors',
|
|
146
|
+
http: 'HttpColors',
|
|
147
|
+
primary: 'CommonThemeColors',
|
|
148
|
+
responses: 'ResponseColors',
|
|
149
|
+
secondary: 'SecondaryColors',
|
|
150
|
+
success: 'CommonThemeColors',
|
|
151
|
+
text: 'TextThemeColors',
|
|
152
|
+
tonalOffset: { type: 'number' },
|
|
153
|
+
warning: 'CommonThemeColors',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
const SizeProps = {
|
|
157
|
+
properties: {
|
|
158
|
+
fontSize: { type: 'string' },
|
|
159
|
+
padding: { type: 'string' },
|
|
160
|
+
minWidth: { type: 'string' },
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
const Sizes = {
|
|
164
|
+
properties: {
|
|
165
|
+
small: 'SizeProps',
|
|
166
|
+
medium: 'SizeProps',
|
|
167
|
+
large: 'SizeProps',
|
|
168
|
+
xlarge: 'SizeProps',
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
const FontConfig = {
|
|
172
|
+
properties: {
|
|
173
|
+
fontFamily: { type: 'string' },
|
|
174
|
+
fontSize: { type: 'string' },
|
|
175
|
+
fontWeight: { type: 'string' },
|
|
176
|
+
lineHeight: { type: 'string' },
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
const ButtonsConfig = {
|
|
180
|
+
properties: Object.assign(Object.assign({}, utils_1.omitObjectProps(FontConfig.properties, ['fontSize', 'lineHeight'])), { borderRadius: { type: 'string' }, hoverStyle: { type: 'string' }, boxShadow: { type: 'string' }, hoverBoxShadow: { type: 'string' }, sizes: 'Sizes' }),
|
|
181
|
+
};
|
|
182
|
+
const BadgeFontConfig = {
|
|
183
|
+
properties: utils_1.pickObjectProps(FontConfig.properties, ['fontSize', 'lineHeight']),
|
|
184
|
+
};
|
|
185
|
+
const BadgeSizes = {
|
|
186
|
+
properties: {
|
|
187
|
+
medium: 'BadgeFontConfig',
|
|
188
|
+
small: 'BadgeFontConfig',
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
const HttpBadgesConfig = {
|
|
192
|
+
properties: Object.assign(Object.assign({}, utils_1.omitObjectProps(FontConfig.properties, ['fontSize', 'lineHeight'])), { borderRadius: { type: 'string' }, color: { type: 'string' }, sizes: 'BadgeSizes' }),
|
|
193
|
+
};
|
|
194
|
+
const LabelControls = {
|
|
195
|
+
properties: {
|
|
196
|
+
top: { type: 'string' },
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
const Panels = {
|
|
200
|
+
properties: {
|
|
201
|
+
borderRadius: { type: 'string' },
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
const TryItButton = {
|
|
205
|
+
properties: {
|
|
206
|
+
fullWidth: { type: 'boolean' },
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
const Components = {
|
|
210
|
+
properties: {
|
|
211
|
+
buttons: 'ButtonsConfig',
|
|
212
|
+
httpBadges: 'HttpBadgesConfig',
|
|
213
|
+
layoutControls: 'LabelControls',
|
|
214
|
+
panels: 'Panels',
|
|
215
|
+
tryItButton: 'TryItButton',
|
|
216
|
+
tryItSendButton: 'TryItButton',
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
const Breakpoints = {
|
|
220
|
+
properties: {
|
|
221
|
+
small: { type: 'string' },
|
|
222
|
+
medium: { type: 'string' },
|
|
223
|
+
large: { type: 'string' },
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
const StackedConfig = {
|
|
227
|
+
properties: {
|
|
228
|
+
maxWidth: 'Breakpoints',
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
const ThreePanelConfig = {
|
|
232
|
+
properties: {
|
|
233
|
+
maxWidth: 'Breakpoints',
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const Layout = {
|
|
237
|
+
properties: {
|
|
238
|
+
showDarkRightPanel: { type: 'boolean' },
|
|
239
|
+
stacked: 'StackedConfig',
|
|
240
|
+
'three-panel': 'ThreePanelConfig',
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
const SchemaColorsConfig = {
|
|
244
|
+
properties: {
|
|
245
|
+
backgroundColor: { type: 'string' },
|
|
246
|
+
border: { type: 'string' },
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
const Schema = {
|
|
250
|
+
properties: {
|
|
251
|
+
breakFieldNames: { type: 'boolean' },
|
|
252
|
+
caretColor: { type: 'string' },
|
|
253
|
+
caretSize: { type: 'string' },
|
|
254
|
+
constraints: 'SchemaColorsConfig',
|
|
255
|
+
defaultDetailsWidth: { type: 'string' },
|
|
256
|
+
examples: 'SchemaColorsConfig',
|
|
257
|
+
labelsTextSize: { type: 'string' },
|
|
258
|
+
linesColor: { type: 'string' },
|
|
259
|
+
nestedBackground: { type: 'string' },
|
|
260
|
+
nestingSpacing: { type: 'string' },
|
|
261
|
+
requireLabelColor: { type: 'string' },
|
|
262
|
+
typeNameColor: { type: 'string' },
|
|
263
|
+
typeTitleColor: { type: 'string' },
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
const GroupItemsConfig = {
|
|
267
|
+
properties: {
|
|
268
|
+
subItemsColor: { type: 'string' },
|
|
269
|
+
textTransform: { type: 'string' },
|
|
270
|
+
fontWeight: { type: 'string' },
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
const Level1Items = {
|
|
274
|
+
properties: utils_1.pickObjectProps(GroupItemsConfig.properties, ['textTransform']),
|
|
275
|
+
};
|
|
276
|
+
const SpacingConfig = {
|
|
277
|
+
properties: {
|
|
278
|
+
unit: { type: 'number' },
|
|
279
|
+
paddingHorizontal: { type: 'string' },
|
|
280
|
+
paddingVertical: { type: 'string' },
|
|
281
|
+
offsetTop: { type: 'string' },
|
|
282
|
+
offsetLeft: { type: 'string' },
|
|
283
|
+
offsetNesting: { type: 'string' },
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
const Sidebar = {
|
|
287
|
+
properties: Object.assign(Object.assign({}, utils_1.omitObjectProps(FontConfig.properties, ['fontWeight', 'lineHeight'])), { activeBgColor: { type: 'string' }, activeTextColor: { type: 'string' }, backgroundColor: { type: 'string' }, borderRadius: { type: 'string' }, breakPath: { type: 'boolean' }, caretColor: { type: 'string' }, caretSize: { type: 'string' }, groupItems: 'GroupItemsConfig', level1items: 'Level1Items', rightLineColor: { type: 'string' }, separatorLabelColor: { type: 'string' }, showAtBreakpoint: { type: 'string' }, spacing: 'SpacingConfig', textColor: { type: 'string' }, width: { type: 'string' } }),
|
|
288
|
+
};
|
|
289
|
+
const Heading = {
|
|
290
|
+
properties: Object.assign(Object.assign({}, FontConfig.properties), { color: { type: 'string' }, transform: { type: 'string' } }),
|
|
291
|
+
};
|
|
292
|
+
const CodeConfig = {
|
|
293
|
+
properties: Object.assign(Object.assign({}, FontConfig.properties), { backgroundColor: { type: 'string' }, color: { type: 'string' }, wordBreak: { type: 'string' }, wrap: { type: 'boolean' } }),
|
|
294
|
+
};
|
|
295
|
+
const HeadingsConfig = {
|
|
296
|
+
properties: utils_1.omitObjectProps(FontConfig.properties, ['fontSize']),
|
|
297
|
+
};
|
|
298
|
+
const LinksConfig = {
|
|
299
|
+
properties: {
|
|
300
|
+
color: { type: 'string' },
|
|
301
|
+
hover: { type: 'string' },
|
|
302
|
+
textDecoration: { type: 'string' },
|
|
303
|
+
visited: { type: 'string' },
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
const Typography = {
|
|
307
|
+
properties: Object.assign(Object.assign({ code: 'CodeConfig', fieldName: 'FontConfig' }, utils_1.pickObjectProps(FontConfig.properties, ['fontSize', 'fontFamily'])), { fontWeightBold: { type: 'string' }, fontWeightLight: { type: 'string' }, fontWeightRegular: { type: 'string' }, heading1: 'Heading', heading2: 'Heading', heading3: 'Heading', headings: 'HeadingsConfig', lineHeight: { type: 'string' }, links: 'LinksConfig', optimizeSpeed: { type: 'boolean' }, rightPanelHeading: 'Heading', smoothing: { type: 'string' } }),
|
|
308
|
+
};
|
|
309
|
+
const TokenProps = {
|
|
310
|
+
properties: Object.assign({ color: { type: 'string' } }, utils_1.omitObjectProps(FontConfig.properties, ['fontWeight'])),
|
|
311
|
+
};
|
|
312
|
+
const CodeBlock = {
|
|
313
|
+
properties: {
|
|
314
|
+
backgroundColor: { type: 'string' },
|
|
315
|
+
borderRadius: { type: 'string' },
|
|
316
|
+
tokens: 'TokenProps',
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
const Logo = {
|
|
320
|
+
properties: {
|
|
321
|
+
gutter: { type: 'string' },
|
|
322
|
+
maxHeight: { type: 'string' },
|
|
323
|
+
maxWidth: { type: 'string' },
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
const ButtonOverrides = {
|
|
327
|
+
properties: {
|
|
328
|
+
custom: { type: 'string' },
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
const Overrides = {
|
|
332
|
+
properties: {
|
|
333
|
+
DownloadButton: 'ButtonOverrides',
|
|
334
|
+
NextSectionButton: 'ButtonOverrides',
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
const RightPanel = {
|
|
338
|
+
properties: {
|
|
339
|
+
backgroundColor: { type: 'string' },
|
|
340
|
+
panelBackgroundColor: { type: 'string' },
|
|
341
|
+
panelControlsBackgroundColor: { type: 'string' },
|
|
342
|
+
showAtBreakpoint: { type: 'string' },
|
|
343
|
+
textColor: { type: 'string' },
|
|
344
|
+
width: { type: 'string' },
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
const Shape = {
|
|
348
|
+
properties: { borderRadius: { type: 'string' } },
|
|
349
|
+
};
|
|
350
|
+
const ThemeSpacing = {
|
|
351
|
+
properties: {
|
|
352
|
+
sectionHorizontal: { type: 'number' },
|
|
353
|
+
sectionVertical: { type: 'number' },
|
|
354
|
+
unit: { type: 'number' },
|
|
355
|
+
},
|
|
356
|
+
};
|
|
90
357
|
const ConfigTheme = {
|
|
91
358
|
properties: {
|
|
92
|
-
breakpoints:
|
|
93
|
-
codeBlock:
|
|
94
|
-
colors:
|
|
95
|
-
components:
|
|
96
|
-
layout:
|
|
97
|
-
logo:
|
|
98
|
-
overrides:
|
|
99
|
-
rightPanel:
|
|
100
|
-
schema:
|
|
101
|
-
shape:
|
|
102
|
-
sidebar:
|
|
103
|
-
spacing:
|
|
104
|
-
typography:
|
|
359
|
+
breakpoints: 'Breakpoints',
|
|
360
|
+
codeBlock: 'CodeBlock',
|
|
361
|
+
colors: 'ThemeColors',
|
|
362
|
+
components: 'Components',
|
|
363
|
+
layout: 'Layout',
|
|
364
|
+
logo: 'Logo',
|
|
365
|
+
overrides: 'Overrides',
|
|
366
|
+
rightPanel: 'RightPanel',
|
|
367
|
+
schema: 'Schema',
|
|
368
|
+
shape: 'Shape',
|
|
369
|
+
sidebar: 'Sidebar',
|
|
370
|
+
spacing: 'ThemeSpacing',
|
|
371
|
+
typography: 'Typography',
|
|
105
372
|
links: { properties: { color: { type: 'string' } } },
|
|
106
373
|
codeSample: { properties: { backgroundColor: { type: 'string' } } },
|
|
107
374
|
},
|
|
108
375
|
};
|
|
376
|
+
const GenerateCodeSamples = {
|
|
377
|
+
properties: {
|
|
378
|
+
skipOptionalParameters: { type: 'boolean' },
|
|
379
|
+
languages: _1.listOf('ConfigLanguage'),
|
|
380
|
+
},
|
|
381
|
+
};
|
|
109
382
|
const ConfigReferenceDocs = {
|
|
110
383
|
properties: {
|
|
111
384
|
theme: 'ConfigTheme',
|
|
@@ -119,12 +392,7 @@ const ConfigReferenceDocs = {
|
|
|
119
392
|
expandDefaultServerVariables: { type: 'boolean' },
|
|
120
393
|
expandResponses: { type: 'string' },
|
|
121
394
|
expandSingleSchemaField: { type: 'boolean' },
|
|
122
|
-
generateCodeSamples:
|
|
123
|
-
properties: {
|
|
124
|
-
skipOptionalParameters: { type: 'boolean' },
|
|
125
|
-
languages: _1.listOf('ConfigLanguage'),
|
|
126
|
-
},
|
|
127
|
-
},
|
|
395
|
+
generateCodeSamples: 'GenerateCodeSamples',
|
|
128
396
|
generatedPayloadSamplesMaxDepth: { type: 'number' },
|
|
129
397
|
hideDownloadButton: { type: 'boolean' },
|
|
130
398
|
hideHostname: { type: 'boolean' },
|
|
@@ -138,7 +406,7 @@ const ConfigReferenceDocs = {
|
|
|
138
406
|
htmlTemplate: { type: 'string' },
|
|
139
407
|
jsonSampleExpandLevel: { type: 'string' },
|
|
140
408
|
labels: 'ConfigLabels',
|
|
141
|
-
layout: { type: '
|
|
409
|
+
layout: { type: 'string' },
|
|
142
410
|
maxDisplayedEnumValues: { type: 'number' },
|
|
143
411
|
menuToggle: { type: 'boolean' },
|
|
144
412
|
nativeScrollbars: { type: 'boolean' },
|
|
@@ -186,4 +454,47 @@ exports.ConfigTypes = {
|
|
|
186
454
|
ConfigLabels,
|
|
187
455
|
ConfigSidebarLinks,
|
|
188
456
|
ConfigTheme,
|
|
457
|
+
ThemeColors,
|
|
458
|
+
CommonThemeColors,
|
|
459
|
+
BorderThemeColors,
|
|
460
|
+
HttpColors,
|
|
461
|
+
ResponseColors,
|
|
462
|
+
SecondaryColors,
|
|
463
|
+
TextThemeColors,
|
|
464
|
+
Sizes,
|
|
465
|
+
ButtonsConfig,
|
|
466
|
+
CommonColorProps,
|
|
467
|
+
BadgeFontConfig,
|
|
468
|
+
BadgeSizes,
|
|
469
|
+
HttpBadgesConfig,
|
|
470
|
+
LabelControls,
|
|
471
|
+
Panels,
|
|
472
|
+
TryItButton,
|
|
473
|
+
Breakpoints,
|
|
474
|
+
StackedConfig,
|
|
475
|
+
ThreePanelConfig,
|
|
476
|
+
SchemaColorsConfig,
|
|
477
|
+
SizeProps,
|
|
478
|
+
Level1Items,
|
|
479
|
+
SpacingConfig,
|
|
480
|
+
FontConfig,
|
|
481
|
+
CodeConfig,
|
|
482
|
+
HeadingsConfig,
|
|
483
|
+
LinksConfig,
|
|
484
|
+
TokenProps,
|
|
485
|
+
CodeBlock,
|
|
486
|
+
Logo,
|
|
487
|
+
ButtonOverrides,
|
|
488
|
+
Overrides,
|
|
489
|
+
RightPanel,
|
|
490
|
+
Shape,
|
|
491
|
+
ThemeSpacing,
|
|
492
|
+
GenerateCodeSamples,
|
|
493
|
+
GroupItemsConfig,
|
|
494
|
+
Components,
|
|
495
|
+
Layout,
|
|
496
|
+
Schema,
|
|
497
|
+
Sidebar,
|
|
498
|
+
Heading,
|
|
499
|
+
Typography,
|
|
189
500
|
};
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HttpResolveConfig } from './config/config';
|
|
2
|
+
import { UserContext } from './walk';
|
|
2
3
|
export { parseYaml, stringifyYaml } from './js-yaml';
|
|
3
4
|
export declare type StackFrame<T> = {
|
|
4
5
|
prev: StackFrame<T> | null;
|
|
@@ -20,3 +21,15 @@ export declare function readFileFromUrl(url: string, config: HttpResolveConfig):
|
|
|
20
21
|
mimeType: any;
|
|
21
22
|
}>;
|
|
22
23
|
export declare function match(url: string, pattern: string): boolean;
|
|
24
|
+
export declare function pickObjectProps<T extends Record<string, unknown>>(object: T, keys: Array<string>): T;
|
|
25
|
+
export declare function omitObjectProps<T extends Record<string, unknown>>(object: T, keys: Array<string>): T;
|
|
26
|
+
export declare function splitCamelCaseIntoWords(str: string): Set<string>;
|
|
27
|
+
export declare function validateMimeType({ type, value }: any, { report, location }: UserContext, allowedValues: string[]): void;
|
|
28
|
+
export declare function validateMimeTypeOAS3({ type, value }: any, { report, location }: UserContext, allowedValues: string[]): void;
|
|
29
|
+
export declare function isSingular(path: string): boolean;
|
|
30
|
+
export declare function readFileAsStringSync(filePath: string): string;
|
|
31
|
+
export declare function isPathParameter(pathSegment: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
|
|
34
|
+
*/
|
|
35
|
+
export declare function slash(path: string): string;
|
package/lib/utils.js
CHANGED
|
@@ -9,10 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.match = exports.readFileFromUrl = exports.isPlainObject = exports.notUndefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
|
|
12
|
+
exports.slash = exports.isPathParameter = exports.readFileAsStringSync = exports.isSingular = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.match = exports.readFileFromUrl = exports.isPlainObject = exports.notUndefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
|
|
13
13
|
const fs = require("fs");
|
|
14
14
|
const minimatch = require("minimatch");
|
|
15
15
|
const node_fetch_1 = require("node-fetch");
|
|
16
|
+
const pluralize = require("pluralize");
|
|
16
17
|
const js_yaml_1 = require("./js-yaml");
|
|
17
18
|
var js_yaml_2 = require("./js-yaml");
|
|
18
19
|
Object.defineProperty(exports, "parseYaml", { enumerable: true, get: function () { return js_yaml_2.parseYaml; } });
|
|
@@ -68,3 +69,78 @@ function match(url, pattern) {
|
|
|
68
69
|
return minimatch(url, pattern);
|
|
69
70
|
}
|
|
70
71
|
exports.match = match;
|
|
72
|
+
function pickObjectProps(object, keys) {
|
|
73
|
+
return Object.fromEntries(keys.filter((key) => key in object).map((key) => [key, object[key]]));
|
|
74
|
+
}
|
|
75
|
+
exports.pickObjectProps = pickObjectProps;
|
|
76
|
+
function omitObjectProps(object, keys) {
|
|
77
|
+
return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key)));
|
|
78
|
+
}
|
|
79
|
+
exports.omitObjectProps = omitObjectProps;
|
|
80
|
+
function splitCamelCaseIntoWords(str) {
|
|
81
|
+
const camel = str
|
|
82
|
+
.split(/(?:[-._])|([A-Z][a-z]+)/)
|
|
83
|
+
.filter(Boolean)
|
|
84
|
+
.map((item) => item.toLocaleLowerCase());
|
|
85
|
+
const caps = str
|
|
86
|
+
.split(/([A-Z]{2,})/)
|
|
87
|
+
.filter((e) => e && e === e.toUpperCase())
|
|
88
|
+
.map((item) => item.toLocaleLowerCase());
|
|
89
|
+
return new Set([...camel, ...caps]);
|
|
90
|
+
}
|
|
91
|
+
exports.splitCamelCaseIntoWords = splitCamelCaseIntoWords;
|
|
92
|
+
function validateMimeType({ type, value }, { report, location }, allowedValues) {
|
|
93
|
+
const ruleType = type === 'consumes' ? 'request' : 'response';
|
|
94
|
+
if (!allowedValues)
|
|
95
|
+
throw new Error(`Parameter "allowedValues" is not provided for "${ruleType}-mime-type" rule`);
|
|
96
|
+
if (!value[type])
|
|
97
|
+
return;
|
|
98
|
+
for (const mime of value[type]) {
|
|
99
|
+
if (!allowedValues.includes(mime)) {
|
|
100
|
+
report({
|
|
101
|
+
message: `Mime type "${mime}" is not allowed`,
|
|
102
|
+
location: location.child(value[type].indexOf(mime)).key(),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.validateMimeType = validateMimeType;
|
|
108
|
+
function validateMimeTypeOAS3({ type, value }, { report, location }, allowedValues) {
|
|
109
|
+
const ruleType = type === 'consumes' ? 'request' : 'response';
|
|
110
|
+
if (!allowedValues)
|
|
111
|
+
throw new Error(`Parameter "allowedValues" is not provided for "${ruleType}-mime-type" rule`);
|
|
112
|
+
if (!value.content)
|
|
113
|
+
return;
|
|
114
|
+
for (const mime of Object.keys(value.content)) {
|
|
115
|
+
if (!allowedValues.includes(mime)) {
|
|
116
|
+
report({
|
|
117
|
+
message: `Mime type "${mime}" is not allowed`,
|
|
118
|
+
location: location.child('content').child(mime).key(),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.validateMimeTypeOAS3 = validateMimeTypeOAS3;
|
|
124
|
+
function isSingular(path) {
|
|
125
|
+
return pluralize.isSingular(path);
|
|
126
|
+
}
|
|
127
|
+
exports.isSingular = isSingular;
|
|
128
|
+
function readFileAsStringSync(filePath) {
|
|
129
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
130
|
+
}
|
|
131
|
+
exports.readFileAsStringSync = readFileAsStringSync;
|
|
132
|
+
function isPathParameter(pathSegment) {
|
|
133
|
+
return pathSegment.startsWith('{') && pathSegment.endsWith('{');
|
|
134
|
+
}
|
|
135
|
+
exports.isPathParameter = isPathParameter;
|
|
136
|
+
/**
|
|
137
|
+
* Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
|
|
138
|
+
*/
|
|
139
|
+
function slash(path) {
|
|
140
|
+
const isExtendedLengthPath = /^\\\\\?\\/.test(path);
|
|
141
|
+
if (isExtendedLengthPath) {
|
|
142
|
+
return path;
|
|
143
|
+
}
|
|
144
|
+
return path.replace(/\\/g, '/');
|
|
145
|
+
}
|
|
146
|
+
exports.slash = slash;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/openapi-core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.67",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"engines": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"Andriy Leliv <andriy@redoc.ly> (https://redoc.ly/)"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@redocly/ajv": "^8.6.
|
|
33
|
+
"@redocly/ajv": "^8.6.4",
|
|
34
34
|
"@types/node": "^14.11.8",
|
|
35
35
|
"colorette": "^1.2.0",
|
|
36
36
|
"js-levenshtein": "^1.1.6",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"lodash.isequal": "^4.5.0",
|
|
39
39
|
"minimatch": "^3.0.4",
|
|
40
40
|
"node-fetch": "^2.6.1",
|
|
41
|
+
"pluralize": "^8.0.0",
|
|
41
42
|
"yaml-ast-parser": "0.0.43"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"@types/lodash.isequal": "^4.5.5",
|
|
47
48
|
"@types/minimatch": "^3.0.3",
|
|
48
49
|
"@types/node-fetch": "^2.5.7",
|
|
50
|
+
"@types/pluralize": "^0.0.29",
|
|
49
51
|
"typescript": "^4.0.5"
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -87,6 +87,19 @@ describe('lint', () => {
|
|
|
87
87
|
"severity": "error",
|
|
88
88
|
"suggest": Array [],
|
|
89
89
|
},
|
|
90
|
+
Object {
|
|
91
|
+
"location": Array [
|
|
92
|
+
Object {
|
|
93
|
+
"pointer": "#/referenceDocs/layout",
|
|
94
|
+
"reportOnKey": false,
|
|
95
|
+
"source": "",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
"message": "Expected type \`string\` but got \`object\`.",
|
|
99
|
+
"ruleId": "spec",
|
|
100
|
+
"severity": "error",
|
|
101
|
+
"suggest": Array [],
|
|
102
|
+
},
|
|
90
103
|
]
|
|
91
104
|
`);
|
|
92
105
|
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { pickObjectProps, omitObjectProps, slash } from '../utils';
|
|
2
|
+
|
|
3
|
+
describe('utils', () => {
|
|
4
|
+
const testObject = {
|
|
5
|
+
a: 'value a',
|
|
6
|
+
b: 'value b',
|
|
7
|
+
c: 'value c',
|
|
8
|
+
d: 'value d',
|
|
9
|
+
e: 'value e',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('pickObjectProps', () => {
|
|
13
|
+
it('returns correct object result', () => {
|
|
14
|
+
expect(pickObjectProps(testObject, ['a', 'b'])).toStrictEqual({ a: 'value a', b: 'value b' });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns correct object if passed non existing key', () => {
|
|
18
|
+
expect(pickObjectProps(testObject, ['a', 'b', 'nonExisting'])).toStrictEqual({
|
|
19
|
+
a: 'value a',
|
|
20
|
+
b: 'value b',
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns an empty object if no keys are passed', () => {
|
|
25
|
+
expect(pickObjectProps(testObject, [])).toStrictEqual({});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('returns an empty object if empty target obj passed', () => {
|
|
29
|
+
expect(pickObjectProps({}, ['d', 'e'])).toStrictEqual({});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('omitObjectProps', () => {
|
|
34
|
+
it('returns correct object result', () => {
|
|
35
|
+
expect(omitObjectProps(testObject, ['a', 'b', 'c'])).toStrictEqual({
|
|
36
|
+
d: 'value d',
|
|
37
|
+
e: 'value e',
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('returns correct object if passed non existing key', () => {
|
|
42
|
+
expect(omitObjectProps(testObject, ['a', 'b', 'c', 'nonExisting'])).toStrictEqual({
|
|
43
|
+
d: 'value d',
|
|
44
|
+
e: 'value e',
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('returns full object if no keys are passed', () => {
|
|
49
|
+
expect(omitObjectProps(testObject, [])).toStrictEqual(testObject);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('returns an empty object if empty target obj passed', () => {
|
|
53
|
+
expect(omitObjectProps({}, ['d', 'e'])).toStrictEqual({});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('slash path', () => {
|
|
58
|
+
it('can correctly slash path', () => {
|
|
59
|
+
[
|
|
60
|
+
['foo\\bar', 'foo/bar'],
|
|
61
|
+
['foo/bar', 'foo/bar'],
|
|
62
|
+
['foo\\中文', 'foo/中文'],
|
|
63
|
+
['foo/中文', 'foo/中文'],
|
|
64
|
+
].forEach(([path, expectRes]) => {
|
|
65
|
+
expect(slash(path)).toBe(expectRes);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('does not modify extended length paths', () => {
|
|
70
|
+
const extended = '\\\\?\\some\\path';
|
|
71
|
+
expect(slash(extended)).toBe(extended);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
package/src/config/all.ts
CHANGED
|
@@ -12,11 +12,13 @@ export default {
|
|
|
12
12
|
'no-identical-paths': 'error',
|
|
13
13
|
'no-ambiguous-paths': 'error',
|
|
14
14
|
'no-path-trailing-slash': 'error',
|
|
15
|
+
'path-segment-plural': 'error',
|
|
15
16
|
'path-declaration-must-exist': 'error',
|
|
16
17
|
'path-not-include-query': 'error',
|
|
17
18
|
'path-parameters-defined': 'error',
|
|
18
19
|
'operation-description': 'error',
|
|
19
20
|
'operation-2xx-response': 'error',
|
|
21
|
+
'operation-4xx-response': 'error',
|
|
20
22
|
'operation-operationId': 'error',
|
|
21
23
|
'operation-summary': 'error',
|
|
22
24
|
'operation-operationId-unique': 'error',
|
|
@@ -29,6 +31,12 @@ export default {
|
|
|
29
31
|
'no-enum-type-mismatch': 'error',
|
|
30
32
|
'boolean-parameter-prefixes': 'error',
|
|
31
33
|
'paths-kebab-case': 'error',
|
|
34
|
+
'no-http-verbs-in-paths': 'error',
|
|
35
|
+
'path-excludes-patterns': {
|
|
36
|
+
severity: 'error',
|
|
37
|
+
patterns: [],
|
|
38
|
+
},
|
|
39
|
+
'request-mime-type': 'error',
|
|
32
40
|
spec: 'error',
|
|
33
41
|
},
|
|
34
42
|
oas3_0Rules: {
|
|
@@ -49,5 +57,5 @@ export default {
|
|
|
49
57
|
'no-unused-components': 'error',
|
|
50
58
|
'no-undefined-server-variable': 'error',
|
|
51
59
|
'no-servers-empty-enum': 'error',
|
|
52
|
-
}
|
|
60
|
+
},
|
|
53
61
|
} as LintRawConfig;
|
package/src/config/config.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { dirname } from 'path';
|
|
|
4
4
|
import { red, blue } from 'colorette';
|
|
5
5
|
|
|
6
6
|
import { parseYaml, stringifyYaml } from '../js-yaml';
|
|
7
|
-
import { notUndefined } from '../utils';
|
|
7
|
+
import { notUndefined, slash } from '../utils';
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
OasVersion,
|
|
@@ -211,7 +211,7 @@ export class LintConfig {
|
|
|
211
211
|
const ignoreFile = path.join(dir, IGNORE_FILE);
|
|
212
212
|
const mapped: Record<string, any> = {};
|
|
213
213
|
for (const absFileName of Object.keys(this.ignore)) {
|
|
214
|
-
const ignoredRules = (mapped[path.relative(dir, absFileName)] = this.ignore[absFileName]);
|
|
214
|
+
const ignoredRules = (mapped[slash(path.relative(dir, absFileName))] = this.ignore[absFileName]);
|
|
215
215
|
for (const ruleId of Object.keys(ignoredRules)) {
|
|
216
216
|
ignoredRules[ruleId] = Array.from(ignoredRules[ruleId]) as any;
|
|
217
217
|
}
|