emdash 0.28.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-hUy8vOB-.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
- package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
- package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
- package/dist/{allowed-origins-CRsJ6BPM.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.d.mts.map +1 -1
- package/dist/api/route-utils.mjs +22 -21
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -4
- package/dist/{api-DxFSorgk.mjs → api-b8WIiGU4.mjs} +306 -154
- package/dist/api-b8WIiGU4.mjs.map +1 -0
- package/dist/api-tokens-Cvmixds7.mjs +3 -0
- package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
- package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
- package/dist/{apply-CDJqIjPU.mjs → apply-CmIJK9j8.mjs} +35 -38
- package/dist/apply-CmIJK9j8.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +97 -13
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +56 -107
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.d.mts +3 -0
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +258 -31
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +47 -3
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +379 -117
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/PluginRegistry.d.mts +5 -1
- package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
- package/dist/astro/routes/PluginRegistry.mjs +2 -1
- package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +11 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +19 -24
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +18 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +14 -13
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
- package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +30 -0
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +49 -41
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +46 -41
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +49 -41
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +49 -42
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +47 -42
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +48 -43
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +43 -40
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +43 -40
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +10 -9
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- package/dist/astro/routes/api/admin/users/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +14 -13
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +11 -10
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +13 -12
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +13 -12
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
- package/dist/astro/routes/api/auth/me.mjs +9 -8
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +6 -3
- package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +16 -6
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +14 -13
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +14 -13
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +13 -12
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +70 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +14 -13
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +9 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +72 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +51 -0
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +20 -19
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +19 -18
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -16
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +19 -18
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +29 -28
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +8 -9
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.d.mts.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +165 -52
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +10 -9
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +26 -10
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +11 -10
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +34 -14
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +10 -9
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +7 -8
- package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
- package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/openapi.json.mjs +71 -24
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +13 -12
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +13 -12
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +14 -13
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +14 -13
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
- package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs +70 -0
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
- package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/relations/index.d.mts +9 -0
- package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
- package/dist/astro/routes/api/relations/index.mjs +54 -0
- package/dist/astro/routes/api/relations/index.mjs.map +1 -0
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +43 -40
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -9
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +43 -40
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +43 -40
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +13 -12
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +14 -12
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +13 -12
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +12 -11
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +12 -11
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
- package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
- package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.mjs +16 -15
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +20 -16
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +19 -15
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -29
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +31 -30
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.mjs +9 -216
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/index.mjs +13 -12
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +9 -9
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
- package/dist/astro/routes/sitemap.xml.mjs +10 -10
- package/dist/astro/types.d.mts +40 -16
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-Dz88F_Fw.mjs → authorize-WxsiePzy.mjs} +7 -4
- package/dist/authorize-WxsiePzy.mjs.map +1 -0
- package/dist/backup-S8kFWtwD.mjs +241 -0
- package/dist/backup-S8kFWtwD.mjs.map +1 -0
- package/dist/{base64-CmWvODNW.mjs → base64-B-PsqheR.mjs} +8 -4
- package/dist/base64-B-PsqheR.mjs.map +1 -0
- package/dist/{byline-Bm8ZgUP9.mjs → byline-XEjchwzZ.mjs} +8 -8
- package/dist/{byline-Bm8ZgUP9.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
- package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-CdU_LTF1.mjs} +2 -2
- package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
- package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
- package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
- package/dist/{bylines-6tm9mgQb.mjs → bylines-BJbT4gKS.mjs} +4 -4
- package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
- package/dist/{bylines-CAZxGSrm.mjs → bylines-czseViYo.mjs} +8 -8
- package/dist/{bylines-CAZxGSrm.mjs.map → bylines-czseViYo.mjs.map} +1 -1
- package/dist/{cache-CEBAZjir.mjs → cache-CGCd6AVM.mjs} +3 -3
- package/dist/{cache-CEBAZjir.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs → challenge-store-BFzgFRog.mjs} +1 -1
- package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
- package/dist/{chunks-B2isWQhr.mjs → chunks-BxXyunY-.mjs} +2 -2
- package/dist/{chunks-B2isWQhr.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
- package/dist/cli/index.mjs +142 -35
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +86 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +20 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-CzeatwBV.mjs → comment-DPT0WKyd.mjs} +2 -2
- package/dist/{comment-CzeatwBV.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
- package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-C65MldIB.mjs} +2 -2
- package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
- package/dist/{comments-BLE-jv5k.mjs → comments-Bz6sCbgD.mjs} +3 -3
- package/dist/{comments-BLE-jv5k.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
- package/dist/{components-B_sATNUc.mjs → components-DZkL4Fx0.mjs} +1 -1
- package/dist/{components-B_sATNUc.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
- package/dist/{content-DhgEth4k.mjs → content-Ci04z2z-.mjs} +227 -34
- package/dist/content-Ci04z2z-.mjs.map +1 -0
- package/dist/{content-refresh-Br4gMzh8.mjs → content-refresh-D4khvC0R.mjs} +100 -8
- package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
- package/dist/{context-BRIpHARC.mjs → context-B6hc7zJL.mjs} +156 -76
- package/dist/context-B6hc7zJL.mjs.map +1 -0
- package/dist/{cron-v4FTEFR_.mjs → cron-BlKIMD_e.mjs} +1 -1
- package/dist/{cron-v4FTEFR_.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
- package/dist/{dashboard-EvEKF5en.mjs → dashboard-C5NkXFbi.mjs} +6 -5
- package/dist/dashboard-C5NkXFbi.mjs.map +1 -0
- package/dist/database/pg-migration-lock.d.mts +21 -0
- package/dist/database/pg-migration-lock.d.mts.map +1 -0
- package/dist/database/pg-migration-lock.mjs +45 -0
- package/dist/database/pg-migration-lock.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +2 -8
- package/dist/db/postgres.mjs.map +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-CK46D-ly.mjs → db-errors-CcWLaRiR.mjs} +4 -2
- package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
- package/dist/{default-CM_D83Mg.mjs → default-C4v9KP56.mjs} +1 -1
- package/dist/{default-CM_D83Mg.mjs.map → default-C4v9KP56.mjs.map} +1 -1
- package/dist/{device-flow-CfGP18Uw.mjs → device-flow-BeA6lUS1.mjs} +6 -7
- package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs +175 -0
- package/dist/dialect-helpers-HxEQGl_1.mjs.map +1 -0
- package/dist/{email-console-CIf4Lfvv.mjs → email-console-C-9Ng8DM.mjs} +1 -1
- package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
- package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
- package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
- package/dist/error-CEGF6UZb.mjs +90 -0
- package/dist/error-CEGF6UZb.mjs.map +1 -0
- package/dist/{error-CkAseSqZ.mjs → errors-DtEXIQQV.mjs} +24 -84
- package/dist/errors-DtEXIQQV.mjs.map +1 -0
- package/dist/{escape-DqD0aCKu.mjs → escape-CFedIB1C.mjs} +1 -1
- package/dist/{escape-DqD0aCKu.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
- package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-DvmlgP-D.mjs} +5 -5
- package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
- package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-DzqIBrrW.mjs} +27 -3
- package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
- package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
- package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
- package/dist/hreflang-CIxH_LKz.d.mts +48 -0
- package/dist/hreflang-CIxH_LKz.d.mts.map +1 -0
- package/dist/hreflang-db2Tpb2o.mjs +102 -0
- package/dist/hreflang-db2Tpb2o.mjs.map +1 -0
- package/dist/{import-fYLf14Co.mjs → import-Dmkm8S1W.mjs} +6 -6
- package/dist/{import-fYLf14Co.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
- package/dist/{index-Bm-Gy8Mh.d.mts → index-BEui-cRd.d.mts} +3 -3
- package/dist/{index-Bm-Gy8Mh.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
- package/dist/{index-B9sIxwe4.d.mts → index-wYnC6u4o.d.mts} +881 -22
- package/dist/index-wYnC6u4o.d.mts.map +1 -0
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +69 -64
- package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
- package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
- package/dist/{load-Djn3HWQS.mjs → load-Cx27ki1l.mjs} +2 -2
- package/dist/{load-Djn3HWQS.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
- package/dist/{loader-CB6YHeul.mjs → loader-Be3ouI5L.mjs} +170 -21
- package/dist/loader-Be3ouI5L.mjs.map +1 -0
- package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-bCq54i7F.mjs} +18 -2
- package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +30 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +30 -4
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +8 -8
- package/dist/{media-BrXIaMFN.mjs → media-BjhhENaJ.mjs} +2 -2
- package/dist/media-BjhhENaJ.mjs.map +1 -0
- package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-jUppPWFy.mjs} +2 -2
- package/dist/{media-allowlist-CRHEeJ_i.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
- package/dist/media-kIV1IxFf.mjs +243 -0
- package/dist/media-kIV1IxFf.mjs.map +1 -0
- package/dist/media-upload-D2wk3EIt.mjs +145 -0
- package/dist/media-upload-D2wk3EIt.mjs.map +1 -0
- package/dist/{media-url-CKi5XSw4.mjs → media-url-BCm5vBn6.mjs} +1 -1
- package/dist/{media-url-CKi5XSw4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
- package/dist/media-usage-CljdO1mc.mjs +554 -0
- package/dist/media-usage-CljdO1mc.mjs.map +1 -0
- package/dist/{menus-b2T4clbO.mjs → menus-BcyElFtI.mjs} +177 -15
- package/dist/menus-BcyElFtI.mjs.map +1 -0
- package/dist/{menus-Cfivc2Ad.mjs → menus-CZyG6rvx.mjs} +3 -3
- package/dist/{menus-Cfivc2Ad.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
- package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
- package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
- package/dist/{mode-BM9QgEmt.mjs → mode-fiXRMfeA.mjs} +1 -1
- package/dist/{mode-BM9QgEmt.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
- package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
- package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
- package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-oqfbBuMH.mjs} +6 -7
- package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
- package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
- package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
- package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
- package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
- package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
- package/dist/{options-iMpRRxIe.d.mts → options-BqMkWfYa.d.mts} +6 -6
- package/dist/{options-iMpRRxIe.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.d.mts.map +1 -1
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-GmjecGct.mjs → parse-C_-6klII.mjs} +4 -12
- package/dist/{parse-GmjecGct.mjs.map → parse-C_-6klII.mjs.map} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
- package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
- package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
- package/dist/{placeholder-BSKwzRe4.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +21 -2
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +18 -16
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugin-utils.mjs +8 -6
- package/dist/plugin-utils.mjs.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs → portable-text-sDj92Kxv.mjs} +1 -1
- package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
- package/dist/{preview-SSXNVPAC.mjs → preview-D4Jnbfx7.mjs} +2 -2
- package/dist/{preview-SSXNVPAC.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
- package/dist/{public-url-Danv47cS.mjs → public-url-DSGTnJFw.mjs} +5 -3
- package/dist/public-url-DSGTnJFw.mjs.map +1 -0
- package/dist/{query-1Cp6U9oo.mjs → query-DR73ZNfm.mjs} +15 -15
- package/dist/query-DR73ZNfm.mjs.map +1 -0
- package/dist/{schema-CX9cfNkZ.mjs → query-Di7DOmPV.mjs} +5 -10
- package/dist/query-Di7DOmPV.mjs.map +1 -0
- package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-CMj83JNW.mjs} +2 -2
- package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs → redirect-Botom7X6.mjs} +1 -1
- package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
- package/dist/{redirect-IyfNirgS.mjs → redirect-CgLPYflR.mjs} +11 -5
- package/dist/redirect-CgLPYflR.mjs.map +1 -0
- package/dist/{redirects-Bs1g42Ri.mjs → redirects-B7t9bKsL.mjs} +6 -6
- package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
- package/dist/{redirects-DXEXBAII.mjs → redirects-BBq3n2Rj.mjs} +10 -143
- package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
- package/dist/{registry-B57vp_X9.mjs → registry-FV15nLge.mjs} +99 -10
- package/dist/registry-FV15nLge.mjs.map +1 -0
- package/dist/relation-9M9j_UWo.mjs +334 -0
- package/dist/relation-9M9j_UWo.mjs.map +1 -0
- package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-5_avdrN_.mjs} +60 -4
- package/dist/relations-5_avdrN_.mjs.map +1 -0
- package/dist/relations-BKvO39-9.mjs +397 -0
- package/dist/relations-BKvO39-9.mjs.map +1 -0
- package/dist/{byline-fields-CHE8UStY.d.mts → relations-Bh8jlFsU.d.mts} +486 -31
- package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
- package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
- package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
- package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DzXYYI-n.mjs} +2 -2
- package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
- package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
- package/dist/{runner-DvFWoz8-.d.mts → runner-Dd8m8k9F.d.mts} +8 -2
- package/dist/runner-Dd8m8k9F.d.mts.map +1 -0
- package/dist/{runner-K8XK101B.mjs → runner-DfnZ5eUr.mjs} +355 -204
- package/dist/runner-DfnZ5eUr.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +4 -4
- package/dist/schema-BXxlHeAf.mjs +9 -0
- package/dist/schema-BXxlHeAf.mjs.map +1 -0
- package/dist/scopes-Bl4IwHA-.mjs +27 -0
- package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
- package/dist/{search-DZN2HZ-V.mjs → search-Bff-7jFt.mjs} +62 -12
- package/dist/search-Bff-7jFt.mjs.map +1 -0
- package/dist/{secrets-kp760LlD.mjs → secrets-CSwQIl4q.mjs} +4 -4
- package/dist/{secrets-kp760LlD.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
- package/dist/{sections-CpF5SaGr.mjs → sections-CwW4s1al.mjs} +3 -3
- package/dist/{sections-CpF5SaGr.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +23 -23
- package/dist/seo/index.d.mts +15 -2
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +22 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-DXu2UQnC.mjs → seo-2cmFHZns.mjs} +2 -2
- package/dist/{seo-DXu2UQnC.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
- package/dist/{seo-89-53DDs.mjs → seo-C3GDfT0V.mjs} +1 -1
- package/dist/{seo-89-53DDs.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
- package/dist/{service-DQmiBMzt.mjs → service-DkGTWGIi.mjs} +3 -3
- package/dist/{service-DQmiBMzt.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
- package/dist/{session-user-Cascbax7.mjs → session-user-DbHqKDKe.mjs} +1 -1
- package/dist/{session-user-Cascbax7.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
- package/dist/{settings-rZyHEcNT.mjs → settings-C4s8hFQm.mjs} +3 -3
- package/dist/{settings-rZyHEcNT.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
- package/dist/{settings-zhmdKyJQ.mjs → settings-CpA4lQFt.mjs} +6 -6
- package/dist/{settings-zhmdKyJQ.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
- package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-CdIlqloh.mjs} +2 -2
- package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
- package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
- package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-C2exrGAi.mjs} +2 -2
- package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
- package/dist/{site-url-BBfDTgZB.mjs → site-url-NGJT6NTU.mjs} +2 -2
- package/dist/{site-url-BBfDTgZB.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
- package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
- package/dist/snapshot-BdpUJKD-.mjs +216 -0
- package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
- package/dist/{ssrf-1g7usGBg.mjs → ssrf-CviKqWmq.mjs} +1 -1
- package/dist/{ssrf-1g7usGBg.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
- package/dist/state-xxv6ZTMv.mjs +128 -0
- package/dist/state-xxv6ZTMv.mjs.map +1 -0
- package/dist/{status-CqJQX1QN.mjs → status-COfycGIU.mjs} +1 -1
- package/dist/{status-CqJQX1QN.mjs.map → status-COfycGIU.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-Bs13SN-F.mjs → taxonomies-Ce49uIzY.mjs} +13 -9
- package/dist/taxonomies-Ce49uIzY.mjs.map +1 -0
- package/dist/{taxonomies-kH9ABDUF.mjs → taxonomies-DjSKBZpq.mjs} +115 -36
- package/dist/taxonomies-DjSKBZpq.mjs.map +1 -0
- package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-DfVooU4W.mjs} +60 -13
- package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
- package/dist/{tokens-BGT0TUUo.mjs → tokens-DVltpO2D.mjs} +2 -2
- package/dist/{tokens-BGT0TUUo.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
- package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
- package/dist/{transport-DPefPMcz.mjs → transport-CKrlqSpD.mjs} +1 -1
- package/dist/{transport-DPefPMcz.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
- package/dist/{transport-BMDWHSgZ.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
- package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
- package/dist/{types-CgvhU-hF.d.mts → types-B4vm81VH.d.mts} +1 -1
- package/dist/{types-CgvhU-hF.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
- package/dist/{types-ea9sAPck.d.mts → types-B97jg3aW.d.mts} +6 -1
- package/dist/{types-ea9sAPck.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
- package/dist/{types-Jo3UYd6b.mjs → types-BD40g7zz.mjs} +1 -1
- package/dist/{types-Jo3UYd6b.mjs.map → types-BD40g7zz.mjs.map} +1 -1
- package/dist/{types-DmHk7vAt.d.mts → types-BNfPHfay.d.mts} +1 -1
- package/dist/{types-DmHk7vAt.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
- package/dist/{types-BcLUUbbR.d.mts → types-BfYUPJdP.d.mts} +11 -3
- package/dist/{types-BcLUUbbR.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
- package/dist/{types-CGbYowGQ.d.mts → types-BvB7gDOD.d.mts} +90 -4
- package/dist/types-BvB7gDOD.d.mts.map +1 -0
- package/dist/{types-vgEWF18A.d.mts → types-C7U0HlEr.d.mts} +1 -1
- package/dist/{types-vgEWF18A.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
- package/dist/{types-CuW0zWDA.mjs → types-D1iJ3DpO.mjs} +3 -3
- package/dist/{types-CuW0zWDA.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
- package/dist/{types-_HFLRzTn.d.mts → types-DPKhI5ib.d.mts} +9 -1
- package/dist/types-DPKhI5ib.d.mts.map +1 -0
- package/dist/{types-g_aFIdW0.d.mts → types-Kmaxdarz.d.mts} +1 -1
- package/dist/{types-g_aFIdW0.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
- package/dist/{types-ClUkdbWb.d.mts → types-iVeZ5g6N.d.mts} +1 -1
- package/dist/{types-ClUkdbWb.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
- package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
- package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
- package/dist/{user-BjAOvU3Z.mjs → user-Bh-L1qo6.mjs} +3 -3
- package/dist/{user-BjAOvU3Z.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
- package/dist/{utils-BJXElxdw.mjs → utils-BbUgmeZG.mjs} +3 -3
- package/dist/{utils-BJXElxdw.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
- package/dist/{validate-Z1b86_3B.d.mts → validate-DULfgpJP.d.mts} +5 -5
- package/dist/{validate-Z1b86_3B.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
- package/dist/{validate-CWSnKVIJ.mjs → validate-V9nCwq_-.mjs} +3 -3
- package/dist/{validate-CWSnKVIJ.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
- package/dist/{validation-0l8-RYj4.mjs → validation-BsVUJfsP.mjs} +10 -10
- package/dist/{validation-0l8-RYj4.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
- package/dist/version-907opKac.mjs +7 -0
- package/dist/{version-qmeO1XZY.mjs.map → version-907opKac.mjs.map} +1 -1
- package/dist/{widgets-hWcIicX8.mjs → widgets-DGv1Z04V.mjs} +4 -4
- package/dist/{widgets-hWcIicX8.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
- package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +4 -4
- package/dist/{wxr-taxonomies-CNFcsNCr.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
- package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-B5prQ5M4.mjs} +3 -3
- package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
- package/package.json +12 -8
- package/src/api/authorize.ts +10 -1
- package/src/api/error.ts +5 -5
- package/src/api/errors.ts +25 -0
- package/src/api/handlers/backup.ts +312 -0
- package/src/api/handlers/content.ts +147 -3
- package/src/api/handlers/dashboard.ts +2 -0
- package/src/api/handlers/device-flow.ts +2 -3
- package/src/api/handlers/index.ts +22 -0
- package/src/api/handlers/marketplace.ts +38 -0
- package/src/api/handlers/media-upload.ts +210 -0
- package/src/api/handlers/media-usage.ts +289 -0
- package/src/api/handlers/oauth-authorization.ts +2 -6
- package/src/api/handlers/plugin-settings.ts +218 -0
- package/src/api/handlers/plugins.ts +41 -0
- package/src/api/handlers/registry.ts +39 -0
- package/src/api/handlers/relations.ts +474 -0
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/handlers/taxonomies.ts +26 -4
- package/src/api/handlers/validate-media-fields.ts +1 -1
- package/src/api/openapi/document.ts +72 -5
- package/src/api/parse.ts +2 -16
- package/src/api/public-url.ts +4 -2
- package/src/api/schemas/comments.ts +6 -0
- package/src/api/schemas/common.ts +6 -2
- package/src/api/schemas/content.ts +8 -0
- package/src/api/schemas/index.ts +2 -0
- package/src/api/schemas/media-usage.ts +120 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/api/schemas/relations.ts +109 -0
- package/src/api/schemas/search.ts +1 -0
- package/src/astro/integration/index.ts +39 -0
- package/src/astro/integration/routes.ts +40 -0
- package/src/astro/integration/runtime.ts +30 -0
- package/src/astro/integration/virtual-modules.ts +41 -7
- package/src/astro/integration/vite-config.ts +17 -1
- package/src/astro/middleware/auth.ts +70 -78
- package/src/astro/middleware/csp.ts +5 -2
- package/src/astro/middleware/request-context.ts +162 -20
- package/src/astro/middleware.ts +108 -40
- package/src/astro/public-plugin-api-routes.ts +2 -1
- package/src/astro/routes/PluginRegistry.tsx +5 -2
- package/src/astro/routes/admin.astro +56 -16
- package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
- package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -2
- package/src/astro/routes/api/admin/comments/index.ts +1 -2
- package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
- package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
- package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/index.ts +9 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
- package/src/astro/routes/api/auth/mode.ts +6 -14
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -5
- package/src/astro/routes/api/auth/oauth/[provider].ts +24 -7
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +95 -0
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +47 -0
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
- package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
- package/src/astro/routes/api/content/[collection]/index.ts +6 -8
- package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
- package/src/astro/routes/api/manifest.ts +2 -9
- package/src/astro/routes/api/mcp.ts +2 -1
- package/src/astro/routes/api/media/[id]/usage.ts +30 -0
- package/src/astro/routes/api/media/[id].ts +17 -6
- package/src/astro/routes/api/media/file/[...key].ts +8 -0
- package/src/astro/routes/api/media.ts +21 -2
- package/src/astro/routes/api/oauth/authorize.ts +2 -6
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
- package/src/astro/routes/api/relations/[id]/index.ts +84 -0
- package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
- package/src/astro/routes/api/relations/index.ts +56 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
- package/src/astro/routes/api/search/index.ts +2 -0
- package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
- package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
- package/src/astro/routes/api/settings/backups/export.ts +43 -0
- package/src/astro/routes/api/settings/backups/index.ts +76 -0
- package/src/astro/routes/api/setup/admin-verify.ts +8 -4
- package/src/astro/routes/api/setup/admin.ts +11 -4
- package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
- package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
- package/src/astro/types.ts +50 -2
- package/src/auth/api-tokens.ts +1 -0
- package/src/auth/oauth-state-store.ts +3 -0
- package/src/auth/providers/github-admin.tsx +5 -6
- package/src/auth/providers/google-admin.tsx +5 -6
- package/src/auth/scopes.ts +3 -9
- package/src/cli/client-factory.ts +0 -1
- package/src/cli/commands/bundle-utils.ts +50 -1
- package/src/cli/commands/bundle.ts +9 -2
- package/src/cli/commands/export-seed.ts +1 -10
- package/src/cli/commands/media.ts +127 -0
- package/src/client/index.ts +123 -2
- package/src/client/transport.ts +1 -1
- package/src/comments/service.ts +1 -1
- package/src/comments/turnstile.ts +64 -0
- package/src/components/BlockquoteGroup.astro +34 -0
- package/src/components/CommentForm.astro +12 -5
- package/src/components/EmDashHead.astro +31 -9
- package/src/components/InlinePortableTextEditor.tsx +88 -33
- package/src/components/PortableText.astro +7 -1
- package/src/components/index.ts +2 -0
- package/src/components/marks/Link.astro +5 -1
- package/src/components/portable-text-blockquote-group.ts +68 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
- package/src/database/dialect-helpers.ts +111 -3
- package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
- package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
- package/src/database/migrations/052_media_usage_read_index.ts +26 -0
- package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
- package/src/database/migrations/runner.ts +52 -6
- package/src/database/pg-migration-lock.ts +72 -0
- package/src/database/repositories/audit.ts +2 -1
- package/src/database/repositories/comment.ts +1 -1
- package/src/database/repositories/content.ts +270 -37
- package/src/database/repositories/media-usage.ts +250 -1
- package/src/database/repositories/media.ts +1 -1
- package/src/database/repositories/plugin-storage.ts +29 -32
- package/src/database/repositories/redirect.ts +14 -2
- package/src/database/repositories/relation.ts +130 -5
- package/src/database/repositories/taxonomy.ts +66 -8
- package/src/database/repositories/types.ts +8 -0
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +9 -0
- package/src/db/postgres.ts +5 -2
- package/src/emdash-runtime.ts +382 -70
- package/src/index.ts +6 -2
- package/src/loader.ts +293 -32
- package/src/mcp/server.ts +251 -8
- package/src/media/image-endpoint.ts +38 -2
- package/src/page/metadata.ts +27 -0
- package/src/plugin-types.ts +19 -0
- package/src/plugin-utils.ts +8 -6
- package/src/plugins/adapt-sandbox-entry.ts +30 -1
- package/src/plugins/context.ts +92 -0
- package/src/plugins/define-plugin.ts +17 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/manifest-schema.ts +30 -1
- package/src/plugins/routes.ts +27 -1
- package/src/plugins/sandbox/runner-options.ts +16 -0
- package/src/plugins/sandbox/types.ts +6 -1
- package/src/plugins/state.ts +17 -1
- package/src/plugins/storage-query.ts +67 -33
- package/src/plugins/types.ts +100 -0
- package/src/schema/byline-registry.ts +1 -1
- package/src/schema/registry.ts +141 -5
- package/src/search/fts-manager.ts +34 -0
- package/src/search/match.ts +50 -0
- package/src/search/query.ts +94 -9
- package/src/seed/apply.ts +28 -29
- package/src/seo/hreflang.ts +192 -0
- package/src/seo/index.ts +22 -4
- package/src/storage/types.ts +6 -0
- package/src/taxonomies/index.ts +62 -45
- package/src/taxonomies/term-counts.ts +117 -0
- package/src/utils/base64.ts +7 -2
- package/src/utils/db-errors.ts +3 -1
- package/src/virtual-modules.d.ts +14 -0
- package/src/visual-editing/editable.ts +41 -35
- package/src/visual-editing/toolbar-bootstrap.ts +120 -0
- package/src/visual-editing/toolbar.ts +47 -1
- package/dist/adapters-hUy8vOB-.d.mts.map +0 -1
- package/dist/api-DxFSorgk.mjs.map +0 -1
- package/dist/api-tokens-DsvvCtdh.mjs +0 -3
- package/dist/apply-CDJqIjPU.mjs.map +0 -1
- package/dist/authorize-Dz88F_Fw.mjs.map +0 -1
- package/dist/base64-CmWvODNW.mjs.map +0 -1
- package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
- package/dist/byline-fields-CHE8UStY.d.mts.map +0 -1
- package/dist/content-DhgEth4k.mjs.map +0 -1
- package/dist/content-refresh-Br4gMzh8.mjs.map +0 -1
- package/dist/context-BRIpHARC.mjs.map +0 -1
- package/dist/dashboard-EvEKF5en.mjs.map +0 -1
- package/dist/db-errors-CK46D-ly.mjs.map +0 -1
- package/dist/device-flow-CfGP18Uw.mjs.map +0 -1
- package/dist/dialect-helpers-DRI5pyY3.mjs +0 -110
- package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
- package/dist/error-CkAseSqZ.mjs.map +0 -1
- package/dist/index-B9sIxwe4.d.mts.map +0 -1
- package/dist/loader-CB6YHeul.mjs.map +0 -1
- package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
- package/dist/media-BrXIaMFN.mjs.map +0 -1
- package/dist/menus-b2T4clbO.mjs.map +0 -1
- package/dist/oauth-authorization-CXWkIGT4.mjs.map +0 -1
- package/dist/public-url-Danv47cS.mjs.map +0 -1
- package/dist/query-1Cp6U9oo.mjs.map +0 -1
- package/dist/redirect-IyfNirgS.mjs.map +0 -1
- package/dist/redirects-DXEXBAII.mjs.map +0 -1
- package/dist/registry-B57vp_X9.mjs.map +0 -1
- package/dist/runner-DvFWoz8-.d.mts.map +0 -1
- package/dist/runner-K8XK101B.mjs.map +0 -1
- package/dist/scheduled-publish-Drffrf2a.d.mts +0 -11
- package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
- package/dist/schema-CX9cfNkZ.mjs.map +0 -1
- package/dist/search-DZN2HZ-V.mjs.map +0 -1
- package/dist/taxonomies-Bs13SN-F.mjs.map +0 -1
- package/dist/taxonomies-kH9ABDUF.mjs.map +0 -1
- package/dist/taxonomy-BxGxZZdu.mjs.map +0 -1
- package/dist/types-CGbYowGQ.d.mts.map +0 -1
- package/dist/types-_HFLRzTn.d.mts.map +0 -1
- package/dist/version-qmeO1XZY.mjs +0 -7
- /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-BB__xfNM.mjs} +0 -0
- /package/dist/{types-DROWRxYV.mjs → types-CK0LxPUQ.mjs} +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import "../../../../../../after-B1IIdH3Y.mjs";
|
|
2
2
|
import { s as invalidateCommentObjectCache } from "../../../../../../object-cache-Bok5j2ae.mjs";
|
|
3
|
-
import "../../../../../../base64-
|
|
4
|
-
import "../../../../../../types-
|
|
5
|
-
import "../../../../../../comment-
|
|
6
|
-
import "../../../../../../options-
|
|
7
|
-
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-
|
|
8
|
-
import { n as parseBody, t as isParseError } from "../../../../../../parse-
|
|
9
|
-
import
|
|
10
|
-
import "../../../../../../
|
|
11
|
-
import "../../../../../../
|
|
3
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
4
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
5
|
+
import "../../../../../../comment-DPT0WKyd.mjs";
|
|
6
|
+
import "../../../../../../options-BlmBHTvX.mjs";
|
|
7
|
+
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
8
|
+
import { n as parseBody, t as isParseError } from "../../../../../../parse-C_-6klII.mjs";
|
|
9
|
+
import "../../../../../../media-kIV1IxFf.mjs";
|
|
10
|
+
import { bt as createReactionBody } from "../../../../../../redirects-BBq3n2Rj.mjs";
|
|
11
|
+
import "../../../../../../relations-5_avdrN_.mjs";
|
|
12
|
+
import "../../../../../../status-COfycGIU.mjs";
|
|
12
13
|
import "../../../../../../api/schemas/index.mjs";
|
|
13
|
-
import { t as extractRequestMeta } from "../../../../../../request-meta-
|
|
14
|
-
import { t as CommentReactionRepository } from "../../../../../../comment-reaction-
|
|
15
|
-
import { i as resolveSecretsCached } from "../../../../../../secrets-
|
|
16
|
-
import { c as hashIp } from "../../../../../../comments-
|
|
14
|
+
import { t as extractRequestMeta } from "../../../../../../request-meta-DzXYYI-n.mjs";
|
|
15
|
+
import { t as CommentReactionRepository } from "../../../../../../comment-reaction-C65MldIB.mjs";
|
|
16
|
+
import { i as resolveSecretsCached } from "../../../../../../secrets-CSwQIl4q.mjs";
|
|
17
|
+
import { c as hashIp } from "../../../../../../comments-Bz6sCbgD.mjs";
|
|
17
18
|
|
|
18
19
|
//#region src/api/handlers/comment-reactions.ts
|
|
19
20
|
/** Max reactions a single voter may register per window before throttling. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactions.mjs","names":[],"sources":["../../../../../../../src/api/handlers/comment-reactions.ts","../../../../../../../src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts"],"sourcesContent":["/**\n * Comment reaction handlers (Tier 1 of the best-in-class comments RFC).\n *\n * Business logic for toggling reactions and reading aggregate counts. Route\n * files stay thin wrappers; these return `ApiResult<T>`.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport {\n\tCommentReactionRepository,\n\ttype ReactionCounts,\n} from \"#db/repositories/comment-reaction.js\";\nimport type { Database } from \"#db/types.js\";\n\nimport { invalidateCommentObjectCache } from \"../../object-cache/index.js\";\nimport type { ApiResult } from \"../types.js\";\n\n/** Max reactions a single voter may register per window before throttling. */\nconst REACTION_RATE_LIMIT = 30;\nconst REACTION_RATE_WINDOW_MINUTES = 10;\n\n/**\n * Reactions the system accepts. Positive-only for now (matches the shipped\n * widget); kept as an allowlist so a voter can't spam arbitrary reaction\n * strings and bloat a comment's count map. Extend (or make configurable) as\n * the UI grows.\n */\nconst ALLOWED_REACTIONS: ReadonlySet<string> = new Set([\"like\"]);\n\nexport interface ReactionToggleResult {\n\tcommentId: string;\n\treaction: string;\n\t/** true if the reaction was added, false if an existing one was removed */\n\treacted: boolean;\n\t/** updated counts for this comment after the toggle */\n\tcounts: ReactionCounts;\n}\n\nexport interface ReactionCountsResult {\n\t/** comment id -> reaction counts */\n\treactions: Record<string, ReactionCounts>;\n\t/** comment id -> reactions the current voter has active (omitted if anonymous) */\n\tviewer?: Record<string, string[]>;\n}\n\n/**\n * Toggle a reaction for a voter on an approved comment belonging to the given\n * content item. Rate-limited per voter.\n */\nexport async function handleReactionToggle(\n\tdb: Kysely<Database>,\n\tparams: {\n\t\tcollection: string;\n\t\tcontentId: string;\n\t\tcommentId: string;\n\t\treaction: string;\n\t\tvoterHash: string;\n\t},\n): Promise<ApiResult<ReactionToggleResult>> {\n\ttry {\n\t\tconst { collection, contentId, commentId, reaction, voterHash } = params;\n\n\t\tif (!ALLOWED_REACTIONS.has(reaction)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: \"Unsupported reaction\" },\n\t\t\t};\n\t\t}\n\n\t\t// The comment must exist, be approved, and belong to this content item.\n\t\tconst comment = await db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select([\"id\", \"status\"])\n\t\t\t.where(\"id\", \"=\", commentId)\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.executeTakeFirst();\n\n\t\tif (!comment) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Comment not found\" } };\n\t\t}\n\t\tif (comment.status !== \"approved\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"COMMENT_NOT_APPROVED\", message: \"Cannot react to this comment\" },\n\t\t\t};\n\t\t}\n\n\t\tconst repo = new CommentReactionRepository(db);\n\n\t\tconst recent = await repo.countRecentByVoter(voterHash, REACTION_RATE_WINDOW_MINUTES);\n\t\tif (recent >= REACTION_RATE_LIMIT) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"RATE_LIMITED\", message: \"Too many reactions. Please try again later.\" },\n\t\t\t};\n\t\t}\n\n\t\tconst { reacted } = await repo.toggle({ commentId, reaction, voterHash });\n\t\tconst countsMap = await repo.countsForComments([commentId]);\n\n\t\t// Reaction counts (and `best` ordering) are folded into cached getComments\n\t\t// reads, so a toggle must orphan them.\n\t\tinvalidateCommentObjectCache();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { commentId, reaction, reacted, counts: countsMap.get(commentId) ?? {} },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"REACTION_TOGGLE_ERROR\", message: \"Failed to toggle reaction\" },\n\t\t};\n\t}\n}\n\n/**\n * Read aggregate reaction counts for every approved comment on a content item,\n * plus (optionally) which reactions the current voter has active.\n */\nexport async function handleReactionCounts(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tcontentId: string,\n\tvoterHash?: string,\n): Promise<ApiResult<ReactionCountsResult>> {\n\ttry {\n\t\tconst comments = await db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.where(\"status\", \"=\", \"approved\")\n\t\t\t.execute();\n\n\t\tconst ids = comments.map((c) => c.id);\n\t\tconst repo = new CommentReactionRepository(db);\n\n\t\tconst countsMap = await repo.countsForComments(ids);\n\t\tconst reactions: Record<string, ReactionCounts> = {};\n\t\tfor (const [id, counts] of countsMap) {\n\t\t\treactions[id] = counts;\n\t\t}\n\n\t\tconst data: ReactionCountsResult = { reactions };\n\n\t\tif (voterHash) {\n\t\t\tconst viewerMap = await repo.viewerReactions(ids, voterHash);\n\t\t\tconst viewer: Record<string, string[]> = {};\n\t\t\tfor (const [id, list] of viewerMap) {\n\t\t\t\tviewer[id] = list;\n\t\t\t}\n\t\t\tdata.viewer = viewer;\n\t\t}\n\n\t\treturn { success: true, data };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"REACTION_COUNTS_ERROR\", message: \"Failed to read reactions\" },\n\t\t};\n\t}\n}\n","/**\n * Public comment reaction endpoints (Tier 1 of the best-in-class comments RFC).\n *\n * GET /_emdash/api/comments/:collection/:contentId/reactions\n * - Aggregate reaction counts for the content's approved comments, plus the\n * current visitor's active reactions.\n * POST /_emdash/api/comments/:collection/:contentId/reactions\n * - Toggle a reaction on a comment. Public, honeypot- and rate-limit-gated.\n *\n * Inherits the `/_emdash/api/comments/` public prefix (no auth); the POST still\n * requires the `X-EmDash-Request: 1` CSRF header like the comment POST.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleReactionCounts, handleReactionToggle } from \"#api/handlers/comment-reactions.js\";\nimport { hashIp } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { createReactionBody } from \"#api/schemas.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\nimport { extractRequestMeta } from \"#plugins/request-meta.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash } = locals;\n\tconst { collection, contentId } = params;\n\n\tif (!collection || !contentId) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection and content ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\t// Salted voter hash from request IP (same primitive as comment ip_hash).\n\t\t// Behind Cloudflare (CF-Connecting-IP) or a configured trusted proxy this\n\t\t// is per-visitor. Without a trusted IP it collapses to a shared \"unknown\"\n\t\t// bucket, so reaction dedup degrades for those visitors — a real\n\t\t// per-visitor token is Tier 2 (visitor identity). Operators should set\n\t\t// trustedProxyHeaders; see the comment ingest route for the same note.\n\t\tconst meta = extractRequestMeta(request, emdash.config);\n\t\tlet voterHash = \"unknown\";\n\t\tif (meta.ip) {\n\t\t\tconst { ipSalt } = await resolveSecretsCached(emdash.db);\n\t\t\tvoterHash = await hashIp(meta.ip, ipSalt);\n\t\t}\n\n\t\tconst result = await handleReactionCounts(emdash.db, collection, contentId, voterHash);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to read reactions\", \"REACTION_COUNTS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash } = locals;\n\tconst { collection, contentId } = params;\n\n\tif (!collection || !contentId) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection and content ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\tconst body = await parseBody(request, createReactionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Anti-spam: honeypot — hidden field filled only by bots. Silently accept.\n\t\tif (body.website_url) {\n\t\t\treturn apiSuccess({ reacted: false, counts: {} });\n\t\t}\n\n\t\tconst meta = extractRequestMeta(request, emdash.config);\n\t\tlet voterHash = \"unknown\";\n\t\tif (meta.ip) {\n\t\t\tconst { ipSalt } = await resolveSecretsCached(emdash.db);\n\t\t\tvoterHash = await hashIp(meta.ip, ipSalt);\n\t\t}\n\n\t\tconst result = await handleReactionToggle(emdash.db, {\n\t\t\tcollection,\n\t\t\tcontentId,\n\t\t\tcommentId: body.commentId,\n\t\t\treaction: body.reaction,\n\t\t\tvoterHash,\n\t\t});\n\n\t\treturn unwrapResult(result, 200);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to toggle reaction\", \"REACTION_TOGGLE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAM,sBAAsB;AAC5B,MAAM,+BAA+B;;;;;;;AAQrC,MAAM,oBAAyC,IAAI,IAAI,CAAC,OAAO,CAAC;;;;;AAsBhE,eAAsB,qBACrB,IACA,QAO2C;AAC3C,KAAI;EACH,MAAM,EAAE,YAAY,WAAW,WAAW,UAAU,cAAc;AAElE,MAAI,CAAC,kBAAkB,IAAI,SAAS,CACnC,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAoB,SAAS;IAAwB;GACpE;EAIF,MAAM,UAAU,MAAM,GACpB,WAAW,mBAAmB,CAC9B,OAAO,CAAC,MAAM,SAAS,CAAC,CACxB,MAAM,MAAM,KAAK,UAAU,CAC3B,MAAM,cAAc,KAAK,WAAW,CACpC,MAAM,cAAc,KAAK,UAAU,CACnC,kBAAkB;AAEpB,MAAI,CAAC,QACJ,QAAO;GAAE,SAAS;GAAO,OAAO;IAAE,MAAM;IAAa,SAAS;IAAqB;GAAE;AAEtF,MAAI,QAAQ,WAAW,WACtB,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAwB,SAAS;IAAgC;GAChF;EAGF,MAAM,OAAO,IAAI,0BAA0B,GAAG;AAG9C,MADe,MAAM,KAAK,mBAAmB,WAAW,6BAA6B,IACvE,oBACb,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAgB,SAAS;IAA+C;GACvF;EAGF,MAAM,EAAE,YAAY,MAAM,KAAK,OAAO;GAAE;GAAW;GAAU;GAAW,CAAC;EACzE,MAAM,YAAY,MAAM,KAAK,kBAAkB,CAAC,UAAU,CAAC;AAI3D,gCAA8B;AAE9B,SAAO;GACN,SAAS;GACT,MAAM;IAAE;IAAW;IAAU;IAAS,QAAQ,UAAU,IAAI,UAAU,IAAI,EAAE;IAAE;GAC9E;SACM;AACP,SAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAyB,SAAS;IAA6B;GAC9E;;;;;;;AAQH,eAAsB,qBACrB,IACA,YACA,WACA,WAC2C;AAC3C,KAAI;EASH,MAAM,OARW,MAAM,GACrB,WAAW,mBAAmB,CAC9B,OAAO,KAAK,CACZ,MAAM,cAAc,KAAK,WAAW,CACpC,MAAM,cAAc,KAAK,UAAU,CACnC,MAAM,UAAU,KAAK,WAAW,CAChC,SAAS,EAEU,KAAK,MAAM,EAAE,GAAG;EACrC,MAAM,OAAO,IAAI,0BAA0B,GAAG;EAE9C,MAAM,YAAY,MAAM,KAAK,kBAAkB,IAAI;EACnD,MAAM,YAA4C,EAAE;AACpD,OAAK,MAAM,CAAC,IAAI,WAAW,UAC1B,WAAU,MAAM;EAGjB,MAAM,OAA6B,EAAE,WAAW;AAEhD,MAAI,WAAW;GACd,MAAM,YAAY,MAAM,KAAK,gBAAgB,KAAK,UAAU;GAC5D,MAAM,SAAmC,EAAE;AAC3C,QAAK,MAAM,CAAC,IAAI,SAAS,UACxB,QAAO,MAAM;AAEd,QAAK,SAAS;;AAGf,SAAO;GAAE,SAAS;GAAM;GAAM;SACvB;AACP,SAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAyB,SAAS;IAA4B;GAC7E;;;;;;AC3IH,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,WAAW;CACnB,MAAM,EAAE,YAAY,cAAc;AAElC,KAAI,CAAC,cAAc,CAAC,UACnB,QAAO,SAAS,oBAAoB,sCAAsC,IAAI;CAG/E,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAElB,KAAI;EAOH,MAAM,OAAO,mBAAmB,SAAS,OAAO,OAAO;EACvD,IAAI,YAAY;AAChB,MAAI,KAAK,IAAI;GACZ,MAAM,EAAE,WAAW,MAAM,qBAAqB,OAAO,GAAG;AACxD,eAAY,MAAM,OAAO,KAAK,IAAI,OAAO;;AAI1C,SAAO,aADQ,MAAM,qBAAqB,OAAO,IAAI,YAAY,WAAW,UAAU,CAC3D;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,wBAAwB;;;AAIhF,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,WAAW;CACnB,MAAM,EAAE,YAAY,cAAc;AAElC,KAAI,CAAC,cAAc,CAAC,UACnB,QAAO,SAAS,oBAAoB,sCAAsC,IAAI;CAG/E,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAElB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,mBAAmB;AACzD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,MAAI,KAAK,YACR,QAAO,WAAW;GAAE,SAAS;GAAO,QAAQ,EAAE;GAAE,CAAC;EAGlD,MAAM,OAAO,mBAAmB,SAAS,OAAO,OAAO;EACvD,IAAI,YAAY;AAChB,MAAI,KAAK,IAAI;GACZ,MAAM,EAAE,WAAW,MAAM,qBAAqB,OAAO,GAAG;AACxD,eAAY,MAAM,OAAO,KAAK,IAAI,OAAO;;AAW1C,SAAO,aARQ,MAAM,qBAAqB,OAAO,IAAI;GACpD;GACA;GACA,WAAW,KAAK;GAChB,UAAU,KAAK;GACf;GACA,CAAC,EAE0B,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,wBAAwB"}
|
|
1
|
+
{"version":3,"file":"reactions.mjs","names":[],"sources":["../../../../../../../src/api/handlers/comment-reactions.ts","../../../../../../../src/astro/routes/api/comments/[collection]/[contentId]/reactions.ts"],"sourcesContent":["/**\n * Comment reaction handlers (Tier 1 of the best-in-class comments RFC).\n *\n * Business logic for toggling reactions and reading aggregate counts. Route\n * files stay thin wrappers; these return `ApiResult<T>`.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport {\n\tCommentReactionRepository,\n\ttype ReactionCounts,\n} from \"#db/repositories/comment-reaction.js\";\nimport type { Database } from \"#db/types.js\";\n\nimport { invalidateCommentObjectCache } from \"../../object-cache/index.js\";\nimport type { ApiResult } from \"../types.js\";\n\n/** Max reactions a single voter may register per window before throttling. */\nconst REACTION_RATE_LIMIT = 30;\nconst REACTION_RATE_WINDOW_MINUTES = 10;\n\n/**\n * Reactions the system accepts. Positive-only for now (matches the shipped\n * widget); kept as an allowlist so a voter can't spam arbitrary reaction\n * strings and bloat a comment's count map. Extend (or make configurable) as\n * the UI grows.\n */\nconst ALLOWED_REACTIONS: ReadonlySet<string> = new Set([\"like\"]);\n\nexport interface ReactionToggleResult {\n\tcommentId: string;\n\treaction: string;\n\t/** true if the reaction was added, false if an existing one was removed */\n\treacted: boolean;\n\t/** updated counts for this comment after the toggle */\n\tcounts: ReactionCounts;\n}\n\nexport interface ReactionCountsResult {\n\t/** comment id -> reaction counts */\n\treactions: Record<string, ReactionCounts>;\n\t/** comment id -> reactions the current voter has active (omitted if anonymous) */\n\tviewer?: Record<string, string[]>;\n}\n\n/**\n * Toggle a reaction for a voter on an approved comment belonging to the given\n * content item. Rate-limited per voter.\n */\nexport async function handleReactionToggle(\n\tdb: Kysely<Database>,\n\tparams: {\n\t\tcollection: string;\n\t\tcontentId: string;\n\t\tcommentId: string;\n\t\treaction: string;\n\t\tvoterHash: string;\n\t},\n): Promise<ApiResult<ReactionToggleResult>> {\n\ttry {\n\t\tconst { collection, contentId, commentId, reaction, voterHash } = params;\n\n\t\tif (!ALLOWED_REACTIONS.has(reaction)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: \"Unsupported reaction\" },\n\t\t\t};\n\t\t}\n\n\t\t// The comment must exist, be approved, and belong to this content item.\n\t\tconst comment = await db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select([\"id\", \"status\"])\n\t\t\t.where(\"id\", \"=\", commentId)\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.executeTakeFirst();\n\n\t\tif (!comment) {\n\t\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"Comment not found\" } };\n\t\t}\n\t\tif (comment.status !== \"approved\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"COMMENT_NOT_APPROVED\", message: \"Cannot react to this comment\" },\n\t\t\t};\n\t\t}\n\n\t\tconst repo = new CommentReactionRepository(db);\n\n\t\tconst recent = await repo.countRecentByVoter(voterHash, REACTION_RATE_WINDOW_MINUTES);\n\t\tif (recent >= REACTION_RATE_LIMIT) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"RATE_LIMITED\", message: \"Too many reactions. Please try again later.\" },\n\t\t\t};\n\t\t}\n\n\t\tconst { reacted } = await repo.toggle({ commentId, reaction, voterHash });\n\t\tconst countsMap = await repo.countsForComments([commentId]);\n\n\t\t// Reaction counts (and `best` ordering) are folded into cached getComments\n\t\t// reads, so a toggle must orphan them.\n\t\tinvalidateCommentObjectCache();\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: { commentId, reaction, reacted, counts: countsMap.get(commentId) ?? {} },\n\t\t};\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"REACTION_TOGGLE_ERROR\", message: \"Failed to toggle reaction\" },\n\t\t};\n\t}\n}\n\n/**\n * Read aggregate reaction counts for every approved comment on a content item,\n * plus (optionally) which reactions the current voter has active.\n */\nexport async function handleReactionCounts(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tcontentId: string,\n\tvoterHash?: string,\n): Promise<ApiResult<ReactionCountsResult>> {\n\ttry {\n\t\tconst comments = await db\n\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t.select(\"id\")\n\t\t\t.where(\"collection\", \"=\", collection)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.where(\"status\", \"=\", \"approved\")\n\t\t\t.execute();\n\n\t\tconst ids = comments.map((c) => c.id);\n\t\tconst repo = new CommentReactionRepository(db);\n\n\t\tconst countsMap = await repo.countsForComments(ids);\n\t\tconst reactions: Record<string, ReactionCounts> = {};\n\t\tfor (const [id, counts] of countsMap) {\n\t\t\treactions[id] = counts;\n\t\t}\n\n\t\tconst data: ReactionCountsResult = { reactions };\n\n\t\tif (voterHash) {\n\t\t\tconst viewerMap = await repo.viewerReactions(ids, voterHash);\n\t\t\tconst viewer: Record<string, string[]> = {};\n\t\t\tfor (const [id, list] of viewerMap) {\n\t\t\t\tviewer[id] = list;\n\t\t\t}\n\t\t\tdata.viewer = viewer;\n\t\t}\n\n\t\treturn { success: true, data };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"REACTION_COUNTS_ERROR\", message: \"Failed to read reactions\" },\n\t\t};\n\t}\n}\n","/**\n * Public comment reaction endpoints (Tier 1 of the best-in-class comments RFC).\n *\n * GET /_emdash/api/comments/:collection/:contentId/reactions\n * - Aggregate reaction counts for the content's approved comments, plus the\n * current visitor's active reactions.\n * POST /_emdash/api/comments/:collection/:contentId/reactions\n * - Toggle a reaction on a comment. Public, honeypot- and rate-limit-gated.\n *\n * Inherits the `/_emdash/api/comments/` public prefix (no auth); the POST still\n * requires the `X-EmDash-Request: 1` CSRF header like the comment POST.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { apiError, apiSuccess, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleReactionCounts, handleReactionToggle } from \"#api/handlers/comment-reactions.js\";\nimport { hashIp } from \"#api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { createReactionBody } from \"#api/schemas.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\nimport { extractRequestMeta } from \"#plugins/request-meta.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash } = locals;\n\tconst { collection, contentId } = params;\n\n\tif (!collection || !contentId) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection and content ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\t// Salted voter hash from request IP (same primitive as comment ip_hash).\n\t\t// Behind Cloudflare (CF-Connecting-IP) or a configured trusted proxy this\n\t\t// is per-visitor. Without a trusted IP it collapses to a shared \"unknown\"\n\t\t// bucket, so reaction dedup degrades for those visitors — a real\n\t\t// per-visitor token is Tier 2 (visitor identity). Operators should set\n\t\t// trustedProxyHeaders; see the comment ingest route for the same note.\n\t\tconst meta = extractRequestMeta(request, emdash.config);\n\t\tlet voterHash = \"unknown\";\n\t\tif (meta.ip) {\n\t\t\tconst { ipSalt } = await resolveSecretsCached(emdash.db);\n\t\t\tvoterHash = await hashIp(meta.ip, ipSalt);\n\t\t}\n\n\t\tconst result = await handleReactionCounts(emdash.db, collection, contentId, voterHash);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to read reactions\", \"REACTION_COUNTS_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash } = locals;\n\tconst { collection, contentId } = params;\n\n\tif (!collection || !contentId) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection and content ID required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\n\ttry {\n\t\tconst body = await parseBody(request, createReactionBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Anti-spam: honeypot — hidden field filled only by bots. Silently accept.\n\t\tif (body.website_url) {\n\t\t\treturn apiSuccess({ reacted: false, counts: {} });\n\t\t}\n\n\t\tconst meta = extractRequestMeta(request, emdash.config);\n\t\tlet voterHash = \"unknown\";\n\t\tif (meta.ip) {\n\t\t\tconst { ipSalt } = await resolveSecretsCached(emdash.db);\n\t\t\tvoterHash = await hashIp(meta.ip, ipSalt);\n\t\t}\n\n\t\tconst result = await handleReactionToggle(emdash.db, {\n\t\t\tcollection,\n\t\t\tcontentId,\n\t\t\tcommentId: body.commentId,\n\t\t\treaction: body.reaction,\n\t\t\tvoterHash,\n\t\t});\n\n\t\treturn unwrapResult(result, 200);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to toggle reaction\", \"REACTION_TOGGLE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,MAAM,sBAAsB;AAC5B,MAAM,+BAA+B;;;;;;;AAQrC,MAAM,oBAAyC,IAAI,IAAI,CAAC,OAAO,CAAC;;;;;AAsBhE,eAAsB,qBACrB,IACA,QAO2C;AAC3C,KAAI;EACH,MAAM,EAAE,YAAY,WAAW,WAAW,UAAU,cAAc;AAElE,MAAI,CAAC,kBAAkB,IAAI,SAAS,CACnC,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAoB,SAAS;IAAwB;GACpE;EAIF,MAAM,UAAU,MAAM,GACpB,WAAW,mBAAmB,CAC9B,OAAO,CAAC,MAAM,SAAS,CAAC,CACxB,MAAM,MAAM,KAAK,UAAU,CAC3B,MAAM,cAAc,KAAK,WAAW,CACpC,MAAM,cAAc,KAAK,UAAU,CACnC,kBAAkB;AAEpB,MAAI,CAAC,QACJ,QAAO;GAAE,SAAS;GAAO,OAAO;IAAE,MAAM;IAAa,SAAS;IAAqB;GAAE;AAEtF,MAAI,QAAQ,WAAW,WACtB,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAwB,SAAS;IAAgC;GAChF;EAGF,MAAM,OAAO,IAAI,0BAA0B,GAAG;AAG9C,MADe,MAAM,KAAK,mBAAmB,WAAW,6BAA6B,IACvE,oBACb,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAgB,SAAS;IAA+C;GACvF;EAGF,MAAM,EAAE,YAAY,MAAM,KAAK,OAAO;GAAE;GAAW;GAAU;GAAW,CAAC;EACzE,MAAM,YAAY,MAAM,KAAK,kBAAkB,CAAC,UAAU,CAAC;AAI3D,gCAA8B;AAE9B,SAAO;GACN,SAAS;GACT,MAAM;IAAE;IAAW;IAAU;IAAS,QAAQ,UAAU,IAAI,UAAU,IAAI,EAAE;IAAE;GAC9E;SACM;AACP,SAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAyB,SAAS;IAA6B;GAC9E;;;;;;;AAQH,eAAsB,qBACrB,IACA,YACA,WACA,WAC2C;AAC3C,KAAI;EASH,MAAM,OARW,MAAM,GACrB,WAAW,mBAAmB,CAC9B,OAAO,KAAK,CACZ,MAAM,cAAc,KAAK,WAAW,CACpC,MAAM,cAAc,KAAK,UAAU,CACnC,MAAM,UAAU,KAAK,WAAW,CAChC,SAAS,EAEU,KAAK,MAAM,EAAE,GAAG;EACrC,MAAM,OAAO,IAAI,0BAA0B,GAAG;EAE9C,MAAM,YAAY,MAAM,KAAK,kBAAkB,IAAI;EACnD,MAAM,YAA4C,EAAE;AACpD,OAAK,MAAM,CAAC,IAAI,WAAW,UAC1B,WAAU,MAAM;EAGjB,MAAM,OAA6B,EAAE,WAAW;AAEhD,MAAI,WAAW;GACd,MAAM,YAAY,MAAM,KAAK,gBAAgB,KAAK,UAAU;GAC5D,MAAM,SAAmC,EAAE;AAC3C,QAAK,MAAM,CAAC,IAAI,SAAS,UACxB,QAAO,MAAM;AAEd,QAAK,SAAS;;AAGf,SAAO;GAAE,SAAS;GAAM;GAAM;SACvB;AACP,SAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAyB,SAAS;IAA4B;GAC7E;;;;;;AC3IH,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,WAAW;CACnB,MAAM,EAAE,YAAY,cAAc;AAElC,KAAI,CAAC,cAAc,CAAC,UACnB,QAAO,SAAS,oBAAoB,sCAAsC,IAAI;CAG/E,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAElB,KAAI;EAOH,MAAM,OAAO,mBAAmB,SAAS,OAAO,OAAO;EACvD,IAAI,YAAY;AAChB,MAAI,KAAK,IAAI;GACZ,MAAM,EAAE,WAAW,MAAM,qBAAqB,OAAO,GAAG;AACxD,eAAY,MAAM,OAAO,KAAK,IAAI,OAAO;;AAI1C,SAAO,aADQ,MAAM,qBAAqB,OAAO,IAAI,YAAY,WAAW,UAAU,CAC3D;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,wBAAwB;;;AAIhF,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,WAAW;CACnB,MAAM,EAAE,YAAY,cAAc;AAElC,KAAI,CAAC,cAAc,CAAC,UACnB,QAAO,SAAS,oBAAoB,sCAAsC,IAAI;CAG/E,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;AAElB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,mBAAmB;AACzD,MAAI,aAAa,KAAK,CAAE,QAAO;AAG/B,MAAI,KAAK,YACR,QAAO,WAAW;GAAE,SAAS;GAAO,QAAQ,EAAE;GAAE,CAAC;EAGlD,MAAM,OAAO,mBAAmB,SAAS,OAAO,OAAO;EACvD,IAAI,YAAY;AAChB,MAAI,KAAK,IAAI;GACZ,MAAM,EAAE,WAAW,MAAM,qBAAqB,OAAO,GAAG;AACxD,eAAY,MAAM,OAAO,KAAK,IAAI,OAAO;;AAW1C,SAAO,aARQ,MAAM,qBAAqB,OAAO,IAAI;GACpD;GACA;GACA,WAAW,KAAK;GAChB,UAAU,KAAK;GACf;GACA,CAAC,EAE0B,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,6BAA6B,wBAAwB"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import { a as unwrapResult, t as apiError } from "../../../../../../error-
|
|
4
|
-
import {
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
4
|
+
import { r as requirePerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/astro/routes/api/content/[collection]/[id]/compare.ts
|
|
7
7
|
const prerender = false;
|
|
8
8
|
const GET = async ({ params, locals }) => {
|
|
9
9
|
const { emdash, user } = locals;
|
|
10
|
+
if (!emdash?.handleContentCompare) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
10
11
|
const denied = requirePerm(user, "content:read_drafts");
|
|
11
12
|
if (denied) return denied;
|
|
12
13
|
const collection = params.collection;
|
|
13
14
|
const id = params.id;
|
|
14
|
-
if (!emdash?.handleContentCompare) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
15
15
|
return unwrapResult(await emdash.handleContentCompare(collection, id));
|
|
16
16
|
};
|
|
17
17
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/compare.ts"],"sourcesContent":["/**\n * Compare live and draft revisions\n *\n * GET /_emdash/api/content/{collection}/{id}/compare\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"content:read_drafts\");\n\tif (denied) return denied;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\
|
|
1
|
+
{"version":3,"file":"compare.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/compare.ts"],"sourcesContent":["/**\n * Compare live and draft revisions\n *\n * GET /_emdash/api/content/{collection}/{id}/compare\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tif (!emdash?.handleContentCompare) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst denied = requirePerm(user, \"content:read_drafts\");\n\tif (denied) return denied;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tconst result = await emdash.handleContentCompare(collection, id);\n\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;AAWA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,aAAa;CAC1D,MAAM,EAAE,QAAQ,SAAS;AACzB,KAAI,CAAC,QAAQ,qBACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpE,MAAM,SAAS,YAAY,MAAM,sBAAsB;AACvD,KAAI,OAAQ,QAAO;CACnB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;AAIlB,QAAO,aAFQ,MAAM,OAAO,qBAAqB,YAAY,GAAG,CAErC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { n as mapErrorStatus } from "../../../../../../errors-DtEXIQQV.mjs";
|
|
4
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
5
|
+
import { n as requireOwnerPerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
5
6
|
|
|
6
7
|
//#region src/astro/routes/api/content/[collection]/[id]/discard-draft.ts
|
|
7
8
|
const prerender = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discard-draft.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/discard-draft.ts"],"sourcesContent":["/**\n * Discard draft changes - reverts to live version\n *\n * POST /_emdash/api/content/{collection}/{id}/discard-draft\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, locals, url, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentDiscardDraft || !emdash?.handleContentGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst locale = url.searchParams.get(\"locale\") || undefined;\n\n\t// Fetch item to check ownership\n\tconst existing = await emdash.handleContentGet(collection, id, locale);\n\tif (!existing.success) {\n\t\treturn apiError(\n\t\t\texisting.error?.code ?? \"UNKNOWN_ERROR\",\n\t\t\texisting.error?.message ?? \"Unknown error\",\n\t\t\tmapErrorStatus(existing.error?.code),\n\t\t);\n\t}\n\tconst existingData =\n\t\texisting.data && typeof existing.data === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above\n\t\t\t\t(existing.data as Record<string, unknown>)\n\t\t\t: undefined;\n\t// Handler returns { item, _rev } — extract the item for ownership check\n\tconst existingItem =\n\t\texistingData?.item && typeof existingData.item === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\t(existingData.item as Record<string, unknown>)\n\t\t\t: existingData;\n\tconst authorId = typeof existingItem?.authorId === \"string\" ? existingItem.authorId : \"\";\n\tconst denied = requireOwnerPerm(user, authorId, \"content:edit_own\", \"content:edit_any\");\n\tif (denied) return denied;\n\n\tconst resolvedId = typeof existingItem?.id === \"string\" ? existingItem.id : id;\n\n\tconst result = await emdash.handleContentDiscardDraft(collection, resolvedId);\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection, resolvedId] });\n\n\treturn unwrapResult(result);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"discard-draft.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/discard-draft.ts"],"sourcesContent":["/**\n * Discard draft changes - reverts to live version\n *\n * POST /_emdash/api/content/{collection}/{id}/discard-draft\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, locals, url, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentDiscardDraft || !emdash?.handleContentGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst locale = url.searchParams.get(\"locale\") || undefined;\n\n\t// Fetch item to check ownership\n\tconst existing = await emdash.handleContentGet(collection, id, locale);\n\tif (!existing.success) {\n\t\treturn apiError(\n\t\t\texisting.error?.code ?? \"UNKNOWN_ERROR\",\n\t\t\texisting.error?.message ?? \"Unknown error\",\n\t\t\tmapErrorStatus(existing.error?.code),\n\t\t);\n\t}\n\tconst existingData =\n\t\texisting.data && typeof existing.data === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above\n\t\t\t\t(existing.data as Record<string, unknown>)\n\t\t\t: undefined;\n\t// Handler returns { item, _rev } — extract the item for ownership check\n\tconst existingItem =\n\t\texistingData?.item && typeof existingData.item === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\t(existingData.item as Record<string, unknown>)\n\t\t\t: existingData;\n\tconst authorId = typeof existingItem?.authorId === \"string\" ? existingItem.authorId : \"\";\n\tconst denied = requireOwnerPerm(user, authorId, \"content:edit_own\", \"content:edit_any\");\n\tif (denied) return denied;\n\n\tconst resolvedId = typeof existingItem?.id === \"string\" ? existingItem.id : id;\n\n\tconst result = await emdash.handleContentDiscardDraft(collection, resolvedId);\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection, resolvedId] });\n\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;;AAWA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,QAAQ,QAAQ,KAAK,YAAY;CACvE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;AAElB,KAAI,CAAC,QAAQ,6BAA6B,CAAC,QAAQ,iBAClD,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,SAAS,IAAI,aAAa,IAAI,SAAS,IAAI;CAGjD,MAAM,WAAW,MAAM,OAAO,iBAAiB,YAAY,IAAI,OAAO;AACtE,KAAI,CAAC,SAAS,QACb,QAAO,SACN,SAAS,OAAO,QAAQ,iBACxB,SAAS,OAAO,WAAW,iBAC3B,eAAe,SAAS,OAAO,KAAK,CACpC;CAEF,MAAM,eACL,SAAS,QAAQ,OAAO,SAAS,SAAS,WAEvC,SAAS,OACT;CAEJ,MAAM,eACL,cAAc,QAAQ,OAAO,aAAa,SAAS,WAEhD,aAAa,OACb;CAEJ,MAAM,SAAS,iBAAiB,MADf,OAAO,cAAc,aAAa,WAAW,aAAa,WAAW,IACtC,oBAAoB,mBAAmB;AACvF,KAAI,OAAQ,QAAO;CAEnB,MAAM,aAAa,OAAO,cAAc,OAAO,WAAW,aAAa,KAAK;CAE5E,MAAM,SAAS,MAAM,OAAO,0BAA0B,YAAY,WAAW;AAE7E,KAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAEhD,KAAI,OAAO,QAAS,OAAM,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,WAAW,EAAE,CAAC;AAE9E,QAAO,aAAa,OAAO"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { n as mapErrorStatus } from "../../../../../../errors-DtEXIQQV.mjs";
|
|
4
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
5
|
+
import { n as requireOwnerPerm, r as requirePerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
5
6
|
|
|
6
7
|
//#region src/astro/routes/api/content/[collection]/[id]/duplicate.ts
|
|
7
8
|
const prerender = false;
|
|
@@ -9,9 +10,9 @@ const POST = async ({ params, locals, cache }) => {
|
|
|
9
10
|
const { emdash, user } = locals;
|
|
10
11
|
const collection = params.collection;
|
|
11
12
|
const id = params.id;
|
|
13
|
+
if (!emdash?.handleContentDuplicate || !emdash?.handleContentGet) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
12
14
|
const denied = requirePerm(user, "content:create");
|
|
13
15
|
if (denied) return denied;
|
|
14
|
-
if (!emdash?.handleContentDuplicate || !emdash?.handleContentGet) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
15
16
|
const existing = await emdash.handleContentGet(collection, id);
|
|
16
17
|
if (!existing.success) return apiError(existing.error?.code ?? "UNKNOWN_ERROR", existing.error?.message ?? "Unknown error", mapErrorStatus(existing.error?.code));
|
|
17
18
|
const existingData = existing.data && typeof existing.data === "object" ? existing.data : void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/duplicate.ts"],"sourcesContent":["/**\n * Duplicate content endpoint - injected by EmDash integration\n *\n * POST /_emdash/api/content/{collection}/{id}/duplicate - Create a copy\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm, requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\
|
|
1
|
+
{"version":3,"file":"duplicate.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/duplicate.ts"],"sourcesContent":["/**\n * Duplicate content endpoint - injected by EmDash integration\n *\n * POST /_emdash/api/content/{collection}/{id}/duplicate - Create a copy\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm, requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentDuplicate || !emdash?.handleContentGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst denied = requirePerm(user, \"content:create\");\n\tif (denied) return denied;\n\n\t// Fetch item to check ownership — duplicating requires read access to the source\n\tconst existing = await emdash.handleContentGet(collection, id);\n\tif (!existing.success) {\n\t\treturn apiError(\n\t\t\texisting.error?.code ?? \"UNKNOWN_ERROR\",\n\t\t\texisting.error?.message ?? \"Unknown error\",\n\t\t\tmapErrorStatus(existing.error?.code),\n\t\t);\n\t}\n\n\tconst existingData =\n\t\texisting.data && typeof existing.data === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above\n\t\t\t\t(existing.data as Record<string, unknown>)\n\t\t\t: undefined;\n\t// Handler returns { item, _rev } — extract the item for ownership check\n\tconst existingItem =\n\t\texistingData?.item && typeof existingData.item === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\t(existingData.item as Record<string, unknown>)\n\t\t\t: existingData;\n\tconst authorId = typeof existingItem?.authorId === \"string\" ? existingItem.authorId : \"\";\n\t// Duplicating requires read access to the source — check ownership-based edit permissions\n\t// since content:read is flat (no own/any split). This ensures authors can only duplicate their own.\n\tconst readDenied = requireOwnerPerm(user, authorId, \"content:edit_own\", \"content:edit_any\");\n\tif (readDenied) return readDenied;\n\n\tconst resolvedId = typeof existingItem?.id === \"string\" ? existingItem.id : id;\n\tconst result = await emdash.handleContentDuplicate(collection, resolvedId, user?.id);\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection] });\n\n\treturn unwrapResult(result, 201);\n};\n"],"mappings":";;;;;;;AAWA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,QAAQ,QAAQ,YAAY;CAClE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;AAElB,KAAI,CAAC,QAAQ,0BAA0B,CAAC,QAAQ,iBAC/C,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpE,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;CAGnB,MAAM,WAAW,MAAM,OAAO,iBAAiB,YAAY,GAAG;AAC9D,KAAI,CAAC,SAAS,QACb,QAAO,SACN,SAAS,OAAO,QAAQ,iBACxB,SAAS,OAAO,WAAW,iBAC3B,eAAe,SAAS,OAAO,KAAK,CACpC;CAGF,MAAM,eACL,SAAS,QAAQ,OAAO,SAAS,SAAS,WAEvC,SAAS,OACT;CAEJ,MAAM,eACL,cAAc,QAAQ,OAAO,aAAa,SAAS,WAEhD,aAAa,OACb;CAIJ,MAAM,aAAa,iBAAiB,MAHnB,OAAO,cAAc,aAAa,WAAW,aAAa,WAAW,IAGlC,oBAAoB,mBAAmB;AAC3F,KAAI,WAAY,QAAO;CAEvB,MAAM,aAAa,OAAO,cAAc,OAAO,WAAW,aAAa,KAAK;CAC5E,MAAM,SAAS,MAAM,OAAO,uBAAuB,YAAY,YAAY,MAAM,GAAG;AAEpF,KAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAEhD,KAAI,OAAO,QAAS,OAAM,MAAM,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAElE,QAAO,aAAa,QAAQ,IAAI"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import { a as unwrapResult, t as apiError } from "../../../../../../error-
|
|
4
|
-
import {
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
4
|
+
import { r as requirePerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/astro/routes/api/content/[collection]/[id]/permanent.ts
|
|
7
7
|
const prerender = false;
|
|
@@ -9,9 +9,9 @@ const DELETE = async ({ params, locals, cache }) => {
|
|
|
9
9
|
const { emdash, user } = locals;
|
|
10
10
|
const collection = params.collection;
|
|
11
11
|
const id = params.id;
|
|
12
|
+
if (!emdash?.handleContentPermanentDelete) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
12
13
|
const denied = requirePerm(user, "content:delete_permanent");
|
|
13
14
|
if (denied) return denied;
|
|
14
|
-
if (!emdash?.handleContentPermanentDelete) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
15
15
|
const result = await emdash.handleContentPermanentDelete(collection, id);
|
|
16
16
|
if (!result.success) return unwrapResult(result);
|
|
17
17
|
if (cache?.enabled) await cache.invalidate({ tags: [collection, id] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permanent.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/permanent.ts"],"sourcesContent":["/**\n * Permanent delete content endpoint - injected by EmDash integration\n *\n * DELETE /_emdash/api/content/{collection}/{id}/permanent - Permanently delete (no undo)\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const DELETE: APIRoute = async ({ params, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\
|
|
1
|
+
{"version":3,"file":"permanent.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/permanent.ts"],"sourcesContent":["/**\n * Permanent delete content endpoint - injected by EmDash integration\n *\n * DELETE /_emdash/api/content/{collection}/{id}/permanent - Permanently delete (no undo)\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, unwrapResult } from \"#api/error.js\";\n\nexport const prerender = false;\n\nexport const DELETE: APIRoute = async ({ params, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentPermanentDelete) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst denied = requirePerm(user, \"content:delete_permanent\");\n\tif (denied) return denied;\n\n\tconst result = await emdash.handleContentPermanentDelete(collection, id);\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection, id] });\n\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;AAWA,MAAa,YAAY;AAEzB,MAAa,SAAmB,OAAO,EAAE,QAAQ,QAAQ,YAAY;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;AAElB,KAAI,CAAC,QAAQ,6BACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpE,MAAM,SAAS,YAAY,MAAM,2BAA2B;AAC5D,KAAI,OAAQ,QAAO;CAEnB,MAAM,SAAS,MAAM,OAAO,6BAA6B,YAAY,GAAG;AAExE,KAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAEhD,KAAI,OAAO,QAAS,OAAM,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC;AAEtE,QAAO,aAAa,OAAO"}
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import { n as getI18nConfig } from "../../../../../../config-CVssduLe.mjs";
|
|
2
2
|
import "../../../../../../after-B1IIdH3Y.mjs";
|
|
3
|
-
import "../../../../../../base64-
|
|
4
|
-
import "../../../../../../types-
|
|
5
|
-
import "../../../../../../options-
|
|
6
|
-
import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-
|
|
7
|
-
import { r as parseOptionalBody, t as isParseError } from "../../../../../../parse-
|
|
8
|
-
import
|
|
9
|
-
import "../../../../../../
|
|
10
|
-
import "../../../../../../
|
|
3
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
4
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
5
|
+
import "../../../../../../options-BlmBHTvX.mjs";
|
|
6
|
+
import { a as unwrapResult, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
7
|
+
import { r as parseOptionalBody, t as isParseError } from "../../../../../../parse-C_-6klII.mjs";
|
|
8
|
+
import "../../../../../../media-kIV1IxFf.mjs";
|
|
9
|
+
import { qt as contentPreviewUrlBody } from "../../../../../../redirects-BBq3n2Rj.mjs";
|
|
10
|
+
import "../../../../../../relations-5_avdrN_.mjs";
|
|
11
|
+
import "../../../../../../status-COfycGIU.mjs";
|
|
11
12
|
import "../../../../../../api/schemas/index.mjs";
|
|
12
|
-
import "../../../../../../tokens-
|
|
13
|
-
import { i as getPreviewUrl } from "../../../../../../preview-
|
|
14
|
-
import { i as resolveSecretsCached } from "../../../../../../secrets-
|
|
15
|
-
import {
|
|
13
|
+
import "../../../../../../tokens-DVltpO2D.mjs";
|
|
14
|
+
import { i as getPreviewUrl } from "../../../../../../preview-D4Jnbfx7.mjs";
|
|
15
|
+
import { i as resolveSecretsCached } from "../../../../../../secrets-CSwQIl4q.mjs";
|
|
16
|
+
import { r as requirePerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
16
17
|
|
|
17
18
|
//#region src/astro/routes/api/content/[collection]/[id]/preview-url.ts
|
|
18
19
|
const prerender = false;
|
|
19
20
|
const DURATION_PATTERN = /^(\d+)([smhdw])$/;
|
|
20
21
|
const POST = async ({ params, request, locals }) => {
|
|
21
22
|
const { emdash, user } = locals;
|
|
23
|
+
if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
22
24
|
const denied = requirePerm(user, "content:read_drafts");
|
|
23
25
|
if (denied) return denied;
|
|
24
26
|
const collection = params.collection;
|
|
25
27
|
const id = params.id;
|
|
26
|
-
if (!emdash?.db) return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
27
28
|
const { previewSecret } = await resolveSecretsCached(emdash.db);
|
|
28
29
|
let entryLocale = null;
|
|
29
30
|
if (emdash?.handleContentGet) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-url.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/preview-url.ts"],"sourcesContent":["/**\n * Preview URL endpoint - generates a signed preview URL for content\n *\n * POST /_emdash/api/content/{collection}/{id}/preview-url\n *\n * Request body:\n * {\n * expiresIn?: string | number; // Default: \"1h\"\n * pathPattern?: string; // Default: \"/{collection}/{id}\" (or EMDASH_PREVIEW_PATH_PATTERN)\n * }\n *\n * Response:\n * {\n * url: string; // The preview URL with token\n * expiresAt: number; // Unix timestamp when token expires\n * }\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { parseOptionalBody, isParseError } from \"#api/parse.js\";\nimport { contentPreviewUrlBody } from \"#api/schemas.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\nimport { getPreviewUrl } from \"#preview/index.js\";\n\nimport { getI18nConfig } from \"../../../../../../i18n/config.js\";\n\nexport const prerender = false;\n\nconst DURATION_PATTERN = /^(\\d+)([smhdw])$/;\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst denied = requirePerm(user, \"content:read_drafts\");\n\tif (denied) return denied;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\
|
|
1
|
+
{"version":3,"file":"preview-url.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/preview-url.ts"],"sourcesContent":["/**\n * Preview URL endpoint - generates a signed preview URL for content\n *\n * POST /_emdash/api/content/{collection}/{id}/preview-url\n *\n * Request body:\n * {\n * expiresIn?: string | number; // Default: \"1h\"\n * pathPattern?: string; // Default: \"/{collection}/{id}\" (or EMDASH_PREVIEW_PATH_PATTERN)\n * }\n *\n * Response:\n * {\n * url: string; // The preview URL with token\n * expiresAt: number; // Unix timestamp when token expires\n * }\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError, unwrapResult } from \"#api/error.js\";\nimport { parseOptionalBody, isParseError } from \"#api/parse.js\";\nimport { contentPreviewUrlBody } from \"#api/schemas.js\";\nimport { resolveSecretsCached } from \"#config/secrets.js\";\nimport { getPreviewUrl } from \"#preview/index.js\";\n\nimport { getI18nConfig } from \"../../../../../../i18n/config.js\";\n\nexport const prerender = false;\n\nconst DURATION_PATTERN = /^(\\d+)([smhdw])$/;\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\tconst denied = requirePerm(user, \"content:read_drafts\");\n\tif (denied) return denied;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\t// Resolve the preview secret. Env override wins; otherwise a stable\n\t// site-specific value is read from (or generated into) the options table.\n\t// The resolver always returns a usable secret, so this path can no\n\t// longer be silently disabled by a missing env var.\n\tconst { previewSecret } = await resolveSecretsCached(emdash.db);\n\n\t// Verify the content exists. The fetched item also yields the entry's\n\t// locale, used below to resolve the `{locale}` placeholder.\n\tlet entryLocale: string | null = null;\n\tif (emdash?.handleContentGet) {\n\t\tconst result = await emdash.handleContentGet(collection, id);\n\t\tif (!result.success) return unwrapResult(result);\n\t\tentryLocale = result.data?.item?.locale ?? null;\n\t}\n\n\t// Parse request body\n\tconst body = await parseOptionalBody(request, contentPreviewUrlBody, {});\n\tif (isParseError(body)) return body;\n\n\tconst expiresIn = body.expiresIn || \"1h\";\n\t// Allow a project-wide default `pathPattern` so the admin's \"View on site\"\n\t// link can match the site's actual route shape without each call having\n\t// to override the default `/{collection}/{id}`.\n\tconst defaultPathPattern = import.meta.env.EMDASH_PREVIEW_PATH_PATTERN || \"/{collection}/{id}\";\n\tconst pathPattern = body.pathPattern || defaultPathPattern;\n\n\t// Resolve the locale segment substituted for `{locale}`: empty when the\n\t// entry is in the default locale and `prefixDefaultLocale` is `false`,\n\t// the entry's own locale otherwise.\n\tconst i18n = getI18nConfig();\n\tlet localeSegment = \"\";\n\tif (entryLocale && i18n) {\n\t\tconst isDefault = entryLocale === i18n.defaultLocale;\n\t\tlocaleSegment = isDefault && !i18n.prefixDefaultLocale ? \"\" : entryLocale;\n\t} else if (entryLocale) {\n\t\tlocaleSegment = entryLocale;\n\t}\n\n\t// Calculate expiry timestamp\n\tconst expiresInSeconds = typeof expiresIn === \"number\" ? expiresIn : parseExpiresIn(expiresIn);\n\tconst expiresAt = Math.floor(Date.now() / 1000) + expiresInSeconds;\n\n\ttry {\n\t\tconst url = await getPreviewUrl({\n\t\t\tcollection,\n\t\t\tid,\n\t\t\tsecret: previewSecret,\n\t\t\texpiresIn,\n\t\t\tpathPattern,\n\t\t\tlocale: localeSegment,\n\t\t});\n\n\t\treturn apiSuccess({ url, expiresAt });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to generate preview URL\", \"TOKEN_ERROR\");\n\t}\n};\n\n/**\n * Parse duration string to seconds\n */\nfunction parseExpiresIn(duration: string): number {\n\tconst match = duration.match(DURATION_PATTERN);\n\tif (!match) {\n\t\treturn 3600; // Default 1 hour\n\t}\n\n\tconst value = parseInt(match[1], 10);\n\tconst unit = match[2];\n\n\tswitch (unit) {\n\t\tcase \"s\":\n\t\t\treturn value;\n\t\tcase \"m\":\n\t\t\treturn value * 60;\n\t\tcase \"h\":\n\t\t\treturn value * 60 * 60;\n\t\tcase \"d\":\n\t\t\treturn value * 60 * 60 * 24;\n\t\tcase \"w\":\n\t\t\treturn value * 60 * 60 * 24 * 7;\n\t\tdefault:\n\t\t\treturn 3600;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA6BA,MAAa,YAAY;AAEzB,MAAM,mBAAmB;AAEzB,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;AACzB,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAEpE,MAAM,SAAS,YAAY,MAAM,sBAAsB;AACvD,KAAI,OAAQ,QAAO;CACnB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;CAMlB,MAAM,EAAE,kBAAkB,MAAM,qBAAqB,OAAO,GAAG;CAI/D,IAAI,cAA6B;AACjC,KAAI,QAAQ,kBAAkB;EAC7B,MAAM,SAAS,MAAM,OAAO,iBAAiB,YAAY,GAAG;AAC5D,MAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAChD,gBAAc,OAAO,MAAM,MAAM,UAAU;;CAI5C,MAAM,OAAO,MAAM,kBAAkB,SAAS,uBAAuB,EAAE,CAAC;AACxE,KAAI,aAAa,KAAK,CAAE,QAAO;CAE/B,MAAM,YAAY,KAAK,aAAa;CAIpC,MAAM,qBAAqB,OAAO,KAAK,IAAI,+BAA+B;CAC1E,MAAM,cAAc,KAAK,eAAe;CAKxC,MAAM,OAAO,eAAe;CAC5B,IAAI,gBAAgB;AACpB,KAAI,eAAe,KAElB,iBADkB,gBAAgB,KAAK,iBACV,CAAC,KAAK,sBAAsB,KAAK;UACpD,YACV,iBAAgB;CAIjB,MAAM,mBAAmB,OAAO,cAAc,WAAW,YAAY,eAAe,UAAU;CAC9F,MAAM,YAAY,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,GAAG;AAElD,KAAI;AAUH,SAAO,WAAW;GAAE,KATR,MAAM,cAAc;IAC/B;IACA;IACA,QAAQ;IACR;IACA;IACA,QAAQ;IACR,CAAC;GAEuB;GAAW,CAAC;UAC7B,OAAO;AACf,SAAO,YAAY,OAAO,kCAAkC,cAAc;;;;;;AAO5E,SAAS,eAAe,UAA0B;CACjD,MAAM,QAAQ,SAAS,MAAM,iBAAiB;AAC9C,KAAI,CAAC,MACJ,QAAO;CAGR,MAAM,QAAQ,SAAS,MAAM,IAAI,GAAG;AAGpC,SAFa,MAAM,IAEnB;EACC,KAAK,IACJ,QAAO;EACR,KAAK,IACJ,QAAO,QAAQ;EAChB,KAAK,IACJ,QAAO,QAAQ,KAAK;EACrB,KAAK,IACJ,QAAO,QAAQ,KAAK,KAAK;EAC1B,KAAK,IACJ,QAAO,QAAQ,KAAK,KAAK,KAAK;EAC/B,QACC,QAAO"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import "../../../../../../
|
|
7
|
-
import "../../../../../../
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { n as mapErrorStatus } from "../../../../../../errors-DtEXIQQV.mjs";
|
|
4
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
5
|
+
import { r as parseOptionalBody, t as isParseError } from "../../../../../../parse-C_-6klII.mjs";
|
|
6
|
+
import "../../../../../../media-kIV1IxFf.mjs";
|
|
7
|
+
import { Jt as contentPublishBody } from "../../../../../../redirects-BBq3n2Rj.mjs";
|
|
8
|
+
import "../../../../../../relations-5_avdrN_.mjs";
|
|
9
|
+
import "../../../../../../status-COfycGIU.mjs";
|
|
8
10
|
import "../../../../../../api/schemas/index.mjs";
|
|
9
|
-
import {
|
|
11
|
+
import { n as requireOwnerPerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
10
12
|
import { hasPermission } from "@emdash-cms/auth";
|
|
11
13
|
|
|
12
14
|
//#region src/astro/routes/api/content/[collection]/[id]/publish.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/publish.ts"],"sourcesContent":["/**\n * Publish content - promotes draft to live\n *\n * POST /_emdash/api/content/{collection}/{id}/publish\n *\n * Optional JSON body: { publishedAt?: string }\n * publishedAt — ISO 8601 datetime to backdate the publish (e.g. when\n * migrating content). Writing publishedAt requires content:publish_any.\n * Without it, the existing published_at is preserved on re-publish and\n * falls back to the current time on first publish.\n */\n\nimport { hasPermission } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\nimport { isParseError, parseOptionalBody } from \"#api/parse.js\";\nimport { contentPublishBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, request, locals, url, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentPublish || !emdash?.handleContentGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Body is optional — empty body means use the legacy behavior (preserve\n\t// or default published_at). Pass `publishedAt` to backdate.\n\tconst body = await parseOptionalBody(request, contentPublishBody, {});\n\tif (isParseError(body)) return body;\n\n\tconst locale = url.searchParams.get(\"locale\") || undefined;\n\n\t// Fetch item to check ownership\n\tconst existing = await emdash.handleContentGet(collection, id, locale);\n\tif (!existing.success) {\n\t\treturn apiError(\n\t\t\texisting.error?.code ?? \"UNKNOWN_ERROR\",\n\t\t\texisting.error?.message ?? \"Unknown error\",\n\t\t\tmapErrorStatus(existing.error?.code),\n\t\t);\n\t}\n\n\tconst existingData =\n\t\texisting.data && typeof existing.data === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above\n\t\t\t\t(existing.data as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst existingItem =\n\t\texistingData?.item && typeof existingData.item === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\t(existingData.item as Record<string, unknown>)\n\t\t\t: existingData;\n\tconst authorId = typeof existingItem?.authorId === \"string\" ? existingItem.authorId : \"\";\n\tconst denied = requireOwnerPerm(user, authorId, \"content:publish_own\", \"content:publish_any\");\n\tif (denied) return denied;\n\n\t// Schema narrows `publishedAt` to `string | undefined`; null is rejected\n\t// at the schema layer (publish has no semantic meaning for \"clear\").\n\tconst publishedAt = body?.publishedAt;\n\n\t// Backdating overwrites historical record — gate behind publish_any\n\t// regardless of ownership.\n\tif (publishedAt !== undefined && !hasPermission(user, \"content:publish_any\")) {\n\t\treturn apiError(\n\t\t\t\"FORBIDDEN\",\n\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t403,\n\t\t);\n\t}\n\n\tconst resolvedId = typeof existingItem?.id === \"string\" ? existingItem.id : id;\n\n\tconst result = await emdash.handleContentPublish(collection, resolvedId, {\n\t\tpublishedAt,\n\t});\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection, resolvedId] });\n\n\treturn unwrapResult(result);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/content/[collection]/[id]/publish.ts"],"sourcesContent":["/**\n * Publish content - promotes draft to live\n *\n * POST /_emdash/api/content/{collection}/{id}/publish\n *\n * Optional JSON body: { publishedAt?: string }\n * publishedAt — ISO 8601 datetime to backdate the publish (e.g. when\n * migrating content). Writing publishedAt requires content:publish_any.\n * Without it, the existing published_at is preserved on re-publish and\n * falls back to the current time on first publish.\n */\n\nimport { hasPermission } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm } from \"#api/authorize.js\";\nimport { apiError, mapErrorStatus, unwrapResult } from \"#api/error.js\";\nimport { isParseError, parseOptionalBody } from \"#api/parse.js\";\nimport { contentPublishBody } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ params, request, locals, url, cache }) => {\n\tconst { emdash, user } = locals;\n\tconst collection = params.collection!;\n\tconst id = params.id!;\n\n\tif (!emdash?.handleContentPublish || !emdash?.handleContentGet) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Body is optional — empty body means use the legacy behavior (preserve\n\t// or default published_at). Pass `publishedAt` to backdate.\n\tconst body = await parseOptionalBody(request, contentPublishBody, {});\n\tif (isParseError(body)) return body;\n\n\tconst locale = url.searchParams.get(\"locale\") || undefined;\n\n\t// Fetch item to check ownership\n\tconst existing = await emdash.handleContentGet(collection, id, locale);\n\tif (!existing.success) {\n\t\treturn apiError(\n\t\t\texisting.error?.code ?? \"UNKNOWN_ERROR\",\n\t\t\texisting.error?.message ?? \"Unknown error\",\n\t\t\tmapErrorStatus(existing.error?.code),\n\t\t);\n\t}\n\n\tconst existingData =\n\t\texisting.data && typeof existing.data === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above\n\t\t\t\t(existing.data as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst existingItem =\n\t\texistingData?.item && typeof existingData.item === \"object\"\n\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\t(existingData.item as Record<string, unknown>)\n\t\t\t: existingData;\n\tconst authorId = typeof existingItem?.authorId === \"string\" ? existingItem.authorId : \"\";\n\tconst denied = requireOwnerPerm(user, authorId, \"content:publish_own\", \"content:publish_any\");\n\tif (denied) return denied;\n\n\t// Schema narrows `publishedAt` to `string | undefined`; null is rejected\n\t// at the schema layer (publish has no semantic meaning for \"clear\").\n\tconst publishedAt = body?.publishedAt;\n\n\t// Backdating overwrites historical record — gate behind publish_any\n\t// regardless of ownership.\n\tif (publishedAt !== undefined && !hasPermission(user, \"content:publish_any\")) {\n\t\treturn apiError(\n\t\t\t\"FORBIDDEN\",\n\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t403,\n\t\t);\n\t}\n\n\tconst resolvedId = typeof existingItem?.id === \"string\" ? existingItem.id : id;\n\n\tconst result = await emdash.handleContentPublish(collection, resolvedId, {\n\t\tpublishedAt,\n\t});\n\n\tif (!result.success) return unwrapResult(result);\n\n\tif (cache?.enabled) await cache.invalidate({ tags: [collection, resolvedId] });\n\n\treturn unwrapResult(result);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,YAAY;AAEzB,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,QAAQ,KAAK,YAAY;CAChF,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,aAAa,OAAO;CAC1B,MAAM,KAAK,OAAO;AAElB,KAAI,CAAC,QAAQ,wBAAwB,CAAC,QAAQ,iBAC7C,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAKpE,MAAM,OAAO,MAAM,kBAAkB,SAAS,oBAAoB,EAAE,CAAC;AACrE,KAAI,aAAa,KAAK,CAAE,QAAO;CAE/B,MAAM,SAAS,IAAI,aAAa,IAAI,SAAS,IAAI;CAGjD,MAAM,WAAW,MAAM,OAAO,iBAAiB,YAAY,IAAI,OAAO;AACtE,KAAI,CAAC,SAAS,QACb,QAAO,SACN,SAAS,OAAO,QAAQ,iBACxB,SAAS,OAAO,WAAW,iBAC3B,eAAe,SAAS,OAAO,KAAK,CACpC;CAGF,MAAM,eACL,SAAS,QAAQ,OAAO,SAAS,SAAS,WAEvC,SAAS,OACT;CACJ,MAAM,eACL,cAAc,QAAQ,OAAO,aAAa,SAAS,WAEhD,aAAa,OACb;CAEJ,MAAM,SAAS,iBAAiB,MADf,OAAO,cAAc,aAAa,WAAW,aAAa,WAAW,IACtC,uBAAuB,sBAAsB;AAC7F,KAAI,OAAQ,QAAO;CAInB,MAAM,cAAc,MAAM;AAI1B,KAAI,gBAAgB,UAAa,CAAC,cAAc,MAAM,sBAAsB,CAC3E,QAAO,SACN,aACA,+DACA,IACA;CAGF,MAAM,aAAa,OAAO,cAAc,OAAO,WAAW,aAAa,KAAK;CAE5E,MAAM,SAAS,MAAM,OAAO,qBAAqB,YAAY,YAAY,EACxE,aACA,CAAC;AAEF,KAAI,CAAC,OAAO,QAAS,QAAO,aAAa,OAAO;AAEhD,KAAI,OAAO,QAAS,OAAM,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,WAAW,EAAE,CAAC;AAE9E,QAAO,aAAa,OAAO"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { APIRoute } from "astro";
|
|
2
|
+
|
|
3
|
+
//#region src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.d.ts
|
|
4
|
+
declare const prerender = false;
|
|
5
|
+
declare const GET: APIRoute;
|
|
6
|
+
declare const POST: APIRoute;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { GET, POST, prerender };
|
|
9
|
+
//# sourceMappingURL=children.d.mts.map
|
package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"children.d.mts","names":[],"sources":["../../../../../../../../../src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts"],"mappings":";;;cAiBa,SAAA;AAAA,cAEA,GAAA,EAAK,QAAA;AAAA,cA+BL,IAAA,EAAM,QAAA"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import "../../../../../../../../dialect-helpers-HxEQGl_1.mjs";
|
|
2
|
+
import "../../../../../../../../after-B1IIdH3Y.mjs";
|
|
3
|
+
import "../../../../../../../../object-cache-Bok5j2ae.mjs";
|
|
4
|
+
import { t as ContentRepository } from "../../../../../../../../content-Ci04z2z-.mjs";
|
|
5
|
+
import "../../../../../../../../base64-B-PsqheR.mjs";
|
|
6
|
+
import "../../../../../../../../types-D1iJ3DpO.mjs";
|
|
7
|
+
import "../../../../../../../../relation-9M9j_UWo.mjs";
|
|
8
|
+
import "../../../../../../../../fts-manager-DzqIBrrW.mjs";
|
|
9
|
+
import "../../../../../../../../content-refresh-D4khvC0R.mjs";
|
|
10
|
+
import "../../../../../../../../registry-FV15nLge.mjs";
|
|
11
|
+
import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../../../../../error-CEGF6UZb.mjs";
|
|
12
|
+
import { i as parseQuery, n as parseBody, t as isParseError } from "../../../../../../../../parse-C_-6klII.mjs";
|
|
13
|
+
import { F as cursorPaginationQuery } from "../../../../../../../../media-kIV1IxFf.mjs";
|
|
14
|
+
import "../../../../../../../../redirects-BBq3n2Rj.mjs";
|
|
15
|
+
import { l as setReferenceChildrenBody } from "../../../../../../../../relations-5_avdrN_.mjs";
|
|
16
|
+
import "../../../../../../../../status-COfycGIU.mjs";
|
|
17
|
+
import "../../../../../../../../api/schemas/index.mjs";
|
|
18
|
+
import { n as requireOwnerPerm, r as requirePerm } from "../../../../../../../../authorize-WxsiePzy.mjs";
|
|
19
|
+
import { n as handleReferenceChildrenSet, t as handleReferenceChildrenGet } from "../../../../../../../../relations-BKvO39-9.mjs";
|
|
20
|
+
import { hasPermission } from "@emdash-cms/auth";
|
|
21
|
+
|
|
22
|
+
//#region src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts
|
|
23
|
+
/**
|
|
24
|
+
* Content-entry reference children endpoint (parent side)
|
|
25
|
+
*
|
|
26
|
+
* GET /_emdash/api/content/:collection/:id/references/:relation/children
|
|
27
|
+
* POST /_emdash/api/content/:collection/:id/references/:relation/children
|
|
28
|
+
*/
|
|
29
|
+
const prerender = false;
|
|
30
|
+
const GET = async ({ params, request, locals }) => {
|
|
31
|
+
const { emdash, user } = locals;
|
|
32
|
+
const { collection, id, relation } = params;
|
|
33
|
+
const dbErr = requireDb(emdash?.db);
|
|
34
|
+
if (dbErr) return dbErr;
|
|
35
|
+
const denied = requirePerm(user, "content:read");
|
|
36
|
+
if (denied) return denied;
|
|
37
|
+
if (!collection || !id || !relation) return apiError("VALIDATION_ERROR", "Collection, id, and relation required", 400);
|
|
38
|
+
const query = parseQuery(new URL(request.url), cursorPaginationQuery);
|
|
39
|
+
if (isParseError(query)) return query;
|
|
40
|
+
try {
|
|
41
|
+
return unwrapResult(await handleReferenceChildrenGet(emdash.db, collection, id, relation, {
|
|
42
|
+
limit: query.limit,
|
|
43
|
+
cursor: query.cursor
|
|
44
|
+
}, hasPermission(user, "content:read_drafts")));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return handleError(error, "Failed to get references", "REFERENCES_GET_ERROR");
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const POST = async ({ params, request, locals }) => {
|
|
50
|
+
const { emdash, user } = locals;
|
|
51
|
+
const { collection, id, relation } = params;
|
|
52
|
+
if (!collection || !id || !relation) return apiError("VALIDATION_ERROR", "Collection, id, and relation required", 400);
|
|
53
|
+
const dbErr = requireDb(emdash?.db);
|
|
54
|
+
if (dbErr) return dbErr;
|
|
55
|
+
const denied = requirePerm(user, "content:edit_own");
|
|
56
|
+
if (denied) return denied;
|
|
57
|
+
const parent = await new ContentRepository(emdash.db).findByIdOrSlug(collection, id);
|
|
58
|
+
if (!parent) return apiError("NOT_FOUND", "Content not found", 404);
|
|
59
|
+
const editDenied = requireOwnerPerm(user, parent.authorId ?? "", "content:edit_own", "content:edit_any");
|
|
60
|
+
if (editDenied) return editDenied;
|
|
61
|
+
try {
|
|
62
|
+
const body = await parseBody(request, setReferenceChildrenBody);
|
|
63
|
+
if (isParseError(body)) return body;
|
|
64
|
+
return unwrapResult(await handleReferenceChildrenSet(emdash.db, collection, id, relation, body.childIds));
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return handleError(error, "Failed to set references", "REFERENCES_SET_ERROR");
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { GET, POST, prerender };
|
|
72
|
+
//# sourceMappingURL=children.mjs.map
|
package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"children.mjs","names":[],"sources":["../../../../../../../../../src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts"],"sourcesContent":["/**\n * Content-entry reference children endpoint (parent side)\n *\n * GET /_emdash/api/content/:collection/:id/references/:relation/children\n * POST /_emdash/api/content/:collection/:id/references/:relation/children\n */\n\nimport { hasPermission } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requireOwnerPerm, requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleReferenceChildrenGet, handleReferenceChildrenSet } from \"#api/handlers/relations.js\";\nimport { isParseError, parseBody, parseQuery } from \"#api/parse.js\";\nimport { cursorPaginationQuery, setReferenceChildrenBody } from \"#api/schemas.js\";\nimport { ContentRepository } from \"#db/repositories/content.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { collection, id, relation } = params;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst denied = requirePerm(user, \"content:read\");\n\tif (denied) return denied;\n\n\tif (!collection || !id || !relation) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection, id, and relation required\", 400);\n\t}\n\n\tconst query = parseQuery(new URL(request.url), cursorPaginationQuery);\n\tif (isParseError(query)) return query;\n\n\ttry {\n\t\tconst result = await handleReferenceChildrenGet(\n\t\t\temdash.db,\n\t\t\tcollection,\n\t\t\tid,\n\t\t\trelation,\n\t\t\t{ limit: query.limit, cursor: query.cursor },\n\t\t\thasPermission(user, \"content:read_drafts\"),\n\t\t);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get references\", \"REFERENCES_GET_ERROR\");\n\t}\n};\n\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { collection, id, relation } = params;\n\n\tif (!collection || !id || !relation) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection, id, and relation required\", 400);\n\t}\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\t// Gate on the base edit capability BEFORE the existence lookup. Resolving the\n\t// entry first would let a user with no edit permission distinguish real ids\n\t// (403) from missing ids (404) — an existence oracle. Mirrors the taxonomy\n\t// edge POST, which checks `content:edit_own` before fetching the entry.\n\tconst denied = requirePerm(user, \"content:edit_own\");\n\tif (denied) return denied;\n\n\t// Resolve the parent entry to gate on its author (ownership-aware write).\n\tconst parent = await new ContentRepository(emdash.db).findByIdOrSlug(collection, id);\n\tif (!parent) return apiError(\"NOT_FOUND\", \"Content not found\", 404);\n\n\tconst editDenied = requireOwnerPerm(\n\t\tuser,\n\t\tparent.authorId ?? \"\",\n\t\t\"content:edit_own\",\n\t\t\"content:edit_any\",\n\t);\n\tif (editDenied) return editDenied;\n\n\ttry {\n\t\tconst body = await parseBody(request, setReferenceChildrenBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst result = await handleReferenceChildrenSet(\n\t\t\temdash.db,\n\t\t\tcollection,\n\t\t\tid,\n\t\t\trelation,\n\t\t\tbody.childIds,\n\t\t);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to set references\", \"REFERENCES_SET_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,YAAY,IAAI,aAAa;CAErC,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAC1B,QAAO,SAAS,oBAAoB,yCAAyC,IAAI;CAGlF,MAAM,QAAQ,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,sBAAsB;AACrE,KAAI,aAAa,MAAM,CAAE,QAAO;AAEhC,KAAI;AASH,SAAO,aARQ,MAAM,2BACpB,OAAO,IACP,YACA,IACA,UACA;GAAE,OAAO,MAAM;GAAO,QAAQ,MAAM;GAAQ,EAC5C,cAAc,MAAM,sBAAsB,CAC1C,CAC0B;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB;;;AAI/E,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,YAAY,IAAI,aAAa;AAErC,KAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAC1B,QAAO,SAAS,oBAAoB,yCAAyC,IAAI;CAGlF,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAKlB,MAAM,SAAS,YAAY,MAAM,mBAAmB;AACpD,KAAI,OAAQ,QAAO;CAGnB,MAAM,SAAS,MAAM,IAAI,kBAAkB,OAAO,GAAG,CAAC,eAAe,YAAY,GAAG;AACpF,KAAI,CAAC,OAAQ,QAAO,SAAS,aAAa,qBAAqB,IAAI;CAEnE,MAAM,aAAa,iBAClB,MACA,OAAO,YAAY,IACnB,oBACA,mBACA;AACD,KAAI,WAAY,QAAO;AAEvB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,yBAAyB;AAC/D,MAAI,aAAa,KAAK,CAAE,QAAO;AAS/B,SAAO,aAPQ,MAAM,2BACpB,OAAO,IACP,YACA,IACA,UACA,KAAK,SACL,CAC0B;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { APIRoute } from "astro";
|
|
2
|
+
|
|
3
|
+
//#region src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.d.ts
|
|
4
|
+
declare const prerender = false;
|
|
5
|
+
declare const GET: APIRoute;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { GET, prerender };
|
|
8
|
+
//# sourceMappingURL=parents.d.mts.map
|
package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parents.d.mts","names":[],"sources":["../../../../../../../../../src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts"],"mappings":";;;cAea,SAAA;AAAA,cAEA,GAAA,EAAK,QAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import "../../../../../../../../dialect-helpers-HxEQGl_1.mjs";
|
|
2
|
+
import "../../../../../../../../after-B1IIdH3Y.mjs";
|
|
3
|
+
import "../../../../../../../../object-cache-Bok5j2ae.mjs";
|
|
4
|
+
import "../../../../../../../../content-Ci04z2z-.mjs";
|
|
5
|
+
import "../../../../../../../../base64-B-PsqheR.mjs";
|
|
6
|
+
import "../../../../../../../../types-D1iJ3DpO.mjs";
|
|
7
|
+
import "../../../../../../../../relation-9M9j_UWo.mjs";
|
|
8
|
+
import "../../../../../../../../fts-manager-DzqIBrrW.mjs";
|
|
9
|
+
import "../../../../../../../../content-refresh-D4khvC0R.mjs";
|
|
10
|
+
import "../../../../../../../../registry-FV15nLge.mjs";
|
|
11
|
+
import { a as unwrapResult, i as requireDb, r as handleError, t as apiError } from "../../../../../../../../error-CEGF6UZb.mjs";
|
|
12
|
+
import { i as parseQuery, t as isParseError } from "../../../../../../../../parse-C_-6klII.mjs";
|
|
13
|
+
import { F as cursorPaginationQuery } from "../../../../../../../../media-kIV1IxFf.mjs";
|
|
14
|
+
import "../../../../../../../../redirects-BBq3n2Rj.mjs";
|
|
15
|
+
import "../../../../../../../../relations-5_avdrN_.mjs";
|
|
16
|
+
import "../../../../../../../../status-COfycGIU.mjs";
|
|
17
|
+
import "../../../../../../../../api/schemas/index.mjs";
|
|
18
|
+
import { r as requirePerm } from "../../../../../../../../authorize-WxsiePzy.mjs";
|
|
19
|
+
import { r as handleReferenceParentsGet } from "../../../../../../../../relations-BKvO39-9.mjs";
|
|
20
|
+
import { hasPermission } from "@emdash-cms/auth";
|
|
21
|
+
|
|
22
|
+
//#region src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts
|
|
23
|
+
/**
|
|
24
|
+
* Content-entry reference parents endpoint (child side, read-only backlink)
|
|
25
|
+
*
|
|
26
|
+
* GET /_emdash/api/content/:collection/:id/references/:relation/parents
|
|
27
|
+
*/
|
|
28
|
+
const prerender = false;
|
|
29
|
+
const GET = async ({ params, request, locals }) => {
|
|
30
|
+
const { emdash, user } = locals;
|
|
31
|
+
const { collection, id, relation } = params;
|
|
32
|
+
const dbErr = requireDb(emdash?.db);
|
|
33
|
+
if (dbErr) return dbErr;
|
|
34
|
+
const denied = requirePerm(user, "content:read");
|
|
35
|
+
if (denied) return denied;
|
|
36
|
+
if (!collection || !id || !relation) return apiError("VALIDATION_ERROR", "Collection, id, and relation required", 400);
|
|
37
|
+
const query = parseQuery(new URL(request.url), cursorPaginationQuery);
|
|
38
|
+
if (isParseError(query)) return query;
|
|
39
|
+
try {
|
|
40
|
+
return unwrapResult(await handleReferenceParentsGet(emdash.db, collection, id, relation, {
|
|
41
|
+
limit: query.limit,
|
|
42
|
+
cursor: query.cursor
|
|
43
|
+
}, hasPermission(user, "content:read_drafts")));
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return handleError(error, "Failed to get references", "REFERENCES_GET_ERROR");
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { GET, prerender };
|
|
51
|
+
//# sourceMappingURL=parents.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parents.mjs","names":[],"sources":["../../../../../../../../../src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts"],"sourcesContent":["/**\n * Content-entry reference parents endpoint (child side, read-only backlink)\n *\n * GET /_emdash/api/content/:collection/:id/references/:relation/parents\n */\n\nimport { hasPermission } from \"@emdash-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, handleError, requireDb, unwrapResult } from \"#api/error.js\";\nimport { handleReferenceParentsGet } from \"#api/handlers/relations.js\";\nimport { isParseError, parseQuery } from \"#api/parse.js\";\nimport { cursorPaginationQuery } from \"#api/schemas.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { collection, id, relation } = params;\n\n\tconst dbErr = requireDb(emdash?.db);\n\tif (dbErr) return dbErr;\n\tconst denied = requirePerm(user, \"content:read\");\n\tif (denied) return denied;\n\n\tif (!collection || !id || !relation) {\n\t\treturn apiError(\"VALIDATION_ERROR\", \"Collection, id, and relation required\", 400);\n\t}\n\n\tconst query = parseQuery(new URL(request.url), cursorPaginationQuery);\n\tif (isParseError(query)) return query;\n\n\ttry {\n\t\tconst result = await handleReferenceParentsGet(\n\t\t\temdash.db,\n\t\t\tcollection,\n\t\t\tid,\n\t\t\trelation,\n\t\t\t{ limit: query.limit, cursor: query.cursor },\n\t\t\thasPermission(user, \"content:read_drafts\"),\n\t\t);\n\t\treturn unwrapResult(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to get references\", \"REFERENCES_GET_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,YAAY,IAAI,aAAa;CAErC,MAAM,QAAQ,UAAU,QAAQ,GAAG;AACnC,KAAI,MAAO,QAAO;CAClB,MAAM,SAAS,YAAY,MAAM,eAAe;AAChD,KAAI,OAAQ,QAAO;AAEnB,KAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAC1B,QAAO,SAAS,oBAAoB,yCAAyC,IAAI;CAGlF,MAAM,QAAQ,WAAW,IAAI,IAAI,QAAQ,IAAI,EAAE,sBAAsB;AACrE,KAAI,aAAa,MAAM,CAAE,QAAO;AAEhC,KAAI;AASH,SAAO,aARQ,MAAM,0BACpB,OAAO,IACP,YACA,IACA,UACA;GAAE,OAAO,MAAM;GAAO,QAAQ,MAAM;GAAQ,EAC5C,cAAc,MAAM,sBAAsB,CAC1C,CAC0B;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import "../../../../../../base64-
|
|
2
|
-
import "../../../../../../types-
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
1
|
+
import "../../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../../types-D1iJ3DpO.mjs";
|
|
3
|
+
import { n as mapErrorStatus } from "../../../../../../errors-DtEXIQQV.mjs";
|
|
4
|
+
import { a as unwrapResult, t as apiError } from "../../../../../../error-CEGF6UZb.mjs";
|
|
5
|
+
import { n as requireOwnerPerm } from "../../../../../../authorize-WxsiePzy.mjs";
|
|
5
6
|
|
|
6
7
|
//#region src/astro/routes/api/content/[collection]/[id]/restore.ts
|
|
7
8
|
const prerender = false;
|