@snaptrude/plugin-core 1.0.2-plainpoint-20261026.2 → 1.0.2

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.
Files changed (103) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/api-manifest.json +60 -0
  4. package/dist/api/core/camera/index.d.ts +4 -12
  5. package/dist/api/core/camera/index.d.ts.map +1 -1
  6. package/dist/api/core/comment/index.d.ts +3 -7
  7. package/dist/api/core/comment/index.d.ts.map +1 -1
  8. package/dist/api/core/geom/create/index.d.ts +21 -69
  9. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  10. package/dist/api/core/geom/query/circle.d.ts +11 -31
  11. package/dist/api/core/geom/query/circle.d.ts.map +1 -1
  12. package/dist/api/core/geom/query/contour.d.ts +7 -19
  13. package/dist/api/core/geom/query/contour.d.ts.map +1 -1
  14. package/dist/api/core/geom/query/curve.d.ts +24 -72
  15. package/dist/api/core/geom/query/curve.d.ts.map +1 -1
  16. package/dist/api/core/geom/query/profile.d.ts +7 -19
  17. package/dist/api/core/geom/query/profile.d.ts.map +1 -1
  18. package/dist/api/core/geom/update/contour.d.ts +12 -36
  19. package/dist/api/core/geom/update/contour.d.ts.map +1 -1
  20. package/dist/api/core/geom/update/curve.d.ts +5 -13
  21. package/dist/api/core/geom/update/curve.d.ts.map +1 -1
  22. package/dist/api/core/geom/update/profile.d.ts +12 -36
  23. package/dist/api/core/geom/update/profile.d.ts.map +1 -1
  24. package/dist/api/core/io/import/index.d.ts +3 -7
  25. package/dist/api/core/io/import/index.d.ts.map +1 -1
  26. package/dist/api/core/math/quat.d.ts +2 -2
  27. package/dist/api/core/math/quat.d.ts.map +1 -1
  28. package/dist/api/core/math/vec3.d.ts +15 -15
  29. package/dist/api/core/math/vec3.d.ts.map +1 -1
  30. package/dist/api/design/boolean/index.d.ts +4 -20
  31. package/dist/api/design/boolean/index.d.ts.map +1 -1
  32. package/dist/api/design/create/bulk-items.d.ts +4 -20
  33. package/dist/api/design/create/bulk-items.d.ts.map +1 -1
  34. package/dist/api/design/create/index.d.ts +27 -67
  35. package/dist/api/design/create/index.d.ts.map +1 -1
  36. package/dist/api/design/delete/index.d.ts +7 -14
  37. package/dist/api/design/delete/index.d.ts.map +1 -1
  38. package/dist/api/design/dimensions.d.ts +4 -12
  39. package/dist/api/design/dimensions.d.ts.map +1 -1
  40. package/dist/api/design/edit/index.d.ts +3 -7
  41. package/dist/api/design/edit/index.d.ts.map +1 -1
  42. package/dist/api/design/erase/index.d.ts +2 -10
  43. package/dist/api/design/erase/index.d.ts.map +1 -1
  44. package/dist/api/design/family.d.ts +1 -5
  45. package/dist/api/design/family.d.ts.map +1 -1
  46. package/dist/api/design/index.d.ts +5 -0
  47. package/dist/api/design/index.d.ts.map +1 -1
  48. package/dist/api/design/lock.d.ts +0 -3
  49. package/dist/api/design/lock.d.ts.map +1 -1
  50. package/dist/api/design/text.d.ts +400 -0
  51. package/dist/api/design/text.d.ts.map +1 -0
  52. package/dist/api/design/transform/index.d.ts +8 -28
  53. package/dist/api/design/transform/index.d.ts.map +1 -1
  54. package/dist/api/entity/space.d.ts +6 -30
  55. package/dist/api/entity/space.d.ts.map +1 -1
  56. package/dist/api/presentation/drawings.d.ts +46 -1
  57. package/dist/api/presentation/drawings.d.ts.map +1 -1
  58. package/dist/api/presentation/graphics.d.ts +4 -0
  59. package/dist/api/presentation/graphics.d.ts.map +1 -1
  60. package/dist/api/presentation/placedViews.d.ts +29 -1
  61. package/dist/api/presentation/placedViews.d.ts.map +1 -1
  62. package/dist/api/presentation/standards.d.ts +14 -0
  63. package/dist/api/presentation/standards.d.ts.map +1 -1
  64. package/dist/handles.d.ts +0 -8
  65. package/dist/handles.d.ts.map +1 -1
  66. package/dist/index.cjs +2281 -2188
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.js +2269 -2187
  69. package/dist/index.js.map +1 -1
  70. package/package.json +13 -13
  71. package/src/api/core/camera/index.ts +5 -5
  72. package/src/api/core/comment/index.ts +3 -3
  73. package/src/api/core/geom/create/index.ts +25 -25
  74. package/src/api/core/geom/query/circle.ts +11 -11
  75. package/src/api/core/geom/query/contour.ts +6 -7
  76. package/src/api/core/geom/query/curve.ts +25 -25
  77. package/src/api/core/geom/query/profile.ts +6 -7
  78. package/src/api/core/geom/update/contour.ts +11 -12
  79. package/src/api/core/geom/update/curve.ts +5 -5
  80. package/src/api/core/geom/update/profile.ts +11 -12
  81. package/src/api/core/io/import/index.ts +2 -3
  82. package/src/api/core/math/quat.ts +2 -2
  83. package/src/api/core/math/vec3.ts +16 -16
  84. package/src/api/design/boolean/index.ts +2 -2
  85. package/src/api/design/create/bulk-items.ts +2 -3
  86. package/src/api/design/create/index.ts +26 -27
  87. package/src/api/design/delete/index.ts +7 -14
  88. package/src/api/design/dimensions.ts +4 -5
  89. package/src/api/design/edit/index.ts +3 -3
  90. package/src/api/design/erase/index.ts +2 -2
  91. package/src/api/design/family.ts +1 -2
  92. package/src/api/design/index.ts +5 -0
  93. package/src/api/design/lock.ts +0 -6
  94. package/src/api/design/text.ts +394 -0
  95. package/src/api/design/transform/index.ts +7 -15
  96. package/src/api/entity/space.ts +4 -5
  97. package/src/api/presentation/graphics.ts +4 -1
  98. package/src/api/presentation/placedViews.ts +12 -0
  99. package/src/api/presentation/standards.ts +6 -0
  100. package/src/handles.ts +0 -11
  101. package/test/designText.test.mjs +72 -0
  102. package/test/paperPensContract.test.mjs +39 -0
  103. package/test/handles.test.mjs +0 -36
