dineway 0.1.45 → 0.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/dist/{activity-events-CpcTzKpF.mjs → activity-events-CNk3clTT.mjs} +1 -1
  2. package/dist/{allowed-origins-3RuuoFjC.mjs → allowed-origins-QirBXiDj.mjs} +1 -1
  3. package/dist/api/route-utils.d.mts +9 -10
  4. package/dist/api/route-utils.mjs +13 -13
  5. package/dist/api/schemas/index.d.mts +2 -2
  6. package/dist/api/schemas/index.mjs +4 -4
  7. package/dist/{api-DkFSCD74.mjs → api-ePsOhL3q.mjs} +101 -56
  8. package/dist/{api-tokens-BFg7tiOQ.mjs → api-tokens-DtvdtIkm.mjs} +1 -1
  9. package/dist/{apply-TIoQ00aH.mjs → apply-BpRBCqUt.mjs} +76 -31
  10. package/dist/astro/index.d.mts +10 -11
  11. package/dist/astro/index.mjs +23 -3
  12. package/dist/astro/middleware/auth.d.mts +9 -10
  13. package/dist/astro/middleware/auth.mjs +5 -5
  14. package/dist/astro/middleware/redirect.mjs +13 -7
  15. package/dist/astro/middleware/request-context.mjs +3 -3
  16. package/dist/astro/middleware/seed.d.mts +1 -1
  17. package/dist/astro/middleware/seed.mjs +2 -2
  18. package/dist/astro/middleware/setup.mjs +1 -1
  19. package/dist/astro/middleware.mjs +120 -82
  20. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
  21. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
  22. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
  23. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
  24. package/dist/astro/routes/api/admin/briefing.mjs +17 -17
  25. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.d.mts +7 -0
  26. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +17 -0
  27. package/dist/astro/routes/api/admin/byline-fields/_slug_.d.mts +9 -0
  28. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +38 -0
  29. package/dist/astro/routes/api/admin/byline-fields/index.d.mts +8 -0
  30. package/dist/astro/routes/api/admin/byline-fields/index.mjs +31 -0
  31. package/dist/astro/routes/api/admin/byline-fields/reorder.d.mts +7 -0
  32. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +24 -0
  33. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +27 -27
  34. package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +8 -0
  35. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +57 -0
  36. package/dist/astro/routes/api/admin/bylines/index.mjs +30 -26
  37. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +11 -11
  38. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  39. package/dist/astro/routes/api/admin/comments/bulk.mjs +9 -9
  40. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  41. package/dist/astro/routes/api/admin/comments/index.mjs +9 -9
  42. package/dist/astro/routes/api/admin/context/_id_/history.mjs +23 -23
  43. package/dist/astro/routes/api/admin/context/_id_/index.mjs +23 -23
  44. package/dist/astro/routes/api/admin/context/_id_/review.mjs +27 -27
  45. package/dist/astro/routes/api/admin/context/_id_/supersede.mjs +27 -27
  46. package/dist/astro/routes/api/admin/context/diff.mjs +26 -26
  47. package/dist/astro/routes/api/admin/context/index.mjs +27 -27
  48. package/dist/astro/routes/api/admin/context/stale.mjs +26 -26
  49. package/dist/astro/routes/api/admin/hitl-requests/_id_/index.mjs +23 -23
  50. package/dist/astro/routes/api/admin/hitl-requests/_id_/resolve.mjs +26 -26
  51. package/dist/astro/routes/api/admin/hitl-requests/index.mjs +26 -26
  52. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +24 -24
  53. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +2 -2
  54. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
  55. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
  56. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +48 -44
  57. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +48 -44
  58. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +42 -38
  59. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +47 -43
  60. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +47 -43
  61. package/dist/astro/routes/api/admin/plugins/index.mjs +42 -38
  62. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
  63. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +42 -38
  64. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +47 -43
  65. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +42 -38
  66. package/dist/astro/routes/api/admin/plugins/updates.mjs +42 -38
  67. package/dist/astro/routes/api/admin/review-requests/_id_/index.mjs +5 -5
  68. package/dist/astro/routes/api/admin/review-requests/_id_/resolve.mjs +26 -26
  69. package/dist/astro/routes/api/admin/review-requests/index.mjs +9 -9
  70. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +42 -38
  71. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
  72. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +42 -38
  73. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +1 -1
  74. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
  75. package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
  76. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
  77. package/dist/astro/routes/api/admin/users/index.mjs +5 -5
  78. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
  79. package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
  80. package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
  81. package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
  82. package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
  83. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  84. package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
  85. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  86. package/dist/astro/routes/api/auth/me.mjs +20 -11
  87. package/dist/astro/routes/api/auth/mode.mjs +1 -1
  88. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +2 -2
  89. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  90. package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
  91. package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
  92. package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
  93. package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
  94. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
  95. package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
  96. package/dist/astro/routes/api/auth/setup-token/index.mjs +5 -5
  97. package/dist/astro/routes/api/auth/setup-token/verify.mjs +2 -2
  98. package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
  99. package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
  100. package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
  101. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
  102. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
  103. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -5
  104. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
  105. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
  106. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +11 -11
  107. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +9 -9
  108. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
  109. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
  110. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +9 -9
  111. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +20 -14
  112. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
  113. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -5
  114. package/dist/astro/routes/api/content/_collection_/_id_.mjs +12 -10
  115. package/dist/astro/routes/api/content/_collection_/index.mjs +9 -9
  116. package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
  117. package/dist/astro/routes/api/dashboard.mjs +8 -8
  118. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  119. package/dist/astro/routes/api/health.mjs +1 -1
  120. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  121. package/dist/astro/routes/api/import/probe.mjs +10 -10
  122. package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -7
  123. package/dist/astro/routes/api/import/wordpress/execute.mjs +29 -28
  124. package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
  125. package/dist/astro/routes/api/import/wordpress/prepare.mjs +31 -31
  126. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +5 -1
  127. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +16 -1
  128. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +30 -30
  129. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  130. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +13 -13
  131. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  132. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +31 -30
  133. package/dist/astro/routes/api/manifest.mjs +4 -4
  134. package/dist/astro/routes/api/mcp.mjs +75 -50
  135. package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -8
  136. package/dist/astro/routes/api/media/_id_.mjs +6 -6
  137. package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
  138. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
  139. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
  140. package/dist/astro/routes/api/media/providers/index.mjs +2 -2
  141. package/dist/astro/routes/api/media/upload-url.mjs +10 -10
  142. package/dist/astro/routes/api/media.mjs +14 -13
  143. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +27 -27
  144. package/dist/astro/routes/api/menus/_name_/items.mjs +27 -27
  145. package/dist/astro/routes/api/menus/_name_/reorder.mjs +27 -27
  146. package/dist/astro/routes/api/menus/_name_/translations.mjs +27 -27
  147. package/dist/astro/routes/api/menus/_name_.mjs +27 -27
  148. package/dist/astro/routes/api/menus/index.mjs +27 -27
  149. package/dist/astro/routes/api/oauth/authorize.mjs +7 -7
  150. package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
  151. package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
  152. package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
  153. package/dist/astro/routes/api/oauth/register.mjs +4 -4
  154. package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
  155. package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
  156. package/dist/astro/routes/api/oauth/token.mjs +6 -6
  157. package/dist/astro/routes/api/openapi.json.mjs +10 -7
  158. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
  159. package/dist/astro/routes/api/redirects/404s/index.mjs +10 -10
  160. package/dist/astro/routes/api/redirects/404s/summary.mjs +10 -10
  161. package/dist/astro/routes/api/redirects/_id_.mjs +28 -28
  162. package/dist/astro/routes/api/redirects/index.mjs +28 -28
  163. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
  164. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
  165. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -39
  166. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -39
  167. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +43 -39
  168. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -39
  169. package/dist/astro/routes/api/schema/collections/index.mjs +43 -39
  170. package/dist/astro/routes/api/schema/index.mjs +7 -7
  171. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +42 -38
  172. package/dist/astro/routes/api/schema/orphans/index.mjs +42 -38
  173. package/dist/astro/routes/api/search/enable.mjs +11 -11
  174. package/dist/astro/routes/api/search/index.mjs +10 -10
  175. package/dist/astro/routes/api/search/rebuild.mjs +11 -11
  176. package/dist/astro/routes/api/search/stats.mjs +7 -7
  177. package/dist/astro/routes/api/search/suggest.mjs +10 -10
  178. package/dist/astro/routes/api/sections/_slug_.mjs +27 -27
  179. package/dist/astro/routes/api/sections/index.mjs +27 -27
  180. package/dist/astro/routes/api/settings/email.mjs +3 -3
  181. package/dist/astro/routes/api/settings.mjs +27 -27
  182. package/dist/astro/routes/api/setup/admin-verify.mjs +11 -11
  183. package/dist/astro/routes/api/setup/admin.mjs +9 -9
  184. package/dist/astro/routes/api/setup/dev-bypass.mjs +24 -23
  185. package/dist/astro/routes/api/setup/dev-reset.mjs +1 -1
  186. package/dist/astro/routes/api/setup/index.mjs +25 -24
  187. package/dist/astro/routes/api/setup/status.mjs +3 -3
  188. package/dist/astro/routes/api/snapshot.mjs +7 -6
  189. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +30 -29
  190. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +30 -29
  191. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +30 -29
  192. package/dist/astro/routes/api/taxonomies/index.mjs +30 -29
  193. package/dist/astro/routes/api/themes/preview.mjs +4 -4
  194. package/dist/astro/routes/api/typegen.mjs +4 -4
  195. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  196. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +3 -3
  197. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +3 -3
  198. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +26 -26
  199. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +27 -27
  200. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +27 -27
  201. package/dist/astro/routes/api/widget-areas/_name_.mjs +25 -25
  202. package/dist/astro/routes/api/widget-areas/index.mjs +27 -27
  203. package/dist/astro/routes/api/widget-components.mjs +2 -2
  204. package/dist/astro/routes/robots.txt.mjs +7 -7
  205. package/dist/astro/routes/sitemap-_collection_.xml.mjs +59 -15
  206. package/dist/astro/routes/sitemap.xml.mjs +8 -8
  207. package/dist/astro/session-driver.d.mts +1 -1
  208. package/dist/astro/session-driver.mjs +3 -3
  209. package/dist/astro/types.d.mts +16 -14
  210. package/dist/{audit-NgiRzqP9.mjs → audit-DuRbTm8L.mjs} +1 -1
  211. package/dist/auth/providers/github.d.mts +1 -1
  212. package/dist/auth/providers/google.d.mts +1 -1
  213. package/dist/{auth-control-guard-1FHtkDP6.mjs → auth-control-guard-Dr14I98m.mjs} +1 -1
  214. package/dist/{authorize-BbIhZi3a.mjs → authorize-BLO0m7fW.mjs} +1 -1
  215. package/dist/{briefing-Jsxs587i.mjs → briefing-BFEWeJtR.mjs} +6 -6
  216. package/dist/{briefing-DD82WaEy.mjs → briefing-C4fJSVYW.mjs} +1 -1
  217. package/dist/byline-CXQcMsBu.mjs +628 -0
  218. package/dist/{bylines-BU6b8jSi.d.mts → byline-fields-Cuo-JI3B.d.mts} +150 -19
  219. package/dist/{import-Br7aP9yh.mjs → byline-fields-D7TJ_oHF.mjs} +57 -3
  220. package/dist/byline-fields-Dc7L6Yry.mjs +113 -0
  221. package/dist/byline-registry-CL8BxPPp.mjs +287 -0
  222. package/dist/bylines-BgriNlW7.mjs +165 -0
  223. package/dist/bylines-D2vqm1aZ.mjs +163 -0
  224. package/dist/{cache-DQyZ-QaB.mjs → cache-GRK71jOU.mjs} +2 -2
  225. package/dist/{chunks-D8KL0nCY.mjs → chunks-DgEw12Bc.mjs} +1 -1
  226. package/dist/cli/index.mjs +993 -90
  227. package/dist/client/external-auth-headers.d.mts +1 -1
  228. package/dist/client/index.d.mts +2 -1
  229. package/dist/client/index.mjs +5 -2
  230. package/dist/{comment-BmJXz3lc.mjs → comment-ogMaF1gk.mjs} +1 -1
  231. package/dist/{comments-yTbeIYc2.mjs → comments-CTSOKrZq.mjs} +1 -1
  232. package/dist/{connection-BCNICDWN.mjs → connection-CiJWiWya.mjs} +44 -13
  233. package/dist/{content-DvpMad_N.mjs → content-BfyjOiMi.mjs} +24 -4
  234. package/dist/content-index-names-Bbu1FY1r.mjs +26 -0
  235. package/dist/{context-DgqEfcWz.mjs → context-CdsYb1m8.mjs} +2 -2
  236. package/dist/{context-Ufrm1lOv.mjs → context-ZMHhwzkG.mjs} +8 -8
  237. package/dist/{context-route-helpers-Dq5U_AXp.mjs → context-route-helpers-YLWx2N1j.mjs} +1 -1
  238. package/dist/{dashboard-BC9bgPOH.mjs → dashboard-D0gWuzNp.mjs} +4 -4
  239. package/dist/db/index.d.mts +3 -3
  240. package/dist/db/index.mjs +2 -2
  241. package/dist/db/libsql.d.mts +1 -1
  242. package/dist/db/libsql.mjs +1 -1
  243. package/dist/db/postgres.d.mts +1 -1
  244. package/dist/db/sqlite.d.mts +1 -1
  245. package/dist/db/sqlite.mjs +1 -1
  246. package/dist/{device-flow-CTS91g4A.mjs → device-flow-B3_FEoMI.mjs} +4 -4
  247. package/dist/{dialect-helpers-TkdbkFad.mjs → dialect-helpers-fk43GbDb.mjs} +13 -3
  248. package/dist/{fts-manager-DnfOsF4s.mjs → fts-manager-EHY2Kes9.mjs} +2 -2
  249. package/dist/{hitl-requests-DaRuZ7tb.mjs → hitl-requests-B1Zqgut6.mjs} +2 -2
  250. package/dist/{hitl-route-helpers-DcPySbZ3.mjs → hitl-route-helpers-CjpWUMuw.mjs} +4 -4
  251. package/dist/{import-DSXK3aQF.mjs → import-CvHY6sf5.mjs} +3 -3
  252. package/dist/{index-BwOO3vu2.d.mts → index-DJVaYiUV.d.mts} +2 -2
  253. package/dist/index.d.mts +16 -17
  254. package/dist/index.mjs +69 -65
  255. package/dist/{jsonld-CLbYsYYH.d.mts → jsonld-AcPnCEGD.d.mts} +2 -2
  256. package/dist/{load-BCCcmoW9.mjs → load-BdbvtoDb.mjs} +1 -1
  257. package/dist/{loader-p2imNN98.mjs → loader-Y0QvC_QO.mjs} +167 -61
  258. package/dist/media/index.d.mts +1 -2
  259. package/dist/media/index.mjs +2 -2
  260. package/dist/media/local-runtime.d.mts +11 -12
  261. package/dist/media/local-runtime.mjs +2 -2
  262. package/dist/{media-Cg4zc9fq.mjs → media-DhBwiCYR.mjs} +6 -1
  263. package/dist/{media-allowlist-D8gsm8_t.mjs → media-allowlist-BsXkT9RK.mjs} +1 -1
  264. package/dist/{menus-DOaL6NaF.mjs → menus-BzGQpw9d.mjs} +2 -2
  265. package/dist/{menus-DzG3-9tQ.mjs → menus-fqqzXyHd.mjs} +5 -5
  266. package/dist/{oauth-authorization-DyOFXQWq.mjs → oauth-authorization-DsF81vki.mjs} +4 -4
  267. package/dist/{oauth-clients-BMs_bmoz.mjs → oauth-clients-Du-V0fEm.mjs} +2 -2
  268. package/dist/page/index.d.mts +2 -2
  269. package/dist/page/index.mjs +1 -1
  270. package/dist/{parse-D7Tu6ku4.mjs → parse-CneSgl7-.mjs} +1 -1
  271. package/dist/{types-cn-fvYQ1.d.mts → placeholder-CXfoCtCd.d.mts} +38 -1
  272. package/dist/plugin-utils.d.mts +22 -10
  273. package/dist/plugin-utils.mjs +8 -10
  274. package/dist/plugins/adapt-sandbox-entry.d.mts +9 -10
  275. package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
  276. package/dist/{plugins-DCDVDF4B.mjs → plugins-BQ5Joz6v.mjs} +36 -6
  277. package/dist/{preview-BhgxNRWI.mjs → preview-D5rvDhRt.mjs} +7 -7
  278. package/dist/{provider-loader-B19YyyBp.d.mts → provider-loader-B5PMjpN7.d.mts} +1 -1
  279. package/dist/{query-BnRpB09I.mjs → query-BJuUydtD.mjs} +3 -3
  280. package/dist/{query-DHvNhBhi.mjs → query-CSx0EdSW.mjs} +30 -18
  281. package/dist/{rate-limit-BWP_kKiZ.mjs → rate-limit-i0G3IAOX.mjs} +2 -2
  282. package/dist/{redirect-BaVvo2te.mjs → redirect-BqFMj67n.mjs} +20 -6
  283. package/dist/{redirects-Ba-lJA5j.mjs → redirects-CJwHl_YG.mjs} +3 -3
  284. package/dist/{redirects-x5ol_Qj9.mjs → redirects-q_cToaHv.mjs} +29 -8
  285. package/dist/{registry-i__XP2WV.mjs → registry-Cq3QRBW2.mjs} +14 -5
  286. package/dist/{request-cache-BpwuE2ix.mjs → request-cache-w5cj5itT.mjs} +9 -1
  287. package/dist/{request-meta-DUGfAeXy.mjs → request-meta-DAb6xaP9.mjs} +1 -1
  288. package/dist/resolve-DTuDyYKs.mjs +100 -0
  289. package/dist/{review-requests-DuIxM4YM.mjs → review-requests-GYqjl2jO.mjs} +1 -1
  290. package/dist/{review-requests-CTUU_RJm.mjs → review-requests-tPw8_pAO.mjs} +1 -1
  291. package/dist/{runner-FhUNNaqA.d.mts → runner-Cnz4dl0f.d.mts} +1 -1
  292. package/dist/{runner-DF2DgD_B.mjs → runner-DTfG5v0G.mjs} +574 -196
  293. package/dist/{runtime-1bE80cmL.d.mts → runtime-Cd-kjPfN.d.mts} +1155 -273
  294. package/dist/runtime.d.mts +10 -11
  295. package/dist/runtime.mjs +4 -4
  296. package/dist/schema-DmHMWnSA.mjs +8 -0
  297. package/dist/{search-Cl9preJT.mjs → search-BAiFLz81.mjs} +3 -3
  298. package/dist/{sections-Zx-2q9IH.mjs → sections-DsuIrFDC.mjs} +2 -2
  299. package/dist/seed/index.d.mts +2 -2
  300. package/dist/seed/index.mjs +18 -17
  301. package/dist/seo/index.d.mts +1 -1
  302. package/dist/seo/index.mjs +1 -0
  303. package/dist/{seo-CJBiMDkj.mjs → seo-5lJOtB5J.mjs} +4 -2
  304. package/dist/{seo-BPb_reaG.mjs → seo-uMFBaR8G.mjs} +1 -1
  305. package/dist/{service-wPGgmbUa.mjs → service-CifrxCru.mjs} +2 -2
  306. package/dist/{settings-nr15a8uv.mjs → settings-BYGdocdj.mjs} +2 -2
  307. package/dist/{settings-DORe02PC.mjs → settings-DNRQuX3d.mjs} +3 -3
  308. package/dist/{site-activity-KFZprBZM.mjs → site-activity-6x1JccoR.mjs} +1 -1
  309. package/dist/{site-context-DuBQk6Mp.mjs → site-context-c1ZFa_OF.mjs} +13 -13
  310. package/dist/storage/local.d.mts +1 -1
  311. package/dist/storage/local.mjs +1 -1
  312. package/dist/storage/s3.d.mts +1 -1
  313. package/dist/storage/s3.mjs +1 -1
  314. package/dist/{taxonomies-DGaw_-aU.mjs → taxonomies-CQFmkP5u.mjs} +3 -3
  315. package/dist/{taxonomies-BVBKoXRf.mjs → taxonomies-faQVeMgj.mjs} +7 -32
  316. package/dist/{taxonomy-BvXRL85P.mjs → taxonomy-BnH-6VsX.mjs} +2 -2
  317. package/dist/{types-DvwHUku7.d.mts → types-B7_vSiPD.d.mts} +16 -0
  318. package/dist/{types-D1DjBFA9.mjs → types-Ck7-WoUD.mjs} +1 -1
  319. package/dist/{types-t7_nCCA9.d.mts → types-DEAQG87T.d.mts} +2 -56
  320. package/dist/{types-C-CMfzSl.d.mts → types-DYKtk8f1.d.mts} +31 -0
  321. package/dist/{types-C3Em8xpG.mjs → types-DbZhHtqS.mjs} +23 -1
  322. package/dist/{types-BIM7jwxr.d.mts → types-UGmU5sWx.d.mts} +1 -1
  323. package/dist/types-nP9vGUFq.d.mts +56 -0
  324. package/dist/ui/server-runtime.d.mts +13 -7
  325. package/dist/ui/server-runtime.mjs +18 -17
  326. package/dist/{user-2aI21yV1.mjs → user-CqZwN21P.mjs} +1 -1
  327. package/dist/{validate-CvQ6cvHH.d.mts → validate-BJuG-ISL.d.mts} +21 -3
  328. package/dist/{validate-JE-WfUQ5.mjs → validate-CK4a1sIF.mjs} +22 -2
  329. package/dist/version-Cb1tZ6s_.mjs +6 -0
  330. package/dist/{widgets-Cj6ULpED.mjs → widgets-CdDvF4fV.mjs} +2 -2
  331. package/dist/{wordpress-slugs-hqItqJrQ.mjs → wordpress-slugs-B6Gw9q3Q.mjs} +1 -1
  332. package/dist/{zod-generator-C4BgFBZV.mjs → zod-generator-D1ROBNuC.mjs} +2 -2
  333. package/package.json +7 -8
  334. package/src/components/InlinePortableTextEditor.tsx +66 -0
  335. package/src/components/code-block-languages.ts +76 -0
  336. package/src/components/inline-code-block.tsx +241 -0
  337. package/dist/byline-DpNNSjET.mjs +0 -219
  338. package/dist/bylines-75_STR73.mjs +0 -114
  339. package/dist/chunk-ClPoSABd.mjs +0 -21
  340. package/dist/db-errors-DHJCB_gY.mjs +0 -23
  341. package/dist/index-Ct0pjZwW.d.mts +0 -835
  342. package/dist/placeholder-BZpCpid_.d.mts +0 -40
  343. package/dist/schema-U-SeFWwn.mjs +0 -8
  344. package/dist/version-DTpFm69w.mjs +0 -6
  345. /package/dist/{adapters-kZjS7plb.d.mts → adapters-OQCImOL7.d.mts} +0 -0
  346. /package/dist/{api-tokens-L0o9Bd7v.mjs → api-tokens-CYUoFGo7.mjs} +0 -0
  347. /package/dist/{challenge-store-cJam-E5R.mjs → challenge-store-DFxX0_15.mjs} +0 -0
  348. /package/dist/{components-BJfa-F6n.mjs → components--pg6zBvu.mjs} +0 -0
  349. /package/dist/{config-XW5tMrH8.mjs → config-CVssduLe.mjs} +0 -0
  350. /package/dist/{context-types-BrSQNye5.mjs → context-types-DQh_XKkn.mjs} +0 -0
  351. /package/dist/{cron-D7FDsRu-.mjs → cron-DxCAU_Sn.mjs} +0 -0
  352. /package/dist/{default-5A3XVR7L.mjs → default-BHauvIdG.mjs} +0 -0
  353. /package/dist/{email-console-Bs1qKx59.mjs → email-console-BOVqIYpB.mjs} +0 -0
  354. /package/dist/{error-DLkgOP5m.mjs → error-DCSuUAZW.mjs} +0 -0
  355. /package/dist/{escape-r8_GbEU2.mjs → escape-BDgouFFY.mjs} +0 -0
  356. /package/dist/{experimental-workflows-BbZbIEZp.mjs → experimental-workflows-CSMffP6q.mjs} +0 -0
  357. /package/dist/{hash-DFFrkivP.mjs → hash-BPmX6P8I.mjs} +0 -0
  358. /package/dist/{manifest-schema-C6fzQoWn.mjs → manifest-schema-qh2P7RDX.mjs} +0 -0
  359. /package/dist/{mime-DYP4V5Ks.mjs → mime-8pAB8-77.mjs} +0 -0
  360. /package/dist/{mode-Bd55iLcP.mjs → mode-CZqCF9dZ.mjs} +0 -0
  361. /package/dist/{normalize-BY_EJnd9.mjs → normalize-O-hi3a27.mjs} +0 -0
  362. /package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-qncPB_IU.mjs} +0 -0
  363. /package/dist/{oauth-user-lookup-DdcI8ZVL.mjs → oauth-user-lookup-BFjWF8wK.mjs} +0 -0
  364. /package/dist/{parser-egIGEco-.mjs → parser-DxfsARXL.mjs} +0 -0
  365. /package/dist/{passkey-config-AX4sjpQ4.mjs → passkey-config-DzHQK90v.mjs} +0 -0
  366. /package/dist/{patterns-CiyXeDgr.mjs → patterns-D9iDO3j8.mjs} +0 -0
  367. /package/dist/{placeholder-b0Ufu0La.mjs → placeholder-BDo81Is5.mjs} +0 -0
  368. /package/dist/{provider-loader-BdRV01gr.mjs → provider-loader-DzUxejk7.mjs} +0 -0
  369. /package/dist/{public-url-BL2r8dmQ.mjs → public-url-DLUM5OOv.mjs} +0 -0
  370. /package/dist/{redirect-Ce_6Yb6z.mjs → redirect-BjIBtDWY.mjs} +0 -0
  371. /package/dist/{secrets-DfeNNoLa.mjs → secrets-CPoFLJjm.mjs} +0 -0
  372. /package/dist/{seo-contributions-C0LXoWw3.mjs → seo-contributions-CqVvReEj.mjs} +0 -0
  373. /package/dist/{setup-complete-C2ztsNhJ.mjs → setup-complete-4EiBS1E5.mjs} +0 -0
  374. /package/dist/{setup-nonce-BTKq7uBi.mjs → setup-nonce-pyGfc9hV.mjs} +0 -0
  375. /package/dist/{sidecar-client-lrf7ErYJ.mjs → sidecar-client-mJxwayYN.mjs} +0 -0
  376. /package/dist/{site-url-C18yBhtv.mjs → site-url-C-cu8Ff2.mjs} +0 -0
  377. /package/dist/{ssrf-KAIQS48_.mjs → ssrf-DiKqWd3N.mjs} +0 -0
  378. /package/dist/{tokens-CsP8Se8S.mjs → tokens-CjSgb0AC.mjs} +0 -0
  379. /package/dist/{transport-nNEGdHkI.d.mts → transport-DidKKxvW.d.mts} +0 -0
  380. /package/dist/{transport-B7kO-4ee.mjs → transport-LSdZVXHF.mjs} +0 -0
  381. /package/dist/{trusted-proxy-Bbm6PLR6.mjs → trusted-proxy-BgIIcbsN.mjs} +0 -0
  382. /package/dist/{types-CNNQ8l0v.mjs → types-Cg276-3z.mjs} +0 -0
  383. /package/dist/{types-BYjPylrZ.d.mts → types-DZpT-PnG.d.mts} +0 -0
  384. /package/dist/{types-BgE6gMFI.d.mts → types-Dryvv7LH.d.mts} +0 -0
  385. /package/dist/{types-BBETcziA.d.mts → types-GaCtZ1k9.d.mts} +0 -0
  386. /package/dist/{url-BzhfYtRn.mjs → url-w7Mp5qAD.mjs} +0 -0
  387. /package/dist/{utils-FEbQMgB5.mjs → utils-wv-zvC-Y.mjs} +0 -0
