@kubb/cli 5.14.6 → 5.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/bin/kubb.js +2 -1
  2. package/dist/{Telemetry-DrnGartf.js → Telemetry-B3edcFoB.js} +12 -86
  3. package/dist/Telemetry-B3edcFoB.js.map +1 -0
  4. package/dist/{Telemetry-B5V_ufmv.cjs → Telemetry-COWGqYmh.cjs} +14 -118
  5. package/dist/Telemetry-COWGqYmh.cjs.map +1 -0
  6. package/dist/{background-CdPT1eaq.cjs → background-B24lIehn.cjs} +5 -6
  7. package/dist/{background-CdPT1eaq.cjs.map → background-B24lIehn.cjs.map} +1 -1
  8. package/dist/{background-C6XHpEo7.js → background-D-7OGjvg.js} +1 -1
  9. package/dist/{background-DlK0by5c.js → background-_dKcGjM7.js} +5 -6
  10. package/dist/{background-DlK0by5c.js.map → background-_dKcGjM7.js.map} +1 -1
  11. package/dist/banner-BdTTDFkG.js +140 -0
  12. package/dist/banner-BdTTDFkG.js.map +1 -0
  13. package/dist/banner-wJFk-L-c.cjs +163 -0
  14. package/dist/banner-wJFk-L-c.cjs.map +1 -0
  15. package/dist/config-BL3HnFhb.js +1 -0
  16. package/dist/config-BWj9jBVj.cjs +62 -0
  17. package/dist/config-BWj9jBVj.cjs.map +1 -0
  18. package/dist/{config-CNqgDSu3.js → config-CQTxXvIG.js} +6 -52
  19. package/dist/config-CQTxXvIG.js.map +1 -0
  20. package/dist/{config-BG_Nr2CZ.cjs → config-CRrmj88c.cjs} +15 -62
  21. package/dist/config-CRrmj88c.cjs.map +1 -0
  22. package/dist/config-Uk3rbZfb.js +49 -0
  23. package/dist/config-Uk3rbZfb.js.map +1 -0
  24. package/dist/configFile-C0DIXNMD.js +993 -0
  25. package/dist/configFile-C0DIXNMD.js.map +1 -0
  26. package/dist/configFile-CoEpHdXG.cjs +1028 -0
  27. package/dist/configFile-CoEpHdXG.cjs.map +1 -0
  28. package/dist/{credentials-C8tjAhTo.js → credentials-B77iJx9H.js} +1 -1
  29. package/dist/{credentials-DDaKqtJn.cjs → credentials-DEsGwcGD.cjs} +3 -4
  30. package/dist/{credentials-DDaKqtJn.cjs.map → credentials-DEsGwcGD.cjs.map} +1 -1
  31. package/dist/{credentials-CZK6zPLv.js → credentials-osgjujE_.js} +3 -4
  32. package/dist/{credentials-CZK6zPLv.js.map → credentials-osgjujE_.js.map} +1 -1
  33. package/dist/env-C3xHRMez.js +1 -0
  34. package/dist/env-eu3XyKqJ.cjs +55 -0
  35. package/dist/env-eu3XyKqJ.cjs.map +1 -0
  36. package/dist/env-rv-VgSGN.js +34 -0
  37. package/dist/env-rv-VgSGN.js.map +1 -0
  38. package/dist/{errors-Cl69p_vI.cjs → errors-BponpdjN.cjs} +3 -4
  39. package/dist/{errors-Cl69p_vI.cjs.map → errors-BponpdjN.cjs.map} +1 -1
  40. package/dist/{errors-DmC83ALX.js → errors-wzqmMpMo.js} +3 -4
  41. package/dist/{errors-DmC83ALX.js.map → errors-wzqmMpMo.js.map} +1 -1
  42. package/dist/index.cjs +37 -2719
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +0 -2
  45. package/dist/index.d.ts +0 -2
  46. package/dist/index.js +35 -2713
  47. package/dist/index.js.map +1 -1
  48. package/dist/installWithSpinner-DpnpxHq5.js +49 -0
  49. package/dist/installWithSpinner-DpnpxHq5.js.map +1 -0
  50. package/dist/installWithSpinner-ONGfIVUJ.cjs +56 -0
  51. package/dist/installWithSpinner-ONGfIVUJ.cjs.map +1 -0
  52. package/dist/{text-CL6N6yPS.js → intro-9PB8sE8z.js} +8 -52
  53. package/dist/intro-9PB8sE8z.js.map +1 -0
  54. package/dist/{text-DrsG1EDN.cjs → intro-YPaf1Imr.cjs} +12 -80
  55. package/dist/intro-YPaf1Imr.cjs.map +1 -0
  56. package/dist/isCIEnvironment-D6xtAAZ2.js +14 -0
  57. package/dist/isCIEnvironment-D6xtAAZ2.js.map +1 -0
  58. package/dist/isCIEnvironment-DiVOMI5Q.cjs +20 -0
  59. package/dist/isCIEnvironment-DiVOMI5Q.cjs.map +1 -0
  60. package/dist/mascot--q1xjKw1.js +63 -0
  61. package/dist/mascot--q1xjKw1.js.map +1 -0
  62. package/dist/mascot-JSA0j3Q_.cjs +80 -0
  63. package/dist/mascot-JSA0j3Q_.cjs.map +1 -0
  64. package/dist/mcp-CYPOFKnP.cjs +20 -0
  65. package/dist/mcp-CYPOFKnP.cjs.map +1 -0
  66. package/dist/mcp-CxeZR5vb.js +21 -0
  67. package/dist/mcp-CxeZR5vb.js.map +1 -0
  68. package/dist/package-D3Yss9Bb.js +5 -0
  69. package/dist/package-D3Yss9Bb.js.map +1 -0
  70. package/dist/package-aX0q9SZr.cjs +10 -0
  71. package/dist/package-aX0q9SZr.cjs.map +1 -0
  72. package/dist/{registry-DOGpflct.js → registry-B3eYk4LN.js} +7 -67
  73. package/dist/registry-B3eYk4LN.js.map +1 -0
  74. package/dist/{registry-BzBp6aZI.cjs → registry-YE1pFWL-.cjs} +4 -82
  75. package/dist/registry-YE1pFWL-.cjs.map +1 -0
  76. package/dist/{reporters-GzXlc4CK.cjs → reporters-2cgjvXwR.cjs} +32 -40
  77. package/dist/{reporters-GzXlc4CK.cjs.map → reporters-2cgjvXwR.cjs.map} +1 -1
  78. package/dist/{reporters-mYHIUZSx.js → reporters-BM430HdQ.js} +19 -27
  79. package/dist/{reporters-mYHIUZSx.js.map → reporters-BM430HdQ.js.map} +1 -1
  80. package/dist/{rolldown-runtime-CPE0t6oh.cjs → rolldown-runtime-C3-Zg-KD.cjs} +1 -2
  81. package/dist/{rolldown-runtime-CRm0XQPb.js → rolldown-runtime-xo6NMXYd.js} +1 -2
  82. package/dist/run-1H9TGT8v.js +77 -0
  83. package/dist/run-1H9TGT8v.js.map +1 -0
  84. package/dist/run-B4zvF9WY.cjs +233 -0
  85. package/dist/run-B4zvF9WY.cjs.map +1 -0
  86. package/dist/run-BYP_t9dR.cjs +324 -0
  87. package/dist/run-BYP_t9dR.cjs.map +1 -0
  88. package/dist/{run-C8Prej7s.cjs → run-Bb19PlwV.cjs} +44 -37
  89. package/dist/run-Bb19PlwV.cjs.map +1 -0
  90. package/dist/{run-DC_xH5H3.cjs → run-BoO7H8RA.cjs} +49 -41
  91. package/dist/run-BoO7H8RA.cjs.map +1 -0
  92. package/dist/run-BrM7-NSV.js +181 -0
  93. package/dist/run-BrM7-NSV.js.map +1 -0
  94. package/dist/{run-l8IiOR_c.js → run-C0KI-NE3.js} +9 -9
  95. package/dist/{run-l8IiOR_c.js.map → run-C0KI-NE3.js.map} +1 -1
  96. package/dist/run-CCLPt4hr.js +1 -0
  97. package/dist/run-CCsdLz3X.js +385 -0
  98. package/dist/run-CCsdLz3X.js.map +1 -0
  99. package/dist/{run-EJtgdIin.js → run-CbX6tpqB.js} +31 -23
  100. package/dist/run-CbX6tpqB.js.map +1 -0
  101. package/dist/run-CrM4jsix.cjs +80 -0
  102. package/dist/run-CrM4jsix.cjs.map +1 -0
  103. package/dist/run-CvFakE3B.cjs +185 -0
  104. package/dist/run-CvFakE3B.cjs.map +1 -0
  105. package/dist/run-D-nn9-Wq.js +319 -0
  106. package/dist/run-D-nn9-Wq.js.map +1 -0
  107. package/dist/{run-CypFtkVE.cjs → run-D5Z6nfzK.cjs} +5 -6
  108. package/dist/{run-CypFtkVE.cjs.map → run-D5Z6nfzK.cjs.map} +1 -1
  109. package/dist/{run-sjzj0ir-.cjs → run-DCqmf5W1.cjs} +10 -10
  110. package/dist/{run-sjzj0ir-.cjs.map → run-DCqmf5W1.cjs.map} +1 -1
  111. package/dist/{run-j1g5si5R.js → run-DFXhBS64.js} +5 -6
  112. package/dist/{run-j1g5si5R.js.map → run-DFXhBS64.js.map} +1 -1
  113. package/dist/run-DgGZOC_x.cjs +389 -0
  114. package/dist/run-DgGZOC_x.cjs.map +1 -0
  115. package/dist/{run-9fs2T2Je.js → run-KqdudiWQ.js} +26 -20
  116. package/dist/run-KqdudiWQ.js.map +1 -0
  117. package/dist/run-RN_31Q4u.js +228 -0
  118. package/dist/run-RN_31Q4u.js.map +1 -0
  119. package/dist/shared-C0EtrdUm.cjs +123 -0
  120. package/dist/shared-C0EtrdUm.cjs.map +1 -0
  121. package/dist/shared-Ct9stKpp.js +94 -0
  122. package/dist/shared-Ct9stKpp.js.map +1 -0
  123. package/dist/{snapshot-laSRD0z1.cjs → snapshot-D7Ytw8S0.cjs} +13 -14
  124. package/dist/{snapshot-laSRD0z1.cjs.map → snapshot-D7Ytw8S0.cjs.map} +1 -1
  125. package/dist/{snapshot-BJWnL6hE.js → snapshot-n7dJGCWv.js} +10 -11
  126. package/dist/{snapshot-BJWnL6hE.js.map → snapshot-n7dJGCWv.js.map} +1 -1
  127. package/dist/spinner-BZaln7O8.js +160 -0
  128. package/dist/spinner-BZaln7O8.js.map +1 -0
  129. package/dist/spinner-CfB0sIPy.cjs +208 -0
  130. package/dist/spinner-CfB0sIPy.cjs.map +1 -0
  131. package/dist/{status-DFEdbBPu.cjs → status-Bc0_4T41.cjs} +7 -8
  132. package/dist/{status-DFEdbBPu.cjs.map → status-Bc0_4T41.cjs.map} +1 -1
  133. package/dist/{status-BjmXLRm2.js → status-DxSkp1cH.js} +6 -7
  134. package/dist/{status-BjmXLRm2.js.map → status-DxSkp1cH.js.map} +1 -1
  135. package/dist/studio-BpYwgFb0.cjs +218 -0
  136. package/dist/studio-BpYwgFb0.cjs.map +1 -0
  137. package/dist/studio-mw6HaPkr.js +215 -0
  138. package/dist/studio-mw6HaPkr.js.map +1 -0
  139. package/dist/studioWorker.js +4 -5
  140. package/dist/{summary-DDnI70tn.js → summary-CbmQKA8l.js} +5 -6
  141. package/dist/{summary-DDnI70tn.js.map → summary-CbmQKA8l.js.map} +1 -1
  142. package/dist/{summary-1DCwzWEU.cjs → summary-Clvl5Hxs.cjs} +7 -8
  143. package/dist/{summary-1DCwzWEU.cjs.map → summary-Clvl5Hxs.cjs.map} +1 -1
  144. package/dist/table-BlRe9YTZ.cjs +15 -0
  145. package/dist/table-BlRe9YTZ.cjs.map +1 -0
  146. package/dist/table-CR7iZJGo.js +10 -0
  147. package/dist/table-CR7iZJGo.js.map +1 -0
  148. package/dist/text-BmiI4s6N.js +13 -0
  149. package/dist/text-BmiI4s6N.js.map +1 -0
  150. package/dist/text-Ep3AulAS.cjs +24 -0
  151. package/dist/text-Ep3AulAS.cjs.map +1 -0
  152. package/dist/time-3BKoci3G.cjs +82 -0
  153. package/dist/time-3BKoci3G.cjs.map +1 -0
  154. package/dist/time-C-wU7VhC.js +65 -0
  155. package/dist/time-C-wU7VhC.js.map +1 -0
  156. package/dist/utils-BdibacYq.js +244 -0
  157. package/dist/utils-BdibacYq.js.map +1 -0
  158. package/dist/utils-CO89mxRU.cjs +290 -0
  159. package/dist/utils-CO89mxRU.cjs.map +1 -0
  160. package/dist/utils-CbJ6hS_t.js +222 -0
  161. package/dist/utils-CbJ6hS_t.js.map +1 -0
  162. package/dist/utils-CcARPB45.cjs +286 -0
  163. package/dist/utils-CcARPB45.cjs.map +1 -0
  164. package/dist/validate-8ZcWXfMt.js +28 -0
  165. package/dist/validate-8ZcWXfMt.js.map +1 -0
  166. package/dist/validate-CMSeDpGT.cjs +27 -0
  167. package/dist/validate-CMSeDpGT.cjs.map +1 -0
  168. package/package.json +7 -7
  169. package/dist/Telemetry-B5V_ufmv.cjs.map +0 -1
  170. package/dist/Telemetry-DrnGartf.js.map +0 -1
  171. package/dist/config-BG_Nr2CZ.cjs.map +0 -1
  172. package/dist/config-CNqgDSu3.js.map +0 -1
  173. package/dist/config-DWDpFSn1.js +0 -1
  174. package/dist/registry-BzBp6aZI.cjs.map +0 -1
  175. package/dist/registry-DOGpflct.js.map +0 -1
  176. package/dist/run-9fs2T2Je.js.map +0 -1
  177. package/dist/run-C8Prej7s.cjs.map +0 -1
  178. package/dist/run-CXVme-aS.js +0 -1
  179. package/dist/run-DC_xH5H3.cjs.map +0 -1
  180. package/dist/run-EJtgdIin.js.map +0 -1
  181. package/dist/text-CL6N6yPS.js.map +0 -1
  182. package/dist/text-DrsG1EDN.cjs.map +0 -1
  183. package/dist/utils-C3vTpUje.cjs +0 -645
  184. package/dist/utils-C3vTpUje.cjs.map +0 -1
  185. package/dist/utils-CIc8YFtr.js +0 -536
  186. package/dist/utils-CIc8YFtr.js.map +0 -1
