emdash 0.29.0 → 0.30.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-DPAkL6QF.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
- package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
- package/dist/{allowed-origins-FXB-FplB.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
- package/dist/{allowed-origins-FXB-FplB.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.d.mts.map +1 -1
- package/dist/api/route-utils.mjs +19 -19
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -4
- package/dist/{api-DVbHNApo.mjs → api-b8WIiGU4.mjs} +253 -153
- package/dist/api-b8WIiGU4.mjs.map +1 -0
- package/dist/api-tokens-Cvmixds7.mjs +3 -0
- package/dist/{api-tokens-UYBkl17d.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
- package/dist/{api-tokens-UYBkl17d.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
- package/dist/{apply-D23iUV4q.mjs → apply-CmIJK9j8.mjs} +34 -37
- package/dist/apply-CmIJK9j8.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -13
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +90 -11
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -11
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +56 -107
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +47 -3
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +326 -110
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/PluginRegistry.d.mts +5 -1
- package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
- package/dist/astro/routes/PluginRegistry.mjs +2 -1
- package/dist/astro/routes/PluginRegistry.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 +7 -7
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +15 -14
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +16 -21
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +15 -14
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -12
- 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 +11 -10
- 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 +11 -10
- 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/repair.mjs +12 -10
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- 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.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +45 -39
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -38
- 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 +42 -39
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +45 -39
- 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 +39 -38
- 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 +45 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -38
- 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 +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -38
- 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 +44 -41
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -38
- 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 +39 -38
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- 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 +5 -5
- 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.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- 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 +5 -5
- package/dist/astro/routes/api/auth/me.mjs +9 -8
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +6 -3
- package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +15 -5
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
- 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 +13 -12
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
- 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 +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -12
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +20 -19
- 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 -4
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
- 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 +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +12 -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 +8 -8
- 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 +17 -16
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -12
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +12 -12
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -11
- package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -12
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +17 -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 -12
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +23 -22
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +7 -8
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.d.mts.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +149 -45
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -8
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +26 -10
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- 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 +10 -9
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +31 -11
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +10 -9
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +7 -8
- package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
- 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 +52 -24
- 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 +20 -32
- 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 +16 -15
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +11 -11
- package/dist/astro/routes/api/relations/index.mjs +16 -15
- 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 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -38
- 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 +39 -38
- 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 +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -9
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +13 -12
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +12 -11
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +13 -12
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +12 -11
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- 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_.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
- package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
- package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
- 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 +19 -15
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +18 -14
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +26 -26
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +28 -27
- 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 -215
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +14 -13
- 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.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
- 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 -7
- 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 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +8 -8
- package/dist/astro/types.d.mts +38 -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-BmCwQCib.mjs → authorize-WxsiePzy.mjs} +7 -4
- package/dist/authorize-WxsiePzy.mjs.map +1 -0
- package/dist/backup-S8kFWtwD.mjs +241 -0
- package/dist/backup-S8kFWtwD.mjs.map +1 -0
- package/dist/{base64-C74Msx8h.mjs → base64-B-PsqheR.mjs} +8 -4
- package/dist/base64-B-PsqheR.mjs.map +1 -0
- package/dist/{byline-BWb5H-65.mjs → byline-XEjchwzZ.mjs} +6 -6
- package/dist/{byline-BWb5H-65.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
- package/dist/{byline-fields-DO6bAYK8.mjs → byline-fields-CdU_LTF1.mjs} +1 -1
- package/dist/{byline-fields-DO6bAYK8.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
- package/dist/{bylines-BGuKFaBy.mjs → bylines-BJbT4gKS.mjs} +4 -4
- package/dist/{bylines-BGuKFaBy.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
- package/dist/{bylines-CHojDMpj.mjs → bylines-czseViYo.mjs} +6 -6
- package/dist/{bylines-CHojDMpj.mjs.map → bylines-czseViYo.mjs.map} +1 -1
- package/dist/{cache-BeR7RfN8.mjs → cache-CGCd6AVM.mjs} +2 -2
- package/dist/{cache-BeR7RfN8.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
- package/dist/{challenge-store-B426wQ6O.mjs → challenge-store-BFzgFRog.mjs} +1 -1
- package/dist/{challenge-store-B426wQ6O.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
- package/dist/{chunks-BU5_nrAC.mjs → chunks-BxXyunY-.mjs} +2 -2
- package/dist/{chunks-BU5_nrAC.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
- package/dist/cli/index.mjs +138 -31
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +54 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +16 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-SWh31kS0.mjs → comment-DPT0WKyd.mjs} +2 -2
- package/dist/{comment-SWh31kS0.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
- package/dist/{comment-reaction-DgcpziXI.mjs → comment-reaction-C65MldIB.mjs} +2 -2
- package/dist/{comment-reaction-DgcpziXI.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
- package/dist/{comments-kZYGppMS.mjs → comments-Bz6sCbgD.mjs} +3 -3
- package/dist/{comments-kZYGppMS.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
- package/dist/{components-CliOkZAs.mjs → components-DZkL4Fx0.mjs} +1 -1
- package/dist/{components-CliOkZAs.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
- package/dist/{content-BO61Sx4j.mjs → content-Ci04z2z-.mjs} +53 -19
- package/dist/content-Ci04z2z-.mjs.map +1 -0
- package/dist/{content-refresh-BkkApzeS.mjs → content-refresh-D4khvC0R.mjs} +95 -3
- package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
- package/dist/{context-DtSFYFuS.mjs → context-B6hc7zJL.mjs} +97 -74
- package/dist/context-B6hc7zJL.mjs.map +1 -0
- package/dist/{cron-YFJ7uNVA.mjs → cron-BlKIMD_e.mjs} +1 -1
- package/dist/{cron-YFJ7uNVA.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
- package/dist/{dashboard-xo_gPs_D.mjs → dashboard-C5NkXFbi.mjs} +4 -4
- package/dist/{dashboard-xo_gPs_D.mjs.map → dashboard-C5NkXFbi.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-BKuXh_fi.mjs → db-errors-CcWLaRiR.mjs} +4 -2
- package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
- package/dist/{default-DY5ovGUG.mjs → default-C4v9KP56.mjs} +1 -1
- package/dist/{default-DY5ovGUG.mjs.map → default-C4v9KP56.mjs.map} +1 -1
- package/dist/{device-flow-CPXQ_QfW.mjs → device-flow-BeA6lUS1.mjs} +5 -6
- package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
- package/dist/{dialect-helpers-Cue7QQOR.mjs → dialect-helpers-HxEQGl_1.mjs} +57 -11
- package/dist/{dialect-helpers-Cue7QQOR.mjs.map → dialect-helpers-HxEQGl_1.mjs.map} +1 -1
- package/dist/{email-console-CjkQc7oY.mjs → email-console-C-9Ng8DM.mjs} +1 -1
- package/dist/{email-console-CjkQc7oY.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
- package/dist/error-CEGF6UZb.mjs +90 -0
- package/dist/error-CEGF6UZb.mjs.map +1 -0
- package/dist/{error-CfJMLSkd.mjs → errors-DtEXIQQV.mjs} +15 -84
- package/dist/errors-DtEXIQQV.mjs.map +1 -0
- package/dist/{escape-r8_GbEU2.mjs → escape-CFedIB1C.mjs} +1 -1
- package/dist/{escape-r8_GbEU2.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
- package/dist/{field-defs-cache-BVrNCgSj.mjs → field-defs-cache-DvmlgP-D.mjs} +2 -2
- package/dist/{field-defs-cache-BVrNCgSj.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
- package/dist/{fts-manager-BD9s77qh.mjs → fts-manager-DzqIBrrW.mjs} +3 -3
- package/dist/{fts-manager-BD9s77qh.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
- package/dist/{hreflang-CgIxhH4k.d.mts → hreflang-CIxH_LKz.d.mts} +2 -2
- package/dist/{hreflang-CgIxhH4k.d.mts.map → hreflang-CIxH_LKz.d.mts.map} +1 -1
- package/dist/{hreflang-pAWUiPd_.mjs → hreflang-db2Tpb2o.mjs} +5 -5
- package/dist/{hreflang-pAWUiPd_.mjs.map → hreflang-db2Tpb2o.mjs.map} +1 -1
- package/dist/{import-2jHtLzsO.mjs → import-Dmkm8S1W.mjs} +4 -4
- package/dist/{import-2jHtLzsO.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
- package/dist/{index-DxjWLKGT.d.mts → index-BEui-cRd.d.mts} +3 -3
- package/dist/{index-DxjWLKGT.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
- package/dist/{index-BXOCyLj0.d.mts → index-wYnC6u4o.d.mts} +780 -15
- package/dist/index-wYnC6u4o.d.mts.map +1 -0
- package/dist/index.d.mts +18 -19
- package/dist/index.mjs +59 -58
- package/dist/{load-DgoWMdRX.mjs → load-Cx27ki1l.mjs} +2 -2
- package/dist/{load-DgoWMdRX.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
- package/dist/{loader-Rb8QlGZp.mjs → loader-Be3ouI5L.mjs} +170 -6
- package/dist/loader-Be3ouI5L.mjs.map +1 -0
- package/dist/{manifest-schema-DeGNma2O.mjs → manifest-schema-bCq54i7F.mjs} +16 -2
- package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +30 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +29 -3
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +12 -13
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +6 -6
- package/dist/{media-D2ZFowpn.mjs → media-BjhhENaJ.mjs} +2 -2
- package/dist/{media-D2ZFowpn.mjs.map → media-BjhhENaJ.mjs.map} +1 -1
- package/dist/{media-allowlist-Dc05vKtt.mjs → media-allowlist-jUppPWFy.mjs} +1 -1
- package/dist/{media-allowlist-Dc05vKtt.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
- package/dist/media-kIV1IxFf.mjs +243 -0
- package/dist/media-kIV1IxFf.mjs.map +1 -0
- package/dist/media-upload-D2wk3EIt.mjs +145 -0
- package/dist/media-upload-D2wk3EIt.mjs.map +1 -0
- package/dist/{media-url-DgIEYZr4.mjs → media-url-BCm5vBn6.mjs} +1 -1
- package/dist/{media-url-DgIEYZr4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
- package/dist/{media-usage-B__v9NMm.mjs → media-usage-CljdO1mc.mjs} +138 -5
- package/dist/{media-usage-B__v9NMm.mjs.map → media-usage-CljdO1mc.mjs.map} +1 -1
- package/dist/{menus-BtvH7Z7t.mjs → menus-BcyElFtI.mjs} +155 -12
- package/dist/menus-BcyElFtI.mjs.map +1 -0
- package/dist/{menus-BpfevlJD.mjs → menus-CZyG6rvx.mjs} +2 -2
- package/dist/{menus-BpfevlJD.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
- package/dist/{mode-BVnhGZ2o.mjs → mode-fiXRMfeA.mjs} +1 -1
- package/dist/{mode-BVnhGZ2o.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
- package/dist/{oauth-authorization-BWqWTHBK.mjs → oauth-authorization-oqfbBuMH.mjs} +5 -6
- package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
- package/dist/{oauth-clients-43_XADoa.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
- package/dist/{oauth-clients-43_XADoa.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
- package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
- package/dist/{oauth-state-store-BRSUEkmx.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Ctgemb0k.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
- package/dist/{oauth-user-lookup-Ctgemb0k.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-COXGTtqd.d.mts → options-BqMkWfYa.d.mts} +6 -6
- package/dist/{options-COXGTtqd.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.d.mts.map +1 -1
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-GLksnn-B.mjs → parse-C_-6klII.mjs} +4 -12
- package/dist/{parse-GLksnn-B.mjs.map → parse-C_-6klII.mjs.map} +1 -1
- package/dist/{passkey-config-CjA1UbDj.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
- package/dist/{passkey-config-CjA1UbDj.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
- package/dist/{placeholder-DR-eeZr-.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
- package/dist/{placeholder-DR-eeZr-.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +21 -2
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +18 -17
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugin-utils.mjs +8 -6
- package/dist/plugin-utils.mjs.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -11
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{portable-text-BAkgEKcv.mjs → portable-text-sDj92Kxv.mjs} +1 -1
- package/dist/{portable-text-BAkgEKcv.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
- package/dist/{preview-Rloa09Wp.mjs → preview-D4Jnbfx7.mjs} +2 -2
- package/dist/{preview-Rloa09Wp.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
- package/dist/{public-url-C0cEvrRu.mjs → public-url-DSGTnJFw.mjs} +5 -3
- package/dist/public-url-DSGTnJFw.mjs.map +1 -0
- package/dist/{query-ZzvXyxWq.mjs → query-DR73ZNfm.mjs} +14 -14
- package/dist/{query-ZzvXyxWq.mjs.map → query-DR73ZNfm.mjs.map} +1 -1
- package/dist/{query-BxT95opY.mjs → query-Di7DOmPV.mjs} +3 -3
- package/dist/{query-BxT95opY.mjs.map → query-Di7DOmPV.mjs.map} +1 -1
- package/dist/{rate-limit-Cg4Rvc_-.mjs → rate-limit-CMj83JNW.mjs} +2 -2
- package/dist/{rate-limit-Cg4Rvc_-.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
- package/dist/{redirect-Ce_6Yb6z.mjs → redirect-Botom7X6.mjs} +1 -1
- package/dist/{redirect-Ce_6Yb6z.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
- package/dist/{redirect-Ch3E98qZ.mjs → redirect-CgLPYflR.mjs} +10 -4
- package/dist/redirect-CgLPYflR.mjs.map +1 -0
- package/dist/{redirects-CXmVGRNZ.mjs → redirects-B7t9bKsL.mjs} +4 -4
- package/dist/{redirects-CXmVGRNZ.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
- package/dist/{redirects-CeD7K7EX.mjs → redirects-BBq3n2Rj.mjs} +4 -175
- package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
- package/dist/{registry-CyIXPi4E.mjs → registry-FV15nLge.mjs} +97 -8
- package/dist/registry-FV15nLge.mjs.map +1 -0
- package/dist/{relation-Ba68Tm4Z.mjs → relation-9M9j_UWo.mjs} +3 -3
- package/dist/{relation-Ba68Tm4Z.mjs.map → relation-9M9j_UWo.mjs.map} +1 -1
- package/dist/{relations-BmBmX4Eb.mjs → relations-5_avdrN_.mjs} +2 -2
- package/dist/{relations-BmBmX4Eb.mjs.map → relations-5_avdrN_.mjs.map} +1 -1
- package/dist/{relations-C8hVyEy0.mjs → relations-BKvO39-9.mjs} +5 -5
- package/dist/{relations-C8hVyEy0.mjs.map → relations-BKvO39-9.mjs.map} +1 -1
- package/dist/{relations-CbBpoOys.d.mts → relations-Bh8jlFsU.d.mts} +306 -4
- package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
- package/dist/{request-meta-DCwktC5P.mjs → request-meta-DzXYYI-n.mjs} +2 -2
- package/dist/{request-meta-DCwktC5P.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
- package/dist/{runner-CiNdIk3y.d.mts → runner-Dd8m8k9F.d.mts} +2 -2
- package/dist/{runner-CiNdIk3y.d.mts.map → runner-Dd8m8k9F.d.mts.map} +1 -1
- package/dist/{runner-jt65bF7F.mjs → runner-DfnZ5eUr.mjs} +333 -199
- package/dist/runner-DfnZ5eUr.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -12
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +4 -4
- package/dist/{schema-DwjufZ1S.mjs → schema-BXxlHeAf.mjs} +3 -3
- package/dist/{schema-DwjufZ1S.mjs.map → schema-BXxlHeAf.mjs.map} +1 -1
- package/dist/scopes-Bl4IwHA-.mjs +27 -0
- package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
- package/dist/{search-Cl875CVE.mjs → search-Bff-7jFt.mjs} +5 -5
- package/dist/{search-Cl875CVE.mjs.map → search-Bff-7jFt.mjs.map} +1 -1
- package/dist/{secrets-CO_bEmII.mjs → secrets-CSwQIl4q.mjs} +3 -3
- package/dist/{secrets-CO_bEmII.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
- package/dist/{sections-DTKzgoiS.mjs → sections-CwW4s1al.mjs} +3 -3
- package/dist/{sections-DTKzgoiS.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +20 -20
- package/dist/seo/index.d.mts +14 -3
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +16 -16
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-BLm6SXzS.mjs → seo-2cmFHZns.mjs} +2 -2
- package/dist/{seo-BLm6SXzS.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
- package/dist/{seo-BjrbXAd_.mjs → seo-C3GDfT0V.mjs} +1 -1
- package/dist/{seo-BjrbXAd_.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
- package/dist/{service-D6zDmKXy.mjs → service-DkGTWGIi.mjs} +3 -3
- package/dist/{service-D6zDmKXy.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
- package/dist/{session-user-DoSs6YM8.mjs → session-user-DbHqKDKe.mjs} +1 -1
- package/dist/{session-user-DoSs6YM8.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
- package/dist/{settings-CmS3TwXf.mjs → settings-C4s8hFQm.mjs} +3 -3
- package/dist/{settings-CmS3TwXf.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
- package/dist/{settings-BuQYvLfy.mjs → settings-CpA4lQFt.mjs} +4 -4
- package/dist/{settings-BuQYvLfy.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
- package/dist/{setup-complete-BPNgLHlU.mjs → setup-complete-CdIlqloh.mjs} +1 -1
- package/dist/{setup-complete-BPNgLHlU.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
- package/dist/{setup-nonce-DEPZX96T.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
- package/dist/{setup-nonce-DEPZX96T.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
- package/dist/{single-flight-cache-DEtW-OEG.mjs → single-flight-cache-C2exrGAi.mjs} +1 -1
- package/dist/{single-flight-cache-DEtW-OEG.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
- package/dist/{site-url-CcLy5D5s.mjs → site-url-NGJT6NTU.mjs} +1 -1
- package/dist/{site-url-CcLy5D5s.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
- package/dist/snapshot-BdpUJKD-.mjs +216 -0
- package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
- package/dist/{ssrf-TrKYJAy0.mjs → ssrf-CviKqWmq.mjs} +1 -1
- package/dist/{ssrf-TrKYJAy0.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
- package/dist/state-xxv6ZTMv.mjs +128 -0
- package/dist/state-xxv6ZTMv.mjs.map +1 -0
- package/dist/{status-D3Gy1Zc6.mjs → status-COfycGIU.mjs} +1 -1
- package/dist/{status-D3Gy1Zc6.mjs.map → status-COfycGIU.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-ClS4RKaZ.mjs → taxonomies-Ce49uIzY.mjs} +4 -4
- package/dist/{taxonomies-ClS4RKaZ.mjs.map → taxonomies-Ce49uIzY.mjs.map} +1 -1
- package/dist/{taxonomies-pUkuD6nj.mjs → taxonomies-DjSKBZpq.mjs} +7 -7
- package/dist/{taxonomies-pUkuD6nj.mjs.map → taxonomies-DjSKBZpq.mjs.map} +1 -1
- package/dist/{taxonomy-BkxbUMSw.mjs → taxonomy-DfVooU4W.mjs} +51 -13
- package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
- package/dist/{tokens-BV6fgl5A.mjs → tokens-DVltpO2D.mjs} +2 -2
- package/dist/{tokens-BV6fgl5A.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
- package/dist/{transport-DTFhhPOg.mjs → transport-CKrlqSpD.mjs} +1 -1
- package/dist/{transport-DTFhhPOg.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
- package/dist/{transport-DmlmzD2U.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
- package/dist/{transport-DmlmzD2U.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CSgZVESw.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
- package/dist/{trusted-proxy-CSgZVESw.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
- package/dist/{types-B6-N9cBB.d.mts → types-B4vm81VH.d.mts} +1 -1
- package/dist/{types-B6-N9cBB.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
- package/dist/{types-Cm4Cz-8M.d.mts → types-B97jg3aW.d.mts} +6 -1
- package/dist/{types-Cm4Cz-8M.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
- package/dist/{types-BNZsPL9z.mjs → types-BD40g7zz.mjs} +1 -1
- package/dist/{types-BNZsPL9z.mjs.map → types-BD40g7zz.mjs.map} +1 -1
- package/dist/{types-QnlQIyPE.d.mts → types-BNfPHfay.d.mts} +1 -1
- package/dist/{types-QnlQIyPE.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
- package/dist/{types-DLIrNtv5.d.mts → types-BfYUPJdP.d.mts} +2 -2
- package/dist/{types-DLIrNtv5.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
- package/dist/{types-CtDVagM4.d.mts → types-BvB7gDOD.d.mts} +38 -4
- package/dist/types-BvB7gDOD.d.mts.map +1 -0
- package/dist/{types-B_pmP7Yq.d.mts → types-C7U0HlEr.d.mts} +1 -1
- package/dist/{types-B_pmP7Yq.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
- package/dist/{types-Ch8pFMEm.mjs → types-D1iJ3DpO.mjs} +3 -3
- package/dist/{types-Ch8pFMEm.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
- package/dist/{types-momGysZk.d.mts → types-DPKhI5ib.d.mts} +9 -1
- package/dist/types-DPKhI5ib.d.mts.map +1 -0
- package/dist/{types-BCVuUPrL.d.mts → types-Kmaxdarz.d.mts} +1 -1
- package/dist/{types-BCVuUPrL.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
- package/dist/{types-qljd1hsL.d.mts → types-iVeZ5g6N.d.mts} +1 -1
- package/dist/{types-qljd1hsL.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
- package/dist/{user-DTxX_Fha.mjs → user-Bh-L1qo6.mjs} +3 -3
- package/dist/{user-DTxX_Fha.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
- package/dist/{utils-Cz8PVrl4.mjs → utils-BbUgmeZG.mjs} +1 -1
- package/dist/{utils-Cz8PVrl4.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
- package/dist/{validate-9jLuE301.d.mts → validate-DULfgpJP.d.mts} +5 -5
- package/dist/{validate-9jLuE301.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
- package/dist/{validate-C3CpWlNt.mjs → validate-V9nCwq_-.mjs} +2 -2
- package/dist/{validate-C3CpWlNt.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
- package/dist/{validation-DM2K_NJC.mjs → validation-BsVUJfsP.mjs} +10 -10
- package/dist/{validation-DM2K_NJC.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
- package/dist/version-907opKac.mjs +7 -0
- package/dist/{version-BlIJvNAZ.mjs.map → version-907opKac.mjs.map} +1 -1
- package/dist/{widgets-B_X6_UXJ.mjs → widgets-DGv1Z04V.mjs} +3 -3
- package/dist/{widgets-B_X6_UXJ.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-tADW4KTa.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
- package/dist/{wxr-taxonomies-tADW4KTa.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-oNJB2S81.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +3 -3
- package/dist/{wxr-taxonomies-oNJB2S81.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
- package/dist/{zod-generator-CrfV79De.mjs → zod-generator-B5prQ5M4.mjs} +2 -2
- package/dist/{zod-generator-CrfV79De.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
- package/package.json +8 -8
- package/src/api/authorize.ts +10 -1
- package/src/api/error.ts +5 -5
- package/src/api/errors.ts +14 -0
- package/src/api/handlers/backup.ts +312 -0
- package/src/api/handlers/content.ts +36 -2
- package/src/api/handlers/device-flow.ts +2 -3
- package/src/api/handlers/index.ts +16 -0
- package/src/api/handlers/marketplace.ts +38 -0
- package/src/api/handlers/media-upload.ts +210 -0
- package/src/api/handlers/media-usage.ts +211 -2
- package/src/api/handlers/oauth-authorization.ts +2 -6
- package/src/api/handlers/plugin-settings.ts +218 -0
- package/src/api/handlers/plugins.ts +41 -0
- package/src/api/handlers/registry.ts +39 -0
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/openapi/document.ts +48 -6
- package/src/api/parse.ts +1 -15
- package/src/api/public-url.ts +4 -2
- package/src/api/schemas/common.ts +6 -2
- package/src/api/schemas/media-usage.ts +72 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/astro/integration/index.ts +38 -0
- package/src/astro/integration/routes.ts +35 -0
- package/src/astro/integration/runtime.ts +6 -0
- package/src/astro/integration/virtual-modules.ts +41 -7
- package/src/astro/integration/vite-config.ts +17 -1
- package/src/astro/middleware/auth.ts +70 -78
- package/src/astro/middleware/csp.ts +5 -2
- package/src/astro/middleware.ts +86 -31
- package/src/astro/public-plugin-api-routes.ts +2 -1
- package/src/astro/routes/PluginRegistry.tsx +5 -2
- package/src/astro/routes/admin.astro +56 -16
- package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
- package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
- package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/index.ts +9 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
- package/src/astro/routes/api/auth/mode.ts +6 -14
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -4
- package/src/astro/routes/api/auth/oauth/[provider].ts +24 -6
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
- package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
- package/src/astro/routes/api/content/[collection]/index.ts +6 -8
- package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
- package/src/astro/routes/api/manifest.ts +2 -9
- package/src/astro/routes/api/mcp.ts +2 -1
- package/src/astro/routes/api/media/[id]/usage.ts +30 -0
- package/src/astro/routes/api/media/[id].ts +17 -6
- package/src/astro/routes/api/media/file/[...key].ts +8 -0
- package/src/astro/routes/api/media.ts +21 -2
- package/src/astro/routes/api/oauth/authorize.ts +2 -6
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
- package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
- package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
- package/src/astro/routes/api/settings/backups/export.ts +43 -0
- package/src/astro/routes/api/settings/backups/index.ts +76 -0
- package/src/astro/routes/api/setup/admin-verify.ts +8 -4
- package/src/astro/routes/api/setup/admin.ts +11 -4
- package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
- package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
- package/src/astro/types.ts +48 -2
- package/src/auth/api-tokens.ts +1 -0
- package/src/auth/oauth-state-store.ts +3 -0
- package/src/auth/providers/github-admin.tsx +5 -6
- package/src/auth/providers/google-admin.tsx +5 -6
- package/src/auth/scopes.ts +3 -9
- package/src/cli/client-factory.ts +0 -1
- package/src/cli/commands/bundle-utils.ts +50 -1
- package/src/cli/commands/bundle.ts +9 -2
- package/src/cli/commands/media.ts +127 -0
- package/src/client/index.ts +84 -2
- package/src/client/transport.ts +1 -1
- package/src/components/EmDashHead.astro +4 -8
- package/src/components/InlinePortableTextEditor.tsx +56 -35
- package/src/components/marks/Link.astro +5 -1
- package/src/database/dialect-helpers.ts +77 -3
- package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
- package/src/database/migrations/052_media_usage_read_index.ts +26 -0
- package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
- package/src/database/migrations/runner.ts +6 -0
- package/src/database/repositories/audit.ts +2 -1
- package/src/database/repositories/content.ts +98 -16
- package/src/database/repositories/media-usage.ts +250 -1
- package/src/database/repositories/plugin-storage.ts +29 -32
- package/src/database/repositories/redirect.ts +14 -2
- package/src/database/repositories/taxonomy.ts +57 -8
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +9 -0
- package/src/emdash-runtime.ts +310 -66
- package/src/loader.ts +292 -1
- package/src/mcp/server.ts +222 -5
- package/src/media/image-endpoint.ts +38 -2
- package/src/page/metadata.ts +27 -0
- package/src/plugin-types.ts +19 -0
- package/src/plugin-utils.ts +8 -6
- package/src/plugins/adapt-sandbox-entry.ts +30 -1
- package/src/plugins/context.ts +7 -0
- package/src/plugins/define-plugin.ts +16 -0
- package/src/plugins/manifest-schema.ts +28 -1
- package/src/plugins/routes.ts +27 -1
- package/src/plugins/sandbox/runner-options.ts +16 -0
- package/src/plugins/sandbox/types.ts +6 -1
- package/src/plugins/state.ts +17 -1
- package/src/plugins/storage-query.ts +67 -33
- package/src/plugins/types.ts +41 -0
- package/src/schema/registry.ts +141 -5
- package/src/seed/apply.ts +28 -29
- package/src/seo/index.ts +19 -4
- package/src/storage/types.ts +6 -0
- package/src/utils/base64.ts +7 -2
- package/src/utils/db-errors.ts +3 -1
- package/src/virtual-modules.d.ts +13 -0
- package/src/visual-editing/toolbar.ts +1 -1
- package/dist/adapters-DPAkL6QF.d.mts.map +0 -1
- package/dist/api-DVbHNApo.mjs.map +0 -1
- package/dist/api-tokens-Dk2GrJMY.mjs +0 -3
- package/dist/apply-D23iUV4q.mjs.map +0 -1
- package/dist/authorize-BmCwQCib.mjs.map +0 -1
- package/dist/base64-C74Msx8h.mjs.map +0 -1
- package/dist/content-BO61Sx4j.mjs.map +0 -1
- package/dist/content-refresh-BkkApzeS.mjs.map +0 -1
- package/dist/context-DtSFYFuS.mjs.map +0 -1
- package/dist/db-errors-BKuXh_fi.mjs.map +0 -1
- package/dist/device-flow-CPXQ_QfW.mjs.map +0 -1
- package/dist/error-CfJMLSkd.mjs.map +0 -1
- package/dist/index-BXOCyLj0.d.mts.map +0 -1
- package/dist/loader-Rb8QlGZp.mjs.map +0 -1
- package/dist/manifest-schema-DeGNma2O.mjs.map +0 -1
- package/dist/menus-BtvH7Z7t.mjs.map +0 -1
- package/dist/oauth-authorization-BWqWTHBK.mjs.map +0 -1
- package/dist/public-url-C0cEvrRu.mjs.map +0 -1
- package/dist/redirect-Ch3E98qZ.mjs.map +0 -1
- package/dist/redirects-CeD7K7EX.mjs.map +0 -1
- package/dist/registry-CyIXPi4E.mjs.map +0 -1
- package/dist/relations-CbBpoOys.d.mts.map +0 -1
- package/dist/runner-jt65bF7F.mjs.map +0 -1
- package/dist/scheduled-publish-DlJHGcuL.d.mts +0 -11
- package/dist/scheduled-publish-DlJHGcuL.d.mts.map +0 -1
- package/dist/taxonomy-BkxbUMSw.mjs.map +0 -1
- package/dist/types-CtDVagM4.d.mts.map +0 -1
- package/dist/types-momGysZk.d.mts.map +0 -1
- package/dist/version-BlIJvNAZ.mjs +0 -7
- /package/dist/{ssrf-B5DOv5E5.mjs → ssrf-BB__xfNM.mjs} +0 -0
- /package/dist/{types-DeCZBZxn.mjs → types-CK0LxPUQ.mjs} +0 -0
|
@@ -590,11 +590,16 @@ export class ContentRepository {
|
|
|
590
590
|
const tableName = getTableName(type);
|
|
591
591
|
const now = new Date().toISOString();
|
|
592
592
|
|
|
593
|
-
// Build update object with parameterized values
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
593
|
+
// Build update object with parameterized values. `version` bumps on
|
|
594
|
+
// every update so the _rev optimistic-concurrency token
|
|
595
|
+
// (version:updated_at) always moves — concurrent editors still get a
|
|
596
|
+
// 409 on stale saves. `updated_at` is stamped only when the request
|
|
597
|
+
// actually carries column writes: a draft-only save on a
|
|
598
|
+
// revision-supporting collection resolves to a column no-op here (all
|
|
599
|
+
// data went into draft storage), and stamping it anyway would register
|
|
600
|
+
// a phantom modification for public "last modified" consumers like
|
|
601
|
+
// sitemap <lastmod> and JSON-LD dateModified (#2143).
|
|
602
|
+
const updates: Record<string, unknown> = {};
|
|
598
603
|
|
|
599
604
|
if (input.status !== undefined) {
|
|
600
605
|
updates.status = input.status;
|
|
@@ -630,6 +635,12 @@ export class ContentRepository {
|
|
|
630
635
|
}
|
|
631
636
|
}
|
|
632
637
|
|
|
638
|
+
const hasColumnWrites = Object.keys(updates).length > 0;
|
|
639
|
+
if (hasColumnWrites) {
|
|
640
|
+
updates.updated_at = now;
|
|
641
|
+
}
|
|
642
|
+
updates.version = sql`version + 1`;
|
|
643
|
+
|
|
633
644
|
await this.db
|
|
634
645
|
.updateTable(tableName as keyof Database)
|
|
635
646
|
.set(updates)
|
|
@@ -637,6 +648,18 @@ export class ContentRepository {
|
|
|
637
648
|
.where("deleted_at" as never, "is", null)
|
|
638
649
|
.execute();
|
|
639
650
|
|
|
651
|
+
// Re-stamp the taxonomy pivot only when a denormalized column actually
|
|
652
|
+
// moved (status/publishedAt/scheduledAt). A plain content edit bumps
|
|
653
|
+
// `updated_at` — which is not denormalized — so it needs no pivot write,
|
|
654
|
+
// keeping the common edit path free of taxonomy write amplification.
|
|
655
|
+
if (
|
|
656
|
+
input.status !== undefined ||
|
|
657
|
+
input.publishedAt !== undefined ||
|
|
658
|
+
input.scheduledAt !== undefined
|
|
659
|
+
) {
|
|
660
|
+
await this.restampEntryPivot(type, id);
|
|
661
|
+
}
|
|
662
|
+
|
|
640
663
|
invalidateCollectionCache(type);
|
|
641
664
|
|
|
642
665
|
const updated = await this.findById(type, id);
|
|
@@ -662,7 +685,10 @@ export class ContentRepository {
|
|
|
662
685
|
`.execute(this.db);
|
|
663
686
|
|
|
664
687
|
const changed = (result.numAffectedRows ?? 0n) > 0n;
|
|
665
|
-
if (changed)
|
|
688
|
+
if (changed) {
|
|
689
|
+
await this.restampEntryPivot(type, id);
|
|
690
|
+
invalidateCollectionCache(type);
|
|
691
|
+
}
|
|
666
692
|
return changed;
|
|
667
693
|
}
|
|
668
694
|
|
|
@@ -683,10 +709,36 @@ export class ContentRepository {
|
|
|
683
709
|
const restored = result.rows[0];
|
|
684
710
|
if (!restored) return null;
|
|
685
711
|
|
|
712
|
+
await this.restampEntryPivot(type, id);
|
|
686
713
|
invalidateCollectionCache(type);
|
|
687
714
|
return this.mapRow(type, restored);
|
|
688
715
|
}
|
|
689
716
|
|
|
717
|
+
/**
|
|
718
|
+
* Re-stamp the denormalized filter + sort columns on every
|
|
719
|
+
* `content_taxonomies` pivot row for an entry from its authoritative `ec_*`
|
|
720
|
+
* row (migration 051). Called after any mutation that moves one of those
|
|
721
|
+
* columns so a taxonomy-filtered listing can seek the entry directly.
|
|
722
|
+
*
|
|
723
|
+
* A single correlated `UPDATE` reads the post-mutation values from `ec_*`, so
|
|
724
|
+
* the pivot converges to the authoritative row. This is NOT atomic with the
|
|
725
|
+
* `ec_*` mutation on D1 (no transactions), which is why the read path
|
|
726
|
+
* re-checks the real predicates on the joined `ec_*` row. Untagged entries
|
|
727
|
+
* have no pivot rows, so the statement is a cheap no-op for them.
|
|
728
|
+
*/
|
|
729
|
+
private async restampEntryPivot(type: string, id: string): Promise<void> {
|
|
730
|
+
const tableName = getTableName(type);
|
|
731
|
+
await sql`
|
|
732
|
+
UPDATE content_taxonomies
|
|
733
|
+
SET (status, scheduled_at, deleted_at, locale, published_at, created_at) = (
|
|
734
|
+
SELECT status, scheduled_at, deleted_at, locale, published_at, created_at
|
|
735
|
+
FROM ${sql.ref(tableName)}
|
|
736
|
+
WHERE ${sql.ref(tableName)}.id = ${id}
|
|
737
|
+
)
|
|
738
|
+
WHERE collection = ${type} AND entry_id = ${id}
|
|
739
|
+
`.execute(this.db);
|
|
740
|
+
}
|
|
741
|
+
|
|
690
742
|
/**
|
|
691
743
|
* Permanently delete content (cannot be undone)
|
|
692
744
|
*/
|
|
@@ -996,6 +1048,7 @@ export class ContentRepository {
|
|
|
996
1048
|
AND deleted_at IS NULL
|
|
997
1049
|
`.execute(this.db);
|
|
998
1050
|
|
|
1051
|
+
await this.restampEntryPivot(type, id);
|
|
999
1052
|
invalidateCollectionCache(type);
|
|
1000
1053
|
|
|
1001
1054
|
const updated = await this.findById(type, id);
|
|
@@ -1035,6 +1088,7 @@ export class ContentRepository {
|
|
|
1035
1088
|
AND deleted_at IS NULL
|
|
1036
1089
|
`.execute(this.db);
|
|
1037
1090
|
|
|
1091
|
+
await this.restampEntryPivot(type, id);
|
|
1038
1092
|
invalidateCollectionCache(type);
|
|
1039
1093
|
|
|
1040
1094
|
const updated = await this.findById(type, id);
|
|
@@ -1296,16 +1350,39 @@ export class ContentRepository {
|
|
|
1296
1350
|
// so the content table always holds the published version
|
|
1297
1351
|
const revision = await revisionRepo.findById(revisionToPublish);
|
|
1298
1352
|
if (revision) {
|
|
1299
|
-
|
|
1353
|
+
// A staged slug lands on the live column only here — it never
|
|
1354
|
+
// passes through update(), so its uniqueness was never checked.
|
|
1355
|
+
// Validate before any write: the `(slug, locale)` unique index
|
|
1356
|
+
// covers every row (drafts and trashed entries included), and
|
|
1357
|
+
// letting the constraint fire mid-publish would surface as an
|
|
1358
|
+
// opaque 500 after draft data already hit the live columns.
|
|
1359
|
+
// A NULL locale never collides (unique indexes treat NULLs as
|
|
1360
|
+
// distinct), so the check only applies to localized rows.
|
|
1361
|
+
const stagedSlug = typeof revision.data._slug === "string" ? revision.data._slug : null;
|
|
1362
|
+
if (stagedSlug !== null && stagedSlug !== existing.slug && existing.locale !== null) {
|
|
1363
|
+
const conflict = await this.findBySlugIncludingTrashed(type, stagedSlug, existing.locale);
|
|
1364
|
+
if (conflict && conflict.id !== id) {
|
|
1365
|
+
throw new EmDashValidationError(
|
|
1366
|
+
`Cannot publish: slug '${stagedSlug}' is already used by another entry` +
|
|
1367
|
+
` in this collection (id: ${conflict.id}). Choose a different slug.`,
|
|
1368
|
+
{ code: "SLUG_CONFLICT" },
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1300
1372
|
|
|
1301
|
-
//
|
|
1302
|
-
|
|
1373
|
+
// Write the slug before the data columns: the slug UPDATE is the
|
|
1374
|
+
// only statement here that can hit the unique constraint (if a
|
|
1375
|
+
// concurrent write took the slug after the check above), and on
|
|
1376
|
+
// D1 there is no transaction to roll back earlier statements.
|
|
1377
|
+
if (stagedSlug !== null) {
|
|
1303
1378
|
await sql`
|
|
1304
1379
|
UPDATE ${sql.ref(tableName)}
|
|
1305
|
-
SET slug = ${
|
|
1380
|
+
SET slug = ${stagedSlug}
|
|
1306
1381
|
WHERE id = ${id}
|
|
1307
1382
|
`.execute(this.db);
|
|
1308
1383
|
}
|
|
1384
|
+
|
|
1385
|
+
await this.syncDataColumns(type, id, revision.data);
|
|
1309
1386
|
}
|
|
1310
1387
|
|
|
1311
1388
|
if (publishedAt !== undefined) {
|
|
@@ -1339,6 +1416,8 @@ export class ContentRepository {
|
|
|
1339
1416
|
}
|
|
1340
1417
|
publishCommitted = true;
|
|
1341
1418
|
|
|
1419
|
+
await this.restampEntryPivot(type, id);
|
|
1420
|
+
|
|
1342
1421
|
const updated = await this.findById(type, id);
|
|
1343
1422
|
if (!updated) {
|
|
1344
1423
|
throw new Error("Content not found");
|
|
@@ -1427,6 +1506,7 @@ export class ContentRepository {
|
|
|
1427
1506
|
AND deleted_at IS NULL
|
|
1428
1507
|
`.execute(this.db);
|
|
1429
1508
|
|
|
1509
|
+
await this.restampEntryPivot(type, id);
|
|
1430
1510
|
invalidateCollectionCache(type);
|
|
1431
1511
|
|
|
1432
1512
|
const updated = await this.findById(type, id);
|
|
@@ -1450,7 +1530,6 @@ export class ContentRepository {
|
|
|
1450
1530
|
*/
|
|
1451
1531
|
async setDraftRevision(type: string, id: string, revisionId: string): Promise<void> {
|
|
1452
1532
|
const tableName = getTableName(type);
|
|
1453
|
-
const now = new Date().toISOString();
|
|
1454
1533
|
|
|
1455
1534
|
const existing = await this.findById(type, id);
|
|
1456
1535
|
if (!existing) {
|
|
@@ -1467,10 +1546,12 @@ export class ContentRepository {
|
|
|
1467
1546
|
throw new EmDashValidationError("Revision does not belong to the specified content item");
|
|
1468
1547
|
}
|
|
1469
1548
|
|
|
1549
|
+
// Draft staging leaves live content untouched, so it must not bump
|
|
1550
|
+
// updated_at — public "content last modified" consumers (sitemap
|
|
1551
|
+
// <lastmod>, dateModified) would see a phantom modification (#2143).
|
|
1470
1552
|
await sql`
|
|
1471
1553
|
UPDATE ${sql.ref(tableName)}
|
|
1472
|
-
SET draft_revision_id = ${revisionId}
|
|
1473
|
-
updated_at = ${now}
|
|
1554
|
+
SET draft_revision_id = ${revisionId}
|
|
1474
1555
|
WHERE id = ${id}
|
|
1475
1556
|
AND deleted_at IS NULL
|
|
1476
1557
|
`.execute(this.db);
|
|
@@ -1486,7 +1567,6 @@ export class ContentRepository {
|
|
|
1486
1567
|
*/
|
|
1487
1568
|
async discardDraft(type: string, id: string): Promise<ContentItem> {
|
|
1488
1569
|
const tableName = getTableName(type);
|
|
1489
|
-
const now = new Date().toISOString();
|
|
1490
1570
|
|
|
1491
1571
|
const existing = await this.findById(type, id);
|
|
1492
1572
|
if (!existing) {
|
|
@@ -1498,10 +1578,12 @@ export class ContentRepository {
|
|
|
1498
1578
|
return existing;
|
|
1499
1579
|
}
|
|
1500
1580
|
|
|
1581
|
+
// Discarding a draft restores the state from before the draft was
|
|
1582
|
+
// staged — nothing about the live entry changed in between, so
|
|
1583
|
+
// updated_at stays at its pre-draft value (#2143).
|
|
1501
1584
|
await sql`
|
|
1502
1585
|
UPDATE ${sql.ref(tableName)}
|
|
1503
|
-
SET draft_revision_id = NULL
|
|
1504
|
-
updated_at = ${now}
|
|
1586
|
+
SET draft_revision_id = NULL
|
|
1505
1587
|
WHERE id = ${id}
|
|
1506
1588
|
AND deleted_at IS NULL
|
|
1507
1589
|
`.execute(this.db);
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
MediaUsageTable,
|
|
21
21
|
} from "../types.js";
|
|
22
22
|
import { validateIdentifier } from "../validate.js";
|
|
23
|
-
import { decodeCursor, encodeCursor, type FindManyResult } from "./types.js";
|
|
23
|
+
import { decodeCursor, encodeCursor, InvalidCursorError, type FindManyResult } from "./types.js";
|
|
24
24
|
|
|
25
25
|
type DatabaseExecutor = Kysely<Database> | Transaction<Database>;
|
|
26
26
|
type MediaUsageSourceNullableStringColumn =
|
|
@@ -36,6 +36,23 @@ const OCCURRENCE_INSERT_BATCH_SIZE = Math.max(
|
|
|
36
36
|
1,
|
|
37
37
|
Math.floor(SQL_BATCH_SIZE / OCCURRENCE_BIND_COLUMNS),
|
|
38
38
|
);
|
|
39
|
+
const CONTENT_SOURCE_ELIGIBILITY = sql<boolean>`(
|
|
40
|
+
s.source_variant = 'draft_overlay'
|
|
41
|
+
OR (
|
|
42
|
+
s.source_variant = 'columns'
|
|
43
|
+
AND (
|
|
44
|
+
s.content_status = 'published'
|
|
45
|
+
OR NOT EXISTS (
|
|
46
|
+
SELECT 1
|
|
47
|
+
FROM _emdash_media_usage_sources AS overlay
|
|
48
|
+
WHERE overlay.source_type = 'content'
|
|
49
|
+
AND overlay.collection_slug = s.collection_slug
|
|
50
|
+
AND overlay.content_id = s.content_id
|
|
51
|
+
AND overlay.source_variant = 'draft_overlay'
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
)`;
|
|
39
56
|
|
|
40
57
|
export interface MediaUsageSourceInput {
|
|
41
58
|
sourceKey: string;
|
|
@@ -193,6 +210,24 @@ export interface FindMediaUsageOptions {
|
|
|
193
210
|
cursor?: string;
|
|
194
211
|
}
|
|
195
212
|
|
|
213
|
+
export interface MediaUsageCollectionIndexStatusScope {
|
|
214
|
+
collectionSlug: string;
|
|
215
|
+
status: string | null;
|
|
216
|
+
schemaVersion: number | null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface MediaUsageEntrySource {
|
|
220
|
+
source: MediaUsageSource;
|
|
221
|
+
occurrences: MediaUsageOccurrence[];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface MediaUsageEntryGroup {
|
|
225
|
+
collectionSlug: string;
|
|
226
|
+
contentId: string;
|
|
227
|
+
contentDeletedAt: string | null;
|
|
228
|
+
sources: MediaUsageEntrySource[];
|
|
229
|
+
}
|
|
230
|
+
|
|
196
231
|
interface MediaUsageSourceRow {
|
|
197
232
|
source_key: string;
|
|
198
233
|
source_type: string;
|
|
@@ -280,6 +315,11 @@ interface JoinedUsageRow {
|
|
|
280
315
|
occurrence_created_at: string;
|
|
281
316
|
}
|
|
282
317
|
|
|
318
|
+
interface GroupedUsageRow extends JoinedUsageRow {
|
|
319
|
+
entry_deleted_at: string | null;
|
|
320
|
+
has_more: number;
|
|
321
|
+
}
|
|
322
|
+
|
|
283
323
|
/** Persistence-only repository for the internal media usage projection tables. */
|
|
284
324
|
export class MediaUsageRepository {
|
|
285
325
|
constructor(private db: Kysely<Database>) {}
|
|
@@ -420,6 +460,169 @@ export class MediaUsageRepository {
|
|
|
420
460
|
};
|
|
421
461
|
}
|
|
422
462
|
|
|
463
|
+
async findActiveEntryCountsByMediaIds(mediaIds: readonly string[]): Promise<Map<string, number>> {
|
|
464
|
+
const uniqueMediaIds = [...new Set(mediaIds)];
|
|
465
|
+
const counts = new Map(uniqueMediaIds.map((mediaId) => [mediaId, 0]));
|
|
466
|
+
|
|
467
|
+
for (const mediaIdBatch of chunks(uniqueMediaIds, SQL_BATCH_SIZE)) {
|
|
468
|
+
const visibleEntries = this.currentContentMediaUsageBaseQuery()
|
|
469
|
+
.select([
|
|
470
|
+
"u.media_id as media_id",
|
|
471
|
+
"s.collection_slug as collection_slug",
|
|
472
|
+
"s.content_id as content_id",
|
|
473
|
+
])
|
|
474
|
+
.where("u.media_id", "in", mediaIdBatch)
|
|
475
|
+
.where((eb) =>
|
|
476
|
+
eb.not(
|
|
477
|
+
eb.exists(
|
|
478
|
+
eb
|
|
479
|
+
.selectFrom("_emdash_media_usage_sources as deleted_source")
|
|
480
|
+
.select("deleted_source.source_key")
|
|
481
|
+
.where("deleted_source.source_type", "=", "content")
|
|
482
|
+
.whereRef("deleted_source.collection_slug", "=", "s.collection_slug")
|
|
483
|
+
.whereRef("deleted_source.content_id", "=", "s.content_id")
|
|
484
|
+
.where("deleted_source.source_variant", "in", ["columns", "draft_overlay"])
|
|
485
|
+
.where("deleted_source.content_deleted_at", "is not", null),
|
|
486
|
+
),
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
.distinct()
|
|
490
|
+
.as("visible_entries");
|
|
491
|
+
|
|
492
|
+
const rows = await this.db
|
|
493
|
+
.selectFrom(visibleEntries)
|
|
494
|
+
.select("media_id")
|
|
495
|
+
.select((eb) => eb.fn.countAll<number>().as("usage_count"))
|
|
496
|
+
.groupBy("media_id")
|
|
497
|
+
.execute();
|
|
498
|
+
|
|
499
|
+
for (const row of rows) {
|
|
500
|
+
if (row.media_id !== null) counts.set(row.media_id, Number(row.usage_count));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return counts;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async findCollectionIndexStatusScopes(
|
|
508
|
+
identity: Pick<MediaUsageIndexStatusIdentity, "adapterId" | "scopeType">,
|
|
509
|
+
): Promise<MediaUsageCollectionIndexStatusScope[]> {
|
|
510
|
+
const rows = await this.db
|
|
511
|
+
.selectFrom("_emdash_collections as collection")
|
|
512
|
+
.leftJoin("_emdash_media_usage_index_status as status", (join) =>
|
|
513
|
+
join
|
|
514
|
+
.on("status.adapter_id", "=", identity.adapterId)
|
|
515
|
+
.on("status.scope_type", "=", identity.scopeType)
|
|
516
|
+
.onRef("status.scope_key", "=", "collection.slug"),
|
|
517
|
+
)
|
|
518
|
+
.select([
|
|
519
|
+
"collection.slug as collection_slug",
|
|
520
|
+
"status.status as status",
|
|
521
|
+
"status.schema_version as schema_version",
|
|
522
|
+
])
|
|
523
|
+
.orderBy("collection.slug", "asc")
|
|
524
|
+
.execute();
|
|
525
|
+
|
|
526
|
+
return rows.map((row) => ({
|
|
527
|
+
collectionSlug: row.collection_slug,
|
|
528
|
+
status: row.status,
|
|
529
|
+
schemaVersion: row.schema_version === null ? null : Number(row.schema_version),
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
async findCurrentEntryUsagePageByMediaId(
|
|
534
|
+
mediaId: string,
|
|
535
|
+
options: FindMediaUsageOptions = {},
|
|
536
|
+
): Promise<FindManyResult<MediaUsageEntryGroup>> {
|
|
537
|
+
const requestedLimit = Math.floor(options.limit ?? 50);
|
|
538
|
+
const limit = Number.isFinite(requestedLimit) ? Math.min(Math.max(1, requestedLimit), 100) : 50;
|
|
539
|
+
const cursor = options.cursor ? decodeCursor(options.cursor) : null;
|
|
540
|
+
if (cursor && (cursor.orderValue.length === 0 || cursor.id.length === 0)) {
|
|
541
|
+
throw new InvalidCursorError(options.cursor ?? "");
|
|
542
|
+
}
|
|
543
|
+
let matchedGroups = this.currentContentMediaUsageBaseQuery()
|
|
544
|
+
.select(["s.collection_slug as collection_slug", "s.content_id as content_id"])
|
|
545
|
+
.where("u.media_id", "=", mediaId)
|
|
546
|
+
.distinct();
|
|
547
|
+
if (cursor) {
|
|
548
|
+
matchedGroups = matchedGroups.where((eb) =>
|
|
549
|
+
eb.or([
|
|
550
|
+
eb("s.collection_slug", ">", cursor.orderValue),
|
|
551
|
+
eb.and([
|
|
552
|
+
eb("s.collection_slug", "=", cursor.orderValue),
|
|
553
|
+
eb("s.content_id", ">", cursor.id),
|
|
554
|
+
]),
|
|
555
|
+
]),
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
matchedGroups = matchedGroups
|
|
559
|
+
.orderBy("s.collection_slug", "asc")
|
|
560
|
+
.orderBy("s.content_id", "asc")
|
|
561
|
+
.limit(limit + 1);
|
|
562
|
+
|
|
563
|
+
const rows: GroupedUsageRow[] = await this.db
|
|
564
|
+
.with("matched_groups", () => matchedGroups)
|
|
565
|
+
.with("page_groups", (db) =>
|
|
566
|
+
db
|
|
567
|
+
.selectFrom("matched_groups")
|
|
568
|
+
.selectAll()
|
|
569
|
+
.orderBy("collection_slug", "asc")
|
|
570
|
+
.orderBy("content_id", "asc")
|
|
571
|
+
.limit(limit),
|
|
572
|
+
)
|
|
573
|
+
.with("entry_state", (db) =>
|
|
574
|
+
db
|
|
575
|
+
.selectFrom("page_groups as page")
|
|
576
|
+
.crossJoin("_emdash_media_usage_sources as state")
|
|
577
|
+
.select(["page.collection_slug", "page.content_id"])
|
|
578
|
+
.select((eb) =>
|
|
579
|
+
eb.fn.max<string | null>("state.content_deleted_at").as("entry_deleted_at"),
|
|
580
|
+
)
|
|
581
|
+
.whereRef("page.collection_slug", "=", "state.collection_slug")
|
|
582
|
+
.whereRef("page.content_id", "=", "state.content_id")
|
|
583
|
+
.where("state.source_type", "=", "content")
|
|
584
|
+
.where("state.source_variant", "in", ["columns", "draft_overlay"])
|
|
585
|
+
.groupBy(["page.collection_slug", "page.content_id"]),
|
|
586
|
+
)
|
|
587
|
+
.selectFrom("entry_state as page")
|
|
588
|
+
.crossJoin("_emdash_media_usage_sources as s")
|
|
589
|
+
.crossJoin("_emdash_media_usage as u")
|
|
590
|
+
.whereRef("page.collection_slug", "=", "s.collection_slug")
|
|
591
|
+
.whereRef("page.content_id", "=", "s.content_id")
|
|
592
|
+
.whereRef("s.source_key", "=", "u.source_key")
|
|
593
|
+
.whereRef("s.current_generation", "=", "u.generation")
|
|
594
|
+
.select(currentUsageSelect)
|
|
595
|
+
.select("page.entry_deleted_at")
|
|
596
|
+
.select(
|
|
597
|
+
sql<number>`CASE
|
|
598
|
+
WHEN (SELECT COUNT(*) FROM matched_groups) > ${limit} THEN 1
|
|
599
|
+
ELSE 0
|
|
600
|
+
END`.as("has_more"),
|
|
601
|
+
)
|
|
602
|
+
.where("u.media_id", "=", mediaId)
|
|
603
|
+
.where("s.source_type", "=", "content")
|
|
604
|
+
.where("s.collection_slug", "is not", null)
|
|
605
|
+
.where("s.content_id", "is not", null)
|
|
606
|
+
.where("s.source_variant", "in", ["columns", "draft_overlay"])
|
|
607
|
+
.where(CONTENT_SOURCE_ELIGIBILITY)
|
|
608
|
+
.orderBy("s.collection_slug", "asc")
|
|
609
|
+
.orderBy("s.content_id", "asc")
|
|
610
|
+
.orderBy("s.source_variant", "asc")
|
|
611
|
+
.orderBy("s.source_key", "asc")
|
|
612
|
+
.orderBy("u.field_path", "asc")
|
|
613
|
+
.orderBy("u.occurrence_index", "asc")
|
|
614
|
+
.orderBy("u.id", "asc")
|
|
615
|
+
.execute();
|
|
616
|
+
|
|
617
|
+
const items = groupUsageRows(rows);
|
|
618
|
+
const result: FindManyResult<MediaUsageEntryGroup> = { items };
|
|
619
|
+
if (Number(rows[0]?.has_more ?? 0) === 1 && items.length > 0) {
|
|
620
|
+
const last = items.at(-1)!;
|
|
621
|
+
result.nextCursor = encodeCursor(last.collectionSlug, last.contentId);
|
|
622
|
+
}
|
|
623
|
+
return result;
|
|
624
|
+
}
|
|
625
|
+
|
|
423
626
|
async findCurrentUsageByMediaId(mediaId: string): Promise<MediaUsageRecord[]> {
|
|
424
627
|
const rows = await this.db
|
|
425
628
|
.selectFrom("_emdash_media_usage_sources as s")
|
|
@@ -889,6 +1092,20 @@ export class MediaUsageRepository {
|
|
|
889
1092
|
.select(currentUsageSelect);
|
|
890
1093
|
}
|
|
891
1094
|
|
|
1095
|
+
private currentContentMediaUsageBaseQuery() {
|
|
1096
|
+
return this.db
|
|
1097
|
+
.selectFrom("_emdash_media_usage as u")
|
|
1098
|
+
.crossJoin("_emdash_media_usage_sources as s")
|
|
1099
|
+
.innerJoin("_emdash_collections as collection", "collection.slug", "s.collection_slug")
|
|
1100
|
+
.whereRef("s.source_key", "=", "u.source_key")
|
|
1101
|
+
.whereRef("s.current_generation", "=", "u.generation")
|
|
1102
|
+
.where("s.source_type", "=", "content")
|
|
1103
|
+
.where("s.collection_slug", "is not", null)
|
|
1104
|
+
.where("s.content_id", "is not", null)
|
|
1105
|
+
.where("s.source_variant", "in", ["columns", "draft_overlay"])
|
|
1106
|
+
.where(CONTENT_SOURCE_ELIGIBILITY);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
892
1109
|
private async deleteSourceKeys(sourceKeys: readonly string[]): Promise<number> {
|
|
893
1110
|
const uniqueSourceKeys = [...new Set(sourceKeys)];
|
|
894
1111
|
if (uniqueSourceKeys.length === 0) return 0;
|
|
@@ -1229,6 +1446,38 @@ const currentUsageSelect = [
|
|
|
1229
1446
|
"u.created_at as occurrence_created_at",
|
|
1230
1447
|
] as const;
|
|
1231
1448
|
|
|
1449
|
+
function groupUsageRows(rows: readonly GroupedUsageRow[]): MediaUsageEntryGroup[] {
|
|
1450
|
+
const groups: MediaUsageEntryGroup[] = [];
|
|
1451
|
+
|
|
1452
|
+
for (const row of rows) {
|
|
1453
|
+
if (row.collection_slug === null || row.content_id === null) continue;
|
|
1454
|
+
const record = rowToUsageRecord(row);
|
|
1455
|
+
let group = groups.at(-1);
|
|
1456
|
+
if (
|
|
1457
|
+
!group ||
|
|
1458
|
+
group.collectionSlug !== row.collection_slug ||
|
|
1459
|
+
group.contentId !== row.content_id
|
|
1460
|
+
) {
|
|
1461
|
+
group = {
|
|
1462
|
+
collectionSlug: row.collection_slug,
|
|
1463
|
+
contentId: row.content_id,
|
|
1464
|
+
contentDeletedAt: row.entry_deleted_at,
|
|
1465
|
+
sources: [],
|
|
1466
|
+
};
|
|
1467
|
+
groups.push(group);
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
let source = group.sources.at(-1);
|
|
1471
|
+
if (!source || source.source.sourceKey !== record.source.sourceKey) {
|
|
1472
|
+
source = { source: record.source, occurrences: [] };
|
|
1473
|
+
group.sources.push(source);
|
|
1474
|
+
}
|
|
1475
|
+
source.occurrences.push(record.occurrence);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
return groups;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1232
1481
|
function rowToSource(row: MediaUsageSourceRow): MediaUsageSource {
|
|
1233
1482
|
return {
|
|
1234
1483
|
sourceKey: row.source_key,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @see PLUGIN-SYSTEM.md § Plugin Storage > Full API Reference
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { Kysely } from "kysely";
|
|
10
|
+
import type { Kysely, RawBuilder } from "kysely";
|
|
11
11
|
import { sql } from "kysely";
|
|
12
12
|
|
|
13
13
|
import {
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
validateWhereClause,
|
|
16
16
|
validateOrderByClause,
|
|
17
17
|
getIndexedFields,
|
|
18
|
-
|
|
18
|
+
jsonOrderExtract,
|
|
19
19
|
} from "../../plugins/storage-query.js";
|
|
20
20
|
import type {
|
|
21
21
|
StorageCollection,
|
|
@@ -27,6 +27,26 @@ import { withTransaction } from "../transaction.js";
|
|
|
27
27
|
import type { Database } from "../types.js";
|
|
28
28
|
import { encodeCursor, decodeCursor } from "./types.js";
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Interleave a `?`-placeholder SQL string with its params into a single
|
|
32
|
+
* boolean raw expression. Used as a WHERE predicate directly — wrapping it
|
|
33
|
+
* in `(...) = 1` breaks on Postgres, which has a strict boolean type (#920).
|
|
34
|
+
*/
|
|
35
|
+
function rawWhereExpr(sqlText: string, params: unknown[]): RawBuilder<boolean> {
|
|
36
|
+
const parts: ReturnType<typeof sql>[] = [];
|
|
37
|
+
let paramIndex = 0;
|
|
38
|
+
const sqlParts = sqlText.split("?");
|
|
39
|
+
for (let i = 0; i < sqlParts.length; i++) {
|
|
40
|
+
if (i > 0) {
|
|
41
|
+
parts.push(sql`${params[paramIndex++]}`);
|
|
42
|
+
}
|
|
43
|
+
if (sqlParts[i]) {
|
|
44
|
+
parts.push(sql.raw(sqlParts[i]));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return sql<boolean>`(${sql.join(parts, sql.raw(""))})`;
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
/**
|
|
31
51
|
* Plugin Storage Repository
|
|
32
52
|
*
|
|
@@ -211,19 +231,7 @@ export class PluginStorageRepository<T = unknown> implements StorageCollection<T
|
|
|
211
231
|
// Add JSON extraction WHERE conditions
|
|
212
232
|
const whereResult = buildWhereClause(this.db, where);
|
|
213
233
|
if (whereResult.sql) {
|
|
214
|
-
|
|
215
|
-
const whereSqlParts: ReturnType<typeof sql>[] = [];
|
|
216
|
-
let paramIndex = 0;
|
|
217
|
-
const sqlParts = whereResult.sql.split("?");
|
|
218
|
-
for (let i = 0; i < sqlParts.length; i++) {
|
|
219
|
-
if (i > 0) {
|
|
220
|
-
whereSqlParts.push(sql`${whereResult.params[paramIndex++]}`);
|
|
221
|
-
}
|
|
222
|
-
if (sqlParts[i]) {
|
|
223
|
-
whereSqlParts.push(sql.raw(sqlParts[i]));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
query = query.where(({ eb }) => eb(sql.join(whereSqlParts, sql.raw("")), "=", sql.raw("1")));
|
|
234
|
+
query = query.where(rawWhereExpr(whereResult.sql, whereResult.params));
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
// Handle cursor-based pagination — throws on invalid cursor.
|
|
@@ -237,7 +245,9 @@ export class PluginStorageRepository<T = unknown> implements StorageCollection<T
|
|
|
237
245
|
// Build ORDER BY using sql template
|
|
238
246
|
if (Object.keys(orderBy).length > 0) {
|
|
239
247
|
for (const [field, direction] of Object.entries(orderBy)) {
|
|
240
|
-
|
|
248
|
+
// Order over the jsonb-native value on Postgres so numeric fields sort
|
|
249
|
+
// numerically, not lexically. See pluginDataOrderExpr.
|
|
250
|
+
const extract = jsonOrderExtract(this.db, field);
|
|
241
251
|
const orderExpr =
|
|
242
252
|
direction === "desc" ? sql`${sql.raw(extract)} desc` : sql`${sql.raw(extract)} asc`;
|
|
243
253
|
query = query.orderBy(orderExpr);
|
|
@@ -289,26 +299,13 @@ export class PluginStorageRepository<T = unknown> implements StorageCollection<T
|
|
|
289
299
|
if (where && Object.keys(where).length > 0) {
|
|
290
300
|
const whereResult = buildWhereClause(this.db, where);
|
|
291
301
|
if (whereResult.sql) {
|
|
292
|
-
|
|
293
|
-
const whereSqlParts: ReturnType<typeof sql>[] = [];
|
|
294
|
-
let paramIndex = 0;
|
|
295
|
-
const sqlParts = whereResult.sql.split("?");
|
|
296
|
-
for (let i = 0; i < sqlParts.length; i++) {
|
|
297
|
-
if (i > 0) {
|
|
298
|
-
whereSqlParts.push(sql`${whereResult.params[paramIndex++]}`);
|
|
299
|
-
}
|
|
300
|
-
if (sqlParts[i]) {
|
|
301
|
-
whereSqlParts.push(sql.raw(sqlParts[i]));
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
query = query.where(({ eb }) =>
|
|
305
|
-
eb(sql.join(whereSqlParts, sql.raw("")), "=", sql.raw("1")),
|
|
306
|
-
);
|
|
302
|
+
query = query.where(rawWhereExpr(whereResult.sql, whereResult.params));
|
|
307
303
|
}
|
|
308
304
|
}
|
|
309
305
|
|
|
310
306
|
const result = await query.executeTakeFirst();
|
|
311
|
-
|
|
307
|
+
// Number() because the pg driver returns COUNT(*) (bigint) as a string.
|
|
308
|
+
return Number(result?.count ?? 0);
|
|
312
309
|
}
|
|
313
310
|
}
|
|
314
311
|
|
|
@@ -347,7 +347,11 @@ export class RedirectRepository {
|
|
|
347
347
|
/**
|
|
348
348
|
* Create an auto-redirect when a content slug changes.
|
|
349
349
|
* Uses the collection's URL pattern to compute old/new URLs.
|
|
350
|
-
* Collapses existing redirect chains pointing to the old URL
|
|
350
|
+
* Collapses existing redirect chains pointing to the old URL and
|
|
351
|
+
* removes redirects that would shadow the now-live new URL, so a
|
|
352
|
+
* rename that is later reverted cannot form a loop (#1986).
|
|
353
|
+
*
|
|
354
|
+
* Returns null when old and new URL are identical (nothing to redirect).
|
|
351
355
|
*/
|
|
352
356
|
async createAutoRedirect(
|
|
353
357
|
collection: string,
|
|
@@ -355,7 +359,7 @@ export class RedirectRepository {
|
|
|
355
359
|
newSlug: string,
|
|
356
360
|
contentId: string,
|
|
357
361
|
urlPattern: string | null,
|
|
358
|
-
): Promise<Redirect> {
|
|
362
|
+
): Promise<Redirect | null> {
|
|
359
363
|
const oldUrl = urlPattern
|
|
360
364
|
? urlPattern.replace("{slug}", oldSlug).replace("{id}", contentId)
|
|
361
365
|
: `/${collection}/${oldSlug}`;
|
|
@@ -363,9 +367,17 @@ export class RedirectRepository {
|
|
|
363
367
|
? urlPattern.replace("{slug}", newSlug).replace("{id}", contentId)
|
|
364
368
|
: `/${collection}/${newSlug}`;
|
|
365
369
|
|
|
370
|
+
// A redirect from a URL to itself would make the page unreachable
|
|
371
|
+
if (oldUrl === newUrl) return null;
|
|
372
|
+
|
|
366
373
|
// Collapse chains: update any existing redirects pointing to the old URL
|
|
367
374
|
await this.collapseChains(oldUrl, newUrl);
|
|
368
375
|
|
|
376
|
+
// The new URL serves live content again — any redirect from it would
|
|
377
|
+
// shadow the page. This also removes the self-redirect that chain
|
|
378
|
+
// collapsing produces when a rename A → B is reverted (A → A).
|
|
379
|
+
await this.db.deleteFrom("_emdash_redirects").where("source", "=", newUrl).execute();
|
|
380
|
+
|
|
369
381
|
// Check if a redirect from this source already exists
|
|
370
382
|
const existing = await this.findBySource(oldUrl);
|
|
371
383
|
if (existing) {
|