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
@@ -17,6 +17,14 @@ export const bylineSummarySchema = z
17
17
  isGuest: z.boolean(),
18
18
  createdAt: z.string(),
19
19
  updatedAt: z.string(),
20
+ /** Locale this byline row is presented in (migration 040). */
21
+ locale: z.string(),
22
+ /**
23
+ * Shared across translations of the same byline (migration 040).
24
+ * Equals `id` for the anchor row; siblings inherit it from their
25
+ * source. Nullable in storage for backwards compatibility.
26
+ */
27
+ translationGroup: z.string().nullable(),
20
28
  })
21
29
  .meta({ id: "BylineSummary" });
22
30
 
@@ -43,6 +51,12 @@ export const bylinesListQuery = cursorPaginationQuery
43
51
  search: z.string().optional(),
44
52
  isGuest: z.coerce.boolean().optional(),
45
53
  userId: z.string().optional(),
54
+ /**
55
+ * Filter by locale (strict per-locale matching, post-migration 040).
56
+ * Rejects empty strings so the picker can't silently fetch the
57
+ * unfiltered list when the admin URL has `?locale=` with no value.
58
+ */
59
+ locale: z.string().min(1).optional(),
46
60
  })
47
61
  .meta({ id: "BylinesListQuery" });
48
62
 
@@ -58,9 +72,41 @@ export const bylineCreateBody = z
58
72
  websiteUrl: httpUrl.nullish(),
59
73
  userId: z.string().nullish(),
60
74
  isGuest: z.boolean().optional(),
75
+ /**
76
+ * Locale this byline row belongs to. When omitted, the DB DEFAULT (the
77
+ * configured `defaultLocale`) is used. Rejects empty strings — an
78
+ * empty locale would create rows no resolver requests.
79
+ */
80
+ locale: z.string().min(1).optional(),
81
+ /**
82
+ * When set, the new row joins the source byline's translation_group
83
+ * rather than minting a fresh one. Requires `locale`.
84
+ */
85
+ translationOf: z.string().min(1).optional(),
61
86
  })
62
87
  .meta({ id: "BylineCreateBody" });
63
88
 
89
+ export const bylineTranslationCreateBody = z
90
+ .object({
91
+ locale: z.string().min(1),
92
+ slug: z
93
+ .string()
94
+ .min(1)
95
+ .regex(bylineSlugPattern, "Slug must contain only lowercase letters, digits, and hyphens")
96
+ .optional(),
97
+ displayName: z.string().min(1).optional(),
98
+ bio: z.string().nullish(),
99
+ avatarMediaId: z.string().nullish(),
100
+ websiteUrl: httpUrl.nullish(),
101
+ })
102
+ .meta({ id: "BylineTranslationCreateBody" });
103
+
104
+ export const bylineTranslationsResponseSchema = z
105
+ .object({
106
+ items: z.array(bylineSummarySchema),
107
+ })
108
+ .meta({ id: "BylineTranslationsResponse" });
109
+
64
110
  export const bylineUpdateBody = z
