emdash 0.18.0 → 0.19.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/api/route-utils.d.mts +2 -2
- package/dist/api/route-utils.mjs +14 -14
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +3 -3
- package/dist/{api-Cs7DAACP.mjs → api-BZ6bhjYs.mjs} +88 -16
- package/dist/api-BZ6bhjYs.mjs.map +1 -0
- package/dist/{apply-BWMV4Zmw.mjs → apply-hQkKKBCf.mjs} +23 -23
- package/dist/apply-hQkKKBCf.mjs.map +1 -0
- package/dist/astro/index.d.mts +8 -8
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +113 -23
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +7 -7
- package/dist/astro/middleware/auth.mjs +2 -2
- package/dist/astro/middleware/redirect.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs +2 -2
- package/dist/astro/middleware.d.mts +26 -4
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +205 -173
- 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 +2 -2
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +3 -3
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
- 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 +12 -12
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +12 -12
- package/dist/astro/routes/api/admin/bylines/index.mjs +12 -12
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +11 -11
- 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 +5 -5
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +31 -31
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +31 -31
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/index.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +31 -31
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +30 -30
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +31 -31
- package/dist/astro/routes/api/admin/plugins/updates.mjs +30 -30
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +30 -30
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +30 -30
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -3
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +6 -6
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +4 -4
- package/dist/astro/routes/api/admin/users/index.mjs +5 -5
- package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/complete.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/index.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/register-options.mjs +6 -6
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +6 -6
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +2 -2
- 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 +7 -7
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +6 -6
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +6 -6
- package/dist/astro/routes/api/auth/passkey/verify.mjs +6 -6
- package/dist/astro/routes/api/auth/signup/complete.mjs +6 -6
- 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 +6 -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 +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +9 -8
- 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_/revisions.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +12 -10
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +9 -8
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.d.mts +8 -0
- package/dist/astro/routes/api/content/_collection_/authors.d.mts.map +1 -0
- package/dist/astro/routes/api/content/_collection_/authors.mjs +19 -0
- package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -0
- 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 +2 -2
- package/dist/astro/routes/api/import/probe.d.mts +2 -2
- package/dist/astro/routes/api/import/probe.mjs +6 -6
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +7 -7
- package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/media.mjs +6 -6
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -9
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +6 -6
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +9 -9
- package/dist/astro/routes/api/manifest.mjs +3 -3
- package/dist/astro/routes/api/mcp.mjs +28 -28
- 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 +6 -6
- package/dist/astro/routes/api/media.mjs +7 -7
- 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 +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +4 -4
- package/dist/astro/routes/api/oauth/device/code.mjs +5 -5
- package/dist/astro/routes/api/oauth/device/token.mjs +5 -5
- package/dist/astro/routes/api/oauth/register.mjs +2 -2
- package/dist/astro/routes/api/oauth/token/refresh.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/revoke.mjs +4 -4
- package/dist/astro/routes/api/oauth/token.mjs +4 -4
- package/dist/astro/routes/api/openapi.json.mjs +17 -3
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/index.mjs +9 -9
- package/dist/astro/routes/api/redirects/404s/summary.mjs +9 -9
- package/dist/astro/routes/api/redirects/_id_.mjs +10 -10
- package/dist/astro/routes/api/redirects/index.mjs +10 -10
- 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 +30 -30
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +30 -30
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +30 -30
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +30 -30
- package/dist/astro/routes/api/schema/collections/index.mjs +30 -30
- package/dist/astro/routes/api/schema/index.mjs +6 -6
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +30 -30
- package/dist/astro/routes/api/schema/orphans/index.mjs +30 -30
- 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/index.mjs +8 -8
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +12 -12
- package/dist/astro/routes/api/setup/admin-verify.mjs +6 -6
- package/dist/astro/routes/api/setup/admin.mjs +6 -6
- package/dist/astro/routes/api/setup/dev-bypass.mjs +18 -18
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +21 -21
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +5 -5
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -11
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -11
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -11
- package/dist/astro/routes/api/taxonomies/index.mjs +11 -11
- 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/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 +2 -2
- package/dist/astro/routes/robots.txt.mjs +6 -6
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +6 -6
- package/dist/astro/routes/sitemap.xml.mjs +6 -6
- package/dist/astro/types.d.mts +15 -8
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{authorize-CotM4Yiu.mjs → authorize-C_8t2KGa.mjs} +2 -2
- package/dist/{authorize-CotM4Yiu.mjs.map → authorize-C_8t2KGa.mjs.map} +1 -1
- package/dist/{byline-CWQ9aSoz.mjs → byline-DUx48sJp.mjs} +6 -6
- package/dist/{byline-CWQ9aSoz.mjs.map → byline-DUx48sJp.mjs.map} +1 -1
- package/dist/{byline-fields-Dr-xcb6S.mjs → byline-fields-51kg6Vuv.mjs} +3 -3
- package/dist/{byline-fields-Dr-xcb6S.mjs.map → byline-fields-51kg6Vuv.mjs.map} +1 -1
- package/dist/{byline-fields-DC3Wkk-U.mjs → byline-fields-C_OsR-KF.mjs} +2 -2
- package/dist/{byline-fields-DC3Wkk-U.mjs.map → byline-fields-C_OsR-KF.mjs.map} +1 -1
- package/dist/{byline-fields-BNy7Ng1U.d.mts → byline-fields-DYXKDuNX.d.mts} +26 -2
- package/dist/byline-fields-DYXKDuNX.d.mts.map +1 -0
- package/dist/{byline-registry-CxK5g559.mjs → byline-registry-CWP7I71B.mjs} +3 -3
- package/dist/{byline-registry-CxK5g559.mjs.map → byline-registry-CWP7I71B.mjs.map} +1 -1
- package/dist/{bylines-LJMgENMI.mjs → bylines-Cx5n-WqP.mjs} +3 -3
- package/dist/{bylines-LJMgENMI.mjs.map → bylines-Cx5n-WqP.mjs.map} +1 -1
- package/dist/{bylines-BJSva1Un.mjs → bylines-wurS258E.mjs} +50 -6
- package/dist/{bylines-BJSva1Un.mjs.map → bylines-wurS258E.mjs.map} +1 -1
- package/dist/{cache-lZL7SgVb.mjs → cache-B_HzASVT.mjs} +3 -3
- package/dist/{cache-lZL7SgVb.mjs.map → cache-B_HzASVT.mjs.map} +1 -1
- package/dist/{chunks-BU-vP9Dh.mjs → chunks-BerYVuve.mjs} +2 -2
- package/dist/{chunks-BU-vP9Dh.mjs.map → chunks-BerYVuve.mjs.map} +1 -1
- package/dist/cli/index.mjs +40 -27
- 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/{comment-C4jVbCM8.mjs → comment-sqQxNpN3.mjs} +2 -2
- package/dist/{comment-C4jVbCM8.mjs.map → comment-sqQxNpN3.mjs.map} +1 -1
- package/dist/{comments-BTAbC0Ek.mjs → comments-CJ0RZsYR.mjs} +3 -3
- package/dist/{comments-BTAbC0Ek.mjs.map → comments-CJ0RZsYR.mjs.map} +1 -1
- package/dist/{content-CyqOmOzm.mjs → content-BIlVx-RX.mjs} +132 -43
- package/dist/content-BIlVx-RX.mjs.map +1 -0
- package/dist/{context-DZ7bEh5-.mjs → context-GG52SPgh.mjs} +10 -10
- package/dist/{context-DZ7bEh5-.mjs.map → context-GG52SPgh.mjs.map} +1 -1
- package/dist/{cron-DZovZUnC.mjs → cron-BJ2ClIlj.mjs} +4 -3
- package/dist/cron-BJ2ClIlj.mjs.map +1 -0
- package/dist/{dashboard-B5WQpNTP.mjs → dashboard-2JgAMWxK.mjs} +4 -4
- package/dist/{dashboard-B5WQpNTP.mjs.map → dashboard-2JgAMWxK.mjs.map} +1 -1
- package/dist/db/index.d.mts +2 -2
- package/dist/db/index.mjs +1 -1
- package/dist/{device-flow-ptLrVINd.mjs → device-flow-s6_q3T7A.mjs} +2 -2
- package/dist/{device-flow-ptLrVINd.mjs.map → device-flow-s6_q3T7A.mjs.map} +1 -1
- package/dist/{error-DJOsMVSt.mjs → error-RwM4dD35.mjs} +2 -2
- package/dist/{error-DJOsMVSt.mjs.map → error-RwM4dD35.mjs.map} +1 -1
- package/dist/{fts-manager-DR1ERA0c.mjs → fts-manager-1RgHmopc.mjs} +2 -2
- package/dist/{fts-manager-DR1ERA0c.mjs.map → fts-manager-1RgHmopc.mjs.map} +1 -1
- package/dist/{index-D60_SzHG.d.mts → index-BpYeJO1E.d.mts} +2 -2
- package/dist/{index-D60_SzHG.d.mts.map → index-BpYeJO1E.d.mts.map} +1 -1
- package/dist/{index-CjKdMZ3U.d.mts → index-FfiTQJq2.d.mts} +199 -17
- package/dist/index-FfiTQJq2.d.mts.map +1 -0
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +43 -43
- package/dist/{load-6ZrRhepW.mjs → load-B84ohfBk.mjs} +2 -2
- package/dist/{load-6ZrRhepW.mjs.map → load-B84ohfBk.mjs.map} +1 -1
- package/dist/{loader-Dyx8dhFV.mjs → loader-CpZKpFz0.mjs} +32 -30
- package/dist/loader-CpZKpFz0.mjs.map +1 -0
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +6 -6
- package/dist/{media-C-oovGCG.mjs → media-JOf3pNkw.mjs} +2 -2
- package/dist/{media-C-oovGCG.mjs.map → media-JOf3pNkw.mjs.map} +1 -1
- package/dist/{menus-DugoYwTX.mjs → menus-DX4_E01q.mjs} +3 -3
- package/dist/{menus-DugoYwTX.mjs.map → menus-DX4_E01q.mjs.map} +1 -1
- package/dist/{menus-BKkxXCmd.mjs → menus-Dp9xporj.mjs} +86 -9
- package/dist/menus-Dp9xporj.mjs.map +1 -0
- package/dist/{normalize-DVV8nbrL.mjs → normalize-CK5o04zr.mjs} +2 -2
- package/dist/{normalize-DVV8nbrL.mjs.map → normalize-CK5o04zr.mjs.map} +1 -1
- package/dist/{oauth-authorization-DvBAL75d.mjs → oauth-authorization-1aPAYjiC.mjs} +2 -2
- package/dist/{oauth-authorization-DvBAL75d.mjs.map → oauth-authorization-1aPAYjiC.mjs.map} +1 -1
- package/dist/{options-BL4X94qY.mjs → options-BPCVnesz.mjs} +1 -1
- package/dist/{options-BL4X94qY.mjs.map → options-BPCVnesz.mjs.map} +1 -1
- package/dist/{options-tb7DJROi.d.mts → options-D4MnavW_.d.mts} +3 -3
- package/dist/{options-tb7DJROi.d.mts.map → options-D4MnavW_.d.mts.map} +1 -1
- package/dist/{parse-BBkFmLVr.mjs → parse-CrGndy1A.mjs} +2 -2
- package/dist/{parse-BBkFmLVr.mjs.map → parse-CrGndy1A.mjs.map} +1 -1
- package/dist/{patterns-CqG5Ya3i.mjs → patterns-p-RBdTbM.mjs} +1 -1
- package/dist/{patterns-CqG5Ya3i.mjs.map → patterns-p-RBdTbM.mjs.map} +1 -1
- package/dist/plugin-utils.d.mts +7 -7
- package/dist/plugins/adapt-sandbox-entry.d.mts +7 -7
- package/dist/{query-Ctlq1aOk.mjs → query-BFQ029Ts.mjs} +21 -15
- package/dist/query-BFQ029Ts.mjs.map +1 -0
- package/dist/{rate-limit-CH6W6ikK.mjs → rate-limit-ClFFUga6.mjs} +2 -2
- package/dist/{rate-limit-CH6W6ikK.mjs.map → rate-limit-ClFFUga6.mjs.map} +1 -1
- package/dist/{redirect-C6tJA7tk.mjs → redirect-CRWIt8Zj.mjs} +3 -3
- package/dist/{redirect-C6tJA7tk.mjs.map → redirect-CRWIt8Zj.mjs.map} +1 -1
- package/dist/{redirects-C0L9JUk4.mjs → redirects-DEygMrRO.mjs} +25 -3
- package/dist/redirects-DEygMrRO.mjs.map +1 -0
- package/dist/{redirects-CacE9eQa.mjs → redirects-OIu6vQ2i.mjs} +5 -5
- package/dist/{redirects-CacE9eQa.mjs.map → redirects-OIu6vQ2i.mjs.map} +1 -1
- package/dist/{registry-CIDxZbhh.mjs → registry-brYh-rAT.mjs} +6 -6
- package/dist/{registry-CIDxZbhh.mjs.map → registry-brYh-rAT.mjs.map} +1 -1
- package/dist/{request-cache-BYMs-BGX.mjs → request-cache-D32LpnmI.mjs} +1 -1
- package/dist/{request-cache-BYMs-BGX.mjs.map → request-cache-D32LpnmI.mjs.map} +1 -1
- package/dist/{runner-pt6Wl-l-.mjs → runner--4wMWwKM.mjs} +217 -166
- package/dist/runner--4wMWwKM.mjs.map +1 -0
- package/dist/{runner-DM1yR5qd.d.mts → runner-BcRuXq_h.d.mts} +2 -2
- package/dist/{runner-DM1yR5qd.d.mts.map → runner-BcRuXq_h.d.mts.map} +1 -1
- package/dist/runtime.d.mts +7 -7
- package/dist/runtime.mjs +2 -2
- package/dist/{schema-B4tk0HAG.mjs → schema-CS7Eg5gh.mjs} +5 -5
- package/dist/{schema-B4tk0HAG.mjs.map → schema-CS7Eg5gh.mjs.map} +1 -1
- package/dist/{search-f-fNfwab.mjs → search-o-aQzHI1.mjs} +4 -4
- package/dist/{search-f-fNfwab.mjs.map → search-o-aQzHI1.mjs.map} +1 -1
- package/dist/{secrets-YYbTgB1w.mjs → secrets-C_ZtRos3.mjs} +2 -2
- package/dist/{secrets-YYbTgB1w.mjs.map → secrets-C_ZtRos3.mjs.map} +1 -1
- package/dist/{sections-biElLfT9.mjs → sections-DhsZ0ns9.mjs} +3 -3
- package/dist/{sections-biElLfT9.mjs.map → sections-DhsZ0ns9.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-BR39kvTF.mjs → seo-B5e6y9Wk.mjs} +2 -2
- package/dist/{seo-BR39kvTF.mjs.map → seo-B5e6y9Wk.mjs.map} +1 -1
- package/dist/{service-BhR2acnc.mjs → service-DAxg8RPR.mjs} +2 -2
- package/dist/{service-BhR2acnc.mjs.map → service-DAxg8RPR.mjs.map} +1 -1
- package/dist/{settings-b5zW1R1T.mjs → settings-B1p-gPUK.mjs} +5 -5
- package/dist/{settings-b5zW1R1T.mjs.map → settings-B1p-gPUK.mjs.map} +1 -1
- package/dist/{settings-D_NJvjgN.mjs → settings-DIsbHTRE.mjs} +3 -3
- package/dist/{settings-D_NJvjgN.mjs.map → settings-DIsbHTRE.mjs.map} +1 -1
- package/dist/{setup-complete-VoEZfasi.mjs → setup-complete-Yuv78yua.mjs} +2 -2
- package/dist/{setup-complete-VoEZfasi.mjs.map → setup-complete-Yuv78yua.mjs.map} +1 -1
- package/dist/{site-url-Cm8-sJy7.mjs → site-url-mEVmwIFi.mjs} +2 -2
- package/dist/{site-url-Cm8-sJy7.mjs.map → site-url-mEVmwIFi.mjs.map} +1 -1
- package/dist/{taxonomies-Crtzy4MT.mjs → taxonomies-BEW7S5AI.mjs} +7 -6
- package/dist/taxonomies-BEW7S5AI.mjs.map +1 -0
- package/dist/{taxonomies-Mhn9rjTQ.mjs → taxonomies-UusDXv3C.mjs} +4 -4
- package/dist/{taxonomies-Mhn9rjTQ.mjs.map → taxonomies-UusDXv3C.mjs.map} +1 -1
- package/dist/{taxonomy-DTZrIQpi.mjs → taxonomy-CdllE4oq.mjs} +3 -3
- package/dist/{taxonomy-DTZrIQpi.mjs.map → taxonomy-CdllE4oq.mjs.map} +1 -1
- package/dist/{transaction-NQj4VJ7Z.mjs → transaction-x2tJQ-A1.mjs} +1 -1
- package/dist/{transaction-NQj4VJ7Z.mjs.map → transaction-x2tJQ-A1.mjs.map} +1 -1
- package/dist/{transport-OnMNbsIA.d.mts → transport-BwQeeY2p.d.mts} +1 -1
- package/dist/{transport-OnMNbsIA.d.mts.map → transport-BwQeeY2p.d.mts.map} +1 -1
- package/dist/{types-K3MDsxpy.mjs → types-BXSUSAjt.mjs} +16 -3
- package/dist/{types-K3MDsxpy.mjs.map → types-BXSUSAjt.mjs.map} +1 -1
- package/dist/{types-D8bhH891.mjs → types-DZk_y-MU.mjs} +1 -1
- package/dist/{types-D8bhH891.mjs.map → types-DZk_y-MU.mjs.map} +1 -1
- package/dist/{types-DawhLFwy.d.mts → types-OT_Es5mp.d.mts} +26 -1
- package/dist/{types-DawhLFwy.d.mts.map → types-OT_Es5mp.d.mts.map} +1 -1
- package/dist/{types-i8_uzhMD.d.mts → types-WVmpZBJV.d.mts} +18 -3
- package/dist/types-WVmpZBJV.d.mts.map +1 -0
- package/dist/{user-DzEUl5zA.mjs → user-C0um7wrg.mjs} +18 -2
- package/dist/user-C0um7wrg.mjs.map +1 -0
- package/dist/{validate-Dy6nkNls.d.mts → validate-BPAHUSge.d.mts} +10 -2
- package/dist/validate-BPAHUSge.d.mts.map +1 -0
- package/dist/{validate-JCXcsqiY.mjs → validate-ZP9Dvg0P.mjs} +6 -3
- package/dist/validate-ZP9Dvg0P.mjs.map +1 -0
- package/dist/{validation-Bq-VyKJg.mjs → validation-CE5i4q0c.mjs} +5 -5
- package/dist/{validation-Bq-VyKJg.mjs.map → validation-CE5i4q0c.mjs.map} +1 -1
- package/dist/version-Dw0JXu45.mjs +7 -0
- package/dist/{version-CnS-Cr8A.mjs.map → version-Dw0JXu45.mjs.map} +1 -1
- package/dist/{widgets-Bap1eS1X.mjs → widgets-ClEnYQCH.mjs} +2 -2
- package/dist/{widgets-Bap1eS1X.mjs.map → widgets-ClEnYQCH.mjs.map} +1 -1
- package/dist/{zod-generator-BSDpkqSH.mjs → zod-generator-Djo_VHCt.mjs} +2 -2
- package/dist/{zod-generator-BSDpkqSH.mjs.map → zod-generator-Djo_VHCt.mjs.map} +1 -1
- package/package.json +5 -5
- package/src/api/handlers/content.ts +107 -8
- package/src/api/handlers/index.ts +2 -0
- package/src/api/openapi/document.ts +25 -0
- package/src/api/schemas/content.ts +33 -0
- package/src/astro/integration/index.ts +98 -0
- package/src/astro/integration/routes.ts +6 -0
- package/src/astro/integration/virtual-modules.ts +39 -0
- package/src/astro/integration/vite-config.ts +12 -0
- package/src/astro/middleware.ts +28 -0
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +8 -4
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id].ts +4 -2
- package/src/astro/routes/api/content/[collection]/authors.ts +34 -0
- package/src/astro/types.ts +8 -1
- package/src/bylines/index.ts +57 -0
- package/src/cli/commands/export-seed.ts +28 -12
- package/src/components/EmDashImage.astro +22 -4
- package/src/components/Image.astro +20 -3
- package/src/database/migrations/043_content_references.ts +121 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/content.ts +225 -67
- package/src/database/repositories/index.ts +7 -0
- package/src/database/repositories/relation.ts +467 -0
- package/src/database/repositories/types.ts +31 -0
- package/src/database/repositories/user.ts +18 -0
- package/src/database/types.ts +34 -0
- package/src/emdash-runtime.ts +141 -42
- package/src/index.ts +8 -1
- package/src/loader.ts +67 -34
- package/src/media/responsive.ts +125 -0
- package/src/plugins/cron.ts +3 -2
- package/src/plugins/index.ts +5 -0
- package/src/plugins/scheduler/node.ts +9 -2
- package/src/query.ts +32 -5
- package/src/scheduled-publish.ts +153 -0
- package/src/seed/apply.ts +16 -6
- package/src/seed/types.ts +9 -0
- package/src/seed/validate.ts +15 -0
- package/src/taxonomies/index.ts +1 -0
- package/src/virtual-modules.d.ts +11 -0
- package/dist/api-Cs7DAACP.mjs.map +0 -1
- package/dist/apply-BWMV4Zmw.mjs.map +0 -1
- package/dist/byline-fields-BNy7Ng1U.d.mts.map +0 -1
- package/dist/content-CyqOmOzm.mjs.map +0 -1
- package/dist/cron-DZovZUnC.mjs.map +0 -1
- package/dist/index-CjKdMZ3U.d.mts.map +0 -1
- package/dist/loader-Dyx8dhFV.mjs.map +0 -1
- package/dist/menus-BKkxXCmd.mjs.map +0 -1
- package/dist/query-Ctlq1aOk.mjs.map +0 -1
- package/dist/redirects-C0L9JUk4.mjs.map +0 -1
- package/dist/runner-pt6Wl-l-.mjs.map +0 -1
- package/dist/taxonomies-Crtzy4MT.mjs.map +0 -1
- package/dist/types-i8_uzhMD.d.mts.map +0 -1
- package/dist/user-DzEUl5zA.mjs.map +0 -1
- package/dist/validate-Dy6nkNls.d.mts.map +0 -1
- package/dist/validate-JCXcsqiY.mjs.map +0 -1
- package/dist/version-CnS-Cr8A.mjs +0 -7
- package/src/plugins/scheduler/piggyback.ts +0 -71
|
@@ -132,7 +132,7 @@ export const PUT: APIRoute = async ({ params, request, locals, cache }) => {
|
|
|
132
132
|
return unwrapResult(result);
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
export const DELETE: APIRoute = async ({ params, locals, cache }) => {
|
|
135
|
+
export const DELETE: APIRoute = async ({ params, locals, url, cache }) => {
|
|
136
136
|
const { emdash, user } = locals;
|
|
137
137
|
const collection = params.collection!;
|
|
138
138
|
const id = params.id!;
|
|
@@ -141,8 +141,10 @@ export const DELETE: APIRoute = async ({ params, locals, cache }) => {
|
|
|
141
141
|
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
const locale = url.searchParams.get("locale") || undefined;
|
|
145
|
+
|
|
144
146
|
// Fetch item to check ownership
|
|
145
|
-
const existing = await emdash.handleContentGet(collection, id);
|
|
147
|
+
const existing = await emdash.handleContentGet(collection, id, locale);
|
|
146
148
|
if (!existing.success) {
|
|
147
149
|
return apiError(
|
|
148
150
|
existing.error?.code ?? "UNKNOWN_ERROR",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content authors endpoint - injected by EmDash integration
|
|
3
|
+
*
|
|
4
|
+
* GET /_emdash/api/content/{collection}/authors - List the distinct authors
|
|
5
|
+
* of a collection's live content, for the admin author filter.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { APIRoute } from "astro";
|
|
9
|
+
|
|
10
|
+
import { requirePerm } from "#api/authorize.js";
|
|
11
|
+
import { apiError, unwrapResult } from "#api/error.js";
|
|
12
|
+
|
|
13
|
+
export const prerender = false;
|
|
14
|
+
|
|
15
|
+
export const GET: APIRoute = async ({ params, locals }) => {
|
|
16
|
+
const { emdash, user } = locals;
|
|
17
|
+
const collection = params.collection!;
|
|
18
|
+
|
|
19
|
+
// Editorial capability, not plain read. This response carries author
|
|
20
|
+
// emails (PII) and reveals the authors of unpublished entries, so it must
|
|
21
|
+
// not be reachable by subscribers (content:read). content:read_drafts is
|
|
22
|
+
// the same tier the list route requires before it stops forcing
|
|
23
|
+
// status=published, so the visibility surfaces line up.
|
|
24
|
+
const denied = requirePerm(user, "content:read_drafts");
|
|
25
|
+
if (denied) return denied;
|
|
26
|
+
|
|
27
|
+
if (!emdash?.handleContentAuthors) {
|
|
28
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const result = await emdash.handleContentAuthors(collection);
|
|
32
|
+
|
|
33
|
+
return unwrapResult(result);
|
|
34
|
+
};
|
package/src/astro/types.ts
CHANGED
|
@@ -233,9 +233,16 @@ export interface EmDashHandlers {
|
|
|
233
233
|
orderBy?: string;
|
|
234
234
|
order?: "asc" | "desc";
|
|
235
235
|
locale?: string;
|
|
236
|
+
q?: string;
|
|
237
|
+
authorId?: string;
|
|
238
|
+
dateField?: "createdAt" | "updatedAt" | "publishedAt";
|
|
239
|
+
dateFrom?: string;
|
|
240
|
+
dateTo?: string;
|
|
236
241
|
},
|
|
237
242
|
) => Promise<HandlerResponse>;
|
|
238
243
|
|
|
244
|
+
handleContentAuthors: (collection: string) => Promise<HandlerResponse>;
|
|
245
|
+
|
|
239
246
|
handleContentGet: (
|
|
240
247
|
collection: string,
|
|
241
248
|
id: string,
|
|
@@ -313,7 +320,7 @@ export interface EmDashHandlers {
|
|
|
313
320
|
handleContentPublish: (
|
|
314
321
|
collection: string,
|
|
315
322
|
id: string,
|
|
316
|
-
options?: { publishedAt?: string },
|
|
323
|
+
options?: { publishedAt?: string; requireScheduledDue?: boolean },
|
|
317
324
|
) => Promise<HandlerResponse>;
|
|
318
325
|
|
|
319
326
|
handleContentUnpublish: (collection: string, id: string) => Promise<HandlerResponse>;
|
package/src/bylines/index.ts
CHANGED
|
@@ -320,6 +320,63 @@ export async function getBylinesForEntries(
|
|
|
320
320
|
return result;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Get content entries credited to a byline, in any credit position.
|
|
325
|
+
*
|
|
326
|
+
* Unlike filtering on the content table's `primary_byline_id` column (which
|
|
327
|
+
* only finds entries where the byline is the first/primary credit), this
|
|
328
|
+
* matches every explicit credit recorded in `_emdash_content_bylines`, so
|
|
329
|
+
* co-authored entries where the byline is a secondary credit are included.
|
|
330
|
+
*
|
|
331
|
+
* `byline` is matched against the byline's `translation_group` (the value
|
|
332
|
+
* stored on credits since migration 040), so a single credit spans every
|
|
333
|
+
* locale variant of the byline. Pass `byline.translationGroup ?? byline.id`
|
|
334
|
+
* from `getByline` / `getBylineBySlug`. An array matches any of the given
|
|
335
|
+
* bylines (OR).
|
|
336
|
+
*
|
|
337
|
+
* The result respects the active locale, status, ordering, and eager
|
|
338
|
+
* hydration of `getEmDashCollection`.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* ```ts
|
|
342
|
+
* import { getBylineBySlug, getEntriesByByline } from "emdash";
|
|
343
|
+
*
|
|
344
|
+
* const byline = await getBylineBySlug("jane-doe");
|
|
345
|
+
* if (byline) {
|
|
346
|
+
* const posts = await getEntriesByByline("posts", byline.translationGroup ?? byline.id, {
|
|
347
|
+
* orderBy: { published_at: "desc" },
|
|
348
|
+
* });
|
|
349
|
+
* }
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* @param collection - The collection slug (e.g. "posts")
|
|
353
|
+
* @param byline - A byline translation group, or an array of them (OR)
|
|
354
|
+
* @param options - Optional locale, ordering, status, and limit
|
|
355
|
+
*/
|
|
356
|
+
export async function getEntriesByByline(
|
|
357
|
+
collection: string,
|
|
358
|
+
byline: string | string[],
|
|
359
|
+
options: {
|
|
360
|
+
locale?: string;
|
|
361
|
+
orderBy?: Record<string, "asc" | "desc">;
|
|
362
|
+
status?: "draft" | "published" | "archived";
|
|
363
|
+
limit?: number;
|
|
364
|
+
} = {},
|
|
365
|
+
): Promise<Array<{ id: string; data: Record<string, unknown> }>> {
|
|
366
|
+
const { getEmDashCollection } = await import("../query.js");
|
|
367
|
+
|
|
368
|
+
const queryOptions: Record<string, unknown> = {
|
|
369
|
+
where: { byline },
|
|
370
|
+
};
|
|
371
|
+
if (options.locale !== undefined) queryOptions.locale = options.locale;
|
|
372
|
+
if (options.orderBy !== undefined) queryOptions.orderBy = options.orderBy;
|
|
373
|
+
if (options.status !== undefined) queryOptions.status = options.status;
|
|
374
|
+
if (options.limit !== undefined) queryOptions.limit = options.limit;
|
|
375
|
+
|
|
376
|
+
const { entries } = await getEmDashCollection(collection, queryOptions);
|
|
377
|
+
return entries;
|
|
378
|
+
}
|
|
379
|
+
|
|
323
380
|
/** Reads `author_id` + `primary_byline_id` for one entry in a single query. */
|
|
324
381
|
async function getEntryContext(
|
|
325
382
|
db: Awaited<ReturnType<typeof getDb>>,
|
|
@@ -20,7 +20,7 @@ import { OptionsRepository } from "../../database/repositories/options.js";
|
|
|
20
20
|
import { TaxonomyRepository } from "../../database/repositories/taxonomy.js";
|
|
21
21
|
import type { Database } from "../../database/types.js";
|
|
22
22
|
import { validateIdentifier } from "../../database/validate.js";
|
|
23
|
-
import { isI18nEnabled } from "../../i18n/config.js";
|
|
23
|
+
import { getI18nConfig, isI18nEnabled } from "../../i18n/config.js";
|
|
24
24
|
import { SchemaRegistry } from "../../schema/registry.js";
|
|
25
25
|
import type { FieldType } from "../../schema/types.js";
|
|
26
26
|
import type {
|
|
@@ -128,7 +128,12 @@ export async function exportSeed(db: Kysely<Database>, withContent?: string): Pr
|
|
|
128
128
|
// middleware, but the CLI never does, so `isI18nEnabled()` is always false
|
|
129
129
|
// under `emdash export-seed` (#1330). Detecting multiple locales in the data
|
|
130
130
|
// keeps the export locale-aware without the runtime flag.
|
|
131
|
-
const i18nEnabled = await
|
|
131
|
+
const { i18nEnabled, defaultLocale } = await detectLocaleInfo(db, seed.collections);
|
|
132
|
+
|
|
133
|
+
// Self-describe the default locale so a non-`en` single-locale project
|
|
134
|
+
// survives the round-trip: `emdash seed` runs outside the runtime and would
|
|
135
|
+
// otherwise backfill omitted locales as `en` (#1421).
|
|
136
|
+
if (defaultLocale) seed.defaultLocale = defaultLocale;
|
|
132
137
|
|
|
133
138
|
// 3. Export taxonomy definitions and terms
|
|
134
139
|
seed.taxonomies = await exportTaxonomies(db, i18nEnabled);
|
|
@@ -216,7 +221,7 @@ async function exportBylines(
|
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
/**
|
|
219
|
-
* Determine
|
|
224
|
+
* Determine locale-awareness and the data's default locale for the export.
|
|
220
225
|
*
|
|
221
226
|
* The runtime initializes the i18n config in middleware, but the CLI never does,
|
|
222
227
|
* so `isI18nEnabled()` is always false under `emdash export-seed` (#1330). When
|
|
@@ -227,39 +232,50 @@ async function exportBylines(
|
|
|
227
232
|
* genuinely single-locale project from a multi-locale one. This keeps
|
|
228
233
|
* single-locale exports on bare ids and gives multi-locale exports the
|
|
229
234
|
* per-locale suffix they need to avoid duplicate seed ids.
|
|
235
|
+
*
|
|
236
|
+
* `defaultLocale` self-describes the single-locale case so a non-`en` default
|
|
237
|
+
* survives the round-trip (#1421). When more than one locale is present every
|
|
238
|
+
* row already carries its own `locale`, so no fallback is needed and we leave it
|
|
239
|
+
* undefined rather than guess which locale is the "default" without the runtime
|
|
240
|
+
* config.
|
|
230
241
|
*/
|
|
231
|
-
async function
|
|
242
|
+
async function detectLocaleInfo(
|
|
232
243
|
db: Kysely<Database>,
|
|
233
244
|
collections: SeedCollection[],
|
|
234
|
-
): Promise<boolean> {
|
|
235
|
-
|
|
245
|
+
): Promise<{ i18nEnabled: boolean; defaultLocale: string | undefined }> {
|
|
246
|
+
const config = getI18nConfig();
|
|
247
|
+
if (isI18nEnabled() && config) {
|
|
248
|
+
return { i18nEnabled: true, defaultLocale: config.defaultLocale };
|
|
249
|
+
}
|
|
236
250
|
|
|
237
251
|
const locales = new Set<string>();
|
|
238
|
-
const collectDistinctLocales = async (tableRef: ReturnType<typeof sql.ref>): Promise<
|
|
252
|
+
const collectDistinctLocales = async (tableRef: ReturnType<typeof sql.ref>): Promise<void> => {
|
|
239
253
|
const result = await sql<{ locale: string | null }>`
|
|
240
254
|
SELECT DISTINCT locale FROM ${tableRef}
|
|
241
255
|
`.execute(db);
|
|
242
256
|
for (const row of result.rows) {
|
|
243
257
|
if (row.locale) locales.add(row.locale);
|
|
244
258
|
}
|
|
245
|
-
return locales.size > 1;
|
|
246
259
|
};
|
|
247
260
|
|
|
248
|
-
|
|
249
|
-
|
|
261
|
+
await collectDistinctLocales(sql.ref("_emdash_taxonomy_defs"));
|
|
262
|
+
await collectDistinctLocales(sql.ref("_emdash_menus"));
|
|
250
263
|
|
|
251
264
|
for (const collection of collections) {
|
|
252
265
|
validateIdentifier(collection.slug, "collection slug");
|
|
253
266
|
// On D1, deleteCollection is non-atomic, so a collection row can outlive
|
|
254
267
|
// its ec_* table. Skip missing tables rather than crashing the export.
|
|
255
268
|
try {
|
|
256
|
-
|
|
269
|
+
await collectDistinctLocales(sql.ref(`ec_${collection.slug}`));
|
|
257
270
|
} catch (error) {
|
|
258
271
|
if (!isMissingTableError(error)) throw error;
|
|
259
272
|
}
|
|
260
273
|
}
|
|
261
274
|
|
|
262
|
-
return
|
|
275
|
+
return {
|
|
276
|
+
i18nEnabled: locales.size > 1,
|
|
277
|
+
defaultLocale: locales.size === 1 ? [...locales][0] : undefined,
|
|
278
|
+
};
|
|
263
279
|
}
|
|
264
280
|
|
|
265
281
|
/**
|
|
@@ -18,11 +18,16 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { MediaValue } from "../fields/types.js";
|
|
20
20
|
import type { HTMLAttributes } from "astro/types";
|
|
21
|
+
import { getImage } from "astro:assets";
|
|
21
22
|
import type { ImageEmbed } from "../media/types.js";
|
|
22
23
|
import { getMediaProvider } from "../media/provider-loader.js";
|
|
23
24
|
import { buildRenderMediaUrl } from "../media/url.js";
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
import {
|
|
26
|
+
buildResponsiveImage,
|
|
27
|
+
toAbsoluteMediaUrl,
|
|
28
|
+
RESPONSIVE_BREAKPOINTS,
|
|
29
|
+
} from "../media/responsive.js";
|
|
30
|
+
import { getPublicOrigin } from "../api/public-url.js";
|
|
26
31
|
|
|
27
32
|
interface Props extends Omit<
|
|
28
33
|
HTMLAttributes<"img">,
|
|
@@ -72,7 +77,7 @@ function generateSrcset(
|
|
|
72
77
|
maxWidth: number,
|
|
73
78
|
aspectRatio?: number
|
|
74
79
|
): string {
|
|
75
|
-
return
|
|
80
|
+
return RESPONSIVE_BREAKPOINTS.filter((w) => w <= maxWidth * 2) // Include up to 2x for retina
|
|
76
81
|
.map((w) => {
|
|
77
82
|
const h = aspectRatio ? Math.round(w / aspectRatio) : undefined;
|
|
78
83
|
return `${getSrc({ width: w, height: h })} ${w}w`;
|
|
@@ -98,8 +103,21 @@ if (img) {
|
|
|
98
103
|
const providerId = img.provider ?? "local";
|
|
99
104
|
|
|
100
105
|
if (providerId === "local" || img.src) {
|
|
101
|
-
// Local provider or direct src URL
|
|
106
|
+
// Local provider or direct src URL. Route through Astro's image service
|
|
107
|
+
// (`astro:assets`) to generate a responsive srcset; on Cloudflare this is
|
|
108
|
+
// the Images binding, on Node it is sharp. Falls back to a plain <img>
|
|
109
|
+
// when the service is unavailable or the source can't be optimized.
|
|
102
110
|
src = img.src || buildLocalImageUrl(img);
|
|
111
|
+
const optimized = await buildResponsiveImage(getImage, {
|
|
112
|
+
src: toAbsoluteMediaUrl(src, getPublicOrigin(Astro.url, Astro.locals.emdash?.config)),
|
|
113
|
+
width: finalWidth,
|
|
114
|
+
height: finalHeight,
|
|
115
|
+
});
|
|
116
|
+
if (optimized) {
|
|
117
|
+
src = optimized.src;
|
|
118
|
+
srcset = optimized.srcset;
|
|
119
|
+
sizes = optimized.sizes;
|
|
120
|
+
}
|
|
103
121
|
} else {
|
|
104
122
|
// External provider
|
|
105
123
|
try {
|
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
* Renders image blocks from WordPress imports and EmDash media.
|
|
6
6
|
* Uses the provider's getSrc function for responsive srcset generation.
|
|
7
7
|
*/
|
|
8
|
+
import { getImage } from "astro:assets";
|
|
8
9
|
import type { ImageEmbed } from "../media/types.js";
|
|
9
10
|
import { getMediaProvider } from "../media/provider-loader.js";
|
|
10
11
|
import { buildRenderMediaUrl } from "../media/url.js";
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
import {
|
|
13
|
+
buildResponsiveImage,
|
|
14
|
+
toAbsoluteMediaUrl,
|
|
15
|
+
RESPONSIVE_BREAKPOINTS,
|
|
16
|
+
} from "../media/responsive.js";
|
|
17
|
+
import { getPublicOrigin } from "../api/public-url.js";
|
|
13
18
|
|
|
14
19
|
export interface Props {
|
|
15
20
|
node: {
|
|
@@ -44,7 +49,7 @@ function generateSrcset(
|
|
|
44
49
|
maxWidth: number,
|
|
45
50
|
aspectRatio?: number,
|
|
46
51
|
): string {
|
|
47
|
-
return
|
|
52
|
+
return RESPONSIVE_BREAKPOINTS.filter((w) => w <= maxWidth * 2)
|
|
48
53
|
.map((w) => {
|
|
49
54
|
const h = aspectRatio ? Math.round(w / aspectRatio) : undefined;
|
|
50
55
|
return `${getSrc({ width: w, height: h })} ${w}w`;
|
|
@@ -131,6 +136,18 @@ if (!src) {
|
|
|
131
136
|
url: asset.url,
|
|
132
137
|
id: asset._ref,
|
|
133
138
|
});
|
|
139
|
+
// Generate a responsive srcset via Astro's image service for local/R2 media.
|
|
140
|
+
// Falls back to the plain URL when optimization isn't possible.
|
|
141
|
+
const optimized = await buildResponsiveImage(getImage, {
|
|
142
|
+
src: toAbsoluteMediaUrl(src, getPublicOrigin(Astro.url, Astro.locals.emdash?.config)),
|
|
143
|
+
width: renderWidth,
|
|
144
|
+
height: renderHeight,
|
|
145
|
+
});
|
|
146
|
+
if (optimized) {
|
|
147
|
+
src = optimized.src;
|
|
148
|
+
srcset = optimized.srcset;
|
|
149
|
+
sizes = optimized.sizes;
|
|
150
|
+
}
|
|
134
151
|
}
|
|
135
152
|
|
|
136
153
|
// Build placeholder background style
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
|
|
3
|
+
import { getI18nConfig } from "../../i18n/config.js";
|
|
4
|
+
import { currentTimestamp } from "../dialect-helpers.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Content references.
|
|
8
|
+
*
|
|
9
|
+
* `_emdash_relations` defines relationship types (row-per-locale, mirroring
|
|
10
|
+
* `_emdash_taxonomy_defs`): which collection is the parent, which is the child
|
|
11
|
+
* (the side that may multiply), and localized labels for each role.
|
|
12
|
+
*
|
|
13
|
+
* `_emdash_content_references` holds directed `parent → child` edges between
|
|
14
|
+
* content entries. Both endpoints and the relation are referenced by
|
|
15
|
+
* `translation_group`, so edges are locale-agnostic. As with
|
|
16
|
+
* `content_taxonomies`, group-linking precludes SQL foreign keys; referential
|
|
17
|
+
* cleanup is an application-layer concern.
|
|
18
|
+
*
|
|
19
|
+
* Idempotency: every `CREATE TABLE` and `CREATE INDEX` uses `.ifNotExists()`,
|
|
20
|
+
* so a partial prior run (a crash mid-migration, or a retry after the runner's
|
|
21
|
+
* race-recovery path) re-applies cleanly — including any indexes that landed in
|
|
22
|
+
* the failed pass after their table.
|
|
23
|
+
*/
|
|
24
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
25
|
+
const defaultLocale = getI18nConfig()?.defaultLocale ?? "en";
|
|
26
|
+
|
|
27
|
+
await db.schema
|
|
28
|
+
.createTable("_emdash_relations")
|
|
29
|
+
.ifNotExists()
|
|
30
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
31
|
+
.addColumn("name", "text", (c) => c.notNull())
|
|
32
|
+
.addColumn("parent_collection", "text", (c) => c.notNull())
|
|
33
|
+
.addColumn("child_collection", "text", (c) => c.notNull())
|
|
34
|
+
.addColumn("parent_label", "text", (c) => c.notNull())
|
|
35
|
+
.addColumn("child_label", "text", (c) => c.notNull())
|
|
36
|
+
.addColumn("locale", "text", (c) => c.notNull().defaultTo(defaultLocale))
|
|
37
|
+
.addColumn("translation_group", "text", (c) => c.notNull())
|
|
38
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
39
|
+
.addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
40
|
+
.addUniqueConstraint("_emdash_relations_name_locale_unique", ["name", "locale"])
|
|
41
|
+
.execute();
|
|
42
|
+
|
|
43
|
+
await db.schema
|
|
44
|
+
.createIndex("idx__emdash_relations_locale")
|
|
45
|
+
.ifNotExists()
|
|
46
|
+
.on("_emdash_relations")
|
|
47
|
+
.column("locale")
|
|
48
|
+
.execute();
|
|
49
|
+
await db.schema
|
|
50
|
+
.createIndex("idx__emdash_relations_translation_group")
|
|
51
|
+
.ifNotExists()
|
|
52
|
+
.on("_emdash_relations")
|
|
53
|
+
.column("translation_group")
|
|
54
|
+
.execute();
|
|
55
|
+
await db.schema
|
|
56
|
+
.createIndex("idx__emdash_relations_parent_collection")
|
|
57
|
+
.ifNotExists()
|
|
58
|
+
.on("_emdash_relations")
|
|
59
|
+
.column("parent_collection")
|
|
60
|
+
.execute();
|
|
61
|
+
await db.schema
|
|
62
|
+
.createIndex("idx__emdash_relations_child_collection")
|
|
63
|
+
.ifNotExists()
|
|
64
|
+
.on("_emdash_relations")
|
|
65
|
+
.column("child_collection")
|
|
66
|
+
.execute();
|
|
67
|
+
|
|
68
|
+
// One row per (translation_group, locale): the row-per-locale model wants a
|
|
69
|
+
// relation to have at most one variant per locale. Migration 040 enforces
|
|
70
|
+
// the same invariant for `_emdash_bylines` with a *partial* unique
|
|
71
|
+
// (`WHERE translation_group IS NOT NULL`) only because it back-fills an
|
|
72
|
+
// existing table; this table is new and `translation_group` is `NOT NULL`,
|
|
73
|
+
// so a plain unique index suffices.
|
|
74
|
+
await db.schema
|
|
75
|
+
.createIndex("idx__emdash_relations_group_locale_unique")
|
|
76
|
+
.ifNotExists()
|
|
77
|
+
.unique()
|
|
78
|
+
.on("_emdash_relations")
|
|
79
|
+
.columns(["translation_group", "locale"])
|
|
80
|
+
.execute();
|
|
81
|
+
|
|
82
|
+
await db.schema
|
|
83
|
+
.createTable("_emdash_content_references")
|
|
84
|
+
.ifNotExists()
|
|
85
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
86
|
+
.addColumn("relation_group", "text", (c) => c.notNull())
|
|
87
|
+
.addColumn("parent_group", "text", (c) => c.notNull())
|
|
88
|
+
.addColumn("child_group", "text", (c) => c.notNull())
|
|
89
|
+
.addColumn("sort_order", "integer", (c) => c.notNull().defaultTo(0))
|
|
90
|
+
.addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
|
|
91
|
+
.addUniqueConstraint("content_references_unique", [
|
|
92
|
+
"relation_group",
|
|
93
|
+
"parent_group",
|
|
94
|
+
"child_group",
|
|
95
|
+
])
|
|
96
|
+
.execute();
|
|
97
|
+
|
|
98
|
+
await db.schema
|
|
99
|
+
.createIndex("idx__emdash_content_references_parent")
|
|
100
|
+
.ifNotExists()
|
|
101
|
+
.on("_emdash_content_references")
|
|
102
|
+
.columns(["parent_group", "relation_group", "sort_order"])
|
|
103
|
+
.execute();
|
|
104
|
+
await db.schema
|
|
105
|
+
.createIndex("idx__emdash_content_references_child")
|
|
106
|
+
.ifNotExists()
|
|
107
|
+
.on("_emdash_content_references")
|
|
108
|
+
.columns(["child_group", "relation_group"])
|
|
109
|
+
.execute();
|
|
110
|
+
await db.schema
|
|
111
|
+
.createIndex("idx__emdash_content_references_relation")
|
|
112
|
+
.ifNotExists()
|
|
113
|
+
.on("_emdash_content_references")
|
|
114
|
+
.column("relation_group")
|
|
115
|
+
.execute();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
119
|
+
await db.schema.dropTable("_emdash_content_references").ifExists().execute();
|
|
120
|
+
await db.schema.dropTable("_emdash_relations").ifExists().execute();
|
|
121
|
+
}
|
|
@@ -44,6 +44,7 @@ import * as m039 from "./039_fix_fts5_triggers.js";
|
|
|
44
44
|
import * as m040 from "./040_byline_i18n.js";
|
|
45
45
|
import * as m041 from "./041_content_locale_list_index.js";
|
|
46
46
|
import * as m042 from "./042_byline_fields.js";
|
|
47
|
+
import * as m043 from "./043_content_references.js";
|
|
47
48
|
|
|
48
49
|
const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
49
50
|
"001_initial": m001,
|
|
@@ -87,6 +88,7 @@ const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
|
|
|
87
88
|
"040_byline_i18n": m040,
|
|
88
89
|
"041_content_locale_list_index": m041,
|
|
89
90
|
"042_byline_fields": m042,
|
|
91
|
+
"043_content_references": m043,
|
|
90
92
|
});
|
|
91
93
|
|
|
92
94
|
/** Total number of registered migrations. Exported for use in tests. */
|