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
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup handlers — portable content backups, on demand and scheduled.
|
|
3
|
+
*
|
|
4
|
+
* A backup is the snapshot format (see `snapshot.ts`) wrapped in a small
|
|
5
|
+
* envelope: all content (including drafts, scheduled, and trashed entries),
|
|
6
|
+
* schema definitions, taxonomies, menus, widgets, revisions, media metadata,
|
|
7
|
+
* and site settings.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately NOT included:
|
|
10
|
+
* - Users, sessions, credentials, API/OAuth tokens (auth data is neither
|
|
11
|
+
* portable nor safe in a user-downloadable file)
|
|
12
|
+
* - Secrets (`emdash:preview_secret`, plugin config, passkey challenges)
|
|
13
|
+
* - Media binaries (metadata only — the files live in the same bucket the
|
|
14
|
+
* scheduled archives are written to)
|
|
15
|
+
*
|
|
16
|
+
* For full point-in-time database recovery on Cloudflare, D1 Time Travel
|
|
17
|
+
* covers the last 30 days out of the box; these backups complement it with
|
|
18
|
+
* user-holdable, longer-lived archives.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { Kysely } from "kysely";
|
|
22
|
+
|
|
23
|
+
import { OptionsRepository } from "../../database/repositories/options.js";
|
|
24
|
+
import type { Database } from "../../database/types.js";
|
|
25
|
+
import type { Storage } from "../../storage/types.js";
|
|
26
|
+
import { VERSION } from "../../version.js";
|
|
27
|
+
import { ErrorCode } from "../errors.js";
|
|
28
|
+
import type { ApiResult } from "../types.js";
|
|
29
|
+
import { generateSnapshot } from "./snapshot.js";
|
|
30
|
+
|
|
31
|
+
// ── Constants ───────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
/** Storage key prefix for scheduled/manual archives. */
|
|
34
|
+
export const BACKUP_STORAGE_PREFIX = "backups/";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Filename prefix within the backups/ folder. Included in the list() prefix
|
|
38
|
+
* so LocalStorage (which matches directory + filename prefix, not flat keys
|
|
39
|
+
* like S3/R2) finds the archives too.
|
|
40
|
+
*/
|
|
41
|
+
const BACKUP_FILE_PREFIX = "emdash-backup-";
|
|
42
|
+
|
|
43
|
+
/** Options key holding the scheduled-backup settings. */
|
|
44
|
+
export const BACKUP_SETTINGS_KEY = "emdash:backups";
|
|
45
|
+
|
|
46
|
+
/** Options key holding the ISO timestamp of the last scheduled run. */
|
|
47
|
+
const BACKUP_LAST_RUN_KEY = "emdash:backups_last_run";
|
|
48
|
+
|
|
49
|
+
/** Minimum interval between scheduled backups (23h — daily with cron jitter). */
|
|
50
|
+
const SCHEDULED_BACKUP_INTERVAL_MS = 23 * 60 * 60 * 1000;
|
|
51
|
+
|
|
52
|
+
/** Retention bounds for stored archives. */
|
|
53
|
+
export const BACKUP_RETENTION_MIN = 1;
|
|
54
|
+
export const BACKUP_RETENTION_MAX = 30;
|
|
55
|
+
const BACKUP_RETENTION_DEFAULT = 7;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Options-table key prefixes included in backups. Site settings plus the
|
|
59
|
+
* site-identity keys (`emdash:site_title`, `emdash:site_tagline`,
|
|
60
|
+
* `emdash:site_url`). Never widen this to a prefix that can match secrets
|
|
61
|
+
* (`emdash:preview_secret`, `plugin:`, `emdash:passkey_pending:`).
|
|
62
|
+
*/
|
|
63
|
+
const BACKUP_OPTION_PREFIXES = ["site:", "emdash:site_", "emdash:locale"];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Archive filename shape. Strict allowlist — the download/delete routes
|
|
67
|
+
* interpolate this into a storage key, so it must never contain `/` or `..`.
|
|
68
|
+
* The random suffix makes names unguessable (defense in depth on top of the
|
|
69
|
+
* media route's backups/ deny) and avoids same-second collisions.
|
|
70
|
+
*/
|
|
71
|
+
const ARCHIVE_NAME_PATTERN =
|
|
72
|
+
/^emdash-backup-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-[0-9a-f]{8}\.json$/;
|
|
73
|
+
|
|
74
|
+
export function isValidArchiveName(name: string): boolean {
|
|
75
|
+
return ARCHIVE_NAME_PATTERN.test(name);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ── Types ───────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
export interface BackupSettings {
|
|
81
|
+
/** Whether daily scheduled backups to storage are enabled. */
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
/** How many archives to keep in storage (oldest pruned first). */
|
|
84
|
+
retention: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface BackupArchive {
|
|
88
|
+
/** Filename within the backups/ prefix (no path separators). */
|
|
89
|
+
name: string;
|
|
90
|
+
/** Size in bytes. */
|
|
91
|
+
size: number;
|
|
92
|
+
/** Last-modified timestamp (ISO). */
|
|
93
|
+
lastModified: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const DEFAULT_SETTINGS: BackupSettings = {
|
|
97
|
+
enabled: false,
|
|
98
|
+
retention: BACKUP_RETENTION_DEFAULT,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function clampRetention(value: number): number {
|
|
102
|
+
if (!Number.isFinite(value)) return BACKUP_RETENTION_DEFAULT;
|
|
103
|
+
return Math.min(BACKUP_RETENTION_MAX, Math.max(BACKUP_RETENTION_MIN, Math.trunc(value)));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── Export ──────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generate a full content backup as a JSON string.
|
|
110
|
+
*
|
|
111
|
+
* ponytail: the whole backup is materialized in memory. Fine for the sites
|
|
112
|
+
* EmDash targets today; truly huge databases should use `wrangler d1 export`
|
|
113
|
+
* (documented on the backups docs page). Upgrade path: stream table-by-table.
|
|
114
|
+
*/
|
|
115
|
+
export async function generateBackupJson(db: Kysely<Database>): Promise<string> {
|
|
116
|
+
const snapshot = await generateSnapshot(db, {
|
|
117
|
+
includeDrafts: true,
|
|
118
|
+
includeTrashed: true,
|
|
119
|
+
optionPrefixes: BACKUP_OPTION_PREFIXES,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return JSON.stringify({
|
|
123
|
+
format: "emdash-backup",
|
|
124
|
+
formatVersion: 1,
|
|
125
|
+
emdashVersion: VERSION,
|
|
126
|
+
generatedAt: snapshot.generatedAt,
|
|
127
|
+
schema: snapshot.schema,
|
|
128
|
+
tables: snapshot.tables,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Derive the archive filename for a given date (plus a random suffix). */
|
|
133
|
+
export function archiveNameForDate(date: Date): string {
|
|
134
|
+
// 2026-07-09T08:45:12.345Z → emdash-backup-2026-07-09T08-45-12-1a2b3c4d.json
|
|
135
|
+
const stamp = date.toISOString().slice(0, 19).replaceAll(":", "-");
|
|
136
|
+
const suffix = crypto.randomUUID().replaceAll("-", "").slice(0, 8);
|
|
137
|
+
return `emdash-backup-${stamp}-${suffix}.json`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ── Settings ────────────────────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
export async function getBackupSettings(db: Kysely<Database>): Promise<BackupSettings> {
|
|
143
|
+
const options = new OptionsRepository(db);
|
|
144
|
+
const stored = await options.get<Partial<BackupSettings>>(BACKUP_SETTINGS_KEY);
|
|
145
|
+
if (!stored) return { ...DEFAULT_SETTINGS };
|
|
146
|
+
return {
|
|
147
|
+
enabled: stored.enabled === true,
|
|
148
|
+
retention: clampRetention(stored.retention ?? BACKUP_RETENTION_DEFAULT),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function updateBackupSettings(
|
|
153
|
+
db: Kysely<Database>,
|
|
154
|
+
input: { enabled: boolean; retention: number },
|
|
155
|
+
): Promise<ApiResult<BackupSettings>> {
|
|
156
|
+
try {
|
|
157
|
+
const settings: BackupSettings = {
|
|
158
|
+
enabled: input.enabled,
|
|
159
|
+
retention: clampRetention(input.retention),
|
|
160
|
+
};
|
|
161
|
+
const options = new OptionsRepository(db);
|
|
162
|
+
await options.set(BACKUP_SETTINGS_KEY, settings);
|
|
163
|
+
return { success: true, data: settings };
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error("[backup] Failed to update settings:", error);
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
error: { code: ErrorCode.BACKUP_SETTINGS_ERROR, message: "Failed to update backup settings" },
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ── Archives in storage ─────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* List stored archives, newest first.
|
|
177
|
+
*
|
|
178
|
+
* ponytail: single unpaginated list. The retention cap (max 30) bounds the
|
|
179
|
+
* archive count, so one page always suffices.
|
|
180
|
+
*/
|
|
181
|
+
export async function listBackupArchives(storage: Storage): Promise<ApiResult<BackupArchive[]>> {
|
|
182
|
+
try {
|
|
183
|
+
const result = await storage.list({
|
|
184
|
+
prefix: `${BACKUP_STORAGE_PREFIX}${BACKUP_FILE_PREFIX}`,
|
|
185
|
+
limit: 100,
|
|
186
|
+
});
|
|
187
|
+
const archives = result.files
|
|
188
|
+
.map((file) => ({
|
|
189
|
+
name: file.key.slice(BACKUP_STORAGE_PREFIX.length),
|
|
190
|
+
size: file.size,
|
|
191
|
+
lastModified: file.lastModified.toISOString(),
|
|
192
|
+
}))
|
|
193
|
+
.filter((archive) => isValidArchiveName(archive.name))
|
|
194
|
+
.toSorted((a, b) => (a.name < b.name ? 1 : -1));
|
|
195
|
+
return { success: true, data: archives };
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.error("[backup] Failed to list archives:", error);
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
error: { code: ErrorCode.BACKUP_LIST_ERROR, message: "Failed to list backup archives" },
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Create a backup and store it as an archive, then prune old archives
|
|
207
|
+
* beyond `retention`.
|
|
208
|
+
*/
|
|
209
|
+
export async function runBackupToStorage(
|
|
210
|
+
db: Kysely<Database>,
|
|
211
|
+
storage: Storage,
|
|
212
|
+
retention: number,
|
|
213
|
+
): Promise<ApiResult<BackupArchive>> {
|
|
214
|
+
try {
|
|
215
|
+
const json = await generateBackupJson(db);
|
|
216
|
+
const name = archiveNameForDate(new Date());
|
|
217
|
+
const body = new TextEncoder().encode(json);
|
|
218
|
+
|
|
219
|
+
await storage.upload({
|
|
220
|
+
key: `${BACKUP_STORAGE_PREFIX}${name}`,
|
|
221
|
+
body,
|
|
222
|
+
contentType: "application/json",
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
await pruneArchives(storage, clampRetention(retention));
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
data: { name, size: body.byteLength, lastModified: new Date().toISOString() },
|
|
230
|
+
};
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error("[backup] Failed to create archive:", error);
|
|
233
|
+
return {
|
|
234
|
+
success: false,
|
|
235
|
+
error: { code: ErrorCode.BACKUP_CREATE_ERROR, message: "Failed to create backup archive" },
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Delete archives beyond the newest `keep`. Failures are logged, not fatal. */
|
|
241
|
+
async function pruneArchives(storage: Storage, keep: number): Promise<void> {
|
|
242
|
+
const listed = await listBackupArchives(storage);
|
|
243
|
+
if (!listed.success) return;
|
|
244
|
+
|
|
245
|
+
for (const archive of listed.data.slice(keep)) {
|
|
246
|
+
try {
|
|
247
|
+
await storage.delete(`${BACKUP_STORAGE_PREFIX}${archive.name}`);
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error(`[backup] Failed to prune archive ${archive.name}:`, error);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export async function deleteBackupArchive(
|
|
255
|
+
storage: Storage,
|
|
256
|
+
name: string,
|
|
257
|
+
): Promise<ApiResult<{ deleted: true }>> {
|
|
258
|
+
if (!isValidArchiveName(name)) {
|
|
259
|
+
return {
|
|
260
|
+
success: false,
|
|
261
|
+
error: { code: ErrorCode.VALIDATION_ERROR, message: "Invalid archive name" },
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
await storage.delete(`${BACKUP_STORAGE_PREFIX}${name}`);
|
|
266
|
+
return { success: true, data: { deleted: true } };
|
|
267
|
+
} catch (error) {
|
|
268
|
+
console.error(`[backup] Failed to delete archive ${name}:`, error);
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
error: { code: ErrorCode.BACKUP_DELETE_ERROR, message: "Failed to delete backup archive" },
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ── Scheduled runs ──────────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Run a scheduled backup if enabled and due. Called from the maintenance
|
|
280
|
+
* tick alongside scheduled publishing and system cleanup — never from a
|
|
281
|
+
* request. Never throws.
|
|
282
|
+
*
|
|
283
|
+
* ponytail: last-run bookkeeping is a plain read-then-write, so two isolates
|
|
284
|
+
* ticking simultaneously could both back up. Worst case is a duplicate
|
|
285
|
+
* archive that retention prunes; not worth a lock.
|
|
286
|
+
*/
|
|
287
|
+
export async function maybeRunScheduledBackup(
|
|
288
|
+
db: Kysely<Database>,
|
|
289
|
+
storage: Storage | undefined,
|
|
290
|
+
): Promise<void> {
|
|
291
|
+
try {
|
|
292
|
+
if (!storage) return;
|
|
293
|
+
|
|
294
|
+
const settings = await getBackupSettings(db);
|
|
295
|
+
if (!settings.enabled) return;
|
|
296
|
+
|
|
297
|
+
const options = new OptionsRepository(db);
|
|
298
|
+
const lastRun = await options.get<string>(BACKUP_LAST_RUN_KEY);
|
|
299
|
+
if (lastRun) {
|
|
300
|
+
const elapsed = Date.now() - Date.parse(lastRun);
|
|
301
|
+
if (Number.isFinite(elapsed) && elapsed < SCHEDULED_BACKUP_INTERVAL_MS) return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const result = await runBackupToStorage(db, storage, settings.retention);
|
|
305
|
+
if (result.success) {
|
|
306
|
+
await options.set(BACKUP_LAST_RUN_KEY, new Date().toISOString());
|
|
307
|
+
console.log(`[backup] Scheduled backup stored: ${result.data.name}`);
|
|
308
|
+
}
|
|
309
|
+
} catch (error) {
|
|
310
|
+
console.error("[backup] Scheduled backup failed:", error);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { Kysely } from "kysely";
|
|
6
6
|
import { sql } from "kysely";
|
|
7
7
|
|
|
8
|
+
import { isSqlite } from "../../database/dialect-helpers.js";
|
|
8
9
|
import { BylineRepository } from "../../database/repositories/byline.js";
|
|
9
10
|
import type { ContentBylineInput } from "../../database/repositories/byline.js";
|
|
10
11
|
import { CommentRepository } from "../../database/repositories/comment.js";
|
|
@@ -12,6 +13,7 @@ import { ContentRepository } from "../../database/repositories/content.js";
|
|
|
12
13
|
import { RedirectRepository } from "../../database/repositories/redirect.js";
|
|
13
14
|
import { RevisionRepository } from "../../database/repositories/revision.js";
|
|
14
15
|
import { SeoRepository } from "../../database/repositories/seo.js";
|
|
16
|
+
import { TaxonomyRepository } from "../../database/repositories/taxonomy.js";
|
|
15
17
|
import {
|
|
16
18
|
EmDashValidationError,
|
|
17
19
|
ScheduledNotDueError,
|
|
@@ -30,7 +32,9 @@ import type { Database } from "../../database/types.js";
|
|
|
30
32
|
import { validateIdentifier } from "../../database/validate.js";
|
|
31
33
|
import { getI18nConfig, isI18nEnabled } from "../../i18n/config.js";
|
|
32
34
|
import { invalidateRedirectCache } from "../../redirects/cache.js";
|
|
33
|
-
import {
|
|
35
|
+
import { FTSManager } from "../../search/fts-manager.js";
|
|
36
|
+
import { invalidateTermCache } from "../../taxonomies/index.js";
|
|
37
|
+
import { isMissingColumnError, isMissingTableError } from "../../utils/db-errors.js";
|
|
34
38
|
import { encodeRev, validateRev } from "../rev.js";
|
|
35
39
|
import type { ApiResult, ContentListResponse, ContentResponse } from "../types.js";
|
|
36
40
|
import { validateMediaFields } from "./validate-media-fields.js";
|
|
@@ -327,6 +331,30 @@ async function resolveSearchColumns(db: Kysely<Database>, collection: string): P
|
|
|
327
331
|
return columns;
|
|
328
332
|
}
|
|
329
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Decide whether the content-list `q` filter can be served from the
|
|
336
|
+
* collection's FTS5 index instead of a full-scan substring LIKE (#1517).
|
|
337
|
+
*
|
|
338
|
+
* Requires SQLite (FTS5 is SQLite-only), search enabled on the collection,
|
|
339
|
+
* every non-slug display column present in the searchable-field set (or the
|
|
340
|
+
* index would miss matches the LIKE finds), and the index table actually
|
|
341
|
+
* existing.
|
|
342
|
+
*/
|
|
343
|
+
async function canUseFtsForListFilter(
|
|
344
|
+
db: Kysely<Database>,
|
|
345
|
+
collection: string,
|
|
346
|
+
searchColumns: string[],
|
|
347
|
+
): Promise<boolean> {
|
|
348
|
+
if (!isSqlite(db)) return false;
|
|
349
|
+
const ftsManager = new FTSManager(db);
|
|
350
|
+
const config = await ftsManager.getSearchConfig(collection);
|
|
351
|
+
if (!config?.enabled) return false;
|
|
352
|
+
const searchable = new Set(await ftsManager.getSearchableFields(collection));
|
|
353
|
+
const covered = searchColumns.every((col) => col === "slug" || searchable.has(col));
|
|
354
|
+
if (!covered) return false;
|
|
355
|
+
return ftsManager.ftsTableExists(collection);
|
|
356
|
+
}
|
|
357
|
+
|
|
330
358
|
/**
|
|
331
359
|
* Create a 301 auto-redirect from an entry's old URL to its new one after a
|
|
332
360
|
* slug change, using the collection's URL pattern. Shared by
|
|
@@ -416,6 +444,7 @@ export async function handleContentList(
|
|
|
416
444
|
if (q) {
|
|
417
445
|
where.q = q;
|
|
418
446
|
where.searchColumns = await resolveSearchColumns(db, collection);
|
|
447
|
+
where.useFts = await canUseFtsForListFilter(db, collection, where.searchColumns);
|
|
419
448
|
}
|
|
420
449
|
|
|
421
450
|
const result = await repo.findMany(collection, {
|
|
@@ -456,6 +485,15 @@ export async function handleContentList(
|
|
|
456
485
|
},
|
|
457
486
|
};
|
|
458
487
|
}
|
|
488
|
+
if (isMissingColumnError(error, "deleted_at")) {
|
|
489
|
+
return {
|
|
490
|
+
success: false,
|
|
491
|
+
error: {
|
|
492
|
+
code: "COLLECTION_SCHEMA_MISMATCH",
|
|
493
|
+
message: `Collection '${collection}' backing table is missing the 'deleted_at' column`,
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
}
|
|
459
497
|
if (error instanceof EmDashValidationError) {
|
|
460
498
|
// e.g. invalid orderBy field
|
|
461
499
|
return {
|
|
@@ -638,6 +676,7 @@ export async function handleContentCreate(
|
|
|
638
676
|
locale?: string;
|
|
639
677
|
translationOf?: string;
|
|
640
678
|
seo?: ContentSeoInput;
|
|
679
|
+
taxonomies?: Record<string, string[]>;
|
|
641
680
|
createdAt?: string | null;
|
|
642
681
|
publishedAt?: string | null;
|
|
643
682
|
},
|
|
@@ -712,7 +751,6 @@ export async function handleContentCreate(
|
|
|
712
751
|
// when the target already has credits, but the cleaner guard
|
|
713
752
|
// is to skip the call entirely.
|
|
714
753
|
if (body.translationOf) {
|
|
715
|
-
const { TaxonomyRepository } = await import("../../database/repositories/taxonomy.js");
|
|
716
754
|
const taxRepo = new TaxonomyRepository(trx);
|
|
717
755
|
await taxRepo.copyEntryTerms(collection, body.translationOf, created.id);
|
|
718
756
|
|
|
@@ -737,6 +775,18 @@ export async function handleContentCreate(
|
|
|
737
775
|
created.seo = { ...SEO_DEFAULTS };
|
|
738
776
|
}
|
|
739
777
|
|
|
778
|
+
// Attach taxonomy terms in the same transaction. The MCP tool
|
|
779
|
+
// (and the REST create body) previously accepted a `taxonomies`
|
|
780
|
+
// field on `content_create` without doing anything with it, so
|
|
781
|
+
// agents publishing a categorized/tagged entry had to make N
|
|
782
|
+
// follow-up REST calls per taxonomy. This resolves each slug in
|
|
783
|
+
// the entry's locale and pipes it through the same
|
|
784
|
+
// `setTermsForEntry` path the `.../terms/{taxonomy}` REST route
|
|
785
|
+
// uses, so the two entry points can't drift.
|
|
786
|
+
if (body.taxonomies) {
|
|
787
|
+
await assignTaxonomies(trx, collection, created.id, effectiveLocale, body.taxonomies);
|
|
788
|
+
}
|
|
789
|
+
|
|
740
790
|
return created;
|
|
741
791
|
});
|
|
742
792
|
|
|
@@ -816,6 +866,7 @@ export async function handleContentUpdate(
|
|
|
816
866
|
locale?: string;
|
|
817
867
|
_rev?: string;
|
|
818
868
|
seo?: ContentSeoInput;
|
|
869
|
+
taxonomies?: Record<string, string[]>;
|
|
819
870
|
publishedAt?: string | null;
|
|
820
871
|
},
|
|
821
872
|
): Promise<ApiResult<ContentResponse>> {
|
|
@@ -922,6 +973,20 @@ export async function handleContentUpdate(
|
|
|
922
973
|
|
|
923
974
|
await hydrateBylines(trx, collection, updated);
|
|
924
975
|
|
|
976
|
+
// Replace taxonomy assignments in the same transaction. Uses the
|
|
977
|
+
// entry's own locale (post-update) to resolve slugs so an update
|
|
978
|
+
// that also changes locale still lands on the correct term
|
|
979
|
+
// variants. See handleContentCreate for rationale.
|
|
980
|
+
if (body.taxonomies) {
|
|
981
|
+
await assignTaxonomies(
|
|
982
|
+
trx,
|
|
983
|
+
collection,
|
|
984
|
+
resolvedId,
|
|
985
|
+
updated.locale ?? body.locale,
|
|
986
|
+
body.taxonomies,
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
|
|
925
990
|
return updated;
|
|
926
991
|
});
|
|
927
992
|
|
|
@@ -1431,14 +1496,39 @@ export async function handleContentPublish(
|
|
|
1431
1496
|
};
|
|
1432
1497
|
}
|
|
1433
1498
|
if (error instanceof EmDashValidationError) {
|
|
1499
|
+
// The staged-slug pre-check tags its error so it maps to the same
|
|
1500
|
+
// 409 SLUG_CONFLICT as direct slug edits in create/update.
|
|
1501
|
+
const details: unknown = error.details;
|
|
1502
|
+
const isSlugConflict =
|
|
1503
|
+
typeof details === "object" &&
|
|
1504
|
+
details !== null &&
|
|
1505
|
+
"code" in details &&
|
|
1506
|
+
details.code === "SLUG_CONFLICT";
|
|
1434
1507
|
return {
|
|
1435
1508
|
success: false,
|
|
1436
1509
|
error: {
|
|
1437
|
-
code: "VALIDATION_ERROR",
|
|
1510
|
+
code: isSlugConflict ? "SLUG_CONFLICT" : "VALIDATION_ERROR",
|
|
1438
1511
|
message: error.message,
|
|
1439
1512
|
},
|
|
1440
1513
|
};
|
|
1441
1514
|
}
|
|
1515
|
+
// Backstop for the pre-check inside repo.publish(): a concurrent write
|
|
1516
|
+
// can still take the slug between the check and the UPDATE, in which
|
|
1517
|
+
// case the `(slug, locale)` unique constraint fires. Same fingerprint
|
|
1518
|
+
// mapping as create/update — never a raw SQLite error to the client.
|
|
1519
|
+
const message = error instanceof Error ? error.message.toLowerCase() : "";
|
|
1520
|
+
if (
|
|
1521
|
+
(message.includes("unique constraint failed") || message.includes("duplicate key")) &&
|
|
1522
|
+
message.includes("slug")
|
|
1523
|
+
) {
|
|
1524
|
+
return {
|
|
1525
|
+
success: false,
|
|
1526
|
+
error: {
|
|
1527
|
+
code: "SLUG_CONFLICT",
|
|
1528
|
+
message: `The staged slug is already used by another entry in collection '${collection}'`,
|
|
1529
|
+
},
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1442
1532
|
console.error("Content publish error:", error);
|
|
1443
1533
|
return {
|
|
1444
1534
|
success: false,
|
|
@@ -1769,3 +1859,57 @@ async function syncNonTranslatableFields(
|
|
|
1769
1859
|
AND id != ${updatedItemId}
|
|
1770
1860
|
`.execute(trx);
|
|
1771
1861
|
}
|
|
1862
|
+
|
|
1863
|
+
/**
|
|
1864
|
+
* Resolve a `{ taxonomyName: [slug, ...] }` map to term IDs and replace the
|
|
1865
|
+
* entry's assignments for each named taxonomy.
|
|
1866
|
+
*
|
|
1867
|
+
* Shared by handleContentCreate and handleContentUpdate so both MCP entry
|
|
1868
|
+
* points behave identically. Slug resolution is scoped to `locale`; passing
|
|
1869
|
+
* `undefined` lets `findBySlug` fall back to its default (lowest locale code)
|
|
1870
|
+
* so callers on single-locale sites don't need to know the site's default.
|
|
1871
|
+
*
|
|
1872
|
+
* Throws EmDashValidationError on unknown slug or wrong shape; the calling
|
|
1873
|
+
* handler translates that into a VALIDATION_ERROR response.
|
|
1874
|
+
*/
|
|
1875
|
+
async function assignTaxonomies(
|
|
1876
|
+
trx: Kysely<Database>,
|
|
1877
|
+
collection: string,
|
|
1878
|
+
entryId: string,
|
|
1879
|
+
locale: string | undefined,
|
|
1880
|
+
taxonomies: Record<string, string[]>,
|
|
1881
|
+
): Promise<void> {
|
|
1882
|
+
const taxRepo = new TaxonomyRepository(trx);
|
|
1883
|
+
let anyChange = false;
|
|
1884
|
+
|
|
1885
|
+
for (const [taxonomyName, slugs] of Object.entries(taxonomies)) {
|
|
1886
|
+
if (!Array.isArray(slugs)) {
|
|
1887
|
+
throw new EmDashValidationError(`taxonomies.${taxonomyName} must be an array of term slugs`);
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
const termIds: string[] = [];
|
|
1891
|
+
for (const slug of slugs) {
|
|
1892
|
+
if (typeof slug !== "string" || slug.length === 0) {
|
|
1893
|
+
throw new EmDashValidationError(
|
|
1894
|
+
`taxonomies.${taxonomyName} contains a non-string or empty slug`,
|
|
1895
|
+
);
|
|
1896
|
+
}
|
|
1897
|
+
const term = await taxRepo.findBySlug(taxonomyName, slug, locale);
|
|
1898
|
+
if (!term) {
|
|
1899
|
+
throw new EmDashValidationError(
|
|
1900
|
+
`Unknown taxonomy term: ${taxonomyName}='${slug}'${
|
|
1901
|
+
locale ? ` (locale '${locale}')` : ""
|
|
1902
|
+
}`,
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1905
|
+
termIds.push(term.id);
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
await taxRepo.setTermsForEntry(collection, entryId, taxonomyName, termIds);
|
|
1909
|
+
anyChange = true;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
// Match the REST route's behaviour: taxonomy term assignments changed,
|
|
1913
|
+
// so invalidate the taxonomy object cache used during hydration.
|
|
1914
|
+
if (anyChange) invalidateTermCache();
|
|
1915
|
+
}
|
|
@@ -21,6 +21,7 @@ export interface CollectionStats {
|
|
|
21
21
|
total: number;
|
|
22
22
|
published: number;
|
|
23
23
|
draft: number;
|
|
24
|
+
scheduled: number;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export interface RecentItem {
|
|
@@ -69,6 +70,7 @@ export async function handleDashboardStats(
|
|
|
69
70
|
total: stats.total,
|
|
70
71
|
published: stats.published,
|
|
71
72
|
draft: stats.draft,
|
|
73
|
+
scheduled: stats.scheduled,
|
|
72
74
|
};
|
|
73
75
|
}),
|
|
74
76
|
);
|
|
@@ -17,8 +17,8 @@ import type { Kysely } from "kysely";
|
|
|
17
17
|
import {
|
|
18
18
|
generatePrefixedToken,
|
|
19
19
|
hashApiToken,
|
|
20
|
+
isValidScope,
|
|
20
21
|
TOKEN_PREFIXES,
|
|
21
|
-
VALID_SCOPES,
|
|
22
22
|
} from "../../auth/api-tokens.js";
|
|
23
23
|
import { withTransaction } from "../../database/transaction.js";
|
|
24
24
|
import type { Database } from "../../database/types.js";
|
|
@@ -112,8 +112,7 @@ function normalizeScopes(requested?: string[]): string[] {
|
|
|
112
112
|
if (!requested || requested.length === 0) {
|
|
113
113
|
return [...DEFAULT_SCOPES];
|
|
114
114
|
}
|
|
115
|
-
|
|
116
|
-
return requested.filter((s) => validSet.has(s));
|
|
115
|
+
return requested.filter(isValidScope);
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
// ---------------------------------------------------------------------------
|
|
@@ -61,6 +61,22 @@ export {
|
|
|
61
61
|
type MediaResponse,
|
|
62
62
|
} from "./media.js";
|
|
63
63
|
|
|
64
|
+
export {
|
|
65
|
+
aggregateMediaUsageCoverageStatus,
|
|
66
|
+
handleMediaUsageDetails,
|
|
67
|
+
handleMediaUsageSummaries,
|
|
68
|
+
handleMediaUsageRepair,
|
|
69
|
+
toMediaUsageRepairResponse,
|
|
70
|
+
type MediaUsageCoverage,
|
|
71
|
+
type MediaUsageCoverageStatus,
|
|
72
|
+
type MediaUsageDetailsResponse,
|
|
73
|
+
type MediaUsageEntryDetail,
|
|
74
|
+
type MediaUsageOccurrenceDetail,
|
|
75
|
+
type MediaUsageRepairResponse,
|
|
76
|
+
type MediaUsageSourceDetail,
|
|
77
|
+
type MediaUsageSummary,
|
|
78
|
+
} from "./media-usage.js";
|
|
79
|
+
|
|
64
80
|
// Schema handlers
|
|
65
81
|
export {
|
|
66
82
|
handleSchemaCollectionList,
|
|
@@ -103,6 +119,12 @@ export {
|
|
|
103
119
|
type PluginListResponse,
|
|
104
120
|
type PluginResponse,
|
|
105
121
|
} from "./plugins.js";
|
|
122
|
+
export {
|
|
123
|
+
handlePluginSettingsGet,
|
|
124
|
+
handlePluginSettingsUpdate,
|
|
125
|
+
getPluginSettingsSchema,
|
|
126
|
+
type PluginSettingsResponse,
|
|
127
|
+
} from "./plugin-settings.js";
|
|
106
128
|
|
|
107
129
|
// Menu handlers
|
|
108
130
|
export {
|
|
@@ -328,6 +328,7 @@ export async function handleMarketplaceInstall(
|
|
|
328
328
|
* Skip the SANDBOX_NOT_AVAILABLE gate so the install can proceed.
|
|
329
329
|
*/
|
|
330
330
|
sandboxBypassed?: boolean;
|
|
331
|
+
confirmMcpTools?: boolean;
|
|
331
332
|
},
|
|
332
333
|
): Promise<ApiResult<MarketplaceInstallResult>> {
|
|
333
334
|
const client = getClient(marketplaceUrl, opts?.siteOrigin);
|
|
@@ -448,6 +449,21 @@ export async function handleMarketplaceInstall(
|
|
|
448
449
|
const bundleIdentityError = validateBundleIdentity(bundle, pluginId, version);
|
|
449
450
|
if (bundleIdentityError) return bundleIdentityError;
|
|
450
451
|
|
|
452
|
+
if ((bundle.manifest.mcp?.tools.length ?? 0) > 0 && !opts?.confirmMcpTools) {
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
error: {
|
|
456
|
+
code: "MCP_TOOL_CONSENT_REQUIRED",
|
|
457
|
+
message: "Plugin MCP tools require explicit consent",
|
|
458
|
+
details: {
|
|
459
|
+
mcpTools: bundle.manifest.mcp?.tools.map(
|
|
460
|
+
({ inputSchema: _, outputSchema: __, ...tool }) => tool,
|
|
461
|
+
),
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
451
467
|
// Store bundle in site-local R2
|
|
452
468
|
await storeBundleInR2(storage, pluginId, version, bundle);
|
|
453
469
|
|
|
@@ -534,6 +550,7 @@ export async function handleMarketplaceUpdate(
|
|
|
534
550
|
version?: string;
|
|
535
551
|
confirmCapabilityChanges?: boolean;
|
|
536
552
|
confirmRouteVisibilityChanges?: boolean;
|
|
553
|
+
confirmMcpTools?: boolean;
|
|
537
554
|
/**
|
|
538
555
|
* When true, sandbox: false bypass mode is active. The sandbox runner
|
|
539
556
|
* is the noop runner (isAvailable() === false) but the runtime will
|
|
@@ -664,6 +681,25 @@ export async function handleMarketplaceUpdate(
|
|
|
664
681
|
};
|
|
665
682
|
}
|
|
666
683
|
|
|
684
|
+
const oldMcpTools = [...(oldBundle?.manifest.mcp?.tools ?? [])].toSorted((a, b) =>
|
|
685
|
+
a.name.localeCompare(b.name),
|
|
686
|
+
);
|
|
687
|
+
const newMcpTools = [...(bundle.manifest.mcp?.tools ?? [])].toSorted((a, b) =>
|
|
688
|
+
a.name.localeCompare(b.name),
|
|
689
|
+
);
|
|
690
|
+
if (JSON.stringify(oldMcpTools) !== JSON.stringify(newMcpTools) && !opts?.confirmMcpTools) {
|
|
691
|
+
return {
|
|
692
|
+
success: false,
|
|
693
|
+
error: {
|
|
694
|
+
code: "MCP_TOOL_CONSENT_REQUIRED",
|
|
695
|
+
message: "Plugin update changes its MCP tools",
|
|
696
|
+
details: {
|
|
697
|
+
mcpTools: newMcpTools.map(({ inputSchema: _, outputSchema: __, ...tool }) => tool),
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
|
|
667
703
|
// Store new bundle
|
|
668
704
|
await storeBundleInR2(storage, pluginId, newVersion, bundle);
|
|
669
705
|
|
|
@@ -673,6 +709,8 @@ export async function handleMarketplaceUpdate(
|
|
|
673
709
|
marketplaceVersion: newVersion,
|
|
674
710
|
displayName: pluginDetail.name,
|
|
675
711
|
description: pluginDetail.description ?? undefined,
|
|
712
|
+
mcpToolsEnabled: false,
|
|
713
|
+
mcpToolsConsent: null,
|
|
676
714
|
});
|
|
677
715
|
|
|
678
716
|
// Clean up old bundle from R2 (best-effort)
|