robuild 0.0.19 → 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.
@@ -1,26 +1,115 @@
1
1
  import { t as RobuildPluginManager } from "./plugin-manager-CwMXjVtp.mjs";
2
2
  import { builtinModules } from "node:module";
3
3
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
4
- import { fileURLToPath, pathToFileURL } from "node:url";
5
4
  import { colors } from "consola/utils";
6
5
  import prettyBytes from "pretty-bytes";
7
- import { cp, mkdir, readFile, readdir, symlink, writeFile } from "node:fs/promises";
8
- import { consola } from "consola";
6
+ import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
9
7
  import { resolveModulePath } from "exsolve";
10
8
  import { parseSync } from "oxc-parser";
11
9
  import { rolldown, watch } from "rolldown";
12
10
  import { dts } from "rolldown-plugin-dts";
13
11
  import { existsSync, promises, readdirSync, statSync } from "node:fs";
14
- import { glob } from "glob";
15
- import { createHash } from "node:crypto";
12
+ import { consola } from "consola";
13
+ import { fileURLToPath, pathToFileURL } from "node:url";
16
14
  import { gzipSync } from "node:zlib";
17
15
  import { minify } from "oxc-minify";
16
+ import { glob } from "glob";
17
+ import { createHash } from "node:crypto";
18
18
  import MagicString from "magic-string";
19
19
  import { transform } from "oxc-transform";
20
20
  import { glob as glob$1 } from "tinyglobby";
21
21
  import { exec } from "node:child_process";
22
22
  import { promisify } from "node:util";
23
23
 
24
+ //#region src/features/logger.ts
25
+ /**
26
+ * Logger instance with configurable log level
27
+ */
28
+ var Logger = class {
29
+ level = "info";
30
+ warningCount = 0;
31
+ errorCount = 0;
32
+ constructor(level = "info") {
33
+ this.level = level;
34
+ this.updateConsolaLevel();
35
+ }
36
+ setLevel(level) {
37
+ this.level = level;
38
+ this.updateConsolaLevel();
39
+ }
40
+ updateConsolaLevel() {
41
+ consola.level = {
42
+ silent: 0,
43
+ error: 1,
44
+ warn: 2,
45
+ info: 3,
46
+ verbose: 4
47
+ }[this.level];
48
+ }
49
+ silent(message, ...args) {
50
+ consola.log(message, ...args);
51
+ }
52
+ error(message, ...args) {
53
+ this.errorCount++;
54
+ consola.error(message, ...args);
55
+ }
56
+ warn(message, ...args) {
57
+ this.warningCount++;
58
+ consola.warn(message, ...args);
59
+ }
60
+ info(message, ...args) {
61
+ consola.info(message, ...args);
62
+ }
63
+ verbose(message, ...args) {
64
+ if (this.level === "verbose") consola.debug(message, ...args);
65
+ }
66
+ success(message, ...args) {
67
+ consola.success(message, ...args);
68
+ }
69
+ log(message, ...args) {
70
+ consola.log(message, ...args);
71
+ }
72
+ /**
73
+ * Debug output - only visible with INSPECT_BUILD env var
74
+ */
75
+ debug(message, ...args) {
76
+ if (process.env.INSPECT_BUILD) consola.log(message, ...args);
77
+ }
78
+ getWarningCount() {
79
+ return this.warningCount;
80
+ }
81
+ getErrorCount() {
82
+ return this.errorCount;
83
+ }
84
+ resetCounts() {
85
+ this.warningCount = 0;
86
+ this.errorCount = 0;
87
+ }
88
+ shouldFailOnWarnings(failOnWarn) {
89
+ return failOnWarn && this.warningCount > 0;
90
+ }
91
+ };
92
+ const logger = new Logger();
93
+ /**
94
+ * Configure global logger
95
+ */
96
+ function configureLogger(level) {
97
+ logger.setLevel(level);
98
+ }
99
+ /**
100
+ * Reset warning and error counts
101
+ */
102
+ function resetLogCounts() {
103
+ logger.resetCounts();
104
+ }
105
+ /**
106
+ * Check if build should fail due to warnings
107
+ */
108
+ function shouldFailOnWarnings(failOnWarn) {
109
+ return logger.shouldFailOnWarnings(failOnWarn);
110
+ }
111
+
112
+ //#endregion
24
113
  //#region src/features/advanced-build.ts
