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
|
@@ -46,6 +46,7 @@ export type LoadContentMediaUsageSnapshotsResult =
|
|
|
46
46
|
| "DRAFT_REVISION_MISMATCH"
|
|
47
47
|
| "DRAFT_REVISION_INVALID";
|
|
48
48
|
source?: MediaUsageSourceInput;
|
|
49
|
+
snapshots?: ContentMediaUsageSnapshot[];
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
export interface ContentMediaUsageSnapshot {
|
|
@@ -116,6 +117,7 @@ export async function loadContentMediaUsageSnapshots(
|
|
|
116
117
|
success: false,
|
|
117
118
|
error: "DRAFT_REVISION_NOT_FOUND",
|
|
118
119
|
source: attemptedDraftSource,
|
|
120
|
+
snapshots,
|
|
119
121
|
};
|
|
120
122
|
}
|
|
121
123
|
if (!revisionResult.success) {
|
|
@@ -123,6 +125,7 @@ export async function loadContentMediaUsageSnapshots(
|
|
|
123
125
|
success: false,
|
|
124
126
|
error: "DRAFT_REVISION_INVALID",
|
|
125
127
|
source: attemptedDraftSource,
|
|
128
|
+
snapshots,
|
|
126
129
|
};
|
|
127
130
|
}
|
|
128
131
|
const revision = revisionResult.revision;
|
|
@@ -131,6 +134,7 @@ export async function loadContentMediaUsageSnapshots(
|
|
|
131
134
|
success: false,
|
|
132
135
|
error: "DRAFT_REVISION_MISMATCH",
|
|
133
136
|
source: attemptedDraftSource,
|
|
137
|
+
snapshots,
|
|
134
138
|
};
|
|
135
139
|
}
|
|
136
140
|
|
package/src/plugins/context.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { MediaRepository } from "../database/repositories/media.js";
|
|
|
13
13
|
import { OptionsRepository } from "../database/repositories/options.js";
|
|
14
14
|
import { PluginStorageRepository } from "../database/repositories/plugin-storage.js";
|
|
15
15
|
import { SeoRepository } from "../database/repositories/seo.js";
|
|
16
|
+
import { TaxonomyRepository, type Taxonomy } from "../database/repositories/taxonomy.js";
|
|
16
17
|
import { UserRepository } from "../database/repositories/user.js";
|
|
17
18
|
import { withTransaction } from "../database/transaction.js";
|
|
18
19
|
import type { Database } from "../database/types.js";
|
|
@@ -52,6 +53,10 @@ import type {
|
|
|
52
53
|
QueryOptions,
|
|
53
54
|
ContentListOptions,
|
|
54
55
|
MediaListOptions,
|
|
56
|
+
TaxonomyAccess,
|
|
57
|
+
TaxonomyDefInfo,
|
|
58
|
+
TaxonomyTermInfo,
|
|
59
|
+
TaxonomyReadOptions,
|
|
55
60
|
} from "./types.js";
|
|
56
61
|
|
|
57
62
|
// =============================================================================
|
|
@@ -194,6 +199,37 @@ async function assertSeoEnabled(
|
|
|
194
199
|
return hasSeo;
|
|
195
200
|
}
|
|
196
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Parse the `collections` JSON column into a string array (`[]` on anything
|
|
204
|
+
* else). Mirrors the guards in the Cloudflare/workerd bridges so an
|
|
205
|
+
* in-process plugin degrades on malformed data instead of crashing.
|
|
206
|
+
*/
|
|
207
|
+
function parseCollectionsColumn(value: string | null): string[] {
|
|
208
|
+
if (!value) return [];
|
|
209
|
+
try {
|
|
210
|
+
const parsed: unknown = JSON.parse(value);
|
|
211
|
+
return Array.isArray(parsed)
|
|
212
|
+
? parsed.filter((item): item is string => typeof item === "string")
|
|
213
|
+
: [];
|
|
214
|
+
} catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Map a repository `Taxonomy` row to the plugin-facing term shape. */
|
|
220
|
+
function taxonomyToTermInfo(term: Taxonomy): TaxonomyTermInfo {
|
|
221
|
+
return {
|
|
222
|
+
id: term.id,
|
|
223
|
+
taxonomy: term.name,
|
|
224
|
+
slug: term.slug,
|
|
225
|
+
label: term.label,
|
|
226
|
+
parentId: term.parentId,
|
|
227
|
+
data: term.data,
|
|
228
|
+
locale: term.locale,
|
|
229
|
+
translationGroup: term.translationGroup,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
197
233
|
/**
|
|
198
234
|
* Create read-only content access
|
|
199
235
|
*/
|
|
@@ -278,6 +314,48 @@ export function createContentAccess(db: Kysely<Database>): ContentAccess {
|
|
|
278
314
|
};
|
|
279
315
|
}
|
|
280
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Create read-only taxonomy access (gated on `taxonomies:read`).
|
|
319
|
+
*/
|
|
320
|
+
export function createTaxonomyAccess(db: Kysely<Database>): TaxonomyAccess {
|
|
321
|
+
const taxonomyRepo = new TaxonomyRepository(db);
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
async getAll(options?: TaxonomyReadOptions): Promise<TaxonomyDefInfo[]> {
|
|
325
|
+
let query = db.selectFrom("_emdash_taxonomy_defs").selectAll();
|
|
326
|
+
if (options?.locale !== undefined) query = query.where("locale", "=", options.locale);
|
|
327
|
+
const rows = await query.orderBy("name", "asc").execute();
|
|
328
|
+
return rows.map((row) => ({
|
|
329
|
+
name: row.name,
|
|
330
|
+
label: row.label,
|
|
331
|
+
labelSingular: row.label_singular,
|
|
332
|
+
hierarchical: row.hierarchical === 1,
|
|
333
|
+
collections: parseCollectionsColumn(row.collections),
|
|
334
|
+
locale: row.locale,
|
|
335
|
+
}));
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
async getTerms(taxonomy: string, options?: TaxonomyReadOptions): Promise<TaxonomyTermInfo[]> {
|
|
339
|
+
const terms = await taxonomyRepo.findByName(taxonomy, { locale: options?.locale });
|
|
340
|
+
return terms.map(taxonomyToTermInfo);
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
async getEntryTerms(
|
|
344
|
+
collection: string,
|
|
345
|
+
entryId: string,
|
|
346
|
+
options?: TaxonomyReadOptions & { taxonomy?: string },
|
|
347
|
+
): Promise<TaxonomyTermInfo[]> {
|
|
348
|
+
const terms = await taxonomyRepo.getTermsForEntry(
|
|
349
|
+
collection,
|
|
350
|
+
entryId,
|
|
351
|
+
options?.taxonomy,
|
|
352
|
+
options?.locale,
|
|
353
|
+
);
|
|
354
|
+
return terms.map(taxonomyToTermInfo);
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
281
359
|
/**
|
|
282
360
|
* Create full content access with write operations.
|
|
283
361
|
*
|
|
@@ -1015,6 +1093,12 @@ export class PluginContextFactory {
|
|
|
1015
1093
|
content = createContentAccess(db);
|
|
1016
1094
|
}
|
|
1017
1095
|
|
|
1096
|
+
// Capability-gated: taxonomies (read-only)
|
|
1097
|
+
let taxonomies: TaxonomyAccess | undefined;
|
|
1098
|
+
if (capabilities.has("taxonomies:read")) {
|
|
1099
|
+
taxonomies = createTaxonomyAccess(db);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1018
1102
|
// Capability-gated: media
|
|
1019
1103
|
// `upload()` only needs `storage`; `getUploadUrl()` is derived from
|
|
1020
1104
|
// storage when no explicit provider is wired. Granting write access on
|
|
@@ -1078,6 +1162,7 @@ export class PluginContextFactory {
|
|
|
1078
1162
|
storage,
|
|
1079
1163
|
kv,
|
|
1080
1164
|
content,
|
|
1165
|
+
taxonomies,
|
|
1081
1166
|
media,
|
|
1082
1167
|
http,
|
|
1083
1168
|
log,
|
package/src/plugins/index.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const CURRENT_PLUGIN_CAPABILITIES = [
|
|
|
27
27
|
"network:request:unrestricted",
|
|
28
28
|
"content:read",
|
|
29
29
|
"content:write",
|
|
30
|
+
"taxonomies:read",
|
|
30
31
|
"media:read",
|
|
31
32
|
"media:write",
|
|
32
33
|
"users:read",
|
|
@@ -246,6 +247,7 @@ const declaredAccessSchema = z.object({
|
|
|
246
247
|
content: z
|
|
247
248
|
.object({ read: accessConstraints.optional(), write: accessConstraints.optional() })
|
|
248
249
|
.optional(),
|
|
250
|
+
taxonomies: z.object({ read: accessConstraints.optional() }).optional(),
|
|
249
251
|
media: z
|
|
250
252
|
.object({ read: accessConstraints.optional(), write: accessConstraints.optional() })
|
|
251
253
|
.optional(),
|
package/src/plugins/types.ts
CHANGED
|
@@ -244,6 +244,45 @@ export type ContentWriteInput = Record<string, unknown> & {
|
|
|
244
244
|
seo?: ContentItemSeoInput;
|
|
245
245
|
};
|
|
246
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Taxonomy definition returned from the taxonomy API (e.g. "category", "tag").
|
|
249
|
+
*/
|
|
250
|
+
export interface TaxonomyDefInfo {
|
|
251
|
+
name: string;
|
|
252
|
+
label: string;
|
|
253
|
+
labelSingular: string | null;
|
|
254
|
+
hierarchical: boolean;
|
|
255
|
+
/** Collections this taxonomy is attached to (e.g. `["posts"]`). */
|
|
256
|
+
collections: string[];
|
|
257
|
+
locale: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Taxonomy term returned from the taxonomy API. Flat shape — for hierarchical
|
|
262
|
+
* taxonomies the tree is reconstructed via `parentId` (which stores the
|
|
263
|
+
* parent's locale-agnostic `translationGroup`).
|
|
264
|
+
*/
|
|
265
|
+
export interface TaxonomyTermInfo {
|
|
266
|
+
id: string;
|
|
267
|
+
/** Taxonomy name this term belongs to (e.g. "category"). */
|
|
268
|
+
taxonomy: string;
|
|
269
|
+
slug: string;
|
|
270
|
+
label: string;
|
|
271
|
+
parentId: string | null;
|
|
272
|
+
/** Term metadata as edited in the admin (`description` etc.). */
|
|
273
|
+
data: Record<string, unknown> | null;
|
|
274
|
+
locale: string;
|
|
275
|
+
translationGroup: string | null;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Options accepted by taxonomy read operations. Omitting `locale` returns
|
|
280
|
+
* rows for every locale.
|
|
281
|
+
*/
|
|
282
|
+
export interface TaxonomyReadOptions {
|
|
283
|
+
locale?: string;
|
|
284
|
+
}
|
|
285
|
+
|
|
247
286
|
/**
|
|
248
287
|
* Content access interface - capability-gated
|
|
249
288
|
*/
|
|
@@ -258,6 +297,23 @@ export interface ContentAccess {
|
|
|
258
297
|
delete?(collection: string, id: string): Promise<boolean>;
|
|
259
298
|
}
|
|
260
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Taxonomy access interface — capability-gated on `taxonomies:read`.
|
|
302
|
+
* Read-only: there is no plugin-facing taxonomy write API.
|
|
303
|
+
*/
|
|
304
|
+
export interface TaxonomyAccess {
|
|
305
|
+
/** List taxonomy definitions. */
|
|
306
|
+
getAll(options?: TaxonomyReadOptions): Promise<TaxonomyDefInfo[]>;
|
|
307
|
+
/** All terms of a taxonomy, ordered by label. */
|
|
308
|
+
getTerms(taxonomy: string, options?: TaxonomyReadOptions): Promise<TaxonomyTermInfo[]>;
|
|
309
|
+
/** Terms assigned to a content entry, optionally scoped to one taxonomy. */
|
|
310
|
+
getEntryTerms(
|
|
311
|
+
collection: string,
|
|
312
|
+
entryId: string,
|
|
313
|
+
options?: TaxonomyReadOptions & { taxonomy?: string },
|
|
314
|
+
): Promise<TaxonomyTermInfo[]>;
|
|
315
|
+
}
|
|
316
|
+
|
|
261
317
|
/**
|
|
262
318
|
* Full content access with write operations
|
|
263
319
|
*/
|
|
@@ -413,6 +469,9 @@ export interface PluginContext<TStorage extends PluginStorageConfig = PluginStor
|
|
|
413
469
|
/** Content access - only if read:content or write:content capability */
|
|
414
470
|
content?: ContentAccess | ContentAccessWithWrite;
|
|
415
471
|
|
|
472
|
+
/** Taxonomy access (read-only) - only if taxonomies:read capability */
|
|
473
|
+
taxonomies?: TaxonomyAccess;
|
|
474
|
+
|
|
416
475
|
/** Media access - only if read:media or write:media capability */
|
|
417
476
|
media?: MediaAccess | MediaAccessWithWrite;
|
|
418
477
|
|
|
@@ -627,7 +627,7 @@ export class BylineSchemaRegistry {
|
|
|
627
627
|
// payload silently. Today's `BylineFieldValidation` is `{ options? }`
|
|
628
628
|
// only, so this branch is a pass-through; left explicit for clarity.
|
|
629
629
|
const { options: _drop, ...rest } = validation;
|
|
630
|
-
return Object.keys(rest).length === 0 ? null :
|
|
630
|
+
return Object.keys(rest).length === 0 ? null : rest;
|
|
631
631
|
}
|
|
632
632
|
}
|
|
633
633
|
|
|
@@ -355,6 +355,40 @@ export class FTSManager {
|
|
|
355
355
|
return fields.map((f) => f.slug);
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Whether a collection has a user-defined `title` field.
|
|
360
|
+
*
|
|
361
|
+
* `title` is not a system column on `ec_*` tables -- it exists only when a
|
|
362
|
+
* collection defines a field with slug `title`. Search and suggestion SQL
|
|
363
|
+
* that selects `c.title` must check this first; otherwise collections
|
|
364
|
+
* without a title field raise "no such column: c.title" (#1178).
|
|
365
|
+
*/
|
|
366
|
+
async hasTitleColumn(collectionSlug: string): Promise<boolean> {
|
|
367
|
+
const withTitle = await this.getCollectionsWithTitleColumn([collectionSlug]);
|
|
368
|
+
return withTitle.has(collectionSlug);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Bulk variant of `hasTitleColumn()`: which of the given collections have
|
|
373
|
+
* a user-defined `title` field. One query instead of one `hasTitleColumn`
|
|
374
|
+
* round-trip pair per collection -- callers that check this once per
|
|
375
|
+
* collection in a loop (multi-collection search, suggestions) should use
|
|
376
|
+
* this instead (AGENTS.md: "one query beats two").
|
|
377
|
+
*/
|
|
378
|
+
async getCollectionsWithTitleColumn(collectionSlugs: string[]): Promise<Set<string>> {
|
|
379
|
+
if (collectionSlugs.length === 0) return new Set();
|
|
380
|
+
|
|
381
|
+
const rows = await this.db
|
|
382
|
+
.selectFrom("_emdash_fields as f")
|
|
383
|
+
.innerJoin("_emdash_collections as c", "c.id", "f.collection_id")
|
|
384
|
+
.select(["c.slug as collection_slug"])
|
|
385
|
+
.where("f.slug", "=", "title")
|
|
386
|
+
.execute();
|
|
387
|
+
|
|
388
|
+
const withTitle = new Set(rows.map((r) => r.collection_slug));
|
|
389
|
+
return new Set(collectionSlugs.filter((slug) => withTitle.has(slug)));
|
|
390
|
+
}
|
|
391
|
+
|
|
358
392
|
/**
|
|
359
393
|
* Enable search for a collection.
|
|
360
394
|
*
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FTS5 match-expression builder for structured (non-user-syntax) queries.
|
|
3
|
+
*
|
|
4
|
+
* Unlike `escapeQuery` in `query.ts` (which powers the public search API and
|
|
5
|
+
* deliberately passes through FTS5 operators like AND/OR/NOT), this builder
|
|
6
|
+
* treats the input as plain words: every term is double-quoted with interior
|
|
7
|
+
* quotes escaped, so the result can never produce an FTS5 syntax error. Used
|
|
8
|
+
* by the admin content-list filter, where the input is a filter box, not a
|
|
9
|
+
* search-syntax field.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const WHITESPACE_RE = /\s+/;
|
|
13
|
+
const DOUBLE_QUOTE_RE = /"/g;
|
|
14
|
+
const GLOB_SPECIAL_RE = /[[\]*?]/g;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Build a prefix-matching FTS5 MATCH expression from free-form input.
|
|
18
|
+
*
|
|
19
|
+
* `hello wor` becomes `"hello"* "wor"*` — implicit AND with per-term prefix
|
|
20
|
+
* matching. Returns `""` when the input contains no usable terms; callers
|
|
21
|
+
* must fall back to their non-FTS path in that case.
|
|
22
|
+
*/
|
|
23
|
+
export function buildFtsPrefixMatch(input: string): string {
|
|
24
|
+
const terms = input
|
|
25
|
+
.trim()
|
|
26
|
+
.split(WHITESPACE_RE)
|
|
27
|
+
.map((term) => term.replace(DOUBLE_QUOTE_RE, '""'))
|
|
28
|
+
.filter((term) => term.length > 0);
|
|
29
|
+
|
|
30
|
+
if (terms.length === 0) return "";
|
|
31
|
+
return terms.map((term) => `"${term}"*`).join(" ");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build a GLOB prefix pattern from free-form input, treating GLOB
|
|
36
|
+
* metacharacters (`* ? [ ]`) literally by wrapping each in a character
|
|
37
|
+
* class (GLOB has no ESCAPE clause).
|
|
38
|
+
*
|
|
39
|
+
* GLOB (unlike default LIKE) is case-sensitive, so with a lowercased
|
|
40
|
+
* pattern it matches slugs (lowercase by construction) while staying
|
|
41
|
+
* servable by the ordinary BINARY-collated slug index — SQLite's GLOB
|
|
42
|
+
* optimization turns a `prefix*` pattern into an index range scan.
|
|
43
|
+
*/
|
|
44
|
+
export function buildSlugGlobPrefix(input: string): string {
|
|
45
|
+
const escaped = input
|
|
46
|
+
.trim()
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(GLOB_SPECIAL_RE, (c) => `[${c}]`);
|
|
49
|
+
return `${escaped}*`;
|
|
50
|
+
}
|
package/src/search/query.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { Kysely } from "kysely";
|
|
8
8
|
import { sql } from "kysely";
|
|
9
9
|
|
|
10
|
+
import { encodeCursor, decodeCursor, InvalidCursorError } from "../database/repositories/types.js";
|
|
10
11
|
import type { Database } from "../database/types.js";
|
|
11
12
|
import { validateIdentifier } from "../database/validate.js";
|
|
12
13
|
import { getDb } from "../loader.js";
|
|
@@ -21,6 +22,44 @@ import type {
|
|
|
21
22
|
SearchStats,
|
|
22
23
|
} from "./types.js";
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Marker stored in the `id` slot of a search pagination cursor.
|
|
27
|
+
*
|
|
28
|
+
* Search results are merged from per-collection FTS queries and re-sorted by
|
|
29
|
+
* score, so there is no single stable keyset column to encode (the way
|
|
30
|
+
* `getEmDashCollection` encodes `(orderValue, id)`). We page over the merged,
|
|
31
|
+
* score-sorted set by offset instead, carried as the cursor's `orderValue`.
|
|
32
|
+
* Reusing `encodeCursor`/`decodeCursor` keeps the opaque base64-JSON shape and
|
|
33
|
+
* the `InvalidCursorError` handling consistent with the rest of the API.
|
|
34
|
+
*/
|
|
35
|
+
const SEARCH_CURSOR_MARKER = "search";
|
|
36
|
+
|
|
37
|
+
/** Encode the next-page offset into an opaque search cursor. */
|
|
38
|
+
function encodeSearchCursor(offset: number): string {
|
|
39
|
+
return encodeCursor(String(offset), SEARCH_CURSOR_MARKER);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Decode a search cursor back to its offset. Throws `InvalidCursorError` for a
|
|
44
|
+
* malformed cursor or one that doesn't carry a non-negative integer offset, so
|
|
45
|
+
* a client pagination bug surfaces immediately rather than silently restarting
|
|
46
|
+
* from the first page.
|
|
47
|
+
*/
|
|
48
|
+
/** Upper bound on a decoded search offset, to cap the per-collection row fetch a forged cursor can trigger. */
|
|
49
|
+
const MAX_SEARCH_OFFSET = 10_000;
|
|
50
|
+
|
|
51
|
+
function decodeSearchOffset(cursor: string): number {
|
|
52
|
+
const { orderValue, id } = decodeCursor(cursor);
|
|
53
|
+
if (id !== SEARCH_CURSOR_MARKER) {
|
|
54
|
+
throw new InvalidCursorError(cursor);
|
|
55
|
+
}
|
|
56
|
+
const offset = Number(orderValue);
|
|
57
|
+
if (!Number.isInteger(offset) || offset < 0 || offset > MAX_SEARCH_OFFSET) {
|
|
58
|
+
throw new InvalidCursorError(cursor);
|
|
59
|
+
}
|
|
60
|
+
return offset;
|
|
61
|
+
}
|
|
62
|
+
|
|
24
63
|
/** Pattern to split on whitespace for query term extraction */
|
|
25
64
|
const WHITESPACE_SPLIT_PATTERN = /\s+/;
|
|
26
65
|
const FTS_OPERATORS_PATTERN = /\b(AND|OR|NOT|NEAR)\b/i;
|
|
@@ -86,6 +125,7 @@ export async function searchWithDb(
|
|
|
86
125
|
const ftsManager = new FTSManager(db);
|
|
87
126
|
const limit = options.limit ?? 20;
|
|
88
127
|
const status = options.status ?? "published";
|
|
128
|
+
const offset = options.cursor ? decodeSearchOffset(options.cursor) : 0;
|
|
89
129
|
|
|
90
130
|
// Get searchable collections
|
|
91
131
|
let collections = options.collections;
|
|
@@ -97,8 +137,15 @@ export async function searchWithDb(
|
|
|
97
137
|
return { items: [] };
|
|
98
138
|
}
|
|
99
139
|
|
|
140
|
+
// To rank the merged window [offset, offset + limit) correctly, each
|
|
141
|
+
// collection must contribute its own top (offset + limit) rows — in the
|
|
142
|
+
// worst case the entire window comes from one collection. The extra +1
|
|
143
|
+
// row detects whether a further page exists.
|
|
144
|
+
const perCollectionLimit = offset + limit + 1;
|
|
145
|
+
|
|
100
146
|
// Search each collection and merge results
|
|
101
147
|
const allResults: SearchResult[] = [];
|
|
148
|
+
const titleColumns = await ftsManager.getCollectionsWithTitleColumn(collections);
|
|
102
149
|
|
|
103
150
|
for (const collection of collections) {
|
|
104
151
|
const config = await ftsManager.getSearchConfig(collection);
|
|
@@ -113,9 +160,10 @@ export async function searchWithDb(
|
|
|
113
160
|
{
|
|
114
161
|
status,
|
|
115
162
|
locale: options.locale,
|
|
116
|
-
limit:
|
|
163
|
+
limit: perCollectionLimit,
|
|
117
164
|
},
|
|
118
165
|
config.weights,
|
|
166
|
+
titleColumns.has(collection),
|
|
119
167
|
);
|
|
120
168
|
|
|
121
169
|
allResults.push(...collectionResults);
|
|
@@ -124,10 +172,13 @@ export async function searchWithDb(
|
|
|
124
172
|
// Sort by score descending
|
|
125
173
|
allResults.sort((a, b) => b.score - a.score);
|
|
126
174
|
|
|
127
|
-
//
|
|
128
|
-
|
|
175
|
+
// Page the merged set by offset. A nextCursor is issued only when at least
|
|
176
|
+
// one result exists past this page.
|
|
177
|
+
const items = allResults.slice(offset, offset + limit);
|
|
178
|
+
const hasMore = allResults.length > offset + limit;
|
|
179
|
+
const nextCursor = hasMore ? encodeSearchCursor(offset + limit) : undefined;
|
|
129
180
|
|
|
130
|
-
return { items };
|
|
181
|
+
return { items, nextCursor };
|
|
131
182
|
}
|
|
132
183
|
|
|
133
184
|
/**
|
|
@@ -159,9 +210,25 @@ export async function searchCollection(
|
|
|
159
210
|
return { items: [] };
|
|
160
211
|
}
|
|
161
212
|
|
|
162
|
-
const
|
|
213
|
+
const limit = options.limit ?? 20;
|
|
214
|
+
const offset = options.cursor ? decodeSearchOffset(options.cursor) : 0;
|
|
215
|
+
|
|
216
|
+
// Over-fetch the [offset, offset + limit) window plus one row to detect a
|
|
217
|
+
// further page, then slice. Keeps the FTS SQL (LIMIT-only) unchanged and
|
|
218
|
+
// the cursor contract identical to the cross-collection path.
|
|
219
|
+
const fetched = await searchSingleCollection(
|
|
220
|
+
db,
|
|
221
|
+
collection,
|
|
222
|
+
query,
|
|
223
|
+
{ status: options.status, locale: options.locale, limit: offset + limit + 1 },
|
|
224
|
+
config.weights,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const items = fetched.slice(offset, offset + limit);
|
|
228
|
+
const hasMore = fetched.length > offset + limit;
|
|
229
|
+
const nextCursor = hasMore ? encodeSearchCursor(offset + limit) : undefined;
|
|
163
230
|
|
|
164
|
-
return { items };
|
|
231
|
+
return { items, nextCursor };
|
|
165
232
|
}
|
|
166
233
|
|
|
167
234
|
/**
|
|
@@ -173,6 +240,7 @@ async function searchSingleCollection(
|
|
|
173
240
|
query: string,
|
|
174
241
|
options: CollectionSearchOptions,
|
|
175
242
|
weights?: Record<string, number>,
|
|
243
|
+
hasTitle?: boolean,
|
|
176
244
|
): Promise<SearchResult[]> {
|
|
177
245
|
// Validate before any raw SQL interpolation
|
|
178
246
|
validateIdentifier(collection, "collection slug");
|
|
@@ -198,6 +266,14 @@ async function searchSingleCollection(
|
|
|
198
266
|
// Get searchable fields for snippet generation
|
|
199
267
|
const searchableFields = await ftsManager.getSearchableFields(collection);
|
|
200
268
|
|
|
269
|
+
// `title` is an optional user-defined field, not a system column. Only
|
|
270
|
+
// select it when the collection actually has one; otherwise the query
|
|
271
|
+
// errors with "no such column: c.title" (#1178). Multi-collection callers
|
|
272
|
+
// precompute this in bulk and pass it in; single-collection callers fall
|
|
273
|
+
// back to the per-collection check.
|
|
274
|
+
const collectionHasTitle = hasTitle ?? (await ftsManager.hasTitleColumn(collection));
|
|
275
|
+
const titleExpr = collectionHasTitle ? sql`c.title` : sql`NULL`;
|
|
276
|
+
|
|
201
277
|
// Build weight string for bm25 if weights provided
|
|
202
278
|
// Format: bm25(table, weight1, weight2, ...)
|
|
203
279
|
// First two weights are for 'id' and 'locale' columns (UNINDEXED, so 0)
|
|
@@ -225,11 +301,11 @@ async function searchSingleCollection(
|
|
|
225
301
|
snippet: string | null;
|
|
226
302
|
score: number;
|
|
227
303
|
}>`
|
|
228
|
-
SELECT
|
|
304
|
+
SELECT
|
|
229
305
|
c.id,
|
|
230
306
|
c.slug,
|
|
231
307
|
c.locale,
|
|
232
|
-
|
|
308
|
+
${titleExpr} as title,
|
|
233
309
|
snippet("${sql.raw(ftsTable)}", 2, '<mark>', '</mark>', '...', 32) as snippet,
|
|
234
310
|
${sql.raw(bm25Expr)} as score
|
|
235
311
|
FROM "${sql.raw(ftsTable)}" f
|
|
@@ -334,14 +410,23 @@ export async function getSuggestions(
|
|
|
334
410
|
}
|
|
335
411
|
|
|
336
412
|
const suggestions: Suggestion[] = [];
|
|
413
|
+
const ftsManager = new FTSManager(db);
|
|
414
|
+
const titleColumns = await ftsManager.getCollectionsWithTitleColumn(collections);
|
|
337
415
|
|
|
338
416
|
for (const collection of collections) {
|
|
339
|
-
const ftsManager = new FTSManager(db);
|
|
340
417
|
const config = await ftsManager.getSearchConfig(collection);
|
|
341
418
|
if (!config?.enabled) {
|
|
342
419
|
continue;
|
|
343
420
|
}
|
|
344
421
|
|
|
422
|
+
// Suggestions are title-based (Suggestion.title is required and the
|
|
423
|
+
// query filters on `c.title IS NOT NULL`). Collections without a
|
|
424
|
+
// `title` field can't produce one, and selecting `c.title` would
|
|
425
|
+
// error, so skip them. See #1178.
|
|
426
|
+
if (!titleColumns.has(collection)) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
|
|
345
430
|
// Validate before raw SQL interpolation
|
|
346
431
|
validateIdentifier(collection, "collection slug");
|
|
347
432
|
|