@snaptrude/plugin-core 0.0.0-bimsvg-20260928124803

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/AGENTS.md +231 -0
  2. package/CHANGELOG.md +341 -0
  3. package/CLAUDE.md +11 -0
  4. package/api-manifest.json +9120 -0
  5. package/dist/api/analysis/daylight.d.ts +603 -0
  6. package/dist/api/analysis/daylight.d.ts.map +1 -0
  7. package/dist/api/analysis/heatmaps.d.ts +658 -0
  8. package/dist/api/analysis/heatmaps.d.ts.map +1 -0
  9. package/dist/api/analysis/illuminance.d.ts +145 -0
  10. package/dist/api/analysis/illuminance.d.ts.map +1 -0
  11. package/dist/api/analysis/index.d.ts +59 -0
  12. package/dist/api/analysis/index.d.ts.map +1 -0
  13. package/dist/api/analysis/shadows.d.ts +165 -0
  14. package/dist/api/analysis/shadows.d.ts.map +1 -0
  15. package/dist/api/analysis/solar.d.ts +249 -0
  16. package/dist/api/analysis/solar.d.ts.map +1 -0
  17. package/dist/api/analysis/sunlightHours.d.ts +208 -0
  18. package/dist/api/analysis/sunlightHours.d.ts.map +1 -0
  19. package/dist/api/analysis/sunpath.d.ts +80 -0
  20. package/dist/api/analysis/sunpath.d.ts.map +1 -0
  21. package/dist/api/analysis/weather.d.ts +193 -0
  22. package/dist/api/analysis/weather.d.ts.map +1 -0
  23. package/dist/api/core/buildings.d.ts +427 -0
  24. package/dist/api/core/buildings.d.ts.map +1 -0
  25. package/dist/api/core/camera/index.d.ts +261 -0
  26. package/dist/api/core/camera/index.d.ts.map +1 -0
  27. package/dist/api/core/comment/index.d.ts +333 -0
  28. package/dist/api/core/comment/index.d.ts.map +1 -0
  29. package/dist/api/core/geom/create/index.d.ts +1073 -0
  30. package/dist/api/core/geom/create/index.d.ts.map +1 -0
  31. package/dist/api/core/geom/delete/index.d.ts +78 -0
  32. package/dist/api/core/geom/delete/index.d.ts.map +1 -0
  33. package/dist/api/core/geom/index.d.ts +33 -0
  34. package/dist/api/core/geom/index.d.ts.map +1 -0
  35. package/dist/api/core/geom/query/arc.d.ts +169 -0
  36. package/dist/api/core/geom/query/arc.d.ts.map +1 -0
  37. package/dist/api/core/geom/query/brep.d.ts +514 -0
  38. package/dist/api/core/geom/query/brep.d.ts.map +1 -0
  39. package/dist/api/core/geom/query/circle.d.ts +378 -0
  40. package/dist/api/core/geom/query/circle.d.ts.map +1 -0
  41. package/dist/api/core/geom/query/contour.d.ts +450 -0
  42. package/dist/api/core/geom/query/contour.d.ts.map +1 -0
  43. package/dist/api/core/geom/query/curve.d.ts +918 -0
  44. package/dist/api/core/geom/query/curve.d.ts.map +1 -0
  45. package/dist/api/core/geom/query/edge.d.ts +128 -0
  46. package/dist/api/core/geom/query/edge.d.ts.map +1 -0
  47. package/dist/api/core/geom/query/face.d.ts +363 -0
  48. package/dist/api/core/geom/query/face.d.ts.map +1 -0
  49. package/dist/api/core/geom/query/halfedge.d.ts +206 -0
  50. package/dist/api/core/geom/query/halfedge.d.ts.map +1 -0
  51. package/dist/api/core/geom/query/index.d.ts +61 -0
  52. package/dist/api/core/geom/query/index.d.ts.map +1 -0
  53. package/dist/api/core/geom/query/profile.d.ts +410 -0
  54. package/dist/api/core/geom/query/profile.d.ts.map +1 -0
  55. package/dist/api/core/geom/query/vertex.d.ts +187 -0
  56. package/dist/api/core/geom/query/vertex.d.ts.map +1 -0
  57. package/dist/api/core/geom/update/contour.d.ts +272 -0
  58. package/dist/api/core/geom/update/contour.d.ts.map +1 -0
  59. package/dist/api/core/geom/update/curve.d.ts +180 -0
  60. package/dist/api/core/geom/update/curve.d.ts.map +1 -0
  61. package/dist/api/core/geom/update/index.d.ts +27 -0
  62. package/dist/api/core/geom/update/index.d.ts.map +1 -0
  63. package/dist/api/core/geom/update/profile.d.ts +329 -0
  64. package/dist/api/core/geom/update/profile.d.ts.map +1 -0
  65. package/dist/api/core/groups.d.ts +485 -0
  66. package/dist/api/core/groups.d.ts.map +1 -0
  67. package/dist/api/core/handles/index.d.ts +210 -0
  68. package/dist/api/core/handles/index.d.ts.map +1 -0
  69. package/dist/api/core/history/index.d.ts +78 -0
  70. package/dist/api/core/history/index.d.ts.map +1 -0
  71. package/dist/api/core/index.d.ts +97 -0
  72. package/dist/api/core/index.d.ts.map +1 -0
  73. package/dist/api/core/io/export/index.d.ts +134 -0
  74. package/dist/api/core/io/export/index.d.ts.map +1 -0
  75. package/dist/api/core/io/import/index.d.ts +455 -0
  76. package/dist/api/core/io/import/index.d.ts.map +1 -0
  77. package/dist/api/core/io/index.d.ts +40 -0
  78. package/dist/api/core/io/index.d.ts.map +1 -0
  79. package/dist/api/core/io/job/index.d.ts +139 -0
  80. package/dist/api/core/io/job/index.d.ts.map +1 -0
  81. package/dist/api/core/io/query/index.d.ts +74 -0
  82. package/dist/api/core/io/query/index.d.ts.map +1 -0
  83. package/dist/api/core/io/terrain/index.d.ts +341 -0
  84. package/dist/api/core/io/terrain/index.d.ts.map +1 -0
  85. package/dist/api/core/io/underlay/index.d.ts +805 -0
  86. package/dist/api/core/io/underlay/index.d.ts.map +1 -0
  87. package/dist/api/core/layers.d.ts +402 -0
  88. package/dist/api/core/layers.d.ts.map +1 -0
  89. package/dist/api/core/math/index.d.ts +18 -0
  90. package/dist/api/core/math/index.d.ts.map +1 -0
  91. package/dist/api/core/math/quat.d.ts +170 -0
  92. package/dist/api/core/math/quat.d.ts.map +1 -0
  93. package/dist/api/core/math/vec3.d.ts +174 -0
  94. package/dist/api/core/math/vec3.d.ts.map +1 -0
  95. package/dist/api/core/mode/index.d.ts +111 -0
  96. package/dist/api/core/mode/index.d.ts.map +1 -0
  97. package/dist/api/core/project/index.d.ts +466 -0
  98. package/dist/api/core/project/index.d.ts.map +1 -0
  99. package/dist/api/core/proposals/index.d.ts +531 -0
  100. package/dist/api/core/proposals/index.d.ts.map +1 -0
  101. package/dist/api/core/storeys/index.d.ts +265 -0
  102. package/dist/api/core/storeys/index.d.ts.map +1 -0
  103. package/dist/api/core/tags.d.ts +860 -0
  104. package/dist/api/core/tags.d.ts.map +1 -0
  105. package/dist/api/core/units/index.d.ts +175 -0
  106. package/dist/api/core/units/index.d.ts.map +1 -0
  107. package/dist/api/core/user.d.ts +44 -0
  108. package/dist/api/core/user.d.ts.map +1 -0
  109. package/dist/api/core/zoom/index.d.ts +49 -0
  110. package/dist/api/core/zoom/index.d.ts.map +1 -0
  111. package/dist/api/design/boolean/index.d.ts +168 -0
  112. package/dist/api/design/boolean/index.d.ts.map +1 -0
  113. package/dist/api/design/create/bulk-items.d.ts +185 -0
  114. package/dist/api/design/create/bulk-items.d.ts.map +1 -0
  115. package/dist/api/design/create/grids.d.ts +132 -0
  116. package/dist/api/design/create/grids.d.ts.map +1 -0
  117. package/dist/api/design/create/index.d.ts +1747 -0
  118. package/dist/api/design/create/index.d.ts.map +1 -0
  119. package/dist/api/design/create/opening-fields.d.ts +37 -0
  120. package/dist/api/design/create/opening-fields.d.ts.map +1 -0
  121. package/dist/api/design/delete/index.d.ts +70 -0
  122. package/dist/api/design/delete/index.d.ts.map +1 -0
  123. package/dist/api/design/dimensions.d.ts +427 -0
  124. package/dist/api/design/dimensions.d.ts.map +1 -0
  125. package/dist/api/design/doors/index.d.ts +470 -0
  126. package/dist/api/design/doors/index.d.ts.map +1 -0
  127. package/dist/api/design/edit/index.d.ts +49 -0
  128. package/dist/api/design/edit/index.d.ts.map +1 -0
  129. package/dist/api/design/erase/index.d.ts +160 -0
  130. package/dist/api/design/erase/index.d.ts.map +1 -0
  131. package/dist/api/design/family.d.ts +611 -0
  132. package/dist/api/design/family.d.ts.map +1 -0
  133. package/dist/api/design/furniture/index.d.ts +296 -0
  134. package/dist/api/design/furniture/index.d.ts.map +1 -0
  135. package/dist/api/design/grids.d.ts +237 -0
  136. package/dist/api/design/grids.d.ts.map +1 -0
  137. package/dist/api/design/index.d.ts +260 -0
  138. package/dist/api/design/index.d.ts.map +1 -0
  139. package/dist/api/design/lock.d.ts +67 -0
  140. package/dist/api/design/lock.d.ts.map +1 -0
  141. package/dist/api/design/materials/index.d.ts +551 -0
  142. package/dist/api/design/materials/index.d.ts.map +1 -0
  143. package/dist/api/design/query/geometry/index.d.ts +252 -0
  144. package/dist/api/design/query/geometry/index.d.ts.map +1 -0
  145. package/dist/api/design/query/grids.d.ts +287 -0
  146. package/dist/api/design/query/grids.d.ts.map +1 -0
  147. package/dist/api/design/query/index.d.ts +1318 -0
  148. package/dist/api/design/query/index.d.ts.map +1 -0
  149. package/dist/api/design/query/referenceLines.d.ts +45 -0
  150. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  151. package/dist/api/design/query/spaces.d.ts +394 -0
  152. package/dist/api/design/query/spaces.d.ts.map +1 -0
  153. package/dist/api/design/selection/index.d.ts +282 -0
  154. package/dist/api/design/selection/index.d.ts.map +1 -0
  155. package/dist/api/design/shared.d.ts +38 -0
  156. package/dist/api/design/shared.d.ts.map +1 -0
  157. package/dist/api/design/transform/index.d.ts +249 -0
  158. package/dist/api/design/transform/index.d.ts.map +1 -0
  159. package/dist/api/design/types/index.d.ts +181 -0
  160. package/dist/api/design/types/index.d.ts.map +1 -0
  161. package/dist/api/design/update/index.d.ts +803 -0
  162. package/dist/api/design/update/index.d.ts.map +1 -0
  163. package/dist/api/design/visibility.d.ts +126 -0
  164. package/dist/api/design/visibility.d.ts.map +1 -0
  165. package/dist/api/design/windows/index.d.ts +300 -0
  166. package/dist/api/design/windows/index.d.ts.map +1 -0
  167. package/dist/api/entity/buildableEnvelope.d.ts +265 -0
  168. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -0
  169. package/dist/api/entity/department.d.ts +1 -0
  170. package/dist/api/entity/department.d.ts.map +1 -0
  171. package/dist/api/entity/index.d.ts +28 -0
  172. package/dist/api/entity/index.d.ts.map +1 -0
  173. package/dist/api/entity/referenceLine.d.ts +210 -0
  174. package/dist/api/entity/referenceLine.d.ts.map +1 -0
  175. package/dist/api/entity/space.d.ts +846 -0
  176. package/dist/api/entity/space.d.ts.map +1 -0
  177. package/dist/api/entity/story.d.ts +476 -0
  178. package/dist/api/entity/story.d.ts.map +1 -0
  179. package/dist/api/index.d.ts +45 -0
  180. package/dist/api/index.d.ts.map +1 -0
  181. package/dist/api/presentation/aiInspiration.d.ts +2400 -0
  182. package/dist/api/presentation/aiInspiration.d.ts.map +1 -0
  183. package/dist/api/presentation/annotate.d.ts +483 -0
  184. package/dist/api/presentation/annotate.d.ts.map +1 -0
  185. package/dist/api/presentation/diagrams.d.ts +184 -0
  186. package/dist/api/presentation/diagrams.d.ts.map +1 -0
  187. package/dist/api/presentation/drawings.d.ts +2900 -0
  188. package/dist/api/presentation/drawings.d.ts.map +1 -0
  189. package/dist/api/presentation/export.d.ts +126 -0
  190. package/dist/api/presentation/export.d.ts.map +1 -0
  191. package/dist/api/presentation/import.d.ts +164 -0
  192. package/dist/api/presentation/import.d.ts.map +1 -0
  193. package/dist/api/presentation/index.d.ts +114 -0
  194. package/dist/api/presentation/index.d.ts.map +1 -0
  195. package/dist/api/presentation/placedViews.d.ts +1232 -0
  196. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  197. package/dist/api/presentation/shapes.d.ts +481 -0
  198. package/dist/api/presentation/shapes.d.ts.map +1 -0
  199. package/dist/api/presentation/sheets.d.ts +643 -0
  200. package/dist/api/presentation/sheets.d.ts.map +1 -0
  201. package/dist/api/presentation/slideshow.d.ts +125 -0
  202. package/dist/api/presentation/slideshow.d.ts.map +1 -0
  203. package/dist/api/presentation/tables.d.ts +81 -0
  204. package/dist/api/presentation/tables.d.ts.map +1 -0
  205. package/dist/api/presentation/viewPresets.d.ts +70 -0
  206. package/dist/api/presentation/viewPresets.d.ts.map +1 -0
  207. package/dist/api/presentation/views.d.ts +741 -0
  208. package/dist/api/presentation/views.d.ts.map +1 -0
  209. package/dist/api/program/adjacency.d.ts +155 -0
  210. package/dist/api/program/adjacency.d.ts.map +1 -0
  211. package/dist/api/program/areas.d.ts +450 -0
  212. package/dist/api/program/areas.d.ts.map +1 -0
  213. package/dist/api/program/classification.d.ts +135 -0
  214. package/dist/api/program/classification.d.ts.map +1 -0
  215. package/dist/api/program/cores.d.ts +78 -0
  216. package/dist/api/program/cores.d.ts.map +1 -0
  217. package/dist/api/program/departments.d.ts +487 -0
  218. package/dist/api/program/departments.d.ts.map +1 -0
  219. package/dist/api/program/index.d.ts +71 -0
  220. package/dist/api/program/index.d.ts.map +1 -0
  221. package/dist/api/program/labels.d.ts +355 -0
  222. package/dist/api/program/labels.d.ts.map +1 -0
  223. package/dist/api/program/layout.d.ts +398 -0
  224. package/dist/api/program/layout.d.ts.map +1 -0
  225. package/dist/api/program/metadata.d.ts +328 -0
  226. package/dist/api/program/metadata.d.ts.map +1 -0
  227. package/dist/api/program/metrics.d.ts +108 -0
  228. package/dist/api/program/metrics.d.ts.map +1 -0
  229. package/dist/api/program/site.d.ts +823 -0
  230. package/dist/api/program/site.d.ts.map +1 -0
  231. package/dist/api/program/spreadsheet.d.ts +2628 -0
  232. package/dist/api/program/spreadsheet.d.ts.map +1 -0
  233. package/dist/api/workspace/index.d.ts +552 -0
  234. package/dist/api/workspace/index.d.ts.map +1 -0
  235. package/dist/errors/codes.d.ts +34 -0
  236. package/dist/errors/codes.d.ts.map +1 -0
  237. package/dist/errors/envelope.d.ts +56 -0
  238. package/dist/errors/envelope.d.ts.map +1 -0
  239. package/dist/errors/index.d.ts +6 -0
  240. package/dist/errors/index.d.ts.map +1 -0
  241. package/dist/errors/plugin-error.d.ts +69 -0
  242. package/dist/errors/plugin-error.d.ts.map +1 -0
  243. package/dist/handles.d.ts +229 -0
  244. package/dist/handles.d.ts.map +1 -0
  245. package/dist/host-utils.d.ts +47 -0
  246. package/dist/host-utils.d.ts.map +1 -0
  247. package/dist/index.cjs +8836 -0
  248. package/dist/index.cjs.map +1 -0
  249. package/dist/index.d.ts +6 -0
  250. package/dist/index.d.ts.map +1 -0
  251. package/dist/index.js +7568 -0
  252. package/dist/index.js.map +1 -0
  253. package/dist/types.d.ts +16 -0
  254. package/dist/types.d.ts.map +1 -0
  255. package/package.json +41 -0
  256. package/scripts/generate-manifest.mjs +238 -0
  257. package/scripts/generate-manifest.test.mjs +292 -0
  258. package/src/api/analysis/daylight.ts +470 -0
  259. package/src/api/analysis/heatmaps.ts +683 -0
  260. package/src/api/analysis/illuminance.ts +155 -0
  261. package/src/api/analysis/index.ts +61 -0
  262. package/src/api/analysis/shadows.ts +183 -0
  263. package/src/api/analysis/solar.ts +237 -0
  264. package/src/api/analysis/sunlightHours.ts +211 -0
  265. package/src/api/analysis/sunpath.ts +83 -0
  266. package/src/api/analysis/weather.ts +179 -0
  267. package/src/api/core/buildings.ts +485 -0
  268. package/src/api/core/camera/index.ts +268 -0
  269. package/src/api/core/comment/index.ts +376 -0
  270. package/src/api/core/geom/create/index.ts +1204 -0
  271. package/src/api/core/geom/delete/index.ts +84 -0
  272. package/src/api/core/geom/index.ts +35 -0
  273. package/src/api/core/geom/query/arc.ts +169 -0
  274. package/src/api/core/geom/query/brep.ts +563 -0
  275. package/src/api/core/geom/query/circle.ts +404 -0
  276. package/src/api/core/geom/query/contour.ts +540 -0
  277. package/src/api/core/geom/query/curve.ts +1078 -0
  278. package/src/api/core/geom/query/edge.ts +130 -0
  279. package/src/api/core/geom/query/face.ts +403 -0
  280. package/src/api/core/geom/query/halfedge.ts +210 -0
  281. package/src/api/core/geom/query/index.ts +63 -0
  282. package/src/api/core/geom/query/profile.ts +473 -0
  283. package/src/api/core/geom/query/vertex.ts +205 -0
  284. package/src/api/core/geom/update/contour.ts +315 -0
  285. package/src/api/core/geom/update/curve.ts +209 -0
  286. package/src/api/core/geom/update/index.ts +29 -0
  287. package/src/api/core/geom/update/profile.ts +377 -0
  288. package/src/api/core/groups.ts +521 -0
  289. package/src/api/core/handles/index.ts +233 -0
  290. package/src/api/core/history/index.ts +84 -0
  291. package/src/api/core/index.ts +99 -0
  292. package/src/api/core/io/export/index.ts +126 -0
  293. package/src/api/core/io/import/index.ts +504 -0
  294. package/src/api/core/io/index.ts +42 -0
  295. package/src/api/core/io/job/index.ts +140 -0
  296. package/src/api/core/io/query/index.ts +71 -0
  297. package/src/api/core/io/terrain/index.ts +360 -0
  298. package/src/api/core/io/underlay/index.ts +705 -0
  299. package/src/api/core/layers.ts +333 -0
  300. package/src/api/core/math/index.ts +20 -0
  301. package/src/api/core/math/quat.ts +172 -0
  302. package/src/api/core/math/vec3.ts +179 -0
  303. package/src/api/core/mode/index.ts +108 -0
  304. package/src/api/core/project/index.ts +479 -0
  305. package/src/api/core/proposals/index.ts +569 -0
  306. package/src/api/core/storeys/index.ts +294 -0
  307. package/src/api/core/tags.ts +911 -0
  308. package/src/api/core/units/index.ts +164 -0
  309. package/src/api/core/user.ts +46 -0
  310. package/src/api/core/zoom/index.ts +51 -0
  311. package/src/api/design/boolean/index.ts +179 -0
  312. package/src/api/design/create/bulk-items.ts +186 -0
  313. package/src/api/design/create/grids.ts +137 -0
  314. package/src/api/design/create/index.ts +1954 -0
  315. package/src/api/design/create/opening-fields.ts +37 -0
  316. package/src/api/design/delete/index.ts +74 -0
  317. package/src/api/design/dimensions.ts +453 -0
  318. package/src/api/design/doors/index.ts +500 -0
  319. package/src/api/design/edit/index.ts +54 -0
  320. package/src/api/design/erase/index.ts +151 -0
  321. package/src/api/design/family.ts +646 -0
  322. package/src/api/design/furniture/index.ts +319 -0
  323. package/src/api/design/grids.ts +237 -0
  324. package/src/api/design/index.ts +274 -0
  325. package/src/api/design/lock.ts +69 -0
  326. package/src/api/design/materials/index.ts +608 -0
  327. package/src/api/design/query/geometry/index.ts +288 -0
  328. package/src/api/design/query/grids.ts +197 -0
  329. package/src/api/design/query/index.ts +1176 -0
  330. package/src/api/design/query/referenceLines.ts +52 -0
  331. package/src/api/design/query/spaces.ts +275 -0
  332. package/src/api/design/selection/index.ts +273 -0
  333. package/src/api/design/shared.ts +40 -0
  334. package/src/api/design/transform/index.ts +254 -0
  335. package/src/api/design/types/index.ts +156 -0
  336. package/src/api/design/update/index.ts +798 -0
  337. package/src/api/design/visibility.ts +143 -0
  338. package/src/api/design/windows/index.ts +333 -0
  339. package/src/api/entity/buildableEnvelope.ts +322 -0
  340. package/src/api/entity/department.ts +0 -0
  341. package/src/api/entity/index.ts +30 -0
  342. package/src/api/entity/referenceLine.ts +235 -0
  343. package/src/api/entity/space.ts +612 -0
  344. package/src/api/entity/story.ts +517 -0
  345. package/src/api/index.ts +47 -0
  346. package/src/api/presentation/aiInspiration.ts +1116 -0
  347. package/src/api/presentation/annotate.ts +417 -0
  348. package/src/api/presentation/diagrams.ts +194 -0
  349. package/src/api/presentation/drawings.ts +529 -0
  350. package/src/api/presentation/export.ts +133 -0
  351. package/src/api/presentation/import.ts +159 -0
  352. package/src/api/presentation/index.ts +129 -0
  353. package/src/api/presentation/placedViews.ts +1203 -0
  354. package/src/api/presentation/shapes.ts +274 -0
  355. package/src/api/presentation/sheets.ts +616 -0
  356. package/src/api/presentation/slideshow.ts +134 -0
  357. package/src/api/presentation/tables.ts +84 -0
  358. package/src/api/presentation/viewPresets.ts +83 -0
  359. package/src/api/presentation/views.ts +698 -0
  360. package/src/api/program/adjacency.ts +164 -0
  361. package/src/api/program/areas.ts +408 -0
  362. package/src/api/program/classification.ts +138 -0
  363. package/src/api/program/cores.ts +83 -0
  364. package/src/api/program/departments.ts +517 -0
  365. package/src/api/program/index.ts +73 -0
  366. package/src/api/program/labels.ts +332 -0
  367. package/src/api/program/layout.ts +422 -0
  368. package/src/api/program/metadata.ts +364 -0
  369. package/src/api/program/metrics.ts +120 -0
  370. package/src/api/program/site.ts +748 -0
  371. package/src/api/program/spreadsheet.ts +2698 -0
  372. package/src/api/workspace/index.ts +612 -0
  373. package/src/errors/codes.ts +136 -0
  374. package/src/errors/envelope.ts +75 -0
  375. package/src/errors/index.ts +21 -0
  376. package/src/errors/plugin-error.ts +134 -0
  377. package/src/handles.ts +282 -0
  378. package/src/host-utils.ts +68 -0
  379. package/src/index.ts +5 -0
  380. package/src/types.ts +16 -0
  381. package/test/errors.test.mjs +184 -0
  382. package/tsconfig.json +22 -0
  383. package/tsup.config.ts +12 -0
