zshy 0.2.4 → 0.3.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.
package/dist/main.js CHANGED
@@ -73,7 +73,6 @@ Examples:
73
73
  const isVerbose = !!args["--verbose"];
74
74
  const isDryRun = !!args["--dry-run"];
75
75
  const failThreshold = args["--fail-threshold"] || "error"; // Default to 'error'
76
- const dryRunPrefix = isDryRun ? "[dryrun] " : "";
77
76
  const isCjsInterop = true; // Enable CJS interop for testing
78
77
  // Validate that the threshold value is one of the allowed values
79
78
  if (failThreshold !== "never" && failThreshold !== "warn" && failThreshold !== "error") {
@@ -141,35 +140,35 @@ Examples:
141
140
  /////////////////////////////////
142
141
  // const pkgJson = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
143
142
  const CONFIG_KEY = "zshy";
144
- let config;
143
+ let rawConfig;
145
144
  if (!pkgJson[CONFIG_KEY]) {
146
145
  emojiLog("❌", `No "${CONFIG_KEY}" key found in package.json`, "error");
147
146
  process.exit(1);
148
147
  }
149
148
  if (typeof pkgJson[CONFIG_KEY] === "string") {
150
- config = {
149
+ rawConfig = {
151
150
  exports: { ".": pkgJson[CONFIG_KEY] },
152
151
  };
153
152
  }
154
153
  else if (typeof pkgJson[CONFIG_KEY] === "object") {
155
- config = { ...pkgJson[CONFIG_KEY] };
156
- if (typeof config.exports === "string") {
157
- config.exports = { ".": config.exports };
154
+ rawConfig = { ...pkgJson[CONFIG_KEY] };
155
+ if (typeof rawConfig.exports === "string") {
156
+ rawConfig.exports = { ".": rawConfig.exports };
158
157
  }
159
- else if (typeof config.exports === "undefined") {
158
+ else if (typeof rawConfig.exports === "undefined") {
160
159
  emojiLog("❌", `Missing "exports" key in package.json#/${CONFIG_KEY}`, "error");
161
160
  process.exit(1);
162
161
  }
163
- else if (typeof config.exports !== "object") {
162
+ else if (typeof rawConfig.exports !== "object") {
164
163
  emojiLog("❌", `Invalid "exports" key in package.json#/${CONFIG_KEY}`, "error");
165
164
  process.exit(1);
166
165
  }
167
166
  // Validate bin field if present
168
- if (config.bin !== undefined) {
169
- if (typeof config.bin === "string") {
167
+ if (rawConfig.bin !== undefined) {
168
+ if (typeof rawConfig.bin === "string") {
170
169
  // Keep string format - we'll handle this in entry point extraction
171
170
  }
172
- else if (typeof config.bin === "object" && config.bin !== null) {
171
+ else if (typeof rawConfig.bin === "object" && rawConfig.bin !== null) {
173
172
  // Object format is valid
174
173
  }
175
174
  else {
@@ -177,9 +176,22 @@ Examples:
177
176
  process.exit(1);
178
177
  }
179
178
  }
180
- // {
181
- // exports: { ".": pkgJson[CONFIG_KEY].exports },
182
- // };
179
+ // Validate conditions field if present
180
+ if (rawConfig.conditions !== undefined) {
181
+ if (typeof rawConfig.conditions === "object" && rawConfig.conditions !== null) {
182
+ // const { import: importCondition, require: requireCondition, ...rest } = config.conditions;
183
+ for (const [condition, value] of Object.entries(rawConfig.conditions)) {
184
+ if (value !== "esm" && value !== "cjs" && value !== "src") {
185
+ emojiLog("❌", `Invalid condition value "${value}" for "${condition}" in package.json#/${CONFIG_KEY}/conditions. Valid values are "esm", "cjs", "src", or null`, "error");
186
+ process.exit(1);
187
+ }
188
+ }
189
+ }
190
+ else {
191
+ emojiLog("❌", `Invalid "conditions" key in package.json#/${CONFIG_KEY}, expected object`, "error");
192
+ process.exit(1);
193
+ }
194
+ }
183
195
  }
184
196
  else if (typeof pkgJson[CONFIG_KEY] === "undefined") {
185
197
  emojiLog("❌", `Missing "${CONFIG_KEY}" key in package.json`, "error");
@@ -190,7 +202,32 @@ Examples:
190
202
  process.exit(1);
191
203
  }
192
204
  if (isVerbose) {
193
- emojiLog("🔧", `Parsed zshy config: ${formatForLog(config)}`);
205
+ emojiLog("🔧", `Parsed zshy config: ${formatForLog(rawConfig)}`);
206
+ }
207
+ // Check for deprecated sourceDialects
208
+ if ("sourceDialects" in rawConfig) {
209
+ emojiLog("❌", 'The "sourceDialects" option is no longer supported. Use "conditions" instead to configure custom export conditions.', "error");
210
+ process.exit(1);
211
+ }
212
+ const config = { ...rawConfig };
213
+ // Normalize cjs property
214
+ if (config.cjs === undefined) {
215
+ config.cjs = true; // Default to true if not specified
216
+ }
217
+ config.noEdit ?? (config.noEdit = false);
218
+ // Validate that if cjs is disabled, no conditions are set to "cjs"
219
+ if (config.cjs === false && config.conditions) {
220
+ const cjsConditions = Object.entries(config.conditions).filter(([_, value]) => value === "cjs");
221
+ if (cjsConditions.length > 0) {
222
+ const conditionNames = cjsConditions.map(([name]) => name).join(", ");
223
+ emojiLog("❌", `CJS is disabled (cjs: false) but the following conditions are set to "cjs": ${conditionNames}. Either enable CJS or change these conditions.`, "error");
224
+ process.exit(1);
225
+ }
226
+ }
227
+ // Validate that if cjs is disabled, package.json type must be "module"
228
+ if (config.cjs === false && pkgJson.type !== "module") {
229
+ emojiLog("❌", `CJS is disabled (cjs: false) but package.json#/type is not set to "module". When disabling CommonJS builds, you must set "type": "module" in your package.json.`, "error");
230
+ process.exit(1);
194
231
  }
195
232
  ///////////////////////////
196
233
  /// read tsconfig ///
@@ -301,7 +338,7 @@ Examples:
301
338
  emojiLog("➡️", "Determining entrypoints...");
302
339
  const entryPoints = [];
303
340
  const rows = [["Subpath", "Entrypoint"]];
304
- for (const [exportPath, sourcePath] of Object.entries(config.exports)) {
341
+ for (const [exportPath, sourcePath] of Object.entries(config.exports ?? {})) {
305
342
  if (exportPath.includes("package.json"))
306
343
  continue;
307
344
  let cleanExportPath;
@@ -387,7 +424,7 @@ Examples:
387
424
  // process.exit(1);
388
425
  // }
389
426
  if (entryPoints.length === 0) {
390
- emojiLog("❌", "No entry points found matching the specified patterns in package.json#/zshy exports", "error");
427
+ emojiLog("❌", "No entry points found matching the specified patterns in package.json#/zshy exports or bin", "error");
391
428
  process.exit(1);
392
429
  }
393
430
  ///////////////////////////////
@@ -449,13 +486,14 @@ Examples:
449
486
  //////////////////////////////////////////////
450
487
  /// clean up outDir and declarationDir ///
451
488
  //////////////////////////////////////////////
489
+ const prefix = isDryRun ? "[dryrun] " : "";
452
490
  if (relRootDir.startsWith(relOutDir)) {
453
- emojiLog("🗑️", `${dryRunPrefix}Skipping cleanup of outDir as it contains source files`);
491
+ emojiLog("🗑️", `${prefix}Skipping cleanup of outDir as it contains source files`);
454
492
  }
455
493
  else {
456
494
  // source files are in the outDir, so skip cleanup
457
495
  // clean up outDir and declarationDir
458
- emojiLog("🗑️", `${dryRunPrefix}Cleaning up outDir...`);
496
+ emojiLog("🗑️", `${prefix}Cleaning up outDir...`);
459
497
  if (!isDryRun) {
460
498
  fs.rmSync(outDir, { recursive: true, force: true });
461
499
  // // print success message in verbose mode
@@ -470,10 +508,10 @@ Examples:
470
508
  // already done
471
509
  }
472
510
  else if (relRootDir.startsWith(relDeclarationDir)) {
473
- emojiLog("🗑️", `${dryRunPrefix}Skipping cleanup of declarationDir as it contains source files`);
511
+ emojiLog("🗑️", `${prefix}Skipping cleanup of declarationDir as it contains source files`);
474
512
  }
475
513
  else {
476
- emojiLog("🗑️", `${dryRunPrefix}Cleaning up declarationDir...`);
514
+ emojiLog("🗑️", `${prefix}Cleaning up declarationDir...`);
477
515
  if (!isDryRun) {
478
516
  fs.rmSync(declarationDir, { recursive: true, force: true });
479
517
  // // print success message in verbose mode
@@ -488,24 +526,27 @@ Examples:
488
526
  /// compile tsc ///
489
527
  ///////////////////////////////
490
528
  const uniqueEntryPoints = [...new Set(entryPoints)];
491
- try {
492
- if (isVerbose) {
493
- emojiLog("→", `Resolved entrypoints: ${formatForLog(uniqueEntryPoints)}`);
494
- emojiLog("→", `Resolved compilerOptions: ${formatForLog({
495
- ...tsconfigJson,
496
- module: ts.ModuleKind[tsconfigJson.module],
497
- moduleResolution: ts.ModuleResolutionKind[tsconfigJson.moduleResolution],
498
- target: ts.ScriptTarget[tsconfigJson.target],
499
- })}`);
500
- }
501
- // Create a build context to track written files, copied assets, and compilation errors/warnings
502
- const buildContext = {
503
- writtenFiles: new Set(),
504
- copiedAssets: new Set(),
505
- errorCount: 0,
506
- warningCount: 0,
507
- };
508
- // CJS
529
+ // try {
530
+ if (isVerbose) {
531
+ emojiLog("→", `Resolved entrypoints: ${formatForLog(uniqueEntryPoints)}`);
532
+ emojiLog("→", `Resolved compilerOptions: ${formatForLog({
533
+ ...tsconfigJson,
534
+ module: ts.ModuleKind[tsconfigJson.module],
535
+ moduleResolution: ts.ModuleResolutionKind[tsconfigJson.moduleResolution],
536
+ target: ts.ScriptTarget[tsconfigJson.target],
537
+ })}`);
538
+ }
539
+ // Create a build context to track written files, copied assets, and compilation errors/warnings
540
+ const buildContext = {
541
+ writtenFiles: new Set(),
542
+ copiedAssets: new Set(),
543
+ errorCount: 0,
544
+ warningCount: 0,
545
+ };
546
+ // Check if CJS should be skipped
547
+ const skipCjs = config.cjs === false;
548
+ // CJS
549
+ if (!skipCjs) {
509
550
  emojiLog("🧱", `Building CJS...${isTypeModule ? ` (rewriting .ts -> .cjs/.d.cts)` : ``}`);
510
551
  await compileProject({
511
552
  configPath: tsconfigPath,
@@ -523,230 +564,272 @@ Examples:
523
564
  outDir,
524
565
  },
525
566
  }, uniqueEntryPoints, buildContext);
526
- // ESM
527
- emojiLog("🧱", `Building ESM...${isTypeModule ? `` : ` (rewriting .ts -> .mjs/.d.mts)`}`);
528
- await compileProject({
529
- configPath: tsconfigPath,
530
- ext: isTypeModule ? "js" : "mjs",
531
- format: "esm",
532
- verbose: isVerbose,
533
- dryRun: isDryRun,
534
- pkgJsonDir,
535
- rootDir,
536
- cjsInterop: isCjsInterop,
537
- compilerOptions: {
538
- ...tsconfigJson,
539
- module: ts.ModuleKind.ESNext,
540
- moduleResolution: ts.ModuleResolutionKind.Bundler,
541
- outDir,
542
- },
543
- }, uniqueEntryPoints, buildContext);
544
- ///////////////////////////////////
545
- /// display written files ///
546
- ///////////////////////////////////
547
- // Display files that were written or would be written (only in verbose mode)
548
- if (isVerbose && buildContext.writtenFiles.size > 0) {
549
- emojiLog("📜", `${dryRunPrefix}Writing files (${buildContext.writtenFiles.size} total)...`);
550
- // Sort files by relative path for consistent display
551
- const sortedFiles = [...buildContext.writtenFiles]
552
- .map((file) => relativePosix(pkgJsonDir, file))
553
- .sort()
554
- .map((relPath) => (relPath.startsWith(".") ? relPath : `./${relPath}`));
555
- sortedFiles.forEach((file) => {
556
- console.log(` ${file}`);
557
- });
558
- }
559
- ///////////////////////////////
560
- /// generate exports ///
561
- ///////////////////////////////
562
- // generate package.json exports
563
- emojiLog("📦", `${dryRunPrefix}Updating package.json#/exports...`);
567
+ }
568
+ else {
569
+ emojiLog("⏭️", "Skipping CJS build (cjs: false)");
570
+ }
571
+ // ESM
572
+ emojiLog("🧱", `Building ESM...${isTypeModule ? `` : ` (rewriting .ts -> .mjs/.d.mts)`}`);
573
+ await compileProject({
574
+ configPath: tsconfigPath,
575
+ ext: isTypeModule ? "js" : "mjs",
576
+ format: "esm",
577
+ verbose: isVerbose,
578
+ dryRun: isDryRun,
579
+ pkgJsonDir,
580
+ rootDir,
581
+ cjsInterop: isCjsInterop,
582
+ compilerOptions: {
583
+ ...tsconfigJson,
584
+ module: ts.ModuleKind.ESNext,
585
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
586
+ outDir,
587
+ },
588
+ }, uniqueEntryPoints, buildContext);
589
+ ///////////////////////////////////
590
+ /// display written files ///
591
+ ///////////////////////////////////
592
+ // Display files that were written or would be written (only in verbose mode)
593
+ if (isVerbose && buildContext.writtenFiles.size > 0) {
594
+ emojiLog("📜", `${prefix}Writing files (${buildContext.writtenFiles.size} total)...`);
595
+ // Sort files by relative path for consistent display
596
+ const sortedFiles = [...buildContext.writtenFiles]
597
+ .map((file) => relativePosix(pkgJsonDir, file))
598
+ .sort()
599
+ .map((relPath) => (relPath.startsWith(".") ? relPath : `./${relPath}`));
600
+ sortedFiles.forEach((file) => {
601
+ console.log(` ${file}`);
602
+ });
603
+ }
604
+ ///////////////////////////////
605
+ /// generate exports ///
606
+ ///////////////////////////////
607
+ // generate package.json exports
608
+ if (config.noEdit) {
609
+ emojiLog("📦", "[noedit] Skipping modification of package.json");
610
+ }
611
+ else {
564
612
  // Generate exports based on zshy config
565
613
  const newExports = {};
566
- const sourceDialects = config.sourceDialects || [];
567
- for (const [exportPath, sourcePath] of Object.entries(config.exports)) {
568
- if (exportPath.includes("package.json")) {
569
- newExports[exportPath] = sourcePath;
570
- continue;
571
- }
572
- const absSourcePath = path.resolve(pkgJsonDir, sourcePath);
573
- const relSourcePath = path.relative(rootDir, absSourcePath);
574
- const absJsPath = path.resolve(outDir, relSourcePath);
575
- const absDtsPath = path.resolve(declarationDir, relSourcePath);
576
- let relJsPath = "./" + relativePosix(pkgJsonDir, absJsPath);
577
- let relDtsPath = "./" + relativePosix(pkgJsonDir, absDtsPath);
578
- if (typeof sourcePath === "string") {
579
- if (sourcePath.endsWith("/*") || sourcePath.endsWith("/**/*")) {
580
- // Handle wildcard exports
581
- const finalExportPath = exportPath;
582
- if (finalExportPath.includes("**")) {
583
- emojiLog("❌", `Export keys cannot contain "**": ${finalExportPath}`, "error");
584
- process.exit(1);
585
- }
586
- // Convert deep glob patterns to simple wildcard patterns in the final export
587
- if (sourcePath.endsWith("/**/*")) {
588
- // Also convert the output paths from /**/* to /*
589
- if (relJsPath.endsWith("/**/*")) {
590
- relJsPath = relJsPath.slice(0, -5) + "/*";
614
+ if (config.exports) {
615
+ // const newExports: Record<string, any> = {};
616
+ emojiLog("📦", `${prefix}Updating package.json...`);
617
+ for (const [exportPath, sourcePath] of Object.entries(config.exports)) {
618
+ if (exportPath.includes("package.json")) {
619
+ newExports[exportPath] = sourcePath;
620
+ continue;
621
+ }
622
+ const absSourcePath = path.resolve(pkgJsonDir, sourcePath);
623
+ const relSourcePath = path.relative(rootDir, absSourcePath);
624
+ const absJsPath = path.resolve(outDir, relSourcePath);
625
+ const absDtsPath = path.resolve(declarationDir, relSourcePath);
626
+ let relJsPath = "./" + relativePosix(pkgJsonDir, absJsPath);
627
+ let relDtsPath = "./" + relativePosix(pkgJsonDir, absDtsPath);
628
+ if (typeof sourcePath === "string") {
629
+ if (sourcePath.endsWith("/*") || sourcePath.endsWith("/**/*")) {
630
+ // Handle wildcard exports
631
+ const finalExportPath = exportPath;
632
+ if (finalExportPath.includes("**")) {
633
+ emojiLog("❌", `Export keys cannot contain "**": ${finalExportPath}`, "error");
634
+ process.exit(1);
591
635
  }
592
- if (relDtsPath.endsWith("/**/*")) {
593
- relDtsPath = relDtsPath.slice(0, -5) + "/*";
636
+ // Convert deep glob patterns to simple wildcard patterns in the final export
637
+ if (sourcePath.endsWith("/**/*")) {
638
+ // Also convert the output paths from /**/* to /*
639
+ if (relJsPath.endsWith("/**/*")) {
640
+ relJsPath = relJsPath.slice(0, -5) + "/*";
641
+ }
642
+ if (relDtsPath.endsWith("/**/*")) {
643
+ relDtsPath = relDtsPath.slice(0, -5) + "/*";
644
+ }
594
645
  }
646
+ // Build exports object with proper condition ordering
647
+ const exportObj = {};
648
+ // Add custom conditions first in their original order
649
+ if (config.conditions) {
650
+ for (const [condition, value] of Object.entries(config.conditions)) {
651
+ if (value === "src") {
652
+ exportObj[condition] = sourcePath;
653
+ }
654
+ else if (value === "esm") {
655
+ exportObj[condition] = relJsPath;
656
+ }
657
+ else if (value === "cjs") {
658
+ exportObj[condition] = relJsPath;
659
+ }
660
+ }
661
+ }
662
+ // Add standard conditions
663
+ exportObj.types = relDtsPath;
664
+ exportObj.import = relJsPath;
665
+ if (!skipCjs) {
666
+ exportObj.require = relJsPath;
667
+ }
668
+ newExports[finalExportPath] = exportObj;
595
669
  }
596
- newExports[finalExportPath] = {
597
- types: relDtsPath,
598
- import: relJsPath,
599
- require: relJsPath,
600
- };
601
- for (const sd of sourceDialects) {
602
- newExports[finalExportPath] = {
603
- [sd]: sourcePath,
604
- ...newExports[finalExportPath],
605
- };
670
+ else if (isSourceFile(sourcePath)) {
671
+ const esmPath = removeExtension(relJsPath) + (isTypeModule ? `.js` : `.mjs`);
672
+ const cjsPath = removeExtension(relJsPath) + (isTypeModule ? `.cjs` : `.js`);
673
+ // Use ESM type declarations when CJS is skipped, otherwise use CJS declarations
674
+ const dtsExt = skipCjs ? (isTypeModule ? ".d.ts" : ".d.mts") : isTypeModule ? ".d.cts" : ".d.ts";
675
+ const dtsPath = removeExtension(relDtsPath) + dtsExt;
676
+ // Build exports object with proper condition ordering
677
+ const exportObj = {};
678
+ // Add custom conditions first in their original order
679
+ if (config.conditions) {
680
+ for (const [condition, value] of Object.entries(config.conditions)) {
681
+ if (value === "src") {
682
+ exportObj[condition] = sourcePath;
683
+ }
684
+ else if (value === "esm") {
685
+ exportObj[condition] = esmPath;
686
+ }
687
+ else if (value === "cjs") {
688
+ exportObj[condition] = cjsPath;
689
+ }
690
+ }
691
+ }
692
+ // Add standard conditions
693
+ exportObj.types = dtsPath;
694
+ exportObj.import = esmPath;
695
+ if (!skipCjs) {
696
+ exportObj.require = cjsPath;
697
+ }
698
+ newExports[exportPath] = exportObj;
699
+ if (exportPath === ".") {
700
+ if (!skipCjs) {
701
+ pkgJson.main = cjsPath;
702
+ pkgJson.module = esmPath;
703
+ pkgJson.types = dtsPath;
704
+ }
705
+ else {
706
+ // Only set module and types, not main
707
+ pkgJson.module = esmPath;
708
+ pkgJson.types = dtsPath;
709
+ }
710
+ if (isVerbose && !config.noEdit) {
711
+ emojiLog("🔧", `Setting "main": ${formatForLog(cjsPath)}`);
712
+ emojiLog("🔧", `Setting "module": ${formatForLog(esmPath)}`);
713
+ emojiLog("🔧", `Setting "types": ${formatForLog(dtsPath)}`);
714
+ }
715
+ }
606
716
  }
607
717
  }
608
- else if (isSourceFile(sourcePath)) {
609
- const esmPath = removeExtension(relJsPath) + (isTypeModule ? `.js` : `.mjs`);
610
- const cjsPath = removeExtension(relJsPath) + (isTypeModule ? `.cjs` : `.js`);
611
- const dtsPath = removeExtension(relDtsPath) + (isTypeModule ? `.d.cts` : `.d.ts`);
612
- newExports[exportPath] = {
613
- types: dtsPath,
614
- import: esmPath,
615
- require: cjsPath,
616
- };
617
- if (exportPath === ".") {
618
- pkgJson.main = cjsPath;
619
- pkgJson.module = esmPath;
620
- pkgJson.types = dtsPath;
621
- }
622
- for (const sd of sourceDialects) {
623
- newExports[exportPath] = {
624
- [sd]: sourcePath,
625
- ...newExports[exportPath],
626
- };
718
+ }
719
+ if (isVerbose && !config.noEdit) {
720
+ emojiLog("🔧", `Setting "exports": ${formatForLog(newExports)}`);
721
+ }
722
+ ///////////////////////////////
723
+ /// generate bin ///
724
+ ///////////////////////////////
725
+ // Generate bin field based on zshy bin config
726
+ if (config.bin) {
727
+ emojiLog("📦", `${prefix}Updating package.json#/bin...`);
728
+ const newBin = {};
729
+ // Convert config.bin to object format for processing
730
+ const binEntries = typeof config.bin === "string" ? [[pkgJson.name, config.bin]] : Object.entries(config.bin);
731
+ for (const [binName, sourcePath] of binEntries) {
732
+ if (typeof sourcePath === "string" && isSourceFile(sourcePath)) {
733
+ const absSourcePath = path.resolve(pkgJsonDir, sourcePath);
734
+ const relSourcePath = path.relative(rootDir, absSourcePath);
735
+ const absJsPath = path.resolve(outDir, relSourcePath);
736
+ const relJsPath = "./" + relativePosix(pkgJsonDir, absJsPath);
737
+ // Use ESM files for bin when CJS is skipped, otherwise use CJS
738
+ const binExt = skipCjs ? (isTypeModule ? ".js" : ".mjs") : isTypeModule ? ".cjs" : ".js";
739
+ const binPath = removeExtension(relJsPath) + binExt;
740
+ newBin[binName] = binPath;
627
741
  }
628
742
  }
743
+ // If original config.bin was a string, output as string
744
+ if (typeof config.bin === "string") {
745
+ pkgJson.bin = Object.values(newBin)[0];
746
+ }
629
747
  else {
630
- emojiLog("❌", `Invalid entrypoint: ${sourcePath}`, "error");
631
- process.exit();
748
+ // Output as object
749
+ pkgJson.bin = newBin;
632
750
  }
633
- }
634
- }
635
- if (isVerbose) {
636
- emojiLog("🔧", `Generated "exports": ${formatForLog(newExports)}`);
637
- }
638
- ///////////////////////////////
639
- /// generate bin ///
640
- ///////////////////////////////
641
- // Generate bin field based on zshy bin config
642
- if (config.bin) {
643
- emojiLog("📦", `${dryRunPrefix}Updating package.json#/bin...`);
644
- const newBin = {};
645
- // Convert config.bin to object format for processing
646
- const binEntries = typeof config.bin === "string" ? [[pkgJson.name, config.bin]] : Object.entries(config.bin);
647
- for (const [binName, sourcePath] of binEntries) {
648
- if (typeof sourcePath === "string" && isSourceFile(sourcePath)) {
649
- const absSourcePath = path.resolve(pkgJsonDir, sourcePath);
650
- const relSourcePath = path.relative(rootDir, absSourcePath);
651
- const absJsPath = path.resolve(outDir, relSourcePath);
652
- const relJsPath = "./" + relativePosix(pkgJsonDir, absJsPath);
653
- // Use CommonJS entrypoint for bin
654
- const binPath = removeExtension(relJsPath) + (isTypeModule ? `.cjs` : `.js`);
655
- newBin[binName] = binPath;
751
+ if (isVerbose && !config.noEdit) {
752
+ emojiLog("🔧", `Setting "bin": ${formatForLog(pkgJson.bin)}`);
656
753
  }
657
754
  }
658
- // If original config.bin was a string, output as string
659
- if (typeof config.bin === "string") {
660
- pkgJson.bin = Object.values(newBin)[0];
661
- }
662
- else {
663
- // Output as object
664
- pkgJson.bin = newBin;
665
- }
666
- if (isVerbose) {
667
- emojiLog("🔧", `Generated "bin": ${formatForLog(pkgJson.bin)}`);
668
- }
669
- }
670
- ///////////////////////////////
671
- /// write pkg json ///
672
- ///////////////////////////////
673
- // Update package.json with new exports
674
- pkgJson.exports = newExports;
675
- if (isDryRun) {
676
- emojiLog("📦", "[dryrun] Skipping package.json modification");
677
- }
678
- else {
679
- fs.writeFileSync(packageJsonPath, JSON.stringify(pkgJson, null, indent) + "\n");
680
- }
681
- if (isAttw) {
682
- // run `@arethetypeswrong/cli --pack .` to check types
683
- emojiLog("🔍", "Checking types with @arethetypeswrong/cli...");
684
- const { execFile } = await import("node:child_process");
685
- const { promisify } = await import("node:util");
686
- const execFileAsync = promisify(execFile);
687
- const [cmd, ...args] = `${pmExec} @arethetypeswrong/cli --pack ${pkgJsonDir} --format table-flipped`.split(" ");
688
- console.dir([cmd, ...args], { depth: null });
689
- let stdout = "";
690
- let stderr = "";
691
- let exitCode = 0;
692
- try {
693
- const result = await execFileAsync(cmd, args, {
694
- cwd: pkgJsonDir,
695
- encoding: "utf-8",
696
- });
697
- stdout = result.stdout;
698
- stderr = result.stderr;
755
+ ///////////////////////////////
756
+ /// write pkg json ///
757
+ ///////////////////////////////
758
+ if (isDryRun) {
759
+ emojiLog("📦", "[dryrun] Skipping package.json modification");
699
760
  }
700
- catch (error) {
701
- stdout = error.stdout || "";
702
- stderr = error.stderr || "";
703
- exitCode = error.code || 1;
761
+ else if (config.noEdit) {
762
+ emojiLog("📦", "[noedit] Skipping package.json modification");
704
763
  }
705
- const output = stdout || stderr;
706
- if (output) {
707
- const indentedOutput = output
708
- .split("\n")
709
- .map((line) => ` ${line}`)
710
- .join("\n");
711
- if (exitCode === 0) {
712
- console.log(indentedOutput);
713
- }
714
- else {
715
- console.error(indentedOutput);
716
- emojiLog("⚠️", "ATTW found issues, but the build was not affected.", "warn");
717
- }
764
+ else {
765
+ fs.writeFileSync(packageJsonPath, JSON.stringify(pkgJson, null, indent) + "\n");
718
766
  }
719
767
  }
720
- // Report total compilation results
721
- if (buildContext.errorCount > 0 || buildContext.warningCount > 0) {
722
- emojiLog("📊", `Compilation finished with ${buildContext.errorCount} error(s) and ${buildContext.warningCount} warning(s)`);
723
- // Apply threshold rules for exit code
724
- if (failThreshold !== "never" && buildContext.errorCount > 0) {
725
- // Both 'warn' and 'error' thresholds cause failure on errors
726
- emojiLog("❌", `Build completed with errors`, "error");
727
- process.exit(1);
728
- }
729
- else if (failThreshold === "warn" && buildContext.warningCount > 0) {
730
- // Only 'warn' threshold causes failure on warnings
731
- emojiLog("⚠️", `Build completed with warnings (exiting with error due to --fail-threshold=warn)`, "warn");
732
- process.exit(1);
733
- }
734
- else if (buildContext.errorCount > 0) {
735
- // If we got here with errors, we're in 'never' mode
736
- emojiLog("⚠️", `Build completed with errors (continuing due to --fail-threshold=never)`, "warn");
768
+ }
769
+ if (isAttw) {
770
+ // run `@arethetypeswrong/cli --pack .` to check types
771
+ emojiLog("🔍", "Checking types with @arethetypeswrong/cli...");
772
+ const { execFile } = await import("node:child_process");
773
+ const { promisify } = await import("node:util");
774
+ const execFileAsync = promisify(execFile);
775
+ const [cmd, ...args] = `${pmExec} @arethetypeswrong/cli --pack ${pkgJsonDir} --format table-flipped`.split(" ");
776
+ console.dir([cmd, ...args], { depth: null });
777
+ let stdout = "";
778
+ let stderr = "";
779
+ let exitCode = 0;
780
+ try {
781
+ const result = await execFileAsync(cmd, args, {
782
+ cwd: pkgJsonDir,
783
+ encoding: "utf-8",
784
+ });
785
+ stdout = result.stdout;
786
+ stderr = result.stderr;
787
+ }
788
+ catch (error) {
789
+ stdout = error.stdout || "";
790
+ stderr = error.stderr || "";
791
+ exitCode = error.code || 1;
792
+ }
793
+ const output = stdout || stderr;
794
+ if (output) {
795
+ const indentedOutput = output
796
+ .split("\n")
797
+ .map((line) => ` ${line}`)
798
+ .join("\n");
799
+ if (exitCode === 0) {
800
+ console.log(indentedOutput);
737
801
  }
738
802
  else {
739
- // Just warnings and not failing on them
740
- emojiLog("🎉", `Build complete with warnings`);
803
+ console.error(indentedOutput);
804
+ emojiLog("⚠️", "ATTW found issues, but the build was not affected.", "warn");
741
805
  }
742
806
  }
807
+ }
808
+ // Report total compilation results
809
+ if (buildContext.errorCount > 0 || buildContext.warningCount > 0) {
810
+ emojiLog("📊", `Compilation finished with ${buildContext.errorCount} error(s) and ${buildContext.warningCount} warning(s)`);
811
+ // Apply threshold rules for exit code
812
+ if (failThreshold !== "never" && buildContext.errorCount > 0) {
813
+ // Both 'warn' and 'error' thresholds cause failure on errors
814
+ emojiLog("❌", `Build completed with errors`, "error");
815
+ process.exit(1);
816
+ }
817
+ else if (failThreshold === "warn" && buildContext.warningCount > 0) {
818
+ // Only 'warn' threshold causes failure on warnings
819
+ emojiLog("⚠️", `Build completed with warnings (exiting with error due to --fail-threshold=warn)`, "warn");
820
+ process.exit(1);
821
+ }
822
+ else if (buildContext.errorCount > 0) {
823
+ // If we got here with errors, we're in 'never' mode
824
+ emojiLog("⚠️", `Build completed with errors (continuing due to --fail-threshold=never)`, "warn");
825
+ }
743
826
  else {
744
- emojiLog("🎉", "Build complete! ✅");
827
+ // Just warnings and not failing on them
828
+ emojiLog("🎉", `Build complete with warnings`);
745
829
  }
746
830
  }
747
- catch (error) {
748
- emojiLog("❌", `Build failed: ${error}`, "error");
749
- process.exit(1);
831
+ else {
832
+ emojiLog("🎉", "Build complete! ✅");
750
833
  }
751
834
  }
752
835
  //# sourceMappingURL=main.js.map