25
114
  /**
26
115
  * Create skip node_modules plugin
@@ -91,7 +180,7 @@ async function processFileUnbundled(inputPath, outputPath, entry) {
91
180
  await mkdir(dirname(finalOutputPath), { recursive: true });
92
181
  await writeFile(finalOutputPath, transformedContent, "utf-8");
93
182
  } catch (error) {
94
- console.warn(`Failed to process file ${inputPath}:`, error);
183
+ logger.warn(`Failed to process file ${inputPath}:`, error);
95
184
  }
96
185
  }
97
186
  /**
@@ -184,6 +273,136 @@ function addBannerFooter(content, banner, footer) {
184
273
  return result;
185
274
  }
186
275
 
276
+ //#endregion
277
+ //#region src/utils.ts
278
+ /**
279
+ * Normalize a path to an absolute path.
280
+ * Handles string paths, URL objects, and undefined values.
281
+ *
282
+ * @param path - The path to normalize (string, URL, or undefined)
283
+ * @param resolveFrom - The base directory to resolve relative paths from
284
+ * @returns The normalized absolute path
285
+ */
286
+ function normalizePath(path, resolveFrom) {
287
+ return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
288
+ }
289
+ function fmtPath(path) {
290
+ return resolve(path).replace(process.cwd(), ".");
291
+ }
292
+ function analyzeDir(dir) {
293
+ if (Array.isArray(dir)) {
294
+ let totalSize = 0;
295
+ let totalFiles = 0;
296
+ for (const d of dir) {
297
+ const { size, files } = analyzeDir(d);
298
+ totalSize += size;
299
+ totalFiles += files;
300
+ }
301
+ return {
302
+ size: totalSize,
303
+ files: totalFiles
304
+ };
305
+ }
306
+ let totalSize = 0;
307
+ try {
308
+ const files = readdirSync(dir, {
309
+ withFileTypes: true,
310
+ recursive: true
311
+ });
312
+ for (const file of files) {
313
+ const fullPath = join(file.parentPath, file.name);
314
+ if (file.isFile()) {
315
+ const { size } = statSync(fullPath);
316
+ totalSize += size;
317
+ }
318
+ }
319
+ return {
320
+ size: totalSize,
321
+ files: files.length
322
+ };
323
+ } catch (error) {
324
+ if (error.code === "ENOENT" || error.code === "ENOTDIR") return {
325
+ size: 0,
326
+ files: 0
327
+ };
328
+ throw error;
329
+ }
330
+ }
331
+ async function distSize(dir, entry) {
332
+ const { output } = await (await rolldown({
333
+ input: join(dir, entry),
334
+ plugins: [],
335
+ platform: "neutral",
336
+ external: (id) => id[0] !== "." && !id.startsWith(dir)
337
+ })).generate({ codeSplitting: false });
338
+ const code = output[0].code;
339
+ const { code: minified } = await minify(entry, code);
340
+ return {
341
+ size: Buffer.byteLength(code),
342
+ minSize: Buffer.byteLength(minified),
343
+ minGzipSize: gzipSync(minified).length
344
+ };
345
+ }
346
+ async function sideEffectSize(dir, entry) {
347
+ const { output } = await (await rolldown({
348
+ input: "#entry",
349
+ platform: "neutral",
350
+ external: (id) => id[0] !== "." && !id.startsWith(dir),
351
+ plugins: [{
352
+ name: "virtual-entry",
353
+ async resolveId(id, importer, opts) {
354
+ if (id === "#entry") return { id };
355
+ const resolved = await this.resolve(id, importer, opts);
356
+ if (!resolved) return null;
357
+ resolved.moduleSideEffects = null;
358
+ return resolved;
359
+ },
360
+ load(id) {
361
+ if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
362
+ }
363
+ }]
364
+ })).generate({ codeSplitting: false });
365
+ if (process.env.INSPECT_BUILD) {
366
+ logger.debug("---------[side effects]---------");
367
+ logger.debug(entry);
368
+ logger.debug(output[0].code);
369
+ logger.debug("-------------------------------");
370
+ }
371
+ return Buffer.byteLength(output[0].code.trim());
372
+ }
373
+
374
+ //#endregion
375
+ //#region src/features/clean.ts
376
+ /**
377
+ * Clean output directory or specific paths.
378
+ * Used by both bundle and transform builders.
379
+ *
380
+ * @param projectRoot - The project root directory
381
+ * @param outDir - The output directory to clean
382
+ * @param cleanPaths - true to clean outDir, or array of specific paths to clean
383
+ */
384
+ async function cleanOutputDir(projectRoot, outDir, cleanPaths) {
385
+ if (!cleanPaths) return;
386
+ if (cleanPaths === true) {
387
+ if (existsSync(outDir)) {
388
+ logger.log(colors.dim(`Cleaning ${fmtPath(outDir)}`));
389
+ await rm(outDir, {
390
+ recursive: true,
391
+ force: true
392
+ });
393
+ }
394
+ } else if (Array.isArray(cleanPaths)) for (const path of cleanPaths) {
395
+ const fullPath = resolve(projectRoot, path);
396
+ if (existsSync(fullPath)) {
397
+ logger.log(colors.dim(`Cleaning ${fmtPath(fullPath)}`));
398
+ await rm(fullPath, {
399
+ recursive: true,
400
+ force: true
401
+ });
402
+ }
403
+ }
404
+ }
405
+
187
406
  //#endregion
188
407
  //#region src/features/copy.ts
189
408
  /**
@@ -191,7 +410,7 @@ function addBannerFooter(content, banner, footer) {
191
410
  */
192
411
  async function copyFiles(cwd, outDir, copyOptions) {
193
412
  if (!copyOptions || copyOptions.length === 0) return;
194
- consola.debug("📁 Copying files...");
413
+ logger.verbose("Copying files...");
195
414
  await Promise.all(copyOptions.map(async (entry) => {
196
415
  const from = typeof entry === "string" ? entry : entry.from;
197
416
  const to = typeof entry === "string" ? resolve(outDir, basename(from)) : resolve(cwd, entry.to);
@@ -201,12 +420,149 @@ async function copyFiles(cwd, outDir, copyOptions) {
201
420
  recursive: true,
202
421
  force: true
203
422
  });
204
- consola.debug(` ${from} → ${to}`);
423
+ logger.verbose(` ${from} → ${to}`);
205
424
  } catch (error) {
206
- consola.warn(`Failed to copy ${from} to ${to}:`, error);
425
+ logger.warn(`Failed to copy ${from} to ${to}:`, error);
207
426
  }
208
427
  }));
209
- consola.debug("Files copied successfully");
428
+ logger.verbose("Files copied successfully");
429
+ }
430
+
431
+ //#endregion
432
+ //#region src/features/entry-resolver.ts
433
+ /**
434
+ * Parse a string entry format like "src/index.ts:dist" or "src/:dist"
435
+ *
436
+ * @param rawEntry - The raw string entry
437
+ * @returns Parsed entry object
438
+ */
439
+ function parseEntryString(rawEntry) {
440
+ const [input, outDir] = rawEntry.split(":");
441
+ if (input.endsWith("/")) return {
442
+ type: "transform",
443
+ input,
444
+ outDir: outDir || "dist"
445
+ };
446
+ return {
447
+ type: "bundle",
448
+ input: input.includes(",") ? input.split(",") : input,
449
+ outDir: outDir || "dist"
450
+ };
451
+ }
452
+ /**
453
+ * Normalize entry input paths to absolute paths.
454
+ * Handles string, array, and object (named entries) formats.
455
+ *
456
+ * @param entryInput - The entry input (string, array, or object)
457
+ * @param pkgDir - The package directory to resolve paths from
458
+ * @returns Normalized input
459
+ */
460
+ function normalizeEntryInput(entryInput, pkgDir) {
461
+ if (typeof entryInput === "object" && !Array.isArray(entryInput)) {
462
+ const normalizedInput = {};
463
+ for (const [key, value] of Object.entries(entryInput)) normalizedInput[key] = normalizePath(value, pkgDir);
464
+ return normalizedInput;
465
+ }
466
+ if (Array.isArray(entryInput)) return entryInput.map((p) => normalizePath(p, pkgDir));
467
+ return normalizePath(entryInput, pkgDir);
468
+ }
469
+ /**
470
+ * Get the entry input from a BundleEntry, supporting both 'input' and 'entry' fields.
471
+ * This provides tsup compatibility.
472
+ *
473
+ * @param entry - The bundle entry
474
+ * @returns The entry input or undefined
475
+ */
476
+ function getBundleEntryInput(entry) {
477
+ return entry.input || entry.entry;
478
+ }
479
+ /**
480
+ * Check if an entry has valid input.
481
+ *
482
+ * @param entry - The entry to check
483
+ * @returns true if the entry has valid input
484
+ */
485
+ function hasValidInput(entry) {
486
+ if (entry.type === "transform") return !!entry.input;
487
+ return !!getBundleEntryInput(entry);
488
+ }
489
+
490
+ //#endregion
491
+ //#region src/features/extensions.ts
492
+ /**
493
+ * Get file extension for a given format (with leading dot).
494
+ * This is the unified function used by bundle, watch, and transform modes.
495
+ *
496
+ * @param format - The module format (es, cjs, iife, umd, etc.)
497
+ * @param platform - The target platform
498
+ * @param fixedExtension - Whether to force .cjs/.mjs extensions
499
+ * @returns The file extension with leading dot (e.g., '.mjs', '.cjs', '.js')
500
+ */
501
+ function getFormatExtension(format, platform = "node", fixedExtension = false) {
502
+ if (fixedExtension) return format === "cjs" || format === "commonjs" ? ".cjs" : ".mjs";
503
+ switch (format) {
504
+ case "es":
505
+ case "esm":
506
+ case "module": return ".mjs";
507
+ case "cjs":
508
+ case "commonjs": return platform === "node" ? ".cjs" : ".js";
509
+ case "iife":
510
+ case "umd": return ".js";
511
+ default: return ".js";
512
+ }
513
+ }
514
+ /**
515
+ * Resolve JavaScript output extension (without leading dot).
516
+ * @deprecated Use getFormatExtension() instead for consistency
517
+ */
518
+ function resolveJsOutputExtension(format, platform = "node", fixedExtension = false) {
519
+ if (fixedExtension) return format === "cjs" ? "cjs" : "mjs";
520
+ switch (format) {
521
+ case "es": return platform === "browser" ? "js" : "mjs";
522
+ case "cjs": return platform === "browser" ? "js" : "cjs";
523
+ case "iife":
524
+ case "umd": return "js";
525
+ default: return "js";
526
+ }
527
+ }
528
+ /**
529
+ * Resolve DTS output extension
530
+ */
531
+ function resolveDtsOutputExtension(format, fixedExtension = false) {
532
+ if (fixedExtension) return format === "cjs" ? "d.cts" : "d.mts";
533
+ switch (format) {
534
+ case "es": return "d.mts";
535
+ case "cjs": return "d.cts";
536
+ default: return "d.ts";
537
+ }
538
+ }
539
+ /**
540
+ * Apply custom output extensions
541
+ */
542
+ function applyOutExtensions(format, outExtensions) {
543
+ const defaultJs = resolveJsOutputExtension(format);
544
+ const defaultDts = resolveDtsOutputExtension(format);
545
+ if (!outExtensions) return {
546
+ js: defaultJs,
547
+ dts: defaultDts
548
+ };
549
+ const custom = outExtensions(format);
550
+ return {
551
+ js: custom.js || defaultJs,
552
+ dts: custom.dts || defaultDts
553
+ };
554
+ }
555
+ /**
556
+ * Create filename with proper extension
557
+ */
558
+ function createFilename(basename, format, isDts = false, options = {}) {
559
+ const { platform, fixedExtension, outExtensions } = options;
560
+ if (outExtensions) {
561
+ const extensions = applyOutExtensions(format, outExtensions);
562
+ return `${basename}.${isDts ? extensions.dts : extensions.js}`;
563
+ }
564
+ if (isDts) return `${basename}.${resolveDtsOutputExtension(format, fixedExtension)}`;
565
+ return `${basename}.${resolveJsOutputExtension(format, platform, fixedExtension)}`;
210
566
  }