@@ -0,0 +1,2698 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import { PluginAreaUnit } from "./metrics"
4
+
5
+ /**
6
+ * Program spreadsheet — read a building's program/takeoff data and render, build,
7
+ * and export report sheets from it. The surface spans two levels:
8
+ *
9
+ * - **High-level renders** — {@linkcode PluginProgramSpreadsheetApi.render} (rows +
10
+ * columns → a formatted, titled table) and its dataset specializations
11
+ * {@linkcode PluginProgramSpreadsheetApi.renderTakeoff} /
12
+ * {@linkcode PluginProgramSpreadsheetApi.renderProgram} (the host pulls the
13
+ * dataset). Authors think "render my takeoff to a sheet".
14
+ * - **Low-level construction** — for authors who need fine control:
15
+ * {@linkcode PluginProgramSpreadsheetApi.createSheet},
16
+ * {@linkcode PluginProgramSpreadsheetApi.setValues},
17
+ * {@linkcode PluginProgramSpreadsheetApi.setFormulas},
18
+ * {@linkcode PluginProgramSpreadsheetApi.setStyles},
19
+ * {@linkcode PluginProgramSpreadsheetApi.mergeCells},
20
+ * {@linkcode PluginProgramSpreadsheetApi.addConditionalFormatting},
21
+ * {@linkcode PluginProgramSpreadsheetApi.recalculate}, and
22
+ * {@linkcode PluginProgramSpreadsheetApi.transaction} (atomic, undoable batch).
23
+ *
24
+ * Plus dataset reads ({@linkcode PluginProgramSpreadsheetApi.getProgram} /
25
+ * {@linkcode PluginProgramSpreadsheetApi.getTakeoff} — the data the render* methods
26
+ * draw — and {@linkcode PluginProgramSpreadsheetApi.getMaterialTakeoff}, surface area
27
+ * per material), sheet reads ({@linkcode PluginProgramSpreadsheetApi.listSheets} /
28
+ * {@linkcode PluginProgramSpreadsheetApi.getSheetData}), charts + emphasis
29
+ * ({@linkcode PluginProgramSpreadsheetApi.addChart} /
30
+ * {@linkcode PluginProgramSpreadsheetApi.highlightCells}), workbook file export
31
+ * ({@linkcode PluginProgramSpreadsheetApi.export}), reusable
32
+ * {@linkcode PluginProgramSpreadsheetApi.templates}, live
33
+ * {@linkcode PluginProgramSpreadsheetApi.bindings}, a sandboxed script escape hatch
34
+ * ({@linkcode PluginProgramSpreadsheetApi.runScript}), an audit log
35
+ * ({@linkcode PluginProgramSpreadsheetApi.getAuditLog}), and a liveness
36
+ * {@linkcode PluginProgramSpreadsheetApi.ping}. `addTable` is intentionally not
37
+ * exposed — `render` composes header + rows + table in one call.
38
+ *
39
+ * **Verb note (naming authority; rows pending merge into constitution §4 by its owner).**
40
+ * Existing §4 verbs used as-is: `get`, `list`, `set` (bulk cell/format writes;
41
+ * read back via {@linkcode PluginProgramSpreadsheetApi.getSheetData}), `create`,
42
+ * `add` (charts, conditional formats), `apply` (templates), `export`, and
43
+ * `transaction` (the sanctioned atomic-batch verb), plus the ratified `render` and
44
+ * `highlight` program domain verbs ◆. New program-domain verbs ratified here ◆:
45
+ * `recalculate` (recompute the workbook's formula results — distinct from
46
+ * `refresh`), `merge` ({@linkcode PluginProgramSpreadsheetApi.mergeCells} spans a
47
+ * cell range — a spreadsheet-domain verb, explicitly NOT the CSG-solid `union`
48
+ * fold), `refresh` ({@linkcode PluginProgramSpreadsheetBindingsApi.refresh}
49
+ * re-pulls a binding's live source — distinct from `recalculate`), `run`
50
+ * ({@linkcode PluginProgramSpreadsheetApi.runScript} executes a sandboxed script),
51
+ * and `ping` (a meta liveness probe). Renames for compliance: the host's `save` →
52
+ * `templates.create`; `getRecentEntries` → `getAuditLog`.
53
+ *
54
+ * Accessed via `snaptrude.program.spreadsheet`.
55
+ */
56
+ export abstract class PluginProgramSpreadsheetApi {
57
+ constructor() {}
58
+
59
+ /**
60
+ * Reusable sheet templates — capture a sheet's layout as a named template and
61
+ * re-apply it to another sheet. See {@linkcode PluginProgramSpreadsheetTemplatesApi}.
62
+ */
63
+ public abstract templates: PluginProgramSpreadsheetTemplatesApi
64
+
65
+ /**
66
+ * Live data bindings — bind a program dataset to a sheet range and refresh it
67
+ * on demand. See {@linkcode PluginProgramSpreadsheetBindingsApi}.
68
+ */
69
+ public abstract bindings: PluginProgramSpreadsheetBindingsApi
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
+
77
+ /**
78
+ * Render a titled, formatted table onto a named sheet (create-or-replace).
79
+ *
80
+ * The intent-level replacement for the raw cell-write sequence: it writes the
81
+ * header + rows, applies per-column format/alignment, optionally wraps the
82
+ * block in a table, freezes the header, and appends a totals row. This is the
83
+ * generic table render; the `render*` family is reserved to also carry
84
+ * dataset-specific renders (`renderTakeoff`, `renderProgram`) once their
85
+ * argument shapes are ratified.
86
+ *
87
+ * @param sheetName - Target sheet name.
88
+ * @param columns - Column definitions, at least one (see
89
+ * {@linkcode PluginSpreadsheetColumn}).
90
+ * @param rows - Row objects keyed by column `key`.
91
+ * @param options - Optional `title`, `startCell` (default `"A1"`), `whenExists`
92
+ * (default `"replace"`), `asTable` (default `true`), `freezeHeader` (default
93
+ * `true`), and `totals` row.
94
+ * @returns A {@linkcode PluginProgramSpreadsheetRenderResult} with the written
95
+ * ranges and counts.
96
+ * @throws If `columns` is empty, the target sheet exists and `whenExists` is
97
+ * `"error"`, or a cell address is invalid.
98
+ *
99
+ * @examplePrompt Render my takeoff as a table on a sheet
100
+ * @examplePrompt Write the area schedule to a spreadsheet with totals
101
+ * @examplePrompt Put the department breakdown on a sheet called "Program"
102
+ * @examplePrompt Output this data as a formatted table with a header
103
+ * @examplePrompt Create a report sheet from these rows and columns
104
+ *
105
+ * # Example
106
+ * ```ts
107
+ * await snaptrude.program.spreadsheet.render(
108
+ * "Program",
109
+ * [
110
+ * { key: "name", header: "Department" },
111
+ * { key: "area", header: "Area", format: "0.00", align: "right" },
112
+ * ],
113
+ * [{ name: "FOH", area: 120.5 }],
114
+ * { totals: [{ column: "area", fn: "sum", label: "Total" }] },
115
+ * )
116
+ * ```
117
+ */
118
+ public abstract render(
119
+ sheetName: string,
120
+ columns: PluginSpreadsheetColumn[],
121
+ rows: Record<string, PluginSpreadsheetCell>[],
122
+ options?: {
123
+ title?: string
124
+ startCell?: string
125
+ whenExists?: "replace" | "error"
126
+ asTable?: boolean
127
+ freezeHeader?: boolean
128
+ totals?: PluginSpreadsheetTotal[]
129
+ },
130
+ ): PluginApiReturn<PluginProgramSpreadsheetRenderResult>
131
+
132
+ /**
133
+ * Render the quantity/material takeoff onto a sheet.
134
+ *
135
+ * A specialization of the render* family: the **host pulls and projects the
136
+ * current takeoff dataset itself** — the plugin supplies only the target
137
+ * `sheetName`, an optional `title`, and an optional `filter`; there is **no
138
+ * data argument**. The `filter` is applied host-side to the projected rows
139
+ * before rendering. Returns the same rendered-artifact record as
140
+ * {@linkcode PluginProgramSpreadsheetApi.render}.
141
+ * _(Authored ahead — optional via the `spreadsheet?` mount until the host
142
+ * round-trip is live.)_
143
+ *
144
+ * @param options - Optional `sheetName`, `title`, and `filter` — a
145
+ * case-insensitive substring kept when any of a row's cell values contains
146
+ * it (a {@linkcode PluginProgramSpreadsheetRenderDatasetArgs}).
147
+ * @returns A {@linkcode PluginProgramSpreadsheetRenderResult} with the written
148
+ * ranges and counts.
149
+ * @throws If the takeoff cannot be rendered.
150
+ *
151
+ * @examplePrompt Render the takeoff onto a sheet
152
+ * @examplePrompt Put the quantity takeoff on a spreadsheet
153
+ * @examplePrompt Generate the takeoff schedule sheet titled Takeoff
154
+ * @examplePrompt Render the material takeoff filtered to the walls
155
+ *
156
+ * # Example
157
+ * ```ts
158
+ * await snaptrude.program.spreadsheet.renderTakeoff({ sheetName: "Takeoff" })
159
+ * ```
160
+ */
161
+ public abstract renderTakeoff(options?: {
162
+ sheetName?: string
163
+ title?: string
164
+ filter?: string
165
+ }): PluginApiReturn<PluginProgramSpreadsheetRenderResult>
166
+
167
+ /**
168
+ * Render the area program onto a sheet.
169
+ *
170
+ * A specialization of the render* family: the **host pulls and projects the
171
+ * current program dataset itself** (departments with area targets vs allocated)
172
+ * — the plugin supplies only the target `sheetName`, an optional `title`, and an
173
+ * optional `filter`; there is **no data argument**. The `filter` is applied
174
+ * host-side to the projected rows before rendering. Returns the same
175
+ * rendered-artifact record as {@linkcode PluginProgramSpreadsheetApi.render}.
176
+ * _(Authored ahead — optional via the `spreadsheet?` mount until the host
177
+ * round-trip is live.)_
178
+ *
179
+ * @param options - Optional `sheetName`, `title`, and `filter` — a
180
+ * case-insensitive substring kept when any of a row's cell values contains
181
+ * it (a {@linkcode PluginProgramSpreadsheetRenderDatasetArgs}).
182
+ * @returns A {@linkcode PluginProgramSpreadsheetRenderResult} with the written
183
+ * ranges and counts.
184
+ * @throws If the program cannot be rendered.
185
+ *
186
+ * @examplePrompt Render the area program onto a sheet
187
+ * @examplePrompt Put the department program on a spreadsheet
188
+ * @examplePrompt Generate the program schedule sheet titled Program
189
+ * @examplePrompt Render the program filtered to the residential departments
190
+ *
191
+ * # Example
192
+ * ```ts
193
+ * await snaptrude.program.spreadsheet.renderProgram({ sheetName: "Program" })
194
+ * ```
195
+ */
196
+ public abstract renderProgram(options?: {
197
+ sheetName?: string
198
+ title?: string
199
+ filter?: string
200
+ }): PluginApiReturn<PluginProgramSpreadsheetRenderResult>
201
+
202
+ /**
203
+ * Export the report workbook to a file (xlsx, pdf, or csv).
204
+ *
205
+ * Returns the file content as base64 so the plugin can download, upload, or
206
+ * attach it. This is the workbook **file** export; to read cell **values** back
207
+ * as data, use {@linkcode PluginProgramSpreadsheetApi.getSheetData} instead.
208
+ *
209
+ * `xlsx` and `pdf` export the **whole** workbook. `csv` is inherently
210
+ * single-sheet: it serializes one sheet's used range — pass `options.sheetName`
211
+ * to choose which sheet, or omit it to serialize the active sheet.
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
+ *
216
+ * @param format - The file format to export to.
217
+ * @param options - Optional `fileName` (without extension; a default is used
218
+ * when omitted) and `sheetName` — the sheet to serialize for `csv`
219
+ * (ignored by `xlsx`/`pdf`, which always export the whole workbook).
220
+ * @returns A {@linkcode PluginProgramSpreadsheetExportResult} with the file's
221
+ * `fileName`, `mimeType`, and base64 `dataBase64`.
222
+ * @throws If the workbook cannot be serialized to the requested format.
223
+ *
224
+ * @examplePrompt Export the report as an Excel file
225
+ * @examplePrompt Download the whole workbook as a PDF
226
+ * @examplePrompt Export the program workbook to xlsx
227
+ * @examplePrompt Save the report as a csv file
228
+ * @examplePrompt Export the Takeoff sheet as CSV
229
+ *
230
+ * # Example
231
+ * ```ts
232
+ * const file = await snaptrude.program.spreadsheet.export("xlsx")
233
+ * // file.fileName, file.mimeType, file.dataBase64
234
+ *
235
+ * // CSV of a specific sheet:
236
+ * const csv = await snaptrude.program.spreadsheet.export("csv", { sheetName: "Takeoff" })
237
+ * ```
238
+ */
239
+ public abstract export(
240
+ format: PluginSpreadsheetExportFormat,
241
+ options?: { fileName?: string; sheetName?: string },
242
+ ): PluginApiReturn<PluginProgramSpreadsheetExportResult>
243
+
244
+ /**
245
+ * List the sheets in the report workbook.
246
+ *
247
+ * @returns A {@linkcode PluginProgramSpreadsheetListSheetsResult} with each sheet's
248
+ * name/index/visibility/size, plus the active sheet name.
249
+ *
250
+ * @examplePrompt List the sheets in the spreadsheet
251
+ * @examplePrompt What sheets are in the report workbook?
252
+ * @examplePrompt Which sheet is currently active?
253
+ * @examplePrompt How many sheets does the report have?
254
+ *
255
+ * # Example
256
+ * ```ts
257
+ * const { sheets, activeSheet } = await snaptrude.program.spreadsheet.listSheets()
258
+ * ```
259
+ */
260
+ public abstract listSheets(): PluginApiReturn<PluginProgramSpreadsheetListSheetsResult>
261
+
262
+ /**
263
+ * Read a sheet's data back as a matrix (and optionally as header-keyed records).
264
+ *
265
+ * @param sheetName - Sheet to read.
266
+ * @param options - Optional `range` (A1; omit to read the sheet's used range)
267
+ * and `header` (`true` to also get records keyed by the header row).
268
+ * @returns A {@linkcode PluginProgramSpreadsheetGetSheetDataResult} with the read
269
+ * `range`, `values` matrix, and optional `records`.
270
+ * @throws If the sheet does not exist or the range is invalid.
271
+ *
272
+ * @examplePrompt Read the data back from the Program sheet
273
+ * @examplePrompt Get the values in range A1:D20 of a sheet
274
+ * @examplePrompt Read a sheet as rows of records keyed by header
275
+ * @examplePrompt What's in the takeoff sheet right now?
276
+ *
277
+ * # Example
278
+ * ```ts
279
+ * const { values, records } = await snaptrude.program.spreadsheet.getSheetData(
280
+ * "Program",
281
+ * { header: true },
282
+ * )
283
+ * ```
284
+ */
285
+ public abstract getSheetData(
286
+ sheetName: string,
287
+ options?: { range?: string; header?: boolean },
288
+ ): PluginApiReturn<PluginProgramSpreadsheetGetSheetDataResult>
289
+
290
+ /**
291
+ * Add a chart to a sheet, driven by a cell range.
292
+ *
293
+ * @param sheetName - Sheet to add the chart to.
294
+ * @param chartType - Chart type (see {@linkcode PluginSpreadsheetChartType}).
295
+ * @param dataRange - A1 range driving the chart.
296
+ * @param options - Optional `title`, `position` (sheet coords), and `size` (px).
297
+ * @returns A {@linkcode PluginProgramSpreadsheetAddChartResult} with the new
298
+ * chart's id.
299
+ * @throws If the sheet or data range is invalid.
300
+ *
301
+ * @examplePrompt Add a bar chart of the department areas
302
+ * @examplePrompt Insert a pie chart from range B2:C10
303
+ * @examplePrompt Put a column chart on the Program sheet
304
+ * @examplePrompt Chart the area breakdown by department
305
+ *
306
+ * # Example
307
+ * ```ts
308
+ * const { chartId } = await snaptrude.program.spreadsheet.addChart(
309
+ * "Program",
310
+ * "column",
311
+ * "A1:B10",
312
+ * { title: "Area by department" },
313
+ * )
314
+ * ```
315
+ */
316
+ public abstract addChart(
317
+ sheetName: string,
318
+ chartType: PluginSpreadsheetChartType,
319
+ dataRange: string,
320
+ options?: {
321
+ title?: string
322
+ position?: { x: number; y: number }
323
+ size?: { width: number; height: number }
324
+ },
325
+ ): PluginApiReturn<PluginProgramSpreadsheetAddChartResult>
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
+
376
+ /**
377
+ * Highlight a range of cells (background color and optional emphasis).
378
+ *
379
+ * @param sheetName - Sheet containing the range.
380
+ * @param range - A1 range to highlight.
381
+ * @param options - Optional `color` (CSS hex; a default emphasis is used when
382
+ * omitted) and `bold`.
383
+ * @returns A {@linkcode PluginProgramSpreadsheetHighlightCellsResult} echoing the
384
+ * highlighted sheet and range.
385
+ * @throws If the sheet or range is invalid.
386
+ *
387
+ * @examplePrompt Highlight the cells that are over budget
388
+ * @examplePrompt Color range A2:A10 red
389
+ * @examplePrompt Highlight B2:D2 in yellow
390
+ * @examplePrompt Emphasize the totals row on the Program sheet
391
+ *
392
+ * # Example
393
+ * ```ts
394
+ * await snaptrude.program.spreadsheet.highlightCells("Program", "A2:A10", {
395
+ * color: "#ffe08a",
396
+ * })
397
+ * ```
398
+ */
399
+ public abstract highlightCells(
400
+ sheetName: string,
401
+ range: string,
402
+ options?: { color?: string; bold?: boolean },
403
+ ): PluginApiReturn<PluginProgramSpreadsheetHighlightCellsResult>
404
+
405
+ // --- Program / takeoff dataset reads (the data the render* methods draw) ---
406
+
407
+ /**
408
+ * Read the area-program dataset (departments with target vs allocated area).
409
+ *
410
+ * Returns the same figures {@linkcode PluginProgramSpreadsheetApi.renderProgram}
411
+ * projects onto a sheet, as render-ready rows — so a plugin can inspect or
412
+ * transform the program before rendering it (or render it itself via
413
+ * {@linkcode PluginProgramSpreadsheetApi.render}). For the canonical
414
+ * area-program summary read, see {@linkcode PluginProgramMetricsApi.get}.
415
+ *
416
+ * @returns A {@linkcode PluginProgramSpreadsheetGetProgramResult} with per-department
417
+ * rows (`targetArea`/`allocatedArea`/`variance`), totals, and the report `units`.
418
+ *
419
+ * @examplePrompt Get the area program data
420
+ * @examplePrompt Read the department program before I render it
421
+ * @examplePrompt Give me the program rows with target vs allocated area
422
+ * @examplePrompt What's the program dataset the report is built from?
423
+ *
424
+ * # Example
425
+ * ```ts
426
+ * const program = await snaptrude.program.spreadsheet.getProgram()
427
+ * for (const row of program.rows) console.log(row.name, row.allocatedArea, row.targetArea)
428
+ * ```
429
+ */
430
+ public abstract getProgram(): PluginApiReturn<PluginProgramSpreadsheetGetProgramResult>
431
+
432
+ /**
433
+ * Read the quantity/material takeoff dataset (per-element quantities).
434
+ *
435
+ * Returns the same rows {@linkcode PluginProgramSpreadsheetApi.renderTakeoff}
436
+ * projects onto a sheet — one record per counted element (category, item,
437
+ * level, quantity, unit) — so a plugin can inspect or transform the takeoff
438
+ * before rendering it (or render it itself via
439
+ * {@linkcode PluginProgramSpreadsheetApi.render}).
440
+ *
441
+ * @returns A {@linkcode PluginProgramSpreadsheetGetTakeoffResult} with the takeoff
442
+ * `rows`, a `rowCount`, and the `generatedAt` timestamp.
443
+ *
444
+ * @examplePrompt Get the takeoff data
445
+ * @examplePrompt Read the quantity takeoff rows
446
+ * @examplePrompt Give me the per-element quantities before I render them
447
+ * @examplePrompt What's in the material takeoff right now?
448
+ *
449
+ * # Example
450
+ * ```ts
451
+ * const takeoff = await snaptrude.program.spreadsheet.getTakeoff()
452
+ * console.log(takeoff.rowCount, "elements")
453
+ * ```
454
+ */
455
+ public abstract getTakeoff(): PluginApiReturn<PluginProgramSpreadsheetGetTakeoffResult>
456
+
457
+ /**
458
+ * Read the material take-off dataset (surface area per material, per element type).
459
+ *
460
+ * The native "Material Take-Off" quantities — the same figures the BIM Take-Off's
461
+ * *Material Take-Off* sheet lists — as render-ready rows: for each material applied
462
+ * to a wall/floor/ceiling/slab/roof family, its rolled-up **surface area** in the
463
+ * project's display units. This is the material-centric complement to
464
+ * {@linkcode PluginProgramSpreadsheetApi.getTakeoff} (which rolls up by element
465
+ * family). A read only — nothing is written and no file is downloaded.
466
+ *
467
+ * When no materials are applied (or the model is empty) the result is simply an
468
+ * empty `rows` array — not an error.
469
+ *
470
+ * @returns A {@linkcode PluginProgramSpreadsheetGetMaterialTakeoffResult} with the
471
+ * material take-off `rows`, a `rowCount`, and the `generatedAt` timestamp.
472
+ *
473
+ * @examplePrompt Get the material take-off
474
+ * @examplePrompt How much of each material is used?
475
+ * @examplePrompt Read the surface area by material
476
+ * @examplePrompt Give me the material quantities before I render them
477
+ * @examplePrompt What's in the material take-off right now?
478
+ *
479
+ * # Example
480
+ * ```ts
481
+ * const mto = await snaptrude.program.spreadsheet.getMaterialTakeoff()
482
+ * for (const row of mto.rows) {
483
+ * console.log(row.objectType, row.family, row.material, row.quantity, row.unit)
484
+ * }
485
+ * ```
486
+ */
487
+ public abstract getMaterialTakeoff(): PluginApiReturn<PluginProgramSpreadsheetGetMaterialTakeoffResult>
488
+
489
+ // --- Sheet construction (lower-level cell writes; render is the high-level path) ---
490
+
491
+ /**
492
+ * Create (or reuse/replace) a named sheet in the report workbook.
493
+ *
494
+ * The blank-canvas complement to {@linkcode PluginProgramSpreadsheetApi.render}:
495
+ * use it when you want an empty sheet to write into with
496
+ * {@linkcode PluginProgramSpreadsheetApi.setValues} /
497
+ * {@linkcode PluginProgramSpreadsheetApi.setFormulas}. By default an existing
498
+ * sheet of the same name is reused; pass `whenExists` to replace or error.
499
+ *
500
+ * @param name - The sheet name to create.
501
+ * @param whenExists - Behaviour if the name exists: `"reuse"` (default),
502
+ * `"replace"`, or `"error"`.
503
+ * @returns A {@linkcode PluginProgramSpreadsheetCreateSheetResult} with the resolved
504
+ * `sheetName`, whether it `replaced` an existing sheet, and its `sheetIndex`.
505
+ * @throws If the sheet exists and `whenExists` is `"error"`.
506
+ *
507
+ * @examplePrompt Create a sheet called Summary
508
+ * @examplePrompt Add a new blank sheet named Takeoff
509
+ * @examplePrompt Make a sheet, replacing it if it already exists
510
+ * @examplePrompt Start a fresh sheet to write into
511
+ *
512
+ * # Example
513
+ * ```ts
514
+ * await snaptrude.program.spreadsheet.createSheet("Summary")
515
+ * ```
516
+ */
517
+ public abstract createSheet(
518
+ name: string,
519
+ whenExists?: PluginSpreadsheetWhenExists,
520
+ ): PluginApiReturn<PluginProgramSpreadsheetCreateSheetResult>
521
+
522
+ /**
523
+ * Write a block of raw values into a sheet, anchored at a cell.
524
+ *
525
+ * The low-level cell-write path (the high-level path is
526
+ * {@linkcode PluginProgramSpreadsheetApi.render}, which adds a header, format,
527
+ * and totals). Values are written row-major from `startCell` (default `"A1"`);
528
+ * columns are auto-sized to fit.
529
+ *
530
+ * @param sheetName - Sheet to write into.
531
+ * @param values - Row-major matrix of values to write.
532
+ * @param startCell - Top-left anchor in A1 notation (default `"A1"`).
533
+ * @returns A {@linkcode PluginProgramSpreadsheetSetValuesResult} with the written
534
+ * `startCell`, `rowCount`, and `colCount`.
535
+ * @throws If the sheet does not exist or `startCell` is invalid.
536
+ *
537
+ * @examplePrompt Write these rows to the sheet starting at A1
538
+ * @examplePrompt Put this data into the Summary sheet
539
+ * @examplePrompt Set the values in the takeoff sheet from B2
540
+ * @examplePrompt Drop this matrix of numbers onto a sheet
541
+ *
542
+ * # Example
543
+ * ```ts
544
+ * await snaptrude.program.spreadsheet.setValues(
545
+ * "Summary",
546
+ * [["Department", "Area"], ["FOH", 120.5]],
547
+ * "A1",
548
+ * )
549
+ * ```
550
+ */
551
+ public abstract setValues(
552
+ sheetName: string,
553
+ values: PluginSpreadsheetCell[][],
554
+ startCell?: string,
555
+ ): PluginApiReturn<PluginProgramSpreadsheetSetValuesResult>
556
+
557
+ /**
558
+ * Set formulas on individual cells of a sheet.
559
+ *
560
+ * Each entry targets one cell (A1 notation) with a formula expression (a
561
+ * leading `=` is optional). Pairs with
562
+ * {@linkcode PluginProgramSpreadsheetApi.recalculate} when you need to force a
563
+ * recompute.
564
+ *
565
+ * @param sheetName - Sheet to set formulas on.
566
+ * @param formulas - The cell → formula assignments (see
567
+ * {@linkcode PluginSpreadsheetFormula}).
568
+ * @returns A {@linkcode PluginProgramSpreadsheetSetFormulasResult} with the `count`
569
+ * of formulas set.
570
+ * @throws If the sheet does not exist or a cell address is invalid.
571
+ *
572
+ * @examplePrompt Put a SUM formula in cell B10
573
+ * @examplePrompt Set formulas totalling each column
574
+ * @examplePrompt Add a formula to compute the variance column
575
+ * @examplePrompt Write =SUM(B2:B9) into B10 on the Summary sheet
576
+ *
577
+ * # Example
578
+ * ```ts
579
+ * await snaptrude.program.spreadsheet.setFormulas("Summary", [
580
+ * { cell: "B10", formula: "=SUM(B2:B9)" },
581
+ * ])
582
+ * ```
583
+ */
584
+ public abstract setFormulas(
585
+ sheetName: string,
586
+ formulas: PluginSpreadsheetFormula[],
587
+ ): PluginApiReturn<PluginProgramSpreadsheetSetFormulasResult>
588
+
589
+ // --- Formatting ---
590
+
591
+ /**
592
+ * Apply cell styles to one or more ranges of a sheet.
593
+ *
594
+ * Sets fill/text color, font, alignment, and number format on each given range.
595
+ * For a quick single-range emphasis,
596
+ * {@linkcode PluginProgramSpreadsheetApi.highlightCells} is the shortcut.
597
+ *
598
+ * @param sheetName - Sheet containing the ranges.
599
+ * @param ranges - Range → style assignments (each a range + a
600
+ * {@linkcode PluginSpreadsheetCellStyle}).
601
+ * @returns A {@linkcode PluginProgramSpreadsheetSetStylesResult} with the `count` of
602
+ * ranges styled.
603
+ * @throws If the sheet does not exist or a range is invalid.
604
+ *
605
+ * @examplePrompt Make the header row bold with a grey fill
606
+ * @examplePrompt Right-align the numbers in column B
607
+ * @examplePrompt Format A1:D1 with a background color and bold text
608
+ * @examplePrompt Style the totals row
609
+ *
610
+ * # Example
611
+ * ```ts
612
+ * await snaptrude.program.spreadsheet.setStyles("Summary", [
613
+ * { range: "A1:D1", style: { fontWeight: "bold", backColor: "#eef" } },
614
+ * ])
615
+ * ```
616
+ */
617
+ public abstract setStyles(
618
+ sheetName: string,
619
+ ranges: PluginSpreadsheetRangeStyle[],
620
+ ): PluginApiReturn<PluginProgramSpreadsheetSetStylesResult>
621
+
622
+ /**
623
+ * Merge a contiguous range of cells into a single spanned cell.
624
+ *
625
+ * Optionally sets the merged cell's value. (Verb ruling: `merge` is a
626
+ * spreadsheet-domain verb here — spanning cells — not the CSG-solid `union`.)
627
+ *
628
+ * @param sheetName - Sheet containing the range.
629
+ * @param range - A1 range to merge into one spanned cell.
630
+ * @param value - Optional value to set in the merged (top-left) cell.
631
+ * @returns A {@linkcode PluginProgramSpreadsheetMergeCellsResult} echoing the merged
632
+ * sheet and range.
633
+ * @throws If the sheet does not exist or the range is invalid.
634
+ *
635
+ * @examplePrompt Merge cells A1 to D1 for the title
636
+ * @examplePrompt Span the header across the first four columns
637
+ * @examplePrompt Merge A1:D1 and set it to "Program Summary"
638
+ *
639
+ * # Example
640
+ * ```ts
641
+ * await snaptrude.program.spreadsheet.mergeCells("Summary", "A1:D1", "Program Summary")
642
+ * ```
643
+ */
644
+ public abstract mergeCells(
645
+ sheetName: string,
646
+ range: string,
647
+ value?: PluginSpreadsheetCell,
648
+ ): PluginApiReturn<PluginProgramSpreadsheetMergeCellsResult>
649
+
650
+ /**
651
+ * Add a conditional-formatting rule to a range.
652
+ *
653
+ * Currently supports data-bar rules (a proportional in-cell bar); more rule
654
+ * types are reserved. For static (non-conditional) emphasis use
655
+ * {@linkcode PluginProgramSpreadsheetApi.highlightCells} or
656
+ * {@linkcode PluginProgramSpreadsheetApi.setStyles}.
657
+ *
658
+ * @param sheetName - Sheet containing the range.
659
+ * @param range - A1 range to format.
660
+ * @param rule - The conditional-format rule (see
661
+ * {@linkcode PluginSpreadsheetConditionalRule}).
662
+ * @returns A {@linkcode PluginProgramSpreadsheetAddConditionalFormattingResult} with
663
+ * whether a rule was `created`.
664
+ * @throws If the sheet does not exist or the range is invalid.
665
+ *
666
+ * @examplePrompt Add data bars to the area column
667
+ * @examplePrompt Show a proportional bar inside cells B2:B10
668
+ * @examplePrompt Add conditional formatting data bars to the quantities
669
+ *
670
+ * # Example
671
+ * ```ts
672
+ * await snaptrude.program.spreadsheet.addConditionalFormatting("Summary", "B2:B10", {
673
+ * type: "dataBar",
674
+ * color: "#4f9cf9",
675
+ * })
676
+ * ```
677
+ */
678
+ public abstract addConditionalFormatting(
679
+ sheetName: string,
680
+ range: string,
681
+ rule: PluginSpreadsheetConditionalRule,
682
+ ): PluginApiReturn<PluginProgramSpreadsheetAddConditionalFormattingResult>
683
+
684
+ // --- Recalculation & atomic batching ---
685
+
686
+ /**
687
+ * Recompute the workbook's formula results.
688
+ *
689
+ * Recalculates every formula (or, when `sheetName` is given, focuses that sheet
690
+ * before recalculating the workbook). (Verb ruling: `recalculate` recomputes
691
+ * formulas — distinct from {@linkcode PluginProgramSpreadsheetBindingsApi.refresh},
692
+ * which re-pulls a binding's source data.)
693
+ *
694
+ * @param options - Optional `sheetName` to focus before recalculating; omit for
695
+ * the whole workbook.
696
+ * @returns A {@linkcode PluginProgramSpreadsheetRecalculateResult} with the recompute
697
+ * `scope` and the focused `sheetName` (or `null`).
698
+ *
699
+ * @examplePrompt Recalculate the workbook
700
+ * @examplePrompt Recompute all the formulas
701
+ * @examplePrompt Recalculate the Summary sheet
702
+ *
703
+ * # Example
704
+ * ```ts
705
+ * await snaptrude.program.spreadsheet.recalculate()
706
+ * ```
707
+ */
708
+ public abstract recalculate(options?: {
709
+ sheetName?: string
710
+ }): PluginApiReturn<PluginProgramSpreadsheetRecalculateResult>
711
+
712
+ /**
713
+ * Run a sequence of sheet operations as one atomic, undoable transaction.
714
+ *
715
+ * Batches cell-construction operations (createSheet/setValues/setFormulas/
716
+ * setStyles/mergeCells) so they commit together and undo as a single step, with
717
+ * events suspended for speed. (`transaction` is the sanctioned §4 atomic-batch
718
+ * verb.)
719
+ *
720
+ * @param operations - The operations to run in order. Each operation's `args`
721
+ * stays that method's schema **object** (the wire shape), not positional.
722
+ * @param label - Optional undo-history label for the batch.
723
+ * @returns A {@linkcode PluginProgramSpreadsheetTransactionResult} with the
724
+ * `operationCount` and each operation's `results`.
725
+ * @throws If any operation names an unsupported method or fails.
726
+ *
727
+ * @examplePrompt Create a sheet and write to it in one atomic step
728
+ * @examplePrompt Batch these sheet edits as a single undoable action
729
+ * @examplePrompt Run these operations together as one transaction
730
+ *
731
+ * # Example
732
+ * ```ts
733
+ * await snaptrude.program.spreadsheet.transaction(
734
+ * [
735
+ * { method: "createSheet", args: { name: "Summary" } },
736
+ * { method: "setValues", args: { sheetName: "Summary", values: [["A", 1]] } },
737
+ * ],
738
+ * "Build summary",
739
+ * )
740
+ * ```
741
+ */
742
+ public abstract transaction(
743
+ operations: PluginSpreadsheetTransactionOp[],
744
+ label?: string,
745
+ ): PluginApiReturn<PluginProgramSpreadsheetTransactionResult>
746
+
747
+ // --- Meta: script escape hatch, audit log, liveness ---
748
+
749
+ /**
750
+ * Run an author-supplied script against a sandboxed workbook facade.
751
+ *
752
+ * The escape hatch for advanced automation the typed methods don't cover: the
753
+ * `script` runs against a restricted `workbook` object with browser/network
754
+ * globals blocked, and its return value is handed back as `result`. Prefer the
755
+ * typed methods where they exist. (Verb ruling: `run` executes a script.)
756
+ *
757
+ * @param script - Script source, run against the sandboxed `workbook` facade.
758
+ * @returns A {@linkcode PluginProgramSpreadsheetRunScriptResult} with the script's
759
+ * `result`.
760
+ * @throws If the script uses a blocked browser/network API or throws at runtime.
761
+ *
762
+ * @examplePrompt Run this SpreadJS script against the workbook
763
+ * @examplePrompt Execute a custom script on the sheets
764
+ * @examplePrompt Run a script to tweak the workbook
765
+ *
766
+ * # Example
767
+ * ```ts
768
+ * const { result } = await snaptrude.program.spreadsheet.runScript(
769
+ * "return workbook.getSheetCount();",
770
+ * )
771
+ * ```
772
+ */
773
+ public abstract runScript(
774
+ script: string,
775
+ ): PluginApiReturn<PluginProgramSpreadsheetRunScriptResult>
776
+
777
+ /**
778
+ * Read the recent audit log of program-spreadsheet operations.
779
+ *
780
+ * Returns the most recent operations performed through this API (method, sheet,
781
+ * status, summary, timestamp), newest first — useful for showing the user what
782
+ * a plugin changed. (Renamed from the host's `getRecentEntries` for §4 `get`
783
+ * compliance.)
784
+ *
785
+ * @param options - Optional `limit` on the entries returned (clamped 1–100,
786
+ * default 20).
787
+ * @returns A {@linkcode PluginProgramSpreadsheetGetAuditLogResult} with the audit
788
+ * `entries`, newest first.
789
+ *
790
+ * @examplePrompt Show the recent spreadsheet actions
791
+ * @examplePrompt What did the plugin change in the workbook?
792
+ * @examplePrompt Get the last 10 audit log entries
793
+ * @examplePrompt Read the program spreadsheet audit log
794
+ *
795
+ * # Example
796
+ * ```ts
797
+ * const { entries } = await snaptrude.program.spreadsheet.getAuditLog({ limit: 10 })
798
+ * ```
799
+ */
800
+ public abstract getAuditLog(options?: {
801
+ limit?: number
802
+ }): PluginApiReturn<PluginProgramSpreadsheetGetAuditLogResult>
803
+
804
+ /**
805
+ * Ping the program-mode spreadsheet bridge to check it is reachable.
806
+ *
807
+ * A liveness probe: resolves with `{ pong: true }` when the program-mode
808
+ * workbook bridge is up. (Verb ruling: `ping` is a meta liveness verb.)
809
+ *
810
+ * @returns A {@linkcode PluginProgramSpreadsheetPingResult} — `{ pong: true }` when
811
+ * the bridge is reachable.
812
+ *
813
+ * @examplePrompt Ping the spreadsheet bridge
814
+ * @examplePrompt Is the program spreadsheet available?
815
+ * @examplePrompt Check the spreadsheet connection is alive
816
+ *
817
+ * # Example
818
+ * ```ts
819
+ * const { pong } = await snaptrude.program.spreadsheet.ping()
820
+ * ```
821
+ */
822
+ public abstract ping(): PluginApiReturn<PluginProgramSpreadsheetPingResult>
823
+
824
+ // --- Custom program sheets (grouped program views) -----------------------------
825
+
826
+ /**
827
+ * Create a **custom program sheet** — a live view of the program grouped by a
828
+ * configurable hierarchy (the Program tab's "Custom" sheet with *Organize →
829
+ * Group by*).
830
+ *
831
+ * Unlike {@linkcode PluginProgramSpreadsheetApi.createSheet} (a blank sheet you
832
+ * write cells into), a custom sheet is data-bound: its rows are the project's
833
+ * spaces, re-rendered from the model, grouped by `groupBy` in order (e.g.
834
+ * `["departmentName", "<metadataHeaderId>", "label"]` for a healthcare
835
+ * department → sub-department → room hierarchy) and showing the `properties`
836
+ * columns. Valid property ids come from
837
+ * {@linkcode PluginProgramSpreadsheetApi.listCustomSheetProperties} — built-in
838
+ * properties plus every program metadata header id. The configuration is
839
+ * saved with the sheet.
840
+ *
841
+ * @param name - The sheet name to create (must not already exist).
842
+ * @param options - Optional `groupBy` (property ids, outermost first; default
843
+ * none), `properties` (column property ids, in order; default
844
+ * `["label", "areas"]`), and `groupColors` (property id → CSS hex fill for
845
+ * that level's group headers).
846
+ * @returns The sheet's {@linkcode PluginSpreadsheetCustomSheet} configuration.
847
+ * @throws If a sheet named `name` already exists, or a property id is unknown.
848
+ *
849
+ * @examplePrompt Create a custom sheet grouped by department then sub-department
850
+ * @examplePrompt Make a program view grouped by storey and label
851
+ * @examplePrompt Build a grouped program sheet for the healthcare hierarchy
852
+ * @examplePrompt Add a custom sheet with a department → room type group-by
853
+ *
854
+ * # Example
855
+ * ```ts
856
+ * const { headers } = await snaptrude.program.metadata.listHeaders()
857
+ * const subDept = headers.find((h) => h.name === "Sub-department")
858
+ * await snaptrude.program.spreadsheet.createCustomSheet("Clinical Program", {
859
+ * groupBy: ["departmentName", subDept.headerId, "label"],
860
+ * properties: ["label", "count", "areas", "netAreaAchieved"],
861
+ * })
862
+ * ```
863
+ */
864
+ public abstract createCustomSheet(
865
+ name: string,
866
+ options?: {
867
+ groupBy?: string[]
868
+ properties?: string[]
869
+ groupColors?: Record<string, string>
870
+ },
871
+ ): PluginApiReturn<PluginProgramSpreadsheetCustomSheetResult>
872
+
873
+ /**
874
+ * Update a custom program sheet's group-by hierarchy, columns, or group colors.
875
+ *
876
+ * A **sparse** update: omitted fields are left unchanged. The sheet is
877
+ * re-rendered once and the configuration saved.
878
+ *
879
+ * @param sheetName - The custom sheet to update.
880
+ * @param options - Any of `groupBy`, `properties`, `groupColors` (see
881
+ * {@linkcode PluginProgramSpreadsheetApi.createCustomSheet}).
882
+ * @returns The sheet's updated {@linkcode PluginSpreadsheetCustomSheet}.
883
+ * @throws If `sheetName` is not a custom program sheet, or a property id is
884
+ * unknown.
885
+ *
886
+ * @examplePrompt Change the custom sheet to group by storey first
887
+ * @examplePrompt Add the Occupancy column to my grouped program sheet
888
+ * @examplePrompt Regroup the Clinical Program sheet by department only
889
+ *
890
+ * # Example
891
+ * ```ts
892
+ * await snaptrude.program.spreadsheet.updateCustomSheet("Clinical Program", {
893
+ * groupBy: ["storey", "departmentName"],
894
+ * })
895
+ * ```
896
+ */
897
+ public abstract updateCustomSheet(
898
+ sheetName: string,
899
+ options: {
900
+ groupBy?: string[]
901
+ properties?: string[]
902
+ groupColors?: Record<string, string>
903
+ },
904
+ ): PluginApiReturn<PluginProgramSpreadsheetCustomSheetResult>
905
+
906
+ /**
907
+ * Get a custom program sheet's configuration.
908
+ *
909
+ * @param sheetName - The sheet to read.
910
+ * @returns Its {@linkcode PluginSpreadsheetCustomSheet}, or `null` when no
911
+ * custom program sheet has that name (plain sheets return `null` too).
912
+ *
913
+ * @examplePrompt How is the Clinical Program sheet grouped?
914
+ * @examplePrompt Get the group-by configuration of this custom sheet
915
+ *
916
+ * # Example
917
+ * ```ts
918
+ * const cfg = await snaptrude.program.spreadsheet.getCustomSheet("Clinical Program")
919
+ * if (cfg) console.log(cfg.groupBy, cfg.properties)
920
+ * ```
921
+ */
922
+ public abstract getCustomSheet(
923
+ sheetName: string,
924
+ ): PluginApiReturn<PluginProgramSpreadsheetGetCustomSheetResult>
925
+
926
+ /**
927
+ * List the custom program sheets in the workbook with their configurations.
928
+ *
929
+ * @returns A {@linkcode PluginProgramSpreadsheetListCustomSheetsResult} with a
930
+ * `sheets` array (empty when there are none).
931
+ *
932
+ * @examplePrompt List the custom program sheets
933
+ * @examplePrompt Which sheets are grouped program views?
934
+ *
935
+ * # Example
936
+ * ```ts
937
+ * const { sheets } = await snaptrude.program.spreadsheet.listCustomSheets()
938
+ * ```
939
+ */
940
+ public abstract listCustomSheets(): PluginApiReturn<PluginProgramSpreadsheetListCustomSheetsResult>
941
+
942
+ /**
943
+ * List the property ids a custom program sheet can show as columns or group by.
944
+ *
945
+ * Built-in properties (`label`, `departmentName`, `storey`, `areas`, …) plus
946
+ * one entry per program metadata header (its `headerId`). `groupable` is
947
+ * `false` for computed properties that can only be columns.
948
+ *
949
+ * @returns A {@linkcode PluginProgramSpreadsheetListCustomSheetPropertiesResult}.
950
+ *
951
+ * @examplePrompt What can I group a custom program sheet by?
952
+ * @examplePrompt List the columns available for a custom sheet
953
+ *
954
+ * # Example
955
+ * ```ts
956
+ * const { properties } = await snaptrude.program.spreadsheet.listCustomSheetProperties()
957
+ * const groupable = properties.filter((p) => p.groupable).map((p) => p.id)
958
+ * ```
959
+ */
960
+ public abstract listCustomSheetProperties(): PluginApiReturn<PluginProgramSpreadsheetListCustomSheetPropertiesResult>
961
+ }
962
+
963
+ /**
964
+ * Program-spreadsheet templates — capture a sheet's layout as a named, reusable
965
+ * template and re-apply it to another sheet.
966
+ *
967
+ * Accessed via `snaptrude.program.spreadsheet.templates`.
968
+ */
969
+ export abstract class PluginProgramSpreadsheetTemplatesApi {
970
+ constructor() {}
971
+
972
+ /**
973
+ * Save a sheet's current layout as a named template.
974
+ *
975
+ * (Renamed from the host's `save` to `create` for §4 compliance.)
976
+ *
977
+ * @param name - Template name (re-saving the same name overwrites it).
978
+ * @param sheetName - The source sheet to capture.
979
+ * @param scope - Template scope: `"project"` (default) or `"global"`.
980
+ * @returns A {@linkcode PluginProgramSpreadsheetTemplatesCreateResult} with the new
981
+ * template's `id`, `name`, `scope`, and source `sheetName`.
982
+ * @throws If the source sheet does not exist.
983
+ *
984
+ * @examplePrompt Save this sheet as a reusable template
985
+ * @examplePrompt Create a template from the Summary sheet
986
+ * @examplePrompt Save the current layout as a template called "Cover"
987
+ *
988
+ * # Example
989
+ * ```ts
990
+ * await snaptrude.program.spreadsheet.templates.create("Cover", "Summary")
991
+ * ```
992
+ */
993
+ public abstract create(
994
+ name: string,
995
+ sheetName: string,
996
+ scope?: PluginSpreadsheetTemplateScope,
997
+ ): PluginApiReturn<PluginProgramSpreadsheetTemplatesCreateResult>
998
+
999
+ /**
1000
+ * Apply a saved template to a target sheet (create-or-replace).
1001
+ *
1002
+ * @param name - The template to apply.
1003
+ * @param targetSheetName - The sheet to create/replace from the template.
1004
+ * @returns A {@linkcode PluginProgramSpreadsheetTemplatesApplyResult} echoing the
1005
+ * applied template and target sheet.
1006
+ * @throws If the named template does not exist.
1007
+ *
1008
+ * @examplePrompt Apply the Cover template to a new sheet
1009
+ * @examplePrompt Use my saved template on the Report sheet
1010
+ * @examplePrompt Apply template "Cover" to sheet "Report"
1011
+ *
1012
+ * # Example
1013
+ * ```ts
1014
+ * await snaptrude.program.spreadsheet.templates.apply("Cover", "Report")
1015
+ * ```
1016
+ */
1017
+ public abstract apply(
1018
+ name: string,
1019
+ targetSheetName: string,
1020
+ ): PluginApiReturn<PluginProgramSpreadsheetTemplatesApplyResult>
1021
+ }
1022
+
1023
+ /**
1024
+ * Program-spreadsheet data bindings — bind a live program dataset to a sheet
1025
+ * range so it can be refreshed on demand.
1026
+ *
1027
+ * A binding links a dataset (e.g. the takeoff) to a target sheet range; a refresh
1028
+ * re-pulls the current data and rewrites the range. Accessed via
1029
+ * `snaptrude.program.spreadsheet.bindings`.
1030
+ */
1031
+ export abstract class PluginProgramSpreadsheetBindingsApi {
1032
+ constructor() {}
1033
+
1034
+ /**
1035
+ * Create a named binding from a dataset to a sheet range (and do an initial refresh).
1036
+ *
1037
+ * @param name - Binding name (re-using a name overwrites it).
1038
+ * @param source - The dataset to bind (see
1039
+ * {@linkcode PluginSpreadsheetBindingSource}).
1040
+ * @param target - The target sheet range (see
1041
+ * {@linkcode PluginSpreadsheetBindingTarget}).
1042
+ * @param mode - How a refresh writes into the target (default `"replaceRange"`).
1043
+ * @returns A {@linkcode PluginProgramSpreadsheetBindingsCreateResult} — the stored
1044
+ * binding plus the `refresh` result of the initial pull.
1045
+ * @throws If the target sheet does not exist.
1046
+ *
1047
+ * @examplePrompt Bind the takeoff to the Data sheet
1048
+ * @examplePrompt Create a live binding from the takeoff to A1 on Data
1049
+ * @examplePrompt Link the takeoff dataset to a sheet range
1050
+ *
1051
+ * # Example
1052
+ * ```ts
1053
+ * await snaptrude.program.spreadsheet.bindings.create(
1054
+ * "takeoff",
1055
+ * { dataset: "takeoff" },
1056
+ * { sheetName: "Data", startCell: "A1" },
1057
+ * )
1058
+ * ```
1059
+ */
1060
+ public abstract create(
1061
+ name: string,
1062
+ source: PluginSpreadsheetBindingSource,
1063
+ target: PluginSpreadsheetBindingTarget,
1064
+ mode?: PluginSpreadsheetBindingMode,
1065
+ ): PluginApiReturn<PluginProgramSpreadsheetBindingsCreateResult>
1066
+
1067
+ /**
1068
+ * Refresh one binding (by name) or all bindings, re-pulling their source data.
1069
+ *
1070
+ * (Verb ruling: `refresh` re-pulls a binding's live source into its target
1071
+ * range — distinct from {@linkcode PluginProgramSpreadsheetApi.recalculate},
1072
+ * which recomputes formulas.)
1073
+ *
1074
+ * @param options - Optional binding `name`; omit it to refresh every binding.
1075
+ * @returns A {@linkcode PluginProgramSpreadsheetBindingsRefreshResult} with a
1076
+ * `refreshed` entry per binding that was updated.
1077
+ * @throws If a `name` is given but no binding with that name exists.
1078
+ *
1079
+ * @examplePrompt Refresh the takeoff binding
1080
+ * @examplePrompt Re-pull all my data bindings
1081
+ * @examplePrompt Refresh every binding on the sheets
1082
+ *
1083
+ * # Example
1084
+ * ```ts
1085
+ * await snaptrude.program.spreadsheet.bindings.refresh({ name: "takeoff" })
1086
+ * ```
1087
+ */
1088
+ public abstract refresh(options?: {
1089
+ name?: string
1090
+ }): PluginApiReturn<PluginProgramSpreadsheetBindingsRefreshResult>
1091
+
1092
+ /**
1093
+ * List all data bindings in the workbook.
1094
+ *
1095
+ * @returns A {@linkcode PluginProgramSpreadsheetBindingsListResult} with every
1096
+ * stored {@linkcode PluginSpreadsheetBinding}.
1097
+ *
1098
+ * @examplePrompt List the data bindings
1099
+ * @examplePrompt What bindings are set up on the sheets?
1100
+ * @examplePrompt Show all the live data bindings
1101
+ *
1102
+ * # Example
1103
+ * ```ts
1104
+ * const { bindings } = await snaptrude.program.spreadsheet.bindings.list()
1105
+ * ```
1106
+ */
1107
+ public abstract list(): PluginApiReturn<PluginProgramSpreadsheetBindingsListResult>
1108
+ }
1109
+
1110
+ /**
1111
+ * Program-spreadsheet plugin datasets — named, plugin-supplied row sets stored
1112
+ * alongside the workbook so bindings can render and re-render them.
1113
+ *
1114
+ * A dataset is uploaded with {@linkcode PluginProgramSpreadsheetDatasetsApi.set}
1115
+ * (upsert by name). A binding whose source is `{ dataset: "plugin", name }`
1116
+ * renders the dataset at its target anchor, and re-renders automatically every
1117
+ * time the dataset is set again — the "refresh on rerun" behaviour. Accessed
1118
+ * via `snaptrude.program.spreadsheet.datasets`.
1119
+ */
1120
+ export abstract class PluginProgramSpreadsheetDatasetsApi {
1121
+ constructor() {}
1122
+
1123
+ /**
1124
+ * Store (upsert) a named plugin dataset.
1125
+ *
1126
+ * Re-using a `name` replaces the dataset and automatically refreshes every
1127
+ * binding whose source is `{ dataset: "plugin", name }` — no extra plugin
1128
+ * calls needed to keep bound ranges current. Limits: at most 10,000 rows and
1129
+ * 2 MB serialized.
1130
+ *
1131
+ * @param name - Dataset name (re-using a name overwrites it).
1132
+ * @param columns - Column definitions (see {@linkcode PluginSpreadsheetColumn});
1133
+ * their order is the column order bindings render.
1134
+ * @param rows - Row objects keyed by column `key`.
1135
+ * @returns A {@linkcode PluginProgramSpreadsheetDatasetsSetResult} with the
1136
+ * stored row count.
1137
+ * @throws If the dataset exceeds 10,000 rows or 2 MB serialized.
1138
+ *
1139
+ * @examplePrompt Store my plugin's rows as a named dataset
1140
+ * @examplePrompt Upload data the sheets can bind to and refresh
1141
+ * @examplePrompt Save a dataset for a live sheet binding
1142
+ * @examplePrompt Push my computed table so a binding keeps it fresh
1143
+ *
1144
+ * # Example
1145
+ * ```ts
1146
+ * await snaptrude.program.spreadsheet.datasets.set(
1147
+ * "costs",
1148
+ * [
1149
+ * { key: "item", header: "Item" },
1150
+ * { key: "cost", header: "Cost", align: "right" },
1151
+ * ],
1152
+ * [{ item: "Concrete", cost: 120 }],
1153
+ * )
1154
+ * ```
1155
+ */
1156
+ public abstract set(
1157
+ name: string,
1158
+ columns: PluginSpreadsheetColumn[],
1159
+ rows: Record<string, PluginSpreadsheetCell>[],
1160
+ ): PluginApiReturn<PluginProgramSpreadsheetDatasetsSetResult>
1161
+
1162
+ /**
1163
+ * List the stored plugin datasets.
1164
+ *
1165
+ * @returns A {@linkcode PluginProgramSpreadsheetDatasetsListResult} with each
1166
+ * dataset's `name`, `rowCount`, and `updatedAt` timestamp.
1167
+ *
1168
+ * @examplePrompt List my plugin datasets
1169
+ * @examplePrompt What datasets are stored for the sheets?
1170
+ * @examplePrompt Show the data sets bindings can use
1171
+ *
1172
+ * # Example
1173
+ * ```ts
1174
+ * const { datasets } = await snaptrude.program.spreadsheet.datasets.list()
1175
+ * ```
1176
+ */
1177
+ public abstract list(): PluginApiReturn<PluginProgramSpreadsheetDatasetsListResult>
1178
+ }
1179
+
1180
+ /** A single spreadsheet cell value. */
1181
+ export const PluginSpreadsheetCell = z.union([
1182
+ z.string(),
1183
+ z.number(),
1184
+ z.boolean(),
1185
+ z.null(),
1186
+ ])
1187
+ export type PluginSpreadsheetCell = z.infer<typeof PluginSpreadsheetCell>
1188
+
1189
+ /** Horizontal alignment for a rendered column. */
1190
+ export const PluginSpreadsheetAlign = z.enum(["left", "center", "right"])
1191
+ export type PluginSpreadsheetAlign = z.infer<typeof PluginSpreadsheetAlign>
1192
+
1193
+ /**
1194
+ * A column definition for {@linkcode PluginProgramSpreadsheetApi.render}.
1195
+ *
1196
+ * | Property | Type | Description |
1197
+ * |---|---|---|
1198
+ * | `key` | `string` | Key into each row object |
1199
+ * | `header` | `string` | Column header text |
1200
+ * | `width` | `number?` | Fixed column width in px; auto-fit when omitted |
1201
+ * | `format` | `string?` | Number/date format string applied to the data cells |
1202
+ * | `align` | `"left" \| "center" \| "right"?` | Cell alignment |
1203
+ */
1204
+ export const PluginSpreadsheetColumn = z.object({
1205
+ key: z.string(),
1206
+ header: z.string(),
1207
+ width: z.number().optional(),
1208
+ format: z.string().optional(),
1209
+ align: PluginSpreadsheetAlign.optional(),
1210
+ })
1211
+ export type PluginSpreadsheetColumn = z.infer<typeof PluginSpreadsheetColumn>
1212
+
1213
+ /**
1214
+ * A totals-row aggregation for {@linkcode PluginProgramSpreadsheetApi.render}.
1215
+ *
1216
+ * | Property | Type | Description |
1217
+ * |---|---|---|
1218
+ * | `column` | `string` | The {@linkcode PluginSpreadsheetColumn} `key` to aggregate |
1219
+ * | `fn` | `"sum" \| "avg" \| "count" \| "min" \| "max"` | Aggregation function |
1220
+ * | `label` | `string?` | Optional label printed in the first column of the totals row |
1221
+ */
1222
+ export const PluginSpreadsheetTotal = z.object({
1223
+ column: z.string(),
1224
+ fn: z.enum(["sum", "avg", "count", "min", "max"]),
1225
+ label: z.string().optional(),
1226
+ })
1227
+ export type PluginSpreadsheetTotal = z.infer<typeof PluginSpreadsheetTotal>
1228
+
1229
+ /**
1230
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.render}.
1231
+ *
1232
+ * | Property | Type | Description |
1233
+ * |---|---|---|
1234
+ * | `sheetName` | `string` | Target sheet name |
1235
+ * | `columns` | {@linkcode PluginSpreadsheetColumn}`[]` | Column definitions (at least one) |
1236
+ * | `rows` | `Record<string, cell>[]` | Row objects keyed by column `key` |
1237
+ * | `title` | `string?` | Optional title rendered above the header |
1238
+ * | `startCell` | `string?` | Top-left anchor in A1 notation (default `"A1"`) |
1239
+ * | `whenExists` | `"replace" \| "error"?` | Behaviour if the sheet exists (default `"replace"`) |
1240
+ * | `asTable` | `boolean?` | Wrap the block in a table (default `true`) |
1241
+ * | `freezeHeader` | `boolean?` | Freeze rows above the data (default `true`) |
1242
+ * | `totals` | {@linkcode PluginSpreadsheetTotal}`[]?` | Optional totals row |
1243
+ */
1244
+ export const PluginProgramSpreadsheetRenderArgs = z.object({
1245
+ sheetName: z.string(),
1246
+ columns: z.array(PluginSpreadsheetColumn),
1247
+ rows: z.array(z.record(z.string(), PluginSpreadsheetCell)),
1248
+ title: z.string().optional(),
1249
+ startCell: z.string().optional(),
1250
+ whenExists: z.enum(["replace", "error"]).optional(),
1251
+ asTable: z.boolean().optional(),
1252
+ freezeHeader: z.boolean().optional(),
1253
+ totals: z.array(PluginSpreadsheetTotal).optional(),
1254
+ })
1255
+ export type PluginProgramSpreadsheetRenderArgs = z.infer<
1256
+ typeof PluginProgramSpreadsheetRenderArgs
1257
+ >
1258
+
1259
+ /**
1260
+ * Result of {@linkcode PluginProgramSpreadsheetApi.render}.
1261
+ *
1262
+ * | Property | Type | Description |
1263
+ * |---|---|---|
1264
+ * | `sheetName` | `string` | The sheet that was written |
1265
+ * | `range` | `string` | A1 range covering the full written block (title + header + data + totals) |
1266
+ * | `headerRange` | `string` | A1 range of the header row alone |
1267
+ * | `rowCount` | `number` | Number of data rows written (excludes title/header/totals) |
1268
+ * | `colCount` | `number` | Number of columns written |
1269
+ * | `tableName` | `string \| null` | The created table's name, or `null` when not wrapped as a table |
1270
+ * | `replaced` | `boolean` | Whether an existing sheet was replaced |
1271
+ */
1272
+ export const PluginProgramSpreadsheetRenderResult = z.object({
1273
+ sheetName: z.string(),
1274
+ range: z.string(),
1275
+ headerRange: z.string(),
1276
+ rowCount: z.number(),
1277
+ colCount: z.number(),
1278
+ tableName: z.string().nullable(),
1279
+ replaced: z.boolean(),
1280
+ })
1281
+ export type PluginProgramSpreadsheetRenderResult = z.infer<
1282
+ typeof PluginProgramSpreadsheetRenderResult
1283
+ >
1284
+
1285
+ /**
1286
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.renderTakeoff} and
1287
+ * {@linkcode PluginProgramSpreadsheetApi.renderProgram} — the dataset render
1288
+ * methods. There is **no data argument**: the host pulls and projects the
1289
+ * takeoff/program dataset itself. All fields are optional. (Both methods share
1290
+ * this args type, as `import.image`/`import.pdf` share their args.)
1291
+ *
1292
+ * | Property | Type | Description |
1293
+ * |---|---|---|
1294
+ * | `sheetName` | `string?` | Target sheet name (a default is used when omitted) |
1295
+ * | `title` | `string?` | Optional title rendered above the table |
1296
+ * | `filter` | `string?` | Case-insensitive substring — a row is kept when any of its cell values contains it (blank/omitted keeps every row). Not a query language. |
1297
+ */
1298
+ export const PluginProgramSpreadsheetRenderDatasetArgs = z.object({
1299
+ sheetName: z.string().optional(),
1300
+ title: z.string().optional(),
1301
+ filter: z.string().optional(),
1302
+ })
1303
+ export type PluginProgramSpreadsheetRenderDatasetArgs = z.infer<
1304
+ typeof PluginProgramSpreadsheetRenderDatasetArgs
1305
+ >
1306
+
1307
+ /** The workbook export file format. */
1308
+ export const PluginSpreadsheetExportFormat = z.enum(["xlsx", "pdf", "csv"])
1309
+ export type PluginSpreadsheetExportFormat = z.infer<
1310
+ typeof PluginSpreadsheetExportFormat
1311
+ >
1312
+
1313
+ /**
1314
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.export}.
1315
+ *
1316
+ * | Property | Type | Description |
1317
+ * |---|---|---|
1318
+ * | `format` | `"xlsx" \| "pdf" \| "csv"` | The file format to export to |
1319
+ * | `fileName` | `string?` | Desired file name (without extension); a default is used when omitted |
1320
+ * | `sheetName` | `string?` | For `csv`: the sheet to serialize (the active sheet when omitted). Ignored by `xlsx`/`pdf`. |
1321
+ */
1322
+ export const PluginProgramSpreadsheetExportArgs = z.object({
1323
+ format: PluginSpreadsheetExportFormat,
1324
+ fileName: z.string().optional(),
1325
+ sheetName: z.string().optional(),
1326
+ })
1327
+ export type PluginProgramSpreadsheetExportArgs = z.infer<
1328
+ typeof PluginProgramSpreadsheetExportArgs
1329
+ >
1330
+
1331
+ /**
1332
+ * Result of {@linkcode PluginProgramSpreadsheetApi.export} — the exported workbook file.
1333
+ *
1334
+ * | Property | Type | Description |
1335
+ * |---|---|---|
1336
+ * | `format` | `"xlsx" \| "pdf" \| "csv"` | The format the file was exported in |
1337
+ * | `fileName` | `string` | The file name (with extension) |
1338
+ * | `mimeType` | `string` | The file's MIME type |
1339
+ * | `dataBase64` | `string` | The file's bytes, base64-encoded |
1340
+ */
1341
+ export const PluginProgramSpreadsheetExportResult = z.object({
1342
+ format: PluginSpreadsheetExportFormat,
1343
+ fileName: z.string(),
1344
+ mimeType: z.string(),
1345
+ dataBase64: z.string(),
1346
+ })
1347
+ export type PluginProgramSpreadsheetExportResult = z.infer<
1348
+ typeof PluginProgramSpreadsheetExportResult
1349
+ >
1350
+
1351
+ /**
1352
+ * Metadata for one sheet in {@linkcode PluginProgramSpreadsheetListSheetsResult}.
1353
+ *
1354
+ * | Property | Type | Description |
1355
+ * |---|---|---|
1356
+ * | `name` | `string` | Sheet name |
1357
+ * | `index` | `number` | Zero-based sheet index |
1358
+ * | `visible` | `boolean` | Whether the sheet is visible |
1359
+ * | `rowCount` | `number` | Total rows in the sheet |
1360
+ * | `colCount` | `number` | Total columns in the sheet |
1361
+ */
1362
+ export const PluginSpreadsheetSheetInfo = z.object({
1363
+ name: z.string(),
1364
+ index: z.number(),
1365
+ visible: z.boolean(),
1366
+ rowCount: z.number(),
1367
+ colCount: z.number(),
1368
+ })
1369
+ export type PluginSpreadsheetSheetInfo = z.infer<
1370
+ typeof PluginSpreadsheetSheetInfo
1371
+ >
1372
+
1373
+ /**
1374
+ * Result of {@linkcode PluginProgramSpreadsheetApi.listSheets}.
1375
+ *
1376
+ * | Property | Type | Description |
1377
+ * |---|---|---|
1378
+ * | `sheets` | {@linkcode PluginSpreadsheetSheetInfo}`[]` | All sheets in the workbook |
1379
+ * | `activeSheet` | `string \| null` | The active sheet name, or `null` |
1380
+ */
1381
+ export const PluginProgramSpreadsheetListSheetsResult = z.object({
1382
+ sheets: z.array(PluginSpreadsheetSheetInfo),
1383
+ activeSheet: z.string().nullable(),
1384
+ })
1385
+ export type PluginProgramSpreadsheetListSheetsResult = z.infer<
1386
+ typeof PluginProgramSpreadsheetListSheetsResult
1387
+ >
1388
+
1389
+ /**
1390
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.getSheetData}.
1391
+ *
1392
+ * | Property | Type | Description |
1393
+ * |---|---|---|
1394
+ * | `sheetName` | `string` | Sheet to read |
1395
+ * | `range` | `string?` | A1 range; defaults to the sheet's used range |
1396
+ * | `header` | `boolean?` | When `true`, also return records keyed by the first (header) row |
1397
+ */
1398
+ export const PluginProgramSpreadsheetGetSheetDataArgs = z.object({
1399
+ sheetName: z.string(),
1400
+ range: z.string().optional(),
1401
+ header: z.boolean().optional(),
1402
+ })
1403
+ export type PluginProgramSpreadsheetGetSheetDataArgs = z.infer<
1404
+ typeof PluginProgramSpreadsheetGetSheetDataArgs
1405
+ >
1406
+
1407
+ /**
1408
+ * Result of {@linkcode PluginProgramSpreadsheetApi.getSheetData}.
1409
+ *
1410
+ * | Property | Type | Description |
1411
+ * |---|---|---|
1412
+ * | `sheetName` | `string` | The sheet that was read |
1413
+ * | `range` | `string` | A1 range that was read |
1414
+ * | `values` | `cell[][]` | Row-major matrix of cell values |
1415
+ * | `records` | `Record<string, cell>[]?` | Present only when `header` was `true`: rows keyed by header |
1416
+ */
1417
+ export const PluginProgramSpreadsheetGetSheetDataResult = z.object({
1418
+ sheetName: z.string(),
1419
+ range: z.string(),
1420
+ values: z.array(z.array(PluginSpreadsheetCell)),
1421
+ records: z.array(z.record(z.string(), PluginSpreadsheetCell)).optional(),
1422
+ })
1423
+ export type PluginProgramSpreadsheetGetSheetDataResult = z.infer<
1424
+ typeof PluginProgramSpreadsheetGetSheetDataResult
1425
+ >
1426
+
1427
+ /** Chart type for {@linkcode PluginProgramSpreadsheetApi.addChart}. */
1428
+ export const PluginSpreadsheetChartType = z.enum([
1429
+ "column",
1430
+ "bar",
1431
+ "line",
1432
+ "pie",
1433
+ "area",
1434
+ "scatter",
1435
+ ])
1436
+ export type PluginSpreadsheetChartType = z.infer<
1437
+ typeof PluginSpreadsheetChartType
1438
+ >
1439
+
1440
+ /**
1441
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.addChart}.
1442
+ *
1443
+ * | Property | Type | Description |
1444
+ * |---|---|---|
1445
+ * | `sheetName` | `string` | Sheet to add the chart to |
1446
+ * | `chartType` | `"column" \| "bar" \| "line" \| "pie" \| "area" \| "scatter"` | Chart type |
1447
+ * | `dataRange` | `string` | A1 range driving the chart |
1448
+ * | `title` | `string?` | Optional chart title |
1449
+ * | `position` | `{ x; y }?` | Top-left position (sheet coords) |
1450
+ * | `size` | `{ width; height }?` | Chart size in px |
1451
+ */
1452
+ export const PluginProgramSpreadsheetAddChartArgs = z.object({
1453
+ sheetName: z.string(),
1454
+ chartType: PluginSpreadsheetChartType,
1455
+ dataRange: z.string(),
1456
+ title: z.string().optional(),
1457
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
1458
+ size: z.object({ width: z.number(), height: z.number() }).optional(),
1459
+ })
1460
+ export type PluginProgramSpreadsheetAddChartArgs = z.infer<
1461
+ typeof PluginProgramSpreadsheetAddChartArgs
1462
+ >
1463
+
1464
+ /**
1465
+ * Result of {@linkcode PluginProgramSpreadsheetApi.addChart}.
1466
+ *
1467
+ * | Property | Type | Description |
1468
+ * |---|---|---|
1469
+ * | `chartId` | `string` | Id of the created chart |
1470
+ */
1471
+ export const PluginProgramSpreadsheetAddChartResult = z.object({
1472
+ chartId: z.string(),
1473
+ })
1474
+ export type PluginProgramSpreadsheetAddChartResult = z.infer<
1475
+ typeof PluginProgramSpreadsheetAddChartResult
1476
+ >
1477
+
1478
+ /**
1479
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.highlightCells}.
1480
+ *
1481
+ * | Property | Type | Description |
1482
+ * |---|---|---|
1483
+ * | `sheetName` | `string` | Sheet containing the range |
1484
+ * | `range` | `string` | A1 range to highlight |
1485
+ * | `color` | `string?` | CSS hex background color (a default emphasis is used when omitted) |
1486
+ * | `bold` | `boolean?` | Also bold the text |
1487
+ */
1488
+ export const PluginProgramSpreadsheetHighlightCellsArgs = z.object({
1489
+ sheetName: z.string(),
1490
+ range: z.string(),
1491
+ color: z.string().optional(),
1492
+ bold: z.boolean().optional(),
1493
+ })
1494
+ export type PluginProgramSpreadsheetHighlightCellsArgs = z.infer<
1495
+ typeof PluginProgramSpreadsheetHighlightCellsArgs
1496
+ >
1497
+
1498
+ /**
1499
+ * Result of {@linkcode PluginProgramSpreadsheetApi.highlightCells}.
1500
+ *
1501
+ * | Property | Type | Description |
1502
+ * |---|---|---|
1503
+ * | `sheetName` | `string` | The sheet that was highlighted |
1504
+ * | `range` | `string` | The range that was highlighted |
1505
+ */
1506
+ export const PluginProgramSpreadsheetHighlightCellsResult = z.object({
1507
+ sheetName: z.string(),
1508
+ range: z.string(),
1509
+ })
1510
+ export type PluginProgramSpreadsheetHighlightCellsResult = z.infer<
1511
+ typeof PluginProgramSpreadsheetHighlightCellsResult
1512
+ >
1513
+
1514
+ // --- getProgram / getTakeoff dataset reads ---------------------------------
1515
+
1516
+ /**
1517
+ * One department row in the area-program dataset. Areas are in the enclosing
1518
+ * {@linkcode PluginProgramSpreadsheetGetProgramResult}'s `units`. This mirrors
1519
+ * {@linkcode PluginProgramDepartmentMetric}, plus a derived `variance`.
1520
+ *
1521
+ * | Property | Type | Description |
1522
+ * |---|---|---|
1523
+ * | `departmentId` | `string` | Department id |
1524
+ * | `name` | `string` | Department name |
1525
+ * | `targetArea` | `number \| null` | Target area, or `null` if no target is set |
1526
+ * | `allocatedArea` | `number` | Area currently allocated to this department |
1527
+ * | `variance` | `number \| null` | `allocatedArea − targetArea`, or `null` when no target |
1528
+ */
1529
+ export const PluginSpreadsheetProgramRow = z.object({
1530
+ departmentId: z.string(),
1531
+ name: z.string(),
1532
+ targetArea: z.number().nullable(),
1533
+ allocatedArea: z.number(),
1534
+ variance: z.number().nullable(),
1535
+ })
1536
+ export type PluginSpreadsheetProgramRow = z.infer<
1537
+ typeof PluginSpreadsheetProgramRow
1538
+ >
1539
+
1540
+ /**
1541
+ * Result of {@linkcode PluginProgramSpreadsheetApi.getProgram} — the area-program
1542
+ * dataset {@linkcode PluginProgramSpreadsheetApi.renderProgram} draws. For the
1543
+ * canonical summary read, see {@linkcode PluginProgramMetricsApi.get}.
1544
+ *
1545
+ * | Property | Type | Description |
1546
+ * |---|---|---|
1547
+ * | `units` | `"ft2" \| "m2"` | The unit every area in this dataset is reported in |
1548
+ * | `rows` | {@linkcode PluginSpreadsheetProgramRow}`[]` | Per-department program rows |
1549
+ * | `totalTargetArea` | `number` | Sum of all department target areas |
1550
+ * | `totalAllocatedArea` | `number` | Total allocated area |
1551
+ * | `generatedAt` | `string` | ISO timestamp of when the dataset was projected |
1552
+ */
1553
+ export const PluginProgramSpreadsheetGetProgramResult = z.object({
1554
+ units: PluginAreaUnit,
1555
+ rows: z.array(PluginSpreadsheetProgramRow),
1556
+ totalTargetArea: z.number(),
1557
+ totalAllocatedArea: z.number(),
1558
+ generatedAt: z.string(),
1559
+ })
1560
+ export type PluginProgramSpreadsheetGetProgramResult = z.infer<
1561
+ typeof PluginProgramSpreadsheetGetProgramResult
1562
+ >
1563
+
1564
+ /**
1565
+ * One family-aggregated row in the quantity/material takeoff dataset. The takeoff
1566
+ * is grouped by object type + category + family (not per element), so each row is
1567
+ * a rolled-up quantity for that family.
1568
+ *
1569
+ * | Property | Type | Description |
1570
+ * |---|---|---|
1571
+ * | `objectType` | `string` | Element object type (e.g. `"Wall"`, `"Door"`, `"Window"`) |
1572
+ * | `category` | `string` | Element category |
1573
+ * | `family` | `string` | Element family the quantity is aggregated over |
1574
+ * | `quantity` | `number` | Aggregated quantity in `unit` |
1575
+ * | `unit` | `string` | Quantity unit (e.g. `"m"` for length, `"m2"` for area) |
1576
+ */
1577
+ export const PluginSpreadsheetTakeoffRow = z.object({
1578
+ objectType: z.string(),
1579
+ category: z.string(),
1580
+ family: z.string(),
1581
+ quantity: z.number(),
1582
+ unit: z.string(),
1583
+ })
1584
+ export type PluginSpreadsheetTakeoffRow = z.infer<
1585
+ typeof PluginSpreadsheetTakeoffRow
1586
+ >
1587
+
1588
+ /**
1589
+ * Result of {@linkcode PluginProgramSpreadsheetApi.getTakeoff} — the takeoff dataset
1590
+ * {@linkcode PluginProgramSpreadsheetApi.renderTakeoff} draws.
1591
+ *
1592
+ * | Property | Type | Description |
1593
+ * |---|---|---|
1594
+ * | `rows` | {@linkcode PluginSpreadsheetTakeoffRow}`[]` | One row per aggregated object-type/category/family group |
1595
+ * | `rowCount` | `number` | Number of rows |
1596
+ * | `generatedAt` | `string` | ISO timestamp of when the dataset was read |
1597
+ */
1598
+ export const PluginProgramSpreadsheetGetTakeoffResult = z.object({
1599
+ rows: z.array(PluginSpreadsheetTakeoffRow),
1600
+ rowCount: z.number(),
1601
+ generatedAt: z.string(),
1602
+ })
1603
+ export type PluginProgramSpreadsheetGetTakeoffResult = z.infer<
1604
+ typeof PluginProgramSpreadsheetGetTakeoffResult
1605
+ >
1606
+
1607
+ /**
1608
+ * One row in the material take-off dataset. The take-off is grouped by element
1609
+ * object type + family + applied material, so each row is a rolled-up surface
1610
+ * area for that material on that family.
1611
+ *
1612
+ * | Property | Type | Description |
1613
+ * |---|---|---|
1614
+ * | `objectType` | `string` | Element object type the material sits on (`"wall"`, `"floor"`, `"ceiling"`, `"slab"`, `"roof"`) |
1615
+ * | `family` | `string` | Element family the quantity is aggregated under |
1616
+ * | `material` | `string` | Applied material name |
1617
+ * | `quantity` | `number` | Rolled-up surface area in `unit` |
1618
+ * | `unit` | `string` | Area unit (e.g. `"sq.ft"` or `"sq.m"`) |
1619
+ */
1620
+ export const PluginSpreadsheetMaterialTakeoffRow = z.object({
1621
+ objectType: z.string(),
1622
+ family: z.string(),
1623
+ material: z.string(),
1624
+ quantity: z.number(),
1625
+ unit: z.string(),
1626
+ })
1627
+ export type PluginSpreadsheetMaterialTakeoffRow = z.infer<
1628
+ typeof PluginSpreadsheetMaterialTakeoffRow
1629
+ >
1630
+
1631
+ /**
1632
+ * Result of {@linkcode PluginProgramSpreadsheetApi.getMaterialTakeoff} — the native
1633
+ * material take-off dataset (surface area per material). Empty when no materials are
1634
+ * applied.
1635
+ *
1636
+ * | Property | Type | Description |
1637
+ * |---|---|---|
1638
+ * | `rows` | {@linkcode PluginSpreadsheetMaterialTakeoffRow}`[]` | One row per object-type/family/material group |
1639
+ * | `rowCount` | `number` | Number of rows |
1640
+ * | `generatedAt` | `string` | ISO timestamp of when the dataset was read |
1641
+ */
1642
+ export const PluginProgramSpreadsheetGetMaterialTakeoffResult = z.object({
1643
+ rows: z.array(PluginSpreadsheetMaterialTakeoffRow),
1644
+ rowCount: z.number(),
1645
+ generatedAt: z.string(),
1646
+ })
1647
+ export type PluginProgramSpreadsheetGetMaterialTakeoffResult = z.infer<
1648
+ typeof PluginProgramSpreadsheetGetMaterialTakeoffResult
1649
+ >
1650
+
1651
+ // --- createSheet -----------------------------------------------------------
1652
+
1653
+ /** Behaviour when {@linkcode PluginProgramSpreadsheetApi.createSheet} targets an existing sheet name. */
1654
+ export const PluginSpreadsheetWhenExists = z.enum(["reuse", "replace", "error"])
1655
+ export type PluginSpreadsheetWhenExists = z.infer<
1656
+ typeof PluginSpreadsheetWhenExists
1657
+ >
1658
+
1659
+ /**
1660
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.createSheet}.
1661
+ *
1662
+ * | Property | Type | Description |
1663
+ * |---|---|---|
1664
+ * | `name` | `string` | The sheet name to create |
1665
+ * | `whenExists` | `"reuse" \| "replace" \| "error"?` | Behaviour if the name exists (default `"reuse"`) |
1666
+ */
1667
+ export const PluginProgramSpreadsheetCreateSheetArgs = z.object({
1668
+ name: z.string(),
1669
+ whenExists: PluginSpreadsheetWhenExists.optional(),
1670
+ })
1671
+ export type PluginProgramSpreadsheetCreateSheetArgs = z.infer<
1672
+ typeof PluginProgramSpreadsheetCreateSheetArgs
1673
+ >
1674
+
1675
+ /**
1676
+ * Result of {@linkcode PluginProgramSpreadsheetApi.createSheet}.
1677
+ *
1678
+ * | Property | Type | Description |
1679
+ * |---|---|---|
1680
+ * | `sheetName` | `string` | The resolved sheet name |
1681
+ * | `replaced` | `boolean` | Whether an existing sheet was replaced/cleared |
1682
+ * | `sheetIndex` | `number \| null` | Zero-based index of the sheet, or `null` if unknown |
1683
+ */
1684
+ export const PluginProgramSpreadsheetCreateSheetResult = z.object({
1685
+ sheetName: z.string(),
1686
+ replaced: z.boolean(),
1687
+ sheetIndex: z.number().nullable(),
1688
+ })
1689
+ export type PluginProgramSpreadsheetCreateSheetResult = z.infer<
1690
+ typeof PluginProgramSpreadsheetCreateSheetResult
1691
+ >
1692
+
1693
+ // --- setValues -------------------------------------------------------------
1694
+
1695
+ /**
1696
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.setValues}.
1697
+ *
1698
+ * | Property | Type | Description |
1699
+ * |---|---|---|
1700
+ * | `sheetName` | `string` | Sheet to write into |
1701
+ * | `values` | `cell[][]` | Row-major matrix of values to write |
1702
+ * | `startCell` | `string?` | Top-left anchor in A1 notation (default `"A1"`) |
1703
+ */
1704
+ export const PluginProgramSpreadsheetSetValuesArgs = z.object({
1705
+ sheetName: z.string(),
1706
+ values: z.array(z.array(PluginSpreadsheetCell)),
1707
+ startCell: z.string().optional(),
1708
+ })
1709
+ export type PluginProgramSpreadsheetSetValuesArgs = z.infer<
1710
+ typeof PluginProgramSpreadsheetSetValuesArgs
1711
+ >
1712
+
1713
+ /**
1714
+ * Result of {@linkcode PluginProgramSpreadsheetApi.setValues}.
1715
+ *
1716
+ * | Property | Type | Description |
1717
+ * |---|---|---|
1718
+ * | `sheetName` | `string` | The sheet that was written |
1719
+ * | `startCell` | `string` | The anchor cell values were written from |
1720
+ * | `rowCount` | `number` | Number of rows written |
1721
+ * | `colCount` | `number` | Widest row's column count |
1722
+ */
1723
+ export const PluginProgramSpreadsheetSetValuesResult = z.object({
1724
+ sheetName: z.string(),
1725
+ startCell: z.string(),
1726
+ rowCount: z.number(),
1727
+ colCount: z.number(),
1728
+ })
1729
+ export type PluginProgramSpreadsheetSetValuesResult = z.infer<
1730
+ typeof PluginProgramSpreadsheetSetValuesResult
1731
+ >
1732
+
1733
+ // --- setFormulas -----------------------------------------------------------
1734
+
1735
+ /**
1736
+ * A single cell formula for {@linkcode PluginProgramSpreadsheetApi.setFormulas}.
1737
+ *
1738
+ * | Property | Type | Description |
1739
+ * |---|---|---|
1740
+ * | `cell` | `string` | Target cell in A1 notation |
1741
+ * | `formula` | `string` | Formula expression (a leading `=` is optional) |
1742
+ */
1743
+ export const PluginSpreadsheetFormula = z.object({
1744
+ cell: z.string(),
1745
+ formula: z.string(),
1746
+ })
1747
+ export type PluginSpreadsheetFormula = z.infer<typeof PluginSpreadsheetFormula>
1748
+
1749
+ /**
1750
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.setFormulas}.
1751
+ *
1752
+ * | Property | Type | Description |
1753
+ * |---|---|---|
1754
+ * | `sheetName` | `string` | Sheet to set formulas on |
1755
+ * | `formulas` | {@linkcode PluginSpreadsheetFormula}`[]` | The cell → formula assignments |
1756
+ */
1757
+ export const PluginProgramSpreadsheetSetFormulasArgs = z.object({
1758
+ sheetName: z.string(),
1759
+ formulas: z.array(PluginSpreadsheetFormula),
1760
+ })
1761
+ export type PluginProgramSpreadsheetSetFormulasArgs = z.infer<
1762
+ typeof PluginProgramSpreadsheetSetFormulasArgs
1763
+ >
1764
+
1765
+ /**
1766
+ * Result of {@linkcode PluginProgramSpreadsheetApi.setFormulas}.
1767
+ *
1768
+ * | Property | Type | Description |
1769
+ * |---|---|---|
1770
+ * | `sheetName` | `string` | The sheet that was written |
1771
+ * | `count` | `number` | Number of formulas set |
1772
+ */
1773
+ export const PluginProgramSpreadsheetSetFormulasResult = z.object({
1774
+ sheetName: z.string(),
1775
+ count: z.number(),
1776
+ })
1777
+ export type PluginProgramSpreadsheetSetFormulasResult = z.infer<
1778
+ typeof PluginProgramSpreadsheetSetFormulasResult
1779
+ >
1780
+
1781
+ // --- setStyles -------------------------------------------------------------
1782
+
1783
+ /** Font weight for a {@linkcode PluginSpreadsheetCellStyle}. */
1784
+ export const PluginSpreadsheetFontWeight = z.enum(["normal", "bold"])
1785
+ export type PluginSpreadsheetFontWeight = z.infer<
1786
+ typeof PluginSpreadsheetFontWeight
1787
+ >
1788
+
1789
+ /** Font style for a {@linkcode PluginSpreadsheetCellStyle}. */
1790
+ export const PluginSpreadsheetFontStyle = z.enum(["normal", "italic"])
1791
+ export type PluginSpreadsheetFontStyle = z.infer<
1792
+ typeof PluginSpreadsheetFontStyle
1793
+ >
1794
+
1795
+ /** Horizontal cell alignment for a {@linkcode PluginSpreadsheetCellStyle}. */
1796
+ export const PluginSpreadsheetHorizontalAlign = z.enum([
1797
+ "left",
1798
+ "center",
1799
+ "right",
1800
+ "general",
1801
+ ])
1802
+ export type PluginSpreadsheetHorizontalAlign = z.infer<
1803
+ typeof PluginSpreadsheetHorizontalAlign
1804
+ >
1805
+
1806
+ /** Vertical cell alignment for a {@linkcode PluginSpreadsheetCellStyle}. */
1807
+ export const PluginSpreadsheetVerticalAlign = z.enum([
1808
+ "top",
1809
+ "center",
1810
+ "bottom",
1811
+ ])
1812
+ export type PluginSpreadsheetVerticalAlign = z.infer<
1813
+ typeof PluginSpreadsheetVerticalAlign
1814
+ >
1815
+
1816
+ /**
1817
+ * A cell style for {@linkcode PluginProgramSpreadsheetApi.setStyles}. All fields
1818
+ * are optional; only the ones provided are applied.
1819
+ *
1820
+ * | Property | Type | Description |
1821
+ * |---|---|---|
1822
+ * | `backColor` | `string?` | Background (fill) color, CSS hex |
1823
+ * | `foreColor` | `string?` | Text color, CSS hex |
1824
+ * | `font` | `string?` | Full CSS font shorthand (overrides the parts below) |
1825
+ * | `fontFamily` | `string?` | Font family |
1826
+ * | `fontSize` | `number?` | Font size in px |
1827
+ * | `fontWeight` | `"normal" \| "bold"?` | Font weight |
1828
+ * | `fontStyle` | `"normal" \| "italic"?` | Font style |
1829
+ * | `formatter` | `string?` | Number/date format string |
1830
+ * | `horizontalAlign` | `"left" \| "center" \| "right" \| "general"?` | Horizontal alignment |
1831
+ * | `verticalAlign` | `"top" \| "center" \| "bottom"?` | Vertical alignment |
1832
+ */
1833
+ export const PluginSpreadsheetCellStyle = z.object({
1834
+ backColor: z.string().optional(),
1835
+ foreColor: z.string().optional(),
1836
+ font: z.string().optional(),
1837
+ fontFamily: z.string().optional(),
1838
+ fontSize: z.number().optional(),
1839
+ fontWeight: PluginSpreadsheetFontWeight.optional(),
1840
+ fontStyle: PluginSpreadsheetFontStyle.optional(),
1841
+ formatter: z.string().optional(),
1842
+ horizontalAlign: PluginSpreadsheetHorizontalAlign.optional(),
1843
+ verticalAlign: PluginSpreadsheetVerticalAlign.optional(),
1844
+ })
1845
+ export type PluginSpreadsheetCellStyle = z.infer<
1846
+ typeof PluginSpreadsheetCellStyle
1847
+ >
1848
+
1849
+ /**
1850
+ * A range + the style to apply to it, for {@linkcode PluginProgramSpreadsheetApi.setStyles}.
1851
+ *
1852
+ * | Property | Type | Description |
1853
+ * |---|---|---|
1854
+ * | `range` | `string` | A1 range to style |
1855
+ * | `style` | {@linkcode PluginSpreadsheetCellStyle} | The style to apply |
1856
+ */
1857
+ export const PluginSpreadsheetRangeStyle = z.object({
1858
+ range: z.string(),
1859
+ style: PluginSpreadsheetCellStyle,
1860
+ })
1861
+ export type PluginSpreadsheetRangeStyle = z.infer<
1862
+ typeof PluginSpreadsheetRangeStyle
1863
+ >
1864
+
1865
+ /**
1866
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.setStyles}.
1867
+ *
1868
+ * | Property | Type | Description |
1869
+ * |---|---|---|
1870
+ * | `sheetName` | `string` | Sheet containing the ranges |
1871
+ * | `ranges` | {@linkcode PluginSpreadsheetRangeStyle}`[]` | Range → style assignments |
1872
+ */
1873
+ export const PluginProgramSpreadsheetSetStylesArgs = z.object({
1874
+ sheetName: z.string(),
1875
+ ranges: z.array(PluginSpreadsheetRangeStyle),
1876
+ })
1877
+ export type PluginProgramSpreadsheetSetStylesArgs = z.infer<
1878
+ typeof PluginProgramSpreadsheetSetStylesArgs
1879
+ >
1880
+
1881
+ /**
1882
+ * Result of {@linkcode PluginProgramSpreadsheetApi.setStyles}.
1883
+ *
1884
+ * | Property | Type | Description |
1885
+ * |---|---|---|
1886
+ * | `sheetName` | `string` | The sheet that was styled |
1887
+ * | `count` | `number` | Number of ranges styled |
1888
+ */
1889
+ export const PluginProgramSpreadsheetSetStylesResult = z.object({
1890
+ sheetName: z.string(),
1891
+ count: z.number(),
1892
+ })
1893
+ export type PluginProgramSpreadsheetSetStylesResult = z.infer<
1894
+ typeof PluginProgramSpreadsheetSetStylesResult
1895
+ >
1896
+
1897
+ // --- mergeCells ------------------------------------------------------------
1898
+
1899
+ /**
1900
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.mergeCells}.
1901
+ *
1902
+ * | Property | Type | Description |
1903
+ * |---|---|---|
1904
+ * | `sheetName` | `string` | Sheet containing the range |
1905
+ * | `range` | `string` | A1 range to merge into one spanned cell |
1906
+ * | `value` | `cell?` | Optional value to set in the merged (top-left) cell |
1907
+ */
1908
+ export const PluginProgramSpreadsheetMergeCellsArgs = z.object({
1909
+ sheetName: z.string(),
1910
+ range: z.string(),
1911
+ value: PluginSpreadsheetCell.optional(),
1912
+ })
1913
+ export type PluginProgramSpreadsheetMergeCellsArgs = z.infer<
1914
+ typeof PluginProgramSpreadsheetMergeCellsArgs
1915
+ >
1916
+
1917
+ /**
1918
+ * Result of {@linkcode PluginProgramSpreadsheetApi.mergeCells}.
1919
+ *
1920
+ * | Property | Type | Description |
1921
+ * |---|---|---|
1922
+ * | `sheetName` | `string` | The sheet that was merged |
1923
+ * | `range` | `string` | The range that was merged |
1924
+ */
1925
+ export const PluginProgramSpreadsheetMergeCellsResult = z.object({
1926
+ sheetName: z.string(),
1927
+ range: z.string(),
1928
+ })
1929
+ export type PluginProgramSpreadsheetMergeCellsResult = z.infer<
1930
+ typeof PluginProgramSpreadsheetMergeCellsResult
1931
+ >
1932
+
1933
+ // --- addConditionalFormatting ----------------------------------------------
1934
+
1935
+ /** Conditional-formatting rule type. Currently only `dataBar`; more are reserved. */
1936
+ export const PluginSpreadsheetConditionalRuleType = z.enum(["dataBar"])
1937
+ export type PluginSpreadsheetConditionalRuleType = z.infer<
1938
+ typeof PluginSpreadsheetConditionalRuleType
1939
+ >
1940
+
1941
+ /**
1942
+ * A conditional-formatting rule for {@linkcode PluginProgramSpreadsheetApi.addConditionalFormatting}.
1943
+ *
1944
+ * | Property | Type | Description |
1945
+ * |---|---|---|
1946
+ * | `type` | `"dataBar"` | The rule kind (a proportional in-cell bar) |
1947
+ * | `color` | `string?` | Bar color, CSS hex (a default is used when omitted) |
1948
+ */
1949
+ export const PluginSpreadsheetConditionalRule = z.object({
1950
+ type: PluginSpreadsheetConditionalRuleType,
1951
+ color: z.string().optional(),
1952
+ })
1953
+ export type PluginSpreadsheetConditionalRule = z.infer<
1954
+ typeof PluginSpreadsheetConditionalRule
1955
+ >
1956
+
1957
+ /**
1958
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.addConditionalFormatting}.
1959
+ *
1960
+ * | Property | Type | Description |
1961
+ * |---|---|---|
1962
+ * | `sheetName` | `string` | Sheet containing the range |
1963
+ * | `range` | `string` | A1 range to format |
1964
+ * | `rule` | {@linkcode PluginSpreadsheetConditionalRule} | The conditional-format rule |
1965
+ */
1966
+ export const PluginProgramSpreadsheetAddConditionalFormattingArgs = z.object({
1967
+ sheetName: z.string(),
1968
+ range: z.string(),
1969
+ rule: PluginSpreadsheetConditionalRule,
1970
+ })
1971
+ export type PluginProgramSpreadsheetAddConditionalFormattingArgs = z.infer<
1972
+ typeof PluginProgramSpreadsheetAddConditionalFormattingArgs
1973
+ >
1974
+
1975
+ /**
1976
+ * Result of {@linkcode PluginProgramSpreadsheetApi.addConditionalFormatting}.
1977
+ *
1978
+ * | Property | Type | Description |
1979
+ * |---|---|---|
1980
+ * | `sheetName` | `string` | The sheet that was formatted |
1981
+ * | `range` | `string` | The range the rule was applied to |
1982
+ * | `created` | `boolean` | Whether a data-bar rule was created (vs a fallback fill) |
1983
+ */
1984
+ export const PluginProgramSpreadsheetAddConditionalFormattingResult = z.object({
1985
+ sheetName: z.string(),
1986
+ range: z.string(),
1987
+ created: z.boolean(),
1988
+ })
1989
+ export type PluginProgramSpreadsheetAddConditionalFormattingResult = z.infer<
1990
+ typeof PluginProgramSpreadsheetAddConditionalFormattingResult
1991
+ >
1992
+
1993
+ // --- recalculate -----------------------------------------------------------
1994
+
1995
+ /**
1996
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.recalculate}.
1997
+ *
1998
+ * | Property | Type | Description |
1999
+ * |---|---|---|
2000
+ * | `sheetName` | `string?` | A sheet to focus before recalculating; omit for the whole workbook |
2001
+ */
2002
+ export const PluginProgramSpreadsheetRecalculateArgs = z.object({
2003
+ sheetName: z.string().optional(),
2004
+ })
2005
+ export type PluginProgramSpreadsheetRecalculateArgs = z.infer<
2006
+ typeof PluginProgramSpreadsheetRecalculateArgs
2007
+ >
2008
+
2009
+ /**
2010
+ * Result of {@linkcode PluginProgramSpreadsheetApi.recalculate}.
2011
+ *
2012
+ * | Property | Type | Description |
2013
+ * |---|---|---|
2014
+ * | `scope` | `"sheet" \| "workbook"` | Whether a single sheet was focused or the whole workbook |
2015
+ * | `sheetName` | `string \| null` | The focused sheet, or `null` for a workbook-wide recompute |
2016
+ */
2017
+ export const PluginProgramSpreadsheetRecalculateResult = z.object({
2018
+ scope: z.enum(["sheet", "workbook"]),
2019
+ sheetName: z.string().nullable(),
2020
+ })
2021
+ export type PluginProgramSpreadsheetRecalculateResult = z.infer<
2022
+ typeof PluginProgramSpreadsheetRecalculateResult
2023
+ >
2024
+
2025
+ // --- transaction -----------------------------------------------------------
2026
+
2027
+ /** A batchable operation name for {@linkcode PluginProgramSpreadsheetApi.transaction}. */
2028
+ export const PluginSpreadsheetTransactionMethod = z.enum([
2029
+ "createSheet",
2030
+ "setValues",
2031
+ "setFormulas",
2032
+ "setStyles",
2033
+ "mergeCells",
2034
+ ])
2035
+ export type PluginSpreadsheetTransactionMethod = z.infer<
2036
+ typeof PluginSpreadsheetTransactionMethod
2037
+ >
2038
+
2039
+ /**
2040
+ * One operation within a {@linkcode PluginProgramSpreadsheetApi.transaction}.
2041
+ *
2042
+ * | Property | Type | Description |
2043
+ * |---|---|---|
2044
+ * | `method` | {@linkcode PluginSpreadsheetTransactionMethod} | The batchable method to run |
2045
+ * | `args` | `unknown` | The `method`'s own arguments object |
2046
+ */
2047
+ export const PluginSpreadsheetTransactionOp = z.object({
2048
+ method: PluginSpreadsheetTransactionMethod,
2049
+ args: z.unknown(),
2050
+ })
2051
+ export type PluginSpreadsheetTransactionOp = z.infer<
2052
+ typeof PluginSpreadsheetTransactionOp
2053
+ >
2054
+
2055
+ /**
2056
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.transaction}.
2057
+ *
2058
+ * | Property | Type | Description |
2059
+ * |---|---|---|
2060
+ * | `operations` | {@linkcode PluginSpreadsheetTransactionOp}`[]` | The operations to run in order |
2061
+ * | `label` | `string?` | Undo-history label for the batch |
2062
+ */
2063
+ export const PluginProgramSpreadsheetTransactionArgs = z.object({
2064
+ operations: z.array(PluginSpreadsheetTransactionOp),
2065
+ label: z.string().optional(),
2066
+ })
2067
+ export type PluginProgramSpreadsheetTransactionArgs = z.infer<
2068
+ typeof PluginProgramSpreadsheetTransactionArgs
2069
+ >
2070
+
2071
+ /**
2072
+ * Result of {@linkcode PluginProgramSpreadsheetApi.transaction}.
2073
+ *
2074
+ * | Property | Type | Description |
2075
+ * |---|---|---|
2076
+ * | `label` | `string` | The undo-history label used |
2077
+ * | `operationCount` | `number` | Number of operations run |
2078
+ * | `results` | `unknown[]` | Each operation's result, in order |
2079
+ */
2080
+ export const PluginProgramSpreadsheetTransactionResult = z.object({
2081
+ label: z.string(),
2082
+ operationCount: z.number(),
2083
+ results: z.array(z.unknown()),
2084
+ })
2085
+ export type PluginProgramSpreadsheetTransactionResult = z.infer<
2086
+ typeof PluginProgramSpreadsheetTransactionResult
2087
+ >
2088
+
2089
+ // --- runScript -------------------------------------------------------------
2090
+
2091
+ /**
2092
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.runScript}.
2093
+ *
2094
+ * | Property | Type | Description |
2095
+ * |---|---|---|
2096
+ * | `script` | `string` | Script source, run against a sandboxed `workbook` facade |
2097
+ */
2098
+ export const PluginProgramSpreadsheetRunScriptArgs = z.object({
2099
+ script: z.string(),
2100
+ })
2101
+ export type PluginProgramSpreadsheetRunScriptArgs = z.infer<
2102
+ typeof PluginProgramSpreadsheetRunScriptArgs
2103
+ >
2104
+
2105
+ /**
2106
+ * Result of {@linkcode PluginProgramSpreadsheetApi.runScript}.
2107
+ *
2108
+ * | Property | Type | Description |
2109
+ * |---|---|---|
2110
+ * | `result` | `unknown` | The script's return value (`null` when it returns nothing) |
2111
+ */
2112
+ export const PluginProgramSpreadsheetRunScriptResult = z.object({
2113
+ result: z.unknown(),
2114
+ })
2115
+ export type PluginProgramSpreadsheetRunScriptResult = z.infer<
2116
+ typeof PluginProgramSpreadsheetRunScriptResult
2117
+ >
2118
+
2119
+ // --- getAuditLog -----------------------------------------------------------
2120
+
2121
+ /** Status of an audit-log entry. */
2122
+ export const PluginSpreadsheetAuditStatus = z.enum(["success", "error"])
2123
+ export type PluginSpreadsheetAuditStatus = z.infer<
2124
+ typeof PluginSpreadsheetAuditStatus
2125
+ >
2126
+
2127
+ /**
2128
+ * One entry in the program-spreadsheet audit log.
2129
+ *
2130
+ * | Property | Type | Description |
2131
+ * |---|---|---|
2132
+ * | `id` | `string` | Entry id |
2133
+ * | `pluginId` | `string` | Id of the plugin that performed the operation |
2134
+ * | `method` | `string` | The API method invoked |
2135
+ * | `label` | `string?` | Optional operation label |
2136
+ * | `sheetName` | `string?` | The sheet the operation targeted, if any |
2137
+ * | `timestamp` | `string` | ISO timestamp |
2138
+ * | `status` | `"success" \| "error"` | Whether the operation succeeded |
2139
+ * | `summary` | `string?` | Short human-readable summary |
2140
+ */
2141
+ export const PluginSpreadsheetAuditEntry = z.object({
2142
+ id: z.string(),
2143
+ pluginId: z.string(),
2144
+ method: z.string(),
2145
+ label: z.string().optional(),
2146
+ sheetName: z.string().optional(),
2147
+ timestamp: z.string(),
2148
+ status: PluginSpreadsheetAuditStatus,
2149
+ summary: z.string().optional(),
2150
+ })
2151
+ export type PluginSpreadsheetAuditEntry = z.infer<
2152
+ typeof PluginSpreadsheetAuditEntry
2153
+ >
2154
+
2155
+ /**
2156
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.getAuditLog}.
2157
+ *
2158
+ * | Property | Type | Description |
2159
+ * |---|---|---|
2160
+ * | `limit` | `number?` | Max entries to return (clamped 1–100, default 20) |
2161
+ */
2162
+ export const PluginProgramSpreadsheetGetAuditLogArgs = z.object({
2163
+ limit: z.number().optional(),
2164
+ })
2165
+ export type PluginProgramSpreadsheetGetAuditLogArgs = z.infer<
2166
+ typeof PluginProgramSpreadsheetGetAuditLogArgs
2167
+ >
2168
+
2169
+ /**
2170
+ * Result of {@linkcode PluginProgramSpreadsheetApi.getAuditLog}.
2171
+ *
2172
+ * | Property | Type | Description |
2173
+ * |---|---|---|
2174
+ * | `entries` | {@linkcode PluginSpreadsheetAuditEntry}`[]` | Recent audit entries, newest first |
2175
+ */
2176
+ export const PluginProgramSpreadsheetGetAuditLogResult = z.object({
2177
+ entries: z.array(PluginSpreadsheetAuditEntry),
2178
+ })
2179
+ export type PluginProgramSpreadsheetGetAuditLogResult = z.infer<
2180
+ typeof PluginProgramSpreadsheetGetAuditLogResult
2181
+ >
2182
+
2183
+ // --- ping ------------------------------------------------------------------
2184
+
2185
+ /**
2186
+ * Result of {@linkcode PluginProgramSpreadsheetApi.ping}.
2187
+ *
2188
+ * | Property | Type | Description |
2189
+ * |---|---|---|
2190
+ * | `pong` | `boolean` | `true` when the program-mode spreadsheet bridge is reachable |
2191
+ */
2192
+ export const PluginProgramSpreadsheetPingResult = z.object({
2193
+ pong: z.boolean(),
2194
+ })
2195
+ export type PluginProgramSpreadsheetPingResult = z.infer<
2196
+ typeof PluginProgramSpreadsheetPingResult
2197
+ >
2198
+
2199
+ // --- templates.* -----------------------------------------------------------
2200
+
2201
+ /** The visibility scope of a saved template. */
2202
+ export const PluginSpreadsheetTemplateScope = z.enum(["project", "global"])
2203
+ export type PluginSpreadsheetTemplateScope = z.infer<
2204
+ typeof PluginSpreadsheetTemplateScope
2205
+ >
2206
+
2207
+ /**
2208
+ * Arguments for {@linkcode PluginProgramSpreadsheetTemplatesApi.create}.
2209
+ *
2210
+ * | Property | Type | Description |
2211
+ * |---|---|---|
2212
+ * | `name` | `string` | Template name (re-saving the same name overwrites it) |
2213
+ * | `sheetName` | `string` | The source sheet to capture |
2214
+ * | `scope` | `"project" \| "global"?` | Template scope (default `"project"`) |
2215
+ */
2216
+ export const PluginProgramSpreadsheetTemplatesCreateArgs = z.object({
2217
+ name: z.string(),
2218
+ sheetName: z.string(),
2219
+ scope: PluginSpreadsheetTemplateScope.optional(),
2220
+ })
2221
+ export type PluginProgramSpreadsheetTemplatesCreateArgs = z.infer<
2222
+ typeof PluginProgramSpreadsheetTemplatesCreateArgs
2223
+ >
2224
+
2225
+ /**
2226
+ * Result of {@linkcode PluginProgramSpreadsheetTemplatesApi.create}.
2227
+ *
2228
+ * | Property | Type | Description |
2229
+ * |---|---|---|
2230
+ * | `id` | `string` | The new template's id |
2231
+ * | `name` | `string` | The template name |
2232
+ * | `scope` | `"project" \| "global"` | The template scope |
2233
+ * | `sheetName` | `string` | The source sheet captured |
2234
+ */
2235
+ export const PluginProgramSpreadsheetTemplatesCreateResult = z.object({
2236
+ id: z.string(),
2237
+ name: z.string(),
2238
+ scope: PluginSpreadsheetTemplateScope,
2239
+ sheetName: z.string(),
2240
+ })
2241
+ export type PluginProgramSpreadsheetTemplatesCreateResult = z.infer<
2242
+ typeof PluginProgramSpreadsheetTemplatesCreateResult
2243
+ >
2244
+
2245
+ /**
2246
+ * Arguments for {@linkcode PluginProgramSpreadsheetTemplatesApi.apply}.
2247
+ *
2248
+ * | Property | Type | Description |
2249
+ * |---|---|---|
2250
+ * | `name` | `string` | The template to apply |
2251
+ * | `targetSheetName` | `string` | The sheet to create/replace from the template |
2252
+ */
2253
+ export const PluginProgramSpreadsheetTemplatesApplyArgs = z.object({
2254
+ name: z.string(),
2255
+ targetSheetName: z.string(),
2256
+ })
2257
+ export type PluginProgramSpreadsheetTemplatesApplyArgs = z.infer<
2258
+ typeof PluginProgramSpreadsheetTemplatesApplyArgs
2259
+ >
2260
+
2261
+ /**
2262
+ * Result of {@linkcode PluginProgramSpreadsheetTemplatesApi.apply}.
2263
+ *
2264
+ * | Property | Type | Description |
2265
+ * |---|---|---|
2266
+ * | `name` | `string` | The template that was applied |
2267
+ * | `targetSheetName` | `string` | The sheet it was applied to |
2268
+ */
2269
+ export const PluginProgramSpreadsheetTemplatesApplyResult = z.object({
2270
+ name: z.string(),
2271
+ targetSheetName: z.string(),
2272
+ })
2273
+ export type PluginProgramSpreadsheetTemplatesApplyResult = z.infer<
2274
+ typeof PluginProgramSpreadsheetTemplatesApplyResult
2275
+ >
2276
+
2277
+ // --- bindings.* ------------------------------------------------------------
2278
+
2279
+ /**
2280
+ * A binding's data source — the built-in takeoff dataset, or a named plugin
2281
+ * dataset stored via {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
2282
+ *
2283
+ * | Property | Type | Description |
2284
+ * |---|---|---|
2285
+ * | `dataset` | `"takeoff" \| "plugin"` | The dataset kind the binding pulls from |
2286
+ * | `name` | `string` | (`"plugin"` only) The stored dataset's name |
2287
+ */
2288
+ export const PluginSpreadsheetBindingSource = z.discriminatedUnion("dataset", [
2289
+ z.object({ dataset: z.literal("takeoff") }),
2290
+ z.object({ dataset: z.literal("plugin"), name: z.string() }),
2291
+ ])
2292
+ export type PluginSpreadsheetBindingSource = z.infer<
2293
+ typeof PluginSpreadsheetBindingSource
2294
+ >
2295
+
2296
+ /** How a binding refresh writes into its target range. Currently only `replaceRange`. */
2297
+ export const PluginSpreadsheetBindingMode = z.enum(["replaceRange"])
2298
+ export type PluginSpreadsheetBindingMode = z.infer<
2299
+ typeof PluginSpreadsheetBindingMode
2300
+ >
2301
+
2302
+ /**
2303
+ * A binding's target range, for {@linkcode PluginProgramSpreadsheetBindingsApi.create}.
2304
+ *
2305
+ * | Property | Type | Description |
2306
+ * |---|---|---|
2307
+ * | `sheetName` | `string` | The sheet to write into |
2308
+ * | `startCell` | `string?` | Top-left anchor in A1 notation (default `"A1"`) |
2309
+ */
2310
+ export const PluginSpreadsheetBindingTarget = z.object({
2311
+ sheetName: z.string(),
2312
+ startCell: z.string().optional(),
2313
+ })
2314
+ export type PluginSpreadsheetBindingTarget = z.infer<
2315
+ typeof PluginSpreadsheetBindingTarget
2316
+ >
2317
+
2318
+ /**
2319
+ * A stored data binding.
2320
+ *
2321
+ * | Property | Type | Description |
2322
+ * |---|---|---|
2323
+ * | `id` | `string` | Binding id |
2324
+ * | `name` | `string` | Binding name (unique per workbook) |
2325
+ * | `pluginId` | `string` | Id of the plugin that owns the binding |
2326
+ * | `source` | {@linkcode PluginSpreadsheetBindingSource} | The bound dataset |
2327
+ * | `target` | `{ sheetName: string; startCell: string }` | The resolved target range anchor |
2328
+ * | `mode` | {@linkcode PluginSpreadsheetBindingMode} | How a refresh writes into the target |
2329
+ * | `createdAt` | `string` | ISO creation timestamp |
2330
+ * | `updatedAt` | `string` | ISO last-refresh timestamp |
2331
+ */
2332
+ export const PluginSpreadsheetBinding = z.object({
2333
+ id: z.string(),
2334
+ name: z.string(),
2335
+ pluginId: z.string(),
2336
+ source: PluginSpreadsheetBindingSource,
2337
+ target: z.object({
2338
+ sheetName: z.string(),
2339
+ startCell: z.string(),
2340
+ }),
2341
+ mode: PluginSpreadsheetBindingMode,
2342
+ createdAt: z.string(),
2343
+ updatedAt: z.string(),
2344
+ })
2345
+ export type PluginSpreadsheetBinding = z.infer<typeof PluginSpreadsheetBinding>
2346
+
2347
+ /**
2348
+ * The outcome of refreshing a single binding.
2349
+ *
2350
+ * | Property | Type | Description |
2351
+ * |---|---|---|
2352
+ * | `id` | `string` | The refreshed binding's id |
2353
+ * | `name` | `string` | The refreshed binding's name |
2354
+ * | `sheetName` | `string` | The sheet that was rewritten |
2355
+ * | `rowCount` | `number` | Number of rows written |
2356
+ */
2357
+ export const PluginSpreadsheetBindingRefresh = z.object({
2358
+ id: z.string(),
2359
+ name: z.string(),
2360
+ sheetName: z.string(),
2361
+ rowCount: z.number(),
2362
+ })
2363
+ export type PluginSpreadsheetBindingRefresh = z.infer<
2364
+ typeof PluginSpreadsheetBindingRefresh
2365
+ >
2366
+
2367
+ /**
2368
+ * Arguments for {@linkcode PluginProgramSpreadsheetBindingsApi.create}.
2369
+ *
2370
+ * | Property | Type | Description |
2371
+ * |---|---|---|
2372
+ * | `name` | `string` | Binding name (re-using a name overwrites it) |
2373
+ * | `source` | {@linkcode PluginSpreadsheetBindingSource} | The dataset to bind |
2374
+ * | `target` | {@linkcode PluginSpreadsheetBindingTarget} | The target sheet range |
2375
+ * | `mode` | {@linkcode PluginSpreadsheetBindingMode}`?` | How a refresh writes (default `"replaceRange"`) |
2376
+ */
2377
+ export const PluginProgramSpreadsheetBindingsCreateArgs = z.object({
2378
+ name: z.string(),
2379
+ source: PluginSpreadsheetBindingSource,
2380
+ target: PluginSpreadsheetBindingTarget,
2381
+ mode: PluginSpreadsheetBindingMode.optional(),
2382
+ })
2383
+ export type PluginProgramSpreadsheetBindingsCreateArgs = z.infer<
2384
+ typeof PluginProgramSpreadsheetBindingsCreateArgs
2385
+ >
2386
+
2387
+ /**
2388
+ * Result of {@linkcode PluginProgramSpreadsheetBindingsApi.create} — the stored
2389
+ * {@linkcode PluginSpreadsheetBinding} plus the initial `refresh` outcome.
2390
+ */
2391
+ export const PluginProgramSpreadsheetBindingsCreateResult =
2392
+ PluginSpreadsheetBinding.extend({
2393
+ refresh: PluginSpreadsheetBindingRefresh,
2394
+ })
2395
+ export type PluginProgramSpreadsheetBindingsCreateResult = z.infer<
2396
+ typeof PluginProgramSpreadsheetBindingsCreateResult
2397
+ >
2398
+
2399
+ /**
2400
+ * Arguments for {@linkcode PluginProgramSpreadsheetBindingsApi.refresh}.
2401
+ *
2402
+ * | Property | Type | Description |
2403
+ * |---|---|---|
2404
+ * | `name` | `string?` | The binding to refresh; omit to refresh every binding |
2405
+ */
2406
+ export const PluginProgramSpreadsheetBindingsRefreshArgs = z.object({
2407
+ name: z.string().optional(),
2408
+ })
2409
+ export type PluginProgramSpreadsheetBindingsRefreshArgs = z.infer<
2410
+ typeof PluginProgramSpreadsheetBindingsRefreshArgs
2411
+ >
2412
+
2413
+ /**
2414
+ * Result of {@linkcode PluginProgramSpreadsheetBindingsApi.refresh}.
2415
+ *
2416
+ * | Property | Type | Description |
2417
+ * |---|---|---|
2418
+ * | `refreshed` | {@linkcode PluginSpreadsheetBindingRefresh}`[]` | One entry per binding refreshed |
2419
+ */
2420
+ export const PluginProgramSpreadsheetBindingsRefreshResult = z.object({
2421
+ refreshed: z.array(PluginSpreadsheetBindingRefresh),
2422
+ })
2423
+ export type PluginProgramSpreadsheetBindingsRefreshResult = z.infer<
2424
+ typeof PluginProgramSpreadsheetBindingsRefreshResult
2425
+ >
2426
+
2427
+ /**
2428
+ * Result of {@linkcode PluginProgramSpreadsheetBindingsApi.list}.
2429
+ *
2430
+ * | Property | Type | Description |
2431
+ * |---|---|---|
2432
+ * | `bindings` | {@linkcode PluginSpreadsheetBinding}`[]` | Every stored binding |
2433
+ */
2434
+ export const PluginProgramSpreadsheetBindingsListResult = z.object({
2435
+ bindings: z.array(PluginSpreadsheetBinding),
2436
+ })
2437
+ export type PluginProgramSpreadsheetBindingsListResult = z.infer<
2438
+ typeof PluginProgramSpreadsheetBindingsListResult
2439
+ >
2440
+
2441
+ // --- datasets.* ------------------------------------------------------------
2442
+
2443
+ /**
2444
+ * Arguments for {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
2445
+ *
2446
+ * | Property | Type | Description |
2447
+ * |---|---|---|
2448
+ * | `name` | `string` | Dataset name (re-using a name overwrites it) |
2449
+ * | `columns` | {@linkcode PluginSpreadsheetColumn}`[]` | Column definitions (at least one) |
2450
+ * | `rows` | `Record<string, cell>[]` | Row objects keyed by column `key` (max 10,000) |
2451
+ */
2452
+ export const PluginProgramSpreadsheetDatasetsSetArgs = z.object({
2453
+ name: z.string(),
2454
+ columns: z.array(PluginSpreadsheetColumn).min(1),
2455
+ rows: z.array(z.record(z.string(), PluginSpreadsheetCell)).max(10_000),
2456
+ })
2457
+ export type PluginProgramSpreadsheetDatasetsSetArgs = z.infer<
2458
+ typeof PluginProgramSpreadsheetDatasetsSetArgs
2459
+ >
2460
+
2461
+ /**
2462
+ * Result of {@linkcode PluginProgramSpreadsheetDatasetsApi.set}.
2463
+ *
2464
+ * | Property | Type | Description |
2465
+ * |---|---|---|
2466
+ * | `name` | `string` | The stored dataset's name |
2467
+ * | `rowCount` | `number` | Number of rows stored |
2468
+ */
2469
+ export const PluginProgramSpreadsheetDatasetsSetResult = z.object({
2470
+ name: z.string(),
2471
+ rowCount: z.number(),
2472
+ })
2473
+ export type PluginProgramSpreadsheetDatasetsSetResult = z.infer<
2474
+ typeof PluginProgramSpreadsheetDatasetsSetResult
2475
+ >
2476
+
2477
+ /**
2478
+ * A stored plugin dataset's summary, for
2479
+ * {@linkcode PluginProgramSpreadsheetDatasetsApi.list}.
2480
+ *
2481
+ * | Property | Type | Description |
2482
+ * |---|---|---|
2483
+ * | `name` | `string` | Dataset name |
2484
+ * | `rowCount` | `number` | Number of rows stored |
2485
+ * | `updatedAt` | `string` | ISO timestamp of the last `set` |
2486
+ */
2487
+ export const PluginSpreadsheetDataset = z.object({
2488
+ name: z.string(),
2489
+ rowCount: z.number(),
2490
+ updatedAt: z.string(),
2491
+ })
2492
+ export type PluginSpreadsheetDataset = z.infer<typeof PluginSpreadsheetDataset>
2493
+
2494
+ /**
2495
+ * Result of {@linkcode PluginProgramSpreadsheetDatasetsApi.list}.
2496
+ *
2497
+ * | Property | Type | Description |
2498
+ * |---|---|---|
2499
+ * | `datasets` | {@linkcode PluginSpreadsheetDataset}`[]` | Every stored dataset |
2500
+ */
2501
+ export const PluginProgramSpreadsheetDatasetsListResult = z.object({
2502
+ datasets: z.array(PluginSpreadsheetDataset),
2503
+ })
2504
+ export type PluginProgramSpreadsheetDatasetsListResult = z.infer<
2505
+ typeof PluginProgramSpreadsheetDatasetsListResult
2506
+ >
2507
+
2508
+ // --- addImage --------------------------------------------------------------
2509
+
2510
+ /**
2511
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.addImage}.
2512
+ *
2513
+ * | Property | Type | Description |
2514
+ * |---|---|---|
2515
+ * | `sheetName` | `string` | Sheet to place the image on |
2516
+ * | `image` | `{ dataUri: string }` | Base64 `data:image/png\|jpeg\|svg+xml` URI (max 2 MB; URLs rejected) |
2517
+ * | `anchorCell` | `string?` | Anchor cell in A1 notation (default `"A1"`) |
2518
+ * | `size` | `{ width; height }?` | Size in px; intrinsic size when omitted |
2519
+ * | `name` | `string?` | Stable picture id — same name replaces on rerun; generated when omitted |
2520
+ */
2521
+ export const PluginProgramSpreadsheetAddImageArgs = z.object({
2522
+ sheetName: z.string(),
2523
+ image: z.object({
2524
+ dataUri: z
2525
+ .string()
2526
+ .max(2_097_152, "image.dataUri exceeds the 2 MB limit")
2527
+ .regex(
2528
+ /^data:image\/(png|jpeg|svg\+xml);base64,/,
2529
+ "image.dataUri must be a base64 data:image/png, jpeg, or svg+xml URI",
2530
+ ),
2531
+ }),
2532
+ anchorCell: z.string().optional(),
2533
+ size: z.object({ width: z.number(), height: z.number() }).optional(),
2534
+ name: z.string().optional(),
2535
+ })
2536
+ export type PluginProgramSpreadsheetAddImageArgs = z.infer<
2537
+ typeof PluginProgramSpreadsheetAddImageArgs
2538
+ >
2539
+
2540
+ /**
2541
+ * Result of {@linkcode PluginProgramSpreadsheetApi.addImage}.
2542
+ *
2543
+ * | Property | Type | Description |
2544
+ * |---|---|---|
2545
+ * | `sheetName` | `string` | The sheet the image was placed on |
2546
+ * | `name` | `string` | The picture's (stable or generated) name |
2547
+ */
2548
+ export const PluginProgramSpreadsheetAddImageResult = z.object({
2549
+ sheetName: z.string(),
2550
+ name: z.string(),
2551
+ })
2552
+ export type PluginProgramSpreadsheetAddImageResult = z.infer<
2553
+ typeof PluginProgramSpreadsheetAddImageResult
2554
+ >
2555
+
2556
+ /**
2557
+ * A custom program sheet's configuration — the grouped, data-bound program view
2558
+ * created by {@linkcode PluginProgramSpreadsheetApi.createCustomSheet}.
2559
+ *
2560
+ * | Property | Type | Description |
2561
+ * |---|---|---|
2562
+ * | `sheetName` | `string` | The sheet's name |
2563
+ * | `groupBy` | `string[]` | Group-by hierarchy, outermost first (property ids); `[]` when ungrouped |
2564
+ * | `properties` | `string[]` | Column property ids in column order (`""` marks an unassigned column) |
2565
+ * | `groupColors` | `Record<string, string>` | Property id → CSS hex fill of that level's group headers |
2566
+ * | `proposalId` | `string \| null` | The proposal the sheet belongs to, or `null` when the project has none |
2567
+ */
2568
+ export const PluginSpreadsheetCustomSheet = z.object({
2569
+ sheetName: z.string(),
2570
+ groupBy: z.array(z.string()),
2571
+ properties: z.array(z.string()),
2572
+ groupColors: z.record(z.string(), z.string()),
2573
+ proposalId: z.string().nullable(),
2574
+ })
2575
+ export type PluginSpreadsheetCustomSheet = z.infer<
2576
+ typeof PluginSpreadsheetCustomSheet
2577
+ >
2578
+
2579
+ /**
2580
+ * The configurable part of a custom program sheet, for
2581
+ * {@linkcode PluginProgramSpreadsheetApi.createCustomSheet} /
2582
+ * {@linkcode PluginProgramSpreadsheetApi.updateCustomSheet}. All fields optional.
2583
+ *
2584
+ * | Property | Type | Description |
2585
+ * |---|---|---|
2586
+ * | `groupBy` | `string[]?` | Group-by hierarchy, outermost first (property ids) |
2587
+ * | `properties` | `string[]?` | Column property ids, in order |
2588
+ * | `groupColors` | `Record<string, string>?` | Property id → CSS hex fill for that level's group headers |
2589
+ */
2590
+ export const PluginSpreadsheetCustomSheetConfig = z.object({
2591
+ groupBy: z.array(z.string().trim().min(1)).max(10).optional(),
2592
+ properties: z.array(z.string()).max(50).optional(),
2593
+ groupColors: z.record(z.string(), z.string()).optional(),
2594
+ })
2595
+ export type PluginSpreadsheetCustomSheetConfig = z.infer<
2596
+ typeof PluginSpreadsheetCustomSheetConfig
2597
+ >
2598
+
2599
+ /**
2600
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.createCustomSheet}.
2601
+ *
2602
+ * | Property | Type | Description |
2603
+ * |---|---|---|
2604
+ * | `name` | `string` | The sheet name to create |
2605
+ * | `groupBy` / `properties` / `groupColors` | — | See {@linkcode PluginSpreadsheetCustomSheetConfig} |
2606
+ */
2607
+ export const PluginProgramSpreadsheetCreateCustomSheetArgs =
2608
+ PluginSpreadsheetCustomSheetConfig.extend({
2609
+ name: z.string().trim().min(1),
2610
+ })
2611
+ export type PluginProgramSpreadsheetCreateCustomSheetArgs = z.infer<
2612
+ typeof PluginProgramSpreadsheetCreateCustomSheetArgs
2613
+ >
2614
+
2615
+ /**
2616
+ * Arguments for {@linkcode PluginProgramSpreadsheetApi.updateCustomSheet}.
2617
+ *
2618
+ * | Property | Type | Description |
2619
+ * |---|---|---|
2620
+ * | `sheetName` | `string` | The custom sheet to update |
2621
+ * | `groupBy` / `properties` / `groupColors` | — | Sparse; see {@linkcode PluginSpreadsheetCustomSheetConfig} |
2622
+ */
2623
+ export const PluginProgramSpreadsheetUpdateCustomSheetArgs =
2624
+ PluginSpreadsheetCustomSheetConfig.extend({
2625
+ sheetName: z.string().trim().min(1),
2626
+ })
2627
+ export type PluginProgramSpreadsheetUpdateCustomSheetArgs = z.infer<
2628
+ typeof PluginProgramSpreadsheetUpdateCustomSheetArgs
2629
+ >
2630
+
2631
+ /** Result of `createCustomSheet` / `updateCustomSheet` — the sheet's configuration. */
2632
+ export const PluginProgramSpreadsheetCustomSheetResult = PluginSpreadsheetCustomSheet
2633
+ export type PluginProgramSpreadsheetCustomSheetResult = z.infer<
2634
+ typeof PluginProgramSpreadsheetCustomSheetResult
2635
+ >
2636
+
2637
+ /** Arguments for {@linkcode PluginProgramSpreadsheetApi.getCustomSheet}. */
2638
+ export const PluginProgramSpreadsheetGetCustomSheetArgs = z.object({
2639
+ sheetName: z.string().trim().min(1),
2640
+ })
2641
+ export type PluginProgramSpreadsheetGetCustomSheetArgs = z.infer<
2642
+ typeof PluginProgramSpreadsheetGetCustomSheetArgs
2643
+ >
2644
+
2645
+ /** Result of {@linkcode PluginProgramSpreadsheetApi.getCustomSheet} — the configuration, or `null`. */
2646
+ export const PluginProgramSpreadsheetGetCustomSheetResult =
2647
+ PluginSpreadsheetCustomSheet.nullable()
2648
+ export type PluginProgramSpreadsheetGetCustomSheetResult = z.infer<
2649
+ typeof PluginProgramSpreadsheetGetCustomSheetResult
2650
+ >
2651
+
2652
+ /**
2653
+ * Result of {@linkcode PluginProgramSpreadsheetApi.listCustomSheets}.
2654
+ *
2655
+ * | Property | Type | Description |
2656
+ * |---|---|---|
2657
+ * | `sheets` | {@linkcode PluginSpreadsheetCustomSheet}`[]` | Every custom program sheet |
2658
+ */
2659
+ export const PluginProgramSpreadsheetListCustomSheetsResult = z.object({
2660
+ sheets: z.array(PluginSpreadsheetCustomSheet),
2661
+ })
2662
+ export type PluginProgramSpreadsheetListCustomSheetsResult = z.infer<
2663
+ typeof PluginProgramSpreadsheetListCustomSheetsResult
2664
+ >
2665
+
2666
+ /**
2667
+ * A property a custom program sheet can show or group by.
2668
+ *
2669
+ * | Property | Type | Description |
2670
+ * |---|---|---|
2671
+ * | `id` | `string` | Property id (built-in key, or a metadata `headerId`) |
2672
+ * | `name` | `string` | Display name |
2673
+ * | `groupable` | `boolean` | Whether the sheet can group by it |
2674
+ * | `custom` | `boolean` | `true` for program metadata headers, `false` for built-ins |
2675
+ */
2676
+ export const PluginSpreadsheetCustomSheetProperty = z.object({
2677
+ id: z.string(),
2678
+ name: z.string(),
2679
+ groupable: z.boolean(),
2680
+ custom: z.boolean(),
2681
+ })
2682
+ export type PluginSpreadsheetCustomSheetProperty = z.infer<
2683
+ typeof PluginSpreadsheetCustomSheetProperty
2684
+ >
2685
+
2686
+ /**
2687
+ * Result of {@linkcode PluginProgramSpreadsheetApi.listCustomSheetProperties}.
2688
+ *
2689
+ * | Property | Type | Description |
2690
+ * |---|---|---|
2691
+ * | `properties` | {@linkcode PluginSpreadsheetCustomSheetProperty}`[]` | Built-ins first, then metadata headers |
2692
+ */
2693
+ export const PluginProgramSpreadsheetListCustomSheetPropertiesResult = z.object({
2694
+ properties: z.array(PluginSpreadsheetCustomSheetProperty),
2695
+ })
2696
+ export type PluginProgramSpreadsheetListCustomSheetPropertiesResult = z.infer<
2697
+ typeof PluginProgramSpreadsheetListCustomSheetPropertiesResult
2698
+ >