@kywi-software/core 0.14.0 → 0.15.1
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 +200 -17
- package/README.md +38 -12
- package/dist/admin/audience-editor.d.ts +2 -0
- package/dist/admin/audience-editor.d.ts.map +1 -1
- package/dist/admin/audience-editor.js +4 -2
- package/dist/admin/audience-editor.js.map +1 -1
- package/dist/admin/chrome.d.ts.map +1 -1
- package/dist/admin/chrome.js +6 -7
- package/dist/admin/chrome.js.map +1 -1
- package/dist/admin/condition-builder.d.ts.map +1 -1
- package/dist/admin/condition-builder.js +16 -3
- package/dist/admin/condition-builder.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/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 +12 -0
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +12 -0
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/rule-tester.d.ts +1 -0
- package/dist/admin/rule-tester.d.ts.map +1 -1
- package/dist/admin/rule-tester.js +7 -4
- package/dist/admin/rule-tester.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/signal-options.d.ts +17 -0
- package/dist/admin/signal-options.d.ts.map +1 -1
- package/dist/admin/signal-options.js +28 -0
- package/dist/admin/signal-options.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/audiences/audiences-data.d.ts +5 -0
- package/dist/admin/surfaces/audiences/audiences-data.d.ts.map +1 -1
- package/dist/admin/surfaces/audiences/audiences-data.js +3 -0
- package/dist/admin/surfaces/audiences/audiences-data.js.map +1 -1
- 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/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/users/users-data.d.ts +14 -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 +40 -4
- 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 +8 -5
- package/dist/admin/surfaces/users/users-new.js.map +1 -1
- package/dist/admin/user-form.d.ts +10 -1
- package/dist/admin/user-form.d.ts.map +1 -1
- package/dist/admin/user-form.js +2 -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/api-key-routes.js +2 -2
- package/dist/api/api-key-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 +31 -19
- package/dist/api/audience-routes.js.map +1 -1
- package/dist/api/audience-runtime-routes.d.ts +23 -0
- package/dist/api/audience-runtime-routes.d.ts.map +1 -1
- package/dist/api/audience-runtime-routes.js +511 -25
- 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 +10 -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/ax-routes.d.ts.map +1 -1
- package/dist/api/ax-routes.js +7 -3
- package/dist/api/ax-routes.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 +6 -6
- package/dist/api/category-routes.js.map +1 -1
- package/dist/api/changeset-routes.js +2 -2
- package/dist/api/changeset-routes.js.map +1 -1
- package/dist/api/comment-routes.js +12 -12
- 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 +44 -19
- package/dist/api/component-routes.js.map +1 -1
- package/dist/api/config-routes.js +4 -4
- package/dist/api/config-routes.js.map +1 -1
- package/dist/api/content-permission-routes.js +2 -2
- package/dist/api/content-permission-routes.js.map +1 -1
- package/dist/api/content-routes.d.ts.map +1 -1
- package/dist/api/content-routes.js +21 -16
- package/dist/api/content-routes.js.map +1 -1
- package/dist/api/content-type-routes.js +3 -3
- package/dist/api/content-type-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 +10 -10
- 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/extension-routes.js +4 -4
- package/dist/api/extension-routes.js.map +1 -1
- package/dist/api/feed-routes.d.ts +2 -2
- package/dist/api/feed-routes.js +5 -5
- package/dist/api/feed-routes.js.map +1 -1
- package/dist/api/form-routes.js +6 -6
- 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 +9 -9
- package/dist/api/group-routes.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +43 -7
- package/dist/api/index.js.map +1 -1
- package/dist/api/layout-routes.d.ts +19 -1
- package/dist/api/layout-routes.d.ts.map +1 -1
- package/dist/api/layout-routes.js +92 -8
- package/dist/api/layout-routes.js.map +1 -1
- package/dist/api/layout-write-guard.d.ts +3 -2
- package/dist/api/layout-write-guard.d.ts.map +1 -1
- package/dist/api/layout-write-guard.js +12 -4
- package/dist/api/layout-write-guard.js.map +1 -1
- package/dist/api/media-routes.d.ts.map +1 -1
- package/dist/api/media-routes.js +100 -35
- 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 +46 -12
- 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 +25 -4
- package/dist/api/nav-routes.js.map +1 -1
- package/dist/api/oauth-routes.js +2 -2
- package/dist/api/oauth-routes.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +82 -34
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/pagination.d.ts +10 -0
- package/dist/api/pagination.d.ts.map +1 -1
- package/dist/api/pagination.js +7 -1
- package/dist/api/pagination.js.map +1 -1
- package/dist/api/response.d.ts +29 -0
- package/dist/api/response.d.ts.map +1 -1
- package/dist/api/response.js +23 -3
- package/dist/api/response.js.map +1 -1
- package/dist/api/search-routes.d.ts.map +1 -1
- package/dist/api/search-routes.js +19 -5
- 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 +37 -20
- 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/site-routes.js +2 -2
- package/dist/api/site-routes.js.map +1 -1
- package/dist/api/tag-routes.d.ts.map +1 -1
- package/dist/api/tag-routes.js +5 -5
- 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.map +1 -1
- package/dist/api/user-routes.js +136 -21
- package/dist/api/user-routes.js.map +1 -1
- package/dist/api/version-routes.js +2 -2
- package/dist/api/version-routes.js.map +1 -1
- package/dist/api/webhook-routes.js +8 -8
- package/dist/api/webhook-routes.js.map +1 -1
- package/dist/api/workflow-routes.d.ts.map +1 -1
- package/dist/api/workflow-routes.js +23 -14
- 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 +16 -2
- package/dist/audiences/collectors/index.d.ts.map +1 -1
- package/dist/audiences/collectors/index.js +29 -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/selfid.d.ts +25 -0
- package/dist/audiences/collectors/selfid.d.ts.map +1 -0
- package/dist/audiences/collectors/selfid.js +46 -0
- package/dist/audiences/collectors/selfid.js.map +1 -0
- package/dist/audiences/collectors/session.d.ts +41 -0
- package/dist/audiences/collectors/session.d.ts.map +1 -0
- package/dist/audiences/collectors/session.js +50 -0
- package/dist/audiences/collectors/session.js.map +1 -0
- 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 +205 -0
- package/dist/audiences/consent.d.ts.map +1 -0
- package/dist/audiences/consent.js +335 -0
- package/dist/audiences/consent.js.map +1 -0
- package/dist/audiences/cookies.d.ts +21 -0
- package/dist/audiences/cookies.d.ts.map +1 -1
- package/dist/audiences/cookies.js +26 -0
- package/dist/audiences/cookies.js.map +1 -1
- package/dist/audiences/engine.d.ts +7 -0
- package/dist/audiences/engine.d.ts.map +1 -1
- package/dist/audiences/engine.js +7 -2
- package/dist/audiences/engine.js.map +1 -1
- package/dist/audiences/entry-page.d.ts +89 -0
- package/dist/audiences/entry-page.d.ts.map +1 -0
- package/dist/audiences/entry-page.js +116 -0
- package/dist/audiences/entry-page.js.map +1 -0
- package/dist/audiences/evaluator/instant-match.d.ts.map +1 -1
- package/dist/audiences/evaluator/instant-match.js +7 -0
- package/dist/audiences/evaluator/instant-match.js.map +1 -1
- package/dist/audiences/index.d.ts +6 -2
- package/dist/audiences/index.d.ts.map +1 -1
- package/dist/audiences/index.js +12 -2
- package/dist/audiences/index.js.map +1 -1
- package/dist/audiences/queries.d.ts +16 -0
- package/dist/audiences/queries.d.ts.map +1 -1
- package/dist/audiences/queries.js +28 -1
- package/dist/audiences/queries.js.map +1 -1
- package/dist/audiences/schema.d.ts +17 -0
- package/dist/audiences/schema.d.ts.map +1 -1
- package/dist/audiences/schema.js +7 -0
- package/dist/audiences/schema.js.map +1 -1
- package/dist/audiences/server-eval.d.ts +32 -1
- package/dist/audiences/server-eval.d.ts.map +1 -1
- package/dist/audiences/server-eval.js +35 -3
- 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/types.d.ts +22 -1
- package/dist/audiences/types.d.ts.map +1 -1
- package/dist/audiences/types.js +1 -0
- package/dist/audiences/types.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/ax/content-source.d.ts +10 -2
- package/dist/ax/content-source.d.ts.map +1 -1
- package/dist/ax/content-source.js +81 -5
- package/dist/ax/content-source.js.map +1 -1
- package/dist/ax/effective-body.d.ts +28 -0
- package/dist/ax/effective-body.d.ts.map +1 -0
- package/dist/ax/effective-body.js +47 -0
- package/dist/ax/effective-body.js.map +1 -0
- package/dist/ax/index.d.ts +3 -1
- package/dist/ax/index.d.ts.map +1 -1
- package/dist/ax/index.js +2 -0
- package/dist/ax/index.js.map +1 -1
- package/dist/ax/jsonld.d.ts +31 -1
- package/dist/ax/jsonld.d.ts.map +1 -1
- package/dist/ax/jsonld.js +35 -22
- package/dist/ax/jsonld.js.map +1 -1
- package/dist/ax/layout-to-html.d.ts +127 -0
- package/dist/ax/layout-to-html.d.ts.map +1 -0
- package/dist/ax/layout-to-html.js +545 -0
- package/dist/ax/layout-to-html.js.map +1 -0
- package/dist/ax/llms-full-txt.d.ts +3 -1
- package/dist/ax/llms-full-txt.d.ts.map +1 -1
- package/dist/ax/llms-full-txt.js +5 -2
- package/dist/ax/llms-full-txt.js.map +1 -1
- package/dist/ax/page-markdown.d.ts +10 -2
- package/dist/ax/page-markdown.d.ts.map +1 -1
- package/dist/ax/page-markdown.js +16 -3
- package/dist/ax/page-markdown.js.map +1 -1
- package/dist/ax/summary.d.ts +4 -0
- package/dist/ax/summary.d.ts.map +1 -1
- package/dist/ax/summary.js +6 -1
- package/dist/ax/summary.js.map +1 -1
- package/dist/ax/types.d.ts +24 -0
- package/dist/ax/types.d.ts.map +1 -1
- package/dist/cache/content-invalidation.d.ts.map +1 -1
- package/dist/cache/content-invalidation.js +11 -0
- package/dist/cache/content-invalidation.js.map +1 -1
- package/dist/config/types.d.ts +43 -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 +25 -0
- package/dist/db/apply-snapshot.d.ts.map +1 -1
- package/dist/db/apply-snapshot.js +48 -16
- package/dist/db/apply-snapshot.js.map +1 -1
- package/dist/db/ax-queries.d.ts +6 -0
- package/dist/db/ax-queries.d.ts.map +1 -1
- package/dist/db/ax-queries.js +6 -0
- package/dist/db/ax-queries.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 +9 -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 +21 -3
- package/dist/db/layout-queries.d.ts.map +1 -1
- package/dist/db/layout-queries.js +14 -6
- 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/search-queries.d.ts.map +1 -1
- package/dist/db/search-queries.js +24 -1
- package/dist/db/search-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/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/hooks/ax-invalidation.d.ts.map +1 -1
- package/dist/hooks/ax-invalidation.js +4 -0
- package/dist/hooks/ax-invalidation.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 +7 -4
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +6 -3
- 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 +26 -38
- 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/seed-defaults.d.ts +45 -0
- package/dist/layout/seed-defaults.d.ts.map +1 -0
- package/dist/layout/seed-defaults.js +75 -0
- package/dist/layout/seed-defaults.js.map +1 -0
- 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/layout/walk.d.ts +14 -0
- package/dist/layout/walk.d.ts.map +1 -0
- package/dist/layout/walk.js +49 -0
- package/dist/layout/walk.js.map +1 -0
- package/dist/media/index.d.ts +1 -1
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.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/media/upload-allowlist.d.ts +23 -0
- package/dist/media/upload-allowlist.d.ts.map +1 -1
- package/dist/media/upload-allowlist.js +29 -0
- package/dist/media/upload-allowlist.js.map +1 -1
- 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 +24 -4
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +17 -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 +622 -46
- package/dist/schema/mysql-tables.js.map +1 -1
- package/dist/scope/jsonld.d.ts +18 -3
- package/dist/scope/jsonld.d.ts.map +1 -1
- package/dist/scope/jsonld.js +6 -4
- package/dist/scope/jsonld.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 +12 -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'),
|
|
@@ -132,7 +193,7 @@ export const kywiGroupsMysql = mysqlTable('kywi_groups', {
|
|
|
132
193
|
name: text('name').notNull(),
|
|
133
194
|
type: varchar('type', { length: 20 }).notNull().default('private'),
|
|
134
195
|
defaultRole: varchar('default_role', { length: 20 }).notNull().default('reader'),
|
|
135
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
196
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
136
197
|
});
|
|
137
198
|
// ── kywiUserGroupsMysql ─────────────────────────────────────────────────────
|
|
138
199
|
// #40: unique(userId, groupId) — see the matching note on kywiUserGroups in
|
|
@@ -149,9 +210,9 @@ export const kywiApiKeysMysql = mysqlTable('kywi_api_keys', {
|
|
|
149
210
|
name: text('name').notNull(),
|
|
150
211
|
keyHash: text('key_hash').notNull(),
|
|
151
212
|
keyPrefix: varchar('key_prefix', { length: 12 }).notNull(),
|
|
152
|
-
scopes: json('scopes').notNull(),
|
|
213
|
+
scopes: json('scopes').notNull().default(mysqlJsonDefault('[]')),
|
|
153
214
|
lastUsedAt: mysqlTs('last_used_at'),
|
|
154
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
215
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
155
216
|
});
|
|
156
217
|
// ── kywiSiteMembershipsMysql ────────────────────────────────────────────────
|
|
157
218
|
// #40: unique(userId, siteId) — see the matching note on kywiSiteMemberships
|
|
@@ -161,8 +222,8 @@ export const kywiApiKeysMysql = mysqlTable('kywi_api_keys', {
|
|
|
161
222
|
export const kywiSiteMembershipsMysql = mysqlTable('kywi_site_memberships', {
|
|
162
223
|
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
163
224
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
164
|
-
groups: json('groups').notNull(),
|
|
165
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
225
|
+
groups: json('groups').notNull().default(mysqlJsonDefault('[]')),
|
|
226
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
166
227
|
}, (t) => [unique().on(t.userId, t.siteId)]);
|
|
167
228
|
// ── kywiMediaMysql ──────────────────────────────────────────────────────────
|
|
168
229
|
export const kywiMediaMysql = mysqlTable('kywi_media', {
|
|
@@ -181,8 +242,8 @@ export const kywiMediaMysql = mysqlTable('kywi_media', {
|
|
|
181
242
|
uploadedBy: mysqlUuid('uploaded_by'),
|
|
182
243
|
storageKey: text('storage_key').notNull(),
|
|
183
244
|
deletedAt: mysqlTs('deleted_at'),
|
|
184
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
185
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
245
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
246
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
186
247
|
});
|
|
187
248
|
// ── kywiFormSubmissionsMysql ────────────────────────────────────────────────
|
|
188
249
|
export const kywiFormSubmissionsMysql = mysqlTable('kywi_form_submissions', {
|
|
@@ -190,7 +251,7 @@ export const kywiFormSubmissionsMysql = mysqlTable('kywi_form_submissions', {
|
|
|
190
251
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
191
252
|
formContentId: mysqlUuid('form_content_id').notNull(),
|
|
192
253
|
data: json('data').notNull(),
|
|
193
|
-
submittedAt: mysqlTs('submitted_at').notNull(),
|
|
254
|
+
submittedAt: mysqlTs('submitted_at').notNull().default(mysqlNow()),
|
|
194
255
|
ipAddress: varchar('ip_address', { length: 45 }),
|
|
195
256
|
status: varchar('status', { length: 20 }).notNull().default('new'),
|
|
196
257
|
});
|
|
@@ -204,7 +265,7 @@ export const kywiContentVersionsMysql = mysqlTable('kywi_content_versions', {
|
|
|
204
265
|
changeNote: text('change_note'),
|
|
205
266
|
status: varchar('status', { length: 20 }).notNull(),
|
|
206
267
|
createdBy: mysqlUuid('created_by'),
|
|
207
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
268
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
208
269
|
});
|
|
209
270
|
// ── kywiCategoriesMysql ─────────────────────────────────────────────────────
|
|
210
271
|
export const kywiCategoriesMysql = mysqlTable('kywi_categories', {
|
|
@@ -218,8 +279,8 @@ export const kywiCategoriesMysql = mysqlTable('kywi_categories', {
|
|
|
218
279
|
isActive: boolean('is_active').notNull().default(true),
|
|
219
280
|
isInterestGroup: boolean('is_interest_group').notNull().default(false),
|
|
220
281
|
notes: text('notes'),
|
|
221
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
222
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
282
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
283
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
223
284
|
});
|
|
224
285
|
// ── kywiTagsMysql ───────────────────────────────────────────────────────────
|
|
225
286
|
export const kywiTagsMysql = mysqlTable('kywi_tags', {
|
|
@@ -229,7 +290,7 @@ export const kywiTagsMysql = mysqlTable('kywi_tags', {
|
|
|
229
290
|
label: text('label').notNull(),
|
|
230
291
|
usageCount: int('usage_count').notNull().default(0),
|
|
231
292
|
groupName: varchar('group_name', { length: 100 }),
|
|
232
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
293
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
233
294
|
});
|
|
234
295
|
// ── kywiCommentsMysql ───────────────────────────────────────────────────────
|
|
235
296
|
export const kywiCommentsMysql = mysqlTable('kywi_comments', {
|
|
@@ -242,8 +303,8 @@ export const kywiCommentsMysql = mysqlTable('kywi_comments', {
|
|
|
242
303
|
authorEmail: text('author_email'),
|
|
243
304
|
body: text('body').notNull(),
|
|
244
305
|
status: varchar('status', { length: 20 }).notNull().default('pending'),
|
|
245
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
246
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
306
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
307
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
247
308
|
});
|
|
248
309
|
// ── kywiExperimentsMysql ─────────────────────────────────────────────────────
|
|
249
310
|
export const kywiExperimentsMysql = mysqlTable('kywi_experiments', {
|
|
@@ -262,9 +323,12 @@ export const kywiExperimentsMysql = mysqlTable('kywi_experiments', {
|
|
|
262
323
|
pausedAt: mysqlTs('paused_at'),
|
|
263
324
|
completedAt: mysqlTs('completed_at'),
|
|
264
325
|
createdBy: mysqlUuid('created_by'),
|
|
265
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
266
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
267
|
-
})
|
|
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
|
+
]);
|
|
268
332
|
// ── kywiExperimentVariantsMysql ──────────────────────────────────────────────
|
|
269
333
|
export const kywiExperimentVariantsMysql = mysqlTable('kywi_experiment_variants', {
|
|
270
334
|
id: mysqlUuidPk(),
|
|
@@ -274,18 +338,25 @@ export const kywiExperimentVariantsMysql = mysqlTable('kywi_experiment_variants'
|
|
|
274
338
|
isControl: boolean('is_control').notNull().default(false),
|
|
275
339
|
variantKey: text('variant_key'),
|
|
276
340
|
sortOrder: int('sort_order').notNull().default(0),
|
|
277
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
278
|
-
})
|
|
341
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
342
|
+
}, (t) => [
|
|
343
|
+
index('kywi_experiment_variants_experiment_idx').on(t.experimentId),
|
|
344
|
+
]);
|
|
279
345
|
// ── kywiExperimentAssignmentsMysql ───────────────────────────────────────────
|
|
280
346
|
export const kywiExperimentAssignmentsMysql = mysqlTable('kywi_experiment_assignments', {
|
|
281
347
|
id: mysqlUuidPk(),
|
|
282
348
|
experimentId: mysqlUuid('experiment_id').notNull().references(() => kywiExperimentsMysql.id),
|
|
283
349
|
variantId: mysqlUuid('variant_id').notNull(),
|
|
284
350
|
siteId: mysqlUuid('site_id').notNull(),
|
|
285
|
-
|
|
286
|
-
|
|
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()),
|
|
287
355
|
exposedAt: mysqlTs('exposed_at'),
|
|
288
|
-
})
|
|
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
|
+
]);
|
|
289
360
|
// ── kywiExperimentConversionsMysql ───────────────────────────────────────────
|
|
290
361
|
export const kywiExperimentConversionsMysql = mysqlTable('kywi_experiment_conversions', {
|
|
291
362
|
id: mysqlUuidPk(),
|
|
@@ -295,8 +366,10 @@ export const kywiExperimentConversionsMysql = mysqlTable('kywi_experiment_conver
|
|
|
295
366
|
visitorId: text('visitor_id').notNull(),
|
|
296
367
|
goalType: text('goal_type').notNull(),
|
|
297
368
|
metadata: json('metadata'),
|
|
298
|
-
occurredAt: mysqlTs('occurred_at').notNull(),
|
|
299
|
-
})
|
|
369
|
+
occurredAt: mysqlTs('occurred_at').notNull().default(mysqlNow()),
|
|
370
|
+
}, (t) => [
|
|
371
|
+
index('kywi_experiment_conversions_exp_variant_idx').on(t.experimentId, t.variantId),
|
|
372
|
+
]);
|
|
300
373
|
// ── kywiContentTypeFieldsMysql (hybrid schema engine — admin-added fields) ────
|
|
301
374
|
export const kywiContentTypeFieldsMysql = mysqlTable('kywi_content_type_fields', {
|
|
302
375
|
id: mysqlUuidPk(),
|
|
@@ -313,8 +386,8 @@ export const kywiContentTypeFieldsMysql = mysqlTable('kywi_content_type_fields',
|
|
|
313
386
|
// 'list' fields set it.
|
|
314
387
|
itemType: varchar('item_type', { length: 50 }),
|
|
315
388
|
sortOrder: int('sort_order').notNull().default(0),
|
|
316
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
317
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
389
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
390
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
318
391
|
}, (t) => [unique().on(t.contentTypeName, t.name)]);
|
|
319
392
|
// ── kywiContentTypesMysql (visual type designer — admin-created types) ────────
|
|
320
393
|
export const kywiContentTypesMysql = mysqlTable('kywi_content_types', {
|
|
@@ -326,8 +399,8 @@ export const kywiContentTypesMysql = mysqlTable('kywi_content_types', {
|
|
|
326
399
|
// Whether the Title field is required on this type (kywi-cms#12). Defaults
|
|
327
400
|
// true — back-compat with every type created before this setting existed.
|
|
328
401
|
titleRequired: boolean('title_required').notNull().default(true),
|
|
329
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
330
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
402
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
403
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
331
404
|
});
|
|
332
405
|
// ── kywiMenusMysql (#110 — named owner-manageable navigation menus) ───────────
|
|
333
406
|
export const kywiMenusMysql = mysqlTable('kywi_menus', {
|
|
@@ -335,8 +408,8 @@ export const kywiMenusMysql = mysqlTable('kywi_menus', {
|
|
|
335
408
|
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
336
409
|
slug: varchar('slug', { length: 255 }).notNull(),
|
|
337
410
|
name: text('name').notNull(),
|
|
338
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
339
|
-
updatedAt: mysqlTs('updated_at').notNull(),
|
|
411
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
412
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
340
413
|
}, (t) => [unique().on(t.siteId, t.slug)]);
|
|
341
414
|
// ── kywiMenuItemsMysql (#110) ────────────────────────────────────────────────
|
|
342
415
|
// See the Postgres twin in base.ts for the contentId-XOR-externalUrl rule (it
|
|
@@ -347,11 +420,514 @@ export const kywiMenuItemsMysql = mysqlTable('kywi_menu_items', {
|
|
|
347
420
|
parentId: mysqlUuid('parent_id'),
|
|
348
421
|
sortOrder: int('sort_order').notNull().default(0),
|
|
349
422
|
label: text('label').notNull(),
|
|
350
|
-
|
|
423
|
+
kind: varchar('kind', { length: 20 }).notNull().default('link'),
|
|
424
|
+
contentId: mysqlUuid('content_id').references(() => kywiContentMysql.id, { onDelete: 'set null' }),
|
|
351
425
|
externalUrl: text('external_url'),
|
|
352
426
|
openInNewWindow: boolean('open_in_new_window').notNull().default(false),
|
|
353
427
|
description: text('description'),
|
|
354
|
-
createdAt: mysqlTs('created_at').notNull(),
|
|
355
|
-
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
|
+
// See the Postgres twin: public audience-name listing (kywi-cms#200).
|
|
639
|
+
isPublic: boolean('is_public').notNull().default(false),
|
|
640
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
641
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
642
|
+
}, (t) => [
|
|
643
|
+
index('kywi_audiences_site_idx').on(t.siteId),
|
|
644
|
+
unique('kywi_audiences_site_priority_uniq').on(t.siteId, t.priority),
|
|
645
|
+
]);
|
|
646
|
+
export const kywiConditionGroupsMysql = mysqlTable('kywi_condition_groups', {
|
|
647
|
+
id: mysqlUuidPk(),
|
|
648
|
+
audienceId: mysqlUuid('audience_id').notNull().references(() => kywiAudiencesMysql.id, { onDelete: 'cascade' }),
|
|
649
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
356
650
|
});
|
|
651
|
+
export const kywiConditionsMysql = mysqlTable('kywi_conditions', {
|
|
652
|
+
id: mysqlUuidPk(),
|
|
653
|
+
groupId: mysqlUuid('group_id').notNull().references(() => kywiConditionGroupsMysql.id, { onDelete: 'cascade' }),
|
|
654
|
+
type: varchar('type', { length: 20 }).notNull(),
|
|
655
|
+
signal: text('signal'),
|
|
656
|
+
operator: text('operator'),
|
|
657
|
+
value: json('value'),
|
|
658
|
+
// `trigger` is a MySQL reserved word; drizzle backtick-quotes every
|
|
659
|
+
// identifier it emits, so the column name needs no rename.
|
|
660
|
+
trigger: text('trigger'),
|
|
661
|
+
points: int('points'),
|
|
662
|
+
threshold: int('threshold'),
|
|
663
|
+
category: text('category'),
|
|
664
|
+
pattern: text('pattern'),
|
|
665
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
666
|
+
});
|
|
667
|
+
export const kywiSelfIdFieldsMysql = mysqlTable('kywi_selfid_fields', {
|
|
668
|
+
// pg: `text PRIMARY KEY` (a caller-supplied field key, not a uuid).
|
|
669
|
+
id: varchar('id', { length: 255 }).primaryKey(),
|
|
670
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
671
|
+
label: text('label').notNull(),
|
|
672
|
+
picklist: json('picklist').notNull(),
|
|
673
|
+
required: boolean('required').notNull().default(false),
|
|
674
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
675
|
+
});
|
|
676
|
+
export const kywiSelfIdWidgetConfigMysql = mysqlTable('kywi_selfid_widget_config', {
|
|
677
|
+
id: mysqlUuidPk(),
|
|
678
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
679
|
+
displayMode: varchar('display_mode', { length: 20 }).notNull().default('modal'),
|
|
680
|
+
trigger: json('trigger').notNull(),
|
|
681
|
+
headline: text('headline').notNull(),
|
|
682
|
+
subheadline: text('subheadline'),
|
|
683
|
+
fieldIds: json('field_ids').notNull(),
|
|
684
|
+
// pg: `text NOT NULL DEFAULT 'Submit'` — narrowed to carry the default.
|
|
685
|
+
submitLabel: varchar('submit_label', { length: 100 }).notNull().default('Submit'),
|
|
686
|
+
skipLabel: text('skip_label'),
|
|
687
|
+
frequency: varchar('frequency', { length: 20 }).notNull().default('once_visitor'),
|
|
688
|
+
});
|
|
689
|
+
export const kywiPreviewTokenDenylistMysql = mysqlTable('kywi_preview_token_denylist', {
|
|
690
|
+
// pg: `text PRIMARY KEY` — a JWT jti.
|
|
691
|
+
jti: varchar('jti', { length: 255 }).primaryKey(),
|
|
692
|
+
audienceId: mysqlUuid('audience_id').notNull(),
|
|
693
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
694
|
+
revokedAt: mysqlTs('revoked_at').notNull().default(mysqlNow()),
|
|
695
|
+
});
|
|
696
|
+
export const kywiAdapterIdentityStoreMysql = mysqlTable('kywi_adapter_identity_store', {
|
|
697
|
+
id: mysqlUuidPk(),
|
|
698
|
+
// pg: `text`, but both columns form a UNIQUE index — narrowed so MySQL can
|
|
699
|
+
// index them without a prefix length.
|
|
700
|
+
visitorId: varchar('visitor_id', { length: 255 }).notNull(),
|
|
701
|
+
adapterId: varchar('adapter_id', { length: 100 }).notNull(),
|
|
702
|
+
payload: json('payload').notNull(),
|
|
703
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
704
|
+
}, (t) => [
|
|
705
|
+
unique('kywi_adapter_identity_visitor_adapter_uniq').on(t.visitorId, t.adapterId),
|
|
706
|
+
]);
|
|
707
|
+
// ── webhooks.ts ──────────────────────────────────────────────────────────────
|
|
708
|
+
export const kywiWebhookEndpointsMysql = mysqlTable('kywi_webhook_endpoints', {
|
|
709
|
+
id: mysqlUuidPk(),
|
|
710
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
711
|
+
url: text('url').notNull(),
|
|
712
|
+
secret: text('secret').notNull(),
|
|
713
|
+
events: json('events').notNull().default(mysqlJsonDefault('[]')),
|
|
714
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
715
|
+
createdBy: mysqlUuid('created_by'),
|
|
716
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
717
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
718
|
+
});
|
|
719
|
+
export const kywiWebhookDeliveriesMysql = mysqlTable('kywi_webhook_deliveries', {
|
|
720
|
+
id: mysqlUuidPk(),
|
|
721
|
+
endpointId: mysqlUuid('endpoint_id').notNull().references(() => kywiWebhookEndpointsMysql.id, { onDelete: 'cascade' }),
|
|
722
|
+
event: varchar('event', { length: 100 }).notNull(),
|
|
723
|
+
payload: json('payload').notNull(),
|
|
724
|
+
status: varchar('status', { length: 20 }).notNull().default('pending'),
|
|
725
|
+
httpStatus: int('http_status'),
|
|
726
|
+
responseBody: text('response_body'),
|
|
727
|
+
attempts: int('attempts').notNull().default(0),
|
|
728
|
+
nextRetryAt: mysqlTs('next_retry_at'),
|
|
729
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
730
|
+
});
|
|
731
|
+
// ── extensions.ts ────────────────────────────────────────────────────────────
|
|
732
|
+
export const kywiExtendSubtypesMysql = mysqlTable('kywi_extend_subtypes', {
|
|
733
|
+
id: mysqlUuidPk(),
|
|
734
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
735
|
+
baseContentType: varchar('base_content_type', { length: 100 }).notNull(),
|
|
736
|
+
description: text('description'),
|
|
737
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
738
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
739
|
+
});
|
|
740
|
+
export const kywiExtendSetsMysql = mysqlTable('kywi_extend_sets', {
|
|
741
|
+
id: mysqlUuidPk(),
|
|
742
|
+
subtypeId: mysqlUuid('subtype_id').notNull().references(() => kywiExtendSubtypesMysql.id, { onDelete: 'cascade' }),
|
|
743
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
744
|
+
label: varchar('label', { length: 200 }).notNull(),
|
|
745
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
746
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
747
|
+
});
|
|
748
|
+
export const kywiExtendAttributesMysql = mysqlTable('kywi_extend_attributes', {
|
|
749
|
+
id: mysqlUuidPk(),
|
|
750
|
+
setId: mysqlUuid('set_id').notNull().references(() => kywiExtendSetsMysql.id, { onDelete: 'cascade' }),
|
|
751
|
+
name: varchar('name', { length: 100 }).notNull(),
|
|
752
|
+
label: varchar('label', { length: 200 }).notNull(),
|
|
753
|
+
type: varchar('type', { length: 50 }).notNull(),
|
|
754
|
+
defaultValue: text('default_value'),
|
|
755
|
+
validation: json('validation'),
|
|
756
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
757
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
758
|
+
});
|
|
759
|
+
export const kywiExtendDataMysql = mysqlTable('kywi_extend_data', {
|
|
760
|
+
id: mysqlUuidPk(),
|
|
761
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
762
|
+
attributeId: mysqlUuid('attribute_id').notNull().references(() => kywiExtendAttributesMysql.id, { onDelete: 'cascade' }),
|
|
763
|
+
stringValue: text('string_value'),
|
|
764
|
+
numberValue: decimal('number_value', { precision: 20, scale: 6 }),
|
|
765
|
+
dateValue: mysqlTs('date_value'),
|
|
766
|
+
booleanValue: boolean('boolean_value'),
|
|
767
|
+
jsonValue: json('json_value'),
|
|
768
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
769
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
770
|
+
});
|
|
771
|
+
export const kywiExtendRelatedSetsMysql = mysqlTable('kywi_extend_related_sets', {
|
|
772
|
+
id: mysqlUuidPk(),
|
|
773
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
774
|
+
setId: mysqlUuid('set_id').notNull().references(() => kywiExtendSetsMysql.id, { onDelete: 'cascade' }),
|
|
775
|
+
data: json('data').notNull(),
|
|
776
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
777
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
778
|
+
});
|
|
779
|
+
// ── reminders.ts ─────────────────────────────────────────────────────────────
|
|
780
|
+
export const kywiRemindersMysql = mysqlTable('kywi_reminders', {
|
|
781
|
+
id: mysqlUuidPk(),
|
|
782
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
783
|
+
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
784
|
+
message: text('message').notNull(),
|
|
785
|
+
remindAt: mysqlTs('remind_at').notNull(),
|
|
786
|
+
dismissed: boolean('dismissed').notNull().default(false),
|
|
787
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
788
|
+
});
|
|
789
|
+
// ── components.ts ────────────────────────────────────────────────────────────
|
|
790
|
+
export const kywiComponentsMysql = mysqlTable('kywi_components', {
|
|
791
|
+
id: mysqlUuidPk(),
|
|
792
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
793
|
+
name: text('name').notNull(),
|
|
794
|
+
description: text('description'),
|
|
795
|
+
// Widened with its Postgres twin (kywi-cms#170) — `'moduleVariantContainer'`
|
|
796
|
+
// is 22 characters and did not fit the old 20.
|
|
797
|
+
type: varchar('type', { length: 40 }).notNull(),
|
|
798
|
+
moduleType: varchar('module_type', { length: 100 }),
|
|
799
|
+
definition: json('definition').notNull(),
|
|
800
|
+
createdBy: mysqlUuid('created_by'),
|
|
801
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
802
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
803
|
+
});
|
|
804
|
+
/**
|
|
805
|
+
* Holder-polymorphic since kywi-cms#156 — see the Postgres table's doc.
|
|
806
|
+
*
|
|
807
|
+
* The two placement indexes are the one place the twin reads differently from
|
|
808
|
+
* Postgres and means the same thing. Postgres declares them PARTIAL (`WHERE
|
|
809
|
+
* content_id IS NOT NULL`); MySQL has no partial indexes, but it does not need
|
|
810
|
+
* one here: a UNIQUE index ignores rows whose indexed columns include a NULL in
|
|
811
|
+
* both engines, so a plain `UNIQUE (component_id, content_id, node_id)` already
|
|
812
|
+
* constrains exactly the content rows and lets every blueprint row (content_id
|
|
813
|
+
* NULL) through — which is precisely what the partial index says out loud. This
|
|
814
|
+
* is NOT the `kywi_content_permissions` situation, where uniqueness genuinely
|
|
815
|
+
* could not be expressed and fell back to the application.
|
|
816
|
+
*
|
|
817
|
+
* The one-holder CHECK — which also ties `holder_kind` to whichever id column
|
|
818
|
+
* is set — is expressible directly: MySQL 8.0.16+ enforces table CHECK
|
|
819
|
+
* constraints. Older MySQL parses and ignores it, so on those versions the
|
|
820
|
+
* invariant rests on the query layer, which never writes another shape.
|
|
821
|
+
*/
|
|
822
|
+
export const kywiComponentInstancesMysql = mysqlTable('kywi_component_instances', {
|
|
823
|
+
id: mysqlUuidPk(),
|
|
824
|
+
componentId: mysqlUuid('component_id').notNull().references(() => kywiComponentsMysql.id, { onDelete: 'cascade' }),
|
|
825
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id),
|
|
826
|
+
holderKind: varchar('holder_kind', { length: 20 }).notNull().default('content'),
|
|
827
|
+
contentId: mysqlUuid('content_id').references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
828
|
+
blueprintId: mysqlUuid('blueprint_id').references(() => kywiSectionTemplatesMysql.id, { onDelete: 'cascade' }),
|
|
829
|
+
contentType: varchar('content_type', { length: 100 }).notNull(),
|
|
830
|
+
// pg: `text`, but it is the third column of the placement UNIQUE index —
|
|
831
|
+
// MySQL cannot index TEXT without a prefix length, so the twin narrows it.
|
|
832
|
+
nodeId: varchar('node_id', { length: 255 }).notNull(),
|
|
833
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
834
|
+
}, (t) => [
|
|
835
|
+
unique('kywi_component_instances_placement').on(t.componentId, t.contentId, t.nodeId),
|
|
836
|
+
unique('kywi_component_instances_blueprint_placement').on(t.componentId, t.blueprintId, t.nodeId),
|
|
837
|
+
index('kywi_component_instances_by_content').on(t.contentId),
|
|
838
|
+
index('kywi_component_instances_by_blueprint').on(t.blueprintId),
|
|
839
|
+
check('kywi_component_instances_one_holder', sql `(${t.holderKind} = 'content' and ${t.contentId} is not null and ${t.blueprintId} is null)
|
|
840
|
+
or (${t.holderKind} = 'blueprint' and ${t.blueprintId} is not null and ${t.contentId} is null)`),
|
|
841
|
+
]);
|
|
842
|
+
// ── comment-subscriptions.ts ─────────────────────────────────────────────────
|
|
843
|
+
export const kywiCommentSubscriptionsMysql = mysqlTable('kywi_comment_subscriptions', {
|
|
844
|
+
id: mysqlUuidPk(),
|
|
845
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
846
|
+
email: text('email').notNull(),
|
|
847
|
+
userId: mysqlUuid('user_id').references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
848
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
849
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
850
|
+
});
|
|
851
|
+
// ── content-permissions.ts ───────────────────────────────────────────────────
|
|
852
|
+
/**
|
|
853
|
+
* The one place a Postgres construct has **no** MySQL equivalent.
|
|
854
|
+
*
|
|
855
|
+
* The Postgres table carries two PARTIAL unique indexes — `unique(content_id,
|
|
856
|
+
* user_id, action) WHERE group_id IS NULL` and its group-side mirror — because
|
|
857
|
+
* a grant row always has exactly one of user_id/group_id set, and `NULL !=
|
|
858
|
+
* NULL` for uniqueness in both dialects, so a plain four-column unique cannot
|
|
859
|
+
* express "no duplicate grant".
|
|
860
|
+
*
|
|
861
|
+
* MySQL has no partial indexes. The twin therefore declares the same two column
|
|
862
|
+
* tuples as PLAIN (non-unique) indexes: they still serve the read path that
|
|
863
|
+
* matters — `access-control.ts`'s permission check and the permissions-tab
|
|
864
|
+
* listing — but uniqueness is left to the application:
|
|
865
|
+
*
|
|
866
|
+
* - `grantContentPermission` (db/content-permission-queries.ts) checks for an
|
|
867
|
+
* existing identical grant before inserting, and
|
|
868
|
+
* - `kywi migrate` runs `dedupeContentPermissionRows` for existing databases.
|
|
869
|
+
*
|
|
870
|
+
* A MySQL 8 alternative would be a unique index over generated columns
|
|
871
|
+
* (`COALESCE(user_id, '-')`), which drizzle's mysql-core cannot declare today;
|
|
872
|
+
* it is recorded as a follow-up rather than hand-written DDL here.
|
|
873
|
+
*/
|
|
874
|
+
export const kywiContentPermissionsMysql = mysqlTable('kywi_content_permissions', {
|
|
875
|
+
id: mysqlUuidPk(),
|
|
876
|
+
contentId: mysqlUuid('content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
877
|
+
userId: mysqlUuid('user_id').references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
878
|
+
groupId: mysqlUuid('group_id').references(() => kywiGroupsMysql.id, { onDelete: 'cascade' }),
|
|
879
|
+
action: varchar('action', { length: 20 }).notNull(),
|
|
880
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
881
|
+
}, (t) => [
|
|
882
|
+
index('kywi_content_permissions_user_grant').on(t.contentId, t.userId, t.action),
|
|
883
|
+
index('kywi_content_permissions_group_grant').on(t.contentId, t.groupId, t.action),
|
|
884
|
+
]);
|
|
885
|
+
// ── content-references.ts ────────────────────────────────────────────────────
|
|
886
|
+
export const kywiContentReferencesMysql = mysqlTable('kywi_content_references', {
|
|
887
|
+
id: mysqlUuidPk(),
|
|
888
|
+
sourceSiteId: mysqlUuid('source_site_id').notNull().references(() => kywiSitesMysql.id),
|
|
889
|
+
sourceContentId: mysqlUuid('source_content_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
890
|
+
targetSiteId: mysqlUuid('target_site_id').notNull().references(() => kywiSitesMysql.id),
|
|
891
|
+
targetContentId: mysqlUuid('target_content_id').notNull().references(() => kywiContentMysql.id),
|
|
892
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
893
|
+
});
|
|
894
|
+
// ── relationships.ts ─────────────────────────────────────────────────────────
|
|
895
|
+
export const kywiContentRelationshipsMysql = mysqlTable('kywi_content_relationships', {
|
|
896
|
+
id: mysqlUuidPk(),
|
|
897
|
+
sourceId: mysqlUuid('source_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
898
|
+
targetId: mysqlUuid('target_id').notNull().references(() => kywiContentMysql.id, { onDelete: 'cascade' }),
|
|
899
|
+
type: varchar('type', { length: 50 }).notNull().default('related'),
|
|
900
|
+
sortOrder: int('sort_order').notNull().default(0),
|
|
901
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
902
|
+
});
|
|
903
|
+
// ── password-reset-tokens.ts ─────────────────────────────────────────────────
|
|
904
|
+
export const kywiPasswordResetTokensMysql = mysqlTable('kywi_password_reset_tokens', {
|
|
905
|
+
id: mysqlUuidPk(),
|
|
906
|
+
userId: mysqlUuid('user_id').notNull().references(() => kywiUsersMysql.id, { onDelete: 'cascade' }),
|
|
907
|
+
tokenHash: text('token_hash').notNull(),
|
|
908
|
+
expiresAt: mysqlTs('expires_at').notNull(),
|
|
909
|
+
usedAt: mysqlTs('used_at'),
|
|
910
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
911
|
+
});
|
|
912
|
+
// ── site-plugins.ts ──────────────────────────────────────────────────────────
|
|
913
|
+
export const kywiSitePluginsMysql = mysqlTable('kywi_site_plugins', {
|
|
914
|
+
id: mysqlUuidPk(),
|
|
915
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
916
|
+
pluginPackage: varchar('plugin_package', { length: 200 }).notNull(),
|
|
917
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
918
|
+
config: json('config'),
|
|
919
|
+
createdAt: mysqlTs('created_at').notNull().default(mysqlNow()),
|
|
920
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
921
|
+
});
|
|
922
|
+
// ── site-settings.ts ─────────────────────────────────────────────────────────
|
|
923
|
+
export const kywiSiteSettingsMysql = mysqlTable('kywi_site_settings', {
|
|
924
|
+
id: mysqlUuidPk(),
|
|
925
|
+
siteId: mysqlUuid('site_id').notNull().references(() => kywiSitesMysql.id, { onDelete: 'cascade' }),
|
|
926
|
+
// `key` is a MySQL reserved word; drizzle backtick-quotes identifiers.
|
|
927
|
+
key: varchar('key', { length: 100 }).notNull(),
|
|
928
|
+
value: json('value').notNull(),
|
|
929
|
+
updatedAt: mysqlTs('updated_at').notNull().default(mysqlNow()),
|
|
930
|
+
}, (t) => [
|
|
931
|
+
unique('kywi_site_settings_site_id_key_unique').on(t.siteId, t.key),
|
|
932
|
+
]);
|
|
357
933
|
//# sourceMappingURL=mysql-tables.js.map
|