@tscircuit/footprinter 0.0.315 → 0.0.317

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/index.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import { AnySoupElement, AnyCircuitElement } from 'circuit-json';
2
2
  import { z } from 'zod';
3
3
 
4
+ type StandardSize = {
5
+ imperial: string;
6
+ metric: string;
7
+ p_mm_min: number;
8
+ ph_mm_min: number;
9
+ pw_mm_min: number;
10
+ h_mm_min: number;
11
+ w_mm_min: number;
12
+ };
13
+ declare const footprintSizes: StandardSize[];
14
+
4
15
  type NowDefined<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
5
16
 
6
17
  declare const any_footprinter_def: z.ZodUnion<[z.ZodObject<{
@@ -1724,17 +1735,6 @@ declare const any_footprinter_def: z.ZodUnion<[z.ZodObject<{
1724
1735
  }>]>;
1725
1736
  type AnyFootprinterDefinitionOutput = z.infer<typeof any_footprinter_def>;
1726
1737
 
1727
- type StandardSize = {
1728
- imperial: string;
1729
- metric: string;
1730
- p_mm_min: number;
1731
- ph_mm_min: number;
1732
- pw_mm_min: number;
1733
- h_mm_min: number;
1734
- w_mm_min: number;
1735
- };
1736
- declare const footprintSizes: StandardSize[];
1737
-
1738
1738
  type BaseOptionKey = "origin" | "norefdes" | "invert" | "faceup" | "nosilkscreen";
1739
1739
  type FootprinterParamsBuilder<K extends string> = {
1740
1740
  [P in K | BaseOptionKey | "params" | "soup" | "circuitJson"]: P extends "params" | "soup" | "circuitJson" ? Footprinter[P] : (v?: number | string | boolean) => FootprinterParamsBuilder<K>;
package/dist/index.js CHANGED
@@ -146,7 +146,8 @@ var platedHoleWithRectPad = (options) => {
146
146
  rectPadWidth,
147
147
  rectPadHeight,
148
148
  holeOffsetX = 0,
149
- holeOffsetY = 0
149
+ holeOffsetY = 0,
150
+ rectBorderRadius
150
151
  } = options;
151
152
  return {
152
153
  pcb_plated_hole_id: "",
@@ -159,6 +160,9 @@ var platedHoleWithRectPad = (options) => {
159
160
  pad_shape: "rect",
160
161
  rect_pad_width: mm2(rectPadWidth),
161
162
  rect_pad_height: mm2(rectPadHeight),
163
+ ...rectBorderRadius !== void 0 && {
164
+ rect_border_radius: rectBorderRadius
165
+ },
162
166
  pcb_port_id: "",
163
167
  layers: ["top", "bottom"],
164
168
  port_hints: [pn.toString()],
@@ -6494,18 +6498,15 @@ var jst_def = base_def.extend({
6494
6498
  pl: length47.optional(),
6495
6499
  w: length47.optional(),
6496
6500
  h: length47.optional(),
6497
- sh: z60.union([z60.boolean(), z60.string(), z60.number()]).optional().transform((v) => {
6498
- if (typeof v === "string") {
6499
- const n = Number(v);
6500
- return Number.isNaN(n) ? true : n;
6501
- }
6502
- return v;
6503
- }).describe(
6501
+ sh: z60.boolean().optional().describe(
6504
6502
  'JST SH (Surface-mount) connector family. SH stands for "Super High-density".'
6505
6503
  ),
6506
6504
  ph: z60.boolean().optional().describe(
6507
6505
  'JST PH (Through-hole) connector family. PH stands for "Pin Header".'
6508
6506
  ),
6507
+ zh: z60.boolean().optional().describe(
6508
+ "JST ZH (Through-hole) connector family. 1.5mm pitch wire-to-board."
6509
+ ),
6509
6510
  string: z60.string().optional()
6510
6511
  });
6511
6512
  var variantDefaults = {
@@ -6523,52 +6524,72 @@ var variantDefaults = {
6523
6524
  pl: length47.parse("1.55mm"),
6524
6525
  w: length47.parse("5.8mm"),
6525
6526
  h: length47.parse("7.8mm")
6527
+ },
6528
+ zh: {
6529
+ p: length47.parse("1.5mm"),
6530
+ id: length47.parse("0.73mm"),
6531
+ pw: length47.parse("1.03mm"),
6532
+ pl: length47.parse("1.73mm"),
6533
+ w: length47.parse("3mm"),
6534
+ h: length47.parse("3.5mm")
6526
6535
  }
6527
6536
  };
6528
6537
  function getVariant(params) {
6529
6538
  if (params.sh) return "sh";
6530
6539
  if (params.ph) return "ph";
6540
+ if (params.zh) return "zh";
6531
6541
  return "ph";
6532
6542
  }
6533
6543
  function generatePads(variant, numPins, p, id, pw, pl) {
6534
6544
  const pads = [];
6535
6545
  if (variant === "ph") {
6536
- const half_p = p / 2;
6537
- pads.push(
6538
- platedHoleWithRectPad({
6539
- pn: 1,
6540
- x: -half_p,
6541
- y: 2,
6542
- holeDiameter: id,
6543
- rectPadWidth: pw,
6544
- rectPadHeight: pl
6545
- })
6546
- );
6547
- pads.push(
6548
- platedHoleWithRectPad({
6549
- pn: 2,
6550
- x: half_p,
6551
- y: 2,
6552
- holeDiameter: id,
6553
- rectPadWidth: pw,
6554
- rectPadHeight: pl
6555
- })
6556
- );
6546
+ const startX = -((numPins - 1) / 2) * p;
6547
+ for (let i = 0; i < numPins; i++) {
6548
+ const x = startX + i * p;
6549
+ pads.push(
6550
+ platedHoleWithRectPad({
6551
+ pn: i + 1,
6552
+ x,
6553
+ y: 2,
6554
+ holeDiameter: id,
6555
+ rectPadWidth: pw,
6556
+ rectPadHeight: pl
6557
+ })
6558
+ );
6559
+ }
6560
+ } else if (variant === "zh") {
6561
+ const startX = -((numPins - 1) / 2) * p;
6562
+ for (let i = 0; i < numPins; i++) {
6563
+ const x = startX + i * p;
6564
+ if (i === 0) {
6565
+ pads.push(
6566
+ platedHoleWithRectPad({
6567
+ pn: i + 1,
6568
+ x,
6569
+ y: 0,
6570
+ holeDiameter: id,
6571
+ rectPadWidth: pw,
6572
+ rectPadHeight: pl,
6573
+ rectBorderRadius: 0.12499977
6574
+ })
6575
+ );
6576
+ } else {
6577
+ pads.push(platedHolePill(i + 1, x, 0, id, pw, pl));
6578
+ }
6579
+ }
6557
6580
  } else {
6558
6581
  const startX = -((numPins - 1) / 2) * p;
6559
6582
  for (let i = 0; i < numPins; i++) {
6560
6583
  const x = startX + i * p;
6561
- console.log("x si", x);
6562
6584
  pads.push(rectpad(i + 1, x, -1.325, pw, pl));
6563
6585
  }
6564
6586
  const sideOffset = (numPins - 1) / 2 * p + 1.3;
6565
- console.log("offset", sideOffset);
6566
6587
  pads.push(rectpad(numPins + 1, -sideOffset, 1.22, 1.2, 1.8));
6567
6588
  pads.push(rectpad(numPins + 2, sideOffset, 1.22, 1.2, 1.8));
6568
6589
  }
6569
6590
  return pads;
6570
6591
  }
6571
- function generateSilkscreenBody(variant, w, h) {
6592
+ function generateSilkscreenBody(variant, w, h, numPins, p) {
6572
6593
  if (variant === "ph") {
6573
6594
  return {
6574
6595
  type: "pcb_silkscreen_path",
@@ -6584,6 +6605,26 @@ function generateSilkscreenBody(variant, w, h) {
6584
6605
  stroke_width: 0.1,
6585
6606
  pcb_silkscreen_path_id: ""
6586
6607
  };
6608
+ } else if (variant === "zh" && numPins && p) {
6609
+ const pinSpan = (numPins - 1) * p;
6610
+ const bodyLeft = -pinSpan / 2 - 1.5;
6611
+ const bodyRight = pinSpan / 2 + 1.5;
6612
+ const bodyTop = -h / 2;
6613
+ const bodyBottom = h / 2;
6614
+ return {
6615
+ type: "pcb_silkscreen_path",
6616
+ layer: "top",
6617
+ pcb_component_id: "",
6618
+ route: [
6619
+ { x: bodyLeft, y: bodyTop },
6620
+ { x: bodyRight, y: bodyTop },
6621
+ { x: bodyRight, y: bodyBottom },
6622
+ { x: bodyLeft, y: bodyBottom },
6623
+ { x: bodyLeft, y: bodyTop }
6624
+ ],
6625
+ stroke_width: 0.1,
6626
+ pcb_silkscreen_path_id: ""
6627
+ };
6587
6628
  } else {
6588
6629
  return {
6589
6630
  type: "pcb_silkscreen_path",
@@ -6605,21 +6646,33 @@ var jst = (raw_params) => {
6605
6646
  const pl = params.pl ?? defaults.pl;
6606
6647
  const w = params.w ?? defaults.w;
6607
6648
  const h = params.h ?? defaults.h;
6608
- let numPins = variant === "sh" ? 4 : 2;
6609
- if (variant === "sh") {
6610
- const str = typeof raw_params.string === "string" ? raw_params.string : "";
6611
- const match = str.match(/sh(\d+)/);
6612
- if (match && match[1]) {
6613
- const parsed = parseInt(match[1], 10);
6614
- if (!Number.isNaN(parsed)) {
6615
- numPins = parsed;
6616
- }
6617
- } else if (typeof params.sh === "number") {
6618
- numPins = params.sh;
6649
+ let numPins;
6650
+ const explicitNumPins = raw_params.num_pins;
6651
+ if (typeof explicitNumPins === "number") {
6652
+ numPins = explicitNumPins;
6653
+ }
6654
+ const str = typeof raw_params.string === "string" ? raw_params.string : "";
6655
+ const match = str.match(/(?:^|_)jst(\d+)(?:_|$)/);
6656
+ const zhMatch = str.match(/(?:^|_)zh(\d+)(?:_|$)/);
6657
+ if (match && match[1]) {
6658
+ const parsed = Number.parseInt(match[1], 10);
6659
+ if (!Number.isNaN(parsed)) {
6660
+ numPins = parsed;
6619
6661
  }
6620
6662
  }
6663
+ if (zhMatch && zhMatch[1]) {
6664
+ const parsed = Number.parseInt(zhMatch[1], 10);
6665
+ if (!Number.isNaN(parsed)) {
6666
+ numPins = parsed;
6667
+ }
6668
+ }
6669
+ if (typeof numPins !== "number") {
6670
+ throw new Error(
6671
+ `JST requires an explicit pin count (e.g. jst6_sh or .jst(6))${params.string ? `, from string "${params.string}"` : ""}`
6672
+ );
6673
+ }
6621
6674
  const pads = generatePads(variant, numPins, p, id, pw, pl);
6622
- const silkscreenBody = generateSilkscreenBody(variant, w, h);
6675
+ const silkscreenBody = generateSilkscreenBody(variant, w, h, numPins, p);
6623
6676
  const silkscreenRefText = silkscreenRef(0, h / 2 + 1, 0.5);
6624
6677
  return {
6625
6678
  circuitJson: [...pads, silkscreenBody, silkscreenRefText],
@@ -6633,7 +6686,8 @@ var jst = (raw_params) => {
6633
6686
  h,
6634
6687
  num_pins: numPins,
6635
6688
  sh: variant === "sh",
6636
- ph: variant === "ph"
6689
+ ph: variant === "ph",
6690
+ zh: variant === "zh"
6637
6691
  }
6638
6692
  };
6639
6693
  };
@@ -9119,10 +9173,27 @@ var to92l = (raw_params) => {
9119
9173
  };
9120
9174
  };
9121
9175
 
9122
- // src/helpers/is-not-null.ts
9123
- function isNotNull(value) {
9124
- return value !== null && value !== void 0;
9125
- }
9176
+ // src/helpers/apply-norefdes.ts
9177
+ var applyNoRefDes = (elements, parameters) => {
9178
+ const refs = elements.filter(
9179
+ (el) => el.type === "pcb_silkscreen_text"
9180
+ );
9181
+ if (refs.length === 0) return elements;
9182
+ for (const ref of refs) {
9183
+ if (parameters.norefdes) {
9184
+ ref.text = "";
9185
+ }
9186
+ }
9187
+ return elements;
9188
+ };
9189
+
9190
+ // src/helpers/apply-nosilkscreen.ts
9191
+ var applyNoSilkscreen = (elements, parameters) => {
9192
+ if (!parameters.nosilkscreen) return elements;
9193
+ return elements.filter((element) => {
9194
+ return element.type !== "pcb_silkscreen_path" && element.type !== "pcb_silkscreen_text";
9195
+ });
9196
+ };
9126
9197
 
9127
9198
  // src/helpers/apply-origin.ts
9128
9199
  var applyOrigin = (elements, origin) => {
@@ -9218,32 +9289,15 @@ var applyOrigin = (elements, origin) => {
9218
9289
  return elements;
9219
9290
  };
9220
9291
 
9221
- // src/helpers/apply-norefdes.ts
9222
- var applyNoRefDes = (elements, parameters) => {
9223
- const refs = elements.filter(
9224
- (el) => el.type === "pcb_silkscreen_text"
9225
- );
9226
- if (refs.length === 0) return elements;
9227
- for (const ref of refs) {
9228
- if (parameters.norefdes) {
9229
- ref.text = "";
9230
- }
9231
- }
9232
- return elements;
9233
- };
9234
-
9235
- // src/helpers/apply-nosilkscreen.ts
9236
- var applyNoSilkscreen = (elements, parameters) => {
9237
- if (!parameters.nosilkscreen) return elements;
9238
- return elements.filter((element) => {
9239
- return element.type !== "pcb_silkscreen_path" && element.type !== "pcb_silkscreen_text";
9240
- });
9241
- };
9292
+ // src/helpers/is-not-null.ts
9293
+ function isNotNull(value) {
9294
+ return value !== null && value !== void 0;
9295
+ }
9242
9296
 
9243
9297
  // src/footprinter.ts
9244
9298
  var string2 = (def) => {
9245
9299
  let fp2 = footprinter();
9246
- const modifiedDef = def.replace(/^((?:\d{4}|\d{5}))(?=$|_|x)/, "res$1");
9300
+ const modifiedDef = def.replace(/^((?:\d{4}|\d{5}))(?=$|_|x)/, "res$1").replace(/^zh(\d+)(?:$|_)/, "jst$1_zh");
9247
9301
  const def_parts = modifiedDef.split(/_(?!metric)/).map((s) => {
9248
9302
  const m = s.match(/([a-zA-Z]+)([\(\d\.\+\?].*)?/);
9249
9303
  if (!m) return null;