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