@svgrid/enterprise 2.5.3 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (620) 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/dist/SvExpressionEditor.svelte.d.ts +12 -0
  8. package/dist/SvFileInput.svelte.d.ts +20 -0
  9. package/dist/SvGridAlerts.svelte.d.ts +77 -0
  10. package/dist/SvGridBoard.svelte.d.ts +30 -0
  11. package/dist/SvGridEditPanel.svelte.d.ts +73 -0
  12. package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
  13. package/dist/SvGridScheduler.svelte.d.ts +30 -0
  14. package/dist/SvImportDialog.svelte.d.ts +88 -0
  15. package/dist/SvLookupInput.svelte.d.ts +21 -0
  16. package/dist/SvPivotDesigner.svelte.d.ts +176 -0
  17. package/dist/SvRecordDetail.svelte.d.ts +58 -0
  18. package/dist/SvSchedule.svelte.d.ts +29 -0
  19. package/dist/SvSchemaChart.svelte.d.ts +61 -0
  20. package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
  21. package/dist/alerts/alert-engine-attach.d.ts +79 -0
  22. package/dist/alerts/alert-engine-attach.js +106 -0
  23. package/dist/alerts/alert-engine.d.ts +42 -0
  24. package/dist/alerts/alert-engine.js +196 -0
  25. package/dist/alerts/alert-formats.d.ts +26 -0
  26. package/dist/alerts/alert-formats.js +58 -0
  27. package/dist/alerts/alert-observer.d.ts +54 -0
  28. package/dist/alerts/alert-observer.js +156 -0
  29. package/dist/alerts/alert-scheduler.d.ts +30 -0
  30. package/dist/alerts/alert-scheduler.js +54 -0
  31. package/dist/alerts/alert-storage.d.ts +31 -0
  32. package/dist/alerts/alert-storage.js +92 -0
  33. package/dist/alerts/alert-store.svelte.d.ts +24 -0
  34. package/dist/alerts/alert-store.svelte.js +69 -0
  35. package/dist/alerts/alert-types.d.ts +86 -0
  36. package/dist/alerts/alert-types.js +1 -0
  37. package/dist/alerts.d.ts +2 -0
  38. package/{src/alerts.ts → dist/alerts.js} +9 -9
  39. package/dist/board.d.ts +7 -0
  40. package/{src/board.ts → dist/board.js} +13 -14
  41. package/dist/cdn/svgrid-enterprise.svelte-external.js +1 -1
  42. package/dist/designer/assets/{index-CBYU-KNn.js → index-BF0UH638.js} +3 -3
  43. package/dist/designer/assets/{src-i309BeJb.js → src-BPJruwB9.js} +1 -1
  44. package/dist/designer/index.html +2 -2
  45. package/dist/edit-panel.d.ts +105 -0
  46. package/dist/edit-panel.js +350 -0
  47. package/dist/export-conditional.d.ts +31 -0
  48. package/dist/export-conditional.js +65 -0
  49. package/dist/export-ooxml.d.ts +93 -0
  50. package/dist/export-ooxml.js +385 -0
  51. package/dist/export-pdf.d.ts +107 -0
  52. package/dist/export-pdf.js +144 -0
  53. package/dist/export-print.d.ts +55 -0
  54. package/dist/export-print.js +91 -0
  55. package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
  56. package/dist/export-serialize.js +11 -0
  57. package/dist/export-xls.d.ts +26 -0
  58. package/dist/export-xls.js +157 -0
  59. package/dist/export.d.ts +323 -0
  60. package/dist/export.js +1021 -0
  61. package/dist/expressions/evaluate.d.ts +17 -0
  62. package/dist/expressions/evaluate.js +214 -0
  63. package/dist/expressions/expression-columns.d.ts +61 -0
  64. package/dist/expressions/expression-columns.js +72 -0
  65. package/dist/expressions/expression-types.d.ts +125 -0
  66. package/dist/expressions/expression-types.js +1 -0
  67. package/dist/expressions/parse.d.ts +25 -0
  68. package/dist/expressions/parse.js +537 -0
  69. package/dist/import.d.ts +232 -0
  70. package/dist/import.js +846 -0
  71. package/dist/index.d.ts +66 -0
  72. package/dist/index.js +91 -0
  73. package/dist/install.d.ts +70 -0
  74. package/dist/install.js +61 -0
  75. package/dist/license-core.d.ts +37 -0
  76. package/dist/license-core.js +81 -0
  77. package/dist/license.d.ts +30 -0
  78. package/dist/license.js +139 -0
  79. package/dist/master-detail.d.ts +23 -0
  80. package/dist/master-detail.js +35 -0
  81. package/dist/node/studio.js +1 -1
  82. package/dist/pivot-chart.d.ts +28 -0
  83. package/dist/pivot-chart.js +71 -0
  84. package/dist/pivot-designer.d.ts +69 -0
  85. package/dist/pivot-designer.js +38 -0
  86. package/dist/pivot-enable.d.ts +6 -0
  87. package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
  88. package/dist/pivot.d.ts +111 -0
  89. package/dist/pivot.js +353 -0
  90. package/dist/print.d.ts +33 -0
  91. package/dist/print.js +61 -0
  92. package/dist/revoked.d.ts +1 -0
  93. package/{src/revoked.ts → dist/revoked.js} +5 -6
  94. package/dist/scheduler-assignments.d.ts +64 -0
  95. package/dist/scheduler-assignments.js +92 -0
  96. package/dist/scheduler-axis.d.ts +81 -0
  97. package/dist/scheduler-axis.js +180 -0
  98. package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
  99. package/dist/scheduler-booking.js +50 -0
  100. package/dist/scheduler-config.d.ts +177 -0
  101. package/dist/scheduler-config.js +1 -0
  102. package/dist/scheduler-dependencies.d.ts +89 -0
  103. package/dist/scheduler-dependencies.js +179 -0
  104. package/dist/scheduler-freebusy.d.ts +19 -0
  105. package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
  106. package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
  107. package/dist/scheduler-heatmap.js +41 -0
  108. package/dist/scheduler-resource-tree.d.ts +48 -0
  109. package/dist/scheduler-resource-tree.js +78 -0
  110. package/dist/scheduler-slots.d.ts +37 -0
  111. package/dist/scheduler-slots.js +80 -0
  112. package/dist/scheduler-summary.d.ts +41 -0
  113. package/dist/scheduler-summary.js +54 -0
  114. package/dist/scheduler.d.ts +7 -0
  115. package/{src/scheduler.ts → dist/scheduler.js} +13 -14
  116. package/dist/scheduling.d.ts +132 -0
  117. package/dist/scheduling.js +228 -0
  118. package/dist/schema-designer.d.ts +42 -0
  119. package/dist/schema-designer.js +117 -0
  120. package/dist/schema.d.ts +369 -0
  121. package/dist/schema.js +216 -0
  122. package/dist/smart-shim.d.ts +62 -0
  123. package/dist/smart-shim.js +34 -0
  124. package/dist/sources/aggregate.d.ts +43 -0
  125. package/dist/sources/aggregate.js +60 -0
  126. package/dist/sources/auth-supabase.d.ts +69 -0
  127. package/dist/sources/auth-supabase.js +39 -0
  128. package/dist/sources/dashboard.d.ts +65 -0
  129. package/dist/sources/dashboard.js +95 -0
  130. package/dist/sources/field-inference.d.ts +23 -0
  131. package/dist/sources/field-inference.js +52 -0
  132. package/dist/sources/filters.d.ts +35 -0
  133. package/dist/sources/filters.js +52 -0
  134. package/dist/sources/index.d.ts +18 -0
  135. package/dist/sources/index.js +18 -0
  136. package/dist/sources/introspect-supabase.d.ts +30 -0
  137. package/dist/sources/introspect-supabase.js +134 -0
  138. package/dist/sources/realtime-supabase.d.ts +37 -0
  139. package/dist/sources/realtime-supabase.js +52 -0
  140. package/dist/sources/relation-lookup.d.ts +50 -0
  141. package/dist/sources/relation-lookup.js +77 -0
  142. package/dist/sources/rest-adapters.d.ts +48 -0
  143. package/dist/sources/rest-adapters.js +85 -0
  144. package/dist/sources/rest.d.ts +38 -0
  145. package/dist/sources/rest.js +86 -0
  146. package/dist/sources/schema-from-columns.d.ts +37 -0
  147. package/dist/sources/schema-from-columns.js +48 -0
  148. package/dist/sources/supabase.d.ts +33 -0
  149. package/dist/sources/supabase.js +74 -0
  150. package/dist/sources/with-entity-rules.d.ts +25 -0
  151. package/dist/sources/with-entity-rules.js +47 -0
  152. package/dist/sources/with-relation-labels.d.ts +26 -0
  153. package/dist/sources/with-relation-labels.js +38 -0
  154. package/dist/staged-editing.d.ts +85 -0
  155. package/dist/staged-editing.js +0 -0
  156. package/dist/studio/bug-report.d.ts +61 -0
  157. package/dist/studio/bug-report.js +126 -0
  158. package/dist/studio/cli.d.ts +56 -0
  159. package/dist/studio/cli.js +70 -0
  160. package/dist/studio/copilot-core.d.ts +22 -0
  161. package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
  162. package/dist/studio/csv.d.ts +36 -0
  163. package/dist/studio/csv.js +173 -0
  164. package/dist/studio/db-connect-string.d.ts +45 -0
  165. package/dist/studio/db-connect-string.js +113 -0
  166. package/dist/studio/deploy-cli.d.ts +35 -0
  167. package/dist/studio/deploy-cli.js +81 -0
  168. package/dist/studio/emit-project.d.ts +77 -0
  169. package/dist/studio/emit-project.js +5389 -0
  170. package/dist/studio/emit-schema.d.ts +110 -0
  171. package/dist/studio/emit-schema.js +1128 -0
  172. package/dist/studio/index.d.ts +35 -0
  173. package/dist/studio/index.js +38 -0
  174. package/dist/studio/init-flow.d.ts +58 -0
  175. package/dist/studio/init-flow.js +451 -0
  176. package/dist/studio/introspect-db.d.ts +47 -0
  177. package/dist/studio/introspect-db.js +255 -0
  178. package/dist/studio/introspect-openapi.d.ts +19 -0
  179. package/dist/studio/introspect-openapi.js +244 -0
  180. package/dist/studio/introspect-prisma.d.ts +25 -0
  181. package/dist/studio/introspect-prisma.js +164 -0
  182. package/dist/studio/introspect.d.ts +35 -0
  183. package/dist/studio/introspect.js +306 -0
  184. package/dist/studio/project.d.ts +1327 -0
  185. package/dist/studio/project.js +1798 -0
  186. package/dist/studio/sample-data.d.ts +19 -0
  187. package/dist/studio/sample-data.js +207 -0
  188. package/dist/studio/samples/ats.d.ts +2 -0
  189. package/dist/studio/samples/ats.js +194 -0
  190. package/dist/studio/samples/clinic.d.ts +2 -0
  191. package/dist/studio/samples/clinic.js +171 -0
  192. package/dist/studio/samples/crm.d.ts +2 -0
  193. package/dist/studio/samples/crm.js +280 -0
  194. package/dist/studio/samples/datasets.d.ts +38 -0
  195. package/dist/studio/samples/datasets.js +296 -0
  196. package/dist/studio/samples/ecommerce.d.ts +2 -0
  197. package/dist/studio/samples/ecommerce.js +178 -0
  198. package/dist/studio/samples/events.d.ts +2 -0
  199. package/dist/studio/samples/events.js +192 -0
  200. package/dist/studio/samples/fleet.d.ts +2 -0
  201. package/dist/studio/samples/fleet.js +203 -0
  202. package/dist/studio/samples/gym.d.ts +2 -0
  203. package/dist/studio/samples/gym.js +205 -0
  204. package/dist/studio/samples/hr.d.ts +2 -0
  205. package/dist/studio/samples/hr.js +186 -0
  206. package/dist/studio/samples/index.d.ts +13 -0
  207. package/dist/studio/samples/index.js +44 -0
  208. package/dist/studio/samples/insurance.d.ts +2 -0
  209. package/dist/studio/samples/insurance.js +220 -0
  210. package/dist/studio/samples/inventory.d.ts +2 -0
  211. package/dist/studio/samples/inventory.js +204 -0
  212. package/dist/studio/samples/invoicing.d.ts +2 -0
  213. package/dist/studio/samples/invoicing.js +154 -0
  214. package/dist/studio/samples/library.d.ts +2 -0
  215. package/dist/studio/samples/library.js +171 -0
  216. package/dist/studio/samples/live-data.d.ts +5 -0
  217. package/dist/studio/samples/live-data.js +261 -0
  218. package/dist/studio/samples/projects.d.ts +2 -0
  219. package/dist/studio/samples/projects.js +203 -0
  220. package/dist/studio/samples/realestate.d.ts +2 -0
  221. package/dist/studio/samples/realestate.js +187 -0
  222. package/dist/studio/samples/restaurant.d.ts +2 -0
  223. package/dist/studio/samples/restaurant.js +180 -0
  224. package/dist/studio/samples/school.d.ts +2 -0
  225. package/dist/studio/samples/school.js +188 -0
  226. package/dist/studio/samples/shared.d.ts +142 -0
  227. package/dist/studio/samples/shared.js +164 -0
  228. package/dist/studio/samples/starter.d.ts +4 -0
  229. package/dist/studio/samples/starter.js +237 -0
  230. package/dist/studio/samples/subscriptions.d.ts +2 -0
  231. package/dist/studio/samples/subscriptions.js +175 -0
  232. package/dist/studio/samples/support.d.ts +2 -0
  233. package/dist/studio/samples/support.js +209 -0
  234. package/dist/studio/scaffold-app.d.ts +22 -0
  235. package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
  236. package/dist/studio/scaffold.d.ts +63 -0
  237. package/dist/studio/scaffold.js +346 -0
  238. package/dist/studio/screen-suites.d.ts +193 -0
  239. package/dist/studio/screen-suites.js +297 -0
  240. package/dist/studio/themes.d.ts +34 -0
  241. package/dist/studio/themes.js +41 -0
  242. package/dist/studio/ui-components.d.ts +89 -0
  243. package/dist/studio/ui-components.generated.d.ts +29 -0
  244. package/dist/studio/ui-components.generated.js +7139 -0
  245. package/dist/studio/ui-components.js +673 -0
  246. package/dist/studio/user-error.d.ts +23 -0
  247. package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
  248. package/dist/studio/verify.d.ts +34 -0
  249. package/dist/studio/verify.js +47 -0
  250. package/dist/sveltekit/in-memory.d.ts +14 -0
  251. package/dist/sveltekit/in-memory.js +113 -0
  252. package/dist/sveltekit/index.d.ts +6 -0
  253. package/dist/sveltekit/index.js +5 -0
  254. package/dist/sveltekit/query-plan.d.ts +44 -0
  255. package/dist/sveltekit/query-plan.js +76 -0
  256. package/dist/sveltekit/sql-source.d.ts +47 -0
  257. package/dist/sveltekit/sql-source.js +106 -0
  258. package/dist/sveltekit/sql.d.ts +48 -0
  259. package/dist/sveltekit/sql.js +73 -0
  260. package/dist/sveltekit/transport.d.ts +209 -0
  261. package/dist/sveltekit/transport.js +219 -0
  262. package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
  263. package/dist/sveltekit/types.js +1 -0
  264. package/dist/upgrade-prompt.d.ts +16 -0
  265. package/dist/upgrade-prompt.js +141 -0
  266. package/dist/version.d.ts +13 -0
  267. package/{src/version.ts → dist/version.js} +1 -1
  268. package/dist/watermark.d.ts +2 -0
  269. package/dist/watermark.js +146 -0
  270. package/package.json +26 -24
  271. package/src/SvBoard.dom.test.ts +0 -67
  272. package/src/SvGridAlerts.dom.test.ts +0 -113
  273. package/src/SvGridEditPanel.dom.test.ts +0 -320
  274. package/src/SvRecordDetail.dom.test.ts +0 -137
  275. package/src/SvSchedule.dom.test.ts +0 -57
  276. package/src/ai-export-pdf.dom.test.ts +0 -77
  277. package/src/ai-export-xlsx.dom.test.ts +0 -90
  278. package/src/ai-export.dom.test.ts +0 -114
  279. package/src/alerts/alert-engine-attach.ts +0 -165
  280. package/src/alerts/alert-engine.test.ts +0 -135
  281. package/src/alerts/alert-engine.ts +0 -260
  282. package/src/alerts/alert-formats.test.ts +0 -87
  283. package/src/alerts/alert-formats.ts +0 -77
  284. package/src/alerts/alert-observer.test.ts +0 -189
  285. package/src/alerts/alert-observer.ts +0 -208
  286. package/src/alerts/alert-scheduler.ts +0 -96
  287. package/src/alerts/alert-storage.test.ts +0 -54
  288. package/src/alerts/alert-storage.ts +0 -116
  289. package/src/alerts/alert-store.svelte.ts +0 -80
  290. package/src/alerts/alert-types.ts +0 -94
  291. package/src/board.dom.test.ts +0 -941
  292. package/src/edit-panel.test.ts +0 -322
  293. package/src/edit-panel.ts +0 -379
  294. package/src/export-conditional.test.ts +0 -60
  295. package/src/export-conditional.ts +0 -94
  296. package/src/export-ooxml.test.ts +0 -152
  297. package/src/export-ooxml.ts +0 -489
  298. package/src/export-pdf.test.ts +0 -138
  299. package/src/export-pdf.ts +0 -245
  300. package/src/export-print.test.ts +0 -66
  301. package/src/export-print.ts +0 -132
  302. package/src/export-serialize.test.ts +0 -56
  303. package/src/export-xls.ts +0 -199
  304. package/src/export-xlsx-roundtrip.test.ts +0 -120
  305. package/src/export-xlsx.test.ts +0 -150
  306. package/src/export.test.ts +0 -349
  307. package/src/export.ts +0 -1464
  308. package/src/expressions/evaluate.test.ts +0 -111
  309. package/src/expressions/evaluate.ts +0 -237
  310. package/src/expressions/expression-columns.ts +0 -133
  311. package/src/expressions/expression-types.ts +0 -84
  312. package/src/expressions/parse.test.ts +0 -106
  313. package/src/expressions/parse.ts +0 -610
  314. package/src/import-automap.test.ts +0 -131
  315. package/src/import-hardening.test.ts +0 -158
  316. package/src/import.test.ts +0 -415
  317. package/src/import.ts +0 -1044
  318. package/src/index.ts +0 -569
  319. package/src/install.ts +0 -154
  320. package/src/license-core.test.ts +0 -23
  321. package/src/license-core.ts +0 -107
  322. package/src/license-expiry.test.ts +0 -144
  323. package/src/license.ts +0 -157
  324. package/src/master-detail.test.ts +0 -61
  325. package/src/master-detail.ts +0 -42
  326. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  327. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
  328. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
  329. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
  330. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
  331. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
  332. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
  333. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
  334. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
  335. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
  336. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
  337. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
  338. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
  339. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
  340. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
  341. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  342. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  343. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  344. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  345. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  346. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  347. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  348. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  349. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  350. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  351. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  352. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  353. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  354. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  355. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  356. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  357. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  358. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  359. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  360. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  361. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  362. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  363. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  364. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  365. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  366. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  367. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  368. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  369. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  370. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  371. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  372. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  373. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  374. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  375. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  376. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
  377. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
  378. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
  379. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
  380. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
  381. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
  382. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
  383. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
  384. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
  385. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
  386. package/src/pivot-chart.test.ts +0 -86
  387. package/src/pivot-chart.ts +0 -112
  388. package/src/pivot-designer.ts +0 -101
  389. package/src/pivot.test.ts +0 -335
  390. package/src/pivot.ts +0 -578
  391. package/src/print.ts +0 -107
  392. package/src/scheduler-assignments.test.ts +0 -97
  393. package/src/scheduler-assignments.ts +0 -134
  394. package/src/scheduler-axis.test.ts +0 -108
  395. package/src/scheduler-axis.ts +0 -238
  396. package/src/scheduler-booking.test.ts +0 -57
  397. package/src/scheduler-config.ts +0 -179
  398. package/src/scheduler-dependencies.test.ts +0 -155
  399. package/src/scheduler-dependencies.ts +0 -223
  400. package/src/scheduler-freebusy.test.ts +0 -41
  401. package/src/scheduler-heatmap.test.ts +0 -39
  402. package/src/scheduler-resource-tree.test.ts +0 -84
  403. package/src/scheduler-resource-tree.ts +0 -107
  404. package/src/scheduler-slots.test.ts +0 -53
  405. package/src/scheduler-slots.ts +0 -94
  406. package/src/scheduler-summary.test.ts +0 -47
  407. package/src/scheduler-summary.ts +0 -81
  408. package/src/scheduling.test.ts +0 -194
  409. package/src/scheduling.ts +0 -293
  410. package/src/schema-designer.test.ts +0 -121
  411. package/src/schema-designer.ts +0 -142
  412. package/src/schema.test.ts +0 -268
  413. package/src/schema.ts +0 -562
  414. package/src/smart-shim.ts +0 -107
  415. package/src/sources/aggregate.test.ts +0 -79
  416. package/src/sources/aggregate.ts +0 -102
  417. package/src/sources/auth-supabase.test.ts +0 -80
  418. package/src/sources/auth-supabase.ts +0 -87
  419. package/src/sources/dashboard.kpi.test.ts +0 -50
  420. package/src/sources/dashboard.test.ts +0 -61
  421. package/src/sources/dashboard.ts +0 -136
  422. package/src/sources/field-inference.test.ts +0 -60
  423. package/src/sources/field-inference.ts +0 -63
  424. package/src/sources/filters.test.ts +0 -58
  425. package/src/sources/filters.ts +0 -70
  426. package/src/sources/index.ts +0 -67
  427. package/src/sources/introspect-supabase.test.ts +0 -112
  428. package/src/sources/introspect-supabase.ts +0 -139
  429. package/src/sources/realtime-supabase.test.ts +0 -93
  430. package/src/sources/realtime-supabase.ts +0 -99
  431. package/src/sources/relation-lookup.test.ts +0 -99
  432. package/src/sources/relation-lookup.ts +0 -128
  433. package/src/sources/rest-adapters.test.ts +0 -95
  434. package/src/sources/rest-adapters.ts +0 -120
  435. package/src/sources/rest.test.ts +0 -104
  436. package/src/sources/rest.ts +0 -129
  437. package/src/sources/schema-from-columns.test.ts +0 -106
  438. package/src/sources/schema-from-columns.ts +0 -88
  439. package/src/sources/supabase.test.ts +0 -110
  440. package/src/sources/supabase.ts +0 -99
  441. package/src/sources/with-entity-rules.test.ts +0 -104
  442. package/src/sources/with-entity-rules.ts +0 -78
  443. package/src/sources/with-relation-labels.test.ts +0 -75
  444. package/src/sources/with-relation-labels.ts +0 -73
  445. package/src/staged-editing.ts +0 -0
  446. package/src/studio/bug-report.test.ts +0 -101
  447. package/src/studio/bug-report.ts +0 -165
  448. package/src/studio/cli.test.ts +0 -187
  449. package/src/studio/cli.ts +0 -117
  450. package/src/studio/copilot-core.test.ts +0 -45
  451. package/src/studio/csv.test.ts +0 -90
  452. package/src/studio/csv.ts +0 -165
  453. package/src/studio/db-connect-string.test.ts +0 -94
  454. package/src/studio/db-connect-string.ts +0 -128
  455. package/src/studio/deploy-cli.test.ts +0 -56
  456. package/src/studio/deploy-cli.ts +0 -100
  457. package/src/studio/emit-project.test.ts +0 -3324
  458. package/src/studio/emit-project.ts +0 -5377
  459. package/src/studio/emit-schema.test.ts +0 -111
  460. package/src/studio/emit-schema.ts +0 -1181
  461. package/src/studio/index.ts +0 -380
  462. package/src/studio/init-flow.test.ts +0 -514
  463. package/src/studio/init-flow.ts +0 -556
  464. package/src/studio/introspect-db.test.ts +0 -186
  465. package/src/studio/introspect-db.ts +0 -312
  466. package/src/studio/introspect-openapi.test.ts +0 -84
  467. package/src/studio/introspect-openapi.ts +0 -252
  468. package/src/studio/introspect-prisma.test.ts +0 -99
  469. package/src/studio/introspect-prisma.ts +0 -175
  470. package/src/studio/introspect.test.ts +0 -172
  471. package/src/studio/introspect.ts +0 -310
  472. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  473. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  474. package/src/studio/pipeline.test.ts +0 -42
  475. package/src/studio/project-robust.test.ts +0 -157
  476. package/src/studio/project.test.ts +0 -929
  477. package/src/studio/project.ts +0 -2394
  478. package/src/studio/sample-data.test.ts +0 -58
  479. package/src/studio/sample-data.ts +0 -203
  480. package/src/studio/samples/ats.ts +0 -202
  481. package/src/studio/samples/clinic.ts +0 -179
  482. package/src/studio/samples/crm.ts +0 -291
  483. package/src/studio/samples/datasets.test.ts +0 -84
  484. package/src/studio/samples/datasets.ts +0 -340
  485. package/src/studio/samples/ecommerce.ts +0 -187
  486. package/src/studio/samples/events.ts +0 -201
  487. package/src/studio/samples/fleet.ts +0 -213
  488. package/src/studio/samples/gym.ts +0 -215
  489. package/src/studio/samples/hr.ts +0 -195
  490. package/src/studio/samples/index.ts +0 -55
  491. package/src/studio/samples/insurance.ts +0 -229
  492. package/src/studio/samples/inventory.ts +0 -213
  493. package/src/studio/samples/invoicing.ts +0 -162
  494. package/src/studio/samples/library.ts +0 -180
  495. package/src/studio/samples/live-data.test.ts +0 -99
  496. package/src/studio/samples/live-data.ts +0 -306
  497. package/src/studio/samples/projects.ts +0 -212
  498. package/src/studio/samples/realestate.ts +0 -196
  499. package/src/studio/samples/restaurant.ts +0 -189
  500. package/src/studio/samples/samples.test.ts +0 -304
  501. package/src/studio/samples/school.ts +0 -197
  502. package/src/studio/samples/seed-floor.test.ts +0 -25
  503. package/src/studio/samples/shared.ts +0 -237
  504. package/src/studio/samples/starter.ts +0 -251
  505. package/src/studio/samples/subscriptions.ts +0 -183
  506. package/src/studio/samples/support.ts +0 -216
  507. package/src/studio/scaffold-app.test.ts +0 -91
  508. package/src/studio/scaffold.test.ts +0 -192
  509. package/src/studio/scaffold.ts +0 -390
  510. package/src/studio/screen-suites.test.ts +0 -269
  511. package/src/studio/screen-suites.ts +0 -448
  512. package/src/studio/themes.ts +0 -62
  513. package/src/studio/ui-components-surface.test.ts +0 -185
  514. package/src/studio/ui-components.generated.ts +0 -7154
  515. package/src/studio/ui-components.ts +0 -742
  516. package/src/studio/verify.test.ts +0 -47
  517. package/src/studio/verify.ts +0 -79
  518. package/src/sveltekit/in-memory.test.ts +0 -104
  519. package/src/sveltekit/in-memory.ts +0 -129
  520. package/src/sveltekit/index.ts +0 -24
  521. package/src/sveltekit/query-plan.test.ts +0 -109
  522. package/src/sveltekit/query-plan.ts +0 -125
  523. package/src/sveltekit/sql-source.test.ts +0 -198
  524. package/src/sveltekit/sql-source.ts +0 -171
  525. package/src/sveltekit/sql.test.ts +0 -80
  526. package/src/sveltekit/sql.ts +0 -131
  527. package/src/sveltekit/transport-scope.test.ts +0 -125
  528. package/src/sveltekit/transport.test.ts +0 -201
  529. package/src/sveltekit/transport.ts +0 -373
  530. package/src/upgrade-prompt.test.ts +0 -71
  531. package/src/upgrade-prompt.ts +0 -162
  532. package/src/version.test.ts +0 -17
  533. package/src/watermark.test.ts +0 -97
  534. package/src/watermark.ts +0 -156
  535. /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
  536. /package/{src → dist}/SvAlertsManager.svelte +0 -0
  537. /package/{src → dist}/SvAlertsPanel.svelte +0 -0
  538. /package/{src → dist}/SvAuthGate.svelte +0 -0
  539. /package/{src → dist}/SvBoard.svelte +0 -0
  540. /package/{src → dist}/SvExportMenu.svelte +0 -0
  541. /package/{src → dist}/SvExpressionEditor.svelte +0 -0
  542. /package/{src → dist}/SvFileInput.svelte +0 -0
  543. /package/{src → dist}/SvGridAlerts.svelte +0 -0
  544. /package/{src → dist}/SvGridBoard.svelte +0 -0
  545. /package/{src → dist}/SvGridEditPanel.svelte +0 -0
  546. /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
  547. /package/{src → dist}/SvGridScheduler.svelte +0 -0
  548. /package/{src → dist}/SvImportDialog.svelte +0 -0
  549. /package/{src → dist}/SvLookupInput.svelte +0 -0
  550. /package/{src → dist}/SvPivotDesigner.svelte +0 -0
  551. /package/{src → dist}/SvRecordDetail.svelte +0 -0
  552. /package/{src → dist}/SvSchedule.svelte +0 -0
  553. /package/{src → dist}/SvSchemaChart.svelte +0 -0
  554. /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
  555. /package/{src → dist}/pdfmake-shims.d.ts +0 -0
  556. /package/{src → dist}/smart.export.d.ts +0 -0
  557. /package/{src → dist}/smart.export.js +0 -0
  558. /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
  559. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
  560. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
  561. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
  562. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
  563. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
  564. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
  565. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
  566. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
  567. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
  568. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
  569. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
  570. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
  571. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
  572. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
  573. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
  574. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
  575. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
  576. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
  577. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
  578. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
  579. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
  580. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
  581. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
  582. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
  583. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
  584. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
  585. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
  586. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
  587. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
  588. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
  589. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
  590. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
  591. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
  592. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
  593. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
  594. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
  595. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
  596. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
  597. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
  598. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
  599. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
  600. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
  601. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
  602. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
  603. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
  604. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
  605. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
  606. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
  607. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
  608. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
  609. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
  610. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
  611. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
  612. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
  613. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
  614. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
  615. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
  616. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
  617. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
  618. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
  619. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
  620. /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
- }