diff --git a/lib/common/cadModel.ts b/lib/common/cadModel.ts index 505a5d0..2c60d04 100644 --- a/lib/common/cadModel.ts +++ b/lib/common/cadModel.ts @@ -1,5 +1,6 @@ import { z } from "zod" import { point3 } from "./point3" +import { expectTypesMatch } from "lib/typecheck" export const rotationPoint3 = z.object({ x: z.union([z.number(), z.string()]), @@ -7,21 +8,57 @@ export const rotationPoint3 = z.object({ z: z.union([z.number(), z.string()]), }) +export interface CadModelBase { + rotationOffset?: + | number + | { x: number | string; y: number | string; z: number | string } + positionOffset?: { + x: number | string + y: number | string + z: number | string + } + size?: { x: number | string; y: number | string; z: number | string } +} + export const cadModelBase = z.object({ rotationOffset: z.number().or(rotationPoint3).optional(), positionOffset: point3.optional(), size: point3.optional(), }) +expectTypesMatch>(true) + +export interface CadModelStl extends CadModelBase { + stlUrl: string +} export const cadModelStl = cadModelBase.extend({ stlUrl: z.string(), }) +export interface CadModelObj extends CadModelBase { + objUrl: string + mtlUrl?: string +} export const cadModelObj = cadModelBase.extend({ objUrl: z.string(), mtlUrl: z.string().optional(), }) +export interface CadModelJscad extends CadModelBase { + jscad: Record +} export const cadModelJscad = cadModelBase.extend({ - jscad: z.any(), + jscad: z.record(z.any()), }) + +export type CadModelProp = string | CadModelStl | CadModelObj | CadModelJscad + +export const cadModelProp = z.union([ + z.string(), + cadModelStl, + cadModelObj, + cadModelJscad, +]) + +type InferredCadModelProp = z.input +expectTypesMatch(true) diff --git a/lib/common/layout.ts b/lib/common/layout.ts index 6af98e3..bf961d4 100644 --- a/lib/common/layout.ts +++ b/lib/common/layout.ts @@ -3,12 +3,24 @@ import { type AnySoupElementInput, distance, layer_ref, + type LayerRef, + type LayerRefInput, rotation, supplier_name, } from "@tscircuit/soup" import { point3 } from "./point3" -import { cadModelJscad, cadModelObj, cadModelStl } from "./cadModel" -import { footprintProp } from "./footprintProp" +import { + cadModelJscad, + cadModelObj, + cadModelProp, + cadModelStl, + type CadModelJscad, + type CadModelObj, + type CadModelProp, + type CadModelStl, +} from "./cadModel" +import { footprintProp, type Footprint } from "./footprintProp" +import { expectTypesMatch } from "lib/typecheck" export const pcbLayoutProps = z.object({ pcbX: distance, @@ -17,6 +29,19 @@ export const pcbLayoutProps = z.object({ layer: layer_ref.optional(), }) +export interface CommonLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + + schX?: string | number + schY?: string | number + schRotation?: string | number + + layer?: LayerRefInput + footprint?: Footprint +} + export const commonLayoutProps = z.object({ pcbX: distance.optional(), pcbY: distance.optional(), @@ -27,22 +52,45 @@ export const commonLayoutProps = z.object({ layer: layer_ref.optional(), footprint: footprintProp.optional(), }) -export type CommonLayoutProps = z.input +type InferredCommonLayoutProps = z.input +expectTypesMatch(true) + +export type SupplierName = + | "jlcpcb" + | "macrofab" + | "pcbway" + | "digikey" + | "mouser" + | "lcsc" +export interface SupplierProps { + supplierPartNumbers?: { [k in SupplierName]?: string[] } +} export const supplierProps = z.object({ supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), }) -export type SupplierProps = z.input + +expectTypesMatch>(true) + +export interface CommonComponentProps extends CommonLayoutProps { + name: string + supplierPartNumbers?: SupplierProps["supplierPartNumbers"] + cadModel?: CadModelProp + children?: any + symbolName?: string +} export const commonComponentProps = commonLayoutProps .merge(supplierProps) .extend({ name: z.string(), - cadModel: z.union([cadModelStl, cadModelObj, cadModelJscad]).optional(), + cadModel: cadModelProp.optional(), children: z.any().optional(), symbolName: z.string().optional(), }) -export type CommonComponentProps = z.input + +type InferredCommonComponentProps = z.input +expectTypesMatch(true) export const lrPins = ["pin1", "left", "pin2", "right"] as const export const lrPolarPins = [ diff --git a/lib/common/schematicPinStyle.ts b/lib/common/schematicPinStyle.ts new file mode 100644 index 0000000..396d2ff --- /dev/null +++ b/lib/common/schematicPinStyle.ts @@ -0,0 +1,24 @@ +import { z } from "zod" +import { distance } from "@tscircuit/soup" +import { expectTypesMatch } from "lib/typecheck" + +export type SchematicPinStyle = Record< + string, + { + leftMargin?: number | string + rightMargin?: number | string + topMargin?: number | string + bottomMargin?: number | string + } +> + +export const schematicPinStyle = z.record( + z.object({ + leftMargin: distance.optional(), + rightMargin: distance.optional(), + topMargin: distance.optional(), + bottomMargin: distance.optional(), + }), +) + +expectTypesMatch>(true) diff --git a/lib/components/capacitor.ts b/lib/components/capacitor.ts new file mode 100644 index 0000000..81b366d --- /dev/null +++ b/lib/components/capacitor.ts @@ -0,0 +1,32 @@ +import { z } from "zod" +import { capacitance } from "@tscircuit/soup" +import { + commonComponentProps, + lrPins, + lrPolarPins, + type CommonComponentProps, +} from "lib/common/layout" +import { expectTypesMatch } from "lib/typecheck" + +export interface CapacitorProps extends CommonComponentProps { + capacitance: number | string + + decouplingFor?: string + decouplingTo?: string + + bypassFor?: string + bypassTo?: string +} + +export const capacitorProps = commonComponentProps.extend({ + capacitance, + + decouplingFor: z.string().optional(), + decouplingTo: z.string().optional(), + + bypassFor: z.string().optional(), + bypassTo: z.string().optional(), +}) +export const capacitorPins = lrPolarPins + +expectTypesMatch>(true) diff --git a/lib/components/chip.ts b/lib/components/chip.ts index 5fd7b28..b12ce21 100644 --- a/lib/components/chip.ts +++ b/lib/components/chip.ts @@ -2,22 +2,14 @@ import { z } from "zod" import { distance } from "@tscircuit/soup" import { commonComponentProps } from "lib/common/layout" import { schematicPortArrangement } from "lib/common/schematicPinDefinitions" +import { schematicPinStyle } from "lib/common/schematicPinStyle" export const chipProps = commonComponentProps.extend({ manufacturerPartNumber: z.string().optional(), pinLabels: z.record(z.number().or(z.string()), z.string()).optional(), schPortArrangement: schematicPortArrangement.optional(), - schPinStyle: z - .record( - z.object({ - leftMargin: distance.optional(), - rightMargin: distance.optional(), - topMargin: distance.optional(), - bottomMargin: distance.optional(), - }), - ) - .optional(), + schPinStyle: schematicPinStyle.optional(), schPinSpacing: distance.optional(), schWidth: distance.optional(), schHeight: distance.optional(), diff --git a/lib/components/jumper.ts b/lib/components/jumper.ts new file mode 100644 index 0000000..0287d30 --- /dev/null +++ b/lib/components/jumper.ts @@ -0,0 +1,32 @@ +import { z } from "zod" +import { + commonComponentProps, + type CommonComponentProps, +} from "lib/common/layout" +import { + schematicPinStyle, + type SchematicPinStyle, +} from "lib/common/schematicPinStyle" +import { distance } from "@tscircuit/soup" +import { expectTypesMatch } from "lib/typecheck" + +export interface JumperProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string +} + +export const jumperProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z.record(z.number().or(z.string()), z.string()).optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), +}) + +type InferredJumperProps = z.input +expectTypesMatch(true) diff --git a/lib/components/resistor.ts b/lib/components/resistor.ts new file mode 100644 index 0000000..d4f538f --- /dev/null +++ b/lib/components/resistor.ts @@ -0,0 +1,30 @@ +import { z } from "zod" +import { resistance } from "@tscircuit/soup" +import { + commonComponentProps, + lrPins, + type CommonComponentProps, +} from "lib/common/layout" +import { expectTypesMatch } from "lib/typecheck" + +export interface ResistorProps extends CommonComponentProps { + resistance: number | string + pullupFor?: string + pullupTo?: string + pulldownFor?: string + pulldownTo?: string +} + +export const resistorProps = commonComponentProps.extend({ + resistance, + + pullupFor: z.string().optional(), + pullupTo: z.string().optional(), + + pulldownFor: z.string().optional(), + pulldownTo: z.string().optional(), +}) +export const resistorPins = lrPins + +type InferredResistorProps = z.input +expectTypesMatch(true) diff --git a/lib/index.ts b/lib/index.ts index 0c6c580..b538f42 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -46,23 +46,10 @@ export * from "./common/schematicPinDefinitions" export * from "./components/board" export * from "./components/chip" +export * from "./components/jumper" -export const supplierProps = z.object({ - supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), -}) -export type SupplierProps = z.input - -export const resistorProps = commonComponentProps.extend({ - resistance, -}) -export const resistorPins = lrPins -export type ResistorProps = z.input - -export const capacitorProps = commonComponentProps.extend({ - capacitance, -}) -export const capacitorPins = lrPolarPins -export type CapacitorProps = z.input +export * from "./components/resistor" +export * from "./components/capacitor" export const inductorProps = commonComponentProps.extend({ inductance, diff --git a/lib/typecheck.ts b/lib/typecheck.ts index b6e7e9c..3dac456 100644 --- a/lib/typecheck.ts +++ b/lib/typecheck.ts @@ -1,3 +1,5 @@ -export const expectTypesMatch = ( - shouldBe: T1 extends T2 ? (T2 extends T1 ? true : false) : false, +import type { TypeEqual } from "ts-expect" + +export const expectTypesMatch = ( + shouldBe: TypeEqual, ): void => {} diff --git a/package-lock.json b/package-lock.json index 7a61547..6241fe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tscircuit/props", - "version": "0.0.42", + "version": "0.0.47", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tscircuit/props", - "version": "0.0.42", + "version": "0.0.47", "license": "ISC", "devDependencies": { "@biomejs/biome": "^1.8.3", @@ -19,6 +19,7 @@ "expect-type": "^0.20.0", "madge": "^8.0.0", "react": "^18.3.1", + "ts-expect": "^1.3.0", "tsup": "^8.0.2", "tsx": "^4.10.2", "typescript": "^5.4.5", @@ -5636,6 +5637,13 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-expect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", + "dev": true, + "license": "MIT" + }, "node_modules/ts-graphviz": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-2.1.2.tgz", diff --git a/package.json b/package.json index 8848251..0e9e835 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "expect-type": "^0.20.0", "madge": "^8.0.0", "react": "^18.3.1", + "ts-expect": "^1.3.0", "tsup": "^8.0.2", "tsx": "^4.10.2", "typescript": "^5.4.5",