@@ -820,6 +820,8 @@ export const PluginViewSettingCategory = z.enum([
820
820
  "Reference Line",
821
821
  "Adjacency Line",
822
822
  "Landscape elements",
823
+ "Text",
824
+ "Annotation",
823
825
  ])
824
826
  export type PluginViewSettingCategory = z.infer<
825
827
  typeof PluginViewSettingCategory
@@ -864,6 +866,10 @@ export type PluginViewLineStyle = z.infer<typeof PluginViewLineStyle>
864
866
  * | `viewStyle` | `"NONE" \| "FILLET" \| "BUBBLE"`? | Shape restyle: block / rounded corner / bubble |
865
867
  * | `radius` | `number`? | Corner radius for `FILLET` (feet) |
866
868
  * | `inset` | `number`? | Shape inset/offset |
869
+ * | `textColor` | `string`? | Dimension / Text / Annotation: `#rrggbb`, or `inherit` (each text keeps its own) |
870
+ * | `textFontFamily` | `string`? | Text / Annotation: one font family for every text, or `inherit` |
871
+ * | `textFontStyle` | `"inherit" \| "Regular" \| "Bold" \| "Italic" \| "Bold Italic"`? | Text / Annotation: one font style, or `inherit` (a family without it draws Regular) |
872
+ * | `leaderVisible` | `boolean`? | Annotation: draw the leaders (line, landing, arrowhead) |
867
873
  */
