emdash 0.32.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-C0ONzkUP.d.mts → adapters-BMyNSSZi.d.mts} +9 -1
- package/dist/adapters-BMyNSSZi.d.mts.map +1 -0
- package/dist/after-CBU2vkoO.mjs +96 -0
- package/dist/after-CBU2vkoO.mjs.map +1 -0
- package/dist/{allowed-origins-CCEi9bPI.mjs → allowed-origins-CG1pACtS.mjs} +2 -2
- package/dist/{allowed-origins-CCEi9bPI.mjs.map → allowed-origins-CG1pACtS.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -4
- package/dist/api/route-utils.d.mts.map +1 -1
- package/dist/api/route-utils.mjs +22 -22
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -5
- package/dist/{api-DgPbMlng.mjs → api-D2hunekQ.mjs} +247 -45
- package/dist/api-D2hunekQ.mjs.map +1 -0
- package/dist/{api-tokens-p-iMzvXR.mjs → api-tokens-CSND0i1z.mjs} +2 -2
- package/dist/{api-tokens-p-iMzvXR.mjs.map → api-tokens-CSND0i1z.mjs.map} +1 -1
- package/dist/{apply-1_6ra7NP.mjs → apply-kwNEJW2l.mjs} +35 -22
- package/dist/apply-kwNEJW2l.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -12
- package/dist/astro/index.mjs +13 -3
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -10
- package/dist/astro/middleware/auth.mjs +8 -8
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +8 -8
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +4 -4
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +10 -10
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +344 -173
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +18 -18
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +18 -18
- package/dist/astro/routes/api/admin/bylines/index.mjs +18 -18
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +16 -16
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/bulk.mjs +12 -12
- package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
- package/dist/astro/routes/api/admin/comments/index.mjs +12 -12
- 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/media-usage/repair.mjs +12 -12
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +46 -45
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +46 -45
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +46 -45
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +46 -45
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +45 -44
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +45 -44
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +45 -44
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- 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 +8 -8
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/index.mjs +7 -7
- package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
- package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/invite/index.mjs +10 -10
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
- package/dist/astro/routes/api/auth/logout.mjs +3 -3
- package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -12
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
- package/dist/astro/routes/api/auth/me.mjs +8 -8
- package/dist/astro/routes/api/auth/mode.mjs +3 -3
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
- package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/options.mjs +13 -13
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/request.mjs +12 -12
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +18 -18
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +15 -15
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -13
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -18
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +16 -16
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/authors.mjs +3 -3
- package/dist/astro/routes/api/content/_collection_/index.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
- package/dist/astro/routes/api/dashboard.mjs +9 -9
- package/dist/astro/routes/api/dev/emails.mjs +3 -3
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +19 -19
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/execute.mjs +15 -15
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +12 -12
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +19 -19
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -11
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +27 -27
- package/dist/astro/routes/api/manifest.mjs +5 -5
- package/dist/astro/routes/api/mcp.mjs +42 -42
- package/dist/astro/routes/api/media/_id_/confirm.mjs +10 -10
- package/dist/astro/routes/api/media/_id_/upload.mjs +6 -6
- package/dist/astro/routes/api/media/_id_/usage.mjs +14 -14
- package/dist/astro/routes/api/media/_id_.mjs +13 -13
- 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 +9 -9
- package/dist/astro/routes/api/media.mjs +13 -13
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/items.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_/translations.mjs +11 -11
- package/dist/astro/routes/api/menus/_name_.mjs +11 -11
- package/dist/astro/routes/api/menus/index.mjs +11 -11
- package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +3 -3
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.mjs +6 -6
- package/dist/astro/routes/api/openapi.json.mjs +36 -5
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +5 -5
- package/dist/astro/routes/api/redirects/404s/index.mjs +12 -12
- package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -12
- package/dist/astro/routes/api/redirects/_id_.mjs +14 -13
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +14 -13
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +18 -18
- package/dist/astro/routes/api/relations/_id_/translations.mjs +13 -13
- package/dist/astro/routes/api/relations/index.mjs +18 -18
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +45 -44
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +45 -44
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +45 -44
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +45 -44
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +45 -44
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/reorder.d.mts +8 -0
- package/dist/astro/routes/api/schema/collections/reorder.d.mts.map +1 -0
- package/dist/astro/routes/api/schema/collections/reorder.mjs +66 -0
- package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -0
- package/dist/astro/routes/api/schema/index.mjs +11 -9
- package/dist/astro/routes/api/schema/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +45 -44
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +45 -44
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.d.mts +1 -0
- package/dist/astro/routes/api/search/enable.d.mts.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +17 -13
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +11 -11
- package/dist/astro/routes/api/search/rebuild.mjs +13 -13
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +7 -7
- package/dist/astro/routes/api/search/suggest.mjs +11 -11
- package/dist/astro/routes/api/sections/_slug_.mjs +11 -11
- package/dist/astro/routes/api/sections/index.mjs +11 -11
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +6 -6
- package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
- package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +16 -16
- package/dist/astro/routes/api/setup/admin-verify.mjs +13 -13
- package/dist/astro/routes/api/setup/admin.mjs +12 -12
- package/dist/astro/routes/api/setup/dev-bypass.mjs +30 -30
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +32 -32
- package/dist/astro/routes/api/setup/status.mjs +4 -4
- package/dist/astro/routes/api/snapshot.mjs +9 -9
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts +8 -0
- package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -0
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +43 -0
- package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -0
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +16 -16
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +16 -16
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +16 -16
- package/dist/astro/routes/api/taxonomies/index.mjs +16 -16
- package/dist/astro/routes/api/themes/preview.mjs +7 -7
- package/dist/astro/routes/api/typegen.mjs +5 -5
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -8
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +11 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +11 -11
- package/dist/astro/routes/api/widget-areas/_name_.mjs +6 -6
- package/dist/astro/routes/api/widget-areas/index.mjs +11 -11
- package/dist/astro/routes/api/widget-components.mjs +3 -3
- package/dist/astro/routes/robots.txt.mjs +9 -9
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
- package/dist/astro/routes/sitemap.xml.mjs +10 -10
- package/dist/astro/types.d.mts +19 -13
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-R5iYYrpa.mjs → authorize-qRhWQnel.mjs} +2 -2
- package/dist/{authorize-R5iYYrpa.mjs.map → authorize-qRhWQnel.mjs.map} +1 -1
- package/dist/{backup-LpQ1V_sR.mjs → backup-CtA6LDNw.mjs} +5 -5
- package/dist/{backup-LpQ1V_sR.mjs.map → backup-CtA6LDNw.mjs.map} +1 -1
- package/dist/{byline-C5TAqs8N.mjs → byline-Cp6csL84.mjs} +9 -9
- package/dist/{byline-C5TAqs8N.mjs.map → byline-Cp6csL84.mjs.map} +1 -1
- package/dist/{byline-fields-T9ZLZMxJ.mjs → byline-fields-CNc0Yq5i.mjs} +2 -2
- package/dist/{byline-fields-T9ZLZMxJ.mjs.map → byline-fields-CNc0Yq5i.mjs.map} +1 -1
- package/dist/{byline-registry-BCuOp4UF.mjs → byline-registry-ZkPKqEwC.mjs} +4 -4
- package/dist/{byline-registry-BCuOp4UF.mjs.map → byline-registry-ZkPKqEwC.mjs.map} +1 -1
- package/dist/{bylines-B8-WGdja.mjs → bylines-CEj5CdT4.mjs} +7 -7
- package/dist/{bylines-B8-WGdja.mjs.map → bylines-CEj5CdT4.mjs.map} +1 -1
- package/dist/{bylines-DGuqBLjV.mjs → bylines-cf-C9lmF.mjs} +4 -4
- package/dist/{bylines-DGuqBLjV.mjs.map → bylines-cf-C9lmF.mjs.map} +1 -1
- package/dist/cache-C9FptTFR.mjs +108 -0
- package/dist/cache-C9FptTFR.mjs.map +1 -0
- package/dist/{challenge-store-BFzgFRog.mjs → challenge-store-D9VNKELo.mjs} +1 -1
- package/dist/{challenge-store-BFzgFRog.mjs.map → challenge-store-D9VNKELo.mjs.map} +1 -1
- package/dist/{chunks-D5dlPeRb.mjs → chunks-DbYzib_k.mjs} +2 -2
- package/dist/{chunks-D5dlPeRb.mjs.map → chunks-DbYzib_k.mjs.map} +1 -1
- package/dist/cli/index.mjs +40 -32
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +2 -2
- package/dist/{comment-DnTxxVHv.mjs → comment-BIkJ6Fil.mjs} +3 -3
- package/dist/{comment-DnTxxVHv.mjs.map → comment-BIkJ6Fil.mjs.map} +1 -1
- package/dist/{comment-reaction-BUlUz2bh.mjs → comment-reaction-D-laEceb.mjs} +2 -2
- package/dist/{comment-reaction-BUlUz2bh.mjs.map → comment-reaction-D-laEceb.mjs.map} +1 -1
- package/dist/{comments-QPKgK3nk.mjs → comments-0_w6KChA.mjs} +3 -3
- package/dist/{comments-QPKgK3nk.mjs.map → comments-0_w6KChA.mjs.map} +1 -1
- package/dist/{components-DZkL4Fx0.mjs → components-BPxrRjpE.mjs} +1 -1
- package/dist/{components-DZkL4Fx0.mjs.map → components-BPxrRjpE.mjs.map} +1 -1
- package/dist/{content-CpfKV9QE.mjs → content-CJ94NEx5.mjs} +165 -112
- package/dist/content-CJ94NEx5.mjs.map +1 -0
- package/dist/{content-refresh-DgqUBeTv.mjs → content-refresh-Xw7aKmou.mjs} +6 -6
- package/dist/{content-refresh-DgqUBeTv.mjs.map → content-refresh-Xw7aKmou.mjs.map} +1 -1
- package/dist/{context-kO4YZB03.mjs → context-C_1nrqnW.mjs} +14 -14
- package/dist/{context-kO4YZB03.mjs.map → context-C_1nrqnW.mjs.map} +1 -1
- package/dist/{cron-BlKIMD_e.mjs → cron-DRV-UC4K.mjs} +1 -1
- package/dist/{cron-BlKIMD_e.mjs.map → cron-DRV-UC4K.mjs.map} +1 -1
- package/dist/{dashboard-DoBwPnON.mjs → dashboard-DINnNVVU.mjs} +5 -5
- package/dist/{dashboard-DoBwPnON.mjs.map → dashboard-DINnNVVU.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{default-C4v9KP56.mjs → default-BD2FG0xV.mjs} +1 -1
- package/dist/{default-C4v9KP56.mjs.map → default-BD2FG0xV.mjs.map} +1 -1
- package/dist/deferred-tasks-C-WRCcKo.d.mts +9 -0
- package/dist/deferred-tasks-C-WRCcKo.d.mts.map +1 -0
- package/dist/{device-flow-DhUsyJU6.mjs → device-flow-CTqd8mud.mjs} +5 -5
- package/dist/{device-flow-DhUsyJU6.mjs.map → device-flow-CTqd8mud.mjs.map} +1 -1
- package/dist/{dialect-helpers-DFwyWjTM.mjs → dialect-helpers-BSbfaO3F.mjs} +24 -16
- package/dist/dialect-helpers-BSbfaO3F.mjs.map +1 -0
- package/dist/{email-console-C-9Ng8DM.mjs → email-console-C6WdcWbL.mjs} +1 -1
- package/dist/{email-console-C-9Ng8DM.mjs.map → email-console-C6WdcWbL.mjs.map} +1 -1
- package/dist/{error-DmmN74gW.mjs → error-oh_9i6bR.mjs} +3 -3
- package/dist/{error-DmmN74gW.mjs.map → error-oh_9i6bR.mjs.map} +1 -1
- package/dist/{errors-DtEXIQQV.mjs → errors-BucQ8VYz.mjs} +2 -1
- package/dist/errors-BucQ8VYz.mjs.map +1 -0
- package/dist/{escape-CdW31WsG.mjs → escape-CXps5F_v.mjs} +1 -1
- package/dist/{escape-CdW31WsG.mjs.map → escape-CXps5F_v.mjs.map} +1 -1
- package/dist/{field-defs-cache-QMVnzTH6.mjs → field-defs-cache-WD82dMQq.mjs} +4 -4
- package/dist/{field-defs-cache-QMVnzTH6.mjs.map → field-defs-cache-WD82dMQq.mjs.map} +1 -1
- package/dist/{fts-manager-vncsZIJm.mjs → fts-manager-BITakW_R.mjs} +37 -13
- package/dist/fts-manager-BITakW_R.mjs.map +1 -0
- package/dist/{hash-Cb7U1b5M.mjs → hash-Cg0TXJPV.mjs} +1 -1
- package/dist/{hash-Cb7U1b5M.mjs.map → hash-Cg0TXJPV.mjs.map} +1 -1
- package/dist/{hreflang-CZbSx6Bg.d.mts → hreflang-BaLCNcDx.d.mts} +2 -2
- package/dist/{hreflang-CZbSx6Bg.d.mts.map → hreflang-BaLCNcDx.d.mts.map} +1 -1
- package/dist/{hreflang-Bg-zMpkr.mjs → hreflang-BdZuVBhL.mjs} +6 -6
- package/dist/{hreflang-Bg-zMpkr.mjs.map → hreflang-BdZuVBhL.mjs.map} +1 -1
- package/dist/{import-PKhLeXvn.mjs → import-C-9uqyT3.mjs} +6 -6
- package/dist/{import-PKhLeXvn.mjs.map → import-C-9uqyT3.mjs.map} +1 -1
- package/dist/{index-j9rTh3cp.d.mts → index-M37iz29I.d.mts} +75 -35
- package/dist/index-M37iz29I.d.mts.map +1 -0
- package/dist/{index-BeNto_Vs.d.mts → index-MGw47uWq.d.mts} +3 -3
- package/dist/{index-BeNto_Vs.d.mts.map → index-MGw47uWq.d.mts.map} +1 -1
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +68 -66
- package/dist/{load-BwTdWE8B.mjs → load-DV1DZuUJ.mjs} +2 -2
- package/dist/{load-BwTdWE8B.mjs.map → load-DV1DZuUJ.mjs.map} +1 -1
- package/dist/{loader-C1XOLV5b.mjs → loader-CGugY7Zl.mjs} +29 -15
- package/dist/loader-CGugY7Zl.mjs.map +1 -0
- package/dist/{manifest-schema-bCq54i7F.mjs → manifest-schema-Da7kj23y.mjs} +1 -1
- package/dist/{manifest-schema-bCq54i7F.mjs.map → manifest-schema-Da7kj23y.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +12 -12
- package/dist/media/local-runtime.mjs +8 -8
- package/dist/{media-tQDZEdu7.mjs → media-BP7S-nHT.mjs} +2 -2
- package/dist/{media-tQDZEdu7.mjs.map → media-BP7S-nHT.mjs.map} +1 -1
- package/dist/{media-DWIzoVFL.mjs → media-OhYL-7Io.mjs} +1 -1
- package/dist/{media-DWIzoVFL.mjs.map → media-OhYL-7Io.mjs.map} +1 -1
- package/dist/{media-allowlist-B7TPD6aq.mjs → media-allowlist-D-peH1H5.mjs} +1 -1
- package/dist/{media-allowlist-B7TPD6aq.mjs.map → media-allowlist-D-peH1H5.mjs.map} +1 -1
- package/dist/{media-upload-Bc9Nc5Zf.mjs → media-upload-DtrwU2B0.mjs} +7 -7
- package/dist/{media-upload-Bc9Nc5Zf.mjs.map → media-upload-DtrwU2B0.mjs.map} +1 -1
- package/dist/{media-url-BCm5vBn6.mjs → media-url-DYs_YLOx.mjs} +1 -1
- package/dist/{media-url-BCm5vBn6.mjs.map → media-url-DYs_YLOx.mjs.map} +1 -1
- package/dist/{media-usage-DPJcNaAq.mjs → media-usage-BlxfTkN0.mjs} +8 -8
- package/dist/{media-usage-DPJcNaAq.mjs.map → media-usage-BlxfTkN0.mjs.map} +1 -1
- package/dist/{menus-BxPLFfIc.mjs → menus-BcQWxeXu.mjs} +4 -4
- package/dist/{menus-BxPLFfIc.mjs.map → menus-BcQWxeXu.mjs.map} +1 -1
- package/dist/{menus-C6qhqP4X.mjs → menus-Y54RDPIN.mjs} +215 -38
- package/dist/menus-Y54RDPIN.mjs.map +1 -0
- package/dist/{mode-fiXRMfeA.mjs → mode-BWyTBe3I.mjs} +1 -1
- package/dist/{mode-fiXRMfeA.mjs.map → mode-BWyTBe3I.mjs.map} +1 -1
- package/dist/{oauth-authorization-C9tFinly.mjs → oauth-authorization-ClvktmrL.mjs} +5 -5
- package/dist/{oauth-authorization-C9tFinly.mjs.map → oauth-authorization-ClvktmrL.mjs.map} +1 -1
- package/dist/{oauth-clients-BwTxE1aE.mjs → oauth-clients-8ao-U66l.mjs} +1 -1
- package/dist/{oauth-clients-BwTxE1aE.mjs.map → oauth-clients-8ao-U66l.mjs.map} +1 -1
- package/dist/{oauth-state-store-DaRUwPWO.mjs → oauth-state-store-B1ofdTiQ.mjs} +1 -1
- package/dist/{oauth-state-store-DaRUwPWO.mjs.map → oauth-state-store-B1ofdTiQ.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-CzuzOSlF.mjs → oauth-user-lookup-CscEuIiR.mjs} +1 -1
- package/dist/{oauth-user-lookup-CzuzOSlF.mjs.map → oauth-user-lookup-CscEuIiR.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{object-cache-Bok5j2ae.mjs → object-cache-71tPfV4A.mjs} +106 -5
- package/dist/object-cache-71tPfV4A.mjs.map +1 -0
- package/dist/{options-aeIs8WFu.d.mts → options-CA4eVX6P.d.mts} +3 -3
- package/dist/{options-aeIs8WFu.d.mts.map → options-CA4eVX6P.d.mts.map} +1 -1
- package/dist/{options-BlmBHTvX.mjs → options-CBXIHUoT.mjs} +1 -1
- package/dist/{options-BlmBHTvX.mjs.map → options-CBXIHUoT.mjs.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{parse-BL49yb9D.mjs → parse-CJKNuewM.mjs} +2 -2
- package/dist/{parse-BL49yb9D.mjs.map → parse-CJKNuewM.mjs.map} +1 -1
- package/dist/{passkey-config-KMhgFjdQ.mjs → passkey-config-D-zrzMJI.mjs} +1 -1
- package/dist/{passkey-config-KMhgFjdQ.mjs.map → passkey-config-D-zrzMJI.mjs.map} +1 -1
- package/dist/{placeholder-Dxo5Zt58.d.mts → placeholder-DaeNS-VG.d.mts} +1 -1
- package/dist/{placeholder-Dxo5Zt58.d.mts.map → placeholder-DaeNS-VG.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +1 -1
- package/dist/plugin-utils.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{portable-text-CNahFfj6.mjs → portable-text-B_kqBmXB.mjs} +1 -1
- package/dist/{portable-text-CNahFfj6.mjs.map → portable-text-B_kqBmXB.mjs.map} +1 -1
- package/dist/{preview-D4Jnbfx7.mjs → preview-BU6PaLpM.mjs} +2 -2
- package/dist/{preview-D4Jnbfx7.mjs.map → preview-BU6PaLpM.mjs.map} +1 -1
- package/dist/{public-url-DSGTnJFw.mjs → public-url-Ox9oOlgp.mjs} +14 -3
- package/dist/public-url-Ox9oOlgp.mjs.map +1 -0
- package/dist/{query-DCiXI7OZ.mjs → query-C5w7PsRQ.mjs} +20 -41
- package/dist/query-C5w7PsRQ.mjs.map +1 -0
- package/dist/{query-1xOcEy18.mjs → query-rC9HKv1N.mjs} +4 -4
- package/dist/{query-1xOcEy18.mjs.map → query-rC9HKv1N.mjs.map} +1 -1
- package/dist/{rate-limit-Vkp9gQ1Y.mjs → rate-limit-kug6q99V.mjs} +2 -2
- package/dist/{rate-limit-Vkp9gQ1Y.mjs.map → rate-limit-kug6q99V.mjs.map} +1 -1
- package/dist/{redirect-BJ6d1yHh.mjs → redirect-DIJxXKOG.mjs} +3 -3
- package/dist/{redirect-BJ6d1yHh.mjs.map → redirect-DIJxXKOG.mjs.map} +1 -1
- package/dist/{redirect-CDgfv9vh.mjs → redirect-Egf2R9yP.mjs} +1 -1
- package/dist/{redirect-CDgfv9vh.mjs.map → redirect-Egf2R9yP.mjs.map} +1 -1
- package/dist/{redirects-Cwkq2H-G.mjs → redirects-Bzm812bY.mjs} +5 -5
- package/dist/{redirects-Cwkq2H-G.mjs.map → redirects-Bzm812bY.mjs.map} +1 -1
- package/dist/{redirects-BOn2DIUs.mjs → redirects-G8wAhWAf.mjs} +20 -6
- package/dist/redirects-G8wAhWAf.mjs.map +1 -0
- package/dist/{registry-BP1JK2xh.mjs → registry-Dbodb4Uo.mjs} +59 -14
- package/dist/registry-Dbodb4Uo.mjs.map +1 -0
- package/dist/{relation-DJ5DZh7B.mjs → relation-Cbe3Sd3m.mjs} +3 -3
- package/dist/{relation-DJ5DZh7B.mjs.map → relation-Cbe3Sd3m.mjs.map} +1 -1
- package/dist/{relations-C4duJnwI.mjs → relations-Bw_E1TXo.mjs} +3 -3
- package/dist/{relations-C4duJnwI.mjs.map → relations-Bw_E1TXo.mjs.map} +1 -1
- package/dist/{relations-DHFQGX0h.d.mts → relations-G2ta7GIl.d.mts} +36 -9
- package/dist/relations-G2ta7GIl.d.mts.map +1 -0
- package/dist/{relations-DpTjftCl.mjs → relations-qHwpUe66.mjs} +5 -5
- package/dist/{relations-DpTjftCl.mjs.map → relations-qHwpUe66.mjs.map} +1 -1
- package/dist/request-context.d.mts +3 -0
- package/dist/request-context.d.mts.map +1 -1
- package/dist/request-context.mjs.map +1 -1
- package/dist/{request-meta-DzXYYI-n.mjs → request-meta-Df-jFbAd.mjs} +2 -2
- package/dist/{request-meta-DzXYYI-n.mjs.map → request-meta-Df-jFbAd.mjs.map} +1 -1
- package/dist/{resolve-BUvFE0Lr.mjs → resolve-DZzG4HqM.mjs} +1 -1
- package/dist/{resolve-BUvFE0Lr.mjs.map → resolve-DZzG4HqM.mjs.map} +1 -1
- package/dist/{runner-BsI18UgP.mjs → runner-BFTrkYhu.mjs} +482 -216
- package/dist/runner-BFTrkYhu.mjs.map +1 -0
- package/dist/{runner-CHdkERbt.d.mts → runner-BaADli8l.d.mts} +2 -2
- package/dist/{runner-CHdkERbt.d.mts.map → runner-BaADli8l.d.mts.map} +1 -1
- package/dist/runtime.d.mts +11 -11
- package/dist/runtime.mjs +3 -3
- package/dist/{schema-eqZhkR0S.mjs → schema-CiQXr6_F.mjs} +3 -3
- package/dist/{schema-eqZhkR0S.mjs.map → schema-CiQXr6_F.mjs.map} +1 -1
- package/dist/{scopes-Be2d8bSb.mjs → scopes-CNJVT5i5.mjs} +3 -3
- package/dist/{scopes-Be2d8bSb.mjs.map → scopes-CNJVT5i5.mjs.map} +1 -1
- package/dist/{search-CeO678cp.mjs → search-FZhx5dDU.mjs} +6 -6
- package/dist/{search-CeO678cp.mjs.map → search-FZhx5dDU.mjs.map} +1 -1
- package/dist/{secrets-870d-7yA.mjs → secrets-DLd8RXee.mjs} +4 -4
- package/dist/{secrets-870d-7yA.mjs.map → secrets-DLd8RXee.mjs.map} +1 -1
- package/dist/{sections-DSuEfirn.mjs → sections-BrIrMUCn.mjs} +3 -3
- package/dist/{sections-DSuEfirn.mjs.map → sections-BrIrMUCn.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +24 -24
- package/dist/seo/index.d.mts +3 -3
- package/dist/seo/index.mjs +17 -17
- package/dist/{seo-C3GDfT0V.mjs → seo-CobNfOvb.mjs} +2 -2
- package/dist/{seo-C3GDfT0V.mjs.map → seo-CobNfOvb.mjs.map} +1 -1
- package/dist/{seo-BAPKiED8.mjs → seo-DTHRntNC.mjs} +3 -3
- package/dist/{seo-BAPKiED8.mjs.map → seo-DTHRntNC.mjs.map} +1 -1
- package/dist/{service-DyFT-k-R.mjs → service-B-pYGPgR.mjs} +4 -4
- package/dist/{service-DyFT-k-R.mjs.map → service-B-pYGPgR.mjs.map} +1 -1
- package/dist/{session-user-BrK2zz7S.mjs → session-user-BvM9-zNl.mjs} +2 -2
- package/dist/{session-user-BrK2zz7S.mjs.map → session-user-BvM9-zNl.mjs.map} +1 -1
- package/dist/{settings-CREKyj8I.mjs → settings-DPHau-WH.mjs} +3 -3
- package/dist/{settings-CREKyj8I.mjs.map → settings-DPHau-WH.mjs.map} +1 -1
- package/dist/{settings-DgKouY2S.mjs → settings-kJhGiQ4z.mjs} +7 -7
- package/dist/{settings-DgKouY2S.mjs.map → settings-kJhGiQ4z.mjs.map} +1 -1
- package/dist/{setup-complete-L7bMK2VI.mjs → setup-complete-u50Qm8rY.mjs} +2 -2
- package/dist/{setup-complete-L7bMK2VI.mjs.map → setup-complete-u50Qm8rY.mjs.map} +1 -1
- package/dist/{setup-nonce-Ct5tjWcq.mjs → setup-nonce-DCjiiOD2.mjs} +1 -1
- package/dist/{setup-nonce-Ct5tjWcq.mjs.map → setup-nonce-DCjiiOD2.mjs.map} +1 -1
- package/dist/{single-flight-cache-C2exrGAi.mjs → single-flight-cache-DW3w11Pu.mjs} +1 -1
- package/dist/{single-flight-cache-C2exrGAi.mjs.map → single-flight-cache-DW3w11Pu.mjs.map} +1 -1
- package/dist/site-url-I-lJ5kma.mjs +16 -0
- package/dist/site-url-I-lJ5kma.mjs.map +1 -0
- package/dist/{snapshot-BdpUJKD-.mjs → snapshot-I_fjLDaD.mjs} +2 -2
- package/dist/{snapshot-BdpUJKD-.mjs.map → snapshot-I_fjLDaD.mjs.map} +1 -1
- package/dist/{ssrf-CviKqWmq.mjs → ssrf-CTa6v21i.mjs} +1 -1
- package/dist/{ssrf-CviKqWmq.mjs.map → ssrf-CTa6v21i.mjs.map} +1 -1
- package/dist/{state-xxv6ZTMv.mjs → state-CQvoefYP.mjs} +1 -1
- package/dist/{state-xxv6ZTMv.mjs.map → state-CQvoefYP.mjs.map} +1 -1
- package/dist/{status-COfycGIU.mjs → status-CIsmlC1E.mjs} +1 -1
- package/dist/{status-COfycGIU.mjs.map → status-CIsmlC1E.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-Dbdki3Un.mjs → taxonomies-CKuaZER5.mjs} +85 -5
- package/dist/taxonomies-CKuaZER5.mjs.map +1 -0
- package/dist/{taxonomies-B61CRSha.mjs → taxonomies-CLN1N92E.mjs} +16 -17
- package/dist/taxonomies-CLN1N92E.mjs.map +1 -0
- package/dist/{taxonomy-DvwWAPvA.mjs → taxonomy-pOrB2kZe.mjs} +142 -15
- package/dist/taxonomy-pOrB2kZe.mjs.map +1 -0
- package/dist/{tokens-DVltpO2D.mjs → tokens-DagaJGK8.mjs} +1 -1
- package/dist/{tokens-DVltpO2D.mjs.map → tokens-DagaJGK8.mjs.map} +1 -1
- package/dist/{transaction-D0FOsb3X.mjs → transaction-NQj4VJ7Z.mjs} +1 -1
- package/dist/{transaction-D0FOsb3X.mjs.map → transaction-NQj4VJ7Z.mjs.map} +1 -1
- package/dist/{transport-DokJOScS.d.mts → transport-CAwTaTp_.d.mts} +1 -1
- package/dist/{transport-DokJOScS.d.mts.map → transport-CAwTaTp_.d.mts.map} +1 -1
- package/dist/{transport-BWQo0Foy.mjs → transport-DVsa5YYo.mjs} +1 -1
- package/dist/{transport-BWQo0Foy.mjs.map → transport-DVsa5YYo.mjs.map} +1 -1
- package/dist/{trusted-proxy-CwjQj0YG.mjs → trusted-proxy-D20_7fyX.mjs} +1 -1
- package/dist/{trusted-proxy-CwjQj0YG.mjs.map → trusted-proxy-D20_7fyX.mjs.map} +1 -1
- package/dist/{types-DqZVPILm.d.mts → types-BGWPMiBO.d.mts} +2 -2
- package/dist/{types-DqZVPILm.d.mts.map → types-BGWPMiBO.d.mts.map} +1 -1
- package/dist/{types-DsAMyD_o.d.mts → types-BK6U01Ro.d.mts} +1 -1
- package/dist/{types-DsAMyD_o.d.mts.map → types-BK6U01Ro.d.mts.map} +1 -1
- package/dist/{types-BD40g7zz.mjs → types-BjxTKxrZ.mjs} +1 -1
- package/dist/{types-BD40g7zz.mjs.map → types-BjxTKxrZ.mjs.map} +1 -1
- package/dist/{types-jISEalTX.d.mts → types-BnFP1M3J.d.mts} +22 -1
- package/dist/types-BnFP1M3J.d.mts.map +1 -0
- package/dist/{types-Dr2GLlwu.d.mts → types-C8oz_ayJ.d.mts} +1 -1
- package/dist/{types-Dr2GLlwu.d.mts.map → types-C8oz_ayJ.d.mts.map} +1 -1
- package/dist/{types-C9P3ysxq.d.mts → types-CbUcuxxc.d.mts} +1 -1
- package/dist/{types-C9P3ysxq.d.mts.map → types-CbUcuxxc.d.mts.map} +1 -1
- package/dist/{types-XrQQ-Aex.mjs → types-Cd8iuS1J.mjs} +10 -3
- package/dist/{types-XrQQ-Aex.mjs.map → types-Cd8iuS1J.mjs.map} +1 -1
- package/dist/types-CtzytVXn.mjs +18 -0
- package/dist/types-CtzytVXn.mjs.map +1 -0
- package/dist/{types-BQY7VYw6.d.mts → types-Cz8hNch2.d.mts} +5 -5
- package/dist/{types-BQY7VYw6.d.mts.map → types-Cz8hNch2.d.mts.map} +1 -1
- package/dist/{types-CcSZCcF1.d.mts → types-DLG4IFEQ.d.mts} +1 -1
- package/dist/{types-CcSZCcF1.d.mts.map → types-DLG4IFEQ.d.mts.map} +1 -1
- package/dist/{types-84Bque3-.d.mts → types-Dc4ntQjQ.d.mts} +10 -1
- package/dist/types-Dc4ntQjQ.d.mts.map +1 -0
- package/dist/{types-DQLZ58GV.d.mts → types-LoagAGzH.d.mts} +1 -1
- package/dist/{types-DQLZ58GV.d.mts.map → types-LoagAGzH.d.mts.map} +1 -1
- package/dist/{types-o7xo7VgH.mjs → types-NBI3rF-_.mjs} +3 -2
- package/dist/types-NBI3rF-_.mjs.map +1 -0
- package/dist/{upload-attempts-C5yd6Gae.mjs → upload-attempts-D8QAFLUJ.mjs} +1 -1
- package/dist/{upload-attempts-C5yd6Gae.mjs.map → upload-attempts-D8QAFLUJ.mjs.map} +1 -1
- package/dist/{user-BAumEmpA.mjs → user-DBrq4UVq.mjs} +3 -3
- package/dist/{user-BAumEmpA.mjs.map → user-DBrq4UVq.mjs.map} +1 -1
- package/dist/{utils-BbUgmeZG.mjs → utils-hLzi_2Fn.mjs} +2 -2
- package/dist/{utils-BbUgmeZG.mjs.map → utils-hLzi_2Fn.mjs.map} +1 -1
- package/dist/{validate-VPnKoIzW.mjs → validate-BpwoDOgt.mjs} +25 -2
- package/dist/validate-BpwoDOgt.mjs.map +1 -0
- package/dist/{validate-CdYcY-Ln.d.mts → validate-C3oSmA7F.d.mts} +15 -5
- package/dist/validate-C3oSmA7F.d.mts.map +1 -0
- package/dist/{validate-Bs_wT2ul.mjs → validate-mKo3RxBM.mjs} +3 -3
- package/dist/{validate-Bs_wT2ul.mjs.map → validate-mKo3RxBM.mjs.map} +1 -1
- package/dist/{validation-BngR0nit.mjs → validation-BgpucsvF.mjs} +10 -10
- package/dist/{validation-BngR0nit.mjs.map → validation-BgpucsvF.mjs.map} +1 -1
- package/dist/version-C4PnpmoV.mjs +7 -0
- package/dist/{version-Bdfb34kk.mjs.map → version-C4PnpmoV.mjs.map} +1 -1
- package/dist/{widgets-L-VndTKD.mjs → widgets-CJJtkiKh.mjs} +3 -3
- package/dist/{widgets-L-VndTKD.mjs.map → widgets-CJJtkiKh.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-BexjtNid.mjs → wxr-taxonomies-9PPSy8X6.mjs} +4 -4
- package/dist/{wxr-taxonomies-BexjtNid.mjs.map → wxr-taxonomies-9PPSy8X6.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-DueaLFd9.d.mts → wxr-taxonomies-Bkpp_2tK.d.mts} +1 -1
- package/dist/{wxr-taxonomies-DueaLFd9.d.mts.map → wxr-taxonomies-Bkpp_2tK.d.mts.map} +1 -1
- package/dist/{zod-generator-DMzfga3g.mjs → zod-generator-CG64Hnbh.mjs} +3 -3
- package/dist/{zod-generator-DMzfga3g.mjs.map → zod-generator-CG64Hnbh.mjs.map} +1 -1
- package/package.json +11 -8
- package/src/after.ts +6 -1
- package/src/api/errors.ts +1 -0
- package/src/api/handlers/content.ts +45 -4
- package/src/api/handlers/marketplace.ts +14 -0
- package/src/api/handlers/registry.ts +14 -0
- package/src/api/handlers/revision.ts +19 -5
- package/src/api/handlers/schema.ts +37 -0
- package/src/api/handlers/snapshot.ts +1 -1
- package/src/api/handlers/taxonomies.ts +101 -1
- package/src/api/openapi/document.ts +48 -0
- package/src/api/public-url.ts +14 -2
- package/src/api/schemas/schema.ts +13 -0
- package/src/api/schemas/search.ts +2 -0
- package/src/api/schemas/taxonomies.ts +18 -0
- package/src/api/site-url.ts +16 -6
- package/src/astro/integration/routes.ts +14 -0
- package/src/astro/integration/runtime.ts +13 -0
- package/src/astro/integration/virtual-modules.ts +2 -0
- package/src/astro/middleware/redirect.ts +2 -10
- package/src/astro/middleware/scoped-db.ts +35 -4
- package/src/astro/middleware.ts +56 -22
- package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -1
- package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +2 -2
- package/src/astro/routes/api/auth/invite/index.ts +2 -2
- package/src/astro/routes/api/auth/magic-link/send.ts +2 -2
- package/src/astro/routes/api/auth/signup/request.ts +2 -2
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +1 -1
- package/src/astro/routes/api/schema/collections/reorder.ts +31 -0
- package/src/astro/routes/api/schema/index.ts +2 -0
- package/src/astro/routes/api/search/enable.ts +5 -1
- package/src/astro/routes/api/search/rebuild.ts +6 -1
- package/src/astro/routes/api/taxonomies/[name]/reorder.ts +41 -0
- package/src/astro/types.ts +6 -0
- package/src/cleanup.ts +31 -26
- package/src/cli/commands/dev.ts +13 -3
- package/src/cli/commands/export-seed.ts +2 -0
- package/src/cli/index.ts +1 -1
- package/src/components/CommentForm.astro +1 -1
- package/src/components/Comments.astro +1 -1
- package/src/components/InlinePortableTextEditor.tsx +171 -31
- package/src/components/OrderedList.astro +14 -0
- package/src/components/PortableText.astro +26 -4
- package/src/components/index.ts +12 -1
- package/src/components/ordered-list.ts +549 -0
- package/src/content/converters/numbered-list.ts +148 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +59 -9
- package/src/content/converters/prosemirror-to-portable-text.ts +23 -12
- package/src/content/converters/types.ts +2 -0
- package/src/content/portable-text-lists.ts +205 -0
- package/src/database/dialect-helpers.ts +3 -22
- package/src/database/migrations/055_content_translation_group_locale_index.ts +67 -0
- package/src/database/migrations/056_taxonomy_term_sort_order.ts +189 -0
- package/src/database/migrations/057_collection_hidden.ts +24 -0
- package/src/database/migrations/058_collection_sort_order.ts +20 -0
- package/src/database/migrations/059_revision_prune_queue.ts +36 -0
- package/src/database/migrations/runner.ts +10 -0
- package/src/database/repositories/content.ts +191 -178
- package/src/database/repositories/revision.ts +82 -17
- package/src/database/repositories/taxonomy.ts +202 -7
- package/src/database/repositories/types.ts +7 -0
- package/src/database/types.ts +13 -1
- package/src/database/validate.ts +39 -0
- package/src/db/adapters.ts +8 -0
- package/src/deferred-tasks.ts +71 -0
- package/src/emdash-runtime.ts +268 -92
- package/src/index.ts +2 -0
- package/src/loader.ts +46 -24
- package/src/media/usage/gc.ts +50 -0
- package/src/object-cache/index.ts +160 -3
- package/src/plugins/routes.ts +34 -0
- package/src/plugins/storage-indexes.ts +50 -11
- package/src/query.ts +21 -42
- package/src/redirects/cache.ts +79 -19
- package/src/request-context.ts +3 -0
- package/src/scheduled-publish.ts +6 -1
- package/src/schema/registry.ts +95 -3
- package/src/schema/types.ts +24 -0
- package/src/search/fts-manager.ts +50 -10
- package/src/search/index.ts +2 -0
- package/src/search/types.ts +6 -0
- package/src/seed/apply.ts +22 -2
- package/src/seed/types.ts +10 -0
- package/src/taxonomies/index.ts +11 -7
- package/src/taxonomies/term-counts.ts +2 -4
- package/src/ui-comments.ts +19 -0
- package/src/ui.ts +11 -3
- package/src/virtual-modules.d.ts +8 -0
- package/dist/adapters-C0ONzkUP.d.mts.map +0 -1
- package/dist/after-B1IIdH3Y.mjs +0 -29
- package/dist/after-B1IIdH3Y.mjs.map +0 -1
- package/dist/api-DgPbMlng.mjs.map +0 -1
- package/dist/apply-1_6ra7NP.mjs.map +0 -1
- package/dist/cache-B26cufFd.mjs +0 -65
- package/dist/cache-B26cufFd.mjs.map +0 -1
- package/dist/content-CpfKV9QE.mjs.map +0 -1
- package/dist/dialect-helpers-DFwyWjTM.mjs.map +0 -1
- package/dist/errors-DtEXIQQV.mjs.map +0 -1
- package/dist/fts-manager-vncsZIJm.mjs.map +0 -1
- package/dist/index-j9rTh3cp.d.mts.map +0 -1
- package/dist/loader-C1XOLV5b.mjs.map +0 -1
- package/dist/menus-C6qhqP4X.mjs.map +0 -1
- package/dist/object-cache-Bok5j2ae.mjs.map +0 -1
- package/dist/public-url-DSGTnJFw.mjs.map +0 -1
- package/dist/query-DCiXI7OZ.mjs.map +0 -1
- package/dist/redirects-BOn2DIUs.mjs.map +0 -1
- package/dist/registry-BP1JK2xh.mjs.map +0 -1
- package/dist/relations-DHFQGX0h.d.mts.map +0 -1
- package/dist/runner-BsI18UgP.mjs.map +0 -1
- package/dist/site-url-8N3kSyVZ.mjs +0 -13
- package/dist/site-url-8N3kSyVZ.mjs.map +0 -1
- package/dist/taxonomies-B61CRSha.mjs.map +0 -1
- package/dist/taxonomies-Dbdki3Un.mjs.map +0 -1
- package/dist/taxonomy-DvwWAPvA.mjs.map +0 -1
- package/dist/types-84Bque3-.d.mts.map +0 -1
- package/dist/types-jISEalTX.d.mts.map +0 -1
- package/dist/types-o7xo7VgH.mjs.map +0 -1
- package/dist/validate-CdYcY-Ln.d.mts.map +0 -1
- package/dist/validate-VPnKoIzW.mjs.map +0 -1
- package/dist/version-Bdfb34kk.mjs +0 -7
- /package/dist/{api-tokens-CEsW_jCg.mjs → api-tokens-Dai9dND0.mjs} +0 -0
- /package/dist/{ssrf-BB__xfNM.mjs → ssrf-Cj568Dgs.mjs} +0 -0
- /package/dist/{types-CK0LxPUQ.mjs → types-DKuWPYV5.mjs} +0 -0
package/src/loader.ts
CHANGED
|
@@ -88,12 +88,19 @@ const SYSTEM_COLUMNS = new Set([
|
|
|
88
88
|
// SEO_ALIAS_COLUMNS, never as flat fields.
|
|
89
89
|
"_emdash_terms",
|
|
90
90
|
"_emdash_bylines",
|
|
91
|
+
"_emdash_bylines_exist",
|
|
91
92
|
SEO_FOLDED_COLUMN,
|
|
92
93
|
]);
|
|
93
94
|
|
|
94
95
|
/** Markers for byline/taxonomy hydration folded into the content query. */
|
|
95
96
|
export const FOLDED_TERMS = Symbol.for("emdash:foldedTerms");
|
|
96
97
|
export const FOLDED_BYLINES = Symbol.for("emdash:foldedBylines");
|
|
98
|
+
/**
|
|
99
|
+
* Marker for whether `_emdash_bylines` has any rows at all (`false` = table
|
|
100
|
+
* empty). Lets byline hydration trust an empty fold instead of re-checking
|
|
101
|
+
* via the byline query path on sites that never use bylines.
|
|
102
|
+
*/
|
|
103
|
+
export const FOLDED_BYLINES_EXIST = Symbol.for("emdash:foldedBylinesExist");
|
|
97
104
|
|
|
98
105
|
/**
|
|
99
106
|
* Correlated JSON-array subqueries that fold taxonomy-term and byline hydration
|
|
@@ -144,7 +151,12 @@ function foldedHydrationSelects(db: Kysely<any>, type: string, outer: string) {
|
|
|
144
151
|
: sql.raw("json_object('roleLabel', cb.role_label, 'sortOrder', cb.sort_order, 'byline', ");
|
|
145
152
|
const credit = sql`${creditObj}${bylineInner})`;
|
|
146
153
|
const bylines = sql`(SELECT ${agg(credit)} FROM ${sql.ref("_emdash_content_bylines")} AS cb ${foldJoin} ${sql.ref("_emdash_bylines")} AS b ON b.translation_group = cb.byline_id LEFT JOIN ${sql.ref("media")} AS m ON m.id = b.avatar_media_id WHERE cb.collection_slug = ${type} AND cb.content_id = ${o}.id AND b.locale = ${o}.locale) AS ${sql.ref("_emdash_bylines")}`;
|
|
147
|
-
|
|
154
|
+
// Uncorrelated existence probe (evaluated once per statement, not per row):
|
|
155
|
+
// 1 when `_emdash_bylines` has any row, NULL when empty. An empty table
|
|
156
|
+
// means an empty fold is authoritative — no credit in any locale, no
|
|
157
|
+
// author-fallback byline — so hydration can skip the byline query path.
|
|
158
|
+
const bylinesExist = sql`(SELECT 1 FROM ${sql.ref("_emdash_bylines")} LIMIT 1) AS ${sql.ref("_emdash_bylines_exist")}`;
|
|
159
|
+
return { terms, bylines, bylinesExist };
|
|
148
160
|
}
|
|
149
161
|
|
|
150
162
|
/**
|
|
@@ -227,6 +239,16 @@ function stashFolded(data: Record<string, unknown>, row: Record<string, unknown>
|
|
|
227
239
|
}
|
|
228
240
|
Object.defineProperty(data, sym, { value, enumerable: false, configurable: true });
|
|
229
241
|
}
|
|
242
|
+
// Existence probe: 1 = table has rows, NULL = empty (both dialects). A row
|
|
243
|
+
// without the column (e.g. a cached snapshot) leaves the marker unset,
|
|
244
|
+
// which hydration treats as "unknown" and falls back conservatively.
|
|
245
|
+
if ("_emdash_bylines_exist" in row) {
|
|
246
|
+
Object.defineProperty(data, FOLDED_BYLINES_EXIST, {
|
|
247
|
+
value: row["_emdash_bylines_exist"] != null,
|
|
248
|
+
enumerable: false,
|
|
249
|
+
configurable: true,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
230
252
|
}
|
|
231
253
|
|
|
232
254
|
/** Resolved SEO shape attached to `entry.data.seo`. Mirrors `ContentSeo`. */
|
|
@@ -703,8 +725,8 @@ function buildPivotLimitOffset(
|
|
|
703
725
|
* Options for {@link buildTaxonomyPivotQuery}.
|
|
704
726
|
*
|
|
705
727
|
* Parameterized on the `deletedIsNull` predicate and `status` condition so the
|
|
706
|
-
* same builder serves the public live path (`deleted_at IS NULL` + published
|
|
707
|
-
*
|
|
728
|
+
* same builder serves the public live path (`deleted_at IS NULL` + published)
|
|
729
|
+
* and, without any schema change, an admin trash (`deleted_at IS NOT
|
|
708
730
|
* NULL`) or all-statuses shape. Admin wiring is out of scope today; the
|
|
709
731
|
* parameters exist so `ContentRepository` can adopt this if it gains taxonomy
|
|
710
732
|
* filtering.
|
|
@@ -727,7 +749,7 @@ export interface TaxonomyPivotQueryOptions {
|
|
|
727
749
|
locale: string | undefined;
|
|
728
750
|
/**
|
|
729
751
|
* Status shape. A concrete value (`published`/`draft`/…) applies the same
|
|
730
|
-
* condition `buildStatusCondition` produces (public: published
|
|
752
|
+
* condition `buildStatusCondition` produces (public: published only).
|
|
731
753
|
* `undefined` drops the status filter entirely — the admin all-statuses shape.
|
|
732
754
|
*/
|
|
733
755
|
status: string | undefined;
|
|
@@ -826,11 +848,11 @@ export function buildTaxonomyPivotQuery(
|
|
|
826
848
|
: sql``;
|
|
827
849
|
|
|
828
850
|
const firstGroupCond = pivotGroupCondition("ct.taxonomy_id", firstGroups);
|
|
829
|
-
const {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
);
|
|
851
|
+
const {
|
|
852
|
+
terms: termsSelect,
|
|
853
|
+
bylines: bylinesSelect,
|
|
854
|
+
bylinesExist: bylinesExistSelect,
|
|
855
|
+
} = foldedHydrationSelects(db, collection, "r");
|
|
834
856
|
|
|
835
857
|
// Authoritative re-check on the joined `ec_*` row.
|
|
836
858
|
const deletedR = deletedIsNull ? sql`r.deleted_at IS NULL` : sql`r.deleted_at IS NOT NULL`;
|
|
@@ -871,7 +893,7 @@ export function buildTaxonomyPivotQuery(
|
|
|
871
893
|
ORDER BY sortval ${dir}, ct.entry_id ${dir}
|
|
872
894
|
${limitClause}
|
|
873
895
|
)
|
|
874
|
-
SELECT r.*, ${termsSelect}, ${bylinesSelect}
|
|
896
|
+
SELECT r.*, ${termsSelect}, ${bylinesSelect}, ${bylinesExistSelect}
|
|
875
897
|
FROM picked JOIN ${sql.ref(tableName)} AS r ON r.id = picked.entry_id
|
|
876
898
|
WHERE ${deletedR} ${statusR} ${localeR}
|
|
877
899
|
ORDER BY picked.sortval ${dir}, picked.entry_id ${dir}
|
|
@@ -894,7 +916,7 @@ export function buildTaxonomyPivotQuery(
|
|
|
894
916
|
${residual}
|
|
895
917
|
${bylineCt}
|
|
896
918
|
)
|
|
897
|
-
SELECT r.*, ${termsSelect}, ${bylinesSelect}
|
|
919
|
+
SELECT r.*, ${termsSelect}, ${bylinesSelect}, ${bylinesExistSelect}
|
|
898
920
|
FROM picked JOIN ${sql.ref(tableName)} AS r ON r.id = picked.entry_id
|
|
899
921
|
WHERE ${deletedR} ${statusR} ${localeR}
|
|
900
922
|
${cursorCond}
|
|
@@ -1257,11 +1279,11 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
1257
1279
|
: sql``;
|
|
1258
1280
|
|
|
1259
1281
|
// Fold byline + taxonomy hydration into the list query.
|
|
1260
|
-
const {
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
);
|
|
1282
|
+
const {
|
|
1283
|
+
terms: termsSelect,
|
|
1284
|
+
bylines: bylinesSelect,
|
|
1285
|
+
bylinesExist: bylinesExistSelect,
|
|
1286
|
+
} = foldedHydrationSelects(db, type, tableName);
|
|
1265
1287
|
|
|
1266
1288
|
// LIMIT/OFFSET clause. SQLite only accepts OFFSET when a
|
|
1267
1289
|
// LIMIT is present, so a bare offset uses `LIMIT -1`
|
|
@@ -1277,7 +1299,7 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
1277
1299
|
: sql`LIMIT -1 OFFSET ${offset}`;
|
|
1278
1300
|
}
|
|
1279
1301
|
result = await sql<Record<string, unknown>>`
|
|
1280
|
-
SELECT *, ${termsSelect}, ${bylinesSelect} FROM ${sql.ref(tableName)}
|
|
1302
|
+
SELECT *, ${termsSelect}, ${bylinesSelect}, ${bylinesExistSelect} FROM ${sql.ref(tableName)}
|
|
1281
1303
|
WHERE deleted_at IS NULL
|
|
1282
1304
|
AND ${statusCondition}
|
|
1283
1305
|
${localeFilter}
|
|
@@ -1413,22 +1435,22 @@ export function emdashLoader(): LiveLoader<EntryData, EntryFilter, CollectionFil
|
|
|
1413
1435
|
// per-result-set column limit, surfacing as a silent null entry. One
|
|
1414
1436
|
// JSON column is one column, so the join stays safe at any width and
|
|
1415
1437
|
// we keep the single round trip.
|
|
1416
|
-
const {
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
);
|
|
1438
|
+
const {
|
|
1439
|
+
terms: termsSelect,
|
|
1440
|
+
bylines: bylinesSelect,
|
|
1441
|
+
bylinesExist: bylinesExistSelect,
|
|
1442
|
+
} = foldedHydrationSelects(db, type, "c");
|
|
1421
1443
|
const seoSelect = foldedSeoSelect(db, type, "c");
|
|
1422
1444
|
const result = locale
|
|
1423
1445
|
? await sql<Record<string, unknown>>`
|
|
1424
|
-
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}
|
|
1446
|
+
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}, ${bylinesExistSelect}
|
|
1425
1447
|
FROM ${sql.ref(tableName)} AS c
|
|
1426
1448
|
WHERE c.deleted_at IS NULL
|
|
1427
1449
|
AND ((c.slug = ${id} AND c.locale = ${locale}) OR c.id = ${id})
|
|
1428
1450
|
LIMIT 1
|
|
1429
1451
|
`.execute(db)
|
|
1430
1452
|
: await sql<Record<string, unknown>>`
|
|
1431
|
-
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}
|
|
1453
|
+
SELECT c.*, ${seoSelect}, ${termsSelect}, ${bylinesSelect}, ${bylinesExistSelect}
|
|
1432
1454
|
FROM ${sql.ref(tableName)} AS c
|
|
1433
1455
|
WHERE c.deleted_at IS NULL
|
|
1434
1456
|
AND (c.slug = ${id} OR c.id = ${id})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media-usage generation GC.
|
|
3
|
+
*
|
|
4
|
+
* Every save writes a fresh generation of `_emdash_media_usage` rows and
|
|
5
|
+
* leaves the superseded generation behind; reads join on
|
|
6
|
+
* `current_generation`, so non-current rows are dead weight. This sweep
|
|
7
|
+
* composes the repository GC methods behind a shared cutoff and batch limit,
|
|
8
|
+
* and is called from `runSystemCleanup` on every scheduler tick.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Kysely } from "kysely";
|
|
12
|
+
|
|
13
|
+
import { MediaUsageRepository } from "../../database/repositories/media-usage.js";
|
|
14
|
+
import type { Database } from "../../database/types.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Only rows older than this are collected. Guarded writers insert occurrence
|
|
18
|
+
* rows before winning the source CAS, so the window must exceed any plausible
|
|
19
|
+
* in-flight write; mirrors the pending-upload abandonment window.
|
|
20
|
+
*/
|
|
21
|
+
const GC_MAX_AGE_MS = 60 * 60 * 1000;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Per-tick cap on rows considered by each GC method, so a large backlog is
|
|
25
|
+
* amortized across ticks instead of one oversized batch (D1 bind limits).
|
|
26
|
+
*/
|
|
27
|
+
const GC_BATCH_LIMIT = 500;
|
|
28
|
+
|
|
29
|
+
export interface MediaUsageCleanupResult {
|
|
30
|
+
staleGenerations: number;
|
|
31
|
+
abandonedGenerations: number;
|
|
32
|
+
orphanOccurrences: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Delete media-usage occurrence rows that can no longer be read: superseded
|
|
37
|
+
* generations, generations abandoned by losing CAS writers, and occurrences
|
|
38
|
+
* whose source row is gone.
|
|
39
|
+
*/
|
|
40
|
+
export async function cleanupMediaUsageGenerations(
|
|
41
|
+
db: Kysely<Database>,
|
|
42
|
+
): Promise<MediaUsageCleanupResult> {
|
|
43
|
+
const cutoff = new Date(Date.now() - GC_MAX_AGE_MS).toISOString();
|
|
44
|
+
const repo = new MediaUsageRepository(db);
|
|
45
|
+
return {
|
|
46
|
+
staleGenerations: await repo.deleteStaleGenerationsOlderThan(cutoff, GC_BATCH_LIMIT),
|
|
47
|
+
abandonedGenerations: await repo.deleteAbandonedGenerationsOlderThan(cutoff, GC_BATCH_LIMIT),
|
|
48
|
+
orphanOccurrences: await repo.deleteOrphanOccurrencesOlderThan(cutoff, GC_BATCH_LIMIT),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -131,6 +131,8 @@ function raceInFlightEpochRead(
|
|
|
131
131
|
const BACKEND_KEY = Symbol.for("emdash:object-cache:backend");
|
|
132
132
|
const EPOCH_KEY = Symbol.for("emdash:object-cache:epochs");
|
|
133
133
|
const PENDING_KEY = Symbol.for("emdash:object-cache:pending-bumps");
|
|
134
|
+
const LAST_CONTENT_WRITE_KEY = Symbol.for("emdash:object-cache:last-content-write");
|
|
135
|
+
const PENDING_CONTENT_WRITE_KEY = Symbol.for("emdash:object-cache:pending-content-write");
|
|
134
136
|
const g = globalThis as Record<symbol, unknown>;
|
|
135
137
|
|
|
136
138
|
const holder: BackendHolder =
|
|
@@ -171,6 +173,39 @@ const pendingBumps: Set<string> =
|
|
|
171
173
|
return s;
|
|
172
174
|
})();
|
|
173
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Isolate-local ms-epoch of the last content-namespace invalidation, plus a
|
|
178
|
+
* cached backend read (same revalidate window as epochs). Adapters that need
|
|
179
|
+
* to prefer fresh SQL after a publish (e.g. Hyperdrive `cachedBinding`) read
|
|
180
|
+
* this via {@link getLastContentWriteAt}.
|
|
181
|
+
*/
|
|
182
|
+
interface LastContentWriteState {
|
|
183
|
+
/** Local / merged stamp; 0 if never set in this isolate. */
|
|
184
|
+
value: number;
|
|
185
|
+
/** `Date.now()` when `value` was last confirmed from the backend (or local stamp). */
|
|
186
|
+
at: number;
|
|
187
|
+
promise?: Promise<number>;
|
|
188
|
+
promiseAt?: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const lastContentWrite: LastContentWriteState =
|
|
192
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)
|
|
193
|
+
(g[LAST_CONTENT_WRITE_KEY] as LastContentWriteState | undefined) ??
|
|
194
|
+
(() => {
|
|
195
|
+
const s: LastContentWriteState = { value: 0, at: 0 };
|
|
196
|
+
g[LAST_CONTENT_WRITE_KEY] = s;
|
|
197
|
+
return s;
|
|
198
|
+
})();
|
|
199
|
+
|
|
200
|
+
/** Whether a backend persist of the content-write stamp is already scheduled. */
|
|
201
|
+
const contentWritePersist: { pending: boolean } =
|
|
202
|
+
// eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)
|
|
203
|
+
(g[PENDING_CONTENT_WRITE_KEY] as { pending: boolean } | undefined) ??
|
|
204
|
+
(() => {
|
|
205
|
+
const s = { pending: false };
|
|
206
|
+
g[PENDING_CONTENT_WRITE_KEY] = s;
|
|
207
|
+
return s;
|
|
208
|
+
})();
|
|
174
209
|
/**
|
|
175
210
|
* Resolve (once per isolate) the configured object-cache backend.
|
|
176
211
|
*
|
|
@@ -246,6 +281,11 @@ export function __setObjectCacheBackendForTests(
|
|
|
246
281
|
holder.backend = backend;
|
|
247
282
|
holder.config = { ...holder.config, ...config };
|
|
248
283
|
epochCache.clear();
|
|
284
|
+
lastContentWrite.value = 0;
|
|
285
|
+
lastContentWrite.at = 0;
|
|
286
|
+
lastContentWrite.promise = undefined;
|
|
287
|
+
lastContentWrite.promiseAt = undefined;
|
|
288
|
+
contentWritePersist.pending = false;
|
|
249
289
|
}
|
|
250
290
|
|
|
251
291
|
/** Build the backend key for a namespace's epoch anchor. */
|
|
@@ -253,6 +293,14 @@ function epochKey(namespace: string): string {
|
|
|
253
293
|
return `${holder.config.keyPrefix}:epoch:${namespace}`;
|
|
254
294
|
}
|
|
255
295
|
|
|
296
|
+
/** Backend key for the shared "last content write" stamp (no short TTL). */
|
|
297
|
+
function lastContentWriteKey(): string {
|
|
298
|
+
return `${holder.config.keyPrefix}:last-content-write-at`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function isContentNamespace(namespace: string): boolean {
|
|
302
|
+
return namespace.startsWith("content:");
|
|
303
|
+
}
|
|
256
304
|
/**
|
|
257
305
|
* Build the (epoch-independent) backend key for a cached value.
|
|
258
306
|
*
|
|
@@ -469,6 +517,95 @@ export async function isObjectCacheActive(): Promise<boolean> {
|
|
|
469
517
|
return backend !== null && !shouldBypass();
|
|
470
518
|
}
|
|
471
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Stamp the isolate-local + backend "last content write" marker when a
|
|
522
|
+
* content collection namespace is invalidated. Used by DB adapters (Hyperdrive)
|
|
523
|
+
* to briefly prefer uncached SQL after a publish so edge/object caches are not
|
|
524
|
+
* reseeded from a stale query-cache hit.
|
|
525
|
+
*/
|
|
526
|
+
function stampLastContentWrite(): void {
|
|
527
|
+
const stamp = Math.max(lastContentWrite.value + 1, Date.now());
|
|
528
|
+
lastContentWrite.value = stamp;
|
|
529
|
+
lastContentWrite.at = stamp;
|
|
530
|
+
// Drop any in-flight backend read so it cannot lower a fresher local stamp.
|
|
531
|
+
lastContentWrite.promise = undefined;
|
|
532
|
+
lastContentWrite.promiseAt = undefined;
|
|
533
|
+
|
|
534
|
+
if (contentWritePersist.pending) return;
|
|
535
|
+
contentWritePersist.pending = true;
|
|
536
|
+
after(async () => {
|
|
537
|
+
contentWritePersist.pending = false;
|
|
538
|
+
try {
|
|
539
|
+
const backend = await getBackend();
|
|
540
|
+
if (!backend) return;
|
|
541
|
+
const latest = lastContentWrite.value;
|
|
542
|
+
// Persistent (no TTL) — same contract as epoch anchors.
|
|
543
|
+
await backend.set(lastContentWriteKey(), String(latest));
|
|
544
|
+
} catch (error) {
|
|
545
|
+
console.error("[object-cache] last-content-write stamp failed:", error);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* ms-epoch of the last content-namespace invalidation (`content:*`), or `0`
|
|
552
|
+
* if unknown. Returns `max(local, backend)` so a warm isolate that just
|
|
553
|
+
* published is immediately correct, and cold isolates learn within their
|
|
554
|
+
* `revalidate` window after another isolate stamped the backend.
|
|
555
|
+
*/
|
|
556
|
+
export async function getLastContentWriteAt(): Promise<number> {
|
|
557
|
+
const local = lastContentWrite.value;
|
|
558
|
+
const now = Date.now();
|
|
559
|
+
// Cache a confirmed miss (`0`) the same way as a positive stamp — otherwise
|
|
560
|
+
// every logged-out request re-reads the backend until the first content write.
|
|
561
|
+
if (now - lastContentWrite.at < holder.config.revalidate) {
|
|
562
|
+
return local;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const backend = await getBackend();
|
|
566
|
+
if (!backend) return local;
|
|
567
|
+
|
|
568
|
+
if (lastContentWrite.promise) {
|
|
569
|
+
const age = now - (lastContentWrite.promiseAt ?? 0);
|
|
570
|
+
const deadline = epochReadDeadline();
|
|
571
|
+
if (age < deadline) {
|
|
572
|
+
return raceInFlightEpochRead(lastContentWrite.promise, deadline - age, local);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const promise = (async () => {
|
|
577
|
+
let value: number;
|
|
578
|
+
try {
|
|
579
|
+
const raw = await withTimeout(
|
|
580
|
+
backend.get(lastContentWriteKey()),
|
|
581
|
+
holder.config.timeout,
|
|
582
|
+
"last-content-write read",
|
|
583
|
+
);
|
|
584
|
+
const parsed = raw === null ? 0 : Number(raw);
|
|
585
|
+
value = Number.isFinite(parsed) ? parsed : 0;
|
|
586
|
+
} catch {
|
|
587
|
+
value = lastContentWrite.value;
|
|
588
|
+
}
|
|
589
|
+
const merged = Math.max(value, lastContentWrite.value);
|
|
590
|
+
lastContentWrite.value = merged;
|
|
591
|
+
lastContentWrite.at = Date.now();
|
|
592
|
+
lastContentWrite.promise = undefined;
|
|
593
|
+
lastContentWrite.promiseAt = undefined;
|
|
594
|
+
return merged;
|
|
595
|
+
})();
|
|
596
|
+
|
|
597
|
+
after(() =>
|
|
598
|
+
promise.then(
|
|
599
|
+
() => undefined,
|
|
600
|
+
() => undefined,
|
|
601
|
+
),
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
lastContentWrite.promise = promise;
|
|
605
|
+
lastContentWrite.promiseAt = now;
|
|
606
|
+
return promise;
|
|
607
|
+
}
|
|
608
|
+
|
|
472
609
|
/**
|
|
473
610
|
* Invalidate every cached value in `namespace` by bumping its epoch.
|
|
474
611
|
*
|
|
@@ -476,6 +613,8 @@ export async function isObjectCacheActive(): Promise<boolean> {
|
|
|
476
613
|
* writing isolate is instantly consistent) and the backend write is deferred
|
|
477
614
|
* via `after`. Other isolates pick up the new epoch within their `revalidate`
|
|
478
615
|
* window. No-ops when the cache is disabled.
|
|
616
|
+
*
|
|
617
|
+
* Content namespaces (`content:*`) also stamp {@link getLastContentWriteAt}.
|
|
479
618
|
*/
|
|
480
619
|
export function invalidateObjectCache(namespace: string): void {
|
|
481
620
|
// Monotonic so two writes in the same millisecond still produce distinct
|
|
@@ -486,6 +625,10 @@ export function invalidateObjectCache(namespace: string): void {
|
|
|
486
625
|
// Optimistic local bump: keep this isolate consistent without a round-trip.
|
|
487
626
|
epochCache.set(namespace, { value: stamp, at: stamp });
|
|
488
627
|
|
|
628
|
+
if (isContentNamespace(namespace)) {
|
|
629
|
+
stampLastContentWrite();
|
|
630
|
+
}
|
|
631
|
+
|
|
489
632
|
// Coalesce repeated bumps of the same namespace within a tick (e.g. a bulk
|
|
490
633
|
// publish loop) into a single backend write that persists the latest epoch.
|
|
491
634
|
if (pendingBumps.has(namespace)) return;
|
|
@@ -504,7 +647,6 @@ export function invalidateObjectCache(namespace: string): void {
|
|
|
504
647
|
}
|
|
505
648
|
});
|
|
506
649
|
}
|
|
507
|
-
|
|
508
650
|
/**
|
|
509
651
|
* Fixed namespaces for data shared across collections. Content reads fold the
|
|
510
652
|
* `BYLINES` and `TAXONOMIES` epochs into their keys (via {@link cachedQuery})
|
|
@@ -525,15 +667,28 @@ export const CacheNamespace = {
|
|
|
525
667
|
|
|
526
668
|
/** Namespace for a content collection's cached queries. */
|
|
527
669
|
export function contentNamespace(collection: string): string {
|
|
670
|
+
return `content:v2:${collection}`;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function legacyContentNamespace(collection: string): string {
|
|
528
674
|
return `content:${collection}`;
|
|
529
675
|
}
|
|
530
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Content epochs carried by current cache entries. The legacy epoch keeps
|
|
679
|
+
* invalidation compatible with publishers from the previous release during a
|
|
680
|
+
* rolling deployment; the versioned epoch makes old cached values unreachable.
|
|
681
|
+
*/
|
|
682
|
+
export function contentCacheNamespaces(collection: string): readonly string[] {
|
|
683
|
+
return [contentNamespace(collection), legacyContentNamespace(collection)];
|
|
684
|
+
}
|
|
685
|
+
|
|
531
686
|
/**
|
|
532
687
|
* Namespaces a content read depends on: the collection itself plus the shared
|
|
533
688
|
* byline/taxonomy data folded into each entry.
|
|
534
689
|
*/
|
|
535
690
|
export function contentNamespaces(collection: string): readonly string[] {
|
|
536
|
-
return [
|
|
691
|
+
return [...contentCacheNamespaces(collection), CacheNamespace.BYLINES, CacheNamespace.TAXONOMIES];
|
|
537
692
|
}
|
|
538
693
|
|
|
539
694
|
/**
|
|
@@ -541,7 +696,9 @@ export function contentNamespaces(collection: string): readonly string[] {
|
|
|
541
696
|
* Call from every write path that mutates rows in `ec_<collection>`.
|
|
542
697
|
*/
|
|
543
698
|
export function invalidateCollectionCache(collection: string): void {
|
|
544
|
-
|
|
699
|
+
for (const namespace of contentCacheNamespaces(collection)) {
|
|
700
|
+
invalidateObjectCache(namespace);
|
|
701
|
+
}
|
|
545
702
|
}
|
|
546
703
|
|
|
547
704
|
/** Invalidate cached taxonomy definitions/terms and all content that hydrates them. */
|
package/src/plugins/routes.ts
CHANGED
|
@@ -82,6 +82,40 @@ export function buildRouteMeta(route: {
|
|
|
82
82
|
return meta;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* HTTP methods that carry a request body. Everything else (GET, HEAD, DELETE)
|
|
87
|
+
* takes its route input from the URL query string.
|
|
88
|
+
*/
|
|
89
|
+
const BODY_METHODS = new Set(["POST", "PUT", "PATCH"]);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Parse a plugin route's input from the request, by method.
|
|
93
|
+
*
|
|
94
|
+
* Body methods (POST/PUT/PATCH) parse the JSON body as before. Bodyless
|
|
95
|
+
* methods (GET/HEAD/DELETE) have no body, so `request.json()` resolves to
|
|
96
|
+
* undefined and fails schema validation (#2146) — parse the query string into
|
|
97
|
+
* an object instead. Repeated keys (`?tag=a&tag=b`) become an array so array
|
|
98
|
+
* schemas work; a single key stays a scalar.
|
|
99
|
+
*/
|
|
100
|
+
export async function parseRouteInput(request: Request): Promise<unknown> {
|
|
101
|
+
if (BODY_METHODS.has(request.method.toUpperCase())) {
|
|
102
|
+
try {
|
|
103
|
+
return await request.json();
|
|
104
|
+
} catch {
|
|
105
|
+
// No body or not JSON
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const params = new URL(request.url).searchParams;
|
|
111
|
+
const input: Record<string, string | string[]> = {};
|
|
112
|
+
for (const key of new Set(params.keys())) {
|
|
113
|
+
const values = params.getAll(key);
|
|
114
|
+
input[key] = values.length > 1 ? values : values[0];
|
|
115
|
+
}
|
|
116
|
+
return input;
|
|
117
|
+
}
|
|
118
|
+
|
|
85
119
|
/**
|
|
86
120
|
* Result from a route invocation
|
|
87
121
|
*/
|
|
@@ -12,9 +12,9 @@ import { sql } from "kysely";
|
|
|
12
12
|
import { jsonExtractExpr, isPostgres } from "../database/dialect-helpers.js";
|
|
13
13
|
import type { Database } from "../database/types.js";
|
|
14
14
|
import {
|
|
15
|
-
validateIdentifier,
|
|
16
15
|
validateJsonFieldName,
|
|
17
16
|
validatePluginIdentifier,
|
|
17
|
+
validateStorageCollectionName,
|
|
18
18
|
} from "../database/validate.js";
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -36,8 +36,10 @@ export function generateIndexName(
|
|
|
36
36
|
/**
|
|
37
37
|
* Generate a Kysely sql expression for creating an expression index.
|
|
38
38
|
*
|
|
39
|
-
* Validates all
|
|
40
|
-
*
|
|
39
|
+
* Validates all inputs before interpolation. The collection uses the
|
|
40
|
+
* permissive manifest-key rules rather than SQL-identifier rules — it is
|
|
41
|
+
* stored as opaque text and only reaches SQL inside the generated index
|
|
42
|
+
* name — so kebab-case collections index like any other.
|
|
41
43
|
*/
|
|
42
44
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
|
|
43
45
|
export function generateCreateIndexSql(
|
|
@@ -47,9 +49,8 @@ export function generateCreateIndexSql(
|
|
|
47
49
|
fields: string[],
|
|
48
50
|
options?: { unique?: boolean },
|
|
49
51
|
): RawBuilder<unknown> {
|
|
50
|
-
// Validate all identifiers
|
|
51
52
|
validatePluginIdentifier(pluginId, "plugin ID");
|
|
52
|
-
|
|
53
|
+
validateStorageCollectionName(collection, "collection name");
|
|
53
54
|
for (const field of fields) {
|
|
54
55
|
validateJsonFieldName(field, "index field name");
|
|
55
56
|
}
|
|
@@ -68,14 +69,15 @@ export function generateCreateIndexSql(
|
|
|
68
69
|
})
|
|
69
70
|
.join(", ");
|
|
70
71
|
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// Composite non-partial index: the leading (plugin_id, collection) columns
|
|
73
|
+
// scope it per plugin/collection — including unique-index semantics — and
|
|
74
|
+
// let it serve the repository's bound-parameter WHERE plus the JSON
|
|
75
|
+
// expression ORDER BY. A partial index (WHERE plugin_id = 'x' AND
|
|
76
|
+
// collection = 'y') is never chosen by SQLite under bound parameters
|
|
77
|
+
// unless ANALYZE has run, and D1 never runs ANALYZE.
|
|
75
78
|
const createKeyword = options?.unique ? "CREATE UNIQUE INDEX" : "CREATE INDEX";
|
|
76
79
|
return sql`${sql.raw(createKeyword)} IF NOT EXISTS ${sql.ref(indexName)}
|
|
77
|
-
ON _plugin_storage(${sql.raw(expressions)})
|
|
78
|
-
WHERE plugin_id = ${sql.lit(pluginId)} AND collection = ${sql.lit(collection)}
|
|
80
|
+
ON _plugin_storage(plugin_id, collection, ${sql.raw(expressions)})
|
|
79
81
|
`;
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -254,6 +256,43 @@ export async function syncStorageIndexes(
|
|
|
254
256
|
};
|
|
255
257
|
}
|
|
256
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Materialize the storage indexes a set of plugins declare in their
|
|
261
|
+
* manifests. Failures are logged per collection and never thrown — a missing
|
|
262
|
+
* index affects query performance, not correctness, so it must not fail an
|
|
263
|
+
* install or a scheduler tick.
|
|
264
|
+
*/
|
|
265
|
+
export async function syncDeclaredStorageIndexes(
|
|
266
|
+
db: Kysely<Database>,
|
|
267
|
+
plugins: Array<{
|
|
268
|
+
id: string;
|
|
269
|
+
storage?: Record<
|
|
270
|
+
string,
|
|
271
|
+
{ indexes: Array<string | string[]>; uniqueIndexes?: Array<string | string[]> }
|
|
272
|
+
>;
|
|
273
|
+
}>,
|
|
274
|
+
): Promise<void> {
|
|
275
|
+
for (const plugin of plugins) {
|
|
276
|
+
for (const [collection, config] of Object.entries(plugin.storage ?? {})) {
|
|
277
|
+
try {
|
|
278
|
+
const result = await syncStorageIndexes(db, plugin.id, collection, config.indexes, {
|
|
279
|
+
uniqueIndexes: config.uniqueIndexes,
|
|
280
|
+
});
|
|
281
|
+
for (const failure of result.errors) {
|
|
282
|
+
console.error(
|
|
283
|
+
`[plugins] Failed to sync storage index ${failure.index} for ${plugin.id}/${collection}: ${failure.error}`,
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
} catch (error) {
|
|
287
|
+
console.error(
|
|
288
|
+
`[plugins] Failed to sync storage indexes for ${plugin.id}/${collection}:`,
|
|
289
|
+
error,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
257
296
|
/**
|
|
258
297
|
* Remove all indexes for a plugin
|
|
259
298
|
*/
|