emdash 0.19.0 → 0.20.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 (403) hide show
  1. package/dist/{adapters-C5AWLJSD.d.mts → adapters-BzIHV3sw.d.mts} +1 -1
  2. package/dist/{adapters-C5AWLJSD.d.mts.map → adapters-BzIHV3sw.d.mts.map} +1 -1
  3. package/dist/{allowed-origins-CyYLEJkp.mjs → allowed-origins-B1u7Qnvg.mjs} +2 -2
  4. package/dist/{allowed-origins-CyYLEJkp.mjs.map → allowed-origins-B1u7Qnvg.mjs.map} +1 -1
  5. package/dist/api/route-utils.d.mts +3 -3
  6. package/dist/api/route-utils.mjs +5 -5
  7. package/dist/api/schemas/index.d.mts +1 -1
  8. package/dist/api/schemas/index.mjs +2 -2
  9. package/dist/{api-BZ6bhjYs.mjs → api-DStv36ik.mjs} +36 -5
  10. package/dist/api-DStv36ik.mjs.map +1 -0
  11. package/dist/{api-tokens-VrXNiNvV.mjs → api-tokens-DPfhPu5V.mjs} +2 -2
  12. package/dist/{api-tokens-VrXNiNvV.mjs.map → api-tokens-DPfhPu5V.mjs.map} +1 -1
  13. package/dist/{apply-hQkKKBCf.mjs → apply-Dr7snAMT.mjs} +7 -7
  14. package/dist/{apply-hQkKKBCf.mjs.map → apply-Dr7snAMT.mjs.map} +1 -1
  15. package/dist/astro/index.d.mts +10 -10
  16. package/dist/astro/index.mjs +3 -3
  17. package/dist/astro/middleware/auth.d.mts +9 -9
  18. package/dist/astro/middleware/auth.mjs +4 -4
  19. package/dist/astro/middleware/redirect.mjs +1 -1
  20. package/dist/astro/middleware/request-context.mjs +1 -1
  21. package/dist/astro/middleware/setup.mjs +1 -1
  22. package/dist/astro/middleware.d.mts +1 -1
  23. package/dist/astro/middleware.d.mts.map +1 -1
  24. package/dist/astro/middleware.mjs +63 -112
  25. package/dist/astro/middleware.mjs.map +1 -1
  26. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +2 -2
  27. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +2 -2
  28. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
  29. package/dist/astro/routes/api/admin/api-tokens/index.mjs +2 -2
  30. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +2 -2
  31. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +4 -4
  32. package/dist/astro/routes/api/admin/byline-fields/index.mjs +4 -4
  33. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +4 -4
  34. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +6 -6
  35. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +6 -6
  36. package/dist/astro/routes/api/admin/bylines/index.mjs +6 -6
  37. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +6 -6
  38. package/dist/astro/routes/api/admin/comments/_id_.mjs +2 -2
  39. package/dist/astro/routes/api/admin/comments/bulk.mjs +4 -4
  40. package/dist/astro/routes/api/admin/comments/counts.mjs +2 -2
  41. package/dist/astro/routes/api/admin/comments/index.mjs +4 -4
  42. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +1 -1
  43. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +1 -1
  44. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +1 -1
  45. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +1 -1
  46. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +14 -14
  47. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +14 -14
  48. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +14 -14
  49. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +14 -14
  50. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +14 -14
  51. package/dist/astro/routes/api/admin/plugins/index.mjs +14 -14
  52. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +1 -1
  53. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +14 -14
  54. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +14 -14
  55. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +14 -14
  56. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +14 -14
  57. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +15 -15
  58. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +14 -14
  59. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +15 -15
  60. package/dist/astro/routes/api/admin/plugins/updates.mjs +14 -14
  61. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +14 -14
  62. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +1 -1
  63. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +14 -14
  64. package/dist/astro/routes/api/admin/users/_id_/index.mjs +2 -2
  65. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +1 -1
  66. package/dist/astro/routes/api/admin/users/index.mjs +2 -2
  67. package/dist/astro/routes/api/auth/dev-bypass.mjs +2 -2
  68. package/dist/astro/routes/api/auth/invite/complete.mjs +6 -6
  69. package/dist/astro/routes/api/auth/invite/index.mjs +3 -3
  70. package/dist/astro/routes/api/auth/invite/register-options.mjs +5 -5
  71. package/dist/astro/routes/api/auth/logout.mjs +1 -1
  72. package/dist/astro/routes/api/auth/magic-link/send.mjs +4 -4
  73. package/dist/astro/routes/api/auth/magic-link/verify.mjs +1 -1
  74. package/dist/astro/routes/api/auth/me.mjs +2 -2
  75. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  76. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +3 -3
  77. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  78. package/dist/astro/routes/api/auth/passkey/_id_.mjs +2 -2
  79. package/dist/astro/routes/api/auth/passkey/options.mjs +6 -6
  80. package/dist/astro/routes/api/auth/passkey/register/options.mjs +5 -5
  81. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +6 -6
  82. package/dist/astro/routes/api/auth/passkey/verify.mjs +6 -6
  83. package/dist/astro/routes/api/auth/signup/complete.mjs +6 -6
  84. package/dist/astro/routes/api/auth/signup/request.mjs +4 -4
  85. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +6 -6
  86. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +1 -1
  87. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +1 -1
  88. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +1 -1
  89. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +1 -1
  90. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +4 -4
  91. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +3 -3
  92. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +1 -1
  93. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +1 -1
  94. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +3 -3
  95. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +5 -5
  96. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +1 -1
  97. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +1 -1
  98. package/dist/astro/routes/api/content/_collection_/_id_.mjs +3 -3
  99. package/dist/astro/routes/api/content/_collection_/authors.mjs +1 -1
  100. package/dist/astro/routes/api/content/_collection_/index.mjs +3 -3
  101. package/dist/astro/routes/api/content/_collection_/trash.mjs +3 -3
  102. package/dist/astro/routes/api/dashboard.mjs +1 -1
  103. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  104. package/dist/astro/routes/api/import/probe.mjs +3 -3
  105. package/dist/astro/routes/api/import/wordpress/analyze.mjs +1 -1
  106. package/dist/astro/routes/api/import/wordpress/execute.d.mts +9 -9
  107. package/dist/astro/routes/api/import/wordpress/execute.mjs +3 -3
  108. package/dist/astro/routes/api/import/wordpress/media.mjs +3 -3
  109. package/dist/astro/routes/api/import/wordpress/prepare.mjs +3 -3
  110. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +3 -3
  111. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  112. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +3 -3
  113. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  114. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +3 -3
  115. package/dist/astro/routes/api/manifest.mjs +2 -2
  116. package/dist/astro/routes/api/mcp.mjs +18 -18
  117. package/dist/astro/routes/api/media/_id_/confirm.mjs +3 -3
  118. package/dist/astro/routes/api/media/_id_.mjs +3 -3
  119. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +1 -1
  120. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +1 -1
  121. package/dist/astro/routes/api/media/providers/index.mjs +1 -1
  122. package/dist/astro/routes/api/media/upload-url.mjs +4 -4
  123. package/dist/astro/routes/api/media.mjs +4 -4
  124. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +3 -3
  125. package/dist/astro/routes/api/menus/_name_/items.mjs +3 -3
  126. package/dist/astro/routes/api/menus/_name_/reorder.mjs +3 -3
  127. package/dist/astro/routes/api/menus/_name_/translations.mjs +3 -3
  128. package/dist/astro/routes/api/menus/_name_.mjs +3 -3
  129. package/dist/astro/routes/api/menus/index.mjs +3 -3
  130. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  131. package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
  132. package/dist/astro/routes/api/oauth/device/code.mjs +5 -5
  133. package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
  134. package/dist/astro/routes/api/oauth/register.mjs +1 -1
  135. package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
  136. package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
  137. package/dist/astro/routes/api/oauth/token.mjs +4 -4
  138. package/dist/astro/routes/api/openapi.json.mjs +1 -1
  139. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +2 -2
  140. package/dist/astro/routes/api/redirects/404s/index.mjs +4 -4
  141. package/dist/astro/routes/api/redirects/404s/summary.mjs +4 -4
  142. package/dist/astro/routes/api/redirects/_id_.mjs +4 -4
  143. package/dist/astro/routes/api/redirects/index.mjs +4 -4
  144. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +1 -1
  145. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +1 -1
  146. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +14 -14
  147. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +14 -14
  148. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +14 -14
  149. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +14 -14
  150. package/dist/astro/routes/api/schema/collections/index.mjs +14 -14
  151. package/dist/astro/routes/api/schema/index.mjs +5 -10
  152. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  153. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +14 -14
  154. package/dist/astro/routes/api/schema/orphans/index.mjs +14 -14
  155. package/dist/astro/routes/api/search/enable.mjs +5 -5
  156. package/dist/astro/routes/api/search/index.mjs +4 -4
  157. package/dist/astro/routes/api/search/rebuild.mjs +5 -5
  158. package/dist/astro/routes/api/search/stats.mjs +3 -3
  159. package/dist/astro/routes/api/search/suggest.mjs +4 -4
  160. package/dist/astro/routes/api/sections/_slug_.mjs +5 -5
  161. package/dist/astro/routes/api/sections/index.mjs +5 -5
  162. package/dist/astro/routes/api/settings/email.mjs +1 -1
  163. package/dist/astro/routes/api/settings.mjs +6 -6
  164. package/dist/astro/routes/api/setup/admin-verify.mjs +7 -7
  165. package/dist/astro/routes/api/setup/admin.mjs +6 -6
  166. package/dist/astro/routes/api/setup/dev-bypass.mjs +10 -10
  167. package/dist/astro/routes/api/setup/index.mjs +9 -9
  168. package/dist/astro/routes/api/setup/status.mjs +2 -2
  169. package/dist/astro/routes/api/snapshot.mjs +3 -3
  170. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +6 -6
  171. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +6 -6
  172. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +6 -6
  173. package/dist/astro/routes/api/taxonomies/index.mjs +6 -6
  174. package/dist/astro/routes/api/themes/preview.mjs +3 -3
  175. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  176. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  177. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  178. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +3 -3
  179. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +6 -5
  180. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  181. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +6 -5
  182. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  183. package/dist/astro/routes/api/widget-areas/_name_.mjs +4 -3
  184. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  185. package/dist/astro/routes/api/widget-areas/index.mjs +6 -5
  186. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  187. package/dist/astro/routes/api/widget-components.mjs +1 -1
  188. package/dist/astro/routes/robots.txt.mjs +3 -3
  189. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  190. package/dist/astro/routes/sitemap-_collection_.xml.mjs +12 -5
  191. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  192. package/dist/astro/routes/sitemap.xml.mjs +4 -4
  193. package/dist/astro/types.d.mts +12 -12
  194. package/dist/auth/providers/github.d.mts +1 -1
  195. package/dist/auth/providers/google.d.mts +1 -1
  196. package/dist/{authorize-C_8t2KGa.mjs → authorize-DsMSVSaY.mjs} +1 -1
  197. package/dist/{authorize-C_8t2KGa.mjs.map → authorize-DsMSVSaY.mjs.map} +1 -1
  198. package/dist/{byline-fields-C_OsR-KF.mjs → byline-fields--WxSNS79.mjs} +1 -1
  199. package/dist/{byline-fields-C_OsR-KF.mjs.map → byline-fields--WxSNS79.mjs.map} +1 -1
  200. package/dist/{byline-fields-51kg6Vuv.mjs → byline-fields-8TMtkBnH.mjs} +2 -2
  201. package/dist/{byline-fields-51kg6Vuv.mjs.map → byline-fields-8TMtkBnH.mjs.map} +1 -1
  202. package/dist/{byline-fields-DYXKDuNX.d.mts → byline-fields-DbibsvTl.d.mts} +5 -1
  203. package/dist/byline-fields-DbibsvTl.d.mts.map +1 -0
  204. package/dist/{bylines-Cx5n-WqP.mjs → bylines-BdxWCnPL.mjs} +1 -1
  205. package/dist/{bylines-Cx5n-WqP.mjs.map → bylines-BdxWCnPL.mjs.map} +1 -1
  206. package/dist/{bylines-wurS258E.mjs → bylines-s8c2DXbH.mjs} +3 -3
  207. package/dist/{bylines-wurS258E.mjs.map → bylines-s8c2DXbH.mjs.map} +1 -1
  208. package/dist/{challenge-store-DGwuCc4R.mjs → challenge-store-DXX3rfdI.mjs} +1 -1
  209. package/dist/{challenge-store-DGwuCc4R.mjs.map → challenge-store-DXX3rfdI.mjs.map} +1 -1
  210. package/dist/cli/index.mjs +11 -10
  211. package/dist/cli/index.mjs.map +1 -1
  212. package/dist/client/cf-access.d.mts +1 -1
  213. package/dist/client/index.d.mts +1 -1
  214. package/dist/client/index.mjs +1 -1
  215. package/dist/{comments-CJ0RZsYR.mjs → comments-Vkivawyl.mjs} +1 -1
  216. package/dist/{comments-CJ0RZsYR.mjs.map → comments-Vkivawyl.mjs.map} +1 -1
  217. package/dist/{components-CTfpu3PZ.mjs → components-CK0cuUoH.mjs} +1 -1
  218. package/dist/{components-CTfpu3PZ.mjs.map → components-CK0cuUoH.mjs.map} +1 -1
  219. package/dist/{context-GG52SPgh.mjs → context-Y7BRkWes.mjs} +2 -2
  220. package/dist/{context-GG52SPgh.mjs.map → context-Y7BRkWes.mjs.map} +1 -1
  221. package/dist/database/instrumentation.d.mts +10 -1
  222. package/dist/database/instrumentation.d.mts.map +1 -1
  223. package/dist/database/instrumentation.mjs +13 -1
  224. package/dist/database/instrumentation.mjs.map +1 -1
  225. package/dist/db/index.d.mts +3 -3
  226. package/dist/db/libsql.d.mts +1 -1
  227. package/dist/db/postgres.d.mts +1 -1
  228. package/dist/db/sqlite.d.mts +1 -1
  229. package/dist/{default-xLFNSsZ9.mjs → default-IlBaTFxM.mjs} +1 -1
  230. package/dist/{default-xLFNSsZ9.mjs.map → default-IlBaTFxM.mjs.map} +1 -1
  231. package/dist/{device-flow-s6_q3T7A.mjs → device-flow-R23SIbQ2.mjs} +4 -4
  232. package/dist/{device-flow-s6_q3T7A.mjs.map → device-flow-R23SIbQ2.mjs.map} +1 -1
  233. package/dist/{escape-bIyGoW5W.mjs → escape-Ds07EEyu.mjs} +1 -1
  234. package/dist/{escape-bIyGoW5W.mjs.map → escape-Ds07EEyu.mjs.map} +1 -1
  235. package/dist/{index-FfiTQJq2.d.mts → index-B1keaX5Y.d.mts} +43 -12
  236. package/dist/{index-FfiTQJq2.d.mts.map → index-B1keaX5Y.d.mts.map} +1 -1
  237. package/dist/{index-BpYeJO1E.d.mts → index-DR56od45.d.mts} +3 -3
  238. package/dist/{index-BpYeJO1E.d.mts.map → index-DR56od45.d.mts.map} +1 -1
  239. package/dist/index.d.mts +16 -16
  240. package/dist/index.mjs +22 -22
  241. package/dist/{load-B84ohfBk.mjs → load-BBetCvLC.mjs} +1 -1
  242. package/dist/{load-B84ohfBk.mjs.map → load-BBetCvLC.mjs.map} +1 -1
  243. package/dist/{loader-CpZKpFz0.mjs → loader-ZN1ll-d-.mjs} +11 -14
  244. package/dist/loader-ZN1ll-d-.mjs.map +1 -0
  245. package/dist/{manifest-schema-Cj-YrzrF.mjs → manifest-schema-BtwbL_vj.mjs} +55 -2
  246. package/dist/manifest-schema-BtwbL_vj.mjs.map +1 -0
  247. package/dist/media/index.d.mts +1 -1
  248. package/dist/media/local-runtime.d.mts +11 -11
  249. package/dist/media/local-runtime.mjs +2 -2
  250. package/dist/{media-allowlist-CMcoYIjQ.mjs → media-allowlist-Dknq-OFY.mjs} +1 -1
  251. package/dist/{media-allowlist-CMcoYIjQ.mjs.map → media-allowlist-Dknq-OFY.mjs.map} +1 -1
  252. package/dist/media-url-VClf8glU.mjs +26 -0
  253. package/dist/media-url-VClf8glU.mjs.map +1 -0
  254. package/dist/{menus-Dp9xporj.mjs → menus-DrQLusqj.mjs} +6 -33
  255. package/dist/menus-DrQLusqj.mjs.map +1 -0
  256. package/dist/{mode-BjlXswIw.mjs → mode-CO2vQHfq.mjs} +1 -1
  257. package/dist/{mode-BjlXswIw.mjs.map → mode-CO2vQHfq.mjs.map} +1 -1
  258. package/dist/{oauth-authorization-1aPAYjiC.mjs → oauth-authorization-Bw4NdF_S.mjs} +4 -4
  259. package/dist/{oauth-authorization-1aPAYjiC.mjs.map → oauth-authorization-Bw4NdF_S.mjs.map} +1 -1
  260. package/dist/{oauth-clients-8mPDStMv.mjs → oauth-clients-BGGFp57s.mjs} +1 -1
  261. package/dist/{oauth-clients-8mPDStMv.mjs.map → oauth-clients-BGGFp57s.mjs.map} +1 -1
  262. package/dist/{oauth-state-store-BJ7YtrfD.mjs → oauth-state-store-97x0xtN2.mjs} +1 -1
  263. package/dist/{oauth-state-store-BJ7YtrfD.mjs.map → oauth-state-store-97x0xtN2.mjs.map} +1 -1
  264. package/dist/{oauth-user-lookup-BdDSDvjF.mjs → oauth-user-lookup-B_vnZHKO.mjs} +1 -1
  265. package/dist/{oauth-user-lookup-BdDSDvjF.mjs.map → oauth-user-lookup-B_vnZHKO.mjs.map} +1 -1
  266. package/dist/{options-D4MnavW_.d.mts → options-DyYIYpPd.d.mts} +3 -3
  267. package/dist/{options-D4MnavW_.d.mts.map → options-DyYIYpPd.d.mts.map} +1 -1
  268. package/dist/page/index.d.mts +2 -2
  269. package/dist/{passkey-config-BDVM86Tj.mjs → passkey-config-C3QgnQnU.mjs} +1 -1
  270. package/dist/{passkey-config-BDVM86Tj.mjs.map → passkey-config-C3QgnQnU.mjs.map} +1 -1
  271. package/dist/{placeholder-B9lUUEmj.d.mts → placeholder-CVBv5z8k.d.mts} +1 -1
  272. package/dist/{placeholder-B9lUUEmj.d.mts.map → placeholder-CVBv5z8k.d.mts.map} +1 -1
  273. package/dist/plugin-types.d.mts +1 -1
  274. package/dist/plugin-utils.d.mts +9 -9
  275. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -9
  276. package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
  277. package/dist/{public-url-egRHCy1m.mjs → public-url-BFVC2OTJ.mjs} +1 -1
  278. package/dist/{public-url-egRHCy1m.mjs.map → public-url-BFVC2OTJ.mjs.map} +1 -1
  279. package/dist/{query-BFQ029Ts.mjs → query-CbUcI4Xk.mjs} +18 -8
  280. package/dist/query-CbUcI4Xk.mjs.map +1 -0
  281. package/dist/{rate-limit-ClFFUga6.mjs → rate-limit-C7hjdkS5.mjs} +1 -1
  282. package/dist/{rate-limit-ClFFUga6.mjs.map → rate-limit-C7hjdkS5.mjs.map} +1 -1
  283. package/dist/{redirect-Cw3JTlmj.mjs → redirect-B_q19j4v.mjs} +1 -1
  284. package/dist/{redirect-Cw3JTlmj.mjs.map → redirect-B_q19j4v.mjs.map} +1 -1
  285. package/dist/{redirects-DEygMrRO.mjs → redirects-CCbCqCCd.mjs} +4 -2
  286. package/dist/redirects-CCbCqCCd.mjs.map +1 -0
  287. package/dist/{redirects-OIu6vQ2i.mjs → redirects-DxVoR7PI.mjs} +1 -1
  288. package/dist/{redirects-OIu6vQ2i.mjs.map → redirects-DxVoR7PI.mjs.map} +1 -1
  289. package/dist/request-context.d.mts +7 -0
  290. package/dist/request-context.d.mts.map +1 -1
  291. package/dist/request-context.mjs +2 -1
  292. package/dist/request-context.mjs.map +1 -1
  293. package/dist/{runner-BcRuXq_h.d.mts → runner-DTdhuI9i.d.mts} +2 -2
  294. package/dist/{runner-BcRuXq_h.d.mts.map → runner-DTdhuI9i.d.mts.map} +1 -1
  295. package/dist/runtime.d.mts +10 -10
  296. package/dist/runtime.mjs +1 -1
  297. package/dist/{schema-CS7Eg5gh.mjs → schema-C1E70ug_.mjs} +2 -2
  298. package/dist/{schema-CS7Eg5gh.mjs.map → schema-C1E70ug_.mjs.map} +1 -1
  299. package/dist/{search-o-aQzHI1.mjs → search-B3SGZw91.mjs} +2 -2
  300. package/dist/{search-o-aQzHI1.mjs.map → search-B3SGZw91.mjs.map} +1 -1
  301. package/dist/{secrets-C_ZtRos3.mjs → secrets-ChPTmy9x.mjs} +1 -1
  302. package/dist/{secrets-C_ZtRos3.mjs.map → secrets-ChPTmy9x.mjs.map} +1 -1
  303. package/dist/{sections-DhsZ0ns9.mjs → sections-D_lVzwRZ.mjs} +2 -2
  304. package/dist/{sections-DhsZ0ns9.mjs.map → sections-D_lVzwRZ.mjs.map} +1 -1
  305. package/dist/seed/index.d.mts +2 -2
  306. package/dist/seed/index.mjs +6 -6
  307. package/dist/seo/index.d.mts +1 -1
  308. package/dist/seo/index.d.mts.map +1 -1
  309. package/dist/seo/index.mjs +3 -12
  310. package/dist/seo/index.mjs.map +1 -1
  311. package/dist/{seo-DfjLvu8i.mjs → seo-D_LPkOtu.mjs} +4 -3
  312. package/dist/seo-D_LPkOtu.mjs.map +1 -0
  313. package/dist/{service-DAxg8RPR.mjs → service-ChDcsTBs.mjs} +2 -2
  314. package/dist/{service-DAxg8RPR.mjs.map → service-ChDcsTBs.mjs.map} +1 -1
  315. package/dist/{settings-DIsbHTRE.mjs → settings-Cv47v9u8.mjs} +2 -2
  316. package/dist/{settings-DIsbHTRE.mjs.map → settings-Cv47v9u8.mjs.map} +1 -1
  317. package/dist/settings-DfxiWY_s.mjs +411 -0
  318. package/dist/settings-DfxiWY_s.mjs.map +1 -0
  319. package/dist/{setup-complete-Yuv78yua.mjs → setup-complete-yvPE4OsP.mjs} +1 -1
  320. package/dist/{setup-complete-Yuv78yua.mjs.map → setup-complete-yvPE4OsP.mjs.map} +1 -1
  321. package/dist/{setup-nonce-Bm0uKqmf.mjs → setup-nonce-C9aFzb94.mjs} +1 -1
  322. package/dist/{setup-nonce-Bm0uKqmf.mjs.map → setup-nonce-C9aFzb94.mjs.map} +1 -1
  323. package/dist/{site-url-mEVmwIFi.mjs → site-url-CnHlmAs9.mjs} +1 -1
  324. package/dist/{site-url-mEVmwIFi.mjs.map → site-url-CnHlmAs9.mjs.map} +1 -1
  325. package/dist/storage/local.d.mts +1 -1
  326. package/dist/storage/s3.d.mts +1 -1
  327. package/dist/{taxonomies-UusDXv3C.mjs → taxonomies-BILwiyGk.mjs} +2 -2
  328. package/dist/{taxonomies-UusDXv3C.mjs.map → taxonomies-BILwiyGk.mjs.map} +1 -1
  329. package/dist/{taxonomies-BEW7S5AI.mjs → taxonomies-BdAmbOwx.mjs} +46 -9
  330. package/dist/taxonomies-BdAmbOwx.mjs.map +1 -0
  331. package/dist/{transport-BwQeeY2p.d.mts → transport-B7PPP2CC.d.mts} +1 -1
  332. package/dist/{transport-BwQeeY2p.d.mts.map → transport-B7PPP2CC.d.mts.map} +1 -1
  333. package/dist/{transport--Ck3RBin.mjs → transport-CmpLD7W3.mjs} +1 -1
  334. package/dist/{transport--Ck3RBin.mjs.map → transport-CmpLD7W3.mjs.map} +1 -1
  335. package/dist/{types-DWnN7weG.d.mts → types-BFgrqwSk.d.mts} +1 -1
  336. package/dist/{types-DWnN7weG.d.mts.map → types-BFgrqwSk.d.mts.map} +1 -1
  337. package/dist/{types-Qa7-HJJC.d.mts → types-BH8-30hc.d.mts} +1 -1
  338. package/dist/{types-Qa7-HJJC.d.mts.map → types-BH8-30hc.d.mts.map} +1 -1
  339. package/dist/{types-OT_Es5mp.d.mts → types-BPzXTV9x.d.mts} +1 -1
  340. package/dist/{types-OT_Es5mp.d.mts.map → types-BPzXTV9x.d.mts.map} +1 -1
  341. package/dist/{types-DbCWhHet.d.mts → types-BUUVn1zr.d.mts} +2 -2
  342. package/dist/types-BUUVn1zr.d.mts.map +1 -0
  343. package/dist/{types-DMwSpvcw.d.mts → types-CPAPl93j.d.mts} +9 -3
  344. package/dist/{types-DMwSpvcw.d.mts.map → types-CPAPl93j.d.mts.map} +1 -1
  345. package/dist/types-CZI4E3qG.mjs +3 -0
  346. package/dist/{types-kwqCOUxj.d.mts → types-D4kUqbHh.d.mts} +1 -1
  347. package/dist/{types-kwqCOUxj.d.mts.map → types-D4kUqbHh.d.mts.map} +1 -1
  348. package/dist/{types-WVmpZBJV.d.mts → types-DTniiNto.d.mts} +2 -2
  349. package/dist/{types-WVmpZBJV.d.mts.map → types-DTniiNto.d.mts.map} +1 -1
  350. package/dist/types-DZk_y-MU.mjs.map +1 -1
  351. package/dist/{types-DX6v9KzJ.d.mts → types-S15DXXNi.d.mts} +1 -1
  352. package/dist/{types-DX6v9KzJ.d.mts.map → types-S15DXXNi.d.mts.map} +1 -1
  353. package/dist/{validate-ZP9Dvg0P.mjs → validate-Bz4vqcX1.mjs} +1 -1
  354. package/dist/{validate-ZP9Dvg0P.mjs.map → validate-Bz4vqcX1.mjs.map} +1 -1
  355. package/dist/{validate-BPAHUSge.d.mts → validate-CNwkPWzz.d.mts} +5 -5
  356. package/dist/{validate-BPAHUSge.d.mts.map → validate-CNwkPWzz.d.mts.map} +1 -1
  357. package/dist/{validation-CE5i4q0c.mjs → validation-DgGTJm3u.mjs} +1 -1
  358. package/dist/{validation-CE5i4q0c.mjs.map → validation-DgGTJm3u.mjs.map} +1 -1
  359. package/dist/version-D-5txk2m.mjs +7 -0
  360. package/dist/{version-Dw0JXu45.mjs.map → version-D-5txk2m.mjs.map} +1 -1
  361. package/dist/{widgets-ClEnYQCH.mjs → widgets-DZfmAbE4.mjs} +47 -44
  362. package/dist/widgets-DZfmAbE4.mjs.map +1 -0
  363. package/package.json +10 -10
  364. package/src/api/handlers/marketplace.ts +2 -5
  365. package/src/api/handlers/registry.ts +70 -0
  366. package/src/api/handlers/seo.ts +9 -1
  367. package/src/api/schemas/schema.ts +13 -1
  368. package/src/astro/middleware.ts +20 -6
  369. package/src/astro/routes/api/schema/index.ts +7 -15
  370. package/src/astro/routes/sitemap-[collection].xml.ts +13 -2
  371. package/src/cli/commands/bundle-utils.ts +2 -0
  372. package/src/cli/commands/secrets.ts +2 -2
  373. package/src/database/instrumentation.ts +13 -0
  374. package/src/emdash-runtime.ts +31 -25
  375. package/src/loader.ts +24 -15
  376. package/src/plugins/manifest-schema.ts +75 -0
  377. package/src/plugins/marketplace.ts +2 -5
  378. package/src/plugins/types.ts +12 -0
  379. package/src/query.ts +13 -2
  380. package/src/request-context.ts +8 -0
  381. package/src/schema/types.ts +11 -1
  382. package/src/seo/index.ts +2 -28
  383. package/src/seo/media-url.ts +32 -0
  384. package/src/settings/index.ts +32 -40
  385. package/src/taxonomies/index.ts +78 -12
  386. package/src/utils/isolate-cache.ts +189 -0
  387. package/src/widgets/index.ts +57 -54
  388. package/dist/api-BZ6bhjYs.mjs.map +0 -1
  389. package/dist/byline-fields-DYXKDuNX.d.mts.map +0 -1
  390. package/dist/loader-CpZKpFz0.mjs.map +0 -1
  391. package/dist/manifest-schema-Cj-YrzrF.mjs.map +0 -1
  392. package/dist/menus-Dp9xporj.mjs.map +0 -1
  393. package/dist/query-BFQ029Ts.mjs.map +0 -1
  394. package/dist/redirects-DEygMrRO.mjs.map +0 -1
  395. package/dist/seo-DfjLvu8i.mjs.map +0 -1
  396. package/dist/settings-B1p-gPUK.mjs +0 -235
  397. package/dist/settings-B1p-gPUK.mjs.map +0 -1
  398. package/dist/taxonomies-BEW7S5AI.mjs.map +0 -1
  399. package/dist/types-Cj2S6FuC.mjs +0 -3
  400. package/dist/types-DbCWhHet.d.mts.map +0 -1
  401. package/dist/version-Dw0JXu45.mjs +0 -7
  402. package/dist/widgets-ClEnYQCH.mjs.map +0 -1
  403. /package/dist/{api-tokens-B6VgoE6M.mjs → api-tokens-Oq39ba-Z.mjs} +0 -0
