emdash 0.28.0 → 0.29.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.
Files changed (687) hide show
  1. package/dist/{adapters-hUy8vOB-.d.mts → adapters-DPAkL6QF.d.mts} +1 -1
  2. package/dist/{adapters-hUy8vOB-.d.mts.map → adapters-DPAkL6QF.d.mts.map} +1 -1
  3. package/dist/{allowed-origins-CRsJ6BPM.mjs → allowed-origins-FXB-FplB.mjs} +2 -2
  4. package/dist/{allowed-origins-CRsJ6BPM.mjs.map → allowed-origins-FXB-FplB.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.mjs +22 -21
  7. package/dist/api/route-utils.mjs.map +1 -1
  8. package/dist/api/schemas/index.d.mts +2 -2
  9. package/dist/api/schemas/index.mjs +4 -4
  10. package/dist/{api-BFURZn1i.mjs → api-DVbHNApo.mjs} +75 -23
  11. package/dist/api-DVbHNApo.mjs.map +1 -0
  12. package/dist/{api-tokens-DvqeZmVq.mjs → api-tokens-UYBkl17d.mjs} +2 -2
  13. package/dist/{api-tokens-DvqeZmVq.mjs.map → api-tokens-UYBkl17d.mjs.map} +1 -1
  14. package/dist/{apply-Bu-8nYHL.mjs → apply-D23iUV4q.mjs} +20 -20
  15. package/dist/{apply-Bu-8nYHL.mjs.map → apply-D23iUV4q.mjs.map} +1 -1
  16. package/dist/astro/index.d.mts +13 -12
  17. package/dist/astro/index.d.mts.map +1 -1
  18. package/dist/astro/index.mjs +10 -5
  19. package/dist/astro/index.mjs.map +1 -1
  20. package/dist/astro/middleware/auth.d.mts +11 -10
  21. package/dist/astro/middleware/auth.d.mts.map +1 -1
  22. package/dist/astro/middleware/auth.mjs +8 -8
  23. package/dist/astro/middleware/redirect.mjs +7 -7
  24. package/dist/astro/middleware/request-context.d.mts +3 -0
  25. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  26. package/dist/astro/middleware/request-context.mjs +257 -30
  27. package/dist/astro/middleware/request-context.mjs.map +1 -1
  28. package/dist/astro/middleware/setup.mjs +1 -1
  29. package/dist/astro/middleware.d.mts +2 -2
  30. package/dist/astro/middleware.d.mts.map +1 -1
  31. package/dist/astro/middleware.mjs +125 -79
  32. package/dist/astro/middleware.mjs.map +1 -1
  33. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +7 -7
  34. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +7 -7
  35. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
  36. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  37. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  38. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -10
  39. package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -10
  40. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -10
  41. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +17 -17
  42. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +17 -17
  43. package/dist/astro/routes/api/admin/bylines/index.mjs +17 -17
  44. package/dist/astro/routes/api/admin/comments/_id_/status.d.mts.map +1 -1
  45. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -13
  46. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  48. package/dist/astro/routes/api/admin/comments/bulk.mjs +10 -10
  49. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  50. package/dist/astro/routes/api/admin/comments/index.d.mts.map +1 -1
  51. package/dist/astro/routes/api/admin/comments/index.mjs +10 -10
  52. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  54. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  55. package/dist/astro/routes/api/admin/media-usage/repair.d.mts +8 -0
  56. package/dist/astro/routes/api/admin/media-usage/repair.d.mts.map +1 -0
  57. package/dist/astro/routes/api/admin/media-usage/repair.mjs +28 -0
  58. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -0
  59. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
  60. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
  61. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +43 -41
  62. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +43 -41
  64. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +42 -40
  66. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +42 -40
  68. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +42 -40
  70. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/plugins/index.mjs +42 -40
  72. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
  74. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +42 -40
  75. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  76. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +42 -40
  77. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  78. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +42 -40
  79. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +42 -40
  81. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +43 -41
  83. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +42 -40
  85. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +43 -41
  87. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/plugins/updates.mjs +42 -40
  89. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +42 -40
  91. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
  93. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +42 -40
  94. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  95. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  96. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -3
  97. package/dist/astro/routes/api/admin/users/_id_/index.mjs +8 -8
  98. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
  99. package/dist/astro/routes/api/admin/users/index.mjs +7 -7
  100. package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
  101. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -3
  102. package/dist/astro/routes/api/auth/invite/complete.mjs +12 -12
  103. package/dist/astro/routes/api/auth/invite/index.mjs +9 -9
  104. package/dist/astro/routes/api/auth/invite/register-options.mjs +11 -11
  105. package/dist/astro/routes/api/auth/logout.mjs +4 -4
  106. package/dist/astro/routes/api/auth/magic-link/send.mjs +11 -11
  107. package/dist/astro/routes/api/auth/magic-link/verify.mjs +4 -4
  108. package/dist/astro/routes/api/auth/me.mjs +8 -8
  109. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  110. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  111. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  112. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  113. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  114. package/dist/astro/routes/api/auth/passkey/_id_.mjs +7 -7
  115. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
  116. package/dist/astro/routes/api/auth/passkey/options.mjs +13 -13
  117. package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -11
  118. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -12
  119. package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -12
  120. package/dist/astro/routes/api/auth/signup/complete.mjs +12 -12
  121. package/dist/astro/routes/api/auth/signup/request.mjs +11 -11
  122. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -3
  123. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.d.mts.map +1 -1
  124. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +69 -14
  125. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  126. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -13
  127. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -4
  128. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +4 -4
  129. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -4
  130. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -4
  131. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +12 -12
  132. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +8 -8
  133. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts +9 -0
  134. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -0
  135. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +71 -0
  136. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -0
  137. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts +8 -0
  138. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.d.mts.map +1 -0
  139. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +50 -0
  140. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -0
  141. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -4
  142. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -4
  143. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +8 -8
  144. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +15 -15
  145. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -4
  146. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +4 -4
  147. package/dist/astro/routes/api/content/_collection_/_id_.mjs +8 -8
  148. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -4
  149. package/dist/astro/routes/api/content/_collection_/index.mjs +8 -8
  150. package/dist/astro/routes/api/content/_collection_/trash.mjs +8 -8
  151. package/dist/astro/routes/api/dashboard.mjs +8 -8
  152. package/dist/astro/routes/api/dev/emails.mjs +4 -4
  153. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  154. package/dist/astro/routes/api/import/probe.mjs +18 -18
  155. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -5
  156. package/dist/astro/routes/api/import/wordpress/execute.d.mts +12 -11
  157. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  158. package/dist/astro/routes/api/import/wordpress/execute.mjs +16 -16
  159. package/dist/astro/routes/api/import/wordpress/media.d.mts +11 -10
  160. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  161. package/dist/astro/routes/api/import/wordpress/media.mjs +11 -11
  162. package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -11
  163. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +12 -16
  164. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  165. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -11
  166. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  167. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +18 -18
  168. package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
  169. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +12 -11
  170. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  171. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +28 -28
  172. package/dist/astro/routes/api/manifest.mjs +6 -6
  173. package/dist/astro/routes/api/mcp.mjs +56 -47
  174. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  175. package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -9
  176. package/dist/astro/routes/api/media/_id_.mjs +8 -8
  177. package/dist/astro/routes/api/media/file/_...key_.mjs +3 -3
  178. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
  179. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
  180. package/dist/astro/routes/api/media/providers/index.mjs +4 -4
  181. package/dist/astro/routes/api/media/upload-url.mjs +10 -10
  182. package/dist/astro/routes/api/media.mjs +13 -13
  183. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +9 -9
  184. package/dist/astro/routes/api/menus/_name_/items.mjs +9 -9
  185. package/dist/astro/routes/api/menus/_name_/reorder.mjs +9 -9
  186. package/dist/astro/routes/api/menus/_name_/translations.mjs +9 -9
  187. package/dist/astro/routes/api/menus/_name_.mjs +9 -9
  188. package/dist/astro/routes/api/menus/index.mjs +9 -9
  189. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  190. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
  191. package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
  192. package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
  193. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  194. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
  195. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
  196. package/dist/astro/routes/api/oauth/token.mjs +7 -7
  197. package/dist/astro/routes/api/openapi.json.mjs +24 -5
  198. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  199. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
  200. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +7 -15
  201. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  202. package/dist/astro/routes/api/redirects/404s/index.mjs +12 -12
  203. package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -12
  204. package/dist/astro/routes/api/redirects/_id_.mjs +13 -13
  205. package/dist/astro/routes/api/redirects/index.mjs +13 -13
  206. package/dist/astro/routes/api/relations/_id_/index.d.mts +10 -0
  207. package/dist/astro/routes/api/relations/_id_/index.d.mts.map +1 -0
  208. package/dist/astro/routes/api/relations/_id_/index.mjs +69 -0
  209. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -0
  210. package/dist/astro/routes/api/relations/_id_/translations.d.mts +8 -0
  211. package/dist/astro/routes/api/relations/_id_/translations.d.mts.map +1 -0
  212. package/dist/astro/routes/api/relations/_id_/translations.mjs +34 -0
  213. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -0
  214. package/dist/astro/routes/api/relations/index.d.mts +9 -0
  215. package/dist/astro/routes/api/relations/index.d.mts.map +1 -0
  216. package/dist/astro/routes/api/relations/index.mjs +53 -0
  217. package/dist/astro/routes/api/relations/index.mjs.map +1 -0
  218. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
  219. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -4
  220. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.d.mts.map +1 -1
  221. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +42 -40
  222. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  223. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.d.mts.map +1 -1
  224. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +42 -40
  225. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  226. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +42 -40
  227. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  228. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +42 -40
  229. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  230. package/dist/astro/routes/api/schema/collections/index.mjs +42 -40
  231. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  232. package/dist/astro/routes/api/schema/index.mjs +9 -9
  233. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +42 -40
  234. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  235. package/dist/astro/routes/api/schema/orphans/index.mjs +42 -40
  236. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  237. package/dist/astro/routes/api/search/enable.mjs +12 -12
  238. package/dist/astro/routes/api/search/index.mjs +13 -12
  239. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  240. package/dist/astro/routes/api/search/rebuild.mjs +12 -12
  241. package/dist/astro/routes/api/search/stats.mjs +8 -8
  242. package/dist/astro/routes/api/search/suggest.mjs +11 -11
  243. package/dist/astro/routes/api/sections/_slug_.mjs +11 -11
  244. package/dist/astro/routes/api/sections/index.mjs +11 -11
  245. package/dist/astro/routes/api/settings/email.mjs +6 -6
  246. package/dist/astro/routes/api/settings.mjs +15 -15
  247. package/dist/astro/routes/api/setup/admin-verify.mjs +13 -13
  248. package/dist/astro/routes/api/setup/admin.mjs +12 -12
  249. package/dist/astro/routes/api/setup/dev-bypass.mjs +29 -29
  250. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  251. package/dist/astro/routes/api/setup/index.mjs +30 -30
  252. package/dist/astro/routes/api/setup/status.mjs +5 -5
  253. package/dist/astro/routes/api/snapshot.mjs +8 -8
  254. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +15 -15
  255. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +15 -15
  256. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +15 -15
  257. package/dist/astro/routes/api/taxonomies/index.mjs +15 -15
  258. package/dist/astro/routes/api/themes/preview.mjs +7 -7
  259. package/dist/astro/routes/api/typegen.mjs +6 -6
  260. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  261. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  262. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  263. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +8 -8
  264. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -12
  265. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -12
  266. package/dist/astro/routes/api/widget-areas/_name_.mjs +8 -8
  267. package/dist/astro/routes/api/widget-areas/index.mjs +12 -12
  268. package/dist/astro/routes/api/widget-components.mjs +4 -4
  269. package/dist/astro/routes/robots.txt.mjs +9 -9
  270. package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -12
  271. package/dist/astro/routes/sitemap.xml.mjs +10 -10
  272. package/dist/astro/types.d.mts +16 -13
  273. package/dist/astro/types.d.mts.map +1 -1
  274. package/dist/auth/providers/github.d.mts +1 -1
  275. package/dist/auth/providers/google.d.mts +1 -1
  276. package/dist/{authorize-Dz88F_Fw.mjs → authorize-BmCwQCib.mjs} +2 -2
  277. package/dist/{authorize-Dz88F_Fw.mjs.map → authorize-BmCwQCib.mjs.map} +1 -1
  278. package/dist/{base64-CmWvODNW.mjs → base64-C74Msx8h.mjs} +1 -1
  279. package/dist/{base64-CmWvODNW.mjs.map → base64-C74Msx8h.mjs.map} +1 -1
  280. package/dist/{byline-Bm8ZgUP9.mjs → byline-BWb5H-65.mjs} +8 -8
  281. package/dist/{byline-Bm8ZgUP9.mjs.map → byline-BWb5H-65.mjs.map} +1 -1
  282. package/dist/{byline-fields-CIx_GuN4.mjs → byline-fields-DO6bAYK8.mjs} +2 -2
  283. package/dist/{byline-fields-CIx_GuN4.mjs.map → byline-fields-DO6bAYK8.mjs.map} +1 -1
  284. package/dist/{byline-registry-BOjqDOim.mjs → byline-registry-BCuOp4UF.mjs} +3 -3
  285. package/dist/{byline-registry-BOjqDOim.mjs.map → byline-registry-BCuOp4UF.mjs.map} +1 -1
  286. package/dist/{bylines-6tm9mgQb.mjs → bylines-BGuKFaBy.mjs} +4 -4
  287. package/dist/{bylines-6tm9mgQb.mjs.map → bylines-BGuKFaBy.mjs.map} +1 -1
  288. package/dist/{bylines-Woq87129.mjs → bylines-CHojDMpj.mjs} +8 -8
  289. package/dist/{bylines-Woq87129.mjs.map → bylines-CHojDMpj.mjs.map} +1 -1
  290. package/dist/{cache-CEBAZjir.mjs → cache-BeR7RfN8.mjs} +3 -3
  291. package/dist/{cache-CEBAZjir.mjs.map → cache-BeR7RfN8.mjs.map} +1 -1
  292. package/dist/{challenge-store-anhwVER0.mjs → challenge-store-B426wQ6O.mjs} +1 -1
  293. package/dist/{challenge-store-anhwVER0.mjs.map → challenge-store-B426wQ6O.mjs.map} +1 -1
  294. package/dist/{chunks-B2isWQhr.mjs → chunks-BU5_nrAC.mjs} +2 -2
  295. package/dist/{chunks-B2isWQhr.mjs.map → chunks-BU5_nrAC.mjs.map} +1 -1
  296. package/dist/cli/index.mjs +28 -28
  297. package/dist/cli/index.mjs.map +1 -1
  298. package/dist/client/cf-access.d.mts +1 -1
  299. package/dist/client/index.d.mts +34 -2
  300. package/dist/client/index.d.mts.map +1 -1
  301. package/dist/client/index.mjs +6 -2
  302. package/dist/client/index.mjs.map +1 -1
  303. package/dist/{comment-CzeatwBV.mjs → comment-SWh31kS0.mjs} +2 -2
  304. package/dist/{comment-CzeatwBV.mjs.map → comment-SWh31kS0.mjs.map} +1 -1
  305. package/dist/{comment-reaction-Cj9QJY7I.mjs → comment-reaction-DgcpziXI.mjs} +2 -2
  306. package/dist/{comment-reaction-Cj9QJY7I.mjs.map → comment-reaction-DgcpziXI.mjs.map} +1 -1
  307. package/dist/{comments-BLE-jv5k.mjs → comments-kZYGppMS.mjs} +3 -3
  308. package/dist/{comments-BLE-jv5k.mjs.map → comments-kZYGppMS.mjs.map} +1 -1
  309. package/dist/{components-B_sATNUc.mjs → components-CliOkZAs.mjs} +1 -1
  310. package/dist/{components-B_sATNUc.mjs.map → components-CliOkZAs.mjs.map} +1 -1
  311. package/dist/{content-DhgEth4k.mjs → content-BO61Sx4j.mjs} +179 -20
  312. package/dist/content-BO61Sx4j.mjs.map +1 -0
  313. package/dist/{content-refresh-CA4uKwzH.mjs → content-refresh-BkkApzeS.mjs} +20 -14
  314. package/dist/content-refresh-BkkApzeS.mjs.map +1 -0
  315. package/dist/{context-CUsR9dXL.mjs → context-DtSFYFuS.mjs} +71 -14
  316. package/dist/context-DtSFYFuS.mjs.map +1 -0
  317. package/dist/{cron-v4FTEFR_.mjs → cron-YFJ7uNVA.mjs} +1 -1
  318. package/dist/{cron-v4FTEFR_.mjs.map → cron-YFJ7uNVA.mjs.map} +1 -1
  319. package/dist/{dashboard-EvEKF5en.mjs → dashboard-xo_gPs_D.mjs} +6 -5
  320. package/dist/dashboard-xo_gPs_D.mjs.map +1 -0
  321. package/dist/database/pg-migration-lock.d.mts +21 -0
  322. package/dist/database/pg-migration-lock.d.mts.map +1 -0
  323. package/dist/database/pg-migration-lock.mjs +45 -0
  324. package/dist/database/pg-migration-lock.mjs.map +1 -0
  325. package/dist/db/index.d.mts +3 -3
  326. package/dist/db/index.mjs +2 -2
  327. package/dist/db/libsql.d.mts +1 -1
  328. package/dist/db/postgres.d.mts +1 -1
  329. package/dist/db/postgres.d.mts.map +1 -1
  330. package/dist/db/postgres.mjs +2 -8
  331. package/dist/db/postgres.mjs.map +1 -1
  332. package/dist/db/sqlite.d.mts +1 -1
  333. package/dist/{db-errors-CK46D-ly.mjs → db-errors-BKuXh_fi.mjs} +1 -1
  334. package/dist/{db-errors-CK46D-ly.mjs.map → db-errors-BKuXh_fi.mjs.map} +1 -1
  335. package/dist/{default-CM_D83Mg.mjs → default-DY5ovGUG.mjs} +1 -1
  336. package/dist/{default-CM_D83Mg.mjs.map → default-DY5ovGUG.mjs.map} +1 -1
  337. package/dist/{device-flow-CfGP18Uw.mjs → device-flow-CPXQ_QfW.mjs} +5 -5
  338. package/dist/{device-flow-CfGP18Uw.mjs.map → device-flow-CPXQ_QfW.mjs.map} +1 -1
  339. package/dist/{dialect-helpers-DRI5pyY3.mjs → dialect-helpers-Cue7QQOR.mjs} +21 -2
  340. package/dist/dialect-helpers-Cue7QQOR.mjs.map +1 -0
  341. package/dist/{email-console-CIf4Lfvv.mjs → email-console-CjkQc7oY.mjs} +1 -1
  342. package/dist/{email-console-CIf4Lfvv.mjs.map → email-console-CjkQc7oY.mjs.map} +1 -1
  343. package/dist/{enrich-BQ0mxJRs.mjs → enrich-CFJJgxs_.mjs} +2 -2
  344. package/dist/{enrich-BQ0mxJRs.mjs.map → enrich-CFJJgxs_.mjs.map} +1 -1
  345. package/dist/{error-CkAseSqZ.mjs → error-CfJMLSkd.mjs} +12 -3
  346. package/dist/error-CfJMLSkd.mjs.map +1 -0
  347. package/dist/{escape-DqD0aCKu.mjs → escape-r8_GbEU2.mjs} +1 -1
  348. package/dist/{escape-DqD0aCKu.mjs.map → escape-r8_GbEU2.mjs.map} +1 -1
  349. package/dist/{field-defs-cache-WUI88LX5.mjs → field-defs-cache-BVrNCgSj.mjs} +5 -5
  350. package/dist/{field-defs-cache-WUI88LX5.mjs.map → field-defs-cache-BVrNCgSj.mjs.map} +1 -1
  351. package/dist/{fts-manager-BbFaF_V8.mjs → fts-manager-BD9s77qh.mjs} +27 -3
  352. package/dist/{fts-manager-BbFaF_V8.mjs.map → fts-manager-BD9s77qh.mjs.map} +1 -1
  353. package/dist/{hash-DrvzIXcz.mjs → hash-DFFrkivP.mjs} +1 -1
  354. package/dist/{hash-DrvzIXcz.mjs.map → hash-DFFrkivP.mjs.map} +1 -1
  355. package/dist/hreflang-CgIxhH4k.d.mts +48 -0
  356. package/dist/hreflang-CgIxhH4k.d.mts.map +1 -0
  357. package/dist/hreflang-pAWUiPd_.mjs +102 -0
  358. package/dist/hreflang-pAWUiPd_.mjs.map +1 -0
  359. package/dist/{import-fYLf14Co.mjs → import-2jHtLzsO.mjs} +6 -6
  360. package/dist/{import-fYLf14Co.mjs.map → import-2jHtLzsO.mjs.map} +1 -1
  361. package/dist/{index-B9sIxwe4.d.mts → index-BXOCyLj0.d.mts} +115 -21
  362. package/dist/index-BXOCyLj0.d.mts.map +1 -0
  363. package/dist/{index-Bm-Gy8Mh.d.mts → index-DxjWLKGT.d.mts} +3 -3
  364. package/dist/{index-Bm-Gy8Mh.d.mts.map → index-DxjWLKGT.d.mts.map} +1 -1
  365. package/dist/index.d.mts +20 -19
  366. package/dist/index.mjs +68 -64
  367. package/dist/{init-lock-6b309ZrF.mjs → init-lock-DJkX6Hto.mjs} +1 -1
  368. package/dist/{init-lock-6b309ZrF.mjs.map → init-lock-DJkX6Hto.mjs.map} +1 -1
  369. package/dist/{load-Djn3HWQS.mjs → load-DgoWMdRX.mjs} +2 -2
  370. package/dist/{load-Djn3HWQS.mjs.map → load-DgoWMdRX.mjs.map} +1 -1
  371. package/dist/{loader-CB6YHeul.mjs → loader-Rb8QlGZp.mjs} +5 -20
  372. package/dist/loader-Rb8QlGZp.mjs.map +1 -0
  373. package/dist/{manifest-schema-BHlgZM1W.mjs → manifest-schema-DeGNma2O.mjs} +3 -1
  374. package/dist/manifest-schema-DeGNma2O.mjs.map +1 -0
  375. package/dist/media/image-endpoint.mjs +1 -1
  376. package/dist/media/index.d.mts +1 -1
  377. package/dist/media/index.mjs +2 -2
  378. package/dist/media/local-runtime.d.mts +13 -12
  379. package/dist/media/local-runtime.d.mts.map +1 -1
  380. package/dist/media/local-runtime.mjs +8 -8
  381. package/dist/{media-BrXIaMFN.mjs → media-D2ZFowpn.mjs} +2 -2
  382. package/dist/media-D2ZFowpn.mjs.map +1 -0
  383. package/dist/{media-allowlist-CRHEeJ_i.mjs → media-allowlist-Dc05vKtt.mjs} +2 -2
  384. package/dist/{media-allowlist-CRHEeJ_i.mjs.map → media-allowlist-Dc05vKtt.mjs.map} +1 -1
  385. package/dist/{media-url-CKi5XSw4.mjs → media-url-DgIEYZr4.mjs} +1 -1
  386. package/dist/{media-url-CKi5XSw4.mjs.map → media-url-DgIEYZr4.mjs.map} +1 -1
  387. package/dist/media-usage-B__v9NMm.mjs +421 -0
  388. package/dist/media-usage-B__v9NMm.mjs.map +1 -0
  389. package/dist/{menus-Cfivc2Ad.mjs → menus-BpfevlJD.mjs} +3 -3
  390. package/dist/{menus-Cfivc2Ad.mjs.map → menus-BpfevlJD.mjs.map} +1 -1
  391. package/dist/{menus-CsZ2ZEK2.mjs → menus-BtvH7Z7t.mjs} +31 -12
  392. package/dist/menus-BtvH7Z7t.mjs.map +1 -0
  393. package/dist/{mime-CCEzze7W.mjs → mime-DfIVjNkr.mjs} +1 -1
  394. package/dist/{mime-CCEzze7W.mjs.map → mime-DfIVjNkr.mjs.map} +1 -1
  395. package/dist/{mode-BM9QgEmt.mjs → mode-BVnhGZ2o.mjs} +1 -1
  396. package/dist/{mode-BM9QgEmt.mjs.map → mode-BVnhGZ2o.mjs.map} +1 -1
  397. package/dist/{normalize-CeglrBT9.mjs → normalize-C-SHXmra.mjs} +1 -1
  398. package/dist/{normalize-CeglrBT9.mjs.map → normalize-C-SHXmra.mjs.map} +1 -1
  399. package/dist/{oauth-authorization-CXWkIGT4.mjs → oauth-authorization-BWqWTHBK.mjs} +5 -5
  400. package/dist/{oauth-authorization-CXWkIGT4.mjs.map → oauth-authorization-BWqWTHBK.mjs.map} +1 -1
  401. package/dist/{oauth-clients-BmTI5rsl.mjs → oauth-clients-43_XADoa.mjs} +1 -1
  402. package/dist/{oauth-clients-BmTI5rsl.mjs.map → oauth-clients-43_XADoa.mjs.map} +1 -1
  403. package/dist/{oauth-state-store-YLFLcH5F.mjs → oauth-state-store-BRSUEkmx.mjs} +1 -1
  404. package/dist/{oauth-state-store-YLFLcH5F.mjs.map → oauth-state-store-BRSUEkmx.mjs.map} +1 -1
  405. package/dist/{oauth-user-lookup-Bsc_GsX-.mjs → oauth-user-lookup-Ctgemb0k.mjs} +1 -1
  406. package/dist/{oauth-user-lookup-Bsc_GsX-.mjs.map → oauth-user-lookup-Ctgemb0k.mjs.map} +1 -1
  407. package/dist/object-cache/memory.d.mts +1 -1
  408. package/dist/{options-DTTML-Tx.mjs → options-BlmBHTvX.mjs} +1 -1
  409. package/dist/{options-DTTML-Tx.mjs.map → options-BlmBHTvX.mjs.map} +1 -1
  410. package/dist/{options-iMpRRxIe.d.mts → options-COXGTtqd.d.mts} +3 -3
  411. package/dist/{options-iMpRRxIe.d.mts.map → options-COXGTtqd.d.mts.map} +1 -1
  412. package/dist/page/index.d.mts +2 -2
  413. package/dist/{parse-GmjecGct.mjs → parse-GLksnn-B.mjs} +2 -2
  414. package/dist/{parse-GmjecGct.mjs.map → parse-GLksnn-B.mjs.map} +1 -1
  415. package/dist/{passkey-config-De0ahnRg.mjs → passkey-config-CjA1UbDj.mjs} +1 -1
  416. package/dist/{passkey-config-De0ahnRg.mjs.map → passkey-config-CjA1UbDj.mjs.map} +1 -1
  417. package/dist/{patterns-BKmjvM7K.mjs → patterns-CiyXeDgr.mjs} +1 -1
  418. package/dist/{patterns-BKmjvM7K.mjs.map → patterns-CiyXeDgr.mjs.map} +1 -1
  419. package/dist/{placeholder-BSKwzRe4.d.mts → placeholder-DR-eeZr-.d.mts} +1 -1
  420. package/dist/{placeholder-BSKwzRe4.d.mts.map → placeholder-DR-eeZr-.d.mts.map} +1 -1
  421. package/dist/plugin-types.d.mts +1 -1
  422. package/dist/plugin-utils.d.mts +11 -10
  423. package/dist/plugin-utils.d.mts.map +1 -1
  424. package/dist/plugins/adapt-sandbox-entry.d.mts +11 -10
  425. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  426. package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
  427. package/dist/{portable-text-cCa0cGV6.mjs → portable-text-BAkgEKcv.mjs} +1 -1
  428. package/dist/{portable-text-cCa0cGV6.mjs.map → portable-text-BAkgEKcv.mjs.map} +1 -1
  429. package/dist/{preview-SSXNVPAC.mjs → preview-Rloa09Wp.mjs} +2 -2
  430. package/dist/{preview-SSXNVPAC.mjs.map → preview-Rloa09Wp.mjs.map} +1 -1
  431. package/dist/{public-url-Danv47cS.mjs → public-url-C0cEvrRu.mjs} +1 -1
  432. package/dist/{public-url-Danv47cS.mjs.map → public-url-C0cEvrRu.mjs.map} +1 -1
  433. package/dist/{schema-Blhoxp3P.mjs → query-BxT95opY.mjs} +5 -10
  434. package/dist/query-BxT95opY.mjs.map +1 -0
  435. package/dist/{query-ByGq6ver.mjs → query-ZzvXyxWq.mjs} +15 -15
  436. package/dist/query-ZzvXyxWq.mjs.map +1 -0
  437. package/dist/{rate-limit-C_Lf63Dd.mjs → rate-limit-Cg4Rvc_-.mjs} +2 -2
  438. package/dist/{rate-limit-C_Lf63Dd.mjs.map → rate-limit-Cg4Rvc_-.mjs.map} +1 -1
  439. package/dist/{redirect-CoW3G-0U.mjs → redirect-Ce_6Yb6z.mjs} +1 -1
  440. package/dist/{redirect-CoW3G-0U.mjs.map → redirect-Ce_6Yb6z.mjs.map} +1 -1
  441. package/dist/{redirect-IyfNirgS.mjs → redirect-Ch3E98qZ.mjs} +4 -4
  442. package/dist/{redirect-IyfNirgS.mjs.map → redirect-Ch3E98qZ.mjs.map} +1 -1
  443. package/dist/{redirects-Bs1g42Ri.mjs → redirects-CXmVGRNZ.mjs} +6 -6
  444. package/dist/{redirects-Bs1g42Ri.mjs.map → redirects-CXmVGRNZ.mjs.map} +1 -1
  445. package/dist/{redirects-DXEXBAII.mjs → redirects-CeD7K7EX.mjs} +43 -5
  446. package/dist/redirects-CeD7K7EX.mjs.map +1 -0
  447. package/dist/{registry-B65mUtPa.mjs → registry-CyIXPi4E.mjs} +8 -8
  448. package/dist/{registry-B65mUtPa.mjs.map → registry-CyIXPi4E.mjs.map} +1 -1
  449. package/dist/relation-Ba68Tm4Z.mjs +334 -0
  450. package/dist/relation-Ba68Tm4Z.mjs.map +1 -0
  451. package/dist/{byline-fields-2Lp5Hbgf.mjs → relations-BmBmX4Eb.mjs} +60 -4
  452. package/dist/relations-BmBmX4Eb.mjs.map +1 -0
  453. package/dist/relations-C8hVyEy0.mjs +397 -0
  454. package/dist/relations-C8hVyEy0.mjs.map +1 -0
  455. package/dist/{byline-fields-Cgrt9-aL.d.mts → relations-CbBpoOys.d.mts} +180 -27
  456. package/dist/relations-CbBpoOys.d.mts.map +1 -0
  457. package/dist/{request-cache-KCNHp_RJ.mjs → request-cache-BSUptuJR.mjs} +1 -1
  458. package/dist/{request-cache-KCNHp_RJ.mjs.map → request-cache-BSUptuJR.mjs.map} +1 -1
  459. package/dist/{request-meta-DbvXaAvU.mjs → request-meta-DCwktC5P.mjs} +2 -2
  460. package/dist/{request-meta-DbvXaAvU.mjs.map → request-meta-DCwktC5P.mjs.map} +1 -1
  461. package/dist/{resolve-DR3wqMTy.mjs → resolve-Cd9dzclN.mjs} +1 -1
  462. package/dist/{resolve-DR3wqMTy.mjs.map → resolve-Cd9dzclN.mjs.map} +1 -1
  463. package/dist/{runner-DvFWoz8-.d.mts → runner-CiNdIk3y.d.mts} +8 -2
  464. package/dist/runner-CiNdIk3y.d.mts.map +1 -0
  465. package/dist/{runner-K8XK101B.mjs → runner-jt65bF7F.mjs} +24 -7
  466. package/dist/{runner-K8XK101B.mjs.map → runner-jt65bF7F.mjs.map} +1 -1
  467. package/dist/runtime.d.mts +12 -11
  468. package/dist/runtime.d.mts.map +1 -1
  469. package/dist/runtime.mjs +4 -4
  470. package/dist/{scheduled-publish-Drffrf2a.d.mts → scheduled-publish-DlJHGcuL.d.mts} +1 -1
  471. package/dist/scheduled-publish-DlJHGcuL.d.mts.map +1 -0
  472. package/dist/schema-DwjufZ1S.mjs +9 -0
  473. package/dist/schema-DwjufZ1S.mjs.map +1 -0
  474. package/dist/{search-DZN2HZ-V.mjs → search-Cl875CVE.mjs} +62 -12
  475. package/dist/search-Cl875CVE.mjs.map +1 -0
  476. package/dist/{secrets-kp760LlD.mjs → secrets-CO_bEmII.mjs} +4 -4
  477. package/dist/{secrets-kp760LlD.mjs.map → secrets-CO_bEmII.mjs.map} +1 -1
  478. package/dist/{sections-CpF5SaGr.mjs → sections-DTKzgoiS.mjs} +3 -3
  479. package/dist/{sections-CpF5SaGr.mjs.map → sections-DTKzgoiS.mjs.map} +1 -1
  480. package/dist/seed/index.d.mts +2 -2
  481. package/dist/seed/index.mjs +23 -23
  482. package/dist/seo/index.d.mts +4 -2
  483. package/dist/seo/index.d.mts.map +1 -1
  484. package/dist/seo/index.mjs +19 -2
  485. package/dist/seo/index.mjs.map +1 -1
  486. package/dist/{seo-DXu2UQnC.mjs → seo-BLm6SXzS.mjs} +2 -2
  487. package/dist/{seo-DXu2UQnC.mjs.map → seo-BLm6SXzS.mjs.map} +1 -1
  488. package/dist/{seo-89-53DDs.mjs → seo-BjrbXAd_.mjs} +1 -1
  489. package/dist/{seo-89-53DDs.mjs.map → seo-BjrbXAd_.mjs.map} +1 -1
  490. package/dist/{service-DQmiBMzt.mjs → service-D6zDmKXy.mjs} +3 -3
  491. package/dist/{service-DQmiBMzt.mjs.map → service-D6zDmKXy.mjs.map} +1 -1
  492. package/dist/{session-user-Cascbax7.mjs → session-user-DoSs6YM8.mjs} +1 -1
  493. package/dist/{session-user-Cascbax7.mjs.map → session-user-DoSs6YM8.mjs.map} +1 -1
  494. package/dist/{settings-zhmdKyJQ.mjs → settings-BuQYvLfy.mjs} +6 -6
  495. package/dist/{settings-zhmdKyJQ.mjs.map → settings-BuQYvLfy.mjs.map} +1 -1
  496. package/dist/{settings-rZyHEcNT.mjs → settings-CmS3TwXf.mjs} +3 -3
  497. package/dist/{settings-rZyHEcNT.mjs.map → settings-CmS3TwXf.mjs.map} +1 -1
  498. package/dist/{setup-complete-Cb3LRyzy.mjs → setup-complete-BPNgLHlU.mjs} +2 -2
  499. package/dist/{setup-complete-Cb3LRyzy.mjs.map → setup-complete-BPNgLHlU.mjs.map} +1 -1
  500. package/dist/{setup-nonce-Z8x0tHf8.mjs → setup-nonce-DEPZX96T.mjs} +1 -1
  501. package/dist/{setup-nonce-Z8x0tHf8.mjs.map → setup-nonce-DEPZX96T.mjs.map} +1 -1
  502. package/dist/{single-flight-cache-BG3B_GhN.mjs → single-flight-cache-DEtW-OEG.mjs} +2 -2
  503. package/dist/{single-flight-cache-BG3B_GhN.mjs.map → single-flight-cache-DEtW-OEG.mjs.map} +1 -1
  504. package/dist/{site-url-BBfDTgZB.mjs → site-url-CcLy5D5s.mjs} +2 -2
  505. package/dist/{site-url-BBfDTgZB.mjs.map → site-url-CcLy5D5s.mjs.map} +1 -1
  506. package/dist/{slugify-Cce3dTdg.mjs → slugify-C_tqlU4G.mjs} +1 -1
  507. package/dist/{slugify-Cce3dTdg.mjs.map → slugify-C_tqlU4G.mjs.map} +1 -1
  508. package/dist/{ssrf-1g7usGBg.mjs → ssrf-TrKYJAy0.mjs} +1 -1
  509. package/dist/{ssrf-1g7usGBg.mjs.map → ssrf-TrKYJAy0.mjs.map} +1 -1
  510. package/dist/{status-CqJQX1QN.mjs → status-D3Gy1Zc6.mjs} +1 -1
  511. package/dist/{status-CqJQX1QN.mjs.map → status-D3Gy1Zc6.mjs.map} +1 -1
  512. package/dist/storage/local.d.mts +1 -1
  513. package/dist/storage/local.mjs +1 -1
  514. package/dist/storage/s3.d.mts +1 -1
  515. package/dist/storage/s3.mjs +1 -1
  516. package/dist/{taxonomies-BGBd16Eu.mjs → taxonomies-ClS4RKaZ.mjs} +13 -9
  517. package/dist/taxonomies-ClS4RKaZ.mjs.map +1 -0
  518. package/dist/{taxonomies-Cnb4F-Pb.mjs → taxonomies-pUkuD6nj.mjs} +115 -36
  519. package/dist/taxonomies-pUkuD6nj.mjs.map +1 -0
  520. package/dist/{taxonomy-BxGxZZdu.mjs → taxonomy-BkxbUMSw.mjs} +12 -3
  521. package/dist/{taxonomy-BxGxZZdu.mjs.map → taxonomy-BkxbUMSw.mjs.map} +1 -1
  522. package/dist/{tokens-BGT0TUUo.mjs → tokens-BV6fgl5A.mjs} +2 -2
  523. package/dist/{tokens-BGT0TUUo.mjs.map → tokens-BV6fgl5A.mjs.map} +1 -1
  524. package/dist/{transaction-qfqpPVpu.mjs → transaction-D0FOsb3X.mjs} +1 -1
  525. package/dist/{transaction-qfqpPVpu.mjs.map → transaction-D0FOsb3X.mjs.map} +1 -1
  526. package/dist/{transport-DPefPMcz.mjs → transport-DTFhhPOg.mjs} +1 -1
  527. package/dist/{transport-DPefPMcz.mjs.map → transport-DTFhhPOg.mjs.map} +1 -1
  528. package/dist/{transport-BMDWHSgZ.d.mts → transport-DmlmzD2U.d.mts} +1 -1
  529. package/dist/{transport-BMDWHSgZ.d.mts.map → transport-DmlmzD2U.d.mts.map} +1 -1
  530. package/dist/{trusted-proxy-VTPRiX2s.mjs → trusted-proxy-CSgZVESw.mjs} +1 -1
  531. package/dist/{trusted-proxy-VTPRiX2s.mjs.map → trusted-proxy-CSgZVESw.mjs.map} +1 -1
  532. package/dist/{types-CgvhU-hF.d.mts → types-B6-N9cBB.d.mts} +1 -1
  533. package/dist/{types-CgvhU-hF.d.mts.map → types-B6-N9cBB.d.mts.map} +1 -1
  534. package/dist/{types-g_aFIdW0.d.mts → types-BCVuUPrL.d.mts} +1 -1
  535. package/dist/{types-g_aFIdW0.d.mts.map → types-BCVuUPrL.d.mts.map} +1 -1
  536. package/dist/{types-Jo3UYd6b.mjs → types-BNZsPL9z.mjs} +1 -1
  537. package/dist/{types-Jo3UYd6b.mjs.map → types-BNZsPL9z.mjs.map} +1 -1
  538. package/dist/{types-vgEWF18A.d.mts → types-B_pmP7Yq.d.mts} +1 -1
  539. package/dist/{types-vgEWF18A.d.mts.map → types-B_pmP7Yq.d.mts.map} +1 -1
  540. package/dist/{types-CuW0zWDA.mjs → types-Ch8pFMEm.mjs} +3 -3
  541. package/dist/{types-CuW0zWDA.mjs.map → types-Ch8pFMEm.mjs.map} +1 -1
  542. package/dist/{types-ea9sAPck.d.mts → types-Cm4Cz-8M.d.mts} +1 -1
  543. package/dist/{types-ea9sAPck.d.mts.map → types-Cm4Cz-8M.d.mts.map} +1 -1
  544. package/dist/{types-CGbYowGQ.d.mts → types-CtDVagM4.d.mts} +55 -3
  545. package/dist/types-CtDVagM4.d.mts.map +1 -0
  546. package/dist/{types-BcLUUbbR.d.mts → types-DLIrNtv5.d.mts} +11 -3
  547. package/dist/{types-BcLUUbbR.d.mts.map → types-DLIrNtv5.d.mts.map} +1 -1
  548. package/dist/{types-DmHk7vAt.d.mts → types-QnlQIyPE.d.mts} +1 -1
  549. package/dist/{types-DmHk7vAt.d.mts.map → types-QnlQIyPE.d.mts.map} +1 -1
  550. package/dist/{types-_HFLRzTn.d.mts → types-momGysZk.d.mts} +1 -1
  551. package/dist/{types-_HFLRzTn.d.mts.map → types-momGysZk.d.mts.map} +1 -1
  552. package/dist/{types-tM44hEcf.mjs → types-o7xo7VgH.mjs} +1 -1
  553. package/dist/{types-tM44hEcf.mjs.map → types-o7xo7VgH.mjs.map} +1 -1
  554. package/dist/{types-ClUkdbWb.d.mts → types-qljd1hsL.d.mts} +1 -1
  555. package/dist/{types-ClUkdbWb.d.mts.map → types-qljd1hsL.d.mts.map} +1 -1
  556. package/dist/{user-BjAOvU3Z.mjs → user-DTxX_Fha.mjs} +3 -3
  557. package/dist/{user-BjAOvU3Z.mjs.map → user-DTxX_Fha.mjs.map} +1 -1
  558. package/dist/{utils-BJXElxdw.mjs → utils-Cz8PVrl4.mjs} +3 -3
  559. package/dist/{utils-BJXElxdw.mjs.map → utils-Cz8PVrl4.mjs.map} +1 -1
  560. package/dist/{validate-Z1b86_3B.d.mts → validate-9jLuE301.d.mts} +5 -5
  561. package/dist/{validate-Z1b86_3B.d.mts.map → validate-9jLuE301.d.mts.map} +1 -1
  562. package/dist/{validate-CWSnKVIJ.mjs → validate-C3CpWlNt.mjs} +3 -3
  563. package/dist/{validate-CWSnKVIJ.mjs.map → validate-C3CpWlNt.mjs.map} +1 -1
  564. package/dist/{validation-c8WjhH8z.mjs → validation-DM2K_NJC.mjs} +10 -10
  565. package/dist/{validation-c8WjhH8z.mjs.map → validation-DM2K_NJC.mjs.map} +1 -1
  566. package/dist/version-BlIJvNAZ.mjs +7 -0
  567. package/dist/{version-CaccU7DM.mjs.map → version-BlIJvNAZ.mjs.map} +1 -1
  568. package/dist/{widgets-hWcIicX8.mjs → widgets-B_X6_UXJ.mjs} +4 -4
  569. package/dist/{widgets-hWcIicX8.mjs.map → widgets-B_X6_UXJ.mjs.map} +1 -1
  570. package/dist/{wxr-taxonomies-BC3OYpvx.mjs → wxr-taxonomies-oNJB2S81.mjs} +4 -4
  571. package/dist/{wxr-taxonomies-BC3OYpvx.mjs.map → wxr-taxonomies-oNJB2S81.mjs.map} +1 -1
  572. package/dist/{wxr-taxonomies-0_uxSrmf.d.mts → wxr-taxonomies-tADW4KTa.d.mts} +1 -1
  573. package/dist/{wxr-taxonomies-0_uxSrmf.d.mts.map → wxr-taxonomies-tADW4KTa.d.mts.map} +1 -1
  574. package/dist/{zod-generator-CacrR-i8.mjs → zod-generator-CrfV79De.mjs} +3 -3
  575. package/dist/{zod-generator-CacrR-i8.mjs.map → zod-generator-CrfV79De.mjs.map} +1 -1
  576. package/package.json +11 -7
  577. package/src/api/errors.ts +11 -0
  578. package/src/api/handlers/content.ts +111 -1
  579. package/src/api/handlers/dashboard.ts +2 -0
  580. package/src/api/handlers/index.ts +6 -0
  581. package/src/api/handlers/media-usage.ts +80 -0
  582. package/src/api/handlers/relations.ts +474 -0
  583. package/src/api/handlers/taxonomies.ts +26 -4
  584. package/src/api/handlers/validate-media-fields.ts +1 -1
  585. package/src/api/openapi/document.ts +25 -0
  586. package/src/api/parse.ts +1 -1
  587. package/src/api/schemas/comments.ts +6 -0
  588. package/src/api/schemas/content.ts +8 -0
  589. package/src/api/schemas/index.ts +2 -0
  590. package/src/api/schemas/media-usage.ts +48 -0
  591. package/src/api/schemas/relations.ts +109 -0
  592. package/src/api/schemas/search.ts +1 -0
  593. package/src/astro/integration/index.ts +1 -0
  594. package/src/astro/integration/routes.ts +5 -0
  595. package/src/astro/integration/runtime.ts +24 -0
  596. package/src/astro/middleware/request-context.ts +162 -20
  597. package/src/astro/middleware.ts +22 -9
  598. package/src/astro/routes/api/admin/comments/[id]/status.ts +1 -2
  599. package/src/astro/routes/api/admin/comments/index.ts +1 -2
  600. package/src/astro/routes/api/admin/media-usage/repair.ts +24 -0
  601. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +1 -2
  602. package/src/astro/routes/api/auth/oauth/[provider].ts +1 -2
  603. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +13 -0
  604. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +97 -0
  605. package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +48 -0
  606. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -15
  607. package/src/astro/routes/api/relations/[id]/index.ts +84 -0
  608. package/src/astro/routes/api/relations/[id]/translations.ts +33 -0
  609. package/src/astro/routes/api/relations/index.ts +56 -0
  610. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +1 -7
  611. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +1 -2
  612. package/src/astro/routes/api/search/index.ts +2 -0
  613. package/src/astro/types.ts +2 -0
  614. package/src/cli/commands/export-seed.ts +1 -10
  615. package/src/client/index.ts +39 -0
  616. package/src/comments/service.ts +1 -1
  617. package/src/comments/turnstile.ts +64 -0
  618. package/src/components/BlockquoteGroup.astro +34 -0
  619. package/src/components/CommentForm.astro +12 -5
  620. package/src/components/EmDashHead.astro +27 -1
  621. package/src/components/InlinePortableTextEditor.tsx +34 -0
  622. package/src/components/PortableText.astro +7 -1
  623. package/src/components/index.ts +2 -0
  624. package/src/components/portable-text-blockquote-group.ts +68 -0
  625. package/src/content/converters/portable-text-to-prosemirror.ts +32 -1
  626. package/src/database/dialect-helpers.ts +34 -0
  627. package/src/database/migrations/039_fix_fts5_triggers.ts +1 -1
  628. package/src/database/migrations/runner.ts +46 -6
  629. package/src/database/pg-migration-lock.ts +72 -0
  630. package/src/database/repositories/comment.ts +1 -1
  631. package/src/database/repositories/content.ts +172 -21
  632. package/src/database/repositories/media-usage.ts +25 -3
  633. package/src/database/repositories/media.ts +1 -1
  634. package/src/database/repositories/relation.ts +130 -5
  635. package/src/database/repositories/taxonomy.ts +9 -0
  636. package/src/database/repositories/types.ts +8 -0
  637. package/src/db/postgres.ts +5 -2
  638. package/src/emdash-runtime.ts +72 -4
  639. package/src/index.ts +6 -2
  640. package/src/loader.ts +1 -31
  641. package/src/mcp/server.ts +29 -3
  642. package/src/media/usage/content-repair.ts +206 -22
  643. package/src/media/usage/content-snapshots.ts +4 -0
  644. package/src/plugins/context.ts +85 -0
  645. package/src/plugins/define-plugin.ts +1 -0
  646. package/src/plugins/index.ts +4 -0
  647. package/src/plugins/manifest-schema.ts +2 -0
  648. package/src/plugins/types.ts +59 -0
  649. package/src/schema/byline-registry.ts +1 -1
  650. package/src/search/fts-manager.ts +34 -0
  651. package/src/search/match.ts +50 -0
  652. package/src/search/query.ts +94 -9
  653. package/src/seo/hreflang.ts +192 -0
  654. package/src/seo/index.ts +3 -0
  655. package/src/taxonomies/index.ts +62 -45
  656. package/src/taxonomies/term-counts.ts +117 -0
  657. package/src/virtual-modules.d.ts +1 -0
  658. package/src/visual-editing/editable.ts +41 -35
  659. package/src/visual-editing/toolbar-bootstrap.ts +120 -0
  660. package/src/visual-editing/toolbar.ts +46 -0
  661. package/dist/api-BFURZn1i.mjs.map +0 -1
  662. package/dist/byline-fields-2Lp5Hbgf.mjs.map +0 -1
  663. package/dist/byline-fields-Cgrt9-aL.d.mts.map +0 -1
  664. package/dist/content-DhgEth4k.mjs.map +0 -1
  665. package/dist/content-refresh-CA4uKwzH.mjs.map +0 -1
  666. package/dist/context-CUsR9dXL.mjs.map +0 -1
  667. package/dist/dashboard-EvEKF5en.mjs.map +0 -1
  668. package/dist/dialect-helpers-DRI5pyY3.mjs.map +0 -1
  669. package/dist/error-CkAseSqZ.mjs.map +0 -1
  670. package/dist/index-B9sIxwe4.d.mts.map +0 -1
  671. package/dist/loader-CB6YHeul.mjs.map +0 -1
  672. package/dist/manifest-schema-BHlgZM1W.mjs.map +0 -1
  673. package/dist/media-BrXIaMFN.mjs.map +0 -1
  674. package/dist/menus-CsZ2ZEK2.mjs.map +0 -1
  675. package/dist/query-ByGq6ver.mjs.map +0 -1
  676. package/dist/redirects-DXEXBAII.mjs.map +0 -1
  677. package/dist/runner-DvFWoz8-.d.mts.map +0 -1
  678. package/dist/scheduled-publish-Drffrf2a.d.mts.map +0 -1
  679. package/dist/schema-Blhoxp3P.mjs.map +0 -1
  680. package/dist/search-DZN2HZ-V.mjs.map +0 -1
  681. package/dist/taxonomies-BGBd16Eu.mjs.map +0 -1
  682. package/dist/taxonomies-Cnb4F-Pb.mjs.map +0 -1
  683. package/dist/types-CGbYowGQ.d.mts.map +0 -1
  684. package/dist/version-CaccU7DM.mjs +0 -7
  685. /package/dist/{api-tokens-DsvvCtdh.mjs → api-tokens-Dk2GrJMY.mjs} +0 -0
  686. /package/dist/{ssrf-CmuGgCq3.mjs → ssrf-B5DOv5E5.mjs} +0 -0
  687. /package/dist/{types-DROWRxYV.mjs → types-DeCZBZxn.mjs} +0 -0
@@ -22,7 +22,11 @@ import { getAuthMode } from "./auth/mode.js";
22
22
  import { getTrustedProxyHeaders } from "./auth/trusted-proxy.js";
23
23
  import { isSqlite } from "./database/dialect-helpers.js";
24
24
  import { kyselyLogOption } from "./database/instrumentation.js";
25
- import { MIGRATION_RACE_WAIT_MS, runMigrations } from "./database/migrations/runner.js";
25
+ import {
26
+ ConcurrentMigrationTimeoutError,
27
+ MIGRATION_RACE_WAIT_MS,
28
+ runMigrations,
29
+ } from "./database/migrations/runner.js";
26
30
  import { RevisionRepository } from "./database/repositories/revision.js";
27
31
  import type {
28
32
  ContentItem as ContentItemInternal,
@@ -385,18 +389,42 @@ const DB_HOLDER_KEY = Symbol.for("emdash:db-cache");
385
389
  interface DbHolder {
386
390
  cache: Map<string, Kysely<Database>>;
387
391
  lock: InitLock;
392
+ /**
393
+ * Recent migration failures, keyed like `cache`. A failed migration is
394
+ * near-certain to fail again immediately (schema conflict, broken
395
+ * migration), and without this every request in a warm isolate would
396
+ * re-attempt it — on Workers with Postgres that stampedes the database
397
+ * through the migration advisory lock (#1744). Entries expire after
398
+ * DB_INIT_FAILURE_BACKOFF_MS; a successful init clears them.
399
+ */
400
+ failures: Map<string, { at: number; message: string }>;
388
401
  }
389
402
  const globalSymbolStore = globalThis as Record<symbol, unknown>;
390
403
  function getDbHolder(): DbHolder {
391
404
  // eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis symbol slot, written only below
392
405
  let holder = globalSymbolStore[DB_HOLDER_KEY] as DbHolder | undefined;
393
406
  if (!holder) {
394
- holder = { cache: new Map<string, Kysely<Database>>(), lock: createInitLock() };
407
+ holder = {
408
+ cache: new Map<string, Kysely<Database>>(),
409
+ lock: createInitLock(),
410
+ failures: new Map(),
411
+ };
395
412
  globalSymbolStore[DB_HOLDER_KEY] = holder;
396
413
  }
414
+ // A holder created by an older copy of this module (dev-server HMR keeps
415
+ // globalThis across reloads) may predate the failures map.
416
+ holder.failures ??= new Map();
397
417
  return holder;
398
418
  }
399
419
 
420
+ /**
421
+ * After a database init fails (migrations threw), skip re-attempting for
422
+ * this long. Cold isolates still get one attempt each, so a transient
423
+ * failure heals on its own; a persistently failing migration is retried at
424
+ * most once per backoff window per isolate instead of on every request.
425
+ */
426
+ const DB_INIT_FAILURE_BACKOFF_MS = 30_000;
427
+
400
428
  /**
401
429
  * Auto-seed runs at most once per isolate per database. Its lock + "done" set
402
430
  * live on globalThis (same bundler-duplication reasoning as the db cache) so a
@@ -1623,14 +1651,52 @@ export class EmDashRuntime {
1623
1651
  // owner's init still completes and populates the cache. Net: a stale
1624
1652
  // lock is reclaimed after a deadline.
1625
1653
  const holder = getDbHolder();
1654
+
1655
+ const throwIfBackingOff = () => {
1656
+ const failure = holder.failures.get(cacheKey);
1657
+ if (!failure) return;
1658
+ if (Date.now() - failure.at < DB_INIT_FAILURE_BACKOFF_MS) {
1659
+ throw new Error(
1660
+ `Database initialization is backing off after a recent migration failure: ${failure.message}`,
1661
+ );
1662
+ }
1663
+ // Expired — drop it so the map only ever holds active backoffs.
1664
+ holder.failures.delete(cacheKey);
1665
+ };
1666
+ throwIfBackingOff();
1667
+
1626
1668
  return initWithLock(
1627
1669
  holder.lock,
1628
1670
  () => holder.cache.get(cacheKey),
1629
1671
  async (isCurrentClaim) => {
1672
+ // Re-check under the lock: a request that entered the wait loop
1673
+ // before the failure was recorded must not immediately re-run
1674
+ // the failing migration when the lock frees up.
1675
+ throwIfBackingOff();
1676
+
1630
1677
  const dialect = deps.createDialect(dbConfig.config);
1631
1678
  const db = new Kysely<Database>({ dialect, log: kyselyLogOption() });
1632
1679
 
1633
- await runMigrations(db);
1680
+ try {
1681
+ await runMigrations(db);
1682
+ } catch (error) {
1683
+ // Timing out behind another instance's in-flight migrations
1684
+ // is not a failure of OUR migration — the holder may just be
1685
+ // slow. Don't back off for it: the next request waits again
1686
+ // and init recovers the moment the holder finishes.
1687
+ if (!(error instanceof ConcurrentMigrationTimeoutError)) {
1688
+ holder.failures.set(cacheKey, {
1689
+ at: Date.now(),
1690
+ message: error instanceof Error ? error.message : String(error),
1691
+ });
1692
+ }
1693
+ // Every attempt builds a fresh dialect/pool; close it or each
1694
+ // failed init leaks its connection(s) (#1744 observed these
1695
+ // piling up as idle Postgres connections).
1696
+ await db.destroy().catch(() => {});
1697
+ throw error;
1698
+ }
1699
+ holder.failures.delete(cacheKey);
1634
1700
 
1635
1701
  // Note: legacy installs may carry a stray `emdash:manifest_cache`
1636
1702
  // row in the options table from versions that persisted a JSON
@@ -2520,7 +2586,7 @@ export class EmDashRuntime {
2520
2586
  ...r.data,
2521
2587
  item: { ...item, data: mergedData, liveData },
2522
2588
  },
2523
- } as T;
2589
+ };
2524
2590
  } catch (error) {
2525
2591
  // Non-fatal — fall back to the unhydrated response. Log so the
2526
2592
  // failure isn't completely silent (the response will look stale
@@ -2540,6 +2606,7 @@ export class EmDashRuntime {
2540
2606
  bylines?: Array<{ bylineId: string; roleLabel?: string | null }>;
2541
2607
  locale?: string;
2542
2608
  translationOf?: string;
2609
+ taxonomies?: Record<string, string[]>;
2543
2610
  },
2544
2611
  ) {
2545
2612
  // Run beforeSave hooks (trusted plugins)
@@ -2604,6 +2671,7 @@ export class EmDashRuntime {
2604
2671
  canonical?: string | null;
2605
2672
  noIndex?: boolean;
2606
2673
  };
2674
+ taxonomies?: Record<string, string[]>;
2607
2675
  publishedAt?: string | null;
2608
2676
  locale?: string;
2609
2677
  /** Skip revision creation (used by autosave) */
package/src/index.ts CHANGED
@@ -247,6 +247,10 @@ export type {
247
247
  MediaAccess,
248
248
  HttpAccess,
249
249
  LogAccess,
250
+ TaxonomyAccess,
251
+ TaxonomyDefInfo,
252
+ TaxonomyTermInfo,
253
+ TaxonomyReadOptions,
250
254
  PluginHooks,
251
255
  HookConfig,
252
256
  HookName,
@@ -404,8 +408,8 @@ export type {
404
408
  } from "./settings/types.js";
405
409
 
406
410
  // SEO
407
- export { getSeoMeta, getContentSeo } from "./seo/index.js";
408
- export type { SeoMeta, SeoMetaOptions } from "./seo/index.js";
411
+ export { getSeoMeta, getContentSeo, getHreflangAlternates } from "./seo/index.js";
412
+ export type { SeoMeta, SeoMetaOptions, HreflangAlternate, HreflangOptions } from "./seo/index.js";
409
413
 
410
414
  // Public page contribution types
411
415
  export type {
package/src/loader.ts CHANGED
@@ -14,7 +14,7 @@
14
14
  import type { LiveLoader } from "astro/loaders";
15
15
  import { Kysely, type RawBuilder, sql, type Dialect } from "kysely";
16
16
 
17
- import { currentTimestampValue, isPostgres } from "./database/dialect-helpers.js";
17
+ import { buildStatusCondition, isPostgres } from "./database/dialect-helpers.js";
18
18
  import { kyselyLogOption } from "./database/instrumentation.js";
19
19
  import { decodeCursor, encodeCursor } from "./database/repositories/types.js";
20
20
  import { validateIdentifier } from "./database/validate.js";
@@ -515,36 +515,6 @@ export type SortDirection = "asc" | "desc";
515
515
  */
516
516
  export type OrderBySpec = Record<string, SortDirection>;
517
517
 
518
- /**
519
- * Build WHERE clause for status filtering.
520
- * When filtering for 'published' status, also include scheduled content
521
- * whose scheduled_at time has passed (treating it as effectively published).
522
- */
523
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance
524
- function buildStatusCondition(
525
- db: Kysely<any>,
526
- status: string,
527
- tablePrefix?: string,
528
- ): ReturnType<typeof sql> {
529
- const statusField = tablePrefix ? `${tablePrefix}.status` : "status";
530
- const scheduledAtField = tablePrefix ? `${tablePrefix}.scheduled_at` : "scheduled_at";
531
-
532
- if (status === "published") {
533
- // Include both published content AND scheduled content past its publish time.
534
- // scheduled_at is stored as text (ISO 8601). On Postgres, we must cast it
535
- // to timestamptz for the comparison with CURRENT_TIMESTAMP to work.
536
- const scheduledAtExpr = isPostgres(db)
537
- ? sql`${sql.ref(scheduledAtField)}::timestamptz`
538
- : sql.ref(scheduledAtField);
539
- const nowExpr = isPostgres(db)
540
- ? currentTimestampValue(db)
541
- : sql`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;
542
- return sql`(${sql.ref(statusField)} = 'published' OR (${sql.ref(statusField)} = 'scheduled' AND ${scheduledAtExpr} <= ${nowExpr}))`;
543
- }
544
-
545
- return sql`${sql.ref(statusField)} = ${status}`;
546
- }
547
-
548
518
  /**
549
519
  * Resolved primary sort field and direction (used for cursor pagination).
550
520
  */
package/src/mcp/server.ts CHANGED
@@ -660,6 +660,12 @@ export function createMcpServer(): McpServer {
660
660
  .describe(
661
661
  "Bylines to credit. Each entry references an existing byline by id (see byline_list / byline_create) with an optional roleLabel. The first entry becomes the primary byline.",
662
662
  ),
663
+ taxonomies: z
664
+ .record(z.string(), z.array(z.string()))
665
+ .optional()
666
+ .describe(
667
+ "Taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Call taxonomy_list to see available taxonomies and taxonomy_list_terms to look up slugs. Missing keys leave that taxonomy unchanged.",
668
+ ),
663
669
  }),
664
670
  annotations: { destructiveHint: false },
665
671
  },
@@ -685,7 +691,7 @@ export function createMcpServer(): McpServer {
685
691
  // Publishing requires publish permission — create as draft then publish
686
692
  if (args.status === "published") {
687
693
  const user = { id: userId, role: getExtra(extra).userRole };
688
- if (!hasPermission(user, "content:publish_own" as Permission)) {
694
+ if (!hasPermission(user, "content:publish_own")) {
689
695
  throw new EmDashAuthError(
690
696
  "Insufficient permissions: publishing requires content:publish_own",
691
697
  "INSUFFICIENT_PERMISSIONS",
@@ -698,6 +704,7 @@ export function createMcpServer(): McpServer {
698
704
  locale: args.locale,
699
705
  translationOf: args.translationOf,
700
706
  bylines: args.bylines,
707
+ taxonomies: args.taxonomies,
701
708
  });
702
709
  if (!result.success) return unwrap(result);
703
710
  const itemId = extractContentId(result.data);
@@ -715,6 +722,7 @@ export function createMcpServer(): McpServer {
715
722
  locale: args.locale,
716
723
  translationOf: args.translationOf,
717
724
  bylines: args.bylines,
725
+ taxonomies: args.taxonomies,
718
726
  }),
719
727
  );
720
728
  },
@@ -771,6 +779,12 @@ export function createMcpServer(): McpServer {
771
779
  .describe(
772
780
  "Replace the byline list for this item. The first entry becomes the primary byline. Pass an empty array to clear all bylines.",
773
781
  ),
782
+ taxonomies: z
783
+ .record(z.string(), z.array(z.string()))
784
+ .optional()
785
+ .describe(
786
+ "Replace taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Only named taxonomies are touched; other taxonomies are left unchanged. Pass an empty array to clear a taxonomy.",
787
+ ),
774
788
  publishedAt: z.iso
775
789
  .datetime({ offset: true, message: "must be an ISO 8601 datetime" })
776
790
  .nullish()
@@ -805,7 +819,7 @@ export function createMcpServer(): McpServer {
805
819
  // route. Status-driven publishes are gated separately below.
806
820
  if (args.publishedAt !== undefined) {
807
821
  const user = { id: userId, role: userRole };
808
- if (!hasPermission(user, "content:publish_any" as Permission)) {
822
+ if (!hasPermission(user, "content:publish_any")) {
809
823
  throw new EmDashAuthError(
810
824
  "Setting publishedAt requires content:publish_any permission",
811
825
  "INSUFFICIENT_PERMISSIONS",
@@ -823,6 +837,7 @@ export function createMcpServer(): McpServer {
823
837
  args.slug ||
824
838
  args.seo !== undefined ||
825
839
  args.bylines !== undefined ||
840
+ args.taxonomies !== undefined ||
826
841
  args.publishedAt !== undefined
827
842
  ) {
828
843
  const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
@@ -832,6 +847,7 @@ export function createMcpServer(): McpServer {
832
847
  locale: args.locale,
833
848
  seo: args.seo,
834
849
  bylines: args.bylines,
850
+ taxonomies: args.taxonomies,
835
851
  publishedAt: args.publishedAt,
836
852
  _rev: args._rev,
837
853
  });
@@ -847,6 +863,7 @@ export function createMcpServer(): McpServer {
847
863
  args.slug ||
848
864
  args.seo !== undefined ||
849
865
  args.bylines !== undefined ||
866
+ args.taxonomies !== undefined ||
850
867
  args.publishedAt !== undefined
851
868
  ) {
852
869
  const updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {
@@ -856,6 +873,7 @@ export function createMcpServer(): McpServer {
856
873
  locale: args.locale,
857
874
  seo: args.seo,
858
875
  bylines: args.bylines,
876
+ taxonomies: args.taxonomies,
859
877
  publishedAt: args.publishedAt,
860
878
  _rev: args._rev,
861
879
  });
@@ -872,6 +890,7 @@ export function createMcpServer(): McpServer {
872
890
  locale: args.locale,
873
891
  seo: args.seo,
874
892
  bylines: args.bylines,
893
+ taxonomies: args.taxonomies,
875
894
  publishedAt: args.publishedAt,
876
895
  _rev: args._rev,
877
896
  }),
@@ -1008,7 +1027,7 @@ export function createMcpServer(): McpServer {
1008
1027
  // regardless of ownership (mirrors the REST PUT route's publishedAt gate).
1009
1028
  if (args.publishedAt !== undefined) {
1010
1029
  const user = { id: userId, role: userRole };
1011
- if (!hasPermission(user, "content:publish_any" as Permission)) {
1030
+ if (!hasPermission(user, "content:publish_any")) {
1012
1031
  throw new EmDashAuthError(
1013
1032
  "Setting publishedAt requires content:publish_any permission",
1014
1033
  "INSUFFICIENT_PERMISSIONS",
@@ -1932,6 +1951,12 @@ export function createMcpServer(): McpServer {
1932
1951
  .optional()
1933
1952
  .describe("Filter results by locale (omit to search all locales)"),
1934
1953
  limit: z.number().int().min(1).max(50).optional().describe("Max results (default 20)"),
1954
+ cursor: z
1955
+ .string()
1956
+ .min(1)
1957
+ .max(2048)
1958
+ .optional()
1959
+ .describe("Pagination cursor from a previous response"),
1935
1960
  }),
1936
1961
  annotations: { readOnlyHint: true },
1937
1962
  },
@@ -1944,6 +1969,7 @@ export function createMcpServer(): McpServer {
1944
1969
  collections: args.collections,
1945
1970
  locale: args.locale,
1946
1971
  limit: args.limit,
1972
+ cursor: args.cursor,
1947
1973
  });
1948
1974
  return jsonResult(results);
1949
1975
  } catch (error) {
@@ -20,6 +20,7 @@ import {
20
20
  } from "./content-refresh.js";
21
21
  import {
22
22
  CONTENT_SOURCE_SCHEMA_VERSION,
23
+ type ContentMediaUsageSnapshot,
23
24
  loadContentMediaUsageSnapshots,
24
25
  } from "./content-snapshots.js";
25
26
  import {
@@ -65,11 +66,48 @@ export interface ContentMediaUsageRepairCollectionResult {
65
66
  completedAt: string | null;
66
67
  }
67
68
 
69
+ export interface ContentMediaUsageRepairAllResult {
70
+ status: ContentMediaUsageRepairStatus;
71
+ collections: ContentMediaUsageRepairCollectionResult[];
72
+ indexedSourceCount: number;
73
+ failedSourceCount: number;
74
+ skippedSourceCount: number;
75
+ deletedSourceCount: number;
76
+ }
77
+
68
78
  export interface ContentMediaUsageCollectionScan {
69
79
  collectionSlug: string;
70
80
  contentIds: string[];
71
81
  }
72
82
 
83
+ interface ContentMediaUsageCollectionRecord {
84
+ id: string;
85
+ slug: string;
86
+ }
87
+
88
+ interface ContentMediaUsageInitialCollectionResult {
89
+ collection: ContentMediaUsageCollectionRecord;
90
+ result: ContentMediaUsageRepairCollectionResult;
91
+ }
92
+
93
+ export async function repairContentMediaUsageAll(
94
+ db: Kysely<Database>,
95
+ ): Promise<ContentMediaUsageRepairAllResult> {
96
+ const collections = await loadContentMediaUsageCollectionRecords(db);
97
+ const results: ContentMediaUsageInitialCollectionResult[] = [];
98
+
99
+ for (const collection of collections) {
100
+ results.push({
101
+ collection,
102
+ result: await repairContentMediaUsageCollectionSafely(db, collection.slug),
103
+ });
104
+ }
105
+
106
+ return aggregateContentMediaUsageRepairAll(
107
+ await filterExistingContentMediaUsageCollectionResults(db, results),
108
+ );
109
+ }
110
+
73
111
  export async function scanContentMediaUsageCollection(
74
112
  db: Kysely<Database>,
75
113
  collectionSlug: string,
@@ -105,6 +143,116 @@ export async function repairContentMediaUsageCollection(
105
143
  );
106
144
  }
107
145
 
146
+ async function loadContentMediaUsageCollectionRecords(
147
+ db: Kysely<Database>,
148
+ ): Promise<ContentMediaUsageCollectionRecord[]> {
149
+ return db
150
+ .selectFrom("_emdash_collections")
151
+ .select(["id", "slug"])
152
+ .orderBy("slug", "asc")
153
+ .execute();
154
+ }
155
+
156
+ async function repairContentMediaUsageCollectionSafely(
157
+ db: Kysely<Database>,
158
+ collectionSlug: string,
159
+ ): Promise<ContentMediaUsageRepairCollectionResult> {
160
+ try {
161
+ return await repairContentMediaUsageCollection(db, { collectionSlug });
162
+ } catch (error) {
163
+ console.error(`[media-usage] Failed to repair collection ${collectionSlug}:`, error);
164
+ const now = new Date().toISOString();
165
+ return {
166
+ scope: contentMediaUsageCollectionScope(collectionSlug),
167
+ status: "failed",
168
+ indexedSourceCount: 0,
169
+ failedSourceCount: 0,
170
+ skippedSourceCount: 0,
171
+ deletedSourceCount: 0,
172
+ lastErrorCode: CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_ERROR,
173
+ startedAt: now,
174
+ completedAt: now,
175
+ };
176
+ }
177
+ }
178
+
179
+ async function filterExistingContentMediaUsageCollectionResults(
180
+ db: Kysely<Database>,
181
+ results: readonly ContentMediaUsageInitialCollectionResult[],
182
+ ): Promise<ContentMediaUsageRepairCollectionResult[]> {
183
+ const currentCollections = await loadContentMediaUsageCollectionRecordsSafely(db);
184
+ const currentIdsBySlug = new Map(
185
+ currentCollections.map((collection) => [collection.slug, collection.id]),
186
+ );
187
+ const includedResults: ContentMediaUsageRepairCollectionResult[] = [];
188
+ const excludedResults: ContentMediaUsageRepairCollectionResult[] = [];
189
+
190
+ for (const { collection, result } of results) {
191
+ if (currentIdsBySlug.get(collection.slug) === collection.id) {
192
+ includedResults.push(result);
193
+ } else {
194
+ excludedResults.push(result);
195
+ }
196
+ }
197
+
198
+ if (excludedResults.length > 0) {
199
+ const repo = new MediaUsageRepository(db);
200
+ for (const result of excludedResults) {
201
+ await repo.deleteIndexStatus(result.scope);
202
+ }
203
+ }
204
+
205
+ return includedResults;
206
+ }
207
+
208
+ async function loadContentMediaUsageCollectionRecordsSafely(
209
+ db: Kysely<Database>,
210
+ ): Promise<ContentMediaUsageCollectionRecord[]> {
211
+ try {
212
+ return await loadContentMediaUsageCollectionRecords(db);
213
+ } catch {
214
+ // Retry once before failing; returning unpruned results can over-report deleted collections.
215
+ }
216
+
217
+ try {
218
+ return await loadContentMediaUsageCollectionRecords(db);
219
+ } catch (error) {
220
+ console.error("[media-usage] Failed to reconcile all-content repair collections:", error);
221
+ throw error;
222
+ }
223
+ }
224
+
225
+ function aggregateContentMediaUsageRepairAll(
226
+ collections: readonly ContentMediaUsageRepairCollectionResult[],
227
+ ): ContentMediaUsageRepairAllResult {
228
+ return {
229
+ status: determineRepairAllStatus(collections),
230
+ collections: [...collections],
231
+ indexedSourceCount: sumCollectionRepairCount(collections, "indexedSourceCount"),
232
+ failedSourceCount: sumCollectionRepairCount(collections, "failedSourceCount"),
233
+ skippedSourceCount: sumCollectionRepairCount(collections, "skippedSourceCount"),
234
+ deletedSourceCount: sumCollectionRepairCount(collections, "deletedSourceCount"),
235
+ };
236
+ }
237
+
238
+ function determineRepairAllStatus(
239
+ collections: readonly ContentMediaUsageRepairCollectionResult[],
240
+ ): ContentMediaUsageRepairStatus {
241
+ if (collections.length === 0) return "complete";
242
+ if (collections.every((collection) => collection.status === "complete")) return "complete";
243
+ if (collections.some((collection) => collection.status === "stale")) return "stale";
244
+ if (collections.some((collection) => collection.status === "partial")) return "partial";
245
+ if (collections.every((collection) => collection.status === "failed")) return "failed";
246
+ return "partial";
247
+ }
248
+
249
+ function sumCollectionRepairCount(
250
+ collections: readonly ContentMediaUsageRepairCollectionResult[],
251
+ key: "indexedSourceCount" | "failedSourceCount" | "skippedSourceCount" | "deletedSourceCount",
252
+ ): number {
253
+ return collections.reduce((sum, collection) => sum + collection[key], 0);
254
+ }
255
+
108
256
  async function repairContentMediaUsageCollectionUnlocked(
109
257
  db: Kysely<Database>,
110
258
  collectionSlug: string,
@@ -147,6 +295,7 @@ async function repairContentMediaUsageCollectionUnlocked(
147
295
  skippedSourceCount: 0,
148
296
  deletedSourceCount: 0,
149
297
  lastErrorCode: CONTENT_MEDIA_USAGE_REPAIR_ERROR.COLLECTION_NOT_FOUND,
298
+ missingContentIds: new Set(),
150
299
  },
151
300
  status: "failed",
152
301
  startedAt,
@@ -155,16 +304,14 @@ async function repairContentMediaUsageCollectionUnlocked(
155
304
  }
156
305
  const counts = await repairScannedContentSources(db, repo, scan);
157
306
  const finalScan = await scanContentMediaUsageCollection(db, collectionSlug);
158
- const scannedContentCount = finalScan?.contentIds.length ?? scan.contentIds.length;
159
307
  if (!finalScan) {
160
308
  counts.failedSourceCount++;
161
309
  counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.COLLECTION_NOT_FOUND;
162
- } else if (!sameContentIds(scan.contentIds, finalScan.contentIds)) {
163
- counts.skippedSourceCount++;
164
- counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
310
+ } else if (!sameContentIds(repairedContentIds(scan.contentIds, counts), finalScan.contentIds)) {
311
+ markRepairConflict(counts);
165
312
  }
166
313
  const completedAt = new Date().toISOString();
167
- const status = determineRepairStatus(counts, scannedContentCount);
314
+ const status = determineRepairStatus(counts);
168
315
  return await finalizeRepairStatus(repo, {
169
316
  ...scope,
170
317
  runToken,
@@ -191,6 +338,7 @@ async function repairContentMediaUsageCollectionUnlocked(
191
338
  skippedSourceCount: 0,
192
339
  deletedSourceCount: 0,
193
340
  lastErrorCode,
341
+ missingContentIds: new Set(),
194
342
  },
195
343
  status: "failed",
196
344
  startedAt,
@@ -205,6 +353,7 @@ interface RepairCounts {
205
353
  skippedSourceCount: number;
206
354
  deletedSourceCount: number;
207
355
  lastErrorCode: ContentMediaUsageRepairErrorCode | null;
356
+ missingContentIds: Set<string>;
208
357
  }
209
358
 
210
359
  async function repairScannedContentSources(
@@ -218,6 +367,7 @@ async function repairScannedContentSources(
218
367
  skippedSourceCount: 0,
219
368
  deletedSourceCount: 0,
220
369
  lastErrorCode: null,
370
+ missingContentIds: new Set(),
221
371
  };
222
372
 
223
373
  const fieldDiscovery = await loadContentMediaUsageFields(db, scan.collectionSlug);
@@ -256,7 +406,16 @@ async function repairContentSource(
256
406
  fieldDiscovery,
257
407
  );
258
408
  if (!snapshotsResult.success) {
409
+ if (snapshotsResult.error === CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_NOT_FOUND) {
410
+ markRepairConflict(counts);
411
+ counts.missingContentIds.add(contentId);
412
+ return;
413
+ }
259
414
  counts.lastErrorCode = snapshotsResult.error;
415
+ if (snapshotsResult.snapshots) {
416
+ // Partial snapshot failures keep absent variants in place; the attempted source is marked below.
417
+ await repairSnapshotSources(repo, snapshotsResult.snapshots, observedSources, counts);
418
+ }
260
419
  if (snapshotsResult.source) {
261
420
  const result = await repo.markSourceAttemptedIfMatching(
262
421
  {
@@ -269,8 +428,7 @@ async function repairContentSource(
269
428
  if (result.attempted) {
270
429
  counts.failedSourceCount++;
271
430
  } else {
272
- counts.skippedSourceCount++;
273
- counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
431
+ markRepairConflict(counts);
274
432
  }
275
433
  return;
276
434
  }
@@ -279,8 +437,29 @@ async function repairContentSource(
279
437
  return;
280
438
  }
281
439
 
440
+ const expectedSourceKeys = await repairSnapshotSources(
441
+ repo,
442
+ snapshotsResult.snapshots,
443
+ observedSources,
444
+ counts,
445
+ );
446
+
447
+ for (const sourceKey of sourceKeys) {
448
+ if (expectedSourceKeys.has(sourceKey)) continue;
449
+ const observedSource = observedSources.get(sourceKey);
450
+ if (!observedSource) continue;
451
+ await deleteObservedSource(repo, sourceKey, observedSource, counts);
452
+ }
453
+ }
454
+
455
+ async function repairSnapshotSources(
456
+ repo: MediaUsageRepository,
457
+ snapshots: readonly ContentMediaUsageSnapshot[],
458
+ observedSources: Map<string, MediaUsageSource>,
459
+ counts: RepairCounts,
460
+ ): Promise<Set<string>> {
282
461
  const expectedSourceKeys = new Set<string>();
283
- for (const snapshot of snapshotsResult.snapshots) {
462
+ for (const snapshot of snapshots) {
284
463
  expectedSourceKeys.add(snapshot.source.sourceKey);
285
464
  const result = await repo.replaceSourceIfMatching(
286
465
  snapshot.source,
@@ -290,17 +469,15 @@ async function repairContentSource(
290
469
  if (result.replaced) {
291
470
  counts.indexedSourceCount++;
292
471
  } else {
293
- counts.skippedSourceCount++;
294
- counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
472
+ markRepairConflict(counts);
295
473
  }
296
474
  }
475
+ return expectedSourceKeys;
476
+ }
297
477
 
298
- for (const sourceKey of sourceKeys) {
299
- if (expectedSourceKeys.has(sourceKey)) continue;
300
- const observedSource = observedSources.get(sourceKey);
301
- if (!observedSource) continue;
302
- await deleteObservedSource(repo, sourceKey, observedSource, counts);
303
- }
478
+ function markRepairConflict(counts: RepairCounts): void {
479
+ counts.skippedSourceCount++;
480
+ counts.lastErrorCode ??= CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
304
481
  }
305
482
 
306
483
  async function reconcileOrphanedContentSources(
@@ -370,8 +547,7 @@ async function deleteObservedSourceIfContentAbsent(
370
547
  }
371
548
  if (result.contentPresent) return;
372
549
  if (result.source) {
373
- counts.skippedSourceCount++;
374
- counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
550
+ markRepairConflict(counts);
375
551
  }
376
552
  }
377
553
 
@@ -387,8 +563,7 @@ async function deleteObservedSource(
387
563
  return;
388
564
  }
389
565
  if (result.source) {
390
- counts.skippedSourceCount++;
391
- counts.lastErrorCode = CONTENT_MEDIA_USAGE_REPAIR_ERROR.CONTENT_USAGE_REPAIR_CONFLICT;
566
+ markRepairConflict(counts);
392
567
  }
393
568
  }
394
569
 
@@ -439,11 +614,12 @@ async function finalizeRepairStatus(
439
614
 
440
615
  function determineRepairStatus(
441
616
  counts: RepairCounts,
442
- scannedContentCount: number,
443
617
  ): Exclude<ContentMediaUsageRepairStatus, "stale"> {
444
618
  if (counts.failedSourceCount === 0 && counts.skippedSourceCount === 0) return "complete";
445
619
  const trustedProgress = counts.indexedSourceCount + counts.deletedSourceCount;
446
- if (trustedProgress === 0 && scannedContentCount > 0) return "failed";
620
+ if (counts.failedSourceCount > 0 && trustedProgress === 0) {
621
+ return "failed";
622
+ }
447
623
  return "partial";
448
624
  }
449
625
 
@@ -477,6 +653,14 @@ function sameContentIds(left: readonly string[], right: readonly string[]): bool
477
653
  return left.every((id) => rightIds.has(id));
478
654
  }
479
655
 
656
+ function repairedContentIds(
657
+ contentIds: readonly string[],
658
+ counts: Pick<RepairCounts, "missingContentIds">,
659
+ ): string[] {
660
+ if (counts.missingContentIds.size === 0) return [...contentIds];
661
+ return contentIds.filter((contentId) => !counts.missingContentIds.has(contentId));
662
+ }
663
+
480
664
  function contentMediaUsageCollectionScope(collectionSlug: string): ContentMediaUsageRepairScope {
481
665
  return {
482
666
  adapterId: CONTENT_MEDIA_USAGE_ADAPTER_ID,