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
package/dist/plugin-utils.mjs
CHANGED
|
@@ -24,13 +24,14 @@ function getPublicPluginApiRouteHandler(locals) {
|
|
|
24
24
|
return typeof handler === "function" ? handler : void 0;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Parse an API response, unwrapping the `{ data: T }` envelope.
|
|
27
|
+
* Parse an API response, unwrapping the `{ success, data: T }` envelope.
|
|
28
28
|
*
|
|
29
|
-
* All plugin API routes return success responses wrapped in
|
|
30
|
-
* by `apiSuccess()`. This helper unwraps that
|
|
29
|
+
* All plugin API routes return success responses wrapped in
|
|
30
|
+
* `{ success: true, data: ... }` by `apiSuccess()`. This helper unwraps that
|
|
31
|
+
* envelope and handles errors.
|
|
31
32
|
*
|
|
32
33
|
* On error responses (non-2xx), throws an Error with the server's message
|
|
33
|
-
* (from `{ error: { message } }`) or the fallback message.
|
|
34
|
+
* (from `{ success: false, error: { message } }`) or the fallback message.
|
|
34
35
|
*
|
|
35
36
|
* @example
|
|
36
37
|
* ```ts
|
|
@@ -45,8 +46,9 @@ async function parseApiResponse(response, fallbackMessage = "Request failed") {
|
|
|
45
46
|
/**
|
|
46
47
|
* Extract the error message from a failed API response.
|
|
47
48
|
*
|
|
48
|
-
* Error responses use the shape `{ error: { code, message } }`.
|
|
49
|
-
* parses that body and returns the message, falling back to the
|
|
49
|
+
* Error responses use the shape `{ success: false, error: { code, message } }`.
|
|
50
|
+
* This helper parses that body and returns the message, falling back to the
|
|
51
|
+
* provided default.
|
|
50
52
|
* Swallows JSON parse failures gracefully.
|
|
51
53
|
*
|
|
52
54
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-utils.mjs","names":[],"sources":["../src/plugin-utils.ts"],"sourcesContent":["/**\n * Shared utilities for plugin admin UIs.\n *\n * Plugin admin components (`admin.tsx`) run inside the EmDash admin dashboard.\n * This module provides the common helpers they all need: API fetching with CSRF\n * protection, response envelope unwrapping, and type narrowing.\n *\n * Import as: `import { apiFetch, parseApiResponse, isRecord } from \"emdash/plugin-utils\";`\n */\n\nimport type { EmDashHandlers } from \"./astro/types.js\";\n\nexport type PublicPluginApiRouteHandler = EmDashHandlers[\"handlePublicPluginApiRoute\"];\n\nexport interface PublicPluginRuntimeLocals {\n\temdash?: {\n\t\thandlePublicPluginApiRoute?: PublicPluginApiRouteHandler;\n\t};\n}\n\n/**\n * Fetch wrapper that adds the `X-EmDash-Request` CSRF protection header.\n *\n * All plugin admin API calls should use this instead of raw `fetch()`.\n * State-changing endpoints reject requests without this header.\n */\nexport function apiFetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n\tconst headers = new Headers(init?.headers);\n\theaders.set(\"X-EmDash-Request\", \"1\");\n\treturn fetch(input, { ...init, headers });\n}\n\n/**\n * Get the public-only plugin route dispatcher exposed to SSR page components.\n *\n * This intentionally reads `handlePublicPluginApiRoute`, not the raw\n * `handlePluginApiRoute` used by core's authenticated plugin API route.\n */\nexport function getPublicPluginApiRouteHandler(\n\tlocals: PublicPluginRuntimeLocals | null | undefined,\n): PublicPluginApiRouteHandler | undefined {\n\tconst handler = locals?.emdash?.handlePublicPluginApiRoute;\n\treturn typeof handler === \"function\" ? handler : undefined;\n}\n\n/**\n * Parse an API response, unwrapping the `{ data: T }` envelope.\n *\n * All plugin API routes return success responses wrapped in `{ data: ... }
|
|
1
|
+
{"version":3,"file":"plugin-utils.mjs","names":[],"sources":["../src/plugin-utils.ts"],"sourcesContent":["/**\n * Shared utilities for plugin admin UIs.\n *\n * Plugin admin components (`admin.tsx`) run inside the EmDash admin dashboard.\n * This module provides the common helpers they all need: API fetching with CSRF\n * protection, response envelope unwrapping, and type narrowing.\n *\n * Import as: `import { apiFetch, parseApiResponse, isRecord } from \"emdash/plugin-utils\";`\n */\n\nimport type { EmDashHandlers } from \"./astro/types.js\";\n\nexport type PublicPluginApiRouteHandler = EmDashHandlers[\"handlePublicPluginApiRoute\"];\n\nexport interface PublicPluginRuntimeLocals {\n\temdash?: {\n\t\thandlePublicPluginApiRoute?: PublicPluginApiRouteHandler;\n\t};\n}\n\n/**\n * Fetch wrapper that adds the `X-EmDash-Request` CSRF protection header.\n *\n * All plugin admin API calls should use this instead of raw `fetch()`.\n * State-changing endpoints reject requests without this header.\n */\nexport function apiFetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n\tconst headers = new Headers(init?.headers);\n\theaders.set(\"X-EmDash-Request\", \"1\");\n\treturn fetch(input, { ...init, headers });\n}\n\n/**\n * Get the public-only plugin route dispatcher exposed to SSR page components.\n *\n * This intentionally reads `handlePublicPluginApiRoute`, not the raw\n * `handlePluginApiRoute` used by core's authenticated plugin API route.\n */\nexport function getPublicPluginApiRouteHandler(\n\tlocals: PublicPluginRuntimeLocals | null | undefined,\n): PublicPluginApiRouteHandler | undefined {\n\tconst handler = locals?.emdash?.handlePublicPluginApiRoute;\n\treturn typeof handler === \"function\" ? handler : undefined;\n}\n\n/**\n * Parse an API response, unwrapping the `{ success, data: T }` envelope.\n *\n * All plugin API routes return success responses wrapped in\n * `{ success: true, data: ... }` by `apiSuccess()`. This helper unwraps that\n * envelope and handles errors.\n *\n * On error responses (non-2xx), throws an Error with the server's message\n * (from `{ success: false, error: { message } }`) or the fallback message.\n *\n * @example\n * ```ts\n * const res = await apiFetch(\"/_emdash/api/plugins/my-plugin/items\");\n * const { items } = await parseApiResponse<{ items: Item[] }>(res, \"Failed to load items\");\n * ```\n */\nexport async function parseApiResponse<T>(\n\tresponse: Response,\n\tfallbackMessage = \"Request failed\",\n): Promise<T> {\n\tif (!response.ok) {\n\t\tthrow new Error(await getErrorMessage(response, `${fallbackMessage}: ${response.statusText}`));\n\t}\n\tconst body: { data: T } = await response.json();\n\treturn body.data;\n}\n\n/**\n * Extract the error message from a failed API response.\n *\n * Error responses use the shape `{ success: false, error: { code, message } }`.\n * This helper parses that body and returns the message, falling back to the\n * provided default.\n * Swallows JSON parse failures gracefully.\n *\n * @example\n * ```ts\n * if (!res.ok) {\n * setError(await getErrorMessage(res, \"Failed to save\"));\n * return;\n * }\n * ```\n */\nexport async function getErrorMessage(response: Response, fallback: string): Promise<string> {\n\tconst body: unknown = await response.json().catch(() => ({}));\n\tif (isRecord(body) && isRecord(body.error)) {\n\t\tconst msg = body.error.message;\n\t\tif (typeof msg === \"string\") return msg;\n\t}\n\treturn fallback;\n}\n\n/**\n * Narrow `unknown` to a plain object record.\n *\n * Useful for safely inspecting untyped API responses before accessing properties.\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,SAAS,OAA+B,MAAuC;CAC9F,MAAM,UAAU,IAAI,QAAQ,MAAM,QAAQ;AAC1C,SAAQ,IAAI,oBAAoB,IAAI;AACpC,QAAO,MAAM,OAAO;EAAE,GAAG;EAAM;EAAS,CAAC;;;;;;;;AAS1C,SAAgB,+BACf,QAC0C;CAC1C,MAAM,UAAU,QAAQ,QAAQ;AAChC,QAAO,OAAO,YAAY,aAAa,UAAU;;;;;;;;;;;;;;;;;;AAmBlD,eAAsB,iBACrB,UACA,kBAAkB,kBACL;AACb,KAAI,CAAC,SAAS,GACb,OAAM,IAAI,MAAM,MAAM,gBAAgB,UAAU,GAAG,gBAAgB,IAAI,SAAS,aAAa,CAAC;AAG/F,SAD0B,MAAM,SAAS,MAAM,EACnC;;;;;;;;;;;;;;;;;;AAmBb,eAAsB,gBAAgB,UAAoB,UAAmC;CAC5F,MAAM,OAAgB,MAAM,SAAS,MAAM,CAAC,aAAa,EAAE,EAAE;AAC7D,KAAI,SAAS,KAAK,IAAI,SAAS,KAAK,MAAM,EAAE;EAC3C,MAAM,MAAM,KAAK,MAAM;AACvB,MAAI,OAAO,QAAQ,SAAU,QAAO;;AAErC,QAAO;;;;;;;AAQR,SAAgB,SAAS,OAAkD;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import "../options-
|
|
2
|
-
import "../types-
|
|
3
|
-
import {
|
|
4
|
-
import "../
|
|
5
|
-
import {
|
|
6
|
-
import "../runner-
|
|
7
|
-
import "../index-
|
|
8
|
-
import "../scheduled-publish-Drffrf2a.mjs";
|
|
1
|
+
import "../options-BqMkWfYa.mjs";
|
|
2
|
+
import "../types-DPKhI5ib.mjs";
|
|
3
|
+
import { Et as ResolvedPlugin } from "../types-BvB7gDOD.mjs";
|
|
4
|
+
import "../relations-Bh8jlFsU.mjs";
|
|
5
|
+
import { gr as PluginDescriptor } from "../index-wYnC6u4o.mjs";
|
|
6
|
+
import "../runner-Dd8m8k9F.mjs";
|
|
7
|
+
import "../index-BEui-cRd.mjs";
|
|
9
8
|
import { SandboxedPlugin } from "../plugin-types.mjs";
|
|
10
|
-
import "../types-
|
|
11
|
-
import "../
|
|
9
|
+
import "../types-C7U0HlEr.mjs";
|
|
10
|
+
import "../hreflang-CIxH_LKz.mjs";
|
|
11
|
+
import "../validate-DULfgpJP.mjs";
|
|
12
12
|
|
|
13
13
|
//#region src/plugins/adapt-sandbox-entry.d.ts
|
|
14
14
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapt-sandbox-entry.d.mts","names":[],"sources":["../../src/plugins/adapt-sandbox-entry.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"adapt-sandbox-entry.d.mts","names":[],"sources":["../../src/plugins/adapt-sandbox-entry.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiJgB,iBAAA,CACf,UAAA,EAAY,eAAA,EACZ,UAAA,EAAY,gBAAA,GACV,cAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as PLUGIN_CAPABILITIES, t as HOOK_NAMES } from "../manifest-schema-
|
|
2
|
-
import { a as normalizeCapabilities } from "../types-
|
|
1
|
+
import { n as PLUGIN_CAPABILITIES, t as HOOK_NAMES } from "../manifest-schema-bCq54i7F.mjs";
|
|
2
|
+
import { a as normalizeCapabilities } from "../types-CK0LxPUQ.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/adapt-sandbox-entry.ts
|
|
5
5
|
/**
|
|
@@ -58,6 +58,8 @@ function normalizeRouteEntry(entry) {
|
|
|
58
58
|
return {
|
|
59
59
|
handler: entry.handler,
|
|
60
60
|
public: entry.public,
|
|
61
|
+
permission: entry.permission,
|
|
62
|
+
cacheControl: entry.cacheControl,
|
|
61
63
|
input: entry.input
|
|
62
64
|
};
|
|
63
65
|
}
|
|
@@ -91,10 +93,12 @@ function adaptSandboxEntry(definition, descriptor) {
|
|
|
91
93
|
}
|
|
92
94
|
const resolvedRoutes = {};
|
|
93
95
|
if (definition.routes) for (const [routeName, rawEntry] of Object.entries(definition.routes)) {
|
|
94
|
-
const { handler, public: publicFlag, input: inputSchema } = normalizeRouteEntry(rawEntry);
|
|
96
|
+
const { handler, public: publicFlag, cacheControl, input: inputSchema, permission } = normalizeRouteEntry(rawEntry);
|
|
95
97
|
resolvedRoutes[routeName] = {
|
|
96
98
|
input: inputSchema,
|
|
97
99
|
public: publicFlag,
|
|
100
|
+
permission,
|
|
101
|
+
cacheControl,
|
|
98
102
|
handler: async (ctx) => {
|
|
99
103
|
const headers = {};
|
|
100
104
|
ctx.request.headers.forEach((value, name) => {
|
|
@@ -131,6 +135,7 @@ function adaptSandboxEntry(definition, descriptor) {
|
|
|
131
135
|
const admin = {};
|
|
132
136
|
if (descriptor.adminPages) admin.pages = descriptor.adminPages;
|
|
133
137
|
if (descriptor.adminWidgets) admin.widgets = descriptor.adminWidgets;
|
|
138
|
+
if (descriptor.settingsSchema) admin.settingsSchema = descriptor.settingsSchema;
|
|
134
139
|
if (descriptor.portableTextBlocks) admin.portableTextBlocks = descriptor.portableTextBlocks;
|
|
135
140
|
if (descriptor.fieldWidgets) admin.fieldWidgets = descriptor.fieldWidgets;
|
|
136
141
|
return {
|
|
@@ -141,6 +146,13 @@ function adaptSandboxEntry(definition, descriptor) {
|
|
|
141
146
|
storage,
|
|
142
147
|
hooks: resolvedHooks,
|
|
143
148
|
routes: resolvedRoutes,
|
|
149
|
+
mcp: { tools: Object.fromEntries(Object.entries(definition.mcp?.tools ?? {}).map(([name, tool]) => [name, {
|
|
150
|
+
description: tool.description,
|
|
151
|
+
route: tool.route,
|
|
152
|
+
input: tool.input,
|
|
153
|
+
output: tool.output,
|
|
154
|
+
destructive: tool.destructive
|
|
155
|
+
}])) },
|
|
144
156
|
admin
|
|
145
157
|
};
|
|
146
158
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapt-sandbox-entry.mjs","names":[],"sources":["../../src/plugins/adapt-sandbox-entry.ts"],"sourcesContent":["/**\n * In-Process Adapter for Standard-Format Plugins\n *\n * Converts a standard plugin definition ({ hooks, routes }) into a\n * ResolvedPlugin compatible with HookPipeline. This allows standard-format\n * plugins to run in-process when placed in the `plugins: []` config array.\n *\n * The adapter wraps each hook and route handler so that the PluginContextFactory\n * provides the same capability-gated context as the native path.\n *\n */\n\nimport type { PluginDescriptor } from \"../astro/integration/runtime.js\";\nimport type { RouteEntry, RouteHandler, SandboxedPlugin } from \"../plugin-types.js\";\nimport { PLUGIN_CAPABILITIES, HOOK_NAMES } from \"./manifest-schema.js\";\nimport { normalizeCapabilities } from \"./types.js\";\nimport type {\n\tResolvedPlugin,\n\tResolvedPluginHooks,\n\tResolvedHook,\n\tPluginRoute,\n\tPluginCapability,\n\tPluginStorageConfig,\n\tPluginAdminConfig,\n} from \"./types.js\";\n\n/**\n * Loose per-hook entry shape used inside the adapter's iteration loop.\n *\n * `SandboxedPlugin.hooks` is a mapped type keyed by hook name, so each\n * entry's type depends on the key. When the adapter iterates with\n * `Object.entries`, the key is `string` (TypeScript can't see the\n * narrowing), so we need a *union* type that covers every hook entry\n * shape — bare handler or config form. This is that union, kept local\n * because it has no use outside the adapter.\n */\n// eslint-disable-next-line typescript-eslint/no-explicit-any -- must accept handlers with specific event types across all hook names\ntype AnyHookHandler = (...args: any[]) => Promise<any>;\ntype AnyHookEntry =\n\t| AnyHookHandler\n\t| {\n\t\t\thandler: AnyHookHandler;\n\t\t\tpriority?: number;\n\t\t\ttimeout?: number;\n\t\t\tdependencies?: string[];\n\t\t\terrorPolicy?: \"continue\" | \"abort\";\n\t\t\texclusive?: boolean;\n\t };\n\n/**\n * Default hook configuration values\n */\nconst DEFAULT_PRIORITY = 100;\nconst DEFAULT_TIMEOUT = 5000;\nconst DEFAULT_ERROR_POLICY = \"abort\" as const;\n\n/**\n * Check if a hook entry is the config form (has a `handler` property).\n */\nfunction isHookConfig(entry: AnyHookEntry): entry is Exclude<AnyHookEntry, AnyHookHandler> {\n\treturn typeof entry === \"object\" && entry !== null && \"handler\" in entry;\n}\n\n/**\n * Resolve a single hook entry to a ResolvedHook.\n *\n * Sandboxed-format hooks use the standard two-arg convention:\n * handler(event, ctx)\n *\n * The HookPipeline dispatch methods also call handlers with (event, ctx),\n * so the handler is compatible as-is — we just normalise the\n * surrounding config (priority, timeout, etc.) to its defaults.\n */\nfunction resolveSandboxedHook(entry: AnyHookEntry, pluginId: string): ResolvedHook<AnyHookHandler> {\n\tif (isHookConfig(entry)) {\n\t\treturn {\n\t\t\tpriority: entry.priority ?? DEFAULT_PRIORITY,\n\t\t\ttimeout: entry.timeout ?? DEFAULT_TIMEOUT,\n\t\t\tdependencies: entry.dependencies ?? [],\n\t\t\terrorPolicy: entry.errorPolicy ?? DEFAULT_ERROR_POLICY,\n\t\t\texclusive: entry.exclusive ?? false,\n\t\t\thandler: entry.handler,\n\t\t\tpluginId,\n\t\t};\n\t}\n\n\t// Bare function handler\n\treturn {\n\t\tpriority: DEFAULT_PRIORITY,\n\t\ttimeout: DEFAULT_TIMEOUT,\n\t\tdependencies: [],\n\t\terrorPolicy: DEFAULT_ERROR_POLICY,\n\t\texclusive: false,\n\t\thandler: entry,\n\t\tpluginId,\n\t};\n}\n\n/**\n * Normalise a `RouteEntry` (bare handler or `{ handler, public?, input? }`\n * config) to the config form. The `input` schema is intentionally typed\n * `unknown` in `RouteEntry` — sandboxed plugins describe it loosely\n * because the strict `z.ZodType<TInput>` constraint of the runtime's\n * `PluginRoute` only narrows once the route is wired into the router.\n * The wider type flows through to the runtime which validates at\n * invocation time.\n */\nfunction normalizeRouteEntry(entry: RouteEntry): {\n\thandler: RouteHandler;\n\tpublic?: boolean;\n\tinput?: PluginRoute[\"input\"];\n} {\n\tif (typeof entry === \"function\") {\n\t\treturn { handler: entry };\n\t}\n\treturn {\n\t\thandler: entry.handler,\n\t\tpublic: entry.public,\n\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- RouteEntry.input is intentionally `unknown` (sandboxed plugins) and validated by the runtime at invocation time\n\t\tinput: entry.input as PluginRoute[\"input\"],\n\t};\n}\n\nconst VALID_CAPABILITIES_SET = new Set<string>(PLUGIN_CAPABILITIES);\n\nconst VALID_HOOK_NAMES_SET = new Set<string>(HOOK_NAMES);\n\n/**\n * Adapt a sandboxed plugin's default export into a ResolvedPlugin.\n *\n * This is the in-process side of sandboxed-format plugins: it takes\n * the `{ hooks, routes }` default export of a sandboxed plugin and\n * produces a `ResolvedPlugin` that enters the HookPipeline alongside\n * native plugins. The descriptor supplies identity (id, version) and\n * the trust contract (capabilities, allowedHosts, storage); the\n * definition supplies behaviour.\n *\n * @param definition - The plugin's default export (matching `SandboxedPlugin` from `emdash/plugin`).\n * @param descriptor - The plugin descriptor with id, version, capabilities, etc.\n * @returns A ResolvedPlugin compatible with HookPipeline.\n */\nexport function adaptSandboxEntry(\n\tdefinition: SandboxedPlugin,\n\tdescriptor: PluginDescriptor,\n): ResolvedPlugin {\n\tconst pluginId = descriptor.id;\n\tconst version = descriptor.version;\n\n\t// A null / array / non-object `definition` would throw a generic\n\t// `TypeError: Cannot read properties of null` further down the\n\t// loop without the plugin id; surface a useful error first.\n\tif (typeof definition !== \"object\" || definition === null || Array.isArray(definition)) {\n\t\tthrow new Error(\n\t\t\t`Plugin \"${pluginId}\" default export must be an object with ` +\n\t\t\t\t`\\`hooks\\` and/or \\`routes\\` (got ${\n\t\t\t\t\tArray.isArray(definition) ? \"array\" : typeof definition\n\t\t\t\t}). Did you forget \\`export default {...} satisfies SandboxedPlugin\\`?`,\n\t\t);\n\t}\n\n\t// Resolve hooks. `SandboxedPlugin.hooks` is keyed by hook name with\n\t// per-key entry types; iterating with `Object.entries` collapses\n\t// keys to `string`, so we treat each entry as the union `AnyHookEntry`\n\t// for the duration of the loop. The widening from the strict mapped\n\t// type to a plain record is sound because each entry still matches\n\t// one of the bare-handler / config-object shapes captured by\n\t// `AnyHookEntry`.\n\tconst resolvedHooks: ResolvedPluginHooks = {};\n\tif (definition.hooks) {\n\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- widening the strict mapped type to a string-keyed record for iteration; entries still match AnyHookEntry\n\t\tconst hookMap = definition.hooks as Record<string, AnyHookEntry>;\n\t\tfor (const [hookName, entry] of Object.entries(hookMap)) {\n\t\t\tif (!VALID_HOOK_NAMES_SET.has(hookName)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Plugin \"${pluginId}\" declares unknown hook \"${hookName}\". ` +\n\t\t\t\t\t\t`Valid hooks: ${[...VALID_HOOK_NAMES_SET].join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The resolved hook has the correct handler type for the hook name.\n\t\t\t// We store it as the generic type and let HookPipeline's typed dispatch\n\t\t\t// methods handle the type narrowing at call time.\n\t\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- bridging untyped map to typed interface\n\t\t\t(resolvedHooks as Record<string, unknown>)[hookName] = resolveSandboxedHook(entry, pluginId);\n\t\t}\n\t}\n\n\t// Resolve routes: sandboxed format uses (routeCtx, pluginCtx) two-arg\n\t// pattern. Native format uses (ctx: RouteContext) single-arg pattern\n\t// where RouteContext extends PluginContext with\n\t// { input, request, requestMeta }. We wrap sandboxed route handlers\n\t// to merge the two args into one.\n\t//\n\t// Route entries can be bare functions or `{ handler, public?, input? }`\n\t// config objects; normalise to the config shape inside the loop.\n\tconst resolvedRoutes: Record<string, PluginRoute> = {};\n\tif (definition.routes) {\n\t\tfor (const [routeName, rawEntry] of Object.entries(definition.routes)) {\n\t\t\tconst normalized = normalizeRouteEntry(rawEntry);\n\t\t\tconst { handler, public: publicFlag, input: inputSchema } = normalized;\n\t\t\tresolvedRoutes[routeName] = {\n\t\t\t\tinput: inputSchema,\n\t\t\t\tpublic: publicFlag,\n\t\t\t\thandler: async (ctx) => {\n\t\t\t\t\t// `ctx.request` is a real WHATWG `Request` (this is the\n\t\t\t\t\t// in-process adapter; the worker-sandbox adapter handles\n\t\t\t\t\t// the serialised case). Flatten `Headers` to the plain\n\t\t\t\t\t// `Record<string, string>` shape that author-facing\n\t\t\t\t\t// `SandboxedRequest` promises so handler bodies are\n\t\t\t\t\t// identical across both adapters.\n\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\tctx.request.headers.forEach((value, name) => {\n\t\t\t\t\t\theaders[name] = value;\n\t\t\t\t\t});\n\t\t\t\t\tconst requestShape = {\n\t\t\t\t\t\turl: ctx.request.url,\n\t\t\t\t\t\tmethod: ctx.request.method,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t};\n\t\t\t\t\tconst routeCtx = {\n\t\t\t\t\t\tinput: ctx.input,\n\t\t\t\t\t\trequest: requestShape,\n\t\t\t\t\t\trequestMeta: ctx.requestMeta,\n\t\t\t\t\t};\n\t\t\t\t\tconst { input: _, request: __, requestMeta: ___, ...pluginCtx } = ctx;\n\t\t\t\t\treturn handler(routeCtx, pluginCtx);\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\t// Build capabilities from descriptor.\n\t// Validate against the known set (same as defineNativePlugin). Both\n\t// current and deprecated names are accepted; deprecated names are\n\t// silently normalized to current names below so the runtime only ever\n\t// sees the canonical form.\n\tconst rawCapabilities = descriptor.capabilities ?? [];\n\tfor (const cap of rawCapabilities) {\n\t\tif (!VALID_CAPABILITIES_SET.has(cap)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid capability \"${cap}\" in plugin \"${pluginId}\". ` +\n\t\t\t\t\t`Valid capabilities: ${[...VALID_CAPABILITIES_SET].join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Silent normalization: rewrite deprecated names to current names.\n\t// Safe assertion — `normalizeCapabilities` only emits validated input\n\t// plus current names from the rename map, all of which are in the union.\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- validated above; normalizeCapabilities only returns capabilities from the union\n\tconst capabilities = normalizeCapabilities(rawCapabilities) as PluginCapability[];\n\tconst allowedHosts = descriptor.allowedHosts ?? [];\n\n\t// Capability implications: broader capabilities imply narrower ones\n\t// (mirrors the normalization in define-plugin.ts for native format).\n\t// Operates on canonical names only.\n\tif (capabilities.includes(\"content:write\") && !capabilities.includes(\"content:read\")) {\n\t\tcapabilities.push(\"content:read\");\n\t}\n\tif (capabilities.includes(\"media:write\") && !capabilities.includes(\"media:read\")) {\n\t\tcapabilities.push(\"media:read\");\n\t}\n\tif (\n\t\tcapabilities.includes(\"network:request:unrestricted\") &&\n\t\t!capabilities.includes(\"network:request\")\n\t) {\n\t\tcapabilities.push(\"network:request\");\n\t}\n\n\t// Build storage config from descriptor.\n\t// StorageCollectionDeclaration uses optional indexes, but PluginStorageConfig\n\t// requires them. Ensure every collection has an indexes array.\n\tconst rawStorage = descriptor.storage ?? {};\n\tconst storage: PluginStorageConfig = {};\n\tfor (const [name, config] of Object.entries(rawStorage)) {\n\t\tstorage[name] = {\n\t\t\tindexes: config.indexes ?? [],\n\t\t\tuniqueIndexes: config.uniqueIndexes,\n\t\t};\n\t}\n\n\t// Build admin config from descriptor.\n\t// Portable Text blocks and field widgets are declarative (Block Kit), so they\n\t// are forwarded for standard/sandboxed plugins just like pages and widgets —\n\t// the admin editor consumes them from the manifest. Only the site-side render\n\t// component (`componentsEntry`) stays native-only.\n\tconst admin: PluginAdminConfig = {};\n\tif (descriptor.adminPages) {\n\t\tadmin.pages = descriptor.adminPages;\n\t}\n\tif (descriptor.adminWidgets) {\n\t\tadmin.widgets = descriptor.adminWidgets;\n\t}\n\tif (descriptor.portableTextBlocks) {\n\t\tadmin.portableTextBlocks = descriptor.portableTextBlocks;\n\t}\n\tif (descriptor.fieldWidgets) {\n\t\tadmin.fieldWidgets = descriptor.fieldWidgets;\n\t}\n\n\treturn {\n\t\tid: pluginId,\n\t\tversion,\n\t\tcapabilities,\n\t\tallowedHosts,\n\t\tstorage,\n\t\thooks: resolvedHooks,\n\t\troutes: resolvedRoutes,\n\t\tadmin,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapt-sandbox-entry.mjs","names":[],"sources":["../../src/plugins/adapt-sandbox-entry.ts"],"sourcesContent":["/**\n * In-Process Adapter for Standard-Format Plugins\n *\n * Converts a standard plugin definition ({ hooks, routes }) into a\n * ResolvedPlugin compatible with HookPipeline. This allows standard-format\n * plugins to run in-process when placed in the `plugins: []` config array.\n *\n * The adapter wraps each hook and route handler so that the PluginContextFactory\n * provides the same capability-gated context as the native path.\n *\n */\n\nimport type { PluginDescriptor } from \"../astro/integration/runtime.js\";\nimport type { RouteEntry, RouteHandler, SandboxedPlugin } from \"../plugin-types.js\";\nimport { PLUGIN_CAPABILITIES, HOOK_NAMES } from \"./manifest-schema.js\";\nimport { normalizeCapabilities } from \"./types.js\";\nimport type {\n\tResolvedPlugin,\n\tResolvedPluginHooks,\n\tResolvedHook,\n\tPluginRoute,\n\tPluginCapability,\n\tPluginStorageConfig,\n\tPluginAdminConfig,\n} from \"./types.js\";\n\n/**\n * Loose per-hook entry shape used inside the adapter's iteration loop.\n *\n * `SandboxedPlugin.hooks` is a mapped type keyed by hook name, so each\n * entry's type depends on the key. When the adapter iterates with\n * `Object.entries`, the key is `string` (TypeScript can't see the\n * narrowing), so we need a *union* type that covers every hook entry\n * shape — bare handler or config form. This is that union, kept local\n * because it has no use outside the adapter.\n */\n// eslint-disable-next-line typescript-eslint/no-explicit-any -- must accept handlers with specific event types across all hook names\ntype AnyHookHandler = (...args: any[]) => Promise<any>;\ntype AnyHookEntry =\n\t| AnyHookHandler\n\t| {\n\t\t\thandler: AnyHookHandler;\n\t\t\tpriority?: number;\n\t\t\ttimeout?: number;\n\t\t\tdependencies?: string[];\n\t\t\terrorPolicy?: \"continue\" | \"abort\";\n\t\t\texclusive?: boolean;\n\t };\n\n/**\n * Default hook configuration values\n */\nconst DEFAULT_PRIORITY = 100;\nconst DEFAULT_TIMEOUT = 5000;\nconst DEFAULT_ERROR_POLICY = \"abort\" as const;\n\n/**\n * Check if a hook entry is the config form (has a `handler` property).\n */\nfunction isHookConfig(entry: AnyHookEntry): entry is Exclude<AnyHookEntry, AnyHookHandler> {\n\treturn typeof entry === \"object\" && entry !== null && \"handler\" in entry;\n}\n\n/**\n * Resolve a single hook entry to a ResolvedHook.\n *\n * Sandboxed-format hooks use the standard two-arg convention:\n * handler(event, ctx)\n *\n * The HookPipeline dispatch methods also call handlers with (event, ctx),\n * so the handler is compatible as-is — we just normalise the\n * surrounding config (priority, timeout, etc.) to its defaults.\n */\nfunction resolveSandboxedHook(entry: AnyHookEntry, pluginId: string): ResolvedHook<AnyHookHandler> {\n\tif (isHookConfig(entry)) {\n\t\treturn {\n\t\t\tpriority: entry.priority ?? DEFAULT_PRIORITY,\n\t\t\ttimeout: entry.timeout ?? DEFAULT_TIMEOUT,\n\t\t\tdependencies: entry.dependencies ?? [],\n\t\t\terrorPolicy: entry.errorPolicy ?? DEFAULT_ERROR_POLICY,\n\t\t\texclusive: entry.exclusive ?? false,\n\t\t\thandler: entry.handler,\n\t\t\tpluginId,\n\t\t};\n\t}\n\n\t// Bare function handler\n\treturn {\n\t\tpriority: DEFAULT_PRIORITY,\n\t\ttimeout: DEFAULT_TIMEOUT,\n\t\tdependencies: [],\n\t\terrorPolicy: DEFAULT_ERROR_POLICY,\n\t\texclusive: false,\n\t\thandler: entry,\n\t\tpluginId,\n\t};\n}\n\n/**\n * Normalise a `RouteEntry` (bare handler or `{ handler, public?, input? }`\n * config) to the config form. The `input` schema is intentionally typed\n * `unknown` in `RouteEntry` — sandboxed plugins describe it loosely\n * because the strict `z.ZodType<TInput>` constraint of the runtime's\n * `PluginRoute` only narrows once the route is wired into the router.\n * The wider type flows through to the runtime which validates at\n * invocation time.\n */\nfunction normalizeRouteEntry(entry: RouteEntry): {\n\thandler: RouteHandler;\n\tpublic?: boolean;\n\tcacheControl?: string;\n\tinput?: PluginRoute[\"input\"];\n\tpermission?: PluginRoute[\"permission\"];\n} {\n\tif (typeof entry === \"function\") {\n\t\treturn { handler: entry };\n\t}\n\treturn {\n\t\thandler: entry.handler,\n\t\tpublic: entry.public,\n\t\tpermission: entry.permission,\n\t\tcacheControl: entry.cacheControl,\n\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- RouteEntry.input is intentionally `unknown` (sandboxed plugins) and validated by the runtime at invocation time\n\t\tinput: entry.input as PluginRoute[\"input\"],\n\t};\n}\n\nconst VALID_CAPABILITIES_SET = new Set<string>(PLUGIN_CAPABILITIES);\n\nconst VALID_HOOK_NAMES_SET = new Set<string>(HOOK_NAMES);\n\n/**\n * Adapt a sandboxed plugin's default export into a ResolvedPlugin.\n *\n * This is the in-process side of sandboxed-format plugins: it takes\n * the `{ hooks, routes }` default export of a sandboxed plugin and\n * produces a `ResolvedPlugin` that enters the HookPipeline alongside\n * native plugins. The descriptor supplies identity (id, version) and\n * the trust contract (capabilities, allowedHosts, storage); the\n * definition supplies behaviour.\n *\n * @param definition - The plugin's default export (matching `SandboxedPlugin` from `emdash/plugin`).\n * @param descriptor - The plugin descriptor with id, version, capabilities, etc.\n * @returns A ResolvedPlugin compatible with HookPipeline.\n */\nexport function adaptSandboxEntry(\n\tdefinition: SandboxedPlugin,\n\tdescriptor: PluginDescriptor,\n): ResolvedPlugin {\n\tconst pluginId = descriptor.id;\n\tconst version = descriptor.version;\n\n\t// A null / array / non-object `definition` would throw a generic\n\t// `TypeError: Cannot read properties of null` further down the\n\t// loop without the plugin id; surface a useful error first.\n\tif (typeof definition !== \"object\" || definition === null || Array.isArray(definition)) {\n\t\tthrow new Error(\n\t\t\t`Plugin \"${pluginId}\" default export must be an object with ` +\n\t\t\t\t`\\`hooks\\` and/or \\`routes\\` (got ${\n\t\t\t\t\tArray.isArray(definition) ? \"array\" : typeof definition\n\t\t\t\t}). Did you forget \\`export default {...} satisfies SandboxedPlugin\\`?`,\n\t\t);\n\t}\n\n\t// Resolve hooks. `SandboxedPlugin.hooks` is keyed by hook name with\n\t// per-key entry types; iterating with `Object.entries` collapses\n\t// keys to `string`, so we treat each entry as the union `AnyHookEntry`\n\t// for the duration of the loop. The widening from the strict mapped\n\t// type to a plain record is sound because each entry still matches\n\t// one of the bare-handler / config-object shapes captured by\n\t// `AnyHookEntry`.\n\tconst resolvedHooks: ResolvedPluginHooks = {};\n\tif (definition.hooks) {\n\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- widening the strict mapped type to a string-keyed record for iteration; entries still match AnyHookEntry\n\t\tconst hookMap = definition.hooks as Record<string, AnyHookEntry>;\n\t\tfor (const [hookName, entry] of Object.entries(hookMap)) {\n\t\t\tif (!VALID_HOOK_NAMES_SET.has(hookName)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Plugin \"${pluginId}\" declares unknown hook \"${hookName}\". ` +\n\t\t\t\t\t\t`Valid hooks: ${[...VALID_HOOK_NAMES_SET].join(\", \")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The resolved hook has the correct handler type for the hook name.\n\t\t\t// We store it as the generic type and let HookPipeline's typed dispatch\n\t\t\t// methods handle the type narrowing at call time.\n\t\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- bridging untyped map to typed interface\n\t\t\t(resolvedHooks as Record<string, unknown>)[hookName] = resolveSandboxedHook(entry, pluginId);\n\t\t}\n\t}\n\n\t// Resolve routes: sandboxed format uses (routeCtx, pluginCtx) two-arg\n\t// pattern. Native format uses (ctx: RouteContext) single-arg pattern\n\t// where RouteContext extends PluginContext with\n\t// { input, request, requestMeta }. We wrap sandboxed route handlers\n\t// to merge the two args into one.\n\t//\n\t// Route entries can be bare functions or `{ handler, public?, input? }`\n\t// config objects; normalise to the config shape inside the loop.\n\tconst resolvedRoutes: Record<string, PluginRoute> = {};\n\tif (definition.routes) {\n\t\tfor (const [routeName, rawEntry] of Object.entries(definition.routes)) {\n\t\t\tconst normalized = normalizeRouteEntry(rawEntry);\n\t\t\tconst {\n\t\t\t\thandler,\n\t\t\t\tpublic: publicFlag,\n\t\t\t\tcacheControl,\n\t\t\t\tinput: inputSchema,\n\t\t\t\tpermission,\n\t\t\t} = normalized;\n\t\t\tresolvedRoutes[routeName] = {\n\t\t\t\tinput: inputSchema,\n\t\t\t\tpublic: publicFlag,\n\t\t\t\tpermission,\n\t\t\t\tcacheControl,\n\t\t\t\thandler: async (ctx) => {\n\t\t\t\t\t// `ctx.request` is a real WHATWG `Request` (this is the\n\t\t\t\t\t// in-process adapter; the worker-sandbox adapter handles\n\t\t\t\t\t// the serialised case). Flatten `Headers` to the plain\n\t\t\t\t\t// `Record<string, string>` shape that author-facing\n\t\t\t\t\t// `SandboxedRequest` promises so handler bodies are\n\t\t\t\t\t// identical across both adapters.\n\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\tctx.request.headers.forEach((value, name) => {\n\t\t\t\t\t\theaders[name] = value;\n\t\t\t\t\t});\n\t\t\t\t\tconst requestShape = {\n\t\t\t\t\t\turl: ctx.request.url,\n\t\t\t\t\t\tmethod: ctx.request.method,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t};\n\t\t\t\t\tconst routeCtx = {\n\t\t\t\t\t\tinput: ctx.input,\n\t\t\t\t\t\trequest: requestShape,\n\t\t\t\t\t\trequestMeta: ctx.requestMeta,\n\t\t\t\t\t};\n\t\t\t\t\tconst { input: _, request: __, requestMeta: ___, ...pluginCtx } = ctx;\n\t\t\t\t\treturn handler(routeCtx, pluginCtx);\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\t// Build capabilities from descriptor.\n\t// Validate against the known set (same as defineNativePlugin). Both\n\t// current and deprecated names are accepted; deprecated names are\n\t// silently normalized to current names below so the runtime only ever\n\t// sees the canonical form.\n\tconst rawCapabilities = descriptor.capabilities ?? [];\n\tfor (const cap of rawCapabilities) {\n\t\tif (!VALID_CAPABILITIES_SET.has(cap)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid capability \"${cap}\" in plugin \"${pluginId}\". ` +\n\t\t\t\t\t`Valid capabilities: ${[...VALID_CAPABILITIES_SET].join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Silent normalization: rewrite deprecated names to current names.\n\t// Safe assertion — `normalizeCapabilities` only emits validated input\n\t// plus current names from the rename map, all of which are in the union.\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- validated above; normalizeCapabilities only returns capabilities from the union\n\tconst capabilities = normalizeCapabilities(rawCapabilities) as PluginCapability[];\n\tconst allowedHosts = descriptor.allowedHosts ?? [];\n\n\t// Capability implications: broader capabilities imply narrower ones\n\t// (mirrors the normalization in define-plugin.ts for native format).\n\t// Operates on canonical names only.\n\tif (capabilities.includes(\"content:write\") && !capabilities.includes(\"content:read\")) {\n\t\tcapabilities.push(\"content:read\");\n\t}\n\tif (capabilities.includes(\"media:write\") && !capabilities.includes(\"media:read\")) {\n\t\tcapabilities.push(\"media:read\");\n\t}\n\tif (\n\t\tcapabilities.includes(\"network:request:unrestricted\") &&\n\t\t!capabilities.includes(\"network:request\")\n\t) {\n\t\tcapabilities.push(\"network:request\");\n\t}\n\n\t// Build storage config from descriptor.\n\t// StorageCollectionDeclaration uses optional indexes, but PluginStorageConfig\n\t// requires them. Ensure every collection has an indexes array.\n\tconst rawStorage = descriptor.storage ?? {};\n\tconst storage: PluginStorageConfig = {};\n\tfor (const [name, config] of Object.entries(rawStorage)) {\n\t\tstorage[name] = {\n\t\t\tindexes: config.indexes ?? [],\n\t\t\tuniqueIndexes: config.uniqueIndexes,\n\t\t};\n\t}\n\n\t// Build admin config from descriptor.\n\t// Portable Text blocks and field widgets are declarative (Block Kit), so they\n\t// are forwarded for standard/sandboxed plugins just like pages and widgets —\n\t// the admin editor consumes them from the manifest. Only the site-side render\n\t// component (`componentsEntry`) stays native-only.\n\tconst admin: PluginAdminConfig = {};\n\tif (descriptor.adminPages) {\n\t\tadmin.pages = descriptor.adminPages;\n\t}\n\tif (descriptor.adminWidgets) {\n\t\tadmin.widgets = descriptor.adminWidgets;\n\t}\n\tif (descriptor.settingsSchema) {\n\t\tadmin.settingsSchema = descriptor.settingsSchema;\n\t}\n\tif (descriptor.portableTextBlocks) {\n\t\tadmin.portableTextBlocks = descriptor.portableTextBlocks;\n\t}\n\tif (descriptor.fieldWidgets) {\n\t\tadmin.fieldWidgets = descriptor.fieldWidgets;\n\t}\n\n\treturn {\n\t\tid: pluginId,\n\t\tversion,\n\t\tcapabilities,\n\t\tallowedHosts,\n\t\tstorage,\n\t\thooks: resolvedHooks,\n\t\troutes: resolvedRoutes,\n\t\tmcp: {\n\t\t\ttools: Object.fromEntries(\n\t\t\t\tObject.entries(definition.mcp?.tools ?? {}).map(([name, tool]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\troute: tool.route,\n\t\t\t\t\t\tinput: tool.input,\n\t\t\t\t\t\toutput: tool.output,\n\t\t\t\t\t\tdestructive: tool.destructive,\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t\t),\n\t\t},\n\t\tadmin,\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -283,4 +283,4 @@ function convertDataForWrite(data, fields) {
|
|
|
283
283
|
|
|
284
284
|
//#endregion
|
|
285
285
|
export { portableTextToMarkdown as i, convertDataForWrite as n, markdownToPortableText as r, convertDataForRead as t };
|
|
286
|
-
//# sourceMappingURL=portable-text-
|
|
286
|
+
//# sourceMappingURL=portable-text-sDj92Kxv.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portable-text-cCa0cGV6.mjs","names":[],"sources":["../src/client/portable-text.ts"],"sourcesContent":["/**\n * Portable Text <-> Markdown conversion layer.\n *\n * Three tiers of block handling:\n * Tier 1: Standard PT blocks <-> standard Markdown (headings, paragraphs, lists, etc.)\n * Tier 2: EmDash custom blocks <-> Markdown directives (future)\n * Tier 3: Unknown blocks <-> opaque HTML comment fences (preserved, not editable)\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Minimal Portable Text block shape */\nexport interface PortableTextBlock {\n\t_type: string;\n\t_key?: string;\n\tstyle?: string;\n\tlevel?: number;\n\tlistItem?: string;\n\tmarkDefs?: MarkDef[];\n\tchildren?: PortableTextSpan[];\n\t[key: string]: unknown;\n}\n\ninterface PortableTextSpan {\n\t_type: string;\n\t_key?: string;\n\ttext?: string;\n\tmarks?: string[];\n\t[key: string]: unknown;\n}\n\ninterface MarkDef {\n\t_key: string;\n\t_type: string;\n\thref?: string;\n\t[key: string]: unknown;\n}\n\ninterface ParsedInline {\n\tspans: PortableTextSpan[];\n\tmarkDefs: MarkDef[];\n}\n\n// ---------------------------------------------------------------------------\n// PT -> Markdown\n// ---------------------------------------------------------------------------\n\n/**\n * Convert Portable Text blocks to Markdown.\n * Unknown block types are serialized as opaque fences.\n */\nexport function portableTextToMarkdown(blocks: PortableTextBlock[]): string {\n\tconst lines: string[] = [];\n\tlet prevWasList = false;\n\n\tfor (let i = 0; i < blocks.length; i++) {\n\t\tconst block = blocks[i];\n\n\t\tif (block._type === \"block\") {\n\t\t\tconst isList = !!block.listItem;\n\n\t\t\t// Blank line between non-contiguous block types\n\t\t\tif (i > 0 && (!isList || !prevWasList)) {\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\n\t\t\tlines.push(renderStandardBlock(block));\n\t\t\tprevWasList = isList;\n\t\t} else if (block._type === \"code\") {\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tconst lang = (block.language as string) || \"\";\n\t\t\tconst code = (block.code as string) || \"\";\n\t\t\tlines.push(\"```\" + lang);\n\t\t\tlines.push(code);\n\t\t\tlines.push(\"```\");\n\t\t\tprevWasList = false;\n\t\t} else if (block._type === \"image\") {\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tconst alt = (block.alt as string) || \"\";\n\t\t\tconst url = (block.asset as { url?: string })?.url || \"\";\n\t\t\tlines.push(``);\n\t\t\tprevWasList = false;\n\t\t} else {\n\t\t\t// Tier 3: Unknown block -> opaque fence\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tlines.push(`<!--ec:block ${JSON.stringify(block)} -->`);\n\t\t\tprevWasList = false;\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction renderStandardBlock(block: PortableTextBlock): string {\n\tconst text = renderSpans(block.children ?? [], block.markDefs ?? []);\n\n\t// List items\n\tif (block.listItem) {\n\t\tconst indent = \" \".repeat(Math.max(0, (block.level ?? 1) - 1));\n\t\tconst marker = block.listItem === \"number\" ? \"1.\" : \"-\";\n\t\treturn `${indent}${marker} ${text}`;\n\t}\n\n\t// Headings\n\tif (block.style && block.style.startsWith(\"h\")) {\n\t\tconst level = parseInt(block.style.substring(1), 10);\n\t\tif (level >= 1 && level <= 6) {\n\t\t\treturn `${\"#\".repeat(level)} ${text}`;\n\t\t}\n\t}\n\n\t// Blockquote\n\tif (block.style === \"blockquote\") {\n\t\treturn `> ${text}`;\n\t}\n\n\treturn text;\n}\n\nfunction renderSpans(spans: PortableTextSpan[], markDefs: MarkDef[]): string {\n\tlet result = \"\";\n\n\tfor (const span of spans) {\n\t\tif (span._type !== \"span\") continue;\n\n\t\tlet text = span.text ?? \"\";\n\t\tconst marks = span.marks ?? [];\n\n\t\tfor (const mark of marks) {\n\t\t\tconst def = markDefs.find((d) => d._key === mark);\n\t\t\tif (def) {\n\t\t\t\tif (def._type === \"link\") {\n\t\t\t\t\ttext = `[${text}](${def.href ?? \"\"})`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (mark) {\n\t\t\t\t\tcase \"strong\":\n\t\t\t\t\t\ttext = `**${text}**`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"em\":\n\t\t\t\t\t\ttext = `_${text}_`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"code\":\n\t\t\t\t\t\ttext = `\\`${text}\\``;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"strike-through\":\n\t\t\t\t\tcase \"strikethrough\":\n\t\t\t\t\t\ttext = `~~${text}~~`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tresult += text;\n\t}\n\n\treturn result;\n}\n\n// ---------------------------------------------------------------------------\n// Markdown -> PT\n// ---------------------------------------------------------------------------\n\n// Regex patterns for markdown parsing\nconst OPAQUE_FENCE_PATTERN = /^<!--ec:block (.+) -->$/;\nconst HEADING_PATTERN = /^(#{1,6})\\s+(.+)$/;\nconst UNORDERED_LIST_PATTERN = /^(\\s*)[-*+]\\s+(.+)$/;\nconst ORDERED_LIST_PATTERN = /^(\\s*)\\d+\\.\\s+(.+)$/;\nconst IMAGE_PATTERN = /^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/;\nconst INLINE_MARKDOWN_PATTERN =\n\t/(\\*\\*(.+?)\\*\\*)|(_(.+?)_)|(`(.+?)`)|(\\[(.+?)\\]\\((.+?)\\))|(~~(.+?)~~)/g;\n\n/**\n * Convert Markdown to Portable Text blocks.\n * Opaque fences (<!--ec:block ... -->) are deserialized and spliced back in.\n */\nexport function markdownToPortableText(markdown: string): PortableTextBlock[] {\n\tconst blocks: PortableTextBlock[] = [];\n\tconst lines = markdown.split(\"\\n\");\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\n\t\t// Opaque fence\n\t\tconst opaqueMatch = line.match(OPAQUE_FENCE_PATTERN);\n\t\tif (opaqueMatch) {\n\t\t\ttry {\n\t\t\t\tblocks.push(JSON.parse(opaqueMatch[1]) as PortableTextBlock);\n\t\t\t} catch {\n\t\t\t\tblocks.push(makeBlock(line));\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Code fence\n\t\tif (line.startsWith(\"```\")) {\n\t\t\tconst lang = line.slice(3).trim();\n\t\t\tconst codeLines: string[] = [];\n\t\t\ti++;\n\t\t\twhile (i < lines.length && !lines[i].startsWith(\"```\")) {\n\t\t\t\tcodeLines.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({\n\t\t\t\t_type: \"code\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\tlanguage: lang || undefined,\n\t\t\t\tcode: codeLines.join(\"\\n\"),\n\t\t\t});\n\t\t\ti++; // skip closing ```\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Blank line\n\t\tif (line.trim() === \"\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Heading\n\t\tconst headingMatch = line.match(HEADING_PATTERN);\n\t\tif (headingMatch) {\n\t\t\tblocks.push(makeBlock(headingMatch[2], `h${headingMatch[1].length}`));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Blockquote\n\t\tif (line.startsWith(\"> \")) {\n\t\t\tblocks.push(makeBlock(line.slice(2), \"blockquote\"));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Unordered list\n\t\tconst ulMatch = line.match(UNORDERED_LIST_PATTERN);\n\t\tif (ulMatch) {\n\t\t\tconst level = Math.floor(ulMatch[1].length / 2) + 1;\n\t\t\tblocks.push(makeListBlock(ulMatch[2], \"bullet\", level));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ordered list\n\t\tconst olMatch = line.match(ORDERED_LIST_PATTERN);\n\t\tif (olMatch) {\n\t\t\tconst level = Math.floor(olMatch[1].length / 2) + 1;\n\t\t\tblocks.push(makeListBlock(olMatch[2], \"number\", level));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Image\n\t\tconst imgMatch = line.match(IMAGE_PATTERN);\n\t\tif (imgMatch) {\n\t\t\tblocks.push({\n\t\t\t\t_type: \"image\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\talt: imgMatch[1],\n\t\t\t\tasset: { url: imgMatch[2] },\n\t\t\t});\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Paragraph\n\t\tblocks.push(makeBlock(line));\n\t\ti++;\n\t}\n\n\treturn blocks;\n}\n\n// ---------------------------------------------------------------------------\n// Block builders\n// ---------------------------------------------------------------------------\n\nfunction makeBlock(text: string, style: string = \"normal\"): PortableTextBlock {\n\tconst { spans, markDefs } = parseInline(text);\n\treturn { _type: \"block\", _key: generateKey(), style, markDefs, children: spans };\n}\n\nfunction makeListBlock(text: string, listItem: string, level: number): PortableTextBlock {\n\tconst { spans, markDefs } = parseInline(text);\n\treturn {\n\t\t_type: \"block\",\n\t\t_key: generateKey(),\n\t\tstyle: \"normal\",\n\t\tlistItem,\n\t\tlevel,\n\t\tmarkDefs,\n\t\tchildren: spans,\n\t};\n}\n\n/**\n * Parse inline markdown (bold, italic, code, links, strikethrough) into PT spans + markDefs.\n */\nfunction parseInline(text: string): ParsedInline {\n\tconst spans: PortableTextSpan[] = [];\n\tconst markDefs: MarkDef[] = [];\n\tconst regex = INLINE_MARKDOWN_PATTERN;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\twhile ((match = regex.exec(text)) !== null) {\n\t\tif (match.index > lastIndex) {\n\t\t\tspans.push({\n\t\t\t\t_type: \"span\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\ttext: text.slice(lastIndex, match.index),\n\t\t\t\tmarks: [],\n\t\t\t});\n\t\t}\n\n\t\tif (match[2] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[2], marks: [\"strong\"] });\n\t\t} else if (match[4] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[4], marks: [\"em\"] });\n\t\t} else if (match[6] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[6], marks: [\"code\"] });\n\t\t} else if (match[8] != null && match[9] != null) {\n\t\t\tconst key = generateKey();\n\t\t\tmarkDefs.push({ _key: key, _type: \"link\", href: match[9] });\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[8], marks: [key] });\n\t\t} else if (match[11] != null) {\n\t\t\tspans.push({\n\t\t\t\t_type: \"span\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\ttext: match[11],\n\t\t\t\tmarks: [\"strike-through\"],\n\t\t\t});\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\tif (lastIndex < text.length) {\n\t\tspans.push({ _type: \"span\", _key: generateKey(), text: text.slice(lastIndex), marks: [] });\n\t}\n\n\tif (spans.length === 0) {\n\t\tspans.push({ _type: \"span\", _key: generateKey(), text, marks: [] });\n\t}\n\n\treturn { spans, markDefs };\n}\n\n// ---------------------------------------------------------------------------\n// Key generation\n// ---------------------------------------------------------------------------\n\nlet keyCounter = 0;\n\nfunction generateKey(): string {\n\treturn `k${(keyCounter++).toString(36)}`;\n}\n\n/** Reset key counter (useful for testing) */\nexport function resetKeyCounter(): void {\n\tkeyCounter = 0;\n}\n\n// ---------------------------------------------------------------------------\n// Schema-aware conversion helpers\n// ---------------------------------------------------------------------------\n\nexport interface FieldSchema {\n\tslug: string;\n\ttype: string;\n}\n\n/**\n * Convert content data for reading: PT fields -> markdown strings.\n * Only converts fields with type \"portableText\" that contain arrays.\n */\nexport function convertDataForRead(\n\tdata: Record<string, unknown>,\n\tfields: FieldSchema[],\n\traw: boolean = false,\n): Record<string, unknown> {\n\tif (raw) return data;\n\n\tconst result = { ...data };\n\tfor (const field of fields) {\n\t\tif (field.type === \"portableText\" && Array.isArray(result[field.slug])) {\n\t\t\tresult[field.slug] = portableTextToMarkdown(result[field.slug] as PortableTextBlock[]);\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Convert content data for writing: markdown strings -> PT arrays.\n * Only converts fields with type \"portableText\" that contain strings.\n */\nexport function convertDataForWrite(\n\tdata: Record<string, unknown>,\n\tfields: FieldSchema[],\n): Record<string, unknown> {\n\tconst result = { ...data };\n\tfor (const field of fields) {\n\t\tif (field.type === \"portableText\" && typeof result[field.slug] === \"string\") {\n\t\t\tresult[field.slug] = markdownToPortableText(result[field.slug] as string);\n\t\t}\n\t}\n\treturn result;\n}\n"],"mappings":";;;;;AAqDA,SAAgB,uBAAuB,QAAqC;CAC3E,MAAM,QAAkB,EAAE;CAC1B,IAAI,cAAc;AAElB,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACvC,MAAM,QAAQ,OAAO;AAErB,MAAI,MAAM,UAAU,SAAS;GAC5B,MAAM,SAAS,CAAC,CAAC,MAAM;AAGvB,OAAI,IAAI,MAAM,CAAC,UAAU,CAAC,aACzB,OAAM,KAAK,GAAG;AAGf,SAAM,KAAK,oBAAoB,MAAM,CAAC;AACtC,iBAAc;aACJ,MAAM,UAAU,QAAQ;AAClC,OAAI,IAAI,EAAG,OAAM,KAAK,GAAG;GACzB,MAAM,OAAQ,MAAM,YAAuB;GAC3C,MAAM,OAAQ,MAAM,QAAmB;AACvC,SAAM,KAAK,QAAQ,KAAK;AACxB,SAAM,KAAK,KAAK;AAChB,SAAM,KAAK,MAAM;AACjB,iBAAc;aACJ,MAAM,UAAU,SAAS;AACnC,OAAI,IAAI,EAAG,OAAM,KAAK,GAAG;GACzB,MAAM,MAAO,MAAM,OAAkB;GACrC,MAAM,MAAO,MAAM,OAA4B,OAAO;AACtD,SAAM,KAAK,KAAK,IAAI,IAAI,IAAI,GAAG;AAC/B,iBAAc;SACR;AAEN,OAAI,IAAI,EAAG,OAAM,KAAK,GAAG;AACzB,SAAM,KAAK,gBAAgB,KAAK,UAAU,MAAM,CAAC,MAAM;AACvD,iBAAc;;;AAIhB,QAAO,MAAM,KAAK,KAAK,GAAG;;AAG3B,SAAS,oBAAoB,OAAkC;CAC9D,MAAM,OAAO,YAAY,MAAM,YAAY,EAAE,EAAE,MAAM,YAAY,EAAE,CAAC;AAGpE,KAAI,MAAM,SAGT,QAAO,GAFQ,KAAK,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,KAAK,EAAE,CAAC,GAChD,MAAM,aAAa,WAAW,OAAO,IAC1B,GAAG;AAI9B,KAAI,MAAM,SAAS,MAAM,MAAM,WAAW,IAAI,EAAE;EAC/C,MAAM,QAAQ,SAAS,MAAM,MAAM,UAAU,EAAE,EAAE,GAAG;AACpD,MAAI,SAAS,KAAK,SAAS,EAC1B,QAAO,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG;;AAKjC,KAAI,MAAM,UAAU,aACnB,QAAO,KAAK;AAGb,QAAO;;AAGR,SAAS,YAAY,OAA2B,UAA6B;CAC5E,IAAI,SAAS;AAEb,MAAK,MAAM,QAAQ,OAAO;AACzB,MAAI,KAAK,UAAU,OAAQ;EAE3B,IAAI,OAAO,KAAK,QAAQ;EACxB,MAAM,QAAQ,KAAK,SAAS,EAAE;AAE9B,OAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,MAAM,SAAS,MAAM,MAAM,EAAE,SAAS,KAAK;AACjD,OAAI,KACH;QAAI,IAAI,UAAU,OACjB,QAAO,IAAI,KAAK,IAAI,IAAI,QAAQ,GAAG;SAGpC,SAAQ,MAAR;IACC,KAAK;AACJ,YAAO,KAAK,KAAK;AACjB;IACD,KAAK;AACJ,YAAO,IAAI,KAAK;AAChB;IACD,KAAK;AACJ,YAAO,KAAK,KAAK;AACjB;IACD,KAAK;IACL,KAAK;AACJ,YAAO,KAAK,KAAK;AACjB;;;AAKJ,YAAU;;AAGX,QAAO;;AAQR,MAAM,uBAAuB;AAC7B,MAAM,kBAAkB;AACxB,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,gBAAgB;AACtB,MAAM,0BACL;;;;;AAMD,SAAgB,uBAAuB,UAAuC;CAC7E,MAAM,SAA8B,EAAE;CACtC,MAAM,QAAQ,SAAS,MAAM,KAAK;CAClC,IAAI,IAAI;AAER,QAAO,IAAI,MAAM,QAAQ;EACxB,MAAM,OAAO,MAAM;EAGnB,MAAM,cAAc,KAAK,MAAM,qBAAqB;AACpD,MAAI,aAAa;AAChB,OAAI;AACH,WAAO,KAAK,KAAK,MAAM,YAAY,GAAG,CAAsB;WACrD;AACP,WAAO,KAAK,UAAU,KAAK,CAAC;;AAE7B;AACA;;AAID,MAAI,KAAK,WAAW,MAAM,EAAE;GAC3B,MAAM,OAAO,KAAK,MAAM,EAAE,CAAC,MAAM;GACjC,MAAM,YAAsB,EAAE;AAC9B;AACA,UAAO,IAAI,MAAM,UAAU,CAAC,MAAM,GAAG,WAAW,MAAM,EAAE;AACvD,cAAU,KAAK,MAAM,GAAG;AACxB;;AAED,UAAO,KAAK;IACX,OAAO;IACP,MAAM,aAAa;IACnB,UAAU,QAAQ;IAClB,MAAM,UAAU,KAAK,KAAK;IAC1B,CAAC;AACF;AACA;;AAID,MAAI,KAAK,MAAM,KAAK,IAAI;AACvB;AACA;;EAID,MAAM,eAAe,KAAK,MAAM,gBAAgB;AAChD,MAAI,cAAc;AACjB,UAAO,KAAK,UAAU,aAAa,IAAI,IAAI,aAAa,GAAG,SAAS,CAAC;AACrE;AACA;;AAID,MAAI,KAAK,WAAW,KAAK,EAAE;AAC1B,UAAO,KAAK,UAAU,KAAK,MAAM,EAAE,EAAE,aAAa,CAAC;AACnD;AACA;;EAID,MAAM,UAAU,KAAK,MAAM,uBAAuB;AAClD,MAAI,SAAS;GACZ,MAAM,QAAQ,KAAK,MAAM,QAAQ,GAAG,SAAS,EAAE,GAAG;AAClD,UAAO,KAAK,cAAc,QAAQ,IAAI,UAAU,MAAM,CAAC;AACvD;AACA;;EAID,MAAM,UAAU,KAAK,MAAM,qBAAqB;AAChD,MAAI,SAAS;GACZ,MAAM,QAAQ,KAAK,MAAM,QAAQ,GAAG,SAAS,EAAE,GAAG;AAClD,UAAO,KAAK,cAAc,QAAQ,IAAI,UAAU,MAAM,CAAC;AACvD;AACA;;EAID,MAAM,WAAW,KAAK,MAAM,cAAc;AAC1C,MAAI,UAAU;AACb,UAAO,KAAK;IACX,OAAO;IACP,MAAM,aAAa;IACnB,KAAK,SAAS;IACd,OAAO,EAAE,KAAK,SAAS,IAAI;IAC3B,CAAC;AACF;AACA;;AAID,SAAO,KAAK,UAAU,KAAK,CAAC;AAC5B;;AAGD,QAAO;;AAOR,SAAS,UAAU,MAAc,QAAgB,UAA6B;CAC7E,MAAM,EAAE,OAAO,aAAa,YAAY,KAAK;AAC7C,QAAO;EAAE,OAAO;EAAS,MAAM,aAAa;EAAE;EAAO;EAAU,UAAU;EAAO;;AAGjF,SAAS,cAAc,MAAc,UAAkB,OAAkC;CACxF,MAAM,EAAE,OAAO,aAAa,YAAY,KAAK;AAC7C,QAAO;EACN,OAAO;EACP,MAAM,aAAa;EACnB,OAAO;EACP;EACA;EACA;EACA,UAAU;EACV;;;;;AAMF,SAAS,YAAY,MAA4B;CAChD,MAAM,QAA4B,EAAE;CACpC,MAAM,WAAsB,EAAE;CAC9B,MAAM,QAAQ;CAEd,IAAI,YAAY;CAChB,IAAI;AAEJ,SAAQ,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM;AAC3C,MAAI,MAAM,QAAQ,UACjB,OAAM,KAAK;GACV,OAAO;GACP,MAAM,aAAa;GACnB,MAAM,KAAK,MAAM,WAAW,MAAM,MAAM;GACxC,OAAO,EAAE;GACT,CAAC;AAGH,MAAI,MAAM,MAAM,KACf,OAAM,KAAK;GAAE,OAAO;GAAQ,MAAM,aAAa;GAAE,MAAM,MAAM;GAAI,OAAO,CAAC,SAAS;GAAE,CAAC;WAC3E,MAAM,MAAM,KACtB,OAAM,KAAK;GAAE,OAAO;GAAQ,MAAM,aAAa;GAAE,MAAM,MAAM;GAAI,OAAO,CAAC,KAAK;GAAE,CAAC;WACvE,MAAM,MAAM,KACtB,OAAM,KAAK;GAAE,OAAO;GAAQ,MAAM,aAAa;GAAE,MAAM,MAAM;GAAI,OAAO,CAAC,OAAO;GAAE,CAAC;WACzE,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM;GAChD,MAAM,MAAM,aAAa;AACzB,YAAS,KAAK;IAAE,MAAM;IAAK,OAAO;IAAQ,MAAM,MAAM;IAAI,CAAC;AAC3D,SAAM,KAAK;IAAE,OAAO;IAAQ,MAAM,aAAa;IAAE,MAAM,MAAM;IAAI,OAAO,CAAC,IAAI;IAAE,CAAC;aACtE,MAAM,OAAO,KACvB,OAAM,KAAK;GACV,OAAO;GACP,MAAM,aAAa;GACnB,MAAM,MAAM;GACZ,OAAO,CAAC,iBAAiB;GACzB,CAAC;AAGH,cAAY,MAAM,QAAQ,MAAM,GAAG;;AAGpC,KAAI,YAAY,KAAK,OACpB,OAAM,KAAK;EAAE,OAAO;EAAQ,MAAM,aAAa;EAAE,MAAM,KAAK,MAAM,UAAU;EAAE,OAAO,EAAE;EAAE,CAAC;AAG3F,KAAI,MAAM,WAAW,EACpB,OAAM,KAAK;EAAE,OAAO;EAAQ,MAAM,aAAa;EAAE;EAAM,OAAO,EAAE;EAAE,CAAC;AAGpE,QAAO;EAAE;EAAO;EAAU;;AAO3B,IAAI,aAAa;AAEjB,SAAS,cAAsB;AAC9B,QAAO,KAAK,cAAc,SAAS,GAAG;;;;;;AAqBvC,SAAgB,mBACf,MACA,QACA,MAAe,OACW;AAC1B,KAAI,IAAK,QAAO;CAEhB,MAAM,SAAS,EAAE,GAAG,MAAM;AAC1B,MAAK,MAAM,SAAS,OACnB,KAAI,MAAM,SAAS,kBAAkB,MAAM,QAAQ,OAAO,MAAM,MAAM,CACrE,QAAO,MAAM,QAAQ,uBAAuB,OAAO,MAAM,MAA6B;AAGxF,QAAO;;;;;;AAOR,SAAgB,oBACf,MACA,QAC0B;CAC1B,MAAM,SAAS,EAAE,GAAG,MAAM;AAC1B,MAAK,MAAM,SAAS,OACnB,KAAI,MAAM,SAAS,kBAAkB,OAAO,OAAO,MAAM,UAAU,SAClE,QAAO,MAAM,QAAQ,uBAAuB,OAAO,MAAM,MAAgB;AAG3E,QAAO"}
|
|
1
|
+
{"version":3,"file":"portable-text-sDj92Kxv.mjs","names":[],"sources":["../src/client/portable-text.ts"],"sourcesContent":["/**\n * Portable Text <-> Markdown conversion layer.\n *\n * Three tiers of block handling:\n * Tier 1: Standard PT blocks <-> standard Markdown (headings, paragraphs, lists, etc.)\n * Tier 2: EmDash custom blocks <-> Markdown directives (future)\n * Tier 3: Unknown blocks <-> opaque HTML comment fences (preserved, not editable)\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Minimal Portable Text block shape */\nexport interface PortableTextBlock {\n\t_type: string;\n\t_key?: string;\n\tstyle?: string;\n\tlevel?: number;\n\tlistItem?: string;\n\tmarkDefs?: MarkDef[];\n\tchildren?: PortableTextSpan[];\n\t[key: string]: unknown;\n}\n\ninterface PortableTextSpan {\n\t_type: string;\n\t_key?: string;\n\ttext?: string;\n\tmarks?: string[];\n\t[key: string]: unknown;\n}\n\ninterface MarkDef {\n\t_key: string;\n\t_type: string;\n\thref?: string;\n\t[key: string]: unknown;\n}\n\ninterface ParsedInline {\n\tspans: PortableTextSpan[];\n\tmarkDefs: MarkDef[];\n}\n\n// ---------------------------------------------------------------------------\n// PT -> Markdown\n// ---------------------------------------------------------------------------\n\n/**\n * Convert Portable Text blocks to Markdown.\n * Unknown block types are serialized as opaque fences.\n */\nexport function portableTextToMarkdown(blocks: PortableTextBlock[]): string {\n\tconst lines: string[] = [];\n\tlet prevWasList = false;\n\n\tfor (let i = 0; i < blocks.length; i++) {\n\t\tconst block = blocks[i];\n\n\t\tif (block._type === \"block\") {\n\t\t\tconst isList = !!block.listItem;\n\n\t\t\t// Blank line between non-contiguous block types\n\t\t\tif (i > 0 && (!isList || !prevWasList)) {\n\t\t\t\tlines.push(\"\");\n\t\t\t}\n\n\t\t\tlines.push(renderStandardBlock(block));\n\t\t\tprevWasList = isList;\n\t\t} else if (block._type === \"code\") {\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tconst lang = (block.language as string) || \"\";\n\t\t\tconst code = (block.code as string) || \"\";\n\t\t\tlines.push(\"```\" + lang);\n\t\t\tlines.push(code);\n\t\t\tlines.push(\"```\");\n\t\t\tprevWasList = false;\n\t\t} else if (block._type === \"image\") {\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tconst alt = (block.alt as string) || \"\";\n\t\t\tconst url = (block.asset as { url?: string })?.url || \"\";\n\t\t\tlines.push(``);\n\t\t\tprevWasList = false;\n\t\t} else {\n\t\t\t// Tier 3: Unknown block -> opaque fence\n\t\t\tif (i > 0) lines.push(\"\");\n\t\t\tlines.push(`<!--ec:block ${JSON.stringify(block)} -->`);\n\t\t\tprevWasList = false;\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction renderStandardBlock(block: PortableTextBlock): string {\n\tconst text = renderSpans(block.children ?? [], block.markDefs ?? []);\n\n\t// List items\n\tif (block.listItem) {\n\t\tconst indent = \" \".repeat(Math.max(0, (block.level ?? 1) - 1));\n\t\tconst marker = block.listItem === \"number\" ? \"1.\" : \"-\";\n\t\treturn `${indent}${marker} ${text}`;\n\t}\n\n\t// Headings\n\tif (block.style && block.style.startsWith(\"h\")) {\n\t\tconst level = parseInt(block.style.substring(1), 10);\n\t\tif (level >= 1 && level <= 6) {\n\t\t\treturn `${\"#\".repeat(level)} ${text}`;\n\t\t}\n\t}\n\n\t// Blockquote\n\tif (block.style === \"blockquote\") {\n\t\treturn `> ${text}`;\n\t}\n\n\treturn text;\n}\n\nfunction renderSpans(spans: PortableTextSpan[], markDefs: MarkDef[]): string {\n\tlet result = \"\";\n\n\tfor (const span of spans) {\n\t\tif (span._type !== \"span\") continue;\n\n\t\tlet text = span.text ?? \"\";\n\t\tconst marks = span.marks ?? [];\n\n\t\tfor (const mark of marks) {\n\t\t\tconst def = markDefs.find((d) => d._key === mark);\n\t\t\tif (def) {\n\t\t\t\tif (def._type === \"link\") {\n\t\t\t\t\ttext = `[${text}](${def.href ?? \"\"})`;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (mark) {\n\t\t\t\t\tcase \"strong\":\n\t\t\t\t\t\ttext = `**${text}**`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"em\":\n\t\t\t\t\t\ttext = `_${text}_`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"code\":\n\t\t\t\t\t\ttext = `\\`${text}\\``;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"strike-through\":\n\t\t\t\t\tcase \"strikethrough\":\n\t\t\t\t\t\ttext = `~~${text}~~`;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tresult += text;\n\t}\n\n\treturn result;\n}\n\n// ---------------------------------------------------------------------------\n// Markdown -> PT\n// ---------------------------------------------------------------------------\n\n// Regex patterns for markdown parsing\nconst OPAQUE_FENCE_PATTERN = /^<!--ec:block (.+) -->$/;\nconst HEADING_PATTERN = /^(#{1,6})\\s+(.+)$/;\nconst UNORDERED_LIST_PATTERN = /^(\\s*)[-*+]\\s+(.+)$/;\nconst ORDERED_LIST_PATTERN = /^(\\s*)\\d+\\.\\s+(.+)$/;\nconst IMAGE_PATTERN = /^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/;\nconst INLINE_MARKDOWN_PATTERN =\n\t/(\\*\\*(.+?)\\*\\*)|(_(.+?)_)|(`(.+?)`)|(\\[(.+?)\\]\\((.+?)\\))|(~~(.+?)~~)/g;\n\n/**\n * Convert Markdown to Portable Text blocks.\n * Opaque fences (<!--ec:block ... -->) are deserialized and spliced back in.\n */\nexport function markdownToPortableText(markdown: string): PortableTextBlock[] {\n\tconst blocks: PortableTextBlock[] = [];\n\tconst lines = markdown.split(\"\\n\");\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\n\t\t// Opaque fence\n\t\tconst opaqueMatch = line.match(OPAQUE_FENCE_PATTERN);\n\t\tif (opaqueMatch) {\n\t\t\ttry {\n\t\t\t\tblocks.push(JSON.parse(opaqueMatch[1]) as PortableTextBlock);\n\t\t\t} catch {\n\t\t\t\tblocks.push(makeBlock(line));\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Code fence\n\t\tif (line.startsWith(\"```\")) {\n\t\t\tconst lang = line.slice(3).trim();\n\t\t\tconst codeLines: string[] = [];\n\t\t\ti++;\n\t\t\twhile (i < lines.length && !lines[i].startsWith(\"```\")) {\n\t\t\t\tcodeLines.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({\n\t\t\t\t_type: \"code\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\tlanguage: lang || undefined,\n\t\t\t\tcode: codeLines.join(\"\\n\"),\n\t\t\t});\n\t\t\ti++; // skip closing ```\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Blank line\n\t\tif (line.trim() === \"\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Heading\n\t\tconst headingMatch = line.match(HEADING_PATTERN);\n\t\tif (headingMatch) {\n\t\t\tblocks.push(makeBlock(headingMatch[2], `h${headingMatch[1].length}`));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Blockquote\n\t\tif (line.startsWith(\"> \")) {\n\t\t\tblocks.push(makeBlock(line.slice(2), \"blockquote\"));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Unordered list\n\t\tconst ulMatch = line.match(UNORDERED_LIST_PATTERN);\n\t\tif (ulMatch) {\n\t\t\tconst level = Math.floor(ulMatch[1].length / 2) + 1;\n\t\t\tblocks.push(makeListBlock(ulMatch[2], \"bullet\", level));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ordered list\n\t\tconst olMatch = line.match(ORDERED_LIST_PATTERN);\n\t\tif (olMatch) {\n\t\t\tconst level = Math.floor(olMatch[1].length / 2) + 1;\n\t\t\tblocks.push(makeListBlock(olMatch[2], \"number\", level));\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Image\n\t\tconst imgMatch = line.match(IMAGE_PATTERN);\n\t\tif (imgMatch) {\n\t\t\tblocks.push({\n\t\t\t\t_type: \"image\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\talt: imgMatch[1],\n\t\t\t\tasset: { url: imgMatch[2] },\n\t\t\t});\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Paragraph\n\t\tblocks.push(makeBlock(line));\n\t\ti++;\n\t}\n\n\treturn blocks;\n}\n\n// ---------------------------------------------------------------------------\n// Block builders\n// ---------------------------------------------------------------------------\n\nfunction makeBlock(text: string, style: string = \"normal\"): PortableTextBlock {\n\tconst { spans, markDefs } = parseInline(text);\n\treturn { _type: \"block\", _key: generateKey(), style, markDefs, children: spans };\n}\n\nfunction makeListBlock(text: string, listItem: string, level: number): PortableTextBlock {\n\tconst { spans, markDefs } = parseInline(text);\n\treturn {\n\t\t_type: \"block\",\n\t\t_key: generateKey(),\n\t\tstyle: \"normal\",\n\t\tlistItem,\n\t\tlevel,\n\t\tmarkDefs,\n\t\tchildren: spans,\n\t};\n}\n\n/**\n * Parse inline markdown (bold, italic, code, links, strikethrough) into PT spans + markDefs.\n */\nfunction parseInline(text: string): ParsedInline {\n\tconst spans: PortableTextSpan[] = [];\n\tconst markDefs: MarkDef[] = [];\n\tconst regex = INLINE_MARKDOWN_PATTERN;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\twhile ((match = regex.exec(text)) !== null) {\n\t\tif (match.index > lastIndex) {\n\t\t\tspans.push({\n\t\t\t\t_type: \"span\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\ttext: text.slice(lastIndex, match.index),\n\t\t\t\tmarks: [],\n\t\t\t});\n\t\t}\n\n\t\tif (match[2] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[2], marks: [\"strong\"] });\n\t\t} else if (match[4] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[4], marks: [\"em\"] });\n\t\t} else if (match[6] != null) {\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[6], marks: [\"code\"] });\n\t\t} else if (match[8] != null && match[9] != null) {\n\t\t\tconst key = generateKey();\n\t\t\tmarkDefs.push({ _key: key, _type: \"link\", href: match[9] });\n\t\t\tspans.push({ _type: \"span\", _key: generateKey(), text: match[8], marks: [key] });\n\t\t} else if (match[11] != null) {\n\t\t\tspans.push({\n\t\t\t\t_type: \"span\",\n\t\t\t\t_key: generateKey(),\n\t\t\t\ttext: match[11],\n\t\t\t\tmarks: [\"strike-through\"],\n\t\t\t});\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\tif (lastIndex < text.length) {\n\t\tspans.push({ _type: \"span\", _key: generateKey(), text: text.slice(lastIndex), marks: [] });\n\t}\n\n\tif (spans.length === 0) {\n\t\tspans.push({ _type: \"span\", _key: generateKey(), text, marks: [] });\n\t}\n\n\treturn { spans, markDefs };\n}\n\n// ---------------------------------------------------------------------------\n// Key generation\n// ---------------------------------------------------------------------------\n\nlet keyCounter = 0;\n\nfunction generateKey(): string {\n\treturn `k${(keyCounter++).toString(36)}`;\n}\n\n/** Reset key counter (useful for testing) */\nexport function resetKeyCounter(): void {\n\tkeyCounter = 0;\n}\n\n// ---------------------------------------------------------------------------\n// Schema-aware conversion helpers\n// ---------------------------------------------------------------------------\n\nexport interface FieldSchema {\n\tslug: string;\n\ttype: string;\n}\n\n/**\n * Convert content data for reading: PT fields -> markdown strings.\n * Only converts fields with type \"portableText\" that contain arrays.\n */\nexport function convertDataForRead(\n\tdata: Record<string, unknown>,\n\tfields: FieldSchema[],\n\traw: boolean = false,\n): Record<string, unknown> {\n\tif (raw) return data;\n\n\tconst result = { ...data };\n\tfor (const field of fields) {\n\t\tif (field.type === \"portableText\" && Array.isArray(result[field.slug])) {\n\t\t\tresult[field.slug] = portableTextToMarkdown(result[field.slug] as PortableTextBlock[]);\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Convert content data for writing: markdown strings -> PT arrays.\n * Only converts fields with type \"portableText\" that contain strings.\n */\nexport function convertDataForWrite(\n\tdata: Record<string, unknown>,\n\tfields: FieldSchema[],\n): Record<string, unknown> {\n\tconst result = { ...data };\n\tfor (const field of fields) {\n\t\tif (field.type === \"portableText\" && typeof result[field.slug] === \"string\") {\n\t\t\tresult[field.slug] = markdownToPortableText(result[field.slug] as string);\n\t\t}\n\t}\n\treturn result;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as generatePreviewToken } from "./tokens-
|
|
1
|
+
import { t as generatePreviewToken } from "./tokens-DVltpO2D.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/preview/urls.ts
|
|
4
4
|
/**
|
|
@@ -104,4 +104,4 @@ function getPreviewToken(url) {
|
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
106
|
export { getPreviewUrl as i, isPreviewRequest as n, buildPreviewUrl as r, getPreviewToken as t };
|
|
107
|
-
//# sourceMappingURL=preview-
|
|
107
|
+
//# sourceMappingURL=preview-D4Jnbfx7.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-
|
|
1
|
+
{"version":3,"file":"preview-D4Jnbfx7.mjs","names":[],"sources":["../src/preview/urls.ts","../src/preview/helpers.ts"],"sourcesContent":["/**\n * Preview URL generation\n *\n * Creates preview URLs that include a signed token for accessing draft content.\n */\n\nimport { generatePreviewToken } from \"./tokens.js\";\n\nconst REPEATED_SLASHES = /\\/{2,}/g;\n\n/**\n * Options for generating a preview URL\n */\nexport interface GetPreviewUrlOptions {\n\t/** Collection slug (e.g., \"posts\") */\n\tcollection: string;\n\t/** Content ID or slug */\n\tid: string;\n\t/** Secret key for signing the token */\n\tsecret: string;\n\t/** How long the preview URL is valid. Default: \"1h\" */\n\texpiresIn?: string | number;\n\t/** Base URL of the site. If not provided, returns a relative URL. */\n\tbaseUrl?: string;\n\t/**\n\t * Custom path pattern. Supports `{collection}`, `{id}` and `{locale}`\n\t * placeholders. Default: `\"/{collection}/{id}\"`.\n\t */\n\tpathPattern?: string;\n\t/**\n\t * Locale segment substituted for the `{locale}` placeholder in `pathPattern`.\n\t * Pass an empty string to omit the locale prefix (e.g. for the default locale\n\t * when `prefixDefaultLocale` is `false`); adjacent slashes left by an empty\n\t * value are collapsed and any trailing slash is trimmed.\n\t */\n\tlocale?: string;\n}\n\n/**\n * Generate a preview URL for content\n *\n * The URL includes a `_preview` query parameter with a signed token.\n *\n * @example\n * ```ts\n * const url = await getPreviewUrl({\n * collection: \"posts\",\n * id: \"hello-world\",\n * secret: process.env.PREVIEW_SECRET!,\n * });\n * // Returns: /posts/hello-world?_preview=eyJj...\n *\n * // With base URL:\n * const fullUrl = await getPreviewUrl({\n * collection: \"posts\",\n * id: \"hello-world\",\n * secret: process.env.PREVIEW_SECRET!,\n * baseUrl: \"https://example.com\",\n * });\n * // Returns: https://example.com/posts/hello-world?_preview=eyJj...\n *\n * // Custom path pattern:\n * const customUrl = await getPreviewUrl({\n * collection: \"posts\",\n * id: \"hello-world\",\n * secret: process.env.PREVIEW_SECRET!,\n * pathPattern: \"/blog/{id}\",\n * });\n * // Returns: /blog/hello-world?_preview=eyJj...\n * ```\n */\nexport async function getPreviewUrl(options: GetPreviewUrlOptions): Promise<string> {\n\tconst {\n\t\tcollection,\n\t\tid,\n\t\tsecret,\n\t\texpiresIn = \"1h\",\n\t\tbaseUrl,\n\t\tpathPattern = \"/{collection}/{id}\",\n\t\tlocale = \"\",\n\t} = options;\n\n\t// Generate the signed token\n\tconst token = await generatePreviewToken({\n\t\tcontentId: `${collection}:${id}`,\n\t\texpiresIn,\n\t\tsecret,\n\t});\n\n\t// Build the path. `{locale}` may resolve to an empty string (default locale\n\t// without a prefix); collapse the resulting double slashes and trim a\n\t// trailing slash so the URL stays clean.\n\tlet path = pathPattern\n\t\t.replace(\"{collection}\", collection)\n\t\t.replace(\"{id}\", id)\n\t\t.replace(\"{locale}\", locale);\n\tpath = path.replace(REPEATED_SLASHES, \"/\");\n\tif (path.length > 1 && path.endsWith(\"/\")) path = path.slice(0, -1);\n\n\t// Add token as query parameter\n\tconst url = new URL(path, baseUrl || \"http://placeholder\");\n\turl.searchParams.set(\"_preview\", token);\n\n\t// Return relative URL if no baseUrl provided\n\tif (!baseUrl) {\n\t\treturn `${url.pathname}${url.search}`;\n\t}\n\n\treturn url.toString();\n}\n\n/**\n * Build a preview URL from a token (when you already have the token)\n *\n * @example\n * ```ts\n * const url = buildPreviewUrl({\n * path: \"/posts/hello-world\",\n * token: existingToken,\n * });\n * ```\n */\nexport function buildPreviewUrl(options: {\n\tpath: string;\n\ttoken: string;\n\tbaseUrl?: string;\n}): string {\n\tconst { path, token, baseUrl } = options;\n\n\tconst url = new URL(path, baseUrl || \"http://placeholder\");\n\turl.searchParams.set(\"_preview\", token);\n\n\tif (!baseUrl) {\n\t\treturn `${url.pathname}${url.search}`;\n\t}\n\n\treturn url.toString();\n}\n","/**\n * Preview helpers for Astro pages\n */\n\n/**\n * Check if a request is a preview request\n *\n * @example\n * ```ts\n * const isPreview = isPreviewRequest(Astro.url);\n * ```\n */\nexport function isPreviewRequest(url: URL): boolean {\n\treturn url.searchParams.has(\"_preview\");\n}\n\n/**\n * Get the preview token from a URL\n *\n * @example\n * ```ts\n * const token = getPreviewToken(Astro.url);\n * ```\n */\nexport function getPreviewToken(url: URL): string | null {\n\treturn url.searchParams.get(\"_preview\");\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DzB,eAAsB,cAAc,SAAgD;CACnF,MAAM,EACL,YACA,IACA,QACA,YAAY,MACZ,SACA,cAAc,sBACd,SAAS,OACN;CAGJ,MAAM,QAAQ,MAAM,qBAAqB;EACxC,WAAW,GAAG,WAAW,GAAG;EAC5B;EACA;EACA,CAAC;CAKF,IAAI,OAAO,YACT,QAAQ,gBAAgB,WAAW,CACnC,QAAQ,QAAQ,GAAG,CACnB,QAAQ,YAAY,OAAO;AAC7B,QAAO,KAAK,QAAQ,kBAAkB,IAAI;AAC1C,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,CAAE,QAAO,KAAK,MAAM,GAAG,GAAG;CAGnE,MAAM,MAAM,IAAI,IAAI,MAAM,WAAW,qBAAqB;AAC1D,KAAI,aAAa,IAAI,YAAY,MAAM;AAGvC,KAAI,CAAC,QACJ,QAAO,GAAG,IAAI,WAAW,IAAI;AAG9B,QAAO,IAAI,UAAU;;;;;;;;;;;;;AActB,SAAgB,gBAAgB,SAIrB;CACV,MAAM,EAAE,MAAM,OAAO,YAAY;CAEjC,MAAM,MAAM,IAAI,IAAI,MAAM,WAAW,qBAAqB;AAC1D,KAAI,aAAa,IAAI,YAAY,MAAM;AAEvC,KAAI,CAAC,QACJ,QAAO,GAAG,IAAI,WAAW,IAAI;AAG9B,QAAO,IAAI,UAAU;;;;;;;;;;;;;;;;AC5HtB,SAAgB,iBAAiB,KAAmB;AACnD,QAAO,IAAI,aAAa,IAAI,WAAW;;;;;;;;;;AAWxC,SAAgB,gBAAgB,KAAyB;AACxD,QAAO,IAAI,aAAa,IAAI,WAAW"}
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* the build. Container deployments set env vars at runtime, so we must read
|
|
8
8
|
* process.env which Vite leaves untouched.
|
|
9
9
|
*
|
|
10
|
-
* On Cloudflare Workers process.env is
|
|
11
|
-
*
|
|
10
|
+
* On Cloudflare Workers process.env is empty by default, so the fallback
|
|
11
|
+
* chain continues to url.origin — unless the Worker enables the
|
|
12
|
+
* `nodejs_compat_populate_process_env` compatibility flag, in which case
|
|
13
|
+
* `vars`/secrets (e.g. EMDASH_SITE_URL) are readable here too.
|
|
12
14
|
*
|
|
13
15
|
* Caches after first call.
|
|
14
16
|
*/
|
|
@@ -85,4 +87,4 @@ function getEnvAllowedOrigins() {
|
|
|
85
87
|
|
|
86
88
|
//#endregion
|
|
87
89
|
export { getPublicOrigin as n, getEnvAllowedOrigins as t };
|
|
88
|
-
//# sourceMappingURL=public-url-
|
|
90
|
+
//# sourceMappingURL=public-url-DSGTnJFw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-url-DSGTnJFw.mjs","names":[],"sources":["../src/api/public-url.ts"],"sourcesContent":["/**\n * Public URL helpers for reverse-proxy deployments.\n *\n * Behind a TLS-terminating proxy the internal request URL\n * (`http://localhost:4321`) differs from the browser-facing origin\n * (`https://mysite.example.com`). These pure helpers resolve the\n * correct public origin from config, falling back to the request URL.\n *\n * Workers-safe: no Node.js imports.\n */\n\n/** Minimal config shape — avoids importing the full EmDashConfig type tree. */\ninterface SiteUrlConfig {\n\tsiteUrl?: string;\n}\n\n/**\n * Resolve siteUrl from runtime environment variables.\n *\n * Uses process.env (not import.meta.env) because Vite statically replaces\n * import.meta.env at build time, baking out any env vars not present during\n * the build. Container deployments set env vars at runtime, so we must read\n * process.env which Vite leaves untouched.\n *\n * On Cloudflare Workers process.env is empty by default, so the fallback\n * chain continues to url.origin — unless the Worker enables the\n * `nodejs_compat_populate_process_env` compatibility flag, in which case\n * `vars`/secrets (e.g. EMDASH_SITE_URL) are readable here too.\n *\n * Caches after first call.\n */\nlet _envSiteUrl: string | undefined | null = null;\n\n/** @internal Reset cached env values — test-only. */\nexport function _resetEnvCache(): void {\n\t_envSiteUrl = null;\n\t_envAllowedOrigins = null;\n}\n\nfunction getEnvSiteUrl(): string | undefined {\n\tif (_envSiteUrl !== null) return _envSiteUrl || undefined;\n\ttry {\n\t\t// process.env is available on Node.js; undefined on Workers\n\t\tconst value =\n\t\t\t(typeof process !== \"undefined\" && process.env?.EMDASH_SITE_URL) ||\n\t\t\t(typeof process !== \"undefined\" && process.env?.SITE_URL) ||\n\t\t\t\"\";\n\t\tif (value) {\n\t\t\tconst parsed = new URL(value);\n\t\t\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\t\t\t_envSiteUrl = \"\";\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\t_envSiteUrl = parsed.origin;\n\t\t} else {\n\t\t\t_envSiteUrl = \"\";\n\t\t}\n\t} catch {\n\t\t_envSiteUrl = \"\";\n\t}\n\treturn _envSiteUrl || undefined;\n}\n\n/**\n * Return the public-facing origin for the site.\n *\n * Resolution order:\n * 1. `config.siteUrl` (set in astro.config.mjs, origin-normalized at startup)\n * 2. `EMDASH_SITE_URL` or `SITE_URL` env var (resolved at runtime for containers)\n * 3. `url.origin` (internal request URL — correct when no proxy)\n *\n * @param url The request URL (`new URL(request.url)` or `Astro.url`)\n * @param config The EmDash config (from `locals.emdash?.config`)\n * @returns Origin string, e.g. `\"https://mysite.example.com\"`\n */\nexport function getPublicOrigin(url: URL, config?: SiteUrlConfig): string {\n\treturn config?.siteUrl || getEnvSiteUrl() || url.origin;\n}\n\n/**\n * Resolve additional accepted passkey origins from runtime environment.\n *\n * Reads `EMDASH_ALLOWED_ORIGINS` (comma-separated list of origins) for\n * multi-origin deployments where the same RP is reachable under several\n * hostnames sharing the registrable parent domain (e.g. apex + preview).\n *\n * Each entry is parsed via `new URL()` and reduced to its `origin`. Unlike\n * `getEnvSiteUrl` (which silently falls back to `url.origin` on bad input),\n * this throws on any unparseable or non-http(s) entry — `EMDASH_ALLOWED_ORIGINS`\n * is an allowlist for passkey verification, so silently dropping a typo would\n * surface as \"I can't authenticate on this origin\" with no diagnostic. Fail\n * loud at first read.\n *\n * Uses `process.env` (Vite leaves it untouched at runtime). Result is cached\n * on success.\n */\nlet _envAllowedOrigins: string[] | null = null;\n\nexport function getEnvAllowedOrigins(): string[] {\n\tif (_envAllowedOrigins !== null) return _envAllowedOrigins;\n\tconst raw = typeof process !== \"undefined\" ? process.env?.EMDASH_ALLOWED_ORIGINS || \"\" : \"\";\n\tconst parsed: string[] = [];\n\tfor (const entry of raw.split(\",\")) {\n\t\tconst trimmed = entry.trim();\n\t\tif (!trimmed) continue;\n\t\tlet u: URL;\n\t\ttry {\n\t\t\tu = new URL(trimmed);\n\t\t} catch (e) {\n\t\t\tthrow new Error(`EmDash config error in EMDASH_ALLOWED_ORIGINS: invalid URL: \"${trimmed}\"`, {\n\t\t\t\tcause: e,\n\t\t\t});\n\t\t}\n\t\tif (u.protocol !== \"http:\" && u.protocol !== \"https:\") {\n\t\t\tthrow new Error(\n\t\t\t\t`EmDash config error in EMDASH_ALLOWED_ORIGINS: origin must be http or https: \"${trimmed}\" (got ${u.protocol})`,\n\t\t\t);\n\t\t}\n\t\tparsed.push(u.origin);\n\t}\n\t_envAllowedOrigins = parsed;\n\treturn parsed;\n}\n\n/**\n * Build a full public URL by appending a path to the public origin.\n *\n * @param url The request URL\n * @param config The EmDash config\n * @param path Path to append (must start with `/`)\n * @returns Full URL string, e.g. `\"https://mysite.example.com/_emdash/admin/login\"`\n */\nexport function getPublicUrl(url: URL, config: SiteUrlConfig | undefined, path: string): string {\n\treturn `${getPublicOrigin(url, config)}${path}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA+BA,IAAI,cAAyC;AAQ7C,SAAS,gBAAoC;AAC5C,KAAI,gBAAgB,KAAM,QAAO,eAAe;AAChD,KAAI;EAEH,MAAM,QACJ,OAAO,YAAY,eAAe,QAAQ,KAAK,mBAC/C,OAAO,YAAY,eAAe,QAAQ,KAAK,YAChD;AACD,MAAI,OAAO;GACV,MAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,OAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UAAU;AAChE,kBAAc;AACd;;AAED,iBAAc,OAAO;QAErB,eAAc;SAER;AACP,gBAAc;;AAEf,QAAO,eAAe;;;;;;;;;;;;;;AAevB,SAAgB,gBAAgB,KAAU,QAAgC;AACzE,QAAO,QAAQ,WAAW,eAAe,IAAI,IAAI;;;;;;;;;;;;;;;;;;;AAoBlD,IAAI,qBAAsC;AAE1C,SAAgB,uBAAiC;AAChD,KAAI,uBAAuB,KAAM,QAAO;CACxC,MAAM,MAAM,OAAO,YAAY,cAAc,QAAQ,KAAK,0BAA0B,KAAK;CACzF,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;EACnC,MAAM,UAAU,MAAM,MAAM;AAC5B,MAAI,CAAC,QAAS;EACd,IAAI;AACJ,MAAI;AACH,OAAI,IAAI,IAAI,QAAQ;WACZ,GAAG;AACX,SAAM,IAAI,MAAM,gEAAgE,QAAQ,IAAI,EAC3F,OAAO,GACP,CAAC;;AAEH,MAAI,EAAE,aAAa,WAAW,EAAE,aAAa,SAC5C,OAAM,IAAI,MACT,iFAAiF,QAAQ,SAAS,EAAE,SAAS,GAC7G;AAEF,SAAO,KAAK,EAAE,OAAO;;AAEtB,sBAAqB;AACrB,QAAO"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as __exportAll } from "./runner-DfnZ5eUr.mjs";
|
|
2
2
|
import { n as getI18nConfig, r as isI18nEnabled, t as getFallbackChain } from "./config-CVssduLe.mjs";
|
|
3
3
|
import { getRequestContext } from "./request-context.mjs";
|
|
4
4
|
import { i as contentNamespaces, n as cachedQuery, u as invalidateSchemaObjectCache } from "./object-cache-Bok5j2ae.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { n as FOLDED_BYLINES, r as FOLDED_TERMS, t as CURSOR_RAW_VALUES } from "./loader-
|
|
5
|
+
import { n as isMissingTableError } from "./db-errors-CcWLaRiR.mjs";
|
|
6
|
+
import { a as encodeCursor } from "./types-D1iJ3DpO.mjs";
|
|
7
|
+
import { r as requestCached } from "./request-cache-BSUptuJR.mjs";
|
|
8
|
+
import { n as FOLDED_BYLINES, r as FOLDED_TERMS, t as CURSOR_RAW_VALUES } from "./loader-Be3ouI5L.mjs";
|
|
9
9
|
|
|
10
10
|
//#region src/visual-editing/editable.ts
|
|
11
11
|
/**
|
|
@@ -655,9 +655,9 @@ async function hydrateEntryBylines(type, entries) {
|
|
|
655
655
|
let needsQueryPath = parsed.some((p) => p.credits.length === 0 && (dataStr(p.data, "authorId") !== "" || dataStr(p.data, "primaryBylineId") !== ""));
|
|
656
656
|
let hasCustomFields = false;
|
|
657
657
|
if (!needsQueryPath) try {
|
|
658
|
-
const { getDb } = await import("./loader-
|
|
658
|
+
const { getDb } = await import("./loader-Be3ouI5L.mjs").then((n) => n.o);
|
|
659
659
|
const db = await getDb();
|
|
660
|
-
const { getBylineFieldDefs } = await import("./field-defs-cache-
|
|
660
|
+
const { getBylineFieldDefs } = await import("./field-defs-cache-DvmlgP-D.mjs").then((n) => n.t);
|
|
661
661
|
hasCustomFields = (await getBylineFieldDefs(db)).length > 0;
|
|
662
662
|
} catch (error) {
|
|
663
663
|
if (!isMissingTableError(error)) needsQueryPath = true;
|
|
@@ -671,7 +671,7 @@ async function hydrateEntryBylines(type, entries) {
|
|
|
671
671
|
}
|
|
672
672
|
}
|
|
673
673
|
try {
|
|
674
|
-
const { getBylinesForEntries } = await import("./bylines-
|
|
674
|
+
const { getBylinesForEntries } = await import("./bylines-czseViYo.mjs").then((n) => n.t);
|
|
675
675
|
const refs = entries.map((e) => {
|
|
676
676
|
const data = entryData(e);
|
|
677
677
|
const id = dataStr(data, "id");
|
|
@@ -749,12 +749,12 @@ async function hydrateEntryTerms(type, entries, locale) {
|
|
|
749
749
|
byTaxonomy: grouped
|
|
750
750
|
});
|
|
751
751
|
}
|
|
752
|
-
const { primeFoldedEntryTerms } = await import("./taxonomies-
|
|
752
|
+
const { primeFoldedEntryTerms } = await import("./taxonomies-DjSKBZpq.mjs").then((n) => n.d);
|
|
753
753
|
primeFoldedEntryTerms(type, perEntry, { locale });
|
|
754
754
|
return;
|
|
755
755
|
}
|
|
756
756
|
try {
|
|
757
|
-
const { getAllTermsForEntries } = await import("./taxonomies-
|
|
757
|
+
const { getAllTermsForEntries } = await import("./taxonomies-DjSKBZpq.mjs").then((n) => n.d);
|
|
758
758
|
const ids = entries.map((e) => dataStr(entryData(e), "id")).filter(Boolean);
|
|
759
759
|
if (ids.length === 0) return;
|
|
760
760
|
const termsMap = await getAllTermsForEntries(type, ids, { locale });
|
|
@@ -788,9 +788,9 @@ async function hydrateEntryTerms(type, entries, locale) {
|
|
|
788
788
|
*/
|
|
789
789
|
async function getTranslations(type, id) {
|
|
790
790
|
try {
|
|
791
|
-
const db = (await import("./loader-
|
|
791
|
+
const db = (await import("./loader-Be3ouI5L.mjs").then((n) => n.o)).getDb;
|
|
792
792
|
const dbInstance = await db();
|
|
793
|
-
const { ContentRepository } = await import("./content-
|
|
793
|
+
const { ContentRepository } = await import("./content-Ci04z2z-.mjs").then((n) => n.n);
|
|
794
794
|
const repo = new ContentRepository(dbInstance);
|
|
795
795
|
const item = await repo.findByIdOrSlug(type, id);
|
|
796
796
|
if (!item) return {
|
|
@@ -864,8 +864,8 @@ function invalidateUrlPatternCache() {
|
|
|
864
864
|
*/
|
|
865
865
|
async function resolveEmDashPath(path) {
|
|
866
866
|
if (!cachedUrlPatterns) {
|
|
867
|
-
const { getDb } = await import("./loader-
|
|
868
|
-
const { SchemaRegistry } = await import("./registry-
|
|
867
|
+
const { getDb } = await import("./loader-Be3ouI5L.mjs").then((n) => n.o);
|
|
868
|
+
const { SchemaRegistry } = await import("./registry-FV15nLge.mjs").then((n) => n.r);
|
|
869
869
|
const collections = await new SchemaRegistry(await getDb()).listCollections();
|
|
870
870
|
cachedUrlPatterns = [];
|
|
871
871
|
for (const collection of collections) {
|
|
@@ -897,4 +897,4 @@ async function resolveEmDashPath(path) {
|
|
|
897
897
|
|
|
898
898
|
//#endregion
|
|
899
899
|
export { invalidateUrlPatternCache as a, createEditable as c, getTranslations as i, createNoop as l, getEmDashCollection as n, query_exports as o, getEmDashEntry as r, resolveEmDashPath as s, getEditMeta as t };
|
|
900
|
-
//# sourceMappingURL=query-
|
|
900
|
+
//# sourceMappingURL=query-DR73ZNfm.mjs.map
|