@snaptrude/plugin-core 0.9.16 → 0.9.18-voids-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.
Files changed (107) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/api-manifest.full.json +10406 -0
  3. package/api-manifest.json +827 -51
  4. package/dist/api/analysis/daylight.d.ts +5 -5
  5. package/dist/api/analysis/solar.d.ts +2 -2
  6. package/dist/api/core/camera/index.d.ts +29 -0
  7. package/dist/api/core/camera/index.d.ts.map +1 -1
  8. package/dist/api/core/geom/create/index.d.ts +7 -1
  9. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  10. package/dist/api/core/geom/update/contour.d.ts +8 -2
  11. package/dist/api/core/geom/update/contour.d.ts.map +1 -1
  12. package/dist/api/core/zoom/index.d.ts +13 -0
  13. package/dist/api/core/zoom/index.d.ts.map +1 -1
  14. package/dist/api/design/bim.d.ts +209 -0
  15. package/dist/api/design/bim.d.ts.map +1 -0
  16. package/dist/api/design/boolean/index.d.ts +2 -0
  17. package/dist/api/design/boolean/index.d.ts.map +1 -1
  18. package/dist/api/design/catalog.d.ts +320 -0
  19. package/dist/api/design/catalog.d.ts.map +1 -0
  20. package/dist/api/design/create/bulk-items.d.ts +65 -25
  21. package/dist/api/design/create/bulk-items.d.ts.map +1 -1
  22. package/dist/api/design/create/index.d.ts +272 -99
  23. package/dist/api/design/create/index.d.ts.map +1 -1
  24. package/dist/api/design/create/opening-fields.d.ts +13 -12
  25. package/dist/api/design/create/opening-fields.d.ts.map +1 -1
  26. package/dist/api/design/delete/index.d.ts +1 -0
  27. package/dist/api/design/delete/index.d.ts.map +1 -1
  28. package/dist/api/design/doors/index.d.ts +18 -24
  29. package/dist/api/design/doors/index.d.ts.map +1 -1
  30. package/dist/api/design/family.d.ts +797 -27
  31. package/dist/api/design/family.d.ts.map +1 -1
  32. package/dist/api/design/index.d.ts +16 -0
  33. package/dist/api/design/index.d.ts.map +1 -1
  34. package/dist/api/design/networks.d.ts +1703 -0
  35. package/dist/api/design/networks.d.ts.map +1 -0
  36. package/dist/api/design/query/index.d.ts +42 -32
  37. package/dist/api/design/query/index.d.ts.map +1 -1
  38. package/dist/api/design/selection/index.d.ts +10 -10
  39. package/dist/api/design/types/index.d.ts +40 -24
  40. package/dist/api/design/types/index.d.ts.map +1 -1
  41. package/dist/api/design/update/index.d.ts +43 -3
  42. package/dist/api/design/update/index.d.ts.map +1 -1
  43. package/dist/api/design/windows/index.d.ts +8 -8
  44. package/dist/api/design/windows/index.d.ts.map +1 -1
  45. package/dist/api/presentation/aiInspiration.d.ts +10 -10
  46. package/dist/api/presentation/annotate.d.ts +38 -22
  47. package/dist/api/presentation/annotate.d.ts.map +1 -1
  48. package/dist/api/presentation/drawingContract.d.ts +32 -0
  49. package/dist/api/presentation/drawingContract.d.ts.map +1 -0
  50. package/dist/api/presentation/drawings.d.ts +3523 -0
  51. package/dist/api/presentation/drawings.d.ts.map +1 -0
  52. package/dist/api/presentation/export.d.ts +23 -5
  53. package/dist/api/presentation/export.d.ts.map +1 -1
  54. package/dist/api/presentation/index.d.ts +41 -12
  55. package/dist/api/presentation/index.d.ts.map +1 -1
  56. package/dist/api/presentation/placedViews.d.ts +106 -6
  57. package/dist/api/presentation/placedViews.d.ts.map +1 -1
  58. package/dist/api/presentation/sections.d.ts +461 -0
  59. package/dist/api/presentation/sections.d.ts.map +1 -0
  60. package/dist/api/presentation/shapes.d.ts +2 -2
  61. package/dist/api/presentation/sheets.d.ts +175 -19
  62. package/dist/api/presentation/sheets.d.ts.map +1 -1
  63. package/dist/api/presentation/viewPresets.d.ts +222 -0
  64. package/dist/api/presentation/viewPresets.d.ts.map +1 -0
  65. package/dist/api/presentation/views.d.ts +103 -5
  66. package/dist/api/presentation/views.d.ts.map +1 -1
  67. package/dist/api/presentation/walkthroughs.d.ts +6 -6
  68. package/dist/errors/codes.d.ts +3 -1
  69. package/dist/errors/codes.d.ts.map +1 -1
  70. package/dist/index.cjs +3749 -2328
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.js +3616 -2328
  73. package/dist/index.js.map +1 -1
  74. package/package.json +1 -1
  75. package/scripts/generate-manifest.mjs +5 -0
  76. package/src/api/core/camera/index.ts +29 -0
  77. package/src/api/core/geom/create/index.ts +7 -1
  78. package/src/api/core/geom/update/contour.ts +8 -2
  79. package/src/api/core/zoom/index.ts +13 -0
  80. package/src/api/design/bim.ts +121 -0
  81. package/src/api/design/boolean/index.ts +2 -0
  82. package/src/api/design/catalog.ts +203 -0
  83. package/src/api/design/create/bulk-items.ts +57 -17
  84. package/src/api/design/create/index.ts +288 -120
  85. package/src/api/design/create/opening-fields.ts +15 -12
  86. package/src/api/design/delete/index.ts +1 -0
  87. package/src/api/design/doors/index.ts +58 -42
  88. package/src/api/design/family.ts +662 -32
  89. package/src/api/design/index.ts +34 -4
  90. package/src/api/design/networks.ts +607 -0
  91. package/src/api/design/query/index.ts +12 -2
  92. package/src/api/design/types/index.ts +31 -24
  93. package/src/api/design/update/index.ts +44 -3
  94. package/src/api/design/windows/index.ts +40 -22
  95. package/src/api/presentation/annotate.ts +90 -58
  96. package/src/api/presentation/drawingContract.ts +70 -0
  97. package/src/api/presentation/drawings.ts +1179 -0
  98. package/src/api/presentation/export.ts +32 -6
  99. package/src/api/presentation/index.ts +48 -14
  100. package/src/api/presentation/placedViews.ts +119 -28
  101. package/src/api/presentation/sections.ts +420 -0
  102. package/src/api/presentation/sheets.ts +181 -20
  103. package/src/api/presentation/viewPresets.ts +241 -0
  104. package/src/api/presentation/views.ts +46 -6
  105. package/src/errors/codes.ts +7 -0
  106. package/test/drawingContract.test.mjs +288 -0
  107. package/test/errors.test.mjs +1 -0
