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
|
@@ -22,6 +22,7 @@ import { getEditMeta } from "../query.js";
|
|
|
22
22
|
import { pluginBlockComponents } from "virtual:emdash/block-components";
|
|
23
23
|
import { emdashComponents } from "./index.js";
|
|
24
24
|
import InlineEditor from "./InlineEditor.astro";
|
|
25
|
+
import { groupBlockquoteRuns } from "./portable-text-blockquote-group.js";
|
|
25
26
|
|
|
26
27
|
export interface Props extends Omit<PortableTextProps, "value"> {
|
|
27
28
|
value: PortableTextProps["value"];
|
|
@@ -37,6 +38,11 @@ const withPlugins = mergeComponents(emdashComponents, { type: pluginBlockCompone
|
|
|
37
38
|
const mergedComponents = userComponents
|
|
38
39
|
? mergeComponents(withPlugins, userComponents)
|
|
39
40
|
: withPlugins;
|
|
41
|
+
|
|
42
|
+
// A multi-paragraph quote is stored as consecutive blockquote-styled blocks
|
|
43
|
+
// (Portable Text is flat); merge each run into one blockquoteGroup node so
|
|
44
|
+
// it renders as a single <blockquote> instead of several (#1884).
|
|
45
|
+
const renderValue = Array.isArray(value) ? groupBlockquoteRuns(value) : value;
|
|
40
46
|
---
|
|
41
47
|
|
|
42
48
|
{editMeta ? (
|
|
@@ -47,5 +53,5 @@ const mergedComponents = userComponents
|
|
|
47
53
|
field={editMeta.field}
|
|
48
54
|
/>
|
|
49
55
|
) : (
|
|
50
|
-
<BasePortableText value={
|
|
56
|
+
<BasePortableText value={renderValue} components={mergedComponents} {...rest} />
|
|
51
57
|
)}
|
package/src/components/index.ts
CHANGED
|
@@ -59,6 +59,7 @@ export { default as StrikeThrough } from "./marks/StrikeThrough.astro";
|
|
|
59
59
|
export { default as Link } from "./marks/Link.astro";
|
|
60
60
|
|
|
61
61
|
import BlockComponent from "./Block.astro";
|
|
62
|
+
import BlockquoteGroupComponent from "./BlockquoteGroup.astro";
|
|
62
63
|
import BreakComponent from "./Break.astro";
|
|
63
64
|
import ButtonComponent from "./Button.astro";
|
|
64
65
|
import ButtonsComponent from "./Buttons.astro";
|
|
@@ -88,6 +89,7 @@ import TableComponent from "./Table.astro";
|
|
|
88
89
|
export const emdashComponents = {
|
|
89
90
|
block: BlockComponent,
|
|
90
91
|
type: {
|
|
92
|
+
blockquoteGroup: BlockquoteGroupComponent,
|
|
91
93
|
image: ImageComponent,
|
|
92
94
|
code: CodeComponent,
|
|
93
95
|
embed: EmbedComponent,
|
|
@@ -19,7 +19,11 @@ export interface Props {
|
|
|
19
19
|
|
|
20
20
|
const { node } = Astro.props;
|
|
21
21
|
const href = sanitizeHref(node?.markDef?.href);
|
|
22
|
-
|
|
22
|
+
// Same-page anchor links (`#section`) are on-page jumps — opening them in a
|
|
23
|
+
// new tab is never desirable, so force same-tab regardless of the mark's
|
|
24
|
+
// `blank` flag.
|
|
25
|
+
const isSamePageAnchor = href.startsWith("#");
|
|
26
|
+
const blank = !isSamePageAnchor && node?.markDef?.blank;
|
|
23
27
|
---
|
|
24
28
|
|
|
25
29
|
<a
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Groups consecutive Portable Text blocks with style "blockquote" into a
|
|
3
|
+
* single synthetic `blockquoteGroup` node so they render as ONE
|
|
4
|
+
* `<blockquote>` with a paragraph per block.
|
|
5
|
+
*
|
|
6
|
+
* Portable Text is flat: a multi-paragraph quote (e.g. from a WordPress
|
|
7
|
+
* `core/quote` import) is stored as consecutive blocks with
|
|
8
|
+
* `style: "blockquote"`. Rendering each of those as its own `<blockquote>`
|
|
9
|
+
* visually splits the quote (#1884).
|
|
10
|
+
*
|
|
11
|
+
* Runs of a single block are left untouched, so existing single-paragraph
|
|
12
|
+
* quotes render byte-for-byte as before.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface TextBlockLike {
|
|
16
|
+
_type: string;
|
|
17
|
+
_key?: string;
|
|
18
|
+
style?: string;
|
|
19
|
+
listItem?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BlockquoteGroupNode {
|
|
23
|
+
_type: "blockquoteGroup";
|
|
24
|
+
_key: string;
|
|
25
|
+
blocks: TextBlockLike[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isBlockquoteBlock(block: unknown): block is TextBlockLike {
|
|
29
|
+
if (typeof block !== "object" || block === null) return false;
|
|
30
|
+
const b: Partial<TextBlockLike> = block;
|
|
31
|
+
// Quote-styled list items belong to their list, not to a quote run.
|
|
32
|
+
return b._type === "block" && b.style === "blockquote" && b.listItem === undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function groupBlockquoteRuns(blocks: unknown[]): unknown[] {
|
|
36
|
+
const result: unknown[] = [];
|
|
37
|
+
let i = 0;
|
|
38
|
+
|
|
39
|
+
while (i < blocks.length) {
|
|
40
|
+
const current = blocks[i];
|
|
41
|
+
if (!isBlockquoteBlock(current)) {
|
|
42
|
+
result.push(current);
|
|
43
|
+
i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const run: TextBlockLike[] = [];
|
|
48
|
+
let next: unknown = current;
|
|
49
|
+
while (i < blocks.length && isBlockquoteBlock(next)) {
|
|
50
|
+
run.push(next);
|
|
51
|
+
i++;
|
|
52
|
+
next = blocks[i];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (run.length === 1) {
|
|
56
|
+
result.push(run[0]);
|
|
57
|
+
} else {
|
|
58
|
+
const group: BlockquoteGroupNode = {
|
|
59
|
+
_type: "blockquoteGroup",
|
|
60
|
+
_key: `${run[0]?._key ?? "quote"}-group`,
|
|
61
|
+
blocks: run,
|
|
62
|
+
};
|
|
63
|
+
result.push(group);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
@@ -60,6 +60,37 @@ export function portableTextToProsemirror(blocks: PortableTextBlock[]): ProseMir
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
content.push(convertList(listBlocks, listType));
|
|
63
|
+
} else if (isTextBlock(block) && block.style === "blockquote") {
|
|
64
|
+
// Collect a blockquote "run": Portable Text is flat, so a
|
|
65
|
+
// multi-paragraph quote is stored as consecutive blocks with
|
|
66
|
+
// style "blockquote" (that's what the Gutenberg importer emits
|
|
67
|
+
// and what prosemirrorToPortableText serializes back to).
|
|
68
|
+
// Without this grouping each paragraph became its own quote
|
|
69
|
+
// node, and editor merges reverted on reload (#1884).
|
|
70
|
+
const quoteBlocks: PortableTextTextBlock[] = [];
|
|
71
|
+
while (i < blocks.length) {
|
|
72
|
+
const current = blocks[i];
|
|
73
|
+
if (
|
|
74
|
+
!isTextBlock(current) ||
|
|
75
|
+
current.style !== "blockquote" ||
|
|
76
|
+
current.listItem !== undefined
|
|
77
|
+
) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
quoteBlocks.push(current);
|
|
81
|
+
i++;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
content.push({
|
|
85
|
+
type: "blockquote",
|
|
86
|
+
content: quoteBlocks.map((quoteBlock) => {
|
|
87
|
+
const paragraph = convertSpans(quoteBlock.children, quoteBlock.markDefs || []);
|
|
88
|
+
return {
|
|
89
|
+
type: "paragraph",
|
|
90
|
+
content: paragraph.length > 0 ? paragraph : undefined,
|
|
91
|
+
};
|
|
92
|
+
}),
|
|
93
|
+
});
|
|
63
94
|
} else {
|
|
64
95
|
const converted = convertBlock(block);
|
|
65
96
|
if (converted) {
|
|
@@ -386,7 +417,7 @@ function convertMarks(
|
|
|
386
417
|
// Unknown mark def type - preserve attrs
|
|
387
418
|
pmMarks.push({
|
|
388
419
|
type: markDef._type,
|
|
389
|
-
attrs: markDef
|
|
420
|
+
attrs: markDef,
|
|
390
421
|
});
|
|
391
422
|
}
|
|
392
423
|
}
|
|
@@ -68,6 +68,40 @@ export function currentTimestampValue(db: Kysely<any>): RawBuilder<string> {
|
|
|
68
68
|
return sql`datetime('now')`;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Build WHERE clause for status filtering on a content table.
|
|
73
|
+
* When filtering for 'published' status, also include scheduled content
|
|
74
|
+
* whose scheduled_at time has passed (treating it as effectively published).
|
|
75
|
+
*
|
|
76
|
+
* Visibility is computed, not flipped by cron, so a literal
|
|
77
|
+
* `status = 'published'` comparison undercounts scheduled-and-due entries —
|
|
78
|
+
* every "publicly visible" filter must go through this helper.
|
|
79
|
+
*/
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
81
|
+
export function buildStatusCondition(
|
|
82
|
+
db: Kysely<any>,
|
|
83
|
+
status: string,
|
|
84
|
+
tablePrefix?: string,
|
|
85
|
+
): ReturnType<typeof sql> {
|
|
86
|
+
const statusField = tablePrefix ? `${tablePrefix}.status` : "status";
|
|
87
|
+
const scheduledAtField = tablePrefix ? `${tablePrefix}.scheduled_at` : "scheduled_at";
|
|
88
|
+
|
|
89
|
+
if (status === "published") {
|
|
90
|
+
// Include both published content AND scheduled content past its publish time.
|
|
91
|
+
// scheduled_at is stored as text (ISO 8601). On Postgres, we must cast it
|
|
92
|
+
// to timestamptz for the comparison with CURRENT_TIMESTAMP to work.
|
|
93
|
+
const scheduledAtExpr = isPostgres(db)
|
|
94
|
+
? sql`${sql.ref(scheduledAtField)}::timestamptz`
|
|
95
|
+
: sql.ref(scheduledAtField);
|
|
96
|
+
const nowExpr = isPostgres(db)
|
|
97
|
+
? currentTimestampValue(db)
|
|
98
|
+
: sql`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
99
|
+
return sql`(${sql.ref(statusField)} = 'published' OR (${sql.ref(statusField)} = 'scheduled' AND ${scheduledAtExpr} <= ${nowExpr}))`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return sql`${sql.ref(statusField)} = ${status}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
71
105
|
/**
|
|
72
106
|
* Check if a table exists in the database.
|
|
73
107
|
*/
|
|
@@ -181,17 +215,91 @@ export function binaryType(db: Kysely<any>): ColumnDataType {
|
|
|
181
215
|
}
|
|
182
216
|
|
|
183
217
|
/**
|
|
184
|
-
* SQL expression for extracting a field from a JSON
|
|
218
|
+
* SQL expression for extracting a field from a JSON column stored as text.
|
|
185
219
|
*
|
|
186
220
|
* sqlite: json_extract(column, '$.path')
|
|
187
|
-
* postgres: column->>'path'
|
|
221
|
+
* postgres: (column)::jsonb->>'path'
|
|
222
|
+
*
|
|
223
|
+
* The Postgres cast is required because JSON columns (e.g.
|
|
224
|
+
* `_plugin_storage.data`) are `text`, and `text ->> unknown` is not an
|
|
225
|
+
* operator. The cast is immutable, so the same expression works in
|
|
226
|
+
* expression indexes — queries and indexes must build it through this
|
|
227
|
+
* helper so the planner can match them.
|
|
188
228
|
*/
|
|
189
229
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
190
230
|
export function jsonExtractExpr(db: Kysely<any>, column: string, path: string): string {
|
|
191
231
|
validateIdentifier(column, "JSON column name");
|
|
192
232
|
validateJsonFieldName(path, "JSON path");
|
|
193
233
|
if (isPostgres(db)) {
|
|
194
|
-
return
|
|
234
|
+
return `(${column})::jsonb->>'${path}'`;
|
|
195
235
|
}
|
|
196
236
|
return `json_extract(${column}, '$.${path}')`;
|
|
197
237
|
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* SQL expression for extracting a queryable field from the plugin-storage
|
|
241
|
+
* `data` column.
|
|
242
|
+
*
|
|
243
|
+
* `_plugin_storage.data` is `text`, so Postgres extraction goes through the
|
|
244
|
+
* `(data)::jsonb->>'field'` cast (#1898) — otherwise `text ->> unknown` is not
|
|
245
|
+
* an operator. But the extracted value is still `text`, so a numeric comparison
|
|
246
|
+
* (`stock >= 10`) compares lexically (`'9' >= '10'` is TRUE) and silently
|
|
247
|
+
* over-counts / oversells; pass `{ numeric: true }` for a numeric comparison.
|
|
248
|
+
*
|
|
249
|
+
* The numeric form is a **type-guarded** cast, not a bare `::numeric`. A bare
|
|
250
|
+
* cast throws `invalid input syntax for type numeric` the moment a single
|
|
251
|
+
* scanned row stores a non-number in that field (documents are schemaless),
|
|
252
|
+
* aborting the whole query — and it would diverge from SQLite, which silently
|
|
253
|
+
* coerces. Guarding with `jsonb_typeof`/`json_type` makes the comparison total
|
|
254
|
+
* and parity-correct on both dialects: a non-number stored value yields `NULL`
|
|
255
|
+
* (no match) instead of an error.
|
|
256
|
+
*
|
|
257
|
+
* The field name is validated before interpolation, so the casts wrap only a
|
|
258
|
+
* safe identifier and add no injection surface.
|
|
259
|
+
*
|
|
260
|
+
* sqlite text: json_extract(data, '$.field')
|
|
261
|
+
* sqlite numeric: CASE WHEN json_type(data, '$.field') IN ('integer', 'real')
|
|
262
|
+
* THEN json_extract(data, '$.field') END
|
|
263
|
+
* postgres text: (data)::jsonb->>'field'
|
|
264
|
+
* postgres numeric: CASE WHEN jsonb_typeof((data)::jsonb->'field') = 'number'
|
|
265
|
+
* THEN ((data)::jsonb->>'field')::numeric END
|
|
266
|
+
*/
|
|
267
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
268
|
+
export function pluginDataExtractExpr(
|
|
269
|
+
db: Kysely<any>,
|
|
270
|
+
field: string,
|
|
271
|
+
options?: { numeric?: boolean },
|
|
272
|
+
): string {
|
|
273
|
+
validateJsonFieldName(field, "plugin storage field name");
|
|
274
|
+
if (isPostgres(db)) {
|
|
275
|
+
const text = `(data)::jsonb->>'${field}'`;
|
|
276
|
+
if (!options?.numeric) return text;
|
|
277
|
+
return `CASE WHEN jsonb_typeof((data)::jsonb->'${field}') = 'number' THEN (${text})::numeric END`;
|
|
278
|
+
}
|
|
279
|
+
const extract = `json_extract(data, '$.${field}')`;
|
|
280
|
+
if (!options?.numeric) return extract;
|
|
281
|
+
return `CASE WHEN json_type(data, '$.${field}') IN ('integer', 'real') THEN ${extract} END`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* SQL expression for ordering plugin-storage rows by a `data` field.
|
|
286
|
+
*
|
|
287
|
+
* `ORDER BY` has no bound operand to infer numeric-vs-text from, so extracting
|
|
288
|
+
* as text (`->>'field'`) would sort a numeric field lexically on Postgres
|
|
289
|
+
* (`[10, 100, 9]`) while SQLite's `json_extract` sorts it numerically — a
|
|
290
|
+
* cross-dialect divergence. Ordering over the jsonb-native value (`->'field'`,
|
|
291
|
+
* single arrow) fixes this: jsonb btree ordering is numeric among numbers,
|
|
292
|
+
* lexical among strings, and total across heterogeneous values (never throws).
|
|
293
|
+
* SQLite's `json_extract` already orders numerically, so it is unchanged.
|
|
294
|
+
*
|
|
295
|
+
* sqlite: json_extract(data, '$.field')
|
|
296
|
+
* postgres: (data)::jsonb->'field'
|
|
297
|
+
*/
|
|
298
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
299
|
+
export function pluginDataOrderExpr(db: Kysely<any>, field: string): string {
|
|
300
|
+
validateJsonFieldName(field, "plugin storage order field name");
|
|
301
|
+
if (isPostgres(db)) {
|
|
302
|
+
return `(data)::jsonb->'${field}'`;
|
|
303
|
+
}
|
|
304
|
+
return `json_extract(data, '$.${field}')`;
|
|
305
|
+
}
|
|
@@ -135,7 +135,7 @@ function isSearchEnabled(searchConfig: string | null): boolean {
|
|
|
135
135
|
typeof parsed === "object" &&
|
|
136
136
|
parsed !== null &&
|
|
137
137
|
"enabled" in parsed &&
|
|
138
|
-
|
|
138
|
+
parsed.enabled === true
|
|
139
139
|
);
|
|
140
140
|
} catch {
|
|
141
141
|
return false;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
|
|
4
|
+
import { columnExists, listTablesLike } from "../dialect-helpers.js";
|
|
5
|
+
import { validateIdentifier } from "../validate.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Denormalize the filter + sort columns from `ec_*` onto `content_taxonomies`
|
|
9
|
+
* and mirror `ec_*`'s composite sort indexes onto the pivot (#1834).
|
|
10
|
+
*
|
|
11
|
+
* A taxonomy-filtered listing used to apply the term filter as a correlated
|
|
12
|
+
* `EXISTS` on `SELECT * FROM ec_<collection> … ORDER BY … LIMIT ?`. The pivot
|
|
13
|
+
* carried only `(collection, entry_id, taxonomy_id)`, so the filter
|
|
14
|
+
* (`deleted_at`, `status`, `locale`) and the sort (`published_at`/`created_at`)
|
|
15
|
+
* could only be evaluated on the `ec_*` row. On stats-blind SQLite/D1 a
|
|
16
|
+
* selective term never fills the `LIMIT`, so the query walked the whole
|
|
17
|
+
* collection (~75k D1 rows read for a one-row page).
|
|
18
|
+
*
|
|
19
|
+
* Copying those columns onto the pivot and indexing them keyed by
|
|
20
|
+
* `(taxonomy_id, collection, …)` lets the loader seek the term and walk a
|
|
21
|
+
* sort-ordered pivot index, short-circuiting on `LIMIT`, then touch `ec_*` only
|
|
22
|
+
* by primary key to hydrate the page.
|
|
23
|
+
*
|
|
24
|
+
* The columns are advisory (D1 has no transactions; the write-path re-stamp is
|
|
25
|
+
* non-atomic), so the read path re-checks the real predicates on the joined
|
|
26
|
+
* `ec_*` row — see loader.ts. `updated_at` is deliberately not denormalized: it
|
|
27
|
+
* moves on every edit and is seldom a public sort, so its write cost outweighs
|
|
28
|
+
* its read value; `updated_at`-sorted taxonomy listings temp-sort instead.
|
|
29
|
+
*
|
|
30
|
+
* Order matters: add the columns, backfill, THEN build the indexes so each
|
|
31
|
+
* index is built once over populated data rather than maintained through the
|
|
32
|
+
* backfill `UPDATE`.
|
|
33
|
+
*
|
|
34
|
+
* Forward-only.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const DENORM_COLUMNS = [
|
|
38
|
+
"status",
|
|
39
|
+
"scheduled_at",
|
|
40
|
+
"deleted_at",
|
|
41
|
+
"locale",
|
|
42
|
+
"published_at",
|
|
43
|
+
"created_at",
|
|
44
|
+
] as const;
|
|
45
|
+
|
|
46
|
+
// `entry_id DESC` (not ASC) matters: the listing orders `<sort> DESC, entry_id
|
|
47
|
+
// DESC` (the common case), and a DESC tiebreaker lets SQLite satisfy the whole
|
|
48
|
+
// ORDER BY from the index — no temp B-tree, clean early-`LIMIT`. An ASC
|
|
49
|
+
// tiebreaker forces `USE TEMP B-TREE FOR LAST TERM OF ORDER BY`, which buffers
|
|
50
|
+
// a whole equal-`sortval` block (e.g. a bulk import sharing one timestamp)
|
|
51
|
+
// before emitting. `DESC` also serves the rarer ASC listing via a backward
|
|
52
|
+
// index scan. Mirrors `ec_*`'s `(deleted_at, [locale,] <sort> DESC, id DESC)`.
|
|
53
|
+
const INDEXES: { name: string; columns: string }[] = [
|
|
54
|
+
{
|
|
55
|
+
name: "idx_content_taxonomies_pub",
|
|
56
|
+
columns: "taxonomy_id, collection, deleted_at, published_at DESC, entry_id DESC",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "idx_content_taxonomies_crt",
|
|
60
|
+
columns: "taxonomy_id, collection, deleted_at, created_at DESC, entry_id DESC",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "idx_content_taxonomies_loc_pub",
|
|
64
|
+
columns: "taxonomy_id, collection, deleted_at, locale, published_at DESC, entry_id DESC",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "idx_content_taxonomies_loc_crt",
|
|
68
|
+
columns: "taxonomy_id, collection, deleted_at, locale, created_at DESC, entry_id DESC",
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
73
|
+
// 1. Add the six denormalized columns (all nullable, no default). Guarded so
|
|
74
|
+
// a partial apply — or a re-run after a mid-migration failure — can retry
|
|
75
|
+
// (`ALTER TABLE ADD COLUMN` is not itself idempotent on either dialect).
|
|
76
|
+
for (const column of DENORM_COLUMNS) {
|
|
77
|
+
if (await columnExists(db, "content_taxonomies", column)) continue;
|
|
78
|
+
await sql`
|
|
79
|
+
ALTER TABLE content_taxonomies ADD COLUMN ${sql.ref(column)} TEXT
|
|
80
|
+
`.execute(db);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 2. Backfill from each content table by primary key. Drive from the actual
|
|
84
|
+
// `ec_*` tables (not `_emdash_collections`) so collections whose table was
|
|
85
|
+
// dropped are skipped naturally; the pivot's `collection` value is the
|
|
86
|
+
// slug, i.e. the table name without its `ec_` prefix.
|
|
87
|
+
const tableNames = await listTablesLike(db, "ec_%");
|
|
88
|
+
for (const tableName of tableNames) {
|
|
89
|
+
validateIdentifier(tableName, "content table name");
|
|
90
|
+
const slug = tableName.slice("ec_".length);
|
|
91
|
+
await sql`
|
|
92
|
+
UPDATE content_taxonomies
|
|
93
|
+
SET (status, scheduled_at, deleted_at, locale, published_at, created_at) = (
|
|
94
|
+
SELECT status, scheduled_at, deleted_at, locale, published_at, created_at
|
|
95
|
+
FROM ${sql.ref(tableName)}
|
|
96
|
+
WHERE ${sql.ref(tableName)}.id = content_taxonomies.entry_id
|
|
97
|
+
)
|
|
98
|
+
WHERE collection = ${slug}
|
|
99
|
+
`.execute(db);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 3. Build the composite sort indexes over the now-populated columns.
|
|
103
|
+
for (const index of INDEXES) {
|
|
104
|
+
await sql`
|
|
105
|
+
CREATE INDEX IF NOT EXISTS ${sql.ref(index.name)}
|
|
106
|
+
ON content_taxonomies (${sql.raw(index.columns)})
|
|
107
|
+
`.execute(db);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
112
|
+
for (const index of INDEXES) {
|
|
113
|
+
await sql`DROP INDEX IF EXISTS ${sql.ref(index.name)}`.execute(db);
|
|
114
|
+
}
|
|
115
|
+
for (const column of DENORM_COLUMNS) {
|
|
116
|
+
await sql`
|
|
117
|
+
ALTER TABLE content_taxonomies DROP COLUMN ${sql.ref(column)}
|
|
118
|
+
`.execute(db);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
|
|
3
|
+
const OLD_INDEX = "idx__emdash_media_usage_media_id";
|
|
4
|
+
const READ_INDEX = "idx__emdash_media_usage_media_source_generation";
|
|
5
|
+
|
|
6
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
7
|
+
// D1 DDL is non-transactional: create the replacement before dropping the
|
|
8
|
+
// old index so an interrupted migration always leaves a media-leading index.
|
|
9
|
+
await db.schema
|
|
10
|
+
.createIndex(READ_INDEX)
|
|
11
|
+
.ifNotExists()
|
|
12
|
+
.on("_emdash_media_usage")
|
|
13
|
+
.columns(["media_id", "source_key", "generation"])
|
|
14
|
+
.execute();
|
|
15
|
+
await db.schema.dropIndex(OLD_INDEX).ifExists().execute();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
19
|
+
await db.schema
|
|
20
|
+
.createIndex(OLD_INDEX)
|
|
21
|
+
.ifNotExists()
|
|
22
|
+
.on("_emdash_media_usage")
|
|
23
|
+
.column("media_id")
|
|
24
|
+
.execute();
|
|
25
|
+
await db.schema.dropIndex(READ_INDEX).ifExists().execute();
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
|
|
3
|
+
import { columnExists } from "../dialect-helpers.js";
|
|
4
|
+
|
|
5
|
+
/** Persist explicit per-plugin MCP enablement and the declaration consented to by an admin. */
|
|
6
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
7
|
+
if (!(await columnExists(db, "_plugin_state", "mcp_tools_enabled"))) {
|
|
8
|
+
await db.schema
|
|
9
|
+
.alterTable("_plugin_state")
|
|
10
|
+
.addColumn("mcp_tools_enabled", "integer", (col) => col.notNull().defaultTo(0))
|
|
11
|
+
.execute();
|
|
12
|
+
}
|
|
13
|
+
if (!(await columnExists(db, "_plugin_state", "mcp_tools_consent"))) {
|
|
14
|
+
await db.schema.alterTable("_plugin_state").addColumn("mcp_tools_consent", "text").execute();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
19
|
+
await db.schema.alterTable("_plugin_state").dropColumn("mcp_tools_consent").execute();
|
|
20
|
+
await db.schema.alterTable("_plugin_state").dropColumn("mcp_tools_enabled").execute();
|
|
21
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Kysely, sql } from "kysely";
|
|
2
2
|
import { type Migration, type MigrationProvider, Migrator } from "kysely/migration";
|
|
3
3
|
|
|
4
|
+
import { MIGRATION_LOCK_BUSY_MESSAGE } from "../pg-migration-lock.js";
|
|
4
5
|
import type { Database } from "../types.js";
|
|
5
6
|
// Import migrations statically for bundling
|
|
6
7
|
import * as m001 from "./001_initial.js";
|
|
@@ -52,6 +53,9 @@ import * as m047 from "./047_restore_taxonomy_parent_index.js";
|
|
|
52
53
|
import * as m048 from "./048_restore_content_taxonomies_term_index.js";
|
|
53
54
|
import * as m049 from "./049_taxonomies_name_locale_index.js";
|
|
54
55
|
import * as m050 from "./050_media_usage_index_status.js";
|
|
56
|
+
import * as m051 from "./051_content_taxonomies_denorm.js";
|
|
57
|
+
import * as m052 from "./052_media_usage_read_index.js";
|
|
58
|
+
import * as m053 from "./053_plugin_mcp_tools.js";
|
|
55
59
|
|
|
56
60
|
const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
57
61
|
"001_initial": m001,
|
|
@@ -103,6 +107,9 @@ const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
|
103
107
|
"048_restore_content_taxonomies_term_index": m048,
|
|
104
108
|
"049_taxonomies_name_locale_index": m049,
|
|
105
109
|
"050_media_usage_index_status": m050,
|
|
110
|
+
"051_content_taxonomies_denorm": m051,
|
|
111
|
+
"052_media_usage_read_index": m052,
|
|
112
|
+
"053_plugin_mcp_tools": m053,
|
|
106
113
|
});
|
|
107
114
|
|
|
108
115
|
/** Total number of registered migrations. Exported for use in tests. */
|
|
@@ -123,12 +130,36 @@ export interface MigrationStatus {
|
|
|
123
130
|
pending: string[];
|
|
124
131
|
}
|
|
125
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Thrown when another instance held the migration lock for the whole wait
|
|
135
|
+
* window. This is NOT a migration failure — the holder may simply be slow
|
|
136
|
+
* (e.g. many pending migrations over a remote Postgres connection) — so
|
|
137
|
+
* callers with failure-backoff logic (`getDatabase` in emdash-runtime.ts)
|
|
138
|
+
* exempt it: the next request waits again instead of backing off, and init
|
|
139
|
+
* recovers as soon as the holder finishes.
|
|
140
|
+
*/
|
|
141
|
+
export class ConcurrentMigrationTimeoutError extends Error {
|
|
142
|
+
constructor(waitMs: number) {
|
|
143
|
+
super(
|
|
144
|
+
`Timed out waiting for another instance's migrations: the migration lock was still held after ${waitMs}ms. ` +
|
|
145
|
+
"It may still be applying migrations, or its migration may be failing repeatedly.",
|
|
146
|
+
);
|
|
147
|
+
this.name = "ConcurrentMigrationTimeoutError";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
126
151
|
/** Custom migration table name */
|
|
127
152
|
const MIGRATION_TABLE = "_emdash_migrations";
|
|
128
153
|
const MIGRATION_LOCK_TABLE = "_emdash_migrations_lock";
|
|
129
154
|
|
|
130
155
|
export interface MigrationOptions {
|
|
131
156
|
migrationTableSchema?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Override how long to wait for a concurrent migrator to finish before
|
|
159
|
+
* giving up. Defaults to MIGRATION_RACE_WAIT_MS; tests shorten it so the
|
|
160
|
+
* give-up path doesn't take 10 seconds per case.
|
|
161
|
+
*/
|
|
162
|
+
raceWaitMs?: number;
|
|
132
163
|
}
|
|
133
164
|
|
|
134
165
|
function createMigrator(db: Kysely<Database>, options?: MigrationOptions): Migrator {
|
|
@@ -260,8 +291,11 @@ async function getAppliedMigrationCount(db: Kysely<Database>): Promise<number |
|
|
|
260
291
|
* been migrated by a newer build still treats the wait as settled instead
|
|
261
292
|
* of timing out.
|
|
262
293
|
*/
|
|
263
|
-
async function waitForConcurrentMigrator(
|
|
264
|
-
|
|
294
|
+
async function waitForConcurrentMigrator(
|
|
295
|
+
db: Kysely<Database>,
|
|
296
|
+
waitMs: number = MIGRATION_RACE_WAIT_MS,
|
|
297
|
+
): Promise<boolean> {
|
|
298
|
+
const deadline = Date.now() + waitMs;
|
|
265
299
|
while (Date.now() < deadline) {
|
|
266
300
|
const count = await getAppliedMigrationCount(db);
|
|
267
301
|
if (count !== null && count >= MIGRATION_COUNT) {
|
|
@@ -341,13 +375,25 @@ export async function runMigrations(
|
|
|
341
375
|
const failedMigration = results?.find((r) => r.status === "Error");
|
|
342
376
|
|
|
343
377
|
// Concurrent-migration race: another caller is applying (or just
|
|
344
|
-
// applied) the same migration.
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
378
|
+
// applied) the same migration. SQLite/D1 surface it as the
|
|
379
|
+
// bookkeeping UNIQUE violation (their migration lock is a no-op);
|
|
380
|
+
// Postgres surfaces it as the fail-fast advisory try-lock reporting
|
|
381
|
+
// busy (see pg-migration-lock.ts). Either way: wait for the
|
|
382
|
+
// concurrent migrator to finish, then verify the schema is fully
|
|
383
|
+
// migrated and treat as success.
|
|
384
|
+
const lockBusy = msg.includes(MIGRATION_LOCK_BUSY_MESSAGE);
|
|
385
|
+
if (MIGRATION_RACE_PATTERN.test(msg) || lockBusy) {
|
|
386
|
+
const settled = await waitForConcurrentMigrator(db, options?.raceWaitMs);
|
|
348
387
|
if (settled) {
|
|
349
388
|
return { applied };
|
|
350
389
|
}
|
|
390
|
+
if (lockBusy) {
|
|
391
|
+
// The lock holder didn't finish within the wait window —
|
|
392
|
+
// either it's slow or its migration is failing. Surface a
|
|
393
|
+
// distinct error type instead of the raw sentinel message so
|
|
394
|
+
// callers can tell "still in progress" from "failed".
|
|
395
|
+
throw new ConcurrentMigrationTimeoutError(options?.raceWaitMs ?? MIGRATION_RACE_WAIT_MS);
|
|
396
|
+
}
|
|
351
397
|
}
|
|
352
398
|
|
|
353
399
|
const failedSuffix = failedMigration ? ` (migration: ${failedMigration.migrationName})` : "";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail-fast Postgres migration locking.
|
|
3
|
+
*
|
|
4
|
+
* Kysely's stock `PostgresAdapter.acquireMigrationLock` runs
|
|
5
|
+
* `select pg_advisory_xact_lock(...)` — an unbounded blocking wait on a
|
|
6
|
+
* database-wide advisory lock, held for the whole migration transaction.
|
|
7
|
+
* On Cloudflare Workers that is a stampede amplifier (#1744): every isolate
|
|
8
|
+
* that cold-starts while migrations are pending parks a connection inside
|
|
9
|
+
* Postgres waiting for the lock, and when the holder's migration fails and
|
|
10
|
+
* rolls back, the next waiter acquires the lock and re-runs the same
|
|
11
|
+
* failing migration.
|
|
12
|
+
*
|
|
13
|
+
* `FailFastPostgresDialect` swaps the blocking wait for
|
|
14
|
+
* `pg_try_advisory_xact_lock`: when another migrator holds the lock, the
|
|
15
|
+
* adapter throws `MIGRATION_LOCK_BUSY_MESSAGE` immediately instead of
|
|
16
|
+
* queueing inside the database. `runMigrations` treats that error like the
|
|
17
|
+
* SQLite/D1 concurrent-migration race — it polls the migration table with
|
|
18
|
+
* cheap bounded SELECTs until the concurrent migrator finishes (or the
|
|
19
|
+
* wait deadline passes), without holding a transaction open.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { DialectAdapter, Kysely, MigrationLockOptions } from "kysely";
|
|
23
|
+
import { PostgresAdapter as KyselyPostgresAdapter, PostgresDialect, sql } from "kysely";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sentinel message thrown when another migrator holds the advisory lock.
|
|
27
|
+
* `runMigrations` matches on it to route into the concurrent-migrator wait.
|
|
28
|
+
*/
|
|
29
|
+
export const MIGRATION_LOCK_BUSY_MESSAGE = "EMDASH_MIGRATION_LOCK_BUSY";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Kysely's advisory lock id (LOCK_ID in kysely's postgres-adapter). Reused
|
|
33
|
+
* deliberately: during a rolling deploy, old isolates still run the stock
|
|
34
|
+
* blocking adapter, and using the same id keeps old and new builds mutually
|
|
35
|
+
* exclusive on the same lock.
|
|
36
|
+
*/
|
|
37
|
+
const KYSELY_PG_MIGRATION_LOCK_ID = BigInt("3853314791062309107");
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Extends the stock adapter so every capability flag and `instanceof` check
|
|
41
|
+
* is inherited, and keeps the class NAME `PostgresAdapter` because
|
|
42
|
+
* `detectDialect()` (dialect-helpers.ts) identifies the dialect via
|
|
43
|
+
* `adapter.constructor.name` — a differently-named adapter would make every
|
|
44
|
+
* dialect helper fall back to SQLite SQL against a Postgres database.
|
|
45
|
+
*/
|
|
46
|
+
class PostgresAdapter extends KyselyPostgresAdapter {
|
|
47
|
+
// eslint-disable-next-line typescript/no-explicit-any -- matches the DialectAdapter signature
|
|
48
|
+
override async acquireMigrationLock(db: Kysely<any>, _opt: MigrationLockOptions): Promise<void> {
|
|
49
|
+
// Transaction-level lock, like the stock adapter: Postgres supports
|
|
50
|
+
// transactional DDL, so `db` here is the migration transaction and
|
|
51
|
+
// the lock is released automatically on commit/rollback.
|
|
52
|
+
const result = await sql<{ acquired: boolean }>`
|
|
53
|
+
select pg_try_advisory_xact_lock(${sql.lit(KYSELY_PG_MIGRATION_LOCK_ID)}) as acquired
|
|
54
|
+
`.execute(db);
|
|
55
|
+
if (!result.rows[0]?.acquired) {
|
|
56
|
+
throw new Error(MIGRATION_LOCK_BUSY_MESSAGE);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Drop-in replacement for Kysely's `PostgresDialect` whose migration lock
|
|
63
|
+
* fails fast instead of blocking inside the database. Everything except
|
|
64
|
+
* `createAdapter` is inherited unchanged, and because it subclasses
|
|
65
|
+
* `PostgresDialect`, the public dialect type of `emdash/db/postgres` stays
|
|
66
|
+
* `PostgresDialect` and `instanceof` checks keep working.
|
|
67
|
+
*/
|
|
68
|
+
export class FailFastPostgresDialect extends PostgresDialect {
|
|
69
|
+
override createAdapter(): DialectAdapter {
|
|
70
|
+
return new PostgresAdapter();
|
|
71
|
+
}
|
|
72
|
+
}
|