emdash 0.19.0 → 0.21.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-C5AWLJSD.d.mts → adapters-BxSmgtbF.d.mts} +1 -1
- package/dist/{adapters-C5AWLJSD.d.mts.map → adapters-BxSmgtbF.d.mts.map} +1 -1
- package/dist/{allowed-origins-CyYLEJkp.mjs → allowed-origins-BqC8cul8.mjs} +2 -2
- package/dist/{allowed-origins-CyYLEJkp.mjs.map → allowed-origins-BqC8cul8.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +13 -12
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +3 -2
- package/dist/{api-BZ6bhjYs.mjs → api-DxjIV2o8.mjs} +46 -15
- package/dist/api-DxjIV2o8.mjs.map +1 -0
- package/dist/{api-tokens-VrXNiNvV.mjs → api-tokens-BFFkB0jB.mjs} +2 -2
- package/dist/{api-tokens-VrXNiNvV.mjs.map → api-tokens-BFFkB0jB.mjs.map} +1 -1
- package/dist/{apply-hQkKKBCf.mjs → apply-CLjxheyb.mjs} +12 -12
- package/dist/{apply-hQkKKBCf.mjs.map → apply-CLjxheyb.mjs.map} +1 -1
- package/dist/astro/index.d.mts +10 -10
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +50 -15
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.mjs +5 -5
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +11 -2
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +3 -2
- 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 +91 -137
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -4
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -4
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +4 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +4 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +8 -7
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +8 -7
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +8 -7
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -12
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +14 -12
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +14 -12
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +9 -8
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/comments/bulk.mjs +7 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +3 -3
- package/dist/astro/routes/api/admin/comments/index.mjs +7 -6
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +3 -3
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +2 -2
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +29 -27
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +29 -27
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +28 -26
- 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 +28 -26
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +28 -26
- 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 +29 -27
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +29 -27
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +28 -26
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +28 -26
- 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 +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +28 -26
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
- package/dist/astro/routes/api/admin/users/index.mjs +5 -4
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +9 -8
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +6 -5
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -7
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -7
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +5 -4
- 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 +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -4
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +10 -9
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -7
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -8
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -8
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +9 -8
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +8 -7
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +11 -9
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/index.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +3 -3
- package/dist/astro/routes/api/dev/emails.mjs +2 -2
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +10 -9
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +10 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +8 -7
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -8
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +8 -7
- 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 +10 -9
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +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 +14 -12
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +3 -3
- package/dist/astro/routes/api/mcp.mjs +20 -19
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +6 -5
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +6 -5
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
- package/dist/astro/routes/api/media/providers/index.mjs +2 -2
- package/dist/astro/routes/api/media/upload-url.mjs +8 -7
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +10 -9
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +6 -5
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +6 -5
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +6 -5
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +6 -5
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +6 -5
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +6 -5
- 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 +5 -5
- package/dist/astro/routes/api/oauth/device/code.mjs +8 -8
- package/dist/astro/routes/api/oauth/device/token.mjs +7 -7
- package/dist/astro/routes/api/oauth/register.mjs +2 -2
- package/dist/astro/routes/api/oauth/token/refresh.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/revoke.mjs +5 -5
- package/dist/astro/routes/api/oauth/token.mjs +5 -5
- package/dist/astro/routes/api/openapi.json.mjs +3 -2
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/index.mjs +7 -6
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +7 -6
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +8 -7
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +8 -7
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +28 -26
- 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 +28 -26
- 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 +28 -26
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +28 -26
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +28 -26
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +8 -13
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +28 -26
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +28 -26
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +9 -8
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +8 -7
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +9 -8
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +5 -5
- package/dist/astro/routes/api/search/suggest.mjs +8 -7
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +8 -7
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +8 -7
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +3 -3
- package/dist/astro/routes/api/settings.mjs +11 -9
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +10 -9
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +9 -8
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +19 -18
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +1 -1
- package/dist/astro/routes/api/setup/index.mjs +20 -18
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +5 -4
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +5 -4
- package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +6 -5
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +9 -7
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +9 -7
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -4
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +9 -7
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +5 -4
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +15 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +6 -5
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +12 -12
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-C_8t2KGa.mjs → authorize-D5gfBVU5.mjs} +2 -2
- package/dist/{authorize-C_8t2KGa.mjs.map → authorize-D5gfBVU5.mjs.map} +1 -1
- package/dist/{byline-DUx48sJp.mjs → byline-V_Qp1Ziw.mjs} +27 -14
- package/dist/byline-V_Qp1Ziw.mjs.map +1 -0
- package/dist/{byline-fields-51kg6Vuv.mjs → byline-fields-B0NO1yUB.mjs} +3 -3
- package/dist/{byline-fields-51kg6Vuv.mjs.map → byline-fields-B0NO1yUB.mjs.map} +1 -1
- package/dist/{byline-fields-DYXKDuNX.d.mts → byline-fields-CQJRIQkn.d.mts} +36 -32
- package/dist/byline-fields-CQJRIQkn.d.mts.map +1 -0
- package/dist/{byline-fields-C_OsR-KF.mjs → byline-fields-nBVqK_Ff.mjs} +2 -2
- package/dist/{byline-fields-C_OsR-KF.mjs.map → byline-fields-nBVqK_Ff.mjs.map} +1 -1
- package/dist/{byline-registry-CWP7I71B.mjs → byline-registry-DedidtqC.mjs} +2 -2
- package/dist/{byline-registry-CWP7I71B.mjs.map → byline-registry-DedidtqC.mjs.map} +1 -1
- package/dist/{bylines-Cx5n-WqP.mjs → bylines-B2NWnIwS.mjs} +2 -2
- package/dist/{bylines-Cx5n-WqP.mjs.map → bylines-B2NWnIwS.mjs.map} +1 -1
- package/dist/{bylines-wurS258E.mjs → bylines-DfGDnred.mjs} +7 -7
- package/dist/{bylines-wurS258E.mjs.map → bylines-DfGDnred.mjs.map} +1 -1
- package/dist/{cache-B_HzASVT.mjs → cache-DTTHWD8n.mjs} +1 -1
- package/dist/{cache-B_HzASVT.mjs.map → cache-DTTHWD8n.mjs.map} +1 -1
- package/dist/{challenge-store-DGwuCc4R.mjs → challenge-store-woE0bbCf.mjs} +1 -1
- package/dist/{challenge-store-DGwuCc4R.mjs.map → challenge-store-woE0bbCf.mjs.map} +1 -1
- package/dist/cli/index.mjs +22 -20
- 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 +1 -1
- package/dist/{comments-CJ0RZsYR.mjs → comments-D2hNuxNa.mjs} +1 -1
- package/dist/{comments-CJ0RZsYR.mjs.map → comments-D2hNuxNa.mjs.map} +1 -1
- package/dist/{components-CTfpu3PZ.mjs → components-DYKp2gmo.mjs} +1 -1
- package/dist/{components-CTfpu3PZ.mjs.map → components-DYKp2gmo.mjs.map} +1 -1
- package/dist/{context-GG52SPgh.mjs → context-Cm4pt1Ws.mjs} +5 -5
- package/dist/{context-GG52SPgh.mjs.map → context-Cm4pt1Ws.mjs.map} +1 -1
- package/dist/{cron-BJ2ClIlj.mjs → cron-DdEVrQ2Y.mjs} +1 -1
- package/dist/{cron-BJ2ClIlj.mjs.map → cron-DdEVrQ2Y.mjs.map} +1 -1
- package/dist/{dashboard-2JgAMWxK.mjs → dashboard-C-UYpps0.mjs} +1 -1
- package/dist/{dashboard-2JgAMWxK.mjs.map → dashboard-C-UYpps0.mjs.map} +1 -1
- package/dist/database/instrumentation.d.mts +10 -1
- package/dist/database/instrumentation.d.mts.map +1 -1
- package/dist/database/instrumentation.mjs +13 -1
- package/dist/database/instrumentation.mjs.map +1 -1
- package/dist/db/index.d.mts +3 -3
- 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-BluWkwGI.mjs} +1 -1
- package/dist/{db-errors-CtzxKBxe.mjs.map → db-errors-BluWkwGI.mjs.map} +1 -1
- package/dist/{default-xLFNSsZ9.mjs → default-NHGuJzQ3.mjs} +1 -1
- package/dist/{default-xLFNSsZ9.mjs.map → default-NHGuJzQ3.mjs.map} +1 -1
- package/dist/{device-flow-s6_q3T7A.mjs → device-flow-BQApWgnW.mjs} +4 -4
- package/dist/{device-flow-s6_q3T7A.mjs.map → device-flow-BQApWgnW.mjs.map} +1 -1
- package/dist/{email-console-DHT2Fbpj.mjs → email-console-BbU3RbWv.mjs} +1 -1
- package/dist/{email-console-DHT2Fbpj.mjs.map → email-console-BbU3RbWv.mjs.map} +1 -1
- package/dist/{error-RwM4dD35.mjs → error-CNn_w7jf.mjs} +1 -1
- package/dist/{error-RwM4dD35.mjs.map → error-CNn_w7jf.mjs.map} +1 -1
- package/dist/{escape-bIyGoW5W.mjs → escape-DPgcxcpL.mjs} +1 -1
- package/dist/{escape-bIyGoW5W.mjs.map → escape-DPgcxcpL.mjs.map} +1 -1
- package/dist/{fts-manager-1RgHmopc.mjs → fts-manager-Cx5z8jdA.mjs} +1 -1
- package/dist/{fts-manager-1RgHmopc.mjs.map → fts-manager-Cx5z8jdA.mjs.map} +1 -1
- package/dist/{hash-9w3pd3-m.mjs → hash-DlvIFn0b.mjs} +1 -1
- package/dist/{hash-9w3pd3-m.mjs.map → hash-DlvIFn0b.mjs.map} +1 -1
- package/dist/{import-Dh8bWmyq.mjs → import-KyxT1Mbs.mjs} +3 -3
- package/dist/{import-Dh8bWmyq.mjs.map → import-KyxT1Mbs.mjs.map} +1 -1
- package/dist/{index-FfiTQJq2.d.mts → index-D2VAiumu.d.mts} +46 -15
- package/dist/{index-FfiTQJq2.d.mts.map → index-D2VAiumu.d.mts.map} +1 -1
- package/dist/{index-BpYeJO1E.d.mts → index-uT2yR66F.d.mts} +3 -3
- package/dist/{index-BpYeJO1E.d.mts.map → index-uT2yR66F.d.mts.map} +1 -1
- package/dist/index.d.mts +16 -16
- package/dist/index.mjs +48 -46
- package/dist/init-lock-DlBHjf9-.mjs +83 -0
- package/dist/init-lock-DlBHjf9-.mjs.map +1 -0
- package/dist/{load-B84ohfBk.mjs → load-Dq91b_DK.mjs} +1 -1
- package/dist/{load-B84ohfBk.mjs.map → load-Dq91b_DK.mjs.map} +1 -1
- package/dist/{loader-CpZKpFz0.mjs → loader-BqWjcH3h.mjs} +12 -15
- package/dist/loader-BqWjcH3h.mjs.map +1 -0
- package/dist/{manifest-schema-Cj-YrzrF.mjs → manifest-schema-DFPeqMAn.mjs} +55 -2
- package/dist/manifest-schema-DFPeqMAn.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 +4 -3
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/{media-allowlist-CMcoYIjQ.mjs → media-allowlist-_A0SuDn4.mjs} +2 -2
- package/dist/{media-allowlist-CMcoYIjQ.mjs.map → media-allowlist-_A0SuDn4.mjs.map} +1 -1
- package/dist/media-url-CqLd69IO.mjs +26 -0
- package/dist/media-url-CqLd69IO.mjs.map +1 -0
- package/dist/{menus-Dp9xporj.mjs → menus-Ryk9L7fT.mjs} +10 -37
- package/dist/menus-Ryk9L7fT.mjs.map +1 -0
- package/dist/{mime-CCEzze7W.mjs → mime-YbtlEtvS.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-YbtlEtvS.mjs.map} +1 -1
- package/dist/{mode-BjlXswIw.mjs → mode-CGXzIbD8.mjs} +1 -1
- package/dist/{mode-BjlXswIw.mjs.map → mode-CGXzIbD8.mjs.map} +1 -1
- package/dist/{normalize-CK5o04zr.mjs → normalize-DKsg36ty.mjs} +1 -1
- package/dist/{normalize-CK5o04zr.mjs.map → normalize-DKsg36ty.mjs.map} +1 -1
- package/dist/{oauth-authorization-1aPAYjiC.mjs → oauth-authorization-C2kVyjXI.mjs} +4 -4
- package/dist/{oauth-authorization-1aPAYjiC.mjs.map → oauth-authorization-C2kVyjXI.mjs.map} +1 -1
- package/dist/{oauth-clients-8mPDStMv.mjs → oauth-clients-BC873NCV.mjs} +1 -1
- package/dist/{oauth-clients-8mPDStMv.mjs.map → oauth-clients-BC873NCV.mjs.map} +1 -1
- package/dist/{oauth-state-store-BJ7YtrfD.mjs → oauth-state-store-Cd--TUaq.mjs} +1 -1
- package/dist/{oauth-state-store-BJ7YtrfD.mjs.map → oauth-state-store-Cd--TUaq.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-BdDSDvjF.mjs → oauth-user-lookup-e4wOvDud.mjs} +1 -1
- package/dist/{oauth-user-lookup-BdDSDvjF.mjs.map → oauth-user-lookup-e4wOvDud.mjs.map} +1 -1
- package/dist/{options-D4MnavW_.d.mts → options-9kLgkE8m.d.mts} +3 -3
- package/dist/{options-D4MnavW_.d.mts.map → options-9kLgkE8m.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-CrGndy1A.mjs → parse-DzSrk1t8.mjs} +2 -2
- package/dist/{parse-CrGndy1A.mjs.map → parse-DzSrk1t8.mjs.map} +1 -1
- package/dist/{passkey-config-BDVM86Tj.mjs → passkey-config-BpjbE_Uv.mjs} +1 -1
- package/dist/{passkey-config-BDVM86Tj.mjs.map → passkey-config-BpjbE_Uv.mjs.map} +1 -1
- package/dist/{placeholder-BZxr8W1j.mjs → placeholder-2xumZh4g.mjs} +1 -1
- package/dist/{placeholder-BZxr8W1j.mjs.map → placeholder-2xumZh4g.mjs.map} +1 -1
- package/dist/{placeholder-B9lUUEmj.d.mts → placeholder-BevVKfay.d.mts} +1 -1
- package/dist/{placeholder-B9lUUEmj.d.mts.map → placeholder-BevVKfay.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 +2 -2
- package/dist/{preview-BfuRkVKW.mjs → preview-Dqv2hwXr.mjs} +2 -2
- package/dist/{preview-BfuRkVKW.mjs.map → preview-Dqv2hwXr.mjs.map} +1 -1
- package/dist/{public-url-egRHCy1m.mjs → public-url-D_zARuvZ.mjs} +1 -1
- package/dist/{public-url-egRHCy1m.mjs.map → public-url-D_zARuvZ.mjs.map} +1 -1
- package/dist/{query-BFQ029Ts.mjs → query-Crm038Mc.mjs} +21 -11
- package/dist/query-Crm038Mc.mjs.map +1 -0
- package/dist/{rate-limit-ClFFUga6.mjs → rate-limit-hRTBqmw1.mjs} +2 -2
- package/dist/{rate-limit-ClFFUga6.mjs.map → rate-limit-hRTBqmw1.mjs.map} +1 -1
- package/dist/{redirect-Cw3JTlmj.mjs → redirect-C-OOkyku.mjs} +1 -1
- package/dist/{redirect-Cw3JTlmj.mjs.map → redirect-C-OOkyku.mjs.map} +1 -1
- package/dist/{redirects-DEygMrRO.mjs → redirects-6Zg2SoYo.mjs} +11 -10
- package/dist/redirects-6Zg2SoYo.mjs.map +1 -0
- package/dist/{redirects-OIu6vQ2i.mjs → redirects-CP3TnTLO.mjs} +20 -14
- package/dist/redirects-CP3TnTLO.mjs.map +1 -0
- package/dist/{registry-brYh-rAT.mjs → registry-diMzD1Wf.mjs} +3 -3
- package/dist/{registry-brYh-rAT.mjs.map → registry-diMzD1Wf.mjs.map} +1 -1
- package/dist/{request-cache-D32LpnmI.mjs → request-cache-UwmBAiUK.mjs} +1 -1
- package/dist/{request-cache-D32LpnmI.mjs.map → request-cache-UwmBAiUK.mjs.map} +1 -1
- package/dist/request-context.d.mts +7 -0
- package/dist/request-context.d.mts.map +1 -1
- package/dist/request-context.mjs +2 -1
- package/dist/request-context.mjs.map +1 -1
- package/dist/{request-meta-7ByVLxB-.mjs → request-meta-DPechd0W.mjs} +2 -2
- package/dist/{request-meta-7ByVLxB-.mjs.map → request-meta-DPechd0W.mjs.map} +1 -1
- package/dist/{resolve-BqYMVG0D.mjs → resolve-B3NUUtVY.mjs} +1 -1
- package/dist/{resolve-BqYMVG0D.mjs.map → resolve-B3NUUtVY.mjs.map} +1 -1
- package/dist/{runner-BcRuXq_h.d.mts → runner-C8vcbvCe.d.mts} +2 -2
- package/dist/{runner-BcRuXq_h.d.mts.map → runner-C8vcbvCe.d.mts.map} +1 -1
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +1 -1
- package/dist/{schema-CS7Eg5gh.mjs → schema-BDOkd3OU.mjs} +4 -4
- package/dist/{schema-CS7Eg5gh.mjs.map → schema-BDOkd3OU.mjs.map} +1 -1
- package/dist/{search-o-aQzHI1.mjs → search-Bs_J_EW-.mjs} +3 -3
- package/dist/{search-o-aQzHI1.mjs.map → search-Bs_J_EW-.mjs.map} +1 -1
- package/dist/{secrets-C_ZtRos3.mjs → secrets-C8xmE6mR.mjs} +21 -11
- package/dist/secrets-C8xmE6mR.mjs.map +1 -0
- package/dist/{sections-DhsZ0ns9.mjs → sections-P0zuBlyz.mjs} +2 -2
- package/dist/{sections-DhsZ0ns9.mjs.map → sections-P0zuBlyz.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +14 -13
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +3 -12
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-DfjLvu8i.mjs → seo-CLhm-Fmb.mjs} +4 -3
- package/dist/seo-CLhm-Fmb.mjs.map +1 -0
- package/dist/{seo-B5e6y9Wk.mjs → seo-DpNgGQjF.mjs} +1 -1
- package/dist/{seo-B5e6y9Wk.mjs.map → seo-DpNgGQjF.mjs.map} +1 -1
- package/dist/{service-DAxg8RPR.mjs → service-CDQQnT8W.mjs} +2 -2
- package/dist/{service-DAxg8RPR.mjs.map → service-CDQQnT8W.mjs.map} +1 -1
- package/dist/{settings-B1p-gPUK.mjs → settings-BjBsmVAo.mjs} +32 -30
- package/dist/settings-BjBsmVAo.mjs.map +1 -0
- package/dist/{settings-DIsbHTRE.mjs → settings-sO0Fif4p.mjs} +2 -2
- package/dist/{settings-DIsbHTRE.mjs.map → settings-sO0Fif4p.mjs.map} +1 -1
- package/dist/{setup-complete-Yuv78yua.mjs → setup-complete-CMMr-oZU.mjs} +1 -1
- package/dist/{setup-complete-Yuv78yua.mjs.map → setup-complete-CMMr-oZU.mjs.map} +1 -1
- package/dist/{setup-nonce-Bm0uKqmf.mjs → setup-nonce-169xl4fV.mjs} +1 -1
- package/dist/{setup-nonce-Bm0uKqmf.mjs.map → setup-nonce-169xl4fV.mjs.map} +1 -1
- package/dist/single-flight-cache-C0UV1Npg.mjs +104 -0
- package/dist/single-flight-cache-C0UV1Npg.mjs.map +1 -0
- package/dist/{site-url-mEVmwIFi.mjs → site-url-vtsuOvSD.mjs} +1 -1
- package/dist/{site-url-mEVmwIFi.mjs.map → site-url-vtsuOvSD.mjs.map} +1 -1
- package/dist/{ssrf-BsVGIE0Z.mjs → ssrf-XO05Voq6.mjs} +1 -1
- package/dist/{ssrf-BsVGIE0Z.mjs.map → ssrf-XO05Voq6.mjs.map} +1 -1
- package/dist/status-2gZklYuj.mjs +30 -0
- package/dist/status-2gZklYuj.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-BEW7S5AI.mjs → taxonomies-BBxYA38v.mjs} +49 -12
- package/dist/taxonomies-BBxYA38v.mjs.map +1 -0
- package/dist/{taxonomies-UusDXv3C.mjs → taxonomies-DuESHWKI.mjs} +2 -2
- package/dist/{taxonomies-UusDXv3C.mjs.map → taxonomies-DuESHWKI.mjs.map} +1 -1
- package/dist/{tokens-Bx2afeT-.mjs → tokens-DMkVjxrx.mjs} +1 -1
- package/dist/{tokens-Bx2afeT-.mjs.map → tokens-DMkVjxrx.mjs.map} +1 -1
- package/dist/{transport--Ck3RBin.mjs → transport-1cIrOb1Y.mjs} +1 -1
- package/dist/{transport--Ck3RBin.mjs.map → transport-1cIrOb1Y.mjs.map} +1 -1
- package/dist/{transport-BwQeeY2p.d.mts → transport-jdvsZEIt.d.mts} +1 -1
- package/dist/{transport-BwQeeY2p.d.mts.map → transport-jdvsZEIt.d.mts.map} +1 -1
- package/dist/{trusted-proxy-B4AfnoAp.mjs → trusted-proxy-CHp41Fjj.mjs} +1 -1
- package/dist/{trusted-proxy-B4AfnoAp.mjs.map → trusted-proxy-CHp41Fjj.mjs.map} +1 -1
- package/dist/{types-DWnN7weG.d.mts → types-BFgYtuKd.d.mts} +1 -1
- package/dist/{types-DWnN7weG.d.mts.map → types-BFgYtuKd.d.mts.map} +1 -1
- package/dist/{types-DZk_y-MU.mjs → types-BIduXPJk.mjs} +1 -1
- package/dist/types-BIduXPJk.mjs.map +1 -0
- package/dist/{types-WVmpZBJV.d.mts → types-BTnnBYVX.d.mts} +2 -2
- package/dist/{types-WVmpZBJV.d.mts.map → types-BTnnBYVX.d.mts.map} +1 -1
- package/dist/types-BoRm8-pp.mjs +3 -0
- package/dist/{types-DbCWhHet.d.mts → types-Bzfk2yC8.d.mts} +2 -2
- package/dist/types-Bzfk2yC8.d.mts.map +1 -0
- package/dist/{types-Qa7-HJJC.d.mts → types-CkEuk-Zr.d.mts} +1 -1
- package/dist/{types-Qa7-HJJC.d.mts.map → types-CkEuk-Zr.d.mts.map} +1 -1
- package/dist/{types-DMwSpvcw.d.mts → types-DO7whVYU.d.mts} +9 -3
- package/dist/{types-DMwSpvcw.d.mts.map → types-DO7whVYU.d.mts.map} +1 -1
- package/dist/{types-DX6v9KzJ.d.mts → types-DdkL6fyv.d.mts} +1 -1
- package/dist/{types-DX6v9KzJ.d.mts.map → types-DdkL6fyv.d.mts.map} +1 -1
- package/dist/{types-DpFmlNyB.mjs → types-DejCHqWT.mjs} +1 -1
- package/dist/{types-DpFmlNyB.mjs.map → types-DejCHqWT.mjs.map} +1 -1
- package/dist/{types-OT_Es5mp.d.mts → types-Del0VMij.d.mts} +1 -1
- package/dist/{types-OT_Es5mp.d.mts.map → types-Del0VMij.d.mts.map} +1 -1
- package/dist/{types-kwqCOUxj.d.mts → types-u_XxjbS8.d.mts} +1 -1
- package/dist/{types-kwqCOUxj.d.mts.map → types-u_XxjbS8.d.mts.map} +1 -1
- package/dist/{utils-C4Ih4DML.mjs → utils-C4M981Br.mjs} +1 -1
- package/dist/{utils-C4Ih4DML.mjs.map → utils-C4M981Br.mjs.map} +1 -1
- package/dist/{validate-ZP9Dvg0P.mjs → validate-DGhQPXzI.mjs} +2 -2
- package/dist/{validate-ZP9Dvg0P.mjs.map → validate-DGhQPXzI.mjs.map} +1 -1
- package/dist/{validate-BPAHUSge.d.mts → validate-cJOiOvT2.d.mts} +5 -5
- package/dist/{validate-BPAHUSge.d.mts.map → validate-cJOiOvT2.d.mts.map} +1 -1
- package/dist/{validation-CE5i4q0c.mjs → validation-DVHjPM1M.mjs} +5 -5
- package/dist/{validation-CE5i4q0c.mjs.map → validation-DVHjPM1M.mjs.map} +1 -1
- package/dist/version-BOjj_cfz.mjs +7 -0
- package/dist/{version-Dw0JXu45.mjs.map → version-BOjj_cfz.mjs.map} +1 -1
- package/dist/{widgets-ClEnYQCH.mjs → widgets-Ci6hLwfO.mjs} +47 -44
- package/dist/widgets-Ci6hLwfO.mjs.map +1 -0
- package/dist/{zod-generator-Djo_VHCt.mjs → zod-generator-CarzgPAu.mjs} +2 -2
- package/dist/{zod-generator-Djo_VHCt.mjs.map → zod-generator-CarzgPAu.mjs.map} +1 -1
- package/package.json +10 -10
- package/src/api/handlers/marketplace.ts +2 -5
- package/src/api/handlers/redirects.ts +24 -13
- package/src/api/handlers/registry.ts +70 -0
- package/src/api/handlers/seo.ts +9 -1
- package/src/api/schemas/redirects.ts +11 -4
- package/src/api/schemas/schema.ts +13 -1
- package/src/astro/integration/index.ts +44 -8
- package/src/astro/integration/routes.ts +46 -9
- package/src/astro/middleware/redirect.ts +12 -0
- package/src/astro/middleware.ts +20 -6
- package/src/astro/routes/api/schema/index.ts +7 -15
- package/src/astro/routes/sitemap-[collection].xml.ts +13 -2
- package/src/bylines/field-defs-cache.ts +70 -20
- package/src/cli/commands/bundle-utils.ts +2 -0
- package/src/cli/commands/doctor.ts +1 -1
- package/src/cli/commands/secrets.ts +2 -2
- package/src/config/secrets.ts +28 -14
- package/src/database/instrumentation.ts +13 -0
- package/src/emdash-runtime.ts +31 -25
- package/src/loader.ts +24 -15
- package/src/plugins/manifest-schema.ts +75 -0
- package/src/plugins/marketplace.ts +2 -5
- package/src/plugins/types.ts +12 -0
- package/src/query.ts +13 -2
- package/src/redirects/status.ts +27 -0
- package/src/request-context.ts +8 -0
- package/src/schema/types.ts +11 -1
- package/src/seo/index.ts +2 -28
- package/src/seo/media-url.ts +32 -0
- package/src/settings/index.ts +32 -40
- package/src/taxonomies/index.ts +78 -12
- package/src/utils/single-flight-cache.ts +194 -0
- package/src/widgets/index.ts +57 -54
- package/dist/api-BZ6bhjYs.mjs.map +0 -1
- package/dist/byline-DUx48sJp.mjs.map +0 -1
- package/dist/byline-fields-DYXKDuNX.d.mts.map +0 -1
- package/dist/loader-CpZKpFz0.mjs.map +0 -1
- package/dist/manifest-schema-Cj-YrzrF.mjs.map +0 -1
- package/dist/menus-Dp9xporj.mjs.map +0 -1
- package/dist/query-BFQ029Ts.mjs.map +0 -1
- package/dist/redirects-DEygMrRO.mjs.map +0 -1
- package/dist/redirects-OIu6vQ2i.mjs.map +0 -1
- package/dist/secrets-C_ZtRos3.mjs.map +0 -1
- package/dist/seo-DfjLvu8i.mjs.map +0 -1
- package/dist/settings-B1p-gPUK.mjs.map +0 -1
- package/dist/taxonomies-BEW7S5AI.mjs.map +0 -1
- package/dist/types-Cj2S6FuC.mjs +0 -3
- package/dist/types-DZk_y-MU.mjs.map +0 -1
- package/dist/types-DbCWhHet.d.mts.map +0 -1
- package/dist/version-Dw0JXu45.mjs +0 -7
- package/dist/widgets-ClEnYQCH.mjs.map +0 -1
- /package/dist/{api-tokens-B6VgoE6M.mjs → api-tokens-C7ywRx7l.mjs} +0 -0
- /package/dist/{ssrf-BvgVcfNQ.mjs → ssrf-CRZGzjdL.mjs} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-
|
|
4
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
5
|
-
import { S as allowedDomainUpdateBody } from "../../../../../redirects-
|
|
6
|
-
import "../../../../../byline-fields-
|
|
3
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
4
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
5
|
+
import { S as allowedDomainUpdateBody } from "../../../../../redirects-6Zg2SoYo.mjs";
|
|
6
|
+
import "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
7
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
7
8
|
import "../../../../../api/schemas/index.mjs";
|
|
8
9
|
import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
|
|
9
10
|
import { Role, roleFromLevel } from "@emdash-cms/auth";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_domain_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/allowed-domains/[domain].ts"],"sourcesContent":["/**\n * PATCH/DELETE /_emdash/api/admin/allowed-domains/[domain]\n *\n * Admin endpoints for managing a specific allowed domain.\n * PATCH - Update domain settings (enabled, defaultRole)\n * DELETE - Remove an allowed domain\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, roleFromLevel } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { allowedDomainUpdateBody } from \"#api/schemas.js\";\n\n/**\n * PATCH - Update domain settings\n */\nexport const PATCH: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { domain } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!domain) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Domain is required\", 400);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst body = await parseBody(request, allowedDomainUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Check if domain exists\n\t\tconst existing = await adapter.getAllowedDomain(domain);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Domain not found\", 404);\n\t\t}\n\n\t\t// Role is already validated as RoleLevel by Zod schema\n\t\tconst defaultRole = body.defaultRole;\n\n\t\t// Update domain\n\t\tconst enabled = body.enabled ?? existing.enabled;\n\t\tawait adapter.updateAllowedDomain(domain, enabled, defaultRole);\n\n\t\t// Fetch updated domain\n\t\tconst updated = await adapter.getAllowedDomain(domain);\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tdomain: updated\n\t\t\t\t? {\n\t\t\t\t\t\tdomain: updated.domain,\n\t\t\t\t\t\tdefaultRole: updated.defaultRole,\n\t\t\t\t\t\troleName: roleFromLevel(updated.defaultRole),\n\t\t\t\t\t\tenabled: updated.enabled,\n\t\t\t\t\t\tcreatedAt: updated.createdAt.toISOString(),\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update allowed domain\", \"DOMAIN_UPDATE_ERROR\");\n\t}\n};\n\n/**\n * DELETE - Remove an allowed domain\n */\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { domain } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!domain) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Domain is required\", 400);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\t// Check if domain exists (optional - delete is idempotent)\n\t\tconst existing = await adapter.getAllowedDomain(domain);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Domain not found\", 404);\n\t\t}\n\n\t\tawait adapter.deleteAllowedDomain(domain);\n\n\t\treturn apiSuccess({ success: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete allowed domain\", \"DOMAIN_DELETE_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_domain_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/allowed-domains/[domain].ts"],"sourcesContent":["/**\n * PATCH/DELETE /_emdash/api/admin/allowed-domains/[domain]\n *\n * Admin endpoints for managing a specific allowed domain.\n * PATCH - Update domain settings (enabled, defaultRole)\n * DELETE - Remove an allowed domain\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, roleFromLevel } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { allowedDomainUpdateBody } from \"#api/schemas.js\";\n\n/**\n * PATCH - Update domain settings\n */\nexport const PATCH: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { domain } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!domain) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Domain is required\", 400);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst body = await parseBody(request, allowedDomainUpdateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Check if domain exists\n\t\tconst existing = await adapter.getAllowedDomain(domain);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Domain not found\", 404);\n\t\t}\n\n\t\t// Role is already validated as RoleLevel by Zod schema\n\t\tconst defaultRole = body.defaultRole;\n\n\t\t// Update domain\n\t\tconst enabled = body.enabled ?? existing.enabled;\n\t\tawait adapter.updateAllowedDomain(domain, enabled, defaultRole);\n\n\t\t// Fetch updated domain\n\t\tconst updated = await adapter.getAllowedDomain(domain);\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tdomain: updated\n\t\t\t\t? {\n\t\t\t\t\t\tdomain: updated.domain,\n\t\t\t\t\t\tdefaultRole: updated.defaultRole,\n\t\t\t\t\t\troleName: roleFromLevel(updated.defaultRole),\n\t\t\t\t\t\tenabled: updated.enabled,\n\t\t\t\t\t\tcreatedAt: updated.createdAt.toISOString(),\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update allowed domain\", \"DOMAIN_UPDATE_ERROR\");\n\t}\n};\n\n/**\n * DELETE - Remove an allowed domain\n */\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { domain } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!domain) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Domain is required\", 400);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\t// Check if domain exists (optional - delete is idempotent)\n\t\tconst existing = await adapter.getAllowedDomain(domain);\n\t\tif (!existing) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Domain not found\", 404);\n\t\t}\n\n\t\tawait adapter.deleteAllowedDomain(domain);\n\n\t\treturn apiSuccess({ success: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete allowed domain\", \"DOMAIN_DELETE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;AAUA,MAAa,YAAY;;;;AAYzB,MAAa,QAAkB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACrE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,2BAA2B,IAAI;AAGlE,KAAI,CAAC,OACJ,QAAO,SAAS,oBAAoB,sBAAsB,IAAI;AAG/D,KAAI,CAAC,QAAQ,KAAK,OAAO,KAAK,MAC7B,QAAO,SAAS,aAAa,6BAA6B,IAAI;CAG/D,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAE9C,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,wBAAwB;AAC9D,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,MAAM,WAAW,MAAM,QAAQ,iBAAiB,OAAO;AACvD,MAAI,CAAC,SACJ,QAAO,SAAS,aAAa,oBAAoB,IAAI;EAItD,MAAM,cAAc,KAAK;EAGzB,MAAM,UAAU,KAAK,WAAW,SAAS;AACzC,QAAM,QAAQ,oBAAoB,QAAQ,SAAS,YAAY;EAG/D,MAAM,UAAU,MAAM,QAAQ,iBAAiB,OAAO;AAEtD,SAAO,WAAW;GACjB,SAAS;GACT,QAAQ,UACL;IACA,QAAQ,QAAQ;IAChB,aAAa,QAAQ;IACrB,UAAU,cAAc,QAAQ,YAAY;IAC5C,SAAS,QAAQ;IACjB,WAAW,QAAQ,UAAU,aAAa;IAC1C,GACA;GACH,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,mCAAmC,sBAAsB;;;;;;AAOrF,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,WAAW;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,2BAA2B,IAAI;AAGlE,KAAI,CAAC,OACJ,QAAO,SAAS,oBAAoB,sBAAsB,IAAI;AAG/D,KAAI,CAAC,QAAQ,KAAK,OAAO,KAAK,MAC7B,QAAO,SAAS,aAAa,6BAA6B,IAAI;CAG/D,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAE9C,KAAI;AAGH,MAAI,CADa,MAAM,QAAQ,iBAAiB,OAAO,CAEtD,QAAO,SAAS,aAAa,oBAAoB,IAAI;AAGtD,QAAM,QAAQ,oBAAoB,OAAO;AAEzC,SAAO,WAAW,EAAE,SAAS,MAAM,CAAC;UAC5B,OAAO;AACf,SAAO,YAAY,OAAO,mCAAmC,sBAAsB"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-
|
|
4
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
5
|
-
import { x as allowedDomainCreateBody } from "../../../../../redirects-
|
|
6
|
-
import "../../../../../byline-fields-
|
|
3
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
4
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
5
|
+
import { x as allowedDomainCreateBody } from "../../../../../redirects-6Zg2SoYo.mjs";
|
|
6
|
+
import "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
7
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
7
8
|
import "../../../../../api/schemas/index.mjs";
|
|
8
9
|
import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
|
|
9
10
|
import { Role, roleFromLevel } from "@emdash-cms/auth";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/allowed-domains/index.ts"],"sourcesContent":["/**\n * GET/POST /_emdash/api/admin/allowed-domains\n *\n * Admin endpoints for managing allowed signup domains.\n * GET - List all allowed domains\n * POST - Add a new allowed domain\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, roleFromLevel } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { allowedDomainCreateBody } from \"#api/schemas.js\";\n\nconst DOMAIN_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]*(\\.[a-zA-Z0-9-]+)+$/;\n\n/**\n * GET - List all allowed domains\n */\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst domains = await adapter.getAllowedDomains();\n\n\t\treturn apiSuccess({\n\t\t\tdomains: domains.map((d) => ({\n\t\t\t\tdomain: d.domain,\n\t\t\t\tdefaultRole: d.defaultRole,\n\t\t\t\troleName: roleFromLevel(d.defaultRole),\n\t\t\t\tenabled: d.enabled,\n\t\t\t\tcreatedAt: d.createdAt.toISOString(),\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to list allowed domains\", \"DOMAIN_LIST_ERROR\");\n\t}\n};\n\n/**\n * POST - Add a new allowed domain\n */\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst body = await parseBody(request, allowedDomainCreateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Role is already validated as RoleLevel by Zod schema\n\t\tconst defaultRole = body.defaultRole;\n\n\t\t// Validate domain format (no protocol, just domain)\n\t\tconst cleanDomain = body.domain.toLowerCase().trim();\n\t\tif (!DOMAIN_REGEX.test(cleanDomain)) {\n\t\t\treturn apiError(\"VALIDATION_ERROR\", \"Invalid domain format\", 400);\n\t\t}\n\n\t\t// Check if domain already exists\n\t\tconst existing = await adapter.getAllowedDomain(cleanDomain);\n\t\tif (existing) {\n\t\t\treturn apiError(\"CONFLICT\", \"Domain already exists\", 409);\n\t\t}\n\n\t\tconst domain = await adapter.createAllowedDomain(cleanDomain, defaultRole);\n\n\t\treturn apiSuccess(\n\t\t\t{\n\t\t\t\tsuccess: true,\n\t\t\t\tdomain: {\n\t\t\t\t\tdomain: domain.domain,\n\t\t\t\t\tdefaultRole: domain.defaultRole,\n\t\t\t\t\troleName: roleFromLevel(domain.defaultRole),\n\t\t\t\t\tenabled: domain.enabled,\n\t\t\t\t\tcreatedAt: domain.createdAt.toISOString(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t201,\n\t\t);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create allowed domain\", \"DOMAIN_CREATE_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/allowed-domains/index.ts"],"sourcesContent":["/**\n * GET/POST /_emdash/api/admin/allowed-domains\n *\n * Admin endpoints for managing allowed signup domains.\n * GET - List all allowed domains\n * POST - Add a new allowed domain\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { Role, roleFromLevel } from \"@emdash-cms/auth\";\nimport { createKyselyAdapter } from \"@emdash-cms/auth/adapters/kysely\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { allowedDomainCreateBody } from \"#api/schemas.js\";\n\nconst DOMAIN_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]*(\\.[a-zA-Z0-9-]+)+$/;\n\n/**\n * GET - List all allowed domains\n */\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst domains = await adapter.getAllowedDomains();\n\n\t\treturn apiSuccess({\n\t\t\tdomains: domains.map((d) => ({\n\t\t\t\tdomain: d.domain,\n\t\t\t\tdefaultRole: d.defaultRole,\n\t\t\t\troleName: roleFromLevel(d.defaultRole),\n\t\t\t\tenabled: d.enabled,\n\t\t\t\tcreatedAt: d.createdAt.toISOString(),\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to list allowed domains\", \"DOMAIN_LIST_ERROR\");\n\t}\n};\n\n/**\n * POST - Add a new allowed domain\n */\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"Database not configured\", 500);\n\t}\n\n\tif (!user || user.role < Role.ADMIN) {\n\t\treturn apiError(\"FORBIDDEN\", \"Admin privileges required\", 403);\n\t}\n\n\tconst adapter = createKyselyAdapter(emdash.db);\n\n\ttry {\n\t\tconst body = await parseBody(request, allowedDomainCreateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Role is already validated as RoleLevel by Zod schema\n\t\tconst defaultRole = body.defaultRole;\n\n\t\t// Validate domain format (no protocol, just domain)\n\t\tconst cleanDomain = body.domain.toLowerCase().trim();\n\t\tif (!DOMAIN_REGEX.test(cleanDomain)) {\n\t\t\treturn apiError(\"VALIDATION_ERROR\", \"Invalid domain format\", 400);\n\t\t}\n\n\t\t// Check if domain already exists\n\t\tconst existing = await adapter.getAllowedDomain(cleanDomain);\n\t\tif (existing) {\n\t\t\treturn apiError(\"CONFLICT\", \"Domain already exists\", 409);\n\t\t}\n\n\t\tconst domain = await adapter.createAllowedDomain(cleanDomain, defaultRole);\n\n\t\treturn apiSuccess(\n\t\t\t{\n\t\t\t\tsuccess: true,\n\t\t\t\tdomain: {\n\t\t\t\t\tdomain: domain.domain,\n\t\t\t\t\tdefaultRole: domain.defaultRole,\n\t\t\t\t\troleName: roleFromLevel(domain.defaultRole),\n\t\t\t\t\tenabled: domain.enabled,\n\t\t\t\t\tcreatedAt: domain.createdAt.toISOString(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t201,\n\t\t);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create allowed domain\", \"DOMAIN_CREATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;AAUA,MAAa,YAAY;AASzB,MAAM,eAAe;;;;AAKrB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,2BAA2B,IAAI;AAGlE,KAAI,CAAC,QAAQ,KAAK,OAAO,KAAK,MAC7B,QAAO,SAAS,aAAa,6BAA6B,IAAI;CAG/D,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAE9C,KAAI;AAGH,SAAO,WAAW,EACjB,UAHe,MAAM,QAAQ,mBAAmB,EAG/B,KAAK,OAAO;GAC5B,QAAQ,EAAE;GACV,aAAa,EAAE;GACf,UAAU,cAAc,EAAE,YAAY;GACtC,SAAS,EAAE;GACX,WAAW,EAAE,UAAU,aAAa;GACpC,EAAE,EACH,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,kCAAkC,oBAAoB;;;;;;AAOlF,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,2BAA2B,IAAI;AAGlE,KAAI,CAAC,QAAQ,KAAK,OAAO,KAAK,MAC7B,QAAO,SAAS,aAAa,6BAA6B,IAAI;CAG/D,MAAM,UAAU,oBAAoB,OAAO,GAAG;AAE9C,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,wBAAwB;AAC9D,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,MAAM,cAAc,KAAK;EAGzB,MAAM,cAAc,KAAK,OAAO,aAAa,CAAC,MAAM;AACpD,MAAI,CAAC,aAAa,KAAK,YAAY,CAClC,QAAO,SAAS,oBAAoB,yBAAyB,IAAI;AAKlE,MADiB,MAAM,QAAQ,iBAAiB,YAAY,CAE3D,QAAO,SAAS,YAAY,yBAAyB,IAAI;EAG1D,MAAM,SAAS,MAAM,QAAQ,oBAAoB,aAAa,YAAY;AAE1E,SAAO,WACN;GACC,SAAS;GACT,QAAQ;IACP,QAAQ,OAAO;IACf,aAAa,OAAO;IACpB,UAAU,cAAc,OAAO,YAAY;IAC3C,SAAS,OAAO;IAChB,WAAW,OAAO,UAAU,aAAa;IACzC;GACD,EACD,IACA;UACO,OAAO;AACf,SAAO,YAAY,OAAO,mCAAmC,sBAAsB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../error-
|
|
4
|
-
import "../../../../../api-tokens-
|
|
5
|
-
import { r as handleApiTokenRevoke } from "../../../../../api-tokens-
|
|
3
|
+
import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
4
|
+
import "../../../../../api-tokens-C7ywRx7l.mjs";
|
|
5
|
+
import { r as handleApiTokenRevoke } from "../../../../../api-tokens-BFFkB0jB.mjs";
|
|
6
6
|
import { Role } from "@emdash-cms/auth";
|
|
7
7
|
|
|
8
8
|
//#region src/astro/routes/api/admin/api-tokens/[id].ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../error-
|
|
4
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
5
|
-
import { n as VALID_SCOPES } from "../../../../../api-tokens-
|
|
6
|
-
import { n as handleApiTokenList, t as handleApiTokenCreate } from "../../../../../api-tokens-
|
|
3
|
+
import { a as unwrapResult, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
4
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
5
|
+
import { n as VALID_SCOPES } from "../../../../../api-tokens-C7ywRx7l.mjs";
|
|
6
|
+
import { n as handleApiTokenList, t as handleApiTokenCreate } from "../../../../../api-tokens-BFFkB0jB.mjs";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { Role } from "@emdash-cms/auth";
|
|
9
9
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import "../../../../../../byline-registry-
|
|
4
|
-
import { a as unwrapResult, i as requireDb, t as apiError } from "../../../../../../error-
|
|
5
|
-
import { n as requirePerm } from "../../../../../../authorize-
|
|
6
|
-
import { s as handleBylineFieldUsage } from "../../../../../../byline-fields-
|
|
3
|
+
import "../../../../../../byline-registry-DedidtqC.mjs";
|
|
4
|
+
import { a as unwrapResult, i as requireDb, t as apiError } from "../../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as requirePerm } from "../../../../../../authorize-D5gfBVU5.mjs";
|
|
6
|
+
import { s as handleBylineFieldUsage } from "../../../../../../byline-fields-nBVqK_Ff.mjs";
|
|
7
7
|
|
|
8
8
|
//#region src/astro/routes/api/admin/byline-fields/[slug]/usage.ts
|
|
9
9
|
const prerender = false;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import "../../../../../byline-registry-
|
|
4
|
-
import { a as unwrapResult, i as requireDb, t as apiError } from "../../../../../error-
|
|
5
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
6
|
-
import "../../../../../redirects-
|
|
7
|
-
import { a as bylineFieldUpdateBody } from "../../../../../byline-fields-
|
|
3
|
+
import "../../../../../byline-registry-DedidtqC.mjs";
|
|
4
|
+
import { a as unwrapResult, i as requireDb, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
6
|
+
import "../../../../../redirects-6Zg2SoYo.mjs";
|
|
7
|
+
import { a as bylineFieldUpdateBody } from "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
8
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
8
9
|
import "../../../../../api/schemas/index.mjs";
|
|
9
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
10
|
-
import { n as handleBylineFieldDelete, o as handleBylineFieldUpdate, r as handleBylineFieldGet } from "../../../../../byline-fields-
|
|
10
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
11
|
+
import { n as handleBylineFieldDelete, o as handleBylineFieldUpdate, r as handleBylineFieldGet } from "../../../../../byline-fields-nBVqK_Ff.mjs";
|
|
11
12
|
|
|
12
13
|
//#region src/astro/routes/api/admin/byline-fields/[slug].ts
|
|
13
14
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_slug_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/[slug].ts"],"sourcesContent":["/**\n * Byline custom-field schema management — single field CRUD.\n *\n * - GET /_emdash/api/admin/byline-fields/{slug} read one definition\n * - PATCH /_emdash/api/admin/byline-fields/{slug} update label / required /\n * translatable / validation /\n * sort order\n * - DELETE /_emdash/api/admin/byline-fields/{slug} drop the definition and all\n * stored values (FK CASCADE +\n * app-level cleanup; see\n * `BylineSchemaRegistry.deleteField`)\n *\n * Thin wrappers around the handler layer; status mapping happens in\n * `unwrapResult`. `slug` and `type` are immutable post-create — see\n * `bylineFieldUpdateBody`. Flipping `translatable` while value rows\n * exist surfaces as a 409 `TRANSLATABLE_LOCKED`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, requireDb, unwrapResult } from \"#api/error.js\";\nimport {\n\thandleBylineFieldDelete,\n\thandleBylineFieldGet,\n\thandleBylineFieldUpdate,\n} from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldUpdateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n// GET requires `schema:read` (Editor+); see sibling `index.ts` GET\n// for rationale.\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:read\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst result = await handleBylineFieldGet(emdash.db, slug);\n\treturn unwrapResult(result);\n};\n\nexport const PATCH: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst body = await parseBody(request, bylineFieldUpdateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldUpdate(emdash.db, slug, {\n\t\tlabel: body.label,\n\t\trequired: body.required,\n\t\ttranslatable: body.translatable,\n\t\t// `null` clears the stored validation; `undefined` leaves it as-is.\n\t\t// The zod schema makes `validation` itself optional, so an absent\n\t\t// key reaches the handler as `undefined`.\n\t\tvalidation: body.validation,\n\t\tsortOrder: body.sortOrder,\n\t});\n\treturn unwrapResult(result);\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst result = await handleBylineFieldDelete(emdash.db, slug);\n\treturn unwrapResult(result);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_slug_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/[slug].ts"],"sourcesContent":["/**\n * Byline custom-field schema management — single field CRUD.\n *\n * - GET /_emdash/api/admin/byline-fields/{slug} read one definition\n * - PATCH /_emdash/api/admin/byline-fields/{slug} update label / required /\n * translatable / validation /\n * sort order\n * - DELETE /_emdash/api/admin/byline-fields/{slug} drop the definition and all\n * stored values (FK CASCADE +\n * app-level cleanup; see\n * `BylineSchemaRegistry.deleteField`)\n *\n * Thin wrappers around the handler layer; status mapping happens in\n * `unwrapResult`. `slug` and `type` are immutable post-create — see\n * `bylineFieldUpdateBody`. Flipping `translatable` while value rows\n * exist surfaces as a 409 `TRANSLATABLE_LOCKED`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, requireDb, unwrapResult } from \"#api/error.js\";\nimport {\n\thandleBylineFieldDelete,\n\thandleBylineFieldGet,\n\thandleBylineFieldUpdate,\n} from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldUpdateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n// GET requires `schema:read` (Editor+); see sibling `index.ts` GET\n// for rationale.\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:read\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst result = await handleBylineFieldGet(emdash.db, slug);\n\treturn unwrapResult(result);\n};\n\nexport const PATCH: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst body = await parseBody(request, bylineFieldUpdateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldUpdate(emdash.db, slug, {\n\t\tlabel: body.label,\n\t\trequired: body.required,\n\t\ttranslatable: body.translatable,\n\t\t// `null` clears the stored validation; `undefined` leaves it as-is.\n\t\t// The zod schema makes `validation` itself optional, so an absent\n\t\t// key reaches the handler as `undefined`.\n\t\tvalidation: body.validation,\n\t\tsortOrder: body.sortOrder,\n\t});\n\treturn unwrapResult(result);\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst slug = params.slug;\n\tif (!slug) return apiError(\"MISSING_PARAM\", \"Field slug is required\", 400);\n\n\tconst result = await handleBylineFieldDelete(emdash.db, slug);\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;;;;;;;;AAgCA,MAAa,YAAY;AAIzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,cAAc;AAC/C,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,OAAO;AACpB,KAAI,CAAC,KAAM,QAAO,SAAS,iBAAiB,0BAA0B,IAAI;AAG1E,QAAO,aADQ,MAAM,qBAAqB,OAAO,IAAI,KAAK,CAC/B;;AAG5B,MAAa,QAAkB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACrE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,OAAO;AACpB,KAAI,CAAC,KAAM,QAAO,SAAS,iBAAiB,0BAA0B,IAAI;CAE1E,MAAM,OAAO,MAAM,UAAU,SAAS,sBAAsB;AAC5D,KAAI,aAAa,KAAK,CAAE,QAAO;AAY/B,QAAO,aAVQ,MAAM,wBAAwB,OAAO,IAAI,MAAM;EAC7D,OAAO,KAAK;EACZ,UAAU,KAAK;EACf,cAAc,KAAK;EAInB,YAAY,KAAK;EACjB,WAAW,KAAK;EAChB,CAAC,CACyB;;AAG5B,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,OAAO;AACpB,KAAI,CAAC,KAAM,QAAO,SAAS,iBAAiB,0BAA0B,IAAI;AAG1E,QAAO,aADQ,MAAM,wBAAwB,OAAO,IAAI,KAAK,CAClC"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import "../../../../../byline-registry-
|
|
4
|
-
import { a as unwrapResult, i as requireDb } from "../../../../../error-
|
|
5
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
6
|
-
import "../../../../../redirects-
|
|
7
|
-
import { t as bylineFieldCreateBody } from "../../../../../byline-fields-
|
|
3
|
+
import "../../../../../byline-registry-DedidtqC.mjs";
|
|
4
|
+
import { a as unwrapResult, i as requireDb } from "../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
6
|
+
import "../../../../../redirects-6Zg2SoYo.mjs";
|
|
7
|
+
import { t as bylineFieldCreateBody } from "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
8
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
8
9
|
import "../../../../../api/schemas/index.mjs";
|
|
9
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
10
|
-
import { i as handleBylineFieldList, t as handleBylineFieldCreate } from "../../../../../byline-fields-
|
|
10
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
11
|
+
import { i as handleBylineFieldList, t as handleBylineFieldCreate } from "../../../../../byline-fields-nBVqK_Ff.mjs";
|
|
11
12
|
|
|
12
13
|
//#region src/astro/routes/api/admin/byline-fields/index.ts
|
|
13
14
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/index.ts"],"sourcesContent":["/**\n * Byline custom-field schema management — list + create.\n *\n * - GET /_emdash/api/admin/byline-fields list every registered field\n * - POST /_emdash/api/admin/byline-fields create a new field definition\n *\n * Thin wrappers around `handleBylineFieldList` / `handleBylineFieldCreate`\n * in `api/handlers/byline-fields.ts`. Both endpoints require\n * `schema:manage`. Reserved-slug + identifier validation runs at the\n * zod layer in `bylineFieldCreateBody`; the registry repeats the check\n * for defence-in-depth. Domain errors surface as typed `ErrorCode`s and\n * are mapped to HTTP statuses by `unwrapResult` → `mapErrorStatus`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineFieldCreate, handleBylineFieldList } from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldCreateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n// GET requires `schema:read` (Editor+), not `schema:manage` — Phase 6\n// of #1174 surfaced the split: editors need to read field definitions\n// to render custom-field inputs in the byline edit form, while only\n// admins manage the registry. The Phase 4 review-round constraint\n// \"every endpoint returns 403 for a user without schema:manage\" is\n// superseded for the read endpoints; mutations remain admin-only.\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:read\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst result = await handleBylineFieldList(emdash.db);\n\treturn unwrapResult(result);\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineFieldCreateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldCreate(emdash.db, {\n\t\tslug: body.slug,\n\t\tlabel: body.label,\n\t\ttype: body.type,\n\t\trequired: body.required,\n\t\ttranslatable: body.translatable,\n\t\tvalidation: body.validation ?? null,\n\t\tsortOrder: body.sortOrder,\n\t});\n\treturn unwrapResult(result, 201);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/index.ts"],"sourcesContent":["/**\n * Byline custom-field schema management — list + create.\n *\n * - GET /_emdash/api/admin/byline-fields list every registered field\n * - POST /_emdash/api/admin/byline-fields create a new field definition\n *\n * Thin wrappers around `handleBylineFieldList` / `handleBylineFieldCreate`\n * in `api/handlers/byline-fields.ts`. Both endpoints require\n * `schema:manage`. Reserved-slug + identifier validation runs at the\n * zod layer in `bylineFieldCreateBody`; the registry repeats the check\n * for defence-in-depth. Domain errors surface as typed `ErrorCode`s and\n * are mapped to HTTP statuses by `unwrapResult` → `mapErrorStatus`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineFieldCreate, handleBylineFieldList } from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldCreateBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\n// GET requires `schema:read` (Editor+), not `schema:manage` — Phase 6\n// of #1174 surfaced the split: editors need to read field definitions\n// to render custom-field inputs in the byline edit form, while only\n// admins manage the registry. The Phase 4 review-round constraint\n// \"every endpoint returns 403 for a user without schema:manage\" is\n// superseded for the read endpoints; mutations remain admin-only.\nexport const GET: APIRoute = async ({ locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:read\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst result = await handleBylineFieldList(emdash.db);\n\treturn unwrapResult(result);\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineFieldCreateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldCreate(emdash.db, {\n\t\tslug: body.slug,\n\t\tlabel: body.label,\n\t\ttype: body.type,\n\t\trequired: body.required,\n\t\ttranslatable: body.translatable,\n\t\tvalidation: body.validation ?? null,\n\t\tsortOrder: body.sortOrder,\n\t});\n\treturn unwrapResult(result, 201);\n};\n"],"mappings":";;;;;;;;;;;;;AAwBA,MAAa,YAAY;AAQzB,MAAa,MAAgB,OAAO,EAAE,aAAa;CAClD,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,cAAc;AAC/C,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAGlB,QAAO,aADQ,MAAM,sBAAsB,OAAO,GAAG,CAC1B;;AAG5B,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,MAAM,UAAU,SAAS,sBAAsB;AAC5D,KAAI,aAAa,KAAK,CAAE,QAAO;AAW/B,QAAO,aATQ,MAAM,wBAAwB,OAAO,IAAI;EACvD,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,MAAM,KAAK;EACX,UAAU,KAAK;EACf,cAAc,KAAK;EACnB,YAAY,KAAK,cAAc;EAC/B,WAAW,KAAK;EAChB,CAAC,EAC0B,IAAI"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
|
-
import "../../../../../byline-registry-
|
|
4
|
-
import { a as unwrapResult, i as requireDb } from "../../../../../error-
|
|
5
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
6
|
-
import "../../../../../redirects-
|
|
7
|
-
import { i as bylineFieldReorderBody } from "../../../../../byline-fields-
|
|
3
|
+
import "../../../../../byline-registry-DedidtqC.mjs";
|
|
4
|
+
import { a as unwrapResult, i as requireDb } from "../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
6
|
+
import "../../../../../redirects-6Zg2SoYo.mjs";
|
|
7
|
+
import { i as bylineFieldReorderBody } from "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
8
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
8
9
|
import "../../../../../api/schemas/index.mjs";
|
|
9
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
10
|
-
import { a as handleBylineFieldReorder } from "../../../../../byline-fields-
|
|
10
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
11
|
+
import { a as handleBylineFieldReorder } from "../../../../../byline-fields-nBVqK_Ff.mjs";
|
|
11
12
|
|
|
12
13
|
//#region src/astro/routes/api/admin/byline-fields/reorder.ts
|
|
13
14
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reorder.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/reorder.ts"],"sourcesContent":["/**\n * Byline field reorder.\n *\n * POST /_emdash/api/admin/byline-fields/reorder\n *\n * Body: `{ slugs: string[] }` — the exact set of currently registered\n * slugs in the desired order. The registry rejects any drift\n * (`REORDER_MISMATCH` → 400). Empty `[]` against an empty registered\n * set is a no-op by registry contract; the zod schema permits it.\n *\n * Thin wrapper around `handleBylineFieldReorder`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineFieldReorder } from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldReorderBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineFieldReorderBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldReorder(emdash.db, body.slugs);\n\treturn unwrapResult(result);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"reorder.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/byline-fields/reorder.ts"],"sourcesContent":["/**\n * Byline field reorder.\n *\n * POST /_emdash/api/admin/byline-fields/reorder\n *\n * Body: `{ slugs: string[] }` — the exact set of currently registered\n * slugs in the desired order. The registry rejects any drift\n * (`REORDER_MISMATCH` → 400). Empty `[]` against an empty registered\n * set is a no-op by registry contract; the zod schema permits it.\n *\n * Thin wrapper around `handleBylineFieldReorder`.\n *\n * Phase 4 of Discussion #1174.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineFieldReorder } from \"#api/handlers/byline-fields.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineFieldReorderBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"schema:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineFieldReorderBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineFieldReorder(emdash.db, body.slugs);\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;;;;;;;;AAuBA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,MAAM,UAAU,SAAS,uBAAuB;AAC7D,KAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,QAAO,aADQ,MAAM,yBAAyB,OAAO,IAAI,KAAK,MAAM,CACzC"}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import "../../../../../../dialect-helpers-DRI5pyY3.mjs";
|
|
2
2
|
import "../../../../../../base64-CqR-7kqF.mjs";
|
|
3
3
|
import "../../../../../../types-BXSUSAjt.mjs";
|
|
4
|
-
import "../../../../../../
|
|
5
|
-
import "../../../../../../
|
|
6
|
-
import
|
|
7
|
-
import "../../../../../../
|
|
8
|
-
import "../../../../../../
|
|
9
|
-
import
|
|
10
|
-
import { n as
|
|
11
|
-
import {
|
|
12
|
-
import "../../../../../../
|
|
4
|
+
import "../../../../../../init-lock-DlBHjf9-.mjs";
|
|
5
|
+
import "../../../../../../request-cache-UwmBAiUK.mjs";
|
|
6
|
+
import "../../../../../../byline-registry-DedidtqC.mjs";
|
|
7
|
+
import { t as BylineRepository } from "../../../../../../byline-V_Qp1Ziw.mjs";
|
|
8
|
+
import "../../../../../../loader-BqWjcH3h.mjs";
|
|
9
|
+
import "../../../../../../resolve-B3NUUtVY.mjs";
|
|
10
|
+
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-CNn_w7jf.mjs";
|
|
11
|
+
import { n as parseBody, t as isParseError } from "../../../../../../parse-DzSrk1t8.mjs";
|
|
12
|
+
import { wn as bylineUpdateBody } from "../../../../../../redirects-6Zg2SoYo.mjs";
|
|
13
|
+
import "../../../../../../byline-fields-B0NO1yUB.mjs";
|
|
14
|
+
import "../../../../../../status-2gZklYuj.mjs";
|
|
13
15
|
import "../../../../../../api/schemas/index.mjs";
|
|
14
|
-
import { a as invalidateBylineCache } from "../../../../../../bylines-
|
|
15
|
-
import { n as requirePerm } from "../../../../../../authorize-
|
|
16
|
-
import { r as handleBylineUpdate } from "../../../../../../bylines-
|
|
16
|
+
import { a as invalidateBylineCache } from "../../../../../../bylines-DfGDnred.mjs";
|
|
17
|
+
import { n as requirePerm } from "../../../../../../authorize-D5gfBVU5.mjs";
|
|
18
|
+
import { r as handleBylineUpdate } from "../../../../../../bylines-B2NWnIwS.mjs";
|
|
17
19
|
|
|
18
20
|
//#region src/astro/routes/api/admin/bylines/[id]/index.ts
|
|
19
21
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/bylines/[id]/index.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineUpdate } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineUpdateBody } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst byline = await repo.findById(params.id!);\n\t\tif (!byline) return apiError(\"NOT_FOUND\", \"Byline not found\", 404);\n\t\treturn apiSuccess(byline);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get byline\", \"BYLINE_GET_ERROR\");\n\t}\n};\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineUpdateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineUpdate(emdash.db, params.id!, {\n\t\tslug: body.slug,\n\t\tdisplayName: body.displayName,\n\t\tbio: body.bio ?? null,\n\t\tavatarMediaId: body.avatarMediaId ?? null,\n\t\twebsiteUrl: body.websiteUrl ?? null,\n\t\tuserId: body.userId ?? null,\n\t\tisGuest: body.isGuest,\n\t\t// Forward `customFields` only when present so the repo treats an\n\t\t// omitted key as \"leave existing values untouched\". An empty\n\t\t// object also no-ops by repo convention — see\n\t\t// `BylineRepository.update`. Validation (unknown slug, type\n\t\t// mismatch, select-choice) happens inside the repo and surfaces\n\t\t// as `EmDashValidationError`, which the handler maps to a 400\n\t\t// `VALIDATION_ERROR` for `unwrapResult` / `mapErrorStatus`.\n\t\tcustomFields: body.customFields,\n\t});\n\n\tif (result.success) invalidateBylineCache();\n\treturn unwrapResult(result);\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst deleted = await repo.delete(params.id!);\n\t\tif (!deleted) return apiError(\"NOT_FOUND\", \"Byline not found\", 404);\n\t\tinvalidateBylineCache();\n\t\treturn apiSuccess({ deleted: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete byline\", \"BYLINE_DELETE_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/bylines/[id]/index.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineUpdate } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineUpdateBody } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst byline = await repo.findById(params.id!);\n\t\tif (!byline) return apiError(\"NOT_FOUND\", \"Byline not found\", 404);\n\t\treturn apiSuccess(byline);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get byline\", \"BYLINE_GET_ERROR\");\n\t}\n};\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst body = await parseBody(request, bylineUpdateBody);\n\tif (isParseError(body)) return body;\n\n\tconst result = await handleBylineUpdate(emdash.db, params.id!, {\n\t\tslug: body.slug,\n\t\tdisplayName: body.displayName,\n\t\tbio: body.bio ?? null,\n\t\tavatarMediaId: body.avatarMediaId ?? null,\n\t\twebsiteUrl: body.websiteUrl ?? null,\n\t\tuserId: body.userId ?? null,\n\t\tisGuest: body.isGuest,\n\t\t// Forward `customFields` only when present so the repo treats an\n\t\t// omitted key as \"leave existing values untouched\". An empty\n\t\t// object also no-ops by repo convention — see\n\t\t// `BylineRepository.update`. Validation (unknown slug, type\n\t\t// mismatch, select-choice) happens inside the repo and surfaces\n\t\t// as `EmDashValidationError`, which the handler maps to a 400\n\t\t// `VALIDATION_ERROR` for `unwrapResult` / `mapErrorStatus`.\n\t\tcustomFields: body.customFields,\n\t});\n\n\tif (result.success) invalidateBylineCache();\n\treturn unwrapResult(result);\n};\n\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst deleted = await repo.delete(params.id!);\n\t\tif (!deleted) return apiError(\"NOT_FOUND\", \"Byline not found\", 404);\n\t\tinvalidateBylineCache();\n\t\treturn apiSuccess({ deleted: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete byline\", \"BYLINE_DELETE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAUA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;EAEH,MAAM,SAAS,MADF,IAAI,iBAAiB,OAAO,GAAG,CAClB,SAAS,OAAO,GAAI;AAC9C,MAAI,CAAC,OAAQ,QAAO,SAAS,aAAa,oBAAoB,IAAI;AAClE,SAAO,WAAW,OAAO;UACjB,OAAO;AACf,SAAO,YAAY,OAAO,wBAAwB,mBAAmB;;;AAIvE,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,OAAO,MAAM,UAAU,SAAS,iBAAiB;AACvD,KAAI,aAAa,KAAK,CAAE,QAAO;CAE/B,MAAM,SAAS,MAAM,mBAAmB,OAAO,IAAI,OAAO,IAAK;EAC9D,MAAM,KAAK;EACX,aAAa,KAAK;EAClB,KAAK,KAAK,OAAO;EACjB,eAAe,KAAK,iBAAiB;EACrC,YAAY,KAAK,cAAc;EAC/B,QAAQ,KAAK,UAAU;EACvB,SAAS,KAAK;EAQd,cAAc,KAAK;EACnB,CAAC;AAEF,KAAI,OAAO,QAAS,wCAAuB;AAC3C,QAAO,aAAa,OAAO;;AAG5B,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAGpE,KAAI;AAGH,MAAI,CADY,MADH,IAAI,iBAAiB,OAAO,GAAG,CACjB,OAAO,OAAO,GAAI,CAC/B,QAAO,SAAS,aAAa,oBAAoB,IAAI;AACnE,yCAAuB;AACvB,SAAO,WAAW,EAAE,SAAS,MAAM,CAAC;UAC5B,OAAO;AACf,SAAO,YAAY,OAAO,2BAA2B,sBAAsB"}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import "../../../../../../dialect-helpers-DRI5pyY3.mjs";
|
|
2
2
|
import "../../../../../../base64-CqR-7kqF.mjs";
|
|
3
3
|
import "../../../../../../types-BXSUSAjt.mjs";
|
|
4
|
-
import "../../../../../../
|
|
5
|
-
import "../../../../../../
|
|
6
|
-
import
|
|
7
|
-
import "../../../../../../
|
|
8
|
-
import "../../../../../../
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import "../../../../../../
|
|
4
|
+
import "../../../../../../init-lock-DlBHjf9-.mjs";
|
|
5
|
+
import "../../../../../../request-cache-UwmBAiUK.mjs";
|
|
6
|
+
import "../../../../../../byline-registry-DedidtqC.mjs";
|
|
7
|
+
import { t as BylineRepository } from "../../../../../../byline-V_Qp1Ziw.mjs";
|
|
8
|
+
import "../../../../../../loader-BqWjcH3h.mjs";
|
|
9
|
+
import "../../../../../../resolve-B3NUUtVY.mjs";
|
|
10
|
+
import { a as unwrapResult, i as requireDb, r as handleError } from "../../../../../../error-CNn_w7jf.mjs";
|
|
11
|
+
import { n as parseBody, t as isParseError } from "../../../../../../parse-DzSrk1t8.mjs";
|
|
12
|
+
import { Sn as bylineTranslationCreateBody } from "../../../../../../redirects-6Zg2SoYo.mjs";
|
|
13
|
+
import "../../../../../../byline-fields-B0NO1yUB.mjs";
|
|
14
|
+
import "../../../../../../status-2gZklYuj.mjs";
|
|
13
15
|
import "../../../../../../api/schemas/index.mjs";
|
|
14
|
-
import { a as invalidateBylineCache } from "../../../../../../bylines-
|
|
15
|
-
import { n as requirePerm } from "../../../../../../authorize-
|
|
16
|
-
import { n as handleBylineTranslations, t as handleBylineCreate } from "../../../../../../bylines-
|
|
16
|
+
import { a as invalidateBylineCache } from "../../../../../../bylines-DfGDnred.mjs";
|
|
17
|
+
import { n as requirePerm } from "../../../../../../authorize-D5gfBVU5.mjs";
|
|
18
|
+
import { n as handleBylineTranslations, t as handleBylineCreate } from "../../../../../../bylines-B2NWnIwS.mjs";
|
|
17
19
|
|
|
18
20
|
//#region src/astro/routes/api/admin/bylines/[id]/translations.ts
|
|
19
21
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translations.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/bylines/[id]/translations.ts"],"sourcesContent":["/**\n * Byline translation endpoints\n *\n * GET /_emdash/api/admin/bylines/:id/translations — list every translation\n * of a byline (siblings\n * in the same\n * translation_group)\n * POST /_emdash/api/admin/bylines/:id/translations — create a new locale\n * variant joining the\n * source's\n * translation_group\n * (body: { locale, ... })\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineCreate, handleBylineTranslations } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineTranslationCreateBody } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst result = await handleBylineTranslations(emdash.db, id);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch byline translations\", \"BYLINE_TRANSLATIONS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, bylineTranslationCreateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Look up the source byline so we can:\n\t\t// (a) emit a clean 404 when it doesn't exist (route layer);\n\t\t// (b) fall back to its slug + display_name + avatar/website when\n\t\t// the body omits them. Editors creating a translation often\n\t\t// want to keep the slug stable and only enter the localized\n\t\t// bio/displayName — defaulting saves clicks.\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst source = await repo.findById(id);\n\t\tif (!source) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: { code: \"NOT_FOUND\", message: \"Byline not found\" } }),\n\t\t\t\t{ status: 404, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\tconst result = await handleBylineCreate(emdash.db, {\n\t\t\tslug: body.slug ?? source.slug,\n\t\t\tdisplayName: body.displayName ?? source.displayName,\n\t\t\tbio: body.bio ?? null,\n\t\t\tavatarMediaId: body.avatarMediaId ?? source.avatarMediaId,\n\t\t\twebsiteUrl: body.websiteUrl ?? source.websiteUrl,\n\t\t\t// Translations don't inherit the source's user_id or guest flag —\n\t\t\t// the partial unique on (user_id, locale) means a single user can\n\t\t\t// own one byline per locale, but the editor must opt into linking\n\t\t\t// the new row by editing it after creation.\n\t\t\tuserId: null,\n\t\t\tisGuest: source.isGuest,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: id,\n\t\t});\n\n\t\tif (result.success) invalidateBylineCache();\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(\n\t\t\terror,\n\t\t\t\"Failed to create byline translation\",\n\t\t\t\"BYLINE_TRANSLATION_CREATE_ERROR\",\n\t\t);\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"translations.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/bylines/[id]/translations.ts"],"sourcesContent":["/**\n * Byline translation endpoints\n *\n * GET /_emdash/api/admin/bylines/:id/translations — list every translation\n * of a byline (siblings\n * in the same\n * translation_group)\n * POST /_emdash/api/admin/bylines/:id/translations — create a new locale\n * variant joining the\n * source's\n * translation_group\n * (body: { locale, ... })\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleBylineCreate, handleBylineTranslations } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { bylineTranslationCreateBody } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst result = await handleBylineTranslations(emdash.db, id);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to fetch byline translations\", \"BYLINE_TRANSLATIONS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst id = params.id!;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, bylineTranslationCreateBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Look up the source byline so we can:\n\t\t// (a) emit a clean 404 when it doesn't exist (route layer);\n\t\t// (b) fall back to its slug + display_name + avatar/website when\n\t\t// the body omits them. Editors creating a translation often\n\t\t// want to keep the slug stable and only enter the localized\n\t\t// bio/displayName — defaulting saves clicks.\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst source = await repo.findById(id);\n\t\tif (!source) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: { code: \"NOT_FOUND\", message: \"Byline not found\" } }),\n\t\t\t\t{ status: 404, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\tconst result = await handleBylineCreate(emdash.db, {\n\t\t\tslug: body.slug ?? source.slug,\n\t\t\tdisplayName: body.displayName ?? source.displayName,\n\t\t\tbio: body.bio ?? null,\n\t\t\tavatarMediaId: body.avatarMediaId ?? source.avatarMediaId,\n\t\t\twebsiteUrl: body.websiteUrl ?? source.websiteUrl,\n\t\t\t// Translations don't inherit the source's user_id or guest flag —\n\t\t\t// the partial unique on (user_id, locale) means a single user can\n\t\t\t// own one byline per locale, but the editor must opt into linking\n\t\t\t// the new row by editing it after creation.\n\t\t\tuserId: null,\n\t\t\tisGuest: source.isGuest,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: id,\n\t\t});\n\n\t\tif (result.success) invalidateBylineCache();\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(\n\t\t\terror,\n\t\t\t\"Failed to create byline translation\",\n\t\t\t\"BYLINE_TRANSLATION_CREATE_ERROR\",\n\t\t);\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,KAAK,OAAO;CAElB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI;AAEH,SAAO,aADQ,MAAM,yBAAyB,OAAO,IAAI,GAAG,CACjC;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,uCAAuC,4BAA4B;;;AAI/F,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,KAAK,OAAO;CAElB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,4BAA4B;AAClE,MAAI,aAAa,KAAK,CAAE,QAAO;EAS/B,MAAM,SAAS,MADF,IAAI,iBAAiB,OAAO,GAAG,CAClB,SAAS,GAAG;AACtC,MAAI,CAAC,OACJ,QAAO,IAAI,SACV,KAAK,UAAU,EAAE,OAAO;GAAE,MAAM;GAAa,SAAS;GAAoB,EAAE,CAAC,EAC7E;GAAE,QAAQ;GAAK,SAAS,EAAE,gBAAgB,oBAAoB;GAAE,CAChE;EAGF,MAAM,SAAS,MAAM,mBAAmB,OAAO,IAAI;GAClD,MAAM,KAAK,QAAQ,OAAO;GAC1B,aAAa,KAAK,eAAe,OAAO;GACxC,KAAK,KAAK,OAAO;GACjB,eAAe,KAAK,iBAAiB,OAAO;GAC5C,YAAY,KAAK,cAAc,OAAO;GAKtC,QAAQ;GACR,SAAS,OAAO;GAChB,QAAQ,KAAK;GACb,eAAe;GACf,CAAC;AAEF,MAAI,OAAO,QAAS,wCAAuB;AAC3C,SAAO,aAAa,QAAQ,IAAI;UACxB,OAAO;AACf,SAAO,YACN,OACA,uCACA,kCACA"}
|
|
@@ -2,19 +2,21 @@ import "../../../../../dialect-helpers-DRI5pyY3.mjs";
|
|
|
2
2
|
import { n as getI18nConfig } from "../../../../../config-CVssduLe.mjs";
|
|
3
3
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
4
4
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
5
|
-
import "../../../../../
|
|
6
|
-
import "../../../../../
|
|
7
|
-
import
|
|
8
|
-
import "../../../../../
|
|
9
|
-
import "../../../../../
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import "../../../../../
|
|
5
|
+
import "../../../../../init-lock-DlBHjf9-.mjs";
|
|
6
|
+
import "../../../../../request-cache-UwmBAiUK.mjs";
|
|
7
|
+
import "../../../../../byline-registry-DedidtqC.mjs";
|
|
8
|
+
import { t as BylineRepository } from "../../../../../byline-V_Qp1Ziw.mjs";
|
|
9
|
+
import "../../../../../loader-BqWjcH3h.mjs";
|
|
10
|
+
import "../../../../../resolve-B3NUUtVY.mjs";
|
|
11
|
+
import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
12
|
+
import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
13
|
+
import { Tn as bylinesListQuery, vn as bylineCreateBody } from "../../../../../redirects-6Zg2SoYo.mjs";
|
|
14
|
+
import "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
15
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
14
16
|
import "../../../../../api/schemas/index.mjs";
|
|
15
|
-
import { a as invalidateBylineCache } from "../../../../../bylines-
|
|
16
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
17
|
-
import { t as handleBylineCreate } from "../../../../../bylines-
|
|
17
|
+
import { a as invalidateBylineCache } from "../../../../../bylines-DfGDnred.mjs";
|
|
18
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
19
|
+
import { t as handleBylineCreate } from "../../../../../bylines-B2NWnIwS.mjs";
|
|
18
20
|
|
|
19
21
|
//#region src/astro/routes/api/admin/bylines/index.ts
|
|
20
22
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/bylines/index.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleBylineCreate } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { bylineCreateBody, bylinesListQuery } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nimport { getI18nConfig } from \"../../../../../i18n/config.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\tconst query = parseQuery(url, bylinesListQuery);\n\tif (isParseError(query)) return query;\n\n\tconst i18n = getI18nConfig();\n\tif (query.locale && i18n && !i18n.locales.includes(query.locale)) {\n\t\treturn apiError(\n\t\t\t\"VALIDATION_ERROR\",\n\t\t\t`Locale \"${query.locale}\" is not configured for this site`,\n\t\t\t400,\n\t\t);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst result = await repo.findMany({\n\t\t\tsearch: query.search,\n\t\t\tisGuest: query.isGuest,\n\t\t\tuserId: query.userId,\n\t\t\tlocale: query.locale,\n\t\t\tcursor: query.cursor,\n\t\t\tlimit: query.limit,\n\t\t});\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to list bylines\", \"BYLINE_LIST_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tconst body = await parseBody(request, bylineCreateBody);\n\tif (isParseError(body)) return body;\n\n\ttry {\n\t\tconst result = await handleBylineCreate(emdash.db, {\n\t\t\tslug: body.slug,\n\t\t\tdisplayName: body.displayName,\n\t\t\tbio: body.bio ?? null,\n\t\t\tavatarMediaId: body.avatarMediaId ?? null,\n\t\t\twebsiteUrl: body.websiteUrl ?? null,\n\t\t\tuserId: body.userId ?? null,\n\t\t\tisGuest: body.isGuest,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: body.translationOf,\n\t\t\tcustomFields: body.customFields,\n\t\t});\n\n\t\tif (result.success) invalidateBylineCache();\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create byline\", \"BYLINE_CREATE_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/bylines/index.ts"],"sourcesContent":["import type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { handleBylineCreate } from \"#api/handlers/bylines.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { bylineCreateBody, bylinesListQuery } from \"#api/schemas.js\";\nimport { invalidateBylineCache } from \"#bylines/index.js\";\nimport { BylineRepository } from \"#db/repositories/byline.js\";\n\nimport { getI18nConfig } from \"../../../../../i18n/config.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ url, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"bylines:read\");\n\tif (denied) return denied;\n\n\tconst query = parseQuery(url, bylinesListQuery);\n\tif (isParseError(query)) return query;\n\n\tconst i18n = getI18nConfig();\n\tif (query.locale && i18n && !i18n.locales.includes(query.locale)) {\n\t\treturn apiError(\n\t\t\t\"VALIDATION_ERROR\",\n\t\t\t`Locale \"${query.locale}\" is not configured for this site`,\n\t\t\t400,\n\t\t);\n\t}\n\n\ttry {\n\t\tconst repo = new BylineRepository(emdash.db);\n\t\tconst result = await repo.findMany({\n\t\t\tsearch: query.search,\n\t\t\tisGuest: query.isGuest,\n\t\t\tuserId: query.userId,\n\t\t\tlocale: query.locale,\n\t\t\tcursor: query.cursor,\n\t\t\tlimit: query.limit,\n\t\t});\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to list bylines\", \"BYLINE_LIST_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"bylines:manage\");\n\tif (denied) return denied;\n\n\tconst body = await parseBody(request, bylineCreateBody);\n\tif (isParseError(body)) return body;\n\n\ttry {\n\t\tconst result = await handleBylineCreate(emdash.db, {\n\t\t\tslug: body.slug,\n\t\t\tdisplayName: body.displayName,\n\t\t\tbio: body.bio ?? null,\n\t\t\tavatarMediaId: body.avatarMediaId ?? null,\n\t\t\twebsiteUrl: body.websiteUrl ?? null,\n\t\t\tuserId: body.userId ?? null,\n\t\t\tisGuest: body.isGuest,\n\t\t\tlocale: body.locale,\n\t\t\ttranslationOf: body.translationOf,\n\t\t\tcustomFields: body.customFields,\n\t\t});\n\n\t\tif (result.success) invalidateBylineCache();\n\t\treturn unwrapResult(result, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to create byline\", \"BYLINE_CREATE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAYA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,KAAK,aAAa;CACvD,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;CAEnB,MAAM,QAAQ,WAAW,KAAK,iBAAiB;AAC/C,KAAI,aAAa,MAAM,CAAE,QAAO;CAEhC,MAAM,OAAO,eAAe;AAC5B,KAAI,MAAM,UAAU,QAAQ,CAAC,KAAK,QAAQ,SAAS,MAAM,OAAO,CAC/D,QAAO,SACN,oBACA,WAAW,MAAM,OAAO,oCACxB,IACA;AAGF,KAAI;AAWH,SAAO,WATQ,MADF,IAAI,iBAAiB,OAAO,GAAG,CAClB,SAAS;GAClC,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,CAAC,CAEuB;UACjB,OAAO;AACf,SAAO,YAAY,OAAO,0BAA0B,oBAAoB;;;AAI1E,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;AAEzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;CAEnB,MAAM,OAAO,MAAM,UAAU,SAAS,iBAAiB;AACvD,KAAI,aAAa,KAAK,CAAE,QAAO;AAE/B,KAAI;EACH,MAAM,SAAS,MAAM,mBAAmB,OAAO,IAAI;GAClD,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,KAAK,KAAK,OAAO;GACjB,eAAe,KAAK,iBAAiB;GACrC,YAAY,KAAK,cAAc;GAC/B,QAAQ,KAAK,UAAU;GACvB,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,eAAe,KAAK;GACpB,cAAc,KAAK;GACnB,CAAC;AAEF,MAAI,OAAO,QAAS,wCAAuB;AAC3C,SAAO,aAAa,QAAQ,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,2BAA2B,sBAAsB"}
|
|
@@ -2,15 +2,16 @@ import "../../../../../../base64-CqR-7kqF.mjs";
|
|
|
2
2
|
import "../../../../../../types-BXSUSAjt.mjs";
|
|
3
3
|
import "../../../../../../comment-sqQxNpN3.mjs";
|
|
4
4
|
import "../../../../../../options-BPCVnesz.mjs";
|
|
5
|
-
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-
|
|
6
|
-
import { n as parseBody, t as isParseError } from "../../../../../../parse-
|
|
7
|
-
import { vt as commentStatusBody } from "../../../../../../redirects-
|
|
8
|
-
import "../../../../../../byline-fields-
|
|
5
|
+
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-CNn_w7jf.mjs";
|
|
6
|
+
import { n as parseBody, t as isParseError } from "../../../../../../parse-DzSrk1t8.mjs";
|
|
7
|
+
import { vt as commentStatusBody } from "../../../../../../redirects-6Zg2SoYo.mjs";
|
|
8
|
+
import "../../../../../../byline-fields-B0NO1yUB.mjs";
|
|
9
|
+
import "../../../../../../status-2gZklYuj.mjs";
|
|
9
10
|
import "../../../../../../api/schemas/index.mjs";
|
|
10
|
-
import { n as requirePerm } from "../../../../../../authorize-
|
|
11
|
-
import { a as handleCommentGet } from "../../../../../../comments-
|
|
12
|
-
import { t as getSiteBaseUrl } from "../../../../../../site-url-
|
|
13
|
-
import { i as sendCommentNotification, n as moderateComment, r as lookupContentAuthor } from "../../../../../../service-
|
|
11
|
+
import { n as requirePerm } from "../../../../../../authorize-D5gfBVU5.mjs";
|
|
12
|
+
import { a as handleCommentGet } from "../../../../../../comments-D2hNuxNa.mjs";
|
|
13
|
+
import { t as getSiteBaseUrl } from "../../../../../../site-url-vtsuOvSD.mjs";
|
|
14
|
+
import { i as sendCommentNotification, n as moderateComment, r as lookupContentAuthor } from "../../../../../../service-CDQQnT8W.mjs";
|
|
14
15
|
|
|
15
16
|
//#region src/astro/routes/api/admin/comments/[id]/status.ts
|
|
16
17
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/comments/[id]/status.ts"],"sourcesContent":["/**\n * Comment status change\n *\n * PUT /_emdash/api/admin/comments/:id/status - Change comment status\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleCommentGet } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { commentStatusBody } from \"#api/schemas.js\";\nimport { getSiteBaseUrl } from \"#api/site-url.js\";\nimport { lookupContentAuthor, sendCommentNotification } from \"#comments/notifications.js\";\nimport { moderateComment, type CommentHookRunner } from \"#comments/service.js\";\nimport type { CommentStatus } from \"#db/repositories/comment.js\";\nimport type { ModerationDecision } from \"#plugins/types.js\";\n\nexport const prerender = false;\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tif (!id) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Comment ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"comments:moderate\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, commentStatusBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst newStatus = body.status as CommentStatus;\n\n\t\t// Build hook runner for the service\n\t\tconst hookRunner: CommentHookRunner = {\n\t\t\tasync runBeforeCreate(event) {\n\t\t\t\treturn emdash.hooks.runCommentBeforeCreate(event);\n\t\t\t},\n\t\t\tasync runModerate(event) {\n\t\t\t\tconst result = await emdash.hooks.invokeExclusiveHook(\"comment:moderate\", event);\n\t\t\t\tif (!result) return { status: \"pending\" as const, reason: \"No moderator configured\" };\n\t\t\t\tif (result.error) return { status: \"pending\" as const, reason: \"Moderation error\" };\n\t\t\t\treturn result.result as ModerationDecision;\n\t\t\t},\n\t\t\tfireAfterCreate(event) {\n\t\t\t\temdash.hooks\n\t\t\t\t\t.runCommentAfterCreate(event)\n\t\t\t\t\t.catch((err) =>\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"[comments] afterCreate error:\",\n\t\t\t\t\t\t\terr instanceof Error ? err.message : err,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t},\n\t\t\tfireAfterModerate(event) {\n\t\t\t\temdash.hooks\n\t\t\t\t\t.runCommentAfterModerate(event)\n\t\t\t\t\t.catch((err) =>\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"[comments] afterModerate error:\",\n\t\t\t\t\t\t\terr instanceof Error ? err.message : err,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\t// Read the comment before updating so we know the previous status\n\t\tconst existing = await handleCommentGet(emdash.db, id);\n\t\tif (!existing.success) {\n\t\t\treturn unwrapResult(existing);\n\t\t}\n\t\tconst previousStatus = existing.data.status;\n\n\t\tconst updated = await moderateComment(\n\t\t\temdash.db,\n\t\t\tid,\n\t\t\tnewStatus,\n\t\t\t{ id: user!.id, name: user!.name ?? null },\n\t\t\thookRunner,\n\t\t);\n\n\t\tif (!updated) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Comment not found\", 404);\n\t\t}\n\n\t\t// Send notification when a comment is newly approved\n\t\tif (newStatus === \"approved\" && previousStatus !== \"approved\" && emdash.email) {\n\t\t\ttry {\n\t\t\t\tconst adminBaseUrl = await getSiteBaseUrl(emdash.db, request);\n\t\t\t\tconst content = await lookupContentAuthor(emdash.db, updated.collection, updated.contentId);\n\t\t\t\tif (content?.author) {\n\t\t\t\t\tawait sendCommentNotification({\n\t\t\t\t\t\temail: emdash.email,\n\t\t\t\t\t\tcomment: updated,\n\t\t\t\t\t\tcontentAuthor: content.author,\n\t\t\t\t\t\tadminBaseUrl,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[comments] notification error:\", err instanceof Error ? err.message : err);\n\t\t\t}\n\t\t}\n\n\t\treturn apiSuccess(updated);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update comment status\", \"COMMENT_STATUS_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"status.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/admin/comments/[id]/status.ts"],"sourcesContent":["/**\n * Comment status change\n *\n * PUT /_emdash/api/admin/comments/:id/status - Change comment status\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleCommentGet } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { commentStatusBody } from \"#api/schemas.js\";\nimport { getSiteBaseUrl } from \"#api/site-url.js\";\nimport { lookupContentAuthor, sendCommentNotification } from \"#comments/notifications.js\";\nimport { moderateComment, type CommentHookRunner } from \"#comments/service.js\";\nimport type { CommentStatus } from \"#db/repositories/comment.js\";\nimport type { ModerationDecision } from \"#plugins/types.js\";\n\nexport const prerender = false;\n\nexport const PUT: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tif (!id) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Comment ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\tconst denied = requirePerm(user, \"comments:moderate\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, commentStatusBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst newStatus = body.status as CommentStatus;\n\n\t\t// Build hook runner for the service\n\t\tconst hookRunner: CommentHookRunner = {\n\t\t\tasync runBeforeCreate(event) {\n\t\t\t\treturn emdash.hooks.runCommentBeforeCreate(event);\n\t\t\t},\n\t\t\tasync runModerate(event) {\n\t\t\t\tconst result = await emdash.hooks.invokeExclusiveHook(\"comment:moderate\", event);\n\t\t\t\tif (!result) return { status: \"pending\" as const, reason: \"No moderator configured\" };\n\t\t\t\tif (result.error) return { status: \"pending\" as const, reason: \"Moderation error\" };\n\t\t\t\treturn result.result as ModerationDecision;\n\t\t\t},\n\t\t\tfireAfterCreate(event) {\n\t\t\t\temdash.hooks\n\t\t\t\t\t.runCommentAfterCreate(event)\n\t\t\t\t\t.catch((err) =>\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"[comments] afterCreate error:\",\n\t\t\t\t\t\t\terr instanceof Error ? err.message : err,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t},\n\t\t\tfireAfterModerate(event) {\n\t\t\t\temdash.hooks\n\t\t\t\t\t.runCommentAfterModerate(event)\n\t\t\t\t\t.catch((err) =>\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"[comments] afterModerate error:\",\n\t\t\t\t\t\t\terr instanceof Error ? err.message : err,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\t// Read the comment before updating so we know the previous status\n\t\tconst existing = await handleCommentGet(emdash.db, id);\n\t\tif (!existing.success) {\n\t\t\treturn unwrapResult(existing);\n\t\t}\n\t\tconst previousStatus = existing.data.status;\n\n\t\tconst updated = await moderateComment(\n\t\t\temdash.db,\n\t\t\tid,\n\t\t\tnewStatus,\n\t\t\t{ id: user!.id, name: user!.name ?? null },\n\t\t\thookRunner,\n\t\t);\n\n\t\tif (!updated) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Comment not found\", 404);\n\t\t}\n\n\t\t// Send notification when a comment is newly approved\n\t\tif (newStatus === \"approved\" && previousStatus !== \"approved\" && emdash.email) {\n\t\t\ttry {\n\t\t\t\tconst adminBaseUrl = await getSiteBaseUrl(emdash.db, request);\n\t\t\t\tconst content = await lookupContentAuthor(emdash.db, updated.collection, updated.contentId);\n\t\t\t\tif (content?.author) {\n\t\t\t\t\tawait sendCommentNotification({\n\t\t\t\t\t\temail: emdash.email,\n\t\t\t\t\t\tcomment: updated,\n\t\t\t\t\t\tcontentAuthor: content.author,\n\t\t\t\t\t\tadminBaseUrl,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[comments] notification error:\", err instanceof Error ? err.message : err);\n\t\t\t}\n\t\t}\n\n\t\treturn apiSuccess(updated);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to update comment status\", \"COMMENT_STATUS_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,OAAO;AAEf,KAAI,CAAC,GACJ,QAAO,SAAS,oBAAoB,uBAAuB,IAAI;CAGhE,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAElB,MAAM,SAAS,YAAY,MAAM,oBAAoB;AACrD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;EAE/B,MAAM,YAAY,KAAK;EAGvB,MAAM,aAAgC;GACrC,MAAM,gBAAgB,OAAO;AAC5B,WAAO,OAAO,MAAM,uBAAuB,MAAM;;GAElD,MAAM,YAAY,OAAO;IACxB,MAAM,SAAS,MAAM,OAAO,MAAM,oBAAoB,oBAAoB,MAAM;AAChF,QAAI,CAAC,OAAQ,QAAO;KAAE,QAAQ;KAAoB,QAAQ;KAA2B;AACrF,QAAI,OAAO,MAAO,QAAO;KAAE,QAAQ;KAAoB,QAAQ;KAAoB;AACnF,WAAO,OAAO;;GAEf,gBAAgB,OAAO;AACtB,WAAO,MACL,sBAAsB,MAAM,CAC5B,OAAO,QACP,QAAQ,MACP,iCACA,eAAe,QAAQ,IAAI,UAAU,IACrC,CACD;;GAEH,kBAAkB,OAAO;AACxB,WAAO,MACL,wBAAwB,MAAM,CAC9B,OAAO,QACP,QAAQ,MACP,mCACA,eAAe,QAAQ,IAAI,UAAU,IACrC,CACD;;GAEH;EAGD,MAAM,WAAW,MAAM,iBAAiB,OAAO,IAAI,GAAG;AACtD,MAAI,CAAC,SAAS,QACb,QAAO,aAAa,SAAS;EAE9B,MAAM,iBAAiB,SAAS,KAAK;EAErC,MAAM,UAAU,MAAM,gBACrB,OAAO,IACP,IACA,WACA;GAAE,IAAI,KAAM;GAAI,MAAM,KAAM,QAAQ;GAAM,EAC1C,WACA;AAED,MAAI,CAAC,QACJ,QAAO,SAAS,aAAa,qBAAqB,IAAI;AAIvD,MAAI,cAAc,cAAc,mBAAmB,cAAc,OAAO,MACvE,KAAI;GACH,MAAM,eAAe,MAAM,eAAe,OAAO,IAAI,QAAQ;GAC7D,MAAM,UAAU,MAAM,oBAAoB,OAAO,IAAI,QAAQ,YAAY,QAAQ,UAAU;AAC3F,OAAI,SAAS,OACZ,OAAM,wBAAwB;IAC7B,OAAO,OAAO;IACd,SAAS;IACT,eAAe,QAAQ;IACvB;IACA,CAAC;WAEK,KAAK;AACb,WAAQ,MAAM,kCAAkC,eAAe,QAAQ,IAAI,UAAU,IAAI;;AAI3F,SAAO,WAAW,QAAQ;UAClB,OAAO;AACf,SAAO,YAAY,OAAO,mCAAmC,uBAAuB"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
3
|
import "../../../../../comment-sqQxNpN3.mjs";
|
|
4
|
-
import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../../error-
|
|
5
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
6
|
-
import { a as handleCommentGet, i as handleCommentDelete } from "../../../../../comments-
|
|
4
|
+
import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
6
|
+
import { a as handleCommentGet, i as handleCommentDelete } from "../../../../../comments-D2hNuxNa.mjs";
|
|
7
7
|
|
|
8
8
|
//#region src/astro/routes/api/admin/comments/[id].ts
|
|
9
9
|
const prerender = false;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import "../../../../../base64-CqR-7kqF.mjs";
|
|
2
2
|
import "../../../../../types-BXSUSAjt.mjs";
|
|
3
3
|
import "../../../../../comment-sqQxNpN3.mjs";
|
|
4
|
-
import { a as unwrapResult, i as requireDb, r as handleError } from "../../../../../error-
|
|
5
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
6
|
-
import { pt as commentBulkBody } from "../../../../../redirects-
|
|
7
|
-
import "../../../../../byline-fields-
|
|
4
|
+
import { a as unwrapResult, i as requireDb, r as handleError } from "../../../../../error-CNn_w7jf.mjs";
|
|
5
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-DzSrk1t8.mjs";
|
|
6
|
+
import { pt as commentBulkBody } from "../../../../../redirects-6Zg2SoYo.mjs";
|
|
7
|
+
import "../../../../../byline-fields-B0NO1yUB.mjs";
|
|
8
|
+
import "../../../../../status-2gZklYuj.mjs";
|
|
8
9
|
import "../../../../../api/schemas/index.mjs";
|
|
9
|
-
import { n as requirePerm } from "../../../../../authorize-
|
|
10
|
-
import { n as handleCommentBulk } from "../../../../../comments-
|
|
10
|
+
import { n as requirePerm } from "../../../../../authorize-D5gfBVU5.mjs";
|
|
11
|
+
import { n as handleCommentBulk } from "../../../../../comments-D2hNuxNa.mjs";
|
|
11
12
|
|
|
12
13
|
//#region src/astro/routes/api/admin/comments/bulk.ts
|
|
13
14
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/comments/bulk.ts"],"sourcesContent":["/**\n * Bulk comment operations\n *\n * POST /_emdash/api/admin/comments/bulk - Bulk status change or delete\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleCommentBulk } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { commentBulkBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\tconst body = await parseBody(request, commentBulkBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Bulk delete requires ADMIN, bulk status change requires EDITOR\n\t\tif (body.action === \"delete\") {\n\t\t\tconst denied = requirePerm(user, \"comments:delete\");\n\t\t\tif (denied) return denied;\n\t\t} else {\n\t\t\tconst denied = requirePerm(user, \"comments:moderate\");\n\t\t\tif (denied) return denied;\n\t\t}\n\n\t\tconst result = await handleCommentBulk(emdash.db, body.ids, body.action);\n\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to perform bulk operation\", \"COMMENT_BULK_ERROR\");\n\t}\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bulk.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/admin/comments/bulk.ts"],"sourcesContent":["/**\n * Bulk comment operations\n *\n * POST /_emdash/api/admin/comments/bulk - Bulk status change or delete\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleCommentBulk } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { commentBulkBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\tconst body = await parseBody(request, commentBulkBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Bulk delete requires ADMIN, bulk status change requires EDITOR\n\t\tif (body.action === \"delete\") {\n\t\t\tconst denied = requirePerm(user, \"comments:delete\");\n\t\t\tif (denied) return denied;\n\t\t} else {\n\t\t\tconst denied = requirePerm(user, \"comments:moderate\");\n\t\t\tif (denied) return denied;\n\t\t}\n\n\t\tconst result = await handleCommentBulk(emdash.db, body.ids, body.action);\n\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to perform bulk operation\", \"COMMENT_BULK_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CAEzB,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAElB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,gBAAgB;AACtD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,MAAI,KAAK,WAAW,UAAU;GAC7B,MAAM,SAAS,YAAY,MAAM,kBAAkB;AACnD,OAAI,OAAQ,QAAO;SACb;GACN,MAAM,SAAS,YAAY,MAAM,oBAAoB;AACrD,OAAI,OAAQ,QAAO;;AAKpB,SAAO,aAFQ,MAAM,kBAAkB,OAAO,IAAI,KAAK,KAAK,KAAK,OAAO,CAE7C;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,oCAAoC,qBAAqB"}
|