@kywi-software/core 0.2.0 → 0.3.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/README.md +57 -2
- package/dist/admin/app.d.ts +10 -1
- package/dist/admin/app.d.ts.map +1 -1
- package/dist/admin/app.js +2 -2
- package/dist/admin/app.js.map +1 -1
- package/dist/admin/approval-queue.d.ts +3 -1
- package/dist/admin/approval-queue.d.ts.map +1 -1
- package/dist/admin/approval-queue.js +2 -2
- package/dist/admin/approval-queue.js.map +1 -1
- package/dist/admin/audience-list.d.ts.map +1 -1
- package/dist/admin/audience-list.js +9 -1
- package/dist/admin/audience-list.js.map +1 -1
- package/dist/admin/chrome.d.ts +7 -1
- package/dist/admin/chrome.d.ts.map +1 -1
- package/dist/admin/chrome.js +2 -1
- package/dist/admin/chrome.js.map +1 -1
- package/dist/admin/content-editor-api.d.ts +27 -1
- package/dist/admin/content-editor-api.d.ts.map +1 -1
- package/dist/admin/content-editor-api.js +60 -2
- package/dist/admin/content-editor-api.js.map +1 -1
- package/dist/admin/content-form.d.ts +62 -6
- package/dist/admin/content-form.d.ts.map +1 -1
- package/dist/admin/content-form.js +118 -13
- package/dist/admin/content-form.js.map +1 -1
- package/dist/admin/content-permissions-tab.d.ts +13 -0
- package/dist/admin/content-permissions-tab.d.ts.map +1 -0
- package/dist/admin/content-permissions-tab.js +90 -0
- package/dist/admin/content-permissions-tab.js.map +1 -0
- package/dist/admin/context.d.ts +8 -0
- package/dist/admin/context.d.ts.map +1 -1
- package/dist/admin/context.js.map +1 -1
- package/dist/admin/feed-builder.d.ts.map +1 -1
- package/dist/admin/feed-builder.js +20 -1
- package/dist/admin/feed-builder.js.map +1 -1
- package/dist/admin/field-components.d.ts.map +1 -1
- package/dist/admin/field-components.js +26 -1
- package/dist/admin/field-components.js.map +1 -1
- package/dist/admin/form-builder.js +6 -1
- package/dist/admin/form-builder.js.map +1 -1
- package/dist/admin/form-helpers.d.ts.map +1 -1
- package/dist/admin/form-helpers.js +2 -0
- package/dist/admin/form-helpers.js.map +1 -1
- package/dist/admin/kywi-logo.d.ts +21 -0
- package/dist/admin/kywi-logo.d.ts.map +1 -0
- package/dist/admin/kywi-logo.js +123 -0
- package/dist/admin/kywi-logo.js.map +1 -0
- package/dist/admin/layout-editor/component-actions.d.ts +18 -0
- package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
- package/dist/admin/layout-editor/component-actions.js +19 -0
- package/dist/admin/layout-editor/component-actions.js.map +1 -1
- package/dist/admin/layout-editor/component-picker-field.d.ts +20 -0
- package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -0
- package/dist/admin/layout-editor/component-picker-field.js +16 -0
- package/dist/admin/layout-editor/component-picker-field.js.map +1 -0
- package/dist/admin/layout-editor/drag-utils.d.ts +48 -0
- package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
- package/dist/admin/layout-editor/drag-utils.js +43 -0
- package/dist/admin/layout-editor/drag-utils.js.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.d.ts +9 -1
- package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-canvas.js +41 -15
- package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
- package/dist/admin/layout-editor/editor-state.d.ts +9 -1
- package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
- package/dist/admin/layout-editor/editor-state.js +34 -0
- package/dist/admin/layout-editor/editor-state.js.map +1 -1
- package/dist/admin/layout-editor/editor.css +83 -0
- package/dist/admin/layout-editor/form-picker-field.d.ts +17 -0
- package/dist/admin/layout-editor/form-picker-field.d.ts.map +1 -0
- package/dist/admin/layout-editor/form-picker-field.js +35 -0
- package/dist/admin/layout-editor/form-picker-field.js.map +1 -0
- package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
- package/dist/admin/layout-editor/layout-editor.js +95 -28
- package/dist/admin/layout-editor/layout-editor.js.map +1 -1
- package/dist/admin/layout-editor/mode-toggle.d.ts.map +1 -1
- package/dist/admin/layout-editor/mode-toggle.js +1 -1
- package/dist/admin/layout-editor/mode-toggle.js.map +1 -1
- package/dist/admin/layout-editor/module-overlay.d.ts +10 -1
- package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/module-overlay.js +3 -3
- package/dist/admin/layout-editor/module-overlay.js.map +1 -1
- package/dist/admin/layout-editor/props-panel.d.ts +10 -1
- package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
- package/dist/admin/layout-editor/props-panel.js +25 -2
- package/dist/admin/layout-editor/props-panel.js.map +1 -1
- package/dist/admin/layout-editor/section-insert-line.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-insert-line.js +1 -1
- package/dist/admin/layout-editor/section-insert-line.js.map +1 -1
- package/dist/admin/layout-editor/section-overlay.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-overlay.js +1 -1
- package/dist/admin/layout-editor/section-overlay.js.map +1 -1
- package/dist/admin/layout-editor/section-template-picker.d.ts +9 -1
- package/dist/admin/layout-editor/section-template-picker.d.ts.map +1 -1
- package/dist/admin/layout-editor/section-template-picker.js +45 -2
- package/dist/admin/layout-editor/section-template-picker.js.map +1 -1
- package/dist/admin/registry.d.ts.map +1 -1
- package/dist/admin/registry.js +11 -0
- package/dist/admin/registry.js.map +1 -1
- package/dist/admin/server.d.ts +15 -2
- package/dist/admin/server.d.ts.map +1 -1
- package/dist/admin/server.js +37 -1
- package/dist/admin/server.js.map +1 -1
- package/dist/admin/shell.d.ts.map +1 -1
- package/dist/admin/shell.js +62 -3
- package/dist/admin/shell.js.map +1 -1
- package/dist/admin/styles/admin.css +105 -27
- package/dist/admin/surface-matcher.d.ts +27 -0
- package/dist/admin/surface-matcher.d.ts.map +1 -1
- package/dist/admin/surface-matcher.js +11 -0
- package/dist/admin/surface-matcher.js.map +1 -1
- package/dist/admin/surfaces/approvals/approvals-data.d.ts +29 -9
- package/dist/admin/surfaces/approvals/approvals-data.d.ts.map +1 -1
- package/dist/admin/surfaces/approvals/approvals-data.js +65 -22
- package/dist/admin/surfaces/approvals/approvals-data.js.map +1 -1
- package/dist/admin/surfaces/approvals/approvals-index.d.ts.map +1 -1
- package/dist/admin/surfaces/approvals/approvals-index.js +47 -14
- package/dist/admin/surfaces/approvals/approvals-index.js.map +1 -1
- package/dist/admin/surfaces/content/content-edit.d.ts.map +1 -1
- package/dist/admin/surfaces/content/content-edit.js +34 -8
- package/dist/admin/surfaces/content/content-edit.js.map +1 -1
- package/dist/admin/surfaces/content/content-index.d.ts.map +1 -1
- package/dist/admin/surfaces/content/content-index.js +29 -2
- package/dist/admin/surfaces/content/content-index.js.map +1 -1
- package/dist/admin/surfaces/content/content-new.d.ts.map +1 -1
- package/dist/admin/surfaces/content/content-new.js +6 -4
- package/dist/admin/surfaces/content/content-new.js.map +1 -1
- package/dist/admin/surfaces/contentTree/content-tree.d.ts.map +1 -1
- package/dist/admin/surfaces/contentTree/content-tree.js +25 -2
- package/dist/admin/surfaces/contentTree/content-tree.js.map +1 -1
- package/dist/admin/surfaces/contentTypes/content-types-designer.d.ts.map +1 -1
- package/dist/admin/surfaces/contentTypes/content-types-designer.js +78 -47
- package/dist/admin/surfaces/contentTypes/content-types-designer.js.map +1 -1
- package/dist/admin/surfaces/feeds/feed-editor.d.ts.map +1 -1
- package/dist/admin/surfaces/feeds/feed-editor.js +21 -4
- package/dist/admin/surfaces/feeds/feed-editor.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 +7 -4
- 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 +2 -1
- package/dist/admin/surfaces/login.js.map +1 -1
- package/dist/admin/surfaces/media/media-client.d.ts.map +1 -1
- package/dist/admin/surfaces/media/media-client.js +10 -2
- package/dist/admin/surfaces/media/media-client.js.map +1 -1
- package/dist/admin/surfaces/settings/settings-site.d.ts.map +1 -1
- package/dist/admin/surfaces/settings/settings-site.js +39 -2
- package/dist/admin/surfaces/settings/settings-site.js.map +1 -1
- package/dist/admin/surfaces/settings/settings-sites.js +18 -0
- package/dist/admin/surfaces/settings/settings-sites.js.map +1 -1
- package/dist/admin/surfaces/trash/trash-index.d.ts.map +1 -1
- package/dist/admin/surfaces/trash/trash-index.js +45 -8
- package/dist/admin/surfaces/trash/trash-index.js.map +1 -1
- package/dist/admin/surfaces/users/users-data.d.ts +11 -0
- package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
- package/dist/admin/surfaces/users/users-data.js +20 -1
- package/dist/admin/surfaces/users/users-data.js.map +1 -1
- package/dist/admin/surfaces/webServices/web-services-data.d.ts +11 -1
- package/dist/admin/surfaces/webServices/web-services-data.d.ts.map +1 -1
- package/dist/admin/surfaces/webServices/web-services-data.js +13 -0
- package/dist/admin/surfaces/webServices/web-services-data.js.map +1 -1
- package/dist/admin/surfaces/webServices/webhooks.d.ts +3 -0
- package/dist/admin/surfaces/webServices/webhooks.d.ts.map +1 -0
- package/dist/admin/surfaces/webServices/webhooks.js +69 -0
- package/dist/admin/surfaces/webServices/webhooks.js.map +1 -0
- package/dist/admin/webhook-manager.d.ts +32 -0
- package/dist/admin/webhook-manager.d.ts.map +1 -0
- package/dist/admin/webhook-manager.js +62 -0
- package/dist/admin/webhook-manager.js.map +1 -0
- package/dist/api/admin-features-routes.d.ts.map +1 -1
- package/dist/api/admin-features-routes.js +30 -0
- package/dist/api/admin-features-routes.js.map +1 -1
- package/dist/api/api-key-routes.d.ts.map +1 -1
- package/dist/api/api-key-routes.js +6 -1
- package/dist/api/api-key-routes.js.map +1 -1
- package/dist/api/auth.d.ts +8 -0
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +11 -1
- package/dist/api/auth.js.map +1 -1
- package/dist/api/comment-routes.d.ts.map +1 -1
- package/dist/api/comment-routes.js +102 -47
- package/dist/api/comment-routes.js.map +1 -1
- package/dist/api/config-routes.d.ts +10 -2
- package/dist/api/config-routes.d.ts.map +1 -1
- package/dist/api/config-routes.js +46 -25
- package/dist/api/config-routes.js.map +1 -1
- package/dist/api/content-routes.d.ts.map +1 -1
- package/dist/api/content-routes.js +41 -0
- package/dist/api/content-routes.js.map +1 -1
- package/dist/api/content-schemas.d.ts.map +1 -1
- package/dist/api/content-schemas.js +34 -1
- package/dist/api/content-schemas.js.map +1 -1
- package/dist/api/content-type-routes.d.ts.map +1 -1
- package/dist/api/content-type-routes.js +58 -3
- package/dist/api/content-type-routes.js.map +1 -1
- package/dist/api/feed-routes.d.ts +180 -0
- package/dist/api/feed-routes.d.ts.map +1 -1
- package/dist/api/feed-routes.js +10 -2
- package/dist/api/feed-routes.js.map +1 -1
- package/dist/api/form-routes.d.ts +6 -0
- package/dist/api/form-routes.d.ts.map +1 -1
- package/dist/api/form-routes.js +93 -14
- package/dist/api/form-routes.js.map +1 -1
- package/dist/api/graphql/resolvers.d.ts +4 -4
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +12 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/media-routes.d.ts.map +1 -1
- package/dist/api/media-routes.js +18 -1
- package/dist/api/media-routes.js.map +1 -1
- package/dist/api/webhook-routes.d.ts.map +1 -1
- package/dist/api/webhook-routes.js +19 -2
- 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 +163 -4
- package/dist/api/workflow-routes.js.map +1 -1
- package/dist/auth/roles.d.ts +28 -0
- package/dist/auth/roles.d.ts.map +1 -1
- package/dist/auth/roles.js +49 -0
- package/dist/auth/roles.js.map +1 -1
- package/dist/config/reserved-field-names.d.ts +29 -0
- package/dist/config/reserved-field-names.d.ts.map +1 -0
- package/dist/config/reserved-field-names.js +59 -0
- package/dist/config/reserved-field-names.js.map +1 -0
- package/dist/config/types.d.ts +31 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/db/analytics-queries.d.ts +1 -1
- package/dist/db/api-key-queries.d.ts +7 -2
- package/dist/db/api-key-queries.d.ts.map +1 -1
- package/dist/db/api-key-queries.js +8 -2
- package/dist/db/api-key-queries.js.map +1 -1
- package/dist/db/apply-snapshot.d.ts +58 -0
- package/dist/db/apply-snapshot.d.ts.map +1 -0
- package/dist/db/apply-snapshot.js +142 -0
- package/dist/db/apply-snapshot.js.map +1 -0
- package/dist/db/audit-queries.d.ts +3 -3
- package/dist/db/category-queries.d.ts +3 -3
- package/dist/db/changeset-audit-queries.d.ts +2 -2
- package/dist/db/changeset-queries.d.ts +5 -5
- package/dist/db/changeset-queries.d.ts.map +1 -1
- package/dist/db/changeset-queries.js +24 -7
- package/dist/db/changeset-queries.js.map +1 -1
- package/dist/db/content-queries.d.ts +6 -0
- package/dist/db/content-queries.d.ts.map +1 -1
- package/dist/db/content-queries.js +8 -0
- package/dist/db/content-queries.js.map +1 -1
- package/dist/db/content-type-queries.d.ts +20 -0
- package/dist/db/content-type-queries.d.ts.map +1 -1
- package/dist/db/content-type-queries.js +32 -0
- package/dist/db/content-type-queries.js.map +1 -1
- package/dist/db/dashboard-queries.d.ts.map +1 -1
- package/dist/db/dashboard-queries.js +5 -1
- package/dist/db/dashboard-queries.js.map +1 -1
- package/dist/db/dynamic-schema.d.ts.map +1 -1
- package/dist/db/dynamic-schema.js +2 -0
- package/dist/db/dynamic-schema.js.map +1 -1
- package/dist/db/extension-queries.d.ts +8 -8
- package/dist/db/feed-queries.d.ts +3 -3
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/media-queries.d.ts +31 -7
- package/dist/db/media-queries.d.ts.map +1 -1
- package/dist/db/media-queries.js +13 -1
- package/dist/db/media-queries.js.map +1 -1
- package/dist/db/membership-dedupe.d.ts +26 -0
- package/dist/db/membership-dedupe.d.ts.map +1 -0
- package/dist/db/membership-dedupe.js +68 -0
- package/dist/db/membership-dedupe.js.map +1 -0
- package/dist/db/revision-queries.d.ts +122 -0
- package/dist/db/revision-queries.d.ts.map +1 -0
- package/dist/db/revision-queries.js +213 -0
- package/dist/db/revision-queries.js.map +1 -0
- package/dist/db/schema-apply.d.ts +8 -0
- package/dist/db/schema-apply.d.ts.map +1 -1
- package/dist/db/schema-apply.js +17 -0
- package/dist/db/schema-apply.js.map +1 -1
- package/dist/db/schema-field-queries.d.ts +2 -0
- package/dist/db/schema-field-queries.d.ts.map +1 -1
- package/dist/db/schema-field-queries.js +4 -0
- package/dist/db/schema-field-queries.js.map +1 -1
- package/dist/db/site-plugin-queries.d.ts +2 -2
- package/dist/db/user-queries.d.ts +12 -0
- package/dist/db/user-queries.d.ts.map +1 -1
- package/dist/db/user-queries.js +18 -4
- package/dist/db/user-queries.js.map +1 -1
- package/dist/db/version-queries.d.ts +37 -0
- package/dist/db/version-queries.d.ts.map +1 -1
- package/dist/db/version-queries.js +36 -0
- package/dist/db/version-queries.js.map +1 -1
- package/dist/db/webhook-queries.d.ts +27 -5
- package/dist/db/webhook-queries.d.ts.map +1 -1
- package/dist/db/webhook-queries.js +17 -0
- package/dist/db/webhook-queries.js.map +1 -1
- package/dist/db/workflow-queries.d.ts +2 -2
- package/dist/experiments/schema.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/webhook-retry.d.ts +22 -1
- package/dist/hooks/webhook-retry.d.ts.map +1 -1
- package/dist/hooks/webhook-retry.js +38 -1
- package/dist/hooks/webhook-retry.js.map +1 -1
- package/dist/host/index.d.ts +28 -0
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +56 -1
- package/dist/host/index.js.map +1 -1
- package/dist/layout/comments-module.d.ts +18 -0
- package/dist/layout/comments-module.d.ts.map +1 -0
- package/dist/layout/comments-module.js +130 -0
- package/dist/layout/comments-module.js.map +1 -0
- package/dist/layout/feed-hydration.d.ts +75 -0
- package/dist/layout/feed-hydration.d.ts.map +1 -0
- package/dist/layout/feed-hydration.js +158 -0
- package/dist/layout/feed-hydration.js.map +1 -0
- package/dist/layout/index.d.ts +2 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +2 -1
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/module-render-context.d.ts +13 -0
- package/dist/layout/module-render-context.d.ts.map +1 -0
- package/dist/layout/module-render-context.js +15 -0
- package/dist/layout/module-render-context.js.map +1 -0
- package/dist/layout/modules-extended.d.ts.map +1 -1
- package/dist/layout/modules-extended.js +92 -13
- package/dist/layout/modules-extended.js.map +1 -1
- package/dist/layout/registry.d.ts.map +1 -1
- package/dist/layout/registry.js +22 -6
- package/dist/layout/registry.js.map +1 -1
- package/dist/layout/renderer.d.ts +17 -1
- package/dist/layout/renderer.d.ts.map +1 -1
- package/dist/layout/renderer.js +11 -4
- package/dist/layout/renderer.js.map +1 -1
- package/dist/nav/index.d.ts +1 -0
- package/dist/nav/index.d.ts.map +1 -1
- package/dist/nav/index.js +4 -0
- package/dist/nav/index.js.map +1 -1
- package/dist/nav/url-resolver.d.ts +10 -2
- package/dist/nav/url-resolver.d.ts.map +1 -1
- package/dist/nav/url-resolver.js +17 -3
- package/dist/nav/url-resolver.js.map +1 -1
- package/dist/schema/base.d.ts +37 -1
- package/dist/schema/base.d.ts.map +1 -1
- package/dist/schema/base.js +20 -2
- package/dist/schema/base.js.map +1 -1
- package/dist/schema/generate.d.ts +8 -0
- package/dist/schema/generate.d.ts.map +1 -1
- package/dist/schema/generate.js +7 -4
- package/dist/schema/generate.js.map +1 -1
- package/dist/schema/mapper.d.ts.map +1 -1
- package/dist/schema/mapper.js +2 -0
- package/dist/schema/mapper.js.map +1 -1
- package/dist/schema/mysql-tables.d.ts +34 -0
- package/dist/schema/mysql-tables.d.ts.map +1 -1
- package/dist/schema/mysql-tables.js +14 -2
- package/dist/schema/mysql-tables.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/site/styles.css +384 -0
- package/package.json +2 -1
package/dist/db/index.d.ts
CHANGED
|
@@ -32,4 +32,7 @@ export * from './category-path-queries.js';
|
|
|
32
32
|
export * from './changeset-queries.js';
|
|
33
33
|
export * from './lock-queries.js';
|
|
34
34
|
export * from './env-guard.js';
|
|
35
|
+
export { loadAdminContentTypes } from './content-type-queries.js';
|
|
36
|
+
export { listCustomContentTables } from './schema-apply.js';
|
|
37
|
+
export { dedupeMembershipRows } from './membership-dedupe.js';
|
|
35
38
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAG3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA"}
|
package/dist/db/index.js
CHANGED
|
@@ -32,4 +32,11 @@ export * from './category-path-queries.js';
|
|
|
32
32
|
export * from './changeset-queries.js';
|
|
33
33
|
export * from './lock-queries.js';
|
|
34
34
|
export * from './env-guard.js';
|
|
35
|
+
// Registry read helpers surfaced for tooling (the CLI's migrate:generate reads
|
|
36
|
+
// admin-created types + their dynamic tables so it never drops them — #38).
|
|
37
|
+
export { loadAdminContentTypes } from './content-type-queries.js';
|
|
38
|
+
export { listCustomContentTables } from './schema-apply.js';
|
|
39
|
+
// One-time duplicate-membership cleanup the CLI runs before applying the #40
|
|
40
|
+
// uniqueness constraints to a pre-existing database.
|
|
41
|
+
export { dedupeMembershipRows } from './membership-dedupe.js';
|
|
35
42
|
//# sourceMappingURL=index.js.map
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,sBAAsB,CAAA;AACpC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,+EAA+E;AAC/E,4EAA4E;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,6EAA6E;AAC7E,qDAAqD;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA"}
|
|
@@ -3,18 +3,42 @@ export declare function listMedia(db: KywiDb, siteId: string): Promise<{
|
|
|
3
3
|
id: string;
|
|
4
4
|
siteId: string;
|
|
5
5
|
updatedAt: Date;
|
|
6
|
-
caption: string | null;
|
|
7
6
|
width: number | null;
|
|
7
|
+
createdAt: Date;
|
|
8
|
+
deletedAt: Date | null;
|
|
9
|
+
filename: string;
|
|
10
|
+
mimeType: string;
|
|
11
|
+
fileSize: number;
|
|
8
12
|
height: number | null;
|
|
13
|
+
duration: number | null;
|
|
14
|
+
originalFilename: string;
|
|
15
|
+
altText: string | null;
|
|
16
|
+
caption: string | null;
|
|
9
17
|
tags: unknown;
|
|
18
|
+
uploadedBy: string | null;
|
|
19
|
+
storageKey: string;
|
|
20
|
+
}[]>;
|
|
21
|
+
/**
|
|
22
|
+
* List soft-deleted media for a site, newest-deleted first (#23 — the Trash
|
|
23
|
+
* surface's media tab). Mirrors `listDeletedContent`'s shape/ordering
|
|
24
|
+
* (`db/content-restore.ts`) so the two trash sources merge predictably.
|
|
25
|
+
*/
|
|
26
|
+
export declare function listDeletedMedia(db: KywiDb, siteId: string): Promise<{
|
|
27
|
+
id: string;
|
|
28
|
+
siteId: string;
|
|
29
|
+
updatedAt: Date;
|
|
30
|
+
width: number | null;
|
|
10
31
|
createdAt: Date;
|
|
11
32
|
deletedAt: Date | null;
|
|
12
33
|
filename: string;
|
|
13
34
|
mimeType: string;
|
|
14
35
|
fileSize: number;
|
|
36
|
+
height: number | null;
|
|
15
37
|
duration: number | null;
|
|
16
38
|
originalFilename: string;
|
|
17
39
|
altText: string | null;
|
|
40
|
+
caption: string | null;
|
|
41
|
+
tags: unknown;
|
|
18
42
|
uploadedBy: string | null;
|
|
19
43
|
storageKey: string;
|
|
20
44
|
}[]>;
|
|
@@ -22,18 +46,18 @@ export declare function getMediaById(db: KywiDb, id: string, siteId?: string): P
|
|
|
22
46
|
id: string;
|
|
23
47
|
siteId: string;
|
|
24
48
|
updatedAt: Date;
|
|
25
|
-
caption: string | null;
|
|
26
49
|
width: number | null;
|
|
27
|
-
height: number | null;
|
|
28
|
-
tags: unknown;
|
|
29
50
|
createdAt: Date;
|
|
30
51
|
deletedAt: Date | null;
|
|
31
52
|
filename: string;
|
|
32
53
|
mimeType: string;
|
|
33
54
|
fileSize: number;
|
|
55
|
+
height: number | null;
|
|
34
56
|
duration: number | null;
|
|
35
57
|
originalFilename: string;
|
|
36
58
|
altText: string | null;
|
|
59
|
+
caption: string | null;
|
|
60
|
+
tags: unknown;
|
|
37
61
|
uploadedBy: string | null;
|
|
38
62
|
storageKey: string;
|
|
39
63
|
} | null>;
|
|
@@ -51,18 +75,18 @@ export declare function createMediaRecord(db: KywiDb, data: {
|
|
|
51
75
|
id: string;
|
|
52
76
|
siteId: string;
|
|
53
77
|
updatedAt: Date;
|
|
54
|
-
caption: string | null;
|
|
55
78
|
width: number | null;
|
|
56
|
-
height: number | null;
|
|
57
|
-
tags: unknown;
|
|
58
79
|
createdAt: Date;
|
|
59
80
|
deletedAt: Date | null;
|
|
60
81
|
filename: string;
|
|
61
82
|
mimeType: string;
|
|
62
83
|
fileSize: number;
|
|
84
|
+
height: number | null;
|
|
63
85
|
duration: number | null;
|
|
64
86
|
originalFilename: string;
|
|
65
87
|
altText: string | null;
|
|
88
|
+
caption: string | null;
|
|
89
|
+
tags: unknown;
|
|
66
90
|
uploadedBy: string | null;
|
|
67
91
|
storageKey: string;
|
|
68
92
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-queries.d.ts","sourceRoot":"","sources":["../../src/db/media-queries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;KAEzD;AAOD,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;UAMzE;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;IACxD,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAC7E,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChI;;;;;;;;;;;;;;;;;;GAGA;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM/F;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO5F;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAC7D,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;UAUhB;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAO1H"}
|
|
1
|
+
{"version":3,"file":"media-queries.d.ts","sourceRoot":"","sources":["../../src/db/media-queries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;KAEzD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;KAMhE;AAOD,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;UAMzE;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;IACxD,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAC7E,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChI;;;;;;;;;;;;;;;;;;GAGA;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM/F;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO5F;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAC7D,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;UAUhB;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAO1H"}
|
package/dist/db/media-queries.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import { eq, and, sql } from 'drizzle-orm';
|
|
1
|
+
import { eq, and, sql, desc } from 'drizzle-orm';
|
|
2
2
|
import { kywiMedia } from '../schema/base.js';
|
|
3
3
|
export async function listMedia(db, siteId) {
|
|
4
4
|
return db.select().from(kywiMedia).where(and(eq(kywiMedia.siteId, siteId), sql `${kywiMedia.deletedAt} IS NULL`));
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* List soft-deleted media for a site, newest-deleted first (#23 — the Trash
|
|
8
|
+
* surface's media tab). Mirrors `listDeletedContent`'s shape/ordering
|
|
9
|
+
* (`db/content-restore.ts`) so the two trash sources merge predictably.
|
|
10
|
+
*/
|
|
11
|
+
export async function listDeletedMedia(db, siteId) {
|
|
12
|
+
return db
|
|
13
|
+
.select()
|
|
14
|
+
.from(kywiMedia)
|
|
15
|
+
.where(and(eq(kywiMedia.siteId, siteId), sql `${kywiMedia.deletedAt} IS NOT NULL`))
|
|
16
|
+
.orderBy(desc(kywiMedia.deletedAt));
|
|
17
|
+
}
|
|
6
18
|
// Item-level queries take an OPTIONAL siteId scope. Callers with a site context
|
|
7
19
|
// (every API route) MUST pass it: kywi_media rows are addressable by UUID, so a
|
|
8
20
|
// query with no siteId predicate lets an admin scoped to one site fetch/mutate
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-queries.js","sourceRoot":"","sources":["../../src/db/media-queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"media-queries.js","sourceRoot":"","sources":["../../src/db/media-queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KywiDb } from './client.js';
|
|
2
|
+
/**
|
|
3
|
+
* One-time cleanup for databases that predate the composite uniqueness
|
|
4
|
+
* constraints on `kywi_user_groups(user_id, group_id)` and
|
|
5
|
+
* `kywi_site_memberships(user_id, site_id)` (kywi-cms#40).
|
|
6
|
+
*
|
|
7
|
+
* Before those constraints existed, the New User flow could write the same
|
|
8
|
+
* membership twice (`onConflictDoNothing()` had no constraint to conflict
|
|
9
|
+
* against), fanning users out across every membership JOIN. Applying the new
|
|
10
|
+
* constraints via `kywi migrate` fails outright on a table that still holds
|
|
11
|
+
* duplicates — so `kywi migrate` runs this first.
|
|
12
|
+
*
|
|
13
|
+
* Keep-row policy per duplicate set:
|
|
14
|
+
* - `kywi_user_groups`: rows are identical; keep an arbitrary one.
|
|
15
|
+
* - `kywi_site_memberships`: keep the row carrying the most `groups` data,
|
|
16
|
+
* then the newest `created_at` (the duplicate written by the implicit
|
|
17
|
+
* default-site grant is typically the empty/older one).
|
|
18
|
+
*
|
|
19
|
+
* Postgres-only (uses ctid + jsonb): callers should skip for other providers.
|
|
20
|
+
* Missing tables (fresh database) are treated as zero duplicates.
|
|
21
|
+
*/
|
|
22
|
+
export declare function dedupeMembershipRows(db: KywiDb): Promise<{
|
|
23
|
+
userGroups: number;
|
|
24
|
+
siteMemberships: number;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=membership-dedupe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"membership-dedupe.d.ts","sourceRoot":"","sources":["../../src/db/membership-dedupe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,CA+C1D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
/**
|
|
3
|
+
* One-time cleanup for databases that predate the composite uniqueness
|
|
4
|
+
* constraints on `kywi_user_groups(user_id, group_id)` and
|
|
5
|
+
* `kywi_site_memberships(user_id, site_id)` (kywi-cms#40).
|
|
6
|
+
*
|
|
7
|
+
* Before those constraints existed, the New User flow could write the same
|
|
8
|
+
* membership twice (`onConflictDoNothing()` had no constraint to conflict
|
|
9
|
+
* against), fanning users out across every membership JOIN. Applying the new
|
|
10
|
+
* constraints via `kywi migrate` fails outright on a table that still holds
|
|
11
|
+
* duplicates — so `kywi migrate` runs this first.
|
|
12
|
+
*
|
|
13
|
+
* Keep-row policy per duplicate set:
|
|
14
|
+
* - `kywi_user_groups`: rows are identical; keep an arbitrary one.
|
|
15
|
+
* - `kywi_site_memberships`: keep the row carrying the most `groups` data,
|
|
16
|
+
* then the newest `created_at` (the duplicate written by the implicit
|
|
17
|
+
* default-site grant is typically the empty/older one).
|
|
18
|
+
*
|
|
19
|
+
* Postgres-only (uses ctid + jsonb): callers should skip for other providers.
|
|
20
|
+
* Missing tables (fresh database) are treated as zero duplicates.
|
|
21
|
+
*/
|
|
22
|
+
export async function dedupeMembershipRows(db) {
|
|
23
|
+
const counts = { userGroups: 0, siteMemberships: 0 };
|
|
24
|
+
const runCount = async (query) => {
|
|
25
|
+
try {
|
|
26
|
+
const result = (await db.execute(query));
|
|
27
|
+
const row = Array.isArray(result) ? result[0] : result.rows?.[0];
|
|
28
|
+
return Number(row?.deleted ?? 0);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
// 42P01 undefined_table: fresh DB, nothing to dedupe.
|
|
32
|
+
if (err?.code === '42P01')
|
|
33
|
+
return 0;
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
counts.userGroups = await runCount(sql `
|
|
38
|
+
WITH deleted AS (
|
|
39
|
+
DELETE FROM kywi_user_groups a
|
|
40
|
+
USING kywi_user_groups b
|
|
41
|
+
WHERE a.user_id = b.user_id
|
|
42
|
+
AND a.group_id = b.group_id
|
|
43
|
+
AND a.ctid < b.ctid
|
|
44
|
+
RETURNING 1
|
|
45
|
+
)
|
|
46
|
+
SELECT count(*)::int AS deleted FROM deleted
|
|
47
|
+
`);
|
|
48
|
+
counts.siteMemberships = await runCount(sql `
|
|
49
|
+
WITH deleted AS (
|
|
50
|
+
DELETE FROM kywi_site_memberships a
|
|
51
|
+
USING kywi_site_memberships b
|
|
52
|
+
WHERE a.user_id = b.user_id
|
|
53
|
+
AND a.site_id = b.site_id
|
|
54
|
+
AND (
|
|
55
|
+
jsonb_array_length(a.groups) < jsonb_array_length(b.groups)
|
|
56
|
+
OR (jsonb_array_length(a.groups) = jsonb_array_length(b.groups)
|
|
57
|
+
AND a.created_at < b.created_at)
|
|
58
|
+
OR (jsonb_array_length(a.groups) = jsonb_array_length(b.groups)
|
|
59
|
+
AND a.created_at = b.created_at
|
|
60
|
+
AND a.ctid < b.ctid)
|
|
61
|
+
)
|
|
62
|
+
RETURNING 1
|
|
63
|
+
)
|
|
64
|
+
SELECT count(*)::int AS deleted FROM deleted
|
|
65
|
+
`);
|
|
66
|
+
return counts;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=membership-dedupe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"membership-dedupe.js","sourceRoot":"","sources":["../../src/db/membership-dedupe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAU;IAEV,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAA;IAEpD,MAAM,QAAQ,GAAG,KAAK,EAAE,KAA6B,EAAmB,EAAE;QACxE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAA2C,CAAA;YAClF,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,MAAiD,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC5G,OAAO,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC,CAAA;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sDAAsD;YACtD,IAAK,GAAyB,EAAE,IAAI,KAAK,OAAO;gBAAE,OAAO,CAAC,CAAA;YAC1D,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC,CAAA;IAED,MAAM,CAAC,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAA;;;;;;;;;;GAUrC,CAAC,CAAA;IAEF,MAAM,CAAC,eAAe,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;GAiB1C,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { type ContentWithCustomFields } from './content-queries.js';
|
|
3
|
+
import type { KywiDb } from './client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Pending revisions (#42) — reviewing edits to already-published content without
|
|
6
|
+
* unpublishing the live version.
|
|
7
|
+
*
|
|
8
|
+
* The problem: an editor could only push edits to a live page by direct-publish;
|
|
9
|
+
* `published → pending` was a forbidden transition, and even if allowed it would
|
|
10
|
+
* pull the page off the live site (only `published` renders). There was no
|
|
11
|
+
* "draft of a published page under review" concept.
|
|
12
|
+
*
|
|
13
|
+
* The model, built entirely on the EXISTING kywi_content_versions table (no new
|
|
14
|
+
* table, no schema migration): a pending revision is a version row with
|
|
15
|
+
* `status = 'pending'` whose snapshot carries the {@link REVISION_MARKER} flag
|
|
16
|
+
* and the PROPOSED (edited) content. The live kywi_content row is never touched
|
|
17
|
+
* on submit, so the published page keeps serving its current content. The marker
|
|
18
|
+
* distinguishes an OUTSTANDING revision from the ordinary historical
|
|
19
|
+
* status='pending' snapshot the draft→pending→approve cycle also produces, so the
|
|
20
|
+
* approvals queue never confuses the two. On resolution the marked row is
|
|
21
|
+
* deleted, so "outstanding revision" == "a marked pending version exists".
|
|
22
|
+
*/
|
|
23
|
+
/** Snapshot flag marking a version row as an outstanding pending revision. */
|
|
24
|
+
export declare const REVISION_MARKER = "__pendingRevision";
|
|
25
|
+
/** Return a copy of a revision snapshot with the internal marker removed. */
|
|
26
|
+
export declare function stripRevisionMarker(snapshot: Record<string, unknown>): Record<string, unknown>;
|
|
27
|
+
/** A pending-revision version joined with its live content, for the queue. */
|
|
28
|
+
export interface PendingRevisionRow {
|
|
29
|
+
versionId: string;
|
|
30
|
+
version: number;
|
|
31
|
+
contentId: string;
|
|
32
|
+
contentTypeName: string;
|
|
33
|
+
title: string;
|
|
34
|
+
siteId: string;
|
|
35
|
+
status: string;
|
|
36
|
+
createdBy: string | null;
|
|
37
|
+
createdAt: Date;
|
|
38
|
+
changeNote: string | null;
|
|
39
|
+
snapshot: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a pending revision: a version snapshot of the proposed content with the
|
|
43
|
+
* revision marker, status 'pending'. The live content row is deliberately NOT
|
|
44
|
+
* modified — the caller has already confirmed the content is published/approved
|
|
45
|
+
* and the point is that it keeps serving until approval.
|
|
46
|
+
*
|
|
47
|
+
* Uses createVersion directly (not recordContentVersion) so a pending revision is
|
|
48
|
+
* never pruned by the retention cap while it awaits review.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createPendingRevision(db: KywiDb, data: {
|
|
51
|
+
contentId: string;
|
|
52
|
+
siteId: string;
|
|
53
|
+
proposed: Record<string, unknown>;
|
|
54
|
+
changeNote?: string | undefined;
|
|
55
|
+
createdBy: string | null;
|
|
56
|
+
}): Promise<{
|
|
57
|
+
id: string;
|
|
58
|
+
siteId: string;
|
|
59
|
+
status: string;
|
|
60
|
+
createdAt: Date;
|
|
61
|
+
createdBy: string | null;
|
|
62
|
+
contentId: string;
|
|
63
|
+
version: number;
|
|
64
|
+
snapshot: unknown;
|
|
65
|
+
changeNote: string | null;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* List outstanding pending revisions for a site — one row per revision version
|
|
69
|
+
* carrying the marker, joined to its (non-deleted) live content. Ordered newest
|
|
70
|
+
* first. Feeds the approvals queue alongside the plain status='pending' drafts.
|
|
71
|
+
*/
|
|
72
|
+
export declare function listPendingRevisions(db: KywiDb, siteId: string): Promise<PendingRevisionRow[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Fetch a single pending-revision version by id, validating it is a marked,
|
|
75
|
+
* still-pending revision belonging to `contentId`. Returns null otherwise (an
|
|
76
|
+
* already-resolved or non-revision version id).
|
|
77
|
+
*/
|
|
78
|
+
export declare function getPendingRevision(db: KywiDb, contentId: string, versionId: string): Promise<{
|
|
79
|
+
id: string;
|
|
80
|
+
version: number;
|
|
81
|
+
siteId: string;
|
|
82
|
+
snapshot: Record<string, unknown>;
|
|
83
|
+
changeNote: string | null;
|
|
84
|
+
} | null>;
|
|
85
|
+
/**
|
|
86
|
+
* Approve a pending revision: apply its proposed snapshot onto the live content
|
|
87
|
+
* (publishing it), record a normal published version of the result, and delete
|
|
88
|
+
* the marked revision row so it leaves the queue. The live page transitions from
|
|
89
|
+
* its old content to the approved content in one step, staying published.
|
|
90
|
+
*/
|
|
91
|
+
export declare function approvePendingRevision(db: KywiDb, opts: {
|
|
92
|
+
contentId: string;
|
|
93
|
+
versionId: string;
|
|
94
|
+
userId: string;
|
|
95
|
+
userEmail: string;
|
|
96
|
+
customTable: PgTableWithColumns<any> | null;
|
|
97
|
+
customFieldNames?: readonly string[];
|
|
98
|
+
}): Promise<{
|
|
99
|
+
success: boolean;
|
|
100
|
+
content?: ContentWithCustomFields;
|
|
101
|
+
error?: string;
|
|
102
|
+
}>;
|
|
103
|
+
/**
|
|
104
|
+
* Reject a pending revision: discard the proposed snapshot (delete the marked
|
|
105
|
+
* row) and record a version on the UNCHANGED live content whose changeNote is
|
|
106
|
+
* `Rejected: <reason>`. Recording it as a version (matching the draft-reject
|
|
107
|
+
* flow) is what surfaces the reason back to the editor — the edit screen reads
|
|
108
|
+
* the latest `Rejected:` version note. The live content is never modified.
|
|
109
|
+
*/
|
|
110
|
+
export declare function rejectPendingRevision(db: KywiDb, opts: {
|
|
111
|
+
contentId: string;
|
|
112
|
+
versionId: string;
|
|
113
|
+
reason?: string | undefined;
|
|
114
|
+
userId: string;
|
|
115
|
+
userEmail: string;
|
|
116
|
+
customTable: PgTableWithColumns<any> | null;
|
|
117
|
+
}): Promise<{
|
|
118
|
+
success: boolean;
|
|
119
|
+
content?: ContentWithCustomFields;
|
|
120
|
+
error?: string;
|
|
121
|
+
}>;
|
|
122
|
+
//# sourceMappingURL=revision-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revision-queries.d.ts","sourceRoot":"","sources":["../../src/db/revision-queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { eq, and, desc, sql } from 'drizzle-orm';
|
|
2
|
+
import { kywiContent, kywiContentVersions } from '../schema/base.js';
|
|
3
|
+
import { createVersion, getLatestVersionNumber, recordContentVersion } from './version-queries.js';
|
|
4
|
+
import { getContentById } from './content-queries.js';
|
|
5
|
+
import { applyContentSnapshot } from './apply-snapshot.js';
|
|
6
|
+
import { createAuditEntry } from './audit-queries.js';
|
|
7
|
+
/**
|
|
8
|
+
* Pending revisions (#42) — reviewing edits to already-published content without
|
|
9
|
+
* unpublishing the live version.
|
|
10
|
+
*
|
|
11
|
+
* The problem: an editor could only push edits to a live page by direct-publish;
|
|
12
|
+
* `published → pending` was a forbidden transition, and even if allowed it would
|
|
13
|
+
* pull the page off the live site (only `published` renders). There was no
|
|
14
|
+
* "draft of a published page under review" concept.
|
|
15
|
+
*
|
|
16
|
+
* The model, built entirely on the EXISTING kywi_content_versions table (no new
|
|
17
|
+
* table, no schema migration): a pending revision is a version row with
|
|
18
|
+
* `status = 'pending'` whose snapshot carries the {@link REVISION_MARKER} flag
|
|
19
|
+
* and the PROPOSED (edited) content. The live kywi_content row is never touched
|
|
20
|
+
* on submit, so the published page keeps serving its current content. The marker
|
|
21
|
+
* distinguishes an OUTSTANDING revision from the ordinary historical
|
|
22
|
+
* status='pending' snapshot the draft→pending→approve cycle also produces, so the
|
|
23
|
+
* approvals queue never confuses the two. On resolution the marked row is
|
|
24
|
+
* deleted, so "outstanding revision" == "a marked pending version exists".
|
|
25
|
+
*/
|
|
26
|
+
/** Snapshot flag marking a version row as an outstanding pending revision. */
|
|
27
|
+
export const REVISION_MARKER = '__pendingRevision';
|
|
28
|
+
/** Return a copy of a revision snapshot with the internal marker removed. */
|
|
29
|
+
export function stripRevisionMarker(snapshot) {
|
|
30
|
+
const { [REVISION_MARKER]: _marker, ...rest } = snapshot;
|
|
31
|
+
return rest;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create a pending revision: a version snapshot of the proposed content with the
|
|
35
|
+
* revision marker, status 'pending'. The live content row is deliberately NOT
|
|
36
|
+
* modified — the caller has already confirmed the content is published/approved
|
|
37
|
+
* and the point is that it keeps serving until approval.
|
|
38
|
+
*
|
|
39
|
+
* Uses createVersion directly (not recordContentVersion) so a pending revision is
|
|
40
|
+
* never pruned by the retention cap while it awaits review.
|
|
41
|
+
*/
|
|
42
|
+
export async function createPendingRevision(db, data) {
|
|
43
|
+
const latest = await getLatestVersionNumber(db, data.contentId);
|
|
44
|
+
const snapshot = { ...data.proposed, [REVISION_MARKER]: true };
|
|
45
|
+
return createVersion(db, {
|
|
46
|
+
contentId: data.contentId,
|
|
47
|
+
siteId: data.siteId,
|
|
48
|
+
version: latest + 1,
|
|
49
|
+
snapshot,
|
|
50
|
+
status: 'pending',
|
|
51
|
+
createdBy: data.createdBy,
|
|
52
|
+
...(data.changeNote !== undefined ? { changeNote: data.changeNote } : {}),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* List outstanding pending revisions for a site — one row per revision version
|
|
57
|
+
* carrying the marker, joined to its (non-deleted) live content. Ordered newest
|
|
58
|
+
* first. Feeds the approvals queue alongside the plain status='pending' drafts.
|
|
59
|
+
*/
|
|
60
|
+
export async function listPendingRevisions(db, siteId) {
|
|
61
|
+
const rows = await db
|
|
62
|
+
.select({
|
|
63
|
+
versionId: kywiContentVersions.id,
|
|
64
|
+
version: kywiContentVersions.version,
|
|
65
|
+
contentId: kywiContentVersions.contentId,
|
|
66
|
+
siteId: kywiContentVersions.siteId,
|
|
67
|
+
createdBy: kywiContentVersions.createdBy,
|
|
68
|
+
createdAt: kywiContentVersions.createdAt,
|
|
69
|
+
changeNote: kywiContentVersions.changeNote,
|
|
70
|
+
snapshot: kywiContentVersions.snapshot,
|
|
71
|
+
contentTypeName: kywiContent.contentTypeName,
|
|
72
|
+
title: kywiContent.title,
|
|
73
|
+
contentStatus: kywiContent.status,
|
|
74
|
+
})
|
|
75
|
+
.from(kywiContentVersions)
|
|
76
|
+
.innerJoin(kywiContent, eq(kywiContent.id, kywiContentVersions.contentId))
|
|
77
|
+
.where(and(eq(kywiContentVersions.siteId, siteId), eq(kywiContentVersions.status, 'pending'), sql `(${kywiContentVersions.snapshot} ->> ${REVISION_MARKER}) = 'true'`, sql `${kywiContent.deletedAt} IS NULL`))
|
|
78
|
+
.orderBy(desc(kywiContentVersions.createdAt));
|
|
79
|
+
return rows.map((r) => ({
|
|
80
|
+
versionId: r.versionId,
|
|
81
|
+
version: r.version,
|
|
82
|
+
contentId: r.contentId,
|
|
83
|
+
contentTypeName: r.contentTypeName,
|
|
84
|
+
title: r.title,
|
|
85
|
+
siteId: r.siteId,
|
|
86
|
+
status: r.contentStatus,
|
|
87
|
+
createdBy: r.createdBy ?? null,
|
|
88
|
+
createdAt: r.createdAt,
|
|
89
|
+
changeNote: r.changeNote ?? null,
|
|
90
|
+
snapshot: r.snapshot,
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Fetch a single pending-revision version by id, validating it is a marked,
|
|
95
|
+
* still-pending revision belonging to `contentId`. Returns null otherwise (an
|
|
96
|
+
* already-resolved or non-revision version id).
|
|
97
|
+
*/
|
|
98
|
+
export async function getPendingRevision(db, contentId, versionId) {
|
|
99
|
+
const [row] = await db
|
|
100
|
+
.select()
|
|
101
|
+
.from(kywiContentVersions)
|
|
102
|
+
.where(eq(kywiContentVersions.id, versionId))
|
|
103
|
+
.limit(1);
|
|
104
|
+
if (!row)
|
|
105
|
+
return null;
|
|
106
|
+
if (row.contentId !== contentId)
|
|
107
|
+
return null;
|
|
108
|
+
if (row.status !== 'pending')
|
|
109
|
+
return null;
|
|
110
|
+
const snapshot = row.snapshot;
|
|
111
|
+
if (snapshot?.[REVISION_MARKER] !== true)
|
|
112
|
+
return null;
|
|
113
|
+
return {
|
|
114
|
+
id: row.id,
|
|
115
|
+
version: row.version,
|
|
116
|
+
siteId: row.siteId,
|
|
117
|
+
snapshot,
|
|
118
|
+
changeNote: row.changeNote ?? null,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Approve a pending revision: apply its proposed snapshot onto the live content
|
|
123
|
+
* (publishing it), record a normal published version of the result, and delete
|
|
124
|
+
* the marked revision row so it leaves the queue. The live page transitions from
|
|
125
|
+
* its old content to the approved content in one step, staying published.
|
|
126
|
+
*/
|
|
127
|
+
export async function approvePendingRevision(db, opts) {
|
|
128
|
+
const revision = await getPendingRevision(db, opts.contentId, opts.versionId);
|
|
129
|
+
if (!revision)
|
|
130
|
+
return { success: false, error: 'Pending revision not found' };
|
|
131
|
+
const content = await db.transaction(async (rawTx) => {
|
|
132
|
+
const tx = rawTx;
|
|
133
|
+
const clean = stripRevisionMarker(revision.snapshot);
|
|
134
|
+
await applyContentSnapshot(tx, opts.contentId, clean, {
|
|
135
|
+
forceStatus: 'published',
|
|
136
|
+
userId: opts.userId,
|
|
137
|
+
customTable: opts.customTable,
|
|
138
|
+
customFieldNames: opts.customFieldNames ?? [],
|
|
139
|
+
});
|
|
140
|
+
// Remove the revision row first so the published version we record next is
|
|
141
|
+
// the highest version number (and the revision leaves the queue).
|
|
142
|
+
await tx.delete(kywiContentVersions).where(eq(kywiContentVersions.id, opts.versionId));
|
|
143
|
+
const applied = await getContentById(tx, opts.customTable, opts.contentId);
|
|
144
|
+
if (applied) {
|
|
145
|
+
await recordContentVersion(tx, {
|
|
146
|
+
contentId: opts.contentId,
|
|
147
|
+
siteId: revision.siteId,
|
|
148
|
+
snapshot: applied,
|
|
149
|
+
status: 'published',
|
|
150
|
+
createdBy: opts.userId,
|
|
151
|
+
changeNote: revision.changeNote
|
|
152
|
+
? `Approved revision: ${revision.changeNote}`
|
|
153
|
+
: 'Approved revision',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
await createAuditEntry(tx, {
|
|
157
|
+
siteId: revision.siteId,
|
|
158
|
+
contentId: opts.contentId,
|
|
159
|
+
action: 'approve',
|
|
160
|
+
fromStatus: 'published',
|
|
161
|
+
toStatus: 'published',
|
|
162
|
+
userId: opts.userId,
|
|
163
|
+
userEmail: opts.userEmail,
|
|
164
|
+
});
|
|
165
|
+
return applied;
|
|
166
|
+
});
|
|
167
|
+
const result = { success: true };
|
|
168
|
+
if (content)
|
|
169
|
+
result.content = content;
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Reject a pending revision: discard the proposed snapshot (delete the marked
|
|
174
|
+
* row) and record a version on the UNCHANGED live content whose changeNote is
|
|
175
|
+
* `Rejected: <reason>`. Recording it as a version (matching the draft-reject
|
|
176
|
+
* flow) is what surfaces the reason back to the editor — the edit screen reads
|
|
177
|
+
* the latest `Rejected:` version note. The live content is never modified.
|
|
178
|
+
*/
|
|
179
|
+
export async function rejectPendingRevision(db, opts) {
|
|
180
|
+
const revision = await getPendingRevision(db, opts.contentId, opts.versionId);
|
|
181
|
+
if (!revision)
|
|
182
|
+
return { success: false, error: 'Pending revision not found' };
|
|
183
|
+
const content = await db.transaction(async (rawTx) => {
|
|
184
|
+
const tx = rawTx;
|
|
185
|
+
await tx.delete(kywiContentVersions).where(eq(kywiContentVersions.id, opts.versionId));
|
|
186
|
+
const current = await getContentById(tx, opts.customTable, opts.contentId);
|
|
187
|
+
if (current) {
|
|
188
|
+
await recordContentVersion(tx, {
|
|
189
|
+
contentId: opts.contentId,
|
|
190
|
+
siteId: revision.siteId,
|
|
191
|
+
snapshot: current,
|
|
192
|
+
status: current.status ?? 'published',
|
|
193
|
+
createdBy: opts.userId,
|
|
194
|
+
changeNote: opts.reason !== undefined ? `Rejected: ${opts.reason}` : 'Rejected',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
await createAuditEntry(tx, {
|
|
198
|
+
siteId: revision.siteId,
|
|
199
|
+
contentId: opts.contentId,
|
|
200
|
+
action: 'reject',
|
|
201
|
+
fromStatus: current?.status ?? 'published',
|
|
202
|
+
toStatus: current?.status ?? 'published',
|
|
203
|
+
userId: opts.userId,
|
|
204
|
+
userEmail: opts.userEmail,
|
|
205
|
+
});
|
|
206
|
+
return current;
|
|
207
|
+
});
|
|
208
|
+
const result = { success: true };
|
|
209
|
+
if (content)
|
|
210
|
+
result.content = content;
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=revision-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revision-queries.js","sourceRoot":"","sources":["../../src/db/revision-queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,14 @@ export interface SchemaDiff {
|
|
|
13
13
|
export declare function diffFields(actualColumns: string[], desiredFields: FieldDefinition[]): SchemaDiff;
|
|
14
14
|
/** Read actual column names for a table from information_schema. */
|
|
15
15
|
export declare function getActualColumns(db: KywiDb, tableName: string): Promise<string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* List every dynamic content-type table (`kywi_ct_*`) that physically exists in
|
|
18
|
+
* the public schema. Used by `migrate:generate` (#38) to compute which dynamic
|
|
19
|
+
* tables are orphans (present in the DB but backed by neither a config type nor
|
|
20
|
+
* a currently-registered admin type) so they can be excluded from the drizzle-kit
|
|
21
|
+
* diff instead of being offered for DROP.
|
|
22
|
+
*/
|
|
23
|
+
export declare function listCustomContentTables(db: KywiDb): Promise<string[]>;
|
|
16
24
|
/** Does a table exist in the public schema? */
|
|
17
25
|
export declare function tableExists(db: KywiDb, tableName: string): Promise<boolean>;
|
|
18
26
|
/**
|