@svgrid/enterprise 2.5.2 → 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.
- package/dist/SvAlertRuleEditor.svelte.d.ts +13 -0
- package/dist/SvAlertsManager.svelte.d.ts +14 -0
- package/dist/SvAlertsPanel.svelte.d.ts +9 -0
- package/dist/SvAuthGate.svelte.d.ts +22 -0
- package/dist/SvBoard.svelte.d.ts +35 -0
- package/dist/SvExportMenu.svelte.d.ts +61 -0
- package/dist/SvExpressionEditor.svelte.d.ts +12 -0
- package/dist/SvFileInput.svelte.d.ts +20 -0
- package/dist/SvGridAlerts.svelte.d.ts +77 -0
- package/dist/SvGridBoard.svelte.d.ts +30 -0
- package/dist/SvGridEditPanel.svelte.d.ts +73 -0
- package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
- package/dist/SvGridScheduler.svelte.d.ts +30 -0
- package/dist/SvImportDialog.svelte.d.ts +88 -0
- package/dist/SvLookupInput.svelte.d.ts +21 -0
- package/dist/SvPivotDesigner.svelte.d.ts +176 -0
- package/dist/SvRecordDetail.svelte.d.ts +58 -0
- package/dist/SvSchedule.svelte.d.ts +29 -0
- package/dist/SvSchemaChart.svelte.d.ts +61 -0
- package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
- package/dist/alerts/alert-engine-attach.d.ts +79 -0
- package/dist/alerts/alert-engine-attach.js +106 -0
- package/dist/alerts/alert-engine.d.ts +42 -0
- package/dist/alerts/alert-engine.js +196 -0
- package/dist/alerts/alert-formats.d.ts +26 -0
- package/dist/alerts/alert-formats.js +58 -0
- package/dist/alerts/alert-observer.d.ts +54 -0
- package/dist/alerts/alert-observer.js +156 -0
- package/dist/alerts/alert-scheduler.d.ts +30 -0
- package/dist/alerts/alert-scheduler.js +54 -0
- package/dist/alerts/alert-storage.d.ts +31 -0
- package/dist/alerts/alert-storage.js +92 -0
- package/dist/alerts/alert-store.svelte.d.ts +24 -0
- package/dist/alerts/alert-store.svelte.js +69 -0
- package/dist/alerts/alert-types.d.ts +86 -0
- package/dist/alerts/alert-types.js +1 -0
- package/dist/alerts.d.ts +2 -0
- package/{src/alerts.ts → dist/alerts.js} +9 -9
- package/dist/board.d.ts +7 -0
- package/{src/board.ts → dist/board.js} +13 -14
- package/dist/cdn/svgrid-enterprise.svelte-external.js +2987 -2981
- package/dist/designer/assets/{index-CM5xvaOy.js → index-BF0UH638.js} +3 -3
- package/dist/designer/assets/{src-D-ET9Mmo.js → src-BPJruwB9.js} +184 -184
- package/dist/designer/index.html +2 -2
- package/dist/edit-panel.d.ts +105 -0
- package/dist/edit-panel.js +350 -0
- package/dist/export-conditional.d.ts +31 -0
- package/dist/export-conditional.js +65 -0
- package/dist/export-ooxml.d.ts +93 -0
- package/dist/export-ooxml.js +385 -0
- package/dist/export-pdf.d.ts +107 -0
- package/dist/export-pdf.js +144 -0
- package/dist/export-print.d.ts +55 -0
- package/dist/export-print.js +91 -0
- package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
- package/dist/export-serialize.js +11 -0
- package/dist/export-xls.d.ts +26 -0
- package/dist/export-xls.js +157 -0
- package/dist/export.d.ts +323 -0
- package/dist/export.js +1021 -0
- package/dist/expressions/evaluate.d.ts +17 -0
- package/dist/expressions/evaluate.js +214 -0
- package/dist/expressions/expression-columns.d.ts +61 -0
- package/dist/expressions/expression-columns.js +72 -0
- package/dist/expressions/expression-types.d.ts +125 -0
- package/dist/expressions/expression-types.js +1 -0
- package/dist/expressions/parse.d.ts +25 -0
- package/dist/expressions/parse.js +537 -0
- package/dist/import.d.ts +232 -0
- package/dist/import.js +846 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +91 -0
- package/dist/install.d.ts +70 -0
- package/dist/install.js +61 -0
- package/dist/license-core.d.ts +37 -0
- package/dist/license-core.js +81 -0
- package/dist/license.d.ts +30 -0
- package/dist/license.js +139 -0
- package/dist/master-detail.d.ts +23 -0
- package/dist/master-detail.js +35 -0
- package/dist/node/studio.js +1 -1
- package/dist/pivot-chart.d.ts +28 -0
- package/dist/pivot-chart.js +71 -0
- package/dist/pivot-designer.d.ts +69 -0
- package/dist/pivot-designer.js +38 -0
- package/dist/pivot-enable.d.ts +6 -0
- package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
- package/dist/pivot.d.ts +111 -0
- package/dist/pivot.js +353 -0
- package/dist/print.d.ts +33 -0
- package/dist/print.js +61 -0
- package/dist/revoked.d.ts +1 -0
- package/{src/revoked.ts → dist/revoked.js} +5 -6
- package/dist/scheduler-assignments.d.ts +64 -0
- package/dist/scheduler-assignments.js +92 -0
- package/dist/scheduler-axis.d.ts +81 -0
- package/dist/scheduler-axis.js +180 -0
- package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
- package/dist/scheduler-booking.js +50 -0
- package/dist/scheduler-config.d.ts +177 -0
- package/dist/scheduler-config.js +1 -0
- package/dist/scheduler-dependencies.d.ts +89 -0
- package/dist/scheduler-dependencies.js +179 -0
- package/dist/scheduler-freebusy.d.ts +19 -0
- package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
- package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
- package/dist/scheduler-heatmap.js +41 -0
- package/dist/scheduler-resource-tree.d.ts +48 -0
- package/dist/scheduler-resource-tree.js +78 -0
- package/dist/scheduler-slots.d.ts +37 -0
- package/dist/scheduler-slots.js +80 -0
- package/dist/scheduler-summary.d.ts +41 -0
- package/dist/scheduler-summary.js +54 -0
- package/dist/scheduler.d.ts +7 -0
- package/{src/scheduler.ts → dist/scheduler.js} +13 -14
- package/dist/scheduling.d.ts +132 -0
- package/dist/scheduling.js +228 -0
- package/dist/schema-designer.d.ts +42 -0
- package/dist/schema-designer.js +117 -0
- package/dist/schema.d.ts +369 -0
- package/dist/schema.js +216 -0
- package/dist/smart-shim.d.ts +62 -0
- package/dist/smart-shim.js +34 -0
- package/dist/sources/aggregate.d.ts +43 -0
- package/dist/sources/aggregate.js +60 -0
- package/dist/sources/auth-supabase.d.ts +69 -0
- package/dist/sources/auth-supabase.js +39 -0
- package/dist/sources/dashboard.d.ts +65 -0
- package/dist/sources/dashboard.js +95 -0
- package/dist/sources/field-inference.d.ts +23 -0
- package/dist/sources/field-inference.js +52 -0
- package/dist/sources/filters.d.ts +35 -0
- package/dist/sources/filters.js +52 -0
- package/dist/sources/index.d.ts +18 -0
- package/dist/sources/index.js +18 -0
- package/dist/sources/introspect-supabase.d.ts +30 -0
- package/dist/sources/introspect-supabase.js +134 -0
- package/dist/sources/realtime-supabase.d.ts +37 -0
- package/dist/sources/realtime-supabase.js +52 -0
- package/dist/sources/relation-lookup.d.ts +50 -0
- package/dist/sources/relation-lookup.js +77 -0
- package/dist/sources/rest-adapters.d.ts +48 -0
- package/dist/sources/rest-adapters.js +85 -0
- package/dist/sources/rest.d.ts +38 -0
- package/dist/sources/rest.js +86 -0
- package/dist/sources/schema-from-columns.d.ts +37 -0
- package/dist/sources/schema-from-columns.js +48 -0
- package/dist/sources/supabase.d.ts +33 -0
- package/dist/sources/supabase.js +74 -0
- package/dist/sources/with-entity-rules.d.ts +25 -0
- package/dist/sources/with-entity-rules.js +47 -0
- package/dist/sources/with-relation-labels.d.ts +26 -0
- package/dist/sources/with-relation-labels.js +38 -0
- package/dist/staged-editing.d.ts +85 -0
- package/dist/staged-editing.js +0 -0
- package/dist/studio/bug-report.d.ts +61 -0
- package/dist/studio/bug-report.js +126 -0
- package/dist/studio/cli.d.ts +56 -0
- package/dist/studio/cli.js +70 -0
- package/dist/studio/copilot-core.d.ts +22 -0
- package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
- package/dist/studio/csv.d.ts +36 -0
- package/dist/studio/csv.js +173 -0
- package/dist/studio/db-connect-string.d.ts +45 -0
- package/dist/studio/db-connect-string.js +113 -0
- package/dist/studio/deploy-cli.d.ts +35 -0
- package/dist/studio/deploy-cli.js +81 -0
- package/dist/studio/emit-project.d.ts +77 -0
- package/dist/studio/emit-project.js +5389 -0
- package/dist/studio/emit-schema.d.ts +110 -0
- package/dist/studio/emit-schema.js +1128 -0
- package/dist/studio/index.d.ts +35 -0
- package/dist/studio/index.js +38 -0
- package/dist/studio/init-flow.d.ts +58 -0
- package/dist/studio/init-flow.js +451 -0
- package/dist/studio/introspect-db.d.ts +47 -0
- package/dist/studio/introspect-db.js +255 -0
- package/dist/studio/introspect-openapi.d.ts +19 -0
- package/dist/studio/introspect-openapi.js +244 -0
- package/dist/studio/introspect-prisma.d.ts +25 -0
- package/dist/studio/introspect-prisma.js +164 -0
- package/dist/studio/introspect.d.ts +35 -0
- package/dist/studio/introspect.js +306 -0
- package/dist/studio/project.d.ts +1327 -0
- package/dist/studio/project.js +1798 -0
- package/dist/studio/sample-data.d.ts +19 -0
- package/dist/studio/sample-data.js +207 -0
- package/dist/studio/samples/ats.d.ts +2 -0
- package/dist/studio/samples/ats.js +194 -0
- package/dist/studio/samples/clinic.d.ts +2 -0
- package/dist/studio/samples/clinic.js +171 -0
- package/dist/studio/samples/crm.d.ts +2 -0
- package/dist/studio/samples/crm.js +280 -0
- package/dist/studio/samples/datasets.d.ts +38 -0
- package/dist/studio/samples/datasets.js +296 -0
- package/dist/studio/samples/ecommerce.d.ts +2 -0
- package/dist/studio/samples/ecommerce.js +178 -0
- package/dist/studio/samples/events.d.ts +2 -0
- package/dist/studio/samples/events.js +192 -0
- package/dist/studio/samples/fleet.d.ts +2 -0
- package/dist/studio/samples/fleet.js +203 -0
- package/dist/studio/samples/gym.d.ts +2 -0
- package/dist/studio/samples/gym.js +205 -0
- package/dist/studio/samples/hr.d.ts +2 -0
- package/dist/studio/samples/hr.js +186 -0
- package/dist/studio/samples/index.d.ts +13 -0
- package/dist/studio/samples/index.js +44 -0
- package/dist/studio/samples/insurance.d.ts +2 -0
- package/dist/studio/samples/insurance.js +220 -0
- package/dist/studio/samples/inventory.d.ts +2 -0
- package/dist/studio/samples/inventory.js +204 -0
- package/dist/studio/samples/invoicing.d.ts +2 -0
- package/dist/studio/samples/invoicing.js +154 -0
- package/dist/studio/samples/library.d.ts +2 -0
- package/dist/studio/samples/library.js +171 -0
- package/dist/studio/samples/live-data.d.ts +5 -0
- package/dist/studio/samples/live-data.js +261 -0
- package/dist/studio/samples/projects.d.ts +2 -0
- package/dist/studio/samples/projects.js +203 -0
- package/dist/studio/samples/realestate.d.ts +2 -0
- package/dist/studio/samples/realestate.js +187 -0
- package/dist/studio/samples/restaurant.d.ts +2 -0
- package/dist/studio/samples/restaurant.js +180 -0
- package/dist/studio/samples/school.d.ts +2 -0
- package/dist/studio/samples/school.js +188 -0
- package/dist/studio/samples/shared.d.ts +142 -0
- package/dist/studio/samples/shared.js +164 -0
- package/dist/studio/samples/starter.d.ts +4 -0
- package/dist/studio/samples/starter.js +237 -0
- package/dist/studio/samples/subscriptions.d.ts +2 -0
- package/dist/studio/samples/subscriptions.js +175 -0
- package/dist/studio/samples/support.d.ts +2 -0
- package/dist/studio/samples/support.js +209 -0
- package/dist/studio/scaffold-app.d.ts +22 -0
- package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
- package/dist/studio/scaffold.d.ts +63 -0
- package/dist/studio/scaffold.js +346 -0
- package/dist/studio/screen-suites.d.ts +193 -0
- package/dist/studio/screen-suites.js +297 -0
- package/dist/studio/themes.d.ts +34 -0
- package/dist/studio/themes.js +41 -0
- package/dist/studio/ui-components.d.ts +89 -0
- package/dist/studio/ui-components.generated.d.ts +29 -0
- package/dist/studio/ui-components.generated.js +7139 -0
- package/dist/studio/ui-components.js +673 -0
- package/dist/studio/user-error.d.ts +23 -0
- package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
- package/dist/studio/verify.d.ts +34 -0
- package/dist/studio/verify.js +47 -0
- package/dist/sveltekit/in-memory.d.ts +14 -0
- package/dist/sveltekit/in-memory.js +113 -0
- package/dist/sveltekit/index.d.ts +6 -0
- package/dist/sveltekit/index.js +5 -0
- package/dist/sveltekit/query-plan.d.ts +44 -0
- package/dist/sveltekit/query-plan.js +76 -0
- package/dist/sveltekit/sql-source.d.ts +47 -0
- package/dist/sveltekit/sql-source.js +106 -0
- package/dist/sveltekit/sql.d.ts +48 -0
- package/dist/sveltekit/sql.js +73 -0
- package/dist/sveltekit/transport.d.ts +209 -0
- package/dist/sveltekit/transport.js +219 -0
- package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
- package/dist/sveltekit/types.js +1 -0
- package/dist/upgrade-prompt.d.ts +16 -0
- package/dist/upgrade-prompt.js +141 -0
- package/dist/version.d.ts +13 -0
- package/{src/version.ts → dist/version.js} +1 -1
- package/dist/watermark.d.ts +2 -0
- package/dist/watermark.js +146 -0
- package/package.json +26 -24
- package/src/SvBoard.dom.test.ts +0 -67
- package/src/SvGridAlerts.dom.test.ts +0 -113
- package/src/SvGridEditPanel.dom.test.ts +0 -320
- package/src/SvRecordDetail.dom.test.ts +0 -137
- package/src/SvSchedule.dom.test.ts +0 -57
- package/src/ai-export-pdf.dom.test.ts +0 -77
- package/src/ai-export-xlsx.dom.test.ts +0 -90
- package/src/ai-export.dom.test.ts +0 -114
- package/src/alerts/alert-engine-attach.ts +0 -165
- package/src/alerts/alert-engine.test.ts +0 -135
- package/src/alerts/alert-engine.ts +0 -260
- package/src/alerts/alert-formats.test.ts +0 -87
- package/src/alerts/alert-formats.ts +0 -77
- package/src/alerts/alert-observer.test.ts +0 -189
- package/src/alerts/alert-observer.ts +0 -208
- package/src/alerts/alert-scheduler.ts +0 -96
- package/src/alerts/alert-storage.test.ts +0 -54
- package/src/alerts/alert-storage.ts +0 -116
- package/src/alerts/alert-store.svelte.ts +0 -80
- package/src/alerts/alert-types.ts +0 -94
- package/src/board.dom.test.ts +0 -941
- package/src/edit-panel.test.ts +0 -322
- package/src/edit-panel.ts +0 -379
- package/src/export-conditional.test.ts +0 -60
- package/src/export-conditional.ts +0 -94
- package/src/export-ooxml.test.ts +0 -152
- package/src/export-ooxml.ts +0 -489
- package/src/export-pdf.test.ts +0 -138
- package/src/export-pdf.ts +0 -245
- package/src/export-print.test.ts +0 -66
- package/src/export-print.ts +0 -132
- package/src/export-serialize.test.ts +0 -56
- package/src/export-xls.ts +0 -199
- package/src/export-xlsx-roundtrip.test.ts +0 -120
- package/src/export-xlsx.test.ts +0 -150
- package/src/export.test.ts +0 -349
- package/src/export.ts +0 -1464
- package/src/expressions/evaluate.test.ts +0 -111
- package/src/expressions/evaluate.ts +0 -237
- package/src/expressions/expression-columns.ts +0 -133
- package/src/expressions/expression-types.ts +0 -84
- package/src/expressions/parse.test.ts +0 -106
- package/src/expressions/parse.ts +0 -610
- package/src/import-automap.test.ts +0 -131
- package/src/import-hardening.test.ts +0 -158
- package/src/import.test.ts +0 -415
- package/src/import.ts +0 -1044
- package/src/index.ts +0 -569
- package/src/install.ts +0 -154
- package/src/license-core.test.ts +0 -23
- package/src/license-core.ts +0 -107
- package/src/license-expiry.test.ts +0 -127
- package/src/license.ts +0 -137
- package/src/master-detail.test.ts +0 -61
- package/src/master-detail.ts +0 -42
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
- package/src/pivot-chart.test.ts +0 -86
- package/src/pivot-chart.ts +0 -112
- package/src/pivot-designer.ts +0 -101
- package/src/pivot.test.ts +0 -335
- package/src/pivot.ts +0 -578
- package/src/print.ts +0 -107
- package/src/scheduler-assignments.test.ts +0 -97
- package/src/scheduler-assignments.ts +0 -134
- package/src/scheduler-axis.test.ts +0 -108
- package/src/scheduler-axis.ts +0 -238
- package/src/scheduler-booking.test.ts +0 -57
- package/src/scheduler-config.ts +0 -179
- package/src/scheduler-dependencies.test.ts +0 -155
- package/src/scheduler-dependencies.ts +0 -223
- package/src/scheduler-freebusy.test.ts +0 -41
- package/src/scheduler-heatmap.test.ts +0 -39
- package/src/scheduler-resource-tree.test.ts +0 -84
- package/src/scheduler-resource-tree.ts +0 -107
- package/src/scheduler-slots.test.ts +0 -53
- package/src/scheduler-slots.ts +0 -94
- package/src/scheduler-summary.test.ts +0 -47
- package/src/scheduler-summary.ts +0 -81
- package/src/scheduling.test.ts +0 -194
- package/src/scheduling.ts +0 -293
- package/src/schema-designer.test.ts +0 -121
- package/src/schema-designer.ts +0 -142
- package/src/schema.test.ts +0 -268
- package/src/schema.ts +0 -562
- package/src/smart-shim.ts +0 -107
- package/src/sources/aggregate.test.ts +0 -79
- package/src/sources/aggregate.ts +0 -102
- package/src/sources/auth-supabase.test.ts +0 -80
- package/src/sources/auth-supabase.ts +0 -87
- package/src/sources/dashboard.kpi.test.ts +0 -50
- package/src/sources/dashboard.test.ts +0 -61
- package/src/sources/dashboard.ts +0 -136
- package/src/sources/field-inference.test.ts +0 -60
- package/src/sources/field-inference.ts +0 -63
- package/src/sources/filters.test.ts +0 -58
- package/src/sources/filters.ts +0 -70
- package/src/sources/index.ts +0 -67
- package/src/sources/introspect-supabase.test.ts +0 -112
- package/src/sources/introspect-supabase.ts +0 -139
- package/src/sources/realtime-supabase.test.ts +0 -93
- package/src/sources/realtime-supabase.ts +0 -99
- package/src/sources/relation-lookup.test.ts +0 -99
- package/src/sources/relation-lookup.ts +0 -128
- package/src/sources/rest-adapters.test.ts +0 -95
- package/src/sources/rest-adapters.ts +0 -120
- package/src/sources/rest.test.ts +0 -104
- package/src/sources/rest.ts +0 -129
- package/src/sources/schema-from-columns.test.ts +0 -106
- package/src/sources/schema-from-columns.ts +0 -88
- package/src/sources/supabase.test.ts +0 -110
- package/src/sources/supabase.ts +0 -99
- package/src/sources/with-entity-rules.test.ts +0 -104
- package/src/sources/with-entity-rules.ts +0 -78
- package/src/sources/with-relation-labels.test.ts +0 -75
- package/src/sources/with-relation-labels.ts +0 -73
- package/src/staged-editing.ts +0 -0
- package/src/studio/bug-report.test.ts +0 -101
- package/src/studio/bug-report.ts +0 -165
- package/src/studio/cli.test.ts +0 -187
- package/src/studio/cli.ts +0 -117
- package/src/studio/copilot-core.test.ts +0 -45
- package/src/studio/csv.test.ts +0 -90
- package/src/studio/csv.ts +0 -165
- package/src/studio/db-connect-string.test.ts +0 -94
- package/src/studio/db-connect-string.ts +0 -128
- package/src/studio/deploy-cli.test.ts +0 -56
- package/src/studio/deploy-cli.ts +0 -100
- package/src/studio/emit-project.test.ts +0 -3324
- package/src/studio/emit-project.ts +0 -5377
- package/src/studio/emit-schema.test.ts +0 -111
- package/src/studio/emit-schema.ts +0 -1181
- package/src/studio/index.ts +0 -380
- package/src/studio/init-flow.test.ts +0 -514
- package/src/studio/init-flow.ts +0 -556
- package/src/studio/introspect-db.test.ts +0 -186
- package/src/studio/introspect-db.ts +0 -312
- package/src/studio/introspect-openapi.test.ts +0 -84
- package/src/studio/introspect-openapi.ts +0 -252
- package/src/studio/introspect-prisma.test.ts +0 -99
- package/src/studio/introspect-prisma.ts +0 -175
- package/src/studio/introspect.test.ts +0 -172
- package/src/studio/introspect.ts +0 -310
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
- package/src/studio/pipeline.test.ts +0 -42
- package/src/studio/project-robust.test.ts +0 -157
- package/src/studio/project.test.ts +0 -929
- package/src/studio/project.ts +0 -2394
- package/src/studio/sample-data.test.ts +0 -58
- package/src/studio/sample-data.ts +0 -203
- package/src/studio/samples/ats.ts +0 -202
- package/src/studio/samples/clinic.ts +0 -179
- package/src/studio/samples/crm.ts +0 -291
- package/src/studio/samples/datasets.test.ts +0 -84
- package/src/studio/samples/datasets.ts +0 -340
- package/src/studio/samples/ecommerce.ts +0 -187
- package/src/studio/samples/events.ts +0 -201
- package/src/studio/samples/fleet.ts +0 -213
- package/src/studio/samples/gym.ts +0 -215
- package/src/studio/samples/hr.ts +0 -195
- package/src/studio/samples/index.ts +0 -55
- package/src/studio/samples/insurance.ts +0 -229
- package/src/studio/samples/inventory.ts +0 -213
- package/src/studio/samples/invoicing.ts +0 -162
- package/src/studio/samples/library.ts +0 -180
- package/src/studio/samples/live-data.test.ts +0 -99
- package/src/studio/samples/live-data.ts +0 -306
- package/src/studio/samples/projects.ts +0 -212
- package/src/studio/samples/realestate.ts +0 -196
- package/src/studio/samples/restaurant.ts +0 -189
- package/src/studio/samples/samples.test.ts +0 -304
- package/src/studio/samples/school.ts +0 -197
- package/src/studio/samples/seed-floor.test.ts +0 -25
- package/src/studio/samples/shared.ts +0 -237
- package/src/studio/samples/starter.ts +0 -251
- package/src/studio/samples/subscriptions.ts +0 -183
- package/src/studio/samples/support.ts +0 -216
- package/src/studio/scaffold-app.test.ts +0 -91
- package/src/studio/scaffold.test.ts +0 -192
- package/src/studio/scaffold.ts +0 -390
- package/src/studio/screen-suites.test.ts +0 -269
- package/src/studio/screen-suites.ts +0 -448
- package/src/studio/themes.ts +0 -62
- package/src/studio/ui-components-surface.test.ts +0 -185
- package/src/studio/ui-components.generated.ts +0 -7154
- package/src/studio/ui-components.ts +0 -742
- package/src/studio/verify.test.ts +0 -47
- package/src/studio/verify.ts +0 -79
- package/src/sveltekit/in-memory.test.ts +0 -104
- package/src/sveltekit/in-memory.ts +0 -129
- package/src/sveltekit/index.ts +0 -24
- package/src/sveltekit/query-plan.test.ts +0 -109
- package/src/sveltekit/query-plan.ts +0 -125
- package/src/sveltekit/sql-source.test.ts +0 -198
- package/src/sveltekit/sql-source.ts +0 -171
- package/src/sveltekit/sql.test.ts +0 -80
- package/src/sveltekit/sql.ts +0 -131
- package/src/sveltekit/transport-scope.test.ts +0 -125
- package/src/sveltekit/transport.test.ts +0 -201
- package/src/sveltekit/transport.ts +0 -373
- package/src/upgrade-prompt.test.ts +0 -71
- package/src/upgrade-prompt.ts +0 -162
- package/src/version.test.ts +0 -17
- package/src/watermark.test.ts +0 -97
- package/src/watermark.ts +0 -156
- /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
- /package/{src → dist}/SvAlertsManager.svelte +0 -0
- /package/{src → dist}/SvAlertsPanel.svelte +0 -0
- /package/{src → dist}/SvAuthGate.svelte +0 -0
- /package/{src → dist}/SvBoard.svelte +0 -0
- /package/{src → dist}/SvExportMenu.svelte +0 -0
- /package/{src → dist}/SvExpressionEditor.svelte +0 -0
- /package/{src → dist}/SvFileInput.svelte +0 -0
- /package/{src → dist}/SvGridAlerts.svelte +0 -0
- /package/{src → dist}/SvGridBoard.svelte +0 -0
- /package/{src → dist}/SvGridEditPanel.svelte +0 -0
- /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
- /package/{src → dist}/SvGridScheduler.svelte +0 -0
- /package/{src → dist}/SvImportDialog.svelte +0 -0
- /package/{src → dist}/SvLookupInput.svelte +0 -0
- /package/{src → dist}/SvPivotDesigner.svelte +0 -0
- /package/{src → dist}/SvRecordDetail.svelte +0 -0
- /package/{src → dist}/SvSchedule.svelte +0 -0
- /package/{src → dist}/SvSchemaChart.svelte +0 -0
- /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
- /package/{src → dist}/pdfmake-shims.d.ts +0 -0
- /package/{src → dist}/smart.export.d.ts +0 -0
- /package/{src → dist}/smart.export.js +0 -0
- /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
- /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
- /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -0
package/src/sources/rest.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createRestDataSource - a `ServerDataSource` over an HTTP/JSON API. Handles the
|
|
3
|
-
* request lifecycle and the four CRUD calls; you point it at a collection URL.
|
|
4
|
-
* The default request/response shaping suits a conventional REST endpoint, and
|
|
5
|
-
* every part is overridable (`buildQuery`, `parse`, `headers`, `fetch`) for
|
|
6
|
-
* bespoke or legacy APIs.
|
|
7
|
-
*
|
|
8
|
-
* const source = createRestDataSource({ url: '/api/customers', schema })
|
|
9
|
-
*
|
|
10
|
-
* Default wire format:
|
|
11
|
-
* read GET {url}?offset&limit&sort&search&<col>=<op>:<value>
|
|
12
|
-
* create POST {url} body: the new row
|
|
13
|
-
* update PATCH {url}/{id} body: the patch
|
|
14
|
-
* delete DELETE {url}/{id}
|
|
15
|
-
* where `sort` is a comma list with `-` for descending (e.g. `-createdAt,name`).
|
|
16
|
-
*/
|
|
17
|
-
import type { RowData, ServerRequest, ServerResult } from '@svgrid/grid'
|
|
18
|
-
import { resolveIdField, type EntitySchema } from '../schema'
|
|
19
|
-
import { nudgeEnterprise } from '../license'
|
|
20
|
-
import type { WritableDataSource } from '../sveltekit/types'
|
|
21
|
-
import { normalizeFilters, type NormalizedPredicate } from './filters'
|
|
22
|
-
|
|
23
|
-
export type RestDataSourceConfig<TData extends RowData> = {
|
|
24
|
-
/** Collection endpoint, e.g. `/api/customers`. */
|
|
25
|
-
url: string
|
|
26
|
-
/** Used to resolve the id field for update/delete when `idField` is omitted. */
|
|
27
|
-
schema?: EntitySchema<TData>
|
|
28
|
-
/** Primary key property (default: from `schema`, else `'id'`). */
|
|
29
|
-
idField?: string
|
|
30
|
-
/** Custom fetch (SSR, auth). Defaults to the global `fetch`. */
|
|
31
|
-
fetch?: typeof fetch
|
|
32
|
-
/** Extra request headers, static or computed per call. */
|
|
33
|
-
headers?: Record<string, string> | (() => Record<string, string>)
|
|
34
|
-
/** Static query params merged into every read (e.g. an API key or filter). */
|
|
35
|
-
query?: Record<string, string>
|
|
36
|
-
/** Build read query params from the grid request. Override for bespoke APIs. */
|
|
37
|
-
buildQuery?: (request: ServerRequest) => Record<string, string>
|
|
38
|
-
/** Parse a read response body into rows + total. Override for bespoke shapes. */
|
|
39
|
-
parse?: (body: unknown, response: Response) => ServerResult<TData>
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const encodePredicate = (p: NormalizedPredicate): string => {
|
|
43
|
-
if (p.op === 'in') return `in:${p.values.join(',')}`
|
|
44
|
-
if (p.op === 'isNull') return 'isNull'
|
|
45
|
-
if (p.op === 'between') return `between:${p.value},${p.valueTo}`
|
|
46
|
-
return `${p.op}:${p.value}`
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function defaultBuildQuery(request: ServerRequest): Record<string, string> {
|
|
50
|
-
const params: Record<string, string> = {
|
|
51
|
-
offset: String(request.startRow),
|
|
52
|
-
limit: String(request.endRow - request.startRow),
|
|
53
|
-
}
|
|
54
|
-
if (request.sortModel.length) {
|
|
55
|
-
params.sort = request.sortModel.map((s) => (s.desc ? '-' : '') + s.id).join(',')
|
|
56
|
-
}
|
|
57
|
-
const { predicates, search } = normalizeFilters(request.filterModel)
|
|
58
|
-
if (search) params.search = search
|
|
59
|
-
for (const p of predicates) params[p.column] = encodePredicate(p)
|
|
60
|
-
return params
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function defaultParse<TData>(body: unknown, response: Response): ServerResult<TData> {
|
|
64
|
-
if (Array.isArray(body)) {
|
|
65
|
-
// Total from a Content-Range header (`items 0-9/240`) when present.
|
|
66
|
-
const range = response.headers.get('content-range')
|
|
67
|
-
const total = range && /\/(\d+)\s*$/.exec(range)
|
|
68
|
-
return { rows: body as TData[], rowCount: total ? Number(total[1]) : body.length }
|
|
69
|
-
}
|
|
70
|
-
const b = (body ?? {}) as Record<string, unknown>
|
|
71
|
-
const rows = (b.rows ?? b.data ?? b.items ?? []) as TData[]
|
|
72
|
-
const rowCount = Number(b.rowCount ?? b.total ?? b.count ?? rows.length)
|
|
73
|
-
return { rows, rowCount }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function createRestDataSource<TData extends RowData>(
|
|
77
|
-
config: RestDataSourceConfig<TData>,
|
|
78
|
-
): WritableDataSource<TData> {
|
|
79
|
-
nudgeEnterprise('Studio') // soft-gate; never blocks
|
|
80
|
-
const doFetch = config.fetch ?? globalThis.fetch
|
|
81
|
-
const idField = config.idField ?? (config.schema ? resolveIdField(config.schema) : 'id')
|
|
82
|
-
const base = config.url.replace(/\/+$/, '')
|
|
83
|
-
const buildQuery = config.buildQuery ?? defaultBuildQuery
|
|
84
|
-
const parse = config.parse ?? defaultParse
|
|
85
|
-
|
|
86
|
-
const headers = (extra?: Record<string, string>): Record<string, string> => {
|
|
87
|
-
const h = typeof config.headers === 'function' ? config.headers() : (config.headers ?? {})
|
|
88
|
-
return { ...h, ...extra }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const send = async (url: string, init?: RequestInit): Promise<unknown> => {
|
|
92
|
-
const res = await doFetch(url, init)
|
|
93
|
-
if (!res.ok) throw new Error(`REST ${init?.method ?? 'GET'} ${url} -> ${res.status} ${res.statusText}`)
|
|
94
|
-
const parsed = res.status === 204 ? undefined : await res.json().catch(() => undefined)
|
|
95
|
-
return { body: parsed, res }
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
async getRows(request: ServerRequest): Promise<ServerResult<TData>> {
|
|
100
|
-
// Static `query` params first; the built paging/sort/filter params win on conflict.
|
|
101
|
-
const qs = new URLSearchParams({ ...config.query, ...buildQuery(request) }).toString()
|
|
102
|
-
const url = qs ? `${base}?${qs}` : base
|
|
103
|
-
const { body, res } = (await send(url, { headers: headers() })) as { body: unknown; res: Response }
|
|
104
|
-
return parse(body, res)
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
async createRow(input: Partial<TData>): Promise<TData> {
|
|
108
|
-
const { body } = (await send(base, {
|
|
109
|
-
method: 'POST',
|
|
110
|
-
headers: headers({ 'content-type': 'application/json' }),
|
|
111
|
-
body: JSON.stringify(input),
|
|
112
|
-
})) as { body: unknown }
|
|
113
|
-
return (body ?? input) as TData
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
async updateRow(id: string, patch: Partial<TData>): Promise<TData> {
|
|
117
|
-
const { body } = (await send(`${base}/${encodeURIComponent(id)}`, {
|
|
118
|
-
method: 'PATCH',
|
|
119
|
-
headers: headers({ 'content-type': 'application/json' }),
|
|
120
|
-
body: JSON.stringify(patch),
|
|
121
|
-
})) as { body: unknown }
|
|
122
|
-
return (body ?? { ...patch, [idField]: id }) as TData
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
async deleteRow(id: string): Promise<void> {
|
|
126
|
-
await send(`${base}/${encodeURIComponent(id)}`, { method: 'DELETE', headers: headers() })
|
|
127
|
-
},
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import type { EntitySchema } from '../schema'
|
|
3
|
-
import { buildEntitySchema, linkRelationLabels, pickLabelField } from './schema-from-columns'
|
|
4
|
-
|
|
5
|
-
describe('buildEntitySchema', () => {
|
|
6
|
-
it('uses an explicit primary key and marks it readonly', () => {
|
|
7
|
-
const s = buildEntitySchema('t', [
|
|
8
|
-
{ name: 'name', type: 'text' },
|
|
9
|
-
{ name: 'code', type: 'text', primaryKey: true },
|
|
10
|
-
])
|
|
11
|
-
expect(s.idField).toBe('code')
|
|
12
|
-
expect(s.fields.find((f) => f.field === 'code')).toMatchObject({ primaryKey: true, readonly: true })
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('falls back to a column named id, then the first column', () => {
|
|
16
|
-
expect(buildEntitySchema('t', [{ name: 'a' }, { name: 'id' }]).idField).toBe('id')
|
|
17
|
-
expect(buildEntitySchema('t', [{ name: 'first' }, { name: 'second' }]).idField).toBe('first')
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('defaults type to text and carries required + enum options', () => {
|
|
21
|
-
const s = buildEntitySchema('t', [
|
|
22
|
-
{ name: 'id', primaryKey: true },
|
|
23
|
-
{ name: 'name', required: true },
|
|
24
|
-
{ name: 'tier', enumValues: ['free', 'pro'] },
|
|
25
|
-
])
|
|
26
|
-
expect(s.fields.find((f) => f.field === 'name')).toMatchObject({ type: 'text', required: true })
|
|
27
|
-
const tier = s.fields.find((f) => f.field === 'tier')
|
|
28
|
-
expect(tier?.type).toBe('enum')
|
|
29
|
-
expect(tier?.options).toEqual([{ value: 'free', label: 'free' }, { value: 'pro', label: 'pro' }])
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('does not mark the primary key as required', () => {
|
|
33
|
-
const s = buildEntitySchema('t', [{ name: 'id', primaryKey: true, required: true }])
|
|
34
|
-
expect(s.fields[0]!).toMatchObject({ primaryKey: true, readonly: true })
|
|
35
|
-
expect(s.fields[0]!.required).toBeUndefined()
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('throws with no columns', () => {
|
|
39
|
-
expect(() => buildEntitySchema('t', [])).toThrow(/no columns/)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('turns a foreign-key column into a relation field', () => {
|
|
43
|
-
const s = buildEntitySchema('contacts', [
|
|
44
|
-
{ name: 'id', primaryKey: true },
|
|
45
|
-
{ name: 'name', required: true },
|
|
46
|
-
{ name: 'company_id', required: true, references: { table: 'companies', column: 'id' } },
|
|
47
|
-
])
|
|
48
|
-
const rel = s.fields.find((f) => f.field === 'company_id')
|
|
49
|
-
expect(rel).toMatchObject({
|
|
50
|
-
field: 'company_id',
|
|
51
|
-
type: 'relation',
|
|
52
|
-
required: true,
|
|
53
|
-
relation: { entity: 'companies', foreignKey: 'company_id', labelField: 'name' },
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('does not turn the primary key into a relation even if it references', () => {
|
|
58
|
-
const s = buildEntitySchema('t', [{ name: 'id', primaryKey: true, references: { table: 'other' } }])
|
|
59
|
-
expect(s.fields[0]!.type).not.toBe('relation')
|
|
60
|
-
expect(s.fields[0]).toMatchObject({ primaryKey: true })
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('honors an explicit labelField on the reference', () => {
|
|
64
|
-
const s = buildEntitySchema('t', [
|
|
65
|
-
{ name: 'id', primaryKey: true },
|
|
66
|
-
{ name: 'owner', references: { table: 'users', labelField: 'email' } },
|
|
67
|
-
])
|
|
68
|
-
expect(s.fields.find((f) => f.field === 'owner')?.relation?.labelField).toBe('email')
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
describe('pickLabelField', () => {
|
|
73
|
-
const make = (fieldNames: [string, 'text' | 'number'][]): EntitySchema => ({
|
|
74
|
-
name: 't', idField: 'id',
|
|
75
|
-
fields: fieldNames.map(([field, type]) => ({ field, type, ...(field === 'id' ? { primaryKey: true } : {}) })),
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('prefers name / title / label', () => {
|
|
79
|
-
expect(pickLabelField(make([['id', 'number'], ['title', 'text'], ['body', 'text']]))).toBe('title')
|
|
80
|
-
})
|
|
81
|
-
it('falls back to the first non-id text field, then the id', () => {
|
|
82
|
-
expect(pickLabelField(make([['id', 'number'], ['slug', 'text']]))).toBe('slug')
|
|
83
|
-
expect(pickLabelField(make([['id', 'number'], ['count', 'number']]))).toBe('id')
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
describe('linkRelationLabels', () => {
|
|
88
|
-
it('resolves each relation labelField from the related schema', () => {
|
|
89
|
-
const companies: EntitySchema = {
|
|
90
|
-
name: 'companies', idField: 'id',
|
|
91
|
-
fields: [{ field: 'id', type: 'number', primaryKey: true }, { field: 'name', type: 'text' }],
|
|
92
|
-
}
|
|
93
|
-
const contacts: EntitySchema = {
|
|
94
|
-
name: 'contacts', idField: 'id',
|
|
95
|
-
fields: [
|
|
96
|
-
{ field: 'id', type: 'number', primaryKey: true },
|
|
97
|
-
{ field: 'company_id', type: 'relation', relation: { entity: 'companies', foreignKey: 'company_id', labelField: 'name' } },
|
|
98
|
-
{ field: 'buddy_id', type: 'relation', relation: { entity: 'missing', foreignKey: 'buddy_id', labelField: 'name' } },
|
|
99
|
-
],
|
|
100
|
-
}
|
|
101
|
-
const [, linkedContacts] = linkRelationLabels([companies, contacts])
|
|
102
|
-
expect(linkedContacts!.fields.find((f) => f.field === 'company_id')?.relation?.labelField).toBe('name')
|
|
103
|
-
// Unknown related entity is left untouched.
|
|
104
|
-
expect(linkedContacts!.fields.find((f) => f.field === 'buddy_id')?.relation?.labelField).toBe('name')
|
|
105
|
-
})
|
|
106
|
-
})
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The shared "columns -> EntitySchema" core. Every introspection path (SQL
|
|
3
|
-
* catalog, PostgREST/OpenAPI, a sample row, manual entry) discovers columns in
|
|
4
|
-
* its own way, then hands a normalized list here to assemble a consistent
|
|
5
|
-
* `EntitySchema` - primary key resolution, readonly on the key, enum options,
|
|
6
|
-
* and a sane default type. Keeping this in one place means the grid + form come
|
|
7
|
-
* out identical no matter which path found the columns.
|
|
8
|
-
*/
|
|
9
|
-
import type { RowData } from '@svgrid/grid'
|
|
10
|
-
import type { EntityField, EntityFieldType, EntitySchema } from '../schema.js'
|
|
11
|
-
import { refineField } from './field-inference.js'
|
|
12
|
-
|
|
13
|
-
/** A discovered foreign key: this column references `table`.`column`. */
|
|
14
|
-
export type ColumnReference = {
|
|
15
|
-
/** Referenced table (becomes the relation's `entity`). */
|
|
16
|
-
table: string
|
|
17
|
-
/** Referenced column (usually the related PK). */
|
|
18
|
-
column?: string
|
|
19
|
-
/** Field on the related entity to show the user. Defaults to `'name'`. */
|
|
20
|
-
labelField?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** One discovered column, backend-neutral. */
|
|
24
|
-
export type IntrospectedColumn = {
|
|
25
|
-
name: string
|
|
26
|
-
/** Actual DB column, when it differs from `name` (e.g. Drizzle `created_at` vs key `createdAt`). */
|
|
27
|
-
dbColumn?: string
|
|
28
|
-
/** High-level type. Defaults to `'text'` when a path can't determine it. */
|
|
29
|
-
type?: EntityFieldType
|
|
30
|
-
primaryKey?: boolean
|
|
31
|
-
/** NOT NULL (becomes a required, non-key field). */
|
|
32
|
-
required?: boolean
|
|
33
|
-
/** Allowed values, for enum columns. */
|
|
34
|
-
enumValues?: string[]
|
|
35
|
-
/** Foreign key: makes this a `relation` field with a searchable lookup. */
|
|
36
|
-
references?: ColumnReference
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** Assemble an EntitySchema from discovered columns. */
|
|
40
|
-
export function buildEntitySchema<TData extends RowData = RowData>(
|
|
41
|
-
table: string,
|
|
42
|
-
columns: IntrospectedColumn[],
|
|
43
|
-
): EntitySchema<TData> {
|
|
44
|
-
if (!columns.length) throw new Error(`buildEntitySchema: "${table}" has no columns`)
|
|
45
|
-
|
|
46
|
-
// Primary key: first flagged pk, else a column literally named "id", else the
|
|
47
|
-
// first column (so update/delete always have a key to target).
|
|
48
|
-
const explicitPk = columns.find((c) => c.primaryKey)?.name
|
|
49
|
-
const idField = explicitPk ?? columns.find((c) => /^id$/i.test(c.name))?.name ?? columns[0]!.name
|
|
50
|
-
|
|
51
|
-
const fields: EntityField<TData>[] = columns.map((c) => {
|
|
52
|
-
const isPk = c.name === idField
|
|
53
|
-
// A foreign-key column (that isn't the PK) becomes a relation field, so the
|
|
54
|
-
// form renders a lookup and master-detail can be inferred.
|
|
55
|
-
if (c.references && !isPk) {
|
|
56
|
-
const rel = { field: c.name, type: 'relation' as const } as EntityField<TData>
|
|
57
|
-
rel.relation = {
|
|
58
|
-
entity: c.references.table,
|
|
59
|
-
foreignKey: c.name,
|
|
60
|
-
labelField: c.references.labelField ?? 'name',
|
|
61
|
-
}
|
|
62
|
-
if (c.dbColumn) rel.dbColumn = c.dbColumn
|
|
63
|
-
if (c.required) rel.required = true
|
|
64
|
-
return rel
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const type: EntityFieldType = c.enumValues?.length ? 'enum' : (c.type ?? 'text')
|
|
68
|
-
const f = { field: c.name, type } as EntityField<TData>
|
|
69
|
-
if (c.dbColumn) f.dbColumn = c.dbColumn
|
|
70
|
-
if (isPk) {
|
|
71
|
-
f.primaryKey = true
|
|
72
|
-
f.readonly = true
|
|
73
|
-
} else if (c.required) {
|
|
74
|
-
f.required = true
|
|
75
|
-
}
|
|
76
|
-
if (type === 'enum' && c.enumValues?.length) {
|
|
77
|
-
f.options = c.enumValues.map((v) => ({ value: v, label: v }))
|
|
78
|
-
}
|
|
79
|
-
// Infer a rich editor from the column name/type (phone / email / rating / ...).
|
|
80
|
-
return refineField(f)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
return { name: table, label: table, idField, fields }
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Schema-level relation helpers live in ../schema (studio consumes them under
|
|
87
|
-
// node16 resolution); re-exported here so introspection consumers get one entry.
|
|
88
|
-
export { pickLabelField, linkRelationLabels } from '../schema.js'
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import type { ServerRequest } from '@svgrid/grid'
|
|
3
|
-
import type { EntitySchema } from '../schema'
|
|
4
|
-
import { createSupabaseDataSource } from './supabase'
|
|
5
|
-
|
|
6
|
-
type Customer = { id: number; name: string; email: string; tier: string; mrr: number }
|
|
7
|
-
|
|
8
|
-
const schema: EntitySchema<Customer> = {
|
|
9
|
-
name: 'customers',
|
|
10
|
-
idField: 'id',
|
|
11
|
-
fields: [
|
|
12
|
-
{ field: 'id', type: 'number', primaryKey: true },
|
|
13
|
-
{ field: 'name', type: 'text' },
|
|
14
|
-
{ field: 'email', type: 'text' },
|
|
15
|
-
{ field: 'tier', type: 'enum', options: [{ value: 'pro', label: 'Pro' }] },
|
|
16
|
-
{ field: 'mrr', type: 'number' },
|
|
17
|
-
],
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** A supabase-js-like builder: chainable AND awaitable (thenable). */
|
|
21
|
-
function makeClient(result: unknown) {
|
|
22
|
-
const calls: Array<[string, unknown[]]> = []
|
|
23
|
-
const builder: any = new Proxy(
|
|
24
|
-
{},
|
|
25
|
-
{
|
|
26
|
-
get(_t, prop: string) {
|
|
27
|
-
if (prop === 'then') return (res: (v: unknown) => void) => Promise.resolve(result).then(res)
|
|
28
|
-
return (...args: unknown[]) => {
|
|
29
|
-
calls.push([prop, args])
|
|
30
|
-
return builder
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
)
|
|
35
|
-
const client = { from: (table: string) => { calls.push(['from', [table]]); return builder } }
|
|
36
|
-
return { client, calls }
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const req = (p: Partial<ServerRequest>): ServerRequest => ({
|
|
40
|
-
startRow: 0, endRow: 10, pageIndex: 0, pageSize: 10, sortModel: [], filterModel: {}, ...p,
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
const has = (calls: Array<[string, unknown[]]>, name: string) => calls.filter((c) => c[0] === name)
|
|
44
|
-
|
|
45
|
-
describe('createSupabaseDataSource reads', () => {
|
|
46
|
-
it('selects with an exact count and returns rows + rowCount', async () => {
|
|
47
|
-
const { client, calls } = makeClient({ data: [{ id: 1, name: 'Ada' }], count: 42, error: null })
|
|
48
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
49
|
-
const out = await src.getRows(req({}))
|
|
50
|
-
expect(has(calls, 'select')[0]![1]).toEqual(['*', { count: 'exact' }])
|
|
51
|
-
expect(has(calls, 'range')[0]![1]).toEqual([0, 9])
|
|
52
|
-
expect(out).toEqual({ rows: [{ id: 1, name: 'Ada' }], rowCount: 42 })
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('maps filters, sort, and global search onto the query builder', async () => {
|
|
56
|
-
const { client, calls } = makeClient({ data: [], count: 0, error: null })
|
|
57
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
58
|
-
await src.getRows(
|
|
59
|
-
req({
|
|
60
|
-
sortModel: [{ id: 'mrr', desc: true }],
|
|
61
|
-
filterModel: {
|
|
62
|
-
global: 'ada',
|
|
63
|
-
columns: {
|
|
64
|
-
name: { operator: 'contains', value: 'a' },
|
|
65
|
-
mrr: { operator: 'greaterThan', value: '100' },
|
|
66
|
-
tier: { operator: 'equals', value: '', selectedValues: ['pro', 'free'] },
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
}),
|
|
70
|
-
)
|
|
71
|
-
expect(has(calls, 'ilike')).toContainEqual(['ilike', ['name', '%a%']])
|
|
72
|
-
expect(has(calls, 'gt')).toContainEqual(['gt', ['mrr', '100']])
|
|
73
|
-
expect(has(calls, 'in')).toContainEqual(['in', ['tier', ['pro', 'free']]])
|
|
74
|
-
expect(has(calls, 'order')).toContainEqual(['order', ['mrr', { ascending: false }]])
|
|
75
|
-
// global search: OR of ILIKEs across text + enum columns (name, email, tier)
|
|
76
|
-
expect(has(calls, 'or')[0]![1][0]).toBe('name.ilike.%ada%,email.ilike.%ada%,tier.ilike.%ada%')
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('throws on a query error', async () => {
|
|
80
|
-
const { client } = makeClient({ data: null, count: null, error: { message: 'boom' } })
|
|
81
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
82
|
-
await expect(src.getRows(req({}))).rejects.toThrow('boom')
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
describe('createSupabaseDataSource writes', () => {
|
|
87
|
-
it('strips the primary key on insert', async () => {
|
|
88
|
-
const { client, calls } = makeClient({ data: { id: 9, name: 'New' }, error: null })
|
|
89
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
90
|
-
const row = await src.createRow({ id: 123, name: 'New' } as Partial<Customer>)
|
|
91
|
-
expect(has(calls, 'insert')[0]![1]).toEqual([{ name: 'New' }])
|
|
92
|
-
expect(row).toEqual({ id: 9, name: 'New' })
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('updates by the schema id field', async () => {
|
|
96
|
-
const { client, calls } = makeClient({ data: { id: 5, name: 'X' }, error: null })
|
|
97
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
98
|
-
await src.updateRow('5', { name: 'X' })
|
|
99
|
-
expect(has(calls, 'update')[0]![1]).toEqual([{ name: 'X' }])
|
|
100
|
-
expect(has(calls, 'eq')[0]![1]).toEqual(['id', '5'])
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('deletes by the schema id field', async () => {
|
|
104
|
-
const { client, calls } = makeClient({ error: null })
|
|
105
|
-
const src = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
106
|
-
await src.deleteRow('7')
|
|
107
|
-
expect(has(calls, 'delete').length).toBe(1)
|
|
108
|
-
expect(has(calls, 'eq')[0]![1]).toEqual(['id', '7'])
|
|
109
|
-
})
|
|
110
|
-
})
|
package/src/sources/supabase.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createSupabaseDataSource - a browser-ready `ServerDataSource` over a Supabase
|
|
3
|
-
* table, using the `supabase-js` client (PostgREST). You bring the client (so
|
|
4
|
-
* there's no dependency here and Row-Level Security + auth apply per request);
|
|
5
|
-
* this maps the grid's sort / filter / page / CRUD onto the query builder.
|
|
6
|
-
*
|
|
7
|
-
* import { createClient } from '@supabase/supabase-js'
|
|
8
|
-
* const client = createClient(url, anonKey)
|
|
9
|
-
* const source = createSupabaseDataSource({ client, table: 'customers', schema })
|
|
10
|
-
*
|
|
11
|
-
* Global search covers the schema's text + enum columns by default; override
|
|
12
|
-
* with `searchColumns`. The primary key comes from the schema (`idField`) and is
|
|
13
|
-
* stripped from inserts (it's database-generated).
|
|
14
|
-
*/
|
|
15
|
-
import type { RowData, ServerRequest, ServerResult } from '@svgrid/grid'
|
|
16
|
-
import { resolveIdField, type EntitySchema } from '../schema'
|
|
17
|
-
import { nudgeEnterprise } from '../license'
|
|
18
|
-
import type { WritableDataSource } from '../sveltekit/types'
|
|
19
|
-
import { normalizeFilters } from './filters'
|
|
20
|
-
|
|
21
|
-
/** The slice of a `supabase-js` client this adapter needs. */
|
|
22
|
-
export type SupabaseClientLike = {
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
-
from(table: string): any
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type SupabaseDataSourceConfig<TData extends RowData> = {
|
|
28
|
-
client: SupabaseClientLike
|
|
29
|
-
/** Table (or view) name. */
|
|
30
|
-
table: string
|
|
31
|
-
schema: EntitySchema<TData>
|
|
32
|
-
/**
|
|
33
|
-
* Columns the global search box matches (OR of ILIKEs). Defaults to the
|
|
34
|
-
* schema's text + enum fields.
|
|
35
|
-
*/
|
|
36
|
-
searchColumns?: string[]
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const sanitize = (term: string) => term.replace(/[%,()]/g, '')
|
|
40
|
-
|
|
41
|
-
export function createSupabaseDataSource<TData extends RowData>(
|
|
42
|
-
config: SupabaseDataSourceConfig<TData>,
|
|
43
|
-
): WritableDataSource<TData> {
|
|
44
|
-
nudgeEnterprise('Studio') // soft-gate; never blocks
|
|
45
|
-
const { client, table, schema } = config
|
|
46
|
-
const idField = resolveIdField(schema)
|
|
47
|
-
const searchColumns =
|
|
48
|
-
config.searchColumns ??
|
|
49
|
-
schema.fields.filter((f) => f.type === 'text' || f.type === 'enum').map((f) => String(f.field))
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
async getRows(request: ServerRequest): Promise<ServerResult<TData>> {
|
|
53
|
-
let q = client.from(table).select('*', { count: 'exact' })
|
|
54
|
-
|
|
55
|
-
const { predicates, search } = normalizeFilters(request.filterModel)
|
|
56
|
-
for (const p of predicates) {
|
|
57
|
-
switch (p.op) {
|
|
58
|
-
case 'in': q = q.in(p.column, p.values); break
|
|
59
|
-
case 'contains': q = q.ilike(p.column, `%${p.value}%`); break
|
|
60
|
-
case 'startsWith': q = q.ilike(p.column, `${p.value}%`); break
|
|
61
|
-
case 'eq': q = q.eq(p.column, p.value); break
|
|
62
|
-
case 'gt': q = q.gt(p.column, p.value); break
|
|
63
|
-
case 'lt': q = q.lt(p.column, p.value); break
|
|
64
|
-
case 'between': q = q.gte(p.column, p.value).lte(p.column, p.valueTo); break
|
|
65
|
-
case 'isNull': q = q.is(p.column, null); break
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (search && searchColumns.length) {
|
|
69
|
-
const term = sanitize(search)
|
|
70
|
-
q = q.or(searchColumns.map((c) => `${c}.ilike.%${term}%`).join(','))
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
for (const s of request.sortModel) q = q.order(s.id, { ascending: !s.desc })
|
|
74
|
-
|
|
75
|
-
const { data, count, error } = await q.range(request.startRow, request.endRow - 1)
|
|
76
|
-
if (error) throw new Error(error.message)
|
|
77
|
-
return { rows: (data ?? []) as ReadonlyArray<TData>, rowCount: count ?? 0 }
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
async createRow(input: Partial<TData>): Promise<TData> {
|
|
81
|
-
const rest = { ...input } as RowData
|
|
82
|
-
delete rest[idField] // primary key is database-generated
|
|
83
|
-
const { data, error } = await client.from(table).insert(rest).select().single()
|
|
84
|
-
if (error) throw new Error(error.message)
|
|
85
|
-
return (data ?? input) as TData
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
async updateRow(id: string, patch: Partial<TData>): Promise<TData> {
|
|
89
|
-
const { data, error } = await client.from(table).update(patch).eq(idField, id).select().single()
|
|
90
|
-
if (error) throw new Error(error.message)
|
|
91
|
-
return (data ?? { ...patch, [idField]: id }) as TData
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
async deleteRow(id: string): Promise<void> {
|
|
95
|
-
const { error } = await client.from(table).delete().eq(idField, id)
|
|
96
|
-
if (error) throw new Error(error.message)
|
|
97
|
-
},
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import type { ServerDataSource, ServerRequest } from '@svgrid/grid'
|
|
3
|
-
import type { EntitySchema } from '../schema'
|
|
4
|
-
import { withEntityRules } from './with-entity-rules'
|
|
5
|
-
|
|
6
|
-
type Order = { id: string; qty: number; price: number; total: number; createdAt?: string }
|
|
7
|
-
|
|
8
|
-
const schema: EntitySchema<Order> = {
|
|
9
|
-
name: 'orders',
|
|
10
|
-
idField: 'id',
|
|
11
|
-
fields: [
|
|
12
|
-
{ field: 'id', type: 'text', primaryKey: true, readonly: true },
|
|
13
|
-
{ field: 'qty', type: 'number', required: true },
|
|
14
|
-
{ field: 'price', type: 'number', required: true },
|
|
15
|
-
{ field: 'total', type: 'number', computed: (r) => Number(r.qty) * Number(r.price) },
|
|
16
|
-
],
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const req: ServerRequest = { startRow: 0, endRow: 10, pageIndex: 0, pageSize: 10, sortModel: [], filterModel: {} }
|
|
20
|
-
|
|
21
|
-
/** A tiny in-memory source we can wrap. */
|
|
22
|
-
function makeSource(seed: Order[] = []): ServerDataSource<Order> {
|
|
23
|
-
let rows = [...seed]
|
|
24
|
-
return {
|
|
25
|
-
async getRows() {
|
|
26
|
-
return { rows: [...rows], rowCount: rows.length }
|
|
27
|
-
},
|
|
28
|
-
async createRow(input) {
|
|
29
|
-
const row = { id: 'x', qty: 0, price: 0, total: 0, ...input } as Order
|
|
30
|
-
rows = [...rows, row]
|
|
31
|
-
return row
|
|
32
|
-
},
|
|
33
|
-
async updateRow(id, patch) {
|
|
34
|
-
const row = { ...rows.find((r) => r.id === id)!, ...patch }
|
|
35
|
-
rows = rows.map((r) => (r.id === id ? row : r))
|
|
36
|
-
return row
|
|
37
|
-
},
|
|
38
|
-
async deleteRow(id) {
|
|
39
|
-
rows = rows.filter((r) => r.id !== id)
|
|
40
|
-
},
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
describe('withEntityRules - computed materialization', () => {
|
|
45
|
-
it('materializes computed fields on getRows', async () => {
|
|
46
|
-
const source = withEntityRules(makeSource([{ id: '1', qty: 3, price: 10, total: 0 }]), schema)
|
|
47
|
-
const { rows } = await source.getRows(req)
|
|
48
|
-
expect(rows[0]!.total).toBe(30)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('materializes computed fields on the created/updated row', async () => {
|
|
52
|
-
const source = withEntityRules(makeSource(), schema)
|
|
53
|
-
const created = await source.createRow!({ id: '1', qty: 2, price: 5 })
|
|
54
|
-
expect(created.total).toBe(10)
|
|
55
|
-
const updated = await source.updateRow!('1', { qty: 4, price: 5 })
|
|
56
|
-
expect(updated.total).toBe(20)
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('withEntityRules - hooks', () => {
|
|
61
|
-
it('runs beforeCreate to transform the payload and afterCreate as a side effect', async () => {
|
|
62
|
-
const afterCreate = vi.fn()
|
|
63
|
-
const withHooks: EntitySchema<Order> = {
|
|
64
|
-
...schema,
|
|
65
|
-
hooks: { beforeCreate: (v) => ({ ...v, createdAt: '2026-01-01' }), afterCreate },
|
|
66
|
-
}
|
|
67
|
-
const source = withEntityRules(makeSource(), withHooks)
|
|
68
|
-
const row = await source.createRow!({ id: '1', qty: 1, price: 1 })
|
|
69
|
-
expect(row.createdAt).toBe('2026-01-01')
|
|
70
|
-
expect(afterCreate).toHaveBeenCalledWith(expect.objectContaining({ id: '1' }))
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('rejects a write when cross-field validate fails', async () => {
|
|
74
|
-
const withHooks: EntitySchema<Order> = {
|
|
75
|
-
...schema,
|
|
76
|
-
hooks: { validate: (v) => (Number(v.qty) <= 0 ? { qty: 'Quantity must be positive' } : null) },
|
|
77
|
-
}
|
|
78
|
-
const source = withEntityRules(makeSource(), withHooks)
|
|
79
|
-
await expect(source.createRow!({ id: '1', qty: 0, price: 5 })).rejects.toThrow(/Quantity must be positive/)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('vetoes a delete when beforeDelete throws', async () => {
|
|
83
|
-
const withHooks: EntitySchema<Order> = {
|
|
84
|
-
...schema,
|
|
85
|
-
hooks: { beforeDelete: () => { throw new Error('locked') } },
|
|
86
|
-
}
|
|
87
|
-
const source = withEntityRules(makeSource([{ id: '1', qty: 1, price: 1, total: 1 }]), withHooks)
|
|
88
|
-
await expect(source.deleteRow!('1')).rejects.toThrow(/locked/)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('leaves optional write methods absent when the source lacks them', () => {
|
|
92
|
-
const readOnly: ServerDataSource<Order> = { getRows: async () => ({ rows: [], rowCount: 0 }) }
|
|
93
|
-
const wrapped = withEntityRules(readOnly, schema)
|
|
94
|
-
expect(wrapped.createRow).toBeUndefined()
|
|
95
|
-
expect(wrapped.deleteRow).toBeUndefined()
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('passes through extra source capabilities (getAggregate)', () => {
|
|
99
|
-
const getAggregate = vi.fn()
|
|
100
|
-
const source = Object.assign(makeSource(), { getAggregate })
|
|
101
|
-
const wrapped = withEntityRules(source, schema)
|
|
102
|
-
expect((wrapped as typeof source).getAggregate).toBe(getAggregate)
|
|
103
|
-
})
|
|
104
|
-
})
|