emdash 1.2.0 → 1.3.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/action-token-SK8zyN7w.mjs +26 -0
- package/dist/action-token-SK8zyN7w.mjs.map +1 -0
- package/dist/activation-Dim4YMM7.mjs +387 -0
- package/dist/activation-Dim4YMM7.mjs.map +1 -0
- package/dist/adapters-F_xorvWv.d.mts +173 -0
- package/dist/adapters-F_xorvWv.d.mts.map +1 -0
- package/dist/allowed-origins-CEug-p0t.mjs +116 -0
- package/dist/allowed-origins-CEug-p0t.mjs.map +1 -0
- package/dist/api/route-utils.d.mts +4 -4
- package/dist/api/route-utils.mjs +47 -45
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/api/schemas/index.mjs +9 -9
- package/dist/api-D-7BNHoz.mjs +5025 -0
- package/dist/api-D-7BNHoz.mjs.map +1 -0
- package/dist/api-tokens-Bx38ZCQp.mjs +173 -0
- package/dist/api-tokens-Bx38ZCQp.mjs.map +1 -0
- package/dist/apply-T7ATgzCh.mjs +1702 -0
- package/dist/apply-T7ATgzCh.mjs.map +1 -0
- package/dist/approvals-D-m6wvGl.mjs +460 -0
- package/dist/approvals-D-m6wvGl.mjs.map +1 -0
- package/dist/artifact-fetch-DIh7iyOV.mjs +659 -0
- package/dist/artifact-fetch-DIh7iyOV.mjs.map +1 -0
- package/dist/artifacts-htGyfCSt.mjs +307 -0
- package/dist/artifacts-htGyfCSt.mjs.map +1 -0
- package/dist/astro/index.d.mts +14 -14
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +109 -18
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +12 -12
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +12 -11
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +60 -40
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +49 -15
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +12 -12
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +116 -408
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +16 -16
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +16 -16
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +16 -16
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -21
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -21
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +22 -21
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
- package/dist/astro/routes/api/admin/core-update.mjs +7 -7
- 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/activation.mjs +20 -20
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +21 -21
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +21 -21
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +23 -22
- package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +29 -28
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +21 -21
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +21 -21
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +71 -69
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +70 -68
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +70 -69
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +79 -78
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +71 -69
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +70 -68
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +78 -77
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +70 -68
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +70 -69
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +80 -79
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +10 -10
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +72 -71
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +71 -69
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +70 -68
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +70 -68
- 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 +7 -7
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +70 -68
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +38 -37
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +38 -37
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +41 -40
- package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +41 -40
- package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +41 -40
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +42 -41
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +42 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +42 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +42 -41
- package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +40 -39
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +42 -41
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -14
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
- package/dist/astro/routes/api/admin/users/index.mjs +14 -14
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/handover.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +19 -19
- package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
- package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
- package/dist/astro/routes/api/auth/logout.mjs +5 -5
- package/dist/astro/routes/api/auth/magic-link/send.mjs +18 -18
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +15 -15
- package/dist/astro/routes/api/auth/me.mjs +15 -15
- package/dist/astro/routes/api/auth/mode.mjs +5 -5
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +8 -8
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
- package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
- package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
- package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -19
- package/dist/astro/routes/api/auth/signup/complete.mjs +19 -19
- package/dist/astro/routes/api/auth/signup/request.mjs +17 -17
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/calendar.mjs +15 -15
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +7 -10
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +20 -17
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +7 -6
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +30 -29
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +34 -33
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +34 -33
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +7 -6
- 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_/schedule.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +19 -18
- 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 +30 -25
- 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_/unpublish.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -17
- 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 +27 -20
- 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_/index.mjs +18 -21
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
- package/dist/astro/routes/api/dashboard.d.mts.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +17 -11
- package/dist/astro/routes/api/dashboard.mjs.map +1 -1
- package/dist/astro/routes/api/dev/emails.mjs +5 -5
- package/dist/astro/routes/api/dev/scheduled-tasks.d.mts +12 -0
- package/dist/astro/routes/api/dev/scheduled-tasks.d.mts.map +1 -0
- package/dist/astro/routes/api/dev/scheduled-tasks.mjs +140 -0
- package/dist/astro/routes/api/dev/scheduled-tasks.mjs.map +1 -0
- package/dist/astro/routes/api/health.mjs +6 -6
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +24 -22
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -20
- package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +15 -14
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +28 -29
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
- package/dist/astro/routes/api/import/wordpress/media.mjs +17 -17
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +19 -17
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +27 -26
- 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 +25 -22
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +55 -34
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +6 -6
- package/dist/astro/routes/api/mcp.mjs +135 -101
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +17 -17
- package/dist/astro/routes/api/media/_id_/replace.mjs +15 -15
- package/dist/astro/routes/api/media/_id_/upload.mjs +8 -8
- package/dist/astro/routes/api/media/_id_/usage.mjs +31 -30
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +29 -28
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +10 -10
- package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
- package/dist/astro/routes/api/media/folders/index.mjs +16 -16
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
- package/dist/astro/routes/api/media/providers/index.mjs +5 -5
- package/dist/astro/routes/api/media/upload-url.mjs +17 -17
- package/dist/astro/routes/api/media.mjs +30 -29
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +19 -18
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +18 -17
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -17
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -17
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +19 -18
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +18 -17
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +8 -8
- package/dist/astro/routes/api/oauth/device/code.mjs +11 -11
- package/dist/astro/routes/api/oauth/device/token.mjs +10 -10
- package/dist/astro/routes/api/oauth/register.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
- package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
- package/dist/astro/routes/api/oauth/token.mjs +8 -8
- package/dist/astro/routes/api/openapi.json.mjs +20 -20
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
- package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
- package/dist/astro/routes/api/redirects/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +32 -23
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.d.mts.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +24 -21
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +34 -33
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +34 -33
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +16 -16
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +70 -68
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +70 -68
- package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
- package/dist/astro/routes/api/schema/block-types/index.mjs +70 -68
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +70 -68
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +70 -68
- 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 +70 -68
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +70 -68
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +70 -68
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +70 -68
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +16 -15
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +70 -68
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +70 -68
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +19 -18
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +18 -17
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +19 -18
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +9 -8
- package/dist/astro/routes/api/search/stats.mjs.map +1 -1
- package/dist/astro/routes/api/search/suggest.mjs +18 -17
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +18 -17
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +18 -17
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
- package/dist/astro/routes/api/settings/domain-notify.mjs +9 -9
- package/dist/astro/routes/api/settings/domain.d.mts.map +1 -1
- package/dist/astro/routes/api/settings/domain.mjs +17 -14
- package/dist/astro/routes/api/settings/domain.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +6 -6
- package/dist/astro/routes/api/settings.d.mts.map +1 -1
- package/dist/astro/routes/api/settings.mjs +23 -20
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.d.mts.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +25 -21
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +18 -18
- package/dist/astro/routes/api/setup/dev-bypass.mjs +42 -40
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
- package/dist/astro/routes/api/setup/index.mjs +48 -46
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +6 -6
- package/dist/astro/routes/api/site/domain-proof.mjs +11 -9
- package/dist/astro/routes/api/site/domain-proof.mjs.map +1 -1
- package/dist/astro/routes/api/snapshot.mjs +8 -8
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +23 -21
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -21
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +24 -22
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +23 -21
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +21 -20
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.mjs +24 -22
- package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +34 -33
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +23 -21
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +18 -18
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +17 -16
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +21 -19
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -18
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +20 -18
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +5 -5
- package/dist/astro/routes/robots.txt.d.mts.map +1 -1
- package/dist/astro/routes/robots.txt.mjs +38 -5
- package/dist/astro/routes/robots.txt.mjs.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -8
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +11 -6
- package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
- package/dist/astro/types.d.mts +19 -17
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/audit-_gieLVGU.mjs +127 -0
- package/dist/audit-_gieLVGU.mjs.map +1 -0
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/auth/providers/microsoft.d.mts +1 -1
- package/dist/authoritative-records-CQlB3JzE.mjs +5183 -0
- package/dist/authoritative-records-CQlB3JzE.mjs.map +1 -0
- package/dist/authorize-DPFBGbE6.mjs +74 -0
- package/dist/authorize-DPFBGbE6.mjs.map +1 -0
- package/dist/backup-3FgVxiDJ.mjs +246 -0
- package/dist/backup-3FgVxiDJ.mjs.map +1 -0
- package/dist/block-types-CYcG56JB.mjs +132 -0
- package/dist/block-types-CYcG56JB.mjs.map +1 -0
- package/dist/block-values-gCX4HBSl.mjs +215 -0
- package/dist/block-values-gCX4HBSl.mjs.map +1 -0
- package/dist/byline-BR1qhyiw.mjs +909 -0
- package/dist/byline-BR1qhyiw.mjs.map +1 -0
- package/dist/byline-fields-4ClDC88c.mjs +123 -0
- package/dist/byline-fields-4ClDC88c.mjs.map +1 -0
- package/dist/byline-fields-BLXZnX7N.mjs +280 -0
- package/dist/byline-fields-BLXZnX7N.mjs.map +1 -0
- package/dist/bylines-CVOvRUL7.mjs +234 -0
- package/dist/bylines-CVOvRUL7.mjs.map +1 -0
- package/dist/bylines-DxOs9B7z.mjs +150 -0
- package/dist/bylines-DxOs9B7z.mjs.map +1 -0
- package/dist/cache-CEU9wo_h.mjs +151 -0
- package/dist/cache-CEU9wo_h.mjs.map +1 -0
- package/dist/canonical-BudtH-Fx.mjs +174 -0
- package/dist/canonical-BudtH-Fx.mjs.map +1 -0
- package/dist/capture-triggers-CT6dK9zd.mjs +362 -0
- package/dist/capture-triggers-CT6dK9zd.mjs.map +1 -0
- package/dist/challenge-store-C17BYx2-.mjs +51 -0
- package/dist/challenge-store-C17BYx2-.mjs.map +1 -0
- package/dist/checksum-CEqvfxGX.mjs +162 -0
- package/dist/checksum-CEqvfxGX.mjs.map +1 -0
- package/dist/chunks-xC4UD5-S.mjs +25 -0
- package/dist/chunks-xC4UD5-S.mjs.map +1 -0
- package/dist/cli/index.mjs +127 -113
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +47 -47
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +12 -10
- package/dist/client/index.mjs.map +1 -1
- package/dist/collection-slugs-cache-e09QeJQt.mjs +85 -0
- package/dist/collection-slugs-cache-e09QeJQt.mjs.map +1 -0
- package/dist/comment-UvIWDKcW.mjs +325 -0
- package/dist/comment-UvIWDKcW.mjs.map +1 -0
- package/dist/comment-reaction-dGp6_FRo.mjs +85 -0
- package/dist/comment-reaction-dGp6_FRo.mjs.map +1 -0
- package/dist/comments-pej-_BUO.mjs +195 -0
- package/dist/comments-pej-_BUO.mjs.map +1 -0
- package/dist/comments-yiRFx3w5.mjs +99 -0
- package/dist/comments-yiRFx3w5.mjs.map +1 -0
- package/dist/components-Brp__9xo.mjs +112 -0
- package/dist/components-Brp__9xo.mjs.map +1 -0
- package/dist/config-Bsm_u_oE.d.mts +6799 -0
- package/dist/config-Bsm_u_oE.d.mts.map +1 -0
- package/dist/config-CFMojMFK.d.mts +39 -0
- package/dist/config-CFMojMFK.d.mts.map +1 -0
- package/dist/config-DBU6iUQB.mjs +228 -0
- package/dist/config-DBU6iUQB.mjs.map +1 -0
- package/dist/connection-BtEN_lP9.mjs +36 -0
- package/dist/connection-BtEN_lP9.mjs.map +1 -0
- package/dist/content-DQSRZTVw.mjs +2075 -0
- package/dist/content-DQSRZTVw.mjs.map +1 -0
- package/dist/content-list-query-CYKcY6Vi.d.mts +26 -0
- package/dist/content-list-query-CYKcY6Vi.d.mts.map +1 -0
- package/dist/content-repair-DNh5--x5.mjs +442 -0
- package/dist/content-repair-DNh5--x5.mjs.map +1 -0
- package/dist/context-BYptmCN0.mjs +2090 -0
- package/dist/context-BYptmCN0.mjs.map +1 -0
- package/dist/credits-B9iORdWB.mjs +110 -0
- package/dist/credits-B9iORdWB.mjs.map +1 -0
- package/dist/cron-D7obTIfk.mjs +306 -0
- package/dist/cron-D7obTIfk.mjs.map +1 -0
- package/dist/dashboard-D0jcgBD7.mjs +167 -0
- package/dist/dashboard-D0jcgBD7.mjs.map +1 -0
- package/dist/database/migration-lock.d.mts +17 -4
- package/dist/database/migration-lock.d.mts.map +1 -1
- package/dist/database/migration-lock.mjs +32 -5
- package/dist/database/migration-lock.mjs.map +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +4 -4
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +4 -4
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +1 -1
- package/dist/db/sqlite-migrations.mjs +4 -4
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +1 -1
- package/dist/default-C0W-PhAp.mjs +81 -0
- package/dist/default-C0W-PhAp.mjs.map +1 -0
- package/dist/deferred-tasks-ZvUECSzI.d.mts +9 -0
- package/dist/deferred-tasks-ZvUECSzI.d.mts.map +1 -0
- package/dist/dev-typegen-EBni_pOQ.mjs +29 -0
- package/dist/dev-typegen-EBni_pOQ.mjs.map +1 -0
- package/dist/device-flow-BkFKBoAn.mjs +521 -0
- package/dist/device-flow-BkFKBoAn.mjs.map +1 -0
- package/dist/digest-DJ1tHCgy.mjs +194 -0
- package/dist/digest-DJ1tHCgy.mjs.map +1 -0
- package/dist/direct-executor-Cbxzg4qe.mjs +117 -0
- package/dist/direct-executor-Cbxzg4qe.mjs.map +1 -0
- package/dist/email-console-FFVJWb9N.mjs +50 -0
- package/dist/email-console-FFVJWb9N.mjs.map +1 -0
- package/dist/email-locale-BJ8DjTzZ.mjs +25 -0
- package/dist/email-locale-BJ8DjTzZ.mjs.map +1 -0
- package/dist/emdash-runtime-DVi7vtXC.mjs +4379 -0
- package/dist/emdash-runtime-DVi7vtXC.mjs.map +1 -0
- package/dist/entry-lock-C7VX0NGK.d.mts +4568 -0
- package/dist/entry-lock-C7VX0NGK.d.mts.map +1 -0
- package/dist/entry-lock-DLxCffFW.mjs +163 -0
- package/dist/entry-lock-DLxCffFW.mjs.map +1 -0
- package/dist/entry-lock-Df6-XhIu.mjs +1211 -0
- package/dist/entry-lock-Df6-XhIu.mjs.map +1 -0
- package/dist/env-types-C3FCVBWe.mjs +38 -0
- package/dist/env-types-C3FCVBWe.mjs.map +1 -0
- package/dist/error-CVWeIOku.mjs +90 -0
- package/dist/error-CVWeIOku.mjs.map +1 -0
- package/dist/errors-B4f4It-2.mjs +120 -0
- package/dist/errors-B4f4It-2.mjs.map +1 -0
- package/dist/errors-BOYNdIo3.mjs +479 -0
- package/dist/errors-BOYNdIo3.mjs.map +1 -0
- package/dist/escape-lsNq38PP.mjs +9 -0
- package/dist/escape-lsNq38PP.mjs.map +1 -0
- package/dist/fence-C3MUitUN.mjs +162 -0
- package/dist/fence-C3MUitUN.mjs.map +1 -0
- package/dist/field-defs-cache-Dez5iWJJ.mjs +77 -0
- package/dist/field-defs-cache-Dez5iWJJ.mjs.map +1 -0
- package/dist/field-map-Bft9LKak.mjs +83 -0
- package/dist/field-map-Bft9LKak.mjs.map +1 -0
- package/dist/fts-manager-Beg3e4bI.mjs +443 -0
- package/dist/fts-manager-Beg3e4bI.mjs.map +1 -0
- package/dist/gc-ByyAYiYE.mjs +75 -0
- package/dist/gc-ByyAYiYE.mjs.map +1 -0
- package/dist/hash-BJaeek87.mjs +37 -0
- package/dist/hash-BJaeek87.mjs.map +1 -0
- package/dist/hook-result-BrdLyOdI.d.mts +31 -0
- package/dist/hook-result-BrdLyOdI.d.mts.map +1 -0
- package/dist/hreflang-C8Jb-hrf.mjs +105 -0
- package/dist/hreflang-C8Jb-hrf.mjs.map +1 -0
- package/dist/hreflang-CY_F5OjF.d.mts +50 -0
- package/dist/hreflang-CY_F5OjF.d.mts.map +1 -0
- package/dist/http-route-dispatch-CyeW6iPv.mjs +342 -0
- package/dist/http-route-dispatch-CyeW6iPv.mjs.map +1 -0
- package/dist/identity-Cael5uTT.mjs +35 -0
- package/dist/identity-Cael5uTT.mjs.map +1 -0
- package/dist/import-BUXjdZUn.mjs +2126 -0
- package/dist/import-BUXjdZUn.mjs.map +1 -0
- package/dist/index-BB9sVisO.d.mts +623 -0
- package/dist/index-BB9sVisO.d.mts.map +1 -0
- package/dist/index.d.mts +23 -23
- package/dist/index.mjs +96 -94
- package/dist/install-finalization-3JX5qQEA.mjs +58 -0
- package/dist/install-finalization-3JX5qQEA.mjs.map +1 -0
- package/dist/json-recordset-BUjxhr77.mjs +12 -0
- package/dist/json-recordset-BUjxhr77.mjs.map +1 -0
- package/dist/json-schema-v_D_pPNG.mjs +15 -0
- package/dist/json-schema-v_D_pPNG.mjs.map +1 -0
- package/dist/keys-CifIkT0N.mjs +61 -0
- package/dist/keys-CifIkT0N.mjs.map +1 -0
- package/dist/kinds-B_Qcl5pz.mjs +974 -0
- package/dist/kinds-B_Qcl5pz.mjs.map +1 -0
- package/dist/lifecycle-7vUJeFRe.mjs +25 -0
- package/dist/lifecycle-7vUJeFRe.mjs.map +1 -0
- package/dist/load-CdAG9wz-.mjs +28 -0
- package/dist/load-CdAG9wz-.mjs.map +1 -0
- package/dist/loader-CswroUbe.mjs +1380 -0
- package/dist/loader-CswroUbe.mjs.map +1 -0
- package/dist/loops-uA4iTOzd.mjs +205 -0
- package/dist/loops-uA4iTOzd.mjs.map +1 -0
- package/dist/manifest-builder-B8zjuH3f.mjs +189 -0
- package/dist/manifest-builder-B8zjuH3f.mjs.map +1 -0
- package/dist/manifest-schema-DNb4XmTS.mjs +497 -0
- package/dist/manifest-schema-DNb4XmTS.mjs.map +1 -0
- package/dist/marketplace-CqbgeIa7.mjs +257 -0
- package/dist/marketplace-CqbgeIa7.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +14 -14
- package/dist/media/local-runtime.mjs +10 -5
- package/dist/media/local-runtime.mjs.map +1 -1
- package/dist/media--dJRU6i2.mjs +294 -0
- package/dist/media--dJRU6i2.mjs.map +1 -0
- package/dist/media-1WC65OCB.mjs +416 -0
- package/dist/media-1WC65OCB.mjs.map +1 -0
- package/dist/media-Bws9f18T.mjs +373 -0
- package/dist/media-Bws9f18T.mjs.map +1 -0
- package/dist/media-allowlist-BJB7MFx6.mjs +45 -0
- package/dist/media-allowlist-BJB7MFx6.mjs.map +1 -0
- package/dist/media-folders-Dn3C16B8.mjs +210 -0
- package/dist/media-folders-Dn3C16B8.mjs.map +1 -0
- package/dist/media-url-BQgKvpQ5.mjs +43 -0
- package/dist/media-url-BQgKvpQ5.mjs.map +1 -0
- package/dist/media-usage-CF0WVcLO.mjs +282 -0
- package/dist/media-usage-CF0WVcLO.mjs.map +1 -0
- package/dist/media-usage-activation-C9HwVw5w.mjs +78 -0
- package/dist/media-usage-activation-C9HwVw5w.mjs.map +1 -0
- package/dist/media-usage-work-CkLa5-nc.mjs +1036 -0
- package/dist/media-usage-work-CkLa5-nc.mjs.map +1 -0
- package/dist/media-usage-work-m3AWTmmC.mjs +151 -0
- package/dist/media-usage-work-m3AWTmmC.mjs.map +1 -0
- package/dist/menus-BCVSSp1z.mjs +753 -0
- package/dist/menus-BCVSSp1z.mjs.map +1 -0
- package/dist/menus-BSzwObhV.mjs +92 -0
- package/dist/menus-BSzwObhV.mjs.map +1 -0
- package/dist/menus-Cl4kwdt7.mjs +3721 -0
- package/dist/menus-Cl4kwdt7.mjs.map +1 -0
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.d.mts.map +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/mode-C-D3qICy.mjs +23 -0
- package/dist/mode-C-D3qICy.mjs.map +1 -0
- package/dist/node-sqlite-compat-CrKzRr0J.mjs +63 -0
- package/dist/node-sqlite-compat-CrKzRr0J.mjs.map +1 -0
- package/dist/oauth-authorization-TpEJrYB7.mjs +274 -0
- package/dist/oauth-authorization-TpEJrYB7.mjs.map +1 -0
- package/dist/oauth-clients-BT0Pg-MO.mjs +266 -0
- package/dist/oauth-clients-BT0Pg-MO.mjs.map +1 -0
- package/dist/oauth-state-store-CHMn_mwc.mjs +50 -0
- package/dist/oauth-state-store-CHMn_mwc.mjs.map +1 -0
- package/dist/oauth-user-lookup-BDgF6IVG.mjs +26 -0
- package/dist/oauth-user-lookup-BDgF6IVG.mjs.map +1 -0
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/options-DJWaq3Ie.d.mts +81 -0
- package/dist/options-DJWaq3Ie.d.mts.map +1 -0
- package/dist/ownership-MiyA7qKO.mjs +12 -0
- package/dist/ownership-MiyA7qKO.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +9 -4
- package/dist/page/index.mjs.map +1 -1
- package/dist/parse-CWHOFc6z.d.mts +176 -0
- package/dist/parse-CWHOFc6z.d.mts.map +1 -0
- package/dist/parse-DgQ2NABT.mjs +81 -0
- package/dist/parse-DgQ2NABT.mjs.map +1 -0
- package/dist/passkey-config-D0kdzEao.mjs +46 -0
- package/dist/passkey-config-D0kdzEao.mjs.map +1 -0
- package/dist/paths-biDzFTY2.mjs +77 -0
- package/dist/paths-biDzFTY2.mjs.map +1 -0
- package/dist/placeholder-D41vk11_.d.mts +306 -0
- package/dist/placeholder-D41vk11_.d.mts.map +1 -0
- package/dist/plan-CCoqxNoU.mjs +135 -0
- package/dist/plan-CCoqxNoU.mjs.map +1 -0
- package/dist/plugin-test-runtime.d.mts +14 -14
- package/dist/plugin-test-runtime.mjs +109 -107
- package/dist/plugin-tool-name-DDUgN_0p.mjs +27 -0
- package/dist/plugin-tool-name-DDUgN_0p.mjs.map +1 -0
- package/dist/plugin-types.d.mts +2 -2
- package/dist/plugin-utils.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +9 -8
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/plugins/host.d.mts +5 -5
- package/dist/plugins/host.mjs +45 -41
- package/dist/plugins-COJ2L49n.mjs +261 -0
- package/dist/plugins-COJ2L49n.mjs.map +1 -0
- package/dist/policy-DLQ--Hnm.mjs +45 -0
- package/dist/policy-DLQ--Hnm.mjs.map +1 -0
- package/dist/portable-text-BH4zgkSm.mjs +311 -0
- package/dist/portable-text-BH4zgkSm.mjs.map +1 -0
- package/dist/preview-DLexxwp3.mjs +107 -0
- package/dist/preview-DLexxwp3.mjs.map +1 -0
- package/dist/protocol-79kUO7jP.d.mts +65 -0
- package/dist/protocol-79kUO7jP.d.mts.map +1 -0
- package/dist/public-plugin-api-routes-BuAMJ8nN.mjs +316 -0
- package/dist/public-plugin-api-routes-BuAMJ8nN.mjs.map +1 -0
- package/dist/public-submission-Di3TsgzX.mjs +251 -0
- package/dist/public-submission-Di3TsgzX.mjs.map +1 -0
- package/dist/public-url-Bt98vysr.mjs +101 -0
- package/dist/public-url-Bt98vysr.mjs.map +1 -0
- package/dist/query-CpnRlBh8.mjs +1156 -0
- package/dist/query-CpnRlBh8.mjs.map +1 -0
- package/dist/query-haKvLAWl.mjs +41 -0
- package/dist/query-haKvLAWl.mjs.map +1 -0
- package/dist/range-CYfeXgGK.mjs +51 -0
- package/dist/range-CYfeXgGK.mjs.map +1 -0
- package/dist/rate-limit-Xp4d0NBY.mjs +127 -0
- package/dist/rate-limit-Xp4d0NBY.mjs.map +1 -0
- package/dist/receipt-BUsQCOeM.mjs +43 -0
- package/dist/receipt-BUsQCOeM.mjs.map +1 -0
- package/dist/redirect-CQAV7mCo.mjs +19 -0
- package/dist/redirect-CQAV7mCo.mjs.map +1 -0
- package/dist/redirect-DiS_3mA4.mjs +423 -0
- package/dist/redirect-DiS_3mA4.mjs.map +1 -0
- package/dist/redirect-paths-CNYq7w80.mjs +36 -0
- package/dist/redirect-paths-CNYq7w80.mjs.map +1 -0
- package/dist/redirects-BEVSRMa2.mjs +148 -0
- package/dist/redirects-BEVSRMa2.mjs.map +1 -0
- package/dist/redirects-BHpy-VsZ.mjs +446 -0
- package/dist/redirects-BHpy-VsZ.mjs.map +1 -0
- package/dist/registry/testing.mjs +3 -3
- package/dist/registry-TUVaid9Z.mjs +8369 -0
- package/dist/registry-TUVaid9Z.mjs.map +1 -0
- package/dist/relations-CA_QuMTU.mjs +776 -0
- package/dist/relations-CA_QuMTU.mjs.map +1 -0
- package/dist/request-context.d.mts +1 -1
- package/dist/request-meta-bwZ_NsvU.mjs +141 -0
- package/dist/request-meta-bwZ_NsvU.mjs.map +1 -0
- package/dist/resolve-DwNM-CXl.mjs +101 -0
- package/dist/resolve-DwNM-CXl.mjs.map +1 -0
- package/dist/revision-BVp8S0e_.mjs +374 -0
- package/dist/revision-BVp8S0e_.mjs.map +1 -0
- package/dist/route-cache-QSOyDEw0.mjs +20 -0
- package/dist/route-cache-QSOyDEw0.mjs.map +1 -0
- package/dist/route-wire-Ca_HWCZ5.mjs +197 -0
- package/dist/route-wire-Ca_HWCZ5.mjs.map +1 -0
- package/dist/routes-BerZFrvV.mjs +272 -0
- package/dist/routes-BerZFrvV.mjs.map +1 -0
- package/dist/runner-BObHz5FC.d.mts +68 -0
- package/dist/runner-BObHz5FC.d.mts.map +1 -0
- package/dist/runner-C5NeAkBQ.mjs +6595 -0
- package/dist/runner-C5NeAkBQ.mjs.map +1 -0
- package/dist/runtime.d.mts +13 -13
- package/dist/runtime.mjs +3 -2
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema/project-env-types.mjs +39 -35
- package/dist/schema/project-env-types.mjs.map +1 -1
- package/dist/schema-C4OBuv6Z.mjs +13 -0
- package/dist/schema-C4OBuv6Z.mjs.map +1 -0
- package/dist/schema-DJRfvM_o.mjs +815 -0
- package/dist/schema-DJRfvM_o.mjs.map +1 -0
- package/dist/scopes-BU03K7Uo.mjs +34 -0
- package/dist/scopes-BU03K7Uo.mjs.map +1 -0
- package/dist/search-DfVzks89.mjs +450 -0
- package/dist/search-DfVzks89.mjs.map +1 -0
- package/dist/sections-BMy4JVUz.mjs +346 -0
- package/dist/sections-BMy4JVUz.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +37 -33
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +24 -20
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo-ClB-dw9w.mjs +188 -0
- package/dist/seo-ClB-dw9w.mjs.map +1 -0
- package/dist/seo-VZYOEy8f.mjs +133 -0
- package/dist/seo-VZYOEy8f.mjs.map +1 -0
- package/dist/service-Bo_usgSk.mjs +150 -0
- package/dist/service-Bo_usgSk.mjs.map +1 -0
- package/dist/session-user-DlpPdf8L.mjs +61 -0
- package/dist/session-user-DlpPdf8L.mjs.map +1 -0
- package/dist/settings-CWb84sDm.mjs +452 -0
- package/dist/settings-CWb84sDm.mjs.map +1 -0
- package/dist/settings-DS914jjE.mjs +66 -0
- package/dist/settings-DS914jjE.mjs.map +1 -0
- package/dist/settings-Dd1uivmQ.mjs +73 -0
- package/dist/settings-Dd1uivmQ.mjs.map +1 -0
- package/dist/setup-complete-BuNxAUiN.mjs +65 -0
- package/dist/setup-complete-BuNxAUiN.mjs.map +1 -0
- package/dist/setup-nonce-BnEAX0iy.mjs +25 -0
- package/dist/setup-nonce-BnEAX0iy.mjs.map +1 -0
- package/dist/site-domain-Bq5j5bVg.mjs +131 -0
- package/dist/site-domain-Bq5j5bVg.mjs.map +1 -0
- package/dist/site-settings-DRHfX7bq.mjs +50 -0
- package/dist/site-settings-DRHfX7bq.mjs.map +1 -0
- package/dist/site-url-MB685I5X.mjs +45 -0
- package/dist/site-url-MB685I5X.mjs.map +1 -0
- package/dist/sitemap-name-BTg2NJJv.mjs +26 -0
- package/dist/sitemap-name-BTg2NJJv.mjs.map +1 -0
- package/dist/slug-aVnUV4SL.mjs +16 -0
- package/dist/slug-aVnUV4SL.mjs.map +1 -0
- package/dist/snapshot-DYsG4uOq.mjs +414 -0
- package/dist/snapshot-DYsG4uOq.mjs.map +1 -0
- package/dist/ssrf-BcYjyM4M.mjs +406 -0
- package/dist/ssrf-BcYjyM4M.mjs.map +1 -0
- package/dist/stage-D8DWgPcO.mjs +662 -0
- package/dist/stage-D8DWgPcO.mjs.map +1 -0
- package/dist/staged-CD_imitH.mjs +686 -0
- package/dist/staged-CD_imitH.mjs.map +1 -0
- package/dist/state-CFbGZziM.mjs +178 -0
- package/dist/state-CFbGZziM.mjs.map +1 -0
- package/dist/status-BFNdxzKc.mjs +30 -0
- package/dist/status-BFNdxzKc.mjs.map +1 -0
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +3 -3
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage-query-DRyu3bSU.d.mts +1615 -0
- package/dist/storage-query-DRyu3bSU.d.mts.map +1 -0
- package/dist/tar-DFjExb9X.mjs +449 -0
- package/dist/tar-DFjExb9X.mjs.map +1 -0
- package/dist/target-CWZs2-o6.mjs +27 -0
- package/dist/target-CWZs2-o6.mjs.map +1 -0
- package/dist/taxonomies-ChnU7Mc8.mjs +697 -0
- package/dist/taxonomies-ChnU7Mc8.mjs.map +1 -0
- package/dist/taxonomies-Dd9JJv_a.mjs +939 -0
- package/dist/taxonomies-Dd9JJv_a.mjs.map +1 -0
- package/dist/taxonomy-C_C_LBAU.mjs +550 -0
- package/dist/taxonomy-C_C_LBAU.mjs.map +1 -0
- package/dist/tokens-BnhSnGwJ.mjs +171 -0
- package/dist/tokens-BnhSnGwJ.mjs.map +1 -0
- package/dist/transfer-ClH6w6BV.mjs +8873 -0
- package/dist/transfer-ClH6w6BV.mjs.map +1 -0
- package/dist/transfer-WmWiR3xf.mjs +166 -0
- package/dist/transfer-WmWiR3xf.mjs.map +1 -0
- package/dist/transfer-download--ofRj9Cw.mjs +33 -0
- package/dist/transfer-download--ofRj9Cw.mjs.map +1 -0
- package/dist/transformations-Bx4lYY0Y.mjs +196 -0
- package/dist/transformations-Bx4lYY0Y.mjs.map +1 -0
- package/dist/transport-BjbqNiPI.mjs +136 -0
- package/dist/transport-BjbqNiPI.mjs.map +1 -0
- package/dist/transport-DxiXnbXk.d.mts +42 -0
- package/dist/transport-DxiXnbXk.d.mts.map +1 -0
- package/dist/trusted-proxy-BU3Nx9g1.mjs +51 -0
- package/dist/trusted-proxy-BU3Nx9g1.mjs.map +1 -0
- package/dist/turnstile-CJwvsOqw.mjs +58 -0
- package/dist/turnstile-CJwvsOqw.mjs.map +1 -0
- package/dist/types-BA3ey2QH.d.mts +87 -0
- package/dist/types-BA3ey2QH.d.mts.map +1 -0
- package/dist/types-Bwpzb5o6.d.mts +227 -0
- package/dist/types-Bwpzb5o6.d.mts.map +1 -0
- package/dist/types-CNB-dj6F.d.mts +289 -0
- package/dist/types-CNB-dj6F.d.mts.map +1 -0
- package/dist/types-CgfFGfO5.mjs +16 -0
- package/dist/types-CgfFGfO5.mjs.map +1 -0
- package/dist/types-D2NEXtgB.mjs +127 -0
- package/dist/types-D2NEXtgB.mjs.map +1 -0
- package/dist/types-DCFavOii.d.mts +916 -0
- package/dist/types-DCFavOii.d.mts.map +1 -0
- package/dist/types-DHO7Pd25.d.mts +366 -0
- package/dist/types-DHO7Pd25.d.mts.map +1 -0
- package/dist/types-DvqVxZXa.d.mts +125 -0
- package/dist/types-DvqVxZXa.d.mts.map +1 -0
- package/dist/types-QoPHm-2w.d.mts +1741 -0
- package/dist/types-QoPHm-2w.d.mts.map +1 -0
- package/dist/types-RLgeIpnF.d.mts +374 -0
- package/dist/types-RLgeIpnF.d.mts.map +1 -0
- package/dist/types-qHVygneX.mjs +77 -0
- package/dist/types-qHVygneX.mjs.map +1 -0
- package/dist/types-sUHaH7lC.mjs +37 -0
- package/dist/types-sUHaH7lC.mjs.map +1 -0
- package/dist/types-slSqujQL.d.mts +204 -0
- package/dist/types-slSqujQL.d.mts.map +1 -0
- package/dist/update-check-BxNg9T6N.mjs +161 -0
- package/dist/update-check-BxNg9T6N.mjs.map +1 -0
- package/dist/upload-attempts-DPFC4COv.mjs +32 -0
- package/dist/upload-attempts-DPFC4COv.mjs.map +1 -0
- package/dist/url-pattern-QATUE_rv.mjs +41 -0
- package/dist/url-pattern-QATUE_rv.mjs.map +1 -0
- package/dist/user-BlCTKVAm.mjs +171 -0
- package/dist/user-BlCTKVAm.mjs.map +1 -0
- package/dist/utils-TPt7w2cS.mjs +442 -0
- package/dist/utils-TPt7w2cS.mjs.map +1 -0
- package/dist/validate-DxYhJQA-.mjs +524 -0
- package/dist/validate-DxYhJQA-.mjs.map +1 -0
- package/dist/validate-emKxGC5F.d.mts +468 -0
- package/dist/validate-emKxGC5F.d.mts.map +1 -0
- package/dist/validation-Ckq4vsVg.mjs +220 -0
- package/dist/validation-Ckq4vsVg.mjs.map +1 -0
- package/dist/version-BZj18Q7G.mjs +9 -0
- package/dist/version-BZj18Q7G.mjs.map +1 -0
- package/dist/version-DHmGpcch.mjs +7 -0
- package/dist/version-DHmGpcch.mjs.map +1 -0
- package/dist/video-DytCnw3L.mjs +54 -0
- package/dist/video-DytCnw3L.mjs.map +1 -0
- package/dist/virtual-modules-DO954n7P.mjs +515 -0
- package/dist/virtual-modules-DO954n7P.mjs.map +1 -0
- package/dist/widgets-DA5XmvVC.mjs +121 -0
- package/dist/widgets-DA5XmvVC.mjs.map +1 -0
- package/dist/wxr-taxonomies-CrMonejI.d.mts +34 -0
- package/dist/wxr-taxonomies-CrMonejI.d.mts.map +1 -0
- package/dist/wxr-taxonomies-RgRG0d5e.mjs +453 -0
- package/dist/wxr-taxonomies-RgRG0d5e.mjs.map +1 -0
- package/dist/zod-generator-D0JKy94C.mjs +424 -0
- package/dist/zod-generator-D0JKy94C.mjs.map +1 -0
- package/package.json +7 -6
- package/src/api/authorize.ts +42 -0
- package/src/api/handlers/dashboard.ts +33 -10
- package/src/api/handlers/manifest.ts +1 -0
- package/src/api/handlers/plugins.ts +1 -0
- package/src/api/handlers/revision.ts +6 -2
- package/src/api/handlers/site-domain.ts +26 -10
- package/src/api/schemas/settings.ts +2 -0
- package/src/api/types.ts +2 -0
- package/src/astro/integration/dev-scheduler-bridge.ts +91 -0
- package/src/astro/integration/index.ts +48 -1
- package/src/astro/integration/routes.ts +8 -0
- package/src/astro/integration/runtime.ts +2 -1
- package/src/astro/integration/virtual-modules.ts +9 -16
- package/src/astro/integration/vite-config.ts +4 -15
- package/src/astro/middleware/auth.ts +3 -1
- package/src/astro/middleware/redirect.ts +71 -42
- package/src/astro/middleware.ts +18 -3
- package/src/astro/prefetch.ts +7 -5
- package/src/astro/public-plugin-api-routes.ts +10 -2
- package/src/astro/routes/api/admin/plugins/registry/artifact.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +1 -5
- package/src/astro/routes/api/content/[collection]/[id]/lock.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +3 -2
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +5 -4
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id].ts +18 -6
- package/src/astro/routes/api/content/[collection]/index.ts +1 -5
- package/src/astro/routes/api/dashboard.ts +4 -1
- package/src/astro/routes/api/dev/scheduled-tasks.ts +20 -0
- package/src/astro/routes/api/import/wordpress/analyze.ts +1 -16
- package/src/astro/routes/api/import/wordpress/execute.ts +8 -3
- package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +4 -1
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +34 -5
- package/src/astro/routes/api/menus/[name]/items/[id].ts +3 -2
- package/src/astro/routes/api/menus/[name]/items.ts +2 -1
- package/src/astro/routes/api/menus/[name]/reorder.ts +2 -1
- package/src/astro/routes/api/menus/[name]/translations.ts +2 -1
- package/src/astro/routes/api/menus/[name].ts +3 -2
- package/src/astro/routes/api/menus/index.ts +2 -1
- package/src/astro/routes/api/redirects/[id].ts +15 -2
- package/src/astro/routes/api/redirects/index.ts +5 -1
- package/src/astro/routes/api/settings/domain.ts +2 -1
- package/src/astro/routes/api/settings.ts +2 -1
- package/src/astro/routes/api/setup/admin-verify.ts +7 -1
- package/src/astro/routes/api/taxonomies/[name]/reorder.ts +2 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +2 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +3 -2
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +2 -1
- package/src/astro/routes/api/taxonomies/[name].ts +3 -2
- package/src/astro/routes/api/taxonomies/index.ts +2 -1
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +2 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +3 -2
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +2 -1
- package/src/astro/routes/api/widget-areas/[name].ts +2 -1
- package/src/astro/routes/api/widget-areas/index.ts +2 -1
- package/src/astro/routes/robots.txt.ts +33 -2
- package/src/astro/types.ts +10 -1
- package/src/auth/types.ts +4 -4
- package/src/cache/redirect-paths.ts +56 -0
- package/src/cache/route-cache.ts +22 -0
- package/src/cli/commands/import/wordpress.ts +3 -27
- package/src/cli/commands/login.ts +35 -43
- package/src/cli/commands/migrate.ts +36 -4
- package/src/cli/commands/seed.ts +18 -8
- package/src/cli/wxr/parser.ts +2 -2
- package/src/client/index.ts +12 -2
- package/src/client/portable-text.ts +21 -7
- package/src/comments/query.ts +8 -2
- package/src/components/CommentForm.astro +2 -2
- package/src/components/Comments.astro +1 -1
- package/src/components/InlinePortableTextEditor.tsx +152 -1325
- package/src/components/inline-block-types.ts +278 -0
- package/src/components/inline-bubble-menu.tsx +696 -0
- package/src/components/inline-editor-ui.tsx +1192 -0
- package/src/components/inline-image.tsx +722 -0
- package/src/components/inline-media-picker.tsx +1221 -0
- package/src/components/inline-slash-menu.tsx +556 -0
- package/src/database/collection-cleanup.ts +30 -0
- package/src/database/datetime-storage.ts +337 -60
- package/src/database/migration-lock.ts +43 -7
- package/src/database/repositories/content.ts +3 -1
- package/src/database/repositories/plugin-storage.ts +109 -8
- package/src/database/repositories/revision.ts +24 -6
- package/src/database/repositories/types.ts +65 -7
- package/src/emdash-runtime.ts +176 -160
- package/src/import/index.ts +1 -0
- package/src/import/registry.ts +17 -0
- package/src/import/sources/wordpress-plugin.ts +151 -9
- package/src/import/types.ts +3 -0
- package/src/import/utils.ts +5 -0
- package/src/loader.ts +36 -2
- package/src/mcp/json-schema.ts +14 -0
- package/src/mcp/plugin-tool-name.ts +36 -0
- package/src/mcp/server.ts +74 -15
- package/src/media/usage/collection-deletion.ts +4 -0
- package/src/migrations/direct-executor.ts +42 -12
- package/src/migrations/protocol.ts +6 -2
- package/src/plugins/adapt-sandbox-entry.ts +16 -6
- package/src/plugins/state.ts +5 -8
- package/src/query.ts +51 -10
- package/src/redirects/cache.ts +34 -2
- package/src/schema/block-values.ts +80 -17
- package/src/schema/registry.ts +9 -1
- package/src/search/query.ts +3 -1
- package/src/seed/apply.ts +32 -8
- package/src/settings/index.ts +20 -0
- package/src/settings/types.ts +2 -0
- package/src/visual-editing/toolbar.ts +46 -12
- package/dist/action-token-BdWad2YG.mjs +0 -26
- package/dist/action-token-BdWad2YG.mjs.map +0 -1
- package/dist/activation-xomsCMJg.mjs +0 -387
- package/dist/activation-xomsCMJg.mjs.map +0 -1
- package/dist/adapters-B4-nbElt.d.mts +0 -173
- package/dist/adapters-B4-nbElt.d.mts.map +0 -1
- package/dist/allowed-origins-CLpHGGlc.mjs +0 -116
- package/dist/allowed-origins-CLpHGGlc.mjs.map +0 -1
- package/dist/api-DBw_IWoi.mjs +0 -5024
- package/dist/api-DBw_IWoi.mjs.map +0 -1
- package/dist/api-tokens-B0ZipcZ-.mjs +0 -173
- package/dist/api-tokens-B0ZipcZ-.mjs.map +0 -1
- package/dist/apply-Cx48saFC.mjs +0 -1680
- package/dist/apply-Cx48saFC.mjs.map +0 -1
- package/dist/approvals-BXgtXA2s.mjs +0 -460
- package/dist/approvals-BXgtXA2s.mjs.map +0 -1
- package/dist/artifact-fetch-DsRczRGG.mjs +0 -659
- package/dist/artifact-fetch-DsRczRGG.mjs.map +0 -1
- package/dist/artifacts-D-O-qj9C.mjs +0 -307
- package/dist/artifacts-D-O-qj9C.mjs.map +0 -1
- package/dist/audit-CCH3MA4Y.mjs +0 -127
- package/dist/audit-CCH3MA4Y.mjs.map +0 -1
- package/dist/authoritative-records-Dcs7l2H5.mjs +0 -5183
- package/dist/authoritative-records-Dcs7l2H5.mjs.map +0 -1
- package/dist/authorize-TdIGpRSE.mjs +0 -49
- package/dist/authorize-TdIGpRSE.mjs.map +0 -1
- package/dist/backup-CZt5Mzwx.mjs +0 -246
- package/dist/backup-CZt5Mzwx.mjs.map +0 -1
- package/dist/block-types-DHnkzE6u.mjs +0 -132
- package/dist/block-types-DHnkzE6u.mjs.map +0 -1
- package/dist/block-values-C4N_F2-G.mjs +0 -175
- package/dist/block-values-C4N_F2-G.mjs.map +0 -1
- package/dist/byline-BmVKOQ8l.mjs +0 -909
- package/dist/byline-BmVKOQ8l.mjs.map +0 -1
- package/dist/byline-fields-B8SDs3M_.mjs +0 -123
- package/dist/byline-fields-B8SDs3M_.mjs.map +0 -1
- package/dist/byline-fields-Bze3ZdAw.mjs +0 -280
- package/dist/byline-fields-Bze3ZdAw.mjs.map +0 -1
- package/dist/bylines-CHhR28r9.mjs +0 -150
- package/dist/bylines-CHhR28r9.mjs.map +0 -1
- package/dist/bylines-DZS4OflA.mjs +0 -234
- package/dist/bylines-DZS4OflA.mjs.map +0 -1
- package/dist/cache-x0z8t_m9.mjs +0 -133
- package/dist/cache-x0z8t_m9.mjs.map +0 -1
- package/dist/canonical-BUcKRYpG.mjs +0 -174
- package/dist/canonical-BUcKRYpG.mjs.map +0 -1
- package/dist/capture-triggers-C9JKoIdT.mjs +0 -362
- package/dist/capture-triggers-C9JKoIdT.mjs.map +0 -1
- package/dist/challenge-store-BHgdPVze.mjs +0 -51
- package/dist/challenge-store-BHgdPVze.mjs.map +0 -1
- package/dist/checksum-BYR5i7qe.mjs +0 -162
- package/dist/checksum-BYR5i7qe.mjs.map +0 -1
- package/dist/chunks-Dr5Vr0zA.mjs +0 -25
- package/dist/chunks-Dr5Vr0zA.mjs.map +0 -1
- package/dist/collection-slugs-cache-B2Gs9Jwx.mjs +0 -85
- package/dist/collection-slugs-cache-B2Gs9Jwx.mjs.map +0 -1
- package/dist/comment-CWla6OHV.mjs +0 -325
- package/dist/comment-CWla6OHV.mjs.map +0 -1
- package/dist/comment-reaction-RZrcs5cW.mjs +0 -85
- package/dist/comment-reaction-RZrcs5cW.mjs.map +0 -1
- package/dist/comments-BzmIKVb2.mjs +0 -99
- package/dist/comments-BzmIKVb2.mjs.map +0 -1
- package/dist/comments-Da_dI2O1.mjs +0 -195
- package/dist/comments-Da_dI2O1.mjs.map +0 -1
- package/dist/components-oFXumpf5.mjs +0 -112
- package/dist/components-oFXumpf5.mjs.map +0 -1
- package/dist/config--wamYxBW.d.mts +0 -39
- package/dist/config--wamYxBW.d.mts.map +0 -1
- package/dist/config-Bo4eOOdV.mjs +0 -228
- package/dist/config-Bo4eOOdV.mjs.map +0 -1
- package/dist/config-C4-UxIk7.d.mts +0 -6790
- package/dist/config-C4-UxIk7.d.mts.map +0 -1
- package/dist/connection-UpzYxtE2.mjs +0 -36
- package/dist/connection-UpzYxtE2.mjs.map +0 -1
- package/dist/content-CcHrqkgp.mjs +0 -2072
- package/dist/content-CcHrqkgp.mjs.map +0 -1
- package/dist/content-list-query-Bxxdd9fv.d.mts +0 -26
- package/dist/content-list-query-Bxxdd9fv.d.mts.map +0 -1
- package/dist/content-repair-havk1F0-.mjs +0 -442
- package/dist/content-repair-havk1F0-.mjs.map +0 -1
- package/dist/context-CvhgHgSH.mjs +0 -2043
- package/dist/context-CvhgHgSH.mjs.map +0 -1
- package/dist/credits-CygUrPOi.mjs +0 -110
- package/dist/credits-CygUrPOi.mjs.map +0 -1
- package/dist/cron-C6ytTOLw.mjs +0 -306
- package/dist/cron-C6ytTOLw.mjs.map +0 -1
- package/dist/dashboard-7_FYfafc.mjs +0 -151
- package/dist/dashboard-7_FYfafc.mjs.map +0 -1
- package/dist/default-CHCUkV4Z.mjs +0 -81
- package/dist/default-CHCUkV4Z.mjs.map +0 -1
- package/dist/deferred-tasks-G0xhcJTl.d.mts +0 -9
- package/dist/deferred-tasks-G0xhcJTl.d.mts.map +0 -1
- package/dist/dev-typegen-Dtl8AfS6.mjs +0 -29
- package/dist/dev-typegen-Dtl8AfS6.mjs.map +0 -1
- package/dist/device-flow-CzDJmQ1q.mjs +0 -521
- package/dist/device-flow-CzDJmQ1q.mjs.map +0 -1
- package/dist/digest-xJmyPv2r.mjs +0 -194
- package/dist/digest-xJmyPv2r.mjs.map +0 -1
- package/dist/direct-executor-BXiYIVJ9.mjs +0 -104
- package/dist/direct-executor-BXiYIVJ9.mjs.map +0 -1
- package/dist/email-console-7ZPApLlm.mjs +0 -50
- package/dist/email-console-7ZPApLlm.mjs.map +0 -1
- package/dist/email-locale-DFdUA6UF.mjs +0 -25
- package/dist/email-locale-DFdUA6UF.mjs.map +0 -1
- package/dist/emdash-runtime-C4oFeVpN.mjs +0 -4363
- package/dist/emdash-runtime-C4oFeVpN.mjs.map +0 -1
- package/dist/entry-lock-B4n0HdQ_.mjs +0 -163
- package/dist/entry-lock-B4n0HdQ_.mjs.map +0 -1
- package/dist/entry-lock-BAAlKYrz.d.mts +0 -4566
- package/dist/entry-lock-BAAlKYrz.d.mts.map +0 -1
- package/dist/entry-lock-Cjz0h45X.mjs +0 -1209
- package/dist/entry-lock-Cjz0h45X.mjs.map +0 -1
- package/dist/env-types-4bkF6Bqg.mjs +0 -38
- package/dist/env-types-4bkF6Bqg.mjs.map +0 -1
- package/dist/error-DxgQdaZ_.mjs +0 -90
- package/dist/error-DxgQdaZ_.mjs.map +0 -1
- package/dist/errors-CjtE5aWF.mjs +0 -120
- package/dist/errors-CjtE5aWF.mjs.map +0 -1
- package/dist/errors-hskQ0C8G.mjs +0 -479
- package/dist/errors-hskQ0C8G.mjs.map +0 -1
- package/dist/escape-ESFhYzwG.mjs +0 -9
- package/dist/escape-ESFhYzwG.mjs.map +0 -1
- package/dist/fence-vc3aHgRA.mjs +0 -162
- package/dist/fence-vc3aHgRA.mjs.map +0 -1
- package/dist/field-defs-cache-zoow36nz.mjs +0 -77
- package/dist/field-defs-cache-zoow36nz.mjs.map +0 -1
- package/dist/field-map-JD1wG0Tq.mjs +0 -83
- package/dist/field-map-JD1wG0Tq.mjs.map +0 -1
- package/dist/fts-manager-WJCN8uU6.mjs +0 -443
- package/dist/fts-manager-WJCN8uU6.mjs.map +0 -1
- package/dist/gc-CsGZiKdH.mjs +0 -75
- package/dist/gc-CsGZiKdH.mjs.map +0 -1
- package/dist/hash-C4DFoJ7Z.mjs +0 -37
- package/dist/hash-C4DFoJ7Z.mjs.map +0 -1
- package/dist/hook-result-CXjtMk7Q.d.mts +0 -31
- package/dist/hook-result-CXjtMk7Q.d.mts.map +0 -1
- package/dist/hreflang-BAma7iRr.mjs +0 -105
- package/dist/hreflang-BAma7iRr.mjs.map +0 -1
- package/dist/hreflang-BsYo4x_M.d.mts +0 -50
- package/dist/hreflang-BsYo4x_M.d.mts.map +0 -1
- package/dist/http-route-dispatch-C8G7hAK6.mjs +0 -342
- package/dist/http-route-dispatch-C8G7hAK6.mjs.map +0 -1
- package/dist/identity-BwBKM1fH.mjs +0 -35
- package/dist/identity-BwBKM1fH.mjs.map +0 -1
- package/dist/import-DJ3Z2wxE.mjs +0 -2021
- package/dist/import-DJ3Z2wxE.mjs.map +0 -1
- package/dist/index-DYsn97dY.d.mts +0 -623
- package/dist/index-DYsn97dY.d.mts.map +0 -1
- package/dist/install-finalization-DCFnFSHv.mjs +0 -58
- package/dist/install-finalization-DCFnFSHv.mjs.map +0 -1
- package/dist/keys-CGvAndSp.mjs +0 -61
- package/dist/keys-CGvAndSp.mjs.map +0 -1
- package/dist/kinds-DT1W4T4Y.mjs +0 -974
- package/dist/kinds-DT1W4T4Y.mjs.map +0 -1
- package/dist/lifecycle-BzglCSY0.mjs +0 -25
- package/dist/lifecycle-BzglCSY0.mjs.map +0 -1
- package/dist/load-DjUqmf3s.mjs +0 -28
- package/dist/load-DjUqmf3s.mjs.map +0 -1
- package/dist/loader-CetY659y.mjs +0 -1355
- package/dist/loader-CetY659y.mjs.map +0 -1
- package/dist/loops-DkT1zkPH.mjs +0 -205
- package/dist/loops-DkT1zkPH.mjs.map +0 -1
- package/dist/manifest-builder-BOFCd9rX.mjs +0 -189
- package/dist/manifest-builder-BOFCd9rX.mjs.map +0 -1
- package/dist/manifest-schema-BiFBPEsp.mjs +0 -497
- package/dist/manifest-schema-BiFBPEsp.mjs.map +0 -1
- package/dist/marketplace-CUlenvZm.mjs +0 -257
- package/dist/marketplace-CUlenvZm.mjs.map +0 -1
- package/dist/media-CRKsKlfK.mjs +0 -416
- package/dist/media-CRKsKlfK.mjs.map +0 -1
- package/dist/media-C_z7sRuC.mjs +0 -294
- package/dist/media-C_z7sRuC.mjs.map +0 -1
- package/dist/media-IT8hQleU.mjs +0 -373
- package/dist/media-IT8hQleU.mjs.map +0 -1
- package/dist/media-allowlist-Ct6wvnT2.mjs +0 -45
- package/dist/media-allowlist-Ct6wvnT2.mjs.map +0 -1
- package/dist/media-folders-DtMt-vAA.mjs +0 -210
- package/dist/media-folders-DtMt-vAA.mjs.map +0 -1
- package/dist/media-url-BpXLqCmf.mjs +0 -43
- package/dist/media-url-BpXLqCmf.mjs.map +0 -1
- package/dist/media-usage-DEPHZZ9X.mjs +0 -282
- package/dist/media-usage-DEPHZZ9X.mjs.map +0 -1
- package/dist/media-usage-activation-V2Siabtw.mjs +0 -78
- package/dist/media-usage-activation-V2Siabtw.mjs.map +0 -1
- package/dist/media-usage-work-Cv1OE59F.mjs +0 -151
- package/dist/media-usage-work-Cv1OE59F.mjs.map +0 -1
- package/dist/media-usage-work-cgDYGvrt.mjs +0 -1015
- package/dist/media-usage-work-cgDYGvrt.mjs.map +0 -1
- package/dist/menus-CvVYfsuk.mjs +0 -753
- package/dist/menus-CvVYfsuk.mjs.map +0 -1
- package/dist/menus-D1HC8npj.mjs +0 -92
- package/dist/menus-D1HC8npj.mjs.map +0 -1
- package/dist/menus-DL8IPIcm.mjs +0 -3721
- package/dist/menus-DL8IPIcm.mjs.map +0 -1
- package/dist/mode-eieqAWLe.mjs +0 -23
- package/dist/mode-eieqAWLe.mjs.map +0 -1
- package/dist/node-sqlite-compat-VuyzJw1b.mjs +0 -63
- package/dist/node-sqlite-compat-VuyzJw1b.mjs.map +0 -1
- package/dist/oauth-authorization-B6ZJbMd2.mjs +0 -274
- package/dist/oauth-authorization-B6ZJbMd2.mjs.map +0 -1
- package/dist/oauth-clients-DVjRc9v3.mjs +0 -266
- package/dist/oauth-clients-DVjRc9v3.mjs.map +0 -1
- package/dist/oauth-state-store-CnmYYsVQ.mjs +0 -50
- package/dist/oauth-state-store-CnmYYsVQ.mjs.map +0 -1
- package/dist/oauth-user-lookup-Dz1_R5vT.mjs +0 -26
- package/dist/oauth-user-lookup-Dz1_R5vT.mjs.map +0 -1
- package/dist/options-BR9XZl7h.d.mts +0 -81
- package/dist/options-BR9XZl7h.d.mts.map +0 -1
- package/dist/ownership-COPyVysP.mjs +0 -12
- package/dist/ownership-COPyVysP.mjs.map +0 -1
- package/dist/parse-BOGhrwSq.d.mts +0 -174
- package/dist/parse-BOGhrwSq.d.mts.map +0 -1
- package/dist/parse-Cn5aSk1N.mjs +0 -81
- package/dist/parse-Cn5aSk1N.mjs.map +0 -1
- package/dist/passkey-config-mMFRQUCj.mjs +0 -46
- package/dist/passkey-config-mMFRQUCj.mjs.map +0 -1
- package/dist/paths-BmcAdBo9.mjs +0 -77
- package/dist/paths-BmcAdBo9.mjs.map +0 -1
- package/dist/placeholder-nOep3_Gn.d.mts +0 -306
- package/dist/placeholder-nOep3_Gn.d.mts.map +0 -1
- package/dist/plan-CDY4K8CH.mjs +0 -135
- package/dist/plan-CDY4K8CH.mjs.map +0 -1
- package/dist/plugins-DFBpfbO3.mjs +0 -261
- package/dist/plugins-DFBpfbO3.mjs.map +0 -1
- package/dist/policy-B_2qnHSy.mjs +0 -45
- package/dist/policy-B_2qnHSy.mjs.map +0 -1
- package/dist/portable-text-Dc2YAusw.mjs +0 -307
- package/dist/portable-text-Dc2YAusw.mjs.map +0 -1
- package/dist/preview-BtzikJ9O.mjs +0 -107
- package/dist/preview-BtzikJ9O.mjs.map +0 -1
- package/dist/protocol-M268ox8L.d.mts +0 -61
- package/dist/protocol-M268ox8L.d.mts.map +0 -1
- package/dist/public-submission-BQZavgZU.mjs +0 -251
- package/dist/public-submission-BQZavgZU.mjs.map +0 -1
- package/dist/public-url-uT1Ok2Tu.mjs +0 -101
- package/dist/public-url-uT1Ok2Tu.mjs.map +0 -1
- package/dist/query-BGG3sDEd.mjs +0 -1127
- package/dist/query-BGG3sDEd.mjs.map +0 -1
- package/dist/query-C_CWlifp.mjs +0 -41
- package/dist/query-C_CWlifp.mjs.map +0 -1
- package/dist/range-CXK_kDbI.mjs +0 -51
- package/dist/range-CXK_kDbI.mjs.map +0 -1
- package/dist/rate-limit-Dvamvay-.mjs +0 -127
- package/dist/rate-limit-Dvamvay-.mjs.map +0 -1
- package/dist/receipt-BmQGzquP.mjs +0 -43
- package/dist/receipt-BmQGzquP.mjs.map +0 -1
- package/dist/redirect-B39kTQ_0.mjs +0 -423
- package/dist/redirect-B39kTQ_0.mjs.map +0 -1
- package/dist/redirect-BguJ00Pv.mjs +0 -19
- package/dist/redirect-BguJ00Pv.mjs.map +0 -1
- package/dist/redirects-C8G4BsfP.mjs +0 -446
- package/dist/redirects-C8G4BsfP.mjs.map +0 -1
- package/dist/redirects-DFT7Wr-e.mjs +0 -148
- package/dist/redirects-DFT7Wr-e.mjs.map +0 -1
- package/dist/registry-DeZ27gVi.mjs +0 -8374
- package/dist/registry-DeZ27gVi.mjs.map +0 -1
- package/dist/relations-DBB1bRJW.mjs +0 -776
- package/dist/relations-DBB1bRJW.mjs.map +0 -1
- package/dist/request-meta-BSvkhIBX.mjs +0 -141
- package/dist/request-meta-BSvkhIBX.mjs.map +0 -1
- package/dist/resolve-BxH64HN9.mjs +0 -100
- package/dist/resolve-BxH64HN9.mjs.map +0 -1
- package/dist/revision-BWEH2qQB.mjs +0 -368
- package/dist/revision-BWEH2qQB.mjs.map +0 -1
- package/dist/route-wire-CwbWB_6O.mjs +0 -197
- package/dist/route-wire-CwbWB_6O.mjs.map +0 -1
- package/dist/routes-BfIxc7ft.mjs +0 -272
- package/dist/routes-BfIxc7ft.mjs.map +0 -1
- package/dist/runner-DkeafPBA.d.mts +0 -68
- package/dist/runner-DkeafPBA.d.mts.map +0 -1
- package/dist/runner-wqt4BrIW.mjs +0 -6383
- package/dist/runner-wqt4BrIW.mjs.map +0 -1
- package/dist/schema-BXIW-JHi.mjs +0 -815
- package/dist/schema-BXIW-JHi.mjs.map +0 -1
- package/dist/schema-I74JwYte.mjs +0 -13
- package/dist/schema-I74JwYte.mjs.map +0 -1
- package/dist/scopes-RWZ5ft_Z.mjs +0 -34
- package/dist/scopes-RWZ5ft_Z.mjs.map +0 -1
- package/dist/search-DxwagyWS.mjs +0 -450
- package/dist/search-DxwagyWS.mjs.map +0 -1
- package/dist/sections-Ccq9ZgyD.mjs +0 -346
- package/dist/sections-Ccq9ZgyD.mjs.map +0 -1
- package/dist/seo-CCnfPWAQ.mjs +0 -133
- package/dist/seo-CCnfPWAQ.mjs.map +0 -1
- package/dist/seo-QCtJ1jjV.mjs +0 -188
- package/dist/seo-QCtJ1jjV.mjs.map +0 -1
- package/dist/service-DX84s2rw.mjs +0 -150
- package/dist/service-DX84s2rw.mjs.map +0 -1
- package/dist/session-user-1dtJc2zv.mjs +0 -61
- package/dist/session-user-1dtJc2zv.mjs.map +0 -1
- package/dist/settings-B1jOxAIl.mjs +0 -443
- package/dist/settings-B1jOxAIl.mjs.map +0 -1
- package/dist/settings-Bc1IBl1t.mjs +0 -66
- package/dist/settings-Bc1IBl1t.mjs.map +0 -1
- package/dist/settings-GaZ5sVgg.mjs +0 -73
- package/dist/settings-GaZ5sVgg.mjs.map +0 -1
- package/dist/setup-complete-DidMAWJS.mjs +0 -65
- package/dist/setup-complete-DidMAWJS.mjs.map +0 -1
- package/dist/setup-nonce-DKl4S4c6.mjs +0 -25
- package/dist/setup-nonce-DKl4S4c6.mjs.map +0 -1
- package/dist/site-domain-CbI51Pc2.mjs +0 -113
- package/dist/site-domain-CbI51Pc2.mjs.map +0 -1
- package/dist/site-settings-CDdT4mVm.mjs +0 -50
- package/dist/site-settings-CDdT4mVm.mjs.map +0 -1
- package/dist/site-url-CrDZaAvo.mjs +0 -45
- package/dist/site-url-CrDZaAvo.mjs.map +0 -1
- package/dist/sitemap-name-W3BTor6X.mjs +0 -26
- package/dist/sitemap-name-W3BTor6X.mjs.map +0 -1
- package/dist/slug-BJhHKoOH.mjs +0 -16
- package/dist/slug-BJhHKoOH.mjs.map +0 -1
- package/dist/snapshot-BuI_2uDe.mjs +0 -414
- package/dist/snapshot-BuI_2uDe.mjs.map +0 -1
- package/dist/ssrf-LM_0wpGA.mjs +0 -406
- package/dist/ssrf-LM_0wpGA.mjs.map +0 -1
- package/dist/stage-DhzZuYaT.mjs +0 -662
- package/dist/stage-DhzZuYaT.mjs.map +0 -1
- package/dist/staged-DboEaWsV.mjs +0 -686
- package/dist/staged-DboEaWsV.mjs.map +0 -1
- package/dist/state-DCXDzjHq.mjs +0 -178
- package/dist/state-DCXDzjHq.mjs.map +0 -1
- package/dist/status-Dl85BK39.mjs +0 -30
- package/dist/status-Dl85BK39.mjs.map +0 -1
- package/dist/storage-query-BOBmeDMD.d.mts +0 -1615
- package/dist/storage-query-BOBmeDMD.d.mts.map +0 -1
- package/dist/tar-K40edFMt.mjs +0 -449
- package/dist/tar-K40edFMt.mjs.map +0 -1
- package/dist/target-BOighEY1.mjs +0 -27
- package/dist/target-BOighEY1.mjs.map +0 -1
- package/dist/taxonomies-DQSywBvX.mjs +0 -697
- package/dist/taxonomies-DQSywBvX.mjs.map +0 -1
- package/dist/taxonomies-Dj5eaobC.mjs +0 -939
- package/dist/taxonomies-Dj5eaobC.mjs.map +0 -1
- package/dist/taxonomy-QrNmTfIZ.mjs +0 -550
- package/dist/taxonomy-QrNmTfIZ.mjs.map +0 -1
- package/dist/tokens-j5L0as2H.mjs +0 -171
- package/dist/tokens-j5L0as2H.mjs.map +0 -1
- package/dist/transfer-CYEw8Tu4.mjs +0 -8873
- package/dist/transfer-CYEw8Tu4.mjs.map +0 -1
- package/dist/transfer-DDX10hkD.mjs +0 -166
- package/dist/transfer-DDX10hkD.mjs.map +0 -1
- package/dist/transfer-download-BAqq6GJv.mjs +0 -33
- package/dist/transfer-download-BAqq6GJv.mjs.map +0 -1
- package/dist/transformations-De44wqV_.mjs +0 -196
- package/dist/transformations-De44wqV_.mjs.map +0 -1
- package/dist/transport-1QjUhCRO.d.mts +0 -42
- package/dist/transport-1QjUhCRO.d.mts.map +0 -1
- package/dist/transport-Ds5pVX7p.mjs +0 -136
- package/dist/transport-Ds5pVX7p.mjs.map +0 -1
- package/dist/trusted-proxy-d4Tk6biT.mjs +0 -51
- package/dist/trusted-proxy-d4Tk6biT.mjs.map +0 -1
- package/dist/turnstile-DaFLtyrs.mjs +0 -58
- package/dist/turnstile-DaFLtyrs.mjs.map +0 -1
- package/dist/types-B4-1P2DK.d.mts +0 -227
- package/dist/types-B4-1P2DK.d.mts.map +0 -1
- package/dist/types-BKXA0f-c.mjs +0 -16
- package/dist/types-BKXA0f-c.mjs.map +0 -1
- package/dist/types-BiHcpUoO.d.mts +0 -374
- package/dist/types-BiHcpUoO.d.mts.map +0 -1
- package/dist/types-BihhvkyN.d.mts +0 -85
- package/dist/types-BihhvkyN.d.mts.map +0 -1
- package/dist/types-Bq9Wohd7.d.mts +0 -363
- package/dist/types-Bq9Wohd7.d.mts.map +0 -1
- package/dist/types-C-Xp0CcN.mjs +0 -103
- package/dist/types-C-Xp0CcN.mjs.map +0 -1
- package/dist/types-C4P7F1Vq.d.mts +0 -1741
- package/dist/types-C4P7F1Vq.d.mts.map +0 -1
- package/dist/types-CGaqwHw4.mjs +0 -37
- package/dist/types-CGaqwHw4.mjs.map +0 -1
- package/dist/types-D4ECCE4X.mjs +0 -77
- package/dist/types-D4ECCE4X.mjs.map +0 -1
- package/dist/types-DcRJp0vS.d.mts +0 -125
- package/dist/types-DcRJp0vS.d.mts.map +0 -1
- package/dist/types-Ff85fTzU.d.mts +0 -289
- package/dist/types-Ff85fTzU.d.mts.map +0 -1
- package/dist/types-UKr5Sf4y.d.mts +0 -916
- package/dist/types-UKr5Sf4y.d.mts.map +0 -1
- package/dist/types-YpN8hZW7.d.mts +0 -204
- package/dist/types-YpN8hZW7.d.mts.map +0 -1
- package/dist/update-check-DrlsK-tt.mjs +0 -161
- package/dist/update-check-DrlsK-tt.mjs.map +0 -1
- package/dist/upload-attempts-D8CPPvRU.mjs +0 -32
- package/dist/upload-attempts-D8CPPvRU.mjs.map +0 -1
- package/dist/url-pattern-Di4Nn3vP.mjs +0 -41
- package/dist/url-pattern-Di4Nn3vP.mjs.map +0 -1
- package/dist/user-B-ZdGjhI.mjs +0 -171
- package/dist/user-B-ZdGjhI.mjs.map +0 -1
- package/dist/utils-D7wL3r6-.mjs +0 -437
- package/dist/utils-D7wL3r6-.mjs.map +0 -1
- package/dist/validate-BSZbSUDk.mjs +0 -524
- package/dist/validate-BSZbSUDk.mjs.map +0 -1
- package/dist/validate-Dfv0DpZi.d.mts +0 -468
- package/dist/validate-Dfv0DpZi.d.mts.map +0 -1
- package/dist/validation-DRyC_Vm5.mjs +0 -219
- package/dist/validation-DRyC_Vm5.mjs.map +0 -1
- package/dist/version-C4kz0PcO.mjs +0 -7
- package/dist/version-C4kz0PcO.mjs.map +0 -1
- package/dist/version-jhs2BRtl.mjs +0 -9
- package/dist/version-jhs2BRtl.mjs.map +0 -1
- package/dist/video-DReZ48Un.mjs +0 -54
- package/dist/video-DReZ48Un.mjs.map +0 -1
- package/dist/virtual-modules-D0e6VbEv.mjs +0 -516
- package/dist/virtual-modules-D0e6VbEv.mjs.map +0 -1
- package/dist/widgets-BkcMzKct.mjs +0 -121
- package/dist/widgets-BkcMzKct.mjs.map +0 -1
- package/dist/wxr-taxonomies-BxI0CbTg.mjs +0 -453
- package/dist/wxr-taxonomies-BxI0CbTg.mjs.map +0 -1
- package/dist/wxr-taxonomies-Dad33GJi.d.mts +0 -34
- package/dist/wxr-taxonomies-Dad33GJi.d.mts.map +0 -1
- package/dist/zod-generator-BQilAboC.mjs +0 -424
- package/dist/zod-generator-BQilAboC.mjs.map +0 -1
- /package/dist/{api-tokens-D2zgAIEt.mjs → api-tokens-CdP49zVF.mjs} +0 -0
- /package/dist/{ssrf-BvNItdxk.mjs → ssrf-DM0E-D_8.mjs} +0 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { t as getMenu } from "./menus-Cl4kwdt7.mjs";
|
|
2
|
+
import { n as createDeferredTaskTracker } from "./after-PcEvMY_6.mjs";
|
|
3
|
+
import { getRequestContext } from "./request-context.mjs";
|
|
4
|
+
import { n as cachedQuery, t as CacheNamespace } from "./object-cache-Bo6DGaC9.mjs";
|
|
5
|
+
import { i as setRequestCacheEntry, r as requestCached } from "./request-cache-C4CIo5ad.mjs";
|
|
6
|
+
import { c as getDb } from "./loader-CswroUbe.mjs";
|
|
7
|
+
import { flushRecorder, isInstrumentationEnabled } from "./database/instrumentation.mjs";
|
|
8
|
+
import { a as getTaxonomyDefs, o as getTaxonomyTerms } from "./taxonomies-ChnU7Mc8.mjs";
|
|
9
|
+
import { a as getSiteSettings } from "./settings-CWb84sDm.mjs";
|
|
10
|
+
import { r as getWidgetAreas } from "./widgets-DA5XmvVC.mjs";
|
|
11
|
+
|
|
12
|
+
//#region src/astro/middleware/scoped-db.ts
|
|
13
|
+
/**
|
|
14
|
+
* Request-scoped database lifecycle helpers.
|
|
15
|
+
*
|
|
16
|
+
* Extracted from middleware.ts so they can be unit-tested without pulling in
|
|
17
|
+
* the virtual:emdash/* module graph. The middleware imports these to settle a
|
|
18
|
+
* request-scoped db adapter's lifecycle around the response.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Astro attaches AstroCookies to outgoing responses via a well-known global
|
|
22
|
+
* symbol. Cloning a Response (`new Response(body, init)`) drops non-header
|
|
23
|
+
* metadata, so any helper that wraps the response must explicitly forward this
|
|
24
|
+
* symbol or `cookies.set()` calls will be silently dropped. `Symbol.for`
|
|
25
|
+
* returns the same registry symbol everywhere, so this matches the copy in
|
|
26
|
+
* middleware.ts.
|
|
27
|
+
*/
|
|
28
|
+
const ASTRO_COOKIES_SYMBOL = Symbol.for("astro.cookies");
|
|
29
|
+
/**
|
|
30
|
+
* Whether the request ended authenticated, for the db adapter's `commit()`.
|
|
31
|
+
* `isAuthenticated` is captured before the route runs, so it misses
|
|
32
|
+
* login/signup/invite requests that create the Astro session mid-request;
|
|
33
|
+
* `session.set()` writes the `astro-session` cookie into the jar synchronously,
|
|
34
|
+
* so scanning the outgoing cookies detects them. Only outgoing cookies count —
|
|
35
|
+
* a stale `astro-session` cookie arriving on an anonymous render must not
|
|
36
|
+
* qualify, or its replica-read bookmark would overwrite a fresher one from an
|
|
37
|
+
* earlier authenticated write.
|
|
38
|
+
*/
|
|
39
|
+
function requestEndedAuthenticated(isAuthenticated, cookies) {
|
|
40
|
+
if (isAuthenticated) return true;
|
|
41
|
+
for (const header of cookies.headers()) if (header.startsWith("astro-session=")) return true;
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
/** Hold the real adapter close behind both response and deferred-task completion. */
|
|
45
|
+
function coordinateScopedDbLifecycle(scoped) {
|
|
46
|
+
if (!scoped.close) return { lifecycle: scoped };
|
|
47
|
+
const close = scoped.close;
|
|
48
|
+
const deferredTasks = createDeferredTaskTracker(() => {
|
|
49
|
+
try {
|
|
50
|
+
close();
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("[emdash] request-scoped db close failed:", error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
closed: deferredTasks.settled,
|
|
57
|
+
deferredTasks,
|
|
58
|
+
lifecycle: {
|
|
59
|
+
commit: scoped.commit,
|
|
60
|
+
close: deferredTasks.settle
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Run a request-scoped db's `close()` once the response body has finished
|
|
66
|
+
* streaming. Astro streams HTML and components issue DB queries during that
|
|
67
|
+
* stream, so a connection-backed adapter (e.g. Postgres over Hyperdrive) must
|
|
68
|
+
* not be torn down until the body is flushed. Bodyless responses (redirects,
|
|
69
|
+
* 304s, errors) close immediately. A guard makes close idempotent and a stream
|
|
70
|
+
* `cancel` (client disconnect) still triggers it so connections never leak.
|
|
71
|
+
*
|
|
72
|
+
* No-op for adapters without a `close` (D1): the response passes through.
|
|
73
|
+
*/
|
|
74
|
+
function wrapResponseForScopedClose(response, close) {
|
|
75
|
+
let closed = false;
|
|
76
|
+
const runClose = () => {
|
|
77
|
+
if (closed) return;
|
|
78
|
+
closed = true;
|
|
79
|
+
try {
|
|
80
|
+
close();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error("[emdash] request-scoped db close failed:", error);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
if (!response.body) {
|
|
86
|
+
runClose();
|
|
87
|
+
return response;
|
|
88
|
+
}
|
|
89
|
+
const transform = new TransformStream({
|
|
90
|
+
flush: runClose,
|
|
91
|
+
cancel: runClose
|
|
92
|
+
});
|
|
93
|
+
const wrapped = new Response(response.body.pipeThrough(transform), response);
|
|
94
|
+
const astroCookies = Reflect.get(response, ASTRO_COOKIES_SYMBOL);
|
|
95
|
+
if (astroCookies !== void 0) Reflect.set(wrapped, ASTRO_COOKIES_SYMBOL, astroCookies);
|
|
96
|
+
wrapped.headers.delete("Content-Length");
|
|
97
|
+
return wrapped;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Run the request body under a request-scoped db, then settle its lifecycle:
|
|
101
|
+
* `commit()` runs before the response is returned (so per-request state like a
|
|
102
|
+
* D1 bookmark cookie is persisted in the headers, even if render throws), while
|
|
103
|
+
* `close()` (if any) is deferred to lifecycle settlement so a
|
|
104
|
+
* connection-backed adapter isn't torn down mid-render or mid-task. On error
|
|
105
|
+
* the lifecycle is settled before rethrowing so it never leaks.
|
|
106
|
+
*
|
|
107
|
+
* On the error path both `commit()` and `close()` are defended: a throw from
|
|
108
|
+
* either is logged and swallowed so it can't replace the propagating render
|
|
109
|
+
* error (which is the one the caller needs to see). On the success path
|
|
110
|
+
* `commit()` is guarded too — if it throws, the connection is closed before the
|
|
111
|
+
* failure is surfaced, so it never leaks. For the current adapters `commit()`
|
|
112
|
+
* is a no-op (Hyperdrive) or a cookie write (D1, no `close`) and `close()` is
|
|
113
|
+
* fire-and-forget, so these guards only matter for a future connection-backed
|
|
114
|
+
* adapter with throwing teardown, but the helper is generic and must not leak
|
|
115
|
+
* or mask.
|
|
116
|
+
*/
|
|
117
|
+
async function finishScoped(scoped, run) {
|
|
118
|
+
let response;
|
|
119
|
+
try {
|
|
120
|
+
response = await run();
|
|
121
|
+
} catch (error) {
|
|
122
|
+
commitSafely(scoped.commit);
|
|
123
|
+
closeSafely(scoped.close);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
scoped.commit();
|
|
128
|
+
} catch (error) {
|
|
129
|
+
closeSafely(scoped.close);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
return scoped.close ? wrapResponseForScopedClose(response, scoped.close) : response;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Run commit() swallowing any error. Used where an exception is already
|
|
136
|
+
* propagating (or about to be thrown) and a commit failure must neither mask it
|
|
137
|
+
* nor skip the subsequent close().
|
|
138
|
+
*/
|
|
139
|
+
function commitSafely(commit) {
|
|
140
|
+
try {
|
|
141
|
+
commit();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.error("[emdash] request-scoped db commit failed during error handling:", error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Run close() swallowing any error. Used on the error/commit-failure paths
|
|
148
|
+
* where another exception is the one the caller must see; a throwing teardown
|
|
149
|
+
* must not replace it.
|
|
150
|
+
*/
|
|
151
|
+
function closeSafely(close) {
|
|
152
|
+
if (!close) return;
|
|
153
|
+
try {
|
|
154
|
+
close();
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error("[emdash] request-scoped db close failed during error handling:", error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/astro/middleware/stream-end-metrics.ts
|
|
162
|
+
/**
|
|
163
|
+
* Stream-end metrics
|
|
164
|
+
*
|
|
165
|
+
* Server-Timing db.* counters are snapshotted when middleware's next()
|
|
166
|
+
* returns — but at that point only the response *headers* are final.
|
|
167
|
+
* Astro streams the body afterwards, and components rendered during
|
|
168
|
+
* streaming issue further DB queries that the headers can never report.
|
|
169
|
+
*
|
|
170
|
+
* This module wraps the response body in an identity TransformStream and
|
|
171
|
+
* snapshots the request metrics in flush(), i.e. when the body actually
|
|
172
|
+
* finishes streaming. The metrics object lives on the request context
|
|
173
|
+
* (AsyncLocalStorage) and is mutated in-place by the Kysely log hook, so
|
|
174
|
+
* a reference captured before wrapping observes every post-header query.
|
|
175
|
+
* The snapshot is emitted as prefixed NDJSON on stdout (same transport as
|
|
176
|
+
* [emdash-query-log] — console.log works in both Node and workerd).
|
|
177
|
+
*
|
|
178
|
+
* Gated on isInstrumentationEnabled() (EMDASH_QUERY_LOG=1): zero overhead
|
|
179
|
+
* in normal production traffic.
|
|
180
|
+
*/
|
|
181
|
+
const STREAM_END_PREFIX = "[emdash-stream-end]";
|
|
182
|
+
/**
|
|
183
|
+
* Wrap a response body so the FINAL request metrics are emitted when the
|
|
184
|
+
* body finishes streaming. Returns the response unchanged when
|
|
185
|
+
* instrumentation is disabled, the body is null, or no request metrics
|
|
186
|
+
* are attached (e.g. outside the middleware's ALS context).
|
|
187
|
+
*/
|
|
188
|
+
function wrapBodyForStreamMetrics(response) {
|
|
189
|
+
if (!isInstrumentationEnabled()) return response;
|
|
190
|
+
if (!response.body) return response;
|
|
191
|
+
const ctx = getRequestContext();
|
|
192
|
+
const metrics = ctx?.metrics;
|
|
193
|
+
if (!metrics) return response;
|
|
194
|
+
const recorder = ctx?.queryRecorder;
|
|
195
|
+
if (recorder) recorder.deferredFlush = true;
|
|
196
|
+
const transform = new TransformStream({ flush() {
|
|
197
|
+
const snapshot = {
|
|
198
|
+
route: recorder?.route,
|
|
199
|
+
method: recorder?.method,
|
|
200
|
+
phase: recorder?.phase,
|
|
201
|
+
totalMs: performance.now() - metrics.start,
|
|
202
|
+
dbCount: metrics.dbCount,
|
|
203
|
+
dbTotalMs: metrics.dbTotalMs,
|
|
204
|
+
dbFirstOffset: metrics.dbFirstOffset,
|
|
205
|
+
dbLastOffset: metrics.dbLastOffset,
|
|
206
|
+
cacheHits: metrics.cacheHits,
|
|
207
|
+
cacheMisses: metrics.cacheMisses
|
|
208
|
+
};
|
|
209
|
+
console.log(`${STREAM_END_PREFIX} ${JSON.stringify(snapshot)}`);
|
|
210
|
+
if (recorder) flushRecorder(recorder);
|
|
211
|
+
} });
|
|
212
|
+
const wrapped = new Response(response.body.pipeThrough(transform), response);
|
|
213
|
+
const astroCookies = Reflect.get(response, ASTRO_COOKIES_SYMBOL);
|
|
214
|
+
if (astroCookies !== void 0) Reflect.set(wrapped, ASTRO_COOKIES_SYMBOL, astroCookies);
|
|
215
|
+
wrapped.headers.delete("Content-Length");
|
|
216
|
+
return wrapped;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region src/astro/prefetch.ts
|
|
221
|
+
/**
|
|
222
|
+
* Eager, transparent prefetch of site-global "chrome" data.
|
|
223
|
+
*
|
|
224
|
+
* On a public page render, the shared layout pulls the same site-global data on
|
|
225
|
+
* every request -- menus, widget areas, taxonomy term lists, site settings --
|
|
226
|
+
* but each is awaited inside a separately-rendered Astro component, so they
|
|
227
|
+
* execute as serial DB round trips. This fires them all CONCURRENTLY at the
|
|
228
|
+
* very start of the request, before `next()`:
|
|
229
|
+
*
|
|
230
|
+
* - On remote backends whose adapter can overlap queries the round trips
|
|
231
|
+
* overlap instead of serializing, collapsing ~N sequential RTTs into ~1
|
|
232
|
+
* wall-clock RTT. On a coalescing backend they additionally batch into a
|
|
233
|
+
* single round trip.
|
|
234
|
+
* - The results land in the per-request `requestCached` store under the exact
|
|
235
|
+
* keys the layout helpers use, so when the components render they hit a warm
|
|
236
|
+
* (in-flight or resolved) cache entry instead of issuing their own query.
|
|
237
|
+
*
|
|
238
|
+
* Nothing here changes what templates call -- it warms the real helpers, so the
|
|
239
|
+
* cache keys and value shapes are guaranteed identical. The caller gates this to
|
|
240
|
+
* the public-page path on a request-scoped (remote) backend that can overlap
|
|
241
|
+
* queries; it is a no-op-ish waste on synchronous local SQLite and only delays
|
|
242
|
+
* the page on a handle that runs one query at a time, so don't call it there.
|
|
243
|
+
*
|
|
244
|
+
* Fire-and-forget: never awaited by middleware, never throws (a prefetch failure
|
|
245
|
+
* must not affect the request -- the helpers will simply run on demand).
|
|
246
|
+
*/
|
|
247
|
+
/** Warm widget areas: one bulk load, primed under each per-area cache key. */
|
|
248
|
+
async function prefetchWidgetAreas() {
|
|
249
|
+
const areas = await requestCached("widget-areas", getWidgetAreas);
|
|
250
|
+
for (const area of areas) setRequestCacheEntry(`widget-area:${area.name}`, area);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Warm every taxonomy's term list via the real helper (primes per-name keys).
|
|
254
|
+
* Counts are left out: they cost an aggregate over the whole assignment pivot
|
|
255
|
+
* per taxonomy, and only a consumer that renders one can say it's needed. A
|
|
256
|
+
* consumer that does asks for it and reuses the term list warmed here.
|
|
257
|
+
*/
|
|
258
|
+
async function prefetchTaxonomyTerms() {
|
|
259
|
+
const defs = await getTaxonomyDefs();
|
|
260
|
+
await Promise.allSettled(defs.map((def) => getTaxonomyTerms(def.name, { includeCounts: false })));
|
|
261
|
+
}
|
|
262
|
+
/** Warm every menu via the real helper (primes `menu:${name}:${locale}`). */
|
|
263
|
+
async function prefetchMenus() {
|
|
264
|
+
const names = await cachedQuery({
|
|
265
|
+
namespace: CacheNamespace.MENUS,
|
|
266
|
+
key: "names",
|
|
267
|
+
load: async () => {
|
|
268
|
+
const rows = await (await getDb()).selectFrom("_emdash_menus").select("name").distinct().execute();
|
|
269
|
+
return [...new Set(rows.map((r) => r.name))];
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
await Promise.allSettled(names.map((name) => getMenu(name)));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Concurrently warm the site-global layout data for the current request.
|
|
276
|
+
* Safe to call only inside the request ALS frame that owns the (remote)
|
|
277
|
+
* request-scoped db. Never throws.
|
|
278
|
+
*/
|
|
279
|
+
async function prefetchLayoutData() {
|
|
280
|
+
try {
|
|
281
|
+
await Promise.allSettled([
|
|
282
|
+
getSiteSettings(),
|
|
283
|
+
prefetchMenus(),
|
|
284
|
+
prefetchWidgetAreas(),
|
|
285
|
+
prefetchTaxonomyTerms()
|
|
286
|
+
]);
|
|
287
|
+
} catch (error) {
|
|
288
|
+
console.error("[emdash] layout prefetch failed (non-fatal):", error);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region src/astro/public-plugin-api-routes.ts
|
|
294
|
+
function getPublicPluginRouteMeta(runtime, pluginId, path) {
|
|
295
|
+
const meta = runtime.getPluginRouteMeta(pluginId, path);
|
|
296
|
+
return meta?.public === true ? meta : null;
|
|
297
|
+
}
|
|
298
|
+
function pluginRouteNotFound() {
|
|
299
|
+
return {
|
|
300
|
+
success: false,
|
|
301
|
+
error: {
|
|
302
|
+
code: "NOT_FOUND",
|
|
303
|
+
message: "Plugin route not found"
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function createPublicPluginApiRouteHandler(runtime) {
|
|
308
|
+
return async (pluginId, method, path, request) => {
|
|
309
|
+
if (!getPublicPluginRouteMeta(runtime, pluginId, path)) return pluginRouteNotFound();
|
|
310
|
+
return runtime.handlePluginApiRoute(pluginId, method, path, request);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
//#endregion
|
|
315
|
+
export { ASTRO_COOKIES_SYMBOL as a, requestEndedAuthenticated as c, wrapBodyForStreamMetrics as i, getPublicPluginRouteMeta as n, coordinateScopedDbLifecycle as o, prefetchLayoutData as r, finishScoped as s, createPublicPluginApiRouteHandler as t };
|
|
316
|
+
//# sourceMappingURL=public-plugin-api-routes-BuAMJ8nN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-plugin-api-routes-BuAMJ8nN.mjs","names":[],"sources":["../src/astro/middleware/scoped-db.ts","../src/astro/middleware/stream-end-metrics.ts","../src/astro/prefetch.ts","../src/astro/public-plugin-api-routes.ts"],"sourcesContent":["/**\n * Request-scoped database lifecycle helpers.\n *\n * Extracted from middleware.ts so they can be unit-tested without pulling in\n * the virtual:emdash/* module graph. The middleware imports these to settle a\n * request-scoped db adapter's lifecycle around the response.\n */\n\nimport { createDeferredTaskTracker } from \"../../deferred-tasks.js\";\nimport type { DeferredTaskTracker } from \"../../deferred-tasks.js\";\n\n/**\n * Astro attaches AstroCookies to outgoing responses via a well-known global\n * symbol. Cloning a Response (`new Response(body, init)`) drops non-header\n * metadata, so any helper that wraps the response must explicitly forward this\n * symbol or `cookies.set()` calls will be silently dropped. `Symbol.for`\n * returns the same registry symbol everywhere, so this matches the copy in\n * middleware.ts.\n */\nexport const ASTRO_COOKIES_SYMBOL = Symbol.for(\"astro.cookies\");\n\ninterface ScopedDbLifecycle {\n\tcommit: () => void;\n\tclose?: () => void;\n}\n\n/**\n * Whether the request ended authenticated, for the db adapter's `commit()`.\n * `isAuthenticated` is captured before the route runs, so it misses\n * login/signup/invite requests that create the Astro session mid-request;\n * `session.set()` writes the `astro-session` cookie into the jar synchronously,\n * so scanning the outgoing cookies detects them. Only outgoing cookies count —\n * a stale `astro-session` cookie arriving on an anonymous render must not\n * qualify, or its replica-read bookmark would overwrite a fresher one from an\n * earlier authenticated write.\n */\nexport function requestEndedAuthenticated(\n\tisAuthenticated: boolean,\n\tcookies: { headers(): Iterable<string> },\n): boolean {\n\tif (isAuthenticated) return true;\n\tfor (const header of cookies.headers()) {\n\t\tif (header.startsWith(\"astro-session=\")) return true;\n\t}\n\treturn false;\n}\n\n/** Hold the real adapter close behind both response and deferred-task completion. */\nexport function coordinateScopedDbLifecycle(scoped: ScopedDbLifecycle): {\n\tclosed?: Promise<void>;\n\tdeferredTasks?: DeferredTaskTracker;\n\tlifecycle: ScopedDbLifecycle;\n} {\n\tif (!scoped.close) return { lifecycle: scoped };\n\n\tconst close = scoped.close;\n\tconst deferredTasks = createDeferredTaskTracker(() => {\n\t\ttry {\n\t\t\tclose();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[emdash] request-scoped db close failed:\", error);\n\t\t}\n\t});\n\treturn {\n\t\tclosed: deferredTasks.settled,\n\t\tdeferredTasks,\n\t\tlifecycle: { commit: scoped.commit, close: deferredTasks.settle },\n\t};\n}\n\n/**\n * Run a request-scoped db's `close()` once the response body has finished\n * streaming. Astro streams HTML and components issue DB queries during that\n * stream, so a connection-backed adapter (e.g. Postgres over Hyperdrive) must\n * not be torn down until the body is flushed. Bodyless responses (redirects,\n * 304s, errors) close immediately. A guard makes close idempotent and a stream\n * `cancel` (client disconnect) still triggers it so connections never leak.\n *\n * No-op for adapters without a `close` (D1): the response passes through.\n */\nexport function wrapResponseForScopedClose(response: Response, close: () => void): Response {\n\tlet closed = false;\n\tconst runClose = () => {\n\t\tif (closed) return;\n\t\tclosed = true;\n\t\ttry {\n\t\t\tclose();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[emdash] request-scoped db close failed:\", error);\n\t\t}\n\t};\n\n\tif (!response.body) {\n\t\trunClose();\n\t\treturn response;\n\t}\n\n\tconst transform = new TransformStream<Uint8Array, Uint8Array>({\n\t\tflush: runClose,\n\t\tcancel: runClose,\n\t});\n\tconst wrapped = new Response(response.body.pipeThrough(transform), response);\n\tconst astroCookies = Reflect.get(response, ASTRO_COOKIES_SYMBOL);\n\tif (astroCookies !== undefined) {\n\t\tReflect.set(wrapped, ASTRO_COOKIES_SYMBOL, astroCookies);\n\t}\n\t// Byte counts are preserved by the identity transform, but a stale\n\t// Content-Length on a reconstructed streaming Response risks truncation.\n\twrapped.headers.delete(\"Content-Length\");\n\treturn wrapped;\n}\n\n/**\n * Run the request body under a request-scoped db, then settle its lifecycle:\n * `commit()` runs before the response is returned (so per-request state like a\n * D1 bookmark cookie is persisted in the headers, even if render throws), while\n * `close()` (if any) is deferred to lifecycle settlement so a\n * connection-backed adapter isn't torn down mid-render or mid-task. On error\n * the lifecycle is settled before rethrowing so it never leaks.\n *\n * On the error path both `commit()` and `close()` are defended: a throw from\n * either is logged and swallowed so it can't replace the propagating render\n * error (which is the one the caller needs to see). On the success path\n * `commit()` is guarded too — if it throws, the connection is closed before the\n * failure is surfaced, so it never leaks. For the current adapters `commit()`\n * is a no-op (Hyperdrive) or a cookie write (D1, no `close`) and `close()` is\n * fire-and-forget, so these guards only matter for a future connection-backed\n * adapter with throwing teardown, but the helper is generic and must not leak\n * or mask.\n */\nexport async function finishScoped(\n\tscoped: ScopedDbLifecycle,\n\trun: () => Promise<Response>,\n): Promise<Response> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await run();\n\t} catch (error) {\n\t\t// A render error is already propagating; neither commit nor close may\n\t\t// mask it, and close must still run so the connection doesn't leak.\n\t\tcommitSafely(scoped.commit);\n\t\tcloseSafely(scoped.close);\n\t\tthrow error;\n\t}\n\ttry {\n\t\tscoped.commit();\n\t} catch (error) {\n\t\t// commit() failed on the success path: close the connection now (the\n\t\t// response won't be wrapped, so stream-end close would never run) and\n\t\t// surface the failure. close is swallowed so it can't mask the commit\n\t\t// error that the caller needs to see.\n\t\tcloseSafely(scoped.close);\n\t\tthrow error;\n\t}\n\treturn scoped.close ? wrapResponseForScopedClose(response, scoped.close) : response;\n}\n\n/**\n * Run commit() swallowing any error. Used where an exception is already\n * propagating (or about to be thrown) and a commit failure must neither mask it\n * nor skip the subsequent close().\n */\nfunction commitSafely(commit: () => void): void {\n\ttry {\n\t\tcommit();\n\t} catch (error) {\n\t\tconsole.error(\"[emdash] request-scoped db commit failed during error handling:\", error);\n\t}\n}\n\n/**\n * Run close() swallowing any error. Used on the error/commit-failure paths\n * where another exception is the one the caller must see; a throwing teardown\n * must not replace it.\n */\nfunction closeSafely(close: (() => void) | undefined): void {\n\tif (!close) return;\n\ttry {\n\t\tclose();\n\t} catch (error) {\n\t\tconsole.error(\"[emdash] request-scoped db close failed during error handling:\", error);\n\t}\n}\n","/**\n * Stream-end metrics\n *\n * Server-Timing db.* counters are snapshotted when middleware's next()\n * returns — but at that point only the response *headers* are final.\n * Astro streams the body afterwards, and components rendered during\n * streaming issue further DB queries that the headers can never report.\n *\n * This module wraps the response body in an identity TransformStream and\n * snapshots the request metrics in flush(), i.e. when the body actually\n * finishes streaming. The metrics object lives on the request context\n * (AsyncLocalStorage) and is mutated in-place by the Kysely log hook, so\n * a reference captured before wrapping observes every post-header query.\n * The snapshot is emitted as prefixed NDJSON on stdout (same transport as\n * [emdash-query-log] — console.log works in both Node and workerd).\n *\n * Gated on isInstrumentationEnabled() (EMDASH_QUERY_LOG=1): zero overhead\n * in normal production traffic.\n */\n\nimport { flushRecorder, isInstrumentationEnabled } from \"../../database/instrumentation.js\";\nimport { getRequestContext } from \"../../request-context.js\";\n// Reuse the single source of truth for Astro's well-known cookies symbol\n// rather than redefining `Symbol.for(\"astro.cookies\")` here — it must stay in\n// lockstep with the copy the rest of the middleware forwards.\nimport { ASTRO_COOKIES_SYMBOL } from \"./scoped-db.js\";\n\nexport const STREAM_END_PREFIX = \"[emdash-stream-end]\";\n\n/** Shape of the NDJSON snapshot emitted when the body finishes streaming. */\nexport interface StreamEndSnapshot {\n\troute?: string;\n\tmethod?: string;\n\tphase?: string;\n\t/** Total elapsed ms from middleware entry to end of body streaming. */\n\ttotalMs: number;\n\tdbCount: number;\n\tdbTotalMs: number;\n\tdbFirstOffset: number | null;\n\tdbLastOffset: number | null;\n\tcacheHits: number;\n\tcacheMisses: number;\n}\n\n/**\n * Wrap a response body so the FINAL request metrics are emitted when the\n * body finishes streaming. Returns the response unchanged when\n * instrumentation is disabled, the body is null, or no request metrics\n * are attached (e.g. outside the middleware's ALS context).\n */\nexport function wrapBodyForStreamMetrics(response: Response): Response {\n\tif (!isInstrumentationEnabled()) return response;\n\tif (!response.body) return response;\n\n\t// Capture the context's metrics object BEFORE wrapping: flush() runs\n\t// after the middleware's ALS frame may have exited, but the object\n\t// reference stays live and is mutated in-place by the Kysely log hook.\n\tconst ctx = getRequestContext();\n\tconst metrics = ctx?.metrics;\n\tif (!metrics) return response;\n\tconst recorder = ctx?.queryRecorder;\n\n\t// Claim the per-query flush: the recorder is mutated in-place by the\n\t// Kysely log hook for the whole request, including queries issued by\n\t// components while the body streams. Flushing here (rather than when\n\t// middleware returns) is what captures those streaming queries. The\n\t// flag tells the middleware's fallback flush to leave this recorder\n\t// to us.\n\tif (recorder) recorder.deferredFlush = true;\n\n\tconst transform = new TransformStream<Uint8Array, Uint8Array>({\n\t\tflush() {\n\t\t\tconst snapshot: StreamEndSnapshot = {\n\t\t\t\troute: recorder?.route,\n\t\t\t\tmethod: recorder?.method,\n\t\t\t\tphase: recorder?.phase,\n\t\t\t\ttotalMs: performance.now() - metrics.start,\n\t\t\t\tdbCount: metrics.dbCount,\n\t\t\t\tdbTotalMs: metrics.dbTotalMs,\n\t\t\t\tdbFirstOffset: metrics.dbFirstOffset,\n\t\t\t\tdbLastOffset: metrics.dbLastOffset,\n\t\t\t\tcacheHits: metrics.cacheHits,\n\t\t\t\tcacheMisses: metrics.cacheMisses,\n\t\t\t};\n\t\t\tconsole.log(`${STREAM_END_PREFIX} ${JSON.stringify(snapshot)}`);\n\t\t\t// Emit the full per-query log now that streaming is complete.\n\t\t\tif (recorder) flushRecorder(recorder);\n\t\t},\n\t});\n\n\tconst wrapped = new Response(response.body.pipeThrough(transform), response);\n\tconst astroCookies = Reflect.get(response, ASTRO_COOKIES_SYMBOL);\n\tif (astroCookies !== undefined) {\n\t\tReflect.set(wrapped, ASTRO_COOKIES_SYMBOL, astroCookies);\n\t}\n\t// The identity transform preserves byte counts today, but a stale\n\t// Content-Length on a re-constructed streaming Response risks\n\t// truncation if anything upstream changes; the header is recomputed\n\t// (or chunked encoding used) by the server layer anyway.\n\twrapped.headers.delete(\"Content-Length\");\n\treturn wrapped;\n}\n","/**\n * Eager, transparent prefetch of site-global \"chrome\" data.\n *\n * On a public page render, the shared layout pulls the same site-global data on\n * every request -- menus, widget areas, taxonomy term lists, site settings --\n * but each is awaited inside a separately-rendered Astro component, so they\n * execute as serial DB round trips. This fires them all CONCURRENTLY at the\n * very start of the request, before `next()`:\n *\n * - On remote backends whose adapter can overlap queries the round trips\n * overlap instead of serializing, collapsing ~N sequential RTTs into ~1\n * wall-clock RTT. On a coalescing backend they additionally batch into a\n * single round trip.\n * - The results land in the per-request `requestCached` store under the exact\n * keys the layout helpers use, so when the components render they hit a warm\n * (in-flight or resolved) cache entry instead of issuing their own query.\n *\n * Nothing here changes what templates call -- it warms the real helpers, so the\n * cache keys and value shapes are guaranteed identical. The caller gates this to\n * the public-page path on a request-scoped (remote) backend that can overlap\n * queries; it is a no-op-ish waste on synchronous local SQLite and only delays\n * the page on a handle that runs one query at a time, so don't call it there.\n *\n * Fire-and-forget: never awaited by middleware, never throws (a prefetch failure\n * must not affect the request -- the helpers will simply run on demand).\n */\n\nimport { getDb } from \"../loader.js\";\nimport { getMenu } from \"../menus/index.js\";\nimport { cachedQuery, CacheNamespace } from \"../object-cache/index.js\";\nimport { requestCached, setRequestCacheEntry } from \"../request-cache.js\";\nimport { getSiteSettings } from \"../settings/index.js\";\nimport { getTaxonomyDefs, getTaxonomyTerms } from \"../taxonomies/index.js\";\nimport { getWidgetAreas } from \"../widgets/index.js\";\n\n/** Warm widget areas: one bulk load, primed under each per-area cache key. */\nasync function prefetchWidgetAreas(): Promise<void> {\n\tconst areas = await requestCached(\"widget-areas\", getWidgetAreas);\n\t// getWidgetArea(name) caches under `widget-area:${name}` and returns the same\n\t// WidgetArea shape getWidgetAreas yields, so priming here makes those calls hit.\n\tfor (const area of areas) {\n\t\tsetRequestCacheEntry(`widget-area:${area.name}`, area);\n\t}\n}\n\n/**\n * Warm every taxonomy's term list via the real helper (primes per-name keys).\n * Counts are left out: they cost an aggregate over the whole assignment pivot\n * per taxonomy, and only a consumer that renders one can say it's needed. A\n * consumer that does asks for it and reuses the term list warmed here.\n */\nasync function prefetchTaxonomyTerms(): Promise<void> {\n\tconst defs = await getTaxonomyDefs();\n\tawait Promise.allSettled(defs.map((def) => getTaxonomyTerms(def.name, { includeCounts: false })));\n}\n\n/** Warm every menu via the real helper (primes `menu:${name}:${locale}`). */\nasync function prefetchMenus(): Promise<void> {\n\t// The layout calls getMenu(name) with hardcoded names; we can't know them, so\n\t// discover every menu name and warm them all (small, bounded chrome table).\n\tconst names = await cachedQuery({\n\t\tnamespace: CacheNamespace.MENUS,\n\t\tkey: \"names\",\n\t\tload: async () => {\n\t\t\tconst db = await getDb();\n\t\t\tconst rows = await db.selectFrom(\"_emdash_menus\").select(\"name\").distinct().execute();\n\t\t\treturn [...new Set(rows.map((r) => r.name))];\n\t\t},\n\t});\n\tawait Promise.allSettled(names.map((name) => getMenu(name)));\n}\n\n/**\n * Concurrently warm the site-global layout data for the current request.\n * Safe to call only inside the request ALS frame that owns the (remote)\n * request-scoped db. Never throws.\n */\nexport async function prefetchLayoutData(): Promise<void> {\n\ttry {\n\t\tawait Promise.allSettled([\n\t\t\tgetSiteSettings(),\n\t\t\tprefetchMenus(),\n\t\t\tprefetchWidgetAreas(),\n\t\t\tprefetchTaxonomyTerms(),\n\t\t]);\n\t} catch (error) {\n\t\t// Defensive: Promise.allSettled shouldn't reject, but never let a prefetch\n\t\t// failure surface to the request.\n\t\tconsole.error(\"[emdash] layout prefetch failed (non-fatal):\", error);\n\t}\n}\n","import type { RouteMeta } from \"../plugins/routes.js\";\nimport type { HandlerResponse } from \"./types.js\";\n\nexport type PublicPluginApiRouteHandler = (\n\tpluginId: string,\n\tmethod: string,\n\tpath: string,\n\trequest: Request,\n) => Promise<HandlerResponse>;\n\ninterface PublicPluginApiRouteRuntime {\n\tgetPluginRouteMeta(pluginId: string, path: string): RouteMeta | null;\n\thandlePluginApiRoute(\n\t\tpluginId: string,\n\t\tmethod: string,\n\t\tpath: string,\n\t\trequest: Request,\n\t): Promise<HandlerResponse>;\n}\n\nexport function getPublicPluginRouteMeta(\n\truntime: Pick<PublicPluginApiRouteRuntime, \"getPluginRouteMeta\">,\n\tpluginId: string,\n\tpath: string,\n): RouteMeta | null {\n\tconst meta = runtime.getPluginRouteMeta(pluginId, path);\n\treturn meta?.public === true ? meta : null;\n}\n\nfunction pluginRouteNotFound(): HandlerResponse {\n\treturn {\n\t\tsuccess: false,\n\t\terror: {\n\t\t\tcode: \"NOT_FOUND\",\n\t\t\tmessage: \"Plugin route not found\",\n\t\t},\n\t};\n}\n\nexport function createPublicPluginApiRouteHandler(\n\truntime: PublicPluginApiRouteRuntime,\n): PublicPluginApiRouteHandler {\n\treturn async (pluginId, method, path, request) => {\n\t\tif (!getPublicPluginRouteMeta(runtime, pluginId, path)) {\n\t\t\treturn pluginRouteNotFound();\n\t\t}\n\n\t\treturn runtime.handlePluginApiRoute(pluginId, method, path, request);\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { t as validateIdentifier } from "./validate-DANX1-Qi.mjs";
|
|
2
|
+
import { t as after } from "./after-PcEvMY_6.mjs";
|
|
3
|
+
import { a as resolveSecretsCached } from "./secrets-Cc_O3Kp-.mjs";
|
|
4
|
+
import { t as CommentRepository } from "./comment-UvIWDKcW.mjs";
|
|
5
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "./error-CVWeIOku.mjs";
|
|
6
|
+
import { n as parseBody, t as isParseError } from "./parse-DgQ2NABT.mjs";
|
|
7
|
+
import { c as createCommentBody } from "./comments-yiRFx3w5.mjs";
|
|
8
|
+
import { t as extractRequestMeta } from "./request-meta-bwZ_NsvU.mjs";
|
|
9
|
+
import { n as getSiteBaseUrl } from "./site-url-MB685I5X.mjs";
|
|
10
|
+
import { t as escapeHtml } from "./escape-lsNq38PP.mjs";
|
|
11
|
+
import { s as hashIp } from "./comments-pej-_BUO.mjs";
|
|
12
|
+
import { t as checkRateLimit } from "./rate-limit-Xp4d0NBY.mjs";
|
|
13
|
+
import { n as createComment } from "./service-Bo_usgSk.mjs";
|
|
14
|
+
import { sql } from "kysely";
|
|
15
|
+
|
|
16
|
+
//#region src/comments/notifications.ts
|
|
17
|
+
const NOTIFICATION_SOURCE = "emdash-comments";
|
|
18
|
+
const MAX_EXCERPT_LENGTH = 500;
|
|
19
|
+
const CRLF_RE = /[\r\n]/g;
|
|
20
|
+
/**
|
|
21
|
+
* Build an email notification for a new comment.
|
|
22
|
+
*/
|
|
23
|
+
function buildCommentNotificationEmail(to, data) {
|
|
24
|
+
const title = data.contentTitle || `${data.collection} item`;
|
|
25
|
+
const subject = `New comment on "${title}"`.replace(CRLF_RE, " ");
|
|
26
|
+
const excerpt = data.commentBody.length > MAX_EXCERPT_LENGTH ? data.commentBody.slice(0, MAX_EXCERPT_LENGTH) + "..." : data.commentBody;
|
|
27
|
+
const adminUrl = `${data.adminBaseUrl}/admin/comments`;
|
|
28
|
+
return {
|
|
29
|
+
to,
|
|
30
|
+
subject,
|
|
31
|
+
text: [
|
|
32
|
+
`${data.commentAuthorName} commented on "${title}":`,
|
|
33
|
+
"",
|
|
34
|
+
excerpt,
|
|
35
|
+
"",
|
|
36
|
+
`View in admin: ${adminUrl}`
|
|
37
|
+
].join("\n"),
|
|
38
|
+
html: [
|
|
39
|
+
`<p><strong>${escapeHtml(data.commentAuthorName)}</strong> commented on “${escapeHtml(title)}”:</p>`,
|
|
40
|
+
`<blockquote style="border-left:3px solid #ccc;padding-left:12px;margin:12px 0;color:#555">${escapeHtml(excerpt)}</blockquote>`,
|
|
41
|
+
`<p><a href="${escapeHtml(adminUrl)}">View in admin</a></p>`
|
|
42
|
+
].join("\n")
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Send a comment notification to the content author if all conditions are met:
|
|
47
|
+
* 1. Comment status is "approved"
|
|
48
|
+
* 2. Content author exists and has an email
|
|
49
|
+
* 3. Email provider is configured
|
|
50
|
+
* 4. Commenter is not the content author (no self-notifications)
|
|
51
|
+
*
|
|
52
|
+
* Returns true if the email was sent, false if skipped.
|
|
53
|
+
*/
|
|
54
|
+
async function sendCommentNotification(params) {
|
|
55
|
+
const { email, comment, contentAuthor, adminBaseUrl } = params;
|
|
56
|
+
if (comment.status !== "approved") return false;
|
|
57
|
+
if (!contentAuthor?.email) return false;
|
|
58
|
+
if (!email.isAvailable()) return false;
|
|
59
|
+
if (comment.authorEmail.toLowerCase() === contentAuthor.email.toLowerCase()) return false;
|
|
60
|
+
const message = buildCommentNotificationEmail(contentAuthor.email, {
|
|
61
|
+
commentAuthorName: comment.authorName,
|
|
62
|
+
commentBody: comment.body,
|
|
63
|
+
contentTitle: params.contentTitle || "",
|
|
64
|
+
collection: comment.collection,
|
|
65
|
+
adminBaseUrl
|
|
66
|
+
});
|
|
67
|
+
await email.send(message, NOTIFICATION_SOURCE);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Look up a content item's author from the database.
|
|
72
|
+
*
|
|
73
|
+
* Used by the admin moderation route where content info isn't
|
|
74
|
+
* readily available (only the comment record is at hand).
|
|
75
|
+
*/
|
|
76
|
+
async function lookupContentAuthor(db, collection, contentId) {
|
|
77
|
+
validateIdentifier(collection, "collection");
|
|
78
|
+
const contentRow = await db.selectFrom(`ec_${collection}`).select(["slug", "author_id"]).where("id", "=", contentId).executeTakeFirst();
|
|
79
|
+
if (!contentRow) return null;
|
|
80
|
+
const typed = contentRow;
|
|
81
|
+
let author;
|
|
82
|
+
if (typed.author_id) {
|
|
83
|
+
const userRow = await db.selectFrom("users").select([
|
|
84
|
+
"id",
|
|
85
|
+
"name",
|
|
86
|
+
"email",
|
|
87
|
+
"email_verified"
|
|
88
|
+
]).where("id", "=", typed.author_id).executeTakeFirst();
|
|
89
|
+
if (userRow && userRow.email_verified) author = {
|
|
90
|
+
id: userRow.id,
|
|
91
|
+
email: userRow.email,
|
|
92
|
+
name: userRow.name
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
slug: typed.slug,
|
|
97
|
+
author
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/comments/public-submission.ts
|
|
103
|
+
function parseCommentModeration(value) {
|
|
104
|
+
if (value === "all" || value === "first_time" || value === "none") return value;
|
|
105
|
+
return "all";
|
|
106
|
+
}
|
|
107
|
+
function isModerationDecision(value) {
|
|
108
|
+
if (typeof value !== "object" || value === null || !("status" in value)) return false;
|
|
109
|
+
if (value.status !== "pending" && value.status !== "approved" && value.status !== "spam") return false;
|
|
110
|
+
return !("reason" in value) || value.reason === void 0 || typeof value.reason === "string";
|
|
111
|
+
}
|
|
112
|
+
async function submitPublicComment(runtime, collection, contentId, request, user) {
|
|
113
|
+
try {
|
|
114
|
+
const body = await parseBody(request, createCommentBody);
|
|
115
|
+
if (isParseError(body)) return body;
|
|
116
|
+
const collectionRow = await runtime.db.selectFrom("_emdash_collections").select([
|
|
117
|
+
"comments_enabled",
|
|
118
|
+
"comments_moderation",
|
|
119
|
+
"comments_closed_after_days",
|
|
120
|
+
"comments_auto_approve_users"
|
|
121
|
+
]).where("slug", "=", collection).executeTakeFirst();
|
|
122
|
+
if (!collectionRow) return apiError("NOT_FOUND", `Collection '${collection}' not found`, 404);
|
|
123
|
+
if (!collectionRow.comments_enabled) return apiError("COMMENTS_DISABLED", "Comments are not enabled for this collection", 403);
|
|
124
|
+
validateIdentifier(collection, "collection");
|
|
125
|
+
const contentRow = (await sql`
|
|
126
|
+
SELECT id, slug, author_id, published_at
|
|
127
|
+
FROM ${sql.ref(`ec_${collection}`)}
|
|
128
|
+
WHERE id = ${contentId}
|
|
129
|
+
AND status = 'published'
|
|
130
|
+
AND deleted_at IS NULL
|
|
131
|
+
`.execute(runtime.db)).rows[0];
|
|
132
|
+
if (!contentRow) return apiError("NOT_FOUND", "Content not found", 404);
|
|
133
|
+
if (collectionRow.comments_closed_after_days > 0) {
|
|
134
|
+
const publishedAt = contentRow.published_at;
|
|
135
|
+
if (publishedAt) {
|
|
136
|
+
const closedDate = new Date(publishedAt);
|
|
137
|
+
closedDate.setDate(closedDate.getDate() + collectionRow.comments_closed_after_days);
|
|
138
|
+
if (/* @__PURE__ */ new Date() > closedDate) return apiError("COMMENTS_CLOSED", "Comments are closed for this content", 403);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (body.website_url) return apiSuccess({
|
|
142
|
+
status: "pending",
|
|
143
|
+
message: "Comment submitted for review"
|
|
144
|
+
});
|
|
145
|
+
const meta = extractRequestMeta(request, runtime.config);
|
|
146
|
+
const { getTurnstileSecretKey, verifyTurnstileToken } = await import("./turnstile-CJwvsOqw.mjs");
|
|
147
|
+
const turnstileSecretKey = getTurnstileSecretKey();
|
|
148
|
+
if (turnstileSecretKey && !await verifyTurnstileToken(body.turnstileToken, turnstileSecretKey, meta.ip)) return apiError("TURNSTILE_FAILED", "CAPTCHA verification failed", 403);
|
|
149
|
+
const { ipSalt } = await resolveSecretsCached(runtime.db);
|
|
150
|
+
const ipHash = meta.ip ? await hashIp(meta.ip, ipSalt) : "unknown";
|
|
151
|
+
if (!(await checkRateLimit(runtime.db, ipHash, "comments/submit", ipHash === "unknown" ? 20 : 5, 600)).allowed) {
|
|
152
|
+
const response = apiError("RATE_LIMITED", "Too many comments. Please try again later.", 429);
|
|
153
|
+
response.headers.set("Retry-After", "600");
|
|
154
|
+
return response;
|
|
155
|
+
}
|
|
156
|
+
const settings = {
|
|
157
|
+
commentsEnabled: true,
|
|
158
|
+
commentsModeration: parseCommentModeration(collectionRow.comments_moderation),
|
|
159
|
+
commentsClosedAfterDays: collectionRow.comments_closed_after_days,
|
|
160
|
+
commentsAutoApproveUsers: collectionRow.comments_auto_approve_users === 1
|
|
161
|
+
};
|
|
162
|
+
const authorName = user?.name || body.authorName;
|
|
163
|
+
const authorEmail = user?.email ?? body.authorEmail;
|
|
164
|
+
let resolvedParentId = body.parentId ?? null;
|
|
165
|
+
if (body.parentId) {
|
|
166
|
+
const parent = await new CommentRepository(runtime.db).findById(body.parentId);
|
|
167
|
+
if (!parent) return apiError("VALIDATION_ERROR", "Parent comment not found", 400);
|
|
168
|
+
if (parent.collection !== collection || parent.contentId !== contentId) return apiError("VALIDATION_ERROR", "Parent comment belongs to different content", 400);
|
|
169
|
+
resolvedParentId = parent.parentId ?? parent.id;
|
|
170
|
+
}
|
|
171
|
+
let contentAuthor;
|
|
172
|
+
if (contentRow.author_id) {
|
|
173
|
+
const authorRow = await runtime.db.selectFrom("users").select([
|
|
174
|
+
"id",
|
|
175
|
+
"name",
|
|
176
|
+
"email",
|
|
177
|
+
"email_verified"
|
|
178
|
+
]).where("id", "=", contentRow.author_id).executeTakeFirst();
|
|
179
|
+
if (authorRow?.email_verified) contentAuthor = {
|
|
180
|
+
id: authorRow.id,
|
|
181
|
+
name: authorRow.name,
|
|
182
|
+
email: authorRow.email
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const result = await createComment(runtime.db, {
|
|
186
|
+
collection,
|
|
187
|
+
contentId,
|
|
188
|
+
parentId: resolvedParentId,
|
|
189
|
+
authorName,
|
|
190
|
+
authorEmail,
|
|
191
|
+
authorUserId: user?.id ?? null,
|
|
192
|
+
body: body.body,
|
|
193
|
+
ipHash,
|
|
194
|
+
userAgent: meta.userAgent
|
|
195
|
+
}, settings, {
|
|
196
|
+
runBeforeCreate: (event) => runtime.hooks.runCommentBeforeCreate(event),
|
|
197
|
+
runModerate: async (event) => {
|
|
198
|
+
const result = await runtime.hooks.invokeExclusiveHook("comment:moderate", event);
|
|
199
|
+
if (!result) return {
|
|
200
|
+
status: "pending",
|
|
201
|
+
reason: "No moderator configured"
|
|
202
|
+
};
|
|
203
|
+
if (result.error) {
|
|
204
|
+
console.error(`[comments] Moderation error (${result.pluginId}):`, result.error.message);
|
|
205
|
+
return {
|
|
206
|
+
status: "pending",
|
|
207
|
+
reason: "Moderation error"
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return isModerationDecision(result.result) ? result.result : {
|
|
211
|
+
status: "pending",
|
|
212
|
+
reason: "Invalid moderation result"
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
fireAfterCreate: (event) => {
|
|
216
|
+
after(() => runtime.hooks.runCommentAfterCreate(event).catch((error) => console.error("[comments] afterCreate error:", error instanceof Error ? error.message : error)));
|
|
217
|
+
},
|
|
218
|
+
fireAfterModerate: (event) => {
|
|
219
|
+
return runtime.hooks.runCommentAfterModerate(event).catch((error) => console.error("[comments] afterModerate error:", error instanceof Error ? error.message : error));
|
|
220
|
+
}
|
|
221
|
+
}, {
|
|
222
|
+
id: contentRow.id,
|
|
223
|
+
collection,
|
|
224
|
+
slug: contentRow.slug,
|
|
225
|
+
author: contentAuthor
|
|
226
|
+
});
|
|
227
|
+
if (!result) return apiError("COMMENT_REJECTED", "Comment was rejected", 403);
|
|
228
|
+
if (result.comment.status === "approved" && runtime.email && contentAuthor) try {
|
|
229
|
+
const adminBaseUrl = await getSiteBaseUrl(runtime.db, request, runtime.config);
|
|
230
|
+
await sendCommentNotification({
|
|
231
|
+
email: runtime.email,
|
|
232
|
+
comment: result.comment,
|
|
233
|
+
contentAuthor,
|
|
234
|
+
adminBaseUrl
|
|
235
|
+
});
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error("[comments] notification error:", error instanceof Error ? error.message : error);
|
|
238
|
+
}
|
|
239
|
+
return apiSuccess({
|
|
240
|
+
id: result.comment.id,
|
|
241
|
+
status: result.comment.status,
|
|
242
|
+
message: result.comment.status === "approved" ? "Comment published" : "Comment submitted for review"
|
|
243
|
+
}, 201);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return handleError(error, "Failed to submit comment", "COMMENT_CREATE_ERROR");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
//#endregion
|
|
250
|
+
export { lookupContentAuthor as n, sendCommentNotification as r, submitPublicComment as t };
|
|
251
|
+
//# sourceMappingURL=public-submission-Di3TsgzX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-submission-Di3TsgzX.mjs","names":[],"sources":["../src/comments/notifications.ts","../src/comments/public-submission.ts"],"sourcesContent":["/**\n * Comment Notification Emails\n *\n * Sends email notifications to content authors when comments are\n * approved on their content. Used by:\n * - Public comment POST route (comment:afterCreate, if auto-approved)\n * - Admin moderation route (comment:afterModerate, when approving)\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { escapeHtml } from \"../api/escape.js\";\nimport type { Database } from \"../database/types.js\";\nimport { validateIdentifier } from \"../database/validate.js\";\nimport type { EmailPipeline } from \"../plugins/email.js\";\nimport type { EmailMessage } from \"../plugins/types.js\";\n\nconst NOTIFICATION_SOURCE = \"emdash-comments\";\nconst MAX_EXCERPT_LENGTH = 500;\nconst CRLF_RE = /[\\r\\n]/g;\n\nexport interface CommentNotificationData {\n\tcommentAuthorName: string;\n\tcommentBody: string;\n\tcontentTitle: string;\n\tcollection: string;\n\tadminBaseUrl: string;\n}\n\n/**\n * Build an email notification for a new comment.\n */\nexport function buildCommentNotificationEmail(\n\tto: string,\n\tdata: CommentNotificationData,\n): EmailMessage {\n\tconst title = data.contentTitle || `${data.collection} item`;\n\tconst subject = `New comment on \"${title}\"`.replace(CRLF_RE, \" \");\n\n\tconst excerpt =\n\t\tdata.commentBody.length > MAX_EXCERPT_LENGTH\n\t\t\t? data.commentBody.slice(0, MAX_EXCERPT_LENGTH) + \"...\"\n\t\t\t: data.commentBody;\n\n\tconst adminUrl = `${data.adminBaseUrl}/admin/comments`;\n\n\tconst text = [\n\t\t`${data.commentAuthorName} commented on \"${title}\":`,\n\t\t\"\",\n\t\texcerpt,\n\t\t\"\",\n\t\t`View in admin: ${adminUrl}`,\n\t].join(\"\\n\");\n\n\tconst html = [\n\t\t`<p><strong>${escapeHtml(data.commentAuthorName)}</strong> commented on “${escapeHtml(title)}”:</p>`,\n\t\t`<blockquote style=\"border-left:3px solid #ccc;padding-left:12px;margin:12px 0;color:#555\">${escapeHtml(excerpt)}</blockquote>`,\n\t\t`<p><a href=\"${escapeHtml(adminUrl)}\">View in admin</a></p>`,\n\t].join(\"\\n\");\n\n\treturn { to, subject, text, html };\n}\n\n/**\n * Send a comment notification to the content author if all conditions are met:\n * 1. Comment status is \"approved\"\n * 2. Content author exists and has an email\n * 3. Email provider is configured\n * 4. Commenter is not the content author (no self-notifications)\n *\n * Returns true if the email was sent, false if skipped.\n */\nexport async function sendCommentNotification(params: {\n\temail: EmailPipeline;\n\tcomment: {\n\t\tauthorName: string;\n\t\tauthorEmail: string;\n\t\tbody: string;\n\t\tstatus: string;\n\t\tcollection: string;\n\t};\n\tcontentTitle?: string;\n\tcontentAuthor?: { email: string; name: string | null };\n\tadminBaseUrl: string;\n}): Promise<boolean> {\n\tconst { email, comment, contentAuthor, adminBaseUrl } = params;\n\n\tif (comment.status !== \"approved\") return false;\n\tif (!contentAuthor?.email) return false;\n\tif (!email.isAvailable()) return false;\n\tif (comment.authorEmail.toLowerCase() === contentAuthor.email.toLowerCase()) return false;\n\n\tconst message = buildCommentNotificationEmail(contentAuthor.email, {\n\t\tcommentAuthorName: comment.authorName,\n\t\tcommentBody: comment.body,\n\t\tcontentTitle: params.contentTitle || \"\",\n\t\tcollection: comment.collection,\n\t\tadminBaseUrl,\n\t});\n\n\tawait email.send(message, NOTIFICATION_SOURCE);\n\treturn true;\n}\n\n/**\n * Look up a content item's author from the database.\n *\n * Used by the admin moderation route where content info isn't\n * readily available (only the comment record is at hand).\n */\nexport async function lookupContentAuthor(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tcontentId: string,\n): Promise<{\n\tslug: string;\n\tauthor?: { id: string; email: string; name: string | null };\n} | null> {\n\tvalidateIdentifier(collection, \"collection\");\n\n\tconst contentRow = await db\n\t\t.selectFrom(`ec_${collection}` as never)\n\t\t.select([\"slug\" as never, \"author_id\" as never])\n\t\t.where(\"id\" as never, \"=\", contentId as never)\n\t\t.executeTakeFirst();\n\n\tif (!contentRow) return null;\n\n\tconst typed = contentRow as { slug: string; author_id: string | null };\n\n\tlet author: { id: string; email: string; name: string | null } | undefined;\n\tif (typed.author_id) {\n\t\tconst userRow = await db\n\t\t\t.selectFrom(\"users\")\n\t\t\t.select([\"id\", \"name\", \"email\", \"email_verified\"])\n\t\t\t.where(\"id\", \"=\", typed.author_id)\n\t\t\t.executeTakeFirst();\n\t\tif (userRow && userRow.email_verified) {\n\t\t\tauthor = { id: userRow.id, email: userRow.email, name: userRow.name };\n\t\t}\n\t}\n\n\treturn { slug: typed.slug, author };\n}\n","import { sql, type Kysely } from \"kysely\";\n\nimport { after } from \"../after.js\";\nimport { apiError, apiSuccess, handleError } from \"../api/error.js\";\nimport { hashIp } from \"../api/handlers/comments.js\";\nimport { isParseError, parseBody } from \"../api/parse.js\";\nimport { createCommentBody } from \"../api/schemas/comments.js\";\nimport { getSiteBaseUrl } from \"../api/site-url.js\";\nimport type { EmDashConfig } from \"../astro/integration/runtime.js\";\nimport { checkRateLimit } from \"../auth/rate-limit.js\";\nimport { resolveSecretsCached } from \"../config/secrets.js\";\nimport { CommentRepository } from \"../database/repositories/comment.js\";\nimport type { Database } from \"../database/types.js\";\nimport { validateIdentifier } from \"../database/validate.js\";\nimport type { EmailPipeline } from \"../plugins/email.js\";\nimport type { HookPipeline } from \"../plugins/hooks.js\";\nimport { extractRequestMeta } from \"../plugins/request-meta.js\";\nimport type { CollectionCommentSettings, ModerationDecision, UserInfo } from \"../plugins/types.js\";\nimport { sendCommentNotification } from \"./notifications.js\";\nimport { createComment, type CommentHookRunner } from \"./service.js\";\n\nexport interface PublicCommentSubmissionRuntime {\n\tdb: Kysely<Database>;\n\tconfig: EmDashConfig;\n\temail: EmailPipeline | null;\n\thooks: HookPipeline;\n}\n\ninterface CommentableContentRow {\n\tid: string;\n\tslug: string;\n\tauthor_id: string | null;\n\tpublished_at: string | null;\n}\n\nfunction parseCommentModeration(value: string): CollectionCommentSettings[\"commentsModeration\"] {\n\tif (value === \"all\" || value === \"first_time\" || value === \"none\") return value;\n\treturn \"all\";\n}\n\nfunction isModerationDecision(value: unknown): value is ModerationDecision {\n\tif (typeof value !== \"object\" || value === null || !(\"status\" in value)) return false;\n\tif (value.status !== \"pending\" && value.status !== \"approved\" && value.status !== \"spam\") {\n\t\treturn false;\n\t}\n\treturn !(\"reason\" in value) || value.reason === undefined || typeof value.reason === \"string\";\n}\n\nexport async function submitPublicComment(\n\truntime: PublicCommentSubmissionRuntime,\n\tcollection: string,\n\tcontentId: string,\n\trequest: Request,\n\tuser?: UserInfo,\n): Promise<Response> {\n\ttry {\n\t\tconst body = await parseBody(request, createCommentBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst collectionRow = await runtime.db\n\t\t\t.selectFrom(\"_emdash_collections\")\n\t\t\t.select([\n\t\t\t\t\"comments_enabled\",\n\t\t\t\t\"comments_moderation\",\n\t\t\t\t\"comments_closed_after_days\",\n\t\t\t\t\"comments_auto_approve_users\",\n\t\t\t])\n\t\t\t.where(\"slug\", \"=\", collection)\n\t\t\t.executeTakeFirst();\n\n\t\tif (!collectionRow) {\n\t\t\treturn apiError(\"NOT_FOUND\", `Collection '${collection}' not found`, 404);\n\t\t}\n\t\tif (!collectionRow.comments_enabled) {\n\t\t\treturn apiError(\"COMMENTS_DISABLED\", \"Comments are not enabled for this collection\", 403);\n\t\t}\n\n\t\tvalidateIdentifier(collection, \"collection\");\n\t\tconst contentResult = await sql<CommentableContentRow>`\n\t\t\tSELECT id, slug, author_id, published_at\n\t\t\tFROM ${sql.ref(`ec_${collection}`)}\n\t\t\tWHERE id = ${contentId}\n\t\t\tAND status = 'published'\n\t\t\tAND deleted_at IS NULL\n\t\t`.execute(runtime.db);\n\t\tconst contentRow = contentResult.rows[0];\n\n\t\tif (!contentRow) return apiError(\"NOT_FOUND\", \"Content not found\", 404);\n\n\t\tif (collectionRow.comments_closed_after_days > 0) {\n\t\t\tconst publishedAt = contentRow.published_at;\n\t\t\tif (publishedAt) {\n\t\t\t\tconst closedDate = new Date(publishedAt);\n\t\t\t\tclosedDate.setDate(closedDate.getDate() + collectionRow.comments_closed_after_days);\n\t\t\t\tif (new Date() > closedDate) {\n\t\t\t\t\treturn apiError(\"COMMENTS_CLOSED\", \"Comments are closed for this content\", 403);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (body.website_url) {\n\t\t\treturn apiSuccess({ status: \"pending\", message: \"Comment submitted for review\" });\n\t\t}\n\n\t\tconst meta = extractRequestMeta(request, runtime.config);\n\n\t\tconst { getTurnstileSecretKey, verifyTurnstileToken } = await import(\"./turnstile.js\");\n\t\tconst turnstileSecretKey = getTurnstileSecretKey();\n\t\tif (\n\t\t\tturnstileSecretKey &&\n\t\t\t!(await verifyTurnstileToken(body.turnstileToken, turnstileSecretKey, meta.ip))\n\t\t) {\n\t\t\treturn apiError(\"TURNSTILE_FAILED\", \"CAPTCHA verification failed\", 403);\n\t\t}\n\n\t\t// Counted after the CAPTCHA so unverified requests can't use up the\n\t\t// shared bucket for visitors without a trusted IP.\n\t\tconst { ipSalt } = await resolveSecretsCached(runtime.db);\n\t\tconst ipHash = meta.ip ? await hashIp(meta.ip, ipSalt) : \"unknown\";\n\t\tconst rateLimit = await checkRateLimit(\n\t\t\truntime.db,\n\t\t\tipHash,\n\t\t\t\"comments/submit\",\n\t\t\tipHash === \"unknown\" ? 20 : 5,\n\t\t\t600,\n\t\t);\n\t\tif (!rateLimit.allowed) {\n\t\t\tconst response = apiError(\"RATE_LIMITED\", \"Too many comments. Please try again later.\", 429);\n\t\t\tresponse.headers.set(\"Retry-After\", \"600\");\n\t\t\treturn response;\n\t\t}\n\n\t\tconst settings: CollectionCommentSettings = {\n\t\t\tcommentsEnabled: true,\n\t\t\tcommentsModeration: parseCommentModeration(collectionRow.comments_moderation),\n\t\t\tcommentsClosedAfterDays: collectionRow.comments_closed_after_days,\n\t\t\tcommentsAutoApproveUsers: collectionRow.comments_auto_approve_users === 1,\n\t\t};\n\n\t\tconst authorName = user?.name || body.authorName;\n\t\tconst authorEmail = user?.email ?? body.authorEmail;\n\t\tlet resolvedParentId = body.parentId ?? null;\n\t\tif (body.parentId) {\n\t\t\tconst parent = await new CommentRepository(runtime.db).findById(body.parentId);\n\t\t\tif (!parent) return apiError(\"VALIDATION_ERROR\", \"Parent comment not found\", 400);\n\t\t\tif (parent.collection !== collection || parent.contentId !== contentId) {\n\t\t\t\treturn apiError(\"VALIDATION_ERROR\", \"Parent comment belongs to different content\", 400);\n\t\t\t}\n\t\t\tresolvedParentId = parent.parentId ?? parent.id;\n\t\t}\n\n\t\tlet contentAuthor: { id: string; name: string | null; email: string } | undefined;\n\t\tif (contentRow.author_id) {\n\t\t\tconst authorRow = await runtime.db\n\t\t\t\t.selectFrom(\"users\")\n\t\t\t\t.select([\"id\", \"name\", \"email\", \"email_verified\"])\n\t\t\t\t.where(\"id\", \"=\", contentRow.author_id)\n\t\t\t\t.executeTakeFirst();\n\t\t\tif (authorRow?.email_verified) {\n\t\t\t\tcontentAuthor = { id: authorRow.id, name: authorRow.name, email: authorRow.email };\n\t\t\t}\n\t\t}\n\n\t\tconst hookRunner: CommentHookRunner = {\n\t\t\trunBeforeCreate: (event) => runtime.hooks.runCommentBeforeCreate(event),\n\t\t\trunModerate: async (event) => {\n\t\t\t\tconst result = await runtime.hooks.invokeExclusiveHook(\"comment:moderate\", event);\n\t\t\t\tif (!result) return { status: \"pending\", reason: \"No moderator configured\" };\n\t\t\t\tif (result.error) {\n\t\t\t\t\tconsole.error(`[comments] Moderation error (${result.pluginId}):`, result.error.message);\n\t\t\t\t\treturn { status: \"pending\", reason: \"Moderation error\" };\n\t\t\t\t}\n\t\t\t\treturn isModerationDecision(result.result)\n\t\t\t\t\t? result.result\n\t\t\t\t\t: { status: \"pending\", reason: \"Invalid moderation result\" };\n\t\t\t},\n\t\t\tfireAfterCreate: (event) => {\n\t\t\t\t// Deferred through after() so the host's waitUntil keeps the hooks\n\t\t\t\t// alive: on Workers, work left running after the response is sent\n\t\t\t\t// can be cancelled (sandboxed plugins never got past their first\n\t\t\t\t// bridge call).\n\t\t\t\tafter(() =>\n\t\t\t\t\truntime.hooks\n\t\t\t\t\t\t.runCommentAfterCreate(event)\n\t\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\"[comments] afterCreate error:\",\n\t\t\t\t\t\t\t\terror instanceof Error ? error.message : error,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t\tfireAfterModerate: (event) => {\n\t\t\t\treturn runtime.hooks\n\t\t\t\t\t.runCommentAfterModerate(event)\n\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"[comments] afterModerate error:\",\n\t\t\t\t\t\t\terror instanceof Error ? error.message : error,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\tconst result = await createComment(\n\t\t\truntime.db,\n\t\t\t{\n\t\t\t\tcollection,\n\t\t\t\tcontentId,\n\t\t\t\tparentId: resolvedParentId,\n\t\t\t\tauthorName,\n\t\t\t\tauthorEmail,\n\t\t\t\tauthorUserId: user?.id ?? null,\n\t\t\t\tbody: body.body,\n\t\t\t\tipHash,\n\t\t\t\tuserAgent: meta.userAgent,\n\t\t\t},\n\t\t\tsettings,\n\t\t\thookRunner,\n\t\t\t{\n\t\t\t\tid: contentRow.id,\n\t\t\t\tcollection,\n\t\t\t\tslug: contentRow.slug,\n\t\t\t\tauthor: contentAuthor,\n\t\t\t},\n\t\t);\n\n\t\tif (!result) return apiError(\"COMMENT_REJECTED\", \"Comment was rejected\", 403);\n\n\t\tif (result.comment.status === \"approved\" && runtime.email && contentAuthor) {\n\t\t\ttry {\n\t\t\t\tconst adminBaseUrl = await getSiteBaseUrl(runtime.db, request, runtime.config);\n\t\t\t\tawait sendCommentNotification({\n\t\t\t\t\temail: runtime.email,\n\t\t\t\t\tcomment: result.comment,\n\t\t\t\t\tcontentAuthor,\n\t\t\t\t\tadminBaseUrl,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"[comments] notification error:\",\n\t\t\t\t\terror instanceof Error ? error.message : error,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn apiSuccess(\n\t\t\t{\n\t\t\t\tid: result.comment.id,\n\t\t\t\tstatus: result.comment.status,\n\t\t\t\tmessage:\n\t\t\t\t\tresult.comment.status === \"approved\"\n\t\t\t\t\t\t? \"Comment published\"\n\t\t\t\t\t\t: \"Comment submitted for review\",\n\t\t\t},\n\t\t\t201,\n\t\t);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to submit comment\", \"COMMENT_CREATE_ERROR\");\n\t}\n}\n"],"mappings":"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"}
|