@tscircuit/cli 0.1.849 → 0.1.850

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 +424 -29
  2. package/package.json +2 -2
package/dist/main.js CHANGED
@@ -61896,8 +61896,8 @@ var require_fill_range = __commonJS((exports2, module2) => {
61896
61896
  var util = __require("util");
61897
61897
  var toRegexRange = require_to_regex_range();
61898
61898
  var isObject3 = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
61899
- var transform = (toNumber) => {
61900
- return (value) => toNumber === true ? Number(value) : String(value);
61899
+ var transform = (toNumber2) => {
61900
+ return (value) => toNumber2 === true ? Number(value) : String(value);
61901
61901
  };
61902
61902
  var isValidValue = (value) => {
61903
61903
  return typeof value === "number" || typeof value === "string" && value !== "";
@@ -61920,14 +61920,14 @@ var require_fill_range = __commonJS((exports2, module2) => {
61920
61920
  }
61921
61921
  return options.stringify === true;
61922
61922
  };
61923
- var pad = (input, maxLength, toNumber) => {
61923
+ var pad = (input, maxLength, toNumber2) => {
61924
61924
  if (maxLength > 0) {
61925
61925
  let dash = input[0] === "-" ? "-" : "";
61926
61926
  if (dash)
61927
61927
  input = input.slice(1);
61928
61928
  input = dash + input.padStart(dash ? maxLength - 1 : maxLength, "0");
61929
61929
  }
61930
- if (toNumber === false) {
61930
+ if (toNumber2 === false) {
61931
61931
  return String(input);
61932
61932
  }
61933
61933
  return input;
@@ -62016,8 +62016,8 @@ var require_fill_range = __commonJS((exports2, module2) => {
62016
62016
  step = Math.max(Math.abs(step), 1);
62017
62017
  let padded = zeros(startString) || zeros(endString) || zeros(stepString);
62018
62018
  let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
62019
- let toNumber = padded === false && stringify(start, end, options) === false;
62020
- let format = options.transform || transform(toNumber);
62019
+ let toNumber2 = padded === false && stringify(start, end, options) === false;
62020
+ let format = options.transform || transform(toNumber2);
62021
62021
  if (options.toRegex && step === 1) {
62022
62022
  return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
62023
62023
  }
@@ -62029,7 +62029,7 @@ var require_fill_range = __commonJS((exports2, module2) => {
62029
62029
  if (options.toRegex === true && step > 1) {
62030
62030
  push(a);
62031
62031
  } else {
62032
- range.push(pad(format(a, index), maxLen, toNumber));
62032
+ range.push(pad(format(a, index), maxLen, toNumber2));
62033
62033
  }
62034
62034
  a = descending ? a - step : a + step;
62035
62035
  index++;
@@ -74375,7 +74375,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
74375
74375
  import { execSync as execSync2 } from "node:child_process";
74376
74376
  var import_semver2 = __toESM2(require_semver2(), 1);
74377
74377
  // package.json
74378
- var version = "0.1.848";
74378
+ var version = "0.1.849";
74379
74379
  var package_default = {
74380
74380
  name: "@tscircuit/cli",
74381
74381
  version,
@@ -74402,7 +74402,7 @@ var package_default = {
74402
74402
  chokidar: "4.0.1",
74403
74403
  "circuit-json": "0.0.325",
74404
74404
  "circuit-json-to-gltf": "^0.0.58",
74405
- "circuit-json-to-kicad": "^0.0.40",
74405
+ "circuit-json-to-kicad": "^0.0.52",
74406
74406
  "circuit-json-to-readable-netlist": "^0.0.13",
74407
74407
  "circuit-json-to-spice": "^0.0.10",
74408
74408
  "circuit-json-to-tscircuit": "^0.0.9",
@@ -76274,6 +76274,10 @@ import {
76274
76274
  Pts,
76275
76275
  SchematicSymbol,
76276
76276
  Stroke,
76277
+ SymbolCircle,
76278
+ SymbolCircleCenter,
76279
+ SymbolCircleFill,
76280
+ SymbolCircleRadius,
76277
76281
  SymbolPin,
76278
76282
  SymbolPinName,
76279
76283
  SymbolPinNames,
@@ -76398,6 +76402,15 @@ import {
76398
76402
  TextEffectsFont as TextEffectsFont7
76399
76403
  } from "kicadts";
76400
76404
  import { parseKicadMod as parseKicadMod2 } from "kicadts";
76405
+ import {
76406
+ EmbeddedFonts as EmbeddedFonts5,
76407
+ SymbolPinNames as SymbolPinNames2,
76408
+ SymbolPinNumbers as SymbolPinNumbers2,
76409
+ SymbolProperty as SymbolProperty4,
76410
+ TextEffects as TextEffects8,
76411
+ TextEffectsFont as TextEffectsFont8,
76412
+ TextEffectsJustify as TextEffectsJustify4
76413
+ } from "kicadts";
76401
76414
  import { KicadSymbolLib as KicadSymbolLib2 } from "kicadts";
76402
76415
  var ConverterStage = class {
76403
76416
  MAX_ITERATIONS = 1000;
@@ -76473,10 +76486,58 @@ function extractReferencePrefix(name) {
76473
76486
  const match = name.match(/^([A-Za-z]+)/);
76474
76487
  return match?.[1]?.toUpperCase() ?? "U";
76475
76488
  }
76489
+ var referencePrefixByFtype = {
76490
+ simple_resistor: "R",
76491
+ simple_capacitor: "C",
76492
+ simple_inductor: "L",
76493
+ simple_diode: "D",
76494
+ simple_led: "D",
76495
+ simple_chip: "U",
76496
+ simple_transistor: "Q",
76497
+ simple_mosfet: "Q",
76498
+ simple_fuse: "F",
76499
+ simple_switch: "SW",
76500
+ simple_push_button: "SW",
76501
+ simple_potentiometer: "RV",
76502
+ simple_crystal: "Y",
76503
+ simple_resonator: "Y",
76504
+ simple_pin_header: "J",
76505
+ simple_pinout: "J",
76506
+ simple_test_point: "TP",
76507
+ simple_battery: "BT"
76508
+ };
76509
+ var referenceDesignatorPattern = /^[A-Za-z]+\d+$/;
76510
+ function isReferenceDesignator(value) {
76511
+ if (!value)
76512
+ return false;
76513
+ return referenceDesignatorPattern.test(value.trim());
76514
+ }
76515
+ function getReferencePrefixForComponent(sourceComponent) {
76516
+ const ftype = sourceComponent?.ftype;
76517
+ if (ftype && referencePrefixByFtype[ftype]) {
76518
+ return referencePrefixByFtype[ftype];
76519
+ }
76520
+ const name = sourceComponent?.name;
76521
+ if (isReferenceDesignator(name)) {
76522
+ return extractReferencePrefix(name);
76523
+ }
76524
+ return extractReferencePrefix(name);
76525
+ }
76526
+ function getReferenceDesignator(sourceComponent) {
76527
+ const name = sourceComponent?.name;
76528
+ if (isReferenceDesignator(name)) {
76529
+ return name.trim();
76530
+ }
76531
+ const prefix = getReferencePrefixForComponent(sourceComponent);
76532
+ return `${prefix}?`;
76533
+ }
76476
76534
  function isBuiltinSymbol(symbolName) {
76477
76535
  return symbolName in symbols;
76478
76536
  }
76479
- function getLibraryId(sourceComp, schematicComp, cadComponent) {
76537
+ function getLibraryId(sourceComp, schematicComp, cadComponent, schematicSymbolName) {
76538
+ if (schematicSymbolName) {
76539
+ return `Custom:${schematicSymbolName}`;
76540
+ }
76480
76541
  if (sourceComp.type !== "source_component") {
76481
76542
  if (schematicComp.symbol_name) {
76482
76543
  if (isBuiltinSymbol(schematicComp.symbol_name)) {
@@ -76493,14 +76554,16 @@ function getLibraryId(sourceComp, schematicComp, cadComponent) {
76493
76554
  return `Custom:${schematicComp.symbol_name}`;
76494
76555
  }
76495
76556
  const ergonomicName = getKicadCompatibleComponentName(sourceComp, cadComponent);
76496
- const refPrefix = extractReferencePrefix(sourceComp.name);
76557
+ const refPrefix = getReferencePrefixForComponent(sourceComp);
76497
76558
  return `Device:${refPrefix}_${ergonomicName}`;
76498
76559
  }
76499
76560
  var AddLibrarySymbolsStage = class extends ConverterStage {
76561
+ processedSymbolNames = /* @__PURE__ */ new Set;
76500
76562
  _step() {
76501
76563
  const { kicadSch, db } = this.ctx;
76502
76564
  const libSymbols = new LibSymbols;
76503
76565
  const librarySymbols = [];
76566
+ this.processedSymbolNames = /* @__PURE__ */ new Set;
76504
76567
  const schematicComponents = db.schematic_component.list();
76505
76568
  for (const schematicComponent of schematicComponents) {
76506
76569
  const libSymbol = this.createLibrarySymbolForComponent(schematicComponent);
@@ -76538,6 +76601,16 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76538
76601
  if (!sourceComp)
76539
76602
  return null;
76540
76603
  const cadComponent = db.cad_component?.list()?.find((cad) => cad.source_component_id === sourceComp.source_component_id);
76604
+ let schematicSymbolId = schematicComponent.schematic_symbol_id;
76605
+ if (!schematicSymbolId) {
76606
+ const linkedPrimitive = this.ctx.circuitJson.find((el) => (el.type === "schematic_line" || el.type === "schematic_circle" || el.type === "schematic_path") && el.schematic_component_id === schematicComponent.schematic_component_id && el.schematic_symbol_id);
76607
+ if (linkedPrimitive) {
76608
+ schematicSymbolId = linkedPrimitive.schematic_symbol_id;
76609
+ }
76610
+ }
76611
+ if (schematicSymbolId) {
76612
+ return this.createLibrarySymbolFromSchematicSymbol(schematicComponent, sourceComp, cadComponent, schematicSymbolId);
76613
+ }
76541
76614
  const symbolName = schematicComponent.symbol_name || (sourceComp.ftype === "simple_chip" ? `generic_chip_${schematicComponent.source_component_id}` : null);
76542
76615
  if (!symbolName)
76543
76616
  return null;
@@ -76555,9 +76628,97 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76555
76628
  description: this.getDescription(sourceComp),
76556
76629
  keywords: this.getKeywords(sourceComp),
76557
76630
  fpFilters: this.getFpFilters(sourceComp),
76558
- footprintRef: footprintName ? `tscircuit:${footprintName}` : ""
76631
+ footprintRef: footprintName ? `tscircuit:${footprintName}` : "",
76632
+ referencePrefix: getReferencePrefixForComponent(sourceComp)
76559
76633
  });
76560
76634
  }
76635
+ createLibrarySymbolFromSchematicSymbol(schematicComponent, sourceComp, cadComponent, schematicSymbolId) {
76636
+ const { db } = this.ctx;
76637
+ const schematicSymbol = this.ctx.circuitJson.find((el) => el.type === "schematic_symbol" && el.schematic_symbol_id === schematicSymbolId);
76638
+ if (!schematicSymbol) {
76639
+ return null;
76640
+ }
76641
+ let symbolName;
76642
+ if (schematicSymbol.name) {
76643
+ symbolName = schematicSymbol.name;
76644
+ } else {
76645
+ const ergonomicName = getKicadCompatibleComponentName(sourceComp, cadComponent);
76646
+ if (ergonomicName) {
76647
+ symbolName = ergonomicName;
76648
+ } else {
76649
+ symbolName = `custom_${sourceComp.ftype || "component"}_${schematicSymbolId}`;
76650
+ }
76651
+ }
76652
+ const libId = `Custom:${symbolName}`;
76653
+ if (this.processedSymbolNames.has(libId)) {
76654
+ return null;
76655
+ }
76656
+ this.processedSymbolNames.add(libId);
76657
+ const symbolData = this.buildSymbolDataFromSchematicPrimitives(schematicSymbolId, schematicSymbol, schematicComponent.schematic_component_id);
76658
+ const footprintName = getKicadCompatibleComponentName(sourceComp, cadComponent);
76659
+ return this.createLibrarySymbol({
76660
+ libId,
76661
+ symbolData,
76662
+ isChip: false,
76663
+ schematicComponent,
76664
+ description: this.getDescription(sourceComp),
76665
+ keywords: this.getKeywords(sourceComp),
76666
+ fpFilters: this.getFpFilters(sourceComp),
76667
+ footprintRef: footprintName ? `tscircuit:${footprintName}` : "",
76668
+ referencePrefix: getReferencePrefixForComponent(sourceComp)
76669
+ });
76670
+ }
76671
+ buildSymbolDataFromSchematicPrimitives(schematicSymbolId, schematicSymbol, schematicComponentId) {
76672
+ const { circuitJson } = this.ctx;
76673
+ const circles = circuitJson.filter((el) => el.type === "schematic_circle" && el.schematic_symbol_id === schematicSymbolId);
76674
+ const lines = circuitJson.filter((el) => el.type === "schematic_line" && el.schematic_symbol_id === schematicSymbolId);
76675
+ const paths = circuitJson.filter((el) => el.type === "schematic_path" && el.schematic_symbol_id === schematicSymbolId);
76676
+ let ports = circuitJson.filter((el) => el.type === "schematic_port" && el.schematic_symbol_id === schematicSymbolId);
76677
+ if (ports.length === 0 && schematicComponentId) {
76678
+ ports = circuitJson.filter((el) => el.type === "schematic_port" && el.schematic_component_id === schematicComponentId && el.display_pin_label);
76679
+ }
76680
+ const primitives2 = [];
76681
+ for (const circle of circles) {
76682
+ primitives2.push({
76683
+ type: "circle",
76684
+ x: circle.center?.x ?? 0,
76685
+ y: circle.center?.y ?? 0,
76686
+ radius: circle.radius ?? 0.5,
76687
+ fill: circle.is_filled ?? false
76688
+ });
76689
+ }
76690
+ for (const line of lines) {
76691
+ primitives2.push({
76692
+ type: "path",
76693
+ points: [
76694
+ { x: line.x1 ?? 0, y: line.y1 ?? 0 },
76695
+ { x: line.x2 ?? 0, y: line.y2 ?? 0 }
76696
+ ]
76697
+ });
76698
+ }
76699
+ for (const path14 of paths) {
76700
+ if (path14.points && path14.points.length > 0) {
76701
+ primitives2.push({
76702
+ type: "path",
76703
+ points: path14.points
76704
+ });
76705
+ }
76706
+ }
76707
+ const symbolPorts = ports.map((port, index) => ({
76708
+ x: port.center?.x ?? 0,
76709
+ y: port.center?.y ?? 0,
76710
+ labels: [port.display_pin_label || `${port.pin_number || index + 1}`],
76711
+ pinNumber: port.pin_number || index + 1,
76712
+ facingDirection: port.facing_direction
76713
+ }));
76714
+ symbolPorts.sort((a, b) => a.pinNumber - b.pinNumber);
76715
+ return {
76716
+ center: schematicSymbol.center || { x: 0, y: 0 },
76717
+ size: schematicSymbol.size || { width: 1, height: 1 },
76718
+ primitives: primitives2,
76719
+ ports: symbolPorts
76720
+ };
76721
+ }
76561
76722
  createLibrarySymbolForNetLabel({
76562
76723
  netLabel,
76563
76724
  isPower,
@@ -76577,7 +76738,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76577
76738
  schematicComponent: undefined,
76578
76739
  description: isPower ? "Power net label" : isGround ? "Ground net label" : "Net symbol",
76579
76740
  keywords: isPower ? "power net" : isGround ? "ground net" : "net",
76580
- fpFilters: ""
76741
+ fpFilters: "",
76742
+ referencePrefix: libId.split(":")[1]?.[0] || "U"
76581
76743
  });
76582
76744
  }
76583
76745
  getSymbolData(symbolName, schematicComponent) {
@@ -76625,7 +76787,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76625
76787
  description,
76626
76788
  keywords,
76627
76789
  fpFilters,
76628
- footprintRef = ""
76790
+ footprintRef = "",
76791
+ referencePrefix
76629
76792
  }) {
76630
76793
  const symbol = new SchematicSymbol({
76631
76794
  libraryId: libId,
@@ -76645,7 +76808,8 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76645
76808
  description,
76646
76809
  keywords,
76647
76810
  fpFilters,
76648
- footprintRef
76811
+ footprintRef,
76812
+ referencePrefix
76649
76813
  });
76650
76814
  const drawingSymbol = this.createDrawingSubsymbol({
76651
76815
  libId,
@@ -76669,9 +76833,10 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76669
76833
  description,
76670
76834
  keywords,
76671
76835
  fpFilters,
76672
- footprintRef = ""
76836
+ footprintRef = "",
76837
+ referencePrefix
76673
76838
  }) {
76674
- const refPrefix = libId.split(":")[1]?.[0] || "U";
76839
+ const refPrefix = referencePrefix || libId.split(":")[1]?.[0] || "U";
76675
76840
  const properties = [
76676
76841
  {
76677
76842
  key: "Reference",
@@ -76773,6 +76938,13 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76773
76938
  fillType
76774
76939
  });
76775
76940
  drawingSymbol.polylines.push(polyline);
76941
+ } else if (primitive.type === "circle") {
76942
+ const circle = this.createCircleFromPrimitive({
76943
+ primitive,
76944
+ scale: symbolScale,
76945
+ center: symbolData.center
76946
+ });
76947
+ drawingSymbol.circles.push(circle);
76776
76948
  }
76777
76949
  }
76778
76950
  return drawingSymbol;
@@ -76802,6 +76974,31 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
76802
76974
  polyline.fill = fill;
76803
76975
  return polyline;
76804
76976
  }
76977
+ createCircleFromPrimitive({
76978
+ primitive,
76979
+ scale: scale4,
76980
+ center
76981
+ }) {
76982
+ const circle = new SymbolCircle;
76983
+ const cx = center?.x ?? 0;
76984
+ const cy = center?.y ?? 0;
76985
+ const scaleMatrix = createScaleMatrix(scale4, scale4);
76986
+ const scaledPos = applyToPoint(scaleMatrix, {
76987
+ x: primitive.x - cx,
76988
+ y: primitive.y - cy
76989
+ });
76990
+ const c = circle;
76991
+ c._sxCenter = new SymbolCircleCenter(scaledPos.x, scaledPos.y);
76992
+ c._sxRadius = new SymbolCircleRadius(primitive.radius * scale4);
76993
+ const stroke = new Stroke;
76994
+ stroke.width = 0.254;
76995
+ stroke.type = "default";
76996
+ c._sxStroke = stroke;
76997
+ const fill = new SymbolCircleFill;
76998
+ fill.type = primitive.fill ? "outline" : "none";
76999
+ c._sxFill = fill;
77000
+ return circle;
77001
+ }
76805
77002
  createPinSubsymbol({
76806
77003
  libId,
76807
77004
  symbolData,
@@ -76969,7 +77166,28 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
76969
77166
  fieldsAutoplaced: true
76970
77167
  });
76971
77168
  const cadComponent = db.cad_component?.list()?.find((cad) => cad.source_component_id === sourceComponent.source_component_id);
76972
- const libId = getLibraryId(sourceComponent, schematicComponent, cadComponent);
77169
+ let schematicSymbolName;
77170
+ let schematicSymbolId = schematicComponent.schematic_symbol_id;
77171
+ if (!schematicSymbolId) {
77172
+ const linkedPrimitive = this.ctx.circuitJson.find((el) => (el.type === "schematic_line" || el.type === "schematic_circle" || el.type === "schematic_path") && el.schematic_component_id === schematicComponent.schematic_component_id && el.schematic_symbol_id);
77173
+ if (linkedPrimitive) {
77174
+ schematicSymbolId = linkedPrimitive.schematic_symbol_id;
77175
+ }
77176
+ }
77177
+ if (schematicSymbolId) {
77178
+ const schematicSymbol = this.ctx.circuitJson.find((el) => el.type === "schematic_symbol" && el.schematic_symbol_id === schematicSymbolId);
77179
+ if (schematicSymbol?.name) {
77180
+ schematicSymbolName = schematicSymbol.name;
77181
+ } else {
77182
+ const ergonomicName = getKicadCompatibleComponentName(sourceComponent, cadComponent);
77183
+ if (ergonomicName) {
77184
+ schematicSymbolName = ergonomicName;
77185
+ } else {
77186
+ schematicSymbolName = `custom_${sourceComponent.ftype || "component"}_${schematicSymbolId}`;
77187
+ }
77188
+ }
77189
+ }
77190
+ const libId = getLibraryId(sourceComponent, schematicComponent, cadComponent, schematicSymbolName);
76973
77191
  const symLibId = new SymbolLibId(libId);
76974
77192
  symbol._sxLibId = symLibId;
76975
77193
  const { reference, value, description } = this.getComponentMetadata(sourceComponent);
@@ -77011,10 +77229,20 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
77011
77229
  effects: this.createTextEffects(1.27, true)
77012
77230
  });
77013
77231
  symbol.properties.push(referenceProperty, valueProperty, footprintProperty, datasheetProperty, descriptionProperty);
77014
- const schematicPorts = db.schematic_port.list().filter((p) => p.schematic_component_id === schematicComponent.schematic_component_id).sort((a, b) => (a.pin_number || 0) - (b.pin_number || 0));
77015
- for (const port of schematicPorts) {
77232
+ let schematicPorts = db.schematic_port.list().filter((p) => p.schematic_component_id === schematicComponent.schematic_component_id);
77233
+ if (schematicSymbolId) {
77234
+ const customSymbolPorts = schematicPorts.filter((p) => p.display_pin_label);
77235
+ if (customSymbolPorts.length > 0) {
77236
+ schematicPorts = customSymbolPorts;
77237
+ }
77238
+ }
77239
+ schematicPorts.sort((a, b) => (a.pin_number || 0) - (b.pin_number || 0));
77240
+ for (let i = 0;i < schematicPorts.length; i++) {
77241
+ const port = schematicPorts[i];
77242
+ if (!port)
77243
+ continue;
77016
77244
  const pin = new SymbolPin2;
77017
- pin.numberString = `${port.pin_number || 1}`;
77245
+ pin.numberString = `${port.pin_number || i + 1}`;
77018
77246
  pin.uuid = crypto.randomUUID();
77019
77247
  symbol.pins.push(pin);
77020
77248
  }
@@ -77078,43 +77306,58 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
77078
77306
  }
77079
77307
  getComponentMetadata(sourceComp) {
77080
77308
  const name = sourceComp.name || "?";
77309
+ const reference = getReferenceDesignator(sourceComp);
77081
77310
  if (sourceComp.ftype === "simple_resistor") {
77082
77311
  return {
77083
- reference: name,
77312
+ reference,
77084
77313
  value: sourceComp.display_resistance || "R",
77085
77314
  description: "Resistor"
77086
77315
  };
77087
77316
  }
77088
77317
  if (sourceComp.ftype === "simple_capacitor") {
77089
77318
  return {
77090
- reference: name,
77319
+ reference,
77091
77320
  value: sourceComp.display_capacitance || "C",
77092
77321
  description: "Capacitor"
77093
77322
  };
77094
77323
  }
77095
77324
  if (sourceComp.ftype === "simple_inductor") {
77096
77325
  return {
77097
- reference: name,
77326
+ reference,
77098
77327
  value: sourceComp.display_inductance || "L",
77099
77328
  description: "Inductor"
77100
77329
  };
77101
77330
  }
77102
77331
  if (sourceComp.ftype === "simple_diode") {
77103
77332
  return {
77104
- reference: name,
77333
+ reference,
77105
77334
  value: "D",
77106
77335
  description: "Diode"
77107
77336
  };
77108
77337
  }
77109
77338
  if (sourceComp.ftype === "simple_chip") {
77110
77339
  return {
77111
- reference: name,
77340
+ reference,
77112
77341
  value: name,
77113
77342
  description: "Integrated Circuit"
77114
77343
  };
77115
77344
  }
77345
+ if (sourceComp.ftype === "simple_led") {
77346
+ return {
77347
+ reference,
77348
+ value: sourceComp.manufacturer_part_number || "",
77349
+ description: "LED"
77350
+ };
77351
+ }
77352
+ if (sourceComp.ftype === "simple_switch") {
77353
+ return {
77354
+ reference,
77355
+ value: sourceComp.manufacturer_part_number || "",
77356
+ description: "Switch"
77357
+ };
77358
+ }
77116
77359
  return {
77117
- reference: name,
77360
+ reference,
77118
77361
  value: name,
77119
77362
  description: "Component"
77120
77363
  };
@@ -79126,6 +79369,140 @@ function updateBuiltinKicadSymbolFootprint(kicadSymbol, options) {
79126
79369
  }
79127
79370
  return { symbolName: kicadSymbol.symbolName, symbol };
79128
79371
  }
79372
+ var DEFAULT_TEXT_SIZE = 1.27;
79373
+ var DEFAULT_TEXT_THICKNESS = 0.15;
79374
+ var toNumber = (value, fallback) => {
79375
+ if (value === undefined)
79376
+ return fallback;
79377
+ const parsed = typeof value === "number" ? value : Number.parseFloat(value);
79378
+ if (Number.isNaN(parsed))
79379
+ return fallback;
79380
+ return parsed;
79381
+ };
79382
+ var createTextEffects = (effectsMeta, fallback) => {
79383
+ if (!effectsMeta)
79384
+ return fallback;
79385
+ const effects = new TextEffects8({
79386
+ font: fallback?.font,
79387
+ justify: fallback?.justify,
79388
+ hiddenText: fallback?.hiddenText ?? false
79389
+ });
79390
+ if (!effects.font) {
79391
+ const defaultFont = new TextEffectsFont8;
79392
+ defaultFont.size = { width: DEFAULT_TEXT_SIZE, height: DEFAULT_TEXT_SIZE };
79393
+ effects.font = defaultFont;
79394
+ }
79395
+ if (effectsMeta.font?.size) {
79396
+ effects.font.size = {
79397
+ width: toNumber(effectsMeta.font.size.x, DEFAULT_TEXT_SIZE),
79398
+ height: toNumber(effectsMeta.font.size.y, DEFAULT_TEXT_SIZE)
79399
+ };
79400
+ }
79401
+ if (effectsMeta.font?.thickness !== undefined) {
79402
+ effects.font.thickness = toNumber(effectsMeta.font.thickness, DEFAULT_TEXT_THICKNESS);
79403
+ }
79404
+ if (!effects.font.size) {
79405
+ effects.font.size = { width: DEFAULT_TEXT_SIZE, height: DEFAULT_TEXT_SIZE };
79406
+ }
79407
+ if (!effects.font.thickness && effectsMeta.font?.thickness !== undefined) {
79408
+ effects.font.thickness = DEFAULT_TEXT_THICKNESS;
79409
+ }
79410
+ const justify = createJustify(effectsMeta.justify);
79411
+ if (justify) {
79412
+ effects.justify = justify;
79413
+ }
79414
+ if (effectsMeta.hide !== undefined) {
79415
+ effects.hiddenText = effectsMeta.hide;
79416
+ }
79417
+ return effects;
79418
+ };
79419
+ var createJustify = (justifyInput) => {
79420
+ if (!justifyInput)
79421
+ return;
79422
+ const values = Array.isArray(justifyInput) ? justifyInput : [justifyInput];
79423
+ const options = {};
79424
+ for (const value of values) {
79425
+ if (value === "left" || value === "right") {
79426
+ options.horizontal = value;
79427
+ } else if (value === "top" || value === "bottom") {
79428
+ options.vertical = value;
79429
+ } else if (value === "mirror") {
79430
+ options.mirror = true;
79431
+ }
79432
+ }
79433
+ if (!options.horizontal && !options.vertical && !options.mirror) {
79434
+ return;
79435
+ }
79436
+ return new TextEffectsJustify4(options);
79437
+ };
79438
+ var applySymbolProperty = (symbol, key, propertyMeta) => {
79439
+ const existingProperty = symbol.properties.find((prop) => prop.key === key);
79440
+ const nextId = propertyMeta.id !== undefined ? toNumber(propertyMeta.id) : existingProperty?.id;
79441
+ const nextAt = propertyMeta.at ? [
79442
+ toNumber(propertyMeta.at.x, 0),
79443
+ toNumber(propertyMeta.at.y, 0),
79444
+ toNumber(propertyMeta.at.rotation, 0)
79445
+ ] : existingProperty?.at;
79446
+ const nextEffects = createTextEffects(propertyMeta.effects, existingProperty?.effects);
79447
+ if (existingProperty) {
79448
+ existingProperty.value = propertyMeta.value;
79449
+ if (nextId !== undefined) {
79450
+ existingProperty.id = nextId;
79451
+ }
79452
+ if (nextAt) {
79453
+ existingProperty.at = nextAt;
79454
+ }
79455
+ if (nextEffects) {
79456
+ existingProperty.effects = nextEffects;
79457
+ }
79458
+ return;
79459
+ }
79460
+ symbol.properties.push(new SymbolProperty4({
79461
+ key,
79462
+ value: propertyMeta.value,
79463
+ id: nextId,
79464
+ at: nextAt,
79465
+ effects: nextEffects
79466
+ }));
79467
+ };
79468
+ function applyKicadSymbolMetadata(kicadSymbol, metadata) {
79469
+ const { symbol } = kicadSymbol;
79470
+ if (metadata.excludeFromSim !== undefined) {
79471
+ symbol.excludeFromSim = metadata.excludeFromSim;
79472
+ }
79473
+ if (metadata.inBom !== undefined) {
79474
+ symbol.inBom = metadata.inBom;
79475
+ }
79476
+ if (metadata.onBoard !== undefined) {
79477
+ symbol.onBoard = metadata.onBoard;
79478
+ }
79479
+ if (metadata.embeddedFonts !== undefined) {
79480
+ symbol._sxEmbeddedFonts = new EmbeddedFonts5(metadata.embeddedFonts);
79481
+ }
79482
+ if (metadata.pinNumbers?.hide !== undefined) {
79483
+ const pinNumbers = symbol.pinNumbers ?? new SymbolPinNumbers2;
79484
+ pinNumbers.hide = metadata.pinNumbers.hide;
79485
+ symbol.pinNumbers = pinNumbers;
79486
+ }
79487
+ if (metadata.pinNames) {
79488
+ const pinNames = symbol.pinNames ?? new SymbolPinNames2;
79489
+ if (metadata.pinNames.offset !== undefined) {
79490
+ pinNames.offset = toNumber(metadata.pinNames.offset, pinNames.offset);
79491
+ }
79492
+ if (metadata.pinNames.hide !== undefined) {
79493
+ pinNames.hide = metadata.pinNames.hide;
79494
+ }
79495
+ symbol.pinNames = pinNames;
79496
+ }
79497
+ if (metadata.properties) {
79498
+ for (const [key, propertyMeta] of Object.entries(metadata.properties)) {
79499
+ if (!propertyMeta)
79500
+ continue;
79501
+ applySymbolProperty(symbol, key, propertyMeta);
79502
+ }
79503
+ }
79504
+ return kicadSymbol;
79505
+ }
79129
79506
  function classifyKicadSymbols(ctx) {
79130
79507
  for (const extractedKicadComponent of ctx.extractedKicadComponents) {
79131
79508
  classifySymbolsForComponent({
@@ -79141,6 +79518,7 @@ function classifySymbolsForComponent({
79141
79518
  const { tscircuitComponentName, kicadSymbols } = extractedKicadComponent;
79142
79519
  const hasCustomFootprint = componentHasCustomFootprint(extractedKicadComponent);
79143
79520
  let hasAddedUserSymbol = false;
79521
+ const metadata = ctx.symbolMetadataMap.get(tscircuitComponentName);
79144
79522
  for (const kicadSymbol of kicadSymbols) {
79145
79523
  if (!kicadSymbol.isBuiltin) {
79146
79524
  if (!hasAddedUserSymbol) {
@@ -79157,7 +79535,8 @@ function classifySymbolsForComponent({
79157
79535
  isPcm: ctx.isPcm
79158
79536
  });
79159
79537
  }
79160
- addUserSymbol({ ctx, kicadSymbol: renamedSymbol });
79538
+ const updatedSymbol = metadata ? applyKicadSymbolMetadata(renamedSymbol, metadata) : renamedSymbol;
79539
+ addUserSymbol({ ctx, kicadSymbol: updatedSymbol });
79161
79540
  } else {
79162
79541
  addUserSymbol({ ctx, kicadSymbol });
79163
79542
  }
@@ -79173,7 +79552,8 @@ function classifySymbolsForComponent({
79173
79552
  kicadFootprintName: tscircuitComponentName,
79174
79553
  isPcm: ctx.isPcm
79175
79554
  });
79176
- addUserSymbol({ ctx, kicadSymbol: renamedSymbol });
79555
+ const updatedSymbol = metadata ? applyKicadSymbolMetadata(renamedSymbol, metadata) : renamedSymbol;
79556
+ addUserSymbol({ ctx, kicadSymbol: updatedSymbol });
79177
79557
  } else {
79178
79558
  const updatedSymbol = updateBuiltinKicadSymbolFootprint(kicadSymbol, {
79179
79559
  isPcm: ctx.isPcm
@@ -79293,6 +79673,7 @@ var KicadLibraryConverter = class {
79293
79673
  kicadLibraryName: options.kicadLibraryName ?? "tscircuit_library",
79294
79674
  includeBuiltins: options.includeBuiltins ?? true,
79295
79675
  getComponentKicadMetadata: options.getComponentKicadMetadata,
79676
+ getComponentKicadSymbolMetadata: options.getComponentKicadSymbolMetadata,
79296
79677
  isPcm: options.isPcm ?? false,
79297
79678
  kicadPcmPackageId: options.kicadPcmPackageId
79298
79679
  });
@@ -79326,6 +79707,12 @@ var KicadLibraryConverter = class {
79326
79707
  this.ctx.footprintMetadataMap.set(exportName, metadata);
79327
79708
  }
79328
79709
  }
79710
+ if (this.ctx.getComponentKicadSymbolMetadata) {
79711
+ const symbolMetadata = await this.ctx.getComponentKicadSymbolMetadata(componentPath, exportName);
79712
+ if (symbolMetadata) {
79713
+ this.ctx.symbolMetadataMap.set(exportName, symbolMetadata);
79714
+ }
79715
+ }
79329
79716
  const circuitJson = await this.options.buildFileToCircuitJson(componentPath, exportName);
79330
79717
  if (circuitJson && (!Array.isArray(circuitJson) || circuitJson.length > 0)) {
79331
79718
  builtTscircuitComponents.push({
@@ -79348,6 +79735,12 @@ var KicadLibraryConverter = class {
79348
79735
  this.ctx.footprintMetadataMap.set(componentName, metadata);
79349
79736
  }
79350
79737
  }
79738
+ if (this.ctx.getComponentKicadSymbolMetadata) {
79739
+ const symbolMetadata = await this.ctx.getComponentKicadSymbolMetadata(componentPath, "default");
79740
+ if (symbolMetadata) {
79741
+ this.ctx.symbolMetadataMap.set(componentName, symbolMetadata);
79742
+ }
79743
+ }
79351
79744
  const circuitJson = await this.options.buildFileToCircuitJson(componentPath, "default");
79352
79745
  if (circuitJson && (!Array.isArray(circuitJson) || circuitJson.length > 0)) {
79353
79746
  builtTscircuitComponents.push({
@@ -79394,9 +79787,11 @@ function createKicadLibraryConverterContext(params2) {
79394
79787
  kicadLibraryName: params2.kicadLibraryName,
79395
79788
  includeBuiltins: params2.includeBuiltins,
79396
79789
  getComponentKicadMetadata: params2.getComponentKicadMetadata,
79790
+ getComponentKicadSymbolMetadata: params2.getComponentKicadSymbolMetadata,
79397
79791
  isPcm: params2.isPcm,
79398
79792
  kicadPcmPackageId: params2.kicadPcmPackageId,
79399
79793
  footprintMetadataMap: /* @__PURE__ */ new Map,
79794
+ symbolMetadataMap: /* @__PURE__ */ new Map,
79400
79795
  builtTscircuitComponents: [],
79401
79796
  extractedKicadComponents: [],
79402
79797
  userKicadFootprints: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.1.849",
3
+ "version": "0.1.850",
4
4
  "main": "dist/main.js",
5
5
  "devDependencies": {
6
6
  "@babel/standalone": "^7.26.9",
@@ -24,7 +24,7 @@
24
24
  "chokidar": "4.0.1",
25
25
  "circuit-json": "0.0.325",
26
26
  "circuit-json-to-gltf": "^0.0.58",
27
- "circuit-json-to-kicad": "^0.0.40",
27
+ "circuit-json-to-kicad": "^0.0.52",
28
28
  "circuit-json-to-readable-netlist": "^0.0.13",
29
29
  "circuit-json-to-spice": "^0.0.10",
30
30
  "circuit-json-to-tscircuit": "^0.0.9",