868
874
  export const PluginPlacedViewStylePatch = z
869
875
  .object({
@@ -921,6 +927,12 @@ export const PluginPlacedViewStylePatch = z
921
927
  .regex(/^#[0-9a-fA-F]{6}$/)
922
928
  .optional(),
923
929
  textMaskPadding: z.number().finite().min(0).max(5).optional(),
930
+ // Text and Annotation rows: one font for every authored text, or `inherit`.
931
+ textFontFamily: z.string().trim().min(1).optional(),
932
+ textFontStyle: z
933
+ .enum(["inherit", "Regular", "Bold", "Italic", "Bold Italic"])
934
+ .optional(),
935
+ leaderVisible: z.boolean().optional(),
924
936
  })
925
937
  .strict()
926
938
  .refine((p) => Object.keys(p).length > 0, {
@@ -82,6 +82,7 @@ const StoredText = z
82
82
  })
83
83
  .strict()
84
84
  .optional(),
85
+ Text: z.object({ textMm: TextSize.optional() }).strict().optional(),
85
86
  })
86
87
  .strict()
87
88
  const StoredDimension = z
@@ -226,6 +227,10 @@ export const PluginGraphicStandardPatch = z
226
227
  })
227
228
  .strict()
228
229
  .optional(),
230
+ Text: z
231
+ .object({ textMm: TextSize.nullable().optional() })
232
+ .strict()
233
+ .optional(),
229
234
  })
230
235
  .strict()
231
236
  .optional(),
@@ -329,6 +334,7 @@ export const PluginResolvedGraphicStandard = z.object({
329
334
  gridBubbleRadiusMm: HeadRadius,
330
335
  sectionTextMm: TextSize,
331
336
  sectionHeadRadiusMm: HeadRadius,
337
+ annotationMm: TextSize,
332
338
  }),
