@tscircuit/cli 0.1.975 → 0.1.976

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/cli/main.js CHANGED
@@ -74395,7 +74395,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
74395
74395
  import { execSync as execSync2 } from "node:child_process";
74396
74396
  var import_semver2 = __toESM2(require_semver2(), 1);
74397
74397
  // package.json
74398
- var version = "0.1.974";
74398
+ var version = "0.1.975";
74399
74399
  var package_default = {
74400
74400
  name: "@tscircuit/cli",
74401
74401
  main: "dist/cli/main.js",
@@ -174470,202 +174470,89 @@ var registerRemove = (program3) => {
174470
174470
  };
174471
174471
 
174472
174472
  // cli/build/register.ts
174473
- import path55 from "node:path";
174474
174473
  import fs54 from "node:fs";
174474
+ import path55 from "node:path";
174475
174475
 
174476
- // cli/build/build-file.ts
174477
- import path42 from "node:path";
174478
- import fs42 from "node:fs";
174476
+ // lib/site/getStaticIndexHtmlFile.ts
174477
+ var getStaticIndexHtmlFile = ({
174478
+ files,
174479
+ standaloneScriptSrc = "./standalone.min.js",
174480
+ defaultMainComponentPath,
174481
+ packageName
174482
+ }) => {
174483
+ const scriptLines = [
174484
+ "window.TSCIRCUIT_USE_RUNFRAME_FOR_CLI = false;",
174485
+ `window.TSCIRCUIT_RUNFRAME_STATIC_FILE_LIST = ${JSON.stringify(files)};`,
174486
+ ...defaultMainComponentPath ? [
174487
+ `window.TSCIRCUIT_DEFAULT_MAIN_COMPONENT_PATH = ${JSON.stringify(defaultMainComponentPath)};`
174488
+ ] : [],
174489
+ ...packageName ? [`window.TSCIRCUIT_PACKAGE_NAME = ${JSON.stringify(packageName)};`] : []
174490
+ ];
174491
+ const scriptBlock = ` <script>
174492
+ ${scriptLines.join(`
174493
+ `)}
174494
+ </script>
174495
+ `;
174496
+ return `<html>
174497
+ <head>
174498
+ <link rel="icon" type="image/png" href="https://github.com/tscircuit.png">
174499
+ <meta charset="UTF-8" />
174500
+ <title>tscircuit</title>
174501
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
174502
+ </head>
174503
+ <body>
174504
+ ${scriptBlock} <script src="https://cdn.tailwindcss.com"></script>
174505
+ <div id="root">loading...</div>
174506
+ <script>
174507
+ globalThis.process = { env: { NODE_ENV: "production" } }
174508
+ </script>
174509
+ <script type="module" src="${standaloneScriptSrc}"></script>
174510
+ </body>
174511
+ </html>`;
174512
+ };
174479
174513
 
174480
- // lib/shared/circuit-json-diagnostics.ts
174481
- function analyzeCircuitJson(circuitJson) {
174482
- const errors = [];
174483
- const warnings = [];
174484
- for (const item of circuitJson) {
174485
- if (!item || typeof item !== "object")
174486
- continue;
174487
- const t3 = item.type;
174488
- if (typeof t3 === "string") {
174489
- if (t3.endsWith("_error"))
174490
- errors.push(item);
174491
- else if (t3.endsWith("_warning"))
174492
- warnings.push(item);
174493
- }
174494
- if ("error_type" in item)
174495
- errors.push(item);
174496
- if ("warning_type" in item)
174497
- warnings.push(item);
174514
+ // cli/utils/get-latest-tscircuit-cdn-url.ts
174515
+ var TSCIRCUIT_NPMJS_API_URL = "https://registry.npmjs.org/tscircuit/latest";
174516
+ async function getLatestTscircuitCdnVersion() {
174517
+ const response = await fetch(TSCIRCUIT_NPMJS_API_URL);
174518
+ if (!response.ok) {
174519
+ throw new Error(`Failed to fetch tscircuit version from CDN: ${response.statusText}`);
174498
174520
  }
174499
- return { errors, warnings };
174500
- }
174501
-
174502
- // lib/shared/get-complete-platform-config.ts
174503
- import { getPlatformConfig } from "@tscircuit/eval/platform-config";
174504
- import { createHash } from "node:crypto";
174505
- import path41 from "node:path";
174506
- import fs41 from "node:fs";
174507
- function createLocalCacheEngine(cacheDir = path41.join(process.cwd(), ".tscircuit", "cache")) {
174508
- return {
174509
- getItem: (key) => {
174510
- try {
174511
- const hash = createHash("md5").update(key).digest("hex");
174512
- const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
174513
- const filePath = path41.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
174514
- return fs41.readFileSync(filePath, "utf-8");
174515
- } catch {
174516
- return null;
174517
- }
174518
- },
174519
- setItem: (key, value) => {
174520
- try {
174521
- fs41.mkdirSync(cacheDir, { recursive: true });
174522
- const hash = createHash("md5").update(key).digest("hex");
174523
- const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
174524
- const filePath = path41.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
174525
- fs41.writeFileSync(filePath, value);
174526
- } catch {}
174527
- }
174528
- };
174521
+ const data = await response.json();
174522
+ return data.version;
174529
174523
  }
174530
- function getCompletePlatformConfig(userConfig) {
174531
- const basePlatformConfig = getPlatformConfig();
174532
- const defaultConfig = {
174533
- ...basePlatformConfig,
174534
- localCacheEngine: createLocalCacheEngine(),
174535
- footprintFileParserMap: {
174536
- ...basePlatformConfig.footprintFileParserMap,
174537
- kicad_mod: {
174538
- loadFromUrl: async (url) => {
174539
- let fetchUrl = url;
174540
- if (url.startsWith("./") || url.startsWith("../")) {
174541
- const absolutePath = path41.resolve(process.cwd(), url);
174542
- fetchUrl = `file://${absolutePath}`;
174543
- } else if (url.startsWith("/")) {
174544
- if (fs41.existsSync(url)) {
174545
- fetchUrl = `file://${url}`;
174546
- } else {
174547
- const relativePath = `.${url}`;
174548
- const absolutePath = path41.resolve(process.cwd(), relativePath);
174549
- if (fs41.existsSync(absolutePath)) {
174550
- fetchUrl = `file://${absolutePath}`;
174551
- } else {
174552
- fetchUrl = `file://${url}`;
174553
- }
174554
- }
174555
- }
174556
- return basePlatformConfig.footprintFileParserMap.kicad_mod.loadFromUrl(fetchUrl);
174557
- }
174558
- }
174559
- }
174560
- };
174561
- if (!userConfig) {
174562
- return defaultConfig;
174563
- }
174564
- return {
174565
- ...defaultConfig,
174566
- ...userConfig,
174567
- footprintFileParserMap: {
174568
- ...defaultConfig.footprintFileParserMap,
174569
- ...userConfig.footprintFileParserMap
174570
- }
174571
- };
174524
+ async function getLatestTscircuitCdnUrl() {
174525
+ const version2 = await getLatestTscircuitCdnVersion();
174526
+ return `https://cdn.jsdelivr.net/npm/tscircuit@${version2}/dist/browser.min.js`;
174572
174527
  }
174573
174528
 
174574
- // cli/build/build-file.ts
174575
- var buildFile = async (input, output, projectDir, options) => {
174576
- try {
174577
- console.log("Generating circuit JSON...");
174578
- const completePlatformConfig = getCompletePlatformConfig(options?.platformConfig);
174579
- const result = await generateCircuitJson({
174580
- filePath: input,
174581
- platformConfig: completePlatformConfig
174582
- });
174583
- fs42.mkdirSync(path42.dirname(output), { recursive: true });
174584
- fs42.writeFileSync(output, JSON.stringify(result.circuitJson, null, 2));
174585
- console.log(`Circuit JSON written to ${path42.relative(projectDir, output)}`);
174586
- const { errors, warnings } = analyzeCircuitJson(result.circuitJson);
174587
- if (!options?.ignoreWarnings) {
174588
- for (const warn of warnings) {
174589
- const msg = warn.message || JSON.stringify(warn);
174590
- console.log(kleur_default.yellow(msg));
174591
- }
174592
- }
174593
- if (!options?.ignoreErrors) {
174594
- for (const err of errors) {
174595
- const msg = err.message || JSON.stringify(err);
174596
- console.error(kleur_default.red(msg));
174597
- if (err.stack) {
174598
- console.log(err.stack);
174599
- }
174600
- }
174601
- }
174602
- if (errors.length > 0 && !options?.ignoreErrors) {
174603
- console.error(kleur_default.red(`Build failed with ${errors.length} error(s). Use --ignore-errors to continue.`));
174604
- return { ok: false };
174605
- } else {
174606
- return {
174607
- ok: true,
174608
- circuitJson: result.circuitJson
174609
- };
174610
- }
174611
- } catch (err) {
174612
- console.error(err);
174613
- if (err instanceof Error) {
174614
- logTsxExtensionHint(err, input);
174615
- logTypeReexportHint(err, input);
174616
- }
174617
- return {
174618
- ok: false,
174619
- isFatalError: {
174620
- errorType: "circuit_generation_failed",
174621
- message: err instanceof Error ? err.message : String(err)
174622
- }
174623
- };
174624
- }
174625
- };
174626
- var logTsxExtensionHint = (error, entryFilePath) => {
174627
- const lowerPath = entryFilePath.toLowerCase();
174628
- const isTsEntry = lowerPath.endsWith(".ts") && !lowerPath.endsWith(".d.ts");
174629
- const isAggregateError = error instanceof AggregateError || String(error).includes("AggregateError");
174630
- if (!isTsEntry || !isAggregateError)
174529
+ // cli/utils/validate-main-in-dist.ts
174530
+ import fs41 from "node:fs";
174531
+ import path41 from "node:path";
174532
+ var validateMainInDist = (projectDir, distDir) => {
174533
+ const packageJsonPath = path41.join(projectDir, "package.json");
174534
+ if (!fs41.existsSync(packageJsonPath))
174631
174535
  return;
174632
- const entryFileName = path42.basename(entryFilePath);
174633
- console.error([
174634
- "",
174635
- `It looks like "${entryFileName}" is a ".ts" file. tscircuit component files must use the ".tsx" extension.`,
174636
- "Try renaming the file to .tsx and re-running the build.",
174637
- ""
174638
- ].join(`
174639
- `));
174640
- };
174641
- var TYPE_REEXPORT_ERROR_REGEX = /SyntaxError: export '([^']+)' not found in '([^']+)'/;
174642
- var logTypeReexportHint = (error, entryFilePath) => {
174643
- const match = String(error).match(TYPE_REEXPORT_ERROR_REGEX);
174644
- if (!match)
174536
+ const packageJson = JSON.parse(fs41.readFileSync(packageJsonPath, "utf-8"));
174537
+ if (typeof packageJson.main !== "string")
174645
174538
  return;
174646
- const [, exportName, fromSpecifier] = match;
174647
- const entryFileName = path42.basename(entryFilePath);
174648
- console.error([
174649
- "",
174650
- `It looks like "${entryFileName}" re-exports the type-only symbol "${exportName}" from "${fromSpecifier}" without the "type" modifier.`,
174651
- "Type-only exports must be re-exported with `export type { ... }`.",
174652
- "Try rewriting the statement as:",
174653
- ` export type { ${exportName} } from "${fromSpecifier}"`,
174654
- ""
174655
- ].join(`
174656
- `));
174539
+ const resolvedMainPath = path41.resolve(projectDir, packageJson.main);
174540
+ const isMainInDist = resolvedMainPath === distDir || resolvedMainPath.startsWith(`${distDir}${path41.sep}`);
174541
+ if (!isMainInDist) {
174542
+ console.warn('When using transpilation, your package\'s "main" field should point inside the `dist/*` directory, usually to "dist/index.js"');
174543
+ }
174657
174544
  };
174658
174545
 
174659
174546
  // cli/build/build-ci.ts
174660
174547
  import { execSync as execSync3 } from "node:child_process";
174661
174548
 
174662
174549
  // lib/shared/install-project-dependencies.ts
174663
- import fs44 from "node:fs";
174664
- import path44 from "node:path";
174665
-
174666
- // lib/shared/collect-tsci-dependencies.ts
174667
174550
  import fs43 from "node:fs";
174668
174551
  import path43 from "node:path";
174552
+
174553
+ // lib/shared/collect-tsci-dependencies.ts
174554
+ import fs42 from "node:fs";
174555
+ import path42 from "node:path";
174669
174556
  var DEFAULT_PATTERNS = ["**/*.{ts,tsx,js,jsx}"];
174670
174557
  var DEFAULT_IGNORES = [
174671
174558
  "**/node_modules/**",
@@ -174680,7 +174567,7 @@ function collectTsciDependencies({
174680
174567
  patterns = DEFAULT_PATTERNS,
174681
174568
  ignore = DEFAULT_IGNORES
174682
174569
  } = {}) {
174683
- const searchRoot = path43.resolve(cwd);
174570
+ const searchRoot = path42.resolve(cwd);
174684
174571
  const files = globbySync(patterns, {
174685
174572
  cwd: searchRoot,
174686
174573
  absolute: true,
@@ -174690,7 +174577,7 @@ function collectTsciDependencies({
174690
174577
  const dependencies2 = new Set;
174691
174578
  for (const filePath of files) {
174692
174579
  try {
174693
- const fileContents = fs43.readFileSync(filePath, "utf-8");
174580
+ const fileContents = fs42.readFileSync(filePath, "utf-8");
174694
174581
  let match;
174695
174582
  while (true) {
174696
174583
  match = IMPORT_PATTERN.exec(fileContents);
@@ -174714,31 +174601,31 @@ async function installProjectDependencies({
174714
174601
  cwd = process.cwd(),
174715
174602
  skipTscircuitPackage = false
174716
174603
  } = {}) {
174717
- const projectRoot = path44.resolve(cwd);
174718
- const packageJsonPath = path44.join(projectRoot, "package.json");
174719
- const npmrcPath = path44.join(projectRoot, ".npmrc");
174604
+ const projectRoot = path43.resolve(cwd);
174605
+ const packageJsonPath = path43.join(projectRoot, "package.json");
174606
+ const npmrcPath = path43.join(projectRoot, ".npmrc");
174720
174607
  const packageManager = getPackageManager();
174721
- if (!fs44.existsSync(projectRoot)) {
174608
+ if (!fs43.existsSync(projectRoot)) {
174722
174609
  throw new Error(`Directory not found: ${projectRoot}`);
174723
174610
  }
174724
174611
  let packageJsonCreated = false;
174725
- if (!fs44.existsSync(packageJsonPath)) {
174612
+ if (!fs43.existsSync(packageJsonPath)) {
174726
174613
  console.log("No package.json found. Generating a new one.");
174727
174614
  generatePackageJson(projectRoot);
174728
174615
  packageJsonCreated = true;
174729
174616
  } else {
174730
174617
  console.log("Found existing package.json.");
174731
174618
  }
174732
- const tsconfigPath = path44.join(projectRoot, "tsconfig.json");
174733
- if (!fs44.existsSync(tsconfigPath)) {
174619
+ const tsconfigPath = path43.join(projectRoot, "tsconfig.json");
174620
+ if (!fs43.existsSync(tsconfigPath)) {
174734
174621
  console.log("No tsconfig.json found. Generating a new one.");
174735
174622
  generateTsConfig(projectRoot);
174736
174623
  }
174737
- if (!fs44.existsSync(npmrcPath)) {
174624
+ if (!fs43.existsSync(npmrcPath)) {
174738
174625
  console.log("Creating .npmrc with tscircuit registry configuration.");
174739
- fs44.writeFileSync(npmrcPath, "@tsci:registry=https://npm.tscircuit.com");
174626
+ fs43.writeFileSync(npmrcPath, "@tsci:registry=https://npm.tscircuit.com");
174740
174627
  }
174741
- const packageJson = JSON.parse(fs44.readFileSync(packageJsonPath, "utf-8"));
174628
+ const packageJson = JSON.parse(fs43.readFileSync(packageJsonPath, "utf-8"));
174742
174629
  if (skipTscircuitPackage) {
174743
174630
  packageJson.dependencies = removeTscircuitPackage(packageJson.dependencies);
174744
174631
  console.log("Skipping tscircuit package installation from dependencies (using cloud container version).");
@@ -174757,7 +174644,7 @@ async function installProjectDependencies({
174757
174644
  console.log("No @tsci dependencies detected in circuit files.");
174758
174645
  }
174759
174646
  }
174760
- fs44.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
174647
+ fs43.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
174761
174648
  `);
174762
174649
  console.log(`Installing dependencies using ${kleur_default.bold(packageManager.name)}...`);
174763
174650
  try {
@@ -174819,213 +174706,193 @@ var applyCiBuildOptions = async ({
174819
174706
  };
174820
174707
  };
174821
174708
 
174822
- // cli/build/resolve-build-options.ts
174823
- var resolveBuildOptions = ({
174824
- cliOptions,
174825
- projectConfig: projectConfig2
174826
- }) => {
174827
- if (cliOptions?.ignoreConfig) {
174828
- return { options: cliOptions, configAppliedOpts: [] };
174829
- }
174830
- const configBuild = projectConfig2?.build;
174831
- const configAppliedOpts = [];
174832
- if (!cliOptions?.kicadProject && configBuild?.kicadProject) {
174833
- configAppliedOpts.push("kicad-project");
174834
- }
174835
- if (!cliOptions?.kicadLibrary && configBuild?.kicadLibrary) {
174836
- configAppliedOpts.push("kicad-library");
174837
- }
174838
- if (!cliOptions?.kicadPcm && configBuild?.kicadPcm) {
174839
- configAppliedOpts.push("kicad-pcm");
174840
- }
174841
- if (!cliOptions?.previewImages && configBuild?.previewImages) {
174842
- configAppliedOpts.push("preview-images");
174843
- }
174844
- if (!cliOptions?.glbs && configBuild?.glbs) {
174845
- configAppliedOpts.push("glbs");
174846
- }
174847
- if (!cliOptions?.transpile && configBuild?.typescriptLibrary) {
174848
- configAppliedOpts.push("transpile");
174849
- }
174850
- const options = {
174851
- ...cliOptions,
174852
- kicadProject: cliOptions?.kicadProject ?? configBuild?.kicadProject,
174853
- kicadLibrary: cliOptions?.kicadLibrary ?? configBuild?.kicadLibrary,
174854
- kicadLibraryName: cliOptions?.kicadLibraryName ?? projectConfig2?.kicadLibraryName,
174855
- kicadPcm: cliOptions?.kicadPcm ?? configBuild?.kicadPcm,
174856
- previewImages: cliOptions?.previewImages ?? configBuild?.previewImages,
174857
- glbs: cliOptions?.glbs ?? configBuild?.glbs,
174858
- transpile: cliOptions?.transpile ?? configBuild?.typescriptLibrary
174859
- };
174860
- return { options, configAppliedOpts };
174861
- };
174862
-
174863
- // cli/build/get-build-entrypoints.ts
174864
- import fs45 from "node:fs";
174709
+ // cli/build/build-file.ts
174865
174710
  import path45 from "node:path";
174866
- var isSubPath2 = (maybeChild, maybeParent) => {
174867
- const relative10 = path45.relative(maybeParent, maybeChild);
174868
- return relative10 === "" || !relative10.startsWith("..") && !path45.isAbsolute(relative10);
174869
- };
174870
- var findProjectRoot = (startDir) => {
174871
- let currentDir = startDir;
174872
- while (currentDir !== path45.dirname(currentDir)) {
174873
- const packageJsonPath = path45.join(currentDir, "package.json");
174874
- if (fs45.existsSync(packageJsonPath)) {
174875
- return currentDir;
174711
+ import fs45 from "node:fs";
174712
+
174713
+ // lib/shared/circuit-json-diagnostics.ts
174714
+ function analyzeCircuitJson(circuitJson) {
174715
+ const errors = [];
174716
+ const warnings = [];
174717
+ for (const item of circuitJson) {
174718
+ if (!item || typeof item !== "object")
174719
+ continue;
174720
+ const t3 = item.type;
174721
+ if (typeof t3 === "string") {
174722
+ if (t3.endsWith("_error"))
174723
+ errors.push(item);
174724
+ else if (t3.endsWith("_warning"))
174725
+ warnings.push(item);
174876
174726
  }
174877
- currentDir = path45.dirname(currentDir);
174727
+ if ("error_type" in item)
174728
+ errors.push(item);
174729
+ if ("warning_type" in item)
174730
+ warnings.push(item);
174878
174731
  }
174879
- return startDir;
174880
- };
174881
- async function getBuildEntrypoints({
174882
- fileOrDir,
174883
- rootDir = process.cwd(),
174884
- includeBoardFiles = true
174885
- }) {
174886
- const resolvedRoot = path45.resolve(rootDir);
174887
- const includeBoardFilePatterns = includeBoardFiles ? getBoardFilePatterns(resolvedRoot) : [];
174888
- const buildFromProjectDir = async () => {
174889
- const projectConfig2 = loadProjectConfig(resolvedRoot);
174890
- const resolvedPreviewComponentPath = projectConfig2?.previewComponentPath ? path45.resolve(resolvedRoot, projectConfig2.previewComponentPath) : undefined;
174891
- const resolvedSiteDefaultComponentPath = projectConfig2?.siteDefaultComponentPath ? path45.resolve(resolvedRoot, projectConfig2.siteDefaultComponentPath) : undefined;
174892
- if (includeBoardFiles) {
174893
- const files = findBoardFiles({ projectDir: resolvedRoot });
174894
- if (files.length > 0) {
174895
- return {
174896
- projectDir: resolvedRoot,
174897
- previewComponentPath: resolvedPreviewComponentPath,
174898
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
174899
- circuitFiles: files
174900
- };
174732
+ return { errors, warnings };
174733
+ }
174734
+
174735
+ // lib/shared/get-complete-platform-config.ts
174736
+ import { getPlatformConfig } from "@tscircuit/eval/platform-config";
174737
+ import { createHash } from "node:crypto";
174738
+ import path44 from "node:path";
174739
+ import fs44 from "node:fs";
174740
+ function createLocalCacheEngine(cacheDir = path44.join(process.cwd(), ".tscircuit", "cache")) {
174741
+ return {
174742
+ getItem: (key) => {
174743
+ try {
174744
+ const hash = createHash("md5").update(key).digest("hex");
174745
+ const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
174746
+ const filePath = path44.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
174747
+ return fs44.readFileSync(filePath, "utf-8");
174748
+ } catch {
174749
+ return null;
174901
174750
  }
174751
+ },
174752
+ setItem: (key, value) => {
174753
+ try {
174754
+ fs44.mkdirSync(cacheDir, { recursive: true });
174755
+ const hash = createHash("md5").update(key).digest("hex");
174756
+ const keyWithSafeCharacters = key.replace(/[^a-zA-Z0-9]/g, "_");
174757
+ const filePath = path44.join(cacheDir, `${keyWithSafeCharacters.slice(keyWithSafeCharacters.length - 10, keyWithSafeCharacters.length)}-${hash}.json`);
174758
+ fs44.writeFileSync(filePath, value);
174759
+ } catch {}
174902
174760
  }
174903
- const mainEntrypoint = await getEntrypoint({
174904
- projectDir: resolvedRoot,
174905
- onSuccess: () => {
174906
- return;
174907
- },
174908
- onError: () => {
174909
- return;
174761
+ };
174762
+ }
174763
+ function getCompletePlatformConfig(userConfig) {
174764
+ const basePlatformConfig = getPlatformConfig();
174765
+ const defaultConfig = {
174766
+ ...basePlatformConfig,
174767
+ localCacheEngine: createLocalCacheEngine(),
174768
+ footprintFileParserMap: {
174769
+ ...basePlatformConfig.footprintFileParserMap,
174770
+ kicad_mod: {
174771
+ loadFromUrl: async (url) => {
174772
+ let fetchUrl = url;
174773
+ if (url.startsWith("./") || url.startsWith("../")) {
174774
+ const absolutePath = path44.resolve(process.cwd(), url);
174775
+ fetchUrl = `file://${absolutePath}`;
174776
+ } else if (url.startsWith("/")) {
174777
+ if (fs44.existsSync(url)) {
174778
+ fetchUrl = `file://${url}`;
174779
+ } else {
174780
+ const relativePath = `.${url}`;
174781
+ const absolutePath = path44.resolve(process.cwd(), relativePath);
174782
+ if (fs44.existsSync(absolutePath)) {
174783
+ fetchUrl = `file://${absolutePath}`;
174784
+ } else {
174785
+ fetchUrl = `file://${url}`;
174786
+ }
174787
+ }
174788
+ }
174789
+ return basePlatformConfig.footprintFileParserMap.kicad_mod.loadFromUrl(fetchUrl);
174790
+ }
174910
174791
  }
174911
- });
174912
- if (mainEntrypoint) {
174913
- return {
174914
- projectDir: resolvedRoot,
174915
- mainEntrypoint,
174916
- previewComponentPath: resolvedPreviewComponentPath,
174917
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
174918
- circuitFiles: [mainEntrypoint]
174919
- };
174920
174792
  }
174921
- return {
174922
- projectDir: resolvedRoot,
174923
- previewComponentPath: resolvedPreviewComponentPath,
174924
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
174925
- circuitFiles: []
174926
- };
174927
174793
  };
174928
- if (fileOrDir) {
174929
- const resolved = path45.resolve(resolvedRoot, fileOrDir);
174930
- if (fs45.existsSync(resolved) && fs45.statSync(resolved).isDirectory()) {
174931
- const projectConfig3 = loadProjectConfig(resolvedRoot);
174932
- const resolvedPreviewComponentPath2 = projectConfig3?.previewComponentPath ? path45.resolve(resolvedRoot, projectConfig3.previewComponentPath) : undefined;
174933
- const resolvedSiteDefaultComponentPath2 = projectConfig3?.siteDefaultComponentPath ? path45.resolve(resolvedRoot, projectConfig3.siteDefaultComponentPath) : undefined;
174934
- if (includeBoardFiles) {
174935
- const circuitFiles = findBoardFiles({
174936
- projectDir: resolvedRoot,
174937
- filePaths: [resolved]
174938
- }).filter((file) => isSubPath2(file, resolved));
174939
- if (circuitFiles.length === 0) {
174940
- throw new Error(`There were no files to build found matching the includeBoardFiles globs: ${JSON.stringify(includeBoardFilePatterns)}`);
174941
- }
174942
- return {
174943
- projectDir: resolvedRoot,
174944
- previewComponentPath: resolvedPreviewComponentPath2,
174945
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath2,
174946
- circuitFiles
174947
- };
174794
+ if (!userConfig) {
174795
+ return defaultConfig;
174796
+ }
174797
+ return {
174798
+ ...defaultConfig,
174799
+ ...userConfig,
174800
+ footprintFileParserMap: {
174801
+ ...defaultConfig.footprintFileParserMap,
174802
+ ...userConfig.footprintFileParserMap
174803
+ }
174804
+ };
174805
+ }
174806
+
174807
+ // cli/build/build-file.ts
174808
+ var buildFile = async (input, output, projectDir, options) => {
174809
+ try {
174810
+ console.log("Generating circuit JSON...");
174811
+ const completePlatformConfig = getCompletePlatformConfig(options?.platformConfig);
174812
+ const result = await generateCircuitJson({
174813
+ filePath: input,
174814
+ platformConfig: completePlatformConfig
174815
+ });
174816
+ fs45.mkdirSync(path45.dirname(output), { recursive: true });
174817
+ fs45.writeFileSync(output, JSON.stringify(result.circuitJson, null, 2));
174818
+ console.log(`Circuit JSON written to ${path45.relative(projectDir, output)}`);
174819
+ const { errors, warnings } = analyzeCircuitJson(result.circuitJson);
174820
+ if (!options?.ignoreWarnings) {
174821
+ for (const warn of warnings) {
174822
+ const msg = warn.message || JSON.stringify(warn);
174823
+ console.log(kleur_default.yellow(msg));
174948
174824
  }
174949
- const projectDir2 = findProjectRoot(resolved);
174950
- const mainEntrypoint = await getEntrypoint({
174951
- projectDir: projectDir2,
174952
- onSuccess: () => {
174953
- return;
174954
- },
174955
- onError: () => {
174956
- return;
174825
+ }
174826
+ if (!options?.ignoreErrors) {
174827
+ for (const err of errors) {
174828
+ const msg = err.message || JSON.stringify(err);
174829
+ console.error(kleur_default.red(msg));
174830
+ if (err.stack) {
174831
+ console.log(err.stack);
174957
174832
  }
174958
- });
174833
+ }
174834
+ }
174835
+ if (errors.length > 0 && !options?.ignoreErrors) {
174836
+ console.error(kleur_default.red(`Build failed with ${errors.length} error(s). Use --ignore-errors to continue.`));
174837
+ return { ok: false };
174838
+ } else {
174959
174839
  return {
174960
- projectDir: projectDir2,
174961
- mainEntrypoint: mainEntrypoint || undefined,
174962
- previewComponentPath: resolvedPreviewComponentPath2,
174963
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath2,
174964
- circuitFiles: mainEntrypoint ? [mainEntrypoint] : []
174840
+ ok: true,
174841
+ circuitJson: result.circuitJson
174965
174842
  };
174966
174843
  }
174967
- const fileDir = path45.dirname(resolved);
174968
- const projectDir = findProjectRoot(fileDir);
174969
- const projectConfig2 = loadProjectConfig(projectDir);
174970
- const resolvedPreviewComponentPath = projectConfig2?.previewComponentPath ? path45.resolve(projectDir, projectConfig2.previewComponentPath) : undefined;
174971
- const resolvedSiteDefaultComponentPath = projectConfig2?.siteDefaultComponentPath ? path45.resolve(projectDir, projectConfig2.siteDefaultComponentPath) : undefined;
174844
+ } catch (err) {
174845
+ console.error(err);
174846
+ if (err instanceof Error) {
174847
+ logTsxExtensionHint(err, input);
174848
+ logTypeReexportHint(err, input);
174849
+ }
174972
174850
  return {
174973
- projectDir,
174974
- previewComponentPath: resolvedPreviewComponentPath,
174975
- siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
174976
- circuitFiles: [resolved]
174851
+ ok: false,
174852
+ isFatalError: {
174853
+ errorType: "circuit_generation_failed",
174854
+ message: err instanceof Error ? err.message : String(err)
174855
+ }
174977
174856
  };
174978
174857
  }
174979
- return buildFromProjectDir();
174980
- }
174981
-
174982
- // lib/site/getStaticIndexHtmlFile.ts
174983
- var getStaticIndexHtmlFile = ({
174984
- files,
174985
- standaloneScriptSrc = "./standalone.min.js",
174986
- defaultMainComponentPath,
174987
- packageName
174988
- }) => {
174989
- const scriptLines = [
174990
- "window.TSCIRCUIT_USE_RUNFRAME_FOR_CLI = false;",
174991
- `window.TSCIRCUIT_RUNFRAME_STATIC_FILE_LIST = ${JSON.stringify(files)};`,
174992
- ...defaultMainComponentPath ? [
174993
- `window.TSCIRCUIT_DEFAULT_MAIN_COMPONENT_PATH = ${JSON.stringify(defaultMainComponentPath)};`
174994
- ] : [],
174995
- ...packageName ? [`window.TSCIRCUIT_PACKAGE_NAME = ${JSON.stringify(packageName)};`] : []
174996
- ];
174997
- const scriptBlock = ` <script>
174998
- ${scriptLines.join(`
174999
- `)}
175000
- </script>
175001
- `;
175002
- return `<html>
175003
- <head>
175004
- <link rel="icon" type="image/png" href="https://github.com/tscircuit.png">
175005
- <meta charset="UTF-8" />
175006
- <title>tscircuit</title>
175007
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
175008
- </head>
175009
- <body>
175010
- ${scriptBlock} <script src="https://cdn.tailwindcss.com"></script>
175011
- <div id="root">loading...</div>
175012
- <script>
175013
- globalThis.process = { env: { NODE_ENV: "production" } }
175014
- </script>
175015
- <script type="module" src="${standaloneScriptSrc}"></script>
175016
- </body>
175017
- </html>`;
174858
+ };
174859
+ var logTsxExtensionHint = (error, entryFilePath) => {
174860
+ const lowerPath = entryFilePath.toLowerCase();
174861
+ const isTsEntry = lowerPath.endsWith(".ts") && !lowerPath.endsWith(".d.ts");
174862
+ const isAggregateError = error instanceof AggregateError || String(error).includes("AggregateError");
174863
+ if (!isTsEntry || !isAggregateError)
174864
+ return;
174865
+ const entryFileName = path45.basename(entryFilePath);
174866
+ console.error([
174867
+ "",
174868
+ `It looks like "${entryFileName}" is a ".ts" file. tscircuit component files must use the ".tsx" extension.`,
174869
+ "Try renaming the file to .tsx and re-running the build.",
174870
+ ""
174871
+ ].join(`
174872
+ `));
174873
+ };
174874
+ var TYPE_REEXPORT_ERROR_REGEX = /SyntaxError: export '([^']+)' not found in '([^']+)'/;
174875
+ var logTypeReexportHint = (error, entryFilePath) => {
174876
+ const match = String(error).match(TYPE_REEXPORT_ERROR_REGEX);
174877
+ if (!match)
174878
+ return;
174879
+ const [, exportName, fromSpecifier] = match;
174880
+ const entryFileName = path45.basename(entryFilePath);
174881
+ console.error([
174882
+ "",
174883
+ `It looks like "${entryFileName}" re-exports the type-only symbol "${exportName}" from "${fromSpecifier}" without the "type" modifier.`,
174884
+ "Type-only exports must be re-exported with `export type { ... }`.",
174885
+ "Try rewriting the statement as:",
174886
+ ` export type { ${exportName} } from "${fromSpecifier}"`,
174887
+ ""
174888
+ ].join(`
174889
+ `));
175018
174890
  };
175019
174891
 
175020
- // cli/build/build-preview-images.ts
174892
+ // cli/build/build-glbs.ts
175021
174893
  import fs46 from "node:fs";
175022
174894
  import path47 from "node:path";
175023
174895
  import { convertCircuitJsonToGltf as convertCircuitJsonToGltf2 } from "circuit-json-to-gltf";
175024
- import {
175025
- convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg2,
175026
- convertCircuitJsonToSchematicSvg as convertCircuitJsonToSchematicSvg2
175027
- } from "circuit-to-svg";
175028
- import { renderGLTFToPNGBufferFromGLBBuffer } from "poppygl";
175029
174896
 
175030
174897
  // cli/build/convert-model-urls-to-file-urls.ts
175031
174898
  import path46 from "node:path";
@@ -175063,18 +174930,127 @@ var convertModelUrlsToFileUrls = (circuitJson) => {
175063
174930
  });
175064
174931
  };
175065
174932
 
175066
- // cli/build/build-preview-images.ts
174933
+ // cli/build/build-glbs.ts
175067
174934
  var viewToArrayBuffer = (view) => {
175068
174935
  const copy = new Uint8Array(view.byteLength);
175069
174936
  copy.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
175070
174937
  return copy.buffer;
175071
174938
  };
174939
+ var normalizeToUint8Array = (value) => {
174940
+ if (value instanceof Uint8Array) {
174941
+ return value;
174942
+ }
174943
+ if (value instanceof ArrayBuffer) {
174944
+ return new Uint8Array(value);
174945
+ }
174946
+ if (ArrayBuffer.isView(value)) {
174947
+ return new Uint8Array(viewToArrayBuffer(value));
174948
+ }
174949
+ throw new Error("Expected Uint8Array, ArrayBuffer, or ArrayBufferView for GLB");
174950
+ };
174951
+ var buildGlbs = async ({
174952
+ builtFiles,
174953
+ distDir
174954
+ }) => {
174955
+ const successfulBuilds = builtFiles.filter((file) => file.ok);
174956
+ if (successfulBuilds.length === 0) {
174957
+ console.warn("No successful build output available for GLB generation.");
174958
+ return;
174959
+ }
174960
+ for (const build of successfulBuilds) {
174961
+ const outputDir = path47.dirname(build.outputPath);
174962
+ const prefixRelative = path47.relative(distDir, outputDir) || ".";
174963
+ const prefix = prefixRelative === "." ? "" : `[${prefixRelative}] `;
174964
+ let circuitJson;
174965
+ try {
174966
+ const circuitJsonRaw = fs46.readFileSync(build.outputPath, "utf-8");
174967
+ circuitJson = JSON.parse(circuitJsonRaw);
174968
+ } catch (error) {
174969
+ console.error(`${prefix}Failed to read circuit JSON:`, error);
174970
+ continue;
174971
+ }
174972
+ try {
174973
+ console.log(`${prefix}Converting circuit to GLB...`);
174974
+ const circuitJsonWithFileUrls = convertModelUrlsToFileUrls(circuitJson);
174975
+ const glbBuffer = await convertCircuitJsonToGltf2(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "glb" }));
174976
+ const glbData = normalizeToUint8Array(glbBuffer);
174977
+ fs46.writeFileSync(path47.join(outputDir, "3d.glb"), Buffer.from(glbData));
174978
+ console.log(`${prefix}Written 3d.glb`);
174979
+ } catch (error) {
174980
+ console.error(`${prefix}Failed to generate GLB:`, error);
174981
+ }
174982
+ }
174983
+ };
174984
+
174985
+ // cli/build/build-preview-gltf.ts
174986
+ import fs47 from "node:fs";
174987
+ import path48 from "node:path";
174988
+ import { convertCircuitJsonToGltf as convertCircuitJsonToGltf3 } from "circuit-json-to-gltf";
174989
+ var buildPreviewGltf = async ({
174990
+ builtFiles,
174991
+ distDir,
174992
+ mainEntrypoint,
174993
+ previewComponentPath
174994
+ }) => {
174995
+ const successfulBuilds = builtFiles.filter((file) => file.ok);
174996
+ const previewEntrypoint = previewComponentPath || mainEntrypoint;
174997
+ const resolvedPreviewEntrypoint = previewEntrypoint ? path48.resolve(previewEntrypoint) : undefined;
174998
+ const previewBuild = (() => {
174999
+ if (resolvedPreviewEntrypoint) {
175000
+ const match = successfulBuilds.find((built) => path48.resolve(built.sourcePath) === resolvedPreviewEntrypoint);
175001
+ if (match)
175002
+ return match;
175003
+ }
175004
+ return successfulBuilds[0];
175005
+ })();
175006
+ if (!previewBuild) {
175007
+ console.warn("No successful build output available for preview GLTF generation.");
175008
+ return;
175009
+ }
175010
+ let circuitJson;
175011
+ try {
175012
+ const circuitJsonRaw = fs47.readFileSync(previewBuild.outputPath, "utf-8");
175013
+ circuitJson = JSON.parse(circuitJsonRaw);
175014
+ } catch (error) {
175015
+ console.error("Failed to read circuit JSON:", error);
175016
+ return;
175017
+ }
175018
+ const sourcePath = previewBuild.sourcePath;
175019
+ const sourceBasename = path48.basename(sourcePath);
175020
+ const gltfFilename = sourceBasename.replace(/(\.(board|circuit))?\.tsx?$/, ".gltf");
175021
+ const outputPath = path48.join(distDir, gltfFilename);
175022
+ try {
175023
+ console.log("Converting circuit to GLTF...");
175024
+ const circuitJsonWithFileUrls = convertModelUrlsToFileUrls(circuitJson);
175025
+ const gltfData = await convertCircuitJsonToGltf3(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "gltf" }));
175026
+ const gltfContent = JSON.stringify(gltfData, null, 2);
175027
+ fs47.writeFileSync(outputPath, gltfContent, "utf-8");
175028
+ console.log(`Written ${gltfFilename}`);
175029
+ } catch (error) {
175030
+ console.error("Failed to generate GLTF:", error);
175031
+ }
175032
+ };
175033
+
175034
+ // cli/build/build-preview-images.ts
175035
+ import fs48 from "node:fs";
175036
+ import path49 from "node:path";
175037
+ import { convertCircuitJsonToGltf as convertCircuitJsonToGltf4 } from "circuit-json-to-gltf";
175038
+ import {
175039
+ convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg2,
175040
+ convertCircuitJsonToSchematicSvg as convertCircuitJsonToSchematicSvg2
175041
+ } from "circuit-to-svg";
175042
+ import { renderGLTFToPNGBufferFromGLBBuffer } from "poppygl";
175043
+ var viewToArrayBuffer2 = (view) => {
175044
+ const copy = new Uint8Array(view.byteLength);
175045
+ copy.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
175046
+ return copy.buffer;
175047
+ };
175072
175048
  var normalizeToArrayBuffer = async (value) => {
175073
175049
  if (value instanceof ArrayBuffer) {
175074
175050
  return value;
175075
175051
  }
175076
175052
  if (ArrayBuffer.isView(value)) {
175077
- return viewToArrayBuffer(value);
175053
+ return viewToArrayBuffer2(value);
175078
175054
  }
175079
175055
  if (value && typeof value === "object") {
175080
175056
  const maybeArrayBufferLike = value;
@@ -175085,7 +175061,7 @@ var normalizeToArrayBuffer = async (value) => {
175085
175061
  }
175086
175062
  throw new Error("Expected ArrayBuffer, ArrayBufferView, or Buffer-compatible object");
175087
175063
  };
175088
- var normalizeToUint8Array = (value) => {
175064
+ var normalizeToUint8Array2 = (value) => {
175089
175065
  if (value instanceof Uint8Array) {
175090
175066
  return value;
175091
175067
  }
@@ -175093,7 +175069,7 @@ var normalizeToUint8Array = (value) => {
175093
175069
  return new Uint8Array(value);
175094
175070
  }
175095
175071
  if (ArrayBuffer.isView(value)) {
175096
- return new Uint8Array(viewToArrayBuffer(value));
175072
+ return new Uint8Array(viewToArrayBuffer2(value));
175097
175073
  }
175098
175074
  throw new Error("Expected Uint8Array, ArrayBuffer, or ArrayBufferView for PNG");
175099
175075
  };
@@ -175102,21 +175078,21 @@ var generatePreviewAssets = async ({
175102
175078
  outputDir,
175103
175079
  distDir
175104
175080
  }) => {
175105
- const prefixRelative = path47.relative(distDir, outputDir) || ".";
175081
+ const prefixRelative = path49.relative(distDir, outputDir) || ".";
175106
175082
  const prefix = prefixRelative === "." ? "" : `[${prefixRelative}] `;
175107
175083
  let circuitJson;
175108
175084
  try {
175109
- const circuitJsonRaw = fs46.readFileSync(build.outputPath, "utf-8");
175085
+ const circuitJsonRaw = fs48.readFileSync(build.outputPath, "utf-8");
175110
175086
  circuitJson = JSON.parse(circuitJsonRaw);
175111
175087
  } catch (error) {
175112
175088
  console.error(`${prefix}Failed to read circuit JSON:`, error);
175113
175089
  return;
175114
175090
  }
175115
- fs46.mkdirSync(outputDir, { recursive: true });
175091
+ fs48.mkdirSync(outputDir, { recursive: true });
175116
175092
  try {
175117
175093
  console.log(`${prefix}Generating PCB SVG...`);
175118
175094
  const pcbSvg = convertCircuitJsonToPcbSvg2(circuitJson);
175119
- fs46.writeFileSync(path47.join(outputDir, "pcb.svg"), pcbSvg, "utf-8");
175095
+ fs48.writeFileSync(path49.join(outputDir, "pcb.svg"), pcbSvg, "utf-8");
175120
175096
  console.log(`${prefix}Written pcb.svg`);
175121
175097
  } catch (error) {
175122
175098
  console.error(`${prefix}Failed to generate PCB SVG:`, error);
@@ -175124,7 +175100,7 @@ var generatePreviewAssets = async ({
175124
175100
  try {
175125
175101
  console.log(`${prefix}Generating schematic SVG...`);
175126
175102
  const schematicSvg = convertCircuitJsonToSchematicSvg2(circuitJson);
175127
- fs46.writeFileSync(path47.join(outputDir, "schematic.svg"), schematicSvg, "utf-8");
175103
+ fs48.writeFileSync(path49.join(outputDir, "schematic.svg"), schematicSvg, "utf-8");
175128
175104
  console.log(`${prefix}Written schematic.svg`);
175129
175105
  } catch (error) {
175130
175106
  console.error(`${prefix}Failed to generate schematic SVG:`, error);
@@ -175132,14 +175108,14 @@ var generatePreviewAssets = async ({
175132
175108
  try {
175133
175109
  console.log(`${prefix}Converting circuit to GLB...`);
175134
175110
  const circuitJsonWithFileUrls = convertModelUrlsToFileUrls(circuitJson);
175135
- const glbBuffer = await convertCircuitJsonToGltf2(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "glb" }));
175111
+ const glbBuffer = await convertCircuitJsonToGltf4(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "glb" }));
175136
175112
  console.log(`${prefix}Rendering GLB to PNG buffer...`);
175137
175113
  const glbArrayBuffer = await normalizeToArrayBuffer(glbBuffer);
175138
175114
  const pngBuffer = await renderGLTFToPNGBufferFromGLBBuffer(glbArrayBuffer, {
175139
175115
  camPos: [10, 10, 10],
175140
175116
  lookAt: [0, 0, 0]
175141
175117
  });
175142
- fs46.writeFileSync(path47.join(outputDir, "3d.png"), Buffer.from(normalizeToUint8Array(pngBuffer)));
175118
+ fs48.writeFileSync(path49.join(outputDir, "3d.png"), Buffer.from(normalizeToUint8Array2(pngBuffer)));
175143
175119
  console.log(`${prefix}Written 3d.png`);
175144
175120
  } catch (error) {
175145
175121
  console.error(`${prefix}Failed to generate 3D PNG:`, error);
@@ -175154,14 +175130,14 @@ var buildPreviewImages = async ({
175154
175130
  }) => {
175155
175131
  const successfulBuilds = builtFiles.filter((file) => file.ok);
175156
175132
  const previewEntrypoint = previewComponentPath || mainEntrypoint;
175157
- const resolvedPreviewEntrypoint = previewEntrypoint ? path47.resolve(previewEntrypoint) : undefined;
175133
+ const resolvedPreviewEntrypoint = previewEntrypoint ? path49.resolve(previewEntrypoint) : undefined;
175158
175134
  if (allImages) {
175159
175135
  if (successfulBuilds.length === 0) {
175160
175136
  console.warn("No successful build output available for preview image generation.");
175161
175137
  return;
175162
175138
  }
175163
175139
  for (const build of successfulBuilds) {
175164
- const outputDir = path47.dirname(build.outputPath);
175140
+ const outputDir = path49.dirname(build.outputPath);
175165
175141
  await generatePreviewAssets({
175166
175142
  build,
175167
175143
  outputDir,
@@ -175172,7 +175148,7 @@ var buildPreviewImages = async ({
175172
175148
  }
175173
175149
  const previewBuild = (() => {
175174
175150
  if (resolvedPreviewEntrypoint) {
175175
- const match = successfulBuilds.find((built) => path47.resolve(built.sourcePath) === resolvedPreviewEntrypoint);
175151
+ const match = successfulBuilds.find((built) => path49.resolve(built.sourcePath) === resolvedPreviewEntrypoint);
175176
175152
  if (match)
175177
175153
  return match;
175178
175154
  }
@@ -175189,110 +175165,6 @@ var buildPreviewImages = async ({
175189
175165
  });
175190
175166
  };
175191
175167
 
175192
- // cli/build/build-preview-gltf.ts
175193
- import fs47 from "node:fs";
175194
- import path48 from "node:path";
175195
- import { convertCircuitJsonToGltf as convertCircuitJsonToGltf3 } from "circuit-json-to-gltf";
175196
- var buildPreviewGltf = async ({
175197
- builtFiles,
175198
- distDir,
175199
- mainEntrypoint,
175200
- previewComponentPath
175201
- }) => {
175202
- const successfulBuilds = builtFiles.filter((file) => file.ok);
175203
- const previewEntrypoint = previewComponentPath || mainEntrypoint;
175204
- const resolvedPreviewEntrypoint = previewEntrypoint ? path48.resolve(previewEntrypoint) : undefined;
175205
- const previewBuild = (() => {
175206
- if (resolvedPreviewEntrypoint) {
175207
- const match = successfulBuilds.find((built) => path48.resolve(built.sourcePath) === resolvedPreviewEntrypoint);
175208
- if (match)
175209
- return match;
175210
- }
175211
- return successfulBuilds[0];
175212
- })();
175213
- if (!previewBuild) {
175214
- console.warn("No successful build output available for preview GLTF generation.");
175215
- return;
175216
- }
175217
- let circuitJson;
175218
- try {
175219
- const circuitJsonRaw = fs47.readFileSync(previewBuild.outputPath, "utf-8");
175220
- circuitJson = JSON.parse(circuitJsonRaw);
175221
- } catch (error) {
175222
- console.error("Failed to read circuit JSON:", error);
175223
- return;
175224
- }
175225
- const sourcePath = previewBuild.sourcePath;
175226
- const sourceBasename = path48.basename(sourcePath);
175227
- const gltfFilename = sourceBasename.replace(/(\.(board|circuit))?\.tsx?$/, ".gltf");
175228
- const outputPath = path48.join(distDir, gltfFilename);
175229
- try {
175230
- console.log("Converting circuit to GLTF...");
175231
- const circuitJsonWithFileUrls = convertModelUrlsToFileUrls(circuitJson);
175232
- const gltfData = await convertCircuitJsonToGltf3(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "gltf" }));
175233
- const gltfContent = JSON.stringify(gltfData, null, 2);
175234
- fs47.writeFileSync(outputPath, gltfContent, "utf-8");
175235
- console.log(`Written ${gltfFilename}`);
175236
- } catch (error) {
175237
- console.error("Failed to generate GLTF:", error);
175238
- }
175239
- };
175240
-
175241
- // cli/build/build-glbs.ts
175242
- import fs48 from "node:fs";
175243
- import path49 from "node:path";
175244
- import { convertCircuitJsonToGltf as convertCircuitJsonToGltf4 } from "circuit-json-to-gltf";
175245
- var viewToArrayBuffer2 = (view) => {
175246
- const copy = new Uint8Array(view.byteLength);
175247
- copy.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
175248
- return copy.buffer;
175249
- };
175250
- var normalizeToUint8Array2 = (value) => {
175251
- if (value instanceof Uint8Array) {
175252
- return value;
175253
- }
175254
- if (value instanceof ArrayBuffer) {
175255
- return new Uint8Array(value);
175256
- }
175257
- if (ArrayBuffer.isView(value)) {
175258
- return new Uint8Array(viewToArrayBuffer2(value));
175259
- }
175260
- throw new Error("Expected Uint8Array, ArrayBuffer, or ArrayBufferView for GLB");
175261
- };
175262
- var buildGlbs = async ({
175263
- builtFiles,
175264
- distDir
175265
- }) => {
175266
- const successfulBuilds = builtFiles.filter((file) => file.ok);
175267
- if (successfulBuilds.length === 0) {
175268
- console.warn("No successful build output available for GLB generation.");
175269
- return;
175270
- }
175271
- for (const build of successfulBuilds) {
175272
- const outputDir = path49.dirname(build.outputPath);
175273
- const prefixRelative = path49.relative(distDir, outputDir) || ".";
175274
- const prefix = prefixRelative === "." ? "" : `[${prefixRelative}] `;
175275
- let circuitJson;
175276
- try {
175277
- const circuitJsonRaw = fs48.readFileSync(build.outputPath, "utf-8");
175278
- circuitJson = JSON.parse(circuitJsonRaw);
175279
- } catch (error) {
175280
- console.error(`${prefix}Failed to read circuit JSON:`, error);
175281
- continue;
175282
- }
175283
- try {
175284
- console.log(`${prefix}Converting circuit to GLB...`);
175285
- const circuitJsonWithFileUrls = convertModelUrlsToFileUrls(circuitJson);
175286
- const glbBuffer = await convertCircuitJsonToGltf4(circuitJsonWithFileUrls, getCircuitJsonToGltfOptions({ format: "glb" }));
175287
- const glbData = normalizeToUint8Array2(glbBuffer);
175288
- fs48.writeFileSync(path49.join(outputDir, "3d.glb"), Buffer.from(glbData));
175289
- console.log(`${prefix}Written 3d.glb`);
175290
- } catch (error) {
175291
- console.error(`${prefix}Failed to generate GLB:`, error);
175292
- }
175293
- }
175294
- };
175295
-
175296
175168
  // cli/build/generate-kicad-project.ts
175297
175169
  import fs49 from "node:fs";
175298
175170
  import path50 from "node:path";
@@ -175349,9 +175221,169 @@ var generateKicadProject = async ({
175349
175221
  };
175350
175222
  };
175351
175223
 
175224
+ // cli/build/get-build-entrypoints.ts
175225
+ import fs50 from "node:fs";
175226
+ import path51 from "node:path";
175227
+ var isSubPath2 = (maybeChild, maybeParent) => {
175228
+ const relative10 = path51.relative(maybeParent, maybeChild);
175229
+ return relative10 === "" || !relative10.startsWith("..") && !path51.isAbsolute(relative10);
175230
+ };
175231
+ var findProjectRoot = (startDir) => {
175232
+ let currentDir = startDir;
175233
+ while (currentDir !== path51.dirname(currentDir)) {
175234
+ const packageJsonPath = path51.join(currentDir, "package.json");
175235
+ if (fs50.existsSync(packageJsonPath)) {
175236
+ return currentDir;
175237
+ }
175238
+ currentDir = path51.dirname(currentDir);
175239
+ }
175240
+ return startDir;
175241
+ };
175242
+ async function getBuildEntrypoints({
175243
+ fileOrDir,
175244
+ rootDir = process.cwd(),
175245
+ includeBoardFiles = true
175246
+ }) {
175247
+ const resolvedRoot = path51.resolve(rootDir);
175248
+ const includeBoardFilePatterns = includeBoardFiles ? getBoardFilePatterns(resolvedRoot) : [];
175249
+ const buildFromProjectDir = async () => {
175250
+ const projectConfig2 = loadProjectConfig(resolvedRoot);
175251
+ const resolvedPreviewComponentPath = projectConfig2?.previewComponentPath ? path51.resolve(resolvedRoot, projectConfig2.previewComponentPath) : undefined;
175252
+ const resolvedSiteDefaultComponentPath = projectConfig2?.siteDefaultComponentPath ? path51.resolve(resolvedRoot, projectConfig2.siteDefaultComponentPath) : undefined;
175253
+ if (includeBoardFiles) {
175254
+ const files = findBoardFiles({ projectDir: resolvedRoot });
175255
+ if (files.length > 0) {
175256
+ return {
175257
+ projectDir: resolvedRoot,
175258
+ previewComponentPath: resolvedPreviewComponentPath,
175259
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
175260
+ circuitFiles: files
175261
+ };
175262
+ }
175263
+ }
175264
+ const mainEntrypoint = await getEntrypoint({
175265
+ projectDir: resolvedRoot,
175266
+ onSuccess: () => {
175267
+ return;
175268
+ },
175269
+ onError: () => {
175270
+ return;
175271
+ }
175272
+ });
175273
+ if (mainEntrypoint) {
175274
+ return {
175275
+ projectDir: resolvedRoot,
175276
+ mainEntrypoint,
175277
+ previewComponentPath: resolvedPreviewComponentPath,
175278
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
175279
+ circuitFiles: [mainEntrypoint]
175280
+ };
175281
+ }
175282
+ return {
175283
+ projectDir: resolvedRoot,
175284
+ previewComponentPath: resolvedPreviewComponentPath,
175285
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
175286
+ circuitFiles: []
175287
+ };
175288
+ };
175289
+ if (fileOrDir) {
175290
+ const resolved = path51.resolve(resolvedRoot, fileOrDir);
175291
+ if (fs50.existsSync(resolved) && fs50.statSync(resolved).isDirectory()) {
175292
+ const projectConfig3 = loadProjectConfig(resolvedRoot);
175293
+ const resolvedPreviewComponentPath2 = projectConfig3?.previewComponentPath ? path51.resolve(resolvedRoot, projectConfig3.previewComponentPath) : undefined;
175294
+ const resolvedSiteDefaultComponentPath2 = projectConfig3?.siteDefaultComponentPath ? path51.resolve(resolvedRoot, projectConfig3.siteDefaultComponentPath) : undefined;
175295
+ if (includeBoardFiles) {
175296
+ const circuitFiles = findBoardFiles({
175297
+ projectDir: resolvedRoot,
175298
+ filePaths: [resolved]
175299
+ }).filter((file) => isSubPath2(file, resolved));
175300
+ if (circuitFiles.length === 0) {
175301
+ throw new Error(`There were no files to build found matching the includeBoardFiles globs: ${JSON.stringify(includeBoardFilePatterns)}`);
175302
+ }
175303
+ return {
175304
+ projectDir: resolvedRoot,
175305
+ previewComponentPath: resolvedPreviewComponentPath2,
175306
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath2,
175307
+ circuitFiles
175308
+ };
175309
+ }
175310
+ const projectDir2 = findProjectRoot(resolved);
175311
+ const mainEntrypoint = await getEntrypoint({
175312
+ projectDir: projectDir2,
175313
+ onSuccess: () => {
175314
+ return;
175315
+ },
175316
+ onError: () => {
175317
+ return;
175318
+ }
175319
+ });
175320
+ return {
175321
+ projectDir: projectDir2,
175322
+ mainEntrypoint: mainEntrypoint || undefined,
175323
+ previewComponentPath: resolvedPreviewComponentPath2,
175324
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath2,
175325
+ circuitFiles: mainEntrypoint ? [mainEntrypoint] : []
175326
+ };
175327
+ }
175328
+ const fileDir = path51.dirname(resolved);
175329
+ const projectDir = findProjectRoot(fileDir);
175330
+ const projectConfig2 = loadProjectConfig(projectDir);
175331
+ const resolvedPreviewComponentPath = projectConfig2?.previewComponentPath ? path51.resolve(projectDir, projectConfig2.previewComponentPath) : undefined;
175332
+ const resolvedSiteDefaultComponentPath = projectConfig2?.siteDefaultComponentPath ? path51.resolve(projectDir, projectConfig2.siteDefaultComponentPath) : undefined;
175333
+ return {
175334
+ projectDir,
175335
+ previewComponentPath: resolvedPreviewComponentPath,
175336
+ siteDefaultComponentPath: resolvedSiteDefaultComponentPath,
175337
+ circuitFiles: [resolved]
175338
+ };
175339
+ }
175340
+ return buildFromProjectDir();
175341
+ }
175342
+
175343
+ // cli/build/resolve-build-options.ts
175344
+ var resolveBuildOptions = ({
175345
+ cliOptions,
175346
+ projectConfig: projectConfig2
175347
+ }) => {
175348
+ if (cliOptions?.ignoreConfig) {
175349
+ return { options: cliOptions, configAppliedOpts: [] };
175350
+ }
175351
+ const configBuild = projectConfig2?.build;
175352
+ const configAppliedOpts = [];
175353
+ if (!cliOptions?.kicadProject && configBuild?.kicadProject) {
175354
+ configAppliedOpts.push("kicad-project");
175355
+ }
175356
+ if (!cliOptions?.kicadLibrary && configBuild?.kicadLibrary) {
175357
+ configAppliedOpts.push("kicad-library");
175358
+ }
175359
+ if (!cliOptions?.kicadPcm && configBuild?.kicadPcm) {
175360
+ configAppliedOpts.push("kicad-pcm");
175361
+ }
175362
+ if (!cliOptions?.previewImages && configBuild?.previewImages) {
175363
+ configAppliedOpts.push("preview-images");
175364
+ }
175365
+ if (!cliOptions?.glbs && configBuild?.glbs) {
175366
+ configAppliedOpts.push("glbs");
175367
+ }
175368
+ if (!cliOptions?.transpile && configBuild?.typescriptLibrary) {
175369
+ configAppliedOpts.push("transpile");
175370
+ }
175371
+ const options = {
175372
+ ...cliOptions,
175373
+ kicadProject: cliOptions?.kicadProject ?? configBuild?.kicadProject,
175374
+ kicadLibrary: cliOptions?.kicadLibrary ?? configBuild?.kicadLibrary,
175375
+ kicadLibraryName: cliOptions?.kicadLibraryName ?? projectConfig2?.kicadLibraryName,
175376
+ kicadPcm: cliOptions?.kicadPcm ?? configBuild?.kicadPcm,
175377
+ previewImages: cliOptions?.previewImages ?? configBuild?.previewImages,
175378
+ glbs: cliOptions?.glbs ?? configBuild?.glbs,
175379
+ transpile: cliOptions?.transpile ?? configBuild?.typescriptLibrary
175380
+ };
175381
+ return { options, configAppliedOpts };
175382
+ };
175383
+
175352
175384
  // cli/build/transpile/index.ts
175353
- import path52 from "node:path";
175354
- import fs51 from "node:fs";
175385
+ import path53 from "node:path";
175386
+ import fs52 from "node:fs";
175355
175387
  import { rollup } from "rollup";
175356
175388
  import typescript from "@rollup/plugin-typescript";
175357
175389
  import resolve11 from "@rollup/plugin-node-resolve";
@@ -175360,11 +175392,11 @@ import json from "@rollup/plugin-json";
175360
175392
  import dts from "rollup-plugin-dts";
175361
175393
 
175362
175394
  // cli/build/transpile/static-asset-plugin.ts
175363
- import fs50 from "node:fs";
175364
- import path51 from "node:path";
175395
+ import fs51 from "node:fs";
175396
+ import path52 from "node:path";
175365
175397
  import { createHash as createHash2 } from "node:crypto";
175366
175398
  function normalizePathSeparators(filePath) {
175367
- return filePath.split(path51.sep).join("/");
175399
+ return filePath.split(path52.sep).join("/");
175368
175400
  }
175369
175401
  var STATIC_ASSET_EXTENSIONS = new Set([
175370
175402
  ".glb",
@@ -175395,24 +175427,24 @@ var createStaticAssetPlugin = ({
175395
175427
  return {
175396
175428
  name: "tsci-static-assets",
175397
175429
  resolveId(source, importer) {
175398
- const ext = path51.extname(source).toLowerCase();
175430
+ const ext = path52.extname(source).toLowerCase();
175399
175431
  if (!STATIC_ASSET_EXTENSIONS.has(ext))
175400
175432
  return null;
175401
- if (path51.isAbsolute(source)) {
175402
- return fs50.existsSync(source) ? { id: normalizePathSeparators(source), external: true } : null;
175433
+ if (path52.isAbsolute(source)) {
175434
+ return fs51.existsSync(source) ? { id: normalizePathSeparators(source), external: true } : null;
175403
175435
  }
175404
175436
  if (importer) {
175405
- const importerNative = importer.split("/").join(path51.sep);
175406
- const resolvedFromImporter = path51.resolve(path51.dirname(importerNative), source);
175407
- if (fs50.existsSync(resolvedFromImporter)) {
175437
+ const importerNative = importer.split("/").join(path52.sep);
175438
+ const resolvedFromImporter = path52.resolve(path52.dirname(importerNative), source);
175439
+ if (fs51.existsSync(resolvedFromImporter)) {
175408
175440
  return {
175409
175441
  id: normalizePathSeparators(resolvedFromImporter),
175410
175442
  external: true
175411
175443
  };
175412
175444
  }
175413
175445
  }
175414
- const resolvedFromProject = path51.resolve(resolvedBaseUrl, source);
175415
- if (fs50.existsSync(resolvedFromProject)) {
175446
+ const resolvedFromProject = path52.resolve(resolvedBaseUrl, source);
175447
+ if (fs51.existsSync(resolvedFromProject)) {
175416
175448
  return {
175417
175449
  id: normalizePathSeparators(resolvedFromProject),
175418
175450
  external: true
@@ -175425,8 +175457,8 @@ var createStaticAssetPlugin = ({
175425
175457
  const wildcard = isWildcard ? source.slice(patternPrefix.length) : "";
175426
175458
  for (const target of targets) {
175427
175459
  const targetPath = isWildcard ? target.replace("*", wildcard) : target;
175428
- const resolvedTarget = path51.resolve(resolvedBaseUrl, targetPath);
175429
- if (fs50.existsSync(resolvedTarget)) {
175460
+ const resolvedTarget = path52.resolve(resolvedBaseUrl, targetPath);
175461
+ if (fs51.existsSync(resolvedTarget)) {
175430
175462
  return {
175431
175463
  id: normalizePathSeparators(resolvedTarget),
175432
175464
  external: true
@@ -175452,18 +175484,18 @@ var createStaticAssetPlugin = ({
175452
175484
  if (chunk.type !== "chunk")
175453
175485
  continue;
175454
175486
  for (const importedId of chunk.imports) {
175455
- const ext = path51.extname(importedId).toLowerCase();
175487
+ const ext = path52.extname(importedId).toLowerCase();
175456
175488
  if (!STATIC_ASSET_EXTENSIONS.has(ext))
175457
175489
  continue;
175458
175490
  if (!copiedAssets.has(importedId)) {
175459
- const assetDir = path51.join(outputDir, "assets");
175460
- fs50.mkdirSync(assetDir, { recursive: true });
175461
- const nativePath = importedId.split("/").join(path51.sep);
175462
- const fileBuffer = fs50.readFileSync(nativePath);
175491
+ const assetDir = path52.join(outputDir, "assets");
175492
+ fs51.mkdirSync(assetDir, { recursive: true });
175493
+ const nativePath = importedId.split("/").join(path52.sep);
175494
+ const fileBuffer = fs51.readFileSync(nativePath);
175463
175495
  const hash = createHash2("sha1").update(fileBuffer).digest("hex").slice(0, 8);
175464
- const fileName = `${path51.basename(importedId, ext)}-${hash}${ext}`;
175465
- const outputFilePath = path51.join(assetDir, fileName);
175466
- fs50.writeFileSync(outputFilePath, fileBuffer);
175496
+ const fileName = `${path52.basename(importedId, ext)}-${hash}${ext}`;
175497
+ const outputFilePath = path52.join(assetDir, fileName);
175498
+ fs51.writeFileSync(outputFilePath, fileBuffer);
175467
175499
  copiedAssets.set(importedId, `./assets/${fileName}`);
175468
175500
  assetIdToOutputPath.set(importedId, `./assets/${fileName}`);
175469
175501
  }
@@ -175485,17 +175517,17 @@ function escapeRegExp(string) {
175485
175517
 
175486
175518
  // cli/build/transpile/index.ts
175487
175519
  var createExternalFunction = (projectDir, tsconfigPath) => (id) => {
175488
- if (id.startsWith(".") || id.startsWith("/") || path52.isAbsolute(id)) {
175520
+ if (id.startsWith(".") || id.startsWith("/") || path53.isAbsolute(id)) {
175489
175521
  return false;
175490
175522
  }
175491
175523
  let baseUrl = projectDir;
175492
175524
  let pathMappings = {};
175493
- if (tsconfigPath && fs51.existsSync(tsconfigPath)) {
175525
+ if (tsconfigPath && fs52.existsSync(tsconfigPath)) {
175494
175526
  try {
175495
- const tsconfigContent = fs51.readFileSync(tsconfigPath, "utf-8");
175527
+ const tsconfigContent = fs52.readFileSync(tsconfigPath, "utf-8");
175496
175528
  const tsconfig = JSON.parse(tsconfigContent);
175497
175529
  if (tsconfig.compilerOptions?.baseUrl) {
175498
- baseUrl = path52.resolve(path52.dirname(tsconfigPath), tsconfig.compilerOptions.baseUrl);
175530
+ baseUrl = path53.resolve(path53.dirname(tsconfigPath), tsconfig.compilerOptions.baseUrl);
175499
175531
  }
175500
175532
  if (tsconfig.compilerOptions?.paths) {
175501
175533
  pathMappings = tsconfig.compilerOptions.paths;
@@ -175509,17 +175541,17 @@ var createExternalFunction = (projectDir, tsconfigPath) => (id) => {
175509
175541
  }
175510
175542
  }
175511
175543
  const potentialPaths = [
175512
- path52.join(baseUrl, id),
175513
- path52.join(baseUrl, `${id}.ts`),
175514
- path52.join(baseUrl, `${id}.tsx`),
175515
- path52.join(baseUrl, `${id}.js`),
175516
- path52.join(baseUrl, `${id}.jsx`),
175517
- path52.join(baseUrl, id, "index.ts"),
175518
- path52.join(baseUrl, id, "index.tsx"),
175519
- path52.join(baseUrl, id, "index.js"),
175520
- path52.join(baseUrl, id, "index.jsx")
175544
+ path53.join(baseUrl, id),
175545
+ path53.join(baseUrl, `${id}.ts`),
175546
+ path53.join(baseUrl, `${id}.tsx`),
175547
+ path53.join(baseUrl, `${id}.js`),
175548
+ path53.join(baseUrl, `${id}.jsx`),
175549
+ path53.join(baseUrl, id, "index.ts"),
175550
+ path53.join(baseUrl, id, "index.tsx"),
175551
+ path53.join(baseUrl, id, "index.js"),
175552
+ path53.join(baseUrl, id, "index.jsx")
175521
175553
  ];
175522
- if (potentialPaths.some((p4) => fs51.existsSync(p4))) {
175554
+ if (potentialPaths.some((p4) => fs52.existsSync(p4))) {
175523
175555
  return false;
175524
175556
  }
175525
175557
  return true;
@@ -175530,17 +175562,17 @@ var transpileFile = async ({
175530
175562
  projectDir
175531
175563
  }) => {
175532
175564
  try {
175533
- fs51.mkdirSync(outputDir, { recursive: true });
175534
- const tsconfigPath = path52.join(projectDir, "tsconfig.json");
175535
- const hasTsConfig = fs51.existsSync(tsconfigPath);
175565
+ fs52.mkdirSync(outputDir, { recursive: true });
175566
+ const tsconfigPath = path53.join(projectDir, "tsconfig.json");
175567
+ const hasTsConfig = fs52.existsSync(tsconfigPath);
175536
175568
  let tsconfigBaseUrl = projectDir;
175537
175569
  let tsconfigPathMappings;
175538
175570
  if (hasTsConfig) {
175539
175571
  try {
175540
- const tsconfigContent = fs51.readFileSync(tsconfigPath, "utf-8");
175572
+ const tsconfigContent = fs52.readFileSync(tsconfigPath, "utf-8");
175541
175573
  const tsconfig = JSON.parse(tsconfigContent);
175542
175574
  if (tsconfig.compilerOptions?.baseUrl) {
175543
- tsconfigBaseUrl = path52.resolve(path52.dirname(tsconfigPath), tsconfig.compilerOptions.baseUrl);
175575
+ tsconfigBaseUrl = path53.resolve(path53.dirname(tsconfigPath), tsconfig.compilerOptions.baseUrl);
175544
175576
  }
175545
175577
  if (tsconfig.compilerOptions?.paths) {
175546
175578
  tsconfigPathMappings = tsconfig.compilerOptions.paths;
@@ -175595,27 +175627,27 @@ var transpileFile = async ({
175595
175627
  external: createExternalFunction(projectDir, hasTsConfig ? tsconfigPath : undefined),
175596
175628
  plugins: getPlugins()
175597
175629
  });
175598
- const esmOutputPath = path52.join(outputDir, "index.js");
175630
+ const esmOutputPath = path53.join(outputDir, "index.js");
175599
175631
  await esmBundle.write({
175600
175632
  file: esmOutputPath,
175601
175633
  format: "es",
175602
175634
  sourcemap: false
175603
175635
  });
175604
- console.log(`ESM bundle written to ${path52.relative(projectDir, esmOutputPath)}`);
175636
+ console.log(`ESM bundle written to ${path53.relative(projectDir, esmOutputPath)}`);
175605
175637
  console.log("Building CommonJS bundle...");
175606
175638
  const cjsBundle = await rollup({
175607
175639
  input,
175608
175640
  external: createExternalFunction(projectDir, hasTsConfig ? tsconfigPath : undefined),
175609
175641
  plugins: getPlugins()
175610
175642
  });
175611
- const cjsOutputPath = path52.join(outputDir, "index.cjs");
175643
+ const cjsOutputPath = path53.join(outputDir, "index.cjs");
175612
175644
  console.log("Writing CJS bundle to:", cjsOutputPath);
175613
175645
  await cjsBundle.write({
175614
175646
  file: cjsOutputPath,
175615
175647
  format: "cjs",
175616
175648
  sourcemap: false
175617
175649
  });
175618
- console.log(`CommonJS bundle written to ${path52.relative(projectDir, cjsOutputPath)}`);
175650
+ console.log(`CommonJS bundle written to ${path53.relative(projectDir, cjsOutputPath)}`);
175619
175651
  console.log("Generating type declarations...");
175620
175652
  const dtsBundle = await rollup({
175621
175653
  input,
@@ -175640,9 +175672,9 @@ var transpileFile = async ({
175640
175672
  dtsContent = dtsContent.replace(/import \* as [\w_]+ from ['"]react\/jsx-runtime['"];?\s*\n?/g, "");
175641
175673
  dtsContent = dtsContent.replace(/[\w_]+\.JSX\.Element/g, "any");
175642
175674
  dtsContent = dtsContent.replace(/export\s*{\s*};\s*$/gm, "").trim();
175643
- const dtsOutputPath = path52.join(outputDir, "index.d.ts");
175644
- fs51.writeFileSync(dtsOutputPath, dtsContent);
175645
- console.log(`Type declarations written to ${path52.relative(projectDir, dtsOutputPath)}`);
175675
+ const dtsOutputPath = path53.join(outputDir, "index.d.ts");
175676
+ fs52.writeFileSync(dtsOutputPath, dtsContent);
175677
+ console.log(`Type declarations written to ${path53.relative(projectDir, dtsOutputPath)}`);
175646
175678
  console.log(kleur_default.green("Transpilation complete!"));
175647
175679
  return true;
175648
175680
  } catch (err) {
@@ -175654,41 +175686,9 @@ var transpileFile = async ({
175654
175686
  }
175655
175687
  };
175656
175688
 
175657
- // cli/utils/validate-main-in-dist.ts
175658
- import fs52 from "node:fs";
175659
- import path53 from "node:path";
175660
- var validateMainInDist = (projectDir, distDir) => {
175661
- const packageJsonPath = path53.join(projectDir, "package.json");
175662
- if (!fs52.existsSync(packageJsonPath))
175663
- return;
175664
- const packageJson = JSON.parse(fs52.readFileSync(packageJsonPath, "utf-8"));
175665
- if (typeof packageJson.main !== "string")
175666
- return;
175667
- const resolvedMainPath = path53.resolve(projectDir, packageJson.main);
175668
- const isMainInDist = resolvedMainPath === distDir || resolvedMainPath.startsWith(`${distDir}${path53.sep}`);
175669
- if (!isMainInDist) {
175670
- console.warn('When using transpilation, your package\'s "main" field should point inside the `dist/*` directory, usually to "dist/index.js"');
175671
- }
175672
- };
175673
-
175674
- // cli/utils/get-latest-tscircuit-cdn-url.ts
175675
- var TSCIRCUIT_NPMJS_API_URL = "https://registry.npmjs.org/tscircuit/latest";
175676
- async function getLatestTscircuitCdnVersion() {
175677
- const response = await fetch(TSCIRCUIT_NPMJS_API_URL);
175678
- if (!response.ok) {
175679
- throw new Error(`Failed to fetch tscircuit version from CDN: ${response.statusText}`);
175680
- }
175681
- const data = await response.json();
175682
- return data.version;
175683
- }
175684
- async function getLatestTscircuitCdnUrl() {
175685
- const version2 = await getLatestTscircuitCdnVersion();
175686
- return `https://cdn.jsdelivr.net/npm/tscircuit@${version2}/dist/browser.min.js`;
175687
- }
175688
-
175689
175689
  // cli/build/worker-pool.ts
175690
- import path54 from "node:path";
175691
175690
  import fs53 from "node:fs";
175691
+ import path54 from "node:path";
175692
175692
  import { Worker } from "node:worker_threads";
175693
175693
  var getWorkerEntrypointPath = () => {
175694
175694
  const tsPath = path54.join(import.meta.dir, "build-worker-entrypoint.ts");
@@ -175709,6 +175709,8 @@ class WorkerPool {
175709
175709
  onLog;
175710
175710
  workerEntrypointPath;
175711
175711
  initialized = false;
175712
+ stopped = false;
175713
+ stopReason = null;
175712
175714
  constructor(options) {
175713
175715
  this.concurrency = options.concurrency;
175714
175716
  this.onLog = options.onLog;
@@ -175779,6 +175781,8 @@ class WorkerPool {
175779
175781
  });
175780
175782
  }
175781
175783
  processQueue() {
175784
+ if (this.stopped)
175785
+ return;
175782
175786
  if (this.jobQueue.length === 0)
175783
175787
  return;
175784
175788
  const availableWorker = this.workers.find((w4) => !w4.busy);
@@ -175799,6 +175803,9 @@ class WorkerPool {
175799
175803
  availableWorker.worker.postMessage(message);
175800
175804
  }
175801
175805
  async queueJob(job) {
175806
+ if (this.stopped) {
175807
+ return Promise.reject(this.stopReason ?? new Error("Worker pool stopped"));
175808
+ }
175802
175809
  await this.initWorkers();
175803
175810
  return new Promise((resolve12, reject) => {
175804
175811
  const queuedJob = {
@@ -175810,6 +175817,16 @@ class WorkerPool {
175810
175817
  this.processQueue();
175811
175818
  });
175812
175819
  }
175820
+ async stop(reason) {
175821
+ if (this.stopped)
175822
+ return;
175823
+ this.stopped = true;
175824
+ this.stopReason = reason;
175825
+ for (const queuedJob of this.jobQueue) {
175826
+ queuedJob.reject(reason);
175827
+ }
175828
+ this.jobQueue = [];
175829
+ }
175813
175830
  async runUntilComplete() {
175814
175831
  return new Promise((resolve12) => {
175815
175832
  const checkComplete = () => {
@@ -175838,22 +175855,31 @@ async function buildFilesWithWorkerPool(options) {
175838
175855
  });
175839
175856
  const results = [];
175840
175857
  const promises = [];
175858
+ const cancellationError = new Error("Build cancelled due fatal error");
175841
175859
  for (const file of options.files) {
175842
175860
  const promise = pool.queueJob({
175843
175861
  filePath: file.filePath,
175844
175862
  outputPath: file.outputPath,
175845
175863
  projectDir: options.projectDir,
175846
175864
  options: options.buildOptions
175847
- }).then((result) => {
175865
+ }).then(async (result) => {
175848
175866
  results.push(result);
175849
175867
  if (options.onJobComplete) {
175850
- options.onJobComplete(result);
175868
+ await options.onJobComplete(result);
175869
+ }
175870
+ if (options.stopOnFatal && result.isFatalError) {
175871
+ await pool.stop(cancellationError);
175851
175872
  }
175852
175873
  return result;
175853
175874
  });
175854
175875
  promises.push(promise);
175855
175876
  }
175856
- await Promise.all(promises);
175877
+ const settledResults = await Promise.allSettled(promises);
175878
+ for (const settledResult of settledResults) {
175879
+ if (settledResult.status === "rejected" && settledResult.reason !== cancellationError) {
175880
+ throw settledResult.reason;
175881
+ }
175882
+ }
175857
175883
  await pool.terminate();
175858
175884
  return results;
175859
175885
  }
@@ -175998,6 +176024,9 @@ var registerBuild = (program3) => {
175998
176024
  console.log(kleur_default.cyan(`[profile] ${relative10}: ${durationMs.toFixed(1)}ms`));
175999
176025
  }
176000
176026
  await processBuildResult(filePath, outputPath, buildOutcome);
176027
+ if (buildOutcome.isFatalError) {
176028
+ break;
176029
+ }
176001
176030
  }
176002
176031
  };
176003
176032
  const buildWithWorkers = async () => {
@@ -176012,6 +176041,7 @@ var registerBuild = (program3) => {
176012
176041
  projectDir,
176013
176042
  concurrency: concurrencyValue,
176014
176043
  buildOptions,
176044
+ stopOnFatal: true,
176015
176045
  onLog: (lines) => {
176016
176046
  for (const line2 of lines) {
176017
176047
  console.log(line2);
@@ -176038,6 +176068,9 @@ var registerBuild = (program3) => {
176038
176068
  ok: result.ok,
176039
176069
  isFatalError: result.isFatalError
176040
176070
  });
176071
+ if (result.isFatalError) {
176072
+ process.exit(1);
176073
+ }
176041
176074
  }
176042
176075
  });
176043
176076
  };