211
567
 
212
568
  //#endregion
@@ -313,7 +669,7 @@ function createGlobImportPlugin(options = {}) {
313
669
  if (optionsStr) try {
314
670
  globOptions = parseGlobOptions(optionsStr);
315
671
  } catch {
316
- console.warn("Failed to parse glob options:", optionsStr);
672
+ logger.warn("Failed to parse glob options:", optionsStr);
317
673
  }
318
674
  const isEager = globOptions.eager ?? eager;
319
675
  const isAsUrls = globOptions.as === "url" || asUrls;
@@ -321,7 +677,7 @@ function createGlobImportPlugin(options = {}) {
321
677
  const replacement = await generateGlobImport(pattern, id, isEager, isAsUrls, patterns);
322
678
  transformedCode = transformedCode.replace(fullMatch, replacement);
323
679
  } catch (error) {
324
- console.error(`Failed to process glob import ${pattern}:`, error);
680
+ logger.error(`Failed to process glob import ${pattern}:`, error);
325
681
  }
326
682
  }
327
683
  return hasGlobImports ? transformedCode : null;
@@ -603,203 +959,74 @@ function addNodeProtocol(id) {
603
959
  return id;
604
960
  }
605
961
  /**
606
- * Remove node: prefix from modules
607
- */
608
- function stripNodeProtocol(id) {
609
- if (id.startsWith("node:")) return id.slice(5);
610
- return id;
611
- }
612
- /**
613
- * Process module ID based on nodeProtocol setting
614
- */
615
- function processNodeProtocol(id, nodeProtocol) {
616
- if (nodeProtocol === "strip") return stripNodeProtocol(id);
617
- if (nodeProtocol === true) return addNodeProtocol(id);
618
- return id;
619
- }
620
- /**
621
- * Transform import/export statements to handle node protocol
622
- */
623
- function transformNodeProtocol(code, nodeProtocol) {
624
- if (!nodeProtocol) return code;
625
- return code.replace(/(?:import|export)(?:\s[^'"]*)?\s['"]([^'"]+)['"]/g, (match, moduleId) => {
626
- const processedId = processNodeProtocol(moduleId, nodeProtocol);
627
- return match.replace(moduleId, processedId);
628
- });
629
- }
630
-
631
- //#endregion
632
- //#region src/plugins/node-protocol.ts
633
- /**
634
- * Rolldown plugin for Node.js protocol handling
635
- */
636
- function nodeProtocolPlugin(nodeProtocol) {
637
- if (!nodeProtocol) return { name: "node-protocol-noop" };
638
- return {
639
- name: "node-protocol",
640
- renderChunk(code) {
641
- return {
642
- code: transformNodeProtocol(code, nodeProtocol),
643
- map: null
644
- };
645
- }
646
- };
647
- }
648
-
649
- //#endregion
650
- //#region src/plugins/shebang.ts
651
- const SHEBANG_RE = /^#![^\n]*/;
652
- function shebangPlugin() {
653
- return {
654
- name: "robuild-shebang",
655
- async writeBundle(options, bundle) {
656
- for (const [fileName, output] of Object.entries(bundle)) {
657
- if (output.type !== "chunk") continue;
658
- if (hasShebang(output.code)) await makeExecutable(resolve(options.dir, fileName));
659
- }
660
- }
661
- };
662
- }
663
- function hasShebang(code) {
664
- return SHEBANG_RE.test(code);
665
- }
666
- async function makeExecutable(filePath) {
667
- await promises.chmod(filePath, 493).catch(() => {});
668
- }
669
-
670
- //#endregion
671
- //#region src/utils.ts
672
- function fmtPath(path) {
673
- return resolve(path).replace(process.cwd(), ".");
674
- }
675
- function analyzeDir(dir) {
676
- if (Array.isArray(dir)) {
677
- let totalSize = 0;
678
- let totalFiles = 0;
679
- for (const d of dir) {
680
- const { size, files } = analyzeDir(d);
681
- totalSize += size;
682
- totalFiles += files;
683
- }
684
- return {
685
- size: totalSize,
686
- files: totalFiles
687
- };
688
- }
689
- let totalSize = 0;
690
- try {
691
- const files = readdirSync(dir, {
692
- withFileTypes: true,
693
- recursive: true
694
- });
695
- for (const file of files) {
696
- const fullPath = join(file.parentPath, file.name);
697
- if (file.isFile()) {
698
- const { size } = statSync(fullPath);
699
- totalSize += size;
700
- }
701
- }
702
- return {
703
- size: totalSize,
704
- files: files.length
705
- };
706
- } catch (error) {
707
- if (error.code === "ENOENT" || error.code === "ENOTDIR") return {
708
- size: 0,
709
- files: 0
710
- };
711
- throw error;
712
- }
713
- }
714
- async function distSize(dir, entry) {
715
- const { output } = await (await rolldown({
716
- input: join(dir, entry),
717
- plugins: [],
718
- platform: "neutral",
719
- external: (id) => id[0] !== "." && !id.startsWith(dir)
720
- })).generate({ inlineDynamicImports: true });
721
- const code = output[0].code;
722
- const { code: minified } = await minify(entry, code);
723
- return {
724
- size: Buffer.byteLength(code),
725
- minSize: Buffer.byteLength(minified),
726
- minGzipSize: gzipSync(minified).length
727
- };
728
- }
729
- async function sideEffectSize(dir, entry) {
730
- const { output } = await (await rolldown({
731
- input: "#entry",
732
- platform: "neutral",
733
- external: (id) => id[0] !== "." && !id.startsWith(dir),
734
- plugins: [{
735
- name: "virtual-entry",
736
- async resolveId(id, importer, opts) {
737
- if (id === "#entry") return { id };
738
- const resolved = await this.resolve(id, importer, opts);
739
- if (!resolved) return null;
740
- resolved.moduleSideEffects = null;
741
- return resolved;
742
- },
743
- load(id) {
744
- if (id === "#entry") return `import * as _lib from "${join(dir, entry)}";`;
745
- }
746
- }]
747
- })).generate({ inlineDynamicImports: true });
748
- if (process.env.INSPECT_BUILD) {
749
- console.log("---------[side effects]---------");
750
- console.log(entry);
751
- console.log(output[0].code);
752
- console.log("-------------------------------");
753
- }
754
- return Buffer.byteLength(output[0].code.trim());
755
- }
756
-
757
- //#endregion
758
- //#region src/builders/bundle.ts
759
- /**
760
- * Get file extension for format
962
+ * Remove node: prefix from modules
761
963
  */
