Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3f82090
Implement PDIP-8 footprint (Issue #371)
Feb 23, 2026
2703095
style: fix formatting using biome
Feb 23, 2026
7e92d2a
fix: resolve pdip8 test failures by fixing Proxy logic and fn registr…
Feb 23, 2026
272d0de
fix: ensure pdip functions are correctly registered and exported
Feb 23, 2026
e22d2dd
fix: resolve regex replacement bug and apply consistent formatting
Feb 23, 2026
bae0360
fix: correct regex syntax error and apply clean formatting
Feb 23, 2026
867ffd8
fix: revert fp to function to maintain backward compatibility while s…
Feb 23, 2026
0665c4c
fix: restore fp as a function and fix syntax errors in footprinter.ts
Feb 23, 2026
32bb13b
fix: implement hybrid Proxy for fp to support both function calls and…
Feb 23, 2026
3e37450
fix: correct test usage of fp() and restore library structure
Feb 23, 2026
ab7032f
fix: final test alignment with standard library call pattern
Feb 23, 2026
2720891
fix: restore original core logic to fix snapshot regressions while ke…
Feb 23, 2026
34ad3e7
fix: clean registration of pdip without breaking existing logic
Feb 23, 2026
035db3c
fix: remove duplicate type identifiers in footprinter.ts
Feb 23, 2026
85c87c9
fix: final clean registration of pdip without logic regressions
Feb 23, 2026
80261e3
fix: carefully add pdip support to proxy without breaking existing fo…
Feb 23, 2026
6b92de9
fix: remove duplicate type definitions in Footprinter interface
Feb 23, 2026
bb26140
fix: restore default num_pins in dip.ts to fix snapshot regression
Feb 23, 2026
697ecd9
fix: correctly parse pin count for JST PH variants in string definiti…
Feb 23, 2026
03e9a7c
fix: restore original jst logic and improve pin count parsing to hand…
Feb 23, 2026
e390832
feat: implement SPDIP (#180) and UTDFN (#183) footprints
Feb 23, 2026
bd2d1aa
fix: implement dynamic pin count parsing for JST PH variants (#495)
Feb 23, 2026
fac6c06
fix: restore original JST PH defaults to prevent snapshot regressions
Feb 23, 2026
09a0860
fix: correctly dispatch SOT-223-5 when called via functional paramete…
Feb 23, 2026
523b24a
Fix CI: formatting and tests
Feb 23, 2026
751f62a
style: apply biome formatting fixes
Feb 23, 2026
f3758c6
chore: trigger CI rerun
Pitrat-wav Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
"files": {
"ignore": ["gallery/**"]
},
"organizeImports": {
"enabled": true
},
Expand Down
4 changes: 2 additions & 2 deletions gallery/generate-grid-content.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from "path"
import fs from "fs"
import path from "node:path"
import fs from "node:fs"

const snapshotsDir = path.join(__dirname, "..", "tests", "__snapshots__")
const outputFile = path.join(__dirname, "content.ts")
Expand Down
3 changes: 2 additions & 1 deletion gallery/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
import React, { useState, useCallback } from "react"
import type React from "react"
import { useState, useCallback } from "react"
import ReactDOM from "react-dom/client"
import { fp } from "src/footprinter"
// @ts-ignore data is built during CI
Expand Down
2 changes: 1 addition & 1 deletion src/fn/axial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "circuit-json"
import { passive, type PassiveDef } from "../helpers/passive-fn"
import { z } from "zod"
import { platedhole } from "src/helpers/platedhole"
import { platedhole } from "../helpers/platedhole"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { base_def } from "../helpers/zod/base_def"

Expand Down
12 changes: 5 additions & 7 deletions src/fn/bga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { ALPHABET } from "../helpers/zod/ALPHABET"
import { z } from "zod"
import { base_def } from "../helpers/zod/base_def"
import { length, distance } from "circuit-json"
import { dim2d } from "src/helpers/zod/dim-2d"
import { function_call } from "src/helpers/zod/function-call"
import type { NowDefined } from "src/helpers/zod/now-defined"
import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef"
import { type PcbSilkscreenPath } from "circuit-json"
import { dim2d } from "../helpers/zod/dim-2d"
import { function_call } from "../helpers/zod/function-call"
import type { NowDefined } from "../helpers/zod/now-defined"
import { type SilkscreenRef, silkscreenRef } from "../helpers/silkscreenRef"
import type { PcbSilkscreenPath } from "circuit-json"

export const bga_def = base_def
.extend({
Expand Down Expand Up @@ -136,7 +136,6 @@ export const bga = (
pin_x = grid.x - 1 - x
pin_y = y
break
case "tl":
default:
// Keep original x,y for pin numbering
break
Expand Down Expand Up @@ -201,7 +200,6 @@ export const bga = (
{ x: edgeX, y: edgeY }, // Back to start
]
break
case "tl":
default:
markerRoute = [
{ x: -edgeX, y: edgeY }, // Start at corner
Expand Down
4 changes: 2 additions & 2 deletions src/fn/breakoutheaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
} from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef"
import { platedhole } from "src/helpers/platedhole"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { platedhole } from "../helpers/platedhole"
import { base_def } from "../helpers/zod/base_def"

export const breakoutheaders_def = base_def.extend({
Expand Down
14 changes: 10 additions & 4 deletions src/fn/dfn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
type SoicInput,
getCcwSoicCoords,
} from "./soic"
import { rectpad } from "src/helpers/rectpad"
import { rectpad } from "../helpers/rectpad"
import { z } from "zod"
import { CORNERS } from "src/helpers/corner"
import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef"
import { CORNERS } from "../helpers/corner"
import { type SilkscreenRef, silkscreenRef } from "../helpers/silkscreenRef"

export const dfn_def = extendSoicDef({})

Expand All @@ -32,7 +32,13 @@ export const dfn = (
widthincludeslegs: true,
})
pads.push(
rectpad(i + 1, x, y, parameters.pl ?? "1mm", parameters.pw ?? "0.6mm"),
rectpad(
i + 1,
x,
y,
Number.parseFloat(parameters.pl ?? "1mm"),
Number.parseFloat(parameters.pw ?? "0.6mm"),
),
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/fn/diode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AnySoupElement } from "circuit-json"
import { passive, type PassiveDef } from "src/helpers/passive-fn"
import { passive, type PassiveDef } from "../helpers/passive-fn"

export const diode = (parameters: {
tht: boolean
Expand Down
6 changes: 3 additions & 3 deletions src/fn/dip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {
PcbFabricationNoteText,
PcbSilkscreenPath,
} from "circuit-json"
import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef"
import { type SilkscreenRef, silkscreenRef } from "../helpers/silkscreenRef"
import { base_def } from "../helpers/zod/base_def"

import { z } from "zod"
Expand All @@ -16,9 +16,9 @@ import type { NowDefined } from "../helpers/zod/now-defined"
function convertMilToMm(value: string | number): number {
if (typeof value === "string") {
if (value.trim().toLowerCase().endsWith("mil")) {
return parseFloat(value) * 0.0254
return Number.parseFloat(value) * 0.0254
}
return parseFloat(value)
return Number.parseFloat(value)
}
return Number(value)
}
Expand Down
2 changes: 1 addition & 1 deletion src/fn/electrolytic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
type PcbSilkscreenPath,
} from "circuit-json"
import { z } from "zod"
import { platedhole } from "src/helpers/platedhole"
import { platedhole } from "../helpers/platedhole"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { base_def } from "../helpers/zod/base_def"

Expand Down
2 changes: 1 addition & 1 deletion src/fn/hc49.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
type PcbSilkscreenPath,
} from "circuit-json"
import { z } from "zod"
import { platedhole } from "src/helpers/platedhole"
import { platedhole } from "../helpers/platedhole"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { base_def } from "../helpers/zod/base_def"

Expand Down
4 changes: 4 additions & 0 deletions src/fn/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export { ms013 } from "./ms013"
export { sot723 } from "./sot723"
export { sod123 } from "./sod123"
export { axial } from "./axial"
export { pdip } from "./pdip"
export { pdip8 } from "./pdip8"
export { radial } from "./radial"
export { pushbutton } from "./pushbutton"
export { stampboard } from "./stampboard"
Expand Down Expand Up @@ -80,3 +82,5 @@ export { sot343 } from "./sot343"
export { m2host } from "./m2host"
export { mountedpcbmodule } from "./mountedpcbmodule"
export { to92l } from "./to92l"
export { spdip } from "./spdip"
export { utdfn } from "./utdfn"
97 changes: 41 additions & 56 deletions src/fn/jst.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,43 @@
import {
length,
type AnySoupElement,
type PcbSilkscreenPath,
} from "circuit-json"
import { z } from "zod"

import { platedHoleWithRectPad } from "src/helpers/platedHoleWithRectPad"
import { rectpad } from "src/helpers/rectpad"
import { length } from "circuit-json"
import type { AnySoupElement, PcbSilkscreenPath } from "circuit-json"
import { platedHoleWithRectPad } from "../helpers/platedHoleWithRectPad"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { base_def } from "../helpers/zod/base_def"

export const jst_def = base_def.extend({
export const jst_def = z.object({
fn: z.string(),
p: length.optional(),
id: length.optional(),
pw: length.optional(),
pl: length.optional(),
w: length.optional(),
h: length.optional(),
sh: z
.boolean()
.optional()
.describe(
'JST SH (Surface-mount) connector family. SH stands for "Super High-density".',
),

ph: z
.boolean()
.optional()
.describe(
'JST PH (Through-hole) connector family. PH stands for "Pin Header".',
),

num_pins: z.number().optional(),
p: z.union([z.string(), z.number()]).optional(),
id: z.union([z.string(), z.number()]).optional(),
pw: z.union([z.string(), z.number()]).optional(),
pl: z.union([z.string(), z.number()]).optional(),
w: z.union([z.string(), z.number()]).optional(),
h: z.union([z.string(), z.number()]).optional(),
sh: z.boolean().optional(),
ph: z.boolean().optional(),
string: z.string().optional(),
})

export type jstDef = z.input<typeof jst_def>
export type jstDef = z.infer<typeof jst_def>

// Variant type
type JstVariant = "ph" | "sh"

const variantDefaults: Record<JstVariant, any> = {
const variantDefaults: Record<
JstVariant,
{ p: number; id: number; pw: number; pl: number; w: number; h: number }
> = {
ph: {
p: length.parse("2.2mm"),
id: length.parse("0.70mm"),
pw: length.parse("1.20mm"),
pl: length.parse("1.20mm"),
pw: length.parse("1.2mm"),
pl: length.parse("1.2mm"),
w: length.parse("6mm"),
h: length.parse("5mm"),
},
sh: {
p: length.parse("1mm"),
id: length.parse("0.70mm"),
pw: length.parse("0.6mm"),
pl: length.parse("1.55mm"),
w: length.parse("5.8mm"),
Expand Down Expand Up @@ -124,15 +111,14 @@ function generateSilkscreenBody(
stroke_width: 0.1,
pcb_silkscreen_path_id: "",
}
} else {
return {
type: "pcb_silkscreen_path",
layer: "top",
pcb_component_id: "",
route: [],
stroke_width: 0.1,
pcb_silkscreen_path_id: "",
}
}
return {
type: "pcb_silkscreen_path",
layer: "top",
pcb_component_id: "",
route: [],
stroke_width: 0.1,
pcb_silkscreen_path_id: "",
}
}

Expand All @@ -143,12 +129,12 @@ export const jst = (
const variant = getVariant(params)
const defaults = variantDefaults[variant]

const p = params.p ?? defaults.p
const id = params.id ?? defaults.id
const pw = params.pw ?? defaults.pw
const pl = params.pl ?? defaults.pl
const w = params.w ?? defaults.w
const h = params.h ?? defaults.h
const p = params.p ? length.parse(params.p) : defaults.p
const id = params.id ? length.parse(params.id) : defaults.id
const pw = params.pw ? length.parse(params.pw) : defaults.pw
const pl = params.pl ? length.parse(params.pl) : defaults.pl
const w = params.w ? length.parse(params.w) : defaults.w
const h = params.h ? length.parse(params.h) : defaults.h

let numPins: number | undefined

Expand All @@ -158,12 +144,11 @@ export const jst = (
}

const str = typeof raw_params.string === "string" ? raw_params.string : ""
const match = str.match(/(?:^|_)jst(\d+)(?:_|$)/)
if (match && match[1]) {
const parsed = parseInt(match[1], 10)
if (!Number.isNaN(parsed)) {
numPins = parsed
}

// Robust parsing: find any sequence of digits after 'jst' or variant prefix
const jstMatch = str.match(/jst.*(\d+)/i)
if (jstMatch?.[1]) {
numPins = Number.parseInt(jstMatch[1], 10)
}

if (typeof numPins !== "number") {
Expand Down
8 changes: 4 additions & 4 deletions src/fn/m2host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ export const m2host = (
// const silkscreenRefText: SilkscreenRef = silkscreenRef(0, padLength, 0.5)

// --- center footprint around (0,0) ---
let minX = Infinity
let maxX = -Infinity
let minY = Infinity
let maxY = -Infinity
let minX = Number.POSITIVE_INFINITY
let maxX = Number.NEGATIVE_INFINITY
let minY = Number.POSITIVE_INFINITY
let maxY = Number.NEGATIVE_INFINITY

const updateBounds = (x: number, y: number, w = 0, h = 0) => {
minX = Math.min(minX, x - w / 2)
Expand Down
2 changes: 1 addition & 1 deletion src/fn/melf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AnySoupElement, PcbSilkscreenPath } from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { length } from "circuit-json"
import { base_def } from "../helpers/zod/base_def"

Expand Down
2 changes: 1 addition & 1 deletion src/fn/micromelf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AnySoupElement, PcbSilkscreenPath } from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { length } from "circuit-json"
import { base_def } from "../helpers/zod/base_def"

Expand Down
2 changes: 1 addition & 1 deletion src/fn/minimelf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AnySoupElement, PcbSilkscreenPath } from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { length } from "circuit-json"
import { base_def } from "../helpers/zod/base_def"

Expand Down
6 changes: 3 additions & 3 deletions src/fn/mountedpcbmodule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type AnyCircuitElement, length } from "circuit-json"
import { determinePinlabelAnchorSide } from "src/helpers/determine-pin-label-anchor-side"
import { silkscreenPin } from "src/helpers/silkscreenPin"
import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef"
import { determinePinlabelAnchorSide } from "../helpers/determine-pin-label-anchor-side"
import { silkscreenPin } from "../helpers/silkscreenPin"
import { type SilkscreenRef, silkscreenRef } from "../helpers/silkscreenRef"
import { z } from "zod"
import { platedHoleWithRectPad } from "../helpers/platedHoleWithRectPad"
import { platedhole } from "../helpers/platedhole"
Expand Down
2 changes: 1 addition & 1 deletion src/fn/msop.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AnyCircuitElement, PcbSilkscreenPath } from "circuit-json"
import { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef"
import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef"
import { length } from "circuit-json"
import { base_def } from "../helpers/zod/base_def"

Expand Down
2 changes: 1 addition & 1 deletion src/fn/pad.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { z } from "zod"
import type { z } from "zod"
import { rectpad } from "../helpers/rectpad"
import { silkscreenRef } from "../helpers/silkscreenRef"
import type { AnySoupElement } from "circuit-json"
Expand Down
12 changes: 12 additions & 0 deletions src/fn/pdip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { dip, dip_def, extendDipDef } from "./dip"

export const pdip_def = extendDipDef({ w: "300mil", p: "2.54mm" })

export const pdip = (raw_params: any) => {
const parameters = pdip_def.parse(raw_params)
return dip({
...parameters,
num_pins: raw_params.num_pins ?? 8,
dip: true,
} as any)
}
Loading