emdash 0.15.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/api/route-utils.mjs +10 -10
- package/dist/api/schemas/index.d.mts +1 -1
- package/dist/{api-CLwG_3dh.mjs → api-BNKqxyFX.mjs} +54 -14
- package/dist/{api-CLwG_3dh.mjs.map → api-BNKqxyFX.mjs.map} +1 -1
- package/dist/{apply-wJhM_bwU.mjs → apply-BOPaD-s9.mjs} +16 -16
- package/dist/{apply-wJhM_bwU.mjs.map → apply-BOPaD-s9.mjs.map} +1 -1
- package/dist/astro/index.d.mts +3 -3
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +33 -1
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +3 -3
- package/dist/astro/middleware/auth.mjs +2 -2
- package/dist/astro/middleware/redirect.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +66 -46
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +3 -3
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +3 -3
- 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/bylines/_id_/index.mjs +8 -8
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +9 -9
- package/dist/astro/routes/api/admin/bylines/index.mjs +9 -9
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +6 -6
- 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 +3 -3
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/index.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +27 -27
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +41 -28
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- 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 +46 -28
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +27 -27
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +27 -27
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +27 -27
- 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 +3 -3
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
- package/dist/astro/routes/api/admin/users/index.mjs +3 -3
- 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 +3 -3
- package/dist/astro/routes/api/auth/invite/index.mjs +3 -3
- package/dist/astro/routes/api/auth/invite/register-options.mjs +3 -3
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/options.mjs +4 -4
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/signup/complete.mjs +3 -3
- package/dist/astro/routes/api/auth/signup/request.mjs +4 -4
- package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +6 -6
- 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_/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 +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +4 -4
- 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.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +8 -8
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/index.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/trash.mjs +4 -4
- 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.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +3 -3
- package/dist/astro/routes/api/import/wordpress/execute.mjs +8 -8
- package/dist/astro/routes/api/import/wordpress/media.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +6 -6
- 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 +7 -7
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +5 -5
- package/dist/astro/routes/api/manifest.mjs +3 -3
- package/dist/astro/routes/api/mcp.mjs +26 -26
- package/dist/astro/routes/api/media/_id_/confirm.mjs +4 -4
- package/dist/astro/routes/api/media/_id_.mjs +4 -4
- 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 +4 -4
- package/dist/astro/routes/api/media.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_/items.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_/translations.mjs +5 -5
- package/dist/astro/routes/api/menus/_name_.mjs +5 -5
- package/dist/astro/routes/api/menus/index.mjs +5 -5
- package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
- package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
- package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
- package/dist/astro/routes/api/oauth/register.mjs +2 -2
- package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
- package/dist/astro/routes/api/oauth/token.mjs +2 -2
- package/dist/astro/routes/api/openapi.json.mjs +2 -2
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/index.mjs +6 -6
- package/dist/astro/routes/api/redirects/404s/summary.mjs +6 -6
- package/dist/astro/routes/api/redirects/_id_.mjs +7 -7
- package/dist/astro/routes/api/redirects/index.mjs +7 -7
- 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 +27 -27
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +27 -27
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +27 -27
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +27 -27
- package/dist/astro/routes/api/schema/collections/index.mjs +27 -27
- package/dist/astro/routes/api/schema/index.mjs +6 -6
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +27 -27
- package/dist/astro/routes/api/schema/orphans/index.mjs +27 -27
- package/dist/astro/routes/api/search/enable.mjs +7 -7
- package/dist/astro/routes/api/search/index.mjs +6 -6
- package/dist/astro/routes/api/search/rebuild.mjs +7 -7
- package/dist/astro/routes/api/search/stats.mjs +6 -6
- package/dist/astro/routes/api/search/suggest.mjs +6 -6
- package/dist/astro/routes/api/sections/_slug_.mjs +6 -6
- package/dist/astro/routes/api/sections/index.mjs +6 -6
- package/dist/astro/routes/api/settings/email.mjs +4 -4
- package/dist/astro/routes/api/settings.mjs +8 -8
- package/dist/astro/routes/api/setup/admin-verify.mjs +3 -3
- package/dist/astro/routes/api/setup/admin.mjs +3 -3
- package/dist/astro/routes/api/setup/dev-bypass.mjs +15 -15
- package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
- package/dist/astro/routes/api/setup/index.mjs +16 -16
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +4 -4
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +9 -9
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +9 -9
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +9 -9
- package/dist/astro/routes/api/taxonomies/index.mjs +9 -9
- package/dist/astro/routes/api/themes/preview.mjs +3 -3
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +4 -4
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +6 -6
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +6 -6
- package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
- package/dist/astro/routes/api/widget-areas/index.mjs +6 -6
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +4 -4
- 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 +5 -5
- package/dist/astro/types.d.mts +10 -3
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{authorize-Bkwe8kuL.mjs → authorize-Bn4S4DUT.mjs} +2 -2
- package/dist/{authorize-Bkwe8kuL.mjs.map → authorize-Bn4S4DUT.mjs.map} +1 -1
- package/dist/{byline-CTaWkMh5.mjs → byline-BDylH_m4.mjs} +3 -3
- package/dist/{byline-CTaWkMh5.mjs.map → byline-BDylH_m4.mjs.map} +1 -1
- package/dist/{bylines-DtDRNF1n.d.mts → bylines-B2_XmnSU.d.mts} +34 -34
- package/dist/{bylines-DtDRNF1n.d.mts.map → bylines-B2_XmnSU.d.mts.map} +1 -1
- package/dist/{bylines-H0Xh5TMy.mjs → bylines-B7TFEvFf.mjs} +2 -2
- package/dist/{bylines-H0Xh5TMy.mjs.map → bylines-B7TFEvFf.mjs.map} +1 -1
- package/dist/{bylines-BYHWU3T7.mjs → bylines-n6nykUyI.mjs} +6 -6
- package/dist/{bylines-BYHWU3T7.mjs.map → bylines-n6nykUyI.mjs.map} +1 -1
- package/dist/{cache-CNk1jIxp.mjs → cache-BcI1yUjR.mjs} +2 -2
- package/dist/{cache-CNk1jIxp.mjs.map → cache-BcI1yUjR.mjs.map} +1 -1
- package/dist/{chunks-BkfVdD-3.mjs → chunks-cYG4SnIP.mjs} +2 -2
- package/dist/{chunks-BkfVdD-3.mjs.map → chunks-cYG4SnIP.mjs.map} +1 -1
- package/dist/cli/index.mjs +61 -15
- 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-_yzlBYPx.mjs → comment-C76G-9tz.mjs} +2 -2
- package/dist/{comment-_yzlBYPx.mjs.map → comment-C76G-9tz.mjs.map} +1 -1
- package/dist/{comments-DxID-rsd.mjs → comments-CCxFFGY1.mjs} +3 -3
- package/dist/{comments-DxID-rsd.mjs.map → comments-CCxFFGY1.mjs.map} +1 -1
- package/dist/{content-C0ooIs-f.mjs → content-8voQNTXX.mjs} +3 -3
- package/dist/{content-C0ooIs-f.mjs.map → content-8voQNTXX.mjs.map} +1 -1
- package/dist/{context-sAnCaUIR.mjs → context-B7qiYrz2.mjs} +7 -7
- package/dist/{context-sAnCaUIR.mjs.map → context-B7qiYrz2.mjs.map} +1 -1
- package/dist/{dashboard-Cqw3ay2X.mjs → dashboard-BeaFSPpx.mjs} +4 -4
- package/dist/{dashboard-Cqw3ay2X.mjs.map → dashboard-BeaFSPpx.mjs.map} +1 -1
- package/dist/db/index.d.mts +1 -1
- package/dist/db/index.mjs +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/{error-CPh_8eLq.mjs → error-ChfADBuu.mjs} +5 -3
- 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/{fts-manager-Mnrtn-r2.mjs → fts-manager-C_b-4x8u.mjs} +2 -2
- package/dist/{fts-manager-Mnrtn-r2.mjs.map → fts-manager-C_b-4x8u.mjs.map} +1 -1
- package/dist/{index-Bv1Wf1zB.d.mts → index-BPZFAcgE.d.mts} +154 -110
- package/dist/index-BPZFAcgE.d.mts.map +1 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +38 -38
- package/dist/{load-DmXNVhst.mjs → load-CLFRjk9r.mjs} +2 -2
- package/dist/{load-DmXNVhst.mjs.map → load-CLFRjk9r.mjs.map} +1 -1
- package/dist/{loader-Chm5h7Gr.mjs → loader-D-vIJjfY.mjs} +86 -46
- package/dist/loader-D-vIJjfY.mjs.map +1 -0
- package/dist/media/local-runtime.d.mts +3 -3
- package/dist/media/local-runtime.mjs +4 -4
- package/dist/{media-oqRcNiQf.mjs → media-CKQd8AYU.mjs} +2 -2
- package/dist/{media-oqRcNiQf.mjs.map → media-CKQd8AYU.mjs.map} +1 -1
- package/dist/{menus-C75SSmRy.mjs → menus-C-nWT5Tu.mjs} +17 -11
- package/dist/menus-C-nWT5Tu.mjs.map +1 -0
- package/dist/{menus-Bjf5R1Qq.mjs → menus-arUNspyU.mjs} +2 -2
- package/dist/{menus-Bjf5R1Qq.mjs.map → menus-arUNspyU.mjs.map} +1 -1
- package/dist/{parse-3-caTKgt.mjs → parse-DHbXfvxO.mjs} +2 -2
- package/dist/{parse-3-caTKgt.mjs.map → parse-DHbXfvxO.mjs.map} +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 +3 -3
- package/dist/{query-BJn8TOPk.mjs → query-7m6-l0f_.mjs} +21 -14
- package/dist/query-7m6-l0f_.mjs.map +1 -0
- package/dist/{rate-limit-D_-gAeJ0.mjs → rate-limit-D8RAXN8b.mjs} +2 -2
- package/dist/{rate-limit-D_-gAeJ0.mjs.map → rate-limit-D8RAXN8b.mjs.map} +1 -1
- package/dist/{redirect-CNv4mHX2.mjs → redirect-CjfDGrTd.mjs} +2 -2
- package/dist/{redirect-CNv4mHX2.mjs.map → redirect-CjfDGrTd.mjs.map} +1 -1
- package/dist/{redirects-B-CUZ1Xh.mjs → redirects-CowoEHdE.mjs} +3 -3
- package/dist/{redirects-B-CUZ1Xh.mjs.map → redirects-CowoEHdE.mjs.map} +1 -1
- package/dist/{registry-DqrAQDXH.mjs → registry-Cyp-dx6J.mjs} +4 -4
- package/dist/{registry-DqrAQDXH.mjs.map → registry-Cyp-dx6J.mjs.map} +1 -1
- package/dist/resolve-D6sM-SgF.mjs +143 -0
- package/dist/resolve-D6sM-SgF.mjs.map +1 -0
- package/dist/{runner-CNHRo1mT.d.mts → runner-DSQBurMS.d.mts} +7 -4
- package/dist/runner-DSQBurMS.d.mts.map +1 -0
- package/dist/{runner-CGlojznK.mjs → runner-Drnvs96u.mjs} +20 -24
- package/dist/{runner-CGlojznK.mjs.map → runner-Drnvs96u.mjs.map} +1 -1
- package/dist/runtime.d.mts +3 -3
- package/dist/runtime.mjs +2 -2
- package/dist/{schema-Djdlfi5G.mjs → schema-CI9mYPX3.mjs} +4 -4
- package/dist/{schema-Djdlfi5G.mjs.map → schema-CI9mYPX3.mjs.map} +1 -1
- package/dist/{search-By-NN3da.mjs → search-DKz_mGBP.mjs} +4 -4
- package/dist/{search-By-NN3da.mjs.map → search-DKz_mGBP.mjs.map} +1 -1
- package/dist/{sections-DcBIlOq1.mjs → sections-DBbCDIAT.mjs} +3 -3
- package/dist/{sections-DcBIlOq1.mjs.map → sections-DBbCDIAT.mjs.map} +1 -1
- package/dist/seed/index.mjs +13 -13
- package/dist/{seo-bjDoq9Eg.mjs → seo-BGCyDlkb.mjs} +2 -2
- package/dist/{seo-bjDoq9Eg.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-BuuTdGAT.mjs → service-B0H7U1Y9.mjs} +2 -2
- package/dist/{service-BuuTdGAT.mjs.map → service-B0H7U1Y9.mjs.map} +1 -1
- package/dist/{settings-hcubRfkr.mjs → settings-BSXRtTzk.mjs} +3 -3
- package/dist/{settings-hcubRfkr.mjs.map → settings-BSXRtTzk.mjs.map} +1 -1
- package/dist/{settings-CJnKiWuR.mjs → settings-DfwNyQkf.mjs} +3 -3
- package/dist/{settings-CJnKiWuR.mjs.map → settings-DfwNyQkf.mjs.map} +1 -1
- package/dist/{taxonomies-CLs9HPE2.mjs → taxonomies-4vx0nmMr.mjs} +4 -4
- package/dist/{taxonomies-CLs9HPE2.mjs.map → taxonomies-4vx0nmMr.mjs.map} +1 -1
- package/dist/{taxonomies-WamPVA2x.mjs → taxonomies-CcvrMLbR.mjs} +7 -7
- package/dist/{taxonomies-WamPVA2x.mjs.map → taxonomies-CcvrMLbR.mjs.map} +1 -1
- package/dist/{taxonomy-D4Uc2LsZ.mjs → taxonomy-zqGQUqgu.mjs} +3 -3
- package/dist/{taxonomy-D4Uc2LsZ.mjs.map → taxonomy-zqGQUqgu.mjs.map} +1 -1
- package/dist/{transport-DOxLfUir.d.mts → transport-C2MGqtL6.d.mts} +1 -1
- package/dist/{transport-DOxLfUir.d.mts.map → transport-C2MGqtL6.d.mts.map} +1 -1
- package/dist/{types-ByV5sgsv.mjs → types-B0bmgwMG.mjs} +2 -2
- package/dist/{types-ByV5sgsv.mjs.map → types-B0bmgwMG.mjs.map} +1 -1
- package/dist/{user-D3BD5zdT.mjs → user-hUSOaIJy.mjs} +2 -2
- package/dist/{user-D3BD5zdT.mjs.map → user-hUSOaIJy.mjs.map} +1 -1
- package/dist/{validate-mz87i8_1.mjs → validate-IGltez8n.mjs} +2 -2
- package/dist/{validate-mz87i8_1.mjs.map → validate-IGltez8n.mjs.map} +1 -1
- package/dist/{validation-DKHhXjPr.mjs → validation-Bmymau7y.mjs} +6 -6
- package/dist/{validation-DKHhXjPr.mjs.map → validation-Bmymau7y.mjs.map} +1 -1
- package/dist/version-BTc87L3L.mjs +7 -0
- package/dist/{version-Ct7C6RSo.mjs.map → version-BTc87L3L.mjs.map} +1 -1
- package/dist/{widgets-lShIQXU5.mjs → widgets-yHQa4c6c.mjs} +2 -2
- package/dist/{widgets-lShIQXU5.mjs.map → widgets-yHQa4c6c.mjs.map} +1 -1
- package/dist/{zod-generator-dvxgmd1M.mjs → zod-generator-B80aap1J.mjs} +2 -2
- package/dist/{zod-generator-dvxgmd1M.mjs.map → zod-generator-B80aap1J.mjs.map} +1 -1
- package/package.json +7 -7
- package/src/api/errors.ts +2 -0
- package/src/api/handlers/index.ts +2 -0
- package/src/api/handlers/registry.ts +69 -1
- package/src/api/handlers/seo.ts +16 -1
- package/src/api/handlers/snapshot.ts +1 -1
- package/src/astro/integration/index.ts +26 -0
- package/src/astro/integration/routes.ts +5 -0
- package/src/astro/integration/runtime.ts +8 -0
- package/src/astro/middleware.ts +4 -0
- package/src/astro/public-plugin-api-routes.ts +41 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +4 -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/import/wordpress/rewrite-url-helpers.ts +22 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +5 -2
- package/src/astro/routes/sitemap-[collection].xml.ts +114 -14
- package/src/astro/types.ts +14 -0
- 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/runner.ts +29 -21
- package/src/emdash-runtime.ts +1 -0
- package/src/i18n/resolve.ts +152 -0
- package/src/index.ts +2 -0
- package/src/loader.ts +133 -59
- package/src/plugin-utils.ts +23 -0
- package/src/query.ts +24 -5
- package/src/utils/db-errors.ts +24 -0
- package/dist/connection-2igzM-AT.mjs +0 -57
- package/dist/connection-2igzM-AT.mjs.map +0 -1
- package/dist/db-errors-CGN9kJfo.mjs.map +0 -1
- package/dist/error-CPh_8eLq.mjs.map +0 -1
- package/dist/index-Bv1Wf1zB.d.mts.map +0 -1
- package/dist/loader-Chm5h7Gr.mjs.map +0 -1
- package/dist/menus-C75SSmRy.mjs.map +0 -1
- package/dist/query-BJn8TOPk.mjs.map +0 -1
- package/dist/resolve-Cj98DuqN.mjs +0 -39
- package/dist/resolve-Cj98DuqN.mjs.map +0 -1
- package/dist/runner-CNHRo1mT.d.mts.map +0 -1
- package/dist/seo-BoR4wCUh.mjs.map +0 -1
- package/dist/version-Ct7C6RSo.mjs +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-oqRcNiQf.mjs","names":[],"sources":["../src/database/repositories/media.ts"],"sourcesContent":["import { sql, type ExpressionBuilder, type Kysely, type SqlBool } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database, MediaRow } from \"../types.js\";\nimport type { FindManyResult } from \"./types.js\";\nimport { encodeCursor, decodeCursor } from \"./types.js\";\n\n/** Escape LIKE wildcard characters and the escape char itself in user-supplied values */\nfunction escapeLike(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"%\", \"\\\\%\").replaceAll(\"_\", \"\\\\_\");\n}\n\n/**\n * Normalize a mimeType filter (string or array) into a clean string[].\n * Entries that are empty strings are dropped.\n */\nfunction normalizeMimeFilter(input?: string | readonly string[]): string[] {\n\tif (!input) return [];\n\tconst arr = Array.isArray(input) ? input : [input];\n\treturn arr\n\t\t.filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0)\n\t\t.map((entry) =>\n\t\t\tentry.endsWith(\"/\") ? entry.toLowerCase() : entry.split(\";\")[0].trim().toLowerCase(),\n\t\t);\n}\n\n/**\n * Build a WHERE clause that matches `mime_type` against any of the given\n * filter entries — exact equality for full MIMEs, LIKE prefix for entries\n * ending in \"/\".\n */\nfunction mimeMatchExpr(eb: ExpressionBuilder<Database, \"media\">, filters: string[]) {\n\treturn eb.or(\n\t\tfilters.map((entry) =>\n\t\t\tentry.endsWith(\"/\")\n\t\t\t\t? sql<SqlBool>`mime_type LIKE ${`${escapeLike(entry)}%`} ESCAPE '\\\\'`\n\t\t\t\t: eb(\"mime_type\", \"=\", entry),\n\t\t),\n\t);\n}\n\nexport type MediaStatus = \"pending\" | \"ready\" | \"failed\";\n\nexport interface MediaItem {\n\tid: string;\n\tfilename: string;\n\tmimeType: string;\n\tsize: number | null;\n\twidth: number | null;\n\theight: number | null;\n\talt: string | null;\n\tcaption: string | null;\n\tstorageKey: string;\n\tstatus: MediaStatus;\n\tcontentHash: string | null;\n\tblurhash: string | null;\n\tdominantColor: string | null;\n\tcreatedAt: string;\n\tauthorId: string | null;\n}\n\nexport interface CreateMediaInput {\n\tfilename: string;\n\tmimeType: string;\n\tsize?: number;\n\twidth?: number;\n\theight?: number;\n\talt?: string;\n\tcaption?: string;\n\tstorageKey: string;\n\tcontentHash?: string;\n\tblurhash?: string;\n\tdominantColor?: string;\n\tstatus?: MediaStatus;\n\tauthorId?: string;\n}\n\nexport interface FindManyMediaOptions {\n\tlimit?: number;\n\tcursor?: string;\n\t/** Filter by MIME type. Pass a string for a single prefix/exact, or an array to match any. Strings ending with \"/\" are treated as LIKE prefix matches; others are exact equality. */\n\tmimeType?: string | readonly string[];\n\tstatus?: MediaStatus | \"all\"; // Filter by status, defaults to \"ready\"\n}\n\n/**\n * Media repository for database operations\n */\nexport class MediaRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t/**\n\t * Create a new media item\n\t */\n\tasync create(input: CreateMediaInput): Promise<MediaItem> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tconst row: Omit<MediaRow, \"rowid\"> = {\n\t\t\tid,\n\t\t\tfilename: input.filename,\n\t\t\tmime_type: input.mimeType,\n\t\t\tsize: input.size ?? null,\n\t\t\twidth: input.width ?? null,\n\t\t\theight: input.height ?? null,\n\t\t\talt: input.alt ?? null,\n\t\t\tcaption: input.caption ?? null,\n\t\t\tstorage_key: input.storageKey,\n\t\t\tcontent_hash: input.contentHash ?? null,\n\t\t\tblurhash: input.blurhash ?? null,\n\t\t\tdominant_color: input.dominantColor ?? null,\n\t\t\tstatus: input.status ?? \"ready\",\n\t\t\tcreated_at: now,\n\t\t\tauthor_id: input.authorId ?? null,\n\t\t};\n\n\t\tawait this.db.insertInto(\"media\").values(row).execute();\n\n\t\treturn this.rowToItem(row as MediaRow);\n\t}\n\n\t/**\n\t * Create a pending media item (for signed URL upload flow)\n\t */\n\tasync createPending(input: {\n\t\tfilename: string;\n\t\tmimeType: string;\n\t\tsize?: number;\n\t\tstorageKey: string;\n\t\tcontentHash?: string;\n\t\tauthorId?: string;\n\t}): Promise<MediaItem> {\n\t\treturn this.create({\n\t\t\t...input,\n\t\t\tstatus: \"pending\",\n\t\t});\n\t}\n\n\t/**\n\t * Confirm upload (mark as ready)\n\t */\n\tasync confirmUpload(\n\t\tid: string,\n\t\tmetadata?: { width?: number; height?: number; size?: number },\n\t): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updates: Partial<MediaRow> = {\n\t\t\tstatus: \"ready\",\n\t\t};\n\t\tif (metadata?.width !== undefined) updates.width = metadata.width;\n\t\tif (metadata?.height !== undefined) updates.height = metadata.height;\n\t\tif (metadata?.size !== undefined) updates.size = metadata.size;\n\n\t\tawait this.db.updateTable(\"media\").set(updates).where(\"id\", \"=\", id).execute();\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Mark upload as failed\n\t */\n\tasync markFailed(id: string): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tawait this.db.updateTable(\"media\").set({ status: \"failed\" }).where(\"id\", \"=\", id).execute();\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Find media by ID\n\t */\n\tasync findById(id: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find media by filename\n\t * Useful for idempotent imports\n\t */\n\tasync findByFilename(filename: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"filename\", \"=\", filename)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find media by content hash\n\t * Used for deduplication - same content = same hash\n\t */\n\tasync findByContentHash(contentHash: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"content_hash\", \"=\", contentHash)\n\t\t\t.where(\"status\", \"=\", \"ready\")\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find many media items with cursor pagination\n\t *\n\t * Uses keyset pagination (cursor-based) for consistent results.\n\t * The cursor encodes the created_at and id of the last item.\n\t */\n\tasync findMany(options: FindManyMediaOptions = {}): Promise<FindManyResult<MediaItem>> {\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\t// Handle cursor-based pagination — throws on invalid cursor.\n\t\tif (options.cursor) {\n\t\t\tconst { orderValue: createdAt, id: cursorId } = decodeCursor(options.cursor);\n\n\t\t\t// Keyset pagination: get items where (created_at, id) < cursor\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", createdAt),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", createdAt), eb(\"id\", \"<\", cursorId)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tconst mimeFilters = normalizeMimeFilter(options.mimeType);\n\t\tif (mimeFilters.length > 0) {\n\t\t\tquery = query.where((eb) => mimeMatchExpr(eb, mimeFilters));\n\t\t}\n\n\t\t// Default to only showing ready items\n\t\tif (options.status !== \"all\") {\n\t\t\tquery = query.where(\"status\", \"=\", options.status ?? \"ready\");\n\t\t}\n\n\t\tconst rows = await query.execute();\n\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit).map((row) => this.rowToItem(row));\n\n\t\tlet nextCursor: string | undefined;\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst lastItem = items.at(-1)!;\n\t\t\tnextCursor = encodeCursor(lastItem.createdAt, lastItem.id);\n\t\t}\n\n\t\treturn { items, nextCursor };\n\t}\n\n\t/**\n\t * Update media metadata\n\t */\n\tasync update(\n\t\tid: string,\n\t\tinput: Partial<Pick<CreateMediaInput, \"alt\" | \"caption\" | \"width\" | \"height\">>,\n\t): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updates: Partial<MediaRow> = {};\n\t\tif (input.alt !== undefined) updates.alt = input.alt;\n\t\tif (input.caption !== undefined) updates.caption = input.caption;\n\t\tif (input.width !== undefined) updates.width = input.width;\n\t\tif (input.height !== undefined) updates.height = input.height;\n\n\t\tif (Object.keys(updates).length > 0) {\n\t\t\tawait this.db.updateTable(\"media\").set(updates).where(\"id\", \"=\", id).execute();\n\t\t}\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Delete media item\n\t */\n\tasync delete(id: string): Promise<boolean> {\n\t\tconst result = await this.db.deleteFrom(\"media\").where(\"id\", \"=\", id).executeTakeFirst();\n\n\t\treturn (result.numDeletedRows ?? 0) > 0;\n\t}\n\n\t/**\n\t * Count media items\n\t */\n\tasync count(mimeType?: string | readonly string[]): Promise<number> {\n\t\tconst filters = normalizeMimeFilter(mimeType);\n\t\tlet query = this.db.selectFrom(\"media\").select((eb) => eb.fn.count<number>(\"id\").as(\"count\"));\n\n\t\tif (filters.length > 0) {\n\t\t\tquery = query.where((eb) => mimeMatchExpr(eb, filters));\n\t\t}\n\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result?.count || 0);\n\t}\n\n\t/**\n\t * Delete pending uploads older than the given age.\n\t * Pending uploads that were never confirmed indicate abandoned upload flows.\n\t *\n\t * Returns the storage keys of deleted rows so callers can remove the\n\t * corresponding files from object storage.\n\t */\n\tasync cleanupPendingUploads(maxAgeMs: number = 60 * 60 * 1000): Promise<string[]> {\n\t\tconst cutoff = new Date(Date.now() - maxAgeMs).toISOString();\n\n\t\t// Select the storage keys first -- SQLite doesn't support RETURNING\n\t\t// on DELETE in all drivers, and Kysely's RETURNING isn't universal.\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.select(\"storage_key\")\n\t\t\t.where(\"status\", \"=\", \"pending\")\n\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t.execute();\n\n\t\tif (rows.length === 0) return [];\n\n\t\tawait this.db\n\t\t\t.deleteFrom(\"media\")\n\t\t\t.where(\"status\", \"=\", \"pending\")\n\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t.execute();\n\n\t\treturn rows.map((r) => r.storage_key);\n\t}\n\n\t/**\n\t * Convert database row to MediaItem\n\t */\n\tprivate rowToItem(row: MediaRow): MediaItem {\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\tfilename: row.filename,\n\t\t\tmimeType: row.mime_type,\n\t\t\tsize: row.size,\n\t\t\twidth: row.width,\n\t\t\theight: row.height,\n\t\t\talt: row.alt,\n\t\t\tcaption: row.caption,\n\t\t\tstorageKey: row.storage_key,\n\t\t\tcontentHash: row.content_hash,\n\t\t\tblurhash: row.blurhash,\n\t\t\tdominantColor: row.dominant_color,\n\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow\n\t\t\tstatus: row.status as MediaStatus,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tauthorId: row.author_id,\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"media-CKQd8AYU.mjs","names":[],"sources":["../src/database/repositories/media.ts"],"sourcesContent":["import { sql, type ExpressionBuilder, type Kysely, type SqlBool } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database, MediaRow } from \"../types.js\";\nimport type { FindManyResult } from \"./types.js\";\nimport { encodeCursor, decodeCursor } from \"./types.js\";\n\n/** Escape LIKE wildcard characters and the escape char itself in user-supplied values */\nfunction escapeLike(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"%\", \"\\\\%\").replaceAll(\"_\", \"\\\\_\");\n}\n\n/**\n * Normalize a mimeType filter (string or array) into a clean string[].\n * Entries that are empty strings are dropped.\n */\nfunction normalizeMimeFilter(input?: string | readonly string[]): string[] {\n\tif (!input) return [];\n\tconst arr = Array.isArray(input) ? input : [input];\n\treturn arr\n\t\t.filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0)\n\t\t.map((entry) =>\n\t\t\tentry.endsWith(\"/\") ? entry.toLowerCase() : entry.split(\";\")[0].trim().toLowerCase(),\n\t\t);\n}\n\n/**\n * Build a WHERE clause that matches `mime_type` against any of the given\n * filter entries — exact equality for full MIMEs, LIKE prefix for entries\n * ending in \"/\".\n */\nfunction mimeMatchExpr(eb: ExpressionBuilder<Database, \"media\">, filters: string[]) {\n\treturn eb.or(\n\t\tfilters.map((entry) =>\n\t\t\tentry.endsWith(\"/\")\n\t\t\t\t? sql<SqlBool>`mime_type LIKE ${`${escapeLike(entry)}%`} ESCAPE '\\\\'`\n\t\t\t\t: eb(\"mime_type\", \"=\", entry),\n\t\t),\n\t);\n}\n\nexport type MediaStatus = \"pending\" | \"ready\" | \"failed\";\n\nexport interface MediaItem {\n\tid: string;\n\tfilename: string;\n\tmimeType: string;\n\tsize: number | null;\n\twidth: number | null;\n\theight: number | null;\n\talt: string | null;\n\tcaption: string | null;\n\tstorageKey: string;\n\tstatus: MediaStatus;\n\tcontentHash: string | null;\n\tblurhash: string | null;\n\tdominantColor: string | null;\n\tcreatedAt: string;\n\tauthorId: string | null;\n}\n\nexport interface CreateMediaInput {\n\tfilename: string;\n\tmimeType: string;\n\tsize?: number;\n\twidth?: number;\n\theight?: number;\n\talt?: string;\n\tcaption?: string;\n\tstorageKey: string;\n\tcontentHash?: string;\n\tblurhash?: string;\n\tdominantColor?: string;\n\tstatus?: MediaStatus;\n\tauthorId?: string;\n}\n\nexport interface FindManyMediaOptions {\n\tlimit?: number;\n\tcursor?: string;\n\t/** Filter by MIME type. Pass a string for a single prefix/exact, or an array to match any. Strings ending with \"/\" are treated as LIKE prefix matches; others are exact equality. */\n\tmimeType?: string | readonly string[];\n\tstatus?: MediaStatus | \"all\"; // Filter by status, defaults to \"ready\"\n}\n\n/**\n * Media repository for database operations\n */\nexport class MediaRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\t/**\n\t * Create a new media item\n\t */\n\tasync create(input: CreateMediaInput): Promise<MediaItem> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tconst row: Omit<MediaRow, \"rowid\"> = {\n\t\t\tid,\n\t\t\tfilename: input.filename,\n\t\t\tmime_type: input.mimeType,\n\t\t\tsize: input.size ?? null,\n\t\t\twidth: input.width ?? null,\n\t\t\theight: input.height ?? null,\n\t\t\talt: input.alt ?? null,\n\t\t\tcaption: input.caption ?? null,\n\t\t\tstorage_key: input.storageKey,\n\t\t\tcontent_hash: input.contentHash ?? null,\n\t\t\tblurhash: input.blurhash ?? null,\n\t\t\tdominant_color: input.dominantColor ?? null,\n\t\t\tstatus: input.status ?? \"ready\",\n\t\t\tcreated_at: now,\n\t\t\tauthor_id: input.authorId ?? null,\n\t\t};\n\n\t\tawait this.db.insertInto(\"media\").values(row).execute();\n\n\t\treturn this.rowToItem(row as MediaRow);\n\t}\n\n\t/**\n\t * Create a pending media item (for signed URL upload flow)\n\t */\n\tasync createPending(input: {\n\t\tfilename: string;\n\t\tmimeType: string;\n\t\tsize?: number;\n\t\tstorageKey: string;\n\t\tcontentHash?: string;\n\t\tauthorId?: string;\n\t}): Promise<MediaItem> {\n\t\treturn this.create({\n\t\t\t...input,\n\t\t\tstatus: \"pending\",\n\t\t});\n\t}\n\n\t/**\n\t * Confirm upload (mark as ready)\n\t */\n\tasync confirmUpload(\n\t\tid: string,\n\t\tmetadata?: { width?: number; height?: number; size?: number },\n\t): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updates: Partial<MediaRow> = {\n\t\t\tstatus: \"ready\",\n\t\t};\n\t\tif (metadata?.width !== undefined) updates.width = metadata.width;\n\t\tif (metadata?.height !== undefined) updates.height = metadata.height;\n\t\tif (metadata?.size !== undefined) updates.size = metadata.size;\n\n\t\tawait this.db.updateTable(\"media\").set(updates).where(\"id\", \"=\", id).execute();\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Mark upload as failed\n\t */\n\tasync markFailed(id: string): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tawait this.db.updateTable(\"media\").set({ status: \"failed\" }).where(\"id\", \"=\", id).execute();\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Find media by ID\n\t */\n\tasync findById(id: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find media by filename\n\t * Useful for idempotent imports\n\t */\n\tasync findByFilename(filename: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"filename\", \"=\", filename)\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find media by content hash\n\t * Used for deduplication - same content = same hash\n\t */\n\tasync findByContentHash(contentHash: string): Promise<MediaItem | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.where(\"content_hash\", \"=\", contentHash)\n\t\t\t.where(\"status\", \"=\", \"ready\")\n\t\t\t.executeTakeFirst();\n\n\t\treturn row ? this.rowToItem(row) : null;\n\t}\n\n\t/**\n\t * Find many media items with cursor pagination\n\t *\n\t * Uses keyset pagination (cursor-based) for consistent results.\n\t * The cursor encodes the created_at and id of the last item.\n\t */\n\tasync findMany(options: FindManyMediaOptions = {}): Promise<FindManyResult<MediaItem>> {\n\t\tconst limit = Math.min(options.limit || 50, 100);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.selectAll()\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\t// Handle cursor-based pagination — throws on invalid cursor.\n\t\tif (options.cursor) {\n\t\t\tconst { orderValue: createdAt, id: cursorId } = decodeCursor(options.cursor);\n\n\t\t\t// Keyset pagination: get items where (created_at, id) < cursor\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", createdAt),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", createdAt), eb(\"id\", \"<\", cursorId)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tconst mimeFilters = normalizeMimeFilter(options.mimeType);\n\t\tif (mimeFilters.length > 0) {\n\t\t\tquery = query.where((eb) => mimeMatchExpr(eb, mimeFilters));\n\t\t}\n\n\t\t// Default to only showing ready items\n\t\tif (options.status !== \"all\") {\n\t\t\tquery = query.where(\"status\", \"=\", options.status ?? \"ready\");\n\t\t}\n\n\t\tconst rows = await query.execute();\n\n\t\tconst hasMore = rows.length > limit;\n\t\tconst items = rows.slice(0, limit).map((row) => this.rowToItem(row));\n\n\t\tlet nextCursor: string | undefined;\n\t\tif (hasMore && items.length > 0) {\n\t\t\tconst lastItem = items.at(-1)!;\n\t\t\tnextCursor = encodeCursor(lastItem.createdAt, lastItem.id);\n\t\t}\n\n\t\treturn { items, nextCursor };\n\t}\n\n\t/**\n\t * Update media metadata\n\t */\n\tasync update(\n\t\tid: string,\n\t\tinput: Partial<Pick<CreateMediaInput, \"alt\" | \"caption\" | \"width\" | \"height\">>,\n\t): Promise<MediaItem | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updates: Partial<MediaRow> = {};\n\t\tif (input.alt !== undefined) updates.alt = input.alt;\n\t\tif (input.caption !== undefined) updates.caption = input.caption;\n\t\tif (input.width !== undefined) updates.width = input.width;\n\t\tif (input.height !== undefined) updates.height = input.height;\n\n\t\tif (Object.keys(updates).length > 0) {\n\t\t\tawait this.db.updateTable(\"media\").set(updates).where(\"id\", \"=\", id).execute();\n\t\t}\n\n\t\treturn this.findById(id);\n\t}\n\n\t/**\n\t * Delete media item\n\t */\n\tasync delete(id: string): Promise<boolean> {\n\t\tconst result = await this.db.deleteFrom(\"media\").where(\"id\", \"=\", id).executeTakeFirst();\n\n\t\treturn (result.numDeletedRows ?? 0) > 0;\n\t}\n\n\t/**\n\t * Count media items\n\t */\n\tasync count(mimeType?: string | readonly string[]): Promise<number> {\n\t\tconst filters = normalizeMimeFilter(mimeType);\n\t\tlet query = this.db.selectFrom(\"media\").select((eb) => eb.fn.count<number>(\"id\").as(\"count\"));\n\n\t\tif (filters.length > 0) {\n\t\t\tquery = query.where((eb) => mimeMatchExpr(eb, filters));\n\t\t}\n\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result?.count || 0);\n\t}\n\n\t/**\n\t * Delete pending uploads older than the given age.\n\t * Pending uploads that were never confirmed indicate abandoned upload flows.\n\t *\n\t * Returns the storage keys of deleted rows so callers can remove the\n\t * corresponding files from object storage.\n\t */\n\tasync cleanupPendingUploads(maxAgeMs: number = 60 * 60 * 1000): Promise<string[]> {\n\t\tconst cutoff = new Date(Date.now() - maxAgeMs).toISOString();\n\n\t\t// Select the storage keys first -- SQLite doesn't support RETURNING\n\t\t// on DELETE in all drivers, and Kysely's RETURNING isn't universal.\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"media\")\n\t\t\t.select(\"storage_key\")\n\t\t\t.where(\"status\", \"=\", \"pending\")\n\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t.execute();\n\n\t\tif (rows.length === 0) return [];\n\n\t\tawait this.db\n\t\t\t.deleteFrom(\"media\")\n\t\t\t.where(\"status\", \"=\", \"pending\")\n\t\t\t.where(\"created_at\", \"<\", cutoff)\n\t\t\t.execute();\n\n\t\treturn rows.map((r) => r.storage_key);\n\t}\n\n\t/**\n\t * Convert database row to MediaItem\n\t */\n\tprivate rowToItem(row: MediaRow): MediaItem {\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\tfilename: row.filename,\n\t\t\tmimeType: row.mime_type,\n\t\t\tsize: row.size,\n\t\t\twidth: row.width,\n\t\t\theight: row.height,\n\t\t\talt: row.alt,\n\t\t\tcaption: row.caption,\n\t\t\tstorageKey: row.storage_key,\n\t\t\tcontentHash: row.content_hash,\n\t\t\tblurhash: row.blurhash,\n\t\t\tdominantColor: row.dominant_color,\n\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow\n\t\t\tstatus: row.status as MediaStatus,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tauthorId: row.author_id,\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
|
|
2
|
-
import { t as CommentRepository } from "./comment-
|
|
2
|
+
import { t as CommentRepository } from "./comment-C76G-9tz.mjs";
|
|
3
3
|
import { t as OptionsRepository } from "./options-BL4X94qY.mjs";
|
|
4
|
-
import { t as PluginContextFactory } from "./context-
|
|
4
|
+
import { t as PluginContextFactory } from "./context-B7qiYrz2.mjs";
|
|
5
5
|
import { n as requestCached } from "./request-cache-dzCt8TZB.mjs";
|
|
6
|
-
import { r as getDb } from "./loader-
|
|
7
|
-
import {
|
|
6
|
+
import { r as getDb } from "./loader-D-vIJjfY.mjs";
|
|
7
|
+
import { i as resolveLocaleChain, r as resolveLocale } from "./resolve-D6sM-SgF.mjs";
|
|
8
8
|
import { r as normalizeCapabilities } from "./types-1NNkmTIn.mjs";
|
|
9
9
|
import { dt as sanitizeHref } from "./redirects-COMLwsV5.mjs";
|
|
10
10
|
import { t as extractRequestMeta } from "./request-meta-C_Cjii-T.mjs";
|
|
11
11
|
import { r as setCronTasksEnabled } from "./cron-Bd3b3iuj.mjs";
|
|
12
12
|
import { sql } from "kysely";
|
|
13
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
14
13
|
import { ulid } from "ulidx";
|
|
15
14
|
import { z } from "astro/zod";
|
|
15
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
16
16
|
|
|
17
17
|
//#region src/fields/image.ts
|
|
18
18
|
const imageSchema = z.object({
|
|
@@ -374,7 +374,8 @@ function portableTextToProsemirror(blocks) {
|
|
|
374
374
|
const listType = block.listItem;
|
|
375
375
|
while (i < blocks.length) {
|
|
376
376
|
const current = blocks[i];
|
|
377
|
-
if (isTextBlock(current)
|
|
377
|
+
if (!isTextBlock(current) || !current.listItem) break;
|
|
378
|
+
if ((current.level || 1) > 1 || current.listItem === listType) {
|
|
378
379
|
listBlocks.push(current);
|
|
379
380
|
i++;
|
|
380
381
|
} else break;
|
|
@@ -497,20 +498,25 @@ function convertListItem(item, nestedItems, parentListType) {
|
|
|
497
498
|
content: spans.length > 0 ? spans : void 0
|
|
498
499
|
});
|
|
499
500
|
if (nestedItems.length > 0) {
|
|
501
|
+
let minLevel = Infinity;
|
|
502
|
+
for (const ni of nestedItems) {
|
|
503
|
+
const level = ni.level || 2;
|
|
504
|
+
if (level < minLevel) minLevel = level;
|
|
505
|
+
}
|
|
500
506
|
let j = 0;
|
|
501
507
|
while (j < nestedItems.length) {
|
|
502
|
-
const
|
|
508
|
+
const anchorType = nestedItems[j].listItem || parentListType;
|
|
503
509
|
const nestedGroup = [];
|
|
504
|
-
|
|
510
|
+
do {
|
|
505
511
|
nestedGroup.push(nestedItems[j]);
|
|
506
512
|
j++;
|
|
507
|
-
}
|
|
513
|
+
} while (j < nestedItems.length && ((nestedItems[j].level || 2) > minLevel || (nestedItems[j].listItem || parentListType) === anchorType));
|
|
508
514
|
if (nestedGroup.length > 0) {
|
|
509
515
|
const adjustedGroup = nestedGroup.map((ni) => ({
|
|
510
516
|
...ni,
|
|
511
517
|
level: (ni.level || 2) - 1
|
|
512
518
|
}));
|
|
513
|
-
content.push(convertList(adjustedGroup,
|
|
519
|
+
content.push(convertList(adjustedGroup, anchorType));
|
|
514
520
|
}
|
|
515
521
|
}
|
|
516
522
|
}
|
|
@@ -2804,4 +2810,4 @@ async function resolveTaxonomyUrl(referenceGroup, db, locale) {
|
|
|
2804
2810
|
|
|
2805
2811
|
//#endregion
|
|
2806
2812
|
export { file as C, reference as S, definePlugin as _, SandboxUnavailableError as a, prosemirrorToPortableText as b, createNoopSandboxRunner as c, PluginRouteError as d, PluginRouteRegistry as f, resolveExclusiveHooks as g, createHookPipeline as h, getComments as i, PluginManager as l, HookPipeline as m, getMenus as n, NoopSandboxRunner as o, EmailPipeline as p, getCommentCount as r, SandboxNotAvailableError as s, getMenu as t, createPluginManager as u, after as v, image as w, portableText as x, portableTextToProsemirror as y };
|
|
2807
|
-
//# sourceMappingURL=menus-
|
|
2813
|
+
//# sourceMappingURL=menus-C-nWT5Tu.mjs.map
|