emdash 0.21.0 → 0.23.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-DAAjOID4.d.mts} +1 -1
- package/dist/{adapters-BxSmgtbF.d.mts.map → adapters-DAAjOID4.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-D5FxMUo8.mjs} +2 -2
- package/dist/{allowed-origins-BqC8cul8.mjs.map → allowed-origins-D5FxMUo8.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-BQ_yKRdG.mjs} +31 -25
- package/dist/api-BQ_yKRdG.mjs.map +1 -0
- package/dist/{api-tokens-BFFkB0jB.mjs → api-tokens-D6ppjIVi.mjs} +13 -3
- package/dist/api-tokens-D6ppjIVi.mjs.map +1 -0
- package/dist/{apply-CLjxheyb.mjs → apply-CWRyxIoO.mjs} +18 -18
- package/dist/{apply-CLjxheyb.mjs.map → apply-CWRyxIoO.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 +122 -26
- 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.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +8 -6
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- 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 +444 -149
- 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 +18 -16
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +18 -16
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +18 -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 +41 -39
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +41 -39
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +40 -38
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +40 -38
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +40 -38
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +40 -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 +40 -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 +40 -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 +40 -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 +40 -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 +41 -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 +40 -38
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +41 -39
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +40 -38
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +40 -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 +40 -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 +17 -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 +19 -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 +40 -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 +40 -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 +40 -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 +40 -38
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +40 -38
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -8
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +40 -38
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +40 -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 +30 -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 +30 -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-Cse0k7B0.mjs} +2 -2
- package/dist/{authorize-D5gfBVU5.mjs.map → authorize-Cse0k7B0.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-DVo-liaP.mjs} +27 -76
- package/dist/byline-DVo-liaP.mjs.map +1 -0
- package/dist/{byline-fields-B0NO1yUB.mjs → byline-fields-B-KXkg5R.mjs} +3 -3
- package/dist/{byline-fields-B0NO1yUB.mjs.map → byline-fields-B-KXkg5R.mjs.map} +1 -1
- package/dist/{byline-fields-nBVqK_Ff.mjs → byline-fields-DaMKzkhO.mjs} +2 -2
- package/dist/{byline-fields-nBVqK_Ff.mjs.map → byline-fields-DaMKzkhO.mjs.map} +1 -1
- package/dist/{byline-fields-CQJRIQkn.d.mts → byline-fields-RFPkDLRw.d.mts} +56 -31
- package/dist/byline-fields-RFPkDLRw.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-f5ppBpD5.mjs} +8 -8
- package/dist/{bylines-DfGDnred.mjs.map → bylines-f5ppBpD5.mjs.map} +1 -1
- package/dist/{bylines-B2NWnIwS.mjs → bylines-pIKgc_TL.mjs} +10 -4
- package/dist/{bylines-B2NWnIwS.mjs.map → bylines-pIKgc_TL.mjs.map} +1 -1
- package/dist/{cache-DTTHWD8n.mjs → cache-Q6V4U-Xz.mjs} +3 -3
- package/dist/{cache-DTTHWD8n.mjs.map → cache-Q6V4U-Xz.mjs.map} +1 -1
- package/dist/{challenge-store-woE0bbCf.mjs → challenge-store-LhiqMccz.mjs} +1 -1
- package/dist/{challenge-store-woE0bbCf.mjs.map → challenge-store-LhiqMccz.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 +29 -27
- 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-Dyb-AutY.mjs +85 -0
- package/dist/comment-reaction-Dyb-AutY.mjs.map +1 -0
- package/dist/{comments-D2hNuxNa.mjs → comments-Cczx7AvD.mjs} +3 -3
- package/dist/{comments-D2hNuxNa.mjs.map → comments-Cczx7AvD.mjs.map} +1 -1
- package/dist/{components-DYKp2gmo.mjs → components-CYt4uVK9.mjs} +1 -1
- package/dist/{components-DYKp2gmo.mjs.map → components-CYt4uVK9.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-B1W8soLv.mjs} +64 -26
- package/dist/context-B1W8soLv.mjs.map +1 -0
- package/dist/{cron-DdEVrQ2Y.mjs → cron-C5LVoNmP.mjs} +14 -2
- package/dist/cron-C5LVoNmP.mjs.map +1 -0
- package/dist/{dashboard-C-UYpps0.mjs → dashboard-CYjpQZ6-.mjs} +4 -4
- package/dist/{dashboard-C-UYpps0.mjs.map → dashboard-CYjpQZ6-.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-UXB1CK42.mjs} +1 -1
- package/dist/{db-errors-BluWkwGI.mjs.map → db-errors-UXB1CK42.mjs.map} +1 -1
- package/dist/{default-NHGuJzQ3.mjs → default-CeRG-Ot4.mjs} +1 -1
- package/dist/{default-NHGuJzQ3.mjs.map → default-CeRG-Ot4.mjs.map} +1 -1
- package/dist/{device-flow-BQApWgnW.mjs → device-flow-DENDCQ9F.mjs} +5 -5
- package/dist/{device-flow-BQApWgnW.mjs.map → device-flow-DENDCQ9F.mjs.map} +1 -1
- package/dist/{email-console-BbU3RbWv.mjs → email-console-DJP32ucW.mjs} +1 -1
- package/dist/{email-console-BbU3RbWv.mjs.map → email-console-DJP32ucW.mjs.map} +1 -1
- package/dist/{error-CNn_w7jf.mjs → error-Bl6kZgtt.mjs} +2 -2
- package/dist/{error-CNn_w7jf.mjs.map → error-Bl6kZgtt.mjs.map} +1 -1
- package/dist/{escape-DPgcxcpL.mjs → escape-Bjio4ZsM.mjs} +1 -1
- package/dist/{escape-DPgcxcpL.mjs.map → escape-Bjio4ZsM.mjs.map} +1 -1
- package/dist/field-defs-cache-ztrdzUGb.mjs +77 -0
- package/dist/field-defs-cache-ztrdzUGb.mjs.map +1 -0
- package/dist/{fts-manager-Cx5z8jdA.mjs → fts-manager-CQuHt-vS.mjs} +2 -2
- package/dist/{fts-manager-Cx5z8jdA.mjs.map → fts-manager-CQuHt-vS.mjs.map} +1 -1
- package/dist/{hash-DlvIFn0b.mjs → hash-DrvzIXcz.mjs} +1 -1
- package/dist/{hash-DlvIFn0b.mjs.map → hash-DrvzIXcz.mjs.map} +1 -1
- package/dist/{import-KyxT1Mbs.mjs → import-Bb1T9WJS.mjs} +4 -4
- package/dist/{import-KyxT1Mbs.mjs.map → import-Bb1T9WJS.mjs.map} +1 -1
- package/dist/{index-D2VAiumu.d.mts → index-BaIj5hIq.d.mts} +198 -21
- package/dist/index-BaIj5hIq.d.mts.map +1 -0
- package/dist/{index-uT2yR66F.d.mts → index-qbL02uhs.d.mts} +3 -3
- package/dist/{index-uT2yR66F.d.mts.map → index-qbL02uhs.d.mts.map} +1 -1
- package/dist/index.d.mts +18 -17
- package/dist/index.mjs +64 -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-BNo-ER8C.mjs} +2 -2
- package/dist/{load-Dq91b_DK.mjs.map → load-BNo-ER8C.mjs.map} +1 -1
- package/dist/{loader-BqWjcH3h.mjs → loader-Dn74CG1b.mjs} +70 -11
- package/dist/loader-Dn74CG1b.mjs.map +1 -0
- package/dist/{manifest-schema-DFPeqMAn.mjs → manifest-schema-BWKnQYQF.mjs} +1 -1
- package/dist/{manifest-schema-DFPeqMAn.mjs.map → manifest-schema-BWKnQYQF.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 +19 -11
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +16 -13
- 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-B77I5_bw.mjs} +2 -2
- package/dist/{media-allowlist-_A0SuDn4.mjs.map → media-allowlist-B77I5_bw.mjs.map} +1 -1
- package/dist/{media-url-CqLd69IO.mjs → media-url-O4rm9-SQ.mjs} +1 -1
- package/dist/{media-url-CqLd69IO.mjs.map → media-url-O4rm9-SQ.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-DS8VTZgo.mjs} +167 -24
- package/dist/menus-DS8VTZgo.mjs.map +1 -0
- package/dist/{mime-YbtlEtvS.mjs → mime-BTzvzJ8M.mjs} +1 -1
- package/dist/{mime-YbtlEtvS.mjs.map → mime-BTzvzJ8M.mjs.map} +1 -1
- package/dist/{mode-CGXzIbD8.mjs → mode-BB0F8xTC.mjs} +1 -1
- package/dist/{mode-CGXzIbD8.mjs.map → mode-BB0F8xTC.mjs.map} +1 -1
- package/dist/{normalize-DKsg36ty.mjs → normalize-ClbNIenm.mjs} +1 -1
- package/dist/{normalize-DKsg36ty.mjs.map → normalize-ClbNIenm.mjs.map} +1 -1
- package/dist/{oauth-authorization-C2kVyjXI.mjs → oauth-authorization-CsvzIp_F.mjs} +5 -5
- package/dist/{oauth-authorization-C2kVyjXI.mjs.map → oauth-authorization-CsvzIp_F.mjs.map} +1 -1
- package/dist/{oauth-clients-BC873NCV.mjs → oauth-clients-C9SYwEbZ.mjs} +1 -1
- package/dist/{oauth-clients-BC873NCV.mjs.map → oauth-clients-C9SYwEbZ.mjs.map} +1 -1
- package/dist/{oauth-state-store-Cd--TUaq.mjs → oauth-state-store---zrApfB.mjs} +1 -1
- package/dist/{oauth-state-store-Cd--TUaq.mjs.map → oauth-state-store---zrApfB.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-e4wOvDud.mjs → oauth-user-lookup-SHsWRlG9.mjs} +1 -1
- package/dist/{oauth-user-lookup-e4wOvDud.mjs.map → oauth-user-lookup-SHsWRlG9.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-CqECG0gM.d.mts} +3 -3
- package/dist/{options-9kLgkE8m.d.mts.map → options-CqECG0gM.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-C9hpjUyY.mjs} +2 -2
- package/dist/{parse-DzSrk1t8.mjs.map → parse-C9hpjUyY.mjs.map} +1 -1
- package/dist/{passkey-config-BpjbE_Uv.mjs → passkey-config-C0YfSBko.mjs} +1 -1
- package/dist/{passkey-config-BpjbE_Uv.mjs.map → passkey-config-C0YfSBko.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-B0s2mWu5.mjs} +1 -1
- package/dist/{placeholder-2xumZh4g.mjs.map → placeholder-B0s2mWu5.mjs.map} +1 -1
- package/dist/{placeholder-BevVKfay.d.mts → placeholder-QoI4gEzP.d.mts} +1 -1
- package/dist/{placeholder-BevVKfay.d.mts.map → placeholder-QoI4gEzP.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-BICg8bTk.mjs} +2 -135
- package/dist/portable-text-BICg8bTk.mjs.map +1 -0
- package/dist/{preview-Dqv2hwXr.mjs → preview-DKGCt2_p.mjs} +2 -2
- package/dist/{preview-Dqv2hwXr.mjs.map → preview-DKGCt2_p.mjs.map} +1 -1
- package/dist/{public-url-D_zARuvZ.mjs → public-url-CTVqgMmg.mjs} +1 -1
- package/dist/{public-url-D_zARuvZ.mjs.map → public-url-CTVqgMmg.mjs.map} +1 -1
- package/dist/{query-Crm038Mc.mjs → query-DgUHZLWB.mjs} +230 -31
- package/dist/query-DgUHZLWB.mjs.map +1 -0
- package/dist/{rate-limit-hRTBqmw1.mjs → rate-limit-BuQ5d4X_.mjs} +2 -2
- package/dist/{rate-limit-hRTBqmw1.mjs.map → rate-limit-BuQ5d4X_.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/{redirect-C-OOkyku.mjs → redirect-CS-PHtNh.mjs} +1 -1
- package/dist/{redirect-C-OOkyku.mjs.map → redirect-CS-PHtNh.mjs.map} +1 -1
- package/dist/{redirects-CP3TnTLO.mjs → redirects-BZ8Mxn8H.mjs} +6 -6
- package/dist/{redirects-CP3TnTLO.mjs.map → redirects-BZ8Mxn8H.mjs.map} +1 -1
- package/dist/{redirects-6Zg2SoYo.mjs → redirects-x9eFPeyi.mjs} +10 -3
- package/dist/redirects-x9eFPeyi.mjs.map +1 -0
- package/dist/{registry-diMzD1Wf.mjs → registry-CK1SS6pi.mjs} +6 -6
- package/dist/{registry-diMzD1Wf.mjs.map → registry-CK1SS6pi.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-CmS1tDFf.mjs} +2 -2
- package/dist/{request-meta-DPechd0W.mjs.map → request-meta-CmS1tDFf.mjs.map} +1 -1
- package/dist/{resolve-B3NUUtVY.mjs → resolve-C7I0qiR0.mjs} +1 -1
- package/dist/{resolve-B3NUUtVY.mjs.map → resolve-C7I0qiR0.mjs.map} +1 -1
- package/dist/{runner-C8vcbvCe.d.mts → runner-CEtq-6Sm.d.mts} +2 -2
- package/dist/{runner-C8vcbvCe.d.mts.map → runner-CEtq-6Sm.d.mts.map} +1 -1
- package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
- package/dist/runner-DYYnW530.mjs.map +1 -0
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +3 -3
- package/dist/{schema-BDOkd3OU.mjs → schema-CbFRFoM7.mjs} +13 -8
- package/dist/schema-CbFRFoM7.mjs.map +1 -0
- package/dist/{search-Bs_J_EW-.mjs → search-C-waE_YW.mjs} +4 -4
- package/dist/{search-Bs_J_EW-.mjs.map → search-C-waE_YW.mjs.map} +1 -1
- package/dist/{secrets-C8xmE6mR.mjs → secrets-BSf9pRRY.mjs} +5 -5
- package/dist/{secrets-C8xmE6mR.mjs.map → secrets-BSf9pRRY.mjs.map} +1 -1
- package/dist/{sections-P0zuBlyz.mjs → sections-osX9U-YJ.mjs} +3 -3
- package/dist/{sections-P0zuBlyz.mjs.map → sections-osX9U-YJ.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +23 -21
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/{seo-DpNgGQjF.mjs → seo-4FovMwNS.mjs} +5 -2
- package/dist/seo-4FovMwNS.mjs.map +1 -0
- package/dist/{seo-CLhm-Fmb.mjs → seo-DCEF-AVr.mjs} +1 -1
- package/dist/{seo-CLhm-Fmb.mjs.map → seo-DCEF-AVr.mjs.map} +1 -1
- package/dist/{service-CDQQnT8W.mjs → service-jby1RRmU.mjs} +3 -3
- package/dist/{service-CDQQnT8W.mjs.map → service-jby1RRmU.mjs.map} +1 -1
- package/dist/session-user-B8aLtKAH.mjs +51 -0
- package/dist/session-user-B8aLtKAH.mjs.map +1 -0
- package/dist/{settings-sO0Fif4p.mjs → settings-4bRT2NIf.mjs} +3 -3
- package/dist/{settings-sO0Fif4p.mjs.map → settings-4bRT2NIf.mjs.map} +1 -1
- package/dist/{settings-BjBsmVAo.mjs → settings-t-H2jPuJ.mjs} +18 -10
- package/dist/settings-t-H2jPuJ.mjs.map +1 -0
- package/dist/{setup-complete-CMMr-oZU.mjs → setup-complete-gEiySUc-.mjs} +2 -2
- package/dist/{setup-complete-CMMr-oZU.mjs.map → setup-complete-gEiySUc-.mjs.map} +1 -1
- package/dist/{setup-nonce-169xl4fV.mjs → setup-nonce-DzS50zme.mjs} +1 -1
- package/dist/{setup-nonce-169xl4fV.mjs.map → setup-nonce-DzS50zme.mjs.map} +1 -1
- package/dist/{single-flight-cache-C0UV1Npg.mjs → single-flight-cache-Cdfkic3t.mjs} +2 -2
- package/dist/{single-flight-cache-C0UV1Npg.mjs.map → single-flight-cache-Cdfkic3t.mjs.map} +1 -1
- package/dist/{site-url-vtsuOvSD.mjs → site-url-BLebyON8.mjs} +2 -2
- package/dist/{site-url-vtsuOvSD.mjs.map → site-url-BLebyON8.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-BRKb343l.mjs} +1 -1
- package/dist/{ssrf-XO05Voq6.mjs.map → ssrf-BRKb343l.mjs.map} +1 -1
- package/dist/{status-2gZklYuj.mjs → status-vUK0SA17.mjs} +1 -1
- package/dist/{status-2gZklYuj.mjs.map → status-vUK0SA17.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-DuESHWKI.mjs → taxonomies-BBB8O-CU.mjs} +7 -7
- package/dist/{taxonomies-DuESHWKI.mjs.map → taxonomies-BBB8O-CU.mjs.map} +1 -1
- package/dist/{taxonomies-BBxYA38v.mjs → taxonomies-Dxrc_szG.mjs} +177 -123
- package/dist/taxonomies-Dxrc_szG.mjs.map +1 -0
- package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
- package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
- package/dist/{tokens-DMkVjxrx.mjs → tokens-LeuXF9gG.mjs} +2 -2
- package/dist/{tokens-DMkVjxrx.mjs.map → tokens-LeuXF9gG.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-jdvsZEIt.d.mts → transport-BZ-03aFT.d.mts} +1 -1
- package/dist/{transport-jdvsZEIt.d.mts.map → transport-BZ-03aFT.d.mts.map} +1 -1
- package/dist/transport-_2nBz7e9.mjs +135 -0
- package/dist/transport-_2nBz7e9.mjs.map +1 -0
- package/dist/{trusted-proxy-CHp41Fjj.mjs → trusted-proxy-DZY5WCn2.mjs} +1 -1
- package/dist/{trusted-proxy-CHp41Fjj.mjs.map → trusted-proxy-DZY5WCn2.mjs.map} +1 -1
- package/dist/{types-Del0VMij.d.mts → types-B-gIxFCE.d.mts} +9 -1
- package/dist/{types-Del0VMij.d.mts.map → types-B-gIxFCE.d.mts.map} +1 -1
- package/dist/{types-DdkL6fyv.d.mts → types-BG8_XTLj.d.mts} +1 -1
- package/dist/{types-DdkL6fyv.d.mts.map → types-BG8_XTLj.d.mts.map} +1 -1
- package/dist/{types-BTnnBYVX.d.mts → types-BWh2MjmA.d.mts} +15 -2
- package/dist/types-BWh2MjmA.d.mts.map +1 -0
- package/dist/{types-CkEuk-Zr.d.mts → types-BWqGVhFn.d.mts} +1 -1
- package/dist/{types-CkEuk-Zr.d.mts.map → types-BWqGVhFn.d.mts.map} +1 -1
- package/dist/{types-DejCHqWT.mjs → types-CQAugunJ.mjs} +1 -1
- package/dist/{types-DejCHqWT.mjs.map → types-CQAugunJ.mjs.map} +1 -1
- package/dist/{types-Bzfk2yC8.d.mts → types-CTLJYMhN.d.mts} +1 -1
- package/dist/{types-Bzfk2yC8.d.mts.map → types-CTLJYMhN.d.mts.map} +1 -1
- package/dist/{types-BFgYtuKd.d.mts → types-CUsXGRVj.d.mts} +1 -1
- package/dist/{types-BFgYtuKd.d.mts.map → types-CUsXGRVj.d.mts.map} +1 -1
- package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
- package/dist/types-DXOIbece.mjs.map +1 -0
- package/dist/{types-u_XxjbS8.d.mts → types-DrYMm9s5.d.mts} +1 -1
- package/dist/{types-u_XxjbS8.d.mts.map → types-DrYMm9s5.d.mts.map} +1 -1
- package/dist/{types-DO7whVYU.d.mts → types-TTx8uP7V.d.mts} +2 -2
- package/dist/{types-DO7whVYU.d.mts.map → types-TTx8uP7V.d.mts.map} +1 -1
- package/dist/types-fS7-VTdR.d.mts +124 -0
- package/dist/types-fS7-VTdR.d.mts.map +1 -0
- 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-B7A57fm9.mjs} +2 -2
- package/dist/{utils-C4M981Br.mjs.map → utils-B7A57fm9.mjs.map} +1 -1
- package/dist/{validate-DGhQPXzI.mjs → validate-0Utjspbs.mjs} +3 -3
- package/dist/{validate-DGhQPXzI.mjs.map → validate-0Utjspbs.mjs.map} +1 -1
- package/dist/{validate-cJOiOvT2.d.mts → validate-DOFrIb-c.d.mts} +5 -5
- package/dist/{validate-cJOiOvT2.d.mts.map → validate-DOFrIb-c.d.mts.map} +1 -1
- package/dist/{validation-DVHjPM1M.mjs → validation-D9EnzH1T.mjs} +6 -6
- package/dist/{validation-DVHjPM1M.mjs.map → validation-D9EnzH1T.mjs.map} +1 -1
- package/dist/version-BgVM_1MU.mjs +7 -0
- package/dist/{version-BOjj_cfz.mjs.map → version-BgVM_1MU.mjs.map} +1 -1
- package/dist/{widgets-Ci6hLwfO.mjs → widgets-BSTzPUYa.mjs} +4 -4
- package/dist/{widgets-Ci6hLwfO.mjs.map → widgets-BSTzPUYa.mjs.map} +1 -1
- package/dist/{zod-generator-CarzgPAu.mjs → zod-generator-ElVQOav7.mjs} +51 -15
- package/dist/zod-generator-ElVQOav7.mjs.map +1 -0
- package/package.json +19 -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/bylines.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 +40 -0
- package/src/astro/integration/vite-config.ts +25 -1
- package/src/astro/middleware/auth.ts +4 -3
- package/src/astro/middleware/request-context.ts +6 -1
- package/src/astro/middleware/scoped-db.ts +131 -0
- package/src/astro/middleware/stream-end-metrics.ts +15 -9
- package/src/astro/middleware.ts +131 -31
- package/src/astro/object-cache/adapters.ts +50 -0
- package/src/astro/prefetch.ts +77 -0
- package/src/astro/routes/admin.astro +5 -1
- package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
- package/src/astro/routes/api/schema/index.ts +9 -3
- 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/cli/commands/export-seed.ts +10 -7
- package/src/comments/query.ts +78 -7
- package/src/comments/ranking.ts +58 -0
- package/src/components/Block.astro +71 -0
- package/src/components/Comments.astro +136 -1
- package/src/components/EmDashMedia.astro +1 -2
- package/src/components/Image.astro +36 -2
- package/src/components/InlinePortableTextEditor.tsx +10 -2
- package/src/components/index.ts +5 -0
- package/src/components/portable-text-text-align.ts +38 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +5 -1
- package/src/content/converters/prosemirror-to-portable-text.ts +8 -0
- package/src/content/converters/types.ts +1 -0
- 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 +27 -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/repositories/types.ts +13 -0
- package/src/database/types.ts +9 -0
- package/src/emdash-runtime.ts +244 -75
- package/src/index.ts +22 -0
- package/src/loader.ts +97 -5
- package/src/mcp/server.ts +307 -20
- package/src/media/image-endpoint.ts +167 -0
- package/src/media/local-runtime.ts +18 -5
- 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/plugins/context.ts +94 -22
- package/src/plugins/cron.ts +18 -2
- package/src/plugins/routes.ts +40 -1
- package/src/query.ts +304 -18
- package/src/schema/query.ts +11 -4
- package/src/schema/zod-generator.ts +53 -8
- package/src/settings/index.ts +18 -5
- package/src/taxonomies/index.ts +263 -165
- package/src/ui.ts +5 -0
- package/src/virtual-modules.d.ts +24 -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/context-Cm4pt1Ws.mjs.map +0 -1
- package/dist/cron-DdEVrQ2Y.mjs.map +0 -1
- package/dist/index-D2VAiumu.d.mts.map +0 -1
- package/dist/init-lock-DlBHjf9-.mjs.map +0 -1
- package/dist/loader-BqWjcH3h.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/types-BTnnBYVX.d.mts.map +0 -1
- package/dist/types-BXSUSAjt.mjs.map +0 -1
- package/dist/version-BOjj_cfz.mjs +0 -7
- package/dist/zod-generator-CarzgPAu.mjs.map +0 -1
- /package/dist/{api-tokens-C7ywRx7l.mjs → api-tokens-B4BQybOp.mjs} +0 -0
- /package/dist/{ssrf-CRZGzjdL.mjs → ssrf-CcX9zvMK.mjs} +0 -0
- /package/dist/{types-BoRm8-pp.mjs → types-BvbeGEtr.mjs} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object-cache adapter functions (config time).
|
|
3
|
+
*
|
|
4
|
+
* These run in `astro.config.mjs` and return serializable
|
|
5
|
+
* {@link ObjectCacheDescriptor}s. The backend is instantiated at runtime by
|
|
6
|
+
* loading the descriptor's `entrypoint`.
|
|
7
|
+
*
|
|
8
|
+
* For Cloudflare KV, use `kvCache()` from `@emdash-cms/cloudflare`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // astro.config.mjs (Node / local)
|
|
13
|
+
* import emdash, { memoryCache } from "emdash/astro";
|
|
14
|
+
*
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* integrations: [emdash({ objectCache: memoryCache() })],
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { ObjectCacheDescriptor, ObjectCacheRuntimeConfig } from "../../object-cache/types.js";
|
|
22
|
+
|
|
23
|
+
/** Options for {@link memoryCache}. */
|
|
24
|
+
export interface MemoryCacheOptions extends ObjectCacheRuntimeConfig {
|
|
25
|
+
/**
|
|
26
|
+
* Soft cap on the number of cached keys per isolate before FIFO eviction.
|
|
27
|
+
* @default 1000
|
|
28
|
+
*/
|
|
29
|
+
maxEntries?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* In-isolate memory object cache.
|
|
34
|
+
*
|
|
35
|
+
* Caches query results across requests within a single isolate/process. On
|
|
36
|
+
* Node (one long-lived process) this is a genuine cross-request cache; on
|
|
37
|
+
* multi-isolate platforms (Cloudflare) prefer `kvCache()` so the cache is
|
|
38
|
+
* shared. Useful for local development regardless of target.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* emdash({ objectCache: memoryCache({ defaultTtl: 600 }) })
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function memoryCache(options: MemoryCacheOptions = {}): ObjectCacheDescriptor {
|
|
46
|
+
return {
|
|
47
|
+
entrypoint: "emdash/object-cache/memory",
|
|
48
|
+
config: { ...options },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eager, transparent prefetch of site-global "chrome" data.
|
|
3
|
+
*
|
|
4
|
+
* On a public page render, the shared layout pulls the same site-global data on
|
|
5
|
+
* every request -- menus, widget areas, taxonomy term lists, site settings --
|
|
6
|
+
* but each is awaited inside a separately-rendered Astro component, so they
|
|
7
|
+
* execute as serial DB round trips. This fires them all CONCURRENTLY at the
|
|
8
|
+
* very start of the request, before `next()`:
|
|
9
|
+
*
|
|
10
|
+
* - On remote backends (D1, Durable Objects) the round trips overlap instead
|
|
11
|
+
* of serializing, collapsing ~N sequential RTTs into ~1 wall-clock RTT. On
|
|
12
|
+
* a coalescing backend they additionally batch into a single round trip.
|
|
13
|
+
* - The results land in the per-request `requestCached` store under the exact
|
|
14
|
+
* keys the layout helpers use, so when the components render they hit a warm
|
|
15
|
+
* (in-flight or resolved) cache entry instead of issuing their own query.
|
|
16
|
+
*
|
|
17
|
+
* Nothing here changes what templates call -- it warms the real helpers, so the
|
|
18
|
+
* cache keys and value shapes are guaranteed identical. The caller gates this to
|
|
19
|
+
* the public-page path on a request-scoped (remote) backend; it is a no-op-ish
|
|
20
|
+
* waste on synchronous local SQLite, so don't call it there.
|
|
21
|
+
*
|
|
22
|
+
* Fire-and-forget: never awaited by middleware, never throws (a prefetch failure
|
|
23
|
+
* must not affect the request -- the helpers will simply run on demand).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { getDb } from "../loader.js";
|
|
27
|
+
import { getMenu } from "../menus/index.js";
|
|
28
|
+
import { setRequestCacheEntry } from "../request-cache.js";
|
|
29
|
+
import { getSiteSettings } from "../settings/index.js";
|
|
30
|
+
import { getTaxonomyDefs, getTaxonomyTerms } from "../taxonomies/index.js";
|
|
31
|
+
import { getWidgetAreas } from "../widgets/index.js";
|
|
32
|
+
|
|
33
|
+
/** Warm widget areas: one bulk load, primed under each per-area cache key. */
|
|
34
|
+
async function prefetchWidgetAreas(): Promise<void> {
|
|
35
|
+
const areas = await getWidgetAreas();
|
|
36
|
+
// getWidgetArea(name) caches under `widget-area:${name}` and returns the same
|
|
37
|
+
// WidgetArea shape getWidgetAreas yields, so priming here makes those calls hit.
|
|
38
|
+
for (const area of areas) {
|
|
39
|
+
setRequestCacheEntry(`widget-area:${area.name}`, area);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Warm every taxonomy's term list via the real helper (primes per-name keys). */
|
|
44
|
+
async function prefetchTaxonomyTerms(): Promise<void> {
|
|
45
|
+
const defs = await getTaxonomyDefs();
|
|
46
|
+
await Promise.allSettled(defs.map((def) => getTaxonomyTerms(def.name)));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Warm every menu via the real helper (primes `menu:${name}:${locale}`). */
|
|
50
|
+
async function prefetchMenus(): Promise<void> {
|
|
51
|
+
const db = await getDb();
|
|
52
|
+
// The layout calls getMenu(name) with hardcoded names; we can't know them, so
|
|
53
|
+
// discover every menu name and warm them all (small, bounded chrome table).
|
|
54
|
+
const rows = await db.selectFrom("_emdash_menus").select("name").distinct().execute();
|
|
55
|
+
const names = [...new Set(rows.map((r) => r.name))];
|
|
56
|
+
await Promise.allSettled(names.map((name) => getMenu(name)));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Concurrently warm the site-global layout data for the current request.
|
|
61
|
+
* Safe to call only inside the request ALS frame that owns the (remote)
|
|
62
|
+
* request-scoped db. Never throws.
|
|
63
|
+
*/
|
|
64
|
+
export async function prefetchLayoutData(): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
await Promise.allSettled([
|
|
67
|
+
getSiteSettings(),
|
|
68
|
+
prefetchMenus(),
|
|
69
|
+
prefetchWidgetAreas(),
|
|
70
|
+
prefetchTaxonomyTerms(),
|
|
71
|
+
]);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
// Defensive: Promise.allSettled shouldn't reject, but never let a prefetch
|
|
74
|
+
// failure surface to the request.
|
|
75
|
+
console.error("[emdash] layout prefetch failed (non-fatal):", error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
* This page serves the EmDash admin React SPA.
|
|
6
6
|
* AdminWrapper imports plugin admin modules and passes them to AdminApp.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
// `?url` keeps the admin stylesheet out of the page's CSS module graph so
|
|
9
|
+
// Astro's dev SSR doesn't inject it into every public route's <head>. We emit
|
|
10
|
+
// it as a route-scoped <link> below instead. See #1281.
|
|
11
|
+
import adminStylesUrl from "@emdash-cms/admin/styles.css?url";
|
|
9
12
|
// Use package-qualified import so Astro generates a proper module URL
|
|
10
13
|
// (relative imports resolve to absolute paths which break client hydration)
|
|
11
14
|
import AdminWrapper from "emdash/routes/PluginRegistry";
|
|
@@ -28,6 +31,7 @@ const pageTitle = adminConfig?.siteName ? `${adminConfig.siteName} Admin` : "EmD
|
|
|
28
31
|
<head>
|
|
29
32
|
<meta charset="UTF-8" />
|
|
30
33
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
34
|
+
<link rel="stylesheet" href={adminStylesUrl} />
|
|
31
35
|
<Font cssVariable="--font-emdash" />
|
|
32
36
|
{adminConfig?.favicon ? (
|
|
33
37
|
<link rel="icon" href={adminConfig.favicon} />
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public comment reaction endpoints (Tier 1 of the best-in-class comments RFC).
|
|
3
|
+
*
|
|
4
|
+
* GET /_emdash/api/comments/:collection/:contentId/reactions
|
|
5
|
+
* - Aggregate reaction counts for the content's approved comments, plus the
|
|
6
|
+
* current visitor's active reactions.
|
|
7
|
+
* POST /_emdash/api/comments/:collection/:contentId/reactions
|
|
8
|
+
* - Toggle a reaction on a comment. Public, honeypot- and rate-limit-gated.
|
|
9
|
+
*
|
|
10
|
+
* Inherits the `/_emdash/api/comments/` public prefix (no auth); the POST still
|
|
11
|
+
* requires the `X-EmDash-Request: 1` CSRF header like the comment POST.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { APIRoute } from "astro";
|
|
15
|
+
|
|
16
|
+
import { apiError, apiSuccess, handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
17
|
+
import { handleReactionCounts, handleReactionToggle } from "#api/handlers/comment-reactions.js";
|
|
18
|
+
import { hashIp } from "#api/handlers/comments.js";
|
|
19
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
20
|
+
import { createReactionBody } from "#api/schemas.js";
|
|
21
|
+
import { resolveSecretsCached } from "#config/secrets.js";
|
|
22
|
+
import { extractRequestMeta } from "#plugins/request-meta.js";
|
|
23
|
+
|
|
24
|
+
export const prerender = false;
|
|
25
|
+
|
|
26
|
+
export const GET: APIRoute = async ({ params, request, locals }) => {
|
|
27
|
+
const { emdash } = locals;
|
|
28
|
+
const { collection, contentId } = params;
|
|
29
|
+
|
|
30
|
+
if (!collection || !contentId) {
|
|
31
|
+
return apiError("VALIDATION_ERROR", "Collection and content ID required", 400);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const dbErr = requireDb(emdash?.db);
|
|
35
|
+
if (dbErr) return dbErr;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Salted voter hash from request IP (same primitive as comment ip_hash).
|
|
39
|
+
// Behind Cloudflare (CF-Connecting-IP) or a configured trusted proxy this
|
|
40
|
+
// is per-visitor. Without a trusted IP it collapses to a shared "unknown"
|
|
41
|
+
// bucket, so reaction dedup degrades for those visitors — a real
|
|
42
|
+
// per-visitor token is Tier 2 (visitor identity). Operators should set
|
|
43
|
+
// trustedProxyHeaders; see the comment ingest route for the same note.
|
|
44
|
+
const meta = extractRequestMeta(request, emdash.config);
|
|
45
|
+
let voterHash = "unknown";
|
|
46
|
+
if (meta.ip) {
|
|
47
|
+
const { ipSalt } = await resolveSecretsCached(emdash.db);
|
|
48
|
+
voterHash = await hashIp(meta.ip, ipSalt);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const result = await handleReactionCounts(emdash.db, collection, contentId, voterHash);
|
|
52
|
+
return unwrapResult(result);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return handleError(error, "Failed to read reactions", "REACTION_COUNTS_ERROR");
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
59
|
+
const { emdash } = locals;
|
|
60
|
+
const { collection, contentId } = params;
|
|
61
|
+
|
|
62
|
+
if (!collection || !contentId) {
|
|
63
|
+
return apiError("VALIDATION_ERROR", "Collection and content ID required", 400);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const dbErr = requireDb(emdash?.db);
|
|
67
|
+
if (dbErr) return dbErr;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const body = await parseBody(request, createReactionBody);
|
|
71
|
+
if (isParseError(body)) return body;
|
|
72
|
+
|
|
73
|
+
// Anti-spam: honeypot — hidden field filled only by bots. Silently accept.
|
|
74
|
+
if (body.website_url) {
|
|
75
|
+
return apiSuccess({ reacted: false, counts: {} });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const meta = extractRequestMeta(request, emdash.config);
|
|
79
|
+
let voterHash = "unknown";
|
|
80
|
+
if (meta.ip) {
|
|
81
|
+
const { ipSalt } = await resolveSecretsCached(emdash.db);
|
|
82
|
+
voterHash = await hashIp(meta.ip, ipSalt);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const result = await handleReactionToggle(emdash.db, {
|
|
86
|
+
collection,
|
|
87
|
+
contentId,
|
|
88
|
+
commentId: body.commentId,
|
|
89
|
+
reaction: body.reaction,
|
|
90
|
+
voterHash,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return unwrapResult(result, 200);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
return handleError(error, "Failed to toggle reaction", "REACTION_TOGGLE_ERROR");
|
|
96
|
+
}
|
|
97
|
+
};
|
|
@@ -15,7 +15,7 @@ import { hashString } from "emdash";
|
|
|
15
15
|
import { requirePerm } from "#api/authorize.js";
|
|
16
16
|
import { apiSuccess, handleError, requireDb } from "#api/error.js";
|
|
17
17
|
import { SchemaRegistry } from "#schema/registry.js";
|
|
18
|
-
import { generateTypeScript } from "#schema/zod-generator.js";
|
|
18
|
+
import { generateTypeScript, uniqueInterfaceNames } from "#schema/zod-generator.js";
|
|
19
19
|
|
|
20
20
|
export const prerender = false;
|
|
21
21
|
|
|
@@ -45,8 +45,14 @@ export const GET: APIRoute = async ({ request, locals }) => {
|
|
|
45
45
|
const format = url.searchParams.get("format");
|
|
46
46
|
|
|
47
47
|
if (format === "typescript") {
|
|
48
|
-
// Generate TypeScript definitions
|
|
49
|
-
|
|
48
|
+
// Generate TypeScript definitions. Singularizing slugs can collapse
|
|
49
|
+
// distinct collections onto the same interface name, so resolve names
|
|
50
|
+
// up front to keep every emitted interface unique (`book` + `books`
|
|
51
|
+
// would otherwise both emit `Book`).
|
|
52
|
+
const interfaceNames = uniqueInterfaceNames(collectionsWithFields);
|
|
53
|
+
const types = collectionsWithFields
|
|
54
|
+
.map((c) => generateTypeScript(c, interfaceNames.get(c.slug)))
|
|
55
|
+
.join("\n\n");
|
|
50
56
|
|
|
51
57
|
const header = `// Generated by EmDash CLI
|
|
52
58
|
// Do not edit manually - run \`emdash types\` to regenerate
|
|
@@ -23,7 +23,7 @@ import { ulid } from "ulidx";
|
|
|
23
23
|
|
|
24
24
|
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
25
25
|
import { escapeHtml } from "#api/escape.js";
|
|
26
|
-
import { handleApiTokenCreate } from "#api/handlers/api-tokens.js";
|
|
26
|
+
import { deleteApiTokensByName, handleApiTokenCreate } from "#api/handlers/api-tokens.js";
|
|
27
27
|
import { getPublicOrigin } from "#api/public-url.js";
|
|
28
28
|
import { isSafeRedirect } from "#api/redirect.js";
|
|
29
29
|
import { runMigrations } from "#db/migrations/runner.js";
|
|
@@ -134,6 +134,10 @@ async function handleDevBypass(context: Parameters<APIRoute>[0]): Promise<Respon
|
|
|
134
134
|
// Optionally create a PAT token (?token=1) for headless/CLI testing.
|
|
135
135
|
let token: string | undefined;
|
|
136
136
|
if (url.searchParams.has("token")) {
|
|
137
|
+
// Idempotent by name: a prior reset can leave a stale dev-bypass-token,
|
|
138
|
+
// and the raw token is only available at creation, so drop any existing
|
|
139
|
+
// one and mint a fresh, usable PAT rather than accumulating duplicates.
|
|
140
|
+
await deleteApiTokensByName(emdash.db, user.id, "dev-bypass-token");
|
|
137
141
|
const result = await handleApiTokenCreate(emdash.db, user.id, {
|
|
138
142
|
name: "dev-bypass-token",
|
|
139
143
|
scopes: [
|
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
import { getPublicOrigin } from "#api/public-url.js";
|
|
21
21
|
import { resolveSecretsCached } from "#config/secrets.js";
|
|
22
22
|
|
|
23
|
+
import { resolveSessionUser } from "../../session-user.js";
|
|
24
|
+
|
|
23
25
|
export const prerender = false;
|
|
24
26
|
|
|
25
27
|
export const GET: APIRoute = async ({ request, locals, url, session }) => {
|
|
@@ -31,7 +33,7 @@ export const GET: APIRoute = async ({ request, locals, url, session }) => {
|
|
|
31
33
|
if (!user && session && emdash?.db) {
|
|
32
34
|
try {
|
|
33
35
|
const { createKyselyAdapter } = await import("@emdash-cms/auth/adapters/kysely");
|
|
34
|
-
const sessionUser = await session
|
|
36
|
+
const sessionUser = await resolveSessionUser(session);
|
|
35
37
|
if (sessionUser?.id) {
|
|
36
38
|
const adapter = createKyselyAdapter(emdash.db);
|
|
37
39
|
const resolved = await adapter.getUserById(sessionUser.id);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { after } from "../after.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Backstop timeout for resolving the session user. A live session-store read
|
|
5
|
+
* settles in a few ms, so this only ever fires on a genuinely stalled read.
|
|
6
|
+
*/
|
|
7
|
+
export const SESSION_GET_TIMEOUT_MS = 3_000;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the Astro session user without risking an isolate-wide hang.
|
|
11
|
+
*
|
|
12
|
+
* On Cloudflare Workers, a request cancelled mid-`session.get()` (client
|
|
13
|
+
* disconnect, context teardown) can leave the underlying session-store read as
|
|
14
|
+
* a promise that never settles — neither resolving nor rejecting. Awaiting it
|
|
15
|
+
* directly hangs the request, and because the stalled promise is shared at the
|
|
16
|
+
* isolate level, every later session-bearing request hangs too (observed as
|
|
17
|
+
* 0-CPU, multi-minute, `canceled` responses; see #1274). A surrounding
|
|
18
|
+
* try/catch cannot help: the promise never rejects.
|
|
19
|
+
*
|
|
20
|
+
* Two layers, mirroring the reclaimable-cache pattern used elsewhere in core:
|
|
21
|
+
* 1. `after()` anchors the read so a cancelled request still drives it to
|
|
22
|
+
* completion — the promise settles and the isolate is not poisoned for
|
|
23
|
+
* subsequent requests (prevents the hang rather than merely surviving it).
|
|
24
|
+
* 2. A timeout is a fail-closed backstop: a still-stalled (or rejecting) read
|
|
25
|
+
* resolves to `undefined`, and every caller treats the absence of a session
|
|
26
|
+
* user as unauthenticated (anonymous on public routes, 401/redirect on
|
|
27
|
+
* protected ones). It can only ever drop privileges for that one request,
|
|
28
|
+
* never grant them.
|
|
29
|
+
*
|
|
30
|
+
* Used by every session read on the request path: the main middleware (the
|
|
31
|
+
* first read on a session-bearing request), the auth middleware, and the
|
|
32
|
+
* preview-snapshot route (which bypasses the auth middleware).
|
|
33
|
+
*/
|
|
34
|
+
export async function resolveSessionUser<T>(
|
|
35
|
+
session: { get(key: "user"): Promise<T> } | undefined,
|
|
36
|
+
timeoutMs = SESSION_GET_TIMEOUT_MS,
|
|
37
|
+
): Promise<T | undefined> {
|
|
38
|
+
if (!session) return undefined;
|
|
39
|
+
const read: Promise<T | undefined> = Promise.resolve(session.get("user")).catch(() => undefined);
|
|
40
|
+
// Keep the worker alive past response/cancellation so the read completes and
|
|
41
|
+
// the shared promise settles — this is what prevents the isolate poisoning.
|
|
42
|
+
after(() =>
|
|
43
|
+
read.then(
|
|
44
|
+
() => undefined,
|
|
45
|
+
() => undefined,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
49
|
+
const timeout = new Promise<undefined>((resolve) => {
|
|
50
|
+
timer = setTimeout(resolve, timeoutMs, undefined);
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
return await Promise.race([read, timeout]);
|
|
54
|
+
} finally {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/astro/types.ts
CHANGED
|
@@ -153,13 +153,16 @@ export async function exportSeed(db: Kysely<Database>, withContent?: string): Pr
|
|
|
153
153
|
|
|
154
154
|
// 7. Export content (if requested)
|
|
155
155
|
if (withContent !== undefined) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
// Treat "all" as a synonym for the bare flag and "true". The args help
|
|
157
|
+
// text documents `all` as a valid value, but without this the literal
|
|
158
|
+
// string is read as a collection name and matches no collection (#1329).
|
|
159
|
+
const includeAll = withContent === "" || withContent === "true" || withContent === "all";
|
|
160
|
+
const collections = includeAll
|
|
161
|
+
? null // all collections
|
|
162
|
+
: withContent
|
|
163
|
+
.split(",")
|
|
164
|
+
.map((s) => s.trim())
|
|
165
|
+
.filter(Boolean);
|
|
163
166
|
|
|
164
167
|
seed.content = await exportContent(
|
|
165
168
|
db,
|
package/src/comments/query.ts
CHANGED
|
@@ -7,15 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
import type { Kysely } from "kysely";
|
|
9
9
|
|
|
10
|
+
import { CommentReactionRepository } from "../database/repositories/comment-reaction.js";
|
|
10
11
|
import { CommentRepository } from "../database/repositories/comment.js";
|
|
11
12
|
import type { PublicComment } from "../database/repositories/comment.js";
|
|
12
13
|
import type { Database } from "../database/types.js";
|
|
13
14
|
import { getDb } from "../loader.js";
|
|
15
|
+
import { cachedQuery, CacheNamespace } from "../object-cache/index.js";
|
|
16
|
+
import { reactionScore } from "./ranking.js";
|
|
14
17
|
|
|
15
18
|
export interface GetCommentsOptions {
|
|
16
19
|
collection: string;
|
|
17
20
|
contentId: string;
|
|
18
21
|
threaded?: boolean;
|
|
22
|
+
/** Attach aggregate reaction counts to each comment. */
|
|
23
|
+
reactions?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Order of top-level comments. `oldest` (default) preserves the existing
|
|
26
|
+
* chronological display; `best` ranks by Wilson-scored reactions (implies
|
|
27
|
+
* `reactions`). Replies always stay chronological.
|
|
28
|
+
*/
|
|
29
|
+
sort?: "oldest" | "best";
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
export interface GetCommentsResult {
|
|
@@ -38,8 +49,21 @@ export interface GetCommentsResult {
|
|
|
38
49
|
* ```
|
|
39
50
|
*/
|
|
40
51
|
export async function getComments(options: GetCommentsOptions): Promise<GetCommentsResult> {
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
// The result varies by every option getCommentsWithDb branches on, so all of
|
|
53
|
+
// them belong in the key. `best` implies reactions, so normalize the reaction
|
|
54
|
+
// flag — `{ sort: "best" }` and `{ sort: "best", reactions: true }` produce
|
|
55
|
+
// identical output and should share one entry.
|
|
56
|
+
const sort = options.sort ?? "oldest";
|
|
57
|
+
const withReactions = options.reactions || sort === "best";
|
|
58
|
+
const threaded = options.threaded ? "t" : "f";
|
|
59
|
+
return cachedQuery({
|
|
60
|
+
namespace: CacheNamespace.COMMENTS,
|
|
61
|
+
key: `comments:${options.collection}:${options.contentId}:${threaded}:${withReactions ? "r" : "n"}:${sort}`,
|
|
62
|
+
load: async () => {
|
|
63
|
+
const db = await getDb();
|
|
64
|
+
return getCommentsWithDb(db, options);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
/**
|
|
@@ -65,16 +89,63 @@ export async function getCommentsWithDb(
|
|
|
65
89
|
limit: MAX_COMMENTS,
|
|
66
90
|
});
|
|
67
91
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
92
|
+
const items: PublicComment[] = options.threaded
|
|
93
|
+
? CommentRepository.assembleThreads(result.items).map((c) =>
|
|
94
|
+
CommentRepository.toPublicComment(c),
|
|
95
|
+
)
|
|
96
|
+
: result.items.map((c) => CommentRepository.toPublicComment(c));
|
|
97
|
+
|
|
98
|
+
// `best` sort needs reaction data, so it implies reactions.
|
|
99
|
+
if (options.reactions || options.sort === "best") {
|
|
100
|
+
await attachReactions(db, items);
|
|
101
|
+
if (options.sort === "best") {
|
|
102
|
+
sortByBest(items);
|
|
103
|
+
}
|
|
72
104
|
}
|
|
73
105
|
|
|
74
|
-
const items = result.items.map((c) => CommentRepository.toPublicComment(c));
|
|
75
106
|
return { items, total };
|
|
76
107
|
}
|
|
77
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Attach aggregate reaction counts to a list of public comments (and their
|
|
111
|
+
* replies), in a single batched query.
|
|
112
|
+
*/
|
|
113
|
+
async function attachReactions(db: Kysely<Database>, items: PublicComment[]): Promise<void> {
|
|
114
|
+
const ids: string[] = [];
|
|
115
|
+
for (const comment of items) {
|
|
116
|
+
ids.push(comment.id);
|
|
117
|
+
if (comment.replies) {
|
|
118
|
+
for (const reply of comment.replies) ids.push(reply.id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (ids.length === 0) return;
|
|
122
|
+
|
|
123
|
+
const counts = await new CommentReactionRepository(db).countsForComments(ids);
|
|
124
|
+
|
|
125
|
+
const assign = (comment: PublicComment) => {
|
|
126
|
+
const reactions = counts.get(comment.id);
|
|
127
|
+
if (reactions) comment.reactions = reactions;
|
|
128
|
+
};
|
|
129
|
+
for (const comment of items) {
|
|
130
|
+
assign(comment);
|
|
131
|
+
comment.replies?.forEach(assign);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Sort top-level comments by Wilson-scored reactions (descending), tie-broken
|
|
137
|
+
* by oldest-first to keep ordering stable.
|
|
138
|
+
*/
|
|
139
|
+
function sortByBest(items: PublicComment[]): void {
|
|
140
|
+
items.sort((a, b) => {
|
|
141
|
+
const scoreDelta = reactionScore(b.reactions ?? {}) - reactionScore(a.reactions ?? {});
|
|
142
|
+
if (scoreDelta !== 0) return scoreDelta;
|
|
143
|
+
if (a.createdAt < b.createdAt) return -1;
|
|
144
|
+
if (a.createdAt > b.createdAt) return 1;
|
|
145
|
+
return 0;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
78
149
|
/**
|
|
79
150
|
* Get the count of approved comments for a content item.
|
|
80
151
|
*
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comment ranking utilities (Tier 1 of the best-in-class comments RFC).
|
|
3
|
+
*
|
|
4
|
+
* Wilson score lower-bound (95% confidence) — the same primitive Reddit uses
|
|
5
|
+
* for its "Best" comment sort. Ranks by the statistical lower bound of the
|
|
6
|
+
* positive-reaction proportion rather than the raw count, so a comment with a
|
|
7
|
+
* couple of reactions can't outrank a heavily-reacted one until it earns
|
|
8
|
+
* confidence, and a late-but-popular comment still rises (submission time is
|
|
9
|
+
* irrelevant).
|
|
10
|
+
*
|
|
11
|
+
* Positive-only reactions (the recommended default) degrade gracefully: with
|
|
12
|
+
* `down = 0` the score still increases monotonically with `up` while penalising
|
|
13
|
+
* low-sample comments — wilson(1,0) ≈ 0.21, wilson(10,0) ≈ 0.73,
|
|
14
|
+
* wilson(200,0) ≈ 0.98.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** z for a 95% two-sided confidence interval. */
|
|
18
|
+
const DEFAULT_Z = 1.96;
|
|
19
|
+
|
|
20
|
+
/** Reactions that count against a comment when both signals are in use. */
|
|
21
|
+
const NEGATIVE_REACTIONS: ReadonlySet<string> = new Set(["dislike", "down"]);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Wilson score lower bound of the positive proportion.
|
|
25
|
+
*
|
|
26
|
+
* @param up count of positive reactions
|
|
27
|
+
* @param down count of negative reactions
|
|
28
|
+
* @returns a score in [0, 1]; 0 when there are no reactions
|
|
29
|
+
*/
|
|
30
|
+
export function wilsonLowerBound(up: number, down: number, z: number = DEFAULT_Z): number {
|
|
31
|
+
const n = up + down;
|
|
32
|
+
if (n <= 0) return 0;
|
|
33
|
+
const phat = up / n;
|
|
34
|
+
const z2 = z * z;
|
|
35
|
+
const denom = 1 + z2 / n;
|
|
36
|
+
const centre = phat + z2 / (2 * n);
|
|
37
|
+
const margin = z * Math.sqrt((phat * (1 - phat) + z2 / (4 * n)) / n);
|
|
38
|
+
return (centre - margin) / denom;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Reduce a per-reaction count map to a single rank score via the Wilson
|
|
43
|
+
* lower bound. Any reaction not in {@link NEGATIVE_REACTIONS} is treated as
|
|
44
|
+
* positive, so the positive-only default (just `like`) works without special
|
|
45
|
+
* casing.
|
|
46
|
+
*/
|
|
47
|
+
export function reactionScore(counts: Record<string, number>): number {
|
|
48
|
+
let up = 0;
|
|
49
|
+
let down = 0;
|
|
50
|
+
for (const [reaction, count] of Object.entries(counts)) {
|
|
51
|
+
if (NEGATIVE_REACTIONS.has(reaction)) {
|
|
52
|
+
down += count;
|
|
53
|
+
} else {
|
|
54
|
+
up += count;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return wilsonLowerBound(up, down);
|
|
58
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* EmDash custom block override for `astro-portabletext`.
|
|
4
|
+
*
|
|
5
|
+
* Renders the same HTML as the upstream Block component (h1..h6, blockquote,
|
|
6
|
+
* `<p>` for `normal`) and additionally surfaces `textAlign` from the rich-text
|
|
7
|
+
* editor as a WordPress-style `has-text-align-{value}` class on the rendered
|
|
8
|
+
* paragraph or heading.
|
|
9
|
+
*
|
|
10
|
+
* `left` is the editor default and intentionally does not produce a class —
|
|
11
|
+
* paragraphs/headings without explicit alignment render exactly as they did
|
|
12
|
+
* before this fix, so existing content is byte-for-byte unchanged.
|
|
13
|
+
*
|
|
14
|
+
* Related: https://github.com/emdash-cms/emdash/issues/1201
|
|
15
|
+
*/
|
|
16
|
+
import type { BlockProps } from "astro-portabletext/types";
|
|
17
|
+
|
|
18
|
+
import { textAlignClassName } from "./portable-text-text-align.js";
|
|
19
|
+
|
|
20
|
+
type TextAlignedNode = BlockProps["node"] & { textAlign?: string };
|
|
21
|
+
type Props = Omit<BlockProps, "node"> & { node: TextAlignedNode };
|
|
22
|
+
|
|
23
|
+
const props = Astro.props as Props;
|
|
24
|
+
const { node, index: _index, isInline: _isInline, ...attrs } = props;
|
|
25
|
+
|
|
26
|
+
const styleIs = (style: string) => style === node.style;
|
|
27
|
+
|
|
28
|
+
// Allowlist-based; attacker-controlled PT data cannot inject arbitrary classes.
|
|
29
|
+
// See `./portable-text-text-align.ts`.
|
|
30
|
+
const alignClass = textAlignClassName(node.textAlign);
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
{
|
|
34
|
+
styleIs("h1") ? (
|
|
35
|
+
<h1 class={alignClass} {...attrs}>
|
|
36
|
+
<slot />
|
|
37
|
+
</h1>
|
|
38
|
+
) : styleIs("h2") ? (
|
|
39
|
+
<h2 class={alignClass} {...attrs}>
|
|
40
|
+
<slot />
|
|
41
|
+
</h2>
|
|
42
|
+
) : styleIs("h3") ? (
|
|
43
|
+
<h3 class={alignClass} {...attrs}>
|
|
44
|
+
<slot />
|
|
45
|
+
</h3>
|
|
46
|
+
) : styleIs("h4") ? (
|
|
47
|
+
<h4 class={alignClass} {...attrs}>
|
|
48
|
+
<slot />
|
|
49
|
+
</h4>
|
|
50
|
+
) : styleIs("h5") ? (
|
|
51
|
+
<h5 class={alignClass} {...attrs}>
|
|
52
|
+
<slot />
|
|
53
|
+
</h5>
|
|
54
|
+
) : styleIs("h6") ? (
|
|
55
|
+
<h6 class={alignClass} {...attrs}>
|
|
56
|
+
<slot />
|
|
57
|
+
</h6>
|
|
58
|
+
) : styleIs("blockquote") ? (
|
|
59
|
+
<blockquote class={alignClass} {...attrs}>
|
|
60
|
+
<slot />
|
|
61
|
+
</blockquote>
|
|
62
|
+
) : styleIs("normal") ? (
|
|
63
|
+
<p class={alignClass} {...attrs}>
|
|
64
|
+
<slot />
|
|
65
|
+
</p>
|
|
66
|
+
) : (
|
|
67
|
+
<p class={alignClass} {...attrs}>
|
|
68
|
+
<slot />
|
|
69
|
+
</p>
|
|
70
|
+
)
|
|
71
|
+
}
|