@twin.org/ts-to-openapi 0.0.1-next.10

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 (32) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +21 -0
  3. package/bin/index.js +8 -0
  4. package/dist/cjs/index.cjs +1131 -0
  5. package/dist/esm/index.mjs +1125 -0
  6. package/dist/locales/en.json +285 -0
  7. package/dist/types/cli.d.ts +23 -0
  8. package/dist/types/commands/httpStatusCodeMap.d.ts +20 -0
  9. package/dist/types/commands/tsToOpenApi.d.ts +21 -0
  10. package/dist/types/index.d.ts +4 -0
  11. package/dist/types/models/IInputPath.d.ts +68 -0
  12. package/dist/types/models/IInputResult.d.ts +15 -0
  13. package/dist/types/models/IOpenApi.d.ts +54 -0
  14. package/dist/types/models/IOpenApiExample.d.ts +13 -0
  15. package/dist/types/models/IOpenApiHeader.d.ts +19 -0
  16. package/dist/types/models/IOpenApiPathMethod.d.ts +64 -0
  17. package/dist/types/models/IOpenApiResponse.d.ts +32 -0
  18. package/dist/types/models/IOpenApiSecurityScheme.d.ts +25 -0
  19. package/dist/types/models/IPackageJson.d.ts +15 -0
  20. package/dist/types/models/ITsToOpenApiConfig.d.ts +61 -0
  21. package/dist/types/models/ITsToOpenApiConfigEntryPoint.d.ts +17 -0
  22. package/docs/changelog.md +5 -0
  23. package/docs/examples.md +890 -0
  24. package/docs/reference/classes/CLI.md +75 -0
  25. package/docs/reference/functions/actionCommandTsToOpenApi.md +23 -0
  26. package/docs/reference/functions/buildCommandTsToOpenApi.md +15 -0
  27. package/docs/reference/functions/tsToOpenApi.md +23 -0
  28. package/docs/reference/index.md +16 -0
  29. package/docs/reference/interfaces/ITsToOpenApiConfig.md +79 -0
  30. package/docs/reference/interfaces/ITsToOpenApiConfigEntryPoint.md +27 -0
  31. package/locales/en.json +45 -0
  32. package/package.json +49 -0
