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
package/src/emdash-runtime.ts
CHANGED
|
@@ -22,7 +22,11 @@ import { getAuthMode } from "./auth/mode.js";
|
|
|
22
22
|
import { getTrustedProxyHeaders } from "./auth/trusted-proxy.js";
|
|
23
23
|
import { isSqlite } from "./database/dialect-helpers.js";
|
|
24
24
|
import { kyselyLogOption } from "./database/instrumentation.js";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
ConcurrentMigrationTimeoutError,
|
|
27
|
+
MIGRATION_RACE_WAIT_MS,
|
|
28
|
+
runMigrations,
|
|
29
|
+
} from "./database/migrations/runner.js";
|
|
26
30
|
import { RevisionRepository } from "./database/repositories/revision.js";
|
|
27
31
|
import type {
|
|
28
32
|
ContentItem as ContentItemInternal,
|
|
@@ -385,18 +389,42 @@ const DB_HOLDER_KEY = Symbol.for("emdash:db-cache");
|
|
|
385
389
|
interface DbHolder {
|
|
386
390
|
cache: Map<string, Kysely<Database>>;
|
|
387
391
|
lock: InitLock;
|
|
392
|
+
/**
|
|
393
|
+
* Recent migration failures, keyed like `cache`. A failed migration is
|
|
394
|
+
* near-certain to fail again immediately (schema conflict, broken
|
|
395
|
+
* migration), and without this every request in a warm isolate would
|
|
396
|
+
* re-attempt it — on Workers with Postgres that stampedes the database
|
|
397
|
+
* through the migration advisory lock (#1744). Entries expire after
|
|
398
|
+
* DB_INIT_FAILURE_BACKOFF_MS; a successful init clears them.
|
|
399
|
+
*/
|
|
400
|
+
failures: Map<string, { at: number; message: string }>;
|
|
388
401
|
}
|
|
389
402
|
const globalSymbolStore = globalThis as Record<symbol, unknown>;
|
|
390
403
|
function getDbHolder(): DbHolder {
|
|
391
404
|
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot, written only below
|
|
392
405
|
let holder = globalSymbolStore[DB_HOLDER_KEY] as DbHolder | undefined;
|
|
393
406
|
if (!holder) {
|
|
394
|
-
holder = {
|
|
407
|
+
holder = {
|
|
408
|
+
cache: new Map<string, Kysely<Database>>(),
|
|
409
|
+
lock: createInitLock(),
|
|
410
|
+
failures: new Map(),
|
|
411
|
+
};
|
|
395
412
|
globalSymbolStore[DB_HOLDER_KEY] = holder;
|
|
396
413
|
}
|
|
414
|
+
// A holder created by an older copy of this module (dev-server HMR keeps
|
|
415
|
+
// globalThis across reloads) may predate the failures map.
|
|
416
|
+
holder.failures ??= new Map();
|
|
397
417
|
return holder;
|
|
398
418
|
}
|
|
399
419
|
|
|
420
|
+
/**
|
|
421
|
+
* After a database init fails (migrations threw), skip re-attempting for
|
|
422
|
+
* this long. Cold isolates still get one attempt each, so a transient
|
|
423
|
+
* failure heals on its own; a persistently failing migration is retried at
|
|
424
|
+
* most once per backoff window per isolate instead of on every request.
|
|
425
|
+
*/
|
|
426
|
+
const DB_INIT_FAILURE_BACKOFF_MS = 30_000;
|
|
427
|
+
|
|
400
428
|
/**
|
|
401
429
|
* Auto-seed runs at most once per isolate per database. Its lock + "done" set
|
|
402
430
|
* live on globalThis (same bundler-duplication reasoning as the db cache) so a
|
|
@@ -1623,14 +1651,52 @@ export class EmDashRuntime {
|
|
|
1623
1651
|
// owner's init still completes and populates the cache. Net: a stale
|
|
1624
1652
|
// lock is reclaimed after a deadline.
|
|
1625
1653
|
const holder = getDbHolder();
|
|
1654
|
+
|
|
1655
|
+
const throwIfBackingOff = () => {
|
|
1656
|
+
const failure = holder.failures.get(cacheKey);
|
|
1657
|
+
if (!failure) return;
|
|
1658
|
+
if (Date.now() - failure.at < DB_INIT_FAILURE_BACKOFF_MS) {
|
|
1659
|
+
throw new Error(
|
|
1660
|
+
`Database initialization is backing off after a recent migration failure: ${failure.message}`,
|
|
1661
|
+
);
|
|
1662
|
+
}
|
|
1663
|
+
// Expired — drop it so the map only ever holds active backoffs.
|
|
1664
|
+
holder.failures.delete(cacheKey);
|
|
1665
|
+
};
|
|
1666
|
+
throwIfBackingOff();
|
|
1667
|
+
|
|
1626
1668
|
return initWithLock(
|
|
1627
1669
|
holder.lock,
|
|
1628
1670
|
() => holder.cache.get(cacheKey),
|
|
1629
1671
|
async (isCurrentClaim) => {
|
|
1672
|
+
// Re-check under the lock: a request that entered the wait loop
|
|
1673
|
+
// before the failure was recorded must not immediately re-run
|
|
1674
|
+
// the failing migration when the lock frees up.
|
|
1675
|
+
throwIfBackingOff();
|
|
1676
|
+
|
|
1630
1677
|
const dialect = deps.createDialect(dbConfig.config);
|
|
1631
1678
|
const db = new Kysely<Database>({ dialect, log: kyselyLogOption() });
|
|
1632
1679
|
|
|
1633
|
-
|
|
1680
|
+
try {
|
|
1681
|
+
await runMigrations(db);
|
|
1682
|
+
} catch (error) {
|
|
1683
|
+
// Timing out behind another instance's in-flight migrations
|
|
1684
|
+
// is not a failure of OUR migration — the holder may just be
|
|
1685
|
+
// slow. Don't back off for it: the next request waits again
|
|
1686
|
+
// and init recovers the moment the holder finishes.
|
|
1687
|
+
if (!(error instanceof ConcurrentMigrationTimeoutError)) {
|
|
1688
|
+
holder.failures.set(cacheKey, {
|
|
1689
|
+
at: Date.now(),
|
|
1690
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
// Every attempt builds a fresh dialect/pool; close it or each
|
|
1694
|
+
// failed init leaks its connection(s) (#1744 observed these
|
|
1695
|
+
// piling up as idle Postgres connections).
|
|
1696
|
+
await db.destroy().catch(() => {});
|
|
1697
|
+
throw error;
|
|
1698
|
+
}
|
|
1699
|
+
holder.failures.delete(cacheKey);
|
|
1634
1700
|
|
|
1635
1701
|
// Note: legacy installs may carry a stray `emdash:manifest_cache`
|
|
1636
1702
|
// row in the options table from versions that persisted a JSON
|
|
@@ -2520,7 +2586,7 @@ export class EmDashRuntime {
|
|
|
2520
2586
|
...r.data,
|
|
2521
2587
|
item: { ...item, data: mergedData, liveData },
|
|
2522
2588
|
},
|
|
2523
|
-
}
|
|
2589
|
+
};
|
|
2524
2590
|
} catch (error) {
|
|
2525
2591
|
// Non-fatal — fall back to the unhydrated response. Log so the
|
|
2526
2592
|
// failure isn't completely silent (the response will look stale
|
|
@@ -2540,6 +2606,7 @@ export class EmDashRuntime {
|
|
|
2540
2606
|
bylines?: Array<{ bylineId: string; roleLabel?: string | null }>;
|
|
2541
2607
|
locale?: string;
|
|
2542
2608
|
translationOf?: string;
|
|
2609
|
+
taxonomies?: Record<string, string[]>;
|
|
2543
2610
|
},
|
|
2544
2611
|
) {
|
|
2545
2612
|
// Run beforeSave hooks (trusted plugins)
|
|
@@ -2604,6 +2671,7 @@ export class EmDashRuntime {
|
|
|
2604
2671
|
canonical?: string | null;
|
|
2605
2672
|
noIndex?: boolean;
|
|
2606
2673
|
};
|
|
2674
|
+
taxonomies?: Record<string, string[]>;
|
|
2607
2675
|
publishedAt?: string | null;
|
|
2608
2676
|
locale?: string;
|
|
2609
2677
|
/** Skip revision creation (used by autosave) */
|
package/src/index.ts
CHANGED
|
@@ -247,6 +247,10 @@ export type {
|
|
|
247
247
|
MediaAccess,
|
|
248
248
|
HttpAccess,
|
|
249
249
|
LogAccess,
|
|
250
|
+
TaxonomyAccess,
|
|
251
|
+
TaxonomyDefInfo,
|
|
252
|
+
TaxonomyTermInfo,
|
|
253
|
+
TaxonomyReadOptions,
|
|
250
254
|
PluginHooks,
|
|
251
255
|
HookConfig,
|
|
252
256
|
HookName,
|
|
@@ -404,8 +408,8 @@ export type {
|
|
|
404
408
|
} from "./settings/types.js";
|
|
405
409
|
|
|
406
410
|
// SEO
|
|
407
|
-
export { getSeoMeta, getContentSeo } from "./seo/index.js";
|
|
408
|
-
export type { SeoMeta, SeoMetaOptions } from "./seo/index.js";
|
|
411
|
+
export { getSeoMeta, getContentSeo, getHreflangAlternates } from "./seo/index.js";
|
|
412
|
+
export type { SeoMeta, SeoMetaOptions, HreflangAlternate, HreflangOptions } from "./seo/index.js";
|
|
409
413
|
|
|
410
414
|
// Public page contribution types
|
|
411
415
|
export type {
|
package/src/loader.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import type { LiveLoader } from "astro/loaders";
|
|
15
15
|
import { Kysely, type RawBuilder, sql, type Dialect } from "kysely";
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { buildStatusCondition, isPostgres } from "./database/dialect-helpers.js";
|
|
18
18
|
import { kyselyLogOption } from "./database/instrumentation.js";
|
|
19
19
|
import { decodeCursor, encodeCursor } from "./database/repositories/types.js";
|
|
20
20
|
import { validateIdentifier } from "./database/validate.js";
|
|
@@ -515,36 +515,6 @@ export type SortDirection = "asc" | "desc";
|
|
|
515
515
|
*/
|
|
516
516
|
export type OrderBySpec = Record<string, SortDirection>;
|
|
517
517
|
|
|
518
|
-
/**
|
|
519
|
-
* Build WHERE clause for status filtering.
|
|
520
|
-
* When filtering for 'published' status, also include scheduled content
|
|
521
|
-
* whose scheduled_at time has passed (treating it as effectively published).
|
|
522
|
-
*/
|
|
523
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
524
|
-
function buildStatusCondition(
|
|
525
|
-
db: Kysely<any>,
|
|
526
|
-
status: string,
|
|
527
|
-
tablePrefix?: string,
|
|
528
|
-
): ReturnType<typeof sql> {
|
|
529
|
-
const statusField = tablePrefix ? `${tablePrefix}.status` : "status";
|
|
530
|
-
const scheduledAtField = tablePrefix ? `${tablePrefix}.scheduled_at` : "scheduled_at";
|
|
531
|
-
|
|
532
|
-
if (status === "published") {
|
|
533
|
-
// Include both published content AND scheduled content past its publish time.
|
|
534
|
-
// scheduled_at is stored as text (ISO 8601). On Postgres, we must cast it
|
|
535
|
-
// to timestamptz for the comparison with CURRENT_TIMESTAMP to work.
|
|
536
|
-
const scheduledAtExpr = isPostgres(db)
|
|
537
|
-
? sql`${sql.ref(scheduledAtField)}::timestamptz`
|
|
538
|
-
: sql.ref(scheduledAtField);
|
|
539
|
-
const nowExpr = isPostgres(db)
|
|
540
|
-
? currentTimestampValue(db)
|
|
541
|
-
: sql`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
542
|
-
return sql`(${sql.ref(statusField)} = 'published' OR (${sql.ref(statusField)} = 'scheduled' AND ${scheduledAtExpr} <= ${nowExpr}))`;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
return sql`${sql.ref(statusField)} = ${status}`;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
518
|
/**
|
|
549
519
|
* Resolved primary sort field and direction (used for cursor pagination).
|
|
550
520
|
*/
|
package/src/mcp/server.ts
CHANGED
|
@@ -660,6 +660,12 @@ export function createMcpServer(): McpServer {
|
|
|
660
660
|
.describe(
|
|
661
661
|
"Bylines to credit. Each entry references an existing byline by id (see byline_list / byline_create) with an optional roleLabel. The first entry becomes the primary byline.",
|
|
662
662
|
),
|
|
663
|
+
taxonomies: z
|
|
664
|
+
.record(z.string(), z.array(z.string()))
|
|
665
|
+
.optional()
|
|
666
|
+
.describe(
|
|
667
|
+
"Taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Call taxonomy_list to see available taxonomies and taxonomy_list_terms to look up slugs. Missing keys leave that taxonomy unchanged.",
|
|
668
|
+
),
|
|
663
669
|
}),
|
|
664
670
|
annotations: { destructiveHint: false },
|
|
665
671
|
},
|
|
@@ -685,7 +691,7 @@ export function createMcpServer(): McpServer {
|
|
|
685
691
|
// Publishing requires publish permission — create as draft then publish
|
|
686
692
|
if (args.status === "published") {
|
|
687
693
|
const user = { id: userId, role: getExtra(extra).userRole };
|
|
688
|
-
if (!hasPermission(user, "content:publish_own"
|
|
694
|
+
if (!hasPermission(user, "content:publish_own")) {
|
|
689
695
|
throw new EmDashAuthError(
|
|
690
696
|
"Insufficient permissions: publishing requires content:publish_own",
|
|
691
697
|
"INSUFFICIENT_PERMISSIONS",
|
|
@@ -698,6 +704,7 @@ export function createMcpServer(): McpServer {
|
|
|
698
704
|
locale: args.locale,
|
|
699
705
|
translationOf: args.translationOf,
|
|
700
706
|
bylines: args.bylines,
|
|
707
|
+
taxonomies: args.taxonomies,
|
|
701
708
|
});
|
|
702
709
|
if (!result.success) return unwrap(result);
|
|
703
710
|
const itemId = extractContentId(result.data);
|
|
@@ -715,6 +722,7 @@ export function createMcpServer(): McpServer {
|
|
|
715
722
|
locale: args.locale,
|
|
716
723
|
translationOf: args.translationOf,
|
|
717
724
|
bylines: args.bylines,
|
|
725
|
+
taxonomies: args.taxonomies,
|
|
718
726
|
}),
|
|
719
727
|
);
|
|
720
728
|
},
|
|
@@ -771,6 +779,12 @@ export function createMcpServer(): McpServer {
|
|
|
771
779
|
.describe(
|
|
772
780
|
"Replace the byline list for this item. The first entry becomes the primary byline. Pass an empty array to clear all bylines.",
|
|
773
781
|
),
|
|
782
|
+
taxonomies: z
|
|
783
|
+
.record(z.string(), z.array(z.string()))
|
|
784
|
+
.optional()
|
|
785
|
+
.describe(
|
|
786
|
+
"Replace taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Only named taxonomies are touched; other taxonomies are left unchanged. Pass an empty array to clear a taxonomy.",
|
|
787
|
+
),
|
|
774
788
|
publishedAt: z.iso
|
|
775
789
|
.datetime({ offset: true, message: "must be an ISO 8601 datetime" })
|
|
776
790
|
.nullish()
|
|
@@ -805,7 +819,7 @@ export function createMcpServer(): McpServer {
|
|
|
805
819
|
// route. Status-driven publishes are gated separately below.
|
|
806
820
|
if (args.publishedAt !== undefined) {
|
|
807
821
|
const user = { id: userId, role: userRole };
|
|
808
|
-
if (!hasPermission(user, "content:publish_any"
|
|
822
|
+
if (!hasPermission(user, "content:publish_any")) {
|
|
809
823
|
throw new EmDashAuthError(
|
|
810
824
|
"Setting publishedAt requires content:publish_any permission",
|
|
811
825
|
"INSUFFICIENT_PERMISSIONS",
|
|
@@ -823,6 +837,7 @@ export function createMcpServer(): McpServer {
|
|
|
823
837
|
args.slug ||
|
|
824
838
|
args.seo !== undefined ||
|
|
825
839
|
args.bylines !== undefined ||
|
|
840
|
+
args.taxonomies !== undefined ||
|
|
826
841
|
args.publishedAt !== undefined
|
|
827
842
|
) {
|
|
828
843
|
const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
|
|
@@ -832,6 +847,7 @@ export function createMcpServer(): McpServer {
|
|
|
832
847
|
locale: args.locale,
|
|
833
848
|
seo: args.seo,
|
|
834
849
|
bylines: args.bylines,
|
|
850
|
+
taxonomies: args.taxonomies,
|
|
835
851
|
publishedAt: args.publishedAt,
|
|
836
852
|
_rev: args._rev,
|
|
837
853
|
});
|
|
@@ -847,6 +863,7 @@ export function createMcpServer(): McpServer {
|
|
|
847
863
|
args.slug ||
|
|
848
864
|
args.seo !== undefined ||
|
|
849
865
|
args.bylines !== undefined ||
|
|
866
|
+
args.taxonomies !== undefined ||
|
|
850
867
|
args.publishedAt !== undefined
|
|
851
868
|
) {
|
|
852
869
|
const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
|
|
@@ -856,6 +873,7 @@ export function createMcpServer(): McpServer {
|
|
|
856
873
|
locale: args.locale,
|
|
857
874
|
seo: args.seo,
|
|
858
875
|
bylines: args.bylines,
|
|
876
|
+
taxonomies: args.taxonomies,
|
|
859
877
|
publishedAt: args.publishedAt,
|
|
860
878
|
_rev: args._rev,
|
|
861
879
|
});
|
|
@@ -872,6 +890,7 @@ export function createMcpServer(): McpServer {
|
|
|
872
890
|
locale: args.locale,
|
|
873
891
|
seo: args.seo,
|
|
874
892
|
bylines: args.bylines,
|
|
893
|
+
taxonomies: args.taxonomies,
|
|
875
894
|
publishedAt: args.publishedAt,
|
|
876
895
|
_rev: args._rev,
|
|
877
896
|
}),
|
|
@@ -1008,7 +1027,7 @@ export function createMcpServer(): McpServer {
|
|
|
1008
1027
|
// regardless of ownership (mirrors the REST PUT route's publishedAt gate).
|
|
1009
1028
|
if (args.publishedAt !== undefined) {
|
|
1010
1029
|
const user = { id: userId, role: userRole };
|
|
1011
|
-
if (!hasPermission(user, "content:publish_any"
|
|
1030
|
+
if (!hasPermission(user, "content:publish_any")) {
|
|
1012
1031
|
throw new EmDashAuthError(
|
|
1013
1032
|
"Setting publishedAt requires content:publish_any permission",
|
|
1014
1033
|
"INSUFFICIENT_PERMISSIONS",
|
|
@@ -1932,6 +1951,12 @@ export function createMcpServer(): McpServer {
|
|
|
1932
1951
|
.optional()
|
|
1933
1952
|
.describe("Filter results by locale (omit to search all locales)"),
|
|
1934
1953
|
limit: z.number().int().min(1).max(50).optional().describe("Max results (default 20)"),
|
|
1954
|
+
cursor: z
|
|
1955
|
+
.string()
|
|
1956
|
+
.min(1)
|
|
1957
|
+
.max(2048)
|
|
1958
|
+
.optional()
|
|
1959
|
+
.describe("Pagination cursor from a previous response"),
|
|
1935
1960
|
}),
|
|
1936
1961
|
annotations: { readOnlyHint: true },
|
|
1937
1962
|
},
|
|
@@ -1944,6 +1969,7 @@ export function createMcpServer(): McpServer {
|
|
|
1944
1969
|
collections: args.collections,
|
|
1945
1970
|
locale: args.locale,
|
|
1946
1971
|
limit: args.limit,
|
|
1972
|
+
cursor: args.cursor,
|
|
1947
1973
|
});
|
|
1948
1974
|
return jsonResult(results);
|
|
1949
1975
|
} catch (error) {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from "./content-refresh.js";
|
|
21
21
|
import {
|
|
22
22
|
CONTENT_SOURCE_SCHEMA_VERSION,
|
|
23
|
+
type ContentMediaUsageSnapshot,
|
|
23
24
|
loadContentMediaUsageSnapshots,
|
|
24
25
|
} from "./content-snapshots.js";
|
|
25
26
|
import {
|
|
@@ -65,11 +66,48 @@ export interface ContentMediaUsageRepairCollectionResult {
|
|
|
65
66
|
completedAt: string | null;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
export interface ContentMediaUsageRepairAllResult {
|
|
70
|
+
status: ContentMediaUsageRepairStatus;
|
|
71
|
+
collections: ContentMediaUsageRepairCollectionResult[];
|
|
72
|
+
indexedSourceCount: number;
|
|
73
|
+
failedSourceCount: number;
|
|
74
|
+
skippedSourceCount: number;
|
|
75
|
+
deletedSourceCount: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
68
78
|
export interface ContentMediaUsageCollectionScan {
|
|
69
79
|
collectionSlug: string;
|
|
70
80
|
contentIds: string[];
|
|
71
81
|
}
|
|
72
82
|
|
|
83
|
+
interface ContentMediaUsageCollectionRecord {
|
|
84
|
+
id: string;
|
|
85
|
+
slug: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface ContentMediaUsageInitialCollectionResult {
|
|
89
|
+
collection: ContentMediaUsageCollectionRecord;
|
|
90
|
+
result: ContentMediaUsageRepairCollectionResult;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function repairContentMediaUsageAll(
|
|
94
|
+
db: Kysely<Database>,
|
|
95
|
+
): Promise<ContentMediaUsageRepairAllResult> {
|
|
96
|
+
const collections = await loadContentMediaUsageCollectionRecords(db);
|
|
97
|
+
const results: ContentMediaUsageInitialCollectionResult[] = [];
|
|
98
|
+
|
|
99
|
+
for (const collection of collections) {
|
|
100
|
+
results.push({
|
|
101
|
+
collection,
|
|
102
|
+
result: await repairContentMediaUsageCollectionSafely(db, collection.slug),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return aggregateContentMediaUsageRepairAll(
|
|
107
|
+
await filterExistingContentMediaUsageCollectionResults(db, results),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
73
111
|
export async function scanContentMediaUsageCollection(
|
|
74
112
|
db: Kysely<Database>,
|
|
75
113
|
collectionSlug: string,
|
|
@@ -105,6 +143,116 @@ export async function repairContentMediaUsageCollection(
|
|
|
105
143
|
);
|
|
106
144
|
}
|
|
107
145
|
|
|
146
|
+
async function loadContentMediaUsageCollectionRecords(
|
|
147
|
+
db: Kysely<Database>,
|
|
148
|
+
): Promise<ContentMediaUsageCollectionRecord[]> {
|
|
149
|
+
return db
|
|
150
|
+
.selectFrom("_emdash_collections")
|
|
151
|
+
.select(["id", "slug"])
|
|
152
|
+
.orderBy("slug", "asc")
|
|
153
|
+
.execute();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function repairContentMediaUsageCollectionSafely(
|
|
157
|
+
db: Kysely<Database>,
|
|
158
|
+
collectionSlug: string,
|
|
159
|
+
): Promise<ContentMediaUsageRepairCollectionResult> {
|
|
160
|
+
try {
|
|
161
|
+
return await repairContentMediaUsageCollection(db, { collectionSlug });
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error(`[media-usage] Failed to repair collection ${collectionSlug}:`, error);
|
|
164
|
+
const now = new Date().toISOString();
|
|
165
|
+
return {
|
|
166
|
+
scope: contentMediaUsageCollectionScope(collectionSlug),
|
|
167
|
+
status: "failed",
|
|
168
|
+
indexedSourceCount: 0,
|
|
169
|
+
failedSourceCount: 0,
|
|
170
|
+
skippedSourceCount: 0,
|
|
171
|
+
deletedSourceCount: 0,
|
|
172
|
+
lastErrorCode: CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_ERROR,
|
|
173
|
+
startedAt: now,
|
|
174
|
+
completedAt: now,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function filterExistingContentMediaUsageCollectionResults(
|
|
180
|
+
db: Kysely<Database>,
|
|
181
|
+
results: readonly ContentMediaUsageInitialCollectionResult[],
|
|
182
|
+
): Promise<ContentMediaUsageRepairCollectionResult[]> {
|
|
183
|
+
const currentCollections = await loadContentMediaUsageCollectionRecordsSafely(db);
|
|
184
|
+
const currentIdsBySlug = new Map(
|
|
185
|
+
currentCollections.map((collection) => [collection.slug, collection.id]),
|
|
186
|
+
);
|
|
187
|
+
const includedResults: ContentMediaUsageRepairCollectionResult[] = [];
|
|
188
|
+
const excludedResults: ContentMediaUsageRepairCollectionResult[] = [];
|
|
189
|
+
|
|
190
|
+
for (const { collection, result } of results) {
|
|
191
|
+
if (currentIdsBySlug.get(collection.slug) === collection.id) {
|
|
192
|
+
includedResults.push(result);
|
|
193
|
+
} else {
|
|
194
|
+
excludedResults.push(result);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (excludedResults.length > 0) {
|
|
199
|
+
const repo = new MediaUsageRepository(db);
|
|
200
|
+
for (const result of excludedResults) {
|
|
201
|
+
await repo.deleteIndexStatus(result.scope);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return includedResults;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function loadContentMediaUsageCollectionRecordsSafely(
|
|
209
|
+
db: Kysely<Database>,
|
|
210
|
+
): Promise<ContentMediaUsageCollectionRecord[]> {
|
|
211
|
+
try {
|
|
212
|
+
return await loadContentMediaUsageCollectionRecords(db);
|
|
213
|
+
} catch {
|
|
214
|
+
// Retry once before failing; returning unpruned results can over-report deleted collections.
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
return await loadContentMediaUsageCollectionRecords(db);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error("[media-usage] Failed to reconcile all-content repair collections:", error);
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function aggregateContentMediaUsageRepairAll(
|
|
226
|
+
collections: readonly ContentMediaUsageRepairCollectionResult[],
|
|
227
|
+
): ContentMediaUsageRepairAllResult {
|
|
228
|
+
return {
|
|
229
|
+
status: determineRepairAllStatus(collections),
|
|
230
|
+
collections: [...collections],
|
|
231
|
+
indexedSourceCount: sumCollectionRepairCount(collections, "indexedSourceCount"),
|
|
232
|
+
failedSourceCount: sumCollectionRepairCount(collections, "failedSourceCount"),
|
|
233
|
+
skippedSourceCount: sumCollectionRepairCount(collections, "skippedSourceCount"),
|
|
234
|
+
deletedSourceCount: sumCollectionRepairCount(collections, "deletedSourceCount"),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function determineRepairAllStatus(
|
|
239
|
+
collections: readonly ContentMediaUsageRepairCollectionResult[],
|
|
240
|
+
): ContentMediaUsageRepairStatus {
|
|
241
|
+
if (collections.length === 0) return "complete";
|
|
242
|
+
if (collections.every((collection) => collection.status === "complete")) return "complete";
|
|
243
|
+
if (collections.some((collection) => collection.status === "stale")) return "stale";
|
|
244
|
+
if (collections.some((collection) => collection.status === "partial")) return "partial";
|
|
245
|
+
if (collections.every((collection) => collection.status === "failed")) return "failed";
|
|
246
|
+
return "partial";
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function sumCollectionRepairCount(
|
|
250
|
+
collections: readonly ContentMediaUsageRepairCollectionResult[],
|
|
251
|
+
key: "indexedSourceCount" | "failedSourceCount" | "skippedSourceCount" | "deletedSourceCount",
|
|
252
|
+
): number {
|
|
253
|
+
return collections.reduce((sum, collection) => sum + collection[key], 0);
|
|
254
|
+
}
|
|
255
|
+
|
|
108
256
|
async function repairContentMediaUsageCollectionUnlocked(
|
|
109
257
|
db: Kysely<Database>,
|
|
110
258
|
collectionSlug: string,
|
|
@@ -147,6 +295,7 @@ async function repairContentMediaUsageCollectionUnlocked(
|
|
|
147
295
|
skippedSourceCount: 0,
|
|
148
296
|
deletedSourceCount: 0,
|
|
149
297
|
lastErrorCode: CONTENT_MEDIA_USAGE_REPAIR_ERROR.COLLECTION_NOT_FOUND,
|
|
298
|
+
missingContentIds: new Set(),
|
|
150
299
|
},
|
|
151
300
|
status: "failed",
|
|
152
301
|
startedAt,
|
|
@@ -155,16 +304,14 @@ async function repairContentMediaUsageCollectionUnlocked(
|
|
|
155
304
|
}
|
|
156
305
|
const counts = await repairScannedContentSources(db, repo, scan);
|
|
157
306
|
const finalScan = await scanContentMediaUsageCollection(db, collectionSlug);
|
|
158
|
-
const scannedContentCount = finalScan?.contentIds.length ?? scan.contentIds.length;
|
|
159
307
|
if (!finalScan) {
|
|
160
308
|
counts.failedSourceCount++;
|
|
161
309
|
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.COLLECTION_NOT_FOUND;
|
|
162
|
-
} else if (!sameContentIds(scan.contentIds, finalScan.contentIds)) {
|
|
163
|
-
counts
|
|
164
|
-
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
310
|
+
} else if (!sameContentIds(repairedContentIds(scan.contentIds, counts), finalScan.contentIds)) {
|
|
311
|
+
markRepairConflict(counts);
|
|
165
312
|
}
|
|
166
313
|
const completedAt = new Date().toISOString();
|
|
167
|
-
const status = determineRepairStatus(counts
|
|
314
|
+
const status = determineRepairStatus(counts);
|
|
168
315
|
return await finalizeRepairStatus(repo, {
|
|
169
316
|
...scope,
|
|
170
317
|
runToken,
|
|
@@ -191,6 +338,7 @@ async function repairContentMediaUsageCollectionUnlocked(
|
|
|
191
338
|
skippedSourceCount: 0,
|
|
192
339
|
deletedSourceCount: 0,
|
|
193
340
|
lastErrorCode,
|
|
341
|
+
missingContentIds: new Set(),
|
|
194
342
|
},
|
|
195
343
|
status: "failed",
|
|
196
344
|
startedAt,
|
|
@@ -205,6 +353,7 @@ interface RepairCounts {
|
|
|
205
353
|
skippedSourceCount: number;
|
|
206
354
|
deletedSourceCount: number;
|
|
207
355
|
lastErrorCode: ContentMediaUsageRepairErrorCode | null;
|
|
356
|
+
missingContentIds: Set<string>;
|
|
208
357
|
}
|
|
209
358
|
|
|
210
359
|
async function repairScannedContentSources(
|
|
@@ -218,6 +367,7 @@ async function repairScannedContentSources(
|
|
|
218
367
|
skippedSourceCount: 0,
|
|
219
368
|
deletedSourceCount: 0,
|
|
220
369
|
lastErrorCode: null,
|
|
370
|
+
missingContentIds: new Set(),
|
|
221
371
|
};
|
|
222
372
|
|
|
223
373
|
const fieldDiscovery = await loadContentMediaUsageFields(db, scan.collectionSlug);
|
|
@@ -256,7 +406,16 @@ async function repairContentSource(
|
|
|
256
406
|
fieldDiscovery,
|
|
257
407
|
);
|
|
258
408
|
if (!snapshotsResult.success) {
|
|
409
|
+
if (snapshotsResult.error === CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_NOT_FOUND) {
|
|
410
|
+
markRepairConflict(counts);
|
|
411
|
+
counts.missingContentIds.add(contentId);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
259
414
|
counts.lastErrorCode = snapshotsResult.error;
|
|
415
|
+
if (snapshotsResult.snapshots) {
|
|
416
|
+
// Partial snapshot failures keep absent variants in place; the attempted source is marked below.
|
|
417
|
+
await repairSnapshotSources(repo, snapshotsResult.snapshots, observedSources, counts);
|
|
418
|
+
}
|
|
260
419
|
if (snapshotsResult.source) {
|
|
261
420
|
const result = await repo.markSourceAttemptedIfMatching(
|
|
262
421
|
{
|
|
@@ -269,8 +428,7 @@ async function repairContentSource(
|
|
|
269
428
|
if (result.attempted) {
|
|
270
429
|
counts.failedSourceCount++;
|
|
271
430
|
} else {
|
|
272
|
-
counts
|
|
273
|
-
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
431
|
+
markRepairConflict(counts);
|
|
274
432
|
}
|
|
275
433
|
return;
|
|
276
434
|
}
|
|
@@ -279,8 +437,29 @@ async function repairContentSource(
|
|
|
279
437
|
return;
|
|
280
438
|
}
|
|
281
439
|
|
|
440
|
+
const expectedSourceKeys = await repairSnapshotSources(
|
|
441
|
+
repo,
|
|
442
|
+
snapshotsResult.snapshots,
|
|
443
|
+
observedSources,
|
|
444
|
+
counts,
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
for (const sourceKey of sourceKeys) {
|
|
448
|
+
if (expectedSourceKeys.has(sourceKey)) continue;
|
|
449
|
+
const observedSource = observedSources.get(sourceKey);
|
|
450
|
+
if (!observedSource) continue;
|
|
451
|
+
await deleteObservedSource(repo, sourceKey, observedSource, counts);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
async function repairSnapshotSources(
|
|
456
|
+
repo: MediaUsageRepository,
|
|
457
|
+
snapshots: readonly ContentMediaUsageSnapshot[],
|
|
458
|
+
observedSources: Map<string, MediaUsageSource>,
|
|
459
|
+
counts: RepairCounts,
|
|
460
|
+
): Promise<Set<string>> {
|
|
282
461
|
const expectedSourceKeys = new Set<string>();
|
|
283
|
-
for (const snapshot of
|
|
462
|
+
for (const snapshot of snapshots) {
|
|
284
463
|
expectedSourceKeys.add(snapshot.source.sourceKey);
|
|
285
464
|
const result = await repo.replaceSourceIfMatching(
|
|
286
465
|
snapshot.source,
|
|
@@ -290,17 +469,15 @@ async function repairContentSource(
|
|
|
290
469
|
if (result.replaced) {
|
|
291
470
|
counts.indexedSourceCount++;
|
|
292
471
|
} else {
|
|
293
|
-
counts
|
|
294
|
-
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
472
|
+
markRepairConflict(counts);
|
|
295
473
|
}
|
|
296
474
|
}
|
|
475
|
+
return expectedSourceKeys;
|
|
476
|
+
}
|
|
297
477
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (!observedSource) continue;
|
|
302
|
-
await deleteObservedSource(repo, sourceKey, observedSource, counts);
|
|
303
|
-
}
|
|
478
|
+
function markRepairConflict(counts: RepairCounts): void {
|
|
479
|
+
counts.skippedSourceCount++;
|
|
480
|
+
counts.lastErrorCode ??= CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
304
481
|
}
|
|
305
482
|
|
|
306
483
|
async function reconcileOrphanedContentSources(
|
|
@@ -370,8 +547,7 @@ async function deleteObservedSourceIfContentAbsent(
|
|
|
370
547
|
}
|
|
371
548
|
if (result.contentPresent) return;
|
|
372
549
|
if (result.source) {
|
|
373
|
-
counts
|
|
374
|
-
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
550
|
+
markRepairConflict(counts);
|
|
375
551
|
}
|
|
376
552
|
}
|
|
377
553
|
|
|
@@ -387,8 +563,7 @@ async function deleteObservedSource(
|
|
|
387
563
|
return;
|
|
388
564
|
}
|
|
389
565
|
if (result.source) {
|
|
390
|
-
counts
|
|
391
|
-
counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
|
|
566
|
+
markRepairConflict(counts);
|
|
392
567
|
}
|
|
393
568
|
}
|
|
394
569
|
|
|
@@ -439,11 +614,12 @@ async function finalizeRepairStatus(
|
|
|
439
614
|
|
|
440
615
|
function determineRepairStatus(
|
|
441
616
|
counts: RepairCounts,
|
|
442
|
-
scannedContentCount: number,
|
|
443
617
|
): Exclude<ContentMediaUsageRepairStatus, "stale"> {
|
|
444
618
|
if (counts.failedSourceCount === 0 && counts.skippedSourceCount === 0) return "complete";
|
|
445
619
|
const trustedProgress = counts.indexedSourceCount + counts.deletedSourceCount;
|
|
446
|
-
if (
|
|
620
|
+
if (counts.failedSourceCount > 0 && trustedProgress === 0) {
|
|
621
|
+
return "failed";
|
|
622
|
+
}
|
|
447
623
|
return "partial";
|
|
448
624
|
}
|
|
449
625
|
|
|
@@ -477,6 +653,14 @@ function sameContentIds(left: readonly string[], right: readonly string[]): bool
|
|
|
477
653
|
return left.every((id) => rightIds.has(id));
|
|
478
654
|
}
|
|
479
655
|
|
|
656
|
+
function repairedContentIds(
|
|
657
|
+
contentIds: readonly string[],
|
|
658
|
+
counts: Pick<RepairCounts, "missingContentIds">,
|
|
659
|
+
): string[] {
|
|
660
|
+
if (counts.missingContentIds.size === 0) return [...contentIds];
|
|
661
|
+
return contentIds.filter((contentId) => !counts.missingContentIds.has(contentId));
|
|
662
|
+
}
|
|
663
|
+
|
|
480
664
|
function contentMediaUsageCollectionScope(collectionSlug: string): ContentMediaUsageRepairScope {
|
|
481
665
|
return {
|
|
482
666
|
adapterId: CONTENT_MEDIA_USAGE_ADAPTER_ID,
|