@kubb/plugin-oas 3.0.0-alpha.15 → 3.0.0-alpha.16

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 (76) hide show
  1. package/dist/{OperationGenerator-BqfyX5-8.d.cts → OperationGenerator-B5CoXmjA.d.cts} +22 -20
  2. package/dist/{OperationGenerator-BqfyX5-8.d.ts → OperationGenerator-B5CoXmjA.d.ts} +22 -20
  3. package/dist/{Schema-BgpIlA79.d.cts → Schema-BsgDay0E.d.cts} +1 -12
  4. package/dist/{Schema-ExMIJOhD.d.ts → Schema-Dvt6i_X3.d.ts} +1 -12
  5. package/dist/chunk-2QECZEUD.js +76 -0
  6. package/dist/chunk-2QECZEUD.js.map +1 -0
  7. package/dist/chunk-4OQEPWOG.js +38 -0
  8. package/dist/chunk-4OQEPWOG.js.map +1 -0
  9. package/dist/chunk-7Q5B67MW.cjs +1110 -0
  10. package/dist/chunk-7Q5B67MW.cjs.map +1 -0
  11. package/dist/chunk-7XBQZ7AX.js +1098 -0
  12. package/dist/chunk-7XBQZ7AX.js.map +1 -0
  13. package/dist/{chunk-AAIEMW6V.cjs → chunk-CQDZGAA6.cjs} +28 -798
  14. package/dist/chunk-CQDZGAA6.cjs.map +1 -0
  15. package/dist/{chunk-M3V3WMCW.js → chunk-CYF724QJ.js} +11 -773
  16. package/dist/chunk-CYF724QJ.js.map +1 -0
  17. package/dist/{chunk-PZTS5YZV.js → chunk-D2N6LDLT.js} +15 -13
  18. package/dist/chunk-D2N6LDLT.js.map +1 -0
  19. package/dist/{chunk-I3ZL3GUQ.cjs → chunk-LCPCIS3S.cjs} +19 -17
  20. package/dist/chunk-LCPCIS3S.cjs.map +1 -0
  21. package/dist/chunk-PUFCST25.cjs +84 -0
  22. package/dist/chunk-PUFCST25.cjs.map +1 -0
  23. package/dist/chunk-TYQZ2BD7.cjs +42 -0
  24. package/dist/chunk-TYQZ2BD7.cjs.map +1 -0
  25. package/dist/components.cjs +5 -6
  26. package/dist/components.d.cts +2 -2
  27. package/dist/components.d.ts +2 -2
  28. package/dist/components.js +2 -3
  29. package/dist/generators.cjs +4 -5
  30. package/dist/generators.d.cts +1 -1
  31. package/dist/generators.d.ts +1 -1
  32. package/dist/generators.js +3 -4
  33. package/dist/hooks.cjs +102 -31
  34. package/dist/hooks.cjs.map +1 -1
  35. package/dist/hooks.d.cts +39 -6
  36. package/dist/hooks.d.ts +39 -6
  37. package/dist/hooks.js +92 -20
  38. package/dist/hooks.js.map +1 -1
  39. package/dist/index.cjs +25 -410
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +2 -2
  42. package/dist/index.d.ts +2 -2
  43. package/dist/index.js +5 -400
  44. package/dist/index.js.map +1 -1
  45. package/dist/utils.cjs +12 -12
  46. package/dist/utils.cjs.map +1 -1
  47. package/dist/utils.d.cts +2 -2
  48. package/dist/utils.d.ts +2 -2
  49. package/dist/utils.js +2 -3
  50. package/dist/utils.js.map +1 -1
  51. package/package.json +10 -10
  52. package/src/OperationGenerator.ts +11 -15
  53. package/src/SchemaGenerator.ts +14 -5
  54. package/src/components/Schema.tsx +1 -98
  55. package/src/generator.tsx +22 -14
  56. package/src/generators/jsonGenerator.ts +4 -4
  57. package/src/hooks/index.ts +2 -0
  58. package/src/hooks/useOperationManager.ts +76 -29
  59. package/src/hooks/useSchemaManager.ts +76 -0
  60. package/src/utils/getParams.ts +1 -1
  61. package/dist/chunk-2PMRS7PB.cjs +0 -8
  62. package/dist/chunk-2PMRS7PB.cjs.map +0 -1
  63. package/dist/chunk-2V64GHQ4.js +0 -32
  64. package/dist/chunk-2V64GHQ4.js.map +0 -1
  65. package/dist/chunk-4JIFKRM5.js +0 -6
  66. package/dist/chunk-4JIFKRM5.js.map +0 -1
  67. package/dist/chunk-5ULY3TQB.cjs +0 -90
  68. package/dist/chunk-5ULY3TQB.cjs.map +0 -1
  69. package/dist/chunk-AAIEMW6V.cjs.map +0 -1
  70. package/dist/chunk-CFU6KMOB.cjs +0 -38
  71. package/dist/chunk-CFU6KMOB.cjs.map +0 -1
  72. package/dist/chunk-GAPWY2CE.js +0 -84
  73. package/dist/chunk-GAPWY2CE.js.map +0 -1
  74. package/dist/chunk-I3ZL3GUQ.cjs.map +0 -1
  75. package/dist/chunk-M3V3WMCW.js.map +0 -1
  76. package/dist/chunk-PZTS5YZV.js.map +0 -1
