emdash 0.13.0 → 0.15.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 (605) hide show
  1. package/dist/{adapters-9DybjTO6.d.mts → adapters-C4yd_UJR.d.mts} +1 -1
  2. package/dist/{adapters-9DybjTO6.d.mts.map → adapters-C4yd_UJR.d.mts.map} +1 -1
  3. package/dist/{allowed-origins-CDdG-4Gd.mjs → allowed-origins-D0fFk9a6.mjs} +2 -2
  4. package/dist/{allowed-origins-CDdG-4Gd.mjs.map → allowed-origins-D0fFk9a6.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.mjs +15 -15
  7. package/dist/api/schemas/index.d.mts +2 -2
  8. package/dist/api/schemas/index.mjs +3 -3
  9. package/dist/{api-ayIQ7rIe.mjs → api-CLwG_3dh.mjs} +523 -59
  10. package/dist/api-CLwG_3dh.mjs.map +1 -0
  11. package/dist/{api-tokens-eYymBhIT.mjs → api-tokens-ucpcNXDt.mjs} +2 -2
  12. package/dist/{api-tokens-eYymBhIT.mjs.map → api-tokens-ucpcNXDt.mjs.map} +1 -1
  13. package/dist/{apply-v4DBgjPw.mjs → apply-wJhM_bwU.mjs} +17 -17
  14. package/dist/{apply-v4DBgjPw.mjs.map → apply-wJhM_bwU.mjs.map} +1 -1
  15. package/dist/astro/index.d.mts +10 -10
  16. package/dist/astro/index.mjs +21 -5
  17. package/dist/astro/index.mjs.map +1 -1
  18. package/dist/astro/middleware/auth.d.mts +9 -9
  19. package/dist/astro/middleware/auth.mjs +6 -6
  20. package/dist/astro/middleware/auth.mjs.map +1 -1
  21. package/dist/astro/middleware/redirect.mjs +4 -4
  22. package/dist/astro/middleware/request-context.mjs +2 -2
  23. package/dist/astro/middleware/request-context.mjs.map +1 -1
  24. package/dist/astro/middleware/setup.mjs +1 -1
  25. package/dist/astro/middleware.d.mts.map +1 -1
  26. package/dist/astro/middleware.mjs +353 -71
  27. package/dist/astro/middleware.mjs.map +1 -1
  28. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
  29. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
  30. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
  31. package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
  32. package/dist/astro/routes/api/admin/bylines/_id_/index.d.mts.map +1 -1
  33. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -17
  34. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  35. package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +9 -0
  36. package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts.map +1 -0
  37. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +70 -0
  38. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -0
  39. package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
  40. package/dist/astro/routes/api/admin/bylines/index.mjs +25 -16
  41. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  42. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +10 -10
  43. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  44. package/dist/astro/routes/api/admin/comments/bulk.mjs +8 -8
  45. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  46. package/dist/astro/routes/api/admin/comments/index.mjs +8 -8
  47. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  48. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  49. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
  50. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
  51. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +32 -31
  52. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +32 -31
  54. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +31 -30
  56. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +31 -30
  58. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +33 -31
  60. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/plugins/index.mjs +31 -30
  62. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  64. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +31 -30
  65. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +33 -31
  67. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  68. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +31 -30
  69. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  70. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts +8 -0
  71. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -0
  72. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +59 -0
  73. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -0
  74. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts +8 -0
  75. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -0
  76. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +72 -0
  77. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -0
  78. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +31 -30
  79. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  80. package/dist/astro/routes/api/admin/plugins/updates.d.mts.map +1 -1
  81. package/dist/astro/routes/api/admin/plugins/updates.mjs +44 -31
  82. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  83. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +31 -30
  84. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  85. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  86. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +31 -30
  87. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  89. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  90. package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
  91. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
  92. package/dist/astro/routes/api/admin/users/index.mjs +5 -5
  93. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
  94. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  95. package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
  96. package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
  97. package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
  98. package/dist/astro/routes/api/auth/logout.mjs +3 -3
  99. package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
  100. package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
  101. package/dist/astro/routes/api/auth/me.mjs +5 -5
  102. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  103. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  104. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  105. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  106. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  107. package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
  108. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  109. package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
  110. package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
  111. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
  112. package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
  113. package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
  114. package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
  115. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  116. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +11 -11
  117. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  118. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  119. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  120. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  121. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  122. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  123. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +9 -9
  124. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +6 -6
  125. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  126. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  127. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  128. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  129. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +6 -6
  130. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  131. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +10 -9
  132. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  133. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  134. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  135. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  136. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  137. package/dist/astro/routes/api/content/_collection_/_id_.mjs +6 -6
  138. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  139. package/dist/astro/routes/api/content/_collection_/index.mjs +6 -6
  140. package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
  141. package/dist/astro/routes/api/dashboard.mjs +7 -7
  142. package/dist/astro/routes/api/dev/emails.mjs +3 -3
  143. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  144. package/dist/astro/routes/api/import/probe.mjs +10 -10
  145. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  146. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  147. package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -8
  148. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  149. package/dist/astro/routes/api/import/wordpress/media.mjs +8 -8
  150. package/dist/astro/routes/api/import/wordpress/prepare.mjs +8 -8
  151. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  152. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +7 -7
  153. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  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 +10 -10
  156. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  157. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +11 -11
  158. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  159. package/dist/astro/routes/api/manifest.mjs +4 -4
  160. package/dist/astro/routes/api/mcp.mjs +29 -29
  161. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  162. package/dist/astro/routes/api/media/_id_/confirm.mjs +6 -6
  163. package/dist/astro/routes/api/media/_id_.mjs +6 -6
  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 +7 -7
  169. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  170. package/dist/astro/routes/api/media.mjs +8 -8
  171. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +7 -7
  172. package/dist/astro/routes/api/menus/_name_/items.mjs +7 -7
  173. package/dist/astro/routes/api/menus/_name_/reorder.mjs +7 -7
  174. package/dist/astro/routes/api/menus/_name_/translations.mjs +7 -7
  175. package/dist/astro/routes/api/menus/_name_.mjs +7 -7
  176. package/dist/astro/routes/api/menus/index.mjs +7 -7
  177. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  178. package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
  179. package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
  180. package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
  181. package/dist/astro/routes/api/oauth/register.mjs +3 -3
  182. package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
  183. package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
  184. package/dist/astro/routes/api/oauth/token.mjs +6 -6
  185. package/dist/astro/routes/api/openapi.json.mjs +3 -3
  186. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  187. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
  188. package/dist/astro/routes/api/redirects/404s/index.mjs +8 -8
  189. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  190. package/dist/astro/routes/api/redirects/404s/summary.mjs +8 -8
  191. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  192. package/dist/astro/routes/api/redirects/_id_.mjs +9 -9
  193. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  194. package/dist/astro/routes/api/redirects/index.mjs +9 -9
  195. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  196. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  197. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  198. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +31 -30
  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 +31 -30
  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 +31 -30
  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 +31 -30
  205. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  206. package/dist/astro/routes/api/schema/collections/index.mjs +31 -30
  207. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  208. package/dist/astro/routes/api/schema/index.mjs +6 -6
  209. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  210. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +31 -30
  211. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  212. package/dist/astro/routes/api/schema/orphans/index.mjs +31 -30
  213. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  214. package/dist/astro/routes/api/search/enable.mjs +9 -9
  215. package/dist/astro/routes/api/search/index.mjs +8 -8
  216. package/dist/astro/routes/api/search/rebuild.mjs +9 -9
  217. package/dist/astro/routes/api/search/stats.mjs +6 -6
  218. package/dist/astro/routes/api/search/suggest.mjs +8 -8
  219. package/dist/astro/routes/api/sections/_slug_.mjs +8 -8
  220. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  221. package/dist/astro/routes/api/sections/index.mjs +8 -8
  222. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  223. package/dist/astro/routes/api/settings/email.mjs +4 -4
  224. package/dist/astro/routes/api/settings.mjs +10 -10
  225. package/dist/astro/routes/api/setup/admin-verify.mjs +10 -10
  226. package/dist/astro/routes/api/setup/admin.mjs +9 -9
  227. package/dist/astro/routes/api/setup/dev-bypass.mjs +22 -22
  228. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  229. package/dist/astro/routes/api/setup/index.mjs +22 -22
  230. package/dist/astro/routes/api/setup/status.mjs +4 -4
  231. package/dist/astro/routes/api/snapshot.mjs +5 -5
  232. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -10
  233. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  234. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -10
  235. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  236. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -10
  237. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  238. package/dist/astro/routes/api/taxonomies/index.mjs +11 -10
  239. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  240. package/dist/astro/routes/api/themes/preview.mjs +5 -5
  241. package/dist/astro/routes/api/typegen.mjs +5 -5
  242. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  243. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  244. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  245. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +6 -6
  246. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +8 -8
  247. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +8 -8
  248. package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
  249. package/dist/astro/routes/api/widget-areas/index.mjs +8 -8
  250. package/dist/astro/routes/api/widget-components.mjs +3 -3
  251. package/dist/astro/routes/robots.txt.mjs +5 -5
  252. package/dist/astro/routes/sitemap-_collection_.xml.mjs +4 -4
  253. package/dist/astro/routes/sitemap.xml.mjs +5 -5
  254. package/dist/astro/types.d.mts +13 -12
  255. package/dist/astro/types.d.mts.map +1 -1
  256. package/dist/auth/providers/github.d.mts +1 -1
  257. package/dist/auth/providers/google.d.mts +1 -1
  258. package/dist/{authorize-BlyCH-96.mjs → authorize-Bkwe8kuL.mjs} +2 -2
  259. package/dist/{authorize-BlyCH-96.mjs.map → authorize-Bkwe8kuL.mjs.map} +1 -1
  260. package/dist/byline-CTaWkMh5.mjs +404 -0
  261. package/dist/byline-CTaWkMh5.mjs.map +1 -0
  262. package/dist/bylines-BYHWU3T7.mjs +174 -0
  263. package/dist/bylines-BYHWU3T7.mjs.map +1 -0
  264. package/dist/{bylines-C6eYUWlZ.d.mts → bylines-DtDRNF1n.d.mts} +63 -18
  265. package/dist/bylines-DtDRNF1n.d.mts.map +1 -0
  266. package/dist/bylines-H0Xh5TMy.mjs +118 -0
  267. package/dist/bylines-H0Xh5TMy.mjs.map +1 -0
  268. package/dist/{cache-CXCpjWiL.mjs → cache-CNk1jIxp.mjs} +2 -2
  269. package/dist/{cache-CXCpjWiL.mjs.map → cache-CNk1jIxp.mjs.map} +1 -1
  270. package/dist/{challenge-store-CJ0OOHOr.mjs → challenge-store-Dng1SxKT.mjs} +1 -1
  271. package/dist/{challenge-store-CJ0OOHOr.mjs.map → challenge-store-Dng1SxKT.mjs.map} +1 -1
  272. package/dist/{chunks-DyGtu1Bv.mjs → chunks-BkfVdD-3.mjs} +2 -2
  273. package/dist/{chunks-DyGtu1Bv.mjs.map → chunks-BkfVdD-3.mjs.map} +1 -1
  274. package/dist/cli/index.mjs +21 -29
  275. package/dist/cli/index.mjs.map +1 -1
  276. package/dist/client/cf-access.d.mts +1 -1
  277. package/dist/client/index.d.mts +1 -1
  278. package/dist/client/index.mjs +1 -1
  279. package/dist/client/index.mjs.map +1 -1
  280. package/dist/{comment-Dd9MI82-.mjs → comment-_yzlBYPx.mjs} +2 -2
  281. package/dist/{comment-Dd9MI82-.mjs.map → comment-_yzlBYPx.mjs.map} +1 -1
  282. package/dist/{comments-koGI0FrK.mjs → comments-DxID-rsd.mjs} +3 -3
  283. package/dist/{comments-koGI0FrK.mjs.map → comments-DxID-rsd.mjs.map} +1 -1
  284. package/dist/{components-mZem7pbe.mjs → components-Dx3DM0gg.mjs} +1 -1
  285. package/dist/{components-mZem7pbe.mjs.map → components-Dx3DM0gg.mjs.map} +1 -1
  286. package/dist/config-CVssduLe.mjs.map +1 -1
  287. package/dist/{content-D6YG26WG.mjs → content-C0ooIs-f.mjs} +3 -3
  288. package/dist/{content-D6YG26WG.mjs.map → content-C0ooIs-f.mjs.map} +1 -1
  289. package/dist/{context-qF8d3IPR.mjs → context-sAnCaUIR.mjs} +10 -10
  290. package/dist/context-sAnCaUIR.mjs.map +1 -0
  291. package/dist/{cron-H8eJ46dv.mjs → cron-Bd3b3iuj.mjs} +1 -1
  292. package/dist/{cron-H8eJ46dv.mjs.map → cron-Bd3b3iuj.mjs.map} +1 -1
  293. package/dist/{dashboard-BmWSIUwY.mjs → dashboard-Cqw3ay2X.mjs} +4 -4
  294. package/dist/{dashboard-BmWSIUwY.mjs.map → dashboard-Cqw3ay2X.mjs.map} +1 -1
  295. package/dist/db/index.d.mts +3 -3
  296. package/dist/db/index.mjs +1 -1
  297. package/dist/db/libsql.d.mts +1 -1
  298. package/dist/db/postgres.d.mts +1 -1
  299. package/dist/db/sqlite.d.mts +1 -1
  300. package/dist/{default-Dbs22Gg4.mjs → default-BvTAYCzx.mjs} +1 -1
  301. package/dist/{default-Dbs22Gg4.mjs.map → default-BvTAYCzx.mjs.map} +1 -1
  302. package/dist/{device-flow-BqJRxa0Q.mjs → device-flow-B9oG8PwP.mjs} +4 -4
  303. package/dist/{device-flow-BqJRxa0Q.mjs.map → device-flow-B9oG8PwP.mjs.map} +1 -1
  304. package/dist/{email-console-Dmp5Q-P2.mjs → email-console-CubRll9q.mjs} +1 -1
  305. package/dist/email-console-CubRll9q.mjs.map +1 -0
  306. package/dist/{error-tSQWIl5U.mjs → error-CPh_8eLq.mjs} +16 -8
  307. package/dist/error-CPh_8eLq.mjs.map +1 -0
  308. package/dist/{escape-B8bdIryO.mjs → escape-Cg6kMELH.mjs} +1 -1
  309. package/dist/{escape-B8bdIryO.mjs.map → escape-Cg6kMELH.mjs.map} +1 -1
  310. package/dist/{fts-manager-B633C-kQ.mjs → fts-manager-Mnrtn-r2.mjs} +2 -2
  311. package/dist/{fts-manager-B633C-kQ.mjs.map → fts-manager-Mnrtn-r2.mjs.map} +1 -1
  312. package/dist/{import-CNfLOgDE.mjs → import-DG80rC_I.mjs} +3 -3
  313. package/dist/{import-CNfLOgDE.mjs.map → import-DG80rC_I.mjs.map} +1 -1
  314. package/dist/{index-UmOMt9T-.d.mts → index-Bv1Wf1zB.d.mts} +235 -18
  315. package/dist/index-Bv1Wf1zB.d.mts.map +1 -0
  316. package/dist/{index-D2gvztOP.d.mts → index-CC42STEm.d.mts} +3 -3
  317. package/dist/{index-D2gvztOP.d.mts.map → index-CC42STEm.d.mts.map} +1 -1
  318. package/dist/index.d.mts +17 -17
  319. package/dist/index.mjs +50 -49
  320. package/dist/{load-QzYRpVN3.mjs → load-DmXNVhst.mjs} +2 -2
  321. package/dist/{load-QzYRpVN3.mjs.map → load-DmXNVhst.mjs.map} +1 -1
  322. package/dist/{loader-Cs6-Bqe6.mjs → loader-Chm5h7Gr.mjs} +3 -3
  323. package/dist/loader-Chm5h7Gr.mjs.map +1 -0
  324. package/dist/{manifest-schema-HCtSh4Jq.mjs → manifest-schema-Czqf0TLu.mjs} +1 -1
  325. package/dist/{manifest-schema-HCtSh4Jq.mjs.map → manifest-schema-Czqf0TLu.mjs.map} +1 -1
  326. package/dist/media/index.d.mts +1 -1
  327. package/dist/media/local-runtime.d.mts +11 -11
  328. package/dist/media/local-runtime.mjs +4 -4
  329. package/dist/{media-allowlist-B8EX01DH.mjs → media-allowlist-BNloC69x.mjs} +1 -1
  330. package/dist/{media-allowlist-B8EX01DH.mjs.map → media-allowlist-BNloC69x.mjs.map} +1 -1
  331. package/dist/{media-Dg7he9uK.mjs → media-oqRcNiQf.mjs} +2 -2
  332. package/dist/media-oqRcNiQf.mjs.map +1 -0
  333. package/dist/{menus-DOzIecHi.mjs → menus-Bjf5R1Qq.mjs} +2 -2
  334. package/dist/menus-Bjf5R1Qq.mjs.map +1 -0
  335. package/dist/{menus-X4Z-eBA1.mjs → menus-C75SSmRy.mjs} +30 -11
  336. package/dist/menus-C75SSmRy.mjs.map +1 -0
  337. package/dist/mime-KV5TqkMN.mjs.map +1 -1
  338. package/dist/{mode-DPRPvJYm.mjs → mode-CaaiebZI.mjs} +1 -1
  339. package/dist/{mode-DPRPvJYm.mjs.map → mode-CaaiebZI.mjs.map} +1 -1
  340. package/dist/{oauth-authorization-62GmpGIH.mjs → oauth-authorization-CTMeVfvj.mjs} +4 -4
  341. package/dist/{oauth-authorization-62GmpGIH.mjs.map → oauth-authorization-CTMeVfvj.mjs.map} +1 -1
  342. package/dist/{oauth-clients-D_B0_-Bz.mjs → oauth-clients-eJCbkVSG.mjs} +1 -1
  343. package/dist/oauth-clients-eJCbkVSG.mjs.map +1 -0
  344. package/dist/{oauth-state-store-DpsZViTu.mjs → oauth-state-store-vOSdOeGe.mjs} +1 -1
  345. package/dist/{oauth-state-store-DpsZViTu.mjs.map → oauth-state-store-vOSdOeGe.mjs.map} +1 -1
  346. package/dist/{oauth-user-lookup-meyS2oB1.mjs → oauth-user-lookup-3JwsVw6N.mjs} +1 -1
  347. package/dist/{oauth-user-lookup-meyS2oB1.mjs.map → oauth-user-lookup-3JwsVw6N.mjs.map} +1 -1
  348. package/dist/options-BL4X94qY.mjs.map +1 -1
  349. package/dist/{options-Cq64Wx0O.d.mts → options-DhV-gwJb.d.mts} +4 -4
  350. package/dist/options-DhV-gwJb.d.mts.map +1 -0
  351. package/dist/page/index.d.mts +2 -2
  352. package/dist/{parse-BFTPon-J.mjs → parse-3-caTKgt.mjs} +2 -2
  353. package/dist/{parse-BFTPon-J.mjs.map → parse-3-caTKgt.mjs.map} +1 -1
  354. package/dist/{passkey-config-Cg86_ISa.mjs → passkey-config-BloQOT3y.mjs} +1 -1
  355. package/dist/{passkey-config-Cg86_ISa.mjs.map → passkey-config-BloQOT3y.mjs.map} +1 -1
  356. package/dist/{placeholder-D3cFCU9y.d.mts → placeholder-KCkkCtgQ.d.mts} +1 -1
  357. package/dist/{placeholder-D3cFCU9y.d.mts.map → placeholder-KCkkCtgQ.d.mts.map} +1 -1
  358. package/dist/plugin-types.d.mts +1 -1
  359. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  360. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  361. package/dist/plugins/adapt-sandbox-entry.mjs +26 -15
  362. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  363. package/dist/{preview-C1LOEbWZ.mjs → preview-D4z0WONU.mjs} +2 -2
  364. package/dist/{preview-C1LOEbWZ.mjs.map → preview-D4z0WONU.mjs.map} +1 -1
  365. package/dist/{public-url-CseXl9Fv.mjs → public-url-CUWWFME2.mjs} +1 -1
  366. package/dist/{public-url-CseXl9Fv.mjs.map → public-url-CUWWFME2.mjs.map} +1 -1
  367. package/dist/{query-axZmO6Tn.mjs → query-BJn8TOPk.mjs} +16 -13
  368. package/dist/{query-axZmO6Tn.mjs.map → query-BJn8TOPk.mjs.map} +1 -1
  369. package/dist/{rate-limit-t5CVjCO6.mjs → rate-limit-D_-gAeJ0.mjs} +2 -2
  370. package/dist/{rate-limit-t5CVjCO6.mjs.map → rate-limit-D_-gAeJ0.mjs.map} +1 -1
  371. package/dist/{redirect-DGRsLO2I.mjs → redirect-BINiRYq4.mjs} +1 -1
  372. package/dist/{redirect-DGRsLO2I.mjs.map → redirect-BINiRYq4.mjs.map} +1 -1
  373. package/dist/{redirect-DkaDxq8e.mjs → redirect-CNv4mHX2.mjs} +2 -2
  374. package/dist/{redirect-DkaDxq8e.mjs.map → redirect-CNv4mHX2.mjs.map} +1 -1
  375. package/dist/{redirects-D1fdd68T.mjs → redirects-B-CUZ1Xh.mjs} +3 -3
  376. package/dist/{redirects-D1fdd68T.mjs.map → redirects-B-CUZ1Xh.mjs.map} +1 -1
  377. package/dist/{redirects-Dmj6KRU3.mjs → redirects-COMLwsV5.mjs} +19 -5
  378. package/dist/redirects-COMLwsV5.mjs.map +1 -0
  379. package/dist/{registry-BnCeHYsf.mjs → registry-DqrAQDXH.mjs} +4 -4
  380. package/dist/{registry-BnCeHYsf.mjs.map → registry-DqrAQDXH.mjs.map} +1 -1
  381. package/dist/request-cache-dzCt8TZB.mjs.map +1 -1
  382. package/dist/request-context.mjs.map +1 -1
  383. package/dist/{request-meta-CLCwSQOS.mjs → request-meta-C_Cjii-T.mjs} +2 -2
  384. package/dist/{request-meta-CLCwSQOS.mjs.map → request-meta-C_Cjii-T.mjs.map} +1 -1
  385. package/dist/resolve-Cj98DuqN.mjs +39 -0
  386. package/dist/resolve-Cj98DuqN.mjs.map +1 -0
  387. package/dist/{runner-DdnQIwz_.mjs → runner-CGlojznK.mjs} +472 -165
  388. package/dist/runner-CGlojznK.mjs.map +1 -0
  389. package/dist/{runner-DcfZewkO.d.mts → runner-CNHRo1mT.d.mts} +2 -2
  390. package/dist/{runner-DcfZewkO.d.mts.map → runner-CNHRo1mT.d.mts.map} +1 -1
  391. package/dist/runtime.d.mts +10 -10
  392. package/dist/runtime.mjs +2 -2
  393. package/dist/{schema-BmqagCwG.mjs → schema-Djdlfi5G.mjs} +4 -4
  394. package/dist/{schema-BmqagCwG.mjs.map → schema-Djdlfi5G.mjs.map} +1 -1
  395. package/dist/{search-CPrvO5u8.mjs → search-By-NN3da.mjs} +4 -4
  396. package/dist/{search-CPrvO5u8.mjs.map → search-By-NN3da.mjs.map} +1 -1
  397. package/dist/{secrets-6pgZyq0K.mjs → secrets-rPdhEBkD.mjs} +1 -1
  398. package/dist/{secrets-6pgZyq0K.mjs.map → secrets-rPdhEBkD.mjs.map} +1 -1
  399. package/dist/{sections-Cm-zb-gZ.mjs → sections-DcBIlOq1.mjs} +3 -3
  400. package/dist/{sections-Cm-zb-gZ.mjs.map → sections-DcBIlOq1.mjs.map} +1 -1
  401. package/dist/seed/index.d.mts +2 -2
  402. package/dist/seed/index.mjs +16 -16
  403. package/dist/seo/index.d.mts +1 -1
  404. package/dist/{seo-DRq9-EPP.mjs → seo-bjDoq9Eg.mjs} +2 -2
  405. package/dist/{seo-DRq9-EPP.mjs.map → seo-bjDoq9Eg.mjs.map} +1 -1
  406. package/dist/{service-vByySp-2.mjs → service-BuuTdGAT.mjs} +3 -3
  407. package/dist/{service-vByySp-2.mjs.map → service-BuuTdGAT.mjs.map} +1 -1
  408. package/dist/{settings-CBBj7HUd.mjs → settings-CJnKiWuR.mjs} +3 -3
  409. package/dist/{settings-CBBj7HUd.mjs.map → settings-CJnKiWuR.mjs.map} +1 -1
  410. package/dist/{settings-xQKsWnzQ.mjs → settings-hcubRfkr.mjs} +3 -3
  411. package/dist/settings-hcubRfkr.mjs.map +1 -0
  412. package/dist/{setup-BGAJ2uXs.mjs → setup-Cf_TyOv5.mjs} +2 -2
  413. package/dist/{setup-BGAJ2uXs.mjs.map → setup-Cf_TyOv5.mjs.map} +1 -1
  414. package/dist/{setup-complete-C6ZCLhKo.mjs → setup-complete-MzzN9u0b.mjs} +1 -1
  415. package/dist/{setup-complete-C6ZCLhKo.mjs.map → setup-complete-MzzN9u0b.mjs.map} +1 -1
  416. package/dist/{setup-nonce-CY1gQiAU.mjs → setup-nonce-DXuriHsg.mjs} +1 -1
  417. package/dist/{setup-nonce-CY1gQiAU.mjs.map → setup-nonce-DXuriHsg.mjs.map} +1 -1
  418. package/dist/{site-url-D-M4Fd8O.mjs → site-url-xkhw1tcz.mjs} +1 -1
  419. package/dist/{site-url-D-M4Fd8O.mjs.map → site-url-xkhw1tcz.mjs.map} +1 -1
  420. package/dist/{ssrf-DzFN_qV-.mjs → ssrf-MZ-zrG6-.mjs} +1 -1
  421. package/dist/{ssrf-DzFN_qV-.mjs.map → ssrf-MZ-zrG6-.mjs.map} +1 -1
  422. package/dist/storage/local.d.mts +1 -1
  423. package/dist/storage/local.mjs +1 -1
  424. package/dist/storage/local.mjs.map +1 -1
  425. package/dist/storage/s3.d.mts +1 -1
  426. package/dist/storage/s3.mjs +1 -1
  427. package/dist/storage/s3.mjs.map +1 -1
  428. package/dist/{taxonomies-Dc0mzlms.mjs → taxonomies-CLs9HPE2.mjs} +4 -4
  429. package/dist/{taxonomies-Dc0mzlms.mjs.map → taxonomies-CLs9HPE2.mjs.map} +1 -1
  430. package/dist/{taxonomies-Cn9UpaR2.mjs → taxonomies-WamPVA2x.mjs} +7 -42
  431. package/dist/taxonomies-WamPVA2x.mjs.map +1 -0
  432. package/dist/{taxonomy-wPfusMK9.mjs → taxonomy-D4Uc2LsZ.mjs} +3 -3
  433. package/dist/{taxonomy-wPfusMK9.mjs.map → taxonomy-D4Uc2LsZ.mjs.map} +1 -1
  434. package/dist/{tokens-DILYNZMi.mjs → tokens-N8otWMmj.mjs} +1 -1
  435. package/dist/{tokens-DILYNZMi.mjs.map → tokens-N8otWMmj.mjs.map} +1 -1
  436. package/dist/{transport-fw-mKJzT.mjs → transport-B6CHddbu.mjs} +1 -1
  437. package/dist/{transport-fw-mKJzT.mjs.map → transport-B6CHddbu.mjs.map} +1 -1
  438. package/dist/{transport-GeXlLscf.d.mts → transport-DOxLfUir.d.mts} +1 -1
  439. package/dist/{transport-GeXlLscf.d.mts.map → transport-DOxLfUir.d.mts.map} +1 -1
  440. package/dist/{trusted-proxy-CJhQIk65.mjs → trusted-proxy-97pajC2f.mjs} +1 -1
  441. package/dist/{trusted-proxy-CJhQIk65.mjs.map → trusted-proxy-97pajC2f.mjs.map} +1 -1
  442. package/dist/{types-CwXMEPRr.mjs → types-ByV5sgsv.mjs} +2 -2
  443. package/dist/types-ByV5sgsv.mjs.map +1 -0
  444. package/dist/{types-Dz9CGX_d.mjs → types-Cd9UCu3t.mjs} +1 -1
  445. package/dist/{types-Dz9CGX_d.mjs.map → types-Cd9UCu3t.mjs.map} +1 -1
  446. package/dist/{types-DmxPPXGf.d.mts → types-CkDSF81F.d.mts} +1 -1
  447. package/dist/{types-DmxPPXGf.d.mts.map → types-CkDSF81F.d.mts.map} +1 -1
  448. package/dist/{types-BWhaSS7U.d.mts → types-CpUuGcd5.d.mts} +1 -1
  449. package/dist/{types-BWhaSS7U.d.mts.map → types-CpUuGcd5.d.mts.map} +1 -1
  450. package/dist/{types-DFowNO60.d.mts → types-D599-ruj.d.mts} +1 -1
  451. package/dist/{types-DFowNO60.d.mts.map → types-D599-ruj.d.mts.map} +1 -1
  452. package/dist/{types-B05e2naf.d.mts → types-DGHWRQgr.d.mts} +3 -3
  453. package/dist/{types-B05e2naf.d.mts.map → types-DGHWRQgr.d.mts.map} +1 -1
  454. package/dist/{types-CzvJd1ND.d.mts → types-DaYDYW6g.d.mts} +14 -1
  455. package/dist/types-DaYDYW6g.d.mts.map +1 -0
  456. package/dist/{types-C1KKK4VP.d.mts → types-DaqNzqVt.d.mts} +16 -1
  457. package/dist/{types-C1KKK4VP.d.mts.map → types-DaqNzqVt.d.mts.map} +1 -1
  458. package/dist/{types-DW1l0gCv.d.mts → types-Dgo6y-Ut.d.mts} +1 -1
  459. package/dist/{types-DW1l0gCv.d.mts.map → types-Dgo6y-Ut.d.mts.map} +1 -1
  460. package/dist/{types-Cb2UCDJg.d.mts → types-bYmRn_Uy.d.mts} +1 -1
  461. package/dist/{types-Cb2UCDJg.d.mts.map → types-bYmRn_Uy.d.mts.map} +1 -1
  462. package/dist/{user-Dr1bOCqS.mjs → user-D3BD5zdT.mjs} +2 -2
  463. package/dist/{user-Dr1bOCqS.mjs.map → user-D3BD5zdT.mjs.map} +1 -1
  464. package/dist/{utils-_F-rWBTN.mjs → utils-C3wTAP-P.mjs} +1 -1
  465. package/dist/{utils-_F-rWBTN.mjs.map → utils-C3wTAP-P.mjs.map} +1 -1
  466. package/dist/{validate-BpQGsmd7.d.mts → validate-DQtHw9NT.d.mts} +5 -5
  467. package/dist/{validate-BpQGsmd7.d.mts.map → validate-DQtHw9NT.d.mts.map} +1 -1
  468. package/dist/{validate-DlFxcVVK.mjs → validate-mz87i8_1.mjs} +2 -2
  469. package/dist/{validate-DlFxcVVK.mjs.map → validate-mz87i8_1.mjs.map} +1 -1
  470. package/dist/{validation-BiFJqUp5.mjs → validation-DKHhXjPr.mjs} +5 -5
  471. package/dist/{validation-BiFJqUp5.mjs.map → validation-DKHhXjPr.mjs.map} +1 -1
  472. package/dist/version-Ct7C6RSo.mjs +7 -0
  473. package/dist/{version-Dw7Z5PVU.mjs.map → version-Ct7C6RSo.mjs.map} +1 -1
  474. package/dist/{widgets-B9j_yzlk.mjs → widgets-lShIQXU5.mjs} +3 -3
  475. package/dist/widgets-lShIQXU5.mjs.map +1 -0
  476. package/dist/{zod-generator-DSyz01KE.mjs → zod-generator-dvxgmd1M.mjs} +2 -2
  477. package/dist/{zod-generator-DSyz01KE.mjs.map → zod-generator-dvxgmd1M.mjs.map} +1 -1
  478. package/package.json +10 -8
  479. package/src/api/error.ts +18 -3
  480. package/src/api/errors.ts +6 -0
  481. package/src/api/handlers/bylines.ts +161 -0
  482. package/src/api/handlers/content.ts +125 -43
  483. package/src/api/handlers/index.ts +6 -0
  484. package/src/api/handlers/marketplace.ts +27 -5
  485. package/src/api/handlers/oauth-clients.ts +1 -1
  486. package/src/api/handlers/registry.ts +568 -22
  487. package/src/api/openapi/document.ts +1 -1
  488. package/src/api/schemas/bylines.ts +46 -0
  489. package/src/astro/integration/index.ts +1 -1
  490. package/src/astro/integration/routes.ts +5 -0
  491. package/src/astro/integration/runtime.ts +12 -1
  492. package/src/astro/integration/virtual-modules.ts +19 -2
  493. package/src/astro/integration/vite-config.ts +2 -2
  494. package/src/astro/middleware/auth.ts +7 -7
  495. package/src/astro/middleware/request-context.ts +1 -1
  496. package/src/astro/middleware.ts +31 -20
  497. package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -12
  498. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +99 -0
  499. package/src/astro/routes/api/admin/bylines/index.ts +22 -11
  500. package/src/astro/routes/api/admin/plugins/[id]/update.ts +1 -0
  501. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +6 -1
  502. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +51 -0
  503. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +79 -0
  504. package/src/astro/routes/api/admin/plugins/updates.ts +43 -6
  505. package/src/astro/routes/api/admin/themes/marketplace/index.ts +1 -1
  506. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +2 -2
  507. package/src/astro/routes/api/auth/oauth/[provider].ts +2 -2
  508. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -2
  509. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -2
  510. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -2
  511. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -2
  512. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +2 -2
  513. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +6 -6
  514. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +1 -1
  515. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -2
  516. package/src/astro/routes/api/content/[collection]/[id].ts +6 -6
  517. package/src/astro/routes/api/import/wordpress/execute.ts +1 -1
  518. package/src/astro/routes/api/import/wordpress/prepare.ts +2 -2
  519. package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +3 -3
  520. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +2 -2
  521. package/src/astro/routes/api/media/upload-url.ts +1 -1
  522. package/src/astro/routes/api/redirects/404s/index.ts +3 -3
  523. package/src/astro/routes/api/redirects/404s/summary.ts +1 -1
  524. package/src/astro/routes/api/redirects/[id].ts +3 -3
  525. package/src/astro/routes/api/redirects/index.ts +2 -2
  526. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +4 -4
  527. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +2 -6
  528. package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +1 -1
  529. package/src/astro/routes/api/schema/collections/[slug]/index.ts +6 -6
  530. package/src/astro/routes/api/schema/collections/index.ts +4 -4
  531. package/src/astro/routes/api/schema/index.ts +1 -1
  532. package/src/astro/routes/api/schema/orphans/[slug].ts +1 -1
  533. package/src/astro/routes/api/schema/orphans/index.ts +1 -1
  534. package/src/astro/routes/api/sections/[slug].ts +3 -3
  535. package/src/astro/routes/api/sections/index.ts +2 -2
  536. package/src/astro/types.ts +4 -0
  537. package/src/auth/rate-limit.ts +1 -1
  538. package/src/auth/trusted-proxy.ts +1 -1
  539. package/src/bylines/index.ts +154 -55
  540. package/src/cli/commands/init.ts +4 -8
  541. package/src/client/index.ts +1 -1
  542. package/src/components/InlinePortableTextEditor.tsx +5 -1
  543. package/src/components/inline-code-block.tsx +343 -0
  544. package/src/config/secrets.ts +3 -3
  545. package/src/database/migrations/006_taxonomy_defs.ts +1 -1
  546. package/src/database/migrations/014_draft_revisions.ts +6 -6
  547. package/src/database/migrations/040_byline_i18n.ts +497 -0
  548. package/src/database/migrations/runner.ts +4 -1
  549. package/src/database/repositories/audit.ts +2 -2
  550. package/src/database/repositories/byline.ts +320 -50
  551. package/src/database/repositories/media.ts +2 -2
  552. package/src/database/repositories/menu.ts +1 -1
  553. package/src/database/repositories/options.ts +3 -3
  554. package/src/database/repositories/plugin-storage.ts +3 -3
  555. package/src/database/repositories/types.ts +13 -0
  556. package/src/database/types.ts +15 -0
  557. package/src/emdash-runtime.ts +492 -20
  558. package/src/i18n/config.ts +1 -1
  559. package/src/index.ts +7 -0
  560. package/src/loader.ts +1 -1
  561. package/src/mcp/server.ts +3 -3
  562. package/src/media/mime.ts +1 -1
  563. package/src/page/absolute-url.ts +1 -1
  564. package/src/plugins/adapt-sandbox-entry.ts +45 -40
  565. package/src/plugins/email-console.ts +1 -1
  566. package/src/plugins/index.ts +1 -0
  567. package/src/plugins/marketplace.ts +1 -1
  568. package/src/plugins/sandbox/index.ts +1 -0
  569. package/src/plugins/sandbox/noop.ts +11 -3
  570. package/src/plugins/sandbox/types.ts +28 -0
  571. package/src/query.ts +17 -2
  572. package/src/registry/config.ts +1 -1
  573. package/src/request-cache.ts +3 -3
  574. package/src/request-context.ts +1 -1
  575. package/src/settings/index.ts +4 -4
  576. package/src/storage/local.ts +1 -1
  577. package/src/storage/s3.ts +3 -3
  578. package/src/widgets/index.ts +1 -1
  579. package/dist/api-ayIQ7rIe.mjs.map +0 -1
  580. package/dist/byline-D09BaS4j.mjs +0 -220
  581. package/dist/byline-D09BaS4j.mjs.map +0 -1
  582. package/dist/bylines-BTM2xtP8.mjs +0 -113
  583. package/dist/bylines-BTM2xtP8.mjs.map +0 -1
  584. package/dist/bylines-C6eYUWlZ.d.mts.map +0 -1
  585. package/dist/context-qF8d3IPR.mjs.map +0 -1
  586. package/dist/email-console-Dmp5Q-P2.mjs.map +0 -1
  587. package/dist/error-tSQWIl5U.mjs.map +0 -1
  588. package/dist/index-UmOMt9T-.d.mts.map +0 -1
  589. package/dist/loader-Cs6-Bqe6.mjs.map +0 -1
  590. package/dist/media-Dg7he9uK.mjs.map +0 -1
  591. package/dist/menus-DOzIecHi.mjs.map +0 -1
  592. package/dist/menus-X4Z-eBA1.mjs.map +0 -1
  593. package/dist/oauth-clients-D_B0_-Bz.mjs.map +0 -1
  594. package/dist/options-Cq64Wx0O.d.mts.map +0 -1
  595. package/dist/redirects-Dmj6KRU3.mjs.map +0 -1
  596. package/dist/runner-DdnQIwz_.mjs.map +0 -1
  597. package/dist/settings-xQKsWnzQ.mjs.map +0 -1
  598. package/dist/taxonomies-Cn9UpaR2.mjs.map +0 -1
  599. package/dist/types-CwXMEPRr.mjs.map +0 -1
  600. package/dist/types-CzvJd1ND.d.mts.map +0 -1
  601. package/dist/version-Dw7Z5PVU.mjs +0 -7
  602. package/dist/widgets-B9j_yzlk.mjs.map +0 -1
  603. /package/dist/{api-tokens-D3C9v02m.mjs → api-tokens-iPIHAY8N.mjs} +0 -0
  604. /package/dist/{ssrf-CTul4uQi.mjs → ssrf-BIcd-aXW.mjs} +0 -0
  605. /package/dist/{types-Db67HHlU.mjs → types-1NNkmTIn.mjs} +0 -0
@@ -0,0 +1,497 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ import { getI18nConfig } from "../../i18n/config.js";
5
+ import { currentTimestamp, isSqlite, listTablesLike } from "../dialect-helpers.js";
6
+ import { validateIdentifier } from "../validate.js";
7
+
8
+ /**
9
+ * i18n for bylines. Adds `locale` + `translation_group` to `_emdash_bylines`
10
+ * and stores translation_groups (not row ids) in
11
+ * `_emdash_content_bylines.byline_id` and `ec_*.primary_byline_id`. Backfill
12
+ * locale and column DEFAULTs use the site's configured defaultLocale.
13
+ *
14
+ * Mirrors the row-per-locale + `translation_group` model PR #916 (migration
15
+ * 036) applied to menus and taxonomies.
16
+ *
17
+ * Key consequences of the model:
18
+ * - `(slug, locale)` is unique on `_emdash_bylines`; a single slug can repeat
19
+ * across locales (one row per locale variant of a byline).
20
+ * - The partial unique on `user_id` widens to `(user_id, locale)` so a CMS
21
+ * user can have one byline per locale.
22
+ * - `_emdash_content_bylines.byline_id` no longer FKs to `_emdash_bylines.id`
23
+ * (it holds a `translation_group`, not a row id). The runtime is
24
+ * responsible for cascading on byline delete — see `BylineRepository.delete`.
25
+ *
26
+ * Hydration is strict per locale (see `BylineRepository.getContentBylines`):
27
+ * a credit at locale X renders iff a byline row exists at locale X within the
28
+ * credited translation group. This mirrors `getEntryTerms` and the convention
29
+ * established by #916. There is no read-time fallback.
30
+ */
31
+
32
+ function getDefaultLocale(): string {
33
+ return getI18nConfig()?.defaultLocale ?? "en";
34
+ }
35
+
36
+ export async function up(db: Kysely<unknown>): Promise<void> {
37
+ const defaultLocale = getDefaultLocale();
38
+
39
+ if (isSqlite(db)) {
40
+ // Rebuild children before parents to drop FKs that would CASCADE
41
+ // on D1 (#1021). `_emdash_content_bylines.byline_id` has an FK to
42
+ // `_emdash_bylines(id) ON DELETE CASCADE` from migration 031.
43
+ // Stripping it first lets us rebuild `_emdash_bylines` without
44
+ // risking a cascading wipe of credits on D1.
45
+ await rebuildContentBylines(db);
46
+ await rebuildBylines(db, defaultLocale);
47
+ await remapPrimaryBylineIds(db);
48
+ return;
49
+ }
50
+
51
+ await pgWidenBylines(db, defaultLocale);
52
+ await pgDropContentBylinesFk(db);
53
+ await remapPrimaryBylineIds(db);
54
+ }
55
+
56
+ async function rebuildContentBylines(db: Kysely<unknown>): Promise<void> {
57
+ // Drops the FK so `byline_id` can point at a translation_group rather
58
+ // than a row id. Runs before `rebuildBylines` so the drop is safe on D1.
59
+ // No remap is needed here: `rebuildBylines` later seeds `translation_group
60
+ // = id` for every preserved row, so the row-id values we copy resolve as
61
+ // translation_group references after the migration completes. This coupling
62
+ // is load-bearing — if the translation_group seed ever changes, this needs
63
+ // an explicit remap *after* `rebuildBylines` runs.
64
+ const fks = await sql<{ id: number }>`PRAGMA foreign_key_list(_emdash_content_bylines)`.execute(
65
+ db,
66
+ );
67
+ if (fks.rows.length === 0) return;
68
+
69
+ await sql.raw(`DROP TABLE IF EXISTS "_emdash_content_bylines_new"`).execute(db);
70
+ await db.schema
71
+ .createTable("_emdash_content_bylines_new")
72
+ .addColumn("id", "text", (c) => c.primaryKey())
73
+ .addColumn("collection_slug", "text", (c) => c.notNull())
74
+ .addColumn("content_id", "text", (c) => c.notNull())
75
+ .addColumn("byline_id", "text", (c) => c.notNull())
76
+ .addColumn("sort_order", "integer", (c) => c.notNull().defaultTo(0))
77
+ .addColumn("role_label", "text")
78
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
79
+ .addUniqueConstraint("content_bylines_unique", ["collection_slug", "content_id", "byline_id"])
80
+ .execute();
81
+
82
+ await sql`
83
+ INSERT INTO _emdash_content_bylines_new
84
+ (id, collection_slug, content_id, byline_id, sort_order, role_label, created_at)
85
+ SELECT id, collection_slug, content_id, byline_id, sort_order, role_label, created_at
86
+ FROM _emdash_content_bylines
87
+ `.execute(db);
88
+
89
+ await db.schema.dropTable("_emdash_content_bylines").execute();
90
+ await sql`ALTER TABLE _emdash_content_bylines_new RENAME TO _emdash_content_bylines`.execute(db);
91
+
92
+ // Indexes from migration 031 dropped with the table; restore.
93
+ await db.schema
94
+ .createIndex("idx_content_bylines_content")
95
+ .on("_emdash_content_bylines")
96
+ .columns(["collection_slug", "content_id", "sort_order"])
97
+ .execute();
98
+ await db.schema
99
+ .createIndex("idx_content_bylines_byline")
100
+ .on("_emdash_content_bylines")
101
+ .column("byline_id")
102
+ .execute();
103
+ }
104
+
105
+ async function rebuildBylines(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
106
+ if (await hasColumn(db, "_emdash_bylines", "locale")) return;
107
+ await sql.raw(`DROP TABLE IF EXISTS "_emdash_bylines_new"`).execute(db);
108
+
109
+ await db.schema
110
+ .createTable("_emdash_bylines_new")
111
+ .addColumn("id", "text", (c) => c.primaryKey())
112
+ .addColumn("slug", "text", (c) => c.notNull())
113
+ .addColumn("display_name", "text", (c) => c.notNull())
114
+ .addColumn("bio", "text")
115
+ .addColumn("avatar_media_id", "text", (c) => c.references("media.id").onDelete("set null"))
116
+ .addColumn("website_url", "text")
117
+ .addColumn("user_id", "text", (c) => c.references("users.id").onDelete("set null"))
118
+ .addColumn("is_guest", "integer", (c) => c.notNull().defaultTo(0))
119
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
120
+ .addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
121
+ .addColumn("locale", "text", (c) => c.notNull().defaultTo(defaultLocale))
122
+ .addColumn("translation_group", "text")
123
+ .addUniqueConstraint("_emdash_bylines_slug_locale_unique", ["slug", "locale"])
124
+ .execute();
125
+
126
+ await sql`
127
+ INSERT INTO _emdash_bylines_new (
128
+ id, slug, display_name, bio, avatar_media_id, website_url,
129
+ user_id, is_guest, created_at, updated_at, locale, translation_group
130
+ )
131
+ SELECT
132
+ id, slug, display_name, bio, avatar_media_id, website_url,
133
+ user_id, is_guest, created_at, updated_at, ${defaultLocale}, id
134
+ FROM _emdash_bylines
135
+ `.execute(db);
136
+
137
+ await db.schema.dropTable("_emdash_bylines").execute();
138
+ await sql`ALTER TABLE _emdash_bylines_new RENAME TO _emdash_bylines`.execute(db);
139
+
140
+ // Indexes from migration 031 dropped with the table; restore the
141
+ // per-slug and per-display-name indexes. The partial unique on
142
+ // user_id widens to (user_id, locale) so one CMS user can own one
143
+ // byline per locale.
144
+ await db.schema.createIndex("idx_bylines_slug").on("_emdash_bylines").column("slug").execute();
145
+ await db.schema
146
+ .createIndex("idx_bylines_display_name")
147
+ .on("_emdash_bylines")
148
+ .column("display_name")
149
+ .execute();
150
+ await sql`
151
+ CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_locale_unique")}
152
+ ON ${sql.ref("_emdash_bylines")} (user_id, locale)
153
+ WHERE user_id IS NOT NULL
154
+ `.execute(db);
155
+
156
+ await db.schema
157
+ .createIndex("idx__emdash_bylines_locale")
158
+ .on("_emdash_bylines")
159
+ .column("locale")
160
+ .execute();
161
+ await db.schema
162
+ .createIndex("idx__emdash_bylines_translation_group")
163
+ .on("_emdash_bylines")
164
+ .column("translation_group")
165
+ .execute();
166
+
167
+ // One row per (translation_group, locale): the row-per-locale model
168
+ // (PR #916) requires that each locale variant of a byline appears
169
+ // exactly once in its translation group. `UNIQUE(slug, locale)` doesn't
170
+ // catch the case where two siblings in the same group use different
171
+ // slugs at the same locale — this partial unique does. `WHERE
172
+ // translation_group IS NOT NULL` is defensive: post-040 every row has a
173
+ // value, but the column is nullable in the schema.
174
+ await sql`
175
+ CREATE UNIQUE INDEX ${sql.ref("idx_bylines_group_locale_unique")}
176
+ ON ${sql.ref("_emdash_bylines")} (translation_group, locale)
177
+ WHERE translation_group IS NOT NULL
178
+ `.execute(db);
179
+ }
180
+
181
+ async function remapPrimaryBylineIds(db: Kysely<unknown>): Promise<void> {
182
+ // Walks every `ec_*` table and remaps `primary_byline_id` (row id →
183
+ // translation_group). On a fresh install translation_group equals id
184
+ // for every row, so the values look unchanged — but the column
185
+ // semantics flip from "FK to _emdash_bylines.id" to "translation_group
186
+ // in _emdash_bylines.translation_group". Once translations exist, the
187
+ // remap is meaningful: a credit pointing at the en-row id still
188
+ // resolves to the same byline group at every locale variant.
189
+ const collections = await listTablesLike(db, "ec_%");
190
+ for (const table of collections) {
191
+ validateIdentifier(table, "content table");
192
+ await sql`
193
+ UPDATE ${sql.ref(table)} SET primary_byline_id = (
194
+ SELECT translation_group FROM _emdash_bylines
195
+ WHERE _emdash_bylines.id = ${sql.ref(table)}.primary_byline_id
196
+ )
197
+ WHERE primary_byline_id IS NOT NULL
198
+ AND EXISTS (
199
+ SELECT 1 FROM _emdash_bylines
200
+ WHERE _emdash_bylines.id = ${sql.ref(table)}.primary_byline_id
201
+ )
202
+ `.execute(db);
203
+ }
204
+ }
205
+
206
+ async function pgWidenBylines(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
207
+ const ref = sql.ref("_emdash_bylines");
208
+ await sql`ALTER TABLE ${ref} ADD COLUMN IF NOT EXISTS locale TEXT NOT NULL DEFAULT ${sql.lit(defaultLocale)}`.execute(
209
+ db,
210
+ );
211
+ await sql`ALTER TABLE ${ref} ADD COLUMN IF NOT EXISTS translation_group TEXT`.execute(db);
212
+ await sql`UPDATE ${ref} SET translation_group = id WHERE translation_group IS NULL`.execute(db);
213
+ await sql`CREATE INDEX IF NOT EXISTS ${sql.ref("idx__emdash_bylines_locale")} ON ${ref} (locale)`.execute(
214
+ db,
215
+ );
216
+ await sql`
217
+ CREATE INDEX IF NOT EXISTS ${sql.ref("idx__emdash_bylines_translation_group")}
218
+ ON ${ref} (translation_group)
219
+ `.execute(db);
220
+
221
+ // Widen UNIQUE(slug) -> UNIQUE(slug, locale)
222
+ const slugCons = await sql<{ conname: string }>`
223
+ SELECT conname FROM pg_constraint c
224
+ WHERE c.conrelid = '_emdash_bylines'::regclass AND c.contype = 'u'
225
+ AND array_length(c.conkey, 1) = 1
226
+ AND (
227
+ SELECT array_agg(a.attname ORDER BY pos.ord)
228
+ FROM unnest(c.conkey) WITH ORDINALITY AS pos(attnum, ord)
229
+ JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = pos.attnum
230
+ )::text[] = ARRAY['slug']
231
+ `.execute(db);
232
+ for (const c of slugCons.rows) {
233
+ await sql`ALTER TABLE ${ref} DROP CONSTRAINT ${sql.ref(c.conname)}`.execute(db);
234
+ }
235
+ await sql`
236
+ ALTER TABLE ${ref}
237
+ ADD CONSTRAINT _emdash_bylines_slug_locale_unique UNIQUE (slug, locale)
238
+ `.execute(db);
239
+
240
+ // Replace the partial unique on (user_id) with (user_id, locale).
241
+ await sql`DROP INDEX IF EXISTS idx_bylines_user_id_unique`.execute(db);
242
+ await sql`
243
+ CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_user_id_locale_unique")}
244
+ ON ${ref} (user_id, locale) WHERE user_id IS NOT NULL
245
+ `.execute(db);
246
+
247
+ // One row per (translation_group, locale): see SQLite branch above.
248
+ await sql`
249
+ CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_group_locale_unique")}
250
+ ON ${ref} (translation_group, locale) WHERE translation_group IS NOT NULL
251
+ `.execute(db);
252
+ }
253
+
254
+ async function pgDropContentBylinesFk(db: Kysely<unknown>): Promise<void> {
255
+ const fks = await sql<{ conname: string }>`
256
+ SELECT conname FROM pg_constraint
257
+ WHERE conrelid = '_emdash_content_bylines'::regclass AND contype = 'f'
258
+ `.execute(db);
259
+ for (const c of fks.rows) {
260
+ await sql`ALTER TABLE _emdash_content_bylines DROP CONSTRAINT ${sql.ref(c.conname)}`.execute(
261
+ db,
262
+ );
263
+ }
264
+ }
265
+
266
+ async function hasColumn(db: Kysely<unknown>, table: string, column: string): Promise<boolean> {
267
+ const rows = await sql<{ name: string }>`PRAGMA table_info(${sql.ref(table)})`.execute(db);
268
+ return rows.rows.some((r) => r.name === column);
269
+ }
270
+
271
+ /**
272
+ * down() restores the FK on `_emdash_content_bylines.byline_id`. Rows whose
273
+ * `byline_id` doesn't resolve to a (translation_group, defaultLocale) row in
274
+ * `_emdash_bylines` would fail the rebuild after other tables are already
275
+ * stripped — leaving the user mid-rollback. Surface dangling rows up front.
276
+ */
277
+ async function assertContentBylinesResolve(
278
+ db: Kysely<unknown>,
279
+ defaultLocale: string,
280
+ ): Promise<void> {
281
+ const result = await sql<{ count: number | string }>`
282
+ SELECT COUNT(*) AS count FROM _emdash_content_bylines cb
283
+ WHERE NOT EXISTS (
284
+ SELECT 1 FROM _emdash_bylines b
285
+ WHERE b.translation_group = cb.byline_id AND b.locale = ${defaultLocale}
286
+ )
287
+ `.execute(db);
288
+ const count = Number(result.rows[0]?.count ?? 0);
289
+ if (count > 0) {
290
+ throw new Error(
291
+ `Cannot revert migration 040_byline_i18n: ` +
292
+ `${count} row(s) in "_emdash_content_bylines" reference a translation_group ` +
293
+ `with no row in "_emdash_bylines" at locale="${defaultLocale}". ` +
294
+ `Clean up the dangling credits before rolling back.`,
295
+ );
296
+ }
297
+ }
298
+
299
+ /**
300
+ * down() is destructive on multi-locale installs (dropping `locale` collapses
301
+ * translated rows onto an ambiguous unique key). Refuse to run when any row
302
+ * sits at a locale other than the configured defaultLocale.
303
+ */
304
+ async function assertSingleLocale(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
305
+ const result = await sql<{ count: number | string }>`
306
+ SELECT COUNT(*) AS count FROM _emdash_bylines WHERE locale != ${defaultLocale}
307
+ `.execute(db);
308
+ const count = Number(result.rows[0]?.count ?? 0);
309
+ if (count > 0) {
310
+ throw new Error(
311
+ `Cannot revert migration 040_byline_i18n: ` +
312
+ `${count} row(s) in "_emdash_bylines" use a non-default locale ` +
313
+ `(defaultLocale="${defaultLocale}"). ` +
314
+ `Reverting would drop them silently. Export translations first ` +
315
+ `(or delete them) and re-run the rollback. ` +
316
+ `See packages/core/src/database/migrations/040_byline_i18n.ts.`,
317
+ );
318
+ }
319
+ }
320
+
321
+ export async function down(db: Kysely<unknown>): Promise<void> {
322
+ const defaultLocale = getDefaultLocale();
323
+ await assertSingleLocale(db, defaultLocale);
324
+ await assertContentBylinesResolve(db, defaultLocale);
325
+
326
+ if (isSqlite(db)) {
327
+ // Indexes first to avoid blocking the table rebuilds.
328
+ await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_locale`).execute(db);
329
+ await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_translation_group`).execute(db);
330
+ await sql.raw(`DROP INDEX IF EXISTS idx_bylines_user_id_locale_unique`).execute(db);
331
+ await sql.raw(`DROP INDEX IF EXISTS idx_bylines_group_locale_unique`).execute(db);
332
+
333
+ // Remap `_emdash_content_bylines.byline_id` and `ec_*.primary_byline_id`
334
+ // from translation_group back to the row id of the defaultLocale
335
+ // anchor. assertSingleLocale guarantees the mapping is 1:1, so the
336
+ // rebuilt FK can validate every reference.
337
+ await remapPrimaryBylineIdsDown(db, defaultLocale);
338
+ await remapContentBylinesDown(db, defaultLocale);
339
+
340
+ // Now safe to rebuild `_emdash_bylines` (strips locale +
341
+ // translation_group, restores UNIQUE(slug) and the partial unique
342
+ // on user_id alone).
343
+ await rebuildBylinesDown(db);
344
+ // And finally restore the FK on `_emdash_content_bylines.byline_id`.
345
+ await restoreContentBylinesFk(db);
346
+ return;
347
+ }
348
+
349
+ await remapPrimaryBylineIdsDown(db, defaultLocale);
350
+ await sql`
351
+ UPDATE _emdash_content_bylines
352
+ SET byline_id = COALESCE(
353
+ (SELECT b.id FROM _emdash_bylines b
354
+ WHERE b.translation_group = _emdash_content_bylines.byline_id
355
+ AND b.locale = ${defaultLocale}),
356
+ byline_id
357
+ )
358
+ `.execute(db);
359
+
360
+ await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_locale`).execute(db);
361
+ await sql.raw(`DROP INDEX IF EXISTS idx__emdash_bylines_translation_group`).execute(db);
362
+ await sql.raw(`DROP INDEX IF EXISTS idx_bylines_user_id_locale_unique`).execute(db);
363
+ await sql.raw(`DROP INDEX IF EXISTS idx_bylines_group_locale_unique`).execute(db);
364
+ await sql
365
+ .raw(
366
+ `ALTER TABLE "_emdash_bylines" DROP CONSTRAINT IF EXISTS _emdash_bylines_slug_locale_unique`,
367
+ )
368
+ .execute(db);
369
+ await sql.raw(`ALTER TABLE "_emdash_bylines" DROP COLUMN IF EXISTS locale`).execute(db);
370
+ await sql
371
+ .raw(`ALTER TABLE "_emdash_bylines" DROP COLUMN IF EXISTS translation_group`)
372
+ .execute(db);
373
+ await sql
374
+ .raw(`ALTER TABLE "_emdash_bylines" ADD CONSTRAINT _emdash_bylines_slug_unique UNIQUE (slug)`)
375
+ .execute(db);
376
+ await sql`
377
+ CREATE UNIQUE INDEX IF NOT EXISTS ${sql.ref("idx_bylines_user_id_unique")}
378
+ ON _emdash_bylines (user_id) WHERE user_id IS NOT NULL
379
+ `.execute(db);
380
+ await sql`
381
+ ALTER TABLE _emdash_content_bylines
382
+ ADD CONSTRAINT _emdash_content_bylines_byline_fk
383
+ FOREIGN KEY (byline_id) REFERENCES _emdash_bylines(id) ON DELETE CASCADE
384
+ `.execute(db);
385
+ }
386
+
387
+ async function remapPrimaryBylineIdsDown(
388
+ db: Kysely<unknown>,
389
+ defaultLocale: string,
390
+ ): Promise<void> {
391
+ const collections = await listTablesLike(db, "ec_%");
392
+ for (const table of collections) {
393
+ validateIdentifier(table, "content table");
394
+ await sql`
395
+ UPDATE ${sql.ref(table)}
396
+ SET primary_byline_id = COALESCE(
397
+ (SELECT b.id FROM _emdash_bylines b
398
+ WHERE b.translation_group = ${sql.ref(table)}.primary_byline_id
399
+ AND b.locale = ${defaultLocale}),
400
+ primary_byline_id
401
+ )
402
+ WHERE primary_byline_id IS NOT NULL
403
+ `.execute(db);
404
+ }
405
+ }
406
+
407
+ async function remapContentBylinesDown(db: Kysely<unknown>, defaultLocale: string): Promise<void> {
408
+ await sql`
409
+ UPDATE _emdash_content_bylines
410
+ SET byline_id = COALESCE(
411
+ (SELECT b.id FROM _emdash_bylines b
412
+ WHERE b.translation_group = _emdash_content_bylines.byline_id
413
+ AND b.locale = ${defaultLocale}),
414
+ byline_id
415
+ )
416
+ `.execute(db);
417
+ }
418
+
419
+ async function rebuildBylinesDown(db: Kysely<unknown>): Promise<void> {
420
+ await sql.raw(`DROP TABLE IF EXISTS "_emdash_bylines_old"`).execute(db);
421
+ await db.schema
422
+ .createTable("_emdash_bylines_old")
423
+ .addColumn("id", "text", (c) => c.primaryKey())
424
+ .addColumn("slug", "text", (c) => c.notNull().unique())
425
+ .addColumn("display_name", "text", (c) => c.notNull())
426
+ .addColumn("bio", "text")
427
+ .addColumn("avatar_media_id", "text", (c) => c.references("media.id").onDelete("set null"))
428
+ .addColumn("website_url", "text")
429
+ .addColumn("user_id", "text", (c) => c.references("users.id").onDelete("set null"))
430
+ .addColumn("is_guest", "integer", (c) => c.notNull().defaultTo(0))
431
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
432
+ .addColumn("updated_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
433
+ .execute();
434
+ await sql`
435
+ INSERT INTO _emdash_bylines_old (
436
+ id, slug, display_name, bio, avatar_media_id, website_url,
437
+ user_id, is_guest, created_at, updated_at
438
+ )
439
+ SELECT
440
+ id, slug, display_name, bio, avatar_media_id, website_url,
441
+ user_id, is_guest, created_at, updated_at
442
+ FROM _emdash_bylines
443
+ `.execute(db);
444
+ await db.schema.dropTable("_emdash_bylines").execute();
445
+ await sql`ALTER TABLE _emdash_bylines_old RENAME TO _emdash_bylines`.execute(db);
446
+
447
+ // Restore the indexes that existed pre-040.
448
+ await db.schema.createIndex("idx_bylines_slug").on("_emdash_bylines").column("slug").execute();
449
+ await db.schema
450
+ .createIndex("idx_bylines_display_name")
451
+ .on("_emdash_bylines")
452
+ .column("display_name")
453
+ .execute();
454
+ await sql`
455
+ CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_unique")}
456
+ ON ${sql.ref("_emdash_bylines")} (user_id)
457
+ WHERE user_id IS NOT NULL
458
+ `.execute(db);
459
+ }
460
+
461
+ async function restoreContentBylinesFk(db: Kysely<unknown>): Promise<void> {
462
+ await sql.raw(`DROP TABLE IF EXISTS "_emdash_content_bylines_old"`).execute(db);
463
+ await db.schema
464
+ .createTable("_emdash_content_bylines_old")
465
+ .addColumn("id", "text", (c) => c.primaryKey())
466
+ .addColumn("collection_slug", "text", (c) => c.notNull())
467
+ .addColumn("content_id", "text", (c) => c.notNull())
468
+ .addColumn("byline_id", "text", (c) =>
469
+ c.notNull().references("_emdash_bylines.id").onDelete("cascade"),
470
+ )
471
+ .addColumn("sort_order", "integer", (c) => c.notNull().defaultTo(0))
472
+ .addColumn("role_label", "text")
473
+ .addColumn("created_at", "text", (c) => c.defaultTo(currentTimestamp(db)))
474
+ .addUniqueConstraint("content_bylines_unique", ["collection_slug", "content_id", "byline_id"])
475
+ .execute();
476
+
477
+ await sql`
478
+ INSERT INTO _emdash_content_bylines_old
479
+ (id, collection_slug, content_id, byline_id, sort_order, role_label, created_at)
480
+ SELECT id, collection_slug, content_id, byline_id, sort_order, role_label, created_at
481
+ FROM _emdash_content_bylines
482
+ `.execute(db);
483
+
484
+ await db.schema.dropTable("_emdash_content_bylines").execute();
485
+ await sql`ALTER TABLE _emdash_content_bylines_old RENAME TO _emdash_content_bylines`.execute(db);
486
+
487
+ await db.schema
488
+ .createIndex("idx_content_bylines_content")
489
+ .on("_emdash_content_bylines")
490
+ .columns(["collection_slug", "content_id", "sort_order"])
491
+ .execute();
492
+ await db.schema
493
+ .createIndex("idx_content_bylines_byline")
494
+ .on("_emdash_content_bylines")
495
+ .column("byline_id")
496
+ .execute();
497
+ }
@@ -1,4 +1,5 @@
1
- import { type Kysely, type Migration, type MigrationProvider, Migrator, sql } from "kysely";
1
+ import { type Kysely, sql } from "kysely";
2
+ import { type Migration, type MigrationProvider, Migrator } from "kysely/migration";
2
3
 
3
4
  import type { Database } from "../types.js";
4
5
  // Import migrations statically for bundling
@@ -40,6 +41,7 @@ import * as m036 from "./036_i18n_menus_and_taxonomies.js";
40
41
  import * as m037 from "./037_credential_algorithm.js";
41
42
  import * as m038 from "./038_registry_plugin_state.js";
42
43
  import * as m039 from "./039_fix_fts5_triggers.js";
44
+ import * as m040 from "./040_byline_i18n.js";
43
45
 
44
46
  const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
45
47
  "001_initial": m001,
@@ -80,6 +82,7 @@ const MIGRATIONS: Readonly<Record<string, Migration>> = Object.freeze({
80
82
  "037_credential_algorithm": m037,
81
83
  "038_registry_plugin_state": m038,
82
84
  "039_fix_fts5_triggers": m039,
85
+ "040_byline_i18n": m040,
83
86
  });
84
87
 
85
88
  /** Total number of registered migrations. Exported for use in tests. */
@@ -280,12 +280,12 @@ export class AuditRepository {
280
280
  timestamp: row.timestamp,
281
281
  actorId: row.actor_id,
282
282
  actorIp: row.actor_ip,
283
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- DB stores string; validated at insert but linter can't follow
283
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow
284
284
  action: row.action as AuditAction,
285
285
  resourceType: row.resource_type,
286
286
  resourceId: row.resource_id,
287
287
  details: row.details ? JSON.parse(row.details) : null,
288
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- DB stores string; validated at insert but linter can't follow
288
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- DB stores string; validated at insert but linter can't follow
289
289
  status: row.status as AuditStatus | null,
290
290
  };
291
291
  }