@@ -1,37 +1,41 @@
1
1
  #!/usr/bin/env node
2
- import { t as __exportAll } from "../chunk-ClPoSABd.mjs";
3
- import { n as createDatabase } from "../connection-BCNICDWN.mjs";
4
- import { c as listTablesLike } from "../dialect-helpers-TkdbkFad.mjs";
5
- import { i as runMigrations, n as getMigrationStatus, t as getMigrationFingerprint } from "../runner-DF2DgD_B.mjs";
6
- import { r as isI18nEnabled } from "../config-XW5tMrH8.mjs";
2
+ import { a as __exportAll, i as runMigrations, n as getMigrationStatus, t as getMigrationFingerprint } from "../runner-DTfG5v0G.mjs";
3
+ import { t as createDatabase } from "../connection-CiJWiWya.mjs";
4
+ import { t as validateIdentifier } from "../validate-VPnKoIzW.mjs";
5
+ import { l as listTablesLike } from "../dialect-helpers-fk43GbDb.mjs";
6
+ import { r as isI18nEnabled } from "../config-CVssduLe.mjs";
7
7
  import { n as slugify } from "../slugify-BzGxlOFx.mjs";
8
- import { t as ContentRepository } from "../content-DvpMad_N.mjs";
8
+ import { t as ContentRepository } from "../content-BfyjOiMi.mjs";
9
9
  import { i as encodeBase64url } from "../base64-C1Q9yr0B.mjs";
