@snaptrude/plugin-core 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -1
- package/api-manifest.full.json +1350 -89
- package/api-manifest.json +1146 -48
- package/dist/api/analysis/daylight.d.ts +603 -0
- package/dist/api/analysis/daylight.d.ts.map +1 -0
- package/dist/api/analysis/heatmaps.d.ts +438 -14
- package/dist/api/analysis/heatmaps.d.ts.map +1 -1
- package/dist/api/analysis/index.d.ts +15 -0
- package/dist/api/analysis/index.d.ts.map +1 -1
- package/dist/api/analysis/solar.d.ts +249 -0
- package/dist/api/analysis/solar.d.ts.map +1 -0
- package/dist/api/analysis/weather.d.ts +193 -0
- package/dist/api/analysis/weather.d.ts.map +1 -0
- package/dist/api/core/camera/index.d.ts +37 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +318 -1
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/index.d.ts +9 -0
- package/dist/api/core/index.d.ts.map +1 -1
- package/dist/api/core/io/export/index.d.ts +3 -1
- package/dist/api/core/io/export/index.d.ts.map +1 -1
- package/dist/api/core/io/import/index.d.ts +61 -0
- package/dist/api/core/io/import/index.d.ts.map +1 -1
- package/dist/api/core/io/terrain/index.d.ts +132 -0
- package/dist/api/core/io/terrain/index.d.ts.map +1 -1
- package/dist/api/core/mode/index.d.ts +99 -0
- package/dist/api/core/mode/index.d.ts.map +1 -0
- package/dist/api/core/storeys/index.d.ts +251 -0
- package/dist/api/core/storeys/index.d.ts.map +1 -0
- package/dist/api/core/tags.d.ts +24 -0
- package/dist/api/core/tags.d.ts.map +1 -1
- package/dist/api/core/zoom/index.d.ts +4 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +115 -4
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +3 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/query/geometry/index.d.ts +112 -0
- package/dist/api/design/query/geometry/index.d.ts.map +1 -1
- package/dist/api/design/query/index.d.ts +4 -0
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/query/referenceLines.d.ts +45 -0
- package/dist/api/design/query/referenceLines.d.ts.map +1 -0
- package/dist/api/design/query/spaces.d.ts +173 -0
- package/dist/api/design/query/spaces.d.ts.map +1 -1
- package/dist/api/design/transform/index.d.ts +12 -0
- package/dist/api/design/transform/index.d.ts.map +1 -1
- package/dist/api/design/update/index.d.ts +51 -1
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/entity/buildableEnvelope.d.ts +4 -0
- package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
- package/dist/api/entity/referenceLine.d.ts +8 -0
- package/dist/api/entity/referenceLine.d.ts.map +1 -1
- package/dist/api/entity/story.d.ts +20 -0
- package/dist/api/entity/story.d.ts.map +1 -1
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/presentation/annotate.d.ts +23 -4
- package/dist/api/presentation/annotate.d.ts.map +1 -1
- package/dist/api/presentation/diagrams.d.ts +64 -2
- package/dist/api/presentation/diagrams.d.ts.map +1 -1
- package/dist/api/presentation/export.d.ts +4 -0
- package/dist/api/presentation/export.d.ts.map +1 -1
- package/dist/api/presentation/import.d.ts +6 -0
- package/dist/api/presentation/import.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +20 -1
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +1139 -0
- package/dist/api/presentation/placedViews.d.ts.map +1 -0
- package/dist/api/presentation/shapes.d.ts +481 -0
- package/dist/api/presentation/shapes.d.ts.map +1 -0
- package/dist/api/presentation/sheets.d.ts +42 -0
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/api/presentation/slideshow.d.ts +125 -0
- package/dist/api/presentation/slideshow.d.ts.map +1 -0
- package/dist/api/presentation/tables.d.ts +81 -0
- package/dist/api/presentation/tables.d.ts.map +1 -0
- package/dist/api/program/site.d.ts +260 -2
- package/dist/api/program/site.d.ts.map +1 -1
- package/dist/api/program/spreadsheet.d.ts +260 -28
- package/dist/api/program/spreadsheet.d.ts.map +1 -1
- package/dist/api/workspace/index.d.ts +505 -0
- package/dist/api/workspace/index.d.ts.map +1 -0
- package/dist/index.cjs +2904 -1761
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2762 -1761
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/scripts/generate-manifest.mjs +45 -0
- package/src/api/analysis/daylight.ts +470 -0
- package/src/api/analysis/heatmaps.ts +444 -17
- package/src/api/analysis/index.ts +15 -0
- package/src/api/analysis/solar.ts +237 -0
- package/src/api/analysis/weather.ts +179 -0
- package/src/api/core/camera/index.ts +39 -0
- package/src/api/core/geom/create/index.ts +344 -1
- package/src/api/core/index.ts +9 -0
- package/src/api/core/io/export/index.ts +3 -1
- package/src/api/core/io/import/index.ts +64 -0
- package/src/api/core/io/terrain/index.ts +143 -0
- package/src/api/core/mode/index.ts +96 -0
- package/src/api/core/storeys/index.ts +279 -0
- package/src/api/core/tags.ts +27 -0
- package/src/api/core/zoom/index.ts +4 -0
- package/src/api/design/create/index.ts +138 -1
- package/src/api/design/delete/index.ts +3 -0
- package/src/api/design/query/geometry/index.ts +125 -3
- package/src/api/design/query/index.ts +4 -0
- package/src/api/design/query/referenceLines.ts +52 -0
- package/src/api/design/query/spaces.ts +143 -0
- package/src/api/design/transform/index.ts +12 -0
- package/src/api/design/update/index.ts +66 -1
- package/src/api/entity/buildableEnvelope.ts +4 -0
- package/src/api/entity/referenceLine.ts +8 -0
- package/src/api/entity/story.ts +20 -0
- package/src/api/index.ts +5 -0
- package/src/api/presentation/annotate.ts +27 -2
- package/src/api/presentation/diagrams.ts +67 -2
- package/src/api/presentation/export.ts +4 -0
- package/src/api/presentation/import.ts +6 -0
- package/src/api/presentation/index.ts +20 -1
- package/src/api/presentation/placedViews.ts +1120 -0
- package/src/api/presentation/shapes.ts +274 -0
- package/src/api/presentation/sheets.ts +54 -0
- package/src/api/presentation/slideshow.ts +134 -0
- package/src/api/presentation/tables.ts +84 -0
- package/src/api/program/site.ts +205 -2
- package/src/api/program/spreadsheet.ts +251 -6
- package/src/api/workspace/index.ts +563 -0
package/src/api/program/site.ts
CHANGED
|
@@ -10,8 +10,10 @@ import { PluginAreaUnit } from "./metrics"
|
|
|
10
10
|
* in Snaptrude units — the same plan space as a space's `planPoints`), and —
|
|
11
11
|
* when the project is geo-located on terrain — their geographic
|
|
12
12
|
* (latitude/longitude) rings. This is the program-planning view of the site;
|
|
13
|
-
* zoning numbers (
|
|
14
|
-
*
|
|
13
|
+
* zoning numbers (FAR/FSI, height limits) live in the site-analysis sheet and
|
|
14
|
+
* are not read here — with one exception: `listEdges` reads each parcel's
|
|
15
|
+
* per-edge front/side/rear classification and effective base setbacks, the
|
|
16
|
+
* same resolution the buildable-envelope setback pills show on canvas.
|
|
15
17
|
*
|
|
16
18
|
* All methods are reads: they return plain records and never throw — `get`
|
|
17
19
|
* returns an empty snapshot (zero totals) when there is no site, and the `list`
|
|
@@ -85,6 +87,47 @@ export abstract class PluginProgramSiteApi {
|
|
|
85
87
|
*/
|
|
86
88
|
public abstract listPolygons(): PluginApiReturn<PluginProgramSiteListPolygonsResult>
|
|
87
89
|
|
|
90
|
+
/**
|
|
91
|
+
* List each site parcel's boundary edges with their front / side / rear
|
|
92
|
+
* classification — the same per-edge roles the buildable-envelope setback
|
|
93
|
+
* pills show on canvas, so a plugin can pick up the user's edge tagging
|
|
94
|
+
* without asking them to set it up again.
|
|
95
|
+
*
|
|
96
|
+
* Role resolution mirrors the canvas exactly: the user's per-edge overrides
|
|
97
|
+
* (set via the setback pills) win over the tangent heuristic
|
|
98
|
+
* (`roleSource: "override"` vs `"heuristic"`). `"street"` never appears — it
|
|
99
|
+
* resolves to `front`. When a parcel has a linked zoning buildable envelope,
|
|
100
|
+
* `setbackMeters` is the effective base setback of the edge (a per-edge
|
|
101
|
+
* exception when one exists, else the role's value); parcels without a
|
|
102
|
+
* zoning envelope classify by heuristic alone and report
|
|
103
|
+
* `setbackMeters: null`.
|
|
104
|
+
*
|
|
105
|
+
* Coordinates are **world meters** (`lengthUnit: "m"`) — unlike
|
|
106
|
+
* {@linkcode PluginProgramSiteApi.listPolygons} footprints, which are
|
|
107
|
+
* Snaptrude units. `edgeIndex` is keyed to the canonicalized (sanitized,
|
|
108
|
+
* CCW) boundary, the same index space the envelope's `edgeOverrides` use.
|
|
109
|
+
* `staleOverridesDropped: true` means the site was edited after the
|
|
110
|
+
* envelope was configured and the persisted overrides no longer align with
|
|
111
|
+
* the live boundary — the heuristic classification is reported instead.
|
|
112
|
+
*
|
|
113
|
+
* @returns A {@linkcode PluginProgramSiteListEdgesResult} with one entry per
|
|
114
|
+
* parcel. Empty when the project has no site.
|
|
115
|
+
*
|
|
116
|
+
* @examplePrompt Which edge of my site is the front?
|
|
117
|
+
* @examplePrompt Read the front / side / rear edges of the plot
|
|
118
|
+
* @examplePrompt What setback applies to each site edge?
|
|
119
|
+
* @examplePrompt Get the site edges the way the setback pills show them
|
|
120
|
+
*
|
|
121
|
+
* # Example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const { sites } = await snaptrude.program.site.listEdges()
|
|
124
|
+
* for (const site of sites)
|
|
125
|
+
* for (const e of site.edges)
|
|
126
|
+
* console.log(e.edgeIndex, e.role, e.roleSource, e.setbackMeters)
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
public abstract listEdges(): PluginApiReturn<PluginProgramSiteListEdgesResult>
|
|
130
|
+
|
|
88
131
|
/**
|
|
89
132
|
* List the site parcels as geographic latitude/longitude rings.
|
|
90
133
|
*
|
|
@@ -186,6 +229,56 @@ export abstract class PluginProgramSiteApi {
|
|
|
186
229
|
* ```
|
|
187
230
|
*/
|
|
188
231
|
public abstract getNorthAngle(): PluginApiReturn<PluginProgramSiteNorthAngleResult>
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get the IANA timezone of the project's geographic location.
|
|
235
|
+
*
|
|
236
|
+
* The timezone identifier (e.g. `"America/New_York"`, `"Asia/Kolkata"`)
|
|
237
|
+
* looked up from the same geo-location
|
|
238
|
+
* {@linkcode PluginProgramSiteApi.getLocation} returns. Returns `null` when
|
|
239
|
+
* the project is not geo-located on terrain.
|
|
240
|
+
*
|
|
241
|
+
* @returns A {@linkcode PluginProgramSiteTimezoneResult} — the IANA timezone
|
|
242
|
+
* id string, or `null` when the project has no geo-located site.
|
|
243
|
+
*
|
|
244
|
+
* @examplePrompt What timezone is this project in?
|
|
245
|
+
* @examplePrompt Get the site's IANA timezone
|
|
246
|
+
* @examplePrompt What's the local time zone at the project location?
|
|
247
|
+
* @examplePrompt Which timezone should I use for the sun study schedule?
|
|
248
|
+
*
|
|
249
|
+
* # Example
|
|
250
|
+
* ```ts
|
|
251
|
+
* const timezone = await snaptrude.program.site.getTimezone()
|
|
252
|
+
* if (timezone) console.log(`Project timezone: ${timezone}`)
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
public abstract getTimezone(): PluginApiReturn<PluginProgramSiteTimezoneResult>
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get the weather file resolved for the project site.
|
|
259
|
+
*
|
|
260
|
+
* A lightweight read of the EPW weather file the `analysis.*` sun and
|
|
261
|
+
* daylight studies compute against — its catalog id, station name, content
|
|
262
|
+
* checksum, and how it was selected. This is the same file (same
|
|
263
|
+
* `weatherFileId`) that {@linkcode PluginAnalysisWeatherApi.getSeries} reads
|
|
264
|
+
* rows from and that a daylight run echoes in its provenance. Returns `null`
|
|
265
|
+
* when the project has no geo-located site (no weather file to resolve).
|
|
266
|
+
*
|
|
267
|
+
* @returns A {@linkcode PluginProgramSiteWeatherResult} —
|
|
268
|
+
* `{ weatherFileId, station, checksum, selectionMethod }`, or `null` when
|
|
269
|
+
* the project has no geo-located site.
|
|
270
|
+
*
|
|
271
|
+
* @examplePrompt Which weather file is my project using?
|
|
272
|
+
* @examplePrompt What EPW station was resolved for this site?
|
|
273
|
+
* @examplePrompt Get the weather file id for the daylight analysis
|
|
274
|
+
*
|
|
275
|
+
* # Example
|
|
276
|
+
* ```ts
|
|
277
|
+
* const weather = await snaptrude.program.site.getWeather()
|
|
278
|
+
* if (weather) console.log(weather.station, weather.selectionMethod)
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
public abstract getWeather(): PluginApiReturn<PluginProgramSiteWeatherResult>
|
|
189
282
|
}
|
|
190
283
|
|
|
191
284
|
/**
|
|
@@ -420,3 +513,113 @@ export const PluginProgramSiteNorthAngleResult = z.number().nullable()
|
|
|
420
513
|
export type PluginProgramSiteNorthAngleResult = z.infer<
|
|
421
514
|
typeof PluginProgramSiteNorthAngleResult
|
|
422
515
|
>
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Result of {@linkcode PluginProgramSiteApi.getTimezone} — the IANA timezone
|
|
519
|
+
* id of the project's geo-location (e.g. `"Europe/London"`), or `null` when
|
|
520
|
+
* the project is not geo-located.
|
|
521
|
+
*/
|
|
522
|
+
export const PluginProgramSiteTimezoneResult = z.string().nullable()
|
|
523
|
+
export type PluginProgramSiteTimezoneResult = z.infer<
|
|
524
|
+
typeof PluginProgramSiteTimezoneResult
|
|
525
|
+
>
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* A summary of the weather file resolved for the project site. Matches the
|
|
529
|
+
* relevant fields of `analysis.weather`'s `PluginWeatherSourceMeta`;
|
|
530
|
+
* `selectionMethod` is one of `"nearest-station"`, `"user-upload"`, or
|
|
531
|
+
* `"project-override"`.
|
|
532
|
+
*
|
|
533
|
+
* | Property | Type | Description |
|
|
534
|
+
* |---|---|---|
|
|
535
|
+
* | `weatherFileId` | `string` | Catalog id (same key as `core.io.import.epw`) |
|
|
536
|
+
* | `station` | `string` | Station/file name |
|
|
537
|
+
* | `checksum` | `string` | sha256 of the EPW file |
|
|
538
|
+
* | `selectionMethod` | `"nearest-station" \| "user-upload" \| "project-override"` | How the file was matched |
|
|
539
|
+
*/
|
|
540
|
+
export const PluginProgramSiteWeather = z.object({
|
|
541
|
+
weatherFileId: z.string(),
|
|
542
|
+
station: z.string(),
|
|
543
|
+
checksum: z.string(),
|
|
544
|
+
selectionMethod: z.enum([
|
|
545
|
+
"nearest-station",
|
|
546
|
+
"user-upload",
|
|
547
|
+
"project-override",
|
|
548
|
+
]),
|
|
549
|
+
})
|
|
550
|
+
export type PluginProgramSiteWeather = z.infer<typeof PluginProgramSiteWeather>
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Result of {@linkcode PluginProgramSiteApi.getWeather} — the resolved weather
|
|
554
|
+
* file summary, or `null` when the project has no geo-located site.
|
|
555
|
+
*/
|
|
556
|
+
export const PluginProgramSiteWeatherResult =
|
|
557
|
+
PluginProgramSiteWeather.nullable()
|
|
558
|
+
export type PluginProgramSiteWeatherResult = z.infer<
|
|
559
|
+
typeof PluginProgramSiteWeatherResult
|
|
560
|
+
>
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Front / side / rear classification of one site-boundary edge. `"street"`
|
|
564
|
+
* never appears — the backend synonym resolves to `front`.
|
|
565
|
+
*/
|
|
566
|
+
export const PluginProgramSiteEdgeRole = z.enum(["front", "side", "rear"])
|
|
567
|
+
export type PluginProgramSiteEdgeRole = z.infer<typeof PluginProgramSiteEdgeRole>
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* One boundary edge of a site parcel, as {@linkcode PluginProgramSiteApi.listEdges}
|
|
571
|
+
* returns it. Coordinates and lengths are world meters.
|
|
572
|
+
*
|
|
573
|
+
* | Property | Type | Description |
|
|
574
|
+
* |---|---|---|
|
|
575
|
+
* | `edgeIndex` | `number` | Index in the canonicalized (sanitized, CCW) boundary — the same index space the envelope's `edgeOverrides` use |
|
|
576
|
+
* | `start` / `end` | `{ x, z }` | Edge endpoints, world XZ meters |
|
|
577
|
+
* | `lengthMeters` | `number` | Edge length in meters |
|
|
578
|
+
* | `role` | `"front" \| "side" \| "rear"` | Resolved classification (user override wins over the heuristic) |
|
|
579
|
+
* | `roleSource` | `"override" \| "heuristic"` | Whether the user reassigned this edge's role or the tangent heuristic classified it |
|
|
580
|
+
* | `setbackMeters` | `number \| null` | Effective base setback (per-edge exception ?? role value); `null` when the parcel has no zoning envelope |
|
|
581
|
+
*/
|
|
582
|
+
export const PluginProgramSiteEdge = z.object({
|
|
583
|
+
edgeIndex: z.number().int().nonnegative(),
|
|
584
|
+
start: z.object({ x: z.number(), z: z.number() }),
|
|
585
|
+
end: z.object({ x: z.number(), z: z.number() }),
|
|
586
|
+
lengthMeters: z.number(),
|
|
587
|
+
role: PluginProgramSiteEdgeRole,
|
|
588
|
+
roleSource: z.enum(["override", "heuristic"]),
|
|
589
|
+
setbackMeters: z.number().nullable(),
|
|
590
|
+
})
|
|
591
|
+
export type PluginProgramSiteEdge = z.infer<typeof PluginProgramSiteEdge>
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Per-parcel entry of {@linkcode PluginProgramSiteApi.listEdges}.
|
|
595
|
+
*
|
|
596
|
+
* | Property | Type | Description |
|
|
597
|
+
* |---|---|---|
|
|
598
|
+
* | `siteId` | `string` | The parcel's component id (same id space as `listPolygons`) |
|
|
599
|
+
* | `buildableEnvelopeId` | `string \| null` | Linked zoning envelope, when one exists |
|
|
600
|
+
* | `usingLiveSiteBoundary` | `boolean` | `true` when edges come from the live site boundary; `false` when only the envelope's persisted source polygon was resolvable |
|
|
601
|
+
* | `staleOverridesDropped` | `boolean` | `true` when persisted edge overrides no longer index-align with the live boundary and were ignored |
|
|
602
|
+
* | `edges` | `PluginProgramSiteEdge[]` | The classified boundary edges |
|
|
603
|
+
*/
|
|
604
|
+
export const PluginProgramSiteEdgesEntry = z.object({
|
|
605
|
+
siteId: z.string(),
|
|
606
|
+
buildableEnvelopeId: z.string().nullable(),
|
|
607
|
+
usingLiveSiteBoundary: z.boolean(),
|
|
608
|
+
staleOverridesDropped: z.boolean(),
|
|
609
|
+
edges: z.array(PluginProgramSiteEdge),
|
|
610
|
+
})
|
|
611
|
+
export type PluginProgramSiteEdgesEntry = z.infer<
|
|
612
|
+
typeof PluginProgramSiteEdgesEntry
|
|
613
|
+
>
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Result of {@linkcode PluginProgramSiteApi.listEdges} — one entry per site
|
|
617
|
+
* parcel; empty when the project has no site. `lengthUnit` is always `"m"`.
|
|
618
|
+
*/
|
|
619
|
+
export const PluginProgramSiteListEdgesResult = z.object({
|
|
620
|
+
lengthUnit: z.literal("m"),
|
|
621
|
+
sites: z.array(PluginProgramSiteEdgesEntry),
|
|
622
|
+
})
|
|
623
|
+
export type PluginProgramSiteListEdgesResult = z.infer<
|
|
624
|
+
typeof PluginProgramSiteListEdgesResult
|
|
625
|
+
>
|
|
@@ -68,6 +68,12 @@ export abstract class PluginProgramSpreadsheetApi {
|
|
|
68
68
|
*/
|
|
69
69
|
public abstract bindings: PluginProgramSpreadsheetBindingsApi
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Plugin datasets — named, plugin-supplied row sets that bindings can render
|
|
73
|
+
* and auto-refresh on rerun. See {@linkcode PluginProgramSpreadsheetDatasetsApi}.
|
|
74
|
+
*/
|
|
75
|
+
public abstract datasets: PluginProgramSpreadsheetDatasetsApi
|
|
76
|
+
|
|
71
77
|
/**
|
|
72
78
|
* Render a titled, formatted table onto a named sheet (create-or-replace).
|
|
73
79
|
*
|
|
@@ -204,6 +210,9 @@ export abstract class PluginProgramSpreadsheetApi {
|
|
|
204
210
|
* single-sheet: it serializes one sheet's used range — pass `options.sheetName`
|
|
205
211
|
* to choose which sheet, or omit it to serialize the active sheet.
|
|
206
212
|
*
|
|
213
|
+
* For a different export intent, see `core.io.export.model` (the 3D model
|
|
214
|
+
* file) and `presentation.export` (Present-mode layout sheets to PDF/PNG/JPG).
|
|
215
|
+
*
|
|
207
216
|
* @param format - The file format to export to.
|
|
208
217
|
* @param options - Optional `fileName` (without extension; a default is used
|
|
209
218
|
* when omitted) and `sheetName` — the sheet to serialize for `csv`
|
|
@@ -315,6 +324,55 @@ export abstract class PluginProgramSpreadsheetApi {
|
|
|
315
324
|
},
|
|
316
325
|
): PluginApiReturn<PluginProgramSpreadsheetAddChartResult>
|
|
317
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Place a floating image on a workbook sheet from a base64 data URI.
|
|
329
|
+
*
|
|
330
|
+
* The image is anchored at a cell's top-left corner (default `"A1"`) and
|
|
331
|
+
* floats over the grid (a SpreadJS floating picture — it does not occupy
|
|
332
|
+
* cells). Only base64 `data:image/png|jpeg|svg+xml` URIs are accepted —
|
|
333
|
+
* never URLs — and the URI is capped at 2 MB. Passing a `name` gives the
|
|
334
|
+
* picture a stable id: re-running with the same `name` replaces the previous
|
|
335
|
+
* picture (rerun-friendly); when omitted a name is generated.
|
|
336
|
+
*
|
|
337
|
+
* For images on Present-mode sheets (the tldraw canvas), use
|
|
338
|
+
* `presentation.shapes` instead — this verb places floating pictures in the
|
|
339
|
+
* SpreadJS workbook.
|
|
340
|
+
*
|
|
341
|
+
* @param sheetName - Sheet to place the image on.
|
|
342
|
+
* @param image - The image payload: a base64 `dataUri`
|
|
343
|
+
* (`data:image/png|jpeg|svg+xml;base64,…`, max 2 MB).
|
|
344
|
+
* @param options - Optional `anchorCell` (A1 notation, default `"A1"`),
|
|
345
|
+
* `size` in px (intrinsic size when omitted), and stable `name`
|
|
346
|
+
* (replace-on-rerun).
|
|
347
|
+
* @returns A {@linkcode PluginProgramSpreadsheetAddImageResult} with the sheet
|
|
348
|
+
* and the picture's name.
|
|
349
|
+
* @throws If the sheet does not exist, or the data URI is not an accepted
|
|
350
|
+
* image type or exceeds 2 MB.
|
|
351
|
+
*
|
|
352
|
+
* @examplePrompt Add my logo image to the report sheet
|
|
353
|
+
* @examplePrompt Place a PNG at cell B2 on the Takeoff sheet
|
|
354
|
+
* @examplePrompt Put an SVG diagram on a spreadsheet sheet
|
|
355
|
+
* @examplePrompt Insert an image into the workbook
|
|
356
|
+
*
|
|
357
|
+
* # Example
|
|
358
|
+
* ```ts
|
|
359
|
+
* const { name } = await snaptrude.program.spreadsheet.addImage(
|
|
360
|
+
* "Report",
|
|
361
|
+
* { dataUri: "data:image/png;base64,iVBORw0..." },
|
|
362
|
+
* { anchorCell: "B2", size: { width: 240, height: 120 }, name: "logo" },
|
|
363
|
+
* )
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
public abstract addImage(
|
|
367
|
+
sheetName: string,
|
|
368
|
+
image: { dataUri: string },
|
|
369
|
+
options?: {
|
|
370
|
+
anchorCell?: string
|
|
371
|
+
size?: { width: number; height: number }
|
|
372
|
+
name?: string
|
|
373
|
+
},
|
|
374
|
+
): PluginApiReturn<PluginProgramSpreadsheetAddImageResult>
|
|
375
|
+
|
|
318
376
|
/**
|
|
319
377
|
* Highlight a range of cells (background color and optional emphasis).
|
|
320
378
|
*
|
|
@@ -911,6 +969,76 @@ export abstract class PluginProgramSpreadsheetBindingsApi {
|
|
|
911
969
|
public abstract list(): PluginApiReturn<PluginProgramSpreadsheetBindingsListResult>
|
|
912
970
|
}
|
|
913
971
|
|
|
972
|
+
/**
|
|
973
|
+
* Program-spreadsheet plugin datasets — named, plugin-supplied row sets stored
|
|
974
|
+
* alongside the workbook so bindings can render and re-render them.
|
|
975
|
+
*
|
|
976
|
+
* A dataset is uploaded with {@linkcode PluginProgramSpreadsheetDatasetsApi.set}
|
|
977
|
+
* (upsert by name). A binding whose source is `{ dataset: "plugin", name }`
|
|
978
|
+
* renders the dataset at its target anchor, and re-renders automatically every
|
|
979
|
+
* time the dataset is set again — the "refresh on rerun" behaviour. Accessed
|
|
980
|
+
* via `snaptrude.program.spreadsheet.datasets`.
|
|
981
|
+
*/
|
|
982
|
+
export abstract class PluginProgramSpreadsheetDatasetsApi {
|
|
983
|
+
constructor() {}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Store (upsert) a named plugin dataset.
|
|
987
|
+
*
|
|
988
|
+
* Re-using a `name` replaces the dataset and automatically refreshes every
|
|
989
|
+
* binding whose source is `{ dataset: "plugin", name }` — no extra plugin
|
|
990
|
+
* calls needed to keep bound ranges current. Limits: at most 10,000 rows and
|
|
991
|
+
* 2 MB serialized.
|
|
992
|
+
*
|
|
993
|
+
* @param name - Dataset name (re-using a name overwrites it).
|
|
994
|
+
* @param columns - Column definitions (see {@linkcode PluginSpreadsheetColumn});
|
|
995
|
+
* their order is the column order bindings render.
|
|
996
|
+
* @param rows - Row objects keyed by column `key`.
|
|
997
|
+
* @returns A {@linkcode PluginProgramSpreadsheetDatasetsSetResult} with the
|
|
998
|
+
* stored row count.
|
|
999
|
+
* @throws If the dataset exceeds 10,000 rows or 2 MB serialized.
|
|
1000
|
+
*
|
|
1001
|
+
* @examplePrompt Store my plugin's rows as a named dataset
|
|
1002
|
+
* @examplePrompt Upload data the sheets can bind to and refresh
|
|
1003
|
+
* @examplePrompt Save a dataset for a live sheet binding
|
|
1004
|
+
* @examplePrompt Push my computed table so a binding keeps it fresh
|
|
1005
|
+
*
|
|
1006
|
+
* # Example
|
|
1007
|
+
* ```ts
|
|
1008
|
+
* await snaptrude.program.spreadsheet.datasets.set(
|
|
1009
|
+
* "costs",
|
|
1010
|
+
* [
|
|
1011
|
+
* { key: "item", header: "Item" },
|
|
1012
|
+
* { key: "cost", header: "Cost", align: "right" },
|
|
1013
|
+
* ],
|
|
1014
|
+
* [{ item: "Concrete", cost: 120 }],
|
|
1015
|
+
* )
|
|
1016
|
+
* ```
|
|
1017
|
+
*/
|
|
1018
|
+
public abstract set(
|
|
1019
|
+
name: string,
|
|
1020
|
+
columns: PluginSpreadsheetColumn[],
|
|
1021
|
+
rows: Record<string, PluginSpreadsheetCell>[],
|
|
1022
|
+
): PluginApiReturn<PluginProgramSpreadsheetDatasetsSetResult>
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* List the stored plugin datasets.
|
|
1026
|
+
*
|
|
1027
|
+
* @returns A {@linkcode PluginProgramSpreadsheetDatasetsListResult} with each
|
|
1028
|
+
* dataset's `name`, `rowCount`, and `updatedAt` timestamp.
|
|
1029
|
+
*
|
|
1030
|
+
* @examplePrompt List my plugin datasets
|
|
1031
|
+
* @examplePrompt What datasets are stored for the sheets?
|
|
1032
|
+
* @examplePrompt Show the data sets bindings can use
|
|
1033
|
+
*
|
|
1034
|
+
* # Example
|
|
1035
|
+
* ```ts
|
|
1036
|
+
* const { datasets } = await snaptrude.program.spreadsheet.datasets.list()
|
|
1037
|
+
* ```
|
|
1038
|
+
*/
|
|
1039
|
+
public abstract list(): PluginApiReturn<PluginProgramSpreadsheetDatasetsListResult>
|
|
1040
|
+
}
|
|
1041
|
+
|
|
914
1042
|
/** A single spreadsheet cell value. */
|
|
915
1043
|
export const PluginSpreadsheetCell = z.union([
|
|
916
1044
|
z.string(),
|
|
@@ -2011,16 +2139,18 @@ export type PluginProgramSpreadsheetTemplatesApplyResult = z.infer<
|
|
|
2011
2139
|
// --- bindings.* ------------------------------------------------------------
|
|
2012
2140
|
|
|
2013
2141
|
/**
|
|
2014
|
-
* A binding's data source
|
|
2015
|
-
*
|
|
2142
|
+
* A binding's data source — the built-in takeoff dataset, or a named plugin
|
|
2143
|
+
* dataset stored via {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
|
|
2016
2144
|
*
|
|
2017
2145
|
* | Property | Type | Description |
|
|
2018
2146
|
* |---|---|---|
|
|
2019
|
-
* | `dataset` | `"takeoff"` | The dataset the binding pulls from |
|
|
2147
|
+
* | `dataset` | `"takeoff" \| "plugin"` | The dataset kind the binding pulls from |
|
|
2148
|
+
* | `name` | `string` | (`"plugin"` only) The stored dataset's name |
|
|
2020
2149
|
*/
|
|
2021
|
-
export const PluginSpreadsheetBindingSource = z.
|
|
2022
|
-
dataset: z.
|
|
2023
|
-
})
|
|
2150
|
+
export const PluginSpreadsheetBindingSource = z.discriminatedUnion("dataset", [
|
|
2151
|
+
z.object({ dataset: z.literal("takeoff") }),
|
|
2152
|
+
z.object({ dataset: z.literal("plugin"), name: z.string() }),
|
|
2153
|
+
])
|
|
2024
2154
|
export type PluginSpreadsheetBindingSource = z.infer<
|
|
2025
2155
|
typeof PluginSpreadsheetBindingSource
|
|
2026
2156
|
>
|
|
@@ -2169,3 +2299,118 @@ export const PluginProgramSpreadsheetBindingsListResult = z.object({
|
|
|
2169
2299
|
export type PluginProgramSpreadsheetBindingsListResult = z.infer<
|
|
2170
2300
|
typeof PluginProgramSpreadsheetBindingsListResult
|
|
2171
2301
|
>
|
|
2302
|
+
|
|
2303
|
+
// --- datasets.* ------------------------------------------------------------
|
|
2304
|
+
|
|
2305
|
+
/**
|
|
2306
|
+
* Arguments for {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
|
|
2307
|
+
*
|
|
2308
|
+
* | Property | Type | Description |
|
|
2309
|
+
* |---|---|---|
|
|
2310
|
+
* | `name` | `string` | Dataset name (re-using a name overwrites it) |
|
|
2311
|
+
* | `columns` | {@linkcode PluginSpreadsheetColumn}`[]` | Column definitions (at least one) |
|
|
2312
|
+
* | `rows` | `Record<string, cell>[]` | Row objects keyed by column `key` (max 10,000) |
|
|
2313
|
+
*/
|
|
2314
|
+
export const PluginProgramSpreadsheetDatasetsSetArgs = z.object({
|
|
2315
|
+
name: z.string(),
|
|
2316
|
+
columns: z.array(PluginSpreadsheetColumn).min(1),
|
|
2317
|
+
rows: z.array(z.record(z.string(), PluginSpreadsheetCell)).max(10_000),
|
|
2318
|
+
})
|
|
2319
|
+
export type PluginProgramSpreadsheetDatasetsSetArgs = z.infer<
|
|
2320
|
+
typeof PluginProgramSpreadsheetDatasetsSetArgs
|
|
2321
|
+
>
|
|
2322
|
+
|
|
2323
|
+
/**
|
|
2324
|
+
* Result of {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
|
|
2325
|
+
*
|
|
2326
|
+
* | Property | Type | Description |
|
|
2327
|
+
* |---|---|---|
|
|
2328
|
+
* | `name` | `string` | The stored dataset's name |
|
|
2329
|
+
* | `rowCount` | `number` | Number of rows stored |
|
|
2330
|
+
*/
|
|
2331
|
+
export const PluginProgramSpreadsheetDatasetsSetResult = z.object({
|
|
2332
|
+
name: z.string(),
|
|
2333
|
+
rowCount: z.number(),
|
|
2334
|
+
})
|
|
2335
|
+
export type PluginProgramSpreadsheetDatasetsSetResult = z.infer<
|
|
2336
|
+
typeof PluginProgramSpreadsheetDatasetsSetResult
|
|
2337
|
+
>
|
|
2338
|
+
|
|
2339
|
+
/**
|
|
2340
|
+
* A stored plugin dataset's summary, for
|
|
2341
|
+
* {@linkcode PluginProgramSpreadsheetDatasetsApi.list}.
|
|
2342
|
+
*
|
|
2343
|
+
* | Property | Type | Description |
|
|
2344
|
+
* |---|---|---|
|
|
2345
|
+
* | `name` | `string` | Dataset name |
|
|
2346
|
+
* | `rowCount` | `number` | Number of rows stored |
|
|
2347
|
+
* | `updatedAt` | `string` | ISO timestamp of the last `set` |
|
|
2348
|
+
*/
|
|
2349
|
+
export const PluginSpreadsheetDataset = z.object({
|
|
2350
|
+
name: z.string(),
|
|
2351
|
+
rowCount: z.number(),
|
|
2352
|
+
updatedAt: z.string(),
|
|
2353
|
+
})
|
|
2354
|
+
export type PluginSpreadsheetDataset = z.infer<typeof PluginSpreadsheetDataset>
|
|
2355
|
+
|
|
2356
|
+
/**
|
|
2357
|
+
* Result of {@linkcode PluginProgramSpreadsheetDatasetsApi.list}.
|
|
2358
|
+
*
|
|
2359
|
+
* | Property | Type | Description |
|
|
2360
|
+
* |---|---|---|
|
|
2361
|
+
* | `datasets` | {@linkcode PluginSpreadsheetDataset}`[]` | Every stored dataset |
|
|
2362
|
+
*/
|
|
2363
|
+
export const PluginProgramSpreadsheetDatasetsListResult = z.object({
|
|
2364
|
+
datasets: z.array(PluginSpreadsheetDataset),
|
|
2365
|
+
})
|
|
2366
|
+
export type PluginProgramSpreadsheetDatasetsListResult = z.infer<
|
|
2367
|
+
typeof PluginProgramSpreadsheetDatasetsListResult
|
|
2368
|
+
>
|
|
2369
|
+
|
|
2370
|
+
// --- addImage --------------------------------------------------------------
|
|
2371
|
+
|
|
2372
|
+
/**
|
|
2373
|
+
* Arguments for {@linkcode PluginProgramSpreadsheetApi.addImage}.
|
|
2374
|
+
*
|
|
2375
|
+
* | Property | Type | Description |
|
|
2376
|
+
* |---|---|---|
|
|
2377
|
+
* | `sheetName` | `string` | Sheet to place the image on |
|
|
2378
|
+
* | `image` | `{ dataUri: string }` | Base64 `data:image/png\|jpeg\|svg+xml` URI (max 2 MB; URLs rejected) |
|
|
2379
|
+
* | `anchorCell` | `string?` | Anchor cell in A1 notation (default `"A1"`) |
|
|
2380
|
+
* | `size` | `{ width; height }?` | Size in px; intrinsic size when omitted |
|
|
2381
|
+
* | `name` | `string?` | Stable picture id — same name replaces on rerun; generated when omitted |
|
|
2382
|
+
*/
|
|
2383
|
+
export const PluginProgramSpreadsheetAddImageArgs = z.object({
|
|
2384
|
+
sheetName: z.string(),
|
|
2385
|
+
image: z.object({
|
|
2386
|
+
dataUri: z
|
|
2387
|
+
.string()
|
|
2388
|
+
.max(2_097_152, "image.dataUri exceeds the 2 MB limit")
|
|
2389
|
+
.regex(
|
|
2390
|
+
/^data:image\/(png|jpeg|svg\+xml);base64,/,
|
|
2391
|
+
"image.dataUri must be a base64 data:image/png, jpeg, or svg+xml URI",
|
|
2392
|
+
),
|
|
2393
|
+
}),
|
|
2394
|
+
anchorCell: z.string().optional(),
|
|
2395
|
+
size: z.object({ width: z.number(), height: z.number() }).optional(),
|
|
2396
|
+
name: z.string().optional(),
|
|
2397
|
+
})
|
|
2398
|
+
export type PluginProgramSpreadsheetAddImageArgs = z.infer<
|
|
2399
|
+
typeof PluginProgramSpreadsheetAddImageArgs
|
|
2400
|
+
>
|
|
2401
|
+
|
|
2402
|
+
/**
|
|
2403
|
+
* Result of {@linkcode PluginProgramSpreadsheetApi.addImage}.
|
|
2404
|
+
*
|
|
2405
|
+
* | Property | Type | Description |
|
|
2406
|
+
* |---|---|---|
|
|
2407
|
+
* | `sheetName` | `string` | The sheet the image was placed on |
|
|
2408
|
+
* | `name` | `string` | The picture's (stable or generated) name |
|
|
2409
|
+
*/
|
|
2410
|
+
export const PluginProgramSpreadsheetAddImageResult = z.object({
|
|
2411
|
+
sheetName: z.string(),
|
|
2412
|
+
name: z.string(),
|
|
2413
|
+
})
|
|
2414
|
+
export type PluginProgramSpreadsheetAddImageResult = z.infer<
|
|
2415
|
+
typeof PluginProgramSpreadsheetAddImageResult
|
|
2416
|
+
>
|