762
- function getFormatExtension(format, platform, fixedExtension = false) {
763
- if (fixedExtension) return format === "cjs" ? ".cjs" : ".mjs";
764
- switch (format) {
765
- case "es":
766
- case "esm":
767
- case "module": return ".mjs";
768
- case "cjs":
769
- case "commonjs": return platform === "node" ? ".cjs" : ".js";
770
- case "iife":
771
- case "umd": return ".js";
772
- default: return ".js";
773
- }
964
+ function stripNodeProtocol(id) {
965
+ if (id.startsWith("node:")) return id.slice(5);
966
+ return id;
774
967
  }
775
968
  /**
776
- * Clean output directory
969
+ * Process module ID based on nodeProtocol setting
777
970
  */
778
- async function cleanOutputDir$1(projectRoot, outDir, cleanPaths) {
779
- if (!cleanPaths) return;
780
- const { rm } = await import("node:fs/promises");
781
- const { existsSync } = await import("node:fs");
782
- if (cleanPaths === true) {
783
- if (existsSync(outDir)) {
784
- consola.log(`🧻 Cleaning up ${fmtPath(outDir)}`);
785
- await rm(outDir, {
786
- recursive: true,
787
- force: true
788
- });
971
+ function processNodeProtocol(id, nodeProtocol) {
972
+ if (nodeProtocol === "strip") return stripNodeProtocol(id);
973
+ if (nodeProtocol === true) return addNodeProtocol(id);
974
+ return id;
975
+ }
976
+ /**
977
+ * Transform import/export statements to handle node protocol
978
+ */
979
+ function transformNodeProtocol(code, nodeProtocol) {
980
+ if (!nodeProtocol) return code;
981
+ return code.replace(/(?:import|export)(?:\s[^'"]*)?\s['"]([^'"]+)['"]/g, (match, moduleId) => {
982
+ const processedId = processNodeProtocol(moduleId, nodeProtocol);
983
+ return match.replace(moduleId, processedId);
984
+ });
985
+ }
986
+
987
+ //#endregion
988
+ //#region src/plugins/node-protocol.ts
989
+ /**
990
+ * Rolldown plugin for Node.js protocol handling
991
+ */
992
+ function nodeProtocolPlugin(nodeProtocol) {
993
+ if (!nodeProtocol) return { name: "node-protocol-noop" };
994
+ return {
995
+ name: "node-protocol",
996
+ renderChunk(code) {
997
+ return {
998
+ code: transformNodeProtocol(code, nodeProtocol),
999
+ map: null
1000
+ };
789
1001
  }
790
- } else if (Array.isArray(cleanPaths)) for (const path of cleanPaths) {
791
- const fullPath = resolve(projectRoot, path);
792
- if (existsSync(fullPath)) {
793
- consola.log(`🧻 Cleaning up ${fmtPath(fullPath)}`);
794
- await rm(fullPath, {
795
- recursive: true,
796
- force: true
797
- });
1002
+ };
1003
+ }
1004
+
1005
+ //#endregion
1006
+ //#region src/plugins/shebang.ts
1007
+ const SHEBANG_RE = /^#![^\n]*/;
1008
+ function shebangPlugin() {
1009
+ return {
1010
+ name: "robuild-shebang",
1011
+ async writeBundle(options, bundle) {
1012
+ for (const [fileName, output] of Object.entries(bundle)) {
1013
+ if (output.type !== "chunk") continue;
1014
+ if (hasShebang(output.code)) await makeExecutable(resolve(options.dir, fileName));
1015
+ }
798
1016
  }
799
- }
1017
+ };
1018
+ }
1019
+ function hasShebang(code) {
1020
+ return SHEBANG_RE.test(code);
1021
+ }
1022
+ async function makeExecutable(filePath) {
1023
+ await promises.chmod(filePath, 493).catch(() => {});
800
1024
  }
1025
+
1026
+ //#endregion
1027
+ //#region src/builders/bundle.ts
801
1028
  async function rolldownBuild(ctx, entry, hooks, config) {
802
- const entryInput = entry.input || entry.entry;
1029
+ const entryInput = getBundleEntryInput(entry);
803
1030
  if (!entryInput) throw new Error("Entry input is required");
804
1031
  const inputs = normalizeBundleInputs(entryInput, ctx);
805
1032
  const pluginManager = new RobuildPluginManager(config || {}, entry, ctx.pkgDir);
@@ -817,16 +1044,16 @@ async function rolldownBuild(ctx, entry, hooks, config) {
817
1044
  outDir: fullOutDir
818
1045
  });
819
1046
  await pluginManager.executeRobuildBuildStart();
820
- await cleanOutputDir$1(ctx.pkgDir, fullOutDir, entry.clean ?? true);
1047
+ await cleanOutputDir(ctx.pkgDir, fullOutDir, entry.clean ?? true);
821
1048
  if (entry.dtsOnly) {
822
- consola.info("Running in dtsOnly mode - only generating declaration files");
1049
+ logger.info("Running in dtsOnly mode - only generating declaration files");
823
1050
  entry.dts = entry.dts === false ? true : entry.dts || true;
824
1051
  }
825
1052
  if (entry.stub) {
826
1053
  for (const [distName, srcPath] of Object.entries(inputs)) {
827
1054
  const distPath = join(ctx.pkgDir, "dist", `${distName}.mjs`);
828
1055
  await mkdir(dirname(distPath), { recursive: true });
829
- consola.log(`${colors.magenta("[stub bundle] ")} ${colors.underline(fmtPath(distPath))}`);
1056
+ logger.log(`${colors.cyan("Stub")} ${colors.green(fmtPath(distPath))}`);
830
1057
  const srcContents = await readFile(srcPath, "utf8");
831
1058
  const hasDefaultExport = parseSync(srcPath, srcContents).module.staticExports.flatMap((e) => e.entries.map((e) => e.exportName.kind === "Default" ? "default" : e.exportName.name)).includes("default");
832
1059
  const firstLine = srcContents.split("\n")[0];
@@ -983,11 +1210,11 @@ async function rolldownBuild(ctx, entry, hooks, config) {
983
1210
  }
984
1211
  if (entry.copy) await copyFiles(ctx.pkgDir, fullOutDir, entry.copy);
985
1212
  await pluginManager.executeRobuildBuildEnd({ allOutputEntries });
986
- consola.log(`\n${allOutputEntries.map((o) => [
987
- `${colors.magenta(`[bundle] `)}${colors.underline(fmtPath(filePathMap.get(o.name) || join(fullOutDir, o.name)))}`,
988
- colors.dim(`${colors.bold("Size:")} ${prettyBytes(o.size)}, ${colors.bold(prettyBytes(o.minSize))} minified, ${prettyBytes(o.minGzipSize)} min+gzipped (Side effects: ${prettyBytes(o.sideEffectSize)})`),
989
- o.exports.some((e) => e !== "default") ? colors.dim(`${colors.bold("Exports:")} ${o.exports.map((e) => e).join(", ")}`) : "",
990
- o.deps.length > 0 ? colors.dim(`${colors.bold("Dependencies:")} ${o.deps.join(", ")}`) : ""
1213
+ logger.log(`\n${allOutputEntries.map((o) => [
1214
+ `${colors.cyan("Bundle")} ${colors.green(fmtPath(filePathMap.get(o.name) || join(fullOutDir, o.name)))}`,
1215
+ colors.dim(` ${prettyBytes(o.size)} / minified: ${prettyBytes(o.minSize)} / gzip: ${prettyBytes(o.minGzipSize)}`),
1216
+ o.exports.some((e) => e !== "default") ? colors.dim(` Exports: ${o.exports.map((e) => e).join(", ")}`) : "",
1217
+ o.deps.length > 0 ? colors.dim(` Dependencies: ${o.deps.join(", ")}`) : ""
991
1218
  ].filter(Boolean).join("\n")).join("\n\n")}`);
992
1219
  }
993
1220
  function normalizeBundleInputs(input, ctx) {
@@ -1026,111 +1253,30 @@ function normalizeBundleInputs(input, ctx) {
1026
1253
  return inputs;
1027
1254
  }
1028
1255
 
1029
- //#endregion
1030
- //#region src/features/extensions.ts
1031
- /**
1032
- * Resolve JavaScript output extension
1033
- */
1034
- function resolveJsOutputExtension(format, platform = "node", fixedExtension = false) {
1035
- if (fixedExtension) return format === "cjs" ? "cjs" : "mjs";
1036
- switch (format) {
1037
- case "es": return platform === "browser" ? "js" : "mjs";
1038
- case "cjs": return platform === "browser" ? "js" : "cjs";
1039
- case "iife":
1040
- case "umd": return "js";
1041
- default: return "js";
1042
- }
1043
- }
1044
- /**
1045
- * Resolve DTS output extension
1046
- */
1047
- function resolveDtsOutputExtension(format, fixedExtension = false) {
1048
- if (fixedExtension) return format === "cjs" ? "d.cts" : "d.mts";
1049
- switch (format) {
1050
- case "es": return "d.mts";
1051
- case "cjs": return "d.cts";
1052
- default: return "d.ts";
1053
- }
1054
- }
1055
- /**
1056
- * Apply custom output extensions
1057
- */
1058
- function applyOutExtensions(format, outExtensions) {
1059
- const defaultJs = resolveJsOutputExtension(format);
1060
- const defaultDts = resolveDtsOutputExtension(format);
1061
- if (!outExtensions) return {
1062
- js: defaultJs,
1063
- dts: defaultDts
1064
- };
1065
- const custom = outExtensions(format);
1066
- return {
1067
- js: custom.js || defaultJs,
1068
- dts: custom.dts || defaultDts
1069
- };
1070
- }
1071
- /**
1072
- * Create filename with proper extension
1073
- */
1074
- function createFilename(basename, format, isDts = false, options = {}) {
1075
- const { platform, fixedExtension, outExtensions } = options;
1076
- if (outExtensions) {
1077
- const extensions = applyOutExtensions(format, outExtensions);
1078
- return `${basename}.${isDts ? extensions.dts : extensions.js}`;
1079
- }
1080
- if (isDts) return `${basename}.${resolveDtsOutputExtension(format, fixedExtension)}`;
1081
- return `${basename}.${resolveJsOutputExtension(format, platform, fixedExtension)}`;
1082
- }
1083
-
1084
1256
  //#endregion
1085
1257
  //#region src/builders/transform.ts
1086
1258
  /**
1087
- * Clean output directory for transform entries
1088
- */
1089
- async function cleanOutputDir(projectRoot, outDir, cleanPaths) {
1090
- if (!cleanPaths) return;
1091
- const { rm } = await import("node:fs/promises");
1092
- const { existsSync } = await import("node:fs");
1093
- if (cleanPaths === true) {
1094
- if (existsSync(outDir)) {
1095
- consola.log(`🧻 Cleaning up ${fmtPath(outDir)}`);
1096
- await rm(outDir, {
1097
- recursive: true,
1098
- force: true
1099
- });
1100
- }
1101
- } else if (Array.isArray(cleanPaths)) for (const path of cleanPaths) {
1102
- const fullPath = resolve(projectRoot, path);
1103
- if (existsSync(fullPath)) {
1104
- consola.log(`🧻 Cleaning up ${fmtPath(fullPath)}`);
1105
- await rm(fullPath, {
1106
- recursive: true,
1107
- force: true
1108
- });
1109
- }
1110
- }
1111
- }
1112
- /**
1113
1259
  * Transform all .ts modules in a directory using oxc-transform.
1114
1260
  */
1115
1261
  async function transformDir(ctx, entry) {
1116
1262
  if (entry.stub) {
1117
- consola.log(`${colors.magenta("[stub transform] ")} ${colors.underline(`${fmtPath(entry.outDir)}/`)}`);
1263
+ logger.log(`${colors.cyan("Stub")} ${colors.green(`${fmtPath(entry.outDir)}/`)}`);
1118
1264
  await symlink(entry.input, entry.outDir, "junction");
1119
1265
  return;
1120
1266
  }
1121
1267
  if (entry.unbundle) {
1122
- consola.log(`${colors.magenta("[unbundle] ")} ${colors.underline(`${fmtPath(entry.outDir)}/`)}`);
1268
+ logger.log(`${colors.cyan("Unbundle")} ${colors.green(`${fmtPath(entry.outDir)}/`)}`);
1123
1269
  await unbundleTransform(ctx, entry);
1124
1270
  return;
1125
1271
  }
1126
- const fullOutDir = resolve(ctx.pkgDir, entry.outDir);
1272
+ const fullOutDir = normalizePath(entry.outDir || "dist", ctx.pkgDir);
1127
1273
  await cleanOutputDir(ctx.pkgDir, fullOutDir, entry.clean ?? true);
1128
1274
  const { statSync } = await import("node:fs");
1129
1275
  let inputDir = entry.input;
1130
1276
  try {
1131
1277
  if (statSync(inputDir).isFile()) {
1132
1278
  inputDir = dirname(inputDir);
1133
- consola.warn(`Transform input should be a directory, not a file. Using directory: ${fmtPath(inputDir)}`);
1279
+ logger.warn(`Transform input should be a directory, not a file. Using directory: ${fmtPath(inputDir)}`);
1134
1280
  }
1135
1281
  } catch (error) {
1136
1282
  if (error.code !== "ENOENT") throw error;
@@ -1183,7 +1329,7 @@ async function transformDir(ctx, entry) {
1183
1329
  })());
1184
1330
  const writtenFiles = await Promise.all(promises);
1185
1331
  if (entry.copy) await copyFiles(ctx.pkgDir, fullOutDir, entry.copy);
1186
- consola.log(`\n${colors.magenta("[transform] ")}${colors.underline(`${fmtPath(entry.outDir)}/`)}\n${writtenFiles.map((f) => colors.dim(fmtPath(f))).join("\n\n")}`);
1332
+ logger.log(`\n${colors.cyan("Transform")} ${colors.green(`${fmtPath(entry.outDir)}/`)} ${colors.dim(`(${writtenFiles.length} files)`)}`);
1187
1333
  }
1188
1334
  /**
1189
1335
  * Transform a .ts module using oxc-transform.
@@ -1268,89 +1414,6 @@ async function transformModule(entryPath, entry) {
1268
1414
  return transformed;
1269
1415
  }
1270
1416
 
1271
- //#endregion
1272
- //#region src/features/logger.ts
1273
- /**
1274
- * Logger instance with configurable log level
1275
- */
1276
- var Logger = class {
1277
- level = "info";
1278
- warningCount = 0;
1279
- errorCount = 0;
1280
- constructor(level = "info") {
1281
- this.level = level;
1282
- this.updateConsolaLevel();
1283
- }
1284
- setLevel(level) {
1285
- this.level = level;
1286
- this.updateConsolaLevel();
1287
- }
1288
- updateConsolaLevel() {
1289
- consola.level = {
1290
- silent: 0,
1291
- error: 1,
1292
- warn: 2,
1293
- info: 3,
1294
- verbose: 4
1295
- }[this.level];
1296
- }
1297
- silent(message, ...args) {
1298
- console.log(message, ...args);
1299
- }
1300
- error(message, ...args) {
1301
- this.errorCount++;
1302
- consola.error(message, ...args);
1303
- }
1304
- warn(message, ...args) {
1305
- this.warningCount++;
1306
- consola.warn(message, ...args);
1307
- }
1308
- info(message, ...args) {
1309
- consola.info(message, ...args);
1310
- }
1311
- verbose(message, ...args) {
1312
- if (this.level === "verbose") consola.debug(message, ...args);
1313
- }
1314
- success(message, ...args) {
1315
- consola.success(message, ...args);
1316
- }
1317
- log(message, ...args) {
1318
- consola.log(message, ...args);
1319
- }
1320
- getWarningCount() {
1321
- return this.warningCount;
1322
- }
1323
- getErrorCount() {
1324
- return this.errorCount;
1325
- }
1326
- resetCounts() {
1327
- this.warningCount = 0;
1328
- this.errorCount = 0;
1329
- }
1330
- shouldFailOnWarnings(failOnWarn) {
1331
- return failOnWarn && this.warningCount > 0;
1332
- }
1333
- };
1334
- const logger = new Logger();
1335
- /**
1336
- * Configure global logger
1337
- */
1338
- function configureLogger(level) {
1339
- logger.setLevel(level);
1340
- }
1341
- /**
1342
- * Reset warning and error counts
1343
- */
1344
- function resetLogCounts() {
1345
- logger.resetCounts();
1346
- }
1347
- /**
1348
- * Check if build should fail due to warnings
1349
- */
1350
- function shouldFailOnWarnings(failOnWarn) {
1351
- return logger.shouldFailOnWarnings(failOnWarn);
1352
- }
1353
-
1354
1417
  //#endregion
1355
1418
  //#region src/features/on-success.ts
1356
1419
  const execAsync = promisify(exec);
@@ -1501,14 +1564,11 @@ function convertExternal(external) {
1501
1564
 
1502
1565
  //#endregion
1503
1566
  //#region src/watch.ts
1504
- function normalizePath$1(path, resolveFrom) {
1505
- return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
1506
- }
1507
1567
  /**
1508
1568
  * Perform watch build using rolldown's built-in watch mode
1509
1569
  */
1510
1570
  async function performWatchBuild(config, ctx, startTime) {
1511
- const { performBuild } = await import("./build-Cm8LX2zF.mjs");
1571
+ const { performBuild } = await import("./build-tpynh1ZI.mjs");
1512
1572
  await performBuild(config, ctx, startTime);
1513
1573
  const bundleEntries = (config.entries || []).filter((entry) => {
1514
1574
  if (typeof entry === "string") return !entry.endsWith("/");
@@ -1528,45 +1588,22 @@ async function performWatchBuild(config, ctx, startTime) {
1528
1588
  * The watch mode then monitors for file changes and triggers rebuilds.
1529
1589
  */
1530
1590
  async function startRolldownWatch(config, ctx, bundleEntries) {
1531
- logger.info("🚧 Using rolldown built-in watch mode...");
1591
+ logger.info("Watching for changes...");
1532
1592
  const { RobuildPluginManager } = await import("./plugin-manager-pCQvlo7q.mjs");
1533
1593
  const watchConfigs = [];
1534
1594
  for (const rawEntry of bundleEntries) {
1535
- let entry;
1536
- if (typeof rawEntry === "string") {
1537
- const [input, outDir] = rawEntry.split(":");
1538
- entry = {
1539
- type: "bundle",
1540
- input,
1541
- outDir: outDir || "dist"
1542
- };
1543
- } else entry = rawEntry;
1544
- const entryInput = entry.input || entry.entry;
1595
+ const entry = typeof rawEntry === "string" ? parseEntryString(rawEntry) : rawEntry;
1596
+ const entryInput = getBundleEntryInput(entry);
1545
1597
  if (!entryInput) {
1546
1598
  logger.warn("Skipping entry without input:", entry);
1547
1599
  continue;
1548
1600
  }
1549
- let normalizedInput;
1550
- if (typeof entryInput === "object" && !Array.isArray(entryInput)) {
1551
- const normalizedObj = {};
1552
- for (const [key, value] of Object.entries(entryInput)) normalizedObj[key] = normalizePath$1(value, ctx.pkgDir);
1553
- normalizedInput = normalizedObj;
1554
- } else if (Array.isArray(entryInput)) normalizedInput = entryInput.map((i) => normalizePath$1(i, ctx.pkgDir));
1555
- else normalizedInput = normalizePath$1(entryInput, ctx.pkgDir);
1601
+ const normalizedInput = normalizeEntryInput(entryInput, ctx.pkgDir);
1556
1602
  const target = entry.target || "es2022";
1557
1603
  const platform = entry.platform || "node";
1558
1604
  const format = entry.format || "es";
1559
- const getExtension = (fmt) => {
1560
- switch (fmt) {
1561
- case "es": return ".mjs";
1562
- case "cjs": return ".cjs";
1563
- case "iife":
1564
- case "umd": return ".js";
1565
- default: return ".mjs";
1566
- }
1567
- };
1568
- const extension = getExtension(Array.isArray(format) ? format[0] : format);
1569
1605
  const rolldownFormat = Array.isArray(format) ? format[0] : format;
1606
+ const extension = getFormatExtension(rolldownFormat, platform);
1570
1607
  const formatMap = {
1571
1608
  esm: "es",
1572
1609
  cjs: "cjs",
@@ -1601,24 +1638,20 @@ async function startRolldownWatch(config, ctx, bundleEntries) {
1601
1638
  watcher.on("event", (event) => {
1602
1639
  switch (event.code) {
1603
1640
  case "START":
1604
- logger.info("🔄 Rebuilding...");
1605
- break;
1606
- case "BUNDLE_START":
1607
- logger.info("📦 Bundling...");
1608
- break;
1609
- case "BUNDLE_END":
1610
- logger.success("✅ Bundle complete");
1641
+ logger.info("Rebuilding...");
1611
1642
  break;
1643
+ case "BUNDLE_START": break;
1644
+ case "BUNDLE_END": break;
1612
1645
  case "END":
1613
- logger.success("🎉 Watch rebuild complete");
1646
+ logger.success("Rebuilt");
1614
1647
  break;
1615
1648
  case "ERROR":
1616
- logger.error("Build error:", event.error);
1649
+ logger.error("Build error:", event.error);
1617
1650
  break;
1618
1651
  }
1619
1652
  });
1620
1653
  const cleanup = async () => {
1621
- consola.info("🛑 Stopping watch mode...");
1654
+ logger.info("Stopping watch mode...");
1622
1655
  await watcher.close();
1623
1656
  process.exit(0);
1624
1657
  };
@@ -1704,11 +1737,11 @@ async function build(config) {
1704
1737
  }
1705
1738
  finalConfig = normalizeTsupConfig(finalConfig);
1706
1739
  if (finalConfig.watch?.enabled) {
1707
- logger.info(`👀 Starting watch mode for \`${ctx.pkg.name || "<no name>"}\` (\`${ctx.pkgDir}\`)`);
1740
+ logger.info(`Watching ${colors.cyan(ctx.pkg.name || "<unnamed>")}`);
1708
1741
  await performWatchBuild(finalConfig, ctx, startTime);
1709
1742
  return;
1710
1743
  }
1711
- logger.info(`📦 Building \`${ctx.pkg.name || "<no name>"}\` (\`${ctx.pkgDir}\`)`);
1744
+ logger.info(`Building ${colors.cyan(ctx.pkg.name || "<unnamed>")}`);
1712
1745
  await performBuild(finalConfig, ctx, startTime);
1713
1746
  }
1714
1747
  /**
@@ -1719,34 +1752,17 @@ async function performBuild(config, ctx, startTime) {
1719
1752
  const hooks = config.hooks || {};
1720
1753
  await hooks.start?.(ctx);
1721
1754
  const entries = (config.entries || []).map((rawEntry) => {
1722
- let entry;
1723
- if (typeof rawEntry === "string") {
1724
- const [input, outDir] = rawEntry.split(":");
1725
- entry = input.endsWith("/") ? {
1726
- type: "transform",
1727
- input,
1728
- outDir
1729
- } : {
1730
- type: "bundle",
1731
- input: input.split(","),
1732
- outDir
1733
- };
1734
- } else entry = rawEntry;
1755
+ let entry = typeof rawEntry === "string" ? parseEntryString(rawEntry) : rawEntry;
1735
1756
  if (entry.type === "bundle") entry = inheritConfig(entry, config);
1736
1757
  else if (entry.type === "transform") entry = inheritConfig(entry, config);
1737
- if (!(entry.type === "transform" ? !!entry.input : !!(entry.input || entry.entry))) throw new Error(`Build entry missing \`input\` or \`entry\`: ${JSON.stringify(entry, null, 2)}`);
1758
+ if (!hasValidInput(entry)) throw new Error(`Build entry missing \`input\` or \`entry\`: ${JSON.stringify(entry, null, 2)}`);
1738
1759
  entry = { ...entry };
1739
1760
  entry.outDir = normalizePath(entry.outDir || "dist", ctx.pkgDir);
1740
1761
  if (entry.type === "transform") {
1741
1762
  if (entry.input) entry.input = normalizePath(entry.input, ctx.pkgDir);
1742
1763
  } else {
1743
- const entryInput = entry.input || entry.entry;
1744
- if (entryInput) if (typeof entryInput === "object" && !Array.isArray(entryInput)) {
1745
- const normalizedInput = {};
1746
- for (const [key, value] of Object.entries(entryInput)) normalizedInput[key] = normalizePath(value, ctx.pkgDir);
1747
- entry.input = normalizedInput;
1748
- } else if (Array.isArray(entryInput)) entry.input = entryInput.map((p) => normalizePath(p, ctx.pkgDir));
1749
- else entry.input = normalizePath(entryInput, ctx.pkgDir);
1764
+ const entryInput = getBundleEntryInput(entry);
1765
+ if (entryInput) entry.input = normalizeEntryInput(entryInput, ctx.pkgDir);
1750
1766
  }
1751
1767
  return entry;
1752
1768
  });
@@ -1757,20 +1773,17 @@ async function performBuild(config, ctx, startTime) {
1757
1773
  await hooks.end?.(ctx);
1758
1774
  if (shouldFailOnWarnings(config.failOnWarn || false)) throw new Error("Build failed due to warnings");
1759
1775
  const dirSize = analyzeDir(outDirs);
1760
- logger.info(colors.dim(`\nΣ Total dist byte size: ${colors.underline(prettyBytes(dirSize.size))} (${colors.underline(dirSize.files)} files)`));
1776
+ logger.info(colors.dim(`\nTotal: ${colors.bold(prettyBytes(dirSize.size))} (${dirSize.files} files)`));
1761
1777
  const duration = Date.now() - start;
1762
- logger.success(`\n✅ robuild finished in ${duration}ms`);
1778
+ logger.success(`\nBuild succeeded in ${colors.bold(`${duration}ms`)}`);
1763
1779
  if (config.onSuccess) {
1764
1780
  const buildResult = createBuildResult([], startTime);
1765
1781
  await executeOnSuccess(config.onSuccess, buildResult, ctx.pkgDir);
1766
1782
  }
1767
1783
  }
1768
- function normalizePath(path, resolveFrom) {
1769
- return typeof path === "string" && isAbsolute(path) ? path : path instanceof URL ? fileURLToPath(path) : resolve(resolveFrom || ".", path || ".");
1770
- }
1771
1784
  async function readJSON(specifier) {
1772
1785
  return (await import(specifier, { with: { type: "json" } })).default;
1773
1786
  }
1774
1787
 
1775
1788
  //#endregion
1776
- export { makeExecutable as a, hasShebang as i, performBuild as n, shebangPlugin as o, SHEBANG_RE as r, nodeProtocolPlugin as s, build as t };
1789
+ export { makeExecutable as a, configureLogger as c, hasShebang as i, logger as l, performBuild as n, shebangPlugin as o, SHEBANG_RE as r, nodeProtocolPlugin as s, build as t };
@@ -0,0 +1,3 @@
1
+ import { n as performBuild, t as build } from "./build-DbAuaVYJ.mjs";
2
+
3
+ export { performBuild };
@@ -2,7 +2,7 @@
2
2
  var package_default = {
3
3
  name: "robuild",
4
4
  type: "module",
5
- version: "0.0.19",
5
+ version: "0.1.0",
6
6
  packageManager: "pnpm@10.11.1",
7
7
  description: "Zero-config ESM/TS package builder. Powered by Rolldown and Oxc",
8
8
  license: "MIT",
package/dist/cli.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { t as build } from "./_chunks/build-snxBrML1.mjs";
2
+ import { c as configureLogger, l as logger, t as build } from "./_chunks/build-DbAuaVYJ.mjs";
3
3
  import { colors } from "consola/utils";
4
- import { consola } from "consola";
5
4
  import process from "node:process";
6
5
  import { loadConfig } from "c12";
7
6
  import { cac } from "cac";
@@ -17,14 +16,13 @@ cli.command("[...entries]", "Bundle or transform files", {
17
16
  try {
18
17
  await runBuild(entries, flags);
19
18
  } catch (error) {
20
- consola.error(error);
19
+ logger.error(String(error));
21
20
  process.exit(1);
22
21
  }
23
22
  });
24
23
  async function runBuild(entries, flags) {
25
- if (flags.logLevel) consola.level = flags.logLevel === "silent" ? 0 : flags.logLevel === "verbose" ? 5 : 3;
26
- consola.info(`robuild ${colors.dim(`v${pkg.default.version}`)}`);
27
- consola.info("");
24
+ if (flags.logLevel) configureLogger(flags.logLevel);
25
+ logger.info(`${colors.cyan("robuild")} ${colors.dim(`v${pkg.default.version}`)}`);
28
26
  const configOptions = {
29
27
  name: "robuild",
30
28
  cwd: flags.dir || "."
@@ -102,8 +100,8 @@ async function runBuild(entries, flags) {
102
100
  });
103
101
  if (flags.stub) for (const entry of processedEntries) entry.stub = true;
104
102
  if (rawEntries.length === 0) {
105
- consola.error("No build entries specified.");
106
- consola.info("Run `robuild --help` for usage information.");
103
+ logger.error("No build entries specified.");
104
+ logger.info("Run `robuild --help` for usage information.");
107
105
  process.exit(1);
108
106
  }
109
107
  await build({
@@ -130,7 +128,7 @@ cli.parse(process.argv, { run: false });
130
128
  try {
131
129
  await cli.runMatchedCommand();
132
130
  } catch (error) {
133
- consola.error(error);
131
+ logger.error(String(error));
134
132
  process.exit(1);
135
133
  }
136
134
 
package/dist/config.d.mts CHANGED
@@ -13,7 +13,7 @@ type Platform = 'browser' | 'node' | 'neutral';
13
13
  /**
14
14
  * Target ES version
15
15
  */
16
- type Target = 'es5' | 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'esnext';
16
+ type Target = 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'esnext';
17
17
  interface CopyEntry {
18
18
  from: string;
19
19
  to: string;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as makeExecutable, i as hasShebang, o as shebangPlugin, r as SHEBANG_RE, s as nodeProtocolPlugin, t as build } from "./_chunks/build-snxBrML1.mjs";
1
+ import { a as makeExecutable, i as hasShebang, l as logger, o as shebangPlugin, r as SHEBANG_RE, s as nodeProtocolPlugin, t as build } from "./_chunks/build-DbAuaVYJ.mjs";
2
2
  import { defineConfig } from "./config.mjs";
3
3
 
4
4
  //#region src/features/plugin-utils.ts
@@ -132,7 +132,7 @@ function textPlugin(extensions = [".txt", ".md"]) {
132
132
  const content = await readFile(id, "utf-8");
133
133
  return `export default ${JSON.stringify(content)}`;
134
134
  } catch (error) {
135
- console.error(`Failed to load text file ${id}:`, error);
135
+ logger.error(`Failed to load text file ${id}:`, error);
136
136
  return null;
137
137
  }
138
138
  return null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "robuild",
3
3
  "type": "module",
4
- "version": "0.0.19",
4
+ "version": "0.1.0",
5
5
  "packageManager": "pnpm@10.11.1",
6
6
  "description": "Zero-config ESM/TS package builder. Powered by Rolldown and Oxc",
7
7
  "license": "MIT",
@@ -1,3 +0,0 @@
1
- import { n as performBuild, t as build } from "./build-snxBrML1.mjs";
2
-
3
- export { performBuild };