@tscircuit/props 0.0.669 → 0.0.671

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,33 @@
1
+ import { url } from "lib/common/url"
1
2
  import { expectTypesMatch } from "lib/typecheck"
2
3
  import { z } from "zod"
3
4
 
4
5
  export interface AssemblyDeviceProps {
5
6
  /** Product-level assembly identity. */
6
7
  name?: string
8
+ /** Imported CAD model URL. Mutually exclusive with cadModel where supported. */
9
+ modelUrl?: string
10
+ /** Modelprinter/footprinter string, trimmed; mutually exclusive with other model sources. */
11
+ model?: string
7
12
  }
8
13
 
9
- export const assemblyDeviceProps = z.object({
10
- name: z.string().optional(),
11
- })
14
+ export const assemblyDeviceProps = z
15
+ .object({
16
+ name: z.string().optional(),
17
+ model: z.string().trim().min(1).optional(),
18
+ modelUrl: url
19
+ .refine((value) => value.trim().length > 0, {
20
+ message: "modelUrl cannot be empty",
21
+ })
22
+ .optional(),
23
+ })
24
+ .refine(
25
+ (device) => device.model === undefined || device.modelUrl === undefined,
26
+ {
27
+ message: "Provide either model or modelUrl, not both",
28
+ path: ["model"],
29
+ },
30
+ )
12
31
 
13
32
  export type AssemblyDevicePropsInput = z.input<typeof assemblyDeviceProps>
14
33
 
@@ -1,3 +1,4 @@
1
+ import { url } from "lib/common/url"
1
2
  import { type Distance, distance } from "lib/common/distance"
2
3
  import { expectTypesMatch } from "lib/typecheck"
3
4
  import { z } from "zod"
@@ -5,6 +6,10 @@ import { z } from "zod"
5
6
  export interface AssemblyScreenProps {
6
7
  /** Stable product-level identity for the screen assembly. */
7
8
  name: string
9
+ /** Imported CAD model URL. Mutually exclusive with cadModel where supported. */
10
+ modelUrl?: string
11
+ /** Modelprinter/footprinter string, trimmed; mutually exclusive with other model sources. */
12
+ model?: string
8
13
  /** Selector for the connector that the screen attaches to. */
9
14
  connectsTo: string
10
15
  /**
@@ -19,7 +24,7 @@ export interface AssemblyScreenProps {
19
24
  height?: Distance
20
25
  /**
21
26
  * Advanced modelprinter string used to render the screen assembly. Required
22
- * when `width` and `height` are omitted.
27
+ * when `width`, `height`, `model`, and `modelUrl` are omitted.
23
28
  */
24
29
  cadModel?: string
25
30
  }
@@ -37,12 +42,35 @@ const positiveDistance = (fieldName: "width" | "height") =>
37
42
  export const assemblyScreenProps = z
38
43
  .object({
39
44
  name: nonemptyString("name"),
45
+ model: z.string().trim().min(1).optional(),
46
+ modelUrl: url
47
+ .refine((value) => value.trim().length > 0, {
48
+ message: "modelUrl cannot be empty",
49
+ })
50
+ .optional(),
40
51
  connectsTo: nonemptyString("connectsTo"),
41
52
  width: positiveDistance("width").optional(),
42
53
  height: positiveDistance("height").optional(),
43
54
  cadModel: nonemptyString("cadModel").optional(),
44
55
  })