@@ -0,0 +1,890 @@
1
+ # @twin.org/ts-to-openapi - Examples
2
+
3
+ ## Command Line Tool
4
+
5
+ First install the tool with the following script.
6
+
7
+ ```shell
8
+ npm install @twin.org/ts-to-openapi
9
+ ```
10
+
11
+ You can then run the tool from the command line e.g.
12
+
13
+ ```shell
14
+ ts-to-openapi
15
+ ```
16
+
17
+ You should see the following response:
18
+
19
+ ```shell
20
+ TypeScript to OpenAPI
21
+ =====================
22
+
23
+ Usage:
24
+ ts-to-openapi <config-json> <output-api-json>
25
+ Error: You must specify the config json
26
+ ```
27
+
28
+ As you can see you must provide both a configuration file, and an output file.
29
+
30
+ An example configuration file looks as follows:
31
+
32
+ ```json
33
+ {
34
+ "title": "TWIN - Test Endpoints",
35
+ "version": "1.0.0",
36
+ "description": "REST API for TWIN - Test Endpoints.",
37
+ "licenseName": "Apache 2.0 License",
38
+ "licenseUrl": "https://opensource.org/licenses/Apache-2.0",
39
+ "servers": ["https://localhost"],
40
+ "authMethods": ["jwtBearer"],
41
+ "restRoutes": [
42
+ {
43
+ "package": "@twin.org/logging-service",
44
+ "version": "next"
45
+ },
46
+ {
47
+ "package": "@twin.org/identity-service",
48
+ "version": "next"
49
+ }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ If you save the example as `config.json` and then want the output in `output.json` you would use the following command line:
55
+
56
+ ```shell
57
+ ts-to-openapi config.json output.json
58
+ ```
59
+
60
+ When running this command you should see the following output:
61
+
62
+ ```shell
63
+ TypeScript to OpenAPI
64
+ =====================
65
+
66
+ Config JSON: config.json
67
+ Output API JSON: output.json
68
+ Loading Config JSON: config.json
69
+ Creating security schemas
70
+ Loading Modules: @twin.org/logging-service@next @twin.org/identity-service@next
71
+
72
+ added 43 packages, and audited 44 packages in 2s
73
+
74
+ 1 package is looking for funding
75
+ run `npm fund` for details
76
+
77
+ found 0 vulnerabilities
78
+
79
+ Reading Package JSON: @twin.org/logging-service
80
+ Importing Module: @twin.org/logging-service
81
+ Reading Package JSON: @twin.org/identity-service
82
+ Importing Module: @twin.org/identity-service
83
+ Route loggingEntryCreate POST /logging/
84
+ Route loggingListEntries GET /logging/
85
+ Route identityCreate POST /identity/
86
+ Route identityUpdate PUT /identity/:identity
87
+ Route identityGet GET /identity/:identity
88
+ Route identitiesList GET /identity/
89
+
90
+ Generating Schemas
91
+ Processing Models //work/node_modules/@twin.org/api-models/dist/types/models/**/*.ts
92
+ Processing Models //work/node_modules/@twin.org/core/dist/types/models/**/*.ts
93
+ Processing Models //work/node_modules/@twin.org/core/dist/types/errors/**/*.ts
94
+ Processing Models //work/node_modules/@twin.org/entity/dist/types/models/**/*.ts
95
+ Processing Models //work/node_modules/@twin.org/logging-models/dist/types/models/**/*.ts
96
+ Processing Models //work/node_modules/@twin.org/services/dist/types/models/**/*.ts
97
+ Processing Models //work/node_modules/@twin.org/web/dist/types/models/**/*.ts
98
+ Processing Models //work/node_modules/@twin.org/web/dist/types/errors/**/*.ts
99
+ Processing Models //work/node_modules/@twin.org/identity-service/dist/types/models/**/*.ts
100
+ Processing Models //work/node_modules/@twin.org/api-models/dist/types/models/**/*.ts
101
+ Processing Models //work/node_modules/@twin.org/core/dist/types/models/**/*.ts
102
+ Processing Models //work/node_modules/@twin.org/core/dist/types/errors/**/*.ts
103
+ Processing Models //work/node_modules/@twin.org/crypto/dist/types/models/**/*.ts
104
+ Processing Models //work/node_modules/@twin.org/entity/dist/types/models/**/*.ts
105
+ Processing Models //work/node_modules/@twin.org/entity-storage-connector-memory/dist/types/models/**/*.ts
106
+ Processing Models //work/node_modules/@twin.org/entity-storage-models/dist/types/models/**/*.ts
107
+ Processing Models //work/node_modules/@twin.org/identity-connector-entity-storage/dist/types/models/**/*.ts
108
+ Processing Models //work/node_modules/@twin.org/identity-models/dist/types/models/**/*.ts
109
+ Processing Models //work/node_modules/@twin.org/services/dist/types/models/**/*.ts
110
+ Processing Models //work/node_modules/@twin.org/vault-connector-entity-storage/dist/types/models/**/*.ts
111
+ Processing Models //work/node_modules/@twin.org/vault-models/dist/types/models/**/*.ts
112
+ Processing Models //work/node_modules/@twin.org/web/dist/types/models/**/*.ts
113
+ Processing Models //work/node_modules/@twin.org/web/dist/types/errors/**/*.ts
114
+
115
+ Finalising Schemas
116
+ Writing Output: output.json
117
+ ```
118
+
119
+ The generated `output.json` should be:
120
+
121
+ ```json
122
+ {
123
+ "openapi": "3.1.0",
124
+ "info": {
125
+ "title": "TWIN - Test Endpoints",
126
+ "description": "REST API for TWIN - Test Endpoints.",
127
+ "version": "1.0.0",
128
+ "license": {
129
+ "name": "Apache 2.0 License",
130
+ "url": "https://opensource.org/licenses/Apache-2.0"
131
+ }
132
+ },
133
+ "servers": [
134
+ {
135
+ "url": "https://localhost"
136
+ }
137
+ ],
138
+ "tags": [],
139
+ "paths": {
140
+ "/logging": {
141
+ "post": {
142
+ "operationId": "loggingEntryCreate",
143
+ "summary": "Create a log entry",
144
+ "tags": ["Logging"],
145
+ "security": [
146
+ {
147
+ "jwtBearerAuthScheme": []
148
+ }
149
+ ],
150
+ "responses": {
151
+ "200": {
152
+ "description": "The rest request ended in created response.",
153
+ "content": {
154
+ "application/json": {
155
+ "schema": {
156
+ "$ref": "#/components/schemas/CreatedResponse"
157
+ }
158
+ }
159
+ },
160
+ "headers": {
161
+ "location": {
162
+ "schema": {
163
+ "type": "string"
164
+ },
165
+ "description": "e.g. c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
166
+ }
167
+ }
168
+ }
169
+ },
170
+ "requestBody": {
171
+ "description": "Create a new log entry.",
172
+ "required": true,
173
+ "content": {
174
+ "application/json": {
175
+ "schema": {
176
+ "$ref": "#/components/schemas/LogEntry"
177
+ },
178
+ "examples": {
179
+ "loggingEntryCreateInfoExample": {
180
+ "value": {
181
+ "level": "info",
182
+ "message": "This is an information message",
183
+ "source": "source",
184
+ "ts": 1715252922273
185
+ }
186
+ },
187
+ "loggingEntryCreateErrorExample": {
188
+ "value": {
189
+ "level": "info",
190
+ "message": "This is an error message",
191
+ "source": "source",
192
+ "ts": 1715252922273,
193
+ "error": {
194
+ "name": "GeneralError",
195
+ "message": "component.error",
196
+ "properties": {
197
+ "foo": "bar"
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ },
207
+ "get": {
208
+ "operationId": "loggingListEntries",
209
+ "summary": "Get a list of the log entries",
210
+ "tags": ["Logging"],
211
+ "parameters": [
212
+ {
213
+ "name": "level",
214
+ "description": "The level of the log entries to retrieve.",
215
+ "in": "query",
216
+ "required": false,
217
+ "schema": {},
218
+ "example": "info"
219
+ },
220
+ {
221
+ "name": "source",
222
+ "description": "The source of the log entries to retrieve.",
223
+ "in": "query",
224
+ "required": false,
225
+ "schema": {
226
+ "type": "string"
227
+ }
228
+ },
229
+ {
230
+ "name": "timeStart",
231
+ "description": "The start time of the metrics to retrieve as a timestamp in ms.",
232
+ "in": "query",
233
+ "required": false,
234
+ "schema": {
235
+ "type": "number"
236
+ }
237
+ },
238
+ {
239
+ "name": "timeEnd",
240
+ "description": "The end time of the metrics to retrieve as a timestamp in ms.",
241
+ "in": "query",
242
+ "required": false,
243
+ "schema": {
244
+ "type": "number"
245
+ }
246
+ },
247
+ {
248
+ "name": "cursor",
249
+ "description": "The optional cursor to get next chunk.",
250
+ "in": "query",
251
+ "required": false,
252
+ "schema": {
253
+ "type": "string"
254
+ }
255
+ },
256
+ {
257
+ "name": "pageSize",
258
+ "description": "The maximum number of entities in a page.",
259
+ "in": "query",
260
+ "required": false,
261
+ "schema": {
262
+ "type": "number"
263
+ }
264
+ }
265
+ ],
266
+ "security": [
267
+ {
268
+ "jwtBearerAuthScheme": []
269
+ }
270
+ ],
271
+ "responses": {
272
+ "200": {
273
+ "description": "Response for log entry list request.",
274
+ "content": {
275
+ "application/json": {
276
+ "schema": {
277
+ "$ref": "#/components/schemas/LoggingListResponse"
278
+ },
279
+ "examples": {
280
+ "listResponseExample": {
281
+ "value": {
282
+ "entities": [
283
+ {
284
+ "level": "info",
285
+ "message": "This is an information message",
286
+ "source": "source",
287
+ "ts": 1715252922273
288
+ }
289
+ ],
290
+ "cursor": "1",
291
+ "pageSize": 10,
292
+ "totalEntities": 20
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ },
302
+ "/identity": {
303
+ "post": {
304
+ "operationId": "identityCreate",
305
+ "summary": "Create a new identity",
306
+ "tags": ["Identity"],
307
+ "security": [
308
+ {
309
+ "jwtBearerAuthScheme": []
310
+ }
311
+ ],
312
+ "responses": {
313
+ "200": {
314
+ "description": "The rest request ended in created response.",
315
+ "content": {
316
+ "application/json": {
317
+ "schema": {
318
+ "$ref": "#/components/schemas/CreatedResponse"
319
+ }
320
+ }
321
+ },
322
+ "headers": {
323
+ "location": {
324
+ "schema": {
325
+ "type": "string"
326
+ },
327
+ "description": "e.g. did:twin:0xc57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
328
+ }
329
+ }
330
+ }
331
+ },
332
+ "requestBody": {
333
+ "description": "Create a new identity.",
334
+ "required": true,
335
+ "content": {
336
+ "application/json": {
337
+ "schema": {
338
+ "$ref": "#/components/schemas/IdentityCreateRequest"
339
+ },
340
+ "examples": {
341
+ "identityCreateRequestExample": {
342
+ "value": {
343
+ "role": "user",
344
+ "properties": [
345
+ {
346
+ "key": "email",
347
+ "type": "https://schema.org/Text",
348
+ "value": "john@example.com"
349
+ },
350
+ {
351
+ "key": "name",
352
+ "type": "https://schema.org/Text",
353
+ "value": "John Doe"
354
+ }
355
+ ]
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+ },
363
+ "get": {
364
+ "operationId": "identitiesList",
365
+ "summary": "Get the list of identities based on the provided criteria",
366
+ "tags": ["Identity"],
367
+ "parameters": [
368
+ {
369
+ "name": "role",
370
+ "description": "The property name to use for lookup.",
371
+ "in": "query",
372
+ "required": false,
373
+ "schema": {},
374
+ "example": "user"
375
+ },
376
+ {
377
+ "name": "propertyNames",
378
+ "description": "The properties to get for the profile, defaults to all. should be a comma separated list.",
379
+ "in": "query",
380
+ "required": false,
381
+ "schema": {
382
+ "type": "string"
383
+ }
384
+ },
385
+ {
386
+ "name": "cursor",
387
+ "description": "The cursor for paged requests.",
388
+ "in": "query",
389
+ "required": false,
390
+ "schema": {
391
+ "type": "string"
392
+ }
393
+ },
394
+ {
395
+ "name": "pageSize",
396
+ "description": "Number of items to return.",
397
+ "in": "query",
398
+ "required": false,
399
+ "schema": {
400
+ "type": "number"
401
+ }
402
+ }
403
+ ],
404
+ "security": [
405
+ {
406
+ "jwtBearerAuthScheme": []
407
+ }
408
+ ],
409
+ "responses": {
410
+ "200": {
411
+ "description": "Response to get a list of identities.",
412
+ "content": {
413
+ "application/json": {
414
+ "schema": {
415
+ "$ref": "#/components/schemas/IdentityListResponse"
416
+ },
417
+ "examples": {
418
+ "identitiesListResponseExample": {
419
+ "value": {
420
+ "identities": [
421
+ {
422
+ "identity": "did:twin:0xc57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
423
+ "properties": [
424
+ {
425
+ "key": "email",
426
+ "type": "https://schema.org/Text",
427
+ "value": "john@example.com"
428
+ }
429
+ ]
430
+ }
431
+ ],
432
+ "cursor": "1",
433
+ "pageSize": 10,
434
+ "totalEntities": 20
435
+ }
436
+ }
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ },
444
+ "/identity/{identity}": {
445
+ "put": {
446
+ "operationId": "identityUpdate",
447
+ "summary": "Update an identity",
448
+ "tags": ["Identity"],
449
+ "parameters": [
450
+ {
451
+ "name": "identity",
452
+ "description": "The identity to update the profile for.",
453
+ "in": "path",
454
+ "required": true,
455
+ "schema": {
456
+ "type": "string"
457
+ },
458
+ "style": "simple",
459
+ "example": "did:twin:0xc57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
460
+ }
461
+ ],
462
+ "security": [
463
+ {
464
+ "jwtBearerAuthScheme": []
465
+ }
466
+ ],
467
+ "responses": {
468
+ "200": {
469
+ "description": "The resource you tried to access does not exist, see the error field for more details.",
470
+ "content": {
471
+ "application/json": {
472
+ "schema": {
473
+ "$ref": "#/components/schemas/NotFoundResponse"
474
+ }
475
+ }
476
+ }
477
+ }
478
+ },
479
+ "requestBody": {
480
+ "description": "Request to update an identity.",
481
+ "required": true,
482
+ "content": {
483
+ "application/json": {
484
+ "schema": {
485
+ "$ref": "#/components/schemas/IdentityUpdateRequest"
486
+ },
487
+ "examples": {
488
+ "identityUpdateRequestExample": {
489
+ "value": {
490
+ "properties": [
491
+ {
492
+ "key": "email",
493
+ "type": "https://schema.org/Text",
494
+ "value": "john@example.com"
495
+ },
496
+ {
497
+ "key": "name",
498
+ "type": "https://schema.org/Text",
499
+ "value": "John Smith"
500
+ }
501
+ ]
502
+ }
503
+ }
504
+ }
505
+ }
506
+ }
507
+ }
508
+ },
509
+ "get": {
510
+ "operationId": "identityGet",
511
+ "summary": "Get the identity details",
512
+ "tags": ["Identity"],
513
+ "parameters": [
514
+ {
515
+ "name": "identity",
516
+ "description": "The identity to get the profile for.",
517
+ "in": "path",
518
+ "required": true,
519
+ "schema": {
520
+ "type": "string"
521
+ },
522
+ "style": "simple",
523
+ "example": "did:twin:0xc57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
524
+ },
525
+ {
526
+ "name": "propertyNames",
527
+ "description": "The properties to get for the profile, defaults to all. should be a comma separated list.",
528
+ "in": "query",
529
+ "required": false,
530
+ "schema": {
531
+ "type": "string"
532
+ },
533
+ "example": "email,name"
534
+ }
535
+ ],
536
+ "security": [
537
+ {
538
+ "jwtBearerAuthScheme": []
539
+ }
540
+ ],
541
+ "responses": {
542
+ "200": {
543
+ "description": "The resource you tried to access does not exist, see the error field for more details.",
544
+ "content": {
545
+ "application/json": {
546
+ "schema": {
547
+ "$ref": "#/components/schemas/NotFoundResponse"
548
+ }
549
+ }
550
+ }
551
+ }
552
+ }
553
+ }
554
+ }
555
+ },
556
+ "components": {
557
+ "schemas": {
558
+ "LogEntry": {
559
+ "type": "object",
560
+ "properties": {
561
+ "level": {
562
+ "$ref": "#/components/schemas/LogLevel"
563
+ },
564
+ "source": {
565
+ "type": "string",
566
+ "description": "The source of the log entry."
567
+ },
568
+ "ts": {
569
+ "type": "number",
570
+ "description": "The timestamp of the log entry, if left blank will be populated by the connector."
571
+ },
572
+ "message": {
573
+ "type": "string",
574
+ "description": "The message."
575
+ },
576
+ "error": {
577
+ "$ref": "#/components/schemas/Error"
578
+ },
579
+ "data": {
580
+ "description": "Optional data for the message."
581
+ }
582
+ },
583
+ "required": ["level", "source", "message"],
584
+ "additionalProperties": false,
585
+ "description": "Interface describing a log entry."
586
+ },
587
+ "LogLevel": {
588
+ "type": "string",
589
+ "enum": ["info", "error", "warn", "trace", "debug"],
590
+ "description": "Log level."
591
+ },
592
+ "Error": {
593
+ "type": "object",
594
+ "properties": {
595
+ "name": {
596
+ "type": "string",
597
+ "description": "The name for the error."
598
+ },
599
+ "message": {
600
+ "type": "string",
601
+ "description": "The message for the error."
602
+ },
603
+ "source": {
604
+ "type": "string",
605
+ "description": "The source of the error."
606
+ },
607
+ "properties": {
608
+ "type": "object",
609
+ "additionalProperties": {},
610
+ "description": "Any additional information for the error."
611
+ },
612
+ "stack": {
613
+ "type": "string",
614
+ "description": "The stack trace for the error."
615
+ },
616
+ "inner": {
617
+ "$ref": "#/components/schemas/Error"
618
+ }
619
+ },
620
+ "required": ["name", "message"],
621
+ "additionalProperties": false,
622
+ "description": "Model to describe serialized error."
623
+ },
624
+ "CreatedResponse": {
625
+ "type": "object",
626
+ "properties": {
627
+ "statusCode": {
628
+ "$ref": "#/components/schemas/HttpStatusCodes"
629
+ },
630
+ "headers": {
631
+ "type": "object",
632
+ "properties": {
633
+ "location": {
634
+ "type": "string",
635
+ "description": "The location where the resource was created."
636
+ }
637
+ },
638
+ "required": ["location"],
639
+ "additionalProperties": false,
640
+ "description": "Additional response headers."
641
+ }
642
+ },
643
+ "required": ["statusCode", "headers"],
644
+ "additionalProperties": false,
645
+ "description": "The rest request ended in created response."
646
+ },
647
+ "HttpStatusCodes": {
648
+ "type": "object",
649
+ "additionalProperties": false,
650
+ "description": "Standard HTTP status codes."
651
+ },
652
+ "LoggingListResponse": {
653
+ "type": "object",
654
+ "properties": {
655
+ "entities": {
656
+ "type": "array",
657
+ "items": {
658
+ "$ref": "#/components/schemas/LogEntry"
659
+ },
660
+ "description": "The entities, which can be partial if a limited keys list was provided."
661
+ },
662
+ "cursor": {
663
+ "type": "string",
664
+ "description": "An optional cursor, when defined can be used to call find to get more entities."
665
+ },
666
+ "pageSize": {
667
+ "type": "number",
668
+ "description": "Number of entities to return."
669
+ },
670
+ "totalEntities": {
671
+ "type": "number",
672
+ "description": "Total entities length."
673
+ }
674
+ },
675
+ "required": ["entities", "totalEntities"],
676
+ "additionalProperties": false,
677
+ "description": "The response payload."
678
+ },
679
+ "IdentityCreateRequest": {
680
+ "type": "object",
681
+ "properties": {
682
+ "role": {
683
+ "$ref": "#/components/schemas/IdentityRole"
684
+ },
685
+ "properties": {
686
+ "type": "array",
687
+ "items": {
688
+ "$ref": "#/components/schemas/Property"
689
+ },
690
+ "description": "Initial properties for the identity."
691
+ }
692
+ },
693
+ "required": ["role"],
694
+ "additionalProperties": false,
695
+ "description": "The data for the request."
696
+ },
697
+ "IdentityRole": {
698
+ "type": "string",
699
+ "enum": ["node", "organization", "user"],
700
+ "description": "The roles that an identity can have."
701
+ },
702
+ "Property": {
703
+ "type": "object",
704
+ "properties": {
705
+ "key": {
706
+ "type": "string",
707
+ "description": "The key for the item."
708
+ },
709
+ "type": {
710
+ "type": "string",
711
+ "description": "The type for the item."
712
+ },
713
+ "value": {
714
+ "description": "The value for the item."
715
+ }
716
+ },
717
+ "required": ["key", "type", "value"],
718
+ "additionalProperties": false,
719
+ "description": "Interface describing a property."
720
+ },
721
+ "IdentityUpdateRequest": {
722
+ "type": "object",
723
+ "properties": {
724
+ "properties": {
725
+ "type": "array",
726
+ "items": {
727
+ "$ref": "#/components/schemas/Property"
728
+ },
729
+ "description": "Properties for the identity."
730
+ }
731
+ },
732
+ "required": ["properties"],
733
+ "additionalProperties": false,
734
+ "description": "The data for the request."
735
+ },
736
+ "NoContentResponse": {
737
+ "type": "object",
738
+ "additionalProperties": false,
739
+ "description": "The rest request ended in success with no data."
740
+ },
741
+ "NotFoundResponse": {
742
+ "type": "object",
743
+ "properties": {
744
+ "name": {
745
+ "type": "string",
746
+ "description": "The name for the error."
747
+ },
748
+ "message": {
749
+ "type": "string",
750
+ "description": "The message for the error."
751
+ },
752
+ "source": {
753
+ "type": "string",
754
+ "description": "The source of the error."
755
+ },
756
+ "properties": {
757
+ "type": "object",
758
+ "additionalProperties": {},
759
+ "description": "Any additional information for the error."
760
+ },
761
+ "stack": {
762
+ "type": "string",
763
+ "description": "The stack trace for the error."
764
+ },
765
+ "inner": {
766
+ "$ref": "#/components/schemas/Error"
767
+ },
768
+ "notFoundId": {
769
+ "type": "string",
770
+ "description": "The id if the item that was not found."
771
+ }
772
+ },
773
+ "additionalProperties": false,
774
+ "required": ["message", "name"],
775
+ "description": "The resource you tried to access does not exist, see the error field for more details."
776
+ },
777
+ "IdentityGetResponse": {
778
+ "type": "object",
779
+ "properties": {
780
+ "role": {
781
+ "$ref": "#/components/schemas/IdentityRole"
782
+ },
783
+ "properties": {
784
+ "type": "array",
785
+ "items": {
786
+ "$ref": "#/components/schemas/Property"
787
+ },
788
+ "description": "The properties for the identity."
789
+ }
790
+ },
791
+ "required": ["role"],
792
+ "additionalProperties": false,
793
+ "description": "The response payload."
794
+ },
795
+ "IdentityListResponse": {
796
+ "type": "object",
797
+ "properties": {
798
+ "identities": {
799
+ "type": "array",
800
+ "items": {
801
+ "type": "object",
802
+ "properties": {
803
+ "identity": {
804
+ "type": "string"
805
+ },
806
+ "properties": {
807
+ "type": "array",
808
+ "items": {
809
+ "$ref": "#/components/schemas/Property"
810
+ }
811
+ }
812
+ },
813
+ "required": ["identity"],
814
+ "additionalProperties": false
815
+ },
816
+ "description": "The identities."
817
+ },
818
+ "cursor": {
819
+ "type": "string",
820
+ "description": "An optional cursor, when defined can be used to call find to get more entities."
821
+ },
822
+ "pageSize": {
823
+ "type": "number",
824
+ "description": "Number of entities to return."
825
+ },
826
+ "totalEntities": {
827
+ "type": "number",
828
+ "description": "Total entities length."
829
+ }
830
+ },
831
+ "required": ["identities", "totalEntities"],
832
+ "additionalProperties": false,
833
+ "description": "The response payload."
834
+ }
835
+ },
836
+ "securitySchemes": {
837
+ "jwtBearerAuthScheme": {
838
+ "type": "http",
839
+ "scheme": "bearer",
840
+ "bearerFormat": "JWT"
841
+ }
842
+ }
843
+ }
844
+ }
845
+ ```
846
+
847
+ You can use a tool such as [https://editor-next.swagger.io/](https://editor-next.swagger.io/) to validate that the schema is correct.
848
+
849
+ ## Programatically
850
+
851
+ You can also use the package programatically as follows:
852
+
853
+ ```typescript
854
+ import { rm, mkdir } from 'node:fs/promises';
855
+ import { CLI, type ITsToOpenApiConfig } from '@twin.org/ts-to-openapi';
856
+
857
+ const config: ITsToOpenApiConfig = {
858
+ title: 'TWIN - Test Endpoints',
859
+ version: '1.0.0',
860
+ description: 'REST API for TWIN - Test Endpoints.',
861
+ licenseName: 'Apache 2.0 License',
862
+ licenseUrl: 'https://opensource.org/licenses/Apache-2.0',
863
+ servers: ['https://localhost'],
864
+ authMethods: ['jwtBearer'],
865
+ restRoutes: [
866
+ {
867
+ package: '@twin.org/logging-service',
868
+ version: 'next'
869
+ },
870
+ {
871
+ package: '@twin.org/identity-service',
872
+ version: 'next'
873
+ }
874
+ ]
875
+ };
876
+
877
+ // Create a working directory for the processing.
878
+ await mkdir('./working');
879
+
880
+ try {
881
+ // Process the config and store in output.json
882
+ const cli = new CLI();
883
+ await cli.process(config, './output.json', './working');
884
+ } catch (err) {
885
+ console.debug(err);
886
+ } finally {
887
+ // Remove the working directory
888
+ await rm('./working');
889
+ }
890
+ ```