@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
@@ -1,198 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import type { ServerRequest } from '@svgrid/grid'
3
- import type { EntitySchema } from '../schema'
4
- import { createSqlDataSource, type SqlExecutor } from './sql-source'
5
-
6
- type Customer = { id: string; name: string; age: number }
7
-
8
- const schema: EntitySchema<Customer> = {
9
- name: 'customers',
10
- idField: 'id',
11
- fields: [
12
- { field: 'id', type: 'text', primaryKey: true },
13
- { field: 'name', type: 'text' },
14
- { field: 'age', type: 'number' },
15
- ],
16
- }
17
-
18
- /** Records every (sql, params) and returns queued results per call. */
19
- function recorder(results: Array<ReadonlyArray<Record<string, unknown>>>) {
20
- const calls: Array<{ sql: string; params: unknown[] }> = []
21
- let i = 0
22
- const execute: SqlExecutor = async (sql, params) => {
23
- calls.push({ sql, params })
24
- return results[i++] ?? []
25
- }
26
- return { execute, calls }
27
- }
28
-
29
- const req = (p: Partial<ServerRequest>): ServerRequest => ({
30
- startRow: 0,
31
- endRow: 50,
32
- pageIndex: 0,
33
- pageSize: 50,
34
- sortModel: [],
35
- filterModel: {},
36
- ...p,
37
- })
38
-
39
- describe('createSqlDataSource reads', () => {
40
- it('builds a parameterized SELECT + COUNT and maps the result', async () => {
41
- const { execute, calls } = recorder([
42
- [{ id: '1', name: 'Ann', age: 30 }],
43
- [{ count: 7 }],
44
- ])
45
- const src = createSqlDataSource({ schema, table: 'customers', execute })
46
- const res = await src.getRows(
47
- req({
48
- filterModel: { columns: { age: { operator: 'greaterThan', value: '20' } } },
49
- sortModel: [{ id: 'name', desc: false }],
50
- startRow: 50,
51
- pageSize: 25,
52
- }),
53
- )
54
-
55
- expect(res.rowCount).toBe(7)
56
- expect(res.rows[0]?.name).toBe('Ann')
57
-
58
- expect(calls[0]!.sql).toBe(
59
- 'SELECT * FROM "customers" WHERE "age" > ? ORDER BY "name" ASC LIMIT 25 OFFSET 50',
60
- )
61
- expect(calls[0]!.params).toEqual([20])
62
- expect(calls[1]!.sql).toBe('SELECT COUNT(*) AS count FROM "customers" WHERE "age" > ?')
63
- expect(calls[1]!.params).toEqual([20])
64
- })
65
-
66
- it('schema-qualifies the table as "schema"."table" when dbSchema is set', async () => {
67
- const { execute, calls } = recorder([[{ id: '1' }], [{ count: 1 }]])
68
- const src = createSqlDataSource({ schema, table: 'customers', dbSchema: 'analytics', execute })
69
- await src.getRows(req({}))
70
- expect(calls[0]!.sql).toContain('FROM "analytics"."customers"')
71
- expect(calls[1]!.sql).toContain('FROM "analytics"."customers"')
72
- // Writes are qualified too.
73
- const { execute: ex2, calls: c2 } = recorder([[{ id: '9' }]])
74
- const src2 = createSqlDataSource({ schema, table: 'customers', dbSchema: 'analytics', execute: ex2 })
75
- await src2.createRow({ name: 'Zed' } as never)
76
- expect(c2[0]!.sql).toContain('INSERT INTO "analytics"."customers"')
77
- })
78
-
79
- it('honors the Postgres dialect ($ placeholders)', async () => {
80
- const { execute, calls } = recorder([[], [{ count: 0 }]])
81
- const src = createSqlDataSource({
82
- schema,
83
- table: 'customers',
84
- execute,
85
- dialect: { placeholders: '$', ilike: true },
86
- })
87
- await src.getRows(req({ filterModel: { columns: { name: { operator: 'contains', value: 'a' } } } }))
88
- expect(calls[0]!.sql).toContain('"name" ILIKE $1')
89
- })
90
- })
91
-
92
- describe('createSqlDataSource writes', () => {
93
- it('creates with a parameterized INSERT ... RETURNING', async () => {
94
- const { execute, calls } = recorder([[{ id: '9', name: 'Zoe', age: 41 }]])
95
- const src = createSqlDataSource({ schema, table: 'customers', execute })
96
- const created = await src.createRow({ id: '9', name: 'Zoe', age: 41 })
97
- expect(created).toEqual({ id: '9', name: 'Zoe', age: 41 })
98
- expect(calls[0]!.sql).toBe(
99
- 'INSERT INTO "customers" ("id", "name", "age") VALUES (?, ?, ?) RETURNING *',
100
- )
101
- expect(calls[0]!.params).toEqual(['9', 'Zoe', 41])
102
- })
103
-
104
- it('updates by id with SET + WHERE', async () => {
105
- const { execute, calls } = recorder([[{ id: '9', name: 'Zoe', age: 42 }]])
106
- const src = createSqlDataSource({ schema, table: 'customers', execute })
107
- await src.updateRow('9', { age: 42 })
108
- expect(calls[0]!.sql).toBe('UPDATE "customers" SET "age" = ? WHERE "id" = ? RETURNING *')
109
- expect(calls[0]!.params).toEqual([42, '9'])
110
- })
111
-
112
- it('deletes by id', async () => {
113
- const { execute, calls } = recorder([[]])
114
- const src = createSqlDataSource({ schema, table: 'customers', execute })
115
- await src.deleteRow('9')
116
- expect(calls[0]!.sql).toBe('DELETE FROM "customers" WHERE "id" = ?')
117
- expect(calls[0]!.params).toEqual(['9'])
118
- })
119
-
120
- it('omits RETURNING and echoes input when returning:false (MySQL)', async () => {
121
- const { execute, calls } = recorder([[]])
122
- const src = createSqlDataSource({ schema, table: 'customers', execute, returning: false })
123
- const created = await src.createRow({ id: '1', name: 'A', age: 1 })
124
- expect(calls[0]!.sql).not.toContain('RETURNING')
125
- expect(created).toEqual({ id: '1', name: 'A', age: 1 })
126
- })
127
-
128
- it('getAggregate emits a GROUP BY with quoted identifiers', async () => {
129
- const { execute, calls } = recorder([[{ category: 'x', value: 10 }, { category: 'y', value: 5 }]])
130
- const src = createSqlDataSource({ schema, table: 'customers', execute })
131
- const out = await src.getAggregate({ dimension: 'name', measure: 'age', reduce: 'sum' })
132
- expect(calls[0]!.sql).toBe('SELECT "name" AS category, SUM("age") AS value FROM "customers" GROUP BY "name" ORDER BY value DESC')
133
- expect(out).toEqual([{ category: 'x', value: 10 }, { category: 'y', value: 5 }])
134
- })
135
-
136
- it('getAggregate uses COUNT(*) for reduce:count', async () => {
137
- const { execute, calls } = recorder([[]])
138
- const src = createSqlDataSource({ schema, table: 'customers', execute })
139
- await src.getAggregate({ dimension: 'name', reduce: 'count' })
140
- expect(calls[0]!.sql).toContain('COUNT(*) AS value')
141
- expect(calls[0]!.sql).toContain('GROUP BY "name"')
142
- })
143
-
144
- it('getAggregate with no dimension emits a single total (no GROUP BY) - a KPI', async () => {
145
- const { execute, calls } = recorder([[{ value: 42 }]])
146
- const src = createSqlDataSource({ schema, table: 'customers', execute })
147
- const out = await src.getAggregate({ measure: 'age', reduce: 'sum' })
148
- expect(calls[0]!.sql).toBe('SELECT SUM("age") AS value FROM "customers"')
149
- expect(calls[0]!.sql).not.toContain('GROUP BY')
150
- expect(out).toEqual([{ category: '', value: 42 }])
151
- })
152
- })
153
-
154
- // A schema whose fields are renamed relative to their DB columns (the Drizzle
155
- // `createdAt: timestamp('created_at')` case).
156
- type Ev = { id: string; startsAt: string }
157
- const renamedSchema: EntitySchema<Ev> = {
158
- name: 'events',
159
- idField: 'id',
160
- fields: [
161
- { field: 'id', dbColumn: 'event_id', type: 'text', primaryKey: true },
162
- { field: 'startsAt', dbColumn: 'starts_at', type: 'datetime' },
163
- ],
164
- }
165
-
166
- describe('createSqlDataSource honors dbColumn (renamed columns)', () => {
167
- it('SELECTs the real columns aliased back to the field names', async () => {
168
- const { execute, calls } = recorder([[{ id: '1', startsAt: 'x' }], [{ count: 1 }]])
169
- const src = createSqlDataSource({ schema: renamedSchema, table: 'events', execute })
170
- await src.getRows(req({ sortModel: [{ id: 'startsAt', desc: true }] }))
171
- expect(calls[0]!.sql).toContain('SELECT "event_id" AS "id", "starts_at" AS "startsAt" FROM "events"')
172
- expect(calls[0]!.sql).toContain('ORDER BY "starts_at" DESC') // sort uses the DB column
173
- })
174
-
175
- it('filters on the real column', async () => {
176
- const { execute, calls } = recorder([[], [{ count: 0 }]])
177
- const src = createSqlDataSource({ schema: renamedSchema, table: 'events', execute })
178
- await src.getRows(req({ filterModel: { columns: { startsAt: { operator: 'contains', value: '2026' } } } }))
179
- // The WHERE predicate targets the real DB column, not the field name.
180
- expect(calls[0]!.sql).toContain('LOWER("starts_at") LIKE')
181
- expect(calls[0]!.sql).not.toContain('LOWER("startsAt")')
182
- })
183
-
184
- it('INSERT / UPDATE write the real columns and RETURNING aliases back', async () => {
185
- const { execute, calls } = recorder([[{ id: '9', startsAt: 'y' }]])
186
- const src = createSqlDataSource({ schema: renamedSchema, table: 'events', execute })
187
- await src.createRow({ id: '9', startsAt: 'y' })
188
- expect(calls[0]!.sql).toContain('INSERT INTO "events" ("event_id", "starts_at")')
189
- expect(calls[0]!.sql).toContain('RETURNING "event_id" AS "id", "starts_at" AS "startsAt"')
190
- })
191
-
192
- it('getAggregate reduces the real measure column', async () => {
193
- const { execute, calls } = recorder([[{ value: 3 }]])
194
- const src = createSqlDataSource({ schema: renamedSchema, table: 'events', execute })
195
- await src.getAggregate({ dimension: 'startsAt', reduce: 'count' })
196
- expect(calls[0]!.sql).toContain('GROUP BY "starts_at"')
197
- })
198
- })
@@ -1,171 +0,0 @@
1
- /**
2
- * createSqlDataSource - a production `ServerDataSource` backed by any SQL
3
- * database. It plans the read with `planQuery` + `planToSql`, and builds
4
- * parameterized INSERT / UPDATE / DELETE for writes. You supply one thing: an
5
- * `execute(sql, params)` that runs a query and returns rows. Every SQL client
6
- * SvelteKit teams use provides that - Drizzle (`db.execute`), postgres.js,
7
- * better-sqlite3, mysql2 - so this is the turnkey "point at your database"
8
- * adapter, the sibling of `createInMemoryDataSource`.
9
- *
10
- * All values are parameterized; identifiers come from the schema-whitelisted
11
- * plan and are quoted. No string interpolation of user input.
12
- *
13
- * Drizzle (Postgres) example:
14
- *
15
- * import { sql } from 'drizzle-orm'
16
- * const source = createSqlDataSource({
17
- * schema: customerSchema,
18
- * table: 'customers',
19
- * dialect: { placeholders: '$', ilike: true },
20
- * execute: (text, params) =>
21
- * db.execute(sql.raw(text, params)).then((r) => r.rows),
22
- * })
23
- */
24
- import type { RowData, ServerRequest, ServerResult } from '@svgrid/grid'
25
- import { resolveIdField, type EntitySchema } from '../schema'
26
- import { nudgeEnterprise } from '../license'
27
- import { planQuery } from './query-plan'
28
- import { planToSql, type SqlDialect } from './sql'
29
- import type { WritableDataSource } from './types'
30
- import type { AggregateBucket, AggregateRequest, AggregateSource } from '../sources/aggregate'
31
-
32
- const SQL_AGG: Record<'sum' | 'avg' | 'min' | 'max', string> = { sum: 'SUM', avg: 'AVG', min: 'MIN', max: 'MAX' }
33
-
34
- /** Run a parameterized query, resolving to the result rows. */
35
- export type SqlExecutor = (
36
- sql: string,
37
- params: unknown[],
38
- ) => Promise<ReadonlyArray<Record<string, unknown>>>
39
-
40
- export type SqlDataSourceConfig<TData extends RowData> = {
41
- schema: EntitySchema<TData>
42
- /** Table (or view) name. Quoted per the dialect; not interpolated raw. */
43
- table: string
44
- /** DB schema / namespace (e.g. Postgres `public`, SQL Server `dbo`). When set,
45
- * the table is addressed as `"schema"."table"`. Each part is quoted separately. */
46
- dbSchema?: string
47
- execute: SqlExecutor
48
- dialect?: SqlDialect
49
- /**
50
- * Append `RETURNING *` to writes and return the row the database echoes back
51
- * (Postgres / SQLite). Set false for MySQL, where the input is returned as-is.
52
- * Default true.
53
- */
54
- returning?: boolean
55
- }
56
-
57
- function quoter(dialect: SqlDialect) {
58
- const q = dialect.quote ?? '"'
59
- return (name: string) => `${q}${name.replace(new RegExp(q, 'g'), q + q)}${q}`
60
- }
61
-
62
- function binder(dialect: SqlDialect, params: unknown[]) {
63
- return (value: unknown) => {
64
- params.push(value)
65
- if (dialect.placeholders === '$') return `$${params.length}`
66
- if (dialect.placeholders === '@') return `@p${params.length}`
67
- return '?'
68
- }
69
- }
70
-
71
- const squish = (sql: string) => sql.replace(/\s+/g, ' ').trim()
72
-
73
- export function createSqlDataSource<TData extends RowData>(
74
- config: SqlDataSourceConfig<TData>,
75
- ): WritableDataSource<TData> & AggregateSource {
76
- nudgeEnterprise('Studio') // soft-gate; never blocks, safe on the server
77
- const { schema, execute } = config
78
- const dialect = config.dialect ?? {}
79
- const returning = config.returning ?? true
80
- const id = quoter(dialect)
81
- const idField = resolveIdField(schema)
82
- // Optionally schema-qualify the table: "schema"."table" (each part quoted separately).
83
- const qtable = config.dbSchema ? `${id(config.dbSchema)}.${id(config.table)}` : id(config.table)
84
-
85
- // Column mapping: when a field has a `dbColumn` (e.g. Drizzle `created_at` vs
86
- // key `createdAt`), read/write the real column and alias it back to the field.
87
- // With no renames, everything is identity - the emitted SQL is byte-identical.
88
- const dbCol = new Map(schema.fields.filter((f) => f.dbColumn).map((f) => [f.field, f.dbColumn!]))
89
- const hasRenames = dbCol.size > 0
90
- const columnOf = (field: string): string => dbCol.get(field) ?? field
91
- const col = (field: string): string => id(columnOf(field))
92
- const projection = hasRenames
93
- ? schema.fields.map((f) => `${id(columnOf(f.field))} AS ${id(f.field)}`).join(', ')
94
- : '*'
95
- const planDialect: SqlDialect = hasRenames ? { ...dialect, column: columnOf } : dialect
96
- const RET = returning ? ` RETURNING ${projection}` : ''
97
-
98
- return {
99
- async getRows(request: ServerRequest): Promise<ServerResult<TData>> {
100
- const plan = planQuery(schema, request)
101
- const sql = planToSql(plan, planDialect)
102
- const t = qtable
103
- const rowsSql = squish(
104
- `SELECT ${projection} FROM ${t} ${sql.whereText} ${sql.orderByText} LIMIT ${sql.limit} OFFSET ${sql.offset}`,
105
- )
106
- const countSql = squish(`SELECT COUNT(*) AS count FROM ${t} ${sql.whereText}`)
107
- const rows = await execute(rowsSql, sql.params)
108
- const countRows = await execute(countSql, sql.params)
109
- const rowCount = Number(countRows[0]?.count ?? rows.length)
110
- return { rows: rows as ReadonlyArray<TData>, rowCount }
111
- },
112
-
113
- async createRow(input: Partial<TData>): Promise<TData> {
114
- const cols = Object.keys(input)
115
- if (cols.length === 0) throw new Error('createSqlDataSource: createRow needs at least one field')
116
- const params: unknown[] = []
117
- const bind = binder(dialect, params)
118
- const values = cols.map((c) => bind((input as RowData)[c]))
119
- const sql = squish(
120
- `INSERT INTO ${qtable} (${cols.map(col).join(', ')}) VALUES (${values.join(', ')})${RET}`,
121
- )
122
- const rows = await execute(sql, params)
123
- return (rows[0] ?? input) as TData
124
- },
125
-
126
- async updateRow(rowIdValue: string, patch: Partial<TData>): Promise<TData> {
127
- const cols = Object.keys(patch)
128
- if (cols.length === 0) throw new Error('createSqlDataSource: updateRow needs at least one field')
129
- const params: unknown[] = []
130
- const bind = binder(dialect, params)
131
- const sets = cols.map((c) => `${col(c)} = ${bind((patch as RowData)[c])}`)
132
- const where = `${col(idField)} = ${bind(rowIdValue)}`
133
- const sql = squish(`UPDATE ${qtable} SET ${sets.join(', ')} WHERE ${where}${RET}`)
134
- const rows = await execute(sql, params)
135
- return (rows[0] ?? { ...patch, [idField]: rowIdValue }) as TData
136
- },
137
-
138
- async deleteRow(rowIdValue: string): Promise<void> {
139
- const params: unknown[] = []
140
- const bind = binder(dialect, params)
141
- const sql = squish(`DELETE FROM ${qtable} WHERE ${col(idField)} = ${bind(rowIdValue)}`)
142
- await execute(sql, params)
143
- },
144
-
145
- async getAggregate(request: AggregateRequest): Promise<AggregateBucket[]> {
146
- // Server-side GROUP BY. Identifiers are schema-quoted (no interpolation of
147
- // user input); the WHERE + params come from the shared query plan.
148
- const plan = planQuery(schema, {
149
- startRow: 0, endRow: 0, pageIndex: 0, pageSize: 0, sortModel: [],
150
- filterModel: request.filterModel ?? {},
151
- })
152
- const sql = planToSql(plan, planDialect)
153
- const fn =
154
- request.reduce === 'count' || !request.measure
155
- ? 'COUNT(*)'
156
- : `${SQL_AGG[request.reduce]}(${col(request.measure)})`
157
- // No dimension -> a single grand total (a KPI), no GROUP BY.
158
- if (!request.dimension) {
159
- const text = squish(`SELECT ${fn} AS value FROM ${qtable} ${sql.whereText}`)
160
- const rows = await execute(text, sql.params)
161
- return [{ category: '', value: Number(rows[0]?.value ?? 0) }]
162
- }
163
- const dim = col(request.dimension)
164
- const text = squish(
165
- `SELECT ${dim} AS category, ${fn} AS value FROM ${qtable} ${sql.whereText} GROUP BY ${dim} ORDER BY value DESC`,
166
- )
167
- const rows = await execute(text, sql.params)
168
- return rows.map((r) => ({ category: String(r.category ?? ''), value: Number(r.value ?? 0) }))
169
- },
170
- }
171
- }
@@ -1,80 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import type { QueryPlan } from './query-plan'
3
- import { planToSql } from './sql'
4
-
5
- const base: QueryPlan = { where: [], search: null, orderBy: [], limit: 50, offset: 0 }
6
-
7
- describe('planToSql', () => {
8
- it('emits parameterized predicates with ANSI defaults', () => {
9
- const plan: QueryPlan = {
10
- ...base,
11
- where: [
12
- { field: 'age', op: 'gt', value: 30 },
13
- { field: 'name', op: 'contains', value: 'ann' },
14
- ],
15
- }
16
- const sql = planToSql(plan)
17
- expect(sql.whereText).toBe('WHERE "age" > ? AND LOWER("name") LIKE LOWER(?)')
18
- expect(sql.params).toEqual([30, '%ann%'])
19
- })
20
-
21
- it('supports the Postgres dialect: $ placeholders and ILIKE', () => {
22
- const plan: QueryPlan = { ...base, where: [{ field: 'name', op: 'startsWith', value: 'A' }] }
23
- const sql = planToSql(plan, { placeholders: '$', ilike: true })
24
- expect(sql.whereText).toBe('WHERE "name" ILIKE $1')
25
- expect(sql.params).toEqual(['A%'])
26
- })
27
-
28
- it('supports SQL Server @p placeholders', () => {
29
- const plan: QueryPlan = { ...base, where: [{ field: 'age', op: 'gt', value: 30 }] }
30
- const sql = planToSql(plan, { placeholders: '@' })
31
- expect(sql.whereText).toBe('WHERE "age" > @p1')
32
- expect(sql.params).toEqual([30])
33
- })
34
-
35
- it('renders between, isBlank, and in', () => {
36
- const plan: QueryPlan = {
37
- ...base,
38
- where: [
39
- { field: 'age', op: 'between', value: 20, valueTo: 40 },
40
- { field: 'note', op: 'isBlank' },
41
- { field: 'tier', op: 'in', values: ['free', 'pro'] },
42
- ],
43
- }
44
- const sql = planToSql(plan)
45
- expect(sql.where).toBe(
46
- '"age" BETWEEN ? AND ? AND ("note" IS NULL OR "note" = \'\') AND "tier" IN (?, ?)',
47
- )
48
- expect(sql.params).toEqual([20, 40, 'free', 'pro'])
49
- })
50
-
51
- it('an empty `in` matches nothing', () => {
52
- const sql = planToSql({ ...base, where: [{ field: 'tier', op: 'in', values: [] }] })
53
- expect(sql.where).toBe('1 = 0')
54
- expect(sql.params).toEqual([])
55
- })
56
-
57
- it('appends a global search as an OR group after the column predicates', () => {
58
- const plan: QueryPlan = {
59
- ...base,
60
- where: [{ field: 'age', op: 'gt', value: 1 }],
61
- search: { term: 'acme', fields: ['name', 'tier'] },
62
- }
63
- const sql = planToSql(plan)
64
- expect(sql.where).toBe(
65
- '"age" > ? AND (LOWER("name") LIKE LOWER(?) OR LOWER("tier") LIKE LOWER(?))',
66
- )
67
- expect(sql.params).toEqual([1, '%acme%', '%acme%'])
68
- })
69
-
70
- it('builds order by and leaves where empty when there are no predicates', () => {
71
- const sql = planToSql({ ...base, orderBy: [{ field: 'name', desc: false }, { field: 'age', desc: true }] })
72
- expect(sql.whereText).toBe('')
73
- expect(sql.orderByText).toBe('ORDER BY "name" ASC, "age" DESC')
74
- })
75
-
76
- it('escapes identifier quote chars', () => {
77
- const sql = planToSql({ ...base, where: [{ field: 'we"ird', op: 'eq', value: 1 }] })
78
- expect(sql.where).toBe('"we""ird" = ?')
79
- })
80
- })
@@ -1,131 +0,0 @@
1
- /**
2
- * `planToSql` - turn a `QueryPlan` into a portable, parameterized SQL fragment.
3
- * This is the backend seam for every SQL database: Drizzle, postgres.js,
4
- * better-sqlite3, mysql2. It emits only a WHERE body, an ORDER BY body, and a
5
- * params array - never a full statement - so you keep control of the SELECT,
6
- * the table, joins, and execution.
7
- *
8
- * All values are parameterized (never interpolated) and every identifier comes
9
- * from the plan, which `planQuery` already whitelisted against the schema - so
10
- * there is no SQL-injection surface here.
11
- *
12
- * Drizzle usage (Postgres):
13
- *
14
- * import { sql } from 'drizzle-orm'
15
- * const { whereText, orderByText, params, limit, offset } =
16
- * planToSql(plan, { placeholders: '$', ilike: true })
17
- * const rows = await db.execute(
18
- * sql.raw(`select * from customers ${whereText} ${orderByText} limit ${limit} offset ${offset}`, params)
19
- * )
20
- *
21
- * (Or map `plan.where` to Drizzle operators directly - the plan is the seam
22
- * either way.)
23
- */
24
- import type { PlanPredicate, QueryPlan } from './query-plan'
25
-
26
- export type SqlDialect = {
27
- /** Identifier quote char. Default `"` (ANSI / Postgres / SQLite). MySQL: `` ` ``. */
28
- quote?: string
29
- /** Placeholder style: `'?'` (SQLite / MySQL), `'$'` for `$1, $2` (Postgres), or `'@'` for `@p1, @p2` (SQL Server). Default `'?'`. */
30
- placeholders?: '?' | '$' | '@'
31
- /** Use `ILIKE` for case-insensitive matching (Postgres) instead of `LOWER(col) LIKE LOWER(?)`. */
32
- ilike?: boolean
33
- /** Map a schema `field` to its real DB column. Default: identity. Lets renamed columns (Drizzle `created_at` vs key `createdAt`) plan correctly. */
34
- column?: (field: string) => string
35
- }
36
-
37
- export type SqlPlan = {
38
- /** WHERE body without the keyword, e.g. `"age" > ? AND "name" ILIKE ?`. Empty string when no predicates. */
39
- where: string
40
- /** WHERE body with the leading `WHERE ` keyword, or `''`. */
41
- whereText: string
42
- /** ORDER BY body without the keyword, e.g. `"name" ASC, "age" DESC`. */
43
- orderBy: string
44
- /** ORDER BY body with the leading `ORDER BY ` keyword, or `''`. */
45
- orderByText: string
46
- params: unknown[]
47
- limit: number
48
- offset: number
49
- }
50
-
51
- export function planToSql(plan: QueryPlan, dialect: SqlDialect = {}): SqlPlan {
52
- const q = dialect.quote ?? '"'
53
- const useIlike = dialect.ilike ?? false
54
- const params: unknown[] = []
55
-
56
- const ph = () => {
57
- if (dialect.placeholders === '$') return `$${params.length}`
58
- if (dialect.placeholders === '@') return `@p${params.length}`
59
- return '?'
60
- }
61
- const bind = (v: unknown): string => {
62
- params.push(v)
63
- return ph()
64
- }
65
- const columnFor = dialect.column ?? ((f: string) => f)
66
- const id = (field: string) => {
67
- const c = columnFor(field)
68
- return `${q}${c.replace(new RegExp(q, 'g'), q + q)}${q}`
69
- }
70
-
71
- const like = (field: string, pattern: string): string => {
72
- const p = bind(pattern)
73
- return useIlike ? `${id(field)} ILIKE ${p}` : `LOWER(${id(field)}) LIKE LOWER(${p})`
74
- }
75
-
76
- const clauses: string[] = []
77
-
78
- for (const pred of plan.where) {
79
- clauses.push(predicateSql(pred, { id, bind, like }))
80
- }
81
-
82
- if (plan.search && plan.search.fields.length > 0) {
83
- const term = `%${plan.search.term}%`
84
- const ors = plan.search.fields.map((f) => like(f, term))
85
- clauses.push(`(${ors.join(' OR ')})`)
86
- }
87
-
88
- const where = clauses.join(' AND ')
89
- const orderBy = plan.orderBy.map((o) => `${id(o.field)} ${o.desc ? 'DESC' : 'ASC'}`).join(', ')
90
-
91
- return {
92
- where,
93
- whereText: where ? `WHERE ${where}` : '',
94
- orderBy,
95
- orderByText: orderBy ? `ORDER BY ${orderBy}` : '',
96
- params,
97
- limit: plan.limit,
98
- offset: plan.offset,
99
- }
100
- }
101
-
102
- function predicateSql(
103
- pred: PlanPredicate,
104
- ctx: { id: (f: string) => string; bind: (v: unknown) => string; like: (f: string, p: string) => string },
105
- ): string {
106
- const { id, bind, like } = ctx
107
- const col = id(pred.field)
108
- switch (pred.op) {
109
- case 'eq':
110
- return `${col} = ${bind(pred.value)}`
111
- case 'contains':
112
- return like(pred.field, `%${pred.value}%`)
113
- case 'startsWith':
114
- return like(pred.field, `${pred.value}%`)
115
- case 'gt':
116
- return `${col} > ${bind(pred.value)}`
117
- case 'lt':
118
- return `${col} < ${bind(pred.value)}`
119
- case 'between':
120
- return `${col} BETWEEN ${bind(pred.value)} AND ${bind(pred.valueTo)}`
121
- case 'isBlank':
122
- return `(${col} IS NULL OR ${col} = '')`
123
- case 'in': {
124
- const vals = pred.values ?? []
125
- if (vals.length === 0) return '1 = 0' // empty IN () matches nothing
126
- return `${col} IN (${vals.map((v) => bind(v)).join(', ')})`
127
- }
128
- default:
129
- return '1 = 1'
130
- }
131
- }