@@ -0,0 +1,1098 @@
1
+ import { getSchemas, getSchemaFactory, parseFromConfig } from './chunk-2QECZEUD.js';
2
+ import { jsonGenerator } from './chunk-D2N6LDLT.js';
3
+ import { init_esm_shims } from './chunk-4OQEPWOG.js';
4
+ import { createPlugin, FileManager, BaseGenerator } from '@kubb/core';
5
+ import transformers, { pascalCase } from '@kubb/core/transformers';
6
+ import path from 'node:path';
7
+ import { getUniqueName } from '@kubb/core/utils';
8
+ import { isReference } from '@kubb/oas';
9
+ import { uniqueWith, isDeepEqual, isNumber } from 'remeda';
10
+
11
+ // src/index.ts
12
+ init_esm_shims();
13
+
14
+ // src/OperationGenerator.ts
15
+ init_esm_shims();
16
+ var OperationGenerator = class extends BaseGenerator {
17
+ #operationsByMethod = {};
18
+ get operationsByMethod() {
19
+ return this.#operationsByMethod;
20
+ }
21
+ set operationsByMethod(paths) {
22
+ this.#operationsByMethod = paths;
23
+ }
24
+ #getOptions(operation, method) {
25
+ const { override = [] } = this.context;
26
+ return override.find(({ pattern, type }) => {
27
+ if (type === "tag") {
28
+ return !!operation.getTags()[0]?.name.match(pattern);
29
+ }
30
+ if (type === "operationId") {
31
+ return !!operation.getOperationId().match(pattern);
32
+ }
33
+ if (type === "path") {
34
+ return !!operation.path.match(pattern);
35
+ }
36
+ if (type === "method") {
37
+ return !!method.match(pattern);
38
+ }
39
+ return false;
40
+ })?.options || {};
41
+ }
42
+ /**
43
+ *
44
+ * @deprecated
45
+ */
46
+ #isExcluded(operation, method) {
47
+ const { exclude = [] } = this.context;
48
+ let matched = false;
49
+ exclude.forEach(({ pattern, type }) => {
50
+ if (type === "tag" && !matched) {
51
+ matched = !!operation.getTags()[0]?.name.match(pattern);
52
+ }
53
+ if (type === "operationId" && !matched) {
54
+ matched = !!operation.getOperationId().match(pattern);
55
+ }
56
+ if (type === "path" && !matched) {
57
+ matched = !!operation.path.match(pattern);
58
+ }
59
+ if (type === "method" && !matched) {
60
+ matched = !!method.match(pattern);
61
+ }
62
+ });
63
+ return matched;
64
+ }
65
+ /**
66
+ *
67
+ * @deprecated
68
+ */
69
+ #isIncluded(operation, method) {
70
+ const { include = [] } = this.context;
71
+ let matched = false;
72
+ include.forEach(({ pattern, type }) => {
73
+ if (type === "tag" && !matched) {
74
+ matched = !!operation.getTags()[0]?.name.match(pattern);
75
+ }
76
+ if (type === "operationId" && !matched) {
77
+ matched = !!operation.getOperationId().match(pattern);
78
+ }
79
+ if (type === "path" && !matched) {
80
+ matched = !!operation.path.match(pattern);
81
+ }
82
+ if (type === "method" && !matched) {
83
+ matched = !!method.match(pattern);
84
+ }
85
+ });
86
+ return matched;
87
+ }
88
+ getSchemas(operation, {
89
+ resolveName = (name) => name
90
+ } = {}) {
91
+ const pathParamsSchema = this.context.oas.getParametersSchema(operation, "path");
92
+ const queryParamsSchema = this.context.oas.getParametersSchema(operation, "query");
93
+ const headerParamsSchema = this.context.oas.getParametersSchema(operation, "header");
94
+ const requestSchema = this.context.oas.getRequestSchema(operation);
95
+ const responseStatusCode = operation.schema.responses && Object.keys(operation.schema.responses).find((key) => key.startsWith("2")) || 200;
96
+ const responseSchema = this.context.oas.getResponseSchema(operation, responseStatusCode);
97
+ const statusCodes = operation.getResponseStatusCodes().map((statusCode) => {
98
+ let name = statusCode;
99
+ if (name === "default") {
100
+ name = "error";
101
+ }
102
+ const schema = this.context.oas.getResponseSchema(operation, statusCode);
103
+ return {
104
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} ${name}`)),
105
+ description: operation.getResponseByStatusCode(statusCode)?.description,
106
+ schema,
107
+ operation,
108
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
109
+ statusCode: name === "error" ? void 0 : Number(statusCode),
110
+ keys: schema?.properties ? Object.keys(schema.properties) : void 0
111
+ };
112
+ });
113
+ return {
114
+ pathParams: pathParamsSchema ? {
115
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} PathParams`)),
116
+ operation,
117
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
118
+ schema: pathParamsSchema,
119
+ keys: pathParamsSchema.properties ? Object.keys(pathParamsSchema.properties) : void 0
120
+ } : void 0,
121
+ queryParams: queryParamsSchema ? {
122
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} QueryParams`)),
123
+ operation,
124
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
125
+ schema: queryParamsSchema,
126
+ keys: queryParamsSchema.properties ? Object.keys(queryParamsSchema.properties) : []
127
+ } : void 0,
128
+ headerParams: headerParamsSchema ? {
129
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} HeaderParams`)),
130
+ operation,
131
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
132
+ schema: headerParamsSchema,
133
+ keys: headerParamsSchema.properties ? Object.keys(headerParamsSchema.properties) : void 0
134
+ } : void 0,
135
+ request: requestSchema ? {
136
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} ${operation.method === "get" ? "queryRequest" : "mutationRequest"}`)),
137
+ description: operation.schema.requestBody?.description,
138
+ operation,
139
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
140
+ schema: requestSchema,
141
+ keys: requestSchema.properties ? Object.keys(requestSchema.properties) : void 0,
142
+ keysToOmit: requestSchema.properties ? Object.keys(requestSchema.properties).filter((key) => {
143
+ const item = requestSchema.properties?.[key];
144
+ return item?.readOnly;
145
+ }) : void 0
146
+ } : void 0,
147
+ response: {
148
+ name: resolveName(transformers.pascalCase(`${operation.getOperationId()} ${operation.method === "get" ? "queryResponse" : "mutationResponse"}`)),
149
+ description: operation.getResponseAsJSONSchema(responseStatusCode)?.at(0)?.description,
150
+ operation,
151
+ operationName: transformers.pascalCase(`${operation.getOperationId()}`),
152
+ schema: responseSchema,
153
+ statusCode: Number(responseStatusCode),
154
+ keys: responseSchema?.properties ? Object.keys(responseSchema.properties) : void 0,
155
+ keysToOmit: responseSchema?.properties ? Object.keys(responseSchema.properties).filter((key) => {
156
+ const item = responseSchema.properties?.[key];
157
+ return item?.writeOnly;
158
+ }) : void 0
159
+ },
160
+ errors: statusCodes.filter((item) => item.statusCode?.toString().startsWith("4") || item.statusCode?.toString().startsWith("5")),
161
+ statusCodes
162
+ };
163
+ }
164
+ #methods = ["get", "post", "patch", "put", "delete"];
165
+ async build(...generators) {
166
+ const { oas } = this.context;
167
+ const paths = oas.getPaths();
168
+ this.operationsByMethod = Object.entries(paths).reduce((acc, [path2, method]) => {
169
+ const methods = Object.keys(method);
170
+ methods.forEach((method2) => {
171
+ const operation = oas.operation(path2, method2);
172
+ if (operation && [this.#methods].some((methods2) => method2 === operation.method)) {
173
+ const isExcluded = this.#isExcluded(operation, method2);
174
+ const isIncluded = this.context.include ? this.#isIncluded(operation, method2) : true;
175
+ if (isIncluded && !isExcluded) {
176
+ if (!acc[path2]) {
177
+ acc[path2] = {};
178
+ }
179
+ acc[path2] = {
180
+ ...acc[path2],
181
+ [method2]: {
182
+ operation,
183
+ schemas: this.getSchemas(operation)
184
+ }
185
+ };
186
+ }
187
+ }
188
+ });
189
+ return acc;
190
+ }, {});
191
+ const promises = Object.keys(this.operationsByMethod).reduce((acc, path2) => {
192
+ const methods = this.operationsByMethod[path2] ? Object.keys(this.operationsByMethod[path2]) : [];
193
+ methods.forEach((method) => {
194
+ const { operation } = this.operationsByMethod[path2]?.[method];
195
+ const options = this.#getOptions(operation, method);
196
+ const methodToCall = this[method];
197
+ if (typeof methodToCall === "function") {
198
+ const promiseMethod = methodToCall?.call(this, operation, {
199
+ ...this.options,
200
+ ...options
201
+ });
202
+ if (promiseMethod) {
203
+ acc.push(promiseMethod);
204
+ }
205
+ }
206
+ const promiseOperation = this.operation.call(this, operation, {
207
+ ...this.options,
208
+ ...options
209
+ });
210
+ if (promiseOperation) {
211
+ acc.push(promiseOperation);
212
+ }
213
+ generators?.forEach((generator) => {
214
+ const promise = generator.operation?.({
215
+ instance: this,
216
+ operation,
217
+ options: {
218
+ ...this.options,
219
+ ...options
220
+ }
221
+ });
222
+ if (promise) {
223
+ acc.push(promise);
224
+ }
225
+ });
226
+ });
227
+ return acc;
228
+ }, []);
229
+ const operations = Object.values(this.operationsByMethod).map((item) => Object.values(item).map((item2) => item2.operation));
230
+ promises.push(this.all(operations.flat().filter(Boolean), this.operationsByMethod));
231
+ generators?.forEach((generator) => {
232
+ const promise = generator.operations?.({
233
+ instance: this,
234
+ operations: operations.flat().filter(Boolean),
235
+ operationsByMethod: this.operationsByMethod,
236
+ options: this.options
237
+ });
238
+ if (promise) {
239
+ promises.push(promise);
240
+ }
241
+ });
242
+ const files = await Promise.all(promises);
243
+ return files.flat().filter(Boolean);
244
+ }
245
+ /**
246
+ * Operation
247
+ */
248
+ async operation(operation, options) {
249
+ return [];
250
+ }
251
+ /**
252
+ * GET
253
+ */
254
+ async get(operation, options) {
255
+ return [];
256
+ }
257
+ /**
258
+ * POST
259
+ */
260
+ async post(operation, options) {
261
+ return [];
262
+ }
263
+ /**
264
+ * PATCH
265
+ */
266
+ async patch(operation, options) {
267
+ return [];
268
+ }
269
+ /**
270
+ * PUT
271
+ */
272
+ async put(operation, options) {
273
+ return [];
274
+ }
275
+ /**
276
+ * DELETE
277
+ */
278
+ async delete(operation, options) {
279
+ return [];
280
+ }
281
+ /**
282
+ * Combination of GET, POST, PATCH, PUT, DELETE
283
+ */
284
+ async all(operations, paths) {
285
+ return [];
286
+ }
287
+ };
288
+
289
+ // src/plugin.ts
290
+ init_esm_shims();
291
+
292
+ // src/SchemaGenerator.ts
293
+ init_esm_shims();
294
+
295
+ // src/SchemaMapper.ts
296
+ init_esm_shims();
297
+ var schemaKeywords = {
298
+ any: "any",
299
+ strict: "strict",
300
+ unknown: "unknown",
301
+ number: "number",
302
+ integer: "integer",
303
+ string: "string",
304
+ boolean: "boolean",
305
+ undefined: "undefined",
306
+ nullable: "nullable",
307
+ null: "null",
308
+ nullish: "nullish",
309
+ array: "array",
310
+ tuple: "tuple",
311
+ enum: "enum",
312
+ union: "union",
313
+ datetime: "datetime",
314
+ date: "date",
315
+ email: "email",
316
+ uuid: "uuid",
317
+ url: "url",
318
+ /* intersection */
319
+ default: "default",
320
+ const: "const",
321
+ and: "and",
322
+ describe: "describe",
323
+ min: "min",
324
+ max: "max",
325
+ optional: "optional",
326
+ readOnly: "readOnly",
327
+ // custom ones
328
+ object: "object",
329
+ ref: "ref",
330
+ matches: "matches",
331
+ firstName: "firstName",
332
+ lastName: "lastName",
333
+ password: "password",
334
+ phone: "phone",
335
+ blob: "blob",
336
+ deprecated: "deprecated",
337
+ example: "example",
338
+ schema: "schema",
339
+ catchall: "catchall",
340
+ time: "time",
341
+ name: "name"
342
+ };
343
+ function isKeyword(meta, keyword) {
344
+ return meta.keyword === keyword;
345
+ }
346
+
347
+ // src/SchemaGenerator.ts
348
+ var SchemaGenerator = class _SchemaGenerator extends BaseGenerator {
349
+ // Collect the types of all referenced schemas, so we can export them later
350
+ refs = {};
351
+ // Keep track of already used type aliases
352
+ #usedAliasNames = {};
353
+ /**
354
+ * Creates a type node from a given schema.
355
+ * Delegates to getBaseTypeFromSchema internally and
356
+ * optionally adds a union with null.
357
+ */
358
+ parse(props) {
359
+ const options = this.#getOptions(props);
360
+ const defaultSchemas = this.#parseSchemaObject(props);
361
+ const schemas = options.transformers?.schema?.(props, defaultSchemas) || defaultSchemas || [];
362
+ return uniqueWith(schemas, isDeepEqual);
363
+ }
364
+ deepSearch(tree, keyword) {
365
+ return _SchemaGenerator.deepSearch(tree, keyword);
366
+ }
367
+ find(tree, keyword) {
368
+ return _SchemaGenerator.find(tree, keyword);
369
+ }
370
+ static deepSearch(tree, keyword) {
371
+ const foundItems = [];
372
+ tree?.forEach((schema) => {
373
+ if (schema.keyword === keyword) {
374
+ foundItems.push(schema);
375
+ }
376
+ if (schema.keyword === schemaKeywords.object) {
377
+ const subItem = schema;
378
+ Object.values(subItem.args?.properties || {}).forEach((entrySchema) => {
379
+ foundItems.push(..._SchemaGenerator.deepSearch(entrySchema, keyword));
380
+ });
381
+ Object.values(subItem.args?.additionalProperties || {}).forEach((entrySchema) => {
382
+ foundItems.push(..._SchemaGenerator.deepSearch([entrySchema], keyword));
383
+ });
384
+ }
385
+ if (schema.keyword === schemaKeywords.array) {
386
+ const subItem = schema;
387
+ subItem.args.items.forEach((entrySchema) => {
388
+ foundItems.push(..._SchemaGenerator.deepSearch([entrySchema], keyword));
389
+ });
390
+ }
391
+ if (schema.keyword === schemaKeywords.and) {
392
+ const subItem = schema;
393
+ subItem.args.forEach((entrySchema) => {
394
+ foundItems.push(..._SchemaGenerator.deepSearch([entrySchema], keyword));
395
+ });
396
+ }
397
+ if (schema.keyword === schemaKeywords.tuple) {
398
+ const subItem = schema;
399
+ subItem.args.items.forEach((entrySchema) => {
400
+ foundItems.push(..._SchemaGenerator.deepSearch([entrySchema], keyword));
401
+ });
402
+ }
403
+ if (schema.keyword === schemaKeywords.union) {
404
+ const subItem = schema;
405
+ subItem.args.forEach((entrySchema) => {
406
+ foundItems.push(..._SchemaGenerator.deepSearch([entrySchema], keyword));
407
+ });
408
+ }
409
+ });
410
+ return foundItems;
411
+ }
412
+ static findInObject(tree, keyword) {
413
+ let foundItem = void 0;
414
+ tree?.forEach((schema) => {
415
+ if (!foundItem && schema.keyword === keyword) {
416
+ foundItem = schema;
417
+ }
418
+ if (schema.keyword === schemaKeywords.object) {
419
+ const subItem = schema;
420
+ Object.values(subItem.args?.properties || {}).forEach((entrySchema) => {
421
+ if (!foundItem) {
422
+ foundItem = _SchemaGenerator.find(entrySchema, keyword);
423
+ }
424
+ });
425
+ Object.values(subItem.args?.additionalProperties || {}).forEach((entrySchema) => {
426
+ if (!foundItem) {
427
+ foundItem = _SchemaGenerator.find([entrySchema], keyword);
428
+ }
429
+ });
430
+ }
431
+ });
432
+ return foundItem;
433
+ }
434
+ static find(tree, keyword) {
435
+ let foundItem = void 0;
436
+ tree?.forEach((schema) => {
437
+ if (!foundItem && schema.keyword === keyword) {
438
+ foundItem = schema;
439
+ }
440
+ if (schema.keyword === schemaKeywords.array) {
441
+ const subItem = schema;
442
+ subItem.args.items.forEach((entrySchema) => {
443
+ if (!foundItem) {
444
+ foundItem = _SchemaGenerator.find([entrySchema], keyword);
445
+ }
446
+ });
447
+ }
448
+ if (schema.keyword === schemaKeywords.and) {
449
+ const subItem = schema;
450
+ subItem.args.forEach((entrySchema) => {
451
+ if (!foundItem) {
452
+ foundItem = _SchemaGenerator.find([entrySchema], keyword);
453
+ }
454
+ });
455
+ }
456
+ if (schema.keyword === schemaKeywords.tuple) {
457
+ const subItem = schema;
458
+ subItem.args.items.forEach((entrySchema) => {
459
+ if (!foundItem) {
460
+ foundItem = _SchemaGenerator.find([entrySchema], keyword);
461
+ }
462
+ });
463
+ }
464
+ if (schema.keyword === schemaKeywords.union) {
465
+ const subItem = schema;
466
+ subItem.args.forEach((entrySchema) => {
467
+ if (!foundItem) {
468
+ foundItem = _SchemaGenerator.find([entrySchema], keyword);
469
+ }
470
+ });
471
+ }
472
+ });
473
+ return foundItem;
474
+ }
475
+ #getUsedEnumNames(props) {
476
+ const options = this.#getOptions(props);
477
+ return options.usedEnumNames || {};
478
+ }
479
+ #getOptions({ name }) {
480
+ const { override = [] } = this.context;
481
+ return {
482
+ ...this.options,
483
+ ...override.find(({ pattern, type }) => {
484
+ if (name && type === "schemaName") {
485
+ return !!name.match(pattern);
486
+ }
487
+ return false;
488
+ })?.options || {}
489
+ };
490
+ }
491
+ #getUnknownReturn(props) {
492
+ const options = this.#getOptions(props);
493
+ if (options.unknownType === "any") {
494
+ return schemaKeywords.any;
495
+ }
496
+ return schemaKeywords.unknown;
497
+ }
498
+ /**
499
+ * Recursively creates a type literal with the given props.
500
+ */
501
+ #parseProperties({ schema, name }) {
502
+ const properties = schema?.properties || {};
503
+ const additionalProperties = schema?.additionalProperties;
504
+ const required = schema?.required;
505
+ const propertiesSchemas = Object.keys(properties).map((propertyName) => {
506
+ const validationFunctions = [];
507
+ const propertySchema = properties[propertyName];
508
+ const isRequired = Array.isArray(required) ? required?.includes(propertyName) : !!required;
509
+ const nullable = propertySchema.nullable ?? propertySchema["x-nullable"] ?? false;
510
+ validationFunctions.push(...this.parse({ schema: propertySchema, name: propertyName, parentName: name }));
511
+ validationFunctions.push({
512
+ keyword: schemaKeywords.name,
513
+ args: propertyName
514
+ });
515
+ if (!isRequired && nullable) {
516
+ validationFunctions.push({ keyword: schemaKeywords.nullish });
517
+ } else if (!isRequired) {
518
+ validationFunctions.push({ keyword: schemaKeywords.optional });
519
+ }
520
+ return {
521
+ [propertyName]: validationFunctions
522
+ };
523
+ }).reduce((acc, curr) => ({ ...acc, ...curr }), {});
524
+ let additionalPropertiesSchemas = [];
525
+ if (additionalProperties) {
526
+ additionalPropertiesSchemas = additionalProperties === true ? [{ keyword: this.#getUnknownReturn({ schema, name }) }] : this.parse({ schema: additionalProperties, parentName: name });
527
+ }
528
+ return [
529
+ {
530
+ keyword: schemaKeywords.object,
531
+ args: {
532
+ properties: propertiesSchemas,
533
+ additionalProperties: additionalPropertiesSchemas
534
+ }
535
+ }
536
+ ];
537
+ }
538
+ /**
539
+ * Create a type alias for the schema referenced by the given ReferenceObject
540
+ */
541
+ #getRefAlias(obj) {
542
+ const { $ref } = obj;
543
+ let ref = this.refs[$ref];
544
+ const originalName = getUniqueName($ref.replace(/.+\//, ""), this.#usedAliasNames);
545
+ const propertyName = this.context.pluginManager.resolveName({
546
+ name: originalName,
547
+ pluginKey: this.context.plugin.key,
548
+ type: "function"
549
+ });
550
+ if (ref) {
551
+ return [
552
+ {
553
+ keyword: schemaKeywords.ref,
554
+ args: { name: ref.propertyName, path: ref.path }
555
+ }
556
+ ];
557
+ }
558
+ const fileName = this.context.pluginManager.resolveName({
559
+ name: originalName,
560
+ pluginKey: this.context.plugin.key,
561
+ type: "file"
562
+ });
563
+ const file = this.context.pluginManager.getFile({
564
+ name: fileName,
565
+ pluginKey: this.context.plugin.key,
566
+ extName: ".ts"
567
+ });
568
+ ref = this.refs[$ref] = {
569
+ propertyName,
570
+ originalName,
571
+ path: file.path
572
+ };
573
+ return [
574
+ {
575
+ keyword: schemaKeywords.ref,
576
+ args: { name: ref.propertyName, path: ref?.path }
577
+ }
578
+ ];
579
+ }
580
+ #getParsedSchemaObject(schema) {
581
+ const parsedSchema = getSchemaFactory(this.context.oas)(schema);
582
+ return parsedSchema;
583
+ }
584
+ /**
585
+ * This is the very core of the OpenAPI to TS conversion - it takes a
586
+ * schema and returns the appropriate type.
587
+ */
588
+ #parseSchemaObject({ schema: _schema, name, parentName }) {
589
+ const options = this.#getOptions({ schema: _schema, name });
590
+ const unknownReturn = this.#getUnknownReturn({ schema: _schema, name });
591
+ const { schema, version } = this.#getParsedSchemaObject(_schema);
592
+ if (!schema) {
593
+ return [{ keyword: unknownReturn }];
594
+ }
595
+ const baseItems = [
596
+ {
597
+ keyword: schemaKeywords.schema,
598
+ args: {
599
+ type: schema.type,
600
+ format: schema.format
601
+ }
602
+ }
603
+ ];
604
+ const min = schema.minimum ?? schema.minLength ?? schema.minItems ?? void 0;
605
+ const max = schema.maximum ?? schema.maxLength ?? schema.maxItems ?? void 0;
606
+ const nullable = schema.nullable ?? schema["x-nullable"] ?? false;
607
+ if (schema.default !== void 0 && !Array.isArray(schema.default)) {
608
+ if (typeof schema.default === "string") {
609
+ baseItems.push({
610
+ keyword: schemaKeywords.default,
611
+ args: transformers.stringify(schema.default)
612
+ });
613
+ } else if (typeof schema.default === "boolean") {
614
+ baseItems.push({
615
+ keyword: schemaKeywords.default,
616
+ args: schema.default ?? false
617
+ });
618
+ } else {
619
+ baseItems.push({
620
+ keyword: schemaKeywords.default,
621
+ args: schema.default
622
+ });
623
+ }
624
+ }
625
+ if (schema.description) {
626
+ baseItems.push({
627
+ keyword: schemaKeywords.describe,
628
+ args: schema.description
629
+ });
630
+ }
631
+ if (schema.pattern) {
632
+ baseItems.unshift({
633
+ keyword: schemaKeywords.matches,
634
+ args: schema.pattern
635
+ });
636
+ }
637
+ if (max !== void 0) {
638
+ baseItems.unshift({ keyword: schemaKeywords.max, args: max });
639
+ }
640
+ if (min !== void 0) {
641
+ baseItems.unshift({ keyword: schemaKeywords.min, args: min });
642
+ }
643
+ if (nullable) {
644
+ baseItems.push({ keyword: schemaKeywords.nullable });
645
+ }
646
+ if (schema.type && Array.isArray(schema.type)) {
647
+ const [_schema2, nullable2] = schema.type;
648
+ if (nullable2 === "null") {
649
+ baseItems.push({ keyword: schemaKeywords.nullable });
650
+ }
651
+ }
652
+ if (schema.readOnly) {
653
+ baseItems.push({ keyword: schemaKeywords.readOnly });
654
+ }
655
+ if (isReference(schema)) {
656
+ return [
657
+ ...this.#getRefAlias(schema),
658
+ nullable && { keyword: schemaKeywords.nullable },
659
+ {
660
+ keyword: schemaKeywords.schema,
661
+ args: {
662
+ type: schema.type,
663
+ format: schema.format
664
+ }
665
+ }
666
+ ].filter(Boolean);
667
+ }
668
+ if (schema.oneOf) {
669
+ const schemaWithoutOneOf = { ...schema, oneOf: void 0 };
670
+ const union = {
671
+ keyword: schemaKeywords.union,
672
+ args: schema.oneOf.map((item) => {
673
+ return item && this.parse({ schema: item, name, parentName })[0];
674
+ }).filter(Boolean).filter((item) => {
675
+ return item && item.keyword !== unknownReturn;
676
+ })
677
+ };
678
+ if (schemaWithoutOneOf.properties) {
679
+ return [...this.parse({ schema: schemaWithoutOneOf, name, parentName }), union, ...baseItems];
680
+ }
681
+ return [union, ...baseItems];
682
+ }
683
+ if (schema.anyOf) {
684
+ const schemaWithoutAnyOf = { ...schema, anyOf: void 0 };
685
+ const union = {
686
+ keyword: schemaKeywords.union,
687
+ args: schema.anyOf.map((item) => {
688
+ return item && this.parse({ schema: item, name, parentName })[0];
689
+ }).filter(Boolean).filter((item) => {
690
+ return item && item.keyword !== unknownReturn;
691
+ }).map((item) => {
692
+ if (isKeyword(item, schemaKeywords.object)) {
693
+ return {
694
+ ...item,
695
+ args: {
696
+ ...item.args,
697
+ strict: true
698
+ }
699
+ };
700
+ }
701
+ return item;
702
+ })
703
+ };
704
+ if (schemaWithoutAnyOf.properties) {
705
+ return [...this.parse({ schema: schemaWithoutAnyOf, name, parentName }), union, ...baseItems];
706
+ }
707
+ return [union, ...baseItems];
708
+ }
709
+ if (schema.allOf) {
710
+ const schemaWithoutAllOf = { ...schema, allOf: void 0 };
711
+ const and = {
712
+ keyword: schemaKeywords.and,
713
+ args: schema.allOf.map((item) => {
714
+ return item && this.parse({ schema: item, name, parentName })[0];
715
+ }).filter(Boolean).filter((item) => {
716
+ return item && item.keyword !== unknownReturn;
717
+ })
718
+ };
719
+ if (schemaWithoutAllOf.properties) {
720
+ return [
721
+ {
722
+ ...and,
723
+ args: [...and.args || [], ...this.parse({ schema: schemaWithoutAllOf, name, parentName })]
724
+ },
725
+ ...baseItems
726
+ ];
727
+ }
728
+ return [and, ...baseItems];
729
+ }
730
+ if (schema.enum) {
731
+ const enumName = getUniqueName(pascalCase([parentName, name, options.enumSuffix].join(" ")), this.#getUsedEnumNames({ schema, name }));
732
+ const typeName = this.context.pluginManager.resolveName({
733
+ name: enumName,
734
+ pluginKey: this.context.plugin.key,
735
+ type: "type"
736
+ });
737
+ const nullableEnum = schema.enum.includes(null);
738
+ if (nullableEnum) {
739
+ baseItems.push({ keyword: schemaKeywords.nullable });
740
+ }
741
+ const filteredValues = schema.enum.filter((value) => value !== null);
742
+ const extensionEnums = ["x-enumNames", "x-enum-varnames"].filter((extensionKey) => extensionKey in schema).map((extensionKey) => {
743
+ return [
744
+ {
745
+ keyword: schemaKeywords.enum,
746
+ args: {
747
+ name,
748
+ typeName,
749
+ asConst: false,
750
+ items: [...new Set(schema[extensionKey])].map((name2, index) => ({
751
+ name: transformers.stringify(name2),
752
+ value: schema.enum?.[index],
753
+ format: isNumber(schema.enum?.[index]) ? "number" : "string"
754
+ }))
755
+ }
756
+ },
757
+ ...baseItems.filter(
758
+ (item) => item.keyword !== schemaKeywords.min && item.keyword !== schemaKeywords.max && item.keyword !== schemaKeywords.matches
759
+ )
760
+ ];
761
+ });
762
+ if (schema.type === "number" || schema.type === "integer") {
763
+ const enumNames = extensionEnums[0]?.find((item) => isKeyword(item, schemaKeywords.enum));
764
+ return [
765
+ {
766
+ keyword: schemaKeywords.enum,
767
+ args: {
768
+ name: enumName,
769
+ typeName,
770
+ asConst: true,
771
+ items: enumNames?.args?.items ? [...new Set(enumNames.args.items)].map(({ name: name2, value }) => ({
772
+ name: name2,
773
+ value,
774
+ format: "number"
775
+ })) : [...new Set(filteredValues)].map((value) => {
776
+ return {
777
+ name: value,
778
+ value,
779
+ format: "number"
780
+ };
781
+ })
782
+ }
783
+ },
784
+ ...baseItems.filter((item) => item.keyword !== schemaKeywords.min && item.keyword !== schemaKeywords.max && item.keyword !== schemaKeywords.matches)
785
+ ];
786
+ }
787
+ if (extensionEnums.length > 0 && extensionEnums[0]) {
788
+ return extensionEnums[0];
789
+ }
790
+ return [
791
+ {
792
+ keyword: schemaKeywords.enum,
793
+ args: {
794
+ name: enumName,
795
+ typeName,
796
+ asConst: false,
797
+ items: [...new Set(filteredValues)].map((value) => ({
798
+ name: transformers.stringify(value),
799
+ value,
800
+ format: isNumber(value) ? "number" : "string"
801
+ }))
802
+ }
803
+ },
804
+ ...baseItems.filter((item) => item.keyword !== schemaKeywords.min && item.keyword !== schemaKeywords.max && item.keyword !== schemaKeywords.matches)
805
+ ];
806
+ }
807
+ if ("prefixItems" in schema) {
808
+ const prefixItems = schema.prefixItems;
809
+ const min2 = schema.minimum ?? schema.minLength ?? schema.minItems ?? void 0;
810
+ const max2 = schema.maximum ?? schema.maxLength ?? schema.maxItems ?? void 0;
811
+ return [
812
+ {
813
+ keyword: schemaKeywords.tuple,
814
+ args: {
815
+ min: min2,
816
+ max: max2,
817
+ items: prefixItems.map((item) => {
818
+ return this.parse({ schema: item, name, parentName })[0];
819
+ }).filter(Boolean)
820
+ }
821
+ },
822
+ ...baseItems.filter((item) => item.keyword !== schemaKeywords.min && item.keyword !== schemaKeywords.max)
823
+ ];
824
+ }
825
+ if (version === "3.1" && "const" in schema) {
826
+ if (schema["const"]) {
827
+ return [
828
+ {
829
+ keyword: schemaKeywords.const,
830
+ args: {
831
+ name: schema["const"],
832
+ format: typeof schema["const"] === "number" ? "number" : "string",
833
+ value: schema["const"]
834
+ }
835
+ },
836
+ ...baseItems
837
+ ];
838
+ }
839
+ return [{ keyword: schemaKeywords.null }];
840
+ }
841
+ if (schema.format) {
842
+ switch (schema.format) {
843
+ case "binary":
844
+ baseItems.push({ keyword: schemaKeywords.blob });
845
+ return baseItems;
846
+ case "date-time":
847
+ if (options.dateType) {
848
+ if (options.dateType === "date") {
849
+ baseItems.unshift({ keyword: schemaKeywords.date, args: { type: "date" } });
850
+ return baseItems;
851
+ }
852
+ if (options.dateType === "stringOffset") {
853
+ baseItems.unshift({ keyword: schemaKeywords.datetime, args: { offset: true } });
854
+ return baseItems;
855
+ }
856
+ if (options.dateType === "stringLocal") {
857
+ baseItems.unshift({ keyword: schemaKeywords.datetime, args: { local: true } });
858
+ return baseItems;
859
+ }
860
+ baseItems.unshift({ keyword: schemaKeywords.datetime, args: { offset: false } });
861
+ return baseItems;
862
+ }
863
+ break;
864
+ case "date":
865
+ if (options.dateType) {
866
+ if (options.dateType === "date") {
867
+ baseItems.unshift({ keyword: schemaKeywords.date, args: { type: "date" } });
868
+ return baseItems;
869
+ }
870
+ baseItems.unshift({ keyword: schemaKeywords.date, args: { type: "string" } });
871
+ return baseItems;
872
+ }
873
+ break;
874
+ case "time":
875
+ if (options.dateType) {
876
+ if (options.dateType === "date") {
877
+ baseItems.unshift({ keyword: schemaKeywords.time, args: { type: "date" } });
878
+ return baseItems;
879
+ }
880
+ baseItems.unshift({ keyword: schemaKeywords.time, args: { type: "string" } });
881
+ return baseItems;
882
+ }
883
+ break;
884
+ case "uuid":
885
+ baseItems.unshift({ keyword: schemaKeywords.uuid });
886
+ break;
887
+ case "email":
888
+ case "idn-email":
889
+ baseItems.unshift({ keyword: schemaKeywords.email });
890
+ break;
891
+ case "uri":
892
+ case "ipv4":
893
+ case "ipv6":
894
+ case "uri-reference":
895
+ case "hostname":
896
+ case "idn-hostname":
897
+ baseItems.unshift({ keyword: schemaKeywords.url });
898
+ break;
899
+ }
900
+ }
901
+ if ("items" in schema || schema.type === "array") {
902
+ const min2 = schema.minimum ?? schema.minLength ?? schema.minItems ?? void 0;
903
+ const max2 = schema.maximum ?? schema.maxLength ?? schema.maxItems ?? void 0;
904
+ const items = this.parse({ schema: "items" in schema ? schema.items : [], name, parentName });
905
+ return [
906
+ {
907
+ keyword: schemaKeywords.array,
908
+ args: {
909
+ items,
910
+ min: min2,
911
+ max: max2
912
+ }
913
+ },
914
+ ...baseItems.filter((item) => item.keyword !== schemaKeywords.min && item.keyword !== schemaKeywords.max)
915
+ ];
916
+ }
917
+ if (schema.properties || schema.additionalProperties) {
918
+ return [...this.#parseProperties({ schema, name }), ...baseItems];
919
+ }
920
+ if (schema.type) {
921
+ if (Array.isArray(schema.type)) {
922
+ const [type] = schema.type;
923
+ return [
924
+ ...this.parse({
925
+ schema: {
926
+ ...schema,
927
+ type
928
+ },
929
+ name,
930
+ parentName
931
+ }),
932
+ ...baseItems
933
+ ].filter(Boolean);
934
+ }
935
+ if (!["boolean", "object", "number", "string", "integer"].includes(schema.type)) {
936
+ this.context.pluginManager.logger.emit("warning", `Schema type '${schema.type}' is not valid for schema ${parentName}.${name}`);
937
+ }
938
+ return [{ keyword: schema.type }, ...baseItems];
939
+ }
940
+ return [{ keyword: unknownReturn }];
941
+ }
942
+ async build(...generators) {
943
+ const { oas, contentType, include } = this.context;
944
+ const schemas = getSchemas({ oas, contentType, includes: include });
945
+ const promises = Object.entries(schemas).reduce((acc, [name, value]) => {
946
+ if (!value) {
947
+ return acc;
948
+ }
949
+ const options = this.#getOptions({ name });
950
+ const promiseOperation = this.schema.call(this, name, value, {
951
+ ...this.options,
952
+ ...options
953
+ });
954
+ if (promiseOperation) {
955
+ acc.push(promiseOperation);
956
+ }
957
+ generators?.forEach((generator) => {
958
+ const tree = this.parse({ schema: value, name });
959
+ const promise = generator.schema?.({
960
+ instance: this,
961
+ schema: {
962
+ name,
963
+ value,
964
+ tree
965
+ },
966
+ options: {
967
+ ...this.options,
968
+ ...options
969
+ }
970
+ });
971
+ if (promise) {
972
+ acc.push(promise);
973
+ }
974
+ });
975
+ return acc;
976
+ }, []);
977
+ const files = await Promise.all(promises);
978
+ return files.flat().filter(Boolean);
979
+ }
980
+ /**
981
+ * Schema
982
+ */
983
+ async schema(name, object, options) {
984
+ return [];
985
+ }
986
+ };
987
+
988
+ // src/plugin.ts
989
+ var pluginOasName = "plugin-oas";
990
+ var pluginOas = createPlugin((options) => {
991
+ const {
992
+ output = {
993
+ path: "schemas",
994
+ export: false,
995
+ exportType: "barrelNamed"
996
+ },
997
+ experimentalFilter: filter,
998
+ experimentalSort: sort,
999
+ validate = true,
1000
+ generators = [jsonGenerator],
1001
+ serverIndex = 0,
1002
+ contentType,
1003
+ oasClass
1004
+ } = options;
1005
+ const getOas = async ({ config, logger, formatOptions }) => {
1006
+ try {
1007
+ const oas = await parseFromConfig(config, formatOptions, oasClass);
1008
+ if (validate) {
1009
+ await oas.valdiate();
1010
+ }
1011
+ return oas;
1012
+ } catch (e) {
1013
+ const error = e;
1014
+ logger.emit("warning", error?.message);
1015
+ return parseFromConfig(config, {}, oasClass);
1016
+ }
1017
+ };
1018
+ return {
1019
+ name: pluginOasName,
1020
+ output,
1021
+ options,
1022
+ context() {
1023
+ const { config, logger } = this;
1024
+ return {
1025
+ getOas(formatOptions) {
1026
+ return getOas({ config, logger, formatOptions });
1027
+ },
1028
+ async getSchemas({ includes } = {}) {
1029
+ const oas = await this.getOas();
1030
+ return getSchemas({ oas, contentType, includes });
1031
+ },
1032
+ async getBaseURL() {
1033
+ const oasInstance = await this.getOas();
1034
+ return oasInstance.api.servers?.at(serverIndex)?.url;
1035
+ },
1036
+ contentType
1037
+ };
1038
+ },
1039
+ resolvePath(baseName, pathMode, options2) {
1040
+ const root = path.resolve(this.config.root, this.config.output.path);
1041
+ const mode = pathMode ?? FileManager.getMode(path.resolve(root, output.path));
1042
+ if (mode === "single") {
1043
+ return path.resolve(root, output.path);
1044
+ }
1045
+ return path.resolve(root, output.path, baseName);
1046
+ },
1047
+ async buildStart() {
1048
+ if (!output) {
1049
+ return;
1050
+ }
1051
+ const oas = await getOas({
1052
+ config: this.config,
1053
+ logger: this.logger,
1054
+ formatOptions: {
1055
+ filterSet: filter,
1056
+ sortSet: sort
1057
+ }
1058
+ });
1059
+ await oas.dereference();
1060
+ const schemaGenerator = new SchemaGenerator(
1061
+ {
1062
+ unknownType: "unknown",
1063
+ dateType: "date",
1064
+ transformers: {},
1065
+ ...this.plugin.options
1066
+ },
1067
+ {
1068
+ oas,
1069
+ pluginManager: this.pluginManager,
1070
+ plugin: this.plugin,
1071
+ contentType,
1072
+ include: void 0,
1073
+ override: void 0,
1074
+ mode: "split",
1075
+ output: output.path
1076
+ }
1077
+ );
1078
+ const schemaFiles = await schemaGenerator.build(...generators);
1079
+ await this.addFile(...schemaFiles);
1080
+ const operationGenerator = new OperationGenerator(this.plugin.options, {
1081
+ oas,
1082
+ pluginManager: this.pluginManager,
1083
+ plugin: this.plugin,
1084
+ contentType,
1085
+ exclude: void 0,
1086
+ include: void 0,
1087
+ override: void 0,
1088
+ mode: "split"
1089
+ });
1090
+ const operationFiles = await operationGenerator.build(...generators);
1091
+ await this.addFile(...operationFiles);
1092
+ }
1093
+ };
1094
+ });
1095
+
1096
+ export { OperationGenerator, SchemaGenerator, isKeyword, pluginOas, pluginOasName, schemaKeywords };
1097
+ //# sourceMappingURL=chunk-7XBQZ7AX.js.map
1098
+ //# sourceMappingURL=chunk-7XBQZ7AX.js.map