@e22m4u/js-openapi 0.0.5
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/.c8rc +9 -0
- package/.commitlintrc +5 -0
- package/.editorconfig +13 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +6 -0
- package/.mocharc.json +4 -0
- package/.prettierrc +7 -0
- package/LICENSE +21 -0
- package/README.md +510 -0
- package/build-cjs.js +16 -0
- package/dist/cjs/index.cjs +2695 -0
- package/eslint.config.js +41 -0
- package/package.json +64 -0
- package/src/data-type/index.d.ts +1 -0
- package/src/data-type/index.js +1 -0
- package/src/data-type/infer-openapi-data-type.d.ts +30 -0
- package/src/data-type/infer-openapi-data-type.js +38 -0
- package/src/data-validation/data-format-validator-map.d.ts +13 -0
- package/src/data-validation/data-format-validator-map.js +36 -0
- package/src/data-validation/data-format-validator-map.spec.js +39 -0
- package/src/data-validation/data-format-validators.d.ts +84 -0
- package/src/data-validation/data-format-validators.js +217 -0
- package/src/data-validation/index.d.ts +3 -0
- package/src/data-validation/index.js +3 -0
- package/src/data-validation/validate-data-with-openapi-schema.d.ts +46 -0
- package/src/data-validation/validate-data-with-openapi-schema.js +1913 -0
- package/src/data-validation/validate-data-with-openapi-schema.spec.js +6953 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +1 -0
- package/src/errors/oa-data-validation-error.d.ts +6 -0
- package/src/errors/oa-data-validation-error.js +6 -0
- package/src/errors/oa-data-validation-error.spec.js +17 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +9 -0
- package/src/json-pointer/escape-json-pointer.d.ts +7 -0
- package/src/json-pointer/escape-json-pointer.js +18 -0
- package/src/json-pointer/escape-json-pointer.spec.js +36 -0
- package/src/json-pointer/index.d.ts +3 -0
- package/src/json-pointer/index.js +3 -0
- package/src/json-pointer/resolve-json-pointer.d.ts +10 -0
- package/src/json-pointer/resolve-json-pointer.js +83 -0
- package/src/json-pointer/resolve-json-pointer.spec.js +103 -0
- package/src/json-pointer/unescape-json-pointer.d.ts +8 -0
- package/src/json-pointer/unescape-json-pointer.js +18 -0
- package/src/json-pointer/unescape-json-pointer.spec.js +32 -0
- package/src/oa-document-builder.d.ts +312 -0
- package/src/oa-document-builder.js +450 -0
- package/src/oa-document-object/index.d.ts +1 -0
- package/src/oa-document-object/index.js +1 -0
- package/src/oa-document-object/validate-shallow-oa-document.d.ts +10 -0
- package/src/oa-document-object/validate-shallow-oa-document.js +209 -0
- package/src/oa-document-object/validate-shallow-oa-document.spec.js +362 -0
- package/src/oa-document-scope.d.ts +52 -0
- package/src/oa-document-scope.js +228 -0
- package/src/oa-reference-object/index.d.ts +3 -0
- package/src/oa-reference-object/index.js +3 -0
- package/src/oa-reference-object/is-oa-reference-object.d.ts +9 -0
- package/src/oa-reference-object/is-oa-reference-object.js +14 -0
- package/src/oa-reference-object/is-oa-reference-object.spec.js +19 -0
- package/src/oa-reference-object/oa-ref.d.ts +11 -0
- package/src/oa-reference-object/oa-ref.js +31 -0
- package/src/oa-reference-object/oa-ref.spec.js +56 -0
- package/src/oa-reference-object/resolve-oa-reference-object.d.ts +18 -0
- package/src/oa-reference-object/resolve-oa-reference-object.js +113 -0
- package/src/oa-reference-object/resolve-oa-reference-object.spec.js +233 -0
- package/src/oa-specification.d.ts +767 -0
- package/src/oa-specification.js +153 -0
- package/src/types.d.ts +4 -0
- package/src/utils/count-unicode.d.ts +11 -0
- package/src/utils/count-unicode.js +15 -0
- package/src/utils/index.d.ts +5 -0
- package/src/utils/index.js +5 -0
- package/src/utils/join-path.d.ts +6 -0
- package/src/utils/join-path.js +36 -0
- package/src/utils/join-path.spec.js +104 -0
- package/src/utils/normalize-path.d.ts +12 -0
- package/src/utils/normalize-path.js +22 -0
- package/src/utils/normalize-path.spec.js +56 -0
- package/src/utils/to-pascal-case.d.ts +6 -0
- package/src/utils/to-pascal-case.js +26 -0
- package/src/utils/to-pascal-case.spec.js +15 -0
- package/src/utils/to-spaced-json.d.ts +17 -0
- package/src/utils/to-spaced-json.js +27 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import {OADocumentScope} from './oa-document-scope.js';
|
|
2
|
+
import {InvalidArgumentError} from '@e22m4u/js-format';
|
|
3
|
+
import {normalizePath} from './utils/normalize-path.js';
|
|
4
|
+
import {isServiceContainer, Service} from '@e22m4u/js-service';
|
|
5
|
+
import {validateShallowOADocument} from './oa-document-object/index.js';
|
|
6
|
+
import {OPENAPI_VERSION, OAOperationMethod} from './oa-specification.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Component type.
|
|
10
|
+
*/
|
|
11
|
+
export const OAComponentType = {
|
|
12
|
+
SCHEMA: 'schema',
|
|
13
|
+
RESPONSE: 'response',
|
|
14
|
+
PARAMETER: 'parameter',
|
|
15
|
+
EXAMPLE: 'example',
|
|
16
|
+
REQUEST_BODY: 'requestBody',
|
|
17
|
+
HEADER: 'header',
|
|
18
|
+
SECURITY_SCHEME: 'securityScheme',
|
|
19
|
+
LINK: 'link',
|
|
20
|
+
CALLBACK: 'callback',
|
|
21
|
+
PATH_ITEM: 'pathItem',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Component types.
|
|
26
|
+
*/
|
|
27
|
+
export const OA_COMPONENT_TYPES = Object.values(OAComponentType);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Component type to components key map.
|
|
31
|
+
*/
|
|
32
|
+
export const OA_COMPONENT_TYPE_TO_COMPONENTS_KEY_MAP = {
|
|
33
|
+
[OAComponentType.SCHEMA]: 'schemas',
|
|
34
|
+
[OAComponentType.RESPONSE]: 'responses',
|
|
35
|
+
[OAComponentType.PARAMETER]: 'parameters',
|
|
36
|
+
[OAComponentType.EXAMPLE]: 'examples',
|
|
37
|
+
[OAComponentType.REQUEST_BODY]: 'requestBodies',
|
|
38
|
+
[OAComponentType.HEADER]: 'headers',
|
|
39
|
+
[OAComponentType.SECURITY_SCHEME]: 'securitySchemes',
|
|
40
|
+
[OAComponentType.LINK]: 'links',
|
|
41
|
+
[OAComponentType.CALLBACK]: 'callbacks',
|
|
42
|
+
[OAComponentType.PATH_ITEM]: 'pathItems',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* OpenAPI Document builder.
|
|
47
|
+
*/
|
|
48
|
+
export class OADocumentBuilder extends Service {
|
|
49
|
+
/**
|
|
50
|
+
* Document.
|
|
51
|
+
*
|
|
52
|
+
* @private
|
|
53
|
+
* @type {object}
|
|
54
|
+
*/
|
|
55
|
+
_document = {
|
|
56
|
+
openapi: OPENAPI_VERSION,
|
|
57
|
+
info: {
|
|
58
|
+
title: 'API Documentation',
|
|
59
|
+
version: '0.0.1',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Constructor.
|
|
65
|
+
*
|
|
66
|
+
* @param {object} [containerOrDocument]
|
|
67
|
+
* @param {object} [document]
|
|
68
|
+
*/
|
|
69
|
+
constructor(containerOrDocument, document) {
|
|
70
|
+
if (isServiceContainer(containerOrDocument)) {
|
|
71
|
+
super(containerOrDocument);
|
|
72
|
+
} else {
|
|
73
|
+
super();
|
|
74
|
+
document = containerOrDocument;
|
|
75
|
+
}
|
|
76
|
+
if (document !== undefined) {
|
|
77
|
+
// если схема документа не является
|
|
78
|
+
// объектом, то выбрасывается ошибка
|
|
79
|
+
if (
|
|
80
|
+
!document ||
|
|
81
|
+
typeof document !== 'object' ||
|
|
82
|
+
Array.isArray(document)
|
|
83
|
+
) {
|
|
84
|
+
throw new InvalidArgumentError(
|
|
85
|
+
'OpenAPI Document Object must be an Object, but %v was given.',
|
|
86
|
+
document,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
// чтобы избежать мутации аргумента,
|
|
90
|
+
// выполняется копирование документа
|
|
91
|
+
document = structuredClone(document);
|
|
92
|
+
// если версия OpenAPI не определена,
|
|
93
|
+
// то устанавливается версия по умолчанию
|
|
94
|
+
if (!document.openapi) {
|
|
95
|
+
document.openapi = this._document.openapi;
|
|
96
|
+
}
|
|
97
|
+
// если Info Object не определен,
|
|
98
|
+
// то устанавливается значение по умолчанию
|
|
99
|
+
if (!document.info) {
|
|
100
|
+
document.info = this._document.info;
|
|
101
|
+
}
|
|
102
|
+
// если свойство "info" не является
|
|
103
|
+
// объектом, то выбрасывается ошибка
|
|
104
|
+
if (
|
|
105
|
+
!document.info ||
|
|
106
|
+
typeof document.info !== 'object' ||
|
|
107
|
+
Array.isArray(document.info)
|
|
108
|
+
) {
|
|
109
|
+
throw new InvalidArgumentError(
|
|
110
|
+
'Property "info" must be an Object, but %v was given.',
|
|
111
|
+
document.info,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
// если свойство "info.title" не определено,
|
|
115
|
+
// то устанавливается значение по умолчанию
|
|
116
|
+
if (!document.info.title) {
|
|
117
|
+
document.info.title = this._document.info.title;
|
|
118
|
+
}
|
|
119
|
+
// если свойство "info.version" не определено,
|
|
120
|
+
// то устанавливается значение по умолчанию
|
|
121
|
+
if (!document.info.version) {
|
|
122
|
+
document.info.version = this._document.info.version;
|
|
123
|
+
}
|
|
124
|
+
// поверхностная проверка свойств документа
|
|
125
|
+
// выполняется после установки значений по умолчанию
|
|
126
|
+
validateShallowOADocument(document);
|
|
127
|
+
this._document = document;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Define component.
|
|
133
|
+
*
|
|
134
|
+
* @param {string} type
|
|
135
|
+
* @param {object} definition
|
|
136
|
+
* @returns {this}
|
|
137
|
+
*/
|
|
138
|
+
defineComponent(type, definition) {
|
|
139
|
+
// type
|
|
140
|
+
if (!OA_COMPONENT_TYPES.includes(type)) {
|
|
141
|
+
throw new InvalidArgumentError(
|
|
142
|
+
'Components type %v is not supported.',
|
|
143
|
+
type,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
// definition
|
|
147
|
+
if (
|
|
148
|
+
!definition ||
|
|
149
|
+
typeof definition !== 'object' ||
|
|
150
|
+
Array.isArray(definition)
|
|
151
|
+
) {
|
|
152
|
+
throw new InvalidArgumentError(
|
|
153
|
+
'Component definition must be an Object, but %v was given.',
|
|
154
|
+
definition,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
// definition.name
|
|
158
|
+
if (!definition.name || typeof definition.name !== 'string') {
|
|
159
|
+
throw new InvalidArgumentError(
|
|
160
|
+
'Property "name" must be a non-empty String, but %v was given.',
|
|
161
|
+
definition.name,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
// definition[type]
|
|
165
|
+
const component = definition[type];
|
|
166
|
+
if (
|
|
167
|
+
!component ||
|
|
168
|
+
typeof component !== 'object' ||
|
|
169
|
+
Array.isArray(component)
|
|
170
|
+
) {
|
|
171
|
+
throw new InvalidArgumentError(
|
|
172
|
+
'Property %v must be an Object, but %v was given.',
|
|
173
|
+
type,
|
|
174
|
+
component,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
// components key
|
|
178
|
+
const key = OA_COMPONENT_TYPE_TO_COMPONENTS_KEY_MAP[type];
|
|
179
|
+
if (!key) {
|
|
180
|
+
throw new InvalidArgumentError(
|
|
181
|
+
'Component type %v does not have a reference to the components key.',
|
|
182
|
+
type,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
this._document.components = this._document.components || {};
|
|
186
|
+
this._document.components[key] = this._document.components[key] || {};
|
|
187
|
+
this._document.components[key][definition.name] =
|
|
188
|
+
structuredClone(component);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Has component.
|
|
194
|
+
*
|
|
195
|
+
* @param {string} type
|
|
196
|
+
* @param {string} name
|
|
197
|
+
* @returns {boolean}
|
|
198
|
+
*/
|
|
199
|
+
hasComponent(type, name) {
|
|
200
|
+
// name
|
|
201
|
+
if (!name || typeof name !== 'string') {
|
|
202
|
+
throw new InvalidArgumentError(
|
|
203
|
+
'Parameter "name" must be a non-empty String, but %v was given.',
|
|
204
|
+
name,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
// components key
|
|
208
|
+
const key = OA_COMPONENT_TYPE_TO_COMPONENTS_KEY_MAP[type];
|
|
209
|
+
if (!key) {
|
|
210
|
+
throw new InvalidArgumentError(
|
|
211
|
+
'Component type %v does not have a reference to the components key.',
|
|
212
|
+
type,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
return Boolean(
|
|
216
|
+
this._document.components &&
|
|
217
|
+
this._document.components[key] &&
|
|
218
|
+
this._document.components[key][name],
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get component.
|
|
224
|
+
*
|
|
225
|
+
* @param {string} type
|
|
226
|
+
* @param {string} name
|
|
227
|
+
* @returns {object}
|
|
228
|
+
*/
|
|
229
|
+
getComponent(type, name) {
|
|
230
|
+
// name
|
|
231
|
+
if (!name || typeof name !== 'string') {
|
|
232
|
+
throw new InvalidArgumentError(
|
|
233
|
+
'Parameter "name" must be a non-empty String, but %v was given.',
|
|
234
|
+
name,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
// components key
|
|
238
|
+
const key = OA_COMPONENT_TYPE_TO_COMPONENTS_KEY_MAP[type];
|
|
239
|
+
if (!key) {
|
|
240
|
+
throw new InvalidArgumentError(
|
|
241
|
+
'Component type %v does not have a reference to the components key.',
|
|
242
|
+
type,
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
const component =
|
|
246
|
+
this._document &&
|
|
247
|
+
this._document.components &&
|
|
248
|
+
this._document.components[key] &&
|
|
249
|
+
this._document.components[key][name];
|
|
250
|
+
if (!component) {
|
|
251
|
+
throw new InvalidArgumentError(
|
|
252
|
+
'Component "#/components/%s/%s" does not exist.',
|
|
253
|
+
key,
|
|
254
|
+
name,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return component;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Define schema component.
|
|
262
|
+
*
|
|
263
|
+
* @param {object} schemaDef
|
|
264
|
+
* @returns {this}
|
|
265
|
+
*/
|
|
266
|
+
defineSchemaComponent(schemaDef) {
|
|
267
|
+
return this.defineComponent(OAComponentType.SCHEMA, schemaDef);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Define response component.
|
|
272
|
+
*
|
|
273
|
+
* @param {object} responseDef
|
|
274
|
+
* @returns {this}
|
|
275
|
+
*/
|
|
276
|
+
defineResponseComponent(responseDef) {
|
|
277
|
+
return this.defineComponent(OAComponentType.RESPONSE, responseDef);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Define parameter component.
|
|
282
|
+
*
|
|
283
|
+
* @param {object} parameterDef
|
|
284
|
+
* @returns {this}
|
|
285
|
+
*/
|
|
286
|
+
defineParameterComponent(parameterDef) {
|
|
287
|
+
return this.defineComponent(OAComponentType.PARAMETER, parameterDef);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Define example component.
|
|
292
|
+
*
|
|
293
|
+
* @param {object} exampleDef
|
|
294
|
+
* @returns {this}
|
|
295
|
+
*/
|
|
296
|
+
defineExampleComponent(exampleDef) {
|
|
297
|
+
return this.defineComponent(OAComponentType.EXAMPLE, exampleDef);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Define request body component.
|
|
302
|
+
*
|
|
303
|
+
* @param {object} requestBodyDef
|
|
304
|
+
* @returns {this}
|
|
305
|
+
*/
|
|
306
|
+
defineRequestBodyComponent(requestBodyDef) {
|
|
307
|
+
return this.defineComponent(OAComponentType.REQUEST_BODY, requestBodyDef);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Define header component.
|
|
312
|
+
*
|
|
313
|
+
* @param {object} headerDef
|
|
314
|
+
* @returns {this}
|
|
315
|
+
*/
|
|
316
|
+
defineHeaderComponent(headerDef) {
|
|
317
|
+
return this.defineComponent(OAComponentType.HEADER, headerDef);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Define security scheme component.
|
|
322
|
+
*
|
|
323
|
+
* @param {object} securitySchemeDef
|
|
324
|
+
* @returns {this}
|
|
325
|
+
*/
|
|
326
|
+
defineSecuritySchemeComponent(securitySchemeDef) {
|
|
327
|
+
return this.defineComponent(
|
|
328
|
+
OAComponentType.SECURITY_SCHEME,
|
|
329
|
+
securitySchemeDef,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Define link component.
|
|
335
|
+
*
|
|
336
|
+
* @param {object} linkDef
|
|
337
|
+
* @returns {this}
|
|
338
|
+
*/
|
|
339
|
+
defineLinkComponent(linkDef) {
|
|
340
|
+
return this.defineComponent(OAComponentType.LINK, linkDef);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Define callback component.
|
|
345
|
+
*
|
|
346
|
+
* @param {object} callbackDef
|
|
347
|
+
* @returns {this}
|
|
348
|
+
*/
|
|
349
|
+
defineCallbackComponent(callbackDef) {
|
|
350
|
+
return this.defineComponent(OAComponentType.CALLBACK, callbackDef);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Define path item component.
|
|
355
|
+
*
|
|
356
|
+
* @param {object} pathItemDef
|
|
357
|
+
* @returns {this}
|
|
358
|
+
*/
|
|
359
|
+
definePathItemComponent(pathItemDef) {
|
|
360
|
+
return this.defineComponent(OAComponentType.PATH_ITEM, pathItemDef);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Define operation.
|
|
365
|
+
*
|
|
366
|
+
* @param {object} operationDef
|
|
367
|
+
*/
|
|
368
|
+
defineOperation(operationDef) {
|
|
369
|
+
if (
|
|
370
|
+
!operationDef ||
|
|
371
|
+
typeof operationDef !== 'object' ||
|
|
372
|
+
Array.isArray(operationDef)
|
|
373
|
+
) {
|
|
374
|
+
throw new InvalidArgumentError(
|
|
375
|
+
'Operation Definition must be an Object, but %v was given.',
|
|
376
|
+
operationDef,
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
// path
|
|
380
|
+
if (!operationDef.path || typeof operationDef.path !== 'string') {
|
|
381
|
+
throw new InvalidArgumentError(
|
|
382
|
+
'Property "path" must be a non-empty String, but %v was given.',
|
|
383
|
+
operationDef.path,
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
// method
|
|
387
|
+
if (!operationDef.method || typeof operationDef.method !== 'string') {
|
|
388
|
+
throw new InvalidArgumentError(
|
|
389
|
+
'Property "method" must be a non-empty String, but %v was given.',
|
|
390
|
+
operationDef.method,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
if (!Object.values(OAOperationMethod).includes(operationDef.method)) {
|
|
394
|
+
throw new InvalidArgumentError(
|
|
395
|
+
'Property "method" must be one of values: %l, but %v was given.',
|
|
396
|
+
Object.values(OAOperationMethod),
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
// operation
|
|
400
|
+
if (
|
|
401
|
+
!operationDef.operation ||
|
|
402
|
+
typeof operationDef.operation !== 'object' ||
|
|
403
|
+
Array.isArray(operationDef.operation)
|
|
404
|
+
) {
|
|
405
|
+
throw new InvalidArgumentError(
|
|
406
|
+
'Property "operation" must be an Object, but %v was given.',
|
|
407
|
+
operationDef.operation,
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
const normalizedPath = normalizePath(operationDef.path);
|
|
411
|
+
if (!this._document.paths) {
|
|
412
|
+
this._document.paths = {};
|
|
413
|
+
}
|
|
414
|
+
if (!this._document.paths[normalizedPath]) {
|
|
415
|
+
this._document.paths[normalizedPath] = {};
|
|
416
|
+
}
|
|
417
|
+
this._document.paths[normalizedPath][operationDef.method] = structuredClone(
|
|
418
|
+
operationDef.operation,
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Create scope.
|
|
424
|
+
*
|
|
425
|
+
* @param {object} [options]
|
|
426
|
+
* @returns {OADocumentScope}
|
|
427
|
+
*/
|
|
428
|
+
createScope(options) {
|
|
429
|
+
return new OADocumentScope(this, options);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Build.
|
|
434
|
+
*
|
|
435
|
+
* @returns {object}
|
|
436
|
+
*/
|
|
437
|
+
build() {
|
|
438
|
+
return structuredClone(this._document);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Build JSON.
|
|
443
|
+
*
|
|
444
|
+
* @param {string|number} [space]
|
|
445
|
+
* @returns {string}
|
|
446
|
+
*/
|
|
447
|
+
buildJson(space = 0) {
|
|
448
|
+
return JSON.stringify(this.build(), null, space);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './validate-shallow-oa-document.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './validate-shallow-oa-document.js';
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {InvalidArgumentError} from '@e22m4u/js-format';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate shallow OADocumentObject.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} documentObject
|
|
7
|
+
*/
|
|
8
|
+
export function validateShallowOADocument(documentObject) {
|
|
9
|
+
if (
|
|
10
|
+
!documentObject ||
|
|
11
|
+
typeof documentObject !== 'object' ||
|
|
12
|
+
Array.isArray(documentObject)
|
|
13
|
+
) {
|
|
14
|
+
throw new InvalidArgumentError(
|
|
15
|
+
'OpenAPI Document Object must be an Object, but %v was given.',
|
|
16
|
+
documentObject,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
// openapi
|
|
20
|
+
if (!documentObject.openapi || typeof documentObject.openapi !== 'string') {
|
|
21
|
+
throw new InvalidArgumentError(
|
|
22
|
+
'Property "openapi" must be a non-empty String, but %v was given.',
|
|
23
|
+
documentObject.openapi,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
// info
|
|
27
|
+
if (
|
|
28
|
+
!documentObject.info ||
|
|
29
|
+
typeof documentObject.info !== 'object' ||
|
|
30
|
+
Array.isArray(documentObject.info)
|
|
31
|
+
) {
|
|
32
|
+
throw new InvalidArgumentError(
|
|
33
|
+
'Property "info" must be an Object, but %v was given.',
|
|
34
|
+
documentObject.info,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
// info.title
|
|
38
|
+
if (
|
|
39
|
+
!documentObject.info.title ||
|
|
40
|
+
typeof documentObject.info.title !== 'string'
|
|
41
|
+
) {
|
|
42
|
+
throw new InvalidArgumentError(
|
|
43
|
+
'Property "info.title" must be a non-empty String, but %v was given.',
|
|
44
|
+
documentObject.info.title,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
// info.version
|
|
48
|
+
if (
|
|
49
|
+
!documentObject.info.version ||
|
|
50
|
+
typeof documentObject.info.version !== 'string'
|
|
51
|
+
) {
|
|
52
|
+
throw new InvalidArgumentError(
|
|
53
|
+
'Property "info.version" must be a non-empty String, but %v was given.',
|
|
54
|
+
documentObject.info.version,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
// jsonSchemaDialect
|
|
58
|
+
if (documentObject.jsonSchemaDialect !== undefined) {
|
|
59
|
+
if (
|
|
60
|
+
!documentObject.jsonSchemaDialect ||
|
|
61
|
+
typeof documentObject.jsonSchemaDialect !== 'string'
|
|
62
|
+
) {
|
|
63
|
+
throw new InvalidArgumentError(
|
|
64
|
+
'Property "jsonSchemaDialect" must be a non-empty String, ' +
|
|
65
|
+
'but %v was given.',
|
|
66
|
+
documentObject.jsonSchemaDialect,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// servers
|
|
71
|
+
if (documentObject.servers !== undefined) {
|
|
72
|
+
if (!Array.isArray(documentObject.servers)) {
|
|
73
|
+
throw new InvalidArgumentError(
|
|
74
|
+
'Property "servers" must be an Array, but %v was given.',
|
|
75
|
+
documentObject.servers,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
// servers[n]
|
|
79
|
+
documentObject.servers.forEach((serverObject, index) => {
|
|
80
|
+
if (
|
|
81
|
+
!serverObject ||
|
|
82
|
+
typeof serverObject !== 'object' ||
|
|
83
|
+
Array.isArray(serverObject)
|
|
84
|
+
) {
|
|
85
|
+
throw new InvalidArgumentError(
|
|
86
|
+
'Element "servers[%d]" must be an Object, but %v was given.',
|
|
87
|
+
index,
|
|
88
|
+
serverObject,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
// servers[n].url
|
|
92
|
+
if (!serverObject.url || typeof serverObject.url !== 'string') {
|
|
93
|
+
throw new InvalidArgumentError(
|
|
94
|
+
'Property "servers[%d].url" must be a non-empty String, ' +
|
|
95
|
+
'but %v was given.',
|
|
96
|
+
index,
|
|
97
|
+
serverObject.url,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// paths
|
|
103
|
+
if (documentObject.paths !== undefined) {
|
|
104
|
+
if (
|
|
105
|
+
!documentObject.paths ||
|
|
106
|
+
typeof documentObject.paths !== 'object' ||
|
|
107
|
+
Array.isArray(documentObject.paths)
|
|
108
|
+
) {
|
|
109
|
+
throw new InvalidArgumentError(
|
|
110
|
+
'Property "paths" must be an Object, but %v was given.',
|
|
111
|
+
documentObject.paths,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// webhooks
|
|
116
|
+
if (documentObject.webhooks !== undefined) {
|
|
117
|
+
if (
|
|
118
|
+
!documentObject.webhooks ||
|
|
119
|
+
typeof documentObject.webhooks !== 'object' ||
|
|
120
|
+
Array.isArray(documentObject.webhooks)
|
|
121
|
+
) {
|
|
122
|
+
throw new InvalidArgumentError(
|
|
123
|
+
'Property "webhooks" must be an Object, but %v was given.',
|
|
124
|
+
documentObject.webhooks,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// components
|
|
129
|
+
if (documentObject.components !== undefined) {
|
|
130
|
+
if (
|
|
131
|
+
!documentObject.components ||
|
|
132
|
+
typeof documentObject.components !== 'object' ||
|
|
133
|
+
Array.isArray(documentObject.components)
|
|
134
|
+
) {
|
|
135
|
+
throw new InvalidArgumentError(
|
|
136
|
+
'Property "components" must be an Object, but %v was given.',
|
|
137
|
+
documentObject.components,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// security
|
|
142
|
+
if (documentObject.security !== undefined) {
|
|
143
|
+
if (!Array.isArray(documentObject.security)) {
|
|
144
|
+
throw new InvalidArgumentError(
|
|
145
|
+
'Property "security" must be an Array, but %v was given.',
|
|
146
|
+
documentObject.security,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
// security[n]
|
|
150
|
+
documentObject.security.forEach((securityRequirementObject, index) => {
|
|
151
|
+
if (
|
|
152
|
+
!securityRequirementObject ||
|
|
153
|
+
typeof securityRequirementObject !== 'object' ||
|
|
154
|
+
Array.isArray(securityRequirementObject)
|
|
155
|
+
) {
|
|
156
|
+
throw new InvalidArgumentError(
|
|
157
|
+
'Element "security[%d]" must be an Object, but %v was given.',
|
|
158
|
+
index,
|
|
159
|
+
securityRequirementObject,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// tags
|
|
165
|
+
if (documentObject.tags !== undefined) {
|
|
166
|
+
if (!Array.isArray(documentObject.tags)) {
|
|
167
|
+
throw new InvalidArgumentError(
|
|
168
|
+
'Property "tags" must be an Array, but %v was given.',
|
|
169
|
+
documentObject.tags,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
// tags[n]
|
|
173
|
+
documentObject.tags.forEach((tagObject, index) => {
|
|
174
|
+
if (
|
|
175
|
+
!tagObject ||
|
|
176
|
+
typeof tagObject !== 'object' ||
|
|
177
|
+
Array.isArray(tagObject)
|
|
178
|
+
) {
|
|
179
|
+
throw new InvalidArgumentError(
|
|
180
|
+
'Element "tags[%d]" must be an Object, but %v was given.',
|
|
181
|
+
index,
|
|
182
|
+
tagObject,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
// tags[n].name
|
|
186
|
+
if (!tagObject.name || typeof tagObject.name !== 'string') {
|
|
187
|
+
throw new InvalidArgumentError(
|
|
188
|
+
'Property "tags[%d].name" must be a non-empty String, ' +
|
|
189
|
+
'but %v was given.',
|
|
190
|
+
index,
|
|
191
|
+
tagObject.name,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// externalDocs
|
|
197
|
+
if (documentObject.externalDocs !== undefined) {
|
|
198
|
+
if (
|
|
199
|
+
!documentObject.externalDocs ||
|
|
200
|
+
typeof documentObject.externalDocs !== 'object' ||
|
|
201
|
+
Array.isArray(documentObject.externalDocs)
|
|
202
|
+
) {
|
|
203
|
+
throw new InvalidArgumentError(
|
|
204
|
+
'Property "externalDocs" must be an Object, but %v was given.',
|
|
205
|
+
documentObject.externalDocs,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|