From 807040e47498f38e8c7f1df038c2be71af598471 Mon Sep 17 00:00:00 2001 From: singularitycurse26-svg Date: Sun, 19 Jul 2026 03:13:42 -0500 Subject: [PATCH] feat: add pdip footprint (PDIP-8) Add pdip footprint function as alias for dip with PDIP defaults. PDIP (Plastic Dual Inline Package) uses same layout as DIP with standard 300mil width and 2.54mm pitch. Closes #371 /claim #371 --- src/fn/index.ts | 1 + src/fn/pdip.ts | 24 ++++++++++++++++++++++++ src/footprinter.ts | 3 +++ tests/pdip.test.ts | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 src/fn/pdip.ts create mode 100644 tests/pdip.test.ts diff --git a/src/fn/index.ts b/src/fn/index.ts index b5904c5b..2d635853 100644 --- a/src/fn/index.ts +++ b/src/fn/index.ts @@ -84,3 +84,4 @@ export { sot343 } from "./sot343" export { m2host } from "./m2host" export { mountedpcbmodule } from "./mountedpcbmodule" export { to92l } from "./to92l" +export { pdip } from "./pdip" diff --git a/src/fn/pdip.ts b/src/fn/pdip.ts new file mode 100644 index 00000000..ab8a51ce --- /dev/null +++ b/src/fn/pdip.ts @@ -0,0 +1,24 @@ +import { dip, extendDipDef } from "./dip" +import { z } from "zod" + +export const pdip_def = extendDipDef({ w: "300mil", p: "2.54mm" }).extend({ + fn: z.string(), +}) + +export const pdip = (raw_params: { + pdip: true + num_pins: number + w: number + p?: number + id?: string | number + od?: string | number +}) => { + return dip({ + dip: true, + num_pins: raw_params.num_pins, + w: raw_params.w, + p: raw_params.p, + id: raw_params.id, + od: raw_params.od, + }) +} diff --git a/src/footprinter.ts b/src/footprinter.ts index ac09348d..458d2d96 100644 --- a/src/footprinter.ts +++ b/src/footprinter.ts @@ -40,6 +40,9 @@ export type Footprinter = { dip: ( num_pins?: number, ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> + pdip: ( + num_pins?: number, + ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> cap: () => FootprinterParamsBuilder crystal: ( num_pins?: number, diff --git a/tests/pdip.test.ts b/tests/pdip.test.ts new file mode 100644 index 00000000..79824add --- /dev/null +++ b/tests/pdip.test.ts @@ -0,0 +1,35 @@ +import { test, expect } from "bun:test" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import { fp } from "../src/footprinter" +import type { AnyCircuitElement } from "circuit-json" + +test("pdip8", () => { + const circuitJson = fp.string("pdip8").circuitJson() as AnyCircuitElement[] + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "pdip8") +}) + +test("pdip8 matches dip8 with same defaults", () => { + const pdipJson = fp.string("pdip8").json() + const dipJson = fp.string("dip8").json() + + expect(pdipJson.num_pins).toBe(8) + expect(pdipJson.w).toBe(dipJson.w) + expect(pdipJson.p).toBe(dipJson.p) + expect(pdipJson.id).toBe(dipJson.id) + expect(pdipJson.od).toBe(dipJson.od) +}) + +test("pdip8 with custom width", () => { + const circuitJson = fp + .string("pdip8_w7.62mm") + .circuitJson() as AnyCircuitElement[] + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "pdip8_w7.62mm") +}) + +test("pdip14", () => { + const circuitJson = fp.string("pdip14").circuitJson() as AnyCircuitElement[] + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "pdip14") +})