@snaptrude/plugin-core 0.9.16 → 0.9.18-networks-20261016.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.
- package/AGENTS.md +231 -231
- package/CHANGELOG.md +408 -402
- package/CLAUDE.md +11 -11
- package/dist/api/analysis/daylight.d.ts +5 -5
- package/dist/api/analysis/solar.d.ts +2 -2
- package/dist/api/core/camera/index.d.ts +29 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +7 -1
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/geom/update/contour.d.ts +8 -2
- package/dist/api/core/geom/update/contour.d.ts.map +1 -1
- package/dist/api/core/zoom/index.d.ts +13 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/bim.d.ts +209 -0
- package/dist/api/design/bim.d.ts.map +1 -0
- package/dist/api/design/boolean/index.d.ts +2 -0
- package/dist/api/design/boolean/index.d.ts.map +1 -1
- package/dist/api/design/catalog.d.ts +320 -0
- package/dist/api/design/catalog.d.ts.map +1 -0
- package/dist/api/design/create/bulk-items.d.ts +65 -25
- package/dist/api/design/create/bulk-items.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +272 -99
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/create/opening-fields.d.ts +13 -12
- package/dist/api/design/create/opening-fields.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +1 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/doors/index.d.ts +18 -24
- package/dist/api/design/doors/index.d.ts.map +1 -1
- package/dist/api/design/family.d.ts +797 -27
- package/dist/api/design/family.d.ts.map +1 -1
- package/dist/api/design/index.d.ts +16 -0
- package/dist/api/design/index.d.ts.map +1 -1
- package/dist/api/design/networks.d.ts +1763 -0
- package/dist/api/design/networks.d.ts.map +1 -0
- package/dist/api/design/query/index.d.ts +42 -32
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/selection/index.d.ts +10 -10
- package/dist/api/design/types/index.d.ts +40 -24
- package/dist/api/design/types/index.d.ts.map +1 -1
- package/dist/api/design/update/index.d.ts +43 -3
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/design/windows/index.d.ts +8 -8
- package/dist/api/design/windows/index.d.ts.map +1 -1
- package/dist/api/presentation/aiInspiration.d.ts +10 -10
- package/dist/api/presentation/annotate.d.ts +38 -22
- package/dist/api/presentation/annotate.d.ts.map +1 -1
- package/dist/api/presentation/drawingContract.d.ts +32 -0
- package/dist/api/presentation/drawingContract.d.ts.map +1 -0
- package/dist/api/presentation/drawings.d.ts +3523 -0
- package/dist/api/presentation/drawings.d.ts.map +1 -0
- package/dist/api/presentation/export.d.ts +23 -5
- package/dist/api/presentation/export.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +41 -12
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +106 -6
- package/dist/api/presentation/placedViews.d.ts.map +1 -1
- package/dist/api/presentation/sections.d.ts +461 -0
- package/dist/api/presentation/sections.d.ts.map +1 -0
- package/dist/api/presentation/shapes.d.ts +2 -2
- package/dist/api/presentation/sheets.d.ts +175 -19
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/api/presentation/viewPresets.d.ts +222 -0
- package/dist/api/presentation/viewPresets.d.ts.map +1 -0
- package/dist/api/presentation/views.d.ts +103 -5
- package/dist/api/presentation/views.d.ts.map +1 -1
- package/dist/api/presentation/walkthroughs.d.ts +6 -6
- package/dist/errors/codes.d.ts +3 -1
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/index.cjs +3788 -2328
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3650 -2328
- package/dist/index.js.map +1 -1
- package/package.json +42 -42
- package/scripts/check-dist-fresh.mjs +22 -22
- package/scripts/generate-manifest.mjs +243 -238
- package/scripts/generate-manifest.test.mjs +303 -303
- package/src/api/analysis/daylight.ts +470 -470
- package/src/api/analysis/heatmaps.ts +683 -683
- package/src/api/analysis/illuminance.ts +155 -155
- package/src/api/analysis/index.ts +61 -61
- package/src/api/analysis/shadows.ts +183 -183
- package/src/api/analysis/solar.ts +237 -237
- package/src/api/analysis/sunlightHours.ts +211 -211
- package/src/api/analysis/sunpath.ts +83 -83
- package/src/api/analysis/weather.ts +179 -179
- package/src/api/core/buildings.ts +485 -485
- package/src/api/core/camera/index.ts +696 -667
- package/src/api/core/comment/index.ts +376 -376
- package/src/api/core/geom/create/index.ts +2139 -2133
- package/src/api/core/geom/delete/index.ts +84 -84
- package/src/api/core/geom/index.ts +35 -35
- package/src/api/core/geom/query/arc.ts +169 -169
- package/src/api/core/geom/query/brep.ts +621 -621
- package/src/api/core/geom/query/circle.ts +404 -404
- package/src/api/core/geom/query/contour.ts +540 -540
- package/src/api/core/geom/query/curve.ts +1102 -1102
- package/src/api/core/geom/query/edge.ts +130 -130
- package/src/api/core/geom/query/face.ts +508 -508
- package/src/api/core/geom/query/halfedge.ts +210 -210
- package/src/api/core/geom/query/index.ts +63 -63
- package/src/api/core/geom/query/profile.ts +473 -473
- package/src/api/core/geom/query/vertex.ts +205 -205
- package/src/api/core/geom/update/contour.ts +323 -317
- package/src/api/core/geom/update/curve.ts +209 -209
- package/src/api/core/geom/update/index.ts +29 -29
- package/src/api/core/geom/update/profile.ts +379 -379
- package/src/api/core/groups.ts +521 -521
- package/src/api/core/handles/index.ts +234 -234
- package/src/api/core/history/index.ts +84 -84
- package/src/api/core/index.ts +99 -99
- package/src/api/core/io/export/index.ts +126 -126
- package/src/api/core/io/import/index.ts +504 -504
- package/src/api/core/io/index.ts +42 -42
- package/src/api/core/io/job/index.ts +140 -140
- package/src/api/core/io/query/index.ts +71 -71
- package/src/api/core/io/terrain/index.ts +360 -360
- package/src/api/core/io/underlay/index.ts +705 -705
- package/src/api/core/layers.ts +540 -540
- package/src/api/core/math/index.ts +20 -20
- package/src/api/core/math/quat.ts +172 -172
- package/src/api/core/math/vec3.ts +179 -179
- package/src/api/core/mode/index.ts +108 -108
- package/src/api/core/project/index.ts +479 -479
- package/src/api/core/proposals/index.ts +570 -570
- package/src/api/core/storeys/index.ts +308 -308
- package/src/api/core/storeys/layers.ts +339 -339
- package/src/api/core/tags.ts +911 -911
- package/src/api/core/units/index.ts +164 -164
- package/src/api/core/user.ts +46 -46
- package/src/api/core/zoom/index.ts +64 -51
- package/src/api/design/bim.ts +121 -0
- package/src/api/design/boolean/index.ts +181 -179
- package/src/api/design/catalog.ts +203 -0
- package/src/api/design/create/bulk-items.ts +294 -254
- package/src/api/design/create/grids.ts +137 -137
- package/src/api/design/create/index.ts +2148 -1980
- package/src/api/design/create/opening-fields.ts +40 -37
- package/src/api/design/delete/index.ts +75 -74
- package/src/api/design/dimensions.ts +453 -453
- package/src/api/design/doors/index.ts +516 -500
- package/src/api/design/edit/index.ts +54 -54
- package/src/api/design/erase/index.ts +151 -151
- package/src/api/design/family.ts +1334 -704
- package/src/api/design/furniture/index.ts +319 -319
- package/src/api/design/grids.ts +237 -237
- package/src/api/design/index.ts +304 -274
- package/src/api/design/lock.ts +69 -69
- package/src/api/design/materials/index.ts +608 -608
- package/src/api/design/networks.ts +667 -0
- package/src/api/design/query/geometry/index.ts +319 -319
- package/src/api/design/query/grids.ts +197 -197
- package/src/api/design/query/index.ts +1236 -1226
- package/src/api/design/query/referenceLines.ts +52 -52
- package/src/api/design/query/spaces.ts +275 -275
- package/src/api/design/selection/index.ts +273 -273
- package/src/api/design/shared.ts +40 -40
- package/src/api/design/transform/index.ts +254 -254
- package/src/api/design/types/index.ts +163 -156
- package/src/api/design/update/index.ts +1024 -983
- package/src/api/design/visibility.ts +143 -143
- package/src/api/design/windows/index.ts +351 -333
- package/src/api/entity/buildableEnvelope.ts +322 -322
- package/src/api/entity/index.ts +30 -30
- package/src/api/entity/referenceLine.ts +235 -235
- package/src/api/entity/space.ts +612 -612
- package/src/api/entity/story.ts +517 -517
- package/src/api/index.ts +47 -47
- package/src/api/presentation/aiInspiration.ts +1116 -1116
- package/src/api/presentation/annotate.ts +417 -385
- package/src/api/presentation/camera.ts +289 -289
- package/src/api/presentation/diagrams.ts +194 -194
- package/src/api/presentation/drawingContract.ts +70 -0
- package/src/api/presentation/drawings.ts +1179 -0
- package/src/api/presentation/export.ts +134 -108
- package/src/api/presentation/import.ts +159 -159
- package/src/api/presentation/index.ts +160 -126
- package/src/api/presentation/placedViews.ts +1211 -1120
- package/src/api/presentation/sections.ts +420 -0
- package/src/api/presentation/shapes.ts +274 -274
- package/src/api/presentation/sheets.ts +746 -585
- package/src/api/presentation/slideshow.ts +134 -134
- package/src/api/presentation/tables.ts +84 -84
- package/src/api/presentation/viewPresets.ts +241 -0
- package/src/api/presentation/views.ts +713 -673
- package/src/api/presentation/walkthroughs.ts +1201 -1201
- package/src/api/program/adjacency.ts +164 -164
- package/src/api/program/areas.ts +408 -408
- package/src/api/program/classification.ts +138 -138
- package/src/api/program/cores.ts +83 -83
- package/src/api/program/departments.ts +517 -517
- package/src/api/program/index.ts +73 -73
- package/src/api/program/labels.ts +332 -332
- package/src/api/program/layout.ts +422 -422
- package/src/api/program/metadata.ts +364 -364
- package/src/api/program/metrics.ts +120 -120
- package/src/api/program/site.ts +748 -748
- package/src/api/program/spreadsheet.ts +2698 -2698
- package/src/api/workspace/index.ts +612 -612
- package/src/errors/codes.ts +143 -136
- package/src/errors/envelope.ts +75 -75
- package/src/errors/index.ts +21 -21
- package/src/errors/plugin-error.ts +134 -134
- package/src/handles.ts +297 -297
- package/src/host-utils.ts +67 -67
- package/src/index.ts +7 -7
- package/src/massParameters.ops.ts +246 -246
- package/src/massParameters.ts +427 -427
- package/src/types.ts +16 -16
- package/test/drawingContract.test.mjs +288 -0
- package/test/errors.test.mjs +185 -184
- package/test/massParameters.test.mjs +952 -952
- package/tsconfig.json +22 -22
- package/tsup.config.ts +12 -12
- package/api-manifest.json +0 -9618
package/src/api/core/layers.ts
CHANGED
|
@@ -1,540 +1,540 @@
|
|
|
1
|
-
import * as z from "zod"
|
|
2
|
-
import { PluginApiReturn } from "../../types"
|
|
3
|
-
import { ComponentHandle } from "../../handles"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Layers — the layers in the **Layers panel** in the left sidebar (the panel
|
|
7
|
-
* with the "+" add-layer button and one row per layer, such as "Default" or
|
|
8
|
-
* "BIM layer"; the radio mark is the active layer).
|
|
9
|
-
*
|
|
10
|
-
* A layer is a named group of objects. Every object is on exactly one layer, and
|
|
11
|
-
* new objects land on the active layer. Each row can be renamed, locked, hidden
|
|
12
|
-
* and deleted, and objects can be moved between layers.
|
|
13
|
-
*
|
|
14
|
-
* These are **not** each storey's sketch surfaces and imported underlays (ids
|
|
15
|
-
* like `ly_5`); those are {@linkcode PluginCoreStoreysLayersApi}
|
|
16
|
-
* (`core.storeys.layers`, formerly `core.layers`). They are also not wall/floor
|
|
17
|
-
* construction-assembly material layers.
|
|
18
|
-
*
|
|
19
|
-
* Each design option ({@linkcode PluginCoreProposalsApi}) owns a set of layers;
|
|
20
|
-
* `core.proposals` records refer to these ids as `bucketIds` and
|
|
21
|
-
* `defaultBucketId`. `list` and every write are scoped to the **active** design
|
|
22
|
-
* option, like the panel; on legacy projects without design options every layer
|
|
23
|
-
* is in scope. Reads never throw for a missing layer (`get` and `getActive`
|
|
24
|
-
* return `null`).
|
|
25
|
-
*
|
|
26
|
-
* **Compatibility.** Before 0.9.15 this namespace was the storey sketch-surface
|
|
27
|
-
* API that is now {@linkcode PluginCoreStoreysLayersApi}. Calls in that shape
|
|
28
|
-
* keep working here and are routed to it: `list(storeyId)`, `getActive(storeyId)`,
|
|
29
|
-
* and `get` / `setActive` / `update(layerId, hidden)` with a storey-layer id
|
|
30
|
-
* (`ly_*`). They are deprecated: new code calls `core.storeys.layers` directly.
|
|
31
|
-
*
|
|
32
|
-
* Accessed via `snaptrude.core.layers`.
|
|
33
|
-
*/
|
|
34
|
-
export abstract class PluginCoreLayersApi {
|
|
35
|
-
constructor() {}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* List the layers in the Layers panel: the active design option's layers,
|
|
39
|
-
* default layer first, then in creation order.
|
|
40
|
-
*
|
|
41
|
-
* @returns A {@linkcode PluginCoreLayersListResult} with a `layers` array.
|
|
42
|
-
*
|
|
43
|
-
* @examplePrompt List all the layers in the Layers panel
|
|
44
|
-
* @examplePrompt Show me the layers in the left sidebar
|
|
45
|
-
* @examplePrompt What layers does this project have?
|
|
46
|
-
* @examplePrompt Show every layer with whether it is locked or hidden
|
|
47
|
-
* @examplePrompt Which layer is the default layer?
|
|
48
|
-
* @examplePrompt Which layers are empty?
|
|
49
|
-
*
|
|
50
|
-
* # Example
|
|
51
|
-
* ```ts
|
|
52
|
-
* const { layers } = await snaptrude.core.layers.list()
|
|
53
|
-
* for (const l of layers) console.log(l.name, l.objectCount, l.locked, l.hidden)
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
public abstract list(): PluginApiReturn<PluginCoreLayersListResult>
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Get one Layers-panel layer by id, including layers owned by other design
|
|
60
|
-
* options.
|
|
61
|
-
*
|
|
62
|
-
* @param layerId - The id of the layer to read.
|
|
63
|
-
* @returns The matching {@linkcode PluginCoreLayer}, or `null` if no layer has
|
|
64
|
-
* that id.
|
|
65
|
-
*
|
|
66
|
-
* @examplePrompt Get the Layers-panel layer with id 3f2a…
|
|
67
|
-
* @examplePrompt Is the Furniture layer locked or hidden?
|
|
68
|
-
* @examplePrompt How many objects are on layer 3f2a…?
|
|
69
|
-
*
|
|
70
|
-
* # Example
|
|
71
|
-
* ```ts
|
|
72
|
-
* const layer = await snaptrude.core.layers.get(layerId)
|
|
73
|
-
* if (layer) console.log(layer.name, layer.objectCount)
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
public abstract get(
|
|
77
|
-
layerId: string,
|
|
78
|
-
): PluginApiReturn<PluginCoreLayersGetResult>
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get the active Layers-panel layer: the one new objects land on.
|
|
82
|
-
*
|
|
83
|
-
* @returns The active {@linkcode PluginCoreLayer}, or `null` if none is set.
|
|
84
|
-
*
|
|
85
|
-
* @examplePrompt Which layer is active?
|
|
86
|
-
* @examplePrompt Which layer in the Layers panel is active?
|
|
87
|
-
* @examplePrompt What layer will new objects go on?
|
|
88
|
-
* @examplePrompt Which layer are new walls and masses being added to?
|
|
89
|
-
*
|
|
90
|
-
* # Example
|
|
91
|
-
* ```ts
|
|
92
|
-
* const active = await snaptrude.core.layers.getActive()
|
|
93
|
-
* if (active) console.log(active.name)
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
public abstract getActive(): PluginApiReturn<PluginCoreLayersGetActiveResult>
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Create a new layer in the Layers panel (the panel's "Add new layer" button
|
|
100
|
-
* followed by naming it).
|
|
101
|
-
*
|
|
102
|
-
* The layer is added to the active design option and is **not** made active;
|
|
103
|
-
* call {@linkcode PluginCoreLayersApi.setActive} to put new objects on it.
|
|
104
|
-
* Names are trimmed, 1-40 characters, and must be unique across all layers
|
|
105
|
-
* (case-insensitive). **Undoable.**
|
|
106
|
-
*
|
|
107
|
-
* @param name - The new layer's name.
|
|
108
|
-
* @returns The created {@linkcode PluginCoreLayer}.
|
|
109
|
-
* @throws `VALIDATION` for an empty name or one longer than 40 characters;
|
|
110
|
-
* `PRECONDITION_FAILED` if a layer with that name already exists.
|
|
111
|
-
*
|
|
112
|
-
* @examplePrompt Create a new layer called Furniture
|
|
113
|
-
* @examplePrompt Add a layer called Landscape
|
|
114
|
-
* @examplePrompt Add a layer named Landscape to the Layers panel
|
|
115
|
-
* @examplePrompt Make a new layer for the facade elements
|
|
116
|
-
* @examplePrompt Create layers named Structure and Services
|
|
117
|
-
*
|
|
118
|
-
* # Example
|
|
119
|
-
* ```ts
|
|
120
|
-
* const layer = await snaptrude.core.layers.create("Furniture")
|
|
121
|
-
* await snaptrude.core.layers.setActive(layer.id)
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
public abstract create(
|
|
125
|
-
name: string,
|
|
126
|
-
): PluginApiReturn<PluginCoreLayersCreateResult>
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Rename a layer (the panel row's "Rename layer").
|
|
130
|
-
*
|
|
131
|
-
* Names are trimmed, 1-40 characters, and must be unique across all layers
|
|
132
|
-
* (case-insensitive; changing only the case of the layer's own name is
|
|
133
|
-
* allowed). The default layer cannot be renamed. **Not undoable.**
|
|
134
|
-
*
|
|
135
|
-
* @param layerId - The id of the layer to rename.
|
|
136
|
-
* @param name - The new name.
|
|
137
|
-
* @returns The updated {@linkcode PluginCoreLayer}.
|
|
138
|
-
* @throws `VALIDATION` for a bad name; `HANDLE_INVALID` for an unknown
|
|
139
|
-
* `layerId`; `PRECONDITION_FAILED` if the layer is the default layer, is
|
|
140
|
-
* outside the active design option, or the name is already used;
|
|
141
|
-
* `OPERATION_FAILED` if the app refuses the rename.
|
|
142
|
-
*
|
|
143
|
-
* @examplePrompt Rename the Furniture layer to Loose furniture
|
|
144
|
-
* @examplePrompt Rename layer 3f2a… to Existing building
|
|
145
|
-
* @examplePrompt Change the name of the Landscape layer
|
|
146
|
-
*
|
|
147
|
-
* # Example
|
|
148
|
-
* ```ts
|
|
149
|
-
* await snaptrude.core.layers.rename(layerId, "Loose furniture")
|
|
150
|
-
* ```
|
|
151
|
-
*/
|
|
152
|
-
public abstract rename(
|
|
153
|
-
layerId: string,
|
|
154
|
-
name: string,
|
|
155
|
-
): PluginApiReturn<PluginCoreLayersRenameResult>
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Lock/unlock or show/hide a layer (the panel row's padlock and eye).
|
|
159
|
-
*
|
|
160
|
-
* A **sparse** update: omitted fields are unchanged. `hidden` is **per-user**:
|
|
161
|
-
* it hides the layer for you, not for collaborators. Locking and hiding block
|
|
162
|
-
* interactive drawing in the app; plugin creates are not blocked (see
|
|
163
|
-
* {@linkcode PluginCoreLayersApi.setActive}). **Undoable**, one undo step per
|
|
164
|
-
* changed field.
|
|
165
|
-
*
|
|
166
|
-
* @param layerId - The id of the layer to update.
|
|
167
|
-
* @param options - `{ locked?, hidden? }`; omitted fields are unchanged.
|
|
168
|
-
* @returns The updated {@linkcode PluginCoreLayer}.
|
|
169
|
-
* @throws `VALIDATION` for any option other than `locked` / `hidden` (to
|
|
170
|
-
* rename, use {@linkcode PluginCoreLayersApi.rename}); `HANDLE_INVALID` for
|
|
171
|
-
* an unknown `layerId`; `PRECONDITION_FAILED` if the layer is outside the
|
|
172
|
-
* active design option, or `hidden` is changed with no signed-in user.
|
|
173
|
-
*
|
|
174
|
-
* @examplePrompt Lock the Default layer
|
|
175
|
-
* @examplePrompt Lock the Structure layer
|
|
176
|
-
* @examplePrompt Hide the Landscape layer in the Layers panel
|
|
177
|
-
* @examplePrompt Unlock layer 3f2a… and show it again
|
|
178
|
-
*
|
|
179
|
-
* # Example
|
|
180
|
-
* ```ts
|
|
181
|
-
* await snaptrude.core.layers.update(layerId, { locked: true, hidden: false })
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
public abstract update(
|
|
185
|
-
layerId: string,
|
|
186
|
-
options?: { locked?: boolean; hidden?: boolean },
|
|
187
|
-
): PluginApiReturn<PluginCoreLayersUpdateResult>
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Make a layer the active layer (clicking its row in the Layers panel).
|
|
191
|
-
*
|
|
192
|
-
* New objects, whether drawn in the app or created by plugins with
|
|
193
|
-
* `design.create.*`, land on the active layer. When the active layer is locked
|
|
194
|
-
* or hidden the app blocks interactive drawing, but plugin creates still land
|
|
195
|
-
* on it: objects created on a hidden layer are invisible, and objects on a
|
|
196
|
-
* locked layer cannot be edited. Unlock or show the layer first
|
|
197
|
-
* ({@linkcode PluginCoreLayersApi.update}). **Not undoable.**
|
|
198
|
-
*
|
|
199
|
-
* @param layerId - The id of the layer to activate.
|
|
200
|
-
* @returns The id of the now-active layer.
|
|
201
|
-
* @throws `HANDLE_INVALID` for an unknown `layerId`; `PRECONDITION_FAILED` if
|
|
202
|
-
* the layer is outside the active design option.
|
|
203
|
-
*
|
|
204
|
-
* @examplePrompt Put new objects on the Furniture layer
|
|
205
|
-
* @examplePrompt Make the Structure layer the active layer in the Layers panel
|
|
206
|
-
* @examplePrompt Switch the active layer to Landscape
|
|
207
|
-
*
|
|
208
|
-
* # Example
|
|
209
|
-
* ```ts
|
|
210
|
-
* await snaptrude.core.layers.setActive(layerId)
|
|
211
|
-
* ```
|
|
212
|
-
*/
|
|
213
|
-
public abstract setActive(
|
|
214
|
-
layerId: string,
|
|
215
|
-
): PluginApiReturn<PluginCoreLayersSetActiveResult>
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Delete a layer (the panel row's "Delete layer").
|
|
219
|
-
*
|
|
220
|
-
* Choose **exactly one** disposition, mirroring the delete dialog:
|
|
221
|
-
*
|
|
222
|
-
* - `{ deleteObjects: true }` destroys the objects on the layer.
|
|
223
|
-
* - `{ targetLayerId }` moves them to another layer of the active design
|
|
224
|
-
* option first, then deletes the emptied layer.
|
|
225
|
-
*
|
|
226
|
-
* A bare `delete(layerId)` is **rejected**: the engine would drop the layer
|
|
227
|
-
* and leave its objects on a missing layer. Refused for the default layer, the
|
|
228
|
-
* last layer, a locked layer, a layer shared with other design options
|
|
229
|
-
* (`proposalIds.length > 1`; unshare it in the app first), and, with
|
|
230
|
-
* `deleteObjects`, when any object on it is locked. The server checks that no
|
|
231
|
-
* collaborator is using the layer (needs a live connection; times out after
|
|
232
|
-
* ~10 s). If the layer was active, the active design option's default layer
|
|
233
|
-
* becomes active.
|
|
234
|
-
*
|
|
235
|
-
* **Treat as permanent.** `core.history.undo` restores the layer in this
|
|
236
|
-
* session only; the server does not re-link it to its design option, so after
|
|
237
|
-
* a reload it is missing from the panel.
|
|
238
|
-
*
|
|
239
|
-
* @param layerId - The id of the layer to delete.
|
|
240
|
-
* @param options - Exactly one disposition: `{ deleteObjects: true }` or
|
|
241
|
-
* `{ targetLayerId }`.
|
|
242
|
-
* @returns Confirmation that the layer was deleted.
|
|
243
|
-
* @throws `VALIDATION` for no disposition, both, or `targetLayerId` equal to
|
|
244
|
-
* `layerId`; `HANDLE_INVALID` for an unknown `layerId` or
|
|
245
|
-
* `targetLayerId`; `PRECONDITION_FAILED` for the refusals above or a layer
|
|
246
|
-
* or target outside the active design option; `OPERATION_FAILED` if the
|
|
247
|
-
* server refuses (a collaborator is using it), the connection is down, or
|
|
248
|
-
* the check times out.
|
|
249
|
-
*
|
|
250
|
-
* @examplePrompt Delete the Furniture layer and everything on it
|
|
251
|
-
* @examplePrompt Delete the Furniture layer and move its objects to Default
|
|
252
|
-
* @examplePrompt Remove layer 3f2a… and move its objects to the default layer
|
|
253
|
-
* @examplePrompt Merge the Services layer into Structure and delete it
|
|
254
|
-
* @examplePrompt Delete every empty layer
|
|
255
|
-
*
|
|
256
|
-
* # Example
|
|
257
|
-
* ```ts
|
|
258
|
-
* await snaptrude.core.layers.delete(layerId, { deleteObjects: true })
|
|
259
|
-
* const { layers } = await snaptrude.core.layers.list()
|
|
260
|
-
* const def = layers.find((l) => l.isDefault)!
|
|
261
|
-
* await snaptrude.core.layers.delete(otherId, { targetLayerId: def.id })
|
|
262
|
-
* ```
|
|
263
|
-
*/
|
|
264
|
-
public abstract delete(
|
|
265
|
-
layerId: string,
|
|
266
|
-
options:
|
|
267
|
-
| { deleteObjects: true; targetLayerId?: never }
|
|
268
|
-
| { deleteObjects?: false; targetLayerId: string },
|
|
269
|
-
): PluginApiReturn<PluginCoreLayersDeleteResult>
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Move objects onto a layer (picking a layer in the object properties panel).
|
|
273
|
-
*
|
|
274
|
-
* Doors, windows and voids hosted by a moved wall (and a terrain's
|
|
275
|
-
* neighbourhood buildings) move with it; if any of those is locked, the parent
|
|
276
|
-
* is skipped as `locked`. Locked objects, unknown ids and objects outside the
|
|
277
|
-
* active design option are returned in `skipped`, never silently dropped. The target layer's own lock
|
|
278
|
-
* does not block the move. An object is always on exactly one layer, so there
|
|
279
|
-
* is no `unassign`: assign to another layer instead. **Undoable** (one step).
|
|
280
|
-
*
|
|
281
|
-
* @param componentIds - The objects to move.
|
|
282
|
-
* @param layerId - The target layer.
|
|
283
|
-
* @returns A {@linkcode PluginCoreLayersAssignResult} splitting `assigned`
|
|
284
|
-
* from `skipped`.
|
|
285
|
-
* @throws `VALIDATION` for an empty `componentIds`; `HANDLE_INVALID` for an
|
|
286
|
-
* unknown `layerId`; `PRECONDITION_FAILED` if the target is outside the
|
|
287
|
-
* active design option.
|
|
288
|
-
*
|
|
289
|
-
* @examplePrompt Move the selected objects to the BIM layer
|
|
290
|
-
* @examplePrompt Move the selected objects to the Furniture layer
|
|
291
|
-
* @examplePrompt Assign the generated walls to the Structure layer
|
|
292
|
-
* @examplePrompt Put these masses on layer 3f2a…
|
|
293
|
-
*
|
|
294
|
-
* # Example
|
|
295
|
-
* ```ts
|
|
296
|
-
* const { assigned, skipped } = await snaptrude.core.layers.assign(ids, layerId)
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
public abstract assign(
|
|
300
|
-
componentIds: ComponentHandle[],
|
|
301
|
-
layerId: string,
|
|
302
|
-
): PluginApiReturn<PluginCoreLayersAssignResult>
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* A layer in the Layers panel.
|
|
307
|
-
*
|
|
308
|
-
* | Property | Type | Description |
|
|
309
|
-
* |---|---|---|
|
|
310
|
-
* | `id` | `string` | Layer id (the ids `core.proposals` records list) |
|
|
311
|
-
* | `name` | `string` | Display name (1-40 characters, unique case-insensitively) |
|
|
312
|
-
* | `isDefault` | `boolean` | The design option's default layer: cannot be renamed or deleted |
|
|
313
|
-
* | `isActive` | `boolean` | Whether new objects land on this layer |
|
|
314
|
-
* | `locked` | `boolean` | Whether the layer is locked (its objects cannot be edited) |
|
|
315
|
-
* | `hidden` | `boolean` | Whether the layer is hidden **for the current user** |
|
|
316
|
-
* | `proposalIds` | `string[]` | Design options that own the layer (more than one = shared) |
|
|
317
|
-
* | `objectCount` | `number` | Objects currently on the layer (0 = empty) |
|
|
318
|
-
*/
|
|
319
|
-
export const PluginCoreLayer = z.object({
|
|
320
|
-
id: z.string(),
|
|
321
|
-
name: z.string(),
|
|
322
|
-
isDefault: z.boolean(),
|
|
323
|
-
isActive: z.boolean(),
|
|
324
|
-
locked: z.boolean(),
|
|
325
|
-
hidden: z.boolean(),
|
|
326
|
-
proposalIds: z.array(z.string()),
|
|
327
|
-
objectCount: z.number().int(),
|
|
328
|
-
})
|
|
329
|
-
export type PluginCoreLayer = z.infer<typeof PluginCoreLayer>
|
|
330
|
-
|
|
331
|
-
/** A layer name: trimmed, 1-40 characters (the panel input's limit). */
|
|
332
|
-
export const PluginCoreLayerName = z.string().trim().min(1).max(40)
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Result of {@linkcode PluginCoreLayersApi.list}.
|
|
336
|
-
*
|
|
337
|
-
* | Property | Type | Description |
|
|
338
|
-
* |---|---|---|
|
|
339
|
-
* | `layers` | {@linkcode PluginCoreLayer}`[]` | The active design option's layers, default first |
|
|
340
|
-
*/
|
|
341
|
-
export const PluginCoreLayersListResult = z.object({
|
|
342
|
-
layers: z.array(PluginCoreLayer),
|
|
343
|
-
})
|
|
344
|
-
export type PluginCoreLayersListResult = z.infer<
|
|
345
|
-
typeof PluginCoreLayersListResult
|
|
346
|
-
>
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Arguments for {@linkcode PluginCoreLayersApi.get}.
|
|
350
|
-
*
|
|
351
|
-
* | Property | Type | Description |
|
|
352
|
-
* |---|---|---|
|
|
353
|
-
* | `layerId` | `string` | The id of the layer to read |
|
|
354
|
-
*/
|
|
355
|
-
export const PluginCoreLayersGetArgs = z.object({ layerId: z.string() })
|
|
356
|
-
export type PluginCoreLayersGetArgs = z.infer<typeof PluginCoreLayersGetArgs>
|
|
357
|
-
|
|
358
|
-
/** Result of {@linkcode PluginCoreLayersApi.get}: the layer, or `null`. */
|
|
359
|
-
export const PluginCoreLayersGetResult = PluginCoreLayer.nullable()
|
|
360
|
-
export type PluginCoreLayersGetResult = z.infer<
|
|
361
|
-
typeof PluginCoreLayersGetResult
|
|
362
|
-
>
|
|
363
|
-
|
|
364
|
-
/** Result of {@linkcode PluginCoreLayersApi.getActive}: the active layer, or `null`. */
|
|
365
|
-
export const PluginCoreLayersGetActiveResult = PluginCoreLayer.nullable()
|
|
366
|
-
export type PluginCoreLayersGetActiveResult = z.infer<
|
|
367
|
-
typeof PluginCoreLayersGetActiveResult
|
|
368
|
-
>
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Arguments for {@linkcode PluginCoreLayersApi.create}.
|
|
372
|
-
*
|
|
373
|
-
* | Property | Type | Description |
|
|
374
|
-
* |---|---|---|
|
|
375
|
-
* | `name` | `string` | The new layer's name (trimmed, 1-40 characters) |
|
|
376
|
-
*/
|
|
377
|
-
export const PluginCoreLayersCreateArgs = z.object({
|
|
378
|
-
name: PluginCoreLayerName,
|
|
379
|
-
})
|
|
380
|
-
export type PluginCoreLayersCreateArgs = z.infer<
|
|
381
|
-
typeof PluginCoreLayersCreateArgs
|
|
382
|
-
>
|
|
383
|
-
|
|
384
|
-
/** Result of {@linkcode PluginCoreLayersApi.create}: the created layer. */
|
|
385
|
-
export const PluginCoreLayersCreateResult = PluginCoreLayer
|
|
386
|
-
export type PluginCoreLayersCreateResult = z.infer<
|
|
387
|
-
typeof PluginCoreLayersCreateResult
|
|
388
|
-
>
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Arguments for {@linkcode PluginCoreLayersApi.rename}.
|
|
392
|
-
*
|
|
393
|
-
* | Property | Type | Description |
|
|
394
|
-
* |---|---|---|
|
|
395
|
-
* | `layerId` | `string` | The id of the layer to rename |
|
|
396
|
-
* | `name` | `string` | The new name (trimmed, 1-40 characters) |
|
|
397
|
-
*/
|
|
398
|
-
export const PluginCoreLayersRenameArgs = z.object({
|
|
399
|
-
layerId: z.string(),
|
|
400
|
-
name: PluginCoreLayerName,
|
|
401
|
-
})
|
|
402
|
-
export type PluginCoreLayersRenameArgs = z.infer<
|
|
403
|
-
typeof PluginCoreLayersRenameArgs
|
|
404
|
-
>
|
|
405
|
-
|
|
406
|
-
/** Result of {@linkcode PluginCoreLayersApi.rename}: the updated layer. */
|
|
407
|
-
export const PluginCoreLayersRenameResult = PluginCoreLayer
|
|
408
|
-
export type PluginCoreLayersRenameResult = z.infer<
|
|
409
|
-
typeof PluginCoreLayersRenameResult
|
|
410
|
-
>
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Arguments for {@linkcode PluginCoreLayersApi.update}. Sparse: only the
|
|
414
|
-
* provided fields are changed.
|
|
415
|
-
*
|
|
416
|
-
* | Property | Type | Description |
|
|
417
|
-
* |---|---|---|
|
|
418
|
-
* | `layerId` | `string` | The id of the layer to update |
|
|
419
|
-
* | `locked` | `boolean \| undefined` | New locked state (unchanged if omitted) |
|
|
420
|
-
* | `hidden` | `boolean \| undefined` | New hidden state for the current user (unchanged if omitted) |
|
|
421
|
-
*/
|
|
422
|
-
export const PluginCoreLayersUpdateArgs = z.object({
|
|
423
|
-
layerId: z.string(),
|
|
424
|
-
locked: z.boolean().optional(),
|
|
425
|
-
hidden: z.boolean().optional(),
|
|
426
|
-
}).strict()
|
|
427
|
-
export type PluginCoreLayersUpdateArgs = z.infer<
|
|
428
|
-
typeof PluginCoreLayersUpdateArgs
|
|
429
|
-
>
|
|
430
|
-
|
|
431
|
-
/** Result of {@linkcode PluginCoreLayersApi.update}: the updated layer. */
|
|
432
|
-
export const PluginCoreLayersUpdateResult = PluginCoreLayer
|
|
433
|
-
export type PluginCoreLayersUpdateResult = z.infer<
|
|
434
|
-
typeof PluginCoreLayersUpdateResult
|
|
435
|
-
>
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Arguments for {@linkcode PluginCoreLayersApi.setActive}.
|
|
439
|
-
*
|
|
440
|
-
* | Property | Type | Description |
|
|
441
|
-
* |---|---|---|
|
|
442
|
-
* | `layerId` | `string` | The id of the layer to activate |
|
|
443
|
-
*/
|
|
444
|
-
export const PluginCoreLayersSetActiveArgs = z.object({ layerId: z.string() })
|
|
445
|
-
export type PluginCoreLayersSetActiveArgs = z.infer<
|
|
446
|
-
typeof PluginCoreLayersSetActiveArgs
|
|
447
|
-
>
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Result of {@linkcode PluginCoreLayersApi.setActive}.
|
|
451
|
-
*
|
|
452
|
-
* | Property | Type | Description |
|
|
453
|
-
* |---|---|---|
|
|
454
|
-
* | `layerId` | `string` | The id of the now-active layer |
|
|
455
|
-
*/
|
|
456
|
-
export const PluginCoreLayersSetActiveResult = z.object({
|
|
457
|
-
layerId: z.string(),
|
|
458
|
-
})
|
|
459
|
-
export type PluginCoreLayersSetActiveResult = z.infer<
|
|
460
|
-
typeof PluginCoreLayersSetActiveResult
|
|
461
|
-
>
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Arguments for {@linkcode PluginCoreLayersApi.delete}. Exactly one
|
|
465
|
-
* disposition is required: `deleteObjects: true` XOR `targetLayerId` (a
|
|
466
|
-
* **different** layer).
|
|
467
|
-
*
|
|
468
|
-
* | Property | Type | Description |
|
|
469
|
-
* |---|---|---|
|
|
470
|
-
* | `layerId` | `string` | The id of the layer to delete |
|
|
471
|
-
* | `deleteObjects` | `boolean \| undefined` | `true` destroys the layer's objects (exclusive with `targetLayerId`) |
|
|
472
|
-
* | `targetLayerId` | `string \| undefined` | Move the layer's objects to this layer, then delete (exclusive with `deleteObjects`) |
|
|
473
|
-
*/
|
|
474
|
-
export const PluginCoreLayersDeleteArgs = z
|
|
475
|
-
.object({
|
|
476
|
-
layerId: z.string(),
|
|
477
|
-
deleteObjects: z.boolean().optional(),
|
|
478
|
-
targetLayerId: z.string().optional(),
|
|
479
|
-
})
|
|
480
|
-
.refine((v) => (v.deleteObjects === true) !== (v.targetLayerId != null), {
|
|
481
|
-
message:
|
|
482
|
-
"Provide exactly one disposition: deleteObjects: true (destroy the layer's objects) or targetLayerId (move them to that layer, then delete)",
|
|
483
|
-
})
|
|
484
|
-
.refine((v) => v.targetLayerId == null || v.targetLayerId !== v.layerId, {
|
|
485
|
-
message: "targetLayerId must be a different layer than layerId",
|
|
486
|
-
})
|
|
487
|
-
export type PluginCoreLayersDeleteArgs = z.infer<
|
|
488
|
-
typeof PluginCoreLayersDeleteArgs
|
|
489
|
-
>
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Result of {@linkcode PluginCoreLayersApi.delete}.
|
|
493
|
-
*
|
|
494
|
-
* | Property | Type | Description |
|
|
495
|
-
* |---|---|---|
|
|
496
|
-
* | `deleted` | `true` | The layer was deleted |
|
|
497
|
-
*/
|
|
498
|
-
export const PluginCoreLayersDeleteResult = z.object({
|
|
499
|
-
deleted: z.literal(true),
|
|
500
|
-
})
|
|
501
|
-
export type PluginCoreLayersDeleteResult = z.infer<
|
|
502
|
-
typeof PluginCoreLayersDeleteResult
|
|
503
|
-
>
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* Arguments for {@linkcode PluginCoreLayersApi.assign}.
|
|
507
|
-
*
|
|
508
|
-
* | Property | Type | Description |
|
|
509
|
-
* |---|---|---|
|
|
510
|
-
* | `componentIds` | `string[]` | The objects to move (at least one) |
|
|
511
|
-
* | `layerId` | `string` | The target layer |
|
|
512
|
-
*/
|
|
513
|
-
export const PluginCoreLayersAssignArgs = z.object({
|
|
514
|
-
componentIds: z.array(ComponentHandle).min(1),
|
|
515
|
-
layerId: z.string(),
|
|
516
|
-
})
|
|
517
|
-
export type PluginCoreLayersAssignArgs = z.infer<
|
|
518
|
-
typeof PluginCoreLayersAssignArgs
|
|
519
|
-
>
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Result of {@linkcode PluginCoreLayersApi.assign}.
|
|
523
|
-
*
|
|
524
|
-
* | Property | Type | Description |
|
|
525
|
-
* |---|---|---|
|
|
526
|
-
* | `assigned` | `string[]` | Ids of the objects that were moved |
|
|
527
|
-
* | `skipped` | `{ id: string; reason: "not-found" \| "locked" \| "outside-proposal" }[]` | Objects that were not moved, each with a reason |
|
|
528
|
-
*/
|
|
529
|
-
export const PluginCoreLayersAssignResult = z.object({
|
|
530
|
-
assigned: z.array(ComponentHandle),
|
|
531
|
-
skipped: z.array(
|
|
532
|
-
z.object({
|
|
533
|
-
id: ComponentHandle,
|
|
534
|
-
reason: z.enum(["not-found", "locked", "outside-proposal"]),
|
|
535
|
-
}),
|
|
536
|
-
),
|
|
537
|
-
})
|
|
538
|
-
export type PluginCoreLayersAssignResult = z.infer<
|
|
539
|
-
typeof PluginCoreLayersAssignResult
|
|
540
|
-
>
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../types"
|
|
3
|
+
import { ComponentHandle } from "../../handles"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Layers — the layers in the **Layers panel** in the left sidebar (the panel
|
|
7
|
+
* with the "+" add-layer button and one row per layer, such as "Default" or
|
|
8
|
+
* "BIM layer"; the radio mark is the active layer).
|
|
9
|
+
*
|
|
10
|
+
* A layer is a named group of objects. Every object is on exactly one layer, and
|
|
11
|
+
* new objects land on the active layer. Each row can be renamed, locked, hidden
|
|
12
|
+
* and deleted, and objects can be moved between layers.
|
|
13
|
+
*
|
|
14
|
+
* These are **not** each storey's sketch surfaces and imported underlays (ids
|
|
15
|
+
* like `ly_5`); those are {@linkcode PluginCoreStoreysLayersApi}
|
|
16
|
+
* (`core.storeys.layers`, formerly `core.layers`). They are also not wall/floor
|
|
17
|
+
* construction-assembly material layers.
|
|
18
|
+
*
|
|
19
|
+
* Each design option ({@linkcode PluginCoreProposalsApi}) owns a set of layers;
|
|
20
|
+
* `core.proposals` records refer to these ids as `bucketIds` and
|
|
21
|
+
* `defaultBucketId`. `list` and every write are scoped to the **active** design
|
|
22
|
+
* option, like the panel; on legacy projects without design options every layer
|
|
23
|
+
* is in scope. Reads never throw for a missing layer (`get` and `getActive`
|
|
24
|
+
* return `null`).
|
|
25
|
+
*
|
|
26
|
+
* **Compatibility.** Before 0.9.15 this namespace was the storey sketch-surface
|
|
27
|
+
* API that is now {@linkcode PluginCoreStoreysLayersApi}. Calls in that shape
|
|
28
|
+
* keep working here and are routed to it: `list(storeyId)`, `getActive(storeyId)`,
|
|
29
|
+
* and `get` / `setActive` / `update(layerId, hidden)` with a storey-layer id
|
|
30
|
+
* (`ly_*`). They are deprecated: new code calls `core.storeys.layers` directly.
|
|
31
|
+
*
|
|
32
|
+
* Accessed via `snaptrude.core.layers`.
|
|
33
|
+
*/
|
|
34
|
+
export abstract class PluginCoreLayersApi {
|
|
35
|
+
constructor() {}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* List the layers in the Layers panel: the active design option's layers,
|
|
39
|
+
* default layer first, then in creation order.
|
|
40
|
+
*
|
|
41
|
+
* @returns A {@linkcode PluginCoreLayersListResult} with a `layers` array.
|
|
42
|
+
*
|
|
43
|
+
* @examplePrompt List all the layers in the Layers panel
|
|
44
|
+
* @examplePrompt Show me the layers in the left sidebar
|
|
45
|
+
* @examplePrompt What layers does this project have?
|
|
46
|
+
* @examplePrompt Show every layer with whether it is locked or hidden
|
|
47
|
+
* @examplePrompt Which layer is the default layer?
|
|
48
|
+
* @examplePrompt Which layers are empty?
|
|
49
|
+
*
|
|
50
|
+
* # Example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const { layers } = await snaptrude.core.layers.list()
|
|
53
|
+
* for (const l of layers) console.log(l.name, l.objectCount, l.locked, l.hidden)
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
public abstract list(): PluginApiReturn<PluginCoreLayersListResult>
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get one Layers-panel layer by id, including layers owned by other design
|
|
60
|
+
* options.
|
|
61
|
+
*
|
|
62
|
+
* @param layerId - The id of the layer to read.
|
|
63
|
+
* @returns The matching {@linkcode PluginCoreLayer}, or `null` if no layer has
|
|
64
|
+
* that id.
|
|
65
|
+
*
|
|
66
|
+
* @examplePrompt Get the Layers-panel layer with id 3f2a…
|
|
67
|
+
* @examplePrompt Is the Furniture layer locked or hidden?
|
|
68
|
+
* @examplePrompt How many objects are on layer 3f2a…?
|
|
69
|
+
*
|
|
70
|
+
* # Example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const layer = await snaptrude.core.layers.get(layerId)
|
|
73
|
+
* if (layer) console.log(layer.name, layer.objectCount)
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
public abstract get(
|
|
77
|
+
layerId: string,
|
|
78
|
+
): PluginApiReturn<PluginCoreLayersGetResult>
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the active Layers-panel layer: the one new objects land on.
|
|
82
|
+
*
|
|
83
|
+
* @returns The active {@linkcode PluginCoreLayer}, or `null` if none is set.
|
|
84
|
+
*
|
|
85
|
+
* @examplePrompt Which layer is active?
|
|
86
|
+
* @examplePrompt Which layer in the Layers panel is active?
|
|
87
|
+
* @examplePrompt What layer will new objects go on?
|
|
88
|
+
* @examplePrompt Which layer are new walls and masses being added to?
|
|
89
|
+
*
|
|
90
|
+
* # Example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const active = await snaptrude.core.layers.getActive()
|
|
93
|
+
* if (active) console.log(active.name)
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
public abstract getActive(): PluginApiReturn<PluginCoreLayersGetActiveResult>
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Create a new layer in the Layers panel (the panel's "Add new layer" button
|
|
100
|
+
* followed by naming it).
|
|
101
|
+
*
|
|
102
|
+
* The layer is added to the active design option and is **not** made active;
|
|
103
|
+
* call {@linkcode PluginCoreLayersApi.setActive} to put new objects on it.
|
|
104
|
+
* Names are trimmed, 1-40 characters, and must be unique across all layers
|
|
105
|
+
* (case-insensitive). **Undoable.**
|
|
106
|
+
*
|
|
107
|
+
* @param name - The new layer's name.
|
|
108
|
+
* @returns The created {@linkcode PluginCoreLayer}.
|
|
109
|
+
* @throws `VALIDATION` for an empty name or one longer than 40 characters;
|
|
110
|
+
* `PRECONDITION_FAILED` if a layer with that name already exists.
|
|
111
|
+
*
|
|
112
|
+
* @examplePrompt Create a new layer called Furniture
|
|
113
|
+
* @examplePrompt Add a layer called Landscape
|
|
114
|
+
* @examplePrompt Add a layer named Landscape to the Layers panel
|
|
115
|
+
* @examplePrompt Make a new layer for the facade elements
|
|
116
|
+
* @examplePrompt Create layers named Structure and Services
|
|
117
|
+
*
|
|
118
|
+
* # Example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const layer = await snaptrude.core.layers.create("Furniture")
|
|
121
|
+
* await snaptrude.core.layers.setActive(layer.id)
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
public abstract create(
|
|
125
|
+
name: string,
|
|
126
|
+
): PluginApiReturn<PluginCoreLayersCreateResult>
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Rename a layer (the panel row's "Rename layer").
|
|
130
|
+
*
|
|
131
|
+
* Names are trimmed, 1-40 characters, and must be unique across all layers
|
|
132
|
+
* (case-insensitive; changing only the case of the layer's own name is
|
|
133
|
+
* allowed). The default layer cannot be renamed. **Not undoable.**
|
|
134
|
+
*
|
|
135
|
+
* @param layerId - The id of the layer to rename.
|
|
136
|
+
* @param name - The new name.
|
|
137
|
+
* @returns The updated {@linkcode PluginCoreLayer}.
|
|
138
|
+
* @throws `VALIDATION` for a bad name; `HANDLE_INVALID` for an unknown
|
|
139
|
+
* `layerId`; `PRECONDITION_FAILED` if the layer is the default layer, is
|
|
140
|
+
* outside the active design option, or the name is already used;
|
|
141
|
+
* `OPERATION_FAILED` if the app refuses the rename.
|
|
142
|
+
*
|
|
143
|
+
* @examplePrompt Rename the Furniture layer to Loose furniture
|
|
144
|
+
* @examplePrompt Rename layer 3f2a… to Existing building
|
|
145
|
+
* @examplePrompt Change the name of the Landscape layer
|
|
146
|
+
*
|
|
147
|
+
* # Example
|
|
148
|
+
* ```ts
|
|
149
|
+
* await snaptrude.core.layers.rename(layerId, "Loose furniture")
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
public abstract rename(
|
|
153
|
+
layerId: string,
|
|
154
|
+
name: string,
|
|
155
|
+
): PluginApiReturn<PluginCoreLayersRenameResult>
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Lock/unlock or show/hide a layer (the panel row's padlock and eye).
|
|
159
|
+
*
|
|
160
|
+
* A **sparse** update: omitted fields are unchanged. `hidden` is **per-user**:
|
|
161
|
+
* it hides the layer for you, not for collaborators. Locking and hiding block
|
|
162
|
+
* interactive drawing in the app; plugin creates are not blocked (see
|
|
163
|
+
* {@linkcode PluginCoreLayersApi.setActive}). **Undoable**, one undo step per
|
|
164
|
+
* changed field.
|
|
165
|
+
*
|
|
166
|
+
* @param layerId - The id of the layer to update.
|
|
167
|
+
* @param options - `{ locked?, hidden? }`; omitted fields are unchanged.
|
|
168
|
+
* @returns The updated {@linkcode PluginCoreLayer}.
|
|
169
|
+
* @throws `VALIDATION` for any option other than `locked` / `hidden` (to
|
|
170
|
+
* rename, use {@linkcode PluginCoreLayersApi.rename}); `HANDLE_INVALID` for
|
|
171
|
+
* an unknown `layerId`; `PRECONDITION_FAILED` if the layer is outside the
|
|
172
|
+
* active design option, or `hidden` is changed with no signed-in user.
|
|
173
|
+
*
|
|
174
|
+
* @examplePrompt Lock the Default layer
|
|
175
|
+
* @examplePrompt Lock the Structure layer
|
|
176
|
+
* @examplePrompt Hide the Landscape layer in the Layers panel
|
|
177
|
+
* @examplePrompt Unlock layer 3f2a… and show it again
|
|
178
|
+
*
|
|
179
|
+
* # Example
|
|
180
|
+
* ```ts
|
|
181
|
+
* await snaptrude.core.layers.update(layerId, { locked: true, hidden: false })
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
public abstract update(
|
|
185
|
+
layerId: string,
|
|
186
|
+
options?: { locked?: boolean; hidden?: boolean },
|
|
187
|
+
): PluginApiReturn<PluginCoreLayersUpdateResult>
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Make a layer the active layer (clicking its row in the Layers panel).
|
|
191
|
+
*
|
|
192
|
+
* New objects, whether drawn in the app or created by plugins with
|
|
193
|
+
* `design.create.*`, land on the active layer. When the active layer is locked
|
|
194
|
+
* or hidden the app blocks interactive drawing, but plugin creates still land
|
|
195
|
+
* on it: objects created on a hidden layer are invisible, and objects on a
|
|
196
|
+
* locked layer cannot be edited. Unlock or show the layer first
|
|
197
|
+
* ({@linkcode PluginCoreLayersApi.update}). **Not undoable.**
|
|
198
|
+
*
|
|
199
|
+
* @param layerId - The id of the layer to activate.
|
|
200
|
+
* @returns The id of the now-active layer.
|
|
201
|
+
* @throws `HANDLE_INVALID` for an unknown `layerId`; `PRECONDITION_FAILED` if
|
|
202
|
+
* the layer is outside the active design option.
|
|
203
|
+
*
|
|
204
|
+
* @examplePrompt Put new objects on the Furniture layer
|
|
205
|
+
* @examplePrompt Make the Structure layer the active layer in the Layers panel
|
|
206
|
+
* @examplePrompt Switch the active layer to Landscape
|
|
207
|
+
*
|
|
208
|
+
* # Example
|
|
209
|
+
* ```ts
|
|
210
|
+
* await snaptrude.core.layers.setActive(layerId)
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
public abstract setActive(
|
|
214
|
+
layerId: string,
|
|
215
|
+
): PluginApiReturn<PluginCoreLayersSetActiveResult>
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Delete a layer (the panel row's "Delete layer").
|
|
219
|
+
*
|
|
220
|
+
* Choose **exactly one** disposition, mirroring the delete dialog:
|
|
221
|
+
*
|
|
222
|
+
* - `{ deleteObjects: true }` destroys the objects on the layer.
|
|
223
|
+
* - `{ targetLayerId }` moves them to another layer of the active design
|
|
224
|
+
* option first, then deletes the emptied layer.
|
|
225
|
+
*
|
|
226
|
+
* A bare `delete(layerId)` is **rejected**: the engine would drop the layer
|
|
227
|
+
* and leave its objects on a missing layer. Refused for the default layer, the
|
|
228
|
+
* last layer, a locked layer, a layer shared with other design options
|
|
229
|
+
* (`proposalIds.length > 1`; unshare it in the app first), and, with
|
|
230
|
+
* `deleteObjects`, when any object on it is locked. The server checks that no
|
|
231
|
+
* collaborator is using the layer (needs a live connection; times out after
|
|
232
|
+
* ~10 s). If the layer was active, the active design option's default layer
|
|
233
|
+
* becomes active.
|
|
234
|
+
*
|
|
235
|
+
* **Treat as permanent.** `core.history.undo` restores the layer in this
|
|
236
|
+
* session only; the server does not re-link it to its design option, so after
|
|
237
|
+
* a reload it is missing from the panel.
|
|
238
|
+
*
|
|
239
|
+
* @param layerId - The id of the layer to delete.
|
|
240
|
+
* @param options - Exactly one disposition: `{ deleteObjects: true }` or
|
|
241
|
+
* `{ targetLayerId }`.
|
|
242
|
+
* @returns Confirmation that the layer was deleted.
|
|
243
|
+
* @throws `VALIDATION` for no disposition, both, or `targetLayerId` equal to
|
|
244
|
+
* `layerId`; `HANDLE_INVALID` for an unknown `layerId` or
|
|
245
|
+
* `targetLayerId`; `PRECONDITION_FAILED` for the refusals above or a layer
|
|
246
|
+
* or target outside the active design option; `OPERATION_FAILED` if the
|
|
247
|
+
* server refuses (a collaborator is using it), the connection is down, or
|
|
248
|
+
* the check times out.
|
|
249
|
+
*
|
|
250
|
+
* @examplePrompt Delete the Furniture layer and everything on it
|
|
251
|
+
* @examplePrompt Delete the Furniture layer and move its objects to Default
|
|
252
|
+
* @examplePrompt Remove layer 3f2a… and move its objects to the default layer
|
|
253
|
+
* @examplePrompt Merge the Services layer into Structure and delete it
|
|
254
|
+
* @examplePrompt Delete every empty layer
|
|
255
|
+
*
|
|
256
|
+
* # Example
|
|
257
|
+
* ```ts
|
|
258
|
+
* await snaptrude.core.layers.delete(layerId, { deleteObjects: true })
|
|
259
|
+
* const { layers } = await snaptrude.core.layers.list()
|
|
260
|
+
* const def = layers.find((l) => l.isDefault)!
|
|
261
|
+
* await snaptrude.core.layers.delete(otherId, { targetLayerId: def.id })
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
public abstract delete(
|
|
265
|
+
layerId: string,
|
|
266
|
+
options:
|
|
267
|
+
| { deleteObjects: true; targetLayerId?: never }
|
|
268
|
+
| { deleteObjects?: false; targetLayerId: string },
|
|
269
|
+
): PluginApiReturn<PluginCoreLayersDeleteResult>
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Move objects onto a layer (picking a layer in the object properties panel).
|
|
273
|
+
*
|
|
274
|
+
* Doors, windows and voids hosted by a moved wall (and a terrain's
|
|
275
|
+
* neighbourhood buildings) move with it; if any of those is locked, the parent
|
|
276
|
+
* is skipped as `locked`. Locked objects, unknown ids and objects outside the
|
|
277
|
+
* active design option are returned in `skipped`, never silently dropped. The target layer's own lock
|
|
278
|
+
* does not block the move. An object is always on exactly one layer, so there
|
|
279
|
+
* is no `unassign`: assign to another layer instead. **Undoable** (one step).
|
|
280
|
+
*
|
|
281
|
+
* @param componentIds - The objects to move.
|
|
282
|
+
* @param layerId - The target layer.
|
|
283
|
+
* @returns A {@linkcode PluginCoreLayersAssignResult} splitting `assigned`
|
|
284
|
+
* from `skipped`.
|
|
285
|
+
* @throws `VALIDATION` for an empty `componentIds`; `HANDLE_INVALID` for an
|
|
286
|
+
* unknown `layerId`; `PRECONDITION_FAILED` if the target is outside the
|
|
287
|
+
* active design option.
|
|
288
|
+
*
|
|
289
|
+
* @examplePrompt Move the selected objects to the BIM layer
|
|
290
|
+
* @examplePrompt Move the selected objects to the Furniture layer
|
|
291
|
+
* @examplePrompt Assign the generated walls to the Structure layer
|
|
292
|
+
* @examplePrompt Put these masses on layer 3f2a…
|
|
293
|
+
*
|
|
294
|
+
* # Example
|
|
295
|
+
* ```ts
|
|
296
|
+
* const { assigned, skipped } = await snaptrude.core.layers.assign(ids, layerId)
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
public abstract assign(
|
|
300
|
+
componentIds: ComponentHandle[],
|
|
301
|
+
layerId: string,
|
|
302
|
+
): PluginApiReturn<PluginCoreLayersAssignResult>
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* A layer in the Layers panel.
|
|
307
|
+
*
|
|
308
|
+
* | Property | Type | Description |
|
|
309
|
+
* |---|---|---|
|
|
310
|
+
* | `id` | `string` | Layer id (the ids `core.proposals` records list) |
|
|
311
|
+
* | `name` | `string` | Display name (1-40 characters, unique case-insensitively) |
|
|
312
|
+
* | `isDefault` | `boolean` | The design option's default layer: cannot be renamed or deleted |
|
|
313
|
+
* | `isActive` | `boolean` | Whether new objects land on this layer |
|
|
314
|
+
* | `locked` | `boolean` | Whether the layer is locked (its objects cannot be edited) |
|
|
315
|
+
* | `hidden` | `boolean` | Whether the layer is hidden **for the current user** |
|
|
316
|
+
* | `proposalIds` | `string[]` | Design options that own the layer (more than one = shared) |
|
|
317
|
+
* | `objectCount` | `number` | Objects currently on the layer (0 = empty) |
|
|
318
|
+
*/
|
|
319
|
+
export const PluginCoreLayer = z.object({
|
|
320
|
+
id: z.string(),
|
|
321
|
+
name: z.string(),
|
|
322
|
+
isDefault: z.boolean(),
|
|
323
|
+
isActive: z.boolean(),
|
|
324
|
+
locked: z.boolean(),
|
|
325
|
+
hidden: z.boolean(),
|
|
326
|
+
proposalIds: z.array(z.string()),
|
|
327
|
+
objectCount: z.number().int(),
|
|
328
|
+
})
|
|
329
|
+
export type PluginCoreLayer = z.infer<typeof PluginCoreLayer>
|
|
330
|
+
|
|
331
|
+
/** A layer name: trimmed, 1-40 characters (the panel input's limit). */
|
|
332
|
+
export const PluginCoreLayerName = z.string().trim().min(1).max(40)
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Result of {@linkcode PluginCoreLayersApi.list}.
|
|
336
|
+
*
|
|
337
|
+
* | Property | Type | Description |
|
|
338
|
+
* |---|---|---|
|
|
339
|
+
* | `layers` | {@linkcode PluginCoreLayer}`[]` | The active design option's layers, default first |
|
|
340
|
+
*/
|
|
341
|
+
export const PluginCoreLayersListResult = z.object({
|
|
342
|
+
layers: z.array(PluginCoreLayer),
|
|
343
|
+
})
|
|
344
|
+
export type PluginCoreLayersListResult = z.infer<
|
|
345
|
+
typeof PluginCoreLayersListResult
|
|
346
|
+
>
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Arguments for {@linkcode PluginCoreLayersApi.get}.
|
|
350
|
+
*
|
|
351
|
+
* | Property | Type | Description |
|
|
352
|
+
* |---|---|---|
|
|
353
|
+
* | `layerId` | `string` | The id of the layer to read |
|
|
354
|
+
*/
|
|
355
|
+
export const PluginCoreLayersGetArgs = z.object({ layerId: z.string() })
|
|
356
|
+
export type PluginCoreLayersGetArgs = z.infer<typeof PluginCoreLayersGetArgs>
|
|
357
|
+
|
|
358
|
+
/** Result of {@linkcode PluginCoreLayersApi.get}: the layer, or `null`. */
|
|
359
|
+
export const PluginCoreLayersGetResult = PluginCoreLayer.nullable()
|
|
360
|
+
export type PluginCoreLayersGetResult = z.infer<
|
|
361
|
+
typeof PluginCoreLayersGetResult
|
|
362
|
+
>
|
|
363
|
+
|
|
364
|
+
/** Result of {@linkcode PluginCoreLayersApi.getActive}: the active layer, or `null`. */
|
|
365
|
+
export const PluginCoreLayersGetActiveResult = PluginCoreLayer.nullable()
|
|
366
|
+
export type PluginCoreLayersGetActiveResult = z.infer<
|
|
367
|
+
typeof PluginCoreLayersGetActiveResult
|
|
368
|
+
>
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Arguments for {@linkcode PluginCoreLayersApi.create}.
|
|
372
|
+
*
|
|
373
|
+
* | Property | Type | Description |
|
|
374
|
+
* |---|---|---|
|
|
375
|
+
* | `name` | `string` | The new layer's name (trimmed, 1-40 characters) |
|
|
376
|
+
*/
|
|
377
|
+
export const PluginCoreLayersCreateArgs = z.object({
|
|
378
|
+
name: PluginCoreLayerName,
|
|
379
|
+
})
|
|
380
|
+
export type PluginCoreLayersCreateArgs = z.infer<
|
|
381
|
+
typeof PluginCoreLayersCreateArgs
|
|
382
|
+
>
|
|
383
|
+
|
|
384
|
+
/** Result of {@linkcode PluginCoreLayersApi.create}: the created layer. */
|
|
385
|
+
export const PluginCoreLayersCreateResult = PluginCoreLayer
|
|
386
|
+
export type PluginCoreLayersCreateResult = z.infer<
|
|
387
|
+
typeof PluginCoreLayersCreateResult
|
|
388
|
+
>
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Arguments for {@linkcode PluginCoreLayersApi.rename}.
|
|
392
|
+
*
|
|
393
|
+
* | Property | Type | Description |
|
|
394
|
+
* |---|---|---|
|
|
395
|
+
* | `layerId` | `string` | The id of the layer to rename |
|
|
396
|
+
* | `name` | `string` | The new name (trimmed, 1-40 characters) |
|
|
397
|
+
*/
|
|
398
|
+
export const PluginCoreLayersRenameArgs = z.object({
|
|
399
|
+
layerId: z.string(),
|
|
400
|
+
name: PluginCoreLayerName,
|
|
401
|
+
})
|
|
402
|
+
export type PluginCoreLayersRenameArgs = z.infer<
|
|
403
|
+
typeof PluginCoreLayersRenameArgs
|
|
404
|
+
>
|
|
405
|
+
|
|
406
|
+
/** Result of {@linkcode PluginCoreLayersApi.rename}: the updated layer. */
|
|
407
|
+
export const PluginCoreLayersRenameResult = PluginCoreLayer
|
|
408
|
+
export type PluginCoreLayersRenameResult = z.infer<
|
|
409
|
+
typeof PluginCoreLayersRenameResult
|
|
410
|
+
>
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Arguments for {@linkcode PluginCoreLayersApi.update}. Sparse: only the
|
|
414
|
+
* provided fields are changed.
|
|
415
|
+
*
|
|
416
|
+
* | Property | Type | Description |
|
|
417
|
+
* |---|---|---|
|
|
418
|
+
* | `layerId` | `string` | The id of the layer to update |
|
|
419
|
+
* | `locked` | `boolean \| undefined` | New locked state (unchanged if omitted) |
|
|
420
|
+
* | `hidden` | `boolean \| undefined` | New hidden state for the current user (unchanged if omitted) |
|
|
421
|
+
*/
|
|
422
|
+
export const PluginCoreLayersUpdateArgs = z.object({
|
|
423
|
+
layerId: z.string(),
|
|
424
|
+
locked: z.boolean().optional(),
|
|
425
|
+
hidden: z.boolean().optional(),
|
|
426
|
+
}).strict()
|
|
427
|
+
export type PluginCoreLayersUpdateArgs = z.infer<
|
|
428
|
+
typeof PluginCoreLayersUpdateArgs
|
|
429
|
+
>
|
|
430
|
+
|
|
431
|
+
/** Result of {@linkcode PluginCoreLayersApi.update}: the updated layer. */
|
|
432
|
+
export const PluginCoreLayersUpdateResult = PluginCoreLayer
|
|
433
|
+
export type PluginCoreLayersUpdateResult = z.infer<
|
|
434
|
+
typeof PluginCoreLayersUpdateResult
|
|
435
|
+
>
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Arguments for {@linkcode PluginCoreLayersApi.setActive}.
|
|
439
|
+
*
|
|
440
|
+
* | Property | Type | Description |
|
|
441
|
+
* |---|---|---|
|
|
442
|
+
* | `layerId` | `string` | The id of the layer to activate |
|
|
443
|
+
*/
|
|
444
|
+
export const PluginCoreLayersSetActiveArgs = z.object({ layerId: z.string() })
|
|
445
|
+
export type PluginCoreLayersSetActiveArgs = z.infer<
|
|
446
|
+
typeof PluginCoreLayersSetActiveArgs
|
|
447
|
+
>
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Result of {@linkcode PluginCoreLayersApi.setActive}.
|
|
451
|
+
*
|
|
452
|
+
* | Property | Type | Description |
|
|
453
|
+
* |---|---|---|
|
|
454
|
+
* | `layerId` | `string` | The id of the now-active layer |
|
|
455
|
+
*/
|
|
456
|
+
export const PluginCoreLayersSetActiveResult = z.object({
|
|
457
|
+
layerId: z.string(),
|
|
458
|
+
})
|
|
459
|
+
export type PluginCoreLayersSetActiveResult = z.infer<
|
|
460
|
+
typeof PluginCoreLayersSetActiveResult
|
|
461
|
+
>
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Arguments for {@linkcode PluginCoreLayersApi.delete}. Exactly one
|
|
465
|
+
* disposition is required: `deleteObjects: true` XOR `targetLayerId` (a
|
|
466
|
+
* **different** layer).
|
|
467
|
+
*
|
|
468
|
+
* | Property | Type | Description |
|
|
469
|
+
* |---|---|---|
|
|
470
|
+
* | `layerId` | `string` | The id of the layer to delete |
|
|
471
|
+
* | `deleteObjects` | `boolean \| undefined` | `true` destroys the layer's objects (exclusive with `targetLayerId`) |
|
|
472
|
+
* | `targetLayerId` | `string \| undefined` | Move the layer's objects to this layer, then delete (exclusive with `deleteObjects`) |
|
|
473
|
+
*/
|
|
474
|
+
export const PluginCoreLayersDeleteArgs = z
|
|
475
|
+
.object({
|
|
476
|
+
layerId: z.string(),
|
|
477
|
+
deleteObjects: z.boolean().optional(),
|
|
478
|
+
targetLayerId: z.string().optional(),
|
|
479
|
+
})
|
|
480
|
+
.refine((v) => (v.deleteObjects === true) !== (v.targetLayerId != null), {
|
|
481
|
+
message:
|
|
482
|
+
"Provide exactly one disposition: deleteObjects: true (destroy the layer's objects) or targetLayerId (move them to that layer, then delete)",
|
|
483
|
+
})
|
|
484
|
+
.refine((v) => v.targetLayerId == null || v.targetLayerId !== v.layerId, {
|
|
485
|
+
message: "targetLayerId must be a different layer than layerId",
|
|
486
|
+
})
|
|
487
|
+
export type PluginCoreLayersDeleteArgs = z.infer<
|
|
488
|
+
typeof PluginCoreLayersDeleteArgs
|
|
489
|
+
>
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Result of {@linkcode PluginCoreLayersApi.delete}.
|
|
493
|
+
*
|
|
494
|
+
* | Property | Type | Description |
|
|
495
|
+
* |---|---|---|
|
|
496
|
+
* | `deleted` | `true` | The layer was deleted |
|
|
497
|
+
*/
|
|
498
|
+
export const PluginCoreLayersDeleteResult = z.object({
|
|
499
|
+
deleted: z.literal(true),
|
|
500
|
+
})
|
|
501
|
+
export type PluginCoreLayersDeleteResult = z.infer<
|
|
502
|
+
typeof PluginCoreLayersDeleteResult
|
|
503
|
+
>
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Arguments for {@linkcode PluginCoreLayersApi.assign}.
|
|
507
|
+
*
|
|
508
|
+
* | Property | Type | Description |
|
|
509
|
+
* |---|---|---|
|
|
510
|
+
* | `componentIds` | `string[]` | The objects to move (at least one) |
|
|
511
|
+
* | `layerId` | `string` | The target layer |
|
|
512
|
+
*/
|
|
513
|
+
export const PluginCoreLayersAssignArgs = z.object({
|
|
514
|
+
componentIds: z.array(ComponentHandle).min(1),
|
|
515
|
+
layerId: z.string(),
|
|
516
|
+
})
|
|
517
|
+
export type PluginCoreLayersAssignArgs = z.infer<
|
|
518
|
+
typeof PluginCoreLayersAssignArgs
|
|
519
|
+
>
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Result of {@linkcode PluginCoreLayersApi.assign}.
|
|
523
|
+
*
|
|
524
|
+
* | Property | Type | Description |
|
|
525
|
+
* |---|---|---|
|
|
526
|
+
* | `assigned` | `string[]` | Ids of the objects that were moved |
|
|
527
|
+
* | `skipped` | `{ id: string; reason: "not-found" \| "locked" \| "outside-proposal" }[]` | Objects that were not moved, each with a reason |
|
|
528
|
+
*/
|
|
529
|
+
export const PluginCoreLayersAssignResult = z.object({
|
|
530
|
+
assigned: z.array(ComponentHandle),
|
|
531
|
+
skipped: z.array(
|
|
532
|
+
z.object({
|
|
533
|
+
id: ComponentHandle,
|
|
534
|
+
reason: z.enum(["not-found", "locked", "outside-proposal"]),
|
|
535
|
+
}),
|
|
536
|
+
),
|
|
537
|
+
})
|
|
538
|
+
export type PluginCoreLayersAssignResult = z.infer<
|
|
539
|
+
typeof PluginCoreLayersAssignResult
|
|
540
|
+
>
|