emdash 0.30.0 → 0.31.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 (387) hide show
  1. package/dist/api/route-utils.mjs +13 -13
  2. package/dist/api/schemas/index.d.mts +1 -1
  3. package/dist/api/schemas/index.mjs +3 -3
  4. package/dist/{api-b8WIiGU4.mjs → api-EibxGP-V.mjs} +23 -23
  5. package/dist/api-EibxGP-V.mjs.map +1 -0
  6. package/dist/{apply-CmIJK9j8.mjs → apply-fGHCAwWN.mjs} +26 -25
  7. package/dist/apply-fGHCAwWN.mjs.map +1 -0
  8. package/dist/astro/index.d.mts +2 -2
  9. package/dist/astro/index.mjs +1 -1
  10. package/dist/astro/middleware/auth.d.mts +2 -2
  11. package/dist/astro/middleware/auth.mjs +2 -2
  12. package/dist/astro/middleware/redirect.mjs +5 -5
  13. package/dist/astro/middleware/request-context.mjs +1 -1
  14. package/dist/astro/middleware.d.mts +2 -2
  15. package/dist/astro/middleware.mjs +139 -68
  16. package/dist/astro/middleware.mjs.map +1 -1
  17. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +6 -6
  18. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +6 -6
  19. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
  20. package/dist/astro/routes/api/admin/api-tokens/index.mjs +3 -3
  21. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +3 -3
  22. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +7 -7
  23. package/dist/astro/routes/api/admin/byline-fields/index.mjs +7 -7
  24. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +7 -7
  25. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +14 -14
  26. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +14 -14
  27. package/dist/astro/routes/api/admin/bylines/index.d.mts.map +1 -1
  28. package/dist/astro/routes/api/admin/bylines/index.mjs +18 -17
  29. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  30. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +10 -10
  31. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  32. package/dist/astro/routes/api/admin/comments/bulk.mjs +9 -9
  33. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  34. package/dist/astro/routes/api/admin/comments/index.mjs +9 -9
  35. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  36. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  37. package/dist/astro/routes/api/admin/media-usage/repair.mjs +10 -10
  38. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
  39. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
  40. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +34 -34
  41. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +34 -34
  42. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +34 -34
  43. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +4 -4
  44. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +34 -34
  45. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +34 -34
  46. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +34 -34
  47. package/dist/astro/routes/api/admin/plugins/index.mjs +34 -34
  48. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  49. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +34 -34
  50. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +34 -34
  51. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +34 -34
  52. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +34 -34
  53. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +35 -35
  54. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +34 -34
  55. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +35 -35
  56. package/dist/astro/routes/api/admin/plugins/updates.mjs +34 -34
  57. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +34 -34
  58. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  59. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +34 -34
  60. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  61. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  62. package/dist/astro/routes/api/admin/users/_id_/index.mjs +6 -6
  63. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
  64. package/dist/astro/routes/api/admin/users/index.mjs +6 -6
  65. package/dist/astro/routes/api/auth/dev-bypass.mjs +4 -4
  66. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  67. package/dist/astro/routes/api/auth/invite/complete.mjs +6 -6
  68. package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
  69. package/dist/astro/routes/api/auth/invite/register-options.mjs +6 -6
  70. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  71. package/dist/astro/routes/api/auth/magic-link/send.mjs +7 -7
  72. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  73. package/dist/astro/routes/api/auth/me.mjs +7 -7
  74. package/dist/astro/routes/api/auth/mode.mjs +2 -2
  75. package/dist/astro/routes/api/auth/passkey/_id_.mjs +6 -6
  76. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  77. package/dist/astro/routes/api/auth/passkey/options.mjs +7 -7
  78. package/dist/astro/routes/api/auth/passkey/register/options.mjs +6 -6
  79. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +6 -6
  80. package/dist/astro/routes/api/auth/passkey/verify.mjs +6 -6
  81. package/dist/astro/routes/api/auth/signup/complete.mjs +6 -6
  82. package/dist/astro/routes/api/auth/signup/request.mjs +7 -7
  83. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  84. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +10 -10
  85. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +10 -10
  86. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  87. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  88. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  89. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  90. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +9 -9
  91. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +7 -7
  92. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +14 -14
  93. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +14 -14
  94. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  95. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  96. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +7 -7
  97. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +13 -13
  98. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  99. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  100. package/dist/astro/routes/api/content/_collection_/_id_.mjs +7 -7
  101. package/dist/astro/routes/api/content/_collection_/authors.mjs +3 -3
  102. package/dist/astro/routes/api/content/_collection_/index.mjs +7 -7
  103. package/dist/astro/routes/api/content/_collection_/trash.mjs +7 -7
  104. package/dist/astro/routes/api/dashboard.mjs +7 -7
  105. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  106. package/dist/astro/routes/api/import/probe.mjs +12 -12
  107. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  108. package/dist/astro/routes/api/import/wordpress/execute.d.mts +2 -2
  109. package/dist/astro/routes/api/import/wordpress/execute.mjs +11 -11
  110. package/dist/astro/routes/api/import/wordpress/media.d.mts +2 -2
  111. package/dist/astro/routes/api/import/wordpress/media.mjs +7 -7
  112. package/dist/astro/routes/api/import/wordpress/prepare.mjs +9 -9
  113. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +2 -2
  114. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +9 -9
  115. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +12 -12
  116. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +2 -2
  117. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +19 -19
  118. package/dist/astro/routes/api/manifest.mjs +3 -3
  119. package/dist/astro/routes/api/mcp.mjs +39 -39
  120. package/dist/astro/routes/api/media/_id_/confirm.mjs +7 -7
  121. package/dist/astro/routes/api/media/_id_/usage.mjs +11 -11
  122. package/dist/astro/routes/api/media/_id_.mjs +10 -10
  123. package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
  124. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
  125. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
  126. package/dist/astro/routes/api/media/providers/index.mjs +3 -3
  127. package/dist/astro/routes/api/media/upload-url.mjs +7 -7
  128. package/dist/astro/routes/api/media.mjs +10 -10
  129. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +8 -8
  130. package/dist/astro/routes/api/menus/_name_/items.mjs +8 -8
  131. package/dist/astro/routes/api/menus/_name_/reorder.mjs +8 -8
  132. package/dist/astro/routes/api/menus/_name_/translations.mjs +8 -8
  133. package/dist/astro/routes/api/menus/_name_.mjs +8 -8
  134. package/dist/astro/routes/api/menus/index.mjs +8 -8
  135. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  136. package/dist/astro/routes/api/oauth/authorize.mjs +23 -9
  137. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  138. package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
  139. package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
  140. package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
  141. package/dist/astro/routes/api/oauth/register.mjs +2 -2
  142. package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
  143. package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
  144. package/dist/astro/routes/api/oauth/token.mjs +2 -2
  145. package/dist/astro/routes/api/openapi.json.mjs +4 -4
  146. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +4 -4
  147. package/dist/astro/routes/api/redirects/404s/index.mjs +10 -10
  148. package/dist/astro/routes/api/redirects/404s/summary.mjs +10 -10
  149. package/dist/astro/routes/api/redirects/_id_.mjs +11 -11
  150. package/dist/astro/routes/api/redirects/index.mjs +11 -11
  151. package/dist/astro/routes/api/relations/_id_/index.mjs +14 -14
  152. package/dist/astro/routes/api/relations/_id_/translations.mjs +10 -10
  153. package/dist/astro/routes/api/relations/index.mjs +14 -14
  154. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  155. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  156. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +34 -34
  157. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +34 -34
  158. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +34 -34
  159. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +34 -34
  160. package/dist/astro/routes/api/schema/collections/index.mjs +34 -34
  161. package/dist/astro/routes/api/schema/index.mjs +8 -8
  162. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +34 -34
  163. package/dist/astro/routes/api/schema/orphans/index.mjs +34 -34
  164. package/dist/astro/routes/api/search/enable.mjs +11 -11
  165. package/dist/astro/routes/api/search/index.mjs +10 -10
  166. package/dist/astro/routes/api/search/rebuild.mjs +11 -11
  167. package/dist/astro/routes/api/search/stats.mjs +7 -7
  168. package/dist/astro/routes/api/search/suggest.mjs +10 -10
  169. package/dist/astro/routes/api/sections/_slug_.mjs +10 -10
  170. package/dist/astro/routes/api/sections/index.mjs +10 -10
  171. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +4 -4
  172. package/dist/astro/routes/api/settings/backups/archives/index.mjs +4 -4
  173. package/dist/astro/routes/api/settings/backups/export.mjs +4 -4
  174. package/dist/astro/routes/api/settings/backups/index.mjs +5 -5
  175. package/dist/astro/routes/api/settings/email.mjs +4 -4
  176. package/dist/astro/routes/api/settings.mjs +12 -12
  177. package/dist/astro/routes/api/setup/admin-verify.mjs +6 -6
  178. package/dist/astro/routes/api/setup/admin.mjs +6 -6
  179. package/dist/astro/routes/api/setup/dev-bypass.mjs +18 -18
  180. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  181. package/dist/astro/routes/api/setup/index.mjs +22 -22
  182. package/dist/astro/routes/api/setup/status.mjs +3 -3
  183. package/dist/astro/routes/api/snapshot.mjs +4 -4
  184. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +13 -13
  185. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +13 -13
  186. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +13 -13
  187. package/dist/astro/routes/api/taxonomies/index.mjs +13 -13
  188. package/dist/astro/routes/api/themes/preview.mjs +4 -4
  189. package/dist/astro/routes/api/typegen.mjs +5 -5
  190. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +7 -7
  191. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +10 -10
  192. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +10 -10
  193. package/dist/astro/routes/api/widget-areas/_name_.mjs +6 -6
  194. package/dist/astro/routes/api/widget-areas/index.mjs +10 -10
  195. package/dist/astro/routes/api/widget-components.mjs +2 -2
  196. package/dist/astro/routes/robots.txt.mjs +5 -5
  197. package/dist/astro/routes/sitemap-_collection_.xml.mjs +7 -7
  198. package/dist/astro/routes/sitemap.xml.mjs +5 -5
  199. package/dist/astro/types.d.mts +2 -2
  200. package/dist/{authorize-WxsiePzy.mjs → authorize-6WPZa1xZ.mjs} +2 -2
  201. package/dist/{authorize-WxsiePzy.mjs.map → authorize-6WPZa1xZ.mjs.map} +1 -1
  202. package/dist/{backup-S8kFWtwD.mjs → backup-Qr9PaGUo.mjs} +2 -2
  203. package/dist/{backup-S8kFWtwD.mjs.map → backup-Qr9PaGUo.mjs.map} +1 -1
  204. package/dist/{byline-XEjchwzZ.mjs → byline-BTOxUlFF.mjs} +6 -6
  205. package/dist/{byline-XEjchwzZ.mjs.map → byline-BTOxUlFF.mjs.map} +1 -1
  206. package/dist/{bylines-czseViYo.mjs → bylines-FyZu6TbJ.mjs} +6 -6
  207. package/dist/{bylines-czseViYo.mjs.map → bylines-FyZu6TbJ.mjs.map} +1 -1
  208. package/dist/{bylines-BJbT4gKS.mjs → bylines-oVN0iPwX.mjs} +12 -8
  209. package/dist/bylines-oVN0iPwX.mjs.map +1 -0
  210. package/dist/{cache-CGCd6AVM.mjs → cache-DDwy3JDW.mjs} +2 -2
  211. package/dist/{cache-CGCd6AVM.mjs.map → cache-DDwy3JDW.mjs.map} +1 -1
  212. package/dist/{chunks-BxXyunY-.mjs → chunks-Bq-5DPrD.mjs} +2 -2
  213. package/dist/{chunks-BxXyunY-.mjs.map → chunks-Bq-5DPrD.mjs.map} +1 -1
  214. package/dist/cli/index.mjs +18 -18
  215. package/dist/{comment-DPT0WKyd.mjs → comment-B9cUud8H.mjs} +2 -2
  216. package/dist/{comment-DPT0WKyd.mjs.map → comment-B9cUud8H.mjs.map} +1 -1
  217. package/dist/{comment-reaction-C65MldIB.mjs → comment-reaction-VUXO981F.mjs} +2 -2
  218. package/dist/{comment-reaction-C65MldIB.mjs.map → comment-reaction-VUXO981F.mjs.map} +1 -1
  219. package/dist/{comments-Bz6sCbgD.mjs → comments-PXj1E9Si.mjs} +3 -3
  220. package/dist/{comments-Bz6sCbgD.mjs.map → comments-PXj1E9Si.mjs.map} +1 -1
  221. package/dist/{config-CVssduLe.mjs → config-B6b_BobR.mjs} +6 -2
  222. package/dist/config-B6b_BobR.mjs.map +1 -0
  223. package/dist/{content-Ci04z2z-.mjs → content-BC43pICM.mjs} +4 -4
  224. package/dist/{content-Ci04z2z-.mjs.map → content-BC43pICM.mjs.map} +1 -1
  225. package/dist/{content-refresh-D4khvC0R.mjs → content-refresh-CPMSauD3.mjs} +4 -4
  226. package/dist/{content-refresh-D4khvC0R.mjs.map → content-refresh-CPMSauD3.mjs.map} +1 -1
  227. package/dist/{context-B6hc7zJL.mjs → context-DOurRIrb.mjs} +10 -10
  228. package/dist/{context-B6hc7zJL.mjs.map → context-DOurRIrb.mjs.map} +1 -1
  229. package/dist/{dashboard-C5NkXFbi.mjs → dashboard-CBm4zhc3.mjs} +4 -4
  230. package/dist/{dashboard-C5NkXFbi.mjs.map → dashboard-CBm4zhc3.mjs.map} +1 -1
  231. package/dist/database/pg-migration-lock.d.mts.map +1 -1
  232. package/dist/database/pg-migration-lock.mjs +1 -4
  233. package/dist/database/pg-migration-lock.mjs.map +1 -1
  234. package/dist/db/index.mjs +2 -2
  235. package/dist/{dialect-helpers-HxEQGl_1.mjs → dialect-helpers-BtOwo2us.mjs} +4 -4
  236. package/dist/dialect-helpers-BtOwo2us.mjs.map +1 -0
  237. package/dist/{error-CEGF6UZb.mjs → error-DJ98TRbQ.mjs} +2 -2
  238. package/dist/{error-CEGF6UZb.mjs.map → error-DJ98TRbQ.mjs.map} +1 -1
  239. package/dist/{field-defs-cache-DvmlgP-D.mjs → field-defs-cache-KfNJ_qLQ.mjs} +2 -2
  240. package/dist/{field-defs-cache-DvmlgP-D.mjs.map → field-defs-cache-KfNJ_qLQ.mjs.map} +1 -1
  241. package/dist/{fts-manager-DzqIBrrW.mjs → fts-manager-hyCU9OOp.mjs} +3 -3
  242. package/dist/{fts-manager-DzqIBrrW.mjs.map → fts-manager-hyCU9OOp.mjs.map} +1 -1
  243. package/dist/{hreflang-db2Tpb2o.mjs → hreflang-CbYeCzl9.mjs} +7 -7
  244. package/dist/{hreflang-db2Tpb2o.mjs.map → hreflang-CbYeCzl9.mjs.map} +1 -1
  245. package/dist/{import-Dmkm8S1W.mjs → import-oDYCgNYQ.mjs} +2 -2
  246. package/dist/{import-Dmkm8S1W.mjs.map → import-oDYCgNYQ.mjs.map} +1 -1
  247. package/dist/{index-wYnC6u4o.d.mts → index-BcEH_FfS.d.mts} +33 -2
  248. package/dist/index-BcEH_FfS.d.mts.map +1 -0
  249. package/dist/index.d.mts +2 -2
  250. package/dist/index.mjs +48 -48
  251. package/dist/{load-Cx27ki1l.mjs → load-Dg5gtWma.mjs} +2 -2
  252. package/dist/{load-Cx27ki1l.mjs.map → load-Dg5gtWma.mjs.map} +1 -1
  253. package/dist/{loader-Be3ouI5L.mjs → loader-D4rigvjR.mjs} +4 -4
  254. package/dist/{loader-Be3ouI5L.mjs.map → loader-D4rigvjR.mjs.map} +1 -1
  255. package/dist/media/local-runtime.d.mts +2 -2
  256. package/dist/media/local-runtime.mjs +5 -5
  257. package/dist/{media-kIV1IxFf.mjs → media-BJ6SRY3g.mjs} +8 -4
  258. package/dist/media-BJ6SRY3g.mjs.map +1 -0
  259. package/dist/{media-BjhhENaJ.mjs → media-its1WLYv.mjs} +2 -2
  260. package/dist/{media-BjhhENaJ.mjs.map → media-its1WLYv.mjs.map} +1 -1
  261. package/dist/{media-upload-D2wk3EIt.mjs → media-upload-DNu3QySc.mjs} +4 -4
  262. package/dist/{media-upload-D2wk3EIt.mjs.map → media-upload-DNu3QySc.mjs.map} +1 -1
  263. package/dist/{media-usage-CljdO1mc.mjs → media-usage-DPQ3K4xB.mjs} +6 -6
  264. package/dist/{media-usage-CljdO1mc.mjs.map → media-usage-DPQ3K4xB.mjs.map} +1 -1
  265. package/dist/{menus-CZyG6rvx.mjs → menus-BMGzWyWH.mjs} +15 -8
  266. package/dist/menus-BMGzWyWH.mjs.map +1 -0
  267. package/dist/{menus-BcyElFtI.mjs → menus-CPf_SW7u.mjs} +86 -8
  268. package/dist/menus-CPf_SW7u.mjs.map +1 -0
  269. package/dist/{parse-C_-6klII.mjs → parse-53zyxlpv.mjs} +2 -2
  270. package/dist/{parse-C_-6klII.mjs.map → parse-53zyxlpv.mjs.map} +1 -1
  271. package/dist/plugin-utils.d.mts +2 -2
  272. package/dist/plugins/adapt-sandbox-entry.d.mts +2 -2
  273. package/dist/{query-DR73ZNfm.mjs → query-BbJQ-dGg.mjs} +14 -14
  274. package/dist/{query-DR73ZNfm.mjs.map → query-BbJQ-dGg.mjs.map} +1 -1
  275. package/dist/{query-Di7DOmPV.mjs → query-DdFGHzQF.mjs} +3 -3
  276. package/dist/{query-Di7DOmPV.mjs.map → query-DdFGHzQF.mjs.map} +1 -1
  277. package/dist/{rate-limit-CMj83JNW.mjs → rate-limit-D3IEiUi2.mjs} +2 -2
  278. package/dist/{rate-limit-CMj83JNW.mjs.map → rate-limit-D3IEiUi2.mjs.map} +1 -1
  279. package/dist/{redirect-CgLPYflR.mjs → redirect-BoUac4NT.mjs} +3 -3
  280. package/dist/{redirect-CgLPYflR.mjs.map → redirect-BoUac4NT.mjs.map} +1 -1
  281. package/dist/{redirects-B7t9bKsL.mjs → redirects-ChbpqKiS.mjs} +3 -3
  282. package/dist/{redirects-B7t9bKsL.mjs.map → redirects-ChbpqKiS.mjs.map} +1 -1
  283. package/dist/{redirects-BBq3n2Rj.mjs → redirects-D457qwt0.mjs} +8 -8
  284. package/dist/redirects-D457qwt0.mjs.map +1 -0
  285. package/dist/{registry-FV15nLge.mjs → registry-y21kjhfG.mjs} +6 -6
  286. package/dist/{registry-FV15nLge.mjs.map → registry-y21kjhfG.mjs.map} +1 -1
  287. package/dist/{relation-9M9j_UWo.mjs → relation-Du0r04E0.mjs} +3 -3
  288. package/dist/{relation-9M9j_UWo.mjs.map → relation-Du0r04E0.mjs.map} +1 -1
  289. package/dist/{relations-Bh8jlFsU.d.mts → relations-BKybBoOX.d.mts} +12 -8
  290. package/dist/relations-BKybBoOX.d.mts.map +1 -0
  291. package/dist/{relations-5_avdrN_.mjs → relations-CZMpBqEd.mjs} +3 -3
  292. package/dist/{relations-5_avdrN_.mjs.map → relations-CZMpBqEd.mjs.map} +1 -1
  293. package/dist/{relations-BKvO39-9.mjs → relations-DtX1UMBH.mjs} +13 -7
  294. package/dist/relations-DtX1UMBH.mjs.map +1 -0
  295. package/dist/{resolve-Cd9dzclN.mjs → resolve-DFr4kq72.mjs} +2 -2
  296. package/dist/{resolve-Cd9dzclN.mjs.map → resolve-DFr4kq72.mjs.map} +1 -1
  297. package/dist/{runner-DfnZ5eUr.mjs → runner-BdeLEgad.mjs} +3 -3
  298. package/dist/{runner-DfnZ5eUr.mjs.map → runner-BdeLEgad.mjs.map} +1 -1
  299. package/dist/runtime.d.mts +2 -2
  300. package/dist/runtime.mjs +3 -3
  301. package/dist/{schema-BXxlHeAf.mjs → schema-BH8P8vaC.mjs} +3 -3
  302. package/dist/{schema-BXxlHeAf.mjs.map → schema-BH8P8vaC.mjs.map} +1 -1
  303. package/dist/{scopes-Bl4IwHA-.mjs → scopes-DTIkIaGA.mjs} +2 -2
  304. package/dist/{scopes-Bl4IwHA-.mjs.map → scopes-DTIkIaGA.mjs.map} +1 -1
  305. package/dist/{search-Bff-7jFt.mjs → search-D-Yhpmvs.mjs} +8 -7
  306. package/dist/search-D-Yhpmvs.mjs.map +1 -0
  307. package/dist/{secrets-CSwQIl4q.mjs → secrets-CQ-69kF9.mjs} +23 -17
  308. package/dist/secrets-CQ-69kF9.mjs.map +1 -0
  309. package/dist/{sections-CwW4s1al.mjs → sections-CzVBAKjw.mjs} +3 -3
  310. package/dist/{sections-CwW4s1al.mjs.map → sections-CzVBAKjw.mjs.map} +1 -1
  311. package/dist/seed/index.mjs +16 -16
  312. package/dist/seo/index.mjs +12 -12
  313. package/dist/{seo-2cmFHZns.mjs → seo-kJzVAmmu.mjs} +2 -2
  314. package/dist/{seo-2cmFHZns.mjs.map → seo-kJzVAmmu.mjs.map} +1 -1
  315. package/dist/{service-DkGTWGIi.mjs → service-CQnc276a.mjs} +2 -2
  316. package/dist/{service-DkGTWGIi.mjs.map → service-CQnc276a.mjs.map} +1 -1
  317. package/dist/{settings-CpA4lQFt.mjs → settings-C2PaBS49.mjs} +3 -3
  318. package/dist/{settings-CpA4lQFt.mjs.map → settings-C2PaBS49.mjs.map} +1 -1
  319. package/dist/{settings-C4s8hFQm.mjs → settings-Dtc0DU31.mjs} +3 -3
  320. package/dist/{settings-C4s8hFQm.mjs.map → settings-Dtc0DU31.mjs.map} +1 -1
  321. package/dist/{taxonomies-DjSKBZpq.mjs → taxonomies-HI9fnTdp.mjs} +7 -7
  322. package/dist/{taxonomies-DjSKBZpq.mjs.map → taxonomies-HI9fnTdp.mjs.map} +1 -1
  323. package/dist/{taxonomies-Ce49uIzY.mjs → taxonomies-rMeBzOjX.mjs} +26 -17
  324. package/dist/taxonomies-rMeBzOjX.mjs.map +1 -0
  325. package/dist/{taxonomy-DfVooU4W.mjs → taxonomy-0mCI25HN.mjs} +3 -3
  326. package/dist/{taxonomy-DfVooU4W.mjs.map → taxonomy-0mCI25HN.mjs.map} +1 -1
  327. package/dist/{types-D1iJ3DpO.mjs → types-CrRUFdej.mjs} +2 -2
  328. package/dist/{types-D1iJ3DpO.mjs.map → types-CrRUFdej.mjs.map} +1 -1
  329. package/dist/{user-Bh-L1qo6.mjs → user-aTXqmXBz.mjs} +3 -3
  330. package/dist/{user-Bh-L1qo6.mjs.map → user-aTXqmXBz.mjs.map} +1 -1
  331. package/dist/{validate-V9nCwq_-.mjs → validate-CDT1jl6_.mjs} +11 -6
  332. package/dist/validate-CDT1jl6_.mjs.map +1 -0
  333. package/dist/validate-DULfgpJP.d.mts.map +1 -1
  334. package/dist/{validation-BsVUJfsP.mjs → validation-DlD0E35W.mjs} +8 -8
  335. package/dist/{validation-BsVUJfsP.mjs.map → validation-DlD0E35W.mjs.map} +1 -1
  336. package/dist/version-Ci6bw6YK.mjs +7 -0
  337. package/dist/{version-907opKac.mjs.map → version-Ci6bw6YK.mjs.map} +1 -1
  338. package/dist/{widgets-DGv1Z04V.mjs → widgets-5fipNkMT.mjs} +2 -2
  339. package/dist/{widgets-DGv1Z04V.mjs.map → widgets-5fipNkMT.mjs.map} +1 -1
  340. package/dist/{wxr-taxonomies-Cs1N6O8z.mjs → wxr-taxonomies-BmUnBNgz.mjs} +4 -4
  341. package/dist/{wxr-taxonomies-Cs1N6O8z.mjs.map → wxr-taxonomies-BmUnBNgz.mjs.map} +1 -1
  342. package/dist/{zod-generator-B5prQ5M4.mjs → zod-generator-CwkHWz4f.mjs} +2 -2
  343. package/dist/{zod-generator-B5prQ5M4.mjs.map → zod-generator-CwkHWz4f.mjs.map} +1 -1
  344. package/package.json +5 -5
  345. package/src/api/handlers/bylines.ts +5 -4
  346. package/src/api/handlers/content.ts +25 -7
  347. package/src/api/handlers/menus.ts +11 -6
  348. package/src/api/handlers/relations.ts +7 -2
  349. package/src/api/handlers/taxonomies.ts +22 -14
  350. package/src/api/schemas/bylines.ts +4 -4
  351. package/src/api/schemas/common.ts +7 -6
  352. package/src/api/schemas/menus.ts +2 -1
  353. package/src/api/schemas/relations.ts +3 -1
  354. package/src/api/schemas/taxonomies.ts +4 -2
  355. package/src/astro/routes/api/admin/bylines/index.ts +5 -8
  356. package/src/astro/routes/api/oauth/authorize.ts +42 -10
  357. package/src/components/Gallery.astro +141 -26
  358. package/src/config/secrets.ts +25 -19
  359. package/src/content/converters/gallery.ts +61 -0
  360. package/src/content/converters/portable-text-to-prosemirror.ts +19 -0
  361. package/src/content/converters/prosemirror-to-portable-text.ts +18 -0
  362. package/src/content/converters/types.ts +36 -0
  363. package/src/database/dialect-helpers.ts +3 -4
  364. package/src/database/pg-migration-lock.ts +1 -4
  365. package/src/emdash-runtime.ts +55 -17
  366. package/src/i18n/config.ts +8 -0
  367. package/src/i18n/repair-locale-casing.ts +51 -0
  368. package/src/search/query.ts +3 -2
  369. package/src/seed/apply.ts +9 -7
  370. package/src/seed/validate.ts +15 -4
  371. package/dist/api-b8WIiGU4.mjs.map +0 -1
  372. package/dist/apply-CmIJK9j8.mjs.map +0 -1
  373. package/dist/bylines-BJbT4gKS.mjs.map +0 -1
  374. package/dist/config-CVssduLe.mjs.map +0 -1
  375. package/dist/dialect-helpers-HxEQGl_1.mjs.map +0 -1
  376. package/dist/index-wYnC6u4o.d.mts.map +0 -1
  377. package/dist/media-kIV1IxFf.mjs.map +0 -1
  378. package/dist/menus-BcyElFtI.mjs.map +0 -1
  379. package/dist/menus-CZyG6rvx.mjs.map +0 -1
  380. package/dist/redirects-BBq3n2Rj.mjs.map +0 -1
  381. package/dist/relations-BKvO39-9.mjs.map +0 -1
  382. package/dist/relations-Bh8jlFsU.d.mts.map +0 -1
  383. package/dist/search-Bff-7jFt.mjs.map +0 -1
  384. package/dist/secrets-CSwQIl4q.mjs.map +0 -1
  385. package/dist/taxonomies-Ce49uIzY.mjs.map +0 -1
  386. package/dist/validate-V9nCwq_-.mjs.map +0 -1
  387. package/dist/version-907opKac.mjs +0 -7
