@kubb/core 1.15.0-canary.20231025T103357 → 1.15.0-canary.20231025T223729

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/index.cjs CHANGED
@@ -3,18 +3,19 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var pc3 = require('picocolors');
6
- var crypto = require('crypto');
7
6
  var fs2 = require('fs-extra');
8
- var changeCase = require('change-case');
9
- var naturalOrderby = require('natural-orderby');
10
- var perf_hooks = require('perf_hooks');
11
7
  var seedrandom = require('seedrandom');
12
- var path2 = require('path');
8
+ var path4 = require('path');
13
9
  var jsRuntime = require('js-runtime');
14
- var dirTree = require('directory-tree');
10
+ var changeCase = require('change-case');
11
+ var crypto2 = require('crypto');
15
12
  var parser = require('@kubb/parser');
13
+ var factory = require('@kubb/parser/factory');
16
14
  var isEqual = require('lodash.isequal');
15
+ var naturalOrderby = require('natural-orderby');
16
+ var dirTree = require('directory-tree');
17
17
  var events = require('events');
18
+ var perf_hooks = require('perf_hooks');
18
19
  var mod = require('module');
19
20
  var os = require('os');
20
21
  var url = require('url');
@@ -24,13 +25,32 @@ var semver = require('semver');
24
25
 
25
26
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
26
27
 
28
+ function _interopNamespace(e) {
29
+ if (e && e.__esModule) return e;
30
+ var n = Object.create(null);
31
+ if (e) {
32
+ Object.keys(e).forEach(function (k) {
33
+ if (k !== 'default') {
34
+ var d = Object.getOwnPropertyDescriptor(e, k);
35
+ Object.defineProperty(n, k, d.get ? d : {
36
+ enumerable: true,
37
+ get: function () { return e[k]; }
38
+ });
39
+ }
40
+ });
41
+ }
42
+ n.default = e;
43
+ return Object.freeze(n);
44
+ }
45
+
27
46
  var pc3__default = /*#__PURE__*/_interopDefault(pc3);
28
- var crypto__default = /*#__PURE__*/_interopDefault(crypto);
29
47
  var fs2__default = /*#__PURE__*/_interopDefault(fs2);
30
48
  var seedrandom__default = /*#__PURE__*/_interopDefault(seedrandom);
31
- var path2__default = /*#__PURE__*/_interopDefault(path2);
32
- var dirTree__default = /*#__PURE__*/_interopDefault(dirTree);
49
+ var path4__default = /*#__PURE__*/_interopDefault(path4);
50
+ var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
51
+ var factory__namespace = /*#__PURE__*/_interopNamespace(factory);
33
52
  var isEqual__default = /*#__PURE__*/_interopDefault(isEqual);
53
+ var dirTree__default = /*#__PURE__*/_interopDefault(dirTree);
34
54
  var mod__default = /*#__PURE__*/_interopDefault(mod);
35
55
  var os__default = /*#__PURE__*/_interopDefault(os);
36
56
  var process__default = /*#__PURE__*/_interopDefault(process);
@@ -43,110 +63,15 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
43
63
  return require.apply(this, arguments);
44
64
  throw Error('Dynamic require of "' + x + '" is not supported');
45
65
  });
