convex 1.40.0 → 1.41.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 (290) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/aiFiles.js +2 -2
  5. package/dist/cjs/cli/aiFiles.js.map +1 -1
  6. package/dist/cjs/cli/configure.js +1 -4
  7. package/dist/cjs/cli/configure.js.map +2 -2
  8. package/dist/cjs/cli/convexExport.js +3 -3
  9. package/dist/cjs/cli/convexExport.js.map +1 -1
  10. package/dist/cjs/cli/convexImport.js +2 -2
  11. package/dist/cjs/cli/convexImport.js.map +1 -1
  12. package/dist/cjs/cli/dashboard.js +19 -6
  13. package/dist/cjs/cli/dashboard.js.map +3 -3
  14. package/dist/cjs/cli/data.js +2 -2
  15. package/dist/cjs/cli/data.js.map +1 -1
  16. package/dist/cjs/cli/deploy.js +5 -5
  17. package/dist/cjs/cli/deploy.js.map +2 -2
  18. package/dist/cjs/cli/deploymentCreate.js +11 -5
  19. package/dist/cjs/cli/deploymentCreate.js.map +2 -2
  20. package/dist/cjs/cli/deploymentSelect.js +5 -5
  21. package/dist/cjs/cli/deploymentSelect.js.map +1 -1
  22. package/dist/cjs/cli/deploymentTokenCreate.js +5 -13
  23. package/dist/cjs/cli/deploymentTokenCreate.js.map +2 -2
  24. package/dist/cjs/cli/deploymentTokenDelete.js +4 -11
  25. package/dist/cjs/cli/deploymentTokenDelete.js.map +2 -2
  26. package/dist/cjs/cli/dev.js +6 -5
  27. package/dist/cjs/cli/dev.js.map +2 -2
  28. package/dist/cjs/cli/env.js +16 -16
  29. package/dist/cjs/cli/env.js.map +2 -2
  30. package/dist/cjs/cli/envDefault.js +10 -10
  31. package/dist/cjs/cli/envDefault.js.map +1 -1
  32. package/dist/cjs/cli/insights.js +3 -3
  33. package/dist/cjs/cli/insights.js.map +1 -1
  34. package/dist/cjs/cli/lib/aiFiles/skills.js +2 -2
  35. package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
  36. package/dist/cjs/cli/lib/command.js +1 -1
  37. package/dist/cjs/cli/lib/command.js.map +1 -1
  38. package/dist/cjs/cli/lib/deployment.js.map +1 -1
  39. package/dist/cjs/cli/lib/deploymentSelection.js +39 -0
  40. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  41. package/dist/cjs/cli/lib/dev.js +31 -0
  42. package/dist/cjs/cli/lib/dev.js.map +2 -2
  43. package/dist/cjs/cli/lib/generateDocs.js +256 -0
  44. package/dist/cjs/cli/lib/generateDocs.js.map +7 -0
  45. package/dist/cjs/cli/lib/localDeployment/anonymous.js +24 -49
  46. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +3 -3
  47. package/dist/cjs/cli/lib/localDeployment/bigBrain.js +0 -9
  48. package/dist/cjs/cli/lib/localDeployment/bigBrain.js.map +2 -2
  49. package/dist/cjs/cli/lib/localDeployment/dashboard.js +30 -68
  50. package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
  51. package/dist/cjs/cli/lib/localDeployment/download.js +14 -1
  52. package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
  53. package/dist/cjs/cli/lib/localDeployment/filePaths.js +33 -4
  54. package/dist/cjs/cli/lib/localDeployment/filePaths.js.map +2 -2
  55. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +37 -126
  56. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +3 -3
  57. package/dist/cjs/cli/lib/localDeployment/secrets.js +91 -0
  58. package/dist/cjs/cli/lib/localDeployment/secrets.js.map +7 -0
  59. package/dist/cjs/cli/lib/localDeployment/upgrade.js +43 -28
  60. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +3 -3
  61. package/dist/cjs/cli/lib/localDeployment/utils.js +0 -19
  62. package/dist/cjs/cli/lib/localDeployment/utils.js.map +3 -3
  63. package/dist/cjs/cli/lib/runTestFunction.js +3 -3
  64. package/dist/cjs/cli/lib/runTestFunction.js.map +1 -1
  65. package/dist/cjs/cli/run.js +5 -5
  66. package/dist/cjs/cli/run.js.map +1 -1
  67. package/dist/cjs/index.js +1 -1
  68. package/dist/cjs/index.js.map +1 -1
  69. package/dist/cjs/server/impl/registration_impl.js +0 -1
  70. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  71. package/dist/cjs/server/index.js.map +2 -2
  72. package/dist/cjs/server/meta.js.map +1 -1
  73. package/dist/cjs/server/registration.js.map +1 -1
  74. package/dist/cjs-types/cli/configure.d.ts +3 -2
  75. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  76. package/dist/cjs-types/cli/dashboard.d.ts.map +1 -1
  77. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  78. package/dist/cjs-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  79. package/dist/cjs-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  80. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  81. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
  82. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +16 -16
  83. package/dist/cjs-types/cli/lib/deployment.d.ts +0 -2
  84. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  85. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +7 -0
  86. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  87. package/dist/cjs-types/cli/lib/dev.d.ts +2 -1
  88. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  89. package/dist/cjs-types/cli/lib/generateDocs.d.ts +20 -0
  90. package/dist/cjs-types/cli/lib/generateDocs.d.ts.map +1 -0
  91. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts +2 -0
  92. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts.map +1 -0
  93. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
  94. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  95. package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
  96. package/dist/cjs-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
  97. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
  98. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  99. package/dist/cjs-types/cli/lib/localDeployment/download.d.ts +11 -1
  100. package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  101. package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
  102. package/dist/cjs-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
  103. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
  104. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  105. package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts +31 -0
  106. package/dist/cjs-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
  107. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
  108. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
  109. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
  110. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  111. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +0 -2
  112. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  113. package/dist/cjs-types/cli/lib/versionApi.d.ts +2 -2
  114. package/dist/cjs-types/index.d.ts +1 -1
  115. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  116. package/dist/cjs-types/server/index.d.ts +1 -1
  117. package/dist/cjs-types/server/index.d.ts.map +1 -1
  118. package/dist/cjs-types/server/meta.d.ts +16 -0
  119. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  120. package/dist/cjs-types/server/registration.d.ts +11 -5
  121. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  122. package/dist/cli.bundle.cjs +66405 -67923
  123. package/dist/cli.bundle.cjs.map +4 -4
  124. package/dist/esm/cli/aiFiles.js +2 -2
  125. package/dist/esm/cli/aiFiles.js.map +1 -1
  126. package/dist/esm/cli/configure.js +1 -4
  127. package/dist/esm/cli/configure.js.map +2 -2
  128. package/dist/esm/cli/convexExport.js +3 -3
  129. package/dist/esm/cli/convexExport.js.map +1 -1
  130. package/dist/esm/cli/convexImport.js +2 -2
  131. package/dist/esm/cli/convexImport.js.map +1 -1
  132. package/dist/esm/cli/dashboard.js +16 -3
  133. package/dist/esm/cli/dashboard.js.map +2 -2
  134. package/dist/esm/cli/data.js +2 -2
  135. package/dist/esm/cli/data.js.map +1 -1
  136. package/dist/esm/cli/deploy.js +5 -5
  137. package/dist/esm/cli/deploy.js.map +2 -2
  138. package/dist/esm/cli/deploymentCreate.js +13 -9
  139. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  140. package/dist/esm/cli/deploymentSelect.js +5 -5
  141. package/dist/esm/cli/deploymentSelect.js.map +1 -1
  142. package/dist/esm/cli/deploymentTokenCreate.js +9 -15
  143. package/dist/esm/cli/deploymentTokenCreate.js.map +2 -2
  144. package/dist/esm/cli/deploymentTokenDelete.js +8 -16
  145. package/dist/esm/cli/deploymentTokenDelete.js.map +2 -2
  146. package/dist/esm/cli/dev.js +6 -5
  147. package/dist/esm/cli/dev.js.map +2 -2
  148. package/dist/esm/cli/env.js +16 -16
  149. package/dist/esm/cli/env.js.map +2 -2
  150. package/dist/esm/cli/envDefault.js +10 -10
  151. package/dist/esm/cli/envDefault.js.map +1 -1
  152. package/dist/esm/cli/insights.js +3 -3
  153. package/dist/esm/cli/insights.js.map +1 -1
  154. package/dist/esm/cli/lib/aiFiles/skills.js +2 -2
  155. package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
  156. package/dist/esm/cli/lib/command.js +1 -1
  157. package/dist/esm/cli/lib/command.js.map +1 -1
  158. package/dist/esm/cli/lib/deployment.js.map +1 -1
  159. package/dist/esm/cli/lib/deploymentSelection.js +38 -0
  160. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  161. package/dist/esm/cli/lib/dev.js +31 -0
  162. package/dist/esm/cli/lib/dev.js.map +2 -2
  163. package/dist/esm/cli/lib/generateDocs.js +233 -0
  164. package/dist/esm/cli/lib/generateDocs.js.map +7 -0
  165. package/dist/esm/cli/lib/localDeployment/anonymous.js +30 -61
  166. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +3 -3
  167. package/dist/esm/cli/lib/localDeployment/bigBrain.js +0 -8
  168. package/dist/esm/cli/lib/localDeployment/bigBrain.js.map +2 -2
  169. package/dist/esm/cli/lib/localDeployment/dashboard.js +36 -69
  170. package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
  171. package/dist/esm/cli/lib/localDeployment/download.js +15 -2
  172. package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
  173. package/dist/esm/cli/lib/localDeployment/filePaths.js +29 -2
  174. package/dist/esm/cli/lib/localDeployment/filePaths.js.map +2 -2
  175. package/dist/esm/cli/lib/localDeployment/localDeployment.js +40 -134
  176. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +3 -3
  177. package/dist/esm/cli/lib/localDeployment/secrets.js +57 -0
  178. package/dist/esm/cli/lib/localDeployment/secrets.js.map +7 -0
  179. package/dist/esm/cli/lib/localDeployment/upgrade.js +45 -28
  180. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +3 -3
  181. package/dist/esm/cli/lib/localDeployment/utils.js +0 -7
  182. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  183. package/dist/esm/cli/lib/runTestFunction.js +3 -3
  184. package/dist/esm/cli/lib/runTestFunction.js.map +1 -1
  185. package/dist/esm/cli/run.js +5 -5
  186. package/dist/esm/cli/run.js.map +1 -1
  187. package/dist/esm/index.js +1 -1
  188. package/dist/esm/index.js.map +1 -1
  189. package/dist/esm/server/impl/registration_impl.js +0 -1
  190. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  191. package/dist/esm/server/index.js.map +2 -2
  192. package/dist/esm-types/cli/configure.d.ts +3 -2
  193. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  194. package/dist/esm-types/cli/dashboard.d.ts.map +1 -1
  195. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  196. package/dist/esm-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  197. package/dist/esm-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  198. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  199. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +4 -4
  200. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +16 -16
  201. package/dist/esm-types/cli/lib/deployment.d.ts +0 -2
  202. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  203. package/dist/esm-types/cli/lib/deploymentSelection.d.ts +7 -0
  204. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  205. package/dist/esm-types/cli/lib/dev.d.ts +2 -1
  206. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  207. package/dist/esm-types/cli/lib/generateDocs.d.ts +20 -0
  208. package/dist/esm-types/cli/lib/generateDocs.d.ts.map +1 -0
  209. package/dist/esm-types/cli/lib/generateDocs.test.d.ts +2 -0
  210. package/dist/esm-types/cli/lib/generateDocs.test.d.ts.map +1 -0
  211. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts +1 -1
  212. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  213. package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts +2 -4
  214. package/dist/esm-types/cli/lib/localDeployment/bigBrain.d.ts.map +1 -1
  215. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +9 -4
  216. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  217. package/dist/esm-types/cli/lib/localDeployment/download.d.ts +11 -1
  218. package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  219. package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts +16 -5
  220. package/dist/esm-types/cli/lib/localDeployment/filePaths.d.ts.map +1 -1
  221. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts +1 -9
  222. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  223. package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts +31 -0
  224. package/dist/esm-types/cli/lib/localDeployment/secrets.d.ts.map +1 -0
  225. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts +2 -0
  226. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts.map +1 -0
  227. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts +6 -3
  228. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  229. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +0 -2
  230. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  231. package/dist/esm-types/cli/lib/versionApi.d.ts +2 -2
  232. package/dist/esm-types/index.d.ts +1 -1
  233. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  234. package/dist/esm-types/server/index.d.ts +1 -1
  235. package/dist/esm-types/server/index.d.ts.map +1 -1
  236. package/dist/esm-types/server/meta.d.ts +16 -0
  237. package/dist/esm-types/server/meta.d.ts.map +1 -1
  238. package/dist/esm-types/server/registration.d.ts +11 -5
  239. package/dist/esm-types/server/registration.d.ts.map +1 -1
  240. package/dist/react.bundle.js +1 -1
  241. package/dist/react.bundle.js.map +1 -1
  242. package/package.json +4 -2
  243. package/src/browser/sync/request_manager.test.ts +2 -2
  244. package/src/cli/aiFiles.ts +2 -2
  245. package/src/cli/configure.ts +4 -6
  246. package/src/cli/convexExport.ts +3 -3
  247. package/src/cli/convexImport.ts +2 -2
  248. package/src/cli/dashboard.ts +29 -3
  249. package/src/cli/data.ts +2 -2
  250. package/src/cli/deploy.ts +5 -5
  251. package/src/cli/deploymentCreate.test.ts +151 -24
  252. package/src/cli/deploymentCreate.ts +21 -11
  253. package/src/cli/deploymentSelect.ts +5 -5
  254. package/src/cli/deploymentSelection.test.ts +0 -3
  255. package/src/cli/deploymentToken.test.ts +34 -23
  256. package/src/cli/deploymentTokenCreate.ts +9 -21
  257. package/src/cli/deploymentTokenDelete.ts +8 -23
  258. package/src/cli/dev.ts +5 -4
  259. package/src/cli/env.ts +16 -16
  260. package/src/cli/envDefault.ts +10 -10
  261. package/src/cli/insights.ts +3 -3
  262. package/src/cli/lib/aiFiles/integration.test.ts +2 -0
  263. package/src/cli/lib/aiFiles/skills.ts +3 -3
  264. package/src/cli/lib/command.ts +2 -2
  265. package/src/cli/lib/deployment.ts +0 -5
  266. package/src/cli/lib/deploymentSelection.ts +67 -0
  267. package/src/cli/lib/dev.ts +39 -0
  268. package/src/cli/lib/generateDocs.test.ts +326 -0
  269. package/src/cli/lib/generateDocs.ts +393 -0
  270. package/src/cli/lib/localDeployment/anonymous.ts +48 -72
  271. package/src/cli/lib/localDeployment/bigBrain.ts +7 -15
  272. package/src/cli/lib/localDeployment/dashboard.ts +48 -80
  273. package/src/cli/lib/localDeployment/download.ts +34 -3
  274. package/src/cli/lib/localDeployment/filePaths.ts +66 -6
  275. package/src/cli/lib/localDeployment/localDeployment.ts +46 -184
  276. package/src/cli/lib/localDeployment/run.test.ts +6 -6
  277. package/src/cli/lib/localDeployment/secrets.test.ts +53 -0
  278. package/src/cli/lib/localDeployment/secrets.ts +93 -0
  279. package/src/cli/lib/localDeployment/tests/keygenFailure.mjs +9 -0
  280. package/src/cli/lib/localDeployment/tests/keygenSuccess.mjs +31 -0
  281. package/src/cli/lib/localDeployment/upgrade.ts +52 -38
  282. package/src/cli/lib/localDeployment/utils.ts +0 -10
  283. package/src/cli/lib/runTestFunction.ts +3 -3
  284. package/src/cli/run.ts +5 -5
  285. package/src/index.ts +1 -1
  286. package/src/server/impl/registration_impl.ts +0 -2
  287. package/src/server/index.ts +1 -0
  288. package/src/server/meta.ts +17 -0
  289. package/src/server/registration.test.ts +2 -35
  290. package/src/server/registration.ts +10 -19
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/anonymous.ts"],
4
- "sourcesContent": ["// ----------------------------------------------------------------------------\n// Anonymous (No account)\n\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n logMessage,\n logVerbose,\n logWarning,\n} from \"../../../bundler/log.js\";\nimport { promptSearch, promptYesNo } from \"../utils/prompts.js\";\nimport {\n bigBrainGenerateAdminKeyForAnonymousDeployment,\n bigBrainPause,\n bigBrainStart,\n} from \"./bigBrain.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n LocalDeploymentKind,\n deploymentStateDir,\n ensureUuidForAnonymousUser,\n legacyDeploymentStateDir,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport { rootDeploymentStateDir } from \"./filePaths.js\";\nimport { LocalDeploymentConfig } from \"./filePaths.js\";\nimport { DeploymentDetails } from \"./localDeployment.js\";\nimport { ensureBackendStopped, localDeploymentUrl } from \"./run.js\";\nimport { ensureBackendRunning } from \"./run.js\";\nimport { handlePotentialUpgrade } from \"./upgrade.js\";\nimport {\n isOffline,\n generateInstanceSecret,\n chooseLocalBackendPorts,\n LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./utils.js\";\nimport { handleDashboard } from \"./dashboard.js\";\nimport { recursivelyDelete, recursivelyCopy } from \"../fsUtils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { isAnonymousDeployment } from \"../deployment.js\";\nimport { createProject } from \"../api.js\";\nimport { removeAnonymousPrefix } from \"../deployment.js\";\nimport { nodeFs } from \"../../../bundler/fs.js\";\nimport { doInitConvexFolder } from \"../codegen.js\";\nimport { readProjectConfig } from \"../config.js\";\nimport { functionsDir } from \"../utils/utils.js\";\nimport { attemptSetupAiFiles } from \"../aiFiles/index.js\";\n\nexport async function handleAnonymousDeployment(\n ctx: Context,\n options: {\n ports: {\n cloud: number | undefined;\n site: number | undefined;\n };\n backendVersion?: string | undefined;\n dashboardVersion?: string | undefined;\n forceUpgrade: boolean;\n deploymentName: string | null;\n chosenConfiguration: \"new\" | \"existing\" | \"ask\" | null;\n },\n): Promise<DeploymentDetails> {\n if (await isOffline()) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Cannot run a local deployment while offline\",\n });\n }\n\n const deployment = await chooseDeployment(ctx, {\n deploymentName: options.deploymentName,\n chosenConfiguration: options.chosenConfiguration,\n });\n if (\n deployment.kind === \"first\" &&\n process.env.CONVEX_AGENT_MODE !== \"anonymous\" &&\n process.stdin.isTTY\n ) {\n logMessage(\n \"This command, `npx convex dev`, will run your Convex backend locally and update it with the function you write in the `convex/` directory.\",\n );\n logMessage(\n \"Use `npx convex dashboard` to view and interact with your project from a web UI.\",\n );\n logMessage(\n \"Use `npx convex docs` to read the docs and `npx convex help` to see other commands.\",\n );\n ensureUuidForAnonymousUser(ctx);\n if (process.stdin.isTTY) {\n const result = await promptYesNo(ctx, {\n message: \"Continue?\",\n default: true,\n });\n if (!result) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Exiting\",\n });\n }\n }\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n await handleDashboard(ctx, version);\n let adminKey: string;\n let instanceSecret: string;\n if (deployment.kind === \"existing\") {\n adminKey = deployment.config.adminKey;\n instanceSecret =\n deployment.config.instanceSecret ?? LOCAL_BACKEND_INSTANCE_SECRET;\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: deployment.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: deployment.deploymentName,\n allowOtherDeployments: true,\n });\n } else {\n instanceSecret = generateInstanceSecret();\n const data = await bigBrainGenerateAdminKeyForAnonymousDeployment(ctx, {\n instanceName: deployment.deploymentName,\n instanceSecret,\n });\n adminKey = data.adminKey;\n }\n\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n suggestedPorts:\n deployment.kind === \"existing\" ? deployment.config.ports : undefined,\n });\n const onActivity = async (isOffline: boolean, _wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName: deployment.deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n };\n\n const { cleanupHandle } = await handlePotentialUpgrade(ctx, {\n deploymentName: deployment.deploymentName,\n deploymentKind: \"anonymous\",\n oldVersion:\n deployment.kind === \"existing\" ? deployment.config.backendVersion : null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n adminKey,\n instanceSecret,\n forceUpgrade: options.forceUpgrade,\n // Anonymous deployments aren't registered against a cloud project.\n cloudProjectId: undefined,\n });\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n });\n\n if (deployment.kind === \"new\") {\n await doInitConvexFolder(ctx);\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n await attemptSetupAiFiles({\n ctx,\n aiFilesConfig: projectConfig.aiFiles,\n convexDir,\n projectDir,\n });\n }\n return {\n adminKey,\n deploymentName: deployment.deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n reference: null,\n isDefault: false,\n onActivity,\n };\n}\n\nexport async function loadAnonymousDeployment(\n ctx: Context,\n deploymentName: string,\n): Promise<LocalDeploymentConfig> {\n const config = loadDeploymentConfig(ctx, \"anonymous\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find deployment with name ${deploymentName}!`,\n });\n }\n return config;\n}\n\n/**\n * List legacy anonymous deployments from the home directory.\n * These are deployments stored in ~/.convex/anonymous-convex-backend-state/\n */\nexport function listLegacyAnonymousDeployments(ctx: Context): Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n}> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n const dir = rootDeploymentStateDir(\"anonymous\");\n if (ctx.fs.exists(dir)) {\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => isAnonymousDeployment(d));\n for (const deploymentName of deploymentNames) {\n const legacyDir = legacyDeploymentStateDir(\"anonymous\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n deployments.push({ deploymentName, config });\n }\n }\n }\n\n return deployments;\n}\n\nexport async function listExistingAnonymousDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n // Check project-local storage first\n const projectLocal = loadProjectLocalConfig(ctx);\n if (\n projectLocal !== null &&\n isAnonymousDeployment(projectLocal.deploymentName)\n ) {\n deployments.push(projectLocal);\n }\n\n // Check legacy home directory, avoiding duplicates\n for (const legacy of listLegacyAnonymousDeployments(ctx)) {\n if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {\n deployments.push(legacy);\n }\n }\n\n return deployments;\n}\n\nasync function chooseDeployment(\n ctx: Context,\n options: {\n deploymentName: string | null;\n chosenConfiguration: \"new\" | \"existing\" | \"ask\" | null;\n },\n): Promise<\n | {\n kind: \"existing\";\n deploymentName: string;\n config: LocalDeploymentConfig;\n }\n | {\n kind: \"new\";\n deploymentName: string;\n }\n | {\n kind: \"first\";\n deploymentName: string;\n }\n> {\n // Check for existing project-local deployment first - use it if it exists\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n if (isAnonymousDeployment(projectLocal.deploymentName)) {\n // Already an anonymous deployment - use it as-is\n return {\n kind: \"existing\",\n deploymentName: projectLocal.deploymentName,\n config: projectLocal.config,\n };\n }\n // Project-local has data from a different deployment type (e.g., \"local-*\")\n // Create a new anonymous deployment that will reuse this data and update the config\n logVerbose(\n `Project-local has ${projectLocal.deploymentName}, switching to anonymous`,\n );\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Check if a specific deployment name was requested (legacy support)\n if (options.deploymentName !== null && options.chosenConfiguration === null) {\n const deployments = await listExistingAnonymousDeployments(ctx);\n const existing = deployments.find(\n (d) => d.deploymentName === options.deploymentName,\n );\n if (existing === undefined) {\n logWarning(`Could not find project with name ${options.deploymentName}!`);\n } else {\n return {\n kind: \"existing\",\n deploymentName: existing.deploymentName,\n config: existing.config,\n };\n }\n }\n\n // Handle agent mode - use fixed name since there's one deployment per project\n if (process.env.CONVEX_AGENT_MODE === \"anonymous\") {\n const deploymentName = \"anonymous-agent\";\n logVerbose(`Deployment name: ${deploymentName}`);\n return {\n kind: \"new\",\n deploymentName,\n };\n }\n\n // No project-local data - check for legacy deployments in home directory\n const legacyDeployments = listLegacyAnonymousDeployments(ctx);\n\n // No legacy deployments - auto-create a new project without prompting\n if (legacyDeployments.length === 0) {\n logMessage(\"Setting up a new project...\");\n return { deploymentName: generateDeploymentName(), kind: \"first\" };\n }\n\n // User explicitly wants a new deployment - create without prompting for name\n if (options.chosenConfiguration === \"new\") {\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Non-interactive terminal - auto-create a new deployment\n if (!process.stdin.isTTY) {\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Legacy deployments exist - prompt user to choose\n const newOrExisting = await promptSearch(ctx, {\n message: \"Which project would you like to use?\",\n choices: [\n ...(options.chosenConfiguration === \"existing\"\n ? []\n : [\n {\n name: \"Create a new one\",\n value: \"new\",\n },\n ]),\n ...legacyDeployments.map((d) => ({\n name: d.deploymentName,\n value: d.deploymentName,\n })),\n ],\n });\n\n if (newOrExisting !== \"new\") {\n const existingDeployment = legacyDeployments.find(\n (d) => d.deploymentName === newOrExisting,\n );\n if (existingDeployment === undefined) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find project with name ${newOrExisting}!`,\n });\n }\n return {\n kind: \"existing\",\n deploymentName: existingDeployment.deploymentName,\n config: existingDeployment.config,\n };\n }\n\n // User chose to create a new one - no name prompt needed\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n}\n\n/**\n * Returns a name for a new anonymous deployment.\n */\nfunction generateDeploymentName() {\n const baseName = path.basename(process.cwd());\n const deploymentName = `anonymous-${baseName}`;\n logVerbose(`Deployment name: ${deploymentName}`);\n return deploymentName;\n}\n\n/**\n * This takes an \"anonymous\" deployment and makes it a \"local\" deployment\n * that is associated with a project in the given team.\n */\nexport async function handleLinkToProject(\n ctx: Context,\n args: {\n deploymentName: string;\n teamSlug: string;\n teamId: number;\n projectSlug: string | null;\n },\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n projectSlug: string;\n}> {\n logVerbose(\n `Linking ${args.deploymentName} to a project in team ${args.teamSlug}`,\n );\n const config = loadDeploymentConfig(ctx, \"anonymous\", args.deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: config.ports.cloud,\n },\n deploymentName: args.deploymentName,\n allowOtherDeployments: true,\n maxTimeSecs: 5,\n });\n const projectName = removeAnonymousPrefix(args.deploymentName);\n let projectSlug: string;\n if (args.projectSlug !== null) {\n projectSlug = args.projectSlug;\n } else {\n const { projectSlug: newProjectSlug } = await createProject(ctx, {\n teamId: args.teamId,\n projectName,\n deploymentToProvision: null,\n });\n projectSlug = newProjectSlug;\n }\n logVerbose(`Creating local deployment in project ${projectSlug}`);\n // Register it in big brain\n const {\n deploymentName: localDeploymentName,\n adminKey,\n projectId,\n } = await bigBrainStart(ctx, {\n port: config.ports.cloud,\n projectSlug,\n teamSlug: args.teamSlug,\n instanceName: null,\n });\n const localConfig = loadDeploymentConfig(ctx, \"local\", localDeploymentName);\n if (localConfig !== null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Project ${projectSlug} already has a local deployment, so we cannot link this anonymous local deployment to it.`,\n });\n }\n logVerbose(`Moving ${args.deploymentName} to ${localDeploymentName}`);\n await moveDeployment(\n ctx,\n {\n deploymentKind: \"anonymous\",\n deploymentName: args.deploymentName,\n },\n {\n deploymentKind: \"local\",\n deploymentName: localDeploymentName,\n },\n );\n logVerbose(`Saving deployment config for ${localDeploymentName}`);\n saveDeploymentConfig(ctx, \"local\", localDeploymentName, {\n adminKey,\n backendVersion: config.backendVersion,\n ports: config.ports,\n cloudProjectId: projectId,\n });\n await bigBrainPause(ctx, {\n projectSlug,\n teamSlug: args.teamSlug,\n });\n logFinishedStep(`Linked ${args.deploymentName} to project ${projectSlug}`);\n return {\n projectSlug,\n deploymentName: localDeploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n };\n}\n\nexport async function moveDeployment(\n ctx: Context,\n oldDeployment: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n },\n newDeployment: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n },\n) {\n const oldPath = deploymentStateDir(\n ctx,\n oldDeployment.deploymentKind,\n oldDeployment.deploymentName,\n );\n const newPath = deploymentStateDir(\n ctx,\n newDeployment.deploymentKind,\n newDeployment.deploymentName,\n );\n\n // If both paths are the same (project-local storage), no file movement needed.\n // The config will be updated separately by saveDeploymentConfig.\n if (oldPath === newPath) {\n logVerbose(\n `Source and destination are the same (${oldPath}), skipping file copy`,\n );\n return;\n }\n\n await recursivelyCopy(ctx, nodeFs, oldPath, newPath);\n recursivelyDelete(ctx, oldPath);\n}\n"],
5
- "mappings": "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",
6
- "names": ["isOffline"]
4
+ "sourcesContent": ["// ----------------------------------------------------------------------------\n// Anonymous (No account)\n\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n logMessage,\n logVerbose,\n logWarning,\n} from \"../../../bundler/log.js\";\nimport { promptSearch, promptYesNo } from \"../utils/prompts.js\";\nimport { bigBrainPause, bigBrainStart } from \"./bigBrain.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n LocalDeploymentKind,\n deploymentStateDir,\n ensureUuidForAnonymousUser,\n legacyDeploymentStateDir,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport { rootDeploymentStateDir } from \"./filePaths.js\";\nimport { LocalDeploymentConfig } from \"./filePaths.js\";\nimport { ensureBackendStopped, localDeploymentUrl } from \"./run.js\";\nimport { handlePotentialUpgradeAndStart } from \"./upgrade.js\";\nimport { chooseLocalBackendPorts } from \"./utils.js\";\nimport { recursivelyDelete, recursivelyCopy } from \"../fsUtils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { DeploymentDetails, isAnonymousDeployment } from \"../deployment.js\";\nimport { createProject } from \"../api.js\";\nimport { removeAnonymousPrefix } from \"../deployment.js\";\nimport { nodeFs } from \"../../../bundler/fs.js\";\nimport { doInitConvexFolder } from \"../codegen.js\";\nimport { readProjectConfig } from \"../config.js\";\nimport { functionsDir } from \"../utils/utils.js\";\nimport { attemptSetupAiFiles } from \"../aiFiles/index.js\";\nimport {\n generateLocalDevSecretsWithLatestBinary,\n LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./secrets.js\";\n\nexport async function handleAnonymousDeployment(\n ctx: Context,\n options: {\n ports: {\n cloud: number | undefined;\n site: number | undefined;\n };\n backendVersion?: string | undefined;\n dashboardVersion?: string | undefined;\n forceUpgrade: boolean;\n deploymentName: string | null;\n chosenConfiguration: \"new\" | \"existing\" | \"ask\" | null;\n },\n): Promise<DeploymentDetails> {\n const deployment = await chooseDeployment(ctx, {\n deploymentName: options.deploymentName,\n chosenConfiguration: options.chosenConfiguration,\n });\n if (\n deployment.kind === \"first\" &&\n process.env.CONVEX_AGENT_MODE !== \"anonymous\" &&\n process.stdin.isTTY\n ) {\n logMessage(\n \"This command, `npx convex dev`, will run your Convex backend locally and update it with the function you write in the `convex/` directory.\",\n );\n logMessage(\n \"Use `npx convex dashboard` to view and interact with your project from a web UI.\",\n );\n logMessage(\n \"Use `npx convex docs` to read the docs and `npx convex help` to see other commands.\",\n );\n ensureUuidForAnonymousUser(ctx);\n if (process.stdin.isTTY) {\n const result = await promptYesNo(ctx, {\n message: \"Continue?\",\n default: true,\n });\n if (!result) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Exiting\",\n });\n }\n }\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n\n const existingCredentials =\n deployment.kind === \"existing\"\n ? {\n adminKey: deployment.config.adminKey,\n instanceSecret:\n deployment.config.instanceSecret ??\n LEGACY_LOCAL_BACKEND_INSTANCE_SECRET,\n }\n : null;\n if (deployment.kind === \"existing\") {\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: deployment.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: deployment.deploymentName,\n allowOtherDeployments: true,\n });\n }\n\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n suggestedPorts:\n deployment.kind === \"existing\" ? deployment.config.ports : undefined,\n });\n\n const { cleanupHandle, adminKey } = await handlePotentialUpgradeAndStart(\n ctx,\n {\n deploymentName: deployment.deploymentName,\n deploymentKind: \"anonymous\",\n oldVersion:\n deployment.kind === \"existing\"\n ? deployment.config.backendVersion\n : null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n existingCredentials,\n forceUpgrade: options.forceUpgrade,\n // Anonymous deployments aren't registered against a cloud project.\n cloudProjectId: undefined,\n },\n );\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n });\n\n if (deployment.kind === \"new\") {\n await doInitConvexFolder(ctx);\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n await attemptSetupAiFiles({\n ctx,\n aiFilesConfig: projectConfig.aiFiles,\n convexDir,\n projectDir,\n });\n }\n return {\n adminKey,\n deploymentName: deployment.deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n reference: null,\n isDefault: false,\n };\n}\n\nexport async function loadAnonymousDeployment(\n ctx: Context,\n deploymentName: string,\n): Promise<LocalDeploymentConfig> {\n const config = loadDeploymentConfig(ctx, \"anonymous\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find deployment with name ${deploymentName}!`,\n });\n }\n return config;\n}\n\n/**\n * List legacy anonymous deployments from the home directory.\n * These are deployments stored in ~/.convex/anonymous-convex-backend-state/\n */\nexport function listLegacyAnonymousDeployments(ctx: Context): Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n}> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n const dir = rootDeploymentStateDir(\"anonymous\");\n if (ctx.fs.exists(dir)) {\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => isAnonymousDeployment(d));\n for (const deploymentName of deploymentNames) {\n const legacyDir = legacyDeploymentStateDir(\"anonymous\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n deployments.push({ deploymentName, config });\n }\n }\n }\n\n return deployments;\n}\n\nexport async function listExistingAnonymousDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n // Check project-local storage first\n const projectLocal = loadProjectLocalConfig(ctx);\n if (\n projectLocal !== null &&\n isAnonymousDeployment(projectLocal.deploymentName)\n ) {\n deployments.push(projectLocal);\n }\n\n // Check legacy home directory, avoiding duplicates\n for (const legacy of listLegacyAnonymousDeployments(ctx)) {\n if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {\n deployments.push(legacy);\n }\n }\n\n return deployments;\n}\n\nasync function chooseDeployment(\n ctx: Context,\n options: {\n deploymentName: string | null;\n chosenConfiguration: \"new\" | \"existing\" | \"ask\" | null;\n },\n): Promise<\n | {\n kind: \"existing\";\n deploymentName: string;\n config: LocalDeploymentConfig;\n }\n | {\n kind: \"new\";\n deploymentName: string;\n }\n | {\n kind: \"first\";\n deploymentName: string;\n }\n> {\n // Check for existing project-local deployment first - use it if it exists\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n if (isAnonymousDeployment(projectLocal.deploymentName)) {\n // Already an anonymous deployment - use it as-is\n return {\n kind: \"existing\",\n deploymentName: projectLocal.deploymentName,\n config: projectLocal.config,\n };\n }\n // Project-local has data from a different deployment type (e.g., \"local-*\")\n // Create a new anonymous deployment that will reuse this data and update the config\n logVerbose(\n `Project-local has ${projectLocal.deploymentName}, switching to anonymous`,\n );\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Check if a specific deployment name was requested (legacy support)\n if (options.deploymentName !== null && options.chosenConfiguration === null) {\n const deployments = await listExistingAnonymousDeployments(ctx);\n const existing = deployments.find(\n (d) => d.deploymentName === options.deploymentName,\n );\n if (existing === undefined) {\n logWarning(`Could not find project with name ${options.deploymentName}!`);\n } else {\n return {\n kind: \"existing\",\n deploymentName: existing.deploymentName,\n config: existing.config,\n };\n }\n }\n\n // Handle agent mode - use fixed name since there's one deployment per project\n if (process.env.CONVEX_AGENT_MODE === \"anonymous\") {\n const deploymentName = \"anonymous-agent\";\n logVerbose(`Deployment name: ${deploymentName}`);\n return {\n kind: \"new\",\n deploymentName,\n };\n }\n\n // No project-local data - check for legacy deployments in home directory\n const legacyDeployments = listLegacyAnonymousDeployments(ctx);\n\n // No legacy deployments - auto-create a new project without prompting\n if (legacyDeployments.length === 0) {\n logMessage(\"Setting up a new project...\");\n return { deploymentName: generateDeploymentName(), kind: \"first\" };\n }\n\n // User explicitly wants a new deployment - create without prompting for name\n if (options.chosenConfiguration === \"new\") {\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Non-interactive terminal - auto-create a new deployment\n if (!process.stdin.isTTY) {\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n }\n\n // Legacy deployments exist - prompt user to choose\n const newOrExisting = await promptSearch(ctx, {\n message: \"Which project would you like to use?\",\n choices: [\n ...(options.chosenConfiguration === \"existing\"\n ? []\n : [\n {\n name: \"Create a new one\",\n value: \"new\",\n },\n ]),\n ...legacyDeployments.map((d) => ({\n name: d.deploymentName,\n value: d.deploymentName,\n })),\n ],\n });\n\n if (newOrExisting !== \"new\") {\n const existingDeployment = legacyDeployments.find(\n (d) => d.deploymentName === newOrExisting,\n );\n if (existingDeployment === undefined) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Could not find project with name ${newOrExisting}!`,\n });\n }\n return {\n kind: \"existing\",\n deploymentName: existingDeployment.deploymentName,\n config: existingDeployment.config,\n };\n }\n\n // User chose to create a new one - no name prompt needed\n return { deploymentName: generateDeploymentName(), kind: \"new\" };\n}\n\n/**\n * Returns a name for a new anonymous deployment.\n */\nfunction generateDeploymentName() {\n const baseName = path.basename(process.cwd());\n const deploymentName = `anonymous-${baseName}`;\n logVerbose(`Deployment name: ${deploymentName}`);\n return deploymentName;\n}\n\n/**\n * This takes an \"anonymous\" deployment and makes it a \"local\" deployment\n * that is associated with a project in the given team.\n */\nexport async function handleLinkToProject(\n ctx: Context,\n args: {\n deploymentName: string;\n teamSlug: string;\n teamId: number;\n projectSlug: string | null;\n },\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n projectSlug: string;\n}> {\n logVerbose(\n `Linking ${args.deploymentName} to a project in team ${args.teamSlug}`,\n );\n const config = loadDeploymentConfig(ctx, \"anonymous\", args.deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: config.ports.cloud,\n },\n deploymentName: args.deploymentName,\n allowOtherDeployments: true,\n maxTimeSecs: 5,\n });\n const projectName = removeAnonymousPrefix(args.deploymentName);\n let projectSlug: string;\n if (args.projectSlug !== null) {\n projectSlug = args.projectSlug;\n } else {\n const { projectSlug: newProjectSlug } = await createProject(ctx, {\n teamId: args.teamId,\n projectName,\n deploymentToProvision: null,\n });\n projectSlug = newProjectSlug;\n }\n logVerbose(`Creating local deployment in project ${projectSlug}`);\n // Register it in big brain\n const { deploymentName: localDeploymentName, projectId } =\n await bigBrainStart(ctx, {\n port: config.ports.cloud,\n projectSlug,\n teamSlug: args.teamSlug,\n instanceName: null,\n });\n const { instanceSecret, adminKey } =\n await generateLocalDevSecretsWithLatestBinary(ctx, {\n deploymentName: localDeploymentName,\n });\n const localConfig = loadDeploymentConfig(ctx, \"local\", localDeploymentName);\n if (localConfig !== null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Project ${projectSlug} already has a local deployment, so we cannot link this anonymous local deployment to it.`,\n });\n }\n logVerbose(`Moving ${args.deploymentName} to ${localDeploymentName}`);\n await moveDeployment(\n ctx,\n {\n deploymentKind: \"anonymous\",\n deploymentName: args.deploymentName,\n },\n {\n deploymentKind: \"local\",\n deploymentName: localDeploymentName,\n },\n );\n logVerbose(`Saving deployment config for ${localDeploymentName}`);\n saveDeploymentConfig(ctx, \"local\", localDeploymentName, {\n instanceSecret,\n adminKey,\n backendVersion: config.backendVersion,\n ports: config.ports,\n cloudProjectId: projectId,\n });\n await bigBrainPause(ctx, {\n projectSlug,\n teamSlug: args.teamSlug,\n });\n logFinishedStep(`Linked ${args.deploymentName} to project ${projectSlug}`);\n return {\n projectSlug,\n deploymentName: localDeploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n };\n}\n\nexport async function moveDeployment(\n ctx: Context,\n oldDeployment: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n },\n newDeployment: {\n deploymentKind: LocalDeploymentKind;\n deploymentName: string;\n },\n) {\n const oldPath = deploymentStateDir(\n ctx,\n oldDeployment.deploymentKind,\n oldDeployment.deploymentName,\n );\n const newPath = deploymentStateDir(\n ctx,\n newDeployment.deploymentKind,\n newDeployment.deploymentName,\n );\n\n // If both paths are the same (project-local storage), no file movement needed.\n // The config will be updated separately by saveDeploymentConfig.\n if (oldPath === newPath) {\n logVerbose(\n `Source and destination are the same (${oldPath}), skipping file copy`,\n );\n return;\n }\n\n await recursivelyCopy(ctx, nodeFs, oldPath, newPath);\n recursivelyDelete(ctx, oldPath);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }
@@ -32,14 +32,6 @@ export async function bigBrainEnableFeatureMetadata(ctx) {
32
32
  data: {}
33
33
  });
