diff --git a/docs/assembly-cable.md b/docs/assembly-cable.md
index f3a6a49f..6e41452a 100644
--- a/docs/assembly-cable.md
+++ b/docs/assembly-cable.md
@@ -33,3 +33,14 @@ are inferred; there are no corresponding props or aliases.
This is an additive props API and requires no migration. The schema validates
the inputs; endpoint resolution, routing, and rendering require support in core
and the CAD renderer.
+
+## Explicit cable models
+
+Set `model` to use a cable specification instead of inferring it from the endpoints.
+
+```tsx
+
+```
+
+`standard` retains its existing meaning. Omitting `model` preserves endpoint inference.
diff --git a/generated/PROPS_OVERVIEW.md b/generated/PROPS_OVERVIEW.md
index fbafb902..a32c9b0e 100644
--- a/generated/PROPS_OVERVIEW.md
+++ b/generated/PROPS_OVERVIEW.md
@@ -164,6 +164,8 @@ export interface AssemblyCableProps {
to: string
/** Optional USB-C-to-USB-C preset. Omit to infer the cable from its endpoints. */
standard?: AssemblyCableStandard
+ /** Explicit cable model specification. Omit to infer the cable from its endpoints. */
+ model?: string
}
diff --git a/lib/assembly/cable.ts b/lib/assembly/cable.ts
index 8b4e226c..393edddc 100644
--- a/lib/assembly/cable.ts
+++ b/lib/assembly/cable.ts
@@ -12,6 +12,8 @@ export interface AssemblyCableProps {
to: string
/** Optional USB-C-to-USB-C preset. Omit to infer the cable from its endpoints. */
standard?: AssemblyCableStandard
+ /** Explicit cable model specification. Omit to infer the cable from its endpoints. */
+ model?: string
}
export const assemblyCableProps = z.object({
@@ -19,6 +21,7 @@ export const assemblyCableProps = z.object({
from: z.string().trim().min(1),
to: z.string().trim().min(1),
standard: z.literal("usb_c").optional(),
+ model: z.string().trim().min(1).optional(),
})
export type AssemblyCablePropsInput = z.input
diff --git a/tests/assembly-cable.test.ts b/tests/assembly-cable.test.ts
index 0911072d..617d1757 100644
--- a/tests/assembly-cable.test.ts
+++ b/tests/assembly-cable.test.ts
@@ -53,3 +53,17 @@ test("assembly.cable requires an identity and two nonempty endpoint strings", ()
)
}
})
+
+test("assembly.cable accepts an explicit model without changing standard behavior", () => {
+ const input = {
+ name: "C1",
+ from: ".J1",
+ to: ".J2",
+ model: "adaptercable_a(jst_sh_pins4)_b(jst_ph_pins4)",
+ }
+ expect(assemblyCableProps.parse(input)).toEqual(input)
+ for (const model of ["", " ", 4, null])
+ expect(assemblyCableProps.safeParse({ ...input, model }).success).toBe(
+ false,
+ )
+})