46
-
47
- // src/utils/cache.ts
48
- function createPluginCache(Store = /* @__PURE__ */ Object.create(null)) {
49
- return {
50
- set(id, value) {
51
- Store[id] = [0, value];
52
- },
53
- get(id) {
54
- const item = Store[id];
55
- if (!item) {
56
- return null;
57
- }
58
- item[0] = 0;
59
- return item[1];
60
- },
61
- has(id) {
62
- const item = Store[id];
63
- if (!item) {
64
- return false;
65
- }
66
- item[0] = 0;
67
- return true;
68
- },
69
- delete(id) {
70
- return delete Store[id];
71
- }
72
- };
73
- }
74
- async function clean(path3) {
75
- return fs2.remove(path3);
66
+ async function clean(path5) {
67
+ return fs2.remove(path5);
76
68
  }
77
- var FunctionParams = class {
78
- type;
79
- items = [];
80
- constructor(type) {
81
- this.type = type;
82
- return this;
83
- }
84
- add(item) {
85
- if (!item) {
86
- return this;
87
- }
88
- if (Array.isArray(item)) {
89
- item.filter(Boolean).forEach((it) => this.items.push(it));
90
- return this;
91
- }
92
- this.items.push(item);
93
- return this;
94
- }
95
- toString() {
96
- const sortedData = naturalOrderby.orderBy(this.items.filter(Boolean), [(v) => !v.default, (v) => v.required ?? true], ["desc", "desc"]);
97
- return sortedData.filter(({ enabled = true }) => enabled).reduce((acc, { name, type, required = true, ...rest }) => {
98
- if (!name) {
99
- acc.push(`${type}${rest.default ? ` = ${rest.default}` : ""}`);
100
- return acc;
101
- }
102
- const parameterName = name.startsWith("{") ? name : changeCase.camelCase(name, { delimiter: "", transform: changeCase.camelCaseTransformMerge });
103
- if (type) {
104
- if (required) {
105
- acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ""}`);
106
- } else {
107
- acc.push(`${parameterName}?: ${type}`);
108
- }
109
- } else {
110
- acc.push(`${parameterName}`);
111
- }
112
- return acc;
113
- }, []).join(", ");
114
- }
69
+ var LogLevel = {
70
+ silent: "silent",
71
+ info: "info",
72
+ debug: "debug"
115
73
  };
116
-
117
- // src/utils/getUniqueName.ts
118
- function getUniqueName(originalName, data) {
119
- let used = data[originalName] || 0;
120
- if (used) {
121
- data[originalName] = ++used;
122
- originalName += used;
123
- }
124
- data[originalName] = 1;
125
- return originalName;
126
- }
127
-
128
- // src/utils/isPromise.ts
129
- function isPromise(result) {
130
- return typeof result?.then === "function";
131
- }
132
- function isPromiseFulfilledResult(result) {
133
- return result.status === "fulfilled";
134
- }
135
- function isPromiseRejectedResult(result) {
136
- return result.status === "rejected";
137
- }
138
-
139
- // src/utils/jsdoc.ts
140
- function createJSDocBlockText({ comments }) {
141
- const filteredComments = comments.filter(Boolean);
142
- if (!filteredComments.length) {
143
- return "";
144
- }
145
- return `/**
146
- * ${filteredComments.join("\n * ")}
147
- */`;
148
- }
149
- function createLogger(spinner) {
74
+ function createLogger({ logLevel, name, spinner }) {
150
75
  const logs = [];
151
76
  const log = (message) => {
152
77
  if (message && spinner) {
@@ -172,6 +97,8 @@ function createLogger(spinner) {
172
97
  }
173
98
  };
174
99
  const logger = {
100
+ name,
101
+ logLevel,
175
102
  log,
176
103
  error,
177
104
  warn,
@@ -181,75 +108,6 @@ function createLogger(spinner) {
181
108
  };
182
109
  return logger;
183
110
  }
184
-
185
- // src/utils/nameSorter.ts
186
- function nameSorter(a, b) {
187
- if (a.name < b.name) {
188
- return -1;
189
- }
190
- if (a.name > b.name) {
191
- return 1;
192
- }
193
- return 0;
194
- }
195
- var Queue = class {
196
- #queue = [];
197
- #workerCount = 0;
198
- #maxParallel;
199
- #debug = false;
200
- constructor(maxParallel, debug = false) {
201
- this.#maxParallel = maxParallel;
202
- this.#debug = debug;
203
- }
204
- run(job, options = { controller: new AbortController(), name: crypto__default.default.randomUUID(), description: "" }) {
205
- return new Promise((resolve, reject) => {
206
- const item = { reject, resolve, job, name: options.name, description: options.description || options.name };
207
- options.controller?.signal.addEventListener("abort", () => {
208
- this.#queue = this.#queue.filter((queueItem) => queueItem.name === item.name);
209
- reject("Aborted");
210
- });
211
- this.#queue.push(item);
212
- this.#work();
213
- });
214
- }
215
- runSync(job, options = { controller: new AbortController(), name: crypto__default.default.randomUUID(), description: "" }) {
216
- new Promise((resolve, reject) => {
217
- const item = { reject, resolve, job, name: options.name, description: options.description || options.name };
218
- options.controller?.signal.addEventListener("abort", () => {
219
- this.#queue = this.#queue.filter((queueItem) => queueItem.name === item.name);
220
- });
221
- this.#queue.push(item);
222
- this.#work();
223
- });
224
- }
225
- get hasJobs() {
226
- return this.#workerCount > 0 || this.#queue.length > 0;
227
- }
228
- get count() {
229
- return this.#workerCount;
230
- }
231
- #work() {
232
- if (this.#workerCount >= this.#maxParallel) {
233
- return;
234
- }
235
- this.#workerCount++;
236
- let entry;
237
- while (entry = this.#queue.shift()) {
238
- const { reject, resolve, job, name, description } = entry;
239
- if (this.#debug) {
240
- perf_hooks.performance.mark(name + "_start");
241
- }
242
- job().then((result) => {
243
- resolve(result);
244
- if (this.#debug) {
245
- perf_hooks.performance.mark(name + "_stop");
246
- perf_hooks.performance.measure(description, name + "_start", name + "_stop");
247
- }
248
- }).catch((err) => reject(err));
249
- }
250
- this.#workerCount--;
251
- }
252
- };
253
111
  var defaultColours = ["black", "blue", "darkBlue", "cyan", "gray", "green", "darkGreen", "magenta", "red", "darkRed", "yellow", "darkYellow"];
254
112
  function randomColour(text, colours = defaultColours) {
255
113
  if (!text) {
@@ -276,46 +134,22 @@ function randomPicoColour(text, colors = defaultColours) {
276
134
  }
277
135
  return formatter(text);
278
136
  }
279
- function slash(path3, platform = "linux") {
280
- const isWindowsPath = /^\\\\\?\\/.test(path3);
281
- if (["linux", "mac"].includes(platform) && !isWindowsPath) {
282
- return path3.replaceAll(/\\/g, "/").replace("../", "").trimEnd();
283
- }
284
- return path3.replaceAll(/\\/g, "/").replace("../", "").trimEnd();
285
- }
286
- function getRelativePath(rootDir, filePath, platform = "linux") {
287
- if (!rootDir || !filePath) {
288
- throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
289
- }
290
- const relativePath = path2__default.default.relative(rootDir, filePath);
291
- const path3 = slash(relativePath, platform);
292
- if (path3.startsWith("../")) {
293
- return path3.replace(path2__default.default.basename(path3), path2__default.default.basename(path3, path2__default.default.extname(filePath)));
294
- }
295
- return `./${path3.replace(path2__default.default.basename(path3), path2__default.default.basename(path3, path2__default.default.extname(filePath)))}`;
296
- }
297
- function getPathMode(path3) {
298
- if (!path3) {
299
- return "directory";
300
- }
301
- return path2__default.default.extname(path3) ? "file" : "directory";
302
- }
303
137
  var reader = jsRuntime.switcher(
304
138
  {
305
- node: async (path3) => {
306
- return fs2__default.default.readFile(path3, { encoding: "utf8" });
139
+ node: async (path5) => {
140
+ return fs2__default.default.readFile(path5, { encoding: "utf8" });
307
141
  },
308
- bun: async (path3) => {
309
- const file = Bun.file(path3);
142
+ bun: async (path5) => {
143
+ const file = Bun.file(path5);
310
144
  return file.text();
311
145
  }
312
146
  },
313
147
  "node"
314
148
  );
315
- var syncReader = jsRuntime.switcher(
149
+ jsRuntime.switcher(
316
150
  {
317
- node: (path3) => {
318
- return fs2__default.default.readFileSync(path3, { encoding: "utf8" });
151
+ node: (path5) => {
152
+ return fs2__default.default.readFileSync(path5, { encoding: "utf8" });
319
153
  },
320
154
  bun: () => {
321
155
  throw new Error("Bun cannot read sync");
@@ -323,113 +157,194 @@ var syncReader = jsRuntime.switcher(
323
157
  },
324
158
  "node"
325
159
  );
326
- async function read(path3) {
327
- return reader(path3);
328
- }
329
- function readSync(path3) {
330
- return syncReader(path3);
331
- }
332
-
333
- // src/utils/renderTemplate.ts
334
- function renderTemplate(template, data = void 0) {
335
- if (!data || !Object.keys(data).length) {
336
- return template.replace(/{{(.*?)}}/g, "");
337
- }
338
- const matches = template.match(/{{(.*?)}}/g);
339
- return matches?.reduce((prev, curr) => {
340
- const index = curr.split(/{{|}}/).filter(Boolean)[0]?.trim();
341
- if (index === void 0) {
342
- return prev;
343
- }
344
- const value = data[index];
345
- if (value === void 0) {
346
- return prev;
347
- }
348
- return prev.replace(curr, () => {
349
- if (typeof value === "boolean") {
350
- return `${value.toString()}` || "false";
351
- }
352
- return value || "";
353
- }).trim();
354
- }, template) || "";
160
+ async function read(path5) {
161
+ return reader(path5);
355
162
  }
356
-
357
- // src/utils/SummaryError.ts
358
- var SummaryError = class extends Error {
359
- summary;
360
- constructor(message, options) {
361
- super(message, { cause: options.cause });
362
- this.name = "SummaryError";
363
- this.summary = options.summary || [];
163
+ var URLPath = class {
164
+ path;
165
+ constructor(path5) {
166
+ this.path = path5;
167
+ return this;
364
168
  }
365
- };
366
-
367
- // src/utils/throttle.ts
368
- var throttle = (fn, delay) => {
369
- let wait = false;
370
- let timeout2;
371
- let cancelled = false;
372
- return [
373
- (...args) => {
374
- if (cancelled) {
375
- return void 0;
376
- }
377
- if (wait) {
378
- return void 0;
169
+ /**
170
+ * Convert Swagger path to URLPath(syntax of Express)
171
+ * @example /pet/{petId} => /pet/:petId
172
+ */
173
+ get URL() {
174
+ return this.toURLPath();
175
+ }
176
+ get isURL() {
177
+ try {
178
+ const url = new URL(this.path);
179
+ if (url?.href) {
180
+ return true;
379
181
  }
380
- const val = fn(...args);
381
- wait = true;
382
- timeout2 = setTimeout(() => {
383
- wait = false;
384
- }, delay);
385
- return val;
386
- },
387
- () => {
388
- cancelled = true;
389
- clearTimeout(timeout2);
182
+ } catch (error) {
183
+ return false;
390
184
  }
391
- ];
392
- };
393
-
394
- // src/utils/timeout.ts
395
- async function timeout(ms) {
396
- return new Promise((resolve) => {
397
- setTimeout(() => {
398
- resolve(true);
399
- }, ms);
400
- });
401
- }
402
-
403
- // src/utils/transformers/combineCodes.ts
404
- function combineCodes(codes) {
405
- return codes.join("\n");
406
- }
407
-
408
- // src/utils/transformers/escape.ts
409
- function escape(text) {
410
- return text ? text.replaceAll("`", "\\`") : "";
411
- }
412
- function jsStringEscape(input) {
413
- return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
414
- switch (character) {
415
- case '"':
416
- case "'":
417
- case "\\":
418
- return "\\" + character;
419
- case "\n":
420
- return "\\n";
421
- case "\r":
422
- return "\\r";
423
- case "\u2028":
424
- return "\\u2028";
425
- case "\u2029":
426
- return "\\u2029";
427
- default:
428
- return "";
185
+ return false;
186
+ }
187
+ /**
188
+ * Convert Swagger path to template literals/ template strings(camelcase)
189
+ * @example /pet/{petId} => `/pet/${petId}`
190
+ * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
191
+ * @example /account/userID => `/account/${userId}`
192
+ */
193
+ get template() {
194
+ return this.toTemplateString();
195
+ }
196
+ get object() {
197
+ return this.toObject();
198
+ }
199
+ get params() {
200
+ return this.getParams();
201
+ }
202
+ toObject({ type = "path", replacer, stringify } = {}) {
203
+ const object = {
204
+ url: type === "path" ? this.toURLPath() : this.toTemplateString(replacer),
205
+ params: this.getParams()
206
+ };
207
+ if (stringify) {
208
+ if (type !== "template") {
209
+ throw new Error("Type should be `template` when using stringiyf");
210
+ }
211
+ return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
212
+ }
213
+ return object;
214
+ }
215
+ /**
216
+ * Convert Swagger path to template literals/ template strings(camelcase)
217
+ * @example /pet/{petId} => `/pet/${petId}`
218
+ * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
219
+ * @example /account/userID => `/account/${userId}`
220
+ */
221
+ toTemplateString(replacer) {
222
+ const regex = /{(\w|-)*}/g;
223
+ const found = this.path.match(regex);
224
+ let newPath = this.path.replaceAll("{", "${");
225
+ if (found) {
226
+ newPath = found.reduce((prev, curr) => {
227
+ const pathParam = replacer ? replacer(changeCase.camelCase(curr, { delimiter: "", transform: changeCase.camelCaseTransformMerge })) : changeCase.camelCase(curr, { delimiter: "", transform: changeCase.camelCaseTransformMerge });
228
+ const replacement = `\${${pathParam}}`;
229
+ return prev.replace(curr, replacement);
230
+ }, this.path);
231
+ }
232
+ return `\`${newPath}\``;
233
+ }
234
+ getParams(replacer) {
235
+ const regex = /{(\w|-)*}/g;
236
+ const found = this.path.match(regex);
237
+ if (!found) {
238
+ return void 0;
239
+ }
240
+ const params = {};
241
+ found.forEach((item) => {
242
+ item = item.replaceAll("{", "").replaceAll("}", "");
243
+ const pathParam = replacer ? replacer(changeCase.camelCase(item, { delimiter: "", transform: changeCase.camelCaseTransformMerge })) : changeCase.camelCase(item, { delimiter: "", transform: changeCase.camelCaseTransformMerge });
244
+ params[pathParam] = pathParam;
245
+ }, this.path);
246
+ return params;
247
+ }
248
+ /**
249
+ * Convert Swagger path to URLPath(syntax of Express)
250
+ * @example /pet/{petId} => /pet/:petId
251
+ */
252
+ toURLPath() {
253
+ return this.path.replaceAll("{", ":").replaceAll("}", "");
254
+ }
255
+ };
256
+
257
+ // src/config.ts
258
+ function defineConfig(options) {
259
+ return options;
260
+ }
261
+ function isInputPath(result) {
262
+ return !!result && "path" in result;
263
+ }
264
+
265
+ // src/utils/timeout.ts
266
+ async function timeout(ms) {
267
+ return new Promise((resolve2) => {
268
+ setTimeout(() => {
269
+ resolve2(true);
270
+ }, ms);
271
+ });
272
+ }
273
+
274
+ // src/utils/transformers/combineCodes.ts
275
+ function combineCodes(codes) {
276
+ return codes.join("\n");
277
+ }
278
+
279
+ // src/utils/transformers/createJSDocBlockText.ts
280
+ function createJSDocBlockText({ comments }) {
281
+ const filteredComments = comments.filter(Boolean);
282
+ if (!filteredComments.length) {
283
+ return "";
284
+ }
285
+ return `/**
286
+ * ${filteredComments.join("\n * ")}
287
+ */`;
288
+ }
289
+
290
+ // src/utils/transformers/escape.ts
291
+ function escape(text) {
292
+ return text ? text.replaceAll("`", "\\`") : "";
293
+ }
294
+ function jsStringEscape(input) {
295
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
296
+ switch (character) {
297
+ case '"':
298
+ case "'":
299
+ case "\\":
300
+ return "\\" + character;
301
+ case "\n":
302
+ return "\\n";
303
+ case "\r":
304
+ return "\\r";
305
+ case "\u2028":
306
+ return "\\u2028";
307
+ case "\u2029":
308
+ return "\\u2029";
309
+ default:
310
+ return "";
429
311
  }
430
312
  });
431
313
  }
432
314
 
315
+ // src/utils/transformers/indent.ts
316
+ function createIndent(size) {
317
+ return Array.from({ length: size + 1 }).join(" ");
318
+ }
319
+
320
+ // src/utils/transformers/nameSorter.ts
321
+ function nameSorter(a, b) {
322
+ if (a.name < b.name) {
323
+ return -1;
324
+ }
325
+ if (a.name > b.name) {
326
+ return 1;
327
+ }
328
+ return 0;
329
+ }
330
+
331
+ // src/utils/transformers/searchAndReplace.ts
332
+ function searchAndReplace(options) {
333
+ const { text, replaceBy, prefix = "", key } = options;
334
+ const searchValues = options.searchValues?.(prefix, key) || [
335
+ `${prefix}["${key}"]`,
336
+ `${prefix}['${key}']`,
337
+ `${prefix}[\`${key}\`]`,
338
+ `${prefix}"${key}"`,
339
+ `${prefix}'${key}'`,
340
+ `${prefix}\`${key}\``,
341
+ new RegExp(`${prefix}${key}`, "g")
342
+ ];
343
+ return searchValues.reduce((prev, searchValue) => {
344
+ return prev.toString().replaceAll(searchValue, replaceBy);
345
+ }, text);
346
+ }
347
+
433
348
  // src/utils/transformers/transformReservedWord.ts
434
349
  var reservedWords = [
435
350
  "abstract",
@@ -522,6 +437,80 @@ function transformReservedWord(word) {
522
437
  }
523
438
  return word;
524
439
  }
440
+
441
+ // src/utils/transformers/index.ts
442
+ var transformers = {
443
+ combineCodes,
444
+ escape,
445
+ jsStringEscape,
446
+ createIndent,
447
+ transformReservedWord,
448
+ nameSorter,
449
+ searchAndReplace,
450
+ JSDoc: {
451
+ createJSDocBlockText
452
+ }
453
+ };
454
+ async function saveCreateDirectory(path5) {
455
+ const passedPath = path4.dirname(path4.resolve(path5));
456
+ await fs2__default.default.mkdir(passedPath, { recursive: true });
457
+ }
458
+ var writer = jsRuntime.switcher(
459
+ {
460
+ node: async (path5, data) => {
461
+ try {
462
+ await fs2__default.default.stat(path4.resolve(path5));
463
+ const oldContent = await fs2__default.default.readFile(path4.resolve(path5), { encoding: "utf-8" });
464
+ if (oldContent?.toString() === data?.toString()) {
465
+ return;
466
+ }
467
+ } catch (_err) {
468
+ }
469
+ await saveCreateDirectory(path5);
470
+ await fs2__default.default.writeFile(path4.resolve(path5), data, { encoding: "utf-8" });
471
+ const savedData = await fs2__default.default.readFile(path4.resolve(path5), { encoding: "utf-8" });
472
+ if (savedData?.toString() !== data?.toString()) {
473
+ throw new Error(`Sanity check failed for ${path5}
474
+
475
+ Data[${data.length}]:
476
+ ${data}
477
+
478
+ Saved[${savedData.length}]:
479
+ ${savedData}
480
+ `);
481
+ }
482
+ return savedData;
483
+ },
484
+ bun: async (path5, data) => {
485
+ try {
486
+ await saveCreateDirectory(path5);
487
+ await Bun.write(path4.resolve(path5), data);
488
+ const file = Bun.file(path4.resolve(path5));
489
+ const savedData = await file.text();
490
+ if (savedData?.toString() !== data?.toString()) {
491
+ throw new Error(`Sanity check failed for ${path5}
492
+
493
+ Data[${data.length}]:
494
+ ${data}
495
+
496
+ Saved[${savedData.length}]:
497
+ ${savedData}
498
+ `);
499
+ }
500
+ return savedData;
501
+ } catch (e) {
502
+ console.log(e, path4.resolve(path5));
503
+ }
504
+ }
505
+ },
506
+ "node"
507
+ );
508
+ async function write(data, path5) {
509
+ if (data.trim() === "") {
510
+ return void 0;
511
+ }
512
+ return writer(path5, data.trim());
513
+ }
525
514
  var TreeNode = class _TreeNode {
526
515
  data;
527
516
  parent;
@@ -586,16 +575,16 @@ var TreeNode = class _TreeNode {
586
575
  }
587
576
  return this;
588
577
  }
589
- static build(path3, options = {}) {
578
+ static build(path5, options = {}) {
590
579
  try {
591
580
  const exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude].filter(Boolean);
592
- const filteredTree = dirTree__default.default(path3, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] });
581
+ const filteredTree = dirTree__default.default(path5, { extensions: options.extensions, exclude: [/node_modules/, ...exclude] });
593
582
  if (!filteredTree) {
594
583
  return null;
595
584
  }
596
- const treeNode = new _TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type || getPathMode(filteredTree.path) });
585
+ const treeNode = new _TreeNode({ name: filteredTree.name, path: filteredTree.path, type: filteredTree.type || FileManager.getMode(filteredTree.path) });
597
586
  const recurse = (node, item) => {
598
- const subNode = node.addChild({ name: item.name, path: item.path, type: item.type || getPathMode(item.path) });
587
+ const subNode = node.addChild({ name: item.name, path: item.path, type: item.type || FileManager.getMode(item.path) });
599
588
  if (item.children?.length) {
600
589
  item.children?.forEach((child) => {
601
590
  recurse(subNode, child);
@@ -610,227 +599,271 @@ var TreeNode = class _TreeNode {
610
599
  }
611
600
  };
612
601
 
613
- // src/utils/uniqueIdFactory.ts
614
- var uniqueIdFactory = (counter) => (str = "") => `${str}${++counter}`;
615
- var URLPath = class {
616
- path;
617
- constructor(path3) {
618
- this.path = path3;
602
+ // src/BarrelManager.ts
603
+ var BarrelManager = class {
604
+ #options = {};
605
+ constructor(options = {}) {
606
+ this.#options = options;
619
607
  return this;
620
608
  }
621
- /**
622
- * Convert Swagger path to URLPath(syntax of Express)
623
- * @example /pet/{petId} => /pet/:petId
624
- */
625
- get URL() {
626
- return this.toURLPath();
627
- }
628
- get isURL() {
629
- try {
630
- const url = new URL(this.path);
631
- if (url?.href) {
632
- return true;
609
+ getIndexes(root, extName) {
610
+ const { treeNode = {}, isTypeOnly, filter, map, output, includeExt } = this.#options;
611
+ const extMapper = {
612
+ ".ts": {
613
+ extensions: /\.ts/,
614
+ exclude: [/schemas/, /json/]
615
+ },
616
+ ".json": {
617
+ extensions: /\.json/,
618
+ exclude: []
633
619
  }
634
- } catch (error) {
635
- return false;
620
+ };
621
+ const tree = TreeNode.build(root, { ...extMapper[extName] || {}, ...treeNode });
622
+ if (!tree) {
623
+ return null;
636
624
  }
637
- return false;
625
+ const fileReducer = (files2, currentTree) => {
626
+ if (!currentTree.children) {
627
+ return [];
628
+ }
629
+ if (currentTree.children?.length > 1) {
630
+ const indexPath = path4__default.default.resolve(currentTree.data.path, "index.ts");
631
+ const exports = currentTree.children.filter(Boolean).map((file) => {
632
+ const importPath = file.data.type === "directory" ? `./${file.data.name}` : `./${file.data.name.replace(/\.[^.]*$/, "")}`;
633
+ if (importPath.includes("index") && indexPath.includes("index")) {
634
+ return void 0;
635
+ }
636
+ return {
637
+ path: includeExt ? file.data.type === "directory" ? `${importPath}/index${extName}` : `${importPath}${extName}` : importPath,
638
+ isTypeOnly
639
+ };
640
+ }).filter(Boolean);
641
+ files2.push({
642
+ path: indexPath,
643
+ baseName: "index.ts",
644
+ source: "",
645
+ exports: output ? exports?.filter((item) => {
646
+ return item.path.endsWith(output.replace(/\.[^.]*$/, ""));
647
+ }) : exports
648
+ });
649
+ } else {
650
+ currentTree.children?.forEach((child) => {
651
+ const indexPath = path4__default.default.resolve(currentTree.data.path, "index.ts");
652
+ const importPath = child.data.type === "directory" ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, "")}`;
653
+ const exports = [
654
+ {
655
+ path: includeExt ? child.data.type === "directory" ? `${importPath}/index${extName}` : `${importPath}${extName}` : importPath,
656
+ isTypeOnly
657
+ }
658
+ ];
659
+ files2.push({
660
+ path: indexPath,
661
+ baseName: "index.ts",
662
+ source: "",
663
+ exports: output ? exports?.filter((item) => {
664
+ return item.path.endsWith(output.replace(/\.[^.]*$/, ""));
665
+ }) : exports
666
+ });
667
+ });
668
+ }
669
+ currentTree.children.forEach((childItem) => {
670
+ fileReducer(files2, childItem);
671
+ });
672
+ return files2;
673
+ };
674
+ const files = fileReducer([], tree).reverse();
675
+ const filteredFiles = filter ? files.filter(filter) : files;
676
+ return map ? filteredFiles.map(map) : filteredFiles;
638
677
  }
678
+ };
679
+
680
+ // src/FileManager.ts
681
+ var FileManager = class _FileManager {
682
+ #cache = /* @__PURE__ */ new Map();
683
+ #task;
684
+ #isWriting = false;
639
685
  /**
640
- * Convert Swagger path to template literals/ template strings(camelcase)
641
- * @example /pet/{petId} => `/pet/${petId}`
642
- * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
643
- * @example /account/userID => `/account/${userId}`
686
+ * Timeout between writes
644
687
  */
645
- get template() {
646
- return this.toTemplateString();
688
+ #timeout = 0;
689
+ #queue;
690
+ constructor(options) {
691
+ if (options) {
692
+ this.#task = options.task;
693
+ this.#queue = options.queue;
694
+ this.#timeout = options.timeout || 0;
695
+ }
696
+ return this;
647
697
  }
648
- get object() {
649
- return this.toObject();
698
+ get files() {
699
+ const files = [];
700
+ this.#cache.forEach((item) => {
701
+ files.push(...item.flat(1));
702
+ });
703
+ return files;
650
704
  }
651
- get params() {
652
- return this.getParams();
705
+ get isExecuting() {
706
+ return this.#queue?.hasJobs ?? this.#isWriting ?? false;
653
707
  }
654
- toObject({ type = "path", replacer, stringify } = {}) {
655
- const object = {
656
- url: type === "path" ? this.toURLPath() : this.toTemplateString(replacer),
657
- params: this.getParams()
658
- };
659
- if (stringify) {
660
- if (type !== "template") {
661
- throw new Error("Type should be `template` when using stringiyf");
708
+ #validate(file) {
709
+ if (!file.validate) {
710
+ return;
711
+ }
712
+ if (!file.path.toLowerCase().endsWith(file.baseName.toLowerCase())) {
713
+ throw new Error(`${file.path} should end with the baseName ${file.baseName}`);
714
+ }
715
+ }
716
+ async add(...files) {
717
+ const promises = files.map((file) => {
718
+ this.#validate(file);
719
+ if (file.override) {
720
+ return this.#add(file);
662
721
  }
663
- return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
722
+ return this.#addOrAppend(file);
723
+ });
724
+ const resolvedFiles = await Promise.all(promises);
725
+ if (files.length > 1) {
726
+ return resolvedFiles;
664
727
  }
665
- return object;
728
+ return resolvedFiles[0];
666
729
  }
667
- /**
668
- * Convert Swagger path to template literals/ template strings(camelcase)
669
- * @example /pet/{petId} => `/pet/${petId}`
670
- * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
671
- * @example /account/userID => `/account/${userId}`
672
- */
673
- toTemplateString(replacer) {
674
- const regex = /{(\w|-)*}/g;
675
- const found = this.path.match(regex);
676
- let newPath = this.path.replaceAll("{", "${");
677
- if (found) {
678
- newPath = found.reduce((prev, curr) => {
679
- const pathParam = replacer ? replacer(changeCase.camelCase(curr, { delimiter: "", transform: changeCase.camelCaseTransformMerge })) : changeCase.camelCase(curr, { delimiter: "", transform: changeCase.camelCaseTransformMerge });
680
- const replacement = `\${${pathParam}}`;
681
- return prev.replace(curr, replacement);
682
- }, this.path);
730
+ async #add(file) {
731
+ const controller = new AbortController();
732
+ const resolvedFile = { id: crypto2__default.default.randomUUID(), ...file };
733
+ this.#cache.set(resolvedFile.path, [{ cancel: () => controller.abort(), ...resolvedFile }]);
734
+ if (this.#queue) {
735
+ await this.#queue.run(
736
+ async () => {
737
+ return this.#task?.(resolvedFile);
738
+ },
739
+ { controller }
740
+ );
683
741
  }
684
- return `\`${newPath}\``;
742
+ return resolvedFile;
685
743
  }
686
- getParams(replacer) {
687
- const regex = /{(\w|-)*}/g;
688
- const found = this.path.match(regex);
689
- if (!found) {
744
+ async #addOrAppend(file) {
745
+ const previousCaches = this.#cache.get(file.path);
746
+ const previousCache = previousCaches ? previousCaches.at(previousCaches.length - 1) : void 0;
747
+ if (previousCache) {
748
+ this.#cache.delete(previousCache.path);
749
+ return this.#add({
750
+ ...file,
751
+ source: previousCache.source && file.source ? `${previousCache.source}
752
+ ${file.source}` : "",
753
+ imports: [...previousCache.imports || [], ...file.imports || []],
754
+ exports: [...previousCache.exports || [], ...file.exports || []],
755
+ env: { ...previousCache.env || {}, ...file.env || {} }
756
+ });
757
+ }
758
+ return this.#add(file);
759
+ }
760
+ async addIndexes({ root, extName = ".ts", meta, options = {} }) {
761
+ const barrelManager = new BarrelManager(options);
762
+ const files = barrelManager.getIndexes(root, extName);
763
+ if (!files) {
690
764
  return void 0;
691
765
  }
692
- const params = {};
693
- found.forEach((item) => {
694
- item = item.replaceAll("{", "").replaceAll("}", "");
695
- const pathParam = replacer ? replacer(changeCase.camelCase(item, { delimiter: "", transform: changeCase.camelCaseTransformMerge })) : changeCase.camelCase(item, { delimiter: "", transform: changeCase.camelCaseTransformMerge });
696
- params[pathParam] = pathParam;
697
- }, this.path);
698
- return params;
766
+ return await Promise.all(
767
+ files.map((file) => {
768
+ return this.#addOrAppend({
769
+ ...file,
770
+ meta: meta ? meta : file.meta
771
+ });
772
+ })
773
+ );
699
774
  }
700
- /**
701
- * Convert Swagger path to URLPath(syntax of Express)
702
- * @example /pet/{petId} => /pet/:petId
703
- */
704
- toURLPath() {
705
- return this.path.replaceAll("{", ":").replaceAll("}", "");
775
+ getCacheByUUID(UUID) {
776
+ let cache;
777
+ this.#cache.forEach((files) => {
778
+ cache = files.find((item) => item.id === UUID);
779
+ });
780
+ return cache;
706
781
  }
707
- };
708
-
709
- // src/utils/Warning.ts
710
- var Warning = class extends Error {
711
- constructor(message, options) {
712
- super(message, { cause: options?.cause });
713
- this.name = "Warning";
782
+ get(path5) {
783
+ return this.#cache.get(path5);
714
784
  }
715
- };
716
- async function saveCreateDirectory(path3) {
717
- const passedPath = path2__default.default.dirname(path2__default.default.resolve(path3));
718
- await fs2__default.default.mkdir(passedPath, { recursive: true });
719
- }
720
- var writer = jsRuntime.switcher(
721
- {
722
- node: async (path3, data) => {
723
- try {
724
- await fs2__default.default.stat(path3);
725
- const oldContent = await fs2__default.default.readFile(path3, { encoding: "utf-8" });
726
- if (oldContent?.toString() === data) {
727
- return;
728
- }
729
- } catch (_err) {
730
- }
731
- await saveCreateDirectory(path3);
732
- return fs2__default.default.writeFile(path2__default.default.resolve(path3), data, { encoding: "utf-8" });
733
- },
734
- bun: async (path3, data) => {
735
- try {
736
- await saveCreateDirectory(path3);
737
- await Bun.write(path2__default.default.resolve(path3), data);
738
- } catch (e) {
739
- console.log(e, path2__default.default.resolve(path3));
740
- }
741
- }
742
- },
743
- "node"
744
- );
745
- async function write(data, path3) {
746
- return writer(path3, data);
747
- }
748
- function getIndexes(root, extName, options = {}) {
749
- const extMapper = {
750
- ".ts": {
751
- extensions: /\.ts/,
752
- exclude: [/schemas/, /json/]
753
- },
754
- ".json": {
755
- extensions: /\.json/,
756
- exclude: []
785
+ remove(path5) {
786
+ const cacheItem = this.get(path5);
787
+ if (!cacheItem) {
788
+ return;
757
789
  }
758
- };
759
- const tree = TreeNode.build(root, { ...extMapper[extName] || {}, ...options });
760
- if (!tree) {
761
- return null;
790
+ this.#cache.delete(path5);
762
791
  }
763
- const fileReducer = (files2, currentTree) => {
764
- if (!currentTree.children) {
765
- return [];
792
+ async write(...params) {
793
+ if (!this.#isWriting) {
794
+ this.#isWriting = true;
795
+ const text = await write(...params);
796
+ this.#isWriting = false;
797
+ return text;
766
798
  }
767
- if (currentTree.children?.length > 1) {
768
- const path3 = path2__default.default.resolve(currentTree.data.path, "index.ts");
769
- const exports = currentTree.children.map((file) => {
770
- if (!file) {
771
- return void 0;
772
- }
773
- const importPath = file.data.type === "directory" ? `./${file.data.name}` : `./${file.data.name.replace(/\.[^.]*$/, "")}`;
774
- if (importPath.includes("index") && path3.includes("index")) {
775
- return void 0;
776
- }
777
- return { path: importPath };
778
- }).filter(Boolean);
779
- files2.push({
780
- path: path3,
781
- baseName: "index.ts",
782
- source: "",
783
- exports
784
- });
785
- } else {
786
- currentTree.children?.forEach((child) => {
787
- const path3 = path2__default.default.resolve(currentTree.data.path, "index.ts");
788
- const importPath = child.data.type === "directory" ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, "")}`;
789
- files2.push({
790
- path: path3,
791
- baseName: "index.ts",
792
- source: "",
793
- exports: [{ path: importPath }]
794
- });
795
- });
799
+ await timeout(this.#timeout);
800
+ return this.write(...params);
801
+ }
802
+ async read(...params) {
803
+ return read(...params);
804
+ }
805
+ // statics
806
+ static getSource(file) {
807
+ if (!_FileManager.isExtensionAllowed(file.baseName)) {
808
+ return file.source;
796
809
  }
797
- currentTree.children.forEach((childItem) => {
798
- fileReducer(files2, childItem);
799
- });
800
- return files2;
801
- };
802
- const files = fileReducer([], tree);
803
- return files;
804
- }
805
- function combineFiles(files) {
806
- return files.filter(Boolean).reduce((acc, curr) => {
807
- const prevIndex = acc.findIndex((item) => item.path === curr.path);
808
- if (prevIndex !== -1) {
810
+ const exports = file.exports ? combineExports(file.exports) : [];
811
+ const imports = file.imports ? combineImports(file.imports, exports, file.source) : [];
812
+ const importNodes = imports.map((item) => factory__namespace.createImportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly }));
813
+ const exportNodes = exports.map(
814
+ (item) => factory__namespace.createExportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly, asAlias: item.asAlias })
815
+ );
816
+ return [parser.print([...importNodes, ...exportNodes]), getEnvSource(file.source, file.env)].join("\n");
817
+ }
818
+ static combineFiles(files) {
819
+ return files.filter(Boolean).reduce((acc, file) => {
820
+ const prevIndex = acc.findIndex((item) => item.path === file.path);
821
+ if (prevIndex === -1) {
822
+ return [...acc, file];
823
+ }
809
824
  const prev = acc[prevIndex];
825
+ if (prev && file.override) {
826
+ acc[prevIndex] = {
827
+ imports: [],
828
+ exports: [],
829
+ ...file
830
+ };
831
+ return acc;
832
+ }
810
833
  if (prev) {
811
834
  acc[prevIndex] = {
812
- ...curr,
813
- source: prev.source && curr.source ? `${prev.source}
814
- ${curr.source}` : "",
815
- imports: [...prev.imports || [], ...curr.imports || []],
816
- exports: [...prev.exports || [], ...curr.exports || []],
817
- env: { ...prev.env || {}, ...curr.env || {} }
835
+ ...file,
836
+ source: prev.source && file.source ? `${prev.source}
837
+ ${file.source}` : "",
838
+ imports: [...prev.imports || [], ...file.imports || []],
839
+ exports: [...prev.exports || [], ...file.exports || []],
840
+ env: { ...prev.env || {}, ...file.env || {} }
818
841
  };
819
842
  }
820
- } else {
821
- acc.push(curr);
843
+ return acc;
844
+ }, []);
845
+ }
846
+ static getMode(path5) {
847
+ if (!path5) {
848
+ return "directory";
822
849
  }
823
- return acc;
824
- }, []);
825
- }
826
- var extensions = [".js", ".ts", ".tsx"];
827
- function isExtensionAllowed(baseName) {
828
- return extensions.some((extension) => baseName.endsWith(extension));
829
- }
850
+ return path4.extname(path5) ? "file" : "directory";
851
+ }
852
+ static get extensions() {
853
+ return [".js", ".ts", ".tsx"];
854
+ }
855
+ static isExtensionAllowed(baseName) {
856
+ return _FileManager.extensions.some((extension) => baseName.endsWith(extension));
857
+ }
858
+ };
830
859
  function combineExports(exports) {
831
- return exports.reduce((prev, curr) => {
860
+ const combinedExports = naturalOrderby.orderBy(exports, [(v) => !v.isTypeOnly], ["asc"]).reduce((prev, curr) => {
832
861
  const name = curr.name;
833
862
  const prevByPath = prev.findLast((imp) => imp.path === curr.path);
863
+ const prevByPathAndIsTypeOnly = prev.findLast((imp) => imp.path === curr.path && isEqual__default.default(imp.name, name) && imp.isTypeOnly);
864
+ if (prevByPathAndIsTypeOnly) {
865
+ return prev;
866
+ }
834
867
  const uniquePrev = prev.findLast(
835
868
  (imp) => imp.path === curr.path && isEqual__default.default(imp.name, name) && imp.isTypeOnly === curr.isTypeOnly && imp.asAlias === curr.asAlias
836
869
  );
@@ -852,12 +885,16 @@ function combineExports(exports) {
852
885
  }
853
886
  return [...prev, curr];
854
887
  }, []);
888
+ return naturalOrderby.orderBy(combinedExports, [(v) => !v.isTypeOnly, (v) => v.asAlias], ["desc", "desc"]);
855
889
  }
856
890
  function combineImports(imports, exports, source) {
857
- return imports.reduce((prev, curr) => {
891
+ const combinedImports = naturalOrderby.orderBy(imports, [(v) => !v.isTypeOnly], ["asc"]).reduce((prev, curr) => {
858
892
  let name = Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name;
859
893
  const hasImportInSource = (importName) => {
860
- const checker = (name2) => name2 && !!source.includes(`${name2}`);
894
+ if (!source) {
895
+ return true;
896
+ }
897
+ const checker = (name2) => name2 && !!source.includes(name2);
861
898
  return checker(importName) || exports.some(({ name: name2 }) => Array.isArray(name2) ? name2.some(checker) : checker(name2));
862
899
  };
863
900
  if (Array.isArray(name)) {
@@ -865,6 +902,10 @@ function combineImports(imports, exports, source) {
865
902
  }
866
903
  const prevByPath = prev.findLast((imp) => imp.path === curr.path && imp.isTypeOnly === curr.isTypeOnly);
867
904
  const uniquePrev = prev.findLast((imp) => imp.path === curr.path && isEqual__default.default(imp.name, name) && imp.isTypeOnly === curr.isTypeOnly);
905
+ const prevByPathNameAndIsTypeOnly = prev.findLast((imp) => imp.path === curr.path && isEqual__default.default(imp.name, name) && imp.isTypeOnly);
906
+ if (prevByPathNameAndIsTypeOnly) {
907
+ return prev;
908
+ }
868
909
  if (uniquePrev || Array.isArray(name) && !name.length) {
869
910
  return prev;
870
911
  }
@@ -886,43 +927,7 @@ function combineImports(imports, exports, source) {
886
927
  }
887
928
  return [...prev, curr];
888
929
  }, []);
889
- }
890
- function createFileSource(file) {
891
- let { source } = file;
892
- if (!isExtensionAllowed(file.baseName)) {
893
- return file.source;
894
- }
895
- const exports = file.exports ? combineExports(file.exports) : [];
896
- const imports = file.imports ? combineImports(file.imports, exports, source) : [];
897
- const importNodes = imports.map((item) => parser.createImportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly }));
898
- const importSource = parser.print(importNodes);
899
- const exportNodes = exports.map((item) => parser.createExportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly, asAlias: item.asAlias }));
900
- const exportSource = parser.print(exportNodes);
901
- source = getEnvSource(file.source, file.env);
902
- if (importSource) {
903
- source = `${importSource}
904
- ${source}`;
905
- }
906
- if (exportSource) {
907
- source = `${exportSource}
908
- ${source}`;
909
- }
910
- return source;
911
- }
912
- function searchAndReplace(options) {
913
- const { text, replaceBy, prefix = "", key } = options;
914
- const searchValues = options.searchValues?.(prefix, key) || [
915
- `${prefix}["${key}"]`,
916
- `${prefix}['${key}']`,
917
- `${prefix}[\`${key}\`]`,
918
- `${prefix}"${key}"`,
919
- `${prefix}'${key}'`,
920
- `${prefix}\`${key}\``,
921
- new RegExp(`${prefix}${key}`, "g")
922
- ];
923
- return searchValues.reduce((prev, searchValue) => {
924
- return prev.toString().replaceAll(searchValue, replaceBy);
925
- }, text);
930
+ return naturalOrderby.orderBy(combinedImports, [(v) => !v.isTypeOnly], ["desc"]);
926
931
  }
927
932
  function getEnvSource(source, env) {
928
933
  if (!env) {
@@ -939,127 +944,117 @@ function getEnvSource(source, env) {
939
944
  throw new TypeError(`Environment should be in upperCase for ${key}`);
940
945
  }
941
946
  if (typeof replaceBy === "string") {
942
- prev = searchAndReplace({ text: prev.replaceAll(`process.env.${key}`, replaceBy), replaceBy, prefix: "process.env", key });
943
- prev = searchAndReplace({ text: prev.replaceAll(new RegExp(`(declare const).*
947
+ prev = transformers.searchAndReplace({ text: prev.replaceAll(`process.env.${key}`, replaceBy), replaceBy, prefix: "process.env", key });
948
+ prev = transformers.searchAndReplace({ text: prev.replaceAll(new RegExp(`(declare const).*
944
949
  `, "ig"), ""), replaceBy, key });
945
950
  }
946
951
  return prev;
947
952
  }, source);
948
953
  }
949
-
950
- // src/managers/fileManager/FileManager.ts
951
- var FileManager = class {
952
- #cache = /* @__PURE__ */ new Map();
953
- #task;
954
- #queue;
955
- constructor(options) {
956
- if (options) {
957
- this.#task = options.task;
958
- this.#queue = options.queue;
959
- }
960
- return this;
961
- }
962
- get extensions() {
963
- return extensions;
954
+ var EventEmitter = class {
955
+ constructor() {
956
+ this.#emitter.setMaxListeners(100);
964
957
  }
965
- get files() {
966
- const files = [];
967
- this.#cache.forEach((item) => {
968
- files.push(...item.flat(1));
969
- });
970
- return files;
958
+ #emitter = new events.EventEmitter();
959
+ emit(eventName, ...eventArg) {
960
+ this.#emitter.emit(eventName, ...eventArg);
971
961
  }
972
- get isExecuting() {
973
- return this.#queue?.hasJobs ?? false;
962
+ on(eventName, handler) {
963
+ this.#emitter.on(eventName, handler);
974
964
  }
975
- async add(file) {
976
- const controller = new AbortController();
977
- const resolvedFile = { id: crypto__default.default.randomUUID(), ...file };
978
- this.#cache.set(resolvedFile.path, [{ cancel: () => controller.abort(), ...resolvedFile }]);
979
- if (this.#queue) {
980
- try {
981
- await this.#queue.run(
982
- async () => {
983
- return this.#task?.(resolvedFile);
984
- },
985
- { controller }
986
- );
987
- } catch {
988
- return resolvedFile;
989
- }
990
- }
991
- return resolvedFile;
965
+ off(eventName, handler) {
966
+ this.#emitter.off(eventName, handler);
992
967
  }
993
- async addOrAppend(file) {
994
- const previousCaches = this.#cache.get(file.path);
995
- const previousCache = previousCaches ? previousCaches.at(previousCaches.length - 1) : void 0;
996
- if (previousCache) {
997
- this.#cache.delete(previousCache.path);
998
- return this.add({
999
- ...file,
1000
- source: previousCache.source && file.source ? `${previousCache.source}
1001
- ${file.source}` : "",
1002
- imports: [...previousCache.imports || [], ...file.imports || []],
1003
- exports: [...previousCache.exports || [], ...file.exports || []],
1004
- env: { ...previousCache.env || {}, ...file.env || {} }
1005
- });
1006
- }
1007
- return this.add(file);
968
+ removeAll() {
969
+ this.#emitter.removeAllListeners();
1008
970
  }
1009
- async addIndexes(root, extName = ".ts", options = {}) {
1010
- const files = await getIndexes(root, extName, options);
1011
- if (!files) {
1012
- return void 0;
1013
- }
1014
- return Promise.all(
1015
- files.map((file) => {
1016
- if (file.override) {
1017
- return this.add(file);
1018
- }
1019
- return this.addOrAppend(file);
1020
- })
1021
- );
971
+ };
972
+ var Queue = class {
973
+ #queue = [];
974
+ eventEmitter = new EventEmitter();
975
+ #workerCount = 0;
976
+ #maxParallel;
977
+ #debug = false;
978
+ constructor(maxParallel, debug = false) {
979
+ this.#maxParallel = maxParallel;
980
+ this.#debug = debug;
1022
981
  }
1023
- #append(path3, file) {
1024
- const previousFiles = this.#cache.get(path3) || [];
1025
- this.#cache.set(path3, [...previousFiles, file]);
982
+ run(job, options = { controller: new AbortController(), name: crypto2__default.default.randomUUID(), description: "" }) {
983
+ return new Promise((resolve2, reject) => {
984
+ const item = { reject, resolve: resolve2, job, name: options.name, description: options.description || options.name };
985
+ options.controller?.signal.addEventListener("abort", () => {
986
+ this.#queue = this.#queue.filter((queueItem) => queueItem.name === item.name);
987
+ reject("Aborted");
988
+ });
989
+ this.#queue.push(item);
990
+ this.#work();
991
+ });
1026
992
  }
1027
- getCacheByUUID(UUID) {
1028
- let cache;
1029
- this.#cache.forEach((files) => {
1030
- cache = files.find((item) => item.id === UUID);
993
+ runSync(job, options = { controller: new AbortController(), name: crypto2__default.default.randomUUID(), description: "" }) {
994
+ new Promise((resolve2, reject) => {
995
+ const item = { reject, resolve: resolve2, job, name: options.name, description: options.description || options.name };
996
+ options.controller?.signal.addEventListener("abort", () => {
997
+ this.#queue = this.#queue.filter((queueItem) => queueItem.name === item.name);
998
+ });
999
+ this.#queue.push(item);
1000
+ this.#work();
1031
1001
  });
1032
- return cache;
1033
1002
  }
1034
- get(path3) {
1035
- return this.#cache.get(path3);
1003
+ get hasJobs() {
1004
+ return this.#workerCount > 0 || this.#queue.length > 0;
1036
1005
  }
1037
- remove(path3) {
1038
- const cacheItem = this.get(path3);
1039
- if (!cacheItem) {
1040
- return;
1041
- }
1042
- this.#cache.delete(path3);
1006
+ get count() {
1007
+ return this.#workerCount;
1043
1008
  }
1044
- async write(...params) {
1045
- if (this.#queue) {
1046
- return this.#queue.run(async () => {
1047
- return write(...params);
1048
- });
1009
+ #work() {
1010
+ if (this.#workerCount >= this.#maxParallel) {
1011
+ return;
1049
1012
  }
1050
- return write(...params);
1051
- }
1052
- async read(...params) {
1053
- if (this.#queue) {
1054
- return this.#queue.run(async () => {
1055
- return read(...params);
1013
+ this.#workerCount++;
1014
+ let entry;
1015
+ while (entry = this.#queue.shift()) {
1016
+ const { reject, resolve: resolve2, job, name, description } = entry;
1017
+ if (this.#debug) {
1018
+ perf_hooks.performance.mark(name + "_start");
1019
+ }
1020
+ job().then((result) => {
1021
+ this.eventEmitter.emit("jobDone", result);
1022
+ resolve2(result);
1023
+ if (this.#debug) {
1024
+ perf_hooks.performance.mark(name + "_stop");
1025
+ perf_hooks.performance.measure(description, name + "_start", name + "_stop");
1026
+ }
1027
+ }).catch((err) => {
1028
+ this.eventEmitter.emit("jobFailed", err);
1029
+ reject(err);
1056
1030
  });
1057
1031
  }
1058
- return read(...params);
1032
+ this.#workerCount--;
1059
1033
  }
1060
1034
  };
1061
1035
 
1062
- // src/managers/pluginManager/ParallelPluginError.ts
1036
+ // src/utils/uniqueName.ts
1037
+ function setUniqueName(originalName, data) {
1038
+ let used = data[originalName] || 0;
1039
+ if (used) {
1040
+ data[originalName] = ++used;
1041
+ return originalName;
1042
+ }
1043
+ data[originalName] = 1;
1044
+ return originalName;
1045
+ }
1046
+
1047
+ // src/errors.ts
1048
+ var PluginError = class extends Error {
1049
+ pluginManager;
1050
+ cause;
1051
+ constructor(message, options) {
1052
+ super(message, { cause: options.cause });
1053
+ this.name = "PluginError";
1054
+ this.cause = options.cause;
1055
+ this.pluginManager = options.pluginManager;
1056
+ }
1057
+ };
1063
1058
  var ParallelPluginError = class extends Error {
1064
1059
  errors = [];
1065
1060
  pluginManager;
@@ -1084,30 +1079,55 @@ var ParallelPluginError = class extends Error {
1084
1079
  })?.cause;
1085
1080
  }
1086
1081
  };
1087
-
1088
- // src/managers/pluginManager/PluginError.ts
1089
- var PluginError = class extends Error {
1090
- pluginManager;
1091
- cause;
1082
+ var SummaryError = class extends Error {
1083
+ summary;
1092
1084
  constructor(message, options) {
1093
1085
  super(message, { cause: options.cause });
1094
- this.name = "PluginError";
1095
- this.cause = options.cause;
1096
- this.pluginManager = options.pluginManager;
1086
+ this.name = "SummaryError";
1087
+ this.summary = options.summary || [];
1097
1088
  }
1098
1089
  };
1099
- function createPlugin(factory) {
1100
- return (options) => {
1101
- const plugin = factory(options);
1102
- if (Array.isArray(plugin)) {
1103
- throw new Error("Not implemented");
1104
- }
1105
- if (!plugin.transform) {
1106
- plugin.transform = function transform(code) {
1107
- return code;
1108
- };
1090
+ var Warning = class extends Error {
1091
+ constructor(message, options) {
1092
+ super(message, { cause: options?.cause });
1093
+ this.name = "Warning";
1094
+ }
1095
+ };
1096
+ var ValidationPluginError = class extends Error {
1097
+ };
1098
+
1099
+ // src/utils/cache.ts
1100
+ function createPluginCache(Store = /* @__PURE__ */ Object.create(null)) {
1101
+ return {
1102
+ set(id, value) {
1103
+ Store[id] = [0, value];
1104
+ },
1105
+ get(id) {
1106
+ const item = Store[id];
1107
+ if (!item) {
1108
+ return null;
1109
+ }
1110
+ item[0] = 0;
1111
+ return item[1];
1112
+ },
1113
+ has(id) {
1114
+ const item = Store[id];
1115
+ if (!item) {
1116
+ return false;
1117
+ }
1118
+ item[0] = 0;
1119
+ return true;
1120
+ },
1121
+ delete(id) {
1122
+ return delete Store[id];
1109
1123
  }
1110
- return plugin;
1124
+ };
1125
+ }
1126
+
1127
+ // src/plugin.ts
1128
+ function createPlugin(factory2) {
1129
+ return (options) => {
1130
+ return factory2(options);
1111
1131
  };
1112
1132
  }
1113
1133
  var pluginName = "core";
@@ -1116,6 +1136,8 @@ var definePlugin = createPlugin((options) => {
1116
1136
  return {
1117
1137
  name: pluginName,
1118
1138
  options,
1139
+ key: ["controller", "core"],
1140
+ kind: "controller",
1119
1141
  api() {
1120
1142
  return {
1121
1143
  get config() {
@@ -1124,18 +1146,18 @@ var definePlugin = createPlugin((options) => {
1124
1146
  get plugins() {
1125
1147
  return options.getPlugins();
1126
1148
  },
1149
+ get plugin() {
1150
+ return options.plugin;
1151
+ },
1127
1152
  logger,
1128
1153
  fileManager,
1129
1154
  pluginManager,
1130
1155
  async addFile(...files) {
1131
- return Promise.all(
1132
- files.map((file) => {
1133
- if (file.override) {
1134
- return fileManager.add(file);
1135
- }
1136
- return fileManager.addOrAppend(file);
1137
- })
1138
- );
1156
+ const resolvedFiles = await fileManager.add(...files);
1157
+ if (!Array.isArray(resolvedFiles)) {
1158
+ return [resolvedFiles];
1159
+ }
1160
+ return resolvedFiles;
1139
1161
  },
1140
1162
  resolvePath,
1141
1163
  resolveName,
@@ -1143,63 +1165,58 @@ var definePlugin = createPlugin((options) => {
1143
1165
  };
1144
1166
  },
1145
1167
  resolvePath(baseName) {
1146
- const root = path2__default.default.resolve(this.config.root, this.config.output.path);
1147
- return path2__default.default.resolve(root, baseName);
1168
+ const root = path4__default.default.resolve(this.config.root, this.config.output.path);
1169
+ return path4__default.default.resolve(root, baseName);
1148
1170
  },
1149
1171
  resolveName(name) {
1150
1172
  return name;
1151
1173
  }
1152
1174
  };
1153
1175
  });
1154
- var EventEmitter = class {
1155
- constructor() {
1156
- this.#emitter.setMaxListeners(100);
1157
- }
1158
- #emitter = new events.EventEmitter();
1159
- emit(eventName, ...eventArg) {
1160
- this.#emitter.emit(eventName, ...eventArg);
1161
- }
1162
- on(eventName, handler) {
1163
- this.#emitter.on(eventName, handler);
1164
- }
1165
- off(eventName, handler) {
1166
- this.#emitter.off(eventName, handler);
1176
+
1177
+ // src/utils/executeStrategies.ts
1178
+ function hookSeq(promises) {
1179
+ return promises.reduce(
1180
+ (promise, func) => {
1181
+ if (!func || typeof func !== "function") {
1182
+ throw new Error("HookSeq needs a function that returns a promise `() => Promise<unknown>`");
1183
+ }
1184
+ return promise.then((result) => {
1185
+ const calledFunc = func();
1186
+ if (calledFunc) {
1187
+ return calledFunc.then(Array.prototype.concat.bind(result));
1188
+ }
1189
+ });
1190
+ },
1191
+ Promise.resolve([])
1192
+ );
1193
+ }
1194
+
1195
+ // src/PromiseManager.ts
1196
+ var PromiseManager = class {
1197
+ #options = {};
1198
+ constructor(options = {}) {
1199
+ this.#options = options;
1200
+ return this;
1167
1201
  }
1168
- removeAll() {
1169
- this.#emitter.removeAllListeners();
1202
+ run(strategy, promises) {
1203
+ if (strategy === "seq") {
1204
+ return hookSeq(promises);
1205
+ }
1206
+ throw new Error(`${strategy} not implemented`);
1170
1207
  }
1171
1208
  };
1172
-
1173
- // src/managers/pluginManager/pluginParser.ts
1174
- var usedPluginNames = {};
1175
- function pluginParser(plugin, context) {
1176
- const key = [plugin.kind, plugin.name, getUniqueName(plugin.name, usedPluginNames).split(plugin.name).at(1)];
1177
- if (plugin.api && typeof plugin.api === "function") {
1178
- const api = plugin.api.call(context);
1179
- return {
1180
- ...plugin,
1181
- key,
1182
- api
1183
- };
1184
- }
1185
- return {
1186
- ...plugin,
1187
- key
1188
- };
1209
+ function isPromise(result) {
1210
+ return !!result && typeof result?.then === "function";
1211
+ }
1212
+ function isPromiseFulfilledResult(result) {
1213
+ return result.status === "fulfilled";
1214
+ }
1215
+ function isPromiseRejectedResult(result) {
1216
+ return result.status === "rejected";
1189
1217
  }
1190
1218
 
1191
- // src/managers/pluginManager/PluginManager.ts
1192
- var hookNames = {
1193
- validate: 1,
1194
- buildStart: 1,
1195
- resolvePath: 1,
1196
- resolveName: 1,
1197
- load: 1,
1198
- transform: 1,
1199
- writeFile: 1,
1200
- buildEnd: 1
1201
- };
1202
- var hooks = Object.keys(hookNames);
1219
+ // src/PluginManager.ts
1203
1220
  var PluginManager = class {
1204
1221
  plugins;
1205
1222
  fileManager;
@@ -1208,10 +1225,14 @@ var PluginManager = class {
1208
1225
  executed = [];
1209
1226
  logger;
1210
1227
  #core;
1228
+ #usedPluginNames = {};
1229
+ #promiseManager;
1211
1230
  constructor(config, options) {
1212
1231
  this.logger = options.logger;
1213
- this.queue = new Queue(100, options.debug);
1214
- this.fileManager = new FileManager({ task: options.task, queue: this.queue });
1232
+ this.queue = new Queue(100, this.logger.logLevel === LogLevel.debug);
1233
+ this.fileManager = new FileManager({ task: options.task, queue: this.queue, timeout: options.writeTimeout });
1234
+ this.#promiseManager = new PromiseManager();
1235
+ const plugins = config.plugins || [];
1215
1236
  const core = definePlugin({
1216
1237
  config,
1217
1238
  logger: this.logger,
@@ -1219,23 +1240,29 @@ var PluginManager = class {
1219
1240
  fileManager: this.fileManager,
1220
1241
  resolvePath: this.resolvePath.bind(this),
1221
1242
  resolveName: this.resolveName.bind(this),
1222
- getPlugins: this.#getSortedPlugins.bind(this),
1223
- plugin: void 0
1243
+ getPlugins: this.#getSortedPlugins.bind(this)
1244
+ });
1245
+ this.#core = this.#parse(core, this, core.api.call(null));
1246
+ this.plugins = [this.#core, ...plugins].map((plugin) => {
1247
+ return this.#parse(plugin, this, this.#core.api);
1224
1248
  });
1225
- this.#core = pluginParser(core, core.api.call(null));
1226
- this.plugins = [this.#core, ...config.plugins || []].reduce((prev, plugin) => {
1227
- const convertedApi = pluginParser(plugin, this.#core?.api);
1228
- return [...prev, convertedApi];
1229
- }, []);
1230
1249
  return this;
1231
1250
  }
1232
1251
  resolvePath = (params) => {
1233
- if (params.pluginName) {
1234
- return this.hookForPluginSync({
1235
- pluginName: params.pluginName,
1252
+ if (params.pluginKey) {
1253
+ const paths = this.hookForPluginSync({
1254
+ pluginKey: params.pluginKey,
1236
1255
  hookName: "resolvePath",
1237
1256
  parameters: [params.baseName, params.directory, params.options]
1238
1257
  });
1258
+ if (paths && paths?.length > 1) {
1259
+ throw new Error(
1260
+ `Cannot return a path where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough
1261
+
1262
+ Paths: ${JSON.stringify(paths, void 0, 2)}`
1263
+ );
1264
+ }
1265
+ return paths?.at(0);
1239
1266
  }
1240
1267
  return this.hookFirstSync({
1241
1268
  hookName: "resolvePath",
@@ -1243,13 +1270,20 @@ var PluginManager = class {
1243
1270
  }).result;
1244
1271
  };
1245
1272
  resolveName = (params) => {
1246
- if (params.pluginName) {
1247
- const name2 = this.hookForPluginSync({
1248
- pluginName: params.pluginName,
1273
+ if (params.pluginKey) {
1274
+ const names = this.hookForPluginSync({
1275
+ pluginKey: params.pluginKey,
1249
1276
  hookName: "resolveName",
1250
1277
  parameters: [params.name, params.type]
1251
1278
  });
1252
- return transformReservedWord(name2 || params.name);
1279
+ if (names && names?.length > 1) {
1280
+ throw new Error(
1281
+ `Cannot return a name where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough
1282
+
1283
+ Names: ${JSON.stringify(names, void 0, 2)}`
1284
+ );
1285
+ }
1286
+ return transformReservedWord(names?.at(0) || params.name);
1253
1287
  }
1254
1288
  const name = this.hookFirstSync({
1255
1289
  hookName: "resolveName",
@@ -1264,30 +1298,35 @@ var PluginManager = class {
1264
1298
  * Run only hook for a specific plugin name
1265
1299
  */
1266
1300
  hookForPlugin({
1267
- pluginName: pluginName2,
1301
+ pluginKey,
1268
1302
  hookName,
1269
1303
  parameters
1270
1304
  }) {
1271
- const plugin = this.getPlugin(hookName, pluginName2);
1272
- return this.#execute({
1273
- strategy: "hookFirst",
1274
- hookName,
1275
- parameters,
1276
- plugin
1277
- });
1305
+ const plugins = this.getPluginsByKey(hookName, pluginKey);
1306
+ const promises = plugins.map((plugin) => {
1307
+ return this.#execute({
1308
+ strategy: "hookFirst",
1309
+ hookName,
1310
+ parameters,
1311
+ plugin
1312
+ });
1313
+ }).filter(Boolean);
1314
+ return Promise.all(promises);
1278
1315
  }
1279
1316
  hookForPluginSync({
1280
- pluginName: pluginName2,
1317
+ pluginKey,
1281
1318
  hookName,
1282
1319
  parameters
1283
1320
  }) {
1284
- const plugin = this.getPlugin(hookName, pluginName2);
1285
- return this.#executeSync({
1286
- strategy: "hookFirst",
1287
- hookName,
1288
- parameters,
1289
- plugin
1290
- });
1321
+ const plugins = this.getPluginsByKey(hookName, pluginKey);
1322
+ return plugins.map((plugin) => {
1323
+ return this.#executeSync({
1324
+ strategy: "hookFirst",
1325
+ hookName,
1326
+ parameters,
1327
+ plugin
1328
+ });
1329
+ }).filter(Boolean);
1291
1330
  }
1292
1331
  /**
1293
1332
  * Chains, first non-null result stops and returns
@@ -1403,37 +1442,58 @@ var PluginManager = class {
1403
1442
  * Chains plugins
1404
1443
  */
1405
1444
  hookSeq({ hookName, parameters }) {
1406
- let promise = Promise.resolve();
1407
- for (const plugin of this.#getSortedPlugins()) {
1408
- promise = promise.then(() => {
1409
- this.#execute({
1410
- strategy: "hookSeq",
1411
- hookName,
1412
- parameters,
1413
- plugin
1414
- });
1445
+ const promises = this.#getSortedPlugins().map((plugin) => {
1446
+ return () => this.#execute({
1447
+ strategy: "hookSeq",
1448
+ hookName,
1449
+ parameters,
1450
+ plugin
1415
1451
  });
1416
- }
1417
- return promise.then(noReturn);
1452
+ });
1453
+ return this.#promiseManager.run("seq", promises);
1418
1454
  }
1419
1455
  #getSortedPlugins(hookName) {
1420
1456
  const plugins = [...this.plugins].filter((plugin) => plugin.name !== "core");
1421
1457
  if (hookName) {
1458
+ if (this.logger.logLevel === "info") {
1459
+ const containsHookName = plugins.some((item) => item[hookName]);
1460
+ if (!containsHookName) {
1461
+ this.logger.warn(`No hook ${hookName} found`);
1462
+ }
1463
+ }
1422
1464
  return plugins.filter((item) => item[hookName]);
1423
1465
  }
1424
1466
  return plugins;
1425
1467
  }
1426
- getPlugin(hookName, pluginName2) {
1468
+ getPluginsByKey(hookName, pluginKey) {
1427
1469
  const plugins = [...this.plugins];
1428
- const pluginByPluginName = plugins.find((item) => item.name === pluginName2 && item[hookName]);
1429
- if (!pluginByPluginName) {
1430
- return this.#core;
1470
+ const [searchKind, searchPluginName, searchIdentifier] = pluginKey;
1471
+ const pluginByPluginName = plugins.filter((plugin) => plugin[hookName]).filter((item) => {
1472
+ const [kind, name, identifier] = item.key;
1473
+ const identifierCheck = identifier?.toString() === searchIdentifier?.toString();
1474
+ const kindCheck = kind === searchKind;
1475
+ const nameCheck = name === searchPluginName;
1476
+ if (searchIdentifier) {
1477
+ return identifierCheck && kindCheck && nameCheck;
1478
+ }
1479
+ return kindCheck && nameCheck;
1480
+ });
1481
+ if (!pluginByPluginName?.length) {
1482
+ const corePlugin = plugins.find((plugin) => plugin.name === "core" && plugin[hookName]);
1483
+ if (this.logger.logLevel === "info") {
1484
+ if (corePlugin) {
1485
+ this.logger.warn(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`);
1486
+ } else {
1487
+ this.logger.warn(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, no fallback found in the '@kubb/core' plugin`);
1488
+ }
1489
+ }
1490
+ return corePlugin ? [corePlugin] : [];
1431
1491
  }
1432
1492
  return pluginByPluginName;
1433
1493
  }
1434
1494
  #addExecutedToCallStack(executer) {
1435
1495
  if (executer) {
1436
- this.eventEmitter.emit("execute", executer);
1496
+ this.eventEmitter.emit("executed", executer);
1437
1497
  this.executed.push(executer);
1438
1498
  }
1439
1499
  }
@@ -1503,7 +1563,7 @@ var PluginManager = class {
1503
1563
  this.eventEmitter.emit("execute", { strategy, hookName, parameters, plugin });
1504
1564
  try {
1505
1565
  if (typeof hook === "function") {
1506
- const fn = hook.apply(this.#core.api, parameters);
1566
+ const fn = hook.apply({ ...this.#core.api, plugin }, parameters);
1507
1567
  output = fn;
1508
1568
  return fn;
1509
1569
  }
@@ -1529,34 +1589,50 @@ var PluginManager = class {
1529
1589
  this.eventEmitter.emit("error", pluginError);
1530
1590
  throw pluginError;
1531
1591
  }
1532
- };
1533
- function noReturn() {
1534
- }
1535
-
1536
- // src/managers/pluginManager/validate.ts
1537
- var ValidationPluginError = class extends Error {
1538
- };
1539
- function getDependedPlugins(plugins, dependedPluginNames) {
1540
- let pluginNames = [];
1541
- if (typeof dependedPluginNames === "string") {
1542
- pluginNames = [dependedPluginNames];
1543
- } else {
1544
- pluginNames = dependedPluginNames;
1545
- }
1546
- return pluginNames.map((pluginName2) => {
1547
- const plugin = plugins.find((plugin2) => plugin2.name === pluginName2);
1548
- if (!plugin) {
1549
- throw new ValidationPluginError(`This plugin depends on the ${pluginName2} plugin.`);
1550
- }
1551
- return plugin;
1552
- });
1553
- }
1554
-
1555
- // src/types.ts
1556
- var LogLevel = {
1557
- silent: "silent",
1558
- info: "info",
1559
- debug: "debug"
1592
+ #parse(plugin, pluginManager, context) {
1593
+ const usedPluginNames = pluginManager.#usedPluginNames;
1594
+ setUniqueName(plugin.name, usedPluginNames);
1595
+ const key = plugin.key || [plugin.kind, plugin.name, usedPluginNames[plugin.name]].filter(Boolean);
1596
+ if (plugin.name !== "core" && usedPluginNames[plugin.name] >= 2) {
1597
+ pluginManager.logger.warn("Using multiple of the same plugin is an experimental feature");
1598
+ }
1599
+ if (!plugin.transform) {
1600
+ plugin.transform = function transform(code) {
1601
+ return code;
1602
+ };
1603
+ }
1604
+ if (plugin.api && typeof plugin.api === "function") {
1605
+ const api = plugin.api.call(context);
1606
+ return {
1607
+ ...plugin,
1608
+ key,
1609
+ api
1610
+ };
1611
+ }
1612
+ return {
1613
+ ...plugin,
1614
+ key
1615
+ };
1616
+ }
1617
+ static getDependedPlugins(plugins, dependedPluginNames) {
1618
+ let pluginNames = [];
1619
+ if (typeof dependedPluginNames === "string") {
1620
+ pluginNames = [dependedPluginNames];
1621
+ } else {
1622
+ pluginNames = dependedPluginNames;
1623
+ }
1624
+ return pluginNames.map((pluginName2) => {
1625
+ const plugin = plugins.find((plugin2) => plugin2.name === pluginName2);
1626
+ if (!plugin) {
1627
+ throw new ValidationPluginError(`This plugin depends on the ${pluginName2} plugin.`);
1628
+ }
1629
+ return plugin;
1630
+ });
1631
+ }
1632
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1633
+ static get hooks() {
1634
+ return ["validate", "buildStart", "resolvePath", "resolveName", "load", "transform", "writeFile", "buildEnd"];
1635
+ }
1560
1636
  };
1561
1637
 
1562
1638
  // src/build.ts
@@ -1564,13 +1640,13 @@ async function transformReducer(_previousCode, result, _plugin) {
1564
1640
  return result;
1565
1641
  }
1566
1642
  async function build(options) {
1567
- const { config, logLevel, logger = createLogger() } = options;
1643
+ const { config, logger = createLogger({ logLevel: LogLevel.silent }) } = options;
1568
1644
  try {
1569
- if ("path" in config.input && !new URLPath(config.input.path).isURL) {
1645
+ if (isInputPath(config) && !new URLPath(config.input.path).isURL) {
1570
1646
  await read(config.input.path);
1571
1647
  }
1572
1648
  } catch (e) {
1573
- if ("path" in config.input) {
1649
+ if (isInputPath(config)) {
1574
1650
  throw new Error(
1575
1651
  "Cannot read file/URL defined in `input.path` or set with `kubb generate PATH` in the CLI of your Kubb config " + pc3__default.default.dim(config.input.path),
1576
1652
  {
@@ -1583,11 +1659,11 @@ async function build(options) {
1583
1659
  await clean(config.output.path);
1584
1660
  }
1585
1661
  const queueTask = async (file) => {
1586
- const { path: path3 } = file;
1587
- let code = createFileSource(file);
1662
+ const { path: path5 } = file;
1663
+ let code = FileManager.getSource(file);
1588
1664
  const { result: loadedResult } = await pluginManager.hookFirst({
1589
1665
  hookName: "load",
1590
- parameters: [path3]
1666
+ parameters: [path5]
1591
1667
  });
1592
1668
  if (loadedResult && isPromise(loadedResult)) {
1593
1669
  code = await loadedResult;
@@ -1598,28 +1674,53 @@ async function build(options) {
1598
1674
  if (code) {
1599
1675
  const transformedCode = await pluginManager.hookReduceArg0({
1600
1676
  hookName: "transform",
1601
- parameters: [code, path3],
1677
+ parameters: [code, path5],
1602
1678
  reduce: transformReducer
1603
1679
  });
1604
1680
  if (config.output.write || config.output.write === void 0) {
1605
- await pluginManager.hookParallel({
1681
+ if (file.meta?.pluginKey) {
1682
+ return pluginManager.hookForPlugin({
1683
+ pluginKey: file.meta?.pluginKey,
1684
+ hookName: "writeFile",
1685
+ parameters: [transformedCode, path5]
1686
+ });
1687
+ }
1688
+ return pluginManager.hookFirst({
1606
1689
  hookName: "writeFile",
1607
- parameters: [transformedCode, path3]
1690
+ parameters: [transformedCode, path5]
1608
1691
  });
1609
1692
  }
1610
1693
  }
1611
1694
  };
1612
- const pluginManager = new PluginManager(config, { debug: logLevel === LogLevel.debug, logger, task: queueTask });
1695
+ const pluginManager = new PluginManager(config, { logger, task: queueTask, writeTimeout: 0 });
1613
1696
  const { plugins, fileManager } = pluginManager;
1614
1697
  pluginManager.on("execute", (executer) => {
1698
+ const { hookName, parameters, plugin } = executer;
1699
+ if (hookName === "writeFile" && logger.spinner) {
1700
+ const [code] = parameters;
1701
+ if (logger.logLevel === LogLevel.info) {
1702
+ logger.spinner.start(`\u{1F4BE} Writing`);
1703
+ }
1704
+ if (logger.logLevel === "debug") {
1705
+ logger.info(`PluginKey ${pc3__default.default.dim(JSON.stringify(plugin.key))}
1706
+ with source
1707
+
1708
+ ${code}`);
1709
+ }
1710
+ }
1711
+ });
1712
+ pluginManager.on("executed", (executer) => {
1615
1713
  const { hookName, plugin, output, parameters } = executer;
1616
1714
  const messsage = `${randomPicoColour(plugin.name)} Executing ${hookName}`;
1617
- if (logLevel === LogLevel.info) {
1618
- if (logger.spinner) {
1715
+ if (logger.logLevel === LogLevel.info && logger.spinner) {
1716
+ if (hookName === "writeFile") {
1717
+ const [_code, path5] = parameters;
1718
+ logger.spinner.suffixText = pc3__default.default.dim(path5);
1719
+ } else {
1619
1720
  logger.spinner.suffixText = messsage;
1620
1721
  }
1621
1722
  }
1622
- if (logLevel === LogLevel.debug) {
1723
+ if (logger.logLevel === LogLevel.debug) {
1623
1724
  logger.info(messsage);
1624
1725
  const logs = [
1625
1726
  parameters && `${pc3__default.default.bgWhite(`Parameters`)} ${randomPicoColour(plugin.name)} ${hookName}`,
@@ -1639,15 +1740,14 @@ async function build(options) {
1639
1740
  parameters: [config]
1640
1741
  });
1641
1742
  await pluginManager.hookParallel({ hookName: "buildEnd" });
1642
- return { files: fileManager.files.map((file) => ({ ...file, source: createFileSource(file) })), pluginManager };
1643
- }
1644
-
1645
- // src/config.ts
1646
- function defineConfig(options) {
1647
- return options;
1743
+ if (!fileManager.isExecuting && logger.spinner) {
1744
+ logger.spinner.suffixText = "";
1745
+ logger.spinner.succeed(`\u{1F4BE} Writing completed`);
1746
+ }
1747
+ return { files: fileManager.files.map((file) => ({ ...file, source: FileManager.getSource(file) })), pluginManager };
1648
1748
  }
1649
1749
 
1650
- // src/generators/Generator.ts
1750
+ // src/Generator.ts
1651
1751
  var Generator = class {
1652
1752
  #options = {};
1653
1753
  #context = {};
@@ -1671,10 +1771,6 @@ var Generator = class {
1671
1771
  }
1672
1772
  };
1673
1773
 
1674
- // src/generators/SchemaGenerator.ts
1675
- var SchemaGenerator = class extends Generator {
1676
- };
1677
-
1678
1774
  // ../../node_modules/.pnpm/yocto-queue@1.0.0/node_modules/yocto-queue/index.js
1679
1775
  var Node = class {
1680
1776
  value;
@@ -1740,18 +1836,18 @@ function pLimit(concurrency) {
1740
1836
  queue.dequeue()();
1741
1837
  }
1742
1838
  };
1743
- const run = async (fn, resolve, args) => {
1839
+ const run = async (fn, resolve2, args) => {
1744
1840
  activeCount++;
1745
1841
  const result = (async () => fn(...args))();
1746
- resolve(result);
1842
+ resolve2(result);
1747
1843
  try {
1748
1844
  await result;
1749
1845
  } catch {
1750
1846
  }
1751
1847
  next();
1752
1848
  };
1753
- const enqueue = (fn, resolve, args) => {
1754
- queue.enqueue(run.bind(void 0, fn, resolve, args));
1849
+ const enqueue = (fn, resolve2, args) => {
1850
+ queue.enqueue(run.bind(void 0, fn, resolve2, args));
1755
1851
  (async () => {
1756
1852
  await Promise.resolve();
1757
1853
  if (activeCount < concurrency && queue.size > 0) {
@@ -1759,8 +1855,8 @@ function pLimit(concurrency) {
1759
1855
  }
1760
1856
  })();
1761
1857
  };
1762
- const generator = (fn, ...args) => new Promise((resolve) => {
1763
- enqueue(fn, resolve, args);
1858
+ const generator = (fn, ...args) => new Promise((resolve2) => {
1859
+ enqueue(fn, resolve2, args);
1764
1860
  });
1765
1861
  Object.defineProperties(generator, {
1766
1862
  activeCount: {
@@ -1835,7 +1931,7 @@ async function locatePath(paths, {
1835
1931
  const statFunction = allowSymlinks ? fs3.promises.stat : fs3.promises.lstat;
1836
1932
  return pLocate(paths, async (path_) => {
1837
1933
  try {
1838
- const stat = await statFunction(path2__default.default.resolve(cwd, path_));
1934
+ const stat = await statFunction(path4__default.default.resolve(cwd, path_));
1839
1935
  return matchType(type, stat);
1840
1936
  } catch {
1841
1937
  return false;
@@ -1852,7 +1948,7 @@ function locatePathSync(paths, {
1852
1948
  const statFunction = allowSymlinks ? fs3__default.default.statSync : fs3__default.default.lstatSync;
1853
1949
  for (const path_ of paths) {
1854
1950
  try {
1855
- const stat = statFunction(path2__default.default.resolve(cwd, path_), {
1951
+ const stat = statFunction(path4__default.default.resolve(cwd, path_), {
1856
1952
  throwIfNoEntry: false
1857
1953
  });
1858
1954
  if (!stat) {
@@ -1870,9 +1966,9 @@ function locatePathSync(paths, {
1870
1966
  var toPath2 = (urlOrPath) => urlOrPath instanceof URL ? url.fileURLToPath(urlOrPath) : urlOrPath;
1871
1967
  var findUpStop = Symbol("findUpStop");
1872
1968
  async function findUpMultiple(name, options = {}) {
1873
- let directory = path2__default.default.resolve(toPath2(options.cwd) || "");
1874
- const { root } = path2__default.default.parse(directory);
1875
- const stopAt = path2__default.default.resolve(directory, options.stopAt || root);
1969
+ let directory = path4__default.default.resolve(toPath2(options.cwd) || "");
1970
+ const { root } = path4__default.default.parse(directory);
1971
+ const stopAt = path4__default.default.resolve(directory, options.stopAt || root);
1876
1972
  const limit = options.limit || Number.POSITIVE_INFINITY;
1877
1973
  const paths = [name].flat();
1878
1974
  const runMatcher = async (locateOptions) => {
@@ -1892,18 +1988,18 @@ async function findUpMultiple(name, options = {}) {
1892
1988
  break;
1893
1989
  }
1894
1990
  if (foundPath) {
1895
- matches.push(path2__default.default.resolve(directory, foundPath));
1991
+ matches.push(path4__default.default.resolve(directory, foundPath));
1896
1992
  }
1897
1993
  if (directory === stopAt || matches.length >= limit) {
1898
1994
  break;
1899
1995
  }
1900
- directory = path2__default.default.dirname(directory);
1996
+ directory = path4__default.default.dirname(directory);
1901
1997
  }
1902
1998
  return matches;
1903
1999
  }
1904
2000
  function findUpMultipleSync(name, options = {}) {
1905
- let directory = path2__default.default.resolve(toPath2(options.cwd) || "");
1906
- const { root } = path2__default.default.parse(directory);
2001
+ let directory = path4__default.default.resolve(toPath2(options.cwd) || "");
2002
+ const { root } = path4__default.default.parse(directory);
1907
2003
  const stopAt = options.stopAt || root;
1908
2004
  const limit = options.limit || Number.POSITIVE_INFINITY;
1909
2005
  const paths = [name].flat();
@@ -1924,12 +2020,12 @@ function findUpMultipleSync(name, options = {}) {
1924
2020
  break;
1925
2021
  }
1926
2022
  if (foundPath) {
1927
- matches.push(path2__default.default.resolve(directory, foundPath));
2023
+ matches.push(path4__default.default.resolve(directory, foundPath));
1928
2024
  }
1929
2025
  if (directory === stopAt || matches.length >= limit) {
1930
2026
  break;
1931
2027
  }
1932
- directory = path2__default.default.dirname(directory);
2028
+ directory = path4__default.default.dirname(directory);
1933
2029
  }
1934
2030
  return matches;
1935
2031
  }
@@ -1963,17 +2059,17 @@ var PackageManager = class _PackageManager {
1963
2059
  }
1964
2060
  return directory;
1965
2061
  }
1966
- getLocation(path3) {
1967
- let location = path3;
2062
+ getLocation(path5) {
2063
+ let location = path5;
1968
2064
  if (this.#cwd) {
1969
2065
  const require2 = mod__default.default.createRequire(this.normalizeDirectory(this.#cwd));
1970
- location = require2.resolve(path3);
2066
+ location = require2.resolve(path5);
1971
2067
  }
1972
2068
  return location;
1973
2069
  }
1974
- async import(path3) {
2070
+ async import(path5) {
1975
2071
  try {
1976
- let location = this.getLocation(path3);
2072
+ let location = this.getLocation(path5);
1977
2073
  if (os__default.default.platform() == "win32") {
1978
2074
  location = url.pathToFileURL(location).href;
1979
2075
  }
@@ -2049,67 +2145,33 @@ var PackageManager = class _PackageManager {
2049
2145
  }
2050
2146
  };
2051
2147
 
2148
+ // src/SchemaGenerator.ts
2149
+ var SchemaGenerator = class extends Generator {
2150
+ };
2151
+
2052
2152
  // src/index.ts
2053
2153
  var src_default = build;
2054
2154
 
2055
- Object.defineProperty(exports, 'pc', {
2056
- enumerable: true,
2057
- get: function () { return pc3__default.default; }
2058
- });
2059
2155
  exports.FileManager = FileManager;
2060
- exports.FunctionParams = FunctionParams;
2061
2156
  exports.Generator = Generator;
2062
- exports.LogLevel = LogLevel;
2063
2157
  exports.PackageManager = PackageManager;
2064
2158
  exports.ParallelPluginError = ParallelPluginError;
2065
2159
  exports.PluginError = PluginError;
2066
2160
  exports.PluginManager = PluginManager;
2067
- exports.Queue = Queue;
2161
+ exports.PromiseManager = PromiseManager;
2068
2162
  exports.SchemaGenerator = SchemaGenerator;
2069
2163
  exports.SummaryError = SummaryError;
2070
- exports.TreeNode = TreeNode;
2071
- exports.URLPath = URLPath;
2072
2164
  exports.ValidationPluginError = ValidationPluginError;
2073
2165
  exports.Warning = Warning;
2074
2166
  exports.build = build;
2075
- exports.clean = clean;
2076
- exports.combineCodes = combineCodes;
2077
- exports.combineExports = combineExports;
2078
- exports.combineFiles = combineFiles;
2079
- exports.combineImports = combineImports;
2080
- exports.createFileSource = createFileSource;
2081
- exports.createJSDocBlockText = createJSDocBlockText;
2082
- exports.createLogger = createLogger;
2083
2167
  exports.createPlugin = createPlugin;
2084
- exports.createPluginCache = createPluginCache;
2085
2168
  exports.default = src_default;
2086
- exports.defaultColours = defaultColours;
2087
2169
  exports.defineConfig = defineConfig;
2088
- exports.escape = escape;
2089
- exports.extensions = extensions;
2090
- exports.getDependedPlugins = getDependedPlugins;
2091
- exports.getIndexes = getIndexes;
2092
- exports.getPathMode = getPathMode;
2093
- exports.getRelativePath = getRelativePath;
2094
- exports.getUniqueName = getUniqueName;
2095
- exports.hooks = hooks;
2096
- exports.isExtensionAllowed = isExtensionAllowed;
2170
+ exports.isInputPath = isInputPath;
2097
2171
  exports.isPromise = isPromise;
2098
2172
  exports.isPromiseFulfilledResult = isPromiseFulfilledResult;
2099
2173
  exports.isPromiseRejectedResult = isPromiseRejectedResult;
2100
- exports.jsStringEscape = jsStringEscape;
2101
2174
  exports.name = pluginName;
2102
- exports.nameSorter = nameSorter;
2103
2175
  exports.pluginName = pluginName;
2104
- exports.randomColour = randomColour;
2105
- exports.randomPicoColour = randomPicoColour;
2106
- exports.read = read;
2107
- exports.readSync = readSync;
2108
- exports.renderTemplate = renderTemplate;
2109
- exports.throttle = throttle;
2110
- exports.timeout = timeout;
2111
- exports.transformReservedWord = transformReservedWord;
2112
- exports.uniqueIdFactory = uniqueIdFactory;
2113
- exports.write = write;
2114
2176
  //# sourceMappingURL=out.js.map
2115
2177
  //# sourceMappingURL=index.cjs.map