@snaptrude/plugin-core 0.9.16 → 0.9.18-edgesetbacks-20261021.1

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 (221) hide show
  1. package/AGENTS.md +231 -231
  2. package/CHANGELOG.md +408 -402
  3. package/CLAUDE.md +11 -11
  4. package/api-manifest.json +1510 -701
  5. package/dist/api/analysis/daylight.d.ts +5 -5
  6. package/dist/api/analysis/solar.d.ts +2 -2
  7. package/dist/api/core/camera/index.d.ts +29 -0
  8. package/dist/api/core/camera/index.d.ts.map +1 -1
  9. package/dist/api/core/geom/create/index.d.ts +7 -1
  10. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  11. package/dist/api/core/geom/update/contour.d.ts +8 -2
  12. package/dist/api/core/geom/update/contour.d.ts.map +1 -1
  13. package/dist/api/core/storeys/index.d.ts +5 -2
  14. package/dist/api/core/storeys/index.d.ts.map +1 -1
  15. package/dist/api/core/zoom/index.d.ts +13 -0
  16. package/dist/api/core/zoom/index.d.ts.map +1 -1
  17. package/dist/api/design/bim.d.ts +299 -0
  18. package/dist/api/design/bim.d.ts.map +1 -0
  19. package/dist/api/design/boolean/index.d.ts +2 -0
  20. package/dist/api/design/boolean/index.d.ts.map +1 -1
  21. package/dist/api/design/catalog.d.ts +320 -0
  22. package/dist/api/design/catalog.d.ts.map +1 -0
  23. package/dist/api/design/create/bulk-items.d.ts +65 -25
  24. package/dist/api/design/create/bulk-items.d.ts.map +1 -1
  25. package/dist/api/design/create/index.d.ts +299 -100
  26. package/dist/api/design/create/index.d.ts.map +1 -1
  27. package/dist/api/design/create/opening-fields.d.ts +13 -12
  28. package/dist/api/design/create/opening-fields.d.ts.map +1 -1
  29. package/dist/api/design/delete/index.d.ts +1 -0
  30. package/dist/api/design/delete/index.d.ts.map +1 -1
  31. package/dist/api/design/doors/index.d.ts +18 -24
  32. package/dist/api/design/doors/index.d.ts.map +1 -1
  33. package/dist/api/design/family.d.ts +813 -35
  34. package/dist/api/design/family.d.ts.map +1 -1
  35. package/dist/api/design/index.d.ts +16 -0
  36. package/dist/api/design/index.d.ts.map +1 -1
  37. package/dist/api/design/networks.d.ts +1703 -0
  38. package/dist/api/design/networks.d.ts.map +1 -0
  39. package/dist/api/design/query/grids.d.ts +2 -2
  40. package/dist/api/design/query/index.d.ts +42 -32
  41. package/dist/api/design/query/index.d.ts.map +1 -1
  42. package/dist/api/design/selection/index.d.ts +10 -10
  43. package/dist/api/design/types/index.d.ts +40 -24
  44. package/dist/api/design/types/index.d.ts.map +1 -1
  45. package/dist/api/design/update/index.d.ts +111 -6
  46. package/dist/api/design/update/index.d.ts.map +1 -1
  47. package/dist/api/design/windows/index.d.ts +8 -8
  48. package/dist/api/design/windows/index.d.ts.map +1 -1
  49. package/dist/api/entity/buildableEnvelope.d.ts +84 -2
  50. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
  51. package/dist/api/presentation/aiInspiration.d.ts +10 -10
  52. package/dist/api/presentation/annotate.d.ts +38 -22
  53. package/dist/api/presentation/annotate.d.ts.map +1 -1
  54. package/dist/api/presentation/drawingContract.d.ts +32 -0
  55. package/dist/api/presentation/drawingContract.d.ts.map +1 -0
  56. package/dist/api/presentation/drawings.d.ts +3523 -0
  57. package/dist/api/presentation/drawings.d.ts.map +1 -0
  58. package/dist/api/presentation/export.d.ts +23 -5
  59. package/dist/api/presentation/export.d.ts.map +1 -1
  60. package/dist/api/presentation/index.d.ts +41 -12
  61. package/dist/api/presentation/index.d.ts.map +1 -1
  62. package/dist/api/presentation/placedViews.d.ts +106 -6
  63. package/dist/api/presentation/placedViews.d.ts.map +1 -1
  64. package/dist/api/presentation/sections.d.ts +461 -0
  65. package/dist/api/presentation/sections.d.ts.map +1 -0
  66. package/dist/api/presentation/shapes.d.ts +2 -2
  67. package/dist/api/presentation/sheets.d.ts +175 -19
  68. package/dist/api/presentation/sheets.d.ts.map +1 -1
  69. package/dist/api/presentation/viewPresets.d.ts +222 -0
  70. package/dist/api/presentation/viewPresets.d.ts.map +1 -0
  71. package/dist/api/presentation/views.d.ts +141 -8
  72. package/dist/api/presentation/views.d.ts.map +1 -1
  73. package/dist/api/presentation/walkthroughs.d.ts +6 -6
  74. package/dist/errors/codes.d.ts +3 -1
  75. package/dist/errors/codes.d.ts.map +1 -1
  76. package/dist/index.cjs +3883 -2385
  77. package/dist/index.cjs.map +1 -1
  78. package/dist/index.js +3744 -2385
  79. package/dist/index.js.map +1 -1
  80. package/package.json +1 -1
  81. package/scripts/check-dist-fresh.mjs +22 -22
  82. package/scripts/generate-manifest.mjs +243 -238
  83. package/scripts/generate-manifest.test.mjs +303 -303
  84. package/src/api/analysis/daylight.ts +470 -470
  85. package/src/api/analysis/heatmaps.ts +683 -683
  86. package/src/api/analysis/illuminance.ts +155 -155
  87. package/src/api/analysis/index.ts +61 -61
  88. package/src/api/analysis/shadows.ts +183 -183
  89. package/src/api/analysis/solar.ts +237 -237
  90. package/src/api/analysis/sunlightHours.ts +211 -211
  91. package/src/api/analysis/sunpath.ts +83 -83
  92. package/src/api/analysis/weather.ts +179 -179
  93. package/src/api/core/buildings.ts +485 -485
  94. package/src/api/core/camera/index.ts +696 -667
  95. package/src/api/core/comment/index.ts +376 -376
  96. package/src/api/core/geom/create/index.ts +2139 -2133
  97. package/src/api/core/geom/delete/index.ts +84 -84
  98. package/src/api/core/geom/index.ts +35 -35
  99. package/src/api/core/geom/query/arc.ts +169 -169
  100. package/src/api/core/geom/query/brep.ts +621 -621
  101. package/src/api/core/geom/query/circle.ts +404 -404
  102. package/src/api/core/geom/query/contour.ts +540 -540
  103. package/src/api/core/geom/query/curve.ts +1102 -1102
  104. package/src/api/core/geom/query/edge.ts +130 -130
  105. package/src/api/core/geom/query/face.ts +508 -508
  106. package/src/api/core/geom/query/halfedge.ts +210 -210
  107. package/src/api/core/geom/query/index.ts +63 -63
  108. package/src/api/core/geom/query/profile.ts +473 -473
  109. package/src/api/core/geom/query/vertex.ts +205 -205
  110. package/src/api/core/geom/update/contour.ts +323 -317
  111. package/src/api/core/geom/update/curve.ts +209 -209
  112. package/src/api/core/geom/update/index.ts +29 -29
  113. package/src/api/core/geom/update/profile.ts +379 -379
  114. package/src/api/core/groups.ts +521 -521
  115. package/src/api/core/handles/index.ts +234 -234
  116. package/src/api/core/history/index.ts +84 -84
  117. package/src/api/core/index.ts +99 -99
  118. package/src/api/core/io/export/index.ts +126 -126
  119. package/src/api/core/io/import/index.ts +504 -504
  120. package/src/api/core/io/index.ts +42 -42
  121. package/src/api/core/io/job/index.ts +140 -140
  122. package/src/api/core/io/query/index.ts +71 -71
  123. package/src/api/core/io/terrain/index.ts +360 -360
  124. package/src/api/core/io/underlay/index.ts +705 -705
  125. package/src/api/core/layers.ts +540 -540
  126. package/src/api/core/math/index.ts +20 -20
  127. package/src/api/core/math/quat.ts +172 -172
  128. package/src/api/core/math/vec3.ts +179 -179
  129. package/src/api/core/mode/index.ts +108 -108
  130. package/src/api/core/project/index.ts +479 -479
  131. package/src/api/core/proposals/index.ts +570 -570
  132. package/src/api/core/storeys/index.ts +311 -308
  133. package/src/api/core/storeys/layers.ts +339 -339
  134. package/src/api/core/tags.ts +911 -911
  135. package/src/api/core/units/index.ts +164 -164
  136. package/src/api/core/user.ts +46 -46
  137. package/src/api/core/zoom/index.ts +64 -51
  138. package/src/api/design/bim.ts +210 -0
  139. package/src/api/design/boolean/index.ts +181 -179
  140. package/src/api/design/catalog.ts +203 -0
  141. package/src/api/design/create/bulk-items.ts +294 -254
  142. package/src/api/design/create/grids.ts +137 -137
  143. package/src/api/design/create/index.ts +2178 -1980
  144. package/src/api/design/create/opening-fields.ts +40 -37
  145. package/src/api/design/delete/index.ts +75 -74
  146. package/src/api/design/dimensions.ts +453 -453
  147. package/src/api/design/doors/index.ts +516 -500
  148. package/src/api/design/edit/index.ts +54 -54
  149. package/src/api/design/erase/index.ts +151 -151
  150. package/src/api/design/family.ts +1342 -704
  151. package/src/api/design/furniture/index.ts +319 -319
  152. package/src/api/design/grids.ts +237 -237
  153. package/src/api/design/index.ts +304 -274
  154. package/src/api/design/lock.ts +69 -69
  155. package/src/api/design/materials/index.ts +608 -608
  156. package/src/api/design/networks.ts +607 -0
  157. package/src/api/design/query/geometry/index.ts +319 -319
  158. package/src/api/design/query/grids.ts +197 -197
  159. package/src/api/design/query/index.ts +1236 -1226
  160. package/src/api/design/query/referenceLines.ts +52 -52
  161. package/src/api/design/query/spaces.ts +275 -275
  162. package/src/api/design/selection/index.ts +273 -273
  163. package/src/api/design/shared.ts +40 -40
  164. package/src/api/design/transform/index.ts +254 -254
  165. package/src/api/design/types/index.ts +163 -156
  166. package/src/api/design/update/index.ts +1096 -983
  167. package/src/api/design/visibility.ts +143 -143
  168. package/src/api/design/windows/index.ts +351 -333
  169. package/src/api/entity/buildableEnvelope.ts +397 -322
  170. package/src/api/entity/index.ts +30 -30
  171. package/src/api/entity/referenceLine.ts +235 -235
  172. package/src/api/entity/space.ts +612 -612
  173. package/src/api/entity/story.ts +517 -517
  174. package/src/api/index.ts +47 -47
  175. package/src/api/presentation/aiInspiration.ts +1116 -1116
  176. package/src/api/presentation/annotate.ts +417 -385
  177. package/src/api/presentation/camera.ts +289 -289
  178. package/src/api/presentation/diagrams.ts +194 -194
  179. package/src/api/presentation/drawingContract.ts +70 -0
  180. package/src/api/presentation/drawings.ts +1179 -0
  181. package/src/api/presentation/export.ts +134 -108
  182. package/src/api/presentation/import.ts +159 -159
  183. package/src/api/presentation/index.ts +160 -126
  184. package/src/api/presentation/placedViews.ts +1211 -1120
  185. package/src/api/presentation/sections.ts +420 -0
  186. package/src/api/presentation/shapes.ts +274 -274
  187. package/src/api/presentation/sheets.ts +746 -585
  188. package/src/api/presentation/slideshow.ts +134 -134
  189. package/src/api/presentation/tables.ts +84 -84
  190. package/src/api/presentation/viewPresets.ts +241 -0
  191. package/src/api/presentation/views.ts +742 -673
  192. package/src/api/presentation/walkthroughs.ts +1201 -1201
  193. package/src/api/program/adjacency.ts +164 -164
  194. package/src/api/program/areas.ts +408 -408
  195. package/src/api/program/classification.ts +138 -138
  196. package/src/api/program/cores.ts +83 -83
  197. package/src/api/program/departments.ts +517 -517
  198. package/src/api/program/index.ts +73 -73
  199. package/src/api/program/labels.ts +332 -332
  200. package/src/api/program/layout.ts +422 -422
  201. package/src/api/program/metadata.ts +364 -364
  202. package/src/api/program/metrics.ts +120 -120
  203. package/src/api/program/site.ts +748 -748
  204. package/src/api/program/spreadsheet.ts +2698 -2698
  205. package/src/api/workspace/index.ts +612 -612
  206. package/src/errors/codes.ts +143 -136
  207. package/src/errors/envelope.ts +75 -75
  208. package/src/errors/index.ts +21 -21
  209. package/src/errors/plugin-error.ts +134 -134
  210. package/src/handles.ts +297 -297
  211. package/src/host-utils.ts +67 -67
  212. package/src/index.ts +7 -7
  213. package/src/massParameters.ops.ts +246 -246
  214. package/src/massParameters.ts +427 -427
  215. package/src/types.ts +16 -16
  216. package/test/drawingContract.test.mjs +288 -0
  217. package/test/errors.test.mjs +185 -184
  218. package/test/massParameters.test.mjs +952 -952
  219. package/test/presentationViewSettings.test.mjs +85 -0
  220. package/tsconfig.json +22 -22
  221. package/tsup.config.ts +12 -12
