emdash 0.14.0 → 0.16.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 (650) 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-BNKqxyFX.mjs} +560 -56
  10. package/dist/api-BNKqxyFX.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-BOPaD-s9.mjs} +17 -17
  14. package/dist/{apply-v4DBgjPw.mjs.map → apply-BOPaD-s9.mjs.map} +1 -1
  15. package/dist/astro/index.d.mts +10 -10
  16. package/dist/astro/index.d.mts.map +1 -1
  17. package/dist/astro/index.mjs +53 -5
  18. package/dist/astro/index.mjs.map +1 -1
  19. package/dist/astro/middleware/auth.d.mts +9 -9
  20. package/dist/astro/middleware/auth.mjs +6 -6
  21. package/dist/astro/middleware/auth.mjs.map +1 -1
  22. package/dist/astro/middleware/redirect.mjs +4 -4
  23. package/dist/astro/middleware/request-context.mjs +3 -3
  24. package/dist/astro/middleware/request-context.mjs.map +1 -1
  25. package/dist/astro/middleware/setup.mjs +1 -1
  26. package/dist/astro/middleware.d.mts.map +1 -1
  27. package/dist/astro/middleware.mjs +377 -75
  28. package/dist/astro/middleware.mjs.map +1 -1
  29. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
  30. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
  31. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
  32. package/dist/astro/routes/api/admin/api-tokens/index.mjs +5 -5
  33. package/dist/astro/routes/api/admin/bylines/_id_/index.d.mts.map +1 -1
  34. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -17
  35. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  36. package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +9 -0
  37. package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts.map +1 -0
  38. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +70 -0
  39. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -0
  40. package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
  41. package/dist/astro/routes/api/admin/bylines/index.mjs +25 -16
  42. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  43. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +10 -10
  44. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  45. package/dist/astro/routes/api/admin/comments/bulk.mjs +8 -8
  46. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  47. package/dist/astro/routes/api/admin/comments/index.mjs +8 -8
  48. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  49. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  50. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +4 -4
  51. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +4 -4
  52. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +33 -32
  53. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  54. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +33 -32
  55. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +32 -31
  57. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  58. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +32 -31
  59. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  60. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +34 -32
  61. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  62. package/dist/astro/routes/api/admin/plugins/index.mjs +32 -31
  63. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  64. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  65. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +32 -31
  66. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +34 -32
  68. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +32 -31
  70. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts +8 -0
  72. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -0
  73. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +59 -0
  74. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -0
  75. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts +8 -0
  76. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -0
  77. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +85 -0
  78. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -0
  79. package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts +8 -0
  80. package/dist/astro/routes/api/admin/plugins/registry/artifact.d.mts.map +1 -0
  81. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +301 -0
  82. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -0
  83. package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
  84. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +51 -32
  85. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/plugins/updates.d.mts.map +1 -1
  87. package/dist/astro/routes/api/admin/plugins/updates.mjs +45 -32
  88. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  89. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +32 -31
  90. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  91. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  92. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +32 -31
  93. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  95. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  96. package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
  97. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +3 -3
  98. package/dist/astro/routes/api/admin/users/index.mjs +5 -5
  99. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
  100. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  101. package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
  102. package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
  103. package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
  104. package/dist/astro/routes/api/auth/logout.mjs +3 -3
  105. package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
  106. package/dist/astro/routes/api/auth/magic-link/verify.mjs +3 -3
  107. package/dist/astro/routes/api/auth/me.mjs +5 -5
  108. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  109. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  110. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
  111. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  112. package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
  113. package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
  114. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  115. package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
  116. package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
  117. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
  118. package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
  119. package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
  120. package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
  121. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  122. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +11 -11
  123. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  124. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  125. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  126. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  127. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  128. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  129. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +9 -9
  130. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +6 -6
  131. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  132. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  133. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  134. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  135. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +6 -6
  136. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  137. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +10 -9
  138. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  139. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  140. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  141. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  142. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  143. package/dist/astro/routes/api/content/_collection_/_id_.mjs +6 -6
  144. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  145. package/dist/astro/routes/api/content/_collection_/index.mjs +6 -6
  146. package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
  147. package/dist/astro/routes/api/dashboard.mjs +7 -7
  148. package/dist/astro/routes/api/dev/emails.mjs +3 -3
  149. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  150. package/dist/astro/routes/api/import/probe.mjs +10 -10
  151. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  152. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  153. package/dist/astro/routes/api/import/wordpress/execute.mjs +9 -8
  154. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  155. package/dist/astro/routes/api/import/wordpress/media.mjs +8 -8
  156. package/dist/astro/routes/api/import/wordpress/prepare.mjs +8 -8
  157. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  158. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +11 -1
  159. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  160. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +17 -1
  161. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  162. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
  163. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +9 -9
  164. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  165. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  166. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +10 -10
  167. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  168. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +11 -11
  169. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  170. package/dist/astro/routes/api/manifest.mjs +4 -4
  171. package/dist/astro/routes/api/mcp.mjs +29 -29
  172. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  173. package/dist/astro/routes/api/media/_id_/confirm.mjs +6 -6
  174. package/dist/astro/routes/api/media/_id_.mjs +6 -6
  175. package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
  176. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
  177. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
  178. package/dist/astro/routes/api/media/providers/index.mjs +3 -3
  179. package/dist/astro/routes/api/media/upload-url.mjs +7 -7
  180. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  181. package/dist/astro/routes/api/media.mjs +8 -8
  182. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +7 -7
  183. package/dist/astro/routes/api/menus/_name_/items.mjs +7 -7
  184. package/dist/astro/routes/api/menus/_name_/reorder.mjs +7 -7
  185. package/dist/astro/routes/api/menus/_name_/translations.mjs +7 -7
  186. package/dist/astro/routes/api/menus/_name_.mjs +7 -7
  187. package/dist/astro/routes/api/menus/index.mjs +7 -7
  188. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  189. package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
  190. package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
  191. package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
  192. package/dist/astro/routes/api/oauth/register.mjs +3 -3
  193. package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
  194. package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
  195. package/dist/astro/routes/api/oauth/token.mjs +6 -6
  196. package/dist/astro/routes/api/openapi.json.mjs +3 -3
  197. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  198. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
  199. package/dist/astro/routes/api/redirects/404s/index.mjs +8 -8
  200. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  201. package/dist/astro/routes/api/redirects/404s/summary.mjs +8 -8
  202. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  203. package/dist/astro/routes/api/redirects/_id_.mjs +9 -9
  204. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  205. package/dist/astro/routes/api/redirects/index.mjs +9 -9
  206. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  207. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  208. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  209. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +32 -31
  210. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  211. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +32 -31
  212. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  213. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +32 -31
  214. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  215. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +32 -31
  216. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  217. package/dist/astro/routes/api/schema/collections/index.mjs +32 -31
  218. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  219. package/dist/astro/routes/api/schema/index.mjs +6 -6
  220. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  221. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +32 -31
  222. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  223. package/dist/astro/routes/api/schema/orphans/index.mjs +32 -31
  224. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  225. package/dist/astro/routes/api/search/enable.mjs +9 -9
  226. package/dist/astro/routes/api/search/index.mjs +8 -8
  227. package/dist/astro/routes/api/search/rebuild.mjs +9 -9
  228. package/dist/astro/routes/api/search/stats.mjs +6 -6
  229. package/dist/astro/routes/api/search/suggest.mjs +8 -8
  230. package/dist/astro/routes/api/sections/_slug_.mjs +8 -8
  231. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  232. package/dist/astro/routes/api/sections/index.mjs +8 -8
  233. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  234. package/dist/astro/routes/api/settings/email.mjs +4 -4
  235. package/dist/astro/routes/api/settings.mjs +10 -10
  236. package/dist/astro/routes/api/setup/admin-verify.mjs +10 -10
  237. package/dist/astro/routes/api/setup/admin.mjs +9 -9
  238. package/dist/astro/routes/api/setup/dev-bypass.mjs +22 -22
  239. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  240. package/dist/astro/routes/api/setup/index.mjs +22 -22
  241. package/dist/astro/routes/api/setup/status.mjs +4 -4
  242. package/dist/astro/routes/api/snapshot.mjs +6 -6
  243. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  244. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +11 -10
  245. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  246. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +11 -10
  247. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  248. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +11 -10
  249. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  250. package/dist/astro/routes/api/taxonomies/index.mjs +11 -10
  251. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  252. package/dist/astro/routes/api/themes/preview.mjs +5 -5
  253. package/dist/astro/routes/api/typegen.mjs +5 -5
  254. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  255. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  256. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  257. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +6 -6
  258. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +8 -8
  259. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +8 -8
  260. package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
  261. package/dist/astro/routes/api/widget-areas/index.mjs +8 -8
  262. package/dist/astro/routes/api/widget-components.mjs +3 -3
  263. package/dist/astro/routes/robots.txt.mjs +5 -5
  264. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  265. package/dist/astro/routes/sitemap-_collection_.xml.mjs +58 -13
  266. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  267. package/dist/astro/routes/sitemap.xml.mjs +6 -6
  268. package/dist/astro/types.d.mts +20 -12
  269. package/dist/astro/types.d.mts.map +1 -1
  270. package/dist/auth/providers/github.d.mts +1 -1
  271. package/dist/auth/providers/google.d.mts +1 -1
  272. package/dist/{authorize-BlyCH-96.mjs → authorize-Bn4S4DUT.mjs} +2 -2
  273. package/dist/{authorize-BlyCH-96.mjs.map → authorize-Bn4S4DUT.mjs.map} +1 -1
  274. package/dist/byline-BDylH_m4.mjs +404 -0
  275. package/dist/byline-BDylH_m4.mjs.map +1 -0
  276. package/dist/{bylines-BdUP8NuI.d.mts → bylines-B2_XmnSU.d.mts} +73 -28
  277. package/dist/bylines-B2_XmnSU.d.mts.map +1 -0
  278. package/dist/bylines-B7TFEvFf.mjs +118 -0
  279. package/dist/bylines-B7TFEvFf.mjs.map +1 -0
  280. package/dist/bylines-n6nykUyI.mjs +174 -0
  281. package/dist/bylines-n6nykUyI.mjs.map +1 -0
  282. package/dist/{cache-CXCpjWiL.mjs → cache-BcI1yUjR.mjs} +2 -2
  283. package/dist/{cache-CXCpjWiL.mjs.map → cache-BcI1yUjR.mjs.map} +1 -1
  284. package/dist/{challenge-store-CJ0OOHOr.mjs → challenge-store-Dng1SxKT.mjs} +1 -1
  285. package/dist/{challenge-store-CJ0OOHOr.mjs.map → challenge-store-Dng1SxKT.mjs.map} +1 -1
  286. package/dist/{chunks-DyGtu1Bv.mjs → chunks-cYG4SnIP.mjs} +2 -2
  287. package/dist/{chunks-DyGtu1Bv.mjs.map → chunks-cYG4SnIP.mjs.map} +1 -1
  288. package/dist/cli/index.mjs +68 -30
  289. package/dist/cli/index.mjs.map +1 -1
  290. package/dist/client/cf-access.d.mts +1 -1
  291. package/dist/client/index.d.mts +1 -1
  292. package/dist/client/index.mjs +1 -1
  293. package/dist/client/index.mjs.map +1 -1
  294. package/dist/{comment-Dd9MI82-.mjs → comment-C76G-9tz.mjs} +2 -2
  295. package/dist/{comment-Dd9MI82-.mjs.map → comment-C76G-9tz.mjs.map} +1 -1
  296. package/dist/{comments-koGI0FrK.mjs → comments-CCxFFGY1.mjs} +3 -3
  297. package/dist/{comments-koGI0FrK.mjs.map → comments-CCxFFGY1.mjs.map} +1 -1
  298. package/dist/{components-mZem7pbe.mjs → components-Dx3DM0gg.mjs} +1 -1
  299. package/dist/{components-mZem7pbe.mjs.map → components-Dx3DM0gg.mjs.map} +1 -1
  300. package/dist/config-CVssduLe.mjs.map +1 -1
  301. package/dist/{content-D6YG26WG.mjs → content-8voQNTXX.mjs} +3 -3
  302. package/dist/{content-D6YG26WG.mjs.map → content-8voQNTXX.mjs.map} +1 -1
  303. package/dist/{context-qF8d3IPR.mjs → context-B7qiYrz2.mjs} +10 -10
  304. package/dist/context-B7qiYrz2.mjs.map +1 -0
  305. package/dist/{cron-H8eJ46dv.mjs → cron-Bd3b3iuj.mjs} +1 -1
  306. package/dist/{cron-H8eJ46dv.mjs.map → cron-Bd3b3iuj.mjs.map} +1 -1
  307. package/dist/{dashboard-BmWSIUwY.mjs → dashboard-BeaFSPpx.mjs} +4 -4
  308. package/dist/{dashboard-BmWSIUwY.mjs.map → dashboard-BeaFSPpx.mjs.map} +1 -1
  309. package/dist/db/index.d.mts +3 -3
  310. package/dist/db/index.mjs +1 -1
  311. package/dist/db/libsql.d.mts +1 -1
  312. package/dist/db/postgres.d.mts +1 -1
  313. package/dist/db/sqlite.d.mts +1 -1
  314. package/dist/db/sqlite.mjs +1 -1
  315. package/dist/{db-errors-CGN9kJfo.mjs → db-errors-BiYqoX-n.mjs} +14 -2
  316. package/dist/db-errors-BiYqoX-n.mjs.map +1 -0
  317. package/dist/{default-Dbs22Gg4.mjs → default-BvTAYCzx.mjs} +1 -1
  318. package/dist/{default-Dbs22Gg4.mjs.map → default-BvTAYCzx.mjs.map} +1 -1
  319. package/dist/{device-flow-BqJRxa0Q.mjs → device-flow-B9oG8PwP.mjs} +4 -4
  320. package/dist/{device-flow-BqJRxa0Q.mjs.map → device-flow-B9oG8PwP.mjs.map} +1 -1
  321. package/dist/{email-console-Dmp5Q-P2.mjs → email-console-CubRll9q.mjs} +1 -1
  322. package/dist/email-console-CubRll9q.mjs.map +1 -0
  323. package/dist/{error-tSQWIl5U.mjs → error-ChfADBuu.mjs} +19 -9
  324. package/dist/error-ChfADBuu.mjs.map +1 -0
  325. package/dist/errors-9P_FDrJ_.mjs +17 -0
  326. package/dist/errors-9P_FDrJ_.mjs.map +1 -0
  327. package/dist/{escape-B8bdIryO.mjs → escape-Cg6kMELH.mjs} +1 -1
  328. package/dist/{escape-B8bdIryO.mjs.map → escape-Cg6kMELH.mjs.map} +1 -1
  329. package/dist/{fts-manager-B633C-kQ.mjs → fts-manager-C_b-4x8u.mjs} +2 -2
  330. package/dist/{fts-manager-B633C-kQ.mjs.map → fts-manager-C_b-4x8u.mjs.map} +1 -1
  331. package/dist/{import-CNfLOgDE.mjs → import-DG80rC_I.mjs} +3 -3
  332. package/dist/{import-CNfLOgDE.mjs.map → import-DG80rC_I.mjs.map} +1 -1
  333. package/dist/{index-BV8iJ-6s.d.mts → index-BPZFAcgE.d.mts} +384 -123
  334. package/dist/index-BPZFAcgE.d.mts.map +1 -0
  335. package/dist/{index-D2gvztOP.d.mts → index-CC42STEm.d.mts} +3 -3
  336. package/dist/{index-D2gvztOP.d.mts.map → index-CC42STEm.d.mts.map} +1 -1
  337. package/dist/index.d.mts +17 -17
  338. package/dist/index.mjs +53 -52
  339. package/dist/{load-QzYRpVN3.mjs → load-CLFRjk9r.mjs} +2 -2
  340. package/dist/{load-QzYRpVN3.mjs.map → load-CLFRjk9r.mjs.map} +1 -1
  341. package/dist/{loader-Cs6-Bqe6.mjs → loader-D-vIJjfY.mjs} +86 -46
  342. package/dist/loader-D-vIJjfY.mjs.map +1 -0
  343. package/dist/{manifest-schema-HCtSh4Jq.mjs → manifest-schema-Czqf0TLu.mjs} +1 -1
  344. package/dist/{manifest-schema-HCtSh4Jq.mjs.map → manifest-schema-Czqf0TLu.mjs.map} +1 -1
  345. package/dist/media/index.d.mts +1 -1
  346. package/dist/media/local-runtime.d.mts +11 -11
  347. package/dist/media/local-runtime.mjs +4 -4
  348. package/dist/{media-Dg7he9uK.mjs → media-CKQd8AYU.mjs} +2 -2
  349. package/dist/media-CKQd8AYU.mjs.map +1 -0
  350. package/dist/{media-allowlist-B8EX01DH.mjs → media-allowlist-BNloC69x.mjs} +1 -1
  351. package/dist/{media-allowlist-B8EX01DH.mjs.map → media-allowlist-BNloC69x.mjs.map} +1 -1
  352. package/dist/{menus-X4Z-eBA1.mjs → menus-C-nWT5Tu.mjs} +42 -17
  353. package/dist/menus-C-nWT5Tu.mjs.map +1 -0
  354. package/dist/{menus-DOzIecHi.mjs → menus-arUNspyU.mjs} +2 -2
  355. package/dist/menus-arUNspyU.mjs.map +1 -0
  356. package/dist/mime-KV5TqkMN.mjs.map +1 -1
  357. package/dist/{mode-DPRPvJYm.mjs → mode-CaaiebZI.mjs} +1 -1
  358. package/dist/{mode-DPRPvJYm.mjs.map → mode-CaaiebZI.mjs.map} +1 -1
  359. package/dist/{oauth-authorization-62GmpGIH.mjs → oauth-authorization-CTMeVfvj.mjs} +4 -4
  360. package/dist/{oauth-authorization-62GmpGIH.mjs.map → oauth-authorization-CTMeVfvj.mjs.map} +1 -1
  361. package/dist/{oauth-clients-D_B0_-Bz.mjs → oauth-clients-eJCbkVSG.mjs} +1 -1
  362. package/dist/oauth-clients-eJCbkVSG.mjs.map +1 -0
  363. package/dist/{oauth-state-store-DpsZViTu.mjs → oauth-state-store-vOSdOeGe.mjs} +1 -1
  364. package/dist/{oauth-state-store-DpsZViTu.mjs.map → oauth-state-store-vOSdOeGe.mjs.map} +1 -1
  365. package/dist/{oauth-user-lookup-meyS2oB1.mjs → oauth-user-lookup-3JwsVw6N.mjs} +1 -1
  366. package/dist/{oauth-user-lookup-meyS2oB1.mjs.map → oauth-user-lookup-3JwsVw6N.mjs.map} +1 -1
  367. package/dist/options-BL4X94qY.mjs.map +1 -1
  368. package/dist/{options-Cq64Wx0O.d.mts → options-DhV-gwJb.d.mts} +4 -4
  369. package/dist/options-DhV-gwJb.d.mts.map +1 -0
  370. package/dist/page/index.d.mts +2 -2
  371. package/dist/{parse-BFTPon-J.mjs → parse-DHbXfvxO.mjs} +2 -2
  372. package/dist/{parse-BFTPon-J.mjs.map → parse-DHbXfvxO.mjs.map} +1 -1
  373. package/dist/{passkey-config-Cg86_ISa.mjs → passkey-config-BloQOT3y.mjs} +1 -1
  374. package/dist/{passkey-config-Cg86_ISa.mjs.map → passkey-config-BloQOT3y.mjs.map} +1 -1
  375. package/dist/{placeholder-D3cFCU9y.d.mts → placeholder-KCkkCtgQ.d.mts} +1 -1
  376. package/dist/{placeholder-D3cFCU9y.d.mts.map → placeholder-KCkkCtgQ.d.mts.map} +1 -1
  377. package/dist/plugin-types.d.mts +1 -1
  378. package/dist/plugin-utils.d.mts +25 -10
  379. package/dist/plugin-utils.d.mts.map +1 -1
  380. package/dist/plugin-utils.mjs +11 -10
  381. package/dist/plugin-utils.mjs.map +1 -1
  382. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  383. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  384. package/dist/plugins/adapt-sandbox-entry.mjs +26 -15
  385. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  386. package/dist/{preview-C1LOEbWZ.mjs → preview-D4z0WONU.mjs} +2 -2
  387. package/dist/{preview-C1LOEbWZ.mjs.map → preview-D4z0WONU.mjs.map} +1 -1
  388. package/dist/{public-url-CseXl9Fv.mjs → public-url-CUWWFME2.mjs} +1 -1
  389. package/dist/{public-url-CseXl9Fv.mjs.map → public-url-CUWWFME2.mjs.map} +1 -1
  390. package/dist/{query-axZmO6Tn.mjs → query-7m6-l0f_.mjs} +27 -17
  391. package/dist/query-7m6-l0f_.mjs.map +1 -0
  392. package/dist/{rate-limit-t5CVjCO6.mjs → rate-limit-D8RAXN8b.mjs} +2 -2
  393. package/dist/{rate-limit-t5CVjCO6.mjs.map → rate-limit-D8RAXN8b.mjs.map} +1 -1
  394. package/dist/{redirect-DGRsLO2I.mjs → redirect-BINiRYq4.mjs} +1 -1
  395. package/dist/{redirect-DGRsLO2I.mjs.map → redirect-BINiRYq4.mjs.map} +1 -1
  396. package/dist/{redirect-DkaDxq8e.mjs → redirect-CjfDGrTd.mjs} +2 -2
  397. package/dist/{redirect-DkaDxq8e.mjs.map → redirect-CjfDGrTd.mjs.map} +1 -1
  398. package/dist/{redirects-Dmj6KRU3.mjs → redirects-COMLwsV5.mjs} +19 -5
  399. package/dist/redirects-COMLwsV5.mjs.map +1 -0
  400. package/dist/{redirects-D1fdd68T.mjs → redirects-CowoEHdE.mjs} +3 -3
  401. package/dist/{redirects-D1fdd68T.mjs.map → redirects-CowoEHdE.mjs.map} +1 -1
  402. package/dist/{registry-BnCeHYsf.mjs → registry-Cyp-dx6J.mjs} +4 -4
  403. package/dist/{registry-BnCeHYsf.mjs.map → registry-Cyp-dx6J.mjs.map} +1 -1
  404. package/dist/request-cache-dzCt8TZB.mjs.map +1 -1
  405. package/dist/request-context.mjs.map +1 -1
  406. package/dist/{request-meta-CLCwSQOS.mjs → request-meta-C_Cjii-T.mjs} +2 -2
  407. package/dist/{request-meta-CLCwSQOS.mjs.map → request-meta-C_Cjii-T.mjs.map} +1 -1
  408. package/dist/resolve-D6sM-SgF.mjs +143 -0
  409. package/dist/resolve-D6sM-SgF.mjs.map +1 -0
  410. package/dist/{runner-DcfZewkO.d.mts → runner-DSQBurMS.d.mts} +8 -5
  411. package/dist/runner-DSQBurMS.d.mts.map +1 -0
  412. package/dist/{runner-DdnQIwz_.mjs → runner-Drnvs96u.mjs} +491 -188
  413. package/dist/runner-Drnvs96u.mjs.map +1 -0
  414. package/dist/runtime.d.mts +10 -10
  415. package/dist/runtime.mjs +2 -2
  416. package/dist/{schema-BmqagCwG.mjs → schema-CI9mYPX3.mjs} +4 -4
  417. package/dist/{schema-BmqagCwG.mjs.map → schema-CI9mYPX3.mjs.map} +1 -1
  418. package/dist/{search-CPrvO5u8.mjs → search-DKz_mGBP.mjs} +4 -4
  419. package/dist/{search-CPrvO5u8.mjs.map → search-DKz_mGBP.mjs.map} +1 -1
  420. package/dist/{secrets-6pgZyq0K.mjs → secrets-rPdhEBkD.mjs} +1 -1
  421. package/dist/{secrets-6pgZyq0K.mjs.map → secrets-rPdhEBkD.mjs.map} +1 -1
  422. package/dist/{sections-Cm-zb-gZ.mjs → sections-DBbCDIAT.mjs} +3 -3
  423. package/dist/{sections-Cm-zb-gZ.mjs.map → sections-DBbCDIAT.mjs.map} +1 -1
  424. package/dist/seed/index.d.mts +2 -2
  425. package/dist/seed/index.mjs +16 -16
  426. package/dist/seo/index.d.mts +1 -1
  427. package/dist/{seo-DRq9-EPP.mjs → seo-BGCyDlkb.mjs} +2 -2
  428. package/dist/{seo-DRq9-EPP.mjs.map → seo-BGCyDlkb.mjs.map} +1 -1
  429. package/dist/{seo-BoR4wCUh.mjs → seo-Dq707mNQ.mjs} +5 -3
  430. package/dist/seo-Dq707mNQ.mjs.map +1 -0
  431. package/dist/{service-vByySp-2.mjs → service-B0H7U1Y9.mjs} +3 -3
  432. package/dist/{service-vByySp-2.mjs.map → service-B0H7U1Y9.mjs.map} +1 -1
  433. package/dist/{settings-xQKsWnzQ.mjs → settings-BSXRtTzk.mjs} +3 -3
  434. package/dist/settings-BSXRtTzk.mjs.map +1 -0
  435. package/dist/{settings-CBBj7HUd.mjs → settings-DfwNyQkf.mjs} +3 -3
  436. package/dist/{settings-CBBj7HUd.mjs.map → settings-DfwNyQkf.mjs.map} +1 -1
  437. package/dist/{setup-BGAJ2uXs.mjs → setup-Cf_TyOv5.mjs} +2 -2
  438. package/dist/{setup-BGAJ2uXs.mjs.map → setup-Cf_TyOv5.mjs.map} +1 -1
  439. package/dist/{setup-complete-C6ZCLhKo.mjs → setup-complete-MzzN9u0b.mjs} +1 -1
  440. package/dist/{setup-complete-C6ZCLhKo.mjs.map → setup-complete-MzzN9u0b.mjs.map} +1 -1
  441. package/dist/{setup-nonce-CY1gQiAU.mjs → setup-nonce-DXuriHsg.mjs} +1 -1
  442. package/dist/{setup-nonce-CY1gQiAU.mjs.map → setup-nonce-DXuriHsg.mjs.map} +1 -1
  443. package/dist/{site-url-D-M4Fd8O.mjs → site-url-xkhw1tcz.mjs} +1 -1
  444. package/dist/{site-url-D-M4Fd8O.mjs.map → site-url-xkhw1tcz.mjs.map} +1 -1
  445. package/dist/{ssrf-DzFN_qV-.mjs → ssrf-MZ-zrG6-.mjs} +1 -1
  446. package/dist/{ssrf-DzFN_qV-.mjs.map → ssrf-MZ-zrG6-.mjs.map} +1 -1
  447. package/dist/storage/local.d.mts +1 -1
  448. package/dist/storage/local.mjs +1 -1
  449. package/dist/storage/local.mjs.map +1 -1
  450. package/dist/storage/s3.d.mts +1 -1
  451. package/dist/storage/s3.mjs +1 -1
  452. package/dist/storage/s3.mjs.map +1 -1
  453. package/dist/{taxonomies-Dc0mzlms.mjs → taxonomies-4vx0nmMr.mjs} +4 -4
  454. package/dist/{taxonomies-Dc0mzlms.mjs.map → taxonomies-4vx0nmMr.mjs.map} +1 -1
  455. package/dist/{taxonomies-Cn9UpaR2.mjs → taxonomies-CcvrMLbR.mjs} +8 -43
  456. package/dist/taxonomies-CcvrMLbR.mjs.map +1 -0
  457. package/dist/{taxonomy-wPfusMK9.mjs → taxonomy-zqGQUqgu.mjs} +3 -3
  458. package/dist/{taxonomy-wPfusMK9.mjs.map → taxonomy-zqGQUqgu.mjs.map} +1 -1
  459. package/dist/{tokens-DILYNZMi.mjs → tokens-N8otWMmj.mjs} +1 -1
  460. package/dist/{tokens-DILYNZMi.mjs.map → tokens-N8otWMmj.mjs.map} +1 -1
  461. package/dist/{transport-fw-mKJzT.mjs → transport-B6CHddbu.mjs} +1 -1
  462. package/dist/{transport-fw-mKJzT.mjs.map → transport-B6CHddbu.mjs.map} +1 -1
  463. package/dist/{transport-GeXlLscf.d.mts → transport-C2MGqtL6.d.mts} +1 -1
  464. package/dist/{transport-GeXlLscf.d.mts.map → transport-C2MGqtL6.d.mts.map} +1 -1
  465. package/dist/{trusted-proxy-CJhQIk65.mjs → trusted-proxy-97pajC2f.mjs} +1 -1
  466. package/dist/{trusted-proxy-CJhQIk65.mjs.map → trusted-proxy-97pajC2f.mjs.map} +1 -1
  467. package/dist/{types-CwXMEPRr.mjs → types-B0bmgwMG.mjs} +2 -2
  468. package/dist/types-B0bmgwMG.mjs.map +1 -0
  469. package/dist/{types-Dz9CGX_d.mjs → types-Cd9UCu3t.mjs} +1 -1
  470. package/dist/{types-Dz9CGX_d.mjs.map → types-Cd9UCu3t.mjs.map} +1 -1
  471. package/dist/{types-DmxPPXGf.d.mts → types-CkDSF81F.d.mts} +1 -1
  472. package/dist/{types-DmxPPXGf.d.mts.map → types-CkDSF81F.d.mts.map} +1 -1
  473. package/dist/{types-BWhaSS7U.d.mts → types-CpUuGcd5.d.mts} +1 -1
  474. package/dist/{types-BWhaSS7U.d.mts.map → types-CpUuGcd5.d.mts.map} +1 -1
  475. package/dist/{types-DFowNO60.d.mts → types-D599-ruj.d.mts} +1 -1
  476. package/dist/{types-DFowNO60.d.mts.map → types-D599-ruj.d.mts.map} +1 -1
  477. package/dist/{types-B05e2naf.d.mts → types-DGHWRQgr.d.mts} +3 -3
  478. package/dist/{types-B05e2naf.d.mts.map → types-DGHWRQgr.d.mts.map} +1 -1
  479. package/dist/{types-CzvJd1ND.d.mts → types-DaYDYW6g.d.mts} +14 -1
  480. package/dist/types-DaYDYW6g.d.mts.map +1 -0
  481. package/dist/{types-C1KKK4VP.d.mts → types-DaqNzqVt.d.mts} +16 -1
  482. package/dist/{types-C1KKK4VP.d.mts.map → types-DaqNzqVt.d.mts.map} +1 -1
  483. package/dist/{types-DW1l0gCv.d.mts → types-Dgo6y-Ut.d.mts} +1 -1
  484. package/dist/{types-DW1l0gCv.d.mts.map → types-Dgo6y-Ut.d.mts.map} +1 -1
  485. package/dist/{types-Cb2UCDJg.d.mts → types-bYmRn_Uy.d.mts} +1 -1
  486. package/dist/{types-Cb2UCDJg.d.mts.map → types-bYmRn_Uy.d.mts.map} +1 -1
  487. package/dist/{user-Dr1bOCqS.mjs → user-hUSOaIJy.mjs} +2 -2
  488. package/dist/{user-Dr1bOCqS.mjs.map → user-hUSOaIJy.mjs.map} +1 -1
  489. package/dist/{utils-_F-rWBTN.mjs → utils-C3wTAP-P.mjs} +1 -1
  490. package/dist/{utils-_F-rWBTN.mjs.map → utils-C3wTAP-P.mjs.map} +1 -1
  491. package/dist/{validate-BpQGsmd7.d.mts → validate-DQtHw9NT.d.mts} +5 -5
  492. package/dist/{validate-BpQGsmd7.d.mts.map → validate-DQtHw9NT.d.mts.map} +1 -1
  493. package/dist/{validate-DlFxcVVK.mjs → validate-IGltez8n.mjs} +2 -2
  494. package/dist/{validate-DlFxcVVK.mjs.map → validate-IGltez8n.mjs.map} +1 -1
  495. package/dist/{validation-BiFJqUp5.mjs → validation-Bmymau7y.mjs} +6 -6
  496. package/dist/{validation-BiFJqUp5.mjs.map → validation-Bmymau7y.mjs.map} +1 -1
  497. package/dist/version-BTc87L3L.mjs +7 -0
  498. package/dist/{version-DNmQakZO.mjs.map → version-BTc87L3L.mjs.map} +1 -1
  499. package/dist/{widgets-B9j_yzlk.mjs → widgets-yHQa4c6c.mjs} +3 -3
  500. package/dist/widgets-yHQa4c6c.mjs.map +1 -0
  501. package/dist/{zod-generator-DSyz01KE.mjs → zod-generator-B80aap1J.mjs} +2 -2
  502. package/dist/{zod-generator-DSyz01KE.mjs.map → zod-generator-B80aap1J.mjs.map} +1 -1
  503. package/package.json +12 -10
  504. package/src/api/error.ts +18 -3
  505. package/src/api/errors.ts +8 -0
  506. package/src/api/handlers/bylines.ts +161 -0
  507. package/src/api/handlers/content.ts +125 -43
  508. package/src/api/handlers/index.ts +8 -0
  509. package/src/api/handlers/marketplace.ts +27 -5
  510. package/src/api/handlers/oauth-clients.ts +1 -1
  511. package/src/api/handlers/registry.ts +622 -5
  512. package/src/api/handlers/seo.ts +16 -1
  513. package/src/api/handlers/snapshot.ts +1 -1
  514. package/src/api/openapi/document.ts +1 -1
  515. package/src/api/schemas/bylines.ts +46 -0
  516. package/src/astro/integration/index.ts +27 -1
  517. package/src/astro/integration/routes.ts +10 -0
  518. package/src/astro/integration/runtime.ts +20 -1
  519. package/src/astro/integration/virtual-modules.ts +19 -2
  520. package/src/astro/integration/vite-config.ts +2 -2
  521. package/src/astro/middleware/auth.ts +7 -7
  522. package/src/astro/middleware/request-context.ts +1 -1
  523. package/src/astro/middleware.ts +35 -20
  524. package/src/astro/public-plugin-api-routes.ts +41 -0
  525. package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -12
  526. package/src/astro/routes/api/admin/bylines/[id]/translations.ts +99 -0
  527. package/src/astro/routes/api/admin/bylines/index.ts +22 -11
  528. package/src/astro/routes/api/admin/plugins/[id]/update.ts +1 -0
  529. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +6 -1
  530. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +51 -0
  531. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +83 -0
  532. package/src/astro/routes/api/admin/plugins/registry/artifact.ts +388 -0
  533. package/src/astro/routes/api/admin/plugins/registry/install.ts +7 -1
  534. package/src/astro/routes/api/admin/plugins/updates.ts +43 -6
  535. package/src/astro/routes/api/admin/themes/marketplace/index.ts +1 -1
  536. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +2 -2
  537. package/src/astro/routes/api/auth/oauth/[provider].ts +2 -2
  538. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -2
  539. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -2
  540. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -2
  541. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -2
  542. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +2 -2
  543. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +6 -6
  544. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +1 -1
  545. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -2
  546. package/src/astro/routes/api/content/[collection]/[id].ts +6 -6
  547. package/src/astro/routes/api/import/wordpress/execute.ts +1 -1
  548. package/src/astro/routes/api/import/wordpress/prepare.ts +2 -2
  549. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +22 -0
  550. package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +8 -5
  551. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +2 -2
  552. package/src/astro/routes/api/media/upload-url.ts +1 -1
  553. package/src/astro/routes/api/redirects/404s/index.ts +3 -3
  554. package/src/astro/routes/api/redirects/404s/summary.ts +1 -1
  555. package/src/astro/routes/api/redirects/[id].ts +3 -3
  556. package/src/astro/routes/api/redirects/index.ts +2 -2
  557. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +4 -4
  558. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +2 -6
  559. package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +1 -1
  560. package/src/astro/routes/api/schema/collections/[slug]/index.ts +6 -6
  561. package/src/astro/routes/api/schema/collections/index.ts +4 -4
  562. package/src/astro/routes/api/schema/index.ts +1 -1
  563. package/src/astro/routes/api/schema/orphans/[slug].ts +1 -1
  564. package/src/astro/routes/api/schema/orphans/index.ts +1 -1
  565. package/src/astro/routes/api/sections/[slug].ts +3 -3
  566. package/src/astro/routes/api/sections/index.ts +2 -2
  567. package/src/astro/routes/sitemap-[collection].xml.ts +114 -14
  568. package/src/astro/types.ts +18 -0
  569. package/src/auth/rate-limit.ts +1 -1
  570. package/src/auth/trusted-proxy.ts +1 -1
  571. package/src/bylines/index.ts +154 -55
  572. package/src/cli/commands/init.ts +4 -8
  573. package/src/client/index.ts +1 -1
  574. package/src/components/InlinePortableTextEditor.tsx +5 -1
  575. package/src/components/inline-code-block.tsx +343 -0
  576. package/src/config/secrets.ts +3 -3
  577. package/src/content/converters/portable-text-to-prosemirror.ts +35 -11
  578. package/src/database/connection.ts +3 -10
  579. package/src/database/errors.ts +14 -0
  580. package/src/database/index.ts +3 -1
  581. package/src/database/migrations/006_taxonomy_defs.ts +1 -1
  582. package/src/database/migrations/014_draft_revisions.ts +6 -6
  583. package/src/database/migrations/040_byline_i18n.ts +497 -0
  584. package/src/database/migrations/runner.ts +33 -22
  585. package/src/database/repositories/audit.ts +2 -2
  586. package/src/database/repositories/byline.ts +320 -50
  587. package/src/database/repositories/media.ts +2 -2
  588. package/src/database/repositories/menu.ts +1 -1
  589. package/src/database/repositories/options.ts +3 -3
  590. package/src/database/repositories/plugin-storage.ts +3 -3
  591. package/src/database/repositories/types.ts +13 -0
  592. package/src/database/types.ts +15 -0
  593. package/src/emdash-runtime.ts +493 -20
  594. package/src/i18n/config.ts +1 -1
  595. package/src/i18n/resolve.ts +152 -0
  596. package/src/index.ts +9 -0
  597. package/src/loader.ts +134 -60
  598. package/src/mcp/server.ts +3 -3
  599. package/src/media/mime.ts +1 -1
  600. package/src/page/absolute-url.ts +1 -1
  601. package/src/plugin-utils.ts +23 -0
  602. package/src/plugins/adapt-sandbox-entry.ts +45 -40
  603. package/src/plugins/email-console.ts +1 -1
  604. package/src/plugins/index.ts +1 -0
  605. package/src/plugins/marketplace.ts +1 -1
  606. package/src/plugins/sandbox/index.ts +1 -0
  607. package/src/plugins/sandbox/noop.ts +11 -3
  608. package/src/plugins/sandbox/types.ts +28 -0
  609. package/src/query.ts +41 -7
  610. package/src/registry/config.ts +1 -1
  611. package/src/request-cache.ts +3 -3
  612. package/src/request-context.ts +1 -1
  613. package/src/settings/index.ts +4 -4
  614. package/src/storage/local.ts +1 -1
  615. package/src/storage/s3.ts +3 -3
  616. package/src/utils/db-errors.ts +24 -0
  617. package/src/widgets/index.ts +1 -1
  618. package/dist/api-BMLZuwM4.mjs.map +0 -1
  619. package/dist/byline-D09BaS4j.mjs +0 -220
  620. package/dist/byline-D09BaS4j.mjs.map +0 -1
  621. package/dist/bylines-BTM2xtP8.mjs +0 -113
  622. package/dist/bylines-BTM2xtP8.mjs.map +0 -1
  623. package/dist/bylines-BdUP8NuI.d.mts.map +0 -1
  624. package/dist/connection-2igzM-AT.mjs +0 -57
  625. package/dist/connection-2igzM-AT.mjs.map +0 -1
  626. package/dist/context-qF8d3IPR.mjs.map +0 -1
  627. package/dist/db-errors-CGN9kJfo.mjs.map +0 -1
  628. package/dist/email-console-Dmp5Q-P2.mjs.map +0 -1
  629. package/dist/error-tSQWIl5U.mjs.map +0 -1
  630. package/dist/index-BV8iJ-6s.d.mts.map +0 -1
  631. package/dist/loader-Cs6-Bqe6.mjs.map +0 -1
  632. package/dist/media-Dg7he9uK.mjs.map +0 -1
  633. package/dist/menus-DOzIecHi.mjs.map +0 -1
  634. package/dist/menus-X4Z-eBA1.mjs.map +0 -1
  635. package/dist/oauth-clients-D_B0_-Bz.mjs.map +0 -1
  636. package/dist/options-Cq64Wx0O.d.mts.map +0 -1
  637. package/dist/query-axZmO6Tn.mjs.map +0 -1
  638. package/dist/redirects-Dmj6KRU3.mjs.map +0 -1
  639. package/dist/runner-DcfZewkO.d.mts.map +0 -1
  640. package/dist/runner-DdnQIwz_.mjs.map +0 -1
  641. package/dist/seo-BoR4wCUh.mjs.map +0 -1
  642. package/dist/settings-xQKsWnzQ.mjs.map +0 -1
  643. package/dist/taxonomies-Cn9UpaR2.mjs.map +0 -1
  644. package/dist/types-CwXMEPRr.mjs.map +0 -1
  645. package/dist/types-CzvJd1ND.d.mts.map +0 -1
  646. package/dist/version-DNmQakZO.mjs +0 -7
  647. package/dist/widgets-B9j_yzlk.mjs.map +0 -1
  648. /package/dist/{api-tokens-D3C9v02m.mjs → api-tokens-iPIHAY8N.mjs} +0 -0
  649. /package/dist/{ssrf-CTul4uQi.mjs → ssrf-BIcd-aXW.mjs} +0 -0
  650. /package/dist/{types-Db67HHlU.mjs → types-1NNkmTIn.mjs} +0 -0
