@snaptrude/plugin-core 0.9.17 → 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 (219) hide show
  1. package/AGENTS.md +231 -231
  2. package/CHANGELOG.md +408 -408
  3. package/CLAUDE.md +11 -11
  4. package/api-manifest.json +1428 -712
  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 +32 -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/shapes.d.ts +2 -2
  65. package/dist/api/presentation/sheets.d.ts +175 -19
  66. package/dist/api/presentation/sheets.d.ts.map +1 -1
  67. package/dist/api/presentation/viewPresets.d.ts +222 -0
  68. package/dist/api/presentation/viewPresets.d.ts.map +1 -0
  69. package/dist/api/presentation/views.d.ts +141 -8
  70. package/dist/api/presentation/views.d.ts.map +1 -1
  71. package/dist/api/presentation/walkthroughs.d.ts +6 -6
  72. package/dist/errors/codes.d.ts +3 -1
  73. package/dist/errors/codes.d.ts.map +1 -1
  74. package/dist/index.cjs +3831 -2444
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.js +3705 -2444
  77. package/dist/index.js.map +1 -1
  78. package/package.json +1 -1
  79. package/scripts/check-dist-fresh.mjs +22 -22
  80. package/scripts/generate-manifest.mjs +243 -238
  81. package/scripts/generate-manifest.test.mjs +303 -303
  82. package/src/api/analysis/daylight.ts +470 -470
  83. package/src/api/analysis/heatmaps.ts +683 -683
  84. package/src/api/analysis/illuminance.ts +155 -155
  85. package/src/api/analysis/index.ts +61 -61
  86. package/src/api/analysis/shadows.ts +183 -183
  87. package/src/api/analysis/solar.ts +237 -237
  88. package/src/api/analysis/sunlightHours.ts +211 -211
  89. package/src/api/analysis/sunpath.ts +83 -83
  90. package/src/api/analysis/weather.ts +179 -179
  91. package/src/api/core/buildings.ts +485 -485
  92. package/src/api/core/camera/index.ts +696 -667
  93. package/src/api/core/comment/index.ts +376 -376
  94. package/src/api/core/geom/create/index.ts +2139 -2133
  95. package/src/api/core/geom/delete/index.ts +84 -84
  96. package/src/api/core/geom/index.ts +35 -35
  97. package/src/api/core/geom/query/arc.ts +169 -169
  98. package/src/api/core/geom/query/brep.ts +621 -621
  99. package/src/api/core/geom/query/circle.ts +404 -404
  100. package/src/api/core/geom/query/contour.ts +540 -540
  101. package/src/api/core/geom/query/curve.ts +1102 -1102
  102. package/src/api/core/geom/query/edge.ts +130 -130
  103. package/src/api/core/geom/query/face.ts +508 -508
  104. package/src/api/core/geom/query/halfedge.ts +210 -210
  105. package/src/api/core/geom/query/index.ts +63 -63
  106. package/src/api/core/geom/query/profile.ts +473 -473
  107. package/src/api/core/geom/query/vertex.ts +205 -205
  108. package/src/api/core/geom/update/contour.ts +323 -317
  109. package/src/api/core/geom/update/curve.ts +209 -209
  110. package/src/api/core/geom/update/index.ts +29 -29
  111. package/src/api/core/geom/update/profile.ts +379 -379
  112. package/src/api/core/groups.ts +521 -521
  113. package/src/api/core/handles/index.ts +234 -234
  114. package/src/api/core/history/index.ts +84 -84
  115. package/src/api/core/index.ts +99 -99
  116. package/src/api/core/io/export/index.ts +126 -126
  117. package/src/api/core/io/import/index.ts +504 -504
  118. package/src/api/core/io/index.ts +42 -42
  119. package/src/api/core/io/job/index.ts +140 -140
  120. package/src/api/core/io/query/index.ts +71 -71
  121. package/src/api/core/io/terrain/index.ts +360 -360
  122. package/src/api/core/io/underlay/index.ts +705 -705
  123. package/src/api/core/layers.ts +540 -540
  124. package/src/api/core/math/index.ts +20 -20
  125. package/src/api/core/math/quat.ts +172 -172
  126. package/src/api/core/math/vec3.ts +179 -179
  127. package/src/api/core/mode/index.ts +108 -108
  128. package/src/api/core/project/index.ts +479 -479
  129. package/src/api/core/proposals/index.ts +570 -570
  130. package/src/api/core/storeys/index.ts +311 -308
  131. package/src/api/core/storeys/layers.ts +339 -339
  132. package/src/api/core/tags.ts +911 -911
  133. package/src/api/core/units/index.ts +164 -164
  134. package/src/api/core/user.ts +46 -46
  135. package/src/api/core/zoom/index.ts +64 -51
  136. package/src/api/design/bim.ts +210 -0
  137. package/src/api/design/boolean/index.ts +181 -179
  138. package/src/api/design/catalog.ts +203 -0
  139. package/src/api/design/create/bulk-items.ts +294 -254
  140. package/src/api/design/create/grids.ts +137 -137
  141. package/src/api/design/create/index.ts +2178 -1980
  142. package/src/api/design/create/opening-fields.ts +40 -37
  143. package/src/api/design/delete/index.ts +75 -74
  144. package/src/api/design/dimensions.ts +453 -453
  145. package/src/api/design/doors/index.ts +516 -500
  146. package/src/api/design/edit/index.ts +54 -54
  147. package/src/api/design/erase/index.ts +151 -151
  148. package/src/api/design/family.ts +1342 -704
  149. package/src/api/design/furniture/index.ts +319 -319
  150. package/src/api/design/grids.ts +237 -237
  151. package/src/api/design/index.ts +304 -274
  152. package/src/api/design/lock.ts +69 -69
  153. package/src/api/design/materials/index.ts +608 -608
  154. package/src/api/design/networks.ts +607 -0
  155. package/src/api/design/query/geometry/index.ts +319 -319
  156. package/src/api/design/query/grids.ts +197 -197
  157. package/src/api/design/query/index.ts +1236 -1226
  158. package/src/api/design/query/referenceLines.ts +52 -52
  159. package/src/api/design/query/spaces.ts +275 -275
  160. package/src/api/design/selection/index.ts +273 -273
  161. package/src/api/design/shared.ts +40 -40
  162. package/src/api/design/transform/index.ts +254 -254
  163. package/src/api/design/types/index.ts +163 -156
  164. package/src/api/design/update/index.ts +1096 -983
  165. package/src/api/design/visibility.ts +143 -143
  166. package/src/api/design/windows/index.ts +351 -333
  167. package/src/api/entity/buildableEnvelope.ts +397 -322
  168. package/src/api/entity/index.ts +30 -30
  169. package/src/api/entity/referenceLine.ts +235 -235
  170. package/src/api/entity/space.ts +612 -612
  171. package/src/api/entity/story.ts +517 -517
  172. package/src/api/index.ts +47 -47
  173. package/src/api/presentation/aiInspiration.ts +1116 -1116
  174. package/src/api/presentation/annotate.ts +417 -385
  175. package/src/api/presentation/camera.ts +289 -289
  176. package/src/api/presentation/diagrams.ts +194 -194
  177. package/src/api/presentation/drawingContract.ts +70 -0
  178. package/src/api/presentation/drawings.ts +1179 -0
  179. package/src/api/presentation/export.ts +134 -108
  180. package/src/api/presentation/import.ts +159 -159
  181. package/src/api/presentation/index.ts +160 -135
  182. package/src/api/presentation/placedViews.ts +1211 -1120
  183. package/src/api/presentation/sections.ts +420 -420
  184. package/src/api/presentation/shapes.ts +274 -274
  185. package/src/api/presentation/sheets.ts +746 -585
  186. package/src/api/presentation/slideshow.ts +134 -134
  187. package/src/api/presentation/tables.ts +84 -84
  188. package/src/api/presentation/viewPresets.ts +241 -0
  189. package/src/api/presentation/views.ts +742 -673
  190. package/src/api/presentation/walkthroughs.ts +1201 -1201
  191. package/src/api/program/adjacency.ts +164 -164
  192. package/src/api/program/areas.ts +408 -408
  193. package/src/api/program/classification.ts +138 -138
  194. package/src/api/program/cores.ts +83 -83
  195. package/src/api/program/departments.ts +517 -517
  196. package/src/api/program/index.ts +73 -73
  197. package/src/api/program/labels.ts +332 -332
  198. package/src/api/program/layout.ts +422 -422
  199. package/src/api/program/metadata.ts +364 -364
  200. package/src/api/program/metrics.ts +120 -120
  201. package/src/api/program/site.ts +748 -748
  202. package/src/api/program/spreadsheet.ts +2698 -2698
  203. package/src/api/workspace/index.ts +612 -612
  204. package/src/errors/codes.ts +143 -136
  205. package/src/errors/envelope.ts +75 -75
  206. package/src/errors/index.ts +21 -21
  207. package/src/errors/plugin-error.ts +134 -134
  208. package/src/handles.ts +297 -297
  209. package/src/host-utils.ts +67 -67
  210. package/src/index.ts +7 -7
  211. package/src/massParameters.ops.ts +246 -246
  212. package/src/massParameters.ts +427 -427
  213. package/src/types.ts +16 -16
  214. package/test/drawingContract.test.mjs +288 -0
  215. package/test/errors.test.mjs +185 -184
  216. package/test/massParameters.test.mjs +952 -952
  217. package/test/presentationViewSettings.test.mjs +85 -0
  218. package/tsconfig.json +22 -22
  219. package/tsup.config.ts +12 -12