@@ -1,274 +1,274 @@
1
- import * as z from "zod"
2
- import { PluginApiReturn } from "../../types"
3
- import {
4
- PluginAnnotateFill,
5
- PluginAnnotateGeoKind,
6
- PluginAnnotateTextColor,
7
- PluginAnnotateTextSize,
8
- } from "./annotate"
9
-
10
- /**
11
- * Presentation shapes — a stable, plugin-owned shape lifecycle on Present-mode
12
- * sheets.
13
- *
14
- * Where {@linkcode PluginPresentationAnnotateApi} is fire-and-forget (every call
15
- * creates a new shape), this namespace keys each shape by a caller-chosen
16
- * string, so rerunning an analysis **updates** its sheet output in place instead
17
- * of duplicating it:
18
- *
19
- * - {@linkcode PluginPresentationShapesApi.upsert} — create or update the shape for a key
20
- * - {@linkcode PluginPresentationShapesApi.remove} — delete the shape for a key
21
- * - {@linkcode PluginPresentationShapesApi.removeAll} — delete every shape owned by the calling plugin
22
- * - {@linkcode PluginPresentationShapesApi.list} — the calling plugin's shapes (key, shapeId, type)
23
- *
24
- * Shape ids are derived deterministically from the plugin id + key, so upserts
25
- * converge across collaborators. Mutations require **Present mode to be open**
26
- * (`list` is a never-throw read); each plugin sees and mutates only its own
27
- * shapes.
28
- *
29
- * Accessed via `snaptrude.presentation.shapes`.
30
- */
31
- export abstract class PluginPresentationShapesApi {
32
- constructor() {}
33
-
34
- /**
35
- * Create or update the shape for a key.
36
- *
37
- * The `shape` spec is a discriminated union over the same four annotation
38
- * kinds as `presentation.annotate` (`text`, `note`, `arrow`, `geo`), with the
39
- * same option shapes. On first call for a key the shape is created on the
40
- * target sheet (`options.sheetId`, default: the first sheet) and nested under
41
- * the sheet frame; on later calls the existing shape is updated in place —
42
- * same shape id, same sheet, one undo step. Positions/bounds are relative to
43
- * the sheet's top-left, in canvas units. Requires Present mode to be open.
44
- *
45
- * @param key - Caller-chosen stable identifier for the shape (per plugin).
46
- * @param shape - The desired shape ({@linkcode PluginPresentationShapeSpec}):
47
- * `{ type: "text" | "note" | "arrow" | "geo", ... }` with the matching
48
- * annotate options. Changing `type` for an existing key replaces the shape
49
- * (same shape id).
50
- * @param options - Optional `sheetId` — the sheet to create the shape on
51
- * (defaults to the first sheet; ignored on update, the shape stays on its
52
- * sheet).
53
- * @returns A {@linkcode PluginPresentationShapesUpsertResult} — the stable
54
- * `shapeId` and `created` (`true` on first upsert, `false` on update).
55
- * @throws If Present mode is not open, the args are invalid, or the sheet id
56
- * is unknown.
57
- *
58
- * @examplePrompt Update the analysis label on the sheet instead of adding another one
59
- * @examplePrompt Rerun the daylight report and refresh its annotations
60
- * @examplePrompt Keep one "FAR: 2.4" text on Sheet 1 that updates on each run
61
- * @examplePrompt Draw a highlight rectangle the plugin can move on the next run
62
- *
63
- * # Example
64
- * ```ts
65
- * const { shapeId, created } = await snaptrude.presentation.shapes.upsert("far-label", {
66
- * type: "text",
67
- * text: "FAR: 2.4",
68
- * position: { x: 40, y: 40 },
69
- * color: "blue",
70
- * })
71
- * ```
72
- */
73
- public abstract upsert(
74
- key: string,
75
- shape: PluginPresentationShapeSpec,
76
- options?: { sheetId?: string },
77
- ): PluginApiReturn<PluginPresentationShapesUpsertResult>
78
-
79
- /**
80
- * Delete the shape for a key.
81
- *
82
- * Removes the calling plugin's shape registered under `key`, if it exists.
83
- * Requires Present mode to be open.
84
- *
85
- * @param key - The key passed to {@linkcode PluginPresentationShapesApi.upsert}.
86
- * @returns `true` if a shape was deleted, `false` if no shape exists for the
87
- * key.
88
- * @throws If Present mode is not open or the key is invalid.
89
- *
90
- * @examplePrompt Remove the FAR label from the sheet
91
- * @examplePrompt Delete the highlight the plugin added earlier
92
- * @examplePrompt Clear the "far-label" annotation
93
- *
94
- * # Example
95
- * ```ts
96
- * const removed = await snaptrude.presentation.shapes.remove("far-label")
97
- * ```
98
- */
99
- public abstract remove(key: string): PluginApiReturn<boolean>
100
-
101
- /**
102
- * Delete every shape owned by the calling plugin.
103
- *
104
- * Removes all shapes the calling plugin has upserted (across all sheets) in
105
- * one undo step. Requires Present mode to be open.
106
- *
107
- * @returns The number of shapes deleted.
108
- * @throws If Present mode is not open.
109
- *
110
- * @examplePrompt Clear all annotations my plugin added
111
- * @examplePrompt Reset the sheet output before rerunning the analysis
112
- * @examplePrompt Remove every plugin-drawn shape
113
- *
114
- * # Example
115
- * ```ts
116
- * const deleted = await snaptrude.presentation.shapes.removeAll()
117
- * ```
118
- */
119
- public abstract removeAll(): PluginApiReturn<number>
120
-
121
- /**
122
- * List the calling plugin's shapes.
123
- *
124
- * Returns one entry per live shape the calling plugin has upserted — its
125
- * `key`, the underlying canvas `shapeId`, and the shape `type`. A never-throw
126
- * read: returns an empty list when Present mode is closed.
127
- *
128
- * @returns A {@linkcode PluginPresentationShapesListResult} with the `shapes`
129
- * array (empty when Present mode is closed).
130
- *
131
- * @examplePrompt Which annotations has my plugin placed on the sheets?
132
- * @examplePrompt List the plugin's shapes before refreshing them
133
- * @examplePrompt Check whether the FAR label already exists
134
- *
135
- * # Example
136
- * ```ts
137
- * const { shapes } = await snaptrude.presentation.shapes.list()
138
- * const hasLabel = shapes.some((s) => s.key === "far-label")
139
- * ```
140
- */
141
- public abstract list(): PluginApiReturn<PluginPresentationShapesListResult>
142
- }
143
-
144
- /**
145
- * Desired shape for {@linkcode PluginPresentationShapesApi.upsert} — a
146
- * discriminated union over the four annotate kinds, with the same option shapes
147
- * as the matching `presentation.annotate` call:
148
- *
149
- * | `type` | Payload | Mirrors |
150
- * |---|---|---|
151
- * | `"text"` | `text`, `position?`, `size?`, `color?` | `annotate.text` |
152
- * | `"note"` | `text`, `position?`, `color?`, `size?` | `annotate.note` |
153
- * | `"arrow"` | `start`, `end`, `color?`, `size?` | `annotate.arrow` |
154
- * | `"geo"` | `kind`, `bounds`, `color?`, `fill?` | `annotate.shape` |
155
- *
156
- * Positions/bounds are relative to the sheet's top-left, in canvas units.
157
- */
158
- export const PluginPresentationShapeSpec = z.discriminatedUnion("type", [
159
- z.object({
160
- type: z.literal("text"),
161
- text: z.string(),
162
- position: z.object({ x: z.number(), y: z.number() }).optional(),
163
- size: PluginAnnotateTextSize.optional(),
164
- color: PluginAnnotateTextColor.optional(),
165
- }),
166
- z.object({
167
- type: z.literal("note"),
168
- text: z.string(),
169
- position: z.object({ x: z.number(), y: z.number() }).optional(),
170
- color: PluginAnnotateTextColor.optional(),
171
- size: PluginAnnotateTextSize.optional(),
172
- }),
173
- z.object({
174
- type: z.literal("arrow"),
175
- start: z.object({ x: z.number(), y: z.number() }),
176
- end: z.object({ x: z.number(), y: z.number() }),
177
- color: PluginAnnotateTextColor.optional(),
178
- size: PluginAnnotateTextSize.optional(),
179
- }),
180
- z.object({
181
- type: z.literal("geo"),
182
- kind: PluginAnnotateGeoKind,
183
- bounds: z.object({
184
- x: z.number(),
185
- y: z.number(),
186
- w: z.number().positive(),
187
- h: z.number().positive(),
188
- }),
189
- color: PluginAnnotateTextColor.optional(),
190
- fill: PluginAnnotateFill.optional(),
191
- }),
192
- ])
193
- export type PluginPresentationShapeSpec = z.infer<
194
- typeof PluginPresentationShapeSpec
195
- >
196
-
197
- /** The shape kind of a plugin-owned shape (the `type` discriminant of {@linkcode PluginPresentationShapeSpec}). */
198
- export const PluginPresentationShapeType = z.enum([
199
- "text",
200
- "note",
201
- "arrow",
202
- "geo",
203
- ])
204
- export type PluginPresentationShapeType = z.infer<
205
- typeof PluginPresentationShapeType
206
- >
207
-
208
- /**
209
- * Arguments for {@linkcode PluginPresentationShapesApi.upsert}.
210
- *
211
- * | Property | Type | Description |
212
- * |---|---|---|
213
- * | `key` | `string` | Caller-chosen stable identifier (non-empty) |
214
- * | `shape` | {@linkcode PluginPresentationShapeSpec} | The desired shape |
215
- * | `sheetId` | `string \| undefined` | Sheet to create on (default: first sheet; ignored on update) |
216
- */
217
- export const PluginPresentationShapesUpsertArgs = z.object({
218
- key: z.string().min(1),
219
- shape: PluginPresentationShapeSpec,
220
- sheetId: z.string().optional(),
221
- })
222
- export type PluginPresentationShapesUpsertArgs = z.infer<
223
- typeof PluginPresentationShapesUpsertArgs
224
- >
225
-
226
- /**
227
- * Result of {@linkcode PluginPresentationShapesApi.upsert}.
228
- *
229
- * | Property | Type | Description |
230
- * |---|---|---|
231
- * | `shapeId` | `string` | Stable id of the canvas shape for the key |
232
- * | `created` | `boolean` | `true` if the shape was created, `false` if updated |
233
- */
234
- export const PluginPresentationShapesUpsertResult = z.object({
235
- shapeId: z.string(),
236
- created: z.boolean(),
237
- })
238
- export type PluginPresentationShapesUpsertResult = z.infer<
239
- typeof PluginPresentationShapesUpsertResult
240
- >
241
-
242
- /**
243
- * Arguments for {@linkcode PluginPresentationShapesApi.remove}.
244
- *
245
- * | Property | Type | Description |
246
- * |---|---|---|
247
- * | `key` | `string` | The key the shape was upserted under (non-empty) |
248
- */
249
- export const PluginPresentationShapesRemoveArgs = z.object({
250
- key: z.string().min(1),
251
- })
252
- export type PluginPresentationShapesRemoveArgs = z.infer<
253
- typeof PluginPresentationShapesRemoveArgs
254
- >
255
-
256
- /**
257
- * Result of {@linkcode PluginPresentationShapesApi.list}.
258
- *
259
- * | Property | Type | Description |
260
- * |---|---|---|
261
- * | `shapes` | `{ key: string; shapeId: string; type: `{@linkcode PluginPresentationShapeType}` }[]` | One entry per live plugin-owned shape |
262
- */
263
- export const PluginPresentationShapesListResult = z.object({
264
- shapes: z.array(
265
- z.object({
266
- key: z.string(),
267
- shapeId: z.string(),
268
- type: PluginPresentationShapeType,
269
- }),
270
- ),
271
- })
272
- export type PluginPresentationShapesListResult = z.infer<
273
- typeof PluginPresentationShapesListResult
274
- >
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import {
4
+ PluginAnnotateFill,
5
+ PluginAnnotateGeoKind,
6
+ PluginAnnotateTextColor,
7
+ PluginAnnotateTextSize,
8
+ } from "./annotate"
9
+
10
+ /**
11
+ * Presentation shapes — a stable, plugin-owned shape lifecycle on Present-mode
12
+ * sheets.
13
+ *
14
+ * Where {@linkcode PluginPresentationAnnotateApi} is fire-and-forget (every call
15
+ * creates a new shape), this namespace keys each shape by a caller-chosen
16
+ * string, so rerunning an analysis **updates** its sheet output in place instead
17
+ * of duplicating it:
18
+ *
19
+ * - {@linkcode PluginPresentationShapesApi.upsert} — create or update the shape for a key
20
+ * - {@linkcode PluginPresentationShapesApi.remove} — delete the shape for a key
21
+ * - {@linkcode PluginPresentationShapesApi.removeAll} — delete every shape owned by the calling plugin
22
+ * - {@linkcode PluginPresentationShapesApi.list} — the calling plugin's shapes (key, shapeId, type)
23
+ *
24
+ * Shape ids are derived deterministically from the plugin id + key, so upserts
25
+ * converge across collaborators. Mutations require **Present mode to be open**
26
+ * (`list` is a never-throw read); each plugin sees and mutates only its own
27
+ * shapes.
28
+ *
29
+ * Accessed via `snaptrude.presentation.shapes`.
30
+ */
31
+ export abstract class PluginPresentationShapesApi {
32
+ constructor() {}
33
+
34
+ /**
35
+ * Create or update the shape for a key.
36
+ *
37
+ * The `shape` spec is a discriminated union over the same four annotation
38
+ * kinds as `presentation.annotate` (`text`, `note`, `arrow`, `geo`), with the
39
+ * same option shapes. On first call for a key the shape is created on the
40
+ * target sheet (`options.sheetId`, default: the first sheet) and nested under
41
+ * the sheet frame; on later calls the existing shape is updated in place —
42
+ * same shape id, same sheet, one undo step. Positions/bounds are relative to
43
+ * the sheet's top-left, in canvas units. Requires Present mode to be open.
44
+ *
45
+ * @param key - Caller-chosen stable identifier for the shape (per plugin).
46
+ * @param shape - The desired shape ({@linkcode PluginPresentationShapeSpec}):
47
+ * `{ type: "text" | "note" | "arrow" | "geo", ... }` with the matching
48
+ * annotate options. Changing `type` for an existing key replaces the shape
49
+ * (same shape id).
50
+ * @param options - Optional `sheetId` — the sheet to create the shape on
51
+ * (defaults to the first sheet; ignored on update, the shape stays on its
52
+ * sheet).
53
+ * @returns A {@linkcode PluginPresentationShapesUpsertResult} — the stable
54
+ * `shapeId` and `created` (`true` on first upsert, `false` on update).
55
+ * @throws If Present mode is not open, the args are invalid, or the sheet id
56
+ * is unknown.
57
+ *
58
+ * @examplePrompt Update the analysis label on the sheet instead of adding another one
59
+ * @examplePrompt Rerun the daylight report and refresh its annotations
60
+ * @examplePrompt Keep one "FAR: 2.4" text on Sheet 1 that updates on each run
61
+ * @examplePrompt Draw a highlight rectangle the plugin can move on the next run
62
+ *
63
+ * # Example
64
+ * ```ts
65
+ * const { shapeId, created } = await snaptrude.presentation.shapes.upsert("far-label", {
66
+ * type: "text",
67
+ * text: "FAR: 2.4",
68
+ * position: { x: 40, y: 40 },
69
+ * color: "blue",
70
+ * })
71
+ * ```
72
+ */
73
+ public abstract upsert(
74
+ key: string,
75
+ shape: PluginPresentationShapeSpec,
76
+ options?: { sheetId?: string },
77
+ ): PluginApiReturn<PluginPresentationShapesUpsertResult>
78
+
79
+ /**
80
+ * Delete the shape for a key.
81
+ *
82
+ * Removes the calling plugin's shape registered under `key`, if it exists.
83
+ * Requires Present mode to be open.
84
+ *
85
+ * @param key - The key passed to {@linkcode PluginPresentationShapesApi.upsert}.
86
+ * @returns `true` if a shape was deleted, `false` if no shape exists for the
87
+ * key.
88
+ * @throws If Present mode is not open or the key is invalid.
89
+ *
90
+ * @examplePrompt Remove the FAR label from the sheet
91
+ * @examplePrompt Delete the highlight the plugin added earlier
92
+ * @examplePrompt Clear the "far-label" annotation
93
+ *
94
+ * # Example
95
+ * ```ts
96
+ * const removed = await snaptrude.presentation.shapes.remove("far-label")
97
+ * ```
98
+ */
99
+ public abstract remove(key: string): PluginApiReturn<boolean>
100
+
101
+ /**
102
+ * Delete every shape owned by the calling plugin.
103
+ *
104
+ * Removes all shapes the calling plugin has upserted (across all sheets) in
105
+ * one undo step. Requires Present mode to be open.
106
+ *
107
+ * @returns The number of shapes deleted.
108
+ * @throws If Present mode is not open.
109
+ *
110
+ * @examplePrompt Clear all annotations my plugin added
111
+ * @examplePrompt Reset the sheet output before rerunning the analysis
112
+ * @examplePrompt Remove every plugin-drawn shape
113
+ *
114
+ * # Example
115
+ * ```ts
116
+ * const deleted = await snaptrude.presentation.shapes.removeAll()
117
+ * ```
118
+ */
119
+ public abstract removeAll(): PluginApiReturn<number>
120
+
121
+ /**
122
+ * List the calling plugin's shapes.
123
+ *
124
+ * Returns one entry per live shape the calling plugin has upserted — its
125
+ * `key`, the underlying canvas `shapeId`, and the shape `type`. A never-throw
126
+ * read: returns an empty list when Present mode is closed.
127
+ *
128
+ * @returns A {@linkcode PluginPresentationShapesListResult} with the `shapes`
129
+ * array (empty when Present mode is closed).
130
+ *
131
+ * @examplePrompt Which annotations has my plugin placed on the sheets?
132
+ * @examplePrompt List the plugin's shapes before refreshing them
133
+ * @examplePrompt Check whether the FAR label already exists
134
+ *
135
+ * # Example
136
+ * ```ts
137
+ * const { shapes } = await snaptrude.presentation.shapes.list()
138
+ * const hasLabel = shapes.some((s) => s.key === "far-label")
139
+ * ```
140
+ */
141
+ public abstract list(): PluginApiReturn<PluginPresentationShapesListResult>
142
+ }
143
+
144
+ /**
145
+ * Desired shape for {@linkcode PluginPresentationShapesApi.upsert} — a
146
+ * discriminated union over the four annotate kinds, with the same option shapes
147
+ * as the matching `presentation.annotate` call:
148
+ *
149
+ * | `type` | Payload | Mirrors |
150
+ * |---|---|---|
151
+ * | `"text"` | `text`, `position?`, `size?`, `color?` | `annotate.text` |
152
+ * | `"note"` | `text`, `position?`, `color?`, `size?` | `annotate.note` |
153
+ * | `"arrow"` | `start`, `end`, `color?`, `size?` | `annotate.arrow` |
154
+ * | `"geo"` | `kind`, `bounds`, `color?`, `fill?` | `annotate.shape` |
155
+ *
156
+ * Positions/bounds are relative to the sheet's top-left, in canvas units.
157
+ */
158
+ export const PluginPresentationShapeSpec = z.discriminatedUnion("type", [
159
+ z.object({
160
+ type: z.literal("text"),
161
+ text: z.string(),
162
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
163
+ size: PluginAnnotateTextSize.optional(),
164
+ color: PluginAnnotateTextColor.optional(),
165
+ }),
166
+ z.object({
167
+ type: z.literal("note"),
168
+ text: z.string(),
169
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
170
+ color: PluginAnnotateTextColor.optional(),
171
+ size: PluginAnnotateTextSize.optional(),
172
+ }),
173
+ z.object({
174
+ type: z.literal("arrow"),
175
+ start: z.object({ x: z.number(), y: z.number() }),
176
+ end: z.object({ x: z.number(), y: z.number() }),
177
+ color: PluginAnnotateTextColor.optional(),
178
+ size: PluginAnnotateTextSize.optional(),
179
+ }),
180
+ z.object({
181
+ type: z.literal("geo"),
182
+ kind: PluginAnnotateGeoKind,
183
+ bounds: z.object({
184
+ x: z.number(),
185
+ y: z.number(),
186
+ w: z.number().positive(),
187
+ h: z.number().positive(),
188
+ }),
189
+ color: PluginAnnotateTextColor.optional(),
190
+ fill: PluginAnnotateFill.optional(),
191
+ }),
192
+ ])
193
+ export type PluginPresentationShapeSpec = z.infer<
194
+ typeof PluginPresentationShapeSpec
195
+ >
196
+
197
+ /** The shape kind of a plugin-owned shape (the `type` discriminant of {@linkcode PluginPresentationShapeSpec}). */
198
+ export const PluginPresentationShapeType = z.enum([
199
+ "text",
200
+ "note",
201
+ "arrow",
202
+ "geo",
203
+ ])
204
+ export type PluginPresentationShapeType = z.infer<
205
+ typeof PluginPresentationShapeType
206
+ >
207
+
208
+ /**
209
+ * Arguments for {@linkcode PluginPresentationShapesApi.upsert}.
210
+ *
211
+ * | Property | Type | Description |
212
+ * |---|---|---|
213
+ * | `key` | `string` | Caller-chosen stable identifier (non-empty) |
214
+ * | `shape` | {@linkcode PluginPresentationShapeSpec} | The desired shape |
215
+ * | `sheetId` | `string \| undefined` | Sheet to create on (default: first sheet; ignored on update) |
216
+ */
217
+ export const PluginPresentationShapesUpsertArgs = z.object({
218
+ key: z.string().min(1),
219
+ shape: PluginPresentationShapeSpec,
220
+ sheetId: z.string().optional(),
221
+ })
222
+ export type PluginPresentationShapesUpsertArgs = z.infer<
223
+ typeof PluginPresentationShapesUpsertArgs
224
+ >
225
+
226
+ /**
227
+ * Result of {@linkcode PluginPresentationShapesApi.upsert}.
228
+ *
229
+ * | Property | Type | Description |
230
+ * |---|---|---|
231
+ * | `shapeId` | `string` | Stable id of the canvas shape for the key |
232
+ * | `created` | `boolean` | `true` if the shape was created, `false` if updated |
233
+ */
234
+ export const PluginPresentationShapesUpsertResult = z.object({
235
+ shapeId: z.string(),
236
+ created: z.boolean(),
237
+ })
238
+ export type PluginPresentationShapesUpsertResult = z.infer<
239
+ typeof PluginPresentationShapesUpsertResult
240
+ >
241
+
242
+ /**
243
+ * Arguments for {@linkcode PluginPresentationShapesApi.remove}.
244
+ *
245
+ * | Property | Type | Description |
246
+ * |---|---|---|
247
+ * | `key` | `string` | The key the shape was upserted under (non-empty) |
248
+ */
249
+ export const PluginPresentationShapesRemoveArgs = z.object({
250
+ key: z.string().min(1),
251
+ })
252
+ export type PluginPresentationShapesRemoveArgs = z.infer<
253
+ typeof PluginPresentationShapesRemoveArgs
254
+ >
255
+
256
+ /**
257
+ * Result of {@linkcode PluginPresentationShapesApi.list}.
258
+ *
259
+ * | Property | Type | Description |
260
+ * |---|---|---|
261
+ * | `shapes` | `{ key: string; shapeId: string; type: `{@linkcode PluginPresentationShapeType}` }[]` | One entry per live plugin-owned shape |
262
+ */
263
+ export const PluginPresentationShapesListResult = z.object({
264
+ shapes: z.array(
265
+ z.object({
266
+ key: z.string(),
267
+ shapeId: z.string(),
268
+ type: PluginPresentationShapeType,
269
+ }),
270
+ ),
271
+ })
272
+ export type PluginPresentationShapesListResult = z.infer<
273
+ typeof PluginPresentationShapesListResult
274
+ >