@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
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import type { EntitySchema } from '../schema'
|
|
3
|
-
import { scaffold } from './scaffold'
|
|
4
|
-
import { summarizeVerify, verifyScaffold } from './verify'
|
|
5
|
-
|
|
6
|
-
const schema: EntitySchema = {
|
|
7
|
-
name: 'customers',
|
|
8
|
-
idField: 'id',
|
|
9
|
-
fields: [
|
|
10
|
-
{ field: 'id', type: 'text', primaryKey: true },
|
|
11
|
-
{ field: 'name', type: 'text' },
|
|
12
|
-
],
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe('verifyScaffold', () => {
|
|
16
|
-
it('reports ok when the scaffolded Svelte page compiles', async () => {
|
|
17
|
-
const { files } = scaffold(schema)
|
|
18
|
-
const res = await verifyScaffold(files)
|
|
19
|
-
expect(res.ok).toBe(true)
|
|
20
|
-
expect(res.checked).toBeGreaterThan(0) // the .svelte page was compiled for real
|
|
21
|
-
expect(res.issues.filter((i) => i.severity === 'error')).toHaveLength(0)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('flags a malformed Svelte file with an error', async () => {
|
|
25
|
-
const res = await verifyScaffold([
|
|
26
|
-
{ path: 'Bad.svelte', description: '', contents: '{#if true}<p>oops' },
|
|
27
|
-
])
|
|
28
|
-
expect(res.ok).toBe(false)
|
|
29
|
-
expect(res.issues.some((i) => i.severity === 'error')).toBe(true)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('skips non-svelte files (they need the project tsc)', async () => {
|
|
33
|
-
const res = await verifyScaffold([{ path: 'x.ts', description: '', contents: 'export const a = 1' }])
|
|
34
|
-
expect(res.skipped).toBe(1)
|
|
35
|
-
expect(res.checked).toBe(0)
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
describe('summarizeVerify', () => {
|
|
40
|
-
it('summarizes ok, failure, and skipped', () => {
|
|
41
|
-
expect(summarizeVerify({ ok: true, issues: [], checked: 2, skipped: 1 })).toMatch(/verified: 2/)
|
|
42
|
-
expect(
|
|
43
|
-
summarizeVerify({ ok: false, checked: 1, skipped: 0, issues: [{ path: 'p.svelte', severity: 'error', message: 'boom' }] }),
|
|
44
|
-
).toMatch(/VERIFICATION FAILED/)
|
|
45
|
-
expect(summarizeVerify({ ok: true, issues: [], checked: 0, skipped: 2 })).toMatch(/skipped/)
|
|
46
|
-
})
|
|
47
|
-
})
|
package/src/studio/verify.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* verifyScaffold - the generator's self-check. Compiles each generated
|
|
3
|
-
* `.svelte` file with Svelte's own compiler and reports any errors, so
|
|
4
|
-
* malformed output is caught BEFORE it's written to a project. This is the
|
|
5
|
-
* cheap first gate of the verify loop; the deep gate (type resolution across
|
|
6
|
-
* real imports) is the host running the project's own `svelte-check`.
|
|
7
|
-
*
|
|
8
|
-
* The Svelte compiler is imported dynamically and best-effort: if it can't be
|
|
9
|
-
* resolved (e.g. a bare `npx @svgrid/mcp` with no svelte on disk), those files
|
|
10
|
-
* are counted as `skipped` rather than failing - the function never throws and
|
|
11
|
-
* carries no hard dependency, so it's safe in Node and in the browser.
|
|
12
|
-
*
|
|
13
|
-
* `.ts` files aren't compiled here (that needs the project's tsc + imports);
|
|
14
|
-
* they're reported as skipped.
|
|
15
|
-
*/
|
|
16
|
-
import type { GeneratedFile } from './scaffold.js'
|
|
17
|
-
|
|
18
|
-
export type VerifySeverity = 'error' | 'warning'
|
|
19
|
-
export type VerifyIssue = { path: string; severity: VerifySeverity; message: string }
|
|
20
|
-
export type VerifyResult = {
|
|
21
|
-
/** True when no error-level issues were found (warnings are allowed). */
|
|
22
|
-
ok: boolean
|
|
23
|
-
issues: VerifyIssue[]
|
|
24
|
-
/** How many files were actually compiled. */
|
|
25
|
-
checked: number
|
|
26
|
-
/** How many files were skipped (non-svelte, or compiler unavailable). */
|
|
27
|
-
skipped: number
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function verifyScaffold(
|
|
31
|
-
files: ReadonlyArray<GeneratedFile>,
|
|
32
|
-
): Promise<VerifyResult> {
|
|
33
|
-
const issues: VerifyIssue[] = []
|
|
34
|
-
let checked = 0
|
|
35
|
-
let skipped = 0
|
|
36
|
-
|
|
37
|
-
let compile: ((source: string, options: Record<string, unknown>) => { warnings: Array<{ message?: string }> }) | undefined
|
|
38
|
-
try {
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
-
const mod: any = await import('svelte/compiler')
|
|
41
|
-
compile = mod.compile
|
|
42
|
-
} catch {
|
|
43
|
-
compile = undefined
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
for (const file of files) {
|
|
47
|
-
if (!file.path.endsWith('.svelte') || !compile) {
|
|
48
|
-
skipped++
|
|
49
|
-
continue
|
|
50
|
-
}
|
|
51
|
-
try {
|
|
52
|
-
const { warnings } = compile(file.contents, { filename: file.path, generate: 'client' })
|
|
53
|
-
checked++
|
|
54
|
-
for (const w of warnings) {
|
|
55
|
-
issues.push({ path: file.path, severity: 'warning', message: w.message ?? 'warning' })
|
|
56
|
-
}
|
|
57
|
-
} catch (err) {
|
|
58
|
-
checked++
|
|
59
|
-
issues.push({
|
|
60
|
-
path: file.path,
|
|
61
|
-
severity: 'error',
|
|
62
|
-
message: err instanceof Error ? err.message : String(err),
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return { ok: !issues.some((i) => i.severity === 'error'), issues, checked, skipped }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** One-line human summary of a verify result, for tool output / logs. */
|
|
71
|
-
export function summarizeVerify(result: VerifyResult): string {
|
|
72
|
-
if (result.checked === 0) {
|
|
73
|
-
return 'verification skipped (Svelte compiler unavailable) - run svelte-check in your project.'
|
|
74
|
-
}
|
|
75
|
-
const errors = result.issues.filter((i) => i.severity === 'error')
|
|
76
|
-
if (errors.length === 0) return `verified: ${result.checked} file(s) compile.`
|
|
77
|
-
return `VERIFICATION FAILED (${errors.length} error(s)):\n` +
|
|
78
|
-
errors.map((e) => ` ${e.path}: ${e.message}`).join('\n')
|
|
79
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import type { ServerRequest } from '@svgrid/grid'
|
|
3
|
-
import type { EntitySchema } from '../schema'
|
|
4
|
-
import { createInMemoryDataSource } from './in-memory'
|
|
5
|
-
|
|
6
|
-
type Customer = { id: string; name: string; age: number; tier: string }
|
|
7
|
-
|
|
8
|
-
const schema: EntitySchema<Customer> = {
|
|
9
|
-
name: 'customers',
|
|
10
|
-
fields: [
|
|
11
|
-
{ field: 'id', type: 'text', primaryKey: true },
|
|
12
|
-
{ field: 'name', type: 'text' },
|
|
13
|
-
{ field: 'age', type: 'number' },
|
|
14
|
-
{ field: 'tier', type: 'enum' },
|
|
15
|
-
],
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const seed: Customer[] = [
|
|
19
|
-
{ id: '1', name: 'Ann', age: 30, tier: 'pro' },
|
|
20
|
-
{ id: '2', name: 'Bob', age: 41, tier: 'free' },
|
|
21
|
-
{ id: '3', name: 'Cara', age: 25, tier: 'pro' },
|
|
22
|
-
{ id: '4', name: 'Dan', age: 55, tier: 'free' },
|
|
23
|
-
{ id: '5', name: 'Eve', age: 38, tier: 'pro' },
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
function req(partial: Partial<ServerRequest>): ServerRequest {
|
|
27
|
-
return { startRow: 0, endRow: 50, pageIndex: 0, pageSize: 50, sortModel: [], filterModel: {}, ...partial }
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
describe('createInMemoryDataSource reads', () => {
|
|
31
|
-
it('filters with a numeric operator and reports the filtered count', async () => {
|
|
32
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
33
|
-
const { rows, rowCount } = await src.getRows(
|
|
34
|
-
req({ filterModel: { columns: { age: { operator: 'greaterThan', value: '35' } } } }),
|
|
35
|
-
)
|
|
36
|
-
expect(rows.map((r) => r.name).sort()).toEqual(['Bob', 'Dan', 'Eve'])
|
|
37
|
-
expect(rowCount).toBe(3)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('runs a case-insensitive global search over textual fields', async () => {
|
|
41
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
42
|
-
const { rows } = await src.getRows(req({ filterModel: { global: 'PRO' } }))
|
|
43
|
-
expect(rows.map((r) => r.id).sort()).toEqual(['1', '3', '5'])
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('sorts descending and pages', async () => {
|
|
47
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
48
|
-
const { rows, rowCount } = await src.getRows(
|
|
49
|
-
req({ sortModel: [{ id: 'age', desc: true }], startRow: 0, pageSize: 2 }),
|
|
50
|
-
)
|
|
51
|
-
expect(rows.map((r) => r.age)).toEqual([55, 41])
|
|
52
|
-
expect(rowCount).toBe(5)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('an `in` (facet) filter selects the listed values', async () => {
|
|
56
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
57
|
-
const { rows } = await src.getRows(
|
|
58
|
-
req({ filterModel: { columns: { tier: { operator: 'equals', value: '', selectedValues: ['free'] } } } }),
|
|
59
|
-
)
|
|
60
|
-
expect(rows.map((r) => r.name).sort()).toEqual(['Bob', 'Dan'])
|
|
61
|
-
})
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
describe('createInMemoryDataSource writes', () => {
|
|
65
|
-
it('creates, updates, and deletes, reflected in subsequent reads', async () => {
|
|
66
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
67
|
-
|
|
68
|
-
const created = await src.createRow({ id: '6', name: 'Fay', age: 22, tier: 'free' })
|
|
69
|
-
expect(created.name).toBe('Fay')
|
|
70
|
-
expect((await src.getRows(req({}))).rowCount).toBe(6)
|
|
71
|
-
|
|
72
|
-
const updated = await src.updateRow('6', { age: 23 })
|
|
73
|
-
expect(updated.age).toBe(23)
|
|
74
|
-
|
|
75
|
-
await src.deleteRow('1')
|
|
76
|
-
const after = await src.getRows(req({}))
|
|
77
|
-
expect(after.rowCount).toBe(5)
|
|
78
|
-
expect(after.rows.some((r) => r.id === '1')).toBe(false)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('throws when updating a missing row', async () => {
|
|
82
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
83
|
-
await expect(src.updateRow('999', { age: 1 })).rejects.toThrow(/no row with id="999"/)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('getAggregate groups + reduces, honoring a filter', async () => {
|
|
87
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
88
|
-
expect(await src.getAggregate({ dimension: 'tier', reduce: 'count' })).toEqual([
|
|
89
|
-
{ category: 'pro', value: 3 },
|
|
90
|
-
{ category: 'free', value: 2 },
|
|
91
|
-
])
|
|
92
|
-
// filtered: only age > 35 -> Bob(free), Dan(free), Eve(pro)
|
|
93
|
-
const filtered = await src.getAggregate({
|
|
94
|
-
dimension: 'tier', reduce: 'count',
|
|
95
|
-
filterModel: { columns: { age: { operator: 'greaterThan', value: '35' } } },
|
|
96
|
-
})
|
|
97
|
-
expect(filtered).toEqual([{ category: 'free', value: 2 }, { category: 'pro', value: 1 }])
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('getAggregate with no dimension is a single grand total (a KPI)', async () => {
|
|
101
|
-
const src = createInMemoryDataSource(seed, schema)
|
|
102
|
-
expect(await src.getAggregate({ reduce: 'count' })).toEqual([{ category: '', value: 5 }])
|
|
103
|
-
})
|
|
104
|
-
})
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory reference `ServerDataSource`. Applies a `QueryPlan` to a plain
|
|
3
|
-
* array - filter, global search, sort, page - and supports the full CRUD
|
|
4
|
-
* contract. It is the executable specification of what a backend adapter must
|
|
5
|
-
* do, and is genuinely useful on its own for small datasets, tests, demos,
|
|
6
|
-
* and prototyping a schema before a database exists behind it.
|
|
7
|
-
*/
|
|
8
|
-
import type { RowData, ServerRequest, ServerResult } from '@svgrid/grid'
|
|
9
|
-
import { resolveIdField, type EntitySchema } from '../schema'
|
|
10
|
-
import { planQuery, type PlanPredicate, type QueryPlan } from './query-plan'
|
|
11
|
-
import type { WritableDataSource } from './types'
|
|
12
|
-
import { aggregateRows, type AggregateBucket, type AggregateRequest, type AggregateSource } from '../sources/aggregate'
|
|
13
|
-
|
|
14
|
-
function asString(v: unknown): string {
|
|
15
|
-
return v == null ? '' : String(v)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function num(v: unknown): number {
|
|
19
|
-
return typeof v === 'number' ? v : Number(v)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function matchesPredicate(row: RowData, p: PlanPredicate): boolean {
|
|
23
|
-
const cell = row[p.field]
|
|
24
|
-
switch (p.op) {
|
|
25
|
-
case 'eq':
|
|
26
|
-
return asString(cell) === asString(p.value)
|
|
27
|
-
case 'contains':
|
|
28
|
-
return asString(cell).toLowerCase().includes(asString(p.value).toLowerCase())
|
|
29
|
-
case 'startsWith':
|
|
30
|
-
return asString(cell).toLowerCase().startsWith(asString(p.value).toLowerCase())
|
|
31
|
-
case 'gt':
|
|
32
|
-
return typeof p.value === 'number' ? num(cell) > p.value : asString(cell) > asString(p.value)
|
|
33
|
-
case 'lt':
|
|
34
|
-
return typeof p.value === 'number' ? num(cell) < p.value : asString(cell) < asString(p.value)
|
|
35
|
-
case 'between': {
|
|
36
|
-
if (typeof p.value === 'number' && typeof p.valueTo === 'number') {
|
|
37
|
-
return num(cell) >= p.value && num(cell) <= p.valueTo
|
|
38
|
-
}
|
|
39
|
-
return asString(cell) >= asString(p.value) && asString(cell) <= asString(p.valueTo)
|
|
40
|
-
}
|
|
41
|
-
case 'isBlank':
|
|
42
|
-
return cell == null || cell === ''
|
|
43
|
-
case 'in':
|
|
44
|
-
return (p.values ?? []).some((v) => asString(v) === asString(cell))
|
|
45
|
-
default:
|
|
46
|
-
return true
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function matches(row: RowData, plan: QueryPlan): boolean {
|
|
51
|
-
if (plan.search) {
|
|
52
|
-
const term = plan.search.term.toLowerCase()
|
|
53
|
-
const hit = plan.search.fields.some((f) => asString(row[f]).toLowerCase().includes(term))
|
|
54
|
-
if (!hit) return false
|
|
55
|
-
}
|
|
56
|
-
return plan.where.every((p) => matchesPredicate(row, p))
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function sortRows<T extends RowData>(rows: T[], orderBy: QueryPlan['orderBy']): T[] {
|
|
60
|
-
if (orderBy.length === 0) return rows
|
|
61
|
-
// Stable multi-key sort: decorate with index, compare keys in order, fall back to index.
|
|
62
|
-
return rows
|
|
63
|
-
.map((row, index) => ({ row, index }))
|
|
64
|
-
.sort((a, b) => {
|
|
65
|
-
for (const { field, desc } of orderBy) {
|
|
66
|
-
const av = a.row[field]
|
|
67
|
-
const bv = b.row[field]
|
|
68
|
-
let cmp: number
|
|
69
|
-
if (typeof av === 'number' && typeof bv === 'number') cmp = av - bv
|
|
70
|
-
else cmp = asString(av).localeCompare(asString(bv))
|
|
71
|
-
if (cmp !== 0) return desc ? -cmp : cmp
|
|
72
|
-
}
|
|
73
|
-
return a.index - b.index
|
|
74
|
-
})
|
|
75
|
-
.map((d) => d.row)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function createInMemoryDataSource<TData extends RowData>(
|
|
79
|
-
initial: ReadonlyArray<TData>,
|
|
80
|
-
schema: EntitySchema<TData>,
|
|
81
|
-
): WritableDataSource<TData> & AggregateSource & { rows(): ReadonlyArray<TData> } {
|
|
82
|
-
let store: TData[] = [...initial]
|
|
83
|
-
const idField = resolveIdField(schema)
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
async getRows(request: ServerRequest): Promise<ServerResult<TData>> {
|
|
87
|
-
const plan = planQuery(schema, request)
|
|
88
|
-
const filtered = sortRows(
|
|
89
|
-
store.filter((r) => matches(r, plan)),
|
|
90
|
-
plan.orderBy,
|
|
91
|
-
)
|
|
92
|
-
return {
|
|
93
|
-
rows: filtered.slice(plan.offset, plan.offset + plan.limit),
|
|
94
|
-
rowCount: filtered.length,
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
async createRow(input: Partial<TData>): Promise<TData> {
|
|
98
|
-
const row = { ...input } as TData
|
|
99
|
-
store = [...store, row]
|
|
100
|
-
return row
|
|
101
|
-
},
|
|
102
|
-
async updateRow(id: string, patch: Partial<TData>): Promise<TData> {
|
|
103
|
-
let updated: TData | undefined
|
|
104
|
-
store = store.map((r) => {
|
|
105
|
-
if (asString(r[idField]) === id) {
|
|
106
|
-
updated = { ...r, ...patch }
|
|
107
|
-
return updated
|
|
108
|
-
}
|
|
109
|
-
return r
|
|
110
|
-
})
|
|
111
|
-
if (!updated) throw new Error(`createInMemoryDataSource: no row with ${idField}="${id}"`)
|
|
112
|
-
return updated
|
|
113
|
-
},
|
|
114
|
-
async deleteRow(id: string): Promise<void> {
|
|
115
|
-
store = store.filter((r) => asString(r[idField]) !== id)
|
|
116
|
-
},
|
|
117
|
-
async getAggregate(request: AggregateRequest): Promise<AggregateBucket[]> {
|
|
118
|
-
// Apply the (optional) filter using the same plan machinery as getRows,
|
|
119
|
-
// over the whole store (no paging), then reduce in memory.
|
|
120
|
-
const plan = planQuery(schema, {
|
|
121
|
-
startRow: 0, endRow: store.length, pageIndex: 0, pageSize: store.length,
|
|
122
|
-
sortModel: [], filterModel: request.filterModel ?? {},
|
|
123
|
-
})
|
|
124
|
-
const filtered = store.filter((r) => matches(r, plan))
|
|
125
|
-
return aggregateRows(filtered, request)
|
|
126
|
-
},
|
|
127
|
-
rows: () => store,
|
|
128
|
-
}
|
|
129
|
-
}
|
package/src/sveltekit/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
planQuery,
|
|
3
|
-
coerce,
|
|
4
|
-
type QueryPlan,
|
|
5
|
-
type PlanPredicate,
|
|
6
|
-
type PlanOp,
|
|
7
|
-
} from './query-plan'
|
|
8
|
-
export { createInMemoryDataSource } from './in-memory'
|
|
9
|
-
export {
|
|
10
|
-
createKitDataSource,
|
|
11
|
-
createKitHandlers,
|
|
12
|
-
type KitDataSourceOptions,
|
|
13
|
-
type KitHandlerOptions,
|
|
14
|
-
type KitScope,
|
|
15
|
-
type KitHandlers,
|
|
16
|
-
type KitMessage,
|
|
17
|
-
} from './transport'
|
|
18
|
-
export { planToSql, type SqlDialect, type SqlPlan } from './sql'
|
|
19
|
-
export {
|
|
20
|
-
createSqlDataSource,
|
|
21
|
-
type SqlExecutor,
|
|
22
|
-
type SqlDataSourceConfig,
|
|
23
|
-
} from './sql-source'
|
|
24
|
-
export type { WritableDataSource } from './types'
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import type { ServerRequest } from '@svgrid/grid'
|
|
3
|
-
import type { EntitySchema } from '../schema'
|
|
4
|
-
import { planQuery } from './query-plan'
|
|
5
|
-
|
|
6
|
-
type Customer = { id: string; name: string; age: number; tier: string; active: boolean }
|
|
7
|
-
|
|
8
|
-
const schema: EntitySchema<Customer> = {
|
|
9
|
-
name: 'customers',
|
|
10
|
-
fields: [
|
|
11
|
-
{ field: 'id', type: 'text', primaryKey: true },
|
|
12
|
-
{ field: 'name', type: 'text' },
|
|
13
|
-
{ field: 'age', type: 'number' },
|
|
14
|
-
{ field: 'tier', type: 'enum', options: [{ value: 'free', label: 'Free' }, { value: 'pro', label: 'Pro' }] },
|
|
15
|
-
{ field: 'active', type: 'boolean' },
|
|
16
|
-
],
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function req(partial: Partial<ServerRequest>): ServerRequest {
|
|
20
|
-
return {
|
|
21
|
-
startRow: 0,
|
|
22
|
-
endRow: 50,
|
|
23
|
-
pageIndex: 0,
|
|
24
|
-
pageSize: 50,
|
|
25
|
-
sortModel: [],
|
|
26
|
-
filterModel: {},
|
|
27
|
-
...partial,
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
describe('planQuery', () => {
|
|
32
|
-
it('maps grid operators to plan predicates', () => {
|
|
33
|
-
const plan = planQuery(
|
|
34
|
-
schema,
|
|
35
|
-
req({ filterModel: { columns: { name: { operator: 'contains', value: 'ann' } } } }),
|
|
36
|
-
)
|
|
37
|
-
expect(plan.where).toEqual([{ field: 'name', op: 'contains', value: 'ann' }])
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('coerces numeric operands to numbers', () => {
|
|
41
|
-
const plan = planQuery(
|
|
42
|
-
schema,
|
|
43
|
-
req({ filterModel: { columns: { age: { operator: 'greaterThan', value: '30' } } } }),
|
|
44
|
-
)
|
|
45
|
-
expect(plan.where[0]).toEqual({ field: 'age', op: 'gt', value: 30 })
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('turns selectedValues into an `in` predicate', () => {
|
|
49
|
-
const plan = planQuery(
|
|
50
|
-
schema,
|
|
51
|
-
req({ filterModel: { columns: { tier: { operator: 'equals', value: '', selectedValues: ['free', 'pro'] } } } }),
|
|
52
|
-
)
|
|
53
|
-
expect(plan.where[0]).toEqual({ field: 'tier', op: 'in', values: ['free', 'pro'] })
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('coerces both bounds of a between', () => {
|
|
57
|
-
const plan = planQuery(
|
|
58
|
-
schema,
|
|
59
|
-
req({ filterModel: { columns: { age: { operator: 'between', value: '20', valueTo: '40' } } } }),
|
|
60
|
-
)
|
|
61
|
-
expect(plan.where[0]).toEqual({ field: 'age', op: 'between', value: 20, valueTo: 40 })
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('whitelists fields: unknown columns are dropped', () => {
|
|
65
|
-
const plan = planQuery(
|
|
66
|
-
schema,
|
|
67
|
-
req({ filterModel: { columns: { evil: { operator: 'contains', value: 'x' } } } }),
|
|
68
|
-
)
|
|
69
|
-
expect(plan.where).toHaveLength(0)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('drops empty operator values but keeps isBlank', () => {
|
|
73
|
-
const plan = planQuery(
|
|
74
|
-
schema,
|
|
75
|
-
req({
|
|
76
|
-
filterModel: {
|
|
77
|
-
columns: {
|
|
78
|
-
name: { operator: 'contains', value: '' },
|
|
79
|
-
id: { operator: 'isBlank', value: '' },
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
}),
|
|
83
|
-
)
|
|
84
|
-
expect(plan.where).toEqual([{ field: 'id', op: 'isBlank' }])
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('builds a search over textual fields only', () => {
|
|
88
|
-
const plan = planQuery(schema, req({ filterModel: { global: ' acme ' } }))
|
|
89
|
-
expect(plan.search).toEqual({ term: 'acme', fields: ['name', 'tier'] })
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('is null-search when no global term', () => {
|
|
93
|
-
expect(planQuery(schema, req({})).search).toBeNull()
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('maps sort, dropping unknown sort fields', () => {
|
|
97
|
-
const plan = planQuery(
|
|
98
|
-
schema,
|
|
99
|
-
req({ sortModel: [{ id: 'age', desc: true }, { id: 'ghost', desc: false }] }),
|
|
100
|
-
)
|
|
101
|
-
expect(plan.orderBy).toEqual([{ field: 'age', desc: true }])
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('carries paging through as limit/offset', () => {
|
|
105
|
-
const plan = planQuery(schema, req({ startRow: 100, pageSize: 25 }))
|
|
106
|
-
expect(plan.limit).toBe(25)
|
|
107
|
-
expect(plan.offset).toBe(100)
|
|
108
|
-
})
|
|
109
|
-
})
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The query-plan seam. `planQuery` turns the grid's `ServerRequest` (sort +
|
|
3
|
-
* filter + paging) into a neutral, backend-agnostic `QueryPlan`. Every backend
|
|
4
|
-
* adapter - the in-memory reference source, `planToSql` for any SQL database,
|
|
5
|
-
* a Drizzle/Supabase mapping - consumes this one plan, so the request-shaping
|
|
6
|
-
* logic (operator mapping, type coercion, field whitelisting) lives and is
|
|
7
|
-
* tested in exactly one place.
|
|
8
|
-
*
|
|
9
|
-
* Security note: only fields declared on the `EntitySchema` reach the plan.
|
|
10
|
-
* Unknown column names in the request are dropped, so a client cannot smuggle
|
|
11
|
-
* arbitrary identifiers through to SQL.
|
|
12
|
-
*/
|
|
13
|
-
import type { RowData, ServerRequest } from '@svgrid/grid'
|
|
14
|
-
import type { EntityFieldType, EntitySchema } from '../schema'
|
|
15
|
-
|
|
16
|
-
/** Normalized predicate operators (a stable superset of the grid's filter operators). */
|
|
17
|
-
export type PlanOp = 'eq' | 'contains' | 'startsWith' | 'gt' | 'lt' | 'between' | 'isBlank' | 'in'
|
|
18
|
-
|
|
19
|
-
export type PlanPredicate = {
|
|
20
|
-
field: string
|
|
21
|
-
op: PlanOp
|
|
22
|
-
/** Single operand (eq / contains / startsWith / gt / lt, and the low bound of between). */
|
|
23
|
-
value?: unknown
|
|
24
|
-
/** Upper bound for `between`. */
|
|
25
|
-
valueTo?: unknown
|
|
26
|
-
/** Operands for `in` (set / facet filter). */
|
|
27
|
-
values?: unknown[]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type QueryPlan = {
|
|
31
|
-
/** AND-combined column predicates. */
|
|
32
|
-
where: PlanPredicate[]
|
|
33
|
-
/** Global free-text search: OR `contains` across these textual fields. Null when no search term. */
|
|
34
|
-
search: { term: string; fields: string[] } | null
|
|
35
|
-
orderBy: Array<{ field: string; desc: boolean }>
|
|
36
|
-
limit: number
|
|
37
|
-
offset: number
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Grid filter operator -> normalized plan operator. Unmapped operators are ignored. */
|
|
41
|
-
const OP_MAP: Record<string, PlanOp> = {
|
|
42
|
-
equals: 'eq',
|
|
43
|
-
contains: 'contains',
|
|
44
|
-
startsWith: 'startsWith',
|
|
45
|
-
greaterThan: 'gt',
|
|
46
|
-
lessThan: 'lt',
|
|
47
|
-
between: 'between',
|
|
48
|
-
isBlank: 'isBlank',
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Field types that global text search scans. */
|
|
52
|
-
const TEXTUAL: ReadonlySet<EntityFieldType> = new Set<EntityFieldType>(['text', 'enum'])
|
|
53
|
-
|
|
54
|
-
/** Coerce a raw string request value to the field's runtime type for correct comparisons. */
|
|
55
|
-
export function coerce(type: EntityFieldType, raw: unknown): unknown {
|
|
56
|
-
if (raw == null) return raw
|
|
57
|
-
switch (type) {
|
|
58
|
-
case 'number': {
|
|
59
|
-
const n = Number(raw)
|
|
60
|
-
return Number.isFinite(n) ? n : undefined
|
|
61
|
-
}
|
|
62
|
-
case 'boolean':
|
|
63
|
-
return raw === true || raw === 'true'
|
|
64
|
-
default:
|
|
65
|
-
// text / date / dateString / datetime / enum / relation / json: compared as strings
|
|
66
|
-
return typeof raw === 'string' ? raw : String(raw)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function planQuery<TData extends RowData>(
|
|
71
|
-
schema: EntitySchema<TData>,
|
|
72
|
-
request: ServerRequest,
|
|
73
|
-
): QueryPlan {
|
|
74
|
-
const fields = new Map(schema.fields.map((f) => [f.field, f]))
|
|
75
|
-
const where: PlanPredicate[] = []
|
|
76
|
-
const fm = request.filterModel ?? {}
|
|
77
|
-
|
|
78
|
-
for (const [field, spec] of Object.entries(fm.columns ?? {})) {
|
|
79
|
-
const def = fields.get(field)
|
|
80
|
-
if (!def) continue // whitelist: ignore columns not on the schema
|
|
81
|
-
|
|
82
|
-
// A facet / set selection wins over the operator filter.
|
|
83
|
-
if (spec.selectedValues && spec.selectedValues.length > 0) {
|
|
84
|
-
where.push({ field, op: 'in', values: spec.selectedValues.map((v) => coerce(def.type, v)) })
|
|
85
|
-
continue
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const op = OP_MAP[spec.operator]
|
|
89
|
-
if (!op) continue
|
|
90
|
-
|
|
91
|
-
if (op === 'isBlank') {
|
|
92
|
-
where.push({ field, op })
|
|
93
|
-
continue
|
|
94
|
-
}
|
|
95
|
-
if (op === 'between') {
|
|
96
|
-
where.push({
|
|
97
|
-
field,
|
|
98
|
-
op,
|
|
99
|
-
value: coerce(def.type, spec.value),
|
|
100
|
-
valueTo: coerce(def.type, spec.valueTo),
|
|
101
|
-
})
|
|
102
|
-
continue
|
|
103
|
-
}
|
|
104
|
-
if (spec.value === '' || spec.value == null) continue
|
|
105
|
-
where.push({ field, op, value: coerce(def.type, spec.value) })
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const term = (fm.global ?? '').trim()
|
|
109
|
-
const search =
|
|
110
|
-
term.length > 0
|
|
111
|
-
? {
|
|
112
|
-
term,
|
|
113
|
-
// Textual, non-key fields: searching a primary key by substring is noise.
|
|
114
|
-
fields: schema.fields
|
|
115
|
-
.filter((f) => TEXTUAL.has(f.type) && !f.primaryKey && f.field !== schema.idField)
|
|
116
|
-
.map((f) => f.field),
|
|
117
|
-
}
|
|
118
|
-
: null
|
|
119
|
-
|
|
120
|
-
const orderBy = (request.sortModel ?? [])
|
|
121
|
-
.filter((s) => fields.has(s.id))
|
|
122
|
-
.map((s) => ({ field: s.id, desc: !!s.desc }))
|
|
123
|
-
|
|
124
|
-
return { where, search, orderBy, limit: request.pageSize, offset: request.startRow }
|
|
125
|
-
}
|