@e22m4u/js-openapi 0.0.5 → 0.0.6

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 (70) hide show
  1. package/README.md +226 -146
  2. package/dist/cjs/index.cjs +2024 -2092
  3. package/package.json +10 -8
  4. package/schema/openapi-3-1/dialect/base.js +21 -0
  5. package/schema/openapi-3-1/meta/base.js +76 -0
  6. package/schema/openapi-3-1/schema-base.js +32 -0
  7. package/schema/openapi-3-1/schema.js +1403 -0
  8. package/src/ajv.js +32 -0
  9. package/src/errors/index.d.ts +1 -1
  10. package/src/errors/index.js +1 -1
  11. package/src/errors/oa-document-object-validation-error.d.ts +6 -0
  12. package/src/errors/oa-document-object-validation-error.js +6 -0
  13. package/src/errors/oa-document-object-validation-error.spec.js +10 -0
  14. package/src/index.d.ts +1 -3
  15. package/src/index.js +1 -3
  16. package/src/json-pointer/resolve-json-pointer.js +1 -1
  17. package/src/json-pointer/unescape-json-pointer.d.ts +1 -2
  18. package/src/oa-document-builder.d.ts +302 -111
  19. package/src/oa-document-builder.js +208 -142
  20. package/src/oa-document-builder.spec.js +1408 -0
  21. package/src/oa-document-object/index.d.ts +1 -1
  22. package/src/oa-document-object/index.js +1 -1
  23. package/src/oa-document-object/validate-oa-document-object.d.ts +18 -0
  24. package/src/oa-document-object/validate-oa-document-object.js +53 -0
  25. package/src/oa-document-object/validate-oa-document-object.spec.js +122 -0
  26. package/src/{oa-document-scope.d.ts → oa-operation-group.d.ts} +7 -7
  27. package/src/{oa-document-scope.js → oa-operation-group.js} +101 -46
  28. package/src/oa-operation-group.spec.js +544 -0
  29. package/src/oa-reference-object/is-oa-reference-object.js +1 -1
  30. package/src/oa-reference-object/is-oa-reference-object.spec.js +1 -1
  31. package/src/oa-reference-object/oa-ref.js +7 -0
  32. package/src/oa-reference-object/resolve-oa-reference-object.js +1 -11
  33. package/src/oa-reference-object/resolve-oa-reference-object.spec.js +0 -10
  34. package/src/oa-specification.d.ts +54 -66
  35. package/src/oa-specification.js +10 -22
  36. package/src/data-type/index.d.ts +0 -1
  37. package/src/data-type/index.js +0 -1
  38. package/src/data-type/infer-openapi-data-type.d.ts +0 -30
  39. package/src/data-type/infer-openapi-data-type.js +0 -38
  40. package/src/data-validation/data-format-validator-map.d.ts +0 -13
  41. package/src/data-validation/data-format-validator-map.js +0 -36
  42. package/src/data-validation/data-format-validator-map.spec.js +0 -39
  43. package/src/data-validation/data-format-validators.d.ts +0 -84
  44. package/src/data-validation/data-format-validators.js +0 -217
  45. package/src/data-validation/index.d.ts +0 -3
  46. package/src/data-validation/index.js +0 -3
  47. package/src/data-validation/validate-data-with-openapi-schema.d.ts +0 -46
  48. package/src/data-validation/validate-data-with-openapi-schema.js +0 -1913
  49. package/src/data-validation/validate-data-with-openapi-schema.spec.js +0 -6953
  50. package/src/errors/oa-data-validation-error.d.ts +0 -6
  51. package/src/errors/oa-data-validation-error.js +0 -6
  52. package/src/errors/oa-data-validation-error.spec.js +0 -17
  53. package/src/oa-document-object/validate-shallow-oa-document.d.ts +0 -10
  54. package/src/oa-document-object/validate-shallow-oa-document.js +0 -209
  55. package/src/oa-document-object/validate-shallow-oa-document.spec.js +0 -362
  56. package/src/utils/count-unicode.d.ts +0 -11
  57. package/src/utils/count-unicode.js +0 -15
  58. package/src/utils/index.d.ts +0 -5
  59. package/src/utils/index.js +0 -5
  60. package/src/utils/join-path.d.ts +0 -6
  61. package/src/utils/join-path.js +0 -36
  62. package/src/utils/join-path.spec.js +0 -104
  63. package/src/utils/normalize-path.d.ts +0 -12
  64. package/src/utils/normalize-path.js +0 -22
  65. package/src/utils/normalize-path.spec.js +0 -56
  66. package/src/utils/to-pascal-case.d.ts +0 -6
  67. package/src/utils/to-pascal-case.js +0 -26
  68. package/src/utils/to-pascal-case.spec.js +0 -15
  69. package/src/utils/to-spaced-json.d.ts +0 -17
  70. package/src/utils/to-spaced-json.js +0 -27