@@ -5,11 +5,12 @@ import "../../types-BXSUSAjt.mjs";
5
5
  import "../../media-JOf3pNkw.mjs";
6
6
  import "../../options-BPCVnesz.mjs";
7
7
  import "../../request-cache-D32LpnmI.mjs";
8
- import "../../loader-CpZKpFz0.mjs";
9
- import { t as handleSitemapData } from "../../seo-DfjLvu8i.mjs";
10
- import { a as getSiteSettingsWithDb } from "../../settings-B1p-gPUK.mjs";
8
+ import "../../loader-ZN1ll-d-.mjs";
9
+ import { t as handleSitemapData } from "../../seo-D_LPkOtu.mjs";
10
+ import { a as getSiteSettingsWithDb } from "../../settings-DfxiWY_s.mjs";
11
11
  import { n as localizePath, t as interpolateUrlPattern } from "../../resolve-BqYMVG0D.mjs";
12
- import { n as getPublicOrigin } from "../../public-url-egRHCy1m.mjs";
12
+ import { t as buildSeoImageUrl } from "../../media-url-VClf8glU.mjs";
13
+ import { n as getPublicOrigin } from "../../public-url-BFVC2OTJ.mjs";
13
14
 
14
15
  //#region src/astro/routes/sitemap-[collection].xml.ts
15
16
  const prerender = false;
@@ -62,13 +63,19 @@ const GET = async ({ params, locals, url }) => {
62
63
  };
63
64
  const useXhtml = i18nEnabled;
64
65
  const lines = ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>"];