@@ -36,6 +36,8 @@ import type {
36
36
  ContentDateField,
37
37
  } from "./database/repositories/types.js";
38
38
  import { validateIdentifier } from "./database/validate.js";
39
+ import { getI18nConfig } from "./i18n/config.js";
40
+ import { repairLocaleCasing } from "./i18n/repair-locale-casing.js";
39
41
  import { normalizeMediaValue } from "./media/normalize.js";
40
42
  import type { MediaProvider, MediaProviderCapabilities } from "./media/types.js";
41
43
  import {
@@ -71,6 +73,12 @@ import { createSingleFlightCache, singleFlightCached } from "./utils/single-flig
71
73
  import { COMMIT, VERSION } from "./version.js";
72
74
 
73
75
  const LEADING_SLASH_PATTERN = /^\//;
76
+ const LOCALE_CASING_REPAIR_OPTION = "emdash:repair_locale_casing";
77
+
78
+ function getLocaleCasingRepairVersion(locales: readonly string[]): string | null {
79
+ if (locales.length === 0) return null;
80
+ return `1:${locales.toSorted().join(",")}`;
81
+ }
74
82
 
75
83
  /**
76
84
  * Parse a JSON column expected to contain an array of strings.
@@ -1130,6 +1138,10 @@ export class EmDashRuntime {
1130
1138
  const storage = EmDashRuntime.getStorage(deps);
1131
1139
 
1132
1140
  let pluginStates: Map<string, string> = new Map();
1141
+ const configuredLocales: string[] =
1142
+ virtualConfig?.i18n?.locales ?? getI18nConfig()?.locales ?? [];
1143
+ const localeCasingRepairVersion = getLocaleCasingRepairVersion(configuredLocales);
1144
+ let storedLocaleCasingRepairVersion: string | undefined;
1133
1145
  let siteInfo:
1134
1146
  | {
1135
1147
  siteName?: string;
@@ -1175,7 +1187,9 @@ export class EmDashRuntime {
1175
1187
  "emdash:site_title",
1176
1188
  "emdash:site_url",
1177
1189
  "emdash:locale",
1190
+ LOCALE_CASING_REPAIR_OPTION,
1178
1191
  ]);
1192
+ storedLocaleCasingRepairVersion = siteOpts.get(LOCALE_CASING_REPAIR_OPTION);
1179
1193
  return {
1180
1194
  siteName: siteOpts.get("emdash:site_title") ?? undefined,
1181
1195
  siteUrl: siteOpts.get("emdash:site_url") ?? undefined,
@@ -1241,6 +1255,20 @@ export class EmDashRuntime {
1241
1255
 
1242
1256
  await Promise.all(coldStartReads);
1243
1257
 
1258
+ if (
1259
+ localeCasingRepairVersion &&
1260
+ (configuredLocales.some(
1261
+ (locale) => locale.includes("-") || locale !== locale.toLowerCase(),
1262
+ ) ||
1263
+ storedLocaleCasingRepairVersion !== undefined) &&
1264
+ storedLocaleCasingRepairVersion !== localeCasingRepairVersion
1265
+ ) {
1266
+ await phase("rt.locale", "Repair locale casing", async () => {
1267
+ await repairLocaleCasing(db, configuredLocales);
1268
+ await new OptionsRepository(db).set(LOCALE_CASING_REPAIR_OPTION, localeCasingRepairVersion);
1269
+ });
1270
+ }
1271
+
1244
1272
  // Auto-seed the default schema for a first load that skipped the setup
1245
1273
  // wizard (the wizard and dev-bypass apply seeds explicitly). Run under a
1246
1274
  // per-isolate lock keyed by the configured db so a reclaimed-and-rerun
@@ -2965,7 +2993,7 @@ export class EmDashRuntime {
2965
2993
  await this.refreshContentUsageAfterSuccessfulWrite(collection, [result.data.id]);
2966
2994
  }
2967
2995
 
2968
- // Run afterDelete hooks (fire-and-forget)
2996
+ // Run afterDelete hooks (deferred past the response via after())
2969
2997
  if (result.success) {
2970
2998
  this.runAfterDeleteHooks(id, collection, false);
2971
2999
  }
@@ -3052,7 +3080,7 @@ export class EmDashRuntime {
3052
3080
  await this.refreshContentUsageAfterSuccessfulWrite(collection, [result.data.item.id]);
3053
3081
  }
3054
3082
 
3055
- // Run afterUnpublish hooks (fire-and-forget)
3083
+ // Run afterUnpublish hooks (deferred past the response via after())
3056
3084
  if (result.success && result.data) {
3057
3085
  this.runAfterUnpublishHooks(contentItemToRecord(result.data.item), collection);
3058
3086
  }
@@ -3746,24 +3774,34 @@ export class EmDashRuntime {
3746
3774
  }
3747
3775
 
3748
3776
  private runAfterDeleteHooks(id: string, collection: string, permanent: boolean): void {
3749
- // Trusted plugins
3750
- if (this.hooks.hasHooks("content:afterDelete")) {
3751
- this.hooks
3752
- .runContentAfterDelete(id, collection, permanent)
3753
- .catch((err) => console.error("EmDash afterDelete hook error:", err));
3754
- }
3777
+ after(async () => {
3778
+ // Trusted plugins
3779
+ if (this.hooks.hasHooks("content:afterDelete")) {
3780
+ try {
3781
+ await this.hooks.runContentAfterDelete(id, collection, permanent);
3782
+ } catch (err) {
3783
+ console.error("EmDash afterDelete hook error:", err);
3784
+ }
3785
+ }
3755
3786
 
3756
- // Sandboxed plugins
3757
- for (const [pluginKey, plugin] of this.sandboxedPlugins) {
3758
- const [pluginId] = pluginKey.split(":");
3759
- if (!pluginId || !this.isPluginEnabled(pluginId)) continue;
3787
+ // Sandboxed plugins
3788
+ const tasks: Promise<void>[] = [];
3789
+ for (const [pluginKey, plugin] of this.sandboxedPlugins) {
3790
+ const [pluginId] = pluginKey.split(":");
3791
+ if (!pluginId || !this.isPluginEnabled(pluginId)) continue;
3760
3792
 
3761
- plugin
3762
- .invokeHook("content:afterDelete", { id, collection, permanent })
3763
- .catch((err) =>
3764
- console.error(`EmDash: Sandboxed plugin ${pluginId} afterDelete error:`, err),
3793
+ tasks.push(
3794
+ (async () => {
3795
+ try {
3796
+ await plugin.invokeHook("content:afterDelete", { id, collection, permanent });
3797
+ } catch (err) {
3798
+ console.error(`EmDash: Sandboxed plugin ${pluginId} afterDelete error:`, err);
3799
+ }
3800
+ })(),
3765
3801
  );
3766
- }
3802
+ }
3803
+ await Promise.allSettled(tasks);
3804
+ });
3767
3805
  }
3768
3806
 
3769
3807
  private runDeferredContentHook(
@@ -30,6 +30,14 @@ export function getI18nConfig(): I18nConfig | null {
30
30
  return _config ?? null;
31
31
  }
32
32
 
33
+ /** Match a locale to the exact casing used by the site configuration. */
34
+ export function resolveConfiguredLocale(locale: string): string {
35
+ return (
36
+ _config?.locales.find((configured) => configured.toLowerCase() === locale.toLowerCase()) ??
37
+ locale
38
+ );
39
+ }
40
+
33
41
  /**
34
42
  * Check if i18n is enabled.
35
43
  * Returns true when multiple locales are configured.
@@ -0,0 +1,51 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ import { listTablesLike } from "../database/dialect-helpers.js";
5
+ import type { Database } from "../database/types.js";
6
+
7
+ /** Rewrite stored locales to the exact casing used by the site configuration. */
8
+ export async function repairLocaleCasing(
9
+ db: Kysely<Database>,
10
+ configuredLocales: readonly string[],
11
+ ): Promise<void> {
12
+ const tableNames = await listTablesLike(db, "ec_%");
13
+
14
+ for (const tableName of tableNames) {
15
+ const table = sql.ref(tableName);
16
+ const slug = tableName.slice("ec_".length);
17
+ for (const locale of configuredLocales) {
18
+ await sql`
19
+ UPDATE ${table} AS target
20
+ SET locale = ${locale}
21
+ WHERE lower(target.locale) = lower(${locale})
22
+ AND target.locale != ${locale}
23
+ AND NOT EXISTS (
24
+ SELECT 1
25
+ FROM ${table} AS existing
26
+ WHERE existing.slug = target.slug AND existing.locale = ${locale}
27
+ )
28
+ AND target.id = (
29
+ SELECT MIN(candidate.id)
30
+ FROM ${table} AS candidate
31
+ WHERE candidate.slug = target.slug
32
+ AND lower(candidate.locale) = lower(${locale})
33
+ AND candidate.locale != ${locale}
34
+ )
35
+ `.execute(db);
36
+
37
+ await sql`
38
+ UPDATE content_taxonomies AS pivot
39
+ SET locale = ${locale}
40
+ WHERE pivot.collection = ${slug}
41
+ AND lower(pivot.locale) = lower(${locale})
42
+ AND pivot.locale != ${locale}
43
+ AND EXISTS (
44
+ SELECT 1
45
+ FROM ${table} AS content
46
+ WHERE content.id = pivot.entry_id AND content.locale = ${locale}
47
+ )
48
+ `.execute(db);
49
+ }
50
+ }
51
+ }
@@ -10,6 +10,7 @@ import { sql } from "kysely";
10
10
  import { encodeCursor, decodeCursor, InvalidCursorError } from "../database/repositories/types.js";
11
11
  import type { Database } from "../database/types.js";
12
12
  import { validateIdentifier } from "../database/validate.js";
13
+ import { resolveConfiguredLocale } from "../i18n/config.js";
13
14
  import { getDb } from "../loader.js";
14
15
  import { FTSManager } from "./fts-manager.js";
15
16
  import type {
@@ -250,7 +251,7 @@ async function searchSingleCollection(
250
251
  const contentTable = ftsManager.getContentTableName(collection);
251
252
  const limit = options.limit ?? 20;
252
253
  const status = options.status ?? "published";
253
- const locale = options.locale;
254
+ const locale = options.locale ? resolveConfiguredLocale(options.locale) : undefined;
254
255
 
255
256
  // Check if FTS table exists
256
257
  if (!(await ftsManager.ftsTableExists(collection))) {
@@ -397,7 +398,7 @@ export async function getSuggestions(
397
398
  options: SuggestOptions = {},
398
399
  ): Promise<Suggestion[]> {
399
400
  const limit = options.limit ?? 5;
400
- const locale = options.locale;
401
+ const locale = options.locale ? resolveConfiguredLocale(options.locale) : undefined;
401
402
 
402
403
  // Get searchable collections
403
404
  let collections = options.collections;
package/src/seed/apply.ts CHANGED
@@ -19,7 +19,7 @@ import { TaxonomyRepository } from "../database/repositories/taxonomy.js";
19
19
  import { withTransaction } from "../database/transaction.js";
20
20
  import type { Database } from "../database/types.js";
21
21
  import type { MediaValue } from "../fields/types.js";
22
- import { getI18nConfig } from "../i18n/config.js";
22
+ import { getI18nConfig, resolveConfiguredLocale } from "../i18n/config.js";
23
23
  import { ssrfSafeFetch, validateExternalUrl } from "../import/ssrf.js";
24
24
  import { markContentMediaUsageCollectionStaleSafely } from "../media/usage/content-refresh.js";
25
25
  import { SchemaRegistry } from "../schema/registry.js";
@@ -263,7 +263,7 @@ export async function applySeed(
263
263
  const termSeedIdMap = new Map<string, string>();
264
264
 
265
265
  for (const taxonomy of seed.taxonomies) {
266
- const defLocale = taxonomy.locale ?? defaultLocale;
266
+ const defLocale = resolveConfiguredLocale(taxonomy.locale ?? defaultLocale);
267
267
 
268
268
  // (name, locale) is the UNIQUE key after migration 036.
269
269
  const existingDef = await db
@@ -340,7 +340,7 @@ export async function applySeed(
340
340
  );
341
341
  } else {
342
342
  for (const term of taxonomy.terms) {
343
- const termLocale = term.locale ?? defLocale;
343
+ const termLocale = resolveConfiguredLocale(term.locale ?? defLocale);
344
344
  const existing = await termRepo.findBySlug(taxonomy.name, term.slug, termLocale);
345
345
  if (existing) {
346
346
  if (onConflict === "error") {
@@ -464,7 +464,7 @@ export async function applySeed(
464
464
  // Resolve the entry's locale up front so a non-`en` single-locale
465
465
  // export (which omits `locale`) is filed under the project default
466
466
  // rather than `en` (#1421).
467
- const entryLocale = entry.locale ?? defaultLocale;
467
+ const entryLocale = resolveConfiguredLocale(entry.locale ?? defaultLocale);
468
468
 
469
469
  // Check if entry exists (by slug + locale for locale-aware lookup)
470
470
  const existing = await contentRepo.findBySlug(collectionSlug, entry.slug, entryLocale);
@@ -621,7 +621,7 @@ export async function applySeed(
621
621
  const itemSeedIdMap = new Map<string, { id: string; translationGroup: string }>();
622
622
 
623
623
  for (const menu of seed.menus) {
624
- const locale = menu.locale ?? defaultLocale;
624
+ const locale = resolveConfiguredLocale(menu.locale ?? defaultLocale);
625
625
  let lookup = db
626
626
  .selectFrom("_emdash_menus")
627
627
  .selectAll()
@@ -867,6 +867,8 @@ async function applyHierarchicalTerms(
867
867
  ): Promise<void> {
868
868
  // "locale::slug" -> id, so the same slug can resolve per locale.
869
869
  const slugToId = new Map<string, string>();
870
+ const resolveTermLocale = (term: SeedTaxonomyTerm) =>
871
+ resolveConfiguredLocale(term.locale ?? defLocale);
870
872
 
871
873
  // Multiple passes — handles deep nesting and translationOf forward refs.
872
874
  let remaining = [...terms];
@@ -876,7 +878,7 @@ async function applyHierarchicalTerms(
876
878
  const processedThisPass: string[] = [];
877
879
 
878
880
  for (const term of remaining) {
879
- const termLocale = term.locale ?? defLocale;
881
+ const termLocale = resolveTermLocale(term);
880
882
  const parentReady = !term.parent || slugToId.has(`${termLocale}::${term.parent}`);
881
883
  const translationReady = !term.translationOf || termSeedIdMap.has(term.translationOf);
882
884
 
@@ -921,7 +923,7 @@ async function applyHierarchicalTerms(
921
923
  }
922
924
 
923
925
  remaining = remaining.filter(
924
- (t) => !processedThisPass.includes(t.slug + "::" + (t.locale ?? defLocale)),
926
+ (term) => !processedThisPass.includes(term.slug + "::" + resolveTermLocale(term)),
925
927
  );
926
928
  maxPasses--;
927
929
  }
@@ -4,6 +4,7 @@
4
4
  * Validates a seed file structure before applying it.
5
5
  */
6
6
 
7
+ import { getI18nConfig, resolveConfiguredLocale } from "../i18n/config.js";
7
8
  import { FIELD_TYPES } from "../schema/types.js";
8
9
  import type { SeedFile, SeedMenuItem, ValidationResult } from "./types.js";
9
10
 
@@ -49,6 +50,9 @@ export function validateSeed(data: unknown): ValidationResult {
49
50
  }
50
51
 
51
52
  const seed = data as Partial<SeedFile>;
53
+ const defaultLocale =
54
+ getI18nConfig()?.defaultLocale ??
55
+ (typeof seed.defaultLocale === "string" ? seed.defaultLocale : "en");
52
56
 
53
57
  // Required fields
54
58
  if (!seed.version) {
@@ -163,7 +167,8 @@ export function validateSeed(data: unknown): ValidationResult {
163
167
  errors.push(`${prefix}: name is required`);
164
168
  } else {
165
169
  // Uniqueness is per (name, locale).
166
- const key = `${taxonomy.name}::${taxonomy.locale ?? ""}`;
170
+ const locale = resolveConfiguredLocale(taxonomy.locale ?? defaultLocale);
171
+ const key = `${taxonomy.name}::${locale}`;
167
172
  if (taxonomyNames.has(key)) {
168
173
  errors.push(
169
174
  taxonomy.locale
@@ -206,7 +211,10 @@ export function validateSeed(data: unknown): ValidationResult {
206
211
  } else {
207
212
  // Uniqueness is per (slug, locale) so the same slug can repeat
208
213
  // across locale variants of the def.
209
- const key = `${term.slug}::${term.locale ?? taxonomy.locale ?? ""}`;
214
+ const locale = resolveConfiguredLocale(
215
+ term.locale ?? taxonomy.locale ?? defaultLocale,
216
+ );
217
+ const key = `${term.slug}::${locale}`;
210
218
  if (termSlugs.has(key)) {
211
219
  errors.push(
212
220
  `${termPrefix}.slug: duplicate term slug "${term.slug}" in taxonomy "${taxonomy.name}"`,
@@ -233,7 +241,9 @@ export function validateSeed(data: unknown): ValidationResult {
233
241
  if (taxonomy.hierarchical && taxonomy.terms) {
234
242
  for (let j = 0; j < taxonomy.terms.length; j++) {
235
243
  const term = taxonomy.terms[j];
236
- const termLocale = term.locale ?? taxonomy.locale ?? "";
244
+ const termLocale = resolveConfiguredLocale(
245
+ term.locale ?? taxonomy.locale ?? defaultLocale,
246
+ );
237
247
  if (term.parent && !termSlugs.has(`${term.parent}::${termLocale}`)) {
238
248
  errors.push(
239
249
  `${prefix}.terms[${j}].parent: parent term "${term.parent}" not found in taxonomy`,
@@ -268,7 +278,8 @@ export function validateSeed(data: unknown): ValidationResult {
268
278
  } else {
269
279
  // Uniqueness is per (name, locale) — siblings of a translation
270
280
  // group share name but differ in locale.
271
- const key = `${menu.name}::${menu.locale ?? ""}`;
281
+ const locale = resolveConfiguredLocale(menu.locale ?? defaultLocale);
282
+ const key = `${menu.name}::${locale}`;
272
283
  if (menuNames.has(key)) {
273
284
  errors.push(
274
285
  menu.locale