@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,308 +1,311 @@
1
- import * as z from "zod"
2
- import { PluginApiReturn } from "../../../types"
3
- import { ComponentHandle } from "../../../handles"
4
- import {
5
- PluginStoryGetProperty,
6
- PluginStoryGetResult,
7
- PluginStoryGetAllResult,
8
- PluginStoryCreateResult,
9
- PluginStoryUpdateResult,
10
- PluginStorySetActiveResult,
11
- PluginStoryDeleteResult,
12
- PluginStoryDuplicateResult,
13
- } from "../../entity/story"
14
- import { PluginCoreStoreysLayersApi } from "./layers"
15
-
16
- /**
17
- * Storey (floor) management.
18
- *
19
- * A storey represents a building floor in the Snaptrude project. Storeys are
20
- * identified by their integer **storey value** (e.g. `1` for the ground floor,
21
- * `2` for the first floor, `-1` for a basement).
22
- *
23
- * This is the canonical home for storey operations; it shares its implementation
24
- * and schemas with the deprecated `entity.story` surface. All methods are **host
25
- * API calls** that return Promises and support undo/redo via Snaptrude's command
26
- * system (except {@linkcode PluginCoreStoreysApi.setActive}, a view change).
27
- *
28
- * - {@linkcode PluginCoreStoreysApi.layers} — each storey's sketch surfaces
29
- * (Wall, Rough) and imported underlays (CAD, PDF, image, terrain): list, get,
30
- * active layer get/set, show/hide. Not the Layers panel; that is `core.layers`.
31
- *
32
- * Accessed via `snaptrude.core.storeys`.
33
- */
34
- export abstract class PluginCoreStoreysApi {
35
- constructor() {}
36
-
37
- /**
38
- * Storey layers — each storey's sketch surfaces and imported underlays (ids
39
- * like `ly_5`), formerly `core.layers`. Not the layers in the Layers panel;
40
- * use `core.layers` for those. See {@linkcode PluginCoreStoreysLayersApi}.
41
- */
42
- public abstract layers: PluginCoreStoreysLayersApi
43
-
44
- /**
45
- * Get properties of a storey by its storey number.
46
- *
47
- * Only the properties listed in `properties` are returned — unlisted
48
- * properties will be `undefined` in the result.
49
- *
50
- * @param storyValue - Integer storey number
51
- * (e.g. `1` for ground floor, `2` for first floor, `-1` for basement)
52
- * @param properties - Array of property names to retrieve. See
53
- * {@linkcode PluginStoryGetProperty} for available values.
54
- * @returns A partial {@linkcode PluginStoryGetResult} containing only the requested properties
55
- * @throws If the storey with the given value does not exist
56
- *
57
- * @examplePrompt What is the height of the ground floor?
58
- * @examplePrompt How many rooms are on the second storey?
59
- * @examplePrompt Get the total floor area of level 3
60
- * @examplePrompt Is the first floor hidden in the viewport?
61
- * @examplePrompt Show me the name and height of storey 2
62
- *
63
- * # Example
64
- * ```ts
65
- * const info = await snaptrude.core.storeys.get(1, ["height", "name", "spacesCount"])
66
- * console.log(info.name, info.height, info.spacesCount)
67
- * ```
68
- */
69
- public abstract get(
70
- storyValue: number,
71
- properties: PluginStoryGetProperty[],
72
- ): PluginApiReturn<PluginStoryGetResult>
73
-
74
- /**
75
- * List all storeys in the current project.
76
- *
77
- * Returns basic identification data for every storey. Storeys are sorted
78
- * from **top to bottom** (highest storey value first).
79
- *
80
- * @returns A {@linkcode PluginCoreStoreysListResult} with a `storeys` array,
81
- * each entry containing `value`, `id`, and `name`
82
- *
83
- * @examplePrompt How many floors does this building have?
84
- * @examplePrompt List all the storeys in the project
85
- * @examplePrompt Show me every level with its name
86
- * @examplePrompt Which storeys exist in this model?
87
- *
88
- * # Example
89
- * ```ts
90
- * const { storeys } = await snaptrude.core.storeys.list()
91
- * for (const s of storeys) {
92
- * console.log(`Storey ${s.value}: ${s.name} (id: ${s.id})`)
93
- * }
94
- * ```
95
- */
96
- public abstract list(): PluginApiReturn<PluginCoreStoreysListResult>
97
-
98
- /**
99
- * Create a new storey (floor) in the project.
100
- *
101
- * The new storey is inserted at the position specified by `storyValue`. This
102
- * operation is undoable.
103
- *
104
- * @param storyValue - Integer storey number
105
- * to create (e.g. `3` to add a third floor)
106
- * @param height - Optional height in Babylon
107
- * units. If omitted, the project's default storey height is used.
108
- * @returns A {@linkcode PluginStoryCreateResult} with `storyId` and `storyValue`
109
- * @throws If a storey with the given value already exists or creation fails
110
- *
111
- * @examplePrompt Add a third floor to the building
112
- * @examplePrompt Create a new storey above the second floor
113
- * @examplePrompt Add a basement level to this project
114
- * @examplePrompt Insert a new level with a custom floor height
115
- *
116
- * # Example
117
- * ```ts
118
- * // Create a new third floor with custom height
119
- * const { storyId } = await snaptrude.core.storeys.create(3, 4.5)
120
- * ```
121
- */
122
- public abstract create(
123
- storyValue: number,
124
- height?: number,
125
- ): PluginApiReturn<PluginStoryCreateResult>
126
-
127
- /**
128
- * Update a storey's floor-to-floor `height` and/or `name`.
129
- *
130
- * **Height** is the same operation as editing the height in the Storeys panel:
131
- * the walls, columns, and masses on the storey are **stretched** to the new
132
- * height, every storey **above shifts up/down** by the delta so the stack stays
133
- * contiguous, and coupled elements (staircases, parametric curtain walls,
134
- * furniture offsets) are re-fitted. The whole height cascade is committed as
135
- * **one undo step**. Height-locked elements are left untouched.
136
- *
137
- * **Name** is the same as renaming the storey in the Storeys panel: it is
138
- * persisted immediately but, mirroring the panel, is **not** part of the height
139
- * undo step.
140
- *
141
- * At least one of `height` or `options.name` must be supplied. Omitting the
142
- * `height` argument (e.g. for a rename-only update) leaves the height untouched.
143
- *
144
- * @param storyValue - Integer storey number identifying the storey to update
145
- * @param height - New floor-to-floor height in
146
- * Babylon units. Omit to leave the height unchanged.
147
- * @param options - `name` (new display name for the storey)
148
- * @returns A {@linkcode PluginStoryUpdateResult} with the storey's
149
- * `storyValue`, `height`, and `name` after the update
150
- * @throws `PRECONDITION_FAILED` if no storey has the given value;
151
- * `VALIDATION` if neither `height` nor `options.name` is supplied;
152
- * `STORY_HEIGHT_REJECTED` if the engine rejects the height;
153
- * `STORY_UPDATE_FAILED` if the storey cannot be re-read after the update
154
- *
155
- * @examplePrompt Change the ground floor height to 3.5 metres
156
- * @examplePrompt Make the second storey taller
157
- * @examplePrompt Rename the ground floor to "Lobby"
158
- * @examplePrompt Set the floor-to-floor height of level 1
159
- *
160
- * # Example
161
- * ```ts
162
- * // Set ground floor height to 5 Babylon units — walls stretch and the
163
- * // floors above move up to match, all in a single undo step.
164
- * const result = await snaptrude.core.storeys.update(1, 5)
165
- * // Rename only, leaving the height untouched.
166
- * await snaptrude.core.storeys.update(1, undefined, { name: "Lobby" })
167
- * ```
168
- */
169
- public abstract update(
170
- storyValue: number,
171
- height?: number,
172
- options?: { name?: string },
173
- ): PluginApiReturn<PluginStoryUpdateResult>
174
-
175
- /**
176
- * Get the active storey's value. Paired with {@linkcode PluginCoreStoreysApi.setActive}.
177
- *
178
- * @returns The active storey value, in the same numbering `list` and `get` use.
179
- *
180
- * @examplePrompt Which storey am I on?
181
- * @examplePrompt What is the current storey?
182
- *
183
- * # Example
184
- * ```ts
185
- * const storey = await snaptrude.core.storeys.getActive()
186
- * ```
187
- */
188
- public abstract getActive(): PluginApiReturn<number>
189
-
190
- /**
191
- * Make a storey the active storey — the same as clicking it in the storey/layer
192
- * panel. Subsequent draws and creates target this storey, and in 2D the
193
- * viewport switches to it. This is a view/navigation change: it is **not**
194
- * undoable and commits nothing to the model.
195
- *
196
- * @param storyValue - Integer storey number to activate
197
- * @returns A {@linkcode PluginStorySetActiveResult} echoing the now-active `storyValue`
198
- * @throws `PRECONDITION_FAILED` if no storey has the given value
199
- *
200
- * @examplePrompt Switch to the second floor
201
- * @examplePrompt Make the ground storey active
202
- * @examplePrompt Go to the basement level
203
- * @examplePrompt Set level 3 as the current storey
204
- *
205
- * # Example
206
- * ```ts
207
- * // Activate storey 2, then draw a wall — it lands on storey 2.
208
- * await snaptrude.core.storeys.setActive(2)
209
- * ```
210
- */
211
- public abstract setActive(
212
- storyValue: number,
213
- ): PluginApiReturn<PluginStorySetActiveResult>
214
-
215
- /**
216
- * Delete a storey and everything on it — the same as removing it from the
217
- * storey panel. Every element placed on the storey (walls, floors, masses, …)
218
- * is deleted with it, the remaining storeys are re-stacked, and the active
219
- * storey falls back to an adjacent one. Committed as a single undo step.
220
- *
221
- * @param storyValue - Integer storey number to delete
222
- * @returns A {@linkcode PluginStoryDeleteResult} with the deleted `storyValue`
223
- * and the `newActiveStory` the editor fell back to
224
- * @throws `PRECONDITION_FAILED` if no storey has the given value; or if plugin
225
- * writes are disabled
226
- *
227
- * @examplePrompt Delete the top floor
228
- * @examplePrompt Remove the basement level
229
- * @examplePrompt Get rid of storey 3
230
- * @examplePrompt Delete the second floor and everything on it
231
- *
232
- * # Example
233
- * ```ts
234
- * const { newActiveStory } = await snaptrude.core.storeys.delete(3)
235
- * console.log(`Deleted storey 3; now on storey ${newActiveStory}`)
236
- * ```
237
- */
238
- public abstract delete(
239
- storyValue: number,
240
- ): PluginApiReturn<PluginStoryDeleteResult>
241
-
242
- /**
243
- * Copy a storey into the adjacent level, up or down.
244
- *
245
- * By default the **whole storey** is copied: every eligible element on the
246
- * active storey (walls, floors, roofs, masses, columns, beams, staircases,
247
- * ceilings, parametric curtain walls, and furniture) is copied into the storey
248
- * one level `"up"` or `"down"`. Pass `options.components` to copy only a subset
249
- * instead. The target storey is **created automatically** if it does not yet
250
- * exist, inheriting the source storey's height.
251
- *
252
- * Copies are **instanced** by default (`unique: false`) — they share geometry
253
- * with the source, so later edits propagate. Set `unique: true` for independent
254
- * geometry. Doors and windows are never copied on their own; they ride along
255
- * with their host wall. Locked, throw-away, and unsupported elements are skipped
256
- * and counted in `skipped`. The whole operation is a single undo step.
257
- *
258
- * @param direction - `"up"` to copy into the storey above, `"down"` for below
259
- * @param options - `components` (restrict to a subset of the storey's elements;
260
- * omit for the whole storey) and `unique` (default `false` = instanced copies;
261
- * `true` = independent geometry)
262
- * @returns A {@linkcode PluginStoryDuplicateResult} with the `sourceStory`, the
263
- * `targetStories` the copies landed on, the `created` component handles, the
264
- * `createdStoryValues` for any storeys generated to receive them, and the
265
- * `skipped` count of ineligible elements
266
- * @throws `NO_ACTIVE_STRUCTURE` if there is no active structure to copy into;
267
- * `NO_ELIGIBLE_ELEMENTS` if nothing on the source storey (or in
268
- * `options.components`) is copyable; `HANDLE_INVALID` for a stale or foreign
269
- * supplied handle; or if plugin writes are disabled
270
- *
271
- * @examplePrompt Copy this floor to the storey above
272
- * @examplePrompt Copy the ground floor down into a new basement
273
- * @examplePrompt Repeat this level upwards with its own independent geometry
274
- * @examplePrompt Copy just the selected walls onto the next floor up
275
- *
276
- * # Example
277
- * ```ts
278
- * // Copy the whole active storey one level up (instanced copies).
279
- * const { targetStories, created, skipped } =
280
- * await snaptrude.core.storeys.copy("up")
281
- * console.log(`Copied ${created.length} elements onto storey ${targetStories}`)
282
- * if (skipped) console.log(`${skipped} elements were skipped`)
283
- * ```
284
- */
285
- public abstract copy(
286
- direction: "up" | "down",
287
- options?: { components?: ComponentHandle[]; unique?: boolean },
288
- ): PluginApiReturn<PluginStoryDuplicateResult>
289
- }
290
-
291
- /**
292
- * Result of {@linkcode PluginCoreStoreysApi.list} — the {@linkcode PluginStoryGetAllResult}
293
- * shape with the array field renamed `stories` → `storeys`. Each entry shares the
294
- * same element type: `{ value, id, name }`, sorted top to bottom.
295
- *
296
- * | Property | Type | Description |
297
- * |---|---|---|
298
- * | `storeys` | `Array<{ value, id, name }>` | All storeys, sorted top to bottom |
299
- */
300
- export const PluginCoreStoreysListResult = z.object({
301
- storeys: PluginStoryGetAllResult.shape.stories,
302
- })
303
-
304
- export type PluginCoreStoreysListResult = z.infer<
305
- typeof PluginCoreStoreysListResult
306
- >
307
-
308
- export * from "./layers"
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../../types"
3
+ import { ComponentHandle } from "../../../handles"
4
+ import {
5
+ PluginStoryGetProperty,
6
+ PluginStoryGetResult,
7
+ PluginStoryGetAllResult,
8
+ PluginStoryCreateResult,
9
+ PluginStoryUpdateResult,
10
+ PluginStorySetActiveResult,
11
+ PluginStoryDeleteResult,
12
+ PluginStoryDuplicateResult,
13
+ } from "../../entity/story"
14
+ import { PluginCoreStoreysLayersApi } from "./layers"
15
+
16
+ /**
17
+ * Storey (floor) management.
18
+ *
19
+ * A storey represents a building floor in the Snaptrude project. Storeys are
20
+ * identified by their integer **storey value** (e.g. `1` for the ground floor,
21
+ * `2` for the first floor, `-1` for a basement).
22
+ *
23
+ * This is the canonical home for storey operations; it shares its implementation
24
+ * and schemas with the deprecated `entity.story` surface. All methods are **host
25
+ * API calls** that return Promises and support undo/redo via Snaptrude's command
26
+ * system (except {@linkcode PluginCoreStoreysApi.setActive}, a view change).
27
+ *
28
+ * - {@linkcode PluginCoreStoreysApi.layers} — each storey's sketch surfaces
29
+ * (Wall, Rough) and imported underlays (CAD, PDF, image, terrain): list, get,
30
+ * active layer get/set, show/hide. Not the Layers panel; that is `core.layers`.
31
+ *
32
+ * Accessed via `snaptrude.core.storeys`.
33
+ */
34
+ export abstract class PluginCoreStoreysApi {
35
+ constructor() {}
36
+
37
+ /**
38
+ * Storey layers — each storey's sketch surfaces and imported underlays (ids
39
+ * like `ly_5`), formerly `core.layers`. Not the layers in the Layers panel;
40
+ * use `core.layers` for those. See {@linkcode PluginCoreStoreysLayersApi}.
41
+ */
42
+ public abstract layers: PluginCoreStoreysLayersApi
43
+
44
+ /**
45
+ * Get properties of a storey by its storey number.
46
+ *
47
+ * Only the properties listed in `properties` are returned — unlisted
48
+ * properties will be `undefined` in the result.
49
+ *
50
+ * @param storyValue - Integer storey number
51
+ * (e.g. `1` for ground floor, `2` for first floor, `-1` for basement)
52
+ * @param properties - Array of property names to retrieve. See
53
+ * {@linkcode PluginStoryGetProperty} for available values.
54
+ * @returns A partial {@linkcode PluginStoryGetResult} containing only the requested properties
55
+ * @throws If the storey with the given value does not exist
56
+ *
57
+ * @examplePrompt What is the height of the ground floor?
58
+ * @examplePrompt How many rooms are on the second storey?
59
+ * @examplePrompt Get the total floor area of level 3
60
+ * @examplePrompt Is the first floor hidden in the viewport?
61
+ * @examplePrompt Show me the name and height of storey 2
62
+ *
63
+ * # Example
64
+ * ```ts
65
+ * const info = await snaptrude.core.storeys.get(1, ["height", "name", "spacesCount"])
66
+ * console.log(info.name, info.height, info.spacesCount)
67
+ * ```
68
+ */
69
+ public abstract get(
70
+ storyValue: number,
71
+ properties: PluginStoryGetProperty[],
72
+ ): PluginApiReturn<PluginStoryGetResult>
73
+
74
+ /**
75
+ * List all storeys in the current project.
76
+ *
77
+ * Returns basic identification data for every storey. Storeys are sorted
78
+ * from **top to bottom** (highest storey value first).
79
+ *
80
+ * @returns A {@linkcode PluginCoreStoreysListResult} with a `storeys` array,
81
+ * each entry containing `value`, `id`, and `name`
82
+ *
83
+ * @examplePrompt How many floors does this building have?
84
+ * @examplePrompt List all the storeys in the project
85
+ * @examplePrompt Show me every level with its name
86
+ * @examplePrompt Which storeys exist in this model?
87
+ *
88
+ * # Example
89
+ * ```ts
90
+ * const { storeys } = await snaptrude.core.storeys.list()
91
+ * for (const s of storeys) {
92
+ * console.log(`Storey ${s.value}: ${s.name} (id: ${s.id})`)
93
+ * }
94
+ * ```
95
+ */
96
+ public abstract list(): PluginApiReturn<PluginCoreStoreysListResult>
97
+
98
+ /**
99
+ * Create a new storey (floor) in the project.
100
+ *
101
+ * The new storey is inserted at the position specified by `storyValue`. This
102
+ * operation is undoable.
103
+ *
104
+ * @param storyValue - Integer storey number
105
+ * to create (e.g. `3` to add a third floor)
106
+ * @param height - Optional height in Babylon
107
+ * units. If omitted, the project's default storey height is used.
108
+ * @returns A {@linkcode PluginStoryCreateResult} with `storyId` and `storyValue`
109
+ * @throws If a storey with the given value already exists or creation fails
110
+ *
111
+ * @examplePrompt Add a third floor to the building
112
+ * @examplePrompt Create a new storey above the second floor
113
+ * @examplePrompt Add a basement level to this project
114
+ * @examplePrompt Insert a new level with a custom floor height
115
+ *
116
+ * # Example
117
+ * ```ts
118
+ * // Create a new third floor with custom height
119
+ * const { storyId } = await snaptrude.core.storeys.create(3, 4.5)
120
+ * ```
121
+ */
122
+ public abstract create(
123
+ storyValue: number,
124
+ height?: number,
125
+ ): PluginApiReturn<PluginStoryCreateResult>
126
+
127
+ /**
128
+ * Update a storey's floor-to-floor `height` and/or `name`.
129
+ *
130
+ * **Height** is the same operation as editing the height in the Storeys panel:
131
+ * the walls, columns, and masses on the storey are **stretched** to the new
132
+ * height, every storey **above shifts up/down** by the delta so the stack stays
133
+ * contiguous, and coupled elements (staircases, parametric curtain walls,
134
+ * furniture offsets) are re-fitted. The whole height cascade is committed as
135
+ * **one undo step**. Height-locked elements are left untouched.
136
+ *
137
+ * **Name** is the same as renaming the storey in the Storeys panel: it is
138
+ * persisted immediately but, mirroring the panel, is **not** part of the height
139
+ * undo step.
140
+ *
141
+ * At least one of `height` or `options.name` must be supplied. Omitting the
142
+ * `height` argument (e.g. for a rename-only update) leaves the height untouched.
143
+ *
144
+ * @param storyValue - Integer storey number identifying the storey to update
145
+ * @param height - New floor-to-floor height in
146
+ * Babylon units. Omit to leave the height unchanged.
147
+ * @param options - `name` (new display name for the storey)
148
+ * @returns A {@linkcode PluginStoryUpdateResult} with the storey's
149
+ * `storyValue`, `height`, and `name` after the update
150
+ * @throws `PRECONDITION_FAILED` if no storey has the given value;
151
+ * `VALIDATION` if neither `height` nor `options.name` is supplied;
152
+ * `STORY_HEIGHT_REJECTED` if the engine rejects the height;
153
+ * `STORY_UPDATE_FAILED` if the storey cannot be re-read after the update
154
+ *
155
+ * @examplePrompt Change the ground floor height to 3.5 metres
156
+ * @examplePrompt Make the second storey taller
157
+ * @examplePrompt Rename the ground floor to "Lobby"
158
+ * @examplePrompt Set the floor-to-floor height of level 1
159
+ *
160
+ * # Example
161
+ * ```ts
162
+ * // Set ground floor height to 5 Babylon units — walls stretch and the
163
+ * // floors above move up to match, all in a single undo step.
164
+ * const result = await snaptrude.core.storeys.update(1, 5)
165
+ * // Rename only, leaving the height untouched.
166
+ * await snaptrude.core.storeys.update(1, undefined, { name: "Lobby" })
167
+ * ```
168
+ */
169
+ public abstract update(
170
+ storyValue: number,
171
+ height?: number,
172
+ options?: { name?: string },
173
+ ): PluginApiReturn<PluginStoryUpdateResult>
174
+
175
+ /**
176
+ * Get the active storey's value. Paired with {@linkcode PluginCoreStoreysApi.setActive}.
177
+ *
178
+ * @returns The active storey value, in the same numbering `list` and `get` use.
179
+ *
180
+ * @examplePrompt Which storey am I on?
181
+ * @examplePrompt What is the current storey?
182
+ *
183
+ * # Example
184
+ * ```ts
185
+ * const storey = await snaptrude.core.storeys.getActive()
186
+ * ```
187
+ */
188
+ public abstract getActive(): PluginApiReturn<number>
189
+
190
+ /**
191
+ * Make a storey the active storey — the same as clicking it in the storey/layer
192
+ * panel. Subsequent draws and creates target this storey, and in 2D the
193
+ * viewport switches to that storey's plan (and its cut range), unless the
194
+ * active view is already a plan on it.
195
+ * This is a view/navigation change: it is **not**
196
+ * undoable and commits nothing to the model.
197
+ *
198
+ * @param storyValue - Integer storey number to activate
199
+ * @returns A {@linkcode PluginStorySetActiveResult} echoing the now-active `storyValue`
200
+ * @throws `PRECONDITION_FAILED` if no storey has the given value, or in 2D if
201
+ * the storey has no plan
202
+ *
203
+ * @examplePrompt Switch to the second floor
204
+ * @examplePrompt Make the ground storey active
205
+ * @examplePrompt Go to the basement level
206
+ * @examplePrompt Set level 3 as the current storey
207
+ *
208
+ * # Example
209
+ * ```ts
210
+ * // Activate storey 2, then draw a wall — it lands on storey 2.
211
+ * await snaptrude.core.storeys.setActive(2)
212
+ * ```
213
+ */
214
+ public abstract setActive(
215
+ storyValue: number,
216
+ ): PluginApiReturn<PluginStorySetActiveResult>
217
+
218
+ /**
219
+ * Delete a storey and everything on it — the same as removing it from the
220
+ * storey panel. Every element placed on the storey (walls, floors, masses, …)
221
+ * is deleted with it, the remaining storeys are re-stacked, and the active
222
+ * storey falls back to an adjacent one. Committed as a single undo step.
223
+ *
224
+ * @param storyValue - Integer storey number to delete
225
+ * @returns A {@linkcode PluginStoryDeleteResult} with the deleted `storyValue`
226
+ * and the `newActiveStory` the editor fell back to
227
+ * @throws `PRECONDITION_FAILED` if no storey has the given value; or if plugin
228
+ * writes are disabled
229
+ *
230
+ * @examplePrompt Delete the top floor
231
+ * @examplePrompt Remove the basement level
232
+ * @examplePrompt Get rid of storey 3
233
+ * @examplePrompt Delete the second floor and everything on it
234
+ *
235
+ * # Example
236
+ * ```ts
237
+ * const { newActiveStory } = await snaptrude.core.storeys.delete(3)
238
+ * console.log(`Deleted storey 3; now on storey ${newActiveStory}`)
239
+ * ```
240
+ */
241
+ public abstract delete(
242
+ storyValue: number,
243
+ ): PluginApiReturn<PluginStoryDeleteResult>
244
+
245
+ /**
246
+ * Copy a storey into the adjacent level, up or down.
247
+ *
248
+ * By default the **whole storey** is copied: every eligible element on the
249
+ * active storey (walls, floors, roofs, masses, columns, beams, staircases,
250
+ * ceilings, parametric curtain walls, and furniture) is copied into the storey
251
+ * one level `"up"` or `"down"`. Pass `options.components` to copy only a subset
252
+ * instead. The target storey is **created automatically** if it does not yet
253
+ * exist, inheriting the source storey's height.
254
+ *
255
+ * Copies are **instanced** by default (`unique: false`) — they share geometry
256
+ * with the source, so later edits propagate. Set `unique: true` for independent
257
+ * geometry. Doors and windows are never copied on their own; they ride along
258
+ * with their host wall. Locked, throw-away, and unsupported elements are skipped
259
+ * and counted in `skipped`. The whole operation is a single undo step.
260
+ *
261
+ * @param direction - `"up"` to copy into the storey above, `"down"` for below
262
+ * @param options - `components` (restrict to a subset of the storey's elements;
263
+ * omit for the whole storey) and `unique` (default `false` = instanced copies;
264
+ * `true` = independent geometry)
265
+ * @returns A {@linkcode PluginStoryDuplicateResult} with the `sourceStory`, the
266
+ * `targetStories` the copies landed on, the `created` component handles, the
267
+ * `createdStoryValues` for any storeys generated to receive them, and the
268
+ * `skipped` count of ineligible elements
269
+ * @throws `NO_ACTIVE_STRUCTURE` if there is no active structure to copy into;
270
+ * `NO_ELIGIBLE_ELEMENTS` if nothing on the source storey (or in
271
+ * `options.components`) is copyable; `HANDLE_INVALID` for a stale or foreign
272
+ * supplied handle; or if plugin writes are disabled
273
+ *
274
+ * @examplePrompt Copy this floor to the storey above
275
+ * @examplePrompt Copy the ground floor down into a new basement
276
+ * @examplePrompt Repeat this level upwards with its own independent geometry
277
+ * @examplePrompt Copy just the selected walls onto the next floor up
278
+ *
279
+ * # Example
280
+ * ```ts
281
+ * // Copy the whole active storey one level up (instanced copies).
282
+ * const { targetStories, created, skipped } =
283
+ * await snaptrude.core.storeys.copy("up")
284
+ * console.log(`Copied ${created.length} elements onto storey ${targetStories}`)
285
+ * if (skipped) console.log(`${skipped} elements were skipped`)
286
+ * ```
287
+ */
288
+ public abstract copy(
289
+ direction: "up" | "down",
290
+ options?: { components?: ComponentHandle[]; unique?: boolean },
291
+ ): PluginApiReturn<PluginStoryDuplicateResult>
292
+ }
293
+
294
+ /**
295
+ * Result of {@linkcode PluginCoreStoreysApi.list} — the {@linkcode PluginStoryGetAllResult}
296
+ * shape with the array field renamed `stories` → `storeys`. Each entry shares the
297
+ * same element type: `{ value, id, name }`, sorted top to bottom.
298
+ *
299
+ * | Property | Type | Description |
300
+ * |---|---|---|
301
+ * | `storeys` | `Array<{ value, id, name }>` | All storeys, sorted top to bottom |
302
+ */
303
+ export const PluginCoreStoreysListResult = z.object({
304
+ storeys: PluginStoryGetAllResult.shape.stories,
305
+ })
306
+
307
+ export type PluginCoreStoreysListResult = z.infer<
308
+ typeof PluginCoreStoreysListResult
309
+ >
310
+
311
+ export * from "./layers"