34
34
  }
35
- export async function bigBrainGenerateAdminKeyForAnonymousDeployment(ctx, data) {
36
- return bigBrainAPI({
37
- ctx,
38
- method: "POST",
39
- path: "local_deployment/generate_admin_key",
40
- data
41
- });
42
- }
43
35
  export async function projectHasExistingCloudDev(ctx, {
44
36
  projectSlug,
45
37
  teamSlug
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/bigBrain.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { bigBrainAPI } from \"../utils/utils.js\";\n\nexport async function bigBrainStart(\n ctx: Context,\n data: {\n // cloud port\n port: number;\n projectSlug: string;\n teamSlug: string;\n instanceName: string | null;\n },\n): Promise<{ deploymentName: string; adminKey: string; projectId: number }> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/start\",\n data,\n });\n}\n\nexport async function bigBrainPause(\n ctx: Context,\n data: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<void> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/pause\",\n data,\n });\n}\n\nexport async function bigBrainRecordActivity(\n ctx: Context,\n data: {\n instanceName: string;\n },\n) {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/record_activity\",\n data,\n });\n}\n\nexport async function bigBrainEnableFeatureMetadata(\n ctx: Context,\n): Promise<{ totalProjects: { kind: \"none\" | \"one\" | \"multiple\" } }> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/enable_feature_metadata\",\n data: {},\n });\n}\n\nexport async function bigBrainGenerateAdminKeyForAnonymousDeployment(\n ctx: Context,\n data: {\n instanceName: string;\n instanceSecret: string;\n },\n) {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/generate_admin_key\",\n data,\n });\n}\n/** Whether a project already has a cloud dev deployment for this user. */\nexport async function projectHasExistingCloudDev(\n ctx: Context,\n {\n projectSlug,\n teamSlug,\n }: {\n projectSlug: string;\n teamSlug: string;\n },\n) {\n const response = await bigBrainAPI<\n | {\n kind: \"Exists\";\n }\n | {\n kind: \"DoesNotExist\";\n }\n >({\n ctx,\n method: \"POST\",\n path: \"deployment/existing_dev\",\n data: { projectSlug, teamSlug },\n });\n if (response.kind === \"Exists\") {\n return true;\n } else if (response.kind === \"DoesNotExist\") {\n return false;\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected /api/deployment/existing_dev response: ${JSON.stringify(response, null, 2)}`,\n });\n}\n"],
5
- "mappings": ";AACA,SAAS,mBAAmB;AAE5B,sBAAsB,cACpB,KACA,MAO0E;AAC1E,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,cACpB,KACA,MAIe;AACf,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,uBACpB,KACA,MAGA;AACA,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,8BACpB,KACmE;AACnE,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM,CAAC;AAAA,EACT,CAAC;AACH;AAEA,sBAAsB,+CACpB,KACA,MAIA;AACA,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,2BACpB,KACA;AAAA,EACE;AAAA,EACA;AACF,GAIA;AACA,QAAM,WAAW,MAAM,YAOrB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM,EAAE,aAAa,SAAS;AAAA,EAChC,CAAC;AACD,MAAI,SAAS,SAAS,UAAU;AAC9B,WAAO;AAAA,EACT,WAAW,SAAS,SAAS,gBAAgB;AAC3C,WAAO;AAAA,EACT;AACA,SAAO,MAAM,IAAI,MAAM;AAAA,IACrB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,gBAAgB,qDAAqD,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EACxG,CAAC;AACH;",
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { bigBrainAPI } from \"../utils/utils.js\";\n\nexport async function bigBrainStart(\n ctx: Context,\n data: {\n // cloud port\n port: number;\n projectSlug: string;\n teamSlug: string;\n instanceName: string | null;\n },\n): Promise<{\n deploymentName: string;\n /** @deprecated */\n adminKey: string;\n projectId: number;\n}> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/start\",\n data,\n });\n}\n\nexport async function bigBrainPause(\n ctx: Context,\n data: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<void> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/pause\",\n data,\n });\n}\n\nexport async function bigBrainRecordActivity(\n ctx: Context,\n data: {\n instanceName: string;\n adminKey: string;\n },\n) {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/record_activity\",\n data,\n });\n}\n\nexport async function bigBrainEnableFeatureMetadata(\n ctx: Context,\n): Promise<{ totalProjects: { kind: \"none\" | \"one\" | \"multiple\" } }> {\n return bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"local_deployment/enable_feature_metadata\",\n data: {},\n });\n}\n\n/** Whether a project already has a cloud dev deployment for this user. */\nexport async function projectHasExistingCloudDev(\n ctx: Context,\n {\n projectSlug,\n teamSlug,\n }: {\n projectSlug: string;\n teamSlug: string;\n },\n) {\n const response = await bigBrainAPI<\n | {\n kind: \"Exists\";\n }\n | {\n kind: \"DoesNotExist\";\n }\n >({\n ctx,\n method: \"POST\",\n path: \"deployment/existing_dev\",\n data: { projectSlug, teamSlug },\n });\n if (response.kind === \"Exists\") {\n return true;\n } else if (response.kind === \"DoesNotExist\") {\n return false;\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected /api/deployment/existing_dev response: ${JSON.stringify(response, null, 2)}`,\n });\n}\n"],
5
+ "mappings": ";AACA,SAAS,mBAAmB;AAE5B,sBAAsB,cACpB,KACA,MAYC;AACD,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,cACpB,KACA,MAIe;AACf,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,uBACpB,KACA,MAIA;AACA,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAEA,sBAAsB,8BACpB,KACmE;AACnE,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM,CAAC;AAAA,EACT,CAAC;AACH;AAGA,sBAAsB,2BACpB,KACA;AAAA,EACE;AAAA,EACA;AACF,GAIA;AACA,QAAM,WAAW,MAAM,YAOrB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM,EAAE,aAAa,SAAS;AAAA,EAChC,CAAC;AACD,MAAI,SAAS,SAAS,UAAU;AAC9B,WAAO;AAAA,EACT,WAAW,SAAS,SAAS,gBAAgB;AAC3C,WAAO;AAAA,EACT;AACA,SAAO,MAAM,IAAI,MAAM;AAAA,IACrB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,gBAAgB,qDAAqD,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EACxG,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -1,41 +1,58 @@
1
1
  "use strict";
