diff --git a/lib/components/base-components/NormalComponent/NormalComponent.ts b/lib/components/base-components/NormalComponent/NormalComponent.ts index 9cbc5d770..92b756dd0 100644 --- a/lib/components/base-components/NormalComponent/NormalComponent.ts +++ b/lib/components/base-components/NormalComponent/NormalComponent.ts @@ -799,8 +799,7 @@ export class NormalComponent< ? { kicad_footprint: props.kicadFootprintMetadata } : undefined, }) - - const footprint = props.footprint ?? this._getImpliedFootprintString() + const footprint = this.getFootprinterString() // Check if we have a Footprint child (e.g., from inflated circuit JSON) const hasFootprintChild = this.children.some( @@ -1389,8 +1388,11 @@ export class NormalComponent< } getFootprinterString(): string | null { - if (typeof this._parsedProps.footprint === "string") { - return this._parsedProps.footprint + const footprint = + this._parsedProps.footprint ?? this._getImpliedFootprintString?.() + if (typeof footprint === "string") { + const libRef = parseLibraryFootprintRef(footprint) + return libRef ? libRef.footprintName : footprint } return null } @@ -1403,8 +1405,7 @@ export class NormalComponent< const cadModelProp = this._parsedProps.cadModel const cadModel = cadModelProp === undefined ? this._asyncFootprintCadModel : cadModelProp - const footprint = - this.getFootprinterString() ?? this._getImpliedFootprintString() + const footprint = this.getFootprinterString() if (!this.pcb_component_id) return if (!cadModel && !footprint) return @@ -1622,10 +1623,8 @@ export class NormalComponent< if (!source_component) return if (source_component.supplier_part_numbers) return - let footprinterString: string | undefined - if (this.props.footprint && typeof this.props.footprint === "string") { - footprinterString = this.props.footprint - } + let footprinterString: string | undefined = + this.getFootprinterString() ?? undefined const supplierPartNumbersMaybePromise = this._getSupplierPartNumbers( partsEngine, diff --git a/lib/components/normal-components/Chip.ts b/lib/components/normal-components/Chip.ts index 182bddfe0..6ff32b352 100644 --- a/lib/components/normal-components/Chip.ts +++ b/lib/components/normal-components/Chip.ts @@ -102,7 +102,7 @@ export class Chip extends NormalComponent< const { _parsedProps: props } = this const { pcbX, pcbY } = this.getResolvedPcbPositionProp() - const footprint = props.footprint ?? this._getImpliedFootprintString() + const footprint = this.getFootprinterString() const hasFootprintChild = this.children.some( (c) => c.componentName === "Footprint", ) diff --git a/tests/features/kicad-prefix-stripping.test.tsx b/tests/features/kicad-prefix-stripping.test.tsx new file mode 100644 index 000000000..afbe7e22a --- /dev/null +++ b/tests/features/kicad-prefix-stripping.test.tsx @@ -0,0 +1,67 @@ +import { expect, test } from "bun:test" +import { getTestFixture } from "tests/fixtures/get-test-fixture" + +test("kicad: prefix is stripped in cad_component but preserved in pcb_component metadata", async () => { + const { circuit } = getTestFixture({ + platform: { + footprintLibraryMap: { + kicad: async (footprintName: string) => { + // Return a minimal footprint + return { + footprintCircuitJson: [ + { + type: "pcb_smtpad", + shape: "rect", + x: 0, + y: 0, + width: 1, + height: 1, + layer: "top", + port_hints: ["1"], + }, + ], + } + }, + }, + }, + }) + + const footprintName = + "Connector_JST/JST_PH_B2B-PH-SM4-TB_1x02-1MP_P2.00mm_Vertical" + const fullFootprintPath = `kicad:${footprintName}` + + circuit.add( + + + , + ) + + await circuit.renderUntilSettled() + + const circuitJson = circuit.getCircuitJson() + + // 1. Verify no "Invalid footprint function" errors occurred (which would be reported as unknown errors or crashes) + // If it rendered at all, it likely didn't crash on fp.string() + + // 2. Check pcb_component + const pcbComponent = circuitJson.find( + (el) => el.type === "pcb_component", + ) as any + expect(pcbComponent).toBeDefined() + // Metadata should still have the prefix if it was passed via props (or however it's handled) + // Actually, let's check what we implemented. We didn't change metadata insertion. + + // 3. Check cad_component - THIS IS THE CRITICAL PART + const cadComponent = circuitJson.find( + (el) => el.type === "cad_component", + ) as any + expect(cadComponent).toBeDefined() + expect(cadComponent.footprinter_string).toBe(footprintName) + expect(cadComponent.footprinter_string).not.toContain("kicad:") + + // 4. Check for any load errors + const loadErrors = circuitJson.filter( + (el) => el.type === "external_footprint_load_error", + ) + expect(loadErrors).toHaveLength(0) +})