@kubb/core 5.0.0-beta.2 → 5.0.0-beta.21
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/README.md +8 -38
- package/dist/KubbDriver-BBRa5CH2.cjs +2231 -0
- package/dist/KubbDriver-BBRa5CH2.cjs.map +1 -0
- package/dist/KubbDriver-Cq1isv2P.js +2110 -0
- package/dist/KubbDriver-Cq1isv2P.js.map +1 -0
- package/dist/{types-CC09VtBt.d.ts → createKubb-CYrw_xaR.d.ts} +1414 -1255
- package/dist/index.cjs +221 -1074
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -185
- package/dist/index.js +211 -1068
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +30 -21
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +5 -5
- package/dist/mocks.js +29 -20
- package/dist/mocks.js.map +1 -1
- package/package.json +6 -18
- package/src/FileManager.ts +75 -58
- package/src/FileProcessor.ts +48 -38
- package/src/KubbDriver.ts +915 -0
- package/src/constants.ts +11 -6
- package/src/createAdapter.ts +84 -1
- package/src/createKubb.ts +1022 -485
- package/src/createRenderer.ts +33 -22
- package/src/defineGenerator.ts +96 -7
- package/src/defineLogger.ts +42 -3
- package/src/defineMiddleware.ts +1 -1
- package/src/defineParser.ts +1 -1
- package/src/definePlugin.ts +304 -8
- package/src/defineResolver.ts +271 -150
- package/src/devtools.ts +8 -1
- package/src/index.ts +2 -2
- package/src/mocks.ts +11 -14
- package/src/storages/fsStorage.ts +13 -37
- package/src/types.ts +39 -1292
- package/dist/PluginDriver-BXibeQk-.cjs +0 -1036
- package/dist/PluginDriver-BXibeQk-.cjs.map +0 -1
- package/dist/PluginDriver-DV3p2Hky.js +0 -945
- package/dist/PluginDriver-DV3p2Hky.js.map +0 -1
- package/src/Kubb.ts +0 -300
- package/src/PluginDriver.ts +0 -424
- package/src/renderNode.ts +0 -35
- package/src/utils/diagnostics.ts +0 -18
- package/src/utils/isInputPath.ts +0 -10
- package/src/utils/packageJSON.ts +0 -99
package/dist/index.cjs
CHANGED
|
@@ -1,184 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
let node_events = require("node:events");
|
|
2
|
+
const require_KubbDriver = require("./KubbDriver-BBRa5CH2.cjs");
|
|
4
3
|
let node_fs_promises = require("node:fs/promises");
|
|
5
4
|
let node_path = require("node:path");
|
|
6
5
|
let _kubb_ast = require("@kubb/ast");
|
|
7
|
-
_kubb_ast =
|
|
6
|
+
_kubb_ast = require_KubbDriver.__toESM(_kubb_ast, 1);
|
|
8
7
|
let node_process = require("node:process");
|
|
9
|
-
//#region ../../internals/utils/src/errors.ts
|
|
10
|
-
/**
|
|
11
|
-
* Thrown when one or more errors occur during a Kubb build.
|
|
12
|
-
* Carries the full list of underlying errors on `errors`.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* throw new BuildError('Build failed', { errors: [err1, err2] })
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
var BuildError = class extends Error {
|
|
20
|
-
errors;
|
|
21
|
-
constructor(message, options) {
|
|
22
|
-
super(message, { cause: options.cause });
|
|
23
|
-
this.name = "BuildError";
|
|
24
|
-
this.errors = options.errors;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Coerces an unknown thrown value to an `Error` instance.
|
|
29
|
-
* Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```ts
|
|
33
|
-
* try { ... } catch(err) {
|
|
34
|
-
* throw new BuildError('Build failed', { cause: toError(err), errors: [] })
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
function toError(value) {
|
|
39
|
-
return value instanceof Error ? value : new Error(String(value));
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
43
|
-
/**
|
|
44
|
-
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
45
|
-
* Wraps Node's `EventEmitter` with full TypeScript event-map inference.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
|
|
50
|
-
* emitter.on('build', async (name) => { console.log(name) })
|
|
51
|
-
* await emitter.emit('build', 'petstore') // all listeners awaited
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
var AsyncEventEmitter = class {
|
|
55
|
-
/**
|
|
56
|
-
* Maximum number of listeners per event before Node emits a memory-leak warning.
|
|
57
|
-
* @default 10
|
|
58
|
-
*/
|
|
59
|
-
constructor(maxListener = 10) {
|
|
60
|
-
this.#emitter.setMaxListeners(maxListener);
|
|
61
|
-
}
|
|
62
|
-
#emitter = new node_events.EventEmitter();
|
|
63
|
-
/**
|
|
64
|
-
* Emits `eventName` and awaits all registered listeners sequentially.
|
|
65
|
-
* Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* await emitter.emit('build', 'petstore')
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
async emit(eventName, ...eventArgs) {
|
|
73
|
-
const listeners = this.#emitter.listeners(eventName);
|
|
74
|
-
if (listeners.length === 0) return;
|
|
75
|
-
for (const listener of listeners) try {
|
|
76
|
-
await listener(...eventArgs);
|
|
77
|
-
} catch (err) {
|
|
78
|
-
let serializedArgs;
|
|
79
|
-
try {
|
|
80
|
-
serializedArgs = JSON.stringify(eventArgs);
|
|
81
|
-
} catch {
|
|
82
|
-
serializedArgs = String(eventArgs);
|
|
83
|
-
}
|
|
84
|
-
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Registers a persistent listener for `eventName`.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* emitter.on('build', async (name) => { console.log(name) })
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
on(eventName, handler) {
|
|
96
|
-
this.#emitter.on(eventName, handler);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Registers a one-shot listener that removes itself after the first invocation.
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```ts
|
|
103
|
-
* emitter.onOnce('build', async (name) => { console.log(name) })
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
onOnce(eventName, handler) {
|
|
107
|
-
const wrapper = (...args) => {
|
|
108
|
-
this.off(eventName, wrapper);
|
|
109
|
-
return handler(...args);
|
|
110
|
-
};
|
|
111
|
-
this.on(eventName, wrapper);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Removes a previously registered listener.
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* ```ts
|
|
118
|
-
* emitter.off('build', handler)
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
off(eventName, handler) {
|
|
122
|
-
this.#emitter.off(eventName, handler);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Returns the number of listeners registered for `eventName`.
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```ts
|
|
129
|
-
* emitter.on('build', handler)
|
|
130
|
-
* emitter.listenerCount('build') // 1
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
listenerCount(eventName) {
|
|
134
|
-
return this.#emitter.listenerCount(eventName);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Removes all listeners from every event channel.
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```ts
|
|
141
|
-
* emitter.removeAll()
|
|
142
|
-
* ```
|
|
143
|
-
*/
|
|
144
|
-
removeAll() {
|
|
145
|
-
this.#emitter.removeAllListeners();
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
//#endregion
|
|
149
|
-
//#region ../../internals/utils/src/time.ts
|
|
150
|
-
/**
|
|
151
|
-
* Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
|
|
152
|
-
* Rounds to 2 decimal places for sub-millisecond precision without noise.
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```ts
|
|
156
|
-
* const start = process.hrtime()
|
|
157
|
-
* doWork()
|
|
158
|
-
* getElapsedMs(start) // 42.35
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
|
-
function getElapsedMs(hrStart) {
|
|
162
|
-
const [seconds, nanoseconds] = process.hrtime(hrStart);
|
|
163
|
-
const ms = seconds * 1e3 + nanoseconds / 1e6;
|
|
164
|
-
return Math.round(ms * 100) / 100;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* formatMs(250) // '250ms'
|
|
172
|
-
* formatMs(1500) // '1.50s'
|
|
173
|
-
* formatMs(90000) // '1m 30.0s'
|
|
174
|
-
* ```
|
|
175
|
-
*/
|
|
176
|
-
function formatMs(ms) {
|
|
177
|
-
if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
|
|
178
|
-
if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
|
|
179
|
-
return `${Math.round(ms)}ms`;
|
|
180
|
-
}
|
|
181
|
-
//#endregion
|
|
182
8
|
//#region ../../internals/utils/src/fs.ts
|
|
183
9
|
/**
|
|
184
10
|
* Resolves to `true` when the file or directory at `path` exists.
|
|
@@ -245,255 +71,6 @@ async function clean(path) {
|
|
|
245
71
|
});
|
|
246
72
|
}
|
|
247
73
|
//#endregion
|
|
248
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
249
|
-
/**
|
|
250
|
-
* JavaScript and Java reserved words.
|
|
251
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
252
|
-
*/
|
|
253
|
-
const reservedWords = new Set([
|
|
254
|
-
"abstract",
|
|
255
|
-
"arguments",
|
|
256
|
-
"boolean",
|
|
257
|
-
"break",
|
|
258
|
-
"byte",
|
|
259
|
-
"case",
|
|
260
|
-
"catch",
|
|
261
|
-
"char",
|
|
262
|
-
"class",
|
|
263
|
-
"const",
|
|
264
|
-
"continue",
|
|
265
|
-
"debugger",
|
|
266
|
-
"default",
|
|
267
|
-
"delete",
|
|
268
|
-
"do",
|
|
269
|
-
"double",
|
|
270
|
-
"else",
|
|
271
|
-
"enum",
|
|
272
|
-
"eval",
|
|
273
|
-
"export",
|
|
274
|
-
"extends",
|
|
275
|
-
"false",
|
|
276
|
-
"final",
|
|
277
|
-
"finally",
|
|
278
|
-
"float",
|
|
279
|
-
"for",
|
|
280
|
-
"function",
|
|
281
|
-
"goto",
|
|
282
|
-
"if",
|
|
283
|
-
"implements",
|
|
284
|
-
"import",
|
|
285
|
-
"in",
|
|
286
|
-
"instanceof",
|
|
287
|
-
"int",
|
|
288
|
-
"interface",
|
|
289
|
-
"let",
|
|
290
|
-
"long",
|
|
291
|
-
"native",
|
|
292
|
-
"new",
|
|
293
|
-
"null",
|
|
294
|
-
"package",
|
|
295
|
-
"private",
|
|
296
|
-
"protected",
|
|
297
|
-
"public",
|
|
298
|
-
"return",
|
|
299
|
-
"short",
|
|
300
|
-
"static",
|
|
301
|
-
"super",
|
|
302
|
-
"switch",
|
|
303
|
-
"synchronized",
|
|
304
|
-
"this",
|
|
305
|
-
"throw",
|
|
306
|
-
"throws",
|
|
307
|
-
"transient",
|
|
308
|
-
"true",
|
|
309
|
-
"try",
|
|
310
|
-
"typeof",
|
|
311
|
-
"var",
|
|
312
|
-
"void",
|
|
313
|
-
"volatile",
|
|
314
|
-
"while",
|
|
315
|
-
"with",
|
|
316
|
-
"yield",
|
|
317
|
-
"Array",
|
|
318
|
-
"Date",
|
|
319
|
-
"hasOwnProperty",
|
|
320
|
-
"Infinity",
|
|
321
|
-
"isFinite",
|
|
322
|
-
"isNaN",
|
|
323
|
-
"isPrototypeOf",
|
|
324
|
-
"length",
|
|
325
|
-
"Math",
|
|
326
|
-
"name",
|
|
327
|
-
"NaN",
|
|
328
|
-
"Number",
|
|
329
|
-
"Object",
|
|
330
|
-
"prototype",
|
|
331
|
-
"String",
|
|
332
|
-
"toString",
|
|
333
|
-
"undefined",
|
|
334
|
-
"valueOf"
|
|
335
|
-
]);
|
|
336
|
-
/**
|
|
337
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
338
|
-
*
|
|
339
|
-
* @example
|
|
340
|
-
* ```ts
|
|
341
|
-
* isValidVarName('status') // true
|
|
342
|
-
* isValidVarName('class') // false (reserved word)
|
|
343
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
344
|
-
* ```
|
|
345
|
-
*/
|
|
346
|
-
function isValidVarName(name) {
|
|
347
|
-
if (!name || reservedWords.has(name)) return false;
|
|
348
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
349
|
-
}
|
|
350
|
-
//#endregion
|
|
351
|
-
//#region ../../internals/utils/src/urlPath.ts
|
|
352
|
-
/**
|
|
353
|
-
* Parses and transforms an OpenAPI/Swagger path string into various URL formats.
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* const p = new URLPath('/pet/{petId}')
|
|
357
|
-
* p.URL // '/pet/:petId'
|
|
358
|
-
* p.template // '`/pet/${petId}`'
|
|
359
|
-
*/
|
|
360
|
-
var URLPath = class {
|
|
361
|
-
/**
|
|
362
|
-
* The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
|
|
363
|
-
*/
|
|
364
|
-
path;
|
|
365
|
-
#options;
|
|
366
|
-
constructor(path, options = {}) {
|
|
367
|
-
this.path = path;
|
|
368
|
-
this.#options = options;
|
|
369
|
-
}
|
|
370
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
371
|
-
*
|
|
372
|
-
* @example
|
|
373
|
-
* ```ts
|
|
374
|
-
* new URLPath('/pet/{petId}').URL // '/pet/:petId'
|
|
375
|
-
* ```
|
|
376
|
-
*/
|
|
377
|
-
get URL() {
|
|
378
|
-
return this.toURLPath();
|
|
379
|
-
}
|
|
380
|
-
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
|
|
381
|
-
*
|
|
382
|
-
* @example
|
|
383
|
-
* ```ts
|
|
384
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
385
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
386
|
-
* ```
|
|
387
|
-
*/
|
|
388
|
-
get isURL() {
|
|
389
|
-
try {
|
|
390
|
-
return !!new URL(this.path).href;
|
|
391
|
-
} catch {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
397
|
-
*
|
|
398
|
-
* @example
|
|
399
|
-
* new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
|
|
400
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
401
|
-
*/
|
|
402
|
-
get template() {
|
|
403
|
-
return this.toTemplateString();
|
|
404
|
-
}
|
|
405
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
406
|
-
*
|
|
407
|
-
* @example
|
|
408
|
-
* ```ts
|
|
409
|
-
* new URLPath('/pet/{petId}').object
|
|
410
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
411
|
-
* ```
|
|
412
|
-
*/
|
|
413
|
-
get object() {
|
|
414
|
-
return this.toObject();
|
|
415
|
-
}
|
|
416
|
-
/** Returns a map of path parameter names, or `undefined` when the path has no parameters.
|
|
417
|
-
*
|
|
418
|
-
* @example
|
|
419
|
-
* ```ts
|
|
420
|
-
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
421
|
-
* new URLPath('/pet').params // undefined
|
|
422
|
-
* ```
|
|
423
|
-
*/
|
|
424
|
-
get params() {
|
|
425
|
-
return this.getParams();
|
|
426
|
-
}
|
|
427
|
-
#transformParam(raw) {
|
|
428
|
-
const param = isValidVarName(raw) ? raw : require_PluginDriver.camelCase(raw);
|
|
429
|
-
return this.#options.casing === "camelcase" ? require_PluginDriver.camelCase(param) : param;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
433
|
-
*/
|
|
434
|
-
#eachParam(fn) {
|
|
435
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
436
|
-
const raw = match[1];
|
|
437
|
-
fn(raw, this.#transformParam(raw));
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
441
|
-
const object = {
|
|
442
|
-
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
443
|
-
params: this.getParams()
|
|
444
|
-
};
|
|
445
|
-
if (stringify) {
|
|
446
|
-
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
447
|
-
if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
|
|
448
|
-
return `{ url: '${object.url}' }`;
|
|
449
|
-
}
|
|
450
|
-
return object;
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
454
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
455
|
-
*
|
|
456
|
-
* @example
|
|
457
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
458
|
-
*/
|
|
459
|
-
toTemplateString({ prefix = "", replacer } = {}) {
|
|
460
|
-
return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
461
|
-
if (i % 2 === 0) return part;
|
|
462
|
-
const param = this.#transformParam(part);
|
|
463
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
464
|
-
}).join("")}\``;
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
468
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
469
|
-
* Returns `undefined` when no path parameters are found.
|
|
470
|
-
*
|
|
471
|
-
* @example
|
|
472
|
-
* ```ts
|
|
473
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').getParams()
|
|
474
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
475
|
-
* ```
|
|
476
|
-
*/
|
|
477
|
-
getParams(replacer) {
|
|
478
|
-
const params = {};
|
|
479
|
-
this.#eachParam((_raw, param) => {
|
|
480
|
-
const key = replacer ? replacer(param) : param;
|
|
481
|
-
params[key] = key;
|
|
482
|
-
});
|
|
483
|
-
return Object.keys(params).length > 0 ? params : void 0;
|
|
484
|
-
}
|
|
485
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
486
|
-
*
|
|
487
|
-
* @example
|
|
488
|
-
* ```ts
|
|
489
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
490
|
-
* ```
|
|
491
|
-
*/
|
|
492
|
-
toURLPath() {
|
|
493
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
//#endregion
|
|
497
74
|
//#region src/createAdapter.ts
|
|
498
75
|
/**
|
|
499
76
|
* Factory for implementing custom adapters that translate non-OpenAPI specs into Kubb's AST.
|
|
@@ -524,177 +101,8 @@ function createAdapter(build) {
|
|
|
524
101
|
return (options) => build(options ?? {});
|
|
525
102
|
}
|
|
526
103
|
//#endregion
|
|
527
|
-
//#region
|
|
528
|
-
var
|
|
529
|
-
value;
|
|
530
|
-
next;
|
|
531
|
-
constructor(value) {
|
|
532
|
-
this.value = value;
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
var Queue = class {
|
|
536
|
-
#head;
|
|
537
|
-
#tail;
|
|
538
|
-
#size;
|
|
539
|
-
constructor() {
|
|
540
|
-
this.clear();
|
|
541
|
-
}
|
|
542
|
-
enqueue(value) {
|
|
543
|
-
const node = new Node(value);
|
|
544
|
-
if (this.#head) {
|
|
545
|
-
this.#tail.next = node;
|
|
546
|
-
this.#tail = node;
|
|
547
|
-
} else {
|
|
548
|
-
this.#head = node;
|
|
549
|
-
this.#tail = node;
|
|
550
|
-
}
|
|
551
|
-
this.#size++;
|
|
552
|
-
}
|
|
553
|
-
dequeue() {
|
|
554
|
-
const current = this.#head;
|
|
555
|
-
if (!current) return;
|
|
556
|
-
this.#head = this.#head.next;
|
|
557
|
-
this.#size--;
|
|
558
|
-
if (!this.#head) this.#tail = void 0;
|
|
559
|
-
return current.value;
|
|
560
|
-
}
|
|
561
|
-
peek() {
|
|
562
|
-
if (!this.#head) return;
|
|
563
|
-
return this.#head.value;
|
|
564
|
-
}
|
|
565
|
-
clear() {
|
|
566
|
-
this.#head = void 0;
|
|
567
|
-
this.#tail = void 0;
|
|
568
|
-
this.#size = 0;
|
|
569
|
-
}
|
|
570
|
-
get size() {
|
|
571
|
-
return this.#size;
|
|
572
|
-
}
|
|
573
|
-
*[Symbol.iterator]() {
|
|
574
|
-
let current = this.#head;
|
|
575
|
-
while (current) {
|
|
576
|
-
yield current.value;
|
|
577
|
-
current = current.next;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
*drain() {
|
|
581
|
-
while (this.#head) yield this.dequeue();
|
|
582
|
-
}
|
|
583
|
-
};
|
|
584
|
-
//#endregion
|
|
585
|
-
//#region ../../node_modules/.pnpm/p-limit@7.3.0/node_modules/p-limit/index.js
|
|
586
|
-
function pLimit(concurrency) {
|
|
587
|
-
let rejectOnClear = false;
|
|
588
|
-
if (typeof concurrency === "object") ({concurrency, rejectOnClear = false} = concurrency);
|
|
589
|
-
validateConcurrency(concurrency);
|
|
590
|
-
if (typeof rejectOnClear !== "boolean") throw new TypeError("Expected `rejectOnClear` to be a boolean");
|
|
591
|
-
const queue = new Queue();
|
|
592
|
-
let activeCount = 0;
|
|
593
|
-
const resumeNext = () => {
|
|
594
|
-
if (activeCount < concurrency && queue.size > 0) {
|
|
595
|
-
activeCount++;
|
|
596
|
-
queue.dequeue().run();
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
|
-
const next = () => {
|
|
600
|
-
activeCount--;
|
|
601
|
-
resumeNext();
|
|
602
|
-
};
|
|
603
|
-
const run = async (function_, resolve, arguments_) => {
|
|
604
|
-
const result = (async () => function_(...arguments_))();
|
|
605
|
-
resolve(result);
|
|
606
|
-
try {
|
|
607
|
-
await result;
|
|
608
|
-
} catch {}
|
|
609
|
-
next();
|
|
610
|
-
};
|
|
611
|
-
const enqueue = (function_, resolve, reject, arguments_) => {
|
|
612
|
-
const queueItem = { reject };
|
|
613
|
-
new Promise((internalResolve) => {
|
|
614
|
-
queueItem.run = internalResolve;
|
|
615
|
-
queue.enqueue(queueItem);
|
|
616
|
-
}).then(run.bind(void 0, function_, resolve, arguments_));
|
|
617
|
-
if (activeCount < concurrency) resumeNext();
|
|
618
|
-
};
|
|
619
|
-
const generator = (function_, ...arguments_) => new Promise((resolve, reject) => {
|
|
620
|
-
enqueue(function_, resolve, reject, arguments_);
|
|
621
|
-
});
|
|
622
|
-
Object.defineProperties(generator, {
|
|
623
|
-
activeCount: { get: () => activeCount },
|
|
624
|
-
pendingCount: { get: () => queue.size },
|
|
625
|
-
clearQueue: { value() {
|
|
626
|
-
if (!rejectOnClear) {
|
|
627
|
-
queue.clear();
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
const abortError = AbortSignal.abort().reason;
|
|
631
|
-
while (queue.size > 0) queue.dequeue().reject(abortError);
|
|
632
|
-
} },
|
|
633
|
-
concurrency: {
|
|
634
|
-
get: () => concurrency,
|
|
635
|
-
set(newConcurrency) {
|
|
636
|
-
validateConcurrency(newConcurrency);
|
|
637
|
-
concurrency = newConcurrency;
|
|
638
|
-
queueMicrotask(() => {
|
|
639
|
-
while (activeCount < concurrency && queue.size > 0) resumeNext();
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
map: { async value(iterable, function_) {
|
|
644
|
-
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
645
|
-
return Promise.all(promises);
|
|
646
|
-
} }
|
|
647
|
-
});
|
|
648
|
-
return generator;
|
|
649
|
-
}
|
|
650
|
-
function validateConcurrency(concurrency) {
|
|
651
|
-
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
652
|
-
}
|
|
653
|
-
//#endregion
|
|
654
|
-
//#region src/FileProcessor.ts
|
|
655
|
-
function joinSources(file) {
|
|
656
|
-
return file.sources.map((item) => (0, _kubb_ast.extractStringsFromNodes)(item.nodes)).filter(Boolean).join("\n\n");
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Converts a single file to a string using the registered parsers.
|
|
660
|
-
* Falls back to joining source values when no matching parser is found.
|
|
661
|
-
*
|
|
662
|
-
* @internal
|
|
663
|
-
*/
|
|
664
|
-
var FileProcessor = class {
|
|
665
|
-
#limit = pLimit(100);
|
|
666
|
-
async parse(file, { parsers, extension } = {}) {
|
|
667
|
-
const parseExtName = extension?.[file.extname] || void 0;
|
|
668
|
-
if (!parsers || !file.extname) return joinSources(file);
|
|
669
|
-
const parser = parsers.get(file.extname);
|
|
670
|
-
if (!parser) return joinSources(file);
|
|
671
|
-
return parser.parse(file, { extname: parseExtName });
|
|
672
|
-
}
|
|
673
|
-
async run(files, { parsers, mode = "sequential", extension, onStart, onEnd, onUpdate } = {}) {
|
|
674
|
-
await onStart?.(files);
|
|
675
|
-
const total = files.length;
|
|
676
|
-
let processed = 0;
|
|
677
|
-
const processOne = async (file) => {
|
|
678
|
-
const source = await this.parse(file, {
|
|
679
|
-
extension,
|
|
680
|
-
parsers
|
|
681
|
-
});
|
|
682
|
-
const currentProcessed = ++processed;
|
|
683
|
-
const percentage = currentProcessed / total * 100;
|
|
684
|
-
await onUpdate?.({
|
|
685
|
-
file,
|
|
686
|
-
source,
|
|
687
|
-
processed: currentProcessed,
|
|
688
|
-
percentage,
|
|
689
|
-
total
|
|
690
|
-
});
|
|
691
|
-
};
|
|
692
|
-
if (mode === "sequential") for (const file of files) await processOne(file);
|
|
693
|
-
else await Promise.all(files.map((file) => this.#limit(() => processOne(file))));
|
|
694
|
-
await onEnd?.(files);
|
|
695
|
-
return files;
|
|
696
|
-
}
|
|
697
|
-
};
|
|
104
|
+
//#region package.json
|
|
105
|
+
var version = "5.0.0-beta.21";
|
|
698
106
|
//#endregion
|
|
699
107
|
//#region src/createStorage.ts
|
|
700
108
|
/**
|
|
@@ -735,12 +143,6 @@ function createStorage(build) {
|
|
|
735
143
|
//#endregion
|
|
736
144
|
//#region src/storages/fsStorage.ts
|
|
737
145
|
/**
|
|
738
|
-
* Detects the filesystem error used to indicate that a path does not exist.
|
|
739
|
-
*/
|
|
740
|
-
function isMissingPathError(error) {
|
|
741
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
742
|
-
}
|
|
743
|
-
/**
|
|
744
146
|
* Built-in filesystem storage driver.
|
|
745
147
|
*
|
|
746
148
|
* This is the default storage when no `storage` option is configured in the root config.
|
|
@@ -771,17 +173,15 @@ const fsStorage = createStorage(() => ({
|
|
|
771
173
|
try {
|
|
772
174
|
await (0, node_fs_promises.access)((0, node_path.resolve)(key));
|
|
773
175
|
return true;
|
|
774
|
-
} catch (
|
|
775
|
-
|
|
776
|
-
throw new Error(`Failed to access storage item "${key}"`, { cause: error });
|
|
176
|
+
} catch (_error) {
|
|
177
|
+
return false;
|
|
777
178
|
}
|
|
778
179
|
},
|
|
779
180
|
async getItem(key) {
|
|
780
181
|
try {
|
|
781
182
|
return await (0, node_fs_promises.readFile)((0, node_path.resolve)(key), "utf8");
|
|
782
|
-
} catch (
|
|
783
|
-
|
|
784
|
-
throw new Error(`Failed to read storage item "${key}"`, { cause: error });
|
|
183
|
+
} catch (_error) {
|
|
184
|
+
return null;
|
|
785
185
|
}
|
|
786
186
|
},
|
|
787
187
|
async setItem(key, value) {
|
|
@@ -791,23 +191,22 @@ const fsStorage = createStorage(() => ({
|
|
|
791
191
|
await (0, node_fs_promises.rm)((0, node_path.resolve)(key), { force: true });
|
|
792
192
|
},
|
|
793
193
|
async getKeys(base) {
|
|
794
|
-
const keys = [];
|
|
795
194
|
const resolvedBase = (0, node_path.resolve)(base ?? process.cwd());
|
|
796
|
-
async function walk(dir, prefix) {
|
|
195
|
+
async function* walk(dir, prefix) {
|
|
797
196
|
let entries;
|
|
798
197
|
try {
|
|
799
198
|
entries = await (0, node_fs_promises.readdir)(dir, { withFileTypes: true });
|
|
800
|
-
} catch (
|
|
801
|
-
|
|
802
|
-
throw new Error(`Failed to list storage keys under "${resolvedBase}"`, { cause: error });
|
|
199
|
+
} catch (_error) {
|
|
200
|
+
return;
|
|
803
201
|
}
|
|
804
202
|
for (const entry of entries) {
|
|
805
203
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
806
|
-
if (entry.isDirectory())
|
|
807
|
-
else
|
|
204
|
+
if (entry.isDirectory()) yield* walk((0, node_path.join)(dir, entry.name), rel);
|
|
205
|
+
else yield rel;
|
|
808
206
|
}
|
|
809
207
|
}
|
|
810
|
-
|
|
208
|
+
const keys = [];
|
|
209
|
+
for await (const key of walk(resolvedBase, "")) keys.push(key);
|
|
811
210
|
return keys;
|
|
812
211
|
},
|
|
813
212
|
async clear(base) {
|
|
@@ -816,475 +215,236 @@ const fsStorage = createStorage(() => ({
|
|
|
816
215
|
}
|
|
817
216
|
}));
|
|
818
217
|
//#endregion
|
|
819
|
-
//#region
|
|
820
|
-
var version = "5.0.0-beta.2";
|
|
821
|
-
//#endregion
|
|
822
|
-
//#region src/utils/diagnostics.ts
|
|
218
|
+
//#region src/createKubb.ts
|
|
823
219
|
/**
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
220
|
+
* Builds a `Storage` view scoped to the file paths produced by the current build.
|
|
221
|
+
* Reads delegate to the underlying `storage` so source bytes stay where they were
|
|
222
|
+
* written; writes register the key so subsequent reads and `getKeys` are scoped
|
|
223
|
+
* to this build's output.
|
|
828
224
|
*/
|
|
829
|
-
function
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
` • Output: ${userConfig.output?.path || "not specified"}`,
|
|
857
|
-
` • Plugins: ${userConfig.plugins?.length || 0}`,
|
|
858
|
-
"Output Settings:",
|
|
859
|
-
` • Storage: ${userConfig.storage ? `custom(${userConfig.storage.name})` : userConfig.output?.write === false ? "disabled" : "filesystem (default)"}`,
|
|
860
|
-
` • Formatter: ${userConfig.output?.format || "none"}`,
|
|
861
|
-
` • Linter: ${userConfig.output?.lint || "none"}`,
|
|
862
|
-
"Environment:",
|
|
863
|
-
Object.entries(diagnosticInfo).map(([key, value]) => ` • ${key}: ${value}`).join("\n")
|
|
864
|
-
]
|
|
865
|
-
});
|
|
866
|
-
try {
|
|
867
|
-
if (isInputPath(userConfig) && !new URLPath(userConfig.input.path).isURL) {
|
|
868
|
-
await exists(userConfig.input.path);
|
|
869
|
-
await hooks.emit("kubb:debug", {
|
|
870
|
-
date: /* @__PURE__ */ new Date(),
|
|
871
|
-
logs: [`✓ Input file validated: ${userConfig.input.path}`]
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
} catch (caughtError) {
|
|
875
|
-
if (isInputPath(userConfig)) {
|
|
876
|
-
const error = caughtError;
|
|
877
|
-
throw new Error(`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${userConfig.input.path}`, { cause: error });
|
|
225
|
+
function createSourcesView(storage) {
|
|
226
|
+
const paths = /* @__PURE__ */ new Set();
|
|
227
|
+
return createStorage(() => ({
|
|
228
|
+
name: `${storage.name}:sources`,
|
|
229
|
+
async hasItem(key) {
|
|
230
|
+
return paths.has(key) && await storage.hasItem(key);
|
|
231
|
+
},
|
|
232
|
+
async getItem(key) {
|
|
233
|
+
return paths.has(key) ? storage.getItem(key) : null;
|
|
234
|
+
},
|
|
235
|
+
async setItem(key, value) {
|
|
236
|
+
paths.add(key);
|
|
237
|
+
await storage.setItem(key, value);
|
|
238
|
+
},
|
|
239
|
+
async removeItem(key) {
|
|
240
|
+
paths.delete(key);
|
|
241
|
+
await storage.removeItem(key);
|
|
242
|
+
},
|
|
243
|
+
async getKeys(base) {
|
|
244
|
+
if (!base) return [...paths];
|
|
245
|
+
const result = [];
|
|
246
|
+
for (const key of paths) if (key.startsWith(base)) result.push(key);
|
|
247
|
+
return result;
|
|
248
|
+
},
|
|
249
|
+
async clear() {
|
|
250
|
+
paths.clear();
|
|
251
|
+
await storage.clear();
|
|
878
252
|
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
|
|
253
|
+
}))();
|
|
254
|
+
}
|
|
255
|
+
function resolveConfig(userConfig) {
|
|
256
|
+
return {
|
|
882
257
|
...userConfig,
|
|
883
258
|
root: userConfig.root || process.cwd(),
|
|
884
259
|
parsers: userConfig.parsers ?? [],
|
|
885
|
-
adapter: userConfig.adapter,
|
|
886
260
|
output: {
|
|
887
261
|
format: false,
|
|
888
262
|
lint: false,
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
defaultBanner: require_PluginDriver.DEFAULT_BANNER,
|
|
263
|
+
extension: require_KubbDriver.DEFAULT_EXTENSION,
|
|
264
|
+
defaultBanner: require_KubbDriver.DEFAULT_BANNER,
|
|
892
265
|
...userConfig.output
|
|
893
266
|
},
|
|
267
|
+
storage: userConfig.storage ?? fsStorage(),
|
|
894
268
|
devtools: userConfig.devtools ? {
|
|
895
|
-
studioUrl:
|
|
269
|
+
studioUrl: require_KubbDriver.DEFAULT_STUDIO_URL,
|
|
896
270
|
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
897
271
|
} : void 0,
|
|
898
|
-
plugins: userConfig.plugins
|
|
899
|
-
};
|
|
900
|
-
const storage = config.output.write === false ? null : config.storage ?? fsStorage();
|
|
901
|
-
if (config.output.clean) {
|
|
902
|
-
await hooks.emit("kubb:debug", {
|
|
903
|
-
date: /* @__PURE__ */ new Date(),
|
|
904
|
-
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
905
|
-
});
|
|
906
|
-
await storage?.clear((0, node_path.resolve)(config.root, config.output.path));
|
|
907
|
-
}
|
|
908
|
-
const driver = new require_PluginDriver.PluginDriver(config, { hooks });
|
|
909
|
-
function registerMiddlewareHook(event, middlewareHooks) {
|
|
910
|
-
const handler = middlewareHooks[event];
|
|
911
|
-
if (handler) hooks.on(event, handler);
|
|
912
|
-
}
|
|
913
|
-
for (const middleware of config.middleware ?? []) for (const event of Object.keys(middleware.hooks)) registerMiddlewareHook(event, middleware.hooks);
|
|
914
|
-
const adapter = config.adapter;
|
|
915
|
-
if (!adapter) throw new Error("No adapter configured. Please provide an adapter in your kubb.config.ts.");
|
|
916
|
-
const source = inputToAdapterSource(config);
|
|
917
|
-
await hooks.emit("kubb:debug", {
|
|
918
|
-
date: /* @__PURE__ */ new Date(),
|
|
919
|
-
logs: [`Running adapter: ${adapter.name}`]
|
|
920
|
-
});
|
|
921
|
-
driver.adapter = adapter;
|
|
922
|
-
driver.inputNode = await adapter.parse(source);
|
|
923
|
-
await hooks.emit("kubb:debug", {
|
|
924
|
-
date: /* @__PURE__ */ new Date(),
|
|
925
|
-
logs: [
|
|
926
|
-
`✓ Adapter '${adapter.name}' resolved InputNode`,
|
|
927
|
-
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
928
|
-
` • Operations: ${driver.inputNode.operations.length}`
|
|
929
|
-
]
|
|
930
|
-
});
|
|
931
|
-
return {
|
|
932
|
-
config,
|
|
933
|
-
hooks,
|
|
934
|
-
driver,
|
|
935
|
-
sources,
|
|
936
|
-
storage
|
|
272
|
+
plugins: userConfig.plugins ?? []
|
|
937
273
|
};
|
|
938
274
|
}
|
|
939
275
|
/**
|
|
940
|
-
*
|
|
941
|
-
* (`schema`, `operation`, `operations`).
|
|
276
|
+
* Returns a snapshot of the current runtime environment.
|
|
942
277
|
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
* of top-level schema names transitively reachable from the included operations and skips
|
|
946
|
-
* schemas that fall outside that set. This ensures that component schemas referenced
|
|
947
|
-
* exclusively by excluded operations are not generated.
|
|
278
|
+
* Useful for attaching context to debug logs and error reports so that
|
|
279
|
+
* issues can be reproduced without manual information gathering.
|
|
948
280
|
*/
|
|
949
|
-
|
|
950
|
-
const { adapter, inputNode, resolver, driver } = context;
|
|
951
|
-
const { exclude, include, override } = plugin.options;
|
|
952
|
-
if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. pluginOas()) before this plugin in your Kubb config.`);
|
|
953
|
-
function resolveRenderer(gen) {
|
|
954
|
-
return gen.renderer === null ? void 0 : gen.renderer ?? plugin.renderer ?? context.config.renderer;
|
|
955
|
-
}
|
|
956
|
-
const generators = plugin.generators ?? [];
|
|
957
|
-
const collectedOperations = [];
|
|
958
|
-
const generatorContext = {
|
|
959
|
-
...context,
|
|
960
|
-
resolver: driver.getResolver(plugin.name)
|
|
961
|
-
};
|
|
962
|
-
const operationFilterTypes = new Set([
|
|
963
|
-
"tag",
|
|
964
|
-
"operationId",
|
|
965
|
-
"path",
|
|
966
|
-
"method",
|
|
967
|
-
"contentType"
|
|
968
|
-
]);
|
|
969
|
-
const hasOperationBasedIncludes = include?.some(({ type }) => operationFilterTypes.has(type)) ?? false;
|
|
970
|
-
const hasSchemaNameIncludes = include?.some(({ type }) => type === "schemaName") ?? false;
|
|
971
|
-
let allowedSchemaNames;
|
|
972
|
-
if (hasOperationBasedIncludes && !hasSchemaNameIncludes) allowedSchemaNames = (0, _kubb_ast.collectUsedSchemaNames)(inputNode.operations.filter((op) => resolver.resolveOptions(op, {
|
|
973
|
-
options: plugin.options,
|
|
974
|
-
exclude,
|
|
975
|
-
include,
|
|
976
|
-
override
|
|
977
|
-
}) !== null), inputNode.schemas);
|
|
978
|
-
await (0, _kubb_ast.walk)(inputNode, {
|
|
979
|
-
depth: "shallow",
|
|
980
|
-
async schema(node) {
|
|
981
|
-
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
982
|
-
if (allowedSchemaNames !== void 0 && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) return;
|
|
983
|
-
const options = resolver.resolveOptions(transformedNode, {
|
|
984
|
-
options: plugin.options,
|
|
985
|
-
exclude,
|
|
986
|
-
include,
|
|
987
|
-
override
|
|
988
|
-
});
|
|
989
|
-
if (options === null) return;
|
|
990
|
-
const ctx = {
|
|
991
|
-
...generatorContext,
|
|
992
|
-
options
|
|
993
|
-
};
|
|
994
|
-
for (const gen of generators) {
|
|
995
|
-
if (!gen.schema) continue;
|
|
996
|
-
await require_PluginDriver.applyHookResult(await gen.schema(transformedNode, ctx), driver, resolveRenderer(gen));
|
|
997
|
-
}
|
|
998
|
-
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
999
|
-
},
|
|
1000
|
-
async operation(node) {
|
|
1001
|
-
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1002
|
-
const options = resolver.resolveOptions(transformedNode, {
|
|
1003
|
-
options: plugin.options,
|
|
1004
|
-
exclude,
|
|
1005
|
-
include,
|
|
1006
|
-
override
|
|
1007
|
-
});
|
|
1008
|
-
if (options !== null) {
|
|
1009
|
-
collectedOperations.push(transformedNode);
|
|
1010
|
-
const ctx = {
|
|
1011
|
-
...generatorContext,
|
|
1012
|
-
options
|
|
1013
|
-
};
|
|
1014
|
-
for (const gen of generators) {
|
|
1015
|
-
if (!gen.operation) continue;
|
|
1016
|
-
await require_PluginDriver.applyHookResult(await gen.operation(transformedNode, ctx), driver, resolveRenderer(gen));
|
|
1017
|
-
}
|
|
1018
|
-
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
if (collectedOperations.length > 0) {
|
|
1023
|
-
const ctx = {
|
|
1024
|
-
...generatorContext,
|
|
1025
|
-
options: plugin.options
|
|
1026
|
-
};
|
|
1027
|
-
for (const gen of generators) {
|
|
1028
|
-
if (!gen.operations) continue;
|
|
1029
|
-
await require_PluginDriver.applyHookResult(await gen.operations(collectedOperations, ctx), driver, resolveRenderer(gen));
|
|
1030
|
-
}
|
|
1031
|
-
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
async function safeBuild(setupResult) {
|
|
1035
|
-
const { driver, hooks, sources, storage } = setupResult;
|
|
1036
|
-
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1037
|
-
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1038
|
-
const config = driver.config;
|
|
1039
|
-
try {
|
|
1040
|
-
await driver.emitSetupHooks();
|
|
1041
|
-
if (driver.adapter && driver.inputNode) await hooks.emit("kubb:build:start", {
|
|
1042
|
-
config,
|
|
1043
|
-
adapter: driver.adapter,
|
|
1044
|
-
inputNode: driver.inputNode,
|
|
1045
|
-
getPlugin: driver.getPlugin.bind(driver),
|
|
1046
|
-
get files() {
|
|
1047
|
-
return driver.fileManager.files;
|
|
1048
|
-
},
|
|
1049
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1050
|
-
});
|
|
1051
|
-
for (const plugin of driver.plugins.values()) {
|
|
1052
|
-
const context = driver.getContext(plugin);
|
|
1053
|
-
const hrStart = process.hrtime();
|
|
1054
|
-
try {
|
|
1055
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
1056
|
-
await hooks.emit("kubb:plugin:start", { plugin });
|
|
1057
|
-
await hooks.emit("kubb:debug", {
|
|
1058
|
-
date: timestamp,
|
|
1059
|
-
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1060
|
-
});
|
|
1061
|
-
if (plugin.generators?.length || driver.hasRegisteredGenerators(plugin.name)) await runPluginAstHooks(plugin, context);
|
|
1062
|
-
const duration = getElapsedMs(hrStart);
|
|
1063
|
-
pluginTimings.set(plugin.name, duration);
|
|
1064
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1065
|
-
plugin,
|
|
1066
|
-
duration,
|
|
1067
|
-
success: true,
|
|
1068
|
-
config,
|
|
1069
|
-
get files() {
|
|
1070
|
-
return driver.fileManager.files;
|
|
1071
|
-
},
|
|
1072
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1073
|
-
});
|
|
1074
|
-
await hooks.emit("kubb:debug", {
|
|
1075
|
-
date: /* @__PURE__ */ new Date(),
|
|
1076
|
-
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1077
|
-
});
|
|
1078
|
-
} catch (caughtError) {
|
|
1079
|
-
const error = caughtError;
|
|
1080
|
-
const errorTimestamp = /* @__PURE__ */ new Date();
|
|
1081
|
-
const duration = getElapsedMs(hrStart);
|
|
1082
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1083
|
-
plugin,
|
|
1084
|
-
duration,
|
|
1085
|
-
success: false,
|
|
1086
|
-
error,
|
|
1087
|
-
config,
|
|
1088
|
-
get files() {
|
|
1089
|
-
return driver.fileManager.files;
|
|
1090
|
-
},
|
|
1091
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1092
|
-
});
|
|
1093
|
-
await hooks.emit("kubb:debug", {
|
|
1094
|
-
date: errorTimestamp,
|
|
1095
|
-
logs: [
|
|
1096
|
-
"✗ Plugin start failed",
|
|
1097
|
-
` • Plugin Name: ${plugin.name}`,
|
|
1098
|
-
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
1099
|
-
" • Stack Trace:",
|
|
1100
|
-
error.stack || "No stack trace available"
|
|
1101
|
-
]
|
|
1102
|
-
});
|
|
1103
|
-
failedPlugins.add({
|
|
1104
|
-
plugin,
|
|
1105
|
-
error
|
|
1106
|
-
});
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
await hooks.emit("kubb:plugins:end", {
|
|
1110
|
-
config,
|
|
1111
|
-
get files() {
|
|
1112
|
-
return driver.fileManager.files;
|
|
1113
|
-
},
|
|
1114
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1115
|
-
});
|
|
1116
|
-
const files = driver.fileManager.files;
|
|
1117
|
-
const parsersMap = /* @__PURE__ */ new Map();
|
|
1118
|
-
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
1119
|
-
const fileProcessor = new FileProcessor();
|
|
1120
|
-
await hooks.emit("kubb:debug", {
|
|
1121
|
-
date: /* @__PURE__ */ new Date(),
|
|
1122
|
-
logs: [`Writing ${files.length} files...`]
|
|
1123
|
-
});
|
|
1124
|
-
await fileProcessor.run(files, {
|
|
1125
|
-
parsers: parsersMap,
|
|
1126
|
-
extension: config.output.extension,
|
|
1127
|
-
onStart: async (processingFiles) => {
|
|
1128
|
-
await hooks.emit("kubb:files:processing:start", { files: processingFiles });
|
|
1129
|
-
},
|
|
1130
|
-
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
1131
|
-
await hooks.emit("kubb:file:processing:update", {
|
|
1132
|
-
file,
|
|
1133
|
-
source,
|
|
1134
|
-
processed,
|
|
1135
|
-
total,
|
|
1136
|
-
percentage,
|
|
1137
|
-
config
|
|
1138
|
-
});
|
|
1139
|
-
if (source) {
|
|
1140
|
-
await storage?.setItem(file.path, source);
|
|
1141
|
-
sources.set(file.path, source);
|
|
1142
|
-
}
|
|
1143
|
-
},
|
|
1144
|
-
onEnd: async (processedFiles) => {
|
|
1145
|
-
await hooks.emit("kubb:files:processing:end", { files: processedFiles });
|
|
1146
|
-
await hooks.emit("kubb:debug", {
|
|
1147
|
-
date: /* @__PURE__ */ new Date(),
|
|
1148
|
-
logs: [`✓ File write process completed for ${processedFiles.length} files`]
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
});
|
|
1152
|
-
await hooks.emit("kubb:build:end", {
|
|
1153
|
-
files,
|
|
1154
|
-
config,
|
|
1155
|
-
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
1156
|
-
});
|
|
1157
|
-
return {
|
|
1158
|
-
failedPlugins,
|
|
1159
|
-
files,
|
|
1160
|
-
driver,
|
|
1161
|
-
pluginTimings,
|
|
1162
|
-
sources
|
|
1163
|
-
};
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
return {
|
|
1166
|
-
failedPlugins,
|
|
1167
|
-
files: [],
|
|
1168
|
-
driver,
|
|
1169
|
-
pluginTimings,
|
|
1170
|
-
error,
|
|
1171
|
-
sources
|
|
1172
|
-
};
|
|
1173
|
-
} finally {
|
|
1174
|
-
driver.dispose();
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
async function build(setupResult) {
|
|
1178
|
-
const { files, driver, failedPlugins, pluginTimings, error, sources } = await safeBuild(setupResult);
|
|
1179
|
-
if (error) throw error;
|
|
1180
|
-
if (failedPlugins.size > 0) {
|
|
1181
|
-
const errors = [...failedPlugins].map(({ error }) => error);
|
|
1182
|
-
throw new BuildError(`Build Error with ${failedPlugins.size} failed plugins`, { errors });
|
|
1183
|
-
}
|
|
281
|
+
function getDiagnosticInfo() {
|
|
1184
282
|
return {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
sources
|
|
283
|
+
nodeVersion: node_process.version,
|
|
284
|
+
KubbVersion: version,
|
|
285
|
+
platform: process.platform,
|
|
286
|
+
arch: process.arch,
|
|
287
|
+
cwd: process.cwd()
|
|
1191
288
|
};
|
|
1192
289
|
}
|
|
1193
|
-
function
|
|
1194
|
-
|
|
1195
|
-
type: "paths",
|
|
1196
|
-
paths: config.input.map((i) => new URLPath(i.path).isURL ? i.path : (0, node_path.resolve)(config.root, i.path))
|
|
1197
|
-
};
|
|
1198
|
-
if ("data" in config.input) return {
|
|
1199
|
-
type: "data",
|
|
1200
|
-
data: config.input.data
|
|
1201
|
-
};
|
|
1202
|
-
if (new URLPath(config.input.path).isURL) return {
|
|
1203
|
-
type: "path",
|
|
1204
|
-
path: config.input.path
|
|
1205
|
-
};
|
|
1206
|
-
return {
|
|
1207
|
-
type: "path",
|
|
1208
|
-
path: (0, node_path.resolve)(config.root, config.input.path)
|
|
1209
|
-
};
|
|
290
|
+
function isInputPath(config) {
|
|
291
|
+
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1210
292
|
}
|
|
1211
293
|
/**
|
|
1212
|
-
*
|
|
294
|
+
* Kubb code-generation instance bound to a single config entry. Resolves the user
|
|
295
|
+
* config during `setup()` and shares `hooks`, `storage`, `driver`, and `config` across
|
|
296
|
+
* the `setup → build` lifecycle.
|
|
1213
297
|
*
|
|
1214
|
-
*
|
|
1215
|
-
* `setup()`. The instance then holds shared state (`hooks`, `sources`, `driver`, `config`)
|
|
1216
|
-
* across the `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
|
|
1217
|
-
* calling `setup()` or `build()`.
|
|
298
|
+
* Attach event listeners to `.hooks` before calling `setup()` or `build()`.
|
|
1218
299
|
*
|
|
1219
300
|
* @example
|
|
1220
301
|
* ```ts
|
|
1221
302
|
* const kubb = createKubb(userConfig)
|
|
1222
|
-
*
|
|
1223
|
-
* kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => {
|
|
1224
|
-
* console.log(`${plugin.name} completed in ${duration}ms`)
|
|
1225
|
-
* })
|
|
1226
|
-
*
|
|
303
|
+
* kubb.hooks.on('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
|
|
1227
304
|
* const { files, failedPlugins } = await kubb.safeBuild()
|
|
1228
305
|
* ```
|
|
1229
306
|
*/
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
307
|
+
var Kubb = class {
|
|
308
|
+
hooks;
|
|
309
|
+
#userConfig;
|
|
310
|
+
#config = null;
|
|
311
|
+
#driver = null;
|
|
312
|
+
#storage = null;
|
|
313
|
+
constructor(userConfig, options = {}) {
|
|
314
|
+
this.#userConfig = userConfig;
|
|
315
|
+
this.hooks = options.hooks ?? new require_KubbDriver.AsyncEventEmitter();
|
|
316
|
+
}
|
|
317
|
+
get storage() {
|
|
318
|
+
if (!this.#storage) throw new Error("[kubb] setup() must be called before accessing storage");
|
|
319
|
+
return this.#storage;
|
|
320
|
+
}
|
|
321
|
+
get driver() {
|
|
322
|
+
if (!this.#driver) throw new Error("[kubb] setup() must be called before accessing driver");
|
|
323
|
+
return this.#driver;
|
|
324
|
+
}
|
|
325
|
+
get config() {
|
|
326
|
+
if (!this.#config) throw new Error("[kubb] setup() must be called before accessing config");
|
|
327
|
+
return this.#config;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Resolves config and initializes the driver. `build()` calls this automatically.
|
|
331
|
+
*/
|
|
332
|
+
async setup() {
|
|
333
|
+
const config = resolveConfig(this.#userConfig);
|
|
334
|
+
const driver = new require_KubbDriver.KubbDriver(config, { hooks: this.hooks });
|
|
335
|
+
const storage = createSourcesView(config.storage);
|
|
336
|
+
await this.hooks.emit("kubb:debug", {
|
|
337
|
+
date: /* @__PURE__ */ new Date(),
|
|
338
|
+
logs: this.#configLogs(config)
|
|
339
|
+
});
|
|
340
|
+
if (isInputPath(this.#userConfig) && !new require_KubbDriver.URLPath(this.#userConfig.input.path).isURL) try {
|
|
341
|
+
await exists(this.#userConfig.input.path);
|
|
342
|
+
await this.hooks.emit("kubb:debug", {
|
|
343
|
+
date: /* @__PURE__ */ new Date(),
|
|
344
|
+
logs: [`✓ Input file validated: ${this.#userConfig.input.path}`]
|
|
345
|
+
});
|
|
346
|
+
} catch (caughtError) {
|
|
347
|
+
throw new Error(`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${this.#userConfig.input.path}`, { cause: caughtError });
|
|
1256
348
|
}
|
|
1257
|
-
|
|
1258
|
-
|
|
349
|
+
if (config.output.clean) {
|
|
350
|
+
await this.hooks.emit("kubb:debug", {
|
|
351
|
+
date: /* @__PURE__ */ new Date(),
|
|
352
|
+
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
353
|
+
});
|
|
354
|
+
await config.storage.clear((0, node_path.resolve)(config.root, config.output.path));
|
|
355
|
+
}
|
|
356
|
+
await driver.setup();
|
|
357
|
+
this.#config = config;
|
|
358
|
+
this.#driver = driver;
|
|
359
|
+
this.#storage = storage;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Runs the full pipeline and throws on any plugin error.
|
|
363
|
+
* Automatically calls `setup()` if needed.
|
|
364
|
+
*/
|
|
365
|
+
async build() {
|
|
366
|
+
const out = await this.safeBuild();
|
|
367
|
+
if (out.error) throw out.error;
|
|
368
|
+
if (out.failedPlugins.size > 0) {
|
|
369
|
+
const errors = [...out.failedPlugins].map(({ error }) => error);
|
|
370
|
+
throw new require_KubbDriver.BuildError(`Build Error with ${out.failedPlugins.size} failed plugins`, { errors });
|
|
371
|
+
}
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Runs the full pipeline and captures errors in `BuildOutput` instead of throwing.
|
|
376
|
+
* Automatically calls `setup()` if needed.
|
|
377
|
+
*/
|
|
378
|
+
async safeBuild() {
|
|
379
|
+
try {
|
|
380
|
+
var _usingCtx$1 = require_KubbDriver._usingCtx();
|
|
381
|
+
if (!this.#driver) await this.setup();
|
|
382
|
+
const cleanup = _usingCtx$1.u(this);
|
|
383
|
+
const driver = cleanup.driver;
|
|
384
|
+
const storage = cleanup.storage;
|
|
385
|
+
const { failedPlugins, pluginTimings, error } = await driver.run({ storage });
|
|
386
|
+
return {
|
|
387
|
+
failedPlugins,
|
|
388
|
+
files: driver.fileManager.files,
|
|
389
|
+
driver,
|
|
390
|
+
pluginTimings,
|
|
391
|
+
storage,
|
|
392
|
+
...error ? { error } : {}
|
|
393
|
+
};
|
|
394
|
+
} catch (_) {
|
|
395
|
+
_usingCtx$1.e = _;
|
|
396
|
+
} finally {
|
|
397
|
+
_usingCtx$1.d();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
dispose() {
|
|
401
|
+
this.#driver?.dispose();
|
|
402
|
+
}
|
|
403
|
+
[Symbol.dispose]() {
|
|
404
|
+
this.dispose();
|
|
405
|
+
}
|
|
406
|
+
#configLogs(config) {
|
|
407
|
+
const u = this.#userConfig;
|
|
408
|
+
const diag = getDiagnosticInfo();
|
|
409
|
+
return [
|
|
410
|
+
"Configuration:",
|
|
411
|
+
` • Name: ${u.name || "unnamed"}`,
|
|
412
|
+
` • Root: ${u.root || process.cwd()}`,
|
|
413
|
+
` • Output: ${u.output?.path || "not specified"}`,
|
|
414
|
+
` • Plugins: ${u.plugins?.length || 0}`,
|
|
415
|
+
"Output Settings:",
|
|
416
|
+
` • Storage: ${config.storage.name}`,
|
|
417
|
+
` • Formatter: ${u.output?.format || "none"}`,
|
|
418
|
+
` • Linter: ${u.output?.lint || "none"}`,
|
|
419
|
+
`Running adapter: ${config.adapter?.name || "none"}`,
|
|
420
|
+
"Environment:",
|
|
421
|
+
Object.entries(diag).map(([key, value]) => ` • ${key}: ${value}`).join("\n")
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* Factory for {@link Kubb}. Equivalent to `new Kubb(userConfig, options)` and kept
|
|
427
|
+
* as the canonical public entry point.
|
|
428
|
+
*/
|
|
429
|
+
function createKubb(userConfig, options = {}) {
|
|
430
|
+
return new Kubb(userConfig, options);
|
|
1259
431
|
}
|
|
1260
432
|
//#endregion
|
|
1261
433
|
//#region src/createRenderer.ts
|
|
1262
434
|
/**
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
* Wrap your renderer factory function with this helper to register it as the
|
|
1266
|
-
* renderer for a generator. Core will call this factory once per render cycle
|
|
1267
|
-
* to obtain a fresh renderer instance.
|
|
435
|
+
* Wraps a renderer factory for use in generator definitions.
|
|
1268
436
|
*
|
|
1269
437
|
* @example
|
|
1270
438
|
* ```ts
|
|
1271
|
-
* // packages/renderer-jsx/src/index.ts
|
|
1272
439
|
* export const jsxRenderer = createRenderer(() => {
|
|
1273
440
|
* const runtime = new Runtime()
|
|
1274
441
|
* return {
|
|
1275
442
|
* async render(element) { await runtime.render(element) },
|
|
1276
443
|
* get files() { return runtime.nodes },
|
|
444
|
+
* dispose() { runtime.unmount() },
|
|
1277
445
|
* unmount(error) { runtime.unmount(error) },
|
|
1278
446
|
* }
|
|
1279
447
|
* })
|
|
1280
|
-
*
|
|
1281
|
-
* // packages/plugin-zod/src/generators/zodGenerator.tsx
|
|
1282
|
-
* import { jsxRenderer } from '@kubb/renderer-jsx'
|
|
1283
|
-
* export const zodGenerator = defineGenerator<PluginZod>({
|
|
1284
|
-
* name: 'zod',
|
|
1285
|
-
* renderer: jsxRenderer,
|
|
1286
|
-
* schema(node, options) { return <File ...>...</File> },
|
|
1287
|
-
* })
|
|
1288
448
|
* ```
|
|
1289
449
|
*/
|
|
1290
450
|
function createRenderer(factory) {
|
|
@@ -1305,7 +465,11 @@ function defineGenerator(generator) {
|
|
|
1305
465
|
/**
|
|
1306
466
|
* Wraps a logger definition into a typed {@link Logger}.
|
|
1307
467
|
*
|
|
1308
|
-
*
|
|
468
|
+
* The optional second type parameter `TInstallReturn` allows loggers to return
|
|
469
|
+
* a value from `install` — for example, a sink factory that the caller can
|
|
470
|
+
* forward to hook execution.
|
|
471
|
+
*
|
|
472
|
+
* @example Basic logger
|
|
1309
473
|
* ```ts
|
|
1310
474
|
* export const myLogger = defineLogger({
|
|
1311
475
|
* name: 'my-logger',
|
|
@@ -1315,6 +479,17 @@ function defineGenerator(generator) {
|
|
|
1315
479
|
* },
|
|
1316
480
|
* })
|
|
1317
481
|
* ```
|
|
482
|
+
*
|
|
483
|
+
* @example Logger that returns a hook sink factory
|
|
484
|
+
* ```ts
|
|
485
|
+
* export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
|
|
486
|
+
* name: 'my-logger',
|
|
487
|
+
* install(context, options) {
|
|
488
|
+
* // … register event handlers …
|
|
489
|
+
* return (commandWithArgs) => ({ onStdout: console.log })
|
|
490
|
+
* },
|
|
491
|
+
* })
|
|
492
|
+
* ```
|
|
1318
493
|
*/
|
|
1319
494
|
function defineLogger(logger) {
|
|
1320
495
|
return logger;
|
|
@@ -1385,34 +560,6 @@ function defineParser(parser) {
|
|
|
1385
560
|
return parser;
|
|
1386
561
|
}
|
|
1387
562
|
//#endregion
|
|
1388
|
-
//#region src/definePlugin.ts
|
|
1389
|
-
/**
|
|
1390
|
-
* Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
|
|
1391
|
-
*
|
|
1392
|
-
* Handlers live in a single `hooks` object (inspired by Astro integrations).
|
|
1393
|
-
* All lifecycle events from `KubbHooks` are available for subscription.
|
|
1394
|
-
*
|
|
1395
|
-
* @note For real plugins, use a `PluginFactoryOptions` type parameter to get type-safe context in `kubb:plugin:setup`.
|
|
1396
|
-
* Plugin names should follow the convention `plugin-<feature>` (e.g., `plugin-react-query`, `plugin-zod`).
|
|
1397
|
-
*
|
|
1398
|
-
* @example
|
|
1399
|
-
* ```ts
|
|
1400
|
-
* import { definePlugin } from '@kubb/core'
|
|
1401
|
-
*
|
|
1402
|
-
* export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
|
|
1403
|
-
* name: 'plugin-ts',
|
|
1404
|
-
* hooks: {
|
|
1405
|
-
* 'kubb:plugin:setup'(ctx) {
|
|
1406
|
-
* ctx.setResolver(resolverTs)
|
|
1407
|
-
* },
|
|
1408
|
-
* },
|
|
1409
|
-
* }))
|
|
1410
|
-
* ```
|
|
1411
|
-
*/
|
|
1412
|
-
function definePlugin(factory) {
|
|
1413
|
-
return (options) => factory(options ?? {});
|
|
1414
|
-
}
|
|
1415
|
-
//#endregion
|
|
1416
563
|
//#region src/storages/memoryStorage.ts
|
|
1417
564
|
/**
|
|
1418
565
|
* In-memory storage driver. Useful for testing and dry-run scenarios where
|
|
@@ -1463,11 +610,11 @@ const memoryStorage = createStorage(() => {
|
|
|
1463
610
|
};
|
|
1464
611
|
});
|
|
1465
612
|
//#endregion
|
|
1466
|
-
exports.AsyncEventEmitter = AsyncEventEmitter;
|
|
1467
|
-
exports.FileManager =
|
|
1468
|
-
exports.FileProcessor = FileProcessor;
|
|
1469
|
-
exports.
|
|
1470
|
-
exports.URLPath = URLPath;
|
|
613
|
+
exports.AsyncEventEmitter = require_KubbDriver.AsyncEventEmitter;
|
|
614
|
+
exports.FileManager = require_KubbDriver.FileManager;
|
|
615
|
+
exports.FileProcessor = require_KubbDriver.FileProcessor;
|
|
616
|
+
exports.KubbDriver = require_KubbDriver.KubbDriver;
|
|
617
|
+
exports.URLPath = require_KubbDriver.URLPath;
|
|
1471
618
|
Object.defineProperty(exports, "ast", {
|
|
1472
619
|
enumerable: true,
|
|
1473
620
|
get: function() {
|
|
@@ -1482,11 +629,11 @@ exports.defineGenerator = defineGenerator;
|
|
|
1482
629
|
exports.defineLogger = defineLogger;
|
|
1483
630
|
exports.defineMiddleware = defineMiddleware;
|
|
1484
631
|
exports.defineParser = defineParser;
|
|
1485
|
-
exports.definePlugin = definePlugin;
|
|
1486
|
-
exports.defineResolver =
|
|
632
|
+
exports.definePlugin = require_KubbDriver.definePlugin;
|
|
633
|
+
exports.defineResolver = require_KubbDriver.defineResolver;
|
|
1487
634
|
exports.fsStorage = fsStorage;
|
|
1488
635
|
exports.isInputPath = isInputPath;
|
|
1489
|
-
exports.logLevel =
|
|
636
|
+
exports.logLevel = require_KubbDriver.logLevel;
|
|
1490
637
|
exports.memoryStorage = memoryStorage;
|
|
1491
638
|
|
|
1492
639
|
//# sourceMappingURL=index.cjs.map
|