65
111
  .object({
66
112
  slug: z
@@ -22,7 +22,7 @@ import {
22
22
  injectAuthProviderRoutes,
23
23
  injectMcpRoute,
24
24
  } from "./routes.js";
25
- import type { EmDashConfig, PluginDescriptor } from "./runtime.js";
25
+ import type { EmDashConfig } from "./runtime.js";
26
26
  import { createViteConfig } from "./vite-config.js";
27
27
 
28
28
  // Re-export runtime types and functions
@@ -447,6 +447,11 @@ export function injectCoreRoutes(injectRoute: InjectRoute): void {
447
447
  entrypoint: resolveRoute("api/admin/bylines/[id]/index.ts"),
448
448
  });
449
449
 
450
+ injectRoute({
451
+ pattern: "/_emdash/api/admin/bylines/[id]/translations",
452
+ entrypoint: resolveRoute("api/admin/bylines/[id]/translations.ts"),
453
+ });
454
+
450
455
  injectRoute({
451
456
  pattern: "/_emdash/api/admin/users/[id]",
452
457
  entrypoint: resolveRoute("api/admin/users/[id]/index.ts"),
@@ -199,6 +199,17 @@ export interface EmDashConfig {
199
199
  */
200
200
  sandboxRunner?: string;
201
201
 
202
+ /**
203
+ * Explicitly disable plugin sandboxing, even if a sandbox runner is configured.
204
+ * Use this as a debugging escape hatch to determine whether a bug is in your
205
+ * plugin code or in the sandbox runtime.
206
+ *
207
+ * When set to `false`, all plugins run in-process without isolation.
208
+ *
209
+ * @default true (sandboxing enabled if sandboxRunner is configured)
210
+ */
211
+ sandbox?: boolean;
212
+
202
213
  /**
203
214
  * Authentication configuration
204
215
  *
@@ -526,7 +537,7 @@ const configHolder = globalThis as Record<symbol, unknown>;
526
537
  * This is set by the virtual module at build time
527
538
  */
528
539
  export function getStoredConfig(): EmDashConfig | null {
529
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- globalThis singleton pattern (see request-context.ts)
540
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- globalThis singleton pattern (see request-context.ts)
530
541
  return (configHolder[STORED_CONFIG_KEY] as EmDashConfig | undefined) ?? null;
531
542
  }
532
543
 
@@ -283,10 +283,14 @@ ${entries.join("\n")}
283
283
  /**
284
284
  * Generates the sandbox runner module.
285
285
  * Imports the configured sandbox runner factory or provides a noop default.
286
+ *
287
+ * When sandbox is explicitly false (debugging escape hatch), we still mark
288
+ * sandboxEnabled = true so sandboxed plugin entries are loaded, but we use
289
+ * the noop runner which falls through to in-process loading via adaptSandboxEntry.
286
290
  */
287
- export function generateSandboxRunnerModule(sandboxRunner?: string): string {
291
+ export function generateSandboxRunnerModule(sandboxRunner?: string, sandbox?: boolean): string {
288
292
  if (!sandboxRunner) {
289
- // No sandbox runner configured - use noop
293
+ // No sandbox runner configured - sandboxed plugins disabled
290
294
  return `
291
295
  // No sandbox runner configured - sandboxed plugins disabled
292
296
  import { createNoopSandboxRunner } from "emdash";
@@ -296,6 +300,19 @@ export const sandboxEnabled = false;
296
300
  `;
297
301
  }
298
302
 
303
+ if (sandbox === false) {
304
+ // sandbox: false escape hatch - plugins are loaded but run in-process
305
+ // (no isolation, for debugging)
306
+ return `
307
+ // Sandbox explicitly disabled (sandbox: false) - plugins run in-process
308
+ import { createNoopSandboxRunner } from "emdash";
309
+
310
+ export const createSandboxRunner = createNoopSandboxRunner;
311
+ export const sandboxEnabled = true;
312
+ export const sandboxBypassed = true;
313
+ `;
314
+ }
315
+
299
316
  return `
300
317
  // Auto-generated sandbox runner module
301
318
  import { createSandboxRunner as _createSandboxRunner } from "${sandboxRunner}";
@@ -233,7 +233,7 @@ export function createVirtualModulesPlugin(options: VitePluginOptions): Plugin {
233
233
  }
234
234
  // Generate sandbox runner module
235
235
  if (id === RESOLVED_VIRTUAL_SANDBOX_RUNNER_ID) {
236
- return generateSandboxRunnerModule(resolvedConfig.sandboxRunner);
236
+ return generateSandboxRunnerModule(resolvedConfig.sandboxRunner, resolvedConfig.sandbox);
237
237
  }
238
238
  // Generate sandboxed plugins config module
239
239
  if (id === RESOLVED_VIRTUAL_SANDBOXED_PLUGINS_ID) {
@@ -346,7 +346,7 @@ export function createViteConfig(
346
346
  { find: "use-sync-external-store/shim", replacement: "use-sync-external-store" },
347
347
  ],
348
348
  },
349
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Monorepo has both vite 6 (docs) and vite 7 (core). tsgo resolves correctly.
349
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Monorepo has both vite 6 (docs) and vite 7 (core). tsgo resolves correctly.
350
350
  plugins: [
351
351
  createVirtualModulesPlugin(options),
352
352
  // In dev mode with source alias, compile Lingui macros on the fly
@@ -475,11 +475,11 @@ async function handleExternalAuth(
475
475
  const authResult = await virtualAuthenticate(request, authMode.config);
476
476
 
477
477
  // Get external auth config for auto-provision settings
478
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowing AuthModeConfig to ExternalAuthConfig after provider check
478
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowing AuthModeConfig to ExternalAuthConfig after provider check
479
479
  const externalConfig = authMode.config as ExternalAuthConfig;
480
480
 
481
481
  // Find or create user
482
- const adapter = createKyselyAdapter(emdash!.db);
482
+ const adapter = createKyselyAdapter(emdash.db);
483
483
  let user = await adapter.getUserByEmail(authResult.email);
484
484
 
485
485
  if (!user) {
@@ -492,9 +492,9 @@ async function handleExternalAuth(
492
492
  }
493
493
 
494
494
  // Check if this is the first user (they become admin)
495
- const userCount = await emdash!.db
495
+ const userCount = await emdash.db
496
496
  .selectFrom("users")
497
- .select(emdash!.db.fn.count("id").as("count"))
497
+ .select(emdash.db.fn.count("id").as("count"))
498
498
  .executeTakeFirst();
499
499
 
500
500
  const isFirstUser = Number(userCount?.count ?? 0) === 0;
@@ -512,7 +512,7 @@ async function handleExternalAuth(
512
512
  updated_at: now,
513
513
  };
514
514
 
515
- await emdash!.db.insertInto("users").values(newUser).execute();
515
+ await emdash.db.insertInto("users").values(newUser).execute();
516
516
 
517
517
  user = await adapter.getUserByEmail(authResult.email);
518
518
 
@@ -539,7 +539,7 @@ async function handleExternalAuth(
539
539
 
540
540
  if (Object.keys(updates).length > 0) {
541
541
  updates.updated_at = new Date().toISOString();
542
- await emdash!.db.updateTable("users").set(updates).where("id", "=", user.id).execute();
542
+ await emdash.db.updateTable("users").set(updates).where("id", "=", user.id).execute();
543
543
 
544
544
  user = {
545
545
  ...user,
@@ -665,7 +665,7 @@ async function handlePasskeyAuth(
665
665
  }
666
666
 
667
667
  // Get full user from database
668
- const adapter = createKyselyAdapter(emdash!.db);
668
+ const adapter = createKyselyAdapter(emdash.db);
669
669
  const user = await adapter.getUserById(sessionUser.id);
670
670
 
671
671
  if (!user) {
@@ -78,7 +78,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
78
78
  const editMode = hasEditCookie && isEditor;
79
79
 
80
80
  // Read locale from Astro's i18n routing
81
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Astro context includes currentLocale when i18n is configured
81
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Astro context includes currentLocale when i18n is configured
82
82
  const locale = (context as { currentLocale?: string }).currentLocale;
83
83
 
84
84
  // Verify preview token if present.
@@ -20,11 +20,8 @@ import type { RequestScopedDbOpts } from "virtual:emdash/dialect";
20
20
  import { mediaProviders as virtualMediaProviders } from "virtual:emdash/media-providers";
21
21
  // @ts-ignore - virtual module
22
22
  import { plugins as virtualPlugins } from "virtual:emdash/plugins";
23
- import {
24
- createSandboxRunner as virtualCreateSandboxRunner,
25
- sandboxEnabled as virtualSandboxEnabled,
26
- // @ts-ignore - virtual module
27
- } from "virtual:emdash/sandbox-runner";
23
+ // @ts-ignore - virtual module
24
+ import * as virtualSandboxRunnerModule from "virtual:emdash/sandbox-runner";
28
25
  // @ts-ignore - virtual module
29
26
  import { sandboxedPlugins as virtualSandboxedPlugins } from "virtual:emdash/sandboxed-plugins";
30
27
  // @ts-ignore - virtual module
@@ -82,11 +79,11 @@ function getConfig(): EmDashConfig | null {
82
79
  // Initialize i18n config on first access (once per worker lifetime)
83
80
  if (!i18nInitialized) {
84
81
  i18nInitialized = true;
85
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module checked as object above
82
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- virtual module checked as object above
86
83
  const config = virtualConfig as Record<string, unknown>;
87
84
  if (config.i18n && typeof config.i18n === "object") {
88
85
  setI18nConfig(
89
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- runtime-checked above
86
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- runtime-checked above
90
87
  config.i18n as {
91
88
  defaultLocale: string;
92
89
  locales: string[];
@@ -98,7 +95,7 @@ function getConfig(): EmDashConfig | null {
98
95
  }
99
96
  }
100
97
 
101
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
98
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- virtual module import is untyped (@ts-ignore above)
102
99
  return virtualConfig as EmDashConfig;
103
100
  }
104
101
  return null;
@@ -108,7 +105,7 @@ function getConfig(): EmDashConfig | null {
108
105
  * Get plugins from virtual module
109
106
  */
110
107
  function getPlugins(): ResolvedPlugin[] {
111
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
108
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- virtual module import is untyped (@ts-ignore above)
112
109
  return (virtualPlugins as ResolvedPlugin[]) || [];
113
110
  }
114
111
 
@@ -116,24 +113,37 @@ function getPlugins(): ResolvedPlugin[] {
116
113
  * Build runtime dependencies from virtual modules
117
114
  */
118
115
  function buildDependencies(config: EmDashConfig): RuntimeDependencies {
116
+ /* eslint-disable typescript-eslint/no-unsafe-type-assertion --
117
+ The virtual:emdash/* imports above use @ts-ignore because tsgo/IDE
118
+ resolution can't see virtual-modules.d.ts in every consumer setup,
119
+ so they arrive as `any`. The casts here line each entry up with
120
+ RuntimeDependencies's expected shape. The contract is enforced by
121
+ the integration that populates these virtual modules. */
122
+ const sandboxModule = virtualSandboxRunnerModule as Record<string, unknown>;
119
123
  return {
120
124
  config,
121
125
  plugins: getPlugins(),
122
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
123
126
  createDialect: virtualCreateDialect as (config: Record<string, unknown>) => unknown,
124
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
125
127
  createStorage: virtualCreateStorage as ((config: Record<string, unknown>) => Storage) | null,
126
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
127
- sandboxEnabled: virtualSandboxEnabled as boolean,
128
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
128
+ sandboxEnabled: sandboxModule.sandboxEnabled as boolean,
129
+ sandboxBypassed: (sandboxModule.sandboxBypassed as boolean) ?? false,
129
130
  sandboxedPluginEntries: (virtualSandboxedPlugins as SandboxedPluginEntry[]) || [],
130
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
131
- createSandboxRunner: virtualCreateSandboxRunner as
132
- | ((opts: { db: Kysely<Database> }) => SandboxRunner)
131
+ createSandboxRunner: sandboxModule.createSandboxRunner as
132
+ | ((opts: {
133
+ db: Kysely<Database>;
134
+ mediaStorage?: {
135
+ upload(options: {
136
+ key: string;
137
+ body: Uint8Array;
138
+ contentType: string;
139
+ }): Promise<unknown>;
140
+ delete(key: string): Promise<unknown>;
141
+ };
142
+ }) => SandboxRunner)
133
143
  | null,
134
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
135
144
  mediaProviderEntries: (virtualMediaProviders as MediaProviderEntry[]) || [],
136
145
  };
146
+ /* eslint-enable typescript-eslint/no-unsafe-type-assertion */
137
147
  }
138
148
 
139
149
  /**
@@ -255,7 +265,7 @@ function createRequestScopedDb(
255
265
  opts: RequestScopedDbOpts,
256
266
  ): { db: Kysely<Database>; commit: () => void } | null {
257
267
  if (typeof virtualCreateRequestScopedDb !== "function") return null;
258
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- adapter returns Kysely<unknown>; cast to Database since core owns that type
268
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- adapter returns Kysely<unknown>; cast to Database since core owns that type
259
269
  const fn = virtualCreateRequestScopedDb as (
260
270
  o: RequestScopedDbOpts,
261
271
  ) => { db: Kysely<Database>; commit: () => void } | null;
@@ -358,7 +368,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
358
368
  try {
359
369
  const runtime = await getRuntime(config, initSubTimings);
360
370
  setupVerified = true;
361
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- partial object; getPageRuntime() only checks for the page-contribution methods
371
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- partial object; getPageRuntime() only checks for the page-contribution methods
362
372
  locals.emdash = {
363
373
  collectPageMetadata: runtime.collectPageMetadata.bind(runtime),
364
374
  collectPageFragments: runtime.collectPageFragments.bind(runtime),
@@ -523,6 +533,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
523
533
 
524
534
  // Sandbox runner (for marketplace plugin install/update)
525
535
  getSandboxRunner: runtime.getSandboxRunner.bind(runtime),
536
+ isSandboxBypassed: runtime.isSandboxBypassed.bind(runtime),
526
537
 
527
538
  // Sync marketplace plugin states (after install/update/uninstall)
528
539
  syncMarketplacePlugins: runtime.syncMarketplacePlugins.bind(runtime),
@@ -1,4 +1,3 @@
1
- import { Role } from "@emdash-cms/auth";
2
1
  import type { APIRoute } from "astro";
3
2
 
4
3
  import { requirePerm } from "#api/authorize.js";
@@ -10,17 +9,9 @@ import { BylineRepository } from "#db/repositories/byline.js";
10
9
 
11
10
  export const prerender = false;
12
11
 
13
- function requireEditor(user: { role: number } | undefined): Response | null {
14
- if (!user || user.role < Role.EDITOR) {
15
- return apiError("FORBIDDEN", "Editor privileges required", 403);
16
- }
17
- return null;
18
- }
19
-
20
12
  export const GET: APIRoute = async ({ params, locals }) => {
21
13
  const { emdash, user } = locals;
22
- // Read access uses content:read so all authenticated roles can view byline data
23
- const denied = requirePerm(user, "content:read");
14
+ const denied = requirePerm(user, "bylines:read");
24
15
  if (denied) return denied;
25
16
 
26
17
  if (!emdash?.db) {
@@ -39,7 +30,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
39
30
 
40
31
  export const PUT: APIRoute = async ({ params, request, locals }) => {
41
32
  const { emdash, user } = locals;
42
- const denied = requireEditor(user);
33
+ const denied = requirePerm(user, "bylines:manage");
43
34
  if (denied) return denied;
44
35
 
45
36
  if (!emdash?.db) {
@@ -71,7 +62,7 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
71
62
 
72
63
  export const DELETE: APIRoute = async ({ params, locals }) => {
73
64
  const { emdash, user } = locals;
74
- const denied = requireEditor(user);
65
+ const denied = requirePerm(user, "bylines:manage");
75
66
  if (denied) return denied;
76
67
 
77
68
  if (!emdash?.db) {
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Byline translation endpoints
3
+ *
4
+ * GET /_emdash/api/admin/bylines/:id/translations — list every translation
5
+ * of a byline (siblings
6
+ * in the same
7
+ * translation_group)
8
+ * POST /_emdash/api/admin/bylines/:id/translations — create a new locale
9
+ * variant joining the
10
+ * source's
11
+ * translation_group
12
+ * (body: { locale, ... })
13
+ */
14
+
15
+ import type { APIRoute } from "astro";
16
+
17
+ import { requirePerm } from "#api/authorize.js";
18
+ import { handleError, requireDb, unwrapResult } from "#api/error.js";
19
+ import { handleBylineCreate, handleBylineTranslations } from "#api/handlers/bylines.js";
20
+ import { isParseError, parseBody } from "#api/parse.js";
21
+ import { bylineTranslationCreateBody } from "#api/schemas.js";
22
+ import { invalidateBylineCache } from "#bylines/index.js";
23
+ import { BylineRepository } from "#db/repositories/byline.js";
24
+
25
+ export const prerender = false;
26
+
27
+ export const GET: APIRoute = async ({ params, locals }) => {
28
+ const { emdash, user } = locals;
29
+ const id = params.id!;
30
+
31
+ const dbErr = requireDb(emdash?.db);
32
+ if (dbErr) return dbErr;
33
+
34
+ const denied = requirePerm(user, "bylines:read");
35
+ if (denied) return denied;
36
+
37
+ try {
38
+ const result = await handleBylineTranslations(emdash.db, id);
39
+ return unwrapResult(result);
40
+ } catch (error) {
41
+ return handleError(error, "Failed to fetch byline translations", "BYLINE_TRANSLATIONS_ERROR");
42
+ }
43
+ };
44
+
45
+ export const POST: APIRoute = async ({ params, request, locals }) => {
46
+ const { emdash, user } = locals;
47
+ const id = params.id!;
48
+
49
+ const dbErr = requireDb(emdash?.db);
50
+ if (dbErr) return dbErr;
51
+
52
+ const denied = requirePerm(user, "bylines:manage");
53
+ if (denied) return denied;
54
+
55
+ try {
56
+ const body = await parseBody(request, bylineTranslationCreateBody);
57
+ if (isParseError(body)) return body;
58
+
59
+ // Look up the source byline so we can:
60
+ // (a) emit a clean 404 when it doesn't exist (route layer);
61
+ // (b) fall back to its slug + display_name + avatar/website when
62
+ // the body omits them. Editors creating a translation often
63
+ // want to keep the slug stable and only enter the localized
64
+ // bio/displayName — defaulting saves clicks.
65
+ const repo = new BylineRepository(emdash.db);
66
+ const source = await repo.findById(id);
67
+ if (!source) {
68
+ return new Response(
69
+ JSON.stringify({ error: { code: "NOT_FOUND", message: "Byline not found" } }),
70
+ { status: 404, headers: { "Content-Type": "application/json" } },
71
+ );
72
+ }
73
+
74
+ const result = await handleBylineCreate(emdash.db, {
75
+ slug: body.slug ?? source.slug,
76
+ displayName: body.displayName ?? source.displayName,
77
+ bio: body.bio ?? null,
78
+ avatarMediaId: body.avatarMediaId ?? source.avatarMediaId,
79
+ websiteUrl: body.websiteUrl ?? source.websiteUrl,
80
+ // Translations don't inherit the source's user_id or guest flag —
81
+ // the partial unique on (user_id, locale) means a single user can
82
+ // own one byline per locale, but the editor must opt into linking
83
+ // the new row by editing it after creation.
84
+ userId: null,
85
+ isGuest: source.isGuest,
86
+ locale: body.locale,
87
+ translationOf: id,
88
+ });
89
+
90
+ if (result.success) invalidateBylineCache();
91
+ return unwrapResult(result, 201);
92
+ } catch (error) {
93
+ return handleError(
94
+ error,
95
+ "Failed to create byline translation",
96
+ "BYLINE_TRANSLATION_CREATE_ERROR",
97
+ );
98
+ }
99
+ };
@@ -1,13 +1,15 @@
1
- import { Role } from "@emdash-cms/auth";
2
1
  import type { APIRoute } from "astro";
3
2
 
4
3
  import { requirePerm } from "#api/authorize.js";
5
- import { apiError, apiSuccess, handleError } from "#api/error.js";
4
+ import { apiError, apiSuccess, handleError, unwrapResult } from "#api/error.js";
5
+ import { handleBylineCreate } from "#api/handlers/bylines.js";
6
6
  import { isParseError, parseBody, parseQuery } from "#api/parse.js";
7
7
  import { bylineCreateBody, bylinesListQuery } from "#api/schemas.js";
8
8
  import { invalidateBylineCache } from "#bylines/index.js";
9
9
  import { BylineRepository } from "#db/repositories/byline.js";
10
10
 
11
+ import { getI18nConfig } from "../../../../../i18n/config.js";
12
+
11
13
  export const prerender = false;
12
14
 
13
15
  export const GET: APIRoute = async ({ url, locals }) => {
@@ -17,19 +19,28 @@ export const GET: APIRoute = async ({ url, locals }) => {
17
19
  return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
18
20
  }
19
21
 
20
- // Read access uses content:read so all authenticated roles can view byline data
21
- const denied = requirePerm(user, "content:read");
22
+ const denied = requirePerm(user, "bylines:read");
22
23
  if (denied) return denied;
23
24
 
24
25
  const query = parseQuery(url, bylinesListQuery);
25
26
  if (isParseError(query)) return query;
26
27
 
28
+ const i18n = getI18nConfig();
29
+ if (query.locale && i18n && !i18n.locales.includes(query.locale)) {
30
+ return apiError(
31
+ "VALIDATION_ERROR",
32
+ `Locale "${query.locale}" is not configured for this site`,
33
+ 400,
34
+ );
35
+ }
36
+
27
37
  try {
28
38
  const repo = new BylineRepository(emdash.db);
29
39
  const result = await repo.findMany({
30
40
  search: query.search,
31
41
  isGuest: query.isGuest,
32
42
  userId: query.userId,
43
+ locale: query.locale,
33
44
  cursor: query.cursor,
34
45
  limit: query.limit,
35
46
  });
@@ -47,16 +58,14 @@ export const POST: APIRoute = async ({ request, locals }) => {
47
58
  return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
48
59
  }
49
60
 
50
- if (!user || user.role < Role.EDITOR) {
51
- return apiError("FORBIDDEN", "Editor privileges required", 403);
52
- }
61
+ const denied = requirePerm(user, "bylines:manage");
62
+ if (denied) return denied;
53
63
 
54
64
  const body = await parseBody(request, bylineCreateBody);
55
65
  if (isParseError(body)) return body;
56
66
 
57
67
  try {
58
- const repo = new BylineRepository(emdash.db);
59
- const byline = await repo.create({
68
+ const result = await handleBylineCreate(emdash.db, {
60
69
  slug: body.slug,
61
70
  displayName: body.displayName,
62
71
  bio: body.bio ?? null,
@@ -64,10 +73,12 @@ export const POST: APIRoute = async ({ request, locals }) => {
64
73
  websiteUrl: body.websiteUrl ?? null,
65
74
  userId: body.userId ?? null,
66
75
  isGuest: body.isGuest,
76
+ locale: body.locale,
77
+ translationOf: body.translationOf,
67
78
  });
68
79
 
69
- invalidateBylineCache();
70
- return apiSuccess(byline, 201);
80
+ if (result.success) invalidateBylineCache();
81
+ return unwrapResult(result, 201);
71
82
  } catch (error) {
72
83
  return handleError(error, "Failed to create byline", "BYLINE_CREATE_ERROR");
73
84
  }
@@ -48,6 +48,7 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
48
48
  version: body.version,
49
49
  confirmCapabilityChanges: body.confirmCapabilityChanges,
50
50
  confirmRouteVisibilityChanges: body.confirmRouteVisibilityChanges,
51
+ sandboxBypassed: emdash.isSandboxBypassed(),
51
52
  },
52
53
  );
53
54
 
@@ -49,7 +49,12 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
49
49
  emdash.getSandboxRunner(),
50
50
  emdash.config.marketplace,
51
51
  id,
52
- { version: body.version, configuredPluginIds, siteOrigin },
52
+ {
53
+ version: body.version,
54
+ configuredPluginIds,
55
+ siteOrigin,
56
+ sandboxBypassed: emdash.isSandboxBypassed(),
57
+ },
53
58
  );
54
59
 
55
60
  if (!result.success) return unwrapResult(result);
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Registry plugin uninstall endpoint (experimental)
3
+ *
4
+ * POST /_emdash/api/admin/plugins/registry/:id/uninstall — Uninstall a
5
+ * registry-source plugin. Mirrors the marketplace uninstall route; the
6
+ * handler refuses non-registry sources, so this won't trash a marketplace
7
+ * or config plugin that shares the id namespace.
8
+ */
9
+
10
+ import type { APIRoute } from "astro";
11
+ import { z } from "zod";
12
+
13
+ import { requirePerm } from "#api/authorize.js";
14
+ import { apiError, unwrapResult } from "#api/error.js";
15
+ import { handleRegistryUninstall } from "#api/index.js";
16
+ import { isParseError, parseOptionalBody } from "#api/parse.js";
17
+
18
+ export const prerender = false;
19
+
20
+ const uninstallBodySchema = z.object({
21
+ deleteData: z.boolean().optional(),
22
+ });
23
+
24
+ export const POST: APIRoute = async ({ params, request, locals }) => {
25
+ const { emdash, user } = locals;
26
+ const { id } = params;
27
+
28
+ if (!emdash?.db) {
29
+ return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
30
+ }
31
+
32
+ const denied = requirePerm(user, "plugins:manage");
33
+ if (denied) return denied;
34
+
35
+ if (!id) {
36
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
37
+ }
38
+
39
+ const body = await parseOptionalBody(request, uninstallBodySchema, {});
40
+ if (isParseError(body)) return body;
41
+
42
+ const result = await handleRegistryUninstall(emdash.db, emdash.storage, id, {
43
+ deleteData: body.deleteData ?? false,
44
+ });
45
+
46
+ if (!result.success) return unwrapResult(result);
47
+
48
+ await emdash.syncRegistryPlugins();
49
+
50
+ return unwrapResult(result);
51
+ };