emdash 1.3.1 → 1.4.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-CGlyigmg.mjs +387 -0
- package/dist/activation-CGlyigmg.mjs.map +1 -0
- package/dist/adapters-D9a1PfqH.d.mts +173 -0
- package/dist/adapters-D9a1PfqH.d.mts.map +1 -0
- package/dist/after-32yNRvd2.mjs +99 -0
- package/dist/after-32yNRvd2.mjs.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 +52 -53
- 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--PYoyeTo.mjs +5098 -0
- package/dist/api--PYoyeTo.mjs.map +1 -0
- package/dist/api-tokens-DqSlkDVI.mjs +9 -0
- package/dist/api-tokens-DqSlkDVI.mjs.map +1 -0
- package/dist/api-tokens-GNCsIegW.mjs +173 -0
- package/dist/api-tokens-GNCsIegW.mjs.map +1 -0
- package/dist/apply-DVnupNeS.mjs +1760 -0
- package/dist/apply-DVnupNeS.mjs.map +1 -0
- package/dist/approvals-DTtYSB27.mjs +460 -0
- package/dist/approvals-DTtYSB27.mjs.map +1 -0
- package/dist/artifact-fetch-DIh7iyOV.mjs +659 -0
- package/dist/artifact-fetch-DIh7iyOV.mjs.map +1 -0
- package/dist/artifacts-Dvdp2KK-.mjs +323 -0
- package/dist/artifacts-Dvdp2KK-.mjs.map +1 -0
- package/dist/astro/index.d.mts +14 -13
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +52 -12
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +12 -11
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +13 -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.mjs +17 -17
- package/dist/astro/middleware/request-context.mjs +12 -7
- 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 -11
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +116 -116
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +13 -13
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +13 -13
- 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 +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +15 -15
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +15 -15
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +15 -15
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +23 -24
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +23 -24
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +23 -24
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -19
- package/dist/astro/routes/api/admin/comments/_id_.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/counts.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/index.mjs +18 -18
- package/dist/astro/routes/api/admin/core-update.mjs +7 -7
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
- 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 +24 -24
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +30 -30
- 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 +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- 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 +74 -75
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +73 -74
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +73 -74
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +84 -85
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +74 -75
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +73 -74
- 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 +83 -84
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +73 -74
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +73 -74
- 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 +85 -86
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +8 -8
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +75 -76
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +74 -75
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +73 -74
- 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 +73 -74
- 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 +6 -6
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +73 -74
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/_...path_.mjs +3 -3
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +40 -41
- 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 +40 -41
- package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +42 -43
- package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs +42 -43
- package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +42 -43
- 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 +43 -44
- 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 +43 -44
- 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 +42 -43
- 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 +43 -44
- package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs +44 -45
- package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +42 -43
- 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 +42 -43
- 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 +44 -45
- 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 +42 -43
- 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 +44 -45
- 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 +42 -43
- 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 +42 -43
- 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 +44 -45
- 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 +42 -43
- 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 +42 -43
- package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -1
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs +44 -45
- package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +13 -13
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
- package/dist/astro/routes/api/admin/users/index.mjs +13 -13
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
- package/dist/astro/routes/api/auth/handover.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/complete.mjs +19 -19
- package/dist/astro/routes/api/auth/invite/index.mjs +15 -15
- package/dist/astro/routes/api/auth/invite/register-options.mjs +16 -16
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- 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 +14 -14
- package/dist/astro/routes/api/auth/mode.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +9 -9
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +13 -13
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +19 -19
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +16 -16
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +17 -17
- 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 +3 -3
- package/dist/astro/routes/api/calendar.mjs +14 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +20 -20
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +17 -17
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +10 -10
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +33 -33
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +35 -35
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +35 -35
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +26 -26
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +14 -14
- package/dist/astro/routes/api/content/_collection_/trash.mjs +14 -14
- package/dist/astro/routes/api/dashboard.mjs +11 -11
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/dev/scheduled-tasks.mjs +112 -112
- package/dist/astro/routes/api/health.mjs +5 -5
- package/dist/astro/routes/api/import/probe.d.mts +3 -2
- package/dist/astro/routes/api/import/probe.d.mts.map +1 -1
- package/dist/astro/routes/api/import/probe.mjs +28 -28
- package/dist/astro/routes/api/import/wordpress/analyze.d.mts +4 -3
- package/dist/astro/routes/api/import/wordpress/analyze.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +6 -28
- package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +12 -11
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +26 -27
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -11
- package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +19 -19
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -12
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +29 -29
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +28 -28
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +12 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +38 -39
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.mjs +96 -97
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -19
- 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 +32 -32
- package/dist/astro/routes/api/media/_id_.mjs +30 -30
- package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +5 -5
- package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +57 -11
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/folders/_id_.mjs +15 -15
- package/dist/astro/routes/api/media/folders/index.mjs +15 -15
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +17 -17
- package/dist/astro/routes/api/media.mjs +34 -34
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +20 -19
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +20 -19
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +20 -19
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +20 -19
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +20 -19
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +20 -19
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +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 +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/token.mjs.map +1 -1
- package/dist/astro/routes/api/openapi.json.mjs +20 -20
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +10 -10
- package/dist/astro/routes/api/redirects/404s/index.mjs +21 -21
- package/dist/astro/routes/api/redirects/404s/summary.mjs +21 -21
- package/dist/astro/routes/api/redirects/_id_.mjs +22 -22
- package/dist/astro/routes/api/redirects/index.mjs +22 -22
- package/dist/astro/routes/api/relations/_id_/index.mjs +35 -35
- package/dist/astro/routes/api/relations/index.mjs +35 -35
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +17 -17
- package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +73 -74
- 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 +73 -74
- 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 +73 -74
- package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +73 -74
- 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 +73 -74
- 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 +73 -74
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +73 -74
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +73 -74
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +73 -74
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +17 -17
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +73 -74
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +73 -74
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +20 -19
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +19 -18
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +20 -19
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +10 -9
- package/dist/astro/routes/api/search/stats.mjs.map +1 -1
- package/dist/astro/routes/api/search/suggest.mjs +19 -18
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +19 -18
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +19 -18
- 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.mjs +21 -21
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +27 -27
- package/dist/astro/routes/api/setup/admin-verify.mjs +22 -22
- package/dist/astro/routes/api/setup/admin.mjs +17 -17
- package/dist/astro/routes/api/setup/dev-bypass.mjs +45 -46
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +51 -52
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/site/domain-proof.mjs +15 -15
- package/dist/astro/routes/api/snapshot.mjs +10 -10
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +25 -25
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +25 -25
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -25
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +25 -25
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +23 -23
- package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -25
- package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +36 -36
- package/dist/astro/routes/api/taxonomies/index.mjs +25 -25
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/visual-editing/action-token.mjs +7 -7
- package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +21 -21
- package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +3 -3
- 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 +28 -17
- 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 +24 -20
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +23 -20
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +13 -10
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +23 -20
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +14 -14
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +17 -17
- package/dist/astro/routes/sitemap.xml.mjs +15 -15
- package/dist/astro/types.d.mts +21 -19
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/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-NJgp8kLI.mjs +74 -0
- package/dist/authorize-NJgp8kLI.mjs.map +1 -0
- package/dist/backup-8rPSJ28a.mjs +246 -0
- package/dist/backup-8rPSJ28a.mjs.map +1 -0
- package/dist/block-types-BbOrfnWs.mjs +132 -0
- package/dist/block-types-BbOrfnWs.mjs.map +1 -0
- package/dist/block-values-Dg0-8PPS.mjs +215 -0
- package/dist/block-values-Dg0-8PPS.mjs.map +1 -0
- package/dist/byline-DHJS-GGb.mjs +994 -0
- package/dist/byline-DHJS-GGb.mjs.map +1 -0
- package/dist/byline-fields-CiR8FvvF.mjs +280 -0
- package/dist/byline-fields-CiR8FvvF.mjs.map +1 -0
- package/dist/byline-fields-D6KYsEa7.mjs +123 -0
- package/dist/byline-fields-D6KYsEa7.mjs.map +1 -0
- package/dist/bylines-Bsg5cH4S.mjs +234 -0
- package/dist/bylines-Bsg5cH4S.mjs.map +1 -0
- package/dist/bylines-f_ZEc6Sn.mjs +150 -0
- package/dist/bylines-f_ZEc6Sn.mjs.map +1 -0
- package/dist/cache-5DHbpEWu.mjs +151 -0
- package/dist/cache-5DHbpEWu.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-BezAvWcB.mjs +362 -0
- package/dist/capture-triggers-BezAvWcB.mjs.map +1 -0
- package/dist/challenge-store-B1C0V4b3.mjs +51 -0
- package/dist/challenge-store-B1C0V4b3.mjs.map +1 -0
- package/dist/checksum-CEqvfxGX.mjs +162 -0
- package/dist/checksum-CEqvfxGX.mjs.map +1 -0
- package/dist/chrome-tags-BIKBMZYO.mjs +24 -0
- package/dist/chrome-tags-BIKBMZYO.mjs.map +1 -0
- package/dist/chunks-DiW8VMwz.mjs +25 -0
- package/dist/chunks-DiW8VMwz.mjs.map +1 -0
- package/dist/cli/index.mjs +52 -53
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +46 -46
- package/dist/client/index.mjs +2 -2
- package/dist/collection-slugs-cache-DIrLjqH-.mjs +91 -0
- package/dist/collection-slugs-cache-DIrLjqH-.mjs.map +1 -0
- package/dist/comment-DB74Zpa4.mjs +335 -0
- package/dist/comment-DB74Zpa4.mjs.map +1 -0
- package/dist/comment-reaction-BScxIWUn.mjs +85 -0
- package/dist/comment-reaction-BScxIWUn.mjs.map +1 -0
- package/dist/comments-Cor_zKml.mjs +195 -0
- package/dist/comments-Cor_zKml.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-D44_8G9J.d.mts +41 -0
- package/dist/config-D44_8G9J.d.mts.map +1 -0
- package/dist/config-DBU6iUQB.mjs +228 -0
- package/dist/config-DBU6iUQB.mjs.map +1 -0
- package/dist/config-sDhZvkLR.d.mts +6835 -0
- package/dist/config-sDhZvkLR.d.mts.map +1 -0
- package/dist/connection-BtEN_lP9.mjs +36 -0
- package/dist/connection-BtEN_lP9.mjs.map +1 -0
- package/dist/content-BKHUVsE5.mjs +2112 -0
- package/dist/content-BKHUVsE5.mjs.map +1 -0
- package/dist/content-list-query-ByP4jRpZ.d.mts +26 -0
- package/dist/content-list-query-ByP4jRpZ.d.mts.map +1 -0
- package/dist/content-policy-BmE0MPZY.mjs +46 -0
- package/dist/content-policy-BmE0MPZY.mjs.map +1 -0
- package/dist/content-repair-Ukdxoq-R.mjs +442 -0
- package/dist/content-repair-Ukdxoq-R.mjs.map +1 -0
- package/dist/context-CzjejcsE.mjs +2089 -0
- package/dist/context-CzjejcsE.mjs.map +1 -0
- package/dist/credits-BKREepht.mjs +110 -0
- package/dist/credits-BKREepht.mjs.map +1 -0
- package/dist/cron-D7obTIfk.mjs +306 -0
- package/dist/cron-D7obTIfk.mjs.map +1 -0
- package/dist/dashboard-ynr1qJWM.mjs +168 -0
- package/dist/dashboard-ynr1qJWM.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +5 -5
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +5 -5
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite-migrations.d.mts +1 -1
- package/dist/db/sqlite-migrations.mjs +5 -5
- 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-wlMFJL95.d.mts +10 -0
- package/dist/deferred-tasks-wlMFJL95.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-D1U392GC.mjs +519 -0
- package/dist/device-flow-D1U392GC.mjs.map +1 -0
- package/dist/dialect-helpers-B1XN2HGB.mjs +314 -0
- package/dist/dialect-helpers-B1XN2HGB.mjs.map +1 -0
- package/dist/digest-DJ1tHCgy.mjs +194 -0
- package/dist/digest-DJ1tHCgy.mjs.map +1 -0
- package/dist/direct-executor-Bs2g0ake.mjs +117 -0
- package/dist/direct-executor-Bs2g0ake.mjs.map +1 -0
- package/dist/dist-BUmWMTbN.mjs +810 -0
- package/dist/dist-BUmWMTbN.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-Bs3HFdnq.mjs +25 -0
- package/dist/email-locale-Bs3HFdnq.mjs.map +1 -0
- package/dist/emdash-runtime-C8T-pZpS.mjs +4425 -0
- package/dist/emdash-runtime-C8T-pZpS.mjs.map +1 -0
- package/dist/enrich-DFlfnd3u.mjs +194 -0
- package/dist/enrich-DFlfnd3u.mjs.map +1 -0
- package/dist/entry-lock-BulbgPBX.d.mts +4568 -0
- package/dist/entry-lock-BulbgPBX.d.mts.map +1 -0
- package/dist/entry-lock-CRVmruM0.mjs +1211 -0
- package/dist/entry-lock-CRVmruM0.mjs.map +1 -0
- package/dist/entry-lock-D-zJQ4q6.mjs +163 -0
- package/dist/entry-lock-D-zJQ4q6.mjs.map +1 -0
- package/dist/entry-locks-CJ9uhqg1.mjs +167 -0
- package/dist/entry-locks-CJ9uhqg1.mjs.map +1 -0
- package/dist/env-types-BE3bCvfP.mjs +38 -0
- package/dist/env-types-BE3bCvfP.mjs.map +1 -0
- package/dist/error-BCMgPxdn.mjs +90 -0
- package/dist/error-BCMgPxdn.mjs.map +1 -0
- package/dist/errors-8gJqv-XV.mjs +492 -0
- package/dist/errors-8gJqv-XV.mjs.map +1 -0
- package/dist/errors-B4f4It-2.mjs +120 -0
- package/dist/errors-B4f4It-2.mjs.map +1 -0
- package/dist/escape-lsNq38PP.mjs +9 -0
- package/dist/escape-lsNq38PP.mjs.map +1 -0
- package/dist/fence-Dagicj14.mjs +162 -0
- package/dist/fence-Dagicj14.mjs.map +1 -0
- package/dist/field-map-BSXdNGt5.mjs +84 -0
- package/dist/field-map-BSXdNGt5.mjs.map +1 -0
- package/dist/fts-manager-6861qcwk.mjs +489 -0
- package/dist/fts-manager-6861qcwk.mjs.map +1 -0
- package/dist/gc-CNkXB3mE.mjs +75 -0
- package/dist/gc-CNkXB3mE.mjs.map +1 -0
- package/dist/hash-BJaeek87.mjs +37 -0
- package/dist/hash-BJaeek87.mjs.map +1 -0
- package/dist/hreflang-8dUOJAPJ.d.mts +50 -0
- package/dist/hreflang-8dUOJAPJ.d.mts.map +1 -0
- package/dist/hreflang-BW5A4FLK.mjs +105 -0
- package/dist/hreflang-BW5A4FLK.mjs.map +1 -0
- package/dist/http-route-dispatch-rXKvTNm9.mjs +342 -0
- package/dist/http-route-dispatch-rXKvTNm9.mjs.map +1 -0
- package/dist/identity-CPRRSovU.mjs +35 -0
- package/dist/identity-CPRRSovU.mjs.map +1 -0
- package/dist/import-yVbfPyfd.mjs +2126 -0
- package/dist/import-yVbfPyfd.mjs.map +1 -0
- package/dist/index-VM7Fzxwe.d.mts +260 -0
- package/dist/index-VM7Fzxwe.d.mts.map +1 -0
- package/dist/index.d.mts +23 -22
- package/dist/index.mjs +104 -105
- package/dist/install-finalization-RU6VrHOX.mjs +58 -0
- package/dist/install-finalization-RU6VrHOX.mjs.map +1 -0
- package/dist/json-recordset-D0WhN2UA.mjs +12 -0
- package/dist/json-recordset-D0WhN2UA.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-B8d7Rdqx.mjs +25 -0
- package/dist/lifecycle-B8d7Rdqx.mjs.map +1 -0
- package/dist/load-D4xtzm6h.mjs +28 -0
- package/dist/load-D4xtzm6h.mjs.map +1 -0
- package/dist/loader-DhnedqY4.mjs +1478 -0
- package/dist/loader-DhnedqY4.mjs.map +1 -0
- package/dist/loops-B2YS-Zzr.mjs +205 -0
- package/dist/loops-B2YS-Zzr.mjs.map +1 -0
- package/dist/manifest-builder-g1FLviel.mjs +196 -0
- package/dist/manifest-builder-g1FLviel.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/image-endpoint.mjs +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +3 -3
- package/dist/media/local-runtime.d.mts +14 -13
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +14 -14
- package/dist/media-BR4_t-Wd.mjs +416 -0
- package/dist/media-BR4_t-Wd.mjs.map +1 -0
- package/dist/media-CikS-q6E.mjs +294 -0
- package/dist/media-CikS-q6E.mjs.map +1 -0
- package/dist/media-DepNLhPq.mjs +383 -0
- package/dist/media-DepNLhPq.mjs.map +1 -0
- package/dist/media-allowlist-BMBLqyWh.mjs +45 -0
- package/dist/media-allowlist-BMBLqyWh.mjs.map +1 -0
- package/dist/media-folders-CI0Wydfo.mjs +210 -0
- package/dist/media-folders-CI0Wydfo.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-X1_20MY-.mjs +282 -0
- package/dist/media-usage-X1_20MY-.mjs.map +1 -0
- package/dist/media-usage-activation-bWusy3M2.mjs +78 -0
- package/dist/media-usage-activation-bWusy3M2.mjs.map +1 -0
- package/dist/media-usage-work-B2RaoJIa.mjs +151 -0
- package/dist/media-usage-work-B2RaoJIa.mjs.map +1 -0
- package/dist/media-usage-work-BCK2J-v_.mjs +1036 -0
- package/dist/media-usage-work-BCK2J-v_.mjs.map +1 -0
- package/dist/menus-B0Qqv_cS.mjs +837 -0
- package/dist/menus-B0Qqv_cS.mjs.map +1 -0
- package/dist/menus-oypxT1pI.mjs +3802 -0
- package/dist/menus-oypxT1pI.mjs.map +1 -0
- package/dist/menus-uEAxWAm1.mjs +92 -0
- package/dist/menus-uEAxWAm1.mjs.map +1 -0
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +4 -4
- package/dist/mime-D1We9jUx.mjs +81 -0
- package/dist/mime-D1We9jUx.mjs.map +1 -0
- 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/normalize-Cx-bNwhP.mjs +220 -0
- package/dist/normalize-Cx-bNwhP.mjs.map +1 -0
- package/dist/oauth-authorization-CPLgBrdo.mjs +287 -0
- package/dist/oauth-authorization-CPLgBrdo.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-BndCfRum.mjs +50 -0
- package/dist/oauth-state-store-BndCfRum.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/object-cache-DmKr09La.mjs +603 -0
- package/dist/object-cache-DmKr09La.mjs.map +1 -0
- package/dist/options-BUUgroHg.d.mts +81 -0
- package/dist/options-BUUgroHg.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 +13 -13
- package/dist/parse-B_b6gZxG.mjs +81 -0
- package/dist/parse-B_b6gZxG.mjs.map +1 -0
- package/dist/parse-Dndx1QmN.d.mts +176 -0
- package/dist/parse-Dndx1QmN.d.mts.map +1 -0
- package/dist/passkey-config-D2Lua5__.mjs +46 -0
- package/dist/passkey-config-D2Lua5__.mjs.map +1 -0
- package/dist/paths-biDzFTY2.mjs +77 -0
- package/dist/paths-biDzFTY2.mjs.map +1 -0
- package/dist/placeholder-CSKu5OkD.d.mts +314 -0
- package/dist/placeholder-CSKu5OkD.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 +16 -14
- package/dist/plugin-test-runtime.d.mts.map +1 -1
- package/dist/plugin-test-runtime.mjs +114 -115
- 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 +1 -1
- package/dist/plugin-utils.d.mts +12 -11
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +12 -11
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +4 -4
- package/dist/plugins/host.d.mts +5 -5
- package/dist/plugins/host.mjs +50 -51
- package/dist/plugins-COJ2L49n.mjs +261 -0
- package/dist/plugins-COJ2L49n.mjs.map +1 -0
- package/dist/policy-BPugqmeV.mjs +53 -0
- package/dist/policy-BPugqmeV.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-PoAfD_9W.d.mts +65 -0
- package/dist/protocol-PoAfD_9W.d.mts.map +1 -0
- package/dist/public-plugin-api-routes-CMljrTby.mjs +316 -0
- package/dist/public-plugin-api-routes-CMljrTby.mjs.map +1 -0
- package/dist/public-submission-ayqoyee4.mjs +251 -0
- package/dist/public-submission-ayqoyee4.mjs.map +1 -0
- package/dist/public-url-Bt98vysr.mjs +101 -0
- package/dist/public-url-Bt98vysr.mjs.map +1 -0
- package/dist/query-D62NntCZ.mjs +1146 -0
- package/dist/query-D62NntCZ.mjs.map +1 -0
- package/dist/query-LmPY2y0C.mjs +41 -0
- package/dist/query-LmPY2y0C.mjs.map +1 -0
- package/dist/range-CYfeXgGK.mjs +51 -0
- package/dist/range-CYfeXgGK.mjs.map +1 -0
- package/dist/rate-limit-C04Llsoc.mjs +127 -0
- package/dist/rate-limit-C04Llsoc.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-DjLdw427.mjs +423 -0
- package/dist/redirect-DjLdw427.mjs.map +1 -0
- package/dist/redirect-paths-DOaVBp6E.mjs +36 -0
- package/dist/redirect-paths-DOaVBp6E.mjs.map +1 -0
- package/dist/redirects-Cpq1catN.mjs +446 -0
- package/dist/redirects-Cpq1catN.mjs.map +1 -0
- package/dist/redirects-CyvvZrCJ.mjs +148 -0
- package/dist/redirects-CyvvZrCJ.mjs.map +1 -0
- package/dist/registry/testing.mjs +3 -3
- package/dist/registry-B0-O575m.mjs +8374 -0
- package/dist/registry-B0-O575m.mjs.map +1 -0
- package/dist/relations-WIOojTL4.mjs +789 -0
- package/dist/relations-WIOojTL4.mjs.map +1 -0
- package/dist/request-context.d.mts +2 -2
- package/dist/request-meta-bwZ_NsvU.mjs +141 -0
- package/dist/request-meta-bwZ_NsvU.mjs.map +1 -0
- package/dist/resolve-BNnm8EkB.mjs +102 -0
- package/dist/resolve-BNnm8EkB.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-avqgc-8r.mjs +272 -0
- package/dist/routes-avqgc-8r.mjs.map +1 -0
- package/dist/runner-Bkkfk4O8.mjs +6669 -0
- package/dist/runner-Bkkfk4O8.mjs.map +1 -0
- package/dist/runner-Dfgp6-S_.d.mts +73 -0
- package/dist/runner-Dfgp6-S_.d.mts.map +1 -0
- package/dist/runtime.d.mts +13 -12
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +4 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema/project-env-types.mjs +42 -43
- package/dist/schema/project-env-types.mjs.map +1 -1
- package/dist/schema-B-3rntlX.mjs +815 -0
- package/dist/schema-B-3rntlX.mjs.map +1 -0
- package/dist/schema-BqBlUZtb.mjs +13 -0
- package/dist/schema-BqBlUZtb.mjs.map +1 -0
- package/dist/scopes-DNaY7Ey0.mjs +34 -0
- package/dist/scopes-DNaY7Ey0.mjs.map +1 -0
- package/dist/search-BPWTnpnD.mjs +450 -0
- package/dist/search-BPWTnpnD.mjs.map +1 -0
- package/dist/secrets-Dswzrz3k.mjs +369 -0
- package/dist/secrets-Dswzrz3k.mjs.map +1 -0
- package/dist/sections-rSao6rBG.mjs +346 -0
- package/dist/sections-rSao6rBG.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +40 -41
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +27 -27
- package/dist/seo-B_H_pqOd.mjs +133 -0
- package/dist/seo-B_H_pqOd.mjs.map +1 -0
- package/dist/seo-ClB-dw9w.mjs +188 -0
- package/dist/seo-ClB-dw9w.mjs.map +1 -0
- package/dist/service-DpiUQVpp.mjs +150 -0
- package/dist/service-DpiUQVpp.mjs.map +1 -0
- package/dist/session-user-DiE4JKPP.mjs +61 -0
- package/dist/session-user-DiE4JKPP.mjs.map +1 -0
- package/dist/settings--XlUdUaI.mjs +66 -0
- package/dist/settings--XlUdUaI.mjs.map +1 -0
- package/dist/settings-D932YP2-.mjs +519 -0
- package/dist/settings-D932YP2-.mjs.map +1 -0
- package/dist/settings-Dd1uivmQ.mjs +73 -0
- package/dist/settings-Dd1uivmQ.mjs.map +1 -0
- package/dist/setup-complete-qsJYWutC.mjs +65 -0
- package/dist/setup-complete-qsJYWutC.mjs.map +1 -0
- package/dist/setup-nonce-CBFgUFXw.mjs +25 -0
- package/dist/setup-nonce-CBFgUFXw.mjs.map +1 -0
- package/dist/site-domain-oRGS_JfA.mjs +131 -0
- package/dist/site-domain-oRGS_JfA.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-B8QP8wud.mjs +26 -0
- package/dist/sitemap-name-B8QP8wud.mjs.map +1 -0
- package/dist/slug-aVnUV4SL.mjs +16 -0
- package/dist/slug-aVnUV4SL.mjs.map +1 -0
- package/dist/snapshot-BjaXDZQ5.mjs +414 -0
- package/dist/snapshot-BjaXDZQ5.mjs.map +1 -0
- package/dist/ssrf-BcYjyM4M.mjs +406 -0
- package/dist/ssrf-BcYjyM4M.mjs.map +1 -0
- package/dist/stage-CZQnXM_G.mjs +662 -0
- package/dist/stage-CZQnXM_G.mjs.map +1 -0
- package/dist/staged-ByBmPFtX.mjs +686 -0
- package/dist/staged-ByBmPFtX.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 +2 -2
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage-query-BFp06Y0s.d.mts +1627 -0
- package/dist/storage-query-BFp06Y0s.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-5SR76j11.mjs +937 -0
- package/dist/taxonomies-5SR76j11.mjs.map +1 -0
- package/dist/taxonomies-B__VmCKQ.mjs +703 -0
- package/dist/taxonomies-B__VmCKQ.mjs.map +1 -0
- package/dist/taxonomy-CMI5fczd.mjs +563 -0
- package/dist/taxonomy-CMI5fczd.mjs.map +1 -0
- package/dist/tokens-BnhSnGwJ.mjs +171 -0
- package/dist/tokens-BnhSnGwJ.mjs.map +1 -0
- package/dist/transfer-BbKfufJ4.mjs +166 -0
- package/dist/transfer-BbKfufJ4.mjs.map +1 -0
- package/dist/transfer-DTGblAj2.mjs +8910 -0
- package/dist/transfer-DTGblAj2.mjs.map +1 -0
- package/dist/transfer-download-D9LQEDX0.mjs +33 -0
- package/dist/transfer-download-D9LQEDX0.mjs.map +1 -0
- package/dist/transformations-Bx4lYY0Y.mjs +196 -0
- package/dist/transformations-Bx4lYY0Y.mjs.map +1 -0
- package/dist/transport-Dzpn5b3i.mjs +137 -0
- package/dist/transport-Dzpn5b3i.mjs.map +1 -0
- package/dist/trusted-proxy-BU3Nx9g1.mjs +51 -0
- package/dist/trusted-proxy-BU3Nx9g1.mjs.map +1 -0
- package/dist/turnstile-Cs2wfkJG.mjs +58 -0
- package/dist/turnstile-Cs2wfkJG.mjs.map +1 -0
- package/dist/types-BAsCk5KU.d.mts +87 -0
- package/dist/types-BAsCk5KU.d.mts.map +1 -0
- package/dist/types-BuvSwT9Y.d.mts +375 -0
- package/dist/types-BuvSwT9Y.d.mts.map +1 -0
- package/dist/types-C4KT3Md2.d.mts +293 -0
- package/dist/types-C4KT3Md2.d.mts.map +1 -0
- package/dist/types-CVXHwIBB.d.mts +125 -0
- package/dist/types-CVXHwIBB.d.mts.map +1 -0
- package/dist/types-C_asjp1J.mjs.map +1 -1
- package/dist/types-CgfFGfO5.mjs +16 -0
- package/dist/types-CgfFGfO5.mjs.map +1 -0
- package/dist/types-Cj0_yZkn.mjs +18 -0
- package/dist/types-Cj0_yZkn.mjs.map +1 -0
- package/dist/types-CjftrmZR.d.mts +1741 -0
- package/dist/types-CjftrmZR.d.mts.map +1 -0
- package/dist/types-DKwRUA-x.d.mts +916 -0
- package/dist/types-DKwRUA-x.d.mts.map +1 -0
- package/dist/types-DwhEvIVb.mjs.map +1 -1
- package/dist/types-GwAyS5SH.d.mts +227 -0
- package/dist/types-GwAyS5SH.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-uU2YNYSt.d.mts +209 -0
- package/dist/types-uU2YNYSt.d.mts.map +1 -0
- package/dist/update-check-ABBJgg6M.mjs +161 -0
- package/dist/update-check-ABBJgg6M.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-By8SzQxS.mjs +171 -0
- package/dist/user-By8SzQxS.mjs.map +1 -0
- package/dist/utils-D5uOi6WS.mjs +450 -0
- package/dist/utils-D5uOi6WS.mjs.map +1 -0
- package/dist/utils-Szp4iBQB.d.mts +376 -0
- package/dist/utils-Szp4iBQB.d.mts.map +1 -0
- package/dist/validate-DDvxy6qG.d.mts +468 -0
- package/dist/validate-DDvxy6qG.d.mts.map +1 -0
- package/dist/validate-Dz-TIOFB.mjs +524 -0
- package/dist/validate-Dz-TIOFB.mjs.map +1 -0
- package/dist/validation-Fc9ZSUS_.mjs +221 -0
- package/dist/validation-Fc9ZSUS_.mjs.map +1 -0
- package/dist/version-BZj18Q7G.mjs +9 -0
- package/dist/version-BZj18Q7G.mjs.map +1 -0
- package/dist/version-Bu6Nlbb5.mjs +7 -0
- package/dist/version-Bu6Nlbb5.mjs.map +1 -0
- package/dist/version-DqB7LIO7.mjs +49 -0
- package/dist/version-DqB7LIO7.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-BUx_Mf2q.mjs +134 -0
- package/dist/widgets-BUx_Mf2q.mjs.map +1 -0
- package/dist/wxr-taxonomies-DbJtWrWM.mjs +454 -0
- package/dist/wxr-taxonomies-DbJtWrWM.mjs.map +1 -0
- package/dist/zod-generator--nlM0930.mjs +425 -0
- package/dist/zod-generator--nlM0930.mjs.map +1 -0
- package/package.json +5 -5
- package/src/api/handlers/content.ts +49 -18
- package/src/api/handlers/device-flow.ts +1 -3
- package/src/api/handlers/menus.ts +3 -3
- package/src/api/handlers/oauth-authorization.ts +1 -3
- package/src/astro/integration/admin-nav.ts +52 -0
- package/src/astro/integration/index.ts +7 -0
- package/src/astro/integration/runtime.ts +14 -0
- package/src/astro/integration/shims/use-sync-external-store-with-selector.js +2 -0
- package/src/astro/integration/shims/use-sync-external-store.js +4 -1
- package/src/astro/middleware/auth.ts +9 -2
- package/src/astro/routes/api/import/wordpress/analyze.ts +5 -29
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +3 -3
- package/src/astro/routes/api/media/file/[...key].ts +18 -4
- package/src/astro/routes/api/oauth/token.ts +5 -1
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +7 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +3 -1
- 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/types.ts +4 -3
- package/src/auth/api-tokens.ts +3 -0
- package/src/cleanup.ts +44 -0
- package/src/components/inline-bubble-menu.tsx +109 -95
- package/src/components/inline-image.tsx +54 -48
- package/src/database/dialect-helpers.ts +10 -3
- package/src/database/repositories/byline.ts +22 -14
- package/src/database/repositories/content.ts +17 -4
- package/src/database/repositories/media.ts +17 -0
- package/src/database/repositories/menu.ts +163 -132
- package/src/database/repositories/types.ts +3 -3
- package/src/database/types.ts +1 -1
- package/src/emdash-runtime.ts +23 -7
- package/src/import/utils.ts +15 -2
- package/src/index.ts +1 -0
- package/src/loader.ts +106 -95
- package/src/media/content-disposition.ts +56 -0
- package/src/media/normalize.ts +2 -0
- package/src/media/usage/content-fields.ts +2 -1
- package/src/menus/index.ts +137 -25
- package/src/object-cache/index.ts +22 -0
- package/src/plugin-test-runtime.ts +1 -0
- package/src/query.ts +44 -40
- package/src/schema/types.ts +7 -6
- package/src/search/fts-manager.ts +5 -3
- package/src/seed/apply.ts +52 -44
- package/src/seed/types.ts +3 -3
- package/src/taxonomies/index.ts +22 -51
- package/src/transfer/import/advance.ts +12 -1
- package/src/transfer/import/scaffold.ts +7 -1
- package/src/transfer/import/stages.ts +53 -2
- package/src/utils/revalidating-cache.ts +85 -0
- package/src/visual-editing/toolbar.ts +7 -2
- package/src/widgets/index.ts +27 -13
- package/dist/action-token-B1ds4laA.mjs +0 -26
- package/dist/action-token-B1ds4laA.mjs.map +0 -1
- package/dist/activation-sGF9br3X.mjs +0 -387
- package/dist/activation-sGF9br3X.mjs.map +0 -1
- package/dist/adapters-BOMSX9PU.d.mts +0 -173
- package/dist/adapters-BOMSX9PU.d.mts.map +0 -1
- package/dist/after-PcEvMY_6.mjs +0 -96
- package/dist/after-PcEvMY_6.mjs.map +0 -1
- package/dist/allowed-origins-CovsTkm3.mjs +0 -116
- package/dist/allowed-origins-CovsTkm3.mjs.map +0 -1
- package/dist/api-C_LxFnOm.mjs +0 -5077
- package/dist/api-C_LxFnOm.mjs.map +0 -1
- package/dist/api-tokens-C7l0GUAF.mjs +0 -3
- package/dist/api-tokens-DQ9Ee-vP.mjs +0 -173
- package/dist/api-tokens-DQ9Ee-vP.mjs.map +0 -1
- package/dist/apply-CLjfxvyH.mjs +0 -1758
- package/dist/apply-CLjfxvyH.mjs.map +0 -1
- package/dist/approvals-ocK89i4H.mjs +0 -460
- package/dist/approvals-ocK89i4H.mjs.map +0 -1
- package/dist/artifact-fetch-CgvvpoWQ.mjs +0 -659
- package/dist/artifact-fetch-CgvvpoWQ.mjs.map +0 -1
- package/dist/artifacts-DwOYYBQm.mjs +0 -323
- package/dist/artifacts-DwOYYBQm.mjs.map +0 -1
- package/dist/authoritative-records-LPtrIGOY.mjs +0 -5183
- package/dist/authoritative-records-LPtrIGOY.mjs.map +0 -1
- package/dist/authorize-CoDsRRp5.mjs +0 -74
- package/dist/authorize-CoDsRRp5.mjs.map +0 -1
- package/dist/backup-2Wj-hTCN.mjs +0 -246
- package/dist/backup-2Wj-hTCN.mjs.map +0 -1
- package/dist/block-types-C3gJEe7l.mjs +0 -132
- package/dist/block-types-C3gJEe7l.mjs.map +0 -1
- package/dist/block-values-CgbMtSGU.mjs +0 -215
- package/dist/block-values-CgbMtSGU.mjs.map +0 -1
- package/dist/byline-CzGZC2Zs.mjs +0 -922
- package/dist/byline-CzGZC2Zs.mjs.map +0 -1
- package/dist/byline-fields-B1qHvRps.mjs +0 -280
- package/dist/byline-fields-B1qHvRps.mjs.map +0 -1
- package/dist/byline-fields-vYd_4Q1e.mjs +0 -123
- package/dist/byline-fields-vYd_4Q1e.mjs.map +0 -1
- package/dist/bylines-BF555iIz.mjs +0 -150
- package/dist/bylines-BF555iIz.mjs.map +0 -1
- package/dist/bylines-DJx6IWWi.mjs +0 -234
- package/dist/bylines-DJx6IWWi.mjs.map +0 -1
- package/dist/cache-BWzswWB-.mjs +0 -151
- package/dist/cache-BWzswWB-.mjs.map +0 -1
- package/dist/canonical-DjF_z6GI.mjs +0 -174
- package/dist/canonical-DjF_z6GI.mjs.map +0 -1
- package/dist/capture-triggers-D7g3fOZj.mjs +0 -362
- package/dist/capture-triggers-D7g3fOZj.mjs.map +0 -1
- package/dist/challenge-store-Cfjdvw86.mjs +0 -51
- package/dist/challenge-store-Cfjdvw86.mjs.map +0 -1
- package/dist/checksum-BF4acJwn.mjs +0 -162
- package/dist/checksum-BF4acJwn.mjs.map +0 -1
- package/dist/chrome-tags-BDs29G3g.mjs +0 -24
- package/dist/chrome-tags-BDs29G3g.mjs.map +0 -1
- package/dist/chunks-CYBOL-zn.mjs +0 -25
- package/dist/chunks-CYBOL-zn.mjs.map +0 -1
- package/dist/collection-slugs-cache-B2J5aESO.mjs +0 -91
- package/dist/collection-slugs-cache-B2J5aESO.mjs.map +0 -1
- package/dist/comment-DV7dybcs.mjs +0 -335
- package/dist/comment-DV7dybcs.mjs.map +0 -1
- package/dist/comment-reaction-CWwqiT6x.mjs +0 -85
- package/dist/comment-reaction-CWwqiT6x.mjs.map +0 -1
- package/dist/comments-DVjWJm8X.mjs +0 -99
- package/dist/comments-DVjWJm8X.mjs.map +0 -1
- package/dist/comments-Q-ILHCEI.mjs +0 -195
- package/dist/comments-Q-ILHCEI.mjs.map +0 -1
- package/dist/components-DnOmvvgg.mjs +0 -112
- package/dist/components-DnOmvvgg.mjs.map +0 -1
- package/dist/config-9IzA83_U.d.mts +0 -6811
- package/dist/config-9IzA83_U.d.mts.map +0 -1
- package/dist/config-BdQzFtmR.mjs +0 -228
- package/dist/config-BdQzFtmR.mjs.map +0 -1
- package/dist/config-Cs2RBkJ6.d.mts +0 -41
- package/dist/config-Cs2RBkJ6.d.mts.map +0 -1
- package/dist/connection-CiXgZyCY.mjs +0 -36
- package/dist/connection-CiXgZyCY.mjs.map +0 -1
- package/dist/content-Dt0Os_WQ.mjs +0 -2109
- package/dist/content-Dt0Os_WQ.mjs.map +0 -1
- package/dist/content-list-query-BK26u9Ly.d.mts +0 -26
- package/dist/content-list-query-BK26u9Ly.d.mts.map +0 -1
- package/dist/content-policy-BLDbNJOb.mjs +0 -46
- package/dist/content-policy-BLDbNJOb.mjs.map +0 -1
- package/dist/content-repair-CjwbLy4m.mjs +0 -442
- package/dist/content-repair-CjwbLy4m.mjs.map +0 -1
- package/dist/context-ErV7UdQY.mjs +0 -2089
- package/dist/context-ErV7UdQY.mjs.map +0 -1
- package/dist/credits-BRyjafiF.mjs +0 -110
- package/dist/credits-BRyjafiF.mjs.map +0 -1
- package/dist/cron-Bm5xa7tv.mjs +0 -306
- package/dist/cron-Bm5xa7tv.mjs.map +0 -1
- package/dist/dashboard-DVxQ5XiI.mjs +0 -168
- package/dist/dashboard-DVxQ5XiI.mjs.map +0 -1
- package/dist/default-B9Tf2n94.mjs +0 -81
- package/dist/default-B9Tf2n94.mjs.map +0 -1
- package/dist/deferred-tasks-CpPEqsga.d.mts +0 -9
- package/dist/deferred-tasks-CpPEqsga.d.mts.map +0 -1
- package/dist/dev-typegen-ZeWYV8Jp.mjs +0 -29
- package/dist/dev-typegen-ZeWYV8Jp.mjs.map +0 -1
- package/dist/device-flow-BbYNZ9Xi.mjs +0 -521
- package/dist/device-flow-BbYNZ9Xi.mjs.map +0 -1
- package/dist/dialect-helpers-7_IqPdh9.mjs +0 -307
- package/dist/dialect-helpers-7_IqPdh9.mjs.map +0 -1
- package/dist/digest-DlBa7kJl.mjs +0 -194
- package/dist/digest-DlBa7kJl.mjs.map +0 -1
- package/dist/direct-executor-5T8gkhvA.mjs +0 -117
- package/dist/direct-executor-5T8gkhvA.mjs.map +0 -1
- package/dist/dist-DY0aOmAP.mjs +0 -810
- package/dist/dist-DY0aOmAP.mjs.map +0 -1
- package/dist/email-console-v3OM8It-.mjs +0 -50
- package/dist/email-console-v3OM8It-.mjs.map +0 -1
- package/dist/email-locale-CoZo-oZx.mjs +0 -25
- package/dist/email-locale-CoZo-oZx.mjs.map +0 -1
- package/dist/emdash-runtime-DwezbIqQ.mjs +0 -4392
- package/dist/emdash-runtime-DwezbIqQ.mjs.map +0 -1
- package/dist/enrich-C3XIJi0O.mjs +0 -194
- package/dist/enrich-C3XIJi0O.mjs.map +0 -1
- package/dist/entry-lock-CY7XpdSw.d.mts +0 -4568
- package/dist/entry-lock-CY7XpdSw.d.mts.map +0 -1
- package/dist/entry-lock-DDuWaAiP.mjs +0 -1211
- package/dist/entry-lock-DDuWaAiP.mjs.map +0 -1
- package/dist/entry-lock-D_Og9Gy3.mjs +0 -163
- package/dist/entry-lock-D_Og9Gy3.mjs.map +0 -1
- package/dist/entry-locks-Cp8_BcQQ.mjs +0 -167
- package/dist/entry-locks-Cp8_BcQQ.mjs.map +0 -1
- package/dist/env-types-Br8uywYA.mjs +0 -38
- package/dist/env-types-Br8uywYA.mjs.map +0 -1
- package/dist/error-CT2SsX5S.mjs +0 -90
- package/dist/error-CT2SsX5S.mjs.map +0 -1
- package/dist/errors-BMaCpLeS.mjs +0 -479
- package/dist/errors-BMaCpLeS.mjs.map +0 -1
- package/dist/errors-DlJwot7q.mjs +0 -120
- package/dist/errors-DlJwot7q.mjs.map +0 -1
- package/dist/escape-BfbDyuQ-.mjs +0 -9
- package/dist/escape-BfbDyuQ-.mjs.map +0 -1
- package/dist/fence-BOD3SxZG.mjs +0 -162
- package/dist/fence-BOD3SxZG.mjs.map +0 -1
- package/dist/field-defs-cache-C7sR7ZeU.mjs +0 -77
- package/dist/field-defs-cache-C7sR7ZeU.mjs.map +0 -1
- package/dist/field-map-C_rDXfdJ.mjs +0 -84
- package/dist/field-map-C_rDXfdJ.mjs.map +0 -1
- package/dist/fts-manager-BzFo0xx6.mjs +0 -483
- package/dist/fts-manager-BzFo0xx6.mjs.map +0 -1
- package/dist/gc-B_c3DPpi.mjs +0 -75
- package/dist/gc-B_c3DPpi.mjs.map +0 -1
- package/dist/hash-A-o2ZX8O.mjs +0 -37
- package/dist/hash-A-o2ZX8O.mjs.map +0 -1
- package/dist/hreflang-BpUK9Lcu.mjs +0 -105
- package/dist/hreflang-BpUK9Lcu.mjs.map +0 -1
- package/dist/hreflang-D07R-RbI.d.mts +0 -50
- package/dist/hreflang-D07R-RbI.d.mts.map +0 -1
- package/dist/http-route-dispatch-C2Ep2Uf6.mjs +0 -342
- package/dist/http-route-dispatch-C2Ep2Uf6.mjs.map +0 -1
- package/dist/identity-BivQ8wkV.mjs +0 -35
- package/dist/identity-BivQ8wkV.mjs.map +0 -1
- package/dist/import-B4UvHNJz.mjs +0 -2126
- package/dist/import-B4UvHNJz.mjs.map +0 -1
- package/dist/index-C37Ty40w.d.mts +0 -623
- package/dist/index-C37Ty40w.d.mts.map +0 -1
- package/dist/install-finalization-BbYaB4wj.mjs +0 -58
- package/dist/install-finalization-BbYaB4wj.mjs.map +0 -1
- package/dist/json-recordset-BjYIWFkV.mjs +0 -12
- package/dist/json-recordset-BjYIWFkV.mjs.map +0 -1
- package/dist/json-schema-Cde7le0s.mjs +0 -15
- package/dist/json-schema-Cde7le0s.mjs.map +0 -1
- package/dist/keys-CusTXpw-.mjs +0 -61
- package/dist/keys-CusTXpw-.mjs.map +0 -1
- package/dist/kinds-DogmNB6n.mjs +0 -974
- package/dist/kinds-DogmNB6n.mjs.map +0 -1
- package/dist/lifecycle-BLCoCz4T.mjs +0 -25
- package/dist/lifecycle-BLCoCz4T.mjs.map +0 -1
- package/dist/load-Dds3KhXr.mjs +0 -28
- package/dist/load-Dds3KhXr.mjs.map +0 -1
- package/dist/loader-D4w4XE7q.mjs +0 -1420
- package/dist/loader-D4w4XE7q.mjs.map +0 -1
- package/dist/loops-IYgzQdQu.mjs +0 -205
- package/dist/loops-IYgzQdQu.mjs.map +0 -1
- package/dist/manifest-builder-CGF5kujD.mjs +0 -196
- package/dist/manifest-builder-CGF5kujD.mjs.map +0 -1
- package/dist/manifest-schema-B0BxPSjB.mjs +0 -497
- package/dist/manifest-schema-B0BxPSjB.mjs.map +0 -1
- package/dist/marketplace-DNvEGLqU.mjs +0 -257
- package/dist/marketplace-DNvEGLqU.mjs.map +0 -1
- package/dist/media-BL9MRrSG.mjs +0 -294
- package/dist/media-BL9MRrSG.mjs.map +0 -1
- package/dist/media-B_x5B9EA.mjs +0 -373
- package/dist/media-B_x5B9EA.mjs.map +0 -1
- package/dist/media-allowlist-CpmqBbIQ.mjs +0 -45
- package/dist/media-allowlist-CpmqBbIQ.mjs.map +0 -1
- package/dist/media-folders-CNs_A_B-.mjs +0 -210
- package/dist/media-folders-CNs_A_B-.mjs.map +0 -1
- package/dist/media-qTTHVkls.mjs +0 -416
- package/dist/media-qTTHVkls.mjs.map +0 -1
- package/dist/media-url-GJboA1fl.mjs +0 -43
- package/dist/media-url-GJboA1fl.mjs.map +0 -1
- package/dist/media-usage-ClWgrX0d.mjs +0 -282
- package/dist/media-usage-ClWgrX0d.mjs.map +0 -1
- package/dist/media-usage-activation-B8Fjtq0h.mjs +0 -78
- package/dist/media-usage-activation-B8Fjtq0h.mjs.map +0 -1
- package/dist/media-usage-work-L8-Au4j-.mjs +0 -1036
- package/dist/media-usage-work-L8-Au4j-.mjs.map +0 -1
- package/dist/media-usage-work-LXgze5j9.mjs +0 -151
- package/dist/media-usage-work-LXgze5j9.mjs.map +0 -1
- package/dist/menus-BAxcbsbv.mjs +0 -818
- package/dist/menus-BAxcbsbv.mjs.map +0 -1
- package/dist/menus-BI6oBXco.mjs +0 -92
- package/dist/menus-BI6oBXco.mjs.map +0 -1
- package/dist/menus-fvGFd4m6.mjs +0 -3725
- package/dist/menus-fvGFd4m6.mjs.map +0 -1
- package/dist/mime-DwhtRyUt.mjs +0 -81
- package/dist/mime-DwhtRyUt.mjs.map +0 -1
- package/dist/mode-DIDSUwuN.mjs +0 -23
- package/dist/mode-DIDSUwuN.mjs.map +0 -1
- package/dist/node-sqlite-compat-Ddr_mlR9.mjs +0 -63
- package/dist/node-sqlite-compat-Ddr_mlR9.mjs.map +0 -1
- package/dist/normalize-Ip_hFAm8.mjs +0 -216
- package/dist/normalize-Ip_hFAm8.mjs.map +0 -1
- package/dist/oauth-authorization-CcMgeT8R.mjs +0 -274
- package/dist/oauth-authorization-CcMgeT8R.mjs.map +0 -1
- package/dist/oauth-clients-C_osi0PU.mjs +0 -266
- package/dist/oauth-clients-C_osi0PU.mjs.map +0 -1
- package/dist/oauth-state-store-DGLP-6CK.mjs +0 -50
- package/dist/oauth-state-store-DGLP-6CK.mjs.map +0 -1
- package/dist/oauth-user-lookup-z77Ee0Hm.mjs +0 -26
- package/dist/oauth-user-lookup-z77Ee0Hm.mjs.map +0 -1
- package/dist/object-cache-EjasjtoQ.mjs +0 -586
- package/dist/object-cache-EjasjtoQ.mjs.map +0 -1
- package/dist/options-CmUpkyKW.d.mts +0 -81
- package/dist/options-CmUpkyKW.d.mts.map +0 -1
- package/dist/ownership-DCk5NutQ.mjs +0 -12
- package/dist/ownership-DCk5NutQ.mjs.map +0 -1
- package/dist/parse-2W-E2f7w.mjs +0 -81
- package/dist/parse-2W-E2f7w.mjs.map +0 -1
- package/dist/parse-6pN8Xqg5.d.mts +0 -176
- package/dist/parse-6pN8Xqg5.d.mts.map +0 -1
- package/dist/passkey-config-DTTZB6EI.mjs +0 -46
- package/dist/passkey-config-DTTZB6EI.mjs.map +0 -1
- package/dist/paths-CQA62503.mjs +0 -77
- package/dist/paths-CQA62503.mjs.map +0 -1
- package/dist/placeholder-BlfXkucE.d.mts +0 -313
- package/dist/placeholder-BlfXkucE.d.mts.map +0 -1
- package/dist/plan-B95eiwnF.mjs +0 -135
- package/dist/plan-B95eiwnF.mjs.map +0 -1
- package/dist/plugin-tool-name-BDA7m4Xa.mjs +0 -27
- package/dist/plugin-tool-name-BDA7m4Xa.mjs.map +0 -1
- package/dist/plugins-BhxLJ008.mjs +0 -261
- package/dist/plugins-BhxLJ008.mjs.map +0 -1
- package/dist/policy-DOJ2sPqB.mjs +0 -53
- package/dist/policy-DOJ2sPqB.mjs.map +0 -1
- package/dist/portable-text-RCMpCj47.mjs +0 -311
- package/dist/portable-text-RCMpCj47.mjs.map +0 -1
- package/dist/preview-DFwL5APO.mjs +0 -107
- package/dist/preview-DFwL5APO.mjs.map +0 -1
- package/dist/protocol-B-ztxp_y.d.mts +0 -65
- package/dist/protocol-B-ztxp_y.d.mts.map +0 -1
- package/dist/public-plugin-api-routes-ik4fPZMv.mjs +0 -316
- package/dist/public-plugin-api-routes-ik4fPZMv.mjs.map +0 -1
- package/dist/public-submission-C5JZIykp.mjs +0 -251
- package/dist/public-submission-C5JZIykp.mjs.map +0 -1
- package/dist/public-url-CQwzRljH.mjs +0 -101
- package/dist/public-url-CQwzRljH.mjs.map +0 -1
- package/dist/query-DuwyFr5Z.mjs +0 -41
- package/dist/query-DuwyFr5Z.mjs.map +0 -1
- package/dist/query-eR_Nz70M.mjs +0 -1157
- package/dist/query-eR_Nz70M.mjs.map +0 -1
- package/dist/range-BQWPjWgQ.mjs +0 -51
- package/dist/range-BQWPjWgQ.mjs.map +0 -1
- package/dist/rate-limit-mPKeQ3sm.mjs +0 -127
- package/dist/rate-limit-mPKeQ3sm.mjs.map +0 -1
- package/dist/receipt-CmUpyuW5.mjs +0 -43
- package/dist/receipt-CmUpyuW5.mjs.map +0 -1
- package/dist/redirect-BtiMkehU.mjs +0 -19
- package/dist/redirect-BtiMkehU.mjs.map +0 -1
- package/dist/redirect-DcmNMvOs.mjs +0 -423
- package/dist/redirect-DcmNMvOs.mjs.map +0 -1
- package/dist/redirect-paths-K5i3xYfR.mjs +0 -36
- package/dist/redirect-paths-K5i3xYfR.mjs.map +0 -1
- package/dist/redirects-BA_TvtuH.mjs +0 -148
- package/dist/redirects-BA_TvtuH.mjs.map +0 -1
- package/dist/redirects-BIrRvgn4.mjs +0 -446
- package/dist/redirects-BIrRvgn4.mjs.map +0 -1
- package/dist/registry-DymfZkAN.mjs +0 -8374
- package/dist/registry-DymfZkAN.mjs.map +0 -1
- package/dist/relations-DrEs3Sc1.mjs +0 -789
- package/dist/relations-DrEs3Sc1.mjs.map +0 -1
- package/dist/request-meta-o8RIf9pa.mjs +0 -141
- package/dist/request-meta-o8RIf9pa.mjs.map +0 -1
- package/dist/resolve-CVy9xgy_.mjs +0 -102
- package/dist/resolve-CVy9xgy_.mjs.map +0 -1
- package/dist/route-cache-DAG5dPhh.mjs +0 -20
- package/dist/route-cache-DAG5dPhh.mjs.map +0 -1
- package/dist/route-wire-Xbsu8Vih.mjs +0 -197
- package/dist/route-wire-Xbsu8Vih.mjs.map +0 -1
- package/dist/routes-YQkSOsws.mjs +0 -272
- package/dist/routes-YQkSOsws.mjs.map +0 -1
- package/dist/runner-CLorw5vo.mjs +0 -6669
- package/dist/runner-CLorw5vo.mjs.map +0 -1
- package/dist/runner-g1A9P-wD.d.mts +0 -73
- package/dist/runner-g1A9P-wD.d.mts.map +0 -1
- package/dist/schema-Bss8qImF.mjs +0 -13
- package/dist/schema-Bss8qImF.mjs.map +0 -1
- package/dist/schema-C036pqEw.mjs +0 -815
- package/dist/schema-C036pqEw.mjs.map +0 -1
- package/dist/scopes-C_SoYl9x.mjs +0 -34
- package/dist/scopes-C_SoYl9x.mjs.map +0 -1
- package/dist/search-uNqCgePJ.mjs +0 -450
- package/dist/search-uNqCgePJ.mjs.map +0 -1
- package/dist/secrets-Cc_O3Kp-.mjs +0 -369
- package/dist/secrets-Cc_O3Kp-.mjs.map +0 -1
- package/dist/sections-BLusMa96.mjs +0 -346
- package/dist/sections-BLusMa96.mjs.map +0 -1
- package/dist/seo-BodxIpws.mjs +0 -188
- package/dist/seo-BodxIpws.mjs.map +0 -1
- package/dist/seo-DaMYIQY8.mjs +0 -133
- package/dist/seo-DaMYIQY8.mjs.map +0 -1
- package/dist/service-BuM1BRsA.mjs +0 -150
- package/dist/service-BuM1BRsA.mjs.map +0 -1
- package/dist/session-user-2DpQDMKw.mjs +0 -61
- package/dist/session-user-2DpQDMKw.mjs.map +0 -1
- package/dist/settings-B3ZmPF_8.mjs +0 -73
- package/dist/settings-B3ZmPF_8.mjs.map +0 -1
- package/dist/settings-P5hwPX6_.mjs +0 -66
- package/dist/settings-P5hwPX6_.mjs.map +0 -1
- package/dist/settings-yIqoN-Ok.mjs +0 -519
- package/dist/settings-yIqoN-Ok.mjs.map +0 -1
- package/dist/setup-complete-eu6MUQnt.mjs +0 -65
- package/dist/setup-complete-eu6MUQnt.mjs.map +0 -1
- package/dist/setup-nonce-CyPOapqY.mjs +0 -25
- package/dist/setup-nonce-CyPOapqY.mjs.map +0 -1
- package/dist/site-domain-8lEJl_0U.mjs +0 -131
- package/dist/site-domain-8lEJl_0U.mjs.map +0 -1
- package/dist/site-settings-uPkW0e6o.mjs +0 -50
- package/dist/site-settings-uPkW0e6o.mjs.map +0 -1
- package/dist/site-url-25SGVXwL.mjs +0 -45
- package/dist/site-url-25SGVXwL.mjs.map +0 -1
- package/dist/sitemap-name-DTK7CYnY.mjs +0 -26
- package/dist/sitemap-name-DTK7CYnY.mjs.map +0 -1
- package/dist/slug-BEDl2IJY.mjs +0 -16
- package/dist/slug-BEDl2IJY.mjs.map +0 -1
- package/dist/snapshot-CvkIBRLY.mjs +0 -414
- package/dist/snapshot-CvkIBRLY.mjs.map +0 -1
- package/dist/ssrf-mcCKMH6B.mjs +0 -406
- package/dist/ssrf-mcCKMH6B.mjs.map +0 -1
- package/dist/stage-BQfGzGOy.mjs +0 -662
- package/dist/stage-BQfGzGOy.mjs.map +0 -1
- package/dist/staged-B5vQGeSf.mjs +0 -686
- package/dist/staged-B5vQGeSf.mjs.map +0 -1
- package/dist/state-dO6t6OxV.mjs +0 -178
- package/dist/state-dO6t6OxV.mjs.map +0 -1
- package/dist/status-DSURZwKS.mjs +0 -30
- package/dist/status-DSURZwKS.mjs.map +0 -1
- package/dist/storage-query-Cy0SZ8iG.d.mts +0 -1619
- package/dist/storage-query-Cy0SZ8iG.d.mts.map +0 -1
- package/dist/tar-DWzcUZ_Q.mjs +0 -449
- package/dist/tar-DWzcUZ_Q.mjs.map +0 -1
- package/dist/target-C9htUbrT.mjs +0 -27
- package/dist/target-C9htUbrT.mjs.map +0 -1
- package/dist/taxonomies-By2aGvq2.mjs +0 -729
- package/dist/taxonomies-By2aGvq2.mjs.map +0 -1
- package/dist/taxonomies-CVRd_jz0.mjs +0 -937
- package/dist/taxonomies-CVRd_jz0.mjs.map +0 -1
- package/dist/taxonomy-BG_xu2Qf.mjs +0 -563
- package/dist/taxonomy-BG_xu2Qf.mjs.map +0 -1
- package/dist/tokens-U5vzgSrM.mjs +0 -171
- package/dist/tokens-U5vzgSrM.mjs.map +0 -1
- package/dist/transfer-DA0OSfaT.mjs +0 -8873
- package/dist/transfer-DA0OSfaT.mjs.map +0 -1
- package/dist/transfer-Pyf3d7ka.mjs +0 -166
- package/dist/transfer-Pyf3d7ka.mjs.map +0 -1
- package/dist/transfer-download-cX7SuWEy.mjs +0 -33
- package/dist/transfer-download-cX7SuWEy.mjs.map +0 -1
- package/dist/transformations-DczubD4j.mjs +0 -196
- package/dist/transformations-DczubD4j.mjs.map +0 -1
- package/dist/transport-DtIrjEFO.mjs +0 -137
- package/dist/transport-DtIrjEFO.mjs.map +0 -1
- package/dist/trusted-proxy-CDRd5Kmw.mjs +0 -51
- package/dist/trusted-proxy-CDRd5Kmw.mjs.map +0 -1
- package/dist/turnstile-Ct5YuFNY.mjs +0 -58
- package/dist/turnstile-Ct5YuFNY.mjs.map +0 -1
- package/dist/types-Bgujop4S.d.mts +0 -374
- package/dist/types-Bgujop4S.d.mts.map +0 -1
- package/dist/types-BirHUEXt.mjs +0 -18
- package/dist/types-BirHUEXt.mjs.map +0 -1
- package/dist/types-BqJgTL_y.d.mts +0 -293
- package/dist/types-BqJgTL_y.d.mts.map +0 -1
- package/dist/types-C-lrOt9T.d.mts +0 -87
- package/dist/types-C-lrOt9T.d.mts.map +0 -1
- package/dist/types-CCEHAhOv.d.mts +0 -916
- package/dist/types-CCEHAhOv.d.mts.map +0 -1
- package/dist/types-CLVwYRBr.d.mts +0 -227
- package/dist/types-CLVwYRBr.d.mts.map +0 -1
- package/dist/types-DVbTb4Hk.mjs +0 -77
- package/dist/types-DVbTb4Hk.mjs.map +0 -1
- package/dist/types-Ddku19Zw.d.mts +0 -209
- package/dist/types-Ddku19Zw.d.mts.map +0 -1
- package/dist/types-FIiGQ3PE.mjs +0 -16
- package/dist/types-FIiGQ3PE.mjs.map +0 -1
- package/dist/types-OauzCOY0.mjs +0 -37
- package/dist/types-OauzCOY0.mjs.map +0 -1
- package/dist/types-mQGTpP-4.d.mts +0 -1741
- package/dist/types-mQGTpP-4.d.mts.map +0 -1
- package/dist/types-nbjz3Mgm.d.mts +0 -125
- package/dist/types-nbjz3Mgm.d.mts.map +0 -1
- package/dist/update-check-hW32-0pf.mjs +0 -161
- package/dist/update-check-hW32-0pf.mjs.map +0 -1
- package/dist/upload-attempts-Bpik1TLF.mjs +0 -32
- package/dist/upload-attempts-Bpik1TLF.mjs.map +0 -1
- package/dist/url-pattern-CJeCyNij.mjs +0 -41
- package/dist/url-pattern-CJeCyNij.mjs.map +0 -1
- package/dist/user-nQInBZbE.mjs +0 -171
- package/dist/user-nQInBZbE.mjs.map +0 -1
- package/dist/utils-govudc_U.mjs +0 -442
- package/dist/utils-govudc_U.mjs.map +0 -1
- package/dist/validate-BxLvcDYh.mjs +0 -524
- package/dist/validate-BxLvcDYh.mjs.map +0 -1
- package/dist/validate-mnoVfASU.d.mts +0 -468
- package/dist/validate-mnoVfASU.d.mts.map +0 -1
- package/dist/validation-DQDEvh87.mjs +0 -221
- package/dist/validation-DQDEvh87.mjs.map +0 -1
- package/dist/version-BOFfLiVT.mjs +0 -49
- package/dist/version-BOFfLiVT.mjs.map +0 -1
- package/dist/version-Dcvx_C9g.mjs +0 -7
- package/dist/version-Dcvx_C9g.mjs.map +0 -1
- package/dist/version-DzTJ3gD7.mjs +0 -9
- package/dist/version-DzTJ3gD7.mjs.map +0 -1
- package/dist/video-BX7AI5nJ.mjs +0 -54
- package/dist/video-BX7AI5nJ.mjs.map +0 -1
- package/dist/virtual-modules-CU29aip9.mjs +0 -515
- package/dist/virtual-modules-CU29aip9.mjs.map +0 -1
- package/dist/widgets-HIeFmZxt.mjs +0 -121
- package/dist/widgets-HIeFmZxt.mjs.map +0 -1
- package/dist/wxr-taxonomies-DyOGhl8W.mjs +0 -454
- package/dist/wxr-taxonomies-DyOGhl8W.mjs.map +0 -1
- package/dist/zod-generator-VxCPVDpo.mjs +0 -425
- package/dist/zod-generator-VxCPVDpo.mjs.map +0 -1
- /package/dist/{ssrf-BBXcxG-f.mjs → ssrf-DM0E-D_8.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-D932YP2-.mjs","names":[],"sources":["../src/plugins/settings.ts","../src/settings/index.ts"],"sourcesContent":["import { resolvePluginEncryptionKeys, type ParsedEncryptionKey } from \"../config/secrets.js\";\nimport type { OptionsRepository } from \"../database/repositories/options.js\";\nimport { decodeBase64url, encodeBase64url } from \"../utils/base64.js\";\nimport { assertStorageKey } from \"./conditional-storage.js\";\nexport { createPluginSecretRedactor } from \"./secret-redactor.js\";\nexport type { PluginSecretRedactor } from \"./secret-redactor.js\";\nimport type {\n\tConditionalDeleteResult,\n\tConditionalWriteResult,\n\tSettingField,\n\tSettingsAccess,\n\tVersionedValue,\n} from \"./types.js\";\n\nconst ENVELOPE_VERSION = 1;\nconst ENVELOPE_MARKER = \"plugin-setting\";\nconst IV_BYTES = 12;\nconst KEY_ID_PATTERN = /^[0-9a-f]{8}$/;\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder(\"utf-8\", { fatal: true });\n\nexport interface EncryptedPluginSetting {\n\t$emdash: \"plugin-setting\";\n\tv: 1;\n\tkid: string;\n\tiv: string;\n\tciphertext: string;\n}\n\nexport class PluginSettingEncryptionError extends Error {\n\toverride readonly name = \"PluginSettingEncryptionError\";\n\treadonly code:\n\t\t| \"PLUGIN_SETTING_ENCRYPTION_KEY_MISSING\"\n\t\t| \"PLUGIN_SETTING_ENCRYPTION_KEY_UNKNOWN\"\n\t\t| \"PLUGIN_SETTING_ENCRYPTION_FAILED\"\n\t\t| \"PLUGIN_SETTING_DECRYPTION_FAILED\";\n\n\tconstructor(code: PluginSettingEncryptionError[\"code\"], message: string) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t}\n}\n\nexport function isEncryptedPluginSetting(value: unknown): value is EncryptedPluginSetting {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n\treturn (\n\t\tObject.keys(value).length === 5 &&\n\t\t\"$emdash\" in value &&\n\t\tvalue.$emdash === ENVELOPE_MARKER &&\n\t\t\"v\" in value &&\n\t\tvalue.v === ENVELOPE_VERSION &&\n\t\t\"kid\" in value &&\n\t\ttypeof value.kid === \"string\" &&\n\t\tKEY_ID_PATTERN.test(value.kid) &&\n\t\t\"iv\" in value &&\n\t\ttypeof value.iv === \"string\" &&\n\t\tBASE64URL_PATTERN.test(value.iv) &&\n\t\t\"ciphertext\" in value &&\n\t\ttypeof value.ciphertext === \"string\" &&\n\t\tBASE64URL_PATTERN.test(value.ciphertext)\n\t);\n}\n\nfunction additionalData(pluginId: string, key: string): Uint8Array {\n\treturn textEncoder.encode(\n\t\tJSON.stringify([\"emdash-plugin-setting\", ENVELOPE_VERSION, pluginId, key]),\n\t);\n}\n\nfunction exactBuffer(bytes: Uint8Array): ArrayBuffer {\n\treturn bytes.slice().buffer;\n}\n\nasync function importEncryptionKey(key: ParsedEncryptionKey, usage: KeyUsage): Promise<CryptoKey> {\n\treturn crypto.subtle.importKey(\"raw\", exactBuffer(key.key), \"AES-GCM\", false, [usage]);\n}\n\nasync function keysOrDefault(\n\tkeys: ParsedEncryptionKey[] | null | undefined,\n): Promise<ParsedEncryptionKey[] | null> {\n\treturn keys === undefined ? resolvePluginEncryptionKeys() : keys;\n}\n\nexport async function encryptPluginSetting(\n\tpluginId: string,\n\tkey: string,\n\tvalue: string,\n\tkeys?: ParsedEncryptionKey[] | null,\n): Promise<EncryptedPluginSetting> {\n\tconst resolved = await keysOrDefault(keys);\n\tconst primary = resolved?.[0];\n\tif (!primary) {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_ENCRYPTION_KEY_MISSING\",\n\t\t\t\"Plugin secret settings require EMDASH_ENCRYPTION_KEY\",\n\t\t);\n\t}\n\n\ttry {\n\t\tconst iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));\n\t\tconst cryptoKey = await importEncryptionKey(primary, \"encrypt\");\n\t\tconst ciphertext = await crypto.subtle.encrypt(\n\t\t\t{\n\t\t\t\tname: \"AES-GCM\",\n\t\t\t\tiv: exactBuffer(iv),\n\t\t\t\tadditionalData: exactBuffer(additionalData(pluginId, key)),\n\t\t\t},\n\t\t\tcryptoKey,\n\t\t\texactBuffer(textEncoder.encode(value)),\n\t\t);\n\t\treturn {\n\t\t\t$emdash: ENVELOPE_MARKER,\n\t\t\tv: ENVELOPE_VERSION,\n\t\t\tkid: primary.kid,\n\t\t\tiv: encodeBase64url(iv),\n\t\t\tciphertext: encodeBase64url(new Uint8Array(ciphertext)),\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof PluginSettingEncryptionError) throw error;\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_ENCRYPTION_FAILED\",\n\t\t\t\"Plugin secret setting could not be encrypted\",\n\t\t);\n\t}\n}\n\nexport async function decryptPluginSetting(\n\tpluginId: string,\n\tkey: string,\n\tenvelope: EncryptedPluginSetting,\n\tkeys?: ParsedEncryptionKey[] | null,\n): Promise<string> {\n\tconst resolved = await keysOrDefault(keys);\n\tif (!resolved?.length) {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_ENCRYPTION_KEY_MISSING\",\n\t\t\t\"Plugin secret setting cannot be decrypted because its encryption key is unavailable\",\n\t\t);\n\t}\n\tconst matched = resolved.find((candidate) => candidate.kid === envelope.kid);\n\tif (!matched) {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_ENCRYPTION_KEY_UNKNOWN\",\n\t\t\t\"Plugin secret setting was encrypted with an unavailable key\",\n\t\t);\n\t}\n\n\ttry {\n\t\tconst iv = decodeBase64url(envelope.iv);\n\t\tconst ciphertext = decodeBase64url(envelope.ciphertext);\n\t\tif (iv.byteLength !== IV_BYTES || ciphertext.byteLength < 16)\n\t\t\tthrow new Error(\"invalid envelope\");\n\t\tconst cryptoKey = await importEncryptionKey(matched, \"decrypt\");\n\t\tconst plaintext = await crypto.subtle.decrypt(\n\t\t\t{\n\t\t\t\tname: \"AES-GCM\",\n\t\t\t\tiv: exactBuffer(iv),\n\t\t\t\tadditionalData: exactBuffer(additionalData(pluginId, key)),\n\t\t\t},\n\t\t\tcryptoKey,\n\t\t\texactBuffer(ciphertext),\n\t\t);\n\t\treturn textDecoder.decode(plaintext);\n\t} catch {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_DECRYPTION_FAILED\",\n\t\t\t\"Plugin secret setting could not be decrypted\",\n\t\t);\n\t}\n}\n\nfunction isSecretField(schema: Record<string, SettingField>, key: string): boolean {\n\treturn schema[key]?.type === \"secret\";\n}\n\nexport async function encodePluginSettingValue(\n\tpluginId: string,\n\tkey: string,\n\tvalue: unknown,\n\tschema: Record<string, SettingField>,\n\tkeys?: ParsedEncryptionKey[] | null,\n\tonSecret?: (key: string, value: string) => void,\n): Promise<unknown> {\n\tif (!isSecretField(schema, key)) return value;\n\tif (typeof value !== \"string\") {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_ENCRYPTION_FAILED\",\n\t\t\t\"Plugin secret settings must be strings\",\n\t\t);\n\t}\n\tonSecret?.(key, value);\n\treturn encryptPluginSetting(pluginId, key, value, keys);\n}\n\nexport async function decodePluginSettingValue<T = unknown>(\n\tpluginId: string,\n\tkey: string,\n\tvalue: unknown,\n\tschema: Record<string, SettingField>,\n\tkeys?: ParsedEncryptionKey[] | null,\n\tonSecret?: (key: string, value: string) => void,\n): Promise<T> {\n\tif (!isSecretField(schema, key)) {\n\t\tif (isEncryptedPluginSetting(value)) {\n\t\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\t\"PLUGIN_SETTING_DECRYPTION_FAILED\",\n\t\t\t\t\"Encrypted plugin setting is not declared as a secret\",\n\t\t\t);\n\t\t}\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- caller supplies the expected non-secret setting type\n\t\treturn value as T;\n\t}\n\tif (typeof value === \"string\") {\n\t\tonSecret?.(key, value);\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- secret schema guarantees a string and caller supplies its compatible type\n\t\treturn value as T;\n\t}\n\tif (!isEncryptedPluginSetting(value)) {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_DECRYPTION_FAILED\",\n\t\t\t\"Plugin secret setting has an invalid encrypted envelope\",\n\t\t);\n\t}\n\tconst decrypted = await decryptPluginSetting(pluginId, key, value, keys);\n\tonSecret?.(key, decrypted);\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- secret schema guarantees a string and caller supplies its compatible type\n\treturn decrypted as T;\n}\n\nexport function createSettingsAccess(\n\toptionsRepo: OptionsRepository,\n\tpluginId: string,\n\tschema: Record<string, SettingField> = {},\n\tkeys?: ParsedEncryptionKey[] | null,\n\tonSecret?: (key: string, value: string) => void,\n): SettingsAccess {\n\tconst prefix = `plugin:${pluginId}:settings:`;\n\tconst optionKey = (key: string) => {\n\t\tassertStorageKey(key);\n\t\treturn `${prefix}${key}`;\n\t};\n\n\treturn {\n\t\tasync get<T>(key: string): Promise<T | null> {\n\t\t\tconst value = await optionsRepo.get(optionKey(key));\n\t\t\treturn value === null\n\t\t\t\t? null\n\t\t\t\t: decodePluginSettingValue<T>(pluginId, key, value, schema, keys, onSecret);\n\t\t},\n\t\tasync getVersioned<T>(key: string): Promise<VersionedValue<T> | null> {\n\t\t\tconst value = await optionsRepo.getVersioned(optionKey(key));\n\t\t\tif (!value) return null;\n\t\t\treturn {\n\t\t\t\tvalue: await decodePluginSettingValue<T>(\n\t\t\t\t\tpluginId,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue.value,\n\t\t\t\t\tschema,\n\t\t\t\t\tkeys,\n\t\t\t\t\tonSecret,\n\t\t\t\t),\n\t\t\t\trevision: value.revision,\n\t\t\t};\n\t\t},\n\t\tasync compareAndSet(\n\t\t\tkey: string,\n\t\t\texpectedRevision: string | null,\n\t\t\tvalue: unknown,\n\t\t): Promise<ConditionalWriteResult> {\n\t\t\treturn optionsRepo.compareAndSet(\n\t\t\t\toptionKey(key),\n\t\t\t\texpectedRevision,\n\t\t\t\tawait encodePluginSettingValue(pluginId, key, value, schema, keys, onSecret),\n\t\t\t);\n\t\t},\n\t\tcompareAndDelete(key: string, expectedRevision: string): Promise<ConditionalDeleteResult> {\n\t\t\treturn optionsRepo.compareAndDelete(optionKey(key), expectedRevision);\n\t\t},\n\t\tasync set(key: string, value: unknown): Promise<void> {\n\t\t\tawait optionsRepo.set(\n\t\t\t\toptionKey(key),\n\t\t\t\tawait encodePluginSettingValue(pluginId, key, value, schema, keys, onSecret),\n\t\t\t);\n\t\t},\n\t\tdelete(key: string): Promise<boolean> {\n\t\t\treturn optionsRepo.delete(optionKey(key));\n\t\t},\n\t\tasync list(keyPrefix = \"\"): Promise<Array<{ key: string; value: unknown }>> {\n\t\t\tassertStorageKey(keyPrefix || \"_\");\n\t\t\tconst values = await optionsRepo.getByPrefix(`${prefix}${keyPrefix}`);\n\t\t\tconst result: Array<{ key: string; value: unknown }> = [];\n\t\t\tfor (const [fullKey, value] of values) {\n\t\t\t\tconst key = fullKey.slice(prefix.length);\n\t\t\t\tresult.push({\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue: await decodePluginSettingValue(pluginId, key, value, schema, keys, onSecret),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t};\n}\n","/**\n * Site Settings API\n *\n * Functions for getting and setting global site configuration.\n * Settings are stored in the options table with 'site:' prefix.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { after } from \"../after.js\";\nimport { siteSettingsTag } from \"../cache/chrome-tags.js\";\nimport { resolvePluginEncryptionKeys } from \"../config/secrets.js\";\nimport { MediaRepository } from \"../database/repositories/media.js\";\nimport { OptionsRepository } from \"../database/repositories/options.js\";\nimport { withTransaction } from \"../database/transaction.js\";\nimport type { Database } from \"../database/types.js\";\nimport { getDb } from \"../loader.js\";\nimport { cachedQuery, invalidateObjectCache } from \"../object-cache/index.js\";\nimport { isRecord } from \"../plugin-utils.js\";\nimport {\n\tPluginSettingEncryptionError,\n\tdecryptPluginSetting,\n\tisEncryptedPluginSetting,\n} from \"../plugins/settings.js\";\nimport type { CacheHint } from \"../query.js\";\nimport { peekRequestCache, requestCached } from \"../request-cache.js\";\nimport { getRequestContext } from \"../request-context.js\";\nimport { bumpRunningExportWriteEpochs } from \"../transfer/fence.js\";\nimport { isMissingTableError } from \"../utils/db-errors.js\";\n\n/** Object-cache namespace for site settings. */\nconst SETTINGS_CACHE_NAMESPACE = \"settings\";\nimport type { Storage } from \"../storage/types.js\";\nimport {\n\tcreateSingleFlightCache,\n\ttype SingleFlightCache,\n\tinvalidateSingleFlightCache,\n\tsingleFlightCached,\n} from \"../utils/single-flight-cache.js\";\nimport type {\n\tMediaReference,\n\tSeoSettings,\n\tSiteSettings,\n\tSiteSettingsUpdate,\n\tSiteSettingKey,\n} from \"./types.js\";\nimport { normalizeSiteSettingsVersion } from \"./version.js\";\n\n/** Prefix for site settings in the options table */\nconst SETTINGS_PREFIX = \"site:\";\n\n/** Settings stored as one object whose fields are updated individually. */\nconst NESTED_SETTING_KEYS = new Set([\"seo\", \"social\"]);\n\nfunction isPluginSettingEnvelopeRecord(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t!Array.isArray(value) &&\n\t\t\"$emdash\" in value &&\n\t\tvalue.$emdash === \"plugin-setting\"\n\t);\n}\n\nasync function decodePersistedPluginSetting(\n\tpluginId: string,\n\tkey: string,\n\tvalue: unknown,\n\tencryptionKeys?: Awaited<ReturnType<typeof resolvePluginEncryptionKeys>>,\n): Promise<unknown> {\n\tif (isEncryptedPluginSetting(value)) {\n\t\treturn decryptPluginSetting(pluginId, key, value, encryptionKeys);\n\t}\n\tif (isPluginSettingEnvelopeRecord(value)) {\n\t\tthrow new PluginSettingEncryptionError(\n\t\t\t\"PLUGIN_SETTING_DECRYPTION_FAILED\",\n\t\t\t\"Plugin secret setting has an invalid encrypted envelope\",\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * Worker-isolate cache for the resolved `site:*` settings.\n *\n * Site settings (title, logo, SEO defaults) change rarely but are read on\n * every public request. Revalidate warm snapshots after 30 seconds in the\n * background, retaining the last good value if the reload fails.\n *\n * Backed by single-flight-cache.ts: concurrent cold reads coalesce onto one\n * query via a reclaimable single-flight lock and the resolved *value* is\n * cached — never a shared in-flight promise, so a cancelled request can't\n * poison the isolate (see that file's header). Stored on globalThis with a\n * Symbol.for key so Vite SSR chunk duplication doesn't produce two\n * independent caches (same pattern as request-context.ts).\n */\ninterface CachedSiteSettings {\n\tdata: Partial<SiteSettings>;\n\tversion: string;\n}\n\ninterface SiteSettingsCache {\n\tsnapshot: CachedSiteSettings | null;\n\texpiresAt: number;\n\tgeneration: number;\n\trevalidatingUntil: number;\n\trefresh: SingleFlightCache<CachedSiteSettings>;\n}\n\nconst SITE_SETTINGS_CACHE_TTL_MS = 30_000;\nconst SITE_SETTINGS_CACHE_KEY = Symbol.for(\"emdash:site-settings:swr\");\nconst g = globalThis as Record<symbol, unknown>;\nconst settingsCache: SiteSettingsCache =\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)\n\t(g[SITE_SETTINGS_CACHE_KEY] as SiteSettingsCache | undefined) ??\n\t(() => {\n\t\tconst c: SiteSettingsCache = {\n\t\t\tsnapshot: null,\n\t\t\texpiresAt: 0,\n\t\t\tgeneration: 0,\n\t\t\trevalidatingUntil: 0,\n\t\t\trefresh: createSingleFlightCache<CachedSiteSettings>(),\n\t\t};\n\t\tg[SITE_SETTINGS_CACHE_KEY] = c;\n\t\treturn c;\n\t})();\n\n/** Capture the resolved snapshot before route-cache headers are finalized. @internal */\nexport function peekSiteSettingsSnapshot(): CachedSiteSettings | null {\n\treturn settingsCache.snapshot;\n}\n\n/** Discard a snapshot found stale by the route-cache freshness check. @internal */\nexport function invalidateSiteSettingsSnapshot(): void {\n\tsettingsCache.generation++;\n\tsettingsCache.snapshot = null;\n\tsettingsCache.expiresAt = 0;\n\tsettingsCache.revalidatingUntil = 0;\n\tinvalidateSingleFlightCache(settingsCache.refresh);\n}\n\n/**\n * Bump the isolate-wide site-settings cache version, forcing the next\n * `getSiteSettings()` to re-query the database.\n *\n * Called from every `site:*` write path. Other isolates still serve their\n * own cached copy while a background refresh picks up remote writes.\n */\nexport function invalidateSiteSettingsCache(): void {\n\tinvalidateSiteSettingsSnapshot();\n\t// Cross-isolate invalidation for the optional distributed object cache.\n\tinvalidateObjectCache(SETTINGS_CACHE_NAMESPACE);\n}\n\n/**\n * Type guard for MediaReference values\n */\nfunction isMediaReference(value: unknown): value is MediaReference {\n\treturn typeof value === \"object\" && value !== null && \"mediaId\" in value;\n}\n\n/**\n * Resolve a media reference to include the full URL plus content metadata.\n *\n * Pulls `mimeType` and intrinsic dimensions from the media row so callers\n * can emit correct head tags (e.g. `<link rel=\"icon\" type=\"image/svg+xml\">`,\n * which Chromium requires when the URL has no `.svg` extension) without\n * a second round-trip to the media table.\n */\nasync function resolveMediaReference(\n\tmediaRef: MediaReference | undefined,\n\tdb: Kysely<Database>,\n\t_storage: Storage | null,\n): Promise<MediaReference | undefined> {\n\tif (!mediaRef?.mediaId) {\n\t\treturn mediaRef;\n\t}\n\n\ttry {\n\t\tconst mediaRepo = new MediaRepository(db);\n\t\tconst media = await mediaRepo.findById(mediaRef.mediaId);\n\n\t\tif (media) {\n\t\t\t// Construct URL using the same pattern as API handlers\n\t\t\treturn {\n\t\t\t\t...mediaRef,\n\t\t\t\turl: `/_emdash/api/media/file/${media.storageKey}`,\n\t\t\t\tcontentType: media.mimeType,\n\t\t\t\t...(media.width !== null ? { width: media.width } : {}),\n\t\t\t\t...(media.height !== null ? { height: media.height } : {}),\n\t\t\t};\n\t\t}\n\t} catch {\n\t\t// If media not found or error, return the reference as-is\n\t}\n\n\treturn mediaRef;\n}\n\n/**\n * Get a single site setting by key\n *\n * Returns `undefined` if the setting has not been configured.\n * For media settings (logo, favicon), the URL is resolved automatically.\n *\n * @param key - The setting key (e.g., \"title\", \"logo\", \"social\")\n * @returns The setting value, or undefined if not set\n *\n * @example\n * ```ts\n * import { getSiteSetting } from \"emdash\";\n *\n * const title = await getSiteSetting(\"title\");\n * const logo = await getSiteSetting(\"logo\");\n * console.log(logo?.url); // Resolved URL\n * ```\n */\nexport async function getSiteSetting<K extends SiteSettingKey>(\n\tkey: K,\n): Promise<SiteSettings[K] | undefined> {\n\t// If `getSiteSettings()` has already been called in this request,\n\t// read from that (request-cached) batch rather than firing a second\n\t// options-table query. Common layout: a Base template pulls the\n\t// whole settings object up-front, then `EmDashHead` or a plugin\n\t// asks for one key — no reason the singular call should round-trip\n\t// again.\n\tconst primed = peekRequestCache<Partial<SiteSettings>>(\"siteSettings\");\n\tif (primed) {\n\t\tconst settings = await primed;\n\t\treturn settings[key];\n\t}\n\n\t// Otherwise cache per-key. Templates that pull several settings\n\t// independently still share the in-flight query for each one.\n\treturn requestCached(`siteSetting:${key}`, async () => {\n\t\tconst db = await getDb();\n\t\treturn getSiteSettingWithDb(key, db);\n\t});\n}\n\n/**\n * Get a single site setting by key (with explicit db)\n *\n * @internal Use `getSiteSetting()` in templates. This variant is for admin routes\n * that already have a database handle.\n */\nexport async function getSiteSettingWithDb<K extends SiteSettingKey>(\n\tkey: K,\n\tdb: Kysely<Database>,\n\tstorage: Storage | null = null,\n): Promise<SiteSettings[K] | undefined> {\n\tconst options = new OptionsRepository(db);\n\tconst value = await options.get<SiteSettings[K]>(`${SETTINGS_PREFIX}${key}`);\n\n\tif (!value) {\n\t\treturn undefined;\n\t}\n\n\t// Resolve media references if needed.\n\t// TS cannot narrow generic K from key equality checks — this is a known limitation.\n\t// We use the non-generic getSiteSettingsWithDb for media resolution instead.\n\tif ((key === \"logo\" || key === \"favicon\") && isMediaReference(value)) {\n\t\tconst resolved = await resolveMediaReference(value, db, storage);\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- TS can't narrow generic K from key equality; resolved type is correct\n\t\treturn resolved as SiteSettings[K] | undefined;\n\t}\n\n\tif (key === \"seo\" && value && typeof value === \"object\") {\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- TS can't narrow generic K from key equality\n\t\tconst seo = value as SeoSettings;\n\t\tif (seo.defaultOgImage) {\n\t\t\tconst resolved = {\n\t\t\t\t...seo,\n\t\t\t\tdefaultOgImage: await resolveMediaReference(seo.defaultOgImage, db, storage),\n\t\t\t};\n\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- TS can't narrow generic K from key equality\n\t\t\treturn resolved as SiteSettings[K] | undefined;\n\t\t}\n\t}\n\n\treturn value;\n}\n\nfunction refreshSiteSettings(): Promise<CachedSiteSettings> {\n\treturn singleFlightCached(\n\t\tsettingsCache.refresh,\n\t\t() =>\n\t\t\tcachedQuery({\n\t\t\t\tnamespace: SETTINGS_CACHE_NAMESPACE,\n\t\t\t\tkey: \"snapshot-v1\",\n\t\t\t\tload: async () => loadSiteSettingsSnapshot(await getDb()),\n\t\t\t}),\n\t\t{ anchor: (promise) => after(() => promise), ownerTimeoutMs: 30_000 },\n\t);\n}\n\nfunction installSiteSettings(snapshot: CachedSiteSettings): void {\n\tsettingsCache.snapshot = snapshot;\n\tsettingsCache.expiresAt = Date.now() + SITE_SETTINGS_CACHE_TTL_MS;\n}\n\nfunction revalidateSiteSettings(): void {\n\tconst now = Date.now();\n\tif (settingsCache.revalidatingUntil > now) return;\n\tsettingsCache.revalidatingUntil = now + SITE_SETTINGS_CACHE_TTL_MS;\n\tconst generation = ++settingsCache.generation;\n\tinvalidateSingleFlightCache(settingsCache.refresh);\n\tafter(async () => {\n\t\ttry {\n\t\t\tconst snapshot = await refreshSiteSettings();\n\t\t\tif (generation === settingsCache.generation) installSiteSettings(snapshot);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[emdash:settings] revalidating site settings failed:\", error);\n\t\t}\n\t});\n}\n\nasync function loadCachedSiteSettings(): Promise<CachedSiteSettings> {\n\tfor (let attempt = 0; attempt < 3; attempt++) {\n\t\tconst snapshot = settingsCache.snapshot;\n\t\tif (snapshot) {\n\t\t\tif (Date.now() >= settingsCache.expiresAt) revalidateSiteSettings();\n\t\t\treturn snapshot;\n\t\t}\n\t\tconst generation = settingsCache.generation;\n\t\tconst loaded = await refreshSiteSettings();\n\t\tif (generation === settingsCache.generation) {\n\t\t\tinstallSiteSettings(loaded);\n\t\t\treturn loaded;\n\t\t}\n\t\tif (attempt === 2) return loaded;\n\t}\n\tthrow new Error(\"Site settings refresh exhausted without loading settings\");\n}\n\n/**\n * Get all site settings\n *\n * Returns all configured settings. Unset values are undefined.\n * Media references (logo/favicon) are resolved to include URLs.\n *\n * @example\n * ```ts\n * import { getSiteSettings } from \"emdash\";\n *\n * const settings = await getSiteSettings();\n * console.log(settings.title); // \"My Site\"\n * console.log(settings.logo?.url); // \"/_emdash/api/media/file/abc123\"\n * ```\n */\nexport function getSiteSettings(): Promise<Partial<SiteSettings>> {\n\treturn requestCached(\"siteSettings\", async () => {\n\t\tconst snapshot = await requestCached(\"siteSettingsSnapshot\", async () => {\n\t\t\tconst ctx = getRequestContext();\n\t\t\tconst requestSettings = ctx?.siteSettings;\n\t\t\tif (ctx?.routeCacheFill) return loadSiteSettingsSnapshot(await getDb());\n\t\t\tlet loaded = requestSettings?.snapshot ?? (await loadCachedSiteSettings());\n\t\t\t// A cold streamed component may join a load started before verification.\n\t\t\t// Reload an older result instead of streaming that snapshot into a fill.\n\t\t\tif (requestSettings?.version !== undefined && loaded.version !== requestSettings.version) {\n\t\t\t\tinvalidateSiteSettingsSnapshot();\n\t\t\t\tconst generation = settingsCache.generation;\n\t\t\t\tloaded = await loadSiteSettingsSnapshot(await getDb());\n\t\t\t\tif (generation === settingsCache.generation) installSiteSettings(loaded);\n\t\t\t}\n\t\t\treturn loaded;\n\t\t});\n\t\treturn snapshot.data;\n\t}).then(async (data) => {\n\t\tconst snapshot = await peekRequestCache<CachedSiteSettings>(\"siteSettingsSnapshot\");\n\t\tif (snapshot) getRequestContext()?.siteSettings?.onRead(snapshot.version);\n\t\treturn data;\n\t});\n}\n\n/**\n * Get all site settings with a Workers edge-cache hint.\n *\n * Use the returned `cacheHint` with `Astro.cache.set()` so pages that render\n * settings can be purged automatically when site settings change.\n */\nexport async function getSiteSettingsWithCacheHint(): Promise<{\n\tdata: Partial<SiteSettings>;\n\tcacheHint: CacheHint;\n}> {\n\tconst data = await getSiteSettings();\n\treturn { data, cacheHint: { tags: [siteSettingsTag()] } };\n}\n\n/**\n * Get all site settings (with explicit db)\n *\n * @internal Use `getSiteSettings()` in templates. This variant is for admin routes\n * that already have a database handle.\n */\nexport async function getSiteSettingsWithDb(\n\tdb: Kysely<Database>,\n\tstorage: Storage | null = null,\n): Promise<Partial<SiteSettings>> {\n\treturn (await loadSiteSettingsSnapshot(db, storage)).data;\n}\n\nasync function loadSiteSettingsSnapshot(\n\tdb: Kysely<Database>,\n\tstorage: Storage | null = null,\n): Promise<CachedSiteSettings> {\n\tconst options = new OptionsRepository(db);\n\tconst allOptions = await options.getVersionedByPrefix(SETTINGS_PREFIX);\n\tconst version = normalizeSiteSettingsVersion(\n\t\tJSON.stringify(\n\t\t\t[...allOptions]\n\t\t\t\t.filter(([key]) => key.startsWith(SETTINGS_PREFIX))\n\t\t\t\t.map(([key, value]) => [key, value.revision]),\n\t\t),\n\t);\n\tconst settings: Record<string, unknown> = {};\n\n\tfor (const [key, value] of allOptions) {\n\t\tconst settingKey = key.replace(SETTINGS_PREFIX, \"\");\n\t\tsettings[settingKey] = value.value;\n\t}\n\n\tconst typedSettings = settings as Partial<SiteSettings>;\n\n\t// Resolve media references\n\tif (typedSettings.logo) {\n\t\ttypedSettings.logo = await resolveMediaReference(typedSettings.logo, db, storage);\n\t}\n\tif (typedSettings.favicon) {\n\t\ttypedSettings.favicon = await resolveMediaReference(typedSettings.favicon, db, storage);\n\t}\n\tif (typedSettings.seo?.defaultOgImage) {\n\t\ttypedSettings.seo = {\n\t\t\t...typedSettings.seo,\n\t\t\tdefaultOgImage: await resolveMediaReference(typedSettings.seo.defaultOgImage, db, storage),\n\t\t};\n\t}\n\n\treturn { data: typedSettings, version };\n}\n\n/**\n * Set site settings (internal function used by admin API)\n *\n * Merges provided settings with existing ones. Only provided fields are updated,\n * including fields inside `seo` and `social`; `seo.defaultOgImage: null` removes the default image.\n * Media references should include just the mediaId; URLs are resolved on read.\n *\n * @param settings - Partial settings object with values to update\n * @param db - Kysely database instance\n * @returns Promise that resolves when settings are saved\n *\n * @internal\n *\n * @example\n * ```ts\n * // Update multiple settings at once\n * await setSiteSettings({\n * title: \"My Site\",\n * tagline: \"Welcome\",\n * logo: { mediaId: \"med_123\", alt: \"Logo\" }\n * }, db);\n * ```\n */\nexport async function setSiteSettings(\n\tsettings: SiteSettingsUpdate,\n\tdb: Kysely<Database>,\n): Promise<void> {\n\tconst updates: Record<string, unknown> = {};\n\tconst deletions: string[] = [];\n\tconst nestedPatches: [key: string, patch: Record<string, unknown>][] = [];\n\n\tfor (const [key, value] of Object.entries(settings)) {\n\t\tif (value === undefined) continue;\n\t\tif (value === null) deletions.push(`${SETTINGS_PREFIX}${key}`);\n\t\telse if (NESTED_SETTING_KEYS.has(key) && isRecord(value)) nestedPatches.push([key, value]);\n\t\telse updates[`${SETTINGS_PREFIX}${key}`] = value;\n\t}\n\n\tif (Object.keys(updates).length === 0 && deletions.length === 0 && nestedPatches.length === 0) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\tawait withTransaction(db, async (trx) => {\n\t\t\tconst transactionOptions = new OptionsRepository(trx);\n\t\t\tawait transactionOptions.setMany(updates);\n\t\t\tawait transactionOptions.deleteMany(deletions);\n\n\t\t\tfor (const [key, patch] of nestedPatches) {\n\t\t\t\tconst optionName = `${SETTINGS_PREFIX}${key}`;\n\t\t\t\tconst next = { ...(await transactionOptions.get<Record<string, unknown>>(optionName)) };\n\t\t\t\tfor (const [field, fieldValue] of Object.entries(patch)) {\n\t\t\t\t\tif (fieldValue === null) delete next[field];\n\t\t\t\t\telse if (fieldValue !== undefined) next[field] = fieldValue;\n\t\t\t\t}\n\t\t\t\tif (Object.keys(next).length === 0) await transactionOptions.delete(optionName);\n\t\t\t\telse await transactionOptions.set(optionName, next);\n\t\t\t}\n\n\t\t\t// A running export detects writes to tables without updated_at via\n\t\t\t// the operation's write_epoch. Record that bump in the same\n\t\t\t// transaction so the settings update is not accepted unless the\n\t\t\t// export fence can see it. When the transfer system has not been\n\t\t\t// installed yet (pre-migration, or a minimal seed fixture), there\n\t\t\t// is no running export to notify, so the absence of its table is\n\t\t\t// not a reason to reject the settings update.\n\t\t\ttry {\n\t\t\t\tawait bumpRunningExportWriteEpochs(trx);\n\t\t\t} catch (error) {\n\t\t\t\tif (isMissingTableError(error)) return;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t} finally {\n\t\tinvalidateSiteSettingsCache();\n\t}\n}\n\n/**\n * Get a single plugin setting by key.\n *\n * Plugin settings are stored in the options table under\n * `plugin:<pluginId>:settings:<key>`.\n */\nexport async function getPluginSetting<T = unknown>(\n\tpluginId: string,\n\tkey: string,\n): Promise<T | undefined> {\n\tconst db = await getDb();\n\treturn getPluginSettingWithDb<T>(pluginId, key, db);\n}\n\n/**\n * Get a single plugin setting by key (with explicit db).\n *\n * @internal Use `getPluginSetting()` in templates and plugin rendering code.\n */\nexport async function getPluginSettingWithDb<T = unknown>(\n\tpluginId: string,\n\tkey: string,\n\tdb: Kysely<Database>,\n): Promise<T | undefined> {\n\tconst options = new OptionsRepository(db);\n\tconst value = await options.get(`plugin:${pluginId}:settings:${key}`);\n\tif (value === null) return undefined;\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- caller supplies the expected plugin setting type\n\treturn (await decodePersistedPluginSetting(pluginId, key, value)) as T;\n}\n\n/**\n * Get all persisted plugin settings for a plugin.\n *\n * Defaults declared in `admin.settingsSchema` are not materialized\n * automatically; callers should apply their own fallback defaults.\n */\nexport async function getPluginSettings(pluginId: string): Promise<Record<string, unknown>> {\n\tconst db = await getDb();\n\treturn getPluginSettingsWithDb(pluginId, db);\n}\n\n/**\n * Get all persisted plugin settings for a plugin (with explicit db).\n *\n * @internal Use `getPluginSettings()` in templates and plugin rendering code.\n */\nexport async function getPluginSettingsWithDb(\n\tpluginId: string,\n\tdb: Kysely<Database>,\n): Promise<Record<string, unknown>> {\n\tconst prefix = `plugin:${pluginId}:settings:`;\n\tconst options = new OptionsRepository(db);\n\tconst allOptions = await options.getByPrefix(prefix);\n\n\tconst entries = [...allOptions].filter(([key]) => key.startsWith(prefix));\n\tconst encryptionKeys = entries.some(([, value]) => isEncryptedPluginSetting(value))\n\t\t? await resolvePluginEncryptionKeys()\n\t\t: undefined;\n\treturn Object.fromEntries(\n\t\tawait Promise.all(\n\t\t\tentries.map(async ([storedKey, value]) => {\n\t\t\t\tconst key = storedKey.slice(prefix.length);\n\t\t\t\treturn [\n\t\t\t\t\tkey,\n\t\t\t\t\tawait decodePersistedPluginSetting(pluginId, key, value, encryptionKeys),\n\t\t\t\t] as const;\n\t\t\t}),\n\t\t),\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAcA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,WAAW;AACjB,MAAM,iBAAiB;AACvB,MAAM,oBAAoB;AAC1B,MAAM,cAAc,IAAI,aAAa;AACrC,MAAM,cAAc,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,CAAC;AAU7D,IAAa,+BAAb,cAAkD,MAAM;CACvD,AAAkB,OAAO;CACzB,AAAS;CAMT,YAAY,MAA4C,SAAiB;AACxE,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,SAAgB,yBAAyB,OAAiD;AACzF,KAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,MAAM,CAAE,QAAO;AAChF,QACC,OAAO,KAAK,MAAM,CAAC,WAAW,KAC9B,aAAa,SACb,MAAM,YAAY,mBAClB,OAAO,SACP,MAAM,MAAM,oBACZ,SAAS,SACT,OAAO,MAAM,QAAQ,YACrB,eAAe,KAAK,MAAM,IAAI,IAC9B,QAAQ,SACR,OAAO,MAAM,OAAO,YACpB,kBAAkB,KAAK,MAAM,GAAG,IAChC,gBAAgB,SAChB,OAAO,MAAM,eAAe,YAC5B,kBAAkB,KAAK,MAAM,WAAW;;AAI1C,SAAS,eAAe,UAAkB,KAAyB;AAClE,QAAO,YAAY,OAClB,KAAK,UAAU;EAAC;EAAyB;EAAkB;EAAU;EAAI,CAAC,CAC1E;;AAGF,SAAS,YAAY,OAAgC;AACpD,QAAO,MAAM,OAAO,CAAC;;AAGtB,eAAe,oBAAoB,KAA0B,OAAqC;AACjG,QAAO,OAAO,OAAO,UAAU,OAAO,YAAY,IAAI,IAAI,EAAE,WAAW,OAAO,CAAC,MAAM,CAAC;;AAGvF,eAAe,cACd,MACwC;AACxC,QAAO,SAAS,SAAY,6BAA6B,GAAG;;AAG7D,eAAsB,qBACrB,UACA,KACA,OACA,MACkC;CAElC,MAAM,WADW,MAAM,cAAc,KAAK,IACf;AAC3B,KAAI,CAAC,QACJ,OAAM,IAAI,6BACT,yCACA,uDACA;AAGF,KAAI;EACH,MAAM,KAAK,OAAO,gBAAgB,IAAI,WAAW,SAAS,CAAC;EAC3D,MAAM,YAAY,MAAM,oBAAoB,SAAS,UAAU;EAC/D,MAAM,aAAa,MAAM,OAAO,OAAO,QACtC;GACC,MAAM;GACN,IAAI,YAAY,GAAG;GACnB,gBAAgB,YAAY,eAAe,UAAU,IAAI,CAAC;GAC1D,EACD,WACA,YAAY,YAAY,OAAO,MAAM,CAAC,CACtC;AACD,SAAO;GACN,SAAS;GACT,GAAG;GACH,KAAK,QAAQ;GACb,IAAI,gBAAgB,GAAG;GACvB,YAAY,gBAAgB,IAAI,WAAW,WAAW,CAAC;GACvD;UACO,OAAO;AACf,MAAI,iBAAiB,6BAA8B,OAAM;AACzD,QAAM,IAAI,6BACT,oCACA,+CACA;;;AAIH,eAAsB,qBACrB,UACA,KACA,UACA,MACkB;CAClB,MAAM,WAAW,MAAM,cAAc,KAAK;AAC1C,KAAI,CAAC,UAAU,OACd,OAAM,IAAI,6BACT,yCACA,sFACA;CAEF,MAAM,UAAU,SAAS,MAAM,cAAc,UAAU,QAAQ,SAAS,IAAI;AAC5E,KAAI,CAAC,QACJ,OAAM,IAAI,6BACT,yCACA,8DACA;AAGF,KAAI;EACH,MAAM,KAAK,gBAAgB,SAAS,GAAG;EACvC,MAAM,aAAa,gBAAgB,SAAS,WAAW;AACvD,MAAI,GAAG,eAAe,YAAY,WAAW,aAAa,GACzD,OAAM,IAAI,MAAM,mBAAmB;EACpC,MAAM,YAAY,MAAM,oBAAoB,SAAS,UAAU;EAC/D,MAAM,YAAY,MAAM,OAAO,OAAO,QACrC;GACC,MAAM;GACN,IAAI,YAAY,GAAG;GACnB,gBAAgB,YAAY,eAAe,UAAU,IAAI,CAAC;GAC1D,EACD,WACA,YAAY,WAAW,CACvB;AACD,SAAO,YAAY,OAAO,UAAU;SAC7B;AACP,QAAM,IAAI,6BACT,oCACA,+CACA;;;AAIH,SAAS,cAAc,QAAsC,KAAsB;AAClF,QAAO,OAAO,MAAM,SAAS;;AAG9B,eAAsB,yBACrB,UACA,KACA,OACA,QACA,MACA,UACmB;AACnB,KAAI,CAAC,cAAc,QAAQ,IAAI,CAAE,QAAO;AACxC,KAAI,OAAO,UAAU,SACpB,OAAM,IAAI,6BACT,oCACA,yCACA;AAEF,YAAW,KAAK,MAAM;AACtB,QAAO,qBAAqB,UAAU,KAAK,OAAO,KAAK;;AAGxD,eAAsB,yBACrB,UACA,KACA,OACA,QACA,MACA,UACa;AACb,KAAI,CAAC,cAAc,QAAQ,IAAI,EAAE;AAChC,MAAI,yBAAyB,MAAM,CAClC,OAAM,IAAI,6BACT,oCACA,uDACA;AAGF,SAAO;;AAER,KAAI,OAAO,UAAU,UAAU;AAC9B,aAAW,KAAK,MAAM;AAEtB,SAAO;;AAER,KAAI,CAAC,yBAAyB,MAAM,CACnC,OAAM,IAAI,6BACT,oCACA,0DACA;CAEF,MAAM,YAAY,MAAM,qBAAqB,UAAU,KAAK,OAAO,KAAK;AACxE,YAAW,KAAK,UAAU;AAE1B,QAAO;;AAGR,SAAgB,qBACf,aACA,UACA,SAAuC,EAAE,EACzC,MACA,UACiB;CACjB,MAAM,SAAS,UAAU,SAAS;CAClC,MAAM,aAAa,QAAgB;AAClC,mBAAiB,IAAI;AACrB,SAAO,GAAG,SAAS;;AAGpB,QAAO;EACN,MAAM,IAAO,KAAgC;GAC5C,MAAM,QAAQ,MAAM,YAAY,IAAI,UAAU,IAAI,CAAC;AACnD,UAAO,UAAU,OACd,OACA,yBAA4B,UAAU,KAAK,OAAO,QAAQ,MAAM,SAAS;;EAE7E,MAAM,aAAgB,KAAgD;GACrE,MAAM,QAAQ,MAAM,YAAY,aAAa,UAAU,IAAI,CAAC;AAC5D,OAAI,CAAC,MAAO,QAAO;AACnB,UAAO;IACN,OAAO,MAAM,yBACZ,UACA,KACA,MAAM,OACN,QACA,MACA,SACA;IACD,UAAU,MAAM;IAChB;;EAEF,MAAM,cACL,KACA,kBACA,OACkC;AAClC,UAAO,YAAY,cAClB,UAAU,IAAI,EACd,kBACA,MAAM,yBAAyB,UAAU,KAAK,OAAO,QAAQ,MAAM,SAAS,CAC5E;;EAEF,iBAAiB,KAAa,kBAA4D;AACzF,UAAO,YAAY,iBAAiB,UAAU,IAAI,EAAE,iBAAiB;;EAEtE,MAAM,IAAI,KAAa,OAA+B;AACrD,SAAM,YAAY,IACjB,UAAU,IAAI,EACd,MAAM,yBAAyB,UAAU,KAAK,OAAO,QAAQ,MAAM,SAAS,CAC5E;;EAEF,OAAO,KAA+B;AACrC,UAAO,YAAY,OAAO,UAAU,IAAI,CAAC;;EAE1C,MAAM,KAAK,YAAY,IAAqD;AAC3E,oBAAiB,aAAa,IAAI;GAClC,MAAM,SAAS,MAAM,YAAY,YAAY,GAAG,SAAS,YAAY;GACrE,MAAM,SAAiD,EAAE;AACzD,QAAK,MAAM,CAAC,SAAS,UAAU,QAAQ;IACtC,MAAM,MAAM,QAAQ,MAAM,OAAO,OAAO;AACxC,WAAO,KAAK;KACX;KACA,OAAO,MAAM,yBAAyB,UAAU,KAAK,OAAO,QAAQ,MAAM,SAAS;KACnF,CAAC;;AAEH,UAAO;;EAER;;;;;;AC9QF,MAAM,2BAA2B;;AAkBjC,MAAM,kBAAkB;;AAGxB,MAAM,sBAAsB,IAAI,IAAI,CAAC,OAAO,SAAS,CAAC;AAEtD,SAAS,8BAA8B,OAAkD;AACxF,QACC,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,MAAM,IACrB,aAAa,SACb,MAAM,YAAY;;AAIpB,eAAe,6BACd,UACA,KACA,OACA,gBACmB;AACnB,KAAI,yBAAyB,MAAM,CAClC,QAAO,qBAAqB,UAAU,KAAK,OAAO,eAAe;AAElE,KAAI,8BAA8B,MAAM,CACvC,OAAM,IAAI,6BACT,oCACA,0DACA;AAEF,QAAO;;AA8BR,MAAM,6BAA6B;AACnC,MAAM,0BAA0B,OAAO,IAAI,2BAA2B;AACtE,MAAM,IAAI;AACV,MAAM,gBAEJ,EAAE,mCACI;CACN,MAAM,IAAuB;EAC5B,UAAU;EACV,WAAW;EACX,YAAY;EACZ,mBAAmB;EACnB,SAAS,yBAA6C;EACtD;AACD,GAAE,2BAA2B;AAC7B,QAAO;IACJ;;AAGL,SAAgB,2BAAsD;AACrE,QAAO,cAAc;;;AAItB,SAAgB,iCAAuC;AACtD,eAAc;AACd,eAAc,WAAW;AACzB,eAAc,YAAY;AAC1B,eAAc,oBAAoB;AAClC,6BAA4B,cAAc,QAAQ;;;;;;;;;AAUnD,SAAgB,8BAAoC;AACnD,iCAAgC;AAEhC,uBAAsB,yBAAyB;;;;;AAMhD,SAAS,iBAAiB,OAAyC;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa;;;;;;;;;;AAWpE,eAAe,sBACd,UACA,IACA,UACsC;AACtC,KAAI,CAAC,UAAU,QACd,QAAO;AAGR,KAAI;EAEH,MAAM,QAAQ,MADI,IAAI,gBAAgB,GAAG,CACX,SAAS,SAAS,QAAQ;AAExD,MAAI,MAEH,QAAO;GACN,GAAG;GACH,KAAK,2BAA2B,MAAM;GACtC,aAAa,MAAM;GACnB,GAAI,MAAM,UAAU,OAAO,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;GACtD,GAAI,MAAM,WAAW,OAAO,EAAE,QAAQ,MAAM,QAAQ,GAAG,EAAE;GACzD;SAEK;AAIR,QAAO;;;;;;;;;;;;;;;;;;;;AAqBR,eAAsB,eACrB,KACuC;CAOvC,MAAM,SAAS,iBAAwC,eAAe;AACtE,KAAI,OAEH,SADiB,MAAM,QACP;AAKjB,QAAO,cAAc,eAAe,OAAO,YAAY;AAEtD,SAAO,qBAAqB,KADjB,MAAM,OAAO,CACY;GACnC;;;;;;;;AASH,eAAsB,qBACrB,KACA,IACA,UAA0B,MACa;CAEvC,MAAM,QAAQ,MADE,IAAI,kBAAkB,GAAG,CACb,IAAqB,GAAG,kBAAkB,MAAM;AAE5E,KAAI,CAAC,MACJ;AAMD,MAAK,QAAQ,UAAU,QAAQ,cAAc,iBAAiB,MAAM,CAGnE,QAFiB,MAAM,sBAAsB,OAAO,IAAI,QAAQ;AAKjE,KAAI,QAAQ,SAAS,SAAS,OAAO,UAAU,UAAU;EAExD,MAAM,MAAM;AACZ,MAAI,IAAI,eAMP,QALiB;GAChB,GAAG;GACH,gBAAgB,MAAM,sBAAsB,IAAI,gBAAgB,IAAI,QAAQ;GAC5E;;AAMH,QAAO;;AAGR,SAAS,sBAAmD;AAC3D,QAAO,mBACN,cAAc,eAEb,YAAY;EACX,WAAW;EACX,KAAK;EACL,MAAM,YAAY,yBAAyB,MAAM,OAAO,CAAC;EACzD,CAAC,EACH;EAAE,SAAS,YAAY,YAAY,QAAQ;EAAE,gBAAgB;EAAQ,CACrE;;AAGF,SAAS,oBAAoB,UAAoC;AAChE,eAAc,WAAW;AACzB,eAAc,YAAY,KAAK,KAAK,GAAG;;AAGxC,SAAS,yBAA+B;CACvC,MAAM,MAAM,KAAK,KAAK;AACtB,KAAI,cAAc,oBAAoB,IAAK;AAC3C,eAAc,oBAAoB,MAAM;CACxC,MAAM,aAAa,EAAE,cAAc;AACnC,6BAA4B,cAAc,QAAQ;AAClD,OAAM,YAAY;AACjB,MAAI;GACH,MAAM,WAAW,MAAM,qBAAqB;AAC5C,OAAI,eAAe,cAAc,WAAY,qBAAoB,SAAS;WAClE,OAAO;AACf,WAAQ,MAAM,wDAAwD,MAAM;;GAE5E;;AAGH,eAAe,yBAAsD;AACpE,MAAK,IAAI,UAAU,GAAG,UAAU,GAAG,WAAW;EAC7C,MAAM,WAAW,cAAc;AAC/B,MAAI,UAAU;AACb,OAAI,KAAK,KAAK,IAAI,cAAc,UAAW,yBAAwB;AACnE,UAAO;;EAER,MAAM,aAAa,cAAc;EACjC,MAAM,SAAS,MAAM,qBAAqB;AAC1C,MAAI,eAAe,cAAc,YAAY;AAC5C,uBAAoB,OAAO;AAC3B,UAAO;;AAER,MAAI,YAAY,EAAG,QAAO;;AAE3B,OAAM,IAAI,MAAM,2DAA2D;;;;;;;;;;;;;;;;;AAkB5E,SAAgB,kBAAkD;AACjE,QAAO,cAAc,gBAAgB,YAAY;AAgBhD,UAfiB,MAAM,cAAc,wBAAwB,YAAY;GACxE,MAAM,MAAM,mBAAmB;GAC/B,MAAM,kBAAkB,KAAK;AAC7B,OAAI,KAAK,eAAgB,QAAO,yBAAyB,MAAM,OAAO,CAAC;GACvE,IAAI,SAAS,iBAAiB,YAAa,MAAM,wBAAwB;AAGzE,OAAI,iBAAiB,YAAY,UAAa,OAAO,YAAY,gBAAgB,SAAS;AACzF,oCAAgC;IAChC,MAAM,aAAa,cAAc;AACjC,aAAS,MAAM,yBAAyB,MAAM,OAAO,CAAC;AACtD,QAAI,eAAe,cAAc,WAAY,qBAAoB,OAAO;;AAEzE,UAAO;IACN,EACc;GACf,CAAC,KAAK,OAAO,SAAS;EACvB,MAAM,WAAW,MAAM,iBAAqC,uBAAuB;AACnF,MAAI,SAAU,oBAAmB,EAAE,cAAc,OAAO,SAAS,QAAQ;AACzE,SAAO;GACN;;;;;;;;AASH,eAAsB,+BAGnB;AAEF,QAAO;EAAE,MADI,MAAM,iBAAiB;EACrB,WAAW,EAAE,MAAM,CAAC,iBAAiB,CAAC,EAAE;EAAE;;;;;;;;AAS1D,eAAsB,sBACrB,IACA,UAA0B,MACO;AACjC,SAAQ,MAAM,yBAAyB,IAAI,QAAQ,EAAE;;AAGtD,eAAe,yBACd,IACA,UAA0B,MACI;CAE9B,MAAM,aAAa,MADH,IAAI,kBAAkB,GAAG,CACR,qBAAqB,gBAAgB;CACtE,MAAM,UAAU,6BACf,KAAK,UACJ,CAAC,GAAG,WAAW,CACb,QAAQ,CAAC,SAAS,IAAI,WAAW,gBAAgB,CAAC,CAClD,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,MAAM,SAAS,CAAC,CAC9C,CACD;CACD,MAAM,WAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,KAAK,UAAU,YAAY;EACtC,MAAM,aAAa,IAAI,QAAQ,iBAAiB,GAAG;AACnD,WAAS,cAAc,MAAM;;CAG9B,MAAM,gBAAgB;AAGtB,KAAI,cAAc,KACjB,eAAc,OAAO,MAAM,sBAAsB,cAAc,MAAM,IAAI,QAAQ;AAElF,KAAI,cAAc,QACjB,eAAc,UAAU,MAAM,sBAAsB,cAAc,SAAS,IAAI,QAAQ;AAExF,KAAI,cAAc,KAAK,eACtB,eAAc,MAAM;EACnB,GAAG,cAAc;EACjB,gBAAgB,MAAM,sBAAsB,cAAc,IAAI,gBAAgB,IAAI,QAAQ;EAC1F;AAGF,QAAO;EAAE,MAAM;EAAe;EAAS;;;;;;;;;;;;;;;;;;;;;;;;;AA0BxC,eAAsB,gBACrB,UACA,IACgB;CAChB,MAAM,UAAmC,EAAE;CAC3C,MAAM,YAAsB,EAAE;CAC9B,MAAM,gBAAiE,EAAE;AAEzE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,EAAE;AACpD,MAAI,UAAU,OAAW;AACzB,MAAI,UAAU,KAAM,WAAU,KAAK,GAAG,kBAAkB,MAAM;WACrD,oBAAoB,IAAI,IAAI,IAAI,SAAS,MAAM,CAAE,eAAc,KAAK,CAAC,KAAK,MAAM,CAAC;MACrF,SAAQ,GAAG,kBAAkB,SAAS;;AAG5C,KAAI,OAAO,KAAK,QAAQ,CAAC,WAAW,KAAK,UAAU,WAAW,KAAK,cAAc,WAAW,EAC3F;AAGD,KAAI;AACH,QAAM,gBAAgB,IAAI,OAAO,QAAQ;GACxC,MAAM,qBAAqB,IAAI,kBAAkB,IAAI;AACrD,SAAM,mBAAmB,QAAQ,QAAQ;AACzC,SAAM,mBAAmB,WAAW,UAAU;AAE9C,QAAK,MAAM,CAAC,KAAK,UAAU,eAAe;IACzC,MAAM,aAAa,GAAG,kBAAkB;IACxC,MAAM,OAAO,EAAE,GAAI,MAAM,mBAAmB,IAA6B,WAAW,EAAG;AACvF,SAAK,MAAM,CAAC,OAAO,eAAe,OAAO,QAAQ,MAAM,CACtD,KAAI,eAAe,KAAM,QAAO,KAAK;aAC5B,eAAe,OAAW,MAAK,SAAS;AAElD,QAAI,OAAO,KAAK,KAAK,CAAC,WAAW,EAAG,OAAM,mBAAmB,OAAO,WAAW;QAC1E,OAAM,mBAAmB,IAAI,YAAY,KAAK;;AAUpD,OAAI;AACH,UAAM,6BAA6B,IAAI;YAC/B,OAAO;AACf,QAAI,oBAAoB,MAAM,CAAE;AAChC,UAAM;;IAEN;WACO;AACT,+BAA6B;;;;;;;;;AAU/B,eAAsB,iBACrB,UACA,KACyB;AAEzB,QAAO,uBAA0B,UAAU,KADhC,MAAM,OAAO,CAC2B;;;;;;;AAQpD,eAAsB,uBACrB,UACA,KACA,IACyB;CAEzB,MAAM,QAAQ,MADE,IAAI,kBAAkB,GAAG,CACb,IAAI,UAAU,SAAS,YAAY,MAAM;AACrE,KAAI,UAAU,KAAM,QAAO;AAE3B,QAAQ,MAAM,6BAA6B,UAAU,KAAK,MAAM;;;;;;;;AASjE,eAAsB,kBAAkB,UAAoD;AAE3F,QAAO,wBAAwB,UADpB,MAAM,OAAO,CACoB;;;;;;;AAQ7C,eAAsB,wBACrB,UACA,IACmC;CACnC,MAAM,SAAS,UAAU,SAAS;CAIlC,MAAM,UAAU,CAAC,GAFE,MADH,IAAI,kBAAkB,GAAG,CACR,YAAY,OAAO,CAErB,CAAC,QAAQ,CAAC,SAAS,IAAI,WAAW,OAAO,CAAC;CACzE,MAAM,iBAAiB,QAAQ,MAAM,GAAG,WAAW,yBAAyB,MAAM,CAAC,GAChF,MAAM,6BAA6B,GACnC;AACH,QAAO,OAAO,YACb,MAAM,QAAQ,IACb,QAAQ,IAAI,OAAO,CAAC,WAAW,WAAW;EACzC,MAAM,MAAM,UAAU,MAAM,OAAO,OAAO;AAC1C,SAAO,CACN,KACA,MAAM,6BAA6B,UAAU,KAAK,OAAO,eAAe,CACxE;GACA,CACF,CACD"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//#region src/transfer/format/settings.ts
|
|
2
|
+
/**
|
|
3
|
+
* Classification of `options` rows for site transfer.
|
|
4
|
+
*
|
|
5
|
+
* - `portable`: exported as `setting` records (explicit allowlist, never a
|
|
6
|
+
* prefix match).
|
|
7
|
+
* - `targetLocal`: belongs to the target installation and is never exported
|
|
8
|
+
* or overwritten by an import.
|
|
9
|
+
* - `excluded`: everything else (secrets, runtime state, plugin options).
|
|
10
|
+
*/
|
|
11
|
+
const PORTABLE_SETTING_NAMES = [
|
|
12
|
+
"emdash:locale",
|
|
13
|
+
"emdash:site_tagline",
|
|
14
|
+
"emdash:site_title",
|
|
15
|
+
"site:dateFormat",
|
|
16
|
+
"site:favicon",
|
|
17
|
+
"site:logo",
|
|
18
|
+
"site:postsPerPage",
|
|
19
|
+
"site:seo",
|
|
20
|
+
"site:social",
|
|
21
|
+
"site:tagline",
|
|
22
|
+
"site:timezone",
|
|
23
|
+
"site:title"
|
|
24
|
+
];
|
|
25
|
+
const PORTABLE_SETTINGS = new Set(PORTABLE_SETTING_NAMES);
|
|
26
|
+
const TARGET_LOCAL_SETTING_NAMES = new Set([
|
|
27
|
+
"site:url",
|
|
28
|
+
"emdash:site_url",
|
|
29
|
+
"emdash:site_id"
|
|
30
|
+
]);
|
|
31
|
+
const TARGET_LOCAL_SETTING_PREFIXES = ["emdash:setup_", "emdash:backups"];
|
|
32
|
+
/** Settings whose value is a plan decision rather than always taken from the package. */
|
|
33
|
+
const DECIDED_SETTING_NAMES = {
|
|
34
|
+
title: ["site:title", "emdash:site_title"],
|
|
35
|
+
tagline: ["site:tagline", "emdash:site_tagline"]
|
|
36
|
+
};
|
|
37
|
+
/** Options the importer resets after writing settings. */
|
|
38
|
+
const POST_IMPORT_OPTION_RESETS = {
|
|
39
|
+
bumpVersion: ["byline_fields_version"],
|
|
40
|
+
delete: ["_redirect_loop_ids"]
|
|
41
|
+
};
|
|
42
|
+
function isPortableSettingName(name) {
|
|
43
|
+
return PORTABLE_SETTINGS.has(name);
|
|
44
|
+
}
|
|
45
|
+
function classifySetting(name) {
|
|
46
|
+
if (PORTABLE_SETTINGS.has(name)) return "portable";
|
|
47
|
+
if (TARGET_LOCAL_SETTING_NAMES.has(name)) return "targetLocal";
|
|
48
|
+
if (TARGET_LOCAL_SETTING_PREFIXES.some((prefix) => name.startsWith(prefix))) return "targetLocal";
|
|
49
|
+
return "excluded";
|
|
50
|
+
}
|
|
51
|
+
/** Settings whose stored value is a `{ mediaId, alt? }` media reference, and where. */
|
|
52
|
+
const SETTING_MEDIA_REFERENCE_PATHS = Object.freeze({
|
|
53
|
+
"site:logo": [["mediaId"]],
|
|
54
|
+
"site:favicon": [["mediaId"]],
|
|
55
|
+
"site:seo": [["defaultOgImage", "mediaId"]]
|
|
56
|
+
});
|
|
57
|
+
/** Media ids referenced by a portable setting's value. */
|
|
58
|
+
function settingMediaIds(name, value) {
|
|
59
|
+
if (!isPortableSettingName(name)) return [];
|
|
60
|
+
const paths = SETTING_MEDIA_REFERENCE_PATHS[name];
|
|
61
|
+
if (!paths) return [];
|
|
62
|
+
const ids = [];
|
|
63
|
+
for (const path of paths) {
|
|
64
|
+
let current = value;
|
|
65
|
+
for (const segment of path) current = current !== null && typeof current === "object" && !Array.isArray(current) && Object.hasOwn(current, segment) ? Reflect.get(current, segment) : void 0;
|
|
66
|
+
if (typeof current === "string" && current.length > 0) ids.push(current);
|
|
67
|
+
}
|
|
68
|
+
return ids;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { settingMediaIds as a, classifySetting as i, PORTABLE_SETTING_NAMES as n, POST_IMPORT_OPTION_RESETS as r, DECIDED_SETTING_NAMES as t };
|
|
73
|
+
//# sourceMappingURL=settings-Dd1uivmQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-Dd1uivmQ.mjs","names":[],"sources":["../src/transfer/format/settings.ts"],"sourcesContent":["/**\n * Classification of `options` rows for site transfer.\n *\n * - `portable`: exported as `setting` records (explicit allowlist, never a\n * prefix match).\n * - `targetLocal`: belongs to the target installation and is never exported\n * or overwritten by an import.\n * - `excluded`: everything else (secrets, runtime state, plugin options).\n */\n\nexport const PORTABLE_SETTING_NAMES = [\n\t\"emdash:locale\",\n\t\"emdash:site_tagline\",\n\t\"emdash:site_title\",\n\t\"site:dateFormat\",\n\t\"site:favicon\",\n\t\"site:logo\",\n\t\"site:postsPerPage\",\n\t\"site:seo\",\n\t\"site:social\",\n\t\"site:tagline\",\n\t\"site:timezone\",\n\t\"site:title\",\n] as const;\n\nexport type PortableSettingName = (typeof PORTABLE_SETTING_NAMES)[number];\n\nconst PORTABLE_SETTINGS: ReadonlySet<string> = new Set(PORTABLE_SETTING_NAMES);\n\nconst TARGET_LOCAL_SETTING_NAMES: ReadonlySet<string> = new Set([\n\t\"site:url\",\n\t\"emdash:site_url\",\n\t\"emdash:site_id\",\n]);\n\nconst TARGET_LOCAL_SETTING_PREFIXES = [\"emdash:setup_\", \"emdash:backups\"] as const;\n\n/** Settings whose value is a plan decision rather than always taken from the package. */\nexport const DECIDED_SETTING_NAMES = {\n\ttitle: [\"site:title\", \"emdash:site_title\"],\n\ttagline: [\"site:tagline\", \"emdash:site_tagline\"],\n} as const satisfies Record<string, readonly PortableSettingName[]>;\n\n/** Options the importer resets after writing settings. */\nexport const POST_IMPORT_OPTION_RESETS = {\n\tbumpVersion: [\"byline_fields_version\"],\n\tdelete: [\"_redirect_loop_ids\"],\n} as const;\n\nexport type SettingClass = \"portable\" | \"targetLocal\" | \"excluded\";\n\nexport function isPortableSettingName(name: string): name is PortableSettingName {\n\treturn PORTABLE_SETTINGS.has(name);\n}\n\nexport function classifySetting(name: string): SettingClass {\n\tif (PORTABLE_SETTINGS.has(name)) return \"portable\";\n\tif (TARGET_LOCAL_SETTING_NAMES.has(name)) return \"targetLocal\";\n\tif (TARGET_LOCAL_SETTING_PREFIXES.some((prefix) => name.startsWith(prefix))) {\n\t\treturn \"targetLocal\";\n\t}\n\treturn \"excluded\";\n}\n\n/** Settings whose stored value is a `{ mediaId, alt? }` media reference, and where. */\nexport const SETTING_MEDIA_REFERENCE_PATHS: Readonly<\n\tPartial<Record<PortableSettingName, readonly (readonly string[])[]>>\n> = Object.freeze({\n\t\"site:logo\": [[\"mediaId\"]],\n\t\"site:favicon\": [[\"mediaId\"]],\n\t\"site:seo\": [[\"defaultOgImage\", \"mediaId\"]],\n});\n\n/** Media ids referenced by a portable setting's value. */\nexport function settingMediaIds(name: string, value: unknown): string[] {\n\tif (!isPortableSettingName(name)) return [];\n\tconst paths = SETTING_MEDIA_REFERENCE_PATHS[name];\n\tif (!paths) return [];\n\tconst ids: string[] = [];\n\tfor (const path of paths) {\n\t\tlet current: unknown = value;\n\t\tfor (const segment of path) {\n\t\t\tcurrent =\n\t\t\t\tcurrent !== null &&\n\t\t\t\ttypeof current === \"object\" &&\n\t\t\t\t!Array.isArray(current) &&\n\t\t\t\tObject.hasOwn(current, segment)\n\t\t\t\t\t? Reflect.get(current, segment)\n\t\t\t\t\t: undefined;\n\t\t}\n\t\tif (typeof current === \"string\" && current.length > 0) ids.push(current);\n\t}\n\treturn ids;\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,yBAAyB;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAID,MAAM,oBAAyC,IAAI,IAAI,uBAAuB;AAE9E,MAAM,6BAAkD,IAAI,IAAI;CAC/D;CACA;CACA;CACA,CAAC;AAEF,MAAM,gCAAgC,CAAC,iBAAiB,iBAAiB;;AAGzE,MAAa,wBAAwB;CACpC,OAAO,CAAC,cAAc,oBAAoB;CAC1C,SAAS,CAAC,gBAAgB,sBAAsB;CAChD;;AAGD,MAAa,4BAA4B;CACxC,aAAa,CAAC,wBAAwB;CACtC,QAAQ,CAAC,qBAAqB;CAC9B;AAID,SAAgB,sBAAsB,MAA2C;AAChF,QAAO,kBAAkB,IAAI,KAAK;;AAGnC,SAAgB,gBAAgB,MAA4B;AAC3D,KAAI,kBAAkB,IAAI,KAAK,CAAE,QAAO;AACxC,KAAI,2BAA2B,IAAI,KAAK,CAAE,QAAO;AACjD,KAAI,8BAA8B,MAAM,WAAW,KAAK,WAAW,OAAO,CAAC,CAC1E,QAAO;AAER,QAAO;;;AAIR,MAAa,gCAET,OAAO,OAAO;CACjB,aAAa,CAAC,CAAC,UAAU,CAAC;CAC1B,gBAAgB,CAAC,CAAC,UAAU,CAAC;CAC7B,YAAY,CAAC,CAAC,kBAAkB,UAAU,CAAC;CAC3C,CAAC;;AAGF,SAAgB,gBAAgB,MAAc,OAA0B;AACvE,KAAI,CAAC,sBAAsB,KAAK,CAAE,QAAO,EAAE;CAC3C,MAAM,QAAQ,8BAA8B;AAC5C,KAAI,CAAC,MAAO,QAAO,EAAE;CACrB,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,QAAQ,OAAO;EACzB,IAAI,UAAmB;AACvB,OAAK,MAAM,WAAW,KACrB,WACC,YAAY,QACZ,OAAO,YAAY,YACnB,CAAC,MAAM,QAAQ,QAAQ,IACvB,OAAO,OAAO,SAAS,QAAQ,GAC5B,QAAQ,IAAI,SAAS,QAAQ,GAC7B;AAEL,MAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,EAAG,KAAI,KAAK,QAAQ;;AAEzE,QAAO"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { u as isPostgres } from "./dialect-helpers-B1XN2HGB.mjs";
|
|
2
|
+
import { t as OptionsRepository } from "./options-DhrI7eMv.mjs";
|
|
3
|
+
import { sql } from "kysely";
|
|
4
|
+
import { ulid } from "ulidx";
|
|
5
|
+
import { Role } from "@emdash-cms/auth";
|
|
6
|
+
|
|
7
|
+
//#region src/api/setup-complete.ts
|
|
8
|
+
/**
|
|
9
|
+
* Shared setup completion logic.
|
|
10
|
+
*
|
|
11
|
+
* Called by OAuth callbacks and the passkey verify step when the first user
|
|
12
|
+
* is created during setup. Persists site title/tagline from setup state
|
|
13
|
+
* and marks setup as complete.
|
|
14
|
+
*/
|
|
15
|
+
const FIRST_ADMIN_LOCK_KEY = 1168624764;
|
|
16
|
+
/**
|
|
17
|
+
* Create the first admin only while the users table is empty.
|
|
18
|
+
*
|
|
19
|
+
* Returns null when a user already exists, including one created by a
|
|
20
|
+
* concurrent call after the caller's own zero-users check. On Postgres the
|
|
21
|
+
* insert runs under an advisory lock, because `NOT EXISTS` alone doesn't see
|
|
22
|
+
* another transaction's uncommitted row under READ COMMITTED.
|
|
23
|
+
*/
|
|
24
|
+
async function createFirstAdmin(db, input) {
|
|
25
|
+
const admin = {
|
|
26
|
+
id: ulid(),
|
|
27
|
+
email: input.email.toLowerCase(),
|
|
28
|
+
name: input.name,
|
|
29
|
+
role: Role.ADMIN
|
|
30
|
+
};
|
|
31
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
32
|
+
const insert = async (executor) => sql`
|
|
33
|
+
INSERT INTO users (id, email, name, role, email_verified, created_at, updated_at)
|
|
34
|
+
SELECT ${admin.id}, ${admin.email}, ${admin.name}, CAST(${admin.role} AS integer), 0, ${now}, ${now}
|
|
35
|
+
WHERE NOT EXISTS (SELECT 1 FROM users)
|
|
36
|
+
RETURNING id
|
|
37
|
+
`.execute(executor);
|
|
38
|
+
return (isPostgres(db) ? await db.transaction().execute(async (trx) => {
|
|
39
|
+
await sql`SELECT pg_advisory_xact_lock(${FIRST_ADMIN_LOCK_KEY})`.execute(trx);
|
|
40
|
+
return insert(trx);
|
|
41
|
+
}) : await insert(db)).rows.length > 0 ? admin : null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Finalize setup after the first admin user is created.
|
|
45
|
+
*
|
|
46
|
+
* Reads the setup_state option (written by the setup wizard's step 1),
|
|
47
|
+
* persists site_title and site_tagline, then marks setup complete.
|
|
48
|
+
*
|
|
49
|
+
* Safe to call multiple times — checks setup_complete first and no-ops
|
|
50
|
+
* if already done.
|
|
51
|
+
*/
|
|
52
|
+
async function finalizeSetup(db) {
|
|
53
|
+
const options = new OptionsRepository(db);
|
|
54
|
+
const setupComplete = await options.get("emdash:setup_complete");
|
|
55
|
+
if (setupComplete === true || setupComplete === "true") return;
|
|
56
|
+
const setupState = await options.get("emdash:setup_state");
|
|
57
|
+
if (setupState?.title && typeof setupState.title === "string") await options.set("emdash:site_title", setupState.title);
|
|
58
|
+
if (setupState?.tagline && typeof setupState.tagline === "string") await options.set("emdash:site_tagline", setupState.tagline);
|
|
59
|
+
await options.set("emdash:setup_complete", true);
|
|
60
|
+
await options.delete("emdash:setup_state");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { finalizeSetup as n, createFirstAdmin as t };
|
|
65
|
+
//# sourceMappingURL=setup-complete-qsJYWutC.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-complete-qsJYWutC.mjs","names":[],"sources":["../src/api/setup-complete.ts"],"sourcesContent":["/**\n * Shared setup completion logic.\n *\n * Called by OAuth callbacks and the passkey verify step when the first user\n * is created during setup. Persists site title/tagline from setup state\n * and marks setup as complete.\n */\n\nimport { Role } from \"@emdash-cms/auth\";\nimport { sql, type Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { isPostgres } from \"../database/dialect-helpers.js\";\nimport { OptionsRepository } from \"../database/repositories/options.js\";\nimport type { Database } from \"../database/types.js\";\n\nexport const FIRST_ADMIN_LOCK_KEY = 1_168_624_764;\n\nexport interface FirstAdmin {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\trole: typeof Role.ADMIN;\n}\n\n/**\n * Create the first admin only while the users table is empty.\n *\n * Returns null when a user already exists, including one created by a\n * concurrent call after the caller's own zero-users check. On Postgres the\n * insert runs under an advisory lock, because `NOT EXISTS` alone doesn't see\n * another transaction's uncommitted row under READ COMMITTED.\n */\nexport async function createFirstAdmin(\n\tdb: Kysely<Database>,\n\tinput: { email: string; name: string | null },\n): Promise<FirstAdmin | null> {\n\tconst admin: FirstAdmin = {\n\t\tid: ulid(),\n\t\temail: input.email.toLowerCase(),\n\t\tname: input.name,\n\t\trole: Role.ADMIN,\n\t};\n\tconst now = new Date().toISOString();\n\tconst insert = async (executor: Kysely<Database>) =>\n\t\tsql<{ id: string }>`\n\t\t\tINSERT INTO users (id, email, name, role, email_verified, created_at, updated_at)\n\t\t\tSELECT ${admin.id}, ${admin.email}, ${admin.name}, CAST(${admin.role} AS integer), 0, ${now}, ${now}\n\t\t\tWHERE NOT EXISTS (SELECT 1 FROM users)\n\t\t\tRETURNING id\n\t\t`.execute(executor);\n\n\tconst result = isPostgres(db)\n\t\t? await db.transaction().execute(async (trx) => {\n\t\t\t\tawait sql`SELECT pg_advisory_xact_lock(${FIRST_ADMIN_LOCK_KEY})`.execute(trx);\n\t\t\t\treturn insert(trx);\n\t\t\t})\n\t\t: await insert(db);\n\treturn result.rows.length > 0 ? admin : null;\n}\n\n/**\n * Finalize setup after the first admin user is created.\n *\n * Reads the setup_state option (written by the setup wizard's step 1),\n * persists site_title and site_tagline, then marks setup complete.\n *\n * Safe to call multiple times — checks setup_complete first and no-ops\n * if already done.\n */\nexport async function finalizeSetup(db: Kysely<Database>): Promise<void> {\n\tconst options = new OptionsRepository(db);\n\n\tconst setupComplete = await options.get(\"emdash:setup_complete\");\n\tif (setupComplete === true || setupComplete === \"true\") return;\n\n\t// Persist site title/tagline from setup state (stored in step 1)\n\tconst setupState = await options.get<Record<string, unknown>>(\"emdash:setup_state\");\n\tif (setupState?.title && typeof setupState.title === \"string\") {\n\t\tawait options.set(\"emdash:site_title\", setupState.title);\n\t}\n\tif (setupState?.tagline && typeof setupState.tagline === \"string\") {\n\t\tawait options.set(\"emdash:site_tagline\", setupState.tagline);\n\t}\n\n\tawait options.set(\"emdash:setup_complete\", true);\n\tawait options.delete(\"emdash:setup_state\");\n}\n"],"mappings":";;;;;;;;;;;;;;AAgBA,MAAa,uBAAuB;;;;;;;;;AAiBpC,eAAsB,iBACrB,IACA,OAC6B;CAC7B,MAAM,QAAoB;EACzB,IAAI,MAAM;EACV,OAAO,MAAM,MAAM,aAAa;EAChC,MAAM,MAAM;EACZ,MAAM,KAAK;EACX;CACD,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;CACpC,MAAM,SAAS,OAAO,aACrB,GAAmB;;YAET,MAAM,GAAG,IAAI,MAAM,MAAM,IAAI,MAAM,KAAK,SAAS,MAAM,KAAK,mBAAmB,IAAI,IAAI,IAAI;;;IAGnG,QAAQ,SAAS;AAQpB,SANe,WAAW,GAAG,GAC1B,MAAM,GAAG,aAAa,CAAC,QAAQ,OAAO,QAAQ;AAC9C,QAAM,GAAG,gCAAgC,qBAAqB,GAAG,QAAQ,IAAI;AAC7E,SAAO,OAAO,IAAI;GACjB,GACD,MAAM,OAAO,GAAG,EACL,KAAK,SAAS,IAAI,QAAQ;;;;;;;;;;;AAYzC,eAAsB,cAAc,IAAqC;CACxE,MAAM,UAAU,IAAI,kBAAkB,GAAG;CAEzC,MAAM,gBAAgB,MAAM,QAAQ,IAAI,wBAAwB;AAChE,KAAI,kBAAkB,QAAQ,kBAAkB,OAAQ;CAGxD,MAAM,aAAa,MAAM,QAAQ,IAA6B,qBAAqB;AACnF,KAAI,YAAY,SAAS,OAAO,WAAW,UAAU,SACpD,OAAM,QAAQ,IAAI,qBAAqB,WAAW,MAAM;AAEzD,KAAI,YAAY,WAAW,OAAO,WAAW,YAAY,SACxD,OAAM,QAAQ,IAAI,uBAAuB,WAAW,QAAQ;AAG7D,OAAM,QAAQ,IAAI,yBAAyB,KAAK;AAChD,OAAM,QAAQ,OAAO,qBAAqB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/auth/setup-nonce.ts
|
|
2
|
+
/**
|
|
3
|
+
* Session binding for the first-setup admin-creation flow.
|
|
4
|
+
*
|
|
5
|
+
* Shared constants for the nonce cookie that ties /_emdash/api/setup/admin
|
|
6
|
+
* and /_emdash/api/setup/admin/verify to the same browser. Without this
|
|
7
|
+
* binding, any unauthenticated caller could POST /setup/admin during the
|
|
8
|
+
* setup window and substitute their own email into the stored setup state
|
|
9
|
+
* before the legitimate admin completes passkey verification.
|
|
10
|
+
*
|
|
11
|
+
* Implementation lives in the two route handlers; this module is just
|
|
12
|
+
* the name / lifetime so both ends agree.
|
|
13
|
+
*/
|
|
14
|
+
/** Cookie name carrying the setup-admin session nonce. */
|
|
15
|
+
const SETUP_NONCE_COOKIE = "emdash_setup_nonce";
|
|
16
|
+
/**
|
|
17
|
+
* Cookie max-age in seconds. One hour is plenty of time to complete
|
|
18
|
+
* a passkey registration; if the user lingers longer the admin step
|
|
19
|
+
* can simply be retried.
|
|
20
|
+
*/
|
|
21
|
+
const SETUP_NONCE_MAX_AGE_SECONDS = 3600;
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { SETUP_NONCE_MAX_AGE_SECONDS as n, SETUP_NONCE_COOKIE as t };
|
|
25
|
+
//# sourceMappingURL=setup-nonce-CBFgUFXw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-nonce-CBFgUFXw.mjs","names":[],"sources":["../src/auth/setup-nonce.ts"],"sourcesContent":["/**\n * Session binding for the first-setup admin-creation flow.\n *\n * Shared constants for the nonce cookie that ties /_emdash/api/setup/admin\n * and /_emdash/api/setup/admin/verify to the same browser. Without this\n * binding, any unauthenticated caller could POST /setup/admin during the\n * setup window and substitute their own email into the stored setup state\n * before the legitimate admin completes passkey verification.\n *\n * Implementation lives in the two route handlers; this module is just\n * the name / lifetime so both ends agree.\n */\n\n/** Cookie name carrying the setup-admin session nonce. */\nexport const SETUP_NONCE_COOKIE = \"emdash_setup_nonce\";\n\n/**\n * Cookie max-age in seconds. One hour is plenty of time to complete\n * a passkey registration; if the user lingers longer the admin step\n * can simply be retried.\n */\nexport const SETUP_NONCE_MAX_AGE_SECONDS = 60 * 60;\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,qBAAqB;;;;;;AAOlC,MAAa,8BAA8B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { t as OptionsRepository } from "./options-DhrI7eMv.mjs";
|
|
2
|
+
import { a as encodeBase64url } from "./base64-BQBZwXCx.mjs";
|
|
3
|
+
import { d as setSiteSettings } from "./settings-D932YP2-.mjs";
|
|
4
|
+
import { r as resolveAndValidateExternalUrl } from "./ssrf-BcYjyM4M.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/api/handlers/site-domain.ts
|
|
7
|
+
const DOMAIN_PROOF_PATH = "/_emdash/api/site/domain-proof";
|
|
8
|
+
const PROOF_OPTION = "emdash:domain_proof";
|
|
9
|
+
const PROOF_TTL_MS = 6e4;
|
|
10
|
+
const CHECK_TIMEOUT_MS = 1e4;
|
|
11
|
+
const IPV4_RE = /^\d{1,3}(\.\d{1,3}){3}$/;
|
|
12
|
+
/**
|
|
13
|
+
* Parse a bare hostname or an `https://` origin into an origin. Paths,
|
|
14
|
+
* ports, credentials, IP addresses, and single-label hosts are rejected.
|
|
15
|
+
*/
|
|
16
|
+
function parseSiteDomain(input) {
|
|
17
|
+
const trimmed = input.trim();
|
|
18
|
+
const candidate = trimmed.includes("://") ? trimmed : `https://${trimmed}`;
|
|
19
|
+
if (!URL.canParse(candidate)) return void 0;
|
|
20
|
+
const url = new URL(candidate);
|
|
21
|
+
if (url.protocol !== "https:") return void 0;
|
|
22
|
+
if (url.username || url.password || url.port || url.search || url.hash) return void 0;
|
|
23
|
+
if (url.pathname !== "/") return void 0;
|
|
24
|
+
const host = url.hostname;
|
|
25
|
+
if (!host.includes(".") || host.endsWith(".") || host.startsWith("[") || IPV4_RE.test(host)) return;
|
|
26
|
+
return url.origin;
|
|
27
|
+
}
|
|
28
|
+
function checkFailed(message, details) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
error: {
|
|
32
|
+
code: "DOMAIN_CHECK_FAILED",
|
|
33
|
+
message,
|
|
34
|
+
details
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Verify that `input` serves this site and store it as the Site URL.
|
|
40
|
+
*/
|
|
41
|
+
async function handleSiteDomainChange(db, input) {
|
|
42
|
+
const origin = parseSiteDomain(input);
|
|
43
|
+
if (!origin) return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: {
|
|
46
|
+
code: "VALIDATION_ERROR",
|
|
47
|
+
message: "Enter a domain such as example.com, without a path or port"
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const options = new OptionsRepository(db);
|
|
51
|
+
const token = encodeBase64url(crypto.getRandomValues(new Uint8Array(24)));
|
|
52
|
+
const proof = {
|
|
53
|
+
token,
|
|
54
|
+
expiresAt: Date.now() + PROOF_TTL_MS
|
|
55
|
+
};
|
|
56
|
+
const revision = await options.setVersioned(PROOF_OPTION, proof);
|
|
57
|
+
try {
|
|
58
|
+
const proofUrl = `${origin}${DOMAIN_PROOF_PATH}`;
|
|
59
|
+
try {
|
|
60
|
+
await resolveAndValidateExternalUrl(proofUrl);
|
|
61
|
+
} catch {
|
|
62
|
+
const host = new URL(origin).hostname;
|
|
63
|
+
return checkFailed(`${host} does not resolve to a public address`, {
|
|
64
|
+
reason: "NO_PUBLIC_ADDRESS",
|
|
65
|
+
host
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
let response;
|
|
69
|
+
try {
|
|
70
|
+
response = await fetch(proofUrl, {
|
|
71
|
+
method: "POST",
|
|
72
|
+
redirect: "manual",
|
|
73
|
+
headers: {
|
|
74
|
+
Accept: "application/json",
|
|
75
|
+
"X-EmDash-Request": "1"
|
|
76
|
+
},
|
|
77
|
+
signal: AbortSignal.timeout(CHECK_TIMEOUT_MS)
|
|
78
|
+
});
|
|
79
|
+
} catch {
|
|
80
|
+
return checkFailed(`Could not reach ${origin}`, {
|
|
81
|
+
reason: "UNREACHABLE",
|
|
82
|
+
origin
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (response.status >= 300 && response.status < 400) {
|
|
86
|
+
const location = response.headers.get("Location");
|
|
87
|
+
const target = location && URL.canParse(location, proofUrl) ? new URL(location, proofUrl) : null;
|
|
88
|
+
return target ? checkFailed(`${origin} redirects to ${target.origin}. Enter that address instead.`, {
|
|
89
|
+
reason: "REDIRECT",
|
|
90
|
+
origin,
|
|
91
|
+
target: target.origin
|
|
92
|
+
}) : checkFailed(`${origin} redirects elsewhere`, {
|
|
93
|
+
reason: "REDIRECT",
|
|
94
|
+
origin
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const body = response.ok ? await response.json().catch(() => null) : null;
|
|
98
|
+
if ((body && typeof body === "object" && "data" in body && body.data && typeof body.data === "object" ? body.data.token : void 0) !== token) return checkFailed(`${origin} does not serve this site yet`, {
|
|
99
|
+
reason: "NOT_SERVING",
|
|
100
|
+
origin
|
|
101
|
+
});
|
|
102
|
+
await setSiteSettings({ url: origin }, db);
|
|
103
|
+
return {
|
|
104
|
+
success: true,
|
|
105
|
+
data: { url: origin }
|
|
106
|
+
};
|
|
107
|
+
} finally {
|
|
108
|
+
await db.deleteFrom("options").where("name", "=", PROOF_OPTION).where("revision", "=", revision).execute();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return the pending domain proof token, if a check is in progress.
|
|
113
|
+
*/
|
|
114
|
+
async function handleDomainProof(db) {
|
|
115
|
+
const proof = await new OptionsRepository(db).get(PROOF_OPTION);
|
|
116
|
+
if (!proof || typeof proof.token !== "string" || proof.expiresAt < Date.now()) return {
|
|
117
|
+
success: false,
|
|
118
|
+
error: {
|
|
119
|
+
code: "NOT_FOUND",
|
|
120
|
+
message: "No domain check in progress"
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
data: { token: proof.token }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { handleSiteDomainChange as n, handleDomainProof as t };
|
|
131
|
+
//# sourceMappingURL=site-domain-oRGS_JfA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-domain-oRGS_JfA.mjs","names":[],"sources":["../src/api/handlers/site-domain.ts"],"sourcesContent":["/**\n * Site domain handlers\n *\n * Changing the site's domain stores the new origin as the Site URL, which\n * links in emails and plugins, sitemaps, and absolute URLs in search and\n * social metadata use. Before it is stored, EmDash fetches a one-time token\n * from the new domain to prove the domain serves this site.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { OptionsRepository } from \"../../database/repositories/options.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { resolveAndValidateExternalUrl } from \"../../security/ssrf.js\";\nimport { setSiteSettings } from \"../../settings/index.js\";\nimport { encodeBase64url } from \"../../utils/base64.js\";\nimport type { ApiResult } from \"../types.js\";\n\nexport const DOMAIN_PROOF_PATH = \"/_emdash/api/site/domain-proof\";\n\nconst PROOF_OPTION = \"emdash:domain_proof\";\nconst PROOF_TTL_MS = 60_000;\nconst CHECK_TIMEOUT_MS = 10_000;\nconst IPV4_RE = /^\\d{1,3}(\\.\\d{1,3}){3}$/;\n\ninterface DomainProof {\n\ttoken: string;\n\texpiresAt: number;\n}\n\n/**\n * Parse a bare hostname or an `https://` origin into an origin. Paths,\n * ports, credentials, IP addresses, and single-label hosts are rejected.\n */\nexport function parseSiteDomain(input: string): string | undefined {\n\tconst trimmed = input.trim();\n\tconst candidate = trimmed.includes(\"://\") ? trimmed : `https://${trimmed}`;\n\tif (!URL.canParse(candidate)) return undefined;\n\tconst url = new URL(candidate);\n\tif (url.protocol !== \"https:\") return undefined;\n\tif (url.username || url.password || url.port || url.search || url.hash) return undefined;\n\tif (url.pathname !== \"/\") return undefined;\n\tconst host = url.hostname;\n\tif (!host.includes(\".\") || host.endsWith(\".\") || host.startsWith(\"[\") || IPV4_RE.test(host)) {\n\t\treturn undefined;\n\t}\n\treturn url.origin;\n}\n\n/** Why a domain check failed, sent as `error.details` with the addresses its message names. */\ntype DomainCheckFailure =\n\t| { reason: \"NO_PUBLIC_ADDRESS\"; host: string }\n\t| { reason: \"UNREACHABLE\"; origin: string }\n\t| { reason: \"REDIRECT\"; origin: string; target?: string }\n\t| { reason: \"NOT_SERVING\"; origin: string };\n\nfunction checkFailed(message: string, details: DomainCheckFailure): ApiResult<never> {\n\treturn { success: false, error: { code: \"DOMAIN_CHECK_FAILED\", message, details } };\n}\n\n/**\n * Verify that `input` serves this site and store it as the Site URL.\n */\nexport async function handleSiteDomainChange(\n\tdb: Kysely<Database>,\n\tinput: string,\n): Promise<ApiResult<{ url: string }>> {\n\tconst origin = parseSiteDomain(input);\n\tif (!origin) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\tmessage: \"Enter a domain such as example.com, without a path or port\",\n\t\t\t},\n\t\t};\n\t}\n\n\tconst options = new OptionsRepository(db);\n\tconst token = encodeBase64url(crypto.getRandomValues(new Uint8Array(24)));\n\tconst proof: DomainProof = { token, expiresAt: Date.now() + PROOF_TTL_MS };\n\tconst revision = await options.setVersioned(PROOF_OPTION, proof);\n\n\ttry {\n\t\tconst proofUrl = `${origin}${DOMAIN_PROOF_PATH}`;\n\t\ttry {\n\t\t\tawait resolveAndValidateExternalUrl(proofUrl);\n\t\t} catch {\n\t\t\tconst host = new URL(origin).hostname;\n\t\t\treturn checkFailed(`${host} does not resolve to a public address`, {\n\t\t\t\treason: \"NO_PUBLIC_ADDRESS\",\n\t\t\t\thost,\n\t\t\t});\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(proofUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tredirect: \"manual\",\n\t\t\t\theaders: { Accept: \"application/json\", \"X-EmDash-Request\": \"1\" },\n\t\t\t\tsignal: AbortSignal.timeout(CHECK_TIMEOUT_MS),\n\t\t\t});\n\t\t} catch {\n\t\t\treturn checkFailed(`Could not reach ${origin}`, { reason: \"UNREACHABLE\", origin });\n\t\t}\n\n\t\tif (response.status >= 300 && response.status < 400) {\n\t\t\tconst location = response.headers.get(\"Location\");\n\t\t\tconst target =\n\t\t\t\tlocation && URL.canParse(location, proofUrl) ? new URL(location, proofUrl) : null;\n\t\t\treturn target\n\t\t\t\t? checkFailed(`${origin} redirects to ${target.origin}. Enter that address instead.`, {\n\t\t\t\t\t\treason: \"REDIRECT\",\n\t\t\t\t\t\torigin,\n\t\t\t\t\t\ttarget: target.origin,\n\t\t\t\t\t})\n\t\t\t\t: checkFailed(`${origin} redirects elsewhere`, { reason: \"REDIRECT\", origin });\n\t\t}\n\n\t\tconst body: unknown = response.ok ? await response.json().catch(() => null) : null;\n\t\tconst received =\n\t\t\tbody &&\n\t\t\ttypeof body === \"object\" &&\n\t\t\t\"data\" in body &&\n\t\t\tbody.data &&\n\t\t\ttypeof body.data === \"object\"\n\t\t\t\t? (body.data as { token?: unknown }).token\n\t\t\t\t: undefined;\n\t\tif (received !== token) {\n\t\t\treturn checkFailed(`${origin} does not serve this site yet`, {\n\t\t\t\treason: \"NOT_SERVING\",\n\t\t\t\torigin,\n\t\t\t});\n\t\t}\n\n\t\tawait setSiteSettings({ url: origin }, db);\n\t\treturn { success: true, data: { url: origin } };\n\t} finally {\n\t\tawait db\n\t\t\t.deleteFrom(\"options\")\n\t\t\t.where(\"name\", \"=\", PROOF_OPTION)\n\t\t\t.where(\"revision\", \"=\", revision)\n\t\t\t.execute();\n\t}\n}\n\n/**\n * Return the pending domain proof token, if a check is in progress.\n */\nexport async function handleDomainProof(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<{ token: string }>> {\n\tconst proof = await new OptionsRepository(db).get<DomainProof>(PROOF_OPTION);\n\tif (!proof || typeof proof.token !== \"string\" || proof.expiresAt < Date.now()) {\n\t\treturn { success: false, error: { code: \"NOT_FOUND\", message: \"No domain check in progress\" } };\n\t}\n\treturn { success: true, data: { token: proof.token } };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { a as settingMediaIds } from "./settings-Dd1uivmQ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/media/usage/site-settings.ts
|
|
4
|
+
/**
|
|
5
|
+
* Media references held by site settings.
|
|
6
|
+
*
|
|
7
|
+
* Usage reads parse these from the stored `site:*` options on every read, so
|
|
8
|
+
* a change through any writer of those options shows up on the next read.
|
|
9
|
+
*/
|
|
10
|
+
const MEDIA_USAGE_SITE_SETTINGS = [
|
|
11
|
+
"logo",
|
|
12
|
+
"favicon",
|
|
13
|
+
"seo.defaultOgImage"
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* One setting per option, which holds while each option has a single path in
|
|
17
|
+
* `SETTING_MEDIA_REFERENCE_PATHS`. A second path needs a setting of its own.
|
|
18
|
+
*/
|
|
19
|
+
const SITE_SETTING_OPTIONS = [
|
|
20
|
+
["site:logo", "logo"],
|
|
21
|
+
["site:favicon", "favicon"],
|
|
22
|
+
["site:seo", "seo.defaultOgImage"]
|
|
23
|
+
];
|
|
24
|
+
const MEDIA_USAGE_SITE_SETTING_OPTIONS = SITE_SETTING_OPTIONS.map(([option]) => option);
|
|
25
|
+
/**
|
|
26
|
+
* Group the site settings that select each media item, in settings order.
|
|
27
|
+
*
|
|
28
|
+
* @param options Raw JSON option values keyed by option name.
|
|
29
|
+
*/
|
|
30
|
+
function groupSiteSettingMediaUsage(options) {
|
|
31
|
+
const usage = /* @__PURE__ */ new Map();
|
|
32
|
+
for (const [option, setting] of SITE_SETTING_OPTIONS) for (const mediaId of settingMediaIds(option, parseOption(options.get(option)))) {
|
|
33
|
+
const settings = usage.get(mediaId);
|
|
34
|
+
if (settings) settings.push(setting);
|
|
35
|
+
else usage.set(mediaId, [setting]);
|
|
36
|
+
}
|
|
37
|
+
return usage;
|
|
38
|
+
}
|
|
39
|
+
function parseOption(value) {
|
|
40
|
+
if (value == null) return void 0;
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(value);
|
|
43
|
+
} catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { MEDIA_USAGE_SITE_SETTING_OPTIONS as n, groupSiteSettingMediaUsage as r, MEDIA_USAGE_SITE_SETTINGS as t };
|
|
50
|
+
//# sourceMappingURL=site-settings-DRHfX7bq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-settings-DRHfX7bq.mjs","names":[],"sources":["../src/media/usage/site-settings.ts"],"sourcesContent":["/**\n * Media references held by site settings.\n *\n * Usage reads parse these from the stored `site:*` options on every read, so\n * a change through any writer of those options shows up on the next read.\n */\n\nimport { settingMediaIds, type PortableSettingName } from \"../../transfer/format/settings.js\";\n\nexport const MEDIA_USAGE_SITE_SETTINGS = [\"logo\", \"favicon\", \"seo.defaultOgImage\"] as const;\n\nexport type MediaUsageSiteSetting = (typeof MEDIA_USAGE_SITE_SETTINGS)[number];\n\n/**\n * One setting per option, which holds while each option has a single path in\n * `SETTING_MEDIA_REFERENCE_PATHS`. A second path needs a setting of its own.\n */\nconst SITE_SETTING_OPTIONS = [\n\t[\"site:logo\", \"logo\"],\n\t[\"site:favicon\", \"favicon\"],\n\t[\"site:seo\", \"seo.defaultOgImage\"],\n] as const satisfies readonly (readonly [PortableSettingName, MediaUsageSiteSetting])[];\n\nexport const MEDIA_USAGE_SITE_SETTING_OPTIONS = SITE_SETTING_OPTIONS.map(([option]) => option);\n\n/**\n * Group the site settings that select each media item, in settings order.\n *\n * @param options Raw JSON option values keyed by option name.\n */\nexport function groupSiteSettingMediaUsage(\n\toptions: ReadonlyMap<string, string | null>,\n): Map<string, MediaUsageSiteSetting[]> {\n\tconst usage = new Map<string, MediaUsageSiteSetting[]>();\n\tfor (const [option, setting] of SITE_SETTING_OPTIONS) {\n\t\tfor (const mediaId of settingMediaIds(option, parseOption(options.get(option)))) {\n\t\t\tconst settings = usage.get(mediaId);\n\t\t\tif (settings) settings.push(setting);\n\t\t\telse usage.set(mediaId, [setting]);\n\t\t}\n\t}\n\treturn usage;\n}\n\nfunction parseOption(value: string | null | undefined): unknown {\n\tif (value == null) return undefined;\n\ttry {\n\t\treturn JSON.parse(value);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,4BAA4B;CAAC;CAAQ;CAAW;CAAqB;;;;;AAQlF,MAAM,uBAAuB;CAC5B,CAAC,aAAa,OAAO;CACrB,CAAC,gBAAgB,UAAU;CAC3B,CAAC,YAAY,qBAAqB;CAClC;AAED,MAAa,mCAAmC,qBAAqB,KAAK,CAAC,YAAY,OAAO;;;;;;AAO9F,SAAgB,2BACf,SACuC;CACvC,MAAM,wBAAQ,IAAI,KAAsC;AACxD,MAAK,MAAM,CAAC,QAAQ,YAAY,qBAC/B,MAAK,MAAM,WAAW,gBAAgB,QAAQ,YAAY,QAAQ,IAAI,OAAO,CAAC,CAAC,EAAE;EAChF,MAAM,WAAW,MAAM,IAAI,QAAQ;AACnC,MAAI,SAAU,UAAS,KAAK,QAAQ;MAC/B,OAAM,IAAI,SAAS,CAAC,QAAQ,CAAC;;AAGpC,QAAO;;AAGR,SAAS,YAAY,OAA2C;AAC/D,KAAI,SAAS,KAAM,QAAO;AAC1B,KAAI;AACH,SAAO,KAAK,MAAM,MAAM;SACjB;AACP"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { t as OptionsRepository } from "./options-DhrI7eMv.mjs";
|
|
2
|
+
import { t as getConfiguredOrigin } from "./public-url-Bt98vysr.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/api/site-url.ts
|
|
5
|
+
const LOOPBACK_HOSTS = new Set([
|
|
6
|
+
"localhost",
|
|
7
|
+
"127.0.0.1",
|
|
8
|
+
"[::1]"
|
|
9
|
+
]);
|
|
10
|
+
/** Sign-in tokens travel in these links, so plain HTTP is only accepted for loopback hosts. */
|
|
11
|
+
function siteUrlSettingOrigin(value) {
|
|
12
|
+
if (typeof value !== "string" || !URL.canParse(value)) return void 0;
|
|
13
|
+
const url = new URL(value);
|
|
14
|
+
if (url.protocol === "https:") return url.origin;
|
|
15
|
+
if (url.protocol === "http:" && LOOPBACK_HOSTS.has(url.hostname)) return url.origin;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The site's public origin for outbound links, in the precedence order
|
|
19
|
+
* described above. `siteUrlSetting` and `setupUrl` are the stored
|
|
20
|
+
* `site:url` and `emdash:site_url` option values.
|
|
21
|
+
*/
|
|
22
|
+
function resolveSiteOrigin(config, siteUrlSetting, setupUrl) {
|
|
23
|
+
return getConfiguredOrigin(config) ?? siteUrlSettingOrigin(siteUrlSetting) ?? (typeof setupUrl === "string" && setupUrl ? setupUrl : void 0);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The origin chosen for the site: the configured origin, then the **Site URL**.
|
|
27
|
+
* Unlike `getSiteBaseUrl`, it never falls back to the origin recorded during
|
|
28
|
+
* setup, which may be an address the site has since moved away from.
|
|
29
|
+
*/
|
|
30
|
+
async function getChosenSiteOrigin(db, config) {
|
|
31
|
+
return getConfiguredOrigin(config) ?? siteUrlSettingOrigin(await new OptionsRepository(db).get("site:url"));
|
|
32
|
+
}
|
|
33
|
+
async function getSiteBaseUrl(db, request, config) {
|
|
34
|
+
const configured = getConfiguredOrigin(config);
|
|
35
|
+
if (configured) return `${configured}/_emdash`;
|
|
36
|
+
const stored = await new OptionsRepository(db).getMany(["site:url", "emdash:site_url"]);
|
|
37
|
+
const storedUrl = resolveSiteOrigin(config, stored.get("site:url"), stored.get("emdash:site_url"));
|
|
38
|
+
if (storedUrl) return `${storedUrl}/_emdash`;
|
|
39
|
+
const url = new URL(request.url);
|
|
40
|
+
return `${url.protocol}//${url.host}/_emdash`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { getSiteBaseUrl as n, resolveSiteOrigin as r, getChosenSiteOrigin as t };
|
|
45
|
+
//# sourceMappingURL=site-url-MB685I5X.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-url-MB685I5X.mjs","names":[],"sources":["../src/api/site-url.ts"],"sourcesContent":["/**\n * Resolve the canonical site base URL for use in outbound links (emails, etc.).\n *\n * Precedence: the operator-configured origin (`config.siteUrl`, then the\n * `EMDASH_SITE_URL`/`SITE_URL` env vars), then the **Site URL** an admin set\n * in Settings > General (`site:url`, origin only), then the `emdash:site_url` option\n * written once during setup, and only before setup completes the request URL.\n * A configured or stored value always beats the request, so Host header\n * spoofing cannot redirect users to attacker-controlled domains.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { OptionsRepository } from \"../database/repositories/options.js\";\nimport type { Database } from \"../database/types.js\";\nimport { getConfiguredOrigin, type SiteUrlConfig } from \"./public-url.js\";\n\nconst LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/** Sign-in tokens travel in these links, so plain HTTP is only accepted for loopback hosts. */\nfunction siteUrlSettingOrigin(value: unknown): string | undefined {\n\tif (typeof value !== \"string\" || !URL.canParse(value)) return undefined;\n\tconst url = new URL(value);\n\tif (url.protocol === \"https:\") return url.origin;\n\tif (url.protocol === \"http:\" && LOOPBACK_HOSTS.has(url.hostname)) return url.origin;\n\treturn undefined;\n}\n\n/**\n * The site's public origin for outbound links, in the precedence order\n * described above. `siteUrlSetting` and `setupUrl` are the stored\n * `site:url` and `emdash:site_url` option values.\n */\nexport function resolveSiteOrigin(\n\tconfig: SiteUrlConfig | undefined,\n\tsiteUrlSetting: unknown,\n\tsetupUrl: unknown,\n): string | undefined {\n\treturn (\n\t\tgetConfiguredOrigin(config) ??\n\t\tsiteUrlSettingOrigin(siteUrlSetting) ??\n\t\t(typeof setupUrl === \"string\" && setupUrl ? setupUrl : undefined)\n\t);\n}\n\n/**\n * The origin chosen for the site: the configured origin, then the **Site URL**.\n * Unlike `getSiteBaseUrl`, it never falls back to the origin recorded during\n * setup, which may be an address the site has since moved away from.\n */\nexport async function getChosenSiteOrigin(\n\tdb: Kysely<Database>,\n\tconfig?: SiteUrlConfig,\n): Promise<string | undefined> {\n\treturn (\n\t\tgetConfiguredOrigin(config) ??\n\t\tsiteUrlSettingOrigin(await new OptionsRepository(db).get(\"site:url\"))\n\t);\n}\n\nexport async function getSiteBaseUrl(\n\tdb: Kysely<Database>,\n\trequest: Request,\n\tconfig?: SiteUrlConfig,\n): Promise<string> {\n\tconst configured = getConfiguredOrigin(config);\n\tif (configured) {\n\t\treturn `${configured}/_emdash`;\n\t}\n\tconst options = new OptionsRepository(db);\n\tconst stored = await options.getMany([\"site:url\", \"emdash:site_url\"]);\n\tconst storedUrl = resolveSiteOrigin(\n\t\tconfig,\n\t\tstored.get(\"site:url\"),\n\t\tstored.get(\"emdash:site_url\"),\n\t);\n\tif (storedUrl) {\n\t\treturn `${storedUrl}/_emdash`;\n\t}\n\t// Fallback: derive from request (only reached before setup completes)\n\tconst url = new URL(request.url);\n\treturn `${url.protocol}//${url.host}/_emdash`;\n}\n"],"mappings":";;;;AAiBA,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAa;CAAa;CAAQ,CAAC;;AAGnE,SAAS,qBAAqB,OAAoC;AACjE,KAAI,OAAO,UAAU,YAAY,CAAC,IAAI,SAAS,MAAM,CAAE,QAAO;CAC9D,MAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,KAAI,IAAI,aAAa,SAAU,QAAO,IAAI;AAC1C,KAAI,IAAI,aAAa,WAAW,eAAe,IAAI,IAAI,SAAS,CAAE,QAAO,IAAI;;;;;;;AAS9E,SAAgB,kBACf,QACA,gBACA,UACqB;AACrB,QACC,oBAAoB,OAAO,IAC3B,qBAAqB,eAAe,KACnC,OAAO,aAAa,YAAY,WAAW,WAAW;;;;;;;AASzD,eAAsB,oBACrB,IACA,QAC8B;AAC9B,QACC,oBAAoB,OAAO,IAC3B,qBAAqB,MAAM,IAAI,kBAAkB,GAAG,CAAC,IAAI,WAAW,CAAC;;AAIvE,eAAsB,eACrB,IACA,SACA,QACkB;CAClB,MAAM,aAAa,oBAAoB,OAAO;AAC9C,KAAI,WACH,QAAO,GAAG,WAAW;CAGtB,MAAM,SAAS,MADC,IAAI,kBAAkB,GAAG,CACZ,QAAQ,CAAC,YAAY,kBAAkB,CAAC;CACrE,MAAM,YAAY,kBACjB,QACA,OAAO,IAAI,WAAW,EACtB,OAAO,IAAI,kBAAkB,CAC7B;AACD,KAAI,UACH,QAAO,GAAG,UAAU;CAGrB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;AAChC,QAAO,GAAG,IAAI,SAAS,IAAI,IAAI,KAAK"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { r as isValidSchemaSlug } from "./slug-aVnUV4SL.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/seo/sitemap-name.ts
|
|
4
|
+
/**
|
|
5
|
+
* The `{name}` in a per-collection sitemap path, `/sitemap-{name}.xml`.
|
|
6
|
+
*/
|
|
7
|
+
/** `{collection}` for page 1, `{collection}-{n}` for page n from 2 up. */
|
|
8
|
+
const SITEMAP_NAME_RE = /^([a-z][a-z0-9_]*)(?:-([2-9]|[1-9]\d{1,5}))?$/;
|
|
9
|
+
/**
|
|
10
|
+
* The collection and page a sitemap name refers to, or null when the name
|
|
11
|
+
* can't belong to any collection (its collection part must be a valid
|
|
12
|
+
* collection slug).
|
|
13
|
+
*/
|
|
14
|
+
function parseCollectionSitemapName(name) {
|
|
15
|
+
const match = SITEMAP_NAME_RE.exec(name);
|
|
16
|
+
const collection = match?.[1];
|
|
17
|
+
if (!match || !isValidSchemaSlug(collection)) return null;
|
|
18
|
+
return {
|
|
19
|
+
collection,
|
|
20
|
+
page: match[2] ? Number(match[2]) : 1
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
export { parseCollectionSitemapName as t };
|
|
26
|
+
//# sourceMappingURL=sitemap-name-B8QP8wud.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sitemap-name-B8QP8wud.mjs","names":[],"sources":["../src/seo/sitemap-name.ts"],"sourcesContent":["/**\n * The `{name}` in a per-collection sitemap path, `/sitemap-{name}.xml`.\n */\n\nimport { isValidSchemaSlug } from \"../schema/slug.js\";\n\n/** `{collection}` for page 1, `{collection}-{n}` for page n from 2 up. */\nconst SITEMAP_NAME_RE = /^([a-z][a-z0-9_]*)(?:-([2-9]|[1-9]\\d{1,5}))?$/;\n\n/**\n * The collection and page a sitemap name refers to, or null when the name\n * can't belong to any collection (its collection part must be a valid\n * collection slug).\n */\nexport function parseCollectionSitemapName(\n\tname: string,\n): { collection: string; page: number } | null {\n\tconst match = SITEMAP_NAME_RE.exec(name);\n\tconst collection = match?.[1];\n\tif (!match || !isValidSchemaSlug(collection)) return null;\n\treturn { collection, page: match[2] ? Number(match[2]) : 1 };\n}\n"],"mappings":";;;;;;;AAOA,MAAM,kBAAkB;;;;;;AAOxB,SAAgB,2BACf,MAC8C;CAC9C,MAAM,QAAQ,gBAAgB,KAAK,KAAK;CACxC,MAAM,aAAa,QAAQ;AAC3B,KAAI,CAAC,SAAS,CAAC,kBAAkB,WAAW,CAAE,QAAO;AACrD,QAAO;EAAE;EAAY,MAAM,MAAM,KAAK,OAAO,MAAM,GAAG,GAAG;EAAG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/schema/slug.ts
|
|
2
|
+
/**
|
|
3
|
+
* The collection and field slug rule.
|
|
4
|
+
*/
|
|
5
|
+
/** Lowercase letter first, then lowercase letters, digits, and underscores. */
|
|
6
|
+
const SCHEMA_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
7
|
+
/** Maximum length of a collection or field slug. */
|
|
8
|
+
const MAX_SCHEMA_SLUG_LENGTH = 63;
|
|
9
|
+
/** Whether `value` is a valid collection or field slug. */
|
|
10
|
+
function isValidSchemaSlug(value) {
|
|
11
|
+
return typeof value === "string" && value.length > 0 && value.length <= MAX_SCHEMA_SLUG_LENGTH && SCHEMA_SLUG_PATTERN.test(value);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { SCHEMA_SLUG_PATTERN as n, isValidSchemaSlug as r, MAX_SCHEMA_SLUG_LENGTH as t };
|
|
16
|
+
//# sourceMappingURL=slug-aVnUV4SL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug-aVnUV4SL.mjs","names":[],"sources":["../src/schema/slug.ts"],"sourcesContent":["/**\n * The collection and field slug rule.\n */\n\n/** Lowercase letter first, then lowercase letters, digits, and underscores. */\nexport const SCHEMA_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;\n\n/** Maximum length of a collection or field slug. */\nexport const MAX_SCHEMA_SLUG_LENGTH = 63;\n\n/** Whether `value` is a valid collection or field slug. */\nexport function isValidSchemaSlug(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.length > 0 &&\n\t\tvalue.length <= MAX_SCHEMA_SLUG_LENGTH &&\n\t\tSCHEMA_SLUG_PATTERN.test(value)\n\t);\n}\n"],"mappings":";;;;;AAKA,MAAa,sBAAsB;;AAGnC,MAAa,yBAAyB;;AAGtC,SAAgB,kBAAkB,OAAiC;AAClE,QACC,OAAO,UAAU,YACjB,MAAM,SAAS,KACf,MAAM,UAAU,0BAChB,oBAAoB,KAAK,MAAM"}
|