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
package/src/emdash-runtime.ts
CHANGED
|
@@ -41,6 +41,8 @@ import type {
|
|
|
41
41
|
PublicPageContext,
|
|
42
42
|
PageMetadataContribution,
|
|
43
43
|
PageFragmentContribution,
|
|
44
|
+
PortableTextBlockConfig,
|
|
45
|
+
FieldWidgetConfig,
|
|
44
46
|
} from "./plugins/types.js";
|
|
45
47
|
import type { FieldType } from "./schema/types.js";
|
|
46
48
|
import { hashString } from "./utils/hash.js";
|
|
@@ -212,6 +214,10 @@ export interface SandboxedPluginEntry {
|
|
|
212
214
|
adminPages?: Array<{ path: string; label?: string; icon?: string }>;
|
|
213
215
|
/** Dashboard widgets */
|
|
214
216
|
adminWidgets?: Array<{ id: string; title?: string; size?: string }>;
|
|
217
|
+
/** Portable Text block types contributed to the editor (declarative Block Kit) */
|
|
218
|
+
portableTextBlocks?: PortableTextBlockConfig[];
|
|
219
|
+
/** Field widget types contributed for schema-field editing UIs */
|
|
220
|
+
fieldWidgets?: FieldWidgetConfig[];
|
|
215
221
|
/** Admin entry module */
|
|
216
222
|
adminEntry?: string;
|
|
217
223
|
/**
|
|
@@ -238,6 +244,15 @@ export interface MediaProviderEntry {
|
|
|
238
244
|
*/
|
|
239
245
|
export interface MediaProviderContext {
|
|
240
246
|
db: Kysely<Database>;
|
|
247
|
+
/**
|
|
248
|
+
* Resolver for the live connection, preferred over `db` by providers that
|
|
249
|
+
* query EmDash's database. Resolves the current request/event-scoped
|
|
250
|
+
* connection from ALS so connection-backed adapters (Postgres over
|
|
251
|
+
* Hyperdrive) don't reuse the per-isolate singleton's socket across events.
|
|
252
|
+
* Providers should resolve per operation rather than capturing `db` once.
|
|
253
|
+
* Omitted-safe: falls back to `db` for stateless adapters (D1, Node SQLite).
|
|
254
|
+
*/
|
|
255
|
+
getDb?: () => Kysely<Database>;
|
|
241
256
|
storage: Storage | null;
|
|
242
257
|
}
|
|
243
258
|
|
|
@@ -256,6 +271,16 @@ export interface RuntimeDependencies {
|
|
|
256
271
|
plugins: ResolvedPlugin[];
|
|
257
272
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
273
|
createDialect: (config: any) => Dialect;
|
|
274
|
+
/**
|
|
275
|
+
* Factory for a dialect that batches same-turn reads into one round trip
|
|
276
|
+
* ({@link EmDashRuntime.create} uses it for the cold-start read phase).
|
|
277
|
+
* Present only on batching backends (D1, DO); absent backends fall back to
|
|
278
|
+
* the singleton. Returns a fresh connection each call — it must never be the
|
|
279
|
+
* long-lived singleton, whose coalescing buffer would be shared across
|
|
280
|
+
* requests.
|
|
281
|
+
*/
|
|
282
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
283
|
+
createCoalescingDialect?: (config: any) => Dialect | null;
|
|
259
284
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
260
285
|
createStorage: ((config: any) => Storage) | null;
|
|
261
286
|
sandboxEnabled: boolean;
|
|
@@ -317,6 +342,7 @@ export interface EmDashRuntimeParts {
|
|
|
317
342
|
allPipelinePlugins: ResolvedPlugin[];
|
|
318
343
|
pipelineFactoryOptions: {
|
|
319
344
|
db: Kysely<Database>;
|
|
345
|
+
getDb?: () => Kysely<Database>;
|
|
320
346
|
storage?: Storage;
|
|
321
347
|
siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
|
|
322
348
|
};
|
|
@@ -364,6 +390,28 @@ function getDbHolder(): DbHolder {
|
|
|
364
390
|
}
|
|
365
391
|
return holder;
|
|
366
392
|
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Auto-seed runs at most once per isolate per database. Its lock + "done" set
|
|
396
|
+
* live on globalThis (same bundler-duplication reasoning as the db cache) so a
|
|
397
|
+
* reclaimed-and-rerun `create()` can't seed a second time concurrently. The
|
|
398
|
+
* lock polls rather than sharing a promise, so it is safe to await across a
|
|
399
|
+
* cancelled owner in workerd.
|
|
400
|
+
*/
|
|
401
|
+
const SEED_HOLDER_KEY = Symbol.for("emdash:seed-state");
|
|
402
|
+
interface SeedHolder {
|
|
403
|
+
done: Set<string>;
|
|
404
|
+
lock: InitLock;
|
|
405
|
+
}
|
|
406
|
+
function getSeedHolder(): SeedHolder {
|
|
407
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot, written only below
|
|
408
|
+
let holder = globalSymbolStore[SEED_HOLDER_KEY] as SeedHolder | undefined;
|
|
409
|
+
if (!holder) {
|
|
410
|
+
holder = { done: new Set<string>(), lock: createInitLock() };
|
|
411
|
+
globalSymbolStore[SEED_HOLDER_KEY] = holder;
|
|
412
|
+
}
|
|
413
|
+
return holder;
|
|
414
|
+
}
|
|
367
415
|
const storageCache = new Map<string, Storage>();
|
|
368
416
|
const sandboxedPluginCache = new Map<string, SandboxedPluginInstance>();
|
|
369
417
|
/**
|
|
@@ -384,7 +432,10 @@ const marketplaceManifestCache = new Map<
|
|
|
384
432
|
{
|
|
385
433
|
id: string;
|
|
386
434
|
version: string;
|
|
387
|
-
admin?: {
|
|
435
|
+
admin?: {
|
|
436
|
+
pages?: PluginAdminPage[];
|
|
437
|
+
widgets?: PluginDashboardWidget[];
|
|
438
|
+
};
|
|
388
439
|
}
|
|
389
440
|
>();
|
|
390
441
|
/** Route metadata for sandboxed plugins: pluginId -> routeName -> RouteMeta */
|
|
@@ -405,7 +456,20 @@ export class EmDashRuntime {
|
|
|
405
456
|
readonly configuredPlugins: ResolvedPlugin[];
|
|
406
457
|
readonly sandboxedPlugins: Map<string, SandboxedPluginInstance>;
|
|
407
458
|
readonly sandboxedPluginEntries: SandboxedPluginEntry[];
|
|
408
|
-
|
|
459
|
+
/**
|
|
460
|
+
* Schema registry bound to the current request/event-scoped connection.
|
|
461
|
+
* Built per access (SchemaRegistry just wraps a db) against `this.db`, the
|
|
462
|
+
* ALS-aware getter — never a captured snapshot of the singleton. On a
|
|
463
|
+
* connection-backed adapter (Postgres over Hyperdrive) a captured singleton
|
|
464
|
+
* would query a socket opened by an earlier event and trip workerd's
|
|
465
|
+
* cross-request I/O guard; the catch in handlers like handleContentUpdate
|
|
466
|
+
* would then silently treat a revision-enabled collection as non-revisioned
|
|
467
|
+
* and write draft edits to live columns. Same reasoning as the per-call
|
|
468
|
+
* registry in _buildManifest().
|
|
469
|
+
*/
|
|
470
|
+
get schemaRegistry(): SchemaRegistry {
|
|
471
|
+
return new SchemaRegistry(this.db);
|
|
472
|
+
}
|
|
409
473
|
private _hooks!: HookPipeline;
|
|
410
474
|
readonly config: EmDashConfig;
|
|
411
475
|
readonly mediaProviders: Map<string, MediaProvider>;
|
|
@@ -436,6 +500,7 @@ export class EmDashRuntime {
|
|
|
436
500
|
/** Factory options for the hook pipeline context factory */
|
|
437
501
|
private pipelineFactoryOptions: {
|
|
438
502
|
db: Kysely<Database>;
|
|
503
|
+
getDb?: () => Kysely<Database>;
|
|
439
504
|
storage?: Storage;
|
|
440
505
|
siteInfo?: { siteName?: string; siteUrl?: string; locale?: string };
|
|
441
506
|
};
|
|
@@ -466,7 +531,6 @@ export class EmDashRuntime {
|
|
|
466
531
|
this.configuredPlugins = parts.configuredPlugins;
|
|
467
532
|
this.sandboxedPlugins = parts.sandboxedPlugins;
|
|
468
533
|
this.sandboxedPluginEntries = parts.sandboxedPluginEntries;
|
|
469
|
-
this.schemaRegistry = new SchemaRegistry(parts.db);
|
|
470
534
|
this._hooks = parts.hooks;
|
|
471
535
|
this.enabledPlugins = parts.enabledPlugins;
|
|
472
536
|
this.pluginStates = parts.pluginStates;
|
|
@@ -612,7 +676,9 @@ export class EmDashRuntime {
|
|
|
612
676
|
// The old pipeline's contextFactoryOptions were built up incrementally
|
|
613
677
|
// via setContextFactory calls during create(). We replay them here.
|
|
614
678
|
if (this.email) {
|
|
615
|
-
|
|
679
|
+
// db/getDb are already wired by createHookPipeline above (they live in
|
|
680
|
+
// pipelineFactoryOptions), so the merge only adds emailPipeline.
|
|
681
|
+
newPipeline.setContextFactory({ emailPipeline: this.email });
|
|
616
682
|
}
|
|
617
683
|
if (this.cronScheduler) {
|
|
618
684
|
const scheduler = this.cronScheduler;
|
|
@@ -976,6 +1042,22 @@ export class EmDashRuntime {
|
|
|
976
1042
|
// Initialize database (connects, runs migrations if needed)
|
|
977
1043
|
const db = await phase("rt.db", "DB init + migrations", () => EmDashRuntime.getDatabase(deps));
|
|
978
1044
|
|
|
1045
|
+
// Resolver for the live connection, mirroring the `get db()` getter
|
|
1046
|
+
// below (which can't be used here — the runtime instance doesn't exist
|
|
1047
|
+
// yet). Long-lived subsystems built during create() (cron executor,
|
|
1048
|
+
// plugin context factory, media providers) capture this resolver rather
|
|
1049
|
+
// than the `db` snapshot, so a connection-backed adapter (Postgres over
|
|
1050
|
+
// Hyperdrive) serves their queries from the current request/event-scoped
|
|
1051
|
+
// connection in ALS instead of the per-isolate singleton — whose socket
|
|
1052
|
+
// belongs to an earlier request and would trip workerd's cross-request
|
|
1053
|
+
// I/O guard. Stateless adapters (D1, Node SQLite) set no ALS db on most
|
|
1054
|
+
// paths, so this falls back to the singleton: unchanged behavior.
|
|
1055
|
+
const resolveDb = (): Kysely<Database> => {
|
|
1056
|
+
const ctx = getRequestContext();
|
|
1057
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- ALS db is typed unknown to avoid a circular import; middleware always sets a Kysely<Database>
|
|
1058
|
+
return (ctx?.db as Kysely<Database> | undefined) ?? db;
|
|
1059
|
+
};
|
|
1060
|
+
|
|
979
1061
|
// Validate EMDASH_ENCRYPTION_KEY once here so a malformed value
|
|
980
1062
|
// surfaces in startup logs instead of as request-time 500s. The key
|
|
981
1063
|
// itself is not yet consumed (a follow-up PR adds plugin-secret
|
|
@@ -989,47 +1071,156 @@ export class EmDashRuntime {
|
|
|
989
1071
|
// Initialize storage (sync)
|
|
990
1072
|
const storage = EmDashRuntime.getStorage(deps);
|
|
991
1073
|
|
|
992
|
-
// Fetch plugin states and site info concurrently — independent reads
|
|
993
|
-
// against different tables (_plugin_state vs options), so they share
|
|
994
|
-
// one round-trip window instead of paying two sequential ones. Each
|
|
995
|
-
// phase() wrapper still records that phase's own duration, and each
|
|
996
|
-
// body keeps its own non-fatal catch.
|
|
997
1074
|
let pluginStates: Map<string, string> = new Map();
|
|
998
1075
|
let siteInfo: { siteName?: string; siteUrl?: string; locale?: string } | undefined;
|
|
999
|
-
|
|
1000
|
-
|
|
1076
|
+
// "Already set up" by default so a read failure (e.g. tables absent on a
|
|
1077
|
+
// pre-migration db) skips seeding rather than seeding a half-built db.
|
|
1078
|
+
let seedGate = { collectionCount: 1, setupDone: true };
|
|
1079
|
+
|
|
1080
|
+
// Seeding must only touch the configured singleton, never a borrowed
|
|
1081
|
+
// per-request db (playground / DO preview) or the loader-fallback db.
|
|
1082
|
+
const reqCtx = getRequestContext();
|
|
1083
|
+
const ownsConfiguredDb = !!deps.config.database && !(reqCtx?.dbIsIsolated && reqCtx.db);
|
|
1084
|
+
|
|
1085
|
+
// Run the init reads on a coalescing connection so the concurrent
|
|
1086
|
+
// same-turn reads flush as one batch() round trip. The singleton can't:
|
|
1087
|
+
// its plain SqliteAdapter reports supportsMultipleConnections=false, so
|
|
1088
|
+
// Kysely's connection mutex serializes concurrent reads into N round
|
|
1089
|
+
// trips. The connection is per-init and discarded — the long-lived
|
|
1090
|
+
// singleton must never coalesce or one request's reads could land in
|
|
1091
|
+
// another's batch. Backends without a coalescing dialect (Node/SQLite)
|
|
1092
|
+
// fall back to the singleton, where serialization costs nothing.
|
|
1093
|
+
let readDb = db;
|
|
1094
|
+
let readDbDisposable: Kysely<Database> | undefined;
|
|
1095
|
+
if (ownsConfiguredDb && deps.createCoalescingDialect && deps.config.database) {
|
|
1096
|
+
try {
|
|
1097
|
+
const dialect = deps.createCoalescingDialect(deps.config.database.config);
|
|
1098
|
+
if (dialect) {
|
|
1099
|
+
readDb = new Kysely<Database>({ dialect, log: kyselyLogOption() });
|
|
1100
|
+
readDbDisposable = readDb;
|
|
1101
|
+
}
|
|
1102
|
+
} catch {
|
|
1103
|
+
readDb = db;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
const optionsRepo = new OptionsRepository(readDb);
|
|
1107
|
+
|
|
1108
|
+
const readSiteInfo = async () => {
|
|
1109
|
+
const siteOpts = await optionsRepo.getMany<string>([
|
|
1110
|
+
"emdash:site_title",
|
|
1111
|
+
"emdash:site_url",
|
|
1112
|
+
"emdash:locale",
|
|
1113
|
+
]);
|
|
1114
|
+
return {
|
|
1115
|
+
siteName: siteOpts.get("emdash:site_title") ?? undefined,
|
|
1116
|
+
siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
|
|
1117
|
+
locale: siteOpts.get("emdash:locale") ?? undefined,
|
|
1118
|
+
};
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1121
|
+
const coldStartReads: Array<Promise<void>> = [
|
|
1001
1122
|
phase("rt.plugins", "Plugin states", async () => {
|
|
1002
1123
|
try {
|
|
1003
|
-
const states = await
|
|
1124
|
+
const states = await readDb
|
|
1004
1125
|
.selectFrom("_plugin_state")
|
|
1005
1126
|
.select(["plugin_id", "status"])
|
|
1006
1127
|
.execute();
|
|
1007
1128
|
pluginStates = new Map(states.map((s) => [s.plugin_id, s.status]));
|
|
1008
1129
|
} catch {
|
|
1009
|
-
//
|
|
1130
|
+
// _plugin_state may not exist yet on a pre-migration db.
|
|
1010
1131
|
}
|
|
1011
1132
|
}),
|
|
1012
|
-
// Load site info for plugin context extensions (1 batch query instead of 3)
|
|
1013
1133
|
phase("rt.site", "Site info options", async () => {
|
|
1014
1134
|
try {
|
|
1015
|
-
|
|
1016
|
-
const siteOpts = await optionsRepo.getMany<string>([
|
|
1017
|
-
"emdash:site_title",
|
|
1018
|
-
"emdash:site_url",
|
|
1019
|
-
"emdash:locale",
|
|
1020
|
-
]);
|
|
1021
|
-
siteInfo = {
|
|
1022
|
-
siteName: siteOpts.get("emdash:site_title") ?? undefined,
|
|
1023
|
-
siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
|
|
1024
|
-
locale: siteOpts.get("emdash:locale") ?? undefined,
|
|
1025
|
-
};
|
|
1135
|
+
siteInfo = await readSiteInfo();
|
|
1026
1136
|
} catch {
|
|
1027
|
-
//
|
|
1137
|
+
// options may not exist yet on a pre-migration db.
|
|
1028
1138
|
}
|
|
1029
1139
|
}),
|
|
1030
|
-
]
|
|
1140
|
+
];
|
|
1141
|
+
|
|
1142
|
+
if (ownsConfiguredDb) {
|
|
1143
|
+
coldStartReads.push(
|
|
1144
|
+
phase("rt.seedcheck", "Auto-seed gate", async () => {
|
|
1145
|
+
try {
|
|
1146
|
+
const [collectionCount, setupOption] = await Promise.all([
|
|
1147
|
+
readDb
|
|
1148
|
+
.selectFrom("_emdash_collections")
|
|
1149
|
+
.select((eb) => eb.fn.countAll<number>().as("count"))
|
|
1150
|
+
.executeTakeFirstOrThrow(),
|
|
1151
|
+
readDb
|
|
1152
|
+
.selectFrom("options")
|
|
1153
|
+
.select("value")
|
|
1154
|
+
.where("name", "=", "emdash:setup_complete")
|
|
1155
|
+
.executeTakeFirst(),
|
|
1156
|
+
]);
|
|
1157
|
+
const setupDone = (() => {
|
|
1158
|
+
try {
|
|
1159
|
+
return !!setupOption && JSON.parse(setupOption.value) === true;
|
|
1160
|
+
} catch {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
})();
|
|
1164
|
+
seedGate = { collectionCount: collectionCount.count, setupDone };
|
|
1165
|
+
} catch {
|
|
1166
|
+
// Leave the "already set up" default so a read failure never
|
|
1167
|
+
// triggers a seed onto a half-built db.
|
|
1168
|
+
}
|
|
1169
|
+
}),
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
await Promise.all(coldStartReads);
|
|
1174
|
+
|
|
1175
|
+
// Auto-seed the default schema for a first load that skipped the setup
|
|
1176
|
+
// wizard (the wizard and dev-bypass apply seeds explicitly). Run under a
|
|
1177
|
+
// per-isolate lock keyed by the configured db so a reclaimed-and-rerun
|
|
1178
|
+
// create() can't apply the seed a second time concurrently.
|
|
1179
|
+
if (seedGate.collectionCount === 0 && !seedGate.setupDone) {
|
|
1180
|
+
const seedKey = deps.config.database?.entrypoint ?? "default";
|
|
1181
|
+
const seedHolder = getSeedHolder();
|
|
1182
|
+
try {
|
|
1183
|
+
await initWithLock(
|
|
1184
|
+
seedHolder.lock,
|
|
1185
|
+
() => (seedHolder.done.has(seedKey) ? true : undefined),
|
|
1186
|
+
async () => {
|
|
1187
|
+
const { applySeed } = await import("./seed/apply.js");
|
|
1188
|
+
const { loadSeed } = await import("./seed/load.js");
|
|
1189
|
+
const { validateSeed } = await import("./seed/validate.js");
|
|
1190
|
+
|
|
1191
|
+
const seed = await loadSeed();
|
|
1192
|
+
const validation = validateSeed(seed);
|
|
1193
|
+
if (validation.valid) {
|
|
1194
|
+
await applySeed(db, seed, { onConflict: "skip" });
|
|
1195
|
+
console.log("Auto-seeded default collections");
|
|
1196
|
+
}
|
|
1197
|
+
seedHolder.done.add(seedKey);
|
|
1198
|
+
return true;
|
|
1199
|
+
},
|
|
1200
|
+
{ deadlineMs: DB_INIT_DEADLINE_MS, anchor: (promise) => after(() => promise) },
|
|
1201
|
+
);
|
|
1202
|
+
// The site-info read ran before the seed wrote its defaults, so
|
|
1203
|
+
// refresh the snapshot the plugin context sees.
|
|
1204
|
+
try {
|
|
1205
|
+
siteInfo = await readSiteInfo();
|
|
1206
|
+
} catch {
|
|
1207
|
+
// Non-fatal — plugin context falls back to undefined fields.
|
|
1208
|
+
}
|
|
1209
|
+
} catch {
|
|
1210
|
+
// Non-fatal — a failed seed (e.g. missing seed module) leaves the
|
|
1211
|
+
// site un-seeded; a later request retries.
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
// The read connection is single-use; everything below uses the singleton.
|
|
1216
|
+
if (readDbDisposable) {
|
|
1217
|
+
try {
|
|
1218
|
+
await readDbDisposable.destroy();
|
|
1219
|
+
} catch {
|
|
1220
|
+
// Non-fatal — the underlying binding is shared and needs no teardown.
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1031
1223
|
|
|
1032
|
-
// Build set of enabled plugins
|
|
1033
1224
|
const enabledPlugins = new Set<string>();
|
|
1034
1225
|
for (const plugin of deps.plugins) {
|
|
1035
1226
|
const status = pluginStates.get(plugin.id);
|
|
@@ -1145,9 +1336,15 @@ export class EmDashRuntime {
|
|
|
1145
1336
|
// Filter to currently enabled plugins for the initial pipeline
|
|
1146
1337
|
const enabledPluginList = allPipelinePlugins.filter((p) => enabledPlugins.has(p.id));
|
|
1147
1338
|
|
|
1148
|
-
// Create hook pipeline
|
|
1339
|
+
// Create hook pipeline. getDb travels here (not just via the email
|
|
1340
|
+
// setContextFactory call below) so it survives rebuildHookPipeline(),
|
|
1341
|
+
// which reconstructs the factory from pipelineFactoryOptions. Without it,
|
|
1342
|
+
// toggling a plugin on an email-less deployment would silently revert
|
|
1343
|
+
// plugin contexts to the singleton db — re-breaking connection-backed
|
|
1344
|
+
// adapters. See #1622.
|
|
1149
1345
|
const pipelineFactoryOptions = {
|
|
1150
1346
|
db,
|
|
1347
|
+
getDb: resolveDb,
|
|
1151
1348
|
storage: storage ?? undefined,
|
|
1152
1349
|
siteInfo,
|
|
1153
1350
|
};
|
|
@@ -1199,7 +1396,7 @@ export class EmDashRuntime {
|
|
|
1199
1396
|
// Initialize media providers
|
|
1200
1397
|
const mediaProviders = new Map<string, MediaProvider>();
|
|
1201
1398
|
const mediaProviderEntries = deps.mediaProviderEntries ?? [];
|
|
1202
|
-
const providerContext: MediaProviderContext = { db, storage };
|
|
1399
|
+
const providerContext: MediaProviderContext = { db, storage, getDb: resolveDb };
|
|
1203
1400
|
|
|
1204
1401
|
for (const entry of mediaProviderEntries) {
|
|
1205
1402
|
try {
|
|
@@ -1240,8 +1437,10 @@ export class EmDashRuntime {
|
|
|
1240
1437
|
};
|
|
1241
1438
|
|
|
1242
1439
|
// Wire email pipeline into context factory (independent of cron —
|
|
1243
|
-
// must not be inside the cron try/catch or ctx.email breaks when cron fails)
|
|
1244
|
-
|
|
1440
|
+
// must not be inside the cron try/catch or ctx.email breaks when cron fails).
|
|
1441
|
+
// db/getDb were already set via pipelineFactoryOptions above; merge only
|
|
1442
|
+
// adds emailPipeline.
|
|
1443
|
+
pipeline.setContextFactory({ emailPipeline });
|
|
1245
1444
|
|
|
1246
1445
|
let cronExecutor: CronExecutor | null = null;
|
|
1247
1446
|
let cronScheduler: CronScheduler | null = null;
|
|
@@ -1253,7 +1452,7 @@ export class EmDashRuntime {
|
|
|
1253
1452
|
|
|
1254
1453
|
await phase("rt.cron", "Cron init (recovery deferred post-response)", async () => {
|
|
1255
1454
|
try {
|
|
1256
|
-
cronExecutor = new CronExecutor(
|
|
1455
|
+
cronExecutor = new CronExecutor(resolveDb, invokeCronHook);
|
|
1257
1456
|
|
|
1258
1457
|
// Recover stale locks from previous crashes. Pure bookkeeping
|
|
1259
1458
|
// against the _emdash_cron_tasks table — no request needs the
|
|
@@ -1435,45 +1634,9 @@ export class EmDashRuntime {
|
|
|
1435
1634
|
// cleanup-flag check costs an extra `options.get()` on every
|
|
1436
1635
|
// isolate cold boot forever. Cheaper to leave it.
|
|
1437
1636
|
|
|
1438
|
-
//
|
|
1439
|
-
//
|
|
1440
|
-
//
|
|
1441
|
-
try {
|
|
1442
|
-
const [collectionCount, setupOption] = await Promise.all([
|
|
1443
|
-
db
|
|
1444
|
-
.selectFrom("_emdash_collections")
|
|
1445
|
-
.select((eb) => eb.fn.countAll<number>().as("count"))
|
|
1446
|
-
.executeTakeFirstOrThrow(),
|
|
1447
|
-
db
|
|
1448
|
-
.selectFrom("options")
|
|
1449
|
-
.select("value")
|
|
1450
|
-
.where("name", "=", "emdash:setup_complete")
|
|
1451
|
-
.executeTakeFirst(),
|
|
1452
|
-
]);
|
|
1453
|
-
|
|
1454
|
-
const setupDone = (() => {
|
|
1455
|
-
try {
|
|
1456
|
-
return setupOption && JSON.parse(setupOption.value) === true;
|
|
1457
|
-
} catch {
|
|
1458
|
-
return false;
|
|
1459
|
-
}
|
|
1460
|
-
})();
|
|
1461
|
-
|
|
1462
|
-
if (collectionCount.count === 0 && !setupDone) {
|
|
1463
|
-
const { applySeed } = await import("./seed/apply.js");
|
|
1464
|
-
const { loadSeed } = await import("./seed/load.js");
|
|
1465
|
-
const { validateSeed } = await import("./seed/validate.js");
|
|
1466
|
-
|
|
1467
|
-
const seed = await loadSeed();
|
|
1468
|
-
const validation = validateSeed(seed);
|
|
1469
|
-
if (validation.valid) {
|
|
1470
|
-
await applySeed(db, seed, { onConflict: "skip" });
|
|
1471
|
-
console.log("Auto-seeded default collections");
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
} catch {
|
|
1475
|
-
// Tables may not exist yet. Non-fatal.
|
|
1476
|
-
}
|
|
1637
|
+
// This returns a migrated but possibly unseeded db; create() runs
|
|
1638
|
+
// the seed gate and applies the seed, batched with its other init
|
|
1639
|
+
// reads.
|
|
1477
1640
|
|
|
1478
1641
|
// Publish only while still the current owner: a reclaimed slow
|
|
1479
1642
|
// init must not flip the cached Kysely identity back after the
|
|
@@ -1570,6 +1733,8 @@ export class EmDashRuntime {
|
|
|
1570
1733
|
storage: entry.storage as never,
|
|
1571
1734
|
adminPages,
|
|
1572
1735
|
adminWidgets,
|
|
1736
|
+
portableTextBlocks: entry.portableTextBlocks,
|
|
1737
|
+
fieldWidgets: entry.fieldWidgets,
|
|
1573
1738
|
});
|
|
1574
1739
|
plugins.push(resolved);
|
|
1575
1740
|
console.log(
|
|
@@ -2096,9 +2261,6 @@ export class EmDashRuntime {
|
|
|
2096
2261
|
}
|
|
2097
2262
|
|
|
2098
2263
|
// Add sandboxed plugins (use entries for admin config)
|
|
2099
|
-
// TODO: sandboxed plugins need fieldWidgets extracted from their manifest
|
|
2100
|
-
// to support Block Kit field widgets. Currently only trusted plugins carry
|
|
2101
|
-
// fieldWidgets through the admin.fieldWidgets path.
|
|
2102
2264
|
for (const entry of this.sandboxedPluginEntries) {
|
|
2103
2265
|
const status = this.pluginStates.get(entry.id);
|
|
2104
2266
|
const enabled = status === undefined || status === "active";
|
|
@@ -2110,9 +2272,15 @@ export class EmDashRuntime {
|
|
|
2110
2272
|
version: entry.version,
|
|
2111
2273
|
enabled,
|
|
2112
2274
|
sandboxed: true,
|
|
2275
|
+
// `adminMode` reflects only admin pages/widgets. A plugin can
|
|
2276
|
+
// contribute portableTextBlocks/fieldWidgets with adminMode "none" —
|
|
2277
|
+
// the admin reads those from the manifest regardless, so don't gate
|
|
2278
|
+
// admin contributions on `adminMode`.
|
|
2113
2279
|
adminMode: hasAdminPages || hasWidgets ? "blocks" : "none",
|
|
2114
2280
|
adminPages: entry.adminPages ?? [],
|
|
2115
2281
|
dashboardWidgets: entry.adminWidgets ?? [],
|
|
2282
|
+
portableTextBlocks: entry.portableTextBlocks,
|
|
2283
|
+
fieldWidgets: entry.fieldWidgets,
|
|
2116
2284
|
};
|
|
2117
2285
|
}
|
|
2118
2286
|
|
|
@@ -2951,6 +3119,7 @@ export class EmDashRuntime {
|
|
|
2951
3119
|
if (trustedPlugin && this.enabledPlugins.has(trustedPlugin.id)) {
|
|
2952
3120
|
const routeRegistry = new PluginRouteRegistry({
|
|
2953
3121
|
db: this.db,
|
|
3122
|
+
storage: this.storage ?? undefined,
|
|
2954
3123
|
emailPipeline: this.email ?? undefined,
|
|
2955
3124
|
trustedProxyHeaders: getTrustedProxyHeaders(this.config),
|
|
2956
3125
|
});
|
package/src/index.ts
CHANGED
|
@@ -192,6 +192,28 @@ export type {
|
|
|
192
192
|
} from "./storage/types.js";
|
|
193
193
|
export { EmDashStorageError } from "./storage/types.js";
|
|
194
194
|
|
|
195
|
+
// Object cache (distributed read-through query cache)
|
|
196
|
+
export {
|
|
197
|
+
cachedQuery,
|
|
198
|
+
invalidateObjectCache,
|
|
199
|
+
invalidateCollectionCache,
|
|
200
|
+
invalidateTaxonomyObjectCache,
|
|
201
|
+
invalidateBylineObjectCache,
|
|
202
|
+
invalidateMenuObjectCache,
|
|
203
|
+
invalidateSchemaObjectCache,
|
|
204
|
+
invalidateCommentObjectCache,
|
|
205
|
+
contentNamespace,
|
|
206
|
+
contentNamespaces,
|
|
207
|
+
CacheNamespace,
|
|
208
|
+
} from "./object-cache/index.js";
|
|
209
|
+
export type { CachedQueryOptions } from "./object-cache/index.js";
|
|
210
|
+
export type {
|
|
211
|
+
ObjectCacheBackend,
|
|
212
|
+
ObjectCacheDescriptor,
|
|
213
|
+
ObjectCacheRuntimeConfig,
|
|
214
|
+
CreateObjectCacheBackendFn,
|
|
215
|
+
} from "./object-cache/types.js";
|
|
216
|
+
|
|
195
217
|
// Plugin system
|
|
196
218
|
export {
|
|
197
219
|
definePlugin,
|
package/src/loader.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { LiveLoader } from "astro/loaders";
|
|
15
|
-
import { Kysely, sql, type Dialect } from "kysely";
|
|
15
|
+
import { Kysely, type RawBuilder, sql, type Dialect } from "kysely";
|
|
16
16
|
|
|
17
17
|
import { currentTimestampValue, isPostgres } from "./database/dialect-helpers.js";
|
|
18
18
|
import { kyselyLogOption } from "./database/instrumentation.js";
|
|
@@ -72,8 +72,83 @@ const SYSTEM_COLUMNS = new Set([
|
|
|
72
72
|
// fields. The aliases are _emdash_-prefixed so they can't shadow a user
|
|
73
73
|
// field named e.g. `seo_title`.
|
|
74
74
|
...SEO_ALIAS_COLUMNS,
|
|
75
|
+
// Folded hydration JSON columns (see foldedHydrationSelects) — surfaced via
|
|
76
|
+
// the FOLDED_* markers, never as flat fields.
|
|
77
|
+
"_emdash_terms",
|
|
78
|
+
"_emdash_bylines",
|
|
75
79
|
]);
|
|
76
80
|
|
|
81
|
+
/** Markers for byline/taxonomy hydration folded into the content query. */
|
|
82
|
+
export const FOLDED_TERMS = Symbol.for("emdash:foldedTerms");
|
|
83
|
+
export const FOLDED_BYLINES = Symbol.for("emdash:foldedBylines");
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Correlated JSON-array subqueries that fold taxonomy-term and byline hydration
|
|
87
|
+
* into the content query, removing the two separate hydration round trips per
|
|
88
|
+
* fetch. `outer` is the content table's alias/name; each subquery correlates on
|
|
89
|
+
* `<outer>.id`, so the base query stays one row per entry (no join fan-out, no
|
|
90
|
+
* duplicated content payload). Order is NOT applied in the aggregate (it differs
|
|
91
|
+
* across dialects) — the consumer sorts terms by label and credits by sortOrder.
|
|
92
|
+
*
|
|
93
|
+
* Dialect-specific aggregation: SQLite `json_group_array`/`json_object` returns
|
|
94
|
+
* a JSON *string*; Postgres `json_agg`/`json_build_object` (coalesced to `[]`)
|
|
95
|
+
* returns parsed JSON. {@link stashFolded} handles both.
|
|
96
|
+
*/
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any Kysely instance
|
|
98
|
+
function foldedHydrationSelects(db: Kysely<any>, type: string, outer: string) {
|
|
99
|
+
const o = sql.ref(outer);
|
|
100
|
+
const pg = isPostgres(db);
|
|
101
|
+
const obj = (pairs: string) =>
|
|
102
|
+
pg ? sql.raw(`json_build_object(${pairs})`) : sql.raw(`json_object(${pairs})`);
|
|
103
|
+
const agg = (inner: RawBuilder<unknown>) =>
|
|
104
|
+
pg ? sql`coalesce(json_agg(${inner}), '[]'::json)` : sql`json_group_array(${inner})`;
|
|
105
|
+
|
|
106
|
+
const termObj = obj(
|
|
107
|
+
"'id', t.id, 'name', t.name, 'slug', t.slug, 'label', t.label, 'parent_id', t.parent_id, 'locale', t.locale, 'translation_group', t.translation_group",
|
|
108
|
+
);
|
|
109
|
+
// Filter terms to the entry's own locale (matches #1441: terms render in the
|
|
110
|
+
// entry's resolved locale, not all locale variants of the attached group).
|
|
111
|
+
const terms = sql`(SELECT ${agg(termObj)} FROM ${sql.ref("content_taxonomies")} AS ct JOIN ${sql.ref("taxonomies")} AS t ON t.translation_group = ct.taxonomy_id WHERE ct.collection = ${type} AND ct.entry_id = ${o}.id AND t.locale = ${o}.locale) AS ${sql.ref("_emdash_terms")}`;
|
|
112
|
+
|
|
113
|
+
const bylineInner = obj(
|
|
114
|
+
"'id', b.id, 'slug', b.slug, 'displayName', b.display_name, 'bio', b.bio, 'avatarMediaId', b.avatar_media_id, 'avatarStorageKey', m.storage_key, 'avatarAlt', m.alt, 'avatarBlurhash', m.blurhash, 'avatarDominantColor', m.dominant_color, 'websiteUrl', b.website_url, 'userId', b.user_id, 'isGuest', b.is_guest, 'createdAt', b.created_at, 'updatedAt', b.updated_at, 'locale', b.locale, 'translationGroup', b.translation_group",
|
|
115
|
+
);
|
|
116
|
+
const creditObj = pg
|
|
117
|
+
? sql.raw(
|
|
118
|
+
"json_build_object('roleLabel', cb.role_label, 'sortOrder', cb.sort_order, 'byline', ",
|
|
119
|
+
)
|
|
120
|
+
: sql.raw("json_object('roleLabel', cb.role_label, 'sortOrder', cb.sort_order, 'byline', ");
|
|
121
|
+
const credit = sql`${creditObj}${bylineInner})`;
|
|
122
|
+
const bylines = sql`(SELECT ${agg(credit)} FROM ${sql.ref("_emdash_content_bylines")} AS cb JOIN ${sql.ref("_emdash_bylines")} AS b ON b.translation_group = cb.byline_id LEFT JOIN ${sql.ref("media")} AS m ON m.id = b.avatar_media_id WHERE cb.collection_slug = ${type} AND cb.content_id = ${o}.id AND b.locale = ${o}.locale) AS ${sql.ref("_emdash_bylines")}`;
|
|
123
|
+
return { terms, bylines };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Stash folded hydration JSON (non-enumerable) for the query.ts fast paths.
|
|
128
|
+
* SQLite returns a JSON string (parse it); Postgres returns already-parsed JSON.
|
|
129
|
+
*/
|
|
130
|
+
function stashFolded(data: Record<string, unknown>, row: Record<string, unknown>): void {
|
|
131
|
+
for (const [col, sym] of [
|
|
132
|
+
["_emdash_terms", FOLDED_TERMS],
|
|
133
|
+
["_emdash_bylines", FOLDED_BYLINES],
|
|
134
|
+
] as const) {
|
|
135
|
+
const raw = row[col];
|
|
136
|
+
let value: unknown;
|
|
137
|
+
if (typeof raw === "string") {
|
|
138
|
+
try {
|
|
139
|
+
value = JSON.parse(raw);
|
|
140
|
+
} catch {
|
|
141
|
+
continue; // malformed: fall back to the query path
|
|
142
|
+
}
|
|
143
|
+
} else if (Array.isArray(raw)) {
|
|
144
|
+
value = raw; // Postgres json/jsonb already parsed by the driver
|
|
145
|
+
} else {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
Object.defineProperty(data, sym, { value, enumerable: false, configurable: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
77
152
|
/** Resolved SEO shape attached to `entry.data.seo`. Mirrors `ContentSeo`. */
|
|
78
153
|
interface EntrySeo {
|
|
79
154
|
title: string | null;
|
|
@@ -785,8 +860,14 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
785
860
|
)`
|
|
786
861
|
: sql``;
|
|
787
862
|
|
|
863
|
+
// Fold byline + taxonomy hydration into the list query.
|
|
864
|
+
const { terms: termsSelect, bylines: bylinesSelect } = foldedHydrationSelects(
|
|
865
|
+
db,
|
|
866
|
+
type,
|
|
867
|
+
tableName,
|
|
868
|
+
);
|
|
788
869
|
result = await sql<Record<string, unknown>>`
|
|
789
|
-
SELECT
|
|
870
|
+
SELECT *, ${termsSelect}, ${bylinesSelect} FROM ${sql.ref(tableName)}
|
|
790
871
|
WHERE deleted_at IS NULL
|
|
791
872
|
AND ${statusCondition}
|
|
792
873
|
${localeFilter}
|
|
@@ -814,11 +895,13 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
814
895
|
rowLocale !== "" &&
|
|
815
896
|
(rowLocale !== i18nConfig.defaultLocale || i18nConfig.prefixDefaultLocale);
|
|
816
897
|
const id = shouldPrefix ? `${rowLocale}/${slug}` : slug;
|
|
898
|
+
const data = mapRowToData(row);
|
|
899
|
+
stashFolded(data, row);
|
|
817
900
|
return {
|
|
818
901
|
id,
|
|
819
902
|
slug: rowStr(row, "slug"),
|
|
820
903
|
status: rowStr(row, "status", "draft"),
|
|
821
|
-
data
|
|
904
|
+
data,
|
|
822
905
|
cacheHint: {
|
|
823
906
|
tags: [rowStr(row, "id")],
|
|
824
907
|
lastModified: row.updated_at ? new Date(rowStr(row, "updated_at")) : undefined,
|
|
@@ -922,9 +1005,17 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
922
1005
|
([col, alias]) => sql`${sql.ref(`s.${col}`)} AS ${sql.ref(alias)}`,
|
|
923
1006
|
),
|
|
924
1007
|
);
|
|
1008
|
+
// Fold byline + taxonomy hydration into the content query (see
|
|
1009
|
+
// foldedHydrationSelects), removing the two separate hydration
|
|
1010
|
+
// round trips per fetch.
|
|
1011
|
+
const { terms: termsSelect, bylines: bylinesSelect } = foldedHydrationSelects(
|
|
1012
|
+
db,
|
|
1013
|
+
type,
|
|
1014
|
+
"c",
|
|
1015
|
+
);
|
|
925
1016
|
const result = locale
|
|
926
1017
|
? await sql<Record<string, unknown>>`
|
|
927
|
-
SELECT c.*, ${seoSelect}
|
|
1018
|
+
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}
|
|
928
1019
|
FROM ${sql.ref(tableName)} AS c
|
|
929
1020
|
LEFT JOIN ${sql.ref("_emdash_seo")} AS s
|
|
930
1021
|
ON s.collection = ${type} AND s.content_id = c.id
|
|
@@ -933,7 +1024,7 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
933
1024
|
LIMIT 1
|
|
934
1025
|
`.execute(db)
|
|
935
1026
|
: await sql<Record<string, unknown>>`
|
|
936
|
-
SELECT c.*, ${seoSelect}
|
|
1027
|
+
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}
|
|
937
1028
|
FROM ${sql.ref(tableName)} AS c
|
|
938
1029
|
LEFT JOIN ${sql.ref("_emdash_seo")} AS s
|
|
939
1030
|
ON s.collection = ${type} AND s.content_id = c.id
|
|
@@ -1015,6 +1106,7 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
1015
1106
|
const entryData = mapRowToData(row);
|
|
1016
1107
|
const entrySeo = extractSeo(row);
|
|
1017
1108
|
if (entrySeo) entryData.seo = entrySeo;
|
|
1109
|
+
stashFolded(entryData, row);
|
|
1018
1110
|
return {
|
|
1019
1111
|
id: entryId,
|
|
1020
1112
|
slug: rowStr(row, "slug"),
|