@tscircuit/cli 0.1.232 → 0.1.234

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +123 -65
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -173655,8 +173655,8 @@ var registerRemove = (program3) => {
173655
173655
  };
173656
173656
 
173657
173657
  // cli/build/register.ts
173658
- import path28 from "node:path";
173659
- import fs29 from "node:fs";
173658
+ import path29 from "node:path";
173659
+ import fs30 from "node:fs";
173660
173660
 
173661
173661
  // cli/build/build-file.ts
173662
173662
  import path26 from "node:path";
@@ -173800,10 +173800,55 @@ ${scriptBlock} <script src="https://cdn.tailwindcss.com"></script>
173800
173800
  </html>`;
173801
173801
  };
173802
173802
 
173803
+ // cli/build/build-preview-images.ts
173804
+ import fs29 from "node:fs";
173805
+ import path28 from "node:path";
173806
+ import {
173807
+ convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg3,
173808
+ convertCircuitJsonToSchematicSvg as convertCircuitJsonToSchematicSvg2
173809
+ } from "circuit-to-svg";
173810
+ import { convertCircuitJsonToSimple3dSvg } from "circuit-json-to-simple-3d";
173811
+ import sharp from "sharp";
173812
+ var buildPreviewImages = async ({
173813
+ builtFiles,
173814
+ distDir,
173815
+ mainEntrypoint
173816
+ }) => {
173817
+ const successfulBuilds = builtFiles.filter((file) => file.ok);
173818
+ const normalizedMainEntrypoint = mainEntrypoint ? path28.resolve(mainEntrypoint) : undefined;
173819
+ const previewBuild = (() => {
173820
+ if (normalizedMainEntrypoint) {
173821
+ const match = successfulBuilds.find((built) => path28.resolve(built.sourcePath) === normalizedMainEntrypoint);
173822
+ if (match)
173823
+ return match;
173824
+ }
173825
+ return successfulBuilds[0];
173826
+ })();
173827
+ if (!previewBuild) {
173828
+ console.warn("No successful build output available for preview image generation.");
173829
+ return;
173830
+ }
173831
+ try {
173832
+ const circuitJsonRaw = fs29.readFileSync(previewBuild.outputPath, "utf-8");
173833
+ const circuitJson = JSON.parse(circuitJsonRaw);
173834
+ const pcbSvg = convertCircuitJsonToPcbSvg3(circuitJson);
173835
+ const schematicSvg = convertCircuitJsonToSchematicSvg2(circuitJson);
173836
+ const simple3dSvg = await convertCircuitJsonToSimple3dSvg(circuitJson);
173837
+ fs29.writeFileSync(path28.join(distDir, "pcb.svg"), pcbSvg, "utf-8");
173838
+ fs29.writeFileSync(path28.join(distDir, "schematic.svg"), schematicSvg, "utf-8");
173839
+ if (simple3dSvg) {
173840
+ const pngBuffer = await sharp(Buffer.from(simple3dSvg)).png().toBuffer();
173841
+ fs29.writeFileSync(path28.join(distDir, "3d.png"), pngBuffer);
173842
+ }
173843
+ } catch (error) {
173844
+ console.error("Failed to generate preview images:", error);
173845
+ }
173846
+ };
173847
+
173803
173848
  // cli/build/register.ts
173804
173849
  var registerBuild = (program3) => {
173805
- program3.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").option("--disable-pcb", "Disable PCB outputs").option("--disable-parts-engine", "Disable the parts engine").option("--site", "Generate a static site in the dist directory").action(async (file, options) => {
173806
- const { projectDir, circuitFiles } = await getBuildEntrypoints({
173850
+ program3.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").option("--disable-pcb", "Disable PCB outputs").option("--disable-parts-engine", "Disable the parts engine").option("--site", "Generate a static site in the dist directory").option("--preview-images", "Generate preview images in the dist directory").action(async (file, options) => {
173851
+ const { projectDir, circuitFiles, mainEntrypoint } = await getBuildEntrypoints({
173807
173852
  fileOrDir: file
173808
173853
  });
173809
173854
  const platformConfig2 = (() => {
@@ -173818,25 +173863,31 @@ var registerBuild = (program3) => {
173818
173863
  }
173819
173864
  return config;
173820
173865
  })();
173821
- const distDir = path28.join(projectDir, "dist");
173822
- fs29.mkdirSync(distDir, { recursive: true });
173866
+ const distDir = path29.join(projectDir, "dist");
173867
+ fs30.mkdirSync(distDir, { recursive: true });
173823
173868
  let hasErrors = false;
173824
173869
  const staticFileReferences = [];
173870
+ const builtFiles = [];
173825
173871
  for (const filePath of circuitFiles) {
173826
- const relative9 = path28.relative(projectDir, filePath);
173872
+ const relative9 = path29.relative(projectDir, filePath);
173827
173873
  const outputDirName = relative9.replace(/(\.board|\.circuit)?\.tsx$/, "");
173828
- const outputPath = path28.join(distDir, outputDirName, "circuit.json");
173874
+ const outputPath = path29.join(distDir, outputDirName, "circuit.json");
173829
173875
  const ok = await buildFile(filePath, outputPath, projectDir, {
173830
173876
  ignoreErrors: options?.ignoreErrors,
173831
173877
  ignoreWarnings: options?.ignoreWarnings,
173832
173878
  platformConfig: platformConfig2
173833
173879
  });
173880
+ builtFiles.push({
173881
+ sourcePath: filePath,
173882
+ outputPath,
173883
+ ok
173884
+ });
173834
173885
  if (!ok) {
173835
173886
  hasErrors = true;
173836
173887
  } else if (options?.site) {
173837
- const normalizedSourcePath = relative9.split(path28.sep).join("/");
173838
- const relativeOutputPath = path28.join(outputDirName, "circuit.json");
173839
- const normalizedOutputPath = relativeOutputPath.split(path28.sep).join("/");
173888
+ const normalizedSourcePath = relative9.split(path29.sep).join("/");
173889
+ const relativeOutputPath = path29.join(outputDirName, "circuit.json");
173890
+ const normalizedOutputPath = relativeOutputPath.split(path29.sep).join("/");
173840
173891
  staticFileReferences.push({
173841
173892
  filePath: normalizedSourcePath,
173842
173893
  fileStaticAssetUrl: `./${normalizedOutputPath}`
@@ -173846,31 +173897,38 @@ var registerBuild = (program3) => {
173846
173897
  if (hasErrors && !options?.ignoreErrors) {
173847
173898
  process.exit(1);
173848
173899
  }
173900
+ if (options?.previewImages) {
173901
+ await buildPreviewImages({
173902
+ builtFiles,
173903
+ distDir,
173904
+ mainEntrypoint
173905
+ });
173906
+ }
173849
173907
  if (options?.site) {
173850
173908
  const indexHtml = getStaticIndexHtmlFile({
173851
173909
  files: staticFileReferences,
173852
173910
  standaloneScriptSrc: "./standalone.min.js"
173853
173911
  });
173854
- fs29.writeFileSync(path28.join(distDir, "index.html"), indexHtml);
173855
- fs29.writeFileSync(path28.join(distDir, "standalone.min.js"), standalone_min_default);
173912
+ fs30.writeFileSync(path29.join(distDir, "index.html"), indexHtml);
173913
+ fs30.writeFileSync(path29.join(distDir, "standalone.min.js"), standalone_min_default);
173856
173914
  }
173857
173915
  });
173858
173916
  };
173859
173917
 
173860
173918
  // lib/shared/snapshot-project.ts
173861
- import fs31 from "node:fs";
173862
- import path29 from "node:path";
173919
+ import fs32 from "node:fs";
173920
+ import path30 from "node:path";
173863
173921
  import looksSame2 from "looks-same";
173864
- import sharp from "sharp";
173922
+ import sharp2 from "sharp";
173865
173923
  import {
173866
- convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg3,
173867
- convertCircuitJsonToSchematicSvg as convertCircuitJsonToSchematicSvg2
173924
+ convertCircuitJsonToPcbSvg as convertCircuitJsonToPcbSvg4,
173925
+ convertCircuitJsonToSchematicSvg as convertCircuitJsonToSchematicSvg3
173868
173926
  } from "circuit-to-svg";
173869
- import { convertCircuitJsonToSimple3dSvg } from "circuit-json-to-simple-3d";
173927
+ import { convertCircuitJsonToSimple3dSvg as convertCircuitJsonToSimple3dSvg2 } from "circuit-json-to-simple-3d";
173870
173928
 
173871
173929
  // lib/shared/compare-images.ts
173872
173930
  import looksSame from "looks-same";
173873
- import fs30 from "node:fs/promises";
173931
+ import fs31 from "node:fs/promises";
173874
173932
  var compareAndCreateDiff = async (buffer1, buffer2, diffPath) => {
173875
173933
  const { equal: equal2 } = await looksSame(buffer1, buffer2, {
173876
173934
  strict: false,
@@ -173886,7 +173944,7 @@ var compareAndCreateDiff = async (buffer1, buffer2, diffPath) => {
173886
173944
  tolerance: 2
173887
173945
  });
173888
173946
  } else {
173889
- await fs30.writeFile(diffPath, buffer2);
173947
+ await fs31.writeFile(diffPath, buffer2);
173890
173948
  }
173891
173949
  }
173892
173950
  return { equal: equal2 };
@@ -173911,19 +173969,19 @@ var snapshotProject = async ({
173911
173969
  ...DEFAULT_IGNORED_PATTERNS,
173912
173970
  ...ignored.map(normalizeIgnorePattern)
173913
173971
  ];
173914
- const resolvedPaths = filePaths.map((f) => path29.resolve(projectDir, f));
173972
+ const resolvedPaths = filePaths.map((f) => path30.resolve(projectDir, f));
173915
173973
  const boardFiles = resolvedPaths.length > 0 ? resolvedPaths.flatMap((p) => {
173916
- if (fs31.existsSync(p) && fs31.statSync(p).isDirectory()) {
173974
+ if (fs32.existsSync(p) && fs32.statSync(p).isDirectory()) {
173917
173975
  return globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
173918
173976
  cwd: p,
173919
173977
  ignore
173920
- }).map((f) => path29.join(p, f));
173978
+ }).map((f) => path30.join(p, f));
173921
173979
  }
173922
173980
  return [p];
173923
173981
  }) : globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
173924
173982
  cwd: projectDir,
173925
173983
  ignore
173926
- }).map((f) => path29.join(projectDir, f));
173984
+ }).map((f) => path30.join(projectDir, f));
173927
173985
  if (boardFiles.length === 0) {
173928
173986
  console.log("No entrypoint found. Run 'tsci init' to bootstrap a project or specify a file with 'tsci snapshot <file>'");
173929
173987
  return onExit(0);
@@ -173935,12 +173993,12 @@ var snapshotProject = async ({
173935
173993
  filePath: file,
173936
173994
  platformConfig: platformConfig2
173937
173995
  });
173938
- const pcbSvg = convertCircuitJsonToPcbSvg3(circuitJson);
173939
- const schSvg = convertCircuitJsonToSchematicSvg2(circuitJson);
173940
- const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg(circuitJson) : null;
173941
- const snapDir = path29.join(path29.dirname(file), "__snapshots__");
173942
- fs31.mkdirSync(snapDir, { recursive: true });
173943
- const base = path29.basename(file).replace(/\.tsx$/, "");
173996
+ const pcbSvg = convertCircuitJsonToPcbSvg4(circuitJson);
173997
+ const schSvg = convertCircuitJsonToSchematicSvg3(circuitJson);
173998
+ const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg2(circuitJson) : null;
173999
+ const snapDir = path30.join(path30.dirname(file), "__snapshots__");
174000
+ fs32.mkdirSync(snapDir, { recursive: true });
174001
+ const base = path30.basename(file).replace(/\.tsx$/, "");
173944
174002
  const pairs3 = [];
173945
174003
  if (pcbOnly || !schematicOnly)
173946
174004
  pairs3.push(["pcb", pcbSvg]);
@@ -173954,31 +174012,31 @@ var snapshotProject = async ({
173954
174012
  }
173955
174013
  for (const [type, newSvg] of pairs3) {
173956
174014
  const is3d = type === "3d";
173957
- const snapPath = path29.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
173958
- const existing = fs31.existsSync(snapPath);
173959
- const newContentBuffer = is3d ? await sharp(Buffer.from(newSvg)).png().toBuffer() : Buffer.from(newSvg, "utf8");
174015
+ const snapPath = path30.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
174016
+ const existing = fs32.existsSync(snapPath);
174017
+ const newContentBuffer = is3d ? await sharp2(Buffer.from(newSvg)).png().toBuffer() : Buffer.from(newSvg, "utf8");
173960
174018
  const newContentForFile = is3d ? newContentBuffer : newSvg;
173961
174019
  if (!existing) {
173962
- fs31.writeFileSync(snapPath, newContentForFile);
173963
- console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
174020
+ fs32.writeFileSync(snapPath, newContentForFile);
174021
+ console.log("✅", kleur_default.gray(path30.relative(projectDir, snapPath)));
173964
174022
  didUpdate = true;
173965
174023
  continue;
173966
174024
  }
173967
- const oldContentBuffer = fs31.readFileSync(snapPath);
174025
+ const oldContentBuffer = fs32.readFileSync(snapPath);
173968
174026
  const diffPath = snapPath.replace(is3d ? ".snap.png" : ".snap.svg", is3d ? ".diff.png" : ".diff.svg");
173969
174027
  const { equal: equal2 } = await compareAndCreateDiff(oldContentBuffer, newContentBuffer, diffPath);
173970
174028
  if (update) {
173971
174029
  if (!forceUpdate && equal2) {
173972
- console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
174030
+ console.log("✅", kleur_default.gray(path30.relative(projectDir, snapPath)));
173973
174031
  } else {
173974
- fs31.writeFileSync(snapPath, newContentForFile);
173975
- console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
174032
+ fs32.writeFileSync(snapPath, newContentForFile);
174033
+ console.log("✅", kleur_default.gray(path30.relative(projectDir, snapPath)));
173976
174034
  didUpdate = true;
173977
174035
  }
173978
174036
  } else if (!equal2) {
173979
174037
  mismatches.push(`${snapPath} (diff: ${diffPath})`);
173980
174038
  } else {
173981
- console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
174039
+ console.log("✅", kleur_default.gray(path30.relative(projectDir, snapPath)));
173982
174040
  }
173983
174041
  }
173984
174042
  }
@@ -174017,22 +174075,22 @@ var registerSnapshot = (program3) => {
174017
174075
  };
174018
174076
 
174019
174077
  // lib/shared/setup-github-actions.ts
174020
- import fs32 from "node:fs";
174021
- import path30 from "node:path";
174078
+ import fs33 from "node:fs";
174079
+ import path31 from "node:path";
174022
174080
  var setupGithubActions = (projectDir = process.cwd()) => {
174023
174081
  const findGitRoot = (startDir) => {
174024
- let dir = path30.resolve(startDir);
174025
- while (dir !== path30.parse(dir).root) {
174026
- if (fs32.existsSync(path30.join(dir, ".git"))) {
174082
+ let dir = path31.resolve(startDir);
174083
+ while (dir !== path31.parse(dir).root) {
174084
+ if (fs33.existsSync(path31.join(dir, ".git"))) {
174027
174085
  return dir;
174028
174086
  }
174029
- dir = path30.dirname(dir);
174087
+ dir = path31.dirname(dir);
174030
174088
  }
174031
174089
  return null;
174032
174090
  };
174033
174091
  const gitRoot = findGitRoot(projectDir) ?? projectDir;
174034
- const workflowsDir = path30.join(gitRoot, ".github", "workflows");
174035
- fs32.mkdirSync(workflowsDir, { recursive: true });
174092
+ const workflowsDir = path31.join(gitRoot, ".github", "workflows");
174093
+ fs33.mkdirSync(workflowsDir, { recursive: true });
174036
174094
  const buildWorkflow = `name: tscircuit Build
