@yorozu/build 0.1.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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/chunks/21EFCjEU.js +19160 -0
  4. package/chunks/CMapqBQB.js +2620 -0
  5. package/chunks/CYSd7-PF.js +623 -0
  6. package/chunks/Cr5v7tI0.js +1824 -0
  7. package/ci/github-actions.d.ts +3 -0
  8. package/ci/index.d.ts +1 -0
  9. package/cli/commands/_utils.d.ts +8 -0
  10. package/cli/commands/build.d.ts +40 -0
  11. package/cli/commands/bump-version.d.ts +27 -0
  12. package/cli/commands/cr.d.ts +27 -0
  13. package/cli/commands/docs.d.ts +9 -0
  14. package/cli/commands/find-changed-packages.d.ts +10 -0
  15. package/cli/commands/gen-changelog.d.ts +10 -0
  16. package/cli/commands/gen-deps-graph.d.ts +15 -0
  17. package/cli/commands/jsr.d.ts +6 -0
  18. package/cli/commands/lint/config.d.ts +1 -0
  19. package/cli/commands/lint/index.d.ts +11 -0
  20. package/cli/commands/lint/validate-workspace-deps.d.ts +23 -0
  21. package/cli/commands/publish.d.ts +62 -0
  22. package/cli/commands/release.d.ts +45 -0
  23. package/cli/index.d.ts +8 -0
  24. package/cli/log.d.ts +3 -0
  25. package/cli/main.d.ts +2 -0
  26. package/config.d.ts +57 -0
  27. package/git/github.d.ts +15 -0
  28. package/git/index.d.ts +2 -0
  29. package/git/utils.d.ts +38 -0
  30. package/index.d.ts +8 -0
  31. package/index.js +26 -0
  32. package/jsr/_deno-directives.d.ts +1 -0
  33. package/jsr/config.d.ts +1 -0
  34. package/jsr/create-packages.d.ts +8 -0
  35. package/jsr/deno-json.d.ts +19 -0
  36. package/jsr/generate-workspace.d.ts +9 -0
  37. package/jsr/index.d.ts +6 -0
  38. package/jsr/populate.d.ts +10 -0
  39. package/jsr/utils/external-libs.d.ts +8 -0
  40. package/jsr/utils/index.d.ts +4 -0
  41. package/jsr/utils/jsr-api.d.ts +23 -0
  42. package/jsr/utils/jsr-json.d.ts +10 -0
  43. package/jsr/utils/jsr.d.ts +10 -0
  44. package/jsr.d.ts +1 -0
  45. package/jsr.js +2 -0
  46. package/misc/_config.d.ts +2 -0
  47. package/misc/exec.d.ts +15 -0
  48. package/misc/fs.d.ts +4 -0
  49. package/misc/index.d.ts +6 -0
  50. package/misc/path.d.ts +1 -0
  51. package/misc/publish-order.d.ts +3 -0
  52. package/misc/tsconfig.d.ts +2 -0
  53. package/npm/index.d.ts +1 -0
  54. package/npm/npm-api.d.ts +6 -0
  55. package/package-json/collect-package-jsons.d.ts +9 -0
  56. package/package-json/find-package-json.d.ts +1 -0
  57. package/package-json/index.d.ts +6 -0
  58. package/package-json/parse.d.ts +11 -0
  59. package/package-json/process-package-json.d.ts +20 -0
  60. package/package-json/types.d.ts +39 -0
  61. package/package-json/utils.d.ts +4 -0
  62. package/package.json +59 -0
  63. package/versioning/bump-version.d.ts +31 -0
  64. package/versioning/collect-files.d.ts +21 -0
  65. package/versioning/generate-changelog.d.ts +8 -0
  66. package/versioning/index.d.ts +4 -0
  67. package/versioning/types.d.ts +21 -0
  68. package/vite/build-plugin.d.ts +73 -0
  69. package/vite/config.d.ts +47 -0
  70. package/vite/index.d.ts +2 -0
  71. package/vite.d.ts +1 -0
  72. package/vite.js +184 -0
  73. package/yorozu-build.d.ts +1 -0
  74. package/yorozu-build.js +527 -0
