emdash 1.1.0 → 1.3.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 (1571) hide show
  1. package/dist/action-token-SK8zyN7w.mjs +26 -0
  2. package/dist/action-token-SK8zyN7w.mjs.map +1 -0
  3. package/dist/activation-Dim4YMM7.mjs +387 -0
  4. package/dist/activation-Dim4YMM7.mjs.map +1 -0
  5. package/dist/adapters-F_xorvWv.d.mts +173 -0
  6. package/dist/adapters-F_xorvWv.d.mts.map +1 -0
  7. package/dist/allowed-origins-CEug-p0t.mjs +116 -0
  8. package/dist/allowed-origins-CEug-p0t.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.d.mts.map +1 -1
  11. package/dist/api/route-utils.mjs +48 -46
  12. package/dist/api/route-utils.mjs.map +1 -1
  13. package/dist/api/schemas/index.d.mts +2 -2
  14. package/dist/api/schemas/index.mjs +10 -10
  15. package/dist/api-D-7BNHoz.mjs +5025 -0
  16. package/dist/api-D-7BNHoz.mjs.map +1 -0
  17. package/dist/api-tokens-Bx38ZCQp.mjs +173 -0
  18. package/dist/api-tokens-Bx38ZCQp.mjs.map +1 -0
  19. package/dist/apply-T7ATgzCh.mjs +1702 -0
  20. package/dist/apply-T7ATgzCh.mjs.map +1 -0
  21. package/dist/approvals-D-m6wvGl.mjs +460 -0
  22. package/dist/approvals-D-m6wvGl.mjs.map +1 -0
  23. package/dist/artifact-fetch-DIh7iyOV.mjs +659 -0
  24. package/dist/artifact-fetch-DIh7iyOV.mjs.map +1 -0
  25. package/dist/artifacts-htGyfCSt.mjs +307 -0
  26. package/dist/artifacts-htGyfCSt.mjs.map +1 -0
  27. package/dist/astro/image-endpoint.d.mts.map +1 -1
  28. package/dist/astro/image-endpoint.mjs +26 -6
  29. package/dist/astro/image-endpoint.mjs.map +1 -1
  30. package/dist/astro/index.d.mts +14 -14
  31. package/dist/astro/index.d.mts.map +1 -1
  32. package/dist/astro/index.mjs +324 -23
  33. package/dist/astro/index.mjs.map +1 -1
  34. package/dist/astro/middleware/auth.d.mts +12 -12
  35. package/dist/astro/middleware/auth.d.mts.map +1 -1
  36. package/dist/astro/middleware/auth.mjs +18 -13
  37. package/dist/astro/middleware/auth.mjs.map +1 -1
  38. package/dist/astro/middleware/media-usage-write-fence.mjs +5 -5
  39. package/dist/astro/middleware/redirect.d.mts.map +1 -1
  40. package/dist/astro/middleware/redirect.mjs +81 -46
  41. package/dist/astro/middleware/redirect.mjs.map +1 -1
  42. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  43. package/dist/astro/middleware/request-context.mjs +117 -56
  44. package/dist/astro/middleware/request-context.mjs.map +1 -1
  45. package/dist/astro/middleware/setup.mjs +1 -1
  46. package/dist/astro/middleware.d.mts +12 -12
  47. package/dist/astro/middleware.d.mts.map +1 -1
  48. package/dist/astro/middleware.mjs +145 -415
  49. package/dist/astro/middleware.mjs.map +1 -1
  50. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -14
  51. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -14
  52. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +7 -6
  53. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  54. package/dist/astro/routes/api/admin/api-tokens/index.mjs +8 -7
  55. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -6
  57. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +16 -16
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs +16 -16
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +16 -16
  60. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +22 -21
  61. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  62. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +22 -21
  63. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  64. package/dist/astro/routes/api/admin/bylines/index.mjs +22 -21
  65. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  66. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +18 -18
  67. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -7
  68. package/dist/astro/routes/api/admin/comments/bulk.mjs +17 -17
  69. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -7
  70. package/dist/astro/routes/api/admin/comments/index.mjs +17 -17
  71. package/dist/astro/routes/api/admin/core-update.mjs +7 -7
  72. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -6
  73. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -5
  74. package/dist/astro/routes/api/admin/media-usage/activation.mjs +20 -20
  75. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +21 -21
  76. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +21 -21
  77. package/dist/astro/routes/api/admin/media-usage/progress.mjs +23 -22
  78. package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/media-usage/repair.mjs +29 -28
  80. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  81. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +21 -21
  82. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +21 -21
  83. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  84. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  85. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +8 -8
  86. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +8 -8
  87. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -70
  88. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  89. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +7 -7
  90. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -69
  91. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +71 -70
  93. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +80 -79
  95. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -70
  97. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +7 -7
  99. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -69
  100. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +79 -78
  102. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -69
  104. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  105. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +71 -70
  106. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  107. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +81 -80
  108. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  109. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +10 -10
  110. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  111. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +73 -72
  112. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +7 -7
  114. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -70
  115. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -69
  117. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +5 -5
  119. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -69
  120. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  121. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +7 -7
  122. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -69
  123. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +4 -4
  125. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +38 -37
  126. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -1
  127. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +38 -37
  128. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +40 -39
  130. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -1
  131. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +40 -39
  132. package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -1
  133. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +40 -39
  134. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -1
  135. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +41 -40
  136. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -1
  137. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +41 -40
  138. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -1
  139. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +40 -39
  140. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -1
  141. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +41 -40
  142. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -1
  143. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +42 -41
  144. package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -1
  145. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +40 -39
  146. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -1
  147. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +40 -39
  148. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -1
  149. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +42 -41
  150. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -1
  151. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +40 -39
  152. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -1
  153. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +42 -41
  154. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -1
  155. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +40 -39
  156. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -1
  157. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +40 -39
  158. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -1
  159. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +42 -41
  160. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -1
  161. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +40 -39
  162. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -1
  163. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +40 -39
  164. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -1
  165. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +42 -41
  166. package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -1
  167. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
  168. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
  169. package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -14
  170. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +6 -6
  171. package/dist/astro/routes/api/admin/users/index.mjs +14 -14
  172. package/dist/astro/routes/api/auth/dev-bypass.mjs +6 -6
  173. package/dist/astro/routes/api/auth/handover.d.mts +8 -0
  174. package/dist/astro/routes/api/auth/handover.d.mts.map +1 -0
  175. package/dist/astro/routes/api/auth/handover.mjs +49 -0
  176. package/dist/astro/routes/api/auth/handover.mjs.map +1 -0
  177. package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
  178. package/dist/astro/routes/api/auth/invite/complete.mjs +19 -19
  179. package/dist/astro/routes/api/auth/invite/index.mjs +16 -16
  180. package/dist/astro/routes/api/auth/invite/register-options.mjs +17 -17
  181. package/dist/astro/routes/api/auth/logout.mjs +5 -5
  182. package/dist/astro/routes/api/auth/magic-link/send.mjs +19 -18
  183. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  184. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  185. package/dist/astro/routes/api/auth/magic-link/verify.mjs +23 -17
  186. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  187. package/dist/astro/routes/api/auth/me.mjs +15 -15
  188. package/dist/astro/routes/api/auth/mode.mjs +5 -5
  189. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +8 -8
  190. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  191. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -14
  192. package/dist/astro/routes/api/auth/passkey/index.mjs +4 -4
  193. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  194. package/dist/astro/routes/api/auth/passkey/options.mjs +27 -20
  195. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  196. package/dist/astro/routes/api/auth/passkey/register/options.mjs +17 -17
  197. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +18 -18
  198. package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -19
  199. package/dist/astro/routes/api/auth/signup/complete.mjs +19 -19
  200. package/dist/astro/routes/api/auth/signup/request.mjs +18 -17
  201. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  202. package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
  203. package/dist/astro/routes/api/calendar.mjs +15 -15
  204. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
  205. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +18 -18
  206. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
  207. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.d.mts.map +1 -1
  208. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -17
  209. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  210. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +7 -10
  211. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  212. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +20 -17
  213. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  214. package/dist/astro/routes/api/content/_collection_/_id_/permanent.d.mts.map +1 -1
  215. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +7 -6
  216. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  217. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +11 -11
  218. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +30 -29
  219. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  220. package/dist/astro/routes/api/content/_collection_/_id_/publish.d.mts.map +1 -1
  221. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -17
  222. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  223. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +35 -34
  224. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  225. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +35 -34
  226. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  227. package/dist/astro/routes/api/content/_collection_/_id_/restore.d.mts.map +1 -1
  228. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +7 -6
  229. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  230. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
  231. package/dist/astro/routes/api/content/_collection_/_id_/schedule.d.mts.map +1 -1
  232. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +19 -18
  233. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  234. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  235. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +31 -26
  236. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  237. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
  238. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.d.mts.map +1 -1
  239. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -17
  240. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  241. package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
  242. package/dist/astro/routes/api/content/_collection_/_id_.mjs +27 -20
  243. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  244. package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
  245. package/dist/astro/routes/api/content/_collection_/index.mjs +18 -21
  246. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  247. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -15
  248. package/dist/astro/routes/api/dashboard.d.mts.map +1 -1
  249. package/dist/astro/routes/api/dashboard.mjs +18 -12
  250. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  251. package/dist/astro/routes/api/dev/emails.mjs +5 -5
  252. package/dist/astro/routes/api/dev/scheduled-tasks.d.mts +12 -0
  253. package/dist/astro/routes/api/dev/scheduled-tasks.d.mts.map +1 -0
  254. package/dist/astro/routes/api/dev/scheduled-tasks.mjs +140 -0
  255. package/dist/astro/routes/api/dev/scheduled-tasks.mjs.map +1 -0
  256. package/dist/astro/routes/api/health.mjs +6 -6
  257. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  258. package/dist/astro/routes/api/import/probe.mjs +25 -23
  259. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  260. package/dist/astro/routes/api/import/wordpress/analyze.d.mts.map +1 -1
  261. package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -20
  262. package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
  263. package/dist/astro/routes/api/import/wordpress/execute.d.mts +15 -14
  264. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  265. package/dist/astro/routes/api/import/wordpress/execute.mjs +36 -30
  266. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  267. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  268. package/dist/astro/routes/api/import/wordpress/media.mjs +17 -17
  269. package/dist/astro/routes/api/import/wordpress/prepare.mjs +19 -17
  270. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  271. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +8 -0
  272. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  273. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +67 -31
  274. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  275. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  276. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +27 -26
  277. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  278. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  279. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +26 -23
  280. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  281. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  282. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
  283. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +63 -35
  284. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  285. package/dist/astro/routes/api/manifest.mjs +9 -6
  286. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  287. package/dist/astro/routes/api/mcp.mjs +135 -101
  288. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  289. package/dist/astro/routes/api/media/_id_/confirm.d.mts.map +1 -1
  290. package/dist/astro/routes/api/media/_id_/confirm.mjs +34 -18
  291. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  292. package/dist/astro/routes/api/media/_id_/replace.mjs +15 -15
  293. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -8
  294. package/dist/astro/routes/api/media/_id_/usage.mjs +31 -30
  295. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  296. package/dist/astro/routes/api/media/_id_.mjs +29 -28
  297. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  298. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +6 -6
  299. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  300. package/dist/astro/routes/api/media/file/_...key_.mjs +45 -15
  301. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  302. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -16
  303. package/dist/astro/routes/api/media/folders/index.mjs +16 -16
  304. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +5 -5
  305. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +5 -5
  306. package/dist/astro/routes/api/media/providers/index.mjs +5 -5
  307. package/dist/astro/routes/api/media/upload-url.mjs +40 -20
  308. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  309. package/dist/astro/routes/api/media.d.mts.map +1 -1
  310. package/dist/astro/routes/api/media.mjs +40 -29
  311. package/dist/astro/routes/api/media.mjs.map +1 -1
  312. package/dist/astro/routes/api/menus/_name_/items/_id_.d.mts.map +1 -1
  313. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +19 -18
  314. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  315. package/dist/astro/routes/api/menus/_name_/items.d.mts.map +1 -1
  316. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -17
  317. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  318. package/dist/astro/routes/api/menus/_name_/reorder.d.mts.map +1 -1
  319. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -17
  320. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  321. package/dist/astro/routes/api/menus/_name_/translations.d.mts.map +1 -1
  322. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -17
  323. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  324. package/dist/astro/routes/api/menus/_name_.d.mts.map +1 -1
  325. package/dist/astro/routes/api/menus/_name_.mjs +19 -18
  326. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  327. package/dist/astro/routes/api/menus/index.d.mts.map +1 -1
  328. package/dist/astro/routes/api/menus/index.mjs +18 -17
  329. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  330. package/dist/astro/routes/api/oauth/authorize.mjs +6 -6
  331. package/dist/astro/routes/api/oauth/device/authorize.mjs +8 -8
  332. package/dist/astro/routes/api/oauth/device/code.mjs +12 -11
  333. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  334. package/dist/astro/routes/api/oauth/device/token.mjs +11 -10
  335. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  336. package/dist/astro/routes/api/oauth/register.mjs +8 -7
  337. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  338. package/dist/astro/routes/api/oauth/token/refresh.mjs +8 -8
  339. package/dist/astro/routes/api/oauth/token/revoke.mjs +8 -8
  340. package/dist/astro/routes/api/oauth/token.mjs +8 -8
  341. package/dist/astro/routes/api/openapi.json.mjs +22 -22
  342. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  343. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +11 -11
  344. package/dist/astro/routes/api/redirects/404s/index.mjs +19 -19
  345. package/dist/astro/routes/api/redirects/404s/summary.mjs +19 -19
  346. package/dist/astro/routes/api/redirects/_id_.d.mts.map +1 -1
  347. package/dist/astro/routes/api/redirects/_id_.mjs +32 -23
  348. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  349. package/dist/astro/routes/api/redirects/index.d.mts.map +1 -1
  350. package/dist/astro/routes/api/redirects/index.mjs +24 -21
  351. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  352. package/dist/astro/routes/api/relations/_id_/index.mjs +35 -34
  353. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  354. package/dist/astro/routes/api/relations/index.mjs +35 -34
  355. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  356. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +5 -5
  357. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +16 -16
  358. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +71 -69
  359. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -1
  360. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +71 -69
  361. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -1
  362. package/dist/astro/routes/api/schema/block-types/index.mjs +71 -69
  363. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -1
  364. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -69
  365. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  366. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -69
  367. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  368. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -69
  369. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  370. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -69
  371. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  372. package/dist/astro/routes/api/schema/collections/index.mjs +71 -69
  373. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  374. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -69
  375. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  376. package/dist/astro/routes/api/schema/index.mjs +17 -16
  377. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  378. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -69
  379. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  380. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -69
  381. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  382. package/dist/astro/routes/api/search/enable.mjs +19 -18
  383. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  384. package/dist/astro/routes/api/search/index.mjs +18 -17
  385. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  386. package/dist/astro/routes/api/search/rebuild.mjs +19 -18
  387. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  388. package/dist/astro/routes/api/search/stats.mjs +9 -8
  389. package/dist/astro/routes/api/search/stats.mjs.map +1 -1
  390. package/dist/astro/routes/api/search/suggest.mjs +18 -17
  391. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  392. package/dist/astro/routes/api/sections/_slug_.mjs +18 -17
  393. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  394. package/dist/astro/routes/api/sections/index.mjs +18 -17
  395. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  396. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +7 -7
  397. package/dist/astro/routes/api/settings/backups/archives/index.mjs +7 -7
  398. package/dist/astro/routes/api/settings/backups/export.mjs +7 -7
  399. package/dist/astro/routes/api/settings/backups/index.mjs +8 -8
  400. package/dist/astro/routes/api/settings/domain-notify.d.mts +8 -0
  401. package/dist/astro/routes/api/settings/domain-notify.d.mts.map +1 -0
  402. package/dist/astro/routes/api/settings/domain-notify.mjs +125 -0
  403. package/dist/astro/routes/api/settings/domain-notify.mjs.map +1 -0
  404. package/dist/astro/routes/api/settings/domain.d.mts +9 -0
  405. package/dist/astro/routes/api/settings/domain.d.mts.map +1 -0
  406. package/dist/astro/routes/api/settings/domain.mjs +64 -0
  407. package/dist/astro/routes/api/settings/domain.mjs.map +1 -0
  408. package/dist/astro/routes/api/settings/email.mjs +6 -6
  409. package/dist/astro/routes/api/settings.d.mts.map +1 -1
  410. package/dist/astro/routes/api/settings.mjs +23 -20
  411. package/dist/astro/routes/api/settings.mjs.map +1 -1
  412. package/dist/astro/routes/api/setup/admin-verify.d.mts.map +1 -1
  413. package/dist/astro/routes/api/setup/admin-verify.mjs +25 -21
  414. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  415. package/dist/astro/routes/api/setup/admin.mjs +18 -18
  416. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -41
  417. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  418. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -4
  419. package/dist/astro/routes/api/setup/index.d.mts.map +1 -1
  420. package/dist/astro/routes/api/setup/index.mjs +53 -47
  421. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  422. package/dist/astro/routes/api/setup/status.mjs +6 -6
  423. package/dist/astro/routes/api/site/domain-proof.d.mts +8 -0
  424. package/dist/astro/routes/api/site/domain-proof.d.mts.map +1 -0
  425. package/dist/astro/routes/api/site/domain-proof.mjs +35 -0
  426. package/dist/astro/routes/api/site/domain-proof.mjs.map +1 -0
  427. package/dist/astro/routes/api/snapshot.mjs +8 -8
  428. package/dist/astro/routes/api/taxonomies/_name_/reorder.d.mts.map +1 -1
  429. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +24 -22
  430. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  431. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.d.mts.map +1 -1
  432. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +24 -22
  433. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  434. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.d.mts.map +1 -1
  435. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -23
  436. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  437. package/dist/astro/routes/api/taxonomies/_name_/terms/index.d.mts.map +1 -1
  438. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +24 -22
  439. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  440. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +22 -21
  441. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  442. package/dist/astro/routes/api/taxonomies/_name_.d.mts.map +1 -1
  443. package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -23
  444. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  445. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +35 -34
  446. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -1
  447. package/dist/astro/routes/api/taxonomies/index.d.mts.map +1 -1
  448. package/dist/astro/routes/api/taxonomies/index.mjs +24 -22
  449. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  450. package/dist/astro/routes/api/themes/preview.mjs +6 -6
  451. package/dist/astro/routes/api/typegen.mjs +6 -6
  452. package/dist/astro/routes/api/visual-editing/action-token.mjs +6 -6
  453. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +18 -18
  454. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +4 -4
  455. package/dist/astro/routes/api/well-known/auth.mjs +1 -1
  456. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  457. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  458. package/dist/astro/routes/api/widget-areas/_name_/reorder.d.mts.map +1 -1
  459. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +17 -16
  460. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  461. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.d.mts.map +1 -1
  462. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +21 -19
  463. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  464. package/dist/astro/routes/api/widget-areas/_name_/widgets.d.mts.map +1 -1
  465. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -18
  466. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  467. package/dist/astro/routes/api/widget-areas/_name_.d.mts.map +1 -1
  468. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
  469. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  470. package/dist/astro/routes/api/widget-areas/index.d.mts.map +1 -1
  471. package/dist/astro/routes/api/widget-areas/index.mjs +20 -18
  472. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  473. package/dist/astro/routes/api/widget-components.mjs +5 -5
  474. package/dist/astro/routes/robots.txt.d.mts.map +1 -1
  475. package/dist/astro/routes/robots.txt.mjs +38 -5
  476. package/dist/astro/routes/robots.txt.mjs.map +1 -1
  477. package/dist/astro/routes/sitemap-_collection_.xml.d.mts.map +1 -1
  478. package/dist/astro/routes/sitemap-_collection_.xml.mjs +33 -11
  479. package/dist/astro/routes/sitemap-_collection_.xml.mjs.map +1 -1
  480. package/dist/astro/routes/sitemap.xml.d.mts.map +1 -1
  481. package/dist/astro/routes/sitemap.xml.mjs +17 -11
  482. package/dist/astro/routes/sitemap.xml.mjs.map +1 -1
  483. package/dist/astro/types.d.mts +32 -18
  484. package/dist/astro/types.d.mts.map +1 -1
  485. package/dist/audit-_gieLVGU.mjs +127 -0
  486. package/dist/audit-_gieLVGU.mjs.map +1 -0
  487. package/dist/auth/providers/github.d.mts +1 -1
  488. package/dist/auth/providers/google.d.mts +1 -1
  489. package/dist/auth/providers/microsoft.d.mts +1 -1
  490. package/dist/authoritative-records-CQlB3JzE.mjs +5183 -0
  491. package/dist/authoritative-records-CQlB3JzE.mjs.map +1 -0
  492. package/dist/authorize-DPFBGbE6.mjs +74 -0
  493. package/dist/authorize-DPFBGbE6.mjs.map +1 -0
  494. package/dist/backup-3FgVxiDJ.mjs +246 -0
  495. package/dist/backup-3FgVxiDJ.mjs.map +1 -0
  496. package/dist/block-types-CYcG56JB.mjs +132 -0
  497. package/dist/block-types-CYcG56JB.mjs.map +1 -0
  498. package/dist/block-values-gCX4HBSl.mjs +215 -0
  499. package/dist/block-values-gCX4HBSl.mjs.map +1 -0
  500. package/dist/byline-BR1qhyiw.mjs +909 -0
  501. package/dist/byline-BR1qhyiw.mjs.map +1 -0
  502. package/dist/byline-fields-4ClDC88c.mjs +123 -0
  503. package/dist/byline-fields-4ClDC88c.mjs.map +1 -0
  504. package/dist/byline-fields-BLXZnX7N.mjs +280 -0
  505. package/dist/byline-fields-BLXZnX7N.mjs.map +1 -0
  506. package/dist/bylines-CVOvRUL7.mjs +234 -0
  507. package/dist/bylines-CVOvRUL7.mjs.map +1 -0
  508. package/dist/bylines-DxOs9B7z.mjs +150 -0
  509. package/dist/bylines-DxOs9B7z.mjs.map +1 -0
  510. package/dist/cache-CEU9wo_h.mjs +151 -0
  511. package/dist/cache-CEU9wo_h.mjs.map +1 -0
  512. package/dist/canonical-BudtH-Fx.mjs +174 -0
  513. package/dist/canonical-BudtH-Fx.mjs.map +1 -0
  514. package/dist/capture-triggers-CT6dK9zd.mjs +362 -0
  515. package/dist/capture-triggers-CT6dK9zd.mjs.map +1 -0
  516. package/dist/challenge-store-C17BYx2-.mjs +51 -0
  517. package/dist/challenge-store-C17BYx2-.mjs.map +1 -0
  518. package/dist/checksum-CEqvfxGX.mjs +162 -0
  519. package/dist/checksum-CEqvfxGX.mjs.map +1 -0
  520. package/dist/chunks-xC4UD5-S.mjs +25 -0
  521. package/dist/chunks-xC4UD5-S.mjs.map +1 -0
  522. package/dist/cli/index.mjs +134 -118
  523. package/dist/cli/index.mjs.map +1 -1
  524. package/dist/client/cf-access.d.mts +1 -1
  525. package/dist/client/index.d.mts +122 -122
  526. package/dist/client/index.d.mts.map +1 -1
  527. package/dist/client/index.mjs +12 -10
  528. package/dist/client/index.mjs.map +1 -1
  529. package/dist/collection-slugs-cache-e09QeJQt.mjs +85 -0
  530. package/dist/collection-slugs-cache-e09QeJQt.mjs.map +1 -0
  531. package/dist/comment-UvIWDKcW.mjs +325 -0
  532. package/dist/comment-UvIWDKcW.mjs.map +1 -0
  533. package/dist/comment-reaction-dGp6_FRo.mjs +85 -0
  534. package/dist/comment-reaction-dGp6_FRo.mjs.map +1 -0
  535. package/dist/comments-pej-_BUO.mjs +195 -0
  536. package/dist/comments-pej-_BUO.mjs.map +1 -0
  537. package/dist/comments-yiRFx3w5.mjs +99 -0
  538. package/dist/comments-yiRFx3w5.mjs.map +1 -0
  539. package/dist/components-Brp__9xo.mjs +112 -0
  540. package/dist/components-Brp__9xo.mjs.map +1 -0
  541. package/dist/config-Bsm_u_oE.d.mts +6799 -0
  542. package/dist/config-Bsm_u_oE.d.mts.map +1 -0
  543. package/dist/config-CFMojMFK.d.mts +39 -0
  544. package/dist/config-CFMojMFK.d.mts.map +1 -0
  545. package/dist/config-DBU6iUQB.mjs +228 -0
  546. package/dist/config-DBU6iUQB.mjs.map +1 -0
  547. package/dist/connection-BtEN_lP9.mjs +36 -0
  548. package/dist/connection-BtEN_lP9.mjs.map +1 -0
  549. package/dist/content-DQSRZTVw.mjs +2075 -0
  550. package/dist/content-DQSRZTVw.mjs.map +1 -0
  551. package/dist/content-list-query-CYKcY6Vi.d.mts +26 -0
  552. package/dist/content-list-query-CYKcY6Vi.d.mts.map +1 -0
  553. package/dist/content-repair-DNh5--x5.mjs +442 -0
  554. package/dist/content-repair-DNh5--x5.mjs.map +1 -0
  555. package/dist/context-BYptmCN0.mjs +2090 -0
  556. package/dist/context-BYptmCN0.mjs.map +1 -0
  557. package/dist/credits-B9iORdWB.mjs +110 -0
  558. package/dist/credits-B9iORdWB.mjs.map +1 -0
  559. package/dist/cron-D7obTIfk.mjs +306 -0
  560. package/dist/cron-D7obTIfk.mjs.map +1 -0
  561. package/dist/dashboard-D0jcgBD7.mjs +167 -0
  562. package/dist/dashboard-D0jcgBD7.mjs.map +1 -0
  563. package/dist/database/migration-lock.d.mts +17 -4
  564. package/dist/database/migration-lock.d.mts.map +1 -1
  565. package/dist/database/migration-lock.mjs +32 -5
  566. package/dist/database/migration-lock.mjs.map +1 -1
  567. package/dist/db/index.d.mts +3 -3
  568. package/dist/db/index.mjs +1 -1
  569. package/dist/db/libsql-migrations.d.mts +1 -1
  570. package/dist/db/libsql-migrations.mjs +4 -4
  571. package/dist/db/libsql.d.mts +1 -1
  572. package/dist/db/postgres-migrations.d.mts +1 -1
  573. package/dist/db/postgres-migrations.mjs +4 -4
  574. package/dist/db/postgres.d.mts +1 -1
  575. package/dist/db/sqlite-migrations.d.mts +1 -1
  576. package/dist/db/sqlite-migrations.mjs +4 -4
  577. package/dist/db/sqlite.d.mts +1 -1
  578. package/dist/db/sqlite.mjs +1 -1
  579. package/dist/default-C0W-PhAp.mjs +81 -0
  580. package/dist/default-C0W-PhAp.mjs.map +1 -0
  581. package/dist/deferred-tasks-ZvUECSzI.d.mts +9 -0
  582. package/dist/deferred-tasks-ZvUECSzI.d.mts.map +1 -0
  583. package/dist/dev-typegen-EBni_pOQ.mjs +29 -0
  584. package/dist/dev-typegen-EBni_pOQ.mjs.map +1 -0
  585. package/dist/device-flow-BkFKBoAn.mjs +521 -0
  586. package/dist/device-flow-BkFKBoAn.mjs.map +1 -0
  587. package/dist/digest-DJ1tHCgy.mjs +194 -0
  588. package/dist/digest-DJ1tHCgy.mjs.map +1 -0
  589. package/dist/direct-executor-Cbxzg4qe.mjs +117 -0
  590. package/dist/direct-executor-Cbxzg4qe.mjs.map +1 -0
  591. package/dist/email-console-FFVJWb9N.mjs +50 -0
  592. package/dist/email-console-FFVJWb9N.mjs.map +1 -0
  593. package/dist/email-locale-BJ8DjTzZ.mjs +25 -0
  594. package/dist/email-locale-BJ8DjTzZ.mjs.map +1 -0
  595. package/dist/emdash-runtime-DVi7vtXC.mjs +4379 -0
  596. package/dist/emdash-runtime-DVi7vtXC.mjs.map +1 -0
  597. package/dist/entry-lock-C7VX0NGK.d.mts +4568 -0
  598. package/dist/entry-lock-C7VX0NGK.d.mts.map +1 -0
  599. package/dist/entry-lock-DLxCffFW.mjs +163 -0
  600. package/dist/entry-lock-DLxCffFW.mjs.map +1 -0
  601. package/dist/entry-lock-Df6-XhIu.mjs +1211 -0
  602. package/dist/entry-lock-Df6-XhIu.mjs.map +1 -0
  603. package/dist/env-types-C3FCVBWe.mjs +38 -0
  604. package/dist/env-types-C3FCVBWe.mjs.map +1 -0
  605. package/dist/error-CVWeIOku.mjs +90 -0
  606. package/dist/error-CVWeIOku.mjs.map +1 -0
  607. package/dist/errors-B4f4It-2.mjs +120 -0
  608. package/dist/errors-B4f4It-2.mjs.map +1 -0
  609. package/dist/errors-BOYNdIo3.mjs +479 -0
  610. package/dist/errors-BOYNdIo3.mjs.map +1 -0
  611. package/dist/escape-lsNq38PP.mjs +9 -0
  612. package/dist/escape-lsNq38PP.mjs.map +1 -0
  613. package/dist/fence-C3MUitUN.mjs +162 -0
  614. package/dist/fence-C3MUitUN.mjs.map +1 -0
  615. package/dist/field-defs-cache-Dez5iWJJ.mjs +77 -0
  616. package/dist/field-defs-cache-Dez5iWJJ.mjs.map +1 -0
  617. package/dist/field-map-Bft9LKak.mjs +83 -0
  618. package/dist/field-map-Bft9LKak.mjs.map +1 -0
  619. package/dist/fts-manager-Beg3e4bI.mjs +443 -0
  620. package/dist/fts-manager-Beg3e4bI.mjs.map +1 -0
  621. package/dist/gc-ByyAYiYE.mjs +75 -0
  622. package/dist/gc-ByyAYiYE.mjs.map +1 -0
  623. package/dist/hash-BJaeek87.mjs +37 -0
  624. package/dist/hash-BJaeek87.mjs.map +1 -0
  625. package/dist/hook-result-BrdLyOdI.d.mts +31 -0
  626. package/dist/hook-result-BrdLyOdI.d.mts.map +1 -0
  627. package/dist/hreflang-C8Jb-hrf.mjs +105 -0
  628. package/dist/hreflang-C8Jb-hrf.mjs.map +1 -0
  629. package/dist/hreflang-CY_F5OjF.d.mts +50 -0
  630. package/dist/hreflang-CY_F5OjF.d.mts.map +1 -0
  631. package/dist/http-route-dispatch-CyeW6iPv.mjs +342 -0
  632. package/dist/http-route-dispatch-CyeW6iPv.mjs.map +1 -0
  633. package/dist/identity-Cael5uTT.mjs +35 -0
  634. package/dist/identity-Cael5uTT.mjs.map +1 -0
  635. package/dist/import-BUXjdZUn.mjs +2126 -0
  636. package/dist/import-BUXjdZUn.mjs.map +1 -0
  637. package/dist/index-BB9sVisO.d.mts +623 -0
  638. package/dist/index-BB9sVisO.d.mts.map +1 -0
  639. package/dist/index.d.mts +24 -24
  640. package/dist/index.mjs +97 -95
  641. package/dist/install-finalization-3JX5qQEA.mjs +58 -0
  642. package/dist/install-finalization-3JX5qQEA.mjs.map +1 -0
  643. package/dist/json-recordset-BUjxhr77.mjs +12 -0
  644. package/dist/json-recordset-BUjxhr77.mjs.map +1 -0
  645. package/dist/json-schema-v_D_pPNG.mjs +15 -0
  646. package/dist/json-schema-v_D_pPNG.mjs.map +1 -0
  647. package/dist/keys-CifIkT0N.mjs +61 -0
  648. package/dist/keys-CifIkT0N.mjs.map +1 -0
  649. package/dist/kinds-B_Qcl5pz.mjs +974 -0
  650. package/dist/kinds-B_Qcl5pz.mjs.map +1 -0
  651. package/dist/lifecycle-7vUJeFRe.mjs +25 -0
  652. package/dist/lifecycle-7vUJeFRe.mjs.map +1 -0
  653. package/dist/load-CdAG9wz-.mjs +28 -0
  654. package/dist/load-CdAG9wz-.mjs.map +1 -0
  655. package/dist/loader-CswroUbe.mjs +1380 -0
  656. package/dist/loader-CswroUbe.mjs.map +1 -0
  657. package/dist/loops-uA4iTOzd.mjs +205 -0
  658. package/dist/loops-uA4iTOzd.mjs.map +1 -0
  659. package/dist/manifest-builder-B8zjuH3f.mjs +189 -0
  660. package/dist/manifest-builder-B8zjuH3f.mjs.map +1 -0
  661. package/dist/manifest-schema-DNb4XmTS.mjs +497 -0
  662. package/dist/manifest-schema-DNb4XmTS.mjs.map +1 -0
  663. package/dist/marketplace-CqbgeIa7.mjs +257 -0
  664. package/dist/marketplace-CqbgeIa7.mjs.map +1 -0
  665. package/dist/media/image-endpoint.d.mts +26 -2
  666. package/dist/media/image-endpoint.d.mts.map +1 -1
  667. package/dist/media/image-endpoint.mjs +73 -3
  668. package/dist/media/image-endpoint.mjs.map +1 -1
  669. package/dist/media/index.d.mts +1 -1
  670. package/dist/media/local-runtime.d.mts +14 -14
  671. package/dist/media/local-runtime.mjs +10 -5
  672. package/dist/media/local-runtime.mjs.map +1 -1
  673. package/dist/media--dJRU6i2.mjs +294 -0
  674. package/dist/media--dJRU6i2.mjs.map +1 -0
  675. package/dist/media-1WC65OCB.mjs +416 -0
  676. package/dist/media-1WC65OCB.mjs.map +1 -0
  677. package/dist/media-Bws9f18T.mjs +373 -0
  678. package/dist/media-Bws9f18T.mjs.map +1 -0
  679. package/dist/media-allowlist-BJB7MFx6.mjs +45 -0
  680. package/dist/media-allowlist-BJB7MFx6.mjs.map +1 -0
  681. package/dist/media-folders-Dn3C16B8.mjs +210 -0
  682. package/dist/media-folders-Dn3C16B8.mjs.map +1 -0
  683. package/dist/media-url-BQgKvpQ5.mjs +43 -0
  684. package/dist/media-url-BQgKvpQ5.mjs.map +1 -0
  685. package/dist/media-usage-CF0WVcLO.mjs +282 -0
  686. package/dist/media-usage-CF0WVcLO.mjs.map +1 -0
  687. package/dist/media-usage-activation-C9HwVw5w.mjs +78 -0
  688. package/dist/media-usage-activation-C9HwVw5w.mjs.map +1 -0
  689. package/dist/media-usage-work-CkLa5-nc.mjs +1036 -0
  690. package/dist/media-usage-work-CkLa5-nc.mjs.map +1 -0
  691. package/dist/media-usage-work-m3AWTmmC.mjs +151 -0
  692. package/dist/media-usage-work-m3AWTmmC.mjs.map +1 -0
  693. package/dist/menus-BCVSSp1z.mjs +753 -0
  694. package/dist/menus-BCVSSp1z.mjs.map +1 -0
  695. package/dist/menus-BSzwObhV.mjs +92 -0
  696. package/dist/menus-BSzwObhV.mjs.map +1 -0
  697. package/dist/menus-Cl4kwdt7.mjs +3721 -0
  698. package/dist/menus-Cl4kwdt7.mjs.map +1 -0
  699. package/dist/migrations/index.d.mts +1 -1
  700. package/dist/migrations/index.d.mts.map +1 -1
  701. package/dist/migrations/index.mjs +3 -3
  702. package/dist/mode-C-D3qICy.mjs +23 -0
  703. package/dist/mode-C-D3qICy.mjs.map +1 -0
  704. package/dist/node-sqlite-compat-CrKzRr0J.mjs +63 -0
  705. package/dist/node-sqlite-compat-CrKzRr0J.mjs.map +1 -0
  706. package/dist/oauth-authorization-TpEJrYB7.mjs +274 -0
  707. package/dist/oauth-authorization-TpEJrYB7.mjs.map +1 -0
  708. package/dist/oauth-clients-BT0Pg-MO.mjs +266 -0
  709. package/dist/oauth-clients-BT0Pg-MO.mjs.map +1 -0
  710. package/dist/oauth-state-store-CHMn_mwc.mjs +50 -0
  711. package/dist/oauth-state-store-CHMn_mwc.mjs.map +1 -0
  712. package/dist/oauth-user-lookup-BDgF6IVG.mjs +26 -0
  713. package/dist/oauth-user-lookup-BDgF6IVG.mjs.map +1 -0
  714. package/dist/object-cache/memory.d.mts +1 -1
  715. package/dist/options-DJWaq3Ie.d.mts +81 -0
  716. package/dist/options-DJWaq3Ie.d.mts.map +1 -0
  717. package/dist/ownership-MiyA7qKO.mjs +12 -0
  718. package/dist/ownership-MiyA7qKO.mjs.map +1 -0
  719. package/dist/page/index.d.mts +2 -2
  720. package/dist/page/index.mjs +9 -4
  721. package/dist/page/index.mjs.map +1 -1
  722. package/dist/parse-CWHOFc6z.d.mts +176 -0
  723. package/dist/parse-CWHOFc6z.d.mts.map +1 -0
  724. package/dist/parse-DgQ2NABT.mjs +81 -0
  725. package/dist/parse-DgQ2NABT.mjs.map +1 -0
  726. package/dist/passkey-config-D0kdzEao.mjs +46 -0
  727. package/dist/passkey-config-D0kdzEao.mjs.map +1 -0
  728. package/dist/paths-biDzFTY2.mjs +77 -0
  729. package/dist/paths-biDzFTY2.mjs.map +1 -0
  730. package/dist/patterns-CMNnYCgf.mjs +159 -0
  731. package/dist/patterns-CMNnYCgf.mjs.map +1 -0
  732. package/dist/placeholder-D41vk11_.d.mts +306 -0
  733. package/dist/placeholder-D41vk11_.d.mts.map +1 -0
  734. package/dist/plan-CCoqxNoU.mjs +135 -0
  735. package/dist/plan-CCoqxNoU.mjs.map +1 -0
  736. package/dist/plugin-test-runtime.d.mts +14 -14
  737. package/dist/plugin-test-runtime.d.mts.map +1 -1
  738. package/dist/plugin-test-runtime.mjs +110 -108
  739. package/dist/plugin-tool-name-DDUgN_0p.mjs +27 -0
  740. package/dist/plugin-tool-name-DDUgN_0p.mjs.map +1 -0
  741. package/dist/plugin-types.d.mts +2 -2
  742. package/dist/plugin-utils.d.mts +12 -12
  743. package/dist/plugin-utils.mjs +1 -1
  744. package/dist/plugin-utils.mjs.map +1 -1
  745. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  746. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  747. package/dist/plugins/adapt-sandbox-entry.mjs +9 -8
  748. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
  749. package/dist/plugins/host.d.mts +5 -5
  750. package/dist/plugins/host.mjs +46 -42
  751. package/dist/plugins-COJ2L49n.mjs +261 -0
  752. package/dist/plugins-COJ2L49n.mjs.map +1 -0
  753. package/dist/policy-DLQ--Hnm.mjs +45 -0
  754. package/dist/policy-DLQ--Hnm.mjs.map +1 -0
  755. package/dist/portable-text-BH4zgkSm.mjs +311 -0
  756. package/dist/portable-text-BH4zgkSm.mjs.map +1 -0
  757. package/dist/preview-DLexxwp3.mjs +107 -0
  758. package/dist/preview-DLexxwp3.mjs.map +1 -0
  759. package/dist/protocol-79kUO7jP.d.mts +65 -0
  760. package/dist/protocol-79kUO7jP.d.mts.map +1 -0
  761. package/dist/public-plugin-api-routes-BuAMJ8nN.mjs +316 -0
  762. package/dist/public-plugin-api-routes-BuAMJ8nN.mjs.map +1 -0
  763. package/dist/public-submission-Di3TsgzX.mjs +251 -0
  764. package/dist/public-submission-Di3TsgzX.mjs.map +1 -0
  765. package/dist/public-url-Bt98vysr.mjs +101 -0
  766. package/dist/public-url-Bt98vysr.mjs.map +1 -0
  767. package/dist/query-CpnRlBh8.mjs +1156 -0
  768. package/dist/query-CpnRlBh8.mjs.map +1 -0
  769. package/dist/query-haKvLAWl.mjs +41 -0
  770. package/dist/query-haKvLAWl.mjs.map +1 -0
  771. package/dist/range-CYfeXgGK.mjs +51 -0
  772. package/dist/range-CYfeXgGK.mjs.map +1 -0
  773. package/dist/rate-limit-Xp4d0NBY.mjs +127 -0
  774. package/dist/rate-limit-Xp4d0NBY.mjs.map +1 -0
  775. package/dist/receipt-BUsQCOeM.mjs +43 -0
  776. package/dist/receipt-BUsQCOeM.mjs.map +1 -0
  777. package/dist/redirect-CQAV7mCo.mjs +19 -0
  778. package/dist/redirect-CQAV7mCo.mjs.map +1 -0
  779. package/dist/redirect-DiS_3mA4.mjs +423 -0
  780. package/dist/redirect-DiS_3mA4.mjs.map +1 -0
  781. package/dist/redirect-paths-CNYq7w80.mjs +36 -0
  782. package/dist/redirect-paths-CNYq7w80.mjs.map +1 -0
  783. package/dist/redirects-BEVSRMa2.mjs +148 -0
  784. package/dist/redirects-BEVSRMa2.mjs.map +1 -0
  785. package/dist/redirects-BHpy-VsZ.mjs +446 -0
  786. package/dist/redirects-BHpy-VsZ.mjs.map +1 -0
  787. package/dist/registry/testing.mjs +3 -3
  788. package/dist/registry-TUVaid9Z.mjs +8369 -0
  789. package/dist/registry-TUVaid9Z.mjs.map +1 -0
  790. package/dist/relations-CA_QuMTU.mjs +776 -0
  791. package/dist/relations-CA_QuMTU.mjs.map +1 -0
  792. package/dist/request-context.d.mts +1 -1
  793. package/dist/request-meta-bwZ_NsvU.mjs +141 -0
  794. package/dist/request-meta-bwZ_NsvU.mjs.map +1 -0
  795. package/dist/resolve-DwNM-CXl.mjs +101 -0
  796. package/dist/resolve-DwNM-CXl.mjs.map +1 -0
  797. package/dist/revision-BVp8S0e_.mjs +374 -0
  798. package/dist/revision-BVp8S0e_.mjs.map +1 -0
  799. package/dist/route-cache-QSOyDEw0.mjs +20 -0
  800. package/dist/route-cache-QSOyDEw0.mjs.map +1 -0
  801. package/dist/route-wire-Ca_HWCZ5.mjs +197 -0
  802. package/dist/route-wire-Ca_HWCZ5.mjs.map +1 -0
  803. package/dist/routes-BerZFrvV.mjs +272 -0
  804. package/dist/routes-BerZFrvV.mjs.map +1 -0
  805. package/dist/runner-BObHz5FC.d.mts +68 -0
  806. package/dist/runner-BObHz5FC.d.mts.map +1 -0
  807. package/dist/runner-C5NeAkBQ.mjs +6595 -0
  808. package/dist/runner-C5NeAkBQ.mjs.map +1 -0
  809. package/dist/runtime.d.mts +13 -13
  810. package/dist/runtime.mjs +3 -2
  811. package/dist/runtime.mjs.map +1 -1
  812. package/dist/schema/project-env-types.mjs +40 -36
  813. package/dist/schema/project-env-types.mjs.map +1 -1
  814. package/dist/schema-C4OBuv6Z.mjs +13 -0
  815. package/dist/schema-C4OBuv6Z.mjs.map +1 -0
  816. package/dist/schema-DJRfvM_o.mjs +815 -0
  817. package/dist/schema-DJRfvM_o.mjs.map +1 -0
  818. package/dist/scopes-BU03K7Uo.mjs +34 -0
  819. package/dist/scopes-BU03K7Uo.mjs.map +1 -0
  820. package/dist/search-DfVzks89.mjs +450 -0
  821. package/dist/search-DfVzks89.mjs.map +1 -0
  822. package/dist/sections-BMy4JVUz.mjs +346 -0
  823. package/dist/sections-BMy4JVUz.mjs.map +1 -0
  824. package/dist/seed/index.d.mts +2 -2
  825. package/dist/seed/index.mjs +38 -34
  826. package/dist/seo/index.d.mts +3 -3
  827. package/dist/seo/index.mjs +25 -21
  828. package/dist/seo/index.mjs.map +1 -1
  829. package/dist/seo-ClB-dw9w.mjs +188 -0
  830. package/dist/seo-ClB-dw9w.mjs.map +1 -0
  831. package/dist/seo-VZYOEy8f.mjs +133 -0
  832. package/dist/seo-VZYOEy8f.mjs.map +1 -0
  833. package/dist/service-Bo_usgSk.mjs +150 -0
  834. package/dist/service-Bo_usgSk.mjs.map +1 -0
  835. package/dist/session-user-DlpPdf8L.mjs +61 -0
  836. package/dist/session-user-DlpPdf8L.mjs.map +1 -0
  837. package/dist/settings-CWb84sDm.mjs +452 -0
  838. package/dist/settings-CWb84sDm.mjs.map +1 -0
  839. package/dist/settings-DS914jjE.mjs +66 -0
  840. package/dist/settings-DS914jjE.mjs.map +1 -0
  841. package/dist/settings-Dd1uivmQ.mjs +73 -0
  842. package/dist/settings-Dd1uivmQ.mjs.map +1 -0
  843. package/dist/setup-complete-BuNxAUiN.mjs +65 -0
  844. package/dist/setup-complete-BuNxAUiN.mjs.map +1 -0
  845. package/dist/setup-nonce-BnEAX0iy.mjs +25 -0
  846. package/dist/setup-nonce-BnEAX0iy.mjs.map +1 -0
  847. package/dist/site-domain-Bq5j5bVg.mjs +131 -0
  848. package/dist/site-domain-Bq5j5bVg.mjs.map +1 -0
  849. package/dist/site-settings-DRHfX7bq.mjs +50 -0
  850. package/dist/site-settings-DRHfX7bq.mjs.map +1 -0
  851. package/dist/site-url-MB685I5X.mjs +45 -0
  852. package/dist/site-url-MB685I5X.mjs.map +1 -0
  853. package/dist/sitemap-name-BTg2NJJv.mjs +26 -0
  854. package/dist/sitemap-name-BTg2NJJv.mjs.map +1 -0
  855. package/dist/slug-aVnUV4SL.mjs +16 -0
  856. package/dist/slug-aVnUV4SL.mjs.map +1 -0
  857. package/dist/slugify-bu2-jKia.mjs +22 -0
  858. package/dist/slugify-bu2-jKia.mjs.map +1 -0
  859. package/dist/snapshot-DYsG4uOq.mjs +414 -0
  860. package/dist/snapshot-DYsG4uOq.mjs.map +1 -0
  861. package/dist/ssrf-BcYjyM4M.mjs +406 -0
  862. package/dist/ssrf-BcYjyM4M.mjs.map +1 -0
  863. package/dist/stage-D8DWgPcO.mjs +662 -0
  864. package/dist/stage-D8DWgPcO.mjs.map +1 -0
  865. package/dist/staged-CD_imitH.mjs +686 -0
  866. package/dist/staged-CD_imitH.mjs.map +1 -0
  867. package/dist/state-CFbGZziM.mjs +178 -0
  868. package/dist/state-CFbGZziM.mjs.map +1 -0
  869. package/dist/status-BFNdxzKc.mjs +30 -0
  870. package/dist/status-BFNdxzKc.mjs.map +1 -0
  871. package/dist/storage/local.d.mts +2 -2
  872. package/dist/storage/local.d.mts.map +1 -1
  873. package/dist/storage/local.mjs +12 -5
  874. package/dist/storage/local.mjs.map +1 -1
  875. package/dist/storage/s3.d.mts +4 -2
  876. package/dist/storage/s3.d.mts.map +1 -1
  877. package/dist/storage/s3.mjs +56 -9
  878. package/dist/storage/s3.mjs.map +1 -1
  879. package/dist/storage-query-DRyu3bSU.d.mts +1615 -0
  880. package/dist/storage-query-DRyu3bSU.d.mts.map +1 -0
  881. package/dist/tar-DFjExb9X.mjs +449 -0
  882. package/dist/tar-DFjExb9X.mjs.map +1 -0
  883. package/dist/target-CWZs2-o6.mjs +27 -0
  884. package/dist/target-CWZs2-o6.mjs.map +1 -0
  885. package/dist/taxonomies-ChnU7Mc8.mjs +697 -0
  886. package/dist/taxonomies-ChnU7Mc8.mjs.map +1 -0
  887. package/dist/taxonomies-Dd9JJv_a.mjs +939 -0
  888. package/dist/taxonomies-Dd9JJv_a.mjs.map +1 -0
  889. package/dist/taxonomy-C_C_LBAU.mjs +550 -0
  890. package/dist/taxonomy-C_C_LBAU.mjs.map +1 -0
  891. package/dist/tokens-BnhSnGwJ.mjs +171 -0
  892. package/dist/tokens-BnhSnGwJ.mjs.map +1 -0
  893. package/dist/transfer-ClH6w6BV.mjs +8873 -0
  894. package/dist/transfer-ClH6w6BV.mjs.map +1 -0
  895. package/dist/transfer-WmWiR3xf.mjs +166 -0
  896. package/dist/transfer-WmWiR3xf.mjs.map +1 -0
  897. package/dist/transfer-download--ofRj9Cw.mjs +33 -0
  898. package/dist/transfer-download--ofRj9Cw.mjs.map +1 -0
  899. package/dist/transformations-Bx4lYY0Y.mjs +196 -0
  900. package/dist/transformations-Bx4lYY0Y.mjs.map +1 -0
  901. package/dist/transport-BjbqNiPI.mjs +136 -0
  902. package/dist/transport-BjbqNiPI.mjs.map +1 -0
  903. package/dist/transport-DxiXnbXk.d.mts +42 -0
  904. package/dist/transport-DxiXnbXk.d.mts.map +1 -0
  905. package/dist/trusted-proxy-BU3Nx9g1.mjs +51 -0
  906. package/dist/trusted-proxy-BU3Nx9g1.mjs.map +1 -0
  907. package/dist/turnstile-CJwvsOqw.mjs +58 -0
  908. package/dist/turnstile-CJwvsOqw.mjs.map +1 -0
  909. package/dist/types-BA3ey2QH.d.mts +87 -0
  910. package/dist/types-BA3ey2QH.d.mts.map +1 -0
  911. package/dist/types-Bwpzb5o6.d.mts +227 -0
  912. package/dist/types-Bwpzb5o6.d.mts.map +1 -0
  913. package/dist/types-CNB-dj6F.d.mts +289 -0
  914. package/dist/types-CNB-dj6F.d.mts.map +1 -0
  915. package/dist/types-CgfFGfO5.mjs +16 -0
  916. package/dist/types-CgfFGfO5.mjs.map +1 -0
  917. package/dist/types-D2NEXtgB.mjs +127 -0
  918. package/dist/types-D2NEXtgB.mjs.map +1 -0
  919. package/dist/types-DCFavOii.d.mts +916 -0
  920. package/dist/types-DCFavOii.d.mts.map +1 -0
  921. package/dist/types-DHO7Pd25.d.mts +366 -0
  922. package/dist/types-DHO7Pd25.d.mts.map +1 -0
  923. package/dist/types-DvqVxZXa.d.mts +125 -0
  924. package/dist/types-DvqVxZXa.d.mts.map +1 -0
  925. package/dist/types-QoPHm-2w.d.mts +1741 -0
  926. package/dist/types-QoPHm-2w.d.mts.map +1 -0
  927. package/dist/types-RLgeIpnF.d.mts +374 -0
  928. package/dist/types-RLgeIpnF.d.mts.map +1 -0
  929. package/dist/types-qHVygneX.mjs +77 -0
  930. package/dist/types-qHVygneX.mjs.map +1 -0
  931. package/dist/types-sUHaH7lC.mjs +37 -0
  932. package/dist/types-sUHaH7lC.mjs.map +1 -0
  933. package/dist/types-slSqujQL.d.mts +204 -0
  934. package/dist/types-slSqujQL.d.mts.map +1 -0
  935. package/dist/update-check-BxNg9T6N.mjs +161 -0
  936. package/dist/update-check-BxNg9T6N.mjs.map +1 -0
  937. package/dist/upload-attempts-DPFC4COv.mjs +32 -0
  938. package/dist/upload-attempts-DPFC4COv.mjs.map +1 -0
  939. package/dist/url-pattern-QATUE_rv.mjs +41 -0
  940. package/dist/url-pattern-QATUE_rv.mjs.map +1 -0
  941. package/dist/user-BlCTKVAm.mjs +171 -0
  942. package/dist/user-BlCTKVAm.mjs.map +1 -0
  943. package/dist/utils-TPt7w2cS.mjs +442 -0
  944. package/dist/utils-TPt7w2cS.mjs.map +1 -0
  945. package/dist/validate-DxYhJQA-.mjs +524 -0
  946. package/dist/validate-DxYhJQA-.mjs.map +1 -0
  947. package/dist/validate-emKxGC5F.d.mts +468 -0
  948. package/dist/validate-emKxGC5F.d.mts.map +1 -0
  949. package/dist/validation-Ckq4vsVg.mjs +220 -0
  950. package/dist/validation-Ckq4vsVg.mjs.map +1 -0
  951. package/dist/version-BZj18Q7G.mjs +9 -0
  952. package/dist/version-BZj18Q7G.mjs.map +1 -0
  953. package/dist/version-DHmGpcch.mjs +7 -0
  954. package/dist/version-DHmGpcch.mjs.map +1 -0
  955. package/dist/video-DytCnw3L.mjs +54 -0
  956. package/dist/video-DytCnw3L.mjs.map +1 -0
  957. package/dist/virtual-modules-DO954n7P.mjs +515 -0
  958. package/dist/virtual-modules-DO954n7P.mjs.map +1 -0
  959. package/dist/widgets-DA5XmvVC.mjs +121 -0
  960. package/dist/widgets-DA5XmvVC.mjs.map +1 -0
  961. package/dist/wxr-taxonomies-CrMonejI.d.mts +34 -0
  962. package/dist/wxr-taxonomies-CrMonejI.d.mts.map +1 -0
  963. package/dist/wxr-taxonomies-RgRG0d5e.mjs +453 -0
  964. package/dist/wxr-taxonomies-RgRG0d5e.mjs.map +1 -0
  965. package/dist/zod-generator-D0JKy94C.mjs +424 -0
  966. package/dist/zod-generator-D0JKy94C.mjs.map +1 -0
  967. package/package.json +15 -11
  968. package/src/api/authorize.ts +42 -0
  969. package/src/api/errors.ts +9 -0
  970. package/src/api/handlers/api-tokens.ts +12 -6
  971. package/src/api/handlers/content.ts +57 -8
  972. package/src/api/handlers/dashboard.ts +33 -10
  973. package/src/api/handlers/domain-move-notice.ts +94 -0
  974. package/src/api/handlers/index.ts +2 -0
  975. package/src/api/handlers/manifest.ts +6 -0
  976. package/src/api/handlers/media-usage.ts +2 -1
  977. package/src/api/handlers/media.ts +1 -0
  978. package/src/api/handlers/plugins.ts +1 -0
  979. package/src/api/handlers/revision.ts +6 -2
  980. package/src/api/handlers/seo.ts +155 -59
  981. package/src/api/handlers/settings.ts +31 -1
  982. package/src/api/handlers/site-domain.ts +159 -0
  983. package/src/api/openapi/document.ts +2 -2
  984. package/src/api/public-url.ts +1 -1
  985. package/src/api/schemas/content.ts +20 -0
  986. package/src/api/schemas/media-usage.ts +7 -1
  987. package/src/api/schemas/media.ts +12 -0
  988. package/src/api/schemas/settings.ts +2 -0
  989. package/src/api/site-url.ts +53 -5
  990. package/src/api/types.ts +4 -0
  991. package/src/astro/image-endpoint.ts +46 -4
  992. package/src/astro/integration/admin-locales.ts +168 -0
  993. package/src/astro/integration/dev-env.ts +84 -0
  994. package/src/astro/integration/dev-scheduler-bridge.ts +91 -0
  995. package/src/astro/integration/index.ts +97 -10
  996. package/src/astro/integration/routes.ts +28 -0
  997. package/src/astro/integration/runtime.ts +17 -1
  998. package/src/astro/integration/virtual-modules.ts +9 -16
  999. package/src/astro/integration/vite-config.ts +22 -16
  1000. package/src/astro/middleware/auth.ts +19 -4
  1001. package/src/astro/middleware/csp.ts +1 -0
  1002. package/src/astro/middleware/redirect.ts +94 -50
  1003. package/src/astro/middleware/request-context.ts +12 -6
  1004. package/src/astro/middleware.ts +71 -17
  1005. package/src/astro/prefetch.ts +7 -5
  1006. package/src/astro/public-plugin-api-routes.ts +10 -2
  1007. package/src/astro/routes/api/admin/plugins/registry/artifact.ts +1 -1
  1008. package/src/astro/routes/api/auth/handover.ts +58 -0
  1009. package/src/astro/routes/api/auth/magic-link/verify.ts +11 -3
  1010. package/src/astro/routes/api/auth/passkey/options.ts +10 -2
  1011. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +2 -1
  1012. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +1 -5
  1013. package/src/astro/routes/api/content/[collection]/[id]/lock.ts +2 -2
  1014. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -1
  1015. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +2 -1
  1016. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +2 -1
  1017. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +3 -2
  1018. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +5 -4
  1019. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +2 -1
  1020. package/src/astro/routes/api/content/[collection]/[id].ts +18 -6
  1021. package/src/astro/routes/api/content/[collection]/index.ts +1 -5
  1022. package/src/astro/routes/api/dashboard.ts +4 -1
  1023. package/src/astro/routes/api/dev/scheduled-tasks.ts +20 -0
  1024. package/src/astro/routes/api/import/wordpress/analyze.ts +1 -16
  1025. package/src/astro/routes/api/import/wordpress/execute.ts +27 -3
  1026. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +80 -42
  1027. package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +4 -1
  1028. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +49 -5
  1029. package/src/astro/routes/api/manifest.ts +10 -0
  1030. package/src/astro/routes/api/media/[id]/confirm.ts +19 -0
  1031. package/src/astro/routes/api/media/file/[...key].ts +60 -12
  1032. package/src/astro/routes/api/media/upload-url.ts +28 -4
  1033. package/src/astro/routes/api/media.ts +15 -0
  1034. package/src/astro/routes/api/menus/[name]/items/[id].ts +3 -2
  1035. package/src/astro/routes/api/menus/[name]/items.ts +2 -1
  1036. package/src/astro/routes/api/menus/[name]/reorder.ts +2 -1
  1037. package/src/astro/routes/api/menus/[name]/translations.ts +2 -1
  1038. package/src/astro/routes/api/menus/[name].ts +3 -2
  1039. package/src/astro/routes/api/menus/index.ts +2 -1
  1040. package/src/astro/routes/api/redirects/[id].ts +15 -2
  1041. package/src/astro/routes/api/redirects/index.ts +5 -1
  1042. package/src/astro/routes/api/schema/index.ts +1 -1
  1043. package/src/astro/routes/api/settings/domain-notify.ts +76 -0
  1044. package/src/astro/routes/api/settings/domain.ts +64 -0
  1045. package/src/astro/routes/api/settings.ts +2 -1
  1046. package/src/astro/routes/api/setup/admin-verify.ts +7 -1
  1047. package/src/astro/routes/api/setup/index.ts +7 -0
  1048. package/src/astro/routes/api/site/domain-proof.ts +28 -0
  1049. package/src/astro/routes/api/taxonomies/[name]/reorder.ts +2 -1
  1050. package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +2 -1
  1051. package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +3 -2
  1052. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +2 -1
  1053. package/src/astro/routes/api/taxonomies/[name].ts +3 -2
  1054. package/src/astro/routes/api/taxonomies/index.ts +2 -1
  1055. package/src/astro/routes/api/widget-areas/[name]/reorder.ts +2 -1
  1056. package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +3 -2
  1057. package/src/astro/routes/api/widget-areas/[name]/widgets.ts +2 -1
  1058. package/src/astro/routes/api/widget-areas/[name].ts +2 -1
  1059. package/src/astro/routes/api/widget-areas/index.ts +2 -1
  1060. package/src/astro/routes/robots.txt.ts +33 -2
  1061. package/src/astro/routes/sitemap-[collection].xml.ts +31 -8
  1062. package/src/astro/routes/sitemap.xml.ts +12 -10
  1063. package/src/astro/types.ts +23 -2
  1064. package/src/auth/rate-limit.ts +18 -13
  1065. package/src/auth/types.ts +11 -4
  1066. package/src/aws-sdk.d.ts +2 -1
  1067. package/src/cache/redirect-paths.ts +56 -0
  1068. package/src/cache/route-cache.ts +22 -0
  1069. package/src/cleanup.ts +26 -0
  1070. package/src/cli/commands/export-seed.ts +2 -0
  1071. package/src/cli/commands/import/wordpress.ts +3 -27
  1072. package/src/cli/commands/login.ts +35 -43
  1073. package/src/cli/commands/migrate.ts +36 -4
  1074. package/src/cli/commands/seed.ts +23 -12
  1075. package/src/cli/wxr/parser.ts +2 -2
  1076. package/src/client/index.ts +18 -3
  1077. package/src/client/portable-text.ts +21 -7
  1078. package/src/comments/public-submission.ts +15 -8
  1079. package/src/comments/query.ts +8 -2
  1080. package/src/components/CommentForm.astro +50 -10
  1081. package/src/components/Comments.astro +51 -29
  1082. package/src/components/EmDashImage.astro +6 -4
  1083. package/src/components/Gallery.astro +4 -3
  1084. package/src/components/Image.astro +4 -3
  1085. package/src/components/InlinePortableTextEditor.tsx +269 -1320
  1086. package/src/components/Video.astro +100 -0
  1087. package/src/components/index.ts +4 -1
  1088. package/src/components/inline-block-types.ts +278 -0
  1089. package/src/components/inline-bubble-menu.tsx +696 -0
  1090. package/src/components/inline-code-block.tsx +8 -0
  1091. package/src/components/inline-editor-ui.tsx +1192 -0
  1092. package/src/components/inline-image.tsx +722 -0
  1093. package/src/components/inline-media-picker.tsx +1221 -0
  1094. package/src/components/inline-slash-menu.tsx +556 -0
  1095. package/src/components/webmcp-search.ts +15 -19
  1096. package/src/components/widgets/RecentPosts.astro +57 -17
  1097. package/src/content/converters/mark-safety.ts +3 -3
  1098. package/src/content/converters/portable-text-identity.ts +1 -0
  1099. package/src/content/converters/portable-text-to-prosemirror.ts +7 -0
  1100. package/src/content/converters/prosemirror-to-portable-text.ts +16 -0
  1101. package/src/content/converters/types.ts +22 -0
  1102. package/src/content/converters/video.ts +77 -0
  1103. package/src/database/collection-cleanup.ts +30 -0
  1104. package/src/database/datetime-storage.ts +337 -60
  1105. package/src/database/migration-lock.ts +43 -7
  1106. package/src/database/migrations/runner.ts +13 -1
  1107. package/src/database/repositories/comment.ts +17 -3
  1108. package/src/database/repositories/content.ts +25 -4
  1109. package/src/database/repositories/plugin-storage.ts +137 -27
  1110. package/src/database/repositories/redirect.ts +24 -2
  1111. package/src/database/repositories/revision.ts +24 -6
  1112. package/src/database/repositories/taxonomy.ts +61 -46
  1113. package/src/database/repositories/types.ts +67 -7
  1114. package/src/emdash-runtime.ts +393 -228
  1115. package/src/import/index.ts +1 -0
  1116. package/src/import/registry.ts +17 -0
  1117. package/src/import/sources/wordpress-plugin.ts +154 -11
  1118. package/src/import/types.ts +3 -0
  1119. package/src/import/utils.ts +7 -3
  1120. package/src/index.ts +3 -0
  1121. package/src/loader.ts +170 -45
  1122. package/src/mcp/json-schema.ts +14 -0
  1123. package/src/mcp/plugin-tool-name.ts +36 -0
  1124. package/src/mcp/server.ts +74 -15
  1125. package/src/media/image-endpoint.ts +101 -1
  1126. package/src/media/responsive.ts +14 -7
  1127. package/src/media/usage/collection-deletion.ts +4 -0
  1128. package/src/media/usage/extractor.ts +19 -2
  1129. package/src/media/usage/types.ts +5 -1
  1130. package/src/migrations/direct-executor.ts +42 -12
  1131. package/src/migrations/protocol.ts +6 -2
  1132. package/src/plugin-utils.ts +1 -1
  1133. package/src/plugins/adapt-sandbox-entry.ts +16 -6
  1134. package/src/plugins/context.ts +3 -7
  1135. package/src/plugins/hooks.ts +1 -1
  1136. package/src/plugins/http-route-dispatch.ts +5 -1
  1137. package/src/plugins/manifest-schema.ts +1 -0
  1138. package/src/plugins/route-error.ts +14 -0
  1139. package/src/plugins/routes.ts +2 -2
  1140. package/src/plugins/state.ts +41 -8
  1141. package/src/plugins/types.ts +6 -0
  1142. package/src/query.ts +59 -10
  1143. package/src/redirects/cache.ts +34 -2
  1144. package/src/redirects/patterns.ts +26 -2
  1145. package/src/schema/block-values.ts +80 -17
  1146. package/src/schema/registry.ts +16 -5
  1147. package/src/schema/slug.ts +19 -0
  1148. package/src/search/query.ts +3 -1
  1149. package/src/search/text-extraction.ts +6 -1
  1150. package/src/seed/apply.ts +32 -8
  1151. package/src/seed/validate.ts +31 -0
  1152. package/src/seo/sitemap-name.ts +22 -0
  1153. package/src/settings/index.ts +20 -0
  1154. package/src/settings/types.ts +2 -0
  1155. package/src/storage/index.ts +2 -0
  1156. package/src/storage/local.ts +10 -2
  1157. package/src/storage/range.ts +54 -0
  1158. package/src/storage/s3.ts +52 -8
  1159. package/src/storage/types.ts +30 -3
  1160. package/src/ui.ts +1 -0
  1161. package/src/utils/slugify.ts +6 -1
  1162. package/src/visual-editing/toolbar.ts +126 -47
  1163. package/src/widgets/components.ts +4 -0
  1164. package/src/widgets/index.ts +74 -82
  1165. package/src/widgets/recent-posts.ts +62 -0
  1166. package/dist/action-token-AgOs1UWD.mjs +0 -26
  1167. package/dist/action-token-AgOs1UWD.mjs.map +0 -1
  1168. package/dist/activation-xomsCMJg.mjs +0 -387
  1169. package/dist/activation-xomsCMJg.mjs.map +0 -1
  1170. package/dist/adapters-DM1oyHIN.d.mts +0 -173
  1171. package/dist/adapters-DM1oyHIN.d.mts.map +0 -1
  1172. package/dist/allowed-origins-CFtudhyw.mjs +0 -116
  1173. package/dist/allowed-origins-CFtudhyw.mjs.map +0 -1
  1174. package/dist/api-CltsXhiX.mjs +0 -4980
  1175. package/dist/api-CltsXhiX.mjs.map +0 -1
  1176. package/dist/api-tokens-P3mAaQgr.mjs +0 -166
  1177. package/dist/api-tokens-P3mAaQgr.mjs.map +0 -1
  1178. package/dist/apply-Q7uvzBWW.mjs +0 -1680
  1179. package/dist/apply-Q7uvzBWW.mjs.map +0 -1
  1180. package/dist/approvals-DycwI6lZ.mjs +0 -460
  1181. package/dist/approvals-DycwI6lZ.mjs.map +0 -1
  1182. package/dist/artifact-fetch-CWxyELVI.mjs +0 -659
  1183. package/dist/artifact-fetch-CWxyELVI.mjs.map +0 -1
  1184. package/dist/artifacts-UzWbysb8.mjs +0 -307
  1185. package/dist/artifacts-UzWbysb8.mjs.map +0 -1
  1186. package/dist/audit-CCH3MA4Y.mjs +0 -127
  1187. package/dist/audit-CCH3MA4Y.mjs.map +0 -1
  1188. package/dist/authoritative-records-dSvXCfzb.mjs +0 -5172
  1189. package/dist/authoritative-records-dSvXCfzb.mjs.map +0 -1
  1190. package/dist/authorize-DeWfk--K.mjs +0 -49
  1191. package/dist/authorize-DeWfk--K.mjs.map +0 -1
  1192. package/dist/backup-CFnbdTSJ.mjs +0 -246
  1193. package/dist/backup-CFnbdTSJ.mjs.map +0 -1
  1194. package/dist/block-types-C0YFSfR7.mjs +0 -132
  1195. package/dist/block-types-C0YFSfR7.mjs.map +0 -1
  1196. package/dist/block-values-H4E0XwE8.mjs +0 -175
  1197. package/dist/block-values-H4E0XwE8.mjs.map +0 -1
  1198. package/dist/byline-BhVslYLz.mjs +0 -909
  1199. package/dist/byline-BhVslYLz.mjs.map +0 -1
  1200. package/dist/byline-fields-DHJs0Mja.mjs +0 -280
  1201. package/dist/byline-fields-DHJs0Mja.mjs.map +0 -1
  1202. package/dist/byline-fields-xdxE9kxZ.mjs +0 -123
  1203. package/dist/byline-fields-xdxE9kxZ.mjs.map +0 -1
  1204. package/dist/bylines-B_nN9liM.mjs +0 -234
  1205. package/dist/bylines-B_nN9liM.mjs.map +0 -1
  1206. package/dist/bylines-C71YACkL.mjs +0 -150
  1207. package/dist/bylines-C71YACkL.mjs.map +0 -1
  1208. package/dist/cache-aTYCL9nK.mjs +0 -133
  1209. package/dist/cache-aTYCL9nK.mjs.map +0 -1
  1210. package/dist/canonical-Y1dpjCnp.mjs +0 -174
  1211. package/dist/canonical-Y1dpjCnp.mjs.map +0 -1
  1212. package/dist/capture-triggers-C9JKoIdT.mjs +0 -362
  1213. package/dist/capture-triggers-C9JKoIdT.mjs.map +0 -1
  1214. package/dist/challenge-store-CxZxPqaw.mjs +0 -51
  1215. package/dist/challenge-store-CxZxPqaw.mjs.map +0 -1
  1216. package/dist/checksum-DtH6m5uk.mjs +0 -162
  1217. package/dist/checksum-DtH6m5uk.mjs.map +0 -1
  1218. package/dist/chunks-zlGB5IQP.mjs +0 -25
  1219. package/dist/chunks-zlGB5IQP.mjs.map +0 -1
  1220. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs +0 -85
  1221. package/dist/collection-slugs-cache-B2Gs9Jwx.mjs.map +0 -1
  1222. package/dist/comment-Bu08Wvr3.mjs +0 -313
  1223. package/dist/comment-Bu08Wvr3.mjs.map +0 -1
  1224. package/dist/comment-reaction-B8SfT-yM.mjs +0 -85
  1225. package/dist/comment-reaction-B8SfT-yM.mjs.map +0 -1
  1226. package/dist/comments-BRtp992B.mjs +0 -99
  1227. package/dist/comments-BRtp992B.mjs.map +0 -1
  1228. package/dist/comments-DVUYqdyC.mjs +0 -195
  1229. package/dist/comments-DVUYqdyC.mjs.map +0 -1
  1230. package/dist/components-CQY-Sgm-.mjs +0 -108
  1231. package/dist/components-CQY-Sgm-.mjs.map +0 -1
  1232. package/dist/config-B-uePMLj.d.mts +0 -39
  1233. package/dist/config-B-uePMLj.d.mts.map +0 -1
  1234. package/dist/config-B6BDSsz2.d.mts +0 -6712
  1235. package/dist/config-B6BDSsz2.d.mts.map +0 -1
  1236. package/dist/config-BsJHiQxC.mjs +0 -228
  1237. package/dist/config-BsJHiQxC.mjs.map +0 -1
  1238. package/dist/connection-B9pIasFd.mjs +0 -36
  1239. package/dist/connection-B9pIasFd.mjs.map +0 -1
  1240. package/dist/content-Dji9vEiW.mjs +0 -2063
  1241. package/dist/content-Dji9vEiW.mjs.map +0 -1
  1242. package/dist/content-list-query-DiNwyKtd.d.mts +0 -26
  1243. package/dist/content-list-query-DiNwyKtd.d.mts.map +0 -1
  1244. package/dist/content-repair-B7wnbzhN.mjs +0 -442
  1245. package/dist/content-repair-B7wnbzhN.mjs.map +0 -1
  1246. package/dist/context-Ctcxc8Ia.mjs +0 -2026
  1247. package/dist/context-Ctcxc8Ia.mjs.map +0 -1
  1248. package/dist/credits-Bu7dlobo.mjs +0 -110
  1249. package/dist/credits-Bu7dlobo.mjs.map +0 -1
  1250. package/dist/cron-xe5XKqA-.mjs +0 -306
  1251. package/dist/cron-xe5XKqA-.mjs.map +0 -1
  1252. package/dist/dashboard-B5hVHOtf.mjs +0 -151
  1253. package/dist/dashboard-B5hVHOtf.mjs.map +0 -1
  1254. package/dist/default-DaoYyFRS.mjs +0 -81
  1255. package/dist/default-DaoYyFRS.mjs.map +0 -1
  1256. package/dist/deferred-tasks-BYcDx2o_.d.mts +0 -9
  1257. package/dist/deferred-tasks-BYcDx2o_.d.mts.map +0 -1
  1258. package/dist/dev-typegen-Dtl8AfS6.mjs +0 -29
  1259. package/dist/dev-typegen-Dtl8AfS6.mjs.map +0 -1
  1260. package/dist/device-flow-Ma5P5d2e.mjs +0 -521
  1261. package/dist/device-flow-Ma5P5d2e.mjs.map +0 -1
  1262. package/dist/digest-xIpR3o64.mjs +0 -194
  1263. package/dist/digest-xIpR3o64.mjs.map +0 -1
  1264. package/dist/direct-executor-DMWwCey3.mjs +0 -104
  1265. package/dist/direct-executor-DMWwCey3.mjs.map +0 -1
  1266. package/dist/email-console-DmqVF5J_.mjs +0 -50
  1267. package/dist/email-console-DmqVF5J_.mjs.map +0 -1
  1268. package/dist/email-locale-Cc5YSXfJ.mjs +0 -25
  1269. package/dist/email-locale-Cc5YSXfJ.mjs.map +0 -1
  1270. package/dist/emdash-runtime-BlybX9Ui.mjs +0 -4249
  1271. package/dist/emdash-runtime-BlybX9Ui.mjs.map +0 -1
  1272. package/dist/entry-lock-De1L8qUQ.mjs +0 -163
  1273. package/dist/entry-lock-De1L8qUQ.mjs.map +0 -1
  1274. package/dist/entry-lock-esmMbgI9.d.mts +0 -4551
  1275. package/dist/entry-lock-esmMbgI9.d.mts.map +0 -1
  1276. package/dist/entry-lock-sxz2PGAT.mjs +0 -1197
  1277. package/dist/entry-lock-sxz2PGAT.mjs.map +0 -1
  1278. package/dist/env-types-BkjCtN13.mjs +0 -38
  1279. package/dist/env-types-BkjCtN13.mjs.map +0 -1
  1280. package/dist/error-B0rgPgsQ.mjs +0 -90
  1281. package/dist/error-B0rgPgsQ.mjs.map +0 -1
  1282. package/dist/errors-CuHQRiBW.mjs +0 -120
  1283. package/dist/errors-CuHQRiBW.mjs.map +0 -1
  1284. package/dist/errors-DTE6C3K_.mjs +0 -470
  1285. package/dist/errors-DTE6C3K_.mjs.map +0 -1
  1286. package/dist/escape-nJW7dR0s.mjs +0 -9
  1287. package/dist/escape-nJW7dR0s.mjs.map +0 -1
  1288. package/dist/fence-CGw57S4v.mjs +0 -162
  1289. package/dist/fence-CGw57S4v.mjs.map +0 -1
  1290. package/dist/field-defs-cache-Bw8w499w.mjs +0 -77
  1291. package/dist/field-defs-cache-Bw8w499w.mjs.map +0 -1
  1292. package/dist/field-map-hn-D-SyH.mjs +0 -83
  1293. package/dist/field-map-hn-D-SyH.mjs.map +0 -1
  1294. package/dist/fts-manager-DacCYIe4.mjs +0 -443
  1295. package/dist/fts-manager-DacCYIe4.mjs.map +0 -1
  1296. package/dist/gc-BBplHrv6.mjs +0 -75
  1297. package/dist/gc-BBplHrv6.mjs.map +0 -1
  1298. package/dist/hash-C4DFoJ7Z.mjs +0 -37
  1299. package/dist/hash-C4DFoJ7Z.mjs.map +0 -1
  1300. package/dist/hook-result-DSRRxu_-.d.mts +0 -31
  1301. package/dist/hook-result-DSRRxu_-.d.mts.map +0 -1
  1302. package/dist/hreflang-CKPunvU0.mjs +0 -105
  1303. package/dist/hreflang-CKPunvU0.mjs.map +0 -1
  1304. package/dist/hreflang-egumj6WF.d.mts +0 -50
  1305. package/dist/hreflang-egumj6WF.d.mts.map +0 -1
  1306. package/dist/http-route-dispatch-DjNFZcJ2.mjs +0 -339
  1307. package/dist/http-route-dispatch-DjNFZcJ2.mjs.map +0 -1
  1308. package/dist/identity-Dfrx2_Bc.mjs +0 -35
  1309. package/dist/identity-Dfrx2_Bc.mjs.map +0 -1
  1310. package/dist/import-ROBvhbNc.mjs +0 -2021
  1311. package/dist/import-ROBvhbNc.mjs.map +0 -1
  1312. package/dist/index-B4sIdCAT.d.mts +0 -623
  1313. package/dist/index-B4sIdCAT.d.mts.map +0 -1
  1314. package/dist/install-finalization-CPM7Gged.mjs +0 -58
  1315. package/dist/install-finalization-CPM7Gged.mjs.map +0 -1
  1316. package/dist/keys-DxqxcAD4.mjs +0 -61
  1317. package/dist/keys-DxqxcAD4.mjs.map +0 -1
  1318. package/dist/kinds-BQl5gN6e.mjs +0 -974
  1319. package/dist/kinds-BQl5gN6e.mjs.map +0 -1
  1320. package/dist/lifecycle-DGQI7itS.mjs +0 -25
  1321. package/dist/lifecycle-DGQI7itS.mjs.map +0 -1
  1322. package/dist/load-DMxRl4VK.mjs +0 -28
  1323. package/dist/load-DMxRl4VK.mjs.map +0 -1
  1324. package/dist/loader-1DMiOq5s.mjs +0 -1303
  1325. package/dist/loader-1DMiOq5s.mjs.map +0 -1
  1326. package/dist/loops-Dn1i16FP.mjs +0 -205
  1327. package/dist/loops-Dn1i16FP.mjs.map +0 -1
  1328. package/dist/manifest-builder-CTw4FmZk.mjs +0 -189
  1329. package/dist/manifest-builder-CTw4FmZk.mjs.map +0 -1
  1330. package/dist/manifest-schema-gy37bD_D.mjs +0 -496
  1331. package/dist/manifest-schema-gy37bD_D.mjs.map +0 -1
  1332. package/dist/marketplace-tHWSsCUo.mjs +0 -257
  1333. package/dist/marketplace-tHWSsCUo.mjs.map +0 -1
  1334. package/dist/media-Bw-Q65ve.mjs +0 -294
  1335. package/dist/media-Bw-Q65ve.mjs.map +0 -1
  1336. package/dist/media-BzUDu7nl.mjs +0 -373
  1337. package/dist/media-BzUDu7nl.mjs.map +0 -1
  1338. package/dist/media-aahnKHze.mjs +0 -408
  1339. package/dist/media-aahnKHze.mjs.map +0 -1
  1340. package/dist/media-allowlist-RMrjo8TU.mjs +0 -45
  1341. package/dist/media-allowlist-RMrjo8TU.mjs.map +0 -1
  1342. package/dist/media-folders-kabR1oJf.mjs +0 -210
  1343. package/dist/media-folders-kabR1oJf.mjs.map +0 -1
  1344. package/dist/media-url-DloW2xrP.mjs +0 -43
  1345. package/dist/media-url-DloW2xrP.mjs.map +0 -1
  1346. package/dist/media-usage-CHHpV7ee.mjs +0 -282
  1347. package/dist/media-usage-CHHpV7ee.mjs.map +0 -1
  1348. package/dist/media-usage-activation-BinYqC_r.mjs +0 -78
  1349. package/dist/media-usage-activation-BinYqC_r.mjs.map +0 -1
  1350. package/dist/media-usage-work-C734aq6s.mjs +0 -1015
  1351. package/dist/media-usage-work-C734aq6s.mjs.map +0 -1
  1352. package/dist/media-usage-work-lxvV0-UO.mjs +0 -151
  1353. package/dist/media-usage-work-lxvV0-UO.mjs.map +0 -1
  1354. package/dist/menus-6RHNq4ZK.mjs +0 -753
  1355. package/dist/menus-6RHNq4ZK.mjs.map +0 -1
  1356. package/dist/menus-AuCTaO9W.mjs +0 -3704
  1357. package/dist/menus-AuCTaO9W.mjs.map +0 -1
  1358. package/dist/menus-BQKqf0Up.mjs +0 -92
  1359. package/dist/menus-BQKqf0Up.mjs.map +0 -1
  1360. package/dist/mode-nh0ppSX5.mjs +0 -23
  1361. package/dist/mode-nh0ppSX5.mjs.map +0 -1
  1362. package/dist/node-sqlite-compat-CDOEcc97.mjs +0 -63
  1363. package/dist/node-sqlite-compat-CDOEcc97.mjs.map +0 -1
  1364. package/dist/oauth-authorization-BtYQ80uU.mjs +0 -274
  1365. package/dist/oauth-authorization-BtYQ80uU.mjs.map +0 -1
  1366. package/dist/oauth-clients-C1S4NQHh.mjs +0 -266
  1367. package/dist/oauth-clients-C1S4NQHh.mjs.map +0 -1
  1368. package/dist/oauth-state-store-CpGi2FZH.mjs +0 -50
  1369. package/dist/oauth-state-store-CpGi2FZH.mjs.map +0 -1
  1370. package/dist/oauth-user-lookup-BNp1aFAr.mjs +0 -26
  1371. package/dist/oauth-user-lookup-BNp1aFAr.mjs.map +0 -1
  1372. package/dist/options-B41aLm1I.d.mts +0 -81
  1373. package/dist/options-B41aLm1I.d.mts.map +0 -1
  1374. package/dist/ownership-DoeAIuTg.mjs +0 -12
  1375. package/dist/ownership-DoeAIuTg.mjs.map +0 -1
  1376. package/dist/parse-CmFDTGzp.mjs +0 -81
  1377. package/dist/parse-CmFDTGzp.mjs.map +0 -1
  1378. package/dist/parse-QVS0t5oR.d.mts +0 -172
  1379. package/dist/parse-QVS0t5oR.d.mts.map +0 -1
  1380. package/dist/passkey-config-C-MxsV22.mjs +0 -46
  1381. package/dist/passkey-config-C-MxsV22.mjs.map +0 -1
  1382. package/dist/paths-kr8hAMMI.mjs +0 -77
  1383. package/dist/paths-kr8hAMMI.mjs.map +0 -1
  1384. package/dist/patterns-DyZJ67I7.mjs +0 -140
  1385. package/dist/patterns-DyZJ67I7.mjs.map +0 -1
  1386. package/dist/placeholder-Dn7MMdWr.d.mts +0 -306
  1387. package/dist/placeholder-Dn7MMdWr.d.mts.map +0 -1
  1388. package/dist/plan-CuQOeU9g.mjs +0 -135
  1389. package/dist/plan-CuQOeU9g.mjs.map +0 -1
  1390. package/dist/plugins-CGb-G98c.mjs +0 -261
  1391. package/dist/plugins-CGb-G98c.mjs.map +0 -1
  1392. package/dist/policy-C5wrDXYV.mjs +0 -45
  1393. package/dist/policy-C5wrDXYV.mjs.map +0 -1
  1394. package/dist/portable-text-BnRuiR1-.mjs +0 -307
  1395. package/dist/portable-text-BnRuiR1-.mjs.map +0 -1
  1396. package/dist/preview-xWNSR1Li.mjs +0 -107
  1397. package/dist/preview-xWNSR1Li.mjs.map +0 -1
  1398. package/dist/protocol-ClxN-m1e.d.mts +0 -61
  1399. package/dist/protocol-ClxN-m1e.d.mts.map +0 -1
  1400. package/dist/public-submission-CkmT2SKv.mjs +0 -250
  1401. package/dist/public-submission-CkmT2SKv.mjs.map +0 -1
  1402. package/dist/public-url-B5a0QAh6.mjs +0 -101
  1403. package/dist/public-url-B5a0QAh6.mjs.map +0 -1
  1404. package/dist/query-DHqFiqqH.mjs +0 -41
  1405. package/dist/query-DHqFiqqH.mjs.map +0 -1
  1406. package/dist/query-DT85BehD.mjs +0 -1125
  1407. package/dist/query-DT85BehD.mjs.map +0 -1
  1408. package/dist/rate-limit-iMvcu3eu.mjs +0 -120
  1409. package/dist/rate-limit-iMvcu3eu.mjs.map +0 -1
  1410. package/dist/receipt-Dpp1uaX9.mjs +0 -43
  1411. package/dist/receipt-Dpp1uaX9.mjs.map +0 -1
  1412. package/dist/redirect-BRoLiWQE.mjs +0 -19
  1413. package/dist/redirect-BRoLiWQE.mjs.map +0 -1
  1414. package/dist/redirect-xZNpBoGp.mjs +0 -417
  1415. package/dist/redirect-xZNpBoGp.mjs.map +0 -1
  1416. package/dist/redirects-D4EWeXAo.mjs +0 -148
  1417. package/dist/redirects-D4EWeXAo.mjs.map +0 -1
  1418. package/dist/redirects-DCKqwiWp.mjs +0 -446
  1419. package/dist/redirects-DCKqwiWp.mjs.map +0 -1
  1420. package/dist/registry-DaXmUsD4.mjs +0 -8369
  1421. package/dist/registry-DaXmUsD4.mjs.map +0 -1
  1422. package/dist/relations-JvBP8nGP.mjs +0 -776
  1423. package/dist/relations-JvBP8nGP.mjs.map +0 -1
  1424. package/dist/request-meta-B6blULFY.mjs +0 -141
  1425. package/dist/request-meta-B6blULFY.mjs.map +0 -1
  1426. package/dist/resolve-DAhHi5tn.mjs +0 -100
  1427. package/dist/resolve-DAhHi5tn.mjs.map +0 -1
  1428. package/dist/revision-BWEH2qQB.mjs +0 -368
  1429. package/dist/revision-BWEH2qQB.mjs.map +0 -1
  1430. package/dist/route-wire-DK600v4u.mjs +0 -197
  1431. package/dist/route-wire-DK600v4u.mjs.map +0 -1
  1432. package/dist/routes-BeZyaCzv.mjs +0 -272
  1433. package/dist/routes-BeZyaCzv.mjs.map +0 -1
  1434. package/dist/runner-CskI4Hmq.mjs +0 -6372
  1435. package/dist/runner-CskI4Hmq.mjs.map +0 -1
  1436. package/dist/runner-J3Cj6DGk.d.mts +0 -68
  1437. package/dist/runner-J3Cj6DGk.d.mts.map +0 -1
  1438. package/dist/schema-CK0ihqMR.mjs +0 -815
  1439. package/dist/schema-CK0ihqMR.mjs.map +0 -1
  1440. package/dist/schema-VtaZSrC-.mjs +0 -13
  1441. package/dist/schema-VtaZSrC-.mjs.map +0 -1
  1442. package/dist/scopes-BRnGlL9t.mjs +0 -34
  1443. package/dist/scopes-BRnGlL9t.mjs.map +0 -1
  1444. package/dist/search-D6-XK1Sn.mjs +0 -448
  1445. package/dist/search-D6-XK1Sn.mjs.map +0 -1
  1446. package/dist/sections-CBDCf7qR.mjs +0 -346
  1447. package/dist/sections-CBDCf7qR.mjs.map +0 -1
  1448. package/dist/seo-BdeEPDNW.mjs +0 -133
  1449. package/dist/seo-BdeEPDNW.mjs.map +0 -1
  1450. package/dist/seo-C61bnPuV.mjs +0 -114
  1451. package/dist/seo-C61bnPuV.mjs.map +0 -1
  1452. package/dist/service-BuRKLMxa.mjs +0 -150
  1453. package/dist/service-BuRKLMxa.mjs.map +0 -1
  1454. package/dist/session-user-CqkPtrPL.mjs +0 -61
  1455. package/dist/session-user-CqkPtrPL.mjs.map +0 -1
  1456. package/dist/settings-0u0lTthS.mjs +0 -51
  1457. package/dist/settings-0u0lTthS.mjs.map +0 -1
  1458. package/dist/settings-WHr45II1.mjs +0 -61
  1459. package/dist/settings-WHr45II1.mjs.map +0 -1
  1460. package/dist/settings-m5tIYnF0.mjs +0 -443
  1461. package/dist/settings-m5tIYnF0.mjs.map +0 -1
  1462. package/dist/setup-complete-B2_dhZZz.mjs +0 -65
  1463. package/dist/setup-complete-B2_dhZZz.mjs.map +0 -1
  1464. package/dist/setup-nonce-CJV9ftSK.mjs +0 -25
  1465. package/dist/setup-nonce-CJV9ftSK.mjs.map +0 -1
  1466. package/dist/site-settings-KJOqJW6W.mjs +0 -50
  1467. package/dist/site-settings-KJOqJW6W.mjs.map +0 -1
  1468. package/dist/site-url-Ceq_AUK0.mjs +0 -16
  1469. package/dist/site-url-Ceq_AUK0.mjs.map +0 -1
  1470. package/dist/slugify-T5GHH42D.mjs +0 -17
  1471. package/dist/slugify-T5GHH42D.mjs.map +0 -1
  1472. package/dist/snapshot-Dzsn3NZa.mjs +0 -414
  1473. package/dist/snapshot-Dzsn3NZa.mjs.map +0 -1
  1474. package/dist/ssrf-DsmvZB80.mjs +0 -406
  1475. package/dist/ssrf-DsmvZB80.mjs.map +0 -1
  1476. package/dist/stage-Csnh_yEd.mjs +0 -662
  1477. package/dist/stage-Csnh_yEd.mjs.map +0 -1
  1478. package/dist/staged-Q7pnEVvI.mjs +0 -686
  1479. package/dist/staged-Q7pnEVvI.mjs.map +0 -1
  1480. package/dist/state-kGdOMQRY.mjs +0 -153
  1481. package/dist/state-kGdOMQRY.mjs.map +0 -1
  1482. package/dist/status-D39Fpy8R.mjs +0 -30
  1483. package/dist/status-D39Fpy8R.mjs.map +0 -1
  1484. package/dist/storage-query-C7iy6eUb.d.mts +0 -1615
  1485. package/dist/storage-query-C7iy6eUb.d.mts.map +0 -1
  1486. package/dist/tar-BWiraSUY.mjs +0 -449
  1487. package/dist/tar-BWiraSUY.mjs.map +0 -1
  1488. package/dist/target-DOFs5oUC.mjs +0 -27
  1489. package/dist/target-DOFs5oUC.mjs.map +0 -1
  1490. package/dist/taxonomies-BS40Wxvi.mjs +0 -939
  1491. package/dist/taxonomies-BS40Wxvi.mjs.map +0 -1
  1492. package/dist/taxonomies-DAZU9VDd.mjs +0 -697
  1493. package/dist/taxonomies-DAZU9VDd.mjs.map +0 -1
  1494. package/dist/taxonomy-XzLE95Vx.mjs +0 -525
  1495. package/dist/taxonomy-XzLE95Vx.mjs.map +0 -1
  1496. package/dist/tokens-DSQan4p7.mjs +0 -171
  1497. package/dist/tokens-DSQan4p7.mjs.map +0 -1
  1498. package/dist/transfer-BcCVxDgf.mjs +0 -166
  1499. package/dist/transfer-BcCVxDgf.mjs.map +0 -1
  1500. package/dist/transfer-OMrancOt.mjs +0 -8873
  1501. package/dist/transfer-OMrancOt.mjs.map +0 -1
  1502. package/dist/transfer-download-Dc-ltjZY.mjs +0 -33
  1503. package/dist/transfer-download-Dc-ltjZY.mjs.map +0 -1
  1504. package/dist/transformations-Ddx7UtrY.mjs +0 -196
  1505. package/dist/transformations-Ddx7UtrY.mjs.map +0 -1
  1506. package/dist/transport-flR-Zmds.d.mts +0 -42
  1507. package/dist/transport-flR-Zmds.d.mts.map +0 -1
  1508. package/dist/transport-umzEbgYO.mjs +0 -136
  1509. package/dist/transport-umzEbgYO.mjs.map +0 -1
  1510. package/dist/trusted-proxy-BqfQFs6a.mjs +0 -51
  1511. package/dist/trusted-proxy-BqfQFs6a.mjs.map +0 -1
  1512. package/dist/turnstile-Do60baId.mjs +0 -58
  1513. package/dist/turnstile-Do60baId.mjs.map +0 -1
  1514. package/dist/types-BT1p3uyb.d.mts +0 -1735
  1515. package/dist/types-BT1p3uyb.d.mts.map +0 -1
  1516. package/dist/types-BYaPWs_F.d.mts +0 -198
  1517. package/dist/types-BYaPWs_F.d.mts.map +0 -1
  1518. package/dist/types-C-Xp0CcN.mjs +0 -103
  1519. package/dist/types-C-Xp0CcN.mjs.map +0 -1
  1520. package/dist/types-CLTQ9b_r.d.mts +0 -374
  1521. package/dist/types-CLTQ9b_r.d.mts.map +0 -1
  1522. package/dist/types-CPkQw2T2.d.mts +0 -85
  1523. package/dist/types-CPkQw2T2.d.mts.map +0 -1
  1524. package/dist/types-CQLvuXoZ.d.mts +0 -198
  1525. package/dist/types-CQLvuXoZ.d.mts.map +0 -1
  1526. package/dist/types-CV5xszpF.d.mts +0 -363
  1527. package/dist/types-CV5xszpF.d.mts.map +0 -1
  1528. package/dist/types-CdEMurNh.mjs +0 -77
  1529. package/dist/types-CdEMurNh.mjs.map +0 -1
  1530. package/dist/types-CxwtnuSS.mjs +0 -37
  1531. package/dist/types-CxwtnuSS.mjs.map +0 -1
  1532. package/dist/types-DGw8KMX_.mjs +0 -16
  1533. package/dist/types-DGw8KMX_.mjs.map +0 -1
  1534. package/dist/types-DOfVMPoo.d.mts +0 -125
  1535. package/dist/types-DOfVMPoo.d.mts.map +0 -1
  1536. package/dist/types-LtS0SM4F.d.mts +0 -287
  1537. package/dist/types-LtS0SM4F.d.mts.map +0 -1
  1538. package/dist/types-ifgOkcBa.d.mts +0 -916
  1539. package/dist/types-ifgOkcBa.d.mts.map +0 -1
  1540. package/dist/update-check-DOc2aBIU.mjs +0 -161
  1541. package/dist/update-check-DOc2aBIU.mjs.map +0 -1
  1542. package/dist/upload-attempts-nzdc3cay.mjs +0 -32
  1543. package/dist/upload-attempts-nzdc3cay.mjs.map +0 -1
  1544. package/dist/url-pattern-hVbqpXs6.mjs +0 -41
  1545. package/dist/url-pattern-hVbqpXs6.mjs.map +0 -1
  1546. package/dist/user-Dnp53zTq.mjs +0 -171
  1547. package/dist/user-Dnp53zTq.mjs.map +0 -1
  1548. package/dist/utils-CoV-PYhg.mjs +0 -439
  1549. package/dist/utils-CoV-PYhg.mjs.map +0 -1
  1550. package/dist/validate-CfQ9_YlD.d.mts +0 -468
  1551. package/dist/validate-CfQ9_YlD.d.mts.map +0 -1
  1552. package/dist/validate-DBX3DKtL.mjs +0 -516
  1553. package/dist/validate-DBX3DKtL.mjs.map +0 -1
  1554. package/dist/validation-BJMiDhB1.mjs +0 -219
  1555. package/dist/validation-BJMiDhB1.mjs.map +0 -1
  1556. package/dist/version-BaT8yKIT.mjs +0 -7
  1557. package/dist/version-BaT8yKIT.mjs.map +0 -1
  1558. package/dist/version-BwEGkqkx.mjs +0 -9
  1559. package/dist/version-BwEGkqkx.mjs.map +0 -1
  1560. package/dist/virtual-modules-B6vJW15k.mjs +0 -516
  1561. package/dist/virtual-modules-B6vJW15k.mjs.map +0 -1
  1562. package/dist/widgets-BkxBAgZ_.mjs +0 -126
  1563. package/dist/widgets-BkxBAgZ_.mjs.map +0 -1
  1564. package/dist/wxr-taxonomies-D7gAJyOF.mjs +0 -453
  1565. package/dist/wxr-taxonomies-D7gAJyOF.mjs.map +0 -1
  1566. package/dist/wxr-taxonomies-DM5J9AsT.d.mts +0 -34
  1567. package/dist/wxr-taxonomies-DM5J9AsT.d.mts.map +0 -1
  1568. package/dist/zod-generator-BQilAboC.mjs +0 -424
  1569. package/dist/zod-generator-BQilAboC.mjs.map +0 -1
  1570. /package/dist/{api-tokens-BLz2MtQs.mjs → api-tokens-CdP49zVF.mjs} +0 -0
  1571. /package/dist/{ssrf-tA45vIPX.mjs → ssrf-DM0E-D_8.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-BUXjdZUn.mjs","names":["normalizeUrl"],"sources":["../src/cli/wxr/parser.ts","../src/import/menus.ts","../src/import/sections.ts","../src/import/comments.ts","../src/import/settings.ts","../src/import/registry.ts","../src/import/sources/wxr.ts","../src/import/sources/wordpress-rest.ts","../src/import/sources/wordpress-plugin.ts","../src/import/index.ts"],"sourcesContent":["/**\n * WordPress WXR (WordPress eXtended RSS) parser\n *\n * Uses SAX streaming parser to handle large export files efficiently.\n * WXR is an RSS extension containing WordPress content exports.\n *\n * @see https://developer.wordpress.org/plugins/data-storage/wp-xml-rpc/\n */\n\nimport type { Readable } from \"node:stream\";\n\nimport sax from \"sax\";\n\n// Regex patterns for WXR parsing\nconst PHP_SERIALIZED_STRING_PATTERN = /s:\\d+:\"([^\"]+)\"/g;\nconst PHP_SERIALIZED_STRING_MATCH_PATTERN = /s:\\d+:\"([^\"]+)\"/;\n\n/**\n * Parsed WordPress export data\n */\nexport interface WxrData {\n\t/** Site metadata */\n\tsite: WxrSite;\n\t/** Posts (including custom post types) */\n\tposts: WxrPost[];\n\t/** Media attachments */\n\tattachments: WxrAttachment[];\n\t/** Categories */\n\tcategories: WxrCategory[];\n\t/** Tags */\n\ttags: WxrTag[];\n\t/** Authors */\n\tauthors: WxrAuthor[];\n\t/** All taxonomy terms (including custom taxonomies and nav_menu) */\n\tterms: WxrTerm[];\n\t/** Parsed navigation menus */\n\tnavMenus: WxrNavMenu[];\n}\n\nexport interface WxrSite {\n\ttitle?: string;\n\tlink?: string;\n\tdescription?: string;\n\tlanguage?: string;\n\tbaseSiteUrl?: string;\n\tbaseBlogUrl?: string;\n}\n\nexport interface WxrPost {\n\tid?: number;\n\ttitle?: string;\n\tlink?: string;\n\tpubDate?: string;\n\tcreator?: string;\n\tguid?: string;\n\tdescription?: string;\n\tcontent?: string;\n\texcerpt?: string;\n\tpostDate?: string;\n\tpostDateGmt?: string;\n\tpostModified?: string;\n\tpostModifiedGmt?: string;\n\tcommentStatus?: string;\n\tpingStatus?: string;\n\tstatus?: string;\n\tpostType?: string;\n\tpostName?: string;\n\tpostPassword?: string;\n\tisSticky?: boolean;\n\t/** Parent post ID for hierarchical content (pages) */\n\tpostParent?: number;\n\t/** Menu order for sorting */\n\tmenuOrder?: number;\n\tcategories: string[];\n\ttags: string[];\n\t/** Custom taxonomy assignments beyond categories/tags */\n\tcustomTaxonomies?: Map<string, string[]>;\n\t/**\n\t * Display labels for per-item category/tag/custom-taxonomy assignments,\n\t * captured from `<category domain=\"...\" nicename=\"...\">Label</category>`\n\t * text content. Used by the importer to back-fill term labels when a\n\t * `<wp:category>` or `<wp:tag>` block wasn't present at the top of the\n\t * WXR (older / hand-edited exports). Keyed by\n\t * `${normalisedTaxonomy}\\u0000${slug}` so categories and tags don't\n\t * collide.\n\t */\n\ttaxonomyLabels?: Map<string, string>;\n\tmeta: Map<string, string>;\n\t/**\n\t * BCP 47 locale code extracted from a detected multilingual plugin\n\t * (WPML's `_icl_lang_code` or Polylang's per-post language taxonomy).\n\t * Absent when no per-post locale could be determined.\n\t */\n\tlocale?: string;\n\t/**\n\t * Source-side translation group ID extracted from a detected multilingual\n\t * plugin (WPML's `trid` / `_icl_translation_id`, or a synthesized id derived\n\t * from Polylang's `_translations` meta). Posts sharing a `translationGroup`\n\t * are translations of one another. The string is opaque -- consumers use it\n\t * only as a key to link posts.\n\t */\n\ttranslationGroup?: string;\n}\n\n/**\n * WPML stores per-post language in postmeta as `_icl_lang_code`. The shared\n * translation id is `trid` (this is the group ID -- every translation of the\n * same content shares it). `_icl_translation_id` exists on some exports too\n * but is a per-translation row id from `wp_icl_translations`, NOT the group\n * id, so it must NOT be used as the group key. We accept it only when `trid`\n * is absent and trust the export to be internally consistent (the only case\n * where that's reasonable is single-post exports with no real grouping).\n *\n * See `wpml_element_trid` in the WPML hook docs: \"the ID of the translation\n * group\".\n */\nconst WPML_LOCALE_META_KEYS = [\"_icl_lang_code\"] as const;\nconst WPML_TRID_META_KEYS = [\"trid\", \"_icl_translation_id\"] as const;\n\n/**\n * Polylang stores per-post language in postmeta as `_locale` on newer\n * exports. The actual language taxonomy assignment lives on\n * `customTaxonomies.language`, which we use as a fallback. Translation\n * grouping is encoded in `_translations` as a serialized PHP map of\n * `{ lang_code => post_id }`; we synthesize a stable group key from the\n * sorted IDs so every member of the group resolves to the same string.\n */\nconst POLYLANG_LOCALE_META_KEY = \"_locale\";\nconst POLYLANG_TRANSLATIONS_META_KEY = \"_translations\";\nconst POLYLANG_LANG_TAXONOMY = \"language\";\n\n/**\n * Extract a list of post-IDs from Polylang's `_translations` PHP-serialized\n * value. The format we care about is roughly:\n *\n * a:2:{s:2:\"en\";i:1;s:2:\"ar\";i:7;}\n *\n * We don't need to round-trip the PHP value -- we just need a stable group\n * key shared by every translation of the same content. Concatenating the\n * sorted IDs gives us exactly that: every post in the group derives the\n * same key from its own copy of `_translations`.\n *\n * Naïve `/i:(\\d+);/g` would also match `i:N;` literals embedded INSIDE\n * string values (e.g. `s:11:\"i:42;hello\";`), which would silently corrupt\n * the group key. We walk the serialized blob token-by-token instead.\n *\n * PHP serializes `s:LEN:\"...\"` with LEN counted in BYTES, not characters\n * (UTF-8 byte length). JS string positions are UTF-16 code units, so we\n * encode to bytes via `TextEncoder` and walk byte offsets. Single-byte-only\n * inputs (the common case for Polylang's `_translations` which only stores\n * ASCII locale codes) take the same path; the encoder is cheap.\n */\nfunction polylangTranslationGroupFromMeta(serialized: string): string | undefined {\n\t// Operate on the UTF-8 byte view so `s:LEN:` advances the right number\n\t// of bytes when the payload contains multibyte characters.\n\tconst encoder = new TextEncoder();\n\tconst bytes = encoder.encode(serialized);\n\tconst decoder = new TextDecoder(\"utf-8\");\n\n\tconst ids: number[] = [];\n\tlet i = 0;\n\tconst n = bytes.length;\n\tconst CHAR_S = 0x73; // 's'\n\tconst CHAR_I = 0x69; // 'i'\n\tconst CHAR_COLON = 0x3a; // ':'\n\tconst CHAR_SEMI = 0x3b; // ';'\n\tconst CHAR_QUOTE = 0x22; // '\"'\n\n\tconst indexOf = (byte: number, from: number): number => {\n\t\tfor (let k = from; k < n; k++) {\n\t\t\tif (bytes[k] === byte) return k;\n\t\t}\n\t\treturn -1;\n\t};\n\n\twhile (i < n) {\n\t\tconst ch = bytes[i];\n\t\tif (ch === CHAR_S && bytes[i + 1] === CHAR_COLON) {\n\t\t\t// s:LEN:\"...\"; — skip the entire string value: the LEN digits,\n\t\t\t// the opening quote, the payload of exactly LEN bytes, the\n\t\t\t// closing quote, and the trailing semicolon.\n\t\t\tconst lenStart = i + 2;\n\t\t\tconst lenEnd = indexOf(CHAR_COLON, lenStart);\n\t\t\tif (lenEnd === -1) break;\n\t\t\tconst lenText = decoder.decode(bytes.slice(lenStart, lenEnd));\n\t\t\tconst len = Number.parseInt(lenText, 10);\n\t\t\tif (!Number.isFinite(len) || len < 0) {\n\t\t\t\ti = lenEnd + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// lenEnd+1 should be `\"`. Defensively check before advancing\n\t\t\t// over the payload -- a malformed input shouldn't crash the\n\t\t\t// import; just skip past this token.\n\t\t\tif (bytes[lenEnd + 1] !== CHAR_QUOTE) {\n\t\t\t\ti = lenEnd + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst payloadStart = lenEnd + 2;\n\t\t\tconst afterPayload = payloadStart + len;\n\t\t\t// afterPayload should point at the closing `\"`; +2 past `\";`.\n\t\t\ti = afterPayload + 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === CHAR_I && bytes[i + 1] === CHAR_COLON) {\n\t\t\tconst valStart = i + 2;\n\t\t\tconst valEnd = indexOf(CHAR_SEMI, valStart);\n\t\t\tif (valEnd === -1) break;\n\t\t\tconst idText = decoder.decode(bytes.slice(valStart, valEnd));\n\t\t\tconst id = Number.parseInt(idText, 10);\n\t\t\tif (Number.isFinite(id)) ids.push(id);\n\t\t\ti = valEnd + 1;\n\t\t\tcontinue;\n\t\t}\n\t\t// Any other token (a:LEN:{...}, b:0;, N;, {, }, :, ;, etc.) -- just\n\t\t// advance one byte. We only care about integer literals; everything\n\t\t// else is structural.\n\t\ti++;\n\t}\n\tif (ids.length === 0) return undefined;\n\tconst sorted = [...new Set(ids)].toSorted((a, b) => a - b);\n\treturn `pll:${sorted.join(\",\")}`;\n}\n\n/**\n * Promote multilingual-plugin metadata from `post.meta` and\n * `post.customTaxonomies` into `post.locale` / `post.translationGroup`.\n *\n * Called once per `<item>` after all of its `<wp:postmeta>` and per-item\n * `<category>` entries have been parsed. Safe to call on posts that have no\n * multilingual metadata -- it's a no-op in that case.\n *\n * WPML wins over Polylang when both are present (they shouldn't co-exist on\n * the same site, but defensive precedence avoids ambiguity).\n */\nfunction promoteI18nMetadata(post: WxrPost): void {\n\t// WPML\n\tfor (const key of WPML_LOCALE_META_KEYS) {\n\t\tconst value = post.meta.get(key);\n\t\tif (value) {\n\t\t\tpost.locale = value;\n\t\t\tbreak;\n\t\t}\n\t}\n\tfor (const key of WPML_TRID_META_KEYS) {\n\t\tconst value = post.meta.get(key);\n\t\tif (value) {\n\t\t\tpost.translationGroup = `wpml:${value}`;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Polylang fallbacks (only fill what WPML didn't already provide)\n\tif (!post.locale) {\n\t\tconst pllLocale = post.meta.get(POLYLANG_LOCALE_META_KEY);\n\t\tif (pllLocale) {\n\t\t\tpost.locale = pllLocale;\n\t\t} else {\n\t\t\t// Polylang's primary language signal is a taxonomy assignment\n\t\t\t// on the `language` custom taxonomy. The nicename is the locale\n\t\t\t// code (e.g. \"en\", \"ar\").\n\t\t\tconst langTaxonomy = post.customTaxonomies?.get(POLYLANG_LANG_TAXONOMY);\n\t\t\tconst firstLang = langTaxonomy?.[0];\n\t\t\tif (firstLang) post.locale = firstLang;\n\t\t}\n\t}\n\n\tif (!post.translationGroup) {\n\t\tconst pllTranslations = post.meta.get(POLYLANG_TRANSLATIONS_META_KEY);\n\t\tif (pllTranslations) {\n\t\t\tconst group = polylangTranslationGroupFromMeta(pllTranslations);\n\t\t\tif (group) post.translationGroup = group;\n\t\t}\n\t}\n}\n\nexport interface WxrAttachment {\n\tid?: number;\n\ttitle?: string;\n\turl?: string;\n\tpostDate?: string;\n\tmeta: Map<string, string>;\n}\n\nexport interface WxrCategory {\n\tid?: number;\n\tnicename?: string;\n\tname?: string;\n\tparent?: string;\n\tdescription?: string;\n}\n\nexport interface WxrTag {\n\tid?: number;\n\tslug?: string;\n\tname?: string;\n\tdescription?: string;\n}\n\n/**\n * Generic taxonomy term (categories, tags, nav_menu, custom taxonomies)\n */\nexport interface WxrTerm {\n\tid: number;\n\ttaxonomy: string; // 'category', 'post_tag', 'nav_menu', 'genre', etc.\n\tslug: string;\n\tname: string;\n\tparent?: string;\n\tdescription?: string;\n}\n\n/**\n * Navigation menu structure\n */\nexport interface WxrNavMenu {\n\tid: number;\n\tname: string; // Menu slug\n\tlabel: string; // Menu name\n\titems: WxrNavMenuItem[];\n}\n\n/**\n * Navigation menu item\n */\nexport interface WxrNavMenuItem {\n\tid: number;\n\tmenuId: number;\n\tparentId?: number;\n\tsortOrder: number;\n\ttype: \"custom\" | \"post_type\" | \"taxonomy\";\n\tobjectType?: string; // 'page', 'post', 'category'\n\tobjectId?: number;\n\turl?: string;\n\ttitle: string;\n\ttarget?: string;\n\tclasses?: string;\n}\n\nexport interface WxrAuthor {\n\tid?: number;\n\tlogin?: string;\n\temail?: string;\n\tdisplayName?: string;\n\tfirstName?: string;\n\tlastName?: string;\n}\n\n/** Extract string value from a SAX attribute (handles both Tag and QualifiedTag) */\nfunction attrStr(attr: string | { value: string } | undefined): string {\n\tif (typeof attr === \"string\") return attr;\n\tif (attr && typeof attr === \"object\" && \"value\" in attr) return attr.value;\n\treturn \"\";\n}\n\n/**\n * Normalise a `<category domain=\"...\">` value to the matching EmDash\n * taxonomy name so per-item label captures can be retrieved later using\n * the same key.\n */\nfunction normaliseDomain(domain: string): string {\n\tif (domain === \"post_tag\") return \"tag\";\n\treturn domain;\n}\n\n/**\n * Persist the human label of a `<category>` text body keyed by the\n * normalised `(taxonomy, slug)` pair. Skips trivial labels that equal the\n * slug (no information vs. just storing the slug).\n */\nfunction captureItemCategoryLabel(\n\titem: WxrPost,\n\tpair: { domain: string; nicename: string },\n\tlabel: string,\n): void {\n\tif (!label || label === pair.nicename) return;\n\tif (!item.taxonomyLabels) item.taxonomyLabels = new Map();\n\tconst key = `${normaliseDomain(pair.domain)}\\u0000${pair.nicename}`;\n\tif (!item.taxonomyLabels.has(key)) item.taxonomyLabels.set(key, label);\n}\n\n/** Type guard for complete WxrTerm (all required fields present) */\nfunction isCompleteWxrTerm(term: Partial<WxrTerm>): term is WxrTerm {\n\treturn (\n\t\tterm.id !== undefined &&\n\t\tterm.taxonomy !== undefined &&\n\t\tterm.slug !== undefined &&\n\t\tterm.name !== undefined\n\t);\n}\n\n/**\n * Parse a WordPress WXR export file\n */\nexport function parseWxr(stream: Readable): Promise<WxrData> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst parser = sax.createStream(true, { trim: true });\n\n\t\tconst data: WxrData = {\n\t\t\tsite: {},\n\t\t\tposts: [],\n\t\t\tattachments: [],\n\t\t\tcategories: [],\n\t\t\ttags: [],\n\t\t\tauthors: [],\n\t\t\tterms: [],\n\t\t\tnavMenus: [],\n\t\t};\n\n\t\t// Parser state\n\t\tlet currentPath: string[] = [];\n\t\tlet currentText = \"\";\n\t\tlet currentItem: WxrPost | null = null;\n\t\tlet currentAttachment: WxrAttachment | null = null;\n\t\tlet currentCategory: WxrCategory | null = null;\n\t\tlet currentTag: WxrTag | null = null;\n\t\tlet currentAuthor: WxrAuthor | null = null;\n\t\tlet currentTerm: Partial<WxrTerm> | null = null;\n\t\tlet currentMetaKey = \"\";\n\t\t// Per-item category element currently open. Captured at opentag so\n\t\t// we can pair the text body (the human label) with the slug when\n\t\t// closetag fires. WXR per-item category elements look like:\n\t\t// <category domain=\"category\" nicename=\"hello-world\">Hello World</category>\n\t\tlet pendingItemCategory: { domain: string; nicename: string } | null = null;\n\n\t\t// Track nav_menu_item posts for post-processing\n\t\tconst navMenuItemPosts: WxrPost[] = [];\n\t\t// Track menu term IDs by slug for linking items to menus\n\t\tconst menuTermsBySlug = new Map<string, number>();\n\n\t\tparser.on(\"opentag\", (node) => {\n\t\t\tconst tagName = node.name.toLowerCase();\n\t\t\tcurrentPath.push(tagName);\n\t\t\tcurrentText = \"\";\n\n\t\t\t// Start new item\n\t\t\tif (tagName === \"item\") {\n\t\t\t\tcurrentItem = {\n\t\t\t\t\tcategories: [],\n\t\t\t\t\ttags: [],\n\t\t\t\t\tcustomTaxonomies: new Map(),\n\t\t\t\t\tmeta: new Map(),\n\t\t\t\t};\n\t\t\t} else if (tagName === \"wp:category\") {\n\t\t\t\tcurrentCategory = {};\n\t\t\t} else if (tagName === \"wp:tag\") {\n\t\t\t\tcurrentTag = {};\n\t\t\t} else if (tagName === \"wp:author\") {\n\t\t\t\tcurrentAuthor = {};\n\t\t\t} else if (tagName === \"wp:term\") {\n\t\t\t\tcurrentTerm = {};\n\t\t\t}\n\n\t\t\t// Handle category/tag/custom taxonomy assignment in items\n\t\t\tif (tagName === \"category\" && currentItem && node.attributes) {\n\t\t\t\tconst domain = attrStr(node.attributes.domain);\n\t\t\t\tconst nicename = attrStr(node.attributes.nicename);\n\t\t\t\tif (domain === \"category\" && nicename) {\n\t\t\t\t\tcurrentItem.categories.push(nicename);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t} else if (domain === \"post_tag\" && nicename) {\n\t\t\t\t\tcurrentItem.tags.push(nicename);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t} else if (domain && nicename && domain !== \"category\" && domain !== \"post_tag\") {\n\t\t\t\t\t// Custom taxonomy (including nav_menu)\n\t\t\t\t\tif (!currentItem.customTaxonomies) {\n\t\t\t\t\t\tcurrentItem.customTaxonomies = new Map();\n\t\t\t\t\t}\n\t\t\t\t\tconst existing = currentItem.customTaxonomies.get(domain) || [];\n\t\t\t\t\texisting.push(nicename);\n\t\t\t\t\tcurrentItem.customTaxonomies.set(domain, existing);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tparser.on(\"text\", (text) => {\n\t\t\tcurrentText += text;\n\t\t});\n\n\t\tparser.on(\"cdata\", (cdata) => {\n\t\t\tcurrentText += cdata;\n\t\t});\n\n\t\tparser.on(\"closetag\", (tagName) => {\n\t\t\tconst tag = tagName.toLowerCase();\n\t\t\tconst text = currentText.trim();\n\n\t\t\t// Site-level metadata (in channel)\n\t\t\tif (currentPath.includes(\"channel\") && !currentItem) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tif (!data.site.title) data.site.title = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"link\":\n\t\t\t\t\t\tif (!data.site.link) data.site.link = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tif (!data.site.description) data.site.description = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"language\":\n\t\t\t\t\t\tdata.site.language = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:base_site_url\":\n\t\t\t\t\t\tdata.site.baseSiteUrl = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:base_blog_url\":\n\t\t\t\t\t\tdata.site.baseBlogUrl = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Item (post/page/attachment) parsing\n\t\t\tif (currentItem) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tcurrentItem.title = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"link\":\n\t\t\t\t\t\tcurrentItem.link = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"pubdate\":\n\t\t\t\t\t\tcurrentItem.pubDate = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"dc:creator\":\n\t\t\t\t\t\tcurrentItem.creator = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"guid\":\n\t\t\t\t\t\tcurrentItem.guid = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tcurrentItem.description = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"content:encoded\":\n\t\t\t\t\t\tcurrentItem.content = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"excerpt:encoded\":\n\t\t\t\t\t\tcurrentItem.excerpt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_id\":\n\t\t\t\t\t\tcurrentItem.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_date\":\n\t\t\t\t\t\tcurrentItem.postDate = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_date_gmt\":\n\t\t\t\t\t\tcurrentItem.postDateGmt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_modified\":\n\t\t\t\t\t\tcurrentItem.postModified = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_modified_gmt\":\n\t\t\t\t\t\tcurrentItem.postModifiedGmt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:comment_status\":\n\t\t\t\t\t\tcurrentItem.commentStatus = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:ping_status\":\n\t\t\t\t\t\tcurrentItem.pingStatus = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:status\":\n\t\t\t\t\t\tcurrentItem.status = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_type\":\n\t\t\t\t\t\tcurrentItem.postType = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_name\":\n\t\t\t\t\t\tcurrentItem.postName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_parent\":\n\t\t\t\t\t\tcurrentItem.postParent = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:menu_order\":\n\t\t\t\t\t\tcurrentItem.menuOrder = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_password\":\n\t\t\t\t\t\tcurrentItem.postPassword = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:is_sticky\":\n\t\t\t\t\t\tcurrentItem.isSticky = text === \"1\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:meta_key\":\n\t\t\t\t\t\tcurrentMetaKey = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:meta_value\":\n\t\t\t\t\t\tif (currentMetaKey) {\n\t\t\t\t\t\t\tcurrentItem.meta.set(currentMetaKey, text);\n\t\t\t\t\t\t\tcurrentMetaKey = \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:attachment_url\":\n\t\t\t\t\t\tif (currentItem.postType === \"attachment\") {\n\t\t\t\t\t\t\t// This is actually an attachment\n\t\t\t\t\t\t\tcurrentAttachment = {\n\t\t\t\t\t\t\t\tid: currentItem.id,\n\t\t\t\t\t\t\t\ttitle: currentItem.title,\n\t\t\t\t\t\t\t\turl: text,\n\t\t\t\t\t\t\t\tpostDate: currentItem.postDate,\n\t\t\t\t\t\t\t\tmeta: currentItem.meta,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"category\":\n\t\t\t\t\t\t// Per-item category text body = the human label for\n\t\t\t\t\t\t// the term (`<category nicename=\"hello-world\">Hello\n\t\t\t\t\t\t// World</category>`). Backfilling from per-item\n\t\t\t\t\t\t// elements (older / hand-edited exports without top-\n\t\t\t\t\t\t// level `<wp:category>` blocks) lands the right label\n\t\t\t\t\t\t// instead of slug-cased nonsense.\n\t\t\t\t\t\tif (pendingItemCategory && text) {\n\t\t\t\t\t\t\tcaptureItemCategoryLabel(currentItem, pendingItemCategory, text);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpendingItemCategory = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"item\":\n\t\t\t\t\t\t// End of item - categorize and store\n\t\t\t\t\t\tif (currentAttachment) {\n\t\t\t\t\t\t\tdata.attachments.push(currentAttachment);\n\t\t\t\t\t\t\tcurrentAttachment = null;\n\t\t\t\t\t\t} else if (currentItem.postType === \"nav_menu_item\") {\n\t\t\t\t\t\t\t// Track nav_menu_item posts for post-processing into menus\n\t\t\t\t\t\t\tnavMenuItemPosts.push(currentItem);\n\t\t\t\t\t\t\tdata.posts.push(currentItem);\n\t\t\t\t\t\t} else if (currentItem.postType !== \"attachment\") {\n\t\t\t\t\t\t\t// Promote multilingual plugin metadata before storing.\n\t\t\t\t\t\t\t// All postmeta and per-item categories are parsed by the time\n\t\t\t\t\t\t\t// the closing </item> tag fires, so it's safe to inspect them.\n\t\t\t\t\t\t\tpromoteI18nMetadata(currentItem);\n\t\t\t\t\t\t\t// Store all non-attachment post types (posts, pages, custom post types)\n\t\t\t\t\t\t\tdata.posts.push(currentItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentItem = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Category parsing\n\t\t\tif (currentCategory) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentCategory.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_nicename\":\n\t\t\t\t\t\tcurrentCategory.nicename = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:cat_name\":\n\t\t\t\t\t\tcurrentCategory.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_parent\":\n\t\t\t\t\t\tcurrentCategory.parent = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_description\":\n\t\t\t\t\t\tcurrentCategory.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category\":\n\t\t\t\t\t\tif (currentCategory.name) {\n\t\t\t\t\t\t\tdata.categories.push(currentCategory);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentCategory = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Tag parsing\n\t\t\tif (currentTag) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentTag.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_slug\":\n\t\t\t\t\t\tcurrentTag.slug = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_name\":\n\t\t\t\t\t\tcurrentTag.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_description\":\n\t\t\t\t\t\tcurrentTag.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag\":\n\t\t\t\t\t\tif (currentTag.name) {\n\t\t\t\t\t\t\tdata.tags.push(currentTag);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentTag = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Author parsing\n\t\t\tif (currentAuthor) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:author_id\":\n\t\t\t\t\t\tcurrentAuthor.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_login\":\n\t\t\t\t\t\tcurrentAuthor.login = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_email\":\n\t\t\t\t\t\tcurrentAuthor.email = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_display_name\":\n\t\t\t\t\t\tcurrentAuthor.displayName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_first_name\":\n\t\t\t\t\t\tcurrentAuthor.firstName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_last_name\":\n\t\t\t\t\t\tcurrentAuthor.lastName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author\":\n\t\t\t\t\t\tif (currentAuthor.login) {\n\t\t\t\t\t\t\tdata.authors.push(currentAuthor);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAuthor = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generic term parsing (wp:term elements - custom taxonomies, nav_menu, etc.)\n\t\t\tif (currentTerm) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentTerm.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_taxonomy\":\n\t\t\t\t\t\tcurrentTerm.taxonomy = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_slug\":\n\t\t\t\t\t\tcurrentTerm.slug = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_name\":\n\t\t\t\t\t\tcurrentTerm.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_parent\":\n\t\t\t\t\t\tcurrentTerm.parent = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_description\":\n\t\t\t\t\t\tcurrentTerm.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term\":\n\t\t\t\t\t\tif (isCompleteWxrTerm(currentTerm)) {\n\t\t\t\t\t\t\tdata.terms.push(currentTerm);\n\t\t\t\t\t\t\t// Track nav_menu terms for building menus\n\t\t\t\t\t\t\tif (currentTerm.taxonomy === \"nav_menu\") {\n\t\t\t\t\t\t\t\tmenuTermsBySlug.set(currentTerm.slug, currentTerm.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentTerm = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentPath.pop();\n\t\t\tcurrentText = \"\";\n\t\t});\n\n\t\tparser.on(\"error\", (err) => {\n\t\t\treject(new Error(`XML parsing error: ${err.message}`));\n\t\t});\n\n\t\tparser.on(\"end\", () => {\n\t\t\t// Post-process nav_menu_item posts into structured menus\n\t\t\tdata.navMenus = buildNavMenus(navMenuItemPosts, menuTermsBySlug);\n\t\t\tresolve(data);\n\t\t});\n\n\t\t// Pipe the stream through the parser\n\t\tstream.pipe(parser);\n\t});\n}\n\n/**\n * Parse a WordPress WXR export from a string\n *\n * Uses the non-streaming SAX parser API for compatibility with\n * environments that don't have Node.js streams (e.g., Cloudflare Workers).\n */\nexport function parseWxrString(xml: string): Promise<WxrData> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst parser = sax.parser(true, { trim: false, normalize: false });\n\n\t\tconst data: WxrData = {\n\t\t\tsite: {},\n\t\t\tposts: [],\n\t\t\tattachments: [],\n\t\t\tcategories: [],\n\t\t\ttags: [],\n\t\t\tauthors: [],\n\t\t\tterms: [],\n\t\t\tnavMenus: [],\n\t\t};\n\n\t\tlet currentPath: string[] = [];\n\t\tlet currentText = \"\";\n\t\tlet currentItem: WxrPost | null = null;\n\t\tlet currentAttachment: WxrAttachment | null = null;\n\t\tlet currentCategory: WxrCategory | null = null;\n\t\tlet currentTag: WxrTag | null = null;\n\t\tlet currentAuthor: WxrAuthor | null = null;\n\t\tlet currentTerm: Partial<WxrTerm> | null = null;\n\t\tlet currentMetaKey = \"\";\n\t\t// Per-item category element currently open (see streaming-parser\n\t\t// counterpart above for rationale).\n\t\tlet pendingItemCategory: { domain: string; nicename: string } | null = null;\n\n\t\t// Track nav_menu_item posts for post-processing\n\t\tconst navMenuItemPosts: WxrPost[] = [];\n\t\t// Track menu term IDs by slug for linking items to menus\n\t\tconst menuTermsBySlug = new Map<string, number>();\n\n\t\tparser.onopentag = (node) => {\n\t\t\tconst tag = node.name.toLowerCase();\n\t\t\tcurrentPath.push(tag);\n\t\t\tcurrentText = \"\";\n\n\t\t\t// Start new elements\n\t\t\tif (tag === \"item\") {\n\t\t\t\tcurrentItem = {\n\t\t\t\t\tcategories: [],\n\t\t\t\t\ttags: [],\n\t\t\t\t\tcustomTaxonomies: new Map(),\n\t\t\t\t\tmeta: new Map(),\n\t\t\t\t};\n\t\t\t} else if (tag === \"wp:category\") {\n\t\t\t\tcurrentCategory = {};\n\t\t\t} else if (tag === \"wp:tag\") {\n\t\t\t\tcurrentTag = {};\n\t\t\t} else if (tag === \"wp:author\") {\n\t\t\t\tcurrentAuthor = {};\n\t\t\t} else if (tag === \"wp:term\") {\n\t\t\t\tcurrentTerm = {};\n\t\t\t}\n\n\t\t\t// Handle category/tag/custom taxonomy assignment in items\n\t\t\tif (tag === \"category\" && currentItem && node.attributes) {\n\t\t\t\tconst domain = attrStr(node.attributes.domain);\n\t\t\t\tconst nicename = attrStr(node.attributes.nicename);\n\t\t\t\tif (domain === \"category\" && nicename) {\n\t\t\t\t\tcurrentItem.categories.push(nicename);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t} else if (domain === \"post_tag\" && nicename) {\n\t\t\t\t\tcurrentItem.tags.push(nicename);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t} else if (domain && nicename && domain !== \"category\" && domain !== \"post_tag\") {\n\t\t\t\t\t// Custom taxonomy (including nav_menu)\n\t\t\t\t\tif (!currentItem.customTaxonomies) {\n\t\t\t\t\t\tcurrentItem.customTaxonomies = new Map();\n\t\t\t\t\t}\n\t\t\t\t\tconst existing = currentItem.customTaxonomies.get(domain) || [];\n\t\t\t\t\texisting.push(nicename);\n\t\t\t\t\tcurrentItem.customTaxonomies.set(domain, existing);\n\t\t\t\t\tpendingItemCategory = { domain, nicename };\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tparser.ontext = (text) => {\n\t\t\tcurrentText += text;\n\t\t};\n\n\t\tparser.oncdata = (cdata) => {\n\t\t\tcurrentText += cdata;\n\t\t};\n\n\t\tparser.onclosetag = (tagName) => {\n\t\t\tconst tag = tagName.toLowerCase();\n\t\t\tconst text = currentText.trim();\n\n\t\t\t// Site metadata: the closing tag is still on the path (rss > channel > tag)\n\t\t\tif (currentPath.length === 3 && currentPath[1] === \"channel\") {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tdata.site.title = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"link\":\n\t\t\t\t\t\tdata.site.link = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tdata.site.description = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"language\":\n\t\t\t\t\t\tdata.site.language = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:base_site_url\":\n\t\t\t\t\t\tdata.site.baseSiteUrl = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:base_blog_url\":\n\t\t\t\t\t\tdata.site.baseBlogUrl = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Item (post/page/attachment) parsing\n\t\t\tif (currentItem) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tcurrentItem.title = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"link\":\n\t\t\t\t\t\tcurrentItem.link = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"pubdate\":\n\t\t\t\t\t\tcurrentItem.pubDate = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"dc:creator\":\n\t\t\t\t\t\tcurrentItem.creator = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"guid\":\n\t\t\t\t\t\tcurrentItem.guid = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tcurrentItem.description = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"content:encoded\":\n\t\t\t\t\t\tcurrentItem.content = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"excerpt:encoded\":\n\t\t\t\t\t\tcurrentItem.excerpt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_id\":\n\t\t\t\t\t\tcurrentItem.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_date\":\n\t\t\t\t\t\tcurrentItem.postDate = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_date_gmt\":\n\t\t\t\t\t\tcurrentItem.postDateGmt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_modified\":\n\t\t\t\t\t\tcurrentItem.postModified = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_modified_gmt\":\n\t\t\t\t\t\tcurrentItem.postModifiedGmt = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:comment_status\":\n\t\t\t\t\t\tcurrentItem.commentStatus = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:ping_status\":\n\t\t\t\t\t\tcurrentItem.pingStatus = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_name\":\n\t\t\t\t\t\tcurrentItem.postName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:status\":\n\t\t\t\t\t\tcurrentItem.status = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_parent\":\n\t\t\t\t\t\tcurrentItem.postParent = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:menu_order\":\n\t\t\t\t\t\tcurrentItem.menuOrder = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_type\":\n\t\t\t\t\t\tcurrentItem.postType = text;\n\t\t\t\t\t\t// If it's an attachment, convert to attachment type\n\t\t\t\t\t\tif (text === \"attachment\") {\n\t\t\t\t\t\t\tcurrentAttachment = {\n\t\t\t\t\t\t\t\tid: currentItem.id,\n\t\t\t\t\t\t\t\ttitle: currentItem.title,\n\t\t\t\t\t\t\t\turl: currentItem.link,\n\t\t\t\t\t\t\t\tpostDate: currentItem.postDate,\n\t\t\t\t\t\t\t\tmeta: new Map(),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:post_password\":\n\t\t\t\t\t\tcurrentItem.postPassword = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:is_sticky\":\n\t\t\t\t\t\tcurrentItem.isSticky = text === \"1\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:attachment_url\":\n\t\t\t\t\t\tif (currentAttachment) {\n\t\t\t\t\t\t\tcurrentAttachment.url = text;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:meta_key\":\n\t\t\t\t\t\tcurrentMetaKey = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:meta_value\":\n\t\t\t\t\t\tif (currentMetaKey && currentItem.meta) {\n\t\t\t\t\t\t\tcurrentItem.meta.set(currentMetaKey, text);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"category\":\n\t\t\t\t\t\t// Per-item category text body = human label. See\n\t\t\t\t\t\t// streaming-parser counterpart for rationale.\n\t\t\t\t\t\tif (pendingItemCategory && text) {\n\t\t\t\t\t\t\tcaptureItemCategoryLabel(currentItem, pendingItemCategory, text);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpendingItemCategory = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"item\":\n\t\t\t\t\t\t// End of item - categorize and store\n\t\t\t\t\t\tif (currentAttachment) {\n\t\t\t\t\t\t\tdata.attachments.push(currentAttachment);\n\t\t\t\t\t\t\tcurrentAttachment = null;\n\t\t\t\t\t\t} else if (currentItem.postType === \"nav_menu_item\") {\n\t\t\t\t\t\t\t// Track nav_menu_item posts for post-processing into menus\n\t\t\t\t\t\t\tnavMenuItemPosts.push(currentItem);\n\t\t\t\t\t\t\tdata.posts.push(currentItem);\n\t\t\t\t\t\t} else if (currentItem.postType !== \"attachment\") {\n\t\t\t\t\t\t\t// Promote multilingual plugin metadata before storing.\n\t\t\t\t\t\t\t// All postmeta and per-item categories are parsed by the time\n\t\t\t\t\t\t\t// the closing </item> tag fires, so it's safe to inspect them.\n\t\t\t\t\t\t\tpromoteI18nMetadata(currentItem);\n\t\t\t\t\t\t\tdata.posts.push(currentItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentItem = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Category parsing\n\t\t\tif (currentCategory) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentCategory.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_nicename\":\n\t\t\t\t\t\tcurrentCategory.nicename = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:cat_name\":\n\t\t\t\t\t\tcurrentCategory.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_parent\":\n\t\t\t\t\t\tcurrentCategory.parent = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category_description\":\n\t\t\t\t\t\tcurrentCategory.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:category\":\n\t\t\t\t\t\tif (currentCategory.name) {\n\t\t\t\t\t\t\tdata.categories.push(currentCategory);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentCategory = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Tag parsing\n\t\t\tif (currentTag) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentTag.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_slug\":\n\t\t\t\t\t\tcurrentTag.slug = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_name\":\n\t\t\t\t\t\tcurrentTag.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag_description\":\n\t\t\t\t\t\tcurrentTag.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:tag\":\n\t\t\t\t\t\tif (currentTag.name) {\n\t\t\t\t\t\t\tdata.tags.push(currentTag);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentTag = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Author parsing\n\t\t\tif (currentAuthor) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:author_id\":\n\t\t\t\t\t\tcurrentAuthor.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_login\":\n\t\t\t\t\t\tcurrentAuthor.login = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_email\":\n\t\t\t\t\t\tcurrentAuthor.email = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_display_name\":\n\t\t\t\t\t\tcurrentAuthor.displayName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_first_name\":\n\t\t\t\t\t\tcurrentAuthor.firstName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author_last_name\":\n\t\t\t\t\t\tcurrentAuthor.lastName = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:author\":\n\t\t\t\t\t\tif (currentAuthor.login) {\n\t\t\t\t\t\t\tdata.authors.push(currentAuthor);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAuthor = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generic term parsing (wp:term elements - custom taxonomies, nav_menu, etc.)\n\t\t\tif (currentTerm) {\n\t\t\t\tswitch (tag) {\n\t\t\t\t\tcase \"wp:term_id\":\n\t\t\t\t\t\tcurrentTerm.id = parseInt(text, 10);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_taxonomy\":\n\t\t\t\t\t\tcurrentTerm.taxonomy = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_slug\":\n\t\t\t\t\t\tcurrentTerm.slug = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_name\":\n\t\t\t\t\t\tcurrentTerm.name = text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_parent\":\n\t\t\t\t\t\tcurrentTerm.parent = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term_description\":\n\t\t\t\t\t\tcurrentTerm.description = text || undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"wp:term\":\n\t\t\t\t\t\tif (isCompleteWxrTerm(currentTerm)) {\n\t\t\t\t\t\t\tdata.terms.push(currentTerm);\n\t\t\t\t\t\t\t// Track nav_menu terms for building menus\n\t\t\t\t\t\t\tif (currentTerm.taxonomy === \"nav_menu\") {\n\t\t\t\t\t\t\t\tmenuTermsBySlug.set(currentTerm.slug, currentTerm.id);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentTerm = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentPath.pop();\n\t\t\tcurrentText = \"\";\n\t\t};\n\n\t\tparser.onerror = (err) => {\n\t\t\treject(new Error(`XML parsing error: ${err.message}`));\n\t\t};\n\n\t\tparser.onend = () => {\n\t\t\t// Post-process nav_menu_item posts into structured menus\n\t\t\tdata.navMenus = buildNavMenus(navMenuItemPosts, menuTermsBySlug);\n\t\t\tresolve(data);\n\t\t};\n\n\t\t// Parse the string (non-streaming)\n\t\tparser.write(xml).close();\n\t});\n}\n\n/**\n * Build structured navigation menus from nav_menu_item posts\n */\nfunction buildNavMenus(\n\tnavMenuItemPosts: WxrPost[],\n\tmenuTermsBySlug: Map<string, number>,\n): WxrNavMenu[] {\n\t// Group menu items by menu slug\n\tconst menuItemsByMenu = new Map<string, WxrPost[]>();\n\n\tfor (const post of navMenuItemPosts) {\n\t\t// Get the nav_menu taxonomy assignment to find which menu this item belongs to\n\t\tconst navMenuSlugs = post.customTaxonomies?.get(\"nav_menu\");\n\t\tif (!navMenuSlugs || navMenuSlugs.length === 0) continue;\n\n\t\tconst menuSlug = navMenuSlugs[0];\n\t\tif (!menuSlug) continue;\n\n\t\tconst items = menuItemsByMenu.get(menuSlug) || [];\n\t\titems.push(post);\n\t\tmenuItemsByMenu.set(menuSlug, items);\n\t}\n\n\t// Build structured menus\n\tconst menus: WxrNavMenu[] = [];\n\n\tfor (const [menuSlug, posts] of menuItemsByMenu) {\n\t\tconst menuId = menuTermsBySlug.get(menuSlug) || 0;\n\n\t\t// Convert posts to menu items\n\t\tconst items: WxrNavMenuItem[] = posts.map((post) => {\n\t\t\tconst meta = post.meta;\n\t\t\tconst menuItemTypeRaw = meta.get(\"_menu_item_type\") || \"custom\";\n\t\t\tconst menuItemType: WxrNavMenuItem[\"type\"] =\n\t\t\t\tmenuItemTypeRaw === \"post_type\" || menuItemTypeRaw === \"taxonomy\"\n\t\t\t\t\t? menuItemTypeRaw\n\t\t\t\t\t: \"custom\";\n\t\t\tconst objectType = meta.get(\"_menu_item_object\");\n\t\t\tconst objectIdStr = meta.get(\"_menu_item_object_id\");\n\t\t\tconst url = meta.get(\"_menu_item_url\");\n\t\t\tconst parentIdStr = meta.get(\"_menu_item_menu_item_parent\");\n\t\t\tconst target = meta.get(\"_menu_item_target\");\n\t\t\tconst classesStr = meta.get(\"_menu_item_classes\");\n\n\t\t\t// Parse classes (stored as serialized PHP array)\n\t\t\tlet classes: string | undefined;\n\t\t\tif (classesStr) {\n\t\t\t\t// Simple extraction of class names from serialized PHP\n\t\t\t\tconst matches = classesStr.match(PHP_SERIALIZED_STRING_PATTERN);\n\t\t\t\tif (matches) {\n\t\t\t\t\tclasses = matches\n\t\t\t\t\t\t.map((m) => m.match(PHP_SERIALIZED_STRING_MATCH_PATTERN)?.[1])\n\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t.join(\" \");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid: post.id || 0,\n\t\t\t\tmenuId,\n\t\t\t\tparentId: parentIdStr ? parseInt(parentIdStr, 10) || undefined : undefined,\n\t\t\t\tsortOrder: post.menuOrder || 0,\n\t\t\t\ttype: menuItemType,\n\t\t\t\tobjectType: objectType || undefined,\n\t\t\t\tobjectId: objectIdStr ? parseInt(objectIdStr, 10) : undefined,\n\t\t\t\turl: url || undefined,\n\t\t\t\ttitle: post.title || \"\",\n\t\t\t\ttarget: target || undefined,\n\t\t\t\tclasses: classes || undefined,\n\t\t\t};\n\t\t});\n\n\t\t// Sort items by menu_order\n\t\titems.sort((a, b) => a.sortOrder - b.sortOrder);\n\n\t\t// Find the menu name from the terms\n\t\t// For now, use the slug as both name and label; we could enhance this\n\t\t// by looking up the actual term name from data.terms\n\t\tmenus.push({\n\t\t\tid: menuId,\n\t\t\tname: menuSlug,\n\t\t\tlabel: menuSlug, // Will be enhanced when we have term data\n\t\t\titems,\n\t\t});\n\t}\n\n\treturn menus;\n}\n","/**\n * Menu import functions\n *\n * Import navigation menus from WordPress WXR exports or plugin API.\n */\n\nimport type { Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { WxrNavMenu, WxrNavMenuItem } from \"../cli/wxr/parser.js\";\nimport type { Database } from \"../database/types.js\";\nimport type { MenuItemType } from \"../menus/types.js\";\nimport { invalidateMenuObjectCache } from \"../object-cache/index.js\";\n\n/**\n * Result of menu import operation\n */\nexport interface MenuImportResult {\n\t/** Number of menus created */\n\tmenusCreated: number;\n\t/** Number of menu items created */\n\titemsCreated: number;\n\t/** Mapping from WP menu slug to EmDash menu ID */\n\tmenuIdMap: Map<string, string>;\n\t/** Errors encountered during import */\n\terrors: Array<{ menu: string; error: string }>;\n}\n\n/**\n * Plugin API menu format (matches /emdash/v1/menus response)\n */\nexport interface PluginMenu {\n\tid: number;\n\tname: string; // slug\n\tlabel: string;\n\titems: PluginMenuItem[];\n}\n\nexport interface PluginMenuItem {\n\tid: number;\n\tparent_id: number | null;\n\tsort_order: number;\n\ttype: \"custom\" | \"post_type\" | \"taxonomy\";\n\tobject: string | null; // 'page', 'post', 'category'\n\tobject_id: number | null;\n\turl: string;\n\ttitle: string;\n\ttarget: string | null;\n\tclasses: string | null;\n}\n\n/**\n * Import navigation menus from WXR export\n *\n * @param menus - Parsed navigation menus from WXR\n * @param db - Database connection\n * @param contentIdMap - Map from WP post ID to EmDash content ID (for resolving references)\n * @returns Import result with counts and ID mapping\n */\nexport async function importMenusFromWxr(\n\tmenus: WxrNavMenu[],\n\tdb: Kysely<Database>,\n\tcontentIdMap: Map<number, string>,\n): Promise<MenuImportResult> {\n\tconst result: MenuImportResult = {\n\t\tmenusCreated: 0,\n\t\titemsCreated: 0,\n\t\tmenuIdMap: new Map(),\n\t\terrors: [],\n\t};\n\n\tfor (const menu of menus) {\n\t\ttry {\n\t\t\t// Check if menu already exists\n\t\t\tconst existing = await db\n\t\t\t\t.selectFrom(\"_emdash_menus\")\n\t\t\t\t.select(\"id\")\n\t\t\t\t.where(\"name\", \"=\", menu.name)\n\t\t\t\t.executeTakeFirst();\n\n\t\t\tif (existing) {\n\t\t\t\tresult.menuIdMap.set(menu.name, existing.id);\n\t\t\t\tcontinue; // Skip existing menus\n\t\t\t}\n\n\t\t\t// Create the menu\n\t\t\tconst menuId = ulid();\n\t\t\tawait db\n\t\t\t\t.insertInto(\"_emdash_menus\")\n\t\t\t\t.values({\n\t\t\t\t\tid: menuId,\n\t\t\t\t\tname: menu.name,\n\t\t\t\t\tlabel: menu.label,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\tresult.menusCreated++;\n\t\t\tresult.menuIdMap.set(menu.name, menuId);\n\n\t\t\t// Import menu items\n\t\t\tconst itemsCreated = await importWxrMenuItems(menu.items, menuId, db, contentIdMap);\n\t\t\tresult.itemsCreated += itemsCreated;\n\t\t} catch (error) {\n\t\t\tresult.errors.push({\n\t\t\t\tmenu: menu.name,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t}\n\t}\n\n\tif (result.menusCreated > 0) invalidateMenuObjectCache();\n\treturn result;\n}\n\n/**\n * Import navigation menus from Plugin API\n *\n * @param menus - Menus from plugin API\n * @param db - Database connection\n * @param contentIdMap - Map from WP post ID to EmDash content ID\n * @returns Import result with counts and ID mapping\n */\nexport async function importMenusFromPlugin(\n\tmenus: PluginMenu[],\n\tdb: Kysely<Database>,\n\tcontentIdMap: Map<number, string>,\n): Promise<MenuImportResult> {\n\tconst result: MenuImportResult = {\n\t\tmenusCreated: 0,\n\t\titemsCreated: 0,\n\t\tmenuIdMap: new Map(),\n\t\terrors: [],\n\t};\n\n\tfor (const menu of menus) {\n\t\ttry {\n\t\t\t// Check if menu already exists\n\t\t\tconst existing = await db\n\t\t\t\t.selectFrom(\"_emdash_menus\")\n\t\t\t\t.select(\"id\")\n\t\t\t\t.where(\"name\", \"=\", menu.name)\n\t\t\t\t.executeTakeFirst();\n\n\t\t\tif (existing) {\n\t\t\t\tresult.menuIdMap.set(menu.name, existing.id);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Create the menu\n\t\t\tconst menuId = ulid();\n\t\t\tawait db\n\t\t\t\t.insertInto(\"_emdash_menus\")\n\t\t\t\t.values({\n\t\t\t\t\tid: menuId,\n\t\t\t\t\tname: menu.name,\n\t\t\t\t\tlabel: menu.label,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\tresult.menusCreated++;\n\t\t\tresult.menuIdMap.set(menu.name, menuId);\n\n\t\t\t// Import menu items\n\t\t\tconst itemsCreated = await importPluginMenuItems(menu.items, menuId, db, contentIdMap);\n\t\t\tresult.itemsCreated += itemsCreated;\n\t\t} catch (error) {\n\t\t\tresult.errors.push({\n\t\t\t\tmenu: menu.name,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t}\n\t}\n\n\tif (result.menusCreated > 0) invalidateMenuObjectCache();\n\treturn result;\n}\n\n/**\n * Import menu items from WXR format\n */\nasync function importWxrMenuItems(\n\titems: WxrNavMenuItem[],\n\tmenuId: string,\n\tdb: Kysely<Database>,\n\tcontentIdMap: Map<number, string>,\n): Promise<number> {\n\t// Build a map of WP menu item IDs to EmDash IDs for parent resolution\n\tconst itemIdMap = new Map<number, string>();\n\tlet count = 0;\n\n\t// Sort items by sort order to maintain hierarchy\n\tconst sortedItems = items.toSorted((a, b) => a.sortOrder - b.sortOrder);\n\n\t// First pass: create all items with temporary parent IDs\n\tfor (const item of sortedItems) {\n\t\tconst itemId = ulid();\n\t\titemIdMap.set(item.id, itemId);\n\n\t\tconst { type, collection, referenceId, customUrl } = mapWxrMenuItem(item, contentIdMap);\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_menu_items\")\n\t\t\t.values({\n\t\t\t\tid: itemId,\n\t\t\t\tmenu_id: menuId,\n\t\t\t\tparent_id: null, // Will be set in second pass\n\t\t\t\tsort_order: item.sortOrder,\n\t\t\t\ttype,\n\t\t\t\treference_collection: collection,\n\t\t\t\treference_id: referenceId,\n\t\t\t\tcustom_url: customUrl,\n\t\t\t\tlabel: item.title,\n\t\t\t\ttitle_attr: null,\n\t\t\t\ttarget: item.target || null,\n\t\t\t\tcss_classes: item.classes || null,\n\t\t\t})\n\t\t\t.execute();\n\n\t\tcount++;\n\t}\n\n\t// Second pass: update parent IDs\n\tfor (const item of sortedItems) {\n\t\tif (item.parentId) {\n\t\t\tconst itemId = itemIdMap.get(item.id);\n\t\t\tconst parentId = itemIdMap.get(item.parentId);\n\n\t\t\tif (itemId && parentId) {\n\t\t\t\tawait db\n\t\t\t\t\t.updateTable(\"_emdash_menu_items\")\n\t\t\t\t\t.set({ parent_id: parentId })\n\t\t\t\t\t.where(\"id\", \"=\", itemId)\n\t\t\t\t\t.execute();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn count;\n}\n\n/**\n * Import menu items from Plugin API format\n */\nasync function importPluginMenuItems(\n\titems: PluginMenuItem[],\n\tmenuId: string,\n\tdb: Kysely<Database>,\n\tcontentIdMap: Map<number, string>,\n): Promise<number> {\n\tconst itemIdMap = new Map<number, string>();\n\tlet count = 0;\n\n\tconst sortedItems = items.toSorted((a, b) => a.sort_order - b.sort_order);\n\n\tfor (const item of sortedItems) {\n\t\tconst itemId = ulid();\n\t\titemIdMap.set(item.id, itemId);\n\n\t\tconst { type, collection, referenceId, customUrl } = mapPluginMenuItem(item, contentIdMap);\n\n\t\tawait db\n\t\t\t.insertInto(\"_emdash_menu_items\")\n\t\t\t.values({\n\t\t\t\tid: itemId,\n\t\t\t\tmenu_id: menuId,\n\t\t\t\tparent_id: null,\n\t\t\t\tsort_order: item.sort_order,\n\t\t\t\ttype,\n\t\t\t\treference_collection: collection,\n\t\t\t\treference_id: referenceId,\n\t\t\t\tcustom_url: customUrl,\n\t\t\t\tlabel: item.title,\n\t\t\t\ttitle_attr: null,\n\t\t\t\ttarget: item.target || null,\n\t\t\t\tcss_classes: item.classes || null,\n\t\t\t})\n\t\t\t.execute();\n\n\t\tcount++;\n\t}\n\n\t// Second pass: update parent IDs\n\tfor (const item of sortedItems) {\n\t\tif (item.parent_id) {\n\t\t\tconst itemId = itemIdMap.get(item.id);\n\t\t\tconst parentId = itemIdMap.get(item.parent_id);\n\n\t\t\tif (itemId && parentId) {\n\t\t\t\tawait db\n\t\t\t\t\t.updateTable(\"_emdash_menu_items\")\n\t\t\t\t\t.set({ parent_id: parentId })\n\t\t\t\t\t.where(\"id\", \"=\", itemId)\n\t\t\t\t\t.execute();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn count;\n}\n\n/**\n * Map WXR menu item to EmDash format\n */\nfunction mapWxrMenuItem(\n\titem: WxrNavMenuItem,\n\tcontentIdMap: Map<number, string>,\n): {\n\ttype: MenuItemType;\n\tcollection: string | null;\n\treferenceId: string | null;\n\tcustomUrl: string | null;\n} {\n\tswitch (item.type) {\n\t\tcase \"custom\":\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\n\t\tcase \"post_type\": {\n\t\t\t// Map WordPress object type to collection\n\t\t\tconst collection = mapObjectToCollection(item.objectType);\n\t\t\tconst referenceId = item.objectId ? contentIdMap.get(item.objectId) || null : null;\n\n\t\t\t// If we can't resolve the reference, fall back to custom URL\n\t\t\tif (!referenceId && item.url) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\tcollection: null,\n\t\t\t\t\treferenceId: null,\n\t\t\t\t\tcustomUrl: item.url,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttype: collection === \"pages\" ? \"page\" : \"post\",\n\t\t\t\tcollection,\n\t\t\t\treferenceId,\n\t\t\t\tcustomUrl: null,\n\t\t\t};\n\t\t}\n\n\t\tcase \"taxonomy\":\n\t\t\t// For taxonomies, we need taxonomy support in menus\n\t\t\t// Fall back to custom URL for now\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\t}\n}\n\n/**\n * Map Plugin menu item to EmDash format\n */\nfunction mapPluginMenuItem(\n\titem: PluginMenuItem,\n\tcontentIdMap: Map<number, string>,\n): {\n\ttype: MenuItemType;\n\tcollection: string | null;\n\treferenceId: string | null;\n\tcustomUrl: string | null;\n} {\n\tswitch (item.type) {\n\t\tcase \"custom\":\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\n\t\tcase \"post_type\": {\n\t\t\tconst collection = mapObjectToCollection(item.object);\n\t\t\tconst referenceId = item.object_id ? contentIdMap.get(item.object_id) || null : null;\n\n\t\t\tif (!referenceId && item.url) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\tcollection: null,\n\t\t\t\t\treferenceId: null,\n\t\t\t\t\tcustomUrl: item.url,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttype: collection === \"pages\" ? \"page\" : \"post\",\n\t\t\t\tcollection,\n\t\t\t\treferenceId,\n\t\t\t\tcustomUrl: null,\n\t\t\t};\n\t\t}\n\n\t\tcase \"taxonomy\":\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\ttype: \"custom\",\n\t\t\t\tcollection: null,\n\t\t\t\treferenceId: null,\n\t\t\t\tcustomUrl: item.url || \"#\",\n\t\t\t};\n\t}\n}\n\n/**\n * Map WordPress object type to EmDash collection name\n */\nfunction mapObjectToCollection(objectType: string | undefined | null): string {\n\tif (!objectType) return \"posts\";\n\n\tconst mapping: Record<string, string> = {\n\t\tpost: \"posts\",\n\t\tpage: \"pages\",\n\t\tproduct: \"products\",\n\t\tportfolio: \"portfolio\",\n\t};\n\n\treturn mapping[objectType] || objectType;\n}\n","/**\n * Sections import functions\n *\n * Import reusable blocks from WordPress WXR exports as EmDash sections.\n */\n\nimport type { PortableTextBlock } from \"@emdash-cms/gutenberg-to-portable-text\";\nimport { gutenbergToPortableText } from \"@emdash-cms/gutenberg-to-portable-text\";\nimport type { Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { WxrPost } from \"../cli/wxr/parser.js\";\nimport type { Database } from \"../database/types.js\";\nimport { slugify } from \"../utils/slugify.js\";\n\n/**\n * Result of sections import operation\n */\nexport interface SectionsImportResult {\n\t/** Number of sections created */\n\tsectionsCreated: number;\n\t/** Number of sections skipped (already exist) */\n\tsectionsSkipped: number;\n\t/** Errors encountered during import */\n\terrors: Array<{ title: string; error: string }>;\n}\n\n/**\n * Import reusable blocks (wp_block post type) from WXR as sections\n *\n * @param posts - All posts from WXR (will filter to wp_block)\n * @param db - Database connection\n * @returns Import result with counts\n */\nexport async function importReusableBlocksAsSections(\n\tposts: WxrPost[],\n\tdb: Kysely<Database>,\n): Promise<SectionsImportResult> {\n\tconst result: SectionsImportResult = {\n\t\tsectionsCreated: 0,\n\t\tsectionsSkipped: 0,\n\t\terrors: [],\n\t};\n\n\t// Filter to only wp_block posts\n\tconst reusableBlocks = posts.filter((post) => post.postType === \"wp_block\");\n\n\tif (reusableBlocks.length === 0) {\n\t\treturn result;\n\t}\n\n\tfor (const block of reusableBlocks) {\n\t\ttry {\n\t\t\tconst slug = block.postName || slugify(block.title || `block-${block.id || Date.now()}`);\n\n\t\t\t// Check if section already exists\n\t\t\tconst existing = await db\n\t\t\t\t.selectFrom(\"_emdash_sections\")\n\t\t\t\t.select(\"id\")\n\t\t\t\t.where(\"slug\", \"=\", slug)\n\t\t\t\t.executeTakeFirst();\n\n\t\t\tif (existing) {\n\t\t\t\tresult.sectionsSkipped++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert Gutenberg content to Portable Text\n\t\t\tconst content: PortableTextBlock[] = block.content\n\t\t\t\t? gutenbergToPortableText(block.content)\n\t\t\t\t: [];\n\n\t\t\tconst id = ulid();\n\t\t\tconst now = new Date().toISOString();\n\n\t\t\tawait db\n\t\t\t\t.insertInto(\"_emdash_sections\")\n\t\t\t\t.values({\n\t\t\t\t\tid,\n\t\t\t\t\tslug,\n\t\t\t\t\ttitle: block.title || \"Untitled Block\",\n\t\t\t\t\tdescription: null,\n\t\t\t\t\tkeywords: null,\n\t\t\t\t\tcontent: JSON.stringify(content),\n\t\t\t\t\tpreview_media_id: null,\n\t\t\t\t\tsource: \"import\",\n\t\t\t\t\ttheme_id: null,\n\t\t\t\t\tcreated_at: now,\n\t\t\t\t\tupdated_at: now,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\tresult.sectionsCreated++;\n\t\t} catch (error) {\n\t\t\tresult.errors.push({\n\t\t\t\ttitle: block.title || \"Untitled Block\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Comment import functions\n *\n * Import comments from the WordPress plugin API into EmDash's native\n * comments table, preserving authors, dates, threading, and status.\n */\n\nimport type { Kysely } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport type { Database } from \"../database/types.js\";\nimport { invalidateCommentObjectCache } from \"../object-cache/index.js\";\n\n/**\n * Plugin API comment format (matches /emdash/v1/comments items)\n */\nexport interface PluginComment {\n\tid: number;\n\tpost_id: number;\n\tparent_id: number | null;\n\tauthor_name: string;\n\tauthor_email: string;\n\t/** Plain-text body (the plugin strips HTML) */\n\tbody: string;\n\t/** ISO 8601 UTC timestamp */\n\tdate_gmt: string;\n\tstatus: \"approved\" | \"pending\";\n}\n\n/**\n * Result of comment import operation\n */\nexport interface CommentsImportResult {\n\t/** Number of comments created */\n\timported: number;\n\t/** Comments skipped (unresolvable post reference or already imported) */\n\tskipped: number;\n\t/** Errors encountered */\n\terrors: Array<{ comment: string; error: string }>;\n}\n\n/**\n * Import comments from the plugin API.\n *\n * Preserves original timestamps and threading. Comments whose post was\n * not imported (no entry in `contentIdMap`) are skipped. Re-running the\n * import is idempotent: a comment with the same post, author email, and\n * timestamp is not created twice.\n *\n * @param comments - Comments from the plugin API (all pages, flat)\n * @param db - Database connection\n * @param contentIdMap - WP post ID -> EmDash content ID\n * @param collectionMap - WP post ID -> EmDash collection slug\n * @param rootIds - Optional pre-seeded WP-comment-ID -> EmDash-root-ID map.\n * The chunked import passes the map accumulated from earlier pages so a\n * reply in page N can thread onto a parent imported in page N-1; the\n * function adds this page's entries to it.\n */\nexport async function importCommentsFromPlugin(\n\tcomments: PluginComment[],\n\tdb: Kysely<Database>,\n\tcontentIdMap: Map<number, string>,\n\tcollectionMap: Map<number, string>,\n\trootIds?: Map<number, string>,\n): Promise<CommentsImportResult> {\n\tconst result: CommentsImportResult = {\n\t\timported: 0,\n\t\tskipped: 0,\n\t\terrors: [],\n\t};\n\n\t// WP comment ID -> EmDash comment ID, for parent threading\n\tconst commentIdMap = new Map<number, string>();\n\n\t// WP comment ID -> EmDash ID of its top-level ancestor. EmDash threads\n\t// are one level deep (assembleThreads nests replies under roots only),\n\t// so deeper WP threads are flattened onto their root comment.\n\tconst rootIdMap = rootIds ?? new Map<number, string>();\n\n\t// Parents must exist before children reference them; WP comment IDs\n\t// are chronological, so ID order guarantees parents come first.\n\tconst sorted = comments.toSorted((a, b) => a.id - b.id);\n\n\tfor (const comment of sorted) {\n\t\tconst label = `${comment.author_name || \"Anonymous\"} (${comment.date_gmt})`;\n\t\ttry {\n\t\t\tconst contentId = contentIdMap.get(comment.post_id);\n\t\t\tconst collection = collectionMap.get(comment.post_id);\n\t\t\tif (!contentId || !collection) {\n\t\t\t\tresult.skipped++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parsed = new Date(comment.date_gmt);\n\t\t\tconst createdAt = Number.isNaN(parsed.getTime())\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: parsed.toISOString();\n\n\t\t\t// Idempotency: same post + author + timestamp + body = already\n\t\t\t// imported (body included so same-second comments from one author\n\t\t\t// don't collide). ponytail: one SELECT per comment — fine at\n\t\t\t// import scale; batch with WHERE IN for six-figure comment counts.\n\t\t\tconst existing = await db\n\t\t\t\t.selectFrom(\"_emdash_comments\")\n\t\t\t\t.select(\"id\")\n\t\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t\t.where(\"author_email\", \"=\", comment.author_email)\n\t\t\t\t.where(\"created_at\", \"=\", createdAt)\n\t\t\t\t.where(\"body\", \"=\", comment.body)\n\t\t\t\t.executeTakeFirst();\n\t\t\tconst parentId =\n\t\t\t\tcomment.parent_id !== null ? (rootIdMap.get(comment.parent_id) ?? null) : null;\n\n\t\t\tif (existing) {\n\t\t\t\tcommentIdMap.set(comment.id, existing.id);\n\t\t\t\trootIdMap.set(comment.id, parentId ?? existing.id);\n\t\t\t\tresult.skipped++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst id = ulid();\n\n\t\t\tawait db\n\t\t\t\t.insertInto(\"_emdash_comments\")\n\t\t\t\t.values({\n\t\t\t\t\tid,\n\t\t\t\t\tcollection,\n\t\t\t\t\tcontent_id: contentId,\n\t\t\t\t\tparent_id: parentId,\n\t\t\t\t\tauthor_name: comment.author_name || \"Anonymous\",\n\t\t\t\t\tauthor_email: comment.author_email,\n\t\t\t\t\tauthor_user_id: null,\n\t\t\t\t\tbody: comment.body,\n\t\t\t\t\tstatus: comment.status,\n\t\t\t\t\tip_hash: null,\n\t\t\t\t\tuser_agent: null,\n\t\t\t\t\tmoderation_metadata: null,\n\t\t\t\t\tcreated_at: createdAt,\n\t\t\t\t\tupdated_at: createdAt,\n\t\t\t\t})\n\t\t\t\t.execute();\n\n\t\t\tcommentIdMap.set(comment.id, id);\n\t\t\trootIdMap.set(comment.id, parentId ?? id);\n\t\t\tresult.imported++;\n\t\t} catch (error) {\n\t\t\tresult.errors.push({\n\t\t\t\tcomment: label,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t}\n\t}\n\n\tif (result.imported > 0) {\n\t\tinvalidateCommentObjectCache();\n\t}\n\n\treturn result;\n}\n","/**\n * Site settings import functions\n *\n * Import site settings from WordPress (title, tagline, logo, favicon)\n * into EmDash's site settings (the `site:*` options read by\n * `getSiteSettings()` and the templates).\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport { OptionsRepository } from \"../database/repositories/options.js\";\nimport type { Database } from \"../database/types.js\";\nimport { invalidateSiteSettingsCache } from \"../settings/index.js\";\nimport type { SiteSettings } from \"../settings/types.js\";\n\n/** Options key prefix used by the site settings module (`settings/index.ts`). */\nconst SETTINGS_PREFIX = \"site:\";\n\n/**\n * Site settings analysis from import source\n */\nexport interface SiteSettingsAnalysis {\n\t/** Site title */\n\ttitle?: string;\n\t/** Site tagline/description */\n\ttagline?: string;\n\t/** Custom logo (source URL + WP attachment ID) */\n\tlogo?: { url: string; id?: number };\n\t/** Favicon/site icon (source URL + WP attachment ID) */\n\tfavicon?: { url: string; id?: number };\n}\n\n/**\n * Result of site settings import\n */\nexport interface SettingsImportResult {\n\t/** Settings that were applied */\n\tapplied: string[];\n\t/** Settings that were skipped (already set) */\n\tskipped: string[];\n\t/** Errors encountered */\n\terrors: Array<{ setting: string; error: string }>;\n}\n\n/**\n * Resolved EmDash media IDs for the logo/favicon source URLs.\n * The caller side-loads the files (they need storage access) and\n * passes the resulting media IDs here.\n */\nexport interface SettingsMediaIds {\n\tlogoMediaId?: string;\n\tfaviconMediaId?: string;\n}\n\n/**\n * Import site settings from analysis into EmDash site settings.\n *\n * Writes the `site:*` options consumed by `getSiteSettings()` and\n * invalidates the settings cache. Logo/favicon are only applied when\n * the caller resolved them to EmDash media IDs.\n *\n * @param settings - Site settings analysis\n * @param db - Database connection\n * @param overwrite - Whether to overwrite existing settings (a fresh\n * site's seed already sets title/tagline, so migrations pass true)\n * @param media - Resolved media IDs for logo/favicon\n */\nexport async function importSiteSettings(\n\tsettings: SiteSettingsAnalysis,\n\tdb: Kysely<Database>,\n\toverwrite = false,\n\tmedia: SettingsMediaIds = {},\n): Promise<SettingsImportResult> {\n\tconst result: SettingsImportResult = {\n\t\tapplied: [],\n\t\tskipped: [],\n\t\terrors: [],\n\t};\n\n\tconst updates: Array<{ setting: keyof SiteSettings; value: unknown }> = [];\n\tif (settings.title) {\n\t\tupdates.push({ setting: \"title\", value: settings.title });\n\t}\n\tif (settings.tagline) {\n\t\tupdates.push({ setting: \"tagline\", value: settings.tagline });\n\t}\n\tif (media.logoMediaId) {\n\t\tupdates.push({ setting: \"logo\", value: { mediaId: media.logoMediaId } });\n\t}\n\tif (media.faviconMediaId) {\n\t\tupdates.push({ setting: \"favicon\", value: { mediaId: media.faviconMediaId } });\n\t}\n\n\tif (updates.length === 0) {\n\t\treturn result;\n\t}\n\n\tconst options = new OptionsRepository(db);\n\ttry {\n\t\tfor (const { setting, value } of updates) {\n\t\t\ttry {\n\t\t\t\tconst key = `${SETTINGS_PREFIX}${setting}`;\n\t\t\t\tif (!overwrite) {\n\t\t\t\t\tconst existing = await options.get(key);\n\t\t\t\t\tif (existing !== null) {\n\t\t\t\t\t\tresult.skipped.push(setting);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait options.set(key, value);\n\t\t\t\tresult.applied.push(setting);\n\t\t\t} catch (error) {\n\t\t\t\tresult.errors.push({\n\t\t\t\t\tsetting,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tif (result.applied.length > 0) {\n\t\t\tinvalidateSiteSettingsCache();\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Parse site settings from WordPress plugin options response\n */\nexport function parseSiteSettingsFromPlugin(\n\toptions: Record<string, unknown>,\n): SiteSettingsAnalysis {\n\tconst settings: SiteSettingsAnalysis = {};\n\n\tif (typeof options.blogname === \"string\" && options.blogname.trim() !== \"\") {\n\t\tsettings.title = options.blogname;\n\t}\n\tif (typeof options.blogdescription === \"string\" && options.blogdescription.trim() !== \"\") {\n\t\tsettings.tagline = options.blogdescription;\n\t}\n\n\tif (typeof options.custom_logo_url === \"string\" && options.custom_logo_url !== \"\") {\n\t\tsettings.logo = {\n\t\t\turl: options.custom_logo_url,\n\t\t\tid: typeof options.custom_logo === \"number\" ? options.custom_logo : undefined,\n\t\t};\n\t}\n\tif (typeof options.site_icon_url === \"string\" && options.site_icon_url !== \"\") {\n\t\tsettings.favicon = {\n\t\t\turl: options.site_icon_url,\n\t\t\tid: typeof options.site_icon === \"number\" ? options.site_icon : undefined,\n\t\t};\n\t}\n\n\treturn settings;\n}\n","/**\n * Import source registry\n *\n * Manages available import sources and provides URL probing.\n */\n\nimport { resolveAndValidateExternalUrl } from \"./ssrf.js\";\nimport type { ImportSource, ProbeResult, SourceProbeResult } from \"./types.js\";\n\n// Regex pattern for URL normalization\nconst TRAILING_SLASHES_PATTERN = /\\/+$/;\n\n/** Registered import sources */\nconst sources = new Map<string, ImportSource>();\n\n/**\n * A bot-protection challenge page (for example Cloudflare's \"Just a moment...\")\n * answered instead of the source's API. Server-side requests can't solve it,\n * so the site owner has to let the importer's requests through.\n */\nexport class SiteChallengeError extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t\"Cloudflare's bot protection answered with a challenge page instead of the EmDash Exporter API. Let requests to /wp-json/emdash/v1/ and ?rest_route=/emdash/v1/ through (for example with a WAF custom rule that skips bot protection), or pause bot protection during the migration.\",\n\t\t);\n\t\tthis.name = \"SiteChallengeError\";\n\t}\n}\n\n/**\n * Register an import source\n */\nexport function registerSource(source: ImportSource): void {\n\tsources.set(source.id, source);\n}\n\n/**\n * Get a source by ID\n */\nexport function getSource(id: string): ImportSource | undefined {\n\treturn sources.get(id);\n}\n\n/**\n * Get all registered sources\n */\nexport function getAllSources(): ImportSource[] {\n\treturn [...sources.values()];\n}\n\n/**\n * Get sources that can handle file uploads\n */\nexport function getFileSources(): ImportSource[] {\n\treturn getAllSources().filter((s) => s.requiresFile);\n}\n\n/**\n * Get sources that can probe URLs\n */\nexport function getUrlSources(): ImportSource[] {\n\treturn getAllSources().filter((s) => s.canProbe);\n}\n\n/**\n * Probe a URL against all registered sources\n *\n * Returns probe results sorted by confidence (definite > likely > possible)\n */\nexport async function probeUrl(url: string): Promise<ProbeResult> {\n\t// Normalize URL\n\tlet normalizedUrl = url.trim();\n\tif (!normalizedUrl.startsWith(\"http\")) {\n\t\tnormalizedUrl = `https://${normalizedUrl}`;\n\t}\n\n\t// Remove trailing slash for consistency\n\tnormalizedUrl = normalizedUrl.replace(TRAILING_SLASHES_PATTERN, \"\");\n\n\t// SSRF: reject internal/private network targets. DNS resolution\n\t// catches hostnames that resolve to private addresses.\n\tawait resolveAndValidateExternalUrl(normalizedUrl);\n\n\tconst results: SourceProbeResult[] = [];\n\tconst urlSources = getUrlSources();\n\tlet challenged = false;\n\n\t// Probe all sources in parallel\n\tconst probePromises = urlSources.map(async (source) => {\n\t\ttry {\n\t\t\tconst result = await source.probe?.(normalizedUrl);\n\t\t\tif (result) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof SiteChallengeError) challenged = true;\n\t\t\t// Probe failed, skip this source\n\t\t\tconsole.debug(`Probe failed for ${source.id}:`, error);\n\t\t}\n\t\treturn null;\n\t});\n\n\tconst probeResults = await Promise.allSettled(probePromises);\n\n\tfor (const result of probeResults) {\n\t\tif (result.status === \"fulfilled\" && result.value) {\n\t\t\tresults.push(result.value);\n\t\t}\n\t}\n\n\t// Sort by confidence\n\tconst confidenceOrder = { definite: 0, likely: 1, possible: 2 };\n\tresults.sort((a, b) => confidenceOrder[a.confidence] - confidenceOrder[b.confidence]);\n\n\treturn {\n\t\turl: normalizedUrl,\n\t\tisWordPress: results.length > 0,\n\t\tbestMatch: results[0] ?? null,\n\t\tallMatches: results,\n\t\t...(challenged && results.length === 0 ? { challenged: true } : {}),\n\t};\n}\n\n/**\n * Clear all registered sources (useful for testing)\n */\nexport function clearSources(): void {\n\tsources.clear();\n}\n","/**\n * WXR (WordPress eXtended RSS) import source\n *\n * Handles WordPress export file uploads (.xml).\n * This wraps the existing WXR parsing and analysis logic.\n */\n\nimport { gutenbergToPortableText } from \"@emdash-cms/gutenberg-to-portable-text\";\n\nimport { parseWxrString, type WxrData, type WxrPost } from \"../../cli/wxr/parser.js\";\nimport type {\n\tImportSource,\n\tImportAnalysis,\n\tImportContext,\n\tSourceInput,\n\tFetchOptions,\n\tNormalizedItem,\n\tPostTypeAnalysis,\n\tAttachmentInfo,\n\tNavMenuAnalysis,\n\tTaxonomyAnalysis,\n\tReusableBlockAnalysis,\n} from \"../types.js\";\nimport {\n\tBASE_REQUIRED_FIELDS,\n\tFEATURED_IMAGE_FIELD,\n\tisInternalPostType,\n\tisInternalMetaKey,\n\tmapWpStatus,\n\tmapPostTypeToCollection,\n\tmapMetaKeyToField,\n\tinferMetaType,\n\tslugify,\n\tbuildAttachmentMap,\n\tgetFilenameFromUrl,\n\tguessMimeType,\n\tcheckSchemaCompatibility,\n\trelativizeContentLinks,\n} from \"../utils.js\";\n\nexport const wxrSource: ImportSource = {\n\tid: \"wxr\",\n\tname: \"WordPress Export File\",\n\tdescription: \"Upload a WordPress export file (.xml)\",\n\ticon: \"upload\",\n\trequiresFile: true,\n\tcanProbe: false,\n\n\tasync analyze(input: SourceInput, context: ImportContext): Promise<ImportAnalysis> {\n\t\tif (input.type !== \"file\") {\n\t\t\tthrow new Error(\"WXR source requires a file input\");\n\t\t}\n\n\t\tconst text = await input.file.text();\n\t\tconst wxr = await parseWxrString(text);\n\n\t\t// Get existing collections for schema compatibility check\n\t\tconst existingCollections = context.getExistingCollections\n\t\t\t? await context.getExistingCollections()\n\t\t\t: new Map();\n\n\t\treturn analyzeWxrData(wxr, existingCollections);\n\t},\n\n\tasync *fetchContent(input: SourceInput, options: FetchOptions): AsyncGenerator<NormalizedItem> {\n\t\tif (input.type !== \"file\") {\n\t\t\tthrow new Error(\"WXR source requires a file input\");\n\t\t}\n\n\t\tconst text = await input.file.text();\n\t\tconst wxr = await parseWxrString(text);\n\n\t\t// Build attachment ID -> URL map for resolving featured images\n\t\tconst attachmentMap = buildAttachmentMap(wxr.attachments);\n\n\t\tlet count = 0;\n\t\tfor (const post of wxr.posts) {\n\t\t\tconst postType = post.postType || \"post\";\n\n\t\t\t// Skip if not in requested post types\n\t\t\tif (!options.postTypes.includes(postType)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Skip internal post types\n\t\t\tif (isInternalPostType(postType)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Skip drafts if not requested\n\t\t\tif (!options.includeDrafts && post.status !== \"publish\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert to normalized item\n\t\t\tyield wxrPostToNormalizedItem(post, attachmentMap, wxr.site.link || \"\");\n\n\t\t\tcount++;\n\t\t\tif (options.limit && count >= options.limit) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t},\n};\n\n/**\n * Analyze WXR data and return normalized ImportAnalysis\n */\nfunction analyzeWxrData(\n\twxr: WxrData,\n\texistingCollections: Map<string, { slug: string; fields: Map<string, { type: string }> }>,\n): ImportAnalysis {\n\t// Count post types and track which have featured images\n\tconst postTypeCounts = new Map<string, number>();\n\tconst postTypesWithThumbnails = new Set<string>();\n\tconst metaKeys = new Map<string, { count: number; samples: string[]; isInternal: boolean }>();\n\tconst authorPostCounts = new Map<string, number>();\n\n\tfor (const post of wxr.posts) {\n\t\tconst type = post.postType || \"post\";\n\t\tpostTypeCounts.set(type, (postTypeCounts.get(type) || 0) + 1);\n\n\t\t// Count posts per author (by login)\n\t\tif (post.creator) {\n\t\t\tauthorPostCounts.set(post.creator, (authorPostCounts.get(post.creator) || 0) + 1);\n\t\t}\n\n\t\t// Track if this post type has featured images\n\t\tif (post.meta.has(\"_thumbnail_id\")) {\n\t\t\tpostTypesWithThumbnails.add(type);\n\t\t}\n\n\t\t// Analyze meta keys\n\t\tfor (const [key, value] of post.meta) {\n\t\t\tconst existing = metaKeys.get(key);\n\t\t\tif (existing) {\n\t\t\t\texisting.count++;\n\t\t\t\tif (existing.samples.length < 3 && value) {\n\t\t\t\t\texisting.samples.push(value.slice(0, 100));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmetaKeys.set(key, {\n\t\t\t\t\tcount: 1,\n\t\t\t\t\tsamples: value ? [value.slice(0, 100)] : [],\n\t\t\t\t\tisInternal: isInternalMetaKey(key),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Map meta keys to fields (for custom fields analysis)\n\tconst customFields = [...metaKeys.entries()]\n\t\t.filter(([_, info]) => !info.isInternal)\n\t\t.map(([key, info]) => ({\n\t\t\tkey,\n\t\t\tcount: info.count,\n\t\t\tsamples: info.samples,\n\t\t\tsuggestedField: mapMetaKeyToField(key),\n\t\t\tsuggestedType: inferMetaType(key, info.samples[0]),\n\t\t\tisInternal: info.isInternal,\n\t\t}))\n\t\t.toSorted((a, b) => b.count - a.count);\n\n\t// Build post type analysis with schema compatibility\n\tconst postTypes: PostTypeAnalysis[] = [...postTypeCounts.entries()]\n\t\t.filter(([type]) => !isInternalPostType(type))\n\t\t.map(([name, count]) => {\n\t\t\tconst suggestedCollection = mapPostTypeToCollection(name);\n\t\t\tconst existingCollection = existingCollections.get(suggestedCollection);\n\n\t\t\t// Build required fields - add featured_image only if posts have thumbnails\n\t\t\tconst requiredFields = [...BASE_REQUIRED_FIELDS];\n\t\t\tif (postTypesWithThumbnails.has(name)) {\n\t\t\t\trequiredFields.push(FEATURED_IMAGE_FIELD);\n\t\t\t}\n\n\t\t\tconst schemaStatus = checkSchemaCompatibility(requiredFields, existingCollection);\n\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tcount,\n\t\t\t\tsuggestedCollection,\n\t\t\t\trequiredFields,\n\t\t\t\tschemaStatus,\n\t\t\t};\n\t\t})\n\t\t.toSorted((a, b) => b.count - a.count);\n\n\t// Build attachment info list\n\tconst attachmentItems: AttachmentInfo[] = wxr.attachments.map((att) => {\n\t\tconst filename = att.url ? getFilenameFromUrl(att.url) : undefined;\n\t\tconst mimeType = filename ? guessMimeType(filename) : undefined;\n\t\treturn {\n\t\t\tid: att.id,\n\t\t\ttitle: att.title,\n\t\t\turl: att.url,\n\t\t\tfilename,\n\t\t\tmimeType,\n\t\t};\n\t});\n\n\t// Analyze navigation menus\n\tconst navMenus: NavMenuAnalysis[] = wxr.navMenus.map((menu) => ({\n\t\tname: menu.name,\n\t\tlabel: menu.label,\n\t\titemCount: menu.items.length,\n\t}));\n\n\t// Analyze custom taxonomies (from wp:term elements, excluding category/post_tag/nav_menu)\n\tconst taxonomyMap = new Map<string, { count: number; samples: string[] }>();\n\tfor (const term of wxr.terms) {\n\t\tif (\n\t\t\tterm.taxonomy === \"category\" ||\n\t\t\tterm.taxonomy === \"post_tag\" ||\n\t\t\tterm.taxonomy === \"nav_menu\"\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst existing = taxonomyMap.get(term.taxonomy);\n\t\tif (existing) {\n\t\t\texisting.count++;\n\t\t\tif (existing.samples.length < 3) {\n\t\t\t\texisting.samples.push(term.name);\n\t\t\t}\n\t\t} else {\n\t\t\ttaxonomyMap.set(term.taxonomy, {\n\t\t\t\tcount: 1,\n\t\t\t\tsamples: [term.name],\n\t\t\t});\n\t\t}\n\t}\n\n\tconst customTaxonomies: TaxonomyAnalysis[] = Array.from(\n\t\ttaxonomyMap.entries(),\n\t\t([slug, info]) => ({\n\t\t\tslug,\n\t\t\ttermCount: info.count,\n\t\t\tsampleTerms: info.samples,\n\t\t}),\n\t).toSorted((a, b) => b.termCount - a.termCount);\n\n\t// Analyze reusable blocks (wp_block post type)\n\tconst reusableBlocks: ReusableBlockAnalysis[] = wxr.posts\n\t\t.filter((post) => post.postType === \"wp_block\")\n\t\t.map((post) => ({\n\t\t\tid: post.id || 0,\n\t\t\ttitle: post.title || \"Untitled Block\",\n\t\t\tslug: post.postName || slugify(post.title || `block-${post.id || Date.now()}`),\n\t\t}));\n\n\treturn {\n\t\tsourceId: \"wxr\",\n\t\tsite: {\n\t\t\ttitle: wxr.site.title || \"WordPress Site\",\n\t\t\turl: wxr.site.link || \"\",\n\t\t},\n\t\tpostTypes,\n\t\tattachments: {\n\t\t\tcount: wxr.attachments.length,\n\t\t\titems: attachmentItems,\n\t\t},\n\t\tcategories: wxr.categories.length,\n\t\ttags: wxr.tags.length,\n\t\tauthors: wxr.authors.map((a) => ({\n\t\t\tid: a.id,\n\t\t\tlogin: a.login,\n\t\t\temail: a.email,\n\t\t\tdisplayName: a.displayName || a.login || \"Unknown\",\n\t\t\tpostCount: a.login ? authorPostCounts.get(a.login) || 0 : 0,\n\t\t})),\n\t\tnavMenus: navMenus.length > 0 ? navMenus : undefined,\n\t\tcustomTaxonomies: customTaxonomies.length > 0 ? customTaxonomies : undefined,\n\t\treusableBlocks: reusableBlocks.length > 0 ? reusableBlocks : undefined,\n\t\tcustomFields,\n\t};\n}\n\n/**\n * Convert a WXR post to a normalized item\n */\nfunction wxrPostToNormalizedItem(\n\tpost: WxrPost,\n\tattachmentMap: Map<string, string>,\n\tsiteUrl: string,\n): NormalizedItem {\n\tconst content = post.content ? gutenbergToPortableText(post.content) : [];\n\tif (siteUrl) relativizeContentLinks(content, siteUrl);\n\n\t// Resolve featured image: _thumbnail_id is the attachment ID, look up the URL\n\tconst thumbnailId = post.meta.get(\"_thumbnail_id\");\n\tconst featuredImage = thumbnailId ? attachmentMap.get(String(thumbnailId)) : undefined;\n\n\t// Convert custom taxonomies Map to Record.\n\t// Strip Polylang's `language` taxonomy -- the parser already promoted it\n\t// to `post.locale`, and exposing it as a content taxonomy here would\n\t// (a) try to insert a `language` taxonomy on EmDash that doesn't exist\n\t// and (b) duplicate the locale signal in two places.\n\tlet customTaxonomies: Record<string, string[]> | undefined;\n\tif (post.customTaxonomies && post.customTaxonomies.size > 0) {\n\t\tconst filtered = Object.fromEntries(\n\t\t\t[...post.customTaxonomies].filter(([taxonomy]) => taxonomy !== \"language\"),\n\t\t);\n\t\tif (Object.keys(filtered).length > 0) {\n\t\t\tcustomTaxonomies = filtered;\n\t\t}\n\t}\n\n\treturn {\n\t\tsourceId: post.id || 0,\n\t\tpostType: post.postType || \"post\",\n\t\tstatus: mapWpStatus(post.status),\n\t\tslug: post.postName || slugify(post.title || `post-${post.id || Date.now()}`),\n\t\ttitle: post.title || \"Untitled\",\n\t\tcontent,\n\t\texcerpt: post.excerpt,\n\t\tdate: parseWxrDate(post.postDateGmt, post.pubDate, post.postDate) ?? new Date(),\n\t\tmodified: parseWxrDate(post.postModifiedGmt, undefined, post.postModified),\n\t\tauthor: post.creator,\n\t\tcategories: post.categories,\n\t\ttags: post.tags,\n\t\tmeta: Object.fromEntries(post.meta),\n\t\tfeaturedImage,\n\t\t// Hierarchical content support\n\t\tparentId: post.postParent && post.postParent !== 0 ? post.postParent : undefined,\n\t\tmenuOrder: post.menuOrder,\n\t\t// Custom taxonomy assignments\n\t\tcustomTaxonomies,\n\t\t// Multilingual plugin metadata (WPML / Polylang) promoted by the parser.\n\t\t// When absent, the caller (e.g. execute route) falls back to the\n\t\t// upload-wide locale.\n\t\tlocale: post.locale,\n\t\ttranslationGroup: post.translationGroup,\n\t};\n}\n\n/**\n * WordPress uses \"0000-00-00 00:00:00\" as a sentinel for missing GMT dates\n * (e.g. unpublished drafts). This must be treated as absent.\n */\nexport const WXR_ZERO_DATE = \"0000-00-00 00:00:00\";\n\n/**\n * Parse a WXR date with the correct fallback chain:\n * 1. GMT date (always UTC, most reliable)\n * 2. pubDate (RFC 2822, includes timezone offset)\n * 3. Site-local date (MySQL datetime without timezone, imprecise but best available)\n *\n * Returns undefined when none of the inputs yield a valid date.\n * Callers that need a guaranteed Date should use `?? new Date()`.\n */\nexport function parseWxrDate(\n\tgmtDate: string | undefined,\n\tpubDate: string | undefined,\n\tlocalDate: string | undefined,\n): Date | undefined {\n\tif (gmtDate && gmtDate !== WXR_ZERO_DATE) {\n\t\t// GMT dates from WordPress are \"YYYY-MM-DD HH:MM:SS\" in UTC.\n\t\t// Append \"Z\" so the JS Date constructor treats them as UTC.\n\t\treturn new Date(gmtDate.replace(\" \", \"T\") + \"Z\");\n\t}\n\n\tif (pubDate) {\n\t\t// RFC 2822 format includes timezone offset, JS Date parses it correctly\n\t\tconst d = new Date(pubDate);\n\t\tif (!isNaN(d.getTime())) return d;\n\t}\n\n\tif (localDate) {\n\t\t// Site-local time without timezone. Normalize to ISO-like form so\n\t\t// runtimes that reject \"YYYY-MM-DD HH:MM:SS\" can still parse it as\n\t\t// local time. If parsing still fails, return undefined.\n\t\tconst d = new Date(localDate.replace(\" \", \"T\"));\n\t\tif (!isNaN(d.getTime())) return d;\n\t}\n\n\treturn undefined;\n}\n\n// Export for use in other sources\nexport { analyzeWxrData, wxrPostToNormalizedItem };\n\n// Re-export shared utilities that other sources may need\nexport {\n\tBASE_REQUIRED_FIELDS,\n\tFEATURED_IMAGE_FIELD,\n\tmapPostTypeToCollection,\n\tisInternalPostType,\n\tcheckSchemaCompatibility,\n} from \"../utils.js\";\n","/**\n * WordPress REST API probe\n *\n * Probes self-hosted WordPress sites to detect capabilities.\n * This source is probe-only - it tells users what's available\n * and suggests next steps (usually: upload WXR file).\n */\n\nimport { ssrfSafeFetch, validateExternalUrl } from \"../ssrf.js\";\nimport type {\n\tImportSource,\n\tImportAnalysis,\n\tImportContext,\n\tSourceInput,\n\tSourceProbeResult,\n\tFetchOptions,\n\tNormalizedItem,\n} from \"../types.js\";\n\nconst TRAILING_SLASHES = /\\/+$/;\nconst WP_JSON_SUFFIX = /\\/wp-json\\/?$/;\n\n/** WordPress REST API discovery response */\ninterface WpApiDiscovery {\n\tname?: string;\n\tdescription?: string;\n\turl?: string;\n\thome?: string;\n\tgmt_offset?: number;\n\ttimezone_string?: string;\n\tnamespaces?: string[];\n\tauthentication?: Record<string, unknown>;\n\troutes?: Record<string, unknown>;\n}\n\nexport const wordpressRestSource: ImportSource = {\n\tid: \"wordpress-rest\",\n\tname: \"WordPress Site\",\n\tdescription: \"Connect to a self-hosted WordPress site\",\n\ticon: \"globe\",\n\trequiresFile: false,\n\tcanProbe: true,\n\n\tasync probe(url: string): Promise<SourceProbeResult | null> {\n\t\ttry {\n\t\t\tconst siteUrl = normalizeUrl(url);\n\n\t\t\t// SSRF protection: validate URL before any outbound requests\n\t\t\tvalidateExternalUrl(siteUrl);\n\n\t\t\t// Try to fetch the WP REST API root\n\t\t\tconst apiUrl = `${siteUrl}/wp-json/`;\n\t\t\tconst response = await ssrfSafeFetch(apiUrl, {\n\t\t\t\theaders: { Accept: \"application/json\" },\n\t\t\t\tsignal: AbortSignal.timeout(10000),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\t// Try alternate location (some sites use different prefix)\n\t\t\t\tconst altResponse = await ssrfSafeFetch(`${siteUrl}/?rest_route=/`, {\n\t\t\t\t\theaders: { Accept: \"application/json\" },\n\t\t\t\t\tsignal: AbortSignal.timeout(10000),\n\t\t\t\t});\n\n\t\t\t\tif (!altResponse.ok) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst data: WpApiDiscovery = await response.json();\n\n\t\t\t// Check if this looks like WordPress\n\t\t\tif (!data.namespaces?.includes(\"wp/v2\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Get content counts (unauthenticated - published only)\n\t\t\tconst preview = await getPublicContentCounts(siteUrl);\n\n\t\t\t// Check for authentication methods\n\t\t\tconst hasAppPasswords = !!data.authentication?.[\"application-passwords\"];\n\n\t\t\treturn {\n\t\t\t\tsourceId: \"wordpress-rest\",\n\t\t\t\tconfidence: \"definite\",\n\t\t\t\tdetected: {\n\t\t\t\t\tplatform: \"wordpress\",\n\t\t\t\t\tsiteTitle: data.name,\n\t\t\t\t\tsiteUrl: data.url || data.home || siteUrl,\n\t\t\t\t},\n\t\t\t\tcapabilities: {\n\t\t\t\t\tpublicContent: true,\n\t\t\t\t\tprivateContent: false, // Would need auth\n\t\t\t\t\tcustomPostTypes: false, // Only if show_in_rest: true\n\t\t\t\t\tallMeta: false, // Only if registered for REST\n\t\t\t\t\tmediaStream: true,\n\t\t\t\t},\n\t\t\t\tauth: hasAppPasswords\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttype: \"password\",\n\t\t\t\t\t\t\tinstructions:\n\t\t\t\t\t\t\t\t\"To import drafts and private content, create an Application Password in WordPress → Users → Your Profile → Application Passwords\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t\tpreview,\n\t\t\t\tsuggestedAction: {\n\t\t\t\t\ttype: \"upload\",\n\t\t\t\t\tinstructions:\n\t\t\t\t\t\t\"For a complete import including drafts, custom post types, and all metadata, export your content from WordPress (Tools → Export) and upload the file here.\",\n\t\t\t\t},\n\t\t\t};\n\t\t} catch {\n\t\t\t// Probe failed - not a WordPress site or not accessible\n\t\t\treturn null;\n\t\t}\n\t},\n\n\tasync analyze(_input: SourceInput, _context: ImportContext): Promise<ImportAnalysis> {\n\t\t// REST-only import not implemented - we use this for probe only\n\t\t// and suggest WXR upload for actual import\n\t\tthrow new Error(\"Direct REST API import not implemented. Please upload a WXR export file.\");\n\t},\n\n\t// eslint-disable-next-line require-yield\n\tasync *fetchContent(_input: SourceInput, _options: FetchOptions): AsyncGenerator<NormalizedItem> {\n\t\tthrow new Error(\"Direct REST API import not implemented. Please upload a WXR export file.\");\n\t},\n};\n\n/**\n * Normalize a URL for API requests\n */\nfunction normalizeUrl(url: string): string {\n\tlet normalized = url.trim();\n\n\t// Add protocol if missing\n\tif (!normalized.startsWith(\"http\")) {\n\t\tnormalized = `https://${normalized}`;\n\t}\n\n\t// Remove trailing slash\n\tnormalized = normalized.replace(TRAILING_SLASHES, \"\");\n\n\t// Remove /wp-json if included\n\tnormalized = normalized.replace(WP_JSON_SUFFIX, \"\");\n\n\treturn normalized;\n}\n\n/**\n * Get public content counts from REST API\n */\nasync function getPublicContentCounts(\n\tsiteUrl: string,\n): Promise<{ posts?: number; pages?: number; media?: number }> {\n\tconst result: { posts?: number; pages?: number; media?: number } = {};\n\n\ttry {\n\t\t// Fetch with per_page=1 to get total from headers\n\t\tconst [postsRes, pagesRes, mediaRes] = await Promise.allSettled([\n\t\t\tssrfSafeFetch(`${siteUrl}/wp-json/wp/v2/posts?per_page=1`, {\n\t\t\t\tsignal: AbortSignal.timeout(5000),\n\t\t\t}),\n\t\t\tssrfSafeFetch(`${siteUrl}/wp-json/wp/v2/pages?per_page=1`, {\n\t\t\t\tsignal: AbortSignal.timeout(5000),\n\t\t\t}),\n\t\t\tssrfSafeFetch(`${siteUrl}/wp-json/wp/v2/media?per_page=1`, {\n\t\t\t\tsignal: AbortSignal.timeout(5000),\n\t\t\t}),\n\t\t]);\n\n\t\tif (postsRes.status === \"fulfilled\" && postsRes.value.ok) {\n\t\t\tconst total = postsRes.value.headers.get(\"X-WP-Total\");\n\t\t\tif (total) result.posts = parseInt(total, 10);\n\t\t}\n\n\t\tif (pagesRes.status === \"fulfilled\" && pagesRes.value.ok) {\n\t\t\tconst total = pagesRes.value.headers.get(\"X-WP-Total\");\n\t\t\tif (total) result.pages = parseInt(total, 10);\n\t\t}\n\n\t\tif (mediaRes.status === \"fulfilled\" && mediaRes.value.ok) {\n\t\t\tconst total = mediaRes.value.headers.get(\"X-WP-Total\");\n\t\t\tif (total) result.media = parseInt(total, 10);\n\t\t}\n\t} catch {\n\t\t// Counts are optional, continue without them\n\t}\n\n\treturn result;\n}\n","/**\n * WordPress Plugin (EmDash Exporter) import source\n *\n * Connects to self-hosted WordPress sites running the EmDash Exporter plugin.\n * Provides full access to all content including drafts, custom post types, and ACF fields.\n */\n\nimport { gutenbergToPortableText } from \"@emdash-cms/gutenberg-to-portable-text\";\n\nimport { encodeBase64 } from \"../../utils/base64.js\";\nimport type { PluginComment } from \"../comments.js\";\nimport type { PluginMenu } from \"../menus.js\";\nimport { SiteChallengeError } from \"../registry.js\";\nimport { ssrfSafeFetch, validateExternalUrl } from \"../ssrf.js\";\nimport type {\n\tImportSource,\n\tImportAnalysis,\n\tImportContext,\n\tSourceInput,\n\tSourceProbeResult,\n\tI18nDetection,\n\tFetchOptions,\n\tNormalizedItem,\n\tPostTypeAnalysis,\n\tAttachmentInfo,\n} from \"../types.js\";\nimport {\n\tBASE_REQUIRED_FIELDS,\n\tFEATURED_IMAGE_FIELD,\n\tmapPostTypeToCollection,\n\tmapWpStatus,\n\tnormalizeUrl,\n\tcheckSchemaCompatibility,\n\tisPluginBookkeepingMeta,\n\tisTypeCompatible,\n\trelativizeContentLinks,\n\tsanitizeFieldSlug,\n} from \"../utils.js\";\nimport { parseWxrDate } from \"./wxr.js\";\n\n// =============================================================================\n// API Response Types\n// =============================================================================\n\n/** Detected i18n plugin info from the WordPress site */\ninterface PluginI18nInfo {\n\t/** Which multilingual plugin is active */\n\tplugin: \"wpml\" | \"polylang\";\n\t/** BCP 47 default locale */\n\tdefault_locale: string;\n\t/** All configured locales */\n\tlocales: string[];\n}\n\n/** Probe response from /emdash/v1/probe */\ninterface PluginProbeResponse {\n\temdash_exporter: string;\n\twordpress_version: string;\n\tsite: {\n\t\ttitle: string;\n\t\tdescription: string;\n\t\turl: string;\n\t\thome: string;\n\t\tlanguage: string;\n\t\ttimezone: string;\n\t};\n\tcapabilities: {\n\t\tapplication_passwords: boolean;\n\t\tacf: boolean;\n\t\tyoast: boolean;\n\t\trankmath: boolean;\n\t};\n\tpost_types: Array<{\n\t\tname: string;\n\t\tlabel: string;\n\t\tcount: number;\n\t}>;\n\tmedia_count: number;\n\tendpoints: Record<string, string>;\n\tauth_instructions: {\n\t\tmethod: string;\n\t\tinstructions: string;\n\t\turl?: string;\n\t};\n\t/** Detected multilingual plugin (WPML or Polylang). Absent when neither is active. */\n\ti18n?: PluginI18nInfo;\n}\n\n/** Analyze response from /emdash/v1/analyze */\ninterface PluginAnalyzeResponse {\n\tsite: {\n\t\ttitle: string;\n\t\turl: string;\n\t};\n\tpost_types: Array<{\n\t\tname: string;\n\t\tlabel: string;\n\t\tlabel_singular: string;\n\t\ttotal: number;\n\t\tby_status: Record<string, number>;\n\t\tsupports: Record<string, unknown>;\n\t\ttaxonomies: string[];\n\t\tcustom_fields: Array<{\n\t\t\tkey: string;\n\t\t\tcount: number;\n\t\t\tinferred_type: string;\n\t\t\tsample: string | null;\n\t\t}>;\n\t\thierarchical: boolean;\n\t\thas_archive: boolean;\n\t}>;\n\ttaxonomies: Array<{\n\t\tname: string;\n\t\tlabel: string;\n\t\thierarchical: boolean;\n\t\tterm_count: number;\n\t\tobject_types: string[];\n\t}>;\n\tauthors: Array<{\n\t\tid: number;\n\t\tlogin: string;\n\t\temail: string;\n\t\tdisplay_name: string;\n\t\tpost_count: number;\n\t}>;\n\tattachments: {\n\t\tcount: number;\n\t\tby_type: Record<string, number>;\n\t};\n\tacf?: Array<{\n\t\tkey: string;\n\t\ttitle: string;\n\t\t/** ACF location rules: OR-groups of AND-ed rules */\n\t\tlocation?: Array<Array<{ param: string; operator: string; value: string }>>;\n\t\tfields: Array<{\n\t\t\tkey: string;\n\t\t\tname: string;\n\t\t\tlabel: string;\n\t\t\ttype: string;\n\t\t\trequired: boolean;\n\t\t}>;\n\t}>;\n\t/** Detected multilingual plugin (WPML or Polylang). Absent when neither is active. */\n\ti18n?: PluginI18nInfo;\n}\n\n/** Content response from /emdash/v1/content */\ninterface PluginContentResponse {\n\titems: PluginPost[];\n\ttotal: number;\n\tpages: number;\n\tpage: number;\n\tper_page: number;\n}\n\n/** Single post from plugin API */\ninterface PluginPost {\n\tid: number;\n\tpost_type: string;\n\tstatus: string;\n\tslug: string;\n\ttitle: string;\n\tcontent: string;\n\texcerpt: string;\n\tdate: string;\n\tdate_gmt: string;\n\tmodified: string;\n\tmodified_gmt: string;\n\tauthor: {\n\t\tid: number;\n\t\tlogin: string;\n\t\temail: string;\n\t\tdisplay_name: string;\n\t} | null;\n\tparent: number | null;\n\tmenu_order: number;\n\ttaxonomies: Record<string, Array<{ id: number; name: string; slug: string }>>;\n\tfeatured_image?: {\n\t\tid: number;\n\t\turl: string;\n\t\tfilename: string;\n\t\tmime_type: string;\n\t\talt: string;\n\t\ttitle: string;\n\t\tcaption: string;\n\t\twidth: number | null;\n\t\theight: number | null;\n\t};\n\tmeta: Record<string, unknown>;\n\tacf?: Record<string, unknown>;\n\tyoast?: Record<string, string>;\n\trankmath?: Record<string, string>;\n\t/** BCP 47 locale from WPML/Polylang (when detected) */\n\tlocale?: string;\n\t/** Translation group ID from WPML trid or Polylang (when detected) */\n\ttranslation_group?: string;\n}\n\n/** Media response from /emdash/v1/media */\ninterface PluginMediaResponse {\n\titems: PluginMediaItem[];\n\ttotal: number;\n\tpages: number;\n\tpage: number;\n\tper_page: number;\n}\n\ninterface PluginMediaItem {\n\tid: number;\n\turl: string;\n\tfilename: string;\n\tmime_type: string;\n\ttitle: string;\n\talt: string;\n\tcaption: string;\n\tdescription: string;\n\twidth?: number;\n\theight?: number;\n\tfilesize?: number;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** Pattern to remove spaces from application passwords */\nconst SPACE_PATTERN = /\\s/g;\n\n/**\n * Identifying User-Agent for outbound WordPress plugin importer requests.\n *\n * The importer sends this on both plugin API calls and direct media downloads.\n * Cloudflare Workers' fetch() has no default User-Agent, and some hosts reject\n * requests without one (returning 403). Using the same value everywhere keeps\n * behavior predictable when the importer is retried against a bot-filtered host.\n */\nconst IMPORTER_USER_AGENT = \"EmDash-Importer/1.0\";\n\n/**\n * Build the REST API URL for a plugin endpoint.\n *\n * `restRoute: false` uses the pretty form (`/wp-json/emdash/v1/...`),\n * `restRoute: true` uses the `?rest_route=` form that works on sites with\n * plain permalinks (where `/wp-json/` doesn't exist).\n */\nfunction pluginApiUrl(\n\tsiteUrl: string,\n\tpath: string,\n\tparams: Record<string, string> = {},\n\trestRoute = false,\n): string {\n\tif (restRoute) {\n\t\tconst url = new URL(siteUrl + \"/\");\n\t\turl.searchParams.set(\"rest_route\", `/emdash/v1/${path}`);\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\turl.searchParams.set(key, value);\n\t\t}\n\t\treturn url.toString();\n\t}\n\tconst url = new URL(`${siteUrl}/wp-json/emdash/v1/${path}`);\n\tfor (const [key, value] of Object.entries(params)) {\n\t\turl.searchParams.set(key, value);\n\t}\n\treturn url.toString();\n}\n\n/**\n * Fetch a plugin API endpoint, falling back to the `?rest_route=` form when\n * the pretty `/wp-json/` route 404s or is unreachable. Sites with \"Plain\"\n * permalinks have no `/wp-json/` rewrite, so without this fallback they\n * always fail with a misleading 404.\n */\nasync function fetchPluginApi(\n\tsiteUrl: string,\n\tpath: string,\n\tparams: Record<string, string>,\n\theadersInit: HeadersInit,\n\ttimeoutMs: number,\n): Promise<Response> {\n\tconst headers = new Headers(headersInit);\n\theaders.set(\"User-Agent\", IMPORTER_USER_AGENT);\n\n\tlet pretty: Response | null = null;\n\ttry {\n\t\tpretty = await ssrfSafeFetch(pluginApiUrl(siteUrl, path, params), {\n\t\t\theaders,\n\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t});\n\t} catch {\n\t\t// Network-level failure -- try the rest_route form before giving up.\n\t}\n\t// Any response other than 404 (including 401/403/500) is authoritative:\n\t// the route exists, so don't mask the real error with a fallback attempt.\n\tconst response =\n\t\tpretty && pretty.status !== 404\n\t\t\t? pretty\n\t\t\t: await ssrfSafeFetch(pluginApiUrl(siteUrl, path, params, true), {\n\t\t\t\t\theaders,\n\t\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t\t});\n\tif (response.headers.get(\"cf-mitigated\") === \"challenge\") {\n\t\tthrow new SiteChallengeError();\n\t}\n\treturn response;\n}\n\n// =============================================================================\n// Import Source\n// =============================================================================\n\nexport const wordpressPluginSource: ImportSource = {\n\tid: \"wordpress-plugin\",\n\tname: \"WordPress (EmDash Exporter)\",\n\tdescription: \"Import from WordPress sites with the EmDash Exporter plugin installed\",\n\ticon: \"plug\",\n\trequiresFile: false,\n\tcanProbe: true,\n\n\tasync probe(url: string): Promise<SourceProbeResult | null> {\n\t\ttry {\n\t\t\tconst siteUrl = normalizeUrl(url);\n\n\t\t\t// SSRF protection: validate URL before any outbound requests\n\t\t\tvalidateExternalUrl(siteUrl);\n\n\t\t\tconst response = await fetchPluginApi(\n\t\t\t\tsiteUrl,\n\t\t\t\t\"probe\",\n\t\t\t\t{},\n\t\t\t\t{ Accept: \"application/json\" },\n\t\t\t\t10000,\n\t\t\t);\n\n\t\t\tif (!response.ok) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst data: PluginProbeResponse = await response.json();\n\n\t\t\t// Verify it's actually our plugin\n\t\t\tif (!data.emdash_exporter) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsourceId: \"wordpress-plugin\",\n\t\t\t\tconfidence: \"definite\",\n\t\t\t\tdetected: {\n\t\t\t\t\tplatform: \"wordpress\",\n\t\t\t\t\tversion: data.wordpress_version,\n\t\t\t\t\tsiteTitle: data.site.title,\n\t\t\t\t\tsiteUrl: data.site.url,\n\t\t\t\t},\n\t\t\t\tcapabilities: {\n\t\t\t\t\tpublicContent: true,\n\t\t\t\t\tprivateContent: true, // Full access with auth\n\t\t\t\t\tcustomPostTypes: true,\n\t\t\t\t\tallMeta: true,\n\t\t\t\t\tmediaStream: true,\n\t\t\t\t},\n\t\t\t\tauth: data.capabilities.application_passwords\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttype: \"password\",\n\t\t\t\t\t\t\tinstructions: data.auth_instructions.instructions,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t\tpreview: {\n\t\t\t\t\tposts: data.post_types.find((p) => p.name === \"post\")?.count,\n\t\t\t\t\tpages: data.post_types.find((p) => p.name === \"page\")?.count,\n\t\t\t\t\tmedia: data.media_count,\n\t\t\t\t},\n\t\t\t\tsuggestedAction: {\n\t\t\t\t\ttype: \"proceed\",\n\t\t\t\t},\n\t\t\t\ti18n: pluginI18nToDetection(data.i18n),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (error instanceof SiteChallengeError) throw error;\n\t\t\treturn null;\n\t\t}\n\t},\n\n\tasync analyze(input: SourceInput, context: ImportContext): Promise<ImportAnalysis> {\n\t\tconst { siteUrl, headers } = getRequestConfig(input);\n\n\t\tconst response = await fetchPluginApi(siteUrl, \"analyze\", {}, headers, 30000);\n\n\t\tif (!response.ok) {\n\t\t\tconst body: unknown = await response.json().catch(() => undefined);\n\t\t\tconst message =\n\t\t\t\ttypeof body === \"object\" &&\n\t\t\t\tbody !== null &&\n\t\t\t\t\"message\" in body &&\n\t\t\t\ttypeof body.message === \"string\"\n\t\t\t\t\t? body.message\n\t\t\t\t\t: \"\";\n\t\t\tthrow new Error(message || `Failed to analyze site: ${response.statusText}`);\n\t\t}\n\n\t\tconst data: PluginAnalyzeResponse = await response.json();\n\n\t\t// Get existing collections for schema check\n\t\tconst existingCollections = context.getExistingCollections\n\t\t\t? await context.getExistingCollections()\n\t\t\t: new Map();\n\n\t\t// Build post type analysis\n\t\tconst postTypes: PostTypeAnalysis[] = data.post_types\n\t\t\t.filter((pt) => pt.total > 0)\n\t\t\t.map((pt) => {\n\t\t\t\tconst suggestedCollection = mapPostTypeToCollection(pt.name);\n\t\t\t\tconst existingCollection = existingCollections.get(suggestedCollection);\n\n\t\t\t\t// Include featured_image if post type supports thumbnails\n\t\t\t\tconst supportsThumbnail = pt.supports && \"thumbnail\" in pt.supports;\n\t\t\t\tconst requiredFields = supportsThumbnail\n\t\t\t\t\t? [...BASE_REQUIRED_FIELDS, FEATURED_IMAGE_FIELD]\n\t\t\t\t\t: [...BASE_REQUIRED_FIELDS];\n\n\t\t\t\t// Surface the post type's custom fields (ACF and plain meta) so\n\t\t\t\t// the prepare step creates them — without this, execute() has no\n\t\t\t\t// matching schema fields and silently drops the values.\n\t\t\t\tconst knownSlugs = new Set(requiredFields.map((f) => f.slug));\n\t\t\t\tconst metaTypes = new Map(\n\t\t\t\t\t(pt.custom_fields ?? []).map((field) => [\n\t\t\t\t\t\tsanitizeFieldSlug(field.key),\n\t\t\t\t\t\tmapInferredFieldType(field.inferred_type),\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\t\tconst jsonAcfFields: AcfFieldInfo[] = [];\n\t\t\t\tfor (const acfField of acfFieldsForPostType(data.acf, pt.name)) {\n\t\t\t\t\tconst slug = sanitizeFieldSlug(acfField.name);\n\t\t\t\t\tif (knownSlugs.has(slug)) continue;\n\t\t\t\t\tknownSlugs.add(slug);\n\t\t\t\t\tconst type = acfImportFieldType(\n\t\t\t\t\t\tacfField,\n\t\t\t\t\t\texistingCollection?.fields.get(slug)?.type,\n\t\t\t\t\t\tmetaTypes.get(slug),\n\t\t\t\t\t);\n\t\t\t\t\tif (type === \"json\") jsonAcfFields.push(acfField);\n\t\t\t\t\trequiredFields.push({\n\t\t\t\t\t\tslug,\n\t\t\t\t\t\tlabel: acfField.label || fieldLabelFromKey(acfField.name),\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\trequired: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tfor (const customField of pt.custom_fields ?? []) {\n\t\t\t\t\tif (isPluginBookkeepingMeta(customField.key)) continue;\n\t\t\t\t\tif (isAcfRowMeta(customField.key, jsonAcfFields)) continue;\n\t\t\t\t\tconst slug = sanitizeFieldSlug(customField.key);\n\t\t\t\t\tif (knownSlugs.has(slug)) continue;\n\t\t\t\t\tknownSlugs.add(slug);\n\t\t\t\t\trequiredFields.push({\n\t\t\t\t\t\tslug,\n\t\t\t\t\t\tlabel: fieldLabelFromKey(customField.key),\n\t\t\t\t\t\ttype: mapInferredFieldType(customField.inferred_type),\n\t\t\t\t\t\trequired: false,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tname: pt.name,\n\t\t\t\t\tcount: pt.total,\n\t\t\t\t\tsuggestedCollection,\n\t\t\t\t\trequiredFields,\n\t\t\t\t\tschemaStatus: checkSchemaCompatibility(requiredFields, existingCollection),\n\t\t\t\t};\n\t\t\t});\n\n\t\t// Fetch the full media list, paginated. Stopping after the first page\n\t\t// silently capped imports at 500 attachments (wp-emdash #1).\n\t\tconst attachments: AttachmentInfo[] = [];\n\t\tif (data.attachments.count > 0) {\n\t\t\ttry {\n\t\t\t\tlet page = 1;\n\t\t\t\tlet totalPages = 1;\n\t\t\t\twhile (page <= totalPages) {\n\t\t\t\t\tconst mediaResponse = await fetchPluginApi(\n\t\t\t\t\t\tsiteUrl,\n\t\t\t\t\t\t\"media\",\n\t\t\t\t\t\t{ per_page: \"500\", page: String(page) },\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\t30000,\n\t\t\t\t\t);\n\t\t\t\t\tif (!mediaResponse.ok) break;\n\t\t\t\t\tconst mediaData: PluginMediaResponse = await mediaResponse.json();\n\t\t\t\t\ttotalPages = mediaData.pages;\n\t\t\t\t\tfor (const item of mediaData.items) {\n\t\t\t\t\t\tattachments.push({\n\t\t\t\t\t\t\tid: item.id,\n\t\t\t\t\t\t\turl: item.url,\n\t\t\t\t\t\t\tfilename: item.filename,\n\t\t\t\t\t\t\tmimeType: item.mime_type,\n\t\t\t\t\t\t\ttitle: item.title,\n\t\t\t\t\t\t\talt: item.alt,\n\t\t\t\t\t\t\tcaption: item.caption,\n\t\t\t\t\t\t\twidth: item.width,\n\t\t\t\t\t\t\theight: item.height,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tpage++;\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof SiteChallengeError) throw e;\n\t\t\t\tconsole.warn(\"Failed to fetch media list:\", e);\n\t\t\t}\n\t\t}\n\n\t\t// Count categories and tags\n\t\tconst categoryTaxonomy = data.taxonomies.find((t) => t.name === \"category\");\n\t\tconst tagTaxonomy = data.taxonomies.find((t) => t.name === \"post_tag\");\n\n\t\treturn {\n\t\t\tsourceId: \"wordpress-plugin\",\n\t\t\tsite: {\n\t\t\t\ttitle: data.site.title,\n\t\t\t\turl: data.site.url,\n\t\t\t},\n\t\t\tpostTypes,\n\t\t\tattachments: {\n\t\t\t\tcount: data.attachments.count,\n\t\t\t\titems: attachments,\n\t\t\t},\n\t\t\tcategories: categoryTaxonomy?.term_count ?? 0,\n\t\t\ttags: tagTaxonomy?.term_count ?? 0,\n\t\t\tauthors: data.authors.map((a) => ({\n\t\t\t\tid: a.id,\n\t\t\t\tlogin: a.login,\n\t\t\t\temail: a.email,\n\t\t\t\tdisplayName: a.display_name,\n\t\t\t\tpostCount: a.post_count,\n\t\t\t})),\n\t\t\ti18n: pluginI18nToDetection(data.i18n),\n\t\t};\n\t},\n\n\tasync *fetchContent(input: SourceInput, options: FetchOptions): AsyncGenerator<NormalizedItem> {\n\t\tconst { siteUrl, headers } = getRequestConfig(input);\n\n\t\tfor (const postType of options.postTypes) {\n\t\t\tlet page = 1;\n\t\t\tlet totalPages = 1;\n\t\t\tlet yielded = 0;\n\n\t\t\twhile (page <= totalPages) {\n\t\t\t\tconst status = options.includeDrafts ? \"any\" : \"publish\";\n\t\t\t\tconst response = await fetchPluginApi(\n\t\t\t\t\tsiteUrl,\n\t\t\t\t\t\"content\",\n\t\t\t\t\t{ post_type: postType, status, per_page: \"100\", page: String(page) },\n\t\t\t\t\theaders,\n\t\t\t\t\t60000,\n\t\t\t\t);\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to fetch ${postType}: ${response.statusText}`);\n\t\t\t\t}\n\n\t\t\t\tconst data: PluginContentResponse = await response.json();\n\t\t\t\ttotalPages = data.pages;\n\n\t\t\t\tfor (const post of data.items) {\n\t\t\t\t\tyield pluginPostToNormalizedItem(post, siteUrl);\n\t\t\t\t\tyielded++;\n\n\t\t\t\t\tif (options.limit && yielded >= options.limit) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpage++;\n\t\t\t}\n\t\t}\n\t},\n\n\tasync fetchMedia(url: string, _input: SourceInput): Promise<Blob> {\n\t\t// SSRF protection: validate media URL before fetching\n\t\tvalidateExternalUrl(url);\n\n\t\t// Media URLs are publicly accessible on WP (ssrfSafeFetch validates redirects)\n\t\tconst response = await ssrfSafeFetch(url, {\n\t\t\theaders: {\n\t\t\t\t\"User-Agent\": IMPORTER_USER_AGENT,\n\t\t\t},\n\t\t});\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch media: ${response.statusText}`);\n\t\t}\n\t\treturn response.blob();\n\t},\n};\n\n/**\n * Fetch a single page of content for one post type. This is the unit of\n * work for the chunked import: one Worker invocation imports one page,\n * keeping each request far below Cloudflare's CPU and subrequest limits\n * (see issue #475).\n */\nexport async function fetchPluginContentPage(options: {\n\tsiteUrl: string;\n\ttoken: string;\n\tpostType: string;\n\tpage: number;\n\tperPage: number;\n\tincludeDrafts: boolean;\n}): Promise<{ items: NormalizedItem[]; totalPages: number }> {\n\tconst { siteUrl, headers } = getRequestConfig({\n\t\ttype: \"url\",\n\t\turl: options.siteUrl,\n\t\ttoken: options.token,\n\t});\n\n\tconst response = await fetchPluginApi(\n\t\tsiteUrl,\n\t\t\"content\",\n\t\t{\n\t\t\tpost_type: options.postType,\n\t\t\tstatus: options.includeDrafts ? \"any\" : \"publish\",\n\t\t\tper_page: String(options.perPage),\n\t\t\tpage: String(options.page),\n\t\t},\n\t\theaders,\n\t\t60000,\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch ${options.postType}: ${response.statusText}`);\n\t}\n\n\tconst data: PluginContentResponse = await response.json();\n\treturn {\n\t\titems: data.items.map((post) => pluginPostToNormalizedItem(post, siteUrl)),\n\t\ttotalPages: data.pages,\n\t};\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/** Plugin `inferred_type` values that are valid EmDash field types as-is */\nconst VALID_INFERRED_TYPES = new Set([\n\t\"string\",\n\t\"text\",\n\t\"number\",\n\t\"integer\",\n\t\"boolean\",\n\t\"datetime\",\n\t\"json\",\n\t\"reference\",\n]);\n\n/**\n * Map the plugin's inferred custom-field type to an EmDash field type.\n * Unknown values fall back to string (always safe for TEXT storage).\n */\nfunction mapInferredFieldType(inferredType: string): string {\n\treturn VALID_INFERRED_TYPES.has(inferredType) ? inferredType : \"string\";\n}\n\n/**\n * EmDash field types for ACF field types that hold a single value and return\n * a scalar by default. When a return format makes `get_fields()` give an\n * array, the raw meta value fills the field instead. Every other ACF type\n * (select, checkbox, relationship, repeater, gallery, ...) can return several\n * values or an object and is stored as JSON.\n */\nconst ACF_FIELD_TYPES: Record<string, string> = {\n\ttext: \"string\",\n\temail: \"string\",\n\turl: \"string\",\n\tpassword: \"string\",\n\tradio: \"string\",\n\tbutton_group: \"string\",\n\tcolor_picker: \"string\",\n\toembed: \"string\",\n\tdate_picker: \"string\",\n\tdate_time_picker: \"string\",\n\ttime_picker: \"string\",\n\ttextarea: \"text\",\n\twysiwyg: \"text\",\n\tnumber: \"number\",\n\trange: \"number\",\n\ttrue_false: \"boolean\",\n};\n\ntype AcfFieldInfo = NonNullable<PluginAnalyzeResponse[\"acf\"]>[number][\"fields\"][number];\n\n/**\n * The field type for an ACF field. A collection created by an earlier\n * import holds the type the raw meta suggested for that key; that type is\n * kept so the collection still imports, and the field's flattened row\n * keys then keep filling their own fields.\n */\nfunction acfImportFieldType(\n\tfield: AcfFieldInfo,\n\texistingType: string | undefined,\n\tmetaType: string | undefined,\n): string {\n\tconst acfType = ACF_FIELD_TYPES[field.type] ?? \"json\";\n\tif (\n\t\texistingType &&\n\t\tmetaType &&\n\t\t!isTypeCompatible(acfType, existingType) &&\n\t\tisTypeCompatible(metaType, existingType)\n\t) {\n\t\treturn existingType;\n\t}\n\treturn acfType;\n}\n\n/** ACF layout-only field types that hold no value */\nconst ACF_LAYOUT_TYPES = new Set([\"tab\", \"message\", \"accordion\"]);\n\n/** Fields of the ACF field groups whose location rules include `post_type == <postType>` */\nfunction acfFieldsForPostType(\n\tgroups: PluginAnalyzeResponse[\"acf\"],\n\tpostType: string,\n): AcfFieldInfo[] {\n\tconst fields: AcfFieldInfo[] = [];\n\tfor (const group of groups ?? []) {\n\t\tconst assigned = group.location?.some((rules) =>\n\t\t\trules.some(\n\t\t\t\t(rule) => rule.param === \"post_type\" && rule.operator === \"==\" && rule.value === postType,\n\t\t\t),\n\t\t);\n\t\tif (!assigned) continue;\n\t\tfor (const field of group.fields) {\n\t\t\tif (field.name && !ACF_LAYOUT_TYPES.has(field.type)) fields.push(field);\n\t\t}\n\t}\n\treturn fields;\n}\n\nconst ACF_ROW_SUFFIX = /^_\\d+_/;\n\n/**\n * ACF stores repeater and flexible content rows as `<name>_<row>_<sub>`\n * meta keys. Their values already arrive whole under the parent field in\n * `get_fields()`.\n */\nfunction isAcfRowMeta(key: string, acfFields: AcfFieldInfo[]): boolean {\n\treturn acfFields.some(\n\t\t(field) =>\n\t\t\t(field.type === \"repeater\" || field.type === \"flexible_content\") &&\n\t\t\tkey.startsWith(field.name) &&\n\t\t\tACF_ROW_SUFFIX.test(key.slice(field.name.length)),\n\t);\n}\n\nconst FIELD_KEY_SEPARATORS = /[_-]+/;\n\n/** Derive a human label from a meta key: \"event_start-date\" -> \"Event Start Date\" */\nfunction fieldLabelFromKey(key: string): string {\n\treturn key\n\t\t.split(FIELD_KEY_SEPARATORS)\n\t\t.filter(Boolean)\n\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t.join(\" \");\n}\n\n/**\n * Convert plugin i18n info to the shared I18nDetection type.\n * Returns undefined when no multilingual plugin is detected.\n */\nfunction pluginI18nToDetection(i18n: PluginI18nInfo | undefined): I18nDetection | undefined {\n\tif (!i18n) return undefined;\n\treturn {\n\t\tplugin: i18n.plugin,\n\t\tdefaultLocale: i18n.default_locale,\n\t\tlocales: i18n.locales,\n\t};\n}\n\n/**\n * Get request configuration from input\n */\nfunction getRequestConfig(input: SourceInput): {\n\tsiteUrl: string;\n\theaders: HeadersInit;\n} {\n\tif (input.type === \"url\") {\n\t\tconst siteUrl = normalizeUrl(input.url);\n\n\t\t// SSRF protection: validate URL before any outbound requests\n\t\tvalidateExternalUrl(siteUrl);\n\t\tconst headers: HeadersInit = {\n\t\t\tAccept: \"application/json\",\n\t\t};\n\n\t\tif (input.token) {\n\t\t\t// Token format: \"username:password\" base64 encoded\n\t\t\theaders[\"Authorization\"] = `Basic ${input.token}`;\n\t\t}\n\n\t\treturn { siteUrl, headers };\n\t}\n\n\tif (input.type === \"oauth\") {\n\t\tconst oauthSiteUrl = normalizeUrl(input.url);\n\n\t\t// SSRF protection: validate URL before any outbound requests\n\t\tvalidateExternalUrl(oauthSiteUrl);\n\n\t\treturn {\n\t\t\tsiteUrl: oauthSiteUrl,\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${input.accessToken}`,\n\t\t\t},\n\t\t};\n\t}\n\n\tthrow new Error(\"WordPress plugin source requires URL or OAuth input\");\n}\n\n/**\n * Convert plugin post to normalized item\n */\nfunction pluginPostToNormalizedItem(post: PluginPost, siteUrl: string): NormalizedItem {\n\tconst content = post.content ? gutenbergToPortableText(post.content) : [];\n\trelativizeContentLinks(content, siteUrl);\n\n\t// Extract categories and tags from taxonomies\n\tconst categories =\n\t\tpost.taxonomies?.category?.map((c) => c.slug) ??\n\t\tpost.taxonomies?.categories?.map((c) => c.slug) ??\n\t\t[];\n\tconst tags =\n\t\tpost.taxonomies?.post_tag?.map((t) => t.slug) ??\n\t\tpost.taxonomies?.tags?.map((t) => t.slug) ??\n\t\t[];\n\n\t// Everything else is a custom taxonomy assignment (genre, product_cat, ...)\n\tconst customTaxonomies: Record<string, string[]> = {};\n\tfor (const [name, terms] of Object.entries(post.taxonomies ?? {})) {\n\t\tif ([\"category\", \"categories\", \"post_tag\", \"tags\"].includes(name)) continue;\n\t\tif (Array.isArray(terms) && terms.length > 0) {\n\t\t\tcustomTaxonomies[name] = terms.map((t) => t.slug);\n\t\t}\n\t}\n\n\t// Build meta from various sources\n\tconst meta: Record<string, unknown> = { ...post.meta };\n\n\t// Include ACF fields in meta\n\tif (post.acf) {\n\t\tmeta._acf = post.acf;\n\t}\n\n\t// Include SEO data in meta\n\tif (post.yoast) {\n\t\tmeta._yoast = post.yoast;\n\t}\n\tif (post.rankmath) {\n\t\tmeta._rankmath = post.rankmath;\n\t}\n\n\treturn {\n\t\tsourceId: post.id,\n\t\tpostType: post.post_type,\n\t\tstatus: mapWpStatus(post.status),\n\t\tslug: post.slug,\n\t\ttitle: post.title,\n\t\tcontent,\n\t\texcerpt: post.excerpt || undefined,\n\t\tdate: parseWxrDate(post.date_gmt, undefined, post.date) ?? new Date(Number.NaN),\n\t\tmodified: parseWxrDate(post.modified_gmt, undefined, post.modified),\n\t\tauthor: post.author?.login,\n\t\tcategories,\n\t\ttags,\n\t\tcustomTaxonomies: Object.keys(customTaxonomies).length > 0 ? customTaxonomies : undefined,\n\t\tmeta,\n\t\tfeaturedImage: post.featured_image?.url,\n\t\tlocale: post.locale,\n\t\ttranslationGroup: post.translation_group,\n\t};\n}\n\n// =============================================================================\n// Utility Functions for External Use\n// =============================================================================\n\n/**\n * Create a Basic Auth token from username and password\n */\nexport function createBasicAuthToken(username: string, password: string): string {\n\t// Remove spaces from application password (WP formats them with spaces)\n\tconst cleanPassword = password.replace(SPACE_PATTERN, \"\");\n\treturn encodeBase64(`${username}:${cleanPassword}`);\n}\n\n/**\n * Fetch media list from plugin API\n */\nexport async function fetchPluginMedia(\n\tsiteUrl: string,\n\tauthToken: string,\n\tpage = 1,\n\tperPage = 100,\n): Promise<PluginMediaResponse> {\n\tconst normalizedSiteUrl = normalizeUrl(siteUrl);\n\n\t// SSRF protection: validate URL before any outbound requests\n\tvalidateExternalUrl(normalizedSiteUrl);\n\n\tconst response = await fetchPluginApi(\n\t\tnormalizedSiteUrl,\n\t\t\"media\",\n\t\t{ per_page: String(perPage), page: String(page) },\n\t\t{ Accept: \"application/json\", Authorization: `Basic ${authToken}` },\n\t\t30000,\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch media: ${response.statusText}`);\n\t}\n\n\treturn response.json();\n}\n\n/**\n * Fetch taxonomies from plugin API\n */\nexport async function fetchPluginTaxonomies(\n\tsiteUrl: string,\n\tauthToken: string,\n): Promise<\n\tArray<{\n\t\tname: string;\n\t\tlabel: string;\n\t\t/** Singular label (added in emdash-exporter 1.2.0) */\n\t\tlabel_singular?: string;\n\t\thierarchical: boolean;\n\t\t/** WP post types this taxonomy is registered for (added in emdash-exporter 1.2.0) */\n\t\tpost_types?: string[];\n\t\tterms: Array<{\n\t\t\tid: number;\n\t\t\tname: string;\n\t\t\tslug: string;\n\t\t\tdescription: string;\n\t\t\tparent: number | null;\n\t\t\tcount: number;\n\t\t}>;\n\t}>\n> {\n\tconst normalizedSiteUrl = normalizeUrl(siteUrl);\n\n\t// SSRF protection: validate URL before any outbound requests\n\tvalidateExternalUrl(normalizedSiteUrl);\n\n\tconst response = await fetchPluginApi(\n\t\tnormalizedSiteUrl,\n\t\t\"taxonomies\",\n\t\t{},\n\t\t{ Accept: \"application/json\", Authorization: `Basic ${authToken}` },\n\t\t30000,\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch taxonomies: ${response.statusText}`);\n\t}\n\n\treturn response.json();\n}\n\n/**\n * Fetch navigation menus from plugin API (added in emdash-exporter 1.1.0).\n * Returns an empty array when the endpoint doesn't exist (older plugin).\n */\nexport async function fetchPluginMenus(siteUrl: string, authToken: string): Promise<PluginMenu[]> {\n\tconst normalizedSiteUrl = normalizeUrl(siteUrl);\n\n\t// SSRF protection: validate URL before any outbound requests\n\tvalidateExternalUrl(normalizedSiteUrl);\n\n\tconst response = await fetchPluginApi(\n\t\tnormalizedSiteUrl,\n\t\t\"menus\",\n\t\t{},\n\t\t{ Accept: \"application/json\", Authorization: `Basic ${authToken}` },\n\t\t30000,\n\t);\n\n\tif (response.status === 404) {\n\t\treturn [];\n\t}\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch menus: ${response.statusText}`);\n\t}\n\n\treturn response.json();\n}\n\n/**\n * Fetch site options from plugin API (title, tagline, logo, favicon, ...)\n */\nexport async function fetchPluginOptions(\n\tsiteUrl: string,\n\tauthToken: string,\n): Promise<Record<string, unknown>> {\n\tconst normalizedSiteUrl = normalizeUrl(siteUrl);\n\n\t// SSRF protection: validate URL before any outbound requests\n\tvalidateExternalUrl(normalizedSiteUrl);\n\n\tconst response = await fetchPluginApi(\n\t\tnormalizedSiteUrl,\n\t\t\"options\",\n\t\t{},\n\t\t{ Accept: \"application/json\", Authorization: `Basic ${authToken}` },\n\t\t30000,\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch options: ${response.statusText}`);\n\t}\n\n\treturn response.json();\n}\n\n/** Comments response from /emdash/v1/comments */\ninterface PluginCommentsResponse {\n\titems: PluginComment[];\n\ttotal: number;\n\tpages: number;\n\tpage: number;\n\tper_page: number;\n}\n\n/**\n * Fetch a single page of comments from the plugin API (added in\n * emdash-exporter 1.2.0). The exporter orders by comment ID ascending, so\n * parents always appear before their children across pages. Returns\n * `totalPages: 0` when the endpoint doesn't exist (older plugin).\n */\nexport async function fetchPluginCommentsPage(\n\tsiteUrl: string,\n\tauthToken: string,\n\tpage: number,\n): Promise<{ items: PluginComment[]; totalPages: number }> {\n\tconst normalizedSiteUrl = normalizeUrl(siteUrl);\n\n\t// SSRF protection: validate URL before any outbound requests\n\tvalidateExternalUrl(normalizedSiteUrl);\n\n\tconst response = await fetchPluginApi(\n\t\tnormalizedSiteUrl,\n\t\t\"comments\",\n\t\t{ per_page: \"500\", page: String(page) },\n\t\t{ Accept: \"application/json\", Authorization: `Basic ${authToken}` },\n\t\t30000,\n\t);\n\n\tif (response.status === 404) {\n\t\treturn { items: [], totalPages: 0 };\n\t}\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch comments: ${response.statusText}`);\n\t}\n\n\tconst data: PluginCommentsResponse = await response.json();\n\treturn { items: data.items, totalPages: data.pages };\n}\n\n/**\n * Fetch all comments from plugin API, paginating through every page.\n * Returns an empty array when the endpoint doesn't exist (older plugin).\n */\nexport async function fetchPluginComments(\n\tsiteUrl: string,\n\tauthToken: string,\n): Promise<PluginComment[]> {\n\tconst comments: PluginComment[] = [];\n\tlet page = 1;\n\tlet totalPages = 1;\n\n\twhile (page <= totalPages) {\n\t\tconst result = await fetchPluginCommentsPage(siteUrl, authToken, page);\n\t\ttotalPages = result.totalPages;\n\t\tcomments.push(...result.items);\n\t\tpage++;\n\t}\n\n\treturn comments;\n}\n","/**\n * Import system\n *\n * Provides a pluggable system for importing content from various sources.\n */\n\n// Core types\nexport type {\n\tImportSource,\n\tImportAnalysis,\n\tImportContext,\n\tSourceInput,\n\tFileInput,\n\tUrlInput,\n\tOAuthInput,\n\tSourceProbeResult,\n\tProbeResult,\n\tSourceAuth,\n\tSourceCapabilities,\n\tSuggestedAction,\n\tPostTypeAnalysis,\n\tImportFieldDef,\n\tFieldCompatibility,\n\tCollectionSchemaStatus,\n\tAttachmentInfo,\n\tNormalizedItem,\n\tImportConfig,\n\tImportResult,\n\tFetchOptions,\n\tPostTypeMapping,\n\tNavMenuAnalysis,\n\tTaxonomyAnalysis,\n} from \"./types.js\";\n\n// Menu import\nexport {\n\timportMenusFromWxr,\n\timportMenusFromPlugin,\n\ttype MenuImportResult,\n\ttype PluginMenu,\n\ttype PluginMenuItem,\n} from \"./menus.js\";\n\n// Sections import\nexport { importReusableBlocksAsSections, type SectionsImportResult } from \"./sections.js\";\n\n// Comments import\nexport {\n\timportCommentsFromPlugin,\n\ttype PluginComment,\n\ttype CommentsImportResult,\n} from \"./comments.js\";\n\n// Site settings import\nexport {\n\timportSiteSettings,\n\tparseSiteSettingsFromPlugin,\n\ttype SiteSettingsAnalysis,\n\ttype SettingsImportResult,\n\ttype SettingsMediaIds,\n} from \"./settings.js\";\n\n// Registry\nexport {\n\tregisterSource,\n\tgetSource,\n\tgetAllSources,\n\tgetFileSources,\n\tgetUrlSources,\n\tprobeUrl,\n\tclearSources,\n\tSiteChallengeError,\n} from \"./registry.js\";\n\n// SSRF protection\nexport { validateExternalUrl, ssrfSafeFetch, SsrfError } from \"./ssrf.js\";\n\n// Sources\nexport { wxrSource, parseWxrDate } from \"./sources/wxr.js\";\nexport { wordpressRestSource } from \"./sources/wordpress-rest.js\";\nexport {\n\twordpressPluginSource,\n\tcreateBasicAuthToken,\n\tfetchPluginMedia,\n\tfetchPluginTaxonomies,\n} from \"./sources/wordpress-plugin.js\";\n\n// Auto-register built-in sources\nimport { registerSource } from \"./registry.js\";\nimport { wordpressPluginSource } from \"./sources/wordpress-plugin.js\";\nimport { wordpressRestSource } from \"./sources/wordpress-rest.js\";\nimport { wxrSource } from \"./sources/wxr.js\";\n\n// Register in priority order (most specific first)\n// Plugin source first - if they have our plugin, use it\nregisterSource(wordpressPluginSource);\nregisterSource(wordpressRestSource);\nregisterSource(wxrSource);\n"],"mappings":"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"}