emdash 0.28.1 → 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-hUy8vOB-.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
- package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
- package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
- package/dist/{allowed-origins-CRsJ6BPM.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 +22 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -4
- package/dist/{api-DxFSorgk.mjs → api-b8WIiGU4.mjs} +306 -154
- package/dist/api-b8WIiGU4.mjs.map +1 -0
- package/dist/api-tokens-Cvmixds7.mjs +3 -0
- package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
- package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
- package/dist/{apply-CDJqIjPU.mjs → apply-CmIJK9j8.mjs} +35 -38
- package/dist/apply-CmIJK9j8.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +97 -13
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- 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.d.mts +3 -0
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +258 -31
- 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 +379 -117
- 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 +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +19 -24
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +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.d.mts.map +1 -1
- 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 +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +30 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +49 -41
- 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 +43 -40
- 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 +46 -41
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +49 -41
- 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 +43 -40
- 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 +49 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +43 -40
- 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 +47 -42
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +43 -40
- 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 +48 -43
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +43 -40
- 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 +43 -40
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +10 -9
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- 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 +14 -13
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +11 -10
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +13 -12
- 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 +13 -12
- 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 +16 -6
- 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 +14 -13
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +14 -13
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +13 -12
- 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.d.mts.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +70 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +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 +9 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +72 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +51 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
- 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 +20 -19
- 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 +19 -18
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -16
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -11
- 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 +19 -18
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +29 -28
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +8 -9
- 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 +165 -52
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +10 -9
- 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 +11 -10
- 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 +34 -14
- 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 +71 -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 +13 -12
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +13 -12
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +14 -13
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +14 -13
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
- package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs +70 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/relations/index.d.mts +9 -0
- package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/index.mjs +54 -0
- package/dist/astro/routes/api/relations/index.mjs.map +1 -0
- 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_.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -40
- 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 +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +43 -40
- 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 +43 -40
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +43 -40
- 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 +14 -12
- 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 +6 -6
- package/dist/astro/routes/api/settings.mjs +16 -15
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +20 -16
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +19 -15
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -29
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +31 -30
- 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 +9 -216
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- 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 +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/index.mjs +13 -12
- 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 +9 -9
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
- package/dist/astro/routes/sitemap.xml.mjs +10 -10
- package/dist/astro/types.d.mts +40 -16
- 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-Dz88F_Fw.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-CmWvODNW.mjs → base64-B-PsqheR.mjs} +8 -4
- package/dist/base64-B-PsqheR.mjs.map +1 -0
- package/dist/{byline-Bm8ZgUP9.mjs → byline-XEjchwzZ.mjs} +8 -8
- package/dist/{byline-Bm8ZgUP9.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
- package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-CdU_LTF1.mjs} +2 -2
- package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
- package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
- package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
- package/dist/{bylines-6tm9mgQb.mjs → bylines-BJbT4gKS.mjs} +4 -4
- package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
- package/dist/{bylines-CAZxGSrm.mjs → bylines-czseViYo.mjs} +8 -8
- package/dist/{bylines-CAZxGSrm.mjs.map → bylines-czseViYo.mjs.map} +1 -1
- package/dist/{cache-CEBAZjir.mjs → cache-CGCd6AVM.mjs} +3 -3
- package/dist/{cache-CEBAZjir.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs → challenge-store-BFzgFRog.mjs} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
- package/dist/{chunks-B2isWQhr.mjs → chunks-BxXyunY-.mjs} +2 -2
- package/dist/{chunks-B2isWQhr.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
- package/dist/cli/index.mjs +142 -35
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +86 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +20 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-CzeatwBV.mjs → comment-DPT0WKyd.mjs} +2 -2
- package/dist/{comment-CzeatwBV.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
- package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-C65MldIB.mjs} +2 -2
- package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
- package/dist/{comments-BLE-jv5k.mjs → comments-Bz6sCbgD.mjs} +3 -3
- package/dist/{comments-BLE-jv5k.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
- package/dist/{components-B_sATNUc.mjs → components-DZkL4Fx0.mjs} +1 -1
- package/dist/{components-B_sATNUc.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
- package/dist/{content-DhgEth4k.mjs → content-Ci04z2z-.mjs} +227 -34
- package/dist/content-Ci04z2z-.mjs.map +1 -0
- package/dist/{content-refresh-Br4gMzh8.mjs → content-refresh-D4khvC0R.mjs} +100 -8
- package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
- package/dist/{context-BRIpHARC.mjs → context-B6hc7zJL.mjs} +156 -76
- package/dist/context-B6hc7zJL.mjs.map +1 -0
- package/dist/{cron-v4FTEFR_.mjs → cron-BlKIMD_e.mjs} +1 -1
- package/dist/{cron-v4FTEFR_.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
- package/dist/{dashboard-EvEKF5en.mjs → dashboard-C5NkXFbi.mjs} +6 -5
- package/dist/dashboard-C5NkXFbi.mjs.map +1 -0
- package/dist/database/pg-migration-lock.d.mts +21 -0
- package/dist/database/pg-migration-lock.d.mts.map +1 -0
- package/dist/database/pg-migration-lock.mjs +45 -0
- package/dist/database/pg-migration-lock.mjs.map +1 -0
- 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/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +2 -8
- package/dist/db/postgres.mjs.map +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CK46D-ly.mjs → db-errors-CcWLaRiR.mjs} +4 -2
- package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
- package/dist/{default-CM_D83Mg.mjs → default-C4v9KP56.mjs} +1 -1
- package/dist/{default-CM_D83Mg.mjs.map → default-C4v9KP56.mjs.map} +1 -1
- package/dist/{device-flow-CfGP18Uw.mjs → device-flow-BeA6lUS1.mjs} +6 -7
- package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs +175 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs.map +1 -0
- package/dist/{email-console-CIf4Lfvv.mjs → email-console-C-9Ng8DM.mjs} +1 -1
- package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
- package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
- package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
- package/dist/error-CEGF6UZb.mjs +90 -0
- package/dist/error-CEGF6UZb.mjs.map +1 -0
- package/dist/{error-CkAseSqZ.mjs → errors-DtEXIQQV.mjs} +24 -84
- package/dist/errors-DtEXIQQV.mjs.map +1 -0
- package/dist/{escape-DqD0aCKu.mjs → escape-CFedIB1C.mjs} +1 -1
- package/dist/{escape-DqD0aCKu.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
- package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-DvmlgP-D.mjs} +5 -5
- package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
- package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-DzqIBrrW.mjs} +27 -3
- package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
- package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
- package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
- package/dist/hreflang-CIxH_LKz.d.mts +48 -0
- package/dist/hreflang-CIxH_LKz.d.mts.map +1 -0
- package/dist/hreflang-db2Tpb2o.mjs +102 -0
- package/dist/hreflang-db2Tpb2o.mjs.map +1 -0
- package/dist/{import-fYLf14Co.mjs → import-Dmkm8S1W.mjs} +6 -6
- package/dist/{import-fYLf14Co.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
- package/dist/{index-Bm-Gy8Mh.d.mts → index-BEui-cRd.d.mts} +3 -3
- package/dist/{index-Bm-Gy8Mh.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
- package/dist/{index-B9sIxwe4.d.mts → index-wYnC6u4o.d.mts} +881 -22
- package/dist/index-wYnC6u4o.d.mts.map +1 -0
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +69 -64
- package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
- package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
- package/dist/{load-Djn3HWQS.mjs → load-Cx27ki1l.mjs} +2 -2
- package/dist/{load-Djn3HWQS.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
- package/dist/{loader-CB6YHeul.mjs → loader-Be3ouI5L.mjs} +170 -21
- package/dist/loader-Be3ouI5L.mjs.map +1 -0
- package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-bCq54i7F.mjs} +18 -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 +30 -4
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +8 -8
- package/dist/{media-BrXIaMFN.mjs → media-BjhhENaJ.mjs} +2 -2
- package/dist/media-BjhhENaJ.mjs.map +1 -0
- package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-jUppPWFy.mjs} +2 -2
- package/dist/{media-allowlist-CRHEeJ_i.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-CKi5XSw4.mjs → media-url-BCm5vBn6.mjs} +1 -1
- package/dist/{media-url-CKi5XSw4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
- package/dist/media-usage-CljdO1mc.mjs +554 -0
- package/dist/media-usage-CljdO1mc.mjs.map +1 -0
- package/dist/{menus-b2T4clbO.mjs → menus-BcyElFtI.mjs} +177 -15
- package/dist/menus-BcyElFtI.mjs.map +1 -0
- package/dist/{menus-Cfivc2Ad.mjs → menus-CZyG6rvx.mjs} +3 -3
- package/dist/{menus-Cfivc2Ad.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
- package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
- package/dist/{mode-BM9QgEmt.mjs → mode-fiXRMfeA.mjs} +1 -1
- package/dist/{mode-BM9QgEmt.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
- package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
- package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
- package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-oqfbBuMH.mjs} +6 -7
- package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
- package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
- package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
- package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
- package/dist/{options-iMpRRxIe.d.mts → options-BqMkWfYa.d.mts} +6 -6
- package/dist/{options-iMpRRxIe.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-GmjecGct.mjs → parse-C_-6klII.mjs} +4 -12
- package/dist/{parse-GmjecGct.mjs.map → parse-C_-6klII.mjs.map} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
- package/dist/{placeholder-BSKwzRe4.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 -16
- 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 -10
- 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-cCa0cGV6.mjs → portable-text-sDj92Kxv.mjs} +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
- package/dist/{preview-SSXNVPAC.mjs → preview-D4Jnbfx7.mjs} +2 -2
- package/dist/{preview-SSXNVPAC.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
- package/dist/{public-url-Danv47cS.mjs → public-url-DSGTnJFw.mjs} +5 -3
- package/dist/public-url-DSGTnJFw.mjs.map +1 -0
- package/dist/{query-1Cp6U9oo.mjs → query-DR73ZNfm.mjs} +15 -15
- package/dist/query-DR73ZNfm.mjs.map +1 -0
- package/dist/{schema-CX9cfNkZ.mjs → query-Di7DOmPV.mjs} +5 -10
- package/dist/query-Di7DOmPV.mjs.map +1 -0
- package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-CMj83JNW.mjs} +2 -2
- package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs → redirect-Botom7X6.mjs} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
- package/dist/{redirect-IyfNirgS.mjs → redirect-CgLPYflR.mjs} +11 -5
- package/dist/redirect-CgLPYflR.mjs.map +1 -0
- package/dist/{redirects-Bs1g42Ri.mjs → redirects-B7t9bKsL.mjs} +6 -6
- package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
- package/dist/{redirects-DXEXBAII.mjs → redirects-BBq3n2Rj.mjs} +10 -143
- package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
- package/dist/{registry-B57vp_X9.mjs → registry-FV15nLge.mjs} +99 -10
- package/dist/registry-FV15nLge.mjs.map +1 -0
- package/dist/relation-9M9j_UWo.mjs +334 -0
- package/dist/relation-9M9j_UWo.mjs.map +1 -0
- package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-5_avdrN_.mjs} +60 -4
- package/dist/relations-5_avdrN_.mjs.map +1 -0
- package/dist/relations-BKvO39-9.mjs +397 -0
- package/dist/relations-BKvO39-9.mjs.map +1 -0
- package/dist/{byline-fields-CHE8UStY.d.mts → relations-Bh8jlFsU.d.mts} +486 -31
- package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
- package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
- package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
- package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DzXYYI-n.mjs} +2 -2
- package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
- package/dist/{runner-DvFWoz8-.d.mts → runner-Dd8m8k9F.d.mts} +8 -2
- package/dist/runner-Dd8m8k9F.d.mts.map +1 -0
- package/dist/{runner-K8XK101B.mjs → runner-DfnZ5eUr.mjs} +355 -204
- package/dist/runner-DfnZ5eUr.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +4 -4
- package/dist/schema-BXxlHeAf.mjs +9 -0
- package/dist/schema-BXxlHeAf.mjs.map +1 -0
- package/dist/scopes-Bl4IwHA-.mjs +27 -0
- package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
- package/dist/{search-DZN2HZ-V.mjs → search-Bff-7jFt.mjs} +62 -12
- package/dist/search-Bff-7jFt.mjs.map +1 -0
- package/dist/{secrets-kp760LlD.mjs → secrets-CSwQIl4q.mjs} +4 -4
- package/dist/{secrets-kp760LlD.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
- package/dist/{sections-CpF5SaGr.mjs → sections-CwW4s1al.mjs} +3 -3
- package/dist/{sections-CpF5SaGr.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +23 -23
- package/dist/seo/index.d.mts +15 -2
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +22 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-DXu2UQnC.mjs → seo-2cmFHZns.mjs} +2 -2
- package/dist/{seo-DXu2UQnC.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
- package/dist/{seo-89-53DDs.mjs → seo-C3GDfT0V.mjs} +1 -1
- package/dist/{seo-89-53DDs.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
- package/dist/{service-DQmiBMzt.mjs → service-DkGTWGIi.mjs} +3 -3
- package/dist/{service-DQmiBMzt.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
- package/dist/{session-user-Cascbax7.mjs → session-user-DbHqKDKe.mjs} +1 -1
- package/dist/{session-user-Cascbax7.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
- package/dist/{settings-rZyHEcNT.mjs → settings-C4s8hFQm.mjs} +3 -3
- package/dist/{settings-rZyHEcNT.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
- package/dist/{settings-zhmdKyJQ.mjs → settings-CpA4lQFt.mjs} +6 -6
- package/dist/{settings-zhmdKyJQ.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
- package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-CdIlqloh.mjs} +2 -2
- package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
- package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-C2exrGAi.mjs} +2 -2
- package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
- package/dist/{site-url-BBfDTgZB.mjs → site-url-NGJT6NTU.mjs} +2 -2
- package/dist/{site-url-BBfDTgZB.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
- package/dist/snapshot-BdpUJKD-.mjs +216 -0
- package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
- package/dist/{ssrf-1g7usGBg.mjs → ssrf-CviKqWmq.mjs} +1 -1
- package/dist/{ssrf-1g7usGBg.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-CqJQX1QN.mjs → status-COfycGIU.mjs} +1 -1
- package/dist/{status-CqJQX1QN.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-Bs13SN-F.mjs → taxonomies-Ce49uIzY.mjs} +13 -9
- package/dist/taxonomies-Ce49uIzY.mjs.map +1 -0
- package/dist/{taxonomies-kH9ABDUF.mjs → taxonomies-DjSKBZpq.mjs} +115 -36
- package/dist/taxonomies-DjSKBZpq.mjs.map +1 -0
- package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-DfVooU4W.mjs} +60 -13
- package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
- package/dist/{tokens-BGT0TUUo.mjs → tokens-DVltpO2D.mjs} +2 -2
- package/dist/{tokens-BGT0TUUo.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
- package/dist/{transport-DPefPMcz.mjs → transport-CKrlqSpD.mjs} +1 -1
- package/dist/{transport-DPefPMcz.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
- package/dist/{types-CgvhU-hF.d.mts → types-B4vm81VH.d.mts} +1 -1
- package/dist/{types-CgvhU-hF.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
- package/dist/{types-ea9sAPck.d.mts → types-B97jg3aW.d.mts} +6 -1
- package/dist/{types-ea9sAPck.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
- package/dist/{types-Jo3UYd6b.mjs → types-BD40g7zz.mjs} +1 -1
- package/dist/{types-Jo3UYd6b.mjs.map → types-BD40g7zz.mjs.map} +1 -1
- package/dist/{types-DmHk7vAt.d.mts → types-BNfPHfay.d.mts} +1 -1
- package/dist/{types-DmHk7vAt.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
- package/dist/{types-BcLUUbbR.d.mts → types-BfYUPJdP.d.mts} +11 -3
- package/dist/{types-BcLUUbbR.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
- package/dist/{types-CGbYowGQ.d.mts → types-BvB7gDOD.d.mts} +90 -4
- package/dist/types-BvB7gDOD.d.mts.map +1 -0
- package/dist/{types-vgEWF18A.d.mts → types-C7U0HlEr.d.mts} +1 -1
- package/dist/{types-vgEWF18A.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
- package/dist/{types-CuW0zWDA.mjs → types-D1iJ3DpO.mjs} +3 -3
- package/dist/{types-CuW0zWDA.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
- package/dist/{types-_HFLRzTn.d.mts → types-DPKhI5ib.d.mts} +9 -1
- package/dist/types-DPKhI5ib.d.mts.map +1 -0
- package/dist/{types-g_aFIdW0.d.mts → types-Kmaxdarz.d.mts} +1 -1
- package/dist/{types-g_aFIdW0.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
- package/dist/{types-ClUkdbWb.d.mts → types-iVeZ5g6N.d.mts} +1 -1
- package/dist/{types-ClUkdbWb.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
- package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
- package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
- package/dist/{user-BjAOvU3Z.mjs → user-Bh-L1qo6.mjs} +3 -3
- package/dist/{user-BjAOvU3Z.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
- package/dist/{utils-BJXElxdw.mjs → utils-BbUgmeZG.mjs} +3 -3
- package/dist/{utils-BJXElxdw.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
- package/dist/{validate-Z1b86_3B.d.mts → validate-DULfgpJP.d.mts} +5 -5
- package/dist/{validate-Z1b86_3B.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
- package/dist/{validate-CWSnKVIJ.mjs → validate-V9nCwq_-.mjs} +3 -3
- package/dist/{validate-CWSnKVIJ.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
- package/dist/{validation-0l8-RYj4.mjs → validation-BsVUJfsP.mjs} +10 -10
- package/dist/{validation-0l8-RYj4.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
- package/dist/version-907opKac.mjs +7 -0
- package/dist/{version-qmeO1XZY.mjs.map → version-907opKac.mjs.map} +1 -1
- package/dist/{widgets-hWcIicX8.mjs → widgets-DGv1Z04V.mjs} +4 -4
- package/dist/{widgets-hWcIicX8.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +4 -4
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
- package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-B5prQ5M4.mjs} +3 -3
- package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
- package/package.json +12 -8
- package/src/api/authorize.ts +10 -1
- package/src/api/error.ts +5 -5
- package/src/api/errors.ts +25 -0
- package/src/api/handlers/backup.ts +312 -0
- package/src/api/handlers/content.ts +147 -3
- package/src/api/handlers/dashboard.ts +2 -0
- package/src/api/handlers/device-flow.ts +2 -3
- package/src/api/handlers/index.ts +22 -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 +289 -0
- 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 +474 -0
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/handlers/taxonomies.ts +26 -4
- package/src/api/handlers/validate-media-fields.ts +1 -1
- package/src/api/openapi/document.ts +72 -5
- package/src/api/parse.ts +2 -16
- package/src/api/public-url.ts +4 -2
- package/src/api/schemas/comments.ts +6 -0
- package/src/api/schemas/common.ts +6 -2
- package/src/api/schemas/content.ts +8 -0
- package/src/api/schemas/index.ts +2 -0
- package/src/api/schemas/media-usage.ts +120 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/api/schemas/relations.ts +109 -0
- package/src/api/schemas/search.ts +1 -0
- package/src/astro/integration/index.ts +39 -0
- package/src/astro/integration/routes.ts +40 -0
- package/src/astro/integration/runtime.ts +30 -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/request-context.ts +162 -20
- package/src/astro/middleware.ts +108 -40
- 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/comments/[id]/status.ts +1 -2
- package/src/astro/routes/api/admin/comments/index.ts +1 -2
- package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
- 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 -5
- package/src/astro/routes/api/auth/oauth/[provider].ts +24 -7
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
- 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 +95 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +47 -0
- 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/relations/[id]/index.ts +84 -0
- package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
- package/src/astro/routes/api/relations/index.ts +56 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
- package/src/astro/routes/api/search/index.ts +2 -0
- 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 +50 -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/export-seed.ts +1 -10
- package/src/cli/commands/media.ts +127 -0
- package/src/client/index.ts +123 -2
- package/src/client/transport.ts +1 -1
- package/src/comments/service.ts +1 -1
- package/src/comments/turnstile.ts +64 -0
- package/src/components/BlockquoteGroup.astro +34 -0
- package/src/components/CommentForm.astro +12 -5
- package/src/components/EmDashHead.astro +31 -9
- package/src/components/InlinePortableTextEditor.tsx +88 -33
- package/src/components/PortableText.astro +7 -1
- package/src/components/index.ts +2 -0
- package/src/components/marks/Link.astro +5 -1
- package/src/components/portable-text-blockquote-group.ts +68 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
- package/src/database/dialect-helpers.ts +111 -3
- package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
- 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 +52 -6
- package/src/database/pg-migration-lock.ts +72 -0
- package/src/database/repositories/audit.ts +2 -1
- package/src/database/repositories/comment.ts +1 -1
- package/src/database/repositories/content.ts +270 -37
- package/src/database/repositories/media-usage.ts +250 -1
- package/src/database/repositories/media.ts +1 -1
- package/src/database/repositories/plugin-storage.ts +29 -32
- package/src/database/repositories/redirect.ts +14 -2
- package/src/database/repositories/relation.ts +130 -5
- package/src/database/repositories/taxonomy.ts +66 -8
- package/src/database/repositories/types.ts +8 -0
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +9 -0
- package/src/db/postgres.ts +5 -2
- package/src/emdash-runtime.ts +382 -70
- package/src/index.ts +6 -2
- package/src/loader.ts +293 -32
- package/src/mcp/server.ts +251 -8
- 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 +92 -0
- package/src/plugins/define-plugin.ts +17 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/manifest-schema.ts +30 -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 +100 -0
- package/src/schema/byline-registry.ts +1 -1
- package/src/schema/registry.ts +141 -5
- package/src/search/fts-manager.ts +34 -0
- package/src/search/match.ts +50 -0
- package/src/search/query.ts +94 -9
- package/src/seed/apply.ts +28 -29
- package/src/seo/hreflang.ts +192 -0
- package/src/seo/index.ts +22 -4
- package/src/storage/types.ts +6 -0
- package/src/taxonomies/index.ts +62 -45
- package/src/taxonomies/term-counts.ts +117 -0
- package/src/utils/base64.ts +7 -2
- package/src/utils/db-errors.ts +3 -1
- package/src/virtual-modules.d.ts +14 -0
- package/src/visual-editing/editable.ts +41 -35
- package/src/visual-editing/toolbar-bootstrap.ts +120 -0
- package/src/visual-editing/toolbar.ts +47 -1
- package/dist/adapters-hUy8vOB-.d.mts.map +0 -1
- package/dist/api-DxFSorgk.mjs.map +0 -1
- package/dist/api-tokens-DsvvCtdh.mjs +0 -3
- package/dist/apply-CDJqIjPU.mjs.map +0 -1
- package/dist/authorize-Dz88F_Fw.mjs.map +0 -1
- package/dist/base64-CmWvODNW.mjs.map +0 -1
- package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
- package/dist/byline-fields-CHE8UStY.d.mts.map +0 -1
- package/dist/content-DhgEth4k.mjs.map +0 -1
- package/dist/content-refresh-Br4gMzh8.mjs.map +0 -1
- package/dist/context-BRIpHARC.mjs.map +0 -1
- package/dist/dashboard-EvEKF5en.mjs.map +0 -1
- package/dist/db-errors-CK46D-ly.mjs.map +0 -1
- package/dist/device-flow-CfGP18Uw.mjs.map +0 -1
- package/dist/dialect-helpers-DRI5pyY3.mjs +0 -110
- package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
- package/dist/error-CkAseSqZ.mjs.map +0 -1
- package/dist/index-B9sIxwe4.d.mts.map +0 -1
- package/dist/loader-CB6YHeul.mjs.map +0 -1
- package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
- package/dist/media-BrXIaMFN.mjs.map +0 -1
- package/dist/menus-b2T4clbO.mjs.map +0 -1
- package/dist/oauth-authorization-CXWkIGT4.mjs.map +0 -1
- package/dist/public-url-Danv47cS.mjs.map +0 -1
- package/dist/query-1Cp6U9oo.mjs.map +0 -1
- package/dist/redirect-IyfNirgS.mjs.map +0 -1
- package/dist/redirects-DXEXBAII.mjs.map +0 -1
- package/dist/registry-B57vp_X9.mjs.map +0 -1
- package/dist/runner-DvFWoz8-.d.mts.map +0 -1
- package/dist/runner-K8XK101B.mjs.map +0 -1
- package/dist/scheduled-publish-Drffrf2a.d.mts +0 -11
- package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
- package/dist/schema-CX9cfNkZ.mjs.map +0 -1
- package/dist/search-DZN2HZ-V.mjs.map +0 -1
- package/dist/taxonomies-Bs13SN-F.mjs.map +0 -1
- package/dist/taxonomies-kH9ABDUF.mjs.map +0 -1
- package/dist/taxonomy-BxGxZZdu.mjs.map +0 -1
- package/dist/types-CGbYowGQ.d.mts.map +0 -1
- package/dist/types-_HFLRzTn.d.mts.map +0 -1
- package/dist/version-qmeO1XZY.mjs +0 -7
- /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-BB__xfNM.mjs} +0 -0
- /package/dist/{types-DROWRxYV.mjs → types-CK0LxPUQ.mjs} +0 -0
package/src/emdash-runtime.ts
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* Created once per worker lifetime, cached and reused across requests.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { Permissions } from "@emdash-cms/auth";
|
|
10
11
|
import type { Element } from "@emdash-cms/blocks";
|
|
11
12
|
import { Kysely, sql, type Dialect } from "kysely";
|
|
12
13
|
import virtualConfig from "virtual:emdash/config";
|
|
14
|
+
import { z } from "zod";
|
|
13
15
|
|
|
14
16
|
import { validateRev } from "./api/rev.js";
|
|
15
17
|
import type {
|
|
@@ -22,7 +24,12 @@ import { getAuthMode } from "./auth/mode.js";
|
|
|
22
24
|
import { getTrustedProxyHeaders } from "./auth/trusted-proxy.js";
|
|
23
25
|
import { isSqlite } from "./database/dialect-helpers.js";
|
|
24
26
|
import { kyselyLogOption } from "./database/instrumentation.js";
|
|
25
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
ConcurrentMigrationTimeoutError,
|
|
29
|
+
MIGRATION_RACE_WAIT_MS,
|
|
30
|
+
runMigrations,
|
|
31
|
+
} from "./database/migrations/runner.js";
|
|
32
|
+
import { AuditRepository } from "./database/repositories/audit.js";
|
|
26
33
|
import { RevisionRepository } from "./database/repositories/revision.js";
|
|
27
34
|
import type {
|
|
28
35
|
ContentItem as ContentItemInternal,
|
|
@@ -37,18 +44,25 @@ import {
|
|
|
37
44
|
markContentMediaUsageCollectionStale,
|
|
38
45
|
refreshContentMediaUsageAfterWrite,
|
|
39
46
|
} from "./media/usage/content-refresh.js";
|
|
40
|
-
import
|
|
47
|
+
import { createSandboxRunnerOptions } from "./plugins/sandbox/runner-options.js";
|
|
48
|
+
import type {
|
|
49
|
+
SandboxedPluginInstance,
|
|
50
|
+
SandboxRunner,
|
|
51
|
+
SandboxRunnerFactory,
|
|
52
|
+
} from "./plugins/sandbox/types.js";
|
|
41
53
|
import type {
|
|
42
54
|
ResolvedPlugin,
|
|
43
55
|
MediaItem,
|
|
44
56
|
PluginManifest,
|
|
45
57
|
PluginCapability,
|
|
46
58
|
PluginStorageConfig,
|
|
59
|
+
PluginMcpManifestConfig,
|
|
47
60
|
PublicPageContext,
|
|
48
61
|
PageMetadataContribution,
|
|
49
62
|
PageFragmentContribution,
|
|
50
63
|
PortableTextBlockConfig,
|
|
51
64
|
FieldWidgetConfig,
|
|
65
|
+
SettingField,
|
|
52
66
|
} from "./plugins/types.js";
|
|
53
67
|
import type { FieldType } from "./schema/types.js";
|
|
54
68
|
import { hashString } from "./utils/hash.js";
|
|
@@ -117,6 +131,7 @@ function isValidMetadataContribution(c: unknown): c is PageMetadataContribution
|
|
|
117
131
|
}
|
|
118
132
|
|
|
119
133
|
import { after } from "./after.js";
|
|
134
|
+
import { maybeRunScheduledBackup } from "./api/handlers/backup.js";
|
|
120
135
|
import { loadBundleFromR2 } from "./api/handlers/marketplace.js";
|
|
121
136
|
import { runSystemCleanup } from "./cleanup.js";
|
|
122
137
|
import {
|
|
@@ -170,7 +185,7 @@ import {
|
|
|
170
185
|
} from "./plugins/hooks.js";
|
|
171
186
|
import { normalizeManifestRoute } from "./plugins/manifest-schema.js";
|
|
172
187
|
import { extractRequestMeta, sanitizeHeadersForSandbox } from "./plugins/request-meta.js";
|
|
173
|
-
import { PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
|
|
188
|
+
import { buildRouteMeta, PluginRouteRegistry, type RouteMeta } from "./plugins/routes.js";
|
|
174
189
|
import type { CronScheduler } from "./plugins/scheduler/types.js";
|
|
175
190
|
import { PluginStateRepository } from "./plugins/state.js";
|
|
176
191
|
import { normalizeRegistryConfig } from "./registry/config.js";
|
|
@@ -216,10 +231,14 @@ export interface SandboxedPluginEntry {
|
|
|
216
231
|
allowedHosts: string[];
|
|
217
232
|
/** Declared storage collections */
|
|
218
233
|
storage: PluginStorageConfig;
|
|
234
|
+
/** Serialized MCP declarations emitted at plugin build time. */
|
|
235
|
+
mcp?: PluginMcpManifestConfig;
|
|
219
236
|
/** Admin pages */
|
|
220
237
|
adminPages?: Array<{ path: string; label?: string; icon?: string }>;
|
|
221
238
|
/** Dashboard widgets */
|
|
222
239
|
adminWidgets?: Array<{ id: string; title?: string; size?: string }>;
|
|
240
|
+
/** Settings schema for the auto-generated admin settings form */
|
|
241
|
+
settingsSchema?: Record<string, SettingField>;
|
|
223
242
|
/** Portable Text block types contributed to the editor (declarative Block Kit) */
|
|
224
243
|
portableTextBlocks?: PortableTextBlockConfig[];
|
|
225
244
|
/** Field widget types contributed for schema-field editing UIs */
|
|
@@ -305,16 +324,8 @@ export interface RuntimeDependencies {
|
|
|
305
324
|
/** Media provider entries from virtual module */
|
|
306
325
|
mediaProviderEntries?: MediaProviderEntry[];
|
|
307
326
|
sandboxedPluginEntries: SandboxedPluginEntry[];
|
|
308
|
-
/** Factory function
|
|
309
|
-
createSandboxRunner:
|
|
310
|
-
| ((opts: {
|
|
311
|
-
db: Kysely<Database>;
|
|
312
|
-
mediaStorage?: {
|
|
313
|
-
upload(options: { key: string; body: Uint8Array; contentType: string }): Promise<unknown>;
|
|
314
|
-
delete(key: string): Promise<unknown>;
|
|
315
|
-
};
|
|
316
|
-
}) => SandboxRunner)
|
|
317
|
-
| null;
|
|
327
|
+
/** Factory function supplied by the active platform adapter. */
|
|
328
|
+
createSandboxRunner: SandboxRunnerFactory | null;
|
|
318
329
|
}
|
|
319
330
|
|
|
320
331
|
/**
|
|
@@ -350,7 +361,12 @@ export interface EmDashRuntimeParts {
|
|
|
350
361
|
db: Kysely<Database>;
|
|
351
362
|
getDb?: () => Kysely<Database>;
|
|
352
363
|
storage?: Storage;
|
|
353
|
-
siteInfo?: {
|
|
364
|
+
siteInfo?: {
|
|
365
|
+
siteName?: string;
|
|
366
|
+
siteUrl?: string;
|
|
367
|
+
locale?: string;
|
|
368
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
369
|
+
};
|
|
354
370
|
};
|
|
355
371
|
runtimeDeps: RuntimeDependencies;
|
|
356
372
|
pipelineRef: { current: HookPipeline };
|
|
@@ -385,18 +401,42 @@ const DB_HOLDER_KEY = Symbol.for("emdash:db-cache");
|
|
|
385
401
|
interface DbHolder {
|
|
386
402
|
cache: Map<string, Kysely<Database>>;
|
|
387
403
|
lock: InitLock;
|
|
404
|
+
/**
|
|
405
|
+
* Recent migration failures, keyed like `cache`. A failed migration is
|
|
406
|
+
* near-certain to fail again immediately (schema conflict, broken
|
|
407
|
+
* migration), and without this every request in a warm isolate would
|
|
408
|
+
* re-attempt it — on Workers with Postgres that stampedes the database
|
|
409
|
+
* through the migration advisory lock (#1744). Entries expire after
|
|
410
|
+
* DB_INIT_FAILURE_BACKOFF_MS; a successful init clears them.
|
|
411
|
+
*/
|
|
412
|
+
failures: Map<string, { at: number; message: string }>;
|
|
388
413
|
}
|
|
389
414
|
const globalSymbolStore = globalThis as Record<symbol, unknown>;
|
|
390
415
|
function getDbHolder(): DbHolder {
|
|
391
416
|
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot, written only below
|
|
392
417
|
let holder = globalSymbolStore[DB_HOLDER_KEY] as DbHolder | undefined;
|
|
393
418
|
if (!holder) {
|
|
394
|
-
holder = {
|
|
419
|
+
holder = {
|
|
420
|
+
cache: new Map<string, Kysely<Database>>(),
|
|
421
|
+
lock: createInitLock(),
|
|
422
|
+
failures: new Map(),
|
|
423
|
+
};
|
|
395
424
|
globalSymbolStore[DB_HOLDER_KEY] = holder;
|
|
396
425
|
}
|
|
426
|
+
// A holder created by an older copy of this module (dev-server HMR keeps
|
|
427
|
+
// globalThis across reloads) may predate the failures map.
|
|
428
|
+
holder.failures ??= new Map();
|
|
397
429
|
return holder;
|
|
398
430
|
}
|
|
399
431
|
|
|
432
|
+
/**
|
|
433
|
+
* After a database init fails (migrations threw), skip re-attempting for
|
|
434
|
+
* this long. Cold isolates still get one attempt each, so a transient
|
|
435
|
+
* failure heals on its own; a persistently failing migration is retried at
|
|
436
|
+
* most once per backoff window per isolate instead of on every request.
|
|
437
|
+
*/
|
|
438
|
+
const DB_INIT_FAILURE_BACKOFF_MS = 30_000;
|
|
439
|
+
|
|
400
440
|
/**
|
|
401
441
|
* Auto-seed runs at most once per isolate per database. Its lock + "done" set
|
|
402
442
|
* live on globalThis (same bundler-duplication reasoning as the db cache) so a
|
|
@@ -441,7 +481,9 @@ const marketplaceManifestCache = new Map<
|
|
|
441
481
|
admin?: {
|
|
442
482
|
pages?: PluginAdminPage[];
|
|
443
483
|
widgets?: PluginDashboardWidget[];
|
|
484
|
+
settingsSchema?: Record<string, SettingField>;
|
|
444
485
|
};
|
|
486
|
+
mcp?: PluginMcpManifestConfig;
|
|
445
487
|
}
|
|
446
488
|
>();
|
|
447
489
|
/** Route metadata for sandboxed plugins: pluginId -> routeName -> RouteMeta */
|
|
@@ -508,7 +550,12 @@ export class EmDashRuntime {
|
|
|
508
550
|
db: Kysely<Database>;
|
|
509
551
|
getDb?: () => Kysely<Database>;
|
|
510
552
|
storage?: Storage;
|
|
511
|
-
siteInfo?: {
|
|
553
|
+
siteInfo?: {
|
|
554
|
+
siteName?: string;
|
|
555
|
+
siteUrl?: string;
|
|
556
|
+
locale?: string;
|
|
557
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
558
|
+
};
|
|
512
559
|
};
|
|
513
560
|
/** Dependencies needed for exclusive hook resolution */
|
|
514
561
|
private runtimeDeps: RuntimeDependencies;
|
|
@@ -628,6 +675,9 @@ export class EmDashRuntime {
|
|
|
628
675
|
console.error("[cleanup] System cleanup failed:", error);
|
|
629
676
|
}
|
|
630
677
|
|
|
678
|
+
// Never throws; no-op unless scheduled backups are enabled and due.
|
|
679
|
+
await maybeRunScheduledBackup(this.db, this.storage ?? undefined);
|
|
680
|
+
|
|
631
681
|
return { published };
|
|
632
682
|
}
|
|
633
683
|
|
|
@@ -686,12 +736,11 @@ export class EmDashRuntime {
|
|
|
686
736
|
// pipelineFactoryOptions), so the merge only adds emailPipeline.
|
|
687
737
|
newPipeline.setContextFactory({ emailPipeline: this.email });
|
|
688
738
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
739
|
+
newPipeline.setContextFactory({
|
|
740
|
+
// Plugin schedules remain database-backed when no in-process scheduler
|
|
741
|
+
// exists; an external trigger is responsible for invoking due tasks.
|
|
742
|
+
cronReschedule: () => this.cronScheduler?.reschedule(),
|
|
743
|
+
});
|
|
695
744
|
|
|
696
745
|
// Update the email pipeline to use the new hook pipeline
|
|
697
746
|
if (this.email) {
|
|
@@ -838,6 +887,7 @@ export class EmDashRuntime {
|
|
|
838
887
|
id: bundle.manifest.id,
|
|
839
888
|
version: bundle.manifest.version,
|
|
840
889
|
admin: bundle.manifest.admin,
|
|
890
|
+
mcp: bundle.manifest.mcp,
|
|
841
891
|
});
|
|
842
892
|
|
|
843
893
|
// Cache route metadata from manifest for auth decisions
|
|
@@ -845,7 +895,7 @@ export class EmDashRuntime {
|
|
|
845
895
|
const routeMetaMap = new Map<string, RouteMeta>();
|
|
846
896
|
for (const entry of bundle.manifest.routes) {
|
|
847
897
|
const normalized = normalizeManifestRoute(entry);
|
|
848
|
-
routeMetaMap.set(normalized.name,
|
|
898
|
+
routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
|
|
849
899
|
}
|
|
850
900
|
sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
|
|
851
901
|
} else {
|
|
@@ -952,12 +1002,13 @@ export class EmDashRuntime {
|
|
|
952
1002
|
id: bundle.manifest.id,
|
|
953
1003
|
version: bundle.manifest.version,
|
|
954
1004
|
admin: bundle.manifest.admin,
|
|
1005
|
+
mcp: bundle.manifest.mcp,
|
|
955
1006
|
});
|
|
956
1007
|
if (bundle.manifest.routes.length > 0) {
|
|
957
1008
|
const routeMetaMap = new Map<string, RouteMeta>();
|
|
958
1009
|
for (const entry of bundle.manifest.routes) {
|
|
959
1010
|
const normalized = normalizeManifestRoute(entry);
|
|
960
|
-
routeMetaMap.set(normalized.name,
|
|
1011
|
+
routeMetaMap.set(normalized.name, buildRouteMeta(normalized));
|
|
961
1012
|
}
|
|
962
1013
|
sandboxedRouteMetaCache.set(pluginId, routeMetaMap);
|
|
963
1014
|
} else {
|
|
@@ -1001,6 +1052,7 @@ export class EmDashRuntime {
|
|
|
1001
1052
|
size:
|
|
1002
1053
|
w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
|
|
1003
1054
|
})),
|
|
1055
|
+
settingsSchema: bundle.manifest.admin?.settingsSchema,
|
|
1004
1056
|
});
|
|
1005
1057
|
newPlugins.push(adapted);
|
|
1006
1058
|
this.allPipelinePlugins.push(adapted);
|
|
@@ -1078,7 +1130,14 @@ export class EmDashRuntime {
|
|
|
1078
1130
|
const storage = EmDashRuntime.getStorage(deps);
|
|
1079
1131
|
|
|
1080
1132
|
let pluginStates: Map<string, string> = new Map();
|
|
1081
|
-
let siteInfo:
|
|
1133
|
+
let siteInfo:
|
|
1134
|
+
| {
|
|
1135
|
+
siteName?: string;
|
|
1136
|
+
siteUrl?: string;
|
|
1137
|
+
locale?: string;
|
|
1138
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
1139
|
+
}
|
|
1140
|
+
| undefined;
|
|
1082
1141
|
// "Already set up" by default so a read failure (e.g. tables absent on a
|
|
1083
1142
|
// pre-migration db) skips seeding rather than seeding a half-built db.
|
|
1084
1143
|
let seedGate = { collectionCount: 1, setupDone: true };
|
|
@@ -1121,6 +1180,10 @@ export class EmDashRuntime {
|
|
|
1121
1180
|
siteName: siteOpts.get("emdash:site_title") ?? undefined,
|
|
1122
1181
|
siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
|
|
1123
1182
|
locale: siteOpts.get("emdash:locale") ?? undefined,
|
|
1183
|
+
// trailingSlash is a build-time Astro routing decision, not a
|
|
1184
|
+
// user-editable setting, so it comes from the Astro config
|
|
1185
|
+
// (virtual:emdash/config), not the options table.
|
|
1186
|
+
trailingSlash: virtualConfig?.trailingSlash,
|
|
1124
1187
|
};
|
|
1125
1188
|
};
|
|
1126
1189
|
|
|
@@ -1358,7 +1421,7 @@ export class EmDashRuntime {
|
|
|
1358
1421
|
|
|
1359
1422
|
// Load sandboxed plugins (build-time, sandbox runner path)
|
|
1360
1423
|
const sandboxedPlugins = await phase("rt.sandbox", "Sandboxed plugins", () =>
|
|
1361
|
-
EmDashRuntime.loadSandboxedPlugins(deps, db, storage),
|
|
1424
|
+
EmDashRuntime.loadSandboxedPlugins(deps, db, storage, siteInfo),
|
|
1362
1425
|
);
|
|
1363
1426
|
|
|
1364
1427
|
// Cold-start: load marketplace- and registry-installed plugins from
|
|
@@ -1376,6 +1439,7 @@ export class EmDashRuntime {
|
|
|
1376
1439
|
storage,
|
|
1377
1440
|
deps,
|
|
1378
1441
|
sandboxedPlugins,
|
|
1442
|
+
siteInfo,
|
|
1379
1443
|
),
|
|
1380
1444
|
),
|
|
1381
1445
|
);
|
|
@@ -1391,6 +1455,7 @@ export class EmDashRuntime {
|
|
|
1391
1455
|
storage,
|
|
1392
1456
|
deps,
|
|
1393
1457
|
sandboxedPlugins,
|
|
1458
|
+
siteInfo,
|
|
1394
1459
|
),
|
|
1395
1460
|
),
|
|
1396
1461
|
);
|
|
@@ -1459,6 +1524,12 @@ export class EmDashRuntime {
|
|
|
1459
1524
|
await phase("rt.cron", "Cron init (recovery deferred post-response)", async () => {
|
|
1460
1525
|
try {
|
|
1461
1526
|
cronExecutor = new CronExecutor(resolveDb, invokeCronHook);
|
|
1527
|
+
// Plugin schedules are always database-backed. On long-lived runtimes this
|
|
1528
|
+
// callback also wakes the timer; on Cloudflare the external Cron Trigger
|
|
1529
|
+
// drives execution, so rescheduling is intentionally a no-op.
|
|
1530
|
+
pipeline.setContextFactory({
|
|
1531
|
+
cronReschedule: () => cronScheduler?.reschedule(),
|
|
1532
|
+
});
|
|
1462
1533
|
|
|
1463
1534
|
// Recover stale locks from previous crashes. Pure bookkeeping
|
|
1464
1535
|
// against the _emdash_cron_tasks table — no request needs the
|
|
@@ -1513,11 +1584,8 @@ export class EmDashRuntime {
|
|
|
1513
1584
|
// by runSystemCleanup. This catches unexpected errors.
|
|
1514
1585
|
console.error("[cleanup] System cleanup failed:", error);
|
|
1515
1586
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
// Add cron reschedule callback (merges with existing factory options)
|
|
1519
|
-
pipeline.setContextFactory({
|
|
1520
|
-
cronReschedule: () => cronScheduler?.reschedule(),
|
|
1587
|
+
// Never throws; no-op unless scheduled backups are enabled and due.
|
|
1588
|
+
await maybeRunScheduledBackup(db, storage ?? undefined);
|
|
1521
1589
|
});
|
|
1522
1590
|
|
|
1523
1591
|
// start() is void on the timer scheduler but the interface
|
|
@@ -1623,14 +1691,52 @@ export class EmDashRuntime {
|
|
|
1623
1691
|
// owner's init still completes and populates the cache. Net: a stale
|
|
1624
1692
|
// lock is reclaimed after a deadline.
|
|
1625
1693
|
const holder = getDbHolder();
|
|
1694
|
+
|
|
1695
|
+
const throwIfBackingOff = () => {
|
|
1696
|
+
const failure = holder.failures.get(cacheKey);
|
|
1697
|
+
if (!failure) return;
|
|
1698
|
+
if (Date.now() - failure.at < DB_INIT_FAILURE_BACKOFF_MS) {
|
|
1699
|
+
throw new Error(
|
|
1700
|
+
`Database initialization is backing off after a recent migration failure: ${failure.message}`,
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
// Expired — drop it so the map only ever holds active backoffs.
|
|
1704
|
+
holder.failures.delete(cacheKey);
|
|
1705
|
+
};
|
|
1706
|
+
throwIfBackingOff();
|
|
1707
|
+
|
|
1626
1708
|
return initWithLock(
|
|
1627
1709
|
holder.lock,
|
|
1628
1710
|
() => holder.cache.get(cacheKey),
|
|
1629
1711
|
async (isCurrentClaim) => {
|
|
1712
|
+
// Re-check under the lock: a request that entered the wait loop
|
|
1713
|
+
// before the failure was recorded must not immediately re-run
|
|
1714
|
+
// the failing migration when the lock frees up.
|
|
1715
|
+
throwIfBackingOff();
|
|
1716
|
+
|
|
1630
1717
|
const dialect = deps.createDialect(dbConfig.config);
|
|
1631
1718
|
const db = new Kysely<Database>({ dialect, log: kyselyLogOption() });
|
|
1632
1719
|
|
|
1633
|
-
|
|
1720
|
+
try {
|
|
1721
|
+
await runMigrations(db);
|
|
1722
|
+
} catch (error) {
|
|
1723
|
+
// Timing out behind another instance's in-flight migrations
|
|
1724
|
+
// is not a failure of OUR migration — the holder may just be
|
|
1725
|
+
// slow. Don't back off for it: the next request waits again
|
|
1726
|
+
// and init recovers the moment the holder finishes.
|
|
1727
|
+
if (!(error instanceof ConcurrentMigrationTimeoutError)) {
|
|
1728
|
+
holder.failures.set(cacheKey, {
|
|
1729
|
+
at: Date.now(),
|
|
1730
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
// Every attempt builds a fresh dialect/pool; close it or each
|
|
1734
|
+
// failed init leaks its connection(s) (#1744 observed these
|
|
1735
|
+
// piling up as idle Postgres connections).
|
|
1736
|
+
await db.destroy().catch(() => {});
|
|
1737
|
+
throw error;
|
|
1738
|
+
}
|
|
1739
|
+
holder.failures.delete(cacheKey);
|
|
1634
1740
|
|
|
1635
1741
|
// Note: legacy installs may carry a stray `emdash:manifest_cache`
|
|
1636
1742
|
// row in the options table from versions that persisted a JSON
|
|
@@ -1739,6 +1845,7 @@ export class EmDashRuntime {
|
|
|
1739
1845
|
storage: entry.storage as never,
|
|
1740
1846
|
adminPages,
|
|
1741
1847
|
adminWidgets,
|
|
1848
|
+
settingsSchema: entry.settingsSchema,
|
|
1742
1849
|
portableTextBlocks: entry.portableTextBlocks,
|
|
1743
1850
|
fieldWidgets: entry.fieldWidgets,
|
|
1744
1851
|
});
|
|
@@ -1760,6 +1867,12 @@ export class EmDashRuntime {
|
|
|
1760
1867
|
deps: RuntimeDependencies,
|
|
1761
1868
|
db: Kysely<Database>,
|
|
1762
1869
|
mediaStorage?: Storage | null,
|
|
1870
|
+
siteInfo?: {
|
|
1871
|
+
siteName?: string;
|
|
1872
|
+
siteUrl?: string;
|
|
1873
|
+
locale?: string;
|
|
1874
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
1875
|
+
},
|
|
1763
1876
|
): Promise<Map<string, SandboxedPluginInstance>> {
|
|
1764
1877
|
// Return cached plugins if already loaded
|
|
1765
1878
|
if (sandboxedPluginCache.size > 0) {
|
|
@@ -1773,20 +1886,25 @@ export class EmDashRuntime {
|
|
|
1773
1886
|
|
|
1774
1887
|
// Create sandbox runner if not exists
|
|
1775
1888
|
if (!sandboxRunner && deps.createSandboxRunner) {
|
|
1776
|
-
sandboxRunner = deps.createSandboxRunner(
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1889
|
+
sandboxRunner = deps.createSandboxRunner(
|
|
1890
|
+
createSandboxRunnerOptions(
|
|
1891
|
+
{
|
|
1892
|
+
db,
|
|
1893
|
+
mediaStorage: mediaStorage
|
|
1894
|
+
? {
|
|
1895
|
+
upload: (opts) =>
|
|
1896
|
+
mediaStorage.upload({
|
|
1897
|
+
key: opts.key,
|
|
1898
|
+
body: opts.body,
|
|
1899
|
+
contentType: opts.contentType,
|
|
1900
|
+
}),
|
|
1901
|
+
delete: (key) => mediaStorage.delete(key),
|
|
1902
|
+
}
|
|
1903
|
+
: undefined,
|
|
1904
|
+
},
|
|
1905
|
+
siteInfo,
|
|
1906
|
+
),
|
|
1907
|
+
);
|
|
1790
1908
|
}
|
|
1791
1909
|
|
|
1792
1910
|
if (!sandboxRunner) {
|
|
@@ -1834,6 +1952,7 @@ export class EmDashRuntime {
|
|
|
1834
1952
|
hooks: [],
|
|
1835
1953
|
routes: [],
|
|
1836
1954
|
admin: {},
|
|
1955
|
+
mcp: entry.mcp,
|
|
1837
1956
|
};
|
|
1838
1957
|
|
|
1839
1958
|
const plugin = await sandboxRunner.load(manifest, entry.code);
|
|
@@ -1869,22 +1988,33 @@ export class EmDashRuntime {
|
|
|
1869
1988
|
storage: Storage,
|
|
1870
1989
|
deps: RuntimeDependencies,
|
|
1871
1990
|
cache: Map<string, SandboxedPluginInstance>,
|
|
1991
|
+
siteInfo?: {
|
|
1992
|
+
siteName?: string;
|
|
1993
|
+
siteUrl?: string;
|
|
1994
|
+
locale?: string;
|
|
1995
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
1996
|
+
},
|
|
1872
1997
|
): Promise<void> {
|
|
1873
1998
|
// Ensure sandbox runner exists with media storage wired up.
|
|
1874
1999
|
// (storage here is the media Storage adapter from the runtime.)
|
|
1875
2000
|
if (!sandboxRunner && deps.createSandboxRunner) {
|
|
1876
|
-
sandboxRunner = deps.createSandboxRunner(
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
2001
|
+
sandboxRunner = deps.createSandboxRunner(
|
|
2002
|
+
createSandboxRunnerOptions(
|
|
2003
|
+
{
|
|
2004
|
+
db,
|
|
2005
|
+
mediaStorage: {
|
|
2006
|
+
upload: (opts) =>
|
|
2007
|
+
storage.upload({
|
|
2008
|
+
key: opts.key,
|
|
2009
|
+
body: opts.body,
|
|
2010
|
+
contentType: opts.contentType,
|
|
2011
|
+
}),
|
|
2012
|
+
delete: (key) => storage.delete(key),
|
|
2013
|
+
},
|
|
2014
|
+
},
|
|
2015
|
+
siteInfo,
|
|
2016
|
+
),
|
|
2017
|
+
);
|
|
1888
2018
|
}
|
|
1889
2019
|
// In sandbox bypass mode, marketplace plugins are loaded in-process
|
|
1890
2020
|
// BEFORE pipeline creation by EmDashRuntime.create(). Skip here.
|
|
@@ -1931,6 +2061,7 @@ export class EmDashRuntime {
|
|
|
1931
2061
|
id: bundle.manifest.id,
|
|
1932
2062
|
version: bundle.manifest.version,
|
|
1933
2063
|
admin: bundle.manifest.admin,
|
|
2064
|
+
mcp: bundle.manifest.mcp,
|
|
1934
2065
|
});
|
|
1935
2066
|
|
|
1936
2067
|
// Cache route metadata from manifest for auth decisions
|
|
@@ -1938,7 +2069,7 @@ export class EmDashRuntime {
|
|
|
1938
2069
|
const routeMeta = new Map<string, RouteMeta>();
|
|
1939
2070
|
for (const entry of bundle.manifest.routes) {
|
|
1940
2071
|
const normalized = normalizeManifestRoute(entry);
|
|
1941
|
-
routeMeta.set(normalized.name,
|
|
2072
|
+
routeMeta.set(normalized.name, buildRouteMeta(normalized));
|
|
1942
2073
|
}
|
|
1943
2074
|
sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
|
|
1944
2075
|
}
|
|
@@ -2002,12 +2133,13 @@ export class EmDashRuntime {
|
|
|
2002
2133
|
id: bundle.manifest.id,
|
|
2003
2134
|
version: bundle.manifest.version,
|
|
2004
2135
|
admin: bundle.manifest.admin,
|
|
2136
|
+
mcp: bundle.manifest.mcp,
|
|
2005
2137
|
});
|
|
2006
2138
|
if (bundle.manifest.routes.length > 0) {
|
|
2007
2139
|
const routeMeta = new Map<string, RouteMeta>();
|
|
2008
2140
|
for (const entry of bundle.manifest.routes) {
|
|
2009
2141
|
const normalized = normalizeManifestRoute(entry);
|
|
2010
|
-
routeMeta.set(normalized.name,
|
|
2142
|
+
routeMeta.set(normalized.name, buildRouteMeta(normalized));
|
|
2011
2143
|
}
|
|
2012
2144
|
sandboxedRouteMetaCache.set(plugin.pluginId, routeMeta);
|
|
2013
2145
|
}
|
|
@@ -2037,6 +2169,7 @@ export class EmDashRuntime {
|
|
|
2037
2169
|
size:
|
|
2038
2170
|
w.size === "full" || w.size === "half" || w.size === "third" ? w.size : undefined,
|
|
2039
2171
|
})),
|
|
2172
|
+
settingsSchema: bundle.manifest.admin?.settingsSchema,
|
|
2040
2173
|
});
|
|
2041
2174
|
resolved.push(adapted);
|
|
2042
2175
|
console.log(
|
|
@@ -2520,7 +2653,7 @@ export class EmDashRuntime {
|
|
|
2520
2653
|
...r.data,
|
|
2521
2654
|
item: { ...item, data: mergedData, liveData },
|
|
2522
2655
|
},
|
|
2523
|
-
}
|
|
2656
|
+
};
|
|
2524
2657
|
} catch (error) {
|
|
2525
2658
|
// Non-fatal — fall back to the unhydrated response. Log so the
|
|
2526
2659
|
// failure isn't completely silent (the response will look stale
|
|
@@ -2540,6 +2673,7 @@ export class EmDashRuntime {
|
|
|
2540
2673
|
bylines?: Array<{ bylineId: string; roleLabel?: string | null }>;
|
|
2541
2674
|
locale?: string;
|
|
2542
2675
|
translationOf?: string;
|
|
2676
|
+
taxonomies?: Record<string, string[]>;
|
|
2543
2677
|
},
|
|
2544
2678
|
) {
|
|
2545
2679
|
// Run beforeSave hooks (trusted plugins)
|
|
@@ -2604,6 +2738,7 @@ export class EmDashRuntime {
|
|
|
2604
2738
|
canonical?: string | null;
|
|
2605
2739
|
noIndex?: boolean;
|
|
2606
2740
|
};
|
|
2741
|
+
taxonomies?: Record<string, string[]>;
|
|
2607
2742
|
publishedAt?: string | null;
|
|
2608
2743
|
locale?: string;
|
|
2609
2744
|
/** Skip revision creation (used by autosave) */
|
|
@@ -2713,13 +2848,14 @@ export class EmDashRuntime {
|
|
|
2713
2848
|
authorId: bodyWithoutRev.authorId ?? undefined,
|
|
2714
2849
|
});
|
|
2715
2850
|
|
|
2716
|
-
// Update entry to point to new draft (metadata only, not data columns)
|
|
2851
|
+
// Update entry to point to new draft (metadata only, not data columns).
|
|
2852
|
+
// No updated_at stamp: draft staging leaves live content untouched,
|
|
2853
|
+
// so public "last modified" consumers must not see a change (#2143).
|
|
2717
2854
|
validateIdentifier(collection, "collection");
|
|
2718
2855
|
const tableName = `ec_${collection}`;
|
|
2719
2856
|
await sql`
|
|
2720
2857
|
UPDATE ${sql.ref(tableName)}
|
|
2721
|
-
SET draft_revision_id = ${revision.id}
|
|
2722
|
-
updated_at = ${new Date().toISOString()}
|
|
2858
|
+
SET draft_revision_id = ${revision.id}
|
|
2723
2859
|
WHERE id = ${resolvedId}
|
|
2724
2860
|
`.execute(this.db);
|
|
2725
2861
|
draftStorageChanged = true;
|
|
@@ -3111,7 +3247,10 @@ export class EmDashRuntime {
|
|
|
3111
3247
|
|
|
3112
3248
|
// Revision-capable collections: restore is "make this revision the
|
|
3113
3249
|
// current draft". The live row's data columns are left untouched
|
|
3114
|
-
// (only `draft_revision_id`
|
|
3250
|
+
// (only `draft_revision_id` changes — no `updated_at` stamp, since
|
|
3251
|
+
// restoring to draft is the same kind of draft-only staging as
|
|
3252
|
+
// Save/Autosave and must not register a phantom modification for
|
|
3253
|
+
// sitemap <lastmod> / JSON-LD dateModified, #2143). The caller
|
|
3115
3254
|
// must then `content_publish` to promote the restored draft to
|
|
3116
3255
|
// live, matching the documented tool contract.
|
|
3117
3256
|
try {
|
|
@@ -3126,8 +3265,7 @@ export class EmDashRuntime {
|
|
|
3126
3265
|
const tableName = `ec_${revision.collection}`;
|
|
3127
3266
|
await sql`
|
|
3128
3267
|
UPDATE ${sql.ref(tableName)}
|
|
3129
|
-
SET draft_revision_id = ${newDraft.id}
|
|
3130
|
-
updated_at = ${new Date().toISOString()}
|
|
3268
|
+
SET draft_revision_id = ${newDraft.id}
|
|
3131
3269
|
WHERE id = ${revision.entryId}
|
|
3132
3270
|
`.execute(this.db);
|
|
3133
3271
|
|
|
@@ -3212,7 +3350,7 @@ export class EmDashRuntime {
|
|
|
3212
3350
|
if (trustedPlugin) {
|
|
3213
3351
|
const route = trustedPlugin.routes[routeKey];
|
|
3214
3352
|
if (!route) return null;
|
|
3215
|
-
return
|
|
3353
|
+
return buildRouteMeta(route);
|
|
3216
3354
|
}
|
|
3217
3355
|
|
|
3218
3356
|
// Check sandboxed plugin route metadata cache
|
|
@@ -3246,6 +3384,18 @@ export class EmDashRuntime {
|
|
|
3246
3384
|
return null;
|
|
3247
3385
|
}
|
|
3248
3386
|
|
|
3387
|
+
/**
|
|
3388
|
+
* Resolve the settings schema for a runtime-installed (marketplace or
|
|
3389
|
+
* registry) plugin from its cached manifest. Returns `{}` for a known
|
|
3390
|
+
* plugin without a schema and `null` for unknown plugins, matching the
|
|
3391
|
+
* contract of `getPluginSettingsSchema` for build-time plugins.
|
|
3392
|
+
*/
|
|
3393
|
+
getRuntimePluginSettingsSchema(pluginId: string): Record<string, SettingField> | null {
|
|
3394
|
+
const meta = marketplaceManifestCache.get(pluginId);
|
|
3395
|
+
if (!meta) return null;
|
|
3396
|
+
return meta.admin?.settingsSchema ?? {};
|
|
3397
|
+
}
|
|
3398
|
+
|
|
3249
3399
|
async handlePluginApiRoute(pluginId: string, _method: string, path: string, request: Request) {
|
|
3250
3400
|
if (!this.isPluginEnabled(pluginId)) {
|
|
3251
3401
|
return {
|
|
@@ -3259,9 +3409,9 @@ export class EmDashRuntime {
|
|
|
3259
3409
|
const trustedPlugin = this.configuredPlugins.find((p) => p.id === pluginId);
|
|
3260
3410
|
if (trustedPlugin && this.enabledPlugins.has(trustedPlugin.id)) {
|
|
3261
3411
|
const routeRegistry = new PluginRouteRegistry({
|
|
3262
|
-
|
|
3263
|
-
storage: this.storage ?? undefined,
|
|
3412
|
+
...this.pipelineFactoryOptions,
|
|
3264
3413
|
emailPipeline: this.email ?? undefined,
|
|
3414
|
+
cronReschedule: () => this.cronScheduler?.reschedule(),
|
|
3265
3415
|
trustedProxyHeaders: getTrustedProxyHeaders(this.config),
|
|
3266
3416
|
});
|
|
3267
3417
|
routeRegistry.register(trustedPlugin);
|
|
@@ -3290,6 +3440,168 @@ export class EmDashRuntime {
|
|
|
3290
3440
|
};
|
|
3291
3441
|
}
|
|
3292
3442
|
|
|
3443
|
+
async getPluginMcpTools(pluginId?: string) {
|
|
3444
|
+
const tools: Array<{
|
|
3445
|
+
pluginId: string;
|
|
3446
|
+
name: string;
|
|
3447
|
+
description: string;
|
|
3448
|
+
route: string;
|
|
3449
|
+
permission: string;
|
|
3450
|
+
destructive: boolean;
|
|
3451
|
+
inputSchema: z.ZodType;
|
|
3452
|
+
outputSchema?: z.ZodType;
|
|
3453
|
+
}> = [];
|
|
3454
|
+
const seen = new Set<string>();
|
|
3455
|
+
|
|
3456
|
+
for (const plugin of this.configuredPlugins) {
|
|
3457
|
+
if (pluginId && plugin.id !== pluginId) continue;
|
|
3458
|
+
for (const [name, tool] of Object.entries(plugin.mcp?.tools ?? {})) {
|
|
3459
|
+
const route = plugin.routes[tool.route];
|
|
3460
|
+
if (!route || route.public || !route.permission || !(route.permission in Permissions))
|
|
3461
|
+
continue;
|
|
3462
|
+
const key = `${plugin.id}__${name}`;
|
|
3463
|
+
if (seen.has(key)) continue;
|
|
3464
|
+
seen.add(key);
|
|
3465
|
+
tools.push({
|
|
3466
|
+
pluginId: plugin.id,
|
|
3467
|
+
name,
|
|
3468
|
+
description: tool.description,
|
|
3469
|
+
route: tool.route,
|
|
3470
|
+
permission: route.permission,
|
|
3471
|
+
destructive: tool.destructive ?? false,
|
|
3472
|
+
inputSchema: tool.input,
|
|
3473
|
+
outputSchema: tool.output,
|
|
3474
|
+
});
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
|
|
3478
|
+
const addManifestTools = (id: string, mcp: PluginMcpManifestConfig | undefined) => {
|
|
3479
|
+
if (pluginId && id !== pluginId) return;
|
|
3480
|
+
for (const tool of mcp?.tools ?? []) {
|
|
3481
|
+
const key = `${id}__${tool.name}`;
|
|
3482
|
+
const routeMeta = this.getPluginRouteMeta(id, tool.route);
|
|
3483
|
+
if (
|
|
3484
|
+
seen.has(key) ||
|
|
3485
|
+
!routeMeta ||
|
|
3486
|
+
routeMeta.public ||
|
|
3487
|
+
routeMeta.permission !== tool.permission ||
|
|
3488
|
+
!(tool.permission in Permissions)
|
|
3489
|
+
) {
|
|
3490
|
+
continue;
|
|
3491
|
+
}
|
|
3492
|
+
seen.add(key);
|
|
3493
|
+
tools.push({
|
|
3494
|
+
pluginId: id,
|
|
3495
|
+
name: tool.name,
|
|
3496
|
+
description: tool.description,
|
|
3497
|
+
route: tool.route,
|
|
3498
|
+
permission: tool.permission,
|
|
3499
|
+
destructive: tool.destructive,
|
|
3500
|
+
inputSchema: z.fromJSONSchema({ ...tool.inputSchema }),
|
|
3501
|
+
outputSchema: tool.outputSchema ? z.fromJSONSchema({ ...tool.outputSchema }) : undefined,
|
|
3502
|
+
});
|
|
3503
|
+
}
|
|
3504
|
+
};
|
|
3505
|
+
|
|
3506
|
+
for (const entry of this.sandboxedPluginEntries) addManifestTools(entry.id, entry.mcp);
|
|
3507
|
+
for (const [id, manifest] of marketplaceManifestCache) addManifestTools(id, manifest.mcp);
|
|
3508
|
+
|
|
3509
|
+
return tools;
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3512
|
+
async getEnabledPluginMcpTools() {
|
|
3513
|
+
const [tools, states] = await Promise.all([
|
|
3514
|
+
this.getPluginMcpTools(),
|
|
3515
|
+
new PluginStateRepository(this.db).getAll(),
|
|
3516
|
+
]);
|
|
3517
|
+
const stateByPlugin = new Map(states.map((state) => [state.pluginId, state]));
|
|
3518
|
+
return tools.filter((tool) => {
|
|
3519
|
+
const state = stateByPlugin.get(tool.pluginId);
|
|
3520
|
+
if (
|
|
3521
|
+
!state?.mcpToolsEnabled ||
|
|
3522
|
+
state.status !== "active" ||
|
|
3523
|
+
!this.isPluginEnabled(tool.pluginId)
|
|
3524
|
+
) {
|
|
3525
|
+
return false;
|
|
3526
|
+
}
|
|
3527
|
+
const consented = state.mcpToolsConsent;
|
|
3528
|
+
return consented === this.serializePluginMcpConsent(tools, tool.pluginId);
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3532
|
+
serializePluginMcpConsent(
|
|
3533
|
+
tools: Awaited<ReturnType<EmDashRuntime["getPluginMcpTools"]>>,
|
|
3534
|
+
pluginId: string,
|
|
3535
|
+
): string {
|
|
3536
|
+
return JSON.stringify(
|
|
3537
|
+
tools
|
|
3538
|
+
.filter((tool) => tool.pluginId === pluginId)
|
|
3539
|
+
.map((tool) => ({
|
|
3540
|
+
name: tool.name,
|
|
3541
|
+
description: tool.description,
|
|
3542
|
+
route: tool.route,
|
|
3543
|
+
permission: tool.permission,
|
|
3544
|
+
destructive: tool.destructive,
|
|
3545
|
+
inputSchema: z.toJSONSchema(tool.inputSchema, { target: "draft-7" }),
|
|
3546
|
+
...(tool.outputSchema
|
|
3547
|
+
? { outputSchema: z.toJSONSchema(tool.outputSchema, { target: "draft-7" }) }
|
|
3548
|
+
: {}),
|
|
3549
|
+
}))
|
|
3550
|
+
.toSorted((a, b) => a.name.localeCompare(b.name)),
|
|
3551
|
+
);
|
|
3552
|
+
}
|
|
3553
|
+
|
|
3554
|
+
async handlePluginMcpTool(
|
|
3555
|
+
pluginId: string,
|
|
3556
|
+
toolName: string,
|
|
3557
|
+
route: string,
|
|
3558
|
+
input: unknown,
|
|
3559
|
+
actorId: string,
|
|
3560
|
+
request: Request,
|
|
3561
|
+
) {
|
|
3562
|
+
const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
|
|
3563
|
+
const audit = new AuditRepository(this.db);
|
|
3564
|
+
const headers = new Headers(request.headers);
|
|
3565
|
+
headers.delete("content-length");
|
|
3566
|
+
headers.delete("content-encoding");
|
|
3567
|
+
const internalRequest = new Request(request.url, {
|
|
3568
|
+
method: "POST",
|
|
3569
|
+
headers,
|
|
3570
|
+
body: JSON.stringify(input),
|
|
3571
|
+
});
|
|
3572
|
+
const result = await this.handlePluginApiRoute(pluginId, "POST", route, internalRequest);
|
|
3573
|
+
await audit.log({
|
|
3574
|
+
actorId,
|
|
3575
|
+
actorIp: requestMeta.ip ?? undefined,
|
|
3576
|
+
action: "plugin_tool_invoke",
|
|
3577
|
+
resourceType: "plugin_mcp_tool",
|
|
3578
|
+
resourceId: `${pluginId}__${toolName}`,
|
|
3579
|
+
details: { pluginId, tool: toolName, route },
|
|
3580
|
+
status: result.success ? "success" : "failure",
|
|
3581
|
+
});
|
|
3582
|
+
return result;
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
async handlePluginMcpDenied(
|
|
3586
|
+
pluginId: string,
|
|
3587
|
+
toolName: string,
|
|
3588
|
+
route: string,
|
|
3589
|
+
actorId: string,
|
|
3590
|
+
request: Request,
|
|
3591
|
+
reason: string,
|
|
3592
|
+
): Promise<void> {
|
|
3593
|
+
const requestMeta = extractRequestMeta(request, getTrustedProxyHeaders(this.config));
|
|
3594
|
+
await new AuditRepository(this.db).log({
|
|
3595
|
+
actorId,
|
|
3596
|
+
actorIp: requestMeta.ip ?? undefined,
|
|
3597
|
+
action: "plugin_tool_invoke",
|
|
3598
|
+
resourceType: "plugin_mcp_tool",
|
|
3599
|
+
resourceId: `${pluginId}__${toolName}`,
|
|
3600
|
+
details: { pluginId, tool: toolName, route, reason },
|
|
3601
|
+
status: "denied",
|
|
3602
|
+
});
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3293
3605
|
// =========================================================================
|
|
3294
3606
|
// Sandboxed Plugin Helpers
|
|
3295
3607
|
// =========================================================================
|