@@ -0,0 +1,2620 @@
1
+ import { __toESM as __toESM$1, asNonNull, asyncPool, collectPackageJsons, error, fileExists, filterPackageJsonsForPublish, findPackageByName, findRootPackage, getWorkspaceRoot, info, loadBuildConfig, normalizeFilePath, number, object, parsePackageJsonFile, processPackageJson, require_picomatch, string as string$1, warn } from "./21EFCjEU.js";
2
+ import { exec, require_semver, sortWorkspaceByPublishOrder } from "./Cr5v7tI0.js";
3
+ import { randomUUID } from "node:crypto";
4
+ import { appendFileSync } from "node:fs";
5
+ import { EOL, tmpdir } from "node:os";
6
+ import process$1 from "node:process";
7
+ import { join, relative, resolve } from "node:path";
8
+ import * as fsp from "node:fs/promises";
9
+ import { readFile, writeFile } from "node:fs/promises";
10
+ import * as td from "typedoc";
11
+ //#region src/ci/github-actions.ts
12
+ function isRunningInGithubActions() {
13
+ return Boolean(process$1.env.GITHUB_ACTIONS);
14
+ }
15
+ function getGithubActionsInput(name) {
16
+ let input = process$1.env[`INPUT_${name.replace(/ /g, "_").toUpperCase()}`];
17
+ if (input === void 0) return void 0;
18
+ return input.trim();
19
+ }
20
+ function writeGithubActionsOutput(name, value) {
21
+ if (process$1.env.GITHUB_OUTPUT === void 0) throw new Error("GITHUB_OUTPUT is not set");
22
+ if (!value.includes(EOL)) {
23
+ appendFileSync(process$1.env.GITHUB_OUTPUT, `${name}=${value}${EOL}`, "utf8");
24
+ return;
25
+ }
26
+ let delim = `---${randomUUID()}---`;
27
+ appendFileSync(process$1.env.GITHUB_OUTPUT, `${name}<<${delim}${EOL}${value}${EOL}${delim}${EOL}`, "utf8");
28
+ }
29
+ //#endregion
30
+ //#region ../utils/src/structures/lru-map.ts
31
+ var LruMap = class {
32
+ #capacity;
33
+ #map;
34
+ constructor(capacity, MapImpl = Map) {
35
+ this.#capacity = capacity;
36
+ this.#map = new MapImpl();
37
+ }
38
+ get size() {
39
+ return this.#map.size;
40
+ }
41
+ get(key) {
42
+ if (!this.#map.has(key)) return void 0;
43
+ let value = this.#map.get(key);
44
+ this.#map.delete(key);
45
+ this.#map.set(key, value);
46
+ return value;
47
+ }
48
+ has(key) {
49
+ return this.#map.has(key);
50
+ }
51
+ set(key, value) {
52
+ if (this.#map.has(key)) this.#map.delete(key);
53
+ this.#map.set(key, value);
54
+ if (this.#map.size > this.#capacity) {
55
+ let oldest = this.#map.keys().next().value;
56
+ if (oldest !== void 0) this.#map.delete(oldest);
57
+ }
58
+ }
59
+ delete(key) {
60
+ this.#map.delete(key);
61
+ }
62
+ clear() {
63
+ this.#map.clear();
64
+ }
65
+ *[Symbol.iterator]() {
66
+ yield* this.#map;
67
+ }
68
+ entries() {
69
+ return this.#map.entries();
70
+ }
71
+ keys() {
72
+ return this.#map.keys();
73
+ }
74
+ values() {
75
+ return this.#map.values();
76
+ }
77
+ };
78
+ //#endregion
79
+ //#region ../../node_modules/.pnpm/@drizzle-team+brocli@0.12.0/node_modules/@drizzle-team/brocli/index.js
80
+ var __create = Object.create;
81
+ var __defProp = Object.defineProperty;
82
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
83
+ var __getOwnPropNames = Object.getOwnPropertyNames;
84
+ var __getProtoOf = Object.getPrototypeOf;
85
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
86
+ var __commonJS = (cb, mod) => function __require() {
87
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
88
+ };
89
+ var __copyProps = (to, from, except, desc) => {
90
+ if (from && typeof from === "object" || typeof from === "function") {
91
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
92
+ get: () => from[key],
93
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
94
+ });
95
+ }
96
+ return to;
97
+ };
98
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
99
+ value: mod,
100
+ enumerable: true
101
+ }) : target, mod));
102
+ var require_clone = __commonJS({ "node_modules/.pnpm/clone@2.1.2/node_modules/clone/clone.js"(exports, module) {
103
+ "use strict";
104
+ var clone2 = function() {
105
+ "use strict";
106
+ function _instanceof(obj, type) {
107
+ return type != null && obj instanceof type;
108
+ }
109
+ var nativeMap;
110
+ try {
111
+ nativeMap = Map;
112
+ } catch (_) {
113
+ nativeMap = function() {};
114
+ }
115
+ var nativeSet;
116
+ try {
117
+ nativeSet = Set;
118
+ } catch (_) {
119
+ nativeSet = function() {};
120
+ }
121
+ var nativePromise;
122
+ try {
123
+ nativePromise = Promise;
124
+ } catch (_) {
125
+ nativePromise = function() {};
126
+ }
127
+ function clone3(parent, circular, depth, prototype, includeNonEnumerable) {
128
+ if (typeof circular === "object") {
129
+ depth = circular.depth;
130
+ prototype = circular.prototype;
131
+ includeNonEnumerable = circular.includeNonEnumerable;
132
+ circular = circular.circular;
133
+ }
134
+ var allParents = [];
135
+ var allChildren = [];
136
+ var useBuffer = typeof Buffer != "undefined";
137
+ if (typeof circular == "undefined") circular = true;
138
+ if (typeof depth == "undefined") depth = Infinity;
139
+ function _clone(parent2, depth2) {
140
+ if (parent2 === null) return null;
141
+ if (depth2 === 0) return parent2;
142
+ var child;
143
+ var proto;
144
+ if (typeof parent2 != "object") return parent2;
145
+ if (_instanceof(parent2, nativeMap)) child = new nativeMap();
146
+ else if (_instanceof(parent2, nativeSet)) child = new nativeSet();
147
+ else if (_instanceof(parent2, nativePromise)) child = new nativePromise(function(resolve, reject) {
148
+ parent2.then(function(value) {
149
+ resolve(_clone(value, depth2 - 1));
150
+ }, function(err) {
151
+ reject(_clone(err, depth2 - 1));
152
+ });
153
+ });
154
+ else if (clone3.__isArray(parent2)) child = [];
155
+ else if (clone3.__isRegExp(parent2)) {
156
+ child = new RegExp(parent2.source, __getRegExpFlags(parent2));
157
+ if (parent2.lastIndex) child.lastIndex = parent2.lastIndex;
158
+ } else if (clone3.__isDate(parent2)) child = new Date(parent2.getTime());
159
+ else if (useBuffer && Buffer.isBuffer(parent2)) {
160
+ if (Buffer.allocUnsafe) child = Buffer.allocUnsafe(parent2.length);
161
+ else child = new Buffer(parent2.length);
162
+ parent2.copy(child);
163
+ return child;
164
+ } else if (_instanceof(parent2, Error)) child = Object.create(parent2);
165
+ else if (typeof prototype == "undefined") {
166
+ proto = Object.getPrototypeOf(parent2);
167
+ child = Object.create(proto);
168
+ } else {
169
+ child = Object.create(prototype);
170
+ proto = prototype;
171
+ }
172
+ if (circular) {
173
+ var index = allParents.indexOf(parent2);
174
+ if (index != -1) return allChildren[index];
175
+ allParents.push(parent2);
176
+ allChildren.push(child);
177
+ }
178
+ if (_instanceof(parent2, nativeMap)) parent2.forEach(function(value, key) {
179
+ var keyChild = _clone(key, depth2 - 1);
180
+ var valueChild = _clone(value, depth2 - 1);
181
+ child.set(keyChild, valueChild);
182
+ });
183
+ if (_instanceof(parent2, nativeSet)) parent2.forEach(function(value) {
184
+ var entryChild = _clone(value, depth2 - 1);
185
+ child.add(entryChild);
186
+ });
187
+ for (var i in parent2) {
188
+ var attrs;
189
+ if (proto) attrs = Object.getOwnPropertyDescriptor(proto, i);
190
+ if (attrs && attrs.set == null) continue;
191
+ child[i] = _clone(parent2[i], depth2 - 1);
192
+ }
193
+ if (Object.getOwnPropertySymbols) {
194
+ var symbols = Object.getOwnPropertySymbols(parent2);
195
+ for (var i = 0; i < symbols.length; i++) {
196
+ var symbol = symbols[i];
197
+ var descriptor = Object.getOwnPropertyDescriptor(parent2, symbol);
198
+ if (descriptor && !descriptor.enumerable && !includeNonEnumerable) continue;
199
+ child[symbol] = _clone(parent2[symbol], depth2 - 1);
200
+ if (!descriptor.enumerable) Object.defineProperty(child, symbol, { enumerable: false });
201
+ }
202
+ }
203
+ if (includeNonEnumerable) {
204
+ var allPropertyNames = Object.getOwnPropertyNames(parent2);
205
+ for (var i = 0; i < allPropertyNames.length; i++) {
206
+ var propertyName = allPropertyNames[i];
207
+ var descriptor = Object.getOwnPropertyDescriptor(parent2, propertyName);
208
+ if (descriptor && descriptor.enumerable) continue;
209
+ child[propertyName] = _clone(parent2[propertyName], depth2 - 1);
210
+ Object.defineProperty(child, propertyName, { enumerable: false });
211
+ }
212
+ }
213
+ return child;
214
+ }
215
+ return _clone(parent, depth);
216
+ }
217
+ clone3.clonePrototype = function clonePrototype(parent) {
218
+ if (parent === null) return null;
219
+ var c = function() {};
220
+ c.prototype = parent;
221
+ return new c();
222
+ };
223
+ function __objToStr(o) {
224
+ return Object.prototype.toString.call(o);
225
+ }
226
+ clone3.__objToStr = __objToStr;
227
+ function __isDate(o) {
228
+ return typeof o === "object" && __objToStr(o) === "[object Date]";
229
+ }
230
+ clone3.__isDate = __isDate;
231
+ function __isArray(o) {
232
+ return typeof o === "object" && __objToStr(o) === "[object Array]";
233
+ }
234
+ clone3.__isArray = __isArray;
235
+ function __isRegExp(o) {
236
+ return typeof o === "object" && __objToStr(o) === "[object RegExp]";
237
+ }
238
+ clone3.__isRegExp = __isRegExp;
239
+ function __getRegExpFlags(re) {
240
+ var flags = "";
241
+ if (re.global) flags += "g";
242
+ if (re.ignoreCase) flags += "i";
243
+ if (re.multiline) flags += "m";
244
+ return flags;
245
+ }
246
+ clone3.__getRegExpFlags = __getRegExpFlags;
247
+ return clone3;
248
+ }();
249
+ if (typeof module === "object" && module.exports) module.exports = clone2;
250
+ } });
251
+ var require_quote = __commonJS({ "node_modules/.pnpm/shell-quote@1.8.1/node_modules/shell-quote/quote.js"(exports, module) {
252
+ "use strict";
253
+ module.exports = function quote(xs) {
254
+ return xs.map(function(s) {
255
+ if (s && typeof s === "object") return s.op.replace(/(.)/g, "\\$1");
256
+ if (/["\s]/.test(s) && !/'/.test(s)) return "'" + s.replace(/(['\\])/g, "\\$1") + "'";
257
+ if (/["'\s]/.test(s)) return "\"" + s.replace(/(["\\$`!])/g, "\\$1") + "\"";
258
+ return String(s).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2");
259
+ }).join(" ");
260
+ };
261
+ } });
262
+ var require_parse = __commonJS({ "node_modules/.pnpm/shell-quote@1.8.1/node_modules/shell-quote/parse.js"(exports, module) {
263
+ "use strict";
264
+ var CONTROL = "(?:" + [
265
+ "\\|\\|",
266
+ "\\&\\&",
267
+ ";;",
268
+ "\\|\\&",
269
+ "\\<\\(",
270
+ "\\<\\<\\<",
271
+ ">>",
272
+ ">\\&",
273
+ "<\\&",
274
+ "[&;()|<>]"
275
+ ].join("|") + ")";
276
+ var controlRE = new RegExp("^" + CONTROL + "$");
277
+ var META = "|&;()<> \\t";
278
+ var SINGLE_QUOTE = "\"((\\\\\"|[^\"])*?)\"";
279
+ var DOUBLE_QUOTE = "'((\\\\'|[^'])*?)'";
280
+ var hash = /^#$/;
281
+ var SQ = "'";
282
+ var DQ = "\"";
283
+ var DS = "$";
284
+ var TOKEN = "";
285
+ var mult = 4294967296;
286
+ for (i = 0; i < 4; i++) TOKEN += (mult * Math.random()).toString(16);
287
+ var i;
288
+ var startsWithToken = new RegExp("^" + TOKEN);
289
+ function matchAll(s, r) {
290
+ var origIndex = r.lastIndex;
291
+ var matches = [];
292
+ var matchObj;
293
+ while (matchObj = r.exec(s)) {
294
+ matches.push(matchObj);
295
+ if (r.lastIndex === matchObj.index) r.lastIndex += 1;
296
+ }
297
+ r.lastIndex = origIndex;
298
+ return matches;
299
+ }
300
+ function getVar(env, pre, key) {
301
+ var r = typeof env === "function" ? env(key) : env[key];
302
+ if (typeof r === "undefined" && key != "") r = "";
303
+ else if (typeof r === "undefined") r = "$";
304
+ if (typeof r === "object") return pre + TOKEN + JSON.stringify(r) + TOKEN;
305
+ return pre + r;
306
+ }
307
+ function parseInternal(string2, env, opts) {
308
+ if (!opts) opts = {};
309
+ var BS = opts.escape || "\\";
310
+ var BAREWORD = "(\\" + BS + `['"` + META + `]|[^\\s'"` + META + "])+";
311
+ var matches = matchAll(string2, new RegExp(["(" + CONTROL + ")", "(" + BAREWORD + "|" + SINGLE_QUOTE + "|" + DOUBLE_QUOTE + ")+"].join("|"), "g"));
312
+ if (matches.length === 0) return [];
313
+ if (!env) env = {};
314
+ var commented = false;
315
+ return matches.map(function(match) {
316
+ var s = match[0];
317
+ if (!s || commented) return;
318
+ if (controlRE.test(s)) return { op: s };
319
+ var quote = false;
320
+ var esc = false;
321
+ var out = "";
322
+ var isGlob = false;
323
+ var i2;
324
+ function parseEnvVar() {
325
+ i2 += 1;
326
+ var varend;
327
+ var varname;
328
+ var char = s.charAt(i2);
329
+ if (char === "{") {
330
+ i2 += 1;
331
+ if (s.charAt(i2) === "}") throw new Error("Bad substitution: " + s.slice(i2 - 2, i2 + 1));
332
+ varend = s.indexOf("}", i2);
333
+ if (varend < 0) throw new Error("Bad substitution: " + s.slice(i2));
334
+ varname = s.slice(i2, varend);
335
+ i2 = varend;
336
+ } else if (/[*@#?$!_-]/.test(char)) {
337
+ varname = char;
338
+ i2 += 1;
339
+ } else {
340
+ var slicedFromI = s.slice(i2);
341
+ varend = slicedFromI.match(/[^\w\d_]/);
342
+ if (!varend) {
343
+ varname = slicedFromI;
344
+ i2 = s.length;
345
+ } else {
346
+ varname = slicedFromI.slice(0, varend.index);
347
+ i2 += varend.index - 1;
348
+ }
349
+ }
350
+ return getVar(env, "", varname);
351
+ }
352
+ for (i2 = 0; i2 < s.length; i2++) {
353
+ var c = s.charAt(i2);
354
+ isGlob = isGlob || !quote && (c === "*" || c === "?");
355
+ if (esc) {
356
+ out += c;
357
+ esc = false;
358
+ } else if (quote) if (c === quote) quote = false;
359
+ else if (quote == SQ) out += c;
360
+ else if (c === BS) {
361
+ i2 += 1;
362
+ c = s.charAt(i2);
363
+ if (c === DQ || c === BS || c === DS) out += c;
364
+ else out += BS + c;
365
+ } else if (c === DS) out += parseEnvVar();
366
+ else out += c;
367
+ else if (c === DQ || c === SQ) quote = c;
368
+ else if (controlRE.test(c)) return { op: s };
369
+ else if (hash.test(c)) {
370
+ commented = true;
371
+ var commentObj = { comment: string2.slice(match.index + i2 + 1) };
372
+ if (out.length) return [out, commentObj];
373
+ return [commentObj];
374
+ } else if (c === BS) esc = true;
375
+ else if (c === DS) out += parseEnvVar();
376
+ else out += c;
377
+ }
378
+ if (isGlob) return {
379
+ op: "glob",
380
+ pattern: out
381
+ };
382
+ return out;
383
+ }).reduce(function(prev, arg) {
384
+ return typeof arg === "undefined" ? prev : prev.concat(arg);
385
+ }, []);
386
+ }
387
+ module.exports = function parse(s, env, opts) {
388
+ var mapped = parseInternal(s, env, opts);
389
+ if (typeof env !== "function") return mapped;
390
+ return mapped.reduce(function(acc, s2) {
391
+ if (typeof s2 === "object") return acc.concat(s2);
392
+ var xs = s2.split(RegExp("(" + TOKEN + ".*?" + TOKEN + ")", "g"));
393
+ if (xs.length === 1) return acc.concat(xs[0]);
394
+ return acc.concat(xs.filter(Boolean).map(function(x) {
395
+ if (startsWithToken.test(x)) return JSON.parse(x.split(TOKEN)[1]);
396
+ return x;
397
+ }));
398
+ }, []);
399
+ };
400
+ } });
401
+ var require_shell_quote = __commonJS({ "node_modules/.pnpm/shell-quote@1.8.1/node_modules/shell-quote/index.js"(exports) {
402
+ "use strict";
403
+ exports.quote = require_quote();
404
+ exports.parse = require_parse();
405
+ } });
406
+ var BroCliError = class extends Error {
407
+ constructor(message, event) {
408
+ super(message === void 0 ? message : `BroCli error: ${message}`);
409
+ this.event = event;
410
+ }
411
+ };
412
+ var import_clone = __toESM(require_clone(), 1);
413
+ var getOptionTypeText = (option) => {
414
+ let result = "";
415
+ switch (option.type) {
416
+ case "boolean":
417
+ result = "";
418
+ break;
419
+ case "number":
420
+ if ((option.minVal ?? option.maxVal) !== void 0) {
421
+ let text = "";
422
+ if (option.isInt) text = text + `integer `;
423
+ if (option.minVal !== void 0) text = text + `[${option.minVal};`;
424
+ else text = text + `(\u221E;`;
425
+ if (option.maxVal !== void 0) text = text + `${option.maxVal}]`;
426
+ else text = text + `\u221E)`;
427
+ result = text;
428
+ break;
429
+ }
430
+ if (option.isInt) {
431
+ result = "integer";
432
+ break;
433
+ }
434
+ result = "number";
435
+ break;
436
+ case "string":
437
+ if (option.enumVals) {
438
+ result = "[ " + option.enumVals.join(" | ") + " ]";
439
+ break;
440
+ }
441
+ result = "string";
442
+ break;
443
+ case "positional":
444
+ result = `${option.isRequired ? "<" : "["}${option.enumVals ? option.enumVals.join("|") : option.name}${option.isRequired ? ">" : "]"}`;
445
+ break;
446
+ }
447
+ if (option.isRequired && option.type !== "positional") result = "!" + (result.length ? "" + result : " ");
448
+ return result;
449
+ };
450
+ var defaultEventHandler = async (event) => {
451
+ switch (event.type) {
452
+ case "command_help": {
453
+ const command2 = event.command;
454
+ const commandName = getCommandNameWithParents(command2);
455
+ const cliName = event.name;
456
+ const desc = command2.desc ?? command2.shortDesc;
457
+ const subs = command2.subcommands?.filter((s) => !s.hidden);
458
+ const subcommands = subs && subs.length ? subs : void 0;
459
+ const defaultGlobals = [{
460
+ config: {
461
+ name: "--help",
462
+ aliases: ["-h"],
463
+ type: "boolean",
464
+ description: `help for ${commandName}`,
465
+ default: void 0
466
+ },
467
+ $output: void 0
468
+ }, {
469
+ config: {
470
+ name: "--version",
471
+ aliases: ["-v"],
472
+ type: "boolean",
473
+ description: `version${cliName ? ` for ${cliName}` : ""}`,
474
+ default: void 0
475
+ },
476
+ $output: void 0
477
+ }];
478
+ const globals = event.globals ? [...Object.values(event.globals), ...defaultGlobals] : defaultGlobals;
479
+ if (desc !== void 0) console.log(`
480
+ ${desc}`);
481
+ const opts = Object.values(command2.options ?? {}).filter((opt) => !opt.config.isHidden);
482
+ const positionals = opts.filter((opt) => opt.config.type === "positional");
483
+ const options = [...opts.filter((opt) => opt.config.type !== "positional"), ...globals];
484
+ console.log("\nUsage:");
485
+ if (command2.handler) console.log(` ${cliName ? cliName + " " : ""}${commandName}${positionals.length ? " " + positionals.map(({ config: p }) => getOptionTypeText(p)).join(" ") : ""} [flags]`);
486
+ else console.log(` ${cliName ? cliName + " " : ""}${commandName} [command]`);
487
+ if (command2.aliases) {
488
+ console.log(`
489
+ Aliases:`);
490
+ console.log(` ${[command2.name, ...command2.aliases].join(", ")}`);
491
+ }
492
+ if (subcommands) {
493
+ console.log("\nAvailable Commands:");
494
+ const paddedLength = subcommands.reduce((p, e) => e.name.length > p ? e.name.length : p, 0) + 3;
495
+ const preDescPad = 2 + paddedLength;
496
+ const data = subcommands.map((s) => ` ${s.name.padEnd(paddedLength)}${(() => {
497
+ const description = s.shortDesc ?? s.desc;
498
+ if (!description?.length) return "";
499
+ const split = description.split("\n");
500
+ return [split.shift(), ...split.map((s2) => "".padEnd(preDescPad) + s2)].join("\n");
501
+ })()}`).join("\n");
502
+ console.log(data);
503
+ }
504
+ if (options.length) {
505
+ const aliasLength = options.reduce((p, e) => {
506
+ const currentLength = e.config.aliases.reduce((pa, a) => pa + a.length, 0) + (e.config.aliases.length - 1) * 2 + 1;
507
+ return currentLength > p ? currentLength : p;
508
+ }, 0);
509
+ const paddedAliasLength = aliasLength > 0 ? aliasLength + 1 : 0;
510
+ const nameLength = options.reduce((p, e) => {
511
+ const typeLen = getOptionTypeText(e.config).length;
512
+ const length = typeLen > 0 ? e.config.name.length + 1 + typeLen : e.config.name.length;
513
+ return length > p ? length : p;
514
+ }, 0) + 3;
515
+ const preDescPad = paddedAliasLength + nameLength + 2;
516
+ const data = options.map(({ config: opt }) => ` ${`${opt.aliases.length ? opt.aliases.join(", ") + "," : ""}`.padEnd(paddedAliasLength)}${`${opt.name}${(() => {
517
+ const typeText = getOptionTypeText(opt);
518
+ return typeText.length ? " " + typeText : "";
519
+ })()}`.padEnd(nameLength)}${(() => {
520
+ if (!opt.description?.length) return opt.default !== void 0 ? `default: ${JSON.stringify(opt.default)}` : "";
521
+ const split = opt.description.split("\n");
522
+ const first = split.shift();
523
+ const def = opt.default !== void 0 ? ` (default: ${JSON.stringify(opt.default)})` : "";
524
+ return [first, ...split.map((s) => "".padEnd(preDescPad) + s)].join("\n") + def;
525
+ })()}`).join("\n");
526
+ console.log("\nFlags:");
527
+ console.log(data);
528
+ }
529
+ if (subcommands) console.log(`
530
+ Use "${cliName ? cliName + " " : ""}${commandName} [command] --help" for more information about a command.
531
+ `);
532
+ return true;
533
+ }
534
+ case "global_help": {
535
+ const cliName = event.name;
536
+ const desc = event.description;
537
+ const commands = event.commands.filter((c) => !c.hidden);
538
+ const defaultGlobals = [{
539
+ config: {
540
+ name: "--help",
541
+ aliases: ["-h"],
542
+ type: "boolean",
543
+ description: `help${cliName ? ` for ${cliName}` : ""}`,
544
+ default: void 0
545
+ },
546
+ $output: void 0
547
+ }, {
548
+ config: {
549
+ name: "--version",
550
+ aliases: ["-v"],
551
+ type: "boolean",
552
+ description: `version${cliName ? ` for ${cliName}` : ""}`,
553
+ default: void 0
554
+ },
555
+ $output: void 0
556
+ }];
557
+ const globals = event.globals ? [...defaultGlobals, ...Object.values(event.globals)] : defaultGlobals;
558
+ if (desc !== void 0) console.log(`${desc}
559
+ `);
560
+ console.log("Usage:");
561
+ console.log(` ${cliName ? cliName + " " : ""}[command]`);
562
+ if (commands.length) {
563
+ console.log("\nAvailable Commands:");
564
+ const paddedLength = commands.reduce((p, e) => e.name.length > p ? e.name.length : p, 0) + 3;
565
+ const data = commands.map((c) => ` ${c.name.padEnd(paddedLength)}${(() => {
566
+ const desc2 = c.shortDesc ?? c.desc;
567
+ if (!desc2?.length) return "";
568
+ const split = desc2.split("\n");
569
+ return [split.shift(), ...split.map((s) => "".padEnd(paddedLength + 2) + s)].join("\n");
570
+ })()}`).join("\n");
571
+ console.log(data);
572
+ } else console.log("\nNo available commands.");
573
+ const aliasLength = globals.reduce((p, e) => {
574
+ const currentLength = e.config.aliases.reduce((pa, a) => pa + a.length, 0) + (e.config.aliases.length - 1) * 2 + 1;
575
+ return currentLength > p ? currentLength : p;
576
+ }, 0);
577
+ const paddedAliasLength = aliasLength > 0 ? aliasLength + 1 : 0;
578
+ const nameLength = globals.reduce((p, e) => {
579
+ const typeLen = getOptionTypeText(e.config).length;
580
+ const length = typeLen > 0 ? e.config.name.length + 1 + typeLen : e.config.name.length;
581
+ return length > p ? length : p;
582
+ }, 0) + 3;
583
+ const preDescPad = paddedAliasLength + nameLength + 2;
584
+ const gData = globals.map(({ config: opt }) => ` ${`${opt.aliases.length ? opt.aliases.join(", ") + "," : ""}`.padEnd(paddedAliasLength)}${`${opt.name}${(() => {
585
+ const typeText = getOptionTypeText(opt);
586
+ return typeText.length ? " " + typeText : "";
587
+ })()}`.padEnd(nameLength)}${(() => {
588
+ if (!opt.description?.length) return opt.default !== void 0 ? `default: ${JSON.stringify(opt.default)}` : "";
589
+ const split = opt.description.split("\n");
590
+ const first = split.shift();
591
+ const def = opt.default !== void 0 ? ` (default: ${JSON.stringify(opt.default)})` : "";
592
+ return [first, ...split.map((s) => "".padEnd(preDescPad) + s)].join("\n") + def;
593
+ })()}`).join("\n");
594
+ console.log("\nFlags:");
595
+ console.log(gData);
596
+ return true;
597
+ }
598
+ case "version": return true;
599
+ case "error": {
600
+ let msg;
601
+ switch (event.violation) {
602
+ case "above_max": {
603
+ const matchedName = event.offender.namePart;
604
+ const data = event.offender.dataPart;
605
+ msg = `Invalid value: number type argument '${matchedName}' expects maximal value of ${event.option.maxVal} as an input, got: ${data}`;
606
+ break;
607
+ }
608
+ case "below_min": {
609
+ const matchedName = event.offender.namePart;
610
+ const data = event.offender.dataPart;
611
+ msg = `Invalid value: number type argument '${matchedName}' expects minimal value of ${event.option.minVal} as an input, got: ${data}`;
612
+ break;
613
+ }
614
+ case "expected_int":
615
+ msg = `Invalid value: number type argument '${event.offender.namePart}' expects an integer as an input, got: ${event.offender.dataPart}`;
616
+ break;
617
+ case "invalid_boolean_syntax": {
618
+ const matchedName = event.offender.namePart;
619
+ event.offender.dataPart;
620
+ msg = `Invalid syntax: boolean type argument '${matchedName}' must have it's value passed in the following formats: ${matchedName}=<value> | ${matchedName} <value> | ${matchedName}.
621
+ Allowed values: true, false, 0, 1`;
622
+ break;
623
+ }
624
+ case "invalid_string_syntax": {
625
+ const matchedName = event.offender.namePart;
626
+ msg = `Invalid syntax: string type argument '${matchedName}' must have it's value passed in the following formats: ${matchedName}=<value> | ${matchedName} <value>`;
627
+ break;
628
+ }
629
+ case "invalid_number_syntax": {
630
+ const matchedName = event.offender.namePart;
631
+ msg = `Invalid syntax: number type argument '${matchedName}' must have it's value passed in the following formats: ${matchedName}=<value> | ${matchedName} <value>`;
632
+ break;
633
+ }
634
+ case "invalid_number_value":
635
+ msg = `Invalid value: number type argument '${event.offender.namePart}' expects a number as an input, got: ${event.offender.dataPart}`;
636
+ break;
637
+ case "enum_violation": {
638
+ const matchedName = event.offender.namePart;
639
+ const data = event.offender.dataPart;
640
+ const option = event.option;
641
+ const values = option.enumVals;
642
+ msg = option.type === "positional" ? `Invalid value: value for the positional argument '${option.name}' must be either one of the following: ${values.join(", ")}; Received: ${data}` : `Invalid value: value for the argument '${matchedName}' must be either one of the following: ${values.join(", ")}; Received: ${data}`;
643
+ break;
644
+ }
645
+ case "unknown_command_error": {
646
+ const msg2 = `Unknown command: '${event.offender}'.
647
+ Type '--help' to get help on the cli.`;
648
+ console.error(msg2);
649
+ return true;
650
+ }
651
+ case "unknown_subcommand_error": {
652
+ const cName = getCommandNameWithParents(event.command);
653
+ const msg2 = `Unknown command: ${cName} ${event.offender}.
654
+ Type '${cName} --help' to get the help on command.`;
655
+ console.error(msg2);
656
+ return true;
657
+ }
658
+ case "missing_args_error": {
659
+ const { missing: missingOpts, command: command2 } = event;
660
+ msg = command2 === "globals" ? `Missing` : `Command '${command2.name}' is missing following required options: ${missingOpts.map((opt) => {
661
+ const name = opt.shift();
662
+ const aliases = opt;
663
+ if (aliases.length) return `${name} [${aliases.join(", ")}]`;
664
+ return name;
665
+ }).join(", ")}`;
666
+ break;
667
+ }
668
+ case "unrecognized_args_error": {
669
+ const { command: command2, unrecognized } = event;
670
+ msg = `Unrecognized options for command '${command2.name}': ${unrecognized.join(", ")}`;
671
+ break;
672
+ }
673
+ case "unknown_error": {
674
+ const e = event.error;
675
+ console.error(typeof e === "object" && e !== null && "message" in e ? e.message : e);
676
+ return true;
677
+ }
678
+ }
679
+ console.error(msg);
680
+ return true;
681
+ }
682
+ }
683
+ return false;
684
+ };
685
+ var eventHandlerWrapper = (customEventHandler) => async (event, options) => await customEventHandler(event, options) ? true : await defaultEventHandler(event, options);
686
+ __toESM(require_shell_quote(), 1);
687
+ function isInt(value) {
688
+ return value === Math.floor(value);
689
+ }
690
+ var executeOrLog = async (target, arg) => typeof target === "string" ? console.log(target) : target ? await target(arg) : void 0;
691
+ var generatePrefix = (name) => name.startsWith("-") ? name : name.length > 1 ? `--${name}` : `-${name}`;
692
+ var validateOptions = (config) => {
693
+ const cloned = (0, import_clone.default)(config);
694
+ const entries = [];
695
+ const storedNames = [];
696
+ const cfgEntries = Object.entries(cloned);
697
+ for (const [key, value] of cfgEntries) {
698
+ const cfg = value._.config;
699
+ if (cfg.name === void 0) cfg.name = key;
700
+ if (cfg.type === "positional") continue;
701
+ if (cfg.name.includes("=")) throw new BroCliError(`Can't define option '${generatePrefix(cfg.name)}' - option names and aliases cannot contain '='!`);
702
+ for (const alias of cfg.aliases) if (alias.includes("=")) throw new BroCliError(`Can't define option '${generatePrefix(cfg.name)}' - option names and aliases cannot contain '='!`);
703
+ cfg.name = generatePrefix(cfg.name);
704
+ cfg.aliases = cfg.aliases.map((a) => generatePrefix(a));
705
+ }
706
+ for (const [key, value] of cfgEntries) {
707
+ const cfg = value._.config;
708
+ if (cfg.type === "positional") {
709
+ entries.push([key, {
710
+ config: cfg,
711
+ $output: void 0
712
+ }]);
713
+ continue;
714
+ }
715
+ const reservedNames = [
716
+ "--help",
717
+ "-h",
718
+ "--version",
719
+ "-v"
720
+ ];
721
+ const allNames = [cfg.name, ...cfg.aliases];
722
+ for (const name of allNames) {
723
+ const match = reservedNames.find((n) => n === name);
724
+ if (match) throw new BroCliError(`Can't define option '${cfg.name}' - name '${match}' is reserved!`);
725
+ }
726
+ for (const storage of storedNames) {
727
+ if (!storage.find((e) => e === cfg.name)) continue;
728
+ throw new BroCliError(`Can't define option '${cfg.name}' - name is already in use by option '${storage[0]}'!`);
729
+ }
730
+ for (const alias of cfg.aliases) for (const storage of storedNames) {
731
+ if (!storage.find((e) => e === alias)) continue;
732
+ throw new BroCliError(`Can't define option '${cfg.name}' - alias '${alias}' is already in use by option '${storage[0]}'!`);
733
+ }
734
+ const currentNames = [cfg.name, ...cfg.aliases];
735
+ storedNames.push(currentNames);
736
+ currentNames.forEach((name, idx) => {
737
+ if (currentNames.findIndex((e) => e === name) === idx) return;
738
+ throw new BroCliError(`Can't define option '${cfg.name}' - duplicate alias '${name}'!`);
739
+ });
740
+ entries.push([key, {
741
+ config: cfg,
742
+ $output: void 0
743
+ }]);
744
+ }
745
+ return Object.fromEntries(entries);
746
+ };
747
+ var assignParent = (parent, subcommands) => subcommands.forEach((e) => {
748
+ e.parent = parent;
749
+ if (e.subcommands) assignParent(e, e.subcommands);
750
+ });
751
+ var command = (command2) => {
752
+ const allNames = command2.aliases ? [command2.name, ...command2.aliases] : [command2.name];
753
+ const cmd = (0, import_clone.default)(command2);
754
+ if (command2.subcommands && command2.options && Object.values(command2.options).find((opt) => opt._.config.type === "positional")) throw new BroCliError(`Can't define command '${cmd.name}' - command can't have subcommands and positional args at the same time!`);
755
+ if (!command2.handler && !command2.subcommands) throw new BroCliError(`Can't define command '${cmd.name}' - command without subcommands must have a handler present!`);
756
+ cmd.options = command2.options ? validateOptions(command2.options) : void 0;
757
+ cmd.name = cmd.name ?? cmd.aliases?.shift();
758
+ if (!cmd.name) throw new BroCliError(`Can't define command without name!`);
759
+ cmd.aliases = cmd.aliases?.length ? cmd.aliases : void 0;
760
+ if (cmd.name.startsWith("-")) throw new BroCliError(`Can't define command '${cmd.name}' - command name can't start with '-'!`);
761
+ cmd.aliases?.forEach((a) => {
762
+ if (a.startsWith("-")) throw new BroCliError(`Can't define command '${cmd.name}' - command aliases can't start with '-'!`);
763
+ });
764
+ allNames.forEach((n, i) => {
765
+ if (n === "help") throw new BroCliError(`Can't define command '${cmd.name}' - 'help' is a reserved name. If you want to redefine help message - do so in runCli's config.`);
766
+ const lCaseName = n?.toLowerCase();
767
+ if (lCaseName === "0" || lCaseName === "1" || lCaseName === "true" || lCaseName === "false") throw new BroCliError(`Can't define command '${cmd.name}' - '${n}' is a reserved for boolean values name!`);
768
+ if (allNames.findIndex((an) => an === n) !== i) throw new BroCliError(`Can't define command '${cmd.name}' - duplicate alias '${n}'!`);
769
+ });
770
+ if (cmd.subcommands) assignParent(cmd, cmd.subcommands);
771
+ return cmd;
772
+ };
773
+ var getCommandInner = (commands, candidates, args, cliName, cliDescription) => {
774
+ const { data: arg, originalIndex: index } = candidates.shift();
775
+ const command2 = commands.find((c) => {
776
+ return (c.aliases ? [c.name, ...c.aliases] : [c.name]).find((name) => name === arg);
777
+ });
778
+ if (!command2) return {
779
+ command: command2,
780
+ args
781
+ };
782
+ const newArgs = removeByIndex(args, index);
783
+ if (!candidates.length || !command2.subcommands) return {
784
+ command: command2,
785
+ args: newArgs
786
+ };
787
+ const newCandidates = candidates.map((c) => ({
788
+ data: c.data,
789
+ originalIndex: c.originalIndex - 1
790
+ }));
791
+ const subcommand = getCommandInner(command2.subcommands, newCandidates, newArgs, cliName, cliDescription);
792
+ if (!subcommand.command) throw new BroCliError(void 0, {
793
+ type: "error",
794
+ violation: "unknown_subcommand_error",
795
+ name: cliName,
796
+ description: cliDescription,
797
+ command: command2,
798
+ offender: candidates[0].data
799
+ });
800
+ return subcommand;
801
+ };
802
+ var getCommand = (commands, args, cliName, cliDescription) => {
803
+ const candidates = [];
804
+ for (let i = 0; i < args.length; ++i) {
805
+ const arg = args[i];
806
+ if (arg === "--help" || arg === "-h" || arg === "--version" || arg === "-v") {
807
+ const lCaseNext = args[i + 1]?.toLowerCase();
808
+ if (lCaseNext === "0" || lCaseNext === "1" || lCaseNext === "true" || lCaseNext === "false") ++i;
809
+ continue;
810
+ }
811
+ if (arg?.startsWith("-")) {
812
+ if (!arg.includes("=")) ++i;
813
+ continue;
814
+ }
815
+ candidates.push({
816
+ data: arg,
817
+ originalIndex: i
818
+ });
819
+ }
820
+ if (!candidates.length) return {
821
+ command: void 0,
822
+ args
823
+ };
824
+ const firstCandidate = candidates[0];
825
+ if (firstCandidate.data === "help") return {
826
+ command: "help",
827
+ args: removeByIndex(args, firstCandidate.originalIndex)
828
+ };
829
+ const { command: command2, args: argsRes } = getCommandInner(commands, candidates, args, cliName, cliDescription);
830
+ if (!command2) throw new BroCliError(void 0, {
831
+ type: "error",
832
+ violation: "unknown_command_error",
833
+ commands,
834
+ name: cliName,
835
+ description: cliDescription,
836
+ offender: firstCandidate.data
837
+ });
838
+ return {
839
+ command: command2,
840
+ args: argsRes
841
+ };
842
+ };
843
+ var parseArg = (command2, options, positionals, arg, nextArg, cliName, cliDescription) => {
844
+ let data = void 0;
845
+ const argSplit = arg.split("=");
846
+ const hasEq = arg.includes("=");
847
+ const namePart = argSplit.shift();
848
+ const dataPart = hasEq ? argSplit.join("=") : nextArg;
849
+ let lcaseData = dataPart?.toLowerCase();
850
+ let skipNext = !hasEq;
851
+ if (namePart === "--help" || namePart === "-h") return {
852
+ isHelp: true,
853
+ skipNext: !hasEq && nextArg?.startsWith("-") ? false : skipNext
854
+ };
855
+ if (namePart === "--version" || namePart === "-v") return {
856
+ isVersion: true,
857
+ skipNext: !hasEq && nextArg?.startsWith("-") ? false : skipNext
858
+ };
859
+ if (!arg.startsWith("-")) {
860
+ if (!positionals.length) return {};
861
+ const pos = positionals.shift();
862
+ if (pos[1].enumVals && !pos[1].enumVals.find((val) => val === arg)) throw new BroCliError(void 0, {
863
+ type: "error",
864
+ name: cliName,
865
+ description: cliDescription,
866
+ violation: "enum_violation",
867
+ command: command2,
868
+ option: pos[1],
869
+ offender: { dataPart: arg }
870
+ });
871
+ data = arg;
872
+ return {
873
+ data,
874
+ skipNext: false,
875
+ name: pos[0],
876
+ option: pos[1]
877
+ };
878
+ }
879
+ const option = options.find(([optKey, opt]) => {
880
+ const names = [opt.name, ...opt.aliases];
881
+ if (opt.type === "boolean") {
882
+ if (!names.find((name) => name === namePart)) return false;
883
+ if (!hasEq && nextArg?.startsWith("-")) {
884
+ data = true;
885
+ skipNext = false;
886
+ return true;
887
+ }
888
+ if (lcaseData === void 0 || lcaseData === "" || lcaseData === "true" || lcaseData === "1") {
889
+ data = true;
890
+ return true;
891
+ }
892
+ if (lcaseData === "false" || lcaseData === "0") {
893
+ data = false;
894
+ return true;
895
+ }
896
+ if (!hasEq) {
897
+ data = true;
898
+ skipNext = false;
899
+ return true;
900
+ }
901
+ throw new BroCliError(void 0, {
902
+ type: "error",
903
+ name: cliName,
904
+ description: cliDescription,
905
+ violation: "invalid_boolean_syntax",
906
+ option: opt,
907
+ command: command2,
908
+ offender: {
909
+ namePart,
910
+ dataPart
911
+ }
912
+ });
913
+ } else {
914
+ if (!names.find((name) => name === namePart)) return false;
915
+ if (opt.type === "string") {
916
+ if (!hasEq && nextArg === void 0) throw new BroCliError(void 0, {
917
+ type: "error",
918
+ name: cliName,
919
+ description: cliDescription,
920
+ violation: "invalid_string_syntax",
921
+ option: opt,
922
+ command: command2,
923
+ offender: {
924
+ namePart,
925
+ dataPart
926
+ }
927
+ });
928
+ if (opt.enumVals && !opt.enumVals.find((val) => val === dataPart)) throw new BroCliError(void 0, {
929
+ type: "error",
930
+ name: cliName,
931
+ description: cliDescription,
932
+ violation: "enum_violation",
933
+ option: opt,
934
+ command: command2,
935
+ offender: {
936
+ namePart,
937
+ dataPart
938
+ }
939
+ });
940
+ data = dataPart;
941
+ return true;
942
+ }
943
+ if (!hasEq && nextArg === void 0) throw new BroCliError(void 0, {
944
+ type: "error",
945
+ name: cliName,
946
+ description: cliDescription,
947
+ violation: "invalid_number_syntax",
948
+ option: opt,
949
+ command: command2,
950
+ offender: {
951
+ namePart,
952
+ dataPart
953
+ }
954
+ });
955
+ const numData = Number(dataPart);
956
+ if (isNaN(numData)) throw new BroCliError(void 0, {
957
+ type: "error",
958
+ name: cliName,
959
+ description: cliDescription,
960
+ violation: "invalid_number_value",
961
+ option: opt,
962
+ command: command2,
963
+ offender: {
964
+ namePart,
965
+ dataPart
966
+ }
967
+ });
968
+ if (opt.isInt && !isInt(numData)) throw new BroCliError(void 0, {
969
+ type: "error",
970
+ name: cliName,
971
+ description: cliDescription,
972
+ violation: "expected_int",
973
+ option: opt,
974
+ command: command2,
975
+ offender: {
976
+ namePart,
977
+ dataPart
978
+ }
979
+ });
980
+ if (opt.minVal !== void 0 && numData < opt.minVal) throw new BroCliError(void 0, {
981
+ type: "error",
982
+ name: cliName,
983
+ description: cliDescription,
984
+ violation: "below_min",
985
+ option: opt,
986
+ command: command2,
987
+ offender: {
988
+ namePart,
989
+ dataPart
990
+ }
991
+ });
992
+ if (opt.maxVal !== void 0 && numData > opt.maxVal) throw new BroCliError(void 0, {
993
+ type: "error",
994
+ name: cliName,
995
+ description: cliDescription,
996
+ violation: "above_max",
997
+ option: opt,
998
+ command: command2,
999
+ offender: {
1000
+ namePart,
1001
+ dataPart
1002
+ }
1003
+ });
1004
+ data = numData;
1005
+ return true;
1006
+ }
1007
+ });
1008
+ return {
1009
+ data,
1010
+ skipNext,
1011
+ name: option?.[0],
1012
+ option: option?.[1]
1013
+ };
1014
+ };
1015
+ var parseOptions = (command2, args, cliName, cliDescription, omitKeysOfUndefinedOptions) => {
1016
+ const options = command2.options;
1017
+ let noOpts = !options;
1018
+ const optEntries = Object.entries(options ?? {}).map((opt) => [opt[0], opt[1].config]);
1019
+ const nonPositionalEntries = optEntries.filter(([key, opt]) => opt.type !== "positional");
1020
+ const positionalEntries = optEntries.filter(([key, opt]) => opt.type === "positional");
1021
+ const result = {};
1022
+ const missingRequiredArr = [];
1023
+ const unrecognizedArgsArr = [];
1024
+ for (let i = 0; i < args.length; ++i) {
1025
+ const arg = args[i];
1026
+ const nextArg = args[i + 1];
1027
+ const { data, name, option, skipNext, isHelp, isVersion } = parseArg(command2, nonPositionalEntries, positionalEntries, arg, nextArg, cliName, cliDescription);
1028
+ if (!option) unrecognizedArgsArr.push(arg.split("=")[0]);
1029
+ if (skipNext) ++i;
1030
+ if (isHelp) return "help";
1031
+ if (isVersion) return "version";
1032
+ result[name] = data;
1033
+ }
1034
+ for (const [optKey, option] of optEntries) {
1035
+ const data = result[optKey] ?? option.default;
1036
+ if (!omitKeysOfUndefinedOptions) result[optKey] = data;
1037
+ else if (data !== void 0) result[optKey] = data;
1038
+ if (option.isRequired && result[optKey] === void 0) missingRequiredArr.push([option.name, ...option.aliases]);
1039
+ }
1040
+ if (missingRequiredArr.length) throw new BroCliError(void 0, {
1041
+ type: "error",
1042
+ violation: "missing_args_error",
1043
+ name: cliName,
1044
+ description: cliDescription,
1045
+ command: command2,
1046
+ missing: missingRequiredArr
1047
+ });
1048
+ if (unrecognizedArgsArr.length) throw new BroCliError(void 0, {
1049
+ type: "error",
1050
+ violation: "unrecognized_args_error",
1051
+ name: cliName,
1052
+ description: cliDescription,
1053
+ command: command2,
1054
+ unrecognized: unrecognizedArgsArr
1055
+ });
1056
+ return noOpts ? void 0 : result;
1057
+ };
1058
+ var parseGlobals = (command2, globals, args, cliName, cliDescription, omitKeysOfUndefinedOptions, ignoreSpecialCases) => {
1059
+ if (!globals) return void 0;
1060
+ const optEntries = Object.entries(globals).map((opt) => [opt[0], opt[1].config]);
1061
+ const result = {};
1062
+ const missingRequiredArr = [];
1063
+ for (let i = 0; i < args.length; ++i) {
1064
+ const arg = args[i];
1065
+ const nextArg = args[i + 1];
1066
+ const { data, name, option, skipNext, isHelp, isVersion } = parseArg(command2, optEntries, [], arg, nextArg, cliName, cliDescription);
1067
+ if (skipNext) ++i;
1068
+ if (!ignoreSpecialCases) {
1069
+ if (isHelp) return "help";
1070
+ if (isVersion) return "version";
1071
+ }
1072
+ if (!option) continue;
1073
+ delete args[i];
1074
+ if (skipNext) delete args[i - 1];
1075
+ result[name] = data;
1076
+ }
1077
+ for (const [optKey, option] of optEntries) {
1078
+ const data = result[optKey] ?? option.default;
1079
+ if (!omitKeysOfUndefinedOptions) result[optKey] = data;
1080
+ else if (data !== void 0) result[optKey] = data;
1081
+ if (option.isRequired && result[optKey] === void 0) missingRequiredArr.push([option.name, ...option.aliases]);
1082
+ }
1083
+ if (missingRequiredArr.length) throw new BroCliError(void 0, {
1084
+ type: "error",
1085
+ violation: "missing_args_error",
1086
+ name: cliName,
1087
+ description: cliDescription,
1088
+ command: command2,
1089
+ missing: missingRequiredArr
1090
+ });
1091
+ return Object.keys(result).length ? result : void 0;
1092
+ };
1093
+ var getCommandNameWithParents = (command2) => command2.parent ? `${getCommandNameWithParents(command2.parent)} ${command2.name}` : command2.name;
1094
+ var validateCommands = (commands, parent) => {
1095
+ const storedNames = {};
1096
+ for (const cmd of commands) {
1097
+ const storageVals = Object.values(storedNames);
1098
+ for (const storage of storageVals) {
1099
+ if (!storage.find((e) => e === cmd.name)) continue;
1100
+ throw new BroCliError(`Can't define command '${getCommandNameWithParents(cmd)}': name is already in use by command '${parent ? `${getCommandNameWithParents(parent)} ` : ""}${storage[0]}'!`);
1101
+ }
1102
+ if (cmd.aliases) for (const alias of cmd.aliases) for (const storage of storageVals) {
1103
+ if (!storage.find((e) => e === alias)) continue;
1104
+ throw new BroCliError(`Can't define command '${getCommandNameWithParents(cmd)}': alias '${alias}' is already in use by command '${parent ? `${getCommandNameWithParents(parent)} ` : ""}${storage[0]}'!`);
1105
+ }
1106
+ storedNames[cmd.name] = cmd.aliases ? [cmd.name, ...cmd.aliases] : [cmd.name];
1107
+ if (cmd.subcommands) cmd.subcommands = validateCommands(cmd.subcommands, cmd);
1108
+ }
1109
+ return commands;
1110
+ };
1111
+ var validateGlobalsInner = (commands, globals) => {
1112
+ for (const c of commands) {
1113
+ const { options } = c;
1114
+ if (!options) continue;
1115
+ for (const { config: opt } of Object.values(options)) {
1116
+ if (globals.find(({ config: g }) => g.name === opt.name)) throw new BroCliError(`Global options overlap with option '${opt.name}' of command '${getCommandNameWithParents(c)}' on name`);
1117
+ let foundAliasOverlap = opt.aliases.find((a) => globals.find(({ config: g }) => g.name === a)) ?? globals.find(({ config: g }) => opt.aliases.find((a) => a === g.name));
1118
+ if (!foundAliasOverlap) for (const { config: g } of globals) {
1119
+ foundAliasOverlap = g.aliases.find((gAlias) => opt.name === gAlias);
1120
+ if (foundAliasOverlap) break;
1121
+ }
1122
+ if (!foundAliasOverlap) for (const { config: g } of globals) {
1123
+ foundAliasOverlap = g.aliases.find((gAlias) => opt.aliases.find((a) => a === gAlias));
1124
+ if (foundAliasOverlap) break;
1125
+ }
1126
+ if (foundAliasOverlap) throw new BroCliError(`Global options overlap with option '${opt.name}' of command '${getCommandNameWithParents(c)}' on alias '${foundAliasOverlap}'`);
1127
+ }
1128
+ if (c.subcommands) validateGlobalsInner(c.subcommands, globals);
1129
+ }
1130
+ };
1131
+ var validateGlobals = (commands, globals) => {
1132
+ if (!globals) return;
1133
+ validateGlobalsInner(commands, Object.values(globals));
1134
+ };
1135
+ var removeByIndex = (arr, idx) => [...arr.slice(0, idx), ...arr.slice(idx + 1, arr.length)];
1136
+ var run = async (commands, config) => {
1137
+ const eventHandler = config?.theme ? eventHandlerWrapper(config.theme) : defaultEventHandler;
1138
+ const argSource = config?.argSource ?? process.argv;
1139
+ const version = config?.version;
1140
+ const help = config?.help;
1141
+ const omitKeysOfUndefinedOptions = config?.omitKeysOfUndefinedOptions ?? false;
1142
+ const cliName = config?.name;
1143
+ const cliDescription = config?.description;
1144
+ const globals = config?.globals;
1145
+ let prepassError;
1146
+ let processedGlobals;
1147
+ let processedCmds;
1148
+ const args = argSource.slice(2, argSource.length);
1149
+ try {
1150
+ processedCmds = validateCommands(commands);
1151
+ processedGlobals = globals ? validateOptions(globals) : void 0;
1152
+ if (processedGlobals) validateGlobals(processedCmds, processedGlobals);
1153
+ } catch (e) {
1154
+ prepassError = e;
1155
+ processedCmds = [];
1156
+ }
1157
+ let preparseError;
1158
+ let _preparsedGlobals;
1159
+ const preparsedGlobals = () => {
1160
+ if (preparseError) throw preparseError;
1161
+ return _preparsedGlobals;
1162
+ };
1163
+ try {
1164
+ _preparsedGlobals = parseGlobals("globals", processedGlobals, [...args], cliName, cliDescription, omitKeysOfUndefinedOptions, true);
1165
+ } catch (e) {
1166
+ preparseError = e;
1167
+ }
1168
+ try {
1169
+ if (prepassError) throw prepassError;
1170
+ if (!args.length) return help !== void 0 ? await executeOrLog(help, preparsedGlobals()) : await eventHandler({
1171
+ type: "global_help",
1172
+ description: cliDescription,
1173
+ name: cliName,
1174
+ commands: processedCmds,
1175
+ globals: processedGlobals
1176
+ }, preparsedGlobals());
1177
+ const helpIndex = args.findIndex((arg) => arg === "--help" || arg === "-h");
1178
+ if (helpIndex !== -1 && (helpIndex > 0 ? args[helpIndex - 1]?.startsWith("-") && !args[helpIndex - 1].includes("=") ? false : true : true)) {
1179
+ const command3 = getCommand(processedCmds, args, cliName, cliDescription).command;
1180
+ if (typeof command3 === "object") return command3.help !== void 0 ? await executeOrLog(command3.help) : await eventHandler({
1181
+ type: "command_help",
1182
+ description: cliDescription,
1183
+ name: cliName,
1184
+ command: command3,
1185
+ globals: processedGlobals
1186
+ }, preparsedGlobals());
1187
+ else return help !== void 0 ? await executeOrLog(help, preparsedGlobals()) : await eventHandler({
1188
+ type: "global_help",
1189
+ description: cliDescription,
1190
+ name: cliName,
1191
+ commands: processedCmds,
1192
+ globals: processedGlobals
1193
+ }, preparsedGlobals());
1194
+ }
1195
+ const versionIndex = args.findIndex((arg) => arg === "--version" || arg === "-v");
1196
+ if (versionIndex !== -1 && (versionIndex > 0 ? args[versionIndex - 1]?.startsWith("-") ? false : true : true)) return version !== void 0 ? await executeOrLog(version, preparsedGlobals()) : await eventHandler({
1197
+ type: "version",
1198
+ name: cliName,
1199
+ description: cliDescription
1200
+ }, preparsedGlobals());
1201
+ const { command: command2, args: newArgs } = getCommand(processedCmds, args, cliName, cliDescription);
1202
+ if (!command2) return help !== void 0 ? await executeOrLog(help, preparsedGlobals()) : await eventHandler({
1203
+ type: "global_help",
1204
+ description: cliDescription,
1205
+ name: cliName,
1206
+ commands: processedCmds,
1207
+ globals: processedGlobals
1208
+ }, preparsedGlobals());
1209
+ if (command2 === "help") {
1210
+ let helpCommand;
1211
+ let newestArgs = newArgs;
1212
+ do {
1213
+ const res = getCommand(processedCmds, newestArgs, cliName, cliDescription);
1214
+ helpCommand = res.command;
1215
+ newestArgs = res.args;
1216
+ } while (helpCommand === "help");
1217
+ return helpCommand ? helpCommand.help !== void 0 ? await executeOrLog(helpCommand.help) : await eventHandler({
1218
+ type: "command_help",
1219
+ description: cliDescription,
1220
+ name: cliName,
1221
+ command: helpCommand,
1222
+ globals: processedGlobals
1223
+ }, preparsedGlobals()) : help !== void 0 ? await executeOrLog(help, preparsedGlobals()) : await eventHandler({
1224
+ type: "global_help",
1225
+ description: cliDescription,
1226
+ name: cliName,
1227
+ commands: processedCmds,
1228
+ globals: processedGlobals
1229
+ }, preparsedGlobals());
1230
+ }
1231
+ const gOptionResult = parseGlobals(command2, processedGlobals, newArgs, cliName, cliDescription, omitKeysOfUndefinedOptions);
1232
+ const optionResult = gOptionResult && (gOptionResult === "help" || gOptionResult === "version") ? gOptionResult : parseOptions(command2, globals ? newArgs.filter((a) => a !== void 0) : newArgs, cliName, cliDescription, omitKeysOfUndefinedOptions);
1233
+ if (optionResult === "help" || gOptionResult === "help") return command2.help !== void 0 ? await executeOrLog(command2.help) : await eventHandler({
1234
+ type: "command_help",
1235
+ description: cliDescription,
1236
+ name: cliName,
1237
+ command: command2,
1238
+ globals: processedGlobals
1239
+ }, preparsedGlobals());
1240
+ if (optionResult === "version" || gOptionResult === "version") return version !== void 0 ? await executeOrLog(version, preparsedGlobals()) : await eventHandler({
1241
+ type: "version",
1242
+ name: cliName,
1243
+ description: cliDescription
1244
+ }, preparsedGlobals());
1245
+ if (command2.handler) {
1246
+ if (config?.hook) await config.hook("before", command2, gOptionResult);
1247
+ await command2.handler(command2.transform ? await command2.transform(optionResult) : optionResult);
1248
+ if (config?.hook) await config.hook("after", command2, gOptionResult);
1249
+ return;
1250
+ } else return command2.help !== void 0 ? await executeOrLog(command2.help) : await eventHandler({
1251
+ type: "command_help",
1252
+ description: cliDescription,
1253
+ name: cliName,
1254
+ command: command2,
1255
+ globals: processedGlobals
1256
+ }, preparsedGlobals());
1257
+ } catch (e) {
1258
+ if (e instanceof BroCliError) if (e.event) await eventHandler(e.event, preparsedGlobals());
1259
+ else if (!config?.noExit) console.error(e.message);
1260
+ else return e.message;
1261
+ else await eventHandler({
1262
+ type: "error",
1263
+ violation: "unknown_error",
1264
+ name: cliName,
1265
+ description: cliDescription,
1266
+ error: e
1267
+ }, preparsedGlobals());
1268
+ if (!config?.noExit) process.exit(1);
1269
+ return;
1270
+ }
1271
+ };
1272
+ var OptionBuilderBase = class _OptionBuilderBase {
1273
+ _;
1274
+ config = () => this._.config;
1275
+ constructor(config) {
1276
+ this._ = {
1277
+ config: config ?? {
1278
+ aliases: [],
1279
+ type: "string"
1280
+ },
1281
+ $output: void 0
1282
+ };
1283
+ }
1284
+ string(name) {
1285
+ return new _OptionBuilderBase({
1286
+ ...this.config(),
1287
+ type: "string",
1288
+ name
1289
+ });
1290
+ }
1291
+ number(name) {
1292
+ return new _OptionBuilderBase({
1293
+ ...this.config(),
1294
+ type: "number",
1295
+ name
1296
+ });
1297
+ }
1298
+ boolean(name) {
1299
+ return new _OptionBuilderBase({
1300
+ ...this.config(),
1301
+ type: "boolean",
1302
+ name
1303
+ });
1304
+ }
1305
+ positional(displayName) {
1306
+ return new _OptionBuilderBase({
1307
+ ...this.config(),
1308
+ type: "positional",
1309
+ name: displayName
1310
+ });
1311
+ }
1312
+ alias(...aliases) {
1313
+ return new _OptionBuilderBase({
1314
+ ...this.config(),
1315
+ aliases
1316
+ });
1317
+ }
1318
+ desc(description) {
1319
+ return new _OptionBuilderBase({
1320
+ ...this.config(),
1321
+ description
1322
+ });
1323
+ }
1324
+ hidden() {
1325
+ return new _OptionBuilderBase({
1326
+ ...this.config(),
1327
+ isHidden: true
1328
+ });
1329
+ }
1330
+ required() {
1331
+ return new _OptionBuilderBase({
1332
+ ...this.config(),
1333
+ isRequired: true
1334
+ });
1335
+ }
1336
+ default(value) {
1337
+ const config = this.config();
1338
+ const enums = config.enumVals;
1339
+ if (enums && !enums.find((v) => value === v)) throw new Error(`Option enums [ ${enums.join(", ")} ] are incompatible with default value ${value}`);
1340
+ return new _OptionBuilderBase({
1341
+ ...config,
1342
+ default: value
1343
+ });
1344
+ }
1345
+ enum(...values) {
1346
+ const config = this.config();
1347
+ const defaultVal = config.default;
1348
+ if (defaultVal !== void 0 && !values.find((v) => defaultVal === v)) throw new Error(`Option enums [ ${values.join(", ")} ] are incompatible with default value ${defaultVal}`);
1349
+ return new _OptionBuilderBase({
1350
+ ...config,
1351
+ enumVals: values
1352
+ });
1353
+ }
1354
+ min(value) {
1355
+ const config = this.config();
1356
+ const maxVal = config.maxVal;
1357
+ if (maxVal !== void 0 && maxVal < value) throw new BroCliError("Unable to define option's min value to be higher than max value!");
1358
+ return new _OptionBuilderBase({
1359
+ ...config,
1360
+ minVal: value
1361
+ });
1362
+ }
1363
+ max(value) {
1364
+ const config = this.config();
1365
+ const minVal = config.minVal;
1366
+ if (minVal !== void 0 && minVal > value) throw new BroCliError("Unable to define option's max value to be lower than min value!");
1367
+ return new _OptionBuilderBase({
1368
+ ...config,
1369
+ maxVal: value
1370
+ });
1371
+ }
1372
+ int() {
1373
+ return new _OptionBuilderBase({
1374
+ ...this.config(),
1375
+ isInt: true
1376
+ });
1377
+ }
1378
+ };
1379
+ function string(name) {
1380
+ return typeof name === "string" ? new OptionBuilderBase().string(name) : new OptionBuilderBase().string();
1381
+ }
1382
+ function boolean(name) {
1383
+ return typeof name === "string" ? new OptionBuilderBase().boolean(name) : new OptionBuilderBase().boolean();
1384
+ }
1385
+ function positional(displayName) {
1386
+ return typeof displayName === "string" ? new OptionBuilderBase().positional(displayName) : new OptionBuilderBase().positional();
1387
+ }
1388
+ //#endregion
1389
+ //#region src/cli/commands/_utils.ts
1390
+ function resolveWorkspaceRoot(root) {
1391
+ return root != null ? resolve(process$1.cwd(), root) : getWorkspaceRoot();
1392
+ }
1393
+ async function loadConfig(params) {
1394
+ let { workspaceRoot, require = false } = params;
1395
+ let config = await loadBuildConfig(workspaceRoot);
1396
+ if (!config && require) throw new Error(`Config not found at ${workspaceRoot}`);
1397
+ return config ?? null;
1398
+ }
1399
+ //#endregion
1400
+ //#region src/cli/commands/build.ts
1401
+ async function resolveViteConfig(workspaceRoot, configured) {
1402
+ if (configured != null) return configured;
1403
+ if (await fileExists(join(workspaceRoot, "vite.config.ts"))) return "vite.config.ts";
1404
+ if (await fileExists(join(workspaceRoot, "vite.config.js"))) return "vite.config.js";
1405
+ return "vite.config.ts";
1406
+ }
1407
+ /**
1408
+ * build a single package using vite
1409
+ *
1410
+ * tiny wrapper on top of `vite build`
1411
+ */
1412
+ async function buildPackage(params) {
1413
+ let config = await loadConfig({ workspaceRoot: params.workspaceRoot });
1414
+ let workspacePackages = params.workspace ?? await collectPackageJsons(params.workspaceRoot, true);
1415
+ let viteConfig = await resolveViteConfig(params.workspaceRoot, config?.viteConfig);
1416
+ let packageRoot = findPackageByName(workspacePackages, params.packageName).path;
1417
+ let env = {
1418
+ ...process$1.env,
1419
+ __YOROZU_INTERNAL_PACKAGES_LIST: JSON.stringify(workspacePackages)
1420
+ };
1421
+ if (params.fixedVersion != null) env.__YOROZU_INTERNAL_FIXED_VERSION = params.fixedVersion;
1422
+ await exec([
1423
+ "npx",
1424
+ "vite",
1425
+ "build",
1426
+ "--config",
1427
+ join(params.workspaceRoot, viteConfig)
1428
+ ], {
1429
+ env,
1430
+ cwd: packageRoot,
1431
+ stdio: "inherit",
1432
+ throwOnError: true
1433
+ });
1434
+ }
1435
+ /**
1436
+ * build every npm-publishable workspace package in publish order
1437
+ */
1438
+ async function buildWorkspace(params) {
1439
+ let workspace = await collectPackageJsons(params.workspaceRoot, true);
1440
+ let ordered = filterPackageJsonsForPublish(sortWorkspaceByPublishOrder(workspace.filter((pkg) => !pkg.root)), "npm");
1441
+ for (let pkg of ordered) {
1442
+ let packageName = asNonNull(pkg.json.name);
1443
+ info(`building ${packageName}`);
1444
+ await buildPackage({
1445
+ workspaceRoot: params.workspaceRoot,
1446
+ workspace,
1447
+ packageName,
1448
+ fixedVersion: params.fixedVersion
1449
+ });
1450
+ }
1451
+ }
1452
+ var buildPackageCli = command({
1453
+ name: "build",
1454
+ desc: "build a package",
1455
+ options: {
1456
+ config: string("config").desc("path to the build.config.js file"),
1457
+ root: string().desc("path to the root of the workspace (default: cwd)"),
1458
+ packageName: positional("package-name").desc("name of the package to build (or :all to build the entire workspace)").default(":all"),
1459
+ fixedVersion: string("fixed-version").desc("fixed version for every managed package (useful for pre-releases)")
1460
+ },
1461
+ handler: async (args) => {
1462
+ let workspaceRoot = args.root != null ? resolve(process$1.cwd(), args.root) : getWorkspaceRoot();
1463
+ if (args.packageName === ":all") {
1464
+ await buildWorkspace({
1465
+ workspaceRoot,
1466
+ fixedVersion: args.fixedVersion
1467
+ });
1468
+ return;
1469
+ }
1470
+ await buildPackage({
1471
+ workspaceRoot,
1472
+ packageName: args.packageName,
1473
+ configPath: args.config,
1474
+ fixedVersion: args.fixedVersion
1475
+ });
1476
+ }
1477
+ });
1478
+ //#endregion
1479
+ //#region src/npm/npm-api.ts
1480
+ var USER_AGENT$1 = "@yorozu/build";
1481
+ var DEFAULT_REGISTRY = "https://registry.npmjs.org";
1482
+ var REQUEST_TIMEOUT_MS$1 = 3e4;
1483
+ var NPM_PACKAGE_NAME_REGEX = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
1484
+ async function npmCheckVersion(params) {
1485
+ let url = `${(params.registry ?? DEFAULT_REGISTRY).replace(/\/$/, "")}/${params.package}/${params.version}`;
1486
+ let res = await fetch(url, {
1487
+ headers: { "User-Agent": USER_AGENT$1 },
1488
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS$1)
1489
+ });
1490
+ if (res.body) res.body.cancel();
1491
+ return res.status === 200;
1492
+ }
1493
+ //#endregion
1494
+ //#region src/cli/commands/publish.ts
1495
+ var DEFAULT_REGISTRY_URL = "https://registry.npmjs.org";
1496
+ function normalizeNpmAuthToken(token) {
1497
+ if (token == null) return void 0;
1498
+ let trimmed = token.trim();
1499
+ return trimmed === "" ? void 0 : trimmed;
1500
+ }
1501
+ function formatNpmAuthRc(registryUrl, token) {
1502
+ return `${new URL(":_authToken", registryUrl).href.replace(/^https:\/\//, "//")}=${token}\n`;
1503
+ }
1504
+ async function prepareNpmPublishAuth(params) {
1505
+ let token = normalizeNpmAuthToken(params.token);
1506
+ if (token == null) return {
1507
+ extraArgs: [],
1508
+ extraEnv: {},
1509
+ cleanup: async () => {}
1510
+ };
1511
+ let dir = await fsp.mkdtemp(join(tmpdir(), "yorozu-npm-auth-"));
1512
+ let npmrcPath = join(dir, ".npmrc");
1513
+ await fsp.writeFile(npmrcPath, formatNpmAuthRc(params.registryUrl, token), { mode: 384 });
1514
+ return {
1515
+ extraArgs: ["--userconfig", npmrcPath],
1516
+ extraEnv: {
1517
+ NPM_TOKEN: token,
1518
+ NODE_AUTH_TOKEN: token
1519
+ },
1520
+ cleanup: async () => {
1521
+ await fsp.rm(dir, {
1522
+ recursive: true,
1523
+ force: true
1524
+ });
1525
+ }
1526
+ };
1527
+ }
1528
+ async function publishPackages(params) {
1529
+ let { workspaceRoot = process$1.cwd(), workspace = await collectPackageJsons(workspaceRoot, true), packages, unpublishExisting = false, skipVersionCheck = false, registryUrl = DEFAULT_REGISTRY_URL, token, distDir = "dist", publishArgs = [], dryRun, withTarballs, withBuild, fixedVersion, noProvenance = false } = params;
1530
+ let ordered = filterPackageJsonsForPublish(sortWorkspaceByPublishOrder(workspace.filter((pkg) => !pkg.root)), "npm");
1531
+ let toPublish = packages.length === 1 && packages[0] === ":all" ? ordered : ordered.filter((pkg) => packages.includes(asNonNull(pkg.json.name)));
1532
+ let failed = [];
1533
+ let tarballs = [];
1534
+ let auth = await prepareNpmPublishAuth({
1535
+ token: dryRun ? void 0 : token,
1536
+ registryUrl
1537
+ });
1538
+ let npmEnv = {
1539
+ ...process$1.env,
1540
+ ...auth.extraEnv
1541
+ };
1542
+ try {
1543
+ if (!dryRun) await exec([
1544
+ "npm",
1545
+ ...auth.extraArgs,
1546
+ "whoami",
1547
+ "--registry",
1548
+ registryUrl
1549
+ ], {
1550
+ throwOnError: true,
1551
+ env: npmEnv
1552
+ });
1553
+ if (!noProvenance && isRunningInGithubActions() && Boolean(process$1.env.ACTIONS_ID_TOKEN_REQUEST_URL) && registryUrl === DEFAULT_REGISTRY_URL) {
1554
+ if (!publishArgs.some((it) => it.startsWith("--provenance"))) publishArgs.push("--provenance");
1555
+ }
1556
+ for (let pkg of toPublish) {
1557
+ let pkgVersion = fixedVersion ?? asNonNull(pkg.json.version);
1558
+ if (!dryRun && !skipVersionCheck && await npmCheckVersion({
1559
+ registry: registryUrl,
1560
+ package: asNonNull(pkg.json.name),
1561
+ version: pkgVersion
1562
+ })) if (unpublishExisting) await exec([
1563
+ "npm",
1564
+ ...auth.extraArgs,
1565
+ "unpublish",
1566
+ "--force",
1567
+ "--registry",
1568
+ registryUrl,
1569
+ `${asNonNull(pkg.json.name)}@${pkgVersion}`
1570
+ ], {
1571
+ stdio: "inherit",
1572
+ env: npmEnv
1573
+ });
1574
+ else {
1575
+ info(`Skipping ${pkg.json.name}@${pkgVersion} because it is already published`);
1576
+ continue;
1577
+ }
1578
+ if (withBuild) if (pkg.json.scripts?.build !== void 0) {
1579
+ if ((await exec([
1580
+ "npm",
1581
+ "run",
1582
+ "build"
1583
+ ], {
1584
+ cwd: join(pkg.path),
1585
+ stdio: "inherit"
1586
+ })).exitCode !== 0) {
1587
+ info(`failed to build ${pkg.json.name}`);
1588
+ failed.push(asNonNull(pkg.json.name));
1589
+ continue;
1590
+ }
1591
+ } else try {
1592
+ await buildPackage({
1593
+ workspaceRoot,
1594
+ workspace,
1595
+ packageName: asNonNull(pkg.json.name),
1596
+ fixedVersion
1597
+ });
1598
+ } catch (err) {
1599
+ info(`failed to build ${pkg.json.name}:`);
1600
+ error(err instanceof Error ? err : new Error(String(err)));
1601
+ failed.push(asNonNull(pkg.json.name));
1602
+ continue;
1603
+ }
1604
+ let fullDistDir = join(pkg.path, distDir);
1605
+ if (fixedVersion != null) {
1606
+ let distPkgJsonPath = join(fullDistDir, "package.json");
1607
+ let pkgJson = await parsePackageJsonFile(distPkgJsonPath);
1608
+ pkgJson.version = fixedVersion;
1609
+ await fsp.writeFile(distPkgJsonPath, JSON.stringify(pkgJson, null, 4));
1610
+ }
1611
+ info(`publishing ${pkg.json.name}@${pkgVersion}`);
1612
+ if (pkg.json.name?.includes("/")) {
1613
+ if (!publishArgs.some((it) => it.startsWith("--access"))) publishArgs.push("--access=public");
1614
+ }
1615
+ if ((await exec([
1616
+ "npm",
1617
+ ...auth.extraArgs,
1618
+ "publish",
1619
+ "--registry",
1620
+ registryUrl,
1621
+ ...dryRun ? ["--dry-run"] : ["-q"],
1622
+ ...publishArgs
1623
+ ], {
1624
+ cwd: fullDistDir,
1625
+ stdio: "inherit",
1626
+ env: npmEnv
1627
+ })).exitCode !== 0) failed.push(asNonNull(pkg.json.name));
1628
+ if (withTarballs) {
1629
+ let tar = await exec([
1630
+ "npm",
1631
+ "pack",
1632
+ "-q"
1633
+ ], { cwd: fullDistDir });
1634
+ if (tar.exitCode !== 0) error(new Error(tar.stderr));
1635
+ else tarballs.push(join(fullDistDir, tar.stdout.trim()));
1636
+ }
1637
+ }
1638
+ return {
1639
+ failed,
1640
+ tarballs
1641
+ };
1642
+ } finally {
1643
+ await auth.cleanup();
1644
+ }
1645
+ }
1646
+ var publishPackagesCli = command({
1647
+ name: "publish",
1648
+ desc: "publish packages to npm",
1649
+ options: {
1650
+ root: string().desc("path to the root of the workspace (default: cwd)"),
1651
+ unpublishExisting: boolean("unpublish-existing").desc("whether to unpublish if the version is already published (only available for certain registries, won't work with registry.npmjs.org)"),
1652
+ skipVersionCheck: boolean("skip-version-check").desc("whether to skip checking if the version is already published"),
1653
+ registryUrl: string("registry").desc("URL of the registry to publish to"),
1654
+ token: string("token").desc("token to use for publishing (passed via env and a temporary local .npmrc, never the global config)"),
1655
+ distDir: string("dist-dir").desc("directory to publish from, relative to package root (default: dist)"),
1656
+ dryRun: boolean("dry-run").desc("whether to skip publishing and only print what is going to happen"),
1657
+ publishArgs: string("publish-args").desc("arguments to pass to `npm publish`"),
1658
+ packages: positional("packages").desc("name of the packages to publish (comma-separated, or :all to publish the entire workspace)").default(":all"),
1659
+ withTarballs: boolean("with-tarballs").desc("whether to generate tarballs in the dist directory using `npm pack` (doesn't work with jsr)"),
1660
+ withBuild: boolean("with-build").desc("whether to build the package before publishing using `build` npm script (or defaulting to building using yorozu-build if one is not found)"),
1661
+ fixedVersion: string("fixed-version").desc("fixed version for every managed package (useful for pre-releases)"),
1662
+ noProvenance: boolean("no-provenance").desc("version to NOT use provenance even when it should be possible")
1663
+ },
1664
+ handler: async (options) => {
1665
+ let { failed, tarballs } = await publishPackages({
1666
+ ...options,
1667
+ workspaceRoot: options.root != null ? resolve(process$1.cwd(), options.root) : getWorkspaceRoot(),
1668
+ packages: options.packages.split(","),
1669
+ publishArgs: options.publishArgs?.split(" ")
1670
+ });
1671
+ if (failed.length > 0) {
1672
+ info("failed to publish:");
1673
+ for (let pkg of failed) info(` ${pkg}`);
1674
+ process$1.exit(1);
1675
+ }
1676
+ if (tarballs.length > 0) if (isRunningInGithubActions()) {
1677
+ info("written paths to tarballs to `tarballs` output");
1678
+ writeGithubActionsOutput("tarballs", tarballs.join(","));
1679
+ } else {
1680
+ info("tarballs generated:");
1681
+ for (let tar of tarballs) info(` ${tar}`);
1682
+ }
1683
+ }
1684
+ });
1685
+ //#endregion
1686
+ //#region src/cli/commands/docs.ts
1687
+ var CUSTOM_ROOT_FIELDS = ["includePackages", "excludePackages"];
1688
+ var DEFAULT_CONFIG = {
1689
+ includeVersion: true,
1690
+ validation: {
1691
+ notExported: true,
1692
+ invalidLink: true,
1693
+ notDocumented: false
1694
+ },
1695
+ excludePrivate: true,
1696
+ excludeExternals: true,
1697
+ excludeInternal: true,
1698
+ exclude: [
1699
+ "**/*/node_modules",
1700
+ "**/*.unit.ts",
1701
+ "**/*.test.ts",
1702
+ "**/*.test-utils.ts"
1703
+ ]
1704
+ };
1705
+ var YorozuTypedocReader = class {
1706
+ name = "@yorozu/build";
1707
+ order = 0;
1708
+ supportsPackages = true;
1709
+ _workspace;
1710
+ _rootConfig;
1711
+ constructor(workspaceRoot) {
1712
+ this.workspaceRoot = workspaceRoot;
1713
+ }
1714
+ _forwardOptions(options, config, cwd) {
1715
+ for (let [key, val] of Object.entries(config)) {
1716
+ if (CUSTOM_ROOT_FIELDS.includes(key)) continue;
1717
+ options.setValue(key, val, cwd);
1718
+ }
1719
+ }
1720
+ async read(options, _logger, cwd, _usedFile) {
1721
+ if (cwd === this.workspaceRoot) {
1722
+ let config = await loadBuildConfig(cwd);
1723
+ this._rootConfig = config;
1724
+ let data = config?.typedoc;
1725
+ if (data != null) this._forwardOptions(options, data, cwd);
1726
+ options.setValue("entryPointStrategy", "packages");
1727
+ this._workspace = await collectPackageJsons(cwd);
1728
+ let entrypoints = [];
1729
+ for (let pkg of this._workspace) {
1730
+ let pkgName = asNonNull(pkg.json.name);
1731
+ if (data?.includePackages && !data.includePackages.includes(pkgName)) continue;
1732
+ if (data?.excludePackages?.includes(pkgName)) continue;
1733
+ if (pkg.json.exports == null && !data?.includePackages?.includes(pkgName)) continue;
1734
+ entrypoints.push(pkg.path);
1735
+ }
1736
+ options.setValue("entryPoints", entrypoints, cwd);
1737
+ return;
1738
+ }
1739
+ let rootConfig = asNonNull(this._rootConfig);
1740
+ if (rootConfig.typedoc != null) this._forwardOptions(options, rootConfig.typedoc, cwd);
1741
+ let pkg = asNonNull(this._workspace?.find((item) => item.path.replace(/\/$/, "") === cwd.replace(/\/$/, "")));
1742
+ let pkgConfig = await loadBuildConfig(cwd);
1743
+ let hookContext = {
1744
+ outDir: "",
1745
+ packageDir: pkg.path,
1746
+ packageName: asNonNull(pkg.json.name),
1747
+ packageJson: pkg.json,
1748
+ jsr: false,
1749
+ typedoc: true
1750
+ };
1751
+ pkgConfig?.preparePackageJson?.(hookContext);
1752
+ let { entrypoints } = processPackageJson({
1753
+ packageJson: pkg.json,
1754
+ onlyEntrypoints: true
1755
+ });
1756
+ options.setValue("entryPoints", Object.values(Object.fromEntries(entrypoints)), cwd);
1757
+ if (!pkgConfig?.typedoc) return;
1758
+ let data = pkgConfig.typedoc;
1759
+ if (typeof data === "function") data = data(options.getRawValues());
1760
+ this._forwardOptions(options, data, cwd);
1761
+ }
1762
+ };
1763
+ async function generateDocs(params) {
1764
+ let app = await td.Application.bootstrapWithPlugins(DEFAULT_CONFIG, [
1765
+ new YorozuTypedocReader(params.workspaceRoot),
1766
+ new td.TSConfigReader(),
1767
+ new td.TypeDocReader()
1768
+ ]);
1769
+ let project = await app.convert();
1770
+ if (!project) throw new Error("Could not convert to typedoc project");
1771
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) throw new Error("There were warnings while converting the project");
1772
+ let preValidationWarnCount = app.logger.warningCount;
1773
+ app.validate(project);
1774
+ let hadValidationWarnings = app.logger.warningCount !== preValidationWarnCount;
1775
+ if (app.logger.hasErrors()) throw new Error("There were errors while validating the project");
1776
+ if (hadValidationWarnings && (app.options.getValue("treatWarningsAsErrors") || app.options.getValue("treatValidationWarningsAsErrors"))) throw new Error("There were warnings while validating the project");
1777
+ if (app.options.getValue("emit") === "none") return;
1778
+ await app.generateOutputs(project);
1779
+ if (app.logger.hasErrors()) throw new Error("There were errors while generating the outputs");
1780
+ if (app.options.getValue("treatWarningsAsErrors") && app.logger.hasWarnings()) throw new Error("There were warnings while generating the outputs");
1781
+ }
1782
+ var generateDocsCli = command({
1783
+ name: "docs",
1784
+ desc: "generate docs using typedoc",
1785
+ options: { root: string().desc("path to the root of the workspace (default: cwd)") },
1786
+ handler: async (args) => {
1787
+ await generateDocs({ workspaceRoot: resolveWorkspaceRoot(args.root) });
1788
+ }
1789
+ });
1790
+ //#endregion
1791
+ //#region src/cli/commands/gen-deps-graph.ts
1792
+ async function generateDepsGraph(params) {
1793
+ let { workspaceRoot, includeRoot = false, includeExternal = false } = params;
1794
+ let pjs = await collectPackageJsons(workspaceRoot, includeRoot);
1795
+ let workspacePackages = /* @__PURE__ */ new Set();
1796
+ let commonPrefix;
1797
+ for (let { json: pj } of pjs) {
1798
+ if (pj.name === void 0) continue;
1799
+ workspacePackages.add(pj.name);
1800
+ let [org, name] = pj.name.split("/");
1801
+ if (!name) {
1802
+ commonPrefix = void 0;
1803
+ break;
1804
+ }
1805
+ if (commonPrefix === void 0) commonPrefix = org;
1806
+ else if (commonPrefix !== org) {
1807
+ commonPrefix = void 0;
1808
+ break;
1809
+ }
1810
+ }
1811
+ const getName = (name) => {
1812
+ if (commonPrefix !== void 0) {
1813
+ let [org, pkg] = name.split("/");
1814
+ if (org === commonPrefix) return pkg;
1815
+ }
1816
+ return name;
1817
+ };
1818
+ let lines = [];
1819
+ for (let { json: pj } of pjs) {
1820
+ if (pj.name === void 0) continue;
1821
+ let name = getName(pj.name);
1822
+ for (let dep of Object.keys(pj.dependencies || {})) {
1823
+ if (!workspacePackages.has(dep) && !includeExternal) continue;
1824
+ lines.push(`"${name}" -> "${getName(dep)}"`);
1825
+ }
1826
+ for (let dep of Object.keys(pj.devDependencies || {})) {
1827
+ if (!workspacePackages.has(dep) && !includeExternal) continue;
1828
+ lines.push(`"${name}" -> "${getName(dep)}" [style=dashed,color=grey]`);
1829
+ }
1830
+ }
1831
+ return `digraph {\n${lines.join("\n")}\n}`;
1832
+ }
1833
+ var generateDepsGraphCli = command({
1834
+ name: "gen-deps-graph",
1835
+ desc: "generate a graphviz dot file of the workspace dependencies",
1836
+ options: {
1837
+ includeRoot: boolean("include-root").desc("whether to include the root package.json in the graph"),
1838
+ includeExternal: boolean("include-external").desc("whether to include external dependencies in the graph"),
1839
+ root: string().desc("path to the root of the workspace (default: cwd)")
1840
+ },
1841
+ handler: async (args) => {
1842
+ info(await generateDepsGraph({
1843
+ workspaceRoot: resolveWorkspaceRoot(args.root),
1844
+ includeRoot: args.includeRoot,
1845
+ includeExternal: args.includeExternal
1846
+ }));
1847
+ }
1848
+ });
1849
+ //#endregion
1850
+ //#region src/git/utils.ts
1851
+ var CONVENTIONAL_COMMIT_RE = /^(\w+)(?:\(([^)]+)\))?(!?): (.+)$/;
1852
+ var BREAKING_CHANGE_RE = /^BREAKING[- ]CHANGE:/;
1853
+ async function getLatestTag(cwd) {
1854
+ let res = await exec([
1855
+ "git",
1856
+ "describe",
1857
+ "--abbrev=0",
1858
+ "--tags"
1859
+ ], { cwd });
1860
+ if (res.exitCode !== 0) {
1861
+ if (res.stderr.match(/^fatal: (?:No names found|No tags can describe)/i)) return null;
1862
+ throw new Error(`git describe failed: ${res.stderr}`);
1863
+ }
1864
+ return res.stdout.trim();
1865
+ }
1866
+ async function getFirstCommit(cwd) {
1867
+ return (await exec([
1868
+ "git",
1869
+ "rev-list",
1870
+ "--max-parents=0",
1871
+ "HEAD"
1872
+ ], {
1873
+ cwd,
1874
+ throwOnError: true
1875
+ })).stdout.trim();
1876
+ }
1877
+ async function getCurrentCommit(cwd) {
1878
+ return (await exec([
1879
+ "git",
1880
+ "rev-parse",
1881
+ "HEAD"
1882
+ ], {
1883
+ cwd,
1884
+ throwOnError: true
1885
+ })).stdout.trim();
1886
+ }
1887
+ async function getCurrentBranch(cwd) {
1888
+ return (await exec([
1889
+ "git",
1890
+ "rev-parse",
1891
+ "--abbrev-ref",
1892
+ "HEAD"
1893
+ ], {
1894
+ cwd,
1895
+ throwOnError: true
1896
+ })).stdout.trim();
1897
+ }
1898
+ async function gitTagExists(tag, cwd) {
1899
+ return (await exec([
1900
+ "git",
1901
+ "tag",
1902
+ "--list",
1903
+ tag
1904
+ ], {
1905
+ cwd,
1906
+ throwOnError: true
1907
+ })).stdout.trim() !== "";
1908
+ }
1909
+ async function findChangedFiles(params) {
1910
+ let { since, until = "HEAD", cwd } = params;
1911
+ let files = (await exec([
1912
+ "git",
1913
+ "diff",
1914
+ "--name-only",
1915
+ since,
1916
+ until
1917
+ ], {
1918
+ cwd,
1919
+ throwOnError: true
1920
+ })).stdout.trim().split("\n");
1921
+ if (files.length === 1 && files[0] === "") return [];
1922
+ return files;
1923
+ }
1924
+ async function getCommitsBetween(params) {
1925
+ let { since, until = "HEAD", cwd, files } = params;
1926
+ let delim = `---${randomUUID()}---`;
1927
+ let lines = (await exec([
1928
+ "git",
1929
+ "log",
1930
+ `--pretty=format:%H %s%n%an%n%ae%n%aI%n%cn%n%ce%n%cI%n%b%n${delim}`,
1931
+ since != null ? `${since}..${until}` : until,
1932
+ ...files?.length ? ["--", ...files] : []
1933
+ ], {
1934
+ cwd,
1935
+ throwOnError: true
1936
+ })).stdout.trim().split("\n");
1937
+ if (lines.length === 1 && lines[0] === "") return [];
1938
+ let items = [];
1939
+ let current = null;
1940
+ for (let i = 0; i < lines.length; i++) {
1941
+ let line = lines[i];
1942
+ if (line === delim) {
1943
+ if (current) items.push(current);
1944
+ current = null;
1945
+ } else if (current) {
1946
+ if (current.description) current.description += "\n";
1947
+ current.description += line;
1948
+ } else {
1949
+ let [hash, ...msg] = line.split(" ");
1950
+ let authorName = lines[++i];
1951
+ let authorEmail = lines[++i];
1952
+ let authorDate = lines[++i];
1953
+ let committerName = lines[++i];
1954
+ let committerEmail = lines[++i];
1955
+ let committerDate = lines[++i];
1956
+ current = {
1957
+ hash,
1958
+ author: {
1959
+ name: authorName,
1960
+ email: authorEmail,
1961
+ date: new Date(authorDate)
1962
+ },
1963
+ committer: {
1964
+ name: committerName,
1965
+ email: committerEmail,
1966
+ date: new Date(committerDate)
1967
+ },
1968
+ message: msg.join(" "),
1969
+ description: ""
1970
+ };
1971
+ }
1972
+ }
1973
+ if (current) items.push(current);
1974
+ return items.reverse();
1975
+ }
1976
+ function parseConventionalCommit(msg) {
1977
+ let [header, ...rest] = msg.split("\n");
1978
+ let match = header.match(CONVENTIONAL_COMMIT_RE);
1979
+ if (!match) return null;
1980
+ let [, type, scope, bang, subject] = match;
1981
+ let footerBreaking = rest.some((line) => BREAKING_CHANGE_RE.test(line.trim()));
1982
+ return {
1983
+ type,
1984
+ ...scope ? { scope } : {},
1985
+ breaking: Boolean(bang) || footerBreaking,
1986
+ subject
1987
+ };
1988
+ }
1989
+ //#endregion
1990
+ //#region src/misc/tsconfig.ts
1991
+ var import_picomatch = /* @__PURE__ */ __toESM$1(require_picomatch(), 1);
1992
+ var tsconfigFilesCache = new LruMap(32);
1993
+ async function getTsconfigFor(cwd) {
1994
+ let res = await exec([
1995
+ "npx",
1996
+ "tsc",
1997
+ "--showConfig"
1998
+ ], {
1999
+ cwd,
2000
+ throwOnError: true
2001
+ });
2002
+ return JSON.parse(res.stdout);
2003
+ }
2004
+ async function getTsconfigFiles(cwd) {
2005
+ let cached = tsconfigFilesCache.get(cwd);
2006
+ if (cached) return cached;
2007
+ let config = await getTsconfigFor(cwd);
2008
+ if (typeof config !== "object" || config === null) throw new Error("tsconfig.json is not an object");
2009
+ if (!("files" in config) || !Array.isArray(config.files)) throw new Error("tsconfig.json > .files is not an array");
2010
+ let files = config.files.map((file) => file.replace(/^\.\//, ""));
2011
+ tsconfigFilesCache.set(cwd, files);
2012
+ return files;
2013
+ }
2014
+ //#endregion
2015
+ //#region src/versioning/collect-files.ts
2016
+ var DEFAULT_EXCLUDE = ["**/*.unit.ts", "**/*.md"];
2017
+ async function defaultShouldInclude(file) {
2018
+ if (!file.file.endsWith(".ts")) return true;
2019
+ try {
2020
+ return (await getTsconfigFiles(join(file.root, file.package.path))).includes(file.file);
2021
+ } catch {
2022
+ return true;
2023
+ }
2024
+ }
2025
+ function fileBelongsToPackage(file, pkgPath) {
2026
+ if (pkgPath === "" || pkgPath === ".") return true;
2027
+ return file === pkgPath || file.startsWith(`${pkgPath}/`);
2028
+ }
2029
+ async function findProjectChangedFiles(params) {
2030
+ let { params: { include, exclude = DEFAULT_EXCLUDE, shouldInclude = defaultShouldInclude } = {}, root: rootInput = process$1.cwd(), since, until } = params;
2031
+ let root = normalizeFilePath(rootInput);
2032
+ let changed = await findChangedFiles({
2033
+ since,
2034
+ until,
2035
+ cwd: root
2036
+ });
2037
+ if (!changed.length) return [];
2038
+ let packages = (params.workspace ?? await collectPackageJsons(root)).filter((pkg) => !pkg.root).map((pkg) => ({
2039
+ pkg,
2040
+ relPath: relative(root, pkg.path)
2041
+ })).sort((a, b) => b.relPath.length - a.relPath.length);
2042
+ let files = [];
2043
+ let includeGlobs = include == null ? null : (0, import_picomatch.default)(include);
2044
+ let excludeGlobs = exclude == null ? null : (0, import_picomatch.default)(exclude);
2045
+ for (let file of changed) {
2046
+ let match = packages.find((item) => fileBelongsToPackage(file, item.relPath));
2047
+ if (!match) continue;
2048
+ let relPath = relative(match.relPath, file);
2049
+ if (includeGlobs != null && !includeGlobs(relPath)) continue;
2050
+ if (excludeGlobs != null && excludeGlobs(relPath)) continue;
2051
+ let info = {
2052
+ file: relPath,
2053
+ package: match.pkg,
2054
+ root
2055
+ };
2056
+ if (!await shouldInclude(info)) continue;
2057
+ files.push(info);
2058
+ }
2059
+ return files;
2060
+ }
2061
+ async function findProjectChangedPackages(params) {
2062
+ let files = await findProjectChangedFiles(params);
2063
+ let set = /* @__PURE__ */ new Set();
2064
+ for (let file of files) set.add(file.package);
2065
+ return Array.from(set);
2066
+ }
2067
+ //#endregion
2068
+ //#region src/cli/commands/cr.ts
2069
+ function selectChangedNpmPackages(params) {
2070
+ let { publishable, changed } = params;
2071
+ let selected = [...changed];
2072
+ let selectedNames = /* @__PURE__ */ new Set();
2073
+ for (let pkg of selected) selectedNames.add(asNonNull(pkg.json.name));
2074
+ let hadChanges = true;
2075
+ while (hadChanges) {
2076
+ hadChanges = false;
2077
+ for (let pkg of publishable) {
2078
+ let pkgName = asNonNull(pkg.json.name);
2079
+ for (let field of ["dependencies", "peerDependencies"]) {
2080
+ let deps = pkg.json[field];
2081
+ if (deps == null) continue;
2082
+ for (let name of Object.keys(deps)) if (selectedNames.has(name) && !selectedNames.has(pkgName)) {
2083
+ hadChanges = true;
2084
+ selected.push(pkg);
2085
+ selectedNames.add(pkgName);
2086
+ break;
2087
+ }
2088
+ }
2089
+ }
2090
+ }
2091
+ return filterPackageJsonsForPublish(selected, "npm");
2092
+ }
2093
+ async function runContinuousRelease(params) {
2094
+ let { workspaceRoot = resolveWorkspaceRoot(), workspace = await collectPackageJsons(workspaceRoot, true), distDir = "dist", extraArgs = [], onlyChanged = false, onlyChangedSince } = params;
2095
+ let workspaceWithoutRoot = workspace.filter((pkg) => !pkg.root);
2096
+ let packages = filterPackageJsonsForPublish(workspaceWithoutRoot, "npm");
2097
+ if (onlyChanged) {
2098
+ let config = await loadConfig({
2099
+ workspaceRoot,
2100
+ require: false
2101
+ });
2102
+ let since = onlyChangedSince ?? await getLatestTag(workspaceRoot);
2103
+ if (since == null) throw new Error("no previous tag found, cannot determine changeset");
2104
+ let changedPackages = await findProjectChangedPackages({
2105
+ params: config?.versioning,
2106
+ workspace: workspaceWithoutRoot,
2107
+ root: workspaceRoot,
2108
+ since
2109
+ });
2110
+ if (!changedPackages.length) {
2111
+ info(`no packages changed since ${since}, nothing to do`);
2112
+ return;
2113
+ }
2114
+ packages = selectChangedNpmPackages({
2115
+ publishable: packages,
2116
+ changed: changedPackages
2117
+ });
2118
+ if (!packages.length) {
2119
+ info(`no packages changed since ${since}, nothing to do`);
2120
+ return;
2121
+ }
2122
+ info(`only publishing changed packages since ${since}:`);
2123
+ for (let pkg of packages) info(` - ${pkg.json.name}`);
2124
+ }
2125
+ if (!isRunningInGithubActions()) throw new Error("cr command is only supported in github actions");
2126
+ let distPaths = [];
2127
+ for (let pkg of packages) {
2128
+ if (pkg.json.scripts?.build !== void 0) await exec([
2129
+ "npm",
2130
+ "run",
2131
+ "build"
2132
+ ], {
2133
+ cwd: join(pkg.path),
2134
+ stdio: "inherit",
2135
+ throwOnError: true
2136
+ });
2137
+ else await buildPackage({
2138
+ workspaceRoot,
2139
+ workspace,
2140
+ packageName: asNonNull(pkg.json.name)
2141
+ });
2142
+ distPaths.push(join(pkg.path, distDir));
2143
+ }
2144
+ if (extraArgs.some((item) => item.startsWith("--pnpm"))) warn("`--pnpm` flag is not supported and may cause issues, please avoid using it");
2145
+ await exec([
2146
+ "npx",
2147
+ "pkg-pr-new",
2148
+ "publish",
2149
+ ...extraArgs,
2150
+ ...distPaths
2151
+ ], {
2152
+ cwd: workspaceRoot,
2153
+ throwOnError: true,
2154
+ stdio: "inherit"
2155
+ });
2156
+ }
2157
+ var runContinuousReleaseCli = command({
2158
+ name: "cr",
2159
+ desc: "publish the workspace to pkg.pr.new",
2160
+ options: {
2161
+ root: string().desc("path to the root of the workspace (default: cwd)"),
2162
+ distDir: string("dist-dir").desc("directory to publish from, relative to package root (default: dist)"),
2163
+ extraArgs: string("extra-args").desc("extra arguments to pass to pkg-pr-new"),
2164
+ onlyChanged: boolean("only-changed").desc("whether to only publish packages changed since the last release.").default(false),
2165
+ onlyChangedSince: string("only-changed-since").desc("starting point for the changelog (defaults to latest tag)")
2166
+ },
2167
+ transform: (args) => {
2168
+ return {
2169
+ workspaceRoot: resolveWorkspaceRoot(args.root),
2170
+ distDir: args.distDir,
2171
+ extraArgs: args.extraArgs?.split(" "),
2172
+ onlyChanged: args.onlyChanged,
2173
+ onlyChangedSince: args.onlyChangedSince
2174
+ };
2175
+ },
2176
+ handler: runContinuousRelease
2177
+ });
2178
+ //#endregion
2179
+ //#region src/cli/commands/lint/validate-workspace-deps.ts
2180
+ var import_semver = /* @__PURE__ */ __toESM$1(require_semver(), 1);
2181
+ var DEP_FIELDS = [
2182
+ "dependencies",
2183
+ "devDependencies",
2184
+ "peerDependencies",
2185
+ "optionalDependencies"
2186
+ ];
2187
+ function versionsCompatible(version, otherVersion) {
2188
+ if (otherVersion.match(/^(?:https?:\/\/|catalog:)/)) return version === otherVersion;
2189
+ if ((0, import_semver.valid)(version) != null) return (0, import_semver.satisfies)(version, otherVersion);
2190
+ if ((0, import_semver.validRange)(version) != null) return (0, import_semver.subset)(otherVersion, version);
2191
+ return version === otherVersion;
2192
+ }
2193
+ async function validateWorkspaceDeps(params) {
2194
+ let { workspaceRoot, config: { includeRoot, externalDependencies: { enabled: externalDependenciesEnabled = true, skipPeerDependencies: externalDependenciesSkipPeerDependencies = false, shouldSkip: externalDependenciesShouldSkip } = {} } = {} } = params;
2195
+ let packages = params.packages ?? await collectPackageJsons(workspaceRoot, includeRoot);
2196
+ let packagesMap = new Map(packages.map((pkg) => [pkg.json.name, pkg]));
2197
+ let versions = {};
2198
+ let errors = [];
2199
+ for (let pkg of packages) {
2200
+ let pj = pkg.json;
2201
+ if (pj.name === void 0) throw new Error("package.json without name is not supported");
2202
+ for (let field of DEP_FIELDS) {
2203
+ let deps = pj[field];
2204
+ if (!deps) continue;
2205
+ for (let [name, version] of Object.entries(deps)) {
2206
+ if (packagesMap.has(name)) {
2207
+ let otherPkg = packagesMap.get(name);
2208
+ if (!Boolean(otherPkg?.json.yorozu?.standalone) && !version.startsWith("workspace:")) errors.push({
2209
+ type: "internal",
2210
+ package: pj.name,
2211
+ dependency: name,
2212
+ subtype: "not_workspace_proto"
2213
+ });
2214
+ continue;
2215
+ }
2216
+ if (version.startsWith("workspace:")) {
2217
+ errors.push({
2218
+ type: "internal",
2219
+ package: pj.name,
2220
+ dependency: name,
2221
+ subtype: "not_workspace_dep"
2222
+ });
2223
+ continue;
2224
+ }
2225
+ if (!externalDependenciesEnabled) continue;
2226
+ if (field === "peerDependencies" && externalDependenciesSkipPeerDependencies) continue;
2227
+ if (externalDependenciesShouldSkip?.({
2228
+ package: pkg,
2229
+ dependency: name,
2230
+ version,
2231
+ field
2232
+ })) continue;
2233
+ if (versions[name] === void 0) versions[name] = {};
2234
+ for (let [pkgName, pkgDepVersion] of Object.entries(versions[name])) if (!versionsCompatible(version, pkgDepVersion)) errors.push({
2235
+ type: "external",
2236
+ package: pj.name,
2237
+ dependency: name,
2238
+ version,
2239
+ at: field,
2240
+ otherPackage: pkgName,
2241
+ otherVersion: pkgDepVersion
2242
+ });
2243
+ versions[name][pj.name] = version;
2244
+ }
2245
+ }
2246
+ }
2247
+ return errors;
2248
+ }
2249
+ //#endregion
2250
+ //#region src/git/github.ts
2251
+ var USER_AGENT = "@yorozu/build";
2252
+ var GITHUB_API_VERSION = "2022-11-28";
2253
+ var DEFAULT_API_URL = "https://api.github.com";
2254
+ var REQUEST_TIMEOUT_MS = 3e4;
2255
+ var UPLOAD_TIMEOUT_MS = 6e4;
2256
+ var ReleaseResponseSchema = object({
2257
+ id: number(),
2258
+ upload_url: string$1()
2259
+ });
2260
+ function toBodyInit(body) {
2261
+ return body;
2262
+ }
2263
+ function githubHeaders(token, extra) {
2264
+ return {
2265
+ Accept: "application/vnd.github+json",
2266
+ "User-Agent": USER_AGENT,
2267
+ "X-GitHub-Api-Version": GITHUB_API_VERSION,
2268
+ Authorization: `Bearer ${token}`,
2269
+ ...extra
2270
+ };
2271
+ }
2272
+ async function readErrorBody(res) {
2273
+ try {
2274
+ return await res.text();
2275
+ } catch {
2276
+ return "";
2277
+ }
2278
+ }
2279
+ async function createGithubRelease(params) {
2280
+ let apiUrl = (params.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
2281
+ let res = await fetch(`${apiUrl}/repos/${params.repo}/releases`, {
2282
+ method: "POST",
2283
+ headers: githubHeaders(params.token, { "Content-Type": "application/json" }),
2284
+ body: JSON.stringify({
2285
+ tag_name: params.tag,
2286
+ name: params.name,
2287
+ body: params.body,
2288
+ draft: params.draft ?? false,
2289
+ prerelease: params.prerelease ?? false
2290
+ }),
2291
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
2292
+ });
2293
+ if (res.status !== 201) throw new Error(`GitHub release request failed with ${res.status}: ${await readErrorBody(res)}`);
2294
+ let release = ReleaseResponseSchema.parse(await res.json());
2295
+ let uploadUrl = release.upload_url.split("{")[0];
2296
+ if (params.artifacts != null && params.artifacts.length > 0) await asyncPool(params.artifacts, async (file) => {
2297
+ let url = new URL(uploadUrl);
2298
+ url.searchParams.set("name", file.name);
2299
+ let upload = await fetch(url, {
2300
+ method: "POST",
2301
+ headers: githubHeaders(params.token, {
2302
+ "Content-Type": file.type,
2303
+ "Content-Length": String(file.body.byteLength)
2304
+ }),
2305
+ body: toBodyInit(file.body),
2306
+ signal: AbortSignal.timeout(UPLOAD_TIMEOUT_MS)
2307
+ });
2308
+ if (upload.status !== 201) throw new Error(`failed to upload artifact: ${file.name}: GitHub artifact upload failed with ${upload.status}: ${await readErrorBody(upload)}`);
2309
+ });
2310
+ return release.id;
2311
+ }
2312
+ //#endregion
2313
+ //#region ../../node_modules/.pnpm/detect-indent@7.0.2/node_modules/detect-indent/index.js
2314
+ var INDENT_REGEX = /^(?:( )+|\t+)/;
2315
+ var INDENT_TYPE_SPACE = "space";
2316
+ var INDENT_TYPE_TAB = "tab";
2317
+ function shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, value) {
2318
+ return ignoreSingleSpaces && indentType === INDENT_TYPE_SPACE && value === 1;
2319
+ }
2320
+ /**
2321
+ Make a Map that counts how many indents/unindents have occurred for a given size and how many lines follow a given indentation.
2322
+
2323
+ The key is a concatenation of the indentation type (s = space and t = tab) and the size of the indents/unindents.
2324
+
2325
+ ```
2326
+ indents = {
2327
+ t3: [1, 0],
2328
+ t4: [1, 5],
2329
+ s5: [1, 0],
2330
+ s12: [1, 0],
2331
+ }
2332
+ ```
2333
+ */
2334
+ function makeIndentsMap(string, ignoreSingleSpaces) {
2335
+ const indents = /* @__PURE__ */ new Map();
2336
+ let previousSize = 0;
2337
+ let previousIndentType;
2338
+ let key;
2339
+ for (const line of string.split(/\n/g)) {
2340
+ if (!line) continue;
2341
+ const matches = line.match(INDENT_REGEX);
2342
+ if (matches === null) {
2343
+ previousSize = 0;
2344
+ previousIndentType = "";
2345
+ } else {
2346
+ const indent = matches[0].length;
2347
+ const indentType = matches[1] ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB;
2348
+ if (shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, indent)) continue;
2349
+ if (indentType !== previousIndentType) previousSize = 0;
2350
+ previousIndentType = indentType;
2351
+ let use = 1;
2352
+ let weight = 0;
2353
+ const indentDifference = indent - previousSize;
2354
+ previousSize = indent;
2355
+ if (indentDifference === 0) {
2356
+ use = 0;
2357
+ weight = 1;
2358
+ } else {
2359
+ const absoluteIndentDifference = Math.abs(indentDifference);
2360
+ if (shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, absoluteIndentDifference)) continue;
2361
+ key = encodeIndentsKey(indentType, absoluteIndentDifference);
2362
+ }
2363
+ const entry = indents.get(key);
2364
+ indents.set(key, entry === void 0 ? [1, 0] : [entry[0] + use, entry[1] + weight]);
2365
+ }
2366
+ }
2367
+ return indents;
2368
+ }
2369
+ function encodeIndentsKey(indentType, indentAmount) {
2370
+ return (indentType === INDENT_TYPE_SPACE ? "s" : "t") + String(indentAmount);
2371
+ }
2372
+ function decodeIndentsKey(indentsKey) {
2373
+ return {
2374
+ type: indentsKey[0] === "s" ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB,
2375
+ amount: Number(indentsKey.slice(1))
2376
+ };
2377
+ }
2378
+ function getMostUsedKey(indents) {
2379
+ let result;
2380
+ let maxUsed = 0;
2381
+ let maxWeight = 0;
2382
+ for (const [key, [usedCount, weight]] of indents) if (usedCount > maxUsed || usedCount === maxUsed && weight > maxWeight) {
2383
+ maxUsed = usedCount;
2384
+ maxWeight = weight;
2385
+ result = key;
2386
+ }
2387
+ return result;
2388
+ }
2389
+ function makeIndentString(type, amount) {
2390
+ return (type === INDENT_TYPE_SPACE ? " " : " ").repeat(amount);
2391
+ }
2392
+ function detectIndent(string) {
2393
+ if (typeof string !== "string") throw new TypeError("Expected a string");
2394
+ let indents = makeIndentsMap(string, true);
2395
+ if (indents.size === 0) indents = makeIndentsMap(string, false);
2396
+ const keyOfMostUsedIndent = getMostUsedKey(indents);
2397
+ let type;
2398
+ let amount = 0;
2399
+ let indent = "";
2400
+ if (keyOfMostUsedIndent !== void 0) {
2401
+ ({type, amount} = decodeIndentsKey(keyOfMostUsedIndent));
2402
+ indent = makeIndentString(type, amount);
2403
+ }
2404
+ return {
2405
+ amount,
2406
+ type,
2407
+ indent
2408
+ };
2409
+ }
2410
+ //#endregion
2411
+ //#region src/versioning/bump-version.ts
2412
+ function isOwnVersioning(pkg) {
2413
+ return Boolean(pkg.json.yorozu?.ownVersioning);
2414
+ }
2415
+ function isStandalone(pkg) {
2416
+ return Boolean(pkg.json.yorozu?.standalone);
2417
+ }
2418
+ function isManaged(pkg) {
2419
+ return !pkg.root && !isOwnVersioning(pkg) && !isStandalone(pkg);
2420
+ }
2421
+ function parseCommit(commit) {
2422
+ return parseConventionalCommit(`${commit.message}\n${commit.description}`);
2423
+ }
2424
+ function summarizeCommits(commits) {
2425
+ let hasBreakingChanges = false;
2426
+ let hasFeatures = false;
2427
+ for (let commit of commits) {
2428
+ let parsed = parseCommit(commit);
2429
+ if (!parsed) continue;
2430
+ if (parsed.breaking) hasBreakingChanges = true;
2431
+ if (parsed.type === "feat") hasFeatures = true;
2432
+ }
2433
+ return {
2434
+ hasBreakingChanges,
2435
+ hasFeatures
2436
+ };
2437
+ }
2438
+ function bumpFromFlags(oldVersion, flags) {
2439
+ let parsedVersion = (0, import_semver.parse)(oldVersion);
2440
+ if (!parsedVersion) throw new Error(`Invalid version: ${oldVersion}`);
2441
+ if (flags.hasBreakingChanges) {
2442
+ if (parsedVersion.major === 0 && parsedVersion.minor === 0) return "patch";
2443
+ if (parsedVersion.major === 0) return "minor";
2444
+ return "major";
2445
+ }
2446
+ if (flags.hasFeatures) return parsedVersion.major === 0 ? "patch" : "minor";
2447
+ return "patch";
2448
+ }
2449
+ function determineBumpType(params) {
2450
+ return bumpFromFlags(params.oldVersion, summarizeCommits(params.commits));
2451
+ }
2452
+ async function writePackageVersion(pkg, version, dryRun) {
2453
+ if (!dryRun) {
2454
+ let pkgJsonPath = pkg.packageJsonPath;
2455
+ let pkgJsonText = await readFile(pkgJsonPath, "utf8");
2456
+ let indent = detectIndent(pkgJsonText).indent || " ";
2457
+ let pkgJson = JSON.parse(pkgJsonText);
2458
+ pkgJson.version = version;
2459
+ await writeFile(pkgJsonPath, `${JSON.stringify(pkgJson, null, indent)}\n`);
2460
+ }
2461
+ pkg.json.version = version;
2462
+ }
2463
+ async function nextStandaloneVersion(pkg, cwd) {
2464
+ let current = asNonNull(pkg.json.version);
2465
+ let tag;
2466
+ try {
2467
+ tag = await getLatestTag(pkg.path);
2468
+ } catch {
2469
+ tag = null;
2470
+ }
2471
+ if (tag == null) return current;
2472
+ let commits;
2473
+ try {
2474
+ let rel = relative(normalizeFilePath(cwd), pkg.path);
2475
+ let pathspec = rel === "" || rel === "." ? "." : rel.endsWith("/") ? rel : `${rel}/`;
2476
+ commits = await getCommitsBetween({
2477
+ since: tag,
2478
+ cwd,
2479
+ files: [pathspec]
2480
+ });
2481
+ } catch {
2482
+ return current;
2483
+ }
2484
+ if (commits.length === 0) return current;
2485
+ let bumpType = determineBumpType({
2486
+ oldVersion: current,
2487
+ commits
2488
+ });
2489
+ let next = (0, import_semver.inc)(current, bumpType);
2490
+ if (next == null) throw new Error(`Invalid version increment: ${current} → ${bumpType}`);
2491
+ return next;
2492
+ }
2493
+ function recordVersion(nextVersions, changedPackages, pkg, prevVersion, next) {
2494
+ if (pkg.json.name != null) nextVersions[pkg.json.name] = next;
2495
+ if (next !== prevVersion) changedPackages.push({
2496
+ package: pkg,
2497
+ prevVersion
2498
+ });
2499
+ }
2500
+ async function bumpVersion(params) {
2501
+ let { workspace, type: explicitType, cwd = process$1.cwd(), since, dryRun = false, withRoot = false } = params;
2502
+ let rootPackage = findRootPackage(workspace);
2503
+ let previousVersion = rootPackage.json.version;
2504
+ if (previousVersion == null) throw new Error("Workspace root package.json is missing a version");
2505
+ let type;
2506
+ let hasFeatures = false;
2507
+ let hasBreakingChanges = false;
2508
+ if (explicitType == null) {
2509
+ let commits = await getCommitsBetween({
2510
+ since,
2511
+ cwd
2512
+ });
2513
+ ({hasFeatures, hasBreakingChanges} = summarizeCommits(commits));
2514
+ type = bumpFromFlags(previousVersion, {
2515
+ hasFeatures,
2516
+ hasBreakingChanges
2517
+ });
2518
+ } else type = explicitType;
2519
+ let nextVersion = (0, import_semver.inc)(previousVersion, type);
2520
+ if (nextVersion == null) throw new Error(`Invalid version increment: ${previousVersion} → ${type}`);
2521
+ let nextVersions = {};
2522
+ let changedPackages = [];
2523
+ for (let pkg of workspace) {
2524
+ if (!isManaged(pkg)) continue;
2525
+ let prevVersion = asNonNull(pkg.json.version);
2526
+ await writePackageVersion(pkg, nextVersion, dryRun);
2527
+ recordVersion(nextVersions, changedPackages, pkg, prevVersion, nextVersion);
2528
+ }
2529
+ if (withRoot) {
2530
+ await writePackageVersion(rootPackage, nextVersion, dryRun);
2531
+ recordVersion(nextVersions, changedPackages, rootPackage, previousVersion, nextVersion);
2532
+ }
2533
+ for (let pkg of workspace) {
2534
+ if (pkg.root || isOwnVersioning(pkg) || !isStandalone(pkg)) continue;
2535
+ let prevVersion = asNonNull(pkg.json.version);
2536
+ let standaloneNext = await nextStandaloneVersion(pkg, cwd);
2537
+ if (standaloneNext === prevVersion) continue;
2538
+ await writePackageVersion(pkg, standaloneNext, dryRun);
2539
+ recordVersion(nextVersions, changedPackages, pkg, prevVersion, standaloneNext);
2540
+ }
2541
+ return {
2542
+ previousVersion,
2543
+ nextVersion,
2544
+ nextVersions,
2545
+ changedPackages,
2546
+ releaseType: type,
2547
+ hasBreakingChanges,
2548
+ hasFeatures
2549
+ };
2550
+ }
2551
+ //#endregion
2552
+ //#region src/versioning/generate-changelog.ts
2553
+ var SKIPPED_TYPES = new Set([
2554
+ "chore",
2555
+ "ci",
2556
+ "docs",
2557
+ "test"
2558
+ ]);
2559
+ function defaultOnParseFailed(commit) {
2560
+ warn(`Failed to parse commit message: ${commit.message}`);
2561
+ }
2562
+ function defaultCommitFormatter(commit, parsed) {
2563
+ let line = `- ${commit.hash}: ${parsed.breaking ? "**❗ BREAKING** " : ""}${commit.message}`;
2564
+ if (parsed.breaking && commit.description) line += `\n${commit.description.trim().split("\n").map((item) => ` ${item}`).join("\n")}`;
2565
+ return line;
2566
+ }
2567
+ function defaultCommitFilter(_commit, parsed) {
2568
+ if (parsed.breaking) return true;
2569
+ if (!parsed.type || SKIPPED_TYPES.has(parsed.type)) return false;
2570
+ return true;
2571
+ }
2572
+ function defaultPackageCommitsFormatter(packageName, commits) {
2573
+ return `### ${packageName}\n${Object.values(commits).join("\n")}`;
2574
+ }
2575
+ async function generateChangelog(params) {
2576
+ let { cwd, since, params: { changelog: { onCommitParseFailed = defaultOnParseFailed, onCommitsFetched, commitFilter = defaultCommitFilter, commitFilterWithFiles, commitFormatter = defaultCommitFormatter, packageCommitsFormatter = defaultPackageCommitsFormatter } = {} } = {} } = params;
2577
+ let commitsByPackage = {};
2578
+ let changedFiles = await findProjectChangedFiles({
2579
+ params: params.params ?? {},
2580
+ workspace: params.workspace,
2581
+ root: cwd,
2582
+ since
2583
+ });
2584
+ let changedFilesByPackage = /* @__PURE__ */ new Map();
2585
+ for (let file of changedFiles) changedFilesByPackage.set(join(relative(file.root, file.package.path), file.file), file.package);
2586
+ let commits = await getCommitsBetween({
2587
+ since,
2588
+ cwd
2589
+ });
2590
+ await onCommitsFetched?.(commits);
2591
+ for (let commit of commits) {
2592
+ let parsed = parseConventionalCommit(`${commit.message}\n${commit.description}`);
2593
+ if (!parsed) {
2594
+ onCommitParseFailed(commit);
2595
+ continue;
2596
+ }
2597
+ if (!commitFilter(commit, parsed)) continue;
2598
+ let changed = await findChangedFiles({
2599
+ since: `${commit.hash}~1`,
2600
+ until: commit.hash,
2601
+ cwd
2602
+ });
2603
+ if (commitFilterWithFiles && !commitFilterWithFiles(commit, parsed, changed)) continue;
2604
+ for (let file of changed) {
2605
+ let pkg = changedFilesByPackage.get(file);
2606
+ if (!pkg) continue;
2607
+ let packageName = asNonNull(pkg.json.name);
2608
+ if (commitsByPackage[packageName] == null) commitsByPackage[packageName] = {};
2609
+ commitsByPackage[packageName][commit.hash] = commitFormatter(commit, parsed, changed);
2610
+ }
2611
+ }
2612
+ let changelog = "";
2613
+ for (let [pkg, packageCommits] of Object.entries(commitsByPackage)) {
2614
+ changelog += packageCommitsFormatter(pkg, packageCommits);
2615
+ changelog += "\n\n";
2616
+ }
2617
+ return changelog;
2618
+ }
2619
+ //#endregion
2620
+ export { LruMap, NPM_PACKAGE_NAME_REGEX, boolean, buildPackage, buildPackageCli, buildWorkspace, bumpVersion, command, createGithubRelease, determineBumpType, findChangedFiles, findProjectChangedFiles, findProjectChangedPackages, generateChangelog, generateDepsGraph, generateDepsGraphCli, generateDocs, generateDocsCli, getCommitsBetween, getCurrentBranch, getCurrentCommit, getFirstCommit, getGithubActionsInput, getLatestTag, getTsconfigFiles, getTsconfigFor, gitTagExists, isRunningInGithubActions, loadConfig, npmCheckVersion, parseConventionalCommit, publishPackages, publishPackagesCli, resolveWorkspaceRoot, run, runContinuousRelease, runContinuousReleaseCli, string, validateWorkspaceDeps, writeGithubActionsOutput };