@kywi-software/core 0.13.0 → 0.15.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/AGENT-PATTERNS.md +153 -17
- package/README.md +38 -12
- package/dist/admin/chrome.d.ts.map +1 -1
- package/dist/admin/chrome.js +57 -8
- package/dist/admin/chrome.js.map +1 -1
- package/dist/admin/field-components.d.ts.map +1 -1
- package/dist/admin/field-components.js +27 -1
- package/dist/admin/field-components.js.map +1 -1
- package/dist/admin/form-helpers.d.ts.map +1 -1
- package/dist/admin/form-helpers.js +6 -1
- package/dist/admin/form-helpers.js.map +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/layout-editor/chrome-env.d.ts +35 -0
- package/dist/admin/layout-editor/chrome-env.d.ts.map +1 -0
- package/dist/admin/layout-editor/chrome-env.js +13 -0
- package/dist/admin/layout-editor/chrome-env.js.map +1 -0
- package/dist/admin/layout-editor/component-actions.d.ts +58 -7
- package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-actions.js +131 -5
- package/dist/admin/layout-editor/component-actions.js.map +1 -1
- package/dist/admin/layout-editor/component-fork.d.ts +4 -4
- package/dist/admin/layout-editor/component-fork.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-fork.js +76 -10
- package/dist/admin/layout-editor/component-fork.js.map +1 -1
- package/dist/admin/layout-editor/component-picker-field.d.ts +17 -3
- package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-picker-field.js +5 -2
- package/dist/admin/layout-editor/component-picker-field.js.map +1 -1
- package/dist/admin/layout-editor/drag-feedback.d.ts +25 -1
- package/dist/admin/layout-editor/drag-feedback.d.ts.map +1 -1
- package/dist/admin/layout-editor/drag-feedback.js +9 -0
- package/dist/admin/layout-editor/drag-feedback.js.map +1 -1
- package/dist/admin/layout-editor/drag-utils.d.ts +103 -5
- package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
- package/dist/admin/layout-editor/drag-utils.js +131 -4
- package/dist/admin/layout-editor/drag-utils.js.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.d.ts +11 -0
- package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.js +134 -20
- package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
- package/dist/admin/layout-editor/editor-dialog.d.ts +58 -3
- package/dist/admin/layout-editor/editor-dialog.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-dialog.js +71 -9
- package/dist/admin/layout-editor/editor-dialog.js.map +1 -1
- package/dist/admin/layout-editor/editor-state.d.ts +119 -0
- package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-state.js +188 -6
- package/dist/admin/layout-editor/editor-state.js.map +1 -1
- package/dist/admin/layout-editor/editor-toolbar.d.ts +10 -1
- package/dist/admin/layout-editor/editor-toolbar.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-toolbar.js +2 -2
- package/dist/admin/layout-editor/editor-toolbar.js.map +1 -1
- package/dist/admin/layout-editor/editor.css +216 -8
- package/dist/admin/layout-editor/inline-text.d.ts +15 -1
- package/dist/admin/layout-editor/inline-text.d.ts.map +1 -1
- package/dist/admin/layout-editor/inline-text.js +30 -2
- package/dist/admin/layout-editor/inline-text.js.map +1 -1
- package/dist/admin/layout-editor/layout-editor.d.ts +21 -16
- package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/layout-editor.js +40 -17
- package/dist/admin/layout-editor/layout-editor.js.map +1 -1
- package/dist/admin/layout-editor/linked-component-notes.d.ts +88 -0
- package/dist/admin/layout-editor/linked-component-notes.d.ts.map +1 -0
- package/dist/admin/layout-editor/linked-component-notes.js +88 -0
- package/dist/admin/layout-editor/linked-component-notes.js.map +1 -0
- package/dist/admin/layout-editor/module-overlay.d.ts +23 -4
- package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-overlay.js +56 -10
- package/dist/admin/layout-editor/module-overlay.js.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-config.js +9 -2
- package/dist/admin/layout-editor/module-variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/module-variant-container-panel.d.ts +75 -0
- package/dist/admin/layout-editor/module-variant-container-panel.d.ts.map +1 -0
- package/dist/admin/layout-editor/module-variant-container-panel.js +29 -0
- package/dist/admin/layout-editor/module-variant-container-panel.js.map +1 -0
- package/dist/admin/layout-editor/node-lookup.d.ts.map +1 -1
- package/dist/admin/layout-editor/node-lookup.js +33 -3
- package/dist/admin/layout-editor/node-lookup.js.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.d.ts.map +1 -1
- package/dist/admin/layout-editor/overlay-shell.js +19 -4
- package/dist/admin/layout-editor/overlay-shell.js.map +1 -1
- package/dist/admin/layout-editor/props-panel.d.ts +28 -11
- package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
- package/dist/admin/layout-editor/props-panel.js +75 -125
- package/dist/admin/layout-editor/props-panel.js.map +1 -1
- package/dist/admin/layout-editor/section-variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-variant-container-config.js +11 -2
- package/dist/admin/layout-editor/section-variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/use-chrome-flip.d.ts +99 -11
- package/dist/admin/layout-editor/use-chrome-flip.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-chrome-flip.js +268 -97
- package/dist/admin/layout-editor/use-chrome-flip.js.map +1 -1
- package/dist/admin/layout-editor/use-component-connect.d.ts +13 -0
- package/dist/admin/layout-editor/use-component-connect.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-connect.js +116 -20
- package/dist/admin/layout-editor/use-component-connect.js.map +1 -1
- package/dist/admin/layout-editor/use-component-fork.d.ts +49 -19
- package/dist/admin/layout-editor/use-component-fork.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-fork.js +28 -19
- package/dist/admin/layout-editor/use-component-fork.js.map +1 -1
- package/dist/admin/layout-editor/use-component-library.d.ts +4 -4
- package/dist/admin/layout-editor/use-component-library.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-component-library.js +1 -1
- package/dist/admin/layout-editor/use-component-library.js.map +1 -1
- package/dist/admin/layout-editor/use-editor-dnd.d.ts +10 -0
- package/dist/admin/layout-editor/use-editor-dnd.d.ts.map +1 -1
- package/dist/admin/layout-editor/use-editor-dnd.js +234 -14
- package/dist/admin/layout-editor/use-editor-dnd.js.map +1 -1
- package/dist/admin/layout-editor/variant-container-config.d.ts.map +1 -1
- package/dist/admin/layout-editor/variant-container-config.js +1 -1
- package/dist/admin/layout-editor/variant-container-config.js.map +1 -1
- package/dist/admin/layout-editor/variant-editor.d.ts +16 -15
- package/dist/admin/layout-editor/variant-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/variant-editor.js +16 -5
- package/dist/admin/layout-editor/variant-editor.js.map +1 -1
- package/dist/admin/primitives.d.ts.map +1 -1
- package/dist/admin/primitives.js +1 -1
- package/dist/admin/primitives.js.map +1 -1
- package/dist/admin/registry.d.ts +24 -2
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +27 -0
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/server.d.ts +10 -1
- package/dist/admin/server.d.ts.map +1 -1
- package/dist/admin/server.js +4 -1
- package/dist/admin/server.js.map +1 -1
- package/dist/admin/site-switcher.d.ts +16 -3
- package/dist/admin/site-switcher.d.ts.map +1 -1
- package/dist/admin/site-switcher.js +18 -3
- package/dist/admin/site-switcher.js.map +1 -1
- package/dist/admin/styles/admin.css +0 -3
- package/dist/admin/surface-matcher.d.ts +6 -2
- package/dist/admin/surface-matcher.d.ts.map +1 -1
- package/dist/admin/surface-matcher.js +42 -5
- package/dist/admin/surface-matcher.js.map +1 -1
- package/dist/admin/surfaces/account/account-password.d.ts +3 -0
- package/dist/admin/surfaces/account/account-password.d.ts.map +1 -0
- package/dist/admin/surfaces/account/account-password.js +58 -0
- package/dist/admin/surfaces/account/account-password.js.map +1 -0
- package/dist/admin/surfaces/components/components-data.d.ts +31 -11
- package/dist/admin/surfaces/components/components-data.d.ts.map +1 -1
- package/dist/admin/surfaces/components/components-data.js +17 -4
- package/dist/admin/surfaces/components/components-data.js.map +1 -1
- package/dist/admin/surfaces/components/components-list.d.ts.map +1 -1
- package/dist/admin/surfaces/components/components-list.js +20 -7
- package/dist/admin/surfaces/components/components-list.js.map +1 -1
- package/dist/admin/surfaces/components/definition-canvas.d.ts +11 -3
- package/dist/admin/surfaces/components/definition-canvas.d.ts.map +1 -1
- package/dist/admin/surfaces/components/definition-canvas.js +138 -17
- package/dist/admin/surfaces/components/definition-canvas.js.map +1 -1
- package/dist/admin/surfaces/dashboard/dashboard-index.d.ts.map +1 -1
- package/dist/admin/surfaces/dashboard/dashboard-index.js +2 -2
- package/dist/admin/surfaces/dashboard/dashboard-index.js.map +1 -1
- package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
- package/dist/admin/surfaces/layouts/layout-editor-client.js +12 -11
- package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
- package/dist/admin/surfaces/login.d.ts.map +1 -1
- package/dist/admin/surfaces/login.js +13 -1
- package/dist/admin/surfaces/login.js.map +1 -1
- package/dist/admin/surfaces/menus/menu-editor.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menu-editor.js +17 -4
- package/dist/admin/surfaces/menus/menu-editor.js.map +1 -1
- package/dist/admin/surfaces/menus/menu-tree.d.ts +18 -4
- package/dist/admin/surfaces/menus/menu-tree.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menu-tree.js +18 -3
- package/dist/admin/surfaces/menus/menu-tree.js.map +1 -1
- package/dist/admin/surfaces/menus/menus-data.d.ts +18 -0
- package/dist/admin/surfaces/menus/menus-data.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menus-data.js +4 -0
- package/dist/admin/surfaces/menus/menus-data.js.map +1 -1
- package/dist/admin/surfaces/menus/menus-list.d.ts.map +1 -1
- package/dist/admin/surfaces/menus/menus-list.js +2 -12
- package/dist/admin/surfaces/menus/menus-list.js.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.d.ts.map +1 -1
- package/dist/admin/surfaces/settings/admin-features.js +12 -1
- package/dist/admin/surfaces/settings/admin-features.js.map +1 -1
- package/dist/admin/surfaces/users/users-data.d.ts +16 -0
- package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-data.js +19 -0
- package/dist/admin/surfaces/users/users-data.js.map +1 -1
- package/dist/admin/surfaces/users/users-detail.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-detail.js +87 -6
- package/dist/admin/surfaces/users/users-detail.js.map +1 -1
- package/dist/admin/surfaces/users/users-new.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-new.js +9 -5
- package/dist/admin/surfaces/users/users-new.js.map +1 -1
- package/dist/admin/user-form.d.ts +13 -2
- package/dist/admin/user-form.d.ts.map +1 -1
- package/dist/admin/user-form.js +3 -2
- package/dist/admin/user-form.js.map +1 -1
- package/dist/api/admin-features-routes.js +2 -2
- package/dist/api/admin-features-routes.js.map +1 -1
- package/dist/api/audience-preview-routes.d.ts +7 -0
- package/dist/api/audience-preview-routes.d.ts.map +1 -1
- package/dist/api/audience-preview-routes.js +4 -4
- package/dist/api/audience-preview-routes.js.map +1 -1
- package/dist/api/audience-routes.d.ts +7 -0
- package/dist/api/audience-routes.d.ts.map +1 -1
- package/dist/api/audience-routes.js +21 -15
- package/dist/api/audience-routes.js.map +1 -1
- package/dist/api/audience-runtime-routes.d.ts +6 -0
- package/dist/api/audience-runtime-routes.d.ts.map +1 -1
- package/dist/api/audience-runtime-routes.js +38 -3
- package/dist/api/audience-runtime-routes.js.map +1 -1
- package/dist/api/auth-routes.d.ts.map +1 -1
- package/dist/api/auth-routes.js +33 -4
- package/dist/api/auth-routes.js.map +1 -1
- package/dist/api/auth.d.ts +1 -0
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +43 -3
- package/dist/api/auth.js.map +1 -1
- package/dist/api/bulk-routes.d.ts.map +1 -1
- package/dist/api/bulk-routes.js +7 -7
- package/dist/api/bulk-routes.js.map +1 -1
- package/dist/api/category-routes.js +3 -3
- package/dist/api/category-routes.js.map +1 -1
- package/dist/api/comment-routes.js +8 -8
- package/dist/api/comment-routes.js.map +1 -1
- package/dist/api/component-routes.d.ts +25 -0
- package/dist/api/component-routes.d.ts.map +1 -1
- package/dist/api/component-routes.js +41 -16
- package/dist/api/component-routes.js.map +1 -1
- package/dist/api/content-routes.js +13 -13
- package/dist/api/content-routes.js.map +1 -1
- package/dist/api/dashboard-routes.js +1 -1
- package/dist/api/dashboard-routes.js.map +1 -1
- package/dist/api/experiment-routes.d.ts +7 -0
- package/dist/api/experiment-routes.d.ts.map +1 -1
- package/dist/api/experiment-routes.js +8 -8
- package/dist/api/experiment-routes.js.map +1 -1
- package/dist/api/experiment-runtime-routes.d.ts +6 -0
- package/dist/api/experiment-runtime-routes.d.ts.map +1 -1
- package/dist/api/experiment-runtime-routes.js +47 -11
- package/dist/api/experiment-runtime-routes.js.map +1 -1
- package/dist/api/feed-routes.d.ts +2 -2
- package/dist/api/feed-routes.js +3 -3
- package/dist/api/feed-routes.js.map +1 -1
- package/dist/api/form-routes.js +4 -4
- package/dist/api/form-routes.js.map +1 -1
- package/dist/api/graphql/resolvers.d.ts +1 -1
- package/dist/api/graphql/resolvers.d.ts.map +1 -1
- package/dist/api/graphql/resolvers.js +68 -33
- package/dist/api/graphql/resolvers.js.map +1 -1
- package/dist/api/group-routes.js +6 -6
- package/dist/api/group-routes.js.map +1 -1
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +97 -7
- package/dist/api/index.js.map +1 -1
- package/dist/api/layout-routes.d.ts.map +1 -1
- package/dist/api/layout-routes.js +27 -3
- package/dist/api/layout-routes.js.map +1 -1
- package/dist/api/media-routes.d.ts.map +1 -1
- package/dist/api/media-routes.js +50 -26
- package/dist/api/media-routes.js.map +1 -1
- package/dist/api/menu-routes.d.ts +9 -1
- package/dist/api/menu-routes.d.ts.map +1 -1
- package/dist/api/menu-routes.js +44 -10
- package/dist/api/menu-routes.js.map +1 -1
- package/dist/api/nav-routes.d.ts +6 -0
- package/dist/api/nav-routes.d.ts.map +1 -1
- package/dist/api/nav-routes.js +24 -3
- package/dist/api/nav-routes.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +68 -33
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/password-gate.d.ts +23 -0
- package/dist/api/password-gate.d.ts.map +1 -0
- package/dist/api/password-gate.js +41 -0
- package/dist/api/password-gate.js.map +1 -0
- package/dist/api/password-reset-routes.d.ts.map +1 -1
- package/dist/api/password-reset-routes.js +13 -6
- package/dist/api/password-reset-routes.js.map +1 -1
- package/dist/api/search-routes.js +2 -2
- package/dist/api/search-routes.js.map +1 -1
- package/dist/api/section-template-routes.d.ts.map +1 -1
- package/dist/api/section-template-routes.js +35 -18
- package/dist/api/section-template-routes.js.map +1 -1
- package/dist/api/site-admin-routes.d.ts +10 -1
- package/dist/api/site-admin-routes.d.ts.map +1 -1
- package/dist/api/site-admin-routes.js +21 -1
- package/dist/api/site-admin-routes.js.map +1 -1
- package/dist/api/site-context.d.ts +35 -5
- package/dist/api/site-context.d.ts.map +1 -1
- package/dist/api/site-context.js +21 -6
- package/dist/api/site-context.js.map +1 -1
- package/dist/api/tag-routes.js +3 -3
- package/dist/api/tag-routes.js.map +1 -1
- package/dist/api/translation-routes.js +5 -5
- package/dist/api/translation-routes.js.map +1 -1
- package/dist/api/user-routes.d.ts +4 -0
- package/dist/api/user-routes.d.ts.map +1 -1
- package/dist/api/user-routes.js +240 -17
- package/dist/api/user-routes.js.map +1 -1
- package/dist/api/webhook-routes.js +5 -5
- package/dist/api/webhook-routes.js.map +1 -1
- package/dist/api/workflow-routes.js +8 -8
- package/dist/api/workflow-routes.js.map +1 -1
- package/dist/audiences/collectors/identity.d.ts +14 -1
- package/dist/audiences/collectors/identity.d.ts.map +1 -1
- package/dist/audiences/collectors/identity.js +16 -3
- package/dist/audiences/collectors/identity.js.map +1 -1
- package/dist/audiences/collectors/index.d.ts +12 -2
- package/dist/audiences/collectors/index.d.ts.map +1 -1
- package/dist/audiences/collectors/index.js +16 -5
- package/dist/audiences/collectors/index.js.map +1 -1
- package/dist/audiences/collectors/pinned-audience.d.ts +28 -2
- package/dist/audiences/collectors/pinned-audience.d.ts.map +1 -1
- package/dist/audiences/collectors/pinned-audience.js +35 -5
- package/dist/audiences/collectors/pinned-audience.js.map +1 -1
- package/dist/audiences/collectors/utm.d.ts +15 -1
- package/dist/audiences/collectors/utm.d.ts.map +1 -1
- package/dist/audiences/collectors/utm.js +16 -2
- package/dist/audiences/collectors/utm.js.map +1 -1
- package/dist/audiences/consent-config.d.ts +21 -0
- package/dist/audiences/consent-config.d.ts.map +1 -0
- package/dist/audiences/consent-config.js +15 -0
- package/dist/audiences/consent-config.js.map +1 -0
- package/dist/audiences/consent-startup.d.ts +39 -0
- package/dist/audiences/consent-startup.d.ts.map +1 -0
- package/dist/audiences/consent-startup.js +105 -0
- package/dist/audiences/consent-startup.js.map +1 -0
- package/dist/audiences/consent.d.ts +192 -0
- package/dist/audiences/consent.d.ts.map +1 -0
- package/dist/audiences/consent.js +322 -0
- package/dist/audiences/consent.js.map +1 -0
- package/dist/audiences/engine.d.ts +7 -0
- package/dist/audiences/engine.d.ts.map +1 -1
- package/dist/audiences/engine.js +6 -2
- package/dist/audiences/engine.js.map +1 -1
- package/dist/audiences/index.d.ts +3 -0
- package/dist/audiences/index.d.ts.map +1 -1
- package/dist/audiences/index.js +6 -0
- package/dist/audiences/index.js.map +1 -1
- package/dist/audiences/server-eval.d.ts +13 -1
- package/dist/audiences/server-eval.d.ts.map +1 -1
- package/dist/audiences/server-eval.js +18 -2
- package/dist/audiences/server-eval.js.map +1 -1
- package/dist/audiences/ssr.d.ts +18 -1
- package/dist/audiences/ssr.d.ts.map +1 -1
- package/dist/audiences/ssr.js +18 -1
- package/dist/audiences/ssr.js.map +1 -1
- package/dist/audiences/utm-persistence.d.ts +20 -7
- package/dist/audiences/utm-persistence.d.ts.map +1 -1
- package/dist/audiences/utm-persistence.js +20 -7
- package/dist/audiences/utm-persistence.js.map +1 -1
- package/dist/auth/roles.d.ts +11 -0
- package/dist/auth/roles.d.ts.map +1 -1
- package/dist/auth/roles.js +13 -0
- package/dist/auth/roles.js.map +1 -1
- package/dist/auth/tokens.d.ts +7 -0
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +24 -2
- package/dist/auth/tokens.js.map +1 -1
- package/dist/config/types.d.ts +50 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +3 -0
- package/dist/config/validate.js.map +1 -1
- package/dist/db/apply-snapshot.d.ts +18 -0
- package/dist/db/apply-snapshot.d.ts.map +1 -1
- package/dist/db/apply-snapshot.js +41 -16
- package/dist/db/apply-snapshot.js.map +1 -1
- package/dist/db/component-instance-queries.d.ts +79 -19
- package/dist/db/component-instance-queries.d.ts.map +1 -1
- package/dist/db/component-instance-queries.js +266 -83
- package/dist/db/component-instance-queries.js.map +1 -1
- package/dist/db/component-queries.d.ts +1 -16
- package/dist/db/component-queries.d.ts.map +1 -1
- package/dist/db/component-queries.js +7 -56
- package/dist/db/component-queries.js.map +1 -1
- package/dist/db/content-queries.d.ts.map +1 -1
- package/dist/db/content-queries.js +1 -2
- package/dist/db/content-queries.js.map +1 -1
- package/dist/db/extension-queries.d.ts +2 -2
- package/dist/db/feed-queries.d.ts +3 -3
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/layout-queries.d.ts +2 -1
- package/dist/db/layout-queries.d.ts.map +1 -1
- package/dist/db/layout-queries.js +3 -3
- package/dist/db/layout-queries.js.map +1 -1
- package/dist/db/menu-queries.d.ts +69 -5
- package/dist/db/menu-queries.d.ts.map +1 -1
- package/dist/db/menu-queries.js +120 -13
- package/dist/db/menu-queries.js.map +1 -1
- package/dist/db/section-template-queries.d.ts +62 -0
- package/dist/db/section-template-queries.d.ts.map +1 -0
- package/dist/db/section-template-queries.js +178 -0
- package/dist/db/section-template-queries.js.map +1 -0
- package/dist/db/site-plugin-queries.d.ts +2 -2
- package/dist/db/tree-queries.d.ts.map +1 -1
- package/dist/db/tree-queries.js +5 -0
- package/dist/db/tree-queries.js.map +1 -1
- package/dist/db/user-queries.d.ts +28 -1
- package/dist/db/user-queries.d.ts.map +1 -1
- package/dist/db/user-queries.js +49 -1
- package/dist/db/user-queries.js.map +1 -1
- package/dist/db/webhook-queries.d.ts +3 -3
- package/dist/db/workflow-queries.d.ts.map +1 -1
- package/dist/db/workflow-queries.js +5 -20
- package/dist/db/workflow-queries.js.map +1 -1
- package/dist/experiments/runtime.d.ts +21 -3
- package/dist/experiments/runtime.d.ts.map +1 -1
- package/dist/experiments/runtime.js +21 -3
- package/dist/experiments/runtime.js.map +1 -1
- package/dist/host/index.d.ts +1 -0
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +12 -0
- package/dist/host/index.js.map +1 -1
- package/dist/layout/component-refs.d.ts +90 -2
- package/dist/layout/component-refs.d.ts.map +1 -1
- package/dist/layout/component-refs.js +293 -16
- package/dist/layout/component-refs.js.map +1 -1
- package/dist/layout/index.d.ts +4 -3
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +3 -2
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/legacy-variant-container.d.ts +123 -0
- package/dist/layout/legacy-variant-container.d.ts.map +1 -0
- package/dist/layout/legacy-variant-container.js +397 -0
- package/dist/layout/legacy-variant-container.js.map +1 -0
- package/dist/layout/module-permissions.d.ts.map +1 -1
- package/dist/layout/module-permissions.js +25 -1
- package/dist/layout/module-permissions.js.map +1 -1
- package/dist/layout/modules-extended.d.ts +28 -1
- package/dist/layout/modules-extended.d.ts.map +1 -1
- package/dist/layout/modules-extended.js +73 -1
- package/dist/layout/modules-extended.js.map +1 -1
- package/dist/layout/modules.d.ts.map +1 -1
- package/dist/layout/modules.js +9 -1
- package/dist/layout/modules.js.map +1 -1
- package/dist/layout/personalization.d.ts +83 -0
- package/dist/layout/personalization.d.ts.map +1 -1
- package/dist/layout/personalization.js +250 -4
- package/dist/layout/personalization.js.map +1 -1
- package/dist/layout/registry.d.ts.map +1 -1
- package/dist/layout/registry.js +20 -0
- package/dist/layout/registry.js.map +1 -1
- package/dist/layout/renderer.d.ts +29 -2
- package/dist/layout/renderer.d.ts.map +1 -1
- package/dist/layout/renderer.js +23 -6
- package/dist/layout/renderer.js.map +1 -1
- package/dist/layout/types.d.ts +17 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/types.js +7 -0
- package/dist/layout/types.js.map +1 -1
- package/dist/media/inline-risk.d.ts +26 -0
- package/dist/media/inline-risk.d.ts.map +1 -0
- package/dist/media/inline-risk.js +142 -0
- package/dist/media/inline-risk.js.map +1 -0
- package/dist/nav/builder.d.ts.map +1 -1
- package/dist/nav/builder.js +15 -3
- package/dist/nav/builder.js.map +1 -1
- package/dist/nav/index.d.ts +1 -1
- package/dist/nav/index.d.ts.map +1 -1
- package/dist/nav/index.js +1 -1
- package/dist/nav/index.js.map +1 -1
- package/dist/nav/menu-resolver.d.ts +11 -0
- package/dist/nav/menu-resolver.d.ts.map +1 -1
- package/dist/nav/menu-resolver.js +49 -9
- package/dist/nav/menu-resolver.js.map +1 -1
- package/dist/nav/paths.d.ts +37 -0
- package/dist/nav/paths.d.ts.map +1 -0
- package/dist/nav/paths.js +48 -0
- package/dist/nav/paths.js.map +1 -0
- package/dist/nav/types.d.ts +6 -0
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/nav/url-resolver.d.ts +1 -5
- package/dist/nav/url-resolver.d.ts.map +1 -1
- package/dist/nav/url-resolver.js +6 -12
- package/dist/nav/url-resolver.js.map +1 -1
- package/dist/schema/base.d.ts +41 -4
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +23 -4
- package/dist/schema/base.js.map +1 -1
- package/dist/schema/components.d.ts +90 -9
- package/dist/schema/components.d.ts.map +1 -1
- package/dist/schema/components.js +113 -22
- package/dist/schema/components.js.map +1 -1
- package/dist/schema/mysql-tables.d.ts +5775 -48
- package/dist/schema/mysql-tables.d.ts.map +1 -1
- package/dist/schema/mysql-tables.js +621 -46
- package/dist/schema/mysql-tables.js.map +1 -1
- package/dist/scope/kywi-form.d.ts +11 -0
- package/dist/scope/kywi-form.d.ts.map +1 -1
- package/dist/scope/kywi-form.js +11 -1
- package/dist/scope/kywi-form.js.map +1 -1
- package/dist/scope/kywi-wizard-form.d.ts.map +1 -1
- package/dist/scope/kywi-wizard-form.js +76 -2
- package/dist/scope/kywi-wizard-form.js.map +1 -1
- package/dist/scope/sticky-offset.d.ts +34 -13
- package/dist/scope/sticky-offset.d.ts.map +1 -1
- package/dist/scope/sticky-offset.js +236 -43
- package/dist/scope/sticky-offset.js.map +1 -1
- package/dist/site/styles.css +61 -15
- package/dist/versioning/scheduler.d.ts +28 -0
- package/dist/versioning/scheduler.d.ts.map +1 -1
- package/dist/versioning/scheduler.js +50 -3
- package/dist/versioning/scheduler.js.map +1 -1
- package/package.json +7 -2
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { sql } from 'drizzle-orm';
|
|
3
|
+
import { mysqlTable, varchar, text, int, boolean, datetime, json, decimal, index, primaryKey, unique, check, } from 'drizzle-orm/mysql-core';
|
|
4
|
+
/**
|
|
5
|
+
* MySQL twins of every Postgres table in this package (kywi-cms#75).
|
|
6
|
+
*
|
|
7
|
+
* MySQL is a supported deployment target, not a Postgres subset: every
|
|
8
|
+
* `pgTable` exported from `schema/` (plus `audiences/` and `experiments/`) has
|
|
9
|
+
* a twin here with the same table name, columns, nullability and defaults.
|
|
10
|
+
* `schema/__tests__/mysql-parity.test.ts` enforces that programmatically —
|
|
11
|
+
* add a pgTable without a twin and it fails.
|
|
12
|
+
*
|
|
13
|
+
* Where a Postgres construct has no MySQL equivalent, the twin says so in a
|
|
14
|
+
* comment and takes the closest expressible shape. The recurring cases:
|
|
15
|
+
*
|
|
16
|
+
* - **`uuid` → `varchar(36)`.** MySQL has no uuid type.
|
|
17
|
+
* - **`timestamptz` → `datetime(3)`.** MySQL's `timestamp` is 2038-bounded and
|
|
18
|
+
* auto-updating; `datetime` with millisecond precision is the faithful twin.
|
|
19
|
+
* `defaultNow()` becomes `DEFAULT CURRENT_TIMESTAMP(3)` ({@link mysqlNow}).
|
|
20
|
+
* - **`jsonb` → `json`.** No jsonb operator classes, so no GIN-equivalent
|
|
21
|
+
* indexing, and a JSON column cannot take a *literal* DEFAULT — see
|
|
22
|
+
* {@link mysqlJsonDefault}.
|
|
23
|
+
* - **`text` → `varchar(n)` when the column is keyed, indexed or defaulted.**
|
|
24
|
+
* MySQL cannot use TEXT as a primary key, cannot index it without a prefix
|
|
25
|
+
* length, and cannot give it a DEFAULT. Every such conversion is marked.
|
|
26
|
+
* - **Partial (`WHERE …`) unique indexes have no MySQL equivalent.** The one
|
|
27
|
+
* place Kywi uses them — `kywi_content_permissions` — falls back to plain
|
|
28
|
+
* lookup indexes plus the app-level dedupe already in the migrate path; see
|
|
29
|
+
* the comment on {@link kywiContentPermissionsMysql} and docs/hosting.md.
|
|
30
|
+
*/
|
|
3
31
|
// ── Helper: UUID primary key for MySQL ──────────────────────────────────────
|
|
4
32
|
function mysqlUuidPk() {
|
|
5
33
|
return varchar({ length: 36 }).primaryKey().$defaultFn(() => randomUUID());
|
|
@@ -10,16 +38,42 @@ function mysqlUuid(name) {
|
|
|
10
38
|
function mysqlTs(name) {
|
|
11
39
|
return datetime(name, { fsp: 3 });
|
|
12
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The MySQL twin of Postgres `defaultNow()`.
|
|
43
|
+
*
|
|
44
|
+
* drizzle's mysql-core exposes `.defaultNow()` only on `timestamp`, and these
|
|
45
|
+
* twins deliberately use `datetime` (see the module doc). `DEFAULT
|
|
46
|
+
* CURRENT_TIMESTAMP(3)` is what `defaultNow()` compiles to for a `datetime(3)`
|
|
47
|
+
* column, and MySQL has accepted it on DATETIME since 5.6.5.
|
|
48
|
+
*
|
|
49
|
+
* Returns a fresh `SQL` each call so no two columns share one node.
|
|
50
|
+
*/
|
|
51
|
+
function mysqlNow() {
|
|
52
|
+
return sql `CURRENT_TIMESTAMP(3)`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The MySQL twin of a Postgres `jsonb(...).default([])`.
|
|
56
|
+
*
|
|
57
|
+
* MySQL rejects a literal DEFAULT on a JSON column outright; since 8.0.13 it
|
|
58
|
+
* accepts a *parenthesised expression* default instead, which is what this
|
|
59
|
+
* emits. On MySQL 8.0.12 and older there is no way to express the default at
|
|
60
|
+
* all and the column has to be written explicitly by the caller — the query
|
|
61
|
+
* layer already does, so the practical effect is limited to hand-written
|
|
62
|
+
* inserts. Documented in docs/hosting.md.
|
|
63
|
+
*/
|
|
64
|
+
function mysqlJsonDefault(literal) {
|
|
65
|
+
return sql.raw(`('${literal.replace(/'/g, "''")}')`);
|
|
66
|
+
}
|
|
13
67
|
// ── kywiSitesMysql ──────────────────────────────────────────────────────────
|
|
14
68
|
export const kywiSitesMysql = mysqlTable('kywi_sites', {
|
|
15
69
|
id: mysqlUuidPk(),
|
|
16
|
-
slug: varchar('slug', { length: 100 }).notNull(),
|
|
70
|
+
slug: varchar('slug', { length: 100 }).notNull().unique(),
|
|
17
71
|
name: text('name').notNull(),
|
|
18
72
|
domain: text('domain').notNull(),
|
|
19
73
|
defaultLocale: varchar('default_locale', { length: 10 }).notNull().default('en'),
|
|
20
74
|
theme: varchar('theme', { length: 100 }).notNull().default('default'),
|
|
21
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
22
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
75
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
76
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
23
77
|
});
|
|
24
78
|
// ── kywiContentMysql ────────────────────────────────────────────────────────
|
|
25
79
|
export const kywiContentMysql = mysqlTable('kywi_content', {
|
|
@@ -27,7 +81,9 @@ export const kywiContentMysql = mysqlTable('kywi_content', {
|
|
|
27
81
|
id: mysqlUuidPk(),
|
|
28
82
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
29
83
|
parentId: mysqlUuid('parent_id'),
|
|
30
|
-
|
|
84
|
+
// pg: `text NOT NULL DEFAULT '/'`. MySQL cannot give a TEXT column a
|
|
85
|
+
// DEFAULT, so the twin narrows to varchar to keep the default.
|
|
86
|
+
path: varchar('path', { length: 1024 }).notNull().default('/'),
|
|
31
87
|
depth: int('depth').notNull().default(0),
|
|
32
88
|
sortOrder: int('sort_order').notNull().default(0),
|
|
33
89
|
title: text('title').notNull(),
|
|
@@ -37,8 +93,8 @@ export const kywiContentMysql = mysqlTable('kywi_content', {
|
|
|
37
93
|
baseType: varchar('base_type', { length: 50 }).notNull(),
|
|
38
94
|
contentTypeName: varchar('content_type_name', { length: 100 }).notNull(),
|
|
39
95
|
publishedAt: mysqlTs('published_at'),
|
|
40
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
41
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
96
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
97
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
42
98
|
createdBy: mysqlUuid('created_by'),
|
|
43
99
|
updatedBy: mysqlUuid('updated_by'),
|
|
44
100
|
metaTitle: text('meta_title'),
|
|
@@ -56,7 +112,9 @@ export const kywiContentMysql = mysqlTable('kywi_content', {
|
|
|
56
112
|
robotsFollow: varchar('robots_follow', { length: 10 }),
|
|
57
113
|
deletedAt: mysqlTs('deleted_at'),
|
|
58
114
|
featuredImageId: mysqlUuid('featured_image_id'),
|
|
59
|
-
|
|
115
|
+
// pg: `text DEFAULT 'no'` — 'no' | 'yes' | ISO date string. Narrowed to
|
|
116
|
+
// varchar so MySQL can carry the default (an ISO-8601 stamp is 29 chars).
|
|
117
|
+
featureInSection: varchar('feature_in_section', { length: 64 }).default('no'),
|
|
60
118
|
expiresAt: mysqlTs('expires_at'),
|
|
61
119
|
excludeFromSearch: boolean('exclude_from_search').notNull().default(false),
|
|
62
120
|
internalNotes: text('internal_notes'),
|
|
@@ -105,15 +163,18 @@ export const kywiContentMysql = mysqlTable('kywi_content', {
|
|
|
105
163
|
// ── kywiUsersMysql ──────────────────────────────────────────────────────────
|
|
106
164
|
export const kywiUsersMysql = mysqlTable('kywi_users', {
|
|
107
165
|
id: mysqlUuidPk(),
|
|
108
|
-
|
|
166
|
+
// pg: `text NOT NULL UNIQUE`. MySQL cannot put a UNIQUE index on TEXT
|
|
167
|
+
// without a prefix length; 320 is the RFC 5321 maximum address length.
|
|
168
|
+
email: varchar('email', { length: 320 }).notNull().unique(),
|
|
109
169
|
passwordHash: text('password_hash').notNull(),
|
|
110
|
-
|
|
111
|
-
|
|
170
|
+
// pg: `text NOT NULL DEFAULT ''` — narrowed so MySQL can carry the default.
|
|
171
|
+
firstName: varchar('first_name', { length: 255 }).notNull().default(''),
|
|
172
|
+
lastName: varchar('last_name', { length: 255 }).notNull().default(''),
|
|
112
173
|
role: varchar('role', { length: 20 }).notNull().default('reader'),
|
|
113
174
|
isActive: boolean('is_active').notNull().default(true),
|
|
114
175
|
lastLoginAt: mysqlTs('last_login_at'),
|
|
115
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
116
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
176
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
177
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
117
178
|
// ── Profile fields ──────────────────────────────────────────────────────────
|
|
118
179
|
company: text('company'),
|
|
119
180
|
jobTitle: text('job_title'),
|
|
@@ -123,6 +184,7 @@ export const kywiUsersMysql = mysqlTable('kywi_users', {
|
|
|
123
184
|
bio: text('bio'),
|
|
124
185
|
preferences: json('preferences'),
|
|
125
186
|
passwordChangedAt: mysqlTs('password_changed_at'),
|
|
187
|
+
passwordResetRequired: boolean('password_reset_required').notNull().default(false),
|
|
126
188
|
});
|
|
127
189
|
// ── kywiGroupsMysql ─────────────────────────────────────────────────────────
|
|
128
190
|
export const kywiGroupsMysql = mysqlTable('kywi_groups', {
|
|
@@ -131,7 +193,7 @@ export const kywiGroupsMysql = mysqlTable('kywi_groups', {
|
|
|
131
193
|
name: text('name').notNull(),
|
|
132
194
|
type: varchar('type', { length: 20 }).notNull().default('private'),
|
|
133
195
|
defaultRole: varchar('default_role', { length: 20 }).notNull().default('reader'),
|
|
134
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
196
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
135
197
|
});
|
|
136
198
|
// ── kywiUserGroupsMysql ─────────────────────────────────────────────────────
|
|
137
199
|
// #40: unique(userId, groupId) — see the matching note on kywiUserGroups in
|
|
@@ -148,9 +210,9 @@ export const kywiApiKeysMysql = mysqlTable('kywi_api_keys', {
|
|
|
148
210
|
name: text('name').notNull(),
|
|
149
211
|
keyHash: text('key_hash').notNull(),
|
|
150
212
|
keyPrefix: varchar('key_prefix', { length: 12 }).notNull(),
|
|
151
|
-
scopes: json('scopes').notNull(),
|
|
213
|
+
scopes: json('scopes').notNull().default(mysqlJsonDefault('[]')),
|
|
152
214
|
lastUsedAt: mysqlTs('last_used_at'),
|
|
153
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
215
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
154
216
|
});
|
|
155
217
|
// ── kywiSiteMembershipsMysql ────────────────────────────────────────────────
|
|
156
218
|
// #40: unique(userId, siteId) — see the matching note on kywiSiteMemberships
|
|
@@ -160,8 +222,8 @@ export const kywiApiKeysMysql = mysqlTable('kywi_api_keys', {
|
|
|
160
222
|
export const kywiSiteMembershipsMysql = mysqlTable('kywi_site_memberships', {
|
|
161
223
|
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
162
224
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
163
|
-
groups: json('groups').notNull(),
|
|
164
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
225
|
+
groups: json('groups').notNull().default(mysqlJsonDefault('[]')),
|
|
226
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
165
227
|
}, (t) => [unique().on(t.userId, t.siteId)]);
|
|
166
228
|
// ── kywiMediaMysql ──────────────────────────────────────────────────────────
|
|
167
229
|
export const kywiMediaMysql = mysqlTable('kywi_media', {
|
|
@@ -180,8 +242,8 @@ export const kywiMediaMysql = mysqlTable('kywi_media', {
|
|
|
180
242
|
uploadedBy: mysqlUuid('uploaded_by'),
|
|
181
243
|
storageKey: text('storage_key').notNull(),
|
|
182
244
|
deletedAt: mysqlTs('deleted_at'),
|
|
183
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
184
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
245
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
246
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
185
247
|
});
|
|
186
248
|
// ── kywiFormSubmissionsMysql ────────────────────────────────────────────────
|
|
187
249
|
export const kywiFormSubmissionsMysql = mysqlTable('kywi_form_submissions', {
|
|
@@ -189,7 +251,7 @@ export const kywiFormSubmissionsMysql = mysqlTable('kywi_form_submissions', {
|
|
|
189
251
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
190
252
|
formContentId: mysqlUuid('form_content_id').notNull(),
|
|
191
253
|
data: json('data').notNull(),
|
|
192
|
-
submittedAt: mysqlTs('submitted_at').notNull(),
|
|
254
|
+
submittedAt: mysqlTs('submitted_at').notNull().default(mysqlNow()),
|
|
193
255
|
ipAddress: varchar('ip_address', { length: 45 }),
|
|
194
256
|
status: varchar('status', { length: 20 }).notNull().default('new'),
|
|
195
257
|
});
|
|
@@ -203,7 +265,7 @@ export const kywiContentVersionsMysql = mysqlTable('kywi_content_versions', {
|
|
|
203
265
|
changeNote: text('change_note'),
|
|
204
266
|
status: varchar('status', { length: 20 }).notNull(),
|
|
205
267
|
createdBy: mysqlUuid('created_by'),
|
|
206
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
268
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
207
269
|
});
|
|
208
270
|
// ── kywiCategoriesMysql ─────────────────────────────────────────────────────
|
|
209
271
|
export const kywiCategoriesMysql = mysqlTable('kywi_categories', {
|
|
@@ -217,8 +279,8 @@ export const kywiCategoriesMysql = mysqlTable('kywi_categories', {
|
|
|
217
279
|
isActive: boolean('is_active').notNull().default(true),
|
|
218
280
|
isInterestGroup: boolean('is_interest_group').notNull().default(false),
|
|
219
281
|
notes: text('notes'),
|
|
220
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
221
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
282
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
283
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
222
284
|
});
|
|
223
285
|
// ── kywiTagsMysql ───────────────────────────────────────────────────────────
|
|
224
286
|
export const kywiTagsMysql = mysqlTable('kywi_tags', {
|
|
@@ -228,7 +290,7 @@ export const kywiTagsMysql = mysqlTable('kywi_tags', {
|
|
|
228
290
|
label: text('label').notNull(),
|
|
229
291
|
usageCount: int('usage_count').notNull().default(0),
|
|
230
292
|
groupName: varchar('group_name', { length: 100 }),
|
|
231
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
293
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
232
294
|
});
|
|
233
295
|
// ── kywiCommentsMysql ───────────────────────────────────────────────────────
|
|
234
296
|
export const kywiCommentsMysql = mysqlTable('kywi_comments', {
|
|
@@ -241,8 +303,8 @@ export const kywiCommentsMysql = mysqlTable('kywi_comments', {
|
|
|
241
303
|
authorEmail: text('author_email'),
|
|
242
304
|
body: text('body').notNull(),
|
|
243
305
|
status: varchar('status', { length: 20 }).notNull().default('pending'),
|
|
244
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
245
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
306
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
307
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
246
308
|
});
|
|
247
309
|
// ── kywiExperimentsMysql ─────────────────────────────────────────────────────
|
|
248
310
|
export const kywiExperimentsMysql = mysqlTable('kywi_experiments', {
|
|
@@ -261,9 +323,12 @@ export const kywiExperimentsMysql = mysqlTable('kywi_experiments', {
|
|
|
261
323
|
pausedAt: mysqlTs('paused_at'),
|
|
262
324
|
completedAt: mysqlTs('completed_at'),
|
|
263
325
|
createdBy: mysqlUuid('created_by'),
|
|
264
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
265
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
266
|
-
})
|
|
326
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
327
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
328
|
+
}, (t) => [
|
|
329
|
+
index('kywi_experiments_site_idx').on(t.siteId),
|
|
330
|
+
index('kywi_experiments_status_idx').on(t.status),
|
|
331
|
+
]);
|
|
267
332
|
// ── kywiExperimentVariantsMysql ──────────────────────────────────────────────
|
|
268
333
|
export const kywiExperimentVariantsMysql = mysqlTable('kywi_experiment_variants', {
|
|
269
334
|
id: mysqlUuidPk(),
|
|
@@ -273,18 +338,25 @@ export const kywiExperimentVariantsMysql = mysqlTable('kywi_experiment_variants'
|
|
|
273
338
|
isControl: boolean('is_control').notNull().default(false),
|
|
274
339
|
variantKey: text('variant_key'),
|
|
275
340
|
sortOrder: int('sort_order').notNull().default(0),
|
|
276
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
277
|
-
})
|
|
341
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
342
|
+
}, (t) => [
|
|
343
|
+
index('kywi_experiment_variants_experiment_idx').on(t.experimentId),
|
|
344
|
+
]);
|
|
278
345
|
// ── kywiExperimentAssignmentsMysql ───────────────────────────────────────────
|
|
279
346
|
export const kywiExperimentAssignmentsMysql = mysqlTable('kywi_experiment_assignments', {
|
|
280
347
|
id: mysqlUuidPk(),
|
|
281
348
|
experimentId: mysqlUuid('experiment_id').notNull().references(() => kywiExperimentsMysql.id),
|
|
282
349
|
variantId: mysqlUuid('variant_id').notNull(),
|
|
283
350
|
siteId: mysqlUuid('site_id').notNull(),
|
|
284
|
-
|
|
285
|
-
|
|
351
|
+
// pg: `text`, but it is half of a UNIQUE index here — MySQL cannot index TEXT
|
|
352
|
+
// without a prefix length, so the twin narrows to varchar.
|
|
353
|
+
visitorId: varchar('visitor_id', { length: 255 }).notNull(),
|
|
354
|
+
assignedAt: mysqlTs('assigned_at').notNull().default(mysqlNow()),
|
|
286
355
|
exposedAt: mysqlTs('exposed_at'),
|
|
287
|
-
})
|
|
356
|
+
}, (t) => [
|
|
357
|
+
unique('kywi_experiment_assignments_exp_visitor_uniq').on(t.experimentId, t.visitorId),
|
|
358
|
+
index('kywi_experiment_assignments_exp_variant_idx').on(t.experimentId, t.variantId),
|
|
359
|
+
]);
|
|
288
360
|
// ── kywiExperimentConversionsMysql ───────────────────────────────────────────
|
|
289
361
|
export const kywiExperimentConversionsMysql = mysqlTable('kywi_experiment_conversions', {
|
|
290
362
|
id: mysqlUuidPk(),
|
|
@@ -294,8 +366,10 @@ export const kywiExperimentConversionsMysql = mysqlTable('kywi_experiment_conver
|
|
|
294
366
|
visitorId: text('visitor_id').notNull(),
|
|
295
367
|
goalType: text('goal_type').notNull(),
|
|
296
368
|
metadata: json('metadata'),
|
|
297
|
-
occurredAt: mysqlTs('occurred_at').notNull(),
|
|
298
|
-
})
|
|
369
|
+
occurredAt: mysqlTs('occurred_at').notNull().default(mysqlNow()),
|
|
370
|
+
}, (t) => [
|
|
371
|
+
index('kywi_experiment_conversions_exp_variant_idx').on(t.experimentId, t.variantId),
|
|
372
|
+
]);
|
|
299
373
|
// ── kywiContentTypeFieldsMysql (hybrid schema engine — admin-added fields) ────
|
|
300
374
|
export const kywiContentTypeFieldsMysql = mysqlTable('kywi_content_type_fields', {
|
|
301
375
|
id: mysqlUuidPk(),
|
|
@@ -312,8 +386,8 @@ export const kywiContentTypeFieldsMysql = mysqlTable('kywi_content_type_fields',
|
|
|
312
386
|
// 'list' fields set it.
|
|
313
387
|
itemType: varchar('item_type', { length: 50 }),
|
|
314
388
|
sortOrder: int('sort_order').notNull().default(0),
|
|
315
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
316
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
389
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
390
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
317
391
|
}, (t) => [unique().on(t.contentTypeName, t.name)]);
|
|
318
392
|
// ── kywiContentTypesMysql (visual type designer — admin-created types) ────────
|
|
319
393
|
export const kywiContentTypesMysql = mysqlTable('kywi_content_types', {
|
|
@@ -325,8 +399,8 @@ export const kywiContentTypesMysql = mysqlTable('kywi_content_types', {
|
|
|
325
399
|
// Whether the Title field is required on this type (kywi-cms#12). Defaults
|
|
326
400
|
// true — back-compat with every type created before this setting existed.
|
|
327
401
|
titleRequired: boolean('title_required').notNull().default(true),
|
|
328
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
329
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
402
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
403
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
330
404
|
});
|
|
331
405
|
// ── kywiMenusMysql (#110 — named owner-manageable navigation menus) ───────────
|
|
332
406
|
export const kywiMenusMysql = mysqlTable('kywi_menus', {
|
|
@@ -334,8 +408,8 @@ export const kywiMenusMysql = mysqlTable('kywi_menus', {
|
|
|
334
408
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
335
409
|
slug: varchar('slug', { length: 255 }).notNull(),
|
|
336
410
|
name: text('name').notNull(),
|
|
337
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
338
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
411
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
412
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
339
413
|
}, (t) => [unique().on(t.siteId, t.slug)]);
|
|
340
414
|
// ── kywiMenuItemsMysql (#110) ────────────────────────────────────────────────
|
|
341
415
|
// See the Postgres twin in base.ts for the contentId-XOR-externalUrl rule (it
|
|
@@ -346,11 +420,512 @@ export const kywiMenuItemsMysql = mysqlTable('kywi_menu_items', {
|
|
|
346
420
|
parentId: mysqlUuid('parent_id'),
|
|
347
421
|
sortOrder: int('sort_order').notNull().default(0),
|
|
348
422
|
label: text('label').notNull(),
|
|
349
|
-
|
|
423
|
+
kind: varchar('kind', { length: 20 }).notNull().default('link'),
|
|
424
|
+
contentId: mysqlUuid('content_id').references(() => kywiContentMysql.id, { onDelete: 'set null' }),
|
|
350
425
|
externalUrl: text('external_url'),
|
|
351
426
|
openInNewWindow: boolean('open_in_new_window').notNull().default(false),
|
|
352
427
|
description: text('description'),
|
|
353
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
354
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
428
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
429
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
430
|
+
});
|
|
431
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
432
|
+
// Twins added by the #75 parity sweep. Ordered to mirror the Postgres modules:
|
|
433
|
+
// base.ts, audiences/, webhooks.ts, extensions.ts, then the small per-feature
|
|
434
|
+
// modules. Every one is asserted against its Postgres original by
|
|
435
|
+
// __tests__/mysql-parity.test.ts.
|
|
436
|
+
// ═════════════════════════════════════════════════════════════════════════════
|
|
437
|
+
// ── base.ts ──────────────────────────────────────────────────────────────────
|
|
438
|
+
export const kywiContentDisplayIntervalsMysql = mysqlTable('kywi_content_display_intervals', {
|
|
439
|
+
id: mysqlUuidPk(),
|
|
440
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
441
|
+
dayOfWeek: int('day_of_week'),
|
|
442
|
+
startTime: text('start_time').notNull(),
|
|
443
|
+
endTime: text('end_time').notNull(),
|
|
444
|
+
startDate: mysqlTs('start_date'),
|
|
445
|
+
endDate: mysqlTs('end_date'),
|
|
446
|
+
});
|
|
447
|
+
export const kywiFeedsMysql = mysqlTable('kywi_feeds', {
|
|
448
|
+
id: mysqlUuidPk(),
|
|
449
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
450
|
+
name: text('name').notNull(),
|
|
451
|
+
slug: varchar('slug', { length: 255 }).notNull(),
|
|
452
|
+
query: json('query').notNull(),
|
|
453
|
+
cacheTtl: int('cache_ttl'),
|
|
454
|
+
createdBy: mysqlUuid('created_by'),
|
|
455
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
456
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
457
|
+
});
|
|
458
|
+
export const kywiFormSubmissionDraftsMysql = mysqlTable('kywi_form_submission_drafts', {
|
|
459
|
+
id: mysqlUuidPk(),
|
|
460
|
+
formContentId: mysqlUuid('form_content_id').notNull(),
|
|
461
|
+
token: varchar('token', { length: 64 }).notNull().unique(),
|
|
462
|
+
data: json('data').notNull(),
|
|
463
|
+
currentStep: int('current_step').notNull().default(0),
|
|
464
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
465
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
466
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
467
|
+
});
|
|
468
|
+
export const kywiAuditLogMysql = mysqlTable('kywi_audit_log', {
|
|
469
|
+
id: mysqlUuidPk(),
|
|
470
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
471
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
472
|
+
action: varchar('action', { length: 30 }).notNull(),
|
|
473
|
+
fromStatus: varchar('from_status', { length: 20 }),
|
|
474
|
+
toStatus: varchar('to_status', { length: 20 }),
|
|
475
|
+
changedFields: json('changed_fields'),
|
|
476
|
+
userId: mysqlUuid('user_id').notNull(),
|
|
477
|
+
userEmail: text('user_email').notNull(),
|
|
478
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
479
|
+
});
|
|
480
|
+
export const kywiContentCategoriesMysql = mysqlTable('kywi_content_categories', {
|
|
481
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
482
|
+
categoryId: mysqlUuid('category_id').notNull().references(() => kywiCategoriesMysql.id, { onDelete: 'cascade' }),
|
|
483
|
+
isFeatured: boolean('is_featured').notNull().default(false),
|
|
484
|
+
featuredUntil: mysqlTs('featured_until'),
|
|
485
|
+
});
|
|
486
|
+
export const kywiContentTagsMysql = mysqlTable('kywi_content_tags', {
|
|
487
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
488
|
+
tagId: mysqlUuid('tag_id').notNull().references(() => kywiTagsMysql.id, { onDelete: 'cascade' }),
|
|
489
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
490
|
+
}, (t) => [primaryKey({ columns: [t.contentId, t.tagId] })]);
|
|
491
|
+
export const kywiOAuthClientsMysql = mysqlTable('kywi_oauth_clients', {
|
|
492
|
+
id: mysqlUuidPk(),
|
|
493
|
+
clientId: varchar('client_id', { length: 64 }).notNull().unique(),
|
|
494
|
+
clientSecret: text('client_secret').notNull(),
|
|
495
|
+
name: text('name').notNull(),
|
|
496
|
+
scopes: json('scopes').notNull().default(mysqlJsonDefault('[]')),
|
|
497
|
+
redirectUris: json('redirect_uris').notNull().default(mysqlJsonDefault('[]')),
|
|
498
|
+
rateLimitPerMinute: int('rate_limit_per_minute').notNull().default(60),
|
|
499
|
+
createdBy: mysqlUuid('created_by'),
|
|
500
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
501
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
502
|
+
});
|
|
503
|
+
export const kywiLoginStrikesMysql = mysqlTable('kywi_login_strikes', {
|
|
504
|
+
id: mysqlUuidPk(),
|
|
505
|
+
userId: text('user_id').notNull(),
|
|
506
|
+
ip: text('ip').notNull(),
|
|
507
|
+
attemptedAt: mysqlTs('attempted_at').notNull().default(mysqlNow()),
|
|
508
|
+
});
|
|
509
|
+
export const kywiMfaSecretsMysql = mysqlTable('kywi_mfa_secrets', {
|
|
510
|
+
id: mysqlUuidPk(),
|
|
511
|
+
// pg: `text NOT NULL UNIQUE`, holding a kywi_users.id. MySQL cannot index
|
|
512
|
+
// TEXT without a prefix length, so the twin narrows to the uuid width.
|
|
513
|
+
userId: varchar('user_id', { length: 36 }).notNull().unique(),
|
|
514
|
+
secret: text('secret').notNull(),
|
|
515
|
+
recoveryCodes: text('recovery_codes').notNull(),
|
|
516
|
+
enabledAt: mysqlTs('enabled_at'),
|
|
517
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
518
|
+
});
|
|
519
|
+
export const kywiMagicLinkTokensMysql = mysqlTable('kywi_magic_link_tokens', {
|
|
520
|
+
id: mysqlUuidPk(),
|
|
521
|
+
userId: text('user_id').notNull(),
|
|
522
|
+
tokenHash: text('token_hash').notNull(),
|
|
523
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
524
|
+
usedAt: mysqlTs('used_at'),
|
|
525
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
526
|
+
});
|
|
527
|
+
export const kywiChangesetsMysql = mysqlTable('kywi_changesets', {
|
|
528
|
+
id: mysqlUuidPk(),
|
|
529
|
+
siteId: text('site_id').notNull(),
|
|
530
|
+
name: text('name').notNull(),
|
|
531
|
+
description: text('description'),
|
|
532
|
+
// pg: `text NOT NULL DEFAULT 'open'` — narrowed so MySQL can carry the default.
|
|
533
|
+
status: varchar('status', { length: 20 }).notNull().default('open'),
|
|
534
|
+
scheduledPublishAt: mysqlTs('scheduled_publish_at'),
|
|
535
|
+
publishedAt: mysqlTs('published_at'),
|
|
536
|
+
publishedBy: text('published_by'),
|
|
537
|
+
createdBy: text('created_by').notNull(),
|
|
538
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
539
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
540
|
+
});
|
|
541
|
+
export const kywiChangesetItemsMysql = mysqlTable('kywi_changeset_items', {
|
|
542
|
+
id: mysqlUuidPk(),
|
|
543
|
+
changesetId: text('changeset_id').notNull(),
|
|
544
|
+
contentId: text('content_id').notNull(),
|
|
545
|
+
versionId: text('version_id'),
|
|
546
|
+
action: text('action').notNull(),
|
|
547
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
548
|
+
});
|
|
549
|
+
export const kywiChangesetAuditMysql = mysqlTable('kywi_changeset_audit', {
|
|
550
|
+
id: mysqlUuidPk(),
|
|
551
|
+
changesetId: text('changeset_id').notNull(),
|
|
552
|
+
siteId: text('site_id').notNull(),
|
|
553
|
+
action: varchar('action', { length: 20 }).notNull(),
|
|
554
|
+
userId: text('user_id').notNull(),
|
|
555
|
+
detail: json('detail'),
|
|
556
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
557
|
+
});
|
|
558
|
+
export const kywiFilenameArchiveMysql = mysqlTable('kywi_filename_archive', {
|
|
559
|
+
id: mysqlUuidPk(),
|
|
560
|
+
siteId: text('site_id').notNull(),
|
|
561
|
+
oldPath: text('old_path').notNull(),
|
|
562
|
+
newPath: text('new_path').notNull(),
|
|
563
|
+
contentId: text('content_id').notNull(),
|
|
564
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
565
|
+
});
|
|
566
|
+
export const kywiContentLocksMysql = mysqlTable('kywi_content_locks', {
|
|
567
|
+
// pg: `text PRIMARY KEY`. MySQL cannot use TEXT as a primary key, so the twin
|
|
568
|
+
// narrows to the uuid width the column actually holds.
|
|
569
|
+
contentId: varchar('content_id', { length: 36 }).primaryKey(),
|
|
570
|
+
userId: text('user_id').notNull(),
|
|
571
|
+
lockedAt: mysqlTs('locked_at').notNull().default(mysqlNow()),
|
|
572
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
573
|
+
});
|
|
574
|
+
export const kywiContentStatsMysql = mysqlTable('kywi_content_stats', {
|
|
575
|
+
// pg: `text PRIMARY KEY` — same TEXT-as-PK narrowing as kywi_content_locks.
|
|
576
|
+
contentId: varchar('content_id', { length: 36 }).primaryKey(),
|
|
577
|
+
views: int('views').notNull().default(0),
|
|
578
|
+
downloads: int('downloads').notNull().default(0),
|
|
579
|
+
commentCount: int('comment_count').notNull().default(0),
|
|
580
|
+
lastViewedAt: mysqlTs('last_viewed_at'),
|
|
581
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
582
|
+
});
|
|
583
|
+
export const kywiViewLogMysql = mysqlTable('kywi_view_log', {
|
|
584
|
+
id: mysqlUuidPk(),
|
|
585
|
+
contentId: text('content_id').notNull(),
|
|
586
|
+
visitorId: text('visitor_id'),
|
|
587
|
+
viewedAt: mysqlTs('viewed_at').notNull().default(mysqlNow()),
|
|
588
|
+
});
|
|
589
|
+
export const kywiSectionTemplatesMysql = mysqlTable('kywi_section_templates', {
|
|
590
|
+
id: mysqlUuidPk(),
|
|
591
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
592
|
+
name: text('name').notNull(),
|
|
593
|
+
category: varchar('category', { length: 100 }).notNull().default('general'),
|
|
594
|
+
definition: json('definition').notNull(),
|
|
595
|
+
createdBy: mysqlUuid('created_by'),
|
|
596
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
597
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
598
|
+
});
|
|
599
|
+
export const kywiApprovalChainsMysql = mysqlTable('kywi_approval_chains', {
|
|
600
|
+
id: mysqlUuidPk(),
|
|
601
|
+
siteId: text('site_id').notNull(),
|
|
602
|
+
name: text('name').notNull(),
|
|
603
|
+
steps: json('steps').notNull(),
|
|
604
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
605
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
606
|
+
});
|
|
607
|
+
export const kywiApprovalActionsMysql = mysqlTable('kywi_approval_actions', {
|
|
608
|
+
id: mysqlUuidPk(),
|
|
609
|
+
chainId: text('chain_id').notNull(),
|
|
610
|
+
contentId: text('content_id').notNull(),
|
|
611
|
+
stepIndex: int('step_index').notNull(),
|
|
612
|
+
action: varchar('action', { length: 20 }).notNull(),
|
|
613
|
+
userId: text('user_id').notNull(),
|
|
614
|
+
comment: text('comment'),
|
|
615
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
616
|
+
});
|
|
617
|
+
export const kywiAnalyticsEventsMysql = mysqlTable('kywi_analytics_events', {
|
|
618
|
+
id: mysqlUuidPk(),
|
|
619
|
+
siteId: mysqlUuid('site_id').notNull(),
|
|
620
|
+
audienceId: mysqlUuid('audience_id').notNull(),
|
|
621
|
+
visitorId: text('visitor_id').notNull(),
|
|
622
|
+
// pg: `text` with an enum of 'matched' | 'impression' | 'click'. Postgres
|
|
623
|
+
// renders a text-with-enum column as plain text; varchar is the MySQL twin.
|
|
624
|
+
eventType: varchar('event_type', { length: 20 }).notNull(),
|
|
625
|
+
contentId: text('content_id'),
|
|
626
|
+
variantId: text('variant_id'),
|
|
627
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
628
|
+
});
|
|
629
|
+
// ── audiences/schema.ts ──────────────────────────────────────────────────────
|
|
630
|
+
export const kywiAudiencesMysql = mysqlTable('kywi_audiences', {
|
|
631
|
+
id: mysqlUuidPk(),
|
|
632
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
633
|
+
name: text('name').notNull(),
|
|
634
|
+
description: text('description'),
|
|
635
|
+
priority: int('priority').notNull(),
|
|
636
|
+
status: varchar('status', { length: 20 }).notNull().default('draft'),
|
|
637
|
+
scoreThreshold: int('score_threshold'),
|
|
638
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
639
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
640
|
+
}, (t) => [
|
|
641
|
+
index('kywi_audiences_site_idx').on(t.siteId),
|
|
642
|
+
unique('kywi_audiences_site_priority_uniq').on(t.siteId, t.priority),
|
|
643
|
+
]);
|
|
644
|
+
export const kywiConditionGroupsMysql = mysqlTable('kywi_condition_groups', {
|
|
645
|
+
id: mysqlUuidPk(),
|
|
646
|
+
audienceId: mysqlUuid('audience_id').notNull().references(() => kywiAudiencesMysql.id, { onDelete: 'cascade' }),
|
|
647
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
355
648
|
});
|
|
649
|
+
export const kywiConditionsMysql = mysqlTable('kywi_conditions', {
|
|
650
|
+
id: mysqlUuidPk(),
|
|
651
|
+
groupId: mysqlUuid('group_id').notNull().references(() => kywiConditionGroupsMysql.id, { onDelete: 'cascade' }),
|
|
652
|
+
type: varchar('type', { length: 20 }).notNull(),
|
|
653
|
+
signal: text('signal'),
|
|
654
|
+
operator: text('operator'),
|
|
655
|
+
value: json('value'),
|
|
656
|
+
// `trigger` is a MySQL reserved word; drizzle backtick-quotes every
|
|
657
|
+
// identifier it emits, so the column name needs no rename.
|
|
658
|
+
trigger: text('trigger'),
|
|
659
|
+
points: int('points'),
|
|
660
|
+
threshold: int('threshold'),
|
|
661
|
+
category: text('category'),
|
|
662
|
+
pattern: text('pattern'),
|
|
663
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
664
|
+
});
|
|
665
|
+
export const kywiSelfIdFieldsMysql = mysqlTable('kywi_selfid_fields', {
|
|
666
|
+
// pg: `text PRIMARY KEY` (a caller-supplied field key, not a uuid).
|
|
667
|
+
id: varchar('id', { length: 255 }).primaryKey(),
|
|
668
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
669
|
+
label: text('label').notNull(),
|
|
670
|
+
picklist: json('picklist').notNull(),
|
|
671
|
+
required: boolean('required').notNull().default(false),
|
|
672
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
673
|
+
});
|
|
674
|
+
export const kywiSelfIdWidgetConfigMysql = mysqlTable('kywi_selfid_widget_config', {
|
|
675
|
+
id: mysqlUuidPk(),
|
|
676
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
677
|
+
displayMode: varchar('display_mode', { length: 20 }).notNull().default('modal'),
|
|
678
|
+
trigger: json('trigger').notNull(),
|
|
679
|
+
headline: text('headline').notNull(),
|
|
680
|
+
subheadline: text('subheadline'),
|
|
681
|
+
fieldIds: json('field_ids').notNull(),
|
|
682
|
+
// pg: `text NOT NULL DEFAULT 'Submit'` — narrowed to carry the default.
|
|
683
|
+
submitLabel: varchar('submit_label', { length: 100 }).notNull().default('Submit'),
|
|
684
|
+
skipLabel: text('skip_label'),
|
|
685
|
+
frequency: varchar('frequency', { length: 20 }).notNull().default('once_visitor'),
|
|
686
|
+
});
|
|
687
|
+
export const kywiPreviewTokenDenylistMysql = mysqlTable('kywi_preview_token_denylist', {
|
|
688
|
+
// pg: `text PRIMARY KEY` — a JWT jti.
|
|
689
|
+
jti: varchar('jti', { length: 255 }).primaryKey(),
|
|
690
|
+
audienceId: mysqlUuid('audience_id').notNull(),
|
|
691
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
692
|
+
revokedAt: mysqlTs('revoked_at').notNull().default(mysqlNow()),
|
|
693
|
+
});
|
|
694
|
+
export const kywiAdapterIdentityStoreMysql = mysqlTable('kywi_adapter_identity_store', {
|
|
695
|
+
id: mysqlUuidPk(),
|
|
696
|
+
// pg: `text`, but both columns form a UNIQUE index — narrowed so MySQL can
|
|
697
|
+
// index them without a prefix length.
|
|
698
|
+
visitorId: varchar('visitor_id', { length: 255 }).notNull(),
|
|
699
|
+
adapterId: varchar('adapter_id', { length: 100 }).notNull(),
|
|
700
|
+
payload: json('payload').notNull(),
|
|
701
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
702
|
+
}, (t) => [
|
|
703
|
+
unique('kywi_adapter_identity_visitor_adapter_uniq').on(t.visitorId, t.adapterId),
|
|
704
|
+
]);
|
|
705
|
+
// ── webhooks.ts ──────────────────────────────────────────────────────────────
|
|
706
|
+
export const kywiWebhookEndpointsMysql = mysqlTable('kywi_webhook_endpoints', {
|
|
707
|
+
id: mysqlUuidPk(),
|
|
708
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
709
|
+
url: text('url').notNull(),
|
|
710
|
+
secret: text('secret').notNull(),
|
|
711
|
+
events: json('events').notNull().default(mysqlJsonDefault('[]')),
|
|
712
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
713
|
+
createdBy: mysqlUuid('created_by'),
|
|
714
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
715
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
716
|
+
});
|
|
717
|
+
export const kywiWebhookDeliveriesMysql = mysqlTable('kywi_webhook_deliveries', {
|
|
718
|
+
id: mysqlUuidPk(),
|
|
719
|
+
endpointId: mysqlUuid('endpoint_id').notNull().references(() => kywiWebhookEndpointsMysql.id, { onDelete: 'cascade' }),
|
|
720
|
+
event: varchar('event', { length: 100 }).notNull(),
|
|
721
|
+
payload: json('payload').notNull(),
|
|
722
|
+
status: varchar('status', { length: 20 }).notNull().default('pending'),
|
|
723
|
+
httpStatus: int('http_status'),
|
|
724
|
+
responseBody: text('response_body'),
|
|
725
|
+
attempts: int('attempts').notNull().default(0),
|
|
726
|
+
nextRetryAt: mysqlTs('next_retry_at'),
|
|
727
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
728
|
+
});
|
|
729
|
+
// ── extensions.ts ────────────────────────────────────────────────────────────
|
|
730
|
+
export const kywiExtendSubtypesMysql = mysqlTable('kywi_extend_subtypes', {
|
|
731
|
+
id: mysqlUuidPk(),
|
|
732
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
733
|
+
baseContentType: varchar('base_content_type', { length: 100 }).notNull(),
|
|
734
|
+
description: text('description'),
|
|
735
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
736
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
737
|
+
});
|
|
738
|
+
export const kywiExtendSetsMysql = mysqlTable('kywi_extend_sets', {
|
|
739
|
+
id: mysqlUuidPk(),
|
|
740
|
+
subtypeId: mysqlUuid('subtype_id').notNull().references(() => kywiExtendSubtypesMysql.id, { onDelete: 'cascade' }),
|
|
741
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
742
|
+
label: varchar('label', { length: 200 }).notNull(),
|
|
743
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
744
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
745
|
+
});
|
|
746
|
+
export const kywiExtendAttributesMysql = mysqlTable('kywi_extend_attributes', {
|
|
747
|
+
id: mysqlUuidPk(),
|
|
748
|
+
setId: mysqlUuid('set_id').notNull().references(() => kywiExtendSetsMysql.id, { onDelete: 'cascade' }),
|
|
749
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
750
|
+
label: varchar('label', { length: 200 }).notNull(),
|
|
751
|
+
type: varchar('type', { length: 50 }).notNull(),
|
|
752
|
+
defaultValue: text('default_value'),
|
|
753
|
+
validation: json('validation'),
|
|
754
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
755
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
756
|
+
});
|
|
757
|
+
export const kywiExtendDataMysql = mysqlTable('kywi_extend_data', {
|
|
758
|
+
id: mysqlUuidPk(),
|
|
759
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
760
|
+
attributeId: mysqlUuid('attribute_id').notNull().references(() => kywiExtendAttributesMysql.id, { onDelete: 'cascade' }),
|
|
761
|
+
stringValue: text('string_value'),
|
|
762
|
+
numberValue: decimal('number_value', { precision: 20, scale: 6 }),
|
|
763
|
+
dateValue: mysqlTs('date_value'),
|
|
764
|
+
booleanValue: boolean('boolean_value'),
|
|
765
|
+
jsonValue: json('json_value'),
|
|
766
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
767
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
768
|
+
});
|
|
769
|
+
export const kywiExtendRelatedSetsMysql = mysqlTable('kywi_extend_related_sets', {
|
|
770
|
+
id: mysqlUuidPk(),
|
|
771
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
772
|
+
setId: mysqlUuid('set_id').notNull().references(() => kywiExtendSetsMysql.id, { onDelete: 'cascade' }),
|
|
773
|
+
data: json('data').notNull(),
|
|
774
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
775
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
776
|
+
});
|
|
777
|
+
// ── reminders.ts ─────────────────────────────────────────────────────────────
|
|
778
|
+
export const kywiRemindersMysql = mysqlTable('kywi_reminders', {
|
|
779
|
+
id: mysqlUuidPk(),
|
|
780
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
781
|
+
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
782
|
+
message: text('message').notNull(),
|
|
783
|
+
remindAt: mysqlTs('remind_at').notNull(),
|
|
784
|
+
dismissed: boolean('dismissed').notNull().default(false),
|
|
785
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
786
|
+
});
|
|
787
|
+
// ── components.ts ────────────────────────────────────────────────────────────
|
|
788
|
+
export const kywiComponentsMysql = mysqlTable('kywi_components', {
|
|
789
|
+
id: mysqlUuidPk(),
|
|
790
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
791
|
+
name: text('name').notNull(),
|
|
792
|
+
description: text('description'),
|
|
793
|
+
// Widened with its Postgres twin (kywi-cms#170) — `'moduleVariantContainer'`
|
|
794
|
+
// is 22 characters and did not fit the old 20.
|
|
795
|
+
type: varchar('type', { length: 40 }).notNull(),
|
|
796
|
+
moduleType: varchar('module_type', { length: 100 }),
|
|
797
|
+
definition: json('definition').notNull(),
|
|
798
|
+
createdBy: mysqlUuid('created_by'),
|
|
799
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
800
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
801
|
+
});
|
|
802
|
+
/**
|
|
803
|
+
* Holder-polymorphic since kywi-cms#156 — see the Postgres table's doc.
|
|
804
|
+
*
|
|
805
|
+
* The two placement indexes are the one place the twin reads differently from
|
|
806
|
+
* Postgres and means the same thing. Postgres declares them PARTIAL (`WHERE
|
|
807
|
+
* content_id IS NOT NULL`); MySQL has no partial indexes, but it does not need
|
|
808
|
+
* one here: a UNIQUE index ignores rows whose indexed columns include a NULL in
|
|
809
|
+
* both engines, so a plain `UNIQUE (component_id, content_id, node_id)` already
|
|
810
|
+
* constrains exactly the content rows and lets every blueprint row (content_id
|
|
811
|
+
* NULL) through — which is precisely what the partial index says out loud. This
|
|
812
|
+
* is NOT the `kywi_content_permissions` situation, where uniqueness genuinely
|
|
813
|
+
* could not be expressed and fell back to the application.
|
|
814
|
+
*
|
|
815
|
+
* The one-holder CHECK — which also ties `holder_kind` to whichever id column
|
|
816
|
+
* is set — is expressible directly: MySQL 8.0.16+ enforces table CHECK
|
|
817
|
+
* constraints. Older MySQL parses and ignores it, so on those versions the
|
|
818
|
+
* invariant rests on the query layer, which never writes another shape.
|
|
819
|
+
*/
|
|
820
|
+
export const kywiComponentInstancesMysql = mysqlTable('kywi_component_instances', {
|
|
821
|
+
id: mysqlUuidPk(),
|
|
822
|
+
componentId: mysqlUuid('component_id').notNull().references(() => kywiComponentsMysql.id, { onDelete: 'cascade' }),
|
|
823
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
824
|
+
holderKind: varchar('holder_kind', { length: 20 }).notNull().default('content'),
|
|
825
|
+
contentId: mysqlUuid('content_id').references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
826
|
+
blueprintId: mysqlUuid('blueprint_id').references(() => kywiSectionTemplatesMysql.id, { onDelete: 'cascade' }),
|
|
827
|
+
contentType: varchar('content_type', { length: 100 }).notNull(),
|
|
828
|
+
// pg: `text`, but it is the third column of the placement UNIQUE index —
|
|
829
|
+
// MySQL cannot index TEXT without a prefix length, so the twin narrows it.
|
|
830
|
+
nodeId: varchar('node_id', { length: 255 }).notNull(),
|
|
831
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
832
|
+
}, (t) => [
|
|
833
|
+
unique('kywi_component_instances_placement').on(t.componentId, t.contentId, t.nodeId),
|
|
834
|
+
unique('kywi_component_instances_blueprint_placement').on(t.componentId, t.blueprintId, t.nodeId),
|
|
835
|
+
index('kywi_component_instances_by_content').on(t.contentId),
|
|
836
|
+
index('kywi_component_instances_by_blueprint').on(t.blueprintId),
|
|
837
|
+
check('kywi_component_instances_one_holder', sql `(${t.holderKind} = 'content' and ${t.contentId} is not null and ${t.blueprintId} is null)
|
|
838
|
+
or (${t.holderKind} = 'blueprint' and ${t.blueprintId} is not null and ${t.contentId} is null)`),
|
|
839
|
+
]);
|
|
840
|
+
// ── comment-subscriptions.ts ─────────────────────────────────────────────────
|
|
841
|
+
export const kywiCommentSubscriptionsMysql = mysqlTable('kywi_comment_subscriptions', {
|
|
842
|
+
id: mysqlUuidPk(),
|
|
843
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
844
|
+
email: text('email').notNull(),
|
|
845
|
+
userId: mysqlUuid('user_id').references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
846
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
847
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
848
|
+
});
|
|
849
|
+
// ── content-permissions.ts ───────────────────────────────────────────────────
|
|
850
|
+
/**
|
|
851
|
+
* The one place a Postgres construct has **no** MySQL equivalent.
|
|
852
|
+
*
|
|
853
|
+
* The Postgres table carries two PARTIAL unique indexes — `unique(content_id,
|
|
854
|
+
* user_id, action) WHERE group_id IS NULL` and its group-side mirror — because
|
|
855
|
+
* a grant row always has exactly one of user_id/group_id set, and `NULL !=
|
|
856
|
+
* NULL` for uniqueness in both dialects, so a plain four-column unique cannot
|
|
857
|
+
* express "no duplicate grant".
|
|
858
|
+
*
|
|
859
|
+
* MySQL has no partial indexes. The twin therefore declares the same two column
|
|
860
|
+
* tuples as PLAIN (non-unique) indexes: they still serve the read path that
|
|
861
|
+
* matters — `access-control.ts`'s permission check and the permissions-tab
|
|
862
|
+
* listing — but uniqueness is left to the application:
|
|
863
|
+
*
|
|
864
|
+
* - `grantContentPermission` (db/content-permission-queries.ts) checks for an
|
|
865
|
+
* existing identical grant before inserting, and
|
|
866
|
+
* - `kywi migrate` runs `dedupeContentPermissionRows` for existing databases.
|
|
867
|
+
*
|
|
868
|
+
* A MySQL 8 alternative would be a unique index over generated columns
|
|
869
|
+
* (`COALESCE(user_id, '-')`), which drizzle's mysql-core cannot declare today;
|
|
870
|
+
* it is recorded as a follow-up rather than hand-written DDL here.
|
|
871
|
+
*/
|
|
872
|
+
export const kywiContentPermissionsMysql = mysqlTable('kywi_content_permissions', {
|
|
873
|
+
id: mysqlUuidPk(),
|
|
874
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
875
|
+
userId: mysqlUuid('user_id').references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
876
|
+
groupId: mysqlUuid('group_id').references(() => kywiGroupsMysql.id, { onDelete: 'cascade' }),
|
|
877
|
+
action: varchar('action', { length: 20 }).notNull(),
|
|
878
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
879
|
+
}, (t) => [
|
|
880
|
+
index('kywi_content_permissions_user_grant').on(t.contentId, t.userId, t.action),
|
|
881
|
+
index('kywi_content_permissions_group_grant').on(t.contentId, t.groupId, t.action),
|
|
882
|
+
]);
|
|
883
|
+
// ── content-references.ts ────────────────────────────────────────────────────
|
|
884
|
+
export const kywiContentReferencesMysql = mysqlTable('kywi_content_references', {
|
|
885
|
+
id: mysqlUuidPk(),
|
|
886
|
+
sourceSiteId: mysqlUuid('source_site_id').notNull().references(() => kywiSitesMysql.id),
|
|
887
|
+
sourceContentId: mysqlUuid('source_content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
888
|
+
targetSiteId: mysqlUuid('target_site_id').notNull().references(() => kywiSitesMysql.id),
|
|
889
|
+
targetContentId: mysqlUuid('target_content_id').notNull().references(() => kywiContentMysql.id),
|
|
890
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
891
|
+
});
|
|
892
|
+
// ── relationships.ts ─────────────────────────────────────────────────────────
|
|
893
|
+
export const kywiContentRelationshipsMysql = mysqlTable('kywi_content_relationships', {
|
|
894
|
+
id: mysqlUuidPk(),
|
|
895
|
+
sourceId: mysqlUuid('source_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
896
|
+
targetId: mysqlUuid('target_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
897
|
+
type: varchar('type', { length: 50 }).notNull().default('related'),
|
|
898
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
899
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
900
|
+
});
|
|
901
|
+
// ── password-reset-tokens.ts ─────────────────────────────────────────────────
|
|
902
|
+
export const kywiPasswordResetTokensMysql = mysqlTable('kywi_password_reset_tokens', {
|
|
903
|
+
id: mysqlUuidPk(),
|
|
904
|
+
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
905
|
+
tokenHash: text('token_hash').notNull(),
|
|
906
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
907
|
+
usedAt: mysqlTs('used_at'),
|
|
908
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
909
|
+
});
|
|
910
|
+
// ── site-plugins.ts ──────────────────────────────────────────────────────────
|
|
911
|
+
export const kywiSitePluginsMysql = mysqlTable('kywi_site_plugins', {
|
|
912
|
+
id: mysqlUuidPk(),
|
|
913
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
914
|
+
pluginPackage: varchar('plugin_package', { length: 200 }).notNull(),
|
|
915
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
916
|
+
config: json('config'),
|
|
917
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
918
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
919
|
+
});
|
|
920
|
+
// ── site-settings.ts ─────────────────────────────────────────────────────────
|
|
921
|
+
export const kywiSiteSettingsMysql = mysqlTable('kywi_site_settings', {
|
|
922
|
+
id: mysqlUuidPk(),
|
|
923
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
924
|
+
// `key` is a MySQL reserved word; drizzle backtick-quotes identifiers.
|
|
925
|
+
key: varchar('key', { length: 100 }).notNull(),
|
|
926
|
+
value: json('value').notNull(),
|
|
927
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
928
|
+
}, (t) => [
|
|
929
|
+
unique('kywi_site_settings_site_id_key_unique').on(t.siteId, t.key),
|
|
930
|
+
]);
|
|
356
931
|
//# sourceMappingURL=mysql-tables.js.map
|