@svgrid/enterprise 2.3.2 → 2.5.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/cdn/svgrid-enterprise.svelte-external.js +5917 -5545
- package/dist/designer/assets/index-oYok52zd.css +1 -0
- package/dist/designer/assets/{index-DVrv9dH6.js → index-qL7ir9C7.js} +89 -89
- package/dist/designer/assets/src-96d31O63.js +2873 -0
- package/dist/designer/assets/src-D-O2F805.css +1 -0
- package/dist/designer/index.html +6 -6
- package/dist/node/studio.js +681 -84
- package/package.json +3 -3
- package/src/SvGridEditPanel.dom.test.ts +174 -0
- package/src/SvGridEditPanel.svelte +209 -46
- package/src/edit-panel.test.ts +145 -36
- package/src/edit-panel.ts +167 -16
- package/src/expressions/evaluate.ts +1 -1
- package/src/expressions/parse.ts +3 -3
- package/src/index.ts +8 -0
- package/src/license-core.ts +77 -5
- package/src/license-expiry.test.ts +91 -0
- package/src/license.ts +31 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +178 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +3875 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +21 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +1938 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +205 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +18 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +264 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +697 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +3 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +134 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +55 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +2 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +46843 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +237 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +2 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +4 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +7 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +4 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +5 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +5 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +5 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +6 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +83 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +559 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +24 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +122 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +2 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +89 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +241 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +4938 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +495 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +190 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +8 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +1 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +138 -0
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +1 -0
- package/src/schema.ts +63 -0
- package/src/studio/emit-project.test.ts +191 -0
- package/src/studio/emit-project.ts +237 -27
- package/src/studio/emit-schema.ts +4 -1
- package/src/studio/index.ts +2 -0
- package/src/studio/init-flow.test.ts +150 -0
- package/src/studio/init-flow.ts +169 -22
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +178 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +3875 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +21 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +1938 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +205 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +18 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +264 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +697 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +3 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +134 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +55 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +2 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +46843 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +237 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +2 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +4 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +7 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +4 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +5 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +5 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +5 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +6 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +83 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +559 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +24 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +122 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +2 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +89 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +241 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +4938 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +495 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +190 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +8 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +1 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +138 -0
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +1 -0
- package/src/studio/project.test.ts +30 -0
- package/src/studio/project.ts +72 -8
- package/src/studio/samples/crm.ts +11 -2
- package/src/studio/samples/insurance.ts +10 -4
- package/src/studio/samples/samples.test.ts +36 -0
- package/src/studio/samples/shared.ts +14 -0
- package/src/studio/samples/support.ts +12 -5
- package/src/studio/screen-suites.test.ts +43 -0
- package/src/studio/screen-suites.ts +5 -2
- package/src/studio/user-error.ts +31 -0
- package/src/upgrade-prompt.ts +23 -10
- package/src/version.test.ts +17 -0
- package/src/version.ts +13 -0
- package/dist/designer/assets/index-DjPp1mn7.css +0 -1
- package/dist/designer/assets/src-BRKu53tV.js +0 -2842
- package/dist/designer/assets/src-DseB1VRN.css +0 -1
|
@@ -4,6 +4,7 @@ import type { EntitySchema } from '../schema'
|
|
|
4
4
|
import { addBlock, addComponentBlock, addFreestandingScreen, addScreenAction, addTabBlock, addAccordionBlock, addAccordionComponent, createProject, enableScreenCode, flattenBlocks, parseProject, serializeProject, addStateVar, setScreenLayout, setLayoutOpts, setDockPaneTitle, dockPaneTitleOf, syncDockPanes, dockPaneIds, removeBlock, setAuth, setComponentBinding, setDataLayer, setDeployTarget, setEntityDataSource, setJob, setTenancy, setTrigger, setHandlerBody, setHandlerSteps, stepsToCode, clickSlot, setScreenHandlersSource, setScreenRenderGrid, setShell, setTheme, setThemePreset, updateBlock, updateScreen, type GridConfig, type MasterDetailConfig, type TabsConfig, type AccordionConfig, type StudioProject } from './project'
|
|
5
5
|
import ts from 'typescript'
|
|
6
6
|
import { emitStudioProject, emitStudioAppBundle, emitStudioFragment, studioDeployInfo, ctxCompletions, ctxAmbientDts } from './emit-project'
|
|
7
|
+
import { crudAppFromSchemas } from './screen-suites'
|
|
7
8
|
import { UI_COMPONENT_REGISTRY } from './ui-components'
|
|
8
9
|
|
|
9
10
|
/** Type-check a handler BODY against a generated ambient ctx `.d.ts` using the real
|
|
@@ -210,6 +211,155 @@ describe('SSR-native screens (renderMode: ssr)', () => {
|
|
|
210
211
|
expect(files.find((f) => f.path === 'src/routes/customers/+page.svelte')!.contents).toMatch(/loadAll\(\)/)
|
|
211
212
|
})
|
|
212
213
|
|
|
214
|
+
it('a facet panel beside the grid becomes a GET form the server can filter on', () => {
|
|
215
|
+
// Every list screen the onboarding generator produces is [filter, grid], so
|
|
216
|
+
// if the facet panel did not survive into SSR, no generated app could ever
|
|
217
|
+
// render on the server.
|
|
218
|
+
const app = crudAppFromSchemas([customers, orders], {
|
|
219
|
+
dataSource: 'sql',
|
|
220
|
+
sources: {
|
|
221
|
+
customers: { kind: 'sql', table: 'customers', dialect: 'postgres' },
|
|
222
|
+
orders: { kind: 'sql', table: 'orders', dialect: 'postgres' },
|
|
223
|
+
},
|
|
224
|
+
})
|
|
225
|
+
const list = app.screens.find((s) => s.id === 'customers')!
|
|
226
|
+
expect(list.blocks.map((b) => b.config.kind)).toContain('filter')
|
|
227
|
+
expect(list.renderMode).toBe('ssr')
|
|
228
|
+
|
|
229
|
+
const files = emitStudioProject(app)
|
|
230
|
+
const server = files.find((f) => f.path === 'src/routes/customers/+page.server.ts')!
|
|
231
|
+
// The load + actions module has to at least parse as TypeScript.
|
|
232
|
+
expect(
|
|
233
|
+
ts.transpileModule(server.contents, { reportDiagnostics: true, compilerOptions: { target: ts.ScriptTarget.ES2021 } })
|
|
234
|
+
.diagnostics?.map((d) => ts.flattenDiagnosticMessageText(d.messageText, '\n')) ?? [],
|
|
235
|
+
).toEqual([])
|
|
236
|
+
const page = files.find((f) => f.path === 'src/routes/customers/+page.svelte')!.contents
|
|
237
|
+
expect(page).toContain('<form method="GET" class="sk-facets">')
|
|
238
|
+
// Named for the param planFromSearchParams reads, so no JS is needed to filter.
|
|
239
|
+
expect(page).toMatch(/<select name='f_tier'>/)
|
|
240
|
+
expect(page).toMatch(/name="sort"/) // sort survives a facet submit
|
|
241
|
+
// `===` binds tighter than `??`: an unparenthesised current-value read would
|
|
242
|
+
// hand `selected` the raw param and mark every option at once.
|
|
243
|
+
expect(page).toMatch(/selected=\{\(page\.url\.searchParams\.get\('f_tier'\) \?\? ''\) === 'pro'\}/)
|
|
244
|
+
for (const f of files) expect(f.contents, f.path).not.toMatch(/\?\?\s*''\s*===/)
|
|
245
|
+
// It renders on the server, so it has to compile both ways.
|
|
246
|
+
for (const mode of ['client', 'server'] as const) {
|
|
247
|
+
expect(() => compile(page, { filename: 'p.svelte', generate: mode }), mode).not.toThrow()
|
|
248
|
+
}
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it('an app with SSR screens keeps SvelteKit\'s server default and opts out per client screen', () => {
|
|
252
|
+
// The root +layout.ts is the first file a reviewer opens. Announcing
|
|
253
|
+
// `ssr = false` there makes the whole app read as a SPA even when most of its
|
|
254
|
+
// screens render on the server.
|
|
255
|
+
const app = crudAppFromSchemas([customers, orders], {
|
|
256
|
+
dataSource: 'sql',
|
|
257
|
+
sources: {
|
|
258
|
+
customers: { kind: 'sql', table: 'customers', dialect: 'postgres' },
|
|
259
|
+
orders: { kind: 'sql', table: 'orders', dialect: 'postgres' },
|
|
260
|
+
},
|
|
261
|
+
})
|
|
262
|
+
const bundle = emitStudioAppBundle(app)
|
|
263
|
+
const layout = bundle.find((f) => f.path === 'src/routes/+layout.ts')!.contents
|
|
264
|
+
expect(layout).not.toMatch(/export const ssr = false/)
|
|
265
|
+
expect(layout).toMatch(/export const prerender = false/)
|
|
266
|
+
|
|
267
|
+
// Every screen that still runs in the browser says so itself, so nothing
|
|
268
|
+
// starts rendering server-side that was never written for it.
|
|
269
|
+
for (const screen of app.screens) {
|
|
270
|
+
const optOut = bundle.find((f) => f.path === `src/routes/${screen.route}/+page.ts`)
|
|
271
|
+
if (screen.renderMode === 'ssr') expect(optOut, `${screen.id} is SSR and needs no opt-out`).toBeUndefined()
|
|
272
|
+
else expect(optOut?.contents, `${screen.id} runs client-side and must opt out`).toMatch(/export const ssr = false/)
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
it('a REST entity on an absolute URL renders on the server, calling the API directly', () => {
|
|
277
|
+
const rest = { kind: 'rest' as const, baseUrl: 'https://api.example.com', path: 'customers', method: 'GET' as const, params: [] }
|
|
278
|
+
const app = crudAppFromSchemas([customers], { dataSource: 'rest', sources: { customers: rest } })
|
|
279
|
+
expect(app.screens.find((s) => s.id === 'customers')!.renderMode).toBe('ssr')
|
|
280
|
+
|
|
281
|
+
const server = emitStudioProject(app).find((f) => f.path === 'src/routes/customers/+page.server.ts')!.contents
|
|
282
|
+
// Reads through the in-process source like memory does...
|
|
283
|
+
expect(server).toMatch(/import \{ customersSource \} from '\$lib\/data'/)
|
|
284
|
+
// ...but the remote API owns the ids, so a create posts only the values.
|
|
285
|
+
expect(server).toMatch(/await customersSource\.createRow\(values\)/)
|
|
286
|
+
expect(server).not.toMatch(/nextId/)
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
it('a relative REST url stays SPA - there is no origin to fetch from on the server', () => {
|
|
290
|
+
const rest = { kind: 'rest' as const, baseUrl: '', path: '/api/customers', method: 'GET' as const, params: [] }
|
|
291
|
+
const app = crudAppFromSchemas([customers], { dataSource: 'rest', sources: { customers: rest } })
|
|
292
|
+
expect(app.screens.every((s) => s.renderMode === undefined)).toBe(true)
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
it('the SSR form follows the schema layout and states the field constraints', () => {
|
|
296
|
+
// The server-rendered form used to be a flat single column that ignored the
|
|
297
|
+
// layout entirely, so the same entity looked like two different forms
|
|
298
|
+
// depending on which path rendered it.
|
|
299
|
+
const laidOut: EntitySchema = {
|
|
300
|
+
name: 'people',
|
|
301
|
+
idField: 'id',
|
|
302
|
+
fields: [
|
|
303
|
+
{ field: 'id', type: 'text', primaryKey: true, readonly: true },
|
|
304
|
+
{ field: 'name', type: 'text', required: true, minLength: 2, maxLength: 60, input: { placeholder: 'Ada Lovelace' } },
|
|
305
|
+
{ field: 'email', type: 'text', format: 'email', input: { help: 'We only use this for receipts.' } },
|
|
306
|
+
{ field: 'notes', type: 'text', input: { editorType: 'textarea', span: 2 } },
|
|
307
|
+
],
|
|
308
|
+
form: { columns: 2, sections: [{ title: 'Contact', description: 'How we reach them.', fields: ['name', 'email'] }] },
|
|
309
|
+
}
|
|
310
|
+
let p = createProject([laidOut])
|
|
311
|
+
p = { ...p, screens: p.screens.map((s) => ({ ...s, renderMode: 'ssr' as const })) }
|
|
312
|
+
const page = emitStudioProject(p).find((f) => f.path === 'src/routes/people/+page.svelte')!.contents
|
|
313
|
+
|
|
314
|
+
expect(page).toContain('<legend>Contact</legend>')
|
|
315
|
+
expect(page).toContain('How we reach them.')
|
|
316
|
+
expect(page).toMatch(/--sk-cols: 2/)
|
|
317
|
+
// Constraints the browser can enforce, mirroring what the action re-checks.
|
|
318
|
+
expect(page).toMatch(/minlength="2"/)
|
|
319
|
+
expect(page).toMatch(/maxlength="60"/)
|
|
320
|
+
expect(page).toMatch(/placeholder="Ada Lovelace"/)
|
|
321
|
+
expect(page).toMatch(/<input type="email"/)
|
|
322
|
+
expect(page).toContain('We only use this for receipts.')
|
|
323
|
+
expect(page).toMatch(/<textarea name='notes'/)
|
|
324
|
+
expect(page).toContain('sk-field--wide')
|
|
325
|
+
// The unassigned field still renders, in a trailing group.
|
|
326
|
+
expect(page).toMatch(/name='notes'/)
|
|
327
|
+
|
|
328
|
+
for (const mode of ['client', 'server'] as const) {
|
|
329
|
+
expect(() => compile(page, { filename: 'p.svelte', generate: mode }), mode).not.toThrow()
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
it('a layout arranged on the grid block reaches the SSR form too', () => {
|
|
334
|
+
// The designer writes the form arrangement onto the grid block. Before this,
|
|
335
|
+
// only the client panel read it, so what you arranged in the designer was not
|
|
336
|
+
// what a server-rendered screen drew.
|
|
337
|
+
let p = createProject([customers])
|
|
338
|
+
const sid = p.screens[0]!.id
|
|
339
|
+
const gid = p.screens[0]!.blocks[0]!.id
|
|
340
|
+
p = updateBlock(p, sid, gid, {
|
|
341
|
+
config: {
|
|
342
|
+
editing: 'form',
|
|
343
|
+
formColumns: 3,
|
|
344
|
+
formSections: [{ title: 'Identity', description: 'Who they are.', fields: ['name'] }],
|
|
345
|
+
} as Partial<GridConfig>,
|
|
346
|
+
})
|
|
347
|
+
p = { ...p, screens: p.screens.map((s) => ({ ...s, renderMode: 'ssr' as const })) }
|
|
348
|
+
|
|
349
|
+
const page = emitStudioProject(p).find((f) => f.path === 'src/routes/customers/+page.svelte')!.contents
|
|
350
|
+
expect(page).toContain('<legend>Identity</legend>')
|
|
351
|
+
expect(page).toContain('Who they are.')
|
|
352
|
+
expect(page).toMatch(/--sk-cols: 3/)
|
|
353
|
+
expect(() => compile(page, { filename: 'p.svelte', generate: 'server' })).not.toThrow()
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
it('an in-memory app stays a SPA at the layout, with no per-screen opt-outs', () => {
|
|
357
|
+
const app = crudAppFromSchemas([customers])
|
|
358
|
+
const bundle = emitStudioAppBundle(app)
|
|
359
|
+
expect(bundle.find((f) => f.path === 'src/routes/+layout.ts')!.contents).toMatch(/export const ssr = false/)
|
|
360
|
+
expect(bundle.filter((f) => f.path.endsWith('/+page.ts'))).toEqual([])
|
|
361
|
+
})
|
|
362
|
+
|
|
213
363
|
it('sql SSR + relation field: prefetches options via the related /api route', () => {
|
|
214
364
|
const p0 = createProject([customers, orders])
|
|
215
365
|
const p: StudioProject = {
|
|
@@ -1593,6 +1743,47 @@ describe('Custom actions', () => {
|
|
|
1593
1743
|
})
|
|
1594
1744
|
})
|
|
1595
1745
|
|
|
1746
|
+
describe('value-driven form fields (the form builder)', () => {
|
|
1747
|
+
const cmp = (column: string, op: string, value: unknown) => ({ kind: 'cmp', column, op, value })
|
|
1748
|
+
const conditional: EntitySchema = {
|
|
1749
|
+
name: 'returns',
|
|
1750
|
+
idField: 'id',
|
|
1751
|
+
fields: [
|
|
1752
|
+
{ field: 'id', type: 'text', primaryKey: true, readonly: true },
|
|
1753
|
+
{ field: 'mode', type: 'text' },
|
|
1754
|
+
{ field: 'justification', type: 'text', when: { visible: cmp('mode', 'equals', 'refund') as never } },
|
|
1755
|
+
],
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
it('carries the conditions into the generated schema, so the app behaves the same', () => {
|
|
1759
|
+
// They are plain data, so they survive the JSON round-trip into schemas.ts
|
|
1760
|
+
// with no compilation step - the reason conditions are a PredicateExpr
|
|
1761
|
+
// rather than a function.
|
|
1762
|
+
const files = emitStudioProject(createProject([conditional]))
|
|
1763
|
+
const schemas = files.find((f) => f.path === 'src/lib/schemas.ts')!.contents
|
|
1764
|
+
expect(schemas).toContain('"when"')
|
|
1765
|
+
expect(schemas).toMatch(/"column": "mode"/)
|
|
1766
|
+
expect(schemas).toMatch(/"op": "equals"/)
|
|
1767
|
+
})
|
|
1768
|
+
|
|
1769
|
+
it('makes an SSR route drop values for fields the form was hiding', () => {
|
|
1770
|
+
let p = createProject([conditional])
|
|
1771
|
+
p = { ...p, screens: p.screens.map((s) => ({ ...s, renderMode: 'ssr' as const })) }
|
|
1772
|
+
const server = emitStudioProject(p).find((f) => f.path === 'src/routes/returns/+page.server.ts')
|
|
1773
|
+
if (!server) return // shape not SSR-eligible in this project; covered elsewhere
|
|
1774
|
+
expect(server.contents).toMatch(/import \{ validateAll, stripHiddenValues \}/)
|
|
1775
|
+
expect(server.contents).toMatch(/stripHiddenValues\(returnsSchema, formToValues\(/)
|
|
1776
|
+
})
|
|
1777
|
+
|
|
1778
|
+
it('leaves a schema without conditions exactly as it was', () => {
|
|
1779
|
+
const p = createProject([customers])
|
|
1780
|
+
const ssr = { ...p, screens: p.screens.map((s) => ({ ...s, renderMode: 'ssr' as const })) }
|
|
1781
|
+
const server = emitStudioProject(ssr).find((f) => f.path === 'src/routes/customers/+page.server.ts')!.contents
|
|
1782
|
+
expect(server).not.toMatch(/stripHiddenValues/)
|
|
1783
|
+
expect(server).toMatch(/const values = formToValues\(/)
|
|
1784
|
+
})
|
|
1785
|
+
})
|
|
1786
|
+
|
|
1596
1787
|
describe('form/dialog layout depth', () => {
|
|
1597
1788
|
const gridScreen = (extra: Partial<GridConfig>) => {
|
|
1598
1789
|
let p = createProject([customers])
|