@@ -32,12 +32,12 @@ export const POST: APIRoute = async ({ params, locals, cache }) => {
32
32
 
33
33
  const existingData =
34
34
  existing.data && typeof existing.data === "object"
35
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler returns unknown data; narrowed by typeof check above
35
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above
36
36
  (existing.data as Record<string, unknown>)
37
37
  : undefined;
38
38
  const existingItem =
39
39
  existingData?.item && typeof existingData.item === "object"
40
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowed by typeof check above
40
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above
41
41
  (existingData.item as Record<string, unknown>)
42
42
  : existingData;
43
43
  const authorId = typeof existingItem?.authorId === "string" ? existingItem.authorId : "";
@@ -35,12 +35,12 @@ export const GET: APIRoute = async ({ params, url, locals }) => {
35
35
  if (result.success && !hasPermission(user, "content:read_drafts")) {
36
36
  const data =
37
37
  result.data && typeof result.data === "object"
38
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler returns unknown data; narrowed by typeof check
38
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check
39
39
  (result.data as Record<string, unknown>)
40
40
  : undefined;
41
41
  const item =
42
42
  data?.item && typeof data.item === "object"
43
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowed by typeof check
43
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check
44
44
  (data.item as Record<string, unknown>)
45
45
  : undefined;
46
46
  const status = typeof item?.status === "string" ? item.status : null;
@@ -87,13 +87,13 @@ export const PUT: APIRoute = async ({ params, request, locals, cache }) => {
87
87
 
88
88
  const existingData =
89
89
  existing.data && typeof existing.data === "object"
90
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler returns unknown data; narrowed by typeof check above
90
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above
91
91
  (existing.data as Record<string, unknown>)
92
92
  : undefined;
93
93
  // Handler returns { item, _rev } — extract the item for ownership and ID resolution
94
94
  const existingItem =
95
95
  existingData?.item && typeof existingData.item === "object"
96
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowed by typeof check above
96
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above
97
97
  (existingData.item as Record<string, unknown>)
98
98
  : existingData;
99
99
  const authorId = typeof existingItem?.authorId === "string" ? existingItem.authorId : "";
@@ -151,13 +151,13 @@ export const DELETE: APIRoute = async ({ params, locals, cache }) => {
151
151
 
152
152
  const deleteData =
153
153
  existing.data && typeof existing.data === "object"
154
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler returns unknown data; narrowed by typeof check above
154
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check above
155
155
  (existing.data as Record<string, unknown>)
156
156
  : undefined;
157
157
  // Handler returns { item, _rev } — extract the item for ownership and ID resolution
158
158
  const deleteItem =
159
159
  deleteData?.item && typeof deleteData.item === "object"
160
- ? // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowed by typeof check above
160
+ ? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above
161
161
  (deleteData.item as Record<string, unknown>)
162
162
  : deleteData;
163
163
  const authorId = typeof deleteItem?.authorId === "string" ? deleteItem.authorId : "";
@@ -376,7 +376,7 @@ export async function importContent(
376
376
  // `api/handlers/content.ts`). `HandlerResponse.data` is
377
377
  // typed as `unknown` to avoid coupling the route surface to
378
378
  // internal handler types, so we narrow here.
379
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler contract documented at handleContentCreate
379
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler contract documented at handleContentCreate
380
380
  const createdItem = (createResult.data as { item: { id: string } } | undefined)?.item;
381
381
 
382
382
  // Track translation group: the first imported post in a group
@@ -20,7 +20,7 @@ import { capitalize, sanitizeSlug, singularize, type ImportFieldDef } from "./an
20
20
 
21
21
  /** Validate that a string is a known FieldType, returning undefined if not */
22
22
  function asFieldType(value: string): FieldType | undefined {
23
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- validated by includes check
23
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- validated by includes check
24
24
  return (FIELD_TYPES as readonly string[]).includes(value) ? (value as FieldType) : undefined;
25
25
  }
26
26
 
@@ -55,7 +55,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
55
55
  const body = await parseBody(request, wpPrepareBody);
56
56
  if (isParseError(body)) return body;
57
57
 
58
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to PrepareRequest
58
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Zod schema output narrowed to PrepareRequest
59
59
  const result = await prepareImport(emdash.db, body as PrepareRequest);
60
60
 
61
61
  // Invalidate the URL pattern cache when prepare adds new collections so
@@ -27,6 +27,28 @@ export function buildBaseUrlMap(urlMap: Record<string, string>): Map<string, str
27
27
  return baseMap;
28
28
  }
29
29
 
30
+ /**
31
+ * Extract the URL to match from a stored media field value.
32
+ *
33
+ * Image/file columns hold a JSON-stringified MediaValue
34
+ * (e.g. `{"provider":"external","id":"","src":"https://.../hero.jpg"}`), but legacy
35
+ * rows may hold a bare URL string. Returns the inner `src` for a MediaValue, otherwise
36
+ * the value unchanged. Without this, the whole JSON blob is passed to findMatchingUrl()
37
+ * and the embedded URL is never matched.
38
+ */
39
+ export function extractMediaUrl(value: string): string {
40
+ try {
41
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- shape validated below
42
+ const parsed = JSON.parse(value) as { src?: unknown };
43
+ if (parsed && typeof parsed.src === "string") {
44
+ return parsed.src;
45
+ }
46
+ } catch {
47
+ // Not JSON — treat the column value as a bare URL.
48
+ }
49
+ return value;
50
+ }
51
+
30
52
  /**
31
53
  * Find matching new URL for a given URL, checking exact, base, and WordPress image-size matches
32
54
  */
@@ -24,6 +24,7 @@ import type { EmDashHandlers } from "#types";
24
24
 
25
25
  import {
26
26
  buildBaseUrlMap,
27
+ extractMediaUrl,
27
28
  findMatchingUrl,
28
29
  rewritePortableTextUrls,
29
30
  rewriteStringUrls,
@@ -134,7 +135,7 @@ async function rewriteUrls(
134
135
  if (!value || typeof value !== "string") continue;
135
136
 
136
137
  try {
137
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- JSON.parse returns unknown; validated by Array.isArray below
138
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- JSON.parse returns unknown; validated by Array.isArray below
138
139
  const blocks = JSON.parse(value) as PortableTextBlock[];
139
140
  if (!Array.isArray(blocks)) continue;
140
141
 
@@ -174,8 +175,10 @@ async function rewriteUrls(
174
175
  const value = row[field.slug];
175
176
  if (!value || typeof value !== "string") continue;
176
177
 
177
- // Try to find a matching rewritten URL
178
- const newUrl = findMatchingUrl(value, urlMap, baseMap);
178
+ // Values are stored as JSON MediaValue objects (e.g. featured_image from
179
+ // import normalizes to {"provider":"external","src":"<wp url>"}). Match on the
180
+ // inner `src`, falling back to the raw value for legacy bare-URL rows.
181
+ const newUrl = findMatchingUrl(extractMediaUrl(value), urlMap, baseMap);
179
182
  if (newUrl) {
180
183
  // Normalize into a proper MediaValue instead of storing a bare URL
181
184
  try {
@@ -192,11 +195,11 @@ async function rewriteUrls(
192
195
  if (rowUpdated) {
193
196
  try {
194
197
  // Build update query dynamically
195
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Kysely dynamic table requires type assertion
198
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic table requires type assertion
196
199
  let query = db.updateTable(tableName as any).where("id", "=", row.id);
197
200
 
198
201
  for (const [key, value] of Object.entries(updates)) {
199
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Kysely dynamic column update requires type assertion
202
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic column update requires type assertion
200
203
  query = query.set({ [key]: value } as any);
201
204
  }
202
205
 
@@ -60,7 +60,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
60
60
  return apiError("SSRF_BLOCKED", msg, 400);
61
61
  }
62
62
 
63
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to WpPluginImportConfig
63
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- Zod schema output narrowed to WpPluginImportConfig
64
64
  const config = body.config as unknown as WpPluginImportConfig;
65
65
 
66
66
  // Get the WordPress plugin source
@@ -316,7 +316,7 @@ async function importContent(
316
316
 
317
317
  // Track translation group: first item in a group establishes the mapping
318
318
  if (item.translationGroup && !translationGroupMap.has(item.translationGroup)) {
319
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- handler success data includes id
319
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler success data includes id
320
320
  const createdData = createResult.data as { id?: string } | undefined;
321
321
  if (createdData?.id) {
322
322
  translationGroupMap.set(item.translationGroup, createdData.id);
@@ -136,7 +136,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
136
136
  if (
137
137
  error instanceof Error &&
138
138
  "code" in error &&
139
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- narrowing error to check custom code property after "code" in error guard
139
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowing error to check custom code property after "code" in error guard
140
140
  (error as { code: string }).code === "NOT_SUPPORTED"
141
141
  ) {
142
142
  return apiError(
@@ -24,7 +24,7 @@ export const GET: APIRoute = async ({ url, 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
 
29
29
  const denied = requirePerm(user, "redirects:read");
30
30
  if (denied) return denied;
@@ -44,7 +44,7 @@ export const DELETE: APIRoute = async ({ locals }) => {
44
44
  const { emdash, user } = locals;
45
45
  const dbErr = requireDb(emdash?.db);
46
46
  if (dbErr) return dbErr;
47
- const db = emdash!.db;
47
+ const db = emdash.db;
48
48
 
49
49
  const denied = requirePerm(user, "redirects:manage");
50
50
  if (denied) return denied;
@@ -61,7 +61,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
61
61
  const { emdash, user } = locals;
62
62
  const dbErr = requireDb(emdash?.db);
63
63
  if (dbErr) return dbErr;
64
- const db = emdash!.db;
64
+ const db = emdash.db;
65
65
 
66
66
  const denied = requirePerm(user, "redirects:manage");
67
67
  if (denied) return denied;
@@ -18,7 +18,7 @@ export const GET: APIRoute = async ({ url, locals }) => {
18
18
  const { emdash, user } = locals;
19
19
  const dbErr = requireDb(emdash?.db);
20
20
  if (dbErr) return dbErr;
21
- const db = emdash!.db;
21
+ const db = emdash.db;
22
22
 
23
23
  const denied = requirePerm(user, "redirects:read");
24
24
  if (denied) return denied;
@@ -25,7 +25,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
25
25
  const { emdash, user } = locals;
26
26
  const dbErr = requireDb(emdash?.db);
27
27
  if (dbErr) return dbErr;
28
- const db = emdash!.db;
28
+ const db = emdash.db;
29
29
  const { id } = params;
30
30
 
31
31
  const denied = requirePerm(user, "redirects:read");
@@ -47,7 +47,7 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
47
47
  const { emdash, user } = locals;
48
48
  const dbErr = requireDb(emdash?.db);
49
49
  if (dbErr) return dbErr;
50
- const db = emdash!.db;
50
+ const db = emdash.db;
51
51
  const { id } = params;
52
52
 
53
53
  const denied = requirePerm(user, "redirects:manage");
@@ -73,7 +73,7 @@ export const DELETE: APIRoute = async ({ params, locals }) => {
73
73
  const { emdash, user } = locals;
74
74
  const dbErr = requireDb(emdash?.db);
75
75
  if (dbErr) return dbErr;
76
- const db = emdash!.db;
76
+ const db = emdash.db;
77
77
  const { id } = params;
78
78
 
79
79
  const denied = requirePerm(user, "redirects:manage");
@@ -20,7 +20,7 @@ export const GET: APIRoute = async ({ url, locals }) => {
20
20
  const { emdash, user } = locals;
21
21
  const dbErr = requireDb(emdash?.db);
22
22
  if (dbErr) return dbErr;
23
- const db = emdash!.db;
23
+ const db = emdash.db;
24
24
 
25
25
  const denied = requirePerm(user, "redirects:read");
26
26
  if (denied) return denied;
@@ -40,7 +40,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
40
40
  const { emdash, user } = locals;
41
41
  const dbErr = requireDb(emdash?.db);
42
42
  if (dbErr) return dbErr;
43
- const db = emdash!.db;
43
+ const db = emdash.db;
44
44
 
45
45
  const denied = requirePerm(user, "redirects:manage");
46
46
  if (denied) return denied;
@@ -32,7 +32,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
32
32
  const denied = requirePerm(user, "schema:read");
33
33
  if (denied) return denied;
34
34
 
35
- const result = await handleSchemaFieldGet(emdash!.db, collectionSlug, fieldSlug);
35
+ const result = await handleSchemaFieldGet(emdash.db, collectionSlug, fieldSlug);
36
36
  return unwrapResult(result);
37
37
  };
38
38
 
@@ -50,9 +50,9 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
50
50
  const body = await parseBody(request, updateFieldBody);
51
51
  if (isParseError(body)) return body;
52
52
 
53
- // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- body is Zod-validated via parseBody(request, updateFieldBody) above
53
+ // eslint-disable-next-line typescript/no-unsafe-type-assertion -- body is Zod-validated via parseBody(request, updateFieldBody) above
54
54
  const result = await handleSchemaFieldUpdate(
55
- emdash!.db,
55
+ emdash.db,
56
56
  collectionSlug,
57
57
  fieldSlug,
58
58
  body as UpdateFieldInput,
@@ -71,6 +71,6 @@ export const DELETE: APIRoute = async ({ params, locals }) => {
71
71
  const denied = requirePerm(user, "schema:manage");
72
72
  if (denied) return denied;
73
73
 
74
- const result = await handleSchemaFieldDelete(emdash!.db, collectionSlug, fieldSlug);
74
+ const result = await handleSchemaFieldDelete(emdash.db, collectionSlug, fieldSlug);
75
75
  return unwrapResult(result);
76
76
  };
@@ -26,7 +26,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
26
26
  const denied = requirePerm(user, "schema:read");
27
27
  if (denied) return denied;
28
28
 
29
- const result = await handleSchemaFieldList(emdash!.db, collectionSlug);
29
+ const result = await handleSchemaFieldList(emdash.db, collectionSlug);
30
30
  return unwrapResult(result);
31
31
  };
32
32
 
@@ -43,10 +43,6 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
43
43
  const body = await parseBody(request, createFieldBody);
44
44
  if (isParseError(body)) return body;
45
45
 
46
- const result = await handleSchemaFieldCreate(
47
- emdash!.db,
48
- collectionSlug,
49
- body as CreateFieldInput,
50
- );
46
+ const result = await handleSchemaFieldCreate(emdash.db, collectionSlug, body as CreateFieldInput);
51
47
  return unwrapResult(result, 201);
52
48
  };
@@ -27,6 +27,6 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
27
27
  const body = await parseBody(request, fieldReorderBody);
28
28
  if (isParseError(body)) return body;
29
29
 
30
- const result = await handleSchemaFieldReorder(emdash!.db, collectionSlug, body.fieldSlugs);
30
+ const result = await handleSchemaFieldReorder(emdash.db, collectionSlug, body.fieldSlugs);
31
31
  return unwrapResult(result);
32
32
  };
@@ -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;
@@ -5,13 +5,25 @@
5
5
  *
6
6
  * Uses the collection's url_pattern to build URLs. Falls back to
7
7
  * /{collection}/{slug} when no pattern is configured.
8
+ *
9
+ * i18n behaviour: when Astro i18n is enabled, the locale prefix is
10
+ * applied via Astro's own `getRelativeLocaleUrl` (which honours
11
+ * `prefixDefaultLocale`, custom `path` mappings, and other `routing`
12
+ * config). Each translation row is emitted as its own `<url>` with
13
+ * `<xhtml:link rel="alternate" hreflang="...">` entries pointing to
14
+ * its siblings (grouped by `translation_group`). The default-locale
15
+ * variant is also linked as `hreflang="x-default"`.
8
16
  */
9
17
 
10
18
  import type { APIRoute } from "astro";
11
19
 
12
20
  import { handleSitemapData } from "#api/handlers/seo.js";
21
+ import { getPublicOrigin } from "#api/public-url.js";
13
22
  import { getSiteSettingsWithDb } from "#settings/index.js";
14
23
 
24
+ import { getI18nConfig, isI18nEnabled } from "../../i18n/config.js";
25
+ import { interpolateUrlPattern, localizePath } from "../../i18n/resolve.js";
26
+
15
27
  export const prerender = false;
16
28
 
17
29
  const TRAILING_SLASH_RE = /\/$/;
@@ -20,8 +32,6 @@ const LT_RE = /</g;
20
32
  const GT_RE = />/g;
21
33
  const QUOT_RE = /"/g;
22
34
  const APOS_RE = /'/g;
23
- const SLUG_PLACEHOLDER = "{slug}";
24
- const ID_PLACEHOLDER = "{id}";
25
35
 
26
36
  export const GET: APIRoute = async ({ params, locals, url }) => {
27
37
  const { emdash } = locals;
@@ -36,7 +46,10 @@ export const GET: APIRoute = async ({ params, locals, url }) => {
36
46
 
37
47
  try {
38
48
  const settings = await getSiteSettingsWithDb(emdash.db);
39
- const siteUrl = (settings.url || url.origin).replace(TRAILING_SLASH_RE, "");
49
+ const siteUrl = (settings.url || getPublicOrigin(url, emdash?.config)).replace(
50
+ TRAILING_SLASH_RE,
51
+ "",
52
+ );
40
53
 
41
54
  const result = await handleSitemapData(emdash.db, collectionSlug);
42
55
 
@@ -55,25 +68,112 @@ export const GET: APIRoute = async ({ params, locals, url }) => {
55
68
  });
56
69
  }
57
70
 
58
- const lines: string[] = [
59
- '<?xml version="1.0" encoding="UTF-8"?>',
60
- '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
61
- ];
71
+ const i18nEnabled = isI18nEnabled();
72
+ const i18nConfig = getI18nConfig();
62
73
 
74
+ // Group entries by `translation_group` so each <url> can advertise
75
+ // its sibling translations via xhtml:link. Rows without a group
76
+ // (legacy/single-locale data) are emitted individually.
77
+ type Entry = (typeof col.entries)[number];
78
+ const groups = new Map<string, Entry[]>();
79
+ const ungrouped: Entry[] = [];
63
80
  for (const entry of col.entries) {
64
- const slug = entry.slug || entry.id;
65
- const path = col.urlPattern
66
- ? col.urlPattern
67
- .replace(SLUG_PLACEHOLDER, encodeURIComponent(slug))
68
- .replace(ID_PLACEHOLDER, encodeURIComponent(entry.id))
69
- : `/${encodeURIComponent(col.collection)}/${encodeURIComponent(slug)}`;
81
+ if (i18nEnabled && entry.translationGroup) {
82
+ const list = groups.get(entry.translationGroup);
83
+ if (list) list.push(entry);
84
+ else groups.set(entry.translationGroup, [entry]);
85
+ } else {
86
+ ungrouped.push(entry);
87
+ }
88
+ }
70
89
 
71
- const loc = `${siteUrl}${path}`;
90
+ // Resolve every URL up-front so we can reference sibling URLs
91
+ // while emitting hreflang alternates without re-resolving.
92
+ // `localizePath` returns `null` when the row's locale isn't in
93
+ // the configured `i18n.locales` list -- the site can't serve a
94
+ // route for it, so the entry is dropped from the sitemap and
95
+ // omitted from sibling alternates.
96
+ const urlByEntry = new Map<string, string | null>();
97
+ const resolveEntryUrl = async (entry: Entry): Promise<string | null> => {
98
+ if (urlByEntry.has(entry.id)) return urlByEntry.get(entry.id) ?? null;
99
+ const path = interpolateUrlPattern({
100
+ pattern: col.urlPattern,
101
+ collection: col.collection,
102
+ slug: entry.slug || entry.id,
103
+ id: entry.id,
104
+ });
105
+ const localized = await localizePath(path, entry.locale);
106
+ const absolute = localized === null ? null : `${siteUrl}${localized}`;
107
+ urlByEntry.set(entry.id, absolute);
108
+ return absolute;
109
+ };
110
+
111
+ const useXhtml = i18nEnabled;
112
+ const lines: string[] = ['<?xml version="1.0" encoding="UTF-8"?>'];
113
+ lines.push(
114
+ useXhtml
115
+ ? '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">'
116
+ : '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
117
+ );
118
+
119
+ const writeUrl = async (entry: Entry, siblings: Entry[] | null) => {
120
+ const loc = await resolveEntryUrl(entry);
121
+ // Skip rows whose locale isn't in the configured `i18n.locales`
122
+ // list. Linking to a route the site can't serve is worse than
123
+ // no link at all (search engines hit a 404 and downrank).
124
+ if (loc === null) return;
72
125
 
73
126
  lines.push(" <url>");
74
127
  lines.push(` <loc>${escapeXml(loc)}</loc>`);
75
128
  lines.push(` <lastmod>${escapeXml(entry.updatedAt)}</lastmod>`);
129
+
130
+ if (useXhtml && siblings && siblings.length > 1) {
131
+ // Emit one xhtml:link per sibling (including self -- Google
132
+ // recommends including the page's own hreflang annotation).
133
+ // Siblings with unroutable locales are skipped here too.
134
+ for (const sib of siblings) {
135
+ const sibLoc = await resolveEntryUrl(sib);
136
+ if (sibLoc === null) continue;
137
+ lines.push(
138
+ ` <xhtml:link rel="alternate" hreflang="${escapeXml(sib.locale)}" href="${escapeXml(sibLoc)}" />`,
139
+ );
140
+ }
141
+
142
+ // x-default: prefer the default-locale sibling, otherwise
143
+ // the first sibling with a routable URL. Stable order:
144
+ // rows arrive sorted by updated_at DESC from the handler.
145
+ const defaultSibling =
146
+ i18nConfig && siblings.find((s) => s.locale === i18nConfig.defaultLocale);
147
+ let xDefaultLoc: string | null = null;
148
+ if (defaultSibling) {
149
+ xDefaultLoc = await resolveEntryUrl(defaultSibling);
150
+ }
151
+ if (xDefaultLoc === null) {
152
+ for (const sib of siblings) {
153
+ const sibLoc = await resolveEntryUrl(sib);
154
+ if (sibLoc !== null) {
155
+ xDefaultLoc = sibLoc;
156
+ break;
157
+ }
158
+ }
159
+ }
160
+ if (xDefaultLoc !== null) {
161
+ lines.push(
162
+ ` <xhtml:link rel="alternate" hreflang="x-default" href="${escapeXml(xDefaultLoc)}" />`,
163
+ );
164
+ }
165
+ }
166
+
76
167
  lines.push(" </url>");
168
+ };
169
+
170
+ for (const siblings of groups.values()) {
171
+ for (const entry of siblings) {
172
+ await writeUrl(entry, siblings);
173
+ }
174
+ }
175
+ for (const entry of ungrouped) {
176
+ await writeUrl(entry, null);
77
177
  }
78
178
 
79
179
  lines.push("</urlset>");