333
339
  dimension: z.object({
334
340
  tickMm: TickLength,
package/src/handles.ts CHANGED
@@ -288,17 +288,6 @@ export const EdgeHandle = handleSchema("edge")
288
288
  export const HalfEdgeHandle = handleSchema("halfedge")
289
289
  export const VertexHandle = handleSchema("vertex")
290
290
  export const Vec3Components = z.object({ x: z.number(), y: z.number(), z: z.number() })
291
- /**
292
- * A vec3 ARGUMENT: a {@linkcode Vec3Handle} in any inbound form, or a plain finite
293
- * `{ x, y, z }` point. Geometry reads return plain points, and callers pass them straight
294
- * back where a vec3 is expected; the host resolves the point as a vector. Returns stay
295
- * {@linkcode Vec3Handle}. Explicitly typed to keep handles.d.ts inside its size budget.
296
- */
297
- export type Vec3Input = Handle<"vec3"> | Vec3Components
298
- export const Vec3Input: z.ZodUnion<readonly [typeof Vec3Handle, typeof Vec3Components]> = z.union(
299
- [Vec3Handle, Vec3Components],
300
- { error: 'expected a "vec3" handle or a plain { x, y, z } point' }
301
- )
302
291
  export const QuatComponents = z.object({
303
292
  x: z.number(),
304
293
  y: z.number(),
@@ -0,0 +1,72 @@
1
+ // The design.text argument contract, checked before transport.
2
+ // Run: node --test test/
3
+ // Imports the BUILT package (dist) — run `pnpm build` first.
4
+ import test from "node:test"
5
+ import assert from "node:assert/strict"
6
+ import {
7
+ PluginDesignTextCreateArgs,
8
+ PluginDesignTextUpdateArgs,
9
+ PluginTextPatch,
10
+ } from "../dist/index.js"
11
+
12
+ const position = "vec3_position"
13
+
14
+ test("create takes one non-blank line of words", () => {
15
+ assert.equal(
16
+ PluginDesignTextCreateArgs.safeParse({ position, content: "LIVING" })
17
+ .success,
18
+ true,
19
+ )
20
+ for (const content of ["", " ", "two\nlines", "two\r\nlines"])
21
+ assert.equal(
22
+ PluginDesignTextCreateArgs.safeParse({ position, content }).success,
23
+ false,
24
+ JSON.stringify(content),
25
+ )
26
+ })
27
+
28
+ test("create takes a #rrggbb colour and a vec3 handle for the arrowhead", () => {
29
+ const ok = {
30
+ position,
31
+ content: "Shear wall",
32
+ color: "#c62828",
33
+ arrowhead: "vec3_head",
34
+ }
35
+ assert.equal(PluginDesignTextCreateArgs.safeParse(ok).success, true)
36
+ for (const color of ["red", "#12345", "c62828"])
37
+ assert.equal(
38
+ PluginDesignTextCreateArgs.safeParse({ ...ok, color }).success,
39
+ false,
40
+ color,
41
+ )
42
+ for (const arrowhead of [{ x: 1, y: 0, z: 2 }, "component_1", "quat_1"])
43
+ assert.equal(
44
+ PluginDesignTextCreateArgs.safeParse({ ...ok, arrowhead }).success,
45
+ false,
46
+ JSON.stringify(arrowhead),
47
+ )
48
+ })
49
+
50
+ test("an update patch sets at least one known field", () => {
51
+ assert.deepEqual(PluginTextPatch.parse({ fontStyle: "Bold" }), {
52
+ fontStyle: "Bold",
53
+ })
54
+ for (const patch of [
55
+ {},
56
+ { size: 3 },
57
+ { content: "Fire exit", rotation: 90 },
58
+ { content: " " },
59
+ ])
60
+ assert.equal(
61
+ PluginTextPatch.safeParse(patch).success,
62
+ false,
63
+ JSON.stringify(patch),
64
+ )
65
+ assert.equal(
66
+ PluginDesignTextUpdateArgs.safeParse({
67
+ texts: [],
68
+ patch: { color: "#1565c0" },
69
+ }).success,
70
+ false,
71
+ )
72
+ })
@@ -2,7 +2,10 @@ import { test } from "node:test"
2
2
  import assert from "node:assert/strict"
3
3
  import {
4
4
  PluginGraphicStandardPatch,
5
+ PluginGraphicsAnnotationCategory,
6
+ PluginGraphicsOverrideCategory,
5
7
  PluginGraphicsOverrides,
8
+ PluginResolvedGraphicStandard,
6
9
  PluginGraphicsSetScaleArgs,
7
10
  PluginDesignCreateReferenceLinesArgs,
8
11
  PluginReferenceLineOptions,
@@ -36,6 +39,42 @@ test("Paper Pens rejects ambiguous, ineffective and stock-writing edits before t
36
39
  assert.deepEqual(PluginGraphicStandardPatch.parse(patch), patch)
37
40
  })
38
41
 
42
+ test("Text is an annotation category with a projection pen and a size, but no view override", () => {
43
+ assert.equal(PluginGraphicsAnnotationCategory.safeParse("Text").success, true)
44
+ assert.equal(PluginGraphicsOverrideCategory.safeParse("Text").success, false)
45
+ assert.equal(
46
+ PluginGraphicsOverrides.safeParse({ Text: { hidden: true } }).success,
47
+ false,
48
+ )
49
+ for (const patch of [
50
+ { annotationText: { Text: { textMm: 3.5 } } },
51
+ { annotationText: { Text: { textMm: null } } },
52
+ { objectStyles: { Text: { projection: 2 } } },
53
+ ])
54
+ assert.deepEqual(PluginGraphicStandardPatch.parse(patch), patch)
55
+ for (const patch of [
56
+ { annotationText: { Text: { textMm: 0 } } },
57
+ { annotationText: { Text: { sizeMm: 3 } } },
58
+ { objectStyles: { Text: { cut: 2 } } },
59
+ ])
60
+ assert.equal(PluginGraphicStandardPatch.safeParse(patch).success, false)
61
+ const text = {
62
+ nameMm: 3,
63
+ areaMm: 2.5,
64
+ dimensionMm: 2.5,
65
+ gridTextMm: 3.5,
66
+ gridBubbleRadiusMm: 5,
67
+ sectionTextMm: 3,
68
+ sectionHeadRadiusMm: 6,
69
+ }
70
+ const resolvedText = PluginResolvedGraphicStandard.shape.text
71
+ assert.equal(resolvedText.safeParse(text).success, false)
72
+ assert.equal(
73
+ resolvedText.safeParse({ ...text, annotationMm: 2.5 }).success,
74
+ true,
75
+ )
76
+ })
77
+
39
78
  test("explicit reference styles cannot conflict with legacy fields or mixed call forms", () => {
40
79
  assert.equal(
41
80
  PluginReferenceLineOptions.safeParse({ styleId: "wide", thickness: 3 })
@@ -1,36 +0,0 @@
1
- // Node built-in test runner suite for the handle schemas.
2
- // Imports the BUILT package (dist) — run `pnpm build` first.
3
- import test from "node:test"
4
- import assert from "node:assert/strict"
5
- import { Vec3Handle, Vec3Input, Handle, PluginDesignMoveArgs } from "../dist/index.js"
6
-
7
- test("a vec3 handle parses in every inbound form, and only as a handle", () => {
8
- for (const v of ["vec3_abc", new Handle("vec3_abc"), { __h: "vec3_abc" }, { id: "vec3_abc" }]) {
9
- const out = Vec3Handle.parse(v)
10
- assert.ok(out instanceof Handle)
11
- assert.equal(out.id, "vec3_abc")
12
- }
13
- assert.equal(Vec3Handle.safeParse({ x: 1, y: 2, z: 3 }).success, false)
14
- const bad = Vec3Handle.safeParse("profile_1")
15
- assert.equal(bad.success, false)
16
- assert.match(bad.error.issues[0].message, /expected a "vec3" handle/)
17
- })
18
-
19
- test("Vec3Input takes a handle or a plain { x, y, z } point", () => {
20
- // Geometry reads return plain points; agents pass them back where a vec3 belongs.
21
- const point = { x: 1, y: 2.5, z: -3 }
22
- assert.deepEqual(Vec3Input.parse(point), point)
23
- assert.ok(Vec3Input.parse("vec3_abc") instanceof Handle)
24
- const args = PluginDesignMoveArgs.parse({ components: ["wl_1"], displacement: { x: 0, y: 0, z: 10 } })
25
- assert.deepEqual(args.displacement, { x: 0, y: 0, z: 10 })
26
- const handled = PluginDesignMoveArgs.parse({ components: ["wl_1"], displacement: "vec3_d" })
27
- assert.equal(handled.displacement.id, "vec3_d")
28
- })
29
-
30
- test("Vec3Input still rejects non-points and wrong handles, with one message", () => {
31
- for (const v of [{ x: 1, y: 2 }, { x: 1, y: Number.NaN, z: 3 }, { x: "1", y: 2, z: 3 }, "profile_1", null, 42]) {
32
- const r = Vec3Input.safeParse(v)
33
- assert.equal(r.success, false, JSON.stringify(v))
34
- assert.equal(r.error.issues[0].message, 'expected a "vec3" handle or a plain { x, y, z } point')
35
- }
36
- })