@kubb/swagger-ts 1.15.0-canary.20231026T132100 → 1.15.0-canary.20231026T165055

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/dist/hooks.js DELETED
@@ -1,605 +0,0 @@
1
- import { createRequire } from 'module';
2
- import { useResolve as useResolve$1 } from '@kubb/swagger/hooks';
3
- import path from 'path';
4
- import { createPlugin, PluginManager, FileManager, SchemaGenerator } from '@kubb/core';
5
- import { renderTemplate, getRelativePath, transformers, getUniqueName } from '@kubb/core/utils';
6
- import { pluginName as pluginName$1, OasBuilder, ImportsGenerator, OperationGenerator as OperationGenerator$1, resolve } from '@kubb/swagger';
7
- import { camelCase, camelCaseTransformMerge, pascalCase, pascalCaseTransformMerge } from 'change-case';
8
- import { print } from '@kubb/parser';
9
- import * as factory from '@kubb/parser/factory';
10
- import { refsSorter, isReference } from '@kubb/swagger/utils';
11
-
12
- createRequire(import.meta.url);
13
- var TypeGenerator = class extends SchemaGenerator {
14
- refs = {};
15
- extraNodes = [];
16
- aliases = [];
17
- // Keep track of already used type aliases
18
- #usedAliasNames = {};
19
- #caseOptions = {
20
- delimiter: "",
21
- stripRegexp: /[^A-Z0-9$]/gi
22
- };
23
- constructor(options = {
24
- usedEnumNames: {},
25
- withJSDocs: true,
26
- resolveName: ({ name }) => name,
27
- enumType: "asConst",
28
- dateType: "string",
29
- optionalType: "questionToken"
30
- }) {
31
- super(options);
32
- return this;
33
- }
34
- build({
35
- schema,
36
- baseName,
37
- description,
38
- keysToOmit
39
- }) {
40
- const nodes = [];
41
- const type = this.#getTypeFromSchema(schema, baseName);
42
- if (!type) {
43
- return this.extraNodes;
44
- }
45
- const node = factory.createTypeAliasDeclaration({
46
- modifiers: [factory.modifiers.export],
47
- name: this.options.resolveName({ name: baseName }) || baseName,
48
- type: keysToOmit?.length ? factory.createOmitDeclaration({ keys: keysToOmit, type, nonNullable: true }) : type
49
- });
50
- if (description) {
51
- nodes.push(
52
- factory.appendJSDocToNode({
53
- node,
54
- comments: [`@description ${description}`]
55
- })
56
- );
57
- } else {
58
- nodes.push(node);
59
- }
60
- const filterdNodes = nodes.filter(
61
- (node2) => !this.extraNodes.some(
62
- (extraNode) => extraNode?.name?.escapedText === node2?.name?.escapedText
63
- )
64
- );
65
- return [...this.extraNodes, ...filterdNodes];
66
- }
67
- /**
68
- * Creates a type node from a given schema.
69
- * Delegates to getBaseTypeFromSchema internally and
70
- * optionally adds a union with null.
71
- */
72
- #getTypeFromSchema(schema, name) {
73
- const type = this.#getBaseTypeFromSchema(schema, name);
74
- if (!type) {
75
- return null;
76
- }
77
- if (schema && !schema.nullable) {
78
- return type;
79
- }
80
- return factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] });
81
- }
82
- /**
83
- * Recursively creates a type literal with the given props.
84
- */
85
- #getTypeFromProperties(baseSchema, baseName) {
86
- const { optionalType } = this.options;
87
- const properties = baseSchema?.properties || {};
88
- const required = baseSchema?.required;
89
- const additionalProperties = baseSchema?.additionalProperties;
90
- const members = Object.keys(properties).map((name) => {
91
- const schema = properties[name];
92
- const isRequired = required && required.includes(name);
93
- let type = this.#getTypeFromSchema(schema, this.options.resolveName({ name: `${baseName || ""} ${name}` }));
94
- if (!type) {
95
- return null;
96
- }
97
- if (!isRequired && ["undefined", "questionTokenAndUndefined"].includes(optionalType)) {
98
- type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] });
99
- }
100
- const propertySignature = factory.createPropertySignature({
101
- questionToken: ["questionToken", "questionTokenAndUndefined"].includes(optionalType) && !isRequired,
102
- name,
103
- type,
104
- readOnly: schema.readOnly
105
- });
106
- if (this.options.withJSDocs) {
107
- return factory.appendJSDocToNode({
108
- node: propertySignature,
109
- comments: [
110
- schema.description ? `@description ${schema.description}` : void 0,
111
- schema.type ? `@type ${schema.type}${isRequired ? "" : " | undefined"} ${schema.format || ""}` : void 0,
112
- schema.example ? `@example ${schema.example}` : void 0,
113
- schema.deprecated ? `@deprecated` : void 0,
114
- schema.default !== void 0 && typeof schema.default === "string" ? `@default '${schema.default}'` : void 0,
115
- schema.default !== void 0 && typeof schema.default !== "string" ? `@default ${schema.default}` : void 0
116
- ].filter(Boolean)
117
- });
118
- }
119
- return propertySignature;
120
- });
121
- if (additionalProperties) {
122
- const type = additionalProperties === true ? factory.keywordTypeNodes.any : this.#getTypeFromSchema(additionalProperties);
123
- if (type) {
124
- members.push(factory.createIndexSignature(type));
125
- }
126
- }
127
- return factory.createTypeLiteralNode(members.filter(Boolean));
128
- }
129
- /**
130
- * Create a type alias for the schema referenced by the given ReferenceObject
131
- */
132
- #getRefAlias(obj, _baseName) {
133
- const { $ref } = obj;
134
- let ref = this.refs[$ref];
135
- if (ref) {
136
- return factory.createTypeReferenceNode(ref.propertyName, void 0);
137
- }
138
- const originalName = getUniqueName($ref.replace(/.+\//, ""), this.#usedAliasNames);
139
- const propertyName = this.options.resolveName({ name: originalName }) || originalName;
140
- ref = this.refs[$ref] = {
141
- propertyName,
142
- originalName
143
- };
144
- return factory.createTypeReferenceNode(ref.propertyName, void 0);
145
- }
146
- /**
147
- * This is the very core of the OpenAPI to TS conversion - it takes a
148
- * schema and returns the appropriate type.
149
- */
150
- #getBaseTypeFromSchema(schema, baseName) {
151
- if (!schema) {
152
- return factory.keywordTypeNodes.any;
153
- }
154
- if (isReference(schema)) {
155
- return this.#getRefAlias(schema, baseName);
156
- }
157
- if (schema.oneOf) {
158
- const schemaWithoutOneOf = { ...schema, oneOf: void 0 };
159
- const union = factory.createUnionDeclaration({
160
- withParentheses: true,
161
- nodes: schema.oneOf.map((item) => {
162
- return this.#getBaseTypeFromSchema(item);
163
- }).filter((item) => {
164
- return item && item !== factory.keywordTypeNodes.any;
165
- })
166
- });
167
- if (schemaWithoutOneOf.properties) {
168
- return factory.createIntersectionDeclaration({
169
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutOneOf, baseName), union].filter(Boolean)
170
- });
171
- }
172
- return union;
173
- }
174
- if (schema.anyOf) {
175
- const schemaWithoutAnyOf = { ...schema, anyOf: void 0 };
176
- const union = factory.createUnionDeclaration({
177
- withParentheses: true,
178
- nodes: schema.anyOf.map((item) => {
179
- return this.#getBaseTypeFromSchema(item);
180
- }).filter((item) => {
181
- return item && item !== factory.keywordTypeNodes.any;
182
- })
183
- });
184
- if (schemaWithoutAnyOf.properties) {
185
- return factory.createIntersectionDeclaration({
186
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutAnyOf, baseName), union].filter(Boolean)
187
- });
188
- }
189
- return union;
190
- }
191
- if (schema.allOf) {
192
- const schemaWithoutAllOf = { ...schema, allOf: void 0 };
193
- const and = factory.createIntersectionDeclaration({
194
- withParentheses: true,
195
- nodes: schema.allOf.map((item) => {
196
- return this.#getBaseTypeFromSchema(item);
197
- }).filter((item) => {
198
- return item && item !== factory.keywordTypeNodes.any;
199
- })
200
- });
201
- if (schemaWithoutAllOf.properties) {
202
- return factory.createIntersectionDeclaration({
203
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutAllOf, baseName), and].filter(Boolean)
204
- });
205
- }
206
- return and;
207
- }
208
- if (schema.enum && baseName) {
209
- const enumName = getUniqueName(baseName, this.options.usedEnumNames);
210
- let enums = [...new Set(schema.enum)].map((key) => [key, key]);
211
- if ("x-enumNames" in schema) {
212
- enums = [...new Set(schema["x-enumNames"])].map((key, index) => {
213
- return [key, schema.enum?.[index]];
214
- });
215
- }
216
- this.extraNodes.push(
217
- ...factory.createEnumDeclaration({
218
- name: camelCase(enumName, this.#caseOptions),
219
- typeName: this.options.resolveName({ name: enumName }),
220
- enums,
221
- type: this.options.enumType
222
- })
223
- );
224
- return factory.createTypeReferenceNode(this.options.resolveName({ name: enumName }), void 0);
225
- }
226
- if (schema.enum) {
227
- return factory.createUnionDeclaration({
228
- nodes: schema.enum.map((name) => {
229
- return factory.createLiteralTypeNode(typeof name === "number" ? factory.createNumericLiteral(name) : factory.createStringLiteral(`${name}`));
230
- })
231
- });
232
- }
233
- if ("items" in schema) {
234
- const node = this.#getTypeFromSchema(schema.items, baseName);
235
- if (node) {
236
- return factory.createArrayTypeNode(node);
237
- }
238
- }
239
- if ("prefixItems" in schema) {
240
- const prefixItems = schema.prefixItems;
241
- return factory.createTupleDeclaration({
242
- nodes: prefixItems.map((item) => {
243
- return this.#getBaseTypeFromSchema(item, void 0);
244
- })
245
- });
246
- }
247
- if (schema.properties || schema.additionalProperties) {
248
- return this.#getTypeFromProperties(schema, baseName);
249
- }
250
- if (schema.type) {
251
- if (Array.isArray(schema.type)) {
252
- const [type, nullable] = schema.type;
253
- return factory.createUnionDeclaration({
254
- nodes: [
255
- this.#getBaseTypeFromSchema(
256
- {
257
- ...schema,
258
- type
259
- },
260
- baseName
261
- ),
262
- nullable ? factory.createLiteralTypeNode(factory.createNull()) : void 0
263
- ].filter(Boolean)
264
- });
265
- }
266
- if (this.options.dateType === "date" && ["date", "date-time"].some((item) => item === schema.format)) {
267
- return factory.createTypeReferenceNode(factory.createIdentifier("Date"));
268
- }
269
- if (schema.type in factory.keywordTypeNodes) {
270
- return factory.keywordTypeNodes[schema.type];
271
- }
272
- }
273
- if (schema.format === "binary") {
274
- return factory.createTypeReferenceNode("Blob", []);
275
- }
276
- return factory.keywordTypeNodes.any;
277
- }
278
- };
279
-
280
- // src/builders/TypeBuilder.ts
281
- var TypeBuilder = class extends OasBuilder {
282
- configure(options) {
283
- if (options) {
284
- this.options = options;
285
- }
286
- if (this.options.fileResolver) {
287
- this.options.withImports = true;
288
- }
289
- return this;
290
- }
291
- print(name) {
292
- const codes = [];
293
- const generated = this.items.filter((operationSchema) => name ? operationSchema.name === name : true).sort(transformers.nameSorter).map((operationSchema) => {
294
- const generator = new TypeGenerator({
295
- usedEnumNames: this.options.usedEnumNames,
296
- withJSDocs: this.options.withJSDocs,
297
- resolveName: this.options.resolveName,
298
- enumType: this.options.enumType,
299
- dateType: this.options.dateType,
300
- optionalType: this.options.optionalType
301
- });
302
- const sources = generator.build({
303
- schema: operationSchema.schema,
304
- baseName: operationSchema.name,
305
- description: operationSchema.description,
306
- keysToOmit: operationSchema.keysToOmit
307
- });
308
- return {
309
- import: {
310
- refs: generator.refs,
311
- name: operationSchema.name
312
- },
313
- sources
314
- };
315
- }).sort(refsSorter);
316
- generated.forEach((item) => {
317
- codes.push(print(item.sources));
318
- });
319
- if (this.options.withImports) {
320
- const importsGenerator = new ImportsGenerator({ fileResolver: this.options.fileResolver });
321
- const importMeta = importsGenerator.build(generated.map((item) => item.import));
322
- if (importMeta) {
323
- const nodes = importMeta.map((item) => {
324
- return factory.createImportDeclaration({
325
- name: [{ propertyName: item.ref.propertyName }],
326
- path: item.path,
327
- isTypeOnly: true
328
- });
329
- });
330
- codes.unshift(print(nodes));
331
- }
332
- }
333
- return transformers.combineCodes(codes);
334
- }
335
- };
336
- var OperationGenerator = class extends OperationGenerator$1 {
337
- resolve(operation) {
338
- const { pluginManager, plugin } = this.context;
339
- return resolve({
340
- operation,
341
- resolveName: pluginManager.resolveName,
342
- resolvePath: pluginManager.resolvePath,
343
- pluginKey: plugin?.key
344
- });
345
- }
346
- async all() {
347
- return null;
348
- }
349
- async get(operation, schemas, options) {
350
- const { mode, enumType, dateType, optionalType, usedEnumNames } = options;
351
- const { pluginManager, plugin } = this.context;
352
- const type = this.resolve(operation);
353
- const fileResolver = (name) => {
354
- const root = pluginManager.resolvePath({ baseName: type.baseName, pluginKey: plugin?.key, options: { tag: operation.getTags()[0]?.name } });
355
- const resolvedTypeId = pluginManager.resolvePath({
356
- baseName: `${name}.ts`,
357
- pluginKey: plugin?.key
358
- });
359
- return getRelativePath(root, resolvedTypeId);
360
- };
361
- const source = new TypeBuilder({
362
- usedEnumNames,
363
- fileResolver: mode === "file" ? void 0 : fileResolver,
364
- withJSDocs: true,
365
- resolveName: (params) => pluginManager.resolveName({ ...params, pluginKey: plugin?.key }),
366
- enumType,
367
- optionalType,
368
- dateType
369
- }).add(schemas.pathParams).add(schemas.queryParams).add(schemas.headerParams).add(schemas.response).add(schemas.errors).configure().print();
370
- return {
371
- path: type.path,
372
- baseName: type.baseName,
373
- source,
374
- meta: {
375
- pluginKey: plugin.key,
376
- tag: operation.getTags()[0]?.name
377
- }
378
- };
379
- }
380
- async post(operation, schemas, options) {
381
- const { mode, enumType, dateType, optionalType, usedEnumNames } = options;
382
- const { pluginManager, plugin } = this.context;
383
- const type = this.resolve(operation);
384
- const fileResolver = (name) => {
385
- const root = pluginManager.resolvePath({ baseName: type.baseName, pluginKey: plugin?.key, options: { tag: operation.getTags()[0]?.name } });
386
- const resolvedTypeId = pluginManager.resolvePath({
387
- baseName: `${name}.ts`,
388
- pluginKey: plugin?.key
389
- });
390
- return getRelativePath(root, resolvedTypeId);
391
- };
392
- const source = new TypeBuilder({
393
- usedEnumNames,
394
- fileResolver: mode === "file" ? void 0 : fileResolver,
395
- withJSDocs: true,
396
- resolveName: (params) => pluginManager.resolveName({ ...params, pluginKey: plugin?.key }),
397
- enumType,
398
- optionalType,
399
- dateType
400
- }).add(schemas.pathParams).add(schemas.queryParams).add(schemas.headerParams).add(schemas.request).add(schemas.response).add(schemas.errors).configure().print();
401
- return {
402
- path: type.path,
403
- baseName: type.baseName,
404
- source,
405
- meta: {
406
- pluginKey: plugin.key,
407
- tag: operation.getTags()[0]?.name
408
- }
409
- };
410
- }
411
- async put(operation, schemas, options) {
412
- return this.post(operation, schemas, options);
413
- }
414
- async patch(operation, schemas, options) {
415
- return this.post(operation, schemas, options);
416
- }
417
- async delete(operation, schemas, options) {
418
- return this.post(operation, schemas, options);
419
- }
420
- };
421
-
422
- // src/plugin.ts
423
- var pluginName = "swagger-ts";
424
- var pluginKey = ["schema", pluginName];
425
- createPlugin((options) => {
426
- const {
427
- output = "types",
428
- groupBy,
429
- skipBy = [],
430
- overrideBy = [],
431
- enumType = "asConst",
432
- dateType = "string",
433
- optionalType = "questionToken",
434
- transformers: transformers2 = {},
435
- exportAs
436
- } = options;
437
- const template = groupBy?.output ? groupBy.output : `${output}/{{tag}}Controller`;
438
- let pluginsOptions;
439
- return {
440
- name: pluginName,
441
- options,
442
- kind: "schema",
443
- validate(plugins) {
444
- pluginsOptions = PluginManager.getDependedPlugins(plugins, [pluginName$1]);
445
- return true;
446
- },
447
- resolvePath(baseName, directory, options2) {
448
- const root = path.resolve(this.config.root, this.config.output.path);
449
- const mode = FileManager.getMode(path.resolve(root, output));
450
- if (mode === "file") {
451
- return path.resolve(root, output);
452
- }
453
- if (options2?.tag && groupBy?.type === "tag") {
454
- const tag = camelCase(options2.tag, { delimiter: "", transform: camelCaseTransformMerge });
455
- return path.resolve(root, renderTemplate(template, { tag }), baseName);
456
- }
457
- return path.resolve(root, output, baseName);
458
- },
459
- resolveName(name) {
460
- const resolvedName = pascalCase(name, { delimiter: "", stripRegexp: /[^A-Z0-9$]/gi, transform: pascalCaseTransformMerge });
461
- return transformers2?.name?.(resolvedName) || resolvedName;
462
- },
463
- async writeFile(source, writePath) {
464
- if (!writePath.endsWith(".ts") || !source) {
465
- return;
466
- }
467
- return this.fileManager.write(source, writePath);
468
- },
469
- async buildStart() {
470
- const [swaggerPlugin] = pluginsOptions;
471
- const oas = await swaggerPlugin.api.getOas();
472
- const schemas = await swaggerPlugin.api.getSchemas();
473
- const root = path.resolve(this.config.root, this.config.output.path);
474
- const mode = FileManager.getMode(path.resolve(root, output));
475
- const usedEnumNames = {};
476
- if (mode === "directory") {
477
- const builder = await new TypeBuilder({
478
- usedEnumNames,
479
- resolveName: (params) => this.resolveName({ pluginKey: this.plugin.key, ...params }),
480
- fileResolver: (name) => {
481
- const resolvedTypeId = this.resolvePath({
482
- baseName: `${name}.ts`,
483
- pluginKey: this.plugin.key
484
- });
485
- const root2 = this.resolvePath({ baseName: ``, pluginKey: this.plugin.key });
486
- return getRelativePath(root2, resolvedTypeId);
487
- },
488
- withJSDocs: true,
489
- enumType,
490
- dateType,
491
- optionalType
492
- }).configure();
493
- Object.entries(schemas).forEach(([name, schema]) => {
494
- return builder.add({
495
- schema,
496
- name
497
- });
498
- });
499
- const mapFolderSchema = async ([name]) => {
500
- const resolvedPath = this.resolvePath({ baseName: `${this.resolveName({ name, pluginKey: this.plugin.key })}.ts`, pluginKey: this.plugin.key });
501
- if (!resolvedPath) {
502
- return null;
503
- }
504
- return this.addFile({
505
- path: resolvedPath,
506
- baseName: `${this.resolveName({ name, pluginKey: this.plugin.key })}.ts`,
507
- source: builder.print(name),
508
- meta: {
509
- pluginKey: this.plugin.key
510
- }
511
- });
512
- };
513
- const promises = Object.entries(schemas).map(mapFolderSchema);
514
- await Promise.all(promises);
515
- }
516
- if (mode === "file") {
517
- const builder = new TypeBuilder({
518
- usedEnumNames,
519
- resolveName: (params) => this.resolveName({ pluginKey: this.plugin.key, ...params }),
520
- withJSDocs: true,
521
- enumType,
522
- dateType,
523
- optionalType
524
- }).configure();
525
- Object.entries(schemas).forEach(([name, schema]) => {
526
- return builder.add({
527
- schema,
528
- name
529
- });
530
- });
531
- const resolvedPath = this.resolvePath({ baseName: "", pluginKey: this.plugin.key });
532
- if (!resolvedPath) {
533
- return;
534
- }
535
- await this.addFile({
536
- path: resolvedPath,
537
- baseName: output,
538
- source: builder.print(),
539
- meta: {
540
- pluginKey: this.plugin.key
541
- },
542
- validate: false
543
- });
544
- }
545
- const operationGenerator = new OperationGenerator(
546
- {
547
- mode,
548
- enumType,
549
- dateType,
550
- optionalType,
551
- usedEnumNames
552
- },
553
- {
554
- oas,
555
- pluginManager: this.pluginManager,
556
- plugin: this.plugin,
557
- contentType: swaggerPlugin.api.contentType,
558
- skipBy,
559
- overrideBy
560
- }
561
- );
562
- const files = await operationGenerator.build();
563
- await this.addFile(...files);
564
- },
565
- async buildEnd() {
566
- if (this.config.output.write === false) {
567
- return;
568
- }
569
- const root = path.resolve(this.config.root, this.config.output.path);
570
- await this.fileManager.addIndexes({
571
- root,
572
- extName: ".ts",
573
- meta: { pluginKey: this.plugin.key },
574
- options: {
575
- map: (file) => {
576
- return {
577
- ...file,
578
- exports: file.exports?.map((item) => {
579
- if (exportAs) {
580
- return {
581
- ...item,
582
- name: exportAs,
583
- asAlias: !!exportAs
584
- };
585
- }
586
- return item;
587
- })
588
- };
589
- },
590
- output,
591
- isTypeOnly: true
592
- }
593
- });
594
- }
595
- };
596
- });
597
-
598
- // src/hooks/useResolve.ts
599
- function useResolve(props = {}) {
600
- return useResolve$1({ pluginKey, ...props });
601
- }
602
-
603
- export { useResolve };
604
- //# sourceMappingURL=out.js.map
605
- //# sourceMappingURL=hooks.js.map