emdash 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-hUy8vOB-.d.mts → adapters-DPAkL6QF.d.mts} +1 -1
- package/dist/{adapters-hUy8vOB-.d.mts.map → adapters-DPAkL6QF.d.mts.map} +1 -1
- package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-FXB-FplB.mjs} +2 -2
- package/dist/{allowed-origins-CRsJ6BPM.mjs.map → allowed-origins-FXB-FplB.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +22 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +4 -4
- package/dist/{api-BFURZn1i.mjs → api-DVbHNApo.mjs} +75 -23
- package/dist/api-DVbHNApo.mjs.map +1 -0
- package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-UYBkl17d.mjs} +2 -2
- package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-UYBkl17d.mjs.map} +1 -1
- package/dist/{apply-Bu-8nYHL.mjs → apply-D23iUV4q.mjs} +20 -20
- package/dist/{apply-Bu-8nYHL.mjs.map → apply-D23iUV4q.mjs.map} +1 -1
- package/dist/astro/index.d.mts +13 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +10 -5
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +11 -10
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +8 -8
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.d.mts +3 -0
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +257 -30
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +2 -2
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +125 -79
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/index.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +28 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +43 -41
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +43 -41
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +42 -40
- 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 +42 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +43 -41
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +43 -41
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +42 -40
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +42 -40
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +42 -40
- 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 +7 -7
- 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_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- 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.d.mts.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +69 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -13
- 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 +12 -12
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +9 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +71 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +50 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +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 +15 -15
- 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 +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +12 -11
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +11 -10
- package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +12 -16
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +12 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +28 -28
- package/dist/astro/routes/api/manifest.mjs +6 -6
- package/dist/astro/routes/api/mcp.mjs +56 -47
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -9
- 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 +9 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs +9 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +9 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs +9 -9
- package/dist/astro/routes/api/menus/_name_.mjs +9 -9
- package/dist/astro/routes/api/menus/index.mjs +9 -9
- 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 +24 -5
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +7 -15
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +12 -12
- package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -12
- package/dist/astro/routes/api/redirects/_id_.mjs +13 -13
- package/dist/astro/routes/api/redirects/index.mjs +13 -13
- package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
- package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs +69 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/relations/index.d.mts +9 -0
- package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/index.mjs +53 -0
- package/dist/astro/routes/api/relations/index.mjs.map +1 -0
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +42 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +42 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +42 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +42 -40
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +42 -40
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -9
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +42 -40
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +42 -40
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +12 -12
- package/dist/astro/routes/api/search/index.mjs +13 -12
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +12 -12
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +11 -11
- package/dist/astro/routes/api/sections/_slug_.mjs +11 -11
- package/dist/astro/routes/api/sections/index.mjs +11 -11
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +15 -15
- 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.mjs +29 -29
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +30 -30
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.mjs +8 -8
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +15 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +15 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +15 -15
- package/dist/astro/routes/api/taxonomies/index.mjs +15 -15
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.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 +12 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -12
- package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/index.mjs +12 -12
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +9 -9
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
- package/dist/astro/routes/sitemap.xml.mjs +10 -10
- package/dist/astro/types.d.mts +16 -13
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-Dz88F_Fw.mjs → authorize-BmCwQCib.mjs} +2 -2
- package/dist/{authorize-Dz88F_Fw.mjs.map → authorize-BmCwQCib.mjs.map} +1 -1
- package/dist/{base64-CmWvODNW.mjs → base64-C74Msx8h.mjs} +1 -1
- package/dist/{base64-CmWvODNW.mjs.map → base64-C74Msx8h.mjs.map} +1 -1
- package/dist/{byline-Bm8ZgUP9.mjs → byline-BWb5H-65.mjs} +8 -8
- package/dist/{byline-Bm8ZgUP9.mjs.map → byline-BWb5H-65.mjs.map} +1 -1
- package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-DO6bAYK8.mjs} +2 -2
- package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-DO6bAYK8.mjs.map} +1 -1
- package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
- package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
- package/dist/{bylines-6tm9mgQb.mjs → bylines-BGuKFaBy.mjs} +4 -4
- package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BGuKFaBy.mjs.map} +1 -1
- package/dist/{bylines-Woq87129.mjs → bylines-CHojDMpj.mjs} +8 -8
- package/dist/{bylines-Woq87129.mjs.map → bylines-CHojDMpj.mjs.map} +1 -1
- package/dist/{cache-CEBAZjir.mjs → cache-BeR7RfN8.mjs} +3 -3
- package/dist/{cache-CEBAZjir.mjs.map → cache-BeR7RfN8.mjs.map} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs → challenge-store-B426wQ6O.mjs} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-B426wQ6O.mjs.map} +1 -1
- package/dist/{chunks-B2isWQhr.mjs → chunks-BU5_nrAC.mjs} +2 -2
- package/dist/{chunks-B2isWQhr.mjs.map → chunks-BU5_nrAC.mjs.map} +1 -1
- package/dist/cli/index.mjs +28 -28
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +34 -2
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +6 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-CzeatwBV.mjs → comment-SWh31kS0.mjs} +2 -2
- package/dist/{comment-CzeatwBV.mjs.map → comment-SWh31kS0.mjs.map} +1 -1
- package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-DgcpziXI.mjs} +2 -2
- package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-DgcpziXI.mjs.map} +1 -1
- package/dist/{comments-BLE-jv5k.mjs → comments-kZYGppMS.mjs} +3 -3
- package/dist/{comments-BLE-jv5k.mjs.map → comments-kZYGppMS.mjs.map} +1 -1
- package/dist/{components-B_sATNUc.mjs → components-CliOkZAs.mjs} +1 -1
- package/dist/{components-B_sATNUc.mjs.map → components-CliOkZAs.mjs.map} +1 -1
- package/dist/{content-DhgEth4k.mjs → content-BO61Sx4j.mjs} +179 -20
- package/dist/content-BO61Sx4j.mjs.map +1 -0
- package/dist/{content-refresh-CA4uKwzH.mjs → content-refresh-BkkApzeS.mjs} +20 -14
- package/dist/content-refresh-BkkApzeS.mjs.map +1 -0
- package/dist/{context-CUsR9dXL.mjs → context-DtSFYFuS.mjs} +71 -14
- package/dist/context-DtSFYFuS.mjs.map +1 -0
- package/dist/{cron-v4FTEFR_.mjs → cron-YFJ7uNVA.mjs} +1 -1
- package/dist/{cron-v4FTEFR_.mjs.map → cron-YFJ7uNVA.mjs.map} +1 -1
- package/dist/{dashboard-EvEKF5en.mjs → dashboard-xo_gPs_D.mjs} +6 -5
- package/dist/dashboard-xo_gPs_D.mjs.map +1 -0
- package/dist/database/pg-migration-lock.d.mts +21 -0
- package/dist/database/pg-migration-lock.d.mts.map +1 -0
- package/dist/database/pg-migration-lock.mjs +45 -0
- package/dist/database/pg-migration-lock.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +2 -8
- package/dist/db/postgres.mjs.map +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CK46D-ly.mjs → db-errors-BKuXh_fi.mjs} +1 -1
- package/dist/{db-errors-CK46D-ly.mjs.map → db-errors-BKuXh_fi.mjs.map} +1 -1
- package/dist/{default-CM_D83Mg.mjs → default-DY5ovGUG.mjs} +1 -1
- package/dist/{default-CM_D83Mg.mjs.map → default-DY5ovGUG.mjs.map} +1 -1
- package/dist/{device-flow-CfGP18Uw.mjs → device-flow-CPXQ_QfW.mjs} +5 -5
- package/dist/{device-flow-CfGP18Uw.mjs.map → device-flow-CPXQ_QfW.mjs.map} +1 -1
- package/dist/{dialect-helpers-DRI5pyY3.mjs → dialect-helpers-Cue7QQOR.mjs} +21 -2
- package/dist/dialect-helpers-Cue7QQOR.mjs.map +1 -0
- package/dist/{email-console-CIf4Lfvv.mjs → email-console-CjkQc7oY.mjs} +1 -1
- package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-CjkQc7oY.mjs.map} +1 -1
- package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
- package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
- package/dist/{error-CkAseSqZ.mjs → error-CfJMLSkd.mjs} +12 -3
- package/dist/error-CfJMLSkd.mjs.map +1 -0
- package/dist/{escape-DqD0aCKu.mjs → escape-r8_GbEU2.mjs} +1 -1
- package/dist/{escape-DqD0aCKu.mjs.map → escape-r8_GbEU2.mjs.map} +1 -1
- package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-BVrNCgSj.mjs} +5 -5
- package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-BVrNCgSj.mjs.map} +1 -1
- package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-BD9s77qh.mjs} +27 -3
- package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-BD9s77qh.mjs.map} +1 -1
- package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
- package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
- package/dist/hreflang-CgIxhH4k.d.mts +48 -0
- package/dist/hreflang-CgIxhH4k.d.mts.map +1 -0
- package/dist/hreflang-pAWUiPd_.mjs +102 -0
- package/dist/hreflang-pAWUiPd_.mjs.map +1 -0
- package/dist/{import-fYLf14Co.mjs → import-2jHtLzsO.mjs} +6 -6
- package/dist/{import-fYLf14Co.mjs.map → import-2jHtLzsO.mjs.map} +1 -1
- package/dist/{index-B9sIxwe4.d.mts → index-BXOCyLj0.d.mts} +115 -21
- package/dist/index-BXOCyLj0.d.mts.map +1 -0
- package/dist/{index-Bm-Gy8Mh.d.mts → index-DxjWLKGT.d.mts} +3 -3
- package/dist/{index-Bm-Gy8Mh.d.mts.map → index-DxjWLKGT.d.mts.map} +1 -1
- package/dist/index.d.mts +20 -19
- package/dist/index.mjs +68 -64
- package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
- package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
- package/dist/{load-Djn3HWQS.mjs → load-DgoWMdRX.mjs} +2 -2
- package/dist/{load-Djn3HWQS.mjs.map → load-DgoWMdRX.mjs.map} +1 -1
- package/dist/{loader-CB6YHeul.mjs → loader-Rb8QlGZp.mjs} +5 -20
- package/dist/loader-Rb8QlGZp.mjs.map +1 -0
- package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-DeGNma2O.mjs} +3 -1
- package/dist/manifest-schema-DeGNma2O.mjs.map +1 -0
- package/dist/media/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +13 -12
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +8 -8
- package/dist/{media-BrXIaMFN.mjs → media-D2ZFowpn.mjs} +2 -2
- package/dist/media-D2ZFowpn.mjs.map +1 -0
- package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-Dc05vKtt.mjs} +2 -2
- package/dist/{media-allowlist-CRHEeJ_i.mjs.map → media-allowlist-Dc05vKtt.mjs.map} +1 -1
- package/dist/{media-url-CKi5XSw4.mjs → media-url-DgIEYZr4.mjs} +1 -1
- package/dist/{media-url-CKi5XSw4.mjs.map → media-url-DgIEYZr4.mjs.map} +1 -1
- package/dist/media-usage-B__v9NMm.mjs +421 -0
- package/dist/media-usage-B__v9NMm.mjs.map +1 -0
- package/dist/{menus-Cfivc2Ad.mjs → menus-BpfevlJD.mjs} +3 -3
- package/dist/{menus-Cfivc2Ad.mjs.map → menus-BpfevlJD.mjs.map} +1 -1
- package/dist/{menus-CsZ2ZEK2.mjs → menus-BtvH7Z7t.mjs} +31 -12
- package/dist/menus-BtvH7Z7t.mjs.map +1 -0
- package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
- package/dist/{mode-BM9QgEmt.mjs → mode-BVnhGZ2o.mjs} +1 -1
- package/dist/{mode-BM9QgEmt.mjs.map → mode-BVnhGZ2o.mjs.map} +1 -1
- package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
- package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
- package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-BWqWTHBK.mjs} +5 -5
- package/dist/{oauth-authorization-CXWkIGT4.mjs.map → oauth-authorization-BWqWTHBK.mjs.map} +1 -1
- package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-43_XADoa.mjs} +1 -1
- package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-43_XADoa.mjs.map} +1 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-BRSUEkmx.mjs} +1 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-BRSUEkmx.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-Ctgemb0k.mjs} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-Ctgemb0k.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
- package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
- package/dist/{options-iMpRRxIe.d.mts → options-COXGTtqd.d.mts} +3 -3
- package/dist/{options-iMpRRxIe.d.mts.map → options-COXGTtqd.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-GmjecGct.mjs → parse-GLksnn-B.mjs} +2 -2
- package/dist/{parse-GmjecGct.mjs.map → parse-GLksnn-B.mjs.map} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-CjA1UbDj.mjs} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-CjA1UbDj.mjs.map} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-DR-eeZr-.d.mts} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts.map → placeholder-DR-eeZr-.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +11 -10
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +11 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{portable-text-cCa0cGV6.mjs → portable-text-BAkgEKcv.mjs} +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-BAkgEKcv.mjs.map} +1 -1
- package/dist/{preview-SSXNVPAC.mjs → preview-Rloa09Wp.mjs} +2 -2
- package/dist/{preview-SSXNVPAC.mjs.map → preview-Rloa09Wp.mjs.map} +1 -1
- package/dist/{public-url-Danv47cS.mjs → public-url-C0cEvrRu.mjs} +1 -1
- package/dist/{public-url-Danv47cS.mjs.map → public-url-C0cEvrRu.mjs.map} +1 -1
- package/dist/{schema-Blhoxp3P.mjs → query-BxT95opY.mjs} +5 -10
- package/dist/query-BxT95opY.mjs.map +1 -0
- package/dist/{query-ByGq6ver.mjs → query-ZzvXyxWq.mjs} +15 -15
- package/dist/query-ZzvXyxWq.mjs.map +1 -0
- package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-Cg4Rvc_-.mjs} +2 -2
- package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-Cg4Rvc_-.mjs.map} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs → redirect-Ce_6Yb6z.mjs} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Ce_6Yb6z.mjs.map} +1 -1
- package/dist/{redirect-IyfNirgS.mjs → redirect-Ch3E98qZ.mjs} +4 -4
- package/dist/{redirect-IyfNirgS.mjs.map → redirect-Ch3E98qZ.mjs.map} +1 -1
- package/dist/{redirects-Bs1g42Ri.mjs → redirects-CXmVGRNZ.mjs} +6 -6
- package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-CXmVGRNZ.mjs.map} +1 -1
- package/dist/{redirects-DXEXBAII.mjs → redirects-CeD7K7EX.mjs} +43 -5
- package/dist/redirects-CeD7K7EX.mjs.map +1 -0
- package/dist/{registry-B65mUtPa.mjs → registry-CyIXPi4E.mjs} +8 -8
- package/dist/{registry-B65mUtPa.mjs.map → registry-CyIXPi4E.mjs.map} +1 -1
- package/dist/relation-Ba68Tm4Z.mjs +334 -0
- package/dist/relation-Ba68Tm4Z.mjs.map +1 -0
- package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-BmBmX4Eb.mjs} +60 -4
- package/dist/relations-BmBmX4Eb.mjs.map +1 -0
- package/dist/relations-C8hVyEy0.mjs +397 -0
- package/dist/relations-C8hVyEy0.mjs.map +1 -0
- package/dist/{byline-fields-Cgrt9-aL.d.mts → relations-CbBpoOys.d.mts} +180 -27
- package/dist/relations-CbBpoOys.d.mts.map +1 -0
- package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
- package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
- package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DCwktC5P.mjs} +2 -2
- package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DCwktC5P.mjs.map} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
- package/dist/{runner-DvFWoz8-.d.mts → runner-CiNdIk3y.d.mts} +8 -2
- package/dist/runner-CiNdIk3y.d.mts.map +1 -0
- package/dist/{runner-K8XK101B.mjs → runner-jt65bF7F.mjs} +24 -7
- package/dist/{runner-K8XK101B.mjs.map → runner-jt65bF7F.mjs.map} +1 -1
- package/dist/runtime.d.mts +12 -11
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +4 -4
- package/dist/{scheduled-publish-Drffrf2a.d.mts → scheduled-publish-DlJHGcuL.d.mts} +1 -1
- package/dist/scheduled-publish-DlJHGcuL.d.mts.map +1 -0
- package/dist/schema-DwjufZ1S.mjs +9 -0
- package/dist/schema-DwjufZ1S.mjs.map +1 -0
- package/dist/{search-DZN2HZ-V.mjs → search-Cl875CVE.mjs} +62 -12
- package/dist/search-Cl875CVE.mjs.map +1 -0
- package/dist/{secrets-kp760LlD.mjs → secrets-CO_bEmII.mjs} +4 -4
- package/dist/{secrets-kp760LlD.mjs.map → secrets-CO_bEmII.mjs.map} +1 -1
- package/dist/{sections-CpF5SaGr.mjs → sections-DTKzgoiS.mjs} +3 -3
- package/dist/{sections-CpF5SaGr.mjs.map → sections-DTKzgoiS.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +23 -23
- package/dist/seo/index.d.mts +4 -2
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +19 -2
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-DXu2UQnC.mjs → seo-BLm6SXzS.mjs} +2 -2
- package/dist/{seo-DXu2UQnC.mjs.map → seo-BLm6SXzS.mjs.map} +1 -1
- package/dist/{seo-89-53DDs.mjs → seo-BjrbXAd_.mjs} +1 -1
- package/dist/{seo-89-53DDs.mjs.map → seo-BjrbXAd_.mjs.map} +1 -1
- package/dist/{service-DQmiBMzt.mjs → service-D6zDmKXy.mjs} +3 -3
- package/dist/{service-DQmiBMzt.mjs.map → service-D6zDmKXy.mjs.map} +1 -1
- package/dist/{session-user-Cascbax7.mjs → session-user-DoSs6YM8.mjs} +1 -1
- package/dist/{session-user-Cascbax7.mjs.map → session-user-DoSs6YM8.mjs.map} +1 -1
- package/dist/{settings-zhmdKyJQ.mjs → settings-BuQYvLfy.mjs} +6 -6
- package/dist/{settings-zhmdKyJQ.mjs.map → settings-BuQYvLfy.mjs.map} +1 -1
- package/dist/{settings-rZyHEcNT.mjs → settings-CmS3TwXf.mjs} +3 -3
- package/dist/{settings-rZyHEcNT.mjs.map → settings-CmS3TwXf.mjs.map} +1 -1
- package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-BPNgLHlU.mjs} +2 -2
- package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-BPNgLHlU.mjs.map} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DEPZX96T.mjs} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DEPZX96T.mjs.map} +1 -1
- package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-DEtW-OEG.mjs} +2 -2
- package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-DEtW-OEG.mjs.map} +1 -1
- package/dist/{site-url-BBfDTgZB.mjs → site-url-CcLy5D5s.mjs} +2 -2
- package/dist/{site-url-BBfDTgZB.mjs.map → site-url-CcLy5D5s.mjs.map} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
- package/dist/{ssrf-1g7usGBg.mjs → ssrf-TrKYJAy0.mjs} +1 -1
- package/dist/{ssrf-1g7usGBg.mjs.map → ssrf-TrKYJAy0.mjs.map} +1 -1
- package/dist/{status-CqJQX1QN.mjs → status-D3Gy1Zc6.mjs} +1 -1
- package/dist/{status-CqJQX1QN.mjs.map → status-D3Gy1Zc6.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-BGBd16Eu.mjs → taxonomies-ClS4RKaZ.mjs} +13 -9
- package/dist/taxonomies-ClS4RKaZ.mjs.map +1 -0
- package/dist/{taxonomies-Cnb4F-Pb.mjs → taxonomies-pUkuD6nj.mjs} +115 -36
- package/dist/taxonomies-pUkuD6nj.mjs.map +1 -0
- package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-BkxbUMSw.mjs} +12 -3
- package/dist/{taxonomy-BxGxZZdu.mjs.map → taxonomy-BkxbUMSw.mjs.map} +1 -1
- package/dist/{tokens-BGT0TUUo.mjs → tokens-BV6fgl5A.mjs} +2 -2
- package/dist/{tokens-BGT0TUUo.mjs.map → tokens-BV6fgl5A.mjs.map} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
- package/dist/{transport-DPefPMcz.mjs → transport-DTFhhPOg.mjs} +1 -1
- package/dist/{transport-DPefPMcz.mjs.map → transport-DTFhhPOg.mjs.map} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts → transport-DmlmzD2U.d.mts} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts.map → transport-DmlmzD2U.d.mts.map} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CSgZVESw.mjs} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CSgZVESw.mjs.map} +1 -1
- package/dist/{types-CgvhU-hF.d.mts → types-B6-N9cBB.d.mts} +1 -1
- package/dist/{types-CgvhU-hF.d.mts.map → types-B6-N9cBB.d.mts.map} +1 -1
- package/dist/{types-g_aFIdW0.d.mts → types-BCVuUPrL.d.mts} +1 -1
- package/dist/{types-g_aFIdW0.d.mts.map → types-BCVuUPrL.d.mts.map} +1 -1
- package/dist/{types-Jo3UYd6b.mjs → types-BNZsPL9z.mjs} +1 -1
- package/dist/{types-Jo3UYd6b.mjs.map → types-BNZsPL9z.mjs.map} +1 -1
- package/dist/{types-vgEWF18A.d.mts → types-B_pmP7Yq.d.mts} +1 -1
- package/dist/{types-vgEWF18A.d.mts.map → types-B_pmP7Yq.d.mts.map} +1 -1
- package/dist/{types-CuW0zWDA.mjs → types-Ch8pFMEm.mjs} +3 -3
- package/dist/{types-CuW0zWDA.mjs.map → types-Ch8pFMEm.mjs.map} +1 -1
- package/dist/{types-ea9sAPck.d.mts → types-Cm4Cz-8M.d.mts} +1 -1
- package/dist/{types-ea9sAPck.d.mts.map → types-Cm4Cz-8M.d.mts.map} +1 -1
- package/dist/{types-CGbYowGQ.d.mts → types-CtDVagM4.d.mts} +55 -3
- package/dist/types-CtDVagM4.d.mts.map +1 -0
- package/dist/{types-BcLUUbbR.d.mts → types-DLIrNtv5.d.mts} +11 -3
- package/dist/{types-BcLUUbbR.d.mts.map → types-DLIrNtv5.d.mts.map} +1 -1
- package/dist/{types-DmHk7vAt.d.mts → types-QnlQIyPE.d.mts} +1 -1
- package/dist/{types-DmHk7vAt.d.mts.map → types-QnlQIyPE.d.mts.map} +1 -1
- package/dist/{types-_HFLRzTn.d.mts → types-momGysZk.d.mts} +1 -1
- package/dist/{types-_HFLRzTn.d.mts.map → types-momGysZk.d.mts.map} +1 -1
- package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
- package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
- package/dist/{types-ClUkdbWb.d.mts → types-qljd1hsL.d.mts} +1 -1
- package/dist/{types-ClUkdbWb.d.mts.map → types-qljd1hsL.d.mts.map} +1 -1
- package/dist/{user-BjAOvU3Z.mjs → user-DTxX_Fha.mjs} +3 -3
- package/dist/{user-BjAOvU3Z.mjs.map → user-DTxX_Fha.mjs.map} +1 -1
- package/dist/{utils-BJXElxdw.mjs → utils-Cz8PVrl4.mjs} +3 -3
- package/dist/{utils-BJXElxdw.mjs.map → utils-Cz8PVrl4.mjs.map} +1 -1
- package/dist/{validate-Z1b86_3B.d.mts → validate-9jLuE301.d.mts} +5 -5
- package/dist/{validate-Z1b86_3B.d.mts.map → validate-9jLuE301.d.mts.map} +1 -1
- package/dist/{validate-CWSnKVIJ.mjs → validate-C3CpWlNt.mjs} +3 -3
- package/dist/{validate-CWSnKVIJ.mjs.map → validate-C3CpWlNt.mjs.map} +1 -1
- package/dist/{validation-c8WjhH8z.mjs → validation-DM2K_NJC.mjs} +10 -10
- package/dist/{validation-c8WjhH8z.mjs.map → validation-DM2K_NJC.mjs.map} +1 -1
- package/dist/version-BlIJvNAZ.mjs +7 -0
- package/dist/{version-CaccU7DM.mjs.map → version-BlIJvNAZ.mjs.map} +1 -1
- package/dist/{widgets-hWcIicX8.mjs → widgets-B_X6_UXJ.mjs} +4 -4
- package/dist/{widgets-hWcIicX8.mjs.map → widgets-B_X6_UXJ.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-BC3OYpvx.mjs → wxr-taxonomies-oNJB2S81.mjs} +4 -4
- package/dist/{wxr-taxonomies-BC3OYpvx.mjs.map → wxr-taxonomies-oNJB2S81.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-tADW4KTa.d.mts} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-tADW4KTa.d.mts.map} +1 -1
- package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-CrfV79De.mjs} +3 -3
- package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-CrfV79De.mjs.map} +1 -1
- package/package.json +11 -7
- package/src/api/errors.ts +11 -0
- package/src/api/handlers/content.ts +111 -1
- package/src/api/handlers/dashboard.ts +2 -0
- package/src/api/handlers/index.ts +6 -0
- package/src/api/handlers/media-usage.ts +80 -0
- package/src/api/handlers/relations.ts +474 -0
- package/src/api/handlers/taxonomies.ts +26 -4
- package/src/api/handlers/validate-media-fields.ts +1 -1
- package/src/api/openapi/document.ts +25 -0
- package/src/api/parse.ts +1 -1
- package/src/api/schemas/comments.ts +6 -0
- package/src/api/schemas/content.ts +8 -0
- package/src/api/schemas/index.ts +2 -0
- package/src/api/schemas/media-usage.ts +48 -0
- package/src/api/schemas/relations.ts +109 -0
- package/src/api/schemas/search.ts +1 -0
- package/src/astro/integration/index.ts +1 -0
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/runtime.ts +24 -0
- package/src/astro/middleware/request-context.ts +162 -20
- package/src/astro/middleware.ts +22 -9
- package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -2
- package/src/astro/routes/api/admin/comments/index.ts +1 -2
- package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +1 -2
- package/src/astro/routes/api/auth/oauth/[provider].ts +1 -2
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +97 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +48 -0
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -15
- package/src/astro/routes/api/relations/[id]/index.ts +84 -0
- package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
- package/src/astro/routes/api/relations/index.ts +56 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
- package/src/astro/routes/api/search/index.ts +2 -0
- package/src/astro/types.ts +2 -0
- package/src/cli/commands/export-seed.ts +1 -10
- package/src/client/index.ts +39 -0
- package/src/comments/service.ts +1 -1
- package/src/comments/turnstile.ts +64 -0
- package/src/components/BlockquoteGroup.astro +34 -0
- package/src/components/CommentForm.astro +12 -5
- package/src/components/EmDashHead.astro +27 -1
- package/src/components/InlinePortableTextEditor.tsx +34 -0
- package/src/components/PortableText.astro +7 -1
- package/src/components/index.ts +2 -0
- package/src/components/portable-text-blockquote-group.ts +68 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
- package/src/database/dialect-helpers.ts +34 -0
- package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
- package/src/database/migrations/runner.ts +46 -6
- package/src/database/pg-migration-lock.ts +72 -0
- package/src/database/repositories/comment.ts +1 -1
- package/src/database/repositories/content.ts +172 -21
- package/src/database/repositories/media-usage.ts +25 -3
- package/src/database/repositories/media.ts +1 -1
- package/src/database/repositories/relation.ts +130 -5
- package/src/database/repositories/taxonomy.ts +9 -0
- package/src/database/repositories/types.ts +8 -0
- package/src/db/postgres.ts +5 -2
- package/src/emdash-runtime.ts +72 -4
- package/src/index.ts +6 -2
- package/src/loader.ts +1 -31
- package/src/mcp/server.ts +29 -3
- package/src/media/usage/content-repair.ts +206 -22
- package/src/media/usage/content-snapshots.ts +4 -0
- package/src/plugins/context.ts +85 -0
- package/src/plugins/define-plugin.ts +1 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/manifest-schema.ts +2 -0
- package/src/plugins/types.ts +59 -0
- package/src/schema/byline-registry.ts +1 -1
- package/src/search/fts-manager.ts +34 -0
- package/src/search/match.ts +50 -0
- package/src/search/query.ts +94 -9
- package/src/seo/hreflang.ts +192 -0
- package/src/seo/index.ts +3 -0
- package/src/taxonomies/index.ts +62 -45
- package/src/taxonomies/term-counts.ts +117 -0
- package/src/virtual-modules.d.ts +1 -0
- package/src/visual-editing/editable.ts +41 -35
- package/src/visual-editing/toolbar-bootstrap.ts +120 -0
- package/src/visual-editing/toolbar.ts +46 -0
- package/dist/api-BFURZn1i.mjs.map +0 -1
- package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
- package/dist/byline-fields-Cgrt9-aL.d.mts.map +0 -1
- package/dist/content-DhgEth4k.mjs.map +0 -1
- package/dist/content-refresh-CA4uKwzH.mjs.map +0 -1
- package/dist/context-CUsR9dXL.mjs.map +0 -1
- package/dist/dashboard-EvEKF5en.mjs.map +0 -1
- package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
- package/dist/error-CkAseSqZ.mjs.map +0 -1
- package/dist/index-B9sIxwe4.d.mts.map +0 -1
- package/dist/loader-CB6YHeul.mjs.map +0 -1
- package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
- package/dist/media-BrXIaMFN.mjs.map +0 -1
- package/dist/menus-CsZ2ZEK2.mjs.map +0 -1
- package/dist/query-ByGq6ver.mjs.map +0 -1
- package/dist/redirects-DXEXBAII.mjs.map +0 -1
- package/dist/runner-DvFWoz8-.d.mts.map +0 -1
- package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
- package/dist/schema-Blhoxp3P.mjs.map +0 -1
- package/dist/search-DZN2HZ-V.mjs.map +0 -1
- package/dist/taxonomies-BGBd16Eu.mjs.map +0 -1
- package/dist/taxonomies-Cnb4F-Pb.mjs.map +0 -1
- package/dist/types-CGbYowGQ.d.mts.map +0 -1
- package/dist/version-CaccU7DM.mjs +0 -7
- /package/dist/{api-tokens-DsvvCtdh.mjs → api-tokens-Dk2GrJMY.mjs} +0 -0
- /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-B5DOv5E5.mjs} +0 -0
- /package/dist/{types-DROWRxYV.mjs → types-DeCZBZxn.mjs} +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hreflang alternate resolution for translated content (#1690).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the sitemap route's semantics so the render path and the
|
|
5
|
+
* sitemap always agree:
|
|
6
|
+
*
|
|
7
|
+
* - Alternates are emitted per published locale variant of a
|
|
8
|
+
* translation group, including a self-referencing entry (Google
|
|
9
|
+
* recommends the page annotate itself).
|
|
10
|
+
* - `x-default` points at the default-locale variant, falling back to
|
|
11
|
+
* the first routable variant when the default locale has no
|
|
12
|
+
* translation.
|
|
13
|
+
* - Variants whose locale isn't in the configured `i18n.locales` list
|
|
14
|
+
* are dropped: linking to a route the site can't serve is worse than
|
|
15
|
+
* no link at all.
|
|
16
|
+
* - Variants flagged `noindex` in the SEO panel are excluded — the
|
|
17
|
+
* sitemap doesn't list them, and pointing search engines at a page
|
|
18
|
+
* that asks not to be indexed is a contradictory signal. When the
|
|
19
|
+
* entry itself is noindex the result is empty: a page opting out of
|
|
20
|
+
* indexing shouldn't announce an hreflang set at all.
|
|
21
|
+
* - When i18n is disabled (or no absolute site URL can be resolved,
|
|
22
|
+
* which hreflang requires) the result is empty and no queries run.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { Kysely } from "kysely";
|
|
26
|
+
|
|
27
|
+
import { ContentRepository } from "../database/repositories/content.js";
|
|
28
|
+
import type { Database } from "../database/types.js";
|
|
29
|
+
import { getI18nConfig, isI18nEnabled } from "../i18n/config.js";
|
|
30
|
+
import { interpolateUrlPattern, localizePath } from "../i18n/resolve.js";
|
|
31
|
+
import { requestCached } from "../request-cache.js";
|
|
32
|
+
import { getCollectionInfoWithDb } from "../schema/query.js";
|
|
33
|
+
import { getSiteSettingsWithDb } from "../settings/index.js";
|
|
34
|
+
|
|
35
|
+
const TRAILING_SLASH_RE = /\/$/;
|
|
36
|
+
const ABSOLUTE_URL_RE = /^https?:\/\//i;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* IDs of variants flagged `noindex` in the SEO panel. Entries without
|
|
40
|
+
* an `_emdash_seo` row are indexable by default (same as the sitemap).
|
|
41
|
+
* The id list is bounded by the number of configured locales, so no
|
|
42
|
+
* chunking is needed.
|
|
43
|
+
*/
|
|
44
|
+
async function findNoindexIds(
|
|
45
|
+
db: Kysely<Database>,
|
|
46
|
+
collection: string,
|
|
47
|
+
ids: string[],
|
|
48
|
+
): Promise<Set<string>> {
|
|
49
|
+
if (ids.length === 0) return new Set();
|
|
50
|
+
const rows = await db
|
|
51
|
+
.selectFrom("_emdash_seo")
|
|
52
|
+
.select("content_id")
|
|
53
|
+
.where("collection", "=", collection)
|
|
54
|
+
.where("content_id", "in", ids)
|
|
55
|
+
.where("seo_no_index", "=", 1)
|
|
56
|
+
.execute();
|
|
57
|
+
return new Set(rows.map((r) => r.content_id));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** A single alternate link, ready to render as `<link rel="alternate">`. */
|
|
61
|
+
export interface HreflangAlternate {
|
|
62
|
+
/** Locale code, or `"x-default"` for the default variant */
|
|
63
|
+
hreflang: string;
|
|
64
|
+
/** Absolute URL of the variant */
|
|
65
|
+
href: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface HreflangOptions {
|
|
69
|
+
/**
|
|
70
|
+
* Absolute site origin (e.g. `https://example.com`) used to build
|
|
71
|
+
* the alternate URLs. Falls back to the site settings URL; when
|
|
72
|
+
* neither is available the result is empty, since hreflang
|
|
73
|
+
* requires fully-qualified URLs.
|
|
74
|
+
*/
|
|
75
|
+
siteUrl?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resolve hreflang alternates for a content entry.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```astro
|
|
83
|
+
* ---
|
|
84
|
+
* import { getHreflangAlternates } from "emdash";
|
|
85
|
+
*
|
|
86
|
+
* const alternates = await getHreflangAlternates("posts", entry.data.id, {
|
|
87
|
+
* siteUrl: Astro.url.origin,
|
|
88
|
+
* });
|
|
89
|
+
* ---
|
|
90
|
+
* <head>
|
|
91
|
+
* {alternates.map((a) => <link rel="alternate" hreflang={a.hreflang} href={a.href} />)}
|
|
92
|
+
* </head>
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export async function getHreflangAlternates(
|
|
96
|
+
collection: string,
|
|
97
|
+
entryId: string,
|
|
98
|
+
options: HreflangOptions = {},
|
|
99
|
+
): Promise<HreflangAlternate[]> {
|
|
100
|
+
if (!isI18nEnabled()) return [];
|
|
101
|
+
const key = `hreflang:${collection}:${entryId}:${options.siteUrl ?? ""}`;
|
|
102
|
+
return requestCached(key, async () => {
|
|
103
|
+
const { getDb } = await import("../loader.js");
|
|
104
|
+
const db = await getDb();
|
|
105
|
+
return getHreflangAlternatesWithDb(db, collection, entryId, options);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Resolve hreflang alternates with an explicit db handle.
|
|
111
|
+
*
|
|
112
|
+
* @internal Use `getHreflangAlternates()` in templates. This variant is
|
|
113
|
+
* for routes/components that already have a database handle.
|
|
114
|
+
*/
|
|
115
|
+
export async function getHreflangAlternatesWithDb(
|
|
116
|
+
db: Kysely<Database>,
|
|
117
|
+
collection: string,
|
|
118
|
+
entryId: string,
|
|
119
|
+
options: HreflangOptions = {},
|
|
120
|
+
): Promise<HreflangAlternate[]> {
|
|
121
|
+
if (!isI18nEnabled()) return [];
|
|
122
|
+
|
|
123
|
+
let siteUrl = options.siteUrl;
|
|
124
|
+
if (!siteUrl) {
|
|
125
|
+
const settings = await getSiteSettingsWithDb(db);
|
|
126
|
+
siteUrl = settings.url;
|
|
127
|
+
}
|
|
128
|
+
// hreflang requires fully-qualified URLs; a relative site URL would
|
|
129
|
+
// produce invalid output (and EmDashHead's isSafeHref would drop it).
|
|
130
|
+
if (!siteUrl || !ABSOLUTE_URL_RE.test(siteUrl)) return [];
|
|
131
|
+
siteUrl = siteUrl.replace(TRAILING_SLASH_RE, "");
|
|
132
|
+
|
|
133
|
+
const repo = new ContentRepository(db);
|
|
134
|
+
const item = await repo.findByIdOrSlug(collection, entryId);
|
|
135
|
+
if (!item) return [];
|
|
136
|
+
|
|
137
|
+
// Legacy rows imported before i18n may have no translation_group;
|
|
138
|
+
// treat them as a single-variant group.
|
|
139
|
+
const group = item.translationGroup || item.id;
|
|
140
|
+
let variants = await repo.findTranslations(collection, group);
|
|
141
|
+
if (variants.length === 0) variants = [item];
|
|
142
|
+
|
|
143
|
+
let published = variants.filter((v) => v.status === "published");
|
|
144
|
+
if (published.length === 0) return [];
|
|
145
|
+
|
|
146
|
+
// Exclude noindex variants, matching the sitemap's `_emdash_seo`
|
|
147
|
+
// filter so head and sitemap agree on which variants are
|
|
148
|
+
// discoverable. When the requested entry itself is noindex, emit
|
|
149
|
+
// nothing: a page opting out of indexing shouldn't announce an
|
|
150
|
+
// hreflang set.
|
|
151
|
+
const noindexIds = await findNoindexIds(
|
|
152
|
+
db,
|
|
153
|
+
collection,
|
|
154
|
+
published.map((v) => v.id),
|
|
155
|
+
);
|
|
156
|
+
if (noindexIds.has(item.id)) return [];
|
|
157
|
+
published = published.filter((v) => !noindexIds.has(v.id));
|
|
158
|
+
|
|
159
|
+
const info = await getCollectionInfoWithDb(db, collection);
|
|
160
|
+
const urlPattern = info?.urlPattern ?? null;
|
|
161
|
+
|
|
162
|
+
const resolved: Array<{ locale: string; href: string }> = [];
|
|
163
|
+
for (const variant of published) {
|
|
164
|
+
const locale = variant.locale || "en";
|
|
165
|
+
const path = interpolateUrlPattern({
|
|
166
|
+
pattern: urlPattern,
|
|
167
|
+
collection,
|
|
168
|
+
slug: variant.slug || variant.id,
|
|
169
|
+
id: variant.id,
|
|
170
|
+
});
|
|
171
|
+
const localized = await localizePath(path, locale);
|
|
172
|
+
if (localized === null) continue;
|
|
173
|
+
resolved.push({ locale, href: `${siteUrl}${localized}` });
|
|
174
|
+
}
|
|
175
|
+
if (resolved.length === 0) return [];
|
|
176
|
+
|
|
177
|
+
resolved.sort((a, b) => a.locale.localeCompare(b.locale));
|
|
178
|
+
const alternates: HreflangAlternate[] = resolved.map((r) => ({
|
|
179
|
+
hreflang: r.locale,
|
|
180
|
+
href: r.href,
|
|
181
|
+
}));
|
|
182
|
+
|
|
183
|
+
// x-default: default-locale variant, else the first routable one.
|
|
184
|
+
// Same fallback the sitemap route uses.
|
|
185
|
+
const defaultLocale = getI18nConfig()?.defaultLocale;
|
|
186
|
+
const xDefault = resolved.find((r) => r.locale === defaultLocale) ?? resolved[0];
|
|
187
|
+
if (xDefault) {
|
|
188
|
+
alternates.push({ hreflang: "x-default", href: xDefault.href });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return alternates;
|
|
192
|
+
}
|
package/src/seo/index.ts
CHANGED
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
import type { ContentSeo } from "../database/repositories/types.js";
|
|
33
33
|
import { buildSeoImageUrl } from "./media-url.js";
|
|
34
34
|
|
|
35
|
+
export { getHreflangAlternates, getHreflangAlternatesWithDb } from "./hreflang.js";
|
|
36
|
+
export type { HreflangAlternate, HreflangOptions } from "./hreflang.js";
|
|
37
|
+
|
|
35
38
|
const TRAILING_SLASH_RE = /\/$/;
|
|
36
39
|
const ABSOLUTE_URL_RE = /^https?:\/\//i;
|
|
37
40
|
|
package/src/taxonomies/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { peekRequestCache, requestCached, setRequestCacheEntry } from "../reques
|
|
|
24
24
|
import { getRequestContext } from "../request-context.js";
|
|
25
25
|
import { chunks, SQL_BATCH_SIZE } from "../utils/chunks.js";
|
|
26
26
|
import { isMissingTableError } from "../utils/db-errors.js";
|
|
27
|
+
import { fetchVisibleTermCounts } from "./term-counts.js";
|
|
27
28
|
import type { TaxonomyDef, TaxonomyTerm, TaxonomyTermRow } from "./types.js";
|
|
28
29
|
|
|
29
30
|
export interface TaxonomyQueryOptions {
|
|
@@ -214,6 +215,18 @@ export async function getTaxonomyDef(
|
|
|
214
215
|
});
|
|
215
216
|
}
|
|
216
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Object-cache namespaces for values that embed visible term counts: the
|
|
220
|
+
* taxonomy epoch (term/assignment writes) plus each counted collection's
|
|
221
|
+
* content epoch, so publishing, unpublishing, or trashing an entry
|
|
222
|
+
* invalidates the cached count promptly. A scheduled entry becoming due
|
|
223
|
+
* flips visibility without a write, so that staleness stays bounded by the
|
|
224
|
+
* cache entry's TTL.
|
|
225
|
+
*/
|
|
226
|
+
function termCountNamespaces(collections: string[]): string[] {
|
|
227
|
+
return [...Array.from(new Set(collections), contentNamespace), CacheNamespace.TAXONOMIES];
|
|
228
|
+
}
|
|
229
|
+
|
|
217
230
|
/**
|
|
218
231
|
* All terms of a taxonomy in a specific locale (flat for non-hierarchical,
|
|
219
232
|
* tree for hierarchical).
|
|
@@ -223,37 +236,38 @@ export async function getTaxonomyTerms(
|
|
|
223
236
|
options: TaxonomyQueryOptions = {},
|
|
224
237
|
): Promise<TaxonomyTerm[]> {
|
|
225
238
|
const locale = resolveLocale(options.locale);
|
|
226
|
-
return requestCached(`taxonomy-terms:${taxonomyName}:${locale ?? "*"}`, () =>
|
|
227
|
-
|
|
228
|
-
|
|
239
|
+
return requestCached(`taxonomy-terms:${taxonomyName}:${locale ?? "*"}`, async () => {
|
|
240
|
+
const def = await getTaxonomyDef(taxonomyName, options);
|
|
241
|
+
if (!def) return [];
|
|
242
|
+
return cachedQuery({
|
|
243
|
+
namespace: termCountNamespaces(def.collections),
|
|
229
244
|
key: `terms:${taxonomyName}:${locale ?? "*"}`,
|
|
230
|
-
load: () => loadTaxonomyTerms(
|
|
231
|
-
})
|
|
232
|
-
);
|
|
245
|
+
load: () => loadTaxonomyTerms(def, locale),
|
|
246
|
+
});
|
|
247
|
+
});
|
|
233
248
|
}
|
|
234
249
|
|
|
235
250
|
async function loadTaxonomyTerms(
|
|
236
|
-
|
|
251
|
+
def: TaxonomyDef,
|
|
237
252
|
locale: string | undefined,
|
|
238
|
-
options: TaxonomyQueryOptions,
|
|
239
253
|
): Promise<TaxonomyTerm[]> {
|
|
240
254
|
const db = await getDb();
|
|
241
255
|
|
|
242
|
-
const def = await getTaxonomyDef(taxonomyName, options);
|
|
243
|
-
if (!def) return [];
|
|
244
|
-
|
|
245
256
|
let termsQuery = db
|
|
246
257
|
.selectFrom("taxonomies")
|
|
247
258
|
.selectAll()
|
|
248
|
-
.where("name", "=",
|
|
259
|
+
.where("name", "=", def.name)
|
|
249
260
|
.orderBy("label", "asc");
|
|
250
261
|
if (locale !== undefined) termsQuery = termsQuery.where("locale", "=", locale);
|
|
251
|
-
const rows = await termsQuery.execute();
|
|
252
262
|
|
|
253
263
|
// Counts are keyed by translation_group (what the pivot stores) and are
|
|
254
|
-
// locale-independent
|
|
255
|
-
//
|
|
256
|
-
|
|
264
|
+
// locale-independent. Only publicly visible entries are counted (#581);
|
|
265
|
+
// the map is request-cached so a term detail rendered on the same page
|
|
266
|
+
// reuses it. Independent of the terms query, so run both concurrently.
|
|
267
|
+
const [rows, counts] = await Promise.all([
|
|
268
|
+
termsQuery.execute(),
|
|
269
|
+
getVisibleTermCounts(def.name, def.collections),
|
|
270
|
+
]);
|
|
257
271
|
|
|
258
272
|
const flatTerms: TaxonomyTermRow[] = rows.map((row) => ({
|
|
259
273
|
id: row.id,
|
|
@@ -282,23 +296,24 @@ async function loadTaxonomyTerms(
|
|
|
282
296
|
}
|
|
283
297
|
|
|
284
298
|
/**
|
|
285
|
-
* Per-translation-group usage counts
|
|
286
|
-
*
|
|
287
|
-
* translation_group),
|
|
288
|
-
*
|
|
299
|
+
* Per-translation-group visible-usage counts for one taxonomy, in a single
|
|
300
|
+
* round-trip (see `fetchVisibleTermCounts`). Counts are locale-independent
|
|
301
|
+
* (the pivot stores translation_group), and the request-cached map is shared
|
|
302
|
+
* by every consumer in the render — the widget (`getTaxonomyTerms`) and the
|
|
303
|
+
* single-term page (`getTerm`) never issue separate count queries.
|
|
289
304
|
*/
|
|
290
|
-
function
|
|
291
|
-
|
|
305
|
+
function getVisibleTermCounts(
|
|
306
|
+
taxonomyName: string,
|
|
307
|
+
collections: string[],
|
|
308
|
+
): Promise<Map<string, number>> {
|
|
309
|
+
// The collection scope is part of the key: per-locale rows of the same def
|
|
310
|
+
// can drift in their declared collections, and a caller may pass a narrower
|
|
311
|
+
// scope. Identical inputs (the widget + term-page hot path) still share one
|
|
312
|
+
// entry.
|
|
313
|
+
const scope = [...new Set(collections)].toSorted().join(",");
|
|
314
|
+
return requestCached(`taxonomy-term-counts:${taxonomyName}:${scope}`, async () => {
|
|
292
315
|
const db = await getDb();
|
|
293
|
-
|
|
294
|
-
.selectFrom("content_taxonomies")
|
|
295
|
-
.select(["taxonomy_id"])
|
|
296
|
-
.select((eb) => eb.fn.count<number>("entry_id").as("count"))
|
|
297
|
-
.groupBy("taxonomy_id")
|
|
298
|
-
.execute();
|
|
299
|
-
const counts = new Map<string, number>();
|
|
300
|
-
for (const row of countsResult) counts.set(row.taxonomy_id, row.count);
|
|
301
|
-
return counts;
|
|
316
|
+
return fetchVisibleTermCounts(db, taxonomyName, collections);
|
|
302
317
|
});
|
|
303
318
|
}
|
|
304
319
|
|
|
@@ -313,13 +328,16 @@ export async function getTerm(
|
|
|
313
328
|
options: TaxonomyQueryOptions = {},
|
|
314
329
|
): Promise<TaxonomyTerm | null> {
|
|
315
330
|
const chain = resolveLocaleChain(options.locale);
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
//
|
|
331
|
+
// The def supplies the collections the visible count is scoped to. It is
|
|
332
|
+
// resolved before cachedQuery so the entry lives under each collection's
|
|
333
|
+
// content namespace — publishing or unpublishing an entry invalidates the
|
|
334
|
+
// embedded count (see termCountNamespaces).
|
|
335
|
+
const def = await getTaxonomyDef(taxonomyName, options);
|
|
336
|
+
const collections = def?.collections ?? [];
|
|
319
337
|
return cachedQuery({
|
|
320
|
-
namespace:
|
|
338
|
+
namespace: termCountNamespaces(collections),
|
|
321
339
|
key: `term:${taxonomyName}:${slug}:${chain.join(",")}`,
|
|
322
|
-
load: () => loadTerm(taxonomyName, slug, chain),
|
|
340
|
+
load: () => loadTerm(taxonomyName, slug, chain, collections),
|
|
323
341
|
});
|
|
324
342
|
}
|
|
325
343
|
|
|
@@ -327,6 +345,7 @@ async function loadTerm(
|
|
|
327
345
|
taxonomyName: string,
|
|
328
346
|
slug: string,
|
|
329
347
|
chain: string[],
|
|
348
|
+
collections: string[],
|
|
330
349
|
): Promise<TaxonomyTerm | null> {
|
|
331
350
|
const db = await getDb();
|
|
332
351
|
|
|
@@ -360,17 +379,15 @@ async function loadTerm(
|
|
|
360
379
|
const termLocale = row.locale;
|
|
361
380
|
if (termLocale) childrenQuery = childrenQuery.where("locale", "=", termLocale);
|
|
362
381
|
|
|
363
|
-
// The usage
|
|
364
|
-
// so run them concurrently to save a round trip on remote
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
.where("taxonomy_id", "=", row.translation_group ?? row.id)
|
|
370
|
-
.executeTakeFirst(),
|
|
382
|
+
// The visible-usage counts and children queries both depend only on the
|
|
383
|
+
// term row, so run them concurrently to save a round trip on remote
|
|
384
|
+
// databases. The counts map is request-cached per taxonomy — on a page
|
|
385
|
+
// that also renders the taxonomy widget it's a free Map lookup.
|
|
386
|
+
const [counts, childRows] = await Promise.all([
|
|
387
|
+
getVisibleTermCounts(taxonomyName, collections),
|
|
371
388
|
childrenQuery.execute(),
|
|
372
389
|
]);
|
|
373
|
-
const count =
|
|
390
|
+
const count = counts.get(row.translation_group ?? row.id) ?? 0;
|
|
374
391
|
|
|
375
392
|
const children = childRows.map<TaxonomyTerm>((child) => ({
|
|
376
393
|
id: child.id,
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared visible-usage counts for taxonomy terms (issue #581).
|
|
3
|
+
*
|
|
4
|
+
* `content_taxonomies` rows are written for every entry regardless of status
|
|
5
|
+
* and are never pruned on unpublish/trash, so counting the pivot directly
|
|
6
|
+
* inflates counts with drafts and soft-deleted entries. Every user-facing
|
|
7
|
+
* count (public widget, single-term page, admin term list) must instead count
|
|
8
|
+
* only entries that are currently visible on the public site:
|
|
9
|
+
* `status = 'published'` OR (`status = 'scheduled'` AND due), AND
|
|
10
|
+
* `deleted_at IS NULL` — via `buildStatusCondition`, which computes scheduled
|
|
11
|
+
* visibility at query time rather than trusting a literal status value.
|
|
12
|
+
*
|
|
13
|
+
* The public render path is latency-sensitive on D1, so per-collection counts
|
|
14
|
+
* are combined into a single round-trip with UNION ALL — one query per
|
|
15
|
+
* taxonomy, never one per collection.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { Kysely } from "kysely";
|
|
19
|
+
import { sql } from "kysely";
|
|
20
|
+
|
|
21
|
+
import { buildStatusCondition } from "../database/dialect-helpers.js";
|
|
22
|
+
import type { Database } from "../database/types.js";
|
|
23
|
+
import { validateIdentifier } from "../database/validate.js";
|
|
24
|
+
import { isMissingTableError } from "../utils/db-errors.js";
|
|
25
|
+
|
|
26
|
+
interface CountRow {
|
|
27
|
+
taxonomy_id: string;
|
|
28
|
+
count: number | string | bigint;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Per-collection count branch. `taxonomy_id` stores the term's
|
|
33
|
+
* translation_group, so results are keyed by group (locale-independent) and
|
|
34
|
+
* each assignment is counted once no matter how many locales the term has.
|
|
35
|
+
*
|
|
36
|
+
* Scoping to the taxonomy uses `translation_group IN (...)` rather than a
|
|
37
|
+
* join on `taxonomies.id` — the anchor row (id == group) can be deleted while
|
|
38
|
+
* sibling translations survive, and a plain join on `translation_group` would
|
|
39
|
+
* multiply counts by the number of locales.
|
|
40
|
+
*/
|
|
41
|
+
function collectionBranch(
|
|
42
|
+
db: Kysely<Database>,
|
|
43
|
+
taxonomyName: string,
|
|
44
|
+
collection: string,
|
|
45
|
+
): ReturnType<typeof sql> {
|
|
46
|
+
return sql`
|
|
47
|
+
SELECT ct.taxonomy_id AS taxonomy_id, COUNT(*) AS count
|
|
48
|
+
FROM content_taxonomies AS ct
|
|
49
|
+
INNER JOIN ${sql.ref(`ec_${collection}`)} AS e ON e.id = ct.entry_id
|
|
50
|
+
WHERE ct.collection = ${collection}
|
|
51
|
+
AND ct.taxonomy_id IN (SELECT translation_group FROM taxonomies WHERE name = ${taxonomyName})
|
|
52
|
+
AND ${buildStatusCondition(db, "published", "e")}
|
|
53
|
+
AND e.deleted_at IS NULL
|
|
54
|
+
GROUP BY ct.taxonomy_id`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function runCounts(
|
|
58
|
+
db: Kysely<Database>,
|
|
59
|
+
taxonomyName: string,
|
|
60
|
+
collections: string[],
|
|
61
|
+
): Promise<Map<string, number>> {
|
|
62
|
+
const branches = collections.map((collection) => collectionBranch(db, taxonomyName, collection));
|
|
63
|
+
const union = sql.join(branches, sql` UNION ALL `);
|
|
64
|
+
const result = await sql<CountRow>`
|
|
65
|
+
SELECT taxonomy_id, SUM(count) AS count
|
|
66
|
+
FROM (${union}) AS per_collection
|
|
67
|
+
GROUP BY taxonomy_id`.execute(db);
|
|
68
|
+
|
|
69
|
+
const counts = new Map<string, number>();
|
|
70
|
+
for (const row of result.rows) counts.set(row.taxonomy_id, Number(row.count));
|
|
71
|
+
return counts;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Count publicly-visible term assignments for one taxonomy, keyed by the
|
|
76
|
+
* term's translation_group (what `content_taxonomies.taxonomy_id` stores).
|
|
77
|
+
*
|
|
78
|
+
* Counts are scoped to the taxonomy's declared collections — pass
|
|
79
|
+
* `TaxonomyDef.collections` (`_emdash_taxonomy_defs.collections`). Collections
|
|
80
|
+
* whose `ec_*` table doesn't exist (pre-migration drift, a declared collection
|
|
81
|
+
* that was never created) are skipped, yielding a partial-but-correct count
|
|
82
|
+
* rather than a throw.
|
|
83
|
+
*
|
|
84
|
+
* One database round-trip for the whole taxonomy (UNION ALL across
|
|
85
|
+
* collections). Callers on the public render path should go through the
|
|
86
|
+
* request-cached wrapper in `taxonomies/index.ts` so a page rendering both the
|
|
87
|
+
* widget and a term detail shares one computation.
|
|
88
|
+
*/
|
|
89
|
+
export async function fetchVisibleTermCounts(
|
|
90
|
+
db: Kysely<Database>,
|
|
91
|
+
taxonomyName: string,
|
|
92
|
+
collections: string[],
|
|
93
|
+
): Promise<Map<string, number>> {
|
|
94
|
+
const unique = [...new Set(collections)];
|
|
95
|
+
for (const collection of unique) validateIdentifier(collection, "collection slug");
|
|
96
|
+
if (unique.length === 0) return new Map();
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
return await runCounts(db, taxonomyName, unique);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (!isMissingTableError(error)) throw error;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// A declared collection has no ec_* table — retry per collection so the
|
|
105
|
+
// existing tables still contribute (still scheduled-aware + deleted_at).
|
|
106
|
+
const counts = new Map<string, number>();
|
|
107
|
+
for (const collection of unique) {
|
|
108
|
+
try {
|
|
109
|
+
for (const [group, count] of await runCounts(db, taxonomyName, [collection])) {
|
|
110
|
+
counts.set(group, (counts.get(group) ?? 0) + count);
|
|
111
|
+
}
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (!isMissingTableError(error)) throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return counts;
|
|
117
|
+
}
|
package/src/virtual-modules.d.ts
CHANGED
|
@@ -46,33 +46,36 @@ export function createEditable(
|
|
|
46
46
|
...(options?.hasDraft && { hasDraft: true }),
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
return new Proxy(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
return new Proxy(
|
|
50
|
+
{},
|
|
51
|
+
{
|
|
52
|
+
get(_, prop) {
|
|
53
|
+
if (prop === "toJSON") return () => ({ "data-emdash-ref": JSON.stringify(base) });
|
|
54
|
+
if (typeof prop === "symbol") return undefined;
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
// data-emdash-ref access returns the entry-level string
|
|
57
|
+
if (prop === "data-emdash-ref") return JSON.stringify(base);
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
"data-emdash-ref": JSON.stringify({ ...base, field: String(prop) }),
|
|
60
|
-
} satisfies FieldAnnotation;
|
|
61
|
-
},
|
|
62
|
-
ownKeys() {
|
|
63
|
-
return ["data-emdash-ref"];
|
|
64
|
-
},
|
|
65
|
-
getOwnPropertyDescriptor(_, prop) {
|
|
66
|
-
if (prop === "data-emdash-ref") {
|
|
59
|
+
// Field-level: return a FieldAnnotation for the specific field
|
|
67
60
|
return {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
"data-emdash-ref": JSON.stringify({ ...base, field: String(prop) }),
|
|
62
|
+
} satisfies FieldAnnotation;
|
|
63
|
+
},
|
|
64
|
+
ownKeys() {
|
|
65
|
+
return ["data-emdash-ref"];
|
|
66
|
+
},
|
|
67
|
+
getOwnPropertyDescriptor(_, prop) {
|
|
68
|
+
if (prop === "data-emdash-ref") {
|
|
69
|
+
return {
|
|
70
|
+
configurable: true,
|
|
71
|
+
enumerable: true,
|
|
72
|
+
value: JSON.stringify(base),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
},
|
|
74
77
|
},
|
|
75
|
-
|
|
78
|
+
);
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
/**
|
|
@@ -80,19 +83,22 @@ export function createEditable(
|
|
|
80
83
|
* Spreading this produces no attributes.
|
|
81
84
|
*/
|
|
82
85
|
export function createNoop(): EditProxy {
|
|
83
|
-
return new Proxy(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
return new Proxy(
|
|
87
|
+
{},
|
|
88
|
+
{
|
|
89
|
+
get(_, prop) {
|
|
90
|
+
if (typeof prop === "symbol") return undefined;
|
|
91
|
+
// All property access returns undefined in noop mode
|
|
92
|
+
return undefined;
|
|
93
|
+
},
|
|
94
|
+
ownKeys() {
|
|
95
|
+
return [];
|
|
96
|
+
},
|
|
97
|
+
getOwnPropertyDescriptor() {
|
|
98
|
+
return undefined;
|
|
99
|
+
},
|
|
94
100
|
},
|
|
95
|
-
|
|
101
|
+
);
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
/**
|