@@ -1,332 +1,332 @@
1
- import * as z from "zod"
2
- import { PluginApiReturn } from "../../types"
3
- import { PluginAreaUnit } from "./metrics"
4
-
5
- /**
6
- * Program labels — the **program rows** of the active program: each label is a
7
- * named space type (e.g. "Exam Room", "Nurse Station") inside a department,
8
- * carrying an area **target** and a unit **count** target.
9
- *
10
- * Labels are the non-department planning entities of program mode. A
11
- * department groups labels; a label groups the spaces (masses) that realize it.
12
- * Target areas live on **departments** ({@linkcode PluginProgramDepartmentsApi.setTargetArea})
13
- * and on **labels** (this namespace) — an individual space carries no target of
14
- * its own; it inherits its label's `targetArea / targetCount`. Program Blocks
15
- * (spaces whose space type is "Program Block") are likewise targeted through
16
- * their label.
17
- *
18
- * `targetArea` is the label's **total** target (all units), in the response's
19
- * `units`; the per-unit target is `targetArea / targetCount`.
20
- *
21
- * Reads never throw for a miss (`get` returns `null`, `list` returns `[]`).
22
- * Writes are undoable and autosaved; when the project has proposals they write
23
- * the **active proposal's** targets.
24
- *
25
- * Accessed via `snaptrude.program.labels`.
26
- */
27
- export abstract class PluginProgramLabelsApi {
28
- constructor() {}
29
-
30
- /**
31
- * List the labels (program rows) of the active program.
32
- *
33
- * @returns A {@linkcode PluginProgramLabelsListResult} with `units` and a
34
- * `labels` array (empty when the project has none).
35
- *
36
- * @examplePrompt List all the program rows with their target areas
37
- * @examplePrompt What space labels are in the program and how many of each?
38
- * @examplePrompt Show every label with its department and target
39
- *
40
- * # Example
41
- * ```ts
42
- * const { units, labels } = await snaptrude.program.labels.list()
43
- * for (const l of labels) console.log(l.name, l.targetArea, units, l.targetCount)
44
- * ```
45
- */
46
- public abstract list(): PluginApiReturn<PluginProgramLabelsListResult>
47
-
48
- /**
49
- * Get a single label by id.
50
- *
51
- * @param labelId - The id of the label to read.
52
- * @returns The matching {@linkcode PluginProgramLabelRecord} (with `units`), or
53
- * `null` if no label has that id.
54
- *
55
- * @examplePrompt Get the label with id lbl_12
56
- * @examplePrompt What is the target area of this program row?
57
- *
58
- * # Example
59
- * ```ts
60
- * const label = await snaptrude.program.labels.get("lbl_12")
61
- * if (label) console.log(label.name, label.targetArea, label.units)
62
- * ```
63
- */
64
- public abstract get(
65
- labelId: string,
66
- ): PluginApiReturn<PluginProgramLabelsGetResult>
67
-
68
- /**
69
- * Create labels (program rows), optionally creating their spaces too.
70
- *
71
- * Each item names a label and its targets. A label is unique per
72
- * (`name`, department); an item matching an existing label **updates** that
73
- * label's targets instead of duplicating it. Unknown departments are created
74
- * by name when `departmentName` is given; omit both department fields for the
75
- * Default department.
76
- *
77
- * By default only the program rows are created (targets to plan against).
78
- * Pass `createSpaces: true` to also instantiate `targetCount` massing spaces
79
- * per label on the canvas, laid out automatically — the same path Program
80
- * Mode's CSV/Interpret import uses.
81
- *
82
- * @param items - The labels to create (1–500).
83
- * @param options - Optional `units` for every `targetArea` (defaults to the
84
- * project's area units) and `createSpaces` (default `false`).
85
- * @returns A {@linkcode PluginProgramLabelsCreateResult} with the created or
86
- * updated label ids, in input order.
87
- * @throws If an item's `departmentId` does not exist.
88
- *
89
- * @examplePrompt Add program rows for 4 exam rooms of 120 sqft each
90
- * @examplePrompt Create the labels from this interpreted program
91
- * @examplePrompt Add an Office label with a 2000 sqft target to the Admin department
92
- * @examplePrompt Create program rows and their spaces on the canvas
93
- *
94
- * # Example
95
- * ```ts
96
- * const { labelIds } = await snaptrude.program.labels.create(
97
- * [{ name: "Exam Room", targetArea: 480, targetCount: 4, departmentName: "Clinic" }],
98
- * { units: "ft2" },
99
- * )
100
- * ```
101
- */
102
- public abstract create(
103
- items: PluginProgramLabelCreateItem[],
104
- options?: { units?: PluginAreaUnit; createSpaces?: boolean },
105
- ): PluginApiReturn<PluginProgramLabelsCreateResult>
106
-
107
- /**
108
- * Set a label's total target area.
109
- *
110
- * The goal the program metrics compare the label's allocated area against.
111
- * Pass `units` to say what unit `targetArea` is in; it defaults to the
112
- * project's area units. Read it back with {@linkcode PluginProgramLabelsApi.get}.
113
- *
114
- * @param labelId - The id of the label whose target to set.
115
- * @param targetArea - The total target area (all units), in `units`.
116
- * @param units - Unit of `targetArea` (defaults to the project's area units).
117
- * @returns The updated {@linkcode PluginProgramLabelRecord} with its `units`.
118
- * @throws If no label has the given id.
119
- *
120
- * @examplePrompt Set the Exam Room target area to 480 sqft
121
- * @examplePrompt Give the Corridor program row a 150 sqm target
122
- * @examplePrompt Update the area target for label lbl_12
123
- *
124
- * # Example
125
- * ```ts
126
- * await snaptrude.program.labels.setTargetArea("lbl_12", 480, "ft2")
127
- * ```
128
- */
129
- public abstract setTargetArea(
130
- labelId: string,
131
- targetArea: number,
132
- units?: PluginAreaUnit,
133
- ): PluginApiReturn<PluginProgramLabelsSetTargetAreaResult>
134
-
135
- /**
136
- * Set a label's target unit count (how many of this space the program calls for).
137
- *
138
- * @param labelId - The id of the label whose count to set.
139
- * @param targetCount - The target number of units (a non-negative integer).
140
- * @returns The updated {@linkcode PluginProgramLabelRecord} with its `units`.
141
- * @throws If no label has the given id.
142
- *
143
- * @examplePrompt Set the Exam Room count to 6
144
- * @examplePrompt The program needs 12 patient rooms — update the count
145
- *
146
- * # Example
147
- * ```ts
148
- * await snaptrude.program.labels.setTargetCount("lbl_12", 6)
149
- * ```
150
- */
151
- public abstract setTargetCount(
152
- labelId: string,
153
- targetCount: number,
154
- ): PluginApiReturn<PluginProgramLabelsSetTargetCountResult>
155
- }
156
-
157
- /**
158
- * A label (program row) in the active program. `targetArea` is the label's
159
- * **total** target in the enclosing response's `units`.
160
- *
161
- * | Property | Type | Description |
162
- * |---|---|---|
163
- * | `id` | `string` | Stable label id |
164
- * | `name` | `string` | Label (space type) name |
165
- * | `color` | `string` | CSS hex color string |
166
- * | `departmentId` | `string` | Id of the department the label belongs to |
167
- * | `targetArea` | `number \| null` | Total target area (all units), or `null` when no target is set |
168
- * | `targetCount` | `number` | Target number of units (`0` when unset) |
169
- * | `storey` | `number \| null` | Default storey new spaces of this label are placed on |
170
- */
171
- export const PluginProgramLabel = z.object({
172
- id: z.string(),
173
- name: z.string(),
174
- color: z.string(),
175
- departmentId: z.string(),
176
- targetArea: z.number().nullable(),
177
- targetCount: z.number(),
178
- storey: z.number().nullable(),
179
- })
180
- export type PluginProgramLabel = z.infer<typeof PluginProgramLabel>
181
-
182
- /** A bare label record carrying its area `units` (per the area-units convention). */
183
- export const PluginProgramLabelRecord = PluginProgramLabel.extend({
184
- units: PluginAreaUnit,
185
- })
186
- export type PluginProgramLabelRecord = z.infer<typeof PluginProgramLabelRecord>
187
-
188
- /**
189
- * Result of {@linkcode PluginProgramLabelsApi.list}.
190
- *
191
- * | Property | Type | Description |
192
- * |---|---|---|
193
- * | `units` | `"ft2" \| "m2"` | The unit every `targetArea` below is reported in |
194
- * | `labels` | {@linkcode PluginProgramLabel}`[]` | All labels in the active program |
195
- */
196
- export const PluginProgramLabelsListResult = z.object({
197
- units: PluginAreaUnit,
198
- labels: z.array(PluginProgramLabel),
199
- })
200
- export type PluginProgramLabelsListResult = z.infer<
201
- typeof PluginProgramLabelsListResult
202
- >
203
-
204
- /** Arguments for {@linkcode PluginProgramLabelsApi.get}. */
205
- export const PluginProgramLabelsGetArgs = z.object({
206
- labelId: z.string(),
207
- })
208
- export type PluginProgramLabelsGetArgs = z.infer<
209
- typeof PluginProgramLabelsGetArgs
210
- >
211
-
212
- /** Result of {@linkcode PluginProgramLabelsApi.get} — the record with `units`, or `null`. */
213
- export const PluginProgramLabelsGetResult = PluginProgramLabelRecord.nullable()
214
- export type PluginProgramLabelsGetResult = z.infer<
215
- typeof PluginProgramLabelsGetResult
216
- >
217
-
218
- /**
219
- * One label to create via {@linkcode PluginProgramLabelsApi.create}.
220
- *
221
- * | Property | Type | Description |
222
- * |---|---|---|
223
- * | `name` | `string` | Label (space type) name |
224
- * | `targetArea` | `number?` | Total target area (all units), in the call's `units` |
225
- * | `targetCount` | `number?` | Target number of units (default `1`) |
226
- * | `departmentId` | `string?` | Existing department to file the label under |
227
- * | `departmentName` | `string?` | Department by name — created when it does not exist (ignored when `departmentId` is given) |
228
- * | `color` | `string?` | CSS hex color (a light color is generated when omitted) |
229
- * | `storey` | `number?` | Storey for spaces of this label (default `1`) |
230
- * | `height` | `number?` | Space height in project length units (for `createSpaces`) |
231
- * | `width` | `number?` | Space width in project length units (for `createSpaces`) |
232
- */
233
- export const PluginProgramLabelCreateItem = z.object({
234
- name: z.string().trim().min(1),
235
- targetArea: z.number().finite().nonnegative().optional(),
236
- targetCount: z.number().int().nonnegative().optional(),
237
- departmentId: z.string().optional(),
238
- departmentName: z.string().optional(),
239
- color: z.string().optional(),
240
- storey: z.number().int().optional(),
241
- height: z.number().finite().positive().optional(),
242
- width: z.number().finite().positive().optional(),
243
- })
244
- export type PluginProgramLabelCreateItem = z.infer<
245
- typeof PluginProgramLabelCreateItem
246
- >
247
-
248
- /** Maximum items per {@linkcode PluginProgramLabelsApi.create} call. */
249
- export const PLUGIN_PROGRAM_LABELS_BATCH_LIMIT = 500
250
-
251
- /**
252
- * Arguments for {@linkcode PluginProgramLabelsApi.create}.
253
- *
254
- * | Property | Type | Description |
255
- * |---|---|---|
256
- * | `items` | {@linkcode PluginProgramLabelCreateItem}`[]` | 1–500 labels |
257
- * | `units` | `"ft2" \| "m2"?` | Unit of every `targetArea` (defaults to the project's area units) |
258
- * | `createSpaces` | `boolean?` | Also create `targetCount` spaces per label on the canvas (default `false`) |
259
- */
260
- export const PluginProgramLabelsCreateArgs = z.object({
261
- items: z
262
- .array(PluginProgramLabelCreateItem)
263
- .min(1)
264
- .max(PLUGIN_PROGRAM_LABELS_BATCH_LIMIT),
265
- units: PluginAreaUnit.optional(),
266
- createSpaces: z.boolean().optional(),
267
- })
268
- export type PluginProgramLabelsCreateArgs = z.infer<
269
- typeof PluginProgramLabelsCreateArgs
270
- >
271
-
272
- /**
273
- * Result of {@linkcode PluginProgramLabelsApi.create}.
274
- *
275
- * | Property | Type | Description |
276
- * |---|---|---|
277
- * | `labelIds` | `string[]` | The created (or updated) label ids, in input order |
278
- * | `createdSpaces` | `boolean` | Whether spaces were also created on the canvas |
279
- */
280
- export const PluginProgramLabelsCreateResult = z.object({
281
- labelIds: z.array(z.string()),
282
- createdSpaces: z.boolean(),
283
- })
284
- export type PluginProgramLabelsCreateResult = z.infer<
285
- typeof PluginProgramLabelsCreateResult
286
- >
287
-
288
- /**
289
- * Arguments for {@linkcode PluginProgramLabelsApi.setTargetArea}.
290
- *
291
- * | Property | Type | Description |
292
- * |---|---|---|
293
- * | `labelId` | `string` | The label whose target to set |
294
- * | `targetArea` | `number` | Total target area, in `units` |
295
- * | `units` | `"ft2" \| "m2"?` | Unit of `targetArea` (defaults to the project's area units) |
296
- */
297
- export const PluginProgramLabelsSetTargetAreaArgs = z.object({
298
- labelId: z.string(),
299
- targetArea: z.number().finite().nonnegative(),
300
- units: PluginAreaUnit.optional(),
301
- })
302
- export type PluginProgramLabelsSetTargetAreaArgs = z.infer<
303
- typeof PluginProgramLabelsSetTargetAreaArgs
304
- >
305
-
306
- /** Result of {@linkcode PluginProgramLabelsApi.setTargetArea} — the updated record with `units`. */
307
- export const PluginProgramLabelsSetTargetAreaResult = PluginProgramLabelRecord
308
- export type PluginProgramLabelsSetTargetAreaResult = z.infer<
309
- typeof PluginProgramLabelsSetTargetAreaResult
310
- >
311
-
312
- /**
313
- * Arguments for {@linkcode PluginProgramLabelsApi.setTargetCount}.
314
- *
315
- * | Property | Type | Description |
316
- * |---|---|---|
317
- * | `labelId` | `string` | The label whose count to set |
318
- * | `targetCount` | `number` | Target number of units (non-negative integer) |
319
- */
320
- export const PluginProgramLabelsSetTargetCountArgs = z.object({
321
- labelId: z.string(),
322
- targetCount: z.number().int().nonnegative(),
323
- })
324
- export type PluginProgramLabelsSetTargetCountArgs = z.infer<
325
- typeof PluginProgramLabelsSetTargetCountArgs
326
- >
327
-
328
- /** Result of {@linkcode PluginProgramLabelsApi.setTargetCount} — the updated record with `units`. */
329
- export const PluginProgramLabelsSetTargetCountResult = PluginProgramLabelRecord
330
- export type PluginProgramLabelsSetTargetCountResult = z.infer<
331
- typeof PluginProgramLabelsSetTargetCountResult
332
- >
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import { PluginAreaUnit } from "./metrics"
4
+
5
+ /**
6
+ * Program labels — the **program rows** of the active program: each label is a
7
+ * named space type (e.g. "Exam Room", "Nurse Station") inside a department,
8
+ * carrying an area **target** and a unit **count** target.
9
+ *
10
+ * Labels are the non-department planning entities of program mode. A
11
+ * department groups labels; a label groups the spaces (masses) that realize it.
12
+ * Target areas live on **departments** ({@linkcode PluginProgramDepartmentsApi.setTargetArea})
13
+ * and on **labels** (this namespace) — an individual space carries no target of
14
+ * its own; it inherits its label's `targetArea / targetCount`. Program Blocks
15
+ * (spaces whose space type is "Program Block") are likewise targeted through
16
+ * their label.
17
+ *
18
+ * `targetArea` is the label's **total** target (all units), in the response's
19
+ * `units`; the per-unit target is `targetArea / targetCount`.
20
+ *
21
+ * Reads never throw for a miss (`get` returns `null`, `list` returns `[]`).
22
+ * Writes are undoable and autosaved; when the project has proposals they write
23
+ * the **active proposal's** targets.
24
+ *
25
+ * Accessed via `snaptrude.program.labels`.
26
+ */
27
+ export abstract class PluginProgramLabelsApi {
28
+ constructor() {}
29
+
30
+ /**
31
+ * List the labels (program rows) of the active program.
32
+ *
33
+ * @returns A {@linkcode PluginProgramLabelsListResult} with `units` and a
34
+ * `labels` array (empty when the project has none).
35
+ *
36
+ * @examplePrompt List all the program rows with their target areas
37
+ * @examplePrompt What space labels are in the program and how many of each?
38
+ * @examplePrompt Show every label with its department and target
39
+ *
40
+ * # Example
41
+ * ```ts
42
+ * const { units, labels } = await snaptrude.program.labels.list()
43
+ * for (const l of labels) console.log(l.name, l.targetArea, units, l.targetCount)
44
+ * ```
45
+ */
46
+ public abstract list(): PluginApiReturn<PluginProgramLabelsListResult>
47
+
48
+ /**
49
+ * Get a single label by id.
50
+ *
51
+ * @param labelId - The id of the label to read.
52
+ * @returns The matching {@linkcode PluginProgramLabelRecord} (with `units`), or
53
+ * `null` if no label has that id.
54
+ *
55
+ * @examplePrompt Get the label with id lbl_12
56
+ * @examplePrompt What is the target area of this program row?
57
+ *
58
+ * # Example
59
+ * ```ts
60
+ * const label = await snaptrude.program.labels.get("lbl_12")
61
+ * if (label) console.log(label.name, label.targetArea, label.units)
62
+ * ```
63
+ */
64
+ public abstract get(
65
+ labelId: string,
66
+ ): PluginApiReturn<PluginProgramLabelsGetResult>
67
+
68
+ /**
69
+ * Create labels (program rows), optionally creating their spaces too.
70
+ *
71
+ * Each item names a label and its targets. A label is unique per
72
+ * (`name`, department); an item matching an existing label **updates** that
73
+ * label's targets instead of duplicating it. Unknown departments are created
74
+ * by name when `departmentName` is given; omit both department fields for the
75
+ * Default department.
76
+ *
77
+ * By default only the program rows are created (targets to plan against).
78
+ * Pass `createSpaces: true` to also instantiate `targetCount` massing spaces
79
+ * per label on the canvas, laid out automatically — the same path Program
80
+ * Mode's CSV/Interpret import uses.
81
+ *
82
+ * @param items - The labels to create (1–500).
83
+ * @param options - Optional `units` for every `targetArea` (defaults to the
84
+ * project's area units) and `createSpaces` (default `false`).
85
+ * @returns A {@linkcode PluginProgramLabelsCreateResult} with the created or
86
+ * updated label ids, in input order.
87
+ * @throws If an item's `departmentId` does not exist.
88
+ *
89
+ * @examplePrompt Add program rows for 4 exam rooms of 120 sqft each
90
+ * @examplePrompt Create the labels from this interpreted program
91
+ * @examplePrompt Add an Office label with a 2000 sqft target to the Admin department
92
+ * @examplePrompt Create program rows and their spaces on the canvas
93
+ *
94
+ * # Example
95
+ * ```ts
96
+ * const { labelIds } = await snaptrude.program.labels.create(
97
+ * [{ name: "Exam Room", targetArea: 480, targetCount: 4, departmentName: "Clinic" }],
98
+ * { units: "ft2" },
99
+ * )
100
+ * ```
101
+ */
102
+ public abstract create(
103
+ items: PluginProgramLabelCreateItem[],
104
+ options?: { units?: PluginAreaUnit; createSpaces?: boolean },
105
+ ): PluginApiReturn<PluginProgramLabelsCreateResult>
106
+
107
+ /**
108
+ * Set a label's total target area.
109
+ *
110
+ * The goal the program metrics compare the label's allocated area against.
111
+ * Pass `units` to say what unit `targetArea` is in; it defaults to the
112
+ * project's area units. Read it back with {@linkcode PluginProgramLabelsApi.get}.
113
+ *
114
+ * @param labelId - The id of the label whose target to set.
115
+ * @param targetArea - The total target area (all units), in `units`.
116
+ * @param units - Unit of `targetArea` (defaults to the project's area units).
117
+ * @returns The updated {@linkcode PluginProgramLabelRecord} with its `units`.
118
+ * @throws If no label has the given id.
119
+ *
120
+ * @examplePrompt Set the Exam Room target area to 480 sqft
121
+ * @examplePrompt Give the Corridor program row a 150 sqm target
122
+ * @examplePrompt Update the area target for label lbl_12
123
+ *
124
+ * # Example
125
+ * ```ts
126
+ * await snaptrude.program.labels.setTargetArea("lbl_12", 480, "ft2")
127
+ * ```
128
+ */
129
+ public abstract setTargetArea(
130
+ labelId: string,
131
+ targetArea: number,
132
+ units?: PluginAreaUnit,
133
+ ): PluginApiReturn<PluginProgramLabelsSetTargetAreaResult>
134
+
135
+ /**
136
+ * Set a label's target unit count (how many of this space the program calls for).
137
+ *
138
+ * @param labelId - The id of the label whose count to set.
139
+ * @param targetCount - The target number of units (a non-negative integer).
140
+ * @returns The updated {@linkcode PluginProgramLabelRecord} with its `units`.
141
+ * @throws If no label has the given id.
142
+ *
143
+ * @examplePrompt Set the Exam Room count to 6
144
+ * @examplePrompt The program needs 12 patient rooms — update the count
145
+ *
146
+ * # Example
147
+ * ```ts
148
+ * await snaptrude.program.labels.setTargetCount("lbl_12", 6)
149
+ * ```
150
+ */
151
+ public abstract setTargetCount(
152
+ labelId: string,
153
+ targetCount: number,
154
+ ): PluginApiReturn<PluginProgramLabelsSetTargetCountResult>
155
+ }
156
+
157
+ /**
158
+ * A label (program row) in the active program. `targetArea` is the label's
159
+ * **total** target in the enclosing response's `units`.
160
+ *
161
+ * | Property | Type | Description |
162
+ * |---|---|---|
163
+ * | `id` | `string` | Stable label id |
164
+ * | `name` | `string` | Label (space type) name |
165
+ * | `color` | `string` | CSS hex color string |
166
+ * | `departmentId` | `string` | Id of the department the label belongs to |
167
+ * | `targetArea` | `number \| null` | Total target area (all units), or `null` when no target is set |
168
+ * | `targetCount` | `number` | Target number of units (`0` when unset) |
169
+ * | `storey` | `number \| null` | Default storey new spaces of this label are placed on |
170
+ */
171
+ export const PluginProgramLabel = z.object({
172
+ id: z.string(),
173
+ name: z.string(),
174
+ color: z.string(),
175
+ departmentId: z.string(),
176
+ targetArea: z.number().nullable(),
177
+ targetCount: z.number(),
178
+ storey: z.number().nullable(),
179
+ })
180
+ export type PluginProgramLabel = z.infer<typeof PluginProgramLabel>
181
+
182
+ /** A bare label record carrying its area `units` (per the area-units convention). */
183
+ export const PluginProgramLabelRecord = PluginProgramLabel.extend({
184
+ units: PluginAreaUnit,
185
+ })
186
+ export type PluginProgramLabelRecord = z.infer<typeof PluginProgramLabelRecord>
187
+
188
+ /**
189
+ * Result of {@linkcode PluginProgramLabelsApi.list}.
190
+ *
191
+ * | Property | Type | Description |
192
+ * |---|---|---|
193
+ * | `units` | `"ft2" \| "m2"` | The unit every `targetArea` below is reported in |
194
+ * | `labels` | {@linkcode PluginProgramLabel}`[]` | All labels in the active program |
195
+ */
196
+ export const PluginProgramLabelsListResult = z.object({
197
+ units: PluginAreaUnit,
198
+ labels: z.array(PluginProgramLabel),
199
+ })
200
+ export type PluginProgramLabelsListResult = z.infer<
201
+ typeof PluginProgramLabelsListResult
202
+ >
203
+
204
+ /** Arguments for {@linkcode PluginProgramLabelsApi.get}. */
205
+ export const PluginProgramLabelsGetArgs = z.object({
206
+ labelId: z.string(),
207
+ })
208
+ export type PluginProgramLabelsGetArgs = z.infer<
209
+ typeof PluginProgramLabelsGetArgs
210
+ >
211
+
212
+ /** Result of {@linkcode PluginProgramLabelsApi.get} — the record with `units`, or `null`. */
213
+ export const PluginProgramLabelsGetResult = PluginProgramLabelRecord.nullable()
214
+ export type PluginProgramLabelsGetResult = z.infer<
215
+ typeof PluginProgramLabelsGetResult
216
+ >
217
+
218
+ /**
219
+ * One label to create via {@linkcode PluginProgramLabelsApi.create}.
220
+ *
221
+ * | Property | Type | Description |
222
+ * |---|---|---|
223
+ * | `name` | `string` | Label (space type) name |
224
+ * | `targetArea` | `number?` | Total target area (all units), in the call's `units` |
225
+ * | `targetCount` | `number?` | Target number of units (default `1`) |
226
+ * | `departmentId` | `string?` | Existing department to file the label under |
227
+ * | `departmentName` | `string?` | Department by name — created when it does not exist (ignored when `departmentId` is given) |
228
+ * | `color` | `string?` | CSS hex color (a light color is generated when omitted) |
229
+ * | `storey` | `number?` | Storey for spaces of this label (default `1`) |
230
+ * | `height` | `number?` | Space height in project length units (for `createSpaces`) |
231
+ * | `width` | `number?` | Space width in project length units (for `createSpaces`) |
232
+ */
233
+ export const PluginProgramLabelCreateItem = z.object({
234
+ name: z.string().trim().min(1),
235
+ targetArea: z.number().finite().nonnegative().optional(),
236
+ targetCount: z.number().int().nonnegative().optional(),
237
+ departmentId: z.string().optional(),
238
+ departmentName: z.string().optional(),
239
+ color: z.string().optional(),
240
+ storey: z.number().int().optional(),
241
+ height: z.number().finite().positive().optional(),
242
+ width: z.number().finite().positive().optional(),
243
+ })
244
+ export type PluginProgramLabelCreateItem = z.infer<
245
+ typeof PluginProgramLabelCreateItem
246
+ >
247
+
248
+ /** Maximum items per {@linkcode PluginProgramLabelsApi.create} call. */
249
+ export const PLUGIN_PROGRAM_LABELS_BATCH_LIMIT = 500
250
+
251
+ /**
252
+ * Arguments for {@linkcode PluginProgramLabelsApi.create}.
253
+ *
254
+ * | Property | Type | Description |
255
+ * |---|---|---|
256
+ * | `items` | {@linkcode PluginProgramLabelCreateItem}`[]` | 1–500 labels |
257
+ * | `units` | `"ft2" \| "m2"?` | Unit of every `targetArea` (defaults to the project's area units) |
258
+ * | `createSpaces` | `boolean?` | Also create `targetCount` spaces per label on the canvas (default `false`) |
259
+ */
260
+ export const PluginProgramLabelsCreateArgs = z.object({
261
+ items: z
262
+ .array(PluginProgramLabelCreateItem)
263
+ .min(1)
264
+ .max(PLUGIN_PROGRAM_LABELS_BATCH_LIMIT),
265
+ units: PluginAreaUnit.optional(),
266
+ createSpaces: z.boolean().optional(),
267
+ })
268
+ export type PluginProgramLabelsCreateArgs = z.infer<
269
+ typeof PluginProgramLabelsCreateArgs
270
+ >
271
+
272
+ /**
273
+ * Result of {@linkcode PluginProgramLabelsApi.create}.
274
+ *
275
+ * | Property | Type | Description |
276
+ * |---|---|---|
277
+ * | `labelIds` | `string[]` | The created (or updated) label ids, in input order |
278
+ * | `createdSpaces` | `boolean` | Whether spaces were also created on the canvas |
279
+ */
280
+ export const PluginProgramLabelsCreateResult = z.object({
281
+ labelIds: z.array(z.string()),
282
+ createdSpaces: z.boolean(),
283
+ })
284
+ export type PluginProgramLabelsCreateResult = z.infer<
285
+ typeof PluginProgramLabelsCreateResult
286
+ >
287
+
288
+ /**
289
+ * Arguments for {@linkcode PluginProgramLabelsApi.setTargetArea}.
290
+ *
291
+ * | Property | Type | Description |
292
+ * |---|---|---|
293
+ * | `labelId` | `string` | The label whose target to set |
294
+ * | `targetArea` | `number` | Total target area, in `units` |
295
+ * | `units` | `"ft2" \| "m2"?` | Unit of `targetArea` (defaults to the project's area units) |
296
+ */
297
+ export const PluginProgramLabelsSetTargetAreaArgs = z.object({
298
+ labelId: z.string(),
299
+ targetArea: z.number().finite().nonnegative(),
300
+ units: PluginAreaUnit.optional(),
301
+ })
302
+ export type PluginProgramLabelsSetTargetAreaArgs = z.infer<
303
+ typeof PluginProgramLabelsSetTargetAreaArgs
304
+ >
305
+
306
+ /** Result of {@linkcode PluginProgramLabelsApi.setTargetArea} — the updated record with `units`. */
307
+ export const PluginProgramLabelsSetTargetAreaResult = PluginProgramLabelRecord
308
+ export type PluginProgramLabelsSetTargetAreaResult = z.infer<
309
+ typeof PluginProgramLabelsSetTargetAreaResult
310
+ >
311
+
312
+ /**
313
+ * Arguments for {@linkcode PluginProgramLabelsApi.setTargetCount}.
314
+ *
315
+ * | Property | Type | Description |
316
+ * |---|---|---|
317
+ * | `labelId` | `string` | The label whose count to set |
318
+ * | `targetCount` | `number` | Target number of units (non-negative integer) |
319
+ */
320
+ export const PluginProgramLabelsSetTargetCountArgs = z.object({
321
+ labelId: z.string(),
322
+ targetCount: z.number().int().nonnegative(),
323
+ })
324
+ export type PluginProgramLabelsSetTargetCountArgs = z.infer<
325
+ typeof PluginProgramLabelsSetTargetCountArgs
326
+ >
327
+
328
+ /** Result of {@linkcode PluginProgramLabelsApi.setTargetCount} — the updated record with `units`. */
329
+ export const PluginProgramLabelsSetTargetCountResult = PluginProgramLabelRecord
330
+ export type PluginProgramLabelsSetTargetCountResult = z.infer<
331
+ typeof PluginProgramLabelsSetTargetCountResult
332
+ >