@svgrid/enterprise 2.5.3 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (624) hide show
  1. package/dist/SvAlertRuleEditor.svelte.d.ts +13 -0
  2. package/dist/SvAlertsManager.svelte.d.ts +14 -0
  3. package/dist/SvAlertsPanel.svelte.d.ts +9 -0
  4. package/dist/SvAuthGate.svelte.d.ts +22 -0
  5. package/dist/SvBoard.svelte.d.ts +35 -0
  6. package/dist/SvExportMenu.svelte.d.ts +61 -0
  7. package/{src → dist}/SvExpressionEditor.svelte +4 -1
  8. package/dist/SvExpressionEditor.svelte.d.ts +12 -0
  9. package/dist/SvFileInput.svelte.d.ts +20 -0
  10. package/dist/SvGridAlerts.svelte.d.ts +77 -0
  11. package/dist/SvGridBoard.svelte.d.ts +30 -0
  12. package/{src → dist}/SvGridEditPanel.svelte +173 -28
  13. package/dist/SvGridEditPanel.svelte.d.ts +75 -0
  14. package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
  15. package/dist/SvGridScheduler.svelte.d.ts +30 -0
  16. package/dist/SvImportDialog.svelte.d.ts +88 -0
  17. package/dist/SvLookupInput.svelte.d.ts +21 -0
  18. package/dist/SvPivotDesigner.svelte.d.ts +176 -0
  19. package/dist/SvRecordDetail.svelte.d.ts +58 -0
  20. package/dist/SvSchedule.svelte.d.ts +29 -0
  21. package/dist/SvSchemaChart.svelte.d.ts +61 -0
  22. package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
  23. package/dist/alerts/alert-engine-attach.d.ts +79 -0
  24. package/dist/alerts/alert-engine-attach.js +106 -0
  25. package/dist/alerts/alert-engine.d.ts +42 -0
  26. package/dist/alerts/alert-engine.js +196 -0
  27. package/dist/alerts/alert-formats.d.ts +26 -0
  28. package/dist/alerts/alert-formats.js +58 -0
  29. package/dist/alerts/alert-observer.d.ts +54 -0
  30. package/dist/alerts/alert-observer.js +156 -0
  31. package/dist/alerts/alert-scheduler.d.ts +30 -0
  32. package/dist/alerts/alert-scheduler.js +54 -0
  33. package/dist/alerts/alert-storage.d.ts +31 -0
  34. package/dist/alerts/alert-storage.js +92 -0
  35. package/dist/alerts/alert-store.svelte.d.ts +24 -0
  36. package/dist/alerts/alert-store.svelte.js +69 -0
  37. package/dist/alerts/alert-types.d.ts +86 -0
  38. package/dist/alerts/alert-types.js +1 -0
  39. package/dist/alerts.d.ts +2 -0
  40. package/{src/alerts.ts → dist/alerts.js} +9 -9
  41. package/dist/board.d.ts +7 -0
  42. package/{src/board.ts → dist/board.js} +13 -14
  43. package/dist/cdn/svgrid-enterprise.svelte-external.js +3220 -2607
  44. package/dist/designer/assets/index-BfzoL904.css +1 -0
  45. package/dist/designer/assets/{index-CBYU-KNn.js → index-CKdwDseq.js} +139 -139
  46. package/dist/designer/assets/src-DCKhP5Xy.css +1 -0
  47. package/dist/designer/assets/{src-i309BeJb.js → src-DLsSdh3J.js} +213 -193
  48. package/dist/designer/index.html +4 -4
  49. package/dist/edit-panel.d.ts +105 -0
  50. package/dist/edit-panel.js +350 -0
  51. package/dist/export-conditional.d.ts +31 -0
  52. package/dist/export-conditional.js +65 -0
  53. package/dist/export-ooxml.d.ts +93 -0
  54. package/dist/export-ooxml.js +385 -0
  55. package/dist/export-pdf.d.ts +107 -0
  56. package/dist/export-pdf.js +144 -0
  57. package/dist/export-print.d.ts +55 -0
  58. package/dist/export-print.js +91 -0
  59. package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
  60. package/dist/export-serialize.js +11 -0
  61. package/dist/export-xls.d.ts +26 -0
  62. package/dist/export-xls.js +157 -0
  63. package/dist/export.d.ts +323 -0
  64. package/dist/export.js +1021 -0
  65. package/dist/expressions/evaluate.d.ts +17 -0
  66. package/dist/expressions/evaluate.js +214 -0
  67. package/dist/expressions/expression-columns.d.ts +61 -0
  68. package/dist/expressions/expression-columns.js +72 -0
  69. package/dist/expressions/expression-types.d.ts +125 -0
  70. package/dist/expressions/expression-types.js +1 -0
  71. package/dist/expressions/parse.d.ts +25 -0
  72. package/dist/expressions/parse.js +537 -0
  73. package/dist/import.d.ts +232 -0
  74. package/dist/import.js +846 -0
  75. package/dist/index.d.ts +66 -0
  76. package/dist/index.js +91 -0
  77. package/dist/install.d.ts +70 -0
  78. package/dist/install.js +61 -0
  79. package/dist/license-core.d.ts +37 -0
  80. package/dist/license-core.js +81 -0
  81. package/dist/license.d.ts +30 -0
  82. package/dist/license.js +139 -0
  83. package/dist/master-detail.d.ts +23 -0
  84. package/dist/master-detail.js +35 -0
  85. package/dist/node/studio.js +683 -13
  86. package/dist/pivot-chart.d.ts +28 -0
  87. package/dist/pivot-chart.js +71 -0
  88. package/dist/pivot-designer.d.ts +69 -0
  89. package/dist/pivot-designer.js +38 -0
  90. package/dist/pivot-enable.d.ts +6 -0
  91. package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
  92. package/dist/pivot.d.ts +111 -0
  93. package/dist/pivot.js +353 -0
  94. package/dist/print.d.ts +33 -0
  95. package/dist/print.js +61 -0
  96. package/dist/revoked.d.ts +1 -0
  97. package/{src/revoked.ts → dist/revoked.js} +5 -6
  98. package/dist/scheduler-assignments.d.ts +64 -0
  99. package/dist/scheduler-assignments.js +92 -0
  100. package/dist/scheduler-axis.d.ts +81 -0
  101. package/dist/scheduler-axis.js +180 -0
  102. package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
  103. package/dist/scheduler-booking.js +50 -0
  104. package/dist/scheduler-config.d.ts +177 -0
  105. package/dist/scheduler-config.js +1 -0
  106. package/dist/scheduler-dependencies.d.ts +89 -0
  107. package/dist/scheduler-dependencies.js +179 -0
  108. package/dist/scheduler-freebusy.d.ts +19 -0
  109. package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
  110. package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
  111. package/dist/scheduler-heatmap.js +41 -0
  112. package/dist/scheduler-resource-tree.d.ts +48 -0
  113. package/dist/scheduler-resource-tree.js +78 -0
  114. package/dist/scheduler-slots.d.ts +37 -0
  115. package/dist/scheduler-slots.js +80 -0
  116. package/dist/scheduler-summary.d.ts +41 -0
  117. package/dist/scheduler-summary.js +54 -0
  118. package/dist/scheduler.d.ts +7 -0
  119. package/{src/scheduler.ts → dist/scheduler.js} +13 -14
  120. package/dist/scheduling.d.ts +132 -0
  121. package/dist/scheduling.js +228 -0
  122. package/dist/schema-designer.d.ts +42 -0
  123. package/dist/schema-designer.js +117 -0
  124. package/dist/schema.d.ts +408 -0
  125. package/dist/schema.js +225 -0
  126. package/dist/smart-shim.d.ts +62 -0
  127. package/dist/smart-shim.js +34 -0
  128. package/dist/sources/aggregate.d.ts +43 -0
  129. package/dist/sources/aggregate.js +60 -0
  130. package/dist/sources/auth-supabase.d.ts +69 -0
  131. package/dist/sources/auth-supabase.js +39 -0
  132. package/dist/sources/dashboard.d.ts +65 -0
  133. package/dist/sources/dashboard.js +95 -0
  134. package/dist/sources/field-inference.d.ts +23 -0
  135. package/dist/sources/field-inference.js +52 -0
  136. package/dist/sources/filters.d.ts +35 -0
  137. package/dist/sources/filters.js +52 -0
  138. package/dist/sources/index.d.ts +18 -0
  139. package/dist/sources/index.js +18 -0
  140. package/dist/sources/introspect-supabase.d.ts +30 -0
  141. package/dist/sources/introspect-supabase.js +134 -0
  142. package/dist/sources/realtime-supabase.d.ts +37 -0
  143. package/dist/sources/realtime-supabase.js +52 -0
  144. package/dist/sources/relation-lookup.d.ts +50 -0
  145. package/dist/sources/relation-lookup.js +77 -0
  146. package/dist/sources/rest-adapters.d.ts +48 -0
  147. package/dist/sources/rest-adapters.js +85 -0
  148. package/dist/sources/rest.d.ts +38 -0
  149. package/dist/sources/rest.js +86 -0
  150. package/dist/sources/schema-from-columns.d.ts +37 -0
  151. package/dist/sources/schema-from-columns.js +48 -0
  152. package/dist/sources/supabase.d.ts +33 -0
  153. package/dist/sources/supabase.js +74 -0
  154. package/dist/sources/with-entity-rules.d.ts +25 -0
  155. package/dist/sources/with-entity-rules.js +47 -0
  156. package/dist/sources/with-relation-labels.d.ts +26 -0
  157. package/dist/sources/with-relation-labels.js +38 -0
  158. package/dist/staged-editing.d.ts +85 -0
  159. package/dist/staged-editing.js +0 -0
  160. package/dist/studio/bug-report.d.ts +61 -0
  161. package/dist/studio/bug-report.js +126 -0
  162. package/dist/studio/cli.d.ts +56 -0
  163. package/dist/studio/cli.js +70 -0
  164. package/dist/studio/copilot-core.d.ts +22 -0
  165. package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
  166. package/dist/studio/csv.d.ts +36 -0
  167. package/dist/studio/csv.js +173 -0
  168. package/dist/studio/db-connect-string.d.ts +45 -0
  169. package/dist/studio/db-connect-string.js +113 -0
  170. package/dist/studio/deploy-cli.d.ts +35 -0
  171. package/dist/studio/deploy-cli.js +81 -0
  172. package/dist/studio/emit-project.d.ts +77 -0
  173. package/dist/studio/emit-project.js +5463 -0
  174. package/dist/studio/emit-schema.d.ts +110 -0
  175. package/dist/studio/emit-schema.js +1128 -0
  176. package/dist/studio/index.d.ts +35 -0
  177. package/dist/studio/index.js +41 -0
  178. package/dist/studio/init-flow.d.ts +58 -0
  179. package/dist/studio/init-flow.js +451 -0
  180. package/dist/studio/introspect-db.d.ts +47 -0
  181. package/dist/studio/introspect-db.js +255 -0
  182. package/dist/studio/introspect-openapi.d.ts +19 -0
  183. package/dist/studio/introspect-openapi.js +244 -0
  184. package/dist/studio/introspect-prisma.d.ts +25 -0
  185. package/dist/studio/introspect-prisma.js +164 -0
  186. package/dist/studio/introspect.d.ts +35 -0
  187. package/dist/studio/introspect.js +306 -0
  188. package/dist/studio/project.d.ts +1448 -0
  189. package/dist/studio/project.js +2187 -0
  190. package/dist/studio/sample-data.d.ts +19 -0
  191. package/dist/studio/sample-data.js +207 -0
  192. package/dist/studio/samples/ats.d.ts +2 -0
  193. package/dist/studio/samples/ats.js +194 -0
  194. package/dist/studio/samples/clinic.d.ts +2 -0
  195. package/dist/studio/samples/clinic.js +171 -0
  196. package/dist/studio/samples/crm.d.ts +2 -0
  197. package/dist/studio/samples/crm.js +280 -0
  198. package/dist/studio/samples/datasets.d.ts +38 -0
  199. package/dist/studio/samples/datasets.js +296 -0
  200. package/dist/studio/samples/ecommerce.d.ts +2 -0
  201. package/dist/studio/samples/ecommerce.js +178 -0
  202. package/dist/studio/samples/events.d.ts +2 -0
  203. package/dist/studio/samples/events.js +192 -0
  204. package/dist/studio/samples/fleet.d.ts +2 -0
  205. package/dist/studio/samples/fleet.js +203 -0
  206. package/dist/studio/samples/gym.d.ts +2 -0
  207. package/dist/studio/samples/gym.js +205 -0
  208. package/dist/studio/samples/hr.d.ts +2 -0
  209. package/dist/studio/samples/hr.js +186 -0
  210. package/dist/studio/samples/index.d.ts +13 -0
  211. package/dist/studio/samples/index.js +44 -0
  212. package/dist/studio/samples/insurance.d.ts +2 -0
  213. package/dist/studio/samples/insurance.js +220 -0
  214. package/dist/studio/samples/inventory.d.ts +2 -0
  215. package/dist/studio/samples/inventory.js +204 -0
  216. package/dist/studio/samples/invoicing.d.ts +2 -0
  217. package/dist/studio/samples/invoicing.js +154 -0
  218. package/dist/studio/samples/library.d.ts +2 -0
  219. package/dist/studio/samples/library.js +171 -0
  220. package/dist/studio/samples/live-data.d.ts +5 -0
  221. package/dist/studio/samples/live-data.js +261 -0
  222. package/dist/studio/samples/projects.d.ts +2 -0
  223. package/dist/studio/samples/projects.js +203 -0
  224. package/dist/studio/samples/realestate.d.ts +2 -0
  225. package/dist/studio/samples/realestate.js +187 -0
  226. package/dist/studio/samples/restaurant.d.ts +2 -0
  227. package/dist/studio/samples/restaurant.js +180 -0
  228. package/dist/studio/samples/school.d.ts +2 -0
  229. package/dist/studio/samples/school.js +188 -0
  230. package/dist/studio/samples/shared.d.ts +142 -0
  231. package/dist/studio/samples/shared.js +164 -0
  232. package/dist/studio/samples/starter.d.ts +4 -0
  233. package/dist/studio/samples/starter.js +237 -0
  234. package/dist/studio/samples/subscriptions.d.ts +2 -0
  235. package/dist/studio/samples/subscriptions.js +175 -0
  236. package/dist/studio/samples/support.d.ts +2 -0
  237. package/dist/studio/samples/support.js +209 -0
  238. package/dist/studio/scaffold-app.d.ts +22 -0
  239. package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
  240. package/dist/studio/scaffold.d.ts +63 -0
  241. package/dist/studio/scaffold.js +346 -0
  242. package/dist/studio/screen-suites.d.ts +193 -0
  243. package/dist/studio/screen-suites.js +297 -0
  244. package/dist/studio/themes.d.ts +34 -0
  245. package/dist/studio/themes.js +41 -0
  246. package/dist/studio/ui-components.d.ts +89 -0
  247. package/dist/studio/ui-components.generated.d.ts +29 -0
  248. package/dist/studio/ui-components.generated.js +7319 -0
  249. package/dist/studio/ui-components.js +673 -0
  250. package/dist/studio/user-error.d.ts +23 -0
  251. package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
  252. package/dist/studio/verify.d.ts +34 -0
  253. package/dist/studio/verify.js +47 -0
  254. package/dist/sveltekit/in-memory.d.ts +14 -0
  255. package/dist/sveltekit/in-memory.js +113 -0
  256. package/dist/sveltekit/index.d.ts +6 -0
  257. package/dist/sveltekit/index.js +5 -0
  258. package/dist/sveltekit/query-plan.d.ts +44 -0
  259. package/dist/sveltekit/query-plan.js +76 -0
  260. package/dist/sveltekit/sql-source.d.ts +47 -0
  261. package/dist/sveltekit/sql-source.js +106 -0
  262. package/dist/sveltekit/sql.d.ts +48 -0
  263. package/dist/sveltekit/sql.js +73 -0
  264. package/dist/sveltekit/transport.d.ts +209 -0
  265. package/dist/sveltekit/transport.js +219 -0
  266. package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
  267. package/dist/sveltekit/types.js +1 -0
  268. package/dist/upgrade-prompt.d.ts +16 -0
  269. package/dist/upgrade-prompt.js +141 -0
  270. package/dist/version.d.ts +13 -0
  271. package/{src/version.ts → dist/version.js} +1 -1
  272. package/dist/watermark.d.ts +2 -0
  273. package/dist/watermark.js +146 -0
  274. package/package.json +28 -26
  275. package/dist/designer/assets/index-oYok52zd.css +0 -1
  276. package/dist/designer/assets/src-D-O2F805.css +0 -1
  277. package/src/SvBoard.dom.test.ts +0 -67
  278. package/src/SvGridAlerts.dom.test.ts +0 -113
  279. package/src/SvGridEditPanel.dom.test.ts +0 -320
  280. package/src/SvRecordDetail.dom.test.ts +0 -137
  281. package/src/SvSchedule.dom.test.ts +0 -57
  282. package/src/ai-export-pdf.dom.test.ts +0 -77
  283. package/src/ai-export-xlsx.dom.test.ts +0 -90
  284. package/src/ai-export.dom.test.ts +0 -114
  285. package/src/alerts/alert-engine-attach.ts +0 -165
  286. package/src/alerts/alert-engine.test.ts +0 -135
  287. package/src/alerts/alert-engine.ts +0 -260
  288. package/src/alerts/alert-formats.test.ts +0 -87
  289. package/src/alerts/alert-formats.ts +0 -77
  290. package/src/alerts/alert-observer.test.ts +0 -189
  291. package/src/alerts/alert-observer.ts +0 -208
  292. package/src/alerts/alert-scheduler.ts +0 -96
  293. package/src/alerts/alert-storage.test.ts +0 -54
  294. package/src/alerts/alert-storage.ts +0 -116
  295. package/src/alerts/alert-store.svelte.ts +0 -80
  296. package/src/alerts/alert-types.ts +0 -94
  297. package/src/board.dom.test.ts +0 -941
  298. package/src/edit-panel.test.ts +0 -322
  299. package/src/edit-panel.ts +0 -379
  300. package/src/export-conditional.test.ts +0 -60
  301. package/src/export-conditional.ts +0 -94
  302. package/src/export-ooxml.test.ts +0 -152
  303. package/src/export-ooxml.ts +0 -489
  304. package/src/export-pdf.test.ts +0 -138
  305. package/src/export-pdf.ts +0 -245
  306. package/src/export-print.test.ts +0 -66
  307. package/src/export-print.ts +0 -132
  308. package/src/export-serialize.test.ts +0 -56
  309. package/src/export-xls.ts +0 -199
  310. package/src/export-xlsx-roundtrip.test.ts +0 -120
  311. package/src/export-xlsx.test.ts +0 -150
  312. package/src/export.test.ts +0 -349
  313. package/src/export.ts +0 -1464
  314. package/src/expressions/evaluate.test.ts +0 -111
  315. package/src/expressions/evaluate.ts +0 -237
  316. package/src/expressions/expression-columns.ts +0 -133
  317. package/src/expressions/expression-types.ts +0 -84
  318. package/src/expressions/parse.test.ts +0 -106
  319. package/src/expressions/parse.ts +0 -610
  320. package/src/import-automap.test.ts +0 -131
  321. package/src/import-hardening.test.ts +0 -158
  322. package/src/import.test.ts +0 -415
  323. package/src/import.ts +0 -1044
  324. package/src/index.ts +0 -569
  325. package/src/install.ts +0 -154
  326. package/src/license-core.test.ts +0 -23
  327. package/src/license-core.ts +0 -107
  328. package/src/license-expiry.test.ts +0 -144
  329. package/src/license.ts +0 -157
  330. package/src/master-detail.test.ts +0 -61
  331. package/src/master-detail.ts +0 -42
  332. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  333. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
  334. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
  335. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
  336. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
  337. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
  338. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
  339. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
  340. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
  341. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
  342. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
  343. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
  344. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
  345. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
  346. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
  347. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  348. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  349. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  350. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  351. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  352. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  353. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  354. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  355. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  356. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  357. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  358. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  359. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  360. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  361. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  362. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  363. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  364. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  365. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  366. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  367. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  368. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  369. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  370. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  371. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  372. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  373. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  374. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  375. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  376. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  377. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  378. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  379. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  380. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  381. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  382. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
  383. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
  384. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
  385. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
  386. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
  387. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
  388. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
  389. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
  390. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
  391. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
  392. package/src/pivot-chart.test.ts +0 -86
  393. package/src/pivot-chart.ts +0 -112
  394. package/src/pivot-designer.ts +0 -101
  395. package/src/pivot.test.ts +0 -335
  396. package/src/pivot.ts +0 -578
  397. package/src/print.ts +0 -107
  398. package/src/scheduler-assignments.test.ts +0 -97
  399. package/src/scheduler-assignments.ts +0 -134
  400. package/src/scheduler-axis.test.ts +0 -108
  401. package/src/scheduler-axis.ts +0 -238
  402. package/src/scheduler-booking.test.ts +0 -57
  403. package/src/scheduler-config.ts +0 -179
  404. package/src/scheduler-dependencies.test.ts +0 -155
  405. package/src/scheduler-dependencies.ts +0 -223
  406. package/src/scheduler-freebusy.test.ts +0 -41
  407. package/src/scheduler-heatmap.test.ts +0 -39
  408. package/src/scheduler-resource-tree.test.ts +0 -84
  409. package/src/scheduler-resource-tree.ts +0 -107
  410. package/src/scheduler-slots.test.ts +0 -53
  411. package/src/scheduler-slots.ts +0 -94
  412. package/src/scheduler-summary.test.ts +0 -47
  413. package/src/scheduler-summary.ts +0 -81
  414. package/src/scheduling.test.ts +0 -194
  415. package/src/scheduling.ts +0 -293
  416. package/src/schema-designer.test.ts +0 -121
  417. package/src/schema-designer.ts +0 -142
  418. package/src/schema.test.ts +0 -268
  419. package/src/schema.ts +0 -562
  420. package/src/smart-shim.ts +0 -107
  421. package/src/sources/aggregate.test.ts +0 -79
  422. package/src/sources/aggregate.ts +0 -102
  423. package/src/sources/auth-supabase.test.ts +0 -80
  424. package/src/sources/auth-supabase.ts +0 -87
  425. package/src/sources/dashboard.kpi.test.ts +0 -50
  426. package/src/sources/dashboard.test.ts +0 -61
  427. package/src/sources/dashboard.ts +0 -136
  428. package/src/sources/field-inference.test.ts +0 -60
  429. package/src/sources/field-inference.ts +0 -63
  430. package/src/sources/filters.test.ts +0 -58
  431. package/src/sources/filters.ts +0 -70
  432. package/src/sources/index.ts +0 -67
  433. package/src/sources/introspect-supabase.test.ts +0 -112
  434. package/src/sources/introspect-supabase.ts +0 -139
  435. package/src/sources/realtime-supabase.test.ts +0 -93
  436. package/src/sources/realtime-supabase.ts +0 -99
  437. package/src/sources/relation-lookup.test.ts +0 -99
  438. package/src/sources/relation-lookup.ts +0 -128
  439. package/src/sources/rest-adapters.test.ts +0 -95
  440. package/src/sources/rest-adapters.ts +0 -120
  441. package/src/sources/rest.test.ts +0 -104
  442. package/src/sources/rest.ts +0 -129
  443. package/src/sources/schema-from-columns.test.ts +0 -106
  444. package/src/sources/schema-from-columns.ts +0 -88
  445. package/src/sources/supabase.test.ts +0 -110
  446. package/src/sources/supabase.ts +0 -99
  447. package/src/sources/with-entity-rules.test.ts +0 -104
  448. package/src/sources/with-entity-rules.ts +0 -78
  449. package/src/sources/with-relation-labels.test.ts +0 -75
  450. package/src/sources/with-relation-labels.ts +0 -73
  451. package/src/staged-editing.ts +0 -0
  452. package/src/studio/bug-report.test.ts +0 -101
  453. package/src/studio/bug-report.ts +0 -165
  454. package/src/studio/cli.test.ts +0 -187
  455. package/src/studio/cli.ts +0 -117
  456. package/src/studio/copilot-core.test.ts +0 -45
  457. package/src/studio/csv.test.ts +0 -90
  458. package/src/studio/csv.ts +0 -165
  459. package/src/studio/db-connect-string.test.ts +0 -94
  460. package/src/studio/db-connect-string.ts +0 -128
  461. package/src/studio/deploy-cli.test.ts +0 -56
  462. package/src/studio/deploy-cli.ts +0 -100
  463. package/src/studio/emit-project.test.ts +0 -3324
  464. package/src/studio/emit-project.ts +0 -5377
  465. package/src/studio/emit-schema.test.ts +0 -111
  466. package/src/studio/emit-schema.ts +0 -1181
  467. package/src/studio/index.ts +0 -380
  468. package/src/studio/init-flow.test.ts +0 -514
  469. package/src/studio/init-flow.ts +0 -556
  470. package/src/studio/introspect-db.test.ts +0 -186
  471. package/src/studio/introspect-db.ts +0 -312
  472. package/src/studio/introspect-openapi.test.ts +0 -84
  473. package/src/studio/introspect-openapi.ts +0 -252
  474. package/src/studio/introspect-prisma.test.ts +0 -99
  475. package/src/studio/introspect-prisma.ts +0 -175
  476. package/src/studio/introspect.test.ts +0 -172
  477. package/src/studio/introspect.ts +0 -310
  478. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  479. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  480. package/src/studio/pipeline.test.ts +0 -42
  481. package/src/studio/project-robust.test.ts +0 -157
  482. package/src/studio/project.test.ts +0 -929
  483. package/src/studio/project.ts +0 -2394
  484. package/src/studio/sample-data.test.ts +0 -58
  485. package/src/studio/sample-data.ts +0 -203
  486. package/src/studio/samples/ats.ts +0 -202
  487. package/src/studio/samples/clinic.ts +0 -179
  488. package/src/studio/samples/crm.ts +0 -291
  489. package/src/studio/samples/datasets.test.ts +0 -84
  490. package/src/studio/samples/datasets.ts +0 -340
  491. package/src/studio/samples/ecommerce.ts +0 -187
  492. package/src/studio/samples/events.ts +0 -201
  493. package/src/studio/samples/fleet.ts +0 -213
  494. package/src/studio/samples/gym.ts +0 -215
  495. package/src/studio/samples/hr.ts +0 -195
  496. package/src/studio/samples/index.ts +0 -55
  497. package/src/studio/samples/insurance.ts +0 -229
  498. package/src/studio/samples/inventory.ts +0 -213
  499. package/src/studio/samples/invoicing.ts +0 -162
  500. package/src/studio/samples/library.ts +0 -180
  501. package/src/studio/samples/live-data.test.ts +0 -99
  502. package/src/studio/samples/live-data.ts +0 -306
  503. package/src/studio/samples/projects.ts +0 -212
  504. package/src/studio/samples/realestate.ts +0 -196
  505. package/src/studio/samples/restaurant.ts +0 -189
  506. package/src/studio/samples/samples.test.ts +0 -304
  507. package/src/studio/samples/school.ts +0 -197
  508. package/src/studio/samples/seed-floor.test.ts +0 -25
  509. package/src/studio/samples/shared.ts +0 -237
  510. package/src/studio/samples/starter.ts +0 -251
  511. package/src/studio/samples/subscriptions.ts +0 -183
  512. package/src/studio/samples/support.ts +0 -216
  513. package/src/studio/scaffold-app.test.ts +0 -91
  514. package/src/studio/scaffold.test.ts +0 -192
  515. package/src/studio/scaffold.ts +0 -390
  516. package/src/studio/screen-suites.test.ts +0 -269
  517. package/src/studio/screen-suites.ts +0 -448
  518. package/src/studio/themes.ts +0 -62
  519. package/src/studio/ui-components-surface.test.ts +0 -185
  520. package/src/studio/ui-components.generated.ts +0 -7154
  521. package/src/studio/ui-components.ts +0 -742
  522. package/src/studio/verify.test.ts +0 -47
  523. package/src/studio/verify.ts +0 -79
  524. package/src/sveltekit/in-memory.test.ts +0 -104
  525. package/src/sveltekit/in-memory.ts +0 -129
  526. package/src/sveltekit/index.ts +0 -24
  527. package/src/sveltekit/query-plan.test.ts +0 -109
  528. package/src/sveltekit/query-plan.ts +0 -125
  529. package/src/sveltekit/sql-source.test.ts +0 -198
  530. package/src/sveltekit/sql-source.ts +0 -171
  531. package/src/sveltekit/sql.test.ts +0 -80
  532. package/src/sveltekit/sql.ts +0 -131
  533. package/src/sveltekit/transport-scope.test.ts +0 -125
  534. package/src/sveltekit/transport.test.ts +0 -201
  535. package/src/sveltekit/transport.ts +0 -373
  536. package/src/upgrade-prompt.test.ts +0 -71
  537. package/src/upgrade-prompt.ts +0 -162
  538. package/src/version.test.ts +0 -17
  539. package/src/watermark.test.ts +0 -97
  540. package/src/watermark.ts +0 -156
  541. /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
  542. /package/{src → dist}/SvAlertsManager.svelte +0 -0
  543. /package/{src → dist}/SvAlertsPanel.svelte +0 -0
  544. /package/{src → dist}/SvAuthGate.svelte +0 -0
  545. /package/{src → dist}/SvBoard.svelte +0 -0
  546. /package/{src → dist}/SvExportMenu.svelte +0 -0
  547. /package/{src → dist}/SvFileInput.svelte +0 -0
  548. /package/{src → dist}/SvGridAlerts.svelte +0 -0
  549. /package/{src → dist}/SvGridBoard.svelte +0 -0
  550. /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
  551. /package/{src → dist}/SvGridScheduler.svelte +0 -0
  552. /package/{src → dist}/SvImportDialog.svelte +0 -0
  553. /package/{src → dist}/SvLookupInput.svelte +0 -0
  554. /package/{src → dist}/SvPivotDesigner.svelte +0 -0
  555. /package/{src → dist}/SvRecordDetail.svelte +0 -0
  556. /package/{src → dist}/SvSchedule.svelte +0 -0
  557. /package/{src → dist}/SvSchemaChart.svelte +0 -0
  558. /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
  559. /package/{src → dist}/pdfmake-shims.d.ts +0 -0
  560. /package/{src → dist}/smart.export.d.ts +0 -0
  561. /package/{src → dist}/smart.export.js +0 -0
  562. /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
  563. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
  564. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
  565. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
  566. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
  567. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
  568. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
  569. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
  570. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
  571. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
  572. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
  573. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
  574. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
  575. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
  576. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
  577. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
  578. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
  579. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
  580. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
  581. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
  582. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
  583. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
  584. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
  585. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
  586. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
  587. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
  588. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
  589. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
  590. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
  591. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
  592. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
  593. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
  594. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
  595. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
  596. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
  597. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
  598. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
  599. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
  600. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
  601. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
  602. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
  603. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
  604. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
  605. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
  606. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
  607. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
  608. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
  609. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
  610. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
  611. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
  612. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
  613. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
  614. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
  615. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
  616. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
  617. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
  618. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
  619. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
  620. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
  621. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
  622. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
  623. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
  624. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -0