package/README.md CHANGED
@@ -1,7 +1,11 @@
1
1
  ## @e22m4u/js-openapi
2
2
 
3
3
  JavaScript модуль для создания
4
- [OpenAPI Документа 3.1.0](https://spec.openapis.org/oas/v3.1.0)
4
+ [OpenAPI Документа 3.1.2](https://spec.openapis.org/oas/v3.1.2)
5
+
6
+ Модуль автоматически проверяет структуру документа при определении компонентов
7
+ и операций. Если передать неверное поле, будет выброшена ошибка с указанием
8
+ пути.
5
9
 
6
10
  ## Содержание
7
11
 
@@ -9,8 +13,8 @@ JavaScript модуль для создания
9
13
  - [Базовый пример](#базовый-пример)
10
14
  - [Работа с компонентами](#работа-с-компонентами)
11
15
  - [Содержимое запросов и ответов](#содержимое-запросов-и-ответов)
12
- - [Группировка маршрутов](#группировка-маршрутов)
13
- - [Проверка данных](#проверка-данных)
16
+ - [Группировка операций](#группировка-операций)
17
+ - [Константы](#константы)
14
18
  - [Тесты](#тесты)
15
19
  - [Лицензия](#лицензия)
16
20
 
@@ -68,7 +72,34 @@ builder.defineOperation({
68
72
  });
69
73
  ```
70
74
 
71
- Формирование JSON документа.
75
+ Сборка документа в виде JavaScript объекта.
76
+
77
+ ```js
78
+ const oaDocumentObject = builder.build();
79
+
80
+ console.log(oaDocumentObject);
81
+ // {
82
+ // openapi: '3.1.2',
83
+ // info: {
84
+ // title: 'My Simple API',
85
+ // version: '0.0.1'
86
+ // },
87
+ // paths: {
88
+ // '/status': {
89
+ // get: {
90
+ // summary: 'Get server status',
91
+ // responses: {
92
+ // '200': {
93
+ // description: 'Server works fine'
94
+ // }
95
+ // }
96
+ // }
97
+ // }
98
+ // }
99
+ // }
100
+ ```
101
+
102
+ Формирование JSON документа (сериализация).
72
103
 
73
104
  ```js
74
105
  const jsonDoc = builder.buildJson(2);
@@ -78,7 +109,7 @@ const jsonDoc = builder.buildJson(2);
78
109
 
79
110
  console.log(jsonDoc);
80
111
  // {
81
- // "openapi": "3.1.0",
112
+ // "openapi": "3.1.2",
82
113
  // "info": {
83
114
  // "title": "My Simple API",
84
115
  // "version": "0.0.1"
@@ -105,22 +136,19 @@ console.log(jsonDoc);
105
136
  ```js
106
137
  import {OADataType, OAOperationMethod} from '@e22m4u/js-openapi';
107
138
 
108
- builder.defineSchemaComponent({
109
- name: 'User', // <= имя нового компонента
110
- schema: {
111
- type: OADataType.OBJECT,
112
- properties: {
113
- id: {
114
- type: OADataType.STRING,
115
- format: 'uuid',
116
- },
117
- email: {
118
- type: OADataType.STRING,
119
- format: 'email',
120
- },
139
+ builder.defineSchemaComponent('User', {
140
+ type: OADataType.OBJECT,
141
+ properties: {
142
+ id: {
143
+ type: OADataType.STRING,
144
+ format: 'uuid',
145
+ },
146
+ email: {
147
+ type: OADataType.STRING,
148
+ format: 'email',
121
149
  },
122
- required: ['id', 'email'],
123
150
  },
151
+ required: ['id', 'email'],
124
152
  });
125
153
  ```
126
154
 
@@ -129,14 +157,13 @@ builder.defineSchemaComponent({
129
157
  ```js
130
158
  import {OADataType, OAParameterLocation} from '@e22m4u/js-openapi';
131
159
 
132
- builder.defineParameterComponent({
133
- name: 'idParam', // <= имя нового компонента
134
- parameter: {
135
- name: 'id',
136
- in: OAParameterLocation.PATH,
137
- description: 'Identifier',
138
- required: true,
139
- },
160
+ builder.defineParameterComponent('idParam', {
161
+ // фактическое имя параметра может
162
+ // отличаться от имени компонента
163
+ name: 'id',
164
+ in: OAParameterLocation.PATH,
165
+ description: 'Identifier',
166
+ required: true,
140
167
  });
141
168
  ```
142
169
 
@@ -178,7 +205,7 @@ builder.defineOperation({
178
205
 
179
206
  ## Содержимое запросов и ответов
180
207
 
181
- Определение тела запроса для операции.
208
+ Определение тела запроса операции.
182
209
 
183
210
  ```js
184
211
  import {OADataType, OAMediaType, OAOperationMethod} from '@e22m4u/js-openapi';
@@ -216,7 +243,7 @@ builder.defineOperation({
216
243
  });
217
244
  ```
218
245
 
219
- Определение тела ответа для операции.
246
+ Определение тела ответа операции.
220
247
 
221
248
  ```js
222
249
  import {OADataType, OAMediaType, OAOperationMethod} from '@e22m4u/js-openapi';
@@ -251,26 +278,24 @@ builder.defineOperation({
251
278
  });
252
279
  ```
253
280
 
254
- Определение компонента схемы для использования в следующем примере.
281
+ Определение компонента схемы для следующего примера.
255
282
 
256
283
  ```js
257
284
  import {OADataType} from '@e22m4u/js-openapi';
258
285
 
259
- builder.defineSchemaComponent({
260
- name: 'UserInput', // <= имя нового компонента
261
- schema: {
262
- type: OADataType.OBJECT,
263
- properties: {
264
- email: {
265
- type: OADataType.STRING,
266
- format: 'email',
267
- },
268
- password: {
269
- type: OADataType.STRING,
270
- },
286
+ // структура начальных данных пользователя
287
+ builder.defineSchemaComponent('UserInput', {
288
+ type: OADataType.OBJECT,
289
+ properties: {
290
+ email: {
291
+ type: OADataType.STRING,
292
+ format: 'email',
293
+ },
294
+ password: {
295
+ type: OADataType.STRING,
271
296
  },
272
- required: ['email', 'password'],
273
297
  },
298
+ required: ['email', 'password'],
274
299
  });
275
300
  ```
276
301
 
@@ -310,21 +335,21 @@ builder.defineOperation({
310
335
  });
311
336
  ```
312
337
 
313
- ## Группировка маршрутов
338
+ ## Группировка операций
314
339
 
315
- Создание области с общим префиксом пути и тегом.
340
+ Создание группы операций с общим префиксом пути и тегом.
316
341
 
317
342
  ```js
318
343
  import {OAOperationMethod} from '@e22m4u/js-openapi';
319
344
 
320
- // создание области /users
321
- const usersScope = builder.createScope({
345
+ // создание группы /users
346
+ const usersOps = builder.createOperationGroup({
322
347
  pathPrefix: '/users',
323
348
  tags: ['User'], // опционально
324
349
  });
325
350
 
326
- // маршрут GET /users/{id}
327
- usersScope.defineOperation({
351
+ // операция GET /users/{id}
352
+ usersOps.defineOperation({
328
353
  path: '/{id}',
329
354
  method: OAOperationMethod.GET,
330
355
  operation: {
@@ -337,8 +362,8 @@ usersScope.defineOperation({
337
362
  },
338
363
  });
339
364
 
340
- // маршрут DELETE /users/{id}
341
- usersScope.defineOperation({
365
+ // операция DELETE /users/{id}
366
+ usersOps.defineOperation({
342
367
  path: '/{id}',
343
368
  method: OAOperationMethod.DELETE,
344
369
  operation: {
@@ -352,23 +377,23 @@ usersScope.defineOperation({
352
377
  });
353
378
  ```
354
379
 
355
- Создание вложенных областей для комбинирования маршрутов.
380
+ Создание вложенных групп для комбинирования операций.
356
381
 
357
382
  ```js
358
383
  import {OAOperationMethod} from '@e22m4u/js-openapi';
359
384
 
360
- // область "/api/v1"
361
- const v1Scope = builder.createScope({
385
+ // группа "/api/v1"
386
+ const v1Ops = builder.createOperationGroup({
362
387
  pathPrefix: '/api/v1',
363
388
  });
364
389
 
365
- // область "/api/v1/admin"
366
- const adminScope = v1Scope.createScope({
390
+ // группа "/api/v1/admin"
391
+ const adminOps = v1Ops.createOperationGroup({
367
392
  pathPrefix: '/admin',
368
393
  });
369
394
 
370
395
  // DELETE /api/v1/admin/users/{id}
371
- adminScope.defineOperation({
396
+ adminOps.defineOperation({
372
397
  path: '/users/{id}',
373
398
  method: OAOperationMethod.DELETE,
374
399
  operation: {
@@ -382,121 +407,176 @@ adminScope.defineOperation({
382
407
  });
383
408
  ```
384
409
 
385
- ## Проверка данных
410
+ ## Константы
386
411
 
387
- Проверка данных с помощью объекта схемы.
412
+ Operation Method
388
413
 
389
414
  ```js
390
- import {OADataType, validateDataWithOpenApiSchema} from '@e22m4u/js-openapi';
391
-
392
- const schema = {
393
- type: OADataType.OBJECT,
394
- properties: {
395
- name: {type: OADataType.STRING},
396
- age: {type: OADataType.NUMBER},
397
- },
415
+ /**
416
+ * Operation Method.
417
+ * https://spec.openapis.org/oas/v3.1.2#path-item-object
418
+ */
419
+ export const OAOperationMethod = {
420
+ GET: 'get',
421
+ PUT: 'put',
422
+ POST: 'post',
423
+ DELETE: 'delete',
424
+ OPTIONS: 'options',
425
+ HEAD: 'head',
426
+ PATCH: 'patch',
427
+ TRACE: 'trace',
398
428
  };
429
+ ```
399
430
 
400
- const data = {
401
- name: 'Fedor',
402
- age: 'invalid',
403
- };
431
+ Parameter Location
404
432
 
405
- validateDataWithOpenApiSchema(data, schema);
406
- // OADataValidationError:
407
- // Value at "/age" must be Number, but String was given.
433
+ ```js
434
+ /**
435
+ * Parameter Location.
436
+ * https://spec.openapis.org/oas/v3.1.2#parameter-locations
437
+ */
438
+ export const OAParameterLocation = {
439
+ QUERY: 'query',
440
+ HEADER: 'header',
441
+ PATH: 'path',
442
+ COOKIE: 'cookie',
443
+ };
408
444
  ```
409
445
 
410
- Отключение выброса ошибки для ручной обработки результата.
446
+ Parameter Style
411
447
 
412
448
  ```js
413
- const result = validateDataWithOpenApiSchema(data, schema, {
414
- silent: true, // <= бесшумный режим
415
- });
416
- console.log(result);
417
- // {
418
- // isValid: false,
419
- // value: 'invalid',
420
- // valueUri: '/age',
421
- // schemaUri: '/properties/age',
422
- // reason: 'Value at "/age" must be Number, but String was given.',
423
- // }
449
+ /**
450
+ * Parameter Style.
451
+ * https://spec.openapis.org/oas/v3.1.2#style-values
452
+ */
453
+ export const OAParameterStyle = {
454
+ MATRIX: 'matrix',
455
+ LABEL: 'label',
456
+ FORM: 'form',
457
+ SIMPLE: 'simple',
458
+ SPACE_DELIMITED: 'spaceDelimited',
459
+ PIPE_DELIMITED: 'pipeDelimited',
460
+ DEEP_OBJECT: 'deepObject',
461
+ };
424
462
  ```
425
463
 
426
- Проверка данных с приведением типов.
464
+ Data type
427
465
 
428
466
  ```js
429
- import {OADataType, validateDataWithOpenApiSchema} from '@e22m4u/js-openapi';
467
+ /**
468
+ * Data type.
469
+ * https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00#section-4.2.1
470
+ */
471
+ export const OADataType = {
472
+ STRING: 'string',
473
+ NUMBER: 'number',
474
+ INTEGER: 'integer',
475
+ BOOLEAN: 'boolean',
476
+ OBJECT: 'object',
477
+ ARRAY: 'array',
478
+ NULL: 'null',
479
+ };
480
+ ```
430
481
 
431
- const schema = {
432
- type: OADataType.OBJECT,
433
- properties: {
434
- phone: {type: OADataType.STRING},
435
- quantity: {type: OADataType.INTEGER},
436
- featured: {type: OADataType.BOOLEAN},
437
- },
482
+ Data format
483
+
484
+ ```js
485
+ /**
486
+ * Data format.
487
+ * https://spec.openapis.org/oas/v3.1.2#dataTypeFormat
488
+ */
489
+ export const OADataFormat = {
490
+ // number
491
+ INT32: 'int32',
492
+ INT64: 'int64',
493
+ FLOAT: 'float',
494
+ DOUBLE: 'double',
495
+ // date and time
496
+ DATE: 'date',
497
+ DATE_TIME: 'date-time',
498
+ TIME: 'time',
499
+ DURATION: 'duration',
500
+ // binary
501
+ BYTE: 'byte',
502
+ BINARY: 'binary',
503
+ // identifiers and network
504
+ EMAIL: 'email',
505
+ IDN_EMAIL: 'idn-email',
506
+ UUID: 'uuid',
507
+ HOSTNAME: 'hostname',
508
+ IDN_HOSTNAME: 'idn-hostname',
509
+ IPV4: 'ipv4',
510
+ IPV6: 'ipv6',
511
+ URI: 'uri',
512
+ URI_REFERENCE: 'uri-reference',
513
+ IRI: 'iri',
514
+ IRI_REFERENCE: 'iri-reference',
515
+ // extra
516
+ PASSWORD: 'password',
517
+ REGEX: 'regex',
518
+ JSON_POINTER: 'json-pointer',
519
+ RELATIVE_JSON_POINTER: 'relative-json-pointer',
438
520
  };
521
+ ```
439
522
 
440
- const data = {
441
- phone: 88005553535, // приводится к строке
442
- quantity: '3', // приводится к целому числу
443
- featured: 'true' // приводится к логическому значению
523
+ Media type
524
+
525
+ ```js
526
+ /**
527
+ * Media type.
528
+ * https://spec.openapis.org/oas/v3.1.2#media-types
529
+ */
530
+ export const OAMediaType = {
531
+ TEXT_PLAIN: 'text/plain',
532
+ TEXT_HTML: 'text/html',
533
+ APPLICATION_XML: 'application/xml',
534
+ APPLICATION_JSON: 'application/json',
535
+ MULTIPART_FORM_DATA: 'multipart/form-data',
444
536
  };
537
+ ```
445
538
 
446
- const result = validateDataWithOpenApiSchema(data, schema, {
447
- coerceTypes: true, // <= приведение типов
448
- });
449
- console.log(result);
450
- // {
451
- // isValid: true,
452
- // value: {
453
- // phone: '88005553535',
454
- // quantity: 3,
455
- // featured: true
456
- // }
457
- // }
539
+ Security Scheme Type
540
+
541
+ ```js
542
+ /**
543
+ * Security Scheme Type.
544
+ * https://spec.openapis.org/oas/v3.1.2#security-scheme-object
545
+ */
546
+ export const OASecuritySchemeType = {
547
+ API_KEY: 'apiKey',
548
+ HTTP: 'http',
549
+ MUTUAL_TLS: 'mutualTLS',
550
+ OAUTH_2: 'oauth2',
551
+ OPEN_ID_CONNECT: 'openIdConnect',
552
+ };
458
553
  ```
459
554
 
460
- Проверка данных с разбором JSON.
555
+ Api Key Location
461
556
 
462
557
  ```js
463
- import {OADataType, validateDataWithOpenApiSchema} from '@e22m4u/js-openapi';
464
-
465
- const schema = {
466
- type: OADataType.ARRAY,
467
- prefixItems: [
468
- {type: OADataType.INTEGER},
469
- {type: OADataType.BOOLEAN},
470
- {type: OADataType.ARRAY},
471
- {type: OADataType.OBJECT},
472
- ],
558
+ /**
559
+ * Api Key Location.
560
+ * https://spec.openapis.org/oas/v3.1.2#security-scheme-object
561
+ */
562
+ export const OAApiKeyLocation = {
563
+ QUERY: 'query',
564
+ HEADER: 'header',
565
+ COOKIE: 'cookie',
473
566
  };
567
+ ```
474
568
 
475
- const data = [
476
- '123', // приводится к целому числу
477
- 'true', // приводится к логическому значению
478
- '[1, 2, 3]', // приводится к массиву
479
- '{"where": {"id": 10}, "include": "user"}', // приводится к объекту
480
- ];
569
+ Access mode
481
570
 
482
- const result = validateDataWithOpenApiSchema(data, schema, {
483
- parseJson: true, // <= разбор JSON
484
- });
485
- console.log(result);
486
- // {
487
- // isValid: true,
488
- // value: [
489
- // 123,
490
- // true,
491
- // [1, 2, 3],
492
- // {
493
- // where: {
494
- // id: 10,
495
- // },
496
- // include: 'user'
497
- // }
498
- // ]
499
- // }
571
+ ```js
572
+ /**
573
+ * Access mode.
574
+ * https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-01#name-readonly-and-writeonly
575
+ */
576
+ export const OAAccessMode = {
577
+ READ: 'read',
578
+ WRITE: 'write',
579
+ };
500
580
  ```
501
581
 
502
582
  ## Тесты