65
- lines.push(useXhtml ? "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">" : "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
66
+ lines.push(useXhtml ? "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\">" : "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\">");
66
67
  const writeUrl = async (entry, siblings) => {
67
68
  const loc = await resolveEntryUrl(entry);
68
69
  if (loc === null) return;
69
70
  lines.push(" <url>");
70
71
  lines.push(` <loc>${escapeXml(loc)}</loc>`);
71
72
  lines.push(` <lastmod>${escapeXml(entry.updatedAt)}</lastmod>`);
73
+ if (entry.image) {
74
+ const imageLoc = buildSeoImageUrl(entry.image, siteUrl);
75
+ lines.push(" <image:image>");
76
+ lines.push(` <image:loc>${escapeXml(imageLoc)}</image:loc>`);
77
+ lines.push(" </image:image>");
78
+ }
72
79
  if (useXhtml && siblings && siblings.length > 1) {
73
80
  for (const sib of siblings) {
74
81
  const sibLoc = await resolveEntryUrl(sib);
@@ -1 +1 @@
1
- {"version":3,"file":"sitemap-_collection_.xml.mjs","names":[],"sources":["../../../src/astro/routes/sitemap-[collection].xml.ts"],"sourcesContent":["/**\n * Per-collection sitemap endpoint\n *\n * GET /sitemap-{collection}.xml - Sitemap for a single content collection.\n *\n * Uses the collection's url_pattern to build URLs. Falls back to\n * /{collection}/{slug} when no pattern is configured.\n *\n * i18n behaviour: when Astro i18n is enabled, the locale prefix is\n * applied via Astro's own `getRelativeLocaleUrl` (which honours\n * `prefixDefaultLocale`, custom `path` mappings, and other `routing`\n * config). Each translation row is emitted as its own `<url>` with\n * `<xhtml:link rel=\"alternate\" hreflang=\"...\">` entries pointing to\n * its siblings (grouped by `translation_group`). The default-locale\n * variant is also linked as `hreflang=\"x-default\"`.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { handleSitemapData } from \"#api/handlers/seo.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { getSiteSettingsWithDb } from \"#settings/index.js\";\n\nimport { getI18nConfig, isI18nEnabled } from \"../../i18n/config.js\";\nimport { interpolateUrlPattern, localizePath } from \"../../i18n/resolve.js\";\n\nexport const prerender = false;\n\nconst TRAILING_SLASH_RE = /\\/$/;\nconst AMP_RE = /&/g;\nconst LT_RE = /</g;\nconst GT_RE = />/g;\nconst QUOT_RE = /\"/g;\nconst APOS_RE = /'/g;\n\nexport const GET: APIRoute = async ({ params, locals, url }) => {\n\tconst { emdash } = locals;\n\tconst collectionSlug = params.collection;\n\n\tif (!emdash?.db || !collectionSlug) {\n\t\treturn new Response(\"<!-- EmDash not configured -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n\n\ttry {\n\t\tconst settings = await getSiteSettingsWithDb(emdash.db);\n\t\tconst siteUrl = (settings.url || getPublicOrigin(url, emdash?.config)).replace(\n\t\t\tTRAILING_SLASH_RE,\n\t\t\t\"\",\n\t\t);\n\n\t\tconst result = await handleSitemapData(emdash.db, collectionSlug);\n\n\t\tif (!result.success || !result.data) {\n\t\t\treturn new Response(\"<!-- Failed to generate sitemap -->\", {\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t\t});\n\t\t}\n\n\t\tconst col = result.data.collections[0];\n\t\tif (!col) {\n\t\t\treturn new Response(\"<!-- Collection not found or empty -->\", {\n\t\t\t\tstatus: 404,\n\t\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t\t});\n\t\t}\n\n\t\tconst i18nEnabled = isI18nEnabled();\n\t\tconst i18nConfig = getI18nConfig();\n\n\t\t// Group entries by `translation_group` so each <url> can advertise\n\t\t// its sibling translations via xhtml:link. Rows without a group\n\t\t// (legacy/single-locale data) are emitted individually.\n\t\ttype Entry = (typeof col.entries)[number];\n\t\tconst groups = new Map<string, Entry[]>();\n\t\tconst ungrouped: Entry[] = [];\n\t\tfor (const entry of col.entries) {\n\t\t\tif (i18nEnabled && entry.translationGroup) {\n\t\t\t\tconst list = groups.get(entry.translationGroup);\n\t\t\t\tif (list) list.push(entry);\n\t\t\t\telse groups.set(entry.translationGroup, [entry]);\n\t\t\t} else {\n\t\t\t\tungrouped.push(entry);\n\t\t\t}\n\t\t}\n\n\t\t// Resolve every URL up-front so we can reference sibling URLs\n\t\t// while emitting hreflang alternates without re-resolving.\n\t\t// `localizePath` returns `null` when the row's locale isn't in\n\t\t// the configured `i18n.locales` list -- the site can't serve a\n\t\t// route for it, so the entry is dropped from the sitemap and\n\t\t// omitted from sibling alternates.\n\t\tconst urlByEntry = new Map<string, string | null>();\n\t\tconst resolveEntryUrl = async (entry: Entry): Promise<string | null> => {\n\t\t\tif (urlByEntry.has(entry.id)) return urlByEntry.get(entry.id) ?? null;\n\t\t\tconst path = interpolateUrlPattern({\n\t\t\t\tpattern: col.urlPattern,\n\t\t\t\tcollection: col.collection,\n\t\t\t\tslug: entry.slug || entry.id,\n\t\t\t\tid: entry.id,\n\t\t\t});\n\t\t\tconst localized = await localizePath(path, entry.locale);\n\t\t\tconst absolute = localized === null ? null : `${siteUrl}${localized}`;\n\t\t\turlByEntry.set(entry.id, absolute);\n\t\t\treturn absolute;\n\t\t};\n\n\t\tconst useXhtml = i18nEnabled;\n\t\tconst lines: string[] = ['<?xml version=\"1.0\" encoding=\"UTF-8\"?>'];\n\t\tlines.push(\n\t\t\tuseXhtml\n\t\t\t\t? '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">'\n\t\t\t\t: '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">',\n\t\t);\n\n\t\tconst writeUrl = async (entry: Entry, siblings: Entry[] | null) => {\n\t\t\tconst loc = await resolveEntryUrl(entry);\n\t\t\t// Skip rows whose locale isn't in the configured `i18n.locales`\n\t\t\t// list. Linking to a route the site can't serve is worse than\n\t\t\t// no link at all (search engines hit a 404 and downrank).\n\t\t\tif (loc === null) return;\n\n\t\t\tlines.push(\" <url>\");\n\t\t\tlines.push(` <loc>${escapeXml(loc)}</loc>`);\n\t\t\tlines.push(` <lastmod>${escapeXml(entry.updatedAt)}</lastmod>`);\n\n\t\t\tif (useXhtml && siblings && siblings.length > 1) {\n\t\t\t\t// Emit one xhtml:link per sibling (including self -- Google\n\t\t\t\t// recommends including the page's own hreflang annotation).\n\t\t\t\t// Siblings with unroutable locales are skipped here too.\n\t\t\t\tfor (const sib of siblings) {\n\t\t\t\t\tconst sibLoc = await resolveEntryUrl(sib);\n\t\t\t\t\tif (sibLoc === null) continue;\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t` <xhtml:link rel=\"alternate\" hreflang=\"${escapeXml(sib.locale)}\" href=\"${escapeXml(sibLoc)}\" />`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// x-default: prefer the default-locale sibling, otherwise\n\t\t\t\t// the first sibling with a routable URL. Stable order:\n\t\t\t\t// rows arrive sorted by updated_at DESC from the handler.\n\t\t\t\tconst defaultSibling =\n\t\t\t\t\ti18nConfig && siblings.find((s) => s.locale === i18nConfig.defaultLocale);\n\t\t\t\tlet xDefaultLoc: string | null = null;\n\t\t\t\tif (defaultSibling) {\n\t\t\t\t\txDefaultLoc = await resolveEntryUrl(defaultSibling);\n\t\t\t\t}\n\t\t\t\tif (xDefaultLoc === null) {\n\t\t\t\t\tfor (const sib of siblings) {\n\t\t\t\t\t\tconst sibLoc = await resolveEntryUrl(sib);\n\t\t\t\t\t\tif (sibLoc !== null) {\n\t\t\t\t\t\t\txDefaultLoc = sibLoc;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (xDefaultLoc !== null) {\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t` <xhtml:link rel=\"alternate\" hreflang=\"x-default\" href=\"${escapeXml(xDefaultLoc)}\" />`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(\" </url>\");\n\t\t};\n\n\t\tfor (const siblings of groups.values()) {\n\t\t\tfor (const entry of siblings) {\n\t\t\t\tawait writeUrl(entry, siblings);\n\t\t\t}\n\t\t}\n\t\tfor (const entry of ungrouped) {\n\t\t\tawait writeUrl(entry, null);\n\t\t}\n\n\t\tlines.push(\"</urlset>\");\n\n\t\treturn new Response(lines.join(\"\\n\"), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/xml; charset=utf-8\",\n\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t},\n\t\t});\n\t} catch {\n\t\treturn new Response(\"<!-- Internal error generating sitemap -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n};\n\n/** Escape special XML characters in a string */\nfunction escapeXml(str: string): string {\n\treturn str\n\t\t.replace(AMP_RE, \"&amp;\")\n\t\t.replace(LT_RE, \"&lt;\")\n\t\t.replace(GT_RE, \"&gt;\")\n\t\t.replace(QUOT_RE, \"&quot;\")\n\t\t.replace(APOS_RE, \"&apos;\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sitemap-_collection_.xml.mjs","names":[],"sources":["../../../src/astro/routes/sitemap-[collection].xml.ts"],"sourcesContent":["/**\n * Per-collection sitemap endpoint\n *\n * GET /sitemap-{collection}.xml - Sitemap for a single content collection.\n *\n * Uses the collection's url_pattern to build URLs. Falls back to\n * /{collection}/{slug} when no pattern is configured.\n *\n * i18n behaviour: when Astro i18n is enabled, the locale prefix is\n * applied via Astro's own `getRelativeLocaleUrl` (which honours\n * `prefixDefaultLocale`, custom `path` mappings, and other `routing`\n * config). Each translation row is emitted as its own `<url>` with\n * `<xhtml:link rel=\"alternate\" hreflang=\"...\">` entries pointing to\n * its siblings (grouped by `translation_group`). The default-locale\n * variant is also linked as `hreflang=\"x-default\"`.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { handleSitemapData } from \"#api/handlers/seo.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\nimport { getSiteSettingsWithDb } from \"#settings/index.js\";\n\nimport { getI18nConfig, isI18nEnabled } from \"../../i18n/config.js\";\nimport { interpolateUrlPattern, localizePath } from \"../../i18n/resolve.js\";\nimport { buildSeoImageUrl } from \"../../seo/media-url.js\";\n\nexport const prerender = false;\n\nconst TRAILING_SLASH_RE = /\\/$/;\nconst AMP_RE = /&/g;\nconst LT_RE = /</g;\nconst GT_RE = />/g;\nconst QUOT_RE = /\"/g;\nconst APOS_RE = /'/g;\n\nexport const GET: APIRoute = async ({ params, locals, url }) => {\n\tconst { emdash } = locals;\n\tconst collectionSlug = params.collection;\n\n\tif (!emdash?.db || !collectionSlug) {\n\t\treturn new Response(\"<!-- EmDash not configured -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n\n\ttry {\n\t\tconst settings = await getSiteSettingsWithDb(emdash.db);\n\t\tconst siteUrl = (settings.url || getPublicOrigin(url, emdash?.config)).replace(\n\t\t\tTRAILING_SLASH_RE,\n\t\t\t\"\",\n\t\t);\n\n\t\tconst result = await handleSitemapData(emdash.db, collectionSlug);\n\n\t\tif (!result.success || !result.data) {\n\t\t\treturn new Response(\"<!-- Failed to generate sitemap -->\", {\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t\t});\n\t\t}\n\n\t\tconst col = result.data.collections[0];\n\t\tif (!col) {\n\t\t\treturn new Response(\"<!-- Collection not found or empty -->\", {\n\t\t\t\tstatus: 404,\n\t\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t\t});\n\t\t}\n\n\t\tconst i18nEnabled = isI18nEnabled();\n\t\tconst i18nConfig = getI18nConfig();\n\n\t\t// Group entries by `translation_group` so each <url> can advertise\n\t\t// its sibling translations via xhtml:link. Rows without a group\n\t\t// (legacy/single-locale data) are emitted individually.\n\t\ttype Entry = (typeof col.entries)[number];\n\t\tconst groups = new Map<string, Entry[]>();\n\t\tconst ungrouped: Entry[] = [];\n\t\tfor (const entry of col.entries) {\n\t\t\tif (i18nEnabled && entry.translationGroup) {\n\t\t\t\tconst list = groups.get(entry.translationGroup);\n\t\t\t\tif (list) list.push(entry);\n\t\t\t\telse groups.set(entry.translationGroup, [entry]);\n\t\t\t} else {\n\t\t\t\tungrouped.push(entry);\n\t\t\t}\n\t\t}\n\n\t\t// Resolve every URL up-front so we can reference sibling URLs\n\t\t// while emitting hreflang alternates without re-resolving.\n\t\t// `localizePath` returns `null` when the row's locale isn't in\n\t\t// the configured `i18n.locales` list -- the site can't serve a\n\t\t// route for it, so the entry is dropped from the sitemap and\n\t\t// omitted from sibling alternates.\n\t\tconst urlByEntry = new Map<string, string | null>();\n\t\tconst resolveEntryUrl = async (entry: Entry): Promise<string | null> => {\n\t\t\tif (urlByEntry.has(entry.id)) return urlByEntry.get(entry.id) ?? null;\n\t\t\tconst path = interpolateUrlPattern({\n\t\t\t\tpattern: col.urlPattern,\n\t\t\t\tcollection: col.collection,\n\t\t\t\tslug: entry.slug || entry.id,\n\t\t\t\tid: entry.id,\n\t\t\t});\n\t\t\tconst localized = await localizePath(path, entry.locale);\n\t\t\tconst absolute = localized === null ? null : `${siteUrl}${localized}`;\n\t\t\turlByEntry.set(entry.id, absolute);\n\t\t\treturn absolute;\n\t\t};\n\n\t\tconst useXhtml = i18nEnabled;\n\t\tconst lines: string[] = ['<?xml version=\"1.0\" encoding=\"UTF-8\"?>'];\n\t\tlines.push(\n\t\t\tuseXhtml\n\t\t\t\t? '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\">'\n\t\t\t\t: '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\">',\n\t\t);\n\n\t\tconst writeUrl = async (entry: Entry, siblings: Entry[] | null) => {\n\t\t\tconst loc = await resolveEntryUrl(entry);\n\t\t\t// Skip rows whose locale isn't in the configured `i18n.locales`\n\t\t\t// list. Linking to a route the site can't serve is worse than\n\t\t\t// no link at all (search engines hit a 404 and downrank).\n\t\t\tif (loc === null) return;\n\n\t\t\tlines.push(\" <url>\");\n\t\t\tlines.push(` <loc>${escapeXml(loc)}</loc>`);\n\t\t\tlines.push(` <lastmod>${escapeXml(entry.updatedAt)}</lastmod>`);\n\n\t\t\t// Google image sitemap extension: advertise the entry's SEO\n\t\t\t// image (the same \"preferred image\" used for og:image) so it\n\t\t\t// can be discovered and indexed for Google Images.\n\t\t\tif (entry.image) {\n\t\t\t\tconst imageLoc = buildSeoImageUrl(entry.image, siteUrl);\n\t\t\t\tlines.push(\" <image:image>\");\n\t\t\t\tlines.push(` <image:loc>${escapeXml(imageLoc)}</image:loc>`);\n\t\t\t\tlines.push(\" </image:image>\");\n\t\t\t}\n\n\t\t\tif (useXhtml && siblings && siblings.length > 1) {\n\t\t\t\t// Emit one xhtml:link per sibling (including self -- Google\n\t\t\t\t// recommends including the page's own hreflang annotation).\n\t\t\t\t// Siblings with unroutable locales are skipped here too.\n\t\t\t\tfor (const sib of siblings) {\n\t\t\t\t\tconst sibLoc = await resolveEntryUrl(sib);\n\t\t\t\t\tif (sibLoc === null) continue;\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t` <xhtml:link rel=\"alternate\" hreflang=\"${escapeXml(sib.locale)}\" href=\"${escapeXml(sibLoc)}\" />`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// x-default: prefer the default-locale sibling, otherwise\n\t\t\t\t// the first sibling with a routable URL. Stable order:\n\t\t\t\t// rows arrive sorted by updated_at DESC from the handler.\n\t\t\t\tconst defaultSibling =\n\t\t\t\t\ti18nConfig && siblings.find((s) => s.locale === i18nConfig.defaultLocale);\n\t\t\t\tlet xDefaultLoc: string | null = null;\n\t\t\t\tif (defaultSibling) {\n\t\t\t\t\txDefaultLoc = await resolveEntryUrl(defaultSibling);\n\t\t\t\t}\n\t\t\t\tif (xDefaultLoc === null) {\n\t\t\t\t\tfor (const sib of siblings) {\n\t\t\t\t\t\tconst sibLoc = await resolveEntryUrl(sib);\n\t\t\t\t\t\tif (sibLoc !== null) {\n\t\t\t\t\t\t\txDefaultLoc = sibLoc;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (xDefaultLoc !== null) {\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t` <xhtml:link rel=\"alternate\" hreflang=\"x-default\" href=\"${escapeXml(xDefaultLoc)}\" />`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlines.push(\" </url>\");\n\t\t};\n\n\t\tfor (const siblings of groups.values()) {\n\t\t\tfor (const entry of siblings) {\n\t\t\t\tawait writeUrl(entry, siblings);\n\t\t\t}\n\t\t}\n\t\tfor (const entry of ungrouped) {\n\t\t\tawait writeUrl(entry, null);\n\t\t}\n\n\t\tlines.push(\"</urlset>\");\n\n\t\treturn new Response(lines.join(\"\\n\"), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/xml; charset=utf-8\",\n\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t},\n\t\t});\n\t} catch {\n\t\treturn new Response(\"<!-- Internal error generating sitemap -->\", {\n\t\t\tstatus: 500,\n\t\t\theaders: { \"Content-Type\": \"application/xml\" },\n\t\t});\n\t}\n};\n\n/** Escape special XML characters in a string */\nfunction escapeXml(str: string): string {\n\treturn str\n\t\t.replace(AMP_RE, \"&amp;\")\n\t\t.replace(LT_RE, \"&lt;\")\n\t\t.replace(GT_RE, \"&gt;\")\n\t\t.replace(QUOT_RE, \"&quot;\")\n\t\t.replace(APOS_RE, \"&apos;\");\n}\n"],"mappings":"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"}
@@ -4,10 +4,10 @@ import "../../types-BXSUSAjt.mjs";
4
4
  import "../../media-JOf3pNkw.mjs";
5
5
  import "../../options-BPCVnesz.mjs";
6
6
  import "../../request-cache-D32LpnmI.mjs";
7
- import "../../loader-CpZKpFz0.mjs";
8
- import { t as handleSitemapData } from "../../seo-DfjLvu8i.mjs";
9
- import { a as getSiteSettingsWithDb } from "../../settings-B1p-gPUK.mjs";
10
- import { n as getPublicOrigin } from "../../public-url-egRHCy1m.mjs";
7
+ import "../../loader-ZN1ll-d-.mjs";
8
+ import { t as handleSitemapData } from "../../seo-D_LPkOtu.mjs";
9
+ import { a as getSiteSettingsWithDb } from "../../settings-DfxiWY_s.mjs";
10
+ import { n as getPublicOrigin } from "../../public-url-BFVC2OTJ.mjs";
11
11
 
12
12
  //#region src/astro/routes/sitemap.xml.ts
13
13
  const prerender = false;
@@ -1,15 +1,15 @@
1
- import { i as ContentItem } from "../types-WVmpZBJV.mjs";
2
- import { d as ContentListResponse, f as ContentResponse } from "../options-D4MnavW_.mjs";
3
- import { t as Database } from "../types-OT_Es5mp.mjs";
4
- import { J as PageFragmentContribution, Z as PageMetadataContribution, ht as PublicPageContext, jt as Element, yt as ResolvedPlugin } from "../types-DMwSpvcw.mjs";
5
- import "../byline-fields-DYXKDuNX.mjs";
6
- import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-B9lUUEmj.mjs";
7
- import { $r as MediaItem, Bt as EmDashConfig, Ft as HookPipeline, Pt as EmailPipeline, cr as MediaListResponse, lr as MediaResponse, qn as SandboxRunner } from "../index-FfiTQJq2.mjs";
8
- import "../runner-BcRuXq_h.mjs";
9
- import "../index-BpYeJO1E.mjs";
10
- import { d as Storage } from "../types-kwqCOUxj.mjs";
11
- import "../types-DWnN7weG.mjs";
12
- import "../validate-BPAHUSge.mjs";
1
+ import { i as ContentItem } from "../types-DTniiNto.mjs";
2
+ import { d as ContentListResponse, f as ContentResponse } from "../options-DyYIYpPd.mjs";
3
+ import { t as Database } from "../types-BPzXTV9x.mjs";
4
+ import { J as PageFragmentContribution, Z as PageMetadataContribution, ht as PublicPageContext, jt as Element, yt as ResolvedPlugin } from "../types-CPAPl93j.mjs";
5
+ import "../byline-fields-DbibsvTl.mjs";
6
+ import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-CVBv5z8k.mjs";
7
+ import { $r as MediaItem, Bt as EmDashConfig, Ft as HookPipeline, Pt as EmailPipeline, cr as MediaListResponse, lr as MediaResponse, qn as SandboxRunner } from "../index-B1keaX5Y.mjs";
8
+ import "../runner-DTdhuI9i.mjs";
9
+ import "../index-DR56od45.mjs";
10
+ import { d as Storage } from "../types-D4kUqbHh.mjs";
11
+ import "../types-BFgrqwSk.mjs";
12
+ import "../validate-CNwkPWzz.mjs";
13
13
  import "../index.mjs";
14
14
  import { Kysely } from "kysely";
15
15
 
@@ -1,4 +1,4 @@
1
- import { r as AuthProviderDescriptor } from "../../types-Qa7-HJJC.mjs";
1
+ import { r as AuthProviderDescriptor } from "../../types-BH8-30hc.mjs";
2
2
 
3
3
  //#region src/auth/providers/github.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { r as AuthProviderDescriptor } from "../../types-Qa7-HJJC.mjs";
1
+ import { r as AuthProviderDescriptor } from "../../types-BH8-30hc.mjs";
2
2
 
3
3
  //#region src/auth/providers/google.d.ts
4
4
  /**
@@ -34,4 +34,4 @@ function requireOwnerPerm(user, ownerId, ownPermission, anyPermission) {
34
34
 
35
35
  //#endregion
36
36
  export { requirePerm as n, requireOwnerPerm as t };
37
- //# sourceMappingURL=authorize-C_8t2KGa.mjs.map
37
+ //# sourceMappingURL=authorize-DsMSVSaY.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"authorize-C_8t2KGa.mjs","names":[],"sources":["../src/api/authorize.ts"],"sourcesContent":["/**\n * Authorization helpers for API routes\n *\n * Thin wrappers around @emdash-cms/auth RBAC that return HTTP responses.\n * Auth middleware handles authentication; these handle authorization.\n */\n\nimport type { Permission, RoleLevel } from \"@emdash-cms/auth\";\nimport { hasPermission, canActOnOwn } from \"@emdash-cms/auth\";\n\nimport { apiError } from \"./error.js\";\n\ninterface UserLike {\n\tid: string;\n\trole: RoleLevel;\n}\n\n/**\n * Check if user has a permission. Returns a 401/403 Response if not, or null if authorized.\n *\n * Usage:\n * ```ts\n * const denied = requirePerm(user, \"schema:manage\");\n * if (denied) return denied;\n * ```\n */\nexport function requirePerm(\n\tuser: UserLike | null | undefined,\n\tpermission: Permission,\n): Response | null {\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\tif (!hasPermission(user, permission)) {\n\t\treturn apiError(\"FORBIDDEN\", \"Insufficient permissions\", 403);\n\t}\n\treturn null;\n}\n\n/**\n * Check if user can act on a resource, considering ownership.\n * Returns a 401/403 Response if not, or null if authorized.\n *\n * Usage:\n * ```ts\n * const denied = requireOwnerPerm(user, item.authorId, \"content:edit_own\", \"content:edit_any\");\n * if (denied) return denied;\n * ```\n */\nexport function requireOwnerPerm(\n\tuser: UserLike | null | undefined,\n\townerId: string,\n\townPermission: Permission,\n\tanyPermission: Permission,\n): Response | null {\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\tif (!canActOnOwn(user, ownerId, ownPermission, anyPermission)) {\n\t\treturn apiError(\"FORBIDDEN\", \"Insufficient permissions\", 403);\n\t}\n\treturn null;\n}\n"],"mappings":";;;;;;;;;;;;;AA0BA,SAAgB,YACf,MACA,YACkB;AAClB,KAAI,CAAC,KACJ,QAAO,SAAS,gBAAgB,2BAA2B,IAAI;AAEhE,KAAI,CAAC,cAAc,MAAM,WAAW,CACnC,QAAO,SAAS,aAAa,4BAA4B,IAAI;AAE9D,QAAO;;;;;;;;;;;;AAaR,SAAgB,iBACf,MACA,SACA,eACA,eACkB;AAClB,KAAI,CAAC,KACJ,QAAO,SAAS,gBAAgB,2BAA2B,IAAI;AAEhE,KAAI,CAAC,YAAY,MAAM,SAAS,eAAe,cAAc,CAC5D,QAAO,SAAS,aAAa,4BAA4B,IAAI;AAE9D,QAAO"}
1
+ {"version":3,"file":"authorize-DsMSVSaY.mjs","names":[],"sources":["../src/api/authorize.ts"],"sourcesContent":["/**\n * Authorization helpers for API routes\n *\n * Thin wrappers around @emdash-cms/auth RBAC that return HTTP responses.\n * Auth middleware handles authentication; these handle authorization.\n */\n\nimport type { Permission, RoleLevel } from \"@emdash-cms/auth\";\nimport { hasPermission, canActOnOwn } from \"@emdash-cms/auth\";\n\nimport { apiError } from \"./error.js\";\n\ninterface UserLike {\n\tid: string;\n\trole: RoleLevel;\n}\n\n/**\n * Check if user has a permission. Returns a 401/403 Response if not, or null if authorized.\n *\n * Usage:\n * ```ts\n * const denied = requirePerm(user, \"schema:manage\");\n * if (denied) return denied;\n * ```\n */\nexport function requirePerm(\n\tuser: UserLike | null | undefined,\n\tpermission: Permission,\n): Response | null {\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\tif (!hasPermission(user, permission)) {\n\t\treturn apiError(\"FORBIDDEN\", \"Insufficient permissions\", 403);\n\t}\n\treturn null;\n}\n\n/**\n * Check if user can act on a resource, considering ownership.\n * Returns a 401/403 Response if not, or null if authorized.\n *\n * Usage:\n * ```ts\n * const denied = requireOwnerPerm(user, item.authorId, \"content:edit_own\", \"content:edit_any\");\n * if (denied) return denied;\n * ```\n */\nexport function requireOwnerPerm(\n\tuser: UserLike | null | undefined,\n\townerId: string,\n\townPermission: Permission,\n\tanyPermission: Permission,\n): Response | null {\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\tif (!canActOnOwn(user, ownerId, ownPermission, anyPermission)) {\n\t\treturn apiError(\"FORBIDDEN\", \"Insufficient permissions\", 403);\n\t}\n\treturn null;\n}\n"],"mappings":";;;;;;;;;;;;;AA0BA,SAAgB,YACf,MACA,YACkB;AAClB,KAAI,CAAC,KACJ,QAAO,SAAS,gBAAgB,2BAA2B,IAAI;AAEhE,KAAI,CAAC,cAAc,MAAM,WAAW,CACnC,QAAO,SAAS,aAAa,4BAA4B,IAAI;AAE9D,QAAO;;;;;;;;;;;;AAaR,SAAgB,iBACf,MACA,SACA,eACA,eACkB;AAClB,KAAI,CAAC,KACJ,QAAO,SAAS,gBAAgB,2BAA2B,IAAI;AAEhE,KAAI,CAAC,YAAY,MAAM,SAAS,eAAe,cAAc,CAC5D,QAAO,SAAS,aAAa,4BAA4B,IAAI;AAE9D,QAAO"}
@@ -120,4 +120,4 @@ async function handleBylineFieldReorder(db, slugs) {
120
120
 
121
121
  //#endregion
122
122
  export { handleBylineFieldReorder as a, handleBylineFieldList as i, handleBylineFieldDelete as n, handleBylineFieldUpdate as o, handleBylineFieldGet as r, handleBylineFieldUsage as s, handleBylineFieldCreate as t };
123
- //# sourceMappingURL=byline-fields-C_OsR-KF.mjs.map
123
+ //# sourceMappingURL=byline-fields--WxSNS79.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"byline-fields-C_OsR-KF.mjs","names":[],"sources":["../src/api/handlers/byline-fields.ts"],"sourcesContent":["/**\n * Handler layer for the byline-fields admin API (Phase 4 of Discussion\n * #1174).\n *\n * Each handler:\n * - Takes the `Kysely<Database>` from the route, returns `ApiResult<T>`.\n * - Wraps the registry call in try/catch.\n * - Translates `BylineSchemaError` → shared `ErrorCode` via\n * `mapBylineSchemaError`. HTTP status comes from `mapErrorStatus` at\n * the route's `unwrapResult` site — handlers don't know about\n * statuses.\n * - Catches everything else, logs server-side, returns a 500-class\n * code without leaking `error.message`.\n *\n * Reserved-slug + identifier validation runs at the zod layer (see\n * `schemas/byline-fields.ts`); the registry repeats it for defence in\n * depth (non-HTTP callers). This module assumes inputs have already\n * passed through whichever zod schema the route used.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../../database/types.js\";\nimport {\n\tBylineSchemaError,\n\tBylineSchemaRegistry,\n\tmapBylineSchemaError,\n} from \"../../schema/byline-registry.js\";\nimport type {\n\tBylineFieldDefinition,\n\tCreateBylineFieldInput,\n\tUpdateBylineFieldInput,\n} from \"../../schema/types.js\";\nimport type { ApiResult } from \"../types.js\";\n\n/**\n * Build a structured failure envelope from a `BylineSchemaError`.\n * Centralised so every handler emits the same shape.\n */\nfunction bylineSchemaErrorResult<T>(error: BylineSchemaError): ApiResult<T> {\n\tconst mapped = mapBylineSchemaError(error);\n\treturn {\n\t\tsuccess: false,\n\t\terror: { code: mapped.code, message: mapped.message, details: mapped.details },\n\t};\n}\n\n/**\n * Build a 500-class failure envelope. Logs the underlying error\n * server-side; the message returned to the client is the static\n * fallback to avoid leaking internals.\n */\nfunction internalErrorResult<T>(\n\terror: unknown,\n\tcode: string,\n\tfallbackMessage: string,\n): ApiResult<T> {\n\tconsole.error(`[${code}]`, error);\n\treturn {\n\t\tsuccess: false,\n\t\terror: { code, message: fallbackMessage },\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// List\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<{ items: BylineFieldDefinition[] }>> {\n\ttry {\n\t\tconst items = await new BylineSchemaRegistry(db).listFields();\n\t\treturn { success: true, data: { items } };\n\t} catch (error) {\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_LIST_ERROR\", \"Failed to list byline fields\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Create\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateBylineFieldInput,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).createField(input);\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_CREATE_ERROR\", \"Failed to create byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Get one\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldGet(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).getField(slug);\n\t\tif (!field) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline field not found\" },\n\t\t\t};\n\t\t}\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_GET_ERROR\", \"Failed to get byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Update\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldUpdate(\n\tdb: Kysely<Database>,\n\tslug: string,\n\tinput: UpdateBylineFieldInput,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).updateField(slug, input);\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_UPDATE_ERROR\", \"Failed to update byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Delete\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldDelete(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<ApiResult<{ deleted: true }>> {\n\ttry {\n\t\tawait new BylineSchemaRegistry(db).deleteField(slug);\n\t\treturn { success: true, data: { deleted: true } };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_DELETE_ERROR\", \"Failed to delete byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldUsage(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<\n\tApiResult<{\n\t\ttranslatableValueCount: number;\n\t\tgroupValueCount: number;\n\t\ttotalAffectedRows: number;\n\t}>\n> {\n\ttry {\n\t\tconst usage = await new BylineSchemaRegistry(db).getFieldUsage(slug);\n\t\treturn { success: true, data: usage };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(\n\t\t\terror,\n\t\t\t\"SCHEMA_FIELD_GET_ERROR\",\n\t\t\t\"Failed to read byline field usage\",\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Reorder\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldReorder(\n\tdb: Kysely<Database>,\n\tslugs: string[],\n): Promise<ApiResult<{ items: BylineFieldDefinition[] }>> {\n\ttry {\n\t\tconst registry = new BylineSchemaRegistry(db);\n\t\tawait registry.reorderFields(slugs);\n\t\tconst items = await registry.listFields();\n\t\treturn { success: true, data: { items } };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(\n\t\t\terror,\n\t\t\t\"SCHEMA_FIELD_REORDER_ERROR\",\n\t\t\t\"Failed to reorder byline fields\",\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;AAuCA,SAAS,wBAA2B,OAAwC;CAC3E,MAAM,SAAS,qBAAqB,MAAM;AAC1C,QAAO;EACN,SAAS;EACT,OAAO;GAAE,MAAM,OAAO;GAAM,SAAS,OAAO;GAAS,SAAS,OAAO;GAAS;EAC9E;;;;;;;AAQF,SAAS,oBACR,OACA,MACA,iBACe;AACf,SAAQ,MAAM,IAAI,KAAK,IAAI,MAAM;AACjC,QAAO;EACN,SAAS;EACT,OAAO;GAAE;GAAM,SAAS;GAAiB;EACzC;;AAOF,eAAsB,sBACrB,IACyD;AACzD,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,OADlB,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,EACtB;GAAE;UACjC,OAAO;AACf,SAAO,oBAAoB,OAAO,2BAA2B,+BAA+B;;;AAQ9F,eAAsB,wBACrB,IACA,OAC4C;AAC5C,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,MAAM;GAC9B;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,qBACrB,IACA,MAC4C;AAC5C,KAAI;EACH,MAAM,QAAQ,MAAM,IAAI,qBAAqB,GAAG,CAAC,SAAS,KAAK;AAC/D,MAAI,CAAC,MACJ,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAa,SAAS;IAA0B;GAC/D;AAEF,SAAO;GAAE,SAAS;GAAM,MAAM;GAAO;UAC7B,OAAO;AACf,SAAO,oBAAoB,OAAO,0BAA0B,6BAA6B;;;AAQ3F,eAAsB,wBACrB,IACA,MACA,OAC4C;AAC5C,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,MAAM,MAAM;GACpC;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,wBACrB,IACA,MACwC;AACxC,KAAI;AACH,QAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,KAAK;AACpD,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,SAAS,MAAM;GAAE;UACzC,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,uBACrB,IACA,MAOC;AACD,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,cAAc,KAAK;GAC/B;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBACN,OACA,0BACA,oCACA;;;AAQH,eAAsB,yBACrB,IACA,OACyD;AACzD,KAAI;EACH,MAAM,WAAW,IAAI,qBAAqB,GAAG;AAC7C,QAAM,SAAS,cAAc,MAAM;AAEnC,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,OADlB,MAAM,SAAS,YAAY,EACF;GAAE;UACjC,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBACN,OACA,8BACA,kCACA"}
1
+ {"version":3,"file":"byline-fields--WxSNS79.mjs","names":[],"sources":["../src/api/handlers/byline-fields.ts"],"sourcesContent":["/**\n * Handler layer for the byline-fields admin API (Phase 4 of Discussion\n * #1174).\n *\n * Each handler:\n * - Takes the `Kysely<Database>` from the route, returns `ApiResult<T>`.\n * - Wraps the registry call in try/catch.\n * - Translates `BylineSchemaError` → shared `ErrorCode` via\n * `mapBylineSchemaError`. HTTP status comes from `mapErrorStatus` at\n * the route's `unwrapResult` site — handlers don't know about\n * statuses.\n * - Catches everything else, logs server-side, returns a 500-class\n * code without leaking `error.message`.\n *\n * Reserved-slug + identifier validation runs at the zod layer (see\n * `schemas/byline-fields.ts`); the registry repeats it for defence in\n * depth (non-HTTP callers). This module assumes inputs have already\n * passed through whichever zod schema the route used.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport type { Database } from \"../../database/types.js\";\nimport {\n\tBylineSchemaError,\n\tBylineSchemaRegistry,\n\tmapBylineSchemaError,\n} from \"../../schema/byline-registry.js\";\nimport type {\n\tBylineFieldDefinition,\n\tCreateBylineFieldInput,\n\tUpdateBylineFieldInput,\n} from \"../../schema/types.js\";\nimport type { ApiResult } from \"../types.js\";\n\n/**\n * Build a structured failure envelope from a `BylineSchemaError`.\n * Centralised so every handler emits the same shape.\n */\nfunction bylineSchemaErrorResult<T>(error: BylineSchemaError): ApiResult<T> {\n\tconst mapped = mapBylineSchemaError(error);\n\treturn {\n\t\tsuccess: false,\n\t\terror: { code: mapped.code, message: mapped.message, details: mapped.details },\n\t};\n}\n\n/**\n * Build a 500-class failure envelope. Logs the underlying error\n * server-side; the message returned to the client is the static\n * fallback to avoid leaking internals.\n */\nfunction internalErrorResult<T>(\n\terror: unknown,\n\tcode: string,\n\tfallbackMessage: string,\n): ApiResult<T> {\n\tconsole.error(`[${code}]`, error);\n\treturn {\n\t\tsuccess: false,\n\t\terror: { code, message: fallbackMessage },\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// List\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldList(\n\tdb: Kysely<Database>,\n): Promise<ApiResult<{ items: BylineFieldDefinition[] }>> {\n\ttry {\n\t\tconst items = await new BylineSchemaRegistry(db).listFields();\n\t\treturn { success: true, data: { items } };\n\t} catch (error) {\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_LIST_ERROR\", \"Failed to list byline fields\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Create\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateBylineFieldInput,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).createField(input);\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_CREATE_ERROR\", \"Failed to create byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Get one\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldGet(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).getField(slug);\n\t\tif (!field) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline field not found\" },\n\t\t\t};\n\t\t}\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_GET_ERROR\", \"Failed to get byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Update\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldUpdate(\n\tdb: Kysely<Database>,\n\tslug: string,\n\tinput: UpdateBylineFieldInput,\n): Promise<ApiResult<BylineFieldDefinition>> {\n\ttry {\n\t\tconst field = await new BylineSchemaRegistry(db).updateField(slug, input);\n\t\treturn { success: true, data: field };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_UPDATE_ERROR\", \"Failed to update byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Delete\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldDelete(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<ApiResult<{ deleted: true }>> {\n\ttry {\n\t\tawait new BylineSchemaRegistry(db).deleteField(slug);\n\t\treturn { success: true, data: { deleted: true } };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(error, \"SCHEMA_FIELD_DELETE_ERROR\", \"Failed to delete byline field\");\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Usage\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldUsage(\n\tdb: Kysely<Database>,\n\tslug: string,\n): Promise<\n\tApiResult<{\n\t\ttranslatableValueCount: number;\n\t\tgroupValueCount: number;\n\t\ttotalAffectedRows: number;\n\t}>\n> {\n\ttry {\n\t\tconst usage = await new BylineSchemaRegistry(db).getFieldUsage(slug);\n\t\treturn { success: true, data: usage };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(\n\t\t\terror,\n\t\t\t\"SCHEMA_FIELD_GET_ERROR\",\n\t\t\t\"Failed to read byline field usage\",\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Reorder\n// ---------------------------------------------------------------------------\n\nexport async function handleBylineFieldReorder(\n\tdb: Kysely<Database>,\n\tslugs: string[],\n): Promise<ApiResult<{ items: BylineFieldDefinition[] }>> {\n\ttry {\n\t\tconst registry = new BylineSchemaRegistry(db);\n\t\tawait registry.reorderFields(slugs);\n\t\tconst items = await registry.listFields();\n\t\treturn { success: true, data: { items } };\n\t} catch (error) {\n\t\tif (error instanceof BylineSchemaError) {\n\t\t\treturn bylineSchemaErrorResult(error);\n\t\t}\n\t\treturn internalErrorResult(\n\t\t\terror,\n\t\t\t\"SCHEMA_FIELD_REORDER_ERROR\",\n\t\t\t\"Failed to reorder byline fields\",\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;AAuCA,SAAS,wBAA2B,OAAwC;CAC3E,MAAM,SAAS,qBAAqB,MAAM;AAC1C,QAAO;EACN,SAAS;EACT,OAAO;GAAE,MAAM,OAAO;GAAM,SAAS,OAAO;GAAS,SAAS,OAAO;GAAS;EAC9E;;;;;;;AAQF,SAAS,oBACR,OACA,MACA,iBACe;AACf,SAAQ,MAAM,IAAI,KAAK,IAAI,MAAM;AACjC,QAAO;EACN,SAAS;EACT,OAAO;GAAE;GAAM,SAAS;GAAiB;EACzC;;AAOF,eAAsB,sBACrB,IACyD;AACzD,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,OADlB,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,EACtB;GAAE;UACjC,OAAO;AACf,SAAO,oBAAoB,OAAO,2BAA2B,+BAA+B;;;AAQ9F,eAAsB,wBACrB,IACA,OAC4C;AAC5C,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,MAAM;GAC9B;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,qBACrB,IACA,MAC4C;AAC5C,KAAI;EACH,MAAM,QAAQ,MAAM,IAAI,qBAAqB,GAAG,CAAC,SAAS,KAAK;AAC/D,MAAI,CAAC,MACJ,QAAO;GACN,SAAS;GACT,OAAO;IAAE,MAAM;IAAa,SAAS;IAA0B;GAC/D;AAEF,SAAO;GAAE,SAAS;GAAM,MAAM;GAAO;UAC7B,OAAO;AACf,SAAO,oBAAoB,OAAO,0BAA0B,6BAA6B;;;AAQ3F,eAAsB,wBACrB,IACA,MACA,OAC4C;AAC5C,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,MAAM,MAAM;GACpC;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,wBACrB,IACA,MACwC;AACxC,KAAI;AACH,QAAM,IAAI,qBAAqB,GAAG,CAAC,YAAY,KAAK;AACpD,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,SAAS,MAAM;GAAE;UACzC,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBAAoB,OAAO,6BAA6B,gCAAgC;;;AAQjG,eAAsB,uBACrB,IACA,MAOC;AACD,KAAI;AAEH,SAAO;GAAE,SAAS;GAAM,MADV,MAAM,IAAI,qBAAqB,GAAG,CAAC,cAAc,KAAK;GAC/B;UAC7B,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBACN,OACA,0BACA,oCACA;;;AAQH,eAAsB,yBACrB,IACA,OACyD;AACzD,KAAI;EACH,MAAM,WAAW,IAAI,qBAAqB,GAAG;AAC7C,QAAM,SAAS,cAAc,MAAM;AAEnC,SAAO;GAAE,SAAS;GAAM,MAAM,EAAE,OADlB,MAAM,SAAS,YAAY,EACF;GAAE;UACjC,OAAO;AACf,MAAI,iBAAiB,kBACpB,QAAO,wBAAwB,MAAM;AAEtC,SAAO,oBACN,OACA,8BACA,kCACA"}
@@ -1,5 +1,5 @@
1
1
  import { i as RESERVED_BYLINE_FIELD_SLUGS } from "./types-DZk_y-MU.mjs";
2
- import { In as roleLevel, Mn as httpUrl } from "./redirects-DEygMrRO.mjs";
2
+ import { In as roleLevel, Mn as httpUrl } from "./redirects-CCbCqCCd.mjs";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/api/schemas/auth.ts
@@ -235,4 +235,4 @@ const bylineFieldUsageResponseSchema = z.object({
235
235
 
236
236
  //#endregion
237
237
  export { passkeyOptionsBody as C, passkeyVerifyBody as D, passkeyRenameBody as E, signupCompleteBody as O, magicLinkSendBody as S, passkeyRegisterVerifyBody as T, wpRewriteUrlsBody as _, bylineFieldUpdateBody as a, inviteCreateBody as b, setupAdminBody as c, setupBody as d, importProbeBody as f, wpPrepareBody as g, wpPluginExecuteBody as h, bylineFieldReorderBody as i, signupRequestBody as k, setupAdminVerifyBody as l, wpPluginAnalyzeBody as m, bylineFieldDefinitionSchema as n, bylineFieldUsageResponseSchema as o, wpMediaImportBody as p, bylineFieldListResponseSchema as r, atprotoLoginBody as s, bylineFieldCreateBody as t, setupAtprotoAdminBody as u, authMeActionBody as v, passkeyRegisterOptionsBody as w, inviteRegisterOptionsBody as x, inviteCompleteBody as y };
238
- //# sourceMappingURL=byline-fields-51kg6Vuv.mjs.map
238
+ //# sourceMappingURL=byline-fields-8TMtkBnH.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"byline-fields-51kg6Vuv.mjs","names":["authenticatorTransport","registrationCredential"],"sources":["../src/api/schemas/auth.ts","../src/api/schemas/import.ts","../src/api/schemas/setup.ts","../src/api/schemas/byline-fields.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { roleLevel } from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// WebAuthn credential schemas (matching @emdash-cms/auth/passkey types)\n// ---------------------------------------------------------------------------\n\nconst authenticatorTransport = z.enum([\"usb\", \"nfc\", \"ble\", \"internal\", \"hybrid\"]);\n\n/** RegistrationResponse — sent by the browser after navigator.credentials.create() */\nconst registrationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tattestationObject: z.string(),\n\t\ttransports: z.array(authenticatorTransport).optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\n/** AuthenticationResponse — sent by the browser after navigator.credentials.get() */\nconst authenticationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tauthenticatorData: z.string(),\n\t\tsignature: z.string(),\n\t\tuserHandle: z.string().optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Auth: Input schemas\n// ---------------------------------------------------------------------------\n\nexport const signupRequestBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t})\n\t.meta({ id: \"SignupRequestBody\" });\n\nexport const signupCompleteBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"SignupCompleteBody\" });\n\nexport const inviteCreateBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t\trole: roleLevel.optional(),\n\t})\n\t.meta({ id: \"InviteCreateBody\" });\n\nexport const inviteRegisterOptionsBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"InviteRegisterOptionsBody\" });\n\nexport const inviteCompleteBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"InviteCompleteBody\" });\n\nexport const magicLinkSendBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t})\n\t.meta({ id: \"MagicLinkSendBody\" });\n\nexport const passkeyOptionsBody = z\n\t.object({\n\t\temail: z.string().email().optional(),\n\t})\n\t.meta({ id: \"PasskeyOptionsBody\" });\n\nexport const passkeyVerifyBody = z\n\t.object({\n\t\tcredential: authenticationCredential,\n\t})\n\t.meta({ id: \"PasskeyVerifyBody\" });\n\nexport const passkeyRegisterOptionsBody = z\n\t.object({\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"PasskeyRegisterOptionsBody\" });\n\nexport const passkeyRegisterVerifyBody = z\n\t.object({\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"PasskeyRegisterVerifyBody\" });\n\nexport const passkeyRenameBody = z\n\t.object({\n\t\tname: z.string().min(1),\n\t})\n\t.meta({ id: \"PasskeyRenameBody\" });\n\nexport const authMeActionBody = z\n\t.object({\n\t\taction: z.string().min(1),\n\t})\n\t.meta({ id: \"AuthMeActionBody\" });\n","import { z } from \"zod\";\n\nimport { httpUrl } from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// Import\n// ---------------------------------------------------------------------------\n\nexport const importProbeBody = z.object({\n\turl: httpUrl,\n});\n\nexport const wpPluginAnalyzeBody = z.object({\n\turl: httpUrl,\n\ttoken: z.string().min(1),\n});\n\nexport const wpPluginExecuteBody = z.object({\n\turl: httpUrl,\n\ttoken: z.string().min(1),\n\tconfig: z.record(z.string(), z.unknown()),\n});\n\nexport const wpPrepareBody = z.object({\n\tpostTypes: z.array(\n\t\tz.object({\n\t\t\tname: z.string().min(1),\n\t\t\tcollection: z.string().min(1),\n\t\t\tfields: z\n\t\t\t\t.array(\n\t\t\t\t\tz.object({\n\t\t\t\t\t\tslug: z.string().min(1),\n\t\t\t\t\t\tlabel: z.string().min(1),\n\t\t\t\t\t\ttype: z.string().min(1),\n\t\t\t\t\t\trequired: z.boolean(),\n\t\t\t\t\t\tsearchable: z.boolean().optional(),\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.optional(),\n\t\t}),\n\t),\n});\n\nexport const wpMediaImportBody = z.object({\n\tattachments: z.array(z.record(z.string(), z.unknown())),\n\tstream: z.boolean().optional(),\n});\n\nexport const wpRewriteUrlsBody = z.object({\n\turlMap: z.record(z.string(), z.string()),\n\tcollections: z.array(z.string()).optional(),\n});\n","import { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Setup\n// ---------------------------------------------------------------------------\n\n/** Registration credential — duplicated reference for setup flow.\n * The canonical definition lives in auth.ts but setup needs it independently\n * because setup runs before auth is configured. */\nconst authenticatorTransport = z.enum([\"usb\", \"nfc\", \"ble\", \"internal\", \"hybrid\"]);\n\nconst registrationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tattestationObject: z.string(),\n\t\ttransports: z.array(authenticatorTransport).optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\nexport const setupBody = z.object({\n\ttitle: z.string().min(1),\n\ttagline: z.string().optional(),\n\tincludeContent: z.boolean(),\n});\n\nexport const setupAdminBody = z.object({\n\temail: z.string().email(),\n\tname: z.string().optional(),\n});\n\nexport const setupAdminVerifyBody = z.object({\n\tcredential: registrationCredential,\n});\n\nexport const atprotoLoginBody = z.object({\n\thandle: z.string().trim().min(1),\n});\n\nexport const setupAtprotoAdminBody = z.object({\n\thandle: z.string().trim().min(1),\n});\n","/**\n * Zod schemas for the byline-fields admin API (Discussion #1174, Phase 4).\n *\n * Reserved-slug + identifier validation runs at the zod layer so the\n * route returns a clean 400 (`VALIDATION_ERROR` from `parseBody`) rather\n * than bubbling a registry-level `BylineSchemaError` (\"RESERVED_SLUG\" /\n * \"INVALID_SLUG\"). The registry repeats the same checks for non-HTTP\n * callers (seeds, scripts) — see `BylineSchemaRegistry.validateSlug`.\n *\n * Field types are constrained to the v1 subset declared in\n * `BYLINE_FIELD_TYPES`. Adding a type to the union there will require a\n * corresponding update to this enum.\n */\n\nimport { z } from \"zod\";\n\nimport { BYLINE_FIELD_TYPES, RESERVED_BYLINE_FIELD_SLUGS } from \"../../schema/types.js\";\n\n/**\n * Slug pattern for byline field definitions — matches the identifier rule\n * used by `validateIdentifier` (and `slugPattern` in `common.ts`).\n * Lowercase letters, digits, and underscores; must start with a letter.\n */\nconst bylineFieldSlugPattern = /^[a-z][a-z0-9_]*$/;\n\n/** Hard cap on a slug — mirrors `BylineSchemaRegistry.MAX_SLUG_LENGTH`. */\nconst MAX_SLUG_LENGTH = 63;\n/** Hard cap on a label — mirrors `BylineSchemaRegistry.MAX_LABEL_LENGTH`. */\nconst MAX_LABEL_LENGTH = 200;\n/** Hard cap on a select field's `options` list. */\nconst MAX_SELECT_OPTIONS = 200;\n\nconst RESERVED_SET: ReadonlySet<string> = new Set(RESERVED_BYLINE_FIELD_SLUGS);\n\n// Enumerate the v1 byline field types explicitly so zod gets the exact\n// literal union for `z.infer<>`. Mirrors `BYLINE_FIELD_TYPES`; CI's\n// type-checker catches drift via the satisfies/import below.\nconst bylineFieldTypeValues = z.enum([\"string\", \"text\", \"url\", \"boolean\", \"select\"]);\n// Compile-time guard: a drift here trips the satisfies check.\ntype _BylineFieldTypeDriftCheck =\n\t(typeof BYLINE_FIELD_TYPES)[number] extends z.infer<typeof bylineFieldTypeValues>\n\t\t? z.infer<typeof bylineFieldTypeValues> extends (typeof BYLINE_FIELD_TYPES)[number]\n\t\t\t? true\n\t\t\t: never\n\t\t: never;\nconst _bylineFieldTypeDriftCheck: _BylineFieldTypeDriftCheck = true;\nvoid _bylineFieldTypeDriftCheck;\n\n/**\n * Validation payload for a byline custom field. v1 only exposes\n * `options` (used by `select`-type fields). Empty/duplicate options are\n * rejected at the registry layer; the zod layer only enforces shape and\n * caps. Future field types may add keys here.\n */\nconst bylineFieldValidationSchema = z\n\t.object({\n\t\toptions: z\n\t\t\t.array(z.string().min(1))\n\t\t\t.min(1, \"select options must contain at least one entry\")\n\t\t\t.max(MAX_SELECT_OPTIONS, `select options cannot exceed ${MAX_SELECT_OPTIONS} entries`)\n\t\t\t.optional(),\n\t})\n\t.strict()\n\t.nullable();\n\n/**\n * Slug validation chain shared by create + reorder bodies. Centralised so\n * the reserved-slug message and pattern are identical everywhere.\n */\nconst bylineFieldSlug = z\n\t.string()\n\t.min(1, \"Byline field slug is required\")\n\t.max(MAX_SLUG_LENGTH, `Byline field slug must be ${MAX_SLUG_LENGTH} characters or less`)\n\t.regex(\n\t\tbylineFieldSlugPattern,\n\t\t\"Byline field slug must contain only lowercase letters, digits, and underscores, and start with a letter\",\n\t)\n\t.refine((slug) => !RESERVED_SET.has(slug), {\n\t\t// Surface the offending slug in the validation issue path-message\n\t\t// for easier debugging from the admin UI's error toast.\n\t\tmessage: \"Byline field slug is reserved\",\n\t});\n\nconst bylineFieldLabel = z\n\t.string()\n\t.min(1, \"Byline field label is required\")\n\t.max(MAX_LABEL_LENGTH, `Byline field label must be ${MAX_LABEL_LENGTH} characters or less`);\n\n// ---------------------------------------------------------------------------\n// Request bodies\n// ---------------------------------------------------------------------------\n\nexport const bylineFieldCreateBody = z\n\t.object({\n\t\tslug: bylineFieldSlug,\n\t\tlabel: bylineFieldLabel,\n\t\ttype: bylineFieldTypeValues,\n\t\trequired: z.boolean().optional(),\n\t\t/**\n\t\t * Whether values are stored per-locale (translatable, default) or\n\t\t * shared across the translation group. See `BylineFieldDefinition`.\n\t\t */\n\t\ttranslatable: z.boolean().optional(),\n\t\tvalidation: bylineFieldValidationSchema.optional(),\n\t\tsortOrder: z.number().int().min(0).optional(),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldCreateBody\" });\n\n/**\n * Update body. `slug` and `type` are intentionally absent — both are\n * immutable post-create (changing them would invalidate stored values).\n * `translatable` flips are gated at the registry layer when value rows\n * exist (`TRANSLATABLE_LOCKED`).\n */\nexport const bylineFieldUpdateBody = z\n\t.object({\n\t\tlabel: bylineFieldLabel.optional(),\n\t\trequired: z.boolean().optional(),\n\t\ttranslatable: z.boolean().optional(),\n\t\tvalidation: bylineFieldValidationSchema.optional(),\n\t\tsortOrder: z.number().int().min(0).optional(),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldUpdateBody\" });\n\nexport const bylineFieldReorderBody = z\n\t.object({\n\t\t/**\n\t\t * Exact set of currently registered slugs in the desired order.\n\t\t * The registry rejects any drift (`REORDER_MISMATCH`); the zod\n\t\t * layer enforces slug shape only. An empty array is permitted —\n\t\t * `reorderFields([])` is a valid no-op when zero fields are\n\t\t * registered (registry contract). Rejecting empty here would\n\t\t * produce a spurious 400 for an admin UI that submits a reorder\n\t\t * after deleting the last field.\n\t\t */\n\t\tslugs: z.array(bylineFieldSlug),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldReorderBody\" });\n\n// ---------------------------------------------------------------------------\n// Response shapes\n// ---------------------------------------------------------------------------\n\nexport const bylineFieldDefinitionSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tslug: z.string(),\n\t\tlabel: z.string(),\n\t\ttype: bylineFieldTypeValues,\n\t\trequired: z.boolean(),\n\t\ttranslatable: z.boolean(),\n\t\tvalidation: z\n\t\t\t.object({\n\t\t\t\toptions: z.array(z.string()).optional(),\n\t\t\t})\n\t\t\t.nullable(),\n\t\tsortOrder: z.number().int(),\n\t\tcreatedAt: z.string(),\n\t\tupdatedAt: z.string(),\n\t})\n\t.meta({ id: \"BylineFieldDefinition\" });\n\nexport const bylineFieldListResponseSchema = z\n\t.object({\n\t\titems: z.array(bylineFieldDefinitionSchema),\n\t})\n\t.meta({ id: \"BylineFieldListResponse\" });\n\n/**\n * Response shape for `GET /api/admin/byline-fields/[slug]/usage`.\n *\n * `translatableValueCount` counts rows in `_emdash_byline_field_values`.\n * `groupValueCount` counts rows in `_emdash_byline_field_group_values`.\n * `totalAffectedRows` is the sum — what the destructive-delete confirm\n * dialog surfaces. Both individual counts are exposed for diagnostic\n * value (e.g. inconsistency with the field's current `translatable`\n * flag would show non-zero on the \"wrong\" side).\n */\nexport const bylineFieldUsageResponseSchema = z\n\t.object({\n\t\ttranslatableValueCount: z.number().int().nonnegative(),\n\t\tgroupValueCount: z.number().int().nonnegative(),\n\t\ttotalAffectedRows: z.number().int().nonnegative(),\n\t})\n\t.meta({ id: \"BylineFieldUsageResponse\" });\n"],"mappings":"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"}
1
+ {"version":3,"file":"byline-fields-8TMtkBnH.mjs","names":["authenticatorTransport","registrationCredential"],"sources":["../src/api/schemas/auth.ts","../src/api/schemas/import.ts","../src/api/schemas/setup.ts","../src/api/schemas/byline-fields.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { roleLevel } from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// WebAuthn credential schemas (matching @emdash-cms/auth/passkey types)\n// ---------------------------------------------------------------------------\n\nconst authenticatorTransport = z.enum([\"usb\", \"nfc\", \"ble\", \"internal\", \"hybrid\"]);\n\n/** RegistrationResponse — sent by the browser after navigator.credentials.create() */\nconst registrationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tattestationObject: z.string(),\n\t\ttransports: z.array(authenticatorTransport).optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\n/** AuthenticationResponse — sent by the browser after navigator.credentials.get() */\nconst authenticationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tauthenticatorData: z.string(),\n\t\tsignature: z.string(),\n\t\tuserHandle: z.string().optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Auth: Input schemas\n// ---------------------------------------------------------------------------\n\nexport const signupRequestBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t})\n\t.meta({ id: \"SignupRequestBody\" });\n\nexport const signupCompleteBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"SignupCompleteBody\" });\n\nexport const inviteCreateBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t\trole: roleLevel.optional(),\n\t})\n\t.meta({ id: \"InviteCreateBody\" });\n\nexport const inviteRegisterOptionsBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"InviteRegisterOptionsBody\" });\n\nexport const inviteCompleteBody = z\n\t.object({\n\t\ttoken: z.string().min(1),\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"InviteCompleteBody\" });\n\nexport const magicLinkSendBody = z\n\t.object({\n\t\temail: z.string().email(),\n\t})\n\t.meta({ id: \"MagicLinkSendBody\" });\n\nexport const passkeyOptionsBody = z\n\t.object({\n\t\temail: z.string().email().optional(),\n\t})\n\t.meta({ id: \"PasskeyOptionsBody\" });\n\nexport const passkeyVerifyBody = z\n\t.object({\n\t\tcredential: authenticationCredential,\n\t})\n\t.meta({ id: \"PasskeyVerifyBody\" });\n\nexport const passkeyRegisterOptionsBody = z\n\t.object({\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"PasskeyRegisterOptionsBody\" });\n\nexport const passkeyRegisterVerifyBody = z\n\t.object({\n\t\tcredential: registrationCredential,\n\t\tname: z.string().optional(),\n\t})\n\t.meta({ id: \"PasskeyRegisterVerifyBody\" });\n\nexport const passkeyRenameBody = z\n\t.object({\n\t\tname: z.string().min(1),\n\t})\n\t.meta({ id: \"PasskeyRenameBody\" });\n\nexport const authMeActionBody = z\n\t.object({\n\t\taction: z.string().min(1),\n\t})\n\t.meta({ id: \"AuthMeActionBody\" });\n","import { z } from \"zod\";\n\nimport { httpUrl } from \"./common.js\";\n\n// ---------------------------------------------------------------------------\n// Import\n// ---------------------------------------------------------------------------\n\nexport const importProbeBody = z.object({\n\turl: httpUrl,\n});\n\nexport const wpPluginAnalyzeBody = z.object({\n\turl: httpUrl,\n\ttoken: z.string().min(1),\n});\n\nexport const wpPluginExecuteBody = z.object({\n\turl: httpUrl,\n\ttoken: z.string().min(1),\n\tconfig: z.record(z.string(), z.unknown()),\n});\n\nexport const wpPrepareBody = z.object({\n\tpostTypes: z.array(\n\t\tz.object({\n\t\t\tname: z.string().min(1),\n\t\t\tcollection: z.string().min(1),\n\t\t\tfields: z\n\t\t\t\t.array(\n\t\t\t\t\tz.object({\n\t\t\t\t\t\tslug: z.string().min(1),\n\t\t\t\t\t\tlabel: z.string().min(1),\n\t\t\t\t\t\ttype: z.string().min(1),\n\t\t\t\t\t\trequired: z.boolean(),\n\t\t\t\t\t\tsearchable: z.boolean().optional(),\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.optional(),\n\t\t}),\n\t),\n});\n\nexport const wpMediaImportBody = z.object({\n\tattachments: z.array(z.record(z.string(), z.unknown())),\n\tstream: z.boolean().optional(),\n});\n\nexport const wpRewriteUrlsBody = z.object({\n\turlMap: z.record(z.string(), z.string()),\n\tcollections: z.array(z.string()).optional(),\n});\n","import { z } from \"zod\";\n\n// ---------------------------------------------------------------------------\n// Setup\n// ---------------------------------------------------------------------------\n\n/** Registration credential — duplicated reference for setup flow.\n * The canonical definition lives in auth.ts but setup needs it independently\n * because setup runs before auth is configured. */\nconst authenticatorTransport = z.enum([\"usb\", \"nfc\", \"ble\", \"internal\", \"hybrid\"]);\n\nconst registrationCredential = z.object({\n\tid: z.string(),\n\trawId: z.string(),\n\ttype: z.literal(\"public-key\"),\n\tresponse: z.object({\n\t\tclientDataJSON: z.string(),\n\t\tattestationObject: z.string(),\n\t\ttransports: z.array(authenticatorTransport).optional(),\n\t}),\n\tauthenticatorAttachment: z.enum([\"platform\", \"cross-platform\"]).optional(),\n});\n\nexport const setupBody = z.object({\n\ttitle: z.string().min(1),\n\ttagline: z.string().optional(),\n\tincludeContent: z.boolean(),\n});\n\nexport const setupAdminBody = z.object({\n\temail: z.string().email(),\n\tname: z.string().optional(),\n});\n\nexport const setupAdminVerifyBody = z.object({\n\tcredential: registrationCredential,\n});\n\nexport const atprotoLoginBody = z.object({\n\thandle: z.string().trim().min(1),\n});\n\nexport const setupAtprotoAdminBody = z.object({\n\thandle: z.string().trim().min(1),\n});\n","/**\n * Zod schemas for the byline-fields admin API (Discussion #1174, Phase 4).\n *\n * Reserved-slug + identifier validation runs at the zod layer so the\n * route returns a clean 400 (`VALIDATION_ERROR` from `parseBody`) rather\n * than bubbling a registry-level `BylineSchemaError` (\"RESERVED_SLUG\" /\n * \"INVALID_SLUG\"). The registry repeats the same checks for non-HTTP\n * callers (seeds, scripts) — see `BylineSchemaRegistry.validateSlug`.\n *\n * Field types are constrained to the v1 subset declared in\n * `BYLINE_FIELD_TYPES`. Adding a type to the union there will require a\n * corresponding update to this enum.\n */\n\nimport { z } from \"zod\";\n\nimport { BYLINE_FIELD_TYPES, RESERVED_BYLINE_FIELD_SLUGS } from \"../../schema/types.js\";\n\n/**\n * Slug pattern for byline field definitions — matches the identifier rule\n * used by `validateIdentifier` (and `slugPattern` in `common.ts`).\n * Lowercase letters, digits, and underscores; must start with a letter.\n */\nconst bylineFieldSlugPattern = /^[a-z][a-z0-9_]*$/;\n\n/** Hard cap on a slug — mirrors `BylineSchemaRegistry.MAX_SLUG_LENGTH`. */\nconst MAX_SLUG_LENGTH = 63;\n/** Hard cap on a label — mirrors `BylineSchemaRegistry.MAX_LABEL_LENGTH`. */\nconst MAX_LABEL_LENGTH = 200;\n/** Hard cap on a select field's `options` list. */\nconst MAX_SELECT_OPTIONS = 200;\n\nconst RESERVED_SET: ReadonlySet<string> = new Set(RESERVED_BYLINE_FIELD_SLUGS);\n\n// Enumerate the v1 byline field types explicitly so zod gets the exact\n// literal union for `z.infer<>`. Mirrors `BYLINE_FIELD_TYPES`; CI's\n// type-checker catches drift via the satisfies/import below.\nconst bylineFieldTypeValues = z.enum([\"string\", \"text\", \"url\", \"boolean\", \"select\"]);\n// Compile-time guard: a drift here trips the satisfies check.\ntype _BylineFieldTypeDriftCheck =\n\t(typeof BYLINE_FIELD_TYPES)[number] extends z.infer<typeof bylineFieldTypeValues>\n\t\t? z.infer<typeof bylineFieldTypeValues> extends (typeof BYLINE_FIELD_TYPES)[number]\n\t\t\t? true\n\t\t\t: never\n\t\t: never;\nconst _bylineFieldTypeDriftCheck: _BylineFieldTypeDriftCheck = true;\nvoid _bylineFieldTypeDriftCheck;\n\n/**\n * Validation payload for a byline custom field. v1 only exposes\n * `options` (used by `select`-type fields). Empty/duplicate options are\n * rejected at the registry layer; the zod layer only enforces shape and\n * caps. Future field types may add keys here.\n */\nconst bylineFieldValidationSchema = z\n\t.object({\n\t\toptions: z\n\t\t\t.array(z.string().min(1))\n\t\t\t.min(1, \"select options must contain at least one entry\")\n\t\t\t.max(MAX_SELECT_OPTIONS, `select options cannot exceed ${MAX_SELECT_OPTIONS} entries`)\n\t\t\t.optional(),\n\t})\n\t.strict()\n\t.nullable();\n\n/**\n * Slug validation chain shared by create + reorder bodies. Centralised so\n * the reserved-slug message and pattern are identical everywhere.\n */\nconst bylineFieldSlug = z\n\t.string()\n\t.min(1, \"Byline field slug is required\")\n\t.max(MAX_SLUG_LENGTH, `Byline field slug must be ${MAX_SLUG_LENGTH} characters or less`)\n\t.regex(\n\t\tbylineFieldSlugPattern,\n\t\t\"Byline field slug must contain only lowercase letters, digits, and underscores, and start with a letter\",\n\t)\n\t.refine((slug) => !RESERVED_SET.has(slug), {\n\t\t// Surface the offending slug in the validation issue path-message\n\t\t// for easier debugging from the admin UI's error toast.\n\t\tmessage: \"Byline field slug is reserved\",\n\t});\n\nconst bylineFieldLabel = z\n\t.string()\n\t.min(1, \"Byline field label is required\")\n\t.max(MAX_LABEL_LENGTH, `Byline field label must be ${MAX_LABEL_LENGTH} characters or less`);\n\n// ---------------------------------------------------------------------------\n// Request bodies\n// ---------------------------------------------------------------------------\n\nexport const bylineFieldCreateBody = z\n\t.object({\n\t\tslug: bylineFieldSlug,\n\t\tlabel: bylineFieldLabel,\n\t\ttype: bylineFieldTypeValues,\n\t\trequired: z.boolean().optional(),\n\t\t/**\n\t\t * Whether values are stored per-locale (translatable, default) or\n\t\t * shared across the translation group. See `BylineFieldDefinition`.\n\t\t */\n\t\ttranslatable: z.boolean().optional(),\n\t\tvalidation: bylineFieldValidationSchema.optional(),\n\t\tsortOrder: z.number().int().min(0).optional(),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldCreateBody\" });\n\n/**\n * Update body. `slug` and `type` are intentionally absent — both are\n * immutable post-create (changing them would invalidate stored values).\n * `translatable` flips are gated at the registry layer when value rows\n * exist (`TRANSLATABLE_LOCKED`).\n */\nexport const bylineFieldUpdateBody = z\n\t.object({\n\t\tlabel: bylineFieldLabel.optional(),\n\t\trequired: z.boolean().optional(),\n\t\ttranslatable: z.boolean().optional(),\n\t\tvalidation: bylineFieldValidationSchema.optional(),\n\t\tsortOrder: z.number().int().min(0).optional(),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldUpdateBody\" });\n\nexport const bylineFieldReorderBody = z\n\t.object({\n\t\t/**\n\t\t * Exact set of currently registered slugs in the desired order.\n\t\t * The registry rejects any drift (`REORDER_MISMATCH`); the zod\n\t\t * layer enforces slug shape only. An empty array is permitted —\n\t\t * `reorderFields([])` is a valid no-op when zero fields are\n\t\t * registered (registry contract). Rejecting empty here would\n\t\t * produce a spurious 400 for an admin UI that submits a reorder\n\t\t * after deleting the last field.\n\t\t */\n\t\tslugs: z.array(bylineFieldSlug),\n\t})\n\t.strict()\n\t.meta({ id: \"BylineFieldReorderBody\" });\n\n// ---------------------------------------------------------------------------\n// Response shapes\n// ---------------------------------------------------------------------------\n\nexport const bylineFieldDefinitionSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tslug: z.string(),\n\t\tlabel: z.string(),\n\t\ttype: bylineFieldTypeValues,\n\t\trequired: z.boolean(),\n\t\ttranslatable: z.boolean(),\n\t\tvalidation: z\n\t\t\t.object({\n\t\t\t\toptions: z.array(z.string()).optional(),\n\t\t\t})\n\t\t\t.nullable(),\n\t\tsortOrder: z.number().int(),\n\t\tcreatedAt: z.string(),\n\t\tupdatedAt: z.string(),\n\t})\n\t.meta({ id: \"BylineFieldDefinition\" });\n\nexport const bylineFieldListResponseSchema = z\n\t.object({\n\t\titems: z.array(bylineFieldDefinitionSchema),\n\t})\n\t.meta({ id: \"BylineFieldListResponse\" });\n\n/**\n * Response shape for `GET /api/admin/byline-fields/[slug]/usage`.\n *\n * `translatableValueCount` counts rows in `_emdash_byline_field_values`.\n * `groupValueCount` counts rows in `_emdash_byline_field_group_values`.\n * `totalAffectedRows` is the sum — what the destructive-delete confirm\n * dialog surfaces. Both individual counts are exposed for diagnostic\n * value (e.g. inconsistency with the field's current `translatable`\n * flag would show non-zero on the \"wrong\" side).\n */\nexport const bylineFieldUsageResponseSchema = z\n\t.object({\n\t\ttranslatableValueCount: z.number().int().nonnegative(),\n\t\tgroupValueCount: z.number().int().nonnegative(),\n\t\ttotalAffectedRows: z.number().int().nonnegative(),\n\t})\n\t.meta({ id: \"BylineFieldUsageResponse\" });\n"],"mappings":"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"}
@@ -646,7 +646,9 @@ declare const createFieldBody: z.ZodObject<{
646
646
  number: "number";
647
647
  boolean: "boolean";
648
648
  text: "text";
649
+ url: "url";
649
650
  select: "select";
651
+ image: "image";
650
652
  datetime: "datetime";
651
653
  integer: "integer";
652
654
  }>;
@@ -684,7 +686,9 @@ declare const updateFieldBody: z.ZodObject<{
684
686
  number: "number";
685
687
  boolean: "boolean";
686
688
  text: "text";
689
+ url: "url";
687
690
  select: "select";
691
+ image: "image";
688
692
  datetime: "datetime";
689
693
  integer: "integer";
690
694
  }>;
@@ -2165,4 +2169,4 @@ declare const bylineFieldUsageResponseSchema: z.ZodObject<{
2165
2169
  }, z.core.$strip>;
2166
2170
  //#endregion
2167
2171
  export { wpRewriteUrlsBody as $, trashedContentListResponseSchema as $n, commentSchema as $t, reorderWidgetsBody as A, mediaResponseSchema as An, menuSchema as At, userSchema as B, contentListResponseSchema as Bn, magicLinkSendBody as Bt, notFoundSummarySchema as C, mediaConfirmBody as Cn, termWithCountSchema as Ct, updateRedirectBody as D, mediaListQuery as Dn, menuItemSchema as Dt, redirectsListQuery as E, mediaItemSchema as En, createMenuItemBody as Et, widgetSchema as F, contentAuthorsResponseSchema as Fn, updateMenuItemBody as Ft, setupAdminVerifyBody as G, contentSeoInput as Gn, passkeyVerifyBody as Gt, usersListQuery as H, contentPublishBody as Hn, passkeyRegisterOptionsBody as Ht, allowedDomainCreateBody as I, contentCompareResponseSchema as In, authMeActionBody as It, importProbeBody as J, contentTranslationSchema as Jn, adminCommentListResponseSchema as Jt, setupAtprotoAdminBody as K, contentSeoSchema as Kn, signupCompleteBody as Kt, allowedDomainUpdateBody as L, contentCreateBody as Ln, inviteCompleteBody as Lt, widgetAreaSchema as M, mediaUploadUrlBody as Mn, menuWithItemsSchema as Mt, widgetAreaWithWidgetsAndCountSchema as N, mediaUploadUrlResponseSchema as Nn, reorderMenuItemsBody as Nt, createWidgetAreaBody as O, mediaListResponseSchema as On, menuItemTypeEnum as Ot, widgetAreaWithWidgetsSchema as P, contentAuthorSchema as Pn, updateMenuBody as Pt, wpPrepareBody as Q, trashedContentItemSchema as Qn, commentListQuery as Qt, userDetailSchema as R, contentItemSchema as Rn, inviteCreateBody as Rt, notFoundSummaryResponseSchema as S, formatFileSize as Sn, termTranslationsSchema as St, redirectSchema as T, mediaExistingResponseSchema as Tn, createMenuBody as Tt, atprotoLoginBody as U, contentResponseSchema as Un, passkeyRegisterVerifyBody as Ut, userUpdateBody as V, contentPreviewUrlBody as Vn, passkeyOptionsBody as Vt, setupAdminBody as W, contentScheduleBody as Wn, passkeyRenameBody as Wt, wpPluginAnalyzeBody as X, contentTrashQuery as Xn, commentBulkResponseSchema as Xt, wpMediaImportBody as Y, contentTranslationsResponseSchema as Yn, commentBulkBody as Yt, wpPluginExecuteBody as Z, contentUpdateBody as Zn, commentCountsResponseSchema as Zt, notFoundEntrySchema as _, orphanedTableSchema as _n, taxonomyListResponseSchema as _t, bylineFieldUpdateBody as a, collectionListResponseSchema as an, httpUrl as ar, searchSuggestQuery as at, notFoundPruneBody as b, updateFieldBody as bn, termResponseSchema as bt, bylineCreditSchema as c, collectionWithFieldsResponseSchema as cn, offsetPaginationQuery as cr, createSectionBody as ct, bylineTranslationCreateBody as d, fieldListResponseSchema as dn, successEnvelope as dr, sectionsListQuery as dt, commentStatusBody as en, VALID_ROLE_LEVELS as er, searchEnableBody as et, bylineTranslationsResponseSchema as f, fieldReorderBody as fn, updateSectionBody as ft, createRedirectBody as g, orphanedTableListResponseSchema as gn, taxonomyDefTranslationsSchema as gt, contentBylineInputSchema as h, orphanRegisterBody as hn, taxonomyDefSchema as ht, bylineFieldReorderBody as i, collectionGetQuery as in, deleteResponseSchema as ir, searchResultSchema as it, updateWidgetBody as j, mediaUpdateBody as jn, menuTranslationsSchema as jt, createWidgetBody as k, mediaProviderListQuery as kn, menuListItemSchema as kt, bylineListResponseSchema as l, createCollectionBody as ln, roleLevel as lr, sectionListResponseSchema as lt, bylinesListQuery as m, fieldSchema as mn, createTermBody as mt, bylineFieldDefinitionSchema as n, publicCommentListResponseSchema as nn, countResponseSchema as nr, searchRebuildBody as nt, bylineFieldUsageResponseSchema as o, collectionResponseSchema as on, localeCode as or, settingsUpdateBody as ot, bylineUpdateBody as p, fieldResponseSchema as pn, createTaxonomyDefBody as pt, setupBody as q, contentTermsBody as qn, signupRequestBody as qt, bylineFieldListResponseSchema as r, publicCommentSchema as rn, cursorPaginationQuery as rr, searchResponseSchema as rt, bylineCreateBody as s, collectionSchema as sn, localeFilterQuery as sr, siteSettingsSchema as st, bylineFieldCreateBody as t, createCommentBody as tn, apiErrorSchema as tr, searchQuery as tt, bylineSummarySchema as u, createFieldBody as un, slugPattern as ur, sectionSchema as ut, notFoundListQuery as v, schemaExportQuery as vn, termGetResponseSchema as vt, redirectListResponseSchema as w, mediaConfirmResponseSchema as wn, updateTermBody as wt, notFoundSummaryQuery as x, DEFAULT_MAX_UPLOAD_SIZE as xn, termSchema as xt, notFoundListResponseSchema as y, updateCollectionBody as yn, termListResponseSchema as yt, userListResponseSchema as z, contentListQuery as zn, inviteRegisterOptionsBody as zt };
2168
- //# sourceMappingURL=byline-fields-DYXKDuNX.d.mts.map
2172
+ //# sourceMappingURL=byline-fields-DbibsvTl.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byline-fields-DbibsvTl.d.mts","names":[],"sources":["../src/api/schemas/common.ts","../src/api/schemas/content.ts","../src/api/schemas/media.ts","../src/api/schemas/schema.ts","../src/api/schemas/comments.ts","../src/api/schemas/auth.ts","../src/api/schemas/menus.ts","../src/api/schemas/taxonomies.ts","../src/api/schemas/sections.ts","../src/api/schemas/settings.ts","../src/api/schemas/search.ts","../src/api/schemas/import.ts","../src/api/schemas/setup.ts","../src/api/schemas/users.ts","../src/api/schemas/widgets.ts","../src/api/schemas/redirects.ts","../src/api/schemas/bylines.ts","../src/api/schemas/byline-fields.ts"],"mappings":"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"}
@@ -201,4 +201,4 @@ async function handleBylineUpdate(db, id, input) {
201
201
 
202
202
  //#endregion
203
203
  export { handleBylineTranslations as n, handleBylineUpdate as r, handleBylineCreate as t };
204
- //# sourceMappingURL=bylines-Cx5n-WqP.mjs.map
204
+ //# sourceMappingURL=bylines-BdxWCnPL.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"bylines-Cx5n-WqP.mjs","names":[],"sources":["../src/api/handlers/bylines.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\n\nimport {\n\tBylineRepository,\n\ttype CreateBylineInput,\n\ttype UpdateBylineInput,\n} from \"../../database/repositories/byline.js\";\nimport { EmDashValidationError, type BylineSummary } from \"../../database/repositories/types.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { getI18nConfig } from \"../../i18n/config.js\";\nimport type { ApiResult } from \"../types.js\";\n\n// `undefined → null` so a missing field in the create payload matches the\n// repo's stored `null` (BylineRepository normalises with `?? null` on write).\nconst norm = (v: string | null | undefined): string | null => v ?? null;\n\n/**\n * Whether the existing byline row's fixed columns match a fresh-create\n * payload after null/undefined normalisation. Used by the D1 create-retry\n * recovery branch.\n */\nfunction bylineFixedFieldsMatch(\n\texisting: BylineSummary,\n\tinput: CreateBylineInput,\n\teffectiveLocale: string,\n): boolean {\n\treturn (\n\t\texisting.displayName === input.displayName &&\n\t\tnorm(existing.bio) === norm(input.bio) &&\n\t\tnorm(existing.avatarMediaId) === norm(input.avatarMediaId) &&\n\t\tnorm(existing.websiteUrl) === norm(input.websiteUrl) &&\n\t\tnorm(existing.userId) === norm(input.userId) &&\n\t\texisting.isGuest === (input.isGuest ?? false) &&\n\t\texisting.locale === effectiveLocale\n\t);\n}\n\n/**\n * Whether every key in `existing` appears in `input` with the same value.\n * Allows `input` to contain additional keys (the partial-write recovery\n * case); rejects on a divergent value or a key the input omits.\n */\nfunction existingCustomFieldsAreSubsetOf(\n\texisting: Record<string, unknown>,\n\tinput: Record<string, unknown> | undefined,\n): boolean {\n\tif (!input) return Object.keys(existing).length === 0;\n\tfor (const [slug, value] of Object.entries(existing)) {\n\t\tif (!Object.hasOwn(input, slug)) return false;\n\t\tif (input[slug] !== value) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Reject locales the site doesn't configure. Returns `null` when the locale\n * is fine (omitted, or matches `locales` in the i18n config, or i18n isn't\n * configured at all).\n */\nfunction rejectUnknownLocale(locale: string | undefined): ApiResult<never> | null {\n\tif (!locale) return null;\n\tconst config = getI18nConfig();\n\tif (!config) return null;\n\tif (config.locales.includes(locale)) return null;\n\treturn {\n\t\tsuccess: false,\n\t\terror: {\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\tmessage: `Locale \"${locale}\" is not configured for this site`,\n\t\t},\n\t};\n}\n\n/**\n * Business-logic helpers for the bylines admin API.\n *\n * Mirrors the shape of `packages/core/src/api/handlers/menus.ts`. Route files\n * stay thin: they parse input, call these handlers, and forward the result via\n * `unwrapResult`. The repository (`BylineRepository`) is strict per locale; the\n * handlers add validation and translation-flow guards on top.\n */\n\nexport interface BylineTranslationsResponse {\n\titems: BylineSummary[];\n}\n\n/**\n * List every translation of a byline (by row id). Returns NOT_FOUND when no\n * row with the given id exists.\n */\nexport async function handleBylineTranslations(\n\tdb: Kysely<Database>,\n\tid: string,\n): Promise<ApiResult<BylineTranslationsResponse>> {\n\ttry {\n\t\tconst repo = new BylineRepository(db);\n\t\tconst anchor = await repo.findById(id);\n\t\tif (!anchor) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline not found\" },\n\t\t\t};\n\t\t}\n\t\tconst items = await repo.listTranslations(id);\n\t\treturn { success: true, data: { items } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"BYLINE_TRANSLATIONS_ERROR\",\n\t\t\t\tmessage: \"Failed to list byline translations\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Create a new byline. When `translationOf` is supplied, the new row joins the\n * source byline's translation_group (a sibling in the same logical identity).\n *\n * Translating from a source row only makes sense when the caller names the\n * target locale, otherwise we'd silently clone into the configured default,\n * which is almost never what's intended (and will collide if the source is\n * already the default-locale row). Mirrors `handleMenuCreate`.\n */\nexport async function handleBylineCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateBylineInput,\n): Promise<ApiResult<BylineSummary>> {\n\ttry {\n\t\tif (input.translationOf && !input.locale) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\tmessage: \"`locale` is required when `translationOf` is provided\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst localeErr = rejectUnknownLocale(input.locale);\n\t\tif (localeErr) return localeErr;\n\n\t\tconst repo = new BylineRepository(db);\n\n\t\t// Existence check up front so the repo's \"Source not found\" throw\n\t\t// becomes a clean NOT_FOUND on the API.\n\t\tlet sourceGroup: string | undefined;\n\t\tif (input.translationOf) {\n\t\t\tconst source = await repo.findById(input.translationOf);\n\t\t\tif (!source) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tmessage: \"Source byline for translation not found\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tsourceGroup = source.translationGroup ?? source.id;\n\t\t}\n\n\t\tconst effectiveLocale = input.locale ?? getI18nConfig()?.defaultLocale ?? \"en\";\n\n\t\t// Translation-group guard: the row-per-locale model (PR #916)\n\t\t// allows exactly one row per (translation_group, locale). Reject\n\t\t// here so callers get a clean 409 instead of a UNIQUE constraint\n\t\t// failure from the partial index. The DB constraint is the safety\n\t\t// net; this is the friendly error.\n\t\tif (sourceGroup) {\n\t\t\tconst siblings = await repo.findByTranslationGroup(sourceGroup);\n\t\t\tif (siblings.some((b) => b.locale === effectiveLocale)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\t\t\tmessage: `Translation already exists in locale \"${effectiveLocale}\" for this byline`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Duplicate guard: same (slug, locale) — matches the DB unique key\n\t\t// from migration 040.\n\t\tconst existing = await repo.findBySlug(input.slug, { locale: effectiveLocale });\n\t\tif (existing) {\n\t\t\t// D1 has no transactions, so a crash between the byline insert\n\t\t\t// and the per-field writes leaves a partial row that's\n\t\t\t// otherwise unrecoverable. Treat a same-identity retry that\n\t\t\t// provides customFields as completing the abandoned create.\n\t\t\t// Recovery requires fixed-column + translation-group +\n\t\t\t// subset-customFields match; anything else collapses to a\n\t\t\t// standard duplicate-slug conflict.\n\t\t\tconst expectedTranslationGroup = sourceGroup ?? existing.id;\n\t\t\tconst inputHasFields = !!input.customFields && Object.keys(input.customFields).length > 0;\n\t\t\tif (\n\t\t\t\tinputHasFields &&\n\t\t\t\tbylineFixedFieldsMatch(existing, input, effectiveLocale) &&\n\t\t\t\texisting.translationGroup === expectedTranslationGroup &&\n\t\t\t\texistingCustomFieldsAreSubsetOf(existing.customFields ?? {}, input.customFields)\n\t\t\t) {\n\t\t\t\tconst recovered = await repo.update(existing.id, {\n\t\t\t\t\tcustomFields: input.customFields,\n\t\t\t\t});\n\t\t\t\tif (recovered) return { success: true, data: recovered };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\t\tmessage: `Byline \"${input.slug}\" already exists${\n\t\t\t\t\t\tinput.locale ? ` in locale \"${input.locale}\"` : \"\"\n\t\t\t\t\t}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst byline = await repo.create(input);\n\t\treturn { success: true, data: byline };\n\t} catch (error) {\n\t\t// Mirror handleBylineUpdate: surface customFields validation\n\t\t// errors as 400 rather than swallowing them as a generic 500.\n\t\tif (error instanceof EmDashValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: error.message },\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[BYLINE_CREATE_ERROR]\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"BYLINE_CREATE_ERROR\", message: \"Failed to create byline\" },\n\t\t};\n\t}\n}\n\n/**\n * Update an existing byline. Forwards every field on `UpdateBylineInput`\n * to `BylineRepository.update`, including the Phase 3 `customFields`\n * map; per-field type validation lives in the repo, which throws\n * `EmDashValidationError` on unknown slugs, type mismatches, or\n * `select`-choice misses. This handler translates that into a clean\n * `VALIDATION_ERROR` (400 via `mapErrorStatus`).\n *\n * Returns `NOT_FOUND` when the byline id doesn't resolve. Generic\n * failures surface as `BYLINE_UPDATE_ERROR` (500) without leaking the\n * underlying message.\n */\nexport async function handleBylineUpdate(\n\tdb: Kysely<Database>,\n\tid: string,\n\tinput: UpdateBylineInput,\n): Promise<ApiResult<BylineSummary>> {\n\ttry {\n\t\tconst repo = new BylineRepository(db);\n\t\tconst byline = await repo.update(id, input);\n\t\tif (!byline) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline not found\" },\n\t\t\t};\n\t\t}\n\t\treturn { success: true, data: byline };\n\t} catch (error) {\n\t\t// Unknown-key + type-mismatch + select-choice writes throw\n\t\t// EmDashValidationError (Phase 3, see BylineRepository.update).\n\t\t// Map to a clean 400 — the error message names the offending\n\t\t// slug/type, which is safe to surface to the admin client.\n\t\tif (error instanceof EmDashValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: error.message },\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[BYLINE_UPDATE_ERROR]\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"BYLINE_UPDATE_ERROR\", message: \"Failed to update byline\" },\n\t\t};\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bylines-BdxWCnPL.mjs","names":[],"sources":["../src/api/handlers/bylines.ts"],"sourcesContent":["import type { Kysely } from \"kysely\";\n\nimport {\n\tBylineRepository,\n\ttype CreateBylineInput,\n\ttype UpdateBylineInput,\n} from \"../../database/repositories/byline.js\";\nimport { EmDashValidationError, type BylineSummary } from \"../../database/repositories/types.js\";\nimport type { Database } from \"../../database/types.js\";\nimport { getI18nConfig } from \"../../i18n/config.js\";\nimport type { ApiResult } from \"../types.js\";\n\n// `undefined → null` so a missing field in the create payload matches the\n// repo's stored `null` (BylineRepository normalises with `?? null` on write).\nconst norm = (v: string | null | undefined): string | null => v ?? null;\n\n/**\n * Whether the existing byline row's fixed columns match a fresh-create\n * payload after null/undefined normalisation. Used by the D1 create-retry\n * recovery branch.\n */\nfunction bylineFixedFieldsMatch(\n\texisting: BylineSummary,\n\tinput: CreateBylineInput,\n\teffectiveLocale: string,\n): boolean {\n\treturn (\n\t\texisting.displayName === input.displayName &&\n\t\tnorm(existing.bio) === norm(input.bio) &&\n\t\tnorm(existing.avatarMediaId) === norm(input.avatarMediaId) &&\n\t\tnorm(existing.websiteUrl) === norm(input.websiteUrl) &&\n\t\tnorm(existing.userId) === norm(input.userId) &&\n\t\texisting.isGuest === (input.isGuest ?? false) &&\n\t\texisting.locale === effectiveLocale\n\t);\n}\n\n/**\n * Whether every key in `existing` appears in `input` with the same value.\n * Allows `input` to contain additional keys (the partial-write recovery\n * case); rejects on a divergent value or a key the input omits.\n */\nfunction existingCustomFieldsAreSubsetOf(\n\texisting: Record<string, unknown>,\n\tinput: Record<string, unknown> | undefined,\n): boolean {\n\tif (!input) return Object.keys(existing).length === 0;\n\tfor (const [slug, value] of Object.entries(existing)) {\n\t\tif (!Object.hasOwn(input, slug)) return false;\n\t\tif (input[slug] !== value) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Reject locales the site doesn't configure. Returns `null` when the locale\n * is fine (omitted, or matches `locales` in the i18n config, or i18n isn't\n * configured at all).\n */\nfunction rejectUnknownLocale(locale: string | undefined): ApiResult<never> | null {\n\tif (!locale) return null;\n\tconst config = getI18nConfig();\n\tif (!config) return null;\n\tif (config.locales.includes(locale)) return null;\n\treturn {\n\t\tsuccess: false,\n\t\terror: {\n\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\tmessage: `Locale \"${locale}\" is not configured for this site`,\n\t\t},\n\t};\n}\n\n/**\n * Business-logic helpers for the bylines admin API.\n *\n * Mirrors the shape of `packages/core/src/api/handlers/menus.ts`. Route files\n * stay thin: they parse input, call these handlers, and forward the result via\n * `unwrapResult`. The repository (`BylineRepository`) is strict per locale; the\n * handlers add validation and translation-flow guards on top.\n */\n\nexport interface BylineTranslationsResponse {\n\titems: BylineSummary[];\n}\n\n/**\n * List every translation of a byline (by row id). Returns NOT_FOUND when no\n * row with the given id exists.\n */\nexport async function handleBylineTranslations(\n\tdb: Kysely<Database>,\n\tid: string,\n): Promise<ApiResult<BylineTranslationsResponse>> {\n\ttry {\n\t\tconst repo = new BylineRepository(db);\n\t\tconst anchor = await repo.findById(id);\n\t\tif (!anchor) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline not found\" },\n\t\t\t};\n\t\t}\n\t\tconst items = await repo.listTranslations(id);\n\t\treturn { success: true, data: { items } };\n\t} catch {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tcode: \"BYLINE_TRANSLATIONS_ERROR\",\n\t\t\t\tmessage: \"Failed to list byline translations\",\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Create a new byline. When `translationOf` is supplied, the new row joins the\n * source byline's translation_group (a sibling in the same logical identity).\n *\n * Translating from a source row only makes sense when the caller names the\n * target locale, otherwise we'd silently clone into the configured default,\n * which is almost never what's intended (and will collide if the source is\n * already the default-locale row). Mirrors `handleMenuCreate`.\n */\nexport async function handleBylineCreate(\n\tdb: Kysely<Database>,\n\tinput: CreateBylineInput,\n): Promise<ApiResult<BylineSummary>> {\n\ttry {\n\t\tif (input.translationOf && !input.locale) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"VALIDATION_ERROR\",\n\t\t\t\t\tmessage: \"`locale` is required when `translationOf` is provided\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst localeErr = rejectUnknownLocale(input.locale);\n\t\tif (localeErr) return localeErr;\n\n\t\tconst repo = new BylineRepository(db);\n\n\t\t// Existence check up front so the repo's \"Source not found\" throw\n\t\t// becomes a clean NOT_FOUND on the API.\n\t\tlet sourceGroup: string | undefined;\n\t\tif (input.translationOf) {\n\t\t\tconst source = await repo.findById(input.translationOf);\n\t\t\tif (!source) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tmessage: \"Source byline for translation not found\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tsourceGroup = source.translationGroup ?? source.id;\n\t\t}\n\n\t\tconst effectiveLocale = input.locale ?? getI18nConfig()?.defaultLocale ?? \"en\";\n\n\t\t// Translation-group guard: the row-per-locale model (PR #916)\n\t\t// allows exactly one row per (translation_group, locale). Reject\n\t\t// here so callers get a clean 409 instead of a UNIQUE constraint\n\t\t// failure from the partial index. The DB constraint is the safety\n\t\t// net; this is the friendly error.\n\t\tif (sourceGroup) {\n\t\t\tconst siblings = await repo.findByTranslationGroup(sourceGroup);\n\t\t\tif (siblings.some((b) => b.locale === effectiveLocale)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\t\t\tmessage: `Translation already exists in locale \"${effectiveLocale}\" for this byline`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Duplicate guard: same (slug, locale) — matches the DB unique key\n\t\t// from migration 040.\n\t\tconst existing = await repo.findBySlug(input.slug, { locale: effectiveLocale });\n\t\tif (existing) {\n\t\t\t// D1 has no transactions, so a crash between the byline insert\n\t\t\t// and the per-field writes leaves a partial row that's\n\t\t\t// otherwise unrecoverable. Treat a same-identity retry that\n\t\t\t// provides customFields as completing the abandoned create.\n\t\t\t// Recovery requires fixed-column + translation-group +\n\t\t\t// subset-customFields match; anything else collapses to a\n\t\t\t// standard duplicate-slug conflict.\n\t\t\tconst expectedTranslationGroup = sourceGroup ?? existing.id;\n\t\t\tconst inputHasFields = !!input.customFields && Object.keys(input.customFields).length > 0;\n\t\t\tif (\n\t\t\t\tinputHasFields &&\n\t\t\t\tbylineFixedFieldsMatch(existing, input, effectiveLocale) &&\n\t\t\t\texisting.translationGroup === expectedTranslationGroup &&\n\t\t\t\texistingCustomFieldsAreSubsetOf(existing.customFields ?? {}, input.customFields)\n\t\t\t) {\n\t\t\t\tconst recovered = await repo.update(existing.id, {\n\t\t\t\t\tcustomFields: input.customFields,\n\t\t\t\t});\n\t\t\t\tif (recovered) return { success: true, data: recovered };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: {\n\t\t\t\t\tcode: \"CONFLICT\",\n\t\t\t\t\tmessage: `Byline \"${input.slug}\" already exists${\n\t\t\t\t\t\tinput.locale ? ` in locale \"${input.locale}\"` : \"\"\n\t\t\t\t\t}`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst byline = await repo.create(input);\n\t\treturn { success: true, data: byline };\n\t} catch (error) {\n\t\t// Mirror handleBylineUpdate: surface customFields validation\n\t\t// errors as 400 rather than swallowing them as a generic 500.\n\t\tif (error instanceof EmDashValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: error.message },\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[BYLINE_CREATE_ERROR]\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"BYLINE_CREATE_ERROR\", message: \"Failed to create byline\" },\n\t\t};\n\t}\n}\n\n/**\n * Update an existing byline. Forwards every field on `UpdateBylineInput`\n * to `BylineRepository.update`, including the Phase 3 `customFields`\n * map; per-field type validation lives in the repo, which throws\n * `EmDashValidationError` on unknown slugs, type mismatches, or\n * `select`-choice misses. This handler translates that into a clean\n * `VALIDATION_ERROR` (400 via `mapErrorStatus`).\n *\n * Returns `NOT_FOUND` when the byline id doesn't resolve. Generic\n * failures surface as `BYLINE_UPDATE_ERROR` (500) without leaking the\n * underlying message.\n */\nexport async function handleBylineUpdate(\n\tdb: Kysely<Database>,\n\tid: string,\n\tinput: UpdateBylineInput,\n): Promise<ApiResult<BylineSummary>> {\n\ttry {\n\t\tconst repo = new BylineRepository(db);\n\t\tconst byline = await repo.update(id, input);\n\t\tif (!byline) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"NOT_FOUND\", message: \"Byline not found\" },\n\t\t\t};\n\t\t}\n\t\treturn { success: true, data: byline };\n\t} catch (error) {\n\t\t// Unknown-key + type-mismatch + select-choice writes throw\n\t\t// EmDashValidationError (Phase 3, see BylineRepository.update).\n\t\t// Map to a clean 400 — the error message names the offending\n\t\t// slug/type, which is safe to surface to the admin client.\n\t\tif (error instanceof EmDashValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"VALIDATION_ERROR\", message: error.message },\n\t\t\t};\n\t\t}\n\t\tconsole.error(\"[BYLINE_UPDATE_ERROR]\", error);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: { code: \"BYLINE_UPDATE_ERROR\", message: \"Failed to update byline\" },\n\t\t};\n\t}\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
3
3
  import { r as requestCached } from "./request-cache-D32LpnmI.mjs";
4
4
  import { t as BylineRepository } from "./byline-DUx48sJp.mjs";
5
5
  import { n as isMissingTableError } from "./db-errors-CtzxKBxe.mjs";
6
- import { r as getDb } from "./loader-CpZKpFz0.mjs";
6
+ import { r as getDb } from "./loader-ZN1ll-d-.mjs";
7
7
  import { i as resolveLocaleChain } from "./resolve-BqYMVG0D.mjs";
8
8
  import { sql } from "kysely";
9
9
 
@@ -217,7 +217,7 @@ async function getBylinesForEntries(collection, entries) {
217
217
  * @param options - Optional locale, ordering, status, and limit
218
218
  */
219
219
  async function getEntriesByByline(collection, byline, options = {}) {
220
- const { getEmDashCollection } = await import("./query-BFQ029Ts.mjs").then((n) => n.o);
220
+ const { getEmDashCollection } = await import("./query-CbUcI4Xk.mjs").then((n) => n.o);
221
221
  const queryOptions = { where: { byline } };
222
222
  if (options.locale !== void 0) queryOptions.locale = options.locale;
223
223
  if (options.orderBy !== void 0) queryOptions.orderBy = options.orderBy;
@@ -229,4 +229,4 @@ async function getEntriesByByline(collection, byline, options = {}) {
229
229
 
230
230
  //#endregion
231
231
  export { invalidateBylineCache as a, getEntriesByByline as i, getByline as n, getBylineBySlug as r, bylines_exports as t };
232
- //# sourceMappingURL=bylines-wurS258E.mjs.map
232
+ //# sourceMappingURL=bylines-s8c2DXbH.mjs.map