@pilotiq/pilotiq 0.7.1 → 0.8.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/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +154 -0
- package/CLAUDE.md +59 -3
- package/dist/Pilotiq.d.ts +83 -0
- package/dist/Pilotiq.d.ts.map +1 -1
- package/dist/Pilotiq.js +39 -0
- package/dist/Pilotiq.js.map +1 -1
- package/dist/actions/Action.d.ts +27 -99
- package/dist/actions/Action.d.ts.map +1 -1
- package/dist/actions/Action.js +52 -754
- package/dist/actions/Action.js.map +1 -1
- package/dist/actions/bulkFactories.d.ts +46 -0
- package/dist/actions/bulkFactories.d.ts.map +1 -0
- package/dist/actions/bulkFactories.js +144 -0
- package/dist/actions/bulkFactories.js.map +1 -0
- package/dist/actions/crudFactories.d.ts +94 -0
- package/dist/actions/crudFactories.d.ts.map +1 -0
- package/dist/actions/crudFactories.js +209 -0
- package/dist/actions/crudFactories.js.map +1 -0
- package/dist/actions/factoryHelpers.d.ts +108 -0
- package/dist/actions/factoryHelpers.d.ts.map +1 -0
- package/dist/actions/factoryHelpers.js +138 -0
- package/dist/actions/factoryHelpers.js.map +1 -0
- package/dist/actions/m2mFactories.d.ts +47 -0
- package/dist/actions/m2mFactories.d.ts.map +1 -0
- package/dist/actions/m2mFactories.js +173 -0
- package/dist/actions/m2mFactories.js.map +1 -0
- package/dist/actions/relationFactories.d.ts +93 -0
- package/dist/actions/relationFactories.d.ts.map +1 -0
- package/dist/actions/relationFactories.js +321 -0
- package/dist/actions/relationFactories.js.map +1 -0
- package/dist/elements/dispatchForm.js +1 -1
- package/dist/elements/dispatchForm.js.map +1 -1
- package/dist/elements/dispatchTable.js +1 -1
- package/dist/elements/dispatchTable.js.map +1 -1
- package/dist/fields/Field.d.ts +31 -0
- package/dist/fields/Field.d.ts.map +1 -1
- package/dist/fields/Field.js +25 -0
- package/dist/fields/Field.js.map +1 -1
- package/dist/pageData/breadcrumbs.d.ts +42 -0
- package/dist/pageData/breadcrumbs.d.ts.map +1 -0
- package/dist/pageData/breadcrumbs.js +172 -0
- package/dist/pageData/breadcrumbs.js.map +1 -0
- package/dist/pageData/forms.d.ts +137 -0
- package/dist/pageData/forms.d.ts.map +1 -0
- package/dist/pageData/forms.js +427 -0
- package/dist/pageData/forms.js.map +1 -0
- package/dist/pageData/helpers.d.ts +239 -0
- package/dist/pageData/helpers.d.ts.map +1 -0
- package/dist/pageData/helpers.js +703 -0
- package/dist/pageData/helpers.js.map +1 -0
- package/dist/pageData/misc.d.ts +76 -0
- package/dist/pageData/misc.d.ts.map +1 -0
- package/dist/pageData/misc.js +263 -0
- package/dist/pageData/misc.js.map +1 -0
- package/dist/pageData/navigation.d.ts +292 -0
- package/dist/pageData/navigation.d.ts.map +1 -0
- package/dist/pageData/navigation.js +591 -0
- package/dist/pageData/navigation.js.map +1 -0
- package/dist/pageData/relationPages.d.ts +172 -0
- package/dist/pageData/relationPages.d.ts.map +1 -0
- package/dist/pageData/relationPages.js +867 -0
- package/dist/pageData/relationPages.js.map +1 -0
- package/dist/pageData/relationTabs.d.ts +65 -0
- package/dist/pageData/relationTabs.d.ts.map +1 -0
- package/dist/pageData/relationTabs.js +258 -0
- package/dist/pageData/relationTabs.js.map +1 -0
- package/dist/pageData/resourcePages.d.ts +48 -0
- package/dist/pageData/resourcePages.d.ts.map +1 -0
- package/dist/pageData/resourcePages.js +504 -0
- package/dist/pageData/resourcePages.js.map +1 -0
- package/dist/pageData.d.ts +12 -792
- package/dist/pageData.d.ts.map +1 -1
- package/dist/pageData.js +24 -3797
- package/dist/pageData.js.map +1 -1
- package/dist/react/AppShell.d.ts +8 -0
- package/dist/react/AppShell.d.ts.map +1 -1
- package/dist/react/AppShell.js +11 -1
- package/dist/react/AppShell.js.map +1 -1
- package/dist/react/CollabExtensionFactoryRegistry.d.ts +47 -0
- package/dist/react/CollabExtensionFactoryRegistry.d.ts.map +1 -0
- package/dist/react/CollabExtensionFactoryRegistry.js +14 -0
- package/dist/react/CollabExtensionFactoryRegistry.js.map +1 -0
- package/dist/react/CollabRoomContext.d.ts +37 -0
- package/dist/react/CollabRoomContext.d.ts.map +1 -0
- package/dist/react/CollabRoomContext.js +12 -0
- package/dist/react/CollabRoomContext.js.map +1 -0
- package/dist/react/FormCollabBindingRegistry.d.ts +62 -0
- package/dist/react/FormCollabBindingRegistry.d.ts.map +1 -0
- package/dist/react/FormCollabBindingRegistry.js +14 -0
- package/dist/react/FormCollabBindingRegistry.js.map +1 -0
- package/dist/react/RecordWrapperGate.d.ts +25 -0
- package/dist/react/RecordWrapperGate.d.ts.map +1 -0
- package/dist/react/RecordWrapperGate.js +30 -0
- package/dist/react/RecordWrapperGate.js.map +1 -0
- package/dist/react/RecordWrapperRegistry.d.ts +31 -0
- package/dist/react/RecordWrapperRegistry.d.ts.map +1 -0
- package/dist/react/RecordWrapperRegistry.js +15 -0
- package/dist/react/RecordWrapperRegistry.js.map +1 -0
- package/dist/react/SchemaRenderer.d.ts +17 -23
- package/dist/react/SchemaRenderer.d.ts.map +1 -1
- package/dist/react/SchemaRenderer.js +71 -3647
- package/dist/react/SchemaRenderer.js.map +1 -1
- package/dist/react/component-slots.d.ts +103 -0
- package/dist/react/component-slots.d.ts.map +1 -0
- package/dist/react/component-slots.js +18 -0
- package/dist/react/component-slots.js.map +1 -0
- package/dist/react/fields/BuilderInput.d.ts.map +1 -1
- package/dist/react/fields/BuilderInput.js +21 -117
- package/dist/react/fields/BuilderInput.js.map +1 -1
- package/dist/react/fields/MarkdownInput.d.ts.map +1 -1
- package/dist/react/fields/MarkdownInput.js +1 -3
- package/dist/react/fields/MarkdownInput.js.map +1 -1
- package/dist/react/fields/RepeaterInput.d.ts.map +1 -1
- package/dist/react/fields/RepeaterInput.js +22 -127
- package/dist/react/fields/RepeaterInput.js.map +1 -1
- package/dist/react/fields/rowState.d.ts +40 -0
- package/dist/react/fields/rowState.d.ts.map +1 -0
- package/dist/react/fields/rowState.js +60 -0
- package/dist/react/fields/rowState.js.map +1 -0
- package/dist/react/fields/useRowReorderDnd.d.ts +28 -0
- package/dist/react/fields/useRowReorderDnd.d.ts.map +1 -0
- package/dist/react/fields/useRowReorderDnd.js +51 -0
- package/dist/react/fields/useRowReorderDnd.js.map +1 -0
- package/dist/react/index.d.ts +9 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +8 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/layouts/SidebarLayout.d.ts +1 -1
- package/dist/react/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/react/layouts/SidebarLayout.js +10 -2
- package/dist/react/layouts/SidebarLayout.js.map +1 -1
- package/dist/react/layouts/TopbarLayout.d.ts +1 -1
- package/dist/react/layouts/TopbarLayout.d.ts.map +1 -1
- package/dist/react/layouts/TopbarLayout.js +19 -11
- package/dist/react/layouts/TopbarLayout.js.map +1 -1
- package/dist/react/parseRecordEditUrl.d.ts +29 -0
- package/dist/react/parseRecordEditUrl.d.ts.map +1 -0
- package/dist/react/parseRecordEditUrl.js +25 -0
- package/dist/react/parseRecordEditUrl.js.map +1 -0
- package/dist/react/persistedState.d.ts +19 -0
- package/dist/react/persistedState.d.ts.map +1 -0
- package/dist/react/persistedState.js +51 -0
- package/dist/react/persistedState.js.map +1 -0
- package/dist/react/schemaRenderer/AlertRenderer.d.ts +12 -0
- package/dist/react/schemaRenderer/AlertRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/AlertRenderer.js +61 -0
- package/dist/react/schemaRenderer/AlertRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/EntryRenderer.d.ts +13 -0
- package/dist/react/schemaRenderer/EntryRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/EntryRenderer.js +277 -0
- package/dist/react/schemaRenderer/EntryRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/SectionRenderer.d.ts +16 -0
- package/dist/react/schemaRenderer/SectionRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/SectionRenderer.js +62 -0
- package/dist/react/schemaRenderer/SectionRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/SimpleElements.d.ts +25 -0
- package/dist/react/schemaRenderer/SimpleElements.d.ts.map +1 -0
- package/dist/react/schemaRenderer/SimpleElements.js +147 -0
- package/dist/react/schemaRenderer/SimpleElements.js.map +1 -0
- package/dist/react/schemaRenderer/TabsRenderer.d.ts +17 -0
- package/dist/react/schemaRenderer/TabsRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/TabsRenderer.js +31 -0
- package/dist/react/schemaRenderer/TabsRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/WizardRenderer.d.ts +34 -0
- package/dist/react/schemaRenderer/WizardRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/WizardRenderer.js +208 -0
- package/dist/react/schemaRenderer/WizardRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/action/ActionGroupTrigger.d.ts +21 -0
- package/dist/react/schemaRenderer/action/ActionGroupTrigger.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/ActionGroupTrigger.js +82 -0
- package/dist/react/schemaRenderer/action/ActionGroupTrigger.js.map +1 -0
- package/dist/react/schemaRenderer/action/ActionModalDialog.d.ts +30 -0
- package/dist/react/schemaRenderer/action/ActionModalDialog.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/ActionModalDialog.js +182 -0
- package/dist/react/schemaRenderer/action/ActionModalDialog.js.map +1 -0
- package/dist/react/schemaRenderer/action/ConfirmActionDialog.d.ts +17 -0
- package/dist/react/schemaRenderer/action/ConfirmActionDialog.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/ConfirmActionDialog.js +19 -0
- package/dist/react/schemaRenderer/action/ConfirmActionDialog.js.map +1 -0
- package/dist/react/schemaRenderer/action/HandlerActionButton.d.ts +16 -0
- package/dist/react/schemaRenderer/action/HandlerActionButton.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/HandlerActionButton.js +16 -0
- package/dist/react/schemaRenderer/action/HandlerActionButton.js.map +1 -0
- package/dist/react/schemaRenderer/action/MethodActionButton.d.ts +22 -0
- package/dist/react/schemaRenderer/action/MethodActionButton.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/MethodActionButton.js +26 -0
- package/dist/react/schemaRenderer/action/MethodActionButton.js.map +1 -0
- package/dist/react/schemaRenderer/action/buttons.d.ts +18 -0
- package/dist/react/schemaRenderer/action/buttons.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/buttons.js +74 -0
- package/dist/react/schemaRenderer/action/buttons.js.map +1 -0
- package/dist/react/schemaRenderer/action/helpers.d.ts +26 -0
- package/dist/react/schemaRenderer/action/helpers.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/helpers.js +126 -0
- package/dist/react/schemaRenderer/action/helpers.js.map +1 -0
- package/dist/react/schemaRenderer/action/renderAction.d.ts +21 -0
- package/dist/react/schemaRenderer/action/renderAction.d.ts.map +1 -0
- package/dist/react/schemaRenderer/action/renderAction.js +102 -0
- package/dist/react/schemaRenderer/action/renderAction.js.map +1 -0
- package/dist/react/schemaRenderer/columnFormat.d.ts +10 -0
- package/dist/react/schemaRenderer/columnFormat.d.ts.map +1 -0
- package/dist/react/schemaRenderer/columnFormat.js +76 -0
- package/dist/react/schemaRenderer/columnFormat.js.map +1 -0
- package/dist/react/schemaRenderer/constants.d.ts +8 -0
- package/dist/react/schemaRenderer/constants.d.ts.map +1 -0
- package/dist/react/schemaRenderer/constants.js +45 -0
- package/dist/react/schemaRenderer/constants.js.map +1 -0
- package/dist/react/schemaRenderer/form/FormRenderer.d.ts +29 -0
- package/dist/react/schemaRenderer/form/FormRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/form/FormRenderer.js +152 -0
- package/dist/react/schemaRenderer/form/FormRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/form/renderField.d.ts +6 -0
- package/dist/react/schemaRenderer/form/renderField.d.ts.map +1 -0
- package/dist/react/schemaRenderer/form/renderField.js +239 -0
- package/dist/react/schemaRenderer/form/renderField.js.map +1 -0
- package/dist/react/schemaRenderer/helpers.d.ts +32 -0
- package/dist/react/schemaRenderer/helpers.d.ts.map +1 -0
- package/dist/react/schemaRenderer/helpers.js +52 -0
- package/dist/react/schemaRenderer/helpers.js.map +1 -0
- package/dist/react/schemaRenderer/table/CardsLayoutBody.d.ts +60 -0
- package/dist/react/schemaRenderer/table/CardsLayoutBody.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/CardsLayoutBody.js +189 -0
- package/dist/react/schemaRenderer/table/CardsLayoutBody.js.map +1 -0
- package/dist/react/schemaRenderer/table/TableRenderer.d.ts +29 -0
- package/dist/react/schemaRenderer/table/TableRenderer.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/TableRenderer.js +85 -0
- package/dist/react/schemaRenderer/table/TableRenderer.js.map +1 -0
- package/dist/react/schemaRenderer/table/TableRendererBody.d.ts +18 -0
- package/dist/react/schemaRenderer/table/TableRendererBody.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/TableRendererBody.js +555 -0
- package/dist/react/schemaRenderer/table/TableRendererBody.js.map +1 -0
- package/dist/react/schemaRenderer/table/filters.d.ts +263 -0
- package/dist/react/schemaRenderer/table/filters.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/filters.js +497 -0
- package/dist/react/schemaRenderer/table/filters.js.map +1 -0
- package/dist/react/schemaRenderer/table/formatCell.d.ts +11 -0
- package/dist/react/schemaRenderer/table/formatCell.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/formatCell.js +172 -0
- package/dist/react/schemaRenderer/table/formatCell.js.map +1 -0
- package/dist/react/schemaRenderer/table/links.d.ts +42 -0
- package/dist/react/schemaRenderer/table/links.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/links.js +55 -0
- package/dist/react/schemaRenderer/table/links.js.map +1 -0
- package/dist/react/schemaRenderer/table/renderRowActions.d.ts +13 -0
- package/dist/react/schemaRenderer/table/renderRowActions.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/renderRowActions.js +25 -0
- package/dist/react/schemaRenderer/table/renderRowActions.js.map +1 -0
- package/dist/react/schemaRenderer/table/url.d.ts +41 -0
- package/dist/react/schemaRenderer/table/url.d.ts.map +1 -0
- package/dist/react/schemaRenderer/table/url.js +114 -0
- package/dist/react/schemaRenderer/table/url.js.map +1 -0
- package/dist/routes/globals.d.ts +13 -0
- package/dist/routes/globals.d.ts.map +1 -0
- package/dist/routes/globals.js +131 -0
- package/dist/routes/globals.js.map +1 -0
- package/dist/routes/helpers.d.ts +217 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +498 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/pages.d.ts +15 -0
- package/dist/routes/pages.d.ts.map +1 -0
- package/dist/routes/pages.js +145 -0
- package/dist/routes/pages.js.map +1 -0
- package/dist/routes/panel.d.ts +19 -0
- package/dist/routes/panel.d.ts.map +1 -0
- package/dist/routes/panel.js +191 -0
- package/dist/routes/panel.js.map +1 -0
- package/dist/routes/relations.d.ts +21 -0
- package/dist/routes/relations.d.ts.map +1 -0
- package/dist/routes/relations.js +1239 -0
- package/dist/routes/relations.js.map +1 -0
- package/dist/routes/resources.d.ts +28 -0
- package/dist/routes/resources.d.ts.map +1 -0
- package/dist/routes/resources.js +741 -0
- package/dist/routes/resources.js.map +1 -0
- package/dist/routes/theme.d.ts +12 -0
- package/dist/routes/theme.d.ts.map +1 -0
- package/dist/routes/theme.js +82 -0
- package/dist/routes/theme.js.map +1 -0
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +64 -3078
- package/dist/routes.js.map +1 -1
- package/dist/vite.d.ts +1 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +31 -10
- package/dist/vite.js.map +1 -1
- package/package.json +2 -1
- package/src/Pilotiq.ts +95 -0
- package/src/actions/Action.ts +79 -723
- package/src/actions/bulkFactories.ts +168 -0
- package/src/actions/crudFactories.ts +220 -0
- package/src/actions/factoryHelpers.ts +177 -0
- package/src/actions/m2mFactories.ts +193 -0
- package/src/actions/relationFactories.ts +372 -0
- package/src/elements/dispatchForm.ts +1 -1
- package/src/elements/dispatchTable.ts +1 -1
- package/src/fields/Field.ts +39 -0
- package/src/pageData/breadcrumbs.ts +288 -0
- package/src/pageData/forms.ts +578 -0
- package/src/pageData/helpers.ts +764 -0
- package/src/pageData/misc.ts +347 -0
- package/src/pageData/navigation.ts +779 -0
- package/src/pageData/relationPages.ts +1246 -0
- package/src/pageData/relationTabs.ts +286 -0
- package/src/pageData/resourcePages.ts +593 -0
- package/src/pageData.ts +122 -4731
- package/src/react/AppShell.tsx +27 -1
- package/src/react/CollabExtensionFactoryRegistry.ts +55 -0
- package/src/react/CollabRoomContext.ts +42 -0
- package/src/react/FormCollabBindingRegistry.ts +72 -0
- package/src/react/RecordWrapperGate.tsx +40 -0
- package/src/react/RecordWrapperRegistry.ts +39 -0
- package/src/react/SchemaRenderer.tsx +230 -6479
- package/src/react/component-slots.test.ts +103 -0
- package/src/react/component-slots.ts +116 -0
- package/src/react/fields/BuilderInput.tsx +29 -117
- package/src/react/fields/MarkdownInput.tsx +0 -1
- package/src/react/fields/RepeaterInput.tsx +29 -130
- package/src/react/fields/rowState.ts +106 -0
- package/src/react/fields/useRowReorderDnd.ts +78 -0
- package/src/react/index.ts +38 -0
- package/src/react/layouts/SidebarLayout.tsx +39 -28
- package/src/react/layouts/TopbarLayout.tsx +70 -57
- package/src/react/parseRecordEditUrl.test.ts +75 -0
- package/src/react/parseRecordEditUrl.ts +55 -0
- package/src/react/persistedState.ts +40 -0
- package/src/react/schemaRenderer/AlertRenderer.tsx +112 -0
- package/src/react/schemaRenderer/EntryRenderer.tsx +501 -0
- package/src/react/schemaRenderer/SectionRenderer.tsx +120 -0
- package/src/react/schemaRenderer/SimpleElements.tsx +306 -0
- package/src/react/schemaRenderer/TabsRenderer.tsx +62 -0
- package/src/react/schemaRenderer/WizardRenderer.tsx +338 -0
- package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +177 -0
- package/src/react/schemaRenderer/action/ActionModalDialog.tsx +273 -0
- package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +61 -0
- package/src/react/schemaRenderer/action/HandlerActionButton.tsx +43 -0
- package/src/react/schemaRenderer/action/MethodActionButton.tsx +64 -0
- package/src/react/schemaRenderer/action/buttons.tsx +99 -0
- package/src/react/schemaRenderer/action/helpers.ts +140 -0
- package/src/react/schemaRenderer/action/renderAction.tsx +245 -0
- package/src/react/schemaRenderer/columnFormat.ts +65 -0
- package/src/react/schemaRenderer/constants.ts +50 -0
- package/src/react/schemaRenderer/form/FormRenderer.tsx +233 -0
- package/src/react/schemaRenderer/form/renderField.tsx +511 -0
- package/src/react/schemaRenderer/helpers.tsx +81 -0
- package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +308 -0
- package/src/react/schemaRenderer/table/TableRenderer.tsx +123 -0
- package/src/react/schemaRenderer/table/TableRendererBody.tsx +974 -0
- package/src/react/schemaRenderer/table/filters.tsx +1233 -0
- package/src/react/schemaRenderer/table/formatCell.tsx +264 -0
- package/src/react/schemaRenderer/table/links.tsx +112 -0
- package/src/react/schemaRenderer/table/renderRowActions.tsx +52 -0
- package/src/react/schemaRenderer/table/url.tsx +143 -0
- package/src/routes/globals.ts +154 -0
- package/src/routes/helpers.ts +668 -0
- package/src/routes/pages.ts +173 -0
- package/src/routes/panel.ts +204 -0
- package/src/routes/relations.ts +1219 -0
- package/src/routes/resources.ts +786 -0
- package/src/routes/theme.ts +109 -0
- package/src/routes.test.ts +1 -1
- package/src/routes.ts +64 -3176
- package/src/schema/TableWidget.test.ts +2 -2
- package/src/theme/migrate.test.ts +178 -0
- package/src/vite.test.ts +184 -0
- package/src/vite.ts +31 -9
|
@@ -16,8 +16,8 @@ import type { ModelLike, ModelQuery } from '../orm/modelDefaults.js'
|
|
|
16
16
|
class StubQuery implements ModelQuery {
|
|
17
17
|
public readonly ops: Array<{ op: string; args: unknown[] }> = []
|
|
18
18
|
constructor(private readonly rows: unknown[], private readonly total = rows.length) {}
|
|
19
|
-
where(): this { this.ops.push({ op: 'where', args
|
|
20
|
-
orWhere(): this { this.ops.push({ op: 'orWhere', args
|
|
19
|
+
where(...args: unknown[]): this { this.ops.push({ op: 'where', args }); return this }
|
|
20
|
+
orWhere(...args: unknown[]): this { this.ops.push({ op: 'orWhere', args }); return this }
|
|
21
21
|
orderBy(column: string, direction?: 'ASC' | 'DESC'): this {
|
|
22
22
|
this.ops.push({ op: 'orderBy', args: [column, direction] })
|
|
23
23
|
return this
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { migrateThemeOverrides } from './migrate.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `migrateThemeOverrides` reads legacy `panelGlobal` rows on every theme
|
|
7
|
+
* GET. It runs against rows persisted before the schema renames landed
|
|
8
|
+
* (accentColor→themeColor, chartPalette→chartColor, preset 'default'
|
|
9
|
+
* gone, baseColor sentinels dropped). A silent regression here corrupts
|
|
10
|
+
* user themes on the next page load — covering it with unit tests is
|
|
11
|
+
* cheap and the matrix is small.
|
|
12
|
+
*/
|
|
13
|
+
describe('migrateThemeOverrides — non-object input', () => {
|
|
14
|
+
for (const bad of [null, undefined, 0, 'string', true, false] as const) {
|
|
15
|
+
it(`returns {} for ${JSON.stringify(bad)}`, () => {
|
|
16
|
+
assert.deepEqual(migrateThemeOverrides(bad), {})
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Arrays are objects in JS but the function uses them via the same
|
|
21
|
+
// key-walk; nothing should match → empty result.
|
|
22
|
+
it('returns {} for an array', () => {
|
|
23
|
+
assert.deepEqual(migrateThemeOverrides([1, 2, 3]), {})
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('migrateThemeOverrides — preset rename', () => {
|
|
28
|
+
it("maps the legacy 'default' preset to 'vega'", () => {
|
|
29
|
+
assert.deepEqual(migrateThemeOverrides({ preset: 'default' }), { preset: 'vega' })
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('passes other preset names through unchanged', () => {
|
|
33
|
+
for (const preset of ['nova', 'maia', 'lyra', 'vega'] as const) {
|
|
34
|
+
assert.deepEqual(migrateThemeOverrides({ preset }), { preset })
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('ignores non-string preset values', () => {
|
|
39
|
+
assert.deepEqual(migrateThemeOverrides({ preset: 42 }), {})
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
describe('migrateThemeOverrides — baseColor mapping', () => {
|
|
44
|
+
it("maps 'slate' to 'mist'", () => {
|
|
45
|
+
assert.deepEqual(migrateThemeOverrides({ baseColor: 'slate' }), { baseColor: 'mist' })
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("drops 'cream' (Vega's bg already supplies it)", () => {
|
|
49
|
+
assert.deepEqual(migrateThemeOverrides({ baseColor: 'cream' }), {})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("drops 'default' (sentinel; no override)", () => {
|
|
53
|
+
assert.deepEqual(migrateThemeOverrides({ baseColor: 'default' }), {})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('passes other baseColor values through unchanged', () => {
|
|
57
|
+
assert.deepEqual(migrateThemeOverrides({ baseColor: 'mist' }), { baseColor: 'mist' })
|
|
58
|
+
assert.deepEqual(migrateThemeOverrides({ baseColor: 'taupe' }), { baseColor: 'taupe' })
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe('migrateThemeOverrides — accentColor → themeColor', () => {
|
|
63
|
+
it("'terracotta' becomes 'base' when paired with preset=vega", () => {
|
|
64
|
+
const out = migrateThemeOverrides({ preset: 'default', accentColor: 'terracotta' })
|
|
65
|
+
// preset: 'default' migrates to 'vega' first; the terracotta branch
|
|
66
|
+
// reads the *migrated* preset, so the Vega-specific 'base' wins.
|
|
67
|
+
assert.deepEqual(out, { preset: 'vega', themeColor: 'base' })
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it("'terracotta' falls back to 'orange' when preset is not vega", () => {
|
|
71
|
+
const out = migrateThemeOverrides({ preset: 'nova', accentColor: 'terracotta' })
|
|
72
|
+
assert.deepEqual(out, { preset: 'nova', themeColor: 'orange' })
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it("'terracotta' alone (no preset) falls back to 'orange'", () => {
|
|
76
|
+
const out = migrateThemeOverrides({ accentColor: 'terracotta' })
|
|
77
|
+
assert.deepEqual(out, { themeColor: 'orange' })
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('passes other accentColor names through as themeColor', () => {
|
|
81
|
+
assert.deepEqual(migrateThemeOverrides({ accentColor: 'blue' }), { themeColor: 'blue' })
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('explicit themeColor wins over legacy accentColor', () => {
|
|
85
|
+
const out = migrateThemeOverrides({ accentColor: 'blue', themeColor: 'red' })
|
|
86
|
+
assert.deepEqual(out, { themeColor: 'red' })
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('migrateThemeOverrides — chartPalette → chartColor', () => {
|
|
91
|
+
const map: Record<string, string> = {
|
|
92
|
+
ocean: 'sky',
|
|
93
|
+
sunset: 'orange',
|
|
94
|
+
forest: 'emerald',
|
|
95
|
+
berry: 'fuchsia',
|
|
96
|
+
terracotta: 'base',
|
|
97
|
+
default: 'base',
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const [from, to] of Object.entries(map)) {
|
|
101
|
+
it(`maps chartPalette '${from}' to chartColor '${to}'`, () => {
|
|
102
|
+
assert.deepEqual(migrateThemeOverrides({ chartPalette: from }), { chartColor: to })
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
it('passes unmapped chartPalette names through as chartColor', () => {
|
|
107
|
+
assert.deepEqual(migrateThemeOverrides({ chartPalette: 'blue' }), { chartColor: 'blue' })
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('explicit chartColor wins over legacy chartPalette', () => {
|
|
111
|
+
const out = migrateThemeOverrides({ chartPalette: 'ocean', chartColor: 'red' })
|
|
112
|
+
assert.deepEqual(out, { chartColor: 'red' })
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('migrateThemeOverrides — pass-through fields', () => {
|
|
117
|
+
it('forwards radius, iconLibrary, fonts, and cssVariables when shapes match', () => {
|
|
118
|
+
const fonts = { heading: 'Space Grotesk', body: 'Inter' }
|
|
119
|
+
const cssVariables = { '--custom-x': 'oklch(0.5 0.1 100)' }
|
|
120
|
+
const out = migrateThemeOverrides({
|
|
121
|
+
radius: 'large',
|
|
122
|
+
iconLibrary: 'tabler',
|
|
123
|
+
fonts,
|
|
124
|
+
cssVariables,
|
|
125
|
+
})
|
|
126
|
+
assert.deepEqual(out, {
|
|
127
|
+
radius: 'large',
|
|
128
|
+
iconLibrary: 'tabler',
|
|
129
|
+
fonts,
|
|
130
|
+
cssVariables,
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('drops radius/iconLibrary when they are not strings', () => {
|
|
135
|
+
const out = migrateThemeOverrides({ radius: 42, iconLibrary: null })
|
|
136
|
+
assert.deepEqual(out, {})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('drops fonts/cssVariables when they are not objects', () => {
|
|
140
|
+
const out = migrateThemeOverrides({ fonts: 'Inter', cssVariables: 'bad' })
|
|
141
|
+
assert.deepEqual(out, {})
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
describe('migrateThemeOverrides — composite migration', () => {
|
|
146
|
+
it('migrates a realistic pre-rename payload end-to-end', () => {
|
|
147
|
+
const legacy = {
|
|
148
|
+
preset: 'default',
|
|
149
|
+
baseColor: 'slate',
|
|
150
|
+
accentColor: 'terracotta',
|
|
151
|
+
chartPalette: 'ocean',
|
|
152
|
+
radius: 'medium',
|
|
153
|
+
iconLibrary: 'lucide',
|
|
154
|
+
fonts: { heading: 'Satoshi' },
|
|
155
|
+
}
|
|
156
|
+
const out = migrateThemeOverrides(legacy)
|
|
157
|
+
assert.deepEqual(out, {
|
|
158
|
+
preset: 'vega',
|
|
159
|
+
baseColor: 'mist',
|
|
160
|
+
themeColor: 'base', // terracotta + preset=vega
|
|
161
|
+
chartColor: 'sky', // ocean → sky
|
|
162
|
+
radius: 'medium',
|
|
163
|
+
iconLibrary: 'lucide',
|
|
164
|
+
fonts: { heading: 'Satoshi' },
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('a clean already-migrated payload is preserved', () => {
|
|
169
|
+
const current = {
|
|
170
|
+
preset: 'vega',
|
|
171
|
+
baseColor: 'mist',
|
|
172
|
+
themeColor: 'blue',
|
|
173
|
+
chartColor: 'sky',
|
|
174
|
+
radius: 'small',
|
|
175
|
+
}
|
|
176
|
+
assert.deepEqual(migrateThemeOverrides(current), current)
|
|
177
|
+
})
|
|
178
|
+
})
|
package/src/vite.test.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { describe, it, before, after } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import os from 'node:os'
|
|
6
|
+
import { generatePages } from './vite.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Regression test for the Vite plugin's generated Vike stubs. The
|
|
10
|
+
* stubs are emitted at construction time (before Vike scans `pages/`)
|
|
11
|
+
* and they are the integration boundary between RudderJS routing and
|
|
12
|
+
* Vike's file-based router — getting them wrong silently breaks SPA
|
|
13
|
+
* navigation. We assert the file tree + critical content invariants
|
|
14
|
+
* rather than a raw text snapshot so cosmetic edits don't churn the
|
|
15
|
+
* test, but functional regressions (a dropped guard, a missing route
|
|
16
|
+
* dir, a non-null assertion lost on a route param) still fail loudly.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
let tmpRoot: string
|
|
20
|
+
|
|
21
|
+
before(() => {
|
|
22
|
+
tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'pilotiq-vite-test-'))
|
|
23
|
+
generatePages(tmpRoot)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
after(() => {
|
|
27
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true })
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const outDir = (): string => path.join(tmpRoot, '(pilotiq)')
|
|
31
|
+
const read = (p: string): string => fs.readFileSync(path.join(outDir(), p), 'utf8')
|
|
32
|
+
|
|
33
|
+
describe('generatePages — file tree', () => {
|
|
34
|
+
const expectedRouteDirs = [
|
|
35
|
+
'dashboard',
|
|
36
|
+
'slug',
|
|
37
|
+
'resource-create',
|
|
38
|
+
'resource-edit',
|
|
39
|
+
'resource-view',
|
|
40
|
+
'relation-list',
|
|
41
|
+
'relation-create',
|
|
42
|
+
'relation-view',
|
|
43
|
+
'relation-edit',
|
|
44
|
+
'nested-relation-list',
|
|
45
|
+
'nested-relation-create',
|
|
46
|
+
'nested-relation-view',
|
|
47
|
+
'nested-relation-edit',
|
|
48
|
+
'theme',
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
it('emits the (pilotiq) directory with all expected route dirs', () => {
|
|
52
|
+
assert.ok(fs.existsSync(outDir()), '(pilotiq) directory should be created')
|
|
53
|
+
for (const dir of expectedRouteDirs) {
|
|
54
|
+
assert.ok(
|
|
55
|
+
fs.existsSync(path.join(outDir(), dir)),
|
|
56
|
+
`route directory "${dir}" should exist`,
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('emits shared files at the (pilotiq) root', () => {
|
|
62
|
+
for (const file of ['+config.ts', '+Head.tsx']) {
|
|
63
|
+
assert.ok(
|
|
64
|
+
fs.existsSync(path.join(outDir(), file)),
|
|
65
|
+
`shared file "${file}" should exist`,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('every route dir has +route.ts, +data.ts, and +Page.tsx', () => {
|
|
71
|
+
// resource-create + resource-edit don't get their own +Page.tsx
|
|
72
|
+
// line in the source — they share `formPage`. The file must still
|
|
73
|
+
// be emitted (writeIfChanged is called for each). Same for nested.
|
|
74
|
+
for (const dir of expectedRouteDirs) {
|
|
75
|
+
for (const file of ['+route.ts', '+data.ts', '+Page.tsx']) {
|
|
76
|
+
assert.ok(
|
|
77
|
+
fs.existsSync(path.join(outDir(), dir, file)),
|
|
78
|
+
`${dir}/${file} should exist`,
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
describe('generatePages — route stubs', () => {
|
|
86
|
+
it('+route.ts files declare RouteSync and check the registry on SSR', () => {
|
|
87
|
+
for (const dir of ['dashboard', 'slug', 'resource-create', 'resource-edit', 'theme']) {
|
|
88
|
+
const src = read(`${dir}/+route.ts`)
|
|
89
|
+
assert.match(src, /import type { RouteSync } from 'vike\/types'/, `${dir}: RouteSync import`)
|
|
90
|
+
assert.match(src, /PilotiqRegistry/, `${dir}: registry import`)
|
|
91
|
+
assert.match(src, /export const route: RouteSync/, `${dir}: route export`)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('non-theme routes guard the registry lookup behind import.meta.env.SSR', () => {
|
|
96
|
+
// Theme route runs the registry check unconditionally because it
|
|
97
|
+
// also needs to verify the themeEditor flag — exempting it keeps
|
|
98
|
+
// the rest of the assertion strict.
|
|
99
|
+
for (const dir of ['dashboard', 'slug', 'resource-create', 'resource-edit']) {
|
|
100
|
+
const src = read(`${dir}/+route.ts`)
|
|
101
|
+
assert.match(
|
|
102
|
+
src,
|
|
103
|
+
/if \(import\.meta\.env\.SSR && !PilotiqRegistry\.findByPath/,
|
|
104
|
+
`${dir}: SSR-guarded registry check`,
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('routeParams use non-null assertion on parts[0] (basePath)', () => {
|
|
110
|
+
// Regression guard for f18898f / 229f290 — without the `!`,
|
|
111
|
+
// noUncheckedIndexedAccess flags `string | undefined` in user
|
|
112
|
+
// typecheck and the playground fails to compile.
|
|
113
|
+
for (const dir of ['dashboard', 'slug', 'resource-create', 'resource-edit', 'theme']) {
|
|
114
|
+
const src = read(`${dir}/+route.ts`)
|
|
115
|
+
assert.match(src, /basePath:\s*parts\[0\]!/, `${dir}: parts[0]! basePath`)
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('slug route rejects the "theme" segment to avoid clobbering the theme editor', () => {
|
|
120
|
+
const src = read('slug/+route.ts')
|
|
121
|
+
assert.match(src, /parts\[1 \+ off\] === 'theme'/)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('resource-view yields to create + theme on the same depth', () => {
|
|
125
|
+
const src = read('resource-view/+route.ts')
|
|
126
|
+
assert.match(src, /parts\[2 \+ off\] === 'create'/)
|
|
127
|
+
assert.match(src, /parts\[1 \+ off\] === 'theme'/)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('all non-dashboard routes import clusterOffset for cluster-prefix support', () => {
|
|
131
|
+
// dashboard is single-segment — no cluster prefix possible.
|
|
132
|
+
// theme is exactly 2 segments under the panel base — also unprefixed.
|
|
133
|
+
for (const dir of ['slug', 'resource-create', 'resource-edit', 'resource-view', 'relation-list']) {
|
|
134
|
+
const src = read(`${dir}/+route.ts`)
|
|
135
|
+
assert.match(src, /import { clusterOffset } from '\.\.\/_clusterOffset\.js'/, `${dir}: clusterOffset import`)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe('generatePages — page stubs', () => {
|
|
141
|
+
it('+Page.tsx renders via SchemaRenderer with passToClient props', () => {
|
|
142
|
+
for (const dir of ['slug', 'resource-create', 'resource-edit', 'resource-view', 'relation-list']) {
|
|
143
|
+
const src = read(`${dir}/+Page.tsx`)
|
|
144
|
+
assert.match(src, /import { SchemaRenderer } from '@pilotiq\/pilotiq\/react'/, `${dir}: SchemaRenderer import`)
|
|
145
|
+
assert.match(src, /usePageContext/, `${dir}: usePageContext import`)
|
|
146
|
+
assert.match(src, /ctx\.data \?\? ctx\.viewProps/, `${dir}: data/viewProps fallback`)
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('+config.ts forwards viewProps + data to the client', () => {
|
|
151
|
+
const src = read('+config.ts')
|
|
152
|
+
assert.match(src, /passToClient:\s*\['viewProps',\s*'data'\]/)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('+data.ts (shared stub) prefers server-set viewProps over running dispatchPageData', () => {
|
|
156
|
+
// The data stub is identical across every route dir — sample one.
|
|
157
|
+
const src = read('slug/+data.ts')
|
|
158
|
+
assert.match(src, /if \(viewProps !== undefined\) return viewProps/)
|
|
159
|
+
assert.match(src, /import { dispatchPageData } from '@pilotiq\/pilotiq'/)
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
describe('generatePages — Head + theme', () => {
|
|
164
|
+
it('+Head.tsx injects the FOUC-prevention script before React hydrates', () => {
|
|
165
|
+
const src = read('+Head.tsx')
|
|
166
|
+
assert.match(src, /pilotiq-theme/, 'localStorage key for theme persistence')
|
|
167
|
+
assert.match(src, /prefers-color-scheme:dark/, 'system-preference fallback')
|
|
168
|
+
assert.match(src, /classList\.add\('dark'\)/, 'dark class application')
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('theme route checks the themeEditor config flag', () => {
|
|
172
|
+
const src = read('theme/+route.ts')
|
|
173
|
+
assert.match(src, /panel\.getConfig\(\)\.themeEditor/)
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('generatePages — idempotency', () => {
|
|
178
|
+
it('re-running on the same dir does not throw and keeps file contents stable', () => {
|
|
179
|
+
const before = read('dashboard/+route.ts')
|
|
180
|
+
generatePages(tmpRoot)
|
|
181
|
+
const after = read('dashboard/+route.ts')
|
|
182
|
+
assert.equal(before, after)
|
|
183
|
+
})
|
|
184
|
+
})
|
package/src/vite.ts
CHANGED
|
@@ -43,7 +43,7 @@ function writeIfChanged(filePath: string, contents: string): void {
|
|
|
43
43
|
fs.writeFileSync(filePath, contents)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function generatePages(pagesRoot: string): void {
|
|
46
|
+
export function generatePages(pagesRoot: string): void {
|
|
47
47
|
const outDir = path.join(pagesRoot, '(pilotiq)')
|
|
48
48
|
|
|
49
49
|
// Shared config
|
|
@@ -390,7 +390,7 @@ export const route: RouteSync = (pageContext) => {
|
|
|
390
390
|
if (parts[5 + off] === 'edit') return false
|
|
391
391
|
if (import.meta.env.SSR && !PilotiqRegistry.findByPath('/' + parts[0])) return false
|
|
392
392
|
return { routeParams: {
|
|
393
|
-
basePath: parts[0]
|
|
393
|
+
basePath: parts[0]!,
|
|
394
394
|
slug: parts[1 + off]!,
|
|
395
395
|
id: parts[2 + off]!,
|
|
396
396
|
relationship: parts[3 + off]!,
|
|
@@ -413,7 +413,7 @@ export const route: RouteSync = (pageContext) => {
|
|
|
413
413
|
if (parts.length !== 7 + off || parts[6 + off] !== 'create') return false
|
|
414
414
|
if (import.meta.env.SSR && !PilotiqRegistry.findByPath('/' + parts[0])) return false
|
|
415
415
|
return { routeParams: {
|
|
416
|
-
basePath: parts[0]
|
|
416
|
+
basePath: parts[0]!,
|
|
417
417
|
slug: parts[1 + off]!,
|
|
418
418
|
id: parts[2 + off]!,
|
|
419
419
|
relationship: parts[3 + off]!,
|
|
@@ -437,7 +437,7 @@ export const route: RouteSync = (pageContext) => {
|
|
|
437
437
|
if (parts[6 + off] === 'create') return false
|
|
438
438
|
if (import.meta.env.SSR && !PilotiqRegistry.findByPath('/' + parts[0])) return false
|
|
439
439
|
return { routeParams: {
|
|
440
|
-
basePath: parts[0]
|
|
440
|
+
basePath: parts[0]!,
|
|
441
441
|
slug: parts[1 + off]!,
|
|
442
442
|
id: parts[2 + off]!,
|
|
443
443
|
relationship: parts[3 + off]!,
|
|
@@ -461,7 +461,7 @@ export const route: RouteSync = (pageContext) => {
|
|
|
461
461
|
if (parts.length !== 8 + off || parts[7 + off] !== 'edit') return false
|
|
462
462
|
if (import.meta.env.SSR && !PilotiqRegistry.findByPath('/' + parts[0])) return false
|
|
463
463
|
return { routeParams: {
|
|
464
|
-
basePath: parts[0]
|
|
464
|
+
basePath: parts[0]!,
|
|
465
465
|
slug: parts[1 + off]!,
|
|
466
466
|
id: parts[2 + off]!,
|
|
467
467
|
relationship: parts[3 + off]!,
|
|
@@ -538,7 +538,18 @@ async function discoverPanelExports(
|
|
|
538
538
|
// jiti gives us a Node-compatible loader that handles .ts/.tsx, ESM,
|
|
539
539
|
// and TypeScript syntax. `fsCache: false` + a fresh instance per
|
|
540
540
|
// call ensures HMR-style regeneration picks up edits.
|
|
541
|
-
|
|
541
|
+
//
|
|
542
|
+
// `jsx: true` enables `@babel/plugin-transform-react-jsx` so panel
|
|
543
|
+
// modules can import `.tsx` files directly (e.g. a custom nav
|
|
544
|
+
// component registered via `Pilotiq.components({ nav })`). Default
|
|
545
|
+
// automatic runtime — matches what the playground's tsconfig assumes
|
|
546
|
+
// (`"jsx": "react-jsx"`) so authors don't need to manually import
|
|
547
|
+
// React in every component.
|
|
548
|
+
const jiti = createJiti(projectRoot, {
|
|
549
|
+
fsCache: false,
|
|
550
|
+
moduleCache: false,
|
|
551
|
+
jsx: { runtime: 'automatic' },
|
|
552
|
+
})
|
|
542
553
|
const out: PanelExport[] = []
|
|
543
554
|
for (const userPath of panelPaths) {
|
|
544
555
|
const resolved = await resolvePanelPath(userPath, projectRoot)
|
|
@@ -553,6 +564,7 @@ async function discoverPanelExports(
|
|
|
553
564
|
throw new Error(
|
|
554
565
|
`[pilotiq vite plugin] Failed to import panel module "${userPath}" (resolved to "${resolved}"): ${msg}\n` +
|
|
555
566
|
`Panel files must be import-safe — top-level code must not run server-only logic.`,
|
|
567
|
+
{ cause: err },
|
|
556
568
|
)
|
|
557
569
|
}
|
|
558
570
|
}
|
|
@@ -592,7 +604,7 @@ import { clusterSlugsByBasePath } from './_components.js'
|
|
|
592
604
|
export function clusterOffset(parts: string[]): number {
|
|
593
605
|
if (parts.length < 2) return 0
|
|
594
606
|
const slugs = clusterSlugsByBasePath['/' + parts[0]]
|
|
595
|
-
return slugs && slugs.includes(parts[1]) ? 1 : 0
|
|
607
|
+
return slugs && slugs.includes(parts[1]!) ? 1 : 0
|
|
596
608
|
}
|
|
597
609
|
`)
|
|
598
610
|
|
|
@@ -609,6 +621,8 @@ export function clusterOffset(parts: string[]): number {
|
|
|
609
621
|
lines.push('export const componentRegistry: Record<string, unknown> = {}')
|
|
610
622
|
lines.push('export const clusterSlugsByBasePath: Record<string, string[]> = {}')
|
|
611
623
|
lines.push('export const rightPanelRegistry: Record<string, unknown> = {}')
|
|
624
|
+
lines.push('export const layoutProviderRegistry: unknown[] = []')
|
|
625
|
+
lines.push('export const componentSlotRegistry: Record<string, unknown> = {}')
|
|
612
626
|
lines.push('')
|
|
613
627
|
writeIfChanged(path.join(outDir, '_components.ts'), lines.join('\n'))
|
|
614
628
|
return
|
|
@@ -633,6 +647,7 @@ export function clusterOffset(parts: string[]): number {
|
|
|
633
647
|
lines.push('const _clusters: Record<string, string[]> = {}')
|
|
634
648
|
lines.push('const _rightPanels: Record<string, unknown> = {}')
|
|
635
649
|
lines.push('const _layoutProviders: unknown[] = []')
|
|
650
|
+
lines.push('const _slots: Record<string, unknown> = {}')
|
|
636
651
|
lines.push('function _add(c: any) { if (typeof c === \'function\' && c.name) _all[c.name] = c }')
|
|
637
652
|
lines.push('function _walk(p: any) {')
|
|
638
653
|
lines.push(' const cfg = p?.getConfig?.()')
|
|
@@ -649,6 +664,12 @@ export function clusterOffset(parts: string[]): number {
|
|
|
649
664
|
lines.push(' if (typeof _C === \'function\') _layoutProviders.push(_C)')
|
|
650
665
|
lines.push(' }')
|
|
651
666
|
lines.push(' }')
|
|
667
|
+
lines.push(' if (cfg?.components && typeof cfg.components === \'object\') {')
|
|
668
|
+
lines.push(' for (const _k of Object.keys(cfg.components)) {')
|
|
669
|
+
lines.push(' const _v = cfg.components[_k]')
|
|
670
|
+
lines.push(' if (typeof _v === \'function\' || (typeof _v === \'object\' && _v !== null)) _slots[_k] = _v')
|
|
671
|
+
lines.push(' }')
|
|
672
|
+
lines.push(' }')
|
|
652
673
|
lines.push(' if (cfg?.path && Array.isArray(cfg?.clusters)) {')
|
|
653
674
|
lines.push(' const slugs = cfg.clusters.map((C: any) => (typeof C?.getSlug === \'function\' ? C.getSlug() : \'\')).filter(Boolean)')
|
|
654
675
|
lines.push(' if (slugs.length > 0) _clusters[cfg.path] = slugs')
|
|
@@ -660,6 +681,7 @@ export function clusterOffset(parts: string[]): number {
|
|
|
660
681
|
lines.push('export const clusterSlugsByBasePath: Record<string, string[]> = _clusters')
|
|
661
682
|
lines.push('export const rightPanelRegistry: Record<string, unknown> = _rightPanels')
|
|
662
683
|
lines.push('export const layoutProviderRegistry: unknown[] = _layoutProviders')
|
|
684
|
+
lines.push('export const componentSlotRegistry: Record<string, unknown> = _slots')
|
|
663
685
|
lines.push('')
|
|
664
686
|
|
|
665
687
|
writeIfChanged(path.join(outDir, '_components.ts'), lines.join('\n'))
|
|
@@ -675,7 +697,7 @@ function writeLayoutWithManifest(pagesRoot: string): void {
|
|
|
675
697
|
import { usePageContext } from 'vike-react/usePageContext'
|
|
676
698
|
import { AppShell, ThemeProvider, generateThemeCSS, NavigateProvider } from '@pilotiq/pilotiq/react'
|
|
677
699
|
import { navigate as vikeNavigate } from 'vike/client/router'
|
|
678
|
-
import { componentRegistry, rightPanelRegistry, layoutProviderRegistry } from './_components.js'
|
|
700
|
+
import { componentRegistry, rightPanelRegistry, layoutProviderRegistry, componentSlotRegistry } from './_components.js'
|
|
679
701
|
import type { ReactNode } from 'react'
|
|
680
702
|
|
|
681
703
|
// Wrap vike's async navigate so the NavigateProvider's fire-and-forget
|
|
@@ -698,7 +720,7 @@ export default function PilotiqLayout({ children }: { children: ReactNode }) {
|
|
|
698
720
|
<NavigateProvider navigate={navigate}>
|
|
699
721
|
<ThemeProvider theme={panel.theme}>
|
|
700
722
|
{themeCss && <style dangerouslySetInnerHTML={{ __html: themeCss }} />}
|
|
701
|
-
<AppShell panel={panel} basePath={basePath} layout={layout} notifications={notifications} currentPath={currentPath} componentRegistry={componentRegistry as any} rightPanelRegistry={rightPanelRegistry as any} layoutProviderRegistry={layoutProviderRegistry as any}>
|
|
723
|
+
<AppShell panel={panel} basePath={basePath} layout={layout} notifications={notifications} currentPath={currentPath ?? ''} componentRegistry={componentRegistry as any} rightPanelRegistry={rightPanelRegistry as any} layoutProviderRegistry={layoutProviderRegistry as any} componentSlotRegistry={componentSlotRegistry as any}>
|
|
702
724
|
{children}
|
|
703
725
|
</AppShell>
|
|
704
726
|
</ThemeProvider>
|