10
- import "../types-D1DjBFA9.mjs";
11
- import { t as MediaRepository } from "../media-Cg4zc9fq.mjs";
12
- import { t as TaxonomyRepository } from "../taxonomy-BvXRL85P.mjs";
10
+ import "../types-Ck7-WoUD.mjs";
11
+ import { t as MediaRepository } from "../media-DhBwiCYR.mjs";
12
+ import { t as TaxonomyRepository } from "../taxonomy-BnH-6VsX.mjs";
13
13
  import { t as OptionsRepository } from "../options-BF11H_FD.mjs";
14
- import "../redirect-BaVvo2te.mjs";
15
- import "../byline-DpNNSjET.mjs";
16
- import "../request-cache-BpwuE2ix.mjs";
17
- import "../fts-manager-DnfOsF4s.mjs";
18
- import { n as SchemaRegistry } from "../registry-i__XP2WV.mjs";
19
- import "../loader-p2imNN98.mjs";
20
- import "../settings-DORe02PC.mjs";
21
- import { i as pluginManifestSchema } from "../manifest-schema-C6fzQoWn.mjs";
22
- import "../ssrf-KAIQS48_.mjs";
23
- import { t as validateSeed } from "../validate-JE-WfUQ5.mjs";
24
- import { t as applySeed } from "../apply-TIoQ00aH.mjs";
25
- import { n as fingerprintKey, r as generateEncryptionKey, t as DinewaySecretsError } from "../secrets-DfeNNoLa.mjs";
14
+ import "../redirect-BqFMj67n.mjs";
15
+ import "../request-cache-w5cj5itT.mjs";
16
+ import "../byline-registry-CL8BxPPp.mjs";
17
+ import { t as BylineRepository } from "../byline-CXQcMsBu.mjs";
18
+ import "../fts-manager-EHY2Kes9.mjs";
19
+ import { n as SchemaRegistry } from "../registry-Cq3QRBW2.mjs";
20
+ import { a as isMissingTableError } from "../loader-Y0QvC_QO.mjs";
21
+ import "../settings-DNRQuX3d.mjs";
22
+ import { n as VERSION } from "../version-Cb1tZ6s_.mjs";
23
+ import { i as pluginManifestSchema } from "../manifest-schema-qh2P7RDX.mjs";
24
+ import "../ssrf-DiKqWd3N.mjs";
25
+ import { t as validateSeed } from "../validate-CK4a1sIF.mjs";
26
+ import { t as applySeed } from "../apply-BpRBCqUt.mjs";
27
+ import { n as fingerprintKey, r as generateEncryptionKey, t as DinewaySecretsError } from "../secrets-CPoFLJjm.mjs";
26
28
  import { createHeaderAwareFetch, customHeadersInterceptor, isRedirectResponse, resolveCustomHeaders } from "../client/external-auth-headers.mjs";
27
- import { o as convertDataForRead } from "../transport-B7kO-4ee.mjs";
29
+ import { o as convertDataForRead } from "../transport-LSdZVXHF.mjs";
28
30
  import { DinewayClient } from "../client/index.mjs";
29
31
  import { LocalStorage } from "../storage/local.mjs";
30
32
  import { createHash } from "node:crypto";
33
+ import { sql } from "kysely";
31
34
  import { imageSize } from "image-size";
32
35
  import { createGzipDecoder, unpackTar } from "modern-tar";