2
2
  import {
3
3
  dashboardOutDir,
4
- loadDashboardConfig,
4
+ loadProjectDashboardConfig,
5
5
  loadUuidForAnonymousUser,
6
- saveDashboardConfig
6
+ saveProjectDashboardConfig
7
7
  } from "./filePaths.js";
8
8
  import { choosePorts } from "./utils.js";
9
9
  import { startServer } from "./serve.js";
10
- import { listExistingAnonymousDeployments } from "./anonymous.js";
11
10
  import { localDeploymentUrl, selfHostedEventTag } from "./run.js";
12
11
  import serveHandler from "serve-handler";
13
- import { ensureDashboardDownloaded } from "./download.js";
12
+ import {
13
+ ensureBackendBinaryDownloaded,
14
+ ensureDashboardDownloaded
15
+ } from "./download.js";
14
16
  import { bigBrainAPIMaybeThrows } from "../utils/utils.js";
15
17
  export const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;
16
- export const DEFAULT_LOCAL_DASHBOARD_API_PORT = 6791;
17
- export async function handleDashboard(ctx, version) {
18
+ export async function handleDashboard(ctx, deployment, options) {
19
+ const { version } = await ensureBackendBinaryDownloaded(
20
+ ctx,
21
+ options.backendVersion === void 0 ? { kind: "latest" } : { kind: "version", version: options.backendVersion }
22
+ );
18
23
  const anonymousId = loadUuidForAnonymousUser(ctx) ?? void 0;
19
- const isRunning = await checkIfDashboardIsRunning(ctx);
20
- if (isRunning) {
21
- return;
22
- }
23
24
  await ensureDashboardDownloaded(ctx, version);
24
- const [dashboardPort, apiPort] = await choosePorts(ctx, {
25
- count: 2,
25
+ const [dashboardPort] = await choosePorts(ctx, {
26
+ count: 1,
26
27
  startPort: DEFAULT_LOCAL_DASHBOARD_PORT,
27
28
  requestedPorts: [null, null]
28
29
  });
29
- await saveDashboardConfig(ctx, {
30
- port: dashboardPort,
31
- apiPort,
32
- version
30
+ saveProjectDashboardConfig(ctx, deployment.name, {
31
+ port: dashboardPort
33
32
  });
34
33
  let hasReportedSelfHostedEvent = false;
34
+ const serverOptions = { cors: false };
35
35
  const { cleanupHandle } = await startServer(
36
36
  ctx,
37
37
  dashboardPort,
38
38
  async (request, response) => {
39
+ const pathname = new URL(
40
+ request.url ?? "/",
41
+ // We only want to extract the pathname so the base doesn’t matter
42
+ "http://localhost"
43
+ ).pathname;
44
+ if (pathname === "/api/current_deployment") {
45
+ serverOptions;
46
+ response.setHeader("Content-Type", "application/json");
47
+ response.end(
48
+ JSON.stringify({
49
+ name: deployment.name,
50
+ url: localDeploymentUrl(deployment.cloudPort),
51
+ adminKey: deployment.adminKey
52
+ })
53
+ );
54
+ return;
55
+ }
39
56
  if (!hasReportedSelfHostedEvent) {
40
57
  hasReportedSelfHostedEvent = true;
41
58
  void reportSelfHostedEvent(ctx, {
@@ -48,9 +65,8 @@ export async function handleDashboard(ctx, version) {
48
65
  public: dashboardOutDir()
49
66
  });
50
67
  },
51
- {}
68
+ serverOptions
52
69
  );
53
- await startServingListDeploymentsApi(ctx, apiPort);
54
70
  return {
55
71
  dashboardPort,
56
72
  cleanupHandle
@@ -77,60 +93,11 @@ async function reportSelfHostedEvent(ctx, {
77
93
  } catch {
78
94
  }
79
95
  }
80
- async function startServingListDeploymentsApi(ctx, port) {
81
- await startServer(
82
- ctx,
83
- port,
84
- async (request, response) => {
85
- const deployments = await listExistingAnonymousDeployments(ctx);
86
- const deploymentsJson = deployments.map((d) => ({
87
- name: d.deploymentName,
88
- url: localDeploymentUrl(d.config.ports.cloud),
89
- adminKey: d.config.adminKey
90
- }));
91
- response.setHeader("Content-Type", "application/json");
92
- response.end(JSON.stringify({ deployments: deploymentsJson }));
93
- },
94
- {
95
- cors: true
96
- }
97
- );
98
- }
99
- export async function checkIfDashboardIsRunning(ctx) {
100
- const dashboardConfig = loadDashboardConfig(ctx);
101
- if (dashboardConfig === null) {
102
- return false;
103
- }
104
- let resp;
105
- try {
106
- resp = await fetch(`http://127.0.0.1:${dashboardConfig.apiPort}`);
107
- } catch {
108
- return false;
109
- }
110
- if (!resp.ok) {
111
- return false;
112
- }
113
- let data;
114
- try {
115
- data = await resp.json();
116
- } catch {
117
- return false;
118
- }
119
- return Array.isArray(data.deployments);
120
- }
121
96
  export function dashboardUrl(ctx, deploymentName) {
122
- const dashboardConfig = loadDashboardConfig(ctx);
97
+ const dashboardConfig = loadProjectDashboardConfig(ctx, deploymentName);
123
98
  if (dashboardConfig === null) {
124
99
  return null;
125
100
  }
126
- const queryParams = new URLSearchParams();
127
- if (dashboardConfig.apiPort !== DEFAULT_LOCAL_DASHBOARD_API_PORT) {
128
- queryParams.set("a", dashboardConfig.apiPort.toString());
129
- }
130
- queryParams.set("d", deploymentName);
131
- const queryString = queryParams.toString();
132
- const url = new URL(`http://127.0.0.1:${dashboardConfig.port}`);
133
- url.search = queryString;
134
- return url.href;
101
+ return `http://127.0.0.1:${dashboardConfig.port}/`;
135
102
  }
136
103
  //# sourceMappingURL=dashboard.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/dashboard.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n dashboardOutDir,\n loadDashboardConfig,\n loadUuidForAnonymousUser,\n saveDashboardConfig,\n} from \"./filePaths.js\";\nimport { choosePorts } from \"./utils.js\";\nimport { startServer } from \"./serve.js\";\nimport { listExistingAnonymousDeployments } from \"./anonymous.js\";\nimport { localDeploymentUrl, selfHostedEventTag } from \"./run.js\";\nimport serveHandler from \"serve-handler\";\nimport { ensureDashboardDownloaded } from \"./download.js\";\nimport { bigBrainAPIMaybeThrows } from \"../utils/utils.js\";\n\nexport const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;\nexport const DEFAULT_LOCAL_DASHBOARD_API_PORT = 6791;\n\n/**\n * This runs the `dashboard-self-hosted` app locally.\n * It's currently just used for the `anonymous` flow, while everything else\n * uses `dashboard.convex.dev`, and some of the code below is written\n * assuming this is only used for `anonymous`.\n */\nexport async function handleDashboard(ctx: Context, version: string) {\n const anonymousId = loadUuidForAnonymousUser(ctx) ?? undefined;\n const isRunning = await checkIfDashboardIsRunning(ctx);\n if (isRunning) {\n // It's possible this is running with a different version, but\n // let's not worry about that for now.\n return;\n }\n await ensureDashboardDownloaded(ctx, version);\n const [dashboardPort, apiPort] = await choosePorts(ctx, {\n count: 2,\n startPort: DEFAULT_LOCAL_DASHBOARD_PORT,\n requestedPorts: [null, null],\n });\n await saveDashboardConfig(ctx, {\n port: dashboardPort,\n apiPort,\n version,\n });\n\n let hasReportedSelfHostedEvent = false;\n\n const { cleanupHandle } = await startServer(\n ctx,\n dashboardPort,\n async (request, response) => {\n if (!hasReportedSelfHostedEvent) {\n hasReportedSelfHostedEvent = true;\n void reportSelfHostedEvent(ctx, {\n anonymousId,\n eventName: \"self_host_dashboard_connected\",\n tag: selfHostedEventTag(\"anonymous\"),\n });\n }\n await serveHandler(request, response, {\n public: dashboardOutDir(),\n });\n },\n {},\n );\n await startServingListDeploymentsApi(ctx, apiPort);\n return {\n dashboardPort,\n cleanupHandle,\n };\n}\n\nasync function reportSelfHostedEvent(\n ctx: Context,\n {\n anonymousId,\n eventName,\n eventFields,\n tag,\n }: {\n anonymousId: string | undefined;\n eventName: string;\n eventFields?: Record<string, unknown>;\n tag: string | undefined;\n },\n) {\n try {\n await bigBrainAPIMaybeThrows({\n ctx,\n method: \"POST\",\n path: \"self_hosted_event\",\n data: {\n selfHostedUuid: anonymousId,\n eventName,\n eventFields,\n tag,\n },\n });\n } catch {\n // ignore\n }\n}\n\n/**\n * This serves a really basic API that just returns a JSON blob with the deployments\n * and their credentials.\n * The locally running dashboard can hit this API.\n */\nasync function startServingListDeploymentsApi(ctx: Context, port: number) {\n await startServer(\n ctx,\n port,\n async (request, response) => {\n const deployments = await listExistingAnonymousDeployments(ctx);\n const deploymentsJson = deployments.map((d) => ({\n name: d.deploymentName,\n url: localDeploymentUrl(d.config.ports.cloud),\n adminKey: d.config.adminKey,\n }));\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(JSON.stringify({ deployments: deploymentsJson }));\n },\n {\n cors: true,\n },\n );\n}\n\nexport async function checkIfDashboardIsRunning(ctx: Context) {\n const dashboardConfig = loadDashboardConfig(ctx);\n if (dashboardConfig === null) {\n return false;\n }\n // We're checking if the mini API server is running and has a response that\n // looks like a list of deployments, since it's easier than checking the\n // dashboard UI + won't trigger the event for the developer opening the dashboard.\n let resp: Response;\n try {\n resp = await fetch(`http://127.0.0.1:${dashboardConfig.apiPort}`);\n } catch {\n return false;\n }\n if (!resp.ok) {\n return false;\n }\n let data: { deployments: { name: string; url: string; adminKey: string }[] };\n try {\n data = await resp.json();\n } catch {\n return false;\n }\n return Array.isArray(data.deployments);\n}\n\nexport function dashboardUrl(ctx: Context, deploymentName: string) {\n const dashboardConfig = loadDashboardConfig(ctx);\n if (dashboardConfig === null) {\n return null;\n }\n\n const queryParams = new URLSearchParams();\n if (dashboardConfig.apiPort !== DEFAULT_LOCAL_DASHBOARD_API_PORT) {\n queryParams.set(\"a\", dashboardConfig.apiPort.toString());\n }\n queryParams.set(\"d\", deploymentName);\n const queryString = queryParams.toString();\n const url = new URL(`http://127.0.0.1:${dashboardConfig.port}`);\n url.search = queryString;\n return url.href;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n dashboardOutDir,\n loadProjectDashboardConfig,\n loadUuidForAnonymousUser,\n saveProjectDashboardConfig,\n} from \"./filePaths.js\";\nimport { choosePorts } from \"./utils.js\";\nimport { startServer } from \"./serve.js\";\nimport { localDeploymentUrl, selfHostedEventTag } from \"./run.js\";\nimport serveHandler from \"serve-handler\";\nimport {\n ensureBackendBinaryDownloaded,\n ensureDashboardDownloaded,\n} from \"./download.js\";\nimport { bigBrainAPIMaybeThrows } from \"../utils/utils.js\";\n\nexport const DEFAULT_LOCAL_DASHBOARD_PORT = 6790;\n\n/**\n * This runs the `dashboard-self-hosted` app locally.\n * It's currently just used for the `anonymous` flow, while everything else\n * uses `dashboard.convex.dev`, and some of the code below is written\n * assuming this is only used for `anonymous`.\n */\nexport async function handleDashboard(\n ctx: Context,\n deployment: { name: string; cloudPort: number; adminKey: string },\n options: {\n /** The backend version to use if the user overrides the default version with the --local-backend-version flag */\n backendVersion: string | undefined;\n },\n) {\n // We call `ensureBackendBinaryDownloaded` here to get the version,\n // but `handleAnonymousDeployment` has already downloaded it.\n const { version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? { kind: \"latest\" }\n : { kind: \"version\", version: options.backendVersion },\n );\n const anonymousId = loadUuidForAnonymousUser(ctx) ?? undefined;\n await ensureDashboardDownloaded(ctx, version);\n const [dashboardPort] = await choosePorts(ctx, {\n count: 1,\n startPort: DEFAULT_LOCAL_DASHBOARD_PORT,\n requestedPorts: [null, null],\n });\n saveProjectDashboardConfig(ctx, deployment.name, {\n port: dashboardPort,\n });\n\n let hasReportedSelfHostedEvent = false;\n\n const serverOptions = { cors: false } as const;\n const { cleanupHandle } = await startServer(\n ctx,\n dashboardPort,\n async (request, response) => {\n const pathname = new URL(\n request.url ?? \"/\",\n // We only want to extract the pathname so the base doesn\u2019t matter\n \"http://localhost\",\n ).pathname;\n\n if (pathname === \"/api/current_deployment\") {\n serverOptions satisfies { cors: false };\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(\n JSON.stringify({\n name: deployment.name,\n url: localDeploymentUrl(deployment.cloudPort),\n adminKey: deployment.adminKey,\n }),\n );\n return;\n }\n\n if (!hasReportedSelfHostedEvent) {\n hasReportedSelfHostedEvent = true;\n void reportSelfHostedEvent(ctx, {\n anonymousId,\n eventName: \"self_host_dashboard_connected\",\n tag: selfHostedEventTag(\"anonymous\"),\n });\n }\n await serveHandler(request, response, {\n public: dashboardOutDir(),\n });\n },\n serverOptions,\n );\n return {\n dashboardPort,\n cleanupHandle,\n };\n}\n\nasync function reportSelfHostedEvent(\n ctx: Context,\n {\n anonymousId,\n eventName,\n eventFields,\n tag,\n }: {\n anonymousId: string | undefined;\n eventName: string;\n eventFields?: Record<string, unknown>;\n tag: string | undefined;\n },\n) {\n try {\n await bigBrainAPIMaybeThrows({\n ctx,\n method: \"POST\",\n path: \"self_hosted_event\",\n data: {\n selfHostedUuid: anonymousId,\n eventName,\n eventFields,\n tag,\n },\n });\n } catch {\n // ignore\n }\n}\n\nexport function dashboardUrl(ctx: Context, deploymentName: string) {\n const dashboardConfig = loadProjectDashboardConfig(ctx, deploymentName);\n if (dashboardConfig === null) {\n return null;\n }\n\n return `http://127.0.0.1:${dashboardConfig.port}/`;\n}\n"],
5
+ "mappings": ";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB,0BAA0B;AACvD,OAAO,kBAAkB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AAEhC,aAAM,+BAA+B;AAQ5C,sBAAsB,gBACpB,KACA,YACA,SAIA;AAGA,QAAM,EAAE,QAAQ,IAAI,MAAM;AAAA,IACxB;AAAA,IACA,QAAQ,mBAAmB,SACvB,EAAE,MAAM,SAAS,IACjB,EAAE,MAAM,WAAW,SAAS,QAAQ,eAAe;AAAA,EACzD;AACA,QAAM,cAAc,yBAAyB,GAAG,KAAK;AACrD,QAAM,0BAA0B,KAAK,OAAO;AAC5C,QAAM,CAAC,aAAa,IAAI,MAAM,YAAY,KAAK;AAAA,IAC7C,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB,CAAC,MAAM,IAAI;AAAA,EAC7B,CAAC;AACD,6BAA2B,KAAK,WAAW,MAAM;AAAA,IAC/C,MAAM;AAAA,EACR,CAAC;AAED,MAAI,6BAA6B;AAEjC,QAAM,gBAAgB,EAAE,MAAM,MAAM;AACpC,QAAM,EAAE,cAAc,IAAI,MAAM;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,OAAO,SAAS,aAAa;AAC3B,YAAM,WAAW,IAAI;AAAA,QACnB,QAAQ,OAAO;AAAA;AAAA,QAEf;AAAA,MACF,EAAE;AAEF,UAAI,aAAa,2BAA2B;AAC1C;AACA,iBAAS,UAAU,gBAAgB,kBAAkB;AACrD,iBAAS;AAAA,UACP,KAAK,UAAU;AAAA,YACb,MAAM,WAAW;AAAA,YACjB,KAAK,mBAAmB,WAAW,SAAS;AAAA,YAC5C,UAAU,WAAW;AAAA,UACvB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAEA,UAAI,CAAC,4BAA4B;AAC/B,qCAA6B;AAC7B,aAAK,sBAAsB,KAAK;AAAA,UAC9B;AAAA,UACA,WAAW;AAAA,UACX,KAAK,mBAAmB,WAAW;AAAA,QACrC,CAAC;AAAA,MACH;AACA,YAAM,aAAa,SAAS,UAAU;AAAA,QACpC,QAAQ,gBAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,sBACb,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMA;AACA,MAAI;AACF,UAAM,uBAAuB;AAAA,MAC3B;AAAA,MACA,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;AAEO,gBAAS,aAAa,KAAc,gBAAwB;AACjE,QAAM,kBAAkB,2BAA2B,KAAK,cAAc;AACtE,MAAI,oBAAoB,MAAM;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,oBAAoB,gBAAgB,IAAI;AACjD;",
6
6
  "names": []
7
7
  }
@@ -15,7 +15,8 @@ import {
15
15
  versionedBinaryDir,
16
16
  dashboardOutDir,
17
17
  resetDashboardDir,
18
- loadDashboardConfig,
18
+ loadGlobalDashboardConfig,
19
+ saveGlobalDashboardConfig,
19
20
  executableName
20
21
  } from "./filePaths.js";
21
22
  import child_process from "child_process";
@@ -66,7 +67,18 @@ async function _ensureBackendBinaryDownloaded(ctx, version) {
66
67
  const binaryPath = await downloadBackendBinary(ctx, version);
67
68
  return { version, binaryPath };
68
69
  }
70
+ let cachedLatestVersion = null;
69
71
  export async function findLatestVersionWithBinary(ctx, requireSuccess) {
72
+ if (cachedLatestVersion !== null) {
73
+ return cachedLatestVersion;
74
+ }
75
+ const result = await _findLatestVersionWithBinary(ctx, requireSuccess);
76
+ if (result !== null) {
77
+ cachedLatestVersion = result;
78
+ }
79
+ return result;
80
+ }
81
+ export async function _findLatestVersionWithBinary(ctx, requireSuccess) {
70
82
  async function maybeCrash(...args) {
71
83
  if (requireSuccess) {
72
84
  return await ctx.crash(...args);
@@ -233,12 +245,13 @@ async function downloadZipFile(ctx, args) {
233
245
  return executablePath(version);
234
246
  }
235
247
  export async function ensureDashboardDownloaded(ctx, version) {
236
- const config = loadDashboardConfig(ctx);
248
+ const config = loadGlobalDashboardConfig(ctx);
237
249
  if (config !== null && config.version === version) {
238
250
  return;
239
251
  }
240
252
  await resetDashboardDir(ctx);
241
253
  await _ensureDashboardDownloaded(ctx, version);
254
+ saveGlobalDashboardConfig(ctx, { version });
242
255
  }
243
256
  async function _ensureDashboardDownloaded(ctx, version) {
244
257
  const zipLocation = dashboardZip();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/download.ts"],
4
- "sourcesContent": ["import { version as npmVersion } from \"../../version.js\";\nimport AdmZip from \"adm-zip\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n startLogProgress,\n logVerbose,\n logMessage,\n logError,\n logWarning,\n} from \"../../../bundler/log.js\";\nimport {\n dashboardZip,\n executablePath,\n versionedBinaryDir,\n dashboardOutDir,\n resetDashboardDir,\n loadDashboardConfig,\n executableName,\n} from \"./filePaths.js\";\nimport child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { Readable } from \"stream\";\nimport { TempPath, nodeFs, withTmpDir } from \"../../../bundler/fs.js\";\nimport { recursivelyDelete, recursivelyCopy } from \"../fsUtils.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport type { ProgressBarInstance } from \"../../../vendor/progress/index.js\";\nimport path from \"path\";\n\nasync function makeExecutable(p: string) {\n switch (process.platform) {\n case \"darwin\":\n case \"linux\": {\n await promisify(child_process.exec)(`chmod +x ${p}`);\n }\n }\n}\n\nexport async function ensureBackendBinaryDownloaded(\n ctx: Context,\n version:\n | { kind: \"latest\"; allowedVersion?: string | undefined }\n | { kind: \"version\"; version: string },\n): Promise<{ binaryPath: string; version: string }> {\n if (version.kind === \"version\") {\n return _ensureBackendBinaryDownloaded(ctx, version.version);\n }\n if (version.allowedVersion) {\n const latestVersionWithBinary = await findLatestVersionWithBinary(\n ctx,\n false,\n );\n if (latestVersionWithBinary === null) {\n logWarning(\n `Failed to get latest version from GitHub, using downloaded version ${version.allowedVersion}`,\n );\n return _ensureBackendBinaryDownloaded(ctx, version.allowedVersion);\n }\n return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);\n }\n const latestVersionWithBinary = await findLatestVersionWithBinary(ctx, true);\n return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);\n}\n\nasync function _ensureBackendBinaryDownloaded(\n ctx: Context,\n version: string,\n): Promise<{ binaryPath: string; version: string }> {\n logVerbose(`Ensuring backend binary downloaded for version ${version}`);\n const existingDownload = await checkForExistingDownload(ctx, version);\n if (existingDownload !== null) {\n logVerbose(`Using existing download at ${existingDownload}`);\n return {\n binaryPath: existingDownload,\n version,\n };\n }\n const binaryPath = await downloadBackendBinary(ctx, version);\n return { version, binaryPath };\n}\n\n/**\n * Finds the latest version of the Convex local backend\n * through version.convex.dev\n */\nexport async function findLatestVersionWithBinary<\n RequireSuccess extends boolean,\n>(\n ctx: Context,\n requireSuccess: RequireSuccess,\n): Promise<RequireSuccess extends true ? string : string | null> {\n // These shouldn't crash when there's a perfectly good binary already available.\n async function maybeCrash(\n ...args: Parameters<typeof ctx.crash>\n ): Promise<RequireSuccess extends true ? never : null> {\n if (requireSuccess) {\n return await ctx.crash(...args);\n }\n if (args[0].printedMessage) {\n logError(args[0].printedMessage);\n } else {\n logError(\"Error fetching latest version\");\n }\n return null as RequireSuccess extends true ? never : null;\n }\n\n logVerbose(\"Fetching latest backend version from version API\");\n\n try {\n const response = await fetch(\n \"https://version.convex.dev/v1/local_backend_version\",\n {\n headers: { \"Convex-Client\": `npm-cli-${npmVersion}` },\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n return await maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `version.convex.dev returned ${response.status}: ${text}`,\n errForSentry: new LocalDeploymentError(\n `version.convex.dev returned ${response.status}: ${text}`,\n ),\n });\n }\n\n const data = (await response.json()) as { version: string };\n if (!data.version) {\n return await maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Invalid response missing version field\",\n errForSentry: new LocalDeploymentError(\n \"Invalid response missing version field\",\n ),\n });\n }\n\n logVerbose(`Latest backend version is ${data.version}`);\n return data.version;\n } catch (e) {\n return maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Failed to fetch latest backend version\",\n errForSentry: new LocalDeploymentError(e?.toString()),\n });\n }\n}\n\n/**\n *\n * @param ctx\n * @param version\n * @returns The binary path if it exists, or null\n */\nasync function checkForExistingDownload(\n ctx: Context,\n version: string,\n): Promise<string | null> {\n const destDir = versionedBinaryDir(version);\n if (!ctx.fs.exists(destDir)) {\n return null;\n }\n const p = executablePath(version);\n if (!ctx.fs.exists(p)) {\n // This directory isn't what we expected. Remove it.\n recursivelyDelete(ctx, destDir, { force: true });\n return null;\n }\n await makeExecutable(p);\n return p;\n}\n\nasync function downloadBackendBinary(\n ctx: Context,\n version: string,\n): Promise<string> {\n const downloadPath = getDownloadPath();\n // Note: We validate earlier that there's a binary for this platform at the specified version,\n // so in practice, we should never hit errors here.\n if (downloadPath === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unsupported platform ${process.platform} and architecture ${process.arch} for local deployment.`,\n });\n }\n await downloadZipFile(ctx, {\n version,\n filename: downloadPath,\n nameForLogging: \"Convex backend binary\",\n onDownloadComplete: async (ctx, unzippedPath) => {\n const name = executableName();\n const tempExecPath = path.join(unzippedPath, name);\n await makeExecutable(tempExecPath);\n logVerbose(\"Marked as executable\");\n ctx.fs.mkdir(versionedBinaryDir(version), { recursive: true });\n ctx.fs.swapTmpFile(tempExecPath as TempPath, executablePath(version));\n },\n });\n return executablePath(version);\n}\n\n/**\n * Get the artifact name, composed of the target convex-local-backend and\n * the Rust \"target triple\" appropriate for the current machine.\n **/\nfunction getDownloadPath() {\n switch (process.platform) {\n case \"darwin\":\n if (process.arch === \"arm64\") {\n return \"convex-local-backend-aarch64-apple-darwin.zip\";\n } else if (process.arch === \"x64\") {\n return \"convex-local-backend-x86_64-apple-darwin.zip\";\n }\n break;\n case \"linux\":\n if (process.arch === \"arm64\") {\n return \"convex-local-backend-aarch64-unknown-linux-gnu.zip\";\n } else if (process.arch === \"x64\") {\n return \"convex-local-backend-x86_64-unknown-linux-gnu.zip\";\n }\n break;\n case \"win32\":\n return \"convex-local-backend-x86_64-pc-windows-msvc.zip\";\n }\n return null;\n}\n\nfunction getGithubDownloadUrl(version: string, filename: string) {\n return `https://github.com/get-convex/convex-backend/releases/download/${version}/${filename}`;\n}\n\nasync function downloadZipFile(\n ctx: Context,\n args: {\n version: string;\n filename: string;\n nameForLogging: string;\n onDownloadComplete: (ctx: Context, unzippedPath: TempPath) => Promise<void>;\n },\n) {\n const { version, filename, nameForLogging } = args;\n const url = getGithubDownloadUrl(version, filename);\n const response = await fetch(url);\n const contentLength = parseInt(\n response.headers.get(\"content-length\") ?? \"\",\n 10,\n );\n let progressBar: ProgressBarInstance | null = null;\n if (!isNaN(contentLength) && contentLength !== 0 && process.stdout.isTTY) {\n progressBar = startLogProgress(\n `Downloading ${nameForLogging} [:bar] :percent :etas`,\n {\n width: 40,\n total: contentLength,\n clear: true,\n },\n );\n } else {\n logMessage(`Downloading ${nameForLogging}`);\n }\n if (response.status !== 200) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `File not found at ${url}.`,\n });\n }\n await withTmpDir(async (tmpDir) => {\n logVerbose(`Created tmp dir ${tmpDir.path}`);\n // Create a file in the tmp dir\n const zipLocation = tmpDir.registerTempPath(null);\n const readable = Readable.fromWeb(response.body! as any);\n await tmpDir.writeFileStream(zipLocation, readable, (chunk: any) => {\n if (progressBar !== null) {\n progressBar.tick(chunk.length);\n }\n });\n if (progressBar) {\n progressBar.terminate();\n logFinishedStep(`Downloaded ${nameForLogging}`);\n }\n logVerbose(\"Downloaded zip file\");\n\n const zip = new AdmZip(zipLocation);\n await withTmpDir(async (versionDir) => {\n logVerbose(`Created tmp dir ${versionDir.path}`);\n zip.extractAllTo(versionDir.path, true);\n logVerbose(\"Extracted from zip file\");\n await args.onDownloadComplete(ctx, versionDir.path);\n });\n });\n return executablePath(version);\n}\n\nexport async function ensureDashboardDownloaded(ctx: Context, version: string) {\n const config = loadDashboardConfig(ctx);\n if (config !== null && config.version === version) {\n return;\n }\n await resetDashboardDir(ctx);\n await _ensureDashboardDownloaded(ctx, version);\n}\nasync function _ensureDashboardDownloaded(ctx: Context, version: string) {\n const zipLocation = dashboardZip();\n if (ctx.fs.exists(zipLocation)) {\n ctx.fs.unlink(zipLocation);\n }\n const outDir = dashboardOutDir();\n await downloadZipFile(ctx, {\n version,\n filename: \"dashboard.zip\",\n nameForLogging: \"Convex dashboard\",\n onDownloadComplete: async (ctx, unzippedPath) => {\n await recursivelyCopy(ctx, nodeFs, unzippedPath, outDir);\n logVerbose(\"Copied into out dir\");\n },\n });\n return outDir;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { version as npmVersion } from \"../../version.js\";\nimport AdmZip from \"adm-zip\";\nimport { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n startLogProgress,\n logVerbose,\n logMessage,\n logError,\n logWarning,\n} from \"../../../bundler/log.js\";\nimport {\n dashboardZip,\n executablePath,\n versionedBinaryDir,\n dashboardOutDir,\n resetDashboardDir,\n loadGlobalDashboardConfig,\n saveGlobalDashboardConfig,\n executableName,\n} from \"./filePaths.js\";\nimport child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { Readable } from \"stream\";\nimport { TempPath, nodeFs, withTmpDir } from \"../../../bundler/fs.js\";\nimport { recursivelyDelete, recursivelyCopy } from \"../fsUtils.js\";\nimport { LocalDeploymentError } from \"./errors.js\";\nimport type { ProgressBarInstance } from \"../../../vendor/progress/index.js\";\nimport path from \"path\";\n\nasync function makeExecutable(p: string) {\n switch (process.platform) {\n case \"darwin\":\n case \"linux\": {\n await promisify(child_process.exec)(`chmod +x ${p}`);\n }\n }\n}\n\nexport async function ensureBackendBinaryDownloaded(\n ctx: Context,\n version:\n | { kind: \"latest\"; allowedVersion?: string | undefined }\n | { kind: \"version\"; version: string },\n): Promise<{ binaryPath: string; version: string }> {\n if (version.kind === \"version\") {\n return _ensureBackendBinaryDownloaded(ctx, version.version);\n }\n if (version.allowedVersion) {\n const latestVersionWithBinary = await findLatestVersionWithBinary(\n ctx,\n false,\n );\n if (latestVersionWithBinary === null) {\n logWarning(\n `Failed to get latest version from GitHub, using downloaded version ${version.allowedVersion}`,\n );\n return _ensureBackendBinaryDownloaded(ctx, version.allowedVersion);\n }\n return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);\n }\n const latestVersionWithBinary = await findLatestVersionWithBinary(ctx, true);\n return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);\n}\n\nasync function _ensureBackendBinaryDownloaded(\n ctx: Context,\n version: string,\n): Promise<{ binaryPath: string; version: string }> {\n logVerbose(`Ensuring backend binary downloaded for version ${version}`);\n const existingDownload = await checkForExistingDownload(ctx, version);\n if (existingDownload !== null) {\n logVerbose(`Using existing download at ${existingDownload}`);\n return {\n binaryPath: existingDownload,\n version,\n };\n }\n const binaryPath = await downloadBackendBinary(ctx, version);\n return { version, binaryPath };\n}\n\nlet cachedLatestVersion: string | null = null;\n\n/**\n * Finds the latest version of the Convex local backend through\n * version.convex.dev, caching the resolved version for the lifetime of the\n * process so repeated lookups hit the network at most once.\n *\n * Wraps {@link _findLatestVersionWithBinary}. Only successful (non-null)\n * results are cached, so a failed `requireSuccess: false` lookup can be retried\n * by a later call.\n */\nexport async function findLatestVersionWithBinary<\n RequireSuccess extends boolean,\n>(\n ctx: Context,\n requireSuccess: RequireSuccess,\n): Promise<RequireSuccess extends true ? string : string | null> {\n if (cachedLatestVersion !== null) {\n return cachedLatestVersion;\n }\n const result = await _findLatestVersionWithBinary(ctx, requireSuccess);\n if (result !== null) {\n cachedLatestVersion = result;\n }\n return result;\n}\n\n/**\n * Finds the latest version of the Convex local backend\n * through version.convex.dev\n */\nexport async function _findLatestVersionWithBinary<\n RequireSuccess extends boolean,\n>(\n ctx: Context,\n requireSuccess: RequireSuccess,\n): Promise<RequireSuccess extends true ? string : string | null> {\n // These shouldn't crash when there's a perfectly good binary already available.\n async function maybeCrash(\n ...args: Parameters<typeof ctx.crash>\n ): Promise<RequireSuccess extends true ? never : null> {\n if (requireSuccess) {\n return await ctx.crash(...args);\n }\n if (args[0].printedMessage) {\n logError(args[0].printedMessage);\n } else {\n logError(\"Error fetching latest version\");\n }\n return null as RequireSuccess extends true ? never : null;\n }\n\n logVerbose(\"Fetching latest backend version from version API\");\n\n try {\n const response = await fetch(\n \"https://version.convex.dev/v1/local_backend_version\",\n {\n headers: { \"Convex-Client\": `npm-cli-${npmVersion}` },\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n return await maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `version.convex.dev returned ${response.status}: ${text}`,\n errForSentry: new LocalDeploymentError(\n `version.convex.dev returned ${response.status}: ${text}`,\n ),\n });\n }\n\n const data = (await response.json()) as { version: string };\n if (!data.version) {\n return await maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Invalid response missing version field\",\n errForSentry: new LocalDeploymentError(\n \"Invalid response missing version field\",\n ),\n });\n }\n\n logVerbose(`Latest backend version is ${data.version}`);\n return data.version;\n } catch (e) {\n return maybeCrash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Failed to fetch latest backend version\",\n errForSentry: new LocalDeploymentError(e?.toString()),\n });\n }\n}\n\n/**\n *\n * @param ctx\n * @param version\n * @returns The binary path if it exists, or null\n */\nasync function checkForExistingDownload(\n ctx: Context,\n version: string,\n): Promise<string | null> {\n const destDir = versionedBinaryDir(version);\n if (!ctx.fs.exists(destDir)) {\n return null;\n }\n const p = executablePath(version);\n if (!ctx.fs.exists(p)) {\n // This directory isn't what we expected. Remove it.\n recursivelyDelete(ctx, destDir, { force: true });\n return null;\n }\n await makeExecutable(p);\n return p;\n}\n\nasync function downloadBackendBinary(\n ctx: Context,\n version: string,\n): Promise<string> {\n const downloadPath = getDownloadPath();\n // Note: We validate earlier that there's a binary for this platform at the specified version,\n // so in practice, we should never hit errors here.\n if (downloadPath === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unsupported platform ${process.platform} and architecture ${process.arch} for local deployment.`,\n });\n }\n await downloadZipFile(ctx, {\n version,\n filename: downloadPath,\n nameForLogging: \"Convex backend binary\",\n onDownloadComplete: async (ctx, unzippedPath) => {\n const name = executableName();\n const tempExecPath = path.join(unzippedPath, name);\n await makeExecutable(tempExecPath);\n logVerbose(\"Marked as executable\");\n ctx.fs.mkdir(versionedBinaryDir(version), { recursive: true });\n ctx.fs.swapTmpFile(tempExecPath as TempPath, executablePath(version));\n },\n });\n return executablePath(version);\n}\n\n/**\n * Get the artifact name, composed of the target convex-local-backend and\n * the Rust \"target triple\" appropriate for the current machine.\n **/\nfunction getDownloadPath() {\n switch (process.platform) {\n case \"darwin\":\n if (process.arch === \"arm64\") {\n return \"convex-local-backend-aarch64-apple-darwin.zip\";\n } else if (process.arch === \"x64\") {\n return \"convex-local-backend-x86_64-apple-darwin.zip\";\n }\n break;\n case \"linux\":\n if (process.arch === \"arm64\") {\n return \"convex-local-backend-aarch64-unknown-linux-gnu.zip\";\n } else if (process.arch === \"x64\") {\n return \"convex-local-backend-x86_64-unknown-linux-gnu.zip\";\n }\n break;\n case \"win32\":\n return \"convex-local-backend-x86_64-pc-windows-msvc.zip\";\n }\n return null;\n}\n\nfunction getGithubDownloadUrl(version: string, filename: string) {\n return `https://github.com/get-convex/convex-backend/releases/download/${version}/${filename}`;\n}\n\nasync function downloadZipFile(\n ctx: Context,\n args: {\n version: string;\n filename: string;\n nameForLogging: string;\n onDownloadComplete: (ctx: Context, unzippedPath: TempPath) => Promise<void>;\n },\n) {\n const { version, filename, nameForLogging } = args;\n const url = getGithubDownloadUrl(version, filename);\n const response = await fetch(url);\n const contentLength = parseInt(\n response.headers.get(\"content-length\") ?? \"\",\n 10,\n );\n let progressBar: ProgressBarInstance | null = null;\n if (!isNaN(contentLength) && contentLength !== 0 && process.stdout.isTTY) {\n progressBar = startLogProgress(\n `Downloading ${nameForLogging} [:bar] :percent :etas`,\n {\n width: 40,\n total: contentLength,\n clear: true,\n },\n );\n } else {\n logMessage(`Downloading ${nameForLogging}`);\n }\n if (response.status !== 200) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `File not found at ${url}.`,\n });\n }\n await withTmpDir(async (tmpDir) => {\n logVerbose(`Created tmp dir ${tmpDir.path}`);\n // Create a file in the tmp dir\n const zipLocation = tmpDir.registerTempPath(null);\n const readable = Readable.fromWeb(response.body! as any);\n await tmpDir.writeFileStream(zipLocation, readable, (chunk: any) => {\n if (progressBar !== null) {\n progressBar.tick(chunk.length);\n }\n });\n if (progressBar) {\n progressBar.terminate();\n logFinishedStep(`Downloaded ${nameForLogging}`);\n }\n logVerbose(\"Downloaded zip file\");\n\n const zip = new AdmZip(zipLocation);\n await withTmpDir(async (versionDir) => {\n logVerbose(`Created tmp dir ${versionDir.path}`);\n zip.extractAllTo(versionDir.path, true);\n logVerbose(\"Extracted from zip file\");\n await args.onDownloadComplete(ctx, versionDir.path);\n });\n });\n return executablePath(version);\n}\n\nexport async function ensureDashboardDownloaded(ctx: Context, version: string) {\n const config = loadGlobalDashboardConfig(ctx);\n if (config !== null && config.version === version) {\n return;\n }\n await resetDashboardDir(ctx);\n await _ensureDashboardDownloaded(ctx, version);\n // Record which version is now in `dashboardOutDir()`\n // so we can skip the download next time.\n saveGlobalDashboardConfig(ctx, { version });\n}\nasync function _ensureDashboardDownloaded(ctx: Context, version: string) {\n const zipLocation = dashboardZip();\n if (ctx.fs.exists(zipLocation)) {\n ctx.fs.unlink(zipLocation);\n }\n const outDir = dashboardOutDir();\n await downloadZipFile(ctx, {\n version,\n filename: \"dashboard.zip\",\n nameForLogging: \"Convex dashboard\",\n onDownloadComplete: async (ctx, unzippedPath) => {\n await recursivelyCopy(ctx, nodeFs, unzippedPath, outDir);\n logVerbose(\"Copied into out dir\");\n },\n });\n return outDir;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["latestVersionWithBinary", "ctx"]
7
7
  }
@@ -144,7 +144,7 @@ export async function resetDashboardDir(ctx) {
144
144
  export function dashboardOutDir() {
145
145
  return path.join(dashboardDir(), "out");
146
146
  }
147
- export function loadDashboardConfig(ctx) {
147
+ export function loadGlobalDashboardConfig(ctx) {
148
148
  const configFile = path.join(dashboardDir(), "config.json");
149
149
  if (!ctx.fs.exists(configFile)) {
150
150
  return null;
@@ -157,13 +157,40 @@ export function loadDashboardConfig(ctx) {
157
157
  return null;
158
158
  }
159
159
  }
160
- export function saveDashboardConfig(ctx, config) {
160
+ export function saveGlobalDashboardConfig(ctx, config) {
161
161
  const configFile = path.join(dashboardDir(), "config.json");
162
162
  if (!ctx.fs.exists(dashboardDir())) {
163
163
  ctx.fs.mkdir(dashboardDir(), { recursive: true });
164
164
  }
165
165
  ctx.fs.writeUtf8File(configFile, JSON.stringify(config));
166
166
  }
167
+ function dashboardConfigPath(ctx, deploymentName) {
168
+ return path.join(
169
+ deploymentStateDir(ctx, "anonymous", deploymentName),
170
+ "dashboard.json"
171
+ );
172
+ }
173
+ export function loadProjectDashboardConfig(ctx, deploymentName) {
174
+ const configFile = dashboardConfigPath(ctx, deploymentName);
175
+ if (!ctx.fs.exists(configFile)) {
176
+ return null;
177
+ }
178
+ const content = ctx.fs.readUtf8File(configFile);
179
+ try {
180
+ return JSON.parse(content);
181
+ } catch (e) {
182
+ logVerbose(`Failed to parse project dashboard config: ${e}`);
183
+ return null;
184
+ }
185
+ }
186
+ export function saveProjectDashboardConfig(ctx, deploymentName, config) {
187
+ const configPath = dashboardConfigPath(ctx, deploymentName);
188
+ const directoryPath = path.dirname(configPath);
189
+ if (!ctx.fs.exists(directoryPath)) {
190
+ ctx.fs.mkdir(directoryPath, { recursive: true });
191
+ }
192
+ ctx.fs.writeUtf8File(configPath, JSON.stringify(config));
193
+ }
167
194
  export function loadUuidForAnonymousUser(ctx) {
168
195
  const configFile = path.join(
169
196
  rootDeploymentStateDir("anonymous"),