45
56
  .superRefine((screen, context) => {
57
+ if (
58
+ screen.model !== undefined &&
59
+ (screen.modelUrl !== undefined || screen.cadModel !== undefined)
60
+ ) {
61
+ context.addIssue({
62
+ code: z.ZodIssueCode.custom,
63
+ message: "Provide only one of model, modelUrl, or cadModel",
64
+ path: ["model"],
65
+ })
66
+ }
67
+ if (screen.modelUrl !== undefined && screen.cadModel !== undefined) {
68
+ context.addIssue({
69
+ code: z.ZodIssueCode.custom,
70
+ message: "Provide either modelUrl or cadModel, not both",
71
+ path: ["modelUrl"],
72
+ })
73
+ }
46
74
  const hasWidth = screen.width !== undefined
47
75
  const hasHeight = screen.height !== undefined
48
76
 
@@ -55,10 +83,15 @@ export const assemblyScreenProps = z
55
83
  return
56
84
  }
57
85
 
58
- if (!hasWidth && screen.cadModel === undefined) {
86
+ if (
87
+ !hasWidth &&
88
+ screen.cadModel === undefined &&
89
+ screen.modelUrl === undefined &&
90
+ screen.model === undefined
91
+ ) {
59
92
  context.addIssue({
60
93
  code: z.ZodIssueCode.custom,
61
- message: "provide either width and height or cadModel",
94
+ message: "provide width and height, model, cadModel, or modelUrl",
62
95
  path: [],
63
96
  })
64
97
  }
@@ -1,3 +1,4 @@
1
+ import { url } from "lib/common/url"
1
2
  import { type CadModelProp, cadModelProp } from "lib/common/cadModel"
2
3
  import { expectTypesMatch } from "lib/typecheck"
3
4
  import type { ReactNode } from "react"
@@ -6,6 +7,10 @@ import { z } from "zod"
6
7
  export interface AssemblySubassemblyProps {
7
8
  /** Stable identity used by selectors from other assembly elements. */
8
9
  name: string
10
+ /** Imported CAD model URL. Mutually exclusive with cadModel where supported. */
11
+ modelUrl?: string
12
+ /** Modelprinter/footprinter string, trimmed; mutually exclusive with other model sources. */
13
+ model?: string
9
14
  /** Human-facing alternate to the stable name. */
10
15
  displayName?: string
11
16
  /** Optional CAD geometry using the existing component cadModel formats. */
@@ -14,14 +19,38 @@ export interface AssemblySubassemblyProps {
14
19
  children?: ReactNode
15
20
  }
16
21
 
17
- export const assemblySubassemblyProps = z.object({
18
- name: z.string().refine((value) => value.trim().length > 0, {
19
- message: "name cannot be empty",
20
- }),
21
- displayName: z.string().optional(),
22
- cadModel: cadModelProp.optional(),
23
- children: z.custom<ReactNode>().optional(),
24
- })
22
+ export const assemblySubassemblyProps = z
23
+ .object({
24
+ name: z.string().refine((value) => value.trim().length > 0, {
25
+ message: "name cannot be empty",
26
+ }),
27
+ displayName: z.string().optional(),
28
+ model: z.string().trim().min(1).optional(),
29
+ modelUrl: url
30
+ .refine((value) => value.trim().length > 0, {
31
+ message: "modelUrl cannot be empty",
32
+ })
33
+ .optional(),
34
+ cadModel: cadModelProp.optional(),
35
+ children: z.custom<ReactNode>().optional(),
36
+ })
37
+ .refine(
38
+ (assembly) =>
39
+ assembly.modelUrl === undefined || assembly.cadModel === undefined,
40
+ {
41
+ message: "Provide either modelUrl or cadModel, not both",
42
+ path: ["modelUrl"],
43
+ },
44
+ )
45
+ .refine(
46
+ (assembly) =>
47
+ assembly.model === undefined ||
48
+ (assembly.modelUrl === undefined && assembly.cadModel === undefined),
49
+ {
50
+ message: "Provide only one of model, modelUrl, or cadModel",
51
+ path: ["model"],
52
+ },
53
+ )
25
54
 
26
55
  export type AssemblySubassemblyPropsInput = z.input<
27
56
  typeof assemblySubassemblyProps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/props",
3
- "version": "0.0.669",
3
+ "version": "0.0.671",
4
4
  "description": "Props for tscircuit builtin component types",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",