package/dist/export.js ADDED
@@ -0,0 +1,1021 @@
1
+ // Import the pure formatters from the grid's Svelte-free `/format` subpath so
2
+ // this module (and the enterprise unit tests) don't drag in SvGrid.svelte.
3
+ import { formatValueForExport, toExcelNumFmt, valueForExcel } from '@svgrid/grid/format';
4
+ import { assertEnterpriseLicensed } from './license';
5
+ import { installSmartShim } from './smart-shim';
6
+ import { downloadBlobFile, downloadTextFile, serializeDelimited, serializeHtml, serializeJson, serializeMarkdown, serializeXml, } from './export-serialize';
7
+ import { serializeSpreadsheetML } from './export-xls';
8
+ import { buildXlsxParts, packageXlsx } from './export-ooxml';
9
+ import { buildPdfDocDefinition } from './export-pdf';
10
+ import { buildConditionalResolver } from './export-conditional';
11
+ /** Formats served by the native, dependency-free, streaming serializers. */
12
+ const NATIVE_TEXT_FORMATS = [
13
+ 'csv',
14
+ 'tsv',
15
+ 'html',
16
+ 'json',
17
+ 'xml',
18
+ 'md',
19
+ ];
20
+ let exporterCtorPromise = null;
21
+ async function getDataExporter() {
22
+ if (typeof window === 'undefined') {
23
+ throw new Error('@svgrid/enterprise: export requires a browser environment');
24
+ }
25
+ if (!exporterCtorPromise) {
26
+ exporterCtorPromise = (async () => {
27
+ installSmartShim();
28
+ // Side-effect import: the IIFE registers Smart.Utilities.DataExporter
29
+ // on the global Smart namespace that installSmartShim() set up.
30
+ await import('./smart.export.js');
31
+ const Ctor = window.Smart?.Utilities?.DataExporter;
32
+ if (!Ctor) {
33
+ throw new Error('@svgrid/enterprise: failed to load Smart.Utilities.DataExporter');
34
+ }
35
+ return Ctor;
36
+ })();
37
+ }
38
+ return exporterCtorPromise;
39
+ }
40
+ async function ensureGlobals(format) {
41
+ const g = globalThis;
42
+ if (format === 'xlsx' && g.JSZip == null) {
43
+ let mod;
44
+ try {
45
+ // Optional peer, loaded on demand. The `@ts-ignore` keeps a consumer's
46
+ // type-check clean when jszip isn't installed (no-op when it is).
47
+ // @ts-ignore - "jszip" is an optional peerDependency
48
+ mod = await import('jszip');
49
+ }
50
+ catch {
51
+ throw new Error('@svgrid/enterprise: xlsx export requires the "jszip" peer dependency. ' +
52
+ 'Install it with: pnpm add jszip');
53
+ }
54
+ g.JSZip = mod.default ?? mod;
55
+ }
56
+ if (format === 'pdf' && g.pdfMake == null) {
57
+ let pdfMakeMod;
58
+ let vfsMod;
59
+ try {
60
+ // Optional peer, loaded on demand (keeps consumer type-checks clean when absent).
61
+ // @ts-ignore - "pdfmake" is an optional peerDependency
62
+ pdfMakeMod = await import('pdfmake/build/pdfmake');
63
+ // @ts-ignore - "pdfmake" is an optional peerDependency
64
+ vfsMod = await import('pdfmake/build/vfs_fonts');
65
+ }
66
+ catch {
67
+ throw new Error('@svgrid/enterprise: pdf export requires the "pdfmake" peer dependency. ' +
68
+ 'Install it with: pnpm add pdfmake');
69
+ }
70
+ const pdfMake = (pdfMakeMod.default ?? pdfMakeMod);
71
+ const vfsRoot = vfsMod.default ?? vfsMod;
72
+ // pdfmake's vfs_fonts file historically exports either { pdfMake: { vfs } }
73
+ // or { default: { vfs } } or { vfs } depending on bundler. Try each shape.
74
+ const candidate = vfsRoot.pdfMake?.vfs ??
75
+ vfsRoot.vfs ??
76
+ vfsRoot.default?.vfs;
77
+ if (candidate)
78
+ pdfMake.vfs = candidate;
79
+ g.pdfMake = pdfMake;
80
+ }
81
+ }
82
+ /** Resolve the {@link ExportRowSource} shorthand against the grid api. */
83
+ export function resolveRowSource(api, source) {
84
+ if (Array.isArray(source))
85
+ return source;
86
+ switch (source) {
87
+ case 'selected':
88
+ return api.getSelectedRows();
89
+ case 'all':
90
+ return api.getData();
91
+ case 'displayed':
92
+ case undefined:
93
+ default:
94
+ return api.getDisplayedRows();
95
+ }
96
+ }
97
+ /** Resolve the export columns, carrying grid header labels + `format`. */
98
+ export function resolveColumns(api, opts, sourceRows) {
99
+ if (opts.columns && opts.columns.length > 0)
100
+ return opts.columns;
101
+ const gridCols = api.getColumns().filter((c) => c.visible && c.field);
102
+ if (gridCols.length > 0) {
103
+ return gridCols.map((c) => ({
104
+ field: c.field,
105
+ header: c.header,
106
+ format: c.format,
107
+ align: c.align,
108
+ }));
109
+ }
110
+ if (sourceRows.length > 0) {
111
+ return Object.keys(sourceRows[0])
112
+ .filter((k) => !k.startsWith('_'))
113
+ .map((field) => ({ field }));
114
+ }
115
+ return [];
116
+ }
117
+ /**
118
+ * The value written for one cell: an `exportValue` hook wins; otherwise the
119
+ * raw field value, formatted to the on-screen display string unless
120
+ * `rawValues` is set.
121
+ */
122
+ function cellValueFor(col, rowData, rawValues) {
123
+ if (col.exportValue) {
124
+ const v = col.exportValue(rowData);
125
+ return v ?? '';
126
+ }
127
+ const raw = rowData[col.field];
128
+ if (rawValues)
129
+ return raw;
130
+ return formatValueForExport(raw, col.format);
131
+ }
132
+ /**
133
+ * Project source rows into the `[header, ...records]` shape the writers
134
+ * consume, applying per-column formatting / `exportValue`. Async so it can
135
+ * yield to the event loop (and honour an abort) on large datasets.
136
+ */
137
+ export async function projectRows(sourceRows, cols, opts) {
138
+ const rawValues = opts.rawValues === true;
139
+ const headerRow = {};
140
+ for (const c of cols)
141
+ headerRow[c.field] = c.header ?? c.field;
142
+ const projected = [headerRow];
143
+ const total = sourceRows.length;
144
+ const CHUNK = 5000;
145
+ for (let i = 0; i < total; i++) {
146
+ if (opts.signal?.aborted)
147
+ throw new DOMException('Export aborted', 'AbortError');
148
+ const r = sourceRows[i];
149
+ const row = {};
150
+ for (const c of cols)
151
+ row[c.field] = cellValueFor(c, r, rawValues);
152
+ projected.push(row);
153
+ if (i > 0 && i % CHUNK === 0) {
154
+ opts.onProgress?.({ phase: 'project', ratio: i / total, row: i, total });
155
+ await new Promise((resolve) => setTimeout(resolve, 0));
156
+ }
157
+ }
158
+ opts.onProgress?.({ phase: 'project', ratio: 1, row: total, total });
159
+ return projected;
160
+ }
161
+ /**
162
+ * Translate the public {@link ExportStyles} shape into the keys the Smart
163
+ * exporter actually consumes:
164
+ * `style.header` → all header cells
165
+ * `style.rows` → all data rows. Cell-prop keys (color, backgroundColor,
166
+ * fontWeight, fontStyle, fontSize, fontFamily,
167
+ * textAlign, verticalAlign, textDecoration, numFmt)
168
+ * are recognised by Smart's `storeCellStyle`.
169
+ * `style.rows.alternationCount` + `alternationStart` +
170
+ * `alternationIndex1BackgroundColor` (etc.) → zebra striping
171
+ * `style.cells.<ref>` → HTML-only per-cell ref overrides
172
+ */
173
+ function translateStyles(styles) {
174
+ if (!styles)
175
+ return undefined;
176
+ const out = {};
177
+ if (styles.headerRow)
178
+ out.header = { ...styles.headerRow };
179
+ const rows = styles.rows ? { ...styles.rows } : {};
180
+ if (styles.rowAlternate) {
181
+ rows.alternationCount = 2;
182
+ rows.alternationStart = 0;
183
+ if (styles.rowAlternate.backgroundColor)
184
+ rows.alternationIndex1BackgroundColor = styles.rowAlternate.backgroundColor;
185
+ if (styles.rowAlternate.color)
186
+ rows.alternationIndex1Color = styles.rowAlternate.color;
187
+ }
188
+ if (Object.keys(rows).length > 0)
189
+ out.rows = rows;
190
+ if (styles.cells)
191
+ out.cells = styles.cells;
192
+ return out;
193
+ }
194
+ let _imgIdCounter = 0;
195
+ const _imgIdCache = new Map();
196
+ function imageIdFor(dataUrl) {
197
+ const cached = _imgIdCache.get(dataUrl);
198
+ if (cached)
199
+ return cached;
200
+ const id = `img${++_imgIdCounter}`;
201
+ _imgIdCache.set(dataUrl, id);
202
+ return id;
203
+ }
204
+ /**
205
+ * Build the image object Smart's xlsx writer expects. The exporter pulls
206
+ * `{ id, base64, imageType, width, height }` off the return of
207
+ * `addImageToCell(...).image` and stores it under `this.images` →
208
+ * eventually written to the workbook as `xl/media/imageN.<imageType>`.
209
+ *
210
+ * `base64` may be a full data URL - Smart strips the prefix when writing.
211
+ */
212
+ function makeSmartImage(dataUrl, width = 64, height = 64) {
213
+ // Extract MIME → imageType. Defaults to png for safety.
214
+ const mime = /^data:image\/([a-zA-Z0-9+]+);/i.exec(dataUrl)?.[1]?.toLowerCase() ?? 'png';
215
+ const imageType = mime === 'jpg' ? 'jpeg'
216
+ : mime === 'svg+xml' ? 'svg'
217
+ : mime;
218
+ return {
219
+ id: imageIdFor(dataUrl),
220
+ base64: dataUrl,
221
+ imageType,
222
+ width,
223
+ height,
224
+ };
225
+ }
226
+ /**
227
+ * Build the header / footer arrays the Smart exporter understands.
228
+ * Each input line becomes one full-width row in the spreadsheet with
229
+ * `style.mergeAcross` so the line spans every column.
230
+ *
231
+ * Image lines are written as a data-URL string into the first column and
232
+ * the wrapper's `addImageToCell` hook embeds them as real picture cells.
233
+ */
234
+ function buildContentRows(lines, datafields) {
235
+ if (!lines || lines.length === 0 || datafields.length === 0)
236
+ return undefined;
237
+ const first = datafields[0];
238
+ const out = [];
239
+ for (const line of lines) {
240
+ const cells = {};
241
+ let style;
242
+ if ('image' in line) {
243
+ cells[first] = line.image;
244
+ style = { mergeAcross: true, textAlign: 'left' };
245
+ }
246
+ else if ('text' in line) {
247
+ cells[first] = line.text;
248
+ style = { mergeAcross: true, ...(line.style ?? {}) };
249
+ }
250
+ else {
251
+ // 3-column { left, center, right }. Distribute across the first,
252
+ // middle, and last datafield.
253
+ const mid = datafields[Math.floor(datafields.length / 2)];
254
+ const last = datafields[datafields.length - 1];
255
+ if (line.left !== undefined)
256
+ cells[first] = line.left;
257
+ if (line.center !== undefined)
258
+ cells[mid] = line.center;
259
+ if (line.right !== undefined)
260
+ cells[last] = line.right;
261
+ style = { textAlign: 'left' };
262
+ }
263
+ out.push({ cells, style });
264
+ }
265
+ return out;
266
+ }
267
+ /**
268
+ * Build an `addImageToCell` handler that embeds a value as a real image
269
+ * cell whenever the value is a data URL. Smart calls this for every body
270
+ * cell AND every header/footer cell, so the same handler covers both
271
+ * code paths.
272
+ *
273
+ * `bodyImageSize` controls the embedded pixel size for body cells (the
274
+ * thumbnails). Header/footer image lines use their own size hint
275
+ * already encoded in the `cells[first]` value's metadata - here we just
276
+ * embed with a slightly larger default so logos read well in the page
277
+ * banner.
278
+ */
279
+ function buildImageHandler(imageFields, bodyImageSize) {
280
+ const allowed = imageFields && imageFields.length > 0 ? new Set(imageFields) : null;
281
+ return (_rowIndex, dataField, value) => {
282
+ if (typeof value !== 'string')
283
+ return null;
284
+ if (!/^data:image\//i.test(value))
285
+ return null;
286
+ if (allowed && !allowed.has(dataField)) {
287
+ // Header/footer image lines come through the first column too -
288
+ // those cells aren't in `imageFields`, but the wrapper wrote the
289
+ // data URL there itself. Embed bigger (logo banner).
290
+ return { image: makeSmartImage(value, 96, 96), value: '' };
291
+ }
292
+ return { image: makeSmartImage(value, bodyImageSize.width, bodyImageSize.height), value: '' };
293
+ };
294
+ }
295
+ /**
296
+ * Build the constructor-options object passed to the Smart DataExporter.
297
+ * Constructor only consumes a small set of keys; instance-level options
298
+ * (`headerContent`, `footerContent`, `addImageToCell`) are applied
299
+ * separately in {@link exportGrid} after `new DataExporter(...)`.
300
+ */
301
+ function buildExporterOptions(opts) {
302
+ const out = {
303
+ exportHeader: true,
304
+ pageOrientation: opts.pageOrientation ?? 'portrait',
305
+ };
306
+ // Freeze the header row (and optional leading columns) so they stay in view
307
+ // when scrolling the xlsx. On by default.
308
+ if (opts.freezeHeader !== false)
309
+ out.freezeHeader = true;
310
+ if (opts.freezeColumns && opts.freezeColumns > 0) {
311
+ out.freezeColumnsCount = Math.floor(opts.freezeColumns);
312
+ }
313
+ const style = translateStyles(opts.styles);
314
+ if (style)
315
+ out.style = style;
316
+ // Smart's xlsx writer emits Excel-native row outlining when
317
+ // `hierarchical: true` is set on the constructor options OR when the
318
+ // second constructor arg is a non-empty groupBy array. We thread
319
+ // hierarchical through here and groupBy through the constructor call
320
+ // site in exportGrid.
321
+ if (opts.hierarchical)
322
+ out.hierarchical = true;
323
+ // Merged cells: translate the friendly {row, col, rowSpan, colSpan} shape to
324
+ // Smart's native {cell: [row, col], rowspan, colspan}. Skip 1x1 "merges"
325
+ // (nothing to span). Ignored when grouping/hierarchy owns the row layout.
326
+ if (opts.merges?.length && !opts.groupBy?.length && !opts.hierarchical) {
327
+ const mergedCells = opts.merges
328
+ .map((m) => ({
329
+ cell: [m.row, m.col],
330
+ rowspan: Math.max(1, Math.floor(m.rowSpan ?? 1)),
331
+ colspan: Math.max(1, Math.floor(m.colSpan ?? 1)),
332
+ }))
333
+ .filter((m) => m.rowspan > 1 || m.colspan > 1);
334
+ if (mergedCells.length)
335
+ out.mergedCells = mergedCells;
336
+ }
337
+ return out;
338
+ }
339
+ /**
340
+ * Apply instance-level options the constructor does not consume.
341
+ * Mutates and returns the exporter for fluent use.
342
+ */
343
+ function applyInstanceOptions(exporter, opts, datafields) {
344
+ const headerRows = buildContentRows(opts.header, datafields);
345
+ const footerRows = buildContentRows(opts.footer, datafields);
346
+ if (headerRows)
347
+ exporter.headerContent = headerRows;
348
+ if (footerRows)
349
+ exporter.footerContent = footerRows;
350
+ // Wire image embedding when the caller opts in via imageFields OR the
351
+ // header/footer carries an image line. Both code paths funnel through
352
+ // the same handler.
353
+ const hasHeaderOrFooterImage = (opts.header?.some((l) => 'image' in l) ?? false) ||
354
+ (opts.footer?.some((l) => 'image' in l) ?? false);
355
+ if (opts.imageFields?.length || hasHeaderOrFooterImage) {
356
+ const bodySize = opts.imageSize ?? { width: 32, height: 32 };
357
+ exporter.addImageToCell = buildImageHandler(opts.imageFields, bodySize);
358
+ }
359
+ return exporter;
360
+ }
361
+ /** Append `.ext` to a filename that doesn't already carry it. */
362
+ function ensureExt(name, ext) {
363
+ return name.toLowerCase().endsWith('.' + ext) ? name : `${name}.${ext}`;
364
+ }
365
+ /** Download the blob (unless `download === false`) and return the result. */
366
+ function deliver(blob, filename, mime, rowCount, download) {
367
+ if (download !== false)
368
+ downloadBlobFile(blob, filename);
369
+ return { blob, filename, mime, rowCount, byteSize: blob.size };
370
+ }
371
+ /** Text-file variant: download via `downloadTextFile`, also return the blob. */
372
+ function deliverText(text, filename, mime, rowCount, download) {
373
+ if (download !== false)
374
+ downloadTextFile(text, filename, mime);
375
+ const blob = new Blob([text], { type: mime });
376
+ return { blob, filename, mime, rowCount, byteSize: blob.size };
377
+ }
378
+ /**
379
+ * Estimate a per-column pixel width from the header + a sample of cell values,
380
+ * for xlsx / xls auto-fit. A column's explicit `width` always wins. ~7px per
381
+ * character, clamped to a sensible range.
382
+ */
383
+ function autoFitWidths(cols, rows, rawValues) {
384
+ const SAMPLE = Math.min(rows.length, 200);
385
+ return cols.map((c) => {
386
+ if (typeof c.width === 'number')
387
+ return c.width;
388
+ let maxChars = String(c.header ?? c.field).length;
389
+ for (let i = 0; i < SAMPLE; i++) {
390
+ const v = cellValueFor(c, rows[i], rawValues);
391
+ const len = v == null ? 0 : String(v).length;
392
+ if (len > maxChars)
393
+ maxChars = len;
394
+ }
395
+ return Math.max(48, Math.min(400, maxChars * 7 + 14));
396
+ });
397
+ }
398
+ /**
399
+ * Freeze-column count: explicit `freezeColumns` wins; otherwise derive it from
400
+ * the grid's left-pinned columns that lead the export column order. Silent
401
+ * (returns undefined) when neither applies.
402
+ */
403
+ function resolveFreezeColumns(api, opts, cols) {
404
+ if (typeof opts.freezeColumns === 'number')
405
+ return opts.freezeColumns;
406
+ const left = api.getColumnPinning().left;
407
+ if (!left || left.length === 0)
408
+ return undefined;
409
+ const pinnedSet = new Set(left);
410
+ // Count leading export columns that are pinned-left (by field id).
411
+ let n = 0;
412
+ for (const c of cols) {
413
+ if (pinnedSet.has(c.field))
414
+ n++;
415
+ else
416
+ break;
417
+ }
418
+ return n > 0 ? n : undefined;
419
+ }
420
+ /** Excel column letter for a 0-based column index (0 -> A, 26 -> AA). */
421
+ function colLetter(index) {
422
+ let n = index;
423
+ let s = '';
424
+ do {
425
+ s = String.fromCharCode(65 + (n % 26)) + s;
426
+ n = Math.floor(n / 26) - 1;
427
+ } while (n >= 0);
428
+ return s;
429
+ }
430
+ /** A `(rowIdx, colIdx) => url` resolver from column `link` hooks, or undefined
431
+ * when no column defines links. */
432
+ export function buildLinkResolver(cols, rows) {
433
+ if (!cols.some((c) => c.link))
434
+ return undefined;
435
+ return (rowIdx, colIdx) => {
436
+ const col = cols[colIdx];
437
+ const row = rows[rowIdx];
438
+ if (!col?.link || !row)
439
+ return undefined;
440
+ return col.link(row) || undefined;
441
+ };
442
+ }
443
+ /** Build a `field -> align` map from resolved columns (for html / md). */
444
+ function alignMap(cols) {
445
+ const align = {};
446
+ for (const c of cols)
447
+ if (c.align)
448
+ align[c.field] = c.align;
449
+ return align;
450
+ }
451
+ /**
452
+ * Serialize projected rows to the requested native format string. Shared by
453
+ * file export and clipboard export. Returns `{ text, mime, ext }`.
454
+ */
455
+ async function serializeNative(format, projected, cols, opts, cellStyle, cellLink) {
456
+ const fields = cols.map((c) => c.field);
457
+ const p = { onProgress: opts.onProgress, signal: opts.signal };
458
+ switch (format) {
459
+ case 'html': {
460
+ const text = await serializeHtml(projected, fields, {
461
+ ...p,
462
+ title: (opts.filename ?? 'grid').trim() || 'grid',
463
+ align: alignMap(cols),
464
+ cellStyle,
465
+ cellLink,
466
+ });
467
+ return { text, mime: 'text/html;charset=utf-8', ext: 'html' };
468
+ }
469
+ case 'json': {
470
+ const text = await serializeJson(projected, fields, p);
471
+ return { text, mime: 'application/json;charset=utf-8', ext: 'json' };
472
+ }
473
+ case 'xml': {
474
+ const text = await serializeXml(projected, fields, p);
475
+ return { text, mime: 'application/xml;charset=utf-8', ext: 'xml' };
476
+ }
477
+ case 'md': {
478
+ const text = await serializeMarkdown(projected, fields, { ...p, align: alignMap(cols) });
479
+ return { text, mime: 'text/markdown;charset=utf-8', ext: 'md' };
480
+ }
481
+ case 'tsv': {
482
+ const text = await serializeDelimited(projected, fields, { ...p, csv: { ...opts.csv, delimiter: '\t' } });
483
+ return { text, mime: 'text/tab-separated-values;charset=utf-8', ext: 'tsv' };
484
+ }
485
+ case 'csv':
486
+ default: {
487
+ const delimiter = opts.csv?.delimiter ?? ',';
488
+ const text = await serializeDelimited(projected, fields, { ...p, csv: { ...opts.csv, delimiter } });
489
+ return { text, mime: 'text/csv;charset=utf-8', ext: 'csv' };
490
+ }
491
+ }
492
+ }
493
+ /**
494
+ * Native text export (csv / tsv / html / json / xml / md). No Smart exporter,
495
+ * no peer deps - pure streaming serialization with progress + abort. Values
496
+ * are formatted to match the on-screen display (json defaults to raw so it
497
+ * stays machine-readable).
498
+ */
499
+ async function exportTextFormat(api, opts) {
500
+ if (opts.sheets && opts.sheets.length > 0) {
501
+ throw new Error(`@svgrid/enterprise: multi-sheet export requires format 'xlsx', got '${opts.format}'`);
502
+ }
503
+ const sourceRows = resolveRowSource(api, opts.rows);
504
+ if (sourceRows.length === 0) {
505
+ throw new Error('@svgrid/enterprise: nothing to export - the grid has no rows');
506
+ }
507
+ const cols = resolveColumns(api, opts, sourceRows);
508
+ // JSON is a data format: default to raw values so consumers get real
509
+ // numbers/dates, not "$19.95" strings. The other formats default formatted.
510
+ const projectOpts = opts.format === 'json' ? { ...opts, rawValues: opts.rawValues ?? true } : opts;
511
+ const projected = await projectRows(sourceRows, cols, projectOpts);
512
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
513
+ // HTML carries conditional formatting (fill / color / bold / icon); the other
514
+ // native formats are unstyled data.
515
+ const cellStyle = opts.format === 'html'
516
+ ? buildConditionalResolver(cols, sourceRows, opts.conditionalFormats)
517
+ : undefined;
518
+ const cellLink = opts.format === 'html' ? buildLinkResolver(cols, sourceRows) : undefined;
519
+ const { text, mime, ext } = await serializeNative(opts.format, projected, cols, opts, cellStyle, cellLink);
520
+ return deliverText(text, ensureExt(filename, ext), mime, sourceRows.length, opts.download);
521
+ }
522
+ /**
523
+ * Legacy `.xls` export (Excel 2003 XML Spreadsheet). Dependency-free and
524
+ * streaming, like the text path, but produces a real typed spreadsheet.
525
+ */
526
+ async function exportXls(api, opts) {
527
+ if (opts.sheets && opts.sheets.length > 0) {
528
+ throw new Error("@svgrid/enterprise: multi-sheet export requires format 'xlsx'. Use 'xls' for a single legacy sheet.");
529
+ }
530
+ const sourceRows = resolveRowSource(api, opts.rows);
531
+ if (sourceRows.length === 0) {
532
+ throw new Error('@svgrid/enterprise: nothing to export - the grid has no rows');
533
+ }
534
+ const cols = resolveColumns(api, opts, sourceRows);
535
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
536
+ const visual = buildConditionalResolver(cols, sourceRows, opts.conditionalFormats);
537
+ const xml = await serializeSpreadsheetML(filename, cols, sourceRows, {
538
+ rawValues: opts.rawValues,
539
+ onProgress: opts.onProgress,
540
+ signal: opts.signal,
541
+ freezeHeader: opts.freezeHeader !== false,
542
+ freezeColumns: resolveFreezeColumns(api, opts, cols),
543
+ widths: opts.autoFitColumns !== false ? autoFitWidths(cols, sourceRows, opts.rawValues === true) : undefined,
544
+ cellVisual: opts.conditionalFormats?.length ? visual : undefined,
545
+ precisionSafe: opts.precisionSafe,
546
+ });
547
+ const mime = 'application/vnd.ms-excel;charset=utf-8';
548
+ return deliverText(xml, ensureExt(filename, 'xls'), mime, sourceRows.length, opts.download);
549
+ }
550
+ /** Columns whose values can be summed for a PDF subtotal row. */
551
+ function isSummableColumn(col) {
552
+ return col.format?.type === 'number' || col.format?.type === 'currency';
553
+ }
554
+ /**
555
+ * Build a grouped PDF body: a bold group header per cluster (nested for
556
+ * multi-level grouping), the cluster's data rows, then a subtotal row summing
557
+ * the numeric / currency columns. Values use the same formatting as the grid.
558
+ */
559
+ export function buildGroupedPdfBody(cols, rows, groupBy) {
560
+ const out = [];
561
+ const headerOf = (field) => cols.find((c) => c.field === field)?.header ?? field;
562
+ // Put the "Subtotal" label in the first NON-numeric column; if every column
563
+ // is numeric, -1 means "don't overwrite a sum with the label".
564
+ const labelColIdx = cols.findIndex((c) => !isSummableColumn(c));
565
+ const recurse = (subset, level) => {
566
+ if (level >= groupBy.length) {
567
+ for (const r of subset) {
568
+ out.push({ kind: 'data', cells: cols.map((c) => String(cellValueFor(c, r, false) ?? '')) });
569
+ }
570
+ return;
571
+ }
572
+ const field = groupBy[level];
573
+ // Preserve first-seen order of group keys.
574
+ const buckets = new Map();
575
+ for (const r of subset) {
576
+ const key = String(r[field] ?? '');
577
+ const bucket = buckets.get(key);
578
+ if (bucket)
579
+ bucket.push(r);
580
+ else
581
+ buckets.set(key, [r]);
582
+ }
583
+ for (const [key, groupRows] of buckets) {
584
+ out.push({ kind: 'group', label: `${headerOf(field)}: ${key} (${groupRows.length})`, level });
585
+ recurse(groupRows, level + 1);
586
+ // Subtotal row for the numeric columns of this cluster.
587
+ const hasSummable = cols.some(isSummableColumn);
588
+ if (hasSummable) {
589
+ const cells = cols.map((c) => {
590
+ if (!isSummableColumn(c))
591
+ return '';
592
+ const sum = groupRows.reduce((a, r) => a + (Number(r[c.field]) || 0), 0);
593
+ return formatValueForExport(sum, c.format);
594
+ });
595
+ if (labelColIdx >= 0)
596
+ cells[labelColIdx] = `Subtotal (${key})`;
597
+ out.push({ kind: 'subtotal', cells });
598
+ }
599
+ }
600
+ };
601
+ recurse(rows, 0);
602
+ return out;
603
+ }
604
+ /**
605
+ * PDF export via our own pdfmake docDefinition (page setup, repeated header,
606
+ * page numbers, per-column alignment/widths, title/logo, theme colors, and
607
+ * group + subtotal rows carried from the grid's grouping). Values are the
608
+ * formatted display strings, so the PDF matches the grid.
609
+ */
610
+ async function exportPdf(api, opts) {
611
+ await ensureGlobals('pdf');
612
+ const pdfMake = globalThis.pdfMake;
613
+ if (!pdfMake) {
614
+ throw new Error('@svgrid/enterprise: pdf export requires the "pdfmake" peer dependency.');
615
+ }
616
+ const sourceRows = resolveRowSource(api, opts.rows);
617
+ if (sourceRows.length === 0) {
618
+ throw new Error('@svgrid/enterprise: nothing to export - the grid has no rows');
619
+ }
620
+ const cols = resolveColumns(api, opts, sourceRows);
621
+ const fields = cols.map((c) => c.field);
622
+ const columns = cols.map((c) => ({ header: c.header ?? c.field, align: c.align }));
623
+ // Carry the grid's active grouping into group + subtotal rows (unless the
624
+ // caller opted out or passed hierarchical), matching the xlsx outline path.
625
+ const autoGrouping = opts.autoGroup !== false && !opts.groupBy?.length && !opts.hierarchical
626
+ ? (api.getState().grouping ?? []).filter((id) => !!id).map((id) => String(id))
627
+ : [];
628
+ const effGroupBy = opts.groupBy?.length
629
+ ? opts.groupBy
630
+ : autoGrouping.length > 0
631
+ ? autoGrouping
632
+ : undefined;
633
+ if (opts.signal?.aborted)
634
+ throw new DOMException('Export aborted', 'AbortError');
635
+ opts.onProgress?.({ phase: 'write', ratio: 0, total: sourceRows.length });
636
+ const pdfOpts = {
637
+ ...opts.pdf,
638
+ pageOrientation: opts.pdf?.pageOrientation ?? opts.pageOrientation,
639
+ };
640
+ const now = new Date();
641
+ let def;
642
+ if (effGroupBy?.length) {
643
+ // Conditional formatting is skipped for grouped PDFs (group / subtotal
644
+ // rows own the layout); the grid colors still show on screen.
645
+ const body = buildGroupedPdfBody(cols, sourceRows, effGroupBy);
646
+ def = buildPdfDocDefinition({ columns, body, opts: pdfOpts, now });
647
+ }
648
+ else {
649
+ const projected = await projectRows(sourceRows, cols, opts);
650
+ const dataRows = projected.slice(1).map((r) => fields.map((f) => String(r[f] ?? '')));
651
+ // Conditional formatting -> per-cell fill / color / bold + icon prefix.
652
+ const visual = buildConditionalResolver(cols, sourceRows, opts.conditionalFormats);
653
+ for (let r = 0; r < dataRows.length; r++) {
654
+ for (let c = 0; c < cols.length; c++) {
655
+ const icon = visual(r, c)?.icon;
656
+ if (icon)
657
+ dataRows[r][c] = `${icon} ${dataRows[r][c] ?? ''}`;
658
+ }
659
+ }
660
+ const link = buildLinkResolver(cols, sourceRows);
661
+ def = buildPdfDocDefinition({
662
+ columns,
663
+ rows: dataRows,
664
+ dataCellStyle: (r, c) => {
665
+ const v = visual(r, c);
666
+ return v ? { fill: v.fill, color: v.color, bold: v.bold } : undefined;
667
+ },
668
+ dataCellLink: link,
669
+ opts: pdfOpts,
670
+ now,
671
+ });
672
+ }
673
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
674
+ const blob = await new Promise((resolve) => pdfMake.createPdf(def).getBlob(resolve));
675
+ opts.onProgress?.({ phase: 'write', ratio: 1, total: sourceRows.length });
676
+ return deliver(blob, ensureExt(filename, 'pdf'), 'application/pdf', sourceRows.length, opts.download);
677
+ }
678
+ /**
679
+ * Resolve one cell into the typed descriptor the native xlsx writer needs:
680
+ * real numbers / dates with a number format (Excel sums + sorts), or a
681
+ * formatted string, plus conditional-format fill / color / bold / icon and a
682
+ * hyperlink.
683
+ */
684
+ async function buildXlsxCellMatrix(cols, rows, rawValues, visual, link, opts) {
685
+ const header = cols.map((c) => c.header ?? c.field);
686
+ const precisionSafe = opts?.precisionSafe === true;
687
+ // Excel stores numbers as 64-bit floats (~15 significant digits); a longer
688
+ // integer (an ID) would be silently rounded. In precision-safe mode we write
689
+ // such values as text so they survive intact.
690
+ const num = (value, base, numFmt) => precisionSafe && Math.abs(value) >= 1e15
691
+ ? { t: 's', value: String(value), ...base }
692
+ : { t: 'n', value, numFmt, ...base };
693
+ const cellFor = (row, r, c) => {
694
+ const col = cols[c];
695
+ const v = visual(r, c);
696
+ const base = { align: col.align, fill: v?.fill, color: v?.color, bold: v?.bold, link: link?.(r, c) };
697
+ if (col.exportValue) {
698
+ const ev = col.exportValue(row);
699
+ if (typeof ev === 'number' && Number.isFinite(ev))
700
+ return num(ev, base, toExcelNumFmt(col.format));
701
+ if (ev instanceof Date)
702
+ return { t: 'd', value: ev, numFmt: toExcelNumFmt(col.format) ?? 'yyyy-mm-dd', ...base };
703
+ return { t: 's', value: ev == null ? '' : String(ev), ...base };
704
+ }
705
+ const raw = row[col.field];
706
+ // An icon-set glyph forces a string cell (icon + formatted value).
707
+ if (v?.icon) {
708
+ const disp = rawValues ? String(raw ?? '') : formatValueForExport(raw, col.format);
709
+ return { t: 's', value: `${v.icon} ${disp}`, ...base };
710
+ }
711
+ if (rawValues) {
712
+ if (typeof raw === 'number' && Number.isFinite(raw))
713
+ return num(raw, base);
714
+ return { t: 's', value: raw == null ? '' : String(raw), ...base };
715
+ }
716
+ const typed = valueForExcel(raw, col.format);
717
+ if (typed.ok) {
718
+ if (typed.value instanceof Date)
719
+ return { t: 'd', value: typed.value, numFmt: toExcelNumFmt(col.format) ?? 'yyyy-mm-dd', ...base };
720
+ return num(typed.value, base, toExcelNumFmt(col.format));
721
+ }
722
+ return { t: 's', value: formatValueForExport(raw, col.format), ...base };
723
+ };
724
+ // Build in chunks, yielding to the event loop so a huge export doesn't freeze
725
+ // the tab (the per-cell Intl formatting is the expensive part).
726
+ const cells = [];
727
+ const total = rows.length;
728
+ const CHUNK = 2000;
729
+ for (let r = 0; r < total; r++) {
730
+ if (opts?.signal?.aborted)
731
+ throw new DOMException('Export aborted', 'AbortError');
732
+ const row = rows[r];
733
+ cells.push(cols.map((_, c) => cellFor(row, r, c)));
734
+ if (r > 0 && r % CHUNK === 0) {
735
+ opts?.onProgress?.({ phase: 'project', ratio: r / total, row: r, total });
736
+ await new Promise((resolve) => setTimeout(resolve, 0));
737
+ }
738
+ }
739
+ return { header, cells };
740
+ }
741
+ /**
742
+ * Native single-sheet xlsx export (our own OOXML writer). Typed numbers +
743
+ * number formats, true per-cell conditional-format fills, freeze header,
744
+ * auto-fit widths, and real hyperlinks - none of which the vendored writer can
745
+ * do. Needs only `jszip`.
746
+ */
747
+ async function exportXlsxNative(api, opts) {
748
+ await ensureGlobals('xlsx'); // loads jszip onto globalThis
749
+ const JSZip = globalThis.JSZip;
750
+ if (!JSZip)
751
+ throw new Error('@svgrid/enterprise: xlsx export requires the "jszip" peer dependency.');
752
+ const src = resolveRowSource(api, opts.rows);
753
+ if (src.length === 0) {
754
+ throw new Error('@svgrid/enterprise: nothing to export - the grid has no rows');
755
+ }
756
+ const cols = resolveColumns(api, opts, src);
757
+ const rawValues = opts.rawValues === true;
758
+ // Color scales + data bars become NATIVE Excel conditional formatting (Excel
759
+ // computes them, so they're interactive). Predicate rules + icon sets stay
760
+ // client-computed per cell. So the per-cell resolver only sees rule/iconSet.
761
+ const cf = opts.conditionalFormats ?? [];
762
+ const cellCf = cf.filter((f) => f.type === 'rule' || f.type === 'iconSet');
763
+ const visual = buildConditionalResolver(cols, src, cellCf);
764
+ const link = buildLinkResolver(cols, src);
765
+ const condFormats = [];
766
+ for (const f of cf) {
767
+ if (f.type !== 'colorScale' && f.type !== 'dataBar')
768
+ continue;
769
+ const targetIdxs = f.columns && f.columns.length > 0
770
+ ? cols.map((c, i) => (f.columns.includes(c.field) ? i : -1)).filter((i) => i >= 0)
771
+ : cols.map((_, i) => i);
772
+ for (const ci of targetIdxs) {
773
+ if (f.type === 'dataBar')
774
+ condFormats.push({ kind: 'dataBar', colIdx: ci, color: f.color });
775
+ else {
776
+ // min/mid/max are optional on the format; fall back to the same defaults
777
+ // the on-screen renderer uses (#ffffff -> #000000) so the export matches.
778
+ const min = f.min ?? '#ffffff';
779
+ const max = f.max ?? '#000000';
780
+ condFormats.push({ kind: 'colorScale', colIdx: ci, colors: f.mid ? [min, f.mid, max] : [min, max] });
781
+ }
782
+ }
783
+ }
784
+ if (opts.signal?.aborted)
785
+ throw new DOMException('Export aborted', 'AbortError');
786
+ opts.onProgress?.({ phase: 'write', ratio: 0, total: src.length });
787
+ const { header, cells } = await buildXlsxCellMatrix(cols, src, rawValues, visual, link, {
788
+ onProgress: opts.onProgress,
789
+ signal: opts.signal,
790
+ precisionSafe: opts.precisionSafe,
791
+ });
792
+ const widths = opts.autoFitColumns !== false ? autoFitWidths(cols, src, rawValues) : undefined;
793
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
794
+ // Excel Table (ListObject): filter dropdowns + banded rows, and optionally a
795
+ // totals row with SUBTOTAL formulas over the summable columns.
796
+ let table;
797
+ if (opts.excelTable) {
798
+ const totalsRow = typeof opts.excelTable === 'object' ? opts.excelTable.totalsRow === true : false;
799
+ const style = typeof opts.excelTable === 'object' ? opts.excelTable.style : undefined;
800
+ table = {
801
+ name: 'Table1',
802
+ totalsRow,
803
+ style,
804
+ totalsFns: cols.map((c) => (isSummableColumn(c) ? 'sum' : undefined)),
805
+ };
806
+ }
807
+ const parts = buildXlsxParts({
808
+ sheetName: filename,
809
+ header,
810
+ rows: cells,
811
+ widths,
812
+ freezeHeader: opts.freezeHeader !== false,
813
+ freezeColumns: resolveFreezeColumns(api, opts, cols),
814
+ condFormats,
815
+ table,
816
+ });
817
+ const blob = await packageXlsx(parts, JSZip);
818
+ opts.onProgress?.({ phase: 'write', ratio: 1, total: src.length });
819
+ return deliver(blob, ensureExt(filename, 'xlsx'), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', src.length, opts.download);
820
+ }
821
+ export async function exportGrid(api, opts) {
822
+ assertEnterpriseLicensed('Export');
823
+ // Native text formats have their own dependency-free, streaming path.
824
+ if (NATIVE_TEXT_FORMATS.includes(opts.format)) {
825
+ return exportTextFormat(api, opts);
826
+ }
827
+ // Legacy xls (SpreadsheetML) is also dependency-free.
828
+ if (opts.format === 'xls') {
829
+ return exportXls(api, opts);
830
+ }
831
+ // PDF via our own pdfmake docDefinition.
832
+ if (opts.format === 'pdf') {
833
+ return exportPdf(api, opts);
834
+ }
835
+ // Native single-sheet xlsx (our OOXML writer): typed numbers + number
836
+ // formats, real per-cell conditional-format fills, freeze, widths, and
837
+ // hyperlinks. Grouping (Excel outline), multi-sheet, images, merges, and
838
+ // header/footer lines keep the vendored writer below.
839
+ if (opts.format === 'xlsx') {
840
+ const gridGrouping = opts.autoGroup !== false ? (api.getState().grouping ?? []).filter((id) => !!id) : [];
841
+ const grouped = (opts.groupBy?.length ?? 0) > 0 || gridGrouping.length > 0;
842
+ // Blanket `styles` (header fill / zebra) are applied by the vendored
843
+ // writer, not our OOXML one - so a styled export (without conditional
844
+ // formatting, which the native writer does render) keeps the Smart path.
845
+ const wantsBlanketStyles = !!opts.styles && !opts.conditionalFormats?.length;
846
+ if (!opts.sheets?.length &&
847
+ !grouped &&
848
+ !opts.hierarchical &&
849
+ !opts.merges?.length &&
850
+ !opts.header?.length &&
851
+ !opts.footer?.length &&
852
+ !opts.imageFields?.length &&
853
+ !wantsBlanketStyles) {
854
+ return exportXlsxNative(api, opts);
855
+ }
856
+ }
857
+ await ensureGlobals(opts.format);
858
+ const Ctor = await getDataExporter();
859
+ // Multi-sheet path. Smart's `spreadsheets` option takes an array of
860
+ // `{ label, dataSource, columns, dataFields? }`. Each entry becomes one
861
+ // tab; the exporter prepends its own header row built from `columns`.
862
+ if (opts.sheets && opts.sheets.length > 0) {
863
+ if (opts.format !== 'xlsx') {
864
+ throw new Error(`@svgrid/enterprise: multi-sheet export requires format 'xlsx', got '${opts.format}'`);
865
+ }
866
+ const rawValues = opts.rawValues === true;
867
+ const sheets = opts.sheets.map((sheet) => {
868
+ // Reuse the single-sheet column derivation (explicit → grid columns →
869
+ // row keys), so per-sheet columns pick up `format` for formatting too.
870
+ const cols = resolveColumns(api, { columns: sheet.columns ?? opts.columns }, sheet.rows);
871
+ // Project each row to only the included fields (in column order),
872
+ // applying per-column formatting / exportValue.
873
+ const dataSource = sheet.rows.map((r) => {
874
+ const out = {};
875
+ for (const c of cols)
876
+ out[c.field] = cellValueFor(c, r, rawValues);
877
+ return out;
878
+ });
879
+ const widths = opts.autoFitColumns !== false ? autoFitWidths(cols, sheet.rows, rawValues) : null;
880
+ return {
881
+ label: sheet.label,
882
+ dataSource,
883
+ columns: cols.map((c, i) => widths
884
+ ? { dataField: c.field, label: c.header ?? c.field, width: widths[i] }
885
+ : { dataField: c.field, label: c.header ?? c.field }),
886
+ dataFields: cols.map((c) => c.field),
887
+ style: translateStyles(sheet.styles ?? opts.styles),
888
+ };
889
+ });
890
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
891
+ const ctorOpts = buildExporterOptions(opts);
892
+ // Smart needs at least one main sheet to operate. Use the first sheet
893
+ // as the "main" exportData payload AND keep the full set on the
894
+ // `spreadsheets` property so the workbook ends up with one tab per
895
+ // entry.
896
+ const firstSheet = sheets[0];
897
+ const exporter = new Ctor(ctorOpts);
898
+ exporter.spreadsheets = sheets;
899
+ applyInstanceOptions(exporter, opts, firstSheet.dataFields);
900
+ // First sheet's data goes through the standard exportData path with
901
+ // its own header row.
902
+ const headerRow = {};
903
+ for (const c of firstSheet.columns)
904
+ headerRow[c.dataField] = c.label;
905
+ const firstSheetRows = [headerRow, ...firstSheet.dataSource];
906
+ if (opts.download === false) {
907
+ throw new Error('@svgrid/enterprise: download:false is not supported for multi-sheet xlsx.');
908
+ }
909
+ exporter.exportData(firstSheetRows, opts.format, filename);
910
+ return undefined;
911
+ }
912
+ // Single-sheet xlsx (grouped / merges / header / footer) path.
913
+ const sourceRows = resolveRowSource(api, opts.rows);
914
+ if (sourceRows.length === 0) {
915
+ throw new Error('@svgrid/enterprise: nothing to export - the grid has no rows');
916
+ }
917
+ const cols = resolveColumns(api, opts, sourceRows);
918
+ const rows = await projectRows(sourceRows, cols, opts);
919
+ const filename = (opts.filename ?? 'grid').trim() || 'grid';
920
+ const datafields = cols.map((c) => c.field);
921
+ // Auto-carry the grid's active row grouping (unless the caller opted out,
922
+ // passed their own groupBy, or is exporting a hierarchy). Grouping column
923
+ // ids line up with field names, which are the projected row keys.
924
+ const autoGrouping = opts.autoGroup !== false && !opts.groupBy?.length && !opts.hierarchical
925
+ ? (api.getState().grouping ?? []).filter((id) => !!id).map((id) => String(id))
926
+ : [];
927
+ const effectiveGroupBy = opts.groupBy?.length
928
+ ? opts.groupBy
929
+ : autoGrouping.length > 0
930
+ ? autoGrouping
931
+ : undefined;
932
+ // The constructor's SECOND arg is `groupBy`: when non-empty AND
933
+ // `hierarchical` is NOT set, Smart wraps each group of rows in an
934
+ // Excel outline row with an expand/collapse button at the group key.
935
+ const groupBy = !opts.hierarchical && effectiveGroupBy?.length ? effectiveGroupBy : undefined;
936
+ // Conditional formatting -> a per-cell style map (A1 refs) that Smart's xlsx
937
+ // writer applies, plus icon-set glyphs prepended to the cell text.
938
+ const ctorOpts = buildExporterOptions(opts);
939
+ if (opts.conditionalFormats?.length) {
940
+ const visual = buildConditionalResolver(cols, sourceRows, opts.conditionalFormats);
941
+ const cfCells = {};
942
+ for (let r = 0; r < sourceRows.length; r++) {
943
+ for (let c = 0; c < cols.length; c++) {
944
+ const v = visual(r, c);
945
+ if (!v)
946
+ continue;
947
+ const st = {};
948
+ if (v.fill)
949
+ st.backgroundColor = v.fill;
950
+ if (v.color)
951
+ st.color = v.color;
952
+ if (v.bold)
953
+ st.fontWeight = 'bold';
954
+ if (Object.keys(st).length)
955
+ cfCells[colLetter(c) + (r + 2)] = st; // header is row 1
956
+ if (v.icon) {
957
+ const dataRow = rows[r + 1]; // header at index 0
958
+ const field = cols[c].field;
959
+ if (dataRow)
960
+ dataRow[field] = `${v.icon} ${dataRow[field] ?? ''}`;
961
+ }
962
+ }
963
+ }
964
+ if (Object.keys(cfCells).length) {
965
+ const style = ctorOpts.style ?? {};
966
+ ctorOpts.style = {
967
+ ...style,
968
+ cells: { ...(style.cells ?? {}), ...cfCells },
969
+ };
970
+ }
971
+ }
972
+ if (opts.download === false) {
973
+ throw new Error('@svgrid/enterprise: download:false is not supported for this xlsx export (grouped / merges / header / footer / images). Use a plain xlsx, xls, pdf, or a text format.');
974
+ }
975
+ if (opts.signal?.aborted)
976
+ throw new DOMException('Export aborted', 'AbortError');
977
+ opts.onProgress?.({ phase: 'write', ratio: 0, total: rows.length - 1 });
978
+ const exporter = new Ctor(ctorOpts, groupBy);
979
+ applyInstanceOptions(exporter, opts, datafields);
980
+ exporter.exportData(rows, opts.format, filename);
981
+ opts.onProgress?.({ phase: 'write', ratio: 1, total: rows.length - 1 });
982
+ return undefined;
983
+ }
984
+ /** Write text (and, for html, rich text/html) to the clipboard. */
985
+ async function writeClipboard(text, format) {
986
+ const nav = typeof navigator !== 'undefined' ? navigator : undefined;
987
+ if (!nav?.clipboard) {
988
+ throw new Error('@svgrid/enterprise: clipboard is unavailable (needs a secure context + user gesture)');
989
+ }
990
+ // For html, offer BOTH text/html (rich paste into Excel / Sheets / Docs) and
991
+ // a text/plain fallback. ClipboardItem may be missing in older browsers.
992
+ const CI = globalThis.ClipboardItem;
993
+ if (format === 'html' && CI && nav.clipboard.write) {
994
+ const item = new CI({
995
+ 'text/html': new Blob([text], { type: 'text/html' }),
996
+ 'text/plain': new Blob([text], { type: 'text/plain' }),
997
+ });
998
+ await nav.clipboard.write([item]);
999
+ return;
1000
+ }
1001
+ await nav.clipboard.writeText(text);
1002
+ }
1003
+ /**
1004
+ * Copy the grid (current view / selection / all) to the clipboard in a native
1005
+ * text format instead of downloading a file. Defaults to `tsv`, which pastes
1006
+ * straight into Excel / Google Sheets as real columns. `html` writes rich
1007
+ * `text/html` so pasted cells keep their table structure.
1008
+ */
1009
+ export async function copyExportToClipboard(api, opts = {}) {
1010
+ assertEnterpriseLicensed('Export');
1011
+ const format = opts.format ?? 'tsv';
1012
+ const sourceRows = resolveRowSource(api, opts.rows);
1013
+ if (sourceRows.length === 0) {
1014
+ throw new Error('@svgrid/enterprise: nothing to copy - the grid has no rows');
1015
+ }
1016
+ const cols = resolveColumns(api, opts, sourceRows);
1017
+ const projectOpts = format === 'json' ? { ...opts, rawValues: opts.rawValues ?? true } : opts;
1018
+ const projected = await projectRows(sourceRows, cols, projectOpts);
1019
+ const { text } = await serializeNative(format, projected, cols, opts);
1020
+ await writeClipboard(text, format);
1021
+ }