@@ -1,645 +0,0 @@
1
- const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
- const require_Telemetry = require("./Telemetry-B5V_ufmv.cjs");
3
- const require_text = require("./text-DrsG1EDN.cjs");
4
- let node_util = require("node:util");
5
- let node_process = require("node:process");
6
- node_process = require_rolldown_runtime.__toESM(node_process, 1);
7
- let node_fs_promises = require("node:fs/promises");
8
- let node_path = require("node:path");
9
- require("node:fs");
10
- //#region ../../internals/utils/src/fs.ts
11
- /**
12
- * Resolves to `true` when the file or directory at `path` exists.
13
- * Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.
14
- *
15
- * @example
16
- * ```ts
17
- * if (await exists('./kubb.config.ts')) {
18
- * const content = await read('./kubb.config.ts')
19
- * }
20
- * ```
21
- */
22
- async function exists(path) {
23
- if (require_Telemetry.runtime.isBun) return Bun.file(path).exists();
24
- return (0, node_fs_promises.access)(path).then(() => true, () => false);
25
- }
26
- /**
27
- * Reads the file at `path` as a UTF-8 string.
28
- * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
29
- *
30
- * @example
31
- * ```ts
32
- * const source = await read('./src/Pet.ts')
33
- * ```
34
- */
35
- async function read(path) {
36
- if (require_Telemetry.runtime.isBun) return Bun.file(path).text();
37
- return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
38
- }
39
- /**
40
- * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact
41
- * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a
42
- * reason to rewrite the file.
43
- *
44
- * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one
45
- * that normalizes what it stores. Trimming only `stored` would leave a source with leading
46
- * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison
47
- * has already dropped.
48
- */
49
- function matchesStored({ stored, source }) {
50
- return stored.trim() === source.trim();
51
- }
52
- /**
53
- * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline
54
- * the way prettier, biome, and oxfmt all do.
55
- * Skips the write when the trimmed content is empty, or when the file already holds that content.
56
- * Creates any missing parent directories automatically.
57
- * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.
58
- *
59
- * @example
60
- * ```ts
61
- * await write('./src/Pet.ts', source) // writes and returns the trimmed content plus a newline
62
- * await write('./src/Pet.ts', source) // null — file unchanged
63
- * await write('./src/Pet.ts', ' ') // null — empty content skipped
64
- * ```
65
- */
66
- async function write(path, data, options = {}) {
67
- const trimmed = data.trim();
68
- if (trimmed === "") return null;
69
- const content = `${trimmed}\n`;
70
- const resolved = (0, node_path.resolve)(path);
71
- let stored = options.stored;
72
- if (stored === void 0) {
73
- if (require_Telemetry.runtime.isBun) {
74
- const file = Bun.file(resolved);
75
- stored = await file.exists() ? await file.text() : null;
76
- } else try {
77
- stored = await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" });
78
- } catch {
79
- stored = null;
80
- }
81
- }
82
- if (matchesStored({
83
- stored: stored ?? "",
84
- source: trimmed
85
- })) return null;
86
- await writeRaw(resolved, content);
87
- if (options.sanity) {
88
- const savedData = await read(resolved);
89
- if (savedData !== content) throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`);
90
- return savedData;
91
- }
92
- return content;
93
- }
94
- /**
95
- * Writes UTF-8 content verbatim, including empty files and surrounding whitespace.
96
- * Uses Bun.write under Bun and creates missing parent directories under either runtime.
97
- *
98
- * @example
99
- * await writeRaw('./cache/output.ts', ' // keep these bytes\n\n')
100
- */
101
- async function writeRaw(path, content) {
102
- const resolved = (0, node_path.resolve)(path);
103
- if (require_Telemetry.runtime.isBun) {
104
- await Bun.write(resolved, content);
105
- return;
106
- }
107
- try {
108
- await (0, node_fs_promises.writeFile)(resolved, content, { encoding: "utf-8" });
109
- } catch (error) {
110
- if (error.code !== "ENOENT") throw error;
111
- await (0, node_fs_promises.mkdir)((0, node_path.dirname)(resolved), { recursive: true });
112
- await (0, node_fs_promises.writeFile)(resolved, content, { encoding: "utf-8" });
113
- }
114
- }
115
- /**
116
- * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved
117
- * to absolute paths first, so relative and `..`-containing inputs compare correctly.
118
- *
119
- * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that
120
- * it does not contain the project root, and before loading a path a caller supplied, check that it
121
- * did not escape the directory it is allowed to read from.
122
- *
123
- * @example
124
- * isPathInside('./src/gen', '.') // true — nested inside the root
125
- * isPathInside('.', '.') // true — the same directory counts as inside
126
- * isPathInside('.', './src/gen') // false — the root is not inside its own output
127
- * isPathInside('../other', '.') // false — escapes the root
128
- */
129
- function isPathInside(path, parent) {
130
- const resolvedPath = (0, node_path.resolve)(path);
131
- const resolvedParent = (0, node_path.resolve)(parent);
132
- if (resolvedPath === resolvedParent) return true;
133
- const rel = (0, node_path.relative)(resolvedParent, resolvedPath);
134
- return rel !== "" && !rel.startsWith("..") && !(0, node_path.isAbsolute)(rel);
135
- }
136
- //#endregion
137
- //#region ../../internals/utils/src/promise.ts
138
- /**
139
- * Runs `run` over every item with at most `limit` in flight. Workers share one iterator, so each
140
- * takes the next item the moment it frees up instead of waiting for a batch to drain.
141
- *
142
- * @example
143
- * ```ts
144
- * await inParallel({ items: files, limit: 50, run: (file) => storage.writeItem(file.path, file.source) })
145
- * ```
146
- */
147
- async function inParallel({ items, limit, run }) {
148
- const queue = items.entries();
149
- const worker = async () => {
150
- for (const [index, item] of queue) await run(item, index);
151
- };
152
- await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
153
- }
154
- //#endregion
155
- //#region src/loggers/banner.ts
156
- /**
157
- * xterm-256 color for each pixel letter of the mascot. Fixed codes rather than named colors, so a
158
- * terminal theme cannot repaint it.
159
- */
160
- const colors = {
161
- /** Hoodie. */
162
- O: 208,
163
- /** Shadow where the hood meets the face. */
164
- R: 166,
165
- /** Face. */
166
- F: 223,
167
- /** Eyes. */
168
- K: 16,
169
- /** Blush. */
170
- B: 217,
171
- /** Mouth. */
172
- M: 131
173
- };
174
- /**
175
- * The two pixel rows of the face around the eyes, for each expression.
176
- */
177
- const eyes = {
178
- open: ["FFFFFFFFFF", "FFKFFFFKFF"],
179
- left: ["FFFFFFFFFF", "FKFFFFKFFF"],
180
- right: ["FFFFFFFFFF", "FFFKFFFFKF"],
181
- blink: ["FFFFFFFFFF", "FKKFFFFKKF"],
182
- happy: ["FFKFFFFKFF", "FKFKFFKFKF"]
183
- };
184
- /**
185
- * The frames the mascot plays when the CLI starts, each with how long it stays on screen. It ends on
186
- * open eyes, which stay.
187
- */
188
- const wakeUp = [
189
- ["blink", 100],
190
- ["open", 180],
191
- ["left", 140],
192
- ["right", 140],
193
- ["open", 80],
194
- ["happy", 220],
195
- ["open", 0]
196
- ];
197
- /**
198
- * The kid in the orange hoodie from the Kubb logo, one letter per pixel and `.` for none. Each
199
- * 2 × 2 block becomes one terminal cell, so a block holds at most two colors.
200
- */
201
- function pixels(expression) {
202
- const [top, bottom] = eyes[expression];
203
- return [
204
- "....OOOOOOOOOO....",
205
- "..OORRRRRRRRRROO..",
206
- `..OO${top}OO..`,
207
- `OOFF${bottom}FFOO`,
208
- "OOFFBBFFMMFFBBFFOO",
209
- "..OOOOFFFFFFOOOO.."
210
- ];
211
- }
212
- /**
213
- * Quadrant glyphs indexed by which quarters are filled: top left 1, top right 2, bottom left 4,
214
- * bottom right 8.
215
- */
216
- const quadrants = " ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█";
217
- /**
218
- * Draws each 2 × 2 block of pixels as one quadrant glyph. The glyph's filled quarters take the first
219
- * color in the block and the rest take the other.
220
- */
221
- function drawHead(expression) {
222
- const rows = pixels(expression);
223
- const lines = [];
224
- for (let y = 0; y < rows.length; y += 2) {
225
- let line = "";
226
- for (let x = 0; x < rows[y].length; x += 2) {
227
- const block = [
228
- rows[y][x],
229
- rows[y][x + 1],
230
- rows[y + 1][x],
231
- rows[y + 1][x + 1]
232
- ];
233
- const fg = block.find((pixel) => pixel in colors);
234
- if (!fg) {
235
- line += " ";
236
- continue;
237
- }
238
- const bg = colors[block.find((pixel) => pixel !== fg) ?? "."];
239
- const mask = block.reduce((bits, pixel, index) => pixel === fg ? bits | 1 << index : bits, 0);
240
- line += `\x1b[38;5;${colors[fg]}${bg === void 0 ? "" : `;48;5;${bg}`}m${quadrants[mask]}\x1b[0m`;
241
- }
242
- lines.push(line);
243
- }
244
- return lines;
245
- }
246
- /**
247
- * Generates the Kubb mascot welcome banner as an ANSI-colored string: the head with the version,
248
- * title, and description beside it.
249
- *
250
- * @example
251
- * ```ts
252
- * console.log(getIntro({ title: 'kubb.config.ts', description: 'generating…', version: '5.0.0', expression: 'open' }))
253
- * ```
254
- */
255
- function getIntro({ title, description, version, expression }) {
256
- const brand = (value, bold = false) => `\x1b[${bold ? "1;" : ""}38;5;${colors.O}m${value}\x1b[0m`;
257
- const text = [
258
- brand(`KUBB v${version}`, true),
259
- (0, node_util.styleText)("gray", title),
260
- `${brand("➜")} ${(0, node_util.styleText)("white", description)}`
261
- ];
262
- return drawHead(expression).map((line, index) => ` ${line} ${text[index]}`).join("\n");
263
- }
264
- /**
265
- * Formats a millisecond duration with a threshold-based ANSI color.
266
- * `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.
267
- *
268
- * @example
269
- * ```ts
270
- * formatMsWithColor(200) // '\x1b[32m200ms\x1b[39m'
271
- * formatMsWithColor(800) // '\x1b[33m800ms\x1b[39m'
272
- * formatMsWithColor(1500) // '\x1b[31m1.50s\x1b[39m'
273
- * ```
274
- */
275
- function formatMsWithColor(ms) {
276
- const formatted = require_Telemetry.formatMs(ms);
277
- if (ms <= 500) return (0, node_util.styleText)("green", formatted);
278
- if (ms <= 1e3) return (0, node_util.styleText)("yellow", formatted);
279
- return (0, node_util.styleText)("red", formatted);
280
- }
281
- /**
282
- * A `size`-cell progress bar: `done` of `total` as filled cells, the rest light. Any progress shows
283
- * at least one cell, and only a finished bar fills the last one.
284
- */
285
- function formatBar(done, total, size = 20) {
286
- const filled = !done ? 0 : done >= total ? size : Math.min(size - 1, Math.max(1, Math.round(done / total * size)));
287
- return (0, node_util.styleText)("magenta", "█".repeat(filled)) + (0, node_util.styleText)("dim", "░".repeat(size - filled));
288
- }
289
- //#endregion
290
- //#region src/ui/spinner.ts
291
- /**
292
- * A progress spinner, or a writer that prints each message it is given when the terminal cannot
293
- * animate one. Callers drive both the same way, including the failure state.
294
- */
295
- function createSpinner() {
296
- return require_text.writer().spinner();
297
- }
298
- /** How long a wait may run before a spinner shows, so a fast answer draws nothing. */
299
- const SPINNER_DELAY_MS = 150;
300
- /**
301
- * Awaits `promise`, showing a spinner with `message` only when it takes longer than 150 ms.
302
- */
303
- async function withSpinner({ promise, message }) {
304
- let spinner;
305
- const timer = setTimeout(() => {
306
- spinner = createSpinner();
307
- spinner.start(message);
308
- }, SPINNER_DELAY_MS);
309
- try {
310
- return await promise;
311
- } finally {
312
- clearTimeout(timer);
313
- spinner?.clear();
314
- }
315
- }
316
- //#endregion
317
- //#region src/runners/generate/utils.ts
318
- /** Glob pattern for paths the file watcher ignores. */
319
- const WATCHER_IGNORED_PATHS = "**/{.git,node_modules}/**";
320
- /**
321
- * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits several) into one rebuild.
322
- * It outlasts chokidar's 100 ms atomic-save window, which holds back the event of a write-then-rename save.
323
- */
324
- const WATCHER_DEBOUNCE_MS = 250;
325
- /** `14:02:11 petStore.yaml changed`, the line a watcher prints when its input changes. */
326
- function formatChange({ target, removed = false, now = /* @__PURE__ */ new Date() }) {
327
- return `${(0, node_util.styleText)("dim", now.toTimeString().slice(0, 8))} ${(0, node_util.styleText)("bold", target)} ${removed ? "removed" : "changed"}`;
328
- }
329
- /**
330
- * Starts a file watcher on the given paths and calls `cb` on any change.
331
- * Ignores `.git` and `node_modules` directories. Event bursts (an editor save emits several)
332
- * are debounced into one call. `cb` must never reject: its result is not awaited, so the caller
333
- * serializes and reports its own builds. Resolves to a function that stops watching.
334
- */
335
- async function startWatcher(path, cb, log = {
336
- info: console.log,
337
- error: console.log
338
- }) {
339
- const { watch } = await import("chokidar");
340
- const watcher = watch(path, {
341
- ignorePermissionErrors: true,
342
- ignored: WATCHER_IGNORED_PATHS,
343
- ignoreInitial: true
344
- });
345
- for (const signal of ["SIGINT", "SIGTERM"]) node_process.default.once(signal, () => void watcher.close());
346
- let debounceTimer = null;
347
- watcher.on("all", (type, file) => {
348
- log.info(formatChange({
349
- target: (0, node_path.relative)(node_process.default.cwd(), file),
350
- removed: type === "unlink"
351
- }));
352
- if (debounceTimer) clearTimeout(debounceTimer);
353
- debounceTimer = setTimeout(() => {
354
- debounceTimer = null;
355
- cb(path);
356
- }, WATCHER_DEBOUNCE_MS);
357
- });
358
- return async () => {
359
- if (debounceTimer) clearTimeout(debounceTimer);
360
- await watcher.close();
361
- };
362
- }
363
- function createSnapshot() {
364
- return {
365
- schemas: /* @__PURE__ */ new Set(),
366
- operations: /* @__PURE__ */ new Set()
367
- };
368
- }
369
- /**
370
- * Collects a {@link BuildSnapshot} from the hooks while a build runs. `take` hands back the finished
371
- * build's snapshot and starts the next one.
372
- */
373
- function trackBuild(hooks) {
374
- let current = createSnapshot();
375
- hooks.hook("kubb:generate:schema", (node) => {
376
- if (node.name) current.schemas.add(node.name);
377
- });
378
- hooks.hook("kubb:generate:operation", (node) => {
379
- current.operations.add(node.operationId);
380
- });
381
- return { take() {
382
- const snapshot = current;
383
- current = createSnapshot();
384
- return snapshot;
385
- } };
386
- }
387
- function diffNames(previous, next) {
388
- return {
389
- added: [...next].filter((name) => !previous.has(name)).length,
390
- removed: [...previous].filter((name) => !next.has(name)).length
391
- };
392
- }
393
- /**
394
- * Compares two {@link BuildSnapshot}s by name.
395
- */
396
- function diffBuilds(previous, next) {
397
- return {
398
- schemas: diffNames(previous.schemas, next.schemas),
399
- operations: diffNames(previous.operations, next.operations)
400
- };
401
- }
402
- /**
403
- * Compares file contents or fingerprints by path.
404
- */
405
- function diffFiles(previous, next) {
406
- const files = [];
407
- let unchanged = 0;
408
- for (const [path, fingerprint] of next) {
409
- const before = previous.get(path);
410
- if (before === fingerprint) unchanged++;
411
- else files.push({
412
- status: before === void 0 ? "A" : "M",
413
- path
414
- });
415
- }
416
- for (const path of previous.keys()) if (!next.has(path)) files.push({
417
- status: "D",
418
- path
419
- });
420
- return {
421
- files,
422
- unchanged
423
- };
424
- }
425
- function countLineChanges(before, after) {
426
- const remaining = /* @__PURE__ */ new Map();
427
- for (const line of before ? before.split("\n") : []) remaining.set(line, (remaining.get(line) ?? 0) + 1);
428
- let added = 0;
429
- for (const line of after ? after.split("\n") : []) {
430
- const count = remaining.get(line) ?? 0;
431
- if (count > 0) remaining.set(line, count - 1);
432
- else added++;
433
- }
434
- const removed = [...remaining.values()].reduce((sum, count) => sum + count, 0);
435
- return {
436
- added,
437
- removed
438
- };
439
- }
440
- /**
441
- * Reads the output before generation, so cleaning the directory cannot erase the diff baseline.
442
- * A missing directory or an unreadable file is skipped.
443
- */
444
- async function readOutputFiles(outputPath) {
445
- const entries = await (0, node_fs_promises.readdir)(outputPath, {
446
- recursive: true,
447
- withFileTypes: true
448
- }).catch(() => []);
449
- const files = /* @__PURE__ */ new Map();
450
- await inParallel({
451
- items: entries.filter((entry) => entry.isFile()).map((entry) => (0, node_path.join)(entry.parentPath, entry.name)),
452
- limit: 50,
453
- run: async (filePath) => {
454
- const source = await read(filePath).catch(() => null);
455
- if (source !== null) files.set(filePath, source);
456
- }
457
- });
458
- return files;
459
- }
460
- /**
461
- * Compares generated output with the files captured before generation. The manifest recognizes
462
- * output rewritten by a formatter, and `clean` includes files the run would delete.
463
- */
464
- async function diffOutput({ storage, paths, clean, manifest, previousFiles }) {
465
- const generated = new Set(paths);
466
- const changes = [];
467
- let unchanged = 0;
468
- await inParallel({
469
- items: paths,
470
- limit: 50,
471
- run: async (filePath, index) => {
472
- const next = await storage.readItem(filePath);
473
- if (next === null) return;
474
- const previous = previousFiles.get(filePath) ?? null;
475
- if (previous !== null && (matchesStored({
476
- stored: previous,
477
- source: next
478
- }) || manifest?.isUpToDate({
479
- key: filePath,
480
- source: next,
481
- disk: previous
482
- }))) {
483
- unchanged++;
484
- return;
485
- }
486
- changes[index] = {
487
- status: previous === null ? "A" : "M",
488
- path: filePath,
489
- ...countLineChanges(previous?.trim() ?? "", previous === null ? next.trimEnd() : next.trim())
490
- };
491
- }
492
- });
493
- const files = changes.filter((file) => file !== void 0);
494
- if (clean) {
495
- for (const [filePath, source] of previousFiles) if (!generated.has(filePath)) files.push({
496
- status: "D",
497
- path: filePath,
498
- ...countLineChanges(source.trimEnd(), "")
499
- });
500
- }
501
- return {
502
- files,
503
- unchanged
504
- };
505
- }
506
- /**
507
- * Reads `r` (rebuild) and `q` (quit) from an interactive stdin in raw mode, and keeps ctrl+c
508
- * working. Returns `undefined` when stdin is not a TTY. Otherwise returns `arm`, which turns raw
509
- * mode back on: a spinner restores the terminal when it stops, so call it after each build. Raw mode
510
- * is restored on exit.
511
- */
512
- function listenForKeys({ rebuild, quit, input = node_process.default.stdin }) {
513
- if (!input.isTTY) return void 0;
514
- const arm = () => {
515
- input.setRawMode(true);
516
- input.resume();
517
- };
518
- input.setEncoding("utf8");
519
- input.on("data", (data) => {
520
- const key = data.trim();
521
- if (key === "r") {
522
- rebuild();
523
- return;
524
- }
525
- if (key === "q" || data === "") {
526
- input.setRawMode(false);
527
- input.pause();
528
- quit(key === "q" ? 0 : 130);
529
- }
530
- });
531
- node_process.default.once("exit", () => input.setRawMode(false));
532
- arm();
533
- return arm;
534
- }
535
- //#endregion
536
- Object.defineProperty(exports, "createSpinner", {
537
- enumerable: true,
538
- get: function() {
539
- return createSpinner;
540
- }
541
- });
542
- Object.defineProperty(exports, "diffBuilds", {
543
- enumerable: true,
544
- get: function() {
545
- return diffBuilds;
546
- }
547
- });
548
- Object.defineProperty(exports, "diffFiles", {
549
- enumerable: true,
550
- get: function() {
551
- return diffFiles;
552
- }
553
- });
554
- Object.defineProperty(exports, "diffOutput", {
555
- enumerable: true,
556
- get: function() {
557
- return diffOutput;
558
- }
559
- });
560
- Object.defineProperty(exports, "exists", {
561
- enumerable: true,
562
- get: function() {
563
- return exists;
564
- }
565
- });
566
- Object.defineProperty(exports, "formatBar", {
567
- enumerable: true,
568
- get: function() {
569
- return formatBar;
570
- }
571
- });
572
- Object.defineProperty(exports, "formatMsWithColor", {
573
- enumerable: true,
574
- get: function() {
575
- return formatMsWithColor;
576
- }
577
- });
578
- Object.defineProperty(exports, "getIntro", {
579
- enumerable: true,
580
- get: function() {
581
- return getIntro;
582
- }
583
- });
584
- Object.defineProperty(exports, "isPathInside", {
585
- enumerable: true,
586
- get: function() {
587
- return isPathInside;
588
- }
589
- });
590
- Object.defineProperty(exports, "listenForKeys", {
591
- enumerable: true,
592
- get: function() {
593
- return listenForKeys;
594
- }
595
- });
596
- Object.defineProperty(exports, "read", {
597
- enumerable: true,
598
- get: function() {
599
- return read;
600
- }
601
- });
602
- Object.defineProperty(exports, "readOutputFiles", {
603
- enumerable: true,
604
- get: function() {
605
- return readOutputFiles;
606
- }
607
- });
608
- Object.defineProperty(exports, "startWatcher", {
609
- enumerable: true,
610
- get: function() {
611
- return startWatcher;
612
- }
613
- });
614
- Object.defineProperty(exports, "trackBuild", {
615
- enumerable: true,
616
- get: function() {
617
- return trackBuild;
618
- }
619
- });
620
- Object.defineProperty(exports, "wakeUp", {
621
- enumerable: true,
622
- get: function() {
623
- return wakeUp;
624
- }
625
- });
626
- Object.defineProperty(exports, "withSpinner", {
627
- enumerable: true,
628
- get: function() {
629
- return withSpinner;
630
- }
631
- });
632
- Object.defineProperty(exports, "write", {
633
- enumerable: true,
634
- get: function() {
635
- return write;
636
- }
637
- });
638
- Object.defineProperty(exports, "writeRaw", {
639
- enumerable: true,
640
- get: function() {
641
- return writeRaw;
642
- }
643
- });
644
-
645
- //# sourceMappingURL=utils-C3vTpUje.cjs.map