emdash 0.36.0 → 0.38.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/{activation-K0kGBWuJ.mjs → activation-DyNTe_Tl.mjs} +3 -3
- package/dist/{activation-K0kGBWuJ.mjs.map → activation-DyNTe_Tl.mjs.map} +1 -1
- package/dist/{adapters-CzL3H752.d.mts → adapters-DCEgOBXi.d.mts} +4 -2
- package/dist/{adapters-CzL3H752.d.mts.map → adapters-DCEgOBXi.d.mts.map} +1 -1
- package/dist/{allowed-origins-maylGaHv.mjs → allowed-origins-GFUVavRj.mjs} +2 -2
- package/dist/{allowed-origins-maylGaHv.mjs.map → allowed-origins-GFUVavRj.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +25 -24
- package/dist/api/route-utils.mjs.map +1 -1
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -5
- package/dist/api-BvxJmnFY.mjs +10094 -0
- package/dist/api-BvxJmnFY.mjs.map +1 -0
- package/dist/{api-tokens-9YrrCoE6.mjs → api-tokens-xpGqMHrC.mjs} +2 -2
- package/dist/{api-tokens-9YrrCoE6.mjs.map → api-tokens-xpGqMHrC.mjs.map} +1 -1
- package/dist/{apply-B_VMpJ2P.mjs → apply-DLmM3R7f.mjs} +26 -22
- package/dist/apply-DLmM3R7f.mjs.map +1 -0
- package/dist/artifact-fetch-P2JXVwOq.mjs +972 -0
- package/dist/artifact-fetch-P2JXVwOq.mjs.map +1 -0
- package/dist/astro/image-endpoint.mjs +2 -2
- package/dist/astro/image-endpoint.mjs.map +1 -1
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +138 -39
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.mjs +6 -6
- package/dist/astro/middleware/media-usage-write-fence.mjs +3 -3
- package/dist/astro/middleware/redirect.mjs +7 -5
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +10 -10
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +223 -232
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +6 -6
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +6 -6
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/api-tokens/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +4 -4
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +9 -9
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +9 -9
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +9 -9
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -17
- package/dist/astro/routes/api/admin/bylines/index.mjs +17 -17
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -13
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +10 -10
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +13 -13
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +15 -15
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +15 -15
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +14 -14
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +17 -17
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +15 -15
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +15 -15
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +59 -56
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +59 -56
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +57 -54
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +57 -54
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +58 -55
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +58 -55
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +57 -54
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +57 -54
- 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 +58 -55
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +57 -54
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +58 -55
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +64 -57
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +18 -16
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +65 -58
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/verify.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +96 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/updates.mjs +57 -54
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +57 -54
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +57 -54
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +6 -6
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +6 -6
- package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +11 -11
- package/dist/astro/routes/api/auth/invite/index.mjs +8 -8
- package/dist/astro/routes/api/auth/invite/register-options.mjs +10 -10
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +10 -10
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +7 -7
- package/dist/astro/routes/api/auth/mode.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +6 -6
- package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +12 -12
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/verify.mjs +11 -11
- package/dist/astro/routes/api/auth/signup/complete.mjs +11 -11
- package/dist/astro/routes/api/auth/signup/request.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -14
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +19 -5
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/lock.d.mts +10 -0
- package/dist/astro/routes/api/content/_collection_/_id_/lock.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +66 -0
- package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -0
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -10
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +20 -18
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +20 -18
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +15 -8
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +16 -15
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +19 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +23 -11
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/index.mjs +14 -9
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -7
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +2 -2
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +15 -14
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +18 -18
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +29 -28
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +213 -74
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +11 -11
- package/dist/astro/routes/api/media/_id_/replace.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/replace.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/replace.mjs +91 -0
- package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
- package/dist/astro/routes/api/media/_id_/usage.mjs +19 -19
- package/dist/astro/routes/api/media/_id_.mjs +18 -18
- package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +3 -2
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/folders/_id_.mjs +8 -8
- package/dist/astro/routes/api/media/folders/index.mjs +8 -8
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
- package/dist/astro/routes/api/media/providers/index.mjs +2 -2
- package/dist/astro/routes/api/media/upload-url.mjs +16 -14
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +53 -30
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +20 -13
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +15 -11
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +15 -11
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +16 -12
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +21 -14
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.d.mts.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +15 -11
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +5 -5
- package/dist/astro/routes/api/oauth/device/code.mjs +8 -8
- package/dist/astro/routes/api/oauth/device/token.mjs +7 -7
- package/dist/astro/routes/api/oauth/register.mjs +2 -2
- package/dist/astro/routes/api/oauth/token/refresh.mjs +5 -5
- package/dist/astro/routes/api/oauth/token/revoke.mjs +5 -5
- package/dist/astro/routes/api/oauth/token.mjs +5 -5
- package/dist/astro/routes/api/openapi.json.mjs +184 -52
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
- package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +13 -12
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +20 -18
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +15 -13
- package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/relations/index.mjs +20 -18
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +57 -54
- 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 +57 -54
- 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 +57 -54
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +57 -54
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +57 -54
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.mjs +57 -54
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +13 -11
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +57 -54
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +57 -54
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +12 -11
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +11 -10
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +12 -11
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +7 -6
- package/dist/astro/routes/api/search/stats.mjs.map +1 -1
- package/dist/astro/routes/api/search/suggest.mjs +11 -10
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +11 -10
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +11 -10
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -6
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +6 -5
- package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -6
- package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -7
- package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings/email.mjs.map +1 -1
- package/dist/astro/routes/api/settings.d.mts.map +1 -1
- package/dist/astro/routes/api/settings.mjs +21 -17
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +12 -12
- package/dist/astro/routes/api/setup/admin.mjs +11 -11
- package/dist/astro/routes/api/setup/dev-bypass.mjs +35 -33
- package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +35 -33
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +8 -7
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +22 -17
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +23 -18
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +27 -19
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +22 -17
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +16 -15
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.mjs +28 -20
- package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +22 -17
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +5 -5
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- 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 +10 -8
- 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 +18 -14
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +16 -13
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +9 -7
- package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/index.mjs +16 -13
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +8 -8
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -12
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +9 -9
- package/dist/astro/types.d.mts +50 -20
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-ByYs-Uxs.mjs → authorize-C2QHlWSS.mjs} +2 -2
- package/dist/{authorize-ByYs-Uxs.mjs.map → authorize-C2QHlWSS.mjs.map} +1 -1
- package/dist/{backup-ChyHfIoX.mjs → backup-oS8ft5Cm.mjs} +5 -5
- package/dist/{backup-ChyHfIoX.mjs.map → backup-oS8ft5Cm.mjs.map} +1 -1
- package/dist/{bundle-DZFhFurR.mjs → bundle-CL0JjIPx.mjs} +4 -4
- package/dist/{bundle-DZFhFurR.mjs.map → bundle-CL0JjIPx.mjs.map} +1 -1
- package/dist/{byline-Cpnwrje1.mjs → byline-Vdi85CsZ.mjs} +27 -14
- package/dist/byline-Vdi85CsZ.mjs.map +1 -0
- package/dist/{byline-fields-CAyA_Umd.mjs → byline-fields-DPVRFMz2.mjs} +2 -2
- package/dist/{byline-fields-CAyA_Umd.mjs.map → byline-fields-DPVRFMz2.mjs.map} +1 -1
- package/dist/{byline-registry-Bpu9-MVs.mjs → byline-registry-BxDGIO0I.mjs} +2 -2
- package/dist/{byline-registry-Bpu9-MVs.mjs.map → byline-registry-BxDGIO0I.mjs.map} +1 -1
- package/dist/{bylines-BSo9B9RX.mjs → bylines-BX8QhcTk.mjs} +7 -7
- package/dist/{bylines-BSo9B9RX.mjs.map → bylines-BX8QhcTk.mjs.map} +1 -1
- package/dist/{bylines-CHjvehVX.mjs → bylines-w-E1IEQd.mjs} +3 -3
- package/dist/{bylines-CHjvehVX.mjs.map → bylines-w-E1IEQd.mjs.map} +1 -1
- package/dist/{cache-5VirJ2Cn.mjs → cache--7HKu5Xm.mjs} +4 -4
- package/dist/{cache-5VirJ2Cn.mjs.map → cache--7HKu5Xm.mjs.map} +1 -1
- package/dist/{capture-triggers-CNW1q3HK.mjs → capture-triggers-CeAsC76Z.mjs} +2 -2
- package/dist/{capture-triggers-CNW1q3HK.mjs.map → capture-triggers-CeAsC76Z.mjs.map} +1 -1
- package/dist/{challenge-store-D5pSY2S1.mjs → challenge-store-BIOak-tp.mjs} +5 -3
- package/dist/challenge-store-BIOak-tp.mjs.map +1 -0
- package/dist/chrome-tags-DzDQBCjX.mjs +24 -0
- package/dist/chrome-tags-DzDQBCjX.mjs.map +1 -0
- package/dist/{chunks-bNiX6_DR.mjs → chunks-VG_tyqnP.mjs} +2 -2
- package/dist/{chunks-bNiX6_DR.mjs.map → chunks-VG_tyqnP.mjs.map} +1 -1
- package/dist/cli/index.mjs +68 -40
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +17 -7
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +17 -12
- package/dist/client/index.mjs.map +1 -1
- package/dist/{collection-deletion-m_oi2c0N.mjs → collection-deletion-BCwaWTDw.mjs} +4 -4
- package/dist/{collection-deletion-m_oi2c0N.mjs.map → collection-deletion-BCwaWTDw.mjs.map} +1 -1
- package/dist/collection-slugs-cache-7lTmNzeA.mjs +85 -0
- package/dist/collection-slugs-cache-7lTmNzeA.mjs.map +1 -0
- package/dist/{comment-reaction-CRuItEjt.mjs → comment-reaction-CDyvPQRj.mjs} +2 -2
- package/dist/{comment-reaction-CRuItEjt.mjs.map → comment-reaction-CDyvPQRj.mjs.map} +1 -1
- package/dist/{comment-DhvLEdhQ.mjs → comment-vxOzWbZN.mjs} +2 -2
- package/dist/{comment-DhvLEdhQ.mjs.map → comment-vxOzWbZN.mjs.map} +1 -1
- package/dist/{comments-CLj4bi8I.mjs → comments-VzmVLyaC.mjs} +2 -2
- package/dist/{comments-CLj4bi8I.mjs.map → comments-VzmVLyaC.mjs.map} +1 -1
- package/dist/{components-v4U4DT2y.mjs → components-CL6Wkdk-.mjs} +1 -1
- package/dist/{components-v4U4DT2y.mjs.map → components-CL6Wkdk-.mjs.map} +1 -1
- package/dist/config--eWjQJE5.mjs +217 -0
- package/dist/config--eWjQJE5.mjs.map +1 -0
- package/dist/{index-DWbJrsAg.d.mts → config-CGAhyOjP.d.mts} +276 -76
- package/dist/config-CGAhyOjP.d.mts.map +1 -0
- package/dist/{config-DrfghTPe.d.mts → config-ChFzshGd.d.mts} +1 -1
- package/dist/{config-DrfghTPe.d.mts.map → config-ChFzshGd.d.mts.map} +1 -1
- package/dist/{content-CP-SeXNa.mjs → content-CNfMWuhY.mjs} +202 -46
- package/dist/content-CNfMWuhY.mjs.map +1 -0
- package/dist/{content-list-query-BhejKVqb.d.mts → content-list-query-B8d4UQp9.d.mts} +1 -1
- package/dist/{content-list-query-BhejKVqb.d.mts.map → content-list-query-B8d4UQp9.d.mts.map} +1 -1
- package/dist/{content-refresh-DLOfIhYc.mjs → content-refresh-GTMyi2Xy.mjs} +53 -26
- package/dist/content-refresh-GTMyi2Xy.mjs.map +1 -0
- package/dist/{content-repair-BCxzy0r4.mjs → content-repair-CIMt5C0U.mjs} +4 -4
- package/dist/{content-repair-BCxzy0r4.mjs.map → content-repair-CIMt5C0U.mjs.map} +1 -1
- package/dist/{context-BR5hRWiK.mjs → context-C9PB8vGd.mjs} +308 -33
- package/dist/context-C9PB8vGd.mjs.map +1 -0
- package/dist/{cron-CWfWrWKG.mjs → cron-DHAy9oyq.mjs} +1 -1
- package/dist/{cron-CWfWrWKG.mjs.map → cron-DHAy9oyq.mjs.map} +1 -1
- package/dist/{dashboard-CkIV2rnQ.mjs → dashboard-BNSvAN8A.mjs} +5 -5
- package/dist/{dashboard-CkIV2rnQ.mjs.map → dashboard-BNSvAN8A.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-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/postgres.d.mts.map +1 -1
- package/dist/db/postgres.mjs +19 -3
- package/dist/db/postgres.mjs.map +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-YMEfcQUx.mjs → default-ByZ0JqZo.mjs} +1 -1
- package/dist/{default-YMEfcQUx.mjs.map → default-ByZ0JqZo.mjs.map} +1 -1
- package/dist/{deferred-tasks-DfqxH5Xf.d.mts → deferred-tasks-Cu4NSJpa.d.mts} +1 -1
- package/dist/{deferred-tasks-DfqxH5Xf.d.mts.map → deferred-tasks-Cu4NSJpa.d.mts.map} +1 -1
- package/dist/dev-typegen-DHT7lcMU.mjs +29 -0
- package/dist/dev-typegen-DHT7lcMU.mjs.map +1 -0
- package/dist/{device-flow-CojjSBwb.mjs → device-flow-Cf6bhCCT.mjs} +4 -4
- package/dist/{device-flow-CojjSBwb.mjs.map → device-flow-Cf6bhCCT.mjs.map} +1 -1
- package/dist/{dialect-helpers-BSbfaO3F.mjs → dialect-helpers-BcQvkHgn.mjs} +83 -2
- package/dist/dialect-helpers-BcQvkHgn.mjs.map +1 -0
- package/dist/{direct-executor-BWeWiRYB.mjs → direct-executor-yAyUGSqB.mjs} +3 -3
- package/dist/{direct-executor-BWeWiRYB.mjs.map → direct-executor-yAyUGSqB.mjs.map} +1 -1
- package/dist/{dist-89xCrGqi.mjs → dist-BAsh8dbf.mjs} +1 -1
- package/dist/{dist-89xCrGqi.mjs.map → dist-BAsh8dbf.mjs.map} +1 -1
- package/dist/{email-console-CEJgR_LB.mjs → email-console-DNup1Fku.mjs} +1 -1
- package/dist/{email-console-CEJgR_LB.mjs.map → email-console-DNup1Fku.mjs.map} +1 -1
- package/dist/{enrich-BX0IDp4z.mjs → enrich-t2Xvjdqa.mjs} +3 -3
- package/dist/{enrich-BX0IDp4z.mjs.map → enrich-t2Xvjdqa.mjs.map} +1 -1
- package/dist/entry-lock-BEr8gDkG.mjs +163 -0
- package/dist/entry-lock-BEr8gDkG.mjs.map +1 -0
- package/dist/{relations-C7B46bcU.d.mts → entry-lock-CGAtrwAR.d.mts} +265 -76
- package/dist/entry-lock-CGAtrwAR.d.mts.map +1 -0
- package/dist/{redirects-CRIM55KH.mjs → entry-lock-DIYHAaSw.mjs} +112 -34
- package/dist/entry-lock-DIYHAaSw.mjs.map +1 -0
- package/dist/entry-locks-BEcX7ET0.mjs +167 -0
- package/dist/entry-locks-BEcX7ET0.mjs.map +1 -0
- package/dist/{error-D9w94fjV.mjs → error-BDcFyoRt.mjs} +2 -2
- package/dist/{error-D9w94fjV.mjs.map → error-BDcFyoRt.mjs.map} +1 -1
- package/dist/{errors-n2j49uNf.mjs → errors-DvMdNrgf.mjs} +10 -1
- package/dist/errors-DvMdNrgf.mjs.map +1 -0
- package/dist/{escape-DN4Qmjsl.mjs → escape-B3asJC6W.mjs} +1 -1
- package/dist/{escape-DN4Qmjsl.mjs.map → escape-B3asJC6W.mjs.map} +1 -1
- package/dist/{field-defs-cache-Bh4q6oar.mjs → field-defs-cache-Cf5FHK0M.mjs} +5 -5
- package/dist/{field-defs-cache-Bh4q6oar.mjs.map → field-defs-cache-Cf5FHK0M.mjs.map} +1 -1
- package/dist/{fts-manager-BhOdW0bi.mjs → fts-manager-iddym8cd.mjs} +4 -4
- package/dist/{fts-manager-BhOdW0bi.mjs.map → fts-manager-iddym8cd.mjs.map} +1 -1
- package/dist/{hash-CTcngWvj.mjs → hash-BRweX6jz.mjs} +1 -1
- package/dist/{hash-CTcngWvj.mjs.map → hash-BRweX6jz.mjs.map} +1 -1
- package/dist/hook-result-BrshYHLx.d.mts +31 -0
- package/dist/hook-result-BrshYHLx.d.mts.map +1 -0
- package/dist/{hreflang-7pTHsLZJ.d.mts → hreflang-CQpu5bMy.d.mts} +2 -2
- package/dist/{hreflang-7pTHsLZJ.d.mts.map → hreflang-CQpu5bMy.d.mts.map} +1 -1
- package/dist/{hreflang-Huc6O5wa.mjs → hreflang-DshnweTC.mjs} +9 -8
- package/dist/{hreflang-Huc6O5wa.mjs.map → hreflang-DshnweTC.mjs.map} +1 -1
- package/dist/{identity-DXmb4aVp.mjs → identity-CjGKDq8J.mjs} +3 -3
- package/dist/{identity-DXmb4aVp.mjs.map → identity-CjGKDq8J.mjs.map} +1 -1
- package/dist/{import-C4_O3KXU.mjs → import-D96g2otw.mjs} +6 -6
- package/dist/{import-C4_O3KXU.mjs.map → import-D96g2otw.mjs.map} +1 -1
- package/dist/{index-6bRee8zb.d.mts → index-1ECYpfiF.d.mts} +3 -3
- package/dist/{index-6bRee8zb.d.mts.map → index-1ECYpfiF.d.mts.map} +1 -1
- package/dist/index.d.mts +22 -21
- package/dist/index.mjs +84 -81
- package/dist/{init-lock-DJkX6Hto.mjs → init-lock-CFNBe_iH.mjs} +1 -1
- package/dist/{init-lock-DJkX6Hto.mjs.map → init-lock-CFNBe_iH.mjs.map} +1 -1
- package/dist/{load-Bo7fZAbg.mjs → load-DPtY9cZo.mjs} +2 -2
- package/dist/{load-Bo7fZAbg.mjs.map → load-DPtY9cZo.mjs.map} +1 -1
- package/dist/{loader-ZsjE4paL.mjs → loader-WJi6GFRn.mjs} +90 -17
- package/dist/loader-WJi6GFRn.mjs.map +1 -0
- package/dist/{manifest-builder-QXuqvVMP.mjs → manifest-builder-BfNlGQIA.mjs} +2 -2
- package/dist/{manifest-builder-QXuqvVMP.mjs.map → manifest-builder-BfNlGQIA.mjs.map} +1 -1
- package/dist/{manifest-schema-CUYPfCEH.mjs → manifest-schema-CILooI5J.mjs} +5 -5
- package/dist/manifest-schema-CILooI5J.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +4 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +6 -4
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +3 -3
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +7 -7
- package/dist/{media-D6SeAfBl.mjs → media-BBm8Wg3f.mjs} +30 -2
- package/dist/media-BBm8Wg3f.mjs.map +1 -0
- package/dist/{media-BjwNuLEu.mjs → media-C1EIZKh1.mjs} +35 -5
- package/dist/media-C1EIZKh1.mjs.map +1 -0
- package/dist/{media-allowlist-D35v7bmL.mjs → media-allowlist-elXJgb_K.mjs} +2 -2
- package/dist/{media-allowlist-D35v7bmL.mjs.map → media-allowlist-elXJgb_K.mjs.map} +1 -1
- package/dist/{media-folders-D-0CmRZj.mjs → media-folders-DASfX_DH.mjs} +1 -1
- package/dist/{media-folders-D-0CmRZj.mjs.map → media-folders-DASfX_DH.mjs.map} +1 -1
- package/dist/{media-upload-C7bLXGcI.mjs → media-upload-C7_AQJ5v.mjs} +9 -9
- package/dist/{media-upload-C7bLXGcI.mjs.map → media-upload-C7_AQJ5v.mjs.map} +1 -1
- package/dist/{media-url-DH7giMx_.mjs → media-url-8dVl1loq.mjs} +19 -2
- package/dist/media-url-8dVl1loq.mjs.map +1 -0
- package/dist/{media-usage-BTRJvS6V.mjs → media-usage-C1EswMTq.mjs} +10 -10
- package/dist/{media-usage-BTRJvS6V.mjs.map → media-usage-C1EswMTq.mjs.map} +1 -1
- package/dist/{media-usage-activation-Dx0kPV6b.mjs → media-usage-activation-CrHNltlL.mjs} +3 -3
- package/dist/{media-usage-activation-Dx0kPV6b.mjs.map → media-usage-activation-CrHNltlL.mjs.map} +1 -1
- package/dist/{media-usage-work-C-fhM30c.mjs → media-usage-work-C5B1zT1c.mjs} +2 -2
- package/dist/{media-usage-work-C-fhM30c.mjs.map → media-usage-work-C5B1zT1c.mjs.map} +1 -1
- package/dist/{media-usage-work-DWb2XPMI.mjs → media-usage-work-IkQx_Yz6.mjs} +4 -4
- package/dist/{media-usage-work-DWb2XPMI.mjs.map → media-usage-work-IkQx_Yz6.mjs.map} +1 -1
- package/dist/{media-usage-write-fence-BwoJVRDC.mjs → media-usage-write-fence-B9anjOSg.mjs} +3 -3
- package/dist/{media-usage-write-fence-BwoJVRDC.mjs.map → media-usage-write-fence-B9anjOSg.mjs.map} +1 -1
- package/dist/{menus-CNg0QlDt.mjs → menus-D8mC4eaN.mjs} +406 -175
- package/dist/menus-D8mC4eaN.mjs.map +1 -0
- package/dist/{menus-CD7EFLwz.mjs → menus-UdwjHZJC.mjs} +12 -4
- package/dist/{menus-CD7EFLwz.mjs.map → menus-UdwjHZJC.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +4 -4
- package/dist/{mime-CUIG6x84.mjs → mime-DYpsOAny.mjs} +1 -1
- package/dist/{mime-CUIG6x84.mjs.map → mime-DYpsOAny.mjs.map} +1 -1
- package/dist/{mode-DaUM_MB2.mjs → mode-Dm4BHhRH.mjs} +1 -1
- package/dist/{mode-DaUM_MB2.mjs.map → mode-Dm4BHhRH.mjs.map} +1 -1
- package/dist/{node-sqlite-compat-Udb4Y-rs.mjs → node-sqlite-compat-2sezm-Zd.mjs} +1 -1
- package/dist/{node-sqlite-compat-Udb4Y-rs.mjs.map → node-sqlite-compat-2sezm-Zd.mjs.map} +1 -1
- package/dist/{normalize-CSxdKBVa.mjs → normalize-4nkKGsuW.mjs} +15 -5
- package/dist/normalize-4nkKGsuW.mjs.map +1 -0
- package/dist/{oauth-authorization-Dpsb-fMJ.mjs → oauth-authorization-BxE_lURD.mjs} +4 -4
- package/dist/{oauth-authorization-Dpsb-fMJ.mjs.map → oauth-authorization-BxE_lURD.mjs.map} +1 -1
- package/dist/{oauth-clients-Bxnoe_67.mjs → oauth-clients-DJIdOdq0.mjs} +1 -1
- package/dist/{oauth-clients-Bxnoe_67.mjs.map → oauth-clients-DJIdOdq0.mjs.map} +1 -1
- package/dist/{oauth-state-store-0C4s0K6w.mjs → oauth-state-store-CsdxP57n.mjs} +1 -1
- package/dist/{oauth-state-store-0C4s0K6w.mjs.map → oauth-state-store-CsdxP57n.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-wlGYSeqX.mjs → oauth-user-lookup-HzzW-dkF.mjs} +1 -1
- package/dist/{oauth-user-lookup-wlGYSeqX.mjs.map → oauth-user-lookup-HzzW-dkF.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-71tPfV4A.mjs → object-cache-DVKnyOfy.mjs} +19 -3
- package/dist/object-cache-DVKnyOfy.mjs.map +1 -0
- package/dist/{options-BHPeIbBd.mjs → options-D1FBiAv1.mjs} +60 -5
- package/dist/options-D1FBiAv1.mjs.map +1 -0
- package/dist/{options-BhZIeFY1.d.mts → options-D8Y0VHc7.d.mts} +30 -11
- package/dist/options-D8Y0VHc7.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.d.mts.map +1 -1
- package/dist/page/index.mjs +12 -0
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-BRJg1kz8.mjs → parse-WRg5C3NX.mjs} +2 -2
- package/dist/{parse-BRJg1kz8.mjs.map → parse-WRg5C3NX.mjs.map} +1 -1
- package/dist/{passkey-config-B3P0nHRR.mjs → passkey-config-qIdO-wF6.mjs} +1 -1
- package/dist/{passkey-config-B3P0nHRR.mjs.map → passkey-config-qIdO-wF6.mjs.map} +1 -1
- package/dist/{patterns-D9iDO3j8.mjs → patterns-DC8CLptu.mjs} +1 -1
- package/dist/{patterns-D9iDO3j8.mjs.map → patterns-DC8CLptu.mjs.map} +1 -1
- package/dist/{placeholder-BR4ZhVJl.d.mts → placeholder-COrvARyD.d.mts} +1 -1
- package/dist/{placeholder-BR4ZhVJl.d.mts.map → placeholder-COrvARyD.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +8 -3
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{policy-BVRganJQ.mjs → policy-XCfb-IE9.mjs} +2 -2
- package/dist/{policy-BVRganJQ.mjs.map → policy-XCfb-IE9.mjs.map} +1 -1
- package/dist/{portable-text-C8Tvp4_g.mjs → portable-text-BS3d5n-0.mjs} +1 -1
- package/dist/{portable-text-C8Tvp4_g.mjs.map → portable-text-BS3d5n-0.mjs.map} +1 -1
- package/dist/{preview-dn2dUyM0.mjs → preview-BxwsGgGp.mjs} +2 -2
- package/dist/{preview-dn2dUyM0.mjs.map → preview-BxwsGgGp.mjs.map} +1 -1
- package/dist/{protocol-CuBEsqgE.d.mts → protocol-CLn58-nw.d.mts} +2 -2
- package/dist/{protocol-CuBEsqgE.d.mts.map → protocol-CLn58-nw.d.mts.map} +1 -1
- package/dist/{public-url-DRz_AinV.mjs → public-url-FWWAvnre.mjs} +1 -1
- package/dist/{public-url-DRz_AinV.mjs.map → public-url-FWWAvnre.mjs.map} +1 -1
- package/dist/{query-D18vTdha.mjs → query-DygOte9M.mjs} +26 -17
- package/dist/query-DygOte9M.mjs.map +1 -0
- package/dist/{query-tZDEdtCN.mjs → query-gtXT03Wc.mjs} +5 -5
- package/dist/{query-tZDEdtCN.mjs.map → query-gtXT03Wc.mjs.map} +1 -1
- package/dist/{rate-limit-on7KPo-v.mjs → rate-limit-CQUPm0dh.mjs} +2 -2
- package/dist/{rate-limit-on7KPo-v.mjs.map → rate-limit-CQUPm0dh.mjs.map} +1 -1
- package/dist/{redirect-DrbEmU9a.mjs → redirect-D1cWafi6.mjs} +1 -1
- package/dist/{redirect-DrbEmU9a.mjs.map → redirect-D1cWafi6.mjs.map} +1 -1
- package/dist/{redirect-CZkbozu9.mjs → redirect-DId44BS1.mjs} +19 -6
- package/dist/redirect-DId44BS1.mjs.map +1 -0
- package/dist/{redirects-BahWiu8Z.mjs → redirects-DN-ZE33W.mjs} +5 -5
- package/dist/{redirects-BahWiu8Z.mjs.map → redirects-DN-ZE33W.mjs.map} +1 -1
- package/dist/{registry-Cx-jEJOS.mjs → registry-DTqaqxed.mjs} +46 -12
- package/dist/registry-DTqaqxed.mjs.map +1 -0
- package/dist/{relation-A6wLF_DS.mjs → relation-DxgCHOBw.mjs} +2 -2
- package/dist/{relation-A6wLF_DS.mjs.map → relation-DxgCHOBw.mjs.map} +1 -1
- package/dist/{relations-Cj5hZ6Zg.mjs → relations-KKDSLUwS.mjs} +4 -4
- package/dist/{relations-Cj5hZ6Zg.mjs.map → relations-KKDSLUwS.mjs.map} +1 -1
- package/dist/{relations-BTPM2saV.mjs → relations-rOmbndUJ.mjs} +8 -8
- package/dist/relations-rOmbndUJ.mjs.map +1 -0
- package/dist/{request-cache-DH9zdCOD.mjs → request-cache-DAZZmesc.mjs} +1 -1
- package/dist/{request-cache-DH9zdCOD.mjs.map → request-cache-DAZZmesc.mjs.map} +1 -1
- package/dist/request-context.d.mts +1 -1
- package/dist/{request-meta-DRp5ENd_.mjs → request-meta-BgjUQLQ-.mjs} +2 -2
- package/dist/{request-meta-DRp5ENd_.mjs.map → request-meta-BgjUQLQ-.mjs.map} +1 -1
- package/dist/{resolve-DxUpTMmE.mjs → resolve-Cy0aWSRj.mjs} +37 -4
- package/dist/resolve-Cy0aWSRj.mjs.map +1 -0
- package/dist/{runner-zgqA_CqP.d.mts → runner-CfwysRM0.d.mts} +3 -2
- package/dist/runner-CfwysRM0.d.mts.map +1 -0
- package/dist/{runner-77GOZCnH.mjs → runner-nEzvnogG.mjs} +476 -295
- package/dist/runner-nEzvnogG.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +3 -2
- package/dist/runtime.mjs.map +1 -1
- package/dist/{schema-BY-oVntF.mjs → schema-CRu38Pr5.mjs} +3 -3
- package/dist/{schema-BY-oVntF.mjs.map → schema-CRu38Pr5.mjs.map} +1 -1
- package/dist/{schema-Cw9kVK0I.mjs → schema-DifxndJx.mjs} +5 -5
- package/dist/{schema-Cw9kVK0I.mjs.map → schema-DifxndJx.mjs.map} +1 -1
- package/dist/{scopes-vMR1uIbt.mjs → scopes-D5A1OZbq.mjs} +3 -3
- package/dist/{scopes-vMR1uIbt.mjs.map → scopes-D5A1OZbq.mjs.map} +1 -1
- package/dist/{search-CfT3KxO5.mjs → search-DEPFSBFq.mjs} +4 -4
- package/dist/{search-CfT3KxO5.mjs.map → search-DEPFSBFq.mjs.map} +1 -1
- package/dist/{secrets-BH2Qow1-.mjs → secrets-CdfzLdoO.mjs} +3 -3
- package/dist/{secrets-BH2Qow1-.mjs.map → secrets-CdfzLdoO.mjs.map} +1 -1
- package/dist/{sections-DTfjyf1z.mjs → sections-3X52kmIR.mjs} +2 -2
- package/dist/{sections-DTfjyf1z.mjs.map → sections-3X52kmIR.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +28 -26
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +20 -21
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-Cm-dtvgk.mjs → seo-Bw68KxRc.mjs} +3 -3
- package/dist/{seo-Cm-dtvgk.mjs.map → seo-Bw68KxRc.mjs.map} +1 -1
- package/dist/{seo-BSiTIXzd.mjs → seo-C4AmbsMU.mjs} +3 -2
- package/dist/seo-C4AmbsMU.mjs.map +1 -0
- package/dist/{service-DYsDHEKe.mjs → service-J_-Vgo7R.mjs} +3 -3
- package/dist/{service-DYsDHEKe.mjs.map → service-J_-Vgo7R.mjs.map} +1 -1
- package/dist/{session-user-CNAfvsdw.mjs → session-user-CbnMMwk6.mjs} +1 -1
- package/dist/{session-user-CNAfvsdw.mjs.map → session-user-CbnMMwk6.mjs.map} +1 -1
- package/dist/{settings-DjtkUo__.mjs → settings-AnEFYICn.mjs} +3 -3
- package/dist/{settings-DjtkUo__.mjs.map → settings-AnEFYICn.mjs.map} +1 -1
- package/dist/{settings-BgN-0DT-.mjs → settings-DcMjREe5.mjs} +21 -8
- package/dist/settings-DcMjREe5.mjs.map +1 -0
- package/dist/{setup-complete-CcpXaPU7.mjs → setup-complete-BClXXTvr.mjs} +2 -2
- package/dist/{setup-complete-CcpXaPU7.mjs.map → setup-complete-BClXXTvr.mjs.map} +1 -1
- package/dist/{setup-nonce-Reyw30jg.mjs → setup-nonce-BheRa4RG.mjs} +1 -1
- package/dist/{setup-nonce-Reyw30jg.mjs.map → setup-nonce-BheRa4RG.mjs.map} +1 -1
- package/dist/{single-flight-cache-BPuGPdcN.mjs → single-flight-cache-jaswDzmQ.mjs} +2 -2
- package/dist/{single-flight-cache-BPuGPdcN.mjs.map → single-flight-cache-jaswDzmQ.mjs.map} +1 -1
- package/dist/{site-url-Cs_V9n3V.mjs → site-url-Bqf-ea3N.mjs} +3 -3
- package/dist/{site-url-Cs_V9n3V.mjs.map → site-url-Bqf-ea3N.mjs.map} +1 -1
- package/dist/{snapshot-DSB8P7Lm.mjs → snapshot-C4CtXntb.mjs} +51 -35
- package/dist/snapshot-C4CtXntb.mjs.map +1 -0
- package/dist/{ssrf-DqebVE34.mjs → ssrf-gl4gFNhw.mjs} +151 -93
- package/dist/ssrf-gl4gFNhw.mjs.map +1 -0
- package/dist/{state-BJfU9Uzw.mjs → state-1F6IOhdQ.mjs} +1 -1
- package/dist/{state-BJfU9Uzw.mjs.map → state-1F6IOhdQ.mjs.map} +1 -1
- package/dist/{status-DDu8HIQl.mjs → status-Cenfk_r5.mjs} +1 -1
- package/dist/{status-DDu8HIQl.mjs.map → status-Cenfk_r5.mjs.map} +1 -1
- package/dist/storage/local.d.mts +2 -1
- package/dist/storage/local.d.mts.map +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/local.mjs.map +1 -1
- package/dist/storage/s3.d.mts +2 -1
- package/dist/storage/s3.d.mts.map +1 -1
- package/dist/storage/s3.mjs +3 -2
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{target-D0o26Azo.mjs → target-CRzeTs8G.mjs} +1 -1
- package/dist/{target-D0o26Azo.mjs.map → target-CRzeTs8G.mjs.map} +1 -1
- package/dist/{taxonomies-CPGxo-bn.mjs → taxonomies-BOdxuZpV.mjs} +23 -13
- package/dist/taxonomies-BOdxuZpV.mjs.map +1 -0
- package/dist/{taxonomies-kmyudNGP.mjs → taxonomies-NcFDq5Gg.mjs} +58 -23
- package/dist/taxonomies-NcFDq5Gg.mjs.map +1 -0
- package/dist/{taxonomy-8X09dLN5.mjs → taxonomy-DP1vny4K.mjs} +12 -4
- package/dist/{taxonomy-8X09dLN5.mjs.map → taxonomy-DP1vny4K.mjs.map} +1 -1
- package/dist/{tokens-gTS-IVUp.mjs → tokens-CDk8ox9p.mjs} +1 -1
- package/dist/{tokens-gTS-IVUp.mjs.map → tokens-CDk8ox9p.mjs.map} +1 -1
- package/dist/{transport-_6R1ub7t.d.mts → transport-BVn4tVb9.d.mts} +1 -1
- package/dist/{transport-_6R1ub7t.d.mts.map → transport-BVn4tVb9.d.mts.map} +1 -1
- package/dist/{transport-fX59xaJz.mjs → transport-DP0JI-8i.mjs} +1 -1
- package/dist/{transport-fX59xaJz.mjs.map → transport-DP0JI-8i.mjs.map} +1 -1
- package/dist/{trusted-proxy-fe6nEgR4.mjs → trusted-proxy-BTM6UxqD.mjs} +1 -1
- package/dist/{trusted-proxy-fe6nEgR4.mjs.map → trusted-proxy-BTM6UxqD.mjs.map} +1 -1
- package/dist/{types-D_DWe7k9.d.mts → types-2n848aVW.d.mts} +3 -2
- package/dist/types-2n848aVW.d.mts.map +1 -0
- package/dist/types-A2cN6a4a.mjs +3 -0
- package/dist/{types-75KIqzL9.mjs → types-BMXnRIrX.mjs} +4 -2
- package/dist/types-BMXnRIrX.mjs.map +1 -0
- package/dist/{types-Vg6f5i3s.d.mts → types-BouXpOsa.d.mts} +121 -4
- package/dist/types-BouXpOsa.d.mts.map +1 -0
- package/dist/{types-BXUmsINL.mjs → types-ByG2coLw.mjs} +1 -1
- package/dist/{types-BXUmsINL.mjs.map → types-ByG2coLw.mjs.map} +1 -1
- package/dist/types-CQPWhPxE.mjs.map +1 -1
- package/dist/{types-Blb-MRC3.d.mts → types-DEfNJ__A.d.mts} +1 -1
- package/dist/{types-Blb-MRC3.d.mts.map → types-DEfNJ__A.d.mts.map} +1 -1
- package/dist/{types-Br-ERaxh.d.mts → types-DKcKSbtB.d.mts} +23 -7
- package/dist/types-DKcKSbtB.d.mts.map +1 -0
- package/dist/{types-BzBd3PeX.d.mts → types-DRYs7uTL.d.mts} +1 -1
- package/dist/{types-BzBd3PeX.d.mts.map → types-DRYs7uTL.d.mts.map} +1 -1
- package/dist/{types-CLqvnd05.d.mts → types-DaEg7KX2.d.mts} +1 -1
- package/dist/{types-CLqvnd05.d.mts.map → types-DaEg7KX2.d.mts.map} +1 -1
- package/dist/{types-DJQxln7q.d.mts → types-LU8utpP_.d.mts} +14 -10
- package/dist/types-LU8utpP_.d.mts.map +1 -0
- package/dist/{types-D5VVLr7J.d.mts → types-VpYfPUxN.d.mts} +1 -1
- package/dist/{types-D5VVLr7J.d.mts.map → types-VpYfPUxN.d.mts.map} +1 -1
- package/dist/{types-DM3vioBY.mjs → types-c9GP7Dj5.mjs} +1 -1
- package/dist/{types-DM3vioBY.mjs.map → types-c9GP7Dj5.mjs.map} +1 -1
- package/dist/{types-DHxzBjbD.d.mts → types-tJWDK__M.d.mts} +14 -1
- package/dist/types-tJWDK__M.d.mts.map +1 -0
- package/dist/{upload-attempts-CNyGSepg.mjs → upload-attempts-C6S2y-lp.mjs} +1 -1
- package/dist/{upload-attempts-CNyGSepg.mjs.map → upload-attempts-C6S2y-lp.mjs.map} +1 -1
- package/dist/{url-pattern-K-KdXcSe.mjs → url-pattern-UYtxVTuj.mjs} +1 -1
- package/dist/{url-pattern-K-KdXcSe.mjs.map → url-pattern-UYtxVTuj.mjs.map} +1 -1
- package/dist/{user-CtYY0tp2.mjs → user-DIsIXogT.mjs} +2 -2
- package/dist/{user-CtYY0tp2.mjs.map → user-DIsIXogT.mjs.map} +1 -1
- package/dist/{utils-HztC73hq.mjs → utils-BicP5Qbg.mjs} +2 -2
- package/dist/{utils-HztC73hq.mjs.map → utils-BicP5Qbg.mjs.map} +1 -1
- package/dist/{validate-Dd-IUjnZ.mjs → validate-D8VPn4Hv.mjs} +8 -3
- package/dist/validate-D8VPn4Hv.mjs.map +1 -0
- package/dist/{validate-DlqdOZXB.d.mts → validate-Df6Dvwbw.d.mts} +12 -7
- package/dist/validate-Df6Dvwbw.d.mts.map +1 -0
- package/dist/{validation-D83n7Npi.mjs → validation-CzMJn9Ku.mjs} +13 -11
- package/dist/{validation-D83n7Npi.mjs.map → validation-CzMJn9Ku.mjs.map} +1 -1
- package/dist/version-CK67_SXX.mjs +7 -0
- package/dist/{version-ri-sCyAp.mjs.map → version-CK67_SXX.mjs.map} +1 -1
- package/dist/{widgets-CpmZd9Q-.mjs → widgets-RFVAxQl3.mjs} +18 -5
- package/dist/widgets-RFVAxQl3.mjs.map +1 -0
- package/dist/{wxr-taxonomies-BFd0y72_.d.mts → wxr-taxonomies-BX4yQL9s.d.mts} +1 -1
- package/dist/{wxr-taxonomies-BFd0y72_.d.mts.map → wxr-taxonomies-BX4yQL9s.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-Df4vxWcU.mjs → wxr-taxonomies-Csdp7yde.mjs} +4 -4
- package/dist/{wxr-taxonomies-Df4vxWcU.mjs.map → wxr-taxonomies-Csdp7yde.mjs.map} +1 -1
- package/dist/{zod-generator-DylzusHh.mjs → zod-generator-CNRGdnBY.mjs} +11 -7
- package/dist/zod-generator-CNRGdnBY.mjs.map +1 -0
- package/package.json +16 -11
- package/src/api/errors.ts +9 -0
- package/src/api/handlers/content.ts +115 -90
- package/src/api/handlers/entry-lock.ts +206 -0
- package/src/api/handlers/index.ts +1 -0
- package/src/api/handlers/manifest.ts +162 -12
- package/src/api/handlers/marketplace.ts +28 -20
- package/src/api/handlers/media.ts +30 -0
- package/src/api/handlers/menus.ts +9 -0
- package/src/api/handlers/registry.ts +406 -297
- package/src/api/handlers/revision.ts +2 -1
- package/src/api/handlers/seo.ts +10 -1
- package/src/api/handlers/snapshot.ts +84 -72
- package/src/api/handlers/taxonomies.ts +25 -9
- package/src/api/openapi/document.ts +196 -11
- package/src/api/parse.ts +1 -1
- package/src/api/schemas/auth.ts +4 -4
- package/src/api/schemas/bylines.ts +3 -3
- package/src/api/schemas/comments.ts +1 -1
- package/src/api/schemas/common.ts +3 -2
- package/src/api/schemas/content.ts +86 -22
- package/src/api/schemas/entry-lock.ts +48 -0
- package/src/api/schemas/index.ts +1 -0
- package/src/api/schemas/media.ts +52 -0
- package/src/api/schemas/redirects.ts +6 -1
- package/src/api/schemas/schema.ts +14 -1
- package/src/api/schemas/setup.ts +1 -1
- package/src/api/schemas/taxonomies.ts +2 -2
- package/src/api/schemas/users.ts +1 -1
- package/src/api/types.ts +25 -10
- package/src/astro/dev-typegen.ts +35 -0
- package/src/astro/image-endpoint.ts +2 -2
- package/src/astro/integration/dev-typegen.ts +91 -0
- package/src/astro/integration/index.ts +18 -50
- package/src/astro/integration/routes.ts +10 -0
- package/src/astro/integration/runtime.ts +13 -5
- package/src/astro/integration/vite-config.ts +51 -2
- package/src/astro/middleware.ts +21 -0
- package/src/astro/routes/api/admin/api-tokens/index.ts +4 -1
- package/src/astro/routes/api/admin/oauth-clients/[id].ts +1 -1
- package/src/astro/routes/api/admin/oauth-clients/index.ts +1 -1
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/artifact.ts +3 -7
- package/src/astro/routes/api/admin/plugins/registry/install.ts +4 -0
- package/src/astro/routes/api/admin/plugins/registry/verify.ts +60 -0
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +18 -2
- package/src/astro/routes/api/content/[collection]/[id]/lock.ts +133 -0
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +12 -1
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +20 -0
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +16 -2
- package/src/astro/routes/api/content/[collection]/[id].ts +27 -2
- package/src/astro/routes/api/content/[collection]/index.ts +3 -0
- package/src/astro/routes/api/manifest.ts +1 -1
- package/src/astro/routes/api/media/[id]/replace.ts +114 -0
- package/src/astro/routes/api/media/file/[...key].ts +4 -1
- package/src/astro/routes/api/media/upload-url.ts +8 -4
- package/src/astro/routes/api/media.ts +54 -8
- package/src/astro/routes/api/menus/[name]/items/[id].ts +7 -2
- package/src/astro/routes/api/menus/[name]/items.ts +4 -1
- package/src/astro/routes/api/menus/[name]/reorder.ts +4 -1
- package/src/astro/routes/api/menus/[name]/translations.ts +4 -1
- package/src/astro/routes/api/menus/[name].ts +7 -2
- package/src/astro/routes/api/menus/index.ts +4 -1
- package/src/astro/routes/api/settings/email.ts +1 -1
- package/src/astro/routes/api/settings.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name]/reorder.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +7 -2
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +4 -1
- package/src/astro/routes/api/taxonomies/[name].ts +7 -2
- package/src/astro/routes/api/taxonomies/index.ts +4 -1
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +3 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +5 -2
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +3 -1
- package/src/astro/routes/api/widget-areas/[name].ts +3 -1
- package/src/astro/routes/api/widget-areas/index.ts +3 -1
- package/src/astro/routes/sitemap-[collection].xml.ts +4 -0
- package/src/astro/types.ts +36 -8
- package/src/auth/challenge-store.ts +3 -1
- package/src/aws-sdk.d.ts +1 -0
- package/src/cache/chrome-tags.ts +24 -0
- package/src/cli/commands/content.ts +31 -5
- package/src/cli/commands/export-seed.ts +2 -0
- package/src/client/index.ts +34 -7
- package/src/components/EmDashBodyEnd.astro +4 -1
- package/src/components/EmDashBodyStart.astro +4 -1
- package/src/components/EmDashHead.astro +35 -16
- package/src/components/EmDashImage.astro +2 -1
- package/src/components/EmDashMedia.astro +2 -1
- package/src/components/Gallery.astro +18 -4
- package/src/components/InlineEditor.astro +3 -1
- package/src/components/InlinePortableTextEditor.tsx +112 -12
- package/src/components/PortableText.astro +4 -0
- package/src/components/Table.astro +147 -62
- package/src/components/widgets/Archives.astro +2 -37
- package/src/config/errors.ts +13 -0
- package/src/content/converters/index.ts +2 -0
- package/src/content/converters/mark-safety.ts +1 -0
- package/src/content/converters/portable-text-identity.ts +139 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +226 -69
- package/src/content/converters/prosemirror-to-portable-text.ts +128 -28
- package/src/content/converters/types.ts +11 -0
- package/src/database/dialect-helpers.ts +125 -0
- package/src/database/migrations/017_authorization_codes.ts +14 -4
- package/src/database/migrations/074_content_deleted_scheduled_index.ts +55 -0
- package/src/database/migrations/075_entry_edit_locks.ts +44 -0
- package/src/database/migrations/076_collection_nav_group.ts +22 -0
- package/src/database/migrations/077_plugin_storage_revisions.ts +89 -0
- package/src/database/migrations/runner.ts +9 -1
- package/src/database/repositories/byline.ts +32 -16
- package/src/database/repositories/content.ts +284 -48
- package/src/database/repositories/entry-locks.ts +257 -0
- package/src/database/repositories/media-usage.ts +66 -37
- package/src/database/repositories/media.ts +60 -1
- package/src/database/repositories/options.ts +69 -5
- package/src/database/repositories/plugin-storage.ts +233 -9
- package/src/database/repositories/redirect.ts +17 -6
- package/src/database/repositories/taxonomy.ts +8 -0
- package/src/database/repositories/types.ts +11 -7
- package/src/database/types.ts +15 -1
- package/src/db/adapters.ts +8 -1
- package/src/db/postgres.ts +23 -0
- package/src/emdash-runtime.ts +196 -199
- package/src/fields/boolean.ts +1 -1
- package/src/fields/datetime.ts +1 -1
- package/src/fields/file.ts +1 -1
- package/src/fields/integer.ts +1 -1
- package/src/fields/json.ts +1 -1
- package/src/fields/multiselect.ts +1 -1
- package/src/fields/number.ts +1 -1
- package/src/fields/portable-text.ts +1 -1
- package/src/fields/richtext.ts +1 -1
- package/src/fields/select.ts +1 -1
- package/src/fields/slug.ts +1 -1
- package/src/fields/text.ts +1 -1
- package/src/fields/textarea.ts +1 -1
- package/src/fields/types.ts +2 -2
- package/src/i18n/resolve.ts +44 -4
- package/src/index.ts +39 -3
- package/src/loader.ts +96 -12
- package/src/mcp/server.ts +251 -29
- package/src/media/image-endpoint.ts +5 -2
- package/src/media/normalize.ts +15 -4
- package/src/media/responsive.ts +23 -0
- package/src/media/usage/cleanup.ts +9 -8
- package/src/media/usage/content-refresh.ts +2 -1
- package/src/menus/index.ts +33 -21
- package/src/object-cache/index.ts +44 -2
- package/src/page/seo-contributions.ts +78 -1
- package/src/page/seo-panel.ts +47 -0
- package/src/plugin-types.ts +27 -1
- package/src/plugins/conditional-storage.ts +30 -0
- package/src/plugins/context.ts +49 -17
- package/src/plugins/hooks.ts +10 -1
- package/src/plugins/index.ts +15 -0
- package/src/plugins/manager.ts +6 -2
- package/src/plugins/manifest-schema.ts +1 -1
- package/src/plugins/routes.ts +3 -1
- package/src/plugins/sandbox/hook-result.ts +52 -0
- package/src/plugins/sandbox/index.ts +10 -0
- package/src/plugins/sandbox/types.ts +16 -2
- package/src/plugins/storage-query.ts +45 -0
- package/src/plugins/storage-update.ts +96 -0
- package/src/plugins/types.ts +120 -0
- package/src/query.ts +29 -3
- package/src/registry/artifact-checksum.ts +15 -0
- package/src/registry/artifact-verification.ts +85 -0
- package/src/registry/authoritative-records.ts +180 -0
- package/src/registry/config.ts +130 -27
- package/src/registry/record-labels.ts +28 -0
- package/src/registry/types.ts +5 -6
- package/src/schema/collection-slugs-cache.ts +157 -0
- package/src/schema/registry.ts +45 -3
- package/src/schema/types.ts +25 -6
- package/src/schema/zod-generator.ts +16 -13
- package/src/security/ssrf.ts +172 -143
- package/src/seed/apply.ts +4 -0
- package/src/seed/types.ts +7 -2
- package/src/seed/validate.ts +18 -1
- package/src/seo/hreflang.ts +1 -0
- package/src/seo/index.ts +5 -10
- package/src/seo/media-url.ts +26 -0
- package/src/settings/index.ts +16 -0
- package/src/storage/local.ts +1 -0
- package/src/storage/s3.ts +2 -0
- package/src/storage/types.ts +2 -0
- package/src/taxonomies/index.ts +40 -20
- package/src/taxonomies/term-counts.ts +22 -5
- package/src/widgets/archives.ts +67 -0
- package/src/widgets/index.ts +16 -0
- package/dist/api-B0w3uBiG.mjs +0 -2269
- package/dist/api-B0w3uBiG.mjs.map +0 -1
- package/dist/apply-B_VMpJ2P.mjs.map +0 -1
- package/dist/byline-Cpnwrje1.mjs.map +0 -1
- package/dist/challenge-store-D5pSY2S1.mjs.map +0 -1
- package/dist/content-CP-SeXNa.mjs.map +0 -1
- package/dist/content-refresh-DLOfIhYc.mjs.map +0 -1
- package/dist/context-BR5hRWiK.mjs.map +0 -1
- package/dist/dialect-helpers-BSbfaO3F.mjs.map +0 -1
- package/dist/errors-n2j49uNf.mjs.map +0 -1
- package/dist/index-DWbJrsAg.d.mts.map +0 -1
- package/dist/loader-ZsjE4paL.mjs.map +0 -1
- package/dist/manifest-schema-CUYPfCEH.mjs.map +0 -1
- package/dist/media-BjwNuLEu.mjs.map +0 -1
- package/dist/media-D6SeAfBl.mjs.map +0 -1
- package/dist/media-url-DH7giMx_.mjs.map +0 -1
- package/dist/menus-CNg0QlDt.mjs.map +0 -1
- package/dist/normalize-CSxdKBVa.mjs.map +0 -1
- package/dist/object-cache-71tPfV4A.mjs.map +0 -1
- package/dist/options-BHPeIbBd.mjs.map +0 -1
- package/dist/options-BhZIeFY1.d.mts.map +0 -1
- package/dist/query-D18vTdha.mjs.map +0 -1
- package/dist/redirect-CZkbozu9.mjs.map +0 -1
- package/dist/redirects-CRIM55KH.mjs.map +0 -1
- package/dist/registry-BiO5WwPq.mjs +0 -2716
- package/dist/registry-BiO5WwPq.mjs.map +0 -1
- package/dist/registry-Cx-jEJOS.mjs.map +0 -1
- package/dist/relations-BTPM2saV.mjs.map +0 -1
- package/dist/relations-C7B46bcU.d.mts.map +0 -1
- package/dist/resolve-DxUpTMmE.mjs.map +0 -1
- package/dist/runner-77GOZCnH.mjs.map +0 -1
- package/dist/runner-zgqA_CqP.d.mts.map +0 -1
- package/dist/seo-BSiTIXzd.mjs.map +0 -1
- package/dist/settings-BgN-0DT-.mjs.map +0 -1
- package/dist/snapshot-DSB8P7Lm.mjs.map +0 -1
- package/dist/ssrf-DqebVE34.mjs.map +0 -1
- package/dist/taxonomies-CPGxo-bn.mjs.map +0 -1
- package/dist/taxonomies-kmyudNGP.mjs.map +0 -1
- package/dist/types-75KIqzL9.mjs.map +0 -1
- package/dist/types-Br-ERaxh.d.mts.map +0 -1
- package/dist/types-D6OcIp2P.mjs +0 -3
- package/dist/types-DHxzBjbD.d.mts.map +0 -1
- package/dist/types-DJQxln7q.d.mts.map +0 -1
- package/dist/types-D_DWe7k9.d.mts.map +0 -1
- package/dist/types-Vg6f5i3s.d.mts.map +0 -1
- package/dist/validate-Dd-IUjnZ.mjs.map +0 -1
- package/dist/validate-DlqdOZXB.d.mts.map +0 -1
- package/dist/version-ri-sCyAp.mjs +0 -7
- package/dist/widgets-CpmZd9Q-.mjs.map +0 -1
- package/dist/zod-generator-DylzusHh.mjs.map +0 -1
- /package/dist/{api-tokens-B5NHLNUN.mjs → api-tokens-B_lfpmH3.mjs} +0 -0
- /package/dist/{ssrf-BPKzkm6O.mjs → ssrf-TQhaljuI.mjs} +0 -0
|
@@ -0,0 +1,972 @@
|
|
|
1
|
+
import { i as resolveAndValidateExternalUrlTarget, t as SsrfError } from "./ssrf-gl4gFNhw.mjs";
|
|
2
|
+
import { RECORD_SCOPED_BLOB_CACHE_TYPE } from "@emdash-cms/registry-lexicons";
|
|
3
|
+
|
|
4
|
+
//#region ../registry-verification/dist/auth-B730dpJ4.js
|
|
5
|
+
const UNSUPPORTED_AUTH_MESSAGE = "This release requires an authentication method the client does not support.";
|
|
6
|
+
function unsupportedAuthDetails(auth) {
|
|
7
|
+
if (!isRecord$1(auth) || typeof auth.hint_url !== "string" || auth.hint_url.length > 2048) return;
|
|
8
|
+
try {
|
|
9
|
+
const url = new URL(auth.hint_url);
|
|
10
|
+
if (url.protocol !== "https:" || url.username || url.password) return void 0;
|
|
11
|
+
return { hintUrl: url.href };
|
|
12
|
+
} catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function isRecord$1(value) {
|
|
17
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region ../registry-verification/dist/errors-CI-j3m_y.js
|
|
22
|
+
function verificationError(code, message, details) {
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
error: {
|
|
26
|
+
code,
|
|
27
|
+
message,
|
|
28
|
+
...details === void 0 ? {} : { details }
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region ../registry-verification/dist/checksum.js
|
|
35
|
+
const SHA2_256_CODE = 18;
|
|
36
|
+
const SHA2_256_LENGTH = 32;
|
|
37
|
+
const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
|
38
|
+
/** Derive the required artifact checksum from a raw sha2-256 blob CID. */
|
|
39
|
+
function multihashFromBlobCid(value) {
|
|
40
|
+
if (!value.startsWith("b")) return verificationError("BLOB_REF_INVALID", "The blob reference CID is malformed.");
|
|
41
|
+
const bytes = decodeBase32(value.slice(1));
|
|
42
|
+
if (bytes === null || bytes.length !== 36 || bytes[0] !== 1 || bytes[1] !== 85) return verificationError("BLOB_REF_INVALID", "Blob references must use a CIDv1 raw sha2-256 CID.");
|
|
43
|
+
const checksum = `b${encodeBase32(bytes.slice(2))}`;
|
|
44
|
+
if (!decodeMultihash(checksum).success) return verificationError("BLOB_REF_INVALID", "Blob references must use a CIDv1 raw sha2-256 CID.");
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
value: checksum
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Decodes a lowercase base32 multibase-encoded multihash. */
|
|
51
|
+
function decodeMultihash(value) {
|
|
52
|
+
if (!value.startsWith("b")) return verificationError("INVALID_MULTIHASH", "Checksums must be lowercase base32 multibase-encoded multihashes.");
|
|
53
|
+
const bytes = decodeBase32(value.slice(1));
|
|
54
|
+
if (bytes === null) return verificationError("INVALID_MULTIHASH", "The multibase checksum is malformed.");
|
|
55
|
+
const code = readVarint(bytes, 0);
|
|
56
|
+
if (code === null) return verificationError("INVALID_MULTIHASH", "The multihash algorithm code is malformed.");
|
|
57
|
+
const length = readVarint(bytes, code.nextOffset);
|
|
58
|
+
if (length === null || length.value !== bytes.length - length.nextOffset) return verificationError("INVALID_MULTIHASH", "The multihash digest length is malformed.");
|
|
59
|
+
if (code.value !== SHA2_256_CODE) return verificationError("UNSUPPORTED_MULTIHASH", "The multihash algorithm is not supported.");
|
|
60
|
+
if (length.value !== SHA2_256_LENGTH) return verificationError("INVALID_MULTIHASH", "The sha2-256 digest must be 32 bytes.");
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
value: {
|
|
64
|
+
algorithm: "sha2-256",
|
|
65
|
+
digest: bytes.slice(length.nextOffset)
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async function computeArtifactDigestCandidates(bytes) {
|
|
70
|
+
const [sha256, sha384, sha512] = await Promise.all([
|
|
71
|
+
crypto.subtle.digest("SHA-256", new Uint8Array(bytes)),
|
|
72
|
+
crypto.subtle.digest("SHA-384", new Uint8Array(bytes)),
|
|
73
|
+
crypto.subtle.digest("SHA-512", new Uint8Array(bytes))
|
|
74
|
+
]);
|
|
75
|
+
return [
|
|
76
|
+
new Uint8Array(sha256),
|
|
77
|
+
new Uint8Array(sha384),
|
|
78
|
+
new Uint8Array(sha512)
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
async function verifyMultihash(bytes, expected) {
|
|
82
|
+
const decoded = decodeMultihash(expected);
|
|
83
|
+
if (!decoded.success) return decoded;
|
|
84
|
+
const actual = await computeDigest(bytes, decoded.value.algorithm);
|
|
85
|
+
if (!actual.success) return actual;
|
|
86
|
+
if (!compareDigestBytes(actual.value, decoded.value.digest)) return verificationError("CHECKSUM_MISMATCH", "The resource bytes do not match the expected checksum.");
|
|
87
|
+
return {
|
|
88
|
+
success: true,
|
|
89
|
+
value: true
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Compare public checksum digest bytes without early exit. Digests are public
|
|
94
|
+
* integrity metadata, so a portable byte loop is preferable to a Node-only
|
|
95
|
+
* timing primitive while still avoiding an ordinary equality short circuit.
|
|
96
|
+
*/
|
|
97
|
+
function compareDigestBytes(left, right) {
|
|
98
|
+
let difference = left.length ^ right.length;
|
|
99
|
+
const maximumLength = Math.max(left.length, right.length);
|
|
100
|
+
for (let index = 0; index < maximumLength; index += 1) difference |= (left[index] ?? 0) ^ (right[index] ?? 0);
|
|
101
|
+
return difference === 0;
|
|
102
|
+
}
|
|
103
|
+
async function computeDigest(bytes, algorithm) {
|
|
104
|
+
if (algorithm !== "sha2-256") return verificationError("UNSUPPORTED_MULTIHASH", "The multihash algorithm is not supported.");
|
|
105
|
+
try {
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
value: new Uint8Array(await crypto.subtle.digest("SHA-256", new Uint8Array(bytes)))
|
|
109
|
+
};
|
|
110
|
+
} catch {
|
|
111
|
+
return verificationError("UNSUPPORTED_MULTIHASH", "The sha2-256 algorithm is unavailable.");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function readVarint(bytes, offset) {
|
|
115
|
+
let value = 0;
|
|
116
|
+
let shift = 0;
|
|
117
|
+
for (let index = offset; index < bytes.length && index < offset + 5; index += 1) {
|
|
118
|
+
const byte = bytes[index];
|
|
119
|
+
if (byte === void 0) return null;
|
|
120
|
+
value |= (byte & 127) << shift;
|
|
121
|
+
if ((byte & 128) === 0) return {
|
|
122
|
+
value,
|
|
123
|
+
nextOffset: index + 1
|
|
124
|
+
};
|
|
125
|
+
shift += 7;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
function encodeBase32(bytes) {
|
|
130
|
+
let result = "";
|
|
131
|
+
let buffer = 0;
|
|
132
|
+
let bits = 0;
|
|
133
|
+
for (const byte of bytes) {
|
|
134
|
+
buffer = buffer << 8 | byte;
|
|
135
|
+
bits += 8;
|
|
136
|
+
while (bits >= 5) {
|
|
137
|
+
result += BASE32_ALPHABET[buffer >>> bits - 5 & 31] ?? "";
|
|
138
|
+
bits -= 5;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (bits > 0) result += BASE32_ALPHABET[buffer << 5 - bits & 31] ?? "";
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function decodeBase32(value) {
|
|
145
|
+
if (value.length === 0) return null;
|
|
146
|
+
let buffer = 0;
|
|
147
|
+
let bits = 0;
|
|
148
|
+
const output = [];
|
|
149
|
+
for (const character of value) {
|
|
150
|
+
const digit = BASE32_ALPHABET.indexOf(character);
|
|
151
|
+
if (digit === -1) return null;
|
|
152
|
+
buffer = buffer << 5 | digit;
|
|
153
|
+
bits += 5;
|
|
154
|
+
if (bits >= 8) {
|
|
155
|
+
output.push(buffer >>> bits - 8 & 255);
|
|
156
|
+
bits -= 8;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (bits > 0 && (buffer & (1 << bits) - 1) !== 0) return null;
|
|
160
|
+
return new Uint8Array(output);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region ../registry-verification/dist/fetch-C8Kl1l1t.js
|
|
165
|
+
const DIGITS = /^\d+$/;
|
|
166
|
+
const IPV4_LITERAL = /^\d{1,3}(?:\.\d{1,3}){3}$/;
|
|
167
|
+
const IPV4_PART = /^\d{1,3}$/;
|
|
168
|
+
const IPV6_PART = /^[0-9a-f]{1,4}$/i;
|
|
169
|
+
const TRAILING_DOT$1 = /\.+$/;
|
|
170
|
+
const DEFAULT_FETCH_LIMITS = {
|
|
171
|
+
headerTimeoutMs: 1e4,
|
|
172
|
+
totalTimeoutMs: 3e4,
|
|
173
|
+
maxBytes: 25 * 1024 * 1024,
|
|
174
|
+
maxRedirects: 3
|
|
175
|
+
};
|
|
176
|
+
async function fetchVerifiedResource(value, options) {
|
|
177
|
+
const limits = {
|
|
178
|
+
headerTimeoutMs: options.headerTimeoutMs ?? DEFAULT_FETCH_LIMITS.headerTimeoutMs,
|
|
179
|
+
totalTimeoutMs: options.totalTimeoutMs ?? DEFAULT_FETCH_LIMITS.totalTimeoutMs,
|
|
180
|
+
maxBytes: options.maxBytes ?? DEFAULT_FETCH_LIMITS.maxBytes,
|
|
181
|
+
maxRedirects: options.maxRedirects ?? DEFAULT_FETCH_LIMITS.maxRedirects
|
|
182
|
+
};
|
|
183
|
+
if (!areValidLimits(limits)) return verificationError("INVALID_URL", "Fetch limits must be positive integers.");
|
|
184
|
+
const startedAt = Date.now();
|
|
185
|
+
let currentUrl = parseAndValidateUrl(value, void 0, options.allowHttpLocalhost === true);
|
|
186
|
+
if (!currentUrl.success) return currentUrl;
|
|
187
|
+
for (let redirects = 0;; redirects += 1) {
|
|
188
|
+
const remaining = limits.totalTimeoutMs - (Date.now() - startedAt);
|
|
189
|
+
if (remaining <= 0) return verificationError("RESOURCE_TIMEOUT", "The resource fetch exceeded its total timeout.");
|
|
190
|
+
const host = isAllowedLoopback(currentUrl.value, options.allowHttpLocalhost === true) ? {
|
|
191
|
+
success: true,
|
|
192
|
+
value: true
|
|
193
|
+
} : await validateHost(currentUrl.value, options.resolveHostname, remaining);
|
|
194
|
+
if (!host.success) return host;
|
|
195
|
+
const remainingAfterResolution = limits.totalTimeoutMs - (Date.now() - startedAt);
|
|
196
|
+
if (remainingAfterResolution <= 0) return verificationError("RESOURCE_TIMEOUT", "The resource fetch exceeded its total timeout.");
|
|
197
|
+
const response = await fetchResponse(options.fetch, currentUrl.value, Math.min(remainingAfterResolution, limits.headerTimeoutMs));
|
|
198
|
+
if (!response.success) return response;
|
|
199
|
+
if (isRedirect(response.value.status)) {
|
|
200
|
+
if (redirects >= limits.maxRedirects) return verificationError("REDIRECT_LIMIT_EXCEEDED", "The resource exceeded the redirect limit.");
|
|
201
|
+
const location = response.value.headers.get("location");
|
|
202
|
+
if (location === null) return verificationError("REDIRECT_LOCATION_MISSING", "The redirect response has no location header.");
|
|
203
|
+
currentUrl = parseAndValidateUrl(location, currentUrl.value, options.allowHttpLocalhost === true);
|
|
204
|
+
if (!currentUrl.success) return currentUrl;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (!response.value.ok && !options.allowedStatuses?.includes(response.value.status)) return verificationError("RESOURCE_STATUS_ERROR", `The resource returned HTTP ${response.value.status}.`);
|
|
208
|
+
const contentLength = response.value.headers.get("content-length");
|
|
209
|
+
if (contentLength !== null && (!DIGITS.test(contentLength) || Number(contentLength) > limits.maxBytes)) return verificationError("RESOURCE_SIZE_EXCEEDED", "The resource exceeds the byte limit.");
|
|
210
|
+
const bytes = await readResponse(response.value, limits.maxBytes, startedAt, limits.totalTimeoutMs);
|
|
211
|
+
if (!bytes.success) return bytes;
|
|
212
|
+
return {
|
|
213
|
+
success: true,
|
|
214
|
+
value: {
|
|
215
|
+
bytes: bytes.value,
|
|
216
|
+
url: currentUrl.value,
|
|
217
|
+
status: response.value.status,
|
|
218
|
+
headers: response.value.headers
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function parseAndValidateUrl(value, base, allowHttpLocalhost = false) {
|
|
224
|
+
let url;
|
|
225
|
+
try {
|
|
226
|
+
url = new URL(value, base);
|
|
227
|
+
} catch {
|
|
228
|
+
return verificationError("INVALID_URL", "The resource URL is invalid.");
|
|
229
|
+
}
|
|
230
|
+
if (url.protocol !== "https:" && !isAllowedLoopback(url, allowHttpLocalhost) || url.username !== "" || url.password !== "") return verificationError("INVALID_URL", "Resource URLs must use HTTPS and cannot include credentials.");
|
|
231
|
+
if (!isAllowedLoopback(url, allowHttpLocalhost) && (isIpLiteral(url.hostname) || isLocalHostname(url.hostname))) return verificationError("HOST_REJECTED", "The resource host is not permitted.");
|
|
232
|
+
return {
|
|
233
|
+
success: true,
|
|
234
|
+
value: url
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function isAllowedLoopback(url, enabled) {
|
|
238
|
+
if (!enabled || url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
239
|
+
const hostname = url.hostname.toLowerCase().replace(TRAILING_DOT$1, "");
|
|
240
|
+
return hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
|
|
241
|
+
}
|
|
242
|
+
async function validateHost(url, resolver, timeoutMs) {
|
|
243
|
+
try {
|
|
244
|
+
const addresses = await withTimeout(Promise.resolve().then(() => resolver(url.hostname)), timeoutMs);
|
|
245
|
+
if (addresses.length === 0 || addresses.some(isForbiddenAddress)) return verificationError("HOST_REJECTED", "The resource host resolved to a forbidden address.");
|
|
246
|
+
return {
|
|
247
|
+
success: true,
|
|
248
|
+
value: true
|
|
249
|
+
};
|
|
250
|
+
} catch (error) {
|
|
251
|
+
if (isAbortError(error)) return verificationError("RESOURCE_TIMEOUT", "The resource fetch exceeded its total timeout.");
|
|
252
|
+
return verificationError("HOST_REJECTED", "The resource host could not be validated.");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async function fetchResponse(fetchImplementation, url, timeoutMs) {
|
|
256
|
+
const controller = new AbortController();
|
|
257
|
+
try {
|
|
258
|
+
return {
|
|
259
|
+
success: true,
|
|
260
|
+
value: await withTimeout(Promise.resolve().then(() => fetchImplementation(url, {
|
|
261
|
+
method: "GET",
|
|
262
|
+
redirect: "manual",
|
|
263
|
+
signal: controller.signal
|
|
264
|
+
})), timeoutMs, () => controller.abort())
|
|
265
|
+
};
|
|
266
|
+
} catch (error) {
|
|
267
|
+
if (controller.signal.aborted || isAbortError(error)) return verificationError("RESOURCE_TIMEOUT", "The resource response headers timed out.");
|
|
268
|
+
return verificationError("FETCH_FAILED", "The resource request failed.");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async function readResponse(response, maximumBytes, startedAt, totalTimeoutMs) {
|
|
272
|
+
if (response.body === null) return {
|
|
273
|
+
success: true,
|
|
274
|
+
value: new Uint8Array()
|
|
275
|
+
};
|
|
276
|
+
const reader = response.body.getReader();
|
|
277
|
+
const chunks = [];
|
|
278
|
+
let length = 0;
|
|
279
|
+
try {
|
|
280
|
+
for (;;) {
|
|
281
|
+
const remaining = totalTimeoutMs - (Date.now() - startedAt);
|
|
282
|
+
if (remaining <= 0) {
|
|
283
|
+
await reader.cancel();
|
|
284
|
+
return verificationError("RESOURCE_TIMEOUT", "The resource fetch exceeded its total timeout.");
|
|
285
|
+
}
|
|
286
|
+
const chunk = await readWithTimeout(reader, remaining);
|
|
287
|
+
if (!chunk.success) {
|
|
288
|
+
await reader.cancel();
|
|
289
|
+
return chunk;
|
|
290
|
+
}
|
|
291
|
+
if (chunk.value.done) break;
|
|
292
|
+
const value = chunk.value.value;
|
|
293
|
+
length += value.length;
|
|
294
|
+
if (length > maximumBytes) {
|
|
295
|
+
await reader.cancel();
|
|
296
|
+
return verificationError("RESOURCE_SIZE_EXCEEDED", "The resource exceeds the byte limit.");
|
|
297
|
+
}
|
|
298
|
+
chunks.push(value);
|
|
299
|
+
}
|
|
300
|
+
} catch {
|
|
301
|
+
return verificationError("FETCH_FAILED", "The resource response could not be read.");
|
|
302
|
+
} finally {
|
|
303
|
+
reader.releaseLock();
|
|
304
|
+
}
|
|
305
|
+
const output = new Uint8Array(length);
|
|
306
|
+
let offset = 0;
|
|
307
|
+
for (const chunk of chunks) {
|
|
308
|
+
output.set(chunk, offset);
|
|
309
|
+
offset += chunk.length;
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
success: true,
|
|
313
|
+
value: output
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
async function readWithTimeout(reader, timeoutMs) {
|
|
317
|
+
try {
|
|
318
|
+
return {
|
|
319
|
+
success: true,
|
|
320
|
+
value: await withTimeout(Promise.resolve().then(() => reader.read()), timeoutMs)
|
|
321
|
+
};
|
|
322
|
+
} catch (error) {
|
|
323
|
+
if (isAbortError(error)) return verificationError("RESOURCE_TIMEOUT", "The resource fetch exceeded its total timeout.");
|
|
324
|
+
return verificationError("FETCH_FAILED", "The resource response could not be read.");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Every operation has both fulfillment and rejection handlers, so an operation
|
|
329
|
+
* that loses the timeout race cannot later become an unhandled rejection.
|
|
330
|
+
*/
|
|
331
|
+
function withTimeout(operation, timeoutMs, onTimeout) {
|
|
332
|
+
return new Promise((resolve, reject) => {
|
|
333
|
+
let settled = false;
|
|
334
|
+
const timeout = setTimeout(() => {
|
|
335
|
+
if (settled) return;
|
|
336
|
+
settled = true;
|
|
337
|
+
onTimeout?.();
|
|
338
|
+
reject(new DOMException("Timed out", "AbortError"));
|
|
339
|
+
}, timeoutMs);
|
|
340
|
+
operation.then((value) => {
|
|
341
|
+
if (settled) return void 0;
|
|
342
|
+
settled = true;
|
|
343
|
+
clearTimeout(timeout);
|
|
344
|
+
resolve(value);
|
|
345
|
+
}, (error) => {
|
|
346
|
+
if (settled) return void 0;
|
|
347
|
+
settled = true;
|
|
348
|
+
clearTimeout(timeout);
|
|
349
|
+
reject(error);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
function areValidLimits(limits) {
|
|
354
|
+
return Object.values(limits).every((value) => Number.isSafeInteger(value) && value > 0);
|
|
355
|
+
}
|
|
356
|
+
function isRedirect(status) {
|
|
357
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
358
|
+
}
|
|
359
|
+
function isAbortError(error) {
|
|
360
|
+
return error instanceof DOMException && error.name === "AbortError";
|
|
361
|
+
}
|
|
362
|
+
function isIpLiteral(hostname) {
|
|
363
|
+
return IPV4_LITERAL.test(hostname) || hostname.includes(":");
|
|
364
|
+
}
|
|
365
|
+
function isLocalHostname(hostname) {
|
|
366
|
+
const normalized = hostname.toLowerCase();
|
|
367
|
+
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") || normalized.endsWith(".internal");
|
|
368
|
+
}
|
|
369
|
+
function isForbiddenAddress(address) {
|
|
370
|
+
const ipv4 = parseIpv4(address);
|
|
371
|
+
if (ipv4 !== null) {
|
|
372
|
+
const [a, b] = ipv4;
|
|
373
|
+
return a === 0 || a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31 || a === 192 && (b === 0 || b === 168) || a === 198 && (b === 18 || b === 19) || a >= 224;
|
|
374
|
+
}
|
|
375
|
+
const ipv6 = parseIpv6(address);
|
|
376
|
+
if (ipv6 === null) return true;
|
|
377
|
+
const first = ipv6[0];
|
|
378
|
+
const isUnspecified = ipv6.every((part) => part === 0);
|
|
379
|
+
const isLoopback = ipv6.slice(0, 7).every((part) => part === 0) && ipv6[7] === 1;
|
|
380
|
+
const isPrivate = (first & 65024) === 64512;
|
|
381
|
+
const isLinkLocal = (first & 65472) === 65152;
|
|
382
|
+
const isMulticast = (first & 65280) === 65280;
|
|
383
|
+
if (ipv6.slice(0, 5).every((part) => part === 0) && ipv6[5] === 65535) return isForbiddenAddress(`${ipv6[6] >>> 8}.${ipv6[6] & 255}.${ipv6[7] >>> 8}.${ipv6[7] & 255}`);
|
|
384
|
+
return isUnspecified || isLoopback || isPrivate || isLinkLocal || isMulticast;
|
|
385
|
+
}
|
|
386
|
+
function parseIpv4(value) {
|
|
387
|
+
const parts = value.split(".");
|
|
388
|
+
if (parts.length !== 4) return null;
|
|
389
|
+
const numbers = parts.map((part) => IPV4_PART.test(part) ? Number(part) : NaN);
|
|
390
|
+
if (numbers.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) return null;
|
|
391
|
+
return [
|
|
392
|
+
numbers[0],
|
|
393
|
+
numbers[1],
|
|
394
|
+
numbers[2],
|
|
395
|
+
numbers[3]
|
|
396
|
+
];
|
|
397
|
+
}
|
|
398
|
+
function parseIpv6(value) {
|
|
399
|
+
if (value.includes(":::") || value.split("::").length > 2) return null;
|
|
400
|
+
const [before = "", after = ""] = value.split("::");
|
|
401
|
+
const head = before === "" ? [] : before.split(":");
|
|
402
|
+
const tail = after === "" ? [] : after.split(":");
|
|
403
|
+
const parts = [...head, ...tail];
|
|
404
|
+
if (parts.some((part) => !IPV6_PART.test(part)) || parts.length > 8) return null;
|
|
405
|
+
if (!value.includes("::") && parts.length !== 8) return null;
|
|
406
|
+
const zeroes = value.includes("::") ? 8 - parts.length : 0;
|
|
407
|
+
return [
|
|
408
|
+
...head,
|
|
409
|
+
...Array.from({ length: zeroes }).fill("0"),
|
|
410
|
+
...tail
|
|
411
|
+
].map((part) => Number.parseInt(part, 16));
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
//#endregion
|
|
415
|
+
//#region ../registry-verification/dist/artifact.js
|
|
416
|
+
const DID_DOCUMENT_MAX_BYTES = 256 * 1024;
|
|
417
|
+
const PLC_DID_PATTERN = /^did:plc:[a-z2-7]{24}$/;
|
|
418
|
+
const CID_PATTERN = /^b[a-z2-7]+$/;
|
|
419
|
+
const UNSAFE_PATH_SEGMENT = /[/\\?#]/;
|
|
420
|
+
async function fetchReleaseArtifact(input, options) {
|
|
421
|
+
const deadline = Date.now() + (options.totalTimeoutMs ?? DEFAULT_FETCH_LIMITS.totalTimeoutMs);
|
|
422
|
+
const { artifact } = input;
|
|
423
|
+
if (!artifact.blob && !artifact.url) return verificationError("RELEASE_ARTIFACT_SOURCE_MISSING", "The release artifact must provide a blob or URL.");
|
|
424
|
+
if (artifact.requiresAuth === true || input.auth !== void 0) return unsupportedAuth(input.auth);
|
|
425
|
+
const blobCid = modernBlobCid(artifact.blob);
|
|
426
|
+
const blobMetadata = blobCid && artifact.blob && "ref" in artifact.blob ? artifact.blob : void 0;
|
|
427
|
+
if (artifact.blob && !blobCid) return verificationError("BLOB_REF_INVALID", "Legacy blob references are not supported.");
|
|
428
|
+
if (blobCid) {
|
|
429
|
+
const expected = multihashFromBlobCid(blobCid);
|
|
430
|
+
if (!expected.success) return expected;
|
|
431
|
+
if (expected.value !== artifact.checksum) return verificationError("CHECKSUM_MISMATCH", "The artifact checksum does not match its blob reference CID.");
|
|
432
|
+
}
|
|
433
|
+
let lastError;
|
|
434
|
+
for (const cache of input.artifactCaches ?? []) {
|
|
435
|
+
const serviceEndpoint = recordScopedCacheEndpoint(cache);
|
|
436
|
+
if (!serviceEndpoint || !blobCid) continue;
|
|
437
|
+
const cacheUrl = recordScopedBlobCacheUrl(serviceEndpoint, input.record, blobCid);
|
|
438
|
+
if (!cacheUrl.success) {
|
|
439
|
+
lastError = cacheUrl.error;
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
const attemptOptions = withinDeadline(options, deadline);
|
|
443
|
+
if (!attemptOptions) return timedOut();
|
|
444
|
+
const result = await fetchAndVerify("artifact-cache", cacheUrl.value, artifact.checksum, withBlobSizeLimit(attemptOptions, blobMetadata), blobMetadata);
|
|
445
|
+
if (result.success) return result;
|
|
446
|
+
lastError = result.error;
|
|
447
|
+
}
|
|
448
|
+
if (blobCid) {
|
|
449
|
+
const resolutionOptions = withinDeadline(options, deadline);
|
|
450
|
+
if (!resolutionOptions) return timedOut();
|
|
451
|
+
const pds = input.pdsEndpoint ? {
|
|
452
|
+
success: true,
|
|
453
|
+
value: input.pdsEndpoint
|
|
454
|
+
} : await resolvePublisherPdsEndpoint(input.record.did, resolutionOptions);
|
|
455
|
+
if (pds.success) {
|
|
456
|
+
const url = blobUrl(pds.value, input.record.did, blobCid);
|
|
457
|
+
if (url.success) {
|
|
458
|
+
const attemptOptions = withinDeadline(options, deadline);
|
|
459
|
+
if (!attemptOptions) return timedOut();
|
|
460
|
+
const result = await fetchAndVerify("blob", url.value, artifact.checksum, withBlobSizeLimit(attemptOptions, blobMetadata), blobMetadata);
|
|
461
|
+
if (result.success) return result;
|
|
462
|
+
lastError = result.error;
|
|
463
|
+
} else lastError = url.error;
|
|
464
|
+
} else lastError = pds.error;
|
|
465
|
+
}
|
|
466
|
+
if (artifact.url) {
|
|
467
|
+
const attemptOptions = withinDeadline(options, deadline);
|
|
468
|
+
if (!attemptOptions) return timedOut();
|
|
469
|
+
const result = await fetchAndVerify("url", artifact.url, artifact.checksum, withBlobSizeLimit(attemptOptions, blobMetadata), blobMetadata);
|
|
470
|
+
if (result.success) return result;
|
|
471
|
+
lastError = result.error;
|
|
472
|
+
}
|
|
473
|
+
return lastError ? {
|
|
474
|
+
success: false,
|
|
475
|
+
error: lastError
|
|
476
|
+
} : verificationError("FETCH_FAILED", "The release artifact could not be fetched.");
|
|
477
|
+
}
|
|
478
|
+
function recordScopedBlobCacheUrl(serviceEndpoint, record, blobCid) {
|
|
479
|
+
try {
|
|
480
|
+
const endpoint = new URL(serviceEndpoint);
|
|
481
|
+
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.pathname !== "/" || endpoint.search || endpoint.hash) throw new Error();
|
|
482
|
+
const segments = [
|
|
483
|
+
"r",
|
|
484
|
+
record.did,
|
|
485
|
+
record.collection,
|
|
486
|
+
record.rkey,
|
|
487
|
+
record.cid,
|
|
488
|
+
blobCid
|
|
489
|
+
];
|
|
490
|
+
if (!CID_PATTERN.test(record.cid) || !CID_PATTERN.test(blobCid) || segments.some((segment) => !isSafePathSegment(segment))) throw new Error();
|
|
491
|
+
return {
|
|
492
|
+
success: true,
|
|
493
|
+
value: new URL(segments.join("/"), endpoint)
|
|
494
|
+
};
|
|
495
|
+
} catch {
|
|
496
|
+
return verificationError("INVALID_URL", "The record-scoped blob cache endpoint is invalid.");
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function recordScopedImageCacheUrl(serviceEndpoint, preset, record, blobCid) {
|
|
500
|
+
const raw = recordScopedBlobCacheUrl(serviceEndpoint, record, blobCid);
|
|
501
|
+
if (!raw.success) return raw;
|
|
502
|
+
const url = new URL(raw.value);
|
|
503
|
+
url.pathname = `/img/${preset}${url.pathname}`;
|
|
504
|
+
return {
|
|
505
|
+
success: true,
|
|
506
|
+
value: url
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
async function resolvePublisherPdsEndpoint(publisherDid, options) {
|
|
510
|
+
const documentUrl = didDocumentUrl(publisherDid);
|
|
511
|
+
if (!documentUrl) return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID is not supported.");
|
|
512
|
+
const fetched = await fetchVerifiedResource(documentUrl, {
|
|
513
|
+
...options,
|
|
514
|
+
maxBytes: DID_DOCUMENT_MAX_BYTES
|
|
515
|
+
});
|
|
516
|
+
if (!fetched.success) return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID document could not be fetched.");
|
|
517
|
+
let document;
|
|
518
|
+
try {
|
|
519
|
+
document = JSON.parse(new TextDecoder().decode(fetched.value.bytes));
|
|
520
|
+
} catch {
|
|
521
|
+
return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID document is malformed.");
|
|
522
|
+
}
|
|
523
|
+
if (!isRecord(document) || document.id !== publisherDid || !Array.isArray(document.service)) return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID document has no valid PDS service.");
|
|
524
|
+
const service = document.service.find((value) => isRecord(value) && (value.id === `${publisherDid}#atproto_pds` || value.id === "#atproto_pds") && value.type === "AtprotoPersonalDataServer" && typeof value.serviceEndpoint === "string");
|
|
525
|
+
if (!isRecord(service) || typeof service.serviceEndpoint !== "string") return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID document has no valid PDS service.");
|
|
526
|
+
try {
|
|
527
|
+
const endpoint = new URL(service.serviceEndpoint);
|
|
528
|
+
if (!(options.allowHttpLocalhost === true && endpoint.protocol === "http:" && (endpoint.hostname === "localhost" || endpoint.hostname === "127.0.0.1")) && endpoint.protocol !== "https:" || endpoint.username || endpoint.password) throw new Error();
|
|
529
|
+
return {
|
|
530
|
+
success: true,
|
|
531
|
+
value: endpoint.href
|
|
532
|
+
};
|
|
533
|
+
} catch {
|
|
534
|
+
return verificationError("PDS_RESOLUTION_FAILED", "The publisher DID document has no valid PDS service.");
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
async function fetchAndVerify(source, url, checksum, options, blobMetadata) {
|
|
538
|
+
const fetched = await fetchVerifiedResource(url, options);
|
|
539
|
+
if (!fetched.success) return blobMetadata && fetched.error.code === "RESOURCE_SIZE_EXCEEDED" ? verificationError("BLOB_METADATA_MISMATCH", "The fetched artifact size does not match its signed blob metadata.") : fetched;
|
|
540
|
+
const verified = await verifyMultihash(fetched.value.bytes, checksum);
|
|
541
|
+
if (!verified.success) return verified;
|
|
542
|
+
const contentType = fetched.value.headers.get("content-type")?.split(";", 1)[0]?.trim();
|
|
543
|
+
if (blobMetadata && (fetched.value.bytes.byteLength !== blobMetadata.size || contentType !== void 0 && contentType !== blobMetadata.mimeType)) return verificationError("BLOB_METADATA_MISMATCH", "The fetched artifact does not match its signed blob metadata.");
|
|
544
|
+
return {
|
|
545
|
+
success: true,
|
|
546
|
+
value: {
|
|
547
|
+
bytes: fetched.value.bytes,
|
|
548
|
+
source,
|
|
549
|
+
url: fetched.value.url
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
function withBlobSizeLimit(options, blobMetadata) {
|
|
554
|
+
if (!blobMetadata) return options;
|
|
555
|
+
return {
|
|
556
|
+
...options,
|
|
557
|
+
maxBytes: Math.min(options.maxBytes ?? DEFAULT_FETCH_LIMITS.maxBytes, blobMetadata.size)
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function blobUrl(pdsEndpoint, publisherDid, cid) {
|
|
561
|
+
try {
|
|
562
|
+
const url = new URL("/xrpc/com.atproto.sync.getBlob", pdsEndpoint);
|
|
563
|
+
url.searchParams.set("did", publisherDid);
|
|
564
|
+
url.searchParams.set("cid", cid);
|
|
565
|
+
return {
|
|
566
|
+
success: true,
|
|
567
|
+
value: url
|
|
568
|
+
};
|
|
569
|
+
} catch {
|
|
570
|
+
return verificationError("PDS_RESOLUTION_FAILED", "The publisher PDS endpoint is invalid.");
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function didDocumentUrl(did) {
|
|
574
|
+
if (PLC_DID_PATTERN.test(did)) return `https://plc.directory/${encodeURIComponent(did)}`;
|
|
575
|
+
if (!did.startsWith("did:web:")) return null;
|
|
576
|
+
try {
|
|
577
|
+
const parts = did.slice(8).split(":").map(decodeURIComponent);
|
|
578
|
+
const host = parts.shift();
|
|
579
|
+
if (!host || parts.some((part) => part === "" || part === "." || part === "..")) return null;
|
|
580
|
+
const path = parts.length === 0 ? "/.well-known/did.json" : `/${parts.join("/")}/did.json`;
|
|
581
|
+
return new URL(path, `https://${host}`).href;
|
|
582
|
+
} catch {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
function unsupportedAuth(auth) {
|
|
587
|
+
return verificationError("AUTH_METHOD_UNSUPPORTED", UNSUPPORTED_AUTH_MESSAGE, unsupportedAuthDetails(auth));
|
|
588
|
+
}
|
|
589
|
+
function withinDeadline(options, deadline) {
|
|
590
|
+
const remaining = deadline - Date.now();
|
|
591
|
+
if (remaining <= 0) return null;
|
|
592
|
+
return {
|
|
593
|
+
...options,
|
|
594
|
+
totalTimeoutMs: remaining
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function timedOut() {
|
|
598
|
+
return verificationError("RESOURCE_TIMEOUT", "Artifact retrieval exceeded its total timeout.");
|
|
599
|
+
}
|
|
600
|
+
function isRecord(value) {
|
|
601
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
602
|
+
}
|
|
603
|
+
function modernBlobCid(blob) {
|
|
604
|
+
if (!blob || !("ref" in blob) || typeof blob.ref?.$link !== "string") return null;
|
|
605
|
+
return blob.ref.$link;
|
|
606
|
+
}
|
|
607
|
+
function recordScopedCacheEndpoint(value) {
|
|
608
|
+
if (!isRecord(value) || value.$type !== RECORD_SCOPED_BLOB_CACHE_TYPE) return null;
|
|
609
|
+
return typeof value.serviceEndpoint === "string" ? value.serviceEndpoint : null;
|
|
610
|
+
}
|
|
611
|
+
function isSafePathSegment(value) {
|
|
612
|
+
if (value.length === 0 || UNSAFE_PATH_SEGMENT.test(value)) return false;
|
|
613
|
+
for (const character of value) {
|
|
614
|
+
const codePoint = character.codePointAt(0);
|
|
615
|
+
if (codePoint !== void 0 && (codePoint <= 31 || codePoint === 127)) return false;
|
|
616
|
+
}
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/registry/artifact-fetch.ts
|
|
622
|
+
const TRAILING_DOT = /\.+$/;
|
|
623
|
+
const HEADER_END = new Uint8Array([
|
|
624
|
+
13,
|
|
625
|
+
10,
|
|
626
|
+
13,
|
|
627
|
+
10
|
|
628
|
+
]);
|
|
629
|
+
const CRLF = new Uint8Array([13, 10]);
|
|
630
|
+
const STATUS_LINE_RE = /^HTTP\/1\.[01] ([2-5][0-9]{2})(?: .*)?$/;
|
|
631
|
+
const HEADER_NAME_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
632
|
+
const FOLDED_HEADER_RE = /^[ \t]/;
|
|
633
|
+
const CONTENT_LENGTH_RE = /^(0|[1-9][0-9]*)$/;
|
|
634
|
+
const CHUNK_SIZE_RE = /^[0-9A-Fa-f]+$/;
|
|
635
|
+
const MAX_HEADER_BYTES = 32 * 1024;
|
|
636
|
+
const LOCALHOST_HOSTNAMES = new Set([
|
|
637
|
+
"localhost",
|
|
638
|
+
"localhost.localdomain",
|
|
639
|
+
"ip6-localhost",
|
|
640
|
+
"ip6-loopback"
|
|
641
|
+
]);
|
|
642
|
+
let defaultTransport = null;
|
|
643
|
+
function isLocalhostHostname(hostname) {
|
|
644
|
+
const normalized = hostname.toLowerCase().replace(TRAILING_DOT, "");
|
|
645
|
+
return LOCALHOST_HOSTNAMES.has(normalized) || normalized.endsWith(".localhost") || normalized === "127.0.0.1" || normalized === "::1" || normalized === "[::1]" || normalized.startsWith("::ffff:127.") || normalized.startsWith("::ffff:7f00:");
|
|
646
|
+
}
|
|
647
|
+
async function resolveSafeArtifactTarget(urlString) {
|
|
648
|
+
let url;
|
|
649
|
+
try {
|
|
650
|
+
url = new URL(urlString);
|
|
651
|
+
} catch {
|
|
652
|
+
throw new Error(`Invalid artifact URL: ${urlString}`);
|
|
653
|
+
}
|
|
654
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") throw new Error(`Artifact URL protocol not allowed: ${url.protocol}`);
|
|
655
|
+
if (url.username || url.password) throw new Error("Artifact URL must not contain embedded credentials");
|
|
656
|
+
const hostname = stripIpv6Brackets(url.hostname.toLowerCase().replace(TRAILING_DOT, ""));
|
|
657
|
+
const localhost = isLocalhostHostname(hostname);
|
|
658
|
+
if (!import.meta.env.DEV) {
|
|
659
|
+
if (url.protocol === "http:") throw new Error("Artifact URL must use https");
|
|
660
|
+
if (localhost) throw new Error(`Artifact URL points to localhost: ${hostname}`);
|
|
661
|
+
} else if (url.protocol === "http:" && !localhost) throw new Error("Artifact URL must use https (http allowed only for localhost in dev)");
|
|
662
|
+
if (localhost) return {
|
|
663
|
+
url,
|
|
664
|
+
addresses: []
|
|
665
|
+
};
|
|
666
|
+
try {
|
|
667
|
+
return await resolveAndValidateExternalUrlTarget(url.href);
|
|
668
|
+
} catch (error) {
|
|
669
|
+
if (error instanceof SsrfError) throw new Error(`Artifact URL rejected: ${error.message}`, { cause: error });
|
|
670
|
+
throw error;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
async function fetchRegistryArtifactUrl(urlString, options) {
|
|
674
|
+
if (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes < 0) throw new TypeError("Registry artifact response limit is invalid");
|
|
675
|
+
const target = await resolveSafeArtifactTarget(urlString);
|
|
676
|
+
if (target.addresses.length === 0) return globalThis.fetch(target.url, {
|
|
677
|
+
redirect: "manual",
|
|
678
|
+
signal: options.signal
|
|
679
|
+
});
|
|
680
|
+
const result = await (defaultTransport ?? await createRuntimeRegistryArtifactTransport()).fetch({
|
|
681
|
+
url: target.url,
|
|
682
|
+
allowedAddresses: target.addresses,
|
|
683
|
+
signal: options.signal,
|
|
684
|
+
maxResponseBytes: options.maxResponseBytes
|
|
685
|
+
});
|
|
686
|
+
if (!target.addresses.includes(result.connectedAddress)) {
|
|
687
|
+
await result.response.body?.cancel().catch(() => void 0);
|
|
688
|
+
throw new Error("Registry artifact transport connected outside the validated address set");
|
|
689
|
+
}
|
|
690
|
+
return result.response;
|
|
691
|
+
}
|
|
692
|
+
async function createRuntimeRegistryArtifactTransport() {
|
|
693
|
+
try {
|
|
694
|
+
const connect = objectProperty(await import("cloudflare:sockets"), "connect");
|
|
695
|
+
if (!isWorkerSocketConnect(connect)) throw new TypeError("Workers socket binding is invalid");
|
|
696
|
+
return createWorkersRegistryArtifactTransport(connect);
|
|
697
|
+
} catch {
|
|
698
|
+
return createNodeRegistryArtifactTransport();
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
function createWorkersRegistryArtifactTransport(connect) {
|
|
702
|
+
return { async fetch(input) {
|
|
703
|
+
let lastError;
|
|
704
|
+
for (const address of input.allowedAddresses) {
|
|
705
|
+
if (input.signal.aborted) throw new Error("Registry artifact request was aborted");
|
|
706
|
+
let socket;
|
|
707
|
+
let tls;
|
|
708
|
+
try {
|
|
709
|
+
socket = connect({
|
|
710
|
+
hostname: address,
|
|
711
|
+
port: parseHttpsPort(input.url)
|
|
712
|
+
}, {
|
|
713
|
+
secureTransport: "starttls",
|
|
714
|
+
allowHalfOpen: false
|
|
715
|
+
});
|
|
716
|
+
await abortable(socket.opened, input.signal, () => socket?.close());
|
|
717
|
+
tls = socket.startTls({ expectedServerHostname: stripIpv6Brackets(input.url.hostname) });
|
|
718
|
+
await abortable(tls.opened, input.signal, () => tls?.close());
|
|
719
|
+
const writer = tls.writable.getWriter();
|
|
720
|
+
try {
|
|
721
|
+
await abortable(writer.write(buildHttpRequest(input.url)), input.signal, () => tls?.close());
|
|
722
|
+
} finally {
|
|
723
|
+
writer.releaseLock();
|
|
724
|
+
}
|
|
725
|
+
const bytes = await readWorkerSocketResponse(tls, input.maxResponseBytes + MAX_HEADER_BYTES, input.signal);
|
|
726
|
+
await tls.close().catch(() => void 0);
|
|
727
|
+
return {
|
|
728
|
+
response: parsedResponseToWebResponse(parsePinnedHttpResponse(bytes, input.maxResponseBytes)),
|
|
729
|
+
connectedAddress: address
|
|
730
|
+
};
|
|
731
|
+
} catch (error) {
|
|
732
|
+
await Promise.all([tls?.close().catch(() => void 0), socket?.close().catch(() => void 0)]);
|
|
733
|
+
if (input.signal.aborted) throw error;
|
|
734
|
+
lastError = error;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
throw new Error("Registry artifact transport could not connect to an approved address", { cause: lastError });
|
|
738
|
+
} };
|
|
739
|
+
}
|
|
740
|
+
async function createNodeRegistryArtifactTransport() {
|
|
741
|
+
const { request } = await import("node:https");
|
|
742
|
+
return { async fetch(input) {
|
|
743
|
+
let lastError;
|
|
744
|
+
for (const address of input.allowedAddresses) try {
|
|
745
|
+
return {
|
|
746
|
+
response: await new Promise((resolve, reject) => {
|
|
747
|
+
const chunks = [];
|
|
748
|
+
let total = 0;
|
|
749
|
+
const req = request({
|
|
750
|
+
protocol: "https:",
|
|
751
|
+
hostname: stripIpv6Brackets(input.url.hostname),
|
|
752
|
+
port: parseHttpsPort(input.url),
|
|
753
|
+
path: `${input.url.pathname}${input.url.search}`,
|
|
754
|
+
method: "GET",
|
|
755
|
+
agent: false,
|
|
756
|
+
headers: {
|
|
757
|
+
Host: input.url.host,
|
|
758
|
+
Connection: "close",
|
|
759
|
+
"Accept-Encoding": "identity"
|
|
760
|
+
},
|
|
761
|
+
lookup: (_hostname, _options, callback) => {
|
|
762
|
+
callback(null, address, address.includes(":") ? 6 : 4);
|
|
763
|
+
},
|
|
764
|
+
signal: input.signal
|
|
765
|
+
}, (upstream) => {
|
|
766
|
+
const contentEncoding = upstream.headers["content-encoding"];
|
|
767
|
+
if (contentEncoding && contentEncoding.toLowerCase() !== "identity") {
|
|
768
|
+
upstream.destroy(/* @__PURE__ */ new Error("Registry artifact response content encoding is unsupported"));
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
upstream.on("data", (chunk) => {
|
|
772
|
+
total += chunk.byteLength;
|
|
773
|
+
if (total > input.maxResponseBytes) {
|
|
774
|
+
upstream.destroy(/* @__PURE__ */ new RangeError("Registry artifact response exceeds its byte limit"));
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
chunks.push(new Uint8Array(chunk));
|
|
778
|
+
});
|
|
779
|
+
upstream.once("error", reject);
|
|
780
|
+
upstream.once("end", () => {
|
|
781
|
+
const bytes = concatBytes(chunks, total);
|
|
782
|
+
const headers = new Headers();
|
|
783
|
+
for (let index = 0; index < upstream.rawHeaders.length; index += 2) headers.append(upstream.rawHeaders[index], upstream.rawHeaders[index + 1]);
|
|
784
|
+
resolve(parsedResponseToWebResponse({
|
|
785
|
+
status: upstream.statusCode ?? 502,
|
|
786
|
+
headers,
|
|
787
|
+
body: bytes
|
|
788
|
+
}));
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
req.once("error", reject);
|
|
792
|
+
req.end();
|
|
793
|
+
}),
|
|
794
|
+
connectedAddress: address
|
|
795
|
+
};
|
|
796
|
+
} catch (error) {
|
|
797
|
+
if (input.signal.aborted) throw error;
|
|
798
|
+
lastError = error;
|
|
799
|
+
}
|
|
800
|
+
throw new Error("Registry artifact transport could not connect to an approved address", { cause: lastError });
|
|
801
|
+
} };
|
|
802
|
+
}
|
|
803
|
+
function parsePinnedHttpResponse(bytes, maxResponseBytes) {
|
|
804
|
+
const headerEnd = findSequence(bytes, HEADER_END, 0);
|
|
805
|
+
if (headerEnd === -1 || headerEnd > MAX_HEADER_BYTES) throw new Error("Registry artifact response headers are invalid or too large");
|
|
806
|
+
const lines = new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, headerEnd)).split("\r\n");
|
|
807
|
+
const statusMatch = STATUS_LINE_RE.exec(lines.shift() ?? "");
|
|
808
|
+
if (!statusMatch) throw new Error("Registry artifact response status line is invalid");
|
|
809
|
+
const headers = new Headers();
|
|
810
|
+
const rawHeaders = /* @__PURE__ */ new Map();
|
|
811
|
+
for (const line of lines) {
|
|
812
|
+
if (FOLDED_HEADER_RE.test(line)) throw new Error("Registry artifact response uses folded headers");
|
|
813
|
+
const separator = line.indexOf(":");
|
|
814
|
+
if (separator < 1) throw new Error("Registry artifact response header is invalid");
|
|
815
|
+
const name = line.slice(0, separator);
|
|
816
|
+
const value = line.slice(separator + 1).trim();
|
|
817
|
+
if (!HEADER_NAME_RE.test(name) || containsInvalidHeaderValue(value)) throw new Error("Registry artifact response header is invalid");
|
|
818
|
+
const normalized = name.toLowerCase();
|
|
819
|
+
const values = rawHeaders.get(normalized) ?? [];
|
|
820
|
+
values.push(value);
|
|
821
|
+
rawHeaders.set(normalized, values);
|
|
822
|
+
headers.append(name, value);
|
|
823
|
+
}
|
|
824
|
+
const contentEncoding = rawHeaders.get("content-encoding");
|
|
825
|
+
if (contentEncoding && (contentEncoding.length !== 1 || contentEncoding[0]?.toLowerCase() !== "identity")) throw new Error("Registry artifact response content encoding is unsupported");
|
|
826
|
+
const contentLength = rawHeaders.get("content-length");
|
|
827
|
+
const transferEncoding = rawHeaders.get("transfer-encoding");
|
|
828
|
+
if (contentLength && transferEncoding) throw new Error("Registry artifact response framing is ambiguous");
|
|
829
|
+
const bodyBytes = bytes.subarray(headerEnd + HEADER_END.length);
|
|
830
|
+
let body;
|
|
831
|
+
if (transferEncoding) {
|
|
832
|
+
if (transferEncoding.length !== 1 || transferEncoding[0]?.toLowerCase() !== "chunked") throw new Error("Registry artifact response transfer encoding is unsupported");
|
|
833
|
+
body = decodeChunkedBody(bodyBytes, maxResponseBytes);
|
|
834
|
+
} else if (contentLength) {
|
|
835
|
+
if (contentLength.length !== 1 || !CONTENT_LENGTH_RE.test(contentLength[0])) throw new Error("Registry artifact response content length is invalid");
|
|
836
|
+
const length = Number(contentLength[0]);
|
|
837
|
+
if (!Number.isSafeInteger(length) || length !== bodyBytes.byteLength) throw new Error("Registry artifact response body length does not match its framing");
|
|
838
|
+
body = new Uint8Array(bodyBytes);
|
|
839
|
+
} else body = new Uint8Array(bodyBytes);
|
|
840
|
+
if (body.byteLength > maxResponseBytes) throw new RangeError("Registry artifact response exceeds its byte limit");
|
|
841
|
+
return {
|
|
842
|
+
status: Number(statusMatch[1]),
|
|
843
|
+
headers,
|
|
844
|
+
body
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
function parsedResponseToWebResponse(parsed) {
|
|
848
|
+
const bodyAllowed = ![
|
|
849
|
+
204,
|
|
850
|
+
205,
|
|
851
|
+
304
|
|
852
|
+
].includes(parsed.status);
|
|
853
|
+
let body = null;
|
|
854
|
+
if (bodyAllowed) {
|
|
855
|
+
body = new ArrayBuffer(parsed.body.byteLength);
|
|
856
|
+
new Uint8Array(body).set(parsed.body);
|
|
857
|
+
}
|
|
858
|
+
return new Response(body, {
|
|
859
|
+
status: parsed.status,
|
|
860
|
+
headers: parsed.headers
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
function buildHttpRequest(url) {
|
|
864
|
+
return new TextEncoder().encode([
|
|
865
|
+
`GET ${url.pathname}${url.search} HTTP/1.1`,
|
|
866
|
+
`Host: ${url.host}`,
|
|
867
|
+
"Connection: close",
|
|
868
|
+
"Accept-Encoding: identity",
|
|
869
|
+
"",
|
|
870
|
+
""
|
|
871
|
+
].join("\r\n"));
|
|
872
|
+
}
|
|
873
|
+
async function readWorkerSocketResponse(socket, maximumBytes, signal) {
|
|
874
|
+
const reader = socket.readable.getReader();
|
|
875
|
+
const chunks = [];
|
|
876
|
+
let total = 0;
|
|
877
|
+
try {
|
|
878
|
+
for (;;) {
|
|
879
|
+
const next = await abortable(reader.read(), signal, () => socket.close());
|
|
880
|
+
if (next.done) break;
|
|
881
|
+
total += next.value.byteLength;
|
|
882
|
+
if (total > maximumBytes) throw new RangeError("Registry artifact response exceeds its byte limit");
|
|
883
|
+
chunks.push(next.value);
|
|
884
|
+
}
|
|
885
|
+
} finally {
|
|
886
|
+
reader.releaseLock();
|
|
887
|
+
}
|
|
888
|
+
return concatBytes(chunks, total);
|
|
889
|
+
}
|
|
890
|
+
function decodeChunkedBody(bytes, maximumBytes) {
|
|
891
|
+
const chunks = [];
|
|
892
|
+
let offset = 0;
|
|
893
|
+
let total = 0;
|
|
894
|
+
for (;;) {
|
|
895
|
+
const lineEnd = findSequence(bytes, CRLF, offset);
|
|
896
|
+
if (lineEnd === -1 || lineEnd - offset > 128) throw new Error("Registry artifact chunk size line is invalid");
|
|
897
|
+
const sizeText = new TextDecoder().decode(bytes.subarray(offset, lineEnd)).split(";", 1)[0];
|
|
898
|
+
if (!sizeText || !CHUNK_SIZE_RE.test(sizeText)) throw new Error("Registry artifact chunk size is invalid");
|
|
899
|
+
const size = Number.parseInt(sizeText, 16);
|
|
900
|
+
if (!Number.isSafeInteger(size)) throw new Error("Registry artifact chunk size is invalid");
|
|
901
|
+
offset = lineEnd + CRLF.length;
|
|
902
|
+
if (size === 0) {
|
|
903
|
+
if (offset + CRLF.length !== bytes.length || bytes[offset] !== 13 || bytes[offset + 1] !== 10) throw new Error("Registry artifact chunk trailer is invalid");
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
if (offset + size + CRLF.length > bytes.length) throw new Error("Registry artifact chunk body is truncated");
|
|
907
|
+
if (bytes[offset + size] !== 13 || bytes[offset + size + 1] !== 10) throw new Error("Registry artifact chunk delimiter is invalid");
|
|
908
|
+
total += size;
|
|
909
|
+
if (total > maximumBytes) throw new RangeError("Registry artifact response exceeds its byte limit");
|
|
910
|
+
chunks.push(new Uint8Array(bytes.subarray(offset, offset + size)));
|
|
911
|
+
offset += size + CRLF.length;
|
|
912
|
+
}
|
|
913
|
+
return concatBytes(chunks, total);
|
|
914
|
+
}
|
|
915
|
+
function findSequence(bytes, sequence, start) {
|
|
916
|
+
outer: for (let offset = start; offset <= bytes.length - sequence.length; offset += 1) {
|
|
917
|
+
for (let index = 0; index < sequence.length; index += 1) if (bytes[offset + index] !== sequence[index]) continue outer;
|
|
918
|
+
return offset;
|
|
919
|
+
}
|
|
920
|
+
return -1;
|
|
921
|
+
}
|
|
922
|
+
function concatBytes(chunks, total) {
|
|
923
|
+
const bytes = new Uint8Array(total);
|
|
924
|
+
let offset = 0;
|
|
925
|
+
for (const chunk of chunks) {
|
|
926
|
+
bytes.set(chunk, offset);
|
|
927
|
+
offset += chunk.byteLength;
|
|
928
|
+
}
|
|
929
|
+
return bytes;
|
|
930
|
+
}
|
|
931
|
+
function containsInvalidHeaderValue(value) {
|
|
932
|
+
for (const character of value) {
|
|
933
|
+
const code = character.codePointAt(0);
|
|
934
|
+
if (code === 0 || code === 10 || code === 13) return true;
|
|
935
|
+
}
|
|
936
|
+
return false;
|
|
937
|
+
}
|
|
938
|
+
function parseHttpsPort(url) {
|
|
939
|
+
const port = url.port === "" ? 443 : Number(url.port);
|
|
940
|
+
if (!Number.isSafeInteger(port) || port < 1 || port > 65535) throw new TypeError("Registry artifact HTTPS port is invalid");
|
|
941
|
+
return port;
|
|
942
|
+
}
|
|
943
|
+
function stripIpv6Brackets(hostname) {
|
|
944
|
+
return hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
|
|
945
|
+
}
|
|
946
|
+
function objectProperty(value, key) {
|
|
947
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
948
|
+
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
949
|
+
}
|
|
950
|
+
function isWorkerSocketConnect(value) {
|
|
951
|
+
return typeof value === "function";
|
|
952
|
+
}
|
|
953
|
+
async function abortable(operation, signal, onAbort) {
|
|
954
|
+
if (signal.aborted) throw new Error("Registry artifact request was aborted");
|
|
955
|
+
let abort;
|
|
956
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
957
|
+
abort = () => {
|
|
958
|
+
onAbort();
|
|
959
|
+
reject(/* @__PURE__ */ new Error("Registry artifact request was aborted"));
|
|
960
|
+
};
|
|
961
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
962
|
+
});
|
|
963
|
+
try {
|
|
964
|
+
return await Promise.race([operation, aborted]);
|
|
965
|
+
} finally {
|
|
966
|
+
if (abort) signal.removeEventListener("abort", abort);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
//#endregion
|
|
971
|
+
export { fetchVerifiedResource as a, verifyMultihash as c, resolvePublisherPdsEndpoint as i, verificationError as l, fetchReleaseArtifact as n, computeArtifactDigestCandidates as o, recordScopedImageCacheUrl as r, multihashFromBlobCid as s, fetchRegistryArtifactUrl as t };
|
|
972
|
+
//# sourceMappingURL=artifact-fetch-P2JXVwOq.mjs.map
|