emdash 0.28.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-hUy8vOB-.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
- package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
- package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
- package/dist/{allowed-origins-CRsJ6BPM.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.d.mts.map +1 -1
- package/dist/api/route-utils.mjs +22 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -4
- package/dist/{api-DxFSorgk.mjs → api-b8WIiGU4.mjs} +306 -154
- package/dist/api-b8WIiGU4.mjs.map +1 -0
- package/dist/api-tokens-Cvmixds7.mjs +3 -0
- package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
- package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
- package/dist/{apply-CDJqIjPU.mjs → apply-CmIJK9j8.mjs} +35 -38
- package/dist/apply-CmIJK9j8.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +97 -13
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +56 -107
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.d.mts +3 -0
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +258 -31
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +47 -3
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +379 -117
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/PluginRegistry.d.mts +5 -1
- package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
- package/dist/astro/routes/PluginRegistry.mjs +2 -1
- package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +19 -24
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +30 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +49 -41
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +46 -41
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +49 -41
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +49 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +48 -43
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +43 -40
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +43 -40
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +10 -9
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- package/dist/astro/routes/api/admin/users/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +14 -13
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +11 -10
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +13 -12
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +13 -12
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
- package/dist/astro/routes/api/auth/me.mjs +9 -8
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +6 -3
- package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +16 -6
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +14 -13
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +13 -12
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +70 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +14 -13
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +9 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +72 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +51 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +20 -19
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +19 -18
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -16
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +19 -18
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +29 -28
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +8 -9
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.d.mts.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +165 -52
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +10 -9
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +26 -10
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +11 -10
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +34 -14
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +10 -9
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +7 -8
- package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
- package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/openapi.json.mjs +71 -24
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +13 -12
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +13 -12
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +14 -13
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +14 -13
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
- package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs +70 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/relations/index.d.mts +9 -0
- package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/index.mjs +54 -0
- package/dist/astro/routes/api/relations/index.mjs.map +1 -0
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -9
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +43 -40
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +43 -40
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +13 -12
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +14 -12
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +13 -12
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +12 -11
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +12 -11
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
- package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
- package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +16 -15
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +20 -16
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +19 -15
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -29
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +31 -30
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.mjs +9 -216
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/index.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +9 -9
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
- package/dist/astro/routes/sitemap.xml.mjs +10 -10
- package/dist/astro/types.d.mts +40 -16
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-Dz88F_Fw.mjs → authorize-WxsiePzy.mjs} +7 -4
- package/dist/authorize-WxsiePzy.mjs.map +1 -0
- package/dist/backup-S8kFWtwD.mjs +241 -0
- package/dist/backup-S8kFWtwD.mjs.map +1 -0
- package/dist/{base64-CmWvODNW.mjs → base64-B-PsqheR.mjs} +8 -4
- package/dist/base64-B-PsqheR.mjs.map +1 -0
- package/dist/{byline-Bm8ZgUP9.mjs → byline-XEjchwzZ.mjs} +8 -8
- package/dist/{byline-Bm8ZgUP9.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
- package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-CdU_LTF1.mjs} +2 -2
- package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
- package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
- package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
- package/dist/{bylines-6tm9mgQb.mjs → bylines-BJbT4gKS.mjs} +4 -4
- package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
- package/dist/{bylines-CAZxGSrm.mjs → bylines-czseViYo.mjs} +8 -8
- package/dist/{bylines-CAZxGSrm.mjs.map → bylines-czseViYo.mjs.map} +1 -1
- package/dist/{cache-CEBAZjir.mjs → cache-CGCd6AVM.mjs} +3 -3
- package/dist/{cache-CEBAZjir.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs → challenge-store-BFzgFRog.mjs} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
- package/dist/{chunks-B2isWQhr.mjs → chunks-BxXyunY-.mjs} +2 -2
- package/dist/{chunks-B2isWQhr.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
- package/dist/cli/index.mjs +142 -35
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +86 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +20 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-CzeatwBV.mjs → comment-DPT0WKyd.mjs} +2 -2
- package/dist/{comment-CzeatwBV.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
- package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-C65MldIB.mjs} +2 -2
- package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
- package/dist/{comments-BLE-jv5k.mjs → comments-Bz6sCbgD.mjs} +3 -3
- package/dist/{comments-BLE-jv5k.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
- package/dist/{components-B_sATNUc.mjs → components-DZkL4Fx0.mjs} +1 -1
- package/dist/{components-B_sATNUc.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
- package/dist/{content-DhgEth4k.mjs → content-Ci04z2z-.mjs} +227 -34
- package/dist/content-Ci04z2z-.mjs.map +1 -0
- package/dist/{content-refresh-Br4gMzh8.mjs → content-refresh-D4khvC0R.mjs} +100 -8
- package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
- package/dist/{context-BRIpHARC.mjs → context-B6hc7zJL.mjs} +156 -76
- package/dist/context-B6hc7zJL.mjs.map +1 -0
- package/dist/{cron-v4FTEFR_.mjs → cron-BlKIMD_e.mjs} +1 -1
- package/dist/{cron-v4FTEFR_.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
- package/dist/{dashboard-EvEKF5en.mjs → dashboard-C5NkXFbi.mjs} +6 -5
- package/dist/dashboard-C5NkXFbi.mjs.map +1 -0
- package/dist/database/pg-migration-lock.d.mts +21 -0
- package/dist/database/pg-migration-lock.d.mts.map +1 -0
- package/dist/database/pg-migration-lock.mjs +45 -0
- package/dist/database/pg-migration-lock.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +2 -8
- package/dist/db/postgres.mjs.map +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CK46D-ly.mjs → db-errors-CcWLaRiR.mjs} +4 -2
- package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
- package/dist/{default-CM_D83Mg.mjs → default-C4v9KP56.mjs} +1 -1
- package/dist/{default-CM_D83Mg.mjs.map → default-C4v9KP56.mjs.map} +1 -1
- package/dist/{device-flow-CfGP18Uw.mjs → device-flow-BeA6lUS1.mjs} +6 -7
- package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs +175 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs.map +1 -0
- package/dist/{email-console-CIf4Lfvv.mjs → email-console-C-9Ng8DM.mjs} +1 -1
- package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
- package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
- package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
- package/dist/error-CEGF6UZb.mjs +90 -0
- package/dist/error-CEGF6UZb.mjs.map +1 -0
- package/dist/{error-CkAseSqZ.mjs → errors-DtEXIQQV.mjs} +24 -84
- package/dist/errors-DtEXIQQV.mjs.map +1 -0
- package/dist/{escape-DqD0aCKu.mjs → escape-CFedIB1C.mjs} +1 -1
- package/dist/{escape-DqD0aCKu.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
- package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-DvmlgP-D.mjs} +5 -5
- package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
- package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-DzqIBrrW.mjs} +27 -3
- package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
- package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
- package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
- package/dist/hreflang-CIxH_LKz.d.mts +48 -0
- package/dist/hreflang-CIxH_LKz.d.mts.map +1 -0
- package/dist/hreflang-db2Tpb2o.mjs +102 -0
- package/dist/hreflang-db2Tpb2o.mjs.map +1 -0
- package/dist/{import-fYLf14Co.mjs → import-Dmkm8S1W.mjs} +6 -6
- package/dist/{import-fYLf14Co.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
- package/dist/{index-Bm-Gy8Mh.d.mts → index-BEui-cRd.d.mts} +3 -3
- package/dist/{index-Bm-Gy8Mh.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
- package/dist/{index-B9sIxwe4.d.mts → index-wYnC6u4o.d.mts} +881 -22
- package/dist/index-wYnC6u4o.d.mts.map +1 -0
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +69 -64
- package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
- package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
- package/dist/{load-Djn3HWQS.mjs → load-Cx27ki1l.mjs} +2 -2
- package/dist/{load-Djn3HWQS.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
- package/dist/{loader-CB6YHeul.mjs → loader-Be3ouI5L.mjs} +170 -21
- package/dist/loader-Be3ouI5L.mjs.map +1 -0
- package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-bCq54i7F.mjs} +18 -2
- package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +30 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +30 -4
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +8 -8
- package/dist/{media-BrXIaMFN.mjs → media-BjhhENaJ.mjs} +2 -2
- package/dist/media-BjhhENaJ.mjs.map +1 -0
- package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-jUppPWFy.mjs} +2 -2
- package/dist/{media-allowlist-CRHEeJ_i.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
- package/dist/media-kIV1IxFf.mjs +243 -0
- package/dist/media-kIV1IxFf.mjs.map +1 -0
- package/dist/media-upload-D2wk3EIt.mjs +145 -0
- package/dist/media-upload-D2wk3EIt.mjs.map +1 -0
- package/dist/{media-url-CKi5XSw4.mjs → media-url-BCm5vBn6.mjs} +1 -1
- package/dist/{media-url-CKi5XSw4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
- package/dist/media-usage-CljdO1mc.mjs +554 -0
- package/dist/media-usage-CljdO1mc.mjs.map +1 -0
- package/dist/{menus-b2T4clbO.mjs → menus-BcyElFtI.mjs} +177 -15
- package/dist/menus-BcyElFtI.mjs.map +1 -0
- package/dist/{menus-Cfivc2Ad.mjs → menus-CZyG6rvx.mjs} +3 -3
- package/dist/{menus-Cfivc2Ad.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
- package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
- package/dist/{mode-BM9QgEmt.mjs → mode-fiXRMfeA.mjs} +1 -1
- package/dist/{mode-BM9QgEmt.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
- package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
- package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
- package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-oqfbBuMH.mjs} +6 -7
- package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
- package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
- package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
- package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
- package/dist/{options-iMpRRxIe.d.mts → options-BqMkWfYa.d.mts} +6 -6
- package/dist/{options-iMpRRxIe.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.d.mts.map +1 -1
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-GmjecGct.mjs → parse-C_-6klII.mjs} +4 -12
- package/dist/{parse-GmjecGct.mjs.map → parse-C_-6klII.mjs.map} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +21 -2
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +18 -16
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugin-utils.mjs +8 -6
- package/dist/plugin-utils.mjs.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs → portable-text-sDj92Kxv.mjs} +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
- package/dist/{preview-SSXNVPAC.mjs → preview-D4Jnbfx7.mjs} +2 -2
- package/dist/{preview-SSXNVPAC.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
- package/dist/{public-url-Danv47cS.mjs → public-url-DSGTnJFw.mjs} +5 -3
- package/dist/public-url-DSGTnJFw.mjs.map +1 -0
- package/dist/{query-1Cp6U9oo.mjs → query-DR73ZNfm.mjs} +15 -15
- package/dist/query-DR73ZNfm.mjs.map +1 -0
- package/dist/{schema-CX9cfNkZ.mjs → query-Di7DOmPV.mjs} +5 -10
- package/dist/query-Di7DOmPV.mjs.map +1 -0
- package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-CMj83JNW.mjs} +2 -2
- package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs → redirect-Botom7X6.mjs} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
- package/dist/{redirect-IyfNirgS.mjs → redirect-CgLPYflR.mjs} +11 -5
- package/dist/redirect-CgLPYflR.mjs.map +1 -0
- package/dist/{redirects-Bs1g42Ri.mjs → redirects-B7t9bKsL.mjs} +6 -6
- package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
- package/dist/{redirects-DXEXBAII.mjs → redirects-BBq3n2Rj.mjs} +10 -143
- package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
- package/dist/{registry-B57vp_X9.mjs → registry-FV15nLge.mjs} +99 -10
- package/dist/registry-FV15nLge.mjs.map +1 -0
- package/dist/relation-9M9j_UWo.mjs +334 -0
- package/dist/relation-9M9j_UWo.mjs.map +1 -0
- package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-5_avdrN_.mjs} +60 -4
- package/dist/relations-5_avdrN_.mjs.map +1 -0
- package/dist/relations-BKvO39-9.mjs +397 -0
- package/dist/relations-BKvO39-9.mjs.map +1 -0
- package/dist/{byline-fields-CHE8UStY.d.mts → relations-Bh8jlFsU.d.mts} +486 -31
- package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
- package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
- package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
- package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DzXYYI-n.mjs} +2 -2
- package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
- package/dist/{runner-DvFWoz8-.d.mts → runner-Dd8m8k9F.d.mts} +8 -2
- package/dist/runner-Dd8m8k9F.d.mts.map +1 -0
- package/dist/{runner-K8XK101B.mjs → runner-DfnZ5eUr.mjs} +355 -204
- package/dist/runner-DfnZ5eUr.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +4 -4
- package/dist/schema-BXxlHeAf.mjs +9 -0
- package/dist/schema-BXxlHeAf.mjs.map +1 -0
- package/dist/scopes-Bl4IwHA-.mjs +27 -0
- package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
- package/dist/{search-DZN2HZ-V.mjs → search-Bff-7jFt.mjs} +62 -12
- package/dist/search-Bff-7jFt.mjs.map +1 -0
- package/dist/{secrets-kp760LlD.mjs → secrets-CSwQIl4q.mjs} +4 -4
- package/dist/{secrets-kp760LlD.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
- package/dist/{sections-CpF5SaGr.mjs → sections-CwW4s1al.mjs} +3 -3
- package/dist/{sections-CpF5SaGr.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +23 -23
- package/dist/seo/index.d.mts +15 -2
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +22 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-DXu2UQnC.mjs → seo-2cmFHZns.mjs} +2 -2
- package/dist/{seo-DXu2UQnC.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
- package/dist/{seo-89-53DDs.mjs → seo-C3GDfT0V.mjs} +1 -1
- package/dist/{seo-89-53DDs.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
- package/dist/{service-DQmiBMzt.mjs → service-DkGTWGIi.mjs} +3 -3
- package/dist/{service-DQmiBMzt.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
- package/dist/{session-user-Cascbax7.mjs → session-user-DbHqKDKe.mjs} +1 -1
- package/dist/{session-user-Cascbax7.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
- package/dist/{settings-rZyHEcNT.mjs → settings-C4s8hFQm.mjs} +3 -3
- package/dist/{settings-rZyHEcNT.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
- package/dist/{settings-zhmdKyJQ.mjs → settings-CpA4lQFt.mjs} +6 -6
- package/dist/{settings-zhmdKyJQ.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
- package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-CdIlqloh.mjs} +2 -2
- package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
- package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-C2exrGAi.mjs} +2 -2
- package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
- package/dist/{site-url-BBfDTgZB.mjs → site-url-NGJT6NTU.mjs} +2 -2
- package/dist/{site-url-BBfDTgZB.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
- package/dist/snapshot-BdpUJKD-.mjs +216 -0
- package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
- package/dist/{ssrf-1g7usGBg.mjs → ssrf-CviKqWmq.mjs} +1 -1
- package/dist/{ssrf-1g7usGBg.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
- package/dist/state-xxv6ZTMv.mjs +128 -0
- package/dist/state-xxv6ZTMv.mjs.map +1 -0
- package/dist/{status-CqJQX1QN.mjs → status-COfycGIU.mjs} +1 -1
- package/dist/{status-CqJQX1QN.mjs.map → status-COfycGIU.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-Bs13SN-F.mjs → taxonomies-Ce49uIzY.mjs} +13 -9
- package/dist/taxonomies-Ce49uIzY.mjs.map +1 -0
- package/dist/{taxonomies-kH9ABDUF.mjs → taxonomies-DjSKBZpq.mjs} +115 -36
- package/dist/taxonomies-DjSKBZpq.mjs.map +1 -0
- package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-DfVooU4W.mjs} +60 -13
- package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
- package/dist/{tokens-BGT0TUUo.mjs → tokens-DVltpO2D.mjs} +2 -2
- package/dist/{tokens-BGT0TUUo.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
- package/dist/{transport-DPefPMcz.mjs → transport-CKrlqSpD.mjs} +1 -1
- package/dist/{transport-DPefPMcz.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
- package/dist/{types-CgvhU-hF.d.mts → types-B4vm81VH.d.mts} +1 -1
- package/dist/{types-CgvhU-hF.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
- package/dist/{types-ea9sAPck.d.mts → types-B97jg3aW.d.mts} +6 -1
- package/dist/{types-ea9sAPck.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
- package/dist/{types-Jo3UYd6b.mjs → types-BD40g7zz.mjs} +1 -1
- package/dist/{types-Jo3UYd6b.mjs.map → types-BD40g7zz.mjs.map} +1 -1
- package/dist/{types-DmHk7vAt.d.mts → types-BNfPHfay.d.mts} +1 -1
- package/dist/{types-DmHk7vAt.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
- package/dist/{types-BcLUUbbR.d.mts → types-BfYUPJdP.d.mts} +11 -3
- package/dist/{types-BcLUUbbR.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
- package/dist/{types-CGbYowGQ.d.mts → types-BvB7gDOD.d.mts} +90 -4
- package/dist/types-BvB7gDOD.d.mts.map +1 -0
- package/dist/{types-vgEWF18A.d.mts → types-C7U0HlEr.d.mts} +1 -1
- package/dist/{types-vgEWF18A.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
- package/dist/{types-CuW0zWDA.mjs → types-D1iJ3DpO.mjs} +3 -3
- package/dist/{types-CuW0zWDA.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
- package/dist/{types-_HFLRzTn.d.mts → types-DPKhI5ib.d.mts} +9 -1
- package/dist/types-DPKhI5ib.d.mts.map +1 -0
- package/dist/{types-g_aFIdW0.d.mts → types-Kmaxdarz.d.mts} +1 -1
- package/dist/{types-g_aFIdW0.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
- package/dist/{types-ClUkdbWb.d.mts → types-iVeZ5g6N.d.mts} +1 -1
- package/dist/{types-ClUkdbWb.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
- package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
- package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
- package/dist/{user-BjAOvU3Z.mjs → user-Bh-L1qo6.mjs} +3 -3
- package/dist/{user-BjAOvU3Z.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
- package/dist/{utils-BJXElxdw.mjs → utils-BbUgmeZG.mjs} +3 -3
- package/dist/{utils-BJXElxdw.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
- package/dist/{validate-Z1b86_3B.d.mts → validate-DULfgpJP.d.mts} +5 -5
- package/dist/{validate-Z1b86_3B.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
- package/dist/{validate-CWSnKVIJ.mjs → validate-V9nCwq_-.mjs} +3 -3
- package/dist/{validate-CWSnKVIJ.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
- package/dist/{validation-0l8-RYj4.mjs → validation-BsVUJfsP.mjs} +10 -10
- package/dist/{validation-0l8-RYj4.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
- package/dist/version-907opKac.mjs +7 -0
- package/dist/{version-qmeO1XZY.mjs.map → version-907opKac.mjs.map} +1 -1
- package/dist/{widgets-hWcIicX8.mjs → widgets-DGv1Z04V.mjs} +4 -4
- package/dist/{widgets-hWcIicX8.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +4 -4
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
- package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-B5prQ5M4.mjs} +3 -3
- package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
- package/package.json +12 -8
- package/src/api/authorize.ts +10 -1
- package/src/api/error.ts +5 -5
- package/src/api/errors.ts +25 -0
- package/src/api/handlers/backup.ts +312 -0
- package/src/api/handlers/content.ts +147 -3
- package/src/api/handlers/dashboard.ts +2 -0
- package/src/api/handlers/device-flow.ts +2 -3
- package/src/api/handlers/index.ts +22 -0
- package/src/api/handlers/marketplace.ts +38 -0
- package/src/api/handlers/media-upload.ts +210 -0
- package/src/api/handlers/media-usage.ts +289 -0
- package/src/api/handlers/oauth-authorization.ts +2 -6
- package/src/api/handlers/plugin-settings.ts +218 -0
- package/src/api/handlers/plugins.ts +41 -0
- package/src/api/handlers/registry.ts +39 -0
- package/src/api/handlers/relations.ts +474 -0
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/handlers/taxonomies.ts +26 -4
- package/src/api/handlers/validate-media-fields.ts +1 -1
- package/src/api/openapi/document.ts +72 -5
- package/src/api/parse.ts +2 -16
- package/src/api/public-url.ts +4 -2
- package/src/api/schemas/comments.ts +6 -0
- package/src/api/schemas/common.ts +6 -2
- package/src/api/schemas/content.ts +8 -0
- package/src/api/schemas/index.ts +2 -0
- package/src/api/schemas/media-usage.ts +120 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/api/schemas/relations.ts +109 -0
- package/src/api/schemas/search.ts +1 -0
- package/src/astro/integration/index.ts +39 -0
- package/src/astro/integration/routes.ts +40 -0
- package/src/astro/integration/runtime.ts +30 -0
- package/src/astro/integration/virtual-modules.ts +41 -7
- package/src/astro/integration/vite-config.ts +17 -1
- package/src/astro/middleware/auth.ts +70 -78
- package/src/astro/middleware/csp.ts +5 -2
- package/src/astro/middleware/request-context.ts +162 -20
- package/src/astro/middleware.ts +108 -40
- package/src/astro/public-plugin-api-routes.ts +2 -1
- package/src/astro/routes/PluginRegistry.tsx +5 -2
- package/src/astro/routes/admin.astro +56 -16
- package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
- package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -2
- package/src/astro/routes/api/admin/comments/index.ts +1 -2
- package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
- package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
- package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/index.ts +9 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
- package/src/astro/routes/api/auth/mode.ts +6 -14
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -5
- package/src/astro/routes/api/auth/oauth/[provider].ts +24 -7
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +95 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +47 -0
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
- package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
- package/src/astro/routes/api/content/[collection]/index.ts +6 -8
- package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
- package/src/astro/routes/api/manifest.ts +2 -9
- package/src/astro/routes/api/mcp.ts +2 -1
- package/src/astro/routes/api/media/[id]/usage.ts +30 -0
- package/src/astro/routes/api/media/[id].ts +17 -6
- package/src/astro/routes/api/media/file/[...key].ts +8 -0
- package/src/astro/routes/api/media.ts +21 -2
- package/src/astro/routes/api/oauth/authorize.ts +2 -6
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
- package/src/astro/routes/api/relations/[id]/index.ts +84 -0
- package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
- package/src/astro/routes/api/relations/index.ts +56 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
- package/src/astro/routes/api/search/index.ts +2 -0
- package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
- package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
- package/src/astro/routes/api/settings/backups/export.ts +43 -0
- package/src/astro/routes/api/settings/backups/index.ts +76 -0
- package/src/astro/routes/api/setup/admin-verify.ts +8 -4
- package/src/astro/routes/api/setup/admin.ts +11 -4
- package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
- package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
- package/src/astro/types.ts +50 -2
- package/src/auth/api-tokens.ts +1 -0
- package/src/auth/oauth-state-store.ts +3 -0
- package/src/auth/providers/github-admin.tsx +5 -6
- package/src/auth/providers/google-admin.tsx +5 -6
- package/src/auth/scopes.ts +3 -9
- package/src/cli/client-factory.ts +0 -1
- package/src/cli/commands/bundle-utils.ts +50 -1
- package/src/cli/commands/bundle.ts +9 -2
- package/src/cli/commands/export-seed.ts +1 -10
- package/src/cli/commands/media.ts +127 -0
- package/src/client/index.ts +123 -2
- package/src/client/transport.ts +1 -1
- package/src/comments/service.ts +1 -1
- package/src/comments/turnstile.ts +64 -0
- package/src/components/BlockquoteGroup.astro +34 -0
- package/src/components/CommentForm.astro +12 -5
- package/src/components/EmDashHead.astro +31 -9
- package/src/components/InlinePortableTextEditor.tsx +88 -33
- package/src/components/PortableText.astro +7 -1
- package/src/components/index.ts +2 -0
- package/src/components/marks/Link.astro +5 -1
- package/src/components/portable-text-blockquote-group.ts +68 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
- package/src/database/dialect-helpers.ts +111 -3
- package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
- package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
- package/src/database/migrations/052_media_usage_read_index.ts +26 -0
- package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
- package/src/database/migrations/runner.ts +52 -6
- package/src/database/pg-migration-lock.ts +72 -0
- package/src/database/repositories/audit.ts +2 -1
- package/src/database/repositories/comment.ts +1 -1
- package/src/database/repositories/content.ts +270 -37
- package/src/database/repositories/media-usage.ts +250 -1
- package/src/database/repositories/media.ts +1 -1
- package/src/database/repositories/plugin-storage.ts +29 -32
- package/src/database/repositories/redirect.ts +14 -2
- package/src/database/repositories/relation.ts +130 -5
- package/src/database/repositories/taxonomy.ts +66 -8
- package/src/database/repositories/types.ts +8 -0
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +9 -0
- package/src/db/postgres.ts +5 -2
- package/src/emdash-runtime.ts +382 -70
- package/src/index.ts +6 -2
- package/src/loader.ts +293 -32
- package/src/mcp/server.ts +251 -8
- package/src/media/image-endpoint.ts +38 -2
- package/src/page/metadata.ts +27 -0
- package/src/plugin-types.ts +19 -0
- package/src/plugin-utils.ts +8 -6
- package/src/plugins/adapt-sandbox-entry.ts +30 -1
- package/src/plugins/context.ts +92 -0
- package/src/plugins/define-plugin.ts +17 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/manifest-schema.ts +30 -1
- package/src/plugins/routes.ts +27 -1
- package/src/plugins/sandbox/runner-options.ts +16 -0
- package/src/plugins/sandbox/types.ts +6 -1
- package/src/plugins/state.ts +17 -1
- package/src/plugins/storage-query.ts +67 -33
- package/src/plugins/types.ts +100 -0
- package/src/schema/byline-registry.ts +1 -1
- package/src/schema/registry.ts +141 -5
- package/src/search/fts-manager.ts +34 -0
- package/src/search/match.ts +50 -0
- package/src/search/query.ts +94 -9
- package/src/seed/apply.ts +28 -29
- package/src/seo/hreflang.ts +192 -0
- package/src/seo/index.ts +22 -4
- package/src/storage/types.ts +6 -0
- package/src/taxonomies/index.ts +62 -45
- package/src/taxonomies/term-counts.ts +117 -0
- package/src/utils/base64.ts +7 -2
- package/src/utils/db-errors.ts +3 -1
- package/src/virtual-modules.d.ts +14 -0
- package/src/visual-editing/editable.ts +41 -35
- package/src/visual-editing/toolbar-bootstrap.ts +120 -0
- package/src/visual-editing/toolbar.ts +47 -1
- package/dist/adapters-hUy8vOB-.d.mts.map +0 -1
- package/dist/api-DxFSorgk.mjs.map +0 -1
- package/dist/api-tokens-DsvvCtdh.mjs +0 -3
- package/dist/apply-CDJqIjPU.mjs.map +0 -1
- package/dist/authorize-Dz88F_Fw.mjs.map +0 -1
- package/dist/base64-CmWvODNW.mjs.map +0 -1
- package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
- package/dist/byline-fields-CHE8UStY.d.mts.map +0 -1
- package/dist/content-DhgEth4k.mjs.map +0 -1
- package/dist/content-refresh-Br4gMzh8.mjs.map +0 -1
- package/dist/context-BRIpHARC.mjs.map +0 -1
- package/dist/dashboard-EvEKF5en.mjs.map +0 -1
- package/dist/db-errors-CK46D-ly.mjs.map +0 -1
- package/dist/device-flow-CfGP18Uw.mjs.map +0 -1
- package/dist/dialect-helpers-DRI5pyY3.mjs +0 -110
- package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
- package/dist/error-CkAseSqZ.mjs.map +0 -1
- package/dist/index-B9sIxwe4.d.mts.map +0 -1
- package/dist/loader-CB6YHeul.mjs.map +0 -1
- package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
- package/dist/media-BrXIaMFN.mjs.map +0 -1
- package/dist/menus-b2T4clbO.mjs.map +0 -1
- package/dist/oauth-authorization-CXWkIGT4.mjs.map +0 -1
- package/dist/public-url-Danv47cS.mjs.map +0 -1
- package/dist/query-1Cp6U9oo.mjs.map +0 -1
- package/dist/redirect-IyfNirgS.mjs.map +0 -1
- package/dist/redirects-DXEXBAII.mjs.map +0 -1
- package/dist/registry-B57vp_X9.mjs.map +0 -1
- package/dist/runner-DvFWoz8-.d.mts.map +0 -1
- package/dist/runner-K8XK101B.mjs.map +0 -1
- package/dist/scheduled-publish-Drffrf2a.d.mts +0 -11
- package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
- package/dist/schema-CX9cfNkZ.mjs.map +0 -1
- package/dist/search-DZN2HZ-V.mjs.map +0 -1
- package/dist/taxonomies-Bs13SN-F.mjs.map +0 -1
- package/dist/taxonomies-kH9ABDUF.mjs.map +0 -1
- package/dist/taxonomy-BxGxZZdu.mjs.map +0 -1
- package/dist/types-CGbYowGQ.d.mts.map +0 -1
- package/dist/types-_HFLRzTn.d.mts.map +0 -1
- package/dist/version-qmeO1XZY.mjs +0 -7
- /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-BB__xfNM.mjs} +0 -0
- /package/dist/{types-DROWRxYV.mjs → types-CK0LxPUQ.mjs} +0 -0
package/src/plugins/types.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import type { Permission } from "@emdash-cms/auth";
|
|
12
13
|
import type { Element } from "@emdash-cms/blocks";
|
|
13
14
|
// The plugin capability vocabulary, the legacy-rename map, and the manifest
|
|
14
15
|
// shape are authored once in @emdash-cms/plugin-types and shared between core
|
|
@@ -28,7 +29,9 @@ import {
|
|
|
28
29
|
type DeclaredAccess,
|
|
29
30
|
type DeprecatedPluginCapability,
|
|
30
31
|
type ManifestHookEntry,
|
|
32
|
+
type ManifestMcpTool,
|
|
31
33
|
type ManifestRouteEntry,
|
|
34
|
+
type PluginMcpManifestConfig,
|
|
32
35
|
type PluginCapability,
|
|
33
36
|
type PluginStorageConfig,
|
|
34
37
|
type StorageCollectionConfig,
|
|
@@ -52,7 +55,9 @@ export {
|
|
|
52
55
|
type DeclaredAccess,
|
|
53
56
|
type DeprecatedPluginCapability,
|
|
54
57
|
type ManifestHookEntry,
|
|
58
|
+
type ManifestMcpTool,
|
|
55
59
|
type ManifestRouteEntry,
|
|
60
|
+
type PluginMcpManifestConfig,
|
|
56
61
|
type PluginCapability,
|
|
57
62
|
type PluginStorageConfig,
|
|
58
63
|
type StorageCollectionConfig,
|
|
@@ -213,6 +218,8 @@ export interface ContentItem {
|
|
|
213
218
|
createdAt: string;
|
|
214
219
|
updatedAt: string;
|
|
215
220
|
publishedAt: string | null;
|
|
221
|
+
/** Scheduled publication time, if set (e.g. scheduled items or scheduled draft changes). */
|
|
222
|
+
scheduledAt?: string | null;
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
export interface ContentListWhere {
|
|
@@ -244,6 +251,45 @@ export type ContentWriteInput = Record<string, unknown> & {
|
|
|
244
251
|
seo?: ContentItemSeoInput;
|
|
245
252
|
};
|
|
246
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Taxonomy definition returned from the taxonomy API (e.g. "category", "tag").
|
|
256
|
+
*/
|
|
257
|
+
export interface TaxonomyDefInfo {
|
|
258
|
+
name: string;
|
|
259
|
+
label: string;
|
|
260
|
+
labelSingular: string | null;
|
|
261
|
+
hierarchical: boolean;
|
|
262
|
+
/** Collections this taxonomy is attached to (e.g. `["posts"]`). */
|
|
263
|
+
collections: string[];
|
|
264
|
+
locale: string;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Taxonomy term returned from the taxonomy API. Flat shape — for hierarchical
|
|
269
|
+
* taxonomies the tree is reconstructed via `parentId` (which stores the
|
|
270
|
+
* parent's locale-agnostic `translationGroup`).
|
|
271
|
+
*/
|
|
272
|
+
export interface TaxonomyTermInfo {
|
|
273
|
+
id: string;
|
|
274
|
+
/** Taxonomy name this term belongs to (e.g. "category"). */
|
|
275
|
+
taxonomy: string;
|
|
276
|
+
slug: string;
|
|
277
|
+
label: string;
|
|
278
|
+
parentId: string | null;
|
|
279
|
+
/** Term metadata as edited in the admin (`description` etc.). */
|
|
280
|
+
data: Record<string, unknown> | null;
|
|
281
|
+
locale: string;
|
|
282
|
+
translationGroup: string | null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Options accepted by taxonomy read operations. Omitting `locale` returns
|
|
287
|
+
* rows for every locale.
|
|
288
|
+
*/
|
|
289
|
+
export interface TaxonomyReadOptions {
|
|
290
|
+
locale?: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
247
293
|
/**
|
|
248
294
|
* Content access interface - capability-gated
|
|
249
295
|
*/
|
|
@@ -258,6 +304,23 @@ export interface ContentAccess {
|
|
|
258
304
|
delete?(collection: string, id: string): Promise<boolean>;
|
|
259
305
|
}
|
|
260
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Taxonomy access interface — capability-gated on `taxonomies:read`.
|
|
309
|
+
* Read-only: there is no plugin-facing taxonomy write API.
|
|
310
|
+
*/
|
|
311
|
+
export interface TaxonomyAccess {
|
|
312
|
+
/** List taxonomy definitions. */
|
|
313
|
+
getAll(options?: TaxonomyReadOptions): Promise<TaxonomyDefInfo[]>;
|
|
314
|
+
/** All terms of a taxonomy, ordered by label. */
|
|
315
|
+
getTerms(taxonomy: string, options?: TaxonomyReadOptions): Promise<TaxonomyTermInfo[]>;
|
|
316
|
+
/** Terms assigned to a content entry, optionally scoped to one taxonomy. */
|
|
317
|
+
getEntryTerms(
|
|
318
|
+
collection: string,
|
|
319
|
+
entryId: string,
|
|
320
|
+
options?: TaxonomyReadOptions & { taxonomy?: string },
|
|
321
|
+
): Promise<TaxonomyTermInfo[]>;
|
|
322
|
+
}
|
|
323
|
+
|
|
261
324
|
/**
|
|
262
325
|
* Full content access with write operations
|
|
263
326
|
*/
|
|
@@ -361,6 +424,14 @@ export interface SiteInfo {
|
|
|
361
424
|
url: string;
|
|
362
425
|
/** Site locale (from settings, defaults to "en") */
|
|
363
426
|
locale: string;
|
|
427
|
+
/**
|
|
428
|
+
* Astro's `trailingSlash` routing policy, from the host's Astro config.
|
|
429
|
+
* Plugins that build absolute URLs (sitemap, canonical, hreflang) should
|
|
430
|
+
* honor this so the URLs they emit match what the site serves. `createSiteInfo`
|
|
431
|
+
* always populates it (defaulting to `"ignore"`, Astro's default); it is
|
|
432
|
+
* optional on the type so pre-existing `SiteInfo` construction stays valid.
|
|
433
|
+
*/
|
|
434
|
+
trailingSlash?: "always" | "never" | "ignore";
|
|
364
435
|
}
|
|
365
436
|
|
|
366
437
|
/**
|
|
@@ -413,6 +484,9 @@ export interface PluginContext<TStorage extends PluginStorageConfig = PluginStor
|
|
|
413
484
|
/** Content access - only if read:content or write:content capability */
|
|
414
485
|
content?: ContentAccess | ContentAccessWithWrite;
|
|
415
486
|
|
|
487
|
+
/** Taxonomy access (read-only) - only if taxonomies:read capability */
|
|
488
|
+
taxonomies?: TaxonomyAccess;
|
|
489
|
+
|
|
416
490
|
/** Media access - only if read:media or write:media capability */
|
|
417
491
|
media?: MediaAccess | MediaAccessWithWrite;
|
|
418
492
|
|
|
@@ -1114,10 +1188,31 @@ export interface PluginRoute<TInput = unknown> {
|
|
|
1114
1188
|
* Public routes skip session/token auth and CSRF checks.
|
|
1115
1189
|
*/
|
|
1116
1190
|
public?: boolean;
|
|
1191
|
+
/** RBAC permission required to invoke the route. Legacy routes default to plugins:manage. */
|
|
1192
|
+
permission?: Permission;
|
|
1193
|
+
/**
|
|
1194
|
+
* `Cache-Control` header value for successful GET responses, e.g.
|
|
1195
|
+
* `"public, max-age=60, stale-while-revalidate=300"`. Only honored on
|
|
1196
|
+
* routes that are also `public: true` — authenticated responses always
|
|
1197
|
+
* keep the default `private, no-store`. Errors are never cached.
|
|
1198
|
+
*/
|
|
1199
|
+
cacheControl?: string;
|
|
1117
1200
|
/** Route handler */
|
|
1118
1201
|
handler: (ctx: RouteContext<TInput>) => Promise<unknown>;
|
|
1119
1202
|
}
|
|
1120
1203
|
|
|
1204
|
+
export interface PluginMcpToolDefinition {
|
|
1205
|
+
description: string;
|
|
1206
|
+
route: string;
|
|
1207
|
+
input: z.ZodType;
|
|
1208
|
+
output?: z.ZodType;
|
|
1209
|
+
destructive?: boolean;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
export interface PluginMcpConfig {
|
|
1213
|
+
tools: Record<string, PluginMcpToolDefinition>;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1121
1216
|
// =============================================================================
|
|
1122
1217
|
// Plugin Definition
|
|
1123
1218
|
// =============================================================================
|
|
@@ -1299,6 +1394,9 @@ export interface PluginDefinition<TStorage extends PluginStorageConfig = PluginS
|
|
|
1299
1394
|
/** API routes */
|
|
1300
1395
|
routes?: Record<string, PluginRoute>;
|
|
1301
1396
|
|
|
1397
|
+
/** Routes explicitly exposed as agent-callable MCP tools. */
|
|
1398
|
+
mcp?: PluginMcpConfig;
|
|
1399
|
+
|
|
1302
1400
|
/** Admin UI configuration */
|
|
1303
1401
|
admin?: PluginAdminConfig;
|
|
1304
1402
|
}
|
|
@@ -1314,6 +1412,7 @@ export interface ResolvedPlugin<TStorage extends PluginStorageConfig = PluginSto
|
|
|
1314
1412
|
storage: TStorage;
|
|
1315
1413
|
hooks: ResolvedPluginHooks;
|
|
1316
1414
|
routes: Record<string, PluginRoute>;
|
|
1415
|
+
mcp?: PluginMcpConfig;
|
|
1317
1416
|
admin: PluginAdminConfig;
|
|
1318
1417
|
}
|
|
1319
1418
|
|
|
@@ -1394,6 +1493,7 @@ export interface PluginManifest {
|
|
|
1394
1493
|
hooks: Array<ManifestHookEntry | HookName>;
|
|
1395
1494
|
/** Route declarations — either plain name strings or structured objects */
|
|
1396
1495
|
routes: Array<ManifestRouteEntry | string>;
|
|
1496
|
+
mcp?: PluginMcpManifestConfig;
|
|
1397
1497
|
admin: PluginAdminConfig;
|
|
1398
1498
|
}
|
|
1399
1499
|
|
|
@@ -627,7 +627,7 @@ export class BylineSchemaRegistry {
|
|
|
627
627
|
// payload silently. Today's `BylineFieldValidation` is `{ options? }`
|
|
628
628
|
// only, so this branch is a pass-through; left explicit for clarity.
|
|
629
629
|
const { options: _drop, ...rest } = validation;
|
|
630
|
-
return Object.keys(rest).length === 0 ? null :
|
|
630
|
+
return Object.keys(rest).length === 0 ? null : rest;
|
|
631
631
|
}
|
|
632
632
|
}
|
|
633
633
|
|
package/src/schema/registry.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { Kysely } from "kysely";
|
|
2
|
-
import type { Selectable } from "kysely";
|
|
1
|
+
import type { ColumnDataType, CreateTableBuilder, Insertable, Kysely, Selectable } from "kysely";
|
|
3
2
|
import { sql } from "kysely";
|
|
4
3
|
import { ulid } from "ulidx";
|
|
5
4
|
|
|
@@ -39,6 +38,12 @@ const WORD_BOUNDARY_PATTERN = /\b\w/g;
|
|
|
39
38
|
|
|
40
39
|
/** Valid column types for runtime validation */
|
|
41
40
|
const COLUMN_TYPES: ReadonlySet<string> = new Set(["TEXT", "REAL", "INTEGER", "JSON"]);
|
|
41
|
+
const COLUMN_TYPE_TO_DATA_TYPE = {
|
|
42
|
+
TEXT: "text",
|
|
43
|
+
REAL: "real",
|
|
44
|
+
INTEGER: "integer",
|
|
45
|
+
JSON: "json",
|
|
46
|
+
} satisfies Record<ColumnType, ColumnDataType>;
|
|
42
47
|
|
|
43
48
|
/** Valid collection source prefixes/values */
|
|
44
49
|
const VALID_SOURCES: ReadonlySet<string> = new Set(["manual", "discovered", "seed"]);
|
|
@@ -64,6 +69,10 @@ const VALID_COLLECTION_SUPPORTS: ReadonlySet<string> = new Set<CollectionSupport
|
|
|
64
69
|
"seo",
|
|
65
70
|
]);
|
|
66
71
|
|
|
72
|
+
// Each _emdash_fields row uses 15 bound parameters. Six rows keep every
|
|
73
|
+
// multi-row INSERT below D1's 100-parameter statement limit.
|
|
74
|
+
const SEED_FIELD_INSERT_BATCH_SIZE = 6;
|
|
75
|
+
|
|
67
76
|
function isCollectionSupport(value: unknown): value is CollectionSupport {
|
|
68
77
|
return typeof value === "string" && VALID_COLLECTION_SUPPORTS.has(value);
|
|
69
78
|
}
|
|
@@ -264,6 +273,113 @@ export class SchemaRegistry {
|
|
|
264
273
|
return collection;
|
|
265
274
|
}
|
|
266
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Create a seed-owned collection and all of its fields in bulk.
|
|
278
|
+
*
|
|
279
|
+
* Fresh seeds can define dozens of fields. Creating them through
|
|
280
|
+
* `createField` performs multiple reads, one ALTER TABLE, and one media
|
|
281
|
+
* usage invalidation per field, which can exhaust D1's per-request query
|
|
282
|
+
* budget. This path validates the full schema before mutating it, creates
|
|
283
|
+
* the complete content table in one statement, and inserts field metadata
|
|
284
|
+
* in parameter-safe batches.
|
|
285
|
+
*/
|
|
286
|
+
async createSeedCollection(
|
|
287
|
+
input: Omit<CreateCollectionInput, "source">,
|
|
288
|
+
fields: readonly CreateFieldInput[],
|
|
289
|
+
): Promise<void> {
|
|
290
|
+
this.validateSlug(input.slug, "collection");
|
|
291
|
+
if (RESERVED_COLLECTION_SLUGS.includes(input.slug)) {
|
|
292
|
+
throw new SchemaError(`Collection slug "${input.slug}" is reserved`, "RESERVED_SLUG");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const existing = await this.getCollection(input.slug);
|
|
296
|
+
if (existing) {
|
|
297
|
+
throw new SchemaError(`Collection "${input.slug}" already exists`, "COLLECTION_EXISTS");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const fieldSlugs = new Set<string>();
|
|
301
|
+
for (const field of fields) {
|
|
302
|
+
this.validateSlug(field.slug, "field");
|
|
303
|
+
if (RESERVED_FIELD_SLUGS.includes(field.slug)) {
|
|
304
|
+
throw new SchemaError(`Field slug "${field.slug}" is reserved`, "RESERVED_SLUG");
|
|
305
|
+
}
|
|
306
|
+
if (fieldSlugs.has(field.slug)) {
|
|
307
|
+
throw new SchemaError(
|
|
308
|
+
`Field "${field.slug}" already exists in collection "${input.slug}"`,
|
|
309
|
+
"FIELD_EXISTS",
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
fieldSlugs.add(field.slug);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const collectionId = ulid();
|
|
316
|
+
const supports = input.supports ?? ["drafts", "revisions"];
|
|
317
|
+
const hasSeo = input.hasSeo ?? supports.includes("seo") ?? false;
|
|
318
|
+
let maxSortOrder = -1;
|
|
319
|
+
const fieldRows: Insertable<FieldTable>[] = fields.map((field) => {
|
|
320
|
+
const sortOrder = field.sortOrder ?? maxSortOrder + 1;
|
|
321
|
+
maxSortOrder = Math.max(maxSortOrder, sortOrder);
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
id: ulid(),
|
|
325
|
+
collection_id: collectionId,
|
|
326
|
+
slug: field.slug,
|
|
327
|
+
label: field.label,
|
|
328
|
+
type: field.type,
|
|
329
|
+
column_type: FIELD_TYPE_TO_COLUMN[field.type],
|
|
330
|
+
required: field.required ? 1 : 0,
|
|
331
|
+
unique: field.unique ? 1 : 0,
|
|
332
|
+
default_value: field.defaultValue !== undefined ? JSON.stringify(field.defaultValue) : null,
|
|
333
|
+
validation: field.validation ? JSON.stringify(field.validation) : null,
|
|
334
|
+
widget: field.widget ?? null,
|
|
335
|
+
options: field.options ? JSON.stringify(field.options) : null,
|
|
336
|
+
sort_order: sortOrder,
|
|
337
|
+
searchable: field.searchable ? 1 : 0,
|
|
338
|
+
translatable: field.translatable === false ? 0 : 1,
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
let schemaMutated = false;
|
|
343
|
+
try {
|
|
344
|
+
await withTransaction(this.db, async (trx) => {
|
|
345
|
+
await trx
|
|
346
|
+
.insertInto("_emdash_collections")
|
|
347
|
+
.values({
|
|
348
|
+
id: collectionId,
|
|
349
|
+
slug: input.slug,
|
|
350
|
+
label: input.label,
|
|
351
|
+
label_singular: input.labelSingular ?? null,
|
|
352
|
+
description: input.description ?? null,
|
|
353
|
+
icon: input.icon ?? null,
|
|
354
|
+
supports: JSON.stringify(supports),
|
|
355
|
+
source: "seed",
|
|
356
|
+
has_seo: hasSeo ? 1 : 0,
|
|
357
|
+
comments_enabled: input.commentsEnabled ? 1 : 0,
|
|
358
|
+
url_pattern: input.urlPattern ?? null,
|
|
359
|
+
})
|
|
360
|
+
.execute();
|
|
361
|
+
schemaMutated = true;
|
|
362
|
+
|
|
363
|
+
await this.createContentTable(input.slug, trx, fields);
|
|
364
|
+
|
|
365
|
+
for (const fieldBatch of chunks(fieldRows, SEED_FIELD_INSERT_BATCH_SIZE)) {
|
|
366
|
+
await trx.insertInto("_emdash_fields").values(fieldBatch).execute();
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
await markContentMediaUsageCollectionStaleSafely(this.db, input.slug, "CONTENT_USAGE_STALE");
|
|
371
|
+
} catch (error) {
|
|
372
|
+
if (schemaMutated) {
|
|
373
|
+
await markContentMediaUsageCollectionStaleSafely(
|
|
374
|
+
this.db,
|
|
375
|
+
input.slug,
|
|
376
|
+
"CONTENT_USAGE_STALE",
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
throw error;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
267
383
|
/**
|
|
268
384
|
* Update a collection
|
|
269
385
|
*/
|
|
@@ -787,11 +903,15 @@ export class SchemaRegistry {
|
|
|
787
903
|
/**
|
|
788
904
|
* Create a content table for a collection
|
|
789
905
|
*/
|
|
790
|
-
private async createContentTable(
|
|
906
|
+
private async createContentTable(
|
|
907
|
+
slug: string,
|
|
908
|
+
db?: Kysely<Database>,
|
|
909
|
+
fields: readonly CreateFieldInput[] = [],
|
|
910
|
+
): Promise<void> {
|
|
791
911
|
const conn = db ?? this.db;
|
|
792
912
|
const tableName = this.getTableName(slug);
|
|
793
913
|
|
|
794
|
-
|
|
914
|
+
let table: CreateTableBuilder<string, string> = conn.schema
|
|
795
915
|
.createTable(tableName)
|
|
796
916
|
.addColumn("id", "text", (col) => col.primaryKey())
|
|
797
917
|
.addColumn("slug", "text")
|
|
@@ -807,7 +927,23 @@ export class SchemaRegistry {
|
|
|
807
927
|
.addColumn("live_revision_id", "text", (col) => col.references("revisions.id"))
|
|
808
928
|
.addColumn("draft_revision_id", "text", (col) => col.references("revisions.id"))
|
|
809
929
|
.addColumn("locale", "text", (col) => col.notNull().defaultTo("en"))
|
|
810
|
-
.addColumn("translation_group", "text")
|
|
930
|
+
.addColumn("translation_group", "text");
|
|
931
|
+
|
|
932
|
+
for (const field of fields) {
|
|
933
|
+
const columnName = this.getColumnName(field.slug);
|
|
934
|
+
const columnType = COLUMN_TYPE_TO_DATA_TYPE[FIELD_TYPE_TO_COLUMN[field.type]];
|
|
935
|
+
table = table.addColumn(columnName, columnType, (column) => {
|
|
936
|
+
if (!field.required) return column;
|
|
937
|
+
|
|
938
|
+
const defaultValue =
|
|
939
|
+
field.defaultValue !== undefined
|
|
940
|
+
? this.formatDefaultValue(field.defaultValue, field.type)
|
|
941
|
+
: this.getEmptyDefault(field.type);
|
|
942
|
+
return column.notNull().defaultTo(sql.raw(defaultValue));
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
await table
|
|
811
947
|
.addUniqueConstraint(`${tableName}_slug_locale_unique`, ["slug", "locale"])
|
|
812
948
|
.execute();
|
|
813
949
|
|
|
@@ -355,6 +355,40 @@ export class FTSManager {
|
|
|
355
355
|
return fields.map((f) => f.slug);
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Whether a collection has a user-defined `title` field.
|
|
360
|
+
*
|
|
361
|
+
* `title` is not a system column on `ec_*` tables -- it exists only when a
|
|
362
|
+
* collection defines a field with slug `title`. Search and suggestion SQL
|
|
363
|
+
* that selects `c.title` must check this first; otherwise collections
|
|
364
|
+
* without a title field raise "no such column: c.title" (#1178).
|
|
365
|
+
*/
|
|
366
|
+
async hasTitleColumn(collectionSlug: string): Promise<boolean> {
|
|
367
|
+
const withTitle = await this.getCollectionsWithTitleColumn([collectionSlug]);
|
|
368
|
+
return withTitle.has(collectionSlug);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Bulk variant of `hasTitleColumn()`: which of the given collections have
|
|
373
|
+
* a user-defined `title` field. One query instead of one `hasTitleColumn`
|
|
374
|
+
* round-trip pair per collection -- callers that check this once per
|
|
375
|
+
* collection in a loop (multi-collection search, suggestions) should use
|
|
376
|
+
* this instead (AGENTS.md: "one query beats two").
|
|
377
|
+
*/
|
|
378
|
+
async getCollectionsWithTitleColumn(collectionSlugs: string[]): Promise<Set<string>> {
|
|
379
|
+
if (collectionSlugs.length === 0) return new Set();
|
|
380
|
+
|
|
381
|
+
const rows = await this.db
|
|
382
|
+
.selectFrom("_emdash_fields as f")
|
|
383
|
+
.innerJoin("_emdash_collections as c", "c.id", "f.collection_id")
|
|
384
|
+
.select(["c.slug as collection_slug"])
|
|
385
|
+
.where("f.slug", "=", "title")
|
|
386
|
+
.execute();
|
|
387
|
+
|
|
388
|
+
const withTitle = new Set(rows.map((r) => r.collection_slug));
|
|
389
|
+
return new Set(collectionSlugs.filter((slug) => withTitle.has(slug)));
|
|
390
|
+
}
|
|
391
|
+
|
|
358
392
|
/**
|
|
359
393
|
* Enable search for a collection.
|
|
360
394
|
*
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FTS5 match-expression builder for structured (non-user-syntax) queries.
|
|
3
|
+
*
|
|
4
|
+
* Unlike `escapeQuery` in `query.ts` (which powers the public search API and
|
|
5
|
+
* deliberately passes through FTS5 operators like AND/OR/NOT), this builder
|
|
6
|
+
* treats the input as plain words: every term is double-quoted with interior
|
|
7
|
+
* quotes escaped, so the result can never produce an FTS5 syntax error. Used
|
|
8
|
+
* by the admin content-list filter, where the input is a filter box, not a
|
|
9
|
+
* search-syntax field.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const WHITESPACE_RE = /\s+/;
|
|
13
|
+
const DOUBLE_QUOTE_RE = /"/g;
|
|
14
|
+
const GLOB_SPECIAL_RE = /[[\]*?]/g;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Build a prefix-matching FTS5 MATCH expression from free-form input.
|
|
18
|
+
*
|
|
19
|
+
* `hello wor` becomes `"hello"* "wor"*` — implicit AND with per-term prefix
|
|
20
|
+
* matching. Returns `""` when the input contains no usable terms; callers
|
|
21
|
+
* must fall back to their non-FTS path in that case.
|
|
22
|
+
*/
|
|
23
|
+
export function buildFtsPrefixMatch(input: string): string {
|
|
24
|
+
const terms = input
|
|
25
|
+
.trim()
|
|
26
|
+
.split(WHITESPACE_RE)
|
|
27
|
+
.map((term) => term.replace(DOUBLE_QUOTE_RE, '""'))
|
|
28
|
+
.filter((term) => term.length > 0);
|
|
29
|
+
|
|
30
|
+
if (terms.length === 0) return "";
|
|
31
|
+
return terms.map((term) => `"${term}"*`).join(" ");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build a GLOB prefix pattern from free-form input, treating GLOB
|
|
36
|
+
* metacharacters (`* ? [ ]`) literally by wrapping each in a character
|
|
37
|
+
* class (GLOB has no ESCAPE clause).
|
|
38
|
+
*
|
|
39
|
+
* GLOB (unlike default LIKE) is case-sensitive, so with a lowercased
|
|
40
|
+
* pattern it matches slugs (lowercase by construction) while staying
|
|
41
|
+
* servable by the ordinary BINARY-collated slug index — SQLite's GLOB
|
|
42
|
+
* optimization turns a `prefix*` pattern into an index range scan.
|
|
43
|
+
*/
|
|
44
|
+
export function buildSlugGlobPrefix(input: string): string {
|
|
45
|
+
const escaped = input
|
|
46
|
+
.trim()
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(GLOB_SPECIAL_RE, (c) => `[${c}]`);
|
|
49
|
+
return `${escaped}*`;
|
|
50
|
+
}
|
package/src/search/query.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { Kysely } from "kysely";
|
|
8
8
|
import { sql } from "kysely";
|
|
9
9
|
|
|
10
|
+
import { encodeCursor, decodeCursor, InvalidCursorError } from "../database/repositories/types.js";
|
|
10
11
|
import type { Database } from "../database/types.js";
|
|
11
12
|
import { validateIdentifier } from "../database/validate.js";
|
|
12
13
|
import { getDb } from "../loader.js";
|
|
@@ -21,6 +22,44 @@ import type {
|
|
|
21
22
|
SearchStats,
|
|
22
23
|
} from "./types.js";
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Marker stored in the `id` slot of a search pagination cursor.
|
|
27
|
+
*
|
|
28
|
+
* Search results are merged from per-collection FTS queries and re-sorted by
|
|
29
|
+
* score, so there is no single stable keyset column to encode (the way
|
|
30
|
+
* `getEmDashCollection` encodes `(orderValue, id)`). We page over the merged,
|
|
31
|
+
* score-sorted set by offset instead, carried as the cursor's `orderValue`.
|
|
32
|
+
* Reusing `encodeCursor`/`decodeCursor` keeps the opaque base64-JSON shape and
|
|
33
|
+
* the `InvalidCursorError` handling consistent with the rest of the API.
|
|
34
|
+
*/
|
|
35
|
+
const SEARCH_CURSOR_MARKER = "search";
|
|
36
|
+
|
|
37
|
+
/** Encode the next-page offset into an opaque search cursor. */
|
|
38
|
+
function encodeSearchCursor(offset: number): string {
|
|
39
|
+
return encodeCursor(String(offset), SEARCH_CURSOR_MARKER);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Decode a search cursor back to its offset. Throws `InvalidCursorError` for a
|
|
44
|
+
* malformed cursor or one that doesn't carry a non-negative integer offset, so
|
|
45
|
+
* a client pagination bug surfaces immediately rather than silently restarting
|
|
46
|
+
* from the first page.
|
|
47
|
+
*/
|
|
48
|
+
/** Upper bound on a decoded search offset, to cap the per-collection row fetch a forged cursor can trigger. */
|
|
49
|
+
const MAX_SEARCH_OFFSET = 10_000;
|
|
50
|
+
|
|
51
|
+
function decodeSearchOffset(cursor: string): number {
|
|
52
|
+
const { orderValue, id } = decodeCursor(cursor);
|
|
53
|
+
if (id !== SEARCH_CURSOR_MARKER) {
|
|
54
|
+
throw new InvalidCursorError(cursor);
|
|
55
|
+
}
|
|
56
|
+
const offset = Number(orderValue);
|
|
57
|
+
if (!Number.isInteger(offset) || offset < 0 || offset > MAX_SEARCH_OFFSET) {
|
|
58
|
+
throw new InvalidCursorError(cursor);
|
|
59
|
+
}
|
|
60
|
+
return offset;
|
|
61
|
+
}
|
|
62
|
+
|
|
24
63
|
/** Pattern to split on whitespace for query term extraction */
|
|
25
64
|
const WHITESPACE_SPLIT_PATTERN = /\s+/;
|
|
26
65
|
const FTS_OPERATORS_PATTERN = /\b(AND|OR|NOT|NEAR)\b/i;
|
|
@@ -86,6 +125,7 @@ export async function searchWithDb(
|
|
|
86
125
|
const ftsManager = new FTSManager(db);
|
|
87
126
|
const limit = options.limit ?? 20;
|
|
88
127
|
const status = options.status ?? "published";
|
|
128
|
+
const offset = options.cursor ? decodeSearchOffset(options.cursor) : 0;
|
|
89
129
|
|
|
90
130
|
// Get searchable collections
|
|
91
131
|
let collections = options.collections;
|
|
@@ -97,8 +137,15 @@ export async function searchWithDb(
|
|
|
97
137
|
return { items: [] };
|
|
98
138
|
}
|
|
99
139
|
|
|
140
|
+
// To rank the merged window [offset, offset + limit) correctly, each
|
|
141
|
+
// collection must contribute its own top (offset + limit) rows — in the
|
|
142
|
+
// worst case the entire window comes from one collection. The extra +1
|
|
143
|
+
// row detects whether a further page exists.
|
|
144
|
+
const perCollectionLimit = offset + limit + 1;
|
|
145
|
+
|
|
100
146
|
// Search each collection and merge results
|
|
101
147
|
const allResults: SearchResult[] = [];
|
|
148
|
+
const titleColumns = await ftsManager.getCollectionsWithTitleColumn(collections);
|
|
102
149
|
|
|
103
150
|
for (const collection of collections) {
|
|
104
151
|
const config = await ftsManager.getSearchConfig(collection);
|
|
@@ -113,9 +160,10 @@ export async function searchWithDb(
|
|
|
113
160
|
{
|
|
114
161
|
status,
|
|
115
162
|
locale: options.locale,
|
|
116
|
-
limit:
|
|
163
|
+
limit: perCollectionLimit,
|
|
117
164
|
},
|
|
118
165
|
config.weights,
|
|
166
|
+
titleColumns.has(collection),
|
|
119
167
|
);
|
|
120
168
|
|
|
121
169
|
allResults.push(...collectionResults);
|
|
@@ -124,10 +172,13 @@ export async function searchWithDb(
|
|
|
124
172
|
// Sort by score descending
|
|
125
173
|
allResults.sort((a, b) => b.score - a.score);
|
|
126
174
|
|
|
127
|
-
//
|
|
128
|
-
|
|
175
|
+
// Page the merged set by offset. A nextCursor is issued only when at least
|
|
176
|
+
// one result exists past this page.
|
|
177
|
+
const items = allResults.slice(offset, offset + limit);
|
|
178
|
+
const hasMore = allResults.length > offset + limit;
|
|
179
|
+
const nextCursor = hasMore ? encodeSearchCursor(offset + limit) : undefined;
|
|
129
180
|
|
|
130
|
-
return { items };
|
|
181
|
+
return { items, nextCursor };
|
|
131
182
|
}
|
|
132
183
|
|
|
133
184
|
/**
|
|
@@ -159,9 +210,25 @@ export async function searchCollection(
|
|
|
159
210
|
return { items: [] };
|
|
160
211
|
}
|
|
161
212
|
|
|
162
|
-
const
|
|
213
|
+
const limit = options.limit ?? 20;
|
|
214
|
+
const offset = options.cursor ? decodeSearchOffset(options.cursor) : 0;
|
|
215
|
+
|
|
216
|
+
// Over-fetch the [offset, offset + limit) window plus one row to detect a
|
|
217
|
+
// further page, then slice. Keeps the FTS SQL (LIMIT-only) unchanged and
|
|
218
|
+
// the cursor contract identical to the cross-collection path.
|
|
219
|
+
const fetched = await searchSingleCollection(
|
|
220
|
+
db,
|
|
221
|
+
collection,
|
|
222
|
+
query,
|
|
223
|
+
{ status: options.status, locale: options.locale, limit: offset + limit + 1 },
|
|
224
|
+
config.weights,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const items = fetched.slice(offset, offset + limit);
|
|
228
|
+
const hasMore = fetched.length > offset + limit;
|
|
229
|
+
const nextCursor = hasMore ? encodeSearchCursor(offset + limit) : undefined;
|
|
163
230
|
|
|
164
|
-
return { items };
|
|
231
|
+
return { items, nextCursor };
|
|
165
232
|
}
|
|
166
233
|
|
|
167
234
|
/**
|
|
@@ -173,6 +240,7 @@ async function searchSingleCollection(
|
|
|
173
240
|
query: string,
|
|
174
241
|
options: CollectionSearchOptions,
|
|
175
242
|
weights?: Record<string, number>,
|
|
243
|
+
hasTitle?: boolean,
|
|
176
244
|
): Promise<SearchResult[]> {
|
|
177
245
|
// Validate before any raw SQL interpolation
|
|
178
246
|
validateIdentifier(collection, "collection slug");
|
|
@@ -198,6 +266,14 @@ async function searchSingleCollection(
|
|
|
198
266
|
// Get searchable fields for snippet generation
|
|
199
267
|
const searchableFields = await ftsManager.getSearchableFields(collection);
|
|
200
268
|
|
|
269
|
+
// `title` is an optional user-defined field, not a system column. Only
|
|
270
|
+
// select it when the collection actually has one; otherwise the query
|
|
271
|
+
// errors with "no such column: c.title" (#1178). Multi-collection callers
|
|
272
|
+
// precompute this in bulk and pass it in; single-collection callers fall
|
|
273
|
+
// back to the per-collection check.
|
|
274
|
+
const collectionHasTitle = hasTitle ?? (await ftsManager.hasTitleColumn(collection));
|
|
275
|
+
const titleExpr = collectionHasTitle ? sql`c.title` : sql`NULL`;
|
|
276
|
+
|
|
201
277
|
// Build weight string for bm25 if weights provided
|
|
202
278
|
// Format: bm25(table, weight1, weight2, ...)
|
|
203
279
|
// First two weights are for 'id' and 'locale' columns (UNINDEXED, so 0)
|
|
@@ -225,11 +301,11 @@ async function searchSingleCollection(
|
|
|
225
301
|
snippet: string | null;
|
|
226
302
|
score: number;
|
|
227
303
|
}>`
|
|
228
|
-
SELECT
|
|
304
|
+
SELECT
|
|
229
305
|
c.id,
|
|
230
306
|
c.slug,
|
|
231
307
|
c.locale,
|
|
232
|
-
|
|
308
|
+
${titleExpr} as title,
|
|
233
309
|
snippet("${sql.raw(ftsTable)}", 2, '<mark>', '</mark>', '...', 32) as snippet,
|
|
234
310
|
${sql.raw(bm25Expr)} as score
|
|
235
311
|
FROM "${sql.raw(ftsTable)}" f
|
|
@@ -334,14 +410,23 @@ export async function getSuggestions(
|
|
|
334
410
|
}
|
|
335
411
|
|
|
336
412
|
const suggestions: Suggestion[] = [];
|
|
413
|
+
const ftsManager = new FTSManager(db);
|
|
414
|
+
const titleColumns = await ftsManager.getCollectionsWithTitleColumn(collections);
|
|
337
415
|
|
|
338
416
|
for (const collection of collections) {
|
|
339
|
-
const ftsManager = new FTSManager(db);
|
|
340
417
|
const config = await ftsManager.getSearchConfig(collection);
|
|
341
418
|
if (!config?.enabled) {
|
|
342
419
|
continue;
|
|
343
420
|
}
|
|
344
421
|
|
|
422
|
+
// Suggestions are title-based (Suggestion.title is required and the
|
|
423
|
+
// query filters on `c.title IS NOT NULL`). Collections without a
|
|
424
|
+
// `title` field can't produce one, and selecting `c.title` would
|
|
425
|
+
// error, so skip them. See #1178.
|
|
426
|
+
if (!titleColumns.has(collection)) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
|
|
345
430
|
// Validate before raw SQL interpolation
|
|
346
431
|
validateIdentifier(collection, "collection slug");
|
|
347
432
|
|