emdash 0.17.1 → 0.18.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 (285) hide show
  1. package/dist/api/route-utils.mjs +11 -11
  2. package/dist/{api-Dmz40c2V.mjs → api-Cs7DAACP.mjs} +12 -12
  3. package/dist/{api-Dmz40c2V.mjs.map → api-Cs7DAACP.mjs.map} +1 -1
  4. package/dist/{apply-CuuZG6op.mjs → apply-BWMV4Zmw.mjs} +16 -16
  5. package/dist/{apply-CuuZG6op.mjs.map → apply-BWMV4Zmw.mjs.map} +1 -1
  6. package/dist/astro/index.mjs +1 -1
  7. package/dist/astro/middleware/auth.mjs +2 -2
  8. package/dist/astro/middleware/redirect.mjs +5 -5
  9. package/dist/astro/middleware.d.mts.map +1 -1
  10. package/dist/astro/middleware.mjs +274 -91
  11. package/dist/astro/middleware.mjs.map +1 -1
  12. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +3 -3
  13. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +3 -3
  14. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
  15. package/dist/astro/routes/api/admin/api-tokens/index.mjs +3 -3
  16. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +3 -3
  17. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +4 -4
  18. package/dist/astro/routes/api/admin/byline-fields/index.mjs +4 -4
  19. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +4 -4
  20. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +9 -9
  21. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +9 -9
  22. package/dist/astro/routes/api/admin/bylines/index.mjs +9 -9
  23. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +7 -7
  24. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  25. package/dist/astro/routes/api/admin/comments/bulk.mjs +6 -6
  26. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  27. package/dist/astro/routes/api/admin/comments/index.mjs +6 -6
  28. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  29. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  30. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
  31. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
  32. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +26 -26
  33. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +26 -26
  34. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +26 -26
  35. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +26 -26
  36. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +26 -26
  37. package/dist/astro/routes/api/admin/plugins/index.mjs +26 -26
  38. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  39. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +26 -26
  40. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +26 -26
  41. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +26 -26
  42. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +26 -26
  43. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +27 -27
  44. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +26 -26
  45. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +27 -27
  46. package/dist/astro/routes/api/admin/plugins/updates.mjs +26 -26
  47. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +26 -26
  48. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  49. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +26 -26
  50. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  51. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  52. package/dist/astro/routes/api/admin/users/_id_/index.mjs +3 -3
  53. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
  54. package/dist/astro/routes/api/admin/users/index.mjs +3 -3
  55. package/dist/astro/routes/api/auth/dev-bypass.mjs +4 -4
  56. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  57. package/dist/astro/routes/api/auth/invite/complete.mjs +3 -3
  58. package/dist/astro/routes/api/auth/invite/index.mjs +3 -3
  59. package/dist/astro/routes/api/auth/invite/register-options.mjs +3 -3
  60. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  61. package/dist/astro/routes/api/auth/magic-link/send.mjs +4 -4
  62. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  63. package/dist/astro/routes/api/auth/me.mjs +4 -4
  64. package/dist/astro/routes/api/auth/passkey/_id_.mjs +3 -3
  65. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  66. package/dist/astro/routes/api/auth/passkey/options.mjs +4 -4
  67. package/dist/astro/routes/api/auth/passkey/register/options.mjs +3 -3
  68. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +3 -3
  69. package/dist/astro/routes/api/auth/passkey/verify.mjs +3 -3
  70. package/dist/astro/routes/api/auth/signup/complete.mjs +3 -3
  71. package/dist/astro/routes/api/auth/signup/request.mjs +4 -4
  72. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  73. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +6 -6
  74. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  75. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  76. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  77. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  78. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +4 -4
  79. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +4 -4
  80. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  81. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  82. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +4 -4
  83. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +9 -9
  84. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  85. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  86. package/dist/astro/routes/api/content/_collection_/_id_.mjs +4 -4
  87. package/dist/astro/routes/api/content/_collection_/index.mjs +4 -4
  88. package/dist/astro/routes/api/content/_collection_/trash.mjs +4 -4
  89. package/dist/astro/routes/api/dashboard.mjs +7 -7
  90. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  91. package/dist/astro/routes/api/import/probe.mjs +4 -4
  92. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  93. package/dist/astro/routes/api/import/wordpress/execute.mjs +8 -8
  94. package/dist/astro/routes/api/import/wordpress/media.mjs +4 -4
  95. package/dist/astro/routes/api/import/wordpress/prepare.mjs +6 -6
  96. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +5 -5
  97. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +4 -4
  98. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +6 -6
  99. package/dist/astro/routes/api/manifest.mjs +3 -3
  100. package/dist/astro/routes/api/mcp.mjs +26 -26
  101. package/dist/astro/routes/api/media/_id_/confirm.mjs +4 -4
  102. package/dist/astro/routes/api/media/_id_.mjs +4 -4
  103. package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
  104. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
  105. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
  106. package/dist/astro/routes/api/media/providers/index.mjs +3 -3
  107. package/dist/astro/routes/api/media/upload-url.mjs +4 -4
  108. package/dist/astro/routes/api/media.mjs +5 -5
  109. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +5 -5
  110. package/dist/astro/routes/api/menus/_name_/items.mjs +5 -5
  111. package/dist/astro/routes/api/menus/_name_/reorder.mjs +5 -5
  112. package/dist/astro/routes/api/menus/_name_/translations.mjs +5 -5
  113. package/dist/astro/routes/api/menus/_name_.mjs +5 -5
  114. package/dist/astro/routes/api/menus/index.mjs +5 -5
  115. package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
  116. package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
  117. package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
  118. package/dist/astro/routes/api/oauth/register.mjs +2 -2
  119. package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
  120. package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
  121. package/dist/astro/routes/api/oauth/token.mjs +2 -2
  122. package/dist/astro/routes/api/openapi.json.mjs +2 -2
  123. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
  124. package/dist/astro/routes/api/redirects/404s/index.mjs +7 -7
  125. package/dist/astro/routes/api/redirects/404s/summary.mjs +7 -7
  126. package/dist/astro/routes/api/redirects/_id_.mjs +8 -8
  127. package/dist/astro/routes/api/redirects/index.mjs +8 -8
  128. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  129. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  130. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +26 -26
  131. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +26 -26
  132. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +26 -26
  133. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +26 -26
  134. package/dist/astro/routes/api/schema/collections/index.mjs +26 -26
  135. package/dist/astro/routes/api/schema/index.mjs +7 -7
  136. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +26 -26
  137. package/dist/astro/routes/api/schema/orphans/index.mjs +26 -26
  138. package/dist/astro/routes/api/search/enable.mjs +8 -8
  139. package/dist/astro/routes/api/search/index.mjs +7 -7
  140. package/dist/astro/routes/api/search/rebuild.mjs +8 -8
  141. package/dist/astro/routes/api/search/stats.mjs +7 -7
  142. package/dist/astro/routes/api/search/suggest.mjs +7 -7
  143. package/dist/astro/routes/api/sections/_slug_.mjs +7 -7
  144. package/dist/astro/routes/api/sections/index.mjs +7 -7
  145. package/dist/astro/routes/api/settings/email.mjs +4 -4
  146. package/dist/astro/routes/api/settings.mjs +9 -9
  147. package/dist/astro/routes/api/setup/admin-verify.mjs +3 -3
  148. package/dist/astro/routes/api/setup/admin.mjs +3 -3
  149. package/dist/astro/routes/api/setup/dev-bypass.mjs +16 -16
  150. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  151. package/dist/astro/routes/api/setup/index.mjs +17 -17
  152. package/dist/astro/routes/api/setup/status.mjs +3 -3
  153. package/dist/astro/routes/api/snapshot.mjs +3 -3
  154. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +9 -9
  155. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +9 -9
  156. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +9 -9
  157. package/dist/astro/routes/api/taxonomies/index.mjs +9 -9
  158. package/dist/astro/routes/api/themes/preview.mjs +3 -3
  159. package/dist/astro/routes/api/typegen.mjs +5 -5
  160. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +4 -4
  161. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +7 -7
  162. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +7 -7
  163. package/dist/astro/routes/api/widget-areas/_name_.mjs +6 -6
  164. package/dist/astro/routes/api/widget-areas/index.mjs +7 -7
  165. package/dist/astro/routes/api/widget-components.mjs +2 -2
  166. package/dist/astro/routes/robots.txt.mjs +5 -5
  167. package/dist/astro/routes/sitemap-_collection_.xml.mjs +5 -5
  168. package/dist/astro/routes/sitemap.xml.mjs +5 -5
  169. package/dist/{authorize-_wWM_44T.mjs → authorize-CotM4Yiu.mjs} +2 -2
  170. package/dist/{authorize-_wWM_44T.mjs.map → authorize-CotM4Yiu.mjs.map} +1 -1
  171. package/dist/{byline-BrIVWLm-.mjs → byline-CWQ9aSoz.mjs} +4 -4
  172. package/dist/{byline-BrIVWLm-.mjs.map → byline-CWQ9aSoz.mjs.map} +1 -1
  173. package/dist/{bylines-C_POWmGT.mjs → bylines-BJSva1Un.mjs} +4 -4
  174. package/dist/{bylines-C_POWmGT.mjs.map → bylines-BJSva1Un.mjs.map} +1 -1
  175. package/dist/{bylines-sqExMElV.mjs → bylines-LJMgENMI.mjs} +3 -3
  176. package/dist/{bylines-sqExMElV.mjs.map → bylines-LJMgENMI.mjs.map} +1 -1
  177. package/dist/{cache-wsDkA8ru.mjs → cache-lZL7SgVb.mjs} +2 -2
  178. package/dist/{cache-wsDkA8ru.mjs.map → cache-lZL7SgVb.mjs.map} +1 -1
  179. package/dist/{chunks-BAYkM-CF.mjs → chunks-BU-vP9Dh.mjs} +2 -2
  180. package/dist/{chunks-BAYkM-CF.mjs.map → chunks-BU-vP9Dh.mjs.map} +1 -1
  181. package/dist/cli/index.mjs +14 -14
  182. package/dist/{comment-Cd29aktf.mjs → comment-C4jVbCM8.mjs} +2 -2
  183. package/dist/{comment-Cd29aktf.mjs.map → comment-C4jVbCM8.mjs.map} +1 -1
  184. package/dist/{comments-B7ufhkxN.mjs → comments-BTAbC0Ek.mjs} +3 -3
  185. package/dist/{comments-B7ufhkxN.mjs.map → comments-BTAbC0Ek.mjs.map} +1 -1
  186. package/dist/{content-BbqKo3Kc.mjs → content-CyqOmOzm.mjs} +3 -3
  187. package/dist/{content-BbqKo3Kc.mjs.map → content-CyqOmOzm.mjs.map} +1 -1
  188. package/dist/{context-BsF1rhoI.mjs → context-DZ7bEh5-.mjs} +8 -8
  189. package/dist/{context-BsF1rhoI.mjs.map → context-DZ7bEh5-.mjs.map} +1 -1
  190. package/dist/{dashboard-BwIX9r-X.mjs → dashboard-B5WQpNTP.mjs} +4 -4
  191. package/dist/{dashboard-BwIX9r-X.mjs.map → dashboard-B5WQpNTP.mjs.map} +1 -1
  192. package/dist/db/index.mjs +2 -2
  193. package/dist/{dialect-helpers-BKCvISIQ.mjs → dialect-helpers-DRI5pyY3.mjs} +3 -3
  194. package/dist/dialect-helpers-DRI5pyY3.mjs.map +1 -0
  195. package/dist/{error-npZWBSb7.mjs → error-DJOsMVSt.mjs} +2 -2
  196. package/dist/{error-npZWBSb7.mjs.map → error-DJOsMVSt.mjs.map} +1 -1
  197. package/dist/{fts-manager-DmUAk-kQ.mjs → fts-manager-DR1ERA0c.mjs} +3 -3
  198. package/dist/{fts-manager-DmUAk-kQ.mjs.map → fts-manager-DR1ERA0c.mjs.map} +1 -1
  199. package/dist/index-CjKdMZ3U.d.mts.map +1 -1
  200. package/dist/index.mjs +35 -35
  201. package/dist/{load-DsoLq7ex.mjs → load-6ZrRhepW.mjs} +2 -2
  202. package/dist/{load-DsoLq7ex.mjs.map → load-6ZrRhepW.mjs.map} +1 -1
  203. package/dist/{loader-CJ6lWO0d.mjs → loader-Dyx8dhFV.mjs} +4 -4
  204. package/dist/{loader-CJ6lWO0d.mjs.map → loader-Dyx8dhFV.mjs.map} +1 -1
  205. package/dist/media/local-runtime.mjs +5 -5
  206. package/dist/{media-jk_HzzOl.mjs → media-C-oovGCG.mjs} +2 -2
  207. package/dist/{media-jk_HzzOl.mjs.map → media-C-oovGCG.mjs.map} +1 -1
  208. package/dist/{menus-CyMO6GBx.mjs → menus-BKkxXCmd.mjs} +30 -11
  209. package/dist/menus-BKkxXCmd.mjs.map +1 -0
  210. package/dist/{menus-B-5-3aon.mjs → menus-DugoYwTX.mjs} +2 -2
  211. package/dist/{menus-B-5-3aon.mjs.map → menus-DugoYwTX.mjs.map} +1 -1
  212. package/dist/{parse-4zO5Y2DL.mjs → parse-BBkFmLVr.mjs} +2 -2
  213. package/dist/{parse-4zO5Y2DL.mjs.map → parse-BBkFmLVr.mjs.map} +1 -1
  214. package/dist/{query-Bt52mHXp.mjs → query-Ctlq1aOk.mjs} +10 -10
  215. package/dist/{query-Bt52mHXp.mjs.map → query-Ctlq1aOk.mjs.map} +1 -1
  216. package/dist/{rate-limit-D6VQqBk_.mjs → rate-limit-CH6W6ikK.mjs} +2 -2
  217. package/dist/{rate-limit-D6VQqBk_.mjs.map → rate-limit-CH6W6ikK.mjs.map} +1 -1
  218. package/dist/{redirect-BZUJltlj.mjs → redirect-C6tJA7tk.mjs} +3 -3
  219. package/dist/{redirect-BZUJltlj.mjs.map → redirect-C6tJA7tk.mjs.map} +1 -1
  220. package/dist/{redirects-DnYuqsEf.mjs → redirects-CacE9eQa.mjs} +3 -3
  221. package/dist/{redirects-DnYuqsEf.mjs.map → redirects-CacE9eQa.mjs.map} +1 -1
  222. package/dist/{registry-Dn6gsx3L.mjs → registry-CIDxZbhh.mjs} +5 -5
  223. package/dist/{registry-Dn6gsx3L.mjs.map → registry-CIDxZbhh.mjs.map} +1 -1
  224. package/dist/runner-DM1yR5qd.d.mts.map +1 -1
  225. package/dist/{runner-eAgyIkeg.mjs → runner-pt6Wl-l-.mjs} +11 -6
  226. package/dist/runner-pt6Wl-l-.mjs.map +1 -0
  227. package/dist/runtime.mjs +3 -3
  228. package/dist/{schema--mYZX4D7.mjs → schema-B4tk0HAG.mjs} +4 -4
  229. package/dist/{schema--mYZX4D7.mjs.map → schema-B4tk0HAG.mjs.map} +1 -1
  230. package/dist/{search-C6U_NvZI.mjs → search-f-fNfwab.mjs} +4 -4
  231. package/dist/{search-C6U_NvZI.mjs.map → search-f-fNfwab.mjs.map} +1 -1
  232. package/dist/{sections-Ba-rJLKb.mjs → sections-biElLfT9.mjs} +3 -3
  233. package/dist/{sections-Ba-rJLKb.mjs.map → sections-biElLfT9.mjs.map} +1 -1
  234. package/dist/seed/index.mjs +14 -14
  235. package/dist/seo/index.mjs +1 -0
  236. package/dist/seo/index.mjs.map +1 -1
  237. package/dist/{seo-BTzb5ksq.mjs → seo-BR39kvTF.mjs} +2 -2
  238. package/dist/{seo-BTzb5ksq.mjs.map → seo-BR39kvTF.mjs.map} +1 -1
  239. package/dist/{service-Cn-kIfZn.mjs → service-BhR2acnc.mjs} +2 -2
  240. package/dist/{service-Cn-kIfZn.mjs.map → service-BhR2acnc.mjs.map} +1 -1
  241. package/dist/{settings-C65OSm41.mjs → settings-D_NJvjgN.mjs} +3 -3
  242. package/dist/{settings-C65OSm41.mjs.map → settings-D_NJvjgN.mjs.map} +1 -1
  243. package/dist/{settings-ChlQbwU0.mjs → settings-b5zW1R1T.mjs} +3 -3
  244. package/dist/{settings-ChlQbwU0.mjs.map → settings-b5zW1R1T.mjs.map} +1 -1
  245. package/dist/{taxonomies-ByLlXrv5.mjs → taxonomies-Crtzy4MT.mjs} +8 -7
  246. package/dist/taxonomies-Crtzy4MT.mjs.map +1 -0
  247. package/dist/{taxonomies-CbO6v7EE.mjs → taxonomies-Mhn9rjTQ.mjs} +4 -4
  248. package/dist/{taxonomies-CbO6v7EE.mjs.map → taxonomies-Mhn9rjTQ.mjs.map} +1 -1
  249. package/dist/{taxonomy-BBK-UAEo.mjs → taxonomy-DTZrIQpi.mjs} +3 -3
  250. package/dist/{taxonomy-BBK-UAEo.mjs.map → taxonomy-DTZrIQpi.mjs.map} +1 -1
  251. package/dist/{types-SF1DwGf2.mjs → types-K3MDsxpy.mjs} +2 -2
  252. package/dist/{types-SF1DwGf2.mjs.map → types-K3MDsxpy.mjs.map} +1 -1
  253. package/dist/{user-X4rtyO4Y.mjs → user-DzEUl5zA.mjs} +2 -2
  254. package/dist/{user-X4rtyO4Y.mjs.map → user-DzEUl5zA.mjs.map} +1 -1
  255. package/dist/{validate-DactmcJG.mjs → validate-JCXcsqiY.mjs} +2 -2
  256. package/dist/{validate-DactmcJG.mjs.map → validate-JCXcsqiY.mjs.map} +1 -1
  257. package/dist/{validation-BYA4i85b.mjs → validation-Bq-VyKJg.mjs} +6 -6
  258. package/dist/{validation-BYA4i85b.mjs.map → validation-Bq-VyKJg.mjs.map} +1 -1
  259. package/dist/version-CnS-Cr8A.mjs +7 -0
  260. package/dist/{version-CWbvq9LG.mjs.map → version-CnS-Cr8A.mjs.map} +1 -1
  261. package/dist/{widgets-DG-1jxnz.mjs → widgets-Bap1eS1X.mjs} +2 -2
  262. package/dist/{widgets-DG-1jxnz.mjs.map → widgets-Bap1eS1X.mjs.map} +1 -1
  263. package/dist/{zod-generator-BNAObjSt.mjs → zod-generator-BSDpkqSH.mjs} +4 -3
  264. package/dist/zod-generator-BSDpkqSH.mjs.map +1 -0
  265. package/package.json +7 -7
  266. package/src/astro/middleware/stream-end-metrics.ts +96 -0
  267. package/src/astro/middleware.ts +114 -40
  268. package/src/components/EmDashImage.astro +1 -0
  269. package/src/database/dialect-helpers.ts +8 -2
  270. package/src/database/migrations/019_i18n.ts +2 -2
  271. package/src/database/migrations/runner.ts +7 -2
  272. package/src/emdash-runtime.ts +177 -126
  273. package/src/menus/index.ts +27 -9
  274. package/src/plugins/hooks.ts +35 -6
  275. package/src/plugins/manager.ts +1 -0
  276. package/src/schema/zod-generator.ts +6 -2
  277. package/src/seo/index.ts +10 -1
  278. package/src/taxonomies/index.ts +12 -8
  279. package/src/utils/init-lock.ts +143 -0
  280. package/dist/dialect-helpers-BKCvISIQ.mjs.map +0 -1
  281. package/dist/menus-CyMO6GBx.mjs.map +0 -1
  282. package/dist/runner-eAgyIkeg.mjs.map +0 -1
  283. package/dist/taxonomies-ByLlXrv5.mjs.map +0 -1
  284. package/dist/version-CWbvq9LG.mjs +0 -7
  285. package/dist/zod-generator-BNAObjSt.mjs.map +0 -1
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Reclaimable initialization lock for isolate-lifetime singletons.
3
+ *
4
+ * Guards "first request initializes, everyone else waits" sections
5
+ * (runtime creation, database init) against a workerd failure mode: if the
6
+ * request that owns the initialization is cancelled mid-await (client
7
+ * disconnect, context teardown), its continuation — including any `finally`
8
+ * that would release the lock — never runs. A plain boolean or shared
9
+ * promise then stays stuck forever and every subsequent request in the
10
+ * isolate hangs until the platform kills it (observed as 524s at the
11
+ * 100-second wall limit, with the isolate poisoned until eviction).
12
+ *
13
+ * This lock instead records *when* the owner started. Waiters poll — we
14
+ * deliberately never await a promise created by another request, which
15
+ * workerd flags — and if the owner has held the lock past `deadlineMs`,
16
+ * the next waiter assumes the owner is dead, reclaims the lock, and runs
17
+ * the initialization itself. Waiters also give up after `maxWaitMs` so a
18
+ * request degrades to an error response rather than hanging.
19
+ */
20
+
21
+ export interface InitLock {
22
+ /** Epoch ms when the current owner claimed the lock, or null when free. */
23
+ ownerStartedAt: number | null;
24
+ /**
25
+ * Monotonic claim counter identifying the current owner. Release is
26
+ * gated on it: a slow owner that finishes after a waiter has reclaimed
27
+ * the lock must not clear the reclaimer's claim — that would let yet
28
+ * another caller claim the lock and start a third concurrent init.
29
+ */
30
+ generation: number;
31
+ }
32
+
33
+ export function createInitLock(): InitLock {
34
+ return { ownerStartedAt: null, generation: 0 };
35
+ }
36
+
37
+ export interface InitLockOptions {
38
+ /**
39
+ * Reclaim the lock if the owner has held it longer than this. Must be
40
+ * comfortably above the slowest legitimate init (cold migrations on a
41
+ * contended D1, including the concurrent-migrator wait) — a too-short
42
+ * deadline risks two concurrent inits, a too-long one delays recovery
43
+ * of a poisoned isolate. Nested locks must compose: an outer lock's
44
+ * deadline must exceed the deadline of any lock its init acquires.
45
+ */
46
+ deadlineMs?: number;
47
+ /** Waiter poll interval. */
48
+ pollMs?: number;
49
+ /**
50
+ * Give up waiting after this long and throw instead of hanging.
51
+ * Defaults to `deadlineMs` plus headroom so a waiter always survives
52
+ * long enough to reclaim a dead owner before giving up.
53
+ */
54
+ maxWaitMs?: number;
55
+ /**
56
+ * Called with the in-flight init promise (errors pre-swallowed) so the
57
+ * caller can hand it to the host's lifetime extender (waitUntil via
58
+ * `after()`). If the owning request is cancelled mid-init, the anchored
59
+ * promise keeps the context alive: init completes, populates the cache,
60
+ * and the `finally` below releases the lock — preventing the poisoning
61
+ * instead of merely recovering from it via reclaim.
62
+ */
63
+ anchor?: (promise: Promise<void>) => void;
64
+ }
65
+
66
+ const DEFAULT_DEADLINE_MS = 15_000;
67
+ const DEFAULT_POLL_MS = 50;
68
+ const MAX_WAIT_HEADROOM_MS = 15_000;
69
+
70
+ function sleep(ms: number): Promise<void> {
71
+ return new Promise((resolve) => setTimeout(resolve, ms));
72
+ }
73
+
74
+ /**
75
+ * Return the cached value if present, otherwise initialize it under the
76
+ * lock. `init` is responsible for storing the value so that `getCached`
77
+ * returns it on subsequent calls — waiters re-check `getCached` after the
78
+ * owner finishes rather than sharing the owner's promise.
79
+ *
80
+ * `init` receives an `isCurrentClaim` predicate and must gate its cache
81
+ * publication on it: a slow init that was reclaimed past the deadline
82
+ * must not overwrite the value published by the reclaimer (for the
83
+ * runtime singleton that would orphan the reclaimer's active cron
84
+ * scheduler). A losing init should also tear down any side resources it
85
+ * started, since its result will never be published.
86
+ */
87
+ export async function initWithLock<T>(
88
+ lock: InitLock,
89
+ getCached: () => T | null | undefined,
90
+ init: (isCurrentClaim: () => boolean) => Promise<T>,
91
+ options?: InitLockOptions,
92
+ ): Promise<T> {
93
+ const deadlineMs = options?.deadlineMs ?? DEFAULT_DEADLINE_MS;
94
+ const pollMs = options?.pollMs ?? DEFAULT_POLL_MS;
95
+ const maxWaitMs = options?.maxWaitMs ?? deadlineMs + MAX_WAIT_HEADROOM_MS;
96
+ // Date.now() is deliberate and only works because every loop iteration
97
+ // awaits: in workerd the clock only advances across I/O, so a sync spin
98
+ // would never observe the deadline. Don't "optimize" away the sleep.
99
+ const waitStart = Date.now();
100
+
101
+ for (;;) {
102
+ const cached = getCached();
103
+ if (cached !== null && cached !== undefined) {
104
+ return cached;
105
+ }
106
+
107
+ const ownerStartedAt = lock.ownerStartedAt;
108
+ if (ownerStartedAt === null || Date.now() - ownerStartedAt > deadlineMs) {
109
+ // Free, or the owner has been gone past the deadline — claim it.
110
+ // Synchronous between awaits, so two waiters can't both claim.
111
+ lock.generation += 1;
112
+ const claim = lock.generation;
113
+ lock.ownerStartedAt = Date.now();
114
+ try {
115
+ // Promise.resolve().then(...) so a synchronous throw from
116
+ // init still becomes a rejection after the anchor attaches.
117
+ const isCurrentClaim = () => lock.generation === claim;
118
+ const initPromise = Promise.resolve().then(() => init(isCurrentClaim));
119
+ options?.anchor?.(
120
+ initPromise.then(
121
+ () => undefined,
122
+ () => undefined,
123
+ ),
124
+ );
125
+ return await initPromise;
126
+ } finally {
127
+ // If this request dies mid-init unanchored this never runs;
128
+ // the next waiter reclaims after deadlineMs instead. Release
129
+ // only while still the current owner: a reclaimer may have
130
+ // taken the lock while this (slow) init was running, and
131
+ // clearing its claim would admit a third concurrent init.
132
+ if (lock.generation === claim) {
133
+ lock.ownerStartedAt = null;
134
+ }
135
+ }
136
+ }
137
+
138
+ if (Date.now() - waitStart > maxWaitMs) {
139
+ throw new Error(`initWithLock: timed out after ${maxWaitMs}ms waiting for initialization`);
140
+ }
141
+ await sleep(pollMs);
142
+ }
143
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"dialect-helpers-BKCvISIQ.mjs","names":[],"sources":["../src/database/dialect-helpers.ts"],"sourcesContent":["/**\n * Dialect-specific SQL helpers\n *\n * Every function takes a Kysely `db` instance and detects the dialect from\n * the adapter class. No module-level state, no globals, no heuristics —\n * the adapter is the source of truth.\n *\n * This is NOT an ORM abstraction — just targeted helpers for the ~15 places\n * that use raw dialect-specific SQL. Most Kysely schema builder code already\n * works cross-dialect.\n */\n\nimport type { ColumnDataType, Kysely, RawBuilder } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport type { DatabaseDialectType } from \"../db/adapters.js\";\nimport { validateIdentifier, validateJsonFieldName } from \"./validate.js\";\n\nexport type { DatabaseDialectType };\n\n/**\n * Detect dialect type from a Kysely instance via the adapter class name.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function detectDialect(db: Kysely<any>): DatabaseDialectType {\n\tconst name = db.getExecutor().adapter.constructor.name;\n\tif (name === \"PostgresAdapter\") return \"postgres\";\n\treturn \"sqlite\";\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function isSqlite(db: Kysely<any>): boolean {\n\treturn detectDialect(db) === \"sqlite\";\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function isPostgres(db: Kysely<any>): boolean {\n\treturn detectDialect(db) === \"postgres\";\n}\n\n/**\n * Default timestamp expression for column defaults.\n * Wrapped in parens for use in CREATE TABLE ... DEFAULT (...).\n *\n * sqlite: (datetime('now'))\n * postgres: CURRENT_TIMESTAMP\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function currentTimestamp(db: Kysely<any>): RawBuilder<string> {\n\tif (isPostgres(db)) {\n\t\treturn sql`CURRENT_TIMESTAMP`;\n\t}\n\treturn sql`(datetime('now'))`;\n}\n\n/**\n * Timestamp expression for use in WHERE clauses and SET expressions.\n * No wrapping parens.\n *\n * sqlite: datetime('now')\n * postgres: CURRENT_TIMESTAMP\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function currentTimestampValue(db: Kysely<any>): RawBuilder<string> {\n\tif (isPostgres(db)) {\n\t\treturn sql`CURRENT_TIMESTAMP`;\n\t}\n\treturn sql`datetime('now')`;\n}\n\n/**\n * Check if a table exists in the database.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport async function tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n\tif (isPostgres(db)) {\n\t\tconst result = await sql<{ exists: boolean }>`\n\t\t\tSELECT EXISTS(\n\t\t\t\tSELECT 1 FROM information_schema.tables\n\t\t\t\tWHERE table_schema = 'public' AND table_name = ${tableName}\n\t\t\t) as exists\n\t\t`.execute(db);\n\t\treturn result.rows[0]?.exists === true;\n\t}\n\n\tconst result = await sql<{ name: string }>`\n\t\tSELECT name FROM sqlite_master\n\t\tWHERE type = 'table' AND name = ${tableName}\n\t`.execute(db);\n\treturn result.rows.length > 0;\n}\n\n/**\n * Check if an index exists in the database.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport async function indexExists(db: Kysely<any>, indexName: string): Promise<boolean> {\n\tif (isPostgres(db)) {\n\t\tconst result = await sql<{ exists: boolean }>`\n\t\t\tSELECT EXISTS(\n\t\t\t\tSELECT 1 FROM pg_indexes\n\t\t\t\tWHERE schemaname = current_schema() AND indexname = ${indexName}\n\t\t\t) as exists\n\t\t`.execute(db);\n\t\treturn result.rows[0]?.exists === true;\n\t}\n\n\tconst result = await sql<{ name: string }>`\n\t\tSELECT name FROM sqlite_master\n\t\tWHERE type = 'index' AND name = ${indexName}\n\t`.execute(db);\n\treturn result.rows.length > 0;\n}\n\n/**\n * Check if a column exists in the database.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport async function columnExists(\n\tdb: Kysely<any>,\n\ttableName: string,\n\tcolumnName: string,\n): Promise<boolean> {\n\tif (isPostgres(db)) {\n\t\tconst result = await sql<{ exists: boolean }>`\n\t\t\tSELECT EXISTS(\n\t\t\t\tSELECT 1 FROM information_schema.columns\n\t\t\t\tWHERE table_schema = current_schema()\n\t\t\t\t\tAND table_name = ${tableName}\n\t\t\t\t\tAND column_name = ${columnName}\n\t\t\t) as exists\n\t\t`.execute(db);\n\t\treturn result.rows[0]?.exists === true;\n\t}\n\n\tconst result = await sql<{ name: string }>`\n\t\tSELECT name FROM pragma_table_info(${tableName})\n\t\tWHERE name = ${columnName}\n\t`.execute(db);\n\treturn result.rows.length > 0;\n}\n\n/**\n * List tables matching a LIKE pattern.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport async function listTablesLike(db: Kysely<any>, pattern: string): Promise<string[]> {\n\tif (isPostgres(db)) {\n\t\tconst result = await sql<{ table_name: string }>`\n\t\t\tSELECT table_name FROM information_schema.tables\n\t\t\tWHERE table_schema = 'public' AND table_name LIKE ${pattern}\n\t\t`.execute(db);\n\t\treturn result.rows.map((r) => r.table_name);\n\t}\n\n\tconst result = await sql<{ name: string }>`\n\t\tSELECT name FROM sqlite_master\n\t\tWHERE type = 'table' AND name LIKE ${pattern}\n\t`.execute(db);\n\treturn result.rows.map((r) => r.name);\n}\n\n/**\n * Column type for binary data.\n *\n * sqlite: blob\n * postgres: bytea\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function binaryType(db: Kysely<any>): ColumnDataType {\n\tif (isPostgres(db)) {\n\t\treturn \"bytea\";\n\t}\n\treturn \"blob\";\n}\n\n/**\n * SQL expression for extracting a field from a JSON/JSONB column.\n *\n * sqlite: json_extract(column, '$.path')\n * postgres: column->>'path'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any Kysely instance\nexport function jsonExtractExpr(db: Kysely<any>, column: string, path: string): string {\n\tvalidateIdentifier(column, \"JSON column name\");\n\tvalidateJsonFieldName(path, \"JSON path\");\n\tif (isPostgres(db)) {\n\t\treturn `${column}->>'${path}'`;\n\t}\n\treturn `json_extract(${column}, '$.${path}')`;\n}\n"],"mappings":";;;;;;;AAwBA,SAAgB,cAAc,IAAsC;AAEnE,KADa,GAAG,aAAa,CAAC,QAAQ,YAAY,SACrC,kBAAmB,QAAO;AACvC,QAAO;;AAIR,SAAgB,SAAS,IAA0B;AAClD,QAAO,cAAc,GAAG,KAAK;;AAI9B,SAAgB,WAAW,IAA0B;AACpD,QAAO,cAAc,GAAG,KAAK;;;;;;;;;AAW9B,SAAgB,iBAAiB,IAAqC;AACrE,KAAI,WAAW,GAAG,CACjB,QAAO,GAAG;AAEX,QAAO,GAAG;;;;;;;;;AAWX,SAAgB,sBAAsB,IAAqC;AAC1E,KAAI,WAAW,GAAG,CACjB,QAAO,GAAG;AAEX,QAAO,GAAG;;;;;AAOX,eAAsB,YAAY,IAAiB,WAAqC;AACvF,KAAI,WAAW,GAAG,CAOjB,SANe,MAAM,GAAwB;;;qDAGM,UAAU;;IAE3D,QAAQ,GAAG,EACC,KAAK,IAAI,WAAW;AAOnC,SAJe,MAAM,GAAqB;;oCAEP,UAAU;GAC3C,QAAQ,GAAG,EACC,KAAK,SAAS;;;;;AA6B7B,eAAsB,aACrB,IACA,WACA,YACmB;AACnB,KAAI,WAAW,GAAG,CASjB,SARe,MAAM,GAAwB;;;;wBAIvB,UAAU;yBACT,WAAW;;IAEhC,QAAQ,GAAG,EACC,KAAK,IAAI,WAAW;AAOnC,SAJe,MAAM,GAAqB;uCACJ,UAAU;iBAChC,WAAW;GACzB,QAAQ,GAAG,EACC,KAAK,SAAS;;;;;AAO7B,eAAsB,eAAe,IAAiB,SAAoC;AACzF,KAAI,WAAW,GAAG,CAKjB,SAJe,MAAM,GAA2B;;uDAEK,QAAQ;IAC3D,QAAQ,GAAG,EACC,KAAK,KAAK,MAAM,EAAE,WAAW;AAO5C,SAJe,MAAM,GAAqB;;uCAEJ,QAAQ;GAC5C,QAAQ,GAAG,EACC,KAAK,KAAK,MAAM,EAAE,KAAK;;;;;;;;AAUtC,SAAgB,WAAW,IAAiC;AAC3D,KAAI,WAAW,GAAG,CACjB,QAAO;AAER,QAAO;;;;;;;;AAUR,SAAgB,gBAAgB,IAAiB,QAAgB,MAAsB;AACtF,oBAAmB,QAAQ,mBAAmB;AAC9C,uBAAsB,MAAM,YAAY;AACxC,KAAI,WAAW,GAAG,CACjB,QAAO,GAAG,OAAO,MAAM,KAAK;AAE7B,QAAO,gBAAgB,OAAO,OAAO,KAAK"}