emdash 0.25.1 → 0.27.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 (418) hide show
  1. package/dist/{adapters-DAAjOID4.d.mts → adapters-u037EnTR.d.mts} +1 -1
  2. package/dist/{adapters-DAAjOID4.d.mts.map → adapters-u037EnTR.d.mts.map} +1 -1
  3. package/dist/api/route-utils.d.mts +3 -3
  4. package/dist/api/route-utils.mjs +11 -11
  5. package/dist/api/schemas/index.d.mts +1 -1
  6. package/dist/{api-D2_sbavn.mjs → api-80kycR9o.mjs} +86 -30
  7. package/dist/api-80kycR9o.mjs.map +1 -0
  8. package/dist/{apply-Bk2mAuLn.mjs → apply-DSypk6Iu.mjs} +20 -18
  9. package/dist/apply-DSypk6Iu.mjs.map +1 -0
  10. package/dist/astro/index.d.mts +11 -10
  11. package/dist/astro/index.d.mts.map +1 -1
  12. package/dist/astro/index.mjs +12 -3
  13. package/dist/astro/index.mjs.map +1 -1
  14. package/dist/astro/middleware/auth.d.mts +10 -9
  15. package/dist/astro/middleware/auth.d.mts.map +1 -1
  16. package/dist/astro/middleware/auth.mjs +4 -3
  17. package/dist/astro/middleware/auth.mjs.map +1 -1
  18. package/dist/astro/middleware/redirect.mjs +4 -4
  19. package/dist/astro/middleware.d.mts +2 -9
  20. package/dist/astro/middleware.d.mts.map +1 -1
  21. package/dist/astro/middleware.mjs +86 -85
  22. package/dist/astro/middleware.mjs.map +1 -1
  23. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +3 -3
  24. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +3 -3
  25. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
  26. package/dist/astro/routes/api/admin/api-tokens/index.mjs +3 -3
  27. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +3 -3
  28. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +4 -4
  29. package/dist/astro/routes/api/admin/byline-fields/index.mjs +4 -4
  30. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +4 -4
  31. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +10 -10
  32. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +10 -10
  33. package/dist/astro/routes/api/admin/bylines/index.mjs +10 -10
  34. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +8 -8
  35. package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
  36. package/dist/astro/routes/api/admin/comments/bulk.mjs +7 -7
  37. package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
  38. package/dist/astro/routes/api/admin/comments/index.mjs +7 -7
  39. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  40. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  41. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
  42. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
  43. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +29 -29
  44. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  45. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +29 -29
  46. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +29 -29
  48. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +28 -28
  50. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +28 -28
  51. package/dist/astro/routes/api/admin/plugins/index.mjs +29 -29
  52. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  54. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +28 -28
  55. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +28 -28
  56. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +28 -28
  57. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +28 -28
  58. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +29 -29
  59. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +28 -28
  60. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +29 -29
  61. package/dist/astro/routes/api/admin/plugins/updates.mjs +28 -28
  62. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +28 -28
  63. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  64. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +28 -28
  65. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  66. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  67. package/dist/astro/routes/api/admin/users/_id_/index.mjs +3 -3
  68. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
  69. package/dist/astro/routes/api/admin/users/index.mjs +3 -3
  70. package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
  71. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  72. package/dist/astro/routes/api/auth/invite/complete.mjs +3 -3
  73. package/dist/astro/routes/api/auth/invite/index.mjs +3 -3
  74. package/dist/astro/routes/api/auth/invite/register-options.mjs +3 -3
  75. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  76. package/dist/astro/routes/api/auth/magic-link/send.mjs +4 -4
  77. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  78. package/dist/astro/routes/api/auth/me.mjs +4 -4
  79. package/dist/astro/routes/api/auth/passkey/_id_.mjs +3 -3
  80. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  81. package/dist/astro/routes/api/auth/passkey/options.mjs +4 -4
  82. package/dist/astro/routes/api/auth/passkey/register/options.mjs +3 -3
  83. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +3 -3
  84. package/dist/astro/routes/api/auth/passkey/verify.mjs +3 -3
  85. package/dist/astro/routes/api/auth/signup/complete.mjs +3 -3
  86. package/dist/astro/routes/api/auth/signup/request.mjs +4 -4
  87. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  88. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +7 -7
  89. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +7 -7
  90. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  91. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  92. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  93. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  94. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +4 -4
  95. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +4 -4
  96. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  97. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  98. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +4 -4
  99. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +9 -9
  100. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  101. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  102. package/dist/astro/routes/api/content/_collection_/_id_.mjs +4 -4
  103. package/dist/astro/routes/api/content/_collection_/authors.mjs +3 -3
  104. package/dist/astro/routes/api/content/_collection_/index.mjs +4 -4
  105. package/dist/astro/routes/api/content/_collection_/trash.mjs +4 -4
  106. package/dist/astro/routes/api/dashboard.mjs +8 -8
  107. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  108. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  109. package/dist/astro/routes/api/import/probe.mjs +4 -4
  110. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  111. package/dist/astro/routes/api/import/wordpress/execute.d.mts +10 -9
  112. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  113. package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -9
  114. package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -9
  115. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  116. package/dist/astro/routes/api/import/wordpress/media.mjs +4 -4
  117. package/dist/astro/routes/api/import/wordpress/prepare.mjs +6 -6
  118. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +5 -5
  119. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  120. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +4 -4
  121. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  122. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +7 -7
  123. package/dist/astro/routes/api/manifest.d.mts.map +1 -1
  124. package/dist/astro/routes/api/manifest.mjs +13 -4
  125. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  126. package/dist/astro/routes/api/mcp.mjs +34 -34
  127. package/dist/astro/routes/api/media/_id_/confirm.mjs +4 -4
  128. package/dist/astro/routes/api/media/_id_.mjs +4 -4
  129. package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
  130. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
  131. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
  132. package/dist/astro/routes/api/media/providers/index.mjs +3 -3
  133. package/dist/astro/routes/api/media/upload-url.mjs +4 -4
  134. package/dist/astro/routes/api/media.mjs +5 -5
  135. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +6 -6
  136. package/dist/astro/routes/api/menus/_name_/items.mjs +6 -6
  137. package/dist/astro/routes/api/menus/_name_/reorder.mjs +6 -6
  138. package/dist/astro/routes/api/menus/_name_/translations.mjs +6 -6
  139. package/dist/astro/routes/api/menus/_name_.mjs +6 -6
  140. package/dist/astro/routes/api/menus/index.mjs +6 -6
  141. package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
  142. package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
  143. package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
  144. package/dist/astro/routes/api/oauth/register.mjs +2 -2
  145. package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
  146. package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
  147. package/dist/astro/routes/api/oauth/token.mjs +2 -2
  148. package/dist/astro/routes/api/openapi.json.mjs +2 -2
  149. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
  150. package/dist/astro/routes/api/redirects/404s/index.mjs +6 -6
  151. package/dist/astro/routes/api/redirects/404s/summary.mjs +6 -6
  152. package/dist/astro/routes/api/redirects/_id_.mjs +7 -7
  153. package/dist/astro/routes/api/redirects/index.mjs +7 -7
  154. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  155. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  156. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +28 -28
  157. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +28 -28
  158. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +28 -28
  159. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +28 -28
  160. package/dist/astro/routes/api/schema/collections/index.mjs +28 -28
  161. package/dist/astro/routes/api/schema/index.mjs +6 -6
  162. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +28 -28
  163. package/dist/astro/routes/api/schema/orphans/index.mjs +28 -28
  164. package/dist/astro/routes/api/search/enable.mjs +7 -7
  165. package/dist/astro/routes/api/search/index.mjs +6 -6
  166. package/dist/astro/routes/api/search/rebuild.mjs +7 -7
  167. package/dist/astro/routes/api/search/stats.mjs +6 -6
  168. package/dist/astro/routes/api/search/suggest.mjs +6 -6
  169. package/dist/astro/routes/api/sections/_slug_.mjs +6 -6
  170. package/dist/astro/routes/api/sections/index.mjs +6 -6
  171. package/dist/astro/routes/api/settings/email.mjs +4 -4
  172. package/dist/astro/routes/api/settings.mjs +9 -9
  173. package/dist/astro/routes/api/setup/admin-verify.mjs +3 -3
  174. package/dist/astro/routes/api/setup/admin.mjs +3 -3
  175. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  176. package/dist/astro/routes/api/setup/dev-bypass.mjs +20 -18
  177. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  178. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  179. package/dist/astro/routes/api/setup/index.mjs +18 -18
  180. package/dist/astro/routes/api/setup/status.mjs +3 -3
  181. package/dist/astro/routes/api/snapshot.mjs +3 -3
  182. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +9 -9
  183. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +9 -9
  184. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +9 -9
  185. package/dist/astro/routes/api/taxonomies/index.mjs +9 -9
  186. package/dist/astro/routes/api/themes/preview.mjs +3 -3
  187. package/dist/astro/routes/api/typegen.mjs +5 -5
  188. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +4 -4
  189. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +6 -6
  190. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +6 -6
  191. package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
  192. package/dist/astro/routes/api/widget-areas/index.mjs +6 -6
  193. package/dist/astro/routes/api/widget-components.mjs +2 -2
  194. package/dist/astro/routes/robots.txt.mjs +5 -5
  195. package/dist/astro/routes/sitemap-_collection_.xml.mjs +10 -9
  196. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  197. package/dist/astro/routes/sitemap.xml.mjs +5 -5
  198. package/dist/astro/types.d.mts +12 -10
  199. package/dist/astro/types.d.mts.map +1 -1
  200. package/dist/auth/providers/github.d.mts +1 -1
  201. package/dist/auth/providers/google.d.mts +1 -1
  202. package/dist/{authorize-CuxZ0i2t.mjs → authorize-C3a_zGsM.mjs} +2 -2
  203. package/dist/{authorize-CuxZ0i2t.mjs.map → authorize-C3a_zGsM.mjs.map} +1 -1
  204. package/dist/{byline-C-YajfV7.mjs → byline-DEKSVPTy.mjs} +6 -6
  205. package/dist/{byline-C-YajfV7.mjs.map → byline-DEKSVPTy.mjs.map} +1 -1
  206. package/dist/{byline-fields-KD3JFRuH.d.mts → byline-fields-CtQ6blXd.d.mts} +32 -32
  207. package/dist/{byline-fields-KD3JFRuH.d.mts.map → byline-fields-CtQ6blXd.d.mts.map} +1 -1
  208. package/dist/{bylines-CPc_q2Vd.mjs → bylines-CiqgTHWF.mjs} +5 -5
  209. package/dist/{bylines-CPc_q2Vd.mjs.map → bylines-CiqgTHWF.mjs.map} +1 -1
  210. package/dist/{bylines-D4KADDAi.mjs → bylines-Ds4-otXl.mjs} +4 -4
  211. package/dist/{bylines-D4KADDAi.mjs.map → bylines-Ds4-otXl.mjs.map} +1 -1
  212. package/dist/{cache-C35VWD5D.mjs → cache-Ciu3e3AF.mjs} +2 -2
  213. package/dist/{cache-C35VWD5D.mjs.map → cache-Ciu3e3AF.mjs.map} +1 -1
  214. package/dist/{chunks-BHgcHh2C.mjs → chunks-CZFiauig.mjs} +2 -2
  215. package/dist/{chunks-BHgcHh2C.mjs.map → chunks-CZFiauig.mjs.map} +1 -1
  216. package/dist/cli/index.mjs +17 -17
  217. package/dist/cli/index.mjs.map +1 -1
  218. package/dist/client/cf-access.d.mts +1 -1
  219. package/dist/client/index.d.mts +1 -1
  220. package/dist/{comment-BDx50EX5.mjs → comment-CH1IrFFs.mjs} +3 -3
  221. package/dist/{comment-BDx50EX5.mjs.map → comment-CH1IrFFs.mjs.map} +1 -1
  222. package/dist/{comment-reaction-Gv_pgfI3.mjs → comment-reaction-kruNY-kP.mjs} +2 -2
  223. package/dist/{comment-reaction-Gv_pgfI3.mjs.map → comment-reaction-kruNY-kP.mjs.map} +1 -1
  224. package/dist/{comments-CXHuQ6jI.mjs → comments-BUJyXbgq.mjs} +3 -3
  225. package/dist/{comments-CXHuQ6jI.mjs.map → comments-BUJyXbgq.mjs.map} +1 -1
  226. package/dist/{content-B43-YrIq.mjs → content-RmfHoWqK.mjs} +4 -4
  227. package/dist/{content-B43-YrIq.mjs.map → content-RmfHoWqK.mjs.map} +1 -1
  228. package/dist/{context-BW3N7wyt.mjs → context-CzUU_WzL.mjs} +7 -7
  229. package/dist/{context-BW3N7wyt.mjs.map → context-CzUU_WzL.mjs.map} +1 -1
  230. package/dist/{dashboard-FIe0S512.mjs → dashboard-CVyGhift.mjs} +4 -4
  231. package/dist/{dashboard-FIe0S512.mjs.map → dashboard-CVyGhift.mjs.map} +1 -1
  232. package/dist/db/index.d.mts +3 -3
  233. package/dist/db/index.mjs +1 -1
  234. package/dist/db/libsql.d.mts +1 -1
  235. package/dist/db/postgres.d.mts +1 -1
  236. package/dist/db/sqlite.d.mts +1 -1
  237. package/dist/{error-DXnK2wF4.mjs → error-BHkLZk-w.mjs} +2 -2
  238. package/dist/{error-DXnK2wF4.mjs.map → error-BHkLZk-w.mjs.map} +1 -1
  239. package/dist/{field-defs-cache-CYYx8xlG.mjs → field-defs-cache-BA-8ZPiT.mjs} +2 -2
  240. package/dist/{field-defs-cache-CYYx8xlG.mjs.map → field-defs-cache-BA-8ZPiT.mjs.map} +1 -1
  241. package/dist/{fts-manager-DW_NR-Fs.mjs → fts-manager-Db9jGavf.mjs} +2 -2
  242. package/dist/{fts-manager-DW_NR-Fs.mjs.map → fts-manager-Db9jGavf.mjs.map} +1 -1
  243. package/dist/{index-Cz6_JBL3.d.mts → index-CDZZjrLT.d.mts} +2430 -2363
  244. package/dist/index-CDZZjrLT.d.mts.map +1 -0
  245. package/dist/{index-qbL02uhs.d.mts → index-DGIjmUXQ.d.mts} +3 -3
  246. package/dist/{index-qbL02uhs.d.mts.map → index-DGIjmUXQ.d.mts.map} +1 -1
  247. package/dist/index.d.mts +16 -15
  248. package/dist/index.mjs +38 -38
  249. package/dist/{load-DMFi4n1p.mjs → load-DpHICVPh.mjs} +2 -2
  250. package/dist/{load-DMFi4n1p.mjs.map → load-DpHICVPh.mjs.map} +1 -1
  251. package/dist/{loader-DrpofRon.mjs → loader-4K37qA-y.mjs} +81 -18
  252. package/dist/loader-4K37qA-y.mjs.map +1 -0
  253. package/dist/{manifest-schema-BOfPXse0.mjs → manifest-schema-kPGX7VS-.mjs} +3 -1
  254. package/dist/manifest-schema-kPGX7VS-.mjs.map +1 -0
  255. package/dist/media/local-runtime.d.mts +11 -10
  256. package/dist/media/local-runtime.d.mts.map +1 -1
  257. package/dist/media/local-runtime.mjs +5 -5
  258. package/dist/{media-BjKxjzk8.mjs → media-C0nRRfs1.mjs} +2 -2
  259. package/dist/{media-BjKxjzk8.mjs.map → media-C0nRRfs1.mjs.map} +1 -1
  260. package/dist/{menus-CxqJ-z-N.mjs → menus-DzRyC1ID.mjs} +50 -68
  261. package/dist/menus-DzRyC1ID.mjs.map +1 -0
  262. package/dist/{menus-8O6xNcYW.mjs → menus-SL2K0xq2.mjs} +3 -3
  263. package/dist/{menus-8O6xNcYW.mjs.map → menus-SL2K0xq2.mjs.map} +1 -1
  264. package/dist/object-cache/memory.d.mts +1 -1
  265. package/dist/{object-cache-SEb2IM4Z.mjs → object-cache-CHbHv83-.mjs} +8 -4
  266. package/dist/object-cache-CHbHv83-.mjs.map +1 -0
  267. package/dist/{options-BvClpP5Q.d.mts → options-41nCWqi9.d.mts} +2 -2
  268. package/dist/{options-BvClpP5Q.d.mts.map → options-41nCWqi9.d.mts.map} +1 -1
  269. package/dist/page/index.d.mts +6 -3
  270. package/dist/page/index.d.mts.map +1 -1
  271. package/dist/page/index.mjs +3 -2
  272. package/dist/page/index.mjs.map +1 -1
  273. package/dist/{parse-DqMWHQ8x.mjs → parse-CqyZj3Hp.mjs} +2 -2
  274. package/dist/{parse-DqMWHQ8x.mjs.map → parse-CqyZj3Hp.mjs.map} +1 -1
  275. package/dist/plugin-types.d.mts +4 -2
  276. package/dist/plugin-types.d.mts.map +1 -1
  277. package/dist/plugin-utils.d.mts +10 -9
  278. package/dist/plugin-utils.d.mts.map +1 -1
  279. package/dist/plugins/adapt-sandbox-entry.d.mts +10 -9
  280. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  281. package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
  282. package/dist/{query-34pfm02Q.mjs → query-B0M-9LYR.mjs} +14 -14
  283. package/dist/{query-34pfm02Q.mjs.map → query-B0M-9LYR.mjs.map} +1 -1
  284. package/dist/{rate-limit-CBQK4ygJ.mjs → rate-limit-BwoUdIpC.mjs} +2 -2
  285. package/dist/{rate-limit-CBQK4ygJ.mjs.map → rate-limit-BwoUdIpC.mjs.map} +1 -1
  286. package/dist/{redirect-C1KVGYWe.mjs → redirect-lMOzG04S.mjs} +2 -2
  287. package/dist/{redirect-C1KVGYWe.mjs.map → redirect-lMOzG04S.mjs.map} +1 -1
  288. package/dist/{redirects-DgnypVir.mjs → redirects-9218MmYl.mjs} +3 -3
  289. package/dist/{redirects-DgnypVir.mjs.map → redirects-9218MmYl.mjs.map} +1 -1
  290. package/dist/{registry-3aOAS4My.mjs → registry-DP-iEtdR.mjs} +4 -4
  291. package/dist/{registry-3aOAS4My.mjs.map → registry-DP-iEtdR.mjs.map} +1 -1
  292. package/dist/{runner-CEtq-6Sm.d.mts → runner-BbR3DfrL.d.mts} +2 -2
  293. package/dist/{runner-CEtq-6Sm.d.mts.map → runner-BbR3DfrL.d.mts.map} +1 -1
  294. package/dist/{runner-BsquExlK.mjs → runner-CFngB4WZ.mjs} +296 -191
  295. package/dist/runner-CFngB4WZ.mjs.map +1 -0
  296. package/dist/runtime.d.mts +10 -9
  297. package/dist/runtime.d.mts.map +1 -1
  298. package/dist/runtime.mjs +2 -2
  299. package/dist/scheduled-publish-BMljtY5G.d.mts +11 -0
  300. package/dist/scheduled-publish-BMljtY5G.d.mts.map +1 -0
  301. package/dist/{schema-BGwx8AQY.mjs → schema-BfJ7bIXH.mjs} +5 -5
  302. package/dist/{schema-BGwx8AQY.mjs.map → schema-BfJ7bIXH.mjs.map} +1 -1
  303. package/dist/{search-Gl747zMP.mjs → search-C7t3PH1J.mjs} +6 -4
  304. package/dist/search-C7t3PH1J.mjs.map +1 -0
  305. package/dist/{sections-C-umuuLj.mjs → sections-Dm0CVX23.mjs} +3 -3
  306. package/dist/{sections-C-umuuLj.mjs.map → sections-Dm0CVX23.mjs.map} +1 -1
  307. package/dist/seed/index.d.mts +2 -2
  308. package/dist/seed/index.mjs +15 -15
  309. package/dist/{seo-BNzkiK_W.mjs → seo-Dd3tbY_k.mjs} +3 -3
  310. package/dist/{seo-BNzkiK_W.mjs.map → seo-Dd3tbY_k.mjs.map} +1 -1
  311. package/dist/{service-CQHK_10l.mjs → service-CTrqp_Jy.mjs} +2 -2
  312. package/dist/{service-CQHK_10l.mjs.map → service-CTrqp_Jy.mjs.map} +1 -1
  313. package/dist/{settings-C4tXRYiG.mjs → settings-BX8cWBus.mjs} +4 -4
  314. package/dist/{settings-C4tXRYiG.mjs.map → settings-BX8cWBus.mjs.map} +1 -1
  315. package/dist/{settings-fPSR6dJa.mjs → settings-CZ7ZP9cW.mjs} +3 -3
  316. package/dist/{settings-fPSR6dJa.mjs.map → settings-CZ7ZP9cW.mjs.map} +1 -1
  317. package/dist/storage/local.d.mts +1 -1
  318. package/dist/storage/s3.d.mts +1 -1
  319. package/dist/{taxonomies-DbAtL6m4.mjs → taxonomies-DChKcVxf.mjs} +5 -4
  320. package/dist/taxonomies-DChKcVxf.mjs.map +1 -0
  321. package/dist/{taxonomies-n8w72lLQ.mjs → taxonomies-ckPjz-6d.mjs} +75 -20
  322. package/dist/taxonomies-ckPjz-6d.mjs.map +1 -0
  323. package/dist/{taxonomy-BBUlGug5.mjs → taxonomy-Cru-he6s.mjs} +4 -4
  324. package/dist/{taxonomy-BBUlGug5.mjs.map → taxonomy-Cru-he6s.mjs.map} +1 -1
  325. package/dist/{transport-BZ-03aFT.d.mts → transport-Blrl2k_o.d.mts} +1 -1
  326. package/dist/{transport-BZ-03aFT.d.mts.map → transport-Blrl2k_o.d.mts.map} +1 -1
  327. package/dist/{types-h2Cwbzi2.d.mts → types-BYnDBVwe.d.mts} +24 -5
  328. package/dist/{types-h2Cwbzi2.d.mts.map → types-BYnDBVwe.d.mts.map} +1 -1
  329. package/dist/{types-BG8_XTLj.d.mts → types-BkZ8DUEI.d.mts} +1 -1
  330. package/dist/{types-BG8_XTLj.d.mts.map → types-BkZ8DUEI.d.mts.map} +1 -1
  331. package/dist/{types-DrYMm9s5.d.mts → types-ByChcBgE.d.mts} +1 -1
  332. package/dist/{types-DrYMm9s5.d.mts.map → types-ByChcBgE.d.mts.map} +1 -1
  333. package/dist/{types-BWqGVhFn.d.mts → types-CvuKO5Pn.d.mts} +1 -1
  334. package/dist/{types-BWqGVhFn.d.mts.map → types-CvuKO5Pn.d.mts.map} +1 -1
  335. package/dist/{types-CmI1OyQg.mjs → types-DU4TSFS5.mjs} +2 -2
  336. package/dist/{types-CmI1OyQg.mjs.map → types-DU4TSFS5.mjs.map} +1 -1
  337. package/dist/{types-CUsXGRVj.d.mts → types-Dbqff978.d.mts} +1 -1
  338. package/dist/{types-CUsXGRVj.d.mts.map → types-Dbqff978.d.mts.map} +1 -1
  339. package/dist/{types-fS7-VTdR.d.mts → types-Y09-wtyU.d.mts} +1 -1
  340. package/dist/{types-fS7-VTdR.d.mts.map → types-Y09-wtyU.d.mts.map} +1 -1
  341. package/dist/{types-B-gIxFCE.d.mts → types-xIfVRNLp.d.mts} +38 -1
  342. package/dist/types-xIfVRNLp.d.mts.map +1 -0
  343. package/dist/{user-JAuc8VUf.mjs → user-DgGbKL9s.mjs} +3 -3
  344. package/dist/{user-JAuc8VUf.mjs.map → user-DgGbKL9s.mjs.map} +1 -1
  345. package/dist/{validate-Va_An3qb.d.mts → validate-9ECmtEpJ.d.mts} +10 -5
  346. package/dist/{validate-Va_An3qb.d.mts.map → validate-9ECmtEpJ.d.mts.map} +1 -1
  347. package/dist/{validate-BzXHWnkV.mjs → validate-CRkcYZAR.mjs} +2 -2
  348. package/dist/{validate-BzXHWnkV.mjs.map → validate-CRkcYZAR.mjs.map} +1 -1
  349. package/dist/{validation-B6DKPTtU.mjs → validation-sR26SOwD.mjs} +5 -5
  350. package/dist/{validation-B6DKPTtU.mjs.map → validation-sR26SOwD.mjs.map} +1 -1
  351. package/dist/version-CrqhKGWn.mjs +7 -0
  352. package/dist/{version-DHdCA24u.mjs.map → version-CrqhKGWn.mjs.map} +1 -1
  353. package/dist/{widgets-C2RbFN0G.mjs → widgets-DRgtn7Cl.mjs} +2 -2
  354. package/dist/{widgets-C2RbFN0G.mjs.map → widgets-DRgtn7Cl.mjs.map} +1 -1
  355. package/dist/{zod-generator-xEHODMJf.mjs → zod-generator-C5JaV--i.mjs} +6 -3
  356. package/dist/zod-generator-C5JaV--i.mjs.map +1 -0
  357. package/package.json +8 -8
  358. package/src/api/handlers/content.ts +59 -16
  359. package/src/api/handlers/plugins.ts +77 -10
  360. package/src/api/handlers/taxonomies.ts +5 -1
  361. package/src/astro/integration/virtual-modules.ts +15 -0
  362. package/src/astro/integration/vite-config.ts +19 -1
  363. package/src/astro/middleware/auth.ts +1 -0
  364. package/src/astro/middleware.ts +1 -0
  365. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +6 -1
  366. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +6 -1
  367. package/src/astro/routes/api/admin/plugins/[id]/index.ts +1 -0
  368. package/src/astro/routes/api/admin/plugins/index.ts +1 -0
  369. package/src/astro/routes/api/manifest.ts +20 -1
  370. package/src/astro/routes/api/setup/dev-bypass.ts +7 -2
  371. package/src/astro/routes/sitemap-[collection].xml.ts +5 -4
  372. package/src/astro/types.ts +4 -0
  373. package/src/cli/commands/seed.ts +1 -1
  374. package/src/components/EmDashHead.astro +23 -3
  375. package/src/components/JsonLdScript.astro +9 -0
  376. package/src/components/LiveSearch.astro +40 -4
  377. package/src/components/live-search-routing.ts +30 -0
  378. package/src/database/migrations/036_i18n_menus_and_taxonomies.ts +39 -18
  379. package/src/database/migrations/046_media_usage_index.ts +115 -0
  380. package/src/database/migrations/047_restore_taxonomy_parent_index.ts +29 -0
  381. package/src/database/migrations/048_restore_content_taxonomies_term_index.ts +32 -0
  382. package/src/database/migrations/runner.ts +6 -0
  383. package/src/database/repositories/media-usage.ts +444 -0
  384. package/src/database/types.ts +39 -0
  385. package/src/emdash-runtime.ts +61 -52
  386. package/src/index.ts +3 -0
  387. package/src/loader.ts +110 -31
  388. package/src/media/usage/extractor.ts +302 -0
  389. package/src/media/usage/types.ts +46 -0
  390. package/src/object-cache/index.ts +8 -2
  391. package/src/page/metadata.ts +23 -3
  392. package/src/plugin-types.ts +10 -0
  393. package/src/plugins/define-plugin.ts +14 -5
  394. package/src/plugins/hooks.ts +53 -65
  395. package/src/plugins/index.ts +5 -0
  396. package/src/plugins/manager.ts +22 -0
  397. package/src/plugins/manifest-schema.ts +2 -0
  398. package/src/plugins/types.ts +35 -3
  399. package/src/schema/zod-generator.ts +9 -1
  400. package/src/search/query.ts +3 -0
  401. package/src/search/types.ts +2 -0
  402. package/src/seed/apply.ts +8 -2
  403. package/src/seed/types.ts +6 -1
  404. package/src/taxonomies/index.ts +121 -18
  405. package/dist/api-D2_sbavn.mjs.map +0 -1
  406. package/dist/apply-Bk2mAuLn.mjs.map +0 -1
  407. package/dist/index-Cz6_JBL3.d.mts.map +0 -1
  408. package/dist/loader-DrpofRon.mjs.map +0 -1
  409. package/dist/manifest-schema-BOfPXse0.mjs.map +0 -1
  410. package/dist/menus-CxqJ-z-N.mjs.map +0 -1
  411. package/dist/object-cache-SEb2IM4Z.mjs.map +0 -1
  412. package/dist/runner-BsquExlK.mjs.map +0 -1
  413. package/dist/search-Gl747zMP.mjs.map +0 -1
  414. package/dist/taxonomies-DbAtL6m4.mjs.map +0 -1
  415. package/dist/taxonomies-n8w72lLQ.mjs.map +0 -1
  416. package/dist/types-B-gIxFCE.d.mts.map +0 -1
  417. package/dist/version-DHdCA24u.mjs +0 -7
  418. package/dist/zod-generator-xEHODMJf.mjs.map +0 -1
