emdash 0.36.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-CzL3H752.d.mts → adapters-BDQwg236.d.mts} +4 -2
- package/dist/{adapters-CzL3H752.d.mts.map → adapters-BDQwg236.d.mts.map} +1 -1
- package/dist/{allowed-origins-maylGaHv.mjs → allowed-origins-BGglilcs.mjs} +2 -2
- package/dist/{allowed-origins-maylGaHv.mjs.map → allowed-origins-BGglilcs.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +17 -17
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -5
- package/dist/api-Dz6rgoa3.mjs +10040 -0
- package/dist/api-Dz6rgoa3.mjs.map +1 -0
- package/dist/{api-tokens-9YrrCoE6.mjs → api-tokens-BSsQACNe.mjs} +2 -2
- package/dist/{api-tokens-9YrrCoE6.mjs.map → api-tokens-BSsQACNe.mjs.map} +1 -1
- package/dist/{apply-B_VMpJ2P.mjs → apply-B4SIOxR1.mjs} +18 -18
- package/dist/{apply-B_VMpJ2P.mjs.map → apply-B4SIOxR1.mjs.map} +1 -1
- 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 +110 -37
- 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 +2 -2
- package/dist/astro/middleware/redirect.mjs +3 -3
- package/dist/astro/middleware/request-context.mjs +2 -2
- 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 +157 -195
- 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 +3 -3
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +8 -8
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +8 -8
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +8 -8
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -14
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +14 -14
- package/dist/astro/routes/api/admin/bylines/index.mjs +14 -14
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +12 -12
- 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 +3 -3
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +2 -2
- package/dist/astro/routes/api/admin/media-usage/activation.mjs +10 -10
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +13 -13
- package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +13 -13
- package/dist/astro/routes/api/admin/media-usage/progress.mjs +11 -11
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +14 -14
- package/dist/astro/routes/api/admin/media-usage/work/index.mjs +13 -13
- package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +13 -13
- 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 +49 -49
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +49 -49
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +47 -47
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +47 -47
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +48 -48
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +48 -48
- package/dist/astro/routes/api/admin/plugins/index.mjs +47 -47
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +47 -47
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +48 -48
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +47 -47
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +48 -48
- 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 +54 -50
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +17 -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 +55 -51
- 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 +93 -0
- package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/updates.mjs +47 -47
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +47 -47
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +47 -47
- 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 +2 -2
- 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 +10 -10
- package/dist/astro/routes/api/auth/invite/index.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/register-options.mjs +9 -9
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +9 -9
- 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 +3 -3
- 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 +11 -11
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +9 -9
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/verify.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/complete.mjs +10 -10
- package/dist/astro/routes/api/auth/signup/request.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +13 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +12 -12
- 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 +14 -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_/permanent.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +10 -10
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +13 -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 +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +15 -15
- 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.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +13 -13
- 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 +14 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/authors.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -7
- package/dist/astro/routes/api/dashboard.mjs +7 -7
- 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 +15 -15
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +2 -2
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +15 -15
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +22 -22
- package/dist/astro/routes/api/manifest.mjs +3 -3
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +188 -65
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -9
- 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 +5 -5
- package/dist/astro/routes/api/media/_id_/usage.mjs +16 -16
- package/dist/astro/routes/api/media/_id_.mjs +15 -15
- 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 +15 -13
- 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 +47 -24
- 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 +104 -38
- 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 +8 -8
- package/dist/astro/routes/api/redirects/404s/summary.mjs +8 -8
- package/dist/astro/routes/api/redirects/_id_.mjs +9 -9
- package/dist/astro/routes/api/redirects/index.mjs +9 -9
- package/dist/astro/routes/api/relations/_id_/index.mjs +15 -15
- package/dist/astro/routes/api/relations/_id_/translations.mjs +10 -10
- package/dist/astro/routes/api/relations/index.mjs +15 -15
- 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 +47 -47
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +47 -47
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +47 -47
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +47 -47
- package/dist/astro/routes/api/schema/collections/index.mjs +47 -47
- package/dist/astro/routes/api/schema/collections/reorder.mjs +47 -47
- package/dist/astro/routes/api/schema/index.mjs +8 -8
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +47 -47
- package/dist/astro/routes/api/schema/orphans/index.mjs +47 -47
- package/dist/astro/routes/api/search/enable.mjs +10 -10
- package/dist/astro/routes/api/search/index.mjs +9 -9
- package/dist/astro/routes/api/search/rebuild.mjs +10 -10
- package/dist/astro/routes/api/search/stats.mjs +5 -5
- package/dist/astro/routes/api/search/suggest.mjs +9 -9
- package/dist/astro/routes/api/sections/_slug_.mjs +9 -9
- package/dist/astro/routes/api/sections/index.mjs +9 -9
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +5 -5
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +4 -4
- package/dist/astro/routes/api/settings/backups/export.mjs +5 -5
- package/dist/astro/routes/api/settings/backups/index.mjs +6 -6
- package/dist/astro/routes/api/settings/email.mjs +4 -4
- 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 +18 -14
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +11 -11
- package/dist/astro/routes/api/setup/admin.mjs +10 -10
- package/dist/astro/routes/api/setup/dev-bypass.mjs +25 -25
- package/dist/astro/routes/api/setup/dev-reset.mjs +1 -1
- package/dist/astro/routes/api/setup/index.mjs +25 -25
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +6 -6
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +19 -15
- 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 +20 -16
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +24 -17
- 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 +19 -15
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +13 -13
- package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -18
- 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 +19 -15
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +4 -4
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +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 +16 -12
- 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 +14 -11
- 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 +7 -5
- 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 +14 -11
- 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 +5 -5
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +8 -8
- package/dist/astro/routes/sitemap.xml.mjs +6 -6
- package/dist/astro/types.d.mts +32 -17
- 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-Bkf_UHhD.mjs} +2 -2
- package/dist/{authorize-ByYs-Uxs.mjs.map → authorize-Bkf_UHhD.mjs.map} +1 -1
- package/dist/{backup-ChyHfIoX.mjs → backup-rwVAl9NI.mjs} +4 -4
- package/dist/{backup-ChyHfIoX.mjs.map → backup-rwVAl9NI.mjs.map} +1 -1
- package/dist/{bundle-DZFhFurR.mjs → bundle-C8S2Zl6U.mjs} +3 -3
- package/dist/{bundle-DZFhFurR.mjs.map → bundle-C8S2Zl6U.mjs.map} +1 -1
- package/dist/{byline-Cpnwrje1.mjs → byline-DuhF7NWl.mjs} +25 -12
- package/dist/byline-DuhF7NWl.mjs.map +1 -0
- package/dist/{byline-fields-CAyA_Umd.mjs → byline-fields-BovY4KYM.mjs} +1 -1
- package/dist/{byline-fields-CAyA_Umd.mjs.map → byline-fields-BovY4KYM.mjs.map} +1 -1
- package/dist/{bylines-BSo9B9RX.mjs → bylines-CJ5nd6Lw.mjs} +6 -6
- package/dist/{bylines-BSo9B9RX.mjs.map → bylines-CJ5nd6Lw.mjs.map} +1 -1
- package/dist/{bylines-CHjvehVX.mjs → bylines-RwBAeOF1.mjs} +3 -3
- package/dist/{bylines-CHjvehVX.mjs.map → bylines-RwBAeOF1.mjs.map} +1 -1
- package/dist/{cache-5VirJ2Cn.mjs → cache-BF5Kvn59.mjs} +2 -2
- package/dist/{cache-5VirJ2Cn.mjs.map → cache-BF5Kvn59.mjs.map} +1 -1
- package/dist/{challenge-store-D5pSY2S1.mjs → challenge-store-DQN_Yrck.mjs} +5 -3
- package/dist/challenge-store-DQN_Yrck.mjs.map +1 -0
- package/dist/chrome-tags-D8fiZG94.mjs +24 -0
- package/dist/chrome-tags-D8fiZG94.mjs.map +1 -0
- package/dist/{chunks-bNiX6_DR.mjs → chunks-C4szrD8o.mjs} +2 -2
- package/dist/{chunks-bNiX6_DR.mjs.map → chunks-C4szrD8o.mjs.map} +1 -1
- package/dist/cli/index.mjs +26 -26
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.mjs +2 -2
- package/dist/{collection-deletion-m_oi2c0N.mjs → collection-deletion-Bj07NHbj.mjs} +2 -2
- package/dist/{collection-deletion-m_oi2c0N.mjs.map → collection-deletion-Bj07NHbj.mjs.map} +1 -1
- package/dist/{comment-reaction-CRuItEjt.mjs → comment-reaction-BhrvSHml.mjs} +2 -2
- package/dist/{comment-reaction-CRuItEjt.mjs.map → comment-reaction-BhrvSHml.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-Ct4ensnf.mjs} +2 -2
- package/dist/{comments-CLj4bi8I.mjs.map → comments-Ct4ensnf.mjs.map} +1 -1
- package/dist/{components-v4U4DT2y.mjs → components-DJbo1z0S.mjs} +1 -1
- package/dist/{components-v4U4DT2y.mjs.map → components-DJbo1z0S.mjs.map} +1 -1
- package/dist/{config-DrfghTPe.d.mts → config-B9eZ340f.d.mts} +1 -1
- package/dist/{config-DrfghTPe.d.mts.map → config-B9eZ340f.d.mts.map} +1 -1
- package/dist/config-it29yDLA.mjs +1163 -0
- package/dist/config-it29yDLA.mjs.map +1 -0
- package/dist/{content-CP-SeXNa.mjs → content-DjvM0T92.mjs} +84 -44
- package/dist/content-DjvM0T92.mjs.map +1 -0
- package/dist/{content-list-query-BhejKVqb.d.mts → content-list-query-Btqd4uV2.d.mts} +1 -1
- package/dist/{content-list-query-BhejKVqb.d.mts.map → content-list-query-Btqd4uV2.d.mts.map} +1 -1
- package/dist/{content-refresh-DLOfIhYc.mjs → content-refresh-Bwp-8yGy.mjs} +48 -21
- package/dist/content-refresh-Bwp-8yGy.mjs.map +1 -0
- package/dist/{content-repair-BCxzy0r4.mjs → content-repair-Czdp7jz5.mjs} +4 -4
- package/dist/{content-repair-BCxzy0r4.mjs.map → content-repair-Czdp7jz5.mjs.map} +1 -1
- package/dist/{context-BR5hRWiK.mjs → context-CX6gxOLW.mjs} +52 -17
- package/dist/context-CX6gxOLW.mjs.map +1 -0
- package/dist/{cron-CWfWrWKG.mjs → cron-C6o7VppJ.mjs} +1 -1
- package/dist/{cron-CWfWrWKG.mjs.map → cron-C6o7VppJ.mjs.map} +1 -1
- package/dist/{dashboard-CkIV2rnQ.mjs → dashboard-C2kTeeRI.mjs} +4 -4
- package/dist/{dashboard-CkIV2rnQ.mjs.map → dashboard-C2kTeeRI.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql-migrations.d.mts +1 -1
- package/dist/db/libsql-migrations.mjs +4 -4
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres-migrations.d.mts +1 -1
- package/dist/db/postgres-migrations.mjs +4 -4
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/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 +4 -4
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +1 -1
- package/dist/{default-YMEfcQUx.mjs → default-Clra32mw.mjs} +1 -1
- package/dist/{default-YMEfcQUx.mjs.map → default-Clra32mw.mjs.map} +1 -1
- package/dist/{deferred-tasks-DfqxH5Xf.d.mts → deferred-tasks-CvDETTJO.d.mts} +1 -1
- package/dist/{deferred-tasks-DfqxH5Xf.d.mts.map → deferred-tasks-CvDETTJO.d.mts.map} +1 -1
- package/dist/dev-typegen-DzOPfsNj.mjs +29 -0
- package/dist/dev-typegen-DzOPfsNj.mjs.map +1 -0
- package/dist/{device-flow-CojjSBwb.mjs → device-flow-D2oCWvLJ.mjs} +4 -4
- package/dist/{device-flow-CojjSBwb.mjs.map → device-flow-D2oCWvLJ.mjs.map} +1 -1
- package/dist/{direct-executor-BWeWiRYB.mjs → direct-executor-Bfa5_ToE.mjs} +3 -3
- package/dist/{direct-executor-BWeWiRYB.mjs.map → direct-executor-Bfa5_ToE.mjs.map} +1 -1
- package/dist/{email-console-CEJgR_LB.mjs → email-console-Dzb6uGYa.mjs} +1 -1
- package/dist/{email-console-CEJgR_LB.mjs.map → email-console-Dzb6uGYa.mjs.map} +1 -1
- package/dist/{error-D9w94fjV.mjs → error-DFrQjppn.mjs} +2 -2
- package/dist/{error-D9w94fjV.mjs.map → error-DFrQjppn.mjs.map} +1 -1
- package/dist/{errors-n2j49uNf.mjs → errors-DsVoDUjJ.mjs} +3 -1
- package/dist/errors-DsVoDUjJ.mjs.map +1 -0
- package/dist/{escape-DN4Qmjsl.mjs → escape-HmHTC1Is.mjs} +1 -1
- package/dist/{escape-DN4Qmjsl.mjs.map → escape-HmHTC1Is.mjs.map} +1 -1
- package/dist/{field-defs-cache-Bh4q6oar.mjs → field-defs-cache-BM4SIRqH.mjs} +2 -2
- package/dist/{field-defs-cache-Bh4q6oar.mjs.map → field-defs-cache-BM4SIRqH.mjs.map} +1 -1
- package/dist/{fts-manager-BhOdW0bi.mjs → fts-manager-Do1BlW2r.mjs} +2 -2
- package/dist/{fts-manager-BhOdW0bi.mjs.map → fts-manager-Do1BlW2r.mjs.map} +1 -1
- package/dist/{hash-CTcngWvj.mjs → hash-3JJPlHF2.mjs} +1 -1
- package/dist/{hash-CTcngWvj.mjs.map → hash-3JJPlHF2.mjs.map} +1 -1
- package/dist/hook-result-DCh2WUpe.d.mts +31 -0
- package/dist/hook-result-DCh2WUpe.d.mts.map +1 -0
- package/dist/{hreflang-7pTHsLZJ.d.mts → hreflang-B6hbAuuO.d.mts} +2 -2
- package/dist/{hreflang-7pTHsLZJ.d.mts.map → hreflang-B6hbAuuO.d.mts.map} +1 -1
- package/dist/{hreflang-Huc6O5wa.mjs → hreflang-DQbPZliA.mjs} +6 -6
- package/dist/{hreflang-Huc6O5wa.mjs.map → hreflang-DQbPZliA.mjs.map} +1 -1
- package/dist/{identity-DXmb4aVp.mjs → identity-DksvEazf.mjs} +3 -3
- package/dist/{identity-DXmb4aVp.mjs.map → identity-DksvEazf.mjs.map} +1 -1
- package/dist/{import-C4_O3KXU.mjs → import-CJpaBBBT.mjs} +5 -5
- package/dist/{import-C4_O3KXU.mjs.map → import-CJpaBBBT.mjs.map} +1 -1
- package/dist/{index-DWbJrsAg.d.mts → index-BJNMCWmu.d.mts} +158 -49
- package/dist/index-BJNMCWmu.d.mts.map +1 -0
- package/dist/{index-6bRee8zb.d.mts → index-Du8K7bWa.d.mts} +3 -3
- package/dist/{index-6bRee8zb.d.mts.map → index-Du8K7bWa.d.mts.map} +1 -1
- package/dist/index.d.mts +22 -21
- package/dist/index.mjs +70 -70
- package/dist/{load-Bo7fZAbg.mjs → load-CawHjTOH.mjs} +2 -2
- package/dist/{load-Bo7fZAbg.mjs.map → load-CawHjTOH.mjs.map} +1 -1
- package/dist/{loader-ZsjE4paL.mjs → loader-Z8vl7zTq.mjs} +48 -13
- package/dist/loader-Z8vl7zTq.mjs.map +1 -0
- package/dist/{manifest-builder-QXuqvVMP.mjs → manifest-builder-COtzuca2.mjs} +2 -2
- package/dist/{manifest-builder-QXuqvVMP.mjs.map → manifest-builder-COtzuca2.mjs.map} +1 -1
- package/dist/{manifest-schema-CUYPfCEH.mjs → manifest-schema-BNWwR8Vd.mjs} +5 -5
- package/dist/manifest-schema-BNWwR8Vd.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 +1 -1
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +4 -4
- package/dist/{media-D6SeAfBl.mjs → media-BBm8Wg3f.mjs} +30 -2
- package/dist/media-BBm8Wg3f.mjs.map +1 -0
- package/dist/{media-BjwNuLEu.mjs → media-BHjus86Y.mjs} +35 -5
- package/dist/media-BHjus86Y.mjs.map +1 -0
- package/dist/{media-allowlist-D35v7bmL.mjs → media-allowlist-CoTBWoDp.mjs} +1 -1
- package/dist/{media-allowlist-D35v7bmL.mjs.map → media-allowlist-CoTBWoDp.mjs.map} +1 -1
- package/dist/{media-folders-D-0CmRZj.mjs → media-folders-BGkATs8n.mjs} +1 -1
- package/dist/{media-folders-D-0CmRZj.mjs.map → media-folders-BGkATs8n.mjs.map} +1 -1
- package/dist/{media-upload-C7bLXGcI.mjs → media-upload-BCidR-EY.mjs} +6 -6
- package/dist/{media-upload-C7bLXGcI.mjs.map → media-upload-BCidR-EY.mjs.map} +1 -1
- package/dist/{media-url-DH7giMx_.mjs → media-url-DHoPr0hq.mjs} +1 -1
- package/dist/{media-url-DH7giMx_.mjs.map → media-url-DHoPr0hq.mjs.map} +1 -1
- package/dist/{media-usage-BTRJvS6V.mjs → media-usage-CdY5jhSR.mjs} +8 -8
- package/dist/{media-usage-BTRJvS6V.mjs.map → media-usage-CdY5jhSR.mjs.map} +1 -1
- package/dist/{media-usage-activation-Dx0kPV6b.mjs → media-usage-activation-BgeMtK5C.mjs} +2 -2
- package/dist/{media-usage-activation-Dx0kPV6b.mjs.map → media-usage-activation-BgeMtK5C.mjs.map} +1 -1
- package/dist/{media-usage-work-DWb2XPMI.mjs → media-usage-work-CnGCdHxx.mjs} +4 -4
- package/dist/{media-usage-work-DWb2XPMI.mjs.map → media-usage-work-CnGCdHxx.mjs.map} +1 -1
- package/dist/{media-usage-work-C-fhM30c.mjs → media-usage-work-D6D9sMCA.mjs} +1 -1
- package/dist/{media-usage-work-C-fhM30c.mjs.map → media-usage-work-D6D9sMCA.mjs.map} +1 -1
- package/dist/{media-usage-write-fence-BwoJVRDC.mjs → media-usage-write-fence-hjeD4u7s.mjs} +2 -2
- package/dist/{media-usage-write-fence-BwoJVRDC.mjs.map → media-usage-write-fence-hjeD4u7s.mjs.map} +1 -1
- package/dist/{menus-CNg0QlDt.mjs → menus-6qSwTNxG.mjs} +346 -94
- package/dist/menus-6qSwTNxG.mjs.map +1 -0
- package/dist/{menus-CD7EFLwz.mjs → menus-uvPLXMZf.mjs} +3 -3
- package/dist/{menus-CD7EFLwz.mjs.map → menus-uvPLXMZf.mjs.map} +1 -1
- package/dist/migrations/index.d.mts +1 -1
- package/dist/migrations/index.mjs +3 -3
- package/dist/{mode-DaUM_MB2.mjs → mode-DN_WneRx.mjs} +1 -1
- package/dist/{mode-DaUM_MB2.mjs.map → mode-DN_WneRx.mjs.map} +1 -1
- package/dist/{node-sqlite-compat-Udb4Y-rs.mjs → node-sqlite-compat-BuJXIeMz.mjs} +1 -1
- package/dist/{node-sqlite-compat-Udb4Y-rs.mjs.map → node-sqlite-compat-BuJXIeMz.mjs.map} +1 -1
- package/dist/{normalize-CSxdKBVa.mjs → normalize-C2xNjTSG.mjs} +15 -5
- package/dist/normalize-C2xNjTSG.mjs.map +1 -0
- package/dist/{oauth-authorization-Dpsb-fMJ.mjs → oauth-authorization-Dj6Kwc21.mjs} +4 -4
- package/dist/{oauth-authorization-Dpsb-fMJ.mjs.map → oauth-authorization-Dj6Kwc21.mjs.map} +1 -1
- package/dist/{oauth-clients-Bxnoe_67.mjs → oauth-clients-FD7I0J8m.mjs} +1 -1
- package/dist/{oauth-clients-Bxnoe_67.mjs.map → oauth-clients-FD7I0J8m.mjs.map} +1 -1
- package/dist/{oauth-state-store-0C4s0K6w.mjs → oauth-state-store-DkmDOmHs.mjs} +1 -1
- package/dist/{oauth-state-store-0C4s0K6w.mjs.map → oauth-state-store-DkmDOmHs.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-wlGYSeqX.mjs → oauth-user-lookup-CvIwGpYd.mjs} +1 -1
- package/dist/{oauth-user-lookup-wlGYSeqX.mjs.map → oauth-user-lookup-CvIwGpYd.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-BhZIeFY1.d.mts → options-CYb4y7hM.d.mts} +24 -11
- package/dist/options-CYb4y7hM.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-BRJg1kz8.mjs → parse-Ckpg-Qfp.mjs} +2 -2
- package/dist/{parse-BRJg1kz8.mjs.map → parse-Ckpg-Qfp.mjs.map} +1 -1
- package/dist/{passkey-config-B3P0nHRR.mjs → passkey-config-O_lj3y0k.mjs} +1 -1
- package/dist/{passkey-config-B3P0nHRR.mjs.map → passkey-config-O_lj3y0k.mjs.map} +1 -1
- package/dist/{placeholder-BR4ZhVJl.d.mts → placeholder-4X9BrRrp.d.mts} +1 -1
- package/dist/{placeholder-BR4ZhVJl.d.mts.map → placeholder-4X9BrRrp.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-Dhtwntrt.mjs} +2 -2
- package/dist/{policy-BVRganJQ.mjs.map → policy-Dhtwntrt.mjs.map} +1 -1
- package/dist/{portable-text-C8Tvp4_g.mjs → portable-text-U85hOafW.mjs} +1 -1
- package/dist/{portable-text-C8Tvp4_g.mjs.map → portable-text-U85hOafW.mjs.map} +1 -1
- package/dist/{preview-dn2dUyM0.mjs → preview-B_vJLvf8.mjs} +2 -2
- package/dist/{preview-dn2dUyM0.mjs.map → preview-B_vJLvf8.mjs.map} +1 -1
- package/dist/{protocol-CuBEsqgE.d.mts → protocol-JdD2YhY9.d.mts} +2 -2
- package/dist/{protocol-CuBEsqgE.d.mts.map → protocol-JdD2YhY9.d.mts.map} +1 -1
- package/dist/{public-url-DRz_AinV.mjs → public-url-CarhZJgf.mjs} +1 -1
- package/dist/{public-url-DRz_AinV.mjs.map → public-url-CarhZJgf.mjs.map} +1 -1
- package/dist/{query-D18vTdha.mjs → query-BZKZcG5b.mjs} +14 -14
- package/dist/{query-D18vTdha.mjs.map → query-BZKZcG5b.mjs.map} +1 -1
- package/dist/{query-tZDEdtCN.mjs → query-BndaFxxp.mjs} +4 -4
- package/dist/{query-tZDEdtCN.mjs.map → query-BndaFxxp.mjs.map} +1 -1
- package/dist/{rate-limit-on7KPo-v.mjs → rate-limit-BZmATC6W.mjs} +2 -2
- package/dist/{rate-limit-on7KPo-v.mjs.map → rate-limit-BZmATC6W.mjs.map} +1 -1
- package/dist/{redirect-DrbEmU9a.mjs → redirect-CzqnLxK-.mjs} +1 -1
- package/dist/{redirect-DrbEmU9a.mjs.map → redirect-CzqnLxK-.mjs.map} +1 -1
- package/dist/{redirects-CRIM55KH.mjs → redirects-BLNOWQTn.mjs} +63 -28
- package/dist/redirects-BLNOWQTn.mjs.map +1 -0
- package/dist/{redirects-BahWiu8Z.mjs → redirects-CqzNM0KM.mjs} +2 -2
- package/dist/{redirects-BahWiu8Z.mjs.map → redirects-CqzNM0KM.mjs.map} +1 -1
- package/dist/{registry-Cx-jEJOS.mjs → registry-AZAsRsor.mjs} +27 -9
- package/dist/registry-AZAsRsor.mjs.map +1 -0
- package/dist/{relation-A6wLF_DS.mjs → relation-04DfKRTO.mjs} +2 -2
- package/dist/{relation-A6wLF_DS.mjs.map → relation-04DfKRTO.mjs.map} +1 -1
- package/dist/{relations-BTPM2saV.mjs → relations-C4htk5sb.mjs} +7 -7
- package/dist/relations-C4htk5sb.mjs.map +1 -0
- package/dist/{relations-Cj5hZ6Zg.mjs → relations-CcFwDJdJ.mjs} +4 -4
- package/dist/{relations-Cj5hZ6Zg.mjs.map → relations-CcFwDJdJ.mjs.map} +1 -1
- package/dist/{relations-C7B46bcU.d.mts → relations-DnRK4YIT.d.mts} +175 -41
- package/dist/relations-DnRK4YIT.d.mts.map +1 -0
- package/dist/request-context.d.mts +1 -1
- package/dist/{request-meta-DRp5ENd_.mjs → request-meta-DYxLlnmz.mjs} +2 -2
- package/dist/{request-meta-DRp5ENd_.mjs.map → request-meta-DYxLlnmz.mjs.map} +1 -1
- package/dist/{resolve-DxUpTMmE.mjs → resolve-prZ3mP7l.mjs} +1 -1
- package/dist/{resolve-DxUpTMmE.mjs.map → resolve-prZ3mP7l.mjs.map} +1 -1
- package/dist/{runner-77GOZCnH.mjs → runner-BLIDKpmA.mjs} +351 -294
- package/dist/runner-BLIDKpmA.mjs.map +1 -0
- package/dist/{runner-zgqA_CqP.d.mts → runner-YKfIMnaF.d.mts} +3 -2
- package/dist/runner-YKfIMnaF.d.mts.map +1 -0
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +1 -1
- package/dist/{schema-BY-oVntF.mjs → schema-CGnBeLiW.mjs} +3 -3
- package/dist/{schema-BY-oVntF.mjs.map → schema-CGnBeLiW.mjs.map} +1 -1
- package/dist/{schema-Cw9kVK0I.mjs → schema-DYr-Vd-L.mjs} +5 -5
- package/dist/{schema-Cw9kVK0I.mjs.map → schema-DYr-Vd-L.mjs.map} +1 -1
- package/dist/{scopes-vMR1uIbt.mjs → scopes-BhWvBavj.mjs} +3 -3
- package/dist/{scopes-vMR1uIbt.mjs.map → scopes-BhWvBavj.mjs.map} +1 -1
- package/dist/{search-CfT3KxO5.mjs → search-C-qDk4kx.mjs} +4 -4
- package/dist/{search-CfT3KxO5.mjs.map → search-C-qDk4kx.mjs.map} +1 -1
- package/dist/{secrets-BH2Qow1-.mjs → secrets-rEtHt-6z.mjs} +1 -1
- package/dist/{secrets-BH2Qow1-.mjs.map → secrets-rEtHt-6z.mjs.map} +1 -1
- package/dist/{sections-DTfjyf1z.mjs → sections-B_nYvlwn.mjs} +2 -2
- package/dist/{sections-DTfjyf1z.mjs.map → sections-B_nYvlwn.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +18 -18
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +13 -13
- package/dist/{seo-Cm-dtvgk.mjs → seo-926NRIgt.mjs} +3 -3
- package/dist/{seo-Cm-dtvgk.mjs.map → seo-926NRIgt.mjs.map} +1 -1
- package/dist/{seo-BSiTIXzd.mjs → seo-CVWkdv6x.mjs} +1 -1
- package/dist/{seo-BSiTIXzd.mjs.map → seo-CVWkdv6x.mjs.map} +1 -1
- package/dist/{service-DYsDHEKe.mjs → service-CJl3ZAYs.mjs} +3 -3
- package/dist/{service-DYsDHEKe.mjs.map → service-CJl3ZAYs.mjs.map} +1 -1
- package/dist/{session-user-CNAfvsdw.mjs → session-user-BlMgqCHS.mjs} +1 -1
- package/dist/{session-user-CNAfvsdw.mjs.map → session-user-BlMgqCHS.mjs.map} +1 -1
- package/dist/{settings-BgN-0DT-.mjs → settings--wobrkkC.mjs} +18 -5
- package/dist/settings--wobrkkC.mjs.map +1 -0
- package/dist/{settings-DjtkUo__.mjs → settings-Cwm6o2jY.mjs} +3 -3
- package/dist/{settings-DjtkUo__.mjs.map → settings-Cwm6o2jY.mjs.map} +1 -1
- package/dist/{setup-complete-CcpXaPU7.mjs → setup-complete-DQbClIN2.mjs} +1 -1
- package/dist/{setup-complete-CcpXaPU7.mjs.map → setup-complete-DQbClIN2.mjs.map} +1 -1
- package/dist/{setup-nonce-Reyw30jg.mjs → setup-nonce-DZCFS2sn.mjs} +1 -1
- package/dist/{setup-nonce-Reyw30jg.mjs.map → setup-nonce-DZCFS2sn.mjs.map} +1 -1
- package/dist/{site-url-Cs_V9n3V.mjs → site-url-BrxA_E9H.mjs} +2 -2
- package/dist/{site-url-Cs_V9n3V.mjs.map → site-url-BrxA_E9H.mjs.map} +1 -1
- package/dist/{snapshot-DSB8P7Lm.mjs → snapshot--OCDTqdb.mjs} +1 -1
- package/dist/{snapshot-DSB8P7Lm.mjs.map → snapshot--OCDTqdb.mjs.map} +1 -1
- package/dist/{ssrf-DqebVE34.mjs → ssrf-5sIM5jzl.mjs} +4 -3
- package/dist/{ssrf-DqebVE34.mjs.map → ssrf-5sIM5jzl.mjs.map} +1 -1
- package/dist/{state-BJfU9Uzw.mjs → state-BpFVsJZB.mjs} +1 -1
- package/dist/{state-BJfU9Uzw.mjs.map → state-BpFVsJZB.mjs.map} +1 -1
- package/dist/{status-DDu8HIQl.mjs → status-B777-dXz.mjs} +1 -1
- package/dist/{status-DDu8HIQl.mjs.map → status-B777-dXz.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-BmR0iTwz.mjs} +1 -1
- package/dist/{target-D0o26Azo.mjs.map → target-BmR0iTwz.mjs.map} +1 -1
- package/dist/{taxonomies-CPGxo-bn.mjs → taxonomies-DkAkMupr.mjs} +16 -13
- package/dist/taxonomies-DkAkMupr.mjs.map +1 -0
- package/dist/{taxonomies-kmyudNGP.mjs → taxonomies-Wfy_Lg12.mjs} +42 -16
- package/dist/taxonomies-Wfy_Lg12.mjs.map +1 -0
- package/dist/{taxonomy-8X09dLN5.mjs → taxonomy-tJepplLL.mjs} +4 -4
- package/dist/{taxonomy-8X09dLN5.mjs.map → taxonomy-tJepplLL.mjs.map} +1 -1
- package/dist/{tokens-gTS-IVUp.mjs → tokens-BCO1oruF.mjs} +1 -1
- package/dist/{tokens-gTS-IVUp.mjs.map → tokens-BCO1oruF.mjs.map} +1 -1
- package/dist/{transport-fX59xaJz.mjs → transport-Dr3qtwXC.mjs} +1 -1
- package/dist/{transport-fX59xaJz.mjs.map → transport-Dr3qtwXC.mjs.map} +1 -1
- package/dist/{transport-_6R1ub7t.d.mts → transport-xh6YKW2G.d.mts} +1 -1
- package/dist/{transport-_6R1ub7t.d.mts.map → transport-xh6YKW2G.d.mts.map} +1 -1
- package/dist/{trusted-proxy-fe6nEgR4.mjs → trusted-proxy-BR5F1Otp.mjs} +1 -1
- package/dist/{trusted-proxy-fe6nEgR4.mjs.map → trusted-proxy-BR5F1Otp.mjs.map} +1 -1
- package/dist/{types-BXUmsINL.mjs → types-3qNFPlci.mjs} +1 -1
- package/dist/{types-BXUmsINL.mjs.map → types-3qNFPlci.mjs.map} +1 -1
- package/dist/{types-Vg6f5i3s.d.mts → types-B6GrPic4.d.mts} +9 -3
- package/dist/{types-Vg6f5i3s.d.mts.map → types-B6GrPic4.d.mts.map} +1 -1
- package/dist/{types-DJQxln7q.d.mts → types-BuHW4xDE.d.mts} +11 -10
- package/dist/types-BuHW4xDE.d.mts.map +1 -0
- package/dist/{types-BzBd3PeX.d.mts → types-C00oyCZp.d.mts} +1 -1
- package/dist/{types-BzBd3PeX.d.mts.map → types-C00oyCZp.d.mts.map} +1 -1
- package/dist/{types-Blb-MRC3.d.mts → types-CDtkNSFQ.d.mts} +1 -1
- package/dist/{types-Blb-MRC3.d.mts.map → types-CDtkNSFQ.d.mts.map} +1 -1
- package/dist/{types-D5VVLr7J.d.mts → types-CPeXo1wF.d.mts} +1 -1
- package/dist/{types-D5VVLr7J.d.mts.map → types-CPeXo1wF.d.mts.map} +1 -1
- package/dist/types-CQPWhPxE.mjs.map +1 -1
- package/dist/{types-D_DWe7k9.d.mts → types-CXFkwEGC.d.mts} +3 -2
- package/dist/types-CXFkwEGC.d.mts.map +1 -0
- package/dist/{types-CLqvnd05.d.mts → types-DczELMop.d.mts} +1 -1
- package/dist/{types-CLqvnd05.d.mts.map → types-DczELMop.d.mts.map} +1 -1
- package/dist/types-DfuTR6dL.mjs +3 -0
- package/dist/{types-DHxzBjbD.d.mts → types-FV23hEoW.d.mts} +1 -1
- package/dist/{types-DHxzBjbD.d.mts.map → types-FV23hEoW.d.mts.map} +1 -1
- package/dist/{types-Br-ERaxh.d.mts → types-xDMtUFnO.d.mts} +1 -1
- package/dist/{types-Br-ERaxh.d.mts.map → types-xDMtUFnO.d.mts.map} +1 -1
- package/dist/{upload-attempts-CNyGSepg.mjs → upload-attempts-BsqoQ1fn.mjs} +1 -1
- package/dist/{upload-attempts-CNyGSepg.mjs.map → upload-attempts-BsqoQ1fn.mjs.map} +1 -1
- package/dist/{url-pattern-K-KdXcSe.mjs → url-pattern-D4c2czpJ.mjs} +1 -1
- package/dist/{url-pattern-K-KdXcSe.mjs.map → url-pattern-D4c2czpJ.mjs.map} +1 -1
- package/dist/{user-CtYY0tp2.mjs → user-BTZ40aq6.mjs} +2 -2
- package/dist/{user-CtYY0tp2.mjs.map → user-BTZ40aq6.mjs.map} +1 -1
- package/dist/{utils-HztC73hq.mjs → utils-BKvNjjhY.mjs} +1 -1
- package/dist/{utils-HztC73hq.mjs.map → utils-BKvNjjhY.mjs.map} +1 -1
- package/dist/{validate-Dd-IUjnZ.mjs → validate-DE_LRwo9.mjs} +2 -2
- package/dist/{validate-Dd-IUjnZ.mjs.map → validate-DE_LRwo9.mjs.map} +1 -1
- package/dist/{validate-DlqdOZXB.d.mts → validate-DUP27OYD.d.mts} +5 -5
- package/dist/{validate-DlqdOZXB.d.mts.map → validate-DUP27OYD.d.mts.map} +1 -1
- package/dist/{validation-D83n7Npi.mjs → validation-BMImFJ11.mjs} +8 -8
- package/dist/{validation-D83n7Npi.mjs.map → validation-BMImFJ11.mjs.map} +1 -1
- package/dist/version-Bii3suaO.mjs +7 -0
- package/dist/{version-ri-sCyAp.mjs.map → version-Bii3suaO.mjs.map} +1 -1
- package/dist/{widgets-CpmZd9Q-.mjs → widgets-D3gJ10xU.mjs} +17 -4
- package/dist/widgets-D3gJ10xU.mjs.map +1 -0
- package/dist/{wxr-taxonomies-BFd0y72_.d.mts → wxr-taxonomies-B2Og_6rU.d.mts} +1 -1
- package/dist/{wxr-taxonomies-BFd0y72_.d.mts.map → wxr-taxonomies-B2Og_6rU.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-Df4vxWcU.mjs → wxr-taxonomies-Cxngsjwo.mjs} +4 -4
- package/dist/{wxr-taxonomies-Df4vxWcU.mjs.map → wxr-taxonomies-Cxngsjwo.mjs.map} +1 -1
- package/dist/{zod-generator-DylzusHh.mjs → zod-generator-BuYSQJB7.mjs} +11 -7
- package/dist/zod-generator-BuYSQJB7.mjs.map +1 -0
- package/package.json +12 -9
- package/src/api/errors.ts +2 -0
- package/src/api/handlers/content.ts +49 -11
- package/src/api/handlers/index.ts +1 -0
- package/src/api/handlers/manifest.ts +161 -12
- package/src/api/handlers/media.ts +30 -0
- package/src/api/handlers/registry.ts +393 -289
- package/src/api/handlers/taxonomies.ts +16 -9
- package/src/api/openapi/document.ts +85 -5
- 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 +78 -22
- package/src/api/schemas/media.ts +52 -0
- package/src/api/schemas/redirects.ts +6 -1
- package/src/api/schemas/schema.ts +4 -0
- 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 +23 -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 +9 -44
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/vite-config.ts +21 -2
- package/src/astro/middleware.ts +5 -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 +8 -2
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -1
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +6 -2
- 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/types.ts +23 -5
- 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/components/EmDashImage.astro +2 -1
- package/src/components/EmDashMedia.astro +2 -1
- package/src/components/InlinePortableTextEditor.tsx +6 -1
- package/src/components/widgets/Archives.astro +2 -37
- 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 +202 -69
- package/src/content/converters/prosemirror-to-portable-text.ts +96 -25
- package/src/content/converters/types.ts +1 -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/runner.ts +3 -1
- package/src/database/repositories/byline.ts +32 -16
- package/src/database/repositories/content.ts +114 -47
- package/src/database/repositories/media-usage.ts +66 -37
- package/src/database/repositories/media.ts +60 -1
- package/src/database/repositories/plugin-storage.ts +74 -9
- package/src/database/repositories/types.ts +8 -7
- package/src/db/adapters.ts +8 -1
- package/src/db/postgres.ts +23 -0
- package/src/emdash-runtime.ts +80 -150
- 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/index.ts +25 -3
- package/src/loader.ts +63 -10
- package/src/mcp/server.ts +228 -24
- package/src/media/image-endpoint.ts +5 -2
- package/src/media/normalize.ts +15 -4
- package/src/media/usage/cleanup.ts +9 -8
- package/src/menus/index.ts +16 -0
- package/src/object-cache/index.ts +44 -2
- package/src/plugin-types.ts +18 -1
- package/src/plugins/hooks.ts +4 -1
- package/src/plugins/index.ts +6 -0
- package/src/plugins/manager.ts +2 -1
- 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/types.ts +6 -0
- 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/record-labels.ts +28 -0
- package/src/schema/registry.ts +26 -3
- package/src/schema/zod-generator.ts +16 -13
- package/src/security/ssrf.ts +5 -2
- 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/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/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/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/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-BhZIeFY1.d.mts.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/runner-77GOZCnH.mjs.map +0 -1
- package/dist/runner-zgqA_CqP.d.mts.map +0 -1
- package/dist/settings-BgN-0DT-.mjs.map +0 -1
- package/dist/taxonomies-CPGxo-bn.mjs.map +0 -1
- package/dist/taxonomies-kmyudNGP.mjs.map +0 -1
- package/dist/types-D6OcIp2P.mjs +0 -3
- package/dist/types-DJQxln7q.d.mts.map +0 -1
- package/dist/types-D_DWe7k9.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-BfYts-sq.mjs} +0 -0
- /package/dist/{ssrf-BPKzkm6O.mjs → ssrf-Dg3cIT-b.mjs} +0 -0
|
@@ -1,44 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Registry
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* aggregator's `resolvePackage` XRPC.
|
|
9
|
-
* 2. Look up the requested release (or the policy-filtered latest one)
|
|
10
|
-
* via `getLatestRelease` / `listReleases`.
|
|
11
|
-
* 3. Require the aggregator's approved listing projection, then apply the
|
|
12
|
-
* independent release-age and environment policies.
|
|
13
|
-
* 4. Fetch the bundle artifact through an advertised record-scoped cache,
|
|
14
|
-
* the publisher PDS, or the publisher-declared URL.
|
|
15
|
-
* 5. Verify the artifact's multibase checksum against the signed
|
|
16
|
-
* release record's `artifacts.package.checksum`.
|
|
17
|
-
* 6. Extract `manifest.json` + `backend.js` + optional `admin.js` from
|
|
18
|
-
* the gzipped tar bundle.
|
|
19
|
-
* 7. Store the extracted files in site-local R2 under the
|
|
20
|
-
* `registry/<plugin-id>/<version>/` prefix.
|
|
21
|
-
* 8. Write a `plugin_states` row with `source = "registry"` and the
|
|
22
|
-
* `(publisher_did, slug)` pair so updates can be resolved later.
|
|
23
|
-
* 9. Sync the runtime so the plugin becomes active immediately.
|
|
24
|
-
*
|
|
25
|
-
* Known gaps (tracked separately):
|
|
26
|
-
*
|
|
27
|
-
* - The aggregator-supplied records are not yet cryptographically
|
|
28
|
-
* verified against the publisher's MST signature. The signed bytes
|
|
29
|
-
* and CIDs are passed through verbatim per the lexicon, but full
|
|
30
|
-
* PDS-direct verification with proof traversal is follow-up work.
|
|
31
|
-
* The artifact checksum is verified end-to-end against the value
|
|
32
|
-
* in the (aggregator-relayed) release record, which is the actual
|
|
33
|
-
* trust boundary for the bytes that end up in the sandbox.
|
|
34
|
-
* - Listing approval controls whether metadata is eligible for discovery.
|
|
35
|
-
* It is never treated as approval of plugin code: checksum, bundle,
|
|
36
|
-
* manifest, access, consent, sandbox, and environment gates remain
|
|
37
|
-
* independent below.
|
|
2
|
+
* Registry installs use aggregator results only for discovery and moderation
|
|
3
|
+
* metadata. The handler reads profile and release records from the publisher's
|
|
4
|
+
* PDS, verifies their repository proofs, then validates the bundle checksum,
|
|
5
|
+
* manifest, policy, and consent before storing or activating executable code.
|
|
6
|
+
* Applicable labels can block installation but cannot supply any verified
|
|
7
|
+
* record, checksum, permission, or executable byte.
|
|
38
8
|
*/
|
|
39
9
|
|
|
40
10
|
import { ClientResponseError, ClientValidationError } from "@atcute/client";
|
|
41
11
|
import type { Did } from "@atcute/lexicons";
|
|
12
|
+
import { canonicalizeDeclaredAccess } from "@emdash-cms/plugin-types";
|
|
13
|
+
import type { CanonicalDeclaredAccess } from "@emdash-cms/plugin-types";
|
|
42
14
|
import { checkEnvCompatibility, findSkippedEnvConstraints } from "@emdash-cms/registry-client/env";
|
|
43
15
|
import type { HostEnv } from "@emdash-cms/registry-client/env";
|
|
44
16
|
import { evaluateRegistryReleaseWithdrawal } from "@emdash-cms/registry-client/withdrawal";
|
|
@@ -50,8 +22,6 @@ import {
|
|
|
50
22
|
import type { Kysely } from "kysely";
|
|
51
23
|
|
|
52
24
|
import type { Database } from "../../database/types.js";
|
|
53
|
-
import { extractBundle } from "../../plugins/marketplace.js";
|
|
54
|
-
import type { PluginBundle } from "../../plugins/marketplace.js";
|
|
55
25
|
import type { SandboxRunner } from "../../plugins/sandbox/types.js";
|
|
56
26
|
import { PluginStateRepository } from "../../plugins/state.js";
|
|
57
27
|
import {
|
|
@@ -61,6 +31,19 @@ import {
|
|
|
61
31
|
import { declaredAccessToCapabilities } from "../../plugins/types.js";
|
|
62
32
|
import type { DeclaredAccess } from "../../plugins/types.js";
|
|
63
33
|
import { fetchRegistryArtifactUrl } from "../../registry/artifact-fetch.js";
|
|
34
|
+
import {
|
|
35
|
+
validateRegistryArtifact,
|
|
36
|
+
type RegistryArtifactVerificationCode,
|
|
37
|
+
} from "../../registry/artifact-verification.js";
|
|
38
|
+
import {
|
|
39
|
+
readAuthoritativePackageRelease,
|
|
40
|
+
verifyAuthoritativePackageRelease,
|
|
41
|
+
type AuthoritativeRecordErrorCode,
|
|
42
|
+
type AuthoritativeRecordReader,
|
|
43
|
+
type AuthoritativeRecordReadOptions,
|
|
44
|
+
type VerifiedAuthoritativeReleaseReport,
|
|
45
|
+
type VerifiedAuthoritativeRecords,
|
|
46
|
+
} from "../../registry/authoritative-records.js";
|
|
64
47
|
import {
|
|
65
48
|
canonicalCapabilitiesForDriftCheck,
|
|
66
49
|
coerceRegistryConfig,
|
|
@@ -69,6 +52,7 @@ import {
|
|
|
69
52
|
validateAggregatorUrl,
|
|
70
53
|
} from "../../registry/config.js";
|
|
71
54
|
import { makeRegistryPluginId } from "../../registry/plugin-id.js";
|
|
55
|
+
import { hasCurrentRecordLabel } from "../../registry/record-labels.js";
|
|
72
56
|
import type { RegistryConfigInput } from "../../registry/types.js";
|
|
73
57
|
import { resolveAndValidateExternalUrlTarget } from "../../security/ssrf.js";
|
|
74
58
|
import { EmDashStorageError } from "../../storage/types.js";
|
|
@@ -84,8 +68,6 @@ import {
|
|
|
84
68
|
|
|
85
69
|
export { assertSafeArtifactUrl } from "../../registry/artifact-fetch.js";
|
|
86
70
|
|
|
87
|
-
const RELEASE_EXTENSION_NSID = "com.emdashcms.experimental.package.releaseExtension";
|
|
88
|
-
|
|
89
71
|
/**
|
|
90
72
|
* Whether two `declaredAccess` blocks grant exactly the same enforced access --
|
|
91
73
|
* the same capabilities AND the same host allow-list. Both are lowered through
|
|
@@ -104,6 +86,10 @@ export function enforcedAccessEqual(a: DeclaredAccess, b: DeclaredAccess): boole
|
|
|
104
86
|
);
|
|
105
87
|
}
|
|
106
88
|
|
|
89
|
+
function verifiedAccessEqual(a: CanonicalDeclaredAccess, b: DeclaredAccess): boolean {
|
|
90
|
+
return JSON.stringify(a) === JSON.stringify(canonicalizeDeclaredAccess(b));
|
|
91
|
+
}
|
|
92
|
+
|
|
107
93
|
// ── Types ──────────────────────────────────────────────────────────
|
|
108
94
|
|
|
109
95
|
export interface RegistryInstallInput {
|
|
@@ -134,6 +120,8 @@ export interface RegistryInstallInput {
|
|
|
134
120
|
*/
|
|
135
121
|
acknowledgedDeclaredAccess?: unknown;
|
|
136
122
|
acknowledgedMcpTools?: unknown;
|
|
123
|
+
acknowledgedProfileCid?: string;
|
|
124
|
+
acknowledgedReleaseCid?: string;
|
|
137
125
|
}
|
|
138
126
|
|
|
139
127
|
export interface RegistryInstallResult {
|
|
@@ -147,84 +135,120 @@ export interface RegistryInstallResult {
|
|
|
147
135
|
version: string;
|
|
148
136
|
/** Capabilities surfaced from the bundle's manifest. */
|
|
149
137
|
capabilities: string[];
|
|
138
|
+
declaredAccess: DeclaredAccess;
|
|
139
|
+
mcpTools: RegistryMcpConsentTool[];
|
|
140
|
+
verification: RegistryRecordVerificationSummary;
|
|
150
141
|
}
|
|
151
142
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
143
|
+
export interface RegistryMcpConsentTool {
|
|
144
|
+
name: string;
|
|
145
|
+
description: string;
|
|
146
|
+
route: string;
|
|
147
|
+
permission: string;
|
|
148
|
+
destructive: boolean;
|
|
149
|
+
}
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
151
|
+
export interface RegistryRecordVerificationSummary {
|
|
152
|
+
profileCid: string;
|
|
153
|
+
releaseCid: string;
|
|
154
|
+
provenance: "verified" | "absent-optional";
|
|
155
|
+
policy: {
|
|
156
|
+
requireProvenance: boolean;
|
|
157
|
+
confirmation: "escalation-only" | "always";
|
|
158
|
+
approvers: string[];
|
|
159
|
+
};
|
|
163
160
|
}
|
|
164
161
|
|
|
165
|
-
|
|
166
|
-
const MULTIHASH_SHA256_CODE = 0x12;
|
|
167
|
-
/** sha2-256 digest length in bytes (single-byte varint). */
|
|
168
|
-
const MULTIHASH_SHA256_LENGTH = 0x20;
|
|
162
|
+
// ── Helpers ────────────────────────────────────────────────────────
|
|
169
163
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
164
|
+
export function registryArtifactError(
|
|
165
|
+
code: RegistryArtifactVerificationCode,
|
|
166
|
+
message: string,
|
|
167
|
+
operation: "install" | "update",
|
|
168
|
+
): ApiResult<never> {
|
|
169
|
+
let apiCode: string;
|
|
170
|
+
switch (code) {
|
|
171
|
+
case "BUNDLE_ID_MISMATCH":
|
|
172
|
+
apiCode = operation === "install" ? "MANIFEST_ID_MISMATCH" : "BUNDLE_IDENTITY_MISMATCH";
|
|
173
|
+
break;
|
|
174
|
+
case "BUNDLE_VERSION_MISMATCH":
|
|
175
|
+
apiCode = operation === "install" ? "MANIFEST_VERSION_MISMATCH" : code;
|
|
176
|
+
break;
|
|
177
|
+
case "CHECKSUM_MISMATCH":
|
|
178
|
+
case "INVALID_MULTIHASH":
|
|
179
|
+
case "UNSUPPORTED_MULTIHASH":
|
|
180
|
+
apiCode = "CHECKSUM_MISMATCH";
|
|
181
|
+
break;
|
|
182
|
+
case "FETCH_FAILED":
|
|
183
|
+
case "HOST_REJECTED":
|
|
184
|
+
case "REDIRECT_LIMIT_EXCEEDED":
|
|
185
|
+
case "REDIRECT_LOCATION_MISSING":
|
|
186
|
+
case "RESOURCE_STATUS_ERROR":
|
|
187
|
+
case "RESOURCE_TIMEOUT":
|
|
188
|
+
apiCode = operation === "install" ? "INSTALL_FAILED" : "UPDATE_FAILED";
|
|
189
|
+
break;
|
|
190
|
+
default:
|
|
191
|
+
apiCode = "INVALID_BUNDLE";
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
error: {
|
|
196
|
+
code: apiCode,
|
|
197
|
+
message,
|
|
198
|
+
details: { verificationCode: code },
|
|
199
|
+
},
|
|
200
|
+
};
|
|
191
201
|
}
|
|
192
202
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
* Hash functions other than sha2-256 are out of scope for this
|
|
207
|
-
* initial release; the install fails closed.
|
|
208
|
-
*/
|
|
209
|
-
export async function verifyChecksum(bytes: Uint8Array, checksum: string): Promise<boolean> {
|
|
210
|
-
if (SHA256_HEX_PATTERN.test(checksum)) {
|
|
211
|
-
const actual = await sha256Hex(bytes);
|
|
212
|
-
return checksum.toLowerCase() === actual;
|
|
213
|
-
}
|
|
203
|
+
function registryRecordError(
|
|
204
|
+
code: AuthoritativeRecordErrorCode,
|
|
205
|
+
message: string,
|
|
206
|
+
): ApiResult<never> {
|
|
207
|
+
return {
|
|
208
|
+
success: false,
|
|
209
|
+
error: {
|
|
210
|
+
code: "RECORD_VERIFICATION_FAILED",
|
|
211
|
+
message,
|
|
212
|
+
details: { verificationCode: code },
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
214
216
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
217
|
+
function recordConsentError(
|
|
218
|
+
input: { profileCid?: string; releaseCid?: string },
|
|
219
|
+
records: VerifiedAuthoritativeRecords,
|
|
220
|
+
): ApiResult<never> | null {
|
|
221
|
+
if (!input.profileCid || !input.releaseCid) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
error: {
|
|
225
|
+
code: "RECORD_CONSENT_REQUIRED",
|
|
226
|
+
message: "Verify the signed package records before confirming this action.",
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (input.profileCid !== records.profile.cid || input.releaseCid !== records.release.cid) {
|
|
231
|
+
return {
|
|
232
|
+
success: false,
|
|
233
|
+
error: {
|
|
234
|
+
code: "RECORD_VERIFICATION_DRIFT",
|
|
235
|
+
message: "The signed package records changed after review. Verify them again.",
|
|
236
|
+
},
|
|
237
|
+
};
|
|
225
238
|
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
226
241
|
|
|
227
|
-
|
|
242
|
+
function recordVerificationSummary(
|
|
243
|
+
records: VerifiedAuthoritativeRecords,
|
|
244
|
+
report: VerifiedAuthoritativeReleaseReport,
|
|
245
|
+
): RegistryRecordVerificationSummary {
|
|
246
|
+
return {
|
|
247
|
+
profileCid: records.profile.cid,
|
|
248
|
+
releaseCid: records.release.cid,
|
|
249
|
+
provenance: report.provenance.status,
|
|
250
|
+
policy: report.value.policy,
|
|
251
|
+
};
|
|
228
252
|
}
|
|
229
253
|
|
|
230
254
|
/**
|
|
@@ -281,6 +305,16 @@ const AGGREGATOR_REQUEST_TIMEOUT_MS = 15_000;
|
|
|
281
305
|
*/
|
|
282
306
|
const AGGREGATOR_TOTAL_BUDGET_MS = 30_000;
|
|
283
307
|
|
|
308
|
+
class RegistryArtifactFetchError extends Error {
|
|
309
|
+
constructor(
|
|
310
|
+
readonly code: RegistryArtifactVerificationCode,
|
|
311
|
+
message: string,
|
|
312
|
+
) {
|
|
313
|
+
super(message);
|
|
314
|
+
this.name = "RegistryArtifactFetchError";
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
284
318
|
/** Build a fetch function that enforces a per-request and per-budget timeout. */
|
|
285
319
|
function timedFetch(totalDeadline: number): typeof fetch {
|
|
286
320
|
return (input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => {
|
|
@@ -339,7 +373,7 @@ async function fetchArtifact(
|
|
|
339
373
|
},
|
|
340
374
|
);
|
|
341
375
|
if (!result.success) {
|
|
342
|
-
throw new
|
|
376
|
+
throw new RegistryArtifactFetchError(result.error.code, result.error.message);
|
|
343
377
|
}
|
|
344
378
|
return result.value.bytes;
|
|
345
379
|
}
|
|
@@ -398,7 +432,13 @@ export async function handleRegistryInstall(
|
|
|
398
432
|
sandboxRunner: SandboxRunner | null,
|
|
399
433
|
registryConfigInput: RegistryConfigInput | undefined,
|
|
400
434
|
input: RegistryInstallInput,
|
|
401
|
-
opts?: {
|
|
435
|
+
opts?: {
|
|
436
|
+
configuredPluginIds?: Set<string>;
|
|
437
|
+
hostEnv?: HostEnv;
|
|
438
|
+
authoritativeRecords?: AuthoritativeRecordReadOptions;
|
|
439
|
+
readAuthoritativeRecords?: AuthoritativeRecordReader;
|
|
440
|
+
verifyOnly?: boolean;
|
|
441
|
+
},
|
|
402
442
|
): Promise<ApiResult<RegistryInstallResult>> {
|
|
403
443
|
// Accept either the bare-string shorthand or the full
|
|
404
444
|
// `RegistryConfig` object (see `RegistryConfigInput`).
|
|
@@ -549,19 +589,9 @@ export async function handleRegistryInstall(
|
|
|
549
589
|
};
|
|
550
590
|
}
|
|
551
591
|
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
// different `(did, slug, version)` than we asked for; the
|
|
556
|
-
// handler would then fetch + checksum-verify + install bytes
|
|
557
|
-
// under the requested package's pluginId but for a different
|
|
558
|
-
// publisher's record. Checksum verification only proves the bytes
|
|
559
|
-
// match the *returned* record, not that the record belongs to
|
|
560
|
-
// the package we requested.
|
|
561
|
-
// `releaseView.release` is validated against the release lexicon by
|
|
562
|
-
// DiscoveryClient (or `null` if it didn't conform). A `null` here makes
|
|
563
|
-
// the identity checks below fail closed, which is the desired outcome.
|
|
564
|
-
const signedRelease = releaseView.release;
|
|
592
|
+
// The aggregator selects the package/version and supplies mirrors and
|
|
593
|
+
// moderation metadata. Its copies of the signed records are not
|
|
594
|
+
// verification inputs.
|
|
565
595
|
if (packageView.did !== publisherDid || packageView.slug !== slug) {
|
|
566
596
|
return {
|
|
567
597
|
success: false,
|
|
@@ -574,9 +604,7 @@ export async function handleRegistryInstall(
|
|
|
574
604
|
if (
|
|
575
605
|
releaseView.did !== publisherDid ||
|
|
576
606
|
releaseView.package !== slug ||
|
|
577
|
-
|
|
578
|
-
(requestedVersion !== undefined && releaseView.version !== requestedVersion) ||
|
|
579
|
-
signedRelease?.version !== releaseView.version
|
|
607
|
+
(requestedVersion !== undefined && releaseView.version !== requestedVersion)
|
|
580
608
|
) {
|
|
581
609
|
return {
|
|
582
610
|
success: false,
|
|
@@ -599,6 +627,55 @@ export async function handleRegistryInstall(
|
|
|
599
627
|
};
|
|
600
628
|
}
|
|
601
629
|
|
|
630
|
+
const authoritative = await (opts?.readAuthoritativeRecords ?? readAuthoritativePackageRelease)(
|
|
631
|
+
publisherDid,
|
|
632
|
+
slug,
|
|
633
|
+
version,
|
|
634
|
+
opts?.authoritativeRecords,
|
|
635
|
+
);
|
|
636
|
+
if (!authoritative.success) {
|
|
637
|
+
return registryRecordError(authoritative.error.code, authoritative.error.message);
|
|
638
|
+
}
|
|
639
|
+
const records = authoritative.value;
|
|
640
|
+
const { profile, release } = records.inspection.value;
|
|
641
|
+
if (
|
|
642
|
+
packageView.uri !== records.profile.uri ||
|
|
643
|
+
packageView.cid !== records.profile.cid ||
|
|
644
|
+
releaseView.uri !== records.release.uri ||
|
|
645
|
+
releaseView.cid !== records.release.cid
|
|
646
|
+
) {
|
|
647
|
+
return {
|
|
648
|
+
success: false,
|
|
649
|
+
error: {
|
|
650
|
+
code: "AGGREGATOR_RECORD_MISMATCH",
|
|
651
|
+
message: "Aggregator metadata does not match the publisher's signed records.",
|
|
652
|
+
},
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
if (!opts?.verifyOnly) {
|
|
656
|
+
const consentError = recordConsentError(
|
|
657
|
+
{
|
|
658
|
+
profileCid: input.acknowledgedProfileCid,
|
|
659
|
+
releaseCid: input.acknowledgedReleaseCid,
|
|
660
|
+
},
|
|
661
|
+
records,
|
|
662
|
+
);
|
|
663
|
+
if (consentError) return consentError;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
const packageYanked =
|
|
667
|
+
hasCurrentRecordLabel(packageView.labels ?? [], "security:yanked", records.profile) ||
|
|
668
|
+
hasCurrentRecordLabel(packageView.labels ?? [], "security-yanked", records.profile);
|
|
669
|
+
if (packageYanked) {
|
|
670
|
+
return {
|
|
671
|
+
success: false,
|
|
672
|
+
error: {
|
|
673
|
+
code: "RELEASE_YANKED",
|
|
674
|
+
message: "This release has been withdrawn",
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
|
|
602
679
|
// Environment compatibility remains an install-safety gate. Listing
|
|
603
680
|
// approval says only that displayed metadata passed moderation. A release
|
|
604
681
|
// may carry a `requires` block (`env:emdash`, `env:astro`, ...). Refuse
|
|
@@ -607,7 +684,7 @@ export async function handleRegistryInstall(
|
|
|
607
684
|
// disabled Install button. `requires` is lexicon-`unknown`; the
|
|
608
685
|
// helper guards its shape.
|
|
609
686
|
if (opts?.hostEnv) {
|
|
610
|
-
const envError = assertEnvCompatible(
|
|
687
|
+
const envError = assertEnvCompatible(release.requires, opts.hostEnv);
|
|
611
688
|
if (envError) return { success: false, error: envError };
|
|
612
689
|
}
|
|
613
690
|
|
|
@@ -617,13 +694,11 @@ export async function handleRegistryInstall(
|
|
|
617
694
|
// must still hit the holdback. The `minimumReleaseAgeExclude`
|
|
618
695
|
// allowlist short-circuits the check for trusted publisher DIDs.
|
|
619
696
|
//
|
|
620
|
-
//
|
|
621
|
-
//
|
|
622
|
-
//
|
|
623
|
-
//
|
|
624
|
-
//
|
|
625
|
-
// follow-up that adds full MST verification). If the timestamp
|
|
626
|
-
// is missing or malformed, we fail closed and reject the install.
|
|
697
|
+
// `releaseView.indexedAt` is aggregator operational data, not part
|
|
698
|
+
// of the signed release. The release schema has no publication
|
|
699
|
+
// timestamp, so minimum age remains a local discovery holdback
|
|
700
|
+
// rather than a cryptographic property. A missing or malformed
|
|
701
|
+
// timestamp fails closed.
|
|
627
702
|
// `registryConfig` is the user-supplied integration option, not
|
|
628
703
|
// the normalized manifest shape, so the duration parse runs once
|
|
629
704
|
// per install. Catch a malformed value here -- normally caught at
|
|
@@ -728,13 +803,10 @@ export async function handleRegistryInstall(
|
|
|
728
803
|
};
|
|
729
804
|
}
|
|
730
805
|
|
|
731
|
-
// Step
|
|
732
|
-
//
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const release = releaseView.release;
|
|
736
|
-
const packageArtifact = release?.artifacts?.package;
|
|
737
|
-
const declaredChecksum = packageArtifact?.checksum;
|
|
806
|
+
// Step 6: fetch bytes through an aggregator cache, the publisher PDS,
|
|
807
|
+
// or the URL in the authoritative signed release. Every source remains untrusted.
|
|
808
|
+
const packageArtifact = release.artifacts.package;
|
|
809
|
+
const declaredChecksum = release.artifacts.package.checksum;
|
|
738
810
|
|
|
739
811
|
if (!packageArtifact || !declaredChecksum) {
|
|
740
812
|
return {
|
|
@@ -746,72 +818,54 @@ export async function handleRegistryInstall(
|
|
|
746
818
|
};
|
|
747
819
|
}
|
|
748
820
|
|
|
749
|
-
|
|
750
|
-
releaseView.artifactCaches ?? [],
|
|
751
|
-
packageArtifact,
|
|
752
|
-
{
|
|
753
|
-
did: publisherDid,
|
|
754
|
-
collection: NSID.packageRelease,
|
|
755
|
-
rkey: `${slug}:${version}`,
|
|
756
|
-
cid: releaseView.cid,
|
|
757
|
-
},
|
|
758
|
-
release.auth,
|
|
759
|
-
);
|
|
760
|
-
|
|
761
|
-
// Step 5: verify the bytes against the signed record's checksum.
|
|
762
|
-
const checksumOk = await verifyChecksum(artifactBytes, declaredChecksum);
|
|
763
|
-
if (!checksumOk) {
|
|
764
|
-
return {
|
|
765
|
-
success: false,
|
|
766
|
-
error: {
|
|
767
|
-
code: "CHECKSUM_MISMATCH",
|
|
768
|
-
message:
|
|
769
|
-
"Artifact bytes do not match the release record's checksum, or the checksum encoding is unsupported.",
|
|
770
|
-
},
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Step 6: extract the bundle.
|
|
775
|
-
let bundle: PluginBundle;
|
|
821
|
+
let artifactBytes: Uint8Array;
|
|
776
822
|
try {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
823
|
+
artifactBytes = await fetchArtifact(
|
|
824
|
+
releaseView.artifactCaches ?? [],
|
|
825
|
+
packageArtifact,
|
|
826
|
+
{
|
|
827
|
+
did: publisherDid,
|
|
828
|
+
collection: NSID.packageRelease,
|
|
829
|
+
rkey: `${slug}:${version}`,
|
|
830
|
+
cid: releaseView.cid,
|
|
784
831
|
},
|
|
785
|
-
|
|
832
|
+
release.auth,
|
|
833
|
+
);
|
|
834
|
+
} catch (error) {
|
|
835
|
+
if (error instanceof RegistryArtifactFetchError) {
|
|
836
|
+
return registryArtifactError(error.code, error.message, "install");
|
|
837
|
+
}
|
|
838
|
+
throw error;
|
|
786
839
|
}
|
|
787
840
|
|
|
788
|
-
//
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
841
|
+
// Steps 6-7: verify the signed checksum, archive, manifest, and
|
|
842
|
+
// expected package identity with the runtime-neutral verifier used
|
|
843
|
+
// by the release service.
|
|
844
|
+
const artifactReport = await validateRegistryArtifact(
|
|
845
|
+
artifactBytes,
|
|
846
|
+
declaredChecksum,
|
|
847
|
+
slug,
|
|
848
|
+
version,
|
|
849
|
+
);
|
|
850
|
+
if (!artifactReport.success) {
|
|
851
|
+
return registryArtifactError(
|
|
852
|
+
artifactReport.error.code,
|
|
853
|
+
artifactReport.error.message,
|
|
854
|
+
"install",
|
|
855
|
+
);
|
|
797
856
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
success: false,
|
|
809
|
-
error: {
|
|
810
|
-
code: "MANIFEST_ID_MISMATCH",
|
|
811
|
-
message: `Bundle manifest id (${bundle.manifest.id}) does not match registry slug (${slug})`,
|
|
812
|
-
},
|
|
813
|
-
};
|
|
857
|
+
const { bundle, artifactDigest, artifactDigests } = artifactReport.value;
|
|
858
|
+
const recordReport = await verifyAuthoritativePackageRelease(records, artifactDigest, {
|
|
859
|
+
...opts?.authoritativeRecords,
|
|
860
|
+
artifactDigests,
|
|
861
|
+
});
|
|
862
|
+
if (!recordReport.success) {
|
|
863
|
+
return registryRecordError(
|
|
864
|
+
recordReport.code,
|
|
865
|
+
recordReport.reasons[0]?.message ?? "The release provenance is invalid.",
|
|
866
|
+
);
|
|
814
867
|
}
|
|
868
|
+
const verification = recordVerificationSummary(records, recordReport);
|
|
815
869
|
|
|
816
870
|
// Rewrite the manifest's id to the derived opaque pluginId before
|
|
817
871
|
// it reaches R2 storage or the sandbox loader. The sandbox uses
|
|
@@ -829,13 +883,8 @@ export async function handleRegistryInstall(
|
|
|
829
883
|
// outside what the user reviewed. The capability-set consent gate below
|
|
830
884
|
// is blind to constraint content (host scope), so compare the full
|
|
831
885
|
// enforced access of record vs bundle here and refuse on any difference.
|
|
832
|
-
const recordExt =
|
|
833
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- extensions is the lexicon's open `unknown` map; narrow to read our own extension
|
|
834
|
-
(release?.extensions as Record<string, { declaredAccess?: DeclaredAccess }> | undefined)?.[
|
|
835
|
-
RELEASE_EXTENSION_NSID
|
|
836
|
-
];
|
|
837
886
|
if (
|
|
838
|
-
!
|
|
887
|
+
!verifiedAccessEqual(recordReport.value.declaredAccess, bundle.manifest.declaredAccess ?? {})
|
|
839
888
|
) {
|
|
840
889
|
return {
|
|
841
890
|
success: false,
|
|
@@ -849,13 +898,9 @@ export async function handleRegistryInstall(
|
|
|
849
898
|
|
|
850
899
|
// Capability consent gate: the admin MUST acknowledge the
|
|
851
900
|
// capabilities the bundle's manifest actually declares before we
|
|
852
|
-
// install it. The bundle manifest is the
|
|
853
|
-
// the
|
|
854
|
-
//
|
|
855
|
-
// assertion that the publisher may or may not have included,
|
|
856
|
-
// and trusting it would let a malicious publisher (or a
|
|
857
|
-
// compromised aggregator) ship a bundle whose manifest
|
|
858
|
-
// requests `content:*` etc. behind an empty consent dialog.
|
|
901
|
+
// install it. The bundle manifest is the runtime enforcement
|
|
902
|
+
// currency; the exact-equality check above binds it to the
|
|
903
|
+
// independently verified signed release.
|
|
859
904
|
//
|
|
860
905
|
// Two outcomes after normalization (filter to strings, dedupe,
|
|
861
906
|
// sort):
|
|
@@ -872,7 +917,7 @@ export async function handleRegistryInstall(
|
|
|
872
917
|
// the runtime starts enforcing `declaredAccess` natively, this
|
|
873
918
|
// comparison switches to that shape.
|
|
874
919
|
const actualCapabilities = canonicalCapabilitiesForDriftCheck(bundle.manifest.capabilities);
|
|
875
|
-
if (actualCapabilities.length > 0) {
|
|
920
|
+
if (!opts?.verifyOnly && actualCapabilities.length > 0) {
|
|
876
921
|
if (input.acknowledgedDeclaredAccess === undefined) {
|
|
877
922
|
return {
|
|
878
923
|
success: false,
|
|
@@ -902,19 +947,31 @@ export async function handleRegistryInstall(
|
|
|
902
947
|
const actualMcpTools = (bundle.manifest.mcp?.tools ?? []).map(
|
|
903
948
|
({ inputSchema: _, outputSchema: __, ...tool }) => tool,
|
|
904
949
|
);
|
|
905
|
-
if (actualMcpTools.length > 0) {
|
|
950
|
+
if (!opts?.verifyOnly && actualMcpTools.length > 0) {
|
|
906
951
|
if (JSON.stringify(input.acknowledgedMcpTools) !== JSON.stringify(actualMcpTools)) {
|
|
907
952
|
return {
|
|
908
953
|
success: false,
|
|
909
954
|
error: {
|
|
910
955
|
code: "MCP_TOOL_CONSENT_REQUIRED",
|
|
911
956
|
message: "Plugin MCP tools require explicit consent",
|
|
912
|
-
details: { mcpTools: actualMcpTools },
|
|
957
|
+
details: { mcpTools: actualMcpTools, verification },
|
|
913
958
|
},
|
|
914
959
|
};
|
|
915
960
|
}
|
|
916
961
|
}
|
|
917
962
|
|
|
963
|
+
const result: RegistryInstallResult = {
|
|
964
|
+
pluginId,
|
|
965
|
+
publisherDid,
|
|
966
|
+
slug,
|
|
967
|
+
version,
|
|
968
|
+
capabilities: bundle.manifest.capabilities,
|
|
969
|
+
declaredAccess: recordReport.value.releaseExtension.declaredAccess,
|
|
970
|
+
mcpTools: actualMcpTools,
|
|
971
|
+
verification,
|
|
972
|
+
};
|
|
973
|
+
if (opts?.verifyOnly) return { success: true, data: result };
|
|
974
|
+
|
|
918
975
|
// Step 7: store in R2 under the registry prefix.
|
|
919
976
|
await storeBundleInR2(storage, pluginId, version, bundle, "registry");
|
|
920
977
|
|
|
@@ -947,13 +1004,11 @@ export async function handleRegistryInstall(
|
|
|
947
1004
|
// Cleanup is best-effort; if it also fails, the row failure
|
|
948
1005
|
// still surfaces to the caller and the orphan R2 bundle costs
|
|
949
1006
|
// only the storage of a single checksum-verified zip.
|
|
950
|
-
// `packageView.profile` is lexicon-validated by DiscoveryClient (or null).
|
|
951
|
-
const profile = packageView.profile;
|
|
952
1007
|
try {
|
|
953
1008
|
await stateRepo.upsert(pluginId, version, "active", {
|
|
954
1009
|
source: "registry",
|
|
955
|
-
displayName: profile
|
|
956
|
-
description: profile
|
|
1010
|
+
displayName: profile.name ?? slug,
|
|
1011
|
+
description: profile.description ?? undefined,
|
|
957
1012
|
registryPublisherDid: publisherDid,
|
|
958
1013
|
registrySlug: slug,
|
|
959
1014
|
});
|
|
@@ -985,13 +1040,7 @@ export async function handleRegistryInstall(
|
|
|
985
1040
|
|
|
986
1041
|
return {
|
|
987
1042
|
success: true,
|
|
988
|
-
data:
|
|
989
|
-
pluginId,
|
|
990
|
-
publisherDid,
|
|
991
|
-
slug,
|
|
992
|
-
version,
|
|
993
|
-
capabilities: bundle.manifest.capabilities,
|
|
994
|
-
},
|
|
1043
|
+
data: result,
|
|
995
1044
|
};
|
|
996
1045
|
} catch (err) {
|
|
997
1046
|
if (err instanceof ClientValidationError) {
|
|
@@ -1129,6 +1178,7 @@ export interface RegistryUpdateResult {
|
|
|
1129
1178
|
capabilityChanges: { added: string[]; removed: string[] };
|
|
1130
1179
|
/** Set only when `newlyPublic` is non-empty, mirroring marketplace. */
|
|
1131
1180
|
routeVisibilityChanges?: { newlyPublic: string[] };
|
|
1181
|
+
verification: RegistryRecordVerificationSummary;
|
|
1132
1182
|
}
|
|
1133
1183
|
|
|
1134
1184
|
/**
|
|
@@ -1153,7 +1203,11 @@ export async function handleRegistryUpdate(
|
|
|
1153
1203
|
confirmCapabilityChanges?: boolean;
|
|
1154
1204
|
confirmRouteVisibilityChanges?: boolean;
|
|
1155
1205
|
confirmMcpTools?: boolean;
|
|
1206
|
+
acknowledgedProfileCid?: string;
|
|
1207
|
+
acknowledgedReleaseCid?: string;
|
|
1156
1208
|
hostEnv?: HostEnv;
|
|
1209
|
+
authoritativeRecords?: AuthoritativeRecordReadOptions;
|
|
1210
|
+
readAuthoritativeRecords?: AuthoritativeRecordReader;
|
|
1157
1211
|
},
|
|
1158
1212
|
): Promise<ApiResult<RegistryUpdateResult>> {
|
|
1159
1213
|
const registryConfig = coerceRegistryConfig(registryConfigInput);
|
|
@@ -1264,16 +1318,12 @@ export async function handleRegistryUpdate(
|
|
|
1264
1318
|
};
|
|
1265
1319
|
}
|
|
1266
1320
|
|
|
1267
|
-
//
|
|
1268
|
-
//
|
|
1269
|
-
// (did, slug, version) under this plugin's pluginId.
|
|
1270
|
-
const signedRelease = releaseView.release;
|
|
1321
|
+
// The aggregator selects the target version and supplies mirrors and
|
|
1322
|
+
// moderation metadata. Its release-record copy is not trusted.
|
|
1271
1323
|
if (
|
|
1272
1324
|
releaseView.did !== publisherDid ||
|
|
1273
1325
|
releaseView.package !== slug ||
|
|
1274
|
-
|
|
1275
|
-
(opts?.version !== undefined && releaseView.version !== opts.version) ||
|
|
1276
|
-
signedRelease?.version !== releaseView.version
|
|
1326
|
+
(opts?.version !== undefined && releaseView.version !== opts.version)
|
|
1277
1327
|
) {
|
|
1278
1328
|
return {
|
|
1279
1329
|
success: false,
|
|
@@ -1284,6 +1334,16 @@ export async function handleRegistryUpdate(
|
|
|
1284
1334
|
},
|
|
1285
1335
|
};
|
|
1286
1336
|
}
|
|
1337
|
+
const packageView = await discovery.getPackage({ did: publisherDid, slug });
|
|
1338
|
+
if (!packageView || packageView.did !== publisherDid || packageView.slug !== slug) {
|
|
1339
|
+
return {
|
|
1340
|
+
success: false,
|
|
1341
|
+
error: {
|
|
1342
|
+
code: "AGGREGATOR_IDENTITY_MISMATCH",
|
|
1343
|
+
message: "Aggregator returned a package view that does not match the installed plugin.",
|
|
1344
|
+
},
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1287
1347
|
|
|
1288
1348
|
const newVersion = releaseView.version;
|
|
1289
1349
|
if (evaluateRegistryReleaseWithdrawal(releaseView, discovery.labelerPolicy).withdrawn) {
|
|
@@ -1301,17 +1361,64 @@ export async function handleRegistryUpdate(
|
|
|
1301
1361
|
},
|
|
1302
1362
|
};
|
|
1303
1363
|
}
|
|
1304
|
-
|
|
1364
|
+
const authoritative = await (opts?.readAuthoritativeRecords ?? readAuthoritativePackageRelease)(
|
|
1365
|
+
publisherDid,
|
|
1366
|
+
slug,
|
|
1367
|
+
newVersion,
|
|
1368
|
+
opts?.authoritativeRecords,
|
|
1369
|
+
);
|
|
1370
|
+
if (!authoritative.success) {
|
|
1371
|
+
return registryRecordError(authoritative.error.code, authoritative.error.message);
|
|
1372
|
+
}
|
|
1373
|
+
const records = authoritative.value;
|
|
1374
|
+
const { profile, release } = records.inspection.value;
|
|
1375
|
+
if (
|
|
1376
|
+
packageView.uri !== records.profile.uri ||
|
|
1377
|
+
packageView.cid !== records.profile.cid ||
|
|
1378
|
+
releaseView.uri !== records.release.uri ||
|
|
1379
|
+
releaseView.cid !== records.release.cid
|
|
1380
|
+
) {
|
|
1381
|
+
return {
|
|
1382
|
+
success: false,
|
|
1383
|
+
error: {
|
|
1384
|
+
code: "AGGREGATOR_RECORD_MISMATCH",
|
|
1385
|
+
message: "Aggregator metadata does not match the publisher's signed records.",
|
|
1386
|
+
},
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
const packageYanked =
|
|
1390
|
+
hasCurrentRecordLabel(packageView.labels ?? [], "security:yanked", records.profile) ||
|
|
1391
|
+
hasCurrentRecordLabel(packageView.labels ?? [], "security-yanked", records.profile);
|
|
1392
|
+
if (packageYanked) {
|
|
1393
|
+
return {
|
|
1394
|
+
success: false,
|
|
1395
|
+
error: { code: "YANKED", message: "Package has been withdrawn" },
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
if (
|
|
1399
|
+
opts?.confirmCapabilityChanges ||
|
|
1400
|
+
opts?.confirmRouteVisibilityChanges ||
|
|
1401
|
+
opts?.confirmMcpTools
|
|
1402
|
+
) {
|
|
1403
|
+
const consentError = recordConsentError(
|
|
1404
|
+
{
|
|
1405
|
+
profileCid: opts.acknowledgedProfileCid,
|
|
1406
|
+
releaseCid: opts.acknowledgedReleaseCid,
|
|
1407
|
+
},
|
|
1408
|
+
records,
|
|
1409
|
+
);
|
|
1410
|
+
if (consentError) return consentError;
|
|
1411
|
+
}
|
|
1305
1412
|
// Environment compatibility remains independent from listing approval.
|
|
1306
1413
|
// An ungated update could otherwise
|
|
1307
1414
|
// land a version whose `requires` the host doesn't satisfy. Same
|
|
1308
1415
|
// guard as install; `requires` is lexicon-`unknown`.
|
|
1309
1416
|
if (opts?.hostEnv) {
|
|
1310
|
-
const envError = assertEnvCompatible(
|
|
1417
|
+
const envError = assertEnvCompatible(release.requires, opts.hostEnv);
|
|
1311
1418
|
if (envError) return { success: false, error: envError };
|
|
1312
1419
|
}
|
|
1313
1420
|
|
|
1314
|
-
const packageArtifact =
|
|
1421
|
+
const packageArtifact = release.artifacts.package;
|
|
1315
1422
|
const declaredChecksum = packageArtifact?.checksum;
|
|
1316
1423
|
if (!packageArtifact || !declaredChecksum) {
|
|
1317
1424
|
return {
|
|
@@ -1323,47 +1430,50 @@ export async function handleRegistryUpdate(
|
|
|
1323
1430
|
};
|
|
1324
1431
|
}
|
|
1325
1432
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
);
|
|
1337
|
-
if (!(await verifyChecksum(artifactBytes, declaredChecksum))) {
|
|
1338
|
-
return {
|
|
1339
|
-
success: false,
|
|
1340
|
-
error: {
|
|
1341
|
-
code: "CHECKSUM_MISMATCH",
|
|
1342
|
-
message: "Artifact bytes do not match the release's published checksum",
|
|
1433
|
+
let artifactBytes: Uint8Array;
|
|
1434
|
+
try {
|
|
1435
|
+
artifactBytes = await fetchArtifact(
|
|
1436
|
+
releaseView.artifactCaches ?? [],
|
|
1437
|
+
packageArtifact,
|
|
1438
|
+
{
|
|
1439
|
+
did: publisherDid,
|
|
1440
|
+
collection: NSID.packageRelease,
|
|
1441
|
+
rkey: `${slug}:${newVersion}`,
|
|
1442
|
+
cid: releaseView.cid,
|
|
1343
1443
|
},
|
|
1344
|
-
|
|
1444
|
+
release.auth,
|
|
1445
|
+
);
|
|
1446
|
+
} catch (error) {
|
|
1447
|
+
if (error instanceof RegistryArtifactFetchError) {
|
|
1448
|
+
return registryArtifactError(error.code, error.message, "update");
|
|
1449
|
+
}
|
|
1450
|
+
throw error;
|
|
1345
1451
|
}
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1452
|
+
const artifactReport = await validateRegistryArtifact(
|
|
1453
|
+
artifactBytes,
|
|
1454
|
+
declaredChecksum,
|
|
1455
|
+
slug,
|
|
1456
|
+
newVersion,
|
|
1457
|
+
);
|
|
1458
|
+
if (!artifactReport.success) {
|
|
1459
|
+
return registryArtifactError(
|
|
1460
|
+
artifactReport.error.code,
|
|
1461
|
+
artifactReport.error.message,
|
|
1462
|
+
"update",
|
|
1463
|
+
);
|
|
1357
1464
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1465
|
+
const { bundle, artifactDigest, artifactDigests } = artifactReport.value;
|
|
1466
|
+
const recordReport = await verifyAuthoritativePackageRelease(records, artifactDigest, {
|
|
1467
|
+
...opts?.authoritativeRecords,
|
|
1468
|
+
artifactDigests,
|
|
1469
|
+
});
|
|
1470
|
+
if (!recordReport.success) {
|
|
1471
|
+
return registryRecordError(
|
|
1472
|
+
recordReport.code,
|
|
1473
|
+
recordReport.reasons[0]?.message ?? "The release provenance is invalid.",
|
|
1474
|
+
);
|
|
1366
1475
|
}
|
|
1476
|
+
const verification = recordVerificationSummary(records, recordReport);
|
|
1367
1477
|
|
|
1368
1478
|
// Rewrite manifest.id to the opaque pluginId so the sandbox loader
|
|
1369
1479
|
// and R2 layout stay in sync across install and update.
|
|
@@ -1374,13 +1484,8 @@ export async function handleRegistryUpdate(
|
|
|
1374
1484
|
// that changes only the host scope (e.g. api.good.com -> evil.com) keeps
|
|
1375
1485
|
// the capability set identical, sails through the escalation diff below,
|
|
1376
1486
|
// and installs a bundle enforcing a scope the record never showed.
|
|
1377
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- extensions is the lexicon's open `unknown` map; narrow to read our own extension
|
|
1378
|
-
const updateRecordExtensions = signedRelease?.extensions as
|
|
1379
|
-
| Record<string, { declaredAccess?: DeclaredAccess }>
|
|
1380
|
-
| undefined;
|
|
1381
|
-
const recordExt = updateRecordExtensions?.[RELEASE_EXTENSION_NSID];
|
|
1382
1487
|
if (
|
|
1383
|
-
!
|
|
1488
|
+
!verifiedAccessEqual(recordReport.value.declaredAccess, bundle.manifest.declaredAccess ?? {})
|
|
1384
1489
|
) {
|
|
1385
1490
|
return {
|
|
1386
1491
|
success: false,
|
|
@@ -1406,7 +1511,7 @@ export async function handleRegistryUpdate(
|
|
|
1406
1511
|
error: {
|
|
1407
1512
|
code: "CAPABILITY_ESCALATION",
|
|
1408
1513
|
message: "Plugin update requires new capabilities",
|
|
1409
|
-
details: { capabilityChanges },
|
|
1514
|
+
details: { capabilityChanges, verification },
|
|
1410
1515
|
},
|
|
1411
1516
|
};
|
|
1412
1517
|
}
|
|
@@ -1419,7 +1524,7 @@ export async function handleRegistryUpdate(
|
|
|
1419
1524
|
error: {
|
|
1420
1525
|
code: "ROUTE_VISIBILITY_ESCALATION",
|
|
1421
1526
|
message: "Plugin update exposes new public (unauthenticated) routes",
|
|
1422
|
-
details: { routeVisibilityChanges, capabilityChanges },
|
|
1527
|
+
details: { routeVisibilityChanges, capabilityChanges, verification },
|
|
1423
1528
|
},
|
|
1424
1529
|
};
|
|
1425
1530
|
}
|
|
@@ -1438,6 +1543,7 @@ export async function handleRegistryUpdate(
|
|
|
1438
1543
|
message: "Plugin update changes its MCP tools",
|
|
1439
1544
|
details: {
|
|
1440
1545
|
mcpTools: newMcpTools.map(({ inputSchema: _, outputSchema: __, ...tool }) => tool),
|
|
1546
|
+
verification,
|
|
1441
1547
|
},
|
|
1442
1548
|
},
|
|
1443
1549
|
};
|
|
@@ -1447,17 +1553,14 @@ export async function handleRegistryUpdate(
|
|
|
1447
1553
|
// so a retry of the same update is idempotent.
|
|
1448
1554
|
await storeBundleInR2(storage, pluginId, newVersion, bundle, "registry");
|
|
1449
1555
|
|
|
1450
|
-
//
|
|
1451
|
-
//
|
|
1452
|
-
// re-fetch the profile here — that's a separate `getPackage` round
|
|
1453
|
-
// trip and the install-time values are still authoritative for
|
|
1454
|
-
// the same package identity).
|
|
1556
|
+
// Refresh display metadata from the same signed profile used for
|
|
1557
|
+
// release-policy verification.
|
|
1455
1558
|
await stateRepo.upsert(pluginId, newVersion, "active", {
|
|
1456
1559
|
source: "registry",
|
|
1457
1560
|
registryPublisherDid: publisherDid,
|
|
1458
1561
|
registrySlug: slug,
|
|
1459
|
-
displayName:
|
|
1460
|
-
description:
|
|
1562
|
+
displayName: profile.name ?? slug,
|
|
1563
|
+
description: profile.description ?? undefined,
|
|
1461
1564
|
mcpToolsEnabled: false,
|
|
1462
1565
|
mcpToolsConsent: null,
|
|
1463
1566
|
});
|
|
@@ -1477,6 +1580,7 @@ export async function handleRegistryUpdate(
|
|
|
1477
1580
|
newVersion,
|
|
1478
1581
|
capabilityChanges,
|
|
1479
1582
|
routeVisibilityChanges: hasNewPublicRoutes ? routeVisibilityChanges : undefined,
|
|
1583
|
+
verification,
|
|
1480
1584
|
},
|
|
1481
1585
|
};
|
|
1482
1586
|
} catch (err) {
|