emdash 0.14.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-BMLZuwM4.mjs → api-CLwG_3dh.mjs} +519 -55
  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-BdUP8NuI.d.mts → bylines-DtDRNF1n.d.mts} +59 -14
  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-BV8iJ-6s.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-DNmQakZO.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 +11 -9
  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 +553 -4
  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-BMLZuwM4.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-BdUP8NuI.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-BV8iJ-6s.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-DNmQakZO.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
@@ -34,7 +34,7 @@ export const GET: APIRoute = async ({ params, url, locals }) => {
34
34
  const query = parseQuery(url, collectionGetQuery);
35
35
  if (isParseError(query)) return query;
36
36
 
37
- const result = await handleSchemaCollectionGet(emdash!.db, slug, {
37
+ const result = await handleSchemaCollectionGet(emdash.db, slug, {
38
38
  includeFields: query.includeFields ?? false,
39
39
  });
40
40
  return unwrapResult(result);
@@ -54,12 +54,12 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
54
54
  if (isParseError(body)) return body;
55
55
 
56
56
  const result = await handleSchemaCollectionUpdate(
57
- emdash!.db,
57
+ emdash.db,
58
58
  slug,
59
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- parseBody validates via Zod
59
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- parseBody validates via Zod
60
60
  body as UpdateCollectionInput,
61
61
  );
62
- emdash!.invalidateUrlPatternCache();
62
+ emdash.invalidateUrlPatternCache();
63
63
  return unwrapResult(result);
64
64
  };
65
65
 
@@ -74,9 +74,9 @@ export const DELETE: APIRoute = async ({ params, url, locals }) => {
74
74
  const denied = requirePerm(user, "schema:manage");
75
75
  if (denied) return denied;
76
76
 
77
- const result = await handleSchemaCollectionDelete(emdash!.db, slug, {
77
+ const result = await handleSchemaCollectionDelete(emdash.db, slug, {
78
78
  force,
79
79
  });
80
- emdash!.invalidateUrlPatternCache();
80
+ emdash.invalidateUrlPatternCache();
81
81
  return unwrapResult(result);
82
82
  };
@@ -25,7 +25,7 @@ export const GET: APIRoute = async ({ locals }) => {
25
25
  const denied = requirePerm(user, "schema:read");
26
26
  if (denied) return denied;
27
27
 
28
- const result = await handleSchemaCollectionList(emdash!.db);
28
+ const result = await handleSchemaCollectionList(emdash.db);
29
29
  return unwrapResult(result);
30
30
  };
31
31
 
@@ -41,8 +41,8 @@ export const POST: APIRoute = async ({ request, locals }) => {
41
41
  const body = await parseBody(request, createCollectionBody);
42
42
  if (isParseError(body)) return body;
43
43
 
44
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to CreateCollectionInput
45
- const result = await handleSchemaCollectionCreate(emdash!.db, body as CreateCollectionInput);
46
- emdash!.invalidateUrlPatternCache();
44
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Zod schema output narrowed to CreateCollectionInput
45
+ const result = await handleSchemaCollectionCreate(emdash.db, body as CreateCollectionInput);
46
+ emdash.invalidateUrlPatternCache();
47
47
  return unwrapResult(result, 201);
48
48
  };
@@ -29,7 +29,7 @@ export const GET: APIRoute = async ({ request, locals }) => {
29
29
  if (denied) return denied;
30
30
 
31
31
  try {
32
- const registry = new SchemaRegistry(emdash!.db);
32
+ const registry = new SchemaRegistry(emdash.db);
33
33
 
34
34
  // Get all collections with their fields
35
35
  const collections = await registry.listCollections();
@@ -31,6 +31,6 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
31
31
  const options = await parseOptionalBody(request, orphanRegisterBody, {});
32
32
  if (isParseError(options)) return options;
33
33
 
34
- const result = await handleOrphanedTableRegister(emdash!.db, slug, options);
34
+ const result = await handleOrphanedTableRegister(emdash.db, slug, options);
35
35
  return unwrapResult(result, 201);
36
36
  };
@@ -21,6 +21,6 @@ export const GET: APIRoute = async ({ locals }) => {
21
21
  const denied = requirePerm(user, "schema:manage");
22
22
  if (denied) return denied;
23
23
 
24
- const result = await handleOrphanedTableList(emdash!.db);
24
+ const result = await handleOrphanedTableList(emdash.db);
25
25
  return unwrapResult(result);
26
26
  };
@@ -24,7 +24,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
24
24
  const { emdash, user } = locals;
25
25
  const dbErr = requireDb(emdash?.db);
26
26
  if (dbErr) return dbErr;
27
- const db = emdash!.db;
27
+ const db = emdash.db;
28
28
  const { slug } = params;
29
29
 
30
30
  const denied = requirePerm(user, "sections:read");
@@ -46,7 +46,7 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
46
46
  const { emdash, user } = locals;
47
47
  const dbErr = requireDb(emdash?.db);
48
48
  if (dbErr) return dbErr;
49
- const db = emdash!.db;
49
+ const db = emdash.db;
50
50
  const { slug } = params;
51
51
 
52
52
  const denied = requirePerm(user, "sections:manage");
@@ -71,7 +71,7 @@ export const DELETE: APIRoute = async ({ params, locals }) => {
71
71
  const { emdash, user } = locals;
72
72
  const dbErr = requireDb(emdash?.db);
73
73
  if (dbErr) return dbErr;
74
- const db = emdash!.db;
74
+ const db = emdash.db;
75
75
  const { slug } = params;
76
76
 
77
77
  const denied = requirePerm(user, "sections:manage");
@@ -19,7 +19,7 @@ export const GET: APIRoute = async ({ url, locals }) => {
19
19
  const { emdash, user } = locals;
20
20
  const dbErr = requireDb(emdash?.db);
21
21
  if (dbErr) return dbErr;
22
- const db = emdash!.db;
22
+ const db = emdash.db;
23
23
 
24
24
  const denied = requirePerm(user, "sections:read");
25
25
  if (denied) return denied;
@@ -39,7 +39,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
39
39
  const { emdash, user } = locals;
40
40
  const dbErr = requireDb(emdash?.db);
41
41
  if (dbErr) return dbErr;
42
- const db = emdash!.db;
42
+ const db = emdash.db;
43
43
 
44
44
  const denied = requirePerm(user, "sections:manage");
45
45
  if (denied) return denied;
@@ -427,6 +427,10 @@ export interface EmDashHandlers {
427
427
  // Sandbox runner (for marketplace plugin install/update)
428
428
  getSandboxRunner: () => import("../plugins/sandbox/types.js").SandboxRunner | null;
429
429
 
430
+ // Whether sandbox bypass mode (sandbox: false) is active. Marketplace
431
+ // install/update routes use this to skip the SANDBOX_NOT_AVAILABLE gate.
432
+ isSandboxBypassed: () => boolean;
433
+
430
434
  // Sync marketplace plugin states (after install/update/uninstall)
431
435
  syncMarketplacePlugins: () => Promise<void>;
432
436
 
@@ -119,7 +119,7 @@ export function rateLimitResponse(retryAfterSeconds: number): Response {
119
119
  */
120
120
  export function getClientIp(request: Request, trustedHeaders: string[] = []): string | null {
121
121
  const headers = request.headers;
122
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- CF Workers runtime shape
122
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- CF Workers runtime shape
123
123
  const cf = (request as unknown as { cf?: Record<string, unknown> }).cf;
124
124
 
125
125
  // On Cloudflare, prefer the cryptographically trustworthy headers. An
@@ -56,7 +56,7 @@ function getEnvTrustedHeaders(): string[] {
56
56
  // value at runtime (Vite/Astro inline import.meta.env at build time,
57
57
  // which locks the value into the bundle). Fall back to import.meta.env
58
58
  // for bundler-managed environments where process.env isn't populated.
59
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- import.meta.env shape varies by bundler
59
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- import.meta.env shape varies by bundler
60
60
  const importMetaEnv = (import.meta as unknown as { env?: Record<string, string | undefined> })
61
61
  .env;
62
62
  raw =
@@ -4,6 +4,16 @@
4
4
  * Provides functions to query byline profiles and byline credits
5
5
  * associated with content entries. Follows the same pattern as
6
6
  * the taxonomies runtime API.
7
+ *
8
+ * i18n model (migration 040): byline rows are per-locale and share a
9
+ * `translation_group`. Credits on `_emdash_content_bylines.byline_id` store
10
+ * the translation_group, so a single credit spans every locale of a byline.
11
+ *
12
+ * Hydration is strict per locale: a credit at locale X renders iff a byline
13
+ * row exists at locale X within the credited translation_group. There is no
14
+ * read-time fallback. Mirrors `getEntryTerms` and the convention in PR #916.
15
+ * Locale is passed in by callers — `query.ts` resolves it from the entry's
16
+ * own `data.locale` for the runtime path.
7
17
  */
8
18
 
9
19
  import { sql } from "kysely";
@@ -11,7 +21,9 @@ import { sql } from "kysely";
11
21
  import { BylineRepository } from "../database/repositories/byline.js";
12
22
  import type { BylineSummary, ContentBylineCredit } from "../database/repositories/types.js";
13
23
  import { validateIdentifier } from "../database/validate.js";
24
+ import { resolveLocaleChain } from "../i18n/resolve.js";
14
25
  import { getDb } from "../loader.js";
26
+ import { requestCached } from "../request-cache.js";
15
27
  import { isMissingTableError } from "../utils/db-errors.js";
16
28
 
17
29
  /**
@@ -49,28 +61,60 @@ export async function getByline(id: string): Promise<BylineSummary | null> {
49
61
  /**
50
62
  * Get a byline by slug.
51
63
  *
64
+ * Standalone identity lookup (e.g. rendering an author profile page). Walks
65
+ * the configured locale fallback chain — same pattern as `getMenu` and
66
+ * `getTerm`, see PR #916. Returns the first match found, walking
67
+ * `[requestedLocale, ...fallbacks, defaultLocale]` in order.
68
+ *
69
+ * Note: this is intentionally different from credit hydration on a content
70
+ * entry (`getEntryBylines`), which is strict per locale with no fallback.
71
+ * The distinction: identity lookups answer "give me this byline", and
72
+ * falling back to another locale's display name is acceptable. Credit
73
+ * hydration answers "what should render on this entry", where falling back
74
+ * silently surfaces a stale-locale name and contradicts editorial intent.
75
+ *
52
76
  * @example
53
77
  * ```ts
54
78
  * import { getBylineBySlug } from "emdash";
55
79
  *
56
- * const byline = await getBylineBySlug("jane-doe");
80
+ * const byline = await getBylineBySlug("jane-doe", { locale: "de-de" });
57
81
  * if (byline) {
58
- * console.log(byline.displayName); // "Jane Doe"
82
+ * console.log(byline.displayName);
59
83
  * }
60
84
  * ```
61
85
  */
62
- export async function getBylineBySlug(slug: string): Promise<BylineSummary | null> {
63
- const db = await getDb();
64
- const repo = new BylineRepository(db);
65
- return repo.findBySlug(slug);
86
+ export async function getBylineBySlug(
87
+ slug: string,
88
+ options?: { locale?: string },
89
+ ): Promise<BylineSummary | null> {
90
+ const chain = resolveLocaleChain(options?.locale);
91
+ const cacheKey = `byline-by-slug:${slug}:${chain.length > 0 ? chain.join(",") : "*"}`;
92
+ return requestCached(cacheKey, async () => {
93
+ const db = await getDb();
94
+ const repo = new BylineRepository(db);
95
+
96
+ if (chain.length === 0) {
97
+ // No i18n or no resolved locale — fall back to the repo's
98
+ // "lowest-locale-code" deterministic match.
99
+ return repo.findBySlug(slug);
100
+ }
101
+
102
+ for (const locale of chain) {
103
+ const row = await repo.findBySlug(slug, { locale });
104
+ if (row) return row;
105
+ }
106
+ return null;
107
+ });
66
108
  }
67
109
 
68
110
  /**
69
111
  * Get byline credits for a single content entry.
70
112
  *
71
- * Returns explicit byline credits from the junction table. If none exist
72
- * but the entry has an `authorId`, falls back to the user-linked byline
73
- * (marked as source: "inferred").
113
+ * Strict per locale (post-migration 040): a credit renders iff a byline row
114
+ * exists at the requested locale within the credited translation_group.
115
+ * Callers wanting fallback behaviour apply it themselves. When `locale` is
116
+ * omitted, returns every locale variant of every credit on the entry —
117
+ * useful for admin tooling, not for end-user rendering.
74
118
  *
75
119
  * Internal: not re-exported from the `emdash` package entry point. Every
76
120
  * entry returned by `getEmDashCollection` / `getEmDashEntry` already has
@@ -81,20 +125,26 @@ export async function getBylineBySlug(slug: string): Promise<BylineSummary | nul
81
125
  export async function getEntryBylines(
82
126
  collection: string,
83
127
  entryId: string,
128
+ options?: { locale?: string },
84
129
  ): Promise<ContentBylineCredit[]> {
85
130
  validateIdentifier(collection, "collection");
86
131
  const db = await getDb();
87
132
  const repo = new BylineRepository(db);
88
133
 
89
- const explicit = await repo.getContentBylines(collection, entryId);
134
+ const localeOpt = options?.locale !== undefined ? { locale: options.locale } : undefined;
135
+ const explicit = await repo.getContentBylines(collection, entryId, localeOpt);
90
136
  if (explicit.length > 0) {
91
137
  return explicit.map((c) => ({ ...c, source: "explicit" as const }));
92
138
  }
93
139
 
94
- // Fallback: look up user-linked byline from author_id
95
- const authorId = await getAuthorId(db, collection, entryId);
96
- if (authorId) {
97
- const fallback = await repo.findByUserId(authorId);
140
+ // `primary_byline_id` is the explicit-credit sentinel: non-null
141
+ // suppresses author fallback even when the credit doesn't resolve
142
+ // at this locale.
143
+ const ctx = await getEntryContext(db, collection, entryId);
144
+ if (ctx.primaryBylineId) return [];
145
+
146
+ if (ctx.authorId) {
147
+ const fallback = await repo.findByUserId(ctx.authorId, localeOpt);
98
148
  if (fallback) {
99
149
  return [{ byline: fallback, sortOrder: 0, roleLabel: null, source: "inferred" }];
100
150
  }
@@ -104,19 +154,27 @@ export async function getEntryBylines(
104
154
  }
105
155
 
106
156
  /**
107
- * An entry reference for batch byline lookups.
157
+ * Entry reference for batch byline lookups. Passing `authorId`,
158
+ * `primaryBylineId`, and `locale` in directly avoids a per-entry
159
+ * `SELECT` against the content table during hydration.
108
160
  *
109
- * `authorId` is read directly from the row when computing the inferred-byline
110
- * fallback passing it in avoids a redundant `SELECT id, author_id` against
111
- * the content table after every list/entry fetch.
161
+ * `primaryBylineId` is the explicit-credit sentinel non-null suppresses
162
+ * author fallback. `locale` drives the strict per-locale join.
112
163
  */
113
164
  export interface BylineEntry {
114
165
  id: string;
115
166
  authorId: string | null;
167
+ primaryBylineId?: string | null;
168
+ locale?: string | null;
116
169
  }
117
170
 
118
171
  /**
119
- * Batch-fetch byline credits for multiple content entries in a single query.
172
+ * Batch-fetch byline credits for multiple content entries.
173
+ *
174
+ * Per-entry strict-locale hydration: entries are bucketed by `entry.locale`
175
+ * and each bucket gets a single batched call to the strict-locale repo
176
+ * method. Items with no `locale` field (legacy / single-locale installs)
177
+ * share an unscoped bucket.
120
178
  *
121
179
  * Internal: consumed by `hydrateEntryBylines` in `query.ts` so that every
122
180
  * entry returned from `getEmDashCollection` / `getEmDashEntry` already has
@@ -125,7 +183,7 @@ export interface BylineEntry {
125
183
  * from the `emdash` package entry point.
126
184
  *
127
185
  * @param collection - The collection slug (e.g., "posts")
128
- * @param entries - Entry id + authorId pairs (authorId is already on the row)
186
+ * @param entries - Entry id + authorId + locale (each entry resolves at its own locale)
129
187
  * @returns Map from entry ID to array of byline credits
130
188
  */
131
189
  export async function getBylinesForEntries(
@@ -145,33 +203,73 @@ export async function getBylinesForEntries(
145
203
 
146
204
  const db = await getDb();
147
205
  const repo = new BylineRepository(db);
148
- const entryIds = entries.map((e) => e.id);
149
-
150
- // Sites with no bylines get an empty map back for one query — the previous
151
- // "has any bylines" probe traded an extra round-trip on every request to
152
- // save that one query on empty sites, which is exactly backwards for the
153
- // common case. Pre-migration databases (bylines table missing) fall
154
- // through to the `isMissingTableError` catch below and return empty.
155
- let bylinesMap;
156
- try {
157
- bylinesMap = await repo.getContentBylinesMany(collection, entryIds);
158
- } catch (error) {
159
- if (isMissingTableError(error)) return result;
160
- throw error;
206
+
207
+ // Bucket entries by locale so each bucket fires a single strict-locale
208
+ // `getContentBylinesMany` call. Items with no locale field share a
209
+ // bucket keyed by null (no `WHERE locale = ?` applied legacy
210
+ // pre-i18n shape).
211
+ const buckets = new Map<string | null, BylineEntry[]>();
212
+ for (const entry of entries) {
213
+ const key = entry.locale ?? null;
214
+ const bucket = buckets.get(key);
215
+ if (bucket) bucket.push(entry);
216
+ else buckets.set(key, [entry]);
161
217
  }
162
218
 
163
- const needsFallback = new Map<string, string>();
164
- for (const { id, authorId } of entries) {
165
- if (!bylinesMap.has(id) && authorId) {
166
- needsFallback.set(id, authorId);
219
+ // Sites with no bylines get an empty map back at the same cost as the
220
+ // previous "has any bylines" probe, without the extra round-trip.
221
+ // Pre-migration databases (bylines table missing) fall through to the
222
+ // `isMissingTableError` catch below and return empty.
223
+ const explicitByEntry = new Map<string, ContentBylineCredit[]>();
224
+ const entriesNeedingAuthorCheck: BylineEntry[] = [];
225
+ for (const [locale, bucket] of buckets) {
226
+ const localeOpt = locale ? { locale } : undefined;
227
+ const bucketIds = bucket.map((e) => e.id);
228
+ let bylinesMap;
229
+ try {
230
+ bylinesMap = await repo.getContentBylinesMany(collection, bucketIds, localeOpt);
231
+ } catch (error) {
232
+ if (isMissingTableError(error)) return result;
233
+ throw error;
234
+ }
235
+ for (const [id, list] of bylinesMap) explicitByEntry.set(id, list);
236
+
237
+ for (const entry of bucket) {
238
+ const hasResolved = bylinesMap.has(entry.id) && bylinesMap.get(entry.id)!.length > 0;
239
+ if (hasResolved) continue;
240
+ if (entry.authorId) entriesNeedingAuthorCheck.push(entry);
167
241
  }
168
242
  }
169
243
 
170
- const uniqueAuthorIds = [...new Set(needsFallback.values())];
171
- const authorBylineMap = await repo.findByUserIds(uniqueAuthorIds);
244
+ // Only entries without an explicit credit (primaryBylineId null) are
245
+ // eligible for author fallback.
246
+ const fallbackByEntry = new Map<string, BylineSummary>();
247
+ if (entriesNeedingAuthorCheck.length > 0) {
248
+ const authorBuckets = new Map<string | null, BylineEntry[]>();
249
+ for (const entry of entriesNeedingAuthorCheck) {
250
+ if (entry.primaryBylineId) continue;
251
+ const key = entry.locale ?? null;
252
+ const bucket = authorBuckets.get(key);
253
+ if (bucket) bucket.push(entry);
254
+ else authorBuckets.set(key, [entry]);
255
+ }
256
+
257
+ for (const [locale, bucket] of authorBuckets) {
258
+ const localeOpt = locale ? { locale } : undefined;
259
+ const authorIds = bucket.map((e) => e.authorId).filter((id): id is string => id !== null);
260
+ const uniqueAuthorIds = [...new Set(authorIds)];
261
+ if (uniqueAuthorIds.length === 0) continue;
262
+ const authorBylineMap = await repo.findByUserIds(uniqueAuthorIds, localeOpt);
263
+ for (const entry of bucket) {
264
+ if (!entry.authorId) continue;
265
+ const f = authorBylineMap.get(entry.authorId);
266
+ if (f) fallbackByEntry.set(entry.id, f);
267
+ }
268
+ }
269
+ }
172
270
 
173
271
  for (const { id } of entries) {
174
- const explicit = bylinesMap.get(id);
272
+ const explicit = explicitByEntry.get(id);
175
273
  if (explicit && explicit.length > 0) {
176
274
  result.set(
177
275
  id,
@@ -180,35 +278,36 @@ export async function getBylinesForEntries(
180
278
  continue;
181
279
  }
182
280
 
183
- const authorId = needsFallback.get(id);
184
- if (authorId) {
185
- const fallback = authorBylineMap.get(authorId);
186
- if (fallback) {
187
- result.set(id, [{ byline: fallback, sortOrder: 0, roleLabel: null, source: "inferred" }]);
188
- }
281
+ const fallback = fallbackByEntry.get(id);
282
+ if (fallback) {
283
+ result.set(id, [{ byline: fallback, sortOrder: 0, roleLabel: null, source: "inferred" }]);
189
284
  }
190
285
  }
191
286
 
192
287
  return result;
193
288
  }
194
289
 
195
- /**
196
- * Look up the author_id for a single content entry.
197
- * Uses raw SQL since we need dynamic table names.
198
- */
199
- async function getAuthorId(
290
+ /** Reads `author_id` + `primary_byline_id` for one entry in a single query. */
291
+ async function getEntryContext(
200
292
  db: Awaited<ReturnType<typeof getDb>>,
201
293
  collection: string,
202
294
  entryId: string,
203
- ): Promise<string | null> {
295
+ ): Promise<{ authorId: string | null; primaryBylineId: string | null }> {
204
296
  validateIdentifier(collection, "collection");
205
297
  const tableName = `ec_${collection}`;
206
298
 
207
- const result = await sql<{ author_id: string | null }>`
208
- SELECT author_id FROM ${sql.ref(tableName)}
299
+ const result = await sql<{
300
+ author_id: string | null;
301
+ primary_byline_id: string | null;
302
+ }>`
303
+ SELECT author_id, primary_byline_id FROM ${sql.ref(tableName)}
209
304
  WHERE id = ${entryId}
210
305
  LIMIT 1
211
306
  `.execute(db);
212
307
 
213
- return result.rows[0]?.author_id ?? null;
308
+ const row = result.rows[0];
309
+ return {
310
+ authorId: row?.author_id ?? null,
311
+ primaryBylineId: row?.primary_byline_id ?? null,
312
+ };
214
313
  }
@@ -9,6 +9,7 @@ import { resolve } from "node:path";
9
9
 
10
10
  import { defineCommand } from "citty";
11
11
  import consola from "consola";
12
+ import { sql } from "kysely";
12
13
 
13
14
  import { createDatabase } from "../../database/connection.js";
14
15
  import { runMigrations } from "../../database/migrations/runner.js";
@@ -44,10 +45,10 @@ async function readPackageJson(cwd: string): Promise<PackageJson | null> {
44
45
  }
45
46
 
46
47
  async function runSqlFile(db: ReturnType<typeof createDatabase>, filePath: string): Promise<void> {
47
- const sql = await readFile(filePath, "utf-8");
48
+ const contents = await readFile(filePath, "utf-8");
48
49
 
49
50
  // Remove single-line comments
50
- const withoutComments = sql
51
+ const withoutComments = contents
51
52
  .split("\n")
52
53
  .filter((line) => !line.trim().startsWith("--"))
53
54
  .join("\n");
@@ -59,11 +60,7 @@ async function runSqlFile(db: ReturnType<typeof createDatabase>, filePath: strin
59
60
  .filter((s) => s.length > 0);
60
61
 
61
62
  for (const statement of statements) {
62
- await db.executeQuery({
63
- sql: statement,
64
- parameters: [],
65
- query: { kind: "RawNode", sqlFragments: [statement], parameters: [] },
66
- });
63
+ await db.executeQuery(sql.raw(statement).compile(db));
67
64
  }
68
65
  }
69
66
 
@@ -73,7 +70,6 @@ async function runSqlFile(db: ReturnType<typeof createDatabase>, filePath: strin
73
70
  async function isAlreadyInitialized(db: ReturnType<typeof createDatabase>): Promise<boolean> {
74
71
  try {
75
72
  // Use raw SQL since this runs on an untyped database connection
76
- const { sql } = await import("kysely");
77
73
  const result = await sql<{
78
74
  count: number;
79
75
  }>`SELECT COUNT(id) as count FROM _emdash_collections`.execute(db);
@@ -19,7 +19,7 @@
19
19
 
20
20
  import mime from "mime/lite";
21
21
 
22
- import type { PortableTextBlock, FieldSchema } from "./portable-text.js";
22
+ import type { FieldSchema } from "./portable-text.js";
23
23
  import { convertDataForRead, convertDataForWrite } from "./portable-text.js";
24
24
  import type { Interceptor } from "./transport.js";
25
25
  import {
@@ -26,6 +26,7 @@ import * as React from "react";
26
26
  import { createPortal } from "react-dom";
27
27
 
28
28
  import { computeThumbnailSize } from "../media/thumbnail.js";
29
+ import { InlineCodeBlockExtension } from "./inline-code-block.js";
29
30
 
30
31
  // ── Portable Text types ────────────────────────────────────────────
31
32
 
@@ -1137,7 +1138,7 @@ function InlineMediaPicker({
1137
1138
  const r = await ecFetch(url);
1138
1139
  const d = await r.json();
1139
1140
  const raw = d.data.items ?? [];
1140
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- API response items mapped to MediaItem shape
1141
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- API response items mapped to MediaItem shape
1141
1142
  const typedRaw = raw as Array<{
1142
1143
  id: string;
1143
1144
  filename?: string;
@@ -1765,7 +1766,10 @@ export function InlinePortableTextEditor({
1765
1766
  StarterKit.configure({
1766
1767
  heading: { levels: [1, 2, 3] },
1767
1768
  dropcursor: { color: "#3b82f6", width: 2 },
1769
+ // Replaced with InlineCodeBlockExtension below (adds language picker).
1770
+ codeBlock: false,
1768
1771
  }),
1772
+ InlineCodeBlockExtension,
1769
1773
  Image.extend({
1770
1774
  addAttributes() {
1771
1775
  return {