174037
174095
 
174038
174096
  on:
@@ -174071,8 +174129,8 @@ jobs:
174071
174129
  - run: bun install
174072
174130
  - run: bunx tsci snapshot
174073
174131
  `;
174074
- writeFileIfNotExists(path30.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
174075
- writeFileIfNotExists(path30.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
174132
+ writeFileIfNotExists(path31.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
174133
+ writeFileIfNotExists(path31.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
174076
174134
  };
174077
174135
 
174078
174136
  // cli/setup/register.ts
@@ -174098,8 +174156,8 @@ var registerSetup = (program3) => {
174098
174156
  };
174099
174157
 
174100
174158
  // cli/convert/register.ts
174101
- import fs33 from "node:fs/promises";
174102
- import path31 from "node:path";
174159
+ import fs34 from "node:fs/promises";
174160
+ import path32 from "node:path";
174103
174161
 
174104
174162
  // node_modules/kicad-component-converter/dist/index.js
174105
174163
  var __create4 = Object.create;
@@ -175411,8 +175469,8 @@ function getErrorMap() {
175411
175469
  return overrideErrorMap;
175412
175470
  }
175413
175471
  var makeIssue = (params2) => {
175414
- const { data, path: path31, errorMaps, issueData } = params2;
175415
- const fullPath = [...path31, ...issueData.path || []];
175472
+ const { data, path: path32, errorMaps, issueData } = params2;
175473
+ const fullPath = [...path32, ...issueData.path || []];
175416
175474
  const fullIssue = {
175417
175475
  ...issueData,
175418
175476
  path: fullPath
@@ -175520,11 +175578,11 @@ var errorUtil;
175520
175578
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
175521
175579
  })(errorUtil || (errorUtil = {}));
175522
175580
  var ParseInputLazyPath = class {
175523
- constructor(parent, value, path31, key) {
175581
+ constructor(parent, value, path32, key) {
175524
175582
  this._cachedPath = [];
175525
175583
  this.parent = parent;
175526
175584
  this.data = value;
175527
- this._path = path31;
175585
+ this._path = path32;
175528
175586
  this._key = key;
175529
175587
  }
175530
175588
  get path() {
@@ -179313,14 +179371,14 @@ function generateArcPath(start, mid, end, numPoints) {
179313
179371
  if (angleDelta < 0) {
179314
179372
  angleDelta += 2 * Math.PI;
179315
179373
  }
179316
- const path31 = [];
179374
+ const path32 = [];
179317
179375
  for (let i = 0;i <= numPoints; i++) {
179318
179376
  const angle = angleStart + i / numPoints * angleDelta;
179319
179377
  const x = center2.x + radius * Math.cos(angle);
179320
179378
  const y = center2.y + radius * Math.sin(angle);
179321
- path31.push({ x, y });
179379
+ path32.push({ x, y });
179322
179380
  }
179323
- return path31;
179381
+ return path32;
179324
179382
  }
179325
179383
  var makePoint = (p) => {
179326
179384
  if (Array.isArray(p)) {
@@ -179764,15 +179822,15 @@ var convertCircuitJsonToTscircuit = (circuitJson, opts) => {
179764
179822
  var registerConvert = (program3) => {
179765
179823
  program3.command("convert").description("Convert a .kicad_mod footprint to a tscircuit component").argument("<file>", "Path to the .kicad_mod file").option("-o, --output <path>", "Output TSX file path").option("-n, --name <component>", "Component name for export").action(async (file, options) => {
179766
179824
  try {
179767
- const inputPath = path31.resolve(file);
179768
- const modContent = await fs33.readFile(inputPath, "utf-8");
179825
+ const inputPath = path32.resolve(file);
179826
+ const modContent = await fs34.readFile(inputPath, "utf-8");
179769
179827
  const circuitJson = await parseKicadModToCircuitJson(modContent);
179770
- const componentName = options.name ?? path31.basename(inputPath, ".kicad_mod");
179828
+ const componentName = options.name ?? path32.basename(inputPath, ".kicad_mod");
179771
179829
  const tsx = convertCircuitJsonToTscircuit(circuitJson, {
179772
179830
  componentName
179773
179831
  });
179774
- const outputPath = options.output ? path31.resolve(options.output) : path31.join(path31.dirname(inputPath), `${componentName}.tsx`);
179775
- await fs33.writeFile(outputPath, tsx);
179832
+ const outputPath = options.output ? path32.resolve(options.output) : path32.join(path32.dirname(inputPath), `${componentName}.tsx`);
179833
+ await fs34.writeFile(outputPath, tsx);
179776
179834
  console.log(kleur_default.green(`Converted ${outputPath}`));
179777
179835
  } catch (error) {
179778
179836
  console.error(kleur_default.red("Failed to convert footprint:"), error instanceof Error ? error.message : error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.232",
3
+ "version": "0.1.234",
4
4
  "main": "dist/main.js",
5
5
  "devDependencies": {
6
6
  "@babel/standalone": "^7.26.9",