lineadraw 0.7.0 → 0.9.0

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/lineadraw.d.ts CHANGED
@@ -10,14 +10,34 @@ declare module "lineadraw" {
10
10
  y: number;
11
11
  };
12
12
  export type Vec2Like = Vec2 | readonly [number, number];
13
+ /** An axis-aligned box (mm). */
14
+ export type Box = {
15
+ minX: number;
16
+ minY: number;
17
+ maxX: number;
18
+ maxY: number;
19
+ };
20
+ /** Arrowhead styles (leaders, dimensions). */
21
+ export type ArrowType = "filled" | "open" | "tick" | "dot" | "none";
22
+ /** Print color remap: as authored, gray levels, or everything black. */
23
+ export type PrintPalette = "color" | "grayscale" | "monochrome";
13
24
  /** Polyline vertex; bulge = tan(sweep/4), 0 = straight. Accepts [x, y, bulge?]. */
14
- export type PolylineVertexLike = {
25
+ export type PolylineVertexInput = {
15
26
  x: number;
16
27
  y: number;
17
28
  bulge?: number;
18
29
  } | readonly [number, number, number?];
19
- /** Style overrides children may carry (otherwise inherited from the instance). */
20
- export type BaseStyle = {
30
+ /** The fields every object input may carry: its layer and the style
31
+ * overrides (otherwise by layer — or, for a block child, by the instance). */
32
+ export type ObjectInputBase = {
33
+ /** The layer, by NAME or id. Absent: `document.add` uses the current
34
+ * layer, a block child the instance's (the portable default; an unknown
35
+ * name falls back to it too). A child on another layer hides with that
36
+ * layer, while its color / line type / width still follow the instance
37
+ * unless it sets its own (ByBlock, as in CAD). */
38
+ layer?: string;
39
+ /** The layer by id only — prefer `layer`. */
40
+ layerId?: string;
21
41
  /** #rrggbb; absent = by layer. */
22
42
  color?: string;
23
43
  /** Line type; absent = by layer. */
@@ -26,39 +46,41 @@ declare module "lineadraw" {
26
46
  lineTypeScale?: number;
27
47
  /** Line weight in mm; absent = by layer. */
28
48
  lineWidth?: number;
49
+ /** Paint opacity 0..1; absent = by layer (opaque unless the layer says). */
50
+ opacity?: number;
29
51
  };
30
52
  /**
31
- * T plus the shared style fields, FLATTENED (the homomorphic map forces the
53
+ * T plus the shared input fields, FLATTENED (the homomorphic map forces the
32
54
  * intersection to resolve): hovers then list every member inline instead of
33
- * the opaque `BaseStyle & { … }` — the block editor has no expand-type
34
- * affordance, so the alias display is all a script author gets.
55
+ * the opaque `ObjectInputBase & { … }` — the block editor has no
56
+ * expand-type affordance, so the alias display is all a script author gets.
35
57
  */
36
- type Styled<T> = {
37
- [K in keyof (T & BaseStyle)]: (T & BaseStyle)[K];
58
+ type ObjectInputShape<T> = {
59
+ [K in keyof (T & ObjectInputBase)]: (T & ObjectInputBase)[K];
38
60
  } & {};
39
- export type Line = Styled<{
61
+ export type LineInput = ObjectInputShape<{
40
62
  type: "line";
41
63
  a: Vec2Like;
42
64
  b: Vec2Like;
43
65
  }>;
44
66
  /** A point: paints as a round dot whose diameter is the lineWidth. */
45
- export type Point = Styled<{
67
+ export type PointInput = ObjectInputShape<{
46
68
  type: "point";
47
69
  p: Vec2Like;
48
70
  }>;
49
- export type Polyline = Styled<{
71
+ export type PolylineInput = ObjectInputShape<{
50
72
  type: "polyline";
51
73
  /** At least 2 vertices. */
52
- points: readonly PolylineVertexLike[];
74
+ points: readonly PolylineVertexInput[];
53
75
  closed?: boolean;
54
76
  }>;
55
- export type Circle = Styled<{
77
+ export type CircleInput = ObjectInputShape<{
56
78
  type: "circle";
57
79
  center: Vec2Like;
58
80
  radius: number;
59
81
  }>;
60
82
  /** Runs CCW from startAngle to endAngle (radians; DXF ARC convention). */
61
- export type Arc = Styled<{
83
+ export type ArcInput = ObjectInputShape<{
62
84
  type: "arc";
63
85
  center: Vec2Like;
64
86
  radius: number;
@@ -66,7 +88,7 @@ declare module "lineadraw" {
66
88
  endAngle: number;
67
89
  }>;
68
90
  /** majorAxis = endpoint vector from center; ratio = minor/major in (0, 1]. */
69
- export type Ellipse = Styled<{
91
+ export type EllipseInput = ObjectInputShape<{
70
92
  type: "ellipse";
71
93
  center: Vec2Like;
72
94
  majorAxis: Vec2Like;
@@ -74,14 +96,25 @@ declare module "lineadraw" {
74
96
  startAngle?: number;
75
97
  endAngle?: number;
76
98
  }>;
77
- export type Hatch = Styled<{
99
+ export type HatchInput = ObjectInputShape<{
78
100
  type: "hatch";
79
101
  /** loops[0] = outer boundary, the rest are holes (even-odd). */
80
102
  loops: readonly {
81
- points: readonly PolylineVertexLike[];
103
+ points: readonly PolylineVertexInput[];
82
104
  }[];
83
105
  fill?: {
84
106
  kind: "solid";
107
+ }
108
+ /** A named pattern: the built-in catalogue (ANSI31, AR-CONC, …) or one of
109
+ * the document's own hatch patterns, by name. `angle` radians, `scale`
110
+ * multiplies the definition's mm; `origin` anchors the pattern frame
111
+ * (block-local mm; absent = the block origin). */
112
+ | {
113
+ kind: "pattern";
114
+ name: string;
115
+ angle: number;
116
+ scale: number;
117
+ origin?: Vec2Like;
85
118
  } | {
86
119
  kind: "lines";
87
120
  angle: number;
@@ -96,10 +129,26 @@ declare module "lineadraw" {
96
129
  /** Pattern spacing multiplier. */
97
130
  scale?: number;
98
131
  }>;
99
- export type Text = Styled<{
132
+ /** Character formatting over [start, end) of a text's `content` (JS string
133
+ * indices). Absent attributes inherit the text's style; `height` is a ratio
134
+ * of its cap height. Setting `content` without `spans` drops old spans. */
135
+ export type TextSpan = {
136
+ start: number;
137
+ end: number;
138
+ font?: string;
139
+ bold?: boolean;
140
+ italic?: boolean;
141
+ underline?: boolean;
142
+ /** "#rrggbb". */
143
+ color?: string;
144
+ height?: number;
145
+ script?: "sub" | "super";
146
+ };
147
+ export type TextInput = ObjectInputShape<{
100
148
  type: "text";
101
149
  position: Vec2Like;
102
150
  content: string;
151
+ spans?: readonly TextSpan[];
103
152
  rotation?: number;
104
153
  /** Justification, as in AutoCAD / DXF: which edge sits on the point —
105
154
  * "left" = the text runs right of it, "right" = left of it; vAlign
@@ -111,46 +160,45 @@ declare module "lineadraw" {
111
160
  frame?: "none" | "rectangle" | "circle" | "slot" | "bottom" | "firstLine";
112
161
  /** MLEADER-style arrow polylines pointing at the text (arrowhead at [0]). */
113
162
  leaderLines?: readonly (readonly Vec2Like[])[];
163
+ /** The document text style to follow (name or id); absent = the first. */
164
+ styleId?: string;
114
165
  /** Style overrides; absent keys inherit the document text style. */
115
- styleOverride?: {
116
- font?: string;
117
- widthFactor?: number;
118
- bold?: boolean;
119
- italic?: boolean;
120
- /** Cap height in mm (before `scale`). */
121
- textHeight?: number;
122
- arrowSize?: number;
123
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
124
- };
166
+ styleOverride?: TextStyleOverride;
125
167
  /** Size multiplier for height + arrow size. */
126
168
  scale?: number;
127
169
  }>;
128
- export type Dimension = Styled<{
170
+ export type DimensionInput = ObjectInputShape<{
129
171
  type: "dimension";
130
172
  kind?: "linear" | "angular" | "radial" | "diameter";
131
173
  /** linear: 2+ chained points (measured point to point); angular: [vertex, a, b]; radial: [center, p]; diameter: [p1, p2]. */
132
174
  points: readonly Vec2Like[];
133
- /** Dimension line offset from the kind's anchor (points[0]; diameter: the
134
- * points' midpoint). anchor + offset lies on the dimension line (angular:
135
- * on the arc; radial/diameter: at the text). */
136
- offset: Vec2Like;
137
- textOverride?: string;
138
- styleOverride?: {
139
- textHeight?: number;
140
- arrowSize?: number;
141
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
142
- /** "short" = a 2×overshoot tick across the dimension line. */
143
- extensionType?: "long" | "short";
144
- extensionOffset?: number;
145
- extensionOvershoot?: number;
146
- textOffset?: number;
147
- precision?: number;
148
- };
175
+ /** linear only: the measuring direction, radians CCW from +X. Unset =
176
+ * aligned to the points. */
177
+ rotation?: number;
178
+ /** linear: signed distance of the dimension line from points[0], positive
179
+ * to the LEFT of the measuring direction; angular: signed arc radius
180
+ * (negative = the complementary arc). Not for radial/diameter. */
181
+ offset?: number;
182
+ /** One per measured segment (linear chain: points.length − 1, others: 1).
183
+ * `along` (mm along the line from the segment origin — radial/diameter:
184
+ * from the center) and `across` (mm off the line) place the text, unset =
185
+ * automatic; `content` is the text, `{value}` = the measurement. */
186
+ labels?: readonly {
187
+ along?: number;
188
+ across?: number;
189
+ content?: string;
190
+ /** Formatting over `content` (spans covering `{value}` format it). */
191
+ spans?: readonly TextSpan[];
192
+ }[];
193
+ /** The document dimension style to follow (name or id); absent = the first. */
194
+ styleId?: string;
195
+ /** Style overrides; absent keys inherit the document dimension style. */
196
+ styleOverride?: DimStyleOverride;
149
197
  /** Annotation size multiplier (text/arrows/offsets). */
150
198
  scale?: number;
151
199
  }>;
152
200
  /** Nested block instance (inputs may hold points, never object references). */
153
- export type Block = Styled<{
201
+ export type BlockInput = ObjectInputShape<{
154
202
  type: "block";
155
203
  definitionId: string;
156
204
  /** Applied last, about the pivot (the first input point). */
@@ -161,8 +209,10 @@ declare module "lineadraw" {
161
209
  inputs?: readonly Vec2Like[];
162
210
  }>;
163
211
  /** A table cell: plain text, or text with merge / alignment / style. */
164
- export type TableCell = string | {
165
- text?: string;
212
+ export type TableCellInput = string | {
213
+ content?: string;
214
+ /** Character formatting over `content`. */
215
+ spans?: readonly TextSpan[];
166
216
  /** Merge from this (top-left) cell; covered cells are ignored. */
167
217
  span?: {
168
218
  cols: number;
@@ -176,7 +226,7 @@ declare module "lineadraw" {
176
226
  };
177
227
  /** Grid of text cells hanging right/down from `position` (top-left);
178
228
  * rows grow to fit their wrapped text. */
179
- export type Table = Styled<{
229
+ export type TableInput = ObjectInputShape<{
180
230
  type: "table";
181
231
  position: Vec2Like;
182
232
  /** Column widths (mm, before `scale`). */
@@ -186,7 +236,7 @@ declare module "lineadraw" {
186
236
  minHeight?: number;
187
237
  }[];
188
238
  /** Row-major `cells[row][column]`, exactly rows × columns. */
189
- cells: readonly (readonly TableCell[])[];
239
+ cells: readonly (readonly TableCellInput[])[];
190
240
  rotation?: number;
191
241
  scale?: number;
192
242
  /** Rows above the heavier header rule. */
@@ -197,9 +247,84 @@ declare module "lineadraw" {
197
247
  styleId?: string;
198
248
  styleOverride?: TextStyleOverride;
199
249
  }>;
200
- export type ModelObject = Line | Point | Polyline | Circle | Arc | Ellipse | Hatch | Text | Dimension | Block | Table;
250
+ /** Where a reference's file lives: a path (relative to the drawing's
251
+ * folder), a url, or EMBEDDED — an asset of the document holding it (add the
252
+ * file's bytes first with `document.addAsset`). */
253
+ export type ReferenceSource = {
254
+ kind: "path";
255
+ path: string;
256
+ cacheKey?: string;
257
+ } | {
258
+ kind: "url";
259
+ url: string;
260
+ } | {
261
+ kind: "asset";
262
+ assetId: string;
263
+ };
264
+ /** A file drawn in place — a .linea, DXF, DWG, PDF page or picture (PNG /
265
+ * JPEG). The file's origin lands at `position`; a picture draws at its
266
+ * natural size (96 dpi) times `scale`. */
267
+ export type ReferenceInput = ObjectInputShape<{
268
+ type: "reference";
269
+ format: "linea" | "dxf" | "dwg" | "pdf" | "png" | "jpg";
270
+ name: string;
271
+ source: ReferenceSource;
272
+ position: Vec2Like;
273
+ /** Radians CCW about `position`. */
274
+ rotation?: number;
275
+ scale?: number;
276
+ /** Flipped left-right (x → −x) before the rotation. */
277
+ mirrored?: boolean;
278
+ /** PDF: the 1-based page, drawn as vectors or rasterized. */
279
+ pdfPage?: number;
280
+ pdfMode?: "vector" | "raster";
281
+ /** The file's layers not drawn, by name. */
282
+ hiddenLayers?: readonly string[];
283
+ hidden?: boolean;
284
+ locked?: boolean;
285
+ /** Crop rectangle in file coordinates. */
286
+ clip?: Box;
287
+ /** Content bounds in file coordinates (the frame drawn before it loads). */
288
+ extent?: Box;
289
+ }>;
290
+ /** Paper-space window into model space; only in a layout (`document.add`
291
+ * with `layout`). */
292
+ export type ViewportInput = ObjectInputShape<{
293
+ type: "viewport";
294
+ /** The frame on the sheet (mm): bottom-left corner + size. */
295
+ rect: {
296
+ x: number;
297
+ y: number;
298
+ w: number;
299
+ h: number;
300
+ };
301
+ /** The model point shown at the frame's centre. */
302
+ modelCenter?: Vec2Like;
303
+ /** Drawing-scale denominator (model mm per paper mm); 1:50 => 50. */
304
+ scale?: number;
305
+ /** Pinned: no pan/zoom-through, no move/resize grips. */
306
+ locked?: boolean;
307
+ /** Layer ids hidden in this viewport only. */
308
+ hiddenLayerIds?: readonly string[];
309
+ }>;
310
+ /** Review note pinned to a point; the editor shows a screen-fixed marker. */
311
+ export type CommentInput = ObjectInputShape<{
312
+ type: "comment";
313
+ /** Tail tip of the bubble (world/sheet mm). */
314
+ position: Vec2Like;
315
+ text?: string;
316
+ tags?: readonly string[];
317
+ }>;
318
+ /** What a script WRITES — the union of the authoring DTOs above (what
319
+ * `document.add` takes). Reads return `ModelObject`. */
320
+ export type ModelObjectInput = LineInput | PointInput | PolylineInput | CircleInput | ArcInput | EllipseInput | HatchInput | TextInput | DimensionInput | BlockInput | TableInput | ViewportInput | CommentInput | ReferenceInput;
321
+ /** One child a block's `draw` may return: every input except viewports and
322
+ * comments (both are drawn only as a space's own objects — a block's would
323
+ * never show). An `asset` reference resolves in the document the instance
324
+ * lives in. */
325
+ export type BlockChildInput = Exclude<ModelObjectInput, ViewportInput | CommentInput>;
201
326
  /** Identity + shared style fields every stored object carries. */
202
- export type StoredObjectBase = {
327
+ export type ObjectBase = {
203
328
  id: string;
204
329
  layerId: string;
205
330
  /** #rrggbb override; absent = by layer. */
@@ -211,43 +336,43 @@ declare module "lineadraw" {
211
336
  opacity?: number;
212
337
  };
213
338
  /** Flattens base + per-type fields so hovers list every member inline
214
- * (same trick as Styled<T> for the authoring DTOs). */
215
- type StoredShape<T> = {
216
- [K in keyof (T & StoredObjectBase)]: (T & StoredObjectBase)[K];
339
+ * (same trick as ObjectInputShape<T> for the authoring DTOs). */
340
+ type ObjectShape<T> = {
341
+ [K in keyof (T & ObjectBase)]: (T & ObjectBase)[K];
217
342
  } & {};
218
343
  /** Stored polyline vertex — bulge always present (default 0 applied). */
219
- export type StoredPolylineVertex = {
344
+ export type PolylineVertex = {
220
345
  x: number;
221
346
  y: number;
222
347
  bulge: number;
223
348
  };
224
- export type StoredLine = StoredShape<{
349
+ export type Line = ObjectShape<{
225
350
  type: "line";
226
351
  a: Vec2;
227
352
  b: Vec2;
228
353
  }>;
229
- export type StoredPoint = StoredShape<{
354
+ export type Point = ObjectShape<{
230
355
  type: "point";
231
356
  p: Vec2;
232
357
  }>;
233
- export type StoredPolyline = StoredShape<{
358
+ export type Polyline = ObjectShape<{
234
359
  type: "polyline";
235
- points: readonly StoredPolylineVertex[];
360
+ points: readonly PolylineVertex[];
236
361
  closed: boolean;
237
362
  }>;
238
- export type StoredCircle = StoredShape<{
363
+ export type Circle = ObjectShape<{
239
364
  type: "circle";
240
365
  center: Vec2;
241
366
  radius: number;
242
367
  }>;
243
- export type StoredArc = StoredShape<{
368
+ export type Arc = ObjectShape<{
244
369
  type: "arc";
245
370
  center: Vec2;
246
371
  radius: number;
247
372
  startAngle: number;
248
373
  endAngle: number;
249
374
  }>;
250
- export type StoredEllipse = StoredShape<{
375
+ export type Ellipse = ObjectShape<{
251
376
  type: "ellipse";
252
377
  center: Vec2;
253
378
  majorAxis: Vec2;
@@ -255,13 +380,15 @@ declare module "lineadraw" {
255
380
  startAngle: number;
256
381
  endAngle: number;
257
382
  }>;
258
- export type StoredHatchFill = {
383
+ export type HatchFill = {
259
384
  kind: "solid";
260
385
  } | {
261
386
  kind: "pattern";
262
387
  name: string;
263
388
  angle: number;
264
389
  scale: number;
390
+ /** World anchor of the pattern frame; absent = the drawing origin. */
391
+ origin?: Vec2;
265
392
  } | {
266
393
  kind: "lines";
267
394
  angle: number;
@@ -273,19 +400,20 @@ declare module "lineadraw" {
273
400
  color2: string;
274
401
  angle: number;
275
402
  };
276
- export type StoredHatch = StoredShape<{
403
+ export type Hatch = ObjectShape<{
277
404
  type: "hatch";
278
405
  /** loops[0] = outer boundary, the rest are holes (even-odd). */
279
406
  loops: readonly {
280
- points: readonly StoredPolylineVertex[];
407
+ points: readonly PolylineVertex[];
281
408
  }[];
282
- fill: StoredHatchFill;
409
+ fill: HatchFill;
283
410
  scale: number;
284
411
  }>;
285
- export type StoredText = StoredShape<{
412
+ export type Text = ObjectShape<{
286
413
  type: "text";
287
414
  position: Vec2;
288
415
  content: string;
416
+ spans?: readonly TextSpan[];
289
417
  leaderLines: readonly (readonly Vec2[])[];
290
418
  /** Word-wrap / frame width in mm; absent = no wrapping. */
291
419
  width?: number;
@@ -294,43 +422,28 @@ declare module "lineadraw" {
294
422
  frame?: "none" | "rectangle" | "circle" | "slot" | "bottom" | "firstLine";
295
423
  styleId?: string;
296
424
  /** Only the keys the user actually overrode on this text. */
297
- styleOverride?: {
298
- font?: string;
299
- widthFactor?: number;
300
- bold?: boolean;
301
- italic?: boolean;
302
- textHeight?: number;
303
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
304
- arrowSize?: number;
305
- };
425
+ styleOverride?: TextStyleOverride;
306
426
  rotation: number;
307
427
  scale: number;
308
428
  }>;
309
- export type StoredDimension = StoredShape<{
429
+ export type Dimension = ObjectShape<{
310
430
  type: "dimension";
311
431
  kind: "linear" | "angular" | "radial" | "diameter";
312
432
  points: readonly Vec2[];
313
- offset: Vec2;
314
- textOverride?: string;
433
+ rotation?: number;
434
+ offset?: number;
435
+ labels: readonly {
436
+ along?: number;
437
+ across?: number;
438
+ content?: string;
439
+ spans?: readonly TextSpan[];
440
+ }[];
315
441
  styleId?: string;
316
442
  /** Only the keys the user actually overrode on this dimension. */
317
- styleOverride?: {
318
- font?: string;
319
- widthFactor?: number;
320
- bold?: boolean;
321
- italic?: boolean;
322
- textHeight?: number;
323
- textOffset?: number;
324
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
325
- arrowSize?: number;
326
- extensionType?: "long" | "short";
327
- extensionOffset?: number;
328
- extensionOvershoot?: number;
329
- precision?: number;
330
- };
443
+ styleOverride?: DimStyleOverride;
331
444
  scale: number;
332
445
  }>;
333
- export type StoredBlock = StoredShape<{
446
+ export type Block = ObjectShape<{
334
447
  type: "block";
335
448
  definitionId: string;
336
449
  rotation: number;
@@ -340,7 +453,7 @@ declare module "lineadraw" {
340
453
  inputs: readonly (Vec2 | string)[];
341
454
  }>;
342
455
  /** Paper-space window into model space; exists only in layout spaces. */
343
- export type StoredViewport = StoredShape<{
456
+ export type Viewport = ObjectShape<{
344
457
  type: "viewport";
345
458
  rect: {
346
459
  x: number;
@@ -354,29 +467,13 @@ declare module "lineadraw" {
354
467
  locked: boolean;
355
468
  hiddenLayerIds: readonly string[];
356
469
  }>;
357
- /** Raster reference; pixels live in the document's assets map. */
358
- export type StoredImage = StoredShape<{
359
- type: "image";
360
- assetId: string;
361
- origin: Vec2;
362
- width: number;
363
- height: number;
364
- rotation: number;
365
- }>;
366
- /** A LINKED file drawn in place (an xref); the document holds only this
367
- * record — the file's content is not readable from scripts. */
368
- export type StoredReference = StoredShape<{
470
+ /** A file drawn in place — linked (an xref) or embedded in the document's
471
+ * assets; the file's content is not readable from scripts. */
472
+ export type Reference = ObjectShape<{
369
473
  type: "reference";
370
474
  format: "linea" | "dxf" | "dwg" | "pdf" | "png" | "jpg";
371
475
  name: string;
372
- source: {
373
- kind: "path";
374
- path: string;
375
- cacheKey?: string;
376
- } | {
377
- kind: "url";
378
- url: string;
379
- };
476
+ source: ReferenceSource;
380
477
  /** Where the file's origin lands. */
381
478
  position: Vec2;
382
479
  rotation: number;
@@ -388,23 +485,15 @@ declare module "lineadraw" {
388
485
  hiddenLayers: readonly string[];
389
486
  /** Switched off: not drawn. */
390
487
  hidden?: boolean;
488
+ /** Locked in the References panel: drawn and snapped, never picked. */
489
+ locked?: boolean;
391
490
  /** Crop rectangle in file coordinates. */
392
- clip?: {
393
- minX: number;
394
- minY: number;
395
- maxX: number;
396
- maxY: number;
397
- };
491
+ clip?: Box;
398
492
  /** Content bounds in file coordinates at the last load. */
399
- extent?: {
400
- minX: number;
401
- minY: number;
402
- maxX: number;
403
- maxY: number;
404
- };
493
+ extent?: Box;
405
494
  }>;
406
495
  /** Review note pinned to a point; the editor shows a screen-fixed marker. */
407
- export type StoredComment = StoredShape<{
496
+ export type Comment = ObjectShape<{
408
497
  type: "comment";
409
498
  /** Tail tip of the bubble (world/sheet mm). */
410
499
  position: Vec2;
@@ -412,19 +501,14 @@ declare module "lineadraw" {
412
501
  tags: readonly string[];
413
502
  }>;
414
503
  /** Text style keys a text, table or table cell may override. */
415
- export type TextStyleOverride = {
416
- font?: string;
417
- widthFactor?: number;
418
- bold?: boolean;
419
- italic?: boolean;
420
- textHeight?: number;
421
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
422
- arrowSize?: number;
423
- };
504
+ export type TextStyleOverride = Partial<Omit<TextStyle, "id" | "name">>;
505
+ /** Dimension style keys a dimension may override. */
506
+ export type DimStyleOverride = Partial<Omit<DimStyle, "id" | "name">>;
424
507
  /** One table cell as stored. */
425
- export type StoredTableCell = {
508
+ export type TableCell = {
426
509
  /** Plain text; "\n" = line break. */
427
- text: string;
510
+ content: string;
511
+ spans?: readonly TextSpan[];
428
512
  /** Merge, on the anchor (top-left) cell; covered cells are ignored. */
429
513
  span?: {
430
514
  cols: number;
@@ -437,7 +521,7 @@ declare module "lineadraw" {
437
521
  color?: string;
438
522
  };
439
523
  /** Grid of text cells hanging right/down from `position` (top-left). */
440
- export type StoredTable = StoredShape<{
524
+ export type Table = ObjectShape<{
441
525
  type: "table";
442
526
  position: Vec2;
443
527
  rotation: number;
@@ -448,7 +532,7 @@ declare module "lineadraw" {
448
532
  minHeight?: number;
449
533
  }[];
450
534
  /** Row-major `cells[row][column]`. */
451
- cells: readonly (readonly StoredTableCell[])[];
535
+ cells: readonly (readonly TableCell[])[];
452
536
  headerRows: number;
453
537
  cellMargin: number;
454
538
  borders: "all" | "outer" | "rows" | "none";
@@ -456,13 +540,13 @@ declare module "lineadraw" {
456
540
  styleOverride?: TextStyleOverride;
457
541
  }>;
458
542
  /** Any object as stored in the document — what reads hand to scripts. */
459
- export type StoredObject = StoredLine | StoredPoint | StoredPolyline | StoredCircle | StoredArc | StoredEllipse | StoredHatch | StoredText | StoredDimension | StoredBlock | StoredViewport | StoredImage | StoredComment | StoredTable | StoredReference;
543
+ export type ModelObject = Line | Point | Polyline | Circle | Arc | Ellipse | Hatch | Text | Dimension | Block | Viewport | Comment | Table | Reference;
460
544
  /**
461
545
  * One choice of a "Select" parameter: the value (what scripts receive) with
462
546
  * an optional properties-panel label. A plain string is shorthand for
463
547
  * `{ value }`.
464
548
  */
465
- export type ParameterOption = string | {
549
+ export type ParamOption = string | {
466
550
  value: string;
467
551
  label?: string;
468
552
  /** A `#rrggbb` color square before the option's label. */
@@ -539,7 +623,7 @@ declare module "lineadraw" {
539
623
  }) | (ParamBase & {
540
624
  type: "enum";
541
625
  default: string;
542
- options: readonly ParameterOption[];
626
+ options: readonly ParamOption[];
543
627
  /** "buttons": a segmented toggle group of the options (short
544
628
  * choices); falls back to the dropdown when they don't fit. */
545
629
  display?: "dropdown" | "buttons";
@@ -565,9 +649,10 @@ declare module "lineadraw" {
565
649
  type: "row";
566
650
  items: readonly RowItemDef[];
567
651
  });
568
- /** A document text style as `draw` reads it (`styles.text(id)`). Heights
569
- * and arrow sizes are mm before an object's `scale`. */
570
- export type TextStyleInfo = {
652
+ /** A document text style (`styles.text(id)` in `draw`,
653
+ * `document.listTextStyles()`). Heights and arrow sizes are mm before an
654
+ * object's `scale`. */
655
+ export type TextStyle = {
571
656
  readonly id: string;
572
657
  readonly name: string;
573
658
  readonly font: string;
@@ -575,11 +660,12 @@ declare module "lineadraw" {
575
660
  readonly bold?: boolean;
576
661
  readonly italic?: boolean;
577
662
  readonly textHeight: number;
578
- readonly arrowType: "filled" | "open" | "tick" | "dot" | "none";
663
+ readonly arrowType: ArrowType;
579
664
  readonly arrowSize: number;
580
665
  };
581
- /** A document dimension style as `draw` reads it (`styles.dim(id)`). */
582
- export type DimStyleInfo = {
666
+ /** A document dimension style (`styles.dim(id)`,
667
+ * `document.listDimStyles()`). */
668
+ export type DimStyle = {
583
669
  readonly id: string;
584
670
  readonly name: string;
585
671
  readonly font: string;
@@ -588,8 +674,9 @@ declare module "lineadraw" {
588
674
  readonly italic?: boolean;
589
675
  readonly textHeight: number;
590
676
  readonly textOffset: number;
591
- readonly arrowType: "filled" | "open" | "tick" | "dot" | "none";
677
+ readonly arrowType: ArrowType;
592
678
  readonly arrowSize: number;
679
+ /** "short" = a 2×overshoot tick across the dimension line. */
593
680
  readonly extensionType: "long" | "short";
594
681
  readonly extensionOffset: number;
595
682
  readonly extensionOvershoot: number;
@@ -599,9 +686,17 @@ declare module "lineadraw" {
599
686
  * (a deleted style, a block from another drawing) gives the document's
600
687
  * first style — the same rule a child's `styleId` follows. */
601
688
  export interface BlockStyles {
602
- text(id?: string): TextStyleInfo;
603
- dim(id?: string): DimStyleInfo;
689
+ text(id?: string): TextStyle;
690
+ dim(id?: string): DimStyle;
604
691
  }
692
+ /** A new text style: a unique name, every other field optional. */
693
+ export type TextStyleInput = {
694
+ name: string;
695
+ } & Partial<Omit<TextStyle, "id">>;
696
+ /** A new dimension style: a unique name, every other field optional. */
697
+ export type DimStyleInput = {
698
+ name: string;
699
+ } & Partial<Omit<DimStyle, "id">>;
605
700
  /** What a `row` may hold: the compact, single-line param kinds. */
606
701
  export type RowItemDef = Extract<ParamDef, {
607
702
  type: "number" | "string" | "boolean" | "enum" | "color" | "textStyle" | "dimStyle" | "font" | "lineType" | "hatchPattern";
@@ -612,14 +707,12 @@ declare module "lineadraw" {
612
707
  items: readonly (infer I)[];
613
708
  } ? I : Q;
614
709
  /**
615
- * The block's parameters table — what the `params` member of a BlockSpec
616
- * declares (or its function form returns).
710
+ * A parameters table — what the `params` member of a block or command spec
711
+ * declares (or a block's function form returns).
617
712
  */
618
- export type BlockParamDefs = readonly ParamDef[];
619
- /** What the script's `draw` export must return. */
620
- export type BlockScriptResult = ModelObject[];
713
+ export type ParamDefs = readonly ParamDef[];
621
714
  /** The value an enum option denotes (its string, or `value` of the record form). */
622
- type OptionValue<O extends ParameterOption> = O extends string ? O : O extends {
715
+ type OptionValue<O extends ParamOption> = O extends string ? O : O extends {
623
716
  value: infer V extends string;
624
717
  } ? V : never;
625
718
  /** The runtime value type of one `params` table entry. */
@@ -650,12 +743,36 @@ declare module "lineadraw" {
650
743
  name: infer N extends string;
651
744
  } ? N : never]: E extends ParamDef ? ParamValue<E> : never;
652
745
  } : P;
653
- /** An axis-aligned box in world mm. */
654
- export type Box = {
655
- minX: number;
656
- minY: number;
657
- maxX: number;
658
- maxY: number;
746
+ /** A document line type definition — objects and layers name it in
747
+ * `lineType`, ahead of the built-in catalogue. */
748
+ export type LineType = {
749
+ /** Case-insensitive, unique per document. */
750
+ name: string;
751
+ description?: string;
752
+ /** Signed dash cycle, mm per 1 mm of line width: >0 dash, <0 gap, 0 dot.
753
+ * Empty = continuous. */
754
+ dashesMm: number[];
755
+ };
756
+ /** One line family of a hatch pattern, in the pattern's own frame. */
757
+ export type HatchPatternLine = {
758
+ /** Radians CCW. */
759
+ angle: number;
760
+ /** Base point, mm. */
761
+ origin: Vec2;
762
+ /** Shift along the line between successive lines (dash phase), mm. */
763
+ deltaX: number;
764
+ /** Perpendicular spacing between successive lines, mm. */
765
+ deltaY: number;
766
+ /** Dash cycle along the line: >0 dash, <0 gap, 0 dot; absent = solid. */
767
+ dashesMm?: number[];
768
+ };
769
+ /** A document hatch pattern definition — pattern fills name it in
770
+ * `fill.name`, ahead of the built-in catalogue. */
771
+ export type HatchPattern = {
772
+ /** Case-insensitive, unique per document. */
773
+ name: string;
774
+ description?: string;
775
+ lines: HatchPatternLine[];
659
776
  };
660
777
  /** Filters for Drawing.query — all present filters AND together. */
661
778
  export type ObjectQuery = {
@@ -668,9 +785,9 @@ declare module "lineadraw" {
668
785
  lineType?: string;
669
786
  /** Substring match on text content. */
670
787
  content?: string;
671
- /** Bounds intersect this box. */
788
+ /** Box intersect this box. */
672
789
  bbox?: Box;
673
- /** Bounds entirely inside this box. */
790
+ /** Box entirely inside this box. */
674
791
  inside?: Box;
675
792
  /** Geometry within `tol` mm of `point`. */
676
793
  near?: {
@@ -681,38 +798,87 @@ declare module "lineadraw" {
681
798
  * model space. */
682
799
  layout?: string;
683
800
  };
684
- /** A STORED object as query() returns it (see StoredObject — schema
685
- * output: defaults applied, points always {x, y}, identity present). */
686
- export type ExistingObject = StoredObject;
801
+ /** `Drawing.summary()`: counts by type / layer, extents, names. */
802
+ export type DocumentSummary = {
803
+ name: string;
804
+ objectCount: number;
805
+ byType: Record<string, number>;
806
+ byLayer: Record<string, number>;
807
+ bbox: Box | null;
808
+ layers: string[];
809
+ layouts: {
810
+ name: string;
811
+ objectCount: number;
812
+ }[];
813
+ settings: {
814
+ units: "mm" | "in";
815
+ };
816
+ };
817
+ /** What `renderSvg` draws: model space or one layout. */
818
+ export type RenderSvgOptions = {
819
+ /** Render this paper layout (name or id) instead of model space. */
820
+ layout?: string;
821
+ /** Crop to this box (world mm; sheet mm in a layout). */
822
+ bbox?: Box;
823
+ /** Padding around the content, mm (default 5). */
824
+ padding?: number;
825
+ /** Default: "color" for model space, the layout's own for a layout. */
826
+ palette?: PrintPalette;
827
+ };
828
+ export type RenderPngOptions = RenderSvgOptions & {
829
+ /** Output width in px (height follows). Default 1024. */
830
+ width?: number;
831
+ /** Background fill, e.g. "#ffffff". Default: the dark canvas. */
832
+ background?: string;
833
+ };
834
+ export type RenderPdfOptions = {
835
+ /** Layouts (names or ids) in page order; default: all of them. */
836
+ layouts?: readonly string[];
837
+ /** Override every page's print palette. */
838
+ palette?: PrintPalette;
839
+ };
687
840
  /** Per-object measurements; null where the type has no natural value. */
688
841
  export type Measurement = {
689
842
  bbox: Box | null;
690
843
  length: number | null;
691
844
  area: number | null;
692
845
  };
693
- /** A layer as stored (defaults applied) plus the current-layer flag. */
694
- export type LayerInfo = {
846
+ /** A document layer (defaults applied). */
847
+ export type Layer = {
695
848
  id: string;
696
849
  name: string;
850
+ /** #rrggbb — objects without their own color take it. */
697
851
  color: string;
852
+ /** Default line type of the layer's objects. */
698
853
  lineType: string;
854
+ /** Default lineweight, mm. */
699
855
  lineWidth: number;
856
+ /** Default paint opacity 0..1. */
700
857
  opacity: number;
701
858
  visible: boolean;
702
859
  locked: boolean;
860
+ /** false = shown on screen but left out of PDF / print output. */
861
+ print: boolean;
862
+ };
863
+ /** A layer as `listLayers()` returns it: plus the current-layer flag. */
864
+ export type LayerInfo = Layer & {
703
865
  current: boolean;
704
- [key: string]: unknown;
705
866
  };
706
- /** A paper layout as stored: sheet metadata + its sheet-space objects. */
707
- export type LayoutInfo = {
867
+ /** A new layer: a unique name, every other field optional. */
868
+ export type LayerInput = {
869
+ name: string;
870
+ } & Partial<Omit<Layer, "id">>;
871
+ /** A paper layout: sheet metadata + its sheet-space objects. */
872
+ export type PaperLayout = {
708
873
  id: string;
709
874
  name: string;
875
+ /** Sheet size, mm. */
710
876
  sheet: {
711
877
  width: number;
712
878
  height: number;
713
879
  };
714
- printPalette: "color" | "grayscale" | "monochrome";
715
- objects: readonly StoredObject[];
880
+ printPalette: PrintPalette;
881
+ objects: readonly ModelObject[];
716
882
  };
717
883
  /** A block module's identity/metadata (from its exports). */
718
884
  export type BlockInfo = {
@@ -739,6 +905,48 @@ declare module "lineadraw" {
739
905
  params?: readonly ParamDef[];
740
906
  };
741
907
  /** What installing module sources reports. */
908
+ /** One configured marketplace (a block / command collection). */
909
+ export type MarketplaceConfig = {
910
+ kind: "builtin";
911
+ } | {
912
+ kind: "github";
913
+ spec: string;
914
+ token?: string;
915
+ } | {
916
+ kind: "folder";
917
+ folder: string;
918
+ };
919
+ /** A configured marketplace as listed — the token itself never shows. */
920
+ export type MarketplaceInfo = {
921
+ key: string;
922
+ kind: "builtin" | "github" | "folder";
923
+ label: string;
924
+ spec?: string;
925
+ folder?: string;
926
+ hasToken: boolean;
927
+ };
928
+ /** A marketplace search hit: the catalog row plus where it came from and
929
+ * how it relates to this document's modules. */
930
+ export type MarketplaceHit = {
931
+ kind: "block" | "command";
932
+ id: string;
933
+ name: string;
934
+ version: string;
935
+ description?: string;
936
+ tags: string[];
937
+ authors: string[];
938
+ dependencies: string[];
939
+ marketplace: MarketplaceInfo;
940
+ status: {
941
+ kind: "absent";
942
+ } | {
943
+ kind: "installed";
944
+ version?: string;
945
+ } | {
946
+ kind: "update";
947
+ from?: string;
948
+ };
949
+ };
742
950
  export type MergeReport = {
743
951
  /** The full library after the merge. */
744
952
  merged: readonly string[];
@@ -798,18 +1006,29 @@ declare module "lineadraw" {
798
1006
  index?: number;
799
1007
  };
800
1008
  /** The whole document as stored (defaults applied). */
801
- export type StoredDocument = {
1009
+ export type LineaDocument = {
802
1010
  id: string;
1011
+ type: "lineadraw";
803
1012
  version: number;
804
- layers: readonly Omit<LayerInfo, "current">[];
1013
+ settings: {
1014
+ units: "mm" | "in";
1015
+ };
1016
+ layers: readonly Layer[];
805
1017
  currentLayerId: string;
806
- objects: readonly StoredObject[];
807
- layouts: readonly LayoutInfo[];
808
- /** Raw block module sources. */
1018
+ /** Model space. */
1019
+ objects: readonly ModelObject[];
1020
+ layouts: readonly PaperLayout[];
1021
+ textStyles: readonly TextStyle[];
1022
+ dimStyles: readonly DimStyle[];
1023
+ /** The document's own line type / hatch pattern definitions. */
1024
+ lineTypes: readonly LineType[];
1025
+ hatchPatterns: readonly HatchPattern[];
1026
+ /** Embedded files: content hash → data URL. */
1027
+ assets: Readonly<Record<string, string>>;
1028
+ /** Block module sources. */
809
1029
  blockDefinitions: readonly string[];
810
- /** Raw command module sources. */
1030
+ /** Command module sources. */
811
1031
  commands: readonly string[];
812
- [key: string]: unknown;
813
1032
  };
814
1033
  /** Where a draw-order move puts the objects. */
815
1034
  export type ReorderPlacement = "front" | "back" | {
@@ -831,57 +1050,29 @@ declare module "lineadraw" {
831
1050
  /** Monotonic change counter. */
832
1051
  readonly revision: number;
833
1052
  /** The full document — a detached snapshot. */
834
- readonly document: StoredDocument;
1053
+ readonly document: LineaDocument;
835
1054
  /** Counts by type/layer, bbox, layer + layout names. */
836
- summary(): {
837
- name: string;
838
- objectCount: number;
839
- byType: Record<string, number>;
840
- byLayer: Record<string, number>;
841
- bbox: Box | null;
842
- layers: string[];
843
- layouts: {
844
- name: string;
845
- objectCount: number;
846
- }[];
847
- };
1055
+ summary(): DocumentSummary;
848
1056
  /** Filtered objects — model space, or one layout via `filter.layout`. */
849
- listObjects(filter?: ObjectQuery): ExistingObject[];
1057
+ listObjects(filter?: ObjectQuery): ModelObject[];
850
1058
  /** One object from ANY space, or undefined. */
851
- getObject(id: string): ExistingObject | undefined;
1059
+ getObject(id: string): ModelObject | undefined;
852
1060
  /** bbox / curve length / enclosed area of one object. */
853
1061
  measure(id: string): Measurement;
854
1062
  listLayers(): LayerInfo[];
855
- listLayouts(): LayoutInfo[];
1063
+ listLayouts(): PaperLayout[];
856
1064
  /** Compilable block definitions in this document. */
857
1065
  listBlockDefinitions(): BlockInfo[];
858
1066
  /** Compilable command modules travelling with this document. */
859
1067
  listUserCommands(): CommandInfo[];
860
1068
  /** Model space (or a layout via `layout`) as an SVG string. */
861
- renderSvg(opts?: {
862
- layout?: string;
863
- bbox?: Box;
864
- padding?: number;
865
- palette?: "color" | "grayscale" | "monochrome";
866
- }): string;
1069
+ renderSvg(opts?: RenderSvgOptions): string;
867
1070
  /** Model space (or a layout) as PNG bytes — absent on hosts that can't
868
1071
  * rasterize, so check before calling. */
869
- renderPng?(opts?: {
870
- layout?: string;
871
- bbox?: Box;
872
- padding?: number;
873
- palette?: "color" | "grayscale" | "monochrome";
874
- /** Output width in px (height follows). Default 1024. */
875
- width?: number;
876
- /** Background fill, e.g. "#ffffff". Default: the dark canvas. */
877
- background?: string;
878
- }): Promise<Uint8Array>;
1072
+ renderPng?(opts?: RenderPngOptions): Promise<Uint8Array>;
879
1073
  /** Multi-page PDF of the layouts (default: all) — absent on hosts
880
1074
  * without fonts, so check before calling. */
881
- renderPdf?(opts?: {
882
- layouts?: readonly string[];
883
- palette?: "color" | "grayscale" | "monochrome";
884
- }): Promise<Uint8Array>;
1075
+ renderPdf?(opts?: RenderPdfOptions): Promise<Uint8Array>;
885
1076
  /** The whole document as DXF text. */
886
1077
  toDxf(): Promise<string>;
887
1078
  /** DWG bytes (default AC1027 — AutoCAD 2013). */
@@ -890,10 +1081,9 @@ declare module "lineadraw" {
890
1081
  }): Promise<Uint8Array>;
891
1082
  /** The `.linea` file text. */
892
1083
  toLinea(): string;
893
- /** Add objects (each may carry `layer` — a name — instead of an id);
894
- * returns the created ids. */
895
- add(objects: readonly (ModelObject & {
896
- layer?: string;
1084
+ /** Add objects (each may carry its own `id`); returns the created ids. */
1085
+ add(objects: readonly (ModelObjectInput & {
1086
+ id?: string;
897
1087
  })[], opts?: {
898
1088
  layout?: string;
899
1089
  }): string[];
@@ -920,53 +1110,72 @@ declare module "lineadraw" {
920
1110
  updateLayout(nameOrId: string, patch: {
921
1111
  name?: string;
922
1112
  sheet?: SheetSpec;
923
- printPalette?: "color" | "grayscale" | "monochrome";
1113
+ printPalette?: PrintPalette;
924
1114
  }): void;
925
1115
  removeLayout(nameOrId: string): void;
926
1116
  /** Explicit total order (names or ids) — the PDF page order. */
927
1117
  reorderLayouts(order: readonly string[]): void;
928
1118
  /** Create a layer (unique name); returns its id. */
929
- addLayer(props: {
930
- name: string;
931
- color?: string;
932
- } & Record<string, unknown>): string;
933
- updateLayer(nameOrId: string, patch: Record<string, unknown>): void;
1119
+ addLayer(props: LayerInput): string;
1120
+ updateLayer(nameOrId: string, patch: Partial<LayerInput>): void;
934
1121
  /** Remove an EMPTY, non-current layer. */
935
1122
  removeLayer(nameOrId: string): void;
936
1123
  /** Explicit total order (names or ids, every layer exactly once). */
937
1124
  reorderLayers(order: readonly string[]): void;
938
1125
  setCurrentLayer(nameOrId: string): void;
939
- listTextStyles(): ({
940
- id: string;
941
- name: string;
942
- } & Record<string, unknown>)[];
943
- listDimStyles(): ({
944
- id: string;
945
- name: string;
946
- } & Record<string, unknown>)[];
1126
+ /** Document-wide settings, merged over the current record. */
1127
+ updateSettings(patch: {
1128
+ units?: "mm" | "in";
1129
+ }): void;
1130
+ /** Configured marketplaces, priority order (tokens hidden). */
1131
+ listMarketplaces(): MarketplaceInfo[];
1132
+ /** Add marketplaces at the top of the priority list; each catalog must be
1133
+ * fetchable. `{ kind: "github", spec: "owner/repo[@branch]", token? }` or
1134
+ * `{ kind: "folder", folder }`. */
1135
+ addMarketplaces(list: readonly MarketplaceConfig[]): Promise<MarketplaceInfo[]>;
1136
+ /** Remove by key, spec, folder or label; the built-in collection stays. */
1137
+ removeMarketplaces(names: readonly string[]): MarketplaceInfo[];
1138
+ /** Search entries across the marketplaces, with install status. */
1139
+ searchMarketplaces(q?: {
1140
+ query?: string;
1141
+ kind?: "block" | "command";
1142
+ marketplace?: string;
1143
+ }): Promise<MarketplaceHit[]>;
1144
+ /** Install (or update) entries by id, dependencies first — one undo step. */
1145
+ installMarketplaceEntries(ids: readonly string[], marketplace?: string): Promise<MergeReport>;
1146
+ listTextStyles(): TextStyle[];
1147
+ listDimStyles(): DimStyle[];
947
1148
  /** Create a style (unique name; unset fields take the defaults); returns
948
1149
  * its id. Styles are addressed by name or id. */
949
- addTextStyle(props: {
950
- name: string;
951
- } & Record<string, unknown>): string;
952
- updateTextStyle(nameOrId: string, patch: Record<string, unknown>): void;
1150
+ addTextStyle(props: TextStyleInput): string;
1151
+ updateTextStyle(nameOrId: string, patch: Partial<TextStyleInput>): void;
953
1152
  /** Remove a style no object uses (refused otherwise). */
954
1153
  removeTextStyle(nameOrId: string): void;
955
- addDimStyle(props: {
956
- name: string;
957
- } & Record<string, unknown>): string;
958
- updateDimStyle(nameOrId: string, patch: Record<string, unknown>): void;
1154
+ addDimStyle(props: DimStyleInput): string;
1155
+ updateDimStyle(nameOrId: string, patch: Partial<DimStyleInput>): void;
959
1156
  removeDimStyle(nameOrId: string): void;
960
- /** @deprecated Use updateDimStyle (default here: the first style). */
961
- setDimStyle(patch: Record<string, unknown>, styleId?: string): void;
962
- /** @deprecated Use updateTextStyle (default here: the first style). */
963
- setTextStyle(patch: Record<string, unknown>, styleId?: string): void;
964
- /** Embed image pixels (a data URL); returns the content-keyed assetId
965
- * that `image` objects reference. */
1157
+ /** The document's own line type definitions (objects and layers name
1158
+ * them, ahead of the built-in catalogue). */
1159
+ listLineTypes(): LineType[];
1160
+ /** Add definitions (names unique, case-insensitive; a clash is refused). */
1161
+ addLineTypes(lineTypes: readonly LineType[]): void;
1162
+ updateLineType(name: string, patch: Partial<LineType>): void;
1163
+ /** Remove a definition; objects still naming it fall back to the
1164
+ * catalogue or continuous. */
1165
+ removeLineType(name: string): void;
1166
+ /** The document's own hatch pattern definitions (same model as line
1167
+ * types: fills name them, ahead of the catalogue). */
1168
+ listHatchPatterns(): HatchPattern[];
1169
+ addHatchPatterns(patterns: readonly HatchPattern[]): void;
1170
+ updateHatchPattern(name: string, patch: Partial<HatchPattern>): void;
1171
+ removeHatchPattern(name: string): void;
1172
+ /** Embed a file (a data URL — PNG, JPEG, PDF…); returns the content-keyed
1173
+ * assetId an embedded reference's `source: { kind: "asset", assetId }`
1174
+ * names. */
966
1175
  addAsset(dataUrl: string): string;
967
- /** Remove an asset (refused while an image references it). */
1176
+ /** Remove an asset (refused while a reference embeds it). */
968
1177
  removeAsset(id: string): void;
969
- /** Embedded image assets and how many images use each. */
1178
+ /** Embedded files and how many references use each. */
970
1179
  listAssets(): {
971
1180
  id: string;
972
1181
  mimeType: string;
@@ -991,7 +1200,8 @@ declare module "lineadraw" {
991
1200
  layoutIds: string[];
992
1201
  }>;
993
1202
  /** Merge a PDF: vectors/text onto the current layer, or (`as: "image"`,
994
- * not available on every host) each page as an image at true scale. */
1203
+ * not available on every host) embedded, each page a raster reference
1204
+ * at true scale. */
995
1205
  importPdfData(data: ArrayBuffer | Uint8Array, opts?: {
996
1206
  as?: "vectors" | "image";
997
1207
  origin?: Vec2Like;
@@ -1091,25 +1301,17 @@ declare module "lineadraw" {
1091
1301
  editor?: EditorSurface;
1092
1302
  inputs: readonly Vec2[];
1093
1303
  params: P;
1094
- /** @deprecated Use `editor.pickPoint({ label })` (throws without an editor). */
1095
- pickPoint(label?: string): Promise<Vec2>;
1096
- /** @deprecated Use `editor.pickObject({ label })`. */
1097
- pickObject(label?: string): Promise<string>;
1098
- /** @deprecated Use `editor.state().selectedIds`. */
1099
- selection(): string[];
1100
- /** @deprecated Use `editor.setSelection(ids)`. */
1101
- setSelection(ids: readonly string[]): void;
1102
- /** @deprecated Use `editor.prompt(message, options)`. */
1103
- prompt(message: string, options?: {
1104
- initial?: string;
1105
- placeholder?: string;
1106
- }): Promise<string>;
1107
- /** @deprecated Use `editor.toast(message, kind)`. */
1108
- showToast(message: string, kind?: "info" | "success" | "error"): void;
1109
1304
  }
1110
1305
 
1111
1306
  // ——— Script contract ———
1112
1307
 
1308
+ /**
1309
+ * @deprecated All "lineadraw/helpers" functions as one object — what
1310
+ * migration-wrapped legacy scripts import. Import the named functions from
1311
+ * "lineadraw/helpers" instead.
1312
+ */
1313
+ export const helpers: Readonly<typeof import("lineadraw/helpers")>;
1314
+
1113
1315
  // #region BlockParams
1114
1316
  /**
1115
1317
  * The open fallback for a block's parameter values, by name. Inside
@@ -1132,12 +1334,12 @@ declare module "lineadraw" {
1132
1334
  /**
1133
1335
  * A referenced document object as `draw` receives it: the STORED record
1134
1336
  * (schema output — defaults applied, points always {x, y}, id/layerId
1135
- * present; see StoredObject), localized against the instance pivot like
1337
+ * present; see ModelObject), localized against the instance pivot like
1136
1338
  * every point input. Null when the reference no longer resolves (the
1137
1339
  * object was deleted) — handle it or throw (a throw shows as the
1138
1340
  * instance's evaluation error).
1139
1341
  */
1140
- export type ResolvedObject = StoredObject | null;
1342
+ export type ResolvedObject = ModelObject | null;
1141
1343
 
1142
1344
  /**
1143
1345
  * How one stored input arrives at `draw`: points pass through
@@ -1219,7 +1421,7 @@ declare module "lineadraw" {
1219
1421
  * typeof / satisfies / as-const annotations. See defineBlock.
1220
1422
  */
1221
1423
  export interface BlockSpec<
1222
- P extends BlockParamDefs = readonly [],
1424
+ P extends ParamDefs = readonly [],
1223
1425
  Pl extends PlaceSpec<P> | undefined = undefined,
1224
1426
  > {
1225
1427
  id: string;
@@ -1269,7 +1471,7 @@ declare module "lineadraw" {
1269
1471
  * lay out with real text sizes. Pass a picked id on to children as
1270
1472
  * `styleId` to let them follow the style. */
1271
1473
  styles: BlockStyles;
1272
- }) => BlockScriptResult;
1474
+ }) => BlockChildInput[];
1273
1475
  }
1274
1476
 
1275
1477
  /**
@@ -1296,14 +1498,14 @@ declare module "lineadraw" {
1296
1498
  * plain named exports describe the same block.
1297
1499
  */
1298
1500
  export function defineBlock<
1299
- const P extends BlockParamDefs = readonly [],
1501
+ const P extends ParamDefs = readonly [],
1300
1502
  const L extends readonly string[] | undefined = undefined,
1301
1503
  >(spec: BlockSpec<P, L>): BlockSpec<P, L>;
1302
1504
  // Function-form place: the props type is concrete (from P) and only the
1303
1505
  // RETURN is inferred — inferring a whole context-sensitive function into
1304
1506
  // a type parameter would fall back to its default.
1305
1507
  export function defineBlock<
1306
- const P extends BlockParamDefs = readonly [],
1508
+ const P extends ParamDefs = readonly [],
1307
1509
  const R extends BlockInputs | Promise<BlockInputs> = BlockInputs,
1308
1510
  >(
1309
1511
  spec: BlockSpec<P, (props: PlaceProps<P>) => R>,
@@ -1314,7 +1516,7 @@ declare module "lineadraw" {
1314
1516
  // above (the script-facing mirror of core's real interfaces).
1315
1517
 
1316
1518
  /** One user command (macro): identity, metadata, and the `run` body. */
1317
- export interface CommandSpec<P extends BlockParamDefs = readonly []> {
1519
+ export interface CommandSpec<P extends ParamDefs = readonly []> {
1318
1520
  id: string;
1319
1521
  name: string;
1320
1522
  description?: string;
@@ -1370,7 +1572,7 @@ declare module "lineadraw" {
1370
1572
  * },
1371
1573
  * });
1372
1574
  */
1373
- export function defineCommand<const P extends BlockParamDefs = readonly []>(
1575
+ export function defineCommand<const P extends ParamDefs = readonly []>(
1374
1576
  spec: CommandSpec<P>,
1375
1577
  ): CommandSpec<P>;
1376
1578
  }
@@ -1405,1149 +1607,4 @@ declare module "lineadraw/helpers" {
1405
1607
  export const dot: (a: Vec2, b: Vec2) => number;
1406
1608
  /** Rotate vector by `angle` (radians, CCW). */
1407
1609
  export const rotate: (p: Vec2, angle: number) => Vec2;
1408
- /**
1409
- * All helpers as one object — what migration-wrapped legacy scripts receive
1410
- * via `import { helpers } from "lineadraw"`. New scripts import the named
1411
- * functions from "lineadraw/helpers" instead.
1412
- */
1413
- export const helpers: Readonly<{
1414
- range: (n: number) => number[];
1415
- polar: (angle: number, distance: number, p?: Vec2) => Vec2;
1416
- toDeg: (r: number) => number;
1417
- toRad: (d: number) => number;
1418
- len: (p: Vec2) => number;
1419
- dist: (a: Vec2, b: Vec2) => number;
1420
- add: (a: Vec2, b: Vec2) => Vec2;
1421
- sub: (a: Vec2, b: Vec2) => Vec2;
1422
- scale: (p: Vec2, s: number) => Vec2;
1423
- norm: (p: Vec2) => Vec2;
1424
- dot: (a: Vec2, b: Vec2) => number;
1425
- rotate: (p: Vec2, angle: number) => Vec2;
1426
- }>;
1427
- }
1428
-
1429
- // The same declarations again at GLOBAL scope, so scripts can annotate
1430
- // without importing. Structurally identical to the "lineadraw" exports, so the
1431
- // two mix freely. Requires a DOM-less lib (blocks/tsconfig and the in-app
1432
- // editor both use lib es2022) — with lib.dom, `Text` would collide.
1433
- /** A 2D point (mm, y-up). Point-valued fields also accept [x, y]. */
1434
- type Vec2 = {
1435
- x: number;
1436
- y: number;
1437
- };
1438
- type Vec2Like = Vec2 | readonly [number, number];
1439
- /** Polyline vertex; bulge = tan(sweep/4), 0 = straight. Accepts [x, y, bulge?]. */
1440
- type PolylineVertexLike = {
1441
- x: number;
1442
- y: number;
1443
- bulge?: number;
1444
- } | readonly [number, number, number?];
1445
- /** Style overrides children may carry (otherwise inherited from the instance). */
1446
- type BaseStyle = {
1447
- /** #rrggbb; absent = by layer. */
1448
- color?: string;
1449
- /** Line type; absent = by layer. */
1450
- lineType?: string;
1451
- /** Dash-pattern length multiplier; absent = 1. */
1452
- lineTypeScale?: number;
1453
- /** Line weight in mm; absent = by layer. */
1454
- lineWidth?: number;
1455
- };
1456
- /**
1457
- * T plus the shared style fields, FLATTENED (the homomorphic map forces the
1458
- * intersection to resolve): hovers then list every member inline instead of
1459
- * the opaque `BaseStyle & { … }` — the block editor has no expand-type
1460
- * affordance, so the alias display is all a script author gets.
1461
- */
1462
- type Styled<T> = {
1463
- [K in keyof (T & BaseStyle)]: (T & BaseStyle)[K];
1464
- } & {};
1465
- type Line = Styled<{
1466
- type: "line";
1467
- a: Vec2Like;
1468
- b: Vec2Like;
1469
- }>;
1470
- /** A point: paints as a round dot whose diameter is the lineWidth. */
1471
- type Point = Styled<{
1472
- type: "point";
1473
- p: Vec2Like;
1474
- }>;
1475
- type Polyline = Styled<{
1476
- type: "polyline";
1477
- /** At least 2 vertices. */
1478
- points: readonly PolylineVertexLike[];
1479
- closed?: boolean;
1480
- }>;
1481
- type Circle = Styled<{
1482
- type: "circle";
1483
- center: Vec2Like;
1484
- radius: number;
1485
- }>;
1486
- /** Runs CCW from startAngle to endAngle (radians; DXF ARC convention). */
1487
- type Arc = Styled<{
1488
- type: "arc";
1489
- center: Vec2Like;
1490
- radius: number;
1491
- startAngle: number;
1492
- endAngle: number;
1493
- }>;
1494
- /** majorAxis = endpoint vector from center; ratio = minor/major in (0, 1]. */
1495
- type Ellipse = Styled<{
1496
- type: "ellipse";
1497
- center: Vec2Like;
1498
- majorAxis: Vec2Like;
1499
- ratio: number;
1500
- startAngle?: number;
1501
- endAngle?: number;
1502
- }>;
1503
- type Hatch = Styled<{
1504
- type: "hatch";
1505
- /** loops[0] = outer boundary, the rest are holes (even-odd). */
1506
- loops: readonly {
1507
- points: readonly PolylineVertexLike[];
1508
- }[];
1509
- fill?: {
1510
- kind: "solid";
1511
- } | {
1512
- kind: "lines";
1513
- angle: number;
1514
- spacing: number;
1515
- } | {
1516
- kind: "gradient";
1517
- shape?: "linear" | "radial";
1518
- color1?: string;
1519
- color2?: string;
1520
- angle?: number;
1521
- };
1522
- /** Pattern spacing multiplier. */
1523
- scale?: number;
1524
- }>;
1525
- type Text = Styled<{
1526
- type: "text";
1527
- position: Vec2Like;
1528
- content: string;
1529
- rotation?: number;
1530
- /** Justification, as in AutoCAD / DXF: which edge sits on the point —
1531
- * "left" = the text runs right of it, "right" = left of it; vAlign
1532
- * "bottom" = the text sits above the point, "top" = below it. */
1533
- hAlign?: "left" | "center" | "right";
1534
- vAlign?: "bottom" | "center" | "top";
1535
- /** Word-wrap / frame width in mm (before `scale`); absent = no wrapping. */
1536
- width?: number;
1537
- frame?: "none" | "rectangle" | "circle" | "slot" | "bottom" | "firstLine";
1538
- /** MLEADER-style arrow polylines pointing at the text (arrowhead at [0]). */
1539
- leaderLines?: readonly (readonly Vec2Like[])[];
1540
- /** Style overrides; absent keys inherit the document text style. */
1541
- styleOverride?: {
1542
- font?: string;
1543
- widthFactor?: number;
1544
- bold?: boolean;
1545
- italic?: boolean;
1546
- /** Cap height in mm (before `scale`). */
1547
- textHeight?: number;
1548
- arrowSize?: number;
1549
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
1550
- };
1551
- /** Size multiplier for height + arrow size. */
1552
- scale?: number;
1553
- }>;
1554
- type Dimension = Styled<{
1555
- type: "dimension";
1556
- kind?: "linear" | "angular" | "radial" | "diameter";
1557
- /** linear: 2+ chained points (measured point to point); angular: [vertex, a, b]; radial: [center, p]; diameter: [p1, p2]. */
1558
- points: readonly Vec2Like[];
1559
- /** Dimension line offset from the kind's anchor (points[0]; diameter: the
1560
- * points' midpoint). anchor + offset lies on the dimension line (angular:
1561
- * on the arc; radial/diameter: at the text). */
1562
- offset: Vec2Like;
1563
- textOverride?: string;
1564
- styleOverride?: {
1565
- textHeight?: number;
1566
- arrowSize?: number;
1567
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
1568
- /** "short" = a 2×overshoot tick across the dimension line. */
1569
- extensionType?: "long" | "short";
1570
- extensionOffset?: number;
1571
- extensionOvershoot?: number;
1572
- textOffset?: number;
1573
- precision?: number;
1574
- };
1575
- /** Annotation size multiplier (text/arrows/offsets). */
1576
- scale?: number;
1577
- }>;
1578
- /** Nested block instance (inputs may hold points, never object references). */
1579
- type Block = Styled<{
1580
- type: "block";
1581
- definitionId: string;
1582
- /** Applied last, about the pivot (the first input point). */
1583
- rotation?: number;
1584
- scale?: number;
1585
- params?: Record<string, number | string | boolean | readonly number[] | readonly string[]>;
1586
- /** Input points in the PARENT's local coords; the first is the pivot. */
1587
- inputs?: readonly Vec2Like[];
1588
- }>;
1589
- /** A table cell: plain text, or text with merge / alignment / style. */
1590
- type TableCell = string | {
1591
- text?: string;
1592
- /** Merge from this (top-left) cell; covered cells are ignored. */
1593
- span?: {
1594
- cols: number;
1595
- rows: number;
1596
- };
1597
- hAlign?: "left" | "center" | "right";
1598
- vAlign?: "top" | "center" | "bottom";
1599
- styleId?: string;
1600
- styleOverride?: TextStyleOverride;
1601
- color?: string;
1602
- };
1603
- /** Grid of text cells hanging right/down from `position` (top-left);
1604
- * rows grow to fit their wrapped text. */
1605
- type Table = Styled<{
1606
- type: "table";
1607
- position: Vec2Like;
1608
- /** Column widths (mm, before `scale`). */
1609
- columns: readonly number[];
1610
- /** Row count, or per-row settings (`minHeight` mm floor). */
1611
- rows: number | readonly {
1612
- minHeight?: number;
1613
- }[];
1614
- /** Row-major `cells[row][column]`, exactly rows × columns. */
1615
- cells: readonly (readonly TableCell[])[];
1616
- rotation?: number;
1617
- scale?: number;
1618
- /** Rows above the heavier header rule. */
1619
- headerRows?: number;
1620
- /** Text inset from the cell edges (mm). */
1621
- cellMargin?: number;
1622
- borders?: "all" | "outer" | "rows" | "none";
1623
- styleId?: string;
1624
- styleOverride?: TextStyleOverride;
1625
- }>;
1626
- type ModelObject = Line | Point | Polyline | Circle | Arc | Ellipse | Hatch | Text | Dimension | Block | Table;
1627
- /** Identity + shared style fields every stored object carries. */
1628
- type StoredObjectBase = {
1629
- id: string;
1630
- layerId: string;
1631
- /** #rrggbb override; absent = by layer. */
1632
- color?: string;
1633
- lineType?: string;
1634
- lineTypeScale?: number;
1635
- lineWidth?: number;
1636
- /** Paint opacity 0..1; absent = opaque. */
1637
- opacity?: number;
1638
- };
1639
- /** Flattens base + per-type fields so hovers list every member inline
1640
- * (same trick as Styled<T> for the authoring DTOs). */
1641
- type StoredShape<T> = {
1642
- [K in keyof (T & StoredObjectBase)]: (T & StoredObjectBase)[K];
1643
- } & {};
1644
- /** Stored polyline vertex — bulge always present (default 0 applied). */
1645
- type StoredPolylineVertex = {
1646
- x: number;
1647
- y: number;
1648
- bulge: number;
1649
- };
1650
- type StoredLine = StoredShape<{
1651
- type: "line";
1652
- a: Vec2;
1653
- b: Vec2;
1654
- }>;
1655
- type StoredPoint = StoredShape<{
1656
- type: "point";
1657
- p: Vec2;
1658
- }>;
1659
- type StoredPolyline = StoredShape<{
1660
- type: "polyline";
1661
- points: readonly StoredPolylineVertex[];
1662
- closed: boolean;
1663
- }>;
1664
- type StoredCircle = StoredShape<{
1665
- type: "circle";
1666
- center: Vec2;
1667
- radius: number;
1668
- }>;
1669
- type StoredArc = StoredShape<{
1670
- type: "arc";
1671
- center: Vec2;
1672
- radius: number;
1673
- startAngle: number;
1674
- endAngle: number;
1675
- }>;
1676
- type StoredEllipse = StoredShape<{
1677
- type: "ellipse";
1678
- center: Vec2;
1679
- majorAxis: Vec2;
1680
- ratio: number;
1681
- startAngle: number;
1682
- endAngle: number;
1683
- }>;
1684
- type StoredHatchFill = {
1685
- kind: "solid";
1686
- } | {
1687
- kind: "pattern";
1688
- name: string;
1689
- angle: number;
1690
- scale: number;
1691
- } | {
1692
- kind: "lines";
1693
- angle: number;
1694
- spacing: number;
1695
- } | {
1696
- kind: "gradient";
1697
- shape: "linear" | "radial";
1698
- color1: string;
1699
- color2: string;
1700
- angle: number;
1701
- };
1702
- type StoredHatch = StoredShape<{
1703
- type: "hatch";
1704
- /** loops[0] = outer boundary, the rest are holes (even-odd). */
1705
- loops: readonly {
1706
- points: readonly StoredPolylineVertex[];
1707
- }[];
1708
- fill: StoredHatchFill;
1709
- scale: number;
1710
- }>;
1711
- type StoredText = StoredShape<{
1712
- type: "text";
1713
- position: Vec2;
1714
- content: string;
1715
- leaderLines: readonly (readonly Vec2[])[];
1716
- /** Word-wrap / frame width in mm; absent = no wrapping. */
1717
- width?: number;
1718
- hAlign: "left" | "center" | "right";
1719
- vAlign: "bottom" | "center" | "top";
1720
- frame?: "none" | "rectangle" | "circle" | "slot" | "bottom" | "firstLine";
1721
- styleId?: string;
1722
- /** Only the keys the user actually overrode on this text. */
1723
- styleOverride?: {
1724
- font?: string;
1725
- widthFactor?: number;
1726
- bold?: boolean;
1727
- italic?: boolean;
1728
- textHeight?: number;
1729
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
1730
- arrowSize?: number;
1731
- };
1732
- rotation: number;
1733
- scale: number;
1734
- }>;
1735
- type StoredDimension = StoredShape<{
1736
- type: "dimension";
1737
- kind: "linear" | "angular" | "radial" | "diameter";
1738
- points: readonly Vec2[];
1739
- offset: Vec2;
1740
- textOverride?: string;
1741
- styleId?: string;
1742
- /** Only the keys the user actually overrode on this dimension. */
1743
- styleOverride?: {
1744
- font?: string;
1745
- widthFactor?: number;
1746
- bold?: boolean;
1747
- italic?: boolean;
1748
- textHeight?: number;
1749
- textOffset?: number;
1750
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
1751
- arrowSize?: number;
1752
- extensionType?: "long" | "short";
1753
- extensionOffset?: number;
1754
- extensionOvershoot?: number;
1755
- precision?: number;
1756
- };
1757
- scale: number;
1758
- }>;
1759
- type StoredBlock = StoredShape<{
1760
- type: "block";
1761
- definitionId: string;
1762
- rotation: number;
1763
- scale: number;
1764
- params: Readonly<Record<string, number | string | boolean | readonly number[] | readonly string[]>>;
1765
- /** World points and/or referenced object ids, in pick order. */
1766
- inputs: readonly (Vec2 | string)[];
1767
- }>;
1768
- /** Paper-space window into model space; exists only in layout spaces. */
1769
- type StoredViewport = StoredShape<{
1770
- type: "viewport";
1771
- rect: {
1772
- x: number;
1773
- y: number;
1774
- w: number;
1775
- h: number;
1776
- };
1777
- modelCenter: Vec2;
1778
- /** Drawing-scale denominator (model mm per paper mm); 1:50 => 50. */
1779
- scale: number;
1780
- locked: boolean;
1781
- hiddenLayerIds: readonly string[];
1782
- }>;
1783
- /** Raster reference; pixels live in the document's assets map. */
1784
- type StoredImage = StoredShape<{
1785
- type: "image";
1786
- assetId: string;
1787
- origin: Vec2;
1788
- width: number;
1789
- height: number;
1790
- rotation: number;
1791
- }>;
1792
- /** A LINKED file drawn in place (an xref); the document holds only this
1793
- * record — the file's content is not readable from scripts. */
1794
- type StoredReference = StoredShape<{
1795
- type: "reference";
1796
- format: "linea" | "dxf" | "dwg" | "pdf" | "png" | "jpg";
1797
- name: string;
1798
- source: {
1799
- kind: "path";
1800
- path: string;
1801
- cacheKey?: string;
1802
- } | {
1803
- kind: "url";
1804
- url: string;
1805
- };
1806
- /** Where the file's origin lands. */
1807
- position: Vec2;
1808
- rotation: number;
1809
- scale: number;
1810
- mirrored?: boolean;
1811
- pdfPage?: number;
1812
- pdfMode?: "vector" | "raster";
1813
- /** The file's layers not drawn, by name. */
1814
- hiddenLayers: readonly string[];
1815
- /** Switched off: not drawn. */
1816
- hidden?: boolean;
1817
- /** Crop rectangle in file coordinates. */
1818
- clip?: {
1819
- minX: number;
1820
- minY: number;
1821
- maxX: number;
1822
- maxY: number;
1823
- };
1824
- /** Content bounds in file coordinates at the last load. */
1825
- extent?: {
1826
- minX: number;
1827
- minY: number;
1828
- maxX: number;
1829
- maxY: number;
1830
- };
1831
- }>;
1832
- /** Review note pinned to a point; the editor shows a screen-fixed marker. */
1833
- type StoredComment = StoredShape<{
1834
- type: "comment";
1835
- /** Tail tip of the bubble (world/sheet mm). */
1836
- position: Vec2;
1837
- text: string;
1838
- tags: readonly string[];
1839
- }>;
1840
- /** Text style keys a text, table or table cell may override. */
1841
- type TextStyleOverride = {
1842
- font?: string;
1843
- widthFactor?: number;
1844
- bold?: boolean;
1845
- italic?: boolean;
1846
- textHeight?: number;
1847
- arrowType?: "filled" | "open" | "tick" | "dot" | "none";
1848
- arrowSize?: number;
1849
- };
1850
- /** One table cell as stored. */
1851
- type StoredTableCell = {
1852
- /** Plain text; "\n" = line break. */
1853
- text: string;
1854
- /** Merge, on the anchor (top-left) cell; covered cells are ignored. */
1855
- span?: {
1856
- cols: number;
1857
- rows: number;
1858
- };
1859
- hAlign?: "left" | "center" | "right";
1860
- vAlign?: "top" | "center" | "bottom";
1861
- styleId?: string;
1862
- styleOverride?: TextStyleOverride;
1863
- color?: string;
1864
- };
1865
- /** Grid of text cells hanging right/down from `position` (top-left). */
1866
- type StoredTable = StoredShape<{
1867
- type: "table";
1868
- position: Vec2;
1869
- rotation: number;
1870
- scale: number;
1871
- /** Column widths (mm, before `scale`). */
1872
- columns: readonly number[];
1873
- rows: readonly {
1874
- minHeight?: number;
1875
- }[];
1876
- /** Row-major `cells[row][column]`. */
1877
- cells: readonly (readonly StoredTableCell[])[];
1878
- headerRows: number;
1879
- cellMargin: number;
1880
- borders: "all" | "outer" | "rows" | "none";
1881
- styleId?: string;
1882
- styleOverride?: TextStyleOverride;
1883
- }>;
1884
- /** Any object as stored in the document — what reads hand to scripts. */
1885
- type StoredObject = StoredLine | StoredPoint | StoredPolyline | StoredCircle | StoredArc | StoredEllipse | StoredHatch | StoredText | StoredDimension | StoredBlock | StoredViewport | StoredImage | StoredComment | StoredTable | StoredReference;
1886
- /**
1887
- * One choice of a "Select" parameter: the value (what scripts receive) with
1888
- * an optional properties-panel label. A plain string is shorthand for
1889
- * `{ value }`.
1890
- */
1891
- type ParameterOption = string | {
1892
- value: string;
1893
- label?: string;
1894
- /** A `#rrggbb` color square before the option's label. */
1895
- swatch?: string;
1896
- };
1897
- /**
1898
- * One entry of the module's optional `params` export — the block's
1899
- * parameters table. `name` is the key scripts read from `params`, `label`
1900
- * the properties-panel caption (defaults to the name).
1901
- */
1902
- /** What every params-table entry may carry: its key, panel caption and
1903
- * tooltip. */
1904
- type ParamBase = {
1905
- /** The key scripts read from `params`. */
1906
- name: string;
1907
- /** The properties-panel caption (defaults to the name). */
1908
- label?: string;
1909
- /** What the parameter means: the label's tooltip in the panel. */
1910
- hint?: string;
1911
- };
1912
- type ParamDef = (ParamBase & {
1913
- type: "number";
1914
- default: number;
1915
- min?: number;
1916
- max?: number;
1917
- /** Whole numbers only. */
1918
- integer?: boolean;
1919
- /** ArrowUp / ArrowDown increment in the panel (default 1). */
1920
- step?: number;
1921
- /** Shown inside the field before / after the value ("1:", "mm"). */
1922
- prefix?: string;
1923
- suffix?: string;
1924
- /** Standard values offered in the field's dropdown; typing stays free. */
1925
- presets?: readonly number[];
1926
- }) | (ParamBase & {
1927
- type: "string";
1928
- default: string;
1929
- placeholder?: string;
1930
- /** A textarea; Shift+Enter starts a new line. */
1931
- multiline?: boolean;
1932
- presets?: readonly string[];
1933
- }) | (ParamBase & {
1934
- type: "boolean";
1935
- default: boolean;
1936
- /** "toggle": a toggle button showing the label (compact, e.g. in a
1937
- * row beside a picker) instead of a switch. */
1938
- display?: "switch" | "toggle";
1939
- })
1940
- /** A list of numbers, edited as space-separated text with Tekla-style
1941
- * `N*d` repeats ("0 2*7200" → [0, 7200, 7200]). */
1942
- | (ParamBase & {
1943
- type: "numberList";
1944
- default: readonly number[];
1945
- /** Shown while the list is empty. */
1946
- placeholder?: string;
1947
- min?: number;
1948
- max?: number;
1949
- presets?: readonly (readonly number[])[];
1950
- })
1951
- /** A list of strings, edited as space-separated words; double quotes group
1952
- * a phrase ('A "B 2"' → ["A", "B 2"]). */
1953
- | (ParamBase & {
1954
- type: "stringList";
1955
- default: readonly string[];
1956
- /** Shown while the list is empty. */
1957
- placeholder?: string;
1958
- presets?: readonly (readonly string[])[];
1959
- })
1960
- /** A `#rrggbb` color: a swatch with a picker; presets form a palette. */
1961
- | (ParamBase & {
1962
- type: "color";
1963
- default: string;
1964
- presets?: readonly string[];
1965
- }) | (ParamBase & {
1966
- type: "enum";
1967
- default: string;
1968
- options: readonly ParameterOption[];
1969
- /** "buttons": a segmented toggle group of the options (short
1970
- * choices); falls back to the dropdown when they don't fit. */
1971
- display?: "dropdown" | "buttons";
1972
- })
1973
- /** Pickers over the document's resources; the value is an id / name.
1974
- * textStyle / dimStyle: a style id ("" or unknown = the document's first
1975
- * style — read it in draw with `styles.text(id)` / `styles.dim(id)`, or
1976
- * hand it to children as `styleId`). font: a font id ("arial"…).
1977
- * lineType / hatchPattern: a linetype / pattern name. */
1978
- | (ParamBase & {
1979
- type: "textStyle" | "dimStyle" | "font" | "lineType" | "hatchPattern";
1980
- default?: string;
1981
- })
1982
- /** A section label between rows in the properties panel. Carries no
1983
- * value: it never appears in the `params` record `draw` receives.
1984
- * `name` stays the unique key (paramVisibility can hide it by name). */
1985
- | (ParamBase & {
1986
- type: "label";
1987
- })
1988
- /** Layout only: 2–3 compact params on one panel row, each item's label a
1989
- * short prefix ("W", "H"). Values stay flat — `params.w`, `params.h`. */
1990
- | (ParamBase & {
1991
- type: "row";
1992
- items: readonly RowItemDef[];
1993
- });
1994
- /** A document text style as `draw` reads it (`styles.text(id)`). Heights
1995
- * and arrow sizes are mm before an object's `scale`. */
1996
- type TextStyleInfo = {
1997
- readonly id: string;
1998
- readonly name: string;
1999
- readonly font: string;
2000
- readonly widthFactor: number;
2001
- readonly bold?: boolean;
2002
- readonly italic?: boolean;
2003
- readonly textHeight: number;
2004
- readonly arrowType: "filled" | "open" | "tick" | "dot" | "none";
2005
- readonly arrowSize: number;
2006
- };
2007
- /** A document dimension style as `draw` reads it (`styles.dim(id)`). */
2008
- type DimStyleInfo = {
2009
- readonly id: string;
2010
- readonly name: string;
2011
- readonly font: string;
2012
- readonly widthFactor: number;
2013
- readonly bold?: boolean;
2014
- readonly italic?: boolean;
2015
- readonly textHeight: number;
2016
- readonly textOffset: number;
2017
- readonly arrowType: "filled" | "open" | "tick" | "dot" | "none";
2018
- readonly arrowSize: number;
2019
- readonly extensionType: "long" | "short";
2020
- readonly extensionOffset: number;
2021
- readonly extensionOvershoot: number;
2022
- readonly precision: number;
2023
- };
2024
- /** `draw`'s `styles`: the document's styles by id. An empty or unknown id
2025
- * (a deleted style, a block from another drawing) gives the document's
2026
- * first style — the same rule a child's `styleId` follows. */
2027
- interface BlockStyles {
2028
- text(id?: string): TextStyleInfo;
2029
- dim(id?: string): DimStyleInfo;
2030
- }
2031
- /** What a `row` may hold: the compact, single-line param kinds. */
2032
- type RowItemDef = Extract<ParamDef, {
2033
- type: "number" | "string" | "boolean" | "enum" | "color" | "textStyle" | "dimStyle" | "font" | "lineType" | "hatchPattern";
2034
- }>;
2035
- /** A table entry's value-carrying params: a row's items, else itself. */
2036
- type FlatParam<Q> = Q extends {
2037
- type: "row";
2038
- items: readonly (infer I)[];
2039
- } ? I : Q;
2040
- /**
2041
- * The block's parameters table — what the `params` member of a BlockSpec
2042
- * declares (or its function form returns).
2043
- */
2044
- type BlockParamDefs = readonly ParamDef[];
2045
- /** What the script's `draw` export must return. */
2046
- type BlockScriptResult = ModelObject[];
2047
- /** The value an enum option denotes (its string, or `value` of the record form). */
2048
- type OptionValue<O extends ParameterOption> = O extends string ? O : O extends {
2049
- value: infer V extends string;
2050
- } ? V : never;
2051
- /** The runtime value type of one `params` table entry. */
2052
- type ParamValue<Q extends ParamDef> = Q extends {
2053
- type: "enum";
2054
- } ? OptionValue<Q["options"][number]> : Q extends {
2055
- type: "number";
2056
- } ? number : Q extends {
2057
- type: "boolean";
2058
- } ? boolean : Q extends {
2059
- type: "numberList";
2060
- } ? readonly number[] : Q extends {
2061
- type: "stringList";
2062
- } ? readonly string[] : string;
2063
- /**
2064
- * The values record a params table produces: each entry's `name` maps to
2065
- * its runtime value type (number/string/boolean, or the enum's option
2066
- * union). This is what `draw`/`place`/`paramVisibility` receive as
2067
- * `params` — inside defineBlock the table type is inferred, so authors
2068
- * never spell this out. Unwraps the function form of `params`; a non-table
2069
- * type (an already-derived values record, or the open BlockParams default)
2070
- * passes through unchanged.
2071
- */
2072
- type ParamValues<P> = P extends () => infer R ? ParamValues<R> : P extends readonly (infer Q extends ParamDef)[] ? {
2073
- readonly [E in FlatParam<Q> as E extends {
2074
- type: "label";
2075
- } ? never : E extends {
2076
- name: infer N extends string;
2077
- } ? N : never]: E extends ParamDef ? ParamValue<E> : never;
2078
- } : P;
2079
- /** An axis-aligned box in world mm. */
2080
- type Box = {
2081
- minX: number;
2082
- minY: number;
2083
- maxX: number;
2084
- maxY: number;
2085
- };
2086
- /** Filters for Drawing.query — all present filters AND together. */
2087
- type ObjectQuery = {
2088
- ids?: readonly string[];
2089
- type?: ModelObject["type"];
2090
- /** Layer name or id. */
2091
- layer?: string;
2092
- /** #rrggbb override (objects without one inherit from their layer). */
2093
- color?: string;
2094
- lineType?: string;
2095
- /** Substring match on text content. */
2096
- content?: string;
2097
- /** Bounds intersect this box. */
2098
- bbox?: Box;
2099
- /** Bounds entirely inside this box. */
2100
- inside?: Box;
2101
- /** Geometry within `tol` mm of `point`. */
2102
- near?: {
2103
- point: Vec2Like;
2104
- tol: number;
2105
- };
2106
- /** Search this paper layout's sheet objects (name or id) instead of
2107
- * model space. */
2108
- layout?: string;
2109
- };
2110
- /** A STORED object as query() returns it (see StoredObject — schema
2111
- * output: defaults applied, points always {x, y}, identity present). */
2112
- type ExistingObject = StoredObject;
2113
- /** Per-object measurements; null where the type has no natural value. */
2114
- type Measurement = {
2115
- bbox: Box | null;
2116
- length: number | null;
2117
- area: number | null;
2118
- };
2119
- /** A layer as stored (defaults applied) plus the current-layer flag. */
2120
- type LayerInfo = {
2121
- id: string;
2122
- name: string;
2123
- color: string;
2124
- lineType: string;
2125
- lineWidth: number;
2126
- opacity: number;
2127
- visible: boolean;
2128
- locked: boolean;
2129
- current: boolean;
2130
- [key: string]: unknown;
2131
- };
2132
- /** A paper layout as stored: sheet metadata + its sheet-space objects. */
2133
- type LayoutInfo = {
2134
- id: string;
2135
- name: string;
2136
- sheet: {
2137
- width: number;
2138
- height: number;
2139
- };
2140
- printPalette: "color" | "grayscale" | "monochrome";
2141
- objects: readonly StoredObject[];
2142
- };
2143
- /** A block module's identity/metadata (from its exports). */
2144
- type BlockInfo = {
2145
- id: string;
2146
- name: string;
2147
- description?: string;
2148
- version?: string;
2149
- authors?: readonly string[];
2150
- tags?: readonly string[];
2151
- dependencies?: readonly string[];
2152
- };
2153
- /** A command module's identity/metadata (from its exports). */
2154
- type CommandInfo = {
2155
- id: string;
2156
- name: string;
2157
- description?: string;
2158
- version?: string;
2159
- authors?: readonly string[];
2160
- tags?: readonly string[];
2161
- /** Declared point inputs (labels), picked or supplied before `run`. */
2162
- inputs?: readonly string[];
2163
- /** Declared parameters (same table as a block's), prompted or supplied
2164
- * before `run`. */
2165
- params?: readonly ParamDef[];
2166
- };
2167
- /** What installing module sources reports. */
2168
- type MergeReport = {
2169
- /** The full library after the merge. */
2170
- merged: readonly string[];
2171
- added: readonly {
2172
- script: string;
2173
- meta: {
2174
- id: string;
2175
- name: string;
2176
- };
2177
- }[];
2178
- replaced: readonly {
2179
- script: string;
2180
- meta: {
2181
- id: string;
2182
- name: string;
2183
- };
2184
- }[];
2185
- skipped: number;
2186
- rejected: readonly {
2187
- script: string;
2188
- error: string;
2189
- }[];
2190
- };
2191
- /** A sheet: a bare preset (orientation from context — landscape for a new
2192
- * layout, the current one when patching), a preset with its orientation, or
2193
- * explicit millimetres. */
2194
- type SheetSpec = "A4" | "A3" | "A2" | "A1" | "A0" | {
2195
- name: "A4" | "A3" | "A2" | "A1" | "A0";
2196
- orientation: "portrait" | "landscape";
2197
- } | {
2198
- width: number;
2199
- height: number;
2200
- };
2201
- /** What an import added (`objectIds` = the new objects). */
2202
- interface ImportReport {
2203
- objects: number;
2204
- objectIds: string[];
2205
1610
  }
2206
- /** Options for Drawing.addLayout. */
2207
- type LayoutSpec = {
2208
- /** Default: A3 landscape. */
2209
- sheet?: SheetSpec;
2210
- /** Viewport scale — `"1:50"` or the denominator; default: fitted. */
2211
- scale?: number | string;
2212
- /** One fitted model viewport (default), or `false` for a bare sheet. */
2213
- viewport?: {
2214
- rect?: {
2215
- x: number;
2216
- y: number;
2217
- w: number;
2218
- h: number;
2219
- };
2220
- scale?: number | string;
2221
- center?: Vec2Like;
2222
- } | false;
2223
- /** Tab position; default: append. */
2224
- index?: number;
2225
- };
2226
- /** The whole document as stored (defaults applied). */
2227
- type StoredDocument = {
2228
- id: string;
2229
- version: number;
2230
- layers: readonly Omit<LayerInfo, "current">[];
2231
- currentLayerId: string;
2232
- objects: readonly StoredObject[];
2233
- layouts: readonly LayoutInfo[];
2234
- /** Raw block module sources. */
2235
- blockDefinitions: readonly string[];
2236
- /** Raw command module sources. */
2237
- commands: readonly string[];
2238
- [key: string]: unknown;
2239
- };
2240
- /** Where a draw-order move puts the objects. */
2241
- type ReorderPlacement = "front" | "back" | {
2242
- above: string;
2243
- } | {
2244
- below: string;
2245
- };
2246
- /**
2247
- * The document as command scripts see it — the SAME `Drawing` interface
2248
- * the agent tools and the SDK use. Angles are RADIANS, point-valued
2249
- * arguments accept {x, y} or [x, y], `layer` resolves by name or id.
2250
- * Object mutations on an editor-attached drawing target the ACTIVE space.
2251
- * Methods throw on invalid input (an uncaught throw cancels the command
2252
- * and rolls its edits back). Reads return detached snapshots.
2253
- */
2254
- interface Drawing {
2255
- /** The document's own id. */
2256
- readonly id: string;
2257
- /** Monotonic change counter. */
2258
- readonly revision: number;
2259
- /** The full document — a detached snapshot. */
2260
- readonly document: StoredDocument;
2261
- /** Counts by type/layer, bbox, layer + layout names. */
2262
- summary(): {
2263
- name: string;
2264
- objectCount: number;
2265
- byType: Record<string, number>;
2266
- byLayer: Record<string, number>;
2267
- bbox: Box | null;
2268
- layers: string[];
2269
- layouts: {
2270
- name: string;
2271
- objectCount: number;
2272
- }[];
2273
- };
2274
- /** Filtered objects — model space, or one layout via `filter.layout`. */
2275
- listObjects(filter?: ObjectQuery): ExistingObject[];
2276
- /** One object from ANY space, or undefined. */
2277
- getObject(id: string): ExistingObject | undefined;
2278
- /** bbox / curve length / enclosed area of one object. */
2279
- measure(id: string): Measurement;
2280
- listLayers(): LayerInfo[];
2281
- listLayouts(): LayoutInfo[];
2282
- /** Compilable block definitions in this document. */
2283
- listBlockDefinitions(): BlockInfo[];
2284
- /** Compilable command modules travelling with this document. */
2285
- listUserCommands(): CommandInfo[];
2286
- /** Model space (or a layout via `layout`) as an SVG string. */
2287
- renderSvg(opts?: {
2288
- layout?: string;
2289
- bbox?: Box;
2290
- padding?: number;
2291
- palette?: "color" | "grayscale" | "monochrome";
2292
- }): string;
2293
- /** Model space (or a layout) as PNG bytes — absent on hosts that can't
2294
- * rasterize, so check before calling. */
2295
- renderPng?(opts?: {
2296
- layout?: string;
2297
- bbox?: Box;
2298
- padding?: number;
2299
- palette?: "color" | "grayscale" | "monochrome";
2300
- /** Output width in px (height follows). Default 1024. */
2301
- width?: number;
2302
- /** Background fill, e.g. "#ffffff". Default: the dark canvas. */
2303
- background?: string;
2304
- }): Promise<Uint8Array>;
2305
- /** Multi-page PDF of the layouts (default: all) — absent on hosts
2306
- * without fonts, so check before calling. */
2307
- renderPdf?(opts?: {
2308
- layouts?: readonly string[];
2309
- palette?: "color" | "grayscale" | "monochrome";
2310
- }): Promise<Uint8Array>;
2311
- /** The whole document as DXF text. */
2312
- toDxf(): Promise<string>;
2313
- /** DWG bytes (default AC1027 — AutoCAD 2013). */
2314
- toDwg(opts?: {
2315
- version?: string;
2316
- }): Promise<Uint8Array>;
2317
- /** The `.linea` file text. */
2318
- toLinea(): string;
2319
- /** Add objects (each may carry `layer` — a name — instead of an id);
2320
- * returns the created ids. */
2321
- add(objects: readonly (ModelObject & {
2322
- layer?: string;
2323
- })[], opts?: {
2324
- layout?: string;
2325
- }): string[];
2326
- /** Apply per-object patches (`{ id, ...changedFields }`). */
2327
- update(entries: readonly ({
2328
- id: string;
2329
- } & Record<string, unknown>)[]): void;
2330
- /** Delete by id (unknown ids are skipped); returns how many went. */
2331
- remove(ids: readonly string[]): number;
2332
- /** Draw order: move the objects (bottom → top) to a placement. */
2333
- reorder(ids: readonly string[], placement: ReorderPlacement): void;
2334
- move(ids: readonly string[], delta: Vec2Like): void;
2335
- rotate(ids: readonly string[], angleRad: number, center?: Vec2Like): void;
2336
- scale(ids: readonly string[], factor: number, center?: Vec2Like): void;
2337
- mirror(ids: readonly string[], axisA: Vec2Like, axisB: Vec2Like): void;
2338
- /** Duplicate displaced by delta; returns the new ids. */
2339
- copy(ids: readonly string[], delta: Vec2Like): string[];
2340
- /** count TOTAL copies at multiples of delta; returns the new ids. */
2341
- array(ids: readonly string[], count: number, delta: Vec2Like): string[];
2342
- /** Create a paper layout; returns its id. */
2343
- addLayout(name: string, opts?: LayoutSpec): string;
2344
- /** Patch a layout's name / sheet / print palette. A bare preset keeps the
2345
- * layout's current orientation. */
2346
- updateLayout(nameOrId: string, patch: {
2347
- name?: string;
2348
- sheet?: SheetSpec;
2349
- printPalette?: "color" | "grayscale" | "monochrome";
2350
- }): void;
2351
- removeLayout(nameOrId: string): void;
2352
- /** Explicit total order (names or ids) — the PDF page order. */
2353
- reorderLayouts(order: readonly string[]): void;
2354
- /** Create a layer (unique name); returns its id. */
2355
- addLayer(props: {
2356
- name: string;
2357
- color?: string;
2358
- } & Record<string, unknown>): string;
2359
- updateLayer(nameOrId: string, patch: Record<string, unknown>): void;
2360
- /** Remove an EMPTY, non-current layer. */
2361
- removeLayer(nameOrId: string): void;
2362
- /** Explicit total order (names or ids, every layer exactly once). */
2363
- reorderLayers(order: readonly string[]): void;
2364
- setCurrentLayer(nameOrId: string): void;
2365
- listTextStyles(): ({
2366
- id: string;
2367
- name: string;
2368
- } & Record<string, unknown>)[];
2369
- listDimStyles(): ({
2370
- id: string;
2371
- name: string;
2372
- } & Record<string, unknown>)[];
2373
- /** Create a style (unique name; unset fields take the defaults); returns
2374
- * its id. Styles are addressed by name or id. */
2375
- addTextStyle(props: {
2376
- name: string;
2377
- } & Record<string, unknown>): string;
2378
- updateTextStyle(nameOrId: string, patch: Record<string, unknown>): void;
2379
- /** Remove a style no object uses (refused otherwise). */
2380
- removeTextStyle(nameOrId: string): void;
2381
- addDimStyle(props: {
2382
- name: string;
2383
- } & Record<string, unknown>): string;
2384
- updateDimStyle(nameOrId: string, patch: Record<string, unknown>): void;
2385
- removeDimStyle(nameOrId: string): void;
2386
- /** @deprecated Use updateDimStyle (default here: the first style). */
2387
- setDimStyle(patch: Record<string, unknown>, styleId?: string): void;
2388
- /** @deprecated Use updateTextStyle (default here: the first style). */
2389
- setTextStyle(patch: Record<string, unknown>, styleId?: string): void;
2390
- /** Embed image pixels (a data URL); returns the content-keyed assetId
2391
- * that `image` objects reference. */
2392
- addAsset(dataUrl: string): string;
2393
- /** Remove an asset (refused while an image references it). */
2394
- removeAsset(id: string): void;
2395
- /** Embedded image assets and how many images use each. */
2396
- listAssets(): {
2397
- id: string;
2398
- mimeType: string;
2399
- bytes: number;
2400
- users: number;
2401
- }[];
2402
- /** Merge DXF text (new layers, objects, layouts); `unitOverride` = mm
2403
- * per drawing unit. */
2404
- importDxfText(text: string, opts?: {
2405
- unitOverride?: number;
2406
- }): ImportReport & {
2407
- layers: number;
2408
- layouts: number;
2409
- layoutIds: string[];
2410
- };
2411
- /** Merge DWG bytes (transcoded to DXF). */
2412
- importDwgData(data: Uint8Array, opts?: {
2413
- unitOverride?: number;
2414
- }): Promise<ImportReport & {
2415
- layers: number;
2416
- layouts: number;
2417
- layoutIds: string[];
2418
- }>;
2419
- /** Merge a PDF: vectors/text onto the current layer, or (`as: "image"`,
2420
- * not available on every host) each page as an image at true scale. */
2421
- importPdfData(data: ArrayBuffer | Uint8Array, opts?: {
2422
- as?: "vectors" | "image";
2423
- origin?: Vec2Like;
2424
- }): Promise<ImportReport & {
2425
- pageCount: number;
2426
- }>;
2427
- /** Merge block module sources into the document library. */
2428
- addBlockDefinitions(sources: readonly string[]): Promise<MergeReport>;
2429
- removeBlockDefinition(id: string): void;
2430
- addUserCommands(sources: readonly string[]): Promise<MergeReport>;
2431
- removeUserCommand(id: string): void;
2432
- /** Escape hatch: apply an already-shaped kernel op batch (validated,
2433
- * atomic, one undo step). */
2434
- applyOps(ops: readonly Record<string, unknown>[]): void;
2435
- /**
2436
- * Group edits into ONE undo step (a command run already is one; nested
2437
- * calls join it). A throw rolls back what the transaction applied.
2438
- */
2439
- transaction<T>(fn: () => T, label?: string): T;
2440
- /** Not available while a command runs (throws) — return or throw. */
2441
- undo(): boolean;
2442
- redo(): boolean;
2443
- }
2444
- /** The editor's state as a script sees it. */
2445
- type EditorState = {
2446
- documentId: string;
2447
- documentName: string;
2448
- space: "model" | {
2449
- layout: string;
2450
- };
2451
- selectedIds: string[];
2452
- readOnly: boolean;
2453
- canUndo: boolean;
2454
- canRedo: boolean;
2455
- };
2456
- /** One runnable editor command (registry entry, macro, or insert-block). */
2457
- type EditorCommandInfo = {
2458
- id: string;
2459
- label: string;
2460
- group: string;
2461
- hotkey?: string;
2462
- };
2463
- /**
2464
- * The interactive half of the context — present only when the command runs
2465
- * inside a live editor (absent when a script runs headlessly, e.g. from the
2466
- * CLI or the MCP server; branch on it). The pickers and `prompt` REJECT
2467
- * when the user cancels (Escape) — let that propagate to abort the command
2468
- * (all edits roll back), or catch it to finish an open-ended collection.
2469
- */
2470
- interface EditorSurface {
2471
- state(): EditorState;
2472
- setActiveSpace(space: "model" | {
2473
- layout: string;
2474
- }): void;
2475
- setSelection(ids: readonly string[]): void;
2476
- /** "fit" (everything in the active space), "selection", some objects'
2477
- * extents (`{ ids }`), or a window (`{ bbox }`, world mm; sheet mm in a
2478
- * layout). */
2479
- zoom(to: "fit" | "selection" | {
2480
- ids: readonly string[];
2481
- } | {
2482
- bbox: Box;
2483
- }): void;
2484
- /** Await one snapped world point; `referencePoint` enables rubber-band
2485
- * + relative typed entry from there. */
2486
- pickPoint(opts?: {
2487
- label?: string;
2488
- referencePoint?: Vec2Like;
2489
- }): Promise<Vec2>;
2490
- /** Await one object click; resolves the object's id. */
2491
- pickObject(opts?: {
2492
- label?: string;
2493
- }): Promise<string>;
2494
- /** Await a typed value from a small input dialog. */
2495
- prompt(message: string, opts?: {
2496
- initial?: string;
2497
- placeholder?: string;
2498
- }): Promise<string>;
2499
- toast(message: string, kind?: "info" | "success" | "error"): void;
2500
- /** Registry commands + macros + insert-block entries. */
2501
- listCommands(): EditorCommandInfo[];
2502
- /** Trigger a command by id — like the user pressing its hotkey. A macro
2503
- * takes its declared `inputs` / `params` up front (params passed skip its
2504
- * params dialog). */
2505
- runCommand(id: string, inputs?: readonly Vec2Like[], params?: Readonly<Record<string, unknown>>): Promise<void>;
2506
- }
2507
- /**
2508
- * What `run` receives. `document` is the Drawing; `editor` the interactive
2509
- * surface when there is one; `inputs` the points the command's declared
2510
- * `inputs` labels produced (picked in the editor, or supplied by the
2511
- * caller), in label order; `params` the values of the declared `params`
2512
- * table (asked for in a dialog in the editor, or passed by the caller;
2513
- * omitted ones take their defaults).
2514
- */
2515
- interface CommandContext<P = Readonly<Record<string, unknown>>> {
2516
- document: Drawing;
2517
- editor?: EditorSurface;
2518
- inputs: readonly Vec2[];
2519
- params: P;
2520
- /** @deprecated Use `editor.pickPoint({ label })` (throws without an editor). */
2521
- pickPoint(label?: string): Promise<Vec2>;
2522
- /** @deprecated Use `editor.pickObject({ label })`. */
2523
- pickObject(label?: string): Promise<string>;
2524
- /** @deprecated Use `editor.state().selectedIds`. */
2525
- selection(): string[];
2526
- /** @deprecated Use `editor.setSelection(ids)`. */
2527
- setSelection(ids: readonly string[]): void;
2528
- /** @deprecated Use `editor.prompt(message, options)`. */
2529
- prompt(message: string, options?: {
2530
- initial?: string;
2531
- placeholder?: string;
2532
- }): Promise<string>;
2533
- /** @deprecated Use `editor.toast(message, kind)`. */
2534
- showToast(message: string, kind?: "info" | "success" | "error"): void;
2535
- }
2536
-
2537
- // Script-contract globals: aliases into the module (not re-declarations),
2538
- // so the in-app editor's BlockParams substitution flows through them.
2539
- declare type BlockParams = import("lineadraw").BlockParams;
2540
- declare type BlockInputs = import("lineadraw").BlockInputs;
2541
- declare type ResolvedObject = import("lineadraw").ResolvedObject;
2542
- declare type ResolvedInput<T> = import("lineadraw").ResolvedInput<T>;
2543
- declare type PlaceProps<P = BlockParams> = import("lineadraw").PlaceProps<P>;
2544
- declare type PlaceSpec<P = BlockParams> = import("lineadraw").PlaceSpec<P>;
2545
- declare type PlaceInputs<Pl> = import("lineadraw").PlaceInputs<Pl>;
2546
- declare type PreviewInputs<Pl> = import("lineadraw").PreviewInputs<Pl>;
2547
- declare type BlockSpec<
2548
- P extends import("lineadraw").BlockParamDefs = readonly [],
2549
- Pl extends PlaceSpec<P> | undefined = undefined,
2550
- > = import("lineadraw").BlockSpec<P, Pl>;
2551
- declare type CommandSpec<
2552
- P extends import("lineadraw").BlockParamDefs = readonly [],
2553
- > = import("lineadraw").CommandSpec<P>;