@@ -34,6 +34,8 @@ export interface Props {
34
34
  limit?: number;
35
35
  /** CSS class for the container */
36
36
  class?: string;
37
+ /** Inline style for the container */
38
+ style?: string;
37
39
  /** CSS class for the input */
38
40
  inputClass?: string;
39
41
  /** CSS class for the results container */
@@ -48,6 +50,10 @@ export interface Props {
48
50
  suggestMode?: boolean;
49
51
  /** Expand input width on focus (provide collapsed and expanded widths) */
50
52
  expandOnFocus?: { collapsed: string; expanded: string };
53
+ /** Search results page to navigate to when pressing Enter without a focused result */
54
+ searchPage?: string;
55
+ /** Per-collection URL templates, e.g. { posts: "/blog/:path" } */
56
+ routeMap?: Record<string, string>;
51
57
  }
52
58
 
53
59
  const {
@@ -57,6 +63,7 @@ const {
57
63
  debounce = 300,
58
64
  limit = 10,
59
65
  class: className = "",
66
+ style: styleAttr = "",
60
67
  inputClass = "",
61
68
  resultsClass = "",
62
69
  resultClass = "",
@@ -64,6 +71,8 @@ const {
64
71
  autofocus = false,
65
72
  suggestMode = false,
66
73
  expandOnFocus,
74
+ searchPage = "",
75
+ routeMap = {},
67
76
  } = Astro.props;
68
77
 
69
78
  const config = {
@@ -74,11 +83,14 @@ const config = {
74
83
  showSnippets,
75
84
  suggestMode,
76
85
  expandOnFocus: expandOnFocus ?? null,
86
+ searchPage,
87
+ routeMap,
77
88
  };
78
89
  ---
79
90
 
80
91
  <emdash-live-search
81
92
  class:list={["emdash-live-search", className]}
93
+ style={styleAttr}
82
94
  data-config={JSON.stringify(config)}
83
95
  >
84
96
  <input
@@ -109,6 +121,12 @@ const config = {
109
121
  </emdash-live-search>
110
122
 
111
123
  <script>
124
+ import {
125
+ buildLiveSearchResultUrl,
126
+ type LiveSearchRouteMap,
127
+ type LiveSearchRoutableResult,
128
+ } from "./live-search-routing.js";
129
+
112
130
  interface SearchResult {
113
131
  collection: string;
114
132
  id: string;
@@ -121,6 +139,7 @@ const config = {
121
139
  interface Suggestion {
122
140
  collection: string;
123
141
  id: string;
142
+ slug?: string | null;
124
143
  title: string;
125
144
  }
126
145
 
@@ -132,6 +151,8 @@ const config = {
132
151
  showSnippets: boolean;
133
152
  suggestMode: boolean;
134
153
  expandOnFocus: { collapsed: string; expanded: string } | null;
154
+ searchPage: string;
155
+ routeMap: LiveSearchRouteMap;
135
156
  }
136
157
 
137
158
  class EmDashLiveSearch extends HTMLElement {
@@ -149,6 +170,8 @@ const config = {
149
170
  showSnippets: true,
150
171
  suggestMode: false,
151
172
  expandOnFocus: null,
173
+ searchPage: "",
174
+ routeMap: {},
152
175
  };
153
176
  private debounceTimer: ReturnType<typeof setTimeout> | null = null;
154
177
  private abortController: AbortController | null = null;
@@ -268,11 +291,25 @@ const config = {
268
291
  ".emdash-live-search-result:focus, .emdash-live-search-result.focused"
269
292
  ) as HTMLAnchorElement | null;
270
293
  if (focused?.href) {
294
+ e.preventDefault();
271
295
  window.location.href = focused.href;
296
+ return;
297
+ }
298
+
299
+ const query = this.input?.value.trim();
300
+ if (query && this.config.searchPage) {
301
+ e.preventDefault();
302
+ const url = new URL(this.config.searchPage, window.location.origin);
303
+ url.searchParams.set("q", query);
304
+ window.location.href = url.toString();
272
305
  }
273
306
  }
274
307
  }
275
308
 
309
+ private buildResultUrl(result: LiveSearchRoutableResult): string {
310
+ return buildLiveSearchResultUrl(result, this.config.routeMap);
311
+ }
312
+
276
313
  private navigateResults(direction: number) {
277
314
  if (!this.resultsList) return;
278
315
 
@@ -369,9 +406,7 @@ const config = {
369
406
  const link = clone.querySelector("a");
370
407
 
371
408
  if (link) {
372
- // Build URL - use slug if available, otherwise id
373
- const path = result.slug ?? result.id;
374
- link.href = `/${result.collection}/${path}`;
409
+ link.href = this.buildResultUrl(result);
375
410
 
376
411
  // Fill in title
377
412
  const titleEl = link.querySelector(
@@ -430,7 +465,7 @@ const config = {
430
465
  const link = clone.querySelector("a");
431
466
 
432
467
  if (link) {
433
- link.href = `/${suggestion.collection}/${suggestion.id}`;
468
+ link.href = this.buildResultUrl(suggestion);
434
469
 
435
470
  const titleEl = link.querySelector(
436
471
  ".emdash-live-search-result-title"
@@ -456,6 +491,7 @@ const config = {
456
491
 
457
492
  link.dataset.id = suggestion.id;
458
493
  link.dataset.collection = suggestion.collection;
494
+ link.dataset.slug = suggestion.slug ?? "";
459
495
  }
460
496
 
461
497
  this.resultsList.appendChild(clone);
@@ -0,0 +1,30 @@
1
+ export interface LiveSearchRoutableResult {
2
+ collection: string;
3
+ id: string;
4
+ slug?: string | null;
5
+ }
6
+
7
+ export type LiveSearchRouteMap = Record<string, string>;
8
+
9
+ function replaceRouteToken(template: string, token: string, value: string): string {
10
+ return template.split(token).join(value);
11
+ }
12
+
13
+ export function buildLiveSearchResultUrl(
14
+ result: LiveSearchRoutableResult,
15
+ routeMap: LiveSearchRouteMap = {},
16
+ ): string {
17
+ const path = result.slug ?? result.id;
18
+ const template = routeMap[result.collection];
19
+
20
+ if (!template) {
21
+ return `/${result.collection}/${path}`;
22
+ }
23
+
24
+ return [
25
+ [":collection", result.collection],
26
+ [":id", result.id],
27
+ [":slug", result.slug ?? result.id],
28
+ [":path", path],
29
+ ].reduce((url, [token, value]) => replaceRouteToken(url, token, value), template);
30
+ }
@@ -199,6 +199,15 @@ async function rebuildTaxonomies(db: Kysely<unknown>, defaultLocale: string): Pr
199
199
  .on("taxonomies")
200
200
  .column("translation_group")
201
201
  .execute();
202
+ // Dropping the old table dropped idx_taxonomies_parent (from 015); recreate
203
+ // it here for parity with rebuildMenuItems/rebuildContentTaxonomies. Existing
204
+ // installs recover it via migration 047.
205
+ await db.schema
206
+ .createIndex("idx_taxonomies_parent")
207
+ .ifNotExists()
208
+ .on("taxonomies")
209
+ .column("parent_id")
210
+ .execute();
202
211
  }
203
212
 
204
213
  async function rebuildTaxonomyDefs(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
@@ -250,27 +259,32 @@ async function rebuildContentTaxonomies(db: Kysely<unknown>): Promise<void> {
250
259
  // is load-bearing — if the translation_group seed ever changes, this needs
251
260
  // an explicit remap *after* `rebuildTaxonomies` runs.
252
261
  const fks = await sql<{ id: number }>`PRAGMA foreign_key_list(content_taxonomies)`.execute(db);
253
- if (fks.rows.length === 0) return;
254
-
255
- await sql.raw(`DROP TABLE IF EXISTS "content_taxonomies_new"`).execute(db);
256
- await db.schema
257
- .createTable("content_taxonomies_new")
258
- .addColumn("collection", "text", (c) => c.notNull())
259
- .addColumn("entry_id", "text", (c) => c.notNull())
260
- .addColumn("taxonomy_id", "text", (c) => c.notNull())
261
- .addPrimaryKeyConstraint("content_taxonomies_pk", ["collection", "entry_id", "taxonomy_id"])
262
- .execute();
262
+ if (fks.rows.length > 0) {
263
+ await sql.raw(`DROP TABLE IF EXISTS "content_taxonomies_new"`).execute(db);
264
+ await db.schema
265
+ .createTable("content_taxonomies_new")
266
+ .addColumn("collection", "text", (c) => c.notNull())
267
+ .addColumn("entry_id", "text", (c) => c.notNull())
268
+ .addColumn("taxonomy_id", "text", (c) => c.notNull())
269
+ .addPrimaryKeyConstraint("content_taxonomies_pk", ["collection", "entry_id", "taxonomy_id"])
270
+ .execute();
263
271
 
264
- await sql`
265
- INSERT OR IGNORE INTO content_taxonomies_new (collection, entry_id, taxonomy_id)
266
- SELECT collection, entry_id, taxonomy_id FROM content_taxonomies
267
- `.execute(db);
272
+ await sql`
273
+ INSERT OR IGNORE INTO content_taxonomies_new (collection, entry_id, taxonomy_id)
274
+ SELECT collection, entry_id, taxonomy_id FROM content_taxonomies
275
+ `.execute(db);
268
276
 
269
- await db.schema.dropTable("content_taxonomies").execute();
270
- await sql`ALTER TABLE content_taxonomies_new RENAME TO content_taxonomies`.execute(db);
277
+ await db.schema.dropTable("content_taxonomies").execute();
278
+ await sql`ALTER TABLE content_taxonomies_new RENAME TO content_taxonomies`.execute(db);
279
+ }
271
280
 
272
- // SQLite drops indexes when the underlying table is dropped. Restore the
273
- // taxonomy_id index from migration 015.
281
+ // Recreate the taxonomy_id index from migration 015 unconditionally, OUTSIDE
282
+ // the FK-presence guard above. The rebuild both strips the FK and drops the
283
+ // old table's indexes, but D1 auto-commits each DDL statement — so a first
284
+ // run that failed after the drop leaves the table with no FK and no index.
285
+ // The retry then finds zero FKs and skips the rebuild; if the index recreate
286
+ // lived inside that guard it would never run and the index would be lost for
287
+ // good (#1701). `IF NOT EXISTS` keeps this a no-op once present.
274
288
  await sql`CREATE INDEX IF NOT EXISTS idx_content_taxonomies_term ON content_taxonomies(taxonomy_id)`.execute(
275
289
  db,
276
290
  );
@@ -569,6 +583,13 @@ async function rebuildTaxonomiesDown(db: Kysely<unknown>): Promise<void> {
569
583
  await db.schema.dropTable("taxonomies").execute();
570
584
  await sql`ALTER TABLE taxonomies_old RENAME TO taxonomies`.execute(db);
571
585
  await db.schema.createIndex("idx_taxonomies_name").on("taxonomies").column("name").execute();
586
+ // Restore the pre-036 (migration 015) parent index so the rollback is faithful.
587
+ await db.schema
588
+ .createIndex("idx_taxonomies_parent")
589
+ .ifNotExists()
590
+ .on("taxonomies")
591
+ .column("parent_id")
592
+ .execute();
572
593
  }
573
594
 
574
595
  async function rebuildTaxonomyDefsDown(db: Kysely<unknown>): Promise<void> {
@@ -0,0 +1,115 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ import { currentTimestamp } from "../dialect-helpers.js";
4
+
5
+ /**
6
+ * Internal media usage projection tables.
7
+ *
8
+ * This migration is DDL-only by design: no backfill, no runtime media/indexing
9
+ * imports, and no content-table scans. Production rows are introduced by later
10
+ * phases once the central snapshot/indexer path is reviewed.
11
+ */
12
+ export async function up(db: Kysely<unknown>): Promise<void> {
13
+ await db.schema
14
+ .createTable("_emdash_media_usage_sources")
15
+ .ifNotExists()
16
+ .addColumn("source_key", "text", (c) => c.primaryKey())
17
+ .addColumn("source_type", "text", (c) => c.notNull())
18
+ .addColumn("collection_slug", "text")
19
+ .addColumn("content_id", "text")
20
+ .addColumn("source_variant", "text", (c) => c.notNull())
21
+ .addColumn("locale", "text")
22
+ .addColumn("translation_group", "text")
23
+ .addColumn("content_slug", "text")
24
+ .addColumn("content_title", "text")
25
+ .addColumn("content_status", "text")
26
+ .addColumn("content_scheduled_at", "text")
27
+ .addColumn("content_deleted_at", "text")
28
+ .addColumn("revision_id", "text")
29
+ .addColumn("current_generation", "text", (c) => c.notNull())
30
+ .addColumn("schema_version", "integer", (c) => c.notNull().defaultTo(1))
31
+ .addColumn("indexed_at", "text", (c) => c.notNull().defaultTo(currentTimestamp(db)))
32
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
33
+ .addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
34
+ .execute();
35
+
36
+ await db.schema
37
+ .createIndex("idx__emdash_media_usage_sources_content")
38
+ .ifNotExists()
39
+ .on("_emdash_media_usage_sources")
40
+ .columns(["source_type", "collection_slug", "content_id"])
41
+ .execute();
42
+ await db.schema
43
+ .createIndex("idx__emdash_media_usage_sources_variant")
44
+ .ifNotExists()
45
+ .on("_emdash_media_usage_sources")
46
+ .columns(["source_type", "source_variant"])
47
+ .execute();
48
+ await db.schema
49
+ .createIndex("idx__emdash_media_usage_sources_locale")
50
+ .ifNotExists()
51
+ .on("_emdash_media_usage_sources")
52
+ .columns(["collection_slug", "locale"])
53
+ .execute();
54
+ await db.schema
55
+ .createIndex("idx__emdash_media_usage_sources_deleted")
56
+ .ifNotExists()
57
+ .on("_emdash_media_usage_sources")
58
+ .column("content_deleted_at")
59
+ .execute();
60
+ await db.schema
61
+ .createIndex("idx__emdash_media_usage_sources_translation_group")
62
+ .ifNotExists()
63
+ .on("_emdash_media_usage_sources")
64
+ .columns(["collection_slug", "translation_group"])
65
+ .execute();
66
+
67
+ await db.schema
68
+ .createTable("_emdash_media_usage")
69
+ .ifNotExists()
70
+ .addColumn("id", "text", (c) => c.primaryKey())
71
+ .addColumn("source_key", "text", (c) => c.notNull())
72
+ .addColumn("generation", "text", (c) => c.notNull())
73
+ .addColumn("field_slug", "text", (c) => c.notNull())
74
+ .addColumn("field_path", "text", (c) => c.notNull())
75
+ .addColumn("occurrence_index", "integer", (c) => c.notNull().defaultTo(0))
76
+ .addColumn("reference_type", "text", (c) => c.notNull())
77
+ .addColumn("media_id", "text")
78
+ .addColumn("provider", "text", (c) => c.notNull().defaultTo("local"))
79
+ .addColumn("provider_asset_id", "text", (c) => c.notNull())
80
+ .addColumn("media_kind", "text")
81
+ .addColumn("mime_type", "text")
82
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
83
+ .execute();
84
+
85
+ await db.schema
86
+ .createIndex("idx__emdash_media_usage_unique_occurrence")
87
+ .ifNotExists()
88
+ .unique()
89
+ .on("_emdash_media_usage")
90
+ .columns(["source_key", "generation", "field_path", "occurrence_index"])
91
+ .execute();
92
+ await db.schema
93
+ .createIndex("idx__emdash_media_usage_media_id")
94
+ .ifNotExists()
95
+ .on("_emdash_media_usage")
96
+ .column("media_id")
97
+ .execute();
98
+ await db.schema
99
+ .createIndex("idx__emdash_media_usage_provider_asset")
100
+ .ifNotExists()
101
+ .on("_emdash_media_usage")
102
+ .columns(["provider", "provider_asset_id"])
103
+ .execute();
104
+ await db.schema
105
+ .createIndex("idx__emdash_media_usage_source_generation")
106
+ .ifNotExists()
107
+ .on("_emdash_media_usage")
108
+ .columns(["source_key", "generation"])
109
+ .execute();
110
+ }
111
+
112
+ export async function down(db: Kysely<unknown>): Promise<void> {
113
+ await db.schema.dropTable("_emdash_media_usage").ifExists().execute();
114
+ await db.schema.dropTable("_emdash_media_usage_sources").ifExists().execute();
115
+ }
@@ -0,0 +1,29 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ /**
4
+ * Restore `idx_taxonomies_parent` on `taxonomies(parent_id)` (#1665).
5
+ *
6
+ * Migration 015 created this index, but 036's SQLite table rebuild
7
+ * (`taxonomies_new` → drop → rename) dropped every index attached to the old
8
+ * table and only recreated `name`/`locale`/`translation_group`. The parent
9
+ * index — which backs hierarchical (parent/child) lookups — was silently lost
10
+ * on any install migrated through 036. The Postgres path in 036 alters the
11
+ * table in place and keeps its indexes, so it is unaffected; `ifNotExists`
12
+ * makes this a no-op there.
13
+ *
14
+ * Forward-only: 036 has already shipped, so existing installs only recover the
15
+ * index here. Fresh installs also get it in 036's rebuild for parity with the
16
+ * other rebuilt tables, making this a no-op for them.
17
+ */
18
+ export async function up(db: Kysely<unknown>): Promise<void> {
19
+ await db.schema
20
+ .createIndex("idx_taxonomies_parent")
21
+ .ifNotExists()
22
+ .on("taxonomies")
23
+ .column("parent_id")
24
+ .execute();
25
+ }
26
+
27
+ export async function down(db: Kysely<unknown>): Promise<void> {
28
+ await db.schema.dropIndex("idx_taxonomies_parent").ifExists().execute();
29
+ }
@@ -0,0 +1,32 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ /**
4
+ * Restore `idx_content_taxonomies_term` on `content_taxonomies(taxonomy_id)` (#1701).
5
+ *
6
+ * Migration 015 created this index. 036's SQLite/D1 table rebuild recreated it,
7
+ * but the recreate was gated behind an FK-presence early-return: if a first run
8
+ * committed the rebuild (stripping the FK and dropping the old index) and then
9
+ * failed before the recreate, the retry saw zero FKs, skipped the whole body,
10
+ * and never restored the index — while 036 was still recorded as applied. The
11
+ * result was an install missing only this one index, with no forward migration
12
+ * to recover it (the sibling `idx_taxonomies_parent` case was fixed by 047).
13
+ *
14
+ * 036 has since been fixed to recreate the index unconditionally, so fresh
15
+ * installs are fine. This recovers the index on installs that hit the trap
16
+ * before that fix. The Postgres path in 036 alters in place and keeps its
17
+ * indexes, so it is unaffected; `ifNotExists` makes this a no-op there.
18
+ *
19
+ * Forward-only.
20
+ */
21
+ export async function up(db: Kysely<unknown>): Promise<void> {
22
+ await db.schema
23
+ .createIndex("idx_content_taxonomies_term")
24
+ .ifNotExists()
25
+ .on("content_taxonomies")
26
+ .column("taxonomy_id")
27
+ .execute();
28
+ }
29
+
30
+ export async function down(db: Kysely<unknown>): Promise<void> {
31
+ await db.schema.dropIndex("idx_content_taxonomies_term").ifExists().execute();
32
+ }
@@ -47,6 +47,9 @@ import * as m042 from "./042_byline_fields.js";
47
47
  import * as m043 from "./043_content_references.js";
48
48
  import * as m044 from "./044_comment_reactions.js";
49
49
  import * as m045 from "./045_taxonomy_parent_group.js";
50
+ import * as m046 from "./046_media_usage_index.js";
51
+ import * as m047 from "./047_restore_taxonomy_parent_index.js";
52
+ import * as m048 from "./048_restore_content_taxonomies_term_index.js";
50
53
 
51
54
  const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
52
55
  "001_initial": m001,
@@ -93,6 +96,9 @@ const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
93
96
  "043_content_references": m043,
94
97
  "044_comment_reactions": m044,
95
98
  "045_taxonomy_parent_group": m045,
99
+ "046_media_usage_index": m046,
100
+ "047_restore_taxonomy_parent_index": m047,
101
+ "048_restore_content_taxonomies_term_index": m048,
96
102
  });
97
103
 
98
104
  /** Total number of registered migrations. Exported for use in tests. */