@@ -34,14 +34,15 @@ export abstract class PluginPresentationAnnotateApi {
34
34
  * falls back to regular. `fontSizePx` sets an exact pixel size, overriding
35
35
  * the `size` preset when both are given (`size` alone keeps working).
36
36
  *
37
- * @param sheetId - The sheet to annotate.
37
+ * @param sheetId - The sheet to annotate, or `undefined` when `options.drawingId` is used.
38
38
  * @param text - The label text.
39
39
  * @param options - Optional `position` (`{ x, y }`, relative to the sheet's
40
40
  * top-left, in canvas units — defaults to the sheet's top-left corner),
41
41
  * `size` (`"s" | "m" | "l" | "xl"`, default `"m"`), `color` (a named
42
42
  * palette color, default `"black"`), and typography: `fontFamily`,
43
43
  * `fontWeight` (numeric string, `-italic` suffix allowed), `fontSizePx`
44
- * (positive px size overriding the `size` preset).
44
+ * (positive px size overriding the `size` preset), and `drawingId` to parent
45
+ * the annotation to a drawing. Pass exactly one parent: `sheetId` or `drawingId`.
45
46
  * @returns A {@linkcode PluginPresentationAnnotateTextResult} with the created
46
47
  * `shapeId`.
47
48
  * @throws If Present mode is not open or the sheet id is invalid.
@@ -61,7 +62,7 @@ export abstract class PluginPresentationAnnotateApi {
61
62
  * ```
62
63
  */
63
64
  public abstract text(
64
- sheetId: string,
65
+ sheetId: string | undefined,
65
66
  text: string,
66
67
  options?: {
67
68
  position?: { x: number; y: number }
@@ -70,6 +71,7 @@ export abstract class PluginPresentationAnnotateApi {
70
71
  fontFamily?: string
71
72
  fontWeight?: string
72
73
  fontSizePx?: number
74
+ drawingId?: string
73
75
  },
74
76
  ): PluginApiReturn<PluginPresentationAnnotateTextResult>
75
77
 
@@ -80,11 +82,12 @@ export abstract class PluginPresentationAnnotateApi {
80
82
  * top-left, in canvas units — the same Arrow tool as the Present toolbar) and
81
83
  * returns the id of the created canvas shape. Requires Present mode to be open.
82
84
  *
83
- * @param sheetId - The sheet to annotate.
85
+ * @param sheetId - The sheet to annotate, or `undefined` when `options.drawingId` is used.
84
86
  * @param start - Arrow tail position (`{ x, y }`, relative to the sheet's top-left).
85
87
  * @param end - Arrow head position (`{ x, y }`, relative to the sheet's top-left).
86
88
  * @param options - Optional `color` (a named palette color, default `"black"`)
87
- * and `size` (stroke weight preset, `"s" | "m" | "l" | "xl"`, default `"m"`).
89
+ * `size` (stroke weight preset, `"s" | "m" | "l" | "xl"`, default `"m"`),
90
+ * and `drawingId` to parent the arrow to a drawing. Pass exactly one parent.
88
91
  * @returns A {@linkcode PluginPresentationAnnotateResult} with the created
89
92
  * `shapeId`.
90
93
  * @throws If Present mode is not open or the sheet id is invalid.
@@ -104,12 +107,13 @@ export abstract class PluginPresentationAnnotateApi {
104
107
  * ```
105
108
  */
106
109
  public abstract arrow(
107
- sheetId: string,
110
+ sheetId: string | undefined,
108
111
  start: { x: number; y: number },
109
112
  end: { x: number; y: number },
110
113
  options?: {
111
114
  color?: PluginAnnotateTextColor
112
115
  size?: PluginAnnotateTextSize
116
+ drawingId?: string
113
117
  },
114
118
  ): PluginApiReturn<PluginPresentationAnnotateResult>
115
119
 
@@ -120,13 +124,14 @@ export abstract class PluginPresentationAnnotateApi {
120
124
  * fixed-size sticky square that grows with its text) and returns the id of
121
125
  * the created canvas shape. Requires Present mode to be open.
122
126
  *
123
- * @param sheetId - The sheet to annotate.
127
+ * @param sheetId - The sheet to annotate, or `undefined` when `options.drawingId` is used.
124
128
  * @param text - The note text.
125
129
  * @param options - Optional `position` (`{ x, y }`, relative to the sheet's
126
130
  * top-left, in canvas units — defaults to the sheet's top-left corner),
127
131
  * `color` (a named palette color, default `"black"` — rendered as the
128
132
  * note's sticky fill), and `size` (text size preset,
129
- * `"s" | "m" | "l" | "xl"`, default `"m"`).
133
+ * `"s" | "m" | "l" | "xl"`, default `"m"`), and `drawingId` to parent
134
+ * the note to a drawing. Pass exactly one parent.
130
135
  * @returns A {@linkcode PluginPresentationAnnotateResult} with the created
131
136
  * `shapeId`.
132
137
  * @throws If Present mode is not open or the sheet id is invalid.
@@ -145,12 +150,13 @@ export abstract class PluginPresentationAnnotateApi {
145
150
  * ```
146
151
  */
147
152
  public abstract note(
148
- sheetId: string,
153
+ sheetId: string | undefined,
149
154
  text: string,
150
155
  options?: {
151
156
  position?: { x: number; y: number }
152
157
  color?: PluginAnnotateTextColor
153
158
  size?: PluginAnnotateTextSize
159
+ drawingId?: string
154
160
  },
155
161
  ): PluginApiReturn<PluginPresentationAnnotateResult>
156
162
 
@@ -162,14 +168,15 @@ export abstract class PluginPresentationAnnotateApi {
162
168
  * top-left, in canvas units) and returns the id of the created canvas shape.
163
169
  * Requires Present mode to be open.
164
170
  *
165
- * @param sheetId - The sheet to annotate.
171
+ * @param sheetId - The sheet to annotate, or `undefined` when `options.drawingId` is used.
166
172
  * @param kind - The shape kind ({@linkcode PluginAnnotateGeoKind}), e.g.
167
173
  * `"rectangle"`, `"ellipse"`, `"cloud"`.
168
174
  * @param bounds - Placement box `{ x, y, w, h }` — `x`/`y` are the shape's
169
175
  * top-left relative to the sheet's top-left; `w`/`h` must be positive.
170
176
  * @param options - Optional `color` (a named palette color, default
171
177
  * `"black"`) and `fill` ({@linkcode PluginAnnotateFill}, default `"none"` —
172
- * outline only).
178
+ * outline only), and `drawingId` to parent the shape to a drawing. Pass
179
+ * exactly one parent: `sheetId` or `drawingId`.
173
180
  * @returns A {@linkcode PluginPresentationAnnotateResult} with the created
174
181
  * `shapeId`.
175
182
  * @throws If Present mode is not open or the sheet id is invalid.
@@ -189,12 +196,13 @@ export abstract class PluginPresentationAnnotateApi {
189
196
  * ```
190
197
  */
191
198
  public abstract shape(
192
- sheetId: string,
199
+ sheetId: string | undefined,
193
200
  kind: PluginAnnotateGeoKind,
194
201
  bounds: { x: number; y: number; w: number; h: number },
195
202
  options?: {
196
203
  color?: PluginAnnotateTextColor
197
204
  fill?: PluginAnnotateFill
205
+ drawingId?: string
198
206
  },
199
207
  ): PluginApiReturn<PluginPresentationAnnotateResult>
200
208
  }
@@ -226,7 +234,8 @@ export type PluginAnnotateTextColor = z.infer<typeof PluginAnnotateTextColor>
226
234
  *
227
235
  * | Property | Type | Description |
228
236
  * |---|---|---|
229
- * | `sheetId` | `string` | The sheet to annotate |
237
+ * | `sheetId` | `string \| undefined` | The sheet parent; omit when `drawingId` is set |
238
+ * | `drawingId` | `string \| undefined` | The drawing parent; mutually exclusive with `sheetId` |
230
239
  * | `text` | `string` | The label text |
231
240
  * | `position` | `{ x: number; y: number } \| undefined` | Where to place it (relative to the sheet) |
232
241
  * | `size` | {@linkcode PluginAnnotateTextSize}` \| undefined` | Text size preset |
@@ -235,22 +244,27 @@ export type PluginAnnotateTextColor = z.infer<typeof PluginAnnotateTextColor>
235
244
  * | `fontWeight` | `string \| undefined` | Numeric weight like `"400"`/`"700"`, `-italic` suffix allowed |
236
245
  * | `fontSizePx` | `number \| undefined` | Exact px size (overrides the `size` preset) |
237
246
  */
238
- export const PluginPresentationAnnotateTextArgs = z.object({
239
- sheetId: z.string(),
240
- text: z.string(),
241
- position: z.object({ x: z.number(), y: z.number() }).optional(),
242
- size: PluginAnnotateTextSize.optional(),
243
- color: PluginAnnotateTextColor.optional(),
244
- fontFamily: z.string().min(1).optional(),
245
- fontWeight: z
246
- .string()
247
- .regex(
248
- /^\d{3}(-italic)?$/,
249
- 'fontWeight must be a numeric string like "400" or "700", optionally with the "-italic" suffix',
250
- )
251
- .optional(),
252
- fontSizePx: z.number().finite().positive().optional(),
253
- })
247
+ export const PluginPresentationAnnotateTextArgs = z
248
+ .object({
249
+ sheetId: z.string().min(1).optional(),
250
+ drawingId: z.string().min(1).optional(),
251
+ text: z.string(),
252
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
253
+ size: PluginAnnotateTextSize.optional(),
254
+ color: PluginAnnotateTextColor.optional(),
255
+ fontFamily: z.string().min(1).optional(),
256
+ fontWeight: z
257
+ .string()
258
+ .regex(
259
+ /^\d{3}(-italic)?$/,
260
+ 'fontWeight must be a numeric string like "400" or "700", optionally with the "-italic" suffix',
261
+ )
262
+ .optional(),
263
+ fontSizePx: z.number().finite().positive().optional(),
264
+ })
265
+ .refine(({ sheetId, drawingId }) => Boolean(sheetId) !== Boolean(drawingId), {
266
+ message: "exactly one of sheetId or drawingId is required",
267
+ })
254
268
  export type PluginPresentationAnnotateTextArgs = z.infer<
255
269
  typeof PluginPresentationAnnotateTextArgs
256
270
  >
@@ -302,19 +316,25 @@ export type PluginAnnotateFill = z.infer<typeof PluginAnnotateFill>
302
316
  *
303
317
  * | Property | Type | Description |
304
318
  * |---|---|---|
305
- * | `sheetId` | `string` | The sheet to annotate |
319
+ * | `sheetId` | `string \| undefined` | The sheet parent; omit when `drawingId` is set |
320
+ * | `drawingId` | `string \| undefined` | The drawing parent; mutually exclusive with `sheetId` |
306
321
  * | `start` | `{ x: number; y: number }` | Arrow tail (relative to the sheet) |
307
322
  * | `end` | `{ x: number; y: number }` | Arrow head (relative to the sheet) |
308
323
  * | `color` | {@linkcode PluginAnnotateTextColor}` \| undefined` | Arrow color |
309
324
  * | `size` | {@linkcode PluginAnnotateTextSize}` \| undefined` | Stroke weight preset |
310
325
  */
311
- export const PluginPresentationAnnotateArrowArgs = z.object({
312
- sheetId: z.string(),
313
- start: z.object({ x: z.number(), y: z.number() }),
314
- end: z.object({ x: z.number(), y: z.number() }),
315
- color: PluginAnnotateTextColor.optional(),
316
- size: PluginAnnotateTextSize.optional(),
317
- })
326
+ export const PluginPresentationAnnotateArrowArgs = z
327
+ .object({
328
+ sheetId: z.string().min(1).optional(),
329
+ drawingId: z.string().min(1).optional(),
330
+ start: z.object({ x: z.number(), y: z.number() }),
331
+ end: z.object({ x: z.number(), y: z.number() }),
332
+ color: PluginAnnotateTextColor.optional(),
333
+ size: PluginAnnotateTextSize.optional(),
334
+ })
335
+ .refine(({ sheetId, drawingId }) => Boolean(sheetId) !== Boolean(drawingId), {
336
+ message: "exactly one of sheetId or drawingId is required",
337
+ })
318
338
  export type PluginPresentationAnnotateArrowArgs = z.infer<
319
339
  typeof PluginPresentationAnnotateArrowArgs
320
340
  >
@@ -324,19 +344,25 @@ export type PluginPresentationAnnotateArrowArgs = z.infer<
324
344
  *
325
345
  * | Property | Type | Description |
326
346
  * |---|---|---|
327
- * | `sheetId` | `string` | The sheet to annotate |
347
+ * | `sheetId` | `string \| undefined` | The sheet parent; omit when `drawingId` is set |
348
+ * | `drawingId` | `string \| undefined` | The drawing parent; mutually exclusive with `sheetId` |
328
349
  * | `text` | `string` | The note text |
329
350
  * | `position` | `{ x: number; y: number } \| undefined` | Where to place it (relative to the sheet) |
330
351
  * | `color` | {@linkcode PluginAnnotateTextColor}` \| undefined` | Sticky fill color |
331
352
  * | `size` | {@linkcode PluginAnnotateTextSize}` \| undefined` | Text size preset |
332
353
  */
333
- export const PluginPresentationAnnotateNoteArgs = z.object({
334
- sheetId: z.string(),
335
- text: z.string(),
336
- position: z.object({ x: z.number(), y: z.number() }).optional(),
337
- color: PluginAnnotateTextColor.optional(),
338
- size: PluginAnnotateTextSize.optional(),
339
- })
354
+ export const PluginPresentationAnnotateNoteArgs = z
355
+ .object({
356
+ sheetId: z.string().min(1).optional(),
357
+ drawingId: z.string().min(1).optional(),
358
+ text: z.string(),
359
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
360
+ color: PluginAnnotateTextColor.optional(),
361
+ size: PluginAnnotateTextSize.optional(),
362
+ })
363
+ .refine(({ sheetId, drawingId }) => Boolean(sheetId) !== Boolean(drawingId), {
364
+ message: "exactly one of sheetId or drawingId is required",
365
+ })
340
366
  export type PluginPresentationAnnotateNoteArgs = z.infer<
341
367
  typeof PluginPresentationAnnotateNoteArgs
342
368
  >
@@ -346,24 +372,30 @@ export type PluginPresentationAnnotateNoteArgs = z.infer<
346
372
  *
347
373
  * | Property | Type | Description |
348
374
  * |---|---|---|
349
- * | `sheetId` | `string` | The sheet to annotate |
375
+ * | `sheetId` | `string \| undefined` | The sheet parent; omit when `drawingId` is set |
376
+ * | `drawingId` | `string \| undefined` | The drawing parent; mutually exclusive with `sheetId` |
350
377
  * | `kind` | {@linkcode PluginAnnotateGeoKind} | The shape kind |
351
378
  * | `bounds` | `{ x: number; y: number; w: number; h: number }` | Placement box (relative to the sheet; `w`/`h` positive) |
352
379
  * | `color` | {@linkcode PluginAnnotateTextColor}` \| undefined` | Outline color |
353
380
  * | `fill` | {@linkcode PluginAnnotateFill}` \| undefined` | Fill style |
354
381
  */
355
- export const PluginPresentationAnnotateShapeArgs = z.object({
356
- sheetId: z.string(),
357
- kind: PluginAnnotateGeoKind,
358
- bounds: z.object({
359
- x: z.number(),
360
- y: z.number(),
361
- w: z.number().positive(),
362
- h: z.number().positive(),
363
- }),
364
- color: PluginAnnotateTextColor.optional(),
365
- fill: PluginAnnotateFill.optional(),
366
- })
382
+ export const PluginPresentationAnnotateShapeArgs = z
383
+ .object({
384
+ sheetId: z.string().min(1).optional(),
385
+ drawingId: z.string().min(1).optional(),
386
+ kind: PluginAnnotateGeoKind,
387
+ bounds: z.object({
388
+ x: z.number(),
389
+ y: z.number(),
390
+ w: z.number().positive(),
391
+ h: z.number().positive(),
392
+ }),
393
+ color: PluginAnnotateTextColor.optional(),
394
+ fill: PluginAnnotateFill.optional(),
395
+ })
396
+ .refine(({ sheetId, drawingId }) => Boolean(sheetId) !== Boolean(drawingId), {
397
+ message: "exactly one of sheetId or drawingId is required",
398
+ })
367
399
  export type PluginPresentationAnnotateShapeArgs = z.infer<
368
400
  typeof PluginPresentationAnnotateShapeArgs
369
401
  >
@@ -0,0 +1,70 @@
1
+ import * as z from "zod"
2
+
3
+ /**
4
+ * Metric architectural scale denominators (`100` means 1:100), the metric
5
+ * values of the placed view's Scale dropdown.
6
+ */
7
+ export const METRIC_DRAWING_SCALES = [
8
+ 10, 20, 50, 100, 150, 200, 250, 500, 1000,
9
+ ] as const
10
+
11
+ /**
12
+ * Imperial detail scale denominators, 1" = 1' (12) to 1/128" = 1' (1536):
13
+ * `48` is 1/4" = 1', `96` is 1/8" = 1'.
14
+ */
15
+ export const IMPERIAL_DETAIL_DRAWING_SCALES = [
16
+ 12, 16, 24, 32, 48, 64, 96, 128, 192, 384, 768, 1536,
17
+ ] as const
18
+
19
+ /** Imperial site (engineering) scale denominators, 1" = 10' (120) to 1" = 400' (4800). */
20
+ export const IMPERIAL_SITE_DRAWING_SCALES = [
21
+ 120, 240, 360, 480, 600, 1200, 2400, 3600, 4800,
22
+ ] as const
23
+
24
+ /**
25
+ * Imperial architectural scale denominators, ascending: the imperial detail
26
+ * and site values of the placed view's Scale dropdown.
27
+ */
28
+ export const IMPERIAL_DRAWING_SCALES: readonly number[] = [
29
+ ...IMPERIAL_DETAIL_DRAWING_SCALES,
30
+ ...IMPERIAL_SITE_DRAWING_SCALES,
31
+ ].sort((a, b) => a - b)
32
+
33
+ /**
34
+ * Every standard architectural scale denominator, metric and imperial,
35
+ * ascending. Drawing and placed-view scale arguments accept only these; the
36
+ * host may further restrict them to the project's unit system.
37
+ */
38
+ export const STANDARD_DRAWING_SCALES: readonly number[] = [
39
+ ...METRIC_DRAWING_SCALES,
40
+ ...IMPERIAL_DRAWING_SCALES,
41
+ ].sort((a, b) => a - b)
42
+
43
+ const standardScaleSet = new Set<number>(STANDARD_DRAWING_SCALES)
44
+
45
+ /** A standard architectural scale denominator; anything else is rejected with the allowed list. */
46
+ export const PluginStandardDrawingScale = z
47
+ .number()
48
+ .finite()
49
+ .refine((scale) => standardScaleSet.has(scale), {
50
+ message: `Scale must be a standard architectural scale denominator in the project's unit system. Metric: ${METRIC_DRAWING_SCALES.join(", ")}; imperial detail: ${IMPERIAL_DETAIL_DRAWING_SCALES.join(", ")}; imperial site: ${IMPERIAL_SITE_DRAWING_SCALES.join(", ")}. Pick the largest standard scale (smallest denominator) at which the view fits its frame or sheet and its room labels stay readable (usually 1:50 to 1:200 for a building plan).`,
51
+ })
52
+
53
+ const EXTENSION = /\.(pdf|svg|png|jpe?g)$/i
54
+ // The host appends ".<ext>", so a trailing dot yields "a.pdf..pdf" and trailing
55
+ // whitespace yields "plan .pdf".
56
+ const TRAILING_DOT_OR_SPACE = /[.\s]$/
57
+
58
+ /**
59
+ * An export base file name without an extension, not ending in a dot or
60
+ * whitespace; the host adds `.pdf`, `.svg`, `.png` or `.jpg`.
61
+ */
62
+ export const PluginExportFileName = z
63
+ .string()
64
+ .refine(
65
+ (name) => !EXTENSION.test(name.trim()) && !TRAILING_DOT_OR_SPACE.test(name),
66
+ {
67
+ message:
68
+ "fileName must be a base name without an extension and not ending in a dot or a space (for example \"Ground Floor Plan\", not \"Ground Floor Plan.pdf\" or \"Ground Floor Plan.\"); the export adds the extension for the format.",
69
+ },
70
+ )