convex 1.40.0 → 1.42.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 (400) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/browser/simple_client-node.js +85 -27
  5. package/dist/cjs/browser/simple_client-node.js.map +3 -3
  6. package/dist/cjs/cli/aiFiles.js +2 -2
  7. package/dist/cjs/cli/aiFiles.js.map +1 -1
  8. package/dist/cjs/cli/configure.js +1 -4
  9. package/dist/cjs/cli/configure.js.map +2 -2
  10. package/dist/cjs/cli/convexExport.js +3 -3
  11. package/dist/cjs/cli/convexExport.js.map +1 -1
  12. package/dist/cjs/cli/convexImport.js +2 -2
  13. package/dist/cjs/cli/convexImport.js.map +1 -1
  14. package/dist/cjs/cli/dashboard.js +19 -6
  15. package/dist/cjs/cli/dashboard.js.map +3 -3
  16. package/dist/cjs/cli/data.js +2 -2
  17. package/dist/cjs/cli/data.js.map +1 -1
  18. package/dist/cjs/cli/deploy.js +5 -5
  19. package/dist/cjs/cli/deploy.js.map +2 -2
  20. package/dist/cjs/cli/deploymentCreate.js +11 -5
  21. package/dist/cjs/cli/deploymentCreate.js.map +2 -2
  22. package/dist/cjs/cli/deploymentSelect.js +5 -5
  23. package/dist/cjs/cli/deploymentSelect.js.map +1 -1
  24. package/dist/cjs/cli/deploymentTokenCreate.js +5 -13
  25. package/dist/cjs/cli/deploymentTokenCreate.js.map +2 -2
  26. package/dist/cjs/cli/deploymentTokenDelete.js +4 -11
  27. package/dist/cjs/cli/deploymentTokenDelete.js.map +2 -2
  28. package/dist/cjs/cli/dev.js +6 -5
  29. package/dist/cjs/cli/dev.js.map +2 -2
  30. package/dist/cjs/cli/env.js +25 -18
  31. package/dist/cjs/cli/env.js.map +2 -2
  32. package/dist/cjs/cli/envDefault.js +20 -15
  33. package/dist/cjs/cli/envDefault.js.map +2 -2
  34. package/dist/cjs/cli/insights.js +14 -4
  35. package/dist/cjs/cli/insights.js.map +2 -2
  36. package/dist/cjs/cli/lib/aiFiles/skills.js +2 -2
  37. package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
  38. package/dist/cjs/cli/lib/command.js +1 -1
  39. package/dist/cjs/cli/lib/command.js.map +1 -1
  40. package/dist/cjs/cli/lib/deployment.js.map +1 -1
  41. package/dist/cjs/cli/lib/deploymentSelection.js +39 -0
  42. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  43. package/dist/cjs/cli/lib/dev.js +31 -0
  44. package/dist/cjs/cli/lib/dev.js.map +2 -2
  45. package/dist/cjs/cli/lib/env.js +5 -1
  46. package/dist/cjs/cli/lib/env.js.map +2 -2
  47. package/dist/cjs/cli/lib/generateDocs.js +256 -0
  48. package/dist/cjs/cli/lib/generateDocs.js.map +7 -0
  49. package/dist/cjs/cli/lib/localDeployment/anonymous.js +24 -49
  50. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +3 -3
  51. package/dist/cjs/cli/lib/localDeployment/bigBrain.js +0 -9
  52. package/dist/cjs/cli/lib/localDeployment/bigBrain.js.map +2 -2
  53. package/dist/cjs/cli/lib/localDeployment/dashboard.js +30 -68
  54. package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
  55. package/dist/cjs/cli/lib/localDeployment/download.js +14 -1
  56. package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
  57. package/dist/cjs/cli/lib/localDeployment/filePaths.js +33 -4
  58. package/dist/cjs/cli/lib/localDeployment/filePaths.js.map +2 -2
  59. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +37 -126
  60. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +3 -3
  61. package/dist/cjs/cli/lib/localDeployment/secrets.js +91 -0
  62. package/dist/cjs/cli/lib/localDeployment/secrets.js.map +7 -0
  63. package/dist/cjs/cli/lib/localDeployment/upgrade.js +43 -28
  64. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +3 -3
  65. package/dist/cjs/cli/lib/localDeployment/utils.js +0 -19
  66. package/dist/cjs/cli/lib/localDeployment/utils.js.map +3 -3
  67. package/dist/cjs/cli/lib/login.js +16 -12
  68. package/dist/cjs/cli/lib/login.js.map +2 -2
  69. package/dist/cjs/cli/lib/logs.js +4 -1
  70. package/dist/cjs/cli/lib/logs.js.map +2 -2
  71. package/dist/cjs/cli/lib/run.js +27 -2
  72. package/dist/cjs/cli/lib/run.js.map +2 -2
  73. package/dist/cjs/cli/lib/runTestFunction.js +3 -3
  74. package/dist/cjs/cli/lib/runTestFunction.js.map +1 -1
  75. package/dist/cjs/cli/lib/utils/utils.js +30 -0
  76. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  77. package/dist/cjs/cli/program.js +2 -1
  78. package/dist/cjs/cli/program.js.map +2 -2
  79. package/dist/cjs/cli/project.js +27 -0
  80. package/dist/cjs/cli/project.js.map +7 -0
  81. package/dist/cjs/cli/projectCreate.js +90 -0
  82. package/dist/cjs/cli/projectCreate.js.map +7 -0
  83. package/dist/cjs/cli/run.js +5 -5
  84. package/dist/cjs/cli/run.js.map +1 -1
  85. package/dist/cjs/index.js +1 -1
  86. package/dist/cjs/index.js.map +1 -1
  87. package/dist/cjs/server/database.js.map +1 -1
  88. package/dist/cjs/server/impl/meta_impl.js +6 -6
  89. package/dist/cjs/server/impl/meta_impl.js.map +2 -2
  90. package/dist/cjs/server/impl/registration_impl.js +9 -3
  91. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  92. package/dist/cjs/server/index.js.map +2 -2
  93. package/dist/cjs/server/meta.js.map +1 -1
  94. package/dist/cjs/server/query.js.map +1 -1
  95. package/dist/cjs/server/registration.js.map +1 -1
  96. package/dist/cjs/server/storage.js.map +1 -1
  97. package/dist/cjs/server/system_fields.js.map +1 -1
  98. package/dist/cjs-types/cli/configure.d.ts +3 -2
  99. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/dashboard.d.ts.map +1 -1
  101. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  103. package/dist/cjs-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  104. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  105. package/dist/cjs-types/cli/env.d.ts.map +1 -1
  106. package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
  107. package/dist/cjs-types/cli/insights.d.ts +1 -0
  108. package/dist/cjs-types/cli/insights.d.ts.map +1 -1
  109. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
  110. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +16 -16
  111. package/dist/cjs-types/cli/lib/deployment.d.ts +0 -2
  112. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  113. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +7 -0
  114. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  115. package/dist/cjs-types/cli/lib/dev.d.ts +2 -1
  116. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  117. package/dist/cjs-types/cli/lib/env.d.ts +3 -1
  118. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  119. package/dist/cjs-types/cli/lib/env.test.d.ts +2 -0
  120. package/dist/cjs-types/cli/lib/env.test.d.ts.map +1 -0
  121. package/dist/cjs-types/cli/lib/generateDocs.d.ts +20 -0
  122. package/dist/cjs-types/cli/lib/generateDocs.d.ts.map +1 -0
  123. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts +2 -0
  124. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts.map +1 -0
  125. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
  126. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  127. package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
  128. package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
  129. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
  130. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  131. package/dist/cjs-types/cli/lib/localDeployment/download.d.ts +11 -1
  132. package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  133. package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
  134. package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
  135. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
  136. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  137. package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts +31 -0
  138. package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
  139. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
  140. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
  141. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
  142. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  143. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +0 -2
  144. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  145. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  146. package/dist/cjs-types/cli/lib/logs.d.ts +1 -1
  147. package/dist/cjs-types/cli/lib/logs.d.ts.map +1 -1
  148. package/dist/cjs-types/cli/lib/run.d.ts +1 -1
  149. package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
  150. package/dist/cjs-types/cli/lib/utils/utils.d.ts +10 -0
  151. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  152. package/dist/cjs-types/cli/lib/versionApi.d.ts +2 -2
  153. package/dist/cjs-types/cli/program.d.ts.map +1 -1
  154. package/dist/cjs-types/cli/project.d.ts +3 -0
  155. package/dist/cjs-types/cli/project.d.ts.map +1 -0
  156. package/dist/cjs-types/cli/projectCreate.d.ts +5 -0
  157. package/dist/cjs-types/cli/projectCreate.d.ts.map +1 -0
  158. package/dist/cjs-types/index.d.ts +1 -1
  159. package/dist/cjs-types/server/database.d.ts +21 -3
  160. package/dist/cjs-types/server/database.d.ts.map +1 -1
  161. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -1
  162. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  163. package/dist/cjs-types/server/index.d.ts +2 -2
  164. package/dist/cjs-types/server/index.d.ts.map +1 -1
  165. package/dist/cjs-types/server/meta.d.ts +26 -0
  166. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  167. package/dist/cjs-types/server/query.d.ts +1 -1
  168. package/dist/cjs-types/server/registration.d.ts +23 -5
  169. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  170. package/dist/cjs-types/server/storage.d.ts +20 -3
  171. package/dist/cjs-types/server/storage.d.ts.map +1 -1
  172. package/dist/cli.bundle.cjs +67155 -68245
  173. package/dist/cli.bundle.cjs.map +4 -4
  174. package/dist/esm/browser/simple_client-node.js +85 -27
  175. package/dist/esm/browser/simple_client-node.js.map +3 -3
  176. package/dist/esm/cli/aiFiles.js +2 -2
  177. package/dist/esm/cli/aiFiles.js.map +1 -1
  178. package/dist/esm/cli/configure.js +1 -4
  179. package/dist/esm/cli/configure.js.map +2 -2
  180. package/dist/esm/cli/convexExport.js +3 -3
  181. package/dist/esm/cli/convexExport.js.map +1 -1
  182. package/dist/esm/cli/convexImport.js +2 -2
  183. package/dist/esm/cli/convexImport.js.map +1 -1
  184. package/dist/esm/cli/dashboard.js +16 -3
  185. package/dist/esm/cli/dashboard.js.map +2 -2
  186. package/dist/esm/cli/data.js +2 -2
  187. package/dist/esm/cli/data.js.map +1 -1
  188. package/dist/esm/cli/deploy.js +5 -5
  189. package/dist/esm/cli/deploy.js.map +2 -2
  190. package/dist/esm/cli/deploymentCreate.js +13 -9
  191. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  192. package/dist/esm/cli/deploymentSelect.js +5 -5
  193. package/dist/esm/cli/deploymentSelect.js.map +1 -1
  194. package/dist/esm/cli/deploymentTokenCreate.js +9 -15
  195. package/dist/esm/cli/deploymentTokenCreate.js.map +2 -2
  196. package/dist/esm/cli/deploymentTokenDelete.js +8 -16
  197. package/dist/esm/cli/deploymentTokenDelete.js.map +2 -2
  198. package/dist/esm/cli/dev.js +6 -5
  199. package/dist/esm/cli/dev.js.map +2 -2
  200. package/dist/esm/cli/env.js +25 -18
  201. package/dist/esm/cli/env.js.map +2 -2
  202. package/dist/esm/cli/envDefault.js +20 -15
  203. package/dist/esm/cli/envDefault.js.map +2 -2
  204. package/dist/esm/cli/insights.js +14 -4
  205. package/dist/esm/cli/insights.js.map +2 -2
  206. package/dist/esm/cli/lib/aiFiles/skills.js +2 -2
  207. package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
  208. package/dist/esm/cli/lib/command.js +1 -1
  209. package/dist/esm/cli/lib/command.js.map +1 -1
  210. package/dist/esm/cli/lib/deployment.js.map +1 -1
  211. package/dist/esm/cli/lib/deploymentSelection.js +38 -0
  212. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  213. package/dist/esm/cli/lib/dev.js +31 -0
  214. package/dist/esm/cli/lib/dev.js.map +2 -2
  215. package/dist/esm/cli/lib/env.js +5 -1
  216. package/dist/esm/cli/lib/env.js.map +2 -2
  217. package/dist/esm/cli/lib/generateDocs.js +233 -0
  218. package/dist/esm/cli/lib/generateDocs.js.map +7 -0
  219. package/dist/esm/cli/lib/localDeployment/anonymous.js +30 -61
  220. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +3 -3
  221. package/dist/esm/cli/lib/localDeployment/bigBrain.js +0 -8
  222. package/dist/esm/cli/lib/localDeployment/bigBrain.js.map +2 -2
  223. package/dist/esm/cli/lib/localDeployment/dashboard.js +36 -69
  224. package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
  225. package/dist/esm/cli/lib/localDeployment/download.js +15 -2
  226. package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
  227. package/dist/esm/cli/lib/localDeployment/filePaths.js +29 -2
  228. package/dist/esm/cli/lib/localDeployment/filePaths.js.map +2 -2
  229. package/dist/esm/cli/lib/localDeployment/localDeployment.js +40 -134
  230. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +3 -3
  231. package/dist/esm/cli/lib/localDeployment/secrets.js +57 -0
  232. package/dist/esm/cli/lib/localDeployment/secrets.js.map +7 -0
  233. package/dist/esm/cli/lib/localDeployment/upgrade.js +45 -28
  234. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +3 -3
  235. package/dist/esm/cli/lib/localDeployment/utils.js +0 -7
  236. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  237. package/dist/esm/cli/lib/login.js +18 -13
  238. package/dist/esm/cli/lib/login.js.map +2 -2
  239. package/dist/esm/cli/lib/logs.js +5 -2
  240. package/dist/esm/cli/lib/logs.js.map +2 -2
  241. package/dist/esm/cli/lib/run.js +32 -3
  242. package/dist/esm/cli/lib/run.js.map +2 -2
  243. package/dist/esm/cli/lib/runTestFunction.js +3 -3
  244. package/dist/esm/cli/lib/runTestFunction.js.map +1 -1
  245. package/dist/esm/cli/lib/utils/utils.js +29 -0
  246. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  247. package/dist/esm/cli/program.js +2 -1
  248. package/dist/esm/cli/program.js.map +2 -2
  249. package/dist/esm/cli/project.js +5 -0
  250. package/dist/esm/cli/project.js.map +7 -0
  251. package/dist/esm/cli/projectCreate.js +68 -0
  252. package/dist/esm/cli/projectCreate.js.map +7 -0
  253. package/dist/esm/cli/run.js +5 -5
  254. package/dist/esm/cli/run.js.map +1 -1
  255. package/dist/esm/index.js +1 -1
  256. package/dist/esm/index.js.map +1 -1
  257. package/dist/esm/server/impl/meta_impl.js +6 -6
  258. package/dist/esm/server/impl/meta_impl.js.map +2 -2
  259. package/dist/esm/server/impl/registration_impl.js +9 -3
  260. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  261. package/dist/esm/server/index.js.map +2 -2
  262. package/dist/esm-types/cli/configure.d.ts +3 -2
  263. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  264. package/dist/esm-types/cli/dashboard.d.ts.map +1 -1
  265. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  266. package/dist/esm-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  267. package/dist/esm-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  268. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  269. package/dist/esm-types/cli/env.d.ts.map +1 -1
  270. package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
  271. package/dist/esm-types/cli/insights.d.ts +1 -0
  272. package/dist/esm-types/cli/insights.d.ts.map +1 -1
  273. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
  274. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +16 -16
  275. package/dist/esm-types/cli/lib/deployment.d.ts +0 -2
  276. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  277. package/dist/esm-types/cli/lib/deploymentSelection.d.ts +7 -0
  278. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  279. package/dist/esm-types/cli/lib/dev.d.ts +2 -1
  280. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  281. package/dist/esm-types/cli/lib/env.d.ts +3 -1
  282. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  283. package/dist/esm-types/cli/lib/env.test.d.ts +2 -0
  284. package/dist/esm-types/cli/lib/env.test.d.ts.map +1 -0
  285. package/dist/esm-types/cli/lib/generateDocs.d.ts +20 -0
  286. package/dist/esm-types/cli/lib/generateDocs.d.ts.map +1 -0
  287. package/dist/esm-types/cli/lib/generateDocs.test.d.ts +2 -0
  288. package/dist/esm-types/cli/lib/generateDocs.test.d.ts.map +1 -0
  289. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
  290. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  291. package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
  292. package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
  293. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
  294. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  295. package/dist/esm-types/cli/lib/localDeployment/download.d.ts +11 -1
  296. package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  297. package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
  298. package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
  299. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
  300. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  301. package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts +31 -0
  302. package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
  303. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
  304. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
  305. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
  306. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  307. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +0 -2
  308. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  309. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  310. package/dist/esm-types/cli/lib/logs.d.ts +1 -1
  311. package/dist/esm-types/cli/lib/logs.d.ts.map +1 -1
  312. package/dist/esm-types/cli/lib/run.d.ts +1 -1
  313. package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
  314. package/dist/esm-types/cli/lib/utils/utils.d.ts +10 -0
  315. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  316. package/dist/esm-types/cli/lib/versionApi.d.ts +2 -2
  317. package/dist/esm-types/cli/program.d.ts.map +1 -1
  318. package/dist/esm-types/cli/project.d.ts +3 -0
  319. package/dist/esm-types/cli/project.d.ts.map +1 -0
  320. package/dist/esm-types/cli/projectCreate.d.ts +5 -0
  321. package/dist/esm-types/cli/projectCreate.d.ts.map +1 -0
  322. package/dist/esm-types/index.d.ts +1 -1
  323. package/dist/esm-types/server/database.d.ts +21 -3
  324. package/dist/esm-types/server/database.d.ts.map +1 -1
  325. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -1
  326. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  327. package/dist/esm-types/server/index.d.ts +2 -2
  328. package/dist/esm-types/server/index.d.ts.map +1 -1
  329. package/dist/esm-types/server/meta.d.ts +26 -0
  330. package/dist/esm-types/server/meta.d.ts.map +1 -1
  331. package/dist/esm-types/server/query.d.ts +1 -1
  332. package/dist/esm-types/server/registration.d.ts +23 -5
  333. package/dist/esm-types/server/registration.d.ts.map +1 -1
  334. package/dist/esm-types/server/storage.d.ts +20 -3
  335. package/dist/esm-types/server/storage.d.ts.map +1 -1
  336. package/dist/react.bundle.js +1 -1
  337. package/dist/react.bundle.js.map +1 -1
  338. package/package.json +7 -5
  339. package/src/browser/sync/request_manager.test.ts +2 -2
  340. package/src/cli/aiFiles.ts +2 -2
  341. package/src/cli/configure.ts +4 -6
  342. package/src/cli/convexExport.ts +3 -3
  343. package/src/cli/convexImport.ts +2 -2
  344. package/src/cli/dashboard.ts +29 -3
  345. package/src/cli/data.ts +2 -2
  346. package/src/cli/deploy.ts +5 -5
  347. package/src/cli/deploymentCreate.test.ts +151 -24
  348. package/src/cli/deploymentCreate.ts +21 -11
  349. package/src/cli/deploymentSelect.ts +5 -5
  350. package/src/cli/deploymentSelection.test.ts +0 -3
  351. package/src/cli/deploymentToken.test.ts +34 -23
  352. package/src/cli/deploymentTokenCreate.ts +9 -21
  353. package/src/cli/deploymentTokenDelete.ts +8 -23
  354. package/src/cli/dev.ts +5 -4
  355. package/src/cli/env.ts +29 -19
  356. package/src/cli/envDefault.ts +21 -15
  357. package/src/cli/insights.ts +15 -3
  358. package/src/cli/lib/aiFiles/integration.test.ts +2 -0
  359. package/src/cli/lib/aiFiles/skills.ts +3 -3
  360. package/src/cli/lib/command.ts +2 -2
  361. package/src/cli/lib/deployment.ts +0 -5
  362. package/src/cli/lib/deploymentSelection.ts +67 -0
  363. package/src/cli/lib/dev.ts +39 -0
  364. package/src/cli/lib/env.test.ts +60 -0
  365. package/src/cli/lib/env.ts +9 -1
  366. package/src/cli/lib/generateDocs.test.ts +326 -0
  367. package/src/cli/lib/generateDocs.ts +393 -0
  368. package/src/cli/lib/localDeployment/anonymous.ts +48 -72
  369. package/src/cli/lib/localDeployment/bigBrain.ts +7 -15
  370. package/src/cli/lib/localDeployment/dashboard.ts +48 -80
  371. package/src/cli/lib/localDeployment/download.ts +34 -3
  372. package/src/cli/lib/localDeployment/filePaths.ts +66 -6
  373. package/src/cli/lib/localDeployment/localDeployment.ts +46 -184
  374. package/src/cli/lib/localDeployment/run.test.ts +6 -6
  375. package/src/cli/lib/localDeployment/secrets.test.ts +53 -0
  376. package/src/cli/lib/localDeployment/secrets.ts +93 -0
  377. package/src/cli/lib/localDeployment/tests/keygenFailure.mjs +9 -0
  378. package/src/cli/lib/localDeployment/tests/keygenSuccess.mjs +31 -0
  379. package/src/cli/lib/localDeployment/upgrade.ts +52 -38
  380. package/src/cli/lib/localDeployment/utils.ts +0 -10
  381. package/src/cli/lib/login.ts +18 -18
  382. package/src/cli/lib/logs.ts +7 -2
  383. package/src/cli/lib/run.ts +37 -3
  384. package/src/cli/lib/runTestFunction.ts +3 -3
  385. package/src/cli/lib/utils/utils.ts +56 -0
  386. package/src/cli/program.ts +2 -0
  387. package/src/cli/project.ts +7 -0
  388. package/src/cli/projectCreate.ts +99 -0
  389. package/src/cli/run.ts +5 -5
  390. package/src/index.ts +1 -1
  391. package/src/server/database.ts +21 -3
  392. package/src/server/impl/meta_impl.ts +7 -6
  393. package/src/server/impl/registration_impl.ts +11 -5
  394. package/src/server/index.ts +2 -0
  395. package/src/server/meta.ts +27 -0
  396. package/src/server/query.ts +1 -1
  397. package/src/server/registration.test.ts +16 -25
  398. package/src/server/registration.ts +25 -19
  399. package/src/server/storage.ts +22 -3
  400. package/src/server/system_fields.ts +1 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/localDeployment/secrets.ts"],
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logVerbose } from \"../../../bundler/log.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport crypto from \"crypto\";\n\nexport const LEGACY_LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n\n/**\n * Generates an instance secret and an admin key for a new (or just upgraded) local deployment.\n */\nexport async function generateLocalDevSecrets(\n ctx: Context,\n {\n deploymentName,\n latestBinaryPath,\n }: {\n deploymentName: string;\n /**\n * A path to the local backend binary.\n *\n * This must always be the latest version of the local binary that has been published,\n * in order to make sure the `keygen admin-key` command is available. If you need to call\n * this without having access to the latest binary, use `generateLocalDevSecretsWithLatestBinary`\n * which will download the latest version when necessary.\n */\n latestBinaryPath: string;\n },\n): Promise<{\n instanceSecret: string;\n adminKey: string;\n}> {\n logVerbose(\"Generating local dev secrets\");\n\n const instanceSecret = generateInstanceSecret();\n\n let stdout: string;\n try {\n ({ stdout } = await promisify(execFile)(latestBinaryPath, [\n \"keygen\",\n \"admin-key\",\n \"--instance-name\",\n deploymentName,\n \"--instance-secret\",\n instanceSecret,\n ]));\n } catch (e) {\n const err = e as { stderr?: string; message: string };\n const detail = err.stderr ? err.stderr : err.message;\n const message = `Failed to generate admin key:\\n${detail}`;\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n const adminKey = stdout.trim();\n\n return {\n instanceSecret,\n adminKey,\n };\n}\n\nfunction generateInstanceSecret(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Similar to generateLocalDevSecrets, but can be called when we\u2019re not confident\n * we have a binary that supports `keygen admin-key`\n */\nexport async function generateLocalDevSecretsWithLatestBinary(\n ctx: Context,\n {\n deploymentName,\n }: {\n deploymentName: string;\n },\n) {\n const { binaryPath: latestBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"latest\",\n },\n );\n return generateLocalDevSecrets(ctx, { deploymentName, latestBinaryPath });\n}\n"],
5
+ "mappings": ";AACA,SAAS,kBAAkB;AAC3B,SAAS,qCAAqC;AAC9C,SAAS,4BAA4B;AACrC,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,OAAO,YAAY;AAEZ,aAAM,uCACX;AAKF,sBAAsB,wBACpB,KACA;AAAA,EACE;AAAA,EACA;AACF,GAeC;AACD,aAAW,8BAA8B;AAEzC,QAAM,iBAAiB,uBAAuB;AAE9C,MAAI;AACJ,MAAI;AACF,KAAC,EAAE,OAAO,IAAI,MAAM,UAAU,QAAQ,EAAE,kBAAkB;AAAA,MACxD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,SAAS,IAAI,SAAS,IAAI,SAAS,IAAI;AAC7C,UAAM,UAAU;AAAA,EAAkC,MAAM;AACxD,WAAO,IAAI,MAAM;AAAA,MACf,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,cAAc,IAAI,qBAAqB,OAAO;AAAA,IAChD,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,OAAO,KAAK;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,yBAAiC;AACxC,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AAMA,sBAAsB,wCACpB,KACA;AAAA,EACE;AACF,GAGA;AACA,QAAM,EAAE,YAAY,iBAAiB,IAAI,MAAM;AAAA,IAC7C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,wBAAwB,KAAK,EAAE,gBAAgB,iBAAiB,CAAC;AAC1E;",
6
+ "names": []
7
+ }
@@ -8,7 +8,6 @@ import {
8
8
  import { runSystemQuery } from "../run.js";
9
9
  import {
10
10
  deploymentStateDir,
11
- loadDeploymentConfig,
12
11
  saveDeploymentConfig
13
12
  } from "./filePaths.js";
14
13
  import {
@@ -30,12 +29,28 @@ import { promptOptions, promptYesNo } from "../utils/prompts.js";
30
29
  import { recursivelyDelete } from "../fsUtils.js";
31
30
  import { LocalDeploymentError } from "./errors.js";
32
31
  import { ensureBackendBinaryDownloaded } from "./download.js";
33
- export async function handlePotentialUpgrade(ctx, args) {
32
+ import {
33
+ generateLocalDevSecretsWithLatestBinary,
34
+ LEGACY_LOCAL_BACKEND_INSTANCE_SECRET
35
+ } from "./secrets.js";
36
+ export async function handlePotentialUpgradeAndStart(ctx, args) {
37
+ const { adminKey, instanceSecret } = args.existingCredentials === null || args.existingCredentials.instanceSecret === LEGACY_LOCAL_BACKEND_INSTANCE_SECRET ? (
38
+ // Using `generateLocalDevSecretsFromLatestBinary` instead of `generateLocalDevSecrets`
39
+ // here, because `newBinaryPath` can be a binary that doesn’t support
40
+ // the `keygen admin-key` subcommand (when the --local-backend-version flag is provided to the CLI)
41
+ //
42
+ // In most cases (the user is not using the flag), we have already downloaded the latest binary
43
+ // shortly before in handleLocalDeployment/handleAnonymousDeployment, so this doesn’t cause an
44
+ // extra download (even if the user chooses later not to upgrade their deployment)
45
+ await generateLocalDevSecretsWithLatestBinary(ctx, {
46
+ deploymentName: args.deploymentName
47
+ })
48
+ ) : args.existingCredentials;
34
49
  const newConfig = {
35
50
  ports: args.ports,
36
51
  backendVersion: args.newVersion,
37
- adminKey: args.adminKey,
38
- instanceSecret: args.instanceSecret,
52
+ adminKey,
53
+ instanceSecret,
39
54
  cloudProjectId: args.cloudProjectId
40
55
  };
41
56
  if (args.oldVersion === null || args.oldVersion === args.newVersion) {
@@ -45,14 +60,15 @@ export async function handlePotentialUpgrade(ctx, args) {
45
60
  args.deploymentName,
46
61
  newConfig
47
62
  );
48
- return runLocalBackend(ctx, {
63
+ const { cleanupHandle: cleanupHandle2 } = await runLocalBackend(ctx, {
49
64
  binaryPath: args.newBinaryPath,
50
65
  deploymentKind: args.deploymentKind,
51
66
  deploymentName: args.deploymentName,
52
67
  ports: args.ports,
53
- instanceSecret: args.instanceSecret,
68
+ instanceSecret,
54
69
  isLatestVersion: true
55
70
  });
71
+ return { cleanupHandle: cleanupHandle2, adminKey };
56
72
  }
57
73
  logVerbose(
58
74
  `Considering upgrade from ${args.oldVersion} to ${args.newVersion}`
@@ -73,14 +89,15 @@ export async function handlePotentialUpgrade(ctx, args) {
73
89
  ...newConfig,
74
90
  backendVersion: args.oldVersion
75
91
  });
76
- return runLocalBackend(ctx, {
92
+ const { cleanupHandle: cleanupHandle2 } = await runLocalBackend(ctx, {
77
93
  binaryPath: oldBinaryPath,
78
94
  ports: args.ports,
79
95
  deploymentKind: args.deploymentKind,
80
96
  deploymentName: args.deploymentName,
81
- instanceSecret: args.instanceSecret,
97
+ instanceSecret,
82
98
  isLatestVersion: false
83
99
  });
100
+ return { cleanupHandle: cleanupHandle2, adminKey };
84
101
  }
85
102
  const choice = args.forceUpgrade || !process.stdin.isTTY ? "transfer" : await promptOptions(ctx, {
86
103
  message: "Transfer data from existing deployment?",
@@ -103,31 +120,31 @@ export async function handlePotentialUpgrade(ctx, args) {
103
120
  args.deploymentName,
104
121
  newConfig
105
122
  );
106
- return runLocalBackend(ctx, {
123
+ const { cleanupHandle: cleanupHandle2 } = await runLocalBackend(ctx, {
107
124
  binaryPath: args.newBinaryPath,
108
125
  deploymentKind: args.deploymentKind,
109
126
  deploymentName: args.deploymentName,
110
127
  ports: args.ports,
111
- instanceSecret: args.instanceSecret,
128
+ instanceSecret,
112
129
  isLatestVersion: true
113
130
  });
131
+ return { cleanupHandle: cleanupHandle2, adminKey };
114
132
  }
115
- const newAdminKey = args.adminKey;
116
- const oldAdminKey = loadDeploymentConfig(ctx, args.deploymentKind, args.deploymentName)?.adminKey ?? args.adminKey;
117
- return handleUpgrade(ctx, {
133
+ const { cleanupHandle } = await handleUpgrade(ctx, {
118
134
  deploymentKind: args.deploymentKind,
119
135
  deploymentName: args.deploymentName,
120
136
  oldVersion: args.oldVersion,
121
137
  newBinaryPath: args.newBinaryPath,
122
138
  newVersion: args.newVersion,
123
139
  ports: args.ports,
124
- oldAdminKey,
125
- newAdminKey,
126
- instanceSecret: args.instanceSecret,
140
+ adminKey,
141
+ instanceSecret,
127
142
  cloudProjectId: args.cloudProjectId
128
143
  });
144
+ return { cleanupHandle, adminKey };
129
145
  }
130
146
  async function handleUpgrade(ctx, args) {
147
+ const { adminKey } = args;
131
148
  const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(
132
149
  ctx,
133
150
  {
@@ -148,7 +165,7 @@ async function handleUpgrade(ctx, args) {
148
165
  const deploymentUrl = localDeploymentUrl(args.ports.cloud);
149
166
  const envs = await runSystemQuery(ctx, {
150
167
  deploymentUrl,
151
- adminKey: args.oldAdminKey,
168
+ adminKey,
152
169
  functionName: "_system/cli/queryEnvironmentVariables",
153
170
  componentPath: void 0,
154
171
  args: {}
@@ -161,13 +178,13 @@ async function handleUpgrade(ctx, args) {
161
178
  if (ctx.fs.exists(exportPath)) {
162
179
  ctx.fs.unlink(exportPath);
163
180
  }
164
- const snaphsotExportState = await startSnapshotExport(ctx, {
181
+ const snapshotExportState = await startSnapshotExport(ctx, {
165
182
  deploymentUrl,
166
- adminKey: args.oldAdminKey,
183
+ adminKey,
167
184
  includeStorage: true,
168
185
  inputPath: exportPath
169
186
  });
170
- if (snaphsotExportState.state !== "completed") {
187
+ if (snapshotExportState.state !== "completed") {
171
188
  return ctx.crash({
172
189
  exitCode: 1,
173
190
  errorType: "fatal",
@@ -175,9 +192,9 @@ async function handleUpgrade(ctx, args) {
175
192
  });
176
193
  }
177
194
  await downloadSnapshotExport(ctx, {
178
- snapshotExportTs: snaphsotExportState.start_ts,
195
+ snapshotExportTs: snapshotExportState.start_ts,
179
196
  inputPath: exportPath,
180
- adminKey: args.oldAdminKey,
197
+ adminKey,
181
198
  deploymentUrl
182
199
  });
183
200
  logVerbose("Stopping the backend on the old version");
@@ -204,7 +221,7 @@ async function handleUpgrade(ctx, args) {
204
221
  if (envs.length > 0) {
205
222
  const fetch = deploymentFetch(ctx, {
206
223
  deploymentUrl,
207
- adminKey: args.newAdminKey
224
+ adminKey
208
225
  });
209
226
  try {
210
227
  await fetch("/api/update_environment_variables", {
@@ -218,7 +235,7 @@ async function handleUpgrade(ctx, args) {
218
235
  logVerbose("Doing a snapshot import");
219
236
  const importId = await uploadForImport(ctx, {
220
237
  deploymentUrl,
221
- adminKey: args.newAdminKey,
238
+ adminKey,
222
239
  filePath: exportPath,
223
240
  importArgs: { format: "zip", mode: "replace", tableName: void 0 },
224
241
  onImportFailed: async (e) => {
@@ -229,7 +246,7 @@ async function handleUpgrade(ctx, args) {
229
246
  let status = await waitForStableImportState(ctx, {
230
247
  importId,
231
248
  deploymentUrl,
232
- adminKey: args.newAdminKey,
249
+ adminKey,
233
250
  onProgress: () => {
234
251
  return 0;
235
252
  }
@@ -245,7 +262,7 @@ async function handleUpgrade(ctx, args) {
245
262
  }
246
263
  await confirmImport(ctx, {
247
264
  importId,
248
- adminKey: args.newAdminKey,
265
+ adminKey,
249
266
  deploymentUrl,
250
267
  onError: async (e) => {
251
268
  logFailure(`Failed to confirm import: ${e}`);
@@ -255,7 +272,7 @@ async function handleUpgrade(ctx, args) {
255
272
  status = await waitForStableImportState(ctx, {
256
273
  importId,
257
274
  deploymentUrl,
258
- adminKey: args.newAdminKey,
275
+ adminKey,
259
276
  onProgress: () => {
260
277
  return 0;
261
278
  }
@@ -274,7 +291,7 @@ async function handleUpgrade(ctx, args) {
274
291
  saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {
275
292
  ports: args.ports,
276
293
  backendVersion: args.newVersion,
277
- adminKey: args.newAdminKey,
294
+ adminKey,
278
295
  instanceSecret: args.instanceSecret,
279
296
  cloudProjectId: args.cloudProjectId
280
297
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/upgrade.ts"],
4
- "sourcesContent": ["import path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logVerbose,\n} from \"../../../bundler/log.js\";\nimport { runSystemQuery } from \"../run.js\";\nimport {\n LocalDeploymentConfig,\n LocalDeploymentKind,\n deploymentStateDir,\n loadDeploymentConfig,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport {\n ensureBackendStopped,\n localDeploymentUrl,\n runLocalBackend,\n} from \"./run.js\";\nimport {\n downloadSnapshotExport,\n startSnapshotExport,\n} from \"../convexExport.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"../utils/utils.js\";\nimport {\n confirmImport,\n uploadForImport,\n waitForStableImportState,\n} from \"../convexImport.js\";\nimport { promptOptions, promptYesNo } from \"../utils/prompts.js\";\nimport { recursivelyDelete } from \"../fsUtils.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nexport async function handlePotentialUpgrade(\n ctx: Context,\n args: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n oldVersion: string | null;\n newBinaryPath: string;\n newVersion: string;\n ports: {\n cloud: number;\n site: number;\n };\n adminKey: string;\n instanceSecret: string;\n forceUpgrade: boolean;\n cloudProjectId: number | undefined;\n },\n): Promise<{ cleanupHandle: string }> {\n const newConfig: LocalDeploymentConfig = {\n ports: args.ports,\n backendVersion: args.newVersion,\n adminKey: args.adminKey,\n instanceSecret: args.instanceSecret,\n cloudProjectId: args.cloudProjectId,\n };\n if (args.oldVersion === null || args.oldVersion === args.newVersion) {\n // No upgrade needed. Save the current config and start running the backend.\n saveDeploymentConfig(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n newConfig,\n );\n return runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n ports: args.ports,\n instanceSecret: args.instanceSecret,\n isLatestVersion: true,\n });\n }\n logVerbose(\n `Considering upgrade from ${args.oldVersion} to ${args.newVersion}`,\n );\n const confirmed =\n args.forceUpgrade ||\n !process.stdin.isTTY ||\n (await promptYesNo(ctx, {\n message: `This deployment is using an older version of the Convex backend. Upgrade now?`,\n default: true,\n }));\n if (!confirmed) {\n const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"version\",\n version: args.oldVersion,\n },\n );\n // Skipping upgrade, save the config with the old version and run.\n saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {\n ...newConfig,\n backendVersion: args.oldVersion,\n });\n return runLocalBackend(ctx, {\n binaryPath: oldBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret: args.instanceSecret,\n isLatestVersion: false,\n });\n }\n const choice =\n args.forceUpgrade || !process.stdin.isTTY\n ? \"transfer\"\n : await promptOptions(ctx, {\n message: \"Transfer data from existing deployment?\",\n default: \"transfer\",\n choices: [\n { name: \"transfer data\", value: \"transfer\" },\n { name: \"start fresh\", value: \"reset\" },\n ],\n });\n const deploymentStatePath = deploymentStateDir(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n );\n if (choice === \"reset\") {\n recursivelyDelete(ctx, deploymentStatePath, { force: true });\n saveDeploymentConfig(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n newConfig,\n );\n return runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n ports: args.ports,\n instanceSecret: args.instanceSecret,\n isLatestVersion: true,\n });\n }\n const newAdminKey = args.adminKey;\n const oldAdminKey =\n loadDeploymentConfig(ctx, args.deploymentKind, args.deploymentName)\n ?.adminKey ?? args.adminKey;\n return handleUpgrade(ctx, {\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n oldVersion: args.oldVersion!,\n newBinaryPath: args.newBinaryPath,\n newVersion: args.newVersion,\n ports: args.ports,\n oldAdminKey,\n newAdminKey,\n instanceSecret: args.instanceSecret,\n cloudProjectId: args.cloudProjectId,\n });\n}\n\nasync function handleUpgrade(\n ctx: Context,\n args: {\n deploymentName: string;\n deploymentKind: LocalDeploymentKind;\n oldVersion: string;\n newBinaryPath: string;\n newVersion: string;\n ports: {\n cloud: number;\n site: number;\n };\n // In most of the cases the admin key is the same for the old and new version.\n // This is helpful when we start generating new admin key formats that might\n // be incompatible with older backend versions.\n oldAdminKey: string;\n newAdminKey: string;\n instanceSecret: string;\n cloudProjectId: number | undefined;\n },\n): Promise<{ cleanupHandle: string }> {\n const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"version\",\n version: args.oldVersion,\n },\n );\n\n logVerbose(\"Running backend on old version\");\n const { cleanupHandle: oldCleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: oldBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret: args.instanceSecret,\n isLatestVersion: false,\n });\n\n logVerbose(\"Downloading env vars\");\n const deploymentUrl = localDeploymentUrl(args.ports.cloud);\n const envs = (await runSystemQuery(ctx, {\n deploymentUrl,\n adminKey: args.oldAdminKey,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as Array<{\n name: string;\n value: string;\n }>;\n\n logVerbose(\"Doing a snapshot export\");\n const exportPath = path.join(\n deploymentStateDir(ctx, args.deploymentKind, args.deploymentName),\n \"export.zip\",\n );\n if (ctx.fs.exists(exportPath)) {\n ctx.fs.unlink(exportPath);\n }\n const snaphsotExportState = await startSnapshotExport(ctx, {\n deploymentUrl,\n adminKey: args.oldAdminKey,\n includeStorage: true,\n inputPath: exportPath,\n });\n if (snaphsotExportState.state !== \"completed\") {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Failed to export snapshot\",\n });\n }\n await downloadSnapshotExport(ctx, {\n snapshotExportTs: snaphsotExportState.start_ts,\n inputPath: exportPath,\n adminKey: args.oldAdminKey,\n deploymentUrl,\n });\n\n logVerbose(\"Stopping the backend on the old version\");\n const oldCleanupFunc = ctx.removeCleanup(oldCleanupHandle);\n if (oldCleanupFunc) {\n await oldCleanupFunc(0);\n }\n await ensureBackendStopped(ctx, {\n ports: args.ports,\n maxTimeSecs: 5,\n deploymentName: args.deploymentName,\n allowOtherDeployments: false,\n });\n\n // TODO(ENG-7078) save old artifacts to backup files\n logVerbose(\"Running backend on new version\");\n const { cleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret: args.instanceSecret,\n isLatestVersion: true,\n });\n\n logVerbose(\"Importing the env vars\");\n if (envs.length > 0) {\n const fetch = deploymentFetch(ctx, {\n deploymentUrl,\n adminKey: args.newAdminKey,\n });\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes: envs }),\n method: \"POST\",\n });\n } catch (e) {\n // TODO: this should ideally have a `LocalDeploymentError`\n return await logAndHandleFetchError(ctx, e);\n }\n }\n\n logVerbose(\"Doing a snapshot import\");\n const importId = await uploadForImport(ctx, {\n deploymentUrl,\n adminKey: args.newAdminKey,\n filePath: exportPath,\n importArgs: { format: \"zip\", mode: \"replace\", tableName: undefined },\n onImportFailed: async (e) => {\n logFailure(`Failed to import snapshot: ${e}`);\n },\n });\n logVerbose(`Snapshot import started`);\n let status = await waitForStableImportState(ctx, {\n importId,\n deploymentUrl,\n adminKey: args.newAdminKey,\n onProgress: () => {\n // do nothing for now\n return 0;\n },\n });\n if (status.state !== \"waiting_for_confirmation\") {\n const message = \"Error while transferring data: Failed to upload snapshot\";\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n await confirmImport(ctx, {\n importId,\n adminKey: args.newAdminKey,\n deploymentUrl,\n onError: async (e) => {\n logFailure(`Failed to confirm import: ${e}`);\n },\n });\n logVerbose(`Snapshot import confirmed`);\n status = await waitForStableImportState(ctx, {\n importId,\n deploymentUrl,\n adminKey: args.newAdminKey,\n onProgress: () => {\n // do nothing for now\n return 0;\n },\n });\n logVerbose(`Snapshot import status: ${status.state}`);\n if (status.state !== \"completed\") {\n const message = \"Error while transferring data: Failed to import snapshot\";\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n logFinishedStep(\"Successfully upgraded to a new backend version\");\n saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {\n ports: args.ports,\n backendVersion: args.newVersion,\n adminKey: args.newAdminKey,\n instanceSecret: args.instanceSecret,\n cloudProjectId: args.cloudProjectId,\n });\n\n return { cleanupHandle };\n}\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["import path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logVerbose,\n} from \"../../../bundler/log.js\";\nimport { runSystemQuery } from \"../run.js\";\nimport {\n LocalDeploymentConfig,\n LocalDeploymentKind,\n deploymentStateDir,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport {\n ensureBackendStopped,\n localDeploymentUrl,\n runLocalBackend,\n} from \"./run.js\";\nimport {\n downloadSnapshotExport,\n startSnapshotExport,\n} from \"../convexExport.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"../utils/utils.js\";\nimport {\n confirmImport,\n uploadForImport,\n waitForStableImportState,\n} from \"../convexImport.js\";\nimport { promptOptions, promptYesNo } from \"../utils/prompts.js\";\nimport { recursivelyDelete } from \"../fsUtils.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport {\n generateLocalDevSecretsWithLatestBinary,\n LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./secrets.js\";\n\nexport async function handlePotentialUpgradeAndStart(\n ctx: Context,\n args: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n oldVersion: string | null;\n newBinaryPath: string;\n newVersion: string;\n ports: {\n cloud: number;\n site: number;\n };\n existingCredentials: { adminKey: string; instanceSecret: string } | null;\n forceUpgrade: boolean;\n cloudProjectId: number | undefined;\n },\n): Promise<{ cleanupHandle: string; adminKey: string }> {\n const { adminKey, instanceSecret } =\n args.existingCredentials === null ||\n args.existingCredentials.instanceSecret ===\n LEGACY_LOCAL_BACKEND_INSTANCE_SECRET\n ? // Using `generateLocalDevSecretsFromLatestBinary` instead of `generateLocalDevSecrets`\n // here, because `newBinaryPath` can be a binary that doesn\u2019t support\n // the `keygen admin-key` subcommand (when the --local-backend-version flag is provided to the CLI)\n //\n // In most cases (the user is not using the flag), we have already downloaded the latest binary\n // shortly before in handleLocalDeployment/handleAnonymousDeployment, so this doesn\u2019t cause an\n // extra download (even if the user chooses later not to upgrade their deployment)\n await generateLocalDevSecretsWithLatestBinary(ctx, {\n deploymentName: args.deploymentName,\n })\n : args.existingCredentials;\n const newConfig: LocalDeploymentConfig = {\n ports: args.ports,\n backendVersion: args.newVersion,\n adminKey,\n instanceSecret,\n cloudProjectId: args.cloudProjectId,\n };\n if (args.oldVersion === null || args.oldVersion === args.newVersion) {\n // No upgrade needed. Save the current config and start running the backend.\n saveDeploymentConfig(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n newConfig,\n );\n const { cleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n ports: args.ports,\n instanceSecret,\n isLatestVersion: true,\n });\n return { cleanupHandle, adminKey };\n }\n logVerbose(\n `Considering upgrade from ${args.oldVersion} to ${args.newVersion}`,\n );\n const confirmed =\n args.forceUpgrade ||\n !process.stdin.isTTY ||\n (await promptYesNo(ctx, {\n message: `This deployment is using an older version of the Convex backend. Upgrade now?`,\n default: true,\n }));\n if (!confirmed) {\n const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"version\",\n version: args.oldVersion,\n },\n );\n // Skipping upgrade, save the config with the old version and run.\n saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {\n ...newConfig,\n backendVersion: args.oldVersion,\n });\n const { cleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: oldBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret,\n isLatestVersion: false,\n });\n return { cleanupHandle, adminKey };\n }\n const choice =\n args.forceUpgrade || !process.stdin.isTTY\n ? \"transfer\"\n : await promptOptions(ctx, {\n message: \"Transfer data from existing deployment?\",\n default: \"transfer\",\n choices: [\n { name: \"transfer data\", value: \"transfer\" },\n { name: \"start fresh\", value: \"reset\" },\n ],\n });\n const deploymentStatePath = deploymentStateDir(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n );\n if (choice === \"reset\") {\n recursivelyDelete(ctx, deploymentStatePath, { force: true });\n saveDeploymentConfig(\n ctx,\n args.deploymentKind,\n args.deploymentName,\n newConfig,\n );\n const { cleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n ports: args.ports,\n instanceSecret,\n isLatestVersion: true,\n });\n return { cleanupHandle, adminKey };\n }\n const { cleanupHandle } = await handleUpgrade(ctx, {\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n oldVersion: args.oldVersion!,\n newBinaryPath: args.newBinaryPath,\n newVersion: args.newVersion,\n ports: args.ports,\n adminKey,\n instanceSecret,\n cloudProjectId: args.cloudProjectId,\n });\n return { cleanupHandle, adminKey };\n}\n\nasync function handleUpgrade(\n ctx: Context,\n args: {\n deploymentName: string;\n deploymentKind: LocalDeploymentKind;\n oldVersion: string;\n newBinaryPath: string;\n newVersion: string;\n ports: {\n cloud: number;\n site: number;\n };\n instanceSecret: string;\n adminKey: string;\n cloudProjectId: number | undefined;\n },\n): Promise<{ cleanupHandle: string }> {\n const { adminKey } = args;\n const { binaryPath: oldBinaryPath } = await ensureBackendBinaryDownloaded(\n ctx,\n {\n kind: \"version\",\n version: args.oldVersion,\n },\n );\n\n logVerbose(\"Running backend on old version\");\n const { cleanupHandle: oldCleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: oldBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret: args.instanceSecret,\n isLatestVersion: false,\n });\n\n logVerbose(\"Downloading env vars\");\n const deploymentUrl = localDeploymentUrl(args.ports.cloud);\n const envs = (await runSystemQuery(ctx, {\n deploymentUrl,\n adminKey,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as Array<{\n name: string;\n value: string;\n }>;\n\n logVerbose(\"Doing a snapshot export\");\n const exportPath = path.join(\n deploymentStateDir(ctx, args.deploymentKind, args.deploymentName),\n \"export.zip\",\n );\n if (ctx.fs.exists(exportPath)) {\n ctx.fs.unlink(exportPath);\n }\n const snapshotExportState = await startSnapshotExport(ctx, {\n deploymentUrl,\n adminKey,\n includeStorage: true,\n inputPath: exportPath,\n });\n if (snapshotExportState.state !== \"completed\") {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Failed to export snapshot\",\n });\n }\n await downloadSnapshotExport(ctx, {\n snapshotExportTs: snapshotExportState.start_ts,\n inputPath: exportPath,\n adminKey,\n deploymentUrl,\n });\n\n logVerbose(\"Stopping the backend on the old version\");\n const oldCleanupFunc = ctx.removeCleanup(oldCleanupHandle);\n if (oldCleanupFunc) {\n await oldCleanupFunc(0);\n }\n await ensureBackendStopped(ctx, {\n ports: args.ports,\n maxTimeSecs: 5,\n deploymentName: args.deploymentName,\n allowOtherDeployments: false,\n });\n\n // TODO(ENG-7078) save old artifacts to backup files\n logVerbose(\"Running backend on new version\");\n const { cleanupHandle } = await runLocalBackend(ctx, {\n binaryPath: args.newBinaryPath,\n ports: args.ports,\n deploymentKind: args.deploymentKind,\n deploymentName: args.deploymentName,\n instanceSecret: args.instanceSecret,\n isLatestVersion: true,\n });\n\n logVerbose(\"Importing the env vars\");\n if (envs.length > 0) {\n const fetch = deploymentFetch(ctx, {\n deploymentUrl,\n adminKey,\n });\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes: envs }),\n method: \"POST\",\n });\n } catch (e) {\n // TODO: this should ideally have a `LocalDeploymentError`\n return await logAndHandleFetchError(ctx, e);\n }\n }\n\n logVerbose(\"Doing a snapshot import\");\n const importId = await uploadForImport(ctx, {\n deploymentUrl,\n adminKey,\n filePath: exportPath,\n importArgs: { format: \"zip\", mode: \"replace\", tableName: undefined },\n onImportFailed: async (e) => {\n logFailure(`Failed to import snapshot: ${e}`);\n },\n });\n logVerbose(`Snapshot import started`);\n let status = await waitForStableImportState(ctx, {\n importId,\n deploymentUrl,\n adminKey,\n onProgress: () => {\n // do nothing for now\n return 0;\n },\n });\n if (status.state !== \"waiting_for_confirmation\") {\n const message = \"Error while transferring data: Failed to upload snapshot\";\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n await confirmImport(ctx, {\n importId,\n adminKey,\n deploymentUrl,\n onError: async (e) => {\n logFailure(`Failed to confirm import: ${e}`);\n },\n });\n logVerbose(`Snapshot import confirmed`);\n status = await waitForStableImportState(ctx, {\n importId,\n deploymentUrl,\n adminKey,\n onProgress: () => {\n // do nothing for now\n return 0;\n },\n });\n logVerbose(`Snapshot import status: ${status.state}`);\n if (status.state !== \"completed\") {\n const message = \"Error while transferring data: Failed to import snapshot\";\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: new LocalDeploymentError(message),\n });\n }\n\n logFinishedStep(\"Successfully upgraded to a new backend version\");\n saveDeploymentConfig(ctx, args.deploymentKind, args.deploymentName, {\n ports: args.ports,\n backendVersion: args.newVersion,\n adminKey,\n instanceSecret: args.instanceSecret,\n cloudProjectId: args.cloudProjectId,\n });\n\n return { cleanupHandle };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["cleanupHandle"]
7
7
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  import { logMessage } from "../../../bundler/log.js";
3
3
  import { detect } from "detect-port";
4
- import crypto from "crypto";
5
4
  import { chalkStderr } from "chalk";
6
5
  export async function choosePorts(ctx, {
7
6
  count,
@@ -54,9 +53,6 @@ export async function chooseLocalBackendPorts(ctx, options) {
54
53
  });
55
54
  return { cloudPort, sitePort };
56
55
  }
57
- export async function isOffline() {
58
- return false;
59
- }
60
56
  export function printLocalDeploymentWelcomeMessage() {
61
57
  logMessage(
62
58
  chalkStderr.cyan("You're trying out the beta local deployment feature!")
@@ -67,8 +63,5 @@ export function printLocalDeploymentWelcomeMessage() {
67
63
  )
68
64
  );
69
65
  }
70
- export function generateInstanceSecret() {
71
- return crypto.randomBytes(32).toString("hex");
72
- }
73
66
  export const LOCAL_BACKEND_INSTANCE_SECRET = "4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974";
74
67
  //# sourceMappingURL=utils.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/utils.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { detect } from \"detect-port\";\nimport crypto from \"crypto\";\nimport { chalkStderr } from \"chalk\";\n\nexport async function choosePorts(\n ctx: Context,\n {\n count,\n requestedPorts,\n suggestedPorts,\n startPort,\n }: {\n count: number;\n /** Ports that must mandatorily be used when provided. */\n requestedPorts?: Array<number | null>;\n /** Ports that will be tried preferentially when provided, but are not required. */\n suggestedPorts?: Array<number | null>;\n startPort: number;\n },\n): Promise<Array<number>> {\n const ports: Array<number> = [];\n for (let i = 0; i < count; i++) {\n const requestedPort = requestedPorts?.[i];\n if (requestedPort !== null) {\n const port = await detect(requestedPort);\n if (port !== requestedPort) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Requested port ${requestedPort} is not available`,\n });\n }\n ports.push(port);\n } else {\n const suggestedPort = suggestedPorts?.[ports.length] ?? null;\n if (suggestedPort !== null) {\n const port = await detect(suggestedPort);\n if (port === suggestedPort) {\n ports.push(suggestedPort);\n continue;\n }\n }\n\n const portToTry =\n ports.length > 0 ? ports[ports.length - 1] + 1 : startPort;\n const port = await detect(portToTry);\n ports.push(port);\n }\n }\n return ports;\n}\n\nexport async function chooseLocalBackendPorts(\n ctx: Context,\n options?: {\n suggestedPorts?:\n | { cloud?: number | undefined; site?: number | undefined }\n | undefined;\n requestedPorts?:\n | { cloud?: number | undefined; site?: number | undefined }\n | undefined;\n },\n): Promise<{ cloudPort: number; sitePort: number }> {\n const { suggestedPorts, requestedPorts } = options ?? {};\n\n const [cloudPort, sitePort] = await choosePorts(ctx, {\n count: 2,\n startPort: 3210,\n requestedPorts: [\n requestedPorts?.cloud ?? null,\n requestedPorts?.site ?? null,\n ],\n suggestedPorts: [\n suggestedPorts?.cloud ?? null,\n suggestedPorts?.site ?? null,\n ],\n });\n return { cloudPort, sitePort };\n}\n\nexport async function isOffline(): Promise<boolean> {\n // TODO(ENG-7080) -- implement this for real\n return false;\n}\n\nexport function printLocalDeploymentWelcomeMessage() {\n logMessage(\n chalkStderr.cyan(\"You're trying out the beta local deployment feature!\"),\n );\n logMessage(\n chalkStderr.cyan(\n \"To learn more, read the docs: https://docs.convex.dev/cli/local-deployments\",\n ),\n );\n}\n\nexport function generateInstanceSecret(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\nexport const LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n"],
5
- "mappings": ";AACA,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AACvB,OAAO,YAAY;AACnB,SAAS,mBAAmB;AAE5B,sBAAsB,YACpB,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQwB;AACxB,QAAM,QAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,gBAAgB,iBAAiB,CAAC;AACxC,QAAI,kBAAkB,MAAM;AAC1B,YAAM,OAAO,MAAM,OAAO,aAAa;AACvC,UAAI,SAAS,eAAe;AAC1B,eAAO,IAAI,MAAM;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,kBAAkB,aAAa;AAAA,QACjD,CAAC;AAAA,MACH;AACA,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,YAAM,gBAAgB,iBAAiB,MAAM,MAAM,KAAK;AACxD,UAAI,kBAAkB,MAAM;AAC1B,cAAMA,QAAO,MAAM,OAAO,aAAa;AACvC,YAAIA,UAAS,eAAe;AAC1B,gBAAM,KAAK,aAAa;AACxB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YACJ,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI;AACnD,YAAM,OAAO,MAAM,OAAO,SAAS;AACnC,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,sBAAsB,wBACpB,KACA,SAQkD;AAClD,QAAM,EAAE,gBAAgB,eAAe,IAAI,WAAW,CAAC;AAEvD,QAAM,CAAC,WAAW,QAAQ,IAAI,MAAM,YAAY,KAAK;AAAA,IACnD,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,IACA,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF,CAAC;AACD,SAAO,EAAE,WAAW,SAAS;AAC/B;AAEA,sBAAsB,YAA8B;AAElD,SAAO;AACT;AAEO,gBAAS,qCAAqC;AACnD;AAAA,IACE,YAAY,KAAK,sDAAsD;AAAA,EACzE;AACA;AAAA,IACE,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,gBAAS,yBAAiC;AAC/C,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AAEO,aAAM,gCACX;",
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { detect } from \"detect-port\";\nimport { chalkStderr } from \"chalk\";\n\nexport async function choosePorts(\n ctx: Context,\n {\n count,\n requestedPorts,\n suggestedPorts,\n startPort,\n }: {\n count: number;\n /** Ports that must mandatorily be used when provided. */\n requestedPorts?: Array<number | null>;\n /** Ports that will be tried preferentially when provided, but are not required. */\n suggestedPorts?: Array<number | null>;\n startPort: number;\n },\n): Promise<Array<number>> {\n const ports: Array<number> = [];\n for (let i = 0; i < count; i++) {\n const requestedPort = requestedPorts?.[i];\n if (requestedPort !== null) {\n const port = await detect(requestedPort);\n if (port !== requestedPort) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Requested port ${requestedPort} is not available`,\n });\n }\n ports.push(port);\n } else {\n const suggestedPort = suggestedPorts?.[ports.length] ?? null;\n if (suggestedPort !== null) {\n const port = await detect(suggestedPort);\n if (port === suggestedPort) {\n ports.push(suggestedPort);\n continue;\n }\n }\n\n const portToTry =\n ports.length > 0 ? ports[ports.length - 1] + 1 : startPort;\n const port = await detect(portToTry);\n ports.push(port);\n }\n }\n return ports;\n}\n\nexport async function chooseLocalBackendPorts(\n ctx: Context,\n options?: {\n suggestedPorts?:\n | { cloud?: number | undefined; site?: number | undefined }\n | undefined;\n requestedPorts?:\n | { cloud?: number | undefined; site?: number | undefined }\n | undefined;\n },\n): Promise<{ cloudPort: number; sitePort: number }> {\n const { suggestedPorts, requestedPorts } = options ?? {};\n\n const [cloudPort, sitePort] = await choosePorts(ctx, {\n count: 2,\n startPort: 3210,\n requestedPorts: [\n requestedPorts?.cloud ?? null,\n requestedPorts?.site ?? null,\n ],\n suggestedPorts: [\n suggestedPorts?.cloud ?? null,\n suggestedPorts?.site ?? null,\n ],\n });\n return { cloudPort, sitePort };\n}\n\nexport function printLocalDeploymentWelcomeMessage() {\n logMessage(\n chalkStderr.cyan(\"You're trying out the beta local deployment feature!\"),\n );\n logMessage(\n chalkStderr.cyan(\n \"To learn more, read the docs: https://docs.convex.dev/cli/local-deployments\",\n ),\n );\n}\n\nexport const LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n"],
5
+ "mappings": ";AACA,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAE5B,sBAAsB,YACpB,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQwB;AACxB,QAAM,QAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,gBAAgB,iBAAiB,CAAC;AACxC,QAAI,kBAAkB,MAAM;AAC1B,YAAM,OAAO,MAAM,OAAO,aAAa;AACvC,UAAI,SAAS,eAAe;AAC1B,eAAO,IAAI,MAAM;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,kBAAkB,aAAa;AAAA,QACjD,CAAC;AAAA,MACH;AACA,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,YAAM,gBAAgB,iBAAiB,MAAM,MAAM,KAAK;AACxD,UAAI,kBAAkB,MAAM;AAC1B,cAAMA,QAAO,MAAM,OAAO,aAAa;AACvC,YAAIA,UAAS,eAAe;AAC1B,gBAAM,KAAK,aAAa;AACxB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YACJ,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI;AACnD,YAAM,OAAO,MAAM,OAAO,SAAS;AACnC,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,sBAAsB,wBACpB,KACA,SAQkD;AAClD,QAAM,EAAE,gBAAgB,eAAe,IAAI,WAAW,CAAC;AAEvD,QAAM,CAAC,WAAW,QAAQ,IAAI,MAAM,YAAY,KAAK;AAAA,IACnD,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,IACA,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF,CAAC;AACD,SAAO,EAAE,WAAW,SAAS;AAC/B;AAEO,gBAAS,qCAAqC;AACnD;AAAA,IACE,YAAY,KAAK,sDAAsD;AAAA,EACzE;AACA;AAAA,IACE,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,aAAM,gCACX;",
6
6
  "names": ["port"]
7
7
  }
@@ -5,7 +5,8 @@ import {
5
5
  bigBrainFetch,
6
6
  logAndHandleFetchError,
7
7
  throwingFetch,
8
- isWebContainer
8
+ isWebContainer,
9
+ typedPlatformClient
9
10
  } from "./utils/utils.js";
10
11
  import open from "open";
11
12
  import { chalkStderr } from "chalk";
@@ -268,18 +269,22 @@ export async function performLogin(ctx, {
268
269
  printedMessage: null
269
270
  });
270
271
  }
271
- const authorizeArgs = {
272
- authnToken: accessToken,
273
- deviceName,
274
- anonymousId
275
- };
276
- const data = await bigBrainAPI({
277
- ctx,
278
- method: "POST",
279
- path: "authorize",
280
- data: authorizeArgs
272
+ ctx._updateBigBrainAuth({
273
+ accessToken,
274
+ kind: "accessToken",
275
+ header: `Bearer ${accessToken}`
281
276
  });
282
- const globalConfig = { accessToken: data.accessToken };
277
+ const response = await typedPlatformClient(ctx).POST(
278
+ "/create_personal_access_token",
279
+ {
280
+ // `anonymousId` links a prior anonymous session to this account. It's
281
+ // intentionally absent from the generated platform API types,
282
+ // so cast to pass it through.
283
+ body: { name: deviceName, anonymousId }
284
+ }
285
+ );
286
+ const newAccessToken = response.data.accessToken;
287
+ const globalConfig = { accessToken: newAccessToken };
283
288
  try {
284
289
  await modifyGlobalConfig(ctx, globalConfig);
285
290
  const path = globalConfigPath();
@@ -293,7 +298,7 @@ export async function performLogin(ctx, {
293
298
  });
294
299
  }
295
300
  logVerbose(`performLogin: updating big brain auth after login`);
296
- await updateBigBrainAuthAfterLogin(ctx, data.accessToken);
301
+ await updateBigBrainAuthAfterLogin(ctx, newAccessToken);
297
302
  logVerbose(`performLogin: checking opt ins, acceptOptIns: ${acceptOptIns}`);
298
303
  const shouldContinue = await optins(ctx, acceptOptIns ?? false);
299
304
  if (!shouldContinue) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/login.ts"],
4
- "sourcesContent": ["import { errors, BaseClient, custom } from \"openid-client\";\nimport {\n bigBrainAPI,\n bigBrainFetch,\n logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\n} from \"./utils/utils.js\";\nimport open from \"open\";\nimport { chalkStderr } from \"chalk\";\nimport { provisionHost } from \"./config.js\";\nimport { version } from \"../version.js\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logError,\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n logVerbose,\n showSpinner,\n} from \"../../bundler/log.js\";\nimport { Issuer } from \"openid-client\";\nimport { hostname } from \"os\";\nimport { execSync } from \"child_process\";\nimport { promptString, promptYesNo } from \"./utils/prompts.js\";\nimport {\n formatPathForPrinting,\n globalConfigPath,\n modifyGlobalConfig,\n} from \"./utils/globalConfig.js\";\nimport { updateBigBrainAuthAfterLogin } from \"./deploymentSelection.js\";\n\n// Per https://github.com/panva/node-openid-client/tree/main/docs#customizing\ncustom.setHttpOptionsDefaults({\n timeout: parseInt(process.env.OPENID_CLIENT_TIMEOUT || \"10000\"),\n});\n\ninterface AuthorizeArgs {\n authnToken: string;\n deviceName: string;\n anonymousId?: string | undefined;\n}\n\nexport async function checkAuthorization(\n ctx: Context,\n acceptOptIns: boolean,\n): Promise<boolean> {\n const header = ctx.bigBrainAuth()?.header ?? null;\n if (header === null) {\n return false;\n }\n try {\n const resp = await fetch(`${provisionHost}/api/authorize`, {\n method: \"HEAD\",\n headers: {\n Authorization: header,\n \"Convex-Client\": `npm-cli-${version}`,\n },\n });\n // Don't throw an error if this request returns a non-200 status.\n // Big Brain responds with a variety of error codes -- 401 if the token is correctly-formed but not valid, and either 400 or 500 if the token is ill-formed.\n // We only care if this check returns a 200 code (so we can skip logging in again) -- any other errors should be silently skipped and we'll run the whole login flow again.\n if (resp.status !== 200) {\n return false;\n }\n } catch (e: any) {\n // This `catch` block should only be hit if a network error was encountered\n logError(\n `Unexpected error when authorizing - are you connected to the internet?`,\n );\n return await logAndHandleFetchError(ctx, e);\n }\n\n // Check that we have optin as well\n const shouldContinue = await optins(ctx, acceptOptIns);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n return true;\n}\n\nasync function performDeviceAuthorization(\n ctx: Context,\n authClient: BaseClient,\n shouldOpen: boolean,\n vercel?: boolean,\n vercelOverride?: string,\n): Promise<string> {\n // Device authorization flow follows this guide: https://github.com/auth0/auth0-device-flow-cli-sample/blob/9f0f3b76a6cd56ea8d99e76769187ea5102d519d/cli.js\n // License: MIT License\n // Copyright (c) 2019 Auth0 Samples\n /*\n The MIT License (MIT)\n\n Copyright (c) 2019 Auth0 Samples\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n */\n\n // Device Authorization Request - https://tools.ietf.org/html/rfc8628#section-3.1\n // Get authentication URL\n let handle;\n try {\n handle = await authClient.deviceAuthorization();\n } catch {\n // We couldn't get verification URL from the auth provider, proceed with manual auth\n return promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n\n // Device Authorization Response - https://tools.ietf.org/html/rfc8628#section-3.2\n // Open authentication URL\n const { verification_uri_complete, user_code, expires_in } = handle;\n\n // Construct Vercel URL if --vercel flag is used\n const urlToOpen = vercel\n ? `https://vercel.com/sso/integrations/${vercelOverride || \"convex\"}?url=${verification_uri_complete}`\n : verification_uri_complete;\n\n logMessage(\n `Visit ${urlToOpen} to finish logging in.\\n` +\n `You should see the following code which expires in ${\n expires_in % 60 === 0\n ? `${expires_in / 60} minutes`\n : `${expires_in} seconds`\n }: ${user_code}`,\n );\n if (shouldOpen) {\n shouldOpen = await promptYesNo(ctx, {\n message: `Open the browser?`,\n default: true,\n });\n }\n\n if (shouldOpen) {\n showSpinner(`Opening ${urlToOpen} in your browser to log in...\\n`);\n try {\n const p = await open(urlToOpen);\n p.once(\"error\", () => {\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n });\n changeSpinner(\"Waiting for the confirmation...\");\n } catch {\n logError(chalkStderr.red(`Unable to open browser.`));\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n }\n } else {\n showSpinner(`Open ${urlToOpen} in your browser to log in.`);\n }\n\n // Device Access Token Request - https://tools.ietf.org/html/rfc8628#section-3.4\n // Device Access Token Response - https://tools.ietf.org/html/rfc8628#section-3.5\n try {\n const tokens = await handle.poll();\n if (typeof tokens.access_token === \"string\") {\n return tokens.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n switch (err.error) {\n case \"access_denied\": // end-user declined the device confirmation prompt, consent or rules failed\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Access denied.\",\n errForSentry: err,\n });\n case \"expired_token\": // end-user did not complete the interaction in time\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Device flow expired.\",\n errForSentry: err,\n });\n default: {\n const message =\n err instanceof errors.OPError\n ? `Error = ${err.error}; error_description = ${err.error_description}`\n : `Login failed with error: ${err}`;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: err,\n });\n }\n }\n }\n}\n\nasync function performPasswordAuthentication(\n ctx: Context,\n clientId: string,\n username: string,\n password: string,\n): Promise<string> {\n if (!process.env.WORKOS_API_SECRET) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"WORKOS_API_SECRET environment variable is not set\",\n });\n }\n\n // Unfortunately, `openid-client` doesn't support the resource owner password credentials flow so we need to manually send the requests.\n const options: Parameters<typeof throwingFetch>[1] = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"password\",\n email: username,\n password: password,\n client_id: clientId,\n client_secret: process.env.WORKOS_API_SECRET,\n }),\n };\n\n try {\n const response = await throwingFetch(\n \"https://apiauth.convex.dev/user_management/authenticate\",\n options,\n );\n const data = await response.json();\n if (typeof data.access_token === \"string\") {\n return data.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n logFailure(`Password flow failed: ${err}`);\n if (err.response) {\n logError(chalkStderr.red(`${JSON.stringify(err.response.data)}`));\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n}\n\nexport async function performLogin(\n ctx: Context,\n {\n overrideAuthUrl,\n overrideAuthClient,\n overrideAuthUsername,\n overrideAuthPassword,\n overrideAccessToken,\n loginFlow,\n open,\n acceptOptIns,\n dumpAccessToken,\n deviceName: deviceNameOverride,\n anonymousId,\n vercel,\n vercelOverride,\n }: {\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n overrideAccessToken?: string | undefined;\n loginFlow?: \"auto\" | \"paste\" | \"poll\" | undefined;\n // default `true`\n open?: boolean | undefined;\n // default `false`\n acceptOptIns?: boolean | undefined;\n dumpAccessToken?: boolean | undefined;\n deviceName?: string | undefined;\n anonymousId?: string | undefined;\n vercel?: boolean | undefined;\n vercelOverride?: string | undefined;\n } = {},\n) {\n loginFlow = loginFlow || \"auto\";\n // Get access token from big-brain\n // Default the device name to the hostname, but allow the user to change this if the terminal is interactive.\n // On Macs, the `hostname()` may be a weirdly-truncated form of the computer name. Attempt to read the \"real\" name before falling back to hostname.\n let deviceName = deviceNameOverride ?? \"\";\n if (!deviceName && process.platform === \"darwin\") {\n try {\n deviceName = execSync(\"scutil --get ComputerName\").toString().trim();\n } catch {\n // Just fall back to the hostname default below.\n }\n }\n if (!deviceName) {\n deviceName = hostname();\n }\n if (!deviceNameOverride) {\n logMessage(\n chalkStderr.bold(\n `Welcome to developing with Convex, let's get you logged in.`,\n ),\n );\n deviceName = await promptString(ctx, {\n message: \"Device name:\",\n default: deviceName,\n });\n }\n\n const issuer = overrideAuthUrl ?? \"https://auth.convex.dev\";\n let authIssuer;\n let accessToken: string;\n\n if (loginFlow === \"paste\" || (loginFlow === \"auto\" && isWebContainer())) {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n } else {\n try {\n authIssuer = await Issuer.discover(issuer);\n } catch {\n // Couldn't contact https://auth.convex.dev/.well-known/openid-configuration,\n // proceed with manual auth.\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n }\n\n // typical path\n if (authIssuer) {\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\n const authClient = new authIssuer.Client({\n client_id: clientId,\n token_endpoint_auth_method: \"none\",\n id_token_signed_response_alg: \"RS256\",\n });\n\n if (overrideAccessToken) {\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else {\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\n );\n }\n }\n\n if (dumpAccessToken) {\n logOutput(`${accessToken!}`);\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n const authorizeArgs: AuthorizeArgs = {\n authnToken: accessToken!,\n deviceName: deviceName,\n anonymousId: anonymousId,\n };\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"authorize\",\n data: authorizeArgs,\n });\n const globalConfig = { accessToken: data.accessToken };\n try {\n await modifyGlobalConfig(ctx, globalConfig);\n const path = globalConfigPath();\n logFinishedStep(`Saved credentials to ${formatPathForPrinting(path)}`);\n } catch (err: unknown) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n\n logVerbose(`performLogin: updating big brain auth after login`);\n await updateBigBrainAuthAfterLogin(ctx, data.accessToken);\n\n logVerbose(`performLogin: checking opt ins, acceptOptIns: ${acceptOptIns}`);\n // Do opt in to TOS and Privacy Policy stuff\n const shouldContinue = await optins(ctx, acceptOptIns ?? false);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n if (vercel) {\n await promptJoinVercelTeams(ctx);\n }\n}\n\ntype PotentialVercelTeam = {\n teamId: number;\n teamName: string;\n teamSlug: string;\n planId: string;\n planName: string;\n pricingNotice: string | null;\n};\n\n// After `--vercel` login, surface any Vercel-marketplace teams the user has\n// access to but isn't yet a member of, and prompt to join each.\nasync function promptJoinVercelTeams(ctx: Context): Promise<void> {\n const fetch = bigBrainFetch(ctx);\n let teams: PotentialVercelTeam[];\n try {\n const res = await fetch(\n new URL(\"vercel/potential_teams\", `${provisionHost}/`),\n );\n if (!res.ok) {\n logVerbose(\n `vercel/potential_teams returned ${res.status}; skipping team-join prompt`,\n );\n return;\n }\n teams = await res.json();\n } catch (err) {\n logVerbose(`Failed to fetch potential Vercel teams: ${String(err)}`);\n return;\n }\n if (teams.length === 0) return;\n\n for (const [index, team] of teams.entries()) {\n const displayName = team.teamName.replace(/ \\(Vercel\\)$/, \"\");\n const counter = teams.length > 1 ? `[${index + 1}/${teams.length}] ` : \"\";\n const lines = [\n chalkStderr.bold(`${counter}You've been invited to join ${displayName}`) +\n ` (${team.planName}) through the Vercel marketplace.`,\n ];\n if (team.pricingNotice) {\n lines.push(chalkStderr.yellow(team.pricingNotice));\n }\n lines.push(`Join \"${displayName}\"?`);\n const join = await promptYesNo(ctx, {\n message: `${lines.join(\"\\n\")}`,\n default: true,\n });\n if (!join) continue;\n try {\n await fetch(\n new URL(\n `vercel/potential_teams/${team.teamId}/join`,\n `${provisionHost}/`,\n ),\n { method: \"POST\" },\n );\n logFinishedStep(`Joined ${displayName}`);\n } catch (err) {\n logFailure(`Failed to join ${displayName}: ${String(err)}`);\n }\n }\n}\n\n/// There are fields like version, but we keep them opaque\ntype OptIn = Record<string, unknown>;\n\ntype OptInToAccept = {\n optIn: OptIn;\n message: string;\n};\n\ntype AcceptOptInsArgs = {\n optInsAccepted: OptIn[];\n};\n\n// Returns whether we can proceed or not.\nasync function optins(ctx: Context, acceptOptIns: boolean): Promise<boolean> {\n const bbAuth = ctx.bigBrainAuth();\n if (bbAuth === null) {\n // This should never happen, but if we're not even logged in, we can't proceed.\n return false;\n }\n switch (bbAuth.kind) {\n case \"accessToken\":\n break;\n case \"deploymentKey\":\n case \"projectKey\":\n case \"previewDeployKey\":\n // If we have a key configured as auth, we do not need to check opt ins.\n return true;\n default: {\n bbAuth satisfies never;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: `Unexpected auth kind ${(bbAuth as any).kind}`,\n printedMessage: \"Hit an unexpected error while logging in.\",\n });\n }\n }\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"check_opt_ins\",\n });\n if (data.optInsToAccept.length === 0) {\n return true;\n }\n for (const optInToAccept of data.optInsToAccept) {\n const confirmed =\n acceptOptIns ||\n (await promptYesNo(ctx, {\n message: optInToAccept.message,\n }));\n if (!confirmed) {\n logFailure(\"Please accept the Terms of Service to use Convex.\");\n return Promise.resolve(false);\n }\n }\n\n const optInsAccepted = data.optInsToAccept.map((o: OptInToAccept) => o.optIn);\n const args: AcceptOptInsArgs = { optInsAccepted };\n await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"accept_opt_ins\",\n data: args,\n });\n return true;\n}\n\nexport async function ensureLoggedIn(\n ctx: Context,\n options?: {\n message?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n },\n) {\n const isLoggedIn = await checkAuthorization(ctx, false);\n if (!isLoggedIn) {\n if (options?.message) {\n logMessage(options.message);\n }\n await performLogin(ctx, {\n acceptOptIns: false,\n overrideAuthUrl: options?.overrideAuthUrl,\n overrideAuthClient: options?.overrideAuthClient,\n overrideAuthUsername: options?.overrideAuthUsername,\n overrideAuthPassword: options?.overrideAuthPassword,\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { errors, BaseClient, custom } from \"openid-client\";\nimport {\n bigBrainAPI,\n bigBrainFetch,\n logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\n typedPlatformClient,\n} from \"./utils/utils.js\";\nimport open from \"open\";\nimport { chalkStderr } from \"chalk\";\nimport { provisionHost } from \"./config.js\";\nimport { version } from \"../version.js\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logError,\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n logVerbose,\n showSpinner,\n} from \"../../bundler/log.js\";\nimport { Issuer } from \"openid-client\";\nimport { hostname } from \"os\";\nimport { execSync } from \"child_process\";\nimport { promptString, promptYesNo } from \"./utils/prompts.js\";\nimport {\n formatPathForPrinting,\n globalConfigPath,\n modifyGlobalConfig,\n} from \"./utils/globalConfig.js\";\nimport { updateBigBrainAuthAfterLogin } from \"./deploymentSelection.js\";\n\n// Per https://github.com/panva/node-openid-client/tree/main/docs#customizing\ncustom.setHttpOptionsDefaults({\n timeout: parseInt(process.env.OPENID_CLIENT_TIMEOUT || \"10000\"),\n});\n\nexport async function checkAuthorization(\n ctx: Context,\n acceptOptIns: boolean,\n): Promise<boolean> {\n const header = ctx.bigBrainAuth()?.header ?? null;\n if (header === null) {\n return false;\n }\n try {\n const resp = await fetch(`${provisionHost}/api/authorize`, {\n method: \"HEAD\",\n headers: {\n Authorization: header,\n \"Convex-Client\": `npm-cli-${version}`,\n },\n });\n // Don't throw an error if this request returns a non-200 status.\n // Big Brain responds with a variety of error codes -- 401 if the token is correctly-formed but not valid, and either 400 or 500 if the token is ill-formed.\n // We only care if this check returns a 200 code (so we can skip logging in again) -- any other errors should be silently skipped and we'll run the whole login flow again.\n if (resp.status !== 200) {\n return false;\n }\n } catch (e: any) {\n // This `catch` block should only be hit if a network error was encountered\n logError(\n `Unexpected error when authorizing - are you connected to the internet?`,\n );\n return await logAndHandleFetchError(ctx, e);\n }\n\n // Check that we have optin as well\n const shouldContinue = await optins(ctx, acceptOptIns);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n return true;\n}\n\nasync function performDeviceAuthorization(\n ctx: Context,\n authClient: BaseClient,\n shouldOpen: boolean,\n vercel?: boolean,\n vercelOverride?: string,\n): Promise<string> {\n // Device authorization flow follows this guide: https://github.com/auth0/auth0-device-flow-cli-sample/blob/9f0f3b76a6cd56ea8d99e76769187ea5102d519d/cli.js\n // License: MIT License\n // Copyright (c) 2019 Auth0 Samples\n /*\n The MIT License (MIT)\n\n Copyright (c) 2019 Auth0 Samples\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n */\n\n // Device Authorization Request - https://tools.ietf.org/html/rfc8628#section-3.1\n // Get authentication URL\n let handle;\n try {\n handle = await authClient.deviceAuthorization();\n } catch {\n // We couldn't get verification URL from the auth provider, proceed with manual auth\n return promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n\n // Device Authorization Response - https://tools.ietf.org/html/rfc8628#section-3.2\n // Open authentication URL\n const { verification_uri_complete, user_code, expires_in } = handle;\n\n // Construct Vercel URL if --vercel flag is used\n const urlToOpen = vercel\n ? `https://vercel.com/sso/integrations/${vercelOverride || \"convex\"}?url=${verification_uri_complete}`\n : verification_uri_complete;\n\n logMessage(\n `Visit ${urlToOpen} to finish logging in.\\n` +\n `You should see the following code which expires in ${\n expires_in % 60 === 0\n ? `${expires_in / 60} minutes`\n : `${expires_in} seconds`\n }: ${user_code}`,\n );\n if (shouldOpen) {\n shouldOpen = await promptYesNo(ctx, {\n message: `Open the browser?`,\n default: true,\n });\n }\n\n if (shouldOpen) {\n showSpinner(`Opening ${urlToOpen} in your browser to log in...\\n`);\n try {\n const p = await open(urlToOpen);\n p.once(\"error\", () => {\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n });\n changeSpinner(\"Waiting for the confirmation...\");\n } catch {\n logError(chalkStderr.red(`Unable to open browser.`));\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n }\n } else {\n showSpinner(`Open ${urlToOpen} in your browser to log in.`);\n }\n\n // Device Access Token Request - https://tools.ietf.org/html/rfc8628#section-3.4\n // Device Access Token Response - https://tools.ietf.org/html/rfc8628#section-3.5\n try {\n const tokens = await handle.poll();\n if (typeof tokens.access_token === \"string\") {\n return tokens.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n switch (err.error) {\n case \"access_denied\": // end-user declined the device confirmation prompt, consent or rules failed\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Access denied.\",\n errForSentry: err,\n });\n case \"expired_token\": // end-user did not complete the interaction in time\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Device flow expired.\",\n errForSentry: err,\n });\n default: {\n const message =\n err instanceof errors.OPError\n ? `Error = ${err.error}; error_description = ${err.error_description}`\n : `Login failed with error: ${err}`;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: err,\n });\n }\n }\n }\n}\n\nasync function performPasswordAuthentication(\n ctx: Context,\n clientId: string,\n username: string,\n password: string,\n): Promise<string> {\n if (!process.env.WORKOS_API_SECRET) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"WORKOS_API_SECRET environment variable is not set\",\n });\n }\n\n // Unfortunately, `openid-client` doesn't support the resource owner password credentials flow so we need to manually send the requests.\n const options: Parameters<typeof throwingFetch>[1] = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"password\",\n email: username,\n password: password,\n client_id: clientId,\n client_secret: process.env.WORKOS_API_SECRET,\n }),\n };\n\n try {\n const response = await throwingFetch(\n \"https://apiauth.convex.dev/user_management/authenticate\",\n options,\n );\n const data = await response.json();\n if (typeof data.access_token === \"string\") {\n return data.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n logFailure(`Password flow failed: ${err}`);\n if (err.response) {\n logError(chalkStderr.red(`${JSON.stringify(err.response.data)}`));\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n}\n\nexport async function performLogin(\n ctx: Context,\n {\n overrideAuthUrl,\n overrideAuthClient,\n overrideAuthUsername,\n overrideAuthPassword,\n overrideAccessToken,\n loginFlow,\n open,\n acceptOptIns,\n dumpAccessToken,\n deviceName: deviceNameOverride,\n anonymousId,\n vercel,\n vercelOverride,\n }: {\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n overrideAccessToken?: string | undefined;\n loginFlow?: \"auto\" | \"paste\" | \"poll\" | undefined;\n // default `true`\n open?: boolean | undefined;\n // default `false`\n acceptOptIns?: boolean | undefined;\n dumpAccessToken?: boolean | undefined;\n deviceName?: string | undefined;\n anonymousId?: string | undefined;\n vercel?: boolean | undefined;\n vercelOverride?: string | undefined;\n } = {},\n) {\n loginFlow = loginFlow || \"auto\";\n // Get access token from big-brain\n // Default the device name to the hostname, but allow the user to change this if the terminal is interactive.\n // On Macs, the `hostname()` may be a weirdly-truncated form of the computer name. Attempt to read the \"real\" name before falling back to hostname.\n let deviceName = deviceNameOverride ?? \"\";\n if (!deviceName && process.platform === \"darwin\") {\n try {\n deviceName = execSync(\"scutil --get ComputerName\").toString().trim();\n } catch {\n // Just fall back to the hostname default below.\n }\n }\n if (!deviceName) {\n deviceName = hostname();\n }\n if (!deviceNameOverride) {\n logMessage(\n chalkStderr.bold(\n `Welcome to developing with Convex, let's get you logged in.`,\n ),\n );\n deviceName = await promptString(ctx, {\n message: \"Device name:\",\n default: deviceName,\n });\n }\n\n const issuer = overrideAuthUrl ?? \"https://auth.convex.dev\";\n let authIssuer;\n let accessToken: string;\n\n if (loginFlow === \"paste\" || (loginFlow === \"auto\" && isWebContainer())) {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n } else {\n try {\n authIssuer = await Issuer.discover(issuer);\n } catch {\n // Couldn't contact https://auth.convex.dev/.well-known/openid-configuration,\n // proceed with manual auth.\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n }\n\n // typical path\n if (authIssuer) {\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\n const authClient = new authIssuer.Client({\n client_id: clientId,\n token_endpoint_auth_method: \"none\",\n id_token_signed_response_alg: \"RS256\",\n });\n\n if (overrideAccessToken) {\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else {\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\n );\n }\n }\n\n if (dumpAccessToken) {\n logOutput(`${accessToken!}`);\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n // Exchange the WorkOS access token for a Convex personal access token.\n ctx._updateBigBrainAuth({\n accessToken: accessToken!,\n kind: \"accessToken\",\n header: `Bearer ${accessToken!}`,\n });\n const response = await typedPlatformClient(ctx).POST(\n \"/create_personal_access_token\",\n {\n // `anonymousId` links a prior anonymous session to this account. It's\n // intentionally absent from the generated platform API types,\n // so cast to pass it through.\n body: { name: deviceName, anonymousId } as { name: string },\n },\n );\n const newAccessToken = response.data!.accessToken;\n const globalConfig = { accessToken: newAccessToken };\n try {\n await modifyGlobalConfig(ctx, globalConfig);\n const path = globalConfigPath();\n logFinishedStep(`Saved credentials to ${formatPathForPrinting(path)}`);\n } catch (err: unknown) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n\n logVerbose(`performLogin: updating big brain auth after login`);\n await updateBigBrainAuthAfterLogin(ctx, newAccessToken);\n\n logVerbose(`performLogin: checking opt ins, acceptOptIns: ${acceptOptIns}`);\n // Do opt in to TOS and Privacy Policy stuff\n const shouldContinue = await optins(ctx, acceptOptIns ?? false);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n if (vercel) {\n await promptJoinVercelTeams(ctx);\n }\n}\n\ntype PotentialVercelTeam = {\n teamId: number;\n teamName: string;\n teamSlug: string;\n planId: string;\n planName: string;\n pricingNotice: string | null;\n};\n\n// After `--vercel` login, surface any Vercel-marketplace teams the user has\n// access to but isn't yet a member of, and prompt to join each.\nasync function promptJoinVercelTeams(ctx: Context): Promise<void> {\n const fetch = bigBrainFetch(ctx);\n let teams: PotentialVercelTeam[];\n try {\n const res = await fetch(\n new URL(\"vercel/potential_teams\", `${provisionHost}/`),\n );\n if (!res.ok) {\n logVerbose(\n `vercel/potential_teams returned ${res.status}; skipping team-join prompt`,\n );\n return;\n }\n teams = await res.json();\n } catch (err) {\n logVerbose(`Failed to fetch potential Vercel teams: ${String(err)}`);\n return;\n }\n if (teams.length === 0) return;\n\n for (const [index, team] of teams.entries()) {\n const displayName = team.teamName.replace(/ \\(Vercel\\)$/, \"\");\n const counter = teams.length > 1 ? `[${index + 1}/${teams.length}] ` : \"\";\n const lines = [\n chalkStderr.bold(`${counter}You've been invited to join ${displayName}`) +\n ` (${team.planName}) through the Vercel marketplace.`,\n ];\n if (team.pricingNotice) {\n lines.push(chalkStderr.yellow(team.pricingNotice));\n }\n lines.push(`Join \"${displayName}\"?`);\n const join = await promptYesNo(ctx, {\n message: `${lines.join(\"\\n\")}`,\n default: true,\n });\n if (!join) continue;\n try {\n await fetch(\n new URL(\n `vercel/potential_teams/${team.teamId}/join`,\n `${provisionHost}/`,\n ),\n { method: \"POST\" },\n );\n logFinishedStep(`Joined ${displayName}`);\n } catch (err) {\n logFailure(`Failed to join ${displayName}: ${String(err)}`);\n }\n }\n}\n\n/// There are fields like version, but we keep them opaque\ntype OptIn = Record<string, unknown>;\n\ntype OptInToAccept = {\n optIn: OptIn;\n message: string;\n};\n\ntype AcceptOptInsArgs = {\n optInsAccepted: OptIn[];\n};\n\n// Returns whether we can proceed or not.\nasync function optins(ctx: Context, acceptOptIns: boolean): Promise<boolean> {\n const bbAuth = ctx.bigBrainAuth();\n if (bbAuth === null) {\n // This should never happen, but if we're not even logged in, we can't proceed.\n return false;\n }\n switch (bbAuth.kind) {\n case \"accessToken\":\n break;\n case \"deploymentKey\":\n case \"projectKey\":\n case \"previewDeployKey\":\n // If we have a key configured as auth, we do not need to check opt ins.\n return true;\n default: {\n bbAuth satisfies never;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: `Unexpected auth kind ${(bbAuth as any).kind}`,\n printedMessage: \"Hit an unexpected error while logging in.\",\n });\n }\n }\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"check_opt_ins\",\n });\n if (data.optInsToAccept.length === 0) {\n return true;\n }\n for (const optInToAccept of data.optInsToAccept) {\n const confirmed =\n acceptOptIns ||\n (await promptYesNo(ctx, {\n message: optInToAccept.message,\n }));\n if (!confirmed) {\n logFailure(\"Please accept the Terms of Service to use Convex.\");\n return Promise.resolve(false);\n }\n }\n\n const optInsAccepted = data.optInsToAccept.map((o: OptInToAccept) => o.optIn);\n const args: AcceptOptInsArgs = { optInsAccepted };\n await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"accept_opt_ins\",\n data: args,\n });\n return true;\n}\n\nexport async function ensureLoggedIn(\n ctx: Context,\n options?: {\n message?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n },\n) {\n const isLoggedIn = await checkAuthorization(ctx, false);\n if (!isLoggedIn) {\n if (options?.message) {\n logMessage(options.message);\n }\n await performLogin(ctx, {\n acceptOptIns: false,\n overrideAuthUrl: options?.overrideAuthUrl,\n overrideAuthClient: options?.overrideAuthClient,\n overrideAuthUsername: options?.overrideAuthUsername,\n overrideAuthPassword: options?.overrideAuthPassword,\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["open", "fetch"]
7
7
  }
@@ -7,7 +7,7 @@ import { nextBackoff } from "./dev.js";
7
7
  import chalk, { chalkStderr } from "chalk";
8
8
  import { stripVTControlCharacters } from "node:util";
9
9
  import { format } from "node:util";
10
- import { deploymentFetch } from "./utils/utils.js";
10
+ import { deploymentFetch, ThrowingFetchError } from "./utils/utils.js";
11
11
  export class LogManager {
12
12
  constructor(mode) {
13
13
  this.mode = mode;
@@ -76,7 +76,10 @@ export async function watchLogs(ctx, url, adminKey, dest, options) {
76
76
  options?.jsonl
77
77
  );
78
78
  }
79
- } catch {
79
+ } catch (e) {
80
+ if (e instanceof ThrowingFetchError && e.response.status === 403) {
81
+ return await e.handle(ctx);
82
+ }
80
83
  numFailures += 1;
81
84
  }
82
85
  if (numFailures > 0) {