emdash 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-BzIHV3sw.d.mts → adapters-hUy8vOB-.d.mts} +1 -1
- package/dist/{adapters-BzIHV3sw.d.mts.map → adapters-hUy8vOB-.d.mts.map} +1 -1
- package/dist/after-B1IIdH3Y.mjs +29 -0
- package/dist/after-B1IIdH3Y.mjs.map +1 -0
- package/dist/{allowed-origins-B1u7Qnvg.mjs → allowed-origins-DjlhyfNN.mjs} +2 -2
- package/dist/{allowed-origins-B1u7Qnvg.mjs.map → allowed-origins-DjlhyfNN.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +20 -18
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +4 -3
- package/dist/{api-DStv36ik.mjs → api-BDuM4bEy.mjs} +31 -25
- package/dist/api-BDuM4bEy.mjs.map +1 -0
- package/dist/{api-tokens-DPfhPu5V.mjs → api-tokens-ViYKeIp9.mjs} +13 -3
- package/dist/api-tokens-ViYKeIp9.mjs.map +1 -0
- package/dist/{apply-Dr7snAMT.mjs → apply-wDqQoxX4.mjs} +18 -18
- package/dist/{apply-Dr7snAMT.mjs.map → apply-wDqQoxX4.mjs.map} +1 -1
- package/dist/astro/image-endpoint.d.mts +8 -0
- package/dist/astro/image-endpoint.d.mts.map +1 -0
- package/dist/astro/image-endpoint.mjs +55 -0
- package/dist/astro/image-endpoint.mjs.map +1 -0
- package/dist/astro/index.d.mts +36 -11
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +160 -35
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +12 -10
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +14 -5
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +5 -4
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +157 -80
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -6
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -6
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -14
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -14
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +17 -14
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +15 -12
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -6
- package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -9
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -6
- package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/index.mjs +12 -9
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +40 -37
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -37
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +39 -36
- 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 +39 -36
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -36
- 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 +40 -37
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +40 -37
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +39 -36
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -36
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +39 -36
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -7
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
- package/dist/astro/routes/api/admin/users/index.mjs +7 -6
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/complete.mjs +12 -11
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +9 -8
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -10
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -10
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
- package/dist/astro/routes/api/auth/me.mjs +8 -7
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -6
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +12 -11
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +11 -10
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +16 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts +9 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.d.mts.map +1 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +179 -0
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -11
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +17 -14
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -7
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +10 -8
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +12 -11
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -14
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +10 -9
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -9
- 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 +12 -11
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +18 -15
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.mjs +213 -45
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -7
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +8 -7
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +10 -9
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +13 -12
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -8
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +11 -8
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -8
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -8
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +11 -8
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +11 -8
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
- package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/openapi.json.mjs +5 -4
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
- package/dist/astro/routes/api/redirects/404s/index.mjs +11 -10
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +11 -10
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +12 -11
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +12 -11
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -36
- 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 +39 -36
- 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 +39 -36
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -36
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +39 -36
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +7 -7
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -36
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +39 -36
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +11 -10
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +10 -9
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +11 -10
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +7 -7
- package/dist/astro/routes/api/search/suggest.mjs +10 -9
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +10 -9
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +10 -9
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +16 -13
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +13 -12
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +12 -11
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -26
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +29 -26
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.d.mts.map +1 -1
- package/dist/astro/routes/api/snapshot.mjs +10 -8
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -13
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +8 -7
- package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -7
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -10
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -10
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
- package/dist/astro/routes/api/widget-areas/index.mjs +11 -10
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +10 -8
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -11
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +11 -9
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +16 -12
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-DsMSVSaY.mjs → authorize-C0EYoUeV.mjs} +2 -2
- package/dist/{authorize-DsMSVSaY.mjs.map → authorize-C0EYoUeV.mjs.map} +1 -1
- package/dist/{base64-CqR-7kqF.mjs → base64-CmWvODNW.mjs} +1 -1
- package/dist/{base64-CqR-7kqF.mjs.map → base64-CmWvODNW.mjs.map} +1 -1
- package/dist/{byline-DUx48sJp.mjs → byline-CC0WS4Gu.mjs} +40 -18
- package/dist/byline-CC0WS4Gu.mjs.map +1 -0
- package/dist/{byline-fields-8TMtkBnH.mjs → byline-fields-53i9Et0x.mjs} +3 -3
- package/dist/{byline-fields-8TMtkBnH.mjs.map → byline-fields-53i9Et0x.mjs.map} +1 -1
- package/dist/{byline-fields--WxSNS79.mjs → byline-fields-DNp0HNKc.mjs} +2 -2
- package/dist/{byline-fields--WxSNS79.mjs.map → byline-fields-DNp0HNKc.mjs.map} +1 -1
- package/dist/{byline-fields-DbibsvTl.d.mts → byline-fields-jy07PZJM.d.mts} +9 -4
- package/dist/byline-fields-jy07PZJM.d.mts.map +1 -0
- package/dist/{byline-registry-CWP7I71B.mjs → byline-registry-BOjqDOim.mjs} +3 -3
- package/dist/{byline-registry-CWP7I71B.mjs.map → byline-registry-BOjqDOim.mjs.map} +1 -1
- package/dist/{bylines-s8c2DXbH.mjs → bylines-CCO1CYnH.mjs} +8 -8
- package/dist/{bylines-s8c2DXbH.mjs.map → bylines-CCO1CYnH.mjs.map} +1 -1
- package/dist/{bylines-BdxWCnPL.mjs → bylines-DGekMGGm.mjs} +10 -4
- package/dist/{bylines-BdxWCnPL.mjs.map → bylines-DGekMGGm.mjs.map} +1 -1
- package/dist/{cache-B_HzASVT.mjs → cache-pXTpun6s.mjs} +3 -3
- package/dist/{cache-B_HzASVT.mjs.map → cache-pXTpun6s.mjs.map} +1 -1
- package/dist/{challenge-store-DXX3rfdI.mjs → challenge-store-C6E_kWTs.mjs} +1 -1
- package/dist/{challenge-store-DXX3rfdI.mjs.map → challenge-store-C6E_kWTs.mjs.map} +1 -1
- package/dist/{chunks-BerYVuve.mjs → chunks-SyjZaYwV.mjs} +2 -2
- package/dist/{chunks-BerYVuve.mjs.map → chunks-SyjZaYwV.mjs.map} +1 -1
- package/dist/cli/index.mjs +29 -27
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +2 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-sqQxNpN3.mjs → comment-80UyJJUR.mjs} +11 -3
- package/dist/comment-80UyJJUR.mjs.map +1 -0
- package/dist/comment-reaction-B6AdcpXw.mjs +85 -0
- package/dist/comment-reaction-B6AdcpXw.mjs.map +1 -0
- package/dist/{comments-Vkivawyl.mjs → comments-CtPkT2tp.mjs} +3 -3
- package/dist/{comments-Vkivawyl.mjs.map → comments-CtPkT2tp.mjs.map} +1 -1
- package/dist/{components-CK0cuUoH.mjs → components-D6ZnrzbB.mjs} +1 -1
- package/dist/{components-CK0cuUoH.mjs.map → components-D6ZnrzbB.mjs.map} +1 -1
- package/dist/{content-BIlVx-RX.mjs → content-2PTDNnoh.mjs} +22 -7
- package/dist/content-2PTDNnoh.mjs.map +1 -0
- package/dist/{context-Y7BRkWes.mjs → context-f1__jpzF.mjs} +11 -11
- package/dist/{context-Y7BRkWes.mjs.map → context-f1__jpzF.mjs.map} +1 -1
- package/dist/{cron-BJ2ClIlj.mjs → cron-CQPxBjYs.mjs} +1 -1
- package/dist/{cron-BJ2ClIlj.mjs.map → cron-CQPxBjYs.mjs.map} +1 -1
- package/dist/{dashboard-2JgAMWxK.mjs → dashboard-BOESNcwE.mjs} +4 -4
- package/dist/{dashboard-2JgAMWxK.mjs.map → dashboard-BOESNcwE.mjs.map} +1 -1
- package/dist/database/instrumentation.d.mts +19 -0
- package/dist/database/instrumentation.d.mts.map +1 -1
- package/dist/database/instrumentation.mjs +8 -1
- package/dist/database/instrumentation.mjs.map +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CtzxKBxe.mjs → db-errors-CrC5w3Jz.mjs} +1 -1
- package/dist/{db-errors-CtzxKBxe.mjs.map → db-errors-CrC5w3Jz.mjs.map} +1 -1
- package/dist/{default-IlBaTFxM.mjs → default-CpBEPn6a.mjs} +1 -1
- package/dist/{default-IlBaTFxM.mjs.map → default-CpBEPn6a.mjs.map} +1 -1
- package/dist/{device-flow-R23SIbQ2.mjs → device-flow-Bn-qiDrw.mjs} +5 -5
- package/dist/{device-flow-R23SIbQ2.mjs.map → device-flow-Bn-qiDrw.mjs.map} +1 -1
- package/dist/{email-console-DHT2Fbpj.mjs → email-console-B9VS6eN4.mjs} +1 -1
- package/dist/{email-console-DHT2Fbpj.mjs.map → email-console-B9VS6eN4.mjs.map} +1 -1
- package/dist/{error-RwM4dD35.mjs → error-BQ1pxs0L.mjs} +2 -2
- package/dist/{error-RwM4dD35.mjs.map → error-BQ1pxs0L.mjs.map} +1 -1
- package/dist/{escape-Ds07EEyu.mjs → escape-BtbJWyaW.mjs} +1 -1
- package/dist/{escape-Ds07EEyu.mjs.map → escape-BtbJWyaW.mjs.map} +1 -1
- package/dist/{fts-manager-1RgHmopc.mjs → fts-manager-DtiWqwNJ.mjs} +2 -2
- package/dist/{fts-manager-1RgHmopc.mjs.map → fts-manager-DtiWqwNJ.mjs.map} +1 -1
- package/dist/{hash-9w3pd3-m.mjs → hash-BowcuPwv.mjs} +1 -1
- package/dist/{hash-9w3pd3-m.mjs.map → hash-BowcuPwv.mjs.map} +1 -1
- package/dist/{import-Dh8bWmyq.mjs → import-DqSGOlmR.mjs} +4 -4
- package/dist/{import-Dh8bWmyq.mjs.map → import-DqSGOlmR.mjs.map} +1 -1
- package/dist/{index-B1keaX5Y.d.mts → index-C2dLNT6S.d.mts} +169 -14
- package/dist/index-C2dLNT6S.d.mts.map +1 -0
- package/dist/{index-DR56od45.d.mts → index-ZDEwR7qW.d.mts} +3 -3
- package/dist/{index-DR56od45.d.mts.map → index-ZDEwR7qW.d.mts.map} +1 -1
- package/dist/index.d.mts +18 -17
- package/dist/index.mjs +63 -59
- package/dist/init-lock-6b309ZrF.mjs +56 -0
- package/dist/init-lock-6b309ZrF.mjs.map +1 -0
- package/dist/{load-BBetCvLC.mjs → load-Dtoo7KcJ.mjs} +2 -2
- package/dist/{load-BBetCvLC.mjs.map → load-Dtoo7KcJ.mjs.map} +1 -1
- package/dist/{loader-ZN1ll-d-.mjs → loader-C8Z48Uof.mjs} +4 -4
- package/dist/{loader-ZN1ll-d-.mjs.map → loader-C8Z48Uof.mjs.map} +1 -1
- package/dist/{manifest-schema-BtwbL_vj.mjs → manifest-schema-DDSbwkAL.mjs} +1 -1
- package/dist/{manifest-schema-BtwbL_vj.mjs.map → manifest-schema-DDSbwkAL.mjs.map} +1 -1
- package/dist/media/image-endpoint.d.mts +74 -0
- package/dist/media/image-endpoint.d.mts.map +1 -0
- package/dist/media/image-endpoint.mjs +162 -0
- package/dist/media/image-endpoint.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +11 -11
- package/dist/media/local-runtime.mjs +9 -7
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-JOf3pNkw.mjs → media-Bw0sA6rb.mjs} +2 -2
- package/dist/{media-JOf3pNkw.mjs.map → media-Bw0sA6rb.mjs.map} +1 -1
- package/dist/{media-allowlist-Dknq-OFY.mjs → media-allowlist-DunzrKFM.mjs} +2 -2
- package/dist/{media-allowlist-Dknq-OFY.mjs.map → media-allowlist-DunzrKFM.mjs.map} +1 -1
- package/dist/{media-url-VClf8glU.mjs → media-url-S22B6aPr.mjs} +1 -1
- package/dist/{media-url-VClf8glU.mjs.map → media-url-S22B6aPr.mjs.map} +1 -1
- package/dist/{menus-DX4_E01q.mjs → menus-CYs0WZoL.mjs} +20 -6
- package/dist/menus-CYs0WZoL.mjs.map +1 -0
- package/dist/{menus-DrQLusqj.mjs → menus-DOs1MQJg.mjs} +120 -20
- package/dist/menus-DOs1MQJg.mjs.map +1 -0
- package/dist/{mime-CCEzze7W.mjs → mime-DYpsOAny.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-DYpsOAny.mjs.map} +1 -1
- package/dist/{mode-CO2vQHfq.mjs → mode-CFh8Dw8G.mjs} +1 -1
- package/dist/{mode-CO2vQHfq.mjs.map → mode-CFh8Dw8G.mjs.map} +1 -1
- package/dist/{normalize-CK5o04zr.mjs → normalize-Uam4_Vkr.mjs} +1 -1
- package/dist/{normalize-CK5o04zr.mjs.map → normalize-Uam4_Vkr.mjs.map} +1 -1
- package/dist/{oauth-authorization-Bw4NdF_S.mjs → oauth-authorization-BN-t83Uy.mjs} +5 -5
- package/dist/{oauth-authorization-Bw4NdF_S.mjs.map → oauth-authorization-BN-t83Uy.mjs.map} +1 -1
- package/dist/{oauth-clients-BGGFp57s.mjs → oauth-clients-R6I_V0qz.mjs} +1 -1
- package/dist/{oauth-clients-BGGFp57s.mjs.map → oauth-clients-R6I_V0qz.mjs.map} +1 -1
- package/dist/{oauth-state-store-97x0xtN2.mjs → oauth-state-store-Csoc6kkR.mjs} +1 -1
- package/dist/{oauth-state-store-97x0xtN2.mjs.map → oauth-state-store-Csoc6kkR.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-B_vnZHKO.mjs → oauth-user-lookup-d7VYjTpx.mjs} +1 -1
- package/dist/{oauth-user-lookup-B_vnZHKO.mjs.map → oauth-user-lookup-d7VYjTpx.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +15 -0
- package/dist/object-cache/memory.d.mts.map +1 -0
- package/dist/object-cache/memory.mjs +56 -0
- package/dist/object-cache/memory.mjs.map +1 -0
- package/dist/object-cache-SEb2IM4Z.mjs +373 -0
- package/dist/object-cache-SEb2IM4Z.mjs.map +1 -0
- package/dist/{options-DyYIYpPd.d.mts → options-DFFpvNJU.d.mts} +3 -3
- package/dist/{options-DyYIYpPd.d.mts.map → options-DFFpvNJU.d.mts.map} +1 -1
- package/dist/{options-BPCVnesz.mjs → options-DTTML-Tx.mjs} +1 -1
- package/dist/{options-BPCVnesz.mjs.map → options-DTTML-Tx.mjs.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-CrGndy1A.mjs → parse-qrHlnzTy.mjs} +2 -2
- package/dist/{parse-CrGndy1A.mjs.map → parse-qrHlnzTy.mjs.map} +1 -1
- package/dist/{passkey-config-C3QgnQnU.mjs → passkey-config-BJTbcnI5.mjs} +1 -1
- package/dist/{passkey-config-C3QgnQnU.mjs.map → passkey-config-BJTbcnI5.mjs.map} +1 -1
- package/dist/{patterns-p-RBdTbM.mjs → patterns-BKmjvM7K.mjs} +1 -1
- package/dist/{patterns-p-RBdTbM.mjs.map → patterns-BKmjvM7K.mjs.map} +1 -1
- package/dist/{placeholder-BZxr8W1j.mjs → placeholder-CIDCpyEY.mjs} +1 -1
- package/dist/{placeholder-BZxr8W1j.mjs.map → placeholder-CIDCpyEY.mjs.map} +1 -1
- package/dist/{placeholder-CVBv5z8k.d.mts → placeholder-CirPauNG.d.mts} +1 -1
- package/dist/{placeholder-CVBv5z8k.d.mts.map → placeholder-CirPauNG.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.mjs +4 -2
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{transport-CmpLD7W3.mjs → portable-text-BIFhrU6T.mjs} +2 -135
- package/dist/portable-text-BIFhrU6T.mjs.map +1 -0
- package/dist/{preview-BfuRkVKW.mjs → preview-IDye9SPQ.mjs} +2 -2
- package/dist/{preview-BfuRkVKW.mjs.map → preview-IDye9SPQ.mjs.map} +1 -1
- package/dist/{public-url-BFVC2OTJ.mjs → public-url-8lFyQ8ZF.mjs} +1 -1
- package/dist/{public-url-BFVC2OTJ.mjs.map → public-url-8lFyQ8ZF.mjs.map} +1 -1
- package/dist/{query-CbUcI4Xk.mjs → query-B1RVFUNM.mjs} +159 -31
- package/dist/query-B1RVFUNM.mjs.map +1 -0
- package/dist/{rate-limit-C7hjdkS5.mjs → rate-limit-DfNAqIWW.mjs} +2 -2
- package/dist/{rate-limit-C7hjdkS5.mjs.map → rate-limit-DfNAqIWW.mjs.map} +1 -1
- package/dist/{redirect-B_q19j4v.mjs → redirect-B4wuX2A5.mjs} +1 -1
- package/dist/{redirect-B_q19j4v.mjs.map → redirect-B4wuX2A5.mjs.map} +1 -1
- package/dist/{redirect-CRWIt8Zj.mjs → redirect-Bifv_yHv.mjs} +3 -3
- package/dist/{redirect-CRWIt8Zj.mjs.map → redirect-Bifv_yHv.mjs.map} +1 -1
- package/dist/{redirects-DxVoR7PI.mjs → redirects-CT_vb3NV.mjs} +24 -18
- package/dist/redirects-CT_vb3NV.mjs.map +1 -0
- package/dist/{redirects-CCbCqCCd.mjs → redirects-DUvXgzCX.mjs} +14 -10
- package/dist/redirects-DUvXgzCX.mjs.map +1 -0
- package/dist/{registry-brYh-rAT.mjs → registry-CjK96fHD.mjs} +6 -6
- package/dist/{registry-brYh-rAT.mjs.map → registry-CjK96fHD.mjs.map} +1 -1
- package/dist/{request-cache-D32LpnmI.mjs → request-cache-KCNHp_RJ.mjs} +1 -1
- package/dist/{request-cache-D32LpnmI.mjs.map → request-cache-KCNHp_RJ.mjs.map} +1 -1
- package/dist/{request-meta-7ByVLxB-.mjs → request-meta-ei3ATilC.mjs} +2 -2
- package/dist/{request-meta-7ByVLxB-.mjs.map → request-meta-ei3ATilC.mjs.map} +1 -1
- package/dist/{resolve-BqYMVG0D.mjs → resolve-CpbBglV0.mjs} +1 -1
- package/dist/{resolve-BqYMVG0D.mjs.map → resolve-CpbBglV0.mjs.map} +1 -1
- package/dist/{runner--4wMWwKM.mjs → runner-DYYnW530.mjs} +201 -170
- package/dist/runner-DYYnW530.mjs.map +1 -0
- package/dist/{runner-DTdhuI9i.d.mts → runner-jdXtFEd3.d.mts} +2 -2
- package/dist/{runner-DTdhuI9i.d.mts.map → runner-jdXtFEd3.d.mts.map} +1 -1
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +3 -3
- package/dist/{schema-C1E70ug_.mjs → schema-5z2Jfnbm.mjs} +13 -8
- package/dist/schema-5z2Jfnbm.mjs.map +1 -0
- package/dist/{search-B3SGZw91.mjs → search-D9FkoM-k.mjs} +4 -4
- package/dist/{search-B3SGZw91.mjs.map → search-D9FkoM-k.mjs.map} +1 -1
- package/dist/{secrets-ChPTmy9x.mjs → secrets-BUE5UQys.mjs} +23 -13
- package/dist/secrets-BUE5UQys.mjs.map +1 -0
- package/dist/{sections-D_lVzwRZ.mjs → sections-DWYZo6HK.mjs} +3 -3
- package/dist/{sections-D_lVzwRZ.mjs.map → sections-DWYZo6HK.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +22 -20
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/{seo-B5e6y9Wk.mjs → seo-Cu47j3mJ.mjs} +5 -2
- package/dist/seo-Cu47j3mJ.mjs.map +1 -0
- package/dist/{seo-D_LPkOtu.mjs → seo-DRnqnstF.mjs} +1 -1
- package/dist/{seo-D_LPkOtu.mjs.map → seo-DRnqnstF.mjs.map} +1 -1
- package/dist/{service-ChDcsTBs.mjs → service-DTmtqCnw.mjs} +3 -3
- package/dist/{service-ChDcsTBs.mjs.map → service-DTmtqCnw.mjs.map} +1 -1
- package/dist/session-user-DmtPMNa1.mjs +51 -0
- package/dist/session-user-DmtPMNa1.mjs.map +1 -0
- package/dist/{settings-Cv47v9u8.mjs → settings-DUrVDN0c.mjs} +3 -3
- package/dist/{settings-Cv47v9u8.mjs.map → settings-DUrVDN0c.mjs.map} +1 -1
- package/dist/settings-yaxu9mU-.mjs +245 -0
- package/dist/settings-yaxu9mU-.mjs.map +1 -0
- package/dist/{setup-complete-yvPE4OsP.mjs → setup-complete-BWFHzgvZ.mjs} +2 -2
- package/dist/{setup-complete-yvPE4OsP.mjs.map → setup-complete-BWFHzgvZ.mjs.map} +1 -1
- package/dist/{setup-nonce-C9aFzb94.mjs → setup-nonce-DFWG-J5c.mjs} +1 -1
- package/dist/{setup-nonce-C9aFzb94.mjs.map → setup-nonce-DFWG-J5c.mjs.map} +1 -1
- package/dist/single-flight-cache-B5p5cNOL.mjs +104 -0
- package/dist/single-flight-cache-B5p5cNOL.mjs.map +1 -0
- package/dist/{site-url-CnHlmAs9.mjs → site-url-BOTPgmeM.mjs} +2 -2
- package/dist/{site-url-CnHlmAs9.mjs.map → site-url-BOTPgmeM.mjs.map} +1 -1
- package/dist/{slugify-Cjh1ssOZ.mjs → slugify-Cce3dTdg.mjs} +1 -1
- package/dist/{slugify-Cjh1ssOZ.mjs.map → slugify-Cce3dTdg.mjs.map} +1 -1
- package/dist/{ssrf-BsVGIE0Z.mjs → ssrf-B0VeRLrp.mjs} +1 -1
- package/dist/{ssrf-BsVGIE0Z.mjs.map → ssrf-B0VeRLrp.mjs.map} +1 -1
- package/dist/status-CB2basWJ.mjs +30 -0
- package/dist/status-CB2basWJ.mjs.map +1 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +2 -2
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-BdAmbOwx.mjs → taxonomies-Be9B1jEj.mjs} +156 -122
- package/dist/taxonomies-Be9B1jEj.mjs.map +1 -0
- package/dist/{taxonomies-BILwiyGk.mjs → taxonomies-CJmkEpdS.mjs} +7 -7
- package/dist/{taxonomies-BILwiyGk.mjs.map → taxonomies-CJmkEpdS.mjs.map} +1 -1
- package/dist/{taxonomy-CdllE4oq.mjs → taxonomy-B2HQuVf5.mjs} +19 -6
- package/dist/taxonomy-B2HQuVf5.mjs.map +1 -0
- package/dist/{tokens-Bx2afeT-.mjs → tokens-BvrJvIB6.mjs} +2 -2
- package/dist/{tokens-Bx2afeT-.mjs.map → tokens-BvrJvIB6.mjs.map} +1 -1
- package/dist/{transaction-x2tJQ-A1.mjs → transaction-qfqpPVpu.mjs} +1 -1
- package/dist/{transaction-x2tJQ-A1.mjs.map → transaction-qfqpPVpu.mjs.map} +1 -1
- package/dist/transport-B4rXnSTf.mjs +135 -0
- package/dist/transport-B4rXnSTf.mjs.map +1 -0
- package/dist/{transport-B7PPP2CC.d.mts → transport-k7YjfmEn.d.mts} +1 -1
- package/dist/{transport-B7PPP2CC.d.mts.map → transport-k7YjfmEn.d.mts.map} +1 -1
- package/dist/{trusted-proxy-B4AfnoAp.mjs → trusted-proxy-DY1_UqHr.mjs} +1 -1
- package/dist/{trusted-proxy-B4AfnoAp.mjs.map → trusted-proxy-DY1_UqHr.mjs.map} +1 -1
- package/dist/{types-CPAPl93j.d.mts → types-CIKX2HO5.d.mts} +2 -2
- package/dist/{types-CPAPl93j.d.mts.map → types-CIKX2HO5.d.mts.map} +1 -1
- package/dist/{types-D4kUqbHh.d.mts → types-CKNXt63n.d.mts} +1 -1
- package/dist/{types-D4kUqbHh.d.mts.map → types-CKNXt63n.d.mts.map} +1 -1
- package/dist/{types-DTniiNto.d.mts → types-CWGYDYqF.d.mts} +2 -2
- package/dist/{types-DTniiNto.d.mts.map → types-CWGYDYqF.d.mts.map} +1 -1
- package/dist/{types-BH8-30hc.d.mts → types-CgvhU-hF.d.mts} +1 -1
- package/dist/{types-BH8-30hc.d.mts.map → types-CgvhU-hF.d.mts.map} +1 -1
- package/dist/{types-BFgrqwSk.d.mts → types-CmivgZbp.d.mts} +1 -1
- package/dist/{types-BFgrqwSk.d.mts.map → types-CmivgZbp.d.mts.map} +1 -1
- package/dist/{types-BPzXTV9x.d.mts → types-Czg1S3gB.d.mts} +9 -1
- package/dist/{types-BPzXTV9x.d.mts.map → types-Czg1S3gB.d.mts.map} +1 -1
- package/dist/types-DCNNfeCv.d.mts +124 -0
- package/dist/types-DCNNfeCv.d.mts.map +1 -0
- package/dist/{types-BUUVn1zr.d.mts → types-DPCpkzvS.d.mts} +1 -1
- package/dist/{types-BUUVn1zr.d.mts.map → types-DPCpkzvS.d.mts.map} +1 -1
- package/dist/{types-S15DXXNi.d.mts → types-DXLVzV2w.d.mts} +1 -1
- package/dist/{types-S15DXXNi.d.mts.map → types-DXLVzV2w.d.mts.map} +1 -1
- package/dist/{types-BXSUSAjt.mjs → types-DXOIbece.mjs} +3 -3
- package/dist/{types-BXSUSAjt.mjs.map → types-DXOIbece.mjs.map} +1 -1
- package/dist/{types-DpFmlNyB.mjs → types-DYF2_Vf4.mjs} +1 -1
- package/dist/{types-DpFmlNyB.mjs.map → types-DYF2_Vf4.mjs.map} +1 -1
- package/dist/{types-DZk_y-MU.mjs → types-tM44hEcf.mjs} +1 -1
- package/dist/{types-DZk_y-MU.mjs.map → types-tM44hEcf.mjs.map} +1 -1
- package/dist/{user-C0um7wrg.mjs → user-Db-Rti_z.mjs} +3 -3
- package/dist/{user-C0um7wrg.mjs.map → user-Db-Rti_z.mjs.map} +1 -1
- package/dist/{utils-C4Ih4DML.mjs → utils-LbHcSRTj.mjs} +2 -2
- package/dist/{utils-C4Ih4DML.mjs.map → utils-LbHcSRTj.mjs.map} +1 -1
- package/dist/{validate-Bz4vqcX1.mjs → validate-Bwl64sxv.mjs} +3 -3
- package/dist/{validate-Bz4vqcX1.mjs.map → validate-Bwl64sxv.mjs.map} +1 -1
- package/dist/{validate-CNwkPWzz.d.mts → validate-CE2M0nvx.d.mts} +5 -5
- package/dist/{validate-CNwkPWzz.d.mts.map → validate-CE2M0nvx.d.mts.map} +1 -1
- package/dist/{validation-DgGTJm3u.mjs → validation-C_yOvFaO.mjs} +6 -6
- package/dist/{validation-DgGTJm3u.mjs.map → validation-C_yOvFaO.mjs.map} +1 -1
- package/dist/version-RnYXYjzD.mjs +7 -0
- package/dist/{version-D-5txk2m.mjs.map → version-RnYXYjzD.mjs.map} +1 -1
- package/dist/{widgets-DZfmAbE4.mjs → widgets-8GONuRHo.mjs} +4 -4
- package/dist/{widgets-DZfmAbE4.mjs.map → widgets-8GONuRHo.mjs.map} +1 -1
- package/dist/{zod-generator-Djo_VHCt.mjs → zod-generator-D481JjzD.mjs} +3 -3
- package/dist/{zod-generator-Djo_VHCt.mjs.map → zod-generator-D481JjzD.mjs.map} +1 -1
- package/package.json +18 -6
- package/src/api/handlers/api-tokens.ts +19 -0
- package/src/api/handlers/comment-reactions.ts +165 -0
- package/src/api/handlers/redirects.ts +24 -13
- package/src/api/handlers/schema.ts +8 -0
- package/src/api/schemas/comments.ts +10 -0
- package/src/api/schemas/redirects.ts +11 -4
- package/src/astro/image-endpoint.ts +84 -0
- package/src/astro/index.ts +6 -0
- package/src/astro/integration/index.ts +127 -30
- package/src/astro/integration/routes.ts +51 -9
- package/src/astro/integration/runtime.ts +65 -1
- package/src/astro/integration/virtual-modules.ts +32 -0
- package/src/astro/integration/vite-config.ts +16 -0
- package/src/astro/middleware/auth.ts +4 -3
- package/src/astro/middleware/redirect.ts +12 -0
- package/src/astro/middleware/stream-end-metrics.ts +11 -1
- package/src/astro/middleware.ts +41 -3
- package/src/astro/object-cache/adapters.ts +50 -0
- package/src/astro/prefetch.ts +77 -0
- package/src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts +97 -0
- package/src/astro/routes/api/setup/dev-bypass.ts +5 -1
- package/src/astro/routes/api/snapshot.ts +3 -1
- package/src/astro/session-user.ts +57 -0
- package/src/astro/types.ts +1 -0
- package/src/bylines/field-defs-cache.ts +70 -20
- package/src/cli/commands/doctor.ts +1 -1
- package/src/comments/query.ts +78 -7
- package/src/comments/ranking.ts +58 -0
- package/src/components/Comments.astro +136 -1
- package/src/config/secrets.ts +28 -14
- package/src/database/instrumentation.ts +21 -1
- package/src/database/migrations/044_comment_reactions.ts +56 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/byline.ts +13 -0
- package/src/database/repositories/comment-reaction.ts +132 -0
- package/src/database/repositories/comment.ts +10 -0
- package/src/database/repositories/content.ts +25 -3
- package/src/database/repositories/menu.ts +13 -1
- package/src/database/repositories/seo.ts +3 -0
- package/src/database/repositories/taxonomy.ts +13 -1
- package/src/database/types.ts +9 -0
- package/src/emdash-runtime.ts +23 -9
- package/src/index.ts +22 -0
- package/src/mcp/server.ts +307 -20
- package/src/media/image-endpoint.ts +167 -0
- package/src/menus/index.ts +11 -4
- package/src/object-cache/codec.ts +73 -0
- package/src/object-cache/index.ts +495 -0
- package/src/object-cache/memory.ts +91 -0
- package/src/object-cache/types.ts +124 -0
- package/src/plugins/adapt-sandbox-entry.ts +11 -1
- package/src/query.ts +196 -17
- package/src/redirects/status.ts +27 -0
- package/src/schema/query.ts +11 -4
- package/src/settings/index.ts +30 -17
- package/src/taxonomies/index.ts +237 -165
- package/src/utils/{isolate-cache.ts → single-flight-cache.ts} +26 -21
- package/src/virtual-modules.d.ts +11 -0
- package/dist/api-DStv36ik.mjs.map +0 -1
- package/dist/api-tokens-DPfhPu5V.mjs.map +0 -1
- package/dist/byline-DUx48sJp.mjs.map +0 -1
- package/dist/byline-fields-DbibsvTl.d.mts.map +0 -1
- package/dist/comment-sqQxNpN3.mjs.map +0 -1
- package/dist/content-BIlVx-RX.mjs.map +0 -1
- package/dist/index-B1keaX5Y.d.mts.map +0 -1
- package/dist/menus-DX4_E01q.mjs.map +0 -1
- package/dist/menus-DrQLusqj.mjs.map +0 -1
- package/dist/query-CbUcI4Xk.mjs.map +0 -1
- package/dist/redirects-CCbCqCCd.mjs.map +0 -1
- package/dist/redirects-DxVoR7PI.mjs.map +0 -1
- package/dist/runner--4wMWwKM.mjs.map +0 -1
- package/dist/schema-C1E70ug_.mjs.map +0 -1
- package/dist/secrets-ChPTmy9x.mjs.map +0 -1
- package/dist/seo-B5e6y9Wk.mjs.map +0 -1
- package/dist/settings-DfxiWY_s.mjs +0 -411
- package/dist/settings-DfxiWY_s.mjs.map +0 -1
- package/dist/taxonomies-BdAmbOwx.mjs.map +0 -1
- package/dist/taxonomy-CdllE4oq.mjs.map +0 -1
- package/dist/transport-CmpLD7W3.mjs.map +0 -1
- package/dist/version-D-5txk2m.mjs +0 -7
- /package/dist/{api-tokens-Oq39ba-Z.mjs → api-tokens-BVH-H8Z9.mjs} +0 -0
- /package/dist/{ssrf-BvgVcfNQ.mjs → ssrf-Cz1e2QPn.mjs} +0 -0
- /package/dist/{types-CZI4E3qG.mjs → types-Bfr2Pj6z.mjs} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-tokens-DPfhPu5V.mjs","names":[],"sources":["../src/api/handlers/api-tokens.ts"],"sourcesContent":["/**\n * API token management handlers.\n *\n * Creates, lists, and revokes Personal Access Tokens (PATs).\n * Token format: ec_pat_<base64url>\n * Only the SHA-256 hash is stored — raw token shown once at creation.\n */\n\nimport type { Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { hashApiToken, generatePrefixedToken } from \"../../auth/api-tokens.js\";\nimport type { Database } from \"../../database/types.js\";\nimport type { ApiResult } from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ApiTokenInfo {\n\tid: string;\n\tname: string;\n\tprefix: string;\n\tscopes: string[];\n\tuserId: string;\n\texpiresAt: string | null;\n\tlastUsedAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface ApiTokenCreateResult {\n\t/** The raw token — shown once, never stored */\n\ttoken: string;\n\t/** Token metadata */\n\tinfo: ApiTokenInfo;\n}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\n/**\n * Create a new API token for a user.\n */\nexport async function handleApiTokenCreate(\n\tdb: Kysely<Database>,\n\tuserId: string,\n\tinput: {\n\t\tname: string;\n\t\tscopes: string[];\n\t\texpiresAt?: string;\n\t},\n): Promise<ApiResult<ApiTokenCreateResult>> {\n\ttry {\n\t\tconst id = ulid();\n\t\tconst { raw, hash, prefix } = generatePrefixedToken(\"ec_pat_\");\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_api_tokens\")\n\t\t\t.values({\n\t\t\t\tid,\n\t\t\t\tname: input.name,\n\t\t\t\ttoken_hash: hash,\n\t\t\t\tprefix,\n\t\t\t\tuser_id: userId,\n\t\t\t\tscopes: JSON.stringify(input.scopes),\n\t\t\t\texpires_at: input.expiresAt ?? null,\n\t\t\t})\n\t\t\t.execute();\n\n\t\tconst info: ApiTokenInfo = {\n\t\t\tid,\n\t\t\tname: input.name,\n\t\t\tprefix,\n\t\t\tscopes: input.scopes,\n\t\t\tuserId,\n\t\t\texpiresAt: input.expiresAt ?? null,\n\t\t\tlastUsedAt: null,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\n\t\treturn { success: true, data: { token: raw, info } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_CREATE_ERROR\",\n\t\t\t\tmessage: \"Failed to create API token\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * List all API tokens for a user (never returns the raw token or hash).\n */\nexport async function handleApiTokenList(\n\tdb: Kysely<Database>,\n\tuserId: string,\n): Promise<ApiResult<{ items: ApiTokenInfo[] }>> {\n\ttry {\n\t\tconst rows = await db\n\t\t\t.selectFrom(\"_emdash_api_tokens\")\n\t\t\t.select([\n\t\t\t\t\"id\",\n\t\t\t\t\"name\",\n\t\t\t\t\"prefix\",\n\t\t\t\t\"scopes\",\n\t\t\t\t\"user_id\",\n\t\t\t\t\"expires_at\",\n\t\t\t\t\"last_used_at\",\n\t\t\t\t\"created_at\",\n\t\t\t])\n\t\t\t.where(\"user_id\", \"=\", userId)\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.execute();\n\n\t\tconst items: ApiTokenInfo[] = rows.map((row) => ({\n\t\t\tid: row.id,\n\t\t\tname: row.name,\n\t\t\tprefix: row.prefix,\n\t\t\tscopes: JSON.parse(row.scopes) as string[],\n\t\t\tuserId: row.user_id,\n\t\t\texpiresAt: row.expires_at,\n\t\t\tlastUsedAt: row.last_used_at,\n\t\t\tcreatedAt: row.created_at,\n\t\t}));\n\n\t\treturn { success: true, data: { items } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_LIST_ERROR\",\n\t\t\t\tmessage: \"Failed to list API tokens\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Revoke (delete) an API token.\n */\nexport async function handleApiTokenRevoke(\n\tdb: Kysely<Database>,\n\ttokenId: string,\n\tuserId: string,\n): Promise<ApiResult<{ revoked: boolean }>> {\n\ttry {\n\t\tconst result = await db\n\t\t\t.deleteFrom(\"_emdash_api_tokens\")\n\t\t\t.where(\"id\", \"=\", tokenId)\n\t\t\t.where(\"user_id\", \"=\", userId)\n\t\t\t.executeTakeFirst();\n\n\t\tif (result.numDeletedRows === 0n) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Token not found\" },\n\t\t\t};\n\t\t}\n\n\t\treturn { success: true, data: { revoked: true } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"TOKEN_REVOKE_ERROR\",\n\t\t\t\tmessage: \"Failed to revoke API token\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Resolve a raw API token (ec_pat_...) to a user ID and scopes.\n * Updates last_used_at on successful lookup.\n * Returns null if the token is invalid or expired.\n */\nexport async function resolveApiToken(\n\tdb: Kysely<Database>,\n\trawToken: string,\n): Promise<{ userId: string; scopes: string[] } | null> {\n\tconst hash = hashApiToken(rawToken);\n\n\tconst row = await db\n\t\t.selectFrom(\"_emdash_api_tokens\")\n\t\t.select([\"id\", \"user_id\", \"scopes\", \"expires_at\"])\n\t\t.where(\"token_hash\", \"=\", hash)\n\t\t.executeTakeFirst();\n\n\tif (!row) return null;\n\n\t// Check expiry\n\tif (row.expires_at && new Date(row.expires_at) < new Date()) {\n\t\treturn null;\n\t}\n\n\t// Update last_used_at (fire-and-forget, don't block the request)\n\tdb.updateTable(\"_emdash_api_tokens\")\n\t\t.set({ last_used_at: new Date().toISOString() })\n\t\t.where(\"id\", \"=\", row.id)\n\t\t.execute()\n\t\t.catch(() => {}); // Non-critical, swallow errors\n\n\treturn {\n\t\tuserId: row.user_id,\n\t\tscopes: JSON.parse(row.scopes) as string[],\n\t};\n}\n\n/**\n * Resolve an OAuth access token (ec_oat_...) to a user ID and scopes.\n * Returns null if the token is invalid or expired.\n */\nexport async function resolveOAuthToken(\n\tdb: Kysely<Database>,\n\trawToken: string,\n): Promise<{ userId: string; scopes: string[] } | null> {\n\tconst hash = hashApiToken(rawToken);\n\n\tconst row = await db\n\t\t.selectFrom(\"_emdash_oauth_tokens\")\n\t\t.select([\"user_id\", \"scopes\", \"expires_at\", \"token_type\"])\n\t\t.where(\"token_hash\", \"=\", hash)\n\t\t.where(\"token_type\", \"=\", \"access\")\n\t\t.executeTakeFirst();\n\n\tif (!row) return null;\n\n\t// Check expiry\n\tif (new Date(row.expires_at) < new Date()) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tuserId: row.user_id,\n\t\tscopes: JSON.parse(row.scopes) as string[],\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"byline-DUx48sJp.mjs","names":[],"sources":["../src/bylines/field-defs-cache.ts","../src/database/repositories/byline.ts"],"sourcesContent":["/**\n * Byline field-definitions cache\n *\n * Discussion #1174 / Phase 3. Two-tier cache for the byline custom-field\n * registry, mirroring the `settings/index.ts` pattern.\n *\n * **Tier 1 — per-isolate (globalThis).** Field definitions change rarely\n * but are read on every byline hydration (admin pages, content rendering,\n * API responses). Caching at the isolate level drops the SELECT-from-\n * `_emdash_byline_fields` from once-per-hydration to once-per-isolate-\n * after-bump. The cache holds a Promise (not the resolved value) so\n * concurrent cold-isolate readers share the in-flight query.\n *\n * Stored on globalThis under `Symbol.for(\"emdash:byline-field-defs\")` so\n * Vite SSR chunk duplication can't produce two independent caches (same\n * pattern as `request-cache.ts` and `request-context.ts`).\n *\n * **Tier 2 — per-request.** Wraps both the version read and the defs\n * fetch in `requestCached` so a single page render that hits byline\n * hydration multiple times (e.g. list view + individual byline lookups\n * in a sidebar) pays at most one version read and one defs fetch in\n * total. The defs cache key includes the version, so a (highly\n * unlikely) mid-request bump still produces a self-consistent view —\n * the second call sees a different key and refetches.\n *\n * **Invalidation.** `options.byline_fields_version` is bumped by every\n * `BylineSchemaRegistry` mutation (Phase 2). Each isolate independently\n * reads the persisted version on the next request and compares against\n * its cached version; mismatch triggers a refetch and overwrite. Other\n * isolates see the change within one request after the bump propagates.\n *\n * **Isolated databases bypass the global cache.** Playground and DO\n * preview sessions set `requestContext.dbIsIsolated = true`, signalling\n * the per-request `db` points at an isolated schema that may diverge\n * from the singleton. Schema-derived caches keyed by the singleton's\n * version would silently leak the singleton's defs into the isolated\n * request. We follow the `loader.ts:74` `getTaxonomyNames` precedent:\n * skip both reading from and writing to the global holder when the\n * request is isolated. The per-request cache (`requestCached`) is keyed\n * by the WeakMap'd `EmDashRequestContext`, so it can't cross-pollinate\n * between requests — it stays in play even for isolated DBs.\n *\n * **Why a versioned cache and not a TTL?** The version counter gives\n * deterministic invalidation without the staleness window a TTL would\n * impose. Field-definition changes need to be visible to the next\n * request, not eventually. The cost is one cheap `options` read per\n * request — cheaper than the field-defs fetch it replaces, and cheaper\n * than maintaining a TTL state machine.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../database/types.js\";\nimport { requestCached } from \"../request-cache.js\";\nimport { getRequestContext } from \"../request-context.js\";\nimport { BylineSchemaRegistry } from \"../schema/byline-registry.js\";\nimport type { BylineFieldDefinition } from \"../schema/types.js\";\n\ninterface FieldDefsHolder {\n\t/** In-flight or resolved defs promise for the cached version. Null until first read. */\n\tcached: Promise<BylineFieldDefinition[]> | null;\n\t/** Persisted-version value that `cached` was fetched against. */\n\tcachedVersion: number;\n}\n\nconst HOLDER_KEY = Symbol.for(\"emdash:byline-field-defs\");\nconst g = globalThis as Record<symbol, unknown>;\nconst holder: FieldDefsHolder =\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-cache.ts)\n\t(g[HOLDER_KEY] as FieldDefsHolder | undefined) ??\n\t(() => {\n\t\tconst h: FieldDefsHolder = { cached: null, cachedVersion: -1 };\n\t\tg[HOLDER_KEY] = h;\n\t\treturn h;\n\t})();\n\nconst REQUEST_CACHE_KEY_VERSION = \"byline-fields-version\";\nconst REQUEST_CACHE_KEY_DEFS_PREFIX = \"byline-field-defs:\";\n\n/**\n * Read the persisted `options.byline_fields_version` counter. Cached for\n * the duration of the current request via `requestCached`. Returns `0`\n * when the row is missing (matches `BylineSchemaRegistry.getVersion`).\n */\nasync function getBylineFieldsVersion(db: Kysely<Database>): Promise<number> {\n\treturn requestCached(REQUEST_CACHE_KEY_VERSION, () => new BylineSchemaRegistry(db).getVersion());\n}\n\n/**\n * Resolve registered byline custom-field definitions. Two-tier cache:\n * per-request via `requestCached`, then per-isolate via the global\n * holder.\n *\n * The global holder is bypassed for isolated requests (playground / DO\n * preview, which point at a divergent schema) and for dirty versions\n * (odd counter — see `BylineSchemaRegistry`'s class JSDoc — indicates\n * an in-flight or crashed mutation). Both bypass paths still hit the\n * per-request cache, so a single render dedupes within itself.\n *\n * Always returns an array. Empty = no custom fields registered.\n */\nexport async function getBylineFieldDefs(db: Kysely<Database>): Promise<BylineFieldDefinition[]> {\n\tconst isolated = getRequestContext()?.dbIsIsolated === true;\n\tconst version = await getBylineFieldsVersion(db);\n\tconst dirty = version % 2 !== 0;\n\treturn requestCached(`${REQUEST_CACHE_KEY_DEFS_PREFIX}${version}`, async () => {\n\t\tif (isolated || dirty) {\n\t\t\treturn new BylineSchemaRegistry(db).listFields();\n\t\t}\n\t\tif (holder.cached !== null && holder.cachedVersion === version) {\n\t\t\treturn holder.cached;\n\t\t}\n\t\tconst defs = new BylineSchemaRegistry(db).listFields().catch((error) => {\n\t\t\tif (holder.cached === defs) {\n\t\t\t\tholder.cached = null;\n\t\t\t\tholder.cachedVersion = -1;\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tholder.cached = defs;\n\t\tholder.cachedVersion = version;\n\t\treturn defs;\n\t});\n}\n\n/**\n * Test/internal helper: clear the per-isolate cache. Useful for unit\n * tests that mutate the registry directly and need to force a refetch\n * without going through the full version-bump path.\n *\n * Production code paths should rely on the version counter for\n * invalidation — calling this from a write path would bypass the\n * coordination that lets other isolates see the change.\n */\nexport function resetBylineFieldDefsCacheForTests(): void {\n\tholder.cached = null;\n\tholder.cachedVersion = -1;\n}\n","import { sql, type Kysely, type Selectable } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { getBylineFieldDefs } from \"../../bylines/field-defs-cache.js\";\nimport {\n\tclearRequestCacheEntry,\n\tpeekRequestCache,\n\tsetRequestCacheEntry,\n} from \"../../request-cache.js\";\nimport type { BylineFieldDefinition, CustomFieldValue } from \"../../schema/types.js\";\nimport { chunks, SQL_BATCH_SIZE } from \"../../utils/chunks.js\";\nimport { listTablesLike } from \"../dialect-helpers.js\";\nimport { withTransaction } from \"../transaction.js\";\nimport type { BylineTable, Database } from \"../types.js\";\nimport { validateIdentifier } from \"../validate.js\";\nimport {\n\tdecodeCursor,\n\tEmDashValidationError,\n\tencodeCursor,\n\ttype BylineSummary,\n\ttype ContentBylineCredit,\n\ttype FindManyResult,\n} from \"./types.js\";\n\ntype BylineRow = Selectable<BylineTable>;\n\n/**\n * A byline row optionally augmented with the avatar's media columns, folded in\n * by the `LEFT JOIN media` in the content-credit hydration queries. The plain\n * `selectAll()` finders produce rows without these keys, so they're optional\n * and `rowToByline` defaults them to null.\n */\ntype BylineRowWithAvatar = BylineRow & {\n\tavatar_storage_key?: string | null;\n\tavatar_alt?: string | null;\n};\n\nexport interface CreateBylineInput {\n\tslug: string;\n\tdisplayName: string;\n\tbio?: string | null;\n\tavatarMediaId?: string | null;\n\twebsiteUrl?: string | null;\n\tuserId?: string | null;\n\tisGuest?: boolean;\n\t/**\n\t * Locale this byline row belongs to. When omitted, the DB DEFAULT (the\n\t * configured `defaultLocale` after migration 040) is used. Keeps behaviour\n\t * consistent with `TaxonomyRepository.create`.\n\t */\n\tlocale?: string;\n\t/**\n\t * When set, the new row joins the source byline's translation_group rather\n\t * than minting a fresh one. The source must exist; otherwise the create\n\t * throws. Mirrors `TaxonomyRepository.create`.\n\t */\n\ttranslationOf?: string;\n\t/**\n\t * Byline custom-field values to seed on the new row (Phase 6 of\n\t * Discussion #1174). Same semantics as `UpdateBylineInput.customFields`:\n\t * keys must match registered slugs in `_emdash_byline_fields`, values\n\t * are validated against the field's type, and writes route to\n\t * `_emdash_byline_field_values` (translatable) or\n\t * `_emdash_byline_field_group_values` (group-shared). Validation runs\n\t * before the row insert so a bad value can't leave a bare byline behind.\n\t */\n\tcustomFields?: Record<string, unknown>;\n}\n\nexport interface UpdateBylineInput {\n\tslug?: string;\n\tdisplayName?: string;\n\tbio?: string | null;\n\tavatarMediaId?: string | null;\n\twebsiteUrl?: string | null;\n\tuserId?: string | null;\n\tisGuest?: boolean;\n\t/**\n\t * Byline custom-field values to write (Phase 3 of Discussion #1174).\n\t *\n\t * Each key must match a registered slug in `_emdash_byline_fields`;\n\t * unknown keys throw `EmDashValidationError`. Per-field writes route\n\t * to `_emdash_byline_field_values` (when the field's `translatable`\n\t * flag is true) or `_emdash_byline_field_group_values` (when false).\n\t * A value of `null` clears the row.\n\t *\n\t * Values are validated against the field's type:\n\t * - `string` / `text` / `url` accept a `string`\n\t * - `boolean` accepts a `boolean`\n\t * - `select` accepts a `string` that appears in `validation.options`\n\t *\n\t * Writes are idempotent (`INSERT … ON CONFLICT DO UPDATE`), so\n\t * retrying the same update produces the same DB state.\n\t */\n\tcustomFields?: Record<string, unknown>;\n}\n\nexport interface ContentBylineInput {\n\tbylineId: string;\n\troleLabel?: string | null;\n}\n\nfunction rowToByline(row: BylineRowWithAvatar): BylineSummary {\n\treturn {\n\t\tid: row.id,\n\t\tslug: row.slug,\n\t\tdisplayName: row.display_name,\n\t\tbio: row.bio,\n\t\tavatarMediaId: row.avatar_media_id,\n\t\tavatarStorageKey: row.avatar_storage_key ?? null,\n\t\tavatarAlt: row.avatar_alt ?? null,\n\t\twebsiteUrl: row.website_url,\n\t\tuserId: row.user_id,\n\t\tisGuest: row.is_guest === 1,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t\tlocale: row.locale,\n\t\ttranslationGroup: row.translation_group,\n\t};\n}\n\n/**\n * Merge a single decoded value into a `BylineSummary.customFields` map.\n * Centralised so the merge semantics (null storage, JSON.parse failure\n * handling) live in one place across both translatable and group-shared\n * paths.\n *\n * A stored row with `value = NULL` (representing an explicit null) is\n * surfaced as `null` in `customFields`. A row with a malformed JSON\n * payload is dropped silently with a `console.warn` — a corrupted\n * payload shouldn't break the entire byline hydration; the field-defs\n * cache will let admins replace the value, and the warning makes the\n * issue debuggable. (Storage path uses `JSON.stringify`, so the only\n * way to get malformed JSON is direct DB tampering or a future\n * migration bug.)\n */\nfunction assignCustomFieldValue(\n\tsummary: BylineSummary,\n\tfield: BylineFieldDefinition,\n\tstored: string | null,\n): void {\n\tconst target = summary.customFields ?? {};\n\tif (stored === null) {\n\t\ttarget[field.slug] = null;\n\t} else {\n\t\ttry {\n\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- coerceFieldValue ran at write time, see field-defs-cache.ts\n\t\t\ttarget[field.slug] = JSON.parse(stored) as CustomFieldValue;\n\t\t} catch {\n\t\t\tconsole.warn(\n\t\t\t\t`[BylineRepository] dropping malformed JSON for byline=${summary.id} ` +\n\t\t\t\t\t`field=${field.slug}: ${stored.slice(0, 60)}`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n\tsummary.customFields = target;\n}\n\n/**\n * Coerce a raw write-path value to `CustomFieldValue`, throwing\n * `EmDashValidationError` on type mismatch. `null` clears the field\n * (DELETE in the write path).\n *\n * TODO: `field.required` is not enforced. The admin UI exposes the\n * toggle but the backend accepts missing values; design pass needed\n * on the enforcement model.\n */\nfunction coerceFieldValue(field: BylineFieldDefinition, raw: unknown): CustomFieldValue {\n\tif (raw === null) return null;\n\n\tswitch (field.type) {\n\t\tcase \"string\":\n\t\tcase \"text\": {\n\t\t\tif (typeof raw !== \"string\") {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" expects a string value (received ${typeof raw})`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: typeof raw },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn raw;\n\t\t}\n\t\tcase \"url\": {\n\t\t\tif (typeof raw !== \"string\") {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" expects a string value (received ${typeof raw})`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: typeof raw },\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Empty string round-trips as a clear from the admin UI; any\n\t\t\t// non-empty value must be a valid http(s) URL. The scheme\n\t\t\t// allowlist mirrors `httpUrl` in `api/schemas/common.ts` —\n\t\t\t// `new URL` alone would accept `javascript:`/`data:` etc.\n\t\t\tif (raw === \"\") return raw;\n\t\t\tlet parsed: URL;\n\t\t\ttry {\n\t\t\t\tparsed = new URL(raw);\n\t\t\t} catch {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" expects a valid URL (received \"${raw}\")`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: raw },\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" must use http or https scheme (received \"${parsed.protocol}\")`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: raw, protocol: parsed.protocol },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn raw;\n\t\t}\n\t\tcase \"boolean\": {\n\t\t\tif (typeof raw !== \"boolean\") {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" expects a boolean value (received ${typeof raw})`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: typeof raw },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn raw;\n\t\t}\n\t\tcase \"select\": {\n\t\t\tif (typeof raw !== \"string\") {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" expects a string value (received ${typeof raw})`,\n\t\t\t\t\t{ slug: field.slug, type: field.type, received: typeof raw },\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst options = field.validation?.options ?? [];\n\t\t\tif (!options.includes(raw)) {\n\t\t\t\tthrow new EmDashValidationError(\n\t\t\t\t\t`Byline field \"${field.slug}\" value \"${raw}\" is not one of the registered choices`,\n\t\t\t\t\t{ slug: field.slug, value: raw, options },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn raw;\n\t\t}\n\t}\n}\n\n/**\n * Byline repository for content credits.\n *\n * Bylines are per-locale (migration 040). Translations of the same byline\n * share a `translation_group` ULID. `_emdash_content_bylines.byline_id` and\n * `ec_*.primary_byline_id` store the translation_group (not a row id) so a\n * single credit spans every locale variant of a byline.\n *\n * The repository does not resolve locale fallbacks on its own — callers\n * supply the locale they want. Hydration is strict per locale: a credit at\n * locale X renders iff a byline row exists at locale X within the credited\n * translation group. This mirrors `TaxonomyRepository.getTermsForEntry` and\n * the convention established by PR #916.\n *\n * Runtime helpers in `packages/core/src/bylines/index.ts` may layer fallback\n * resolution on top for the \"look up one byline by slug\" path, but the\n * relation-hydration methods on this class are always strict.\n */\nexport class BylineRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t// ============================================\n\t// Custom-field hydration (Phase 3 of #1174)\n\t// ============================================\n\n\t/**\n\t * Merge `customFields` onto each `BylineSummary` produced from the\n\t * given rows. Two batched queries total — one against\n\t * `_emdash_byline_field_values` (keyed by `byline_id`), one against\n\t * `_emdash_byline_field_group_values` (keyed by `translation_group`)\n\t * — both chunked at `SQL_BATCH_SIZE` for D1's bound-parameter cap.\n\t *\n\t * When zero fields are registered, every row gets `customFields = {}`\n\t * with no value-table reads (the field-defs cache returns `[]`).\n\t * Group-shared values are looked up via the row's `translation_group`,\n\t * so every locale sibling of the same byline identity sees the same\n\t * non-translatable value without re-reading per row.\n\t *\n\t * **Duplicate-row handling.** Callers (notably `getContentBylinesMany`\n\t * for list views with repeated authors) can pass the same byline row\n\t * multiple times. We assign values by *iterating both `rows` and\n\t * `summaries` in lockstep by index*, not by deduping into a Map keyed\n\t * on byline id. A Map approach silently drops earlier duplicates' merge\n\t * step (last writer wins, earlier instances keep their initial `{}`).\n\t * Iterating by index gives every duplicate its own merged copy.\n\t *\n\t * Hydration is *strict per row* — values are merged onto whichever\n\t * `BylineRow` produced them. Fallback semantics (e.g. \"if no value\n\t * for this locale, show the default-locale value\") are not the\n\t * repository's concern; consumers layer them on top if wanted, the\n\t * same way `BylineRepository` doesn't resolve locale fallback for\n\t * the base byline lookup.\n\t */\n\tprivate async withCustomFields(rows: BylineRow[]): Promise<BylineSummary[]> {\n\t\tconst summaries = rows.map(rowToByline);\n\t\t// Always populate `customFields = {}` (PR plan AC #6) — even when\n\t\t// no fields are registered, every BylineSummary carries the empty\n\t\t// object. A fresh object per summary so duplicate rows don't share\n\t\t// state.\n\t\tfor (const summary of summaries) {\n\t\t\tsummary.customFields = {};\n\t\t}\n\t\tawait this.applyCustomFieldsTo(summaries);\n\t\treturn summaries;\n\t}\n\n\tprivate async withCustomFieldsOne(row: BylineRow | undefined): Promise<BylineSummary | null> {\n\t\tif (!row) return null;\n\t\tconst [result] = await this.withCustomFields([row]);\n\t\treturn result ?? null;\n\t}\n\n\t/**\n\t * Hydrate `customFields` on each `BylineSummary`, mutating in place.\n\t *\n\t * The public entry point for callers that fetch byline rows in\n\t * multiple passes (e.g. `getBylinesForEntries`, which buckets by\n\t * locale and calls `getContentBylinesMany` per bucket) and want a\n\t * single batched hydration over the union of bylines, not one per\n\t * pass. Use with the `skipHydration` option on the read methods to\n\t * defer customFields work to a single call here.\n\t *\n\t * Two batched queries total (translatable + group-shared) regardless\n\t * of how many bylines, locales, or translation_groups are in the\n\t * input — meets the Phase 3 query-count envelope for mixed-locale\n\t * list views even when sibling locales reference disjoint\n\t * translation_groups.\n\t *\n\t * Replaces any existing `customFields` on each summary with a freshly\n\t * fetched map. Callers that want to merge rather than replace should\n\t * not use this entry point.\n\t */\n\tasync hydrateBylineCustomFields(summaries: BylineSummary[]): Promise<void> {\n\t\tfor (const summary of summaries) {\n\t\t\tsummary.customFields = {};\n\t\t}\n\t\tawait this.applyCustomFieldsTo(summaries);\n\t}\n\n\t/**\n\t * Shared merge engine for `withCustomFields` and\n\t * `hydrateBylineCustomFields`. Reads field defs (cached), batches the\n\t * translatable + group-shared fetches, and walks `summaries` directly\n\t * to apply values.\n\t *\n\t * Iterates `summaries` (not a `summaryById` map) so duplicate\n\t * `BylineSummary` objects sharing the same `id` — e.g. the same\n\t * author credited to multiple entries — each get their own merged\n\t * values. The previous Map-based dedup silently dropped earlier\n\t * duplicates' merge step.\n\t */\n\tprivate async applyCustomFieldsTo(summaries: BylineSummary[]): Promise<void> {\n\t\tif (summaries.length === 0) return;\n\n\t\tconst defs = await getBylineFieldDefs(this.db);\n\t\tif (defs.length === 0) return;\n\n\t\tconst fieldById = new Map(defs.map((d) => [d.id, d]));\n\n\t\t// Translatable values, batched by byline_id (unique per locale, so\n\t\t// IDs across different locale buckets don't collide — one batched\n\t\t// query covers everything).\n\t\tconst translatableByByline = new Map<string, Map<string, string | null>>();\n\t\tconst bylineIds = [...new Set(summaries.map((s) => s.id))];\n\t\tfor (const chunk of chunks(bylineIds, SQL_BATCH_SIZE)) {\n\t\t\tconst trRows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_byline_field_values\")\n\t\t\t\t.select([\"byline_id\", \"field_id\", \"value\"])\n\t\t\t\t.where(\"byline_id\", \"in\", chunk)\n\t\t\t\t.execute();\n\t\t\tfor (const trRow of trRows) {\n\t\t\t\tlet fieldMap = translatableByByline.get(trRow.byline_id);\n\t\t\t\tif (!fieldMap) {\n\t\t\t\t\tfieldMap = new Map();\n\t\t\t\t\ttranslatableByByline.set(trRow.byline_id, fieldMap);\n\t\t\t\t}\n\t\t\t\tfieldMap.set(trRow.field_id, trRow.value);\n\t\t\t}\n\t\t}\n\n\t\t// Group-shared values, batched over the union of translation_groups,\n\t\t// with per-group request-cache priming so subsequent calls within\n\t\t// the same request share the lookup. Together with the\n\t\t// `hydrateBylineCustomFields` + `skipHydration` flow in\n\t\t// `getBylinesForEntries`, this keeps mixed-locale list views to\n\t\t// **one** group-shared query per request, even for disjoint\n\t\t// translation_groups across locale buckets.\n\t\tconst groups = [\n\t\t\t...new Set(\n\t\t\t\tsummaries\n\t\t\t\t\t.map((s) => s.translationGroup)\n\t\t\t\t\t.filter((g): g is string => typeof g === \"string\" && g.length > 0),\n\t\t\t),\n\t\t];\n\t\tconst groupByGroup = await this.loadGroupValuesByIds(groups);\n\n\t\t// Each loop gates on `field.translatable` so a row in the wrong\n\t\t// owner table (e.g. left over from a translatable flip) can't\n\t\t// leak into hydration.\n\t\tfor (const summary of summaries) {\n\t\t\tconst trValues = translatableByByline.get(summary.id);\n\t\t\tif (trValues) {\n\t\t\t\tfor (const [fieldId, value] of trValues) {\n\t\t\t\t\tconst field = fieldById.get(fieldId);\n\t\t\t\t\tif (!field || !field.translatable) continue;\n\t\t\t\t\tassignCustomFieldValue(summary, field, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (summary.translationGroup) {\n\t\t\t\tconst grpValues = groupByGroup.get(summary.translationGroup);\n\t\t\t\tif (grpValues) {\n\t\t\t\t\tfor (const [fieldId, value] of grpValues) {\n\t\t\t\t\t\tconst field = fieldById.get(fieldId);\n\t\t\t\t\t\tif (!field || field.translatable) continue;\n\t\t\t\t\t\tassignCustomFieldValue(summary, field, value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Resolve the group-shared custom-field values for a set of\n\t * translation_groups, sharing work across hydration calls within the\n\t * same request via per-group `requestCached` entries.\n\t *\n\t * The non-translatable storage table (`_emdash_byline_field_group_values`)\n\t * is keyed by `translation_group`, which is locale-agnostic. Combining\n\t * this method with `skipHydration` on `getContentBylinesMany` and a\n\t * single `hydrateBylineCustomFields` call (see\n\t * `getBylinesForEntries`) keeps mixed-locale list hydration to **one**\n\t * batched group-shared SQL per request — even with disjoint\n\t * translation_groups across locale buckets. Solo callers (`findById`,\n\t * `findMany`, etc.) still get the same per-call batching they had\n\t * before; the cache simply means a second call in the same request\n\t * for an overlapping group is free.\n\t *\n\t * Cache key: `byline-field-group-values:${groupId}` — one entry per\n\t * group. Writes use `setRequestCacheEntry` (idempotent, doesn't\n\t * overwrite); `BylineRepository.update` calls `clearRequestCacheEntry`\n\t * after a group-shared write to keep the cache fresh within the same\n\t * request.\n\t */\n\tprivate async loadGroupValuesByIds(\n\t\tgroups: string[],\n\t): Promise<Map<string, Map<string, string | null>>> {\n\t\tconst result = new Map<string, Map<string, string | null>>();\n\t\tif (groups.length === 0) return result;\n\n\t\t// First pass: pull any already-cached groups from the request scope.\n\t\tconst missing: string[] = [];\n\t\tfor (const g of groups) {\n\t\t\tconst cached = peekRequestCache<Map<string, string | null>>(`byline-field-group-values:${g}`);\n\t\t\tif (cached) {\n\t\t\t\tresult.set(g, await cached);\n\t\t\t} else {\n\t\t\t\tmissing.push(g);\n\t\t\t}\n\t\t}\n\n\t\tif (missing.length === 0) return result;\n\n\t\t// Second pass: one batched SQL for the union of all missing groups\n\t\t// (chunked for D1's bound-parameter cap). Initialise empty maps for\n\t\t// missing groups so the primed cache covers \"this group has no\n\t\t// values\" — preventing a re-fetch on subsequent calls.\n\t\tconst fetched = new Map<string, Map<string, string | null>>();\n\t\tfor (const g of missing) fetched.set(g, new Map());\n\t\tfor (const chunk of chunks(missing, SQL_BATCH_SIZE)) {\n\t\t\tconst grpRows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_byline_field_group_values\")\n\t\t\t\t.select([\"translation_group\", \"field_id\", \"value\"])\n\t\t\t\t.where(\"translation_group\", \"in\", chunk)\n\t\t\t\t.execute();\n\t\t\tfor (const grpRow of grpRows) {\n\t\t\t\tconst fieldMap = fetched.get(grpRow.translation_group);\n\t\t\t\tif (!fieldMap) continue;\n\t\t\t\tfieldMap.set(grpRow.field_id, grpRow.value);\n\t\t\t}\n\t\t}\n\n\t\tfor (const g of missing) {\n\t\t\tconst m = fetched.get(g);\n\t\t\tif (!m) continue;\n\t\t\tsetRequestCacheEntry(`byline-field-group-values:${g}`, m);\n\t\t\tresult.set(g, m);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// ============================================\n\t// Reads\n\t// ============================================\n\n\tasync findById(id: string): Promise<BylineSummary | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\t\treturn this.withCustomFieldsOne(row);\n\t}\n\n\t/**\n\t * Find a byline by slug. When `locale` is provided, filter by it strictly.\n\t * When omitted, returns the lowest-locale-code match (deterministic across\n\t * calls). Mirrors `TaxonomyRepository.findBySlug`.\n\t */\n\tasync findBySlug(slug: string, options?: { locale?: string }): Promise<BylineSummary | null> {\n\t\tlet query = this.db.selectFrom(\"_emdash_bylines\").selectAll().where(\"slug\", \"=\", slug);\n\t\tif (options?.locale !== undefined) query = query.where(\"locale\", \"=\", options.locale);\n\t\tconst row = await query.orderBy(\"locale\", \"asc\").executeTakeFirst();\n\t\treturn this.withCustomFieldsOne(row);\n\t}\n\n\t/**\n\t * Find the byline linked to a CMS user. Post-migration 040 the partial\n\t * unique on user_id is `(user_id, locale)`, so `locale` is required to\n\t * disambiguate when multiple locale variants exist. When omitted, returns\n\t * the lowest-locale-code match.\n\t */\n\tasync findByUserId(userId: string, options?: { locale?: string }): Promise<BylineSummary | null> {\n\t\tlet query = this.db.selectFrom(\"_emdash_bylines\").selectAll().where(\"user_id\", \"=\", userId);\n\t\tif (options?.locale !== undefined) query = query.where(\"locale\", \"=\", options.locale);\n\t\tconst row = await query.orderBy(\"locale\", \"asc\").executeTakeFirst();\n\t\treturn this.withCustomFieldsOne(row);\n\t}\n\n\tasync findMany(options?: {\n\t\tsearch?: string;\n\t\tisGuest?: boolean;\n\t\tuserId?: string;\n\t\tlocale?: string;\n\t\tcursor?: string;\n\t\tlimit?: number;\n\t}): Promise<FindManyResult<BylineSummary>> {\n\t\tconst limit = Math.min(Math.max(options?.limit ?? 50, 1), 100);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\tif (options?.search) {\n\t\t\tconst escaped = options.search\n\t\t\t\t.replaceAll(\"\\\\\", \"\\\\\\\\\")\n\t\t\t\t.replaceAll(\"%\", \"\\\\%\")\n\t\t\t\t.replaceAll(\"_\", \"\\\\_\");\n\t\t\tconst term = `%${escaped}%`;\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([eb(\"display_name\", \"like\", term), eb(\"slug\", \"like\", term)]),\n\t\t\t);\n\t\t}\n\n\t\tif (options?.isGuest !== undefined) {\n\t\t\tquery = query.where(\"is_guest\", \"=\", options.isGuest ? 1 : 0);\n\t\t}\n\n\t\tif (options?.userId !== undefined) {\n\t\t\tquery = query.where(\"user_id\", \"=\", options.userId);\n\t\t}\n\n\t\tif (options?.locale !== undefined) {\n\t\t\tquery = query.where(\"locale\", \"=\", options.locale);\n\t\t}\n\n\t\tif (options?.cursor) {\n\t\t\tconst decoded = decodeCursor(options.cursor);\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", decoded.orderValue),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", decoded.orderValue), eb(\"id\", \"<\", decoded.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await query.execute();\n\t\tconst pageRows = rows.slice(0, limit);\n\t\tconst items = await this.withCustomFields(pageRows);\n\t\tconst result: FindManyResult<BylineSummary> = { items };\n\n\t\tif (rows.length > limit) {\n\t\t\tconst last = items.at(-1);\n\t\t\tif (last) {\n\t\t\t\tresult.nextCursor = encodeCursor(last.createdAt, last.id);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * List every sibling row in `translation_group`. Used by the admin\n\t * `TranslationsPanel` to render one entry per configured locale.\n\t */\n\tasync listTranslations(id: string): Promise<BylineSummary[]> {\n\t\tconst anchor = await this.findById(id);\n\t\tif (!anchor) return [];\n\t\tconst group = anchor.translationGroup ?? anchor.id;\n\t\treturn this.findByTranslationGroup(group);\n\t}\n\n\t/**\n\t * Direct lookup by `translation_group`. Returns every locale variant of a\n\t * byline, ordered by locale code (deterministic).\n\t */\n\tasync findByTranslationGroup(translationGroup: string): Promise<BylineSummary[]> {\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.where(\"translation_group\", \"=\", translationGroup)\n\t\t\t.orderBy(\"locale\", \"asc\")\n\t\t\t.execute();\n\t\treturn this.withCustomFields(rows);\n\t}\n\n\t/**\n\t * Validate a `customFields` input map into a write list before any row\n\t * write — throws `EmDashValidationError` on unknown slugs, type\n\t * mismatches, or select-choice misses.\n\t */\n\tprivate async resolveCustomFieldWrites(\n\t\tcustomFields: Record<string, unknown> | undefined,\n\t): Promise<Array<{ field: BylineFieldDefinition; value: CustomFieldValue }>> {\n\t\tif (!customFields || Object.keys(customFields).length === 0) return [];\n\t\tconst defs = await getBylineFieldDefs(this.db);\n\t\tconst bySlug = new Map(defs.map((d) => [d.slug, d]));\n\t\tconst writes: Array<{ field: BylineFieldDefinition; value: CustomFieldValue }> = [];\n\t\tfor (const [slug, raw] of Object.entries(customFields)) {\n\t\t\tconst field = bySlug.get(slug);\n\t\t\tif (!field) {\n\t\t\t\tthrow new EmDashValidationError(`Unknown byline custom field \"${slug}\"`, {\n\t\t\t\t\tslug,\n\t\t\t\t\tregistered: defs.map((d) => d.slug),\n\t\t\t\t});\n\t\t\t}\n\t\t\twrites.push({ field, value: coerceFieldValue(field, raw) });\n\t\t}\n\t\treturn writes;\n\t}\n\n\t/**\n\t * Write a validated custom-field list against a byline row inside the\n\t * caller's transaction. Per-field writes route to\n\t * `_emdash_byline_field_values` (translatable) or\n\t * `_emdash_byline_field_group_values` (group-shared); `null` clears.\n\t * Returns `true` when any group-shared row was touched so the caller\n\t * can invalidate the per-request cache post-commit.\n\t */\n\tprivate async applyCustomFieldWritesInTrx(\n\t\ttrx: Kysely<Database>,\n\t\tbylineId: string,\n\t\ttranslationGroup: string,\n\t\twrites: Array<{ field: BylineFieldDefinition; value: CustomFieldValue }>,\n\t\tnow: string,\n\t): Promise<boolean> {\n\t\tif (writes.length === 0) return false;\n\t\tlet touchedGroupShared = false;\n\t\tfor (const { field, value } of writes) {\n\t\t\tif (!field.translatable) touchedGroupShared = true;\n\t\t\tif (field.translatable) {\n\t\t\t\tif (value === null) {\n\t\t\t\t\tawait trx\n\t\t\t\t\t\t.deleteFrom(\"_emdash_byline_field_values\")\n\t\t\t\t\t\t.where(\"byline_id\", \"=\", bylineId)\n\t\t\t\t\t\t.where(\"field_id\", \"=\", field.id)\n\t\t\t\t\t\t.execute();\n\t\t\t\t} else {\n\t\t\t\t\tconst encoded = JSON.stringify(value);\n\t\t\t\t\tawait trx\n\t\t\t\t\t\t.insertInto(\"_emdash_byline_field_values\")\n\t\t\t\t\t\t.values({\n\t\t\t\t\t\t\tbyline_id: bylineId,\n\t\t\t\t\t\t\tfield_id: field.id,\n\t\t\t\t\t\t\tvalue: encoded,\n\t\t\t\t\t\t\tcreated_at: now,\n\t\t\t\t\t\t\tupdated_at: now,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.onConflict((oc) =>\n\t\t\t\t\t\t\toc.columns([\"byline_id\", \"field_id\"]).doUpdateSet({\n\t\t\t\t\t\t\t\tvalue: encoded,\n\t\t\t\t\t\t\t\tupdated_at: now,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.execute();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (value === null) {\n\t\t\t\t\tawait trx\n\t\t\t\t\t\t.deleteFrom(\"_emdash_byline_field_group_values\")\n\t\t\t\t\t\t.where(\"translation_group\", \"=\", translationGroup)\n\t\t\t\t\t\t.where(\"field_id\", \"=\", field.id)\n\t\t\t\t\t\t.execute();\n\t\t\t\t} else {\n\t\t\t\t\tconst encoded = JSON.stringify(value);\n\t\t\t\t\tawait trx\n\t\t\t\t\t\t.insertInto(\"_emdash_byline_field_group_values\")\n\t\t\t\t\t\t.values({\n\t\t\t\t\t\t\ttranslation_group: translationGroup,\n\t\t\t\t\t\t\tfield_id: field.id,\n\t\t\t\t\t\t\tvalue: encoded,\n\t\t\t\t\t\t\tcreated_at: now,\n\t\t\t\t\t\t\tupdated_at: now,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.onConflict((oc) =>\n\t\t\t\t\t\t\toc.columns([\"translation_group\", \"field_id\"]).doUpdateSet({\n\t\t\t\t\t\t\t\tvalue: encoded,\n\t\t\t\t\t\t\t\tupdated_at: now,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.execute();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn touchedGroupShared;\n\t}\n\n\tasync create(input: CreateBylineInput): Promise<BylineSummary> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\t// Validate customFields before opening the transaction so a bad\n\t\t// value surfaces as VALIDATION_ERROR without aborting an insert.\n\t\tconst customFieldWrites = await this.resolveCustomFieldWrites(input.customFields);\n\n\t\t// translationOf joins the source's group; otherwise mint a fresh\n\t\t// group = id (matches migration 040's backfill pattern).\n\t\tlet translationGroup: string = id;\n\t\tif (input.translationOf) {\n\t\t\tconst source = await this.findById(input.translationOf);\n\t\t\tif (!source) throw new Error(\"Source byline for translation not found\");\n\t\t\ttranslationGroup = source.translationGroup ?? source.id;\n\t\t}\n\n\t\t// Wrap insert + custom-field writes in one transaction so a\n\t\t// partial failure rolls both back on Node/PG. D1 still has its\n\t\t// own no-transactions limitation — recovery for that path lives\n\t\t// in `handleBylineCreate`.\n\t\tlet touchedGroupShared = false;\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait trx\n\t\t\t\t.insertInto(\"_emdash_bylines\")\n\t\t\t\t.values({\n\t\t\t\t\tid,\n\t\t\t\t\tslug: input.slug,\n\t\t\t\t\tdisplay_name: input.displayName,\n\t\t\t\t\tbio: input.bio ?? null,\n\t\t\t\t\tavatar_media_id: input.avatarMediaId ?? null,\n\t\t\t\t\twebsite_url: input.websiteUrl ?? null,\n\t\t\t\t\tuser_id: input.userId ?? null,\n\t\t\t\t\tis_guest: input.isGuest ? 1 : 0,\n\t\t\t\t\tcreated_at: now,\n\t\t\t\t\tupdated_at: now,\n\t\t\t\t\t// Omit `locale` so the DB DEFAULT (configured defaultLocale)\n\t\t\t\t\t// applies — matches TaxonomyRepository.create.\n\t\t\t\t\t...(input.locale !== undefined ? { locale: input.locale } : {}),\n\t\t\t\t\ttranslation_group: translationGroup,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\ttouchedGroupShared = await this.applyCustomFieldWritesInTrx(\n\t\t\t\ttrx,\n\t\t\t\tid,\n\t\t\t\ttranslationGroup,\n\t\t\t\tcustomFieldWrites,\n\t\t\t\tnow,\n\t\t\t);\n\t\t});\n\n\t\tif (touchedGroupShared) {\n\t\t\tclearRequestCacheEntry(`byline-field-group-values:${translationGroup}`);\n\t\t}\n\n\t\tconst byline = await this.findById(id);\n\t\tif (!byline) {\n\t\t\tthrow new Error(\"Failed to create byline\");\n\t\t}\n\t\treturn byline;\n\t}\n\n\tasync update(id: string, input: UpdateBylineInput): Promise<BylineSummary | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) return null;\n\n\t\t// Validate customFields before opening the transaction so a bad\n\t\t// value surfaces as VALIDATION_ERROR without aborting an update.\n\t\tconst customFieldWrites = await this.resolveCustomFieldWrites(input.customFields);\n\n\t\tconst now = new Date().toISOString();\n\t\tconst updates: Record<string, unknown> = { updated_at: now };\n\n\t\tif (input.slug !== undefined) updates.slug = input.slug;\n\t\tif (input.displayName !== undefined) updates.display_name = input.displayName;\n\t\tif (input.bio !== undefined) updates.bio = input.bio;\n\t\tif (input.avatarMediaId !== undefined) updates.avatar_media_id = input.avatarMediaId;\n\t\tif (input.websiteUrl !== undefined) updates.website_url = input.websiteUrl;\n\t\tif (input.userId !== undefined) updates.user_id = input.userId;\n\t\tif (input.isGuest !== undefined) updates.is_guest = input.isGuest ? 1 : 0;\n\n\t\tconst group = existing.translationGroup ?? existing.id;\n\t\t// Wrap row update + custom-field writes in one transaction so a\n\t\t// partial failure rolls both back on Node/PG. The post-commit\n\t\t// invalidation below clears the per-request cache that the\n\t\t// top-of-method `findById` populated for this group.\n\t\tlet touchedGroupShared = false;\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait trx.updateTable(\"_emdash_bylines\").set(updates).where(\"id\", \"=\", id).execute();\n\t\t\ttouchedGroupShared = await this.applyCustomFieldWritesInTrx(\n\t\t\t\ttrx,\n\t\t\t\tid,\n\t\t\t\tgroup,\n\t\t\t\tcustomFieldWrites,\n\t\t\t\tnow,\n\t\t\t);\n\t\t});\n\n\t\tif (touchedGroupShared) {\n\t\t\tclearRequestCacheEntry(`byline-field-group-values:${group}`);\n\t\t}\n\n\t\treturn await this.findById(id);\n\t}\n\n\t/**\n\t * Delete a byline row. When this row is the last sibling in its\n\t * translation group, also drops every junction row pointing at the group,\n\t * clears `primary_byline_id` references, and removes the byline's\n\t * non-translatable custom-field values. When other siblings remain in\n\t * the group, junctions, `primary_byline_id` pointers, and group-shared\n\t * custom-field values stay intact — the credit (and its shared metadata)\n\t * lives on at other locales.\n\t *\n\t * **Application-level cascade.** The byline domain has standardised on\n\t * app-level cascade rather than trusting FK ON DELETE CASCADE, partly\n\t * because migration 040 had to strip its own FK to support the\n\t * translation_group remap (#1021), and partly so cleanup doesn't\n\t * depend on `PRAGMA foreign_keys = ON` (set in production via\n\t * `connection.ts:60`, but easy to bypass in tests, scripts, and\n\t * one-off tools). Every byline-related deletion table is cleared\n\t * explicitly here:\n\t *\n\t * - `_emdash_byline_field_values` (per-byline translatable values) —\n\t * migration 041 declares FK ON DELETE CASCADE on `byline_id`; the\n\t * explicit DELETE removes the dependency on that pragma.\n\t * - `_emdash_content_bylines` — migration 040 dropped its FK.\n\t * - `ec_*.primary_byline_id` — never had an FK.\n\t * - `_emdash_byline_field_group_values` (translation-group-keyed) —\n\t * keyed by a text column with no FK to bylines, so app-level cleanup\n\t * is the only path.\n\t *\n\t * The FKs that remain (migration 041) serve as defense-in-depth.\n\t */\n\tasync delete(id: string): Promise<boolean> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) return false;\n\n\t\tconst group = existing.translationGroup ?? existing.id;\n\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\t// Per-row translatable custom-field values. Done BEFORE the\n\t\t\t// byline row delete so the application-level cleanup is\n\t\t\t// observable in the transaction log even if FK enforcement is\n\t\t\t// off; migration 041's FK ON DELETE CASCADE would catch any\n\t\t\t// row we miss, but the explicit DELETE is what the rest of\n\t\t\t// the byline domain expects to see.\n\t\t\tawait trx.deleteFrom(\"_emdash_byline_field_values\").where(\"byline_id\", \"=\", id).execute();\n\n\t\t\tawait trx.deleteFrom(\"_emdash_bylines\").where(\"id\", \"=\", id).execute();\n\n\t\t\t// Count remaining siblings in the translation group. If none\n\t\t\t// remain, purge dependent rows; otherwise leave them intact so\n\t\t\t// the credit still resolves at other locales.\n\t\t\tconst remaining = await trx\n\t\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t\t.select(({ fn }) => [fn.count<number>(\"id\").as(\"count\")])\n\t\t\t\t.where(\"translation_group\", \"=\", group)\n\t\t\t\t.executeTakeFirst();\n\t\t\tconst remainingCount = Number(remaining?.count ?? 0);\n\t\t\tif (remainingCount > 0) return;\n\n\t\t\t// Last sibling gone: cascade in application code.\n\t\t\tawait trx.deleteFrom(\"_emdash_content_bylines\").where(\"byline_id\", \"=\", group).execute();\n\n\t\t\t// Group-shared custom-field values are keyed by translation_group\n\t\t\t// (no FK to bylines), so they don't cascade with the byline row.\n\t\t\t// Clean them up explicitly so deleting the last sibling of an\n\t\t\t// identity doesn't leave orphan group values pointing at a\n\t\t\t// vanished translation group. Per-row translatable values\n\t\t\t// (`_emdash_byline_field_values` keyed by byline_id) already\n\t\t\t// cascaded when each sibling row was deleted, so no extra\n\t\t\t// cleanup is needed for that table.\n\t\t\tawait trx\n\t\t\t\t.deleteFrom(\"_emdash_byline_field_group_values\")\n\t\t\t\t.where(\"translation_group\", \"=\", group)\n\t\t\t\t.execute();\n\n\t\t\tconst tableNames = await listTablesLike(trx, \"ec_%\");\n\t\t\tfor (const tableName of tableNames) {\n\t\t\t\tvalidateIdentifier(tableName, \"content table\");\n\t\t\t\tawait sql`\n\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\tSET primary_byline_id = NULL\n\t\t\t\t\tWHERE primary_byline_id = ${group}\n\t\t\t\t`.execute(trx);\n\t\t\t}\n\t\t});\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Strict per-locale credit hydration. Joins `_emdash_content_bylines` to\n\t * `_emdash_bylines` on `translation_group = byline_id`, then filters to\n\t * the requested locale. Credits whose translation group lacks a row at\n\t * the requested locale are omitted — callers wanting fallback behaviour\n\t * apply it themselves. Mirrors `TaxonomyRepository.getTermsForEntry`.\n\t */\n\tasync getContentBylines(\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t\toptions?: { locale?: string },\n\t): Promise<ContentBylineCredit[]> {\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_content_bylines as cb\")\n\t\t\t.innerJoin(\"_emdash_bylines as b\", \"b.translation_group\", \"cb.byline_id\")\n\t\t\t.leftJoin(\"media as m\", \"m.id\", \"b.avatar_media_id\")\n\t\t\t.select([\n\t\t\t\t\"cb.sort_order as sort_order\",\n\t\t\t\t\"cb.role_label as role_label\",\n\t\t\t\t\"b.id as id\",\n\t\t\t\t\"b.slug as slug\",\n\t\t\t\t\"b.display_name as display_name\",\n\t\t\t\t\"b.bio as bio\",\n\t\t\t\t\"b.avatar_media_id as avatar_media_id\",\n\t\t\t\t\"m.storage_key as avatar_storage_key\",\n\t\t\t\t\"m.alt as avatar_alt\",\n\t\t\t\t\"b.website_url as website_url\",\n\t\t\t\t\"b.user_id as user_id\",\n\t\t\t\t\"b.is_guest as is_guest\",\n\t\t\t\t\"b.created_at as created_at\",\n\t\t\t\t\"b.updated_at as updated_at\",\n\t\t\t\t\"b.locale as locale\",\n\t\t\t\t\"b.translation_group as translation_group\",\n\t\t\t])\n\t\t\t.where(\"cb.collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"cb.content_id\", \"=\", contentId)\n\t\t\t.orderBy(\"cb.sort_order\", \"asc\");\n\t\tif (options?.locale !== undefined) query = query.where(\"b.locale\", \"=\", options.locale);\n\n\t\tconst rows = await query.execute();\n\t\t// Reconstruct byline rows to feed `withCustomFields`. The JOIN selects\n\t\t// the `BylineRow` columns under the `b.` alias plus the avatar media\n\t\t// columns from the `media` LEFT JOIN; carry both through so\n\t\t// `rowToByline` can populate `avatarStorageKey`/`avatarAlt` (otherwise\n\t\t// the join runs but its values are dropped here).\n\t\tconst bylineRows: BylineRowWithAvatar[] = rows.map((row) => ({\n\t\t\tid: row.id,\n\t\t\tslug: row.slug,\n\t\t\tdisplay_name: row.display_name,\n\t\t\tbio: row.bio,\n\t\t\tavatar_media_id: row.avatar_media_id,\n\t\t\tavatar_storage_key: row.avatar_storage_key,\n\t\t\tavatar_alt: row.avatar_alt,\n\t\t\twebsite_url: row.website_url,\n\t\t\tuser_id: row.user_id,\n\t\t\tis_guest: row.is_guest,\n\t\t\tcreated_at: row.created_at,\n\t\t\tupdated_at: row.updated_at,\n\t\t\tlocale: row.locale,\n\t\t\ttranslation_group: row.translation_group,\n\t\t}));\n\t\tconst hydrated = await this.withCustomFields(bylineRows);\n\t\treturn rows.map((row, i) => {\n\t\t\tconst byline = hydrated[i];\n\t\t\tif (!byline) {\n\t\t\t\t// Defensive: hydrated and rows are produced in lock-step;\n\t\t\t\t// this branch is unreachable unless `withCustomFields`\n\t\t\t\t// breaks its contract.\n\t\t\t\tthrow new Error(\"getContentBylines: hydration row count mismatch\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbyline,\n\t\t\t\tsortOrder: row.sort_order,\n\t\t\t\troleLabel: row.role_label,\n\t\t\t};\n\t\t});\n\t}\n\n\t/**\n\t * Does this entry have any explicit byline credits — at any locale?\n\t *\n\t * Used to disambiguate \"no credits exist\" (fall back to author-linked\n\t * byline) from \"credits exist but don't resolve at the requested locale\"\n\t * (strict per-locale model: render no byline). Without this check the\n\t * locale-strict hydration would silently turn a missing translation into\n\t * an author-inferred byline, contradicting editorial intent.\n\t */\n\tasync hasContentBylines(collectionSlug: string, contentId: string): Promise<boolean> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.limit(1)\n\t\t\t.executeTakeFirst();\n\t\treturn row !== undefined;\n\t}\n\n\t/**\n\t * Batch variant of `hasContentBylines`. Returns the set of content IDs\n\t * that have at least one junction row (locale-agnostic).\n\t */\n\tasync hasContentBylinesMany(collectionSlug: string, contentIds: string[]): Promise<Set<string>> {\n\t\tconst result = new Set<string>();\n\t\tif (contentIds.length === 0) return result;\n\n\t\tconst uniqueContentIds = [...new Set(contentIds)];\n\t\tfor (const chunk of chunks(uniqueContentIds, SQL_BATCH_SIZE)) {\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t\t\t.select(\"content_id\")\n\t\t\t\t.distinct()\n\t\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t\t.where(\"content_id\", \"in\", chunk)\n\t\t\t\t.execute();\n\t\t\tfor (const row of rows) result.add(row.content_id);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Batch variant of `getContentBylines`. Same strict-per-locale semantics\n\t * applied to the requested locale (single value, not per-entry).\n\t *\n\t * When callers need per-entry-locale filtering (e.g. a list endpoint\n\t * returning entries at mixed locales), they should group the input ids by\n\t * the entry's locale and call this method once per group.\n\t *\n\t * When the caller will issue multiple `getContentBylinesMany` calls in\n\t * one request (e.g. per locale bucket) and wants a *single* batched\n\t * customFields hydration over the union of returned bylines, pass\n\t * `skipHydration: true` on each call and finish with\n\t * `hydrateBylineCustomFields(allBylines)`. The returned bylines carry\n\t * `customFields = {}` until that hydration call runs — matching the\n\t * \"always populated\" invariant from AC #6 — so callers that forget to\n\t * hydrate get an empty map rather than `undefined`.\n\t */\n\tasync getContentBylinesMany(\n\t\tcollectionSlug: string,\n\t\tcontentIds: string[],\n\t\toptions?: { locale?: string; skipHydration?: boolean },\n\t): Promise<Map<string, ContentBylineCredit[]>> {\n\t\tconst result = new Map<string, ContentBylineCredit[]>();\n\t\tif (contentIds.length === 0) return result;\n\n\t\tconst uniqueContentIds = [...new Set(contentIds)];\n\t\tfor (const chunk of chunks(uniqueContentIds, SQL_BATCH_SIZE)) {\n\t\t\tlet query = this.db\n\t\t\t\t.selectFrom(\"_emdash_content_bylines as cb\")\n\t\t\t\t.innerJoin(\"_emdash_bylines as b\", \"b.translation_group\", \"cb.byline_id\")\n\t\t\t\t.leftJoin(\"media as m\", \"m.id\", \"b.avatar_media_id\")\n\t\t\t\t.select([\n\t\t\t\t\t\"cb.content_id as content_id\",\n\t\t\t\t\t\"cb.sort_order as sort_order\",\n\t\t\t\t\t\"cb.role_label as role_label\",\n\t\t\t\t\t\"b.id as id\",\n\t\t\t\t\t\"b.slug as slug\",\n\t\t\t\t\t\"b.display_name as display_name\",\n\t\t\t\t\t\"b.bio as bio\",\n\t\t\t\t\t\"b.avatar_media_id as avatar_media_id\",\n\t\t\t\t\t\"m.storage_key as avatar_storage_key\",\n\t\t\t\t\t\"m.alt as avatar_alt\",\n\t\t\t\t\t\"b.website_url as website_url\",\n\t\t\t\t\t\"b.user_id as user_id\",\n\t\t\t\t\t\"b.is_guest as is_guest\",\n\t\t\t\t\t\"b.created_at as created_at\",\n\t\t\t\t\t\"b.updated_at as updated_at\",\n\t\t\t\t\t\"b.locale as locale\",\n\t\t\t\t\t\"b.translation_group as translation_group\",\n\t\t\t\t])\n\t\t\t\t.where(\"cb.collection_slug\", \"=\", collectionSlug)\n\t\t\t\t.where(\"cb.content_id\", \"in\", chunk)\n\t\t\t\t.orderBy(\"cb.sort_order\", \"asc\");\n\t\t\tif (options?.locale !== undefined) query = query.where(\"b.locale\", \"=\", options.locale);\n\n\t\t\tconst rows = await query.execute();\n\t\t\t// Carry the avatar media columns from the LEFT JOIN through the\n\t\t\t// reshape so `rowToByline` can populate avatarStorageKey/avatarAlt.\n\t\t\tconst bylineRows: BylineRowWithAvatar[] = rows.map((row) => ({\n\t\t\t\tid: row.id,\n\t\t\t\tslug: row.slug,\n\t\t\t\tdisplay_name: row.display_name,\n\t\t\t\tbio: row.bio,\n\t\t\t\tavatar_media_id: row.avatar_media_id,\n\t\t\t\tavatar_storage_key: row.avatar_storage_key,\n\t\t\t\tavatar_alt: row.avatar_alt,\n\t\t\t\twebsite_url: row.website_url,\n\t\t\t\tuser_id: row.user_id,\n\t\t\t\tis_guest: row.is_guest,\n\t\t\t\tcreated_at: row.created_at,\n\t\t\t\tupdated_at: row.updated_at,\n\t\t\t\tlocale: row.locale,\n\t\t\t\ttranslation_group: row.translation_group,\n\t\t\t}));\n\n\t\t\t// When `skipHydration` is set, return BylineSummary objects with\n\t\t\t// `customFields = {}`. The caller is responsible for batching\n\t\t\t// `hydrateBylineCustomFields` across multiple\n\t\t\t// `getContentBylinesMany` calls. Otherwise hydrate per-call —\n\t\t\t// the historical behaviour for solo callers.\n\t\t\tlet bylines: BylineSummary[];\n\t\t\tif (options?.skipHydration === true) {\n\t\t\t\tbylines = bylineRows.map(rowToByline);\n\t\t\t\tfor (const b of bylines) b.customFields = {};\n\t\t\t} else {\n\t\t\t\tbylines = await this.withCustomFields(bylineRows);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < rows.length; i++) {\n\t\t\t\tconst row = rows[i];\n\t\t\t\tconst byline = bylines[i];\n\t\t\t\tif (!row || !byline) continue;\n\t\t\t\tconst contentId = row.content_id;\n\t\t\t\tconst credit: ContentBylineCredit = {\n\t\t\t\t\tbyline,\n\t\t\t\t\tsortOrder: row.sort_order,\n\t\t\t\t\troleLabel: row.role_label,\n\t\t\t\t};\n\t\t\t\tconst existing = result.get(contentId);\n\t\t\t\tif (existing) {\n\t\t\t\t\texisting.push(credit);\n\t\t\t\t} else {\n\t\t\t\t\tresult.set(contentId, [credit]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Batch-fetch byline profiles linked to user IDs in a single query.\n\t * Strict-locale variant of `findByUserId`.\n\t *\n\t * `skipHydration: true` returns bylines with `customFields = {}` so\n\t * callers issuing multiple `findByUserIds` calls in one request (e.g.\n\t * the per-locale-bucket author-fallback path in `getBylinesForEntries`)\n\t * can defer customFields hydration to a single batched\n\t * `hydrateBylineCustomFields` call across the union — keeping the\n\t * Phase 3 query-count envelope at \"+1 group-shared query per\n\t * hydration pass\" even when buckets fetch disjoint author bylines.\n\t */\n\tasync findByUserIds(\n\t\tuserIds: string[],\n\t\toptions?: { locale?: string; skipHydration?: boolean },\n\t): Promise<Map<string, BylineSummary>> {\n\t\tconst result = new Map<string, BylineSummary>();\n\t\tif (userIds.length === 0) return result;\n\n\t\tfor (const chunk of chunks(userIds, SQL_BATCH_SIZE)) {\n\t\t\t// LEFT JOIN media so author-inferred bylines (the fallback path in\n\t\t\t// `getBylinesForEntries`) carry the same render-ready avatar storage\n\t\t\t// key as explicitly-credited bylines do.\n\t\t\tlet query = this.db\n\t\t\t\t.selectFrom(\"_emdash_bylines as b\")\n\t\t\t\t.leftJoin(\"media as m\", \"m.id\", \"b.avatar_media_id\")\n\t\t\t\t.select([\n\t\t\t\t\t\"b.id as id\",\n\t\t\t\t\t\"b.slug as slug\",\n\t\t\t\t\t\"b.display_name as display_name\",\n\t\t\t\t\t\"b.bio as bio\",\n\t\t\t\t\t\"b.avatar_media_id as avatar_media_id\",\n\t\t\t\t\t\"m.storage_key as avatar_storage_key\",\n\t\t\t\t\t\"m.alt as avatar_alt\",\n\t\t\t\t\t\"b.website_url as website_url\",\n\t\t\t\t\t\"b.user_id as user_id\",\n\t\t\t\t\t\"b.is_guest as is_guest\",\n\t\t\t\t\t\"b.created_at as created_at\",\n\t\t\t\t\t\"b.updated_at as updated_at\",\n\t\t\t\t\t\"b.locale as locale\",\n\t\t\t\t\t\"b.translation_group as translation_group\",\n\t\t\t\t])\n\t\t\t\t.where(\"b.user_id\", \"in\", chunk);\n\t\t\tif (options?.locale !== undefined) query = query.where(\"b.locale\", \"=\", options.locale);\n\n\t\t\tconst rows = await query.execute();\n\t\t\tlet bylines: BylineSummary[];\n\t\t\tif (options?.skipHydration === true) {\n\t\t\t\tbylines = rows.map(rowToByline);\n\t\t\t\tfor (const b of bylines) b.customFields = {};\n\t\t\t} else {\n\t\t\t\tbylines = await this.withCustomFields(rows);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < rows.length; i++) {\n\t\t\t\tconst row = rows[i];\n\t\t\t\tconst summary = bylines[i];\n\t\t\t\tif (!row || !summary || !row.user_id) continue;\n\t\t\t\tresult.set(row.user_id, summary);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Clone every junction row from `sourceContentId` to `targetContentId`,\n\t * preserving `sort_order` and `role_label`. Used by the content\n\t * translation flow: a newly created translation inherits the source's\n\t * byline credits at the storage level. Because the junction stores\n\t * `translation_group` (not a row id), the copy is locale-agnostic — the\n\t * credits resolve to whichever locale variants of each byline exist when\n\t * the translated entry is hydrated.\n\t *\n\t * No-op when the source has no credits. Skips when the target already\n\t * has credits (idempotent for re-runs).\n\t */\n\tasync copyContentBylines(\n\t\tcollection: string,\n\t\tsourceContentId: string,\n\t\ttargetContentId: string,\n\t): Promise<void> {\n\t\tvalidateIdentifier(collection, \"collection slug\");\n\t\tconst tableName = `ec_${collection}`;\n\t\tvalidateIdentifier(tableName, \"content table\");\n\n\t\t// Like `setContentBylines`, this method is expected to be called\n\t\t// within a transaction context (content handlers wrap in\n\t\t// withTransaction). All operations use `this.db` directly so an\n\t\t// outer transaction can serialise the copy alongside the create.\n\t\tconst existing = await this.db\n\t\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"collection_slug\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", targetContentId)\n\t\t\t.executeTakeFirst();\n\t\tif (existing) return;\n\n\t\tconst sourceRows = await this.db\n\t\t\t.selectFrom(\"_emdash_content_bylines\")\n\t\t\t.select([\"byline_id\", \"sort_order\", \"role_label\"])\n\t\t\t.where(\"collection_slug\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", sourceContentId)\n\t\t\t.orderBy(\"sort_order\", \"asc\")\n\t\t\t.execute();\n\t\tif (sourceRows.length === 0) return;\n\n\t\tconst now = new Date().toISOString();\n\t\tawait this.db\n\t\t\t.insertInto(\"_emdash_content_bylines\")\n\t\t\t.values(\n\t\t\t\tsourceRows.map((row) => ({\n\t\t\t\t\tid: ulid(),\n\t\t\t\t\tcollection_slug: collection,\n\t\t\t\t\tcontent_id: targetContentId,\n\t\t\t\t\tbyline_id: row.byline_id,\n\t\t\t\t\tsort_order: row.sort_order,\n\t\t\t\t\trole_label: row.role_label,\n\t\t\t\t\tcreated_at: now,\n\t\t\t\t})),\n\t\t\t)\n\t\t\t.execute();\n\n\t\t// Mirror primary_byline_id from source so the cached pointer on the\n\t\t// target row matches the junction state we just wrote.\n\t\tconst firstByline = sourceRows[0]?.byline_id ?? null;\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET primary_byline_id = ${firstByline}\n\t\t\tWHERE id = ${targetContentId}\n\t\t`.execute(this.db);\n\t}\n\n\t/**\n\t * Replace the set of byline credits on a content entry. Accepts row ids\n\t * at the wire (consistent with how the admin sends them), translates\n\t * each to its `translation_group` on write, and stores the group in\n\t * `_emdash_content_bylines.byline_id` and `ec_*.primary_byline_id`.\n\t *\n\t * The returned credits are hydrated with strict-locale matching at the\n\t * locale of the rows the caller supplied (i.e. the locale of the byline\n\t * each `bylineId` resolves to) — adequate for the autosave round-trip,\n\t * which then re-hydrates the entry against its own locale separately.\n\t */\n\tasync setContentBylines(\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t\tinputBylines: ContentBylineInput[],\n\t): Promise<ContentBylineCredit[]> {\n\t\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\t\tconst tableName = `ec_${collectionSlug}`;\n\t\tvalidateIdentifier(tableName, \"content table\");\n\n\t\t// Resolve each wire row id to its translation_group up front so we\n\t\t// can (a) validate the rows exist and (b) dedupe by the value that\n\t\t// actually lands in the junction. Deduping by wire row id BEFORE\n\t\t// resolving would let two locale siblings of the same byline slip\n\t\t// through and trigger a UNIQUE(collection, content, byline_id)\n\t\t// failure at insert time. A single SELECT keeps this O(1) DB\n\t\t// calls regardless of how many credits are being set.\n\t\tconst idToGroup = new Map<string, string>();\n\t\tif (inputBylines.length > 0) {\n\t\t\tconst wireIds = [...new Set(inputBylines.map((item) => item.bylineId))];\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t\t.select([\"id\", \"translation_group\"])\n\t\t\t\t.where(\"id\", \"in\", wireIds)\n\t\t\t\t.execute();\n\t\t\tif (rows.length !== wireIds.length) {\n\t\t\t\tthrow new Error(\"One or more byline IDs do not exist\");\n\t\t\t}\n\t\t\tfor (const row of rows) {\n\t\t\t\tidToGroup.set(row.id, row.translation_group ?? row.id);\n\t\t\t}\n\t\t}\n\n\t\t// Dedupe by translation_group. Preserves the order of first\n\t\t// occurrence so the editor's intent (which sibling appears first)\n\t\t// is honored. `roleLabel` follows the first occurrence too.\n\t\tconst seenGroups = new Set<string>();\n\t\tconst bylines: Array<ContentBylineInput & { group: string }> = [];\n\t\tfor (const item of inputBylines) {\n\t\t\tconst group = idToGroup.get(item.bylineId);\n\t\t\tif (!group) {\n\t\t\t\tthrow new Error(`Missing translation_group for byline ${item.bylineId}`);\n\t\t\t}\n\t\t\tif (seenGroups.has(group)) continue;\n\t\t\tseenGroups.add(group);\n\t\t\tbylines.push({ ...item, group });\n\t\t}\n\n\t\t// This method is expected to be called within a transaction context\n\t\t// (content handlers wrap in withTransaction, seed applies sequentially).\n\t\t// All operations use this.db directly -- callers are responsible for\n\t\t// wrapping in a transaction when atomicity is required.\n\t\tawait this.db\n\t\t\t.deleteFrom(\"_emdash_content_bylines\")\n\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.execute();\n\n\t\tfor (let i = 0; i < bylines.length; i++) {\n\t\t\tconst item = bylines[i];\n\t\t\tif (!item) continue;\n\t\t\tawait this.db\n\t\t\t\t.insertInto(\"_emdash_content_bylines\")\n\t\t\t\t.values({\n\t\t\t\t\tid: ulid(),\n\t\t\t\t\tcollection_slug: collectionSlug,\n\t\t\t\t\tcontent_id: contentId,\n\t\t\t\t\tbyline_id: item.group,\n\t\t\t\t\tsort_order: i,\n\t\t\t\t\trole_label: item.roleLabel ?? null,\n\t\t\t\t\tcreated_at: new Date().toISOString(),\n\t\t\t\t})\n\t\t\t\t.execute();\n\t\t}\n\n\t\tconst primaryGroup = bylines[0]?.group ?? null;\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET primary_byline_id = ${primaryGroup}\n\t\t\tWHERE id = ${contentId}\n\t\t`.execute(this.db);\n\n\t\treturn await this.getContentBylines(collectionSlug, contentId);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"byline-fields-DbibsvTl.d.mts","names":[],"sources":["../src/api/schemas/common.ts","../src/api/schemas/content.ts","../src/api/schemas/media.ts","../src/api/schemas/schema.ts","../src/api/schemas/comments.ts","../src/api/schemas/auth.ts","../src/api/schemas/menus.ts","../src/api/schemas/taxonomies.ts","../src/api/schemas/sections.ts","../src/api/schemas/settings.ts","../src/api/schemas/search.ts","../src/api/schemas/import.ts","../src/api/schemas/setup.ts","../src/api/schemas/users.ts","../src/api/schemas/widgets.ts","../src/api/schemas/redirects.ts","../src/api/schemas/bylines.ts","../src/api/schemas/byline-fields.ts"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"comment-sqQxNpN3.mjs","names":[],"sources":["../src/database/repositories/comment.ts"],"sourcesContent":["import { sql, type ExpressionBuilder, type Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database } from \"../types.js\";\nimport { encodeCursor, decodeCursor, type FindManyResult } from \"./types.js\";\n\n/** Matches LIKE wildcard characters and the escape character itself */\nconst LIKE_ESCAPE_RE = /[%_\\\\]/g;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type CommentStatus = \"pending\" | \"approved\" | \"spam\" | \"trash\";\n\nexport interface Comment {\n\tid: string;\n\tcollection: string;\n\tcontentId: string;\n\tparentId: string | null;\n\tauthorName: string;\n\tauthorEmail: string;\n\tauthorUserId: string | null;\n\tbody: string;\n\tstatus: CommentStatus;\n\tipHash: string | null;\n\tuserAgent: string | null;\n\tmoderationMetadata: Record<string, unknown> | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\n/** Public-facing comment shape — no private fields */\nexport interface PublicComment {\n\tid: string;\n\tparentId: string | null;\n\tauthorName: string;\n\tisRegisteredUser: boolean;\n\tbody: string;\n\tcreatedAt: string;\n\treplies?: PublicComment[];\n}\n\nexport interface CreateCommentInput {\n\tcollection: string;\n\tcontentId: string;\n\tparentId?: string | null;\n\tauthorName: string;\n\tauthorEmail: string;\n\tauthorUserId?: string | null;\n\tbody: string;\n\tstatus?: CommentStatus;\n\tipHash?: string | null;\n\tuserAgent?: string | null;\n\tmoderationMetadata?: Record<string, unknown> | null;\n}\n\nexport interface CommentFindOptions {\n\tstatus?: CommentStatus;\n\tcollection?: string;\n\tsearch?: string;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Repository\n// ---------------------------------------------------------------------------\n\nexport class CommentRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t/**\n\t * Create a new comment\n\t */\n\tasync create(input: CreateCommentInput): Promise<Comment> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tawait this.db\n\t\t\t.insertInto(\"_emdash_comments\")\n\t\t\t.values({\n\t\t\t\tid,\n\t\t\t\tcollection: input.collection,\n\t\t\t\tcontent_id: input.contentId,\n\t\t\t\tparent_id: input.parentId ?? null,\n\t\t\t\tauthor_name: input.authorName,\n\t\t\t\tauthor_email: input.authorEmail,\n\t\t\t\tauthor_user_id: input.authorUserId ?? null,\n\t\t\t\tbody: input.body,\n\t\t\t\tstatus: input.status ?? \"pending\",\n\t\t\t\tip_hash: input.ipHash ?? null,\n\t\t\t\tuser_agent: input.userAgent ?? null,\n\t\t\t\tmoderation_metadata: input.moderationMetadata\n\t\t\t\t\t? JSON.stringify(input.moderationMetadata)\n\t\t\t\t\t: null,\n\t\t\t\tcreated_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.execute();\n\n\t\tconst comment = await this.findById(id);\n\t\tif (!comment) {\n\t\t\tthrow new Error(\"Failed to create comment\");\n\t\t}\n\t\treturn comment;\n\t}\n\n\t/**\n\t * Find comment by ID\n\t */\n\tasync findById(id: string): Promise<Comment | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToComment(row) : null;\n\t}\n\n\t/**\n\t * Find comments for a content item with optional status filter.\n\t * Results are ordered by created_at ASC (oldest first) for display.\n\t */\n\tasync findByContent(\n\t\tcollection: string,\n\t\tcontentId: string,\n\t\toptions: { status?: CommentStatus; limit?: number; cursor?: string } = {},\n\t): Promise<FindManyResult<Comment>> {\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.selectAll()\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId);\n\n\t\tif (options.status) {\n\t\t\tquery = query.where(\"status\", \"=\", options.status);\n\t\t}\n\n\t\t// Cursor pagination (ascending by created_at)\n\t\tif (options.cursor) {\n\t\t\tconst decoded = decodeCursor(options.cursor);\n\t\t\tquery = query.where((eb: ExpressionBuilder<Database, \"_emdash_comments\">) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \">\", decoded.orderValue),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", decoded.orderValue), eb(\"id\", \">\", decoded.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tquery = query\n\t\t\t.orderBy(\"created_at\", \"asc\")\n\t\t\t.orderBy(\"id\", \"asc\")\n\t\t\t.limit(limit + 1);\n\n\t\tconst rows = await query.execute();\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit).map((r) => this.rowToComment(r));\n\n\t\tconst result: FindManyResult<Comment> = { items };\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst last = items.at(-1)!;\n\t\t\tresult.nextCursor = encodeCursor(last.createdAt, last.id);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Find comments by status (moderation inbox).\n\t * Results are ordered by created_at DESC (newest first).\n\t */\n\tasync findByStatus(\n\t\tstatus: CommentStatus,\n\t\toptions: { collection?: string; search?: string; limit?: number; cursor?: string } = {},\n\t): Promise<FindManyResult<Comment>> {\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\tlet query = this.db.selectFrom(\"_emdash_comments\").selectAll().where(\"status\", \"=\", status);\n\n\t\tif (options.collection) {\n\t\t\tquery = query.where(\"collection\", \"=\", options.collection);\n\t\t}\n\n\t\tif (options.search) {\n\t\t\t// Escape LIKE wildcards to prevent them acting as SQL pattern characters\n\t\t\tconst escaped = options.search.replace(LIKE_ESCAPE_RE, (ch) => `\\\\${ch}`);\n\t\t\tconst term = `%${escaped}%`;\n\t\t\tquery = query.where((eb: ExpressionBuilder<Database, \"_emdash_comments\">) =>\n\t\t\t\teb.or([\n\t\t\t\t\tsql<boolean>`author_name LIKE ${term} ESCAPE '\\\\'`,\n\t\t\t\t\tsql<boolean>`author_email LIKE ${term} ESCAPE '\\\\'`,\n\t\t\t\t\tsql<boolean>`body LIKE ${term} ESCAPE '\\\\'`,\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\t// Cursor pagination (descending by created_at)\n\t\tif (options.cursor) {\n\t\t\tconst decoded = decodeCursor(options.cursor);\n\t\t\tquery = query.where((eb: ExpressionBuilder<Database, \"_emdash_comments\">) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", decoded.orderValue),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", decoded.orderValue), eb(\"id\", \"<\", decoded.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tquery = query\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\tconst rows = await query.execute();\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit).map((r) => this.rowToComment(r));\n\n\t\tconst result: FindManyResult<Comment> = { items };\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst last = items.at(-1)!;\n\t\t\tresult.nextCursor = encodeCursor(last.createdAt, last.id);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Update comment status\n\t */\n\tasync updateStatus(id: string, status: CommentStatus): Promise<Comment | null> {\n\t\tconst now = new Date().toISOString();\n\n\t\tawait this.db\n\t\t\t.updateTable(\"_emdash_comments\")\n\t\t\t.set({ status, updated_at: now })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.execute();\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Bulk update comment statuses\n\t */\n\tasync bulkUpdateStatus(ids: string[], status: CommentStatus): Promise<number> {\n\t\tif (ids.length === 0) return 0;\n\n\t\tconst now = new Date().toISOString();\n\n\t\tconst result = await this.db\n\t\t\t.updateTable(\"_emdash_comments\")\n\t\t\t.set({ status, updated_at: now })\n\t\t\t.where(\"id\", \"in\", ids)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result.numUpdatedRows ?? 0);\n\t}\n\n\t/**\n\t * Hard-delete a single comment. Replies cascade via FK.\n\t */\n\tasync delete(id: string): Promise<boolean> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_comments\")\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\n\t\treturn (result.numDeletedRows ?? 0) > 0;\n\t}\n\n\t/**\n\t * Bulk hard-delete comments\n\t */\n\tasync bulkDelete(ids: string[]): Promise<number> {\n\t\tif (ids.length === 0) return 0;\n\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_comments\")\n\t\t\t.where(\"id\", \"in\", ids)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\t/**\n\t * Delete all comments for a content item (cascade on content deletion)\n\t */\n\tasync deleteByContent(collection: string, contentId: string): Promise<number> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"_emdash_comments\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\t/**\n\t * Count comments for a content item, optionally filtered by status\n\t */\n\tasync countByContent(\n\t\tcollection: string,\n\t\tcontentId: string,\n\t\tstatus?: CommentStatus,\n\t): Promise<number> {\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId);\n\n\t\tif (status) {\n\t\t\tquery = query.where(\"status\", \"=\", status);\n\t\t}\n\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result?.count ?? 0);\n\t}\n\n\t/**\n\t * Count comments grouped by status (for inbox badges)\n\t *\n\t * Uses four parallel COUNT queries with WHERE filters to leverage partial indexes\n\t * (idx_comments_pending, idx_comments_approved, idx_comments_spam, idx_comments_trash)\n\t * instead of a full table GROUP BY scan.\n\t */\n\tasync countByStatus(): Promise<Record<CommentStatus, number>> {\n\t\t// Execute four parallel COUNT queries, each using its partial index\n\t\tconst [pending, approved, spam, trash] = await Promise.all([\n\t\t\tthis.db\n\t\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t\t.where(\"status\", \"=\", \"pending\")\n\t\t\t\t.executeTakeFirst(),\n\t\t\tthis.db\n\t\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t\t.where(\"status\", \"=\", \"approved\")\n\t\t\t\t.executeTakeFirst(),\n\t\t\tthis.db\n\t\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t\t.where(\"status\", \"=\", \"spam\")\n\t\t\t\t.executeTakeFirst(),\n\t\t\tthis.db\n\t\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t\t.where(\"status\", \"=\", \"trash\")\n\t\t\t\t.executeTakeFirst(),\n\t\t]);\n\n\t\treturn {\n\t\t\tpending: Number(pending?.count ?? 0),\n\t\t\tapproved: Number(approved?.count ?? 0),\n\t\t\tspam: Number(spam?.count ?? 0),\n\t\t\ttrash: Number(trash?.count ?? 0),\n\t\t};\n\t}\n\n\t/**\n\t * Count approved comments from a given email address.\n\t * Used for \"first time commenter\" moderation logic.\n\t */\n\tasync countApprovedByEmail(email: string): Promise<number> {\n\t\tconst result = await this.db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t.where(\"author_email\", \"=\", email)\n\t\t\t.where(\"status\", \"=\", \"approved\")\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result?.count ?? 0);\n\t}\n\n\t/**\n\t * Update the moderation metadata JSON on a comment\n\t */\n\tasync updateModerationMetadata(id: string, metadata: Record<string, unknown>): Promise<void> {\n\t\tawait this.db\n\t\t\t.updateTable(\"_emdash_comments\")\n\t\t\t.set({ moderation_metadata: JSON.stringify(metadata) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.execute();\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// Helpers\n\t// ---------------------------------------------------------------------------\n\n\t/**\n\t * Assemble a flat list of comments into a threaded structure (1-level nesting)\n\t */\n\tstatic assembleThreads(comments: Comment[]): Comment[] {\n\t\tconst roots: Comment[] = [];\n\t\tconst childrenMap = new Map<string, Comment[]>();\n\n\t\tfor (const comment of comments) {\n\t\t\tif (comment.parentId) {\n\t\t\t\tconst siblings = childrenMap.get(comment.parentId) ?? [];\n\t\t\t\tsiblings.push(comment);\n\t\t\t\tchildrenMap.set(comment.parentId, siblings);\n\t\t\t} else {\n\t\t\t\troots.push(comment);\n\t\t\t}\n\t\t}\n\n\t\t// Attach children as a non-standard property — callers map to PublicComment.replies\n\t\treturn roots.map((root) => ({\n\t\t\t...root,\n\t\t\t_replies: childrenMap.get(root.id) ?? [],\n\t\t})) as Comment[];\n\t}\n\n\t/**\n\t * Convert a Comment to its public-facing shape\n\t */\n\tstatic toPublicComment(comment: Comment & { _replies?: Comment[] }): PublicComment {\n\t\tconst pub: PublicComment = {\n\t\t\tid: comment.id,\n\t\t\tparentId: comment.parentId,\n\t\t\tauthorName: comment.authorName,\n\t\t\tisRegisteredUser: comment.authorUserId !== null,\n\t\t\tbody: comment.body,\n\t\t\tcreatedAt: comment.createdAt,\n\t\t};\n\n\t\tif (comment._replies && comment._replies.length > 0) {\n\t\t\tpub.replies = comment._replies.map((r) => CommentRepository.toPublicComment(r));\n\t\t}\n\n\t\treturn pub;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- selectAll returns runtime row\n\tprivate rowToComment(row: any): Comment {\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\tcollection: row.collection,\n\t\t\tcontentId: row.content_id,\n\t\t\tparentId: row.parent_id,\n\t\t\tauthorName: row.author_name,\n\t\t\tauthorEmail: row.author_email,\n\t\t\tauthorUserId: row.author_user_id,\n\t\t\tbody: row.body,\n\t\t\tstatus: row.status as CommentStatus,\n\t\t\tipHash: row.ip_hash,\n\t\t\tuserAgent: row.user_agent,\n\t\t\tmoderationMetadata: row.moderation_metadata ? safeJsonParse(row.moderation_metadata) : null,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tupdatedAt: row.updated_at,\n\t\t};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Module helpers\n// ---------------------------------------------------------------------------\n\nfunction safeJsonParse(value: string): Record<string, unknown> | null {\n\ttry {\n\t\treturn JSON.parse(value) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"content-BIlVx-RX.mjs","names":[],"sources":["../src/database/repositories/revision.ts","../src/database/repositories/content.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\nimport { monotonicFactory } from \"ulidx\";\n\nimport type { Database, RevisionTable } from \"../types.js\";\n\nconst monotonic = monotonicFactory();\n\nexport interface Revision {\n\tid: string;\n\tcollection: string;\n\tentryId: string;\n\tdata: Record<string, unknown>;\n\tauthorId: string | null;\n\tcreatedAt: string;\n}\n\nexport interface CreateRevisionInput {\n\tcollection: string;\n\tentryId: string;\n\tdata: Record<string, unknown>;\n\tauthorId?: string;\n}\n\n/**\n * Revision repository for version history\n *\n * Each revision stores a JSON snapshot of the content at a point in time.\n * Used when collection has `supports: [\"revisions\"]` enabled.\n */\nexport class RevisionRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t/**\n\t * Create a new revision\n\t */\n\tasync create(input: CreateRevisionInput): Promise<Revision> {\n\t\tconst id = monotonic();\n\n\t\tconst row: Omit<RevisionTable, \"created_at\"> = {\n\t\t\tid,\n\t\t\tcollection: input.collection,\n\t\t\tentry_id: input.entryId,\n\t\t\tdata: JSON.stringify(input.data),\n\t\t\tauthor_id: input.authorId ?? null,\n\t\t};\n\n\t\tawait this.db.insertInto(\"revisions\").values(row).execute();\n\n\t\tconst revision = await this.findById(id);\n\t\tif (!revision) {\n\t\t\tthrow new Error(\"Failed to create revision\");\n\t\t}\n\t\treturn revision;\n\t}\n\n\t/**\n\t * Find revision by ID\n\t */\n\tasync findById(id: string): Promise<Revision | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"revisions\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToRevision(row) : null;\n\t}\n\n\t/**\n\t * Get all revisions for an entry (newest first)\n\t *\n\t * Orders by monotonic ULID (descending). The monotonic factory\n\t * guarantees strictly increasing IDs even within the same millisecond.\n\t */\n\tasync findByEntry(\n\t\tcollection: string,\n\t\tentryId: string,\n\t\toptions: { limit?: number } = {},\n\t): Promise<Revision[]> {\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"revisions\")\n\t\t\t.selectAll()\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.orderBy(\"id\", \"desc\");\n\n\t\tif (options.limit) {\n\t\t\tquery = query.limit(options.limit);\n\t\t}\n\n\t\tconst rows = await query.execute();\n\t\treturn rows.map((row) => this.rowToRevision(row));\n\t}\n\n\t/**\n\t * Get the most recent revision for an entry\n\t */\n\tasync findLatest(collection: string, entryId: string): Promise<Revision | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"revisions\")\n\t\t\t.selectAll()\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(1)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToRevision(row) : null;\n\t}\n\n\t/**\n\t * Count revisions for an entry\n\t */\n\tasync countByEntry(collection: string, entryId: string): Promise<number> {\n\t\tconst result = await this.db\n\t\t\t.selectFrom(\"revisions\")\n\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result?.count || 0);\n\t}\n\n\t/**\n\t * Delete all revisions for an entry (use when entry is deleted)\n\t */\n\tasync deleteByEntry(collection: string, entryId: string): Promise<number> {\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"revisions\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\t/**\n\t * Delete old revisions, keeping the most recent N\n\t */\n\tasync pruneOldRevisions(collection: string, entryId: string, keepCount: number): Promise<number> {\n\t\t// Get IDs of revisions to keep\n\t\tconst keep = await this.db\n\t\t\t.selectFrom(\"revisions\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\") // ULID tiebreaker\n\t\t\t.limit(keepCount)\n\t\t\t.execute();\n\n\t\tconst keepIds = keep.map((r) => r.id);\n\n\t\tif (keepIds.length === 0) return 0;\n\n\t\t// Delete everything else for this entry\n\t\tconst result = await this.db\n\t\t\t.deleteFrom(\"revisions\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"entry_id\", \"=\", entryId)\n\t\t\t.where(\"id\", \"not in\", keepIds)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result.numDeletedRows ?? 0);\n\t}\n\n\t/**\n\t * Update revision data in place\n\t * Used for autosave to avoid creating many small revisions.\n\t */\n\tasync updateData(id: string, data: Record<string, unknown>): Promise<void> {\n\t\tawait this.db\n\t\t\t.updateTable(\"revisions\")\n\t\t\t.set({ data: JSON.stringify(data) })\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.execute();\n\t}\n\n\t/**\n\t * Convert database row to Revision object\n\t */\n\tprivate rowToRevision(row: {\n\t\tid: string;\n\t\tcollection: string;\n\t\tentry_id: string;\n\t\tdata: string;\n\t\tauthor_id: string | null;\n\t\tcreated_at: string;\n\t}): Revision {\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\tcollection: row.collection,\n\t\t\tentryId: row.entry_id,\n\t\t\tdata: JSON.parse(row.data),\n\t\t\tauthorId: row.author_id,\n\t\t\tcreatedAt: row.created_at,\n\t\t};\n\t}\n}\n","import { sql, type Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { slugify } from \"../../utils/slugify.js\";\nimport type { Database } from \"../types.js\";\nimport { validateIdentifier } from \"../validate.js\";\nimport { RevisionRepository } from \"./revision.js\";\nimport type {\n\tCreateContentInput,\n\tUpdateContentInput,\n\tFindManyOptions,\n\tFindManyResult,\n\tContentItem,\n\tContentDateField,\n} from \"./types.js\";\nimport {\n\tEmDashValidationError,\n\tScheduledNotDueError,\n\tencodeCursor,\n\tdecodeCursor,\n} from \"./types.js\";\n\n// Regex pattern for ULID validation\nconst ULID_PATTERN = /^[0-9A-Z]{26}$/;\n\n// LIKE wildcards that must be escaped so user search input is matched literally.\nconst LIKE_WILDCARD_RE = /[\\\\%_]/g;\n\n/**\n * Whitelist mapping a public date-filter field to its physical column. Keeping\n * this separate from `mapOrderField` makes the filterable set explicit and\n * prevents filtering on arbitrary columns.\n */\nconst DATE_FILTER_COLUMNS: Record<ContentDateField, \"created_at\" | \"updated_at\" | \"published_at\"> =\n\t{\n\t\tcreatedAt: \"created_at\",\n\t\tupdatedAt: \"updated_at\",\n\t\tpublishedAt: \"published_at\",\n\t};\n\n/**\n * System columns that exist in every ec_* table\n */\nconst SYSTEM_COLUMNS = new Set([\n\t\"id\",\n\t\"slug\",\n\t\"status\",\n\t\"author_id\",\n\t\"primary_byline_id\",\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]);\n\n/**\n * Get the table name for a collection type\n */\nfunction getTableName(type: string): string {\n\tvalidateIdentifier(type, \"collection type\");\n\treturn `ec_${type}`;\n}\n\n/**\n * Serialize a value for database storage\n * Objects/arrays are JSON-stringified\n * Booleans are converted to 0/1 for SQLite\n */\nfunction serializeValue(value: unknown): unknown {\n\tif (value === null || value === undefined) {\n\t\treturn null;\n\t}\n\tif (typeof value === \"boolean\") {\n\t\treturn value ? 1 : 0;\n\t}\n\tif (typeof value === \"object\") {\n\t\treturn JSON.stringify(value);\n\t}\n\treturn value;\n}\n\n/**\n * Deserialize a value from database storage\n * Attempts to parse JSON strings that look like objects/arrays\n */\nfunction deserializeValue(value: unknown): unknown {\n\tif (typeof value === \"string\") {\n\t\t// Try to parse if it looks like JSON\n\t\tif (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value);\n\t\t\t} catch {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n}\n\n/** Pattern for escaping special regex characters */\nconst REGEX_ESCAPE_PATTERN = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Escape special regex characters in a string for use in `new RegExp()`\n */\nfunction escapeRegExp(s: string): string {\n\treturn s.replace(REGEX_ESCAPE_PATTERN, \"\\\\$&\");\n}\n\n/**\n * Repository for content CRUD operations\n *\n * Content is stored in per-collection tables (ec_posts, ec_pages, etc.)\n * Each field becomes a real column in the table.\n */\nexport class ContentRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t/**\n\t * Create a new content item\n\t */\n\tasync create(input: CreateContentInput): Promise<ContentItem> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tconst {\n\t\t\ttype,\n\t\t\tslug,\n\t\t\tdata,\n\t\t\tstatus = \"draft\",\n\t\t\tauthorId,\n\t\t\tprimaryBylineId,\n\t\t\tlocale,\n\t\t\ttranslationOf,\n\t\t\tpublishedAt,\n\t\t\tcreatedAt,\n\t\t} = input;\n\n\t\t// Validate required fields\n\t\tif (!type) {\n\t\t\tthrow new EmDashValidationError(\"Content type is required\");\n\t\t}\n\n\t\tconst tableName = getTableName(type);\n\n\t\t// Resolve translation_group: if translationOf is set, look up the source item's group\n\t\tlet translationGroup: string = id; // default: self-reference\n\t\tif (translationOf) {\n\t\t\tconst source = await this.findById(type, translationOf);\n\t\t\tif (!source) {\n\t\t\t\tthrow new EmDashValidationError(\"Translation source content not found\");\n\t\t\t}\n\t\t\ttranslationGroup = source.translationGroup || source.id;\n\t\t}\n\n\t\t// Build column names and values\n\t\tconst columns: string[] = [\n\t\t\t\"id\",\n\t\t\t\"slug\",\n\t\t\t\"status\",\n\t\t\t\"author_id\",\n\t\t\t\"primary_byline_id\",\n\t\t\t\"created_at\",\n\t\t\t\"updated_at\",\n\t\t\t\"published_at\",\n\t\t\t\"version\",\n\t\t\t\"locale\",\n\t\t\t\"translation_group\",\n\t\t];\n\t\tconst values: unknown[] = [\n\t\t\tid,\n\t\t\tslug || null,\n\t\t\tstatus,\n\t\t\tauthorId || null,\n\t\t\tprimaryBylineId ?? null,\n\t\t\tcreatedAt || now,\n\t\t\tnow,\n\t\t\tpublishedAt || null,\n\t\t\t1,\n\t\t\tlocale || \"en\",\n\t\t\ttranslationGroup,\n\t\t];\n\n\t\t// Add data fields as columns (skip system columns to prevent injection via data)\n\t\tif (data && typeof data === \"object\") {\n\t\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\t\tif (!SYSTEM_COLUMNS.has(key)) {\n\t\t\t\t\tvalidateIdentifier(key, \"content field name\");\n\t\t\t\t\tcolumns.push(key);\n\t\t\t\t\tvalues.push(serializeValue(value));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Build dynamic INSERT using raw SQL\n\t\tconst columnRefs = columns.map((c) => sql.ref(c));\n\t\tconst valuePlaceholders = values.map((v) => (v === null ? sql`NULL` : sql`${v}`));\n\n\t\tawait sql`\n\t\t\tINSERT INTO ${sql.ref(tableName)} (${sql.join(columnRefs, sql`, `)})\n\t\t\tVALUES (${sql.join(valuePlaceholders, sql`, `)})\n\t\t`.execute(this.db);\n\n\t\t// Fetch and return the created item\n\t\tconst item = await this.findById(type, id);\n\t\tif (!item) {\n\t\t\tthrow new Error(\"Failed to create content\");\n\t\t}\n\t\treturn item;\n\t}\n\n\t/**\n\t * Generate a unique slug for a content item within a collection.\n\t *\n\t * Checks the collection table for existing slugs that match `baseSlug`\n\t * (optionally scoped to a locale) and appends a numeric suffix (`-1`,\n\t * `-2`, etc.) on collision to guarantee uniqueness.\n\t *\n\t * Returns `null` if `baseSlug` is empty after slugification.\n\t */\n\tasync generateUniqueSlug(type: string, text: string, locale?: string): Promise<string | null> {\n\t\tconst baseSlug = slugify(text);\n\t\tif (!baseSlug) return null;\n\n\t\tconst tableName = getTableName(type);\n\n\t\t// Check if the base slug is available\n\t\tconst existing = locale\n\t\t\t? await sql<{ slug: string }>`\n\t\t\t\t\tSELECT slug FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${baseSlug}\n\t\t\t\t\tAND locale = ${locale}\n\t\t\t\t\tLIMIT 1\n\t\t\t\t`.execute(this.db)\n\t\t\t: await sql<{ slug: string }>`\n\t\t\t\t\tSELECT slug FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${baseSlug}\n\t\t\t\t\tLIMIT 1\n\t\t\t\t`.execute(this.db);\n\n\t\tif (existing.rows.length === 0) {\n\t\t\treturn baseSlug;\n\t\t}\n\n\t\t// Find all slugs matching the pattern `baseSlug` or `baseSlug-N`\n\t\tconst pattern = `${baseSlug}-%`;\n\t\tconst candidates = locale\n\t\t\t? await sql<{ slug: string }>`\n\t\t\t\t\tSELECT slug FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE (slug = ${baseSlug} OR slug LIKE ${pattern})\n\t\t\t\t\tAND locale = ${locale}\n\t\t\t\t`.execute(this.db)\n\t\t\t: await sql<{ slug: string }>`\n\t\t\t\t\tSELECT slug FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${baseSlug} OR slug LIKE ${pattern}\n\t\t\t\t`.execute(this.db);\n\n\t\t// Find the highest numeric suffix in use\n\t\tlet maxSuffix = 0;\n\t\tconst suffixPattern = new RegExp(`^${escapeRegExp(baseSlug)}-(\\\\d+)$`);\n\t\tfor (const row of candidates.rows) {\n\t\t\tconst match = suffixPattern.exec(row.slug);\n\t\t\tif (match) {\n\t\t\t\tconst n = parseInt(match[1], 10);\n\t\t\t\tif (n > maxSuffix) maxSuffix = n;\n\t\t\t}\n\t\t}\n\n\t\treturn `${baseSlug}-${maxSuffix + 1}`;\n\t}\n\n\t/**\n\t * Duplicate a content item\n\t * Creates a new draft copy with \"(Copy)\" appended to the title.\n\t * A slug is auto-generated from the new title by the handler layer.\n\t */\n\tasync duplicate(type: string, id: string, authorId?: string): Promise<ContentItem> {\n\t\t// Fetch the original item\n\t\tconst original = await this.findById(type, id);\n\t\tif (!original) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\t// Prepare the new data\n\t\tconst newData = { ...original.data };\n\n\t\t// Append \"(Copy)\" to title if present\n\t\tif (typeof newData.title === \"string\") {\n\t\t\tnewData.title = `${newData.title} (Copy)`;\n\t\t} else if (typeof newData.name === \"string\") {\n\t\t\tnewData.name = `${newData.name} (Copy)`;\n\t\t}\n\n\t\t// Auto-generate a unique slug from the new title/name\n\t\tconst slugSource =\n\t\t\ttypeof newData.title === \"string\"\n\t\t\t\t? newData.title\n\t\t\t\t: typeof newData.name === \"string\"\n\t\t\t\t\t? newData.name\n\t\t\t\t\t: null;\n\n\t\tconst slug = slugSource\n\t\t\t? await this.generateUniqueSlug(type, slugSource, original.locale ?? undefined)\n\t\t\t: null;\n\n\t\t// Create the duplicate as a draft — use override authorId if provided (caller owns the copy)\n\t\treturn this.create({\n\t\t\ttype,\n\t\t\tslug,\n\t\t\tdata: newData,\n\t\t\tstatus: \"draft\",\n\t\t\tauthorId: authorId || original.authorId || undefined,\n\t\t});\n\t}\n\n\t/**\n\t * Find content by ID\n\t */\n\tasync findById(type: string, id: string): Promise<ContentItem | null> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql<Record<string, unknown>>`\n\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\tconst row = result.rows[0];\n\t\tif (!row) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.mapRow(type, row);\n\t}\n\n\t/**\n\t * Find content by id, including trashed (soft-deleted) items.\n\t * Used by restore endpoint for ownership checks.\n\t */\n\tasync findByIdIncludingTrashed(type: string, id: string): Promise<ContentItem | null> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql<Record<string, unknown>>`\n\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\tWHERE id = ${id}\n\t\t`.execute(this.db);\n\n\t\tconst row = result.rows[0];\n\t\tif (!row) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.mapRow(type, row);\n\t}\n\n\t/**\n\t * Find content by ID or slug. Tries ID first if it looks like a ULID,\n\t * otherwise tries slug. Falls back to the other if the first lookup misses.\n\t */\n\tasync findByIdOrSlug(\n\t\ttype: string,\n\t\tidentifier: string,\n\t\tlocale?: string,\n\t): Promise<ContentItem | null> {\n\t\treturn this._findByIdOrSlug(type, identifier, false, locale);\n\t}\n\n\t/**\n\t * Find content by ID or slug, including trashed (soft-deleted) items.\n\t * Used by restore/permanent-delete endpoints.\n\t */\n\tasync findByIdOrSlugIncludingTrashed(\n\t\ttype: string,\n\t\tidentifier: string,\n\t\tlocale?: string,\n\t): Promise<ContentItem | null> {\n\t\treturn this._findByIdOrSlug(type, identifier, true, locale);\n\t}\n\n\tprivate async _findByIdOrSlug(\n\t\ttype: string,\n\t\tidentifier: string,\n\t\tincludeTrashed: boolean,\n\t\tlocale?: string,\n\t): Promise<ContentItem | null> {\n\t\t// ULIDs are 26 uppercase alphanumeric chars\n\t\tconst looksLikeUlid = ULID_PATTERN.test(identifier);\n\n\t\tconst findById = includeTrashed\n\t\t\t? (t: string, id: string) => this.findByIdIncludingTrashed(t, id)\n\t\t\t: (t: string, id: string) => this.findById(t, id);\n\t\tconst findBySlug = includeTrashed\n\t\t\t? (t: string, s: string) => this.findBySlugIncludingTrashed(t, s, locale)\n\t\t\t: (t: string, s: string) => this.findBySlug(t, s, locale);\n\n\t\tif (looksLikeUlid) {\n\t\t\t// Try ID first, fall back to slug\n\t\t\tconst byId = await findById(type, identifier);\n\t\t\tif (byId) return byId;\n\t\t\treturn findBySlug(type, identifier);\n\t\t}\n\t\t// Try slug first, fall back to ID\n\t\tconst bySlug = await findBySlug(type, identifier);\n\t\tif (bySlug) return bySlug;\n\t\treturn findById(type, identifier);\n\t}\n\n\t/**\n\t * Find content by slug\n\t */\n\tasync findBySlug(type: string, slug: string, locale?: string): Promise<ContentItem | null> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = locale\n\t\t\t? await sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${slug}\n\t\t\t\t\tAND locale = ${locale}\n\t\t\t\t\tAND deleted_at IS NULL\n\t\t\t\t`.execute(this.db)\n\t\t\t: await sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${slug}\n\t\t\t\t\tAND deleted_at IS NULL\n\t\t\t\t\tORDER BY locale ASC\n\t\t\t\t\tLIMIT 1\n\t\t\t\t`.execute(this.db);\n\n\t\tconst row = result.rows[0];\n\t\tif (!row) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.mapRow(type, row);\n\t}\n\n\t/**\n\t * Find content by slug, including trashed (soft-deleted) items.\n\t * Used by restore/permanent-delete endpoints.\n\t */\n\tasync findBySlugIncludingTrashed(\n\t\ttype: string,\n\t\tslug: string,\n\t\tlocale?: string,\n\t): Promise<ContentItem | null> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = locale\n\t\t\t? await sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${slug}\n\t\t\t\t\tAND locale = ${locale}\n\t\t\t\t`.execute(this.db)\n\t\t\t: await sql<Record<string, unknown>>`\n\t\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\t\tWHERE slug = ${slug}\n\t\t\t\t\tORDER BY locale ASC\n\t\t\t\t\tLIMIT 1\n\t\t\t\t`.execute(this.db);\n\n\t\tconst row = result.rows[0];\n\t\tif (!row) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.mapRow(type, row);\n\t}\n\n\t/**\n\t * Find many content items with filtering and pagination\n\t */\n\tasync findMany(\n\t\ttype: string,\n\t\toptions: FindManyOptions = {},\n\t): Promise<FindManyResult<ContentItem>> {\n\t\tconst tableName = getTableName(type);\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\t// Determine ordering\n\t\tconst orderField = options.orderBy?.field || \"createdAt\";\n\t\tconst orderDirection = options.orderBy?.direction || \"desc\";\n\t\tconst dbField = this.mapOrderField(orderField);\n\n\t\t// Validate order direction to prevent injection\n\t\tconst safeOrderDirection = orderDirection.toLowerCase() === \"asc\" ? \"ASC\" : \"DESC\";\n\n\t\t// Build query with parameterized values (no string interpolation)\n\t\t// Note: Dynamic content tables have deleted_at column, cast needed for Kysely\n\t\tlet query = this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.selectAll()\n\t\t\t.where(\"deleted_at\" as never, \"is\", null);\n\n\t\t// Apply filters with parameterized queries\n\t\tif (options.where?.status) {\n\t\t\tquery = query.where(\"status\", \"=\", options.where.status);\n\t\t}\n\n\t\tif (options.where?.authorId) {\n\t\t\tquery = query.where(\"author_id\", \"=\", options.where.authorId);\n\t\t}\n\n\t\tif (options.where?.locale) {\n\t\t\tquery = query.where(\"locale\" as any, \"=\", options.where.locale);\n\t\t}\n\n\t\tquery = this.applySearchFilter(query, options.where);\n\t\tquery = this.applyDateFilter(query, options.where);\n\n\t\t// Handle cursor pagination — decodeCursor throws InvalidCursorError\n\t\t// on malformed input; let it propagate so handlers surface a\n\t\t// structured INVALID_CURSOR rather than silently returning page 1.\n\t\tif (options.cursor) {\n\t\t\tconst { orderValue, id: cursorId } = decodeCursor(options.cursor);\n\n\t\t\tif (safeOrderDirection === \"DESC\") {\n\t\t\t\tquery = query.where((eb) =>\n\t\t\t\t\teb.or([\n\t\t\t\t\t\teb(dbField as any, \"<\", orderValue),\n\t\t\t\t\t\teb.and([eb(dbField as any, \"=\", orderValue), eb(\"id\", \"<\", cursorId)]),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tquery = query.where((eb) =>\n\t\t\t\t\teb.or([\n\t\t\t\t\t\teb(dbField as any, \">\", orderValue),\n\t\t\t\t\t\teb.and([eb(dbField as any, \"=\", orderValue), eb(\"id\", \">\", cursorId)]),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Apply ordering and limit\n\t\tquery = query\n\t\t\t.orderBy(dbField as any, safeOrderDirection === \"ASC\" ? \"asc\" : \"desc\")\n\t\t\t.orderBy(\"id\", safeOrderDirection === \"ASC\" ? \"asc\" : \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\t// Run the page fetch and the unbounded count together — the UI needs\n\t\t// both to render a stable denominator (kept on every page intentionally),\n\t\t// and issuing them in parallel on SQLite is essentially free.\n\t\tconst [rows, total] = await Promise.all([query.execute(), this.count(type, options.where)]);\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit);\n\n\t\tconst mappedResult: FindManyResult<ContentItem> = {\n\t\t\titems: items.map((row) => this.mapRow(type, row as Record<string, unknown>)),\n\t\t\ttotal,\n\t\t};\n\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst lastRow = items.at(-1) as Record<string, unknown>;\n\t\t\tconst lastOrderValue = lastRow[dbField];\n\t\t\tconst orderStr =\n\t\t\t\ttypeof lastOrderValue === \"string\" || typeof lastOrderValue === \"number\"\n\t\t\t\t\t? String(lastOrderValue)\n\t\t\t\t\t: \"\";\n\t\t\tmappedResult.nextCursor = encodeCursor(orderStr, String(lastRow.id));\n\t\t}\n\n\t\treturn mappedResult;\n\t}\n\n\t/**\n\t * Update content\n\t */\n\tasync update(type: string, id: string, input: UpdateContentInput): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\t// Build update object with parameterized values\n\t\tconst updates: Record<string, unknown> = {\n\t\t\tupdated_at: now,\n\t\t\tversion: sql`version + 1`,\n\t\t};\n\n\t\tif (input.status !== undefined) {\n\t\t\tupdates.status = input.status;\n\t\t}\n\n\t\tif (input.slug !== undefined) {\n\t\t\tupdates.slug = input.slug;\n\t\t}\n\n\t\tif (input.publishedAt !== undefined) {\n\t\t\tupdates.published_at = input.publishedAt;\n\t\t}\n\n\t\tif (input.scheduledAt !== undefined) {\n\t\t\tupdates.scheduled_at = input.scheduledAt;\n\t\t}\n\n\t\tif (input.authorId !== undefined) {\n\t\t\tupdates.author_id = input.authorId;\n\t\t}\n\n\t\tif (input.primaryBylineId !== undefined) {\n\t\t\tupdates.primary_byline_id = input.primaryBylineId;\n\t\t}\n\n\t\t// Update data fields (skip system columns to prevent injection via data)\n\t\tif (input.data !== undefined && typeof input.data === \"object\") {\n\t\t\tfor (const [key, value] of Object.entries(input.data)) {\n\t\t\t\tif (!SYSTEM_COLUMNS.has(key)) {\n\t\t\t\t\tvalidateIdentifier(key, \"content field name\");\n\t\t\t\t\tupdates[key] = serializeValue(value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait this.db\n\t\t\t.updateTable(tableName as keyof Database)\n\t\t\t.set(updates)\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.where(\"deleted_at\" as never, \"is\", null)\n\t\t\t.execute();\n\n\t\tconst updated = await this.findById(type, id);\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Content not found\");\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Delete content (soft delete - moves to trash)\n\t */\n\tasync delete(type: string, id: string): Promise<boolean> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst result = await sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET deleted_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\treturn (result.numAffectedRows ?? 0n) > 0n;\n\t}\n\n\t/**\n\t * Restore content from trash\n\t */\n\tasync restore(type: string, id: string): Promise<boolean> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET deleted_at = NULL\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NOT NULL\n\t\t`.execute(this.db);\n\n\t\treturn (result.numAffectedRows ?? 0n) > 0n;\n\t}\n\n\t/**\n\t * Permanently delete content (cannot be undone)\n\t */\n\t/**\n\t * Permanently delete a soft-deleted content row.\n\t *\n\t * Returns `true` only when a soft-deleted (trashed) row was removed.\n\t * Returns `false` when no row exists OR when the row exists but is live —\n\t * the caller is responsible for distinguishing these cases (typically via\n\t * a follow-up `findByIdOrSlugIncludingTrashed` to surface NOT_FOUND vs\n\t * NOT_TRASHED). The `AND deleted_at IS NOT NULL` clause is the safety net\n\t * that prevents permanent delete from bypassing the trash workflow.\n\t */\n\tasync permanentDelete(type: string, id: string): Promise<boolean> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql`\n\t\t\tDELETE FROM ${sql.ref(tableName)}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NOT NULL\n\t\t`.execute(this.db);\n\n\t\treturn (result.numAffectedRows ?? 0n) > 0n;\n\t}\n\n\t/**\n\t * Find trashed content items\n\t */\n\tasync findTrashed(\n\t\ttype: string,\n\t\toptions: Omit<FindManyOptions, \"where\"> = {},\n\t): Promise<FindManyResult<ContentItem & { deletedAt: string }>> {\n\t\tconst tableName = getTableName(type);\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\t// Determine ordering - default to most recently deleted\n\t\tconst orderField = options.orderBy?.field || \"deletedAt\";\n\t\tconst orderDirection = options.orderBy?.direction || \"desc\";\n\t\tconst dbField = this.mapOrderField(orderField);\n\n\t\tconst safeOrderDirection = orderDirection.toLowerCase() === \"asc\" ? \"ASC\" : \"DESC\";\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.selectAll()\n\t\t\t.where(\"deleted_at\" as never, \"is not\", null);\n\n\t\t// Handle cursor pagination — decodeCursor throws on invalid input.\n\t\tif (options.cursor) {\n\t\t\tconst { orderValue, id: cursorId } = decodeCursor(options.cursor);\n\n\t\t\tif (safeOrderDirection === \"DESC\") {\n\t\t\t\tquery = query.where((eb) =>\n\t\t\t\t\teb.or([\n\t\t\t\t\t\teb(dbField as any, \"<\", orderValue),\n\t\t\t\t\t\teb.and([eb(dbField as any, \"=\", orderValue), eb(\"id\", \"<\", cursorId)]),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tquery = query.where((eb) =>\n\t\t\t\t\teb.or([\n\t\t\t\t\t\teb(dbField as any, \">\", orderValue),\n\t\t\t\t\t\teb.and([eb(dbField as any, \"=\", orderValue), eb(\"id\", \">\", cursorId)]),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tquery = query\n\t\t\t.orderBy(dbField as any, safeOrderDirection === \"ASC\" ? \"asc\" : \"desc\")\n\t\t\t.orderBy(\"id\", safeOrderDirection === \"ASC\" ? \"asc\" : \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\tconst rows = await query.execute();\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit);\n\n\t\tconst mappedResult: FindManyResult<ContentItem & { deletedAt: string }> = {\n\t\t\titems: items.map((row) => {\n\t\t\t\tconst record = row as Record<string, unknown>;\n\t\t\t\treturn {\n\t\t\t\t\t...this.mapRow(type, record),\n\t\t\t\t\tdeletedAt: typeof record.deleted_at === \"string\" ? record.deleted_at : \"\",\n\t\t\t\t};\n\t\t\t}),\n\t\t};\n\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst lastRow = items.at(-1) as Record<string, unknown>;\n\t\t\tconst lastOrderValue = lastRow[dbField];\n\t\t\tconst orderStr =\n\t\t\t\ttypeof lastOrderValue === \"string\" || typeof lastOrderValue === \"number\"\n\t\t\t\t\t? String(lastOrderValue)\n\t\t\t\t\t: \"\";\n\t\t\tmappedResult.nextCursor = encodeCursor(orderStr, String(lastRow.id));\n\t\t}\n\n\t\treturn mappedResult;\n\t}\n\n\t/**\n\t * Count trashed content items\n\t */\n\tasync countTrashed(type: string): Promise<number> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t.where(\"deleted_at\" as never, \"is not\", null)\n\t\t\t.executeTakeFirst();\n\n\t\treturn Number(result?.count || 0);\n\t}\n\n\t/**\n\t * Apply the optional case-insensitive `q` substring filter across the\n\t * handler-resolved `searchColumns` (OR'd). User input is treated literally\n\t * (LIKE wildcards escaped) and `lower()` is applied on both sides for\n\t * SQLite/Postgres case-insensitive parity.\n\t */\n\tprivate applySearchFilter<QB extends { where: (cb: (eb: any) => unknown) => QB }>(\n\t\tquery: QB,\n\t\twhere?: { q?: string; searchColumns?: string[] },\n\t): QB {\n\t\tconst term = where?.q?.trim();\n\t\tconst columns = where?.searchColumns;\n\t\tif (!term || !columns || columns.length === 0) return query;\n\n\t\tconst escaped = term.replace(LIKE_WILDCARD_RE, (c) => `\\\\${c}`);\n\t\tconst pattern = `%${escaped}%`;\n\n\t\treturn query.where((eb) =>\n\t\t\teb.or(\n\t\t\t\tcolumns.map((col) => {\n\t\t\t\t\tvalidateIdentifier(col, \"search column\");\n\t\t\t\t\treturn eb(sql`lower(${sql.ref(col)})`, \"like\", sql`lower(${pattern}) escape '\\\\'`);\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\t/**\n\t * Apply the optional inclusive date-range filter. The field is mapped\n\t * through `DATE_FILTER_COLUMNS` (a closed whitelist), and bounds compare\n\t * lexicographically against the stored ISO 8601 timestamps. A `publishedAt`\n\t * range naturally excludes never-published rows (their column is NULL).\n\t */\n\tprivate applyDateFilter<QB extends { where: (cb: (eb: any) => unknown) => QB }>(\n\t\tquery: QB,\n\t\twhere?: { dateFilter?: { field: string; from?: string; to?: string } },\n\t): QB {\n\t\tconst filter = where?.dateFilter;\n\t\tif (!filter) return query;\n\t\tconst column = DATE_FILTER_COLUMNS[filter.field as ContentDateField];\n\t\tif (!column) {\n\t\t\tthrow new EmDashValidationError(`Invalid date filter field: ${filter.field}`);\n\t\t}\n\t\tconst { from, to } = filter;\n\t\tif (!from && !to) return query;\n\n\t\tlet next = query;\n\t\tif (from) next = next.where((eb) => eb(column as any, \">=\", from));\n\t\tif (to) next = next.where((eb) => eb(column as any, \"<=\", to));\n\t\treturn next;\n\t}\n\n\t/**\n\t * Count content items\n\t */\n\tasync count(type: string, where?: FindManyOptions[\"where\"]): Promise<number> {\n\t\tconst tableName = getTableName(type);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.select((eb) => eb.fn.count(\"id\").as(\"count\"))\n\t\t\t.where(\"deleted_at\" as never, \"is\", null);\n\n\t\tif (where?.status) {\n\t\t\tquery = query.where(\"status\", \"=\", where.status);\n\t\t}\n\n\t\tif (where?.authorId) {\n\t\t\tquery = query.where(\"author_id\", \"=\", where.authorId);\n\t\t}\n\n\t\tif (where?.locale) {\n\t\t\tquery = query.where(\"locale\" as any, \"=\", where.locale);\n\t\t}\n\n\t\tquery = this.applySearchFilter(query, where);\n\t\tquery = this.applyDateFilter(query, where);\n\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result?.count || 0);\n\t}\n\n\t/**\n\t * Distinct, non-null `author_id` values across the collection's live\n\t * (non-trashed) content. Used to populate the admin author filter with\n\t * only the users who have actually authored entries, rather than the\n\t * full user directory (which requires admin privileges to read).\n\t */\n\tasync findDistinctAuthorIds(type: string): Promise<string[]> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.select(\"author_id\")\n\t\t\t.distinct()\n\t\t\t.where(\"deleted_at\" as never, \"is\", null)\n\t\t\t.where(\"author_id\" as never, \"is not\", null)\n\t\t\t.execute();\n\n\t\treturn rows\n\t\t\t.map((row) => (row as { author_id: string | null }).author_id)\n\t\t\t.filter((id): id is string => id !== null);\n\t}\n\n\t// get overall statistics (total, published, draft) for a content type in a single query\n\tasync getStats(type: string): Promise<{ total: number; published: number; draft: number }> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await this.db\n\t\t\t.selectFrom(tableName as keyof Database)\n\t\t\t.select((eb) => [\n\t\t\t\teb.fn.count(\"id\").as(\"total\"),\n\t\t\t\teb.fn.sum(eb.case().when(\"status\", \"=\", \"published\").then(1).else(0).end()).as(\"published\"),\n\t\t\t\teb.fn.sum(eb.case().when(\"status\", \"=\", \"draft\").then(1).else(0).end()).as(\"draft\"),\n\t\t\t])\n\t\t\t.where(\"deleted_at\" as never, \"is\", null)\n\t\t\t.executeTakeFirst();\n\n\t\treturn {\n\t\t\ttotal: Number(result?.total || 0),\n\t\t\tpublished: Number(result?.published || 0),\n\t\t\tdraft: Number(result?.draft || 0),\n\t\t};\n\t}\n\n\t/**\n\t * Schedule content for future publishing\n\t *\n\t * Sets status to 'scheduled' and stores the scheduled publish time.\n\t * The content will be auto-published when the scheduled time is reached.\n\t */\n\tasync schedule(type: string, id: string, scheduledAt: string): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\t// Validate scheduledAt is in the future\n\t\tconst scheduledDate = new Date(scheduledAt);\n\t\tif (isNaN(scheduledDate.getTime())) {\n\t\t\tthrow new EmDashValidationError(\"Invalid scheduled date\");\n\t\t}\n\t\tif (scheduledDate <= new Date()) {\n\t\t\tthrow new EmDashValidationError(\"Scheduled date must be in the future\");\n\t\t}\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\t// Published posts keep their status — the schedule applies to the\n\t\t// pending draft, not the currently-live revision. Unpublished posts\n\t\t// transition to 'scheduled' so they aren't visible before the time.\n\t\tconst newStatus = existing.status === \"published\" ? \"published\" : \"scheduled\";\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET status = ${newStatus},\n\t\t\t\tscheduled_at = ${scheduledAt},\n\t\t\t\tupdated_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\tconst updated = await this.findById(type, id);\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Content not found\");\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Unschedule content\n\t *\n\t * Clears the scheduled time. Published posts stay published;\n\t * draft/scheduled posts revert to 'draft'.\n\t */\n\tasync unschedule(type: string, id: string): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\t// Published posts keep their status — just clear the pending schedule.\n\t\t// Draft/scheduled posts revert to 'draft'.\n\t\tconst newStatus = existing.status === \"published\" ? \"published\" : \"draft\";\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET status = ${newStatus},\n\t\t\t\tscheduled_at = NULL,\n\t\t\t\tupdated_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND scheduled_at IS NOT NULL\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\tconst updated = await this.findById(type, id);\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Content not found\");\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Find content that is ready to be published\n\t *\n\t * Returns all content where scheduled_at <= now, regardless of status.\n\t * This covers both draft-scheduled posts (status='scheduled') and\n\t * published posts with scheduled draft changes (status='published').\n\t *\n\t * `limit` (optional) caps how many due rows are returned, oldest-due first.\n\t * The scheduled-publishing sweep passes a limit so a large backlog can't\n\t * fan out unbounded publish/webhook work in a single tick (and blow a Worker\n\t * invocation's CPU/subrequest budget); the remainder drains on later ticks.\n\t */\n\tasync findReadyToPublish(type: string, limit?: number): Promise<ContentItem[]> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\t// Embed an empty fragment when unbounded so callers that want every due\n\t\t// row (manual flows, tests) keep the original behaviour.\n\t\tconst limitClause =\n\t\t\ttypeof limit === \"number\" && Number.isInteger(limit) && limit > 0\n\t\t\t\t? sql`LIMIT ${limit}`\n\t\t\t\t: sql``;\n\n\t\tconst result = await sql<Record<string, unknown>>`\n\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\tWHERE scheduled_at IS NOT NULL\n\t\t\tAND scheduled_at <= ${now}\n\t\t\tAND deleted_at IS NULL\n\t\t\tORDER BY scheduled_at ASC\n\t\t\t${limitClause}\n\t\t`.execute(this.db);\n\n\t\treturn result.rows.map((row) => this.mapRow(type, row));\n\t}\n\n\t/**\n\t * Find all translations in a translation group\n\t */\n\tasync findTranslations(type: string, translationGroup: string): Promise<ContentItem[]> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql<Record<string, unknown>>`\n\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\tWHERE translation_group = ${translationGroup}\n\t\t\tAND deleted_at IS NULL\n\t\t\tORDER BY locale ASC\n\t\t`.execute(this.db);\n\n\t\treturn result.rows.map((row) => this.mapRow(type, row));\n\t}\n\n\t/**\n\t * Publish the current draft\n\t *\n\t * Promotes draft_revision_id to live_revision_id and clears draft pointer.\n\t * Syncs the draft revision's data into the content table columns so the\n\t * content table always reflects the published version.\n\t * If no draft revision exists, creates one from current data and publishes it.\n\t *\n\t * `publishedAt` (optional) overrides the publication timestamp. If omitted,\n\t * the existing `published_at` is preserved (idempotent re-publish keeps the\n\t * original date) and falls back to the current time on first publish. Pass\n\t * an explicit value to backdate a publish (e.g. when migrating content from\n\t * another CMS).\n\t *\n\t * `requireDue` (optional) gates the publish on the row still being due:\n\t * `scheduled_at` non-null and in the past. Used by the scheduled-publishing\n\t * sweep to avoid publishing content an editor unscheduled or rescheduled\n\t * between selection and publish. It claims the row with a single conditional\n\t * UPDATE (clearing `scheduled_at`) before any other write, so it is atomic\n\t * even on D1 (no multi-statement transactions) and serialises against\n\t * `unschedule()` and concurrent sweeps — no TOCTOU and no double publish.\n\t */\n\tasync publish(\n\t\ttype: string,\n\t\tid: string,\n\t\tpublishedAt?: string,\n\t\trequireDue = false,\n\t): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\t// Scheduled sweep: atomically claim the row before any other write. A\n\t\t// single conditional UPDATE is atomic per-statement on every dialect\n\t\t// (it doesn't depend on a wrapping transaction, which D1 lacks). If the\n\t\t// schedule was cleared or pushed to the future (unschedule/reschedule)\n\t\t// or another sweep already claimed it, this affects 0 rows and we bail\n\t\t// before promoting any revision — so the row can't be double-published.\n\t\tlet claimedScheduledAt: string | null = null;\n\t\tlet claimedUpdatedAt: string | null = null;\n\t\tif (requireDue) {\n\t\t\tconst claim = await sql`\n\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\tSET scheduled_at = NULL,\n\t\t\t\t\tupdated_at = ${now}\n\t\t\t\tWHERE id = ${id}\n\t\t\t\tAND scheduled_at IS NOT NULL\n\t\t\t\tAND scheduled_at <= ${now}\n\t\t\t\tAND deleted_at IS NULL\n\t\t\t`.execute(this.db);\n\t\t\tif ((claim.numAffectedRows ?? 0n) === 0n) {\n\t\t\t\tthrow new ScheduledNotDueError();\n\t\t\t}\n\t\t\t// Remember what we cleared so we can put it back if the publish work\n\t\t\t// below fails on a driver without transactions (see catch). Both\n\t\t\t// values come from the pre-claim snapshot: if a concurrent\n\t\t\t// reschedule-to-a-different-past-time landed between findById and the\n\t\t\t// claim, the restore writes the snapshot value rather than the one the\n\t\t\t// claim actually cleared. That window is tiny and the restore is\n\t\t\t// best-effort retry bookkeeping, so the imprecision is acceptable.\n\t\t\tclaimedScheduledAt = existing.scheduledAt;\n\t\t\tclaimedUpdatedAt = existing.updatedAt;\n\t\t}\n\n\t\t// Track whether the final publish write committed. On D1 the claim above\n\t\t// is already durable (withTransaction is a no-op there), so if a later\n\t\t// step throws we must restore the schedule — otherwise the row is left\n\t\t// `scheduled` with `scheduled_at = NULL` and no sweep ever retries it.\n\t\tlet publishCommitted = false;\n\t\ttry {\n\t\t\tconst revisionRepo = new RevisionRepository(this.db);\n\t\t\tlet revisionToPublish = existing.draftRevisionId || existing.liveRevisionId;\n\n\t\t\tif (!revisionToPublish) {\n\t\t\t\t// No revision exists - create one from current data\n\t\t\t\tconst revision = await revisionRepo.create({\n\t\t\t\t\tcollection: type,\n\t\t\t\t\tentryId: id,\n\t\t\t\t\tdata: existing.data,\n\t\t\t\t});\n\t\t\t\trevisionToPublish = revision.id;\n\t\t\t}\n\n\t\t\t// Sync the revision's data into the content table columns\n\t\t\t// so the content table always holds the published version\n\t\t\tconst revision = await revisionRepo.findById(revisionToPublish);\n\t\t\tif (revision) {\n\t\t\t\tawait this.syncDataColumns(type, id, revision.data);\n\n\t\t\t\t// Sync slug from revision if stored there\n\t\t\t\tif (typeof revision.data._slug === \"string\") {\n\t\t\t\t\tawait sql`\n\t\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\t\tSET slug = ${revision.data._slug}\n\t\t\t\t\t\tWHERE id = ${id}\n\t\t\t\t\t`.execute(this.db);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (publishedAt !== undefined) {\n\t\t\t\t// Caller supplied an explicit timestamp, so we overwrite published_at\n\t\t\t\t// directly (used to backdate a publish, e.g. for content migrations).\n\t\t\t\tawait sql`\n\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\tSET live_revision_id = ${revisionToPublish},\n\t\t\t\t\t\tdraft_revision_id = NULL,\n\t\t\t\t\t\tstatus = 'published',\n\t\t\t\t\t\tscheduled_at = NULL,\n\t\t\t\t\t\tpublished_at = ${publishedAt},\n\t\t\t\t\t\tupdated_at = ${now}\n\t\t\t\t\tWHERE id = ${id}\n\t\t\t\t\tAND deleted_at IS NULL\n\t\t\t\t`.execute(this.db);\n\t\t\t} else {\n\t\t\t\t// No timestamp supplied — preserve existing published_at on\n\t\t\t\t// idempotent re-publish, fall back to `now` on first publish.\n\t\t\t\tawait sql`\n\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\tSET live_revision_id = ${revisionToPublish},\n\t\t\t\t\t\tdraft_revision_id = NULL,\n\t\t\t\t\t\tstatus = 'published',\n\t\t\t\t\t\tscheduled_at = NULL,\n\t\t\t\t\t\tpublished_at = COALESCE(published_at, ${now}),\n\t\t\t\t\t\tupdated_at = ${now}\n\t\t\t\t\tWHERE id = ${id}\n\t\t\t\t\tAND deleted_at IS NULL\n\t\t\t\t`.execute(this.db);\n\t\t\t}\n\t\t\tpublishCommitted = true;\n\n\t\t\tconst updated = await this.findById(type, id);\n\t\t\tif (!updated) {\n\t\t\t\tthrow new Error(\"Content not found\");\n\t\t\t}\n\n\t\t\treturn updated;\n\t\t} catch (error) {\n\t\t\t// Best-effort schedule restore for the no-transaction (D1) case so a\n\t\t\t// failed publish stays retryable. Skipped when the publish actually\n\t\t\t// committed (the failure was afterwards). On SQLite/Postgres the\n\t\t\t// enclosing transaction rolls the claim back, so this restore also\n\t\t\t// rolls back — a harmless no-op. Never mask the original error.\n\t\t\tif (requireDue && claimedScheduledAt && !publishCommitted) {\n\t\t\t\ttry {\n\t\t\t\t\t// Only restore if the row still has pending work: either it's not\n\t\t\t\t\t// published, or it's a published row that still has a draft change\n\t\t\t\t\t// queued. This avoids re-adding a stale schedule (and triggering a\n\t\t\t\t\t// redundant republish) when another actor fully published the row\n\t\t\t\t\t// in the failure window — that publish clears draft_revision_id.\n\t\t\t\t\t// Restore updated_at to its pre-claim value too — the claim bumped\n\t\t\t\t\t// it to `now`, and a failed publish made no real change, so leaving\n\t\t\t\t\t// it advanced would be a phantom modification for \"changed since\"\n\t\t\t\t\t// consumers (sync, ETags, incremental indexers).\n\t\t\t\t\tawait sql`\n\t\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\t\tSET scheduled_at = ${claimedScheduledAt},\n\t\t\t\t\t\t\tupdated_at = ${claimedUpdatedAt ?? now}\n\t\t\t\t\t\tWHERE id = ${id}\n\t\t\t\t\t\tAND scheduled_at IS NULL\n\t\t\t\t\t\tAND deleted_at IS NULL\n\t\t\t\t\t\tAND (status != 'published' OR draft_revision_id IS NOT NULL)\n\t\t\t\t\t`.execute(this.db);\n\t\t\t\t} catch (restoreError) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`[content] Failed to restore schedule for ${type}/${id} after publish failure:`,\n\t\t\t\t\t\trestoreError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unpublish content\n\t *\n\t * Removes live pointer but preserves draft. If no draft exists,\n\t * creates one from the live version so the content isn't lost.\n\t */\n\tasync unpublish(type: string, id: string): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\t// If no draft exists, create one from the live version\n\t\tif (!existing.draftRevisionId && existing.liveRevisionId) {\n\t\t\tconst revisionRepo = new RevisionRepository(this.db);\n\t\t\tconst liveRevision = await revisionRepo.findById(existing.liveRevisionId);\n\t\t\tif (liveRevision) {\n\t\t\t\tconst draft = await revisionRepo.create({\n\t\t\t\t\tcollection: type,\n\t\t\t\t\tentryId: id,\n\t\t\t\t\tdata: liveRevision.data,\n\t\t\t\t});\n\n\t\t\t\tawait sql`\n\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\tSET draft_revision_id = ${draft.id}\n\t\t\t\t\tWHERE id = ${id}\n\t\t\t\t`.execute(this.db);\n\t\t\t}\n\t\t}\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET live_revision_id = NULL,\n\t\t\t\tstatus = 'draft',\n\t\t\t\tpublished_at = NULL,\n\t\t\t\tupdated_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\tconst updated = await this.findById(type, id);\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Content not found\");\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Set the draft revision pointer for a content item.\n\t *\n\t * Used by seed/import paths that stage a new revision's data before\n\t * promoting it to live via `publish()`.\n\t *\n\t * Validates that the content item exists and is not soft-deleted, that\n\t * the revision exists, and that the revision belongs to the same\n\t * collection and entry. Without these checks, a caller could leave the\n\t * content row pointing at a missing or unrelated revision.\n\t */\n\tasync setDraftRevision(type: string, id: string, revisionId: string): Promise<void> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\tconst revisionRepo = new RevisionRepository(this.db);\n\t\tconst revision = await revisionRepo.findById(revisionId);\n\t\tif (!revision) {\n\t\t\tthrow new EmDashValidationError(\"Revision not found\");\n\t\t}\n\n\t\tif (revision.collection !== type || revision.entryId !== id) {\n\t\t\tthrow new EmDashValidationError(\"Revision does not belong to the specified content item\");\n\t\t}\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET draft_revision_id = ${revisionId},\n\t\t\t\tupdated_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\t}\n\n\t/**\n\t * Discard pending draft changes\n\t *\n\t * Clears draft_revision_id. The content table columns already hold the\n\t * published version, so no data sync is needed.\n\t */\n\tasync discardDraft(type: string, id: string): Promise<ContentItem> {\n\t\tconst tableName = getTableName(type);\n\t\tconst now = new Date().toISOString();\n\n\t\tconst existing = await this.findById(type, id);\n\t\tif (!existing) {\n\t\t\tthrow new EmDashValidationError(\"Content item not found\");\n\t\t}\n\n\t\tif (!existing.draftRevisionId) {\n\t\t\t// No draft to discard\n\t\t\treturn existing;\n\t\t}\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET draft_revision_id = NULL,\n\t\t\t\tupdated_at = ${now}\n\t\t\tWHERE id = ${id}\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\tconst updated = await this.findById(type, id);\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Content not found\");\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Sync data columns in the content table from a data object.\n\t * Used to promote revision data into the content table on publish.\n\t * Keys starting with _ are revision metadata (e.g. _slug) and are skipped.\n\t */\n\tprivate async syncDataColumns(\n\t\ttype: string,\n\t\tid: string,\n\t\tdata: Record<string, unknown>,\n\t): Promise<void> {\n\t\tconst tableName = getTableName(type);\n\t\tconst updates: Record<string, unknown> = {};\n\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (SYSTEM_COLUMNS.has(key)) continue;\n\t\t\tif (key.startsWith(\"_\")) continue; // revision metadata\n\t\t\tvalidateIdentifier(key, \"content field name\");\n\t\t\tupdates[key] = serializeValue(value);\n\t\t}\n\n\t\tif (Object.keys(updates).length === 0) return;\n\n\t\tawait this.db\n\t\t\t.updateTable(tableName as keyof Database)\n\t\t\t.set(updates)\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.execute();\n\t}\n\n\t/**\n\t * Count content items with a pending schedule.\n\t * Includes both draft-scheduled (status='scheduled') and published\n\t * posts with scheduled draft changes (status='published', scheduled_at set).\n\t */\n\tasync countScheduled(type: string): Promise<number> {\n\t\tconst tableName = getTableName(type);\n\n\t\tconst result = await sql<{ count: number }>`\n\t\t\tSELECT COUNT(id) as count FROM ${sql.ref(tableName)}\n\t\t\tWHERE scheduled_at IS NOT NULL\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(this.db);\n\n\t\treturn Number(result.rows[0]?.count || 0);\n\t}\n\n\t/**\n\t * Map database row to ContentItem\n\t * Extracts system columns and puts content fields in data\n\t * Excludes null values from data to match input semantics\n\t */\n\tprivate mapRow(type: string, row: Record<string, unknown>): ContentItem {\n\t\tconst data: Record<string, unknown> = {};\n\n\t\tfor (const [key, value] of Object.entries(row)) {\n\t\t\tif (!SYSTEM_COLUMNS.has(key) && value !== null) {\n\t\t\t\tdata[key] = deserializeValue(value);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tid: row.id as string,\n\t\t\ttype,\n\t\t\tslug: row.slug as string | null,\n\t\t\tstatus: row.status as string,\n\t\t\tdata,\n\t\t\tauthorId: row.author_id as string | null,\n\t\t\tprimaryBylineId: (row.primary_byline_id as string | null) ?? null,\n\t\t\tcreatedAt: row.created_at as string,\n\t\t\tupdatedAt: row.updated_at as string,\n\t\t\tpublishedAt: row.published_at as string | null,\n\t\t\tscheduledAt: row.scheduled_at as string | null,\n\t\t\tliveRevisionId: (row.live_revision_id as string | null) ?? null,\n\t\t\tdraftRevisionId: (row.draft_revision_id as string | null) ?? null,\n\t\t\tversion: typeof row.version === \"number\" ? row.version : 1,\n\t\t\tlocale: (row.locale as string) ?? null,\n\t\t\ttranslationGroup: (row.translation_group as string) ?? null,\n\t\t};\n\t}\n\n\t/**\n\t * Map order field names to database columns.\n\t * Only allows known fields to prevent column enumeration via crafted orderBy values.\n\t */\n\tprivate mapOrderField(field: string): string {\n\t\tconst mapping: Record<string, string> = {\n\t\t\tcreatedAt: \"created_at\",\n\t\t\tupdatedAt: \"updated_at\",\n\t\t\tpublishedAt: \"published_at\",\n\t\t\tscheduledAt: \"scheduled_at\",\n\t\t\tdeletedAt: \"deleted_at\",\n\t\t\ttitle: \"title\",\n\t\t\tname: \"name\",\n\t\t\tslug: \"slug\",\n\t\t\tstatus: \"status\",\n\t\t\tlocale: \"locale\",\n\t\t};\n\n\t\tconst mapped = mapping[field];\n\t\tif (!mapped) {\n\t\t\tthrow new EmDashValidationError(`Invalid order field: ${field}`);\n\t\t}\n\t\treturn mapped;\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-B1keaX5Y.d.mts","names":[],"sources":["../src/database/errors.ts","../src/database/connection.ts","../src/database/repositories/content.ts","../src/database/repositories/media.ts","../src/database/repositories/user.ts","../src/database/repositories/revision.ts","../src/database/repositories/comment.ts","../src/database/repositories/plugin-storage.ts","../src/fields/types.ts","../src/fields/image.ts","../src/fields/file.ts","../src/fields/reference.ts","../src/fields/portable-text.ts","../src/api/handlers/content.ts","../src/api/handlers/manifest.ts","../src/api/handlers/revision.ts","../src/api/handlers/media.ts","../src/schema/registry.ts","../src/schema/query.ts","../src/sections/types.ts","../src/sections/index.ts","../src/plugins/sandbox/types.ts","../src/registry/types.ts","../src/content/converters/types.ts","../src/content/converters/prosemirror-to-portable-text.ts","../src/content/converters/portable-text-to-prosemirror.ts","../src/utils/hash.ts","../src/utils/url.ts","../src/loader.ts","../src/visual-editing/editable.ts","../src/query.ts","../src/after.ts","../src/i18n/config.ts","../src/plugins/define-plugin.ts","../src/astro/storage/types.ts","../src/astro/integration/runtime.ts","../src/plugins/manifest-schema.ts","../src/plugins/hooks.ts","../src/plugins/email.ts","../src/plugins/context.ts","../src/plugins/routes.ts","../src/plugins/manager.ts","../src/plugins/cron.ts","../src/plugins/scheduler/types.ts","../src/plugins/scheduler/node.ts","../src/plugins/sandbox/noop.ts","../src/preview/tokens.ts","../src/preview/urls.ts","../src/preview/helpers.ts","../src/settings/index.ts","../src/comments/query.ts","../src/menus/types.ts","../src/menus/index.ts","../src/bylines/index.ts","../src/taxonomies/types.ts","../src/taxonomies/index.ts","../src/widgets/types.ts","../src/widgets/index.ts","../src/search/types.ts","../src/search/fts-manager.ts","../src/search/query.ts","../src/search/text-extraction.ts"],"mappings":"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"}
|