emdash 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-BMyNSSZi.d.mts → adapters-Bb1vG41D.d.mts} +33 -2
- package/dist/adapters-Bb1vG41D.d.mts.map +1 -0
- package/dist/{allowed-origins-CG1pACtS.mjs → allowed-origins-DW7sYyqg.mjs} +2 -2
- package/dist/{allowed-origins-CG1pACtS.mjs.map → allowed-origins-DW7sYyqg.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +22 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +6 -5
- package/dist/{api-D2hunekQ.mjs → api-BeBglVxU.mjs} +98 -407
- package/dist/api-BeBglVxU.mjs.map +1 -0
- package/dist/{api-tokens-CSND0i1z.mjs → api-tokens-KO24G1Fd.mjs} +2 -2
- package/dist/{api-tokens-CSND0i1z.mjs.map → api-tokens-KO24G1Fd.mjs.map} +1 -1
- package/dist/{apply-kwNEJW2l.mjs → apply-kUDt80-G.mjs} +131 -107
- package/dist/apply-kUDt80-G.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +163 -49
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.mjs +8 -8
- package/dist/astro/middleware/media-usage-write-fence.d.mts +7 -0
- package/dist/astro/middleware/media-usage-write-fence.d.mts.map +1 -0
- package/dist/astro/middleware/media-usage-write-fence.mjs +35 -0
- package/dist/astro/middleware/media-usage-write-fence.mjs.map +1 -0
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +10 -7
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +12 -11
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +1763 -173
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +12 -11
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +12 -11
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +12 -11
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -11
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/index.mjs +12 -11
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +36 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +36 -0
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +15 -14
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/work/index.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/work/index.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +37 -0
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/work/retry.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/work/retry.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +37 -0
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -0
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +51 -43
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +51 -43
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +50 -42
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +50 -42
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +50 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +50 -42
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +51 -43
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +51 -43
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +47 -42
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +47 -42
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +4 -4
- package/dist/astro/routes/api/admin/users/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -9
- package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/complete.mjs +13 -12
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +10 -9
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +12 -11
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
- package/dist/astro/routes/api/auth/me.mjs +10 -9
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +9 -8
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +13 -12
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +15 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +11 -10
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +11 -10
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +44 -31
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -10
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +11 -10
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +10 -8
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +18 -16
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +15 -15
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +14 -12
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +13 -12
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +14 -14
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +18 -16
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +28 -27
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.d.mts.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +174 -72
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +13 -11
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
- package/dist/astro/routes/api/media/_id_/usage.mjs +17 -16
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +16 -15
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +11 -10
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +18 -15
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/items.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_.mjs +11 -11
- package/dist/astro/routes/api/menus/index.mjs +11 -11
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
- package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/openapi.json.mjs +152 -6
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +8 -7
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +13 -12
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +18 -17
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +13 -12
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +18 -17
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -5
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +47 -42
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +10 -9
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +47 -42
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +47 -42
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +13 -13
- package/dist/astro/routes/api/search/index.mjs +12 -12
- package/dist/astro/routes/api/search/rebuild.mjs +13 -13
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +12 -12
- package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +12 -11
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +6 -6
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +14 -13
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +14 -13
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +13 -12
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +30 -31
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/index.mjs +31 -35
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.mjs +8 -8
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +18 -16
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.d.mts +8 -0
- package/dist/astro/routes/api/taxonomies/_name_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +46 -0
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/taxonomies/_name_.d.mts +19 -0
- package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -0
- package/dist/astro/routes/api/taxonomies/_name_.mjs +88 -0
- package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -0
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +10 -9
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -6
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +7 -6
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +10 -10
- package/dist/astro/routes/sitemap.xml.mjs +8 -7
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +35 -17
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-qRhWQnel.mjs → authorize-DUElxgOQ.mjs} +2 -2
- package/dist/{authorize-qRhWQnel.mjs.map → authorize-DUElxgOQ.mjs.map} +1 -1
- package/dist/{backup-CtA6LDNw.mjs → backup-DWYpJlLj.mjs} +4 -4
- package/dist/{backup-CtA6LDNw.mjs.map → backup-DWYpJlLj.mjs.map} +1 -1
- package/dist/{base64-B-PsqheR.mjs → base64-CvLhUKQv.mjs} +1 -1
- package/dist/{base64-B-PsqheR.mjs.map → base64-CvLhUKQv.mjs.map} +1 -1
- package/dist/bundle-vn56sLos.mjs +663 -0
- package/dist/bundle-vn56sLos.mjs.map +1 -0
- package/dist/{byline-fields-CNc0Yq5i.mjs → byline-fields-txaLGoME.mjs} +2 -2
- package/dist/{byline-fields-CNc0Yq5i.mjs.map → byline-fields-txaLGoME.mjs.map} +1 -1
- package/dist/{byline-registry-ZkPKqEwC.mjs → byline-registry-DDun8sxh.mjs} +2 -2
- package/dist/{byline-registry-ZkPKqEwC.mjs.map → byline-registry-DDun8sxh.mjs.map} +1 -1
- package/dist/{byline-Cp6csL84.mjs → byline-yjvWq4ip.mjs} +5 -5
- package/dist/{byline-Cp6csL84.mjs.map → byline-yjvWq4ip.mjs.map} +1 -1
- package/dist/{bylines-cf-C9lmF.mjs → bylines-Bu7pchQ4.mjs} +5 -5
- package/dist/{bylines-cf-C9lmF.mjs.map → bylines-Bu7pchQ4.mjs.map} +1 -1
- package/dist/{bylines-CEj5CdT4.mjs → bylines-DjXS5p0P.mjs} +7 -7
- package/dist/{bylines-CEj5CdT4.mjs.map → bylines-DjXS5p0P.mjs.map} +1 -1
- package/dist/{cache-C9FptTFR.mjs → cache-C46-3Irl.mjs} +3 -3
- package/dist/{cache-C9FptTFR.mjs.map → cache-C46-3Irl.mjs.map} +1 -1
- package/dist/{challenge-store-D9VNKELo.mjs → challenge-store-SIL5DsF2.mjs} +1 -1
- package/dist/{challenge-store-D9VNKELo.mjs.map → challenge-store-SIL5DsF2.mjs.map} +1 -1
- package/dist/{chunks-DbYzib_k.mjs → chunks-fiZ8G9RJ.mjs} +2 -2
- package/dist/{chunks-DbYzib_k.mjs.map → chunks-fiZ8G9RJ.mjs.map} +1 -1
- package/dist/cli/index.mjs +655 -677
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +74 -4
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +25 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/collection-deletion-DQPvMD8R.mjs +779 -0
- package/dist/collection-deletion-DQPvMD8R.mjs.map +1 -0
- package/dist/{comment-BIkJ6Fil.mjs → comment-Dxlep6cE.mjs} +2 -2
- package/dist/{comment-BIkJ6Fil.mjs.map → comment-Dxlep6cE.mjs.map} +1 -1
- package/dist/{comment-reaction-D-laEceb.mjs → comment-reaction-D-2J84UE.mjs} +2 -2
- package/dist/{comment-reaction-D-laEceb.mjs.map → comment-reaction-D-2J84UE.mjs.map} +1 -1
- package/dist/{comments-0_w6KChA.mjs → comments-CTfZtLmM.mjs} +3 -3
- package/dist/{comments-0_w6KChA.mjs.map → comments-CTfZtLmM.mjs.map} +1 -1
- package/dist/{components-BPxrRjpE.mjs → components-CQy3lh9x.mjs} +1 -1
- package/dist/{components-BPxrRjpE.mjs.map → components-CQy3lh9x.mjs.map} +1 -1
- package/dist/{config-DyF3OKg_.mjs → config-C3EBstHi.mjs} +18 -2
- package/dist/config-C3EBstHi.mjs.map +1 -0
- package/dist/config-COQzTe5Q.d.mts +34 -0
- package/dist/config-COQzTe5Q.d.mts.map +1 -0
- package/dist/{content-CJ94NEx5.mjs → content-ZHCc1ngN.mjs} +509 -78
- package/dist/content-ZHCc1ngN.mjs.map +1 -0
- package/dist/content-list-query-wJ2WN8Vp.d.mts +26 -0
- package/dist/content-list-query-wJ2WN8Vp.d.mts.map +1 -0
- package/dist/content-refresh-B_8SJzuU.mjs +2560 -0
- package/dist/content-refresh-B_8SJzuU.mjs.map +1 -0
- package/dist/{context-C_1nrqnW.mjs → context-ZldbZcle.mjs} +25 -17
- package/dist/context-ZldbZcle.mjs.map +1 -0
- package/dist/{cron-DRV-UC4K.mjs → cron-Y9aLtgrA.mjs} +1 -1
- package/dist/{cron-DRV-UC4K.mjs.map → cron-Y9aLtgrA.mjs.map} +1 -1
- package/dist/{dashboard-DINnNVVU.mjs → dashboard-DvHbk_cv.mjs} +44 -10
- package/dist/dashboard-DvHbk_cv.mjs.map +1 -0
- package/dist/db/index.d.mts +4 -4
- package/dist/db/index.mjs +31 -8
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-migrations.d.mts +11 -0
- package/dist/db/libsql-migrations.d.mts.map +1 -0
- package/dist/db/libsql-migrations.mjs +57 -0
- package/dist/db/libsql-migrations.mjs.map +1 -0
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +10 -0
- package/dist/db/postgres-migrations.d.mts.map +1 -0
- package/dist/db/postgres-migrations.mjs +47 -0
- package/dist/db/postgres-migrations.mjs.map +1 -0
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +10 -0
- package/dist/db/sqlite-migrations.d.mts.map +1 -0
- package/dist/db/sqlite-migrations.mjs +28 -0
- package/dist/db/sqlite-migrations.mjs.map +1 -0
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CcWLaRiR.mjs → db-errors-Cl-sKYTm.mjs} +1 -1
- package/dist/{db-errors-CcWLaRiR.mjs.map → db-errors-Cl-sKYTm.mjs.map} +1 -1
- package/dist/{default-BD2FG0xV.mjs → default-DdDl3fxv.mjs} +1 -1
- package/dist/{default-BD2FG0xV.mjs.map → default-DdDl3fxv.mjs.map} +1 -1
- package/dist/{deferred-tasks-C-WRCcKo.d.mts → deferred-tasks-SDWxrgzJ.d.mts} +1 -1
- package/dist/{deferred-tasks-C-WRCcKo.d.mts.map → deferred-tasks-SDWxrgzJ.d.mts.map} +1 -1
- package/dist/{device-flow-CTqd8mud.mjs → device-flow-C0GdD_z8.mjs} +4 -4
- package/dist/{device-flow-CTqd8mud.mjs.map → device-flow-C0GdD_z8.mjs.map} +1 -1
- package/dist/direct-executor-CDXeJCSs.mjs +85 -0
- package/dist/direct-executor-CDXeJCSs.mjs.map +1 -0
- package/dist/dist-D_6CKR8z.mjs +810 -0
- package/dist/dist-D_6CKR8z.mjs.map +1 -0
- package/dist/{email-console-C6WdcWbL.mjs → email-console-BHNjIwiB.mjs} +1 -1
- package/dist/{email-console-C6WdcWbL.mjs.map → email-console-BHNjIwiB.mjs.map} +1 -1
- package/dist/{enrich-CFJJgxs_.mjs → enrich-_ySMEvEE.mjs} +2 -2
- package/dist/{enrich-CFJJgxs_.mjs.map → enrich-_ySMEvEE.mjs.map} +1 -1
- package/dist/{error-oh_9i6bR.mjs → error-DupyJZE2.mjs} +3 -3
- package/dist/{error-oh_9i6bR.mjs.map → error-DupyJZE2.mjs.map} +1 -1
- package/dist/{errors-BucQ8VYz.mjs → errors-CLUPm7aD.mjs} +14 -2
- package/dist/errors-CLUPm7aD.mjs.map +1 -0
- package/dist/{escape-CXps5F_v.mjs → escape-DUY2r2Zs.mjs} +1 -1
- package/dist/{escape-CXps5F_v.mjs.map → escape-DUY2r2Zs.mjs.map} +1 -1
- package/dist/{field-defs-cache-WD82dMQq.mjs → field-defs-cache-BzwBlJrR.mjs} +4 -4
- package/dist/{field-defs-cache-WD82dMQq.mjs.map → field-defs-cache-BzwBlJrR.mjs.map} +1 -1
- package/dist/{fts-manager-BITakW_R.mjs → fts-manager-DyZEohZC.mjs} +76 -50
- package/dist/fts-manager-DyZEohZC.mjs.map +1 -0
- package/dist/{hreflang-BdZuVBhL.mjs → hreflang-BBe83kKa.mjs} +7 -7
- package/dist/{hreflang-BdZuVBhL.mjs.map → hreflang-BBe83kKa.mjs.map} +1 -1
- package/dist/{hreflang-BaLCNcDx.d.mts → hreflang-DwT2E0Sa.d.mts} +2 -2
- package/dist/{hreflang-BaLCNcDx.d.mts.map → hreflang-DwT2E0Sa.d.mts.map} +1 -1
- package/dist/identity-Ys6Dlc9C.mjs +35 -0
- package/dist/identity-Ys6Dlc9C.mjs.map +1 -0
- package/dist/{import-C-9uqyT3.mjs → import-DPkLmeXO.mjs} +5 -5
- package/dist/{import-C-9uqyT3.mjs.map → import-DPkLmeXO.mjs.map} +1 -1
- package/dist/{index-M37iz29I.d.mts → index-BVBZj4-7.d.mts} +236 -104
- package/dist/index-BVBZj4-7.d.mts.map +1 -0
- package/dist/{index-MGw47uWq.d.mts → index-C9KuQyO-.d.mts} +5 -10
- package/dist/index-C9KuQyO-.d.mts.map +1 -0
- package/dist/index.d.mts +21 -19
- package/dist/index.mjs +73 -67
- package/dist/{init-lock-DJkX6Hto.mjs → init-lock-6b309ZrF.mjs} +1 -1
- package/dist/{init-lock-DJkX6Hto.mjs.map → init-lock-6b309ZrF.mjs.map} +1 -1
- package/dist/{load-DV1DZuUJ.mjs → load-YJ2xl3ra.mjs} +2 -2
- package/dist/{load-DV1DZuUJ.mjs.map → load-YJ2xl3ra.mjs.map} +1 -1
- package/dist/{loader-CGugY7Zl.mjs → loader-CdG_Ci3H.mjs} +95 -53
- package/dist/loader-CdG_Ci3H.mjs.map +1 -0
- package/dist/manifest-builder-B252yQUf.mjs +189 -0
- package/dist/manifest-builder-B252yQUf.mjs.map +1 -0
- package/dist/{manifest-schema-Da7kj23y.mjs → manifest-schema-BXbUAHod.mjs} +1 -1
- package/dist/{manifest-schema-Da7kj23y.mjs.map → manifest-schema-BXbUAHod.mjs.map} +1 -1
- package/dist/media/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +3 -2
- package/dist/media/index.mjs.map +1 -1
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +6 -5
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-OhYL-7Io.mjs → media-BWWWb8kg.mjs} +92 -3
- package/dist/media-BWWWb8kg.mjs.map +1 -0
- package/dist/{media-BP7S-nHT.mjs → media-CzhAn2--.mjs} +2 -2
- package/dist/{media-BP7S-nHT.mjs.map → media-CzhAn2--.mjs.map} +1 -1
- package/dist/{media-allowlist-D-peH1H5.mjs → media-allowlist-D6x-Us02.mjs} +14 -3
- package/dist/media-allowlist-D6x-Us02.mjs.map +1 -0
- package/dist/{media-upload-DtrwU2B0.mjs → media-upload-CHBVn6m-.mjs} +10 -8
- package/dist/{media-upload-DtrwU2B0.mjs.map → media-upload-CHBVn6m-.mjs.map} +1 -1
- package/dist/{media-url-DYs_YLOx.mjs → media-url-BvoX88FA.mjs} +1 -1
- package/dist/{media-url-DYs_YLOx.mjs.map → media-url-BvoX88FA.mjs.map} +1 -1
- package/dist/{media-usage-BlxfTkN0.mjs → media-usage-BZCydfvu.mjs} +137 -60
- package/dist/media-usage-BZCydfvu.mjs.map +1 -0
- package/dist/media-usage-work-CLo_6tct.mjs +152 -0
- package/dist/media-usage-work-CLo_6tct.mjs.map +1 -0
- package/dist/media-usage-work-DrCbqBcl.mjs +424 -0
- package/dist/media-usage-work-DrCbqBcl.mjs.map +1 -0
- package/dist/media-usage-write-fence-aHEgN1zB.mjs +42 -0
- package/dist/media-usage-write-fence-aHEgN1zB.mjs.map +1 -0
- package/dist/{menus-Y54RDPIN.mjs → menus-DSo5QeW0.mjs} +351 -95
- package/dist/menus-DSo5QeW0.mjs.map +1 -0
- package/dist/{menus-BcQWxeXu.mjs → menus-TCNSd2vp.mjs} +3 -3
- package/dist/{menus-BcQWxeXu.mjs.map → menus-TCNSd2vp.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +22 -0
- package/dist/migrations/index.d.mts.map +1 -0
- package/dist/migrations/index.mjs +7 -0
- package/dist/{mode-BWyTBe3I.mjs → mode-BDoH_WcF.mjs} +1 -1
- package/dist/{mode-BWyTBe3I.mjs.map → mode-BDoH_WcF.mjs.map} +1 -1
- package/dist/{normalize-C-SHXmra.mjs → normalize-Bc-s_r-a.mjs} +1 -1
- package/dist/{normalize-C-SHXmra.mjs.map → normalize-Bc-s_r-a.mjs.map} +1 -1
- package/dist/{oauth-authorization-ClvktmrL.mjs → oauth-authorization-iOikmrJd.mjs} +4 -4
- package/dist/{oauth-authorization-ClvktmrL.mjs.map → oauth-authorization-iOikmrJd.mjs.map} +1 -1
- package/dist/{oauth-clients-8ao-U66l.mjs → oauth-clients-CvI0nHMJ.mjs} +1 -1
- package/dist/{oauth-clients-8ao-U66l.mjs.map → oauth-clients-CvI0nHMJ.mjs.map} +1 -1
- package/dist/{oauth-state-store-B1ofdTiQ.mjs → oauth-state-store-Ba8KZlwW.mjs} +1 -1
- package/dist/{oauth-state-store-B1ofdTiQ.mjs.map → oauth-state-store-Ba8KZlwW.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-CscEuIiR.mjs → oauth-user-lookup-C5SQwGYC.mjs} +1 -1
- package/dist/{oauth-user-lookup-CscEuIiR.mjs.map → oauth-user-lookup-C5SQwGYC.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-CA4eVX6P.d.mts → options--hhz-jZ1.d.mts} +4 -3
- package/dist/options--hhz-jZ1.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-CJKNuewM.mjs → parse-DFbuc-Fh.mjs} +2 -2
- package/dist/{parse-CJKNuewM.mjs.map → parse-DFbuc-Fh.mjs.map} +1 -1
- package/dist/{passkey-config-D-zrzMJI.mjs → passkey-config-DFAmUyuE.mjs} +1 -1
- package/dist/{passkey-config-D-zrzMJI.mjs.map → passkey-config-DFAmUyuE.mjs.map} +1 -1
- package/dist/{placeholder-DaeNS-VG.d.mts → placeholder-Dp0K3RkD.d.mts} +1 -1
- package/dist/{placeholder-DaeNS-VG.d.mts.map → placeholder-Dp0K3RkD.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +8 -1
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +7 -4
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/policy-TluUIxuu.mjs +45 -0
- package/dist/policy-TluUIxuu.mjs.map +1 -0
- package/dist/{portable-text-B_kqBmXB.mjs → portable-text-imBW5cHK.mjs} +1 -1
- package/dist/{portable-text-B_kqBmXB.mjs.map → portable-text-imBW5cHK.mjs.map} +1 -1
- package/dist/{preview-BU6PaLpM.mjs → preview-PW-nOnq4.mjs} +2 -2
- package/dist/{preview-BU6PaLpM.mjs.map → preview-PW-nOnq4.mjs.map} +1 -1
- package/dist/protocol-DjsJHTlK.d.mts +52 -0
- package/dist/protocol-DjsJHTlK.d.mts.map +1 -0
- package/dist/{public-url-Ox9oOlgp.mjs → public-url-CWoFhQT8.mjs} +1 -1
- package/dist/{public-url-Ox9oOlgp.mjs.map → public-url-CWoFhQT8.mjs.map} +1 -1
- package/dist/{query-rC9HKv1N.mjs → query-BWs7O5Il.mjs} +3 -3
- package/dist/{query-rC9HKv1N.mjs.map → query-BWs7O5Il.mjs.map} +1 -1
- package/dist/{query-C5w7PsRQ.mjs → query-zTVAR1Sl.mjs} +31 -49
- package/dist/query-zTVAR1Sl.mjs.map +1 -0
- package/dist/{rate-limit-kug6q99V.mjs → rate-limit-Bx4g9m3p.mjs} +2 -2
- package/dist/{rate-limit-kug6q99V.mjs.map → rate-limit-Bx4g9m3p.mjs.map} +1 -1
- package/dist/{redirect-Egf2R9yP.mjs → redirect-BgAOGHDq.mjs} +1 -1
- package/dist/{redirect-Egf2R9yP.mjs.map → redirect-BgAOGHDq.mjs.map} +1 -1
- package/dist/{redirect-DIJxXKOG.mjs → redirect-COsS6SWJ.mjs} +2 -2
- package/dist/{redirect-DIJxXKOG.mjs.map → redirect-COsS6SWJ.mjs.map} +1 -1
- package/dist/{redirects-G8wAhWAf.mjs → redirects-DTDHWH31.mjs} +133 -14
- package/dist/redirects-DTDHWH31.mjs.map +1 -0
- package/dist/{redirects-Bzm812bY.mjs → redirects-DyChwDkG.mjs} +4 -4
- package/dist/{redirects-Bzm812bY.mjs.map → redirects-DyChwDkG.mjs.map} +1 -1
- package/dist/registry-Cqa2I749.mjs +1275 -0
- package/dist/registry-Cqa2I749.mjs.map +1 -0
- package/dist/{relation-Cbe3Sd3m.mjs → relation-BnHB0T4J.mjs} +3 -3
- package/dist/{relation-Cbe3Sd3m.mjs.map → relation-BnHB0T4J.mjs.map} +1 -1
- package/dist/{relations-Bw_E1TXo.mjs → relations-BBApI4e2.mjs} +3 -3
- package/dist/{relations-Bw_E1TXo.mjs.map → relations-BBApI4e2.mjs.map} +1 -1
- package/dist/{relations-G2ta7GIl.d.mts → relations-BHo5A8Zf.d.mts} +367 -33
- package/dist/relations-BHo5A8Zf.d.mts.map +1 -0
- package/dist/{relations-qHwpUe66.mjs → relations-D5sM5fW0.mjs} +6 -6
- package/dist/{relations-qHwpUe66.mjs.map → relations-D5sM5fW0.mjs.map} +1 -1
- package/dist/request-context.d.mts +1 -1
- package/dist/{request-meta-Df-jFbAd.mjs → request-meta-DgZJh3zG.mjs} +2 -2
- package/dist/{request-meta-Df-jFbAd.mjs.map → request-meta-DgZJh3zG.mjs.map} +1 -1
- package/dist/{resolve-DZzG4HqM.mjs → resolve-DOhVEvty.mjs} +2 -2
- package/dist/{resolve-DZzG4HqM.mjs.map → resolve-DOhVEvty.mjs.map} +1 -1
- package/dist/{runner-BaADli8l.d.mts → runner-BYHZn3Jy.d.mts} +16 -3
- package/dist/runner-BYHZn3Jy.d.mts.map +1 -0
- package/dist/{runner-BFTrkYhu.mjs → runner-C1T11CfC.mjs} +1190 -257
- package/dist/runner-C1T11CfC.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +4 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema-2AOsSn2v.mjs +390 -0
- package/dist/schema-2AOsSn2v.mjs.map +1 -0
- package/dist/{schema-CiQXr6_F.mjs → schema-DZ5YVVZj.mjs} +3 -3
- package/dist/{schema-CiQXr6_F.mjs.map → schema-DZ5YVVZj.mjs.map} +1 -1
- package/dist/{scopes-CNJVT5i5.mjs → scopes-8ClPF2bC.mjs} +3 -3
- package/dist/{scopes-CNJVT5i5.mjs.map → scopes-8ClPF2bC.mjs.map} +1 -1
- package/dist/{search-FZhx5dDU.mjs → search-u1QYdOCG.mjs} +25 -15
- package/dist/search-u1QYdOCG.mjs.map +1 -0
- package/dist/{secrets-DLd8RXee.mjs → secrets-BEgsAQEU.mjs} +3 -3
- package/dist/{secrets-DLd8RXee.mjs.map → secrets-BEgsAQEU.mjs.map} +1 -1
- package/dist/{sections-BrIrMUCn.mjs → sections-DmHviGyM.mjs} +3 -3
- package/dist/{sections-BrIrMUCn.mjs.map → sections-DmHviGyM.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +24 -22
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +16 -15
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-CobNfOvb.mjs → seo-AFpVvTqr.mjs} +5 -3
- package/dist/seo-AFpVvTqr.mjs.map +1 -0
- package/dist/{seo-DTHRntNC.mjs → seo-Dq4G-RrO.mjs} +2 -2
- package/dist/{seo-DTHRntNC.mjs.map → seo-Dq4G-RrO.mjs.map} +1 -1
- package/dist/{service-B-pYGPgR.mjs → service-BpArayPr.mjs} +3 -3
- package/dist/{service-B-pYGPgR.mjs.map → service-BpArayPr.mjs.map} +1 -1
- package/dist/{session-user-BvM9-zNl.mjs → session-user-BEorKVT-.mjs} +1 -1
- package/dist/{session-user-BvM9-zNl.mjs.map → session-user-BEorKVT-.mjs.map} +1 -1
- package/dist/{settings-DPHau-WH.mjs → settings-DE9xtzqd.mjs} +3 -3
- package/dist/{settings-DPHau-WH.mjs.map → settings-DE9xtzqd.mjs.map} +1 -1
- package/dist/{settings-kJhGiQ4z.mjs → settings-xRdoUZr0.mjs} +4 -4
- package/dist/{settings-kJhGiQ4z.mjs.map → settings-xRdoUZr0.mjs.map} +1 -1
- package/dist/{setup-complete-u50Qm8rY.mjs → setup-complete-BnT8pq_C.mjs} +1 -1
- package/dist/{setup-complete-u50Qm8rY.mjs.map → setup-complete-BnT8pq_C.mjs.map} +1 -1
- package/dist/{setup-nonce-DCjiiOD2.mjs → setup-nonce-CBitf_oQ.mjs} +1 -1
- package/dist/{setup-nonce-DCjiiOD2.mjs.map → setup-nonce-CBitf_oQ.mjs.map} +1 -1
- package/dist/{single-flight-cache-DW3w11Pu.mjs → single-flight-cache-B0eLKS6K.mjs} +2 -2
- package/dist/{single-flight-cache-DW3w11Pu.mjs.map → single-flight-cache-B0eLKS6K.mjs.map} +1 -1
- package/dist/{site-url-I-lJ5kma.mjs → site-url-DjpIXMXJ.mjs} +2 -2
- package/dist/{site-url-I-lJ5kma.mjs.map → site-url-DjpIXMXJ.mjs.map} +1 -1
- package/dist/slugify-B994zkXC.mjs +17 -0
- package/dist/slugify-B994zkXC.mjs.map +1 -0
- package/dist/{snapshot-I_fjLDaD.mjs → snapshot-BBlGkb2q.mjs} +1 -1
- package/dist/{snapshot-I_fjLDaD.mjs.map → snapshot-BBlGkb2q.mjs.map} +1 -1
- package/dist/{ssrf-CTa6v21i.mjs → ssrf-Cpvg_n3A.mjs} +1 -1
- package/dist/{ssrf-CTa6v21i.mjs.map → ssrf-Cpvg_n3A.mjs.map} +1 -1
- package/dist/{state-CQvoefYP.mjs → state-DYwPue40.mjs} +1 -1
- package/dist/{state-CQvoefYP.mjs.map → state-DYwPue40.mjs.map} +1 -1
- package/dist/{status-CIsmlC1E.mjs → status-CWVYpbD8.mjs} +1 -1
- package/dist/{status-CIsmlC1E.mjs.map → status-CWVYpbD8.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +3 -3
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/target-DixqqV5i.mjs +27 -0
- package/dist/target-DixqqV5i.mjs.map +1 -0
- package/dist/{taxonomies-CLN1N92E.mjs → taxonomies-BlrncHi9.mjs} +75 -64
- package/dist/taxonomies-BlrncHi9.mjs.map +1 -0
- package/dist/{taxonomies-CKuaZER5.mjs → taxonomies-OHUIiIpI.mjs} +280 -56
- package/dist/taxonomies-OHUIiIpI.mjs.map +1 -0
- package/dist/{taxonomy-pOrB2kZe.mjs → taxonomy-BqCZ1TdU.mjs} +131 -78
- package/dist/taxonomy-BqCZ1TdU.mjs.map +1 -0
- package/dist/{tokens-DagaJGK8.mjs → tokens-C39klX8R.mjs} +2 -2
- package/dist/{tokens-DagaJGK8.mjs.map → tokens-C39klX8R.mjs.map} +1 -1
- package/dist/{transport-DVsa5YYo.mjs → transport-DBJwa-Si.mjs} +1 -1
- package/dist/{transport-DVsa5YYo.mjs.map → transport-DBJwa-Si.mjs.map} +1 -1
- package/dist/{transport-CAwTaTp_.d.mts → transport-RQE36APG.d.mts} +1 -1
- package/dist/{transport-CAwTaTp_.d.mts.map → transport-RQE36APG.d.mts.map} +1 -1
- package/dist/{trusted-proxy-D20_7fyX.mjs → trusted-proxy-CEVekpby.mjs} +1 -1
- package/dist/{trusted-proxy-D20_7fyX.mjs.map → trusted-proxy-CEVekpby.mjs.map} +1 -1
- package/dist/{types-NBI3rF-_.mjs → types-75KIqzL9.mjs} +18 -2
- package/dist/types-75KIqzL9.mjs.map +1 -0
- package/dist/{types-BjxTKxrZ.mjs → types-BW1syrlw.mjs} +1 -1
- package/dist/{types-BjxTKxrZ.mjs.map → types-BW1syrlw.mjs.map} +1 -1
- package/dist/{types-DLG4IFEQ.d.mts → types-BcqdcT-r.d.mts} +1 -1
- package/dist/{types-DLG4IFEQ.d.mts.map → types-BcqdcT-r.d.mts.map} +1 -1
- package/dist/{types-LoagAGzH.d.mts → types-BntycPTF.d.mts} +1 -1
- package/dist/{types-LoagAGzH.d.mts.map → types-BntycPTF.d.mts.map} +1 -1
- package/dist/{types-BnFP1M3J.d.mts → types-C2pMvO62.d.mts} +32 -10
- package/dist/types-C2pMvO62.d.mts.map +1 -0
- package/dist/{types-Cd8iuS1J.mjs → types-CQPWhPxE.mjs} +9 -12
- package/dist/types-CQPWhPxE.mjs.map +1 -0
- package/dist/{types-C8oz_ayJ.d.mts → types-CXnOzDe1.d.mts} +1 -1
- package/dist/{types-C8oz_ayJ.d.mts.map → types-CXnOzDe1.d.mts.map} +1 -1
- package/dist/types-CtzytVXn.mjs.map +1 -1
- package/dist/{types-BGWPMiBO.d.mts → types-DN64_zzZ.d.mts} +44 -5
- package/dist/types-DN64_zzZ.d.mts.map +1 -0
- package/dist/{types-Dc4ntQjQ.d.mts → types-DQIDRKF2.d.mts} +124 -1
- package/dist/types-DQIDRKF2.d.mts.map +1 -0
- package/dist/{types-CbUcuxxc.d.mts → types-DWRhk9xZ.d.mts} +1 -1
- package/dist/{types-CbUcuxxc.d.mts.map → types-DWRhk9xZ.d.mts.map} +1 -1
- package/dist/{types-BK6U01Ro.d.mts → types-Dfk8KI5R.d.mts} +1 -1
- package/dist/{types-BK6U01Ro.d.mts.map → types-Dfk8KI5R.d.mts.map} +1 -1
- package/dist/{types-Cz8hNch2.d.mts → types-DrJrVCT1.d.mts} +25 -5
- package/dist/types-DrJrVCT1.d.mts.map +1 -0
- package/dist/{upload-attempts-D8QAFLUJ.mjs → upload-attempts-D4FS8LT6.mjs} +1 -1
- package/dist/{upload-attempts-D8QAFLUJ.mjs.map → upload-attempts-D4FS8LT6.mjs.map} +1 -1
- package/dist/url-pattern-BHS0V5Ng.mjs +33 -0
- package/dist/url-pattern-BHS0V5Ng.mjs.map +1 -0
- package/dist/{user-DBrq4UVq.mjs → user-DJZfUJVE.mjs} +3 -3
- package/dist/{user-DBrq4UVq.mjs.map → user-DJZfUJVE.mjs.map} +1 -1
- package/dist/{utils-hLzi_2Fn.mjs → utils-D4vD_Y98.mjs} +3 -3
- package/dist/{utils-hLzi_2Fn.mjs.map → utils-D4vD_Y98.mjs.map} +1 -1
- package/dist/{validate-mKo3RxBM.mjs → validate-BMLBvxOC.mjs} +24 -5
- package/dist/validate-BMLBvxOC.mjs.map +1 -0
- package/dist/{validate-C3oSmA7F.d.mts → validate-CTqt5nuE.d.mts} +15 -7
- package/dist/validate-CTqt5nuE.d.mts.map +1 -0
- package/dist/{validation-BgpucsvF.mjs → validation-npvENUCB.mjs} +11 -10
- package/dist/{validation-BgpucsvF.mjs.map → validation-npvENUCB.mjs.map} +1 -1
- package/dist/version-DB_fqCSI.mjs +7 -0
- package/dist/{version-C4PnpmoV.mjs.map → version-DB_fqCSI.mjs.map} +1 -1
- package/dist/{widgets-CJJtkiKh.mjs → widgets-BD3ho7Rq.mjs} +3 -3
- package/dist/{widgets-CJJtkiKh.mjs.map → widgets-BD3ho7Rq.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-9PPSy8X6.mjs → wxr-taxonomies-B1R3vBoD.mjs} +13 -32
- package/dist/{wxr-taxonomies-9PPSy8X6.mjs.map → wxr-taxonomies-B1R3vBoD.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-Bkpp_2tK.d.mts → wxr-taxonomies-Ca68766D.d.mts} +1 -1
- package/dist/{wxr-taxonomies-Bkpp_2tK.d.mts.map → wxr-taxonomies-Ca68766D.d.mts.map} +1 -1
- package/dist/{zod-generator-CG64Hnbh.mjs → zod-generator-LC-on_Vb.mjs} +52 -5
- package/dist/zod-generator-LC-on_Vb.mjs.map +1 -0
- package/package.json +32 -8
- package/src/api/errors.ts +12 -0
- package/src/api/handlers/content.ts +127 -29
- package/src/api/handlers/dashboard.ts +12 -2
- package/src/api/handlers/index.ts +16 -0
- package/src/api/handlers/manifest.ts +2 -0
- package/src/api/handlers/media-allowlist.ts +13 -2
- package/src/api/handlers/media-usage-work.ts +188 -0
- package/src/api/handlers/media-usage.ts +5 -3
- package/src/api/handlers/schema.ts +9 -3
- package/src/api/handlers/seo.ts +5 -2
- package/src/api/handlers/taxonomies.ts +345 -82
- package/src/api/media-usage-write-fence.ts +64 -0
- package/src/api/openapi/document.ts +199 -0
- package/src/api/schemas/common.ts +3 -1
- package/src/api/schemas/content.ts +122 -1
- package/src/api/schemas/media-usage.ts +133 -0
- package/src/api/schemas/schema.ts +78 -3
- package/src/api/schemas/taxonomies.ts +40 -8
- package/src/api/types.ts +1 -0
- package/src/astro/integration/index.ts +101 -56
- package/src/astro/integration/routes.ts +34 -4
- package/src/astro/integration/runtime.ts +18 -0
- package/src/astro/integration/virtual-modules.ts +25 -1
- package/src/astro/integration/vite-config.ts +16 -1
- package/src/astro/middleware/media-usage-write-fence.ts +30 -0
- package/src/astro/middleware/redirect.ts +12 -2
- package/src/astro/middleware/scoped-db.ts +21 -0
- package/src/astro/middleware.ts +140 -16
- package/src/astro/routes/api/admin/media-usage/collection-deletions/index.ts +22 -0
- package/src/astro/routes/api/admin/media-usage/collection-deletions/retry.ts +22 -0
- package/src/astro/routes/api/admin/media-usage/work/index.ts +26 -0
- package/src/astro/routes/api/admin/media-usage/work/retry.ts +26 -0
- package/src/astro/routes/api/admin/plugins/[id]/disable.ts +4 -0
- package/src/astro/routes/api/admin/plugins/[id]/enable.ts +4 -0
- package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +4 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +4 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +4 -0
- package/src/astro/routes/api/auth/dev-bypass.ts +0 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +67 -31
- package/src/astro/routes/api/import/wordpress/execute.ts +3 -10
- package/src/astro/routes/api/mcp.ts +1 -0
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +7 -1
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +1 -7
- package/src/astro/routes/api/setup/dev-bypass.ts +2 -7
- package/src/astro/routes/api/setup/index.ts +5 -13
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +1 -0
- package/src/astro/routes/api/taxonomies/[name]/translations.ts +48 -0
- package/src/astro/routes/api/taxonomies/[name].ts +102 -0
- package/src/astro/types.ts +25 -4
- package/src/cleanup.ts +6 -12
- package/src/cli/commands/doctor.ts +193 -6
- package/src/cli/commands/export-seed.ts +4 -1
- package/src/cli/commands/migrate.ts +593 -0
- package/src/cli/index.ts +2 -23
- package/src/client/index.ts +119 -0
- package/src/components/Block.astro +12 -0
- package/src/components/InlinePortableTextEditor.tsx +89 -1
- package/src/content/converters/mark-safety.ts +120 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +25 -16
- package/src/content/converters/prosemirror-to-portable-text.ts +12 -2
- package/src/content-list-query.ts +29 -0
- package/src/database/index.ts +8 -2
- package/src/database/migrations/060_collection_admin_config.ts +16 -0
- package/src/database/migrations/061_media_usage_cleanup.ts +77 -0
- package/src/database/migrations/062_media_usage_cleanup_fence.ts +295 -0
- package/src/database/migrations/063_media_usage_incremental_work.ts +397 -0
- package/src/database/migrations/064_fts_plain_text.ts +253 -0
- package/src/database/migrations/065_media_usage_collection_deletion.ts +85 -0
- package/src/database/migrations/066_media_usage_reconciliation.ts +115 -0
- package/src/database/migrations/067_indexed_content_fields.ts +39 -0
- package/src/database/migrations/068_content_taxonomy_entry_groups.ts +61 -0
- package/src/database/migrations/069_collection_title_date_fields.ts +45 -0
- package/src/database/migrations/070_collection_routable.ts +18 -0
- package/src/database/migrations/policy.ts +70 -0
- package/src/database/migrations/runner.ts +71 -3
- package/src/database/repositories/content.ts +861 -96
- package/src/database/repositories/media-usage-work.ts +848 -0
- package/src/database/repositories/media-usage.ts +1502 -138
- package/src/database/repositories/revision.ts +17 -6
- package/src/database/repositories/taxonomy.ts +234 -103
- package/src/database/repositories/types.ts +51 -2
- package/src/database/types.ts +134 -16
- package/src/db/adapters.ts +78 -2
- package/src/db/index.ts +6 -1
- package/src/db/libsql-migrations.ts +72 -0
- package/src/db/postgres-migrations.ts +59 -0
- package/src/db/sqlite-migrations.ts +37 -0
- package/src/emdash-runtime.ts +271 -35
- package/src/fields/file.ts +7 -4
- package/src/fields/image.ts +8 -1
- package/src/fields/types.ts +18 -5
- package/src/i18n/config.ts +32 -0
- package/src/i18n/normalize.ts +31 -0
- package/src/i18n/repair-locale-casing.ts +0 -14
- package/src/i18n/taxonomy-locale-diagnostic.ts +47 -0
- package/src/import/wxr-taxonomies.ts +7 -47
- package/src/index.ts +32 -3
- package/src/loader.ts +119 -65
- package/src/mcp/server.ts +242 -34
- package/src/media/usage/activation.ts +626 -0
- package/src/media/usage/capture-triggers.ts +543 -0
- package/src/media/usage/cleanup.ts +305 -0
- package/src/media/usage/collection-deletion-processor.ts +356 -0
- package/src/media/usage/collection-deletion.ts +836 -0
- package/src/media/usage/content-fields.ts +40 -3
- package/src/media/usage/content-refresh.ts +356 -47
- package/src/media/usage/content-repair.ts +180 -61
- package/src/media/usage/content-snapshots.ts +85 -105
- package/src/media/usage/projection-fingerprint.ts +129 -0
- package/src/media/usage/reconciliation-processor.ts +372 -0
- package/src/media/usage/reconciliation.ts +1117 -0
- package/src/media/usage/source-key.ts +4 -0
- package/src/media/usage/types.ts +2 -0
- package/src/media/usage/work-processor.ts +248 -0
- package/src/menus/index.ts +246 -141
- package/src/migrations/config-loader.ts +205 -0
- package/src/migrations/direct-executor.ts +141 -0
- package/src/migrations/identity.ts +46 -0
- package/src/migrations/index.ts +19 -0
- package/src/migrations/integration-metadata.ts +67 -0
- package/src/migrations/manifest-builder.ts +55 -0
- package/src/migrations/manifest-writer.ts +63 -0
- package/src/migrations/manifest.ts +197 -0
- package/src/migrations/protocol.ts +59 -0
- package/src/migrations/target.ts +35 -0
- package/src/plugin-types.ts +8 -0
- package/src/plugins/adapt-sandbox-entry.ts +24 -5
- package/src/plugins/context.ts +24 -7
- package/src/plugins/index.ts +9 -0
- package/src/plugins/routes.ts +43 -1
- package/src/plugins/sandbox/index.ts +10 -1
- package/src/plugins/sandbox/types.ts +78 -1
- package/src/plugins/scheduler/node.ts +13 -1
- package/src/plugins/scheduler/types.ts +2 -0
- package/src/plugins/types.ts +39 -2
- package/src/query.ts +29 -37
- package/src/scheduler-health.ts +46 -0
- package/src/schema/registry.ts +777 -255
- package/src/schema/types.ts +50 -8
- package/src/schema/url-pattern.ts +33 -0
- package/src/schema/zod-generator.ts +77 -5
- package/src/search/fts-manager.ts +117 -76
- package/src/search/query.ts +32 -11
- package/src/search/types.ts +2 -0
- package/src/seed/apply.ts +68 -15
- package/src/seed/types.ts +11 -3
- package/src/seed/validate.ts +52 -2
- package/src/taxonomies/index.ts +77 -75
- package/src/taxonomies/term-counts.ts +21 -8
- package/src/utils/slugify.ts +1 -29
- package/src/virtual-modules.d.ts +24 -0
- package/dist/adapters-BMyNSSZi.d.mts.map +0 -1
- package/dist/api-D2hunekQ.mjs.map +0 -1
- package/dist/apply-kwNEJW2l.mjs.map +0 -1
- package/dist/config-DyF3OKg_.mjs.map +0 -1
- package/dist/content-CJ94NEx5.mjs.map +0 -1
- package/dist/content-refresh-Xw7aKmou.mjs +0 -1629
- package/dist/content-refresh-Xw7aKmou.mjs.map +0 -1
- package/dist/context-C_1nrqnW.mjs.map +0 -1
- package/dist/dashboard-DINnNVVU.mjs.map +0 -1
- package/dist/errors-BucQ8VYz.mjs.map +0 -1
- package/dist/fts-manager-BITakW_R.mjs.map +0 -1
- package/dist/index-M37iz29I.d.mts.map +0 -1
- package/dist/index-MGw47uWq.d.mts.map +0 -1
- package/dist/loader-CGugY7Zl.mjs.map +0 -1
- package/dist/media-OhYL-7Io.mjs.map +0 -1
- package/dist/media-allowlist-D-peH1H5.mjs.map +0 -1
- package/dist/media-usage-BlxfTkN0.mjs.map +0 -1
- package/dist/menus-Y54RDPIN.mjs.map +0 -1
- package/dist/options-CA4eVX6P.d.mts.map +0 -1
- package/dist/query-C5w7PsRQ.mjs.map +0 -1
- package/dist/redirects-G8wAhWAf.mjs.map +0 -1
- package/dist/registry-Dbodb4Uo.mjs +0 -840
- package/dist/registry-Dbodb4Uo.mjs.map +0 -1
- package/dist/relations-G2ta7GIl.d.mts.map +0 -1
- package/dist/runner-BFTrkYhu.mjs.map +0 -1
- package/dist/runner-BaADli8l.d.mts.map +0 -1
- package/dist/search-FZhx5dDU.mjs.map +0 -1
- package/dist/seo-CobNfOvb.mjs.map +0 -1
- package/dist/slugify-C_tqlU4G.mjs +0 -30
- package/dist/slugify-C_tqlU4G.mjs.map +0 -1
- package/dist/taxonomies-CKuaZER5.mjs.map +0 -1
- package/dist/taxonomies-CLN1N92E.mjs.map +0 -1
- package/dist/taxonomy-pOrB2kZe.mjs.map +0 -1
- package/dist/types-BGWPMiBO.d.mts.map +0 -1
- package/dist/types-BnFP1M3J.d.mts.map +0 -1
- package/dist/types-Cd8iuS1J.mjs.map +0 -1
- package/dist/types-Cz8hNch2.d.mts.map +0 -1
- package/dist/types-Dc4ntQjQ.d.mts.map +0 -1
- package/dist/types-NBI3rF-_.mjs.map +0 -1
- package/dist/validate-C3oSmA7F.d.mts.map +0 -1
- package/dist/validate-mKo3RxBM.mjs.map +0 -1
- package/dist/version-C4PnpmoV.mjs +0 -7
- package/dist/zod-generator-CG64Hnbh.mjs.map +0 -1
- /package/dist/{api-tokens-Dai9dND0.mjs → api-tokens-rIXC6LdE.mjs} +0 -0
- /package/dist/{ssrf-Cj568Dgs.mjs → ssrf-DpXgKsna.mjs} +0 -0
- /package/dist/{types-DKuWPYV5.mjs → types-CP1CflWf.mjs} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as __exportAll } from "./runner-C1T11CfC.mjs";
|
|
2
2
|
import { t as validateIdentifier } from "./validate-BpwoDOgt.mjs";
|
|
3
3
|
import { c as invalidateCollectionCache } from "./object-cache-71tPfV4A.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import { n as
|
|
7
|
-
import {
|
|
4
|
+
import { c as isIndexableFieldType } from "./types-75KIqzL9.mjs";
|
|
5
|
+
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-fiZ8G9RJ.mjs";
|
|
6
|
+
import { n as isMissingTableError } from "./db-errors-Cl-sKYTm.mjs";
|
|
7
|
+
import { n as slugify } from "./slugify-B994zkXC.mjs";
|
|
8
|
+
import { a as ScheduledNotDueError, i as InvalidCursorError, n as ContentMutationConflictError, o as decodeCursor, r as EmDashValidationError, s as encodeCursor, t as ContentCollectionNotFoundError } from "./types-CQPWhPxE.mjs";
|
|
8
9
|
import { sql } from "kysely";
|
|
9
10
|
import { monotonicFactory, ulid } from "ulidx";
|
|
10
11
|
|
|
@@ -134,15 +135,18 @@ var RevisionRepository = class {
|
|
|
134
135
|
/**
|
|
135
136
|
* Delete old revisions, keeping the most recent N
|
|
136
137
|
*/
|
|
137
|
-
async pruneOldRevisions(collection, entryId, keepCount) {
|
|
138
|
+
async pruneOldRevisions(collection, entryId, keepCount, throughRevisionId) {
|
|
138
139
|
validateIdentifier(collection, "collection");
|
|
139
140
|
const tableName = `ec_${collection}`;
|
|
140
|
-
|
|
141
|
+
let keepQuery = this.db.selectFrom("revisions").select("id").where("collection", "=", collection).where("entry_id", "=", entryId).orderBy("created_at", "desc").orderBy("id", "desc").limit(keepCount);
|
|
142
|
+
if (throughRevisionId) keepQuery = keepQuery.where("id", "<=", throughRevisionId);
|
|
143
|
+
const keepIds = (await keepQuery.execute()).map((r) => r.id);
|
|
141
144
|
if (keepIds.length === 0) return 0;
|
|
142
145
|
const result = await sql`
|
|
143
146
|
DELETE FROM revisions
|
|
144
147
|
WHERE collection = ${collection}
|
|
145
148
|
AND entry_id = ${entryId}
|
|
149
|
+
${throughRevisionId ? sql`AND id <= ${throughRevisionId}` : sql``}
|
|
146
150
|
AND id NOT IN (${sql.join(keepIds.map((id) => sql`${id}`))})
|
|
147
151
|
AND NOT EXISTS (
|
|
148
152
|
SELECT 1 FROM ${sql.ref(tableName)} AS content
|
|
@@ -153,7 +157,7 @@ var RevisionRepository = class {
|
|
|
153
157
|
return Number(result.numAffectedRows ?? 0);
|
|
154
158
|
}
|
|
155
159
|
async pruneQueuedEntry(collection, entryId, queuedRevisionId, keepCount) {
|
|
156
|
-
const pruned = await this.pruneOldRevisions(collection, entryId, keepCount);
|
|
160
|
+
const pruned = await this.pruneOldRevisions(collection, entryId, keepCount, queuedRevisionId);
|
|
157
161
|
await this.db.deleteFrom("_emdash_revision_prune_queue").where("collection", "=", collection).where("entry_id", "=", entryId).where("revision_id", "=", queuedRevisionId).execute();
|
|
158
162
|
return pruned;
|
|
159
163
|
}
|
|
@@ -189,10 +193,17 @@ var RevisionRepository = class {
|
|
|
189
193
|
|
|
190
194
|
//#endregion
|
|
191
195
|
//#region src/database/repositories/content.ts
|
|
192
|
-
var content_exports = /* @__PURE__ */ __exportAll({
|
|
196
|
+
var content_exports = /* @__PURE__ */ __exportAll({
|
|
197
|
+
ContentRepository: () => ContentRepository,
|
|
198
|
+
isSystemOrderField: () => isSystemOrderField
|
|
199
|
+
});
|
|
193
200
|
const ULID_PATTERN = /^[0-9A-Z]{26}$/;
|
|
194
201
|
const SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/;
|
|
202
|
+
const MAX_DRAFT_STAGE_ATTEMPTS = 32;
|
|
195
203
|
const LIKE_WILDCARD_RE = /[\\%_]/g;
|
|
204
|
+
const MAX_INDEXED_FIELD_FILTERS = 20;
|
|
205
|
+
const MAX_IN_FILTER_VALUES = SQL_BATCH_SIZE;
|
|
206
|
+
const MAX_FILTER_STRING_LENGTH = 2048;
|
|
196
207
|
function nullableColumnMatch(column, value) {
|
|
197
208
|
validateIdentifier(column, "content column");
|
|
198
209
|
return value === null ? sql`${sql.ref(column)} IS NULL` : sql`${sql.ref(column)} = ${value}`;
|
|
@@ -204,6 +215,10 @@ function matchesPublication(observed, existing, revision, revisionId, slug, publ
|
|
|
204
215
|
if (observed.version !== existing.version + 1 || observed.status !== "published" || observed.slug !== slug || observed.liveRevisionId !== revisionId || observed.draftRevisionId !== null || observed.scheduledAt !== null || observed.publishedAt !== publishedAt || observed.updatedAt !== updatedAt) return false;
|
|
205
216
|
return Object.entries(revision.data).every(([key, value]) => SYSTEM_COLUMNS.has(key) || key.startsWith("_") || sameStoredValue(observed.data[key], value));
|
|
206
217
|
}
|
|
218
|
+
function matchesLifecyclePublication(observed, existing, liveRevisionId, publishedAt, updatedAt) {
|
|
219
|
+
if (observed.version !== existing.version + 1 || observed.status !== "published" || observed.slug !== existing.slug || observed.liveRevisionId !== liveRevisionId || observed.draftRevisionId !== null || observed.scheduledAt !== null || observed.publishedAt !== publishedAt || observed.updatedAt !== updatedAt) return false;
|
|
220
|
+
return Object.entries(existing.data).every(([key, value]) => sameStoredValue(observed.data[key], value));
|
|
221
|
+
}
|
|
207
222
|
function matchesPublicationFence(observed, existing) {
|
|
208
223
|
return observed.version === existing.version && observed.status === existing.status && observed.liveRevisionId === existing.liveRevisionId && observed.draftRevisionId === existing.draftRevisionId && observed.scheduledAt === existing.scheduledAt;
|
|
209
224
|
}
|
|
@@ -212,6 +227,31 @@ function isConfirmedStatementFailure(error) {
|
|
|
212
227
|
const code = error.code;
|
|
213
228
|
return typeof code === "string" && (code.startsWith("SQLITE_") || SQLSTATE_PATTERN.test(code));
|
|
214
229
|
}
|
|
230
|
+
function encodeIndexedFieldCursor(field, value, id) {
|
|
231
|
+
const payload = {
|
|
232
|
+
version: 1,
|
|
233
|
+
field,
|
|
234
|
+
value
|
|
235
|
+
};
|
|
236
|
+
return encodeCursor(JSON.stringify(payload), id);
|
|
237
|
+
}
|
|
238
|
+
function decodeIndexedFieldCursor(cursor, field) {
|
|
239
|
+
const { orderValue, id } = decodeCursor(cursor);
|
|
240
|
+
let payload;
|
|
241
|
+
try {
|
|
242
|
+
payload = JSON.parse(orderValue);
|
|
243
|
+
} catch {
|
|
244
|
+
throw new InvalidCursorError(cursor);
|
|
245
|
+
}
|
|
246
|
+
if (payload === null || typeof payload !== "object") throw new InvalidCursorError(cursor);
|
|
247
|
+
const candidate = payload;
|
|
248
|
+
const validValue = candidate.value === null || typeof candidate.value === "string" || typeof candidate.value === "number";
|
|
249
|
+
if (candidate.version !== 1 || candidate.field !== field || !validValue) throw new InvalidCursorError(cursor);
|
|
250
|
+
return {
|
|
251
|
+
value: candidate.value,
|
|
252
|
+
id
|
|
253
|
+
};
|
|
254
|
+
}
|
|
215
255
|
/**
|
|
216
256
|
* Whitelist mapping a public date-filter field to its physical column. Keeping
|
|
217
257
|
* this separate from `mapOrderField` makes the filterable set explicit and
|
|
@@ -223,6 +263,27 @@ const DATE_FILTER_COLUMNS = {
|
|
|
223
263
|
publishedAt: "published_at"
|
|
224
264
|
};
|
|
225
265
|
/**
|
|
266
|
+
* Built-in sort fields → their physical columns. A closed set that blocks
|
|
267
|
+
* sorting by arbitrary columns; per-collection fields are allowed
|
|
268
|
+
* separately via `mapOrderField`'s `sortableExtras`.
|
|
269
|
+
*/
|
|
270
|
+
const ORDER_FIELD_COLUMNS = {
|
|
271
|
+
createdAt: "created_at",
|
|
272
|
+
updatedAt: "updated_at",
|
|
273
|
+
publishedAt: "published_at",
|
|
274
|
+
scheduledAt: "scheduled_at",
|
|
275
|
+
deletedAt: "deleted_at",
|
|
276
|
+
title: "title",
|
|
277
|
+
name: "name",
|
|
278
|
+
slug: "slug",
|
|
279
|
+
status: "status",
|
|
280
|
+
locale: "locale"
|
|
281
|
+
};
|
|
282
|
+
/** True when `field` maps to a system column and needs no per-collection resolution. */
|
|
283
|
+
function isSystemOrderField(field) {
|
|
284
|
+
return field in ORDER_FIELD_COLUMNS;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
226
287
|
* System columns that exist in every ec_* table
|
|
227
288
|
*/
|
|
228
289
|
const SYSTEM_COLUMNS = new Set([
|
|
@@ -260,6 +321,15 @@ function serializeValue(value) {
|
|
|
260
321
|
if (typeof value === "object") return JSON.stringify(value);
|
|
261
322
|
return value;
|
|
262
323
|
}
|
|
324
|
+
function writableContentData(data) {
|
|
325
|
+
const writable = {};
|
|
326
|
+
for (const [key, value] of Object.entries(data)) {
|
|
327
|
+
if (SYSTEM_COLUMNS.has(key)) continue;
|
|
328
|
+
validateIdentifier(key, "content field name");
|
|
329
|
+
writable[key] = value;
|
|
330
|
+
}
|
|
331
|
+
return writable;
|
|
332
|
+
}
|
|
263
333
|
/**
|
|
264
334
|
* Deserialize a value from database storage
|
|
265
335
|
* Attempts to parse JSON strings that look like objects/arrays
|
|
@@ -296,7 +366,7 @@ var ContentRepository = class {
|
|
|
296
366
|
* Create a new content item
|
|
297
367
|
*/
|
|
298
368
|
async create(input) {
|
|
299
|
-
const id = ulid();
|
|
369
|
+
const id = input.id ?? ulid();
|
|
300
370
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
301
371
|
const { type, slug, data, status = "draft", authorId, primaryBylineId, locale, translationOf, publishedAt, createdAt } = input;
|
|
302
372
|
if (!type) throw new EmDashValidationError("Content type is required");
|
|
@@ -358,7 +428,7 @@ var ContentRepository = class {
|
|
|
358
428
|
* (optionally scoped to a locale) and appends a numeric suffix (`-1`,
|
|
359
429
|
* `-2`, etc.) on collision to guarantee uniqueness.
|
|
360
430
|
*
|
|
361
|
-
* Returns
|
|
431
|
+
* Returns null when slug normalization cannot produce a value.
|
|
362
432
|
*/
|
|
363
433
|
async generateUniqueSlug(type, text, locale) {
|
|
364
434
|
const baseSlug = slugify(text);
|
|
@@ -521,7 +591,9 @@ var ContentRepository = class {
|
|
|
521
591
|
const limit = Math.min(options.limit || 50, 100);
|
|
522
592
|
const orderField = options.orderBy?.field || "createdAt";
|
|
523
593
|
const orderDirection = options.orderBy?.direction || "desc";
|
|
524
|
-
const
|
|
594
|
+
const resolvedOrderField = await this.resolveOrderField(type, orderField, options.sortableExtras);
|
|
595
|
+
const dbField = resolvedOrderField.column;
|
|
596
|
+
const resolvedFieldFilters = await this.resolveFieldFilters(type, options.where?.fieldFilters);
|
|
525
597
|
const safeOrderDirection = orderDirection.toLowerCase() === "asc" ? "ASC" : "DESC";
|
|
526
598
|
let query = this.db.selectFrom(tableName).selectAll().where("deleted_at", "is", null);
|
|
527
599
|
if (options.where?.status) query = query.where("status", "=", options.where.status);
|
|
@@ -529,13 +601,42 @@ var ContentRepository = class {
|
|
|
529
601
|
if (options.where?.locale) query = query.where("locale", "=", options.where.locale);
|
|
530
602
|
query = this.applySearchFilter(query, options.where, type);
|
|
531
603
|
query = this.applyDateFilter(query, options.where);
|
|
532
|
-
|
|
604
|
+
query = this.applyBylineFilter(query, options.where, type);
|
|
605
|
+
query = this.applyFieldFilters(query, resolvedFieldFilters);
|
|
606
|
+
if (options.cursor) if (resolvedOrderField.indexedCustomField) {
|
|
607
|
+
const { value, id: cursorId } = decodeIndexedFieldCursor(options.cursor, orderField);
|
|
608
|
+
const isPresent = sql`${sql.ref(dbField)} IS NOT NULL`;
|
|
609
|
+
const falseLiteral = sql`FALSE`;
|
|
610
|
+
const trueLiteral = sql`TRUE`;
|
|
611
|
+
if (safeOrderDirection === "ASC" && value === null) query = query.where(sql`
|
|
612
|
+
(${isPresent}) > ${falseLiteral}
|
|
613
|
+
OR ((${isPresent}) = ${falseLiteral} AND ${sql.ref("id")} > ${cursorId})
|
|
614
|
+
`);
|
|
615
|
+
else if (safeOrderDirection === "DESC" && value === null) query = query.where(sql`
|
|
616
|
+
(${isPresent}) = ${falseLiteral} AND ${sql.ref("id")} < ${cursorId}
|
|
617
|
+
`);
|
|
618
|
+
else if (safeOrderDirection === "ASC") query = query.where(sql`
|
|
619
|
+
(${isPresent}, ${sql.ref(dbField)}, ${sql.ref("id")})
|
|
620
|
+
> (${trueLiteral}, ${value}, ${cursorId})
|
|
621
|
+
`);
|
|
622
|
+
else query = query.where(sql`
|
|
623
|
+
(${isPresent}, ${sql.ref(dbField)}, ${sql.ref("id")})
|
|
624
|
+
< (${trueLiteral}, ${value}, ${cursorId})
|
|
625
|
+
`);
|
|
626
|
+
} else {
|
|
533
627
|
const { orderValue, id: cursorId } = decodeCursor(options.cursor);
|
|
534
628
|
if (safeOrderDirection === "DESC") query = query.where((eb) => eb.or([eb(dbField, "<", orderValue), eb.and([eb(dbField, "=", orderValue), eb("id", "<", cursorId)])]));
|
|
535
629
|
else query = query.where((eb) => eb.or([eb(dbField, ">", orderValue), eb.and([eb(dbField, "=", orderValue), eb("id", ">", cursorId)])]));
|
|
536
630
|
}
|
|
537
|
-
|
|
538
|
-
|
|
631
|
+
const indexedOrderFilter = resolvedOrderField.indexedCustomField ? resolvedFieldFilters.find((filter) => filter.column === dbField) : void 0;
|
|
632
|
+
if (resolvedOrderField.indexedCustomField && !indexedOrderFilter) query = query.orderBy(sql`${sql.ref(dbField)} IS NOT NULL`, safeOrderDirection === "ASC" ? "asc" : "desc");
|
|
633
|
+
if (indexedOrderFilter?.kind !== "null") query = query.orderBy(dbField, safeOrderDirection === "ASC" ? "asc" : "desc");
|
|
634
|
+
query = query.orderBy("id", safeOrderDirection === "ASC" ? "asc" : "desc").limit(limit + 1);
|
|
635
|
+
const [rowsResult, countResult] = await Promise.allSettled([query.execute(), this.countWithResolvedFilters(type, options.where, resolvedFieldFilters)]);
|
|
636
|
+
if (rowsResult.status === "rejected") throw rowsResult.reason;
|
|
637
|
+
if (countResult.status === "rejected") throw countResult.reason;
|
|
638
|
+
const rows = rowsResult.value;
|
|
639
|
+
const total = countResult.value;
|
|
539
640
|
const hasMore = rows.length > limit;
|
|
540
641
|
const items = rows.slice(0, limit);
|
|
541
642
|
const mappedResult = {
|
|
@@ -545,7 +646,10 @@ var ContentRepository = class {
|
|
|
545
646
|
if (hasMore && items.length > 0) {
|
|
546
647
|
const lastRow = items.at(-1);
|
|
547
648
|
const lastOrderValue = lastRow[dbField];
|
|
548
|
-
|
|
649
|
+
if (resolvedOrderField.indexedCustomField) {
|
|
650
|
+
if (lastOrderValue !== null && typeof lastOrderValue !== "string" && typeof lastOrderValue !== "number") throw new EmDashValidationError(`Invalid indexed value for order field: ${orderField}`);
|
|
651
|
+
mappedResult.nextCursor = encodeIndexedFieldCursor(orderField, lastOrderValue, String(lastRow.id));
|
|
652
|
+
} else mappedResult.nextCursor = encodeCursor(typeof lastOrderValue === "string" || typeof lastOrderValue === "number" ? String(lastOrderValue) : "", String(lastRow.id));
|
|
549
653
|
}
|
|
550
654
|
return mappedResult;
|
|
551
655
|
}
|
|
@@ -562,23 +666,137 @@ var ContentRepository = class {
|
|
|
562
666
|
if (input.scheduledAt !== void 0) updates.scheduled_at = input.scheduledAt;
|
|
563
667
|
if (input.authorId !== void 0) updates.author_id = input.authorId;
|
|
564
668
|
if (input.primaryBylineId !== void 0) updates.primary_byline_id = input.primaryBylineId;
|
|
565
|
-
if (input.data !== void 0 && typeof input.data === "object")
|
|
566
|
-
for (const [key, value] of Object.entries(input.data)) if (!SYSTEM_COLUMNS.has(key)) {
|
|
567
|
-
validateIdentifier(key, "content field name");
|
|
568
|
-
updates[key] = serializeValue(value);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
669
|
+
if (input.data !== void 0 && typeof input.data === "object") for (const [key, value] of Object.entries(writableContentData(input.data))) updates[key] = serializeValue(value);
|
|
571
670
|
const hasColumnWrites = Object.keys(updates).length > 0;
|
|
572
671
|
if (hasColumnWrites) updates.updated_at = now;
|
|
573
672
|
updates.version = sql`version + 1`;
|
|
574
673
|
await this.db.updateTable(tableName).set(updates).where("id", "=", id).where("deleted_at", "is", null).execute();
|
|
575
|
-
if (input.status !== void 0 || input.publishedAt !== void 0 || input.scheduledAt !== void 0) await this.restampEntryPivot(type, id);
|
|
576
674
|
if (hasColumnWrites) invalidateCollectionCache(type);
|
|
577
675
|
const updated = await this.findById(type, id);
|
|
578
676
|
if (!updated) throw new Error("Content not found");
|
|
579
677
|
return updated;
|
|
580
678
|
}
|
|
581
679
|
/**
|
|
680
|
+
* Update plugin-authored fields without letting content columns diverge
|
|
681
|
+
* from the revision pointers that publication promotes.
|
|
682
|
+
*/
|
|
683
|
+
async updateDraftAware(type, id, input) {
|
|
684
|
+
const data = input.data ? writableContentData(input.data) : {};
|
|
685
|
+
const stagedSlug = typeof input.slug === "string" ? input.slug : void 0;
|
|
686
|
+
if (!(Object.keys(data).length > 0 || stagedSlug !== void 0)) return this.update(type, id, {
|
|
687
|
+
...input,
|
|
688
|
+
data
|
|
689
|
+
});
|
|
690
|
+
const collectionRows = await this.db.selectFrom("_emdash_collections as collection").leftJoin("_emdash_fields as field", "field.collection_id", "collection.id").select(["collection.supports", "field.slug as fieldSlug"]).where("collection.slug", "=", type).execute();
|
|
691
|
+
const supportsRaw = collectionRows[0]?.supports;
|
|
692
|
+
const supports = supportsRaw ? JSON.parse(supportsRaw) : [];
|
|
693
|
+
if (!Array.isArray(supports) || !supports.includes("revisions")) return this.update(type, id, {
|
|
694
|
+
...input,
|
|
695
|
+
data
|
|
696
|
+
});
|
|
697
|
+
const fieldSlugs = new Set(collectionRows.map((row) => row.fieldSlug).filter(Boolean));
|
|
698
|
+
for (const field of Object.keys(data)) if (!fieldSlugs.has(field)) throw new EmDashValidationError(`Unknown field '${field}' in collection '${type}'`);
|
|
699
|
+
const revisionRepo = new RevisionRepository(this.db);
|
|
700
|
+
let existing = await this.findById(type, id);
|
|
701
|
+
for (let attempt = 0; existing && attempt < MAX_DRAFT_STAGE_ATTEMPTS; attempt++) {
|
|
702
|
+
let baseData = existing.data;
|
|
703
|
+
if (existing.draftRevisionId) {
|
|
704
|
+
const draft = await revisionRepo.findById(existing.draftRevisionId);
|
|
705
|
+
if (draft) baseData = draft.data;
|
|
706
|
+
}
|
|
707
|
+
const mergedData = {
|
|
708
|
+
...baseData,
|
|
709
|
+
...data
|
|
710
|
+
};
|
|
711
|
+
if (stagedSlug !== void 0) mergedData._slug = stagedSlug;
|
|
712
|
+
const revision = await revisionRepo.create({
|
|
713
|
+
collection: type,
|
|
714
|
+
entryId: id,
|
|
715
|
+
data: mergedData,
|
|
716
|
+
...input.authorId ? { authorId: input.authorId } : {}
|
|
717
|
+
});
|
|
718
|
+
let staged;
|
|
719
|
+
try {
|
|
720
|
+
staged = await this.replaceDraftRevisionForUpdate(type, id, revision.id, existing, input);
|
|
721
|
+
} catch (error) {
|
|
722
|
+
await this.deleteUnstagedRevision(revisionRepo, type, id, revision.id);
|
|
723
|
+
throw error;
|
|
724
|
+
}
|
|
725
|
+
if (staged) {
|
|
726
|
+
const updated = await this.findById(type, id);
|
|
727
|
+
if (!updated) throw new Error("Content not found");
|
|
728
|
+
const draftData = {};
|
|
729
|
+
for (const [key, value] of Object.entries(mergedData)) if (!key.startsWith("_")) draftData[key] = value;
|
|
730
|
+
return {
|
|
731
|
+
...updated,
|
|
732
|
+
data: {
|
|
733
|
+
...updated.data,
|
|
734
|
+
...draftData
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
await this.deleteUnstagedRevision(revisionRepo, type, id, revision.id);
|
|
739
|
+
existing = await this.findById(type, id);
|
|
740
|
+
}
|
|
741
|
+
if (!existing) throw new Error("Content not found");
|
|
742
|
+
throw new ContentMutationConflictError();
|
|
743
|
+
}
|
|
744
|
+
async deleteUnstagedRevision(revisionRepo, type, id, revisionId) {
|
|
745
|
+
try {
|
|
746
|
+
await revisionRepo.deleteIfUnreferenced(type, id, revisionId);
|
|
747
|
+
} catch (error) {
|
|
748
|
+
console.error(`[content] Failed to clean up unstaged revision ${revisionId}:`, error);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
async replaceDraftRevisionForUpdate(type, id, revisionId, expected, input) {
|
|
752
|
+
const tableName = getTableName(type);
|
|
753
|
+
const assignments = [sql`draft_revision_id = ${revisionId}`];
|
|
754
|
+
let liveMetadataChanged = false;
|
|
755
|
+
if (input.status !== void 0) {
|
|
756
|
+
assignments.push(sql`status = ${input.status}`);
|
|
757
|
+
liveMetadataChanged = true;
|
|
758
|
+
}
|
|
759
|
+
if (input.slug === null) {
|
|
760
|
+
assignments.push(sql`slug = NULL`);
|
|
761
|
+
liveMetadataChanged = true;
|
|
762
|
+
}
|
|
763
|
+
if (input.publishedAt !== void 0) {
|
|
764
|
+
assignments.push(sql`published_at = ${input.publishedAt}`);
|
|
765
|
+
liveMetadataChanged = true;
|
|
766
|
+
}
|
|
767
|
+
if (input.scheduledAt !== void 0) {
|
|
768
|
+
assignments.push(sql`scheduled_at = ${input.scheduledAt}`);
|
|
769
|
+
liveMetadataChanged = true;
|
|
770
|
+
}
|
|
771
|
+
if (input.authorId !== void 0) {
|
|
772
|
+
assignments.push(sql`author_id = ${input.authorId}`);
|
|
773
|
+
liveMetadataChanged = true;
|
|
774
|
+
}
|
|
775
|
+
if (input.primaryBylineId !== void 0) {
|
|
776
|
+
assignments.push(sql`primary_byline_id = ${input.primaryBylineId}`);
|
|
777
|
+
liveMetadataChanged = true;
|
|
778
|
+
}
|
|
779
|
+
if (liveMetadataChanged) assignments.push(sql`updated_at = ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
780
|
+
assignments.push(sql`version = version + 1`);
|
|
781
|
+
const changed = ((await sql`
|
|
782
|
+
UPDATE ${sql.ref(tableName)}
|
|
783
|
+
SET ${sql.join(assignments, sql`, `)}
|
|
784
|
+
WHERE id = ${id}
|
|
785
|
+
AND deleted_at IS NULL
|
|
786
|
+
AND version = ${expected.version}
|
|
787
|
+
AND ${nullableColumnMatch("live_revision_id", expected.liveRevisionId)}
|
|
788
|
+
AND ${nullableColumnMatch("draft_revision_id", expected.draftRevisionId)}
|
|
789
|
+
AND EXISTS (
|
|
790
|
+
SELECT 1 FROM revisions
|
|
791
|
+
WHERE revisions.id = ${revisionId}
|
|
792
|
+
AND revisions.collection = ${type}
|
|
793
|
+
AND revisions.entry_id = ${id}
|
|
794
|
+
)
|
|
795
|
+
`.execute(this.db)).numAffectedRows ?? 0n) > 0n;
|
|
796
|
+
if (changed && liveMetadataChanged) invalidateCollectionCache(type);
|
|
797
|
+
return changed;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
582
800
|
* Delete content (soft delete - moves to trash)
|
|
583
801
|
*/
|
|
584
802
|
async delete(type, id) {
|
|
@@ -590,10 +808,7 @@ var ContentRepository = class {
|
|
|
590
808
|
WHERE id = ${id}
|
|
591
809
|
AND deleted_at IS NULL
|
|
592
810
|
`.execute(this.db)).numAffectedRows ?? 0n) > 0n;
|
|
593
|
-
if (changed)
|
|
594
|
-
await this.restampEntryPivot(type, id);
|
|
595
|
-
invalidateCollectionCache(type);
|
|
596
|
-
}
|
|
811
|
+
if (changed) invalidateCollectionCache(type);
|
|
597
812
|
return changed;
|
|
598
813
|
}
|
|
599
814
|
/**
|
|
@@ -609,35 +824,10 @@ var ContentRepository = class {
|
|
|
609
824
|
RETURNING *
|
|
610
825
|
`.execute(this.db)).rows[0];
|
|
611
826
|
if (!restored) return null;
|
|
612
|
-
await this.restampEntryPivot(type, id);
|
|
613
827
|
invalidateCollectionCache(type);
|
|
614
828
|
return this.mapRow(type, restored);
|
|
615
829
|
}
|
|
616
830
|
/**
|
|
617
|
-
* Re-stamp the denormalized filter + sort columns on every
|
|
618
|
-
* `content_taxonomies` pivot row for an entry from its authoritative `ec_*`
|
|
619
|
-
* row (migration 051). Called after any mutation that moves one of those
|
|
620
|
-
* columns so a taxonomy-filtered listing can seek the entry directly.
|
|
621
|
-
*
|
|
622
|
-
* A single correlated `UPDATE` reads the post-mutation values from `ec_*`, so
|
|
623
|
-
* the pivot converges to the authoritative row. This is NOT atomic with the
|
|
624
|
-
* `ec_*` mutation on D1 (no transactions), which is why the read path
|
|
625
|
-
* re-checks the real predicates on the joined `ec_*` row. Untagged entries
|
|
626
|
-
* have no pivot rows, so the statement is a cheap no-op for them.
|
|
627
|
-
*/
|
|
628
|
-
async restampEntryPivot(type, id) {
|
|
629
|
-
const tableName = getTableName(type);
|
|
630
|
-
await sql`
|
|
631
|
-
UPDATE content_taxonomies
|
|
632
|
-
SET (status, scheduled_at, deleted_at, locale, published_at, created_at) = (
|
|
633
|
-
SELECT status, scheduled_at, deleted_at, locale, published_at, created_at
|
|
634
|
-
FROM ${sql.ref(tableName)}
|
|
635
|
-
WHERE ${sql.ref(tableName)}.id = ${id}
|
|
636
|
-
)
|
|
637
|
-
WHERE collection = ${type} AND entry_id = ${id}
|
|
638
|
-
`.execute(this.db);
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
831
|
* Permanently delete content (cannot be undone)
|
|
642
832
|
*/
|
|
643
833
|
/**
|
|
@@ -734,7 +924,7 @@ var ContentRepository = class {
|
|
|
734
924
|
const pattern = `%${term.replace(LIKE_WILDCARD_RE, (c) => `\\${c}`)}%`;
|
|
735
925
|
return query.where((eb) => eb.or(columns.map((col) => {
|
|
736
926
|
validateIdentifier(col, "search column");
|
|
737
|
-
return
|
|
927
|
+
return sql`lower(CAST(${sql.ref(col)} AS TEXT)) LIKE lower(${pattern}) ESCAPE '\\'`;
|
|
738
928
|
})));
|
|
739
929
|
}
|
|
740
930
|
/**
|
|
@@ -756,9 +946,57 @@ var ContentRepository = class {
|
|
|
756
946
|
return next;
|
|
757
947
|
}
|
|
758
948
|
/**
|
|
949
|
+
* Apply the optional byline filter as a correlated (NOT) EXISTS against
|
|
950
|
+
* `_emdash_content_bylines`.
|
|
951
|
+
*
|
|
952
|
+
* Correlating from the content table preserves the outer sort index so
|
|
953
|
+
* `LIMIT` can short-circuit. `mode: "none"` tests the junction rather than
|
|
954
|
+
* `primary_byline_id` because the two are written in the same call but
|
|
955
|
+
* are not atomically consistent, so the junction is authoritative.
|
|
956
|
+
*
|
|
957
|
+
* Whether a credit *renders* is locale-scoped; whether one *exists* is
|
|
958
|
+
* not. Both are needed: the first decides what the filter matches, the
|
|
959
|
+
* second decides whether the author fallback applies at all.
|
|
960
|
+
*/
|
|
961
|
+
applyBylineFilter(query, where, type) {
|
|
962
|
+
const filter = where?.bylineFilter;
|
|
963
|
+
if (!filter) return query;
|
|
964
|
+
const tableName = getTableName(type);
|
|
965
|
+
const idColumn = `${tableName}.id`;
|
|
966
|
+
const authorColumn = `${tableName}.author_id`;
|
|
967
|
+
const localeColumn = `${tableName}.locale`;
|
|
968
|
+
const creditRenders = (eb, bylineIds) => {
|
|
969
|
+
let sub = eb.selectFrom("_emdash_content_bylines as cb").innerJoin("_emdash_bylines as b", "b.translation_group", "cb.byline_id").select("cb.id").where("cb.collection_slug", "=", type).whereRef("cb.content_id", "=", idColumn);
|
|
970
|
+
sub = filter.locale ? sub.where("b.locale", "=", filter.locale) : sub.whereRef("b.locale", "=", localeColumn);
|
|
971
|
+
if (bylineIds) sub = sub.where("cb.byline_id", "in", bylineIds);
|
|
972
|
+
return eb.exists(sub);
|
|
973
|
+
};
|
|
974
|
+
const hasExplicitCredit = (eb) => eb.exists(eb.selectFrom("_emdash_content_bylines as cb").select("cb.id").where("cb.collection_slug", "=", type).whereRef("cb.content_id", "=", idColumn));
|
|
975
|
+
const authorHasByline = (eb, bylineIds) => {
|
|
976
|
+
let sub = eb.selectFrom("_emdash_bylines as b").select("b.id").whereRef("b.user_id", "=", authorColumn);
|
|
977
|
+
sub = filter.locale ? sub.where("b.locale", "=", filter.locale) : sub.whereRef("b.locale", "=", localeColumn);
|
|
978
|
+
if (bylineIds) sub = sub.where("b.translation_group", "in", bylineIds);
|
|
979
|
+
return eb.exists(sub);
|
|
980
|
+
};
|
|
981
|
+
if (filter.mode === "none") return query.where((eb) => {
|
|
982
|
+
const uncredited = eb.not(creditRenders(eb));
|
|
983
|
+
return filter.includeInferred ? eb.and([uncredited, eb.or([hasExplicitCredit(eb), eb.not(authorHasByline(eb))])]) : uncredited;
|
|
984
|
+
});
|
|
985
|
+
const bylineIds = filter.bylineIds ?? [];
|
|
986
|
+
if (bylineIds.length === 0) return query.where(() => sql`1 = 0`);
|
|
987
|
+
return query.where((eb) => {
|
|
988
|
+
if (!filter.includeInferred) return creditRenders(eb, bylineIds);
|
|
989
|
+
return eb.or([creditRenders(eb, bylineIds), eb.and([eb.not(hasExplicitCredit(eb)), authorHasByline(eb, bylineIds)])]);
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
759
993
|
* Count content items
|
|
760
994
|
*/
|
|
761
995
|
async count(type, where) {
|
|
996
|
+
const resolvedFieldFilters = await this.resolveFieldFilters(type, where?.fieldFilters);
|
|
997
|
+
return this.countWithResolvedFilters(type, where, resolvedFieldFilters);
|
|
998
|
+
}
|
|
999
|
+
async countWithResolvedFilters(type, where, resolvedFieldFilters) {
|
|
762
1000
|
const tableName = getTableName(type);
|
|
763
1001
|
let query = this.db.selectFrom(tableName).select((eb) => eb.fn.count("id").as("count")).where("deleted_at", "is", null);
|
|
764
1002
|
if (where?.status) query = query.where("status", "=", where.status);
|
|
@@ -766,6 +1004,8 @@ var ContentRepository = class {
|
|
|
766
1004
|
if (where?.locale) query = query.where("locale", "=", where.locale);
|
|
767
1005
|
query = this.applySearchFilter(query, where, type);
|
|
768
1006
|
query = this.applyDateFilter(query, where);
|
|
1007
|
+
query = this.applyBylineFilter(query, where, type);
|
|
1008
|
+
query = this.applyFieldFilters(query, resolvedFieldFilters);
|
|
769
1009
|
const result = await query.executeTakeFirst();
|
|
770
1010
|
return Number(result?.count || 0);
|
|
771
1011
|
}
|
|
@@ -779,19 +1019,22 @@ var ContentRepository = class {
|
|
|
779
1019
|
const tableName = getTableName(type);
|
|
780
1020
|
return (await this.db.selectFrom(tableName).select("author_id").distinct().where("deleted_at", "is", null).where("author_id", "is not", null).execute()).map((row) => row.author_id).filter((id) => id !== null);
|
|
781
1021
|
}
|
|
782
|
-
async getStats(type) {
|
|
1022
|
+
async getStats(type, now = /* @__PURE__ */ new Date()) {
|
|
783
1023
|
const tableName = getTableName(type);
|
|
1024
|
+
const nowIso = now.toISOString();
|
|
784
1025
|
const result = await this.db.selectFrom(tableName).select((eb) => [
|
|
785
1026
|
eb.fn.count("id").as("total"),
|
|
786
1027
|
eb.fn.sum(eb.case().when("status", "=", "published").then(1).else(0).end()).as("published"),
|
|
787
1028
|
eb.fn.sum(eb.case().when("status", "=", "draft").then(1).else(0).end()).as("draft"),
|
|
788
|
-
sql`SUM(CASE WHEN scheduled_at IS NOT NULL THEN 1 ELSE 0 END)`.as("scheduled")
|
|
1029
|
+
sql`SUM(CASE WHEN scheduled_at IS NOT NULL THEN 1 ELSE 0 END)`.as("scheduled"),
|
|
1030
|
+
sql`SUM(CASE WHEN scheduled_at IS NOT NULL AND scheduled_at <= ${nowIso} THEN 1 ELSE 0 END)`.as("overdue_scheduled")
|
|
789
1031
|
]).where("deleted_at", "is", null).executeTakeFirst();
|
|
790
1032
|
return {
|
|
791
1033
|
total: Number(result?.total || 0),
|
|
792
1034
|
published: Number(result?.published || 0),
|
|
793
1035
|
draft: Number(result?.draft || 0),
|
|
794
|
-
scheduled: Number(result?.scheduled || 0)
|
|
1036
|
+
scheduled: Number(result?.scheduled || 0),
|
|
1037
|
+
overdueScheduled: Number(result?.overdue_scheduled || 0)
|
|
795
1038
|
};
|
|
796
1039
|
}
|
|
797
1040
|
/**
|
|
@@ -817,7 +1060,6 @@ var ContentRepository = class {
|
|
|
817
1060
|
WHERE id = ${id}
|
|
818
1061
|
AND deleted_at IS NULL
|
|
819
1062
|
`.execute(this.db);
|
|
820
|
-
await this.restampEntryPivot(type, id);
|
|
821
1063
|
invalidateCollectionCache(type);
|
|
822
1064
|
const updated = await this.findById(type, id);
|
|
823
1065
|
if (!updated) throw new Error("Content not found");
|
|
@@ -844,7 +1086,6 @@ var ContentRepository = class {
|
|
|
844
1086
|
AND scheduled_at IS NOT NULL
|
|
845
1087
|
AND deleted_at IS NULL
|
|
846
1088
|
`.execute(this.db);
|
|
847
|
-
await this.restampEntryPivot(type, id);
|
|
848
1089
|
invalidateCollectionCache(type);
|
|
849
1090
|
const updated = await this.findById(type, id);
|
|
850
1091
|
if (!updated) throw new Error("Content not found");
|
|
@@ -988,6 +1229,8 @@ var ContentRepository = class {
|
|
|
988
1229
|
* Syncs the draft revision's data into the content table columns so the
|
|
989
1230
|
* content table always reflects the published version.
|
|
990
1231
|
* If no draft revision exists, creates one from current data and publishes it.
|
|
1232
|
+
* When `promoteRevision` is false, publishes the current content-table data
|
|
1233
|
+
* by changing lifecycle metadata only.
|
|
991
1234
|
*
|
|
992
1235
|
* `publishedAt` (optional) overrides the publication timestamp. If omitted,
|
|
993
1236
|
* the existing `published_at` is preserved (idempotent re-publish keeps the
|
|
@@ -999,12 +1242,76 @@ var ContentRepository = class {
|
|
|
999
1242
|
* `expectedScheduledAt` additionally fences changes made after a sweep
|
|
1000
1243
|
* selected the row but before publication preparation began.
|
|
1001
1244
|
*/
|
|
1002
|
-
async publish(type, id, publishedAt, requireDue = false, expectedScheduledAt) {
|
|
1245
|
+
async publish(type, id, publishedAt, requireDue = false, expectedScheduledAt, promoteRevision = true, requireSlug = true) {
|
|
1003
1246
|
const tableName = getTableName(type);
|
|
1004
1247
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1005
1248
|
const existing = await this.findById(type, id);
|
|
1006
1249
|
if (!existing) throw new EmDashValidationError("Content item not found");
|
|
1007
1250
|
if (requireDue && expectedScheduledAt !== void 0 && existing.scheduledAt !== expectedScheduledAt) throw new ScheduledNotDueError();
|
|
1251
|
+
if (!promoteRevision && requireSlug && !existing.slug?.trim()) throw new EmDashValidationError("Cannot publish routable content without a slug");
|
|
1252
|
+
if (!promoteRevision) {
|
|
1253
|
+
const revisionRepo = new RevisionRepository(this.db);
|
|
1254
|
+
let provisionalRevisionId = null;
|
|
1255
|
+
try {
|
|
1256
|
+
let liveRevisionId = existing.liveRevisionId;
|
|
1257
|
+
if (!liveRevisionId) {
|
|
1258
|
+
const revision = await revisionRepo.create({
|
|
1259
|
+
collection: type,
|
|
1260
|
+
entryId: id,
|
|
1261
|
+
data: existing.data
|
|
1262
|
+
});
|
|
1263
|
+
liveRevisionId = revision.id;
|
|
1264
|
+
provisionalRevisionId = revision.id;
|
|
1265
|
+
}
|
|
1266
|
+
const intendedPublishedAt = publishedAt ?? existing.publishedAt ?? now;
|
|
1267
|
+
const duePredicate = requireDue ? sql`AND scheduled_at IS NOT NULL AND scheduled_at <= ${now}` : sql``;
|
|
1268
|
+
let published = false;
|
|
1269
|
+
try {
|
|
1270
|
+
published = ((await sql`
|
|
1271
|
+
UPDATE ${sql.ref(tableName)}
|
|
1272
|
+
SET live_revision_id = ${liveRevisionId},
|
|
1273
|
+
draft_revision_id = NULL,
|
|
1274
|
+
status = 'published',
|
|
1275
|
+
scheduled_at = NULL,
|
|
1276
|
+
published_at = ${intendedPublishedAt},
|
|
1277
|
+
updated_at = ${now},
|
|
1278
|
+
version = version + 1
|
|
1279
|
+
WHERE id = ${id}
|
|
1280
|
+
AND deleted_at IS NULL
|
|
1281
|
+
AND version = ${existing.version}
|
|
1282
|
+
AND status = ${existing.status}
|
|
1283
|
+
AND ${nullableColumnMatch("live_revision_id", existing.liveRevisionId)}
|
|
1284
|
+
AND ${nullableColumnMatch("draft_revision_id", existing.draftRevisionId)}
|
|
1285
|
+
AND ${nullableColumnMatch("scheduled_at", existing.scheduledAt)}
|
|
1286
|
+
${duePredicate}
|
|
1287
|
+
`.execute(this.db)).numAffectedRows ?? 0n) > 0n;
|
|
1288
|
+
} catch (error) {
|
|
1289
|
+
if (isConfirmedStatementFailure(error)) throw error;
|
|
1290
|
+
let observed;
|
|
1291
|
+
try {
|
|
1292
|
+
observed = await this.findById(type, id);
|
|
1293
|
+
} catch (reconciliationError) {
|
|
1294
|
+
throw new Error("Unable to confirm whether content publication completed", { cause: reconciliationError });
|
|
1295
|
+
}
|
|
1296
|
+
if (!observed) throw new Error("Unable to confirm whether content publication completed", { cause: error });
|
|
1297
|
+
published = matchesLifecyclePublication(observed, existing, liveRevisionId, intendedPublishedAt, now);
|
|
1298
|
+
if (!published && matchesPublicationFence(observed, existing)) throw error;
|
|
1299
|
+
if (!published) throw new Error("Unable to confirm whether content publication completed", { cause: error });
|
|
1300
|
+
}
|
|
1301
|
+
if (!published) throw requireDue ? new ScheduledNotDueError() : new ContentMutationConflictError();
|
|
1302
|
+
invalidateCollectionCache(type);
|
|
1303
|
+
const updated = await this.findById(type, id);
|
|
1304
|
+
if (!updated) throw new Error("Content not found");
|
|
1305
|
+
return updated;
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
if (provisionalRevisionId) try {
|
|
1308
|
+
await revisionRepo.deleteIfUnreferenced(type, id, provisionalRevisionId);
|
|
1309
|
+
} catch (cleanupError) {
|
|
1310
|
+
console.error(`[content] Failed to clean up provisional revision ${provisionalRevisionId}:`, cleanupError);
|
|
1311
|
+
}
|
|
1312
|
+
throw error;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1008
1315
|
const revisionRepo = new RevisionRepository(this.db);
|
|
1009
1316
|
let provisionalRevisionId = null;
|
|
1010
1317
|
try {
|
|
@@ -1022,6 +1329,7 @@ var ContentRepository = class {
|
|
|
1022
1329
|
if (!revision || revision.collection !== type || revision.entryId !== id) throw new EmDashValidationError("Revision does not belong to the specified content item");
|
|
1023
1330
|
const stagedSlug = typeof revision.data._slug === "string" ? revision.data._slug : null;
|
|
1024
1331
|
const intendedSlug = stagedSlug ?? existing.slug;
|
|
1332
|
+
if (requireSlug && !intendedSlug?.trim()) throw new EmDashValidationError("Cannot publish routable content without a slug");
|
|
1025
1333
|
const intendedPublishedAt = publishedAt ?? existing.publishedAt ?? now;
|
|
1026
1334
|
if (stagedSlug !== null && stagedSlug !== existing.slug && existing.locale !== null) {
|
|
1027
1335
|
const conflict = await this.findBySlugIncludingTrashed(type, stagedSlug, existing.locale);
|
|
@@ -1071,7 +1379,6 @@ var ContentRepository = class {
|
|
|
1071
1379
|
}
|
|
1072
1380
|
if (!promoted) throw requireDue ? new ScheduledNotDueError() : new ContentMutationConflictError();
|
|
1073
1381
|
invalidateCollectionCache(type);
|
|
1074
|
-
await this.restampEntryPivot(type, id);
|
|
1075
1382
|
const updated = await this.findById(type, id);
|
|
1076
1383
|
if (!updated) throw new Error("Content not found");
|
|
1077
1384
|
return updated;
|
|
@@ -1120,7 +1427,6 @@ var ContentRepository = class {
|
|
|
1120
1427
|
WHERE id = ${id}
|
|
1121
1428
|
AND deleted_at IS NULL
|
|
1122
1429
|
`.execute(this.db);
|
|
1123
|
-
await this.restampEntryPivot(type, id);
|
|
1124
1430
|
invalidateCollectionCache(type);
|
|
1125
1431
|
const updated = await this.findById(type, id);
|
|
1126
1432
|
if (!updated) throw new Error("Content not found");
|
|
@@ -1226,28 +1532,153 @@ var ContentRepository = class {
|
|
|
1226
1532
|
translationGroup: row.translation_group ?? null
|
|
1227
1533
|
};
|
|
1228
1534
|
}
|
|
1535
|
+
normalizeFilterScalar(field, type, value) {
|
|
1536
|
+
if (type === "number" || type === "integer") {
|
|
1537
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new EmDashValidationError(`Filter for field "${field}" must use a finite number`);
|
|
1538
|
+
if (type === "integer" && !Number.isInteger(value)) throw new EmDashValidationError(`Filter for field "${field}" must use an integer`);
|
|
1539
|
+
return value;
|
|
1540
|
+
}
|
|
1541
|
+
if (type === "boolean") {
|
|
1542
|
+
if (typeof value !== "boolean") throw new EmDashValidationError(`Filter for field "${field}" must use a boolean`);
|
|
1543
|
+
return value ? 1 : 0;
|
|
1544
|
+
}
|
|
1545
|
+
if (typeof value !== "string") throw new EmDashValidationError(`Filter for field "${field}" must use a string`);
|
|
1546
|
+
if (value.length > MAX_FILTER_STRING_LENGTH) throw new EmDashValidationError(`Filter value for field "${field}" exceeds ${MAX_FILTER_STRING_LENGTH} characters`);
|
|
1547
|
+
return value;
|
|
1548
|
+
}
|
|
1549
|
+
normalizeFieldFilter(field, type, value) {
|
|
1550
|
+
if (value === null) return {
|
|
1551
|
+
column: field,
|
|
1552
|
+
kind: "null"
|
|
1553
|
+
};
|
|
1554
|
+
if (typeof value !== "object") return {
|
|
1555
|
+
column: field,
|
|
1556
|
+
kind: "exact",
|
|
1557
|
+
value: this.normalizeFilterScalar(field, type, value)
|
|
1558
|
+
};
|
|
1559
|
+
if (Array.isArray(value)) throw new EmDashValidationError(`Invalid filter for field "${field}"`);
|
|
1560
|
+
const record = value;
|
|
1561
|
+
const keys = Object.keys(record);
|
|
1562
|
+
if (keys.length === 1 && keys[0] === "in") {
|
|
1563
|
+
if (!Array.isArray(record.in) || record.in.length === 0) throw new EmDashValidationError(`IN filter for field "${field}" must not be empty`);
|
|
1564
|
+
if (record.in.length > MAX_IN_FILTER_VALUES) throw new EmDashValidationError(`IN filter for field "${field}" exceeds ${MAX_IN_FILTER_VALUES} values`);
|
|
1565
|
+
return {
|
|
1566
|
+
column: field,
|
|
1567
|
+
kind: "in",
|
|
1568
|
+
values: record.in.map((entry) => this.normalizeFilterScalar(field, type, entry))
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
const rangeKeys = new Set([
|
|
1572
|
+
"gt",
|
|
1573
|
+
"gte",
|
|
1574
|
+
"lt",
|
|
1575
|
+
"lte"
|
|
1576
|
+
]);
|
|
1577
|
+
if (keys.length === 0 || keys.some((key) => !rangeKeys.has(key))) throw new EmDashValidationError(`Invalid filter operator for field "${field}"`);
|
|
1578
|
+
if (type === "boolean") throw new EmDashValidationError(`Boolean field "${field}" does not support range filters`);
|
|
1579
|
+
const bounds = {};
|
|
1580
|
+
for (const key of keys) {
|
|
1581
|
+
if (record[key] === void 0) continue;
|
|
1582
|
+
bounds[key] = this.normalizeFilterScalar(field, type, record[key]);
|
|
1583
|
+
}
|
|
1584
|
+
if (Object.keys(bounds).length === 0) throw new EmDashValidationError(`Range filter for field "${field}" has no bounds`);
|
|
1585
|
+
return {
|
|
1586
|
+
column: field,
|
|
1587
|
+
kind: "range",
|
|
1588
|
+
bounds
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
async collectionExists(type) {
|
|
1592
|
+
return await this.db.selectFrom("_emdash_collections").where("slug", "=", type).select("id").executeTakeFirst() !== void 0;
|
|
1593
|
+
}
|
|
1594
|
+
async resolveFieldFilters(type, filters) {
|
|
1595
|
+
const resolvedFilters = filters ?? {};
|
|
1596
|
+
const fields = Object.keys(resolvedFilters);
|
|
1597
|
+
if (fields.length === 0) return [];
|
|
1598
|
+
if (fields.length > MAX_INDEXED_FIELD_FILTERS) {
|
|
1599
|
+
if (!await this.collectionExists(type)) return [];
|
|
1600
|
+
throw new EmDashValidationError(`Content list queries support at most ${MAX_INDEXED_FIELD_FILTERS} indexed field filters`);
|
|
1601
|
+
}
|
|
1602
|
+
const rows = await this.db.selectFrom("_emdash_fields as field").innerJoin("_emdash_collections as collection", "collection.id", "field.collection_id").where("collection.slug", "=", type).where("field.slug", "in", fields).where("field.indexed", "=", 1).select(["field.slug", "field.type"]).execute();
|
|
1603
|
+
const metadata = new Map(rows.map((row) => [row.slug, row.type]));
|
|
1604
|
+
if (metadata.size === 0 && !await this.collectionExists(type)) return [];
|
|
1605
|
+
for (const field of fields) try {
|
|
1606
|
+
validateIdentifier(field, "content filter field");
|
|
1607
|
+
} catch {
|
|
1608
|
+
throw new EmDashValidationError(`Invalid content filter field: ${field}`);
|
|
1609
|
+
}
|
|
1610
|
+
const normalized = fields.map((field) => {
|
|
1611
|
+
const fieldType = metadata.get(field);
|
|
1612
|
+
if (!fieldType || !isIndexableFieldType(fieldType)) throw new EmDashValidationError(`Cannot filter by field "${field}". Custom fields must be indexed before filtering.`);
|
|
1613
|
+
return this.normalizeFieldFilter(field, fieldType, resolvedFilters[field]);
|
|
1614
|
+
});
|
|
1615
|
+
if (normalized.reduce((total, filter) => {
|
|
1616
|
+
if (filter.kind === "null") return total;
|
|
1617
|
+
if (filter.kind === "exact") return total + 1;
|
|
1618
|
+
if (filter.kind === "in") return total + filter.values.length;
|
|
1619
|
+
return total + Object.keys(filter.bounds).length;
|
|
1620
|
+
}, 0) > SQL_BATCH_SIZE) throw new EmDashValidationError(`Indexed field filters have a total operand budget of ${SQL_BATCH_SIZE}`);
|
|
1621
|
+
return normalized;
|
|
1622
|
+
}
|
|
1623
|
+
applyFieldFilters(query, filters) {
|
|
1624
|
+
let next = query;
|
|
1625
|
+
for (const filter of filters) {
|
|
1626
|
+
const column = sql.ref(filter.column);
|
|
1627
|
+
const isPresent = sql`${column} IS NOT NULL`;
|
|
1628
|
+
if (filter.kind === "null") {
|
|
1629
|
+
next = next.where(() => sql`(${isPresent}) = FALSE AND ${column} IS NULL`);
|
|
1630
|
+
continue;
|
|
1631
|
+
}
|
|
1632
|
+
if (filter.kind === "exact") {
|
|
1633
|
+
next = next.where(() => sql`(${isPresent}) = TRUE AND ${column} = ${filter.value}`);
|
|
1634
|
+
continue;
|
|
1635
|
+
}
|
|
1636
|
+
if (filter.kind === "in") {
|
|
1637
|
+
const values = sql.join(filter.values.map((value) => sql`${value}`), sql`, `);
|
|
1638
|
+
next = next.where(() => sql`(${isPresent}) = TRUE AND ${column} IN (${values})`);
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
next = next.where(() => sql`(${isPresent}) = TRUE`);
|
|
1642
|
+
if (filter.bounds.gt !== void 0) next = next.where(() => sql`${column} > ${filter.bounds.gt}`);
|
|
1643
|
+
if (filter.bounds.gte !== void 0) next = next.where(() => sql`${column} >= ${filter.bounds.gte}`);
|
|
1644
|
+
if (filter.bounds.lt !== void 0) next = next.where(() => sql`${column} < ${filter.bounds.lt}`);
|
|
1645
|
+
if (filter.bounds.lte !== void 0) next = next.where(() => sql`${column} <= ${filter.bounds.lte}`);
|
|
1646
|
+
}
|
|
1647
|
+
return next;
|
|
1648
|
+
}
|
|
1229
1649
|
/**
|
|
1230
1650
|
* Map order field names to database columns.
|
|
1231
1651
|
* Only allows known fields to prevent column enumeration via crafted orderBy values.
|
|
1232
1652
|
*/
|
|
1233
|
-
mapOrderField(field) {
|
|
1234
|
-
const mapped =
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1653
|
+
mapOrderField(field, sortableExtras = []) {
|
|
1654
|
+
const mapped = ORDER_FIELD_COLUMNS[field];
|
|
1655
|
+
if (mapped) return mapped;
|
|
1656
|
+
if (sortableExtras.includes(field)) {
|
|
1657
|
+
validateIdentifier(field, "order field");
|
|
1658
|
+
return field;
|
|
1659
|
+
}
|
|
1660
|
+
throw new EmDashValidationError(`Invalid order field: ${field}`);
|
|
1661
|
+
}
|
|
1662
|
+
async resolveOrderField(type, field, sortableExtras = []) {
|
|
1663
|
+
try {
|
|
1664
|
+
return {
|
|
1665
|
+
column: this.mapOrderField(field, sortableExtras),
|
|
1666
|
+
indexedCustomField: false
|
|
1667
|
+
};
|
|
1668
|
+
} catch (error) {
|
|
1669
|
+
if (!(error instanceof EmDashValidationError)) throw error;
|
|
1670
|
+
}
|
|
1671
|
+
const customField = await this.db.selectFrom("_emdash_collections as collection").leftJoin("_emdash_fields as field", (join) => join.onRef("field.collection_id", "=", "collection.id").on("field.slug", "=", field).on("field.indexed", "=", 1)).where("collection.slug", "=", type).select(["collection.id as collectionId", "field.slug as fieldSlug"]).executeTakeFirst();
|
|
1672
|
+
if (!customField) throw new ContentCollectionNotFoundError(type);
|
|
1673
|
+
if (!customField.fieldSlug) throw new EmDashValidationError(`Invalid order field: ${field}. Custom fields must be indexed before sorting.`);
|
|
1674
|
+
validateIdentifier(customField.fieldSlug, "content order field");
|
|
1675
|
+
return {
|
|
1676
|
+
column: customField.fieldSlug,
|
|
1677
|
+
indexedCustomField: true
|
|
1678
|
+
};
|
|
1248
1679
|
}
|
|
1249
1680
|
};
|
|
1250
1681
|
|
|
1251
1682
|
//#endregion
|
|
1252
|
-
export { content_exports as n,
|
|
1253
|
-
//# sourceMappingURL=content-
|
|
1683
|
+
export { RevisionRepository as i, content_exports as n, isSystemOrderField as r, ContentRepository as t };
|
|
1684
|
+
//# sourceMappingURL=content-ZHCc1ngN.mjs.map
|