emdash 0.14.0 → 0.16.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-9DybjTO6.d.mts → adapters-C4yd_UJR.d.mts} +1 -1
- package/dist/{adapters-9DybjTO6.d.mts.map → adapters-C4yd_UJR.d.mts.map} +1 -1
- package/dist/{allowed-origins-CDdG-4Gd.mjs → allowed-origins-D0fFk9a6.mjs} +2 -2
- package/dist/{allowed-origins-CDdG-4Gd.mjs.map → allowed-origins-D0fFk9a6.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.mjs +15 -15
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +3 -3
- package/dist/{api-BMLZuwM4.mjs → api-BNKqxyFX.mjs} +560 -56
- package/dist/api-BNKqxyFX.mjs.map +1 -0
- package/dist/{api-tokens-eYymBhIT.mjs → api-tokens-ucpcNXDt.mjs} +2 -2
- package/dist/{api-tokens-eYymBhIT.mjs.map → api-tokens-ucpcNXDt.mjs.map} +1 -1
- package/dist/{apply-v4DBgjPw.mjs → apply-BOPaD-s9.mjs} +17 -17
- package/dist/{apply-v4DBgjPw.mjs.map → apply-BOPaD-s9.mjs.map} +1 -1
- package/dist/astro/index.d.mts +10 -10
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +53 -5
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +9 -9
- package/dist/astro/middleware/auth.mjs +6 -6
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +377 -75
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/bylines/_id_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -17
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +9 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +70 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -0
- package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +25 -16
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +10 -10
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +8 -8
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +8 -8
- 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/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +33 -32
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +33 -32
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +34 -32
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +32 -31
- 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 +34 -32
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +32 -31
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +59 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +85 -0
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +301 -0
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +51 -32
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +45 -32
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +32 -31
- 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 +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +32 -31
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
- package/dist/astro/routes/api/admin/users/index.mjs +5 -5
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
- package/dist/astro/routes/api/auth/logout.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/me.mjs +5 -5
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
- package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
- package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
- 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_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +6 -6
- package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
- package/dist/astro/routes/api/dashboard.mjs +7 -7
- package/dist/astro/routes/api/dev/emails.mjs +3 -3
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
- package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -8
- package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +11 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +17 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +11 -11
- 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/mcp.mjs +29 -29
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +6 -6
- package/dist/astro/routes/api/media/_id_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
- package/dist/astro/routes/api/media/providers/index.mjs +3 -3
- package/dist/astro/routes/api/media/upload-url.mjs +7 -7
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.mjs +8 -8
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/items.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_/translations.mjs +7 -7
- package/dist/astro/routes/api/menus/_name_.mjs +7 -7
- package/dist/astro/routes/api/menus/index.mjs +7 -7
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.mjs +6 -6
- package/dist/astro/routes/api/openapi.json.mjs +3 -3
- 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/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +8 -8
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +9 -9
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +9 -9
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +32 -31
- 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 +32 -31
- 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 +32 -31
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +32 -31
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +32 -31
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +6 -6
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +32 -31
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +32 -31
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +9 -9
- package/dist/astro/routes/api/search/index.mjs +8 -8
- package/dist/astro/routes/api/search/rebuild.mjs +9 -9
- package/dist/astro/routes/api/search/stats.mjs +6 -6
- package/dist/astro/routes/api/search/suggest.mjs +8 -8
- package/dist/astro/routes/api/sections/_slug_.mjs +8 -8
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +8 -8
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/email.mjs +4 -4
- package/dist/astro/routes/api/settings.mjs +10 -10
- package/dist/astro/routes/api/setup/admin-verify.mjs +10 -10
- package/dist/astro/routes/api/setup/admin.mjs +9 -9
- package/dist/astro/routes/api/setup/dev-bypass.mjs +22 -22
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +22 -22
- package/dist/astro/routes/api/setup/status.mjs +4 -4
- package/dist/astro/routes/api/snapshot.mjs +6 -6
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -10
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +11 -10
- 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 +5 -5
- 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.mjs +6 -6
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
- package/dist/astro/routes/api/widget-areas/index.mjs +8 -8
- package/dist/astro/routes/api/widget-components.mjs +3 -3
- package/dist/astro/routes/robots.txt.mjs +5 -5
- package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +58 -13
- package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
- package/dist/astro/routes/sitemap.xml.mjs +6 -6
- package/dist/astro/types.d.mts +20 -12
- 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-BlyCH-96.mjs → authorize-Bn4S4DUT.mjs} +2 -2
- package/dist/{authorize-BlyCH-96.mjs.map → authorize-Bn4S4DUT.mjs.map} +1 -1
- package/dist/byline-BDylH_m4.mjs +404 -0
- package/dist/byline-BDylH_m4.mjs.map +1 -0
- package/dist/{bylines-BdUP8NuI.d.mts → bylines-B2_XmnSU.d.mts} +73 -28
- package/dist/bylines-B2_XmnSU.d.mts.map +1 -0
- package/dist/bylines-B7TFEvFf.mjs +118 -0
- package/dist/bylines-B7TFEvFf.mjs.map +1 -0
- package/dist/bylines-n6nykUyI.mjs +174 -0
- package/dist/bylines-n6nykUyI.mjs.map +1 -0
- package/dist/{cache-CXCpjWiL.mjs → cache-BcI1yUjR.mjs} +2 -2
- package/dist/{cache-CXCpjWiL.mjs.map → cache-BcI1yUjR.mjs.map} +1 -1
- package/dist/{challenge-store-CJ0OOHOr.mjs → challenge-store-Dng1SxKT.mjs} +1 -1
- package/dist/{challenge-store-CJ0OOHOr.mjs.map → challenge-store-Dng1SxKT.mjs.map} +1 -1
- package/dist/{chunks-DyGtu1Bv.mjs → chunks-cYG4SnIP.mjs} +2 -2
- package/dist/{chunks-DyGtu1Bv.mjs.map → chunks-cYG4SnIP.mjs.map} +1 -1
- package/dist/cli/index.mjs +68 -30
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-Dd9MI82-.mjs → comment-C76G-9tz.mjs} +2 -2
- package/dist/{comment-Dd9MI82-.mjs.map → comment-C76G-9tz.mjs.map} +1 -1
- package/dist/{comments-koGI0FrK.mjs → comments-CCxFFGY1.mjs} +3 -3
- package/dist/{comments-koGI0FrK.mjs.map → comments-CCxFFGY1.mjs.map} +1 -1
- package/dist/{components-mZem7pbe.mjs → components-Dx3DM0gg.mjs} +1 -1
- package/dist/{components-mZem7pbe.mjs.map → components-Dx3DM0gg.mjs.map} +1 -1
- package/dist/config-CVssduLe.mjs.map +1 -1
- package/dist/{content-D6YG26WG.mjs → content-8voQNTXX.mjs} +3 -3
- package/dist/{content-D6YG26WG.mjs.map → content-8voQNTXX.mjs.map} +1 -1
- package/dist/{context-qF8d3IPR.mjs → context-B7qiYrz2.mjs} +10 -10
- package/dist/context-B7qiYrz2.mjs.map +1 -0
- package/dist/{cron-H8eJ46dv.mjs → cron-Bd3b3iuj.mjs} +1 -1
- package/dist/{cron-H8eJ46dv.mjs.map → cron-Bd3b3iuj.mjs.map} +1 -1
- package/dist/{dashboard-BmWSIUwY.mjs → dashboard-BeaFSPpx.mjs} +4 -4
- package/dist/{dashboard-BmWSIUwY.mjs.map → dashboard-BeaFSPpx.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +1 -1
- package/dist/{db-errors-CGN9kJfo.mjs → db-errors-BiYqoX-n.mjs} +14 -2
- package/dist/db-errors-BiYqoX-n.mjs.map +1 -0
- package/dist/{default-Dbs22Gg4.mjs → default-BvTAYCzx.mjs} +1 -1
- package/dist/{default-Dbs22Gg4.mjs.map → default-BvTAYCzx.mjs.map} +1 -1
- package/dist/{device-flow-BqJRxa0Q.mjs → device-flow-B9oG8PwP.mjs} +4 -4
- package/dist/{device-flow-BqJRxa0Q.mjs.map → device-flow-B9oG8PwP.mjs.map} +1 -1
- package/dist/{email-console-Dmp5Q-P2.mjs → email-console-CubRll9q.mjs} +1 -1
- package/dist/email-console-CubRll9q.mjs.map +1 -0
- package/dist/{error-tSQWIl5U.mjs → error-ChfADBuu.mjs} +19 -9
- package/dist/error-ChfADBuu.mjs.map +1 -0
- package/dist/errors-9P_FDrJ_.mjs +17 -0
- package/dist/errors-9P_FDrJ_.mjs.map +1 -0
- package/dist/{escape-B8bdIryO.mjs → escape-Cg6kMELH.mjs} +1 -1
- package/dist/{escape-B8bdIryO.mjs.map → escape-Cg6kMELH.mjs.map} +1 -1
- package/dist/{fts-manager-B633C-kQ.mjs → fts-manager-C_b-4x8u.mjs} +2 -2
- package/dist/{fts-manager-B633C-kQ.mjs.map → fts-manager-C_b-4x8u.mjs.map} +1 -1
- package/dist/{import-CNfLOgDE.mjs → import-DG80rC_I.mjs} +3 -3
- package/dist/{import-CNfLOgDE.mjs.map → import-DG80rC_I.mjs.map} +1 -1
- package/dist/{index-BV8iJ-6s.d.mts → index-BPZFAcgE.d.mts} +384 -123
- package/dist/index-BPZFAcgE.d.mts.map +1 -0
- package/dist/{index-D2gvztOP.d.mts → index-CC42STEm.d.mts} +3 -3
- package/dist/{index-D2gvztOP.d.mts.map → index-CC42STEm.d.mts.map} +1 -1
- package/dist/index.d.mts +17 -17
- package/dist/index.mjs +53 -52
- package/dist/{load-QzYRpVN3.mjs → load-CLFRjk9r.mjs} +2 -2
- package/dist/{load-QzYRpVN3.mjs.map → load-CLFRjk9r.mjs.map} +1 -1
- package/dist/{loader-Cs6-Bqe6.mjs → loader-D-vIJjfY.mjs} +86 -46
- package/dist/loader-D-vIJjfY.mjs.map +1 -0
- package/dist/{manifest-schema-HCtSh4Jq.mjs → manifest-schema-Czqf0TLu.mjs} +1 -1
- package/dist/{manifest-schema-HCtSh4Jq.mjs.map → manifest-schema-Czqf0TLu.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +11 -11
- package/dist/media/local-runtime.mjs +4 -4
- package/dist/{media-Dg7he9uK.mjs → media-CKQd8AYU.mjs} +2 -2
- package/dist/media-CKQd8AYU.mjs.map +1 -0
- package/dist/{media-allowlist-B8EX01DH.mjs → media-allowlist-BNloC69x.mjs} +1 -1
- package/dist/{media-allowlist-B8EX01DH.mjs.map → media-allowlist-BNloC69x.mjs.map} +1 -1
- package/dist/{menus-X4Z-eBA1.mjs → menus-C-nWT5Tu.mjs} +42 -17
- package/dist/menus-C-nWT5Tu.mjs.map +1 -0
- package/dist/{menus-DOzIecHi.mjs → menus-arUNspyU.mjs} +2 -2
- package/dist/menus-arUNspyU.mjs.map +1 -0
- package/dist/mime-KV5TqkMN.mjs.map +1 -1
- package/dist/{mode-DPRPvJYm.mjs → mode-CaaiebZI.mjs} +1 -1
- package/dist/{mode-DPRPvJYm.mjs.map → mode-CaaiebZI.mjs.map} +1 -1
- package/dist/{oauth-authorization-62GmpGIH.mjs → oauth-authorization-CTMeVfvj.mjs} +4 -4
- package/dist/{oauth-authorization-62GmpGIH.mjs.map → oauth-authorization-CTMeVfvj.mjs.map} +1 -1
- package/dist/{oauth-clients-D_B0_-Bz.mjs → oauth-clients-eJCbkVSG.mjs} +1 -1
- package/dist/oauth-clients-eJCbkVSG.mjs.map +1 -0
- package/dist/{oauth-state-store-DpsZViTu.mjs → oauth-state-store-vOSdOeGe.mjs} +1 -1
- package/dist/{oauth-state-store-DpsZViTu.mjs.map → oauth-state-store-vOSdOeGe.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-meyS2oB1.mjs → oauth-user-lookup-3JwsVw6N.mjs} +1 -1
- package/dist/{oauth-user-lookup-meyS2oB1.mjs.map → oauth-user-lookup-3JwsVw6N.mjs.map} +1 -1
- package/dist/options-BL4X94qY.mjs.map +1 -1
- package/dist/{options-Cq64Wx0O.d.mts → options-DhV-gwJb.d.mts} +4 -4
- package/dist/options-DhV-gwJb.d.mts.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-BFTPon-J.mjs → parse-DHbXfvxO.mjs} +2 -2
- package/dist/{parse-BFTPon-J.mjs.map → parse-DHbXfvxO.mjs.map} +1 -1
- package/dist/{passkey-config-Cg86_ISa.mjs → passkey-config-BloQOT3y.mjs} +1 -1
- package/dist/{passkey-config-Cg86_ISa.mjs.map → passkey-config-BloQOT3y.mjs.map} +1 -1
- package/dist/{placeholder-D3cFCU9y.d.mts → placeholder-KCkkCtgQ.d.mts} +1 -1
- package/dist/{placeholder-D3cFCU9y.d.mts.map → placeholder-KCkkCtgQ.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +25 -10
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugin-utils.mjs +11 -10
- package/dist/plugin-utils.mjs.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +26 -15
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{preview-C1LOEbWZ.mjs → preview-D4z0WONU.mjs} +2 -2
- package/dist/{preview-C1LOEbWZ.mjs.map → preview-D4z0WONU.mjs.map} +1 -1
- package/dist/{public-url-CseXl9Fv.mjs → public-url-CUWWFME2.mjs} +1 -1
- package/dist/{public-url-CseXl9Fv.mjs.map → public-url-CUWWFME2.mjs.map} +1 -1
- package/dist/{query-axZmO6Tn.mjs → query-7m6-l0f_.mjs} +27 -17
- package/dist/query-7m6-l0f_.mjs.map +1 -0
- package/dist/{rate-limit-t5CVjCO6.mjs → rate-limit-D8RAXN8b.mjs} +2 -2
- package/dist/{rate-limit-t5CVjCO6.mjs.map → rate-limit-D8RAXN8b.mjs.map} +1 -1
- package/dist/{redirect-DGRsLO2I.mjs → redirect-BINiRYq4.mjs} +1 -1
- package/dist/{redirect-DGRsLO2I.mjs.map → redirect-BINiRYq4.mjs.map} +1 -1
- package/dist/{redirect-DkaDxq8e.mjs → redirect-CjfDGrTd.mjs} +2 -2
- package/dist/{redirect-DkaDxq8e.mjs.map → redirect-CjfDGrTd.mjs.map} +1 -1
- package/dist/{redirects-Dmj6KRU3.mjs → redirects-COMLwsV5.mjs} +19 -5
- package/dist/redirects-COMLwsV5.mjs.map +1 -0
- package/dist/{redirects-D1fdd68T.mjs → redirects-CowoEHdE.mjs} +3 -3
- package/dist/{redirects-D1fdd68T.mjs.map → redirects-CowoEHdE.mjs.map} +1 -1
- package/dist/{registry-BnCeHYsf.mjs → registry-Cyp-dx6J.mjs} +4 -4
- package/dist/{registry-BnCeHYsf.mjs.map → registry-Cyp-dx6J.mjs.map} +1 -1
- package/dist/request-cache-dzCt8TZB.mjs.map +1 -1
- package/dist/request-context.mjs.map +1 -1
- package/dist/{request-meta-CLCwSQOS.mjs → request-meta-C_Cjii-T.mjs} +2 -2
- package/dist/{request-meta-CLCwSQOS.mjs.map → request-meta-C_Cjii-T.mjs.map} +1 -1
- package/dist/resolve-D6sM-SgF.mjs +143 -0
- package/dist/resolve-D6sM-SgF.mjs.map +1 -0
- package/dist/{runner-DcfZewkO.d.mts → runner-DSQBurMS.d.mts} +8 -5
- package/dist/runner-DSQBurMS.d.mts.map +1 -0
- package/dist/{runner-DdnQIwz_.mjs → runner-Drnvs96u.mjs} +491 -188
- package/dist/runner-Drnvs96u.mjs.map +1 -0
- package/dist/runtime.d.mts +10 -10
- package/dist/runtime.mjs +2 -2
- package/dist/{schema-BmqagCwG.mjs → schema-CI9mYPX3.mjs} +4 -4
- package/dist/{schema-BmqagCwG.mjs.map → schema-CI9mYPX3.mjs.map} +1 -1
- package/dist/{search-CPrvO5u8.mjs → search-DKz_mGBP.mjs} +4 -4
- package/dist/{search-CPrvO5u8.mjs.map → search-DKz_mGBP.mjs.map} +1 -1
- package/dist/{secrets-6pgZyq0K.mjs → secrets-rPdhEBkD.mjs} +1 -1
- package/dist/{secrets-6pgZyq0K.mjs.map → secrets-rPdhEBkD.mjs.map} +1 -1
- package/dist/{sections-Cm-zb-gZ.mjs → sections-DBbCDIAT.mjs} +3 -3
- package/dist/{sections-Cm-zb-gZ.mjs.map → sections-DBbCDIAT.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +16 -16
- package/dist/seo/index.d.mts +1 -1
- package/dist/{seo-DRq9-EPP.mjs → seo-BGCyDlkb.mjs} +2 -2
- package/dist/{seo-DRq9-EPP.mjs.map → seo-BGCyDlkb.mjs.map} +1 -1
- package/dist/{seo-BoR4wCUh.mjs → seo-Dq707mNQ.mjs} +5 -3
- package/dist/seo-Dq707mNQ.mjs.map +1 -0
- package/dist/{service-vByySp-2.mjs → service-B0H7U1Y9.mjs} +3 -3
- package/dist/{service-vByySp-2.mjs.map → service-B0H7U1Y9.mjs.map} +1 -1
- package/dist/{settings-xQKsWnzQ.mjs → settings-BSXRtTzk.mjs} +3 -3
- package/dist/settings-BSXRtTzk.mjs.map +1 -0
- package/dist/{settings-CBBj7HUd.mjs → settings-DfwNyQkf.mjs} +3 -3
- package/dist/{settings-CBBj7HUd.mjs.map → settings-DfwNyQkf.mjs.map} +1 -1
- package/dist/{setup-BGAJ2uXs.mjs → setup-Cf_TyOv5.mjs} +2 -2
- package/dist/{setup-BGAJ2uXs.mjs.map → setup-Cf_TyOv5.mjs.map} +1 -1
- package/dist/{setup-complete-C6ZCLhKo.mjs → setup-complete-MzzN9u0b.mjs} +1 -1
- package/dist/{setup-complete-C6ZCLhKo.mjs.map → setup-complete-MzzN9u0b.mjs.map} +1 -1
- package/dist/{setup-nonce-CY1gQiAU.mjs → setup-nonce-DXuriHsg.mjs} +1 -1
- package/dist/{setup-nonce-CY1gQiAU.mjs.map → setup-nonce-DXuriHsg.mjs.map} +1 -1
- package/dist/{site-url-D-M4Fd8O.mjs → site-url-xkhw1tcz.mjs} +1 -1
- package/dist/{site-url-D-M4Fd8O.mjs.map → site-url-xkhw1tcz.mjs.map} +1 -1
- package/dist/{ssrf-DzFN_qV-.mjs → ssrf-MZ-zrG6-.mjs} +1 -1
- package/dist/{ssrf-DzFN_qV-.mjs.map → ssrf-MZ-zrG6-.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/local.mjs.map +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{taxonomies-Dc0mzlms.mjs → taxonomies-4vx0nmMr.mjs} +4 -4
- package/dist/{taxonomies-Dc0mzlms.mjs.map → taxonomies-4vx0nmMr.mjs.map} +1 -1
- package/dist/{taxonomies-Cn9UpaR2.mjs → taxonomies-CcvrMLbR.mjs} +8 -43
- package/dist/taxonomies-CcvrMLbR.mjs.map +1 -0
- package/dist/{taxonomy-wPfusMK9.mjs → taxonomy-zqGQUqgu.mjs} +3 -3
- package/dist/{taxonomy-wPfusMK9.mjs.map → taxonomy-zqGQUqgu.mjs.map} +1 -1
- package/dist/{tokens-DILYNZMi.mjs → tokens-N8otWMmj.mjs} +1 -1
- package/dist/{tokens-DILYNZMi.mjs.map → tokens-N8otWMmj.mjs.map} +1 -1
- package/dist/{transport-fw-mKJzT.mjs → transport-B6CHddbu.mjs} +1 -1
- package/dist/{transport-fw-mKJzT.mjs.map → transport-B6CHddbu.mjs.map} +1 -1
- package/dist/{transport-GeXlLscf.d.mts → transport-C2MGqtL6.d.mts} +1 -1
- package/dist/{transport-GeXlLscf.d.mts.map → transport-C2MGqtL6.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CJhQIk65.mjs → trusted-proxy-97pajC2f.mjs} +1 -1
- package/dist/{trusted-proxy-CJhQIk65.mjs.map → trusted-proxy-97pajC2f.mjs.map} +1 -1
- package/dist/{types-CwXMEPRr.mjs → types-B0bmgwMG.mjs} +2 -2
- package/dist/types-B0bmgwMG.mjs.map +1 -0
- package/dist/{types-Dz9CGX_d.mjs → types-Cd9UCu3t.mjs} +1 -1
- package/dist/{types-Dz9CGX_d.mjs.map → types-Cd9UCu3t.mjs.map} +1 -1
- package/dist/{types-DmxPPXGf.d.mts → types-CkDSF81F.d.mts} +1 -1
- package/dist/{types-DmxPPXGf.d.mts.map → types-CkDSF81F.d.mts.map} +1 -1
- package/dist/{types-BWhaSS7U.d.mts → types-CpUuGcd5.d.mts} +1 -1
- package/dist/{types-BWhaSS7U.d.mts.map → types-CpUuGcd5.d.mts.map} +1 -1
- package/dist/{types-DFowNO60.d.mts → types-D599-ruj.d.mts} +1 -1
- package/dist/{types-DFowNO60.d.mts.map → types-D599-ruj.d.mts.map} +1 -1
- package/dist/{types-B05e2naf.d.mts → types-DGHWRQgr.d.mts} +3 -3
- package/dist/{types-B05e2naf.d.mts.map → types-DGHWRQgr.d.mts.map} +1 -1
- package/dist/{types-CzvJd1ND.d.mts → types-DaYDYW6g.d.mts} +14 -1
- package/dist/types-DaYDYW6g.d.mts.map +1 -0
- package/dist/{types-C1KKK4VP.d.mts → types-DaqNzqVt.d.mts} +16 -1
- package/dist/{types-C1KKK4VP.d.mts.map → types-DaqNzqVt.d.mts.map} +1 -1
- package/dist/{types-DW1l0gCv.d.mts → types-Dgo6y-Ut.d.mts} +1 -1
- package/dist/{types-DW1l0gCv.d.mts.map → types-Dgo6y-Ut.d.mts.map} +1 -1
- package/dist/{types-Cb2UCDJg.d.mts → types-bYmRn_Uy.d.mts} +1 -1
- package/dist/{types-Cb2UCDJg.d.mts.map → types-bYmRn_Uy.d.mts.map} +1 -1
- package/dist/{user-Dr1bOCqS.mjs → user-hUSOaIJy.mjs} +2 -2
- package/dist/{user-Dr1bOCqS.mjs.map → user-hUSOaIJy.mjs.map} +1 -1
- package/dist/{utils-_F-rWBTN.mjs → utils-C3wTAP-P.mjs} +1 -1
- package/dist/{utils-_F-rWBTN.mjs.map → utils-C3wTAP-P.mjs.map} +1 -1
- package/dist/{validate-BpQGsmd7.d.mts → validate-DQtHw9NT.d.mts} +5 -5
- package/dist/{validate-BpQGsmd7.d.mts.map → validate-DQtHw9NT.d.mts.map} +1 -1
- package/dist/{validate-DlFxcVVK.mjs → validate-IGltez8n.mjs} +2 -2
- package/dist/{validate-DlFxcVVK.mjs.map → validate-IGltez8n.mjs.map} +1 -1
- package/dist/{validation-BiFJqUp5.mjs → validation-Bmymau7y.mjs} +6 -6
- package/dist/{validation-BiFJqUp5.mjs.map → validation-Bmymau7y.mjs.map} +1 -1
- package/dist/version-BTc87L3L.mjs +7 -0
- package/dist/{version-DNmQakZO.mjs.map → version-BTc87L3L.mjs.map} +1 -1
- package/dist/{widgets-B9j_yzlk.mjs → widgets-yHQa4c6c.mjs} +3 -3
- package/dist/widgets-yHQa4c6c.mjs.map +1 -0
- package/dist/{zod-generator-DSyz01KE.mjs → zod-generator-B80aap1J.mjs} +2 -2
- package/dist/{zod-generator-DSyz01KE.mjs.map → zod-generator-B80aap1J.mjs.map} +1 -1
- package/package.json +12 -10
- package/src/api/error.ts +18 -3
- package/src/api/errors.ts +8 -0
- package/src/api/handlers/bylines.ts +161 -0
- package/src/api/handlers/content.ts +125 -43
- package/src/api/handlers/index.ts +8 -0
- package/src/api/handlers/marketplace.ts +27 -5
- package/src/api/handlers/oauth-clients.ts +1 -1
- package/src/api/handlers/registry.ts +622 -5
- package/src/api/handlers/seo.ts +16 -1
- package/src/api/handlers/snapshot.ts +1 -1
- package/src/api/openapi/document.ts +1 -1
- package/src/api/schemas/bylines.ts +46 -0
- package/src/astro/integration/index.ts +27 -1
- package/src/astro/integration/routes.ts +10 -0
- package/src/astro/integration/runtime.ts +20 -1
- package/src/astro/integration/virtual-modules.ts +19 -2
- package/src/astro/integration/vite-config.ts +2 -2
- package/src/astro/middleware/auth.ts +7 -7
- package/src/astro/middleware/request-context.ts +1 -1
- package/src/astro/middleware.ts +35 -20
- package/src/astro/public-plugin-api-routes.ts +41 -0
- package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -12
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +99 -0
- package/src/astro/routes/api/admin/bylines/index.ts +22 -11
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +1 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +6 -1
- package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +51 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +83 -0
- package/src/astro/routes/api/admin/plugins/registry/artifact.ts +388 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +7 -1
- package/src/astro/routes/api/admin/plugins/updates.ts +43 -6
- package/src/astro/routes/api/admin/themes/marketplace/index.ts +1 -1
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +2 -2
- package/src/astro/routes/api/auth/oauth/[provider].ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +6 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id].ts +6 -6
- package/src/astro/routes/api/import/wordpress/execute.ts +1 -1
- package/src/astro/routes/api/import/wordpress/prepare.ts +2 -2
- package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +22 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +8 -5
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +2 -2
- package/src/astro/routes/api/media/upload-url.ts +1 -1
- package/src/astro/routes/api/redirects/404s/index.ts +3 -3
- package/src/astro/routes/api/redirects/404s/summary.ts +1 -1
- package/src/astro/routes/api/redirects/[id].ts +3 -3
- package/src/astro/routes/api/redirects/index.ts +2 -2
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +4 -4
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +2 -6
- package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +1 -1
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +6 -6
- package/src/astro/routes/api/schema/collections/index.ts +4 -4
- package/src/astro/routes/api/schema/index.ts +1 -1
- package/src/astro/routes/api/schema/orphans/[slug].ts +1 -1
- package/src/astro/routes/api/schema/orphans/index.ts +1 -1
- package/src/astro/routes/api/sections/[slug].ts +3 -3
- package/src/astro/routes/api/sections/index.ts +2 -2
- package/src/astro/routes/sitemap-[collection].xml.ts +114 -14
- package/src/astro/types.ts +18 -0
- package/src/auth/rate-limit.ts +1 -1
- package/src/auth/trusted-proxy.ts +1 -1
- package/src/bylines/index.ts +154 -55
- package/src/cli/commands/init.ts +4 -8
- package/src/client/index.ts +1 -1
- package/src/components/InlinePortableTextEditor.tsx +5 -1
- package/src/components/inline-code-block.tsx +343 -0
- package/src/config/secrets.ts +3 -3
- package/src/content/converters/portable-text-to-prosemirror.ts +35 -11
- package/src/database/connection.ts +3 -10
- package/src/database/errors.ts +14 -0
- package/src/database/index.ts +3 -1
- package/src/database/migrations/006_taxonomy_defs.ts +1 -1
- package/src/database/migrations/014_draft_revisions.ts +6 -6
- package/src/database/migrations/040_byline_i18n.ts +497 -0
- package/src/database/migrations/runner.ts +33 -22
- package/src/database/repositories/audit.ts +2 -2
- package/src/database/repositories/byline.ts +320 -50
- package/src/database/repositories/media.ts +2 -2
- package/src/database/repositories/menu.ts +1 -1
- package/src/database/repositories/options.ts +3 -3
- package/src/database/repositories/plugin-storage.ts +3 -3
- package/src/database/repositories/types.ts +13 -0
- package/src/database/types.ts +15 -0
- package/src/emdash-runtime.ts +493 -20
- package/src/i18n/config.ts +1 -1
- package/src/i18n/resolve.ts +152 -0
- package/src/index.ts +9 -0
- package/src/loader.ts +134 -60
- package/src/mcp/server.ts +3 -3
- package/src/media/mime.ts +1 -1
- package/src/page/absolute-url.ts +1 -1
- package/src/plugin-utils.ts +23 -0
- package/src/plugins/adapt-sandbox-entry.ts +45 -40
- package/src/plugins/email-console.ts +1 -1
- package/src/plugins/index.ts +1 -0
- package/src/plugins/marketplace.ts +1 -1
- package/src/plugins/sandbox/index.ts +1 -0
- package/src/plugins/sandbox/noop.ts +11 -3
- package/src/plugins/sandbox/types.ts +28 -0
- package/src/query.ts +41 -7
- package/src/registry/config.ts +1 -1
- package/src/request-cache.ts +3 -3
- package/src/request-context.ts +1 -1
- package/src/settings/index.ts +4 -4
- package/src/storage/local.ts +1 -1
- package/src/storage/s3.ts +3 -3
- package/src/utils/db-errors.ts +24 -0
- package/src/widgets/index.ts +1 -1
- package/dist/api-BMLZuwM4.mjs.map +0 -1
- package/dist/byline-D09BaS4j.mjs +0 -220
- package/dist/byline-D09BaS4j.mjs.map +0 -1
- package/dist/bylines-BTM2xtP8.mjs +0 -113
- package/dist/bylines-BTM2xtP8.mjs.map +0 -1
- package/dist/bylines-BdUP8NuI.d.mts.map +0 -1
- package/dist/connection-2igzM-AT.mjs +0 -57
- package/dist/connection-2igzM-AT.mjs.map +0 -1
- package/dist/context-qF8d3IPR.mjs.map +0 -1
- package/dist/db-errors-CGN9kJfo.mjs.map +0 -1
- package/dist/email-console-Dmp5Q-P2.mjs.map +0 -1
- package/dist/error-tSQWIl5U.mjs.map +0 -1
- package/dist/index-BV8iJ-6s.d.mts.map +0 -1
- package/dist/loader-Cs6-Bqe6.mjs.map +0 -1
- package/dist/media-Dg7he9uK.mjs.map +0 -1
- package/dist/menus-DOzIecHi.mjs.map +0 -1
- package/dist/menus-X4Z-eBA1.mjs.map +0 -1
- package/dist/oauth-clients-D_B0_-Bz.mjs.map +0 -1
- package/dist/options-Cq64Wx0O.d.mts.map +0 -1
- package/dist/query-axZmO6Tn.mjs.map +0 -1
- package/dist/redirects-Dmj6KRU3.mjs.map +0 -1
- package/dist/runner-DcfZewkO.d.mts.map +0 -1
- package/dist/runner-DdnQIwz_.mjs.map +0 -1
- package/dist/seo-BoR4wCUh.mjs.map +0 -1
- package/dist/settings-xQKsWnzQ.mjs.map +0 -1
- package/dist/taxonomies-Cn9UpaR2.mjs.map +0 -1
- package/dist/types-CwXMEPRr.mjs.map +0 -1
- package/dist/types-CzvJd1ND.d.mts.map +0 -1
- package/dist/version-DNmQakZO.mjs +0 -7
- package/dist/widgets-B9j_yzlk.mjs.map +0 -1
- /package/dist/{api-tokens-D3C9v02m.mjs → api-tokens-iPIHAY8N.mjs} +0 -0
- /package/dist/{ssrf-CTul4uQi.mjs → ssrf-BIcd-aXW.mjs} +0 -0
- /package/dist/{types-Db67HHlU.mjs → types-1NNkmTIn.mjs} +0 -0
package/src/i18n/resolve.ts
CHANGED
|
@@ -35,3 +35,155 @@ export function resolveLocaleChain(explicit?: string): string[] {
|
|
|
35
35
|
if (!isI18nEnabled()) return [locale];
|
|
36
36
|
return getFallbackChain(locale);
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
const REPEATED_SLASHES = /\/{2,}/g;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Interpolate a collection `url_pattern` with a row's slug and id.
|
|
43
|
+
*
|
|
44
|
+
* Falls back to `/{collection}/{slug}` when no pattern is configured.
|
|
45
|
+
* Does NOT apply any locale prefix — pass the result through
|
|
46
|
+
* Astro's `getRelativeLocaleUrl` / `getAbsoluteLocaleUrl` (or the
|
|
47
|
+
* `localizePath` helper below) to add the locale segment.
|
|
48
|
+
*/
|
|
49
|
+
export function interpolateUrlPattern(options: {
|
|
50
|
+
pattern: string | null;
|
|
51
|
+
collection: string;
|
|
52
|
+
slug: string;
|
|
53
|
+
id: string;
|
|
54
|
+
}): string {
|
|
55
|
+
const { pattern, collection, slug, id } = options;
|
|
56
|
+
const basePattern = pattern ?? `/${encodeURIComponent(collection)}/{slug}`;
|
|
57
|
+
let path = basePattern
|
|
58
|
+
.replace("{slug}", encodeURIComponent(slug))
|
|
59
|
+
.replace("{id}", encodeURIComponent(id));
|
|
60
|
+
path = path.replace(REPEATED_SLASHES, "/");
|
|
61
|
+
if (path.length > 1 && path.endsWith("/")) path = path.slice(0, -1);
|
|
62
|
+
if (!path.startsWith("/")) path = `/${path}`;
|
|
63
|
+
return path;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Apply a locale prefix to a path, honouring the user's Astro `i18n`
|
|
68
|
+
* routing config (`prefixDefaultLocale`, custom `path`/`codes` mappings).
|
|
69
|
+
*
|
|
70
|
+
* Reads the resolved config from `astro:config/server`, which is always
|
|
71
|
+
* available regardless of whether i18n is enabled -- so this function
|
|
72
|
+
* works in both i18n and non-i18n builds without tripping Astro's
|
|
73
|
+
* `i18nNotEnabled` resolver (the case with importing `astro:i18n`).
|
|
74
|
+
*
|
|
75
|
+
* Returns:
|
|
76
|
+
* - The original `path` when i18n is not configured.
|
|
77
|
+
* - The original `path` for the default locale when
|
|
78
|
+
* `prefixDefaultLocale` is false.
|
|
79
|
+
* - `/{segment}{path}` for any other configured locale, where
|
|
80
|
+
* `{segment}` is the locale's custom `path` if one is set,
|
|
81
|
+
* otherwise the locale code.
|
|
82
|
+
* - `null` when the row's locale isn't in the configured list.
|
|
83
|
+
* Callers should drop the entry: a sitemap link to a route the
|
|
84
|
+
* site can't serve is worse than no link at all (search engines
|
|
85
|
+
* get a 404 / soft-404 and downrank the page).
|
|
86
|
+
*
|
|
87
|
+
* Falls back to `getI18nConfig()` (EmDash's mirror of the same config,
|
|
88
|
+
* populated at runtime startup) when `astro:config/server` is
|
|
89
|
+
* unavailable -- e.g. running outside an Astro build context, such as
|
|
90
|
+
* in vitest.
|
|
91
|
+
*/
|
|
92
|
+
export async function localizePath(path: string, locale: string): Promise<string | null> {
|
|
93
|
+
const segment = await resolveLocaleSegment(locale);
|
|
94
|
+
if (segment === undefined) return null;
|
|
95
|
+
if (segment === null || segment === "") return normalizePath(path);
|
|
96
|
+
return normalizePath(`/${segment}${path}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Resolve the URL segment to use for a locale.
|
|
101
|
+
*
|
|
102
|
+
* Returns:
|
|
103
|
+
* - `null` when i18n isn't configured (caller should not prefix).
|
|
104
|
+
* - `""` when the locale is the default locale and
|
|
105
|
+
* `prefixDefaultLocale` is false (caller should not prefix).
|
|
106
|
+
* - The locale's custom `path` value, or the locale string itself.
|
|
107
|
+
* - `undefined` when the locale isn't in the configured list --
|
|
108
|
+
* the row points at a route the site can't serve.
|
|
109
|
+
*/
|
|
110
|
+
async function resolveLocaleSegment(locale: string): Promise<string | null | undefined> {
|
|
111
|
+
const i18n = await readAstroI18nConfig();
|
|
112
|
+
if (!i18n || !i18n.locales || i18n.locales.length <= 1) return null;
|
|
113
|
+
|
|
114
|
+
const isDefault = locale === i18n.defaultLocale;
|
|
115
|
+
if (isDefault && !i18n.prefixDefaultLocale) return "";
|
|
116
|
+
|
|
117
|
+
// When the locale has a custom `path`/`codes` mapping, use the path
|
|
118
|
+
// for the URL segment. Otherwise use the locale code directly.
|
|
119
|
+
for (const entry of i18n.locales) {
|
|
120
|
+
if (typeof entry === "string") {
|
|
121
|
+
if (entry === locale) return entry;
|
|
122
|
+
} else if (entry.codes.includes(locale)) {
|
|
123
|
+
return entry.path;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
interface AstroI18nConfig {
|
|
131
|
+
defaultLocale: string;
|
|
132
|
+
locales: Array<string | { codes: readonly string[]; path: string }>;
|
|
133
|
+
prefixDefaultLocale?: boolean;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let astroI18nCache: AstroI18nConfig | null | undefined;
|
|
137
|
+
|
|
138
|
+
async function readAstroI18nConfig(): Promise<AstroI18nConfig | null> {
|
|
139
|
+
if (astroI18nCache !== undefined) return astroI18nCache;
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const mod = (await import("astro:config/server")) as {
|
|
143
|
+
i18n?: {
|
|
144
|
+
defaultLocale: string;
|
|
145
|
+
locales: Array<string | { codes: readonly string[]; path: string }>;
|
|
146
|
+
routing?: { prefixDefaultLocale?: boolean } | string;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
if (!mod.i18n) {
|
|
150
|
+
astroI18nCache = null;
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const routing = mod.i18n.routing;
|
|
154
|
+
astroI18nCache = {
|
|
155
|
+
defaultLocale: mod.i18n.defaultLocale,
|
|
156
|
+
locales: mod.i18n.locales,
|
|
157
|
+
prefixDefaultLocale:
|
|
158
|
+
typeof routing === "object" ? (routing.prefixDefaultLocale ?? false) : false,
|
|
159
|
+
};
|
|
160
|
+
return astroI18nCache;
|
|
161
|
+
} catch {
|
|
162
|
+
// `astro:config/server` isn't resolvable (e.g. running under vitest
|
|
163
|
+
// outside an Astro build). Fall back to EmDash's runtime config,
|
|
164
|
+
// which is populated at startup via the same astroConfig object.
|
|
165
|
+
const cfg = getI18nConfig();
|
|
166
|
+
if (!cfg || !isI18nEnabled()) {
|
|
167
|
+
astroI18nCache = null;
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
astroI18nCache = {
|
|
171
|
+
defaultLocale: cfg.defaultLocale,
|
|
172
|
+
locales: cfg.locales,
|
|
173
|
+
prefixDefaultLocale: cfg.prefixDefaultLocale,
|
|
174
|
+
};
|
|
175
|
+
return astroI18nCache;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** @internal -- exposed for tests to reset the module-level cache. */
|
|
180
|
+
export function _resetAstroI18nCacheForTests(): void {
|
|
181
|
+
astroI18nCache = undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function normalizePath(path: string): string {
|
|
185
|
+
let p = path.replace(REPEATED_SLASHES, "/");
|
|
186
|
+
if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
|
|
187
|
+
if (!p.startsWith("/")) p = `/${p}`;
|
|
188
|
+
return p;
|
|
189
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,9 @@ export type {
|
|
|
12
12
|
export {
|
|
13
13
|
ContentRepository,
|
|
14
14
|
MediaRepository,
|
|
15
|
+
PluginStorageRepository,
|
|
16
|
+
UserRepository,
|
|
17
|
+
OptionsRepository,
|
|
15
18
|
EmDashValidationError,
|
|
16
19
|
InvalidCursorError,
|
|
17
20
|
} from "./database/repositories/index.js";
|
|
@@ -125,6 +128,8 @@ export type {
|
|
|
125
128
|
ResolvePathResult,
|
|
126
129
|
TranslationSummary,
|
|
127
130
|
TranslationsResult,
|
|
131
|
+
WhereRange,
|
|
132
|
+
WhereValue,
|
|
128
133
|
} from "./query.js";
|
|
129
134
|
|
|
130
135
|
// Request context (ALS-based ambient state for query functions)
|
|
@@ -198,7 +203,11 @@ export {
|
|
|
198
203
|
// Sandbox
|
|
199
204
|
NoopSandboxRunner,
|
|
200
205
|
SandboxNotAvailableError,
|
|
206
|
+
SandboxUnavailableError,
|
|
201
207
|
createNoopSandboxRunner,
|
|
208
|
+
// HTTP access for plugins (shared between in-process, Cloudflare, and workerd runners)
|
|
209
|
+
createHttpAccess,
|
|
210
|
+
createUnrestrictedHttpAccess,
|
|
202
211
|
} from "./plugins/index.js";
|
|
203
212
|
export type {
|
|
204
213
|
PluginDefinition,
|
package/src/loader.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { decodeCursor, encodeCursor } from "./database/repositories/types.js";
|
|
|
20
20
|
import { validateIdentifier } from "./database/validate.js";
|
|
21
21
|
import type { Database } from "./index.js";
|
|
22
22
|
import { getRequestContext } from "./request-context.js";
|
|
23
|
-
import { isMissingTableError } from "./utils/db-errors.js";
|
|
23
|
+
import { isMissingColumnError, isMissingTableError } from "./utils/db-errors.js";
|
|
24
24
|
|
|
25
25
|
const FIELD_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
26
26
|
|
|
@@ -311,10 +311,12 @@ function buildStatusCondition(
|
|
|
311
311
|
const scheduledAtExpr = isPostgres(db)
|
|
312
312
|
? sql`${sql.ref(scheduledAtField)}::timestamptz`
|
|
313
313
|
: sql.ref(scheduledAtField);
|
|
314
|
-
|
|
314
|
+
const nowExpr = isPostgres(db)
|
|
315
|
+
? currentTimestampValue(db)
|
|
316
|
+
: sql`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
|
|
317
|
+
return sql`(${sql.ref(statusField)} = 'published' OR (${sql.ref(statusField)} = 'scheduled' AND ${scheduledAtExpr} <= ${nowExpr}))`;
|
|
315
318
|
}
|
|
316
319
|
|
|
317
|
-
// For other statuses (draft, archived), just match exactly
|
|
318
320
|
return sql`${sql.ref(statusField)} = ${status}`;
|
|
319
321
|
}
|
|
320
322
|
|
|
@@ -408,6 +410,65 @@ function buildCursorCondition(
|
|
|
408
410
|
return sql`(${sql.ref(primary.field)} > ${orderValue} OR (${sql.ref(primary.field)} = ${orderValue} AND ${sql.ref(idField)} > ${cursorId}))`;
|
|
409
411
|
}
|
|
410
412
|
|
|
413
|
+
/** Type guard: is the where value a range object (not a string or array)? */
|
|
414
|
+
function isWhereRange(value: WhereValue): value is WhereRange {
|
|
415
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Build AND conditions for non-taxonomy field filters.
|
|
420
|
+
* Returns an array of sql fragments; empty if no field filters apply.
|
|
421
|
+
* Field names are validated against FIELD_NAME_PATTERN to prevent injection.
|
|
422
|
+
*/
|
|
423
|
+
function buildFieldConditions(
|
|
424
|
+
fields: Record<string, WhereValue>,
|
|
425
|
+
tablePrefix?: string,
|
|
426
|
+
): ReturnType<typeof sql>[] {
|
|
427
|
+
const conditions: ReturnType<typeof sql>[] = [];
|
|
428
|
+
|
|
429
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
430
|
+
if (!FIELD_NAME_PATTERN.test(key)) {
|
|
431
|
+
console.warn(`[emdash] where filter: invalid field name "${key}" ignored`);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (value == null) continue;
|
|
435
|
+
const ref = tablePrefix ? sql.ref(`${tablePrefix}.${key}`) : sql.ref(key);
|
|
436
|
+
|
|
437
|
+
if (isWhereRange(value)) {
|
|
438
|
+
if (value.gt !== undefined) conditions.push(sql`${ref} > ${value.gt}`);
|
|
439
|
+
if (value.gte !== undefined) conditions.push(sql`${ref} >= ${value.gte}`);
|
|
440
|
+
if (value.lt !== undefined) conditions.push(sql`${ref} < ${value.lt}`);
|
|
441
|
+
if (value.lte !== undefined) conditions.push(sql`${ref} <= ${value.lte}`);
|
|
442
|
+
} else if (Array.isArray(value)) {
|
|
443
|
+
if (value.length > 0) {
|
|
444
|
+
conditions.push(sql`${ref} IN (${sql.join(value.map((v) => sql`${v}`))})`);
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
conditions.push(sql`${ref} = ${value}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return conditions;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Range filter for comparison operators on field values.
|
|
456
|
+
* Values are compared as strings in the database. This works correctly for
|
|
457
|
+
* ISO 8601 dates (e.g. "2024-01-01T00:00:00Z") because lexicographic ordering
|
|
458
|
+
* matches chronological ordering. Ensure date values use a consistent format.
|
|
459
|
+
*/
|
|
460
|
+
export interface WhereRange {
|
|
461
|
+
gt?: string;
|
|
462
|
+
gte?: string;
|
|
463
|
+
lt?: string;
|
|
464
|
+
lte?: string;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* A where clause value: exact match, multi-value match, or range comparison.
|
|
469
|
+
*/
|
|
470
|
+
export type WhereValue = string | string[] | WhereRange;
|
|
471
|
+
|
|
411
472
|
/**
|
|
412
473
|
* Filter for loadCollection - type is required
|
|
413
474
|
*/
|
|
@@ -421,9 +482,16 @@ export interface CollectionFilter {
|
|
|
421
482
|
*/
|
|
422
483
|
cursor?: string;
|
|
423
484
|
/**
|
|
424
|
-
* Filter by field values
|
|
485
|
+
* Filter by field values, taxonomy terms, or ranges.
|
|
486
|
+
*
|
|
487
|
+
* Taxonomy names are detected automatically and filtered via JOIN.
|
|
488
|
+
* Other keys are treated as column filters on the content table.
|
|
489
|
+
*
|
|
490
|
+
* @example { category: 'news' } - taxonomy term
|
|
491
|
+
* @example { series: 'main' } - exact match on a content field
|
|
492
|
+
* @example { published_at: { gte: '2024-01-01', lt: '2025-01-01' } } - date range
|
|
425
493
|
*/
|
|
426
|
-
where?: Record<string,
|
|
494
|
+
where?: Record<string, WhereValue>;
|
|
427
495
|
/**
|
|
428
496
|
* Order results by field(s)
|
|
429
497
|
* @default { created_at: "desc" }
|
|
@@ -471,7 +539,7 @@ export async function getDb(): Promise<Kysely<Database>> {
|
|
|
471
539
|
// Per-request DB override via ALS (normal mode)
|
|
472
540
|
const ctx = getRequestContext();
|
|
473
541
|
if (ctx?.db) {
|
|
474
|
-
return ctx.db as Kysely<Database>; // eslint-disable-line typescript
|
|
542
|
+
return ctx.db as Kysely<Database>; // eslint-disable-line typescript/no-unsafe-type-assertion -- db is typed as unknown in RequestContext to avoid circular deps
|
|
475
543
|
}
|
|
476
544
|
|
|
477
545
|
if (!dbInstance) {
|
|
@@ -551,79 +619,81 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
551
619
|
? buildCursorCondition(cursor, orderBy, tableName)
|
|
552
620
|
: null;
|
|
553
621
|
|
|
554
|
-
//
|
|
622
|
+
// Separate taxonomy filters from field filters
|
|
555
623
|
let result: { rows: Record<string, unknown>[] };
|
|
624
|
+
let taxonomyFilter: { name: string; slugs: string[] } | null = null;
|
|
625
|
+
const fieldFilters: Record<string, WhereValue> = {};
|
|
556
626
|
|
|
557
627
|
if (where && Object.keys(where).length > 0) {
|
|
558
|
-
// Get taxonomy names to detect taxonomy filters
|
|
559
628
|
const taxNames = await getTaxonomyNames(db);
|
|
560
|
-
const taxonomyFilters: Record<string, string | string[]> = {};
|
|
561
629
|
|
|
562
630
|
for (const [key, value] of Object.entries(where)) {
|
|
631
|
+
if (value == null) continue;
|
|
563
632
|
if (taxNames.has(key)) {
|
|
564
|
-
|
|
633
|
+
if (isWhereRange(value)) {
|
|
634
|
+
console.warn(
|
|
635
|
+
`[emdash] where filter: range operators are not supported on taxonomy "${key}", ignored`,
|
|
636
|
+
);
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
if (taxonomyFilter) {
|
|
640
|
+
console.warn(
|
|
641
|
+
`[emdash] where filter: only one taxonomy is supported per query, "${key}" ignored`,
|
|
642
|
+
);
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
const slugs = Array.isArray(value) ? value : [value];
|
|
646
|
+
taxonomyFilter = { name: key, slugs };
|
|
647
|
+
} else {
|
|
648
|
+
fieldFilters[key] = value;
|
|
565
649
|
}
|
|
566
650
|
}
|
|
651
|
+
}
|
|
567
652
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
AND ct.entry_id = ${sql.ref(tableName)}.id
|
|
588
|
-
INNER JOIN taxonomies t
|
|
589
|
-
ON t.id = ct.taxonomy_id
|
|
590
|
-
WHERE ${sql.ref(tableName)}.deleted_at IS NULL
|
|
591
|
-
AND ${statusCondition}
|
|
592
|
-
${localeCondition}
|
|
593
|
-
${cursorCond}
|
|
594
|
-
AND t.name = ${taxName}
|
|
595
|
-
AND t.slug IN (${sql.join(slugs.map((s) => sql`${s}`))})
|
|
596
|
-
${orderByClause}
|
|
597
|
-
${fetchLimit ? sql`LIMIT ${fetchLimit}` : sql``}
|
|
598
|
-
`.execute(db);
|
|
599
|
-
} else {
|
|
600
|
-
// No taxonomy filters, use simple query
|
|
601
|
-
const orderByClause = buildOrderByClause(orderBy);
|
|
602
|
-
const statusCondition = buildStatusCondition(db, status);
|
|
603
|
-
const localeFilter = locale ? sql`AND locale = ${locale}` : sql``;
|
|
604
|
-
const cursorCond = cursorCondition ? sql`AND ${cursorCondition}` : sql``;
|
|
605
|
-
result = await sql<Record<string, unknown>>`
|
|
606
|
-
SELECT * FROM ${sql.ref(tableName)}
|
|
607
|
-
WHERE deleted_at IS NULL
|
|
653
|
+
if (taxonomyFilter) {
|
|
654
|
+
const orderByClause = buildOrderByClause(orderBy, tableName);
|
|
655
|
+
const statusCondition = buildStatusCondition(db, status, tableName);
|
|
656
|
+
const localeCondition = locale
|
|
657
|
+
? sql`AND ${sql.ref(tableName)}.locale = ${locale}`
|
|
658
|
+
: sql``;
|
|
659
|
+
const cursorCond = cursorConditionPrefixed ? sql`AND ${cursorConditionPrefixed}` : sql``;
|
|
660
|
+
const fieldConds = buildFieldConditions(fieldFilters, tableName);
|
|
661
|
+
const fieldCondsSQL =
|
|
662
|
+
fieldConds.length > 0 ? sql`${sql.join(fieldConds, sql` AND `)}` : null;
|
|
663
|
+
|
|
664
|
+
result = await sql<Record<string, unknown>>`
|
|
665
|
+
SELECT DISTINCT ${sql.ref(tableName)}.* FROM ${sql.ref(tableName)}
|
|
666
|
+
INNER JOIN content_taxonomies ct
|
|
667
|
+
ON ct.collection = ${type}
|
|
668
|
+
AND ct.entry_id = ${sql.ref(tableName)}.id
|
|
669
|
+
INNER JOIN taxonomies t
|
|
670
|
+
ON t.id = ct.taxonomy_id
|
|
671
|
+
WHERE ${sql.ref(tableName)}.deleted_at IS NULL
|
|
608
672
|
AND ${statusCondition}
|
|
609
|
-
${
|
|
673
|
+
${localeCondition}
|
|
610
674
|
${cursorCond}
|
|
611
|
-
${
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
675
|
+
AND t.name = ${taxonomyFilter.name}
|
|
676
|
+
AND t.slug IN (${sql.join(taxonomyFilter.slugs.map((s) => sql`${s}`))})
|
|
677
|
+
${fieldCondsSQL ? sql`AND ${fieldCondsSQL}` : sql``}
|
|
678
|
+
${orderByClause}
|
|
679
|
+
${fetchLimit ? sql`LIMIT ${fetchLimit}` : sql``}
|
|
680
|
+
`.execute(db);
|
|
615
681
|
} else {
|
|
616
|
-
// No where clause, use simple query
|
|
617
682
|
const orderByClause = buildOrderByClause(orderBy);
|
|
618
683
|
const statusCondition = buildStatusCondition(db, status);
|
|
619
684
|
const localeFilter = locale ? sql`AND locale = ${locale}` : sql``;
|
|
620
685
|
const cursorCond = cursorCondition ? sql`AND ${cursorCondition}` : sql``;
|
|
686
|
+
const fieldConds = buildFieldConditions(fieldFilters);
|
|
687
|
+
const fieldCondsSQL =
|
|
688
|
+
fieldConds.length > 0 ? sql`${sql.join(fieldConds, sql` AND `)}` : null;
|
|
689
|
+
|
|
621
690
|
result = await sql<Record<string, unknown>>`
|
|
622
691
|
SELECT * FROM ${sql.ref(tableName)}
|
|
623
692
|
WHERE deleted_at IS NULL
|
|
624
693
|
AND ${statusCondition}
|
|
625
694
|
${localeFilter}
|
|
626
695
|
${cursorCond}
|
|
696
|
+
${fieldCondsSQL ? sql`AND ${fieldCondsSQL}` : sql``}
|
|
627
697
|
${orderByClause}
|
|
628
698
|
${fetchLimit ? sql`LIMIT ${fetchLimit}` : sql``}
|
|
629
699
|
`.execute(db);
|
|
@@ -693,13 +763,17 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
693
763
|
},
|
|
694
764
|
};
|
|
695
765
|
} catch (error) {
|
|
696
|
-
// Handle missing table gracefully - return empty collection.
|
|
697
|
-
//
|
|
698
|
-
|
|
766
|
+
// Handle missing table/column gracefully - return empty collection.
|
|
767
|
+
// Missing table happens before migrations have run.
|
|
768
|
+
// Missing column happens when a where filter references a non-existent field.
|
|
769
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
770
|
+
if (isMissingTableError(error) || isMissingColumnError(error)) {
|
|
771
|
+
if (isMissingColumnError(error)) {
|
|
772
|
+
console.warn(`[emdash] where filter: ${message}`);
|
|
773
|
+
}
|
|
699
774
|
return { entries: [] };
|
|
700
775
|
}
|
|
701
776
|
|
|
702
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
703
777
|
return {
|
|
704
778
|
error: new Error(`Failed to load collection: ${message}`),
|
|
705
779
|
};
|
package/src/mcp/server.ts
CHANGED
|
@@ -511,12 +511,12 @@ export function createMcpServer(): McpServer {
|
|
|
511
511
|
if (result.success && !canReadDrafts(extra)) {
|
|
512
512
|
const data =
|
|
513
513
|
result.data && typeof result.data === "object"
|
|
514
|
-
? // eslint-disable-next-line typescript
|
|
514
|
+
? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check
|
|
515
515
|
(result.data as Record<string, unknown>)
|
|
516
516
|
: undefined;
|
|
517
517
|
const item =
|
|
518
518
|
data?.item && typeof data.item === "object"
|
|
519
|
-
? // eslint-disable-next-line typescript
|
|
519
|
+
? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check
|
|
520
520
|
(data.item as Record<string, unknown>)
|
|
521
521
|
: undefined;
|
|
522
522
|
const status = typeof item?.status === "string" ? item.status : null;
|
|
@@ -1140,7 +1140,7 @@ export function createMcpServer(): McpServer {
|
|
|
1140
1140
|
if (result.success && !canReadDrafts(extra)) {
|
|
1141
1141
|
const data =
|
|
1142
1142
|
result.data && typeof result.data === "object"
|
|
1143
|
-
? // eslint-disable-next-line typescript
|
|
1143
|
+
? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check
|
|
1144
1144
|
(result.data as Record<string, unknown>)
|
|
1145
1145
|
: undefined;
|
|
1146
1146
|
const translations = Array.isArray(data?.translations) ? data.translations : [];
|
package/src/media/mime.ts
CHANGED
package/src/page/absolute-url.ts
CHANGED
|
@@ -44,7 +44,7 @@ const OTHER_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
44
44
|
* exploitable, plus more pathological shapes like leading newlines that
|
|
45
45
|
* could inject across header boundaries downstream.
|
|
46
46
|
*/
|
|
47
|
-
// eslint-disable-next-line
|
|
47
|
+
// eslint-disable-next-line no-control-regex -- intentional: rejecting control chars is the whole point of this regex
|
|
48
48
|
const WHITESPACE_OR_CONTROL_RE = /[\s\u0000-\u001f\u007f-\u009f]/;
|
|
49
49
|
const TRAILING_SLASH_RE = /\/$/;
|
|
50
50
|
|
package/src/plugin-utils.ts
CHANGED
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
* Import as: `import { apiFetch, parseApiResponse, isRecord } from "emdash/plugin-utils";`
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type { EmDashHandlers } from "./astro/types.js";
|
|
12
|
+
|
|
13
|
+
export type PublicPluginApiRouteHandler = EmDashHandlers["handlePublicPluginApiRoute"];
|
|
14
|
+
|
|
15
|
+
export interface PublicPluginRuntimeLocals {
|
|
16
|
+
emdash?: {
|
|
17
|
+
handlePublicPluginApiRoute?: PublicPluginApiRouteHandler;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
/**
|
|
12
22
|
* Fetch wrapper that adds the `X-EmDash-Request` CSRF protection header.
|
|
13
23
|
*
|
|
@@ -20,6 +30,19 @@ export function apiFetch(input: string | URL | Request, init?: RequestInit): Pro
|
|
|
20
30
|
return fetch(input, { ...init, headers });
|
|
21
31
|
}
|
|
22
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Get the public-only plugin route dispatcher exposed to SSR page components.
|
|
35
|
+
*
|
|
36
|
+
* This intentionally reads `handlePublicPluginApiRoute`, not the raw
|
|
37
|
+
* `handlePluginApiRoute` used by core's authenticated plugin API route.
|
|
38
|
+
*/
|
|
39
|
+
export function getPublicPluginApiRouteHandler(
|
|
40
|
+
locals: PublicPluginRuntimeLocals | null | undefined,
|
|
41
|
+
): PublicPluginApiRouteHandler | undefined {
|
|
42
|
+
const handler = locals?.emdash?.handlePublicPluginApiRoute;
|
|
43
|
+
return typeof handler === "function" ? handler : undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
23
46
|
/**
|
|
24
47
|
* Parse an API response, unwrapping the `{ data: T }` envelope.
|
|
25
48
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { PluginDescriptor } from "../astro/integration/runtime.js";
|
|
14
|
-
import type { SandboxedPlugin } from "../plugin-types.js";
|
|
14
|
+
import type { RouteEntry, RouteHandler, SandboxedPlugin } from "../plugin-types.js";
|
|
15
15
|
import { PLUGIN_CAPABILITIES, HOOK_NAMES } from "./manifest-schema.js";
|
|
16
16
|
import { normalizeCapabilities } from "./types.js";
|
|
17
17
|
import type {
|
|
@@ -96,6 +96,31 @@ function resolveSandboxedHook(entry: AnyHookEntry, pluginId: string): ResolvedHo
|
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Normalise a `RouteEntry` (bare handler or `{ handler, public?, input? }`
|
|
101
|
+
* config) to the config form. The `input` schema is intentionally typed
|
|
102
|
+
* `unknown` in `RouteEntry` — sandboxed plugins describe it loosely
|
|
103
|
+
* because the strict `z.ZodType<TInput>` constraint of the runtime's
|
|
104
|
+
* `PluginRoute` only narrows once the route is wired into the router.
|
|
105
|
+
* The wider type flows through to the runtime which validates at
|
|
106
|
+
* invocation time.
|
|
107
|
+
*/
|
|
108
|
+
function normalizeRouteEntry(entry: RouteEntry): {
|
|
109
|
+
handler: RouteHandler;
|
|
110
|
+
public?: boolean;
|
|
111
|
+
input?: PluginRoute["input"];
|
|
112
|
+
} {
|
|
113
|
+
if (typeof entry === "function") {
|
|
114
|
+
return { handler: entry };
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
handler: entry.handler,
|
|
118
|
+
public: entry.public,
|
|
119
|
+
// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- RouteEntry.input is intentionally `unknown` (sandboxed plugins) and validated by the runtime at invocation time
|
|
120
|
+
input: entry.input as PluginRoute["input"],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
99
124
|
const VALID_CAPABILITIES_SET = new Set<string>(PLUGIN_CAPABILITIES);
|
|
100
125
|
|
|
101
126
|
const VALID_HOOK_NAMES_SET = new Set<string>(HOOK_NAMES);
|
|
@@ -136,9 +161,13 @@ export function adaptSandboxEntry(
|
|
|
136
161
|
// Resolve hooks. `SandboxedPlugin.hooks` is keyed by hook name with
|
|
137
162
|
// per-key entry types; iterating with `Object.entries` collapses
|
|
138
163
|
// keys to `string`, so we treat each entry as the union `AnyHookEntry`
|
|
139
|
-
// for the duration of the loop.
|
|
164
|
+
// for the duration of the loop. The widening from the strict mapped
|
|
165
|
+
// type to a plain record is sound because each entry still matches
|
|
166
|
+
// one of the bare-handler / config-object shapes captured by
|
|
167
|
+
// `AnyHookEntry`.
|
|
140
168
|
const resolvedHooks: ResolvedPluginHooks = {};
|
|
141
169
|
if (definition.hooks) {
|
|
170
|
+
// eslint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- widening the strict mapped type to a string-keyed record for iteration; entries still match AnyHookEntry
|
|
142
171
|
const hookMap = definition.hooks as Record<string, AnyHookEntry>;
|
|
143
172
|
for (const [hookName, entry] of Object.entries(hookMap)) {
|
|
144
173
|
if (!VALID_HOOK_NAMES_SET.has(hookName)) {
|
|
@@ -166,49 +195,25 @@ export function adaptSandboxEntry(
|
|
|
166
195
|
const resolvedRoutes: Record<string, PluginRoute> = {};
|
|
167
196
|
if (definition.routes) {
|
|
168
197
|
for (const [routeName, rawEntry] of Object.entries(definition.routes)) {
|
|
169
|
-
const
|
|
170
|
-
const handler =
|
|
171
|
-
? (rawEntry as { handler: (...args: unknown[]) => Promise<unknown> }).handler
|
|
172
|
-
: (rawEntry as (...args: unknown[]) => Promise<unknown>);
|
|
173
|
-
const publicFlag = isConfig ? (rawEntry as { public?: boolean }).public : undefined;
|
|
174
|
-
const inputSchema = isConfig ? (rawEntry as { input?: unknown }).input : undefined;
|
|
198
|
+
const normalized = normalizeRouteEntry(rawEntry);
|
|
199
|
+
const { handler, public: publicFlag, input: inputSchema } = normalized;
|
|
175
200
|
resolvedRoutes[routeName] = {
|
|
176
|
-
|
|
177
|
-
input: inputSchema as PluginRoute["input"],
|
|
201
|
+
input: inputSchema,
|
|
178
202
|
public: publicFlag,
|
|
179
203
|
handler: async (ctx) => {
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
// `
|
|
183
|
-
// `Record<string, string>`
|
|
184
|
-
//
|
|
185
|
-
//
|
|
204
|
+
// `ctx.request` is a real WHATWG `Request` (this is the
|
|
205
|
+
// in-process adapter; the worker-sandbox adapter handles
|
|
206
|
+
// the serialised case). Flatten `Headers` to the plain
|
|
207
|
+
// `Record<string, string>` shape that author-facing
|
|
208
|
+
// `SandboxedRequest` promises so handler bodies are
|
|
209
|
+
// identical across both adapters.
|
|
186
210
|
const headers: Record<string, string> = {};
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (typeof (h as Headers).forEach === "function") {
|
|
191
|
-
(h as Headers).forEach((value, name) => {
|
|
192
|
-
headers[name] = value;
|
|
193
|
-
});
|
|
194
|
-
} else {
|
|
195
|
-
for (const [name, value] of Object.entries(h as Record<string, string>)) {
|
|
196
|
-
headers[name] = value;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
211
|
+
ctx.request.headers.forEach((value, name) => {
|
|
212
|
+
headers[name] = value;
|
|
213
|
+
});
|
|
201
214
|
const requestShape = {
|
|
202
|
-
url:
|
|
203
|
-
|
|
204
|
-
typeof (ctx.request as { url: unknown }).url === "string"
|
|
205
|
-
? (ctx.request as { url: string }).url
|
|
206
|
-
: "",
|
|
207
|
-
method:
|
|
208
|
-
(ctx.request as { method?: unknown } | undefined)?.method &&
|
|
209
|
-
typeof (ctx.request as { method: unknown }).method === "string"
|
|
210
|
-
? (ctx.request as { method: string }).method
|
|
211
|
-
: "GET",
|
|
215
|
+
url: ctx.request.url,
|
|
216
|
+
method: ctx.request.method,
|
|
212
217
|
headers,
|
|
213
218
|
};
|
|
214
219
|
const routeCtx = {
|
|
@@ -33,7 +33,7 @@ export interface StoredEmail {
|
|
|
33
33
|
const GLOBAL_KEY = Symbol.for("emdash:dev-emails");
|
|
34
34
|
const g = globalThis as Record<symbol, unknown>;
|
|
35
35
|
const storedEmails: StoredEmail[] = (() => {
|
|
36
|
-
// eslint-disable-next-line typescript
|
|
36
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)
|
|
37
37
|
const existing = g[GLOBAL_KEY] as StoredEmail[] | undefined;
|
|
38
38
|
if (existing) return existing;
|
|
39
39
|
const fresh: StoredEmail[] = [];
|