emdash 0.29.0 → 0.31.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-EibxGP-V.mjs} +260 -160
- package/dist/api-EibxGP-V.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-fGHCAwWN.mjs} +42 -44
- package/dist/apply-fGHCAwWN.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 +410 -123
- 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 +16 -15
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -22
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +20 -18
- 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 +41 -40
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +41 -40
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +46 -40
- 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 +40 -39
- 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 +43 -40
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +46 -40
- 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 +40 -39
- 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 +46 -41
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +40 -39
- 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 +44 -41
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +40 -39
- 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 +45 -42
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +41 -40
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +40 -39
- 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 +40 -39
- 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 +14 -13
- 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 +19 -18
- 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 +13 -13
- 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 +24 -23
- 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 +29 -16
- 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 +40 -39
- 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 +40 -39
- 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 +40 -39
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +40 -39
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +40 -39
- 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 +40 -39
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +40 -39
- 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 +15 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +15 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +15 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +15 -14
- 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 +11 -11
- 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-6WPZa1xZ.mjs} +7 -4
- package/dist/authorize-6WPZa1xZ.mjs.map +1 -0
- package/dist/backup-Qr9PaGUo.mjs +241 -0
- package/dist/backup-Qr9PaGUo.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-BTOxUlFF.mjs} +6 -6
- package/dist/{byline-BWb5H-65.mjs.map → byline-BTOxUlFF.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-CHojDMpj.mjs → bylines-FyZu6TbJ.mjs} +7 -7
- package/dist/{bylines-CHojDMpj.mjs.map → bylines-FyZu6TbJ.mjs.map} +1 -1
- package/dist/{bylines-BGuKFaBy.mjs → bylines-oVN0iPwX.mjs} +12 -8
- package/dist/bylines-oVN0iPwX.mjs.map +1 -0
- package/dist/{cache-BeR7RfN8.mjs → cache-DDwy3JDW.mjs} +2 -2
- package/dist/{cache-BeR7RfN8.mjs.map → cache-DDwy3JDW.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-Bq-5DPrD.mjs} +2 -2
- package/dist/{chunks-BU5_nrAC.mjs.map → chunks-Bq-5DPrD.mjs.map} +1 -1
- package/dist/cli/index.mjs +139 -32
- 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-B9cUud8H.mjs} +2 -2
- package/dist/{comment-SWh31kS0.mjs.map → comment-B9cUud8H.mjs.map} +1 -1
- package/dist/{comment-reaction-DgcpziXI.mjs → comment-reaction-VUXO981F.mjs} +2 -2
- package/dist/{comment-reaction-DgcpziXI.mjs.map → comment-reaction-VUXO981F.mjs.map} +1 -1
- package/dist/{comments-kZYGppMS.mjs → comments-PXj1E9Si.mjs} +3 -3
- package/dist/{comments-kZYGppMS.mjs.map → comments-PXj1E9Si.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/{config-CVssduLe.mjs → config-B6b_BobR.mjs} +6 -2
- package/dist/config-B6b_BobR.mjs.map +1 -0
- package/dist/{content-BO61Sx4j.mjs → content-BC43pICM.mjs} +53 -19
- package/dist/content-BC43pICM.mjs.map +1 -0
- package/dist/{content-refresh-BkkApzeS.mjs → content-refresh-CPMSauD3.mjs} +96 -4
- package/dist/content-refresh-CPMSauD3.mjs.map +1 -0
- package/dist/{context-DtSFYFuS.mjs → context-DOurRIrb.mjs} +97 -74
- package/dist/context-DOurRIrb.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-CBm4zhc3.mjs} +4 -4
- package/dist/{dashboard-xo_gPs_D.mjs.map → dashboard-CBm4zhc3.mjs.map} +1 -1
- package/dist/database/pg-migration-lock.d.mts.map +1 -1
- package/dist/database/pg-migration-lock.mjs +1 -4
- package/dist/database/pg-migration-lock.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-BtOwo2us.mjs} +60 -14
- package/dist/dialect-helpers-BtOwo2us.mjs.map +1 -0
- 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-DJ98TRbQ.mjs +90 -0
- package/dist/error-DJ98TRbQ.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-KfNJ_qLQ.mjs} +2 -2
- package/dist/{field-defs-cache-BVrNCgSj.mjs.map → field-defs-cache-KfNJ_qLQ.mjs.map} +1 -1
- package/dist/{fts-manager-BD9s77qh.mjs → fts-manager-hyCU9OOp.mjs} +3 -3
- package/dist/{fts-manager-BD9s77qh.mjs.map → fts-manager-hyCU9OOp.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-CbYeCzl9.mjs} +7 -7
- package/dist/{hreflang-pAWUiPd_.mjs.map → hreflang-CbYeCzl9.mjs.map} +1 -1
- package/dist/{import-2jHtLzsO.mjs → import-oDYCgNYQ.mjs} +4 -4
- package/dist/{import-2jHtLzsO.mjs.map → import-oDYCgNYQ.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-BcEH_FfS.d.mts} +812 -16
- package/dist/index-BcEH_FfS.d.mts.map +1 -0
- package/dist/index.d.mts +18 -19
- package/dist/index.mjs +61 -60
- package/dist/{load-DgoWMdRX.mjs → load-Dg5gtWma.mjs} +2 -2
- package/dist/{load-DgoWMdRX.mjs.map → load-Dg5gtWma.mjs.map} +1 -1
- package/dist/{loader-Rb8QlGZp.mjs → loader-D4rigvjR.mjs} +170 -6
- package/dist/loader-D4rigvjR.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-BJ6SRY3g.mjs +247 -0
- package/dist/media-BJ6SRY3g.mjs.map +1 -0
- 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-D2ZFowpn.mjs → media-its1WLYv.mjs} +2 -2
- package/dist/{media-D2ZFowpn.mjs.map → media-its1WLYv.mjs.map} +1 -1
- package/dist/media-upload-DNu3QySc.mjs +145 -0
- package/dist/media-upload-DNu3QySc.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-DPQ3K4xB.mjs} +138 -5
- package/dist/{media-usage-B__v9NMm.mjs.map → media-usage-DPQ3K4xB.mjs.map} +1 -1
- package/dist/{menus-BpfevlJD.mjs → menus-BMGzWyWH.mjs} +15 -8
- package/dist/menus-BMGzWyWH.mjs.map +1 -0
- package/dist/{menus-BtvH7Z7t.mjs → menus-CPf_SW7u.mjs} +234 -13
- package/dist/menus-CPf_SW7u.mjs.map +1 -0
- 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-53zyxlpv.mjs} +4 -12
- package/dist/{parse-GLksnn-B.mjs.map → parse-53zyxlpv.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-BbJQ-dGg.mjs} +15 -15
- package/dist/{query-ZzvXyxWq.mjs.map → query-BbJQ-dGg.mjs.map} +1 -1
- package/dist/{query-BxT95opY.mjs → query-DdFGHzQF.mjs} +3 -3
- package/dist/{query-BxT95opY.mjs.map → query-DdFGHzQF.mjs.map} +1 -1
- package/dist/{rate-limit-Cg4Rvc_-.mjs → rate-limit-D3IEiUi2.mjs} +2 -2
- package/dist/{rate-limit-Cg4Rvc_-.mjs.map → rate-limit-D3IEiUi2.mjs.map} +1 -1
- package/dist/{redirect-Ch3E98qZ.mjs → redirect-BoUac4NT.mjs} +10 -4
- package/dist/redirect-BoUac4NT.mjs.map +1 -0
- 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/{redirects-CXmVGRNZ.mjs → redirects-ChbpqKiS.mjs} +4 -4
- package/dist/{redirects-CXmVGRNZ.mjs.map → redirects-ChbpqKiS.mjs.map} +1 -1
- package/dist/{redirects-CeD7K7EX.mjs → redirects-D457qwt0.mjs} +10 -181
- package/dist/redirects-D457qwt0.mjs.map +1 -0
- package/dist/{registry-CyIXPi4E.mjs → registry-y21kjhfG.mjs} +97 -8
- package/dist/registry-y21kjhfG.mjs.map +1 -0
- package/dist/{relation-Ba68Tm4Z.mjs → relation-Du0r04E0.mjs} +3 -3
- package/dist/{relation-Ba68Tm4Z.mjs.map → relation-Du0r04E0.mjs.map} +1 -1
- package/dist/{relations-CbBpoOys.d.mts → relations-BKybBoOX.d.mts} +315 -9
- package/dist/relations-BKybBoOX.d.mts.map +1 -0
- package/dist/{relations-BmBmX4Eb.mjs → relations-CZMpBqEd.mjs} +3 -3
- package/dist/{relations-BmBmX4Eb.mjs.map → relations-CZMpBqEd.mjs.map} +1 -1
- package/dist/{relations-C8hVyEy0.mjs → relations-DtX1UMBH.mjs} +13 -7
- package/dist/relations-DtX1UMBH.mjs.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/{resolve-Cd9dzclN.mjs → resolve-DFr4kq72.mjs} +2 -2
- package/dist/{resolve-Cd9dzclN.mjs.map → resolve-DFr4kq72.mjs.map} +1 -1
- package/dist/{runner-jt65bF7F.mjs → runner-BdeLEgad.mjs} +334 -200
- package/dist/runner-BdeLEgad.mjs.map +1 -0
- 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/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-BH8P8vaC.mjs} +3 -3
- package/dist/{schema-DwjufZ1S.mjs.map → schema-BH8P8vaC.mjs.map} +1 -1
- package/dist/scopes-DTIkIaGA.mjs +27 -0
- package/dist/scopes-DTIkIaGA.mjs.map +1 -0
- package/dist/{search-Cl875CVE.mjs → search-D-Yhpmvs.mjs} +8 -7
- package/dist/search-D-Yhpmvs.mjs.map +1 -0
- package/dist/{secrets-CO_bEmII.mjs → secrets-CQ-69kF9.mjs} +25 -19
- package/dist/secrets-CQ-69kF9.mjs.map +1 -0
- package/dist/{sections-DTKzgoiS.mjs → sections-CzVBAKjw.mjs} +3 -3
- package/dist/{sections-DTKzgoiS.mjs.map → sections-CzVBAKjw.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 +17 -17
- package/dist/seo/index.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/{seo-BLm6SXzS.mjs → seo-kJzVAmmu.mjs} +2 -2
- package/dist/{seo-BLm6SXzS.mjs.map → seo-kJzVAmmu.mjs.map} +1 -1
- package/dist/{service-D6zDmKXy.mjs → service-CQnc276a.mjs} +3 -3
- package/dist/{service-D6zDmKXy.mjs.map → service-CQnc276a.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-BuQYvLfy.mjs → settings-C2PaBS49.mjs} +4 -4
- package/dist/{settings-BuQYvLfy.mjs.map → settings-C2PaBS49.mjs.map} +1 -1
- package/dist/{settings-CmS3TwXf.mjs → settings-Dtc0DU31.mjs} +3 -3
- package/dist/{settings-CmS3TwXf.mjs.map → settings-Dtc0DU31.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-pUkuD6nj.mjs → taxonomies-HI9fnTdp.mjs} +8 -8
- package/dist/{taxonomies-pUkuD6nj.mjs.map → taxonomies-HI9fnTdp.mjs.map} +1 -1
- package/dist/{taxonomies-ClS4RKaZ.mjs → taxonomies-rMeBzOjX.mjs} +26 -17
- package/dist/taxonomies-rMeBzOjX.mjs.map +1 -0
- package/dist/{taxonomy-BkxbUMSw.mjs → taxonomy-0mCI25HN.mjs} +51 -13
- package/dist/taxonomy-0mCI25HN.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-CrRUFdej.mjs} +3 -3
- package/dist/{types-Ch8pFMEm.mjs.map → types-CrRUFdej.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-aTXqmXBz.mjs} +3 -3
- package/dist/{user-DTxX_Fha.mjs.map → user-aTXqmXBz.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-C3CpWlNt.mjs → validate-CDT1jl6_.mjs} +11 -6
- package/dist/validate-CDT1jl6_.mjs.map +1 -0
- 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/{validation-DM2K_NJC.mjs → validation-DlD0E35W.mjs} +10 -10
- package/dist/{validation-DM2K_NJC.mjs.map → validation-DlD0E35W.mjs.map} +1 -1
- package/dist/version-Ci6bw6YK.mjs +7 -0
- package/dist/{version-BlIJvNAZ.mjs.map → version-Ci6bw6YK.mjs.map} +1 -1
- package/dist/{widgets-B_X6_UXJ.mjs → widgets-5fipNkMT.mjs} +3 -3
- package/dist/{widgets-B_X6_UXJ.mjs.map → widgets-5fipNkMT.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-BmUnBNgz.mjs} +4 -4
- package/dist/{wxr-taxonomies-oNJB2S81.mjs.map → wxr-taxonomies-BmUnBNgz.mjs.map} +1 -1
- package/dist/{zod-generator-CrfV79De.mjs → zod-generator-CwkHWz4f.mjs} +2 -2
- package/dist/{zod-generator-CrfV79De.mjs.map → zod-generator-CwkHWz4f.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/bylines.ts +5 -4
- package/src/api/handlers/content.ts +61 -9
- 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/menus.ts +11 -6
- 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/relations.ts +7 -2
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/handlers/taxonomies.ts +22 -14
- 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/bylines.ts +4 -4
- package/src/api/schemas/common.ts +13 -8
- package/src/api/schemas/media-usage.ts +72 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/api/schemas/menus.ts +2 -1
- package/src/api/schemas/relations.ts +3 -1
- package/src/api/schemas/taxonomies.ts +4 -2
- 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/bylines/index.ts +5 -8
- 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 +43 -15
- 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/Gallery.astro +141 -26
- package/src/components/InlinePortableTextEditor.tsx +56 -35
- package/src/components/marks/Link.astro +5 -1
- package/src/config/secrets.ts +25 -19
- package/src/content/converters/gallery.ts +61 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +19 -0
- package/src/content/converters/prosemirror-to-portable-text.ts +18 -0
- package/src/content/converters/types.ts +36 -0
- package/src/database/dialect-helpers.ts +80 -7
- 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/pg-migration-lock.ts +1 -4
- 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 +365 -83
- package/src/i18n/config.ts +8 -0
- package/src/i18n/repair-locale-casing.ts +51 -0
- 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/search/query.ts +3 -2
- package/src/seed/apply.ts +37 -36
- package/src/seed/validate.ts +15 -4
- 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/bylines-BGuKFaBy.mjs.map +0 -1
- package/dist/config-CVssduLe.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/dialect-helpers-Cue7QQOR.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-BpfevlJD.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-C8hVyEy0.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/search-Cl875CVE.mjs.map +0 -1
- package/dist/secrets-CO_bEmII.mjs.map +0 -1
- package/dist/taxonomies-ClS4RKaZ.mjs.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/validate-C3CpWlNt.mjs.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
package/src/i18n/config.ts
CHANGED
|
@@ -30,6 +30,14 @@ export function getI18nConfig(): I18nConfig | null {
|
|
|
30
30
|
return _config ?? null;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/** Match a locale to the exact casing used by the site configuration. */
|
|
34
|
+
export function resolveConfiguredLocale(locale: string): string {
|
|
35
|
+
return (
|
|
36
|
+
_config?.locales.find((configured) => configured.toLowerCase() === locale.toLowerCase()) ??
|
|
37
|
+
locale
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
/**
|
|
34
42
|
* Check if i18n is enabled.
|
|
35
43
|
* Returns true when multiple locales are configured.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
|
|
4
|
+
import { listTablesLike } from "../database/dialect-helpers.js";
|
|
5
|
+
import type { Database } from "../database/types.js";
|
|
6
|
+
|
|
7
|
+
/** Rewrite stored locales to the exact casing used by the site configuration. */
|
|
8
|
+
export async function repairLocaleCasing(
|
|
9
|
+
db: Kysely<Database>,
|
|
10
|
+
configuredLocales: readonly string[],
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
const tableNames = await listTablesLike(db, "ec_%");
|
|
13
|
+
|
|
14
|
+
for (const tableName of tableNames) {
|
|
15
|
+
const table = sql.ref(tableName);
|
|
16
|
+
const slug = tableName.slice("ec_".length);
|
|
17
|
+
for (const locale of configuredLocales) {
|
|
18
|
+
await sql`
|
|
19
|
+
UPDATE ${table} AS target
|
|
20
|
+
SET locale = ${locale}
|
|
21
|
+
WHERE lower(target.locale) = lower(${locale})
|
|
22
|
+
AND target.locale != ${locale}
|
|
23
|
+
AND NOT EXISTS (
|
|
24
|
+
SELECT 1
|
|
25
|
+
FROM ${table} AS existing
|
|
26
|
+
WHERE existing.slug = target.slug AND existing.locale = ${locale}
|
|
27
|
+
)
|
|
28
|
+
AND target.id = (
|
|
29
|
+
SELECT MIN(candidate.id)
|
|
30
|
+
FROM ${table} AS candidate
|
|
31
|
+
WHERE candidate.slug = target.slug
|
|
32
|
+
AND lower(candidate.locale) = lower(${locale})
|
|
33
|
+
AND candidate.locale != ${locale}
|
|
34
|
+
)
|
|
35
|
+
`.execute(db);
|
|
36
|
+
|
|
37
|
+
await sql`
|
|
38
|
+
UPDATE content_taxonomies AS pivot
|
|
39
|
+
SET locale = ${locale}
|
|
40
|
+
WHERE pivot.collection = ${slug}
|
|
41
|
+
AND lower(pivot.locale) = lower(${locale})
|
|
42
|
+
AND pivot.locale != ${locale}
|
|
43
|
+
AND EXISTS (
|
|
44
|
+
SELECT 1
|
|
45
|
+
FROM ${table} AS content
|
|
46
|
+
WHERE content.id = pivot.entry_id AND content.locale = ${locale}
|
|
47
|
+
)
|
|
48
|
+
`.execute(db);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/loader.ts
CHANGED
|
@@ -646,6 +646,263 @@ function buildFieldConditions(
|
|
|
646
646
|
return conditions;
|
|
647
647
|
}
|
|
648
648
|
|
|
649
|
+
/**
|
|
650
|
+
* Resolve a taxonomy filter (`name` + one or more `slug`s, optionally scoped to
|
|
651
|
+
* `locale`) to the set of `translation_group`s the pivot stores in
|
|
652
|
+
* `content_taxonomies.taxonomy_id`. Exact terms only — no subtree expansion.
|
|
653
|
+
*
|
|
654
|
+
* Mirrors the meaning of the old EXISTS join (`t.name = ? AND t.slug IN (?)
|
|
655
|
+
* [AND t.locale = ?]`): a pivot row matches when its group has a term with that
|
|
656
|
+
* name/slug in the active locale. Resolving to explicit values (rather than an
|
|
657
|
+
* `IN (subquery)`) keeps the single-term case a plain equality on the pivot
|
|
658
|
+
* index, which is what gives the clean early-`LIMIT` seek.
|
|
659
|
+
*/
|
|
660
|
+
async function resolveTermGroups(
|
|
661
|
+
db: Kysely<Database>,
|
|
662
|
+
name: string,
|
|
663
|
+
slugs: string[],
|
|
664
|
+
locale: string | undefined,
|
|
665
|
+
): Promise<string[]> {
|
|
666
|
+
let query = db
|
|
667
|
+
.selectFrom("taxonomies")
|
|
668
|
+
.select("translation_group")
|
|
669
|
+
.distinct()
|
|
670
|
+
.where("name", "=", name)
|
|
671
|
+
.where("slug", "in", slugs);
|
|
672
|
+
if (locale) query = query.where("locale", "=", locale);
|
|
673
|
+
const rows = await query.execute();
|
|
674
|
+
const groups = new Set<string>();
|
|
675
|
+
for (const row of rows) {
|
|
676
|
+
if (row.translation_group) groups.add(row.translation_group);
|
|
677
|
+
}
|
|
678
|
+
return [...groups];
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** Equality (single) or `IN` (multiple) condition on a pivot group column. */
|
|
682
|
+
function pivotGroupCondition(ref: string, groups: string[]): ReturnType<typeof sql> {
|
|
683
|
+
if (groups.length === 1) return sql`${sql.ref(ref)} = ${groups[0]}`;
|
|
684
|
+
return sql`${sql.ref(ref)} IN (${sql.join(groups.map((g) => sql`${g}`))})`;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/** LIMIT/OFFSET fragment matching the loader's single-table variant. */
|
|
688
|
+
function buildPivotLimitOffset(
|
|
689
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any Kysely instance
|
|
690
|
+
db: Kysely<any>,
|
|
691
|
+
fetchLimit: number | undefined,
|
|
692
|
+
offset: number | undefined,
|
|
693
|
+
): ReturnType<typeof sql> {
|
|
694
|
+
if (fetchLimit != null && offset != null) return sql`LIMIT ${fetchLimit} OFFSET ${offset}`;
|
|
695
|
+
if (fetchLimit != null) return sql`LIMIT ${fetchLimit}`;
|
|
696
|
+
if (offset != null) {
|
|
697
|
+
return isPostgres(db) ? sql`OFFSET ${offset}` : sql`LIMIT -1 OFFSET ${offset}`;
|
|
698
|
+
}
|
|
699
|
+
return sql``;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Options for {@link buildTaxonomyPivotQuery}.
|
|
704
|
+
*
|
|
705
|
+
* Parameterized on the `deletedIsNull` predicate and `status` condition so the
|
|
706
|
+
* same builder serves the public live path (`deleted_at IS NULL` + published/
|
|
707
|
+
* scheduled) and, without any schema change, an admin trash (`deleted_at IS NOT
|
|
708
|
+
* NULL`) or all-statuses shape. Admin wiring is out of scope today; the
|
|
709
|
+
* parameters exist so `ContentRepository` can adopt this if it gains taxonomy
|
|
710
|
+
* filtering.
|
|
711
|
+
*/
|
|
712
|
+
export interface TaxonomyPivotQueryOptions {
|
|
713
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any Kysely instance
|
|
714
|
+
db: Kysely<any>;
|
|
715
|
+
/** Collection slug (pivot `collection` value). */
|
|
716
|
+
collection: string;
|
|
717
|
+
/** Content table name (`ec_<collection>`). */
|
|
718
|
+
tableName: string;
|
|
719
|
+
/**
|
|
720
|
+
* Resolved translation_group sets, one per taxonomy filter. The first drives
|
|
721
|
+
* the pivot seek; each additional set becomes a residual `EXISTS` (AND across
|
|
722
|
+
* taxonomies). Multiple groups within a set are OR'd (dedup via GROUP BY).
|
|
723
|
+
*/
|
|
724
|
+
groupSets: string[][];
|
|
725
|
+
orderBy: OrderBySpec | undefined;
|
|
726
|
+
cursor: string | undefined;
|
|
727
|
+
locale: string | undefined;
|
|
728
|
+
/**
|
|
729
|
+
* Status shape. A concrete value (`published`/`draft`/…) applies the same
|
|
730
|
+
* condition `buildStatusCondition` produces (public: published-or-scheduled).
|
|
731
|
+
* `undefined` drops the status filter entirely — the admin all-statuses shape.
|
|
732
|
+
*/
|
|
733
|
+
status: string | undefined;
|
|
734
|
+
/** `true` → `deleted_at IS NULL` (live); `false` → `IS NOT NULL` (trash). */
|
|
735
|
+
deletedIsNull: boolean;
|
|
736
|
+
/** Byline translation_groups for an AND'd byline filter, or `null`. */
|
|
737
|
+
bylineGroups: string[] | null;
|
|
738
|
+
fetchLimit: number | undefined;
|
|
739
|
+
offset: number | undefined;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Build the pivot-driven taxonomy listing query (#1834).
|
|
744
|
+
*
|
|
745
|
+
* Drives from a pivot-only CTE (`picked`) that carries the sort column, seeks
|
|
746
|
+
* the term on a `(taxonomy_id, collection, deleted_at, [locale,] <sort> DESC,
|
|
747
|
+
* entry_id DESC)` index, and lets `LIMIT` short-circuit; then joins `ec_*` by primary
|
|
748
|
+
* key to hydrate the page **and re-checks the real filter predicates on the
|
|
749
|
+
* joined row** — the pivot columns are advisory (non-atomic re-stamp on D1), so
|
|
750
|
+
* `ec_*` is authoritative for membership. Ordering stays pivot-driven to keep
|
|
751
|
+
* the early-`LIMIT`.
|
|
752
|
+
*
|
|
753
|
+
* Two shapes:
|
|
754
|
+
* - **Indexed sort** (`published_at`/`created_at`, single sort field): the
|
|
755
|
+
* pivot index is covering for `(entry_id, sortval)`, so `LIMIT` lives in
|
|
756
|
+
* `picked` and short-circuits.
|
|
757
|
+
* - **Temp-sort** (`updated_at` or any other field, or multi-field sort): no
|
|
758
|
+
* pivot sort index applies, so `picked` collects the tagged candidate set and
|
|
759
|
+
* the outer query sorts the joined rows. Bounded to tagged rows — no
|
|
760
|
+
* `ec_*` full scan — but no early-`LIMIT`.
|
|
761
|
+
*/
|
|
762
|
+
export function buildTaxonomyPivotQuery(
|
|
763
|
+
opts: TaxonomyPivotQueryOptions,
|
|
764
|
+
): ReturnType<typeof sql<Record<string, unknown>>> {
|
|
765
|
+
const {
|
|
766
|
+
db,
|
|
767
|
+
collection,
|
|
768
|
+
tableName,
|
|
769
|
+
groupSets,
|
|
770
|
+
orderBy,
|
|
771
|
+
cursor,
|
|
772
|
+
locale,
|
|
773
|
+
status,
|
|
774
|
+
deletedIsNull,
|
|
775
|
+
bylineGroups,
|
|
776
|
+
fetchLimit,
|
|
777
|
+
offset,
|
|
778
|
+
} = opts;
|
|
779
|
+
|
|
780
|
+
const primary = getPrimarySort(orderBy);
|
|
781
|
+
const validSortKeys = orderBy
|
|
782
|
+
? Object.keys(orderBy).filter((k) => FIELD_NAME_PATTERN.test(k))
|
|
783
|
+
: [];
|
|
784
|
+
const singleSort = validSortKeys.length <= 1;
|
|
785
|
+
const isIndexedSort =
|
|
786
|
+
singleSort && (primary.field === "published_at" || primary.field === "created_at");
|
|
787
|
+
const dir = primary.direction === "asc" ? sql`ASC` : sql`DESC`;
|
|
788
|
+
const cmp = primary.direction === "asc" ? sql.raw(">") : sql.raw("<");
|
|
789
|
+
|
|
790
|
+
const firstGroups = groupSets[0] ?? [];
|
|
791
|
+
const restGroups = groupSets.slice(1);
|
|
792
|
+
const multiGroup = firstGroups.length > 1;
|
|
793
|
+
|
|
794
|
+
// Pivot-local narrowing predicates (advisory — re-checked on `ec_*` below).
|
|
795
|
+
// `status === undefined` means an all-statuses shape (admin), so the status
|
|
796
|
+
// condition is dropped entirely.
|
|
797
|
+
const deletedCt = deletedIsNull ? sql`ct.deleted_at IS NULL` : sql`ct.deleted_at IS NOT NULL`;
|
|
798
|
+
const statusCt =
|
|
799
|
+
status !== undefined ? sql`AND ${buildStatusCondition(db, status, "ct")}` : sql``;
|
|
800
|
+
const localeCt = locale ? sql`AND ct.locale = ${locale}` : sql``;
|
|
801
|
+
|
|
802
|
+
// Multi-term AND: one residual pivot-PK EXISTS per additional taxonomy.
|
|
803
|
+
const residual =
|
|
804
|
+
restGroups.length > 0
|
|
805
|
+
? sql`${sql.join(
|
|
806
|
+
restGroups.map(
|
|
807
|
+
(g) => sql`AND EXISTS (
|
|
808
|
+
SELECT 1 FROM content_taxonomies ct2
|
|
809
|
+
WHERE ct2.collection = ${collection}
|
|
810
|
+
AND ct2.entry_id = ct.entry_id
|
|
811
|
+
AND ${pivotGroupCondition("ct2.taxonomy_id", g)}
|
|
812
|
+
)`,
|
|
813
|
+
),
|
|
814
|
+
sql` `,
|
|
815
|
+
)}`
|
|
816
|
+
: sql``;
|
|
817
|
+
|
|
818
|
+
// Byline filter keeps its EXISTS, correlated on `ct.entry_id`.
|
|
819
|
+
const bylineCt = bylineGroups
|
|
820
|
+
? sql`AND EXISTS (
|
|
821
|
+
SELECT 1 FROM _emdash_content_bylines cb
|
|
822
|
+
WHERE cb.collection_slug = ${collection}
|
|
823
|
+
AND cb.content_id = ct.entry_id
|
|
824
|
+
AND cb.byline_id IN (${sql.join(bylineGroups.map((g) => sql`${g}`))})
|
|
825
|
+
)`
|
|
826
|
+
: sql``;
|
|
827
|
+
|
|
828
|
+
const firstGroupCond = pivotGroupCondition("ct.taxonomy_id", firstGroups);
|
|
829
|
+
const { terms: termsSelect, bylines: bylinesSelect } = foldedHydrationSelects(
|
|
830
|
+
db,
|
|
831
|
+
collection,
|
|
832
|
+
"r",
|
|
833
|
+
);
|
|
834
|
+
|
|
835
|
+
// Authoritative re-check on the joined `ec_*` row.
|
|
836
|
+
const deletedR = deletedIsNull ? sql`r.deleted_at IS NULL` : sql`r.deleted_at IS NOT NULL`;
|
|
837
|
+
const statusR = status !== undefined ? sql`AND ${buildStatusCondition(db, status, "r")}` : sql``;
|
|
838
|
+
const localeR = locale ? sql`AND r.locale = ${locale}` : sql``;
|
|
839
|
+
|
|
840
|
+
if (isIndexedSort) {
|
|
841
|
+
const sortRef = sql.ref(`ct.${primary.field}`);
|
|
842
|
+
const sortval = multiGroup ? sql`MAX(${sortRef})` : sortRef;
|
|
843
|
+
const groupByClause = multiGroup ? sql`GROUP BY ct.entry_id` : sql``;
|
|
844
|
+
|
|
845
|
+
let cursorClause = sql``;
|
|
846
|
+
let havingClause = sql``;
|
|
847
|
+
if (cursor) {
|
|
848
|
+
const { orderValue, id } = decodeCursor(cursor);
|
|
849
|
+
const cond = sql`(${sortval} ${cmp} ${orderValue} OR (${sortval} = ${orderValue} AND ct.entry_id ${cmp} ${id}))`;
|
|
850
|
+
// A GROUP BY makes `sortval` an aggregate → cursor goes in HAVING.
|
|
851
|
+
if (multiGroup) havingClause = sql`HAVING ${cond}`;
|
|
852
|
+
else cursorClause = sql`AND ${cond}`;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const limitClause = buildPivotLimitOffset(db, fetchLimit, offset);
|
|
856
|
+
|
|
857
|
+
return sql<Record<string, unknown>>`
|
|
858
|
+
WITH picked AS (
|
|
859
|
+
SELECT ct.entry_id AS entry_id, ${sortval} AS sortval
|
|
860
|
+
FROM content_taxonomies ct
|
|
861
|
+
WHERE ct.collection = ${collection}
|
|
862
|
+
AND ${firstGroupCond}
|
|
863
|
+
AND ${deletedCt}
|
|
864
|
+
${statusCt}
|
|
865
|
+
${localeCt}
|
|
866
|
+
${residual}
|
|
867
|
+
${bylineCt}
|
|
868
|
+
${cursorClause}
|
|
869
|
+
${groupByClause}
|
|
870
|
+
${havingClause}
|
|
871
|
+
ORDER BY sortval ${dir}, ct.entry_id ${dir}
|
|
872
|
+
${limitClause}
|
|
873
|
+
)
|
|
874
|
+
SELECT r.*, ${termsSelect}, ${bylinesSelect}
|
|
875
|
+
FROM picked JOIN ${sql.ref(tableName)} AS r ON r.id = picked.entry_id
|
|
876
|
+
WHERE ${deletedR} ${statusR} ${localeR}
|
|
877
|
+
ORDER BY picked.sortval ${dir}, picked.entry_id ${dir}
|
|
878
|
+
`;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// Temp-sort path: seek the term via the pivot, sort the joined candidate set.
|
|
882
|
+
const orderByClause = buildOrderByClause(orderBy, "r");
|
|
883
|
+
const cursorCond = cursor ? sql`AND ${buildCursorCondition(cursor, orderBy, "r")}` : sql``;
|
|
884
|
+
const limitClause = buildPivotLimitOffset(db, fetchLimit, offset);
|
|
885
|
+
return sql<Record<string, unknown>>`
|
|
886
|
+
WITH picked AS (
|
|
887
|
+
SELECT DISTINCT ct.entry_id AS entry_id
|
|
888
|
+
FROM content_taxonomies ct
|
|
889
|
+
WHERE ct.collection = ${collection}
|
|
890
|
+
AND ${firstGroupCond}
|
|
891
|
+
AND ${deletedCt}
|
|
892
|
+
${statusCt}
|
|
893
|
+
${localeCt}
|
|
894
|
+
${residual}
|
|
895
|
+
${bylineCt}
|
|
896
|
+
)
|
|
897
|
+
SELECT r.*, ${termsSelect}, ${bylinesSelect}
|
|
898
|
+
FROM picked JOIN ${sql.ref(tableName)} AS r ON r.id = picked.entry_id
|
|
899
|
+
WHERE ${deletedR} ${statusR} ${localeR}
|
|
900
|
+
${cursorCond}
|
|
901
|
+
${orderByClause}
|
|
902
|
+
${limitClause}
|
|
903
|
+
`;
|
|
904
|
+
}
|
|
905
|
+
|
|
649
906
|
/**
|
|
650
907
|
* Range filter for comparison operators on field values.
|
|
651
908
|
* Values are compared as strings in the database. This works correctly for
|
|
@@ -912,7 +1169,41 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
912
1169
|
return { entries: [], cacheHint: { tags: [type] } };
|
|
913
1170
|
}
|
|
914
1171
|
|
|
915
|
-
{
|
|
1172
|
+
if (taxonomyFilters.length > 0 && Object.keys(fieldFilters).length === 0) {
|
|
1173
|
+
// Pivot-drive fast path (#1834): seek the matching entries on the
|
|
1174
|
+
// denormalized `content_taxonomies` pivot instead of scanning the
|
|
1175
|
+
// whole collection and probing a taxonomy EXISTS per row. Only the
|
|
1176
|
+
// taxonomy path is restructured — a taxonomy filter combined with a
|
|
1177
|
+
// content-field filter falls through to the single-table shape
|
|
1178
|
+
// below (field predicates live on `ec_*`, not the pivot). A byline
|
|
1179
|
+
// filter rides along inside the pivot CTE (see the builder).
|
|
1180
|
+
const groupSets: string[][] = [];
|
|
1181
|
+
for (const taxFilter of taxonomyFilters) {
|
|
1182
|
+
const groups = await resolveTermGroups(db, taxFilter.name, taxFilter.slugs, locale);
|
|
1183
|
+
// A slug that resolves to no term matches nothing; since taxonomy
|
|
1184
|
+
// filters AND together, one empty set empties the whole result.
|
|
1185
|
+
if (groups.length === 0) {
|
|
1186
|
+
return { entries: [], cacheHint: { tags: [type] } };
|
|
1187
|
+
}
|
|
1188
|
+
groupSets.push(groups);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
result = await buildTaxonomyPivotQuery({
|
|
1192
|
+
db,
|
|
1193
|
+
collection: type,
|
|
1194
|
+
tableName,
|
|
1195
|
+
groupSets,
|
|
1196
|
+
orderBy,
|
|
1197
|
+
cursor,
|
|
1198
|
+
locale,
|
|
1199
|
+
status,
|
|
1200
|
+
// Public listings only ever want live content.
|
|
1201
|
+
deletedIsNull: true,
|
|
1202
|
+
bylineGroups: bylineFilter ? bylineFilter.groups : null,
|
|
1203
|
+
fetchLimit,
|
|
1204
|
+
offset,
|
|
1205
|
+
}).execute(db);
|
|
1206
|
+
} else {
|
|
916
1207
|
// Taxonomy and byline filters are applied as correlated
|
|
917
1208
|
// `EXISTS` semi-joins rather than `INNER JOIN ... DISTINCT`.
|
|
918
1209
|
// A join fan-out would force `SELECT DISTINCT table.*`, and
|
package/src/mcp/server.ts
CHANGED
|
@@ -10,17 +10,19 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { Permission, RoleLevel } from "@emdash-cms/auth";
|
|
13
|
-
import { canActOnOwn, hasPermission, Role } from "@emdash-cms/auth";
|
|
13
|
+
import { canActOnOwn, hasPermission, Permissions, Role } from "@emdash-cms/auth";
|
|
14
14
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
18
|
bylineCreateBody,
|
|
19
19
|
bylineUpdateBody,
|
|
20
|
+
CONTENT_TYPE_RE,
|
|
20
21
|
contentBylineInputSchema,
|
|
21
22
|
contentSeoInput,
|
|
22
23
|
} from "#api/schemas.js";
|
|
23
24
|
|
|
25
|
+
import type { MediaUsageRepairRequest } from "../api/schemas/media-usage.js";
|
|
24
26
|
import type { EmDashHandlers } from "../astro/types.js";
|
|
25
27
|
import { hasScope } from "../auth/api-tokens.js";
|
|
26
28
|
import { convertDataForRead, convertDataForWrite } from "../client/portable-text.js";
|
|
@@ -76,6 +78,35 @@ const settingsSeoSchema = z.object({
|
|
|
76
78
|
.describe("Bing Webmaster Tools verification token"),
|
|
77
79
|
});
|
|
78
80
|
|
|
81
|
+
const mediaUsageRepairToolSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
scope: z.enum(["collection", "all"]).describe("Repair one collection or all collections"),
|
|
84
|
+
collection: z
|
|
85
|
+
.string()
|
|
86
|
+
.min(1)
|
|
87
|
+
.max(63)
|
|
88
|
+
.regex(COLLECTION_SLUG_PATTERN, "Invalid collection slug")
|
|
89
|
+
.optional()
|
|
90
|
+
.describe("Collection slug; required only when scope is collection"),
|
|
91
|
+
})
|
|
92
|
+
.strict()
|
|
93
|
+
.superRefine((input, ctx) => {
|
|
94
|
+
if (input.scope === "collection" && input.collection === undefined) {
|
|
95
|
+
ctx.addIssue({
|
|
96
|
+
code: "custom",
|
|
97
|
+
path: ["collection"],
|
|
98
|
+
message: "Collection is required when scope is collection",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (input.scope === "all" && input.collection !== undefined) {
|
|
102
|
+
ctx.addIssue({
|
|
103
|
+
code: "custom",
|
|
104
|
+
path: ["collection"],
|
|
105
|
+
message: "Collection must be omitted when scope is all",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
79
110
|
// ---------------------------------------------------------------------------
|
|
80
111
|
// Helpers
|
|
81
112
|
// ---------------------------------------------------------------------------
|
|
@@ -88,6 +119,7 @@ type HandlerResult = {
|
|
|
88
119
|
|
|
89
120
|
type SuccessEnvelope = {
|
|
90
121
|
content: Array<{ type: "text"; text: string }>;
|
|
122
|
+
structuredContent?: Record<string, unknown>;
|
|
91
123
|
_meta?: Record<string, unknown>;
|
|
92
124
|
};
|
|
93
125
|
|
|
@@ -450,7 +482,21 @@ function extractContentId(data: unknown): string | undefined {
|
|
|
450
482
|
// Server factory
|
|
451
483
|
// ---------------------------------------------------------------------------
|
|
452
484
|
|
|
453
|
-
export
|
|
485
|
+
export interface PluginMcpRegistration {
|
|
486
|
+
pluginId: string;
|
|
487
|
+
name: string;
|
|
488
|
+
description: string;
|
|
489
|
+
route: string;
|
|
490
|
+
permission: string;
|
|
491
|
+
destructive: boolean;
|
|
492
|
+
inputSchema: z.ZodType;
|
|
493
|
+
outputSchema?: z.ZodType;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export function createMcpServer(
|
|
497
|
+
pluginTools: PluginMcpRegistration[] = [],
|
|
498
|
+
request?: Request,
|
|
499
|
+
): McpServer {
|
|
454
500
|
const server = new McpServer(
|
|
455
501
|
{ name: "emdash", version: "0.1.0" },
|
|
456
502
|
{ capabilities: { logging: {} } },
|
|
@@ -484,6 +530,78 @@ export function createMcpServer(): McpServer {
|
|
|
484
530
|
)(name, config, wrapped);
|
|
485
531
|
}) as typeof server.registerTool;
|
|
486
532
|
|
|
533
|
+
for (const tool of pluginTools) {
|
|
534
|
+
if (!(tool.permission in Permissions)) continue;
|
|
535
|
+
server.registerTool(
|
|
536
|
+
`${tool.pluginId}__${tool.name}`,
|
|
537
|
+
{
|
|
538
|
+
description: tool.description,
|
|
539
|
+
inputSchema: tool.inputSchema,
|
|
540
|
+
outputSchema: tool.outputSchema,
|
|
541
|
+
annotations: { destructiveHint: tool.destructive },
|
|
542
|
+
},
|
|
543
|
+
async (input, extra) => {
|
|
544
|
+
const payload = getExtra(extra);
|
|
545
|
+
const requiredScope = `mcp:tools:${tool.pluginId}`;
|
|
546
|
+
if (payload.tokenScopes && !hasScope(payload.tokenScopes, requiredScope)) {
|
|
547
|
+
if (request) {
|
|
548
|
+
await payload.emdash.handlePluginMcpDenied(
|
|
549
|
+
tool.pluginId,
|
|
550
|
+
tool.name,
|
|
551
|
+
tool.route,
|
|
552
|
+
payload.userId,
|
|
553
|
+
request,
|
|
554
|
+
`Missing scope: ${requiredScope}`,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
throw new EmDashAuthError(
|
|
558
|
+
`Insufficient scope: requires ${requiredScope}`,
|
|
559
|
+
"INSUFFICIENT_SCOPE",
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
if (!hasPermission({ role: payload.userRole }, tool.permission as Permission)) {
|
|
563
|
+
if (request) {
|
|
564
|
+
await payload.emdash.handlePluginMcpDenied(
|
|
565
|
+
tool.pluginId,
|
|
566
|
+
tool.name,
|
|
567
|
+
tool.route,
|
|
568
|
+
payload.userId,
|
|
569
|
+
request,
|
|
570
|
+
`Missing permission: ${tool.permission}`,
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
throw new EmDashAuthError(
|
|
574
|
+
`Insufficient permission: requires ${tool.permission}`,
|
|
575
|
+
"INSUFFICIENT_PERMISSIONS",
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
if (!request) return respondError("INTERNAL_ERROR", "Missing MCP request context");
|
|
579
|
+
const result = await payload.emdash.handlePluginMcpTool(
|
|
580
|
+
tool.pluginId,
|
|
581
|
+
tool.name,
|
|
582
|
+
tool.route,
|
|
583
|
+
input,
|
|
584
|
+
payload.userId,
|
|
585
|
+
request,
|
|
586
|
+
);
|
|
587
|
+
if (!result.success) return unwrap(result);
|
|
588
|
+
if (tool.outputSchema) {
|
|
589
|
+
if (!result.data || typeof result.data !== "object" || Array.isArray(result.data)) {
|
|
590
|
+
return respondError(
|
|
591
|
+
"INVALID_PLUGIN_OUTPUT",
|
|
592
|
+
"Plugin tool output must be an object when outputSchema is declared",
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }],
|
|
597
|
+
structuredContent: result.data as Record<string, unknown>,
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
return respondData(result.data);
|
|
601
|
+
},
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
|
|
487
605
|
// =====================================================================
|
|
488
606
|
// Content tools
|
|
489
607
|
// =====================================================================
|
|
@@ -1794,9 +1912,8 @@ export function createMcpServer(): McpServer {
|
|
|
1794
1912
|
"caller is responsible for placing the file at `storageKey` (typically " +
|
|
1795
1913
|
"using a signed upload URL obtained from the admin UI or a separate API). " +
|
|
1796
1914
|
"This tool persists the metadata record so the file is discoverable via " +
|
|
1797
|
-
"media_list / media_get and can be referenced by content.
|
|
1798
|
-
"
|
|
1799
|
-
"flow instead.",
|
|
1915
|
+
"media_list / media_get and can be referenced by content. To upload the " +
|
|
1916
|
+
"file itself, use media_upload (base64 data or a public URL) instead.",
|
|
1800
1917
|
inputSchema: z.object({
|
|
1801
1918
|
filename: z.string().describe("Original filename (e.g. 'logo.png')"),
|
|
1802
1919
|
mimeType: z.string().describe("MIME type (e.g. 'image/png')"),
|
|
@@ -1833,6 +1950,70 @@ export function createMcpServer(): McpServer {
|
|
|
1833
1950
|
},
|
|
1834
1951
|
);
|
|
1835
1952
|
|
|
1953
|
+
server.registerTool(
|
|
1954
|
+
"media_upload",
|
|
1955
|
+
{
|
|
1956
|
+
title: "Upload Media",
|
|
1957
|
+
description:
|
|
1958
|
+
"Upload a media file from base64-encoded data or an external URL and " +
|
|
1959
|
+
"register it in the media library. Returns the media item with id, " +
|
|
1960
|
+
"storageKey, and url — ready to reference from content fields (e.g. " +
|
|
1961
|
+
"featured_image) via content_create / content_update. Uploads are " +
|
|
1962
|
+
"deduplicated by content hash: re-uploading identical bytes returns " +
|
|
1963
|
+
"the existing item with deduplicated: true. URL fetches must resolve " +
|
|
1964
|
+
"to a public http(s) host (SSRF-guarded). Subject to the global " +
|
|
1965
|
+
"upload MIME allowlist and the configured maximum upload size.",
|
|
1966
|
+
inputSchema: z.object({
|
|
1967
|
+
filename: z.string().min(1).describe("Filename including extension (e.g. 'cover.png')"),
|
|
1968
|
+
base64: z
|
|
1969
|
+
.string()
|
|
1970
|
+
.optional()
|
|
1971
|
+
.describe("Base64-encoded file contents. Provide exactly one of base64 / url."),
|
|
1972
|
+
url: z
|
|
1973
|
+
.string()
|
|
1974
|
+
.url()
|
|
1975
|
+
.optional()
|
|
1976
|
+
.describe(
|
|
1977
|
+
"Public http(s) URL to fetch the file from. Provide exactly one of base64 / url.",
|
|
1978
|
+
),
|
|
1979
|
+
contentType: z
|
|
1980
|
+
.string()
|
|
1981
|
+
.regex(CONTENT_TYPE_RE, "Invalid content type")
|
|
1982
|
+
.optional()
|
|
1983
|
+
.describe(
|
|
1984
|
+
"MIME type (e.g. 'image/png'). Required with base64; with url it " +
|
|
1985
|
+
"defaults to the response's Content-Type header.",
|
|
1986
|
+
),
|
|
1987
|
+
alt: z.string().optional().describe("Alt text for accessibility"),
|
|
1988
|
+
}),
|
|
1989
|
+
annotations: { destructiveHint: false },
|
|
1990
|
+
},
|
|
1991
|
+
async (args, extra) => {
|
|
1992
|
+
requireScope(extra, "media:write");
|
|
1993
|
+
requireRole(extra, Role.CONTRIBUTOR);
|
|
1994
|
+
const { emdash, userId } = getExtra(extra);
|
|
1995
|
+
if (!emdash.storage) {
|
|
1996
|
+
return respondError("NO_STORAGE", "Storage not configured");
|
|
1997
|
+
}
|
|
1998
|
+
try {
|
|
1999
|
+
const { handleMediaUpload } = await import("../api/handlers/media-upload.js");
|
|
2000
|
+
return unwrap(
|
|
2001
|
+
await handleMediaUpload(emdash.db, emdash.storage, {
|
|
2002
|
+
filename: args.filename,
|
|
2003
|
+
base64: args.base64,
|
|
2004
|
+
url: args.url,
|
|
2005
|
+
contentType: args.contentType,
|
|
2006
|
+
alt: args.alt,
|
|
2007
|
+
authorId: userId,
|
|
2008
|
+
maxUploadSize: emdash.config.maxUploadSize,
|
|
2009
|
+
}),
|
|
2010
|
+
);
|
|
2011
|
+
} catch (error) {
|
|
2012
|
+
return respondHandlerError(error, "UPLOAD_ERROR");
|
|
2013
|
+
}
|
|
2014
|
+
},
|
|
2015
|
+
);
|
|
2016
|
+
|
|
1836
2017
|
server.registerTool(
|
|
1837
2018
|
"media_get",
|
|
1838
2019
|
{
|
|
@@ -1927,6 +2108,42 @@ export function createMcpServer(): McpServer {
|
|
|
1927
2108
|
},
|
|
1928
2109
|
);
|
|
1929
2110
|
|
|
2111
|
+
server.registerTool(
|
|
2112
|
+
"media_usage_repair",
|
|
2113
|
+
{
|
|
2114
|
+
title: "Repair Media Usage Index",
|
|
2115
|
+
description:
|
|
2116
|
+
"Repair content media usage indexes for one collection or every collection. " +
|
|
2117
|
+
"Returns complete, partial, failed, or stale status; inspect the structured result.",
|
|
2118
|
+
inputSchema: mediaUsageRepairToolSchema,
|
|
2119
|
+
},
|
|
2120
|
+
async (args, extra) => {
|
|
2121
|
+
requireScope(extra, "admin");
|
|
2122
|
+
requireRole(extra, Role.ADMIN);
|
|
2123
|
+
const ec = getEmDash(extra);
|
|
2124
|
+
|
|
2125
|
+
let input: MediaUsageRepairRequest;
|
|
2126
|
+
if (args.scope === "collection") {
|
|
2127
|
+
if (args.collection === undefined) {
|
|
2128
|
+
return respondError(
|
|
2129
|
+
"VALIDATION_ERROR",
|
|
2130
|
+
"Collection is required when scope is collection",
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
input = { scope: "collection", collection: args.collection };
|
|
2134
|
+
} else {
|
|
2135
|
+
input = { scope: "all" };
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
try {
|
|
2139
|
+
const { handleMediaUsageRepair } = await import("../api/handlers/media-usage.js");
|
|
2140
|
+
return unwrap(await handleMediaUsageRepair(ec.db, input));
|
|
2141
|
+
} catch (error) {
|
|
2142
|
+
return respondHandlerError(error, "MEDIA_USAGE_REPAIR_ERROR");
|
|
2143
|
+
}
|
|
2144
|
+
},
|
|
2145
|
+
);
|
|
2146
|
+
|
|
1930
2147
|
// =====================================================================
|
|
1931
2148
|
// Search tool
|
|
1932
2149
|
// =====================================================================
|