emdash 0.21.0 → 0.22.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-BxSmgtbF.d.mts → adapters-hUy8vOB-.d.mts} +1 -1
- package/dist/{adapters-BxSmgtbF.d.mts.map → adapters-hUy8vOB-.d.mts.map} +1 -1
- package/dist/after-B1IIdH3Y.mjs +29 -0
- package/dist/after-B1IIdH3Y.mjs.map +1 -0
- package/dist/{allowed-origins-BqC8cul8.mjs → allowed-origins-DjlhyfNN.mjs} +2 -2
- package/dist/{allowed-origins-BqC8cul8.mjs.map → allowed-origins-DjlhyfNN.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +20 -19
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +4 -4
- package/dist/{api-DxjIV2o8.mjs → api-BDuM4bEy.mjs} +31 -25
- package/dist/api-BDuM4bEy.mjs.map +1 -0
- package/dist/{api-tokens-BFFkB0jB.mjs → api-tokens-ViYKeIp9.mjs} +13 -3
- package/dist/api-tokens-ViYKeIp9.mjs.map +1 -0
- package/dist/{apply-CLjxheyb.mjs → apply-wDqQoxX4.mjs} +18 -18
- package/dist/{apply-CLjxheyb.mjs.map → apply-wDqQoxX4.mjs.map} +1 -1
- package/dist/astro/image-endpoint.d.mts +8 -0
- package/dist/astro/image-endpoint.d.mts.map +1 -0
- package/dist/astro/image-endpoint.mjs +55 -0
- package/dist/astro/image-endpoint.mjs.map +1 -0
- package/dist/astro/index.d.mts +36 -11
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +114 -24
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +12 -10
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +6 -6
- package/dist/astro/middleware/request-context.mjs +5 -5
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +153 -79
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -16
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -16
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +17 -16
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +15 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -6
- package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -10
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -6
- package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/index.mjs +12 -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/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 +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +39 -38
- 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 +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -38
- 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 +39 -38
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -8
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
- package/dist/astro/routes/api/admin/users/index.mjs +7 -7
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
- package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -11
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
- package/dist/astro/routes/api/auth/me.mjs +8 -8
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +13 -13
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/request.mjs +11 -11
- package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +16 -15
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +9 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts.map +1 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +179 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +17 -15
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
- package/dist/astro/routes/api/dashboard.mjs +10 -8
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- 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 +12 -12
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -15
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +12 -12
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +18 -17
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.mjs +213 -46
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -8
- package/dist/astro/routes/api/media/_id_.mjs +8 -8
- package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +10 -10
- package/dist/astro/routes/api/media.mjs +13 -13
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -9
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +11 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +11 -9
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +11 -9
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- 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 +5 -5
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
- package/dist/astro/routes/api/redirects/404s/index.mjs +11 -11
- package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -11
- package/dist/astro/routes/api/redirects/_id_.mjs +12 -12
- package/dist/astro/routes/api/redirects/index.mjs +12 -12
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +39 -38
- 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 +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +7 -7
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +11 -11
- package/dist/astro/routes/api/search/index.mjs +10 -10
- package/dist/astro/routes/api/search/rebuild.mjs +11 -11
- package/dist/astro/routes/api/search/stats.mjs +7 -7
- package/dist/astro/routes/api/search/suggest.mjs +10 -10
- package/dist/astro/routes/api/sections/_slug_.mjs +10 -10
- package/dist/astro/routes/api/sections/index.mjs +10 -10
- 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 +13 -13
- package/dist/astro/routes/api/setup/admin.mjs +12 -12
- package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -27
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +29 -28
- 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.d.mts.map +1 -1
- package/dist/astro/routes/api/snapshot.mjs +10 -9
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -14
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -14
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +8 -8
- 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.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -11
- package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
- package/dist/astro/routes/api/widget-areas/index.mjs +11 -11
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +10 -9
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -12
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +11 -10
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +16 -12
- 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-D5gfBVU5.mjs → authorize-C0EYoUeV.mjs} +2 -2
- package/dist/{authorize-D5gfBVU5.mjs.map → authorize-C0EYoUeV.mjs.map} +1 -1
- package/dist/{base64-CqR-7kqF.mjs → base64-CmWvODNW.mjs} +1 -1
- package/dist/{base64-CqR-7kqF.mjs.map → base64-CmWvODNW.mjs.map} +1 -1
- package/dist/{byline-V_Qp1Ziw.mjs → byline-CC0WS4Gu.mjs} +17 -8
- package/dist/byline-CC0WS4Gu.mjs.map +1 -0
- package/dist/{byline-fields-B0NO1yUB.mjs → byline-fields-53i9Et0x.mjs} +3 -3
- package/dist/{byline-fields-B0NO1yUB.mjs.map → byline-fields-53i9Et0x.mjs.map} +1 -1
- package/dist/{byline-fields-nBVqK_Ff.mjs → byline-fields-DNp0HNKc.mjs} +2 -2
- package/dist/{byline-fields-nBVqK_Ff.mjs.map → byline-fields-DNp0HNKc.mjs.map} +1 -1
- package/dist/{byline-fields-CQJRIQkn.d.mts → byline-fields-jy07PZJM.d.mts} +36 -31
- package/dist/byline-fields-jy07PZJM.d.mts.map +1 -0
- package/dist/{byline-registry-DedidtqC.mjs → byline-registry-BOjqDOim.mjs} +3 -3
- package/dist/{byline-registry-DedidtqC.mjs.map → byline-registry-BOjqDOim.mjs.map} +1 -1
- package/dist/{bylines-DfGDnred.mjs → bylines-CCO1CYnH.mjs} +8 -8
- package/dist/{bylines-DfGDnred.mjs.map → bylines-CCO1CYnH.mjs.map} +1 -1
- package/dist/{bylines-B2NWnIwS.mjs → bylines-DGekMGGm.mjs} +10 -4
- package/dist/{bylines-B2NWnIwS.mjs.map → bylines-DGekMGGm.mjs.map} +1 -1
- package/dist/{cache-DTTHWD8n.mjs → cache-pXTpun6s.mjs} +3 -3
- package/dist/{cache-DTTHWD8n.mjs.map → cache-pXTpun6s.mjs.map} +1 -1
- package/dist/{challenge-store-woE0bbCf.mjs → challenge-store-C6E_kWTs.mjs} +1 -1
- package/dist/{challenge-store-woE0bbCf.mjs.map → challenge-store-C6E_kWTs.mjs.map} +1 -1
- package/dist/{chunks-BerYVuve.mjs → chunks-SyjZaYwV.mjs} +2 -2
- package/dist/{chunks-BerYVuve.mjs.map → chunks-SyjZaYwV.mjs.map} +1 -1
- package/dist/cli/index.mjs +27 -26
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +2 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-sqQxNpN3.mjs → comment-80UyJJUR.mjs} +11 -3
- package/dist/comment-80UyJJUR.mjs.map +1 -0
- package/dist/comment-reaction-B6AdcpXw.mjs +85 -0
- package/dist/comment-reaction-B6AdcpXw.mjs.map +1 -0
- package/dist/{comments-D2hNuxNa.mjs → comments-CtPkT2tp.mjs} +3 -3
- package/dist/{comments-D2hNuxNa.mjs.map → comments-CtPkT2tp.mjs.map} +1 -1
- package/dist/{components-DYKp2gmo.mjs → components-D6ZnrzbB.mjs} +1 -1
- package/dist/{components-DYKp2gmo.mjs.map → components-D6ZnrzbB.mjs.map} +1 -1
- package/dist/{content-BIlVx-RX.mjs → content-2PTDNnoh.mjs} +22 -7
- package/dist/content-2PTDNnoh.mjs.map +1 -0
- package/dist/{context-Cm4pt1Ws.mjs → context-f1__jpzF.mjs} +11 -11
- package/dist/{context-Cm4pt1Ws.mjs.map → context-f1__jpzF.mjs.map} +1 -1
- package/dist/{cron-DdEVrQ2Y.mjs → cron-CQPxBjYs.mjs} +1 -1
- package/dist/{cron-DdEVrQ2Y.mjs.map → cron-CQPxBjYs.mjs.map} +1 -1
- package/dist/{dashboard-C-UYpps0.mjs → dashboard-BOESNcwE.mjs} +4 -4
- package/dist/{dashboard-C-UYpps0.mjs.map → dashboard-BOESNcwE.mjs.map} +1 -1
- package/dist/database/instrumentation.d.mts +19 -0
- package/dist/database/instrumentation.d.mts.map +1 -1
- package/dist/database/instrumentation.mjs +8 -1
- package/dist/database/instrumentation.mjs.map +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-BluWkwGI.mjs → db-errors-CrC5w3Jz.mjs} +1 -1
- package/dist/{db-errors-BluWkwGI.mjs.map → db-errors-CrC5w3Jz.mjs.map} +1 -1
- package/dist/{default-NHGuJzQ3.mjs → default-CpBEPn6a.mjs} +1 -1
- package/dist/{default-NHGuJzQ3.mjs.map → default-CpBEPn6a.mjs.map} +1 -1
- package/dist/{device-flow-BQApWgnW.mjs → device-flow-Bn-qiDrw.mjs} +5 -5
- package/dist/{device-flow-BQApWgnW.mjs.map → device-flow-Bn-qiDrw.mjs.map} +1 -1
- package/dist/{email-console-BbU3RbWv.mjs → email-console-B9VS6eN4.mjs} +1 -1
- package/dist/{email-console-BbU3RbWv.mjs.map → email-console-B9VS6eN4.mjs.map} +1 -1
- package/dist/{error-CNn_w7jf.mjs → error-BQ1pxs0L.mjs} +2 -2
- package/dist/{error-CNn_w7jf.mjs.map → error-BQ1pxs0L.mjs.map} +1 -1
- package/dist/{escape-DPgcxcpL.mjs → escape-BtbJWyaW.mjs} +1 -1
- package/dist/{escape-DPgcxcpL.mjs.map → escape-BtbJWyaW.mjs.map} +1 -1
- package/dist/{fts-manager-Cx5z8jdA.mjs → fts-manager-DtiWqwNJ.mjs} +2 -2
- package/dist/{fts-manager-Cx5z8jdA.mjs.map → fts-manager-DtiWqwNJ.mjs.map} +1 -1
- package/dist/{hash-DlvIFn0b.mjs → hash-BowcuPwv.mjs} +1 -1
- package/dist/{hash-DlvIFn0b.mjs.map → hash-BowcuPwv.mjs.map} +1 -1
- package/dist/{import-KyxT1Mbs.mjs → import-DqSGOlmR.mjs} +4 -4
- package/dist/{import-KyxT1Mbs.mjs.map → import-DqSGOlmR.mjs.map} +1 -1
- package/dist/{index-D2VAiumu.d.mts → index-C2dLNT6S.d.mts} +172 -17
- package/dist/index-C2dLNT6S.d.mts.map +1 -0
- package/dist/{index-uT2yR66F.d.mts → index-ZDEwR7qW.d.mts} +3 -3
- package/dist/{index-uT2yR66F.d.mts.map → index-ZDEwR7qW.d.mts.map} +1 -1
- package/dist/index.d.mts +18 -17
- package/dist/index.mjs +63 -61
- package/dist/{init-lock-DlBHjf9-.mjs → init-lock-6b309ZrF.mjs} +2 -29
- package/dist/init-lock-6b309ZrF.mjs.map +1 -0
- package/dist/{load-Dq91b_DK.mjs → load-Dtoo7KcJ.mjs} +2 -2
- package/dist/{load-Dq91b_DK.mjs.map → load-Dtoo7KcJ.mjs.map} +1 -1
- package/dist/{loader-BqWjcH3h.mjs → loader-C8Z48Uof.mjs} +4 -4
- package/dist/{loader-BqWjcH3h.mjs.map → loader-C8Z48Uof.mjs.map} +1 -1
- package/dist/{manifest-schema-DFPeqMAn.mjs → manifest-schema-DDSbwkAL.mjs} +1 -1
- package/dist/{manifest-schema-DFPeqMAn.mjs.map → manifest-schema-DDSbwkAL.mjs.map} +1 -1
- package/dist/media/image-endpoint.d.mts +74 -0
- package/dist/media/image-endpoint.d.mts.map +1 -0
- package/dist/media/image-endpoint.mjs +162 -0
- package/dist/media/image-endpoint.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +11 -11
- package/dist/media/local-runtime.mjs +9 -8
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-JOf3pNkw.mjs → media-Bw0sA6rb.mjs} +2 -2
- package/dist/{media-JOf3pNkw.mjs.map → media-Bw0sA6rb.mjs.map} +1 -1
- package/dist/{media-allowlist-_A0SuDn4.mjs → media-allowlist-DunzrKFM.mjs} +2 -2
- package/dist/{media-allowlist-_A0SuDn4.mjs.map → media-allowlist-DunzrKFM.mjs.map} +1 -1
- package/dist/{media-url-CqLd69IO.mjs → media-url-S22B6aPr.mjs} +1 -1
- package/dist/{media-url-CqLd69IO.mjs.map → media-url-S22B6aPr.mjs.map} +1 -1
- package/dist/{menus-DX4_E01q.mjs → menus-CYs0WZoL.mjs} +20 -6
- package/dist/menus-CYs0WZoL.mjs.map +1 -0
- package/dist/{menus-Ryk9L7fT.mjs → menus-DOs1MQJg.mjs} +120 -20
- package/dist/menus-DOs1MQJg.mjs.map +1 -0
- package/dist/{mime-YbtlEtvS.mjs → mime-DYpsOAny.mjs} +1 -1
- package/dist/{mime-YbtlEtvS.mjs.map → mime-DYpsOAny.mjs.map} +1 -1
- package/dist/{mode-CGXzIbD8.mjs → mode-CFh8Dw8G.mjs} +1 -1
- package/dist/{mode-CGXzIbD8.mjs.map → mode-CFh8Dw8G.mjs.map} +1 -1
- package/dist/{normalize-DKsg36ty.mjs → normalize-Uam4_Vkr.mjs} +1 -1
- package/dist/{normalize-DKsg36ty.mjs.map → normalize-Uam4_Vkr.mjs.map} +1 -1
- package/dist/{oauth-authorization-C2kVyjXI.mjs → oauth-authorization-BN-t83Uy.mjs} +5 -5
- package/dist/{oauth-authorization-C2kVyjXI.mjs.map → oauth-authorization-BN-t83Uy.mjs.map} +1 -1
- package/dist/{oauth-clients-BC873NCV.mjs → oauth-clients-R6I_V0qz.mjs} +1 -1
- package/dist/{oauth-clients-BC873NCV.mjs.map → oauth-clients-R6I_V0qz.mjs.map} +1 -1
- package/dist/{oauth-state-store-Cd--TUaq.mjs → oauth-state-store-Csoc6kkR.mjs} +1 -1
- package/dist/{oauth-state-store-Cd--TUaq.mjs.map → oauth-state-store-Csoc6kkR.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-e4wOvDud.mjs → oauth-user-lookup-d7VYjTpx.mjs} +1 -1
- package/dist/{oauth-user-lookup-e4wOvDud.mjs.map → oauth-user-lookup-d7VYjTpx.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +15 -0
- package/dist/object-cache/memory.d.mts.map +1 -0
- package/dist/object-cache/memory.mjs +56 -0
- package/dist/object-cache/memory.mjs.map +1 -0
- package/dist/object-cache-SEb2IM4Z.mjs +373 -0
- package/dist/object-cache-SEb2IM4Z.mjs.map +1 -0
- package/dist/{options-9kLgkE8m.d.mts → options-DFFpvNJU.d.mts} +3 -3
- package/dist/{options-9kLgkE8m.d.mts.map → options-DFFpvNJU.d.mts.map} +1 -1
- package/dist/{options-BPCVnesz.mjs → options-DTTML-Tx.mjs} +1 -1
- package/dist/{options-BPCVnesz.mjs.map → options-DTTML-Tx.mjs.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-DzSrk1t8.mjs → parse-qrHlnzTy.mjs} +2 -2
- package/dist/{parse-DzSrk1t8.mjs.map → parse-qrHlnzTy.mjs.map} +1 -1
- package/dist/{passkey-config-BpjbE_Uv.mjs → passkey-config-BJTbcnI5.mjs} +1 -1
- package/dist/{passkey-config-BpjbE_Uv.mjs.map → passkey-config-BJTbcnI5.mjs.map} +1 -1
- package/dist/{patterns-p-RBdTbM.mjs → patterns-BKmjvM7K.mjs} +1 -1
- package/dist/{patterns-p-RBdTbM.mjs.map → patterns-BKmjvM7K.mjs.map} +1 -1
- package/dist/{placeholder-2xumZh4g.mjs → placeholder-CIDCpyEY.mjs} +1 -1
- package/dist/{placeholder-2xumZh4g.mjs.map → placeholder-CIDCpyEY.mjs.map} +1 -1
- package/dist/{placeholder-BevVKfay.d.mts → placeholder-CirPauNG.d.mts} +1 -1
- package/dist/{placeholder-BevVKfay.d.mts.map → placeholder-CirPauNG.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.mjs +4 -2
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{transport-1cIrOb1Y.mjs → portable-text-BIFhrU6T.mjs} +2 -135
- package/dist/portable-text-BIFhrU6T.mjs.map +1 -0
- package/dist/{preview-Dqv2hwXr.mjs → preview-IDye9SPQ.mjs} +2 -2
- package/dist/{preview-Dqv2hwXr.mjs.map → preview-IDye9SPQ.mjs.map} +1 -1
- package/dist/{public-url-D_zARuvZ.mjs → public-url-8lFyQ8ZF.mjs} +1 -1
- package/dist/{public-url-D_zARuvZ.mjs.map → public-url-8lFyQ8ZF.mjs.map} +1 -1
- package/dist/{query-Crm038Mc.mjs → query-B1RVFUNM.mjs} +159 -31
- package/dist/query-B1RVFUNM.mjs.map +1 -0
- package/dist/{rate-limit-hRTBqmw1.mjs → rate-limit-DfNAqIWW.mjs} +2 -2
- package/dist/{rate-limit-hRTBqmw1.mjs.map → rate-limit-DfNAqIWW.mjs.map} +1 -1
- package/dist/{redirect-C-OOkyku.mjs → redirect-B4wuX2A5.mjs} +1 -1
- package/dist/{redirect-C-OOkyku.mjs.map → redirect-B4wuX2A5.mjs.map} +1 -1
- package/dist/{redirect-CRWIt8Zj.mjs → redirect-Bifv_yHv.mjs} +3 -3
- package/dist/{redirect-CRWIt8Zj.mjs.map → redirect-Bifv_yHv.mjs.map} +1 -1
- package/dist/{redirects-CP3TnTLO.mjs → redirects-CT_vb3NV.mjs} +6 -6
- package/dist/{redirects-CP3TnTLO.mjs.map → redirects-CT_vb3NV.mjs.map} +1 -1
- package/dist/{redirects-6Zg2SoYo.mjs → redirects-DUvXgzCX.mjs} +8 -3
- package/dist/redirects-DUvXgzCX.mjs.map +1 -0
- package/dist/{registry-diMzD1Wf.mjs → registry-CjK96fHD.mjs} +6 -6
- package/dist/{registry-diMzD1Wf.mjs.map → registry-CjK96fHD.mjs.map} +1 -1
- package/dist/{request-cache-UwmBAiUK.mjs → request-cache-KCNHp_RJ.mjs} +1 -1
- package/dist/{request-cache-UwmBAiUK.mjs.map → request-cache-KCNHp_RJ.mjs.map} +1 -1
- package/dist/{request-meta-DPechd0W.mjs → request-meta-ei3ATilC.mjs} +2 -2
- package/dist/{request-meta-DPechd0W.mjs.map → request-meta-ei3ATilC.mjs.map} +1 -1
- package/dist/{resolve-B3NUUtVY.mjs → resolve-CpbBglV0.mjs} +1 -1
- package/dist/{resolve-B3NUUtVY.mjs.map → resolve-CpbBglV0.mjs.map} +1 -1
- package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
- package/dist/runner-DYYnW530.mjs.map +1 -0
- package/dist/{runner-C8vcbvCe.d.mts → runner-jdXtFEd3.d.mts} +2 -2
- package/dist/{runner-C8vcbvCe.d.mts.map → runner-jdXtFEd3.d.mts.map} +1 -1
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +3 -3
- package/dist/{schema-BDOkd3OU.mjs → schema-5z2Jfnbm.mjs} +13 -8
- package/dist/schema-5z2Jfnbm.mjs.map +1 -0
- package/dist/{search-Bs_J_EW-.mjs → search-D9FkoM-k.mjs} +4 -4
- package/dist/{search-Bs_J_EW-.mjs.map → search-D9FkoM-k.mjs.map} +1 -1
- package/dist/{secrets-C8xmE6mR.mjs → secrets-BUE5UQys.mjs} +5 -5
- package/dist/{secrets-C8xmE6mR.mjs.map → secrets-BUE5UQys.mjs.map} +1 -1
- package/dist/{sections-P0zuBlyz.mjs → sections-DWYZo6HK.mjs} +3 -3
- package/dist/{sections-P0zuBlyz.mjs.map → sections-DWYZo6HK.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +22 -21
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/{seo-DpNgGQjF.mjs → seo-Cu47j3mJ.mjs} +5 -2
- package/dist/seo-Cu47j3mJ.mjs.map +1 -0
- package/dist/{seo-CLhm-Fmb.mjs → seo-DRnqnstF.mjs} +1 -1
- package/dist/{seo-CLhm-Fmb.mjs.map → seo-DRnqnstF.mjs.map} +1 -1
- package/dist/{service-CDQQnT8W.mjs → service-DTmtqCnw.mjs} +3 -3
- package/dist/{service-CDQQnT8W.mjs.map → service-DTmtqCnw.mjs.map} +1 -1
- package/dist/session-user-DmtPMNa1.mjs +51 -0
- package/dist/session-user-DmtPMNa1.mjs.map +1 -0
- package/dist/{settings-sO0Fif4p.mjs → settings-DUrVDN0c.mjs} +3 -3
- package/dist/{settings-sO0Fif4p.mjs.map → settings-DUrVDN0c.mjs.map} +1 -1
- package/dist/{settings-BjBsmVAo.mjs → settings-yaxu9mU-.mjs} +18 -10
- package/dist/settings-yaxu9mU-.mjs.map +1 -0
- package/dist/{setup-complete-CMMr-oZU.mjs → setup-complete-BWFHzgvZ.mjs} +2 -2
- package/dist/{setup-complete-CMMr-oZU.mjs.map → setup-complete-BWFHzgvZ.mjs.map} +1 -1
- package/dist/{setup-nonce-169xl4fV.mjs → setup-nonce-DFWG-J5c.mjs} +1 -1
- package/dist/{setup-nonce-169xl4fV.mjs.map → setup-nonce-DFWG-J5c.mjs.map} +1 -1
- package/dist/{single-flight-cache-C0UV1Npg.mjs → single-flight-cache-B5p5cNOL.mjs} +2 -2
- package/dist/{single-flight-cache-C0UV1Npg.mjs.map → single-flight-cache-B5p5cNOL.mjs.map} +1 -1
- package/dist/{site-url-vtsuOvSD.mjs → site-url-BOTPgmeM.mjs} +2 -2
- package/dist/{site-url-vtsuOvSD.mjs.map → site-url-BOTPgmeM.mjs.map} +1 -1
- package/dist/{slugify-Cjh1ssOZ.mjs → slugify-Cce3dTdg.mjs} +1 -1
- package/dist/{slugify-Cjh1ssOZ.mjs.map → slugify-Cce3dTdg.mjs.map} +1 -1
- package/dist/{ssrf-XO05Voq6.mjs → ssrf-B0VeRLrp.mjs} +1 -1
- package/dist/{ssrf-XO05Voq6.mjs.map → ssrf-B0VeRLrp.mjs.map} +1 -1
- package/dist/{status-2gZklYuj.mjs → status-CB2basWJ.mjs} +1 -1
- package/dist/{status-2gZklYuj.mjs.map → status-CB2basWJ.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-BBxYA38v.mjs → taxonomies-Be9B1jEj.mjs} +156 -122
- package/dist/taxonomies-Be9B1jEj.mjs.map +1 -0
- package/dist/{taxonomies-DuESHWKI.mjs → taxonomies-CJmkEpdS.mjs} +7 -7
- package/dist/{taxonomies-DuESHWKI.mjs.map → taxonomies-CJmkEpdS.mjs.map} +1 -1
- package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
- package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
- package/dist/{tokens-DMkVjxrx.mjs → tokens-BvrJvIB6.mjs} +2 -2
- package/dist/{tokens-DMkVjxrx.mjs.map → tokens-BvrJvIB6.mjs.map} +1 -1
- package/dist/{transaction-x2tJQ-A1.mjs → transaction-qfqpPVpu.mjs} +1 -1
- package/dist/{transaction-x2tJQ-A1.mjs.map → transaction-qfqpPVpu.mjs.map} +1 -1
- package/dist/transport-B4rXnSTf.mjs +135 -0
- package/dist/transport-B4rXnSTf.mjs.map +1 -0
- package/dist/{transport-jdvsZEIt.d.mts → transport-k7YjfmEn.d.mts} +1 -1
- package/dist/{transport-jdvsZEIt.d.mts.map → transport-k7YjfmEn.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CHp41Fjj.mjs → trusted-proxy-DY1_UqHr.mjs} +1 -1
- package/dist/{trusted-proxy-CHp41Fjj.mjs.map → trusted-proxy-DY1_UqHr.mjs.map} +1 -1
- package/dist/{types-DO7whVYU.d.mts → types-CIKX2HO5.d.mts} +2 -2
- package/dist/{types-DO7whVYU.d.mts.map → types-CIKX2HO5.d.mts.map} +1 -1
- package/dist/{types-u_XxjbS8.d.mts → types-CKNXt63n.d.mts} +1 -1
- package/dist/{types-u_XxjbS8.d.mts.map → types-CKNXt63n.d.mts.map} +1 -1
- package/dist/{types-BTnnBYVX.d.mts → types-CWGYDYqF.d.mts} +2 -2
- package/dist/{types-BTnnBYVX.d.mts.map → types-CWGYDYqF.d.mts.map} +1 -1
- package/dist/{types-CkEuk-Zr.d.mts → types-CgvhU-hF.d.mts} +1 -1
- package/dist/{types-CkEuk-Zr.d.mts.map → types-CgvhU-hF.d.mts.map} +1 -1
- package/dist/{types-BFgYtuKd.d.mts → types-CmivgZbp.d.mts} +1 -1
- package/dist/{types-BFgYtuKd.d.mts.map → types-CmivgZbp.d.mts.map} +1 -1
- package/dist/{types-Del0VMij.d.mts → types-Czg1S3gB.d.mts} +9 -1
- package/dist/{types-Del0VMij.d.mts.map → types-Czg1S3gB.d.mts.map} +1 -1
- package/dist/types-DCNNfeCv.d.mts +124 -0
- package/dist/types-DCNNfeCv.d.mts.map +1 -0
- package/dist/{types-Bzfk2yC8.d.mts → types-DPCpkzvS.d.mts} +1 -1
- package/dist/{types-Bzfk2yC8.d.mts.map → types-DPCpkzvS.d.mts.map} +1 -1
- package/dist/{types-DdkL6fyv.d.mts → types-DXLVzV2w.d.mts} +1 -1
- package/dist/{types-DdkL6fyv.d.mts.map → types-DXLVzV2w.d.mts.map} +1 -1
- package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
- package/dist/{types-BXSUSAjt.mjs.map → types-DXOIbece.mjs.map} +1 -1
- package/dist/{types-DejCHqWT.mjs → types-DYF2_Vf4.mjs} +1 -1
- package/dist/{types-DejCHqWT.mjs.map → types-DYF2_Vf4.mjs.map} +1 -1
- package/dist/{types-BIduXPJk.mjs → types-tM44hEcf.mjs} +1 -1
- package/dist/{types-BIduXPJk.mjs.map → types-tM44hEcf.mjs.map} +1 -1
- package/dist/{user-C0um7wrg.mjs → user-Db-Rti_z.mjs} +3 -3
- package/dist/{user-C0um7wrg.mjs.map → user-Db-Rti_z.mjs.map} +1 -1
- package/dist/{utils-C4M981Br.mjs → utils-LbHcSRTj.mjs} +2 -2
- package/dist/{utils-C4M981Br.mjs.map → utils-LbHcSRTj.mjs.map} +1 -1
- package/dist/{validate-DGhQPXzI.mjs → validate-Bwl64sxv.mjs} +3 -3
- package/dist/{validate-DGhQPXzI.mjs.map → validate-Bwl64sxv.mjs.map} +1 -1
- package/dist/{validate-cJOiOvT2.d.mts → validate-CE2M0nvx.d.mts} +5 -5
- package/dist/{validate-cJOiOvT2.d.mts.map → validate-CE2M0nvx.d.mts.map} +1 -1
- package/dist/{validation-DVHjPM1M.mjs → validation-C_yOvFaO.mjs} +6 -6
- package/dist/{validation-DVHjPM1M.mjs.map → validation-C_yOvFaO.mjs.map} +1 -1
- package/dist/version-RnYXYjzD.mjs +7 -0
- package/dist/{version-BOjj_cfz.mjs.map → version-RnYXYjzD.mjs.map} +1 -1
- package/dist/{widgets-Ci6hLwfO.mjs → widgets-8GONuRHo.mjs} +4 -4
- package/dist/{widgets-Ci6hLwfO.mjs.map → widgets-8GONuRHo.mjs.map} +1 -1
- package/dist/{zod-generator-CarzgPAu.mjs → zod-generator-D481JjzD.mjs} +3 -3
- package/dist/{zod-generator-CarzgPAu.mjs.map → zod-generator-D481JjzD.mjs.map} +1 -1
- package/package.json +18 -6
- package/src/api/handlers/api-tokens.ts +19 -0
- package/src/api/handlers/comment-reactions.ts +165 -0
- package/src/api/handlers/schema.ts +8 -0
- package/src/api/schemas/comments.ts +10 -0
- package/src/astro/image-endpoint.ts +84 -0
- package/src/astro/index.ts +6 -0
- package/src/astro/integration/index.ts +83 -22
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/runtime.ts +65 -1
- package/src/astro/integration/virtual-modules.ts +32 -0
- package/src/astro/integration/vite-config.ts +16 -0
- package/src/astro/middleware/auth.ts +4 -3
- package/src/astro/middleware/stream-end-metrics.ts +11 -1
- package/src/astro/middleware.ts +41 -3
- package/src/astro/object-cache/adapters.ts +50 -0
- package/src/astro/prefetch.ts +77 -0
- package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
- package/src/astro/routes/api/setup/dev-bypass.ts +5 -1
- package/src/astro/routes/api/snapshot.ts +3 -1
- package/src/astro/session-user.ts +57 -0
- package/src/astro/types.ts +1 -0
- package/src/comments/query.ts +78 -7
- package/src/comments/ranking.ts +58 -0
- package/src/components/Comments.astro +136 -1
- package/src/database/instrumentation.ts +21 -1
- package/src/database/migrations/044_comment_reactions.ts +56 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/byline.ts +13 -0
- package/src/database/repositories/comment-reaction.ts +132 -0
- package/src/database/repositories/comment.ts +10 -0
- package/src/database/repositories/content.ts +25 -3
- package/src/database/repositories/menu.ts +13 -1
- package/src/database/repositories/seo.ts +3 -0
- package/src/database/repositories/taxonomy.ts +13 -1
- package/src/database/types.ts +9 -0
- package/src/emdash-runtime.ts +18 -4
- package/src/index.ts +22 -0
- package/src/mcp/server.ts +307 -20
- package/src/media/image-endpoint.ts +167 -0
- package/src/menus/index.ts +11 -4
- package/src/object-cache/codec.ts +73 -0
- package/src/object-cache/index.ts +495 -0
- package/src/object-cache/memory.ts +91 -0
- package/src/object-cache/types.ts +124 -0
- package/src/plugins/adapt-sandbox-entry.ts +11 -1
- package/src/query.ts +196 -17
- package/src/schema/query.ts +11 -4
- package/src/settings/index.ts +18 -5
- package/src/taxonomies/index.ts +237 -165
- package/src/virtual-modules.d.ts +11 -0
- package/dist/api-DxjIV2o8.mjs.map +0 -1
- package/dist/api-tokens-BFFkB0jB.mjs.map +0 -1
- package/dist/byline-V_Qp1Ziw.mjs.map +0 -1
- package/dist/byline-fields-CQJRIQkn.d.mts.map +0 -1
- package/dist/comment-sqQxNpN3.mjs.map +0 -1
- package/dist/content-BIlVx-RX.mjs.map +0 -1
- package/dist/index-D2VAiumu.d.mts.map +0 -1
- package/dist/init-lock-DlBHjf9-.mjs.map +0 -1
- package/dist/menus-DX4_E01q.mjs.map +0 -1
- package/dist/menus-Ryk9L7fT.mjs.map +0 -1
- package/dist/query-Crm038Mc.mjs.map +0 -1
- package/dist/redirects-6Zg2SoYo.mjs.map +0 -1
- package/dist/runner--4wMWwKM.mjs.map +0 -1
- package/dist/schema-BDOkd3OU.mjs.map +0 -1
- package/dist/seo-DpNgGQjF.mjs.map +0 -1
- package/dist/settings-BjBsmVAo.mjs.map +0 -1
- package/dist/taxonomies-BBxYA38v.mjs.map +0 -1
- package/dist/taxonomy-CdllE4oq.mjs.map +0 -1
- package/dist/transport-1cIrOb1Y.mjs.map +0 -1
- package/dist/version-BOjj_cfz.mjs +0 -7
- /package/dist/{api-tokens-C7ywRx7l.mjs → api-tokens-BVH-H8Z9.mjs} +0 -0
- /package/dist/{ssrf-CRZGzjdL.mjs → ssrf-Cz1e2QPn.mjs} +0 -0
- /package/dist/{types-BoRm8-pp.mjs → types-Bfr2Pj6z.mjs} +0 -0
package/src/mcp/server.ts
CHANGED
|
@@ -14,10 +14,17 @@ import { canActOnOwn, hasPermission, Role } from "@emdash-cms/auth";
|
|
|
14
14
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
bylineCreateBody,
|
|
19
|
+
bylineUpdateBody,
|
|
20
|
+
contentBylineInputSchema,
|
|
21
|
+
contentSeoInput,
|
|
22
|
+
} from "#api/schemas.js";
|
|
18
23
|
|
|
19
24
|
import type { EmDashHandlers } from "../astro/types.js";
|
|
20
25
|
import { hasScope } from "../auth/api-tokens.js";
|
|
26
|
+
import { convertDataForRead, convertDataForWrite } from "../client/portable-text.js";
|
|
27
|
+
import type { FieldSchema } from "../client/portable-text.js";
|
|
21
28
|
|
|
22
29
|
const COLLECTION_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
23
30
|
/** http(s) scheme matcher used by `settings_update` URL validation. */
|
|
@@ -268,6 +275,64 @@ function getEmDash(extra: { authInfo?: { extra?: Record<string, unknown> } }): E
|
|
|
268
275
|
return getExtra(extra).emdash;
|
|
269
276
|
}
|
|
270
277
|
|
|
278
|
+
async function getCollectionFields(
|
|
279
|
+
ec: EmDashHandlers,
|
|
280
|
+
collection: string,
|
|
281
|
+
): Promise<FieldSchema[] | null> {
|
|
282
|
+
try {
|
|
283
|
+
const { SchemaRegistry } = await import("../schema/index.js");
|
|
284
|
+
const col = await new SchemaRegistry(ec.db).getCollectionWithFields(collection);
|
|
285
|
+
return col ? col.fields : null;
|
|
286
|
+
} catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Convert markdown strings to Portable Text for `portableText` fields on write.
|
|
293
|
+
* Non-string values pass through, so callers may still send Portable Text. If
|
|
294
|
+
* the schema can't be loaded, data is returned unchanged for the handler to
|
|
295
|
+
* validate.
|
|
296
|
+
*/
|
|
297
|
+
async function convertWriteData(
|
|
298
|
+
ec: EmDashHandlers,
|
|
299
|
+
collection: string,
|
|
300
|
+
data: Record<string, unknown>,
|
|
301
|
+
): Promise<Record<string, unknown>> {
|
|
302
|
+
const fields = await getCollectionFields(ec, collection);
|
|
303
|
+
if (!fields) return data;
|
|
304
|
+
return convertDataForWrite(data, fields);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Convert `portableText` field values on each item's `data` to markdown,
|
|
309
|
+
* mutating in place. Inverse of {@link convertWriteData}, gated on the read
|
|
310
|
+
* tools' `markdown` argument.
|
|
311
|
+
*/
|
|
312
|
+
async function applyReadMarkdown(
|
|
313
|
+
ec: EmDashHandlers,
|
|
314
|
+
collection: string,
|
|
315
|
+
items: Array<Record<string, unknown>>,
|
|
316
|
+
): Promise<void> {
|
|
317
|
+
const fields = await getCollectionFields(ec, collection);
|
|
318
|
+
if (!fields) return;
|
|
319
|
+
for (const item of items) {
|
|
320
|
+
if (item.data && typeof item.data === "object") {
|
|
321
|
+
item.data = convertDataForRead(
|
|
322
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above
|
|
323
|
+
item.data as Record<string, unknown>,
|
|
324
|
+
fields,
|
|
325
|
+
false,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async function invalidateBylines(): Promise<void> {
|
|
332
|
+
const { invalidateBylineCache } = await import("../bylines/index.js");
|
|
333
|
+
invalidateBylineCache();
|
|
334
|
+
}
|
|
335
|
+
|
|
271
336
|
/**
|
|
272
337
|
* Enforce a scope requirement on the current request.
|
|
273
338
|
*
|
|
@@ -460,6 +525,12 @@ export function createMcpServer(): McpServer {
|
|
|
460
525
|
.string()
|
|
461
526
|
.optional()
|
|
462
527
|
.describe("Filter by locale (e.g. 'en', 'fr'). Only relevant when i18n is enabled."),
|
|
528
|
+
markdown: z
|
|
529
|
+
.boolean()
|
|
530
|
+
.optional()
|
|
531
|
+
.describe(
|
|
532
|
+
"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).",
|
|
533
|
+
),
|
|
463
534
|
}),
|
|
464
535
|
annotations: { readOnlyHint: true },
|
|
465
536
|
},
|
|
@@ -469,16 +540,26 @@ export function createMcpServer(): McpServer {
|
|
|
469
540
|
// Subscribers must only see published content; force the status
|
|
470
541
|
// filter regardless of caller-supplied value.
|
|
471
542
|
const status = canReadDrafts(extra) ? args.status : "published";
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
543
|
+
const result = await ec.handleContentList(args.collection, {
|
|
544
|
+
status,
|
|
545
|
+
limit: args.limit,
|
|
546
|
+
cursor: args.cursor,
|
|
547
|
+
orderBy: args.orderBy,
|
|
548
|
+
order: args.order,
|
|
549
|
+
locale: args.locale,
|
|
550
|
+
});
|
|
551
|
+
if (result.success && args.markdown) {
|
|
552
|
+
const payload = result.data;
|
|
553
|
+
if (
|
|
554
|
+
payload &&
|
|
555
|
+
typeof payload === "object" &&
|
|
556
|
+
"items" in payload &&
|
|
557
|
+
Array.isArray(payload.items)
|
|
558
|
+
) {
|
|
559
|
+
await applyReadMarkdown(ec, args.collection, payload.items);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return unwrap(result);
|
|
482
563
|
},
|
|
483
564
|
);
|
|
484
565
|
|
|
@@ -499,6 +580,12 @@ export function createMcpServer(): McpServer {
|
|
|
499
580
|
.describe(
|
|
500
581
|
"Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.",
|
|
501
582
|
),
|
|
583
|
+
markdown: z
|
|
584
|
+
.boolean()
|
|
585
|
+
.optional()
|
|
586
|
+
.describe(
|
|
587
|
+
"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).",
|
|
588
|
+
),
|
|
502
589
|
}),
|
|
503
590
|
annotations: { readOnlyHint: true },
|
|
504
591
|
},
|
|
@@ -527,6 +614,9 @@ export function createMcpServer(): McpServer {
|
|
|
527
614
|
});
|
|
528
615
|
}
|
|
529
616
|
}
|
|
617
|
+
if (result.success && args.markdown && result.data?.item) {
|
|
618
|
+
await applyReadMarkdown(ec, args.collection, [result.data.item]);
|
|
619
|
+
}
|
|
530
620
|
return unwrap(result);
|
|
531
621
|
},
|
|
532
622
|
);
|
|
@@ -538,9 +628,12 @@ export function createMcpServer(): McpServer {
|
|
|
538
628
|
description:
|
|
539
629
|
"Create a new content item in a collection. The 'data' object should " +
|
|
540
630
|
"contain field values matching the collection's schema (use " +
|
|
541
|
-
"schema_get_collection to check).
|
|
542
|
-
"
|
|
543
|
-
"
|
|
631
|
+
"schema_get_collection to check). For rich text (portableText) fields, " +
|
|
632
|
+
"pass a Markdown string — converted to Portable Text automatically; prefer " +
|
|
633
|
+
"this. Pass a Portable Text JSON array only for complex content Markdown " +
|
|
634
|
+
"can't express (custom blocks, embeds). A slug is auto-generated if not " +
|
|
635
|
+
"provided. Items are created as 'draft' by default — use content_publish " +
|
|
636
|
+
"to make them live.",
|
|
544
637
|
inputSchema: z.object({
|
|
545
638
|
collection: z.string().describe("Collection slug (e.g. 'posts', 'pages')"),
|
|
546
639
|
data: z
|
|
@@ -561,6 +654,12 @@ export function createMcpServer(): McpServer {
|
|
|
561
654
|
.describe(
|
|
562
655
|
"ID of the content item this is a translation of. Links items in the same translation group.",
|
|
563
656
|
),
|
|
657
|
+
bylines: z
|
|
658
|
+
.array(contentBylineInputSchema)
|
|
659
|
+
.optional()
|
|
660
|
+
.describe(
|
|
661
|
+
"Bylines to credit. Each entry references an existing byline by id (see byline_list / byline_create) with an optional roleLabel. The first entry becomes the primary byline.",
|
|
662
|
+
),
|
|
564
663
|
}),
|
|
565
664
|
annotations: { destructiveHint: false },
|
|
566
665
|
},
|
|
@@ -581,6 +680,8 @@ export function createMcpServer(): McpServer {
|
|
|
581
680
|
);
|
|
582
681
|
}
|
|
583
682
|
|
|
683
|
+
const data = await convertWriteData(emdash, args.collection, args.data);
|
|
684
|
+
|
|
584
685
|
// Publishing requires publish permission — create as draft then publish
|
|
585
686
|
if (args.status === "published") {
|
|
586
687
|
const user = { id: userId, role: getExtra(extra).userRole };
|
|
@@ -591,11 +692,12 @@ export function createMcpServer(): McpServer {
|
|
|
591
692
|
);
|
|
592
693
|
}
|
|
593
694
|
const result = await emdash.handleContentCreate(args.collection, {
|
|
594
|
-
data
|
|
695
|
+
data,
|
|
595
696
|
slug: args.slug,
|
|
596
697
|
authorId: userId,
|
|
597
698
|
locale: args.locale,
|
|
598
699
|
translationOf: args.translationOf,
|
|
700
|
+
bylines: args.bylines,
|
|
599
701
|
});
|
|
600
702
|
if (!result.success) return unwrap(result);
|
|
601
703
|
const itemId = extractContentId(result.data);
|
|
@@ -607,11 +709,12 @@ export function createMcpServer(): McpServer {
|
|
|
607
709
|
|
|
608
710
|
return unwrap(
|
|
609
711
|
await emdash.handleContentCreate(args.collection, {
|
|
610
|
-
data
|
|
712
|
+
data,
|
|
611
713
|
slug: args.slug,
|
|
612
714
|
authorId: userId,
|
|
613
715
|
locale: args.locale,
|
|
614
716
|
translationOf: args.translationOf,
|
|
717
|
+
bylines: args.bylines,
|
|
615
718
|
}),
|
|
616
719
|
);
|
|
617
720
|
},
|
|
@@ -623,7 +726,10 @@ export function createMcpServer(): McpServer {
|
|
|
623
726
|
title: "Update Content",
|
|
624
727
|
description:
|
|
625
728
|
"Update an existing content item. Only include fields you want to change " +
|
|
626
|
-
"in the 'data' object — unspecified fields are left unchanged.
|
|
729
|
+
"in the 'data' object — unspecified fields are left unchanged. Rich text " +
|
|
730
|
+
"(portableText) fields accept a Markdown string (recommended, converted " +
|
|
731
|
+
"automatically); use a Portable Text JSON array only for complex content " +
|
|
732
|
+
"Markdown can't express (custom blocks, embeds). Pass the " +
|
|
627
733
|
"_rev token from content_get to enable optimistic concurrency checking " +
|
|
628
734
|
"(the update fails if the item was modified since you read it). " +
|
|
629
735
|
"`seo` and `bylines` are persisted alongside the field updates in a " +
|
|
@@ -690,6 +796,10 @@ export function createMcpServer(): McpServer {
|
|
|
690
796
|
const ownerId = extractContentAuthorId(existing.data);
|
|
691
797
|
requireOwnership(extra, ownerId, "content:edit_own", "content:edit_any");
|
|
692
798
|
|
|
799
|
+
const data = args.data
|
|
800
|
+
? await convertWriteData(emdash, args.collection, args.data)
|
|
801
|
+
: args.data;
|
|
802
|
+
|
|
693
803
|
// Writing publishedAt directly (incl. clearing to null) overwrites
|
|
694
804
|
// historical record — gate behind publish_any, mirroring the REST PUT
|
|
695
805
|
// route. Status-driven publishes are gated separately below.
|
|
@@ -716,7 +826,7 @@ export function createMcpServer(): McpServer {
|
|
|
716
826
|
args.publishedAt !== undefined
|
|
717
827
|
) {
|
|
718
828
|
const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
|
|
719
|
-
data
|
|
829
|
+
data,
|
|
720
830
|
slug: args.slug,
|
|
721
831
|
authorId: userId,
|
|
722
832
|
locale: args.locale,
|
|
@@ -740,7 +850,7 @@ export function createMcpServer(): McpServer {
|
|
|
740
850
|
args.publishedAt !== undefined
|
|
741
851
|
) {
|
|
742
852
|
const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
|
|
743
|
-
data
|
|
853
|
+
data,
|
|
744
854
|
slug: args.slug,
|
|
745
855
|
authorId: userId,
|
|
746
856
|
locale: args.locale,
|
|
@@ -756,7 +866,7 @@ export function createMcpServer(): McpServer {
|
|
|
756
866
|
|
|
757
867
|
return unwrap(
|
|
758
868
|
await emdash.handleContentUpdate(args.collection, resolvedId, {
|
|
759
|
-
data
|
|
869
|
+
data,
|
|
760
870
|
slug: args.slug,
|
|
761
871
|
authorId: userId,
|
|
762
872
|
locale: args.locale,
|
|
@@ -1163,6 +1273,183 @@ export function createMcpServer(): McpServer {
|
|
|
1163
1273
|
},
|
|
1164
1274
|
);
|
|
1165
1275
|
|
|
1276
|
+
// =====================================================================
|
|
1277
|
+
// Byline tools
|
|
1278
|
+
// =====================================================================
|
|
1279
|
+
|
|
1280
|
+
server.registerTool(
|
|
1281
|
+
"byline_list",
|
|
1282
|
+
{
|
|
1283
|
+
title: "List Bylines",
|
|
1284
|
+
description:
|
|
1285
|
+
"List bylines (author/contributor credits) with optional filtering and " +
|
|
1286
|
+
"pagination. Bylines are standalone records referenced by content items; " +
|
|
1287
|
+
"use the returned id with content_create/content_update or byline_get. Use " +
|
|
1288
|
+
"the nextCursor value from the response to fetch the next page.",
|
|
1289
|
+
inputSchema: z.object({
|
|
1290
|
+
search: z.string().optional().describe("Filter by display name or slug substring"),
|
|
1291
|
+
isGuest: z.boolean().optional().describe("Filter by guest (true) or linked-user (false)"),
|
|
1292
|
+
userId: z.string().optional().describe("Filter to the byline linked to a CMS user ID"),
|
|
1293
|
+
locale: z.string().optional().describe("Filter by locale (omit for all)"),
|
|
1294
|
+
limit: z.number().int().min(1).max(100).optional().describe("Max items (default 50)"),
|
|
1295
|
+
cursor: z.string().min(1).max(2048).optional().describe("Pagination cursor"),
|
|
1296
|
+
}),
|
|
1297
|
+
annotations: { readOnlyHint: true },
|
|
1298
|
+
},
|
|
1299
|
+
async (args, extra) => {
|
|
1300
|
+
requireScope(extra, "content:read");
|
|
1301
|
+
const ec = getEmDash(extra);
|
|
1302
|
+
try {
|
|
1303
|
+
const { BylineRepository } = await import("../database/repositories/byline.js");
|
|
1304
|
+
const repo = new BylineRepository(ec.db);
|
|
1305
|
+
return jsonResult(
|
|
1306
|
+
await repo.findMany({
|
|
1307
|
+
search: args.search,
|
|
1308
|
+
isGuest: args.isGuest,
|
|
1309
|
+
userId: args.userId,
|
|
1310
|
+
locale: args.locale,
|
|
1311
|
+
limit: args.limit,
|
|
1312
|
+
cursor: args.cursor,
|
|
1313
|
+
}),
|
|
1314
|
+
);
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
return respondHandlerError(error, "BYLINE_LIST_ERROR");
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
);
|
|
1320
|
+
|
|
1321
|
+
server.registerTool(
|
|
1322
|
+
"byline_get",
|
|
1323
|
+
{
|
|
1324
|
+
title: "Get Byline",
|
|
1325
|
+
description:
|
|
1326
|
+
"Get a single byline by its ID, including bio, avatar, website, linked " +
|
|
1327
|
+
"user, and any custom fields.",
|
|
1328
|
+
inputSchema: z.object({
|
|
1329
|
+
id: z.string().describe("Byline ID"),
|
|
1330
|
+
}),
|
|
1331
|
+
annotations: { readOnlyHint: true },
|
|
1332
|
+
},
|
|
1333
|
+
async (args, extra) => {
|
|
1334
|
+
requireScope(extra, "content:read");
|
|
1335
|
+
const ec = getEmDash(extra);
|
|
1336
|
+
try {
|
|
1337
|
+
const { BylineRepository } = await import("../database/repositories/byline.js");
|
|
1338
|
+
const byline = await new BylineRepository(ec.db).findById(args.id);
|
|
1339
|
+
if (!byline) return respondError("NOT_FOUND", `Byline '${args.id}' not found`);
|
|
1340
|
+
return jsonResult(byline);
|
|
1341
|
+
} catch (error) {
|
|
1342
|
+
return respondHandlerError(error, "BYLINE_GET_ERROR");
|
|
1343
|
+
}
|
|
1344
|
+
},
|
|
1345
|
+
);
|
|
1346
|
+
|
|
1347
|
+
server.registerTool(
|
|
1348
|
+
"byline_create",
|
|
1349
|
+
{
|
|
1350
|
+
title: "Create Byline",
|
|
1351
|
+
description:
|
|
1352
|
+
"Create a new byline (author/contributor credit). The slug must be unique " +
|
|
1353
|
+
"and contain only lowercase letters, digits, and hyphens. Link the byline " +
|
|
1354
|
+
"to a CMS user via userId, or leave it as a standalone guest credit. The " +
|
|
1355
|
+
"returned id can then be passed to content_create/content_update bylines.",
|
|
1356
|
+
inputSchema: z.object({ ...bylineCreateBody.shape }),
|
|
1357
|
+
annotations: { destructiveHint: false },
|
|
1358
|
+
},
|
|
1359
|
+
async (args, extra) => {
|
|
1360
|
+
requireScope(extra, "content:write");
|
|
1361
|
+
requireRole(extra, Role.EDITOR);
|
|
1362
|
+
const ec = getEmDash(extra);
|
|
1363
|
+
try {
|
|
1364
|
+
const { handleBylineCreate } = await import("../api/handlers/bylines.js");
|
|
1365
|
+
const result = await handleBylineCreate(ec.db, args);
|
|
1366
|
+
if (result.success) await invalidateBylines();
|
|
1367
|
+
return unwrap(result);
|
|
1368
|
+
} catch (error) {
|
|
1369
|
+
return respondHandlerError(error, "BYLINE_CREATE_ERROR");
|
|
1370
|
+
}
|
|
1371
|
+
},
|
|
1372
|
+
);
|
|
1373
|
+
|
|
1374
|
+
server.registerTool(
|
|
1375
|
+
"byline_update",
|
|
1376
|
+
{
|
|
1377
|
+
title: "Update Byline",
|
|
1378
|
+
description:
|
|
1379
|
+
"Update an existing byline. Any field can be omitted to leave it " +
|
|
1380
|
+
"unchanged. Renaming the slug must not collide with another byline.",
|
|
1381
|
+
inputSchema: z.object({
|
|
1382
|
+
id: z.string().describe("Byline ID to update"),
|
|
1383
|
+
...bylineUpdateBody.shape,
|
|
1384
|
+
}),
|
|
1385
|
+
},
|
|
1386
|
+
async (args, extra) => {
|
|
1387
|
+
requireScope(extra, "content:write");
|
|
1388
|
+
requireRole(extra, Role.EDITOR);
|
|
1389
|
+
const ec = getEmDash(extra);
|
|
1390
|
+
try {
|
|
1391
|
+
const { handleBylineUpdate } = await import("../api/handlers/bylines.js");
|
|
1392
|
+
const { id, ...input } = args;
|
|
1393
|
+
const result = await handleBylineUpdate(ec.db, id, input);
|
|
1394
|
+
if (result.success) await invalidateBylines();
|
|
1395
|
+
return unwrap(result);
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
return respondHandlerError(error, "BYLINE_UPDATE_ERROR");
|
|
1398
|
+
}
|
|
1399
|
+
},
|
|
1400
|
+
);
|
|
1401
|
+
|
|
1402
|
+
server.registerTool(
|
|
1403
|
+
"byline_delete",
|
|
1404
|
+
{
|
|
1405
|
+
title: "Delete Byline",
|
|
1406
|
+
description:
|
|
1407
|
+
"Permanently delete a byline. Any content crediting this byline loses the " +
|
|
1408
|
+
"association, and it is cleared as a primary byline where set.",
|
|
1409
|
+
inputSchema: z.object({
|
|
1410
|
+
id: z.string().describe("Byline ID to delete"),
|
|
1411
|
+
}),
|
|
1412
|
+
annotations: { destructiveHint: true },
|
|
1413
|
+
},
|
|
1414
|
+
async (args, extra) => {
|
|
1415
|
+
requireScope(extra, "content:write");
|
|
1416
|
+
requireRole(extra, Role.EDITOR);
|
|
1417
|
+
const ec = getEmDash(extra);
|
|
1418
|
+
try {
|
|
1419
|
+
const { BylineRepository } = await import("../database/repositories/byline.js");
|
|
1420
|
+
const deleted = await new BylineRepository(ec.db).delete(args.id);
|
|
1421
|
+
if (!deleted) return respondError("NOT_FOUND", `Byline '${args.id}' not found`);
|
|
1422
|
+
await invalidateBylines();
|
|
1423
|
+
return jsonResult({ deleted: args.id });
|
|
1424
|
+
} catch (error) {
|
|
1425
|
+
return respondHandlerError(error, "BYLINE_DELETE_ERROR");
|
|
1426
|
+
}
|
|
1427
|
+
},
|
|
1428
|
+
);
|
|
1429
|
+
|
|
1430
|
+
server.registerTool(
|
|
1431
|
+
"byline_translations",
|
|
1432
|
+
{
|
|
1433
|
+
title: "List Byline Translations",
|
|
1434
|
+
description:
|
|
1435
|
+
"Return every locale variant of a byline, identified via its shared translation_group.",
|
|
1436
|
+
inputSchema: z.object({
|
|
1437
|
+
id: z.string().describe("Byline id (or translation_group)"),
|
|
1438
|
+
}),
|
|
1439
|
+
annotations: { readOnlyHint: true },
|
|
1440
|
+
},
|
|
1441
|
+
async (args, extra) => {
|
|
1442
|
+
requireScope(extra, "content:read");
|
|
1443
|
+
const ec = getEmDash(extra);
|
|
1444
|
+
try {
|
|
1445
|
+
const { handleBylineTranslations } = await import("../api/handlers/bylines.js");
|
|
1446
|
+
return unwrap(await handleBylineTranslations(ec.db, args.id));
|
|
1447
|
+
} catch (error) {
|
|
1448
|
+
return respondHandlerError(error, "BYLINE_TRANSLATIONS_ERROR");
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
);
|
|
1452
|
+
|
|
1166
1453
|
// =====================================================================
|
|
1167
1454
|
// Schema tools
|
|
1168
1455
|
// =====================================================================
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portable helpers shared by the platform image-endpoint modules.
|
|
3
|
+
*
|
|
4
|
+
* EmDash wraps Astro's image endpoint (`image.endpoint`) so that source bytes
|
|
5
|
+
* for EmDash media are read straight from the storage adapter instead of being
|
|
6
|
+
* fetched over HTTP. The platform endpoint modules (Node: sharp via
|
|
7
|
+
* `astro:assets`; Cloudflare: the `IMAGES` binding) do the actual transform;
|
|
8
|
+
* this module holds the platform-agnostic bits they share: recognizing an
|
|
9
|
+
* EmDash media URL and validating transform query params.
|
|
10
|
+
*
|
|
11
|
+
* Kept free of `astro:*` / `virtual:emdash/*` imports so it stays in the
|
|
12
|
+
* precompiled package and can be unit-tested directly.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { INTERNAL_MEDIA_PREFIX } from "./normalize.js";
|
|
16
|
+
|
|
17
|
+
/** Output formats the wrapped endpoint can produce on Cloudflare. */
|
|
18
|
+
export const ALLOWED_TRANSFORM_FORMATS = ["webp", "avif", "jpeg", "png"] as const;
|
|
19
|
+
|
|
20
|
+
/** Default output format -- broad support, strong compression. */
|
|
21
|
+
export const DEFAULT_TRANSFORM_FORMAT: ImageTransformFormat = "webp";
|
|
22
|
+
|
|
23
|
+
/** Upper bound for a requested dimension; caps the work a single request asks for. */
|
|
24
|
+
export const MAX_TRANSFORM_DIMENSION = 4000;
|
|
25
|
+
|
|
26
|
+
/** A format string accepted by {@link ImageTransformOptions.format}. */
|
|
27
|
+
export type ImageTransformFormat = (typeof ALLOWED_TRANSFORM_FORMATS)[number];
|
|
28
|
+
|
|
29
|
+
/** Validated options for a single transform. */
|
|
30
|
+
export interface ImageTransformOptions {
|
|
31
|
+
width?: number;
|
|
32
|
+
height?: number;
|
|
33
|
+
format: ImageTransformFormat;
|
|
34
|
+
quality?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Long-lived immutable cache -- transform output is deterministic per key+params. */
|
|
38
|
+
export const IMMUTABLE_IMAGE_CACHE = "public, max-age=31536000, immutable";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Raster types safe to render inline. Anything else (SVG, PDF, ...) is served
|
|
42
|
+
* as an attachment so it can't execute as an active document. Mirrors the
|
|
43
|
+
* `/_emdash/api/media/file/{key}` route's allowlist.
|
|
44
|
+
*/
|
|
45
|
+
const SAFE_INLINE_IMAGE_TYPES = new Set([
|
|
46
|
+
"image/jpeg",
|
|
47
|
+
"image/png",
|
|
48
|
+
"image/gif",
|
|
49
|
+
"image/webp",
|
|
50
|
+
"image/avif",
|
|
51
|
+
"image/x-icon",
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Headers for streaming **original** stored bytes (the no-transform fallback).
|
|
56
|
+
* Carries the same stored-XSS protections as the media file route: a sandbox
|
|
57
|
+
* CSP, `nosniff`, and `Content-Disposition: attachment` for anything not on the
|
|
58
|
+
* inline raster allowlist (so a stored SVG can't run scripts in the site
|
|
59
|
+
* origin). Transformed output is always generated raster and doesn't need this.
|
|
60
|
+
*/
|
|
61
|
+
export function originalMediaHeaders(contentType: string): Record<string, string> {
|
|
62
|
+
return {
|
|
63
|
+
"Content-Type": contentType,
|
|
64
|
+
"Cache-Control": IMMUTABLE_IMAGE_CACHE,
|
|
65
|
+
"X-Content-Type-Options": "nosniff",
|
|
66
|
+
"Content-Security-Policy":
|
|
67
|
+
"sandbox; default-src 'none'; img-src 'self'; style-src 'unsafe-inline'",
|
|
68
|
+
"Content-Disposition": SAFE_INLINE_IMAGE_TYPES.has(contentType) ? "inline" : "attachment",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Storage keys safe to serve: the flat `{ulid}{ext}` shape, no slashes/traversal. */
|
|
73
|
+
const SAFE_STORAGE_KEY = /^[A-Za-z0-9._-]+$/;
|
|
74
|
+
|
|
75
|
+
/** Plain decimal digits only -- rejects "1e3", "0x10", "+5", whitespace. */
|
|
76
|
+
const DECIMAL_DIGITS = /^\d+$/;
|
|
77
|
+
|
|
78
|
+
/** Whether a storage key is safe to resolve against the storage backend. */
|
|
79
|
+
export function isSafeTransformKey(key: string): boolean {
|
|
80
|
+
return SAFE_STORAGE_KEY.test(key);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* If `href` points at the internal EmDash media route
|
|
85
|
+
* (`/_emdash/api/media/file/{key}`) with a safe key, return the key; otherwise
|
|
86
|
+
* `null` (the endpoint then delegates to the stock image endpoint for bundled
|
|
87
|
+
* assets, allowed remote, and `publicUrl` media).
|
|
88
|
+
*
|
|
89
|
+
* The component absolutizes same-origin media (Astro only optimizes absolute,
|
|
90
|
+
* remote-allowed URLs), so `href` is typically `https://site/_emdash/...` but
|
|
91
|
+
* may be relative. We match on the **pathname** only and never fetch `href` —
|
|
92
|
+
* the key is read from our own storage — so the host is irrelevant and can't be
|
|
93
|
+
* an SSRF vector. A dummy base resolves both absolute and relative forms and
|
|
94
|
+
* strips any query/fragment.
|
|
95
|
+
*/
|
|
96
|
+
export function matchInternalMediaKey(href: string | null | undefined): string | null {
|
|
97
|
+
if (!href) return null;
|
|
98
|
+
let pathname: string;
|
|
99
|
+
try {
|
|
100
|
+
pathname = new URL(href, "http://localhost").pathname;
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
if (!pathname.startsWith(INTERNAL_MEDIA_PREFIX)) return null;
|
|
105
|
+
const key = pathname.slice(INTERNAL_MEDIA_PREFIX.length);
|
|
106
|
+
if (!key || !isSafeTransformKey(key)) return null;
|
|
107
|
+
return key;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Type guard for {@link ImageTransformFormat}. */
|
|
111
|
+
export function isTransformFormat(value: string): value is ImageTransformFormat {
|
|
112
|
+
return (ALLOWED_TRANSFORM_FORMATS as readonly string[]).includes(value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Outcome of parsing transform query params: validated options or an error. */
|
|
116
|
+
export type ParsedTransformParams =
|
|
117
|
+
| { ok: true; options: ImageTransformOptions }
|
|
118
|
+
| { ok: false; message: string };
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Parse and validate `?w=&h=&f=&q=` query params. Width is required (it sizes
|
|
122
|
+
* the rendition); dimensions are bounded so a request can't ask for an
|
|
123
|
+
* unbounded or nonsensical transform.
|
|
124
|
+
*/
|
|
125
|
+
export function parseTransformParams(params: URLSearchParams): ParsedTransformParams {
|
|
126
|
+
const width = parseDimension(params.get("w"));
|
|
127
|
+
if (width === null) return { ok: false, message: "Invalid 'w' (width)" };
|
|
128
|
+
if (width === undefined) return { ok: false, message: "Missing 'w' (width)" };
|
|
129
|
+
|
|
130
|
+
const height = parseDimension(params.get("h"));
|
|
131
|
+
if (height === null) return { ok: false, message: "Invalid 'h' (height)" };
|
|
132
|
+
|
|
133
|
+
const formatRaw = params.get("f");
|
|
134
|
+
let format: ImageTransformFormat = DEFAULT_TRANSFORM_FORMAT;
|
|
135
|
+
if (formatRaw !== null) {
|
|
136
|
+
if (!isTransformFormat(formatRaw)) {
|
|
137
|
+
return { ok: false, message: `Unsupported 'f' (format): ${formatRaw}` };
|
|
138
|
+
}
|
|
139
|
+
format = formatRaw;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const qualityRaw = params.get("q");
|
|
143
|
+
let quality: number | undefined;
|
|
144
|
+
if (qualityRaw !== null) {
|
|
145
|
+
const q = Number(qualityRaw);
|
|
146
|
+
if (!Number.isInteger(q) || q < 1 || q > 100) {
|
|
147
|
+
return { ok: false, message: "Invalid 'q' (quality), expected 1-100" };
|
|
148
|
+
}
|
|
149
|
+
quality = q;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { ok: true, options: { width, height, format, quality } };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Parse a dimension query value.
|
|
157
|
+
* - `undefined`: param absent
|
|
158
|
+
* - `null`: present but invalid (non-integer, out of range)
|
|
159
|
+
* - `number`: valid, within [1, MAX_TRANSFORM_DIMENSION]
|
|
160
|
+
*/
|
|
161
|
+
function parseDimension(raw: string | null): number | undefined | null {
|
|
162
|
+
if (raw === null) return undefined;
|
|
163
|
+
if (!DECIMAL_DIGITS.test(raw)) return null;
|
|
164
|
+
const n = Number(raw);
|
|
165
|
+
if (n < 1 || n > MAX_TRANSFORM_DIMENSION) return null;
|
|
166
|
+
return n;
|
|
167
|
+
}
|
package/src/menus/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type { Database } from "../database/types.js";
|
|
|
15
15
|
import { validateIdentifier } from "../database/validate.js";
|
|
16
16
|
import { resolveLocale, resolveLocaleChain } from "../i18n/resolve.js";
|
|
17
17
|
import { getDb } from "../loader.js";
|
|
18
|
+
import { cachedQuery, CacheNamespace } from "../object-cache/index.js";
|
|
18
19
|
import { requestCached } from "../request-cache.js";
|
|
19
20
|
import { sanitizeHref } from "../utils/url.js";
|
|
20
21
|
import type { Menu, MenuItem, MenuItemRow } from "./types.js";
|
|
@@ -36,10 +37,16 @@ export interface MenuQueryOptions {
|
|
|
36
37
|
*/
|
|
37
38
|
export function getMenu(name: string, options: MenuQueryOptions = {}): Promise<Menu | null> {
|
|
38
39
|
const locale = resolveLocale(options.locale);
|
|
39
|
-
return requestCached(`menu:${name}:${locale ?? "*"}`,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return requestCached(`menu:${name}:${locale ?? "*"}`, () =>
|
|
41
|
+
cachedQuery({
|
|
42
|
+
namespace: CacheNamespace.MENUS,
|
|
43
|
+
key: `${name}:${locale ?? "*"}`,
|
|
44
|
+
load: async () => {
|
|
45
|
+
const db = await getDb();
|
|
46
|
+
return getMenuWithDb(name, db, { locale });
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
/**
|