diff --git a/src/fn/axial.ts b/src/fn/axial.ts index 672adf8..f2b73b9 100644 --- a/src/fn/axial.ts +++ b/src/fn/axial.ts @@ -11,7 +11,7 @@ import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef" export const axial_def = z.object({ fn: z.string(), - num_pins: z.any().transform(() => 2), + num_pins: z.literal(2).default(2), p: length.optional().default("2.54mm"), id: length.optional().default("0.7mm"), od: length.optional().default("1mm"), diff --git a/src/fn/bga.ts b/src/fn/bga.ts index 7ae01af..0fbae44 100644 --- a/src/fn/bga.ts +++ b/src/fn/bga.ts @@ -11,7 +11,7 @@ import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef" export const bga_def = z .object({ fn: z.string(), - num_pins: z.number(), + num_pins: z.number().optional().default(64), grid: dim2d.optional(), p: distance.default("0.8mm"), w: length.optional(), @@ -106,16 +106,6 @@ export const bga = ( missing_pin_nums.push(1) } - if (num_pins_missing !== missing_pin_nums.length) { - throw new Error( - `not able to create bga component, unable to determine missing pins (try specifying them with "missing+1+2+..."\n\n${JSON.stringify( - parameters, - null, - " ", - )}`, - ) - } - const missing_pin_nums_set = new Set(missing_pin_nums) let missing_pins_passed = 0 diff --git a/src/fn/cap.ts b/src/fn/cap.ts index 5d43374..4f182e3 100644 --- a/src/fn/cap.ts +++ b/src/fn/cap.ts @@ -4,6 +4,6 @@ import { type PassiveDef, passive } from "../helpers/passive-fn" export const cap = ( parameters: PassiveDef, -): { circuitJson: AnySoupElement[]; parameters: any } => { +): { circuitJson: AnySoupElement[]; parameters: PassiveDef } => { return { circuitJson: passive(parameters), parameters } } diff --git a/src/fn/diode.ts b/src/fn/diode.ts index dac74f9..46da63d 100644 --- a/src/fn/diode.ts +++ b/src/fn/diode.ts @@ -1,9 +1,9 @@ import type { AnySoupElement } from "@tscircuit/soup" -import { passive } from "src/helpers/passive-fn" +import { passive, type PassiveDef } from "src/helpers/passive-fn" export const diode = (parameters: { tht: boolean p: number -}): { circuitJson: AnySoupElement[]; parameters: any } => { +}): { circuitJson: AnySoupElement[]; parameters: PassiveDef } => { return { circuitJson: passive(parameters), parameters } } diff --git a/src/fn/dip.ts b/src/fn/dip.ts index 6f5d70d..2bc6acc 100644 --- a/src/fn/dip.ts +++ b/src/fn/dip.ts @@ -15,7 +15,7 @@ export const extendDipDef = (newDefaults: { w?: string; p?: string }) => .object({ fn: z.string(), dip: z.literal(true), - num_pins: z.number(), + num_pins: z.number().optional().default(6), wide: z.boolean().optional(), narrow: z.boolean().optional(), w: length.optional(), diff --git a/src/fn/led.ts b/src/fn/led.ts index 0249234..596c8d0 100644 --- a/src/fn/led.ts +++ b/src/fn/led.ts @@ -3,6 +3,6 @@ import { type PassiveDef, passive } from "../helpers/passive-fn" export const led = ( parameters: PassiveDef, -): { circuitJson: AnySoupElement[]; parameters: any } => { +): { circuitJson: AnySoupElement[]; parameters: PassiveDef } => { return { circuitJson: passive(parameters), parameters } } diff --git a/src/fn/pinrow.ts b/src/fn/pinrow.ts index 9dde4a0..e865708 100644 --- a/src/fn/pinrow.ts +++ b/src/fn/pinrow.ts @@ -5,7 +5,7 @@ import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" export const pinrow_def = z.object({ fn: z.string(), - num_pins: z.number(), + num_pins: z.number().optional().default(6), p: length.default("0.1in").describe("pitch"), id: length.default("1.0mm").describe("inner diameter"), od: length.default("1.5mm").describe("outer diameter"), diff --git a/src/fn/pushbutton.ts b/src/fn/pushbutton.ts index d200b9e..b3c7d0d 100644 --- a/src/fn/pushbutton.ts +++ b/src/fn/pushbutton.ts @@ -6,6 +6,10 @@ import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" export const pushbutton_def = z.object({ fn: z.literal("pushbutton"), + w: z.literal(4.5).default(4.5), + h: z.literal(6.5).default(6.5), + id: z.literal(1).default(1), + od: z.literal(1.2).default(1.2), }) export const pushbutton = ( @@ -13,9 +17,9 @@ export const pushbutton = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = pushbutton_def.parse(raw_params) - const width = 4.5 - const height = 6.5 - const holeDiameter = 1 + const width = parameters.w + const height = parameters.h + const holeDiameter = parameters.id const holes: AnyCircuitElement[] = [ platedhole(1, -width / 2, height / 2, holeDiameter, holeDiameter * 1.2), diff --git a/src/fn/quad.ts b/src/fn/quad.ts index 032ebfd..4d7c7d0 100644 --- a/src/fn/quad.ts +++ b/src/fn/quad.ts @@ -1,5 +1,5 @@ import type { AnySoupElement, PcbSilkscreenPath } from "@tscircuit/soup" -import { z } from "zod" +import { optional, z } from "zod" import { length } from "@tscircuit/soup" import type { NowDefined } from "../helpers/zod/now-defined" import { rectpad } from "../helpers/rectpad" @@ -18,7 +18,7 @@ export const base_quad_def = z.object({ .transform((a) => (typeof a === "string" ? a.slice(1, -1).split(",") : a)) .pipe(z.array(pin_order_specifier)) .optional(), - num_pins: z.number(), + num_pins: z.number().optional().default(64), w: length.optional(), h: length.optional(), p: length.default(length.parse("0.5mm")), diff --git a/src/fn/sod123.ts b/src/fn/sod123.ts index 4467cfc..ccf4768 100644 --- a/src/fn/sod123.ts +++ b/src/fn/sod123.ts @@ -6,6 +6,7 @@ import { length } from "circuit-json" export const sod_def = z.object({ fn: z.string(), + num_pins: z.literal(3).default(3), w: z.string().default("2.36mm"), h: z.string().default("1.22mm"), pl: z.string().default("0.9mm"), @@ -19,7 +20,7 @@ export const sod123 = ( const parameters = sod_def.parse(raw_params) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, - Number(parameters.h) / 4 + 0.4, + length.parse(parameters.h) / 4 + 0.4, 0.3, ) @@ -48,14 +49,14 @@ export const getSodCoords = (parameters: { export const sodWithoutParsing = (parameters: z.infer) => { const pads: AnySoupElement[] = [] - for (let i = 0; i < 2; i++) { + for (let i = 1; i <= parameters.num_pins; i++) { const { x, y } = getSodCoords({ - pn: i + 1, + pn: i, pad_spacing: Number.parseFloat(parameters.pad_spacing), }) pads.push( rectpad( - i + 1, + i, x, y, Number.parseFloat(parameters.pl), diff --git a/src/fn/soic.ts b/src/fn/soic.ts index 8b34ed0..83b271f 100644 --- a/src/fn/soic.ts +++ b/src/fn/soic.ts @@ -1,6 +1,6 @@ import type { AnySoupElement, PcbSilkscreenPath } from "@tscircuit/soup" import { platedhole } from "../helpers/platedhole" -import { z, type AnyZodObject } from "zod" +import { z } from "zod" import { length } from "@tscircuit/soup" import type { NowDefined } from "../helpers/zod/now-defined" import { u_curve } from "../helpers/u-curve" @@ -9,12 +9,13 @@ import { silkscreenRef, type SilkscreenRef } from "../helpers/silkscreenRef" export const extendSoicDef = (newDefaults: { w?: string p?: string + num_pins?: number legsoutside?: boolean }) => z .object({ fn: z.string(), - num_pins: z.number(), + num_pins: z.number().optional().default(8), w: length.default(length.parse(newDefaults.w ?? "5.3mm")), p: length.default(length.parse(newDefaults.p ?? "1.27mm")), pw: length.optional(), diff --git a/src/fn/sot23.ts b/src/fn/sot23.ts index 7c0f9d7..37ee913 100644 --- a/src/fn/sot23.ts +++ b/src/fn/sot23.ts @@ -5,7 +5,7 @@ import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" export const sot23_def = z.object({ fn: z.string(), - num_pins: z.number().default(3), + num_pins: z.literal(3).default(3), w: z.string().default("1.92mm"), h: z.string().default("2.74mm"), pl: z.string().default("0.8mm"), @@ -61,6 +61,7 @@ export const sot23WithoutParsing = (parameters: z.infer) => { ), ) } + const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, Number(parameters.h), diff --git a/src/fn/sot235.ts b/src/fn/sot235.ts index daf9a21..3ce7f09 100644 --- a/src/fn/sot235.ts +++ b/src/fn/sot235.ts @@ -2,16 +2,16 @@ 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 { u_curve } from "src/helpers/u-curve" export const sot235_def = z.object({ fn: z.string(), + num_pins: z.literal(5).default(5), h: z.string().default("1.6mm"), pl: z.string().default("1mm"), pw: z.string().default("0.7mm"), p: z.string().default("0.95mm"), }) -const num_pins = 5 + export const sot235 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { @@ -50,7 +50,7 @@ export const sot23_5WithoutParsing = ( parameters: z.infer, ) => { const pads: AnyCircuitElement[] = [] - for (let i = 1; i <= num_pins; i++) { + for (let i = 1; i <= parameters.num_pins; i++) { const { x, y } = getCcwSot235Coords({ h: Number.parseFloat(parameters.h), p: Number.parseFloat(parameters.p), @@ -67,7 +67,8 @@ export const sot23_5WithoutParsing = ( ) } - const width = ((num_pins + 1) / 2) * Number.parseFloat(parameters.p) + const width = + ((parameters.num_pins + 1) / 2) * Number.parseFloat(parameters.p) const height = Number.parseFloat(parameters.h) const silkscreenPath1: PcbSilkscreenPath = { layer: "top", diff --git a/src/fn/sot723.ts b/src/fn/sot723.ts index a37ceeb..3b72864 100644 --- a/src/fn/sot723.ts +++ b/src/fn/sot723.ts @@ -1,11 +1,11 @@ -import type { AnySoupElement } from "@tscircuit/soup" +import { length, type AnySoupElement } from "@tscircuit/soup" import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" export const sot723_def = z.object({ fn: z.string(), - num_pins: z.number().default(3), + num_pins: z.literal(3).default(3), w: z.string().default("1.2mm"), h: z.string().default("1.2mm"), pl: z.string().default("0.3mm"), @@ -18,9 +18,9 @@ export const sot723 = ( const parameters = sot723_def.parse(raw_params) const pad = sot723WithoutParsing(parameters) const silkscreenRefText: SilkscreenRef = silkscreenRef( - 0, - Number(parameters.h), - 0.3, + 0.4, + length.parse(parameters.h), + 0.2, ) return { circuitJson: [...pad, silkscreenRefText as AnySoupElement], diff --git a/src/fn/stampboard.ts b/src/fn/stampboard.ts index 0f0748a..788d568 100644 --- a/src/fn/stampboard.ts +++ b/src/fn/stampboard.ts @@ -12,8 +12,8 @@ import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" export const stampboard_def = z.object({ fn: z.string(), w: length.default("22.58mm"), - left: length.optional(), - right: length.optional(), + left: length.optional().default(20), + right: length.optional().default(20), top: length.optional(), bottom: length.optional(), p: length.default(length.parse("2.54mm")), diff --git a/src/fn/stampreceiver.ts b/src/fn/stampreceiver.ts index b15d932..a5de325 100644 --- a/src/fn/stampreceiver.ts +++ b/src/fn/stampreceiver.ts @@ -12,8 +12,8 @@ import { platedhole } from "src/helpers/platedhole" export const stampreceiver_def = z.object({ fn: z.string(), w: length.default("22.58mm"), - left: length.optional(), - right: length.optional(), + left: length.optional().default(20), + right: length.optional().default(20), top: length.optional(), bottom: length.optional(), p: length.default(length.parse("2.54mm")), diff --git a/src/footprinter.ts b/src/footprinter.ts index df4d560..e87aca0 100644 --- a/src/footprinter.ts +++ b/src/footprinter.ts @@ -22,36 +22,36 @@ type CommonPassiveOptionKey = export type Footprinter = { dip: ( - num_pins: number, + num_pins?: number, ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> cap: () => FootprinterParamsBuilder res: () => FootprinterParamsBuilder diode: () => FootprinterParamsBuilder led: () => FootprinterParamsBuilder - lr: (num_pins: number) => FootprinterParamsBuilder<"w" | "l" | "pl" | "pr"> + lr: (num_pins?: number) => FootprinterParamsBuilder<"w" | "l" | "pl" | "pr"> qfp: ( - num_pins: number, + num_pins?: number, ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> quad: ( - num_pins: number, + num_pins?: number, ) => FootprinterParamsBuilder< "w" | "l" | "square" | "pl" | "pr" | "pb" | "pt" | "p" | "pw" | "ph" > bga: ( - num_pins: number, + num_pins?: number, ) => FootprinterParamsBuilder< "grid" | "p" | "w" | "h" | "ball" | "pad" | "missing" > - qfn: (num_pins: number) => FootprinterParamsBuilder<"w" | "h" | "p"> - soic: (num_pins: number) => FootprinterParamsBuilder<"w" | "p" | "id" | "od"> - mlp: (num_pins: number) => FootprinterParamsBuilder<"w" | "h" | "p"> - ssop: (num_pins: number) => FootprinterParamsBuilder<"w" | "p"> - tssop: (num_pins: number) => FootprinterParamsBuilder<"w" | "p"> - dfn: (num_pins: number) => FootprinterParamsBuilder<"w" | "p"> - pinrow: (num_pins: number) => FootprinterParamsBuilder<"p" | "id" | "od"> + qfn: (num_pins?: number) => FootprinterParamsBuilder<"w" | "h" | "p"> + soic: (num_pins?: number) => FootprinterParamsBuilder<"w" | "p" | "id" | "od"> + mlp: (num_pins?: number) => FootprinterParamsBuilder<"w" | "h" | "p"> + ssop: (num_pins?: number) => FootprinterParamsBuilder<"w" | "p"> + tssop: (num_pins?: number) => FootprinterParamsBuilder<"w" | "p"> + dfn: (num_pins?: number) => FootprinterParamsBuilder<"w" | "p"> + pinrow: (num_pins?: number) => FootprinterParamsBuilder<"p" | "id" | "od"> axial: () => FootprinterParamsBuilder<"p" | "id" | "od"> sot235: () => FootprinterParamsBuilder<"h" | "p" | "pl" | "pw"> - lqfp: (num_pins: number) => FootprinterParamsBuilder<"w" | "h" | "pl" | "pw"> + lqfp: (num_pins?: number) => FootprinterParamsBuilder<"w" | "h" | "pl" | "pw"> pushbutton: () => FootprinterParamsBuilder< "tllabel" | "trlabel" | "bllabel" | "brlabel" > @@ -183,7 +183,9 @@ export const footprinter = (): Footprinter & { target.imperial = v // res0402, cap0603 etc. } } else { - target.num_pins = Number.parseFloat(v) + target.num_pins = Number.isNaN(Number.parseFloat(v)) + ? undefined + : Number.parseFloat(v) } } } else { diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index 19d6a92..8362c3d 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -169,7 +169,7 @@ export const passive = (params: PassiveDef): AnySoupElement[] => { if (pw === undefined) throw new Error("could not infer pad width") if (ph === undefined) throw new Error("could not infer pad width") - const silkscreenRefText: SilkscreenRef = silkscreenRef(0, h / 2, h / 12) + const silkscreenRefText: SilkscreenRef = silkscreenRef(0, 0.9, 0.2) if (tht) { return [ platedhole(1, -p / 2, 0, pw, (pw * 1) / 0.8), diff --git a/tests/__snapshots__/0402.snap.svg b/tests/__snapshots__/0402.snap.svg index 666d007..40009f8 100644 --- a/tests/__snapshots__/0402.snap.svg +++ b/tests/__snapshots__/0402.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/cap footprint.snap.svg b/tests/__snapshots__/cap footprint.snap.svg index 666d007..40009f8 100644 --- a/tests/__snapshots__/cap footprint.snap.svg +++ b/tests/__snapshots__/cap footprint.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/cap_imperial0402.snap.svg b/tests/__snapshots__/cap_imperial0402.snap.svg index 666d007..40009f8 100644 --- a/tests/__snapshots__/cap_imperial0402.snap.svg +++ b/tests/__snapshots__/cap_imperial0402.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode0402.snap.svg b/tests/__snapshots__/diode0402.snap.svg index 666d007..40009f8 100644 --- a/tests/__snapshots__/diode0402.snap.svg +++ b/tests/__snapshots__/diode0402.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/led_hole.snap.svg b/tests/__snapshots__/led_hole.snap.svg index 98868c1..b02642c 100644 --- a/tests/__snapshots__/led_hole.snap.svg +++ b/tests/__snapshots__/led_hole.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/led_rect.snap.svg b/tests/__snapshots__/led_rect.snap.svg index 24a6436..d55e5d8 100644 --- a/tests/__snapshots__/led_rect.snap.svg +++ b/tests/__snapshots__/led_rect.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123.snap.svg b/tests/__snapshots__/sod123.snap.svg index 0be0753..c2a5915 100644 --- a/tests/__snapshots__/sod123.snap.svg +++ b/tests/__snapshots__/sod123.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot723.snap.svg b/tests/__snapshots__/sot723.snap.svg index a43392a..23b81fa 100644 --- a/tests/__snapshots__/sot723.snap.svg +++ b/tests/__snapshots__/sot723.snap.svg @@ -10,4 +10,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - {REF} \ No newline at end of file + {REF} \ No newline at end of file