emdash 0.27.0 → 0.28.1
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-u037EnTR.d.mts → adapters-hUy8vOB-.d.mts} +1 -1
- package/dist/{adapters-u037EnTR.d.mts.map → adapters-hUy8vOB-.d.mts.map} +1 -1
- package/dist/{allowed-origins-D5FxMUo8.mjs → allowed-origins-CRsJ6BPM.mjs} +2 -2
- package/dist/{allowed-origins-D5FxMUo8.mjs.map → allowed-origins-CRsJ6BPM.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +17 -16
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +3 -3
- package/dist/{api-80kycR9o.mjs → api-DxFSorgk.mjs} +33 -23
- package/dist/api-DxFSorgk.mjs.map +1 -0
- package/dist/{api-tokens-D6ppjIVi.mjs → api-tokens-DvqeZmVq.mjs} +2 -2
- package/dist/{api-tokens-D6ppjIVi.mjs.map → api-tokens-DvqeZmVq.mjs.map} +1 -1
- package/dist/{apply-DSypk6Iu.mjs → apply-CDJqIjPU.mjs} +111 -74
- package/dist/apply-CDJqIjPU.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.mjs +3 -3
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +50 -11
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +5 -5
- package/dist/astro/middleware/request-context.mjs +2 -2
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +2 -2
- package/dist/astro/middleware.mjs +124 -71
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +6 -6
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +4 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +8 -8
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +8 -8
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +8 -8
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -14
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +14 -14
- package/dist/astro/routes/api/admin/bylines/index.mjs +14 -14
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +12 -12
- 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.mjs +10 -10
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +37 -36
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +37 -36
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +36 -35
- 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 +36 -35
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +36 -35
- 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 +37 -36
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +37 -36
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +36 -35
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +36 -35
- 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 +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +36 -35
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +6 -6
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +6 -6
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/complete.mjs +10 -10
- package/dist/astro/routes/api/auth/invite/index.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/register-options.mjs +9 -9
- package/dist/astro/routes/api/auth/logout.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/send.mjs +9 -9
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/me.mjs +7 -7
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +6 -6
- package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/options.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +9 -9
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/verify.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/complete.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/request.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +13 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +12 -12
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +10 -10
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +7 -7
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +7 -7
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +7 -7
- package/dist/astro/routes/api/content/_collection_/authors.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/index.mjs +7 -7
- package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -7
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +3 -3
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +19 -11
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -41
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +12 -407
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +19 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +97 -79
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +19 -11
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +40 -2
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +519 -39
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/mcp.mjs +39 -39
- package/dist/astro/routes/api/media/_id_/confirm.mjs +7 -7
- package/dist/astro/routes/api/media/_id_.mjs +7 -7
- package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
- package/dist/astro/routes/api/media/providers/index.mjs +3 -3
- package/dist/astro/routes/api/media/upload-url.mjs +8 -8
- package/dist/astro/routes/api/media.mjs +9 -9
- 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 +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.mjs +6 -6
- package/dist/astro/routes/api/openapi.json.mjs +4 -4
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +6 -14
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +9 -9
- package/dist/astro/routes/api/redirects/404s/summary.mjs +9 -9
- package/dist/astro/routes/api/redirects/_id_.mjs +10 -10
- package/dist/astro/routes/api/redirects/index.mjs +10 -10
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +36 -35
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +36 -35
- 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 +36 -35
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +36 -35
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +36 -35
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +7 -6
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +36 -35
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +36 -35
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +10 -10
- package/dist/astro/routes/api/search/index.mjs +9 -9
- package/dist/astro/routes/api/search/rebuild.mjs +10 -10
- package/dist/astro/routes/api/search/stats.mjs +6 -6
- package/dist/astro/routes/api/search/suggest.mjs +9 -9
- package/dist/astro/routes/api/sections/_slug_.mjs +9 -9
- package/dist/astro/routes/api/sections/index.mjs +9 -9
- package/dist/astro/routes/api/settings/email.mjs +4 -4
- package/dist/astro/routes/api/settings.mjs +12 -12
- package/dist/astro/routes/api/setup/admin-verify.mjs +11 -11
- package/dist/astro/routes/api/setup/admin.mjs +10 -10
- package/dist/astro/routes/api/setup/dev-bypass.mjs +25 -24
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +26 -25
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +4 -4
- package/dist/astro/routes/api/snapshot.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +13 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +13 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +13 -13
- package/dist/astro/routes/api/taxonomies/index.mjs +13 -13
- package/dist/astro/routes/api/themes/preview.mjs +5 -5
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- 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 +7 -7
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +9 -9
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +9 -9
- package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
- package/dist/astro/routes/api/widget-areas/index.mjs +9 -9
- package/dist/astro/routes/api/widget-components.mjs +3 -3
- package/dist/astro/routes/robots.txt.mjs +6 -6
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +7 -7
- package/dist/astro/types.d.mts +13 -13
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-C3a_zGsM.mjs → authorize-Dz88F_Fw.mjs} +2 -2
- package/dist/{authorize-C3a_zGsM.mjs.map → authorize-Dz88F_Fw.mjs.map} +1 -1
- package/dist/{byline-DEKSVPTy.mjs → byline-Bm8ZgUP9.mjs} +6 -6
- package/dist/{byline-DEKSVPTy.mjs.map → byline-Bm8ZgUP9.mjs.map} +1 -1
- package/dist/{byline-fields-eyJMblSr.mjs → byline-fields-2Lp5Hbgf.mjs} +18 -3
- package/dist/byline-fields-2Lp5Hbgf.mjs.map +1 -0
- package/dist/{byline-fields-CtQ6blXd.d.mts → byline-fields-CHE8UStY.d.mts} +47 -32
- package/dist/{byline-fields-CtQ6blXd.d.mts.map → byline-fields-CHE8UStY.d.mts.map} +1 -1
- package/dist/{byline-fields-DaMKzkhO.mjs → byline-fields-CIx_GuN4.mjs} +1 -1
- package/dist/{byline-fields-DaMKzkhO.mjs.map → byline-fields-CIx_GuN4.mjs.map} +1 -1
- package/dist/{bylines-Ds4-otXl.mjs → bylines-6tm9mgQb.mjs} +4 -4
- package/dist/{bylines-Ds4-otXl.mjs.map → bylines-6tm9mgQb.mjs.map} +1 -1
- package/dist/{bylines-CiqgTHWF.mjs → bylines-CAZxGSrm.mjs} +6 -6
- package/dist/{bylines-CiqgTHWF.mjs.map → bylines-CAZxGSrm.mjs.map} +1 -1
- package/dist/{cache-Ciu3e3AF.mjs → cache-CEBAZjir.mjs} +2 -2
- package/dist/{cache-Ciu3e3AF.mjs.map → cache-CEBAZjir.mjs.map} +1 -1
- package/dist/{challenge-store-LhiqMccz.mjs → challenge-store-anhwVER0.mjs} +1 -1
- package/dist/{challenge-store-LhiqMccz.mjs.map → challenge-store-anhwVER0.mjs.map} +1 -1
- package/dist/{chunks-CZFiauig.mjs → chunks-B2isWQhr.mjs} +2 -2
- package/dist/{chunks-CZFiauig.mjs.map → chunks-B2isWQhr.mjs.map} +1 -1
- package/dist/cli/index.mjs +22 -21
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +2 -2
- package/dist/{comment-CH1IrFFs.mjs → comment-CzeatwBV.mjs} +3 -3
- package/dist/{comment-CH1IrFFs.mjs.map → comment-CzeatwBV.mjs.map} +1 -1
- package/dist/{comment-reaction-kruNY-kP.mjs → comment-reaction-Cj9QJY7I.mjs} +2 -2
- package/dist/{comment-reaction-kruNY-kP.mjs.map → comment-reaction-Cj9QJY7I.mjs.map} +1 -1
- package/dist/{comments-BUJyXbgq.mjs → comments-BLE-jv5k.mjs} +3 -3
- package/dist/{comments-BUJyXbgq.mjs.map → comments-BLE-jv5k.mjs.map} +1 -1
- package/dist/{components-CYt4uVK9.mjs → components-B_sATNUc.mjs} +1 -1
- package/dist/{components-CYt4uVK9.mjs.map → components-B_sATNUc.mjs.map} +1 -1
- package/dist/{content-RmfHoWqK.mjs → content-DhgEth4k.mjs} +4 -4
- package/dist/{content-RmfHoWqK.mjs.map → content-DhgEth4k.mjs.map} +1 -1
- package/dist/content-refresh-Br4gMzh8.mjs +1537 -0
- package/dist/content-refresh-Br4gMzh8.mjs.map +1 -0
- package/dist/{context-CzUU_WzL.mjs → context-BRIpHARC.mjs} +76 -54
- package/dist/context-BRIpHARC.mjs.map +1 -0
- package/dist/{cron-C5LVoNmP.mjs → cron-v4FTEFR_.mjs} +1 -1
- package/dist/{cron-C5LVoNmP.mjs.map → cron-v4FTEFR_.mjs.map} +1 -1
- package/dist/{dashboard-CVyGhift.mjs → dashboard-EvEKF5en.mjs} +4 -4
- package/dist/{dashboard-CVyGhift.mjs.map → dashboard-EvEKF5en.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{default-CeRG-Ot4.mjs → default-CM_D83Mg.mjs} +1 -1
- package/dist/{default-CeRG-Ot4.mjs.map → default-CM_D83Mg.mjs.map} +1 -1
- package/dist/{device-flow-DENDCQ9F.mjs → device-flow-CfGP18Uw.mjs} +4 -4
- package/dist/{device-flow-DENDCQ9F.mjs.map → device-flow-CfGP18Uw.mjs.map} +1 -1
- package/dist/{email-console-DJP32ucW.mjs → email-console-CIf4Lfvv.mjs} +1 -1
- package/dist/{email-console-DJP32ucW.mjs.map → email-console-CIf4Lfvv.mjs.map} +1 -1
- package/dist/{error-BHkLZk-w.mjs → error-CkAseSqZ.mjs} +2 -2
- package/dist/{error-BHkLZk-w.mjs.map → error-CkAseSqZ.mjs.map} +1 -1
- package/dist/{escape-Bjio4ZsM.mjs → escape-DqD0aCKu.mjs} +1 -1
- package/dist/{escape-Bjio4ZsM.mjs.map → escape-DqD0aCKu.mjs.map} +1 -1
- package/dist/{field-defs-cache-BA-8ZPiT.mjs → field-defs-cache-WUI88LX5.mjs} +2 -2
- package/dist/{field-defs-cache-BA-8ZPiT.mjs.map → field-defs-cache-WUI88LX5.mjs.map} +1 -1
- package/dist/{fts-manager-Db9jGavf.mjs → fts-manager-BbFaF_V8.mjs} +2 -2
- package/dist/{fts-manager-Db9jGavf.mjs.map → fts-manager-BbFaF_V8.mjs.map} +1 -1
- package/dist/{import-Bb1T9WJS.mjs → import-fYLf14Co.mjs} +514 -25
- package/dist/import-fYLf14Co.mjs.map +1 -0
- package/dist/{index-CDZZjrLT.d.mts → index-B9sIxwe4.d.mts} +21 -22
- package/dist/{index-CDZZjrLT.d.mts.map → index-B9sIxwe4.d.mts.map} +1 -1
- package/dist/{index-DGIjmUXQ.d.mts → index-Bm-Gy8Mh.d.mts} +25 -4
- package/dist/index-Bm-Gy8Mh.d.mts.map +1 -0
- package/dist/index.d.mts +18 -18
- package/dist/index.mjs +54 -53
- package/dist/{load-DpHICVPh.mjs → load-Djn3HWQS.mjs} +2 -2
- package/dist/{load-DpHICVPh.mjs.map → load-Djn3HWQS.mjs.map} +1 -1
- package/dist/{loader-4K37qA-y.mjs → loader-CB6YHeul.mjs} +6 -5
- package/dist/loader-CB6YHeul.mjs.map +1 -0
- package/dist/{manifest-schema-kPGX7VS-.mjs → manifest-schema-BHlgZM1W.mjs} +1 -1
- package/dist/{manifest-schema-kPGX7VS-.mjs.map → manifest-schema-BHlgZM1W.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +5 -5
- package/dist/{media-C0nRRfs1.mjs → media-BrXIaMFN.mjs} +2 -2
- package/dist/{media-C0nRRfs1.mjs.map → media-BrXIaMFN.mjs.map} +1 -1
- package/dist/{media-allowlist-Du8t1u6a.mjs → media-allowlist-CRHEeJ_i.mjs} +1 -1
- package/dist/{media-allowlist-Du8t1u6a.mjs.map → media-allowlist-CRHEeJ_i.mjs.map} +1 -1
- package/dist/{media-url-O4rm9-SQ.mjs → media-url-CKi5XSw4.mjs} +1 -1
- package/dist/{media-url-O4rm9-SQ.mjs.map → media-url-CKi5XSw4.mjs.map} +1 -1
- package/dist/{menus-SL2K0xq2.mjs → menus-Cfivc2Ad.mjs} +3 -3
- package/dist/{menus-SL2K0xq2.mjs.map → menus-Cfivc2Ad.mjs.map} +1 -1
- package/dist/{menus-DzRyC1ID.mjs → menus-b2T4clbO.mjs} +16 -12
- package/dist/{menus-DzRyC1ID.mjs.map → menus-b2T4clbO.mjs.map} +1 -1
- package/dist/{mode-BB0F8xTC.mjs → mode-BM9QgEmt.mjs} +1 -1
- package/dist/{mode-BB0F8xTC.mjs.map → mode-BM9QgEmt.mjs.map} +1 -1
- package/dist/{oauth-authorization-CsvzIp_F.mjs → oauth-authorization-CXWkIGT4.mjs} +4 -4
- package/dist/{oauth-authorization-CsvzIp_F.mjs.map → oauth-authorization-CXWkIGT4.mjs.map} +1 -1
- package/dist/{oauth-clients-C9SYwEbZ.mjs → oauth-clients-BmTI5rsl.mjs} +1 -1
- package/dist/{oauth-clients-C9SYwEbZ.mjs.map → oauth-clients-BmTI5rsl.mjs.map} +1 -1
- package/dist/{oauth-state-store---zrApfB.mjs → oauth-state-store-YLFLcH5F.mjs} +1 -1
- package/dist/{oauth-state-store---zrApfB.mjs.map → oauth-state-store-YLFLcH5F.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-SHsWRlG9.mjs → oauth-user-lookup-Bsc_GsX-.mjs} +1 -1
- package/dist/{oauth-user-lookup-SHsWRlG9.mjs.map → oauth-user-lookup-Bsc_GsX-.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-CHbHv83-.mjs → object-cache-Bok5j2ae.mjs} +43 -3
- package/dist/object-cache-Bok5j2ae.mjs.map +1 -0
- package/dist/{options-41nCWqi9.d.mts → options-iMpRRxIe.d.mts} +3 -3
- package/dist/{options-41nCWqi9.d.mts.map → options-iMpRRxIe.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-CqyZj3Hp.mjs → parse-GmjecGct.mjs} +2 -2
- package/dist/{parse-CqyZj3Hp.mjs.map → parse-GmjecGct.mjs.map} +1 -1
- package/dist/{passkey-config-C0YfSBko.mjs → passkey-config-De0ahnRg.mjs} +1 -1
- package/dist/{passkey-config-C0YfSBko.mjs.map → passkey-config-De0ahnRg.mjs.map} +1 -1
- package/dist/{placeholder-Cuce9U-m.d.mts → placeholder-BSKwzRe4.d.mts} +1 -1
- package/dist/{placeholder-Cuce9U-m.d.mts.map → placeholder-BSKwzRe4.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{portable-text-BICg8bTk.mjs → portable-text-cCa0cGV6.mjs} +1 -1
- package/dist/{portable-text-BICg8bTk.mjs.map → portable-text-cCa0cGV6.mjs.map} +1 -1
- package/dist/{preview-DKGCt2_p.mjs → preview-SSXNVPAC.mjs} +2 -2
- package/dist/{preview-DKGCt2_p.mjs.map → preview-SSXNVPAC.mjs.map} +1 -1
- package/dist/{public-url-CTVqgMmg.mjs → public-url-Danv47cS.mjs} +1 -1
- package/dist/{public-url-CTVqgMmg.mjs.map → public-url-Danv47cS.mjs.map} +1 -1
- package/dist/{query-B0M-9LYR.mjs → query-1Cp6U9oo.mjs} +14 -14
- package/dist/{query-B0M-9LYR.mjs.map → query-1Cp6U9oo.mjs.map} +1 -1
- package/dist/{rate-limit-BwoUdIpC.mjs → rate-limit-C_Lf63Dd.mjs} +2 -2
- package/dist/{rate-limit-BwoUdIpC.mjs.map → rate-limit-C_Lf63Dd.mjs.map} +1 -1
- package/dist/{redirect-CS-PHtNh.mjs → redirect-CoW3G-0U.mjs} +1 -1
- package/dist/{redirect-CS-PHtNh.mjs.map → redirect-CoW3G-0U.mjs.map} +1 -1
- package/dist/{redirect-lMOzG04S.mjs → redirect-IyfNirgS.mjs} +2 -2
- package/dist/{redirect-lMOzG04S.mjs.map → redirect-IyfNirgS.mjs.map} +1 -1
- package/dist/{redirects-9218MmYl.mjs → redirects-Bs1g42Ri.mjs} +4 -4
- package/dist/{redirects-9218MmYl.mjs.map → redirects-Bs1g42Ri.mjs.map} +1 -1
- package/dist/{redirects-Dcbuisoj.mjs → redirects-DXEXBAII.mjs} +2 -2
- package/dist/{redirects-Dcbuisoj.mjs.map → redirects-DXEXBAII.mjs.map} +1 -1
- package/dist/{registry-DP-iEtdR.mjs → registry-B57vp_X9.mjs} +122 -79
- package/dist/registry-B57vp_X9.mjs.map +1 -0
- package/dist/{request-meta-CmS1tDFf.mjs → request-meta-DbvXaAvU.mjs} +2 -2
- package/dist/{request-meta-CmS1tDFf.mjs.map → request-meta-DbvXaAvU.mjs.map} +1 -1
- package/dist/{resolve-C7I0qiR0.mjs → resolve-DR3wqMTy.mjs} +1 -1
- package/dist/{resolve-C7I0qiR0.mjs.map → resolve-DR3wqMTy.mjs.map} +1 -1
- package/dist/{runner-BbR3DfrL.d.mts → runner-DvFWoz8-.d.mts} +2 -2
- package/dist/{runner-BbR3DfrL.d.mts.map → runner-DvFWoz8-.d.mts.map} +1 -1
- package/dist/{runner-CFngB4WZ.mjs → runner-K8XK101B.mjs} +309 -190
- package/dist/runner-K8XK101B.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +2 -2
- package/dist/{scheduled-publish-BMljtY5G.d.mts → scheduled-publish-Drffrf2a.d.mts} +1 -1
- package/dist/scheduled-publish-Drffrf2a.d.mts.map +1 -0
- package/dist/{schema-BfJ7bIXH.mjs → schema-CX9cfNkZ.mjs} +5 -5
- package/dist/{schema-BfJ7bIXH.mjs.map → schema-CX9cfNkZ.mjs.map} +1 -1
- package/dist/{search-C7t3PH1J.mjs → search-DZN2HZ-V.mjs} +4 -4
- package/dist/{search-C7t3PH1J.mjs.map → search-DZN2HZ-V.mjs.map} +1 -1
- package/dist/{secrets-BSf9pRRY.mjs → secrets-kp760LlD.mjs} +2 -2
- package/dist/{secrets-BSf9pRRY.mjs.map → secrets-kp760LlD.mjs.map} +1 -1
- package/dist/{sections-Dm0CVX23.mjs → sections-CpF5SaGr.mjs} +3 -3
- package/dist/{sections-Dm0CVX23.mjs.map → sections-CpF5SaGr.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +19 -18
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/{seo-BkhuuaaE.mjs → seo-89-53DDs.mjs} +1 -1
- package/dist/{seo-BkhuuaaE.mjs.map → seo-89-53DDs.mjs.map} +1 -1
- package/dist/{seo-Dd3tbY_k.mjs → seo-DXu2UQnC.mjs} +3 -3
- package/dist/{seo-Dd3tbY_k.mjs.map → seo-DXu2UQnC.mjs.map} +1 -1
- package/dist/{service-CTrqp_Jy.mjs → service-DQmiBMzt.mjs} +3 -3
- package/dist/{service-CTrqp_Jy.mjs.map → service-DQmiBMzt.mjs.map} +1 -1
- package/dist/{session-user-B8aLtKAH.mjs → session-user-Cascbax7.mjs} +1 -1
- package/dist/{session-user-B8aLtKAH.mjs.map → session-user-Cascbax7.mjs.map} +1 -1
- package/dist/{settings-CZ7ZP9cW.mjs → settings-rZyHEcNT.mjs} +3 -3
- package/dist/{settings-CZ7ZP9cW.mjs.map → settings-rZyHEcNT.mjs.map} +1 -1
- package/dist/{settings-BX8cWBus.mjs → settings-zhmdKyJQ.mjs} +5 -5
- package/dist/{settings-BX8cWBus.mjs.map → settings-zhmdKyJQ.mjs.map} +1 -1
- package/dist/{setup-complete-gEiySUc-.mjs → setup-complete-Cb3LRyzy.mjs} +1 -1
- package/dist/{setup-complete-gEiySUc-.mjs.map → setup-complete-Cb3LRyzy.mjs.map} +1 -1
- package/dist/{setup-nonce-DzS50zme.mjs → setup-nonce-Z8x0tHf8.mjs} +1 -1
- package/dist/{setup-nonce-DzS50zme.mjs.map → setup-nonce-Z8x0tHf8.mjs.map} +1 -1
- package/dist/{single-flight-cache-Cdfkic3t.mjs → single-flight-cache-BG3B_GhN.mjs} +1 -1
- package/dist/{single-flight-cache-Cdfkic3t.mjs.map → single-flight-cache-BG3B_GhN.mjs.map} +1 -1
- package/dist/{site-url-BLebyON8.mjs → site-url-BBfDTgZB.mjs} +1 -1
- package/dist/{site-url-BLebyON8.mjs.map → site-url-BBfDTgZB.mjs.map} +1 -1
- package/dist/{ssrf-BRKb343l.mjs → ssrf-1g7usGBg.mjs} +1 -1
- package/dist/{ssrf-BRKb343l.mjs.map → ssrf-1g7usGBg.mjs.map} +1 -1
- package/dist/{status-vUK0SA17.mjs → status-CqJQX1QN.mjs} +1 -1
- package/dist/{status-vUK0SA17.mjs.map → status-CqJQX1QN.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-DChKcVxf.mjs → taxonomies-Bs13SN-F.mjs} +4 -4
- package/dist/{taxonomies-DChKcVxf.mjs.map → taxonomies-Bs13SN-F.mjs.map} +1 -1
- package/dist/{taxonomies-ckPjz-6d.mjs → taxonomies-kH9ABDUF.mjs} +7 -7
- package/dist/{taxonomies-ckPjz-6d.mjs.map → taxonomies-kH9ABDUF.mjs.map} +1 -1
- package/dist/{taxonomy-Cru-he6s.mjs → taxonomy-BxGxZZdu.mjs} +4 -4
- package/dist/{taxonomy-Cru-he6s.mjs.map → taxonomy-BxGxZZdu.mjs.map} +1 -1
- package/dist/{tokens-LeuXF9gG.mjs → tokens-BGT0TUUo.mjs} +1 -1
- package/dist/{tokens-LeuXF9gG.mjs.map → tokens-BGT0TUUo.mjs.map} +1 -1
- package/dist/{transport-Blrl2k_o.d.mts → transport-BMDWHSgZ.d.mts} +1 -1
- package/dist/{transport-Blrl2k_o.d.mts.map → transport-BMDWHSgZ.d.mts.map} +1 -1
- package/dist/{transport-_2nBz7e9.mjs → transport-DPefPMcz.mjs} +1 -1
- package/dist/{transport-_2nBz7e9.mjs.map → transport-DPefPMcz.mjs.map} +1 -1
- package/dist/{trusted-proxy-DZY5WCn2.mjs → trusted-proxy-VTPRiX2s.mjs} +1 -1
- package/dist/{trusted-proxy-DZY5WCn2.mjs.map → trusted-proxy-VTPRiX2s.mjs.map} +1 -1
- package/dist/{types-ETmO_jQr.d.mts → types-BcLUUbbR.d.mts} +2 -2
- package/dist/{types-ETmO_jQr.d.mts.map → types-BcLUUbbR.d.mts.map} +1 -1
- package/dist/{types-BYnDBVwe.d.mts → types-CGbYowGQ.d.mts} +2 -2
- package/dist/{types-BYnDBVwe.d.mts.map → types-CGbYowGQ.d.mts.map} +1 -1
- package/dist/{types-CvuKO5Pn.d.mts → types-CgvhU-hF.d.mts} +1 -1
- package/dist/{types-CvuKO5Pn.d.mts.map → types-CgvhU-hF.d.mts.map} +1 -1
- package/dist/{types-Y09-wtyU.d.mts → types-ClUkdbWb.d.mts} +1 -1
- package/dist/{types-Y09-wtyU.d.mts.map → types-ClUkdbWb.d.mts.map} +1 -1
- package/dist/{types-DU4TSFS5.mjs → types-CuW0zWDA.mjs} +2 -2
- package/dist/{types-DU4TSFS5.mjs.map → types-CuW0zWDA.mjs.map} +1 -1
- package/dist/{types-BkZ8DUEI.d.mts → types-DmHk7vAt.d.mts} +1 -1
- package/dist/{types-BkZ8DUEI.d.mts.map → types-DmHk7vAt.d.mts.map} +1 -1
- package/dist/{types-CQAugunJ.mjs → types-Jo3UYd6b.mjs} +1 -1
- package/dist/{types-CQAugunJ.mjs.map → types-Jo3UYd6b.mjs.map} +1 -1
- package/dist/{types-xIfVRNLp.d.mts → types-_HFLRzTn.d.mts} +22 -1
- package/dist/types-_HFLRzTn.d.mts.map +1 -0
- package/dist/{types-ByChcBgE.d.mts → types-ea9sAPck.d.mts} +1 -1
- package/dist/{types-ByChcBgE.d.mts.map → types-ea9sAPck.d.mts.map} +1 -1
- package/dist/{types-CNlaBFzx.d.mts → types-g_aFIdW0.d.mts} +1 -1
- package/dist/{types-CNlaBFzx.d.mts.map → types-g_aFIdW0.d.mts.map} +1 -1
- package/dist/{types-Dbqff978.d.mts → types-vgEWF18A.d.mts} +19 -1
- package/dist/{types-Dbqff978.d.mts.map → types-vgEWF18A.d.mts.map} +1 -1
- package/dist/{user-DgGbKL9s.mjs → user-BjAOvU3Z.mjs} +3 -3
- package/dist/{user-DgGbKL9s.mjs.map → user-BjAOvU3Z.mjs.map} +1 -1
- package/dist/{utils-B7A57fm9.mjs → utils-BJXElxdw.mjs} +156 -7
- package/dist/utils-BJXElxdw.mjs.map +1 -0
- package/dist/{validate-CRkcYZAR.mjs → validate-CWSnKVIJ.mjs} +2 -2
- package/dist/{validate-CRkcYZAR.mjs.map → validate-CWSnKVIJ.mjs.map} +1 -1
- package/dist/{validate-9ECmtEpJ.d.mts → validate-Z1b86_3B.d.mts} +5 -5
- package/dist/{validate-9ECmtEpJ.d.mts.map → validate-Z1b86_3B.d.mts.map} +1 -1
- package/dist/{validation-sR26SOwD.mjs → validation-0l8-RYj4.mjs} +8 -5
- package/dist/{validation-sR26SOwD.mjs.map → validation-0l8-RYj4.mjs.map} +1 -1
- package/dist/version-qmeO1XZY.mjs +7 -0
- package/dist/{version-CrqhKGWn.mjs.map → version-qmeO1XZY.mjs.map} +1 -1
- package/dist/{widgets-DRgtn7Cl.mjs → widgets-hWcIicX8.mjs} +3 -3
- package/dist/{widgets-DRgtn7Cl.mjs.map → widgets-hWcIicX8.mjs.map} +1 -1
- package/dist/wxr-taxonomies-0_uxSrmf.d.mts +34 -0
- package/dist/wxr-taxonomies-0_uxSrmf.d.mts.map +1 -0
- package/dist/wxr-taxonomies-CNFcsNCr.mjs +425 -0
- package/dist/wxr-taxonomies-CNFcsNCr.mjs.map +1 -0
- package/dist/{zod-generator-C5JaV--i.mjs → zod-generator-CacrR-i8.mjs} +2 -2
- package/dist/{zod-generator-C5JaV--i.mjs.map → zod-generator-CacrR-i8.mjs.map} +1 -1
- package/package.json +7 -7
- package/src/api/handlers/content.ts +10 -7
- package/src/api/schemas/import.ts +19 -0
- package/src/astro/integration/runtime.ts +3 -6
- package/src/astro/middleware/auth.ts +9 -3
- package/src/astro/middleware/csp.ts +54 -3
- package/src/astro/routes/admin.astro +9 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +122 -98
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +794 -44
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -15
- package/src/components/EmDashImage.astro +59 -23
- package/src/components/Image.astro +36 -35
- package/src/database/migrations/049_taxonomies_name_locale_index.ts +42 -0
- package/src/database/migrations/050_media_usage_index_status.ts +142 -0
- package/src/database/migrations/runner.ts +4 -0
- package/src/database/repositories/media-usage.ts +955 -59
- package/src/database/types.ts +22 -0
- package/src/emdash-runtime.ts +123 -3
- package/src/import/comments.ts +159 -0
- package/src/import/index.ts +8 -1
- package/src/import/settings.ts +65 -189
- package/src/import/sources/wordpress-plugin.ts +338 -42
- package/src/import/sources/wxr.ts +4 -1
- package/src/import/types.ts +12 -0
- package/src/import/utils.ts +207 -0
- package/src/import/wxr-taxonomies.ts +39 -0
- package/src/loader.ts +13 -2
- package/src/media/usage/content-fields.ts +119 -0
- package/src/media/usage/content-refresh.ts +524 -0
- package/src/media/usage/content-repair.ts +675 -0
- package/src/media/usage/content-snapshots.ts +439 -0
- package/src/media/usage/extractor.ts +4 -4
- package/src/media/usage/source-key.ts +22 -0
- package/src/menus/index.ts +17 -1
- package/src/object-cache/index.ts +82 -7
- package/src/plugins/context.ts +100 -71
- package/src/schema/registry.ts +240 -154
- package/src/seed/apply.ts +156 -99
- package/dist/api-80kycR9o.mjs.map +0 -1
- package/dist/apply-DSypk6Iu.mjs.map +0 -1
- package/dist/byline-fields-eyJMblSr.mjs.map +0 -1
- package/dist/context-CzUU_WzL.mjs.map +0 -1
- package/dist/import-Bb1T9WJS.mjs.map +0 -1
- package/dist/index-DGIjmUXQ.d.mts.map +0 -1
- package/dist/loader-4K37qA-y.mjs.map +0 -1
- package/dist/object-cache-CHbHv83-.mjs.map +0 -1
- package/dist/registry-DP-iEtdR.mjs.map +0 -1
- package/dist/runner-CFngB4WZ.mjs.map +0 -1
- package/dist/scheduled-publish-BMljtY5G.d.mts.map +0 -1
- package/dist/types-xIfVRNLp.d.mts.map +0 -1
- package/dist/utils-B7A57fm9.mjs.map +0 -1
- package/dist/version-CrqhKGWn.mjs +0 -7
- /package/dist/{api-tokens-B4BQybOp.mjs → api-tokens-DsvvCtdh.mjs} +0 -0
- /package/dist/{ssrf-CcX9zvMK.mjs → ssrf-CmuGgCq3.mjs} +0 -0
- /package/dist/{types-BvbeGEtr.mjs → types-DROWRxYV.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-refresh-Br4gMzh8.mjs","names":["isRecord","isRecord","readString"],"sources":["../src/database/repositories/media-usage.ts","../src/media/usage/content-fields.ts","../src/media/usage/extractor.ts","../src/media/usage/source-key.ts","../src/media/usage/content-snapshots.ts","../src/media/usage/content-refresh.ts"],"sourcesContent":["import {\n\tsql,\n\ttype ExpressionBuilder,\n\ttype Insertable,\n\ttype Kysely,\n\ttype Selectable,\n\ttype Transaction,\n\ttype Updateable,\n} from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { MediaUsageContentSourceVariant } from \"../../media/usage/source-key.js\";\nimport type { MediaKind, MediaUsageReferenceType } from \"../../media/usage/types.js\";\nimport { chunks, SQL_BATCH_SIZE } from \"../../utils/chunks.js\";\nimport { withTransaction } from \"../transaction.js\";\nimport type {\n\tDatabase,\n\tMediaUsageIndexStatusTable,\n\tMediaUsageSourceTable,\n\tMediaUsageTable,\n} from \"../types.js\";\nimport { validateIdentifier } from \"../validate.js\";\nimport { decodeCursor, encodeCursor, type FindManyResult } from \"./types.js\";\n\ntype DatabaseExecutor = Kysely<Database> | Transaction<Database>;\ntype MediaUsageSourceNullableStringColumn =\n\t| \"source_fingerprint\"\n\t| \"source_updated_at\"\n\t| \"revision_id\"\n\t| \"updated_at\"\n\t| \"last_attempted_at\"\n\t| \"last_error_code\";\n\nconst OCCURRENCE_BIND_COLUMNS = 13;\nconst OCCURRENCE_INSERT_BATCH_SIZE = Math.max(\n\t1,\n\tMath.floor(SQL_BATCH_SIZE / OCCURRENCE_BIND_COLUMNS),\n);\n\nexport interface MediaUsageSourceInput {\n\tsourceKey: string;\n\tsourceType: string;\n\tcollectionSlug?: string | null;\n\tcontentId?: string | null;\n\tsourceVariant: MediaUsageContentSourceVariant;\n\tlocale?: string | null;\n\ttranslationGroup?: string | null;\n\tcontentSlug?: string | null;\n\tcontentTitle?: string | null;\n\tcontentStatus?: string | null;\n\tcontentScheduledAt?: string | null;\n\tcontentDeletedAt?: string | null;\n\trevisionId?: string | null;\n\tschemaVersion?: number;\n\tsourceUpdatedAt?: string | null;\n\tsourceVersion?: number | null;\n\tsourceFingerprint?: string | null;\n\tsourceCompleteness?: MediaUsageSourceCompleteness;\n\tlastAttemptedAt?: string | null;\n\tlastErrorCode?: string | null;\n}\n\nexport interface MediaUsageOccurrenceInput {\n\tfieldSlug: string;\n\tfieldPath: string;\n\toccurrenceIndex?: number;\n\treferenceType: MediaUsageReferenceType;\n\tmediaId: string | null;\n\tprovider: string;\n\tproviderAssetId: string;\n\tmediaKind?: MediaKind | null;\n\tmimeType?: string | null;\n}\n\nexport interface MediaUsageSource {\n\tsourceKey: string;\n\tsourceType: string;\n\tcollectionSlug: string | null;\n\tcontentId: string | null;\n\tsourceVariant: string;\n\tlocale: string | null;\n\ttranslationGroup: string | null;\n\tcontentSlug: string | null;\n\tcontentTitle: string | null;\n\tcontentStatus: string | null;\n\tcontentScheduledAt: string | null;\n\tcontentDeletedAt: string | null;\n\trevisionId: string | null;\n\tcurrentGeneration: string;\n\tschemaVersion: number;\n\tsourceUpdatedAt: string | null;\n\tsourceVersion: number | null;\n\tsourceFingerprint: string | null;\n\tsourceCompleteness: string;\n\tlastAttemptedAt: string | null;\n\tlastErrorCode: string | null;\n\tindexedAt: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface MediaUsageGuardedReplaceResult {\n\treplaced: boolean;\n\t/** Populated only when a guarded replacement did not win the current source row. */\n\tsource: MediaUsageSource | null;\n}\n\nexport interface MediaUsageGuardedDeleteResult {\n\tdeleted: boolean;\n\tsource: MediaUsageSource | null;\n}\n\nexport interface MediaUsageGuardedAbsentDeleteResult extends MediaUsageGuardedDeleteResult {\n\tcontentPresent: boolean;\n}\n\nexport interface MediaUsageGuardedAttemptResult {\n\tattempted: boolean;\n\t/** Populated only when a guarded attempted mark did not win the current source row. */\n\tsource: MediaUsageSource | null;\n}\n\nexport interface MediaUsageIndexStatusRepairInput extends MediaUsageIndexStatusIdentity {\n\trunToken: string;\n\tschemaVersion?: number;\n\tstartedAt: string;\n\tupdatedAt?: string;\n}\n\nexport interface MediaUsageIndexStatusFinalizeInput extends MediaUsageIndexStatusIdentity {\n\trunToken: string;\n\tstatus: Exclude<MediaUsageIndexStatusValue, \"never\" | \"running\" | \"stale\">;\n\tschemaVersion?: number;\n\tcompletedAt: string;\n\tindexedSourceCount?: number;\n\tfailedSourceCount?: number;\n\tlastErrorCode?: string | null;\n\tupdatedAt?: string;\n}\n\nexport interface MediaUsageGuardedIndexStatusResult {\n\tfinalized: boolean;\n\tstatus: MediaUsageIndexStatus | null;\n}\n\nexport type MediaUsageSourceCompleteness =\n\t| \"unknown\"\n\t| \"complete\"\n\t| \"partial\"\n\t| \"failed\"\n\t| \"unsupported\";\n\nexport type MediaUsageIndexStatusValue =\n\t| \"never\"\n\t| \"running\"\n\t| \"complete\"\n\t| \"partial\"\n\t| \"failed\"\n\t| \"stale\";\n\nexport interface MediaUsageIndexStatusIdentity {\n\tadapterId: string;\n\tscopeType: string;\n\tscopeKey: string;\n}\n\nexport interface MediaUsageIndexStatusInput extends MediaUsageIndexStatusIdentity {\n\tstatus: MediaUsageIndexStatusValue;\n\tschemaVersion?: number;\n\tstartedAt?: string | null;\n\tcompletedAt?: string | null;\n\tcursor?: string | null;\n\tindexedSourceCount?: number;\n\tfailedSourceCount?: number;\n\tlastErrorCode?: string | null;\n\tupdatedAt?: string;\n}\n\nexport interface MediaUsageIndexStatus extends MediaUsageIndexStatusIdentity {\n\tstatus: string;\n\tschemaVersion: number;\n\tstartedAt: string | null;\n\tcompletedAt: string | null;\n\tcursor: string | null;\n\tindexedSourceCount: number;\n\tfailedSourceCount: number;\n\tlastErrorCode: string | null;\n\tupdatedAt: string;\n}\n\nexport interface FindMediaUsageOptions {\n\tlimit?: number;\n\tcursor?: string;\n}\n\ninterface MediaUsageSourceRow {\n\tsource_key: string;\n\tsource_type: string;\n\tcollection_slug: string | null;\n\tcontent_id: string | null;\n\tsource_variant: string;\n\tlocale: string | null;\n\ttranslation_group: string | null;\n\tcontent_slug: string | null;\n\tcontent_title: string | null;\n\tcontent_status: string | null;\n\tcontent_scheduled_at: string | null;\n\tcontent_deleted_at: string | null;\n\trevision_id: string | null;\n\tcurrent_generation: string;\n\tschema_version: number;\n\tsource_updated_at: string | null;\n\tsource_version: number | null;\n\tsource_fingerprint: string | null;\n\tsource_completeness: string;\n\tlast_attempted_at: string | null;\n\tlast_error_code: string | null;\n\tindexed_at: string;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport interface MediaUsageOccurrence {\n\tid: string;\n\tsourceKey: string;\n\tgeneration: string;\n\tfieldSlug: string;\n\tfieldPath: string;\n\toccurrenceIndex: number;\n\treferenceType: string;\n\tmediaId: string | null;\n\tprovider: string;\n\tproviderAssetId: string;\n\tmediaKind: string | null;\n\tmimeType: string | null;\n\tcreatedAt: string;\n}\n\nexport interface MediaUsageRecord {\n\tsource: MediaUsageSource;\n\toccurrence: MediaUsageOccurrence;\n}\n\ninterface JoinedUsageRow {\n\tsource_key: string;\n\tsource_type: string;\n\tcollection_slug: string | null;\n\tcontent_id: string | null;\n\tsource_variant: string;\n\tlocale: string | null;\n\ttranslation_group: string | null;\n\tcontent_slug: string | null;\n\tcontent_title: string | null;\n\tcontent_status: string | null;\n\tcontent_scheduled_at: string | null;\n\tcontent_deleted_at: string | null;\n\trevision_id: string | null;\n\tcurrent_generation: string;\n\tschema_version: number;\n\tsource_updated_at: string | null;\n\tsource_version: number | null;\n\tsource_fingerprint: string | null;\n\tsource_completeness: string;\n\tlast_attempted_at: string | null;\n\tlast_error_code: string | null;\n\tindexed_at: string;\n\tsource_created_at: string;\n\tsource_row_updated_at: string;\n\toccurrence_id: string;\n\tgeneration: string;\n\tfield_slug: string;\n\tfield_path: string;\n\toccurrence_index: number;\n\treference_type: string;\n\tmedia_id: string | null;\n\tprovider: string;\n\tprovider_asset_id: string;\n\tmedia_kind: string | null;\n\tmime_type: string | null;\n\toccurrence_created_at: string;\n}\n\n/** Persistence-only repository for the internal media usage projection tables. */\nexport class MediaUsageRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\tasync replaceSource(\n\t\tsource: MediaUsageSourceInput,\n\t\toccurrences: readonly MediaUsageOccurrenceInput[],\n\t): Promise<MediaUsageSource> {\n\t\tconst generation = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait this.insertOccurrences(trx, source.sourceKey, generation, occurrences, now);\n\t\t\tawait this.upsertSource(trx, source, generation, now);\n\t\t});\n\n\t\tconst replaced = await this.findSource(source.sourceKey);\n\t\tif (!replaced) {\n\t\t\tthrow new Error(`Media usage source ${source.sourceKey} was not persisted`);\n\t\t}\n\t\treturn replaced;\n\t}\n\tasync replaceSourceIfCurrent(\n\t\tsource: MediaUsageSourceInput,\n\t\toccurrences: readonly MediaUsageOccurrenceInput[],\n\t\texpectedCurrentGeneration: string | null,\n\t): Promise<MediaUsageGuardedReplaceResult> {\n\t\tconst generation = ulid();\n\t\tconst now = new Date().toISOString();\n\t\tconst row = this.buildSourceRow(source, generation, now);\n\t\tlet replaced = false;\n\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait this.insertOccurrences(trx, source.sourceKey, generation, occurrences, now);\n\t\t\tif (expectedCurrentGeneration === null) {\n\t\t\t\treplaced = await this.insertSourceIfAbsent(trx, row);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treplaced = await this.updateSourceIfGeneration(trx, row, expectedCurrentGeneration);\n\t\t});\n\n\t\treturn {\n\t\t\treplaced,\n\t\t\tsource: replaced ? null : await this.findSource(source.sourceKey),\n\t\t};\n\t}\n\n\tasync findSource(sourceKey: string): Promise<MediaUsageSource | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t\t.selectAll()\n\t\t\t.where(\"source_key\", \"=\", sourceKey)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? rowToSource(row) : null;\n\t}\n\n\tasync findSources(sourceKeys: readonly string[]): Promise<Map<string, MediaUsageSource>> {\n\t\tconst uniqueSourceKeys = [...new Set(sourceKeys)];\n\t\tconst sources = new Map<string, MediaUsageSource>();\n\t\tif (uniqueSourceKeys.length === 0) return sources;\n\n\t\tfor (const sourceKeyBatch of chunks(uniqueSourceKeys, SQL_BATCH_SIZE)) {\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t.selectAll()\n\t\t\t\t.where(\"source_key\", \"in\", sourceKeyBatch)\n\t\t\t\t.execute();\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst source = rowToSource(row);\n\t\t\t\tsources.set(source.sourceKey, source);\n\t\t\t}\n\t\t}\n\n\t\treturn sources;\n\t}\n\n\tasync replaceSourceIfMatching(\n\t\tsource: MediaUsageSourceInput,\n\t\toccurrences: readonly MediaUsageOccurrenceInput[],\n\t\texpectedSource: MediaUsageSource | null,\n\t): Promise<MediaUsageGuardedReplaceResult> {\n\t\tconst generation = ulid();\n\t\tconst now = new Date().toISOString();\n\t\tconst row = this.buildSourceRow(source, generation, now);\n\t\tlet replaced = false;\n\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait this.insertOccurrences(trx, source.sourceKey, generation, occurrences, now);\n\t\t\tif (expectedSource === null) {\n\t\t\t\treplaced = await this.insertSourceIfAbsent(trx, row);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treplaced = await this.updateSourceIfMatching(trx, row, expectedSource);\n\t\t});\n\n\t\treturn {\n\t\t\treplaced,\n\t\t\tsource: replaced ? null : await this.findSource(source.sourceKey),\n\t\t};\n\t}\n\n\tasync markSourceAttempted(source: MediaUsageSourceInput): Promise<MediaUsageSource> {\n\t\tconst now = new Date().toISOString();\n\t\tconst row = this.buildAttemptedSourceRow(source, now);\n\t\tconst updates = this.attemptedSourceUpdateSet(source, row);\n\n\t\tawait this.db\n\t\t\t.insertInto(\"_emdash_media_usage_sources\")\n\t\t\t.values(row)\n\t\t\t.onConflict((oc) => oc.column(\"source_key\").doUpdateSet(updates))\n\t\t\t.execute();\n\n\t\tconst attempted = await this.findSource(source.sourceKey);\n\t\tif (!attempted) {\n\t\t\tthrow new Error(`Media usage source ${source.sourceKey} was not persisted`);\n\t\t}\n\t\treturn attempted;\n\t}\n\n\tasync markSourceAttemptedIfMatching(\n\t\tsource: MediaUsageSourceInput,\n\t\texpectedSource: MediaUsageSource | null,\n\t): Promise<MediaUsageGuardedAttemptResult> {\n\t\tconst now = new Date().toISOString();\n\t\tconst row = this.buildAttemptedSourceRow(source, now);\n\t\tlet attempted = false;\n\n\t\tif (expectedSource === null) {\n\t\t\tattempted = await this.insertSourceIfAbsent(this.db, row);\n\t\t} else {\n\t\t\tattempted = await this.updateAttemptedSourceIfMatching(this.db, source, row, expectedSource);\n\t\t}\n\n\t\treturn {\n\t\t\tattempted,\n\t\t\tsource: attempted ? null : await this.findSource(source.sourceKey),\n\t\t};\n\t}\n\n\tasync findCurrentUsageByMediaId(mediaId: string): Promise<MediaUsageRecord[]> {\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources as s\")\n\t\t\t.innerJoin(\"_emdash_media_usage as u\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"u.source_key\", \"=\", \"s.source_key\")\n\t\t\t\t\t.onRef(\"u.generation\", \"=\", \"s.current_generation\"),\n\t\t\t)\n\t\t\t.select(currentUsageSelect)\n\t\t\t.where(\"u.media_id\", \"=\", mediaId)\n\t\t\t.orderBy(\"s.source_key\", \"asc\")\n\t\t\t.orderBy(\"u.field_path\", \"asc\")\n\t\t\t.orderBy(\"u.occurrence_index\", \"asc\")\n\t\t\t.execute();\n\n\t\treturn rows.map(rowToUsageRecord);\n\t}\n\n\tasync findCurrentUsageByProviderAsset(\n\t\tprovider: string,\n\t\tproviderAssetId: string,\n\t): Promise<MediaUsageRecord[]> {\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources as s\")\n\t\t\t.innerJoin(\"_emdash_media_usage as u\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"u.source_key\", \"=\", \"s.source_key\")\n\t\t\t\t\t.onRef(\"u.generation\", \"=\", \"s.current_generation\"),\n\t\t\t)\n\t\t\t.select(currentUsageSelect)\n\t\t\t.where(\"u.provider\", \"=\", provider)\n\t\t\t.where(\"u.provider_asset_id\", \"=\", providerAssetId)\n\t\t\t.orderBy(\"s.source_key\", \"asc\")\n\t\t\t.orderBy(\"u.field_path\", \"asc\")\n\t\t\t.orderBy(\"u.occurrence_index\", \"asc\")\n\t\t\t.execute();\n\n\t\treturn rows.map(rowToUsageRecord);\n\t}\n\n\tasync findCurrentUsagePageByMediaId(\n\t\tmediaId: string,\n\t\toptions: FindMediaUsageOptions = {},\n\t): Promise<FindManyResult<MediaUsageRecord>> {\n\t\treturn this.findCurrentUsagePage((query) => query.where(\"u.media_id\", \"=\", mediaId), options);\n\t}\n\n\tasync findCurrentUsagePageByProviderAsset(\n\t\tprovider: string,\n\t\tproviderAssetId: string,\n\t\toptions: FindMediaUsageOptions = {},\n\t): Promise<FindManyResult<MediaUsageRecord>> {\n\t\treturn this.findCurrentUsagePage(\n\t\t\t(query) =>\n\t\t\t\tquery.where(\"u.provider\", \"=\", provider).where(\"u.provider_asset_id\", \"=\", providerAssetId),\n\t\t\toptions,\n\t\t);\n\t}\n\n\tasync deleteSource(sourceKey: string): Promise<number> {\n\t\treturn this.deleteSources([sourceKey]);\n\t}\n\n\tasync deleteSourceIfCurrent(\n\t\tsourceKey: string,\n\t\texpectedCurrentGeneration: string,\n\t): Promise<MediaUsageGuardedDeleteResult> {\n\t\tlet deleted = false;\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tconst result = await trx\n\t\t\t\t.deleteFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t.where(\"source_key\", \"=\", sourceKey)\n\t\t\t\t.where(\"current_generation\", \"=\", expectedCurrentGeneration)\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted = Number(result.numDeletedRows ?? 0) > 0;\n\t\t\tif (!deleted) return;\n\t\t\tawait this.deleteSourceGenerationOccurrences(trx, sourceKey, expectedCurrentGeneration);\n\t\t});\n\n\t\treturn {\n\t\t\tdeleted,\n\t\t\tsource: await this.findSource(sourceKey),\n\t\t};\n\t}\n\n\tasync deleteSourceIfMatching(\n\t\tsourceKey: string,\n\t\texpectedSource: MediaUsageSource,\n\t): Promise<MediaUsageGuardedDeleteResult> {\n\t\tlet deleted = false;\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tconst result = await trx\n\t\t\t\t.deleteFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t.where(\"source_key\", \"=\", sourceKey)\n\t\t\t\t.where(this.sourceMatchExpression(expectedSource))\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted = Number(result.numDeletedRows ?? 0) > 0;\n\t\t\tif (!deleted) return;\n\t\t\tawait this.deleteSourceGenerationOccurrences(\n\t\t\t\ttrx,\n\t\t\t\tsourceKey,\n\t\t\t\texpectedSource.currentGeneration,\n\t\t\t);\n\t\t});\n\n\t\treturn {\n\t\t\tdeleted,\n\t\t\tsource: await this.findSource(sourceKey),\n\t\t};\n\t}\n\n\tasync deleteSourceIfMatchingContentAbsent(\n\t\tsourceKey: string,\n\t\texpectedSource: MediaUsageSource,\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t): Promise<MediaUsageGuardedAbsentDeleteResult> {\n\t\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\t\tconst tableName = `ec_${collectionSlug}`;\n\t\tlet deleted = false;\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tconst result = await trx\n\t\t\t\t.deleteFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t.where(\"source_key\", \"=\", sourceKey)\n\t\t\t\t.where(this.sourceMatchExpression(expectedSource))\n\t\t\t\t.where(\n\t\t\t\t\tsql<boolean>`NOT EXISTS (SELECT 1 FROM ${sql.ref(tableName)} WHERE id = ${contentId})`,\n\t\t\t\t)\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted = Number(result.numDeletedRows ?? 0) > 0;\n\t\t\tif (!deleted) return;\n\t\t\tawait this.deleteSourceGenerationOccurrences(\n\t\t\t\ttrx,\n\t\t\t\tsourceKey,\n\t\t\t\texpectedSource.currentGeneration,\n\t\t\t);\n\t\t});\n\t\tconst contentPresent = deleted ? false : await this.contentRowExists(tableName, contentId);\n\n\t\treturn {\n\t\t\tdeleted,\n\t\t\tcontentPresent,\n\t\t\tsource: deleted || contentPresent ? null : await this.findSource(sourceKey),\n\t\t};\n\t}\n\n\tasync deleteSources(sourceKeys: readonly string[]): Promise<number> {\n\t\treturn this.deleteSourceKeys(sourceKeys);\n\t}\n\n\tasync deleteContentSources(collectionSlug: string, contentId: string): Promise<number> {\n\t\tconst sourceRows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t\t.select(\"source_key\")\n\t\t\t.where(\"source_type\", \"=\", \"content\")\n\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.execute();\n\t\tconst sourceKeys = sourceRows.map((row) => row.source_key);\n\t\treturn this.deleteSourceKeys(sourceKeys);\n\t}\n\n\tasync deleteCollectionSources(collectionSlug: string): Promise<number> {\n\t\tlet deleted = 0;\n\t\twhile (true) {\n\t\t\tconst sourceRows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t.select(\"source_key\")\n\t\t\t\t.where(\"source_type\", \"=\", \"content\")\n\t\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t\t.orderBy(\"source_key\", \"asc\")\n\t\t\t\t.limit(SQL_BATCH_SIZE)\n\t\t\t\t.execute();\n\t\t\tif (sourceRows.length === 0) break;\n\n\t\t\tdeleted += await this.deleteSourceKeys(sourceRows.map((row) => row.source_key));\n\t\t}\n\t\treturn deleted;\n\t}\n\n\tasync findCollectionContentSources(collectionSlug: string): Promise<MediaUsageSource[]> {\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t\t.selectAll()\n\t\t\t.where(\"source_type\", \"=\", \"content\")\n\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t.orderBy(\"source_key\", \"asc\")\n\t\t\t.execute();\n\t\treturn rows.map((row) => rowToSource(row));\n\t}\n\n\tasync deleteOrphanOccurrencesOlderThan(cutoff: string, limit: number): Promise<number> {\n\t\tconst batchLimit = Math.floor(limit);\n\t\tif (batchLimit <= 0) return 0;\n\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage as u\")\n\t\t\t.leftJoin(\"_emdash_media_usage_sources as s\", (join) =>\n\t\t\t\tjoin.onRef(\"s.source_key\", \"=\", \"u.source_key\"),\n\t\t\t)\n\t\t\t.select(\"u.id\")\n\t\t\t.where(\"s.source_key\", \"is\", null)\n\t\t\t.where(\"u.created_at\", \"<\", cutoff)\n\t\t\t.orderBy(\"u.created_at\", \"asc\")\n\t\t\t.orderBy(\"u.id\", \"asc\")\n\t\t\t.limit(batchLimit)\n\t\t\t.execute();\n\n\t\tlet deleted = 0;\n\t\tfor (const idBatch of chunks(\n\t\t\trows.map((row) => row.id),\n\t\t\tSQL_BATCH_SIZE,\n\t\t)) {\n\t\t\tconst result = await this.db\n\t\t\t\t.deleteFrom(\"_emdash_media_usage\")\n\t\t\t\t.where(\"id\", \"in\", idBatch)\n\t\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t\t.where(\n\t\t\t\t\tsql<boolean>`NOT EXISTS (SELECT 1 FROM _emdash_media_usage_sources s WHERE s.source_key = _emdash_media_usage.source_key)`,\n\t\t\t\t)\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted += Number(result.numDeletedRows ?? 0);\n\t\t}\n\t\treturn deleted;\n\t}\n\n\tasync deleteStaleGenerationsOlderThan(cutoff: string, limit: number): Promise<number> {\n\t\tconst batchLimit = Math.floor(limit);\n\t\tif (batchLimit <= 0) return 0;\n\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage as u\")\n\t\t\t.innerJoin(\"_emdash_media_usage_sources as s\", (join) =>\n\t\t\t\tjoin.onRef(\"s.source_key\", \"=\", \"u.source_key\"),\n\t\t\t)\n\t\t\t.select(\"u.id\")\n\t\t\t.where(\"u.created_at\", \"<\", cutoff)\n\t\t\t.whereRef(\"u.generation\", \"!=\", \"s.current_generation\")\n\t\t\t.whereRef(\"u.created_at\", \"<\", \"s.indexed_at\")\n\t\t\t.orderBy(\"u.created_at\", \"asc\")\n\t\t\t.orderBy(\"u.id\", \"asc\")\n\t\t\t.limit(batchLimit)\n\t\t\t.execute();\n\n\t\tconst ids = rows.map((row) => row.id);\n\t\tif (ids.length === 0) return 0;\n\n\t\tlet deleted = 0;\n\t\tfor (const idBatch of chunks(ids, SQL_BATCH_SIZE)) {\n\t\t\tconst result = await this.db\n\t\t\t\t.deleteFrom(\"_emdash_media_usage\")\n\t\t\t\t.where(\"id\", \"in\", idBatch)\n\t\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t\t.where((eb) =>\n\t\t\t\t\teb.exists(\n\t\t\t\t\t\teb\n\t\t\t\t\t\t\t.selectFrom(\"_emdash_media_usage_sources as s\")\n\t\t\t\t\t\t\t.select(\"s.source_key\")\n\t\t\t\t\t\t\t.whereRef(\"s.source_key\", \"=\", \"_emdash_media_usage.source_key\")\n\t\t\t\t\t\t\t.whereRef(\"s.current_generation\", \"!=\", \"_emdash_media_usage.generation\")\n\t\t\t\t\t\t\t.whereRef(\"_emdash_media_usage.created_at\", \"<\", \"s.indexed_at\"),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted += Number(result.numDeletedRows ?? 0);\n\t\t}\n\t\treturn deleted;\n\t}\n\n\tasync deleteAbandonedGenerationsOlderThan(cutoff: string, limit: number): Promise<number> {\n\t\tconst batchLimit = Math.floor(limit);\n\t\tif (batchLimit <= 0) return 0;\n\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage as u\")\n\t\t\t.innerJoin(\"_emdash_media_usage_sources as s\", (join) =>\n\t\t\t\tjoin.onRef(\"s.source_key\", \"=\", \"u.source_key\"),\n\t\t\t)\n\t\t\t.select(\"u.id\")\n\t\t\t.where(\"u.created_at\", \"<\", cutoff)\n\t\t\t.whereRef(\"u.generation\", \"!=\", \"s.current_generation\")\n\t\t\t.whereRef(\"u.created_at\", \">=\", \"s.indexed_at\")\n\t\t\t.orderBy(\"u.created_at\", \"asc\")\n\t\t\t.orderBy(\"u.id\", \"asc\")\n\t\t\t.limit(batchLimit)\n\t\t\t.execute();\n\n\t\tlet deleted = 0;\n\t\tfor (const idBatch of chunks(\n\t\t\trows.map((row) => row.id),\n\t\t\tSQL_BATCH_SIZE,\n\t\t)) {\n\t\t\tconst result = await this.db\n\t\t\t\t.deleteFrom(\"_emdash_media_usage\")\n\t\t\t\t.where(\"id\", \"in\", idBatch)\n\t\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t\t.where((eb) =>\n\t\t\t\t\teb.exists(\n\t\t\t\t\t\teb\n\t\t\t\t\t\t\t.selectFrom(\"_emdash_media_usage_sources as s\")\n\t\t\t\t\t\t\t.select(\"s.source_key\")\n\t\t\t\t\t\t\t.whereRef(\"s.source_key\", \"=\", \"_emdash_media_usage.source_key\")\n\t\t\t\t\t\t\t.whereRef(\"s.current_generation\", \"!=\", \"_emdash_media_usage.generation\")\n\t\t\t\t\t\t\t.whereRef(\"_emdash_media_usage.created_at\", \">=\", \"s.indexed_at\"),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.executeTakeFirst();\n\t\t\tdeleted += Number(result.numDeletedRows ?? 0);\n\t\t}\n\t\treturn deleted;\n\t}\n\n\tasync upsertIndexStatus(input: MediaUsageIndexStatusInput): Promise<MediaUsageIndexStatus> {\n\t\tconst now = input.updatedAt ?? new Date().toISOString();\n\t\tconst row = {\n\t\t\tadapter_id: input.adapterId,\n\t\t\tscope_type: input.scopeType,\n\t\t\tscope_key: input.scopeKey,\n\t\t\tstatus: input.status,\n\t\t\tschema_version: input.schemaVersion ?? 1,\n\t\t\tstarted_at: input.startedAt ?? null,\n\t\t\tcompleted_at: input.completedAt ?? null,\n\t\t\tcursor: input.cursor ?? null,\n\t\t\tindexed_source_count: input.indexedSourceCount ?? 0,\n\t\t\tfailed_source_count: input.failedSourceCount ?? 0,\n\t\t\tlast_error_code: input.lastErrorCode ?? null,\n\t\t\tupdated_at: now,\n\t\t};\n\n\t\tawait this.db\n\t\t\t.insertInto(\"_emdash_media_usage_index_status\")\n\t\t\t.values(row)\n\t\t\t.onConflict((oc) =>\n\t\t\t\toc.columns([\"adapter_id\", \"scope_type\", \"scope_key\"]).doUpdateSet({\n\t\t\t\t\tstatus: row.status,\n\t\t\t\t\tschema_version: row.schema_version,\n\t\t\t\t\tstarted_at: row.started_at,\n\t\t\t\t\tcompleted_at: row.completed_at,\n\t\t\t\t\tcursor: row.cursor,\n\t\t\t\t\tindexed_source_count: row.indexed_source_count,\n\t\t\t\t\tfailed_source_count: row.failed_source_count,\n\t\t\t\t\tlast_error_code: row.last_error_code,\n\t\t\t\t\tupdated_at: row.updated_at,\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.execute();\n\n\t\tconst status = await this.findIndexStatus(input);\n\t\tif (!status) {\n\t\t\tthrow new Error(\n\t\t\t\t`Media usage index status ${input.adapterId}:${input.scopeType}:${input.scopeKey} was not persisted`,\n\t\t\t);\n\t\t}\n\t\treturn status;\n\t}\n\n\tasync beginIndexStatusRepair(\n\t\tinput: MediaUsageIndexStatusRepairInput,\n\t): Promise<MediaUsageIndexStatus> {\n\t\treturn this.upsertIndexStatus({\n\t\t\tadapterId: input.adapterId,\n\t\t\tscopeType: input.scopeType,\n\t\t\tscopeKey: input.scopeKey,\n\t\t\tstatus: \"running\",\n\t\t\tschemaVersion: input.schemaVersion,\n\t\t\tstartedAt: input.startedAt,\n\t\t\tcompletedAt: null,\n\t\t\tcursor: input.runToken,\n\t\t\tindexedSourceCount: 0,\n\t\t\tfailedSourceCount: 0,\n\t\t\tlastErrorCode: null,\n\t\t\tupdatedAt: input.updatedAt,\n\t\t});\n\t}\n\n\tasync finalizeIndexStatusRepairIfRunning(\n\t\tinput: MediaUsageIndexStatusFinalizeInput,\n\t): Promise<MediaUsageGuardedIndexStatusResult> {\n\t\tconst updates: Updateable<MediaUsageIndexStatusTable> = {\n\t\t\tstatus: input.status,\n\t\t\tcompleted_at: input.completedAt,\n\t\t\tcursor: null,\n\t\t\tindexed_source_count: input.indexedSourceCount ?? 0,\n\t\t\tfailed_source_count: input.failedSourceCount ?? 0,\n\t\t\tlast_error_code: input.lastErrorCode ?? null,\n\t\t\tupdated_at: input.updatedAt ?? new Date().toISOString(),\n\t\t};\n\t\tif (input.schemaVersion !== undefined) updates.schema_version = input.schemaVersion;\n\n\t\tconst result = await this.db\n\t\t\t.updateTable(\"_emdash_media_usage_index_status\")\n\t\t\t.set(updates)\n\t\t\t.where(\"adapter_id\", \"=\", input.adapterId)\n\t\t\t.where(\"scope_type\", \"=\", input.scopeType)\n\t\t\t.where(\"scope_key\", \"=\", input.scopeKey)\n\t\t\t.where(\"status\", \"=\", \"running\")\n\t\t\t.where(\"cursor\", \"=\", input.runToken)\n\t\t\t.executeTakeFirst();\n\t\tconst finalized = Number(result.numUpdatedRows ?? 0) > 0;\n\n\t\treturn {\n\t\t\tfinalized,\n\t\t\tstatus: await this.findIndexStatus(input),\n\t\t};\n\t}\n\n\tasync findIndexStatus(\n\t\tidentity: MediaUsageIndexStatusIdentity,\n\t): Promise<MediaUsageIndexStatus | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_index_status\")\n\t\t\t.selectAll()\n\t\t\t.where(\"adapter_id\", \"=\", identity.adapterId)\n\t\t\t.where(\"scope_type\", \"=\", identity.scopeType)\n\t\t\t.where(\"scope_key\", \"=\", identity.scopeKey)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? rowToIndexStatus(row) : null;\n\t}\n\n\tasync deleteIndexStatus(identity: MediaUsageIndexStatusIdentity): Promise<number> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_media_usage_index_status\")\n\t\t\t.where(\"adapter_id\", \"=\", identity.adapterId)\n\t\t\t.where(\"scope_type\", \"=\", identity.scopeType)\n\t\t\t.where(\"scope_key\", \"=\", identity.scopeKey)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\tprivate async findCurrentUsagePage(\n\t\tapplyFilter: (\n\t\t\tquery: ReturnType<MediaUsageRepository[\"currentUsageBaseQuery\"]>,\n\t\t) => ReturnType<MediaUsageRepository[\"currentUsageBaseQuery\"]>,\n\t\toptions: FindMediaUsageOptions,\n\t): Promise<FindManyResult<MediaUsageRecord>> {\n\t\tconst limit = Math.min(Math.max(1, options.limit ?? 50), 100);\n\t\tlet query = applyFilter(this.currentUsageBaseQuery())\n\t\t\t.orderBy(\"u.id\", \"asc\")\n\t\t\t.limit(limit + 1);\n\n\t\tif (options.cursor) {\n\t\t\tconst { id } = decodeCursor(options.cursor);\n\t\t\tquery = query.where(\"u.id\", \">\", id);\n\t\t}\n\n\t\tconst rows = await query.execute();\n\t\tconst items = rows.slice(0, limit).map(rowToUsageRecord);\n\t\tconst result: FindManyResult<MediaUsageRecord> = { items };\n\n\t\tif (rows.length > limit && items.length > 0) {\n\t\t\tconst last = items.at(-1)!;\n\t\t\tresult.nextCursor = encodeCursor(last.occurrence.id, last.occurrence.id);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate currentUsageBaseQuery() {\n\t\treturn this.db\n\t\t\t.selectFrom(\"_emdash_media_usage_sources as s\")\n\t\t\t.innerJoin(\"_emdash_media_usage as u\", (join) =>\n\t\t\t\tjoin\n\t\t\t\t\t.onRef(\"u.source_key\", \"=\", \"s.source_key\")\n\t\t\t\t\t.onRef(\"u.generation\", \"=\", \"s.current_generation\"),\n\t\t\t)\n\t\t\t.select(currentUsageSelect);\n\t}\n\n\tprivate async deleteSourceKeys(sourceKeys: readonly string[]): Promise<number> {\n\t\tconst uniqueSourceKeys = [...new Set(sourceKeys)];\n\t\tif (uniqueSourceKeys.length === 0) return 0;\n\n\t\treturn withTransaction(this.db, async (trx) => {\n\t\t\tlet deleted = 0;\n\t\t\tfor (const sourceKeyBatch of chunks(uniqueSourceKeys, SQL_BATCH_SIZE)) {\n\t\t\t\tconst result = await trx\n\t\t\t\t\t.deleteFrom(\"_emdash_media_usage_sources\")\n\t\t\t\t\t.where(\"source_key\", \"in\", sourceKeyBatch)\n\t\t\t\t\t.executeTakeFirst();\n\t\t\t\tdeleted += Number(result.numDeletedRows ?? 0);\n\n\t\t\t\tawait trx\n\t\t\t\t\t.deleteFrom(\"_emdash_media_usage\")\n\t\t\t\t\t.where(\"source_key\", \"in\", sourceKeyBatch)\n\t\t\t\t\t.execute();\n\t\t\t}\n\t\t\treturn deleted;\n\t\t});\n\t}\n\n\tprivate async deleteSourceGenerationOccurrences(\n\t\tdb: DatabaseExecutor,\n\t\tsourceKey: string,\n\t\tgeneration: string,\n\t): Promise<void> {\n\t\t// Guarded source deletes remove only the generation that won the source CAS;\n\t\t// unmatched generations become invisible orphans reclaimed by age-gated cleanup.\n\t\tawait db\n\t\t\t.deleteFrom(\"_emdash_media_usage\")\n\t\t\t.where(\"source_key\", \"=\", sourceKey)\n\t\t\t.where(\"generation\", \"=\", generation)\n\t\t\t.execute();\n\t}\n\n\tprivate async insertOccurrences(\n\t\tdb: DatabaseExecutor,\n\t\tsourceKey: string,\n\t\tgeneration: string,\n\t\toccurrences: readonly MediaUsageOccurrenceInput[],\n\t\tnow: string,\n\t): Promise<void> {\n\t\tif (occurrences.length === 0) return;\n\n\t\tconst rows = occurrences.map((occurrence) => ({\n\t\t\tid: ulid(),\n\t\t\tsource_key: sourceKey,\n\t\t\tgeneration,\n\t\t\tfield_slug: occurrence.fieldSlug,\n\t\t\tfield_path: occurrence.fieldPath,\n\t\t\toccurrence_index: occurrence.occurrenceIndex ?? 0,\n\t\t\treference_type: occurrence.referenceType,\n\t\t\tmedia_id: occurrence.mediaId,\n\t\t\tprovider: occurrence.provider,\n\t\t\tprovider_asset_id: occurrence.providerAssetId,\n\t\t\tmedia_kind: occurrence.mediaKind ?? null,\n\t\t\tmime_type: occurrence.mimeType ?? null,\n\t\t\tcreated_at: now,\n\t\t}));\n\n\t\tfor (const rowBatch of chunks(rows, OCCURRENCE_INSERT_BATCH_SIZE)) {\n\t\t\tawait db.insertInto(\"_emdash_media_usage\").values(rowBatch).execute();\n\t\t}\n\t}\n\n\tprivate async upsertSource(\n\t\tdb: DatabaseExecutor,\n\t\tsource: MediaUsageSourceInput,\n\t\tgeneration: string,\n\t\tnow: string,\n\t): Promise<void> {\n\t\tconst row = this.buildSourceRow(source, generation, now);\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_media_usage_sources\")\n\t\t\t.values(row)\n\t\t\t.onConflict((oc) => oc.column(\"source_key\").doUpdateSet(this.sourceUpdateSet(row)))\n\t\t\t.execute();\n\t}\n\n\tprivate async insertSourceIfAbsent(\n\t\tdb: DatabaseExecutor,\n\t\trow: Insertable<MediaUsageSourceTable>,\n\t): Promise<boolean> {\n\t\tconst result = await db\n\t\t\t.insertInto(\"_emdash_media_usage_sources\")\n\t\t\t.values(row)\n\t\t\t.onConflict((oc) => oc.column(\"source_key\").doNothing())\n\t\t\t.executeTakeFirst();\n\t\treturn (result.numInsertedOrUpdatedRows ?? 0n) > 0n;\n\t}\n\n\tprivate async updateSourceIfGeneration(\n\t\tdb: DatabaseExecutor,\n\t\trow: ReturnType<MediaUsageRepository[\"buildSourceRow\"]>,\n\t\texpectedCurrentGeneration: string,\n\t): Promise<boolean> {\n\t\tconst result = await db\n\t\t\t.updateTable(\"_emdash_media_usage_sources\")\n\t\t\t.set(this.sourceUpdateSet(row))\n\t\t\t.where(\"source_key\", \"=\", row.source_key)\n\t\t\t.where(\"current_generation\", \"=\", expectedCurrentGeneration)\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numUpdatedRows ?? 0) > 0;\n\t}\n\n\tprivate async updateSourceIfMatching(\n\t\tdb: DatabaseExecutor,\n\t\trow: ReturnType<MediaUsageRepository[\"buildSourceRow\"]>,\n\t\texpectedSource: MediaUsageSource,\n\t): Promise<boolean> {\n\t\tconst result = await db\n\t\t\t.updateTable(\"_emdash_media_usage_sources\")\n\t\t\t.set(this.sourceUpdateSet(row))\n\t\t\t.where(\"source_key\", \"=\", row.source_key)\n\t\t\t.where(this.sourceMatchExpression(expectedSource))\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numUpdatedRows ?? 0) > 0;\n\t}\n\n\tprivate async updateAttemptedSourceIfMatching(\n\t\tdb: DatabaseExecutor,\n\t\tsource: MediaUsageSourceInput,\n\t\trow: ReturnType<MediaUsageRepository[\"buildAttemptedSourceRow\"]>,\n\t\texpectedSource: MediaUsageSource,\n\t): Promise<boolean> {\n\t\tconst result = await db\n\t\t\t.updateTable(\"_emdash_media_usage_sources\")\n\t\t\t.set(this.attemptedSourceUpdateSet(source, row))\n\t\t\t.where(\"source_key\", \"=\", row.source_key)\n\t\t\t.where(this.sourceMatchExpression(expectedSource))\n\t\t\t.executeTakeFirst();\n\t\treturn Number(result.numUpdatedRows ?? 0) > 0;\n\t}\n\n\tprivate sourceMatchExpression(expectedSource: MediaUsageSource) {\n\t\treturn (eb: ExpressionBuilder<Database, \"_emdash_media_usage_sources\">) =>\n\t\t\teb.and([\n\t\t\t\teb(\"current_generation\", \"=\", expectedSource.currentGeneration),\n\t\t\t\teb(\"source_completeness\", \"=\", expectedSource.sourceCompleteness),\n\t\t\t\tthis.nullableStringExpression(eb, \"updated_at\", expectedSource.updatedAt),\n\t\t\t\tthis.nullableStringExpression(eb, \"source_fingerprint\", expectedSource.sourceFingerprint),\n\t\t\t\tthis.nullableStringExpression(eb, \"source_updated_at\", expectedSource.sourceUpdatedAt),\n\t\t\t\tthis.nullableNumberExpression(eb, \"source_version\", expectedSource.sourceVersion),\n\t\t\t\tthis.nullableStringExpression(eb, \"revision_id\", expectedSource.revisionId),\n\t\t\t\tthis.nullableStringExpression(eb, \"last_attempted_at\", expectedSource.lastAttemptedAt),\n\t\t\t\tthis.nullableStringExpression(eb, \"last_error_code\", expectedSource.lastErrorCode),\n\t\t\t]);\n\t}\n\n\tprivate nullableStringExpression(\n\t\teb: ExpressionBuilder<Database, \"_emdash_media_usage_sources\">,\n\t\tcolumn: MediaUsageSourceNullableStringColumn,\n\t\tvalue: string | null,\n\t) {\n\t\treturn value === null ? eb(column, \"is\", null) : eb(column, \"=\", value);\n\t}\n\n\tprivate nullableNumberExpression(\n\t\teb: ExpressionBuilder<Database, \"_emdash_media_usage_sources\">,\n\t\tcolumn: \"source_version\",\n\t\tvalue: number | null,\n\t) {\n\t\treturn value === null ? eb(column, \"is\", null) : eb(column, \"=\", value);\n\t}\n\n\tprivate async contentRowExists(tableName: string, contentId: string): Promise<boolean> {\n\t\tconst result = await sql<{ id: string }>`\n\t\t\tSELECT id\n\t\t\tFROM ${sql.ref(tableName)}\n\t\t\tWHERE id = ${contentId}\n\t\t\tLIMIT 1\n\t\t`.execute(this.db);\n\t\treturn result.rows.length > 0;\n\t}\n\n\tprivate buildSourceRow(source: MediaUsageSourceInput, generation: string, now: string) {\n\t\treturn {\n\t\t\tsource_key: source.sourceKey,\n\t\t\tsource_type: source.sourceType,\n\t\t\tcollection_slug: source.collectionSlug ?? null,\n\t\t\tcontent_id: source.contentId ?? null,\n\t\t\tsource_variant: source.sourceVariant,\n\t\t\tlocale: source.locale ?? null,\n\t\t\ttranslation_group: source.translationGroup ?? null,\n\t\t\tcontent_slug: source.contentSlug ?? null,\n\t\t\tcontent_title: source.contentTitle ?? null,\n\t\t\tcontent_status: source.contentStatus ?? null,\n\t\t\tcontent_scheduled_at: source.contentScheduledAt ?? null,\n\t\t\tcontent_deleted_at: source.contentDeletedAt ?? null,\n\t\t\trevision_id: source.revisionId ?? null,\n\t\t\tcurrent_generation: generation,\n\t\t\tschema_version: source.schemaVersion ?? 1,\n\t\t\tsource_updated_at: source.sourceUpdatedAt ?? null,\n\t\t\tsource_version: source.sourceVersion ?? null,\n\t\t\tsource_fingerprint: source.sourceFingerprint ?? null,\n\t\t\t// Complete means this source was fully refreshed for the extractor's current\n\t\t\t// schema/version coverage, not that every possible reference shape is known.\n\t\t\tsource_completeness: source.sourceCompleteness ?? \"complete\",\n\t\t\tlast_attempted_at: source.lastAttemptedAt ?? now,\n\t\t\tlast_error_code: null,\n\t\t\tindexed_at: now,\n\t\t\tupdated_at: now,\n\t\t};\n\t}\n\n\tprivate buildAttemptedSourceRow(source: MediaUsageSourceInput, now: string) {\n\t\treturn {\n\t\t\tsource_key: source.sourceKey,\n\t\t\tsource_type: source.sourceType,\n\t\t\tcollection_slug: source.collectionSlug ?? null,\n\t\t\tcontent_id: source.contentId ?? null,\n\t\t\tsource_variant: source.sourceVariant,\n\t\t\tlocale: source.locale ?? null,\n\t\t\ttranslation_group: source.translationGroup ?? null,\n\t\t\tcontent_slug: source.contentSlug ?? null,\n\t\t\tcontent_title: source.contentTitle ?? null,\n\t\t\tcontent_status: source.contentStatus ?? null,\n\t\t\tcontent_scheduled_at: source.contentScheduledAt ?? null,\n\t\t\tcontent_deleted_at: source.contentDeletedAt ?? null,\n\t\t\trevision_id: source.revisionId ?? null,\n\t\t\tcurrent_generation: ulid(),\n\t\t\tschema_version: source.schemaVersion ?? 1,\n\t\t\tsource_updated_at: source.sourceUpdatedAt ?? null,\n\t\t\tsource_version: source.sourceVersion ?? null,\n\t\t\tsource_fingerprint: source.sourceFingerprint ?? null,\n\t\t\tsource_completeness:\n\t\t\t\tsource.sourceCompleteness ?? (source.lastErrorCode ? \"failed\" : \"unknown\"),\n\t\t\tlast_attempted_at: source.lastAttemptedAt ?? now,\n\t\t\tlast_error_code: source.lastErrorCode ?? null,\n\t\t\tindexed_at: now,\n\t\t\tupdated_at: now,\n\t\t};\n\t}\n\n\tprivate attemptedSourceUpdateSet(\n\t\tsource: MediaUsageSourceInput,\n\t\trow: ReturnType<MediaUsageRepository[\"buildAttemptedSourceRow\"]>,\n\t): Updateable<MediaUsageSourceTable> {\n\t\tconst updates: Updateable<MediaUsageSourceTable> = {\n\t\t\tsource_type: row.source_type,\n\t\t\tsource_variant: row.source_variant,\n\t\t\tsource_completeness: row.source_completeness,\n\t\t\tlast_attempted_at: row.last_attempted_at,\n\t\t\tlast_error_code: row.last_error_code,\n\t\t\tupdated_at: row.updated_at,\n\t\t};\n\n\t\tif (source.collectionSlug !== undefined) updates.collection_slug = row.collection_slug;\n\t\tif (source.contentId !== undefined) updates.content_id = row.content_id;\n\t\tif (source.locale !== undefined) updates.locale = row.locale;\n\t\tif (source.translationGroup !== undefined) updates.translation_group = row.translation_group;\n\t\tif (source.contentSlug !== undefined) updates.content_slug = row.content_slug;\n\t\tif (source.contentTitle !== undefined) updates.content_title = row.content_title;\n\t\tif (source.contentStatus !== undefined) updates.content_status = row.content_status;\n\t\tif (source.contentScheduledAt !== undefined) {\n\t\t\tupdates.content_scheduled_at = row.content_scheduled_at;\n\t\t}\n\t\tif (source.contentDeletedAt !== undefined) updates.content_deleted_at = row.content_deleted_at;\n\t\tif (source.revisionId !== undefined) updates.revision_id = row.revision_id;\n\t\tif (source.schemaVersion !== undefined) updates.schema_version = row.schema_version;\n\t\tif (source.sourceUpdatedAt !== undefined) updates.source_updated_at = row.source_updated_at;\n\t\tif (source.sourceVersion !== undefined) updates.source_version = row.source_version;\n\t\tif (source.sourceFingerprint !== undefined) {\n\t\t\tupdates.source_fingerprint = row.source_fingerprint;\n\t\t}\n\n\t\treturn updates;\n\t}\n\n\tprivate sourceUpdateSet(\n\t\trow: ReturnType<MediaUsageRepository[\"buildSourceRow\"]>,\n\t): Updateable<MediaUsageSourceTable> {\n\t\treturn {\n\t\t\tsource_type: row.source_type,\n\t\t\tcollection_slug: row.collection_slug,\n\t\t\tcontent_id: row.content_id,\n\t\t\tsource_variant: row.source_variant,\n\t\t\tlocale: row.locale,\n\t\t\ttranslation_group: row.translation_group,\n\t\t\tcontent_slug: row.content_slug,\n\t\t\tcontent_title: row.content_title,\n\t\t\tcontent_status: row.content_status,\n\t\t\tcontent_scheduled_at: row.content_scheduled_at,\n\t\t\tcontent_deleted_at: row.content_deleted_at,\n\t\t\trevision_id: row.revision_id,\n\t\t\tcurrent_generation: row.current_generation,\n\t\t\tschema_version: row.schema_version,\n\t\t\tsource_updated_at: row.source_updated_at,\n\t\t\tsource_version: row.source_version,\n\t\t\tsource_fingerprint: row.source_fingerprint,\n\t\t\tsource_completeness: row.source_completeness,\n\t\t\tlast_attempted_at: row.last_attempted_at,\n\t\t\tlast_error_code: row.last_error_code,\n\t\t\tindexed_at: row.indexed_at,\n\t\t\tupdated_at: row.updated_at,\n\t\t};\n\t}\n}\n\nconst currentUsageSelect = [\n\t\"s.source_key as source_key\",\n\t\"s.source_type as source_type\",\n\t\"s.collection_slug as collection_slug\",\n\t\"s.content_id as content_id\",\n\t\"s.source_variant as source_variant\",\n\t\"s.locale as locale\",\n\t\"s.translation_group as translation_group\",\n\t\"s.content_slug as content_slug\",\n\t\"s.content_title as content_title\",\n\t\"s.content_status as content_status\",\n\t\"s.content_scheduled_at as content_scheduled_at\",\n\t\"s.content_deleted_at as content_deleted_at\",\n\t\"s.revision_id as revision_id\",\n\t\"s.current_generation as current_generation\",\n\t\"s.schema_version as schema_version\",\n\t\"s.source_updated_at as source_updated_at\",\n\t\"s.source_version as source_version\",\n\t\"s.source_fingerprint as source_fingerprint\",\n\t\"s.source_completeness as source_completeness\",\n\t\"s.last_attempted_at as last_attempted_at\",\n\t\"s.last_error_code as last_error_code\",\n\t\"s.indexed_at as indexed_at\",\n\t\"s.created_at as source_created_at\",\n\t\"s.updated_at as source_row_updated_at\",\n\t\"u.id as occurrence_id\",\n\t\"u.generation as generation\",\n\t\"u.field_slug as field_slug\",\n\t\"u.field_path as field_path\",\n\t\"u.occurrence_index as occurrence_index\",\n\t\"u.reference_type as reference_type\",\n\t\"u.media_id as media_id\",\n\t\"u.provider as provider\",\n\t\"u.provider_asset_id as provider_asset_id\",\n\t\"u.media_kind as media_kind\",\n\t\"u.mime_type as mime_type\",\n\t\"u.created_at as occurrence_created_at\",\n] as const;\n\nfunction rowToSource(row: MediaUsageSourceRow): MediaUsageSource {\n\treturn {\n\t\tsourceKey: row.source_key,\n\t\tsourceType: row.source_type,\n\t\tcollectionSlug: row.collection_slug,\n\t\tcontentId: row.content_id,\n\t\tsourceVariant: row.source_variant,\n\t\tlocale: row.locale,\n\t\ttranslationGroup: row.translation_group,\n\t\tcontentSlug: row.content_slug,\n\t\tcontentTitle: row.content_title,\n\t\tcontentStatus: row.content_status,\n\t\tcontentScheduledAt: row.content_scheduled_at,\n\t\tcontentDeletedAt: row.content_deleted_at,\n\t\trevisionId: row.revision_id,\n\t\tcurrentGeneration: row.current_generation,\n\t\tschemaVersion: Number(row.schema_version),\n\t\tsourceUpdatedAt: row.source_updated_at,\n\t\tsourceVersion: row.source_version === null ? null : Number(row.source_version),\n\t\tsourceFingerprint: row.source_fingerprint,\n\t\tsourceCompleteness: row.source_completeness,\n\t\tlastAttemptedAt: row.last_attempted_at,\n\t\tlastErrorCode: row.last_error_code,\n\t\tindexedAt: row.indexed_at,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t};\n}\n\nfunction rowToOccurrence(row: Selectable<MediaUsageTable>): MediaUsageOccurrence {\n\treturn {\n\t\tid: row.id,\n\t\tsourceKey: row.source_key,\n\t\tgeneration: row.generation,\n\t\tfieldSlug: row.field_slug,\n\t\tfieldPath: row.field_path,\n\t\toccurrenceIndex: Number(row.occurrence_index),\n\t\treferenceType: row.reference_type,\n\t\tmediaId: row.media_id,\n\t\tprovider: row.provider,\n\t\tproviderAssetId: row.provider_asset_id,\n\t\tmediaKind: row.media_kind,\n\t\tmimeType: row.mime_type,\n\t\tcreatedAt: row.created_at,\n\t};\n}\n\nfunction rowToUsageRecord(row: JoinedUsageRow): MediaUsageRecord {\n\treturn {\n\t\tsource: rowToSource({\n\t\t\tsource_key: row.source_key,\n\t\t\tsource_type: row.source_type,\n\t\t\tcollection_slug: row.collection_slug,\n\t\t\tcontent_id: row.content_id,\n\t\t\tsource_variant: row.source_variant,\n\t\t\tlocale: row.locale,\n\t\t\ttranslation_group: row.translation_group,\n\t\t\tcontent_slug: row.content_slug,\n\t\t\tcontent_title: row.content_title,\n\t\t\tcontent_status: row.content_status,\n\t\t\tcontent_scheduled_at: row.content_scheduled_at,\n\t\t\tcontent_deleted_at: row.content_deleted_at,\n\t\t\trevision_id: row.revision_id,\n\t\t\tcurrent_generation: row.current_generation,\n\t\t\tschema_version: row.schema_version,\n\t\t\tsource_updated_at: row.source_updated_at,\n\t\t\tsource_version: row.source_version,\n\t\t\tsource_fingerprint: row.source_fingerprint,\n\t\t\tsource_completeness: row.source_completeness,\n\t\t\tlast_attempted_at: row.last_attempted_at,\n\t\t\tlast_error_code: row.last_error_code,\n\t\t\tindexed_at: row.indexed_at,\n\t\t\tcreated_at: row.source_created_at,\n\t\t\tupdated_at: row.source_row_updated_at,\n\t\t}),\n\t\toccurrence: rowToOccurrence({\n\t\t\tid: row.occurrence_id,\n\t\t\tsource_key: row.source_key,\n\t\t\tgeneration: row.generation,\n\t\t\tfield_slug: row.field_slug,\n\t\t\tfield_path: row.field_path,\n\t\t\toccurrence_index: row.occurrence_index,\n\t\t\treference_type: row.reference_type,\n\t\t\tmedia_id: row.media_id,\n\t\t\tprovider: row.provider,\n\t\t\tprovider_asset_id: row.provider_asset_id,\n\t\t\tmedia_kind: row.media_kind,\n\t\t\tmime_type: row.mime_type,\n\t\t\tcreated_at: row.occurrence_created_at,\n\t\t}),\n\t};\n}\n\nfunction rowToIndexStatus(row: Selectable<MediaUsageIndexStatusTable>): MediaUsageIndexStatus {\n\treturn {\n\t\tadapterId: row.adapter_id,\n\t\tscopeType: row.scope_type,\n\t\tscopeKey: row.scope_key,\n\t\tstatus: row.status,\n\t\tschemaVersion: Number(row.schema_version),\n\t\tstartedAt: row.started_at,\n\t\tcompletedAt: row.completed_at,\n\t\tcursor: row.cursor,\n\t\tindexedSourceCount: Number(row.indexed_source_count),\n\t\tfailedSourceCount: Number(row.failed_source_count),\n\t\tlastErrorCode: row.last_error_code,\n\t\tupdatedAt: row.updated_at,\n\t};\n}\n","import type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../../database/types.js\";\nimport { validateIdentifier } from \"../../database/validate.js\";\nimport type { MediaUsageExtractionField, MediaUsageExtractionSubField } from \"./types.js\";\n\nexport type ContentMediaUsageField = MediaUsageExtractionField;\n\nexport interface ContentMediaUsageFieldDiscovery {\n\textractionFields: ContentMediaUsageField[];\n\tdisplayFieldSlugs: string[];\n}\n\nexport class MediaUsageFieldDiscoveryError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: \"INVALID_REPEATER_VALIDATION\",\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MediaUsageFieldDiscoveryError\";\n\t}\n}\n\ninterface FieldDiscoveryRow {\n\tslug: string;\n\ttype: string;\n\tvalidation: string | null;\n}\n\nconst DISPLAY_FIELD_SLUGS = [\"title\", \"name\"] as const;\nconst SUPPORTED_TOP_LEVEL_TYPES = [\"file\", \"image\", \"portableText\"] as const;\n\ntype SupportedTopLevelType = (typeof SUPPORTED_TOP_LEVEL_TYPES)[number];\n\nexport async function loadContentMediaUsageFields(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<ContentMediaUsageFieldDiscovery> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_fields\")\n\t\t.innerJoin(\"_emdash_collections\", \"_emdash_collections.id\", \"_emdash_fields.collection_id\")\n\t\t.select([\"_emdash_fields.slug\", \"_emdash_fields.type\", \"_emdash_fields.validation\"])\n\t\t.where(\"_emdash_collections.slug\", \"=\", collectionSlug)\n\t\t.execute();\n\n\tconst extractionFields: ContentMediaUsageField[] = [];\n\tconst rowBySlug = new Map<string, FieldDiscoveryRow>();\n\n\tfor (const row of rows) {\n\t\trowBySlug.set(row.slug, row);\n\t\tif (isSupportedTopLevelType(row.type)) {\n\t\t\tvalidateIdentifier(row.slug, \"media usage field slug\");\n\t\t\textractionFields.push({ slug: row.slug, type: row.type });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (row.type === \"repeater\") {\n\t\t\tvalidateIdentifier(row.slug, \"media usage field slug\");\n\t\t\tconst subFields = normalizeRepeaterImageSubFields(row.validation);\n\t\t\tif (subFields.length > 0) {\n\t\t\t\textractionFields.push({\n\t\t\t\t\tslug: row.slug,\n\t\t\t\t\ttype: \"repeater\",\n\t\t\t\t\tvalidation: { subFields },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\textractionFields.sort((a, b) => a.slug.localeCompare(b.slug));\n\n\treturn {\n\t\textractionFields,\n\t\tdisplayFieldSlugs: DISPLAY_FIELD_SLUGS.filter((slug) => {\n\t\t\tif (!rowBySlug.has(slug)) return false;\n\t\t\tvalidateIdentifier(slug, \"media usage display field slug\");\n\t\t\treturn true;\n\t\t}),\n\t};\n}\n\nfunction normalizeRepeaterImageSubFields(\n\trawValidation: string | null,\n): MediaUsageExtractionSubField[] {\n\tconst validation = parseValidation(rawValidation);\n\tif (!isRecord(validation) || !Array.isArray(validation.subFields)) return [];\n\n\tconst subFields: MediaUsageExtractionSubField[] = [];\n\tfor (const subField of validation.subFields) {\n\t\tif (!isRecord(subField) || subField.type !== \"image\") continue;\n\t\tif (typeof subField.slug !== \"string\") continue;\n\t\tvalidateIdentifier(subField.slug, \"media usage repeater sub-field slug\");\n\t\tsubFields.push({ slug: subField.slug, type: \"image\" });\n\t}\n\n\treturn subFields.toSorted((a, b) => a.slug.localeCompare(b.slug));\n}\n\nfunction parseValidation(rawValidation: string | null): unknown {\n\tif (!rawValidation) return null;\n\ttry {\n\t\treturn JSON.parse(rawValidation);\n\t} catch {\n\t\tthrow new MediaUsageFieldDiscoveryError(\n\t\t\t\"Repeater field validation must be valid JSON before media usage can be discovered\",\n\t\t\t\"INVALID_REPEATER_VALIDATION\",\n\t\t);\n\t}\n}\n\nfunction isSupportedTopLevelType(value: string): value is SupportedTopLevelType {\n\treturn (SUPPORTED_TOP_LEVEL_TYPES as readonly string[]).includes(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { normalizeMime } from \"../mime.js\";\nimport { INTERNAL_MEDIA_PREFIX } from \"../normalize.js\";\nimport type {\n\tExtractedMediaUsageOccurrence,\n\tExtractMediaUsageOccurrencesInput,\n\tMediaKind,\n\tMediaUsageExtractionSubField,\n\tMediaUsageReferenceType,\n} from \"./types.js\";\n\nconst URL_LIKE_RE = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\ninterface MediaRef {\n\tmediaId: string | null;\n\tprovider: string;\n\tproviderAssetId: string;\n\tmediaKind: MediaKind | null;\n\tmimeType: string | null;\n}\n\ninterface AddOccurrenceInput {\n\tfieldSlug: string;\n\tfieldPath: string;\n\treferenceType: MediaUsageReferenceType;\n\tvalue: unknown;\n\tfallbackKind: MediaKind | null;\n}\n\nexport function extractMediaUsageOccurrences({\n\tfields,\n\tdata,\n}: ExtractMediaUsageOccurrencesInput): ExtractedMediaUsageOccurrence[] {\n\tconst occurrences: ExtractedMediaUsageOccurrence[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const field of fields) {\n\t\tconst value = data[field.slug];\n\n\t\tif (field.type === \"image\") {\n\t\t\taddOccurrence(occurrences, seen, {\n\t\t\t\tfieldSlug: field.slug,\n\t\t\t\tfieldPath: field.slug,\n\t\t\t\treferenceType: \"image_field\",\n\t\t\t\tvalue,\n\t\t\t\tfallbackKind: \"image\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (field.type === \"file\") {\n\t\t\taddOccurrence(occurrences, seen, {\n\t\t\t\tfieldSlug: field.slug,\n\t\t\t\tfieldPath: field.slug,\n\t\t\t\treferenceType: \"file_field\",\n\t\t\t\tvalue,\n\t\t\t\tfallbackKind: null,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (field.type === \"repeater\") {\n\t\t\textractRepeaterOccurrences(occurrences, seen, field.slug, value, field.validation?.subFields);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (field.type === \"portableText\") {\n\t\t\textractPortableTextOccurrences(occurrences, seen, field.slug, value);\n\t\t}\n\t}\n\n\treturn occurrences;\n}\n\nfunction extractRepeaterOccurrences(\n\toccurrences: ExtractedMediaUsageOccurrence[],\n\tseen: Set<string>,\n\tfieldSlug: string,\n\tvalue: unknown,\n\tsubFields: readonly MediaUsageExtractionSubField[] | undefined,\n): void {\n\tif (!Array.isArray(value) || !Array.isArray(subFields)) return;\n\n\tfor (const [itemIndex, item] of value.entries()) {\n\t\tif (!isRecord(item)) continue;\n\n\t\tfor (const subField of subFields) {\n\t\t\tif (subField.type !== \"image\") continue;\n\n\t\t\taddOccurrence(occurrences, seen, {\n\t\t\t\tfieldSlug,\n\t\t\t\tfieldPath: `${fieldSlug}[${itemIndex}].${subField.slug}`,\n\t\t\t\treferenceType: \"image_field\",\n\t\t\t\tvalue: item[subField.slug],\n\t\t\t\tfallbackKind: \"image\",\n\t\t\t});\n\t\t}\n\t}\n}\n\nfunction extractPortableTextOccurrences(\n\toccurrences: ExtractedMediaUsageOccurrence[],\n\tseen: Set<string>,\n\tfieldSlug: string,\n\tvalue: unknown,\n): void {\n\tif (!Array.isArray(value)) return;\n\n\tfor (const [blockIndex, block] of value.entries()) {\n\t\tif (!isRecord(block) || block._type !== \"image\" || !isRecord(block.asset)) continue;\n\n\t\tconst provider = normalizeProvider(block.asset.provider);\n\t\tconst ref = readPortableTextAssetRef(block.asset, provider);\n\t\tif (!ref) continue;\n\n\t\taddRefOccurrence(occurrences, seen, {\n\t\t\tfieldSlug,\n\t\t\tfieldPath: `${fieldSlug}[${blockIndex}].asset.${ref.key}`,\n\t\t\treferenceType: \"portable_text_image\",\n\t\t\tref: buildMediaRef({\n\t\t\t\tid: ref.id,\n\t\t\t\tprovider,\n\t\t\t\tmimeType: normalizeMimeValue(block.asset.mimeType),\n\t\t\t\tfallbackKind: \"image\",\n\t\t\t}),\n\t\t});\n\t}\n}\n\nfunction addOccurrence(\n\toccurrences: ExtractedMediaUsageOccurrence[],\n\tseen: Set<string>,\n\tinput: AddOccurrenceInput,\n): void {\n\tconst ref = readMediaRef(input.value, input.fallbackKind);\n\tif (!ref) return;\n\n\taddRefOccurrence(occurrences, seen, {\n\t\tfieldSlug: input.fieldSlug,\n\t\tfieldPath: input.fieldPath,\n\t\treferenceType: input.referenceType,\n\t\tref,\n\t});\n}\n\nfunction addRefOccurrence(\n\toccurrences: ExtractedMediaUsageOccurrence[],\n\tseen: Set<string>,\n\tinput: {\n\t\tfieldSlug: string;\n\t\tfieldPath: string;\n\t\treferenceType: MediaUsageReferenceType;\n\t\tref: MediaRef | null;\n\t},\n): void {\n\tif (!input.ref) return;\n\n\tconst occurrence: ExtractedMediaUsageOccurrence = {\n\t\tfieldSlug: input.fieldSlug,\n\t\tfieldPath: input.fieldPath,\n\t\toccurrenceIndex: 0,\n\t\treferenceType: input.referenceType,\n\t\tmediaId: input.ref.mediaId,\n\t\tprovider: input.ref.provider,\n\t\tproviderAssetId: input.ref.providerAssetId,\n\t\tmediaKind: input.ref.mediaKind,\n\t\tmimeType: input.ref.mimeType,\n\t};\n\n\tconst key = [\n\t\toccurrence.fieldSlug,\n\t\toccurrence.fieldPath,\n\t\toccurrence.occurrenceIndex,\n\t\toccurrence.referenceType,\n\t\toccurrence.provider,\n\t\toccurrence.providerAssetId,\n\t\toccurrence.mediaId ?? \"\",\n\t].join(\"\\0\");\n\n\tif (seen.has(key)) return;\n\tseen.add(key);\n\toccurrences.push(occurrence);\n}\n\nfunction readMediaRef(value: unknown, fallbackKind: MediaKind | null): MediaRef | null {\n\tif (typeof value === \"string\") {\n\t\tconst id = normalizeLocalMediaId(value);\n\t\treturn id ? buildMediaRef({ id, provider: \"local\", mimeType: null, fallbackKind }) : null;\n\t}\n\n\tif (!isRecord(value)) return null;\n\n\tconst provider = normalizeProvider(value.provider);\n\tconst id = provider === \"local\" ? normalizeLocalMediaId(value.id) : normalizeStableId(value.id);\n\tif (!id) return null;\n\n\treturn buildMediaRef({\n\t\tid,\n\t\tprovider,\n\t\tmimeType: normalizeMimeValue(value.mimeType),\n\t\tfallbackKind,\n\t});\n}\n\nfunction buildMediaRef(input: {\n\tid: string;\n\tprovider: string;\n\tmimeType: string | null;\n\tfallbackKind: MediaKind | null;\n}): MediaRef | null {\n\tconst provider = normalizeProvider(input.provider);\n\tif (provider === \"external\") return null;\n\n\treturn {\n\t\tmediaId: provider === \"local\" ? input.id : null,\n\t\tprovider,\n\t\tproviderAssetId: input.id,\n\t\tmediaKind: mediaKindFromMime(input.mimeType) ?? input.fallbackKind,\n\t\tmimeType: input.mimeType,\n\t};\n}\n\nfunction readPortableTextAssetRef(\n\tasset: Record<string, unknown>,\n\tprovider: string,\n): { key: \"_ref\" | \"id\"; id: string } | null {\n\tconst normalizeId = provider === \"local\" ? normalizeLocalMediaId : normalizeStableId;\n\tconst ref = normalizeId(asset._ref);\n\tif (ref) return { key: \"_ref\", id: ref };\n\n\tconst id = normalizeId(asset.id);\n\tif (id) return { key: \"id\", id };\n\n\treturn null;\n}\n\nfunction normalizeProvider(value: unknown): string {\n\tconst provider = readString(value)?.trim();\n\treturn provider || \"local\";\n}\n\nfunction normalizeLocalMediaId(value: unknown): string | null {\n\tconst id = normalizeStableId(value);\n\tif (!id) return null;\n\treturn id.includes(\"/\") ? null : id;\n}\n\nfunction normalizeStableId(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst trimmed = value.trim();\n\tif (!trimmed) return null;\n\tif (URL_LIKE_RE.test(trimmed)) return null;\n\tif (trimmed.startsWith(INTERNAL_MEDIA_PREFIX)) return null;\n\treturn trimmed;\n}\n\nfunction normalizeMimeValue(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = normalizeMime(value);\n\treturn normalized.includes(\"/\") ? normalized : null;\n}\n\nfunction mediaKindFromMime(mimeType: string | null): MediaKind | null {\n\tif (!mimeType) return null;\n\tif (mimeType.startsWith(\"image/\")) return \"image\";\n\tif (mimeType.startsWith(\"video/\")) return \"video\";\n\tif (mimeType.startsWith(\"audio/\")) return \"audio\";\n\tif (mimeType.startsWith(\"font/\") || mimeType.startsWith(\"application/font-\")) return \"font\";\n\tif (mimeType.startsWith(\"text/\")) return \"text\";\n\tif (isDocumentMime(mimeType)) return \"document\";\n\tif (isArchiveMime(mimeType)) return \"archive\";\n\treturn \"other\";\n}\n\nfunction isDocumentMime(mimeType: string): boolean {\n\treturn (\n\t\tmimeType === \"application/pdf\" ||\n\t\tmimeType === \"application/msword\" ||\n\t\tmimeType === \"application/rtf\" ||\n\t\tmimeType === \"application/vnd.ms-excel\" ||\n\t\tmimeType === \"application/vnd.ms-powerpoint\" ||\n\t\tmimeType.startsWith(\"application/vnd.openxmlformats-officedocument.\")\n\t);\n}\n\nfunction isArchiveMime(mimeType: string): boolean {\n\treturn (\n\t\tmimeType === \"application/zip\" ||\n\t\tmimeType === \"application/gzip\" ||\n\t\tmimeType === \"application/x-tar\" ||\n\t\tmimeType === \"application/x-7z-compressed\" ||\n\t\tmimeType === \"application/x-rar-compressed\" ||\n\t\tmimeType === \"application/vnd.rar\"\n\t);\n}\n\nfunction readString(value: unknown): string | null {\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","export const MEDIA_USAGE_CONTENT_SOURCE_VARIANTS = [\"columns\", \"draft_overlay\"] as const;\n\nexport type MediaUsageContentSourceVariant = (typeof MEDIA_USAGE_CONTENT_SOURCE_VARIANTS)[number];\n\nexport interface ContentMediaUsageSourceKeyInput {\n\tcollectionSlug: string;\n\tcontentId: string;\n\tsourceVariant: MediaUsageContentSourceVariant;\n}\n\nexport function isMediaUsageContentSourceVariant(\n\tvalue: unknown,\n): value is MediaUsageContentSourceVariant {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\t(MEDIA_USAGE_CONTENT_SOURCE_VARIANTS as readonly string[]).includes(value)\n\t);\n}\n\nexport function buildContentMediaUsageSourceKey(input: ContentMediaUsageSourceKeyInput): string {\n\treturn `content:${input.collectionSlug}:${input.contentId}:${input.sourceVariant}`;\n}\n","import { sql, type Kysely } from \"kysely\";\n\nimport type {\n\tMediaUsageOccurrenceInput,\n\tMediaUsageSourceInput,\n} from \"../../database/repositories/media-usage.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { validateIdentifier } from \"../../database/validate.js\";\nimport { hashString } from \"../../utils/hash.js\";\nimport {\n\tloadContentMediaUsageFields,\n\ttype ContentMediaUsageField,\n\ttype ContentMediaUsageFieldDiscovery,\n} from \"./content-fields.js\";\nimport { extractMediaUsageOccurrences } from \"./extractor.js\";\nimport {\n\tbuildContentMediaUsageSourceKey,\n\ttype MediaUsageContentSourceVariant,\n} from \"./source-key.js\";\n\nexport const CONTENT_SOURCE_SCHEMA_VERSION = 1;\n\nconst CONTENT_SYSTEM_COLUMNS = [\n\t\"id\",\n\t\"slug\",\n\t\"status\",\n\t\"created_at\",\n\t\"updated_at\",\n\t\"published_at\",\n\t\"scheduled_at\",\n\t\"deleted_at\",\n\t\"version\",\n\t\"live_revision_id\",\n\t\"draft_revision_id\",\n\t\"locale\",\n\t\"translation_group\",\n] as const;\n\nexport type LoadContentMediaUsageSnapshotsResult =\n\t| { success: true; snapshots: ContentMediaUsageSnapshot[] }\n\t| {\n\t\t\tsuccess: false;\n\t\t\terror:\n\t\t\t\t| \"CONTENT_NOT_FOUND\"\n\t\t\t\t| \"DRAFT_REVISION_NOT_FOUND\"\n\t\t\t\t| \"DRAFT_REVISION_MISMATCH\"\n\t\t\t\t| \"DRAFT_REVISION_INVALID\";\n\t\t\tsource?: MediaUsageSourceInput;\n\t\t\tsnapshots?: ContentMediaUsageSnapshot[];\n\t };\n\nexport interface ContentMediaUsageSnapshot {\n\tsource: MediaUsageSourceInput;\n\toccurrences: MediaUsageOccurrenceInput[];\n\tfields: readonly ContentMediaUsageField[];\n}\n\nexport async function loadContentMediaUsageSnapshots(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n\tfieldDiscovery?: ContentMediaUsageFieldDiscovery,\n): Promise<LoadContentMediaUsageSnapshotsResult> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\tconst discovery = fieldDiscovery ?? (await loadContentMediaUsageFields(db, collectionSlug));\n\tconst row = await loadContentRow(db, collectionSlug, contentId, [\n\t\t...discovery.extractionFields.map((field) => field.slug),\n\t\t...discovery.displayFieldSlugs,\n\t]);\n\n\tif (!row) return { success: false, error: \"CONTENT_NOT_FOUND\" };\n\n\tconst columnsData = projectData(\n\t\trow,\n\t\tdiscovery.extractionFields.map((field) => field.slug),\n\t);\n\tconst displayData = projectRawData(row, discovery.displayFieldSlugs);\n\tconst occurrences = extractMediaUsageOccurrences({\n\t\tfields: discovery.extractionFields,\n\t\tdata: columnsData,\n\t});\n\tconst columnsRevisionId = readNullableString(row.live_revision_id);\n\tconst columnsFingerprint = await buildSourceFingerprint({\n\t\tcollectionSlug,\n\t\tsourceVariant: \"columns\",\n\t\trevisionId: columnsRevisionId,\n\t\tfields: discovery.extractionFields,\n\t\tdata: columnsData,\n\t});\n\tconst snapshots: ContentMediaUsageSnapshot[] = [\n\t\t{\n\t\t\tsource: buildContentSource({\n\t\t\t\tcollectionSlug,\n\t\t\t\trow,\n\t\t\t\tdisplayData,\n\t\t\t\tsourceVariant: \"columns\",\n\t\t\t\trevisionId: columnsRevisionId,\n\t\t\t\tsourceFingerprint: columnsFingerprint,\n\t\t\t}),\n\t\t\toccurrences,\n\t\t\tfields: discovery.extractionFields,\n\t\t},\n\t];\n\n\tconst draftRevisionId = readNullableString(row.draft_revision_id);\n\tif (draftRevisionId) {\n\t\tconst attemptedDraftSource = buildContentSource({\n\t\t\tcollectionSlug,\n\t\t\trow,\n\t\t\tdisplayData,\n\t\t\tsourceVariant: \"draft_overlay\",\n\t\t\trevisionId: draftRevisionId,\n\t\t});\n\t\tconst revisionResult = await loadRevisionRow(db, draftRevisionId);\n\t\tif (!revisionResult) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"DRAFT_REVISION_NOT_FOUND\",\n\t\t\t\tsource: attemptedDraftSource,\n\t\t\t\tsnapshots,\n\t\t\t};\n\t\t}\n\t\tif (!revisionResult.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"DRAFT_REVISION_INVALID\",\n\t\t\t\tsource: attemptedDraftSource,\n\t\t\t\tsnapshots,\n\t\t\t};\n\t\t}\n\t\tconst revision = revisionResult.revision;\n\t\tif (revision.collection !== collectionSlug || revision.entryId !== row.id) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: \"DRAFT_REVISION_MISMATCH\",\n\t\t\t\tsource: attemptedDraftSource,\n\t\t\t\tsnapshots,\n\t\t\t};\n\t\t}\n\n\t\tconst revisionData = stripRevisionMetadata(revision.data);\n\t\tconst draftOverlayData = { ...columnsData, ...revisionData };\n\t\tconst draftDisplayData = {\n\t\t\t...displayData,\n\t\t\t...projectPresentData(revisionData, discovery.displayFieldSlugs),\n\t\t};\n\t\tconst draftContentSlug =\n\t\t\treadNullableString(revision.data._slug) ?? readNullableString(row.slug);\n\t\tconst draftFingerprint = await buildSourceFingerprint({\n\t\t\tcollectionSlug,\n\t\t\tsourceVariant: \"draft_overlay\",\n\t\t\trevisionId: draftRevisionId,\n\t\t\tfields: discovery.extractionFields,\n\t\t\tdata: draftOverlayData,\n\t\t});\n\t\tsnapshots.push({\n\t\t\tsource: buildContentSource({\n\t\t\t\tcollectionSlug,\n\t\t\t\trow,\n\t\t\t\tdisplayData: draftDisplayData,\n\t\t\t\tsourceVariant: \"draft_overlay\",\n\t\t\t\trevisionId: draftRevisionId,\n\t\t\t\tcontentSlug: draftContentSlug,\n\t\t\t\tsourceFingerprint: draftFingerprint,\n\t\t\t}),\n\t\t\toccurrences: extractMediaUsageOccurrences({\n\t\t\t\tfields: discovery.extractionFields,\n\t\t\t\tdata: draftOverlayData,\n\t\t\t}),\n\t\t\tfields: discovery.extractionFields,\n\t\t});\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\tsnapshots,\n\t};\n}\n\ninterface RevisionSnapshotRow {\n\tid: string;\n\tcollection: string;\n\tentryId: string;\n\tdata: Record<string, unknown>;\n}\n\nasync function loadContentRow(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n\tfieldSlugs: readonly string[],\n): Promise<Record<string, unknown> | null> {\n\tconst tableName = getContentTableName(collectionSlug);\n\tconst columns = uniqueColumns([...CONTENT_SYSTEM_COLUMNS, ...fieldSlugs]);\n\tconst columnRefs = columns.map((column) => sql.ref(column));\n\tconst result = await sql<Record<string, unknown>>`\n\t\tSELECT ${sql.join(columnRefs, sql`, `)}\n\t\tFROM ${sql.ref(tableName)}\n\t\tWHERE id = ${contentId}\n\t\tLIMIT 1\n\t`.execute(db);\n\n\treturn result.rows[0] ?? null;\n}\n\nasync function loadRevisionRow(\n\tdb: Kysely<Database>,\n\trevisionId: string,\n): Promise<{ success: true; revision: RevisionSnapshotRow } | { success: false } | null> {\n\tconst row = await db\n\t\t.selectFrom(\"revisions\")\n\t\t.select([\"id\", \"collection\", \"entry_id\", \"data\"])\n\t\t.where(\"id\", \"=\", revisionId)\n\t\t.executeTakeFirst();\n\tif (!row) return null;\n\tconst data = parseRevisionData(row.data);\n\tif (!data) return { success: false };\n\treturn {\n\t\tsuccess: true,\n\t\trevision: {\n\t\t\tid: row.id,\n\t\t\tcollection: row.collection,\n\t\t\tentryId: row.entry_id,\n\t\t\tdata,\n\t\t},\n\t};\n}\n\nfunction buildContentSource(input: {\n\tcollectionSlug: string;\n\trow: Record<string, unknown>;\n\tdisplayData: Record<string, unknown>;\n\tsourceVariant: MediaUsageContentSourceVariant;\n\trevisionId: string | null;\n\tcontentSlug?: string | null;\n\tsourceFingerprint?: string | null;\n}): MediaUsageSourceInput {\n\tconst { collectionSlug, row, displayData, sourceVariant, revisionId } = input;\n\tconst contentId = readString(row.id) ?? \"\";\n\tconst contentSlug = input.contentSlug ?? readNullableString(row.slug);\n\tconst source: MediaUsageSourceInput = {\n\t\tsourceKey: buildContentMediaUsageSourceKey({\n\t\t\tcollectionSlug,\n\t\t\tcontentId,\n\t\t\tsourceVariant,\n\t\t}),\n\t\tsourceType: \"content\",\n\t\tcollectionSlug,\n\t\tcontentId,\n\t\tsourceVariant,\n\t\tlocale: readNullableString(row.locale),\n\t\ttranslationGroup: readNullableString(row.translation_group),\n\t\tcontentSlug,\n\t\tcontentTitle: deriveContentTitle(displayData, contentSlug, contentId),\n\t\tcontentStatus: readNullableString(row.status),\n\t\tcontentScheduledAt: readNullableString(row.scheduled_at),\n\t\tcontentDeletedAt: readNullableString(row.deleted_at),\n\t\trevisionId,\n\t\tschemaVersion: CONTENT_SOURCE_SCHEMA_VERSION,\n\t\tsourceUpdatedAt: readNullableString(row.updated_at),\n\t\tsourceVersion: readNumber(row.version),\n\t};\n\tif (input.sourceFingerprint !== undefined) source.sourceFingerprint = input.sourceFingerprint;\n\treturn source;\n}\n\nasync function buildSourceFingerprint(input: {\n\tcollectionSlug: string;\n\tsourceVariant: MediaUsageContentSourceVariant;\n\trevisionId: string | null;\n\tfields: readonly ContentMediaUsageField[];\n\tdata: Record<string, unknown>;\n}): Promise<string> {\n\treturn hashString(\n\t\tcanonicalJson({\n\t\t\tschemaVersion: CONTENT_SOURCE_SCHEMA_VERSION,\n\t\t\tcollectionSlug: input.collectionSlug,\n\t\t\tsourceVariant: input.sourceVariant,\n\t\t\tfields: normalizeFingerprintFields(input.fields),\n\t\t\tvalues: projectFingerprintData(input.data, input.fields),\n\t\t\trevisionId: input.sourceVariant === \"draft_overlay\" ? input.revisionId : null,\n\t\t}),\n\t);\n}\n\nfunction normalizeFingerprintFields(\n\tfields: readonly ContentMediaUsageField[],\n): Record<string, unknown>[] {\n\treturn fields\n\t\t.map((field) => {\n\t\t\tif (field.type !== \"repeater\") return { slug: field.slug, type: field.type };\n\t\t\treturn {\n\t\t\t\tslug: field.slug,\n\t\t\t\ttype: field.type,\n\t\t\t\tsubFields: (field.validation?.subFields ?? [])\n\t\t\t\t\t.map((subField) => ({ slug: subField.slug, type: subField.type }))\n\t\t\t\t\t.toSorted((a, b) => a.slug.localeCompare(b.slug)),\n\t\t\t};\n\t\t})\n\t\t.toSorted((a, b) => String(a.slug).localeCompare(String(b.slug)));\n}\n\nfunction projectFingerprintData(\n\tdata: Record<string, unknown>,\n\tfields: readonly ContentMediaUsageField[],\n): Record<string, unknown> {\n\tconst projected: Record<string, unknown> = {};\n\tfor (const field of fields) {\n\t\tprojected[field.slug] = Object.hasOwn(data, field.slug) ? data[field.slug] : null;\n\t}\n\treturn projected;\n}\n\nfunction canonicalJson(value: unknown): string {\n\treturn JSON.stringify(canonicalize(value));\n}\n\nfunction canonicalize(value: unknown): unknown {\n\tif (value === undefined) return null;\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (Array.isArray(value)) return value.map((item) => canonicalize(item));\n\tif (!isRecord(value)) return value;\n\n\tconst canonical: Record<string, unknown> = {};\n\tfor (const key of Object.keys(value).toSorted()) {\n\t\tcanonical[key] = canonicalize(value[key]);\n\t}\n\treturn canonical;\n}\n\nfunction projectData(\n\trow: Record<string, unknown>,\n\tfieldSlugs: readonly string[],\n): Record<string, unknown> {\n\tconst data: Record<string, unknown> = {};\n\tfor (const fieldSlug of fieldSlugs) {\n\t\tdata[fieldSlug] = deserializeValue(row[fieldSlug] ?? null);\n\t}\n\treturn data;\n}\n\nfunction projectRawData(\n\trow: Record<string, unknown>,\n\tfieldSlugs: readonly string[],\n): Record<string, unknown> {\n\tconst data: Record<string, unknown> = {};\n\tfor (const fieldSlug of fieldSlugs) {\n\t\tdata[fieldSlug] = row[fieldSlug] ?? null;\n\t}\n\treturn data;\n}\n\nfunction projectPresentData(\n\trow: Record<string, unknown>,\n\tfieldSlugs: readonly string[],\n): Record<string, unknown> {\n\tconst data: Record<string, unknown> = {};\n\tfor (const fieldSlug of fieldSlugs) {\n\t\tif (Object.hasOwn(row, fieldSlug)) data[fieldSlug] = row[fieldSlug];\n\t}\n\treturn data;\n}\n\nfunction uniqueColumns(columns: readonly string[]): string[] {\n\tconst unique = [...new Set(columns)];\n\tfor (const column of unique) validateIdentifier(column, \"content media usage column\");\n\treturn unique;\n}\n\nfunction getContentTableName(collectionSlug: string): string {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\treturn `ec_${collectionSlug}`;\n}\n\nfunction deserializeValue(value: unknown): unknown {\n\tif (typeof value === \"string\" && (value.startsWith(\"{\") || value.startsWith(\"[\"))) {\n\t\ttry {\n\t\t\treturn JSON.parse(value);\n\t\t} catch {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction parseRevisionData(value: unknown): Record<string, unknown> | null {\n\tif (typeof value === \"string\") {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(value);\n\t\t\treturn isRecord(parsed) ? parsed : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn isRecord(value) ? value : null;\n}\n\nfunction stripRevisionMetadata(data: Record<string, unknown>): Record<string, unknown> {\n\tconst stripped: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (!key.startsWith(\"_\")) stripped[key] = value;\n\t}\n\treturn stripped;\n}\n\nfunction deriveContentTitle(\n\tdisplayData: Record<string, unknown>,\n\tcontentSlug: string | null,\n\tcontentId: string,\n): string | null {\n\tfor (const fieldSlug of [\"title\", \"name\"] as const) {\n\t\tconst value = displayData[fieldSlug];\n\t\tif (typeof value === \"string\" && value.trim()) return value;\n\t}\n\treturn contentSlug ?? contentId;\n}\n\nfunction readString(value: unknown): string | null {\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction readNullableString(value: unknown): string | null {\n\treturn value === null || value === undefined ? null : readString(value);\n}\n\nfunction readNumber(value: unknown): number | null {\n\tif (typeof value === \"number\" && Number.isFinite(value)) return value;\n\tif (typeof value === \"bigint\") return Number(value);\n\tif (typeof value === \"string\" && value) {\n\t\tconst parsed = Number(value);\n\t\treturn Number.isFinite(parsed) ? parsed : null;\n\t}\n\treturn null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { sql, type Kysely } from \"kysely\";\n\nimport { MediaUsageRepository } from \"../../database/repositories/media-usage.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { validateIdentifier } from \"../../database/validate.js\";\nimport { isI18nEnabled } from \"../../i18n/config.js\";\nimport { loadContentMediaUsageFields } from \"./content-fields.js\";\nimport {\n\tCONTENT_SOURCE_SCHEMA_VERSION,\n\tloadContentMediaUsageSnapshots,\n} from \"./content-snapshots.js\";\nimport {\n\tbuildContentMediaUsageSourceKey,\n\tMEDIA_USAGE_CONTENT_SOURCE_VARIANTS,\n} from \"./source-key.js\";\n\nexport const CONTENT_MEDIA_USAGE_ADAPTER_ID = \"content-media\";\nexport const CONTENT_MEDIA_USAGE_COLLECTION_SCOPE = \"collection\";\n\nconst CONTENT_USAGE_LOCKS_KEY = Symbol.for(\"emdash.mediaUsage.contentLocks\");\nconst CONTENT_USAGE_COLLECTION_LOCKS_KEY = Symbol.for(\"emdash.mediaUsage.collectionLocks\");\nconst CONTENT_USAGE_REFRESH_MAX_ATTEMPTS = 2;\n\n// These maps only de-dupe usage work inside the current isolate/process. Cross-worker\n// correctness comes from expected-generation guards on repository writes.\n\nexport type ContentMediaUsageRefreshErrorCode =\n\t| \"CONTENT_NOT_FOUND\"\n\t| \"DRAFT_REVISION_NOT_FOUND\"\n\t| \"DRAFT_REVISION_MISMATCH\"\n\t| \"DRAFT_REVISION_INVALID\"\n\t| \"CONTENT_USAGE_REFRESH_ERROR\"\n\t| \"CONTENT_USAGE_DELETE_ERROR\"\n\t| \"CONTENT_USAGE_GENERATION_CONFLICT\"\n\t| \"CONTENT_USAGE_STALE\";\n\nexport interface ContentMediaUsageRefreshResult {\n\tsuccess: boolean;\n\trefreshedSourceCount: number;\n\tdeletedSourceCount: number;\n\tfailedSourceCount: number;\n\terrorCode?: ContentMediaUsageRefreshErrorCode;\n}\n\nconst ZERO_RESULT: ContentMediaUsageRefreshResult = {\n\tsuccess: true,\n\trefreshedSourceCount: 0,\n\tdeletedSourceCount: 0,\n\tfailedSourceCount: 0,\n};\n\nexport async function refreshContentMediaUsage(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\treturn withContentUsageCollectionLock(collectionSlug, () =>\n\t\twithContentUsageLock(collectionSlug, contentId, () =>\n\t\t\trefreshContentMediaUsageUnlocked(db, collectionSlug, contentId),\n\t\t),\n\t);\n}\n\nasync function refreshContentMediaUsageUnlocked(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\ttry {\n\t\tlet conflictResult: ContentMediaUsageRefreshResult | null = null;\n\t\tfor (let attempt = 0; attempt < CONTENT_USAGE_REFRESH_MAX_ATTEMPTS; attempt++) {\n\t\t\tconst result = await refreshContentMediaUsageAttempt(db, collectionSlug, contentId);\n\t\t\tif (result.errorCode !== \"CONTENT_USAGE_GENERATION_CONFLICT\") return result;\n\t\t\tconflictResult = result;\n\t\t}\n\n\t\treturn markGenerationConflict(db, collectionSlug, {\n\t\t\trefreshedSourceCount: conflictResult?.refreshedSourceCount ?? 0,\n\t\t\tdeletedSourceCount: conflictResult?.deletedSourceCount ?? 0,\n\t\t});\n\t} catch (error) {\n\t\tconsole.error(`[media-usage] Failed to refresh ${collectionSlug}/${contentId}:`, error);\n\t\tawait markContentMediaUsageCollectionStaleSafely(\n\t\t\tdb,\n\t\t\tcollectionSlug,\n\t\t\t\"CONTENT_USAGE_REFRESH_ERROR\",\n\t\t);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\trefreshedSourceCount: 0,\n\t\t\tdeletedSourceCount: 0,\n\t\t\tfailedSourceCount: 0,\n\t\t\terrorCode: \"CONTENT_USAGE_REFRESH_ERROR\",\n\t\t};\n\t}\n}\n\nasync function refreshContentMediaUsageAttempt(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\tconst repo = new MediaUsageRepository(db);\n\tconst observedGenerations = await loadObservedContentSourceGenerations(\n\t\tdb,\n\t\tcollectionSlug,\n\t\tcontentId,\n\t);\n\tconst snapshotsResult = await loadContentMediaUsageSnapshots(db, collectionSlug, contentId);\n\tif (!snapshotsResult.success) {\n\t\treturn markSnapshotFailure(db, collectionSlug, snapshotsResult);\n\t}\n\n\tif (!(await contentCollectionExists(db, collectionSlug))) {\n\t\tconst deletedSourceCount = await repo.deleteContentSources(collectionSlug, contentId);\n\t\treturn { ...ZERO_RESULT, deletedSourceCount };\n\t}\n\n\tlet refreshedSourceCount = 0;\n\tfor (const snapshot of snapshotsResult.snapshots) {\n\t\tconst result = await repo.replaceSourceIfCurrent(\n\t\t\tsnapshot.source,\n\t\t\tsnapshot.occurrences,\n\t\t\tobservedGenerations.get(snapshot.source.sourceKey) ?? null,\n\t\t);\n\t\tif (!result.replaced) {\n\t\t\treturn generationConflictResult({\n\t\t\t\trefreshedSourceCount,\n\t\t\t\tdeletedSourceCount: 0,\n\t\t\t});\n\t\t}\n\t\trefreshedSourceCount++;\n\t}\n\tif (!(await contentCollectionExists(db, collectionSlug))) {\n\t\tconst deletedSourceCount = await repo.deleteContentSources(collectionSlug, contentId);\n\t\treturn { ...ZERO_RESULT, deletedSourceCount };\n\t}\n\n\tconst expectedSourceKeys = new Set(\n\t\tsnapshotsResult.snapshots.map((snapshot) => snapshot.source.sourceKey),\n\t);\n\tconst absentSourceKeys = MEDIA_USAGE_CONTENT_SOURCE_VARIANTS.map((sourceVariant) =>\n\t\tbuildContentMediaUsageSourceKey({ collectionSlug, contentId, sourceVariant }),\n\t).filter((sourceKey) => !expectedSourceKeys.has(sourceKey));\n\tlet deletedSourceCount = 0;\n\tfor (const sourceKey of absentSourceKeys) {\n\t\tconst expectedGeneration = observedGenerations.get(sourceKey) ?? null;\n\t\tif (expectedGeneration === null) continue;\n\n\t\tconst result = await repo.deleteSourceIfCurrent(sourceKey, expectedGeneration);\n\t\tif (result.deleted) {\n\t\t\tdeletedSourceCount++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (result.source) {\n\t\t\treturn generationConflictResult({\n\t\t\t\trefreshedSourceCount,\n\t\t\t\tdeletedSourceCount,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn {\n\t\tsuccess: true,\n\t\trefreshedSourceCount,\n\t\tdeletedSourceCount,\n\t\tfailedSourceCount: 0,\n\t};\n}\n\nasync function loadObservedContentSourceGenerations(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<Map<string, string | null>> {\n\tconst generations = new Map<string, string | null>();\n\tconst sourceKeys = MEDIA_USAGE_CONTENT_SOURCE_VARIANTS.map((sourceVariant) =>\n\t\tbuildContentMediaUsageSourceKey({\n\t\t\tcollectionSlug,\n\t\t\tcontentId,\n\t\t\tsourceVariant,\n\t\t}),\n\t);\n\tfor (const sourceKey of sourceKeys) {\n\t\tgenerations.set(sourceKey, null);\n\t}\n\n\tconst rows = await db\n\t\t.selectFrom(\"_emdash_media_usage_sources\")\n\t\t.select([\"source_key\", \"current_generation\"])\n\t\t.where(\"source_key\", \"in\", sourceKeys)\n\t\t.execute();\n\tfor (const row of rows) {\n\t\tgenerations.set(row.source_key, row.current_generation);\n\t}\n\n\treturn generations;\n}\n\nasync function markGenerationConflict(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcounts: Pick<ContentMediaUsageRefreshResult, \"refreshedSourceCount\" | \"deletedSourceCount\">,\n): Promise<ContentMediaUsageRefreshResult> {\n\tawait markContentMediaUsageCollectionStaleSafely(\n\t\tdb,\n\t\tcollectionSlug,\n\t\t\"CONTENT_USAGE_GENERATION_CONFLICT\",\n\t);\n\treturn {\n\t\tsuccess: false,\n\t\trefreshedSourceCount: counts.refreshedSourceCount,\n\t\tdeletedSourceCount: counts.deletedSourceCount,\n\t\tfailedSourceCount: 0,\n\t\terrorCode: \"CONTENT_USAGE_GENERATION_CONFLICT\",\n\t};\n}\n\nfunction generationConflictResult(\n\tcounts: Pick<ContentMediaUsageRefreshResult, \"refreshedSourceCount\" | \"deletedSourceCount\">,\n): ContentMediaUsageRefreshResult {\n\treturn {\n\t\tsuccess: false,\n\t\trefreshedSourceCount: counts.refreshedSourceCount,\n\t\tdeletedSourceCount: counts.deletedSourceCount,\n\t\tfailedSourceCount: 0,\n\t\terrorCode: \"CONTENT_USAGE_GENERATION_CONFLICT\",\n\t};\n}\n\nasync function contentCollectionExists(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<boolean> {\n\tconst row = await db\n\t\t.selectFrom(\"_emdash_collections\")\n\t\t.select(\"id\")\n\t\t.where(\"slug\", \"=\", collectionSlug)\n\t\t.executeTakeFirst();\n\treturn row !== undefined;\n}\n\nexport async function deleteContentMediaUsage(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\treturn withContentUsageCollectionLock(collectionSlug, () =>\n\t\twithContentUsageLock(collectionSlug, contentId, () =>\n\t\t\tdeleteContentMediaUsageUnlocked(db, collectionSlug, contentId),\n\t\t),\n\t);\n}\n\nasync function deleteContentMediaUsageUnlocked(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\ttry {\n\t\tconst deletedSourceCount = await new MediaUsageRepository(db).deleteContentSources(\n\t\t\tcollectionSlug,\n\t\t\tcontentId,\n\t\t);\n\t\treturn { ...ZERO_RESULT, deletedSourceCount };\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`[media-usage] Failed to delete usage for ${collectionSlug}/${contentId}:`,\n\t\t\terror,\n\t\t);\n\t\tawait markContentMediaUsageCollectionStaleSafely(\n\t\t\tdb,\n\t\t\tcollectionSlug,\n\t\t\t\"CONTENT_USAGE_DELETE_ERROR\",\n\t\t);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\trefreshedSourceCount: 0,\n\t\t\tdeletedSourceCount: 0,\n\t\t\tfailedSourceCount: 0,\n\t\t\terrorCode: \"CONTENT_USAGE_DELETE_ERROR\",\n\t\t};\n\t}\n}\n\nexport async function deleteContentMediaUsageCollection(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\treturn withContentUsageCollectionLock(collectionSlug, () =>\n\t\tdeleteContentMediaUsageCollectionUnlocked(db, collectionSlug),\n\t);\n}\n\nasync function deleteContentMediaUsageCollectionUnlocked(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n): Promise<ContentMediaUsageRefreshResult> {\n\ttry {\n\t\tconst repo = new MediaUsageRepository(db);\n\t\tconst deletedSourceCount = await repo.deleteCollectionSources(collectionSlug);\n\t\tawait repo.deleteIndexStatus({\n\t\t\tadapterId: CONTENT_MEDIA_USAGE_ADAPTER_ID,\n\t\t\tscopeType: CONTENT_MEDIA_USAGE_COLLECTION_SCOPE,\n\t\t\tscopeKey: collectionSlug,\n\t\t});\n\t\treturn { ...ZERO_RESULT, deletedSourceCount };\n\t} catch (error) {\n\t\tconsole.error(`[media-usage] Failed to delete usage for collection ${collectionSlug}:`, error);\n\t\ttry {\n\t\t\tawait new MediaUsageRepository(db).deleteIndexStatus({\n\t\t\t\tadapterId: CONTENT_MEDIA_USAGE_ADAPTER_ID,\n\t\t\t\tscopeType: CONTENT_MEDIA_USAGE_COLLECTION_SCOPE,\n\t\t\t\tscopeKey: collectionSlug,\n\t\t\t});\n\t\t} catch (statusError) {\n\t\t\tconsole.error(\n\t\t\t\t`[media-usage] Failed to clear usage status for deleted collection ${collectionSlug}:`,\n\t\t\t\tstatusError,\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\trefreshedSourceCount: 0,\n\t\t\tdeletedSourceCount: 0,\n\t\t\tfailedSourceCount: 0,\n\t\t\terrorCode: \"CONTENT_USAGE_DELETE_ERROR\",\n\t\t};\n\t}\n}\n\nexport async function refreshContentMediaUsageAfterWrite(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tcontentId: string,\n): Promise<void> {\n\tconst result = await refreshContentMediaUsage(db, collectionSlug, contentId);\n\tif (!result.success) {\n\t\tconsole.error(\n\t\t\t`[media-usage] Usage refresh for ${collectionSlug}/${contentId} finished with ${result.errorCode}`,\n\t\t);\n\t}\n}\n\nexport async function markContentMediaUsageCollectionStale(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tlastErrorCode: string,\n): Promise<void> {\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\tconst repo = new MediaUsageRepository(db);\n\tconst identity = {\n\t\tadapterId: CONTENT_MEDIA_USAGE_ADAPTER_ID,\n\t\tscopeType: CONTENT_MEDIA_USAGE_COLLECTION_SCOPE,\n\t\tscopeKey: collectionSlug,\n\t};\n\tconst existing = await repo.findIndexStatus(identity);\n\tawait repo.upsertIndexStatus({\n\t\t...identity,\n\t\tstatus: \"stale\",\n\t\tschemaVersion: existing?.schemaVersion ?? CONTENT_SOURCE_SCHEMA_VERSION,\n\t\tstartedAt: existing?.startedAt ?? null,\n\t\tcompletedAt: existing?.completedAt ?? null,\n\t\tcursor: existing?.cursor ?? null,\n\t\tindexedSourceCount: existing?.indexedSourceCount ?? 0,\n\t\tfailedSourceCount: existing?.failedSourceCount ?? 0,\n\t\tlastErrorCode,\n\t});\n}\n\nexport async function findNonTranslatableSiblingContentIds(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tupdatedContentId: string,\n\ttranslationGroup: string | null | undefined,\n\tupdatedData: Record<string, unknown> | undefined,\n): Promise<string[]> {\n\tif (!isI18nEnabled() || !updatedData || !translationGroup) return [];\n\n\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\tconst collection = await db\n\t\t.selectFrom(\"_emdash_collections\")\n\t\t.select(\"id\")\n\t\t.where(\"slug\", \"=\", collectionSlug)\n\t\t.executeTakeFirst();\n\tif (!collection) return [];\n\n\tconst fields = await db\n\t\t.selectFrom(\"_emdash_fields\")\n\t\t.select(\"slug\")\n\t\t.where(\"collection_id\", \"=\", collection.id)\n\t\t.where(\"translatable\", \"=\", 0)\n\t\t.execute();\n\n\tconst touchedNonTranslatableSlugs = fields\n\t\t.filter((field) => field.slug in updatedData)\n\t\t.map((field) => field.slug);\n\tif (touchedNonTranslatableSlugs.length === 0) return [];\n\n\tconst usageFields = await loadContentMediaUsageFields(db, collectionSlug);\n\tconst usageRelevantSlugs = new Set([\n\t\t...usageFields.extractionFields.map((field) => field.slug),\n\t\t...usageFields.displayFieldSlugs,\n\t]);\n\tif (!touchedNonTranslatableSlugs.some((slug) => usageRelevantSlugs.has(slug))) return [];\n\n\tconst tableName = `ec_${collectionSlug}`;\n\tconst rows = await sql<{ id: string }>`\n\t\tSELECT id\n\t\tFROM ${sql.ref(tableName)}\n\t\tWHERE translation_group = ${translationGroup}\n\t\tAND id != ${updatedContentId}\n\t\tORDER BY id ASC\n\t`.execute(db);\n\n\treturn rows.rows.map((row) => row.id);\n}\n\nasync function markSnapshotFailure(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tresult: Exclude<Awaited<ReturnType<typeof loadContentMediaUsageSnapshots>>, { success: true }>,\n): Promise<ContentMediaUsageRefreshResult> {\n\tconst repo = new MediaUsageRepository(db);\n\tif (result.source) {\n\t\tawait repo.markSourceAttempted({\n\t\t\t...result.source,\n\t\t\tsourceCompleteness: \"failed\",\n\t\t\tlastErrorCode: result.error,\n\t\t});\n\t}\n\tawait markContentMediaUsageCollectionStale(db, collectionSlug, result.error);\n\treturn {\n\t\tsuccess: false,\n\t\trefreshedSourceCount: 0,\n\t\tdeletedSourceCount: 0,\n\t\tfailedSourceCount: result.source ? 1 : 0,\n\t\terrorCode: result.error,\n\t};\n}\n\nexport async function markContentMediaUsageCollectionStaleSafely(\n\tdb: Kysely<Database>,\n\tcollectionSlug: string,\n\tlastErrorCode: ContentMediaUsageRefreshErrorCode,\n): Promise<boolean> {\n\ttry {\n\t\tawait markContentMediaUsageCollectionStale(db, collectionSlug, lastErrorCode);\n\t\treturn true;\n\t} catch (error) {\n\t\tconsole.error(`[media-usage] Failed to mark ${collectionSlug} stale:`, error);\n\t\treturn false;\n\t}\n}\n\nasync function withContentUsageLock<T>(\n\tcollectionSlug: string,\n\tcontentId: string,\n\tfn: () => Promise<T>,\n): Promise<T> {\n\tconst locks = getContentUsageLocks();\n\tconst lockKey = `${collectionSlug}\\0${contentId}`;\n\tconst previous = locks.get(lockKey) ?? Promise.resolve();\n\tlet releaseCurrent!: () => void;\n\tconst current = new Promise<void>((resolve) => {\n\t\treleaseCurrent = resolve;\n\t});\n\tconst next = previous.catch(() => {}).then(() => current);\n\tlocks.set(lockKey, next);\n\n\ttry {\n\t\tawait previous.catch(() => {});\n\t\treturn await fn();\n\t} finally {\n\t\treleaseCurrent();\n\t\tif (locks.get(lockKey) === next) locks.delete(lockKey);\n\t}\n}\n\nexport async function withContentUsageCollectionLock<T>(\n\tcollectionSlug: string,\n\tfn: () => Promise<T>,\n): Promise<T> {\n\t// Coarse by design: row refreshes and collection source deletes must not interleave.\n\tconst locks = getContentUsageCollectionLocks();\n\tconst previous = locks.get(collectionSlug) ?? Promise.resolve();\n\tlet releaseCurrent!: () => void;\n\tconst current = new Promise<void>((resolve) => {\n\t\treleaseCurrent = resolve;\n\t});\n\tconst next = previous.catch(() => {}).then(() => current);\n\tlocks.set(collectionSlug, next);\n\n\ttry {\n\t\tawait previous.catch(() => {});\n\t\treturn await fn();\n\t} finally {\n\t\treleaseCurrent();\n\t\tif (locks.get(collectionSlug) === next) locks.delete(collectionSlug);\n\t}\n}\n\nfunction getContentUsageLocks(): Map<string, Promise<void>> {\n\tconst global = globalThis as typeof globalThis & Record<symbol, unknown>;\n\tconst existing = global[CONTENT_USAGE_LOCKS_KEY];\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot stores only this map\n\tif (existing instanceof Map) return existing as Map<string, Promise<void>>;\n\tconst locks = new Map<string, Promise<void>>();\n\tglobal[CONTENT_USAGE_LOCKS_KEY] = locks;\n\treturn locks;\n}\n\nfunction getContentUsageCollectionLocks(): Map<string, Promise<void>> {\n\tconst global = globalThis as typeof globalThis & Record<symbol, unknown>;\n\tconst existing = global[CONTENT_USAGE_COLLECTION_LOCKS_KEY];\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot stores only this map\n\tif (existing instanceof Map) return existing as Map<string, Promise<void>>;\n\tconst locks = new Map<string, Promise<void>>();\n\tglobal[CONTENT_USAGE_COLLECTION_LOCKS_KEY] = locks;\n\treturn locks;\n}\n"],"mappings":"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"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { n as validateJsonFieldName } from "./validate-VPnKoIzW.mjs";
|
|
2
2
|
import { s as jsonExtractExpr } from "./dialect-helpers-DRI5pyY3.mjs";
|
|
3
|
-
import { t as ContentRepository } from "./content-
|
|
4
|
-
import { a as encodeCursor, i as decodeCursor } from "./types-
|
|
5
|
-
import { t as MediaRepository } from "./media-
|
|
6
|
-
import { t as UserRepository } from "./user-
|
|
3
|
+
import { t as ContentRepository } from "./content-DhgEth4k.mjs";
|
|
4
|
+
import { a as encodeCursor, i as decodeCursor } from "./types-CuW0zWDA.mjs";
|
|
5
|
+
import { t as MediaRepository } from "./media-BrXIaMFN.mjs";
|
|
6
|
+
import { t as UserRepository } from "./user-BjAOvU3Z.mjs";
|
|
7
7
|
import { t as OptionsRepository } from "./options-DTTML-Tx.mjs";
|
|
8
8
|
import { t as withTransaction } from "./transaction-qfqpPVpu.mjs";
|
|
9
9
|
import { t as enrichImageMetadata } from "./enrich-BQ0mxJRs.mjs";
|
|
10
|
-
import { t as SeoRepository } from "./seo-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { t as
|
|
10
|
+
import { t as SeoRepository } from "./seo-DXu2UQnC.mjs";
|
|
11
|
+
import { a as markContentMediaUsageCollectionStaleSafely } from "./content-refresh-Br4gMzh8.mjs";
|
|
12
|
+
import { o as invalidateSiteSettingsCache } from "./settings-zhmdKyJQ.mjs";
|
|
13
|
+
import { i as stripCredentialHeaders, n as resolveAndValidateExternalUrl, t as SsrfError } from "./ssrf-1g7usGBg.mjs";
|
|
14
|
+
import { t as CronAccessImpl } from "./cron-v4FTEFR_.mjs";
|
|
14
15
|
import { sql } from "kysely";
|
|
15
16
|
import { ulid } from "ulidx";
|
|
16
17
|
|
|
@@ -495,57 +496,78 @@ function createContentAccessWithWrite(db) {
|
|
|
495
496
|
...createContentAccess(db),
|
|
496
497
|
async create(collection, data) {
|
|
497
498
|
const { fields, seo } = splitSeoFromInput(data);
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
499
|
+
let contentMutated = false;
|
|
500
|
+
try {
|
|
501
|
+
const created = await withTransaction(db, async (trx) => {
|
|
502
|
+
const trxContentRepo = new ContentRepository(trx);
|
|
503
|
+
const trxSeoRepo = new SeoRepository(trx);
|
|
504
|
+
const hasSeo = await assertSeoEnabled(trxSeoRepo, collection, seo);
|
|
505
|
+
const item = await trxContentRepo.create({
|
|
506
|
+
type: collection,
|
|
507
|
+
data: fields
|
|
508
|
+
});
|
|
509
|
+
contentMutated = true;
|
|
510
|
+
const result = {
|
|
511
|
+
id: item.id,
|
|
512
|
+
type: item.type,
|
|
513
|
+
slug: item.slug,
|
|
514
|
+
status: item.status,
|
|
515
|
+
data: item.data,
|
|
516
|
+
createdAt: item.createdAt,
|
|
517
|
+
updatedAt: item.updatedAt,
|
|
518
|
+
locale: item.locale,
|
|
519
|
+
publishedAt: item.publishedAt
|
|
520
|
+
};
|
|
521
|
+
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
522
|
+
return result;
|
|
505
523
|
});
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
createdAt: item.createdAt,
|
|
513
|
-
updatedAt: item.updatedAt,
|
|
514
|
-
locale: item.locale,
|
|
515
|
-
publishedAt: item.publishedAt
|
|
516
|
-
};
|
|
517
|
-
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
518
|
-
return result;
|
|
519
|
-
});
|
|
524
|
+
await markContentMediaUsageCollectionStaleSafely(db, collection, "CONTENT_USAGE_STALE");
|
|
525
|
+
return created;
|
|
526
|
+
} catch (error) {
|
|
527
|
+
if (contentMutated) await markContentMediaUsageCollectionStaleSafely(db, collection, "CONTENT_USAGE_STALE");
|
|
528
|
+
throw error;
|
|
529
|
+
}
|
|
520
530
|
},
|
|
521
531
|
async update(collection, id, data) {
|
|
522
532
|
const { fields, seo } = splitSeoFromInput(data);
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
533
|
+
const hasFieldUpdates = Object.keys(fields).length > 0;
|
|
534
|
+
let contentMutated = false;
|
|
535
|
+
try {
|
|
536
|
+
const updated = await withTransaction(db, async (trx) => {
|
|
537
|
+
const trxContentRepo = new ContentRepository(trx);
|
|
538
|
+
const trxSeoRepo = new SeoRepository(trx);
|
|
539
|
+
const hasSeo = await assertSeoEnabled(trxSeoRepo, collection, seo);
|
|
540
|
+
const item = hasFieldUpdates ? await trxContentRepo.update(collection, id, { data: fields }) : await (async () => {
|
|
541
|
+
const existing = await trxContentRepo.findById(collection, id);
|
|
542
|
+
if (!existing) throw new Error("Content not found");
|
|
543
|
+
return existing;
|
|
544
|
+
})();
|
|
545
|
+
if (hasFieldUpdates) contentMutated = true;
|
|
546
|
+
const result = {
|
|
547
|
+
id: item.id,
|
|
548
|
+
type: item.type,
|
|
549
|
+
slug: item.slug,
|
|
550
|
+
status: item.status,
|
|
551
|
+
data: item.data,
|
|
552
|
+
createdAt: item.createdAt,
|
|
553
|
+
updatedAt: item.updatedAt,
|
|
554
|
+
locale: item.locale,
|
|
555
|
+
publishedAt: item.publishedAt
|
|
556
|
+
};
|
|
557
|
+
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
558
|
+
return result;
|
|
559
|
+
});
|
|
560
|
+
if (hasFieldUpdates) await markContentMediaUsageCollectionStaleSafely(db, collection, "CONTENT_USAGE_STALE");
|
|
561
|
+
return updated;
|
|
562
|
+
} catch (error) {
|
|
563
|
+
if (contentMutated) await markContentMediaUsageCollectionStaleSafely(db, collection, "CONTENT_USAGE_STALE");
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
546
566
|
},
|
|
547
567
|
async delete(collection, id) {
|
|
548
|
-
|
|
568
|
+
const deleted = await new ContentRepository(db).delete(collection, id);
|
|
569
|
+
if (deleted) await markContentMediaUsageCollectionStaleSafely(db, collection, "CONTENT_USAGE_STALE");
|
|
570
|
+
return deleted;
|
|
549
571
|
}
|
|
550
572
|
};
|
|
551
573
|
}
|
|
@@ -920,4 +942,4 @@ var PluginContextFactory = class {
|
|
|
920
942
|
|
|
921
943
|
//#endregion
|
|
922
944
|
export { PluginStorageRepository as a, createUnrestrictedHttpAccess as i, createHttpAccess as n, createStorageAccess as r, PluginContextFactory as t };
|
|
923
|
-
//# sourceMappingURL=context-
|
|
945
|
+
//# sourceMappingURL=context-BRIpHARC.mjs.map
|