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
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
ContentDateField,
|
|
19
19
|
} from "./types.js";
|
|
20
20
|
import {
|
|
21
|
+
ContentMutationConflictError,
|
|
21
22
|
EmDashValidationError,
|
|
22
23
|
ScheduledNotDueError,
|
|
23
24
|
encodeCursor,
|
|
@@ -26,10 +27,64 @@ import {
|
|
|
26
27
|
|
|
27
28
|
// Regex pattern for ULID validation
|
|
28
29
|
const ULID_PATTERN = /^[0-9A-Z]{26}$/;
|
|
30
|
+
const SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/;
|
|
29
31
|
|
|
30
32
|
// LIKE wildcards that must be escaped so user search input is matched literally.
|
|
31
33
|
const LIKE_WILDCARD_RE = /[\\%_]/g;
|
|
32
34
|
|
|
35
|
+
function nullableColumnMatch(column: string, value: string | null): ReturnType<typeof sql> {
|
|
36
|
+
validateIdentifier(column, "content column");
|
|
37
|
+
return value === null ? sql`${sql.ref(column)} IS NULL` : sql`${sql.ref(column)} = ${value}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function sameStoredValue(left: unknown, right: unknown): boolean {
|
|
41
|
+
return Object.is(serializeValue(left), serializeValue(right));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function matchesPublication(
|
|
45
|
+
observed: ContentItem,
|
|
46
|
+
existing: ContentItem,
|
|
47
|
+
revision: { data: Record<string, unknown> },
|
|
48
|
+
revisionId: string,
|
|
49
|
+
slug: string | null,
|
|
50
|
+
publishedAt: string,
|
|
51
|
+
updatedAt: string,
|
|
52
|
+
): boolean {
|
|
53
|
+
if (
|
|
54
|
+
observed.version !== existing.version + 1 ||
|
|
55
|
+
observed.status !== "published" ||
|
|
56
|
+
observed.slug !== slug ||
|
|
57
|
+
observed.liveRevisionId !== revisionId ||
|
|
58
|
+
observed.draftRevisionId !== null ||
|
|
59
|
+
observed.scheduledAt !== null ||
|
|
60
|
+
observed.publishedAt !== publishedAt ||
|
|
61
|
+
observed.updatedAt !== updatedAt
|
|
62
|
+
) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return Object.entries(revision.data).every(
|
|
67
|
+
([key, value]) =>
|
|
68
|
+
SYSTEM_COLUMNS.has(key) || key.startsWith("_") || sameStoredValue(observed.data[key], value),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function matchesPublicationFence(observed: ContentItem, existing: ContentItem): boolean {
|
|
73
|
+
return (
|
|
74
|
+
observed.version === existing.version &&
|
|
75
|
+
observed.status === existing.status &&
|
|
76
|
+
observed.liveRevisionId === existing.liveRevisionId &&
|
|
77
|
+
observed.draftRevisionId === existing.draftRevisionId &&
|
|
78
|
+
observed.scheduledAt === existing.scheduledAt
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isConfirmedStatementFailure(error: unknown): boolean {
|
|
83
|
+
if (typeof error !== "object" || error === null || !("code" in error)) return false;
|
|
84
|
+
const code = (error as { code?: unknown }).code;
|
|
85
|
+
return typeof code === "string" && (code.startsWith("SQLITE_") || SQLSTATE_PATTERN.test(code));
|
|
86
|
+
}
|
|
87
|
+
|
|
33
88
|
/**
|
|
34
89
|
* Whitelist mapping a public date-filter field to its physical column. Keeping
|
|
35
90
|
* this separate from `mapOrderField` makes the filterable set explicit and
|
|
@@ -591,15 +646,8 @@ export class ContentRepository {
|
|
|
591
646
|
const tableName = getTableName(type);
|
|
592
647
|
const now = new Date().toISOString();
|
|
593
648
|
|
|
594
|
-
//
|
|
595
|
-
//
|
|
596
|
-
// (version:updated_at) always moves — concurrent editors still get a
|
|
597
|
-
// 409 on stale saves. `updated_at` is stamped only when the request
|
|
598
|
-
// actually carries column writes: a draft-only save on a
|
|
599
|
-
// revision-supporting collection resolves to a column no-op here (all
|
|
600
|
-
// data went into draft storage), and stamping it anyway would register
|
|
601
|
-
// a phantom modification for public "last modified" consumers like
|
|
602
|
-
// sitemap <lastmod> and JSON-LD dateModified (#2143).
|
|
649
|
+
// Every update advances the optimistic-concurrency version. updated_at
|
|
650
|
+
// advances only when a content-row column actually changes.
|
|
603
651
|
const updates: Record<string, unknown> = {};
|
|
604
652
|
|
|
605
653
|
if (input.status !== undefined) {
|
|
@@ -1158,6 +1206,10 @@ export class ContentRepository {
|
|
|
1158
1206
|
* Lets callers resolve many edge groups without an N+1 per group. The caller
|
|
1159
1207
|
* groups the flat result by `translationGroup` itself.
|
|
1160
1208
|
*
|
|
1209
|
+
* `translation_group` leads the sort so the ordering follows
|
|
1210
|
+
* `idx_{table}_del_tg_locale` past its `deleted_at` equality; callers group by
|
|
1211
|
+
* `translationGroup`, so the per-group locale order they rely on is preserved.
|
|
1212
|
+
*
|
|
1161
1213
|
* `publishedOnly` restricts the result to `status = 'published'` — reference
|
|
1162
1214
|
* reads pass this for callers without `content:read_drafts` so draft/scheduled
|
|
1163
1215
|
* entries never leak through an edge traversal.
|
|
@@ -1184,7 +1236,7 @@ export class ContentRepository {
|
|
|
1184
1236
|
WHERE translation_group IN (${sql.join(chunk)})
|
|
1185
1237
|
AND deleted_at IS NULL
|
|
1186
1238
|
${publishedFilter}
|
|
1187
|
-
ORDER BY locale ASC
|
|
1239
|
+
ORDER BY translation_group ASC, locale ASC
|
|
1188
1240
|
`.execute(this.db);
|
|
1189
1241
|
for (const row of result.rows) items.push(this.mapRow(type, row));
|
|
1190
1242
|
}
|
|
@@ -1274,19 +1326,16 @@ export class ContentRepository {
|
|
|
1274
1326
|
* an explicit value to backdate a publish (e.g. when migrating content from
|
|
1275
1327
|
* another CMS).
|
|
1276
1328
|
*
|
|
1277
|
-
* `requireDue`
|
|
1278
|
-
* `
|
|
1279
|
-
*
|
|
1280
|
-
* between selection and publish. It claims the row with a single conditional
|
|
1281
|
-
* UPDATE (clearing `scheduled_at`) before any other write, so it is atomic
|
|
1282
|
-
* even on D1 (no multi-statement transactions) and serialises against
|
|
1283
|
-
* `unschedule()` and concurrent sweeps — no TOCTOU and no double publish.
|
|
1329
|
+
* `requireDue` gates the final update on the row still being due.
|
|
1330
|
+
* `expectedScheduledAt` additionally fences changes made after a sweep
|
|
1331
|
+
* selected the row but before publication preparation began.
|
|
1284
1332
|
*/
|
|
1285
1333
|
async publish(
|
|
1286
1334
|
type: string,
|
|
1287
1335
|
id: string,
|
|
1288
1336
|
publishedAt?: string,
|
|
1289
1337
|
requireDue = false,
|
|
1338
|
+
expectedScheduledAt?: string,
|
|
1290
1339
|
): Promise<ContentItem> {
|
|
1291
1340
|
const tableName = getTableName(type);
|
|
1292
1341
|
const now = new Date().toISOString();
|
|
@@ -1295,128 +1344,126 @@ export class ContentRepository {
|
|
|
1295
1344
|
if (!existing) {
|
|
1296
1345
|
throw new EmDashValidationError("Content item not found");
|
|
1297
1346
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
// before promoting any revision — so the row can't be double-published.
|
|
1305
|
-
let claimedScheduledAt: string | null = null;
|
|
1306
|
-
let claimedUpdatedAt: string | null = null;
|
|
1307
|
-
if (requireDue) {
|
|
1308
|
-
const claim = await sql`
|
|
1309
|
-
UPDATE ${sql.ref(tableName)}
|
|
1310
|
-
SET scheduled_at = NULL,
|
|
1311
|
-
updated_at = ${now}
|
|
1312
|
-
WHERE id = ${id}
|
|
1313
|
-
AND scheduled_at IS NOT NULL
|
|
1314
|
-
AND scheduled_at <= ${now}
|
|
1315
|
-
AND deleted_at IS NULL
|
|
1316
|
-
`.execute(this.db);
|
|
1317
|
-
if ((claim.numAffectedRows ?? 0n) === 0n) {
|
|
1318
|
-
throw new ScheduledNotDueError();
|
|
1319
|
-
}
|
|
1320
|
-
// Remember what we cleared so we can put it back if the publish work
|
|
1321
|
-
// below fails on a driver without transactions (see catch). Both
|
|
1322
|
-
// values come from the pre-claim snapshot: if a concurrent
|
|
1323
|
-
// reschedule-to-a-different-past-time landed between findById and the
|
|
1324
|
-
// claim, the restore writes the snapshot value rather than the one the
|
|
1325
|
-
// claim actually cleared. That window is tiny and the restore is
|
|
1326
|
-
// best-effort retry bookkeeping, so the imprecision is acceptable.
|
|
1327
|
-
claimedScheduledAt = existing.scheduledAt;
|
|
1328
|
-
claimedUpdatedAt = existing.updatedAt;
|
|
1347
|
+
if (
|
|
1348
|
+
requireDue &&
|
|
1349
|
+
expectedScheduledAt !== undefined &&
|
|
1350
|
+
existing.scheduledAt !== expectedScheduledAt
|
|
1351
|
+
) {
|
|
1352
|
+
throw new ScheduledNotDueError();
|
|
1329
1353
|
}
|
|
1330
1354
|
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
// step throws we must restore the schedule — otherwise the row is left
|
|
1334
|
-
// `scheduled` with `scheduled_at = NULL` and no sweep ever retries it.
|
|
1335
|
-
let publishCommitted = false;
|
|
1355
|
+
const revisionRepo = new RevisionRepository(this.db);
|
|
1356
|
+
let provisionalRevisionId: string | null = null;
|
|
1336
1357
|
try {
|
|
1337
|
-
const revisionRepo = new RevisionRepository(this.db);
|
|
1338
1358
|
let revisionToPublish = existing.draftRevisionId || existing.liveRevisionId;
|
|
1339
1359
|
|
|
1340
1360
|
if (!revisionToPublish) {
|
|
1341
|
-
// No revision exists - create one from current data
|
|
1342
1361
|
const revision = await revisionRepo.create({
|
|
1343
1362
|
collection: type,
|
|
1344
1363
|
entryId: id,
|
|
1345
1364
|
data: existing.data,
|
|
1346
1365
|
});
|
|
1347
1366
|
revisionToPublish = revision.id;
|
|
1367
|
+
provisionalRevisionId = revision.id;
|
|
1348
1368
|
}
|
|
1349
1369
|
|
|
1350
|
-
// Sync the revision's data into the content table columns
|
|
1351
|
-
// so the content table always holds the published version
|
|
1352
1370
|
const revision = await revisionRepo.findById(revisionToPublish);
|
|
1353
|
-
if (revision) {
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
// Validate before any write: the `(slug, locale)` unique index
|
|
1357
|
-
// covers every row (drafts and trashed entries included), and
|
|
1358
|
-
// letting the constraint fire mid-publish would surface as an
|
|
1359
|
-
// opaque 500 after draft data already hit the live columns.
|
|
1360
|
-
// A NULL locale never collides (unique indexes treat NULLs as
|
|
1361
|
-
// distinct), so the check only applies to localized rows.
|
|
1362
|
-
const stagedSlug = typeof revision.data._slug === "string" ? revision.data._slug : null;
|
|
1363
|
-
if (stagedSlug !== null && stagedSlug !== existing.slug && existing.locale !== null) {
|
|
1364
|
-
const conflict = await this.findBySlugIncludingTrashed(type, stagedSlug, existing.locale);
|
|
1365
|
-
if (conflict && conflict.id !== id) {
|
|
1366
|
-
throw new EmDashValidationError(
|
|
1367
|
-
`Cannot publish: slug '${stagedSlug}' is already used by another entry` +
|
|
1368
|
-
` in this collection (id: ${conflict.id}). Choose a different slug.`,
|
|
1369
|
-
{ code: "SLUG_CONFLICT" },
|
|
1370
|
-
);
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1371
|
+
if (!revision || revision.collection !== type || revision.entryId !== id) {
|
|
1372
|
+
throw new EmDashValidationError("Revision does not belong to the specified content item");
|
|
1373
|
+
}
|
|
1373
1374
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1375
|
+
const stagedSlug = typeof revision.data._slug === "string" ? revision.data._slug : null;
|
|
1376
|
+
const intendedSlug = stagedSlug ?? existing.slug;
|
|
1377
|
+
const intendedPublishedAt = publishedAt ?? existing.publishedAt ?? now;
|
|
1378
|
+
if (stagedSlug !== null && stagedSlug !== existing.slug && existing.locale !== null) {
|
|
1379
|
+
const conflict = await this.findBySlugIncludingTrashed(type, stagedSlug, existing.locale);
|
|
1380
|
+
if (conflict && conflict.id !== id) {
|
|
1381
|
+
throw new EmDashValidationError(
|
|
1382
|
+
`Cannot publish: slug '${stagedSlug}' is already used by another entry` +
|
|
1383
|
+
` in this collection (id: ${conflict.id}). Choose a different slug.`,
|
|
1384
|
+
{ code: "SLUG_CONFLICT" },
|
|
1385
|
+
);
|
|
1384
1386
|
}
|
|
1385
|
-
|
|
1386
|
-
await this.syncDataColumns(type, id, revision.data);
|
|
1387
1387
|
}
|
|
1388
1388
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1389
|
+
const assignments: ReturnType<typeof sql>[] = [];
|
|
1390
|
+
if (stagedSlug !== null) assignments.push(sql`slug = ${stagedSlug}`);
|
|
1391
|
+
for (const [key, value] of Object.entries(revision.data)) {
|
|
1392
|
+
if (SYSTEM_COLUMNS.has(key) || key.startsWith("_")) continue;
|
|
1393
|
+
validateIdentifier(key, "content field name");
|
|
1394
|
+
assignments.push(sql`${sql.ref(key)} = ${serializeValue(value)}`);
|
|
1395
|
+
}
|
|
1396
|
+
assignments.push(
|
|
1397
|
+
sql`live_revision_id = ${revisionToPublish}`,
|
|
1398
|
+
sql`draft_revision_id = NULL`,
|
|
1399
|
+
sql`status = 'published'`,
|
|
1400
|
+
sql`scheduled_at = NULL`,
|
|
1401
|
+
sql`published_at = ${intendedPublishedAt}`,
|
|
1402
|
+
sql`updated_at = ${now}`,
|
|
1403
|
+
sql`version = version + 1`,
|
|
1404
|
+
);
|
|
1405
|
+
|
|
1406
|
+
const duePredicate = requireDue
|
|
1407
|
+
? sql`AND scheduled_at IS NOT NULL AND scheduled_at <= ${now}`
|
|
1408
|
+
: sql``;
|
|
1409
|
+
let promoted = false;
|
|
1410
|
+
try {
|
|
1411
|
+
const result = await sql`
|
|
1407
1412
|
UPDATE ${sql.ref(tableName)}
|
|
1408
|
-
SET
|
|
1409
|
-
draft_revision_id = NULL,
|
|
1410
|
-
status = 'published',
|
|
1411
|
-
scheduled_at = NULL,
|
|
1412
|
-
published_at = COALESCE(published_at, ${now}),
|
|
1413
|
-
updated_at = ${now}
|
|
1413
|
+
SET ${sql.join(assignments, sql`, `)}
|
|
1414
1414
|
WHERE id = ${id}
|
|
1415
1415
|
AND deleted_at IS NULL
|
|
1416
|
+
AND version = ${existing.version}
|
|
1417
|
+
AND status = ${existing.status}
|
|
1418
|
+
AND ${nullableColumnMatch("live_revision_id", existing.liveRevisionId)}
|
|
1419
|
+
AND ${nullableColumnMatch("draft_revision_id", existing.draftRevisionId)}
|
|
1420
|
+
AND ${nullableColumnMatch("scheduled_at", existing.scheduledAt)}
|
|
1421
|
+
${duePredicate}
|
|
1422
|
+
AND EXISTS (
|
|
1423
|
+
SELECT 1 FROM revisions
|
|
1424
|
+
WHERE revisions.id = ${revisionToPublish}
|
|
1425
|
+
AND revisions.collection = ${type}
|
|
1426
|
+
AND revisions.entry_id = ${id}
|
|
1427
|
+
)
|
|
1416
1428
|
`.execute(this.db);
|
|
1429
|
+
promoted = (result.numAffectedRows ?? 0n) > 0n;
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
if (isConfirmedStatementFailure(error)) throw error;
|
|
1432
|
+
let observed: ContentItem | null;
|
|
1433
|
+
try {
|
|
1434
|
+
observed = await this.findById(type, id);
|
|
1435
|
+
} catch (reconciliationError) {
|
|
1436
|
+
throw new Error("Unable to confirm whether content publication completed", {
|
|
1437
|
+
cause: reconciliationError,
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
if (!observed) {
|
|
1441
|
+
throw new Error("Unable to confirm whether content publication completed", {
|
|
1442
|
+
cause: error,
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
promoted = matchesPublication(
|
|
1446
|
+
observed,
|
|
1447
|
+
existing,
|
|
1448
|
+
revision,
|
|
1449
|
+
revisionToPublish,
|
|
1450
|
+
intendedSlug,
|
|
1451
|
+
intendedPublishedAt,
|
|
1452
|
+
now,
|
|
1453
|
+
);
|
|
1454
|
+
if (!promoted && matchesPublicationFence(observed, existing)) throw error;
|
|
1455
|
+
if (!promoted) {
|
|
1456
|
+
throw new Error("Unable to confirm whether content publication completed", {
|
|
1457
|
+
cause: error,
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
if (!promoted) {
|
|
1463
|
+
throw requireDue ? new ScheduledNotDueError() : new ContentMutationConflictError();
|
|
1417
1464
|
}
|
|
1418
|
-
publishCommitted = true;
|
|
1419
1465
|
|
|
1466
|
+
invalidateCollectionCache(type);
|
|
1420
1467
|
await this.restampEntryPivot(type, id);
|
|
1421
1468
|
|
|
1422
1469
|
const updated = await this.findById(type, id);
|
|
@@ -1424,38 +1471,15 @@ export class ContentRepository {
|
|
|
1424
1471
|
throw new Error("Content not found");
|
|
1425
1472
|
}
|
|
1426
1473
|
|
|
1427
|
-
invalidateCollectionCache(type);
|
|
1428
1474
|
return updated;
|
|
1429
1475
|
} catch (error) {
|
|
1430
|
-
|
|
1431
|
-
// failed publish stays retryable. Skipped when the publish actually
|
|
1432
|
-
// committed (the failure was afterwards). On SQLite/Postgres the
|
|
1433
|
-
// enclosing transaction rolls the claim back, so this restore also
|
|
1434
|
-
// rolls back — a harmless no-op. Never mask the original error.
|
|
1435
|
-
if (requireDue && claimedScheduledAt && !publishCommitted) {
|
|
1476
|
+
if (provisionalRevisionId) {
|
|
1436
1477
|
try {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
// queued. This avoids re-adding a stale schedule (and triggering a
|
|
1440
|
-
// redundant republish) when another actor fully published the row
|
|
1441
|
-
// in the failure window — that publish clears draft_revision_id.
|
|
1442
|
-
// Restore updated_at to its pre-claim value too — the claim bumped
|
|
1443
|
-
// it to `now`, and a failed publish made no real change, so leaving
|
|
1444
|
-
// it advanced would be a phantom modification for "changed since"
|
|
1445
|
-
// consumers (sync, ETags, incremental indexers).
|
|
1446
|
-
await sql`
|
|
1447
|
-
UPDATE ${sql.ref(tableName)}
|
|
1448
|
-
SET scheduled_at = ${claimedScheduledAt},
|
|
1449
|
-
updated_at = ${claimedUpdatedAt ?? now}
|
|
1450
|
-
WHERE id = ${id}
|
|
1451
|
-
AND scheduled_at IS NULL
|
|
1452
|
-
AND deleted_at IS NULL
|
|
1453
|
-
AND (status != 'published' OR draft_revision_id IS NOT NULL)
|
|
1454
|
-
`.execute(this.db);
|
|
1455
|
-
} catch (restoreError) {
|
|
1478
|
+
await revisionRepo.deleteIfUnreferenced(type, id, provisionalRevisionId);
|
|
1479
|
+
} catch (cleanupError) {
|
|
1456
1480
|
console.error(
|
|
1457
|
-
`[content] Failed to
|
|
1458
|
-
|
|
1481
|
+
`[content] Failed to clean up provisional revision ${provisionalRevisionId}:`,
|
|
1482
|
+
cleanupError,
|
|
1459
1483
|
);
|
|
1460
1484
|
}
|
|
1461
1485
|
}
|
|
@@ -1530,8 +1554,6 @@ export class ContentRepository {
|
|
|
1530
1554
|
* content row pointing at a missing or unrelated revision.
|
|
1531
1555
|
*/
|
|
1532
1556
|
async setDraftRevision(type: string, id: string, revisionId: string): Promise<void> {
|
|
1533
|
-
const tableName = getTableName(type);
|
|
1534
|
-
|
|
1535
1557
|
const existing = await this.findById(type, id);
|
|
1536
1558
|
if (!existing) {
|
|
1537
1559
|
throw new EmDashValidationError("Content item not found");
|
|
@@ -1547,15 +1569,35 @@ export class ContentRepository {
|
|
|
1547
1569
|
throw new EmDashValidationError("Revision does not belong to the specified content item");
|
|
1548
1570
|
}
|
|
1549
1571
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1572
|
+
if (!(await this.replaceDraftRevision(type, id, revisionId, existing))) {
|
|
1573
|
+
throw new ContentMutationConflictError();
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
async replaceDraftRevision(
|
|
1578
|
+
type: string,
|
|
1579
|
+
id: string,
|
|
1580
|
+
revisionId: string,
|
|
1581
|
+
expected: Pick<ContentItem, "version" | "liveRevisionId" | "draftRevisionId">,
|
|
1582
|
+
): Promise<boolean> {
|
|
1583
|
+
const tableName = getTableName(type);
|
|
1584
|
+
const result = await sql`
|
|
1554
1585
|
UPDATE ${sql.ref(tableName)}
|
|
1555
|
-
SET draft_revision_id = ${revisionId}
|
|
1586
|
+
SET draft_revision_id = ${revisionId},
|
|
1587
|
+
version = version + 1
|
|
1556
1588
|
WHERE id = ${id}
|
|
1557
1589
|
AND deleted_at IS NULL
|
|
1590
|
+
AND version = ${expected.version}
|
|
1591
|
+
AND ${nullableColumnMatch("live_revision_id", expected.liveRevisionId)}
|
|
1592
|
+
AND ${nullableColumnMatch("draft_revision_id", expected.draftRevisionId)}
|
|
1593
|
+
AND EXISTS (
|
|
1594
|
+
SELECT 1 FROM revisions
|
|
1595
|
+
WHERE revisions.id = ${revisionId}
|
|
1596
|
+
AND revisions.collection = ${type}
|
|
1597
|
+
AND revisions.entry_id = ${id}
|
|
1598
|
+
)
|
|
1558
1599
|
`.execute(this.db);
|
|
1600
|
+
return (result.numAffectedRows ?? 0n) > 0n;
|
|
1559
1601
|
}
|
|
1560
1602
|
|
|
1561
1603
|
/**
|
|
@@ -1595,35 +1637,6 @@ export class ContentRepository {
|
|
|
1595
1637
|
return updated;
|
|
1596
1638
|
}
|
|
1597
1639
|
|
|
1598
|
-
/**
|
|
1599
|
-
* Sync data columns in the content table from a data object.
|
|
1600
|
-
* Used to promote revision data into the content table on publish.
|
|
1601
|
-
* Keys starting with _ are revision metadata (e.g. _slug) and are skipped.
|
|
1602
|
-
*/
|
|
1603
|
-
private async syncDataColumns(
|
|
1604
|
-
type: string,
|
|
1605
|
-
id: string,
|
|
1606
|
-
data: Record<string, unknown>,
|
|
1607
|
-
): Promise<void> {
|
|
1608
|
-
const tableName = getTableName(type);
|
|
1609
|
-
const updates: Record<string, unknown> = {};
|
|
1610
|
-
|
|
1611
|
-
for (const [key, value] of Object.entries(data)) {
|
|
1612
|
-
if (SYSTEM_COLUMNS.has(key)) continue;
|
|
1613
|
-
if (key.startsWith("_")) continue; // revision metadata
|
|
1614
|
-
validateIdentifier(key, "content field name");
|
|
1615
|
-
updates[key] = serializeValue(value);
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
|
-
if (Object.keys(updates).length === 0) return;
|
|
1619
|
-
|
|
1620
|
-
await this.db
|
|
1621
|
-
.updateTable(tableName as keyof Database)
|
|
1622
|
-
.set(updates)
|
|
1623
|
-
.where("id", "=", id)
|
|
1624
|
-
.execute();
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
1640
|
/**
|
|
1628
1641
|
* Count content items with a pending schedule.
|
|
1629
1642
|
* Includes both draft-scheduled (status='scheduled') and published
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { sql, type Kysely } from "kysely";
|
|
2
2
|
import { monotonicFactory } from "ulidx";
|
|
3
3
|
|
|
4
4
|
import type { Database, RevisionTable } from "../types.js";
|
|
5
|
+
import { validateIdentifier } from "../validate.js";
|
|
5
6
|
|
|
6
7
|
const monotonic = monotonicFactory();
|
|
7
8
|
|
|
@@ -50,6 +51,26 @@ export class RevisionRepository {
|
|
|
50
51
|
if (!revision) {
|
|
51
52
|
throw new Error("Failed to create revision");
|
|
52
53
|
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
await this.db
|
|
57
|
+
.insertInto("_emdash_revision_prune_queue")
|
|
58
|
+
.values({
|
|
59
|
+
collection: input.collection,
|
|
60
|
+
entry_id: input.entryId,
|
|
61
|
+
revision_id: id,
|
|
62
|
+
})
|
|
63
|
+
.onConflict((conflict) =>
|
|
64
|
+
conflict.columns(["collection", "entry_id"]).doUpdateSet({ revision_id: id }),
|
|
65
|
+
)
|
|
66
|
+
.execute();
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error(
|
|
69
|
+
`[revisions] Failed to queue revision pruning for ${input.collection}/${input.entryId}:`,
|
|
70
|
+
error,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
53
74
|
return revision;
|
|
54
75
|
}
|
|
55
76
|
|
|
@@ -132,6 +153,19 @@ export class RevisionRepository {
|
|
|
132
153
|
.where("entry_id", "=", entryId)
|
|
133
154
|
.executeTakeFirst();
|
|
134
155
|
|
|
156
|
+
try {
|
|
157
|
+
await this.db
|
|
158
|
+
.deleteFrom("_emdash_revision_prune_queue")
|
|
159
|
+
.where("collection", "=", collection)
|
|
160
|
+
.where("entry_id", "=", entryId)
|
|
161
|
+
.execute();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error(
|
|
164
|
+
`[revisions] Failed to clear queued revision pruning for ${collection}/${entryId}:`,
|
|
165
|
+
error,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
135
169
|
return Number(result.numDeletedRows ?? 0);
|
|
136
170
|
}
|
|
137
171
|
|
|
@@ -139,6 +173,8 @@ export class RevisionRepository {
|
|
|
139
173
|
* Delete old revisions, keeping the most recent N
|
|
140
174
|
*/
|
|
141
175
|
async pruneOldRevisions(collection: string, entryId: string, keepCount: number): Promise<number> {
|
|
176
|
+
validateIdentifier(collection, "collection");
|
|
177
|
+
const tableName = `ec_${collection}`;
|
|
142
178
|
// Get IDs of revisions to keep
|
|
143
179
|
const keep = await this.db
|
|
144
180
|
.selectFrom("revisions")
|
|
@@ -154,27 +190,56 @@ export class RevisionRepository {
|
|
|
154
190
|
|
|
155
191
|
if (keepIds.length === 0) return 0;
|
|
156
192
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
.
|
|
162
|
-
|
|
163
|
-
|
|
193
|
+
const result = await sql`
|
|
194
|
+
DELETE FROM revisions
|
|
195
|
+
WHERE collection = ${collection}
|
|
196
|
+
AND entry_id = ${entryId}
|
|
197
|
+
AND id NOT IN (${sql.join(keepIds.map((id) => sql`${id}`))})
|
|
198
|
+
AND NOT EXISTS (
|
|
199
|
+
SELECT 1 FROM ${sql.ref(tableName)} AS content
|
|
200
|
+
WHERE content.live_revision_id = revisions.id
|
|
201
|
+
OR content.draft_revision_id = revisions.id
|
|
202
|
+
)
|
|
203
|
+
`.execute(this.db);
|
|
164
204
|
|
|
165
|
-
return Number(result.
|
|
205
|
+
return Number(result.numAffectedRows ?? 0);
|
|
166
206
|
}
|
|
167
207
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
208
|
+
async pruneQueuedEntry(
|
|
209
|
+
collection: string,
|
|
210
|
+
entryId: string,
|
|
211
|
+
queuedRevisionId: string,
|
|
212
|
+
keepCount: number,
|
|
213
|
+
): Promise<number> {
|
|
214
|
+
const pruned = await this.pruneOldRevisions(collection, entryId, keepCount);
|
|
173
215
|
await this.db
|
|
174
|
-
.
|
|
175
|
-
.
|
|
176
|
-
.where("
|
|
216
|
+
.deleteFrom("_emdash_revision_prune_queue")
|
|
217
|
+
.where("collection", "=", collection)
|
|
218
|
+
.where("entry_id", "=", entryId)
|
|
219
|
+
.where("revision_id", "=", queuedRevisionId)
|
|
177
220
|
.execute();
|
|
221
|
+
return pruned;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async deleteIfUnreferenced(
|
|
225
|
+
collection: string,
|
|
226
|
+
entryId: string,
|
|
227
|
+
revisionId: string,
|
|
228
|
+
): Promise<boolean> {
|
|
229
|
+
validateIdentifier(collection, "collection");
|
|
230
|
+
const tableName = `ec_${collection}`;
|
|
231
|
+
const result = await sql`
|
|
232
|
+
DELETE FROM revisions
|
|
233
|
+
WHERE id = ${revisionId}
|
|
234
|
+
AND collection = ${collection}
|
|
235
|
+
AND entry_id = ${entryId}
|
|
236
|
+
AND NOT EXISTS (
|
|
237
|
+
SELECT 1 FROM ${sql.ref(tableName)} AS content
|
|
238
|
+
WHERE content.live_revision_id = revisions.id
|
|
239
|
+
OR content.draft_revision_id = revisions.id
|
|
240
|
+
)
|
|
241
|
+
`.execute(this.db);
|
|
242
|
+
return (result.numAffectedRows ?? 0n) > 0n;
|
|
178
243
|
}
|
|
179
244
|
|
|
180
245
|
/**
|