33
36
  import { createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
34
37
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
38
+ import { pathToFileURL } from "node:url";
35
39
  import { defineCommand, runCommand, runMain } from "citty";
36
40
  import consola, { consola as consola$1 } from "consola";
37
41
  import pc from "picocolors";
@@ -718,6 +722,10 @@ const updateCommand = defineCommand({
718
722
  description: "Revision token from get (prevents overwriting unseen changes)",
719
723
  required: true
720
724
  },
725
+ locale: {
726
+ type: "string",
727
+ description: "Locale for slug resolution"
728
+ },
721
729
  draft: {
722
730
  type: "boolean",
723
731
  description: "Keep as draft instead of auto-publishing"
@@ -731,10 +739,11 @@ const updateCommand = defineCommand({
731
739
  const client = createClientFromArgs(args);
732
740
  const updated = await client.update(args.collection, args.id, {
733
741
  data,
734
- _rev: args.rev
742
+ _rev: args.rev,
743
+ locale: args.locale
735
744
  });
736
- if (!args.draft && updated.draftRevisionId) await client.publish(args.collection, args.id);
737
- output(await client.get(args.collection, args.id), args);
745
+ if (!args.draft && updated.draftRevisionId) await client.publish(args.collection, updated.id);
746
+ output(await client.get(args.collection, updated.id), args);
738
747
  } catch (error) {
739
748
  consola$1.error(error instanceof Error ? error.message : "Unknown error");
740
749
  process.exit(1);
@@ -1631,13 +1640,33 @@ async function writeForgewayDeployMetadata(cwd, metadata) {
1631
1640
  //#endregion
1632
1641
  //#region src/cli/commands/deploy/utils/forgeway-secrets.ts
1633
1642
  const DINEWAY_CONFIG_DIR_NAME = ".dineway";
1634
- const TRAILING_SLASH_PATTERN$1 = /\/$/;
1643
+ const DINEWAY_USER_CONFIG_DIR_NAME = "dineway";
1644
+ const TRAILING_SLASH_PATTERN$2 = /\/$/;
1635
1645
  function getDinewayConfigDir(cwd = process.cwd()) {
1636
1646
  return join(cwd, DINEWAY_CONFIG_DIR_NAME);
1637
1647
  }
1648
+ function getDinewayUserConfigDir() {
1649
+ return join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), DINEWAY_USER_CONFIG_DIR_NAME);
1650
+ }
1638
1651
  function getForgewaySecretPath(cwd = process.cwd()) {
1639
1652
  return join(getDinewayConfigDir(cwd), "forgeway.json");
1640
1653
  }
1654
+ function getForgewayAccountSecretPath() {
1655
+ return join(getDinewayUserConfigDir(), "forgeway.json");
1656
+ }
1657
+ function normalizePlatformApiUrl$1(platformApiUrl) {
1658
+ return platformApiUrl.replace(TRAILING_SLASH_PATTERN$2, "");
1659
+ }
1660
+ function normalizeEmail$2(email) {
1661
+ return email.trim().toLowerCase();
1662
+ }
1663
+ function accountKey(platformApiUrl, email) {
1664
+ return `${normalizePlatformApiUrl$1(platformApiUrl)}#${normalizeEmail$2(email)}`;
1665
+ }
1666
+ function normalizeLookup(lookup) {
1667
+ if (typeof lookup === "string") return { cwd: lookup };
1668
+ return lookup ?? {};
1669
+ }
1641
1670
  async function readStore(cwd = process.cwd()) {
1642
1671
  try {
1643
1672
  const raw = await readFile(getForgewaySecretPath(cwd), "utf-8");
@@ -1658,16 +1687,66 @@ async function writeStore(store, cwd = process.cwd()) {
1658
1687
  });
1659
1688
  await chmod(file, 384);
1660
1689
  }
1661
- async function readForgewayCredentials(cwd) {
1662
- return (await readStore(cwd)).credentials ?? null;
1690
+ async function readAccountStore() {
1691
+ try {
1692
+ const raw = await readFile(getForgewayAccountSecretPath(), "utf-8");
1693
+ return JSON.parse(raw);
1694
+ } catch {
1695
+ return { version: 1 };
1696
+ }
1663
1697
  }
1664
- async function writeForgewayCredentials(credentials, cwd) {
1665
- const store = await readStore(cwd);
1666
- store.credentials = credentials;
1667
- await writeStore(store, cwd);
1698
+ async function writeAccountStore(store) {
1699
+ await mkdir(getDinewayUserConfigDir(), {
1700
+ recursive: true,
1701
+ mode: 448
1702
+ });
1703
+ const file = getForgewayAccountSecretPath();
1704
+ await writeFile(file, JSON.stringify({
1705
+ ...store,
1706
+ version: 1
1707
+ }, null, " ") + "\n", {
1708
+ encoding: "utf-8",
1709
+ mode: 384
1710
+ });
1711
+ await chmod(file, 384);
1712
+ }
1713
+ function accountMatches(credentials, lookup) {
1714
+ if (lookup.platformApiUrl && normalizePlatformApiUrl$1(credentials.platformApiUrl) !== normalizePlatformApiUrl$1(lookup.platformApiUrl)) return false;
1715
+ if (lookup.email && normalizeEmail$2(credentials.user?.email ?? "") !== normalizeEmail$2(lookup.email)) return false;
1716
+ return true;
1717
+ }
1718
+ async function readForgewayCredentials(lookup) {
1719
+ const normalizedLookup = normalizeLookup(lookup);
1720
+ const store = await readAccountStore();
1721
+ const accounts = Object.values(store.accounts ?? {}).filter((credentials) => accountMatches(credentials, normalizedLookup));
1722
+ if (normalizedLookup.platformApiUrl && normalizedLookup.email) return store.accounts?.[accountKey(normalizedLookup.platformApiUrl, normalizedLookup.email)] ?? null;
1723
+ if (accounts.length === 1) return accounts[0] ?? null;
1724
+ return null;
1725
+ }
1726
+ async function writeForgewayCredentials(credentials, lookup) {
1727
+ const normalizedLookup = normalizeLookup(lookup);
1728
+ const platformApiUrl = normalizePlatformApiUrl$1(normalizedLookup.platformApiUrl ?? credentials.platformApiUrl);
1729
+ const email = normalizeEmail$2(normalizedLookup.email ?? credentials.user?.email ?? "");
1730
+ if (!email) throw new Error("Forgeway credentials require a user email before they can be stored.");
1731
+ const key = accountKey(platformApiUrl, email);
1732
+ const store = await readAccountStore();
1733
+ store.accounts = {
1734
+ ...store.accounts,
1735
+ [key]: {
1736
+ ...credentials,
1737
+ platformApiUrl
1738
+ }
1739
+ };
1740
+ store.lastAccountKey = key;
1741
+ await writeAccountStore(store);
1742
+ }
1743
+ async function listForgewayCredentials(platformApiUrl) {
1744
+ const lookup = platformApiUrl ? { platformApiUrl } : {};
1745
+ const store = await readAccountStore();
1746
+ return Object.values(store.accounts ?? {}).filter((credentials) => accountMatches(credentials, lookup));
1668
1747
  }
1669
1748
  function shadowGrantKey(platformApiUrl, placeId) {
1670
- return `${platformApiUrl.replace(TRAILING_SLASH_PATTERN$1, "")}#${placeId ?? "__unbound__"}`;
1749
+ return `${platformApiUrl.replace(TRAILING_SLASH_PATTERN$2, "")}#${placeId ?? "__unbound__"}`;
1671
1750
  }
1672
1751
  async function readForgewayShadowGrant(platformApiUrl, placeId, cwd) {
1673
1752
  const store = await readStore(cwd);
@@ -1690,7 +1769,7 @@ async function writeForgewayShadowGrant(grant, cwd) {
1690
1769
 
1691
1770
  //#endregion
1692
1771
  //#region src/cli/commands/deploy/targets/forgeway.ts
1693
- const DEFAULT_DINEWAY_API_BASE_URL = "https://api.dineway.ai";
1772
+ const DEFAULT_DINEWAY_API_BASE_URL$1 = "https://api.dineway.ai";
1694
1773
  const DATABASE_ENV_VAR_NAMES = ["DINEWAY_DATABASE_URL", "DINEWAY_DATABASE_AUTH_TOKEN"];
1695
1774
  const POLL_INTERVAL_MS$1 = 5e3;
1696
1775
  const POLL_TIMEOUT_MS$1 = 3e5;
@@ -1705,9 +1784,12 @@ const NON_COMPARE_PATTERN = /[^\p{Letter}\p{Number}]+/gu;
1705
1784
  const LOCATION_PARTS_PATTERN = /[,;|/]+|\s+-\s+/u;
1706
1785
  const JWT_PATTERN = /[A-Za-z0-9_-]{32,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g;
1707
1786
  const TOKEN_ASSIGNMENT_PATTERN = /(DINEWAY_DATABASE_AUTH_TOKEN|DATABASE_AUTH_TOKEN|AUTH_TOKEN)=\S+/gi;
1708
- const TRAILING_SLASH_PATTERN = /\/$/;
1787
+ const TRAILING_SLASH_PATTERN$1 = /\/$/;
1709
1788
  const BACKSLASH_PATTERN = /\\/g;
1710
- const SHADOW_EMAIL_PATTERN = /^shadow_[a-f0-9]{16}@dineway\.ai$/i;
1789
+ const DINEWAY_PACKAGE_NAME = "dineway";
1790
+ const SEMVER_VERSION_PATTERN = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
1791
+ const LOCAL_PACKAGE_SPEC_PATTERN = /^(?:workspace|file|link|portal):/;
1792
+ const SHADOW_EMAIL_PATTERN$1 = /^shadow_[a-f0-9]{16}@dineway\.ai$/i;
1711
1793
  const OTP_PATTERN = /^\d{6}$/;
1712
1794
  const FOOD_TYPES = new Set([
1713
1795
  "restaurant",
@@ -1756,7 +1838,7 @@ var ForgewayApiError = class extends Error {
1756
1838
  this.name = "ForgewayApiError";
1757
1839
  }
1758
1840
  };
1759
- function normalizeForgewayUser(user) {
1841
+ function normalizeForgewayUser$1(user) {
1760
1842
  return {
1761
1843
  id: user.id,
1762
1844
  name: user.profile?.name ?? user.name ?? user.email,
@@ -1777,7 +1859,7 @@ async function fileExists$8(path) {
1777
1859
  }
1778
1860
  }
1779
1861
  function normalizePlatformApiUrl(value) {
1780
- return (value || DEFAULT_DINEWAY_API_BASE_URL).replace(TRAILING_SLASH_PATTERN, "");
1862
+ return (value || DEFAULT_DINEWAY_API_BASE_URL$1).replace(TRAILING_SLASH_PATTERN$1, "");
1781
1863
  }
1782
1864
  function resolvePlatformApiUrl(savedPlatformApiUrl) {
1783
1865
  return normalizePlatformApiUrl(getEnv("DINEWAY_API_BASE_URL") ?? (typeof savedPlatformApiUrl === "string" ? savedPlatformApiUrl : void 0));
@@ -1840,7 +1922,7 @@ async function parseErrorResponse(response) {
1840
1922
  }
1841
1923
  return `Forgeway request failed: ${response.status}`;
1842
1924
  }
1843
- function normalizeEmail(email) {
1925
+ function normalizeEmail$1(email) {
1844
1926
  return email.trim().toLowerCase();
1845
1927
  }
1846
1928
  function normalizeOtp(otp) {
@@ -1848,8 +1930,8 @@ function normalizeOtp(otp) {
1848
1930
  if (!OTP_PATTERN.test(value)) throw new Error("Forgeway email verification OTP must be a 6-digit numeric code.");
1849
1931
  return value;
1850
1932
  }
1851
- function isShadowEmail(email) {
1852
- return Boolean(email && SHADOW_EMAIL_PATTERN.test(email));
1933
+ function isShadowEmail$1(email) {
1934
+ return Boolean(email && SHADOW_EMAIL_PATTERN$1.test(email));
1853
1935
  }
1854
1936
  async function refreshFormalAccessToken(context, deps) {
1855
1937
  if (!context.refreshToken) throw new Error("Forgeway formal account refresh token is missing. Run dineway deploy again.");
@@ -1861,19 +1943,22 @@ async function refreshFormalAccessToken(context, deps) {
1861
1943
  if (!response.ok) throw new Error("Failed to refresh Forgeway formal account credentials. Run dineway deploy again.");
1862
1944
  const payload = await response.json();
1863
1945
  if (!payload.accessToken) throw new Error("Forgeway refresh response was missing accessToken.");
1864
- const user = assertVerifiedFormalAccountUser(payload.user ? normalizeForgewayUser(payload.user) : context.user, context.user?.email);
1946
+ const user = assertVerifiedFormalAccountUser(payload.user ? normalizeForgewayUser$1(payload.user) : context.user, context.user?.email);
1865
1947
  const updated = {
1866
1948
  platformApiUrl: context.platformApiUrl,
1867
1949
  accessToken: payload.accessToken,
1868
1950
  refreshToken: payload.refreshToken ?? context.refreshToken,
1869
1951
  ...user ? { user } : {},
1870
- source: "shadow-email-upgrade",
1871
- ...context.placeId ? { placeId: context.placeId } : {}
1952
+ source: "shadow-email-upgrade"
1872
1953
  };
1873
1954
  context.accessToken = updated.accessToken;
1874
1955
  context.refreshToken = updated.refreshToken;
1875
1956
  context.user = updated.user;
1876
- await (deps.writeCredentials ?? writeForgewayCredentials)(updated, context.projectDir);
1957
+ await (deps.writeCredentials ?? writeForgewayCredentials)(updated, {
1958
+ cwd: context.projectDir,
1959
+ platformApiUrl: context.platformApiUrl,
1960
+ email: user.email
1961
+ });
1877
1962
  return payload.accessToken;
1878
1963
  }
1879
1964
  async function refreshShadowAccessToken(context, deps) {
@@ -1895,7 +1980,7 @@ async function refreshShadowAccessToken(context, deps) {
1895
1980
  refreshToken: payload.refreshToken,
1896
1981
  restaurantName: context.restaurantName,
1897
1982
  city: context.city,
1898
- user: payload.user ? normalizeForgewayUser(payload.user) : void 0,
1983
+ user: payload.user ? normalizeForgewayUser$1(payload.user) : void 0,
1899
1984
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1900
1985
  }, context.projectDir);
1901
1986
  return payload.accessToken;
@@ -1922,25 +2007,62 @@ async function promptRequired(question, initialValue, deps, errorMessage) {
1922
2007
  async function readSavedForgewayMetadata(cwd) {
1923
2008
  return await readForgewayDeployMetadata(cwd).catch(() => ({}));
1924
2009
  }
1925
- async function resolveForgewayAccountEmail(options, grant, cwd, deps) {
1926
- const stored = await (deps.readCredentials ?? readForgewayCredentials)(cwd);
1927
- const storedEmail = stored?.source === "shadow-email-upgrade" && stored.placeId === grant.placeId && stored.user?.emailVerified === true && !isShadowEmail(stored.user?.email) ? stored.user?.email : void 0;
1928
- const suppliedEmail = options.email ?? getEnv("DINEWAY_EMAIL") ?? getEnv("FORGEWAY_EMAIL");
1929
- if ((options.sendOtp || options.otp) && !suppliedEmail) throw new Error("Forgeway OTP deploy requires --email or DINEWAY_EMAIL.");
1930
- const email = normalizeEmail(suppliedEmail ?? storedEmail ?? await promptRequired("Dineway account email: ", void 0, deps, "Dineway account email is required. Pass --email or set DINEWAY_EMAIL."));
1931
- if (!email || isShadowEmail(email)) throw new Error("Dineway account email must be a real owner email, not a shadow user email.");
2010
+ function getDependencySpec(pkg, name) {
2011
+ for (const key of ["dependencies", "devDependencies"]) {
2012
+ const deps = pkg[key];
2013
+ if (!deps || typeof deps !== "object") continue;
2014
+ const value = deps[name];
2015
+ if (typeof value === "string" && value.trim()) return value.trim();
2016
+ }
2017
+ }
2018
+ async function readProjectPackage(cwd) {
2019
+ try {
2020
+ return await readDeployPackageJson(cwd);
2021
+ } catch {
2022
+ return null;
2023
+ }
2024
+ }
2025
+ function isDinewayDependencySpecCompatible(dependencySpec, cliVersion) {
2026
+ const spec = dependencySpec.trim();
2027
+ if (LOCAL_PACKAGE_SPEC_PATTERN.test(spec)) return true;
2028
+ return spec.includes(cliVersion);
2029
+ }
2030
+ async function assertProjectDinewayRuntimeCompatible(cwd, cliVersion = VERSION) {
2031
+ if (!SEMVER_VERSION_PATTERN.test(cliVersion)) return;
2032
+ const pkg = await readProjectPackage(cwd);
2033
+ if (!pkg) return;
2034
+ const dependencySpec = getDependencySpec(pkg, DINEWAY_PACKAGE_NAME);
2035
+ if (!dependencySpec) return;
2036
+ if (isDinewayDependencySpecCompatible(dependencySpec, cliVersion)) return;
2037
+ throw new Error(`Forgeway deploy requires the deployed Dineway runtime to match the deploy CLI because the CLI initializes the managed database before the site starts. The CLI is ${DINEWAY_PACKAGE_NAME}@${cliVersion}, but package.json declares ${DINEWAY_PACKAGE_NAME}: ${JSON.stringify(dependencySpec)}. Update package.json and reinstall with your package manager, for example: ${DINEWAY_PACKAGE_NAME}@^${cliVersion}. To deploy with the current manifest instead, run the matching CLI version.`);
2038
+ }
2039
+ function explicitPublisherEmail(options) {
2040
+ return options.email ?? getEnv("DINEWAY_EMAIL") ?? getEnv("FORGEWAY_EMAIL");
2041
+ }
2042
+ function savedPublisherEmail(saved) {
2043
+ return typeof saved.publisherEmail === "string" && saved.publisherEmail.trim() ? saved.publisherEmail : void 0;
2044
+ }
2045
+ function validatePublisherEmail(rawEmail) {
2046
+ const email = normalizeEmail$1(rawEmail);
2047
+ if (!email || isShadowEmail$1(email)) throw new Error("Dineway account email must be a real owner email, not a shadow user email.");
1932
2048
  return email;
1933
2049
  }
1934
- function isStoredFormalCredentialForGrant(stored, grant, email) {
1935
- if (!stored?.accessToken || stored.source !== "shadow-email-upgrade" || stored.placeId !== grant.placeId || !stored.user) return false;
1936
- if (normalizeEmail(stored.user.email) !== email) return false;
2050
+ async function resolveForgewayAccountEmail(options, saved, deps, preferredEmail) {
2051
+ const suppliedEmail = options.email ?? getEnv("DINEWAY_EMAIL") ?? getEnv("FORGEWAY_EMAIL");
2052
+ const savedEmail = savedPublisherEmail(saved);
2053
+ if ((options.sendOtp || options.otp) && !suppliedEmail && !preferredEmail && !savedEmail) throw new Error("Forgeway OTP deploy requires --email or DINEWAY_EMAIL.");
2054
+ return validatePublisherEmail(suppliedEmail ?? preferredEmail ?? savedEmail ?? await promptRequired("Dineway account email: ", void 0, deps, "Dineway account email is required. Pass --email or set DINEWAY_EMAIL."));
2055
+ }
2056
+ function isStoredFormalCredentialForEmail(stored, email) {
2057
+ if (!stored?.accessToken || !stored.user) return false;
2058
+ if (email && normalizeEmail$1(stored.user.email) !== email) return false;
1937
2059
  if (stored.user.emailVerified !== true) return false;
1938
- if (isShadowEmail(stored.user.email)) return false;
2060
+ if (isShadowEmail$1(stored.user.email)) return false;
1939
2061
  return true;
1940
2062
  }
1941
2063
  function assertVerifiedFormalAccountUser(user, expectedEmail) {
1942
- if (!user || user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway formal account credentials require a verified formal account.");
1943
- if (expectedEmail && normalizeEmail(user.email) !== normalizeEmail(expectedEmail)) throw new Error("Forgeway refresh returned credentials for a different email.");
2064
+ if (!user || user.emailVerified !== true || isShadowEmail$1(user.email)) throw new Error("Forgeway formal account credentials require a verified formal account.");
2065
+ if (expectedEmail && normalizeEmail$1(user.email) !== normalizeEmail$1(expectedEmail)) throw new Error("Forgeway refresh returned credentials for a different email.");
1944
2066
  return user;
1945
2067
  }
1946
2068
  async function shadowUpgradeFetch(context, path, deps, options) {
@@ -1963,7 +2085,7 @@ async function startShadowEmailUpgrade(context, email, deps) {
1963
2085
  method: "POST",
1964
2086
  body: JSON.stringify({ email })
1965
2087
  });
1966
- if (payload.email && normalizeEmail(payload.email) !== email) throw new Error("Forgeway email verification response returned a different email.");
2088
+ if (payload.email && normalizeEmail$1(payload.email) !== email) throw new Error("Forgeway email verification response returned a different email.");
1967
2089
  return payload;
1968
2090
  }
1969
2091
  async function verifyShadowEmailUpgrade(context, email, otp, deps) {
@@ -1975,21 +2097,24 @@ async function verifyShadowEmailUpgrade(context, email, otp, deps) {
1975
2097
  })
1976
2098
  });
1977
2099
  if (!payload.accessToken || !payload.refreshToken || !payload.user) throw new Error("Forgeway email upgrade response was missing credentials.");
1978
- const user = normalizeForgewayUser(payload.user);
1979
- if (normalizeEmail(user.email) !== email) throw new Error("Forgeway email upgrade returned credentials for a different email.");
1980
- if (user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway email upgrade did not return a verified formal account.");
2100
+ const user = normalizeForgewayUser$1(payload.user);
2101
+ if (normalizeEmail$1(user.email) !== email) throw new Error("Forgeway email upgrade returned credentials for a different email.");
2102
+ if (user.emailVerified !== true || isShadowEmail$1(user.email)) throw new Error("Forgeway email upgrade did not return a verified formal account.");
1981
2103
  return {
1982
2104
  platformApiUrl: context.platformApiUrl,
1983
2105
  accessToken: payload.accessToken,
1984
2106
  refreshToken: payload.refreshToken,
1985
2107
  user,
1986
- source: "shadow-email-upgrade",
1987
- ...context.placeId ? { placeId: context.placeId } : {}
2108
+ source: "shadow-email-upgrade"
1988
2109
  };
1989
2110
  }
1990
- async function resolveFormalAccountCredentials(context, grant, email, options, deps) {
1991
- const stored = await (deps.readCredentials ?? readForgewayCredentials)(context.projectDir);
1992
- if (!options.sendOtp && !options.otp && isStoredFormalCredentialForGrant(stored, grant, email)) return {
2111
+ async function resolveFormalAccountCredentials(context, email, options, deps) {
2112
+ const stored = await (deps.readCredentials ?? readForgewayCredentials)({
2113
+ cwd: context.projectDir,
2114
+ platformApiUrl: context.platformApiUrl,
2115
+ email
2116
+ });
2117
+ if (!options.sendOtp && !options.otp && isStoredFormalCredentialForEmail(stored, email)) return {
1993
2118
  status: "verified",
1994
2119
  credentials: {
1995
2120
  ...stored,
@@ -2000,13 +2125,17 @@ async function resolveFormalAccountCredentials(context, grant, email, options, d
2000
2125
  const response = await startShadowEmailUpgrade(context, email, deps);
2001
2126
  return {
2002
2127
  status: "otp-sent",
2003
- email: response.email ? normalizeEmail(response.email) : email,
2128
+ email: response.email ? normalizeEmail$1(response.email) : email,
2004
2129
  expiresAt: response.expiresAt
2005
2130
  };
2006
2131
  }
2007
2132
  if (options.otp) {
2008
2133
  const credentials = await verifyShadowEmailUpgrade(context, email, normalizeOtp(options.otp), deps);
2009
- await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, context.projectDir);
2134
+ await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, {
2135
+ cwd: context.projectDir,
2136
+ platformApiUrl: context.platformApiUrl,
2137
+ email
2138
+ });
2010
2139
  return {
2011
2140
  status: "verified",
2012
2141
  credentials
@@ -2015,13 +2144,111 @@ async function resolveFormalAccountCredentials(context, grant, email, options, d
2015
2144
  await startShadowEmailUpgrade(context, email, deps);
2016
2145
  consola.info(`Sent Forgeway email verification code to ${email}`);
2017
2146
  const credentials = await verifyShadowEmailUpgrade(context, email, await promptRequired("Email verification code: ", void 0, deps, "Email verification code is required."), deps);
2018
- await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, context.projectDir);
2147
+ await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, {
2148
+ cwd: context.projectDir,
2149
+ platformApiUrl: context.platformApiUrl,
2150
+ email
2151
+ });
2019
2152
  return {
2020
2153
  status: "verified",
2021
2154
  credentials
2022
2155
  };
2023
2156
  }
2024
- async function resolveShadowProjectContext(cwd, options, deps) {
2157
+ async function readCachedPublisherCredentials(cwd, platformApiUrl, email, deps) {
2158
+ const credentials = await (deps.readCredentials ?? readForgewayCredentials)({
2159
+ cwd,
2160
+ platformApiUrl,
2161
+ email
2162
+ });
2163
+ return isStoredFormalCredentialForEmail(credentials, email) ? credentials : void 0;
2164
+ }
2165
+ async function resolveCachedPublisherAccount(cwd, options, saved, platformApiUrl, deps) {
2166
+ const suppliedEmail = explicitPublisherEmail(options);
2167
+ if (suppliedEmail) {
2168
+ const email = validatePublisherEmail(suppliedEmail);
2169
+ return {
2170
+ email,
2171
+ credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
2172
+ };
2173
+ }
2174
+ const projectEmail = savedPublisherEmail(saved);
2175
+ if (projectEmail) {
2176
+ const email = validatePublisherEmail(projectEmail);
2177
+ return {
2178
+ email,
2179
+ credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
2180
+ };
2181
+ }
2182
+ const singleCredentials = await (deps.readCredentials ?? readForgewayCredentials)({
2183
+ cwd,
2184
+ platformApiUrl
2185
+ });
2186
+ if (isStoredFormalCredentialForEmail(singleCredentials)) return {
2187
+ email: normalizeEmail$1(singleCredentials.user.email),
2188
+ credentials: singleCredentials
2189
+ };
2190
+ const accounts = (await (deps.listCredentials ?? listForgewayCredentials)(platformApiUrl)).filter((credentials) => isStoredFormalCredentialForEmail(credentials));
2191
+ if (accounts.length === 1) {
2192
+ const credentials = accounts[0];
2193
+ return {
2194
+ email: normalizeEmail$1(credentials.user.email),
2195
+ credentials
2196
+ };
2197
+ }
2198
+ if (accounts.length > 1) {
2199
+ const email = validatePublisherEmail(await promptRequired("Dineway account email: ", void 0, deps, "Multiple Dineway accounts are stored on this computer. Pass --email or set DINEWAY_EMAIL."));
2200
+ return {
2201
+ email,
2202
+ credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
2203
+ };
2204
+ }
2205
+ return {};
2206
+ }
2207
+ async function resolveFormalProjectContext(cwd, options, deps) {
2208
+ const saved = await readSavedForgewayMetadata(cwd);
2209
+ const platformApiUrl = resolvePlatformApiUrl(saved.platformApiUrl);
2210
+ const account = await resolveCachedPublisherAccount(cwd, options, saved, platformApiUrl, deps);
2211
+ if (!account.credentials) return {
2212
+ status: "missing",
2213
+ email: account.email
2214
+ };
2215
+ const user = assertVerifiedFormalAccountUser(account.credentials.user, account.email);
2216
+ const savedPlaceId = options.placeId ?? getEnv("DINEWAY_PLACE_ID") ?? (typeof saved.placeId === "string" ? saved.placeId : void 0);
2217
+ if (savedPlaceId && !PLACE_ID_PATTERN.test(savedPlaceId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
2218
+ const context = {
2219
+ projectDir: cwd,
2220
+ platformApiUrl,
2221
+ authKind: "formal-account",
2222
+ accessToken: account.credentials.accessToken,
2223
+ refreshToken: account.credentials.refreshToken,
2224
+ user,
2225
+ ossHost: platformApiUrl,
2226
+ placeId: savedPlaceId,
2227
+ restaurantName: options.restaurantName,
2228
+ city: options.city
2229
+ };
2230
+ let restaurant = {
2231
+ name: options.restaurantName,
2232
+ city: options.city
2233
+ };
2234
+ if (!context.placeId) {
2235
+ const resolvedRestaurant = await resolveShadowRestaurantInfo(options, deps);
2236
+ restaurant = resolvedRestaurant;
2237
+ context.placeId = await resolvePlaceIdWithFormalSearch({
2238
+ context,
2239
+ restaurant: resolvedRestaurant,
2240
+ deps
2241
+ });
2242
+ context.restaurantName = resolvedRestaurant.name;
2243
+ context.city = resolvedRestaurant.city;
2244
+ }
2245
+ return {
2246
+ status: "ready",
2247
+ context,
2248
+ restaurant
2249
+ };
2250
+ }
2251
+ async function resolveShadowProjectContext(cwd, options, deps, preferredEmail) {
2025
2252
  const saved = await readSavedForgewayMetadata(cwd);
2026
2253
  const platformApiUrl = resolvePlatformApiUrl(saved.platformApiUrl);
2027
2254
  const savedPlaceId = options.placeId ?? getEnv("DINEWAY_PLACE_ID") ?? (typeof saved.placeId === "string" ? saved.placeId : void 0);
@@ -2077,8 +2304,7 @@ async function resolveShadowProjectContext(cwd, options, deps) {
2077
2304
  restaurantName: restaurant.name,
2078
2305
  city: restaurant.city
2079
2306
  };
2080
- const accountEmail = await resolveForgewayAccountEmail(options, grant, cwd, deps);
2081
- const credentialsResult = await resolveFormalAccountCredentials(shadowContext, grant, accountEmail, options, deps);
2307
+ const credentialsResult = await resolveFormalAccountCredentials(shadowContext, await resolveForgewayAccountEmail(options, saved, deps, preferredEmail), options, deps);
2082
2308
  if (credentialsResult.status === "otp-sent") return credentialsResult;
2083
2309
  const { credentials } = credentialsResult;
2084
2310
  return {
@@ -2095,7 +2321,13 @@ async function resolveShadowProjectContext(cwd, options, deps) {
2095
2321
  };
2096
2322
  }
2097
2323
  async function resolveProjectContext(cwd, options, deps) {
2098
- return await resolveShadowProjectContext(cwd, options, deps);
2324
+ let preferredEmail;
2325
+ if (!options.sendOtp && !options.otp) {
2326
+ const formal = await resolveFormalProjectContext(cwd, options, deps);
2327
+ if (formal.status !== "missing") return formal;
2328
+ preferredEmail = formal.email;
2329
+ }
2330
+ return await resolveShadowProjectContext(cwd, options, deps, preferredEmail);
2099
2331
  }
2100
2332
  async function createShadowUser(platformApiUrl, placeId, deps) {
2101
2333
  const response = await forgewayRequest(`${platformApiUrl}/api/auth/users/shadow`, {
@@ -2344,7 +2576,7 @@ async function bindShadowGrantPlace(options) {
2344
2576
  refreshToken: payload.refreshToken ?? context.refreshToken ?? options.grant.refreshToken,
2345
2577
  restaurantName: options.restaurant.name,
2346
2578
  city: options.restaurant.city,
2347
- user: payload.user ? normalizeForgewayUser(payload.user) : context.user ?? options.grant.user
2579
+ user: payload.user ? normalizeForgewayUser$1(payload.user) : context.user ?? options.grant.user
2348
2580
  });
2349
2581
  await (options.deps.writeShadowGrant ?? writeForgewayShadowGrant)(grant, options.cwd);
2350
2582
  return grant;
@@ -2364,6 +2596,20 @@ async function resolvePlaceIdWithShadowSearch(options) {
2364
2596
  placeId: finalPlaceId
2365
2597
  });
2366
2598
  }
2599
+ async function resolvePlaceIdWithFormalSearch(options) {
2600
+ const candidates = extractPlaceCandidates(await ossFetch(options.context, "/api/places/search", options.deps, {
2601
+ method: "POST",
2602
+ body: JSON.stringify({ textQuery: `${options.restaurant.name} in ${options.restaurant.city}` })
2603
+ }));
2604
+ if (candidates.length === 0) throw new Error(`Dineway place search returned no candidates for "${options.restaurant.name} in ${options.restaurant.city}".`);
2605
+ const selected = selectPlaceCandidate(candidates, {
2606
+ name: options.restaurant.name,
2607
+ city: options.restaurant.city
2608
+ });
2609
+ const finalPlaceId = selected ? candidatePlaceId(selected.candidate) : "";
2610
+ if (!PLACE_ID_PATTERN.test(finalPlaceId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
2611
+ return finalPlaceId;
2612
+ }
2367
2613
  async function createShadowGrant(options) {
2368
2614
  if (options.placeId && !PLACE_ID_PATTERN.test(options.placeId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
2369
2615
  const auth = await createShadowUser(options.platformApiUrl, options.placeId, options.deps);
@@ -2374,14 +2620,14 @@ async function createShadowGrant(options) {
2374
2620
  refreshToken: auth.refreshToken,
2375
2621
  restaurantName: options.restaurantName,
2376
2622
  city: options.city,
2377
- user: auth.user ? normalizeForgewayUser(auth.user) : void 0,
2623
+ user: auth.user ? normalizeForgewayUser$1(auth.user) : void 0,
2378
2624
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2379
2625
  };
2380
2626
  await (options.deps.writeShadowGrant ?? writeForgewayShadowGrant)(grant, options.cwd);
2381
2627
  return grant;
2382
2628
  }
2383
2629
  async function ossFetch(context, path, deps, options = {}) {
2384
- const request = async (token) => await forgewayRequest(`${context.ossHost.replace(TRAILING_SLASH_PATTERN, "")}${path}`, {
2630
+ const request = async (token) => await forgewayRequest(`${context.ossHost.replace(TRAILING_SLASH_PATTERN$1, "")}${path}`, {
2385
2631
  ...options,
2386
2632
  headers: {
2387
2633
  "Content-Type": "application/json",
@@ -2861,6 +3107,8 @@ async function deployForgeway(cwd, options, deps = {}) {
2861
3107
  const sourceDir = resolve(cwd);
2862
3108
  if (!(await stat(sourceDir).catch(() => null))?.isDirectory()) throw new Error(`"${sourceDir}" is not a valid directory.`);
2863
3109
  if (EXCLUDE_PATTERNS.includes(basename(sourceDir))) throw new Error(`"${basename(sourceDir)}" is an excluded directory and cannot be deployed.`);
3110
+ const database = parseDatabaseMode(options.database);
3111
+ if (database !== "none") await assertProjectDinewayRuntimeCompatible(cwd, deps.dinewayVersion ?? VERSION);
2864
3112
  await ensureProjectGitignoreDinewayLocalState(cwd);
2865
3113
  const verbose = isVerboseDeploy(options);
2866
3114
  const project = await resolveProjectContext(cwd, options, deps);
@@ -2870,7 +3118,6 @@ async function deployForgeway(cwd, options, deps = {}) {
2870
3118
  if (options.skipSeed) consola.info("Skipping seed initialization by request");
2871
3119
  await ensureRestaurantClaim(context, restaurant, deps);
2872
3120
  const { site } = await resolveDeploymentSite(cwd, context, options, seedPath, deps, restaurant);
2873
- const database = parseDatabaseMode(options.database);
2874
3121
  if (database !== "none") {
2875
3122
  consola.start("Initializing Forgeway managed database");
2876
3123
  try {
@@ -2905,6 +3152,7 @@ async function deployForgeway(cwd, options, deps = {}) {
2905
3152
  deps,
2906
3153
  verbose
2907
3154
  });
3155
+ if (context.user?.email) await writeForgewayDeployMetadata(cwd, { publisherEmail: normalizeEmail$1(context.user.email) });
2908
3156
  const url = deployment.liveUrl ?? `https://${site.domain}`;
2909
3157
  await (deps.writeProjectEnv ?? persistForgewayCliEnv)(cwd, {
2910
3158
  siteUrl: url,
@@ -3961,15 +4209,77 @@ async function exportSeed(db, withContent) {
3961
4209
  };
3962
4210
  seed.settings = await exportSettings(db);
3963
4211
  seed.collections = await exportCollections(db);
3964
- seed.taxonomies = await exportTaxonomies(db);
3965
- seed.menus = await exportMenus(db);
4212
+ const i18nEnabled = await detectI18nEnabled(db, seed.collections);
4213
+ seed.taxonomies = await exportTaxonomies(db, i18nEnabled);
4214
+ seed.menus = await exportMenus(db, i18nEnabled);
3966
4215
  seed.widgetAreas = await exportWidgetAreas(db);
4216
+ const { bylines, idToSeedId: bylineIdToSeedId } = await exportBylines(db);
4217
+ if (bylines.length > 0) seed.bylines = bylines;
3967
4218
  if (withContent !== void 0) {
3968
4219
  const collections = withContent === "" || withContent === "true" ? null : withContent.split(",").map((s) => s.trim()).filter(Boolean);
3969
- seed.content = await exportContent(db, seed.collections || [], collections);
4220
+ seed.content = await exportContent(db, seed.collections || [], collections, bylineIdToSeedId, i18nEnabled);
3970
4221
  }
3971
4222
  return seed;
3972
4223
  }
4224
+ async function exportBylines(db) {
4225
+ const bylineRepo = new BylineRepository(db);
4226
+ const bylines = [];
4227
+ const idToSeedId = /* @__PURE__ */ new Map();
4228
+ let cursor;
4229
+ do {
4230
+ const result = await bylineRepo.findMany({
4231
+ limit: 100,
4232
+ cursor
4233
+ });
4234
+ for (const byline of result.items) {
4235
+ const seedId = `byline:${byline.slug}`;
4236
+ idToSeedId.set(byline.id, seedId);
4237
+ bylines.push({
4238
+ id: seedId,
4239
+ slug: byline.slug,
4240
+ displayName: byline.displayName,
4241
+ bio: byline.bio || void 0,
4242
+ websiteUrl: byline.websiteUrl || void 0,
4243
+ isGuest: byline.isGuest || void 0
4244
+ });
4245
+ }
4246
+ cursor = result.nextCursor;
4247
+ } while (cursor);
4248
+ return {
4249
+ bylines,
4250
+ idToSeedId
4251
+ };
4252
+ }
4253
+ /**
4254
+ * Determine whether export should preserve locale-suffixed seed ids.
4255
+ *
4256
+ * Runtime i18n config is initialized by middleware, but `dineway export-seed`
4257
+ * runs in a CLI process. When the runtime flag is unset, derive multi-locale
4258
+ * status from stored rows instead: a project is multi-locale when any
4259
+ * i18n-aware table contains more than one distinct locale.
4260
+ */
4261
+ async function detectI18nEnabled(db, collections) {
4262
+ if (isI18nEnabled()) return true;
4263
+ const locales = /* @__PURE__ */ new Set();
4264
+ const collectDistinctLocales = async (tableRef) => {
4265
+ const result = await sql`
4266
+ SELECT DISTINCT locale FROM ${tableRef}
4267
+ `.execute(db);
4268
+ for (const row of result.rows) if (row.locale) locales.add(row.locale);
4269
+ return locales.size > 1;
4270
+ };
4271
+ if (await collectDistinctLocales(sql.ref("_dineway_taxonomy_defs"))) return true;
4272
+ if (await collectDistinctLocales(sql.ref("_dineway_menus"))) return true;
4273
+ for (const collection of collections) {
4274
+ validateIdentifier(collection.slug, "collection slug");
4275
+ try {
4276
+ if (await collectDistinctLocales(sql.ref(`ec_${collection.slug}`))) return true;
4277
+ } catch (error) {
4278
+ if (!isMissingTableError(error)) throw error;
4279
+ }
4280
+ }
4281
+ return false;
4282
+ }
3973
4283
  /**
3974
4284
  * Export site settings
3975
4285
  */
@@ -4019,8 +4329,7 @@ async function exportCollections(db) {
4019
4329
  /**
4020
4330
  * Export taxonomy definitions and terms
4021
4331
  */
4022
- async function exportTaxonomies(db) {
4023
- const i18nEnabled = isI18nEnabled();
4332
+ async function exportTaxonomies(db, i18nEnabled) {
4024
4333
  const defs = await db.selectFrom("_dineway_taxonomy_defs").selectAll().orderBy(["name", "locale"]).execute();
4025
4334
  const result = [];
4026
4335
  const termRepo = new TaxonomyRepository(db);
@@ -4077,8 +4386,7 @@ async function exportTaxonomies(db) {
4077
4386
  /**
4078
4387
  * Export menus with their items
4079
4388
  */
4080
- async function exportMenus(db) {
4081
- const i18nEnabled = isI18nEnabled();
4389
+ async function exportMenus(db, i18nEnabled) {
4082
4390
  const menus = await db.selectFrom("_dineway_menus").selectAll().orderBy(["name", "locale"]).execute();
4083
4391
  const result = [];
4084
4392
  const groupToSeedId = /* @__PURE__ */ new Map();
@@ -4200,11 +4508,12 @@ async function exportWidgetAreas(db) {
4200
4508
  /**
4201
4509
  * Export content from collections
4202
4510
  */
4203
- async function exportContent(db, collections, includeCollections) {
4511
+ async function exportContent(db, collections, includeCollections, bylineIdToSeedId, i18nEnabled) {
4204
4512
  const content = {};
4205
4513
  const contentRepo = new ContentRepository(db);
4206
4514
  const taxonomyRepo = new TaxonomyRepository(db);
4207
4515
  const mediaRepo = new MediaRepository(db);
4516
+ const bylineRepo = new BylineRepository(db);
4208
4517
  const mediaMap = /* @__PURE__ */ new Map();
4209
4518
  try {
4210
4519
  let cursor;
@@ -4223,7 +4532,6 @@ async function exportContent(db, collections, includeCollections) {
4223
4532
  cursor = result.nextCursor;
4224
4533
  } while (cursor);
4225
4534
  } catch {}
4226
- const i18nEnabled = isI18nEnabled();
4227
4535
  for (const collection of collections) {
4228
4536
  if (includeCollections && !includeCollections.includes(collection.slug)) continue;
4229
4537
  const entries = [];
@@ -4253,6 +4561,8 @@ async function exportContent(db, collections, includeCollections) {
4253
4561
  }
4254
4562
  const taxonomies = await getTaxonomyAssignments(taxonomyRepo, collection.slug, item.id);
4255
4563
  if (Object.keys(taxonomies).length > 0) entry.taxonomies = taxonomies;
4564
+ const bylines = await getBylineCredits(bylineRepo, collection.slug, item.id, bylineIdToSeedId);
4565
+ if (bylines.length > 0) entry.bylines = bylines;
4256
4566
  entries.push(entry);
4257
4567
  }
4258
4568
  cursor = result.nextCursor;
@@ -4299,6 +4609,15 @@ function processDataForExport(data, fields, mediaMap) {
4299
4609
  }
4300
4610
  return result;
4301
4611
  }
4612
+ async function getBylineCredits(bylineRepo, collection, entryId, bylineIdToSeedId) {
4613
+ return (await bylineRepo.getContentBylines(collection, entryId)).flatMap((credit) => {
4614
+ const seedId = bylineIdToSeedId.get(credit.byline.id);
4615
+ if (!seedId) return [];
4616
+ const seedCredit = { byline: seedId };
4617
+ if (credit.roleLabel) seedCredit.roleLabel = credit.roleLabel;
4618
+ return [seedCredit];
4619
+ });
4620
+ }
4302
4621
  /**
4303
4622
  * Get taxonomy term assignments for a content entry
4304
4623
  */
@@ -4977,6 +5296,9 @@ const MAX_SCREENSHOTS = 5;
4977
5296
  const MAX_SCREENSHOT_WIDTH = 1920;
4978
5297
  const MAX_SCREENSHOT_HEIGHT = 1080;
4979
5298
  const ICON_SIZE = 256;
5299
+ function toFileImportSpecifier(filePath) {
5300
+ return pathToFileURL(filePath).href;
5301
+ }
4980
5302
  /** Matches Node.js built-in imports in bundled output. */
4981
5303
  const NODE_BUILTIN_IMPORT_RE = /(?:import|export|require)\s*(?:\(|[^(]*?\bfrom\s+)["'](?:node:)?([a-z_]+)(?:\/[^"']*)?\s*["']\)?/g;
4982
5304
  const LEADING_DOT_SLASH_RE = /^\.\//;
@@ -5303,7 +5625,7 @@ const bundleCommand = defineCommand({
5303
5625
  consola.error("Failed to build main entry — no output found in", mainOutDir);
5304
5626
  process.exit(1);
5305
5627
  }
5306
- const pluginModule = await import(mainOutputPath);
5628
+ const pluginModule = await import(toFileImportSpecifier(mainOutputPath));
5307
5629
  let resolvedPlugin;
5308
5630
  if (typeof pluginModule.createPlugin === "function") resolvedPlugin = pluginModule.createPlugin();
5309
5631
  else if (typeof pluginModule.default === "function") resolvedPlugin = pluginModule.default();
@@ -5347,7 +5669,7 @@ const bundleCommand = defineCommand({
5347
5669
  });
5348
5670
  const backendProbePath = await findBuildOutput(backendProbeDir, basename(backendEntry).replace(TS_EXT_RE, ""));
5349
5671
  if (backendProbePath) {
5350
- const standardDef = (await import(backendProbePath)).default ?? {};
5672
+ const standardDef = (await import(toFileImportSpecifier(backendProbePath))).default ?? {};
5351
5673
  const hooks = standardDef.hooks;
5352
5674
  const routes = standardDef.routes;
5353
5675
  if (hooks) for (const hookName of Object.keys(hooks)) {
@@ -6858,6 +7180,586 @@ const seedCommand = defineCommand({
6858
7180
  }
6859
7181
  });
6860
7182
 
7183
+ //#endregion
7184
+ //#region src/cli/forgeway-seo-client.ts
7185
+ const DEFAULT_DINEWAY_API_BASE_URL = "https://api.dineway.ai";
7186
+ const TRAILING_SLASH_PATTERN = /\/$/;
7187
+ const SHADOW_EMAIL_PATTERN = /^shadow_[a-f0-9]{16}@dineway\.ai$/i;
7188
+ var ForgewaySeoApiError = class extends Error {
7189
+ constructor(message, status, body) {
7190
+ super(message);
7191
+ this.status = status;
7192
+ this.body = body;
7193
+ this.name = "ForgewaySeoApiError";
7194
+ }
7195
+ };
7196
+ function normalizeApiUrl(value) {
7197
+ return (value || DEFAULT_DINEWAY_API_BASE_URL).replace(TRAILING_SLASH_PATTERN, "");
7198
+ }
7199
+ function resolveForgewaySeoApiUrl(savedPlatformApiUrl, cwd = process.cwd()) {
7200
+ return normalizeApiUrl(getProjectEnvValue("DINEWAY_API_BASE_URL", cwd) ?? (typeof savedPlatformApiUrl === "string" ? savedPlatformApiUrl : void 0));
7201
+ }
7202
+ function normalizeEmail(value) {
7203
+ return value?.trim().toLowerCase() ?? "";
7204
+ }
7205
+ function isShadowEmail(email) {
7206
+ return Boolean(email && SHADOW_EMAIL_PATTERN.test(email));
7207
+ }
7208
+ function assertFormalUser(user) {
7209
+ if (!user || user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway SEO provider access requires verified formal Forgeway credentials. Run `dineway deploy forgeway` and complete email verification first.");
7210
+ return user;
7211
+ }
7212
+ function normalizeForgewayUser(user, fallback) {
7213
+ if (!user?.id || !user.email) return fallback;
7214
+ return {
7215
+ id: user.id,
7216
+ name: user.profile?.name ?? user.name ?? user.email,
7217
+ email: user.email,
7218
+ avatarUrl: user.profile?.avatar_url ?? user.avatarUrl ?? user.avatar_url ?? null,
7219
+ emailVerified: user.emailVerified ?? user.email_verified ?? false
7220
+ };
7221
+ }
7222
+ async function parseJsonResponse(response) {
7223
+ const text = await response.text();
7224
+ if (!text) return {};
7225
+ try {
7226
+ return JSON.parse(text);
7227
+ } catch {
7228
+ return { message: text };
7229
+ }
7230
+ }
7231
+ function errorMessage(body, fallback) {
7232
+ if (typeof body !== "object" || body === null) return fallback;
7233
+ const record = body;
7234
+ if (typeof record.message === "string") return record.message;
7235
+ if (typeof record.error === "string") return record.error;
7236
+ const nestedError = record.error;
7237
+ if (typeof nestedError === "object" && nestedError !== null) {
7238
+ const message = nestedError.message;
7239
+ if (typeof message === "string") return message;
7240
+ }
7241
+ return fallback;
7242
+ }
7243
+ var ForgewaySeoGatewayClient = class {
7244
+ fetchImpl;
7245
+ readCredentials;
7246
+ writeCredentials;
7247
+ cwd;
7248
+ constructor(deps = {}) {
7249
+ this.fetchImpl = deps.fetch ?? fetch;
7250
+ this.readCredentials = deps.readCredentials ?? readForgewayCredentials;
7251
+ this.writeCredentials = deps.writeCredentials ?? writeForgewayCredentials;
7252
+ this.cwd = deps.cwd ?? process.cwd();
7253
+ }
7254
+ async loadCredentials() {
7255
+ const metadata = await readForgewayDeployMetadata(this.cwd).catch(() => ({}));
7256
+ const platformApiUrl = resolveForgewaySeoApiUrl(metadata.platformApiUrl, this.cwd);
7257
+ const credentials = await this.readCredentials({
7258
+ cwd: this.cwd,
7259
+ platformApiUrl,
7260
+ email: typeof metadata.publisherEmail === "string" ? metadata.publisherEmail : void 0
7261
+ });
7262
+ if (!credentials?.accessToken) throw new Error("Forgeway SEO provider access requires stored Forgeway credentials. Run `dineway deploy forgeway` first.");
7263
+ assertFormalUser(credentials.user);
7264
+ if (!credentials.refreshToken) throw new Error("Forgeway SEO provider access requires a stored formal-account refresh token. Run `dineway deploy forgeway` again.");
7265
+ return {
7266
+ ...credentials,
7267
+ platformApiUrl: resolveForgewaySeoApiUrl(credentials.platformApiUrl, this.cwd)
7268
+ };
7269
+ }
7270
+ async refreshAccessToken(credentials) {
7271
+ const response = await this.fetchImpl(`${credentials.platformApiUrl}/api/auth/refresh?client_type=server`, {
7272
+ method: "POST",
7273
+ headers: { "Content-Type": "application/json" },
7274
+ body: JSON.stringify({ refreshToken: credentials.refreshToken })
7275
+ });
7276
+ const body = await parseJsonResponse(response);
7277
+ if (!response.ok) throw new ForgewaySeoApiError(errorMessage(body, "Failed to refresh Forgeway formal account credentials. Run `dineway deploy forgeway` again."), response.status, body);
7278
+ if (!body.accessToken) throw new Error("Forgeway refresh response was missing accessToken.");
7279
+ const user = assertFormalUser(normalizeForgewayUser(body.user, credentials.user));
7280
+ if (credentials.user?.email && normalizeEmail(user.email) !== normalizeEmail(credentials.user.email)) throw new Error("Forgeway refresh returned credentials for a different email.");
7281
+ const updated = {
7282
+ ...credentials,
7283
+ accessToken: body.accessToken,
7284
+ refreshToken: body.refreshToken ?? credentials.refreshToken,
7285
+ user
7286
+ };
7287
+ await this.writeCredentials(updated, {
7288
+ cwd: this.cwd,
7289
+ platformApiUrl: updated.platformApiUrl,
7290
+ email: user.email
7291
+ });
7292
+ return updated;
7293
+ }
7294
+ async request(path, body, init) {
7295
+ const credentials = await this.refreshAccessToken(await this.loadCredentials());
7296
+ const response = await this.fetchImpl(`${credentials.platformApiUrl}${path}`, {
7297
+ method: init?.method ?? "POST",
7298
+ headers: {
7299
+ Authorization: `Bearer ${credentials.accessToken}`,
7300
+ "Content-Type": "application/json"
7301
+ },
7302
+ body: init?.method === "GET" ? void 0 : JSON.stringify(body ?? {})
7303
+ });
7304
+ const payload = await parseJsonResponse(response);
7305
+ if (!response.ok) throw new ForgewaySeoApiError(errorMessage(payload, `Forgeway SEO request failed with status ${response.status}.`), response.status, payload);
7306
+ return payload;
7307
+ }
7308
+ };
7309
+
7310
+ //#endregion
7311
+ //#region src/cli/commands/seo.ts
7312
+ const hostedProviderArgs = {
7313
+ json: {
7314
+ type: "boolean",
7315
+ description: "Output as JSON"
7316
+ },
7317
+ "force-refresh": {
7318
+ type: "boolean",
7319
+ description: "Bypass Forgeway SEO provider cache"
7320
+ }
7321
+ };
7322
+ const dataForSeoCommonArgs = {
7323
+ ...hostedProviderArgs,
7324
+ "location-code": {
7325
+ type: "string",
7326
+ description: "DataForSEO location code",
7327
+ default: "2840"
7328
+ },
7329
+ "language-code": {
7330
+ type: "string",
7331
+ description: "DataForSEO language code",
7332
+ default: "en"
7333
+ },
7334
+ device: {
7335
+ type: "string",
7336
+ description: "Device type: desktop or mobile",
7337
+ default: "desktop"
7338
+ }
7339
+ };
7340
+ function toStringValue(value) {
7341
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
7342
+ }
7343
+ function toNumberValue(value, fallback) {
7344
+ const raw = toStringValue(value);
7345
+ if (!raw) return fallback;
7346
+ const parsed = Number(raw);
7347
+ return Number.isFinite(parsed) ? parsed : fallback;
7348
+ }
7349
+ function forceRefresh(args) {
7350
+ return args["force-refresh"] === true;
7351
+ }
7352
+ function formats(value) {
7353
+ const raw = toStringValue(value);
7354
+ if (!raw) return void 0;
7355
+ return raw.split(",").map((item) => item.trim()).filter(Boolean);
7356
+ }
7357
+ function requireArg(value, name) {
7358
+ const normalized = toStringValue(value);
7359
+ if (!normalized) throw new Error(`${name} is required.`);
7360
+ return normalized;
7361
+ }
7362
+ async function runSeoRequest(args, path, body) {
7363
+ configureOutputMode(args);
7364
+ try {
7365
+ output(await new ForgewaySeoGatewayClient().request(path, body), args);
7366
+ } catch (error) {
7367
+ consola$1.error(error instanceof Error ? error.message : "Unknown error");
7368
+ process.exit(1);
7369
+ }
7370
+ }
7371
+ const firecrawlCommand = defineCommand({
7372
+ meta: {
7373
+ name: "firecrawl",
7374
+ description: "Forgeway-hosted Firecrawl workflows"
7375
+ },
7376
+ subCommands: {
7377
+ scrape: defineCommand({
7378
+ meta: {
7379
+ name: "scrape",
7380
+ description: "Scrape one URL through Forgeway-hosted Firecrawl"
7381
+ },
7382
+ args: {
7383
+ url: {
7384
+ type: "positional",
7385
+ description: "URL to scrape",
7386
+ required: true
7387
+ },
7388
+ ...hostedProviderArgs,
7389
+ formats: {
7390
+ type: "string",
7391
+ description: "Comma-separated Firecrawl formats",
7392
+ default: "markdown"
7393
+ },
7394
+ "only-main-content": {
7395
+ type: "boolean",
7396
+ description: "Return main content only",
7397
+ default: true
7398
+ },
7399
+ "timeout-ms": {
7400
+ type: "string",
7401
+ description: "Provider timeout in milliseconds",
7402
+ default: "60000"
7403
+ }
7404
+ },
7405
+ async run({ args }) {
7406
+ await runSeoRequest(args, "/api/firecrawl/scrape", {
7407
+ url: requireArg(args.url, "url"),
7408
+ formats: formats(args.formats),
7409
+ onlyMainContent: args["only-main-content"] !== false,
7410
+ timeoutMs: toNumberValue(args["timeout-ms"], 6e4),
7411
+ forceRefresh: forceRefresh(args)
7412
+ });
7413
+ }
7414
+ }),
7415
+ map: defineCommand({
7416
+ meta: {
7417
+ name: "map",
7418
+ description: "Map URLs through Forgeway-hosted Firecrawl"
7419
+ },
7420
+ args: {
7421
+ url: {
7422
+ type: "positional",
7423
+ description: "Base URL to map",
7424
+ required: true
7425
+ },
7426
+ ...hostedProviderArgs,
7427
+ search: {
7428
+ type: "string",
7429
+ description: "Optional relevance search term"
7430
+ },
7431
+ sitemap: {
7432
+ type: "string",
7433
+ description: "Sitemap mode: skip, include, or only",
7434
+ default: "include"
7435
+ },
7436
+ limit: {
7437
+ type: "string",
7438
+ description: "Maximum URLs",
7439
+ default: "100"
7440
+ },
7441
+ "include-subdomains": {
7442
+ type: "boolean",
7443
+ description: "Include subdomains"
7444
+ },
7445
+ "ignore-query-parameters": {
7446
+ type: "boolean",
7447
+ description: "Ignore query parameters",
7448
+ default: true
7449
+ }
7450
+ },
7451
+ async run({ args }) {
7452
+ await runSeoRequest(args, "/api/firecrawl/map", {
7453
+ url: requireArg(args.url, "url"),
7454
+ search: toStringValue(args.search),
7455
+ sitemap: toStringValue(args.sitemap) ?? "include",
7456
+ limit: toNumberValue(args.limit, 100),
7457
+ includeSubdomains: args["include-subdomains"] === true,
7458
+ ignoreQueryParameters: args["ignore-query-parameters"] !== false,
7459
+ forceRefresh: forceRefresh(args)
7460
+ });
7461
+ }
7462
+ }),
7463
+ crawl: defineCommand({
7464
+ meta: {
7465
+ name: "crawl",
7466
+ description: "Start a bounded Firecrawl crawl, or check status with --id"
7467
+ },
7468
+ args: {
7469
+ url: {
7470
+ type: "positional",
7471
+ description: "Base URL to crawl"
7472
+ },
7473
+ ...hostedProviderArgs,
7474
+ id: {
7475
+ type: "string",
7476
+ description: "Existing Firecrawl crawl id to check"
7477
+ },
7478
+ limit: {
7479
+ type: "string",
7480
+ description: "Maximum pages",
7481
+ default: "25"
7482
+ },
7483
+ "max-depth": {
7484
+ type: "string",
7485
+ description: "Maximum discovery depth",
7486
+ default: "3"
7487
+ },
7488
+ "allow-subdomains": {
7489
+ type: "boolean",
7490
+ description: "Allow subdomains"
7491
+ },
7492
+ "allow-external-links": {
7493
+ type: "boolean",
7494
+ description: "Allow external links"
7495
+ },
7496
+ formats: {
7497
+ type: "string",
7498
+ description: "Comma-separated scrape formats",
7499
+ default: "markdown"
7500
+ }
7501
+ },
7502
+ async run({ args }) {
7503
+ const crawlId = toStringValue(args.id);
7504
+ if (crawlId) {
7505
+ configureOutputMode(args);
7506
+ try {
7507
+ output(await new ForgewaySeoGatewayClient().request(`/api/firecrawl/crawl/${encodeURIComponent(crawlId)}`, void 0, { method: "GET" }), args);
7508
+ } catch (error) {
7509
+ consola$1.error(error instanceof Error ? error.message : "Unknown error");
7510
+ process.exit(1);
7511
+ }
7512
+ return;
7513
+ }
7514
+ await runSeoRequest(args, "/api/firecrawl/crawl", {
7515
+ url: requireArg(args.url, "url"),
7516
+ limit: toNumberValue(args.limit, 25),
7517
+ maxDiscoveryDepth: toNumberValue(args["max-depth"], 3),
7518
+ allowExternalLinks: args["allow-external-links"] === true,
7519
+ allowSubdomains: args["allow-subdomains"] === true,
7520
+ scrapeFormats: formats(args.formats),
7521
+ forceRefresh: forceRefresh(args)
7522
+ });
7523
+ }
7524
+ }),
7525
+ search: defineCommand({
7526
+ meta: {
7527
+ name: "search",
7528
+ description: "Search through Forgeway-hosted Firecrawl"
7529
+ },
7530
+ args: {
7531
+ query: {
7532
+ type: "positional",
7533
+ description: "Search query",
7534
+ required: true
7535
+ },
7536
+ ...hostedProviderArgs,
7537
+ limit: {
7538
+ type: "string",
7539
+ description: "Maximum results",
7540
+ default: "10"
7541
+ },
7542
+ scrape: {
7543
+ type: "boolean",
7544
+ description: "Scrape result markdown"
7545
+ }
7546
+ },
7547
+ async run({ args }) {
7548
+ await runSeoRequest(args, "/api/firecrawl/search", {
7549
+ query: requireArg(args.query, "query"),
7550
+ limit: toNumberValue(args.limit, 10),
7551
+ scrape: args.scrape === true,
7552
+ forceRefresh: forceRefresh(args)
7553
+ });
7554
+ }
7555
+ })
7556
+ }
7557
+ });
7558
+ function dataForSeoBase(args) {
7559
+ return {
7560
+ locationCode: toNumberValue(args["location-code"], 2840),
7561
+ languageCode: toStringValue(args["language-code"]) ?? "en",
7562
+ device: toStringValue(args.device) ?? "desktop",
7563
+ forceRefresh: forceRefresh(args)
7564
+ };
7565
+ }
7566
+ const dataForSeoSerpCommand = defineCommand({
7567
+ meta: {
7568
+ name: "serp",
7569
+ description: "Fetch Google organic SERP data"
7570
+ },
7571
+ args: {
7572
+ keyword: {
7573
+ type: "positional",
7574
+ description: "Keyword",
7575
+ required: true
7576
+ },
7577
+ ...dataForSeoCommonArgs,
7578
+ depth: {
7579
+ type: "string",
7580
+ description: "SERP depth",
7581
+ default: "10"
7582
+ }
7583
+ },
7584
+ async run({ args }) {
7585
+ await runSeoRequest(args, "/api/dataforseo/serp", {
7586
+ keyword: requireArg(args.keyword, "keyword"),
7587
+ depth: toNumberValue(args.depth, 10),
7588
+ ...dataForSeoBase(args)
7589
+ });
7590
+ }
7591
+ });
7592
+ const dataForSeoMapsCommand = defineCommand({
7593
+ meta: {
7594
+ name: "maps",
7595
+ description: "Fetch Google Maps SERP data"
7596
+ },
7597
+ args: {
7598
+ keyword: {
7599
+ type: "positional",
7600
+ description: "Keyword",
7601
+ required: true
7602
+ },
7603
+ ...dataForSeoCommonArgs,
7604
+ depth: {
7605
+ type: "string",
7606
+ description: "Maps depth",
7607
+ default: "10"
7608
+ }
7609
+ },
7610
+ async run({ args }) {
7611
+ await runSeoRequest(args, "/api/dataforseo/maps", {
7612
+ keyword: requireArg(args.keyword, "keyword"),
7613
+ depth: toNumberValue(args.depth, 10),
7614
+ ...dataForSeoBase(args)
7615
+ });
7616
+ }
7617
+ });
7618
+ const dataForSeoKeywordsCommand = defineCommand({
7619
+ meta: {
7620
+ name: "keywords",
7621
+ description: "Fetch keyword suggestions"
7622
+ },
7623
+ args: {
7624
+ keyword: {
7625
+ type: "positional",
7626
+ description: "Seed keyword",
7627
+ required: true
7628
+ },
7629
+ ...dataForSeoCommonArgs,
7630
+ limit: {
7631
+ type: "string",
7632
+ description: "Maximum suggestions",
7633
+ default: "20"
7634
+ }
7635
+ },
7636
+ async run({ args }) {
7637
+ await runSeoRequest(args, "/api/dataforseo/keywords", {
7638
+ keyword: requireArg(args.keyword, "keyword"),
7639
+ limit: toNumberValue(args.limit, 20),
7640
+ includeSerpInfo: true,
7641
+ includeSeedKeyword: true,
7642
+ ...dataForSeoBase(args)
7643
+ });
7644
+ }
7645
+ });
7646
+ const dataForSeoCompetitorsCommand = defineCommand({
7647
+ meta: {
7648
+ name: "competitors",
7649
+ description: "Fetch competitor-domain data"
7650
+ },
7651
+ args: {
7652
+ domain: {
7653
+ type: "positional",
7654
+ description: "Target domain",
7655
+ required: true
7656
+ },
7657
+ ...dataForSeoCommonArgs,
7658
+ limit: {
7659
+ type: "string",
7660
+ description: "Maximum competitors",
7661
+ default: "20"
7662
+ }
7663
+ },
7664
+ async run({ args }) {
7665
+ await runSeoRequest(args, "/api/dataforseo/competitors", {
7666
+ targetDomain: requireArg(args.domain, "domain"),
7667
+ limit: toNumberValue(args.limit, 20),
7668
+ ...dataForSeoBase(args)
7669
+ });
7670
+ }
7671
+ });
7672
+ const dataForSeoAiScrapeCommand = defineCommand({
7673
+ meta: {
7674
+ name: "ai-scrape",
7675
+ description: "Fetch DataForSEO AI scraper response data"
7676
+ },
7677
+ args: {
7678
+ keyword: {
7679
+ type: "positional",
7680
+ description: "AI search keyword",
7681
+ required: true
7682
+ },
7683
+ ...dataForSeoCommonArgs,
7684
+ platform: {
7685
+ type: "string",
7686
+ description: "AI platform: chat_gpt, gemini, or perplexity",
7687
+ default: "chat_gpt"
7688
+ }
7689
+ },
7690
+ async run({ args }) {
7691
+ await runSeoRequest(args, "/api/dataforseo/ai-scrape", {
7692
+ keyword: requireArg(args.keyword, "keyword"),
7693
+ platform: toStringValue(args.platform) ?? "chat_gpt",
7694
+ ...dataForSeoBase(args)
7695
+ });
7696
+ }
7697
+ });
7698
+ const dataForSeoAiMentionsCommand = defineCommand({
7699
+ meta: {
7700
+ name: "ai-mentions",
7701
+ description: "Fetch DataForSEO LLM mention data"
7702
+ },
7703
+ args: {
7704
+ ...dataForSeoCommonArgs,
7705
+ domain: {
7706
+ type: "string",
7707
+ description: "Target domain"
7708
+ },
7709
+ keyword: {
7710
+ type: "string",
7711
+ description: "Target keyword"
7712
+ },
7713
+ platform: {
7714
+ type: "string",
7715
+ description: "Mention platform: google or chat_gpt",
7716
+ default: "google"
7717
+ },
7718
+ limit: {
7719
+ type: "string",
7720
+ description: "Maximum mentions",
7721
+ default: "20"
7722
+ }
7723
+ },
7724
+ async run({ args }) {
7725
+ if (!toStringValue(args.domain) && !toStringValue(args.keyword)) {
7726
+ consola$1.error("domain or keyword is required.");
7727
+ process.exit(1);
7728
+ }
7729
+ await runSeoRequest(args, "/api/dataforseo/ai-mentions", {
7730
+ targetDomain: toStringValue(args.domain),
7731
+ keyword: toStringValue(args.keyword),
7732
+ platform: toStringValue(args.platform) ?? "google",
7733
+ limit: toNumberValue(args.limit, 20),
7734
+ ...dataForSeoBase(args)
7735
+ });
7736
+ }
7737
+ });
7738
+ const dataForSeoCommand = defineCommand({
7739
+ meta: {
7740
+ name: "dataforseo",
7741
+ description: "Forgeway-hosted DataForSEO workflows"
7742
+ },
7743
+ subCommands: {
7744
+ serp: dataForSeoSerpCommand,
7745
+ maps: dataForSeoMapsCommand,
7746
+ keywords: dataForSeoKeywordsCommand,
7747
+ competitors: dataForSeoCompetitorsCommand,
7748
+ "ai-scrape": dataForSeoAiScrapeCommand,
7749
+ "ai-mentions": dataForSeoAiMentionsCommand
7750
+ }
7751
+ });
7752
+ const seoCommand = defineCommand({
7753
+ meta: {
7754
+ name: "seo",
7755
+ description: "Hosted SEO provider workflows through Forgeway"
7756
+ },
7757
+ subCommands: {
7758
+ firecrawl: firecrawlCommand,
7759
+ dataforseo: dataForSeoCommand
7760
+ }
7761
+ });
7762
+
6861
7763
  //#endregion
6862
7764
  //#region src/cli/commands/taxonomy.ts
6863
7765
  /**
@@ -7074,6 +7976,7 @@ runMain(defineCommand({
7074
7976
  schema: schemaCommand,
7075
7977
  media: mediaCommand,
7076
7978
  search: searchCommand,
7979
+ seo: seoCommand,
7077
7980
  taxonomy: taxonomyCommand,
7078
7981
  menu: menuCommand,
7079
7982
  plugin: pluginCommand