convex 1.46.0 → 1.48.0-alpha.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 (479) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/dist/browser.bundle.js +7 -1
  3. package/dist/browser.bundle.js.map +2 -2
  4. package/dist/cjs/bundler/context.js +7 -5
  5. package/dist/cjs/bundler/context.js.map +2 -2
  6. package/dist/cjs/bundler/fs.js +47 -6
  7. package/dist/cjs/bundler/fs.js.map +2 -2
  8. package/dist/cjs/bundler/index.js +5 -4
  9. package/dist/cjs/bundler/index.js.map +2 -2
  10. package/dist/cjs/cli/account.js +237 -0
  11. package/dist/cjs/cli/account.js.map +7 -0
  12. package/dist/cjs/cli/codegen.js +0 -4
  13. package/dist/cjs/cli/codegen.js.map +2 -2
  14. package/dist/cjs/cli/configure.js +28 -6
  15. package/dist/cjs/cli/configure.js.map +2 -2
  16. package/dist/cjs/cli/deploy.js +27 -2
  17. package/dist/cjs/cli/deploy.js.map +2 -2
  18. package/dist/cjs/cli/deploymentSelect.js +2 -2
  19. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  20. package/dist/cjs/cli/dev.js +6 -0
  21. package/dist/cjs/cli/dev.js.map +2 -2
  22. package/dist/cjs/cli/env.js +10 -5
  23. package/dist/cjs/cli/env.js.map +2 -2
  24. package/dist/cjs/cli/envDefault.js +7 -2
  25. package/dist/cjs/cli/envDefault.js.map +2 -2
  26. package/dist/cjs/cli/generatedApi.js.map +1 -1
  27. package/dist/cjs/cli/lib/api.js +2 -0
  28. package/dist/cjs/cli/lib/api.js.map +2 -2
  29. package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js +113 -0
  30. package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
  31. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js +36 -47
  32. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  33. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js +58 -39
  34. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
  35. package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js +90 -0
  36. package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
  37. package/dist/cjs/cli/lib/codegen.js.map +2 -2
  38. package/dist/cjs/cli/lib/command.js +2 -1
  39. package/dist/cjs/cli/lib/command.js.map +2 -2
  40. package/dist/cjs/cli/lib/components/definition/bundle.js +37 -11
  41. package/dist/cjs/cli/lib/components/definition/bundle.js.map +2 -2
  42. package/dist/cjs/cli/lib/components.js +48 -5
  43. package/dist/cjs/cli/lib/components.js.map +2 -2
  44. package/dist/cjs/cli/lib/config.js +56 -17
  45. package/dist/cjs/cli/lib/config.js.map +2 -2
  46. package/dist/cjs/cli/lib/deploy2.js +3 -1
  47. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  48. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js +30 -2
  49. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js.map +2 -2
  50. package/dist/cjs/cli/lib/deployKeyWarning.js +43 -0
  51. package/dist/cjs/cli/lib/deployKeyWarning.js.map +7 -0
  52. package/dist/cjs/cli/lib/deployment.js +2 -0
  53. package/dist/cjs/cli/lib/deployment.js.map +2 -2
  54. package/dist/cjs/cli/lib/deploymentSelection.js +27 -18
  55. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  56. package/dist/cjs/cli/lib/dev.js +5 -0
  57. package/dist/cjs/cli/lib/dev.js.map +2 -2
  58. package/dist/cjs/cli/lib/envvars.js +32 -0
  59. package/dist/cjs/cli/lib/envvars.js.map +2 -2
  60. package/dist/cjs/cli/lib/formatValidationProgress.js +47 -0
  61. package/dist/cjs/cli/lib/formatValidationProgress.js.map +7 -0
  62. package/dist/cjs/cli/lib/fsUtils.js +1 -1
  63. package/dist/cjs/cli/lib/fsUtils.js.map +2 -2
  64. package/dist/cjs/cli/lib/generateDocs.js +1 -1
  65. package/dist/cjs/cli/lib/generateDocs.js.map +1 -1
  66. package/dist/cjs/cli/lib/indexes.js.map +1 -1
  67. package/dist/cjs/cli/lib/login.js +28 -4
  68. package/dist/cjs/cli/lib/login.js.map +2 -2
  69. package/dist/cjs/cli/lib/mcp/requestContext.js +5 -1
  70. package/dist/cjs/cli/lib/mcp/requestContext.js.map +2 -2
  71. package/dist/cjs/cli/lib/mcp/tools/env.js +10 -3
  72. package/dist/cjs/cli/lib/mcp/tools/env.js.map +2 -2
  73. package/dist/cjs/cli/lib/profileManagement.js +196 -0
  74. package/dist/cjs/cli/lib/profileManagement.js.map +7 -0
  75. package/dist/cjs/cli/lib/profiles.js +333 -0
  76. package/dist/cjs/cli/lib/profiles.js.map +7 -0
  77. package/dist/cjs/cli/lib/run.js +4 -0
  78. package/dist/cjs/cli/lib/run.js.map +2 -2
  79. package/dist/cjs/cli/lib/schemaEvaluation.js +62 -0
  80. package/dist/cjs/cli/lib/schemaEvaluation.js.map +7 -0
  81. package/dist/cjs/cli/lib/usageLimits.js +4 -2
  82. package/dist/cjs/cli/lib/usageLimits.js.map +2 -2
  83. package/dist/cjs/cli/lib/utils/mutex.js +9 -24
  84. package/dist/cjs/cli/lib/utils/mutex.js.map +2 -2
  85. package/dist/cjs/cli/lib/utils/utils.js +66 -27
  86. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  87. package/dist/cjs/cli/login.js +213 -114
  88. package/dist/cjs/cli/login.js.map +3 -3
  89. package/dist/cjs/cli/logout.js +113 -12
  90. package/dist/cjs/cli/logout.js.map +3 -3
  91. package/dist/cjs/cli/mcp.js +43 -10
  92. package/dist/cjs/cli/mcp.js.map +3 -3
  93. package/dist/cjs/cli/program.js +2 -1
  94. package/dist/cjs/cli/program.js.map +2 -2
  95. package/dist/cjs/cli/projectCreate.js +1 -1
  96. package/dist/cjs/cli/projectCreate.js.map +1 -1
  97. package/dist/cjs/index.js +1 -1
  98. package/dist/cjs/index.js.map +1 -1
  99. package/dist/cjs/server/impl/actions_impl.js +8 -3
  100. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  101. package/dist/cjs/server/impl/storage_impl.js +29 -0
  102. package/dist/cjs/server/impl/storage_impl.js.map +2 -2
  103. package/dist/cjs/server/index.js +1 -0
  104. package/dist/cjs/server/index.js.map +2 -2
  105. package/dist/cjs/server/meta.js.map +1 -1
  106. package/dist/cjs/server/registration.js.map +1 -1
  107. package/dist/cjs/server/schema.js +34 -12
  108. package/dist/cjs/server/schema.js.map +2 -2
  109. package/dist/cjs/server/storage.js.map +1 -1
  110. package/dist/cjs/values/validators.js +1 -1
  111. package/dist/cjs/values/validators.js.map +2 -2
  112. package/dist/cjs/values/value.js +6 -0
  113. package/dist/cjs/values/value.js.map +2 -2
  114. package/dist/cjs-types/bundler/context.d.ts +5 -0
  115. package/dist/cjs-types/bundler/context.d.ts.map +1 -1
  116. package/dist/cjs-types/bundler/fs.d.ts +7 -2
  117. package/dist/cjs-types/bundler/fs.d.ts.map +1 -1
  118. package/dist/cjs-types/bundler/index.d.ts +9 -2
  119. package/dist/cjs-types/bundler/index.d.ts.map +1 -1
  120. package/dist/cjs-types/cli/account.d.ts +6 -0
  121. package/dist/cjs-types/cli/account.d.ts.map +1 -0
  122. package/dist/cjs-types/cli/codegen.d.ts.map +1 -1
  123. package/dist/cjs-types/cli/configure.d.ts +6 -0
  124. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  125. package/dist/cjs-types/cli/deploy.d.ts +2 -0
  126. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  127. package/dist/cjs-types/cli/deploymentCreate.d.ts +6 -6
  128. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  129. package/dist/cjs-types/cli/dev.d.ts +1 -0
  130. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  131. package/dist/cjs-types/cli/env.d.ts.map +1 -1
  132. package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
  133. package/dist/cjs-types/cli/generatedApi.d.ts +1 -1
  134. package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
  135. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  136. package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
  137. package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
  138. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
  139. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  140. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
  141. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
  142. package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
  143. package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
  144. package/dist/cjs-types/cli/lib/codegen.d.ts +0 -3
  145. package/dist/cjs-types/cli/lib/codegen.d.ts.map +1 -1
  146. package/dist/cjs-types/cli/lib/command.d.ts +2 -0
  147. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  148. package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts +13 -0
  149. package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
  150. package/dist/cjs-types/cli/lib/components.d.ts +4 -0
  151. package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
  152. package/dist/cjs-types/cli/lib/config.d.ts +2 -1
  153. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  154. package/dist/cjs-types/cli/lib/deploy2.d.ts +2 -0
  155. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  156. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
  157. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
  158. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts +3 -0
  159. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
  160. package/dist/cjs-types/cli/lib/deployment.d.ts +2 -0
  161. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  162. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +2 -1
  163. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  164. package/dist/cjs-types/cli/lib/dev.d.ts +1 -0
  165. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  166. package/dist/cjs-types/cli/lib/envvars.d.ts +6 -0
  167. package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
  168. package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts +8 -0
  169. package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
  170. package/dist/cjs-types/cli/lib/fsUtils.d.ts +1 -0
  171. package/dist/cjs-types/cli/lib/fsUtils.d.ts.map +1 -1
  172. package/dist/cjs-types/cli/lib/login.d.ts +3 -1
  173. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  174. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  175. package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts +8 -5
  176. package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
  177. package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  178. package/dist/cjs-types/cli/lib/profileManagement.d.ts +10 -0
  179. package/dist/cjs-types/cli/lib/profileManagement.d.ts.map +1 -0
  180. package/dist/cjs-types/cli/lib/profiles.d.ts +59 -0
  181. package/dist/cjs-types/cli/lib/profiles.d.ts.map +1 -0
  182. package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
  183. package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts +33 -0
  184. package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
  185. package/dist/cjs-types/cli/lib/usageLimits.d.ts +1 -1
  186. package/dist/cjs-types/cli/lib/usageLimits.d.ts.map +1 -1
  187. package/dist/cjs-types/cli/lib/utils/mutex.d.ts +1 -3
  188. package/dist/cjs-types/cli/lib/utils/mutex.d.ts.map +1 -1
  189. package/dist/cjs-types/cli/lib/utils/utils.d.ts +15 -2
  190. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  191. package/dist/cjs-types/cli/login.d.ts +21 -0
  192. package/dist/cjs-types/cli/login.d.ts.map +1 -1
  193. package/dist/cjs-types/cli/logout.d.ts +8 -1
  194. package/dist/cjs-types/cli/logout.d.ts.map +1 -1
  195. package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
  196. package/dist/cjs-types/cli/program.d.ts.map +1 -1
  197. package/dist/cjs-types/index.d.ts +1 -1
  198. package/dist/cjs-types/index.d.ts.map +1 -1
  199. package/dist/cjs-types/server/impl/actions_impl.d.ts +18 -3
  200. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  201. package/dist/cjs-types/server/impl/storage_impl.d.ts.map +1 -1
  202. package/dist/cjs-types/server/index.d.ts +1 -1
  203. package/dist/cjs-types/server/index.d.ts.map +1 -1
  204. package/dist/cjs-types/server/meta.d.ts +63 -0
  205. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  206. package/dist/cjs-types/server/registration.d.ts +10 -0
  207. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  208. package/dist/cjs-types/server/schema.d.ts +33 -0
  209. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  210. package/dist/cjs-types/server/storage.d.ts.map +1 -1
  211. package/dist/cjs-types/values/value.d.ts.map +1 -1
  212. package/dist/cli.bundle.cjs +4889 -2980
  213. package/dist/cli.bundle.cjs.map +4 -4
  214. package/dist/esm/bundler/context.js +7 -5
  215. package/dist/esm/bundler/context.js.map +2 -2
  216. package/dist/esm/bundler/fs.js +47 -6
  217. package/dist/esm/bundler/fs.js.map +2 -2
  218. package/dist/esm/bundler/index.js +5 -4
  219. package/dist/esm/bundler/index.js.map +2 -2
  220. package/dist/esm/cli/account.js +221 -0
  221. package/dist/esm/cli/account.js.map +7 -0
  222. package/dist/esm/cli/codegen.js +0 -4
  223. package/dist/esm/cli/codegen.js.map +2 -2
  224. package/dist/esm/cli/configure.js +27 -6
  225. package/dist/esm/cli/configure.js.map +2 -2
  226. package/dist/esm/cli/deploy.js +27 -2
  227. package/dist/esm/cli/deploy.js.map +2 -2
  228. package/dist/esm/cli/deploymentSelect.js +6 -3
  229. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  230. package/dist/esm/cli/dev.js +6 -0
  231. package/dist/esm/cli/dev.js.map +2 -2
  232. package/dist/esm/cli/env.js +11 -6
  233. package/dist/esm/cli/env.js.map +2 -2
  234. package/dist/esm/cli/envDefault.js +7 -2
  235. package/dist/esm/cli/envDefault.js.map +2 -2
  236. package/dist/esm/cli/lib/api.js +2 -0
  237. package/dist/esm/cli/lib/api.js.map +2 -2
  238. package/dist/esm/cli/lib/checkForLargeIndexBackfill.js +95 -0
  239. package/dist/esm/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
  240. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js +37 -48
  241. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  242. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js +63 -41
  243. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
  244. package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js +68 -0
  245. package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
  246. package/dist/esm/cli/lib/codegen.js.map +2 -2
  247. package/dist/esm/cli/lib/command.js +2 -1
  248. package/dist/esm/cli/lib/command.js.map +2 -2
  249. package/dist/esm/cli/lib/components/definition/bundle.js +37 -11
  250. package/dist/esm/cli/lib/components/definition/bundle.js.map +2 -2
  251. package/dist/esm/cli/lib/components.js +55 -5
  252. package/dist/esm/cli/lib/components.js.map +2 -2
  253. package/dist/esm/cli/lib/config.js +55 -17
  254. package/dist/esm/cli/lib/config.js.map +2 -2
  255. package/dist/esm/cli/lib/deploy2.js +3 -1
  256. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  257. package/dist/esm/cli/lib/deployApi/evaluateSchema.js +28 -2
  258. package/dist/esm/cli/lib/deployApi/evaluateSchema.js.map +2 -2
  259. package/dist/esm/cli/lib/deployKeyWarning.js +27 -0
  260. package/dist/esm/cli/lib/deployKeyWarning.js.map +7 -0
  261. package/dist/esm/cli/lib/deployment.js +2 -2
  262. package/dist/esm/cli/lib/deployment.js.map +2 -2
  263. package/dist/esm/cli/lib/deploymentSelection.js +35 -20
  264. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  265. package/dist/esm/cli/lib/dev.js +5 -0
  266. package/dist/esm/cli/lib/dev.js.map +2 -2
  267. package/dist/esm/cli/lib/envvars.js +35 -1
  268. package/dist/esm/cli/lib/envvars.js.map +2 -2
  269. package/dist/esm/cli/lib/formatValidationProgress.js +24 -0
  270. package/dist/esm/cli/lib/formatValidationProgress.js.map +7 -0
  271. package/dist/esm/cli/lib/fsUtils.js +1 -1
  272. package/dist/esm/cli/lib/fsUtils.js.map +2 -2
  273. package/dist/esm/cli/lib/generateDocs.js +1 -1
  274. package/dist/esm/cli/lib/generateDocs.js.map +1 -1
  275. package/dist/esm/cli/lib/indexes.js.map +1 -1
  276. package/dist/esm/cli/lib/login.js +36 -4
  277. package/dist/esm/cli/lib/login.js.map +2 -2
  278. package/dist/esm/cli/lib/mcp/requestContext.js +5 -1
  279. package/dist/esm/cli/lib/mcp/requestContext.js.map +2 -2
  280. package/dist/esm/cli/lib/mcp/tools/env.js +10 -3
  281. package/dist/esm/cli/lib/mcp/tools/env.js.map +2 -2
  282. package/dist/esm/cli/lib/profileManagement.js +179 -0
  283. package/dist/esm/cli/lib/profileManagement.js.map +7 -0
  284. package/dist/esm/cli/lib/profiles.js +288 -0
  285. package/dist/esm/cli/lib/profiles.js.map +7 -0
  286. package/dist/esm/cli/lib/run.js +4 -0
  287. package/dist/esm/cli/lib/run.js.map +2 -2
  288. package/dist/esm/cli/lib/schemaEvaluation.js +39 -0
  289. package/dist/esm/cli/lib/schemaEvaluation.js.map +7 -0
  290. package/dist/esm/cli/lib/usageLimits.js +4 -2
  291. package/dist/esm/cli/lib/usageLimits.js.map +2 -2
  292. package/dist/esm/cli/lib/utils/mutex.js +9 -24
  293. package/dist/esm/cli/lib/utils/mutex.js.map +2 -2
  294. package/dist/esm/cli/lib/utils/utils.js +63 -27
  295. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  296. package/dist/esm/cli/login.js +225 -112
  297. package/dist/esm/cli/login.js.map +3 -3
  298. package/dist/esm/cli/logout.js +110 -13
  299. package/dist/esm/cli/logout.js.map +2 -2
  300. package/dist/esm/cli/mcp.js +34 -10
  301. package/dist/esm/cli/mcp.js.map +2 -2
  302. package/dist/esm/cli/program.js +2 -1
  303. package/dist/esm/cli/program.js.map +2 -2
  304. package/dist/esm/cli/projectCreate.js +1 -1
  305. package/dist/esm/cli/projectCreate.js.map +1 -1
  306. package/dist/esm/index.js +1 -1
  307. package/dist/esm/index.js.map +1 -1
  308. package/dist/esm/server/impl/actions_impl.js +7 -3
  309. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  310. package/dist/esm/server/impl/storage_impl.js +29 -0
  311. package/dist/esm/server/impl/storage_impl.js.map +2 -2
  312. package/dist/esm/server/index.js +4 -1
  313. package/dist/esm/server/index.js.map +2 -2
  314. package/dist/esm/server/schema.js +34 -12
  315. package/dist/esm/server/schema.js.map +2 -2
  316. package/dist/esm/values/validators.js +1 -1
  317. package/dist/esm/values/validators.js.map +2 -2
  318. package/dist/esm/values/value.js +6 -0
  319. package/dist/esm/values/value.js.map +2 -2
  320. package/dist/esm-types/bundler/context.d.ts +5 -0
  321. package/dist/esm-types/bundler/context.d.ts.map +1 -1
  322. package/dist/esm-types/bundler/fs.d.ts +7 -2
  323. package/dist/esm-types/bundler/fs.d.ts.map +1 -1
  324. package/dist/esm-types/bundler/index.d.ts +9 -2
  325. package/dist/esm-types/bundler/index.d.ts.map +1 -1
  326. package/dist/esm-types/cli/account.d.ts +6 -0
  327. package/dist/esm-types/cli/account.d.ts.map +1 -0
  328. package/dist/esm-types/cli/codegen.d.ts.map +1 -1
  329. package/dist/esm-types/cli/configure.d.ts +6 -0
  330. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  331. package/dist/esm-types/cli/deploy.d.ts +2 -0
  332. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  333. package/dist/esm-types/cli/deploymentCreate.d.ts +6 -6
  334. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  335. package/dist/esm-types/cli/dev.d.ts +1 -0
  336. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  337. package/dist/esm-types/cli/env.d.ts.map +1 -1
  338. package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
  339. package/dist/esm-types/cli/generatedApi.d.ts +1 -1
  340. package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
  341. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  342. package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
  343. package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
  344. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
  345. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  346. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
  347. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
  348. package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
  349. package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
  350. package/dist/esm-types/cli/lib/codegen.d.ts +0 -3
  351. package/dist/esm-types/cli/lib/codegen.d.ts.map +1 -1
  352. package/dist/esm-types/cli/lib/command.d.ts +2 -0
  353. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  354. package/dist/esm-types/cli/lib/components/definition/bundle.d.ts +13 -0
  355. package/dist/esm-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
  356. package/dist/esm-types/cli/lib/components.d.ts +4 -0
  357. package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
  358. package/dist/esm-types/cli/lib/config.d.ts +2 -1
  359. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  360. package/dist/esm-types/cli/lib/deploy2.d.ts +2 -0
  361. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  362. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
  363. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
  364. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts +3 -0
  365. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
  366. package/dist/esm-types/cli/lib/deployment.d.ts +2 -0
  367. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  368. package/dist/esm-types/cli/lib/deploymentSelection.d.ts +2 -1
  369. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  370. package/dist/esm-types/cli/lib/dev.d.ts +1 -0
  371. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  372. package/dist/esm-types/cli/lib/envvars.d.ts +6 -0
  373. package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
  374. package/dist/esm-types/cli/lib/formatValidationProgress.d.ts +8 -0
  375. package/dist/esm-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
  376. package/dist/esm-types/cli/lib/fsUtils.d.ts +1 -0
  377. package/dist/esm-types/cli/lib/fsUtils.d.ts.map +1 -1
  378. package/dist/esm-types/cli/lib/login.d.ts +3 -1
  379. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  380. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  381. package/dist/esm-types/cli/lib/mcp/tools/env.d.ts +8 -5
  382. package/dist/esm-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
  383. package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  384. package/dist/esm-types/cli/lib/profileManagement.d.ts +10 -0
  385. package/dist/esm-types/cli/lib/profileManagement.d.ts.map +1 -0
  386. package/dist/esm-types/cli/lib/profiles.d.ts +59 -0
  387. package/dist/esm-types/cli/lib/profiles.d.ts.map +1 -0
  388. package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
  389. package/dist/esm-types/cli/lib/schemaEvaluation.d.ts +33 -0
  390. package/dist/esm-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
  391. package/dist/esm-types/cli/lib/usageLimits.d.ts +1 -1
  392. package/dist/esm-types/cli/lib/usageLimits.d.ts.map +1 -1
  393. package/dist/esm-types/cli/lib/utils/mutex.d.ts +1 -3
  394. package/dist/esm-types/cli/lib/utils/mutex.d.ts.map +1 -1
  395. package/dist/esm-types/cli/lib/utils/utils.d.ts +15 -2
  396. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  397. package/dist/esm-types/cli/login.d.ts +21 -0
  398. package/dist/esm-types/cli/login.d.ts.map +1 -1
  399. package/dist/esm-types/cli/logout.d.ts +8 -1
  400. package/dist/esm-types/cli/logout.d.ts.map +1 -1
  401. package/dist/esm-types/cli/mcp.d.ts.map +1 -1
  402. package/dist/esm-types/cli/program.d.ts.map +1 -1
  403. package/dist/esm-types/index.d.ts +1 -1
  404. package/dist/esm-types/index.d.ts.map +1 -1
  405. package/dist/esm-types/server/impl/actions_impl.d.ts +18 -3
  406. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  407. package/dist/esm-types/server/impl/storage_impl.d.ts.map +1 -1
  408. package/dist/esm-types/server/index.d.ts +1 -1
  409. package/dist/esm-types/server/index.d.ts.map +1 -1
  410. package/dist/esm-types/server/meta.d.ts +63 -0
  411. package/dist/esm-types/server/meta.d.ts.map +1 -1
  412. package/dist/esm-types/server/registration.d.ts +10 -0
  413. package/dist/esm-types/server/registration.d.ts.map +1 -1
  414. package/dist/esm-types/server/schema.d.ts +33 -0
  415. package/dist/esm-types/server/schema.d.ts.map +1 -1
  416. package/dist/esm-types/server/storage.d.ts.map +1 -1
  417. package/dist/esm-types/values/value.d.ts.map +1 -1
  418. package/dist/react.bundle.js +7 -1
  419. package/dist/react.bundle.js.map +2 -2
  420. package/package.json +5 -5
  421. package/schemas/convex.schema.json +5 -5
  422. package/src/bundler/context.ts +9 -5
  423. package/src/bundler/fs.ts +54 -5
  424. package/src/bundler/index.ts +9 -4
  425. package/src/cli/account.ts +320 -0
  426. package/src/cli/codegen.ts +0 -2
  427. package/src/cli/configure.ts +45 -9
  428. package/src/cli/deploy.ts +36 -5
  429. package/src/cli/deploymentSelect.ts +7 -4
  430. package/src/cli/dev.ts +9 -0
  431. package/src/cli/env.ts +12 -6
  432. package/src/cli/envDefault.ts +8 -2
  433. package/src/cli/generatedApi.ts +1 -1
  434. package/src/cli/lib/api.ts +5 -1
  435. package/src/cli/lib/checkForLargeIndexBackfill.ts +173 -0
  436. package/src/cli/lib/checkForLargeIndexDeletion.ts +45 -58
  437. package/src/cli/lib/checkForSlowSchemaValidation.ts +76 -65
  438. package/src/cli/lib/checkForStagedValidatorDeletion.ts +104 -0
  439. package/src/cli/lib/codegen.ts +0 -3
  440. package/src/cli/lib/command.ts +3 -0
  441. package/src/cli/lib/components/definition/bundle.ts +68 -14
  442. package/src/cli/lib/components.ts +71 -4
  443. package/src/cli/lib/config.ts +85 -18
  444. package/src/cli/lib/deploy2.ts +10 -1
  445. package/src/cli/lib/deployApi/evaluateSchema.ts +35 -0
  446. package/src/cli/lib/deployKeyWarning.ts +43 -0
  447. package/src/cli/lib/deployment.ts +2 -2
  448. package/src/cli/lib/deploymentSelection.ts +37 -18
  449. package/src/cli/lib/dev.ts +14 -0
  450. package/src/cli/lib/envvars.ts +43 -1
  451. package/src/cli/lib/formatValidationProgress.ts +35 -0
  452. package/src/cli/lib/fsUtils.ts +5 -2
  453. package/src/cli/lib/generateDocs.ts +1 -1
  454. package/src/cli/lib/indexes.ts +1 -1
  455. package/src/cli/lib/login.ts +47 -3
  456. package/src/cli/lib/mcp/requestContext.ts +7 -1
  457. package/src/cli/lib/mcp/tools/env.ts +17 -3
  458. package/src/cli/lib/profileManagement.ts +262 -0
  459. package/src/cli/lib/profiles.ts +398 -0
  460. package/src/cli/lib/run.ts +2 -0
  461. package/src/cli/lib/schemaEvaluation.ts +88 -0
  462. package/src/cli/lib/usageLimits.ts +2 -0
  463. package/src/cli/lib/utils/mutex.ts +9 -27
  464. package/src/cli/lib/utils/utils.ts +83 -36
  465. package/src/cli/login.ts +293 -168
  466. package/src/cli/logout.ts +142 -17
  467. package/src/cli/mcp.ts +48 -11
  468. package/src/cli/program.ts +2 -0
  469. package/src/cli/projectCreate.ts +1 -1
  470. package/src/index.ts +1 -1
  471. package/src/server/impl/actions_impl.ts +26 -6
  472. package/src/server/impl/storage_impl.ts +30 -0
  473. package/src/server/index.ts +5 -1
  474. package/src/server/meta.ts +56 -2
  475. package/src/server/registration.ts +10 -0
  476. package/src/server/schema.ts +37 -15
  477. package/src/server/storage.ts +17 -0
  478. package/src/values/validators.ts +1 -1
  479. package/src/values/value.ts +9 -5
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ import { logMessage, logWarning } from "../../bundler/log.js";
3
+ import { provisionHost } from "./config.js";
4
+ import { version } from "../version.js";
5
+ import {
6
+ isAnonymousDeployment,
7
+ getDeploymentTypeFromConfiguredDeployment,
8
+ stripDeploymentTypePrefix
9
+ } from "./deployment.js";
10
+ import { CONVEX_DEPLOYMENT_ENV_VAR_NAME } from "./utils/utils.js";
11
+ import { promptYesNo } from "./utils/prompts.js";
12
+ import { loadProjectEnvironmentVariables } from "./envvars.js";
13
+ import {
14
+ readProfileCredentials,
15
+ readProfileSettings,
16
+ readProfileToken,
17
+ savedProfileNames,
18
+ writeProfileDirectory
19
+ } from "./profiles.js";
20
+ export async function profileApi(token, pathname, body) {
21
+ return await fetch(`${provisionHost}${pathname}`, {
22
+ method: body === void 0 ? "GET" : "POST",
23
+ headers: {
24
+ Authorization: `Bearer ${token}`,
25
+ "Convex-Client": `npm-cli-${version}`,
26
+ ...body === void 0 ? {} : { "Content-Type": "application/json" }
27
+ },
28
+ ...body === void 0 ? {} : { body: JSON.stringify(body) },
29
+ signal: AbortSignal.timeout(1e4)
30
+ });
31
+ }
32
+ export async function deploymentAccess(token, deploymentName) {
33
+ try {
34
+ const response = await profileApi(
35
+ token,
36
+ `/v1/deployments/${encodeURIComponent(deploymentName)}`
37
+ );
38
+ if (response.ok) return "yes";
39
+ return [401, 403, 404].includes(response.status) ? "no" : "unknown";
40
+ } catch {
41
+ return "unknown";
42
+ }
43
+ }
44
+ export async function projectAccess(token, target) {
45
+ if (target.kind === "deploymentName")
46
+ return deploymentAccess(token, target.deploymentName);
47
+ if (target.kind !== "teamAndProjectSlugs") return "unknown";
48
+ try {
49
+ const response = await profileApi(
50
+ token,
51
+ `/v1/teams/${encodeURIComponent(target.teamSlug)}/projects/${encodeURIComponent(target.projectSlug)}`
52
+ );
53
+ if (response.ok) return "yes";
54
+ return [401, 403, 404].includes(response.status) ? "no" : "unknown";
55
+ } catch {
56
+ return "unknown";
57
+ }
58
+ }
59
+ function configuredCloudDeployment() {
60
+ const configured = process.env[CONVEX_DEPLOYMENT_ENV_VAR_NAME]?.trim();
61
+ if (!configured || getDeploymentTypeFromConfiguredDeployment(configured) === "local")
62
+ return null;
63
+ const name = stripDeploymentTypePrefix(configured);
64
+ return isAnonymousDeployment(name) ? null : name;
65
+ }
66
+ export async function bindProfileToDirectory(ctx, name, force = false, target) {
67
+ const credentials = await readProfileCredentials(ctx, {
68
+ name,
69
+ source: "account selection"
70
+ });
71
+ loadProjectEnvironmentVariables();
72
+ const deployment = configuredCloudDeployment();
73
+ const selectedTarget = target ?? (deployment === null ? null : {
74
+ kind: "deploymentName",
75
+ deploymentName: deployment,
76
+ deploymentType: null
77
+ });
78
+ if (!force && selectedTarget !== null) {
79
+ const label = selectedTarget.kind === "teamAndProjectSlugs" ? `project "${selectedTarget.teamSlug}/${selectedTarget.projectSlug}"` : `deployment "${selectedTarget.kind === "deploymentName" ? selectedTarget.deploymentName : "configured"}"`;
80
+ const access = await projectAccess(
81
+ credentials.accessToken,
82
+ selectedTarget
83
+ );
84
+ if (access !== "yes") {
85
+ logWarning(
86
+ access === "no" ? `Account "${name}" cannot access ${label}.` : `Could not verify whether account "${name}" can access ${label}.`
87
+ );
88
+ if (!process.stdin.isTTY || !await promptYesNo(ctx, {
89
+ message: `Use account "${name}" here anyway?`,
90
+ default: false
91
+ })) {
92
+ logMessage(
93
+ `Directory selection unchanged. To select this account anyway, run \`npx convex account select ${name} --force\`.`
94
+ );
95
+ return false;
96
+ }
97
+ }
98
+ }
99
+ await writeProfileDirectory(ctx, name);
100
+ return true;
101
+ }
102
+ export async function profileLoginMetadata(ctx, profile, loginToken, previous) {
103
+ let identity = null;
104
+ try {
105
+ const response = await profileApi(loginToken, "/api/dashboard/profile");
106
+ if (response.ok) {
107
+ const data = await response.json();
108
+ if ((typeof data.id === "number" || typeof data.id === "string") && typeof data.email === "string") {
109
+ identity = { memberId: String(data.id), email: data.email };
110
+ }
111
+ }
112
+ } catch {
113
+ }
114
+ const sameAccount = previous !== null && (previous.memberId === void 0 || identity === null) ? await tokensBelongToSameAccount(previous.accessToken, loginToken) : null;
115
+ if (previous !== null && (previous.memberId === void 0 || identity === null ? sameAccount !== true : identity.memberId !== previous.memberId)) {
116
+ return await ctx.crash({
117
+ exitCode: 1,
118
+ errorType: "fatal",
119
+ printedMessage: sameAccount === null && (previous.memberId === void 0 || identity === null) ? `Could not verify the identity of saved account "${profile.name}". To replace this saved login, run \`npx convex logout --account ${profile.name}\` followed by \`npx convex login --account ${profile.name}\`. Choose the intended account when logging in.` : `The login does not match saved account "${profile.name}". Log in with the matching account, or choose another name with \`npx convex login --account <name>\`.`
120
+ });
121
+ }
122
+ return {
123
+ ...identity ?? (previous?.memberId === void 0 ? {} : { memberId: previous.memberId, email: previous.email })
124
+ };
125
+ }
126
+ async function tokensBelongToSameAccount(older, newer) {
127
+ try {
128
+ const responses = await Promise.all(
129
+ [older, newer].map(
130
+ (token) => profileApi(token, "/v1/list_personal_access_tokens?limit=100")
131
+ )
132
+ );
133
+ if (responses.some((response) => !response.ok)) return null;
134
+ const lists = await Promise.all(
135
+ responses.map((response) => response.json())
136
+ );
137
+ if (lists.some(
138
+ (list) => !Array.isArray(list.items) || list.items.length === 0
139
+ ))
140
+ return null;
141
+ const ids = new Set(
142
+ lists[0].items.map((token) => String(token.id))
143
+ );
144
+ if (lists[1].items.some((token) => ids.has(String(token.id))))
145
+ return true;
146
+ return lists.some((list) => list.pagination?.hasMore !== false) ? null : false;
147
+ } catch {
148
+ return null;
149
+ }
150
+ }
151
+ export async function revokeReplacedProfileToken(ctx, previous, accessToken) {
152
+ if (previous === void 0 || previous === accessToken) return;
153
+ const settings = await readProfileSettings(ctx);
154
+ if (settings.revokeReplacedTokens === false || settings.accessToken === previous)
155
+ return;
156
+ for (const name of savedProfileNames(ctx)) {
157
+ const token = readProfileToken(ctx, name);
158
+ if (token === null) {
159
+ logWarning(
160
+ `The new login was saved, but account "${name}" could not be read. Skipping revocation of the replaced token.`
161
+ );
162
+ return;
163
+ }
164
+ if (token === previous) return;
165
+ }
166
+ try {
167
+ const response = await profileApi(
168
+ accessToken,
169
+ "/v1/delete_personal_access_token",
170
+ { id: previous }
171
+ );
172
+ if (response.ok) return;
173
+ } catch {
174
+ }
175
+ logWarning(
176
+ "The new login was saved, but the replaced token could not be revoked. You can remove it in the dashboard's account settings."
177
+ );
178
+ }
179
+ //# sourceMappingURL=profileManagement.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/lib/profileManagement.ts"],
4
+ "sourcesContent": ["import { ProjectSelection } from \"./deploymentSelection.js\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logMessage, logWarning } from \"../../bundler/log.js\";\nimport { provisionHost } from \"./config.js\";\nimport { version } from \"../version.js\";\nimport {\n isAnonymousDeployment,\n getDeploymentTypeFromConfiguredDeployment,\n stripDeploymentTypePrefix,\n} from \"./deployment.js\";\nimport { CONVEX_DEPLOYMENT_ENV_VAR_NAME } from \"./utils/utils.js\";\nimport { promptYesNo } from \"./utils/prompts.js\";\nimport { loadProjectEnvironmentVariables } from \"./envvars.js\";\nimport {\n ProfileCredentials,\n ProfileSelection,\n readProfileCredentials,\n readProfileSettings,\n readProfileToken,\n savedProfileNames,\n writeProfileDirectory,\n} from \"./profiles.js\";\n\nexport async function profileApi(\n token: string,\n pathname: string,\n body?: unknown,\n) {\n return await fetch(`${provisionHost}${pathname}`, {\n method: body === undefined ? \"GET\" : \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Convex-Client\": `npm-cli-${version}`,\n ...(body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n signal: AbortSignal.timeout(10_000),\n });\n}\n\nexport async function deploymentAccess(\n token: string,\n deploymentName: string,\n): Promise<\"yes\" | \"no\" | \"unknown\"> {\n try {\n const response = await profileApi(\n token,\n `/v1/deployments/${encodeURIComponent(deploymentName)}`,\n );\n if (response.ok) return \"yes\";\n return [401, 403, 404].includes(response.status) ? \"no\" : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nexport async function projectAccess(\n token: string,\n target: ProjectSelection,\n): Promise<\"yes\" | \"no\" | \"unknown\"> {\n if (target.kind === \"deploymentName\")\n return deploymentAccess(token, target.deploymentName);\n if (target.kind !== \"teamAndProjectSlugs\") return \"unknown\";\n try {\n const response = await profileApi(\n token,\n `/v1/teams/${encodeURIComponent(target.teamSlug)}/projects/${encodeURIComponent(target.projectSlug)}`,\n );\n if (response.ok) return \"yes\";\n return [401, 403, 404].includes(response.status) ? \"no\" : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction configuredCloudDeployment(): string | null {\n const configured = process.env[CONVEX_DEPLOYMENT_ENV_VAR_NAME]?.trim();\n if (\n !configured ||\n getDeploymentTypeFromConfiguredDeployment(configured) === \"local\"\n )\n return null;\n const name = stripDeploymentTypePrefix(configured);\n return isAnonymousDeployment(name) ? null : name;\n}\n\nexport async function bindProfileToDirectory(\n ctx: Context,\n name: string,\n force = false,\n target?: ProjectSelection,\n): Promise<boolean> {\n const credentials = await readProfileCredentials(ctx, {\n name,\n source: \"account selection\",\n });\n loadProjectEnvironmentVariables();\n const deployment = configuredCloudDeployment();\n const selectedTarget =\n target ??\n (deployment === null\n ? null\n : {\n kind: \"deploymentName\" as const,\n deploymentName: deployment,\n deploymentType: null,\n });\n if (!force && selectedTarget !== null) {\n const label =\n selectedTarget.kind === \"teamAndProjectSlugs\"\n ? `project \"${selectedTarget.teamSlug}/${selectedTarget.projectSlug}\"`\n : `deployment \"${selectedTarget.kind === \"deploymentName\" ? selectedTarget.deploymentName : \"configured\"}\"`;\n const access = await projectAccess(\n credentials!.accessToken,\n selectedTarget,\n );\n if (access !== \"yes\") {\n logWarning(\n access === \"no\"\n ? `Account \"${name}\" cannot access ${label}.`\n : `Could not verify whether account \"${name}\" can access ${label}.`,\n );\n if (\n !process.stdin.isTTY ||\n !(await promptYesNo(ctx, {\n message: `Use account \"${name}\" here anyway?`,\n default: false,\n }))\n ) {\n logMessage(\n `Directory selection unchanged. To select this account anyway, run \\`npx convex account select ${name} --force\\`.`,\n );\n return false;\n }\n }\n }\n await writeProfileDirectory(ctx, name);\n return true;\n}\n\nexport async function profileLoginMetadata(\n ctx: Context,\n profile: ProfileSelection,\n loginToken: string,\n previous: ProfileCredentials | null,\n): Promise<Omit<ProfileCredentials, \"accessToken\">> {\n let identity: { memberId: string; email: string } | null = null;\n try {\n const response = await profileApi(loginToken, \"/api/dashboard/profile\");\n if (response.ok) {\n const data = await response.json();\n if (\n (typeof data.id === \"number\" || typeof data.id === \"string\") &&\n typeof data.email === \"string\"\n ) {\n identity = { memberId: String(data.id), email: data.email };\n }\n }\n } catch {\n // Older authentication tokens can be valid without access to the dashboard profile API.\n }\n const sameAccount =\n previous !== null && (previous.memberId === undefined || identity === null)\n ? await tokensBelongToSameAccount(previous.accessToken, loginToken)\n : null;\n if (\n previous !== null &&\n (previous.memberId === undefined || identity === null\n ? sameAccount !== true\n : identity.memberId !== previous.memberId)\n ) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n sameAccount === null &&\n (previous.memberId === undefined || identity === null)\n ? `Could not verify the identity of saved account \"${profile.name}\". To replace this saved login, run \\`npx convex logout --account ${profile.name}\\` followed by \\`npx convex login --account ${profile.name}\\`. Choose the intended account when logging in.`\n : `The login does not match saved account \"${profile.name}\". Log in with the matching account, or choose another name with \\`npx convex login --account <name>\\`.`,\n });\n }\n return {\n ...(identity ??\n (previous?.memberId === undefined\n ? {}\n : { memberId: previous.memberId, email: previous.email })),\n };\n}\n\nasync function tokensBelongToSameAccount(\n older: string,\n newer: string,\n): Promise<boolean | null> {\n try {\n const responses = await Promise.all(\n [older, newer].map((token) =>\n profileApi(token, \"/v1/list_personal_access_tokens?limit=100\"),\n ),\n );\n if (responses.some((response) => !response.ok)) return null;\n const lists = await Promise.all(\n responses.map((response) => response.json()),\n );\n if (\n lists.some(\n (list) => !Array.isArray(list.items) || list.items.length === 0,\n )\n )\n return null;\n const ids = new Set(\n lists[0].items.map((token: { id: unknown }) => String(token.id)),\n );\n if (\n lists[1].items.some((token: { id: unknown }) => ids.has(String(token.id)))\n )\n return true;\n // Disjoint partial pages cannot establish that the accounts differ.\n return lists.some((list) => list.pagination?.hasMore !== false)\n ? null\n : false;\n } catch {\n return null;\n }\n}\n\nexport async function revokeReplacedProfileToken(\n ctx: Context,\n previous: string | undefined,\n accessToken: string,\n) {\n if (previous === undefined || previous === accessToken) return;\n const settings = await readProfileSettings(ctx);\n if (\n settings.revokeReplacedTokens === false ||\n settings.accessToken === previous\n )\n return;\n for (const name of savedProfileNames(ctx)) {\n const token = readProfileToken(ctx, name);\n if (token === null) {\n logWarning(\n `The new login was saved, but account \"${name}\" could not be read. Skipping revocation of the replaced token.`,\n );\n return;\n }\n if (token === previous) return;\n }\n try {\n // The API verifies token ownership using the newly authenticated account.\n const response = await profileApi(\n accessToken,\n \"/v1/delete_personal_access_token\",\n { id: previous },\n );\n if (response.ok) return;\n } catch {\n // The new credentials are already saved, so a failed revocation can be retried in the dashboard.\n }\n logWarning(\n \"The new login was saved, but the replaced token could not be revoked. You can remove it in the dashboard's account settings.\",\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ import path from "path";
3
+ import { isDeepStrictEqual } from "util";
4
+ import { randomUUID } from "crypto";
5
+ import * as dotenv from "dotenv";
6
+ import { z } from "zod";
7
+ import { logFinishedStep, logWarning } from "../../bundler/log.js";
8
+ import { globalConfigPath, readGlobalConfig } from "./utils/globalConfig.js";
9
+ import { ENV_VAR_FILE_PATH, rootDirectory } from "./utils/utils.js";
10
+ import { CONVEX_ACCOUNT_ENV_VAR } from "./envvars.js";
11
+ const settingsSchema = z.object({
12
+ defaultProfile: z.string().optional(),
13
+ directories: z.record(z.string()).optional(),
14
+ revokeReplacedTokens: z.boolean().optional()
15
+ }).passthrough();
16
+ const credentialsSchema = z.object({
17
+ accessToken: z.string().min(1),
18
+ memberId: z.string().optional(),
19
+ email: z.string().optional()
20
+ }).passthrough();
21
+ export async function readProfileSettings(ctx) {
22
+ if (!ctx.fs.exists(globalConfigPath())) return {};
23
+ try {
24
+ return settingsSchema.parse(
25
+ JSON.parse(ctx.fs.readUtf8File(globalConfigPath()))
26
+ );
27
+ } catch {
28
+ return await ctx.crash({
29
+ exitCode: 1,
30
+ errorType: "invalid filesystem data",
31
+ printedMessage: `Unable to read account settings from ${globalConfigPath()}. Check defaultProfile, directories, and revokeReplacedTokens.`
32
+ });
33
+ }
34
+ }
35
+ function writeProfileSettings(ctx, settings) {
36
+ if (Object.keys(settings).length === 0) {
37
+ if (ctx.fs.exists(globalConfigPath())) ctx.fs.unlink(globalConfigPath());
38
+ return;
39
+ }
40
+ const temporary = `${globalConfigPath()}.${randomUUID()}.tmp`;
41
+ try {
42
+ ctx.fs.writeUtf8File(temporary, JSON.stringify(settings, null, 2), 384);
43
+ ctx.fs.swapTmpFile(temporary, globalConfigPath());
44
+ } finally {
45
+ if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);
46
+ }
47
+ }
48
+ export async function updateProfileSettings(ctx, update, afterWrite) {
49
+ const lockPath = `${globalConfigPath()}.lock`;
50
+ ctx.fs.mkdir(rootDirectory(), { allowExisting: true });
51
+ const deadline = Date.now() + 5e3;
52
+ for (; ; ) {
53
+ try {
54
+ ctx.fs.mkdir(lockPath);
55
+ break;
56
+ } catch (err) {
57
+ if (err.code !== "EEXIST") throw err;
58
+ if (Date.now() >= deadline) {
59
+ return await ctx.crash({
60
+ exitCode: 1,
61
+ errorType: "fatal",
62
+ printedMessage: `Another command is updating Convex accounts. Retry after it finishes. If it was interrupted, remove ${lockPath}.`
63
+ });
64
+ }
65
+ await new Promise((resolve) => setTimeout(resolve, 25));
66
+ }
67
+ }
68
+ let released = false;
69
+ const release = () => {
70
+ if (released) return;
71
+ ctx.fs.rmdir(lockPath);
72
+ released = true;
73
+ };
74
+ const cleanup = ctx.registerCleanup(async () => release());
75
+ try {
76
+ const settings = await readProfileSettings(ctx);
77
+ const result = await update(settings);
78
+ writeProfileSettings(ctx, settings);
79
+ afterWrite?.();
80
+ return result;
81
+ } finally {
82
+ ctx.removeCleanup(cleanup);
83
+ release();
84
+ }
85
+ }
86
+ export function profileConfigPath(name) {
87
+ return path.join(
88
+ rootDirectory(),
89
+ "profiles",
90
+ `${encodeURIComponent(name)}.json`
91
+ );
92
+ }
93
+ export async function validateProfileName(ctx, name) {
94
+ if (!/^[a-z0-9][a-z0-9_-]*$/.test(name)) {
95
+ await ctx.crash({
96
+ exitCode: 1,
97
+ errorType: "invalid filesystem or env vars",
98
+ printedMessage: "Account names must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, and underscores."
99
+ });
100
+ }
101
+ }
102
+ export async function getProfileSelection(ctx, options = {}) {
103
+ let name = options.name;
104
+ let source = "--account";
105
+ if (name === void 0 && process.env[CONVEX_ACCOUNT_ENV_VAR] !== void 0) {
106
+ name = process.env[CONVEX_ACCOUNT_ENV_VAR];
107
+ source = `${CONVEX_ACCOUNT_ENV_VAR} environment variable`;
108
+ }
109
+ if (name === void 0) {
110
+ const files = options.envFile ? [options.envFile] : [ENV_VAR_FILE_PATH, ".env"];
111
+ for (const file of files) {
112
+ if (!ctx.fs.exists(file)) continue;
113
+ name = dotenv.parse(ctx.fs.readUtf8File(file))[CONVEX_ACCOUNT_ENV_VAR];
114
+ if (name !== void 0) {
115
+ source = `${CONVEX_ACCOUNT_ENV_VAR} in ${file}`;
116
+ break;
117
+ }
118
+ }
119
+ }
120
+ if (name === void 0) {
121
+ const config = await readProfileSettings(ctx);
122
+ const binding = findProfileDirectory(
123
+ config.directories ?? {},
124
+ process.cwd()
125
+ );
126
+ name = binding?.name ?? config.defaultProfile;
127
+ source = binding ? `directory selection for ${binding.directory}` : `default account in ${globalConfigPath()}`;
128
+ }
129
+ if (name === void 0) return null;
130
+ await validateProfileName(ctx, name);
131
+ return { name, source };
132
+ }
133
+ export async function readProfileAuth(ctx, profile, allowMissing = false) {
134
+ const credentials = await readProfileCredentials(ctx, profile, allowMissing);
135
+ return credentials === null ? null : {
136
+ kind: "accessToken",
137
+ accessToken: credentials.accessToken,
138
+ header: `Bearer ${credentials.accessToken}`,
139
+ profile
140
+ };
141
+ }
142
+ export async function readProfileCredentials(ctx, profile, allowMissing = false) {
143
+ await validateProfileName(ctx, profile.name);
144
+ const configPath = profileConfigPath(profile.name);
145
+ if (!ctx.fs.exists(configPath)) {
146
+ if (allowMissing) return null;
147
+ return await ctx.crash({
148
+ exitCode: 1,
149
+ errorType: "invalid filesystem data",
150
+ printedMessage: `Account "${profile.name}" selected by ${profile.source} is not logged in. Run \`npx convex login --account ${profile.name}\`.`
151
+ });
152
+ }
153
+ try {
154
+ return credentialsSchema.parse(JSON.parse(ctx.fs.readUtf8File(configPath)));
155
+ } catch {
156
+ return await ctx.crash({
157
+ exitCode: 1,
158
+ errorType: "invalid filesystem data",
159
+ printedMessage: `Unable to read credentials for account "${profile.name}" from ${configPath}.`
160
+ });
161
+ }
162
+ }
163
+ export function readProfileToken(ctx, name) {
164
+ try {
165
+ const token = JSON.parse(
166
+ ctx.fs.readUtf8File(profileConfigPath(name))
167
+ ).accessToken;
168
+ return typeof token === "string" && token.length > 0 ? token : null;
169
+ } catch {
170
+ return null;
171
+ }
172
+ }
173
+ async function writeCredentialsFile(ctx, name, credentials) {
174
+ const configPath = profileConfigPath(name);
175
+ const directory = path.dirname(configPath);
176
+ ctx.fs.mkdir(directory, { allowExisting: true });
177
+ for (const dir of [rootDirectory(), directory]) {
178
+ if (!ctx.fs.lstat(dir).isDirectory()) {
179
+ return await ctx.crash({
180
+ exitCode: 1,
181
+ errorType: "invalid filesystem data",
182
+ printedMessage: `Cannot save account credentials through a symlink or non-directory: ${dir}.`
183
+ });
184
+ }
185
+ }
186
+ const temporary = `${configPath}.${randomUUID()}.tmp`;
187
+ try {
188
+ ctx.fs.writeUtf8File(
189
+ temporary,
190
+ JSON.stringify(credentials, null, 2),
191
+ 384
192
+ );
193
+ ctx.fs.swapTmpFile(temporary, configPath);
194
+ } finally {
195
+ if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);
196
+ }
197
+ }
198
+ export async function writeProfileCredentials(ctx, name, accessToken, metadata = {}, expected) {
199
+ await validateProfileName(ctx, name);
200
+ await updateProfileSettings(ctx, async (settings) => {
201
+ if (expected !== void 0) {
202
+ const current = await readProfileCredentials(
203
+ ctx,
204
+ { name, source: "login" },
205
+ true
206
+ );
207
+ if (!isDeepStrictEqual(current, expected)) {
208
+ return await ctx.crash({
209
+ exitCode: 1,
210
+ errorType: "fatal",
211
+ printedMessage: `Account "${name}" changed during login. Retry the login.`
212
+ });
213
+ }
214
+ }
215
+ await writeCredentialsFile(ctx, name, { ...metadata, accessToken });
216
+ if (settings.defaultProfile === name) settings.accessToken = accessToken;
217
+ });
218
+ }
219
+ export async function legacyAuthForFirstProfile(ctx, profile) {
220
+ const settings = await readProfileSettings(ctx);
221
+ const profilesDir = path.dirname(profileConfigPath(profile.name));
222
+ if (settings.defaultProfile !== void 0 || ctx.fs.exists(profilesDir) && ctx.fs.listDir(profilesDir).some((entry) => entry.name.endsWith(".json"))) {
223
+ return null;
224
+ }
225
+ const config = readGlobalConfig(ctx);
226
+ return config === null ? null : {
227
+ kind: "accessToken",
228
+ accessToken: config.accessToken,
229
+ header: `Bearer ${config.accessToken}`,
230
+ profile
231
+ };
232
+ }
233
+ export async function initializeDefaultProfile(ctx, profile, namingLegacyAccount, select = true) {
234
+ const defaultProfile = await updateProfileSettings(ctx, async (settings) => {
235
+ if (settings.defaultProfile !== void 0) return void 0;
236
+ const credentials = await readProfileCredentials(ctx, profile);
237
+ const accessToken = credentials.accessToken;
238
+ const legacyToken = settings.accessToken;
239
+ if (!select && (savedProfileNames(ctx).some((name) => name !== profile.name) || !namingLegacyAccount && typeof legacyToken === "string" && legacyToken.length > 0 && legacyToken !== accessToken))
240
+ return void 0;
241
+ if (!namingLegacyAccount && typeof legacyToken === "string" && legacyToken.length > 0 && legacyToken !== accessToken) {
242
+ let legacyName = "default";
243
+ for (let suffix = 2; ctx.fs.exists(profileConfigPath(legacyName)); suffix++) {
244
+ legacyName = `default-${suffix}`;
245
+ }
246
+ await writeCredentialsFile(ctx, legacyName, { accessToken: legacyToken });
247
+ settings.defaultProfile = legacyName;
248
+ } else {
249
+ settings.defaultProfile = profile.name;
250
+ settings.accessToken = accessToken;
251
+ }
252
+ return settings.defaultProfile;
253
+ });
254
+ if (defaultProfile !== void 0)
255
+ logFinishedStep(`Default account: ${defaultProfile}`);
256
+ }
257
+ export function findProfileDirectory(directories, cwd) {
258
+ let directory = path.resolve(cwd);
259
+ for (; ; ) {
260
+ if (Object.hasOwn(directories, directory)) {
261
+ return { directory, name: directories[directory] };
262
+ }
263
+ const parent = path.dirname(directory);
264
+ if (parent === directory) return null;
265
+ directory = parent;
266
+ }
267
+ }
268
+ export function savedProfileNames(ctx) {
269
+ const directory = path.join(rootDirectory(), "profiles");
270
+ if (!ctx.fs.exists(directory)) return [];
271
+ return ctx.fs.listDir(directory).filter((entry) => entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -5)).sort();
272
+ }
273
+ export async function writeProfileDirectory(ctx, name) {
274
+ await validateProfileName(ctx, name);
275
+ await updateProfileSettings(ctx, (settings) => {
276
+ settings.directories = { ...settings.directories, [process.cwd()]: name };
277
+ });
278
+ logFinishedStep(
279
+ `Saved directory selection: ${name} (applies to this directory and its subdirectories).`
280
+ );
281
+ const selected = await getProfileSelection(ctx);
282
+ if (selected !== null && selected.name !== name) {
283
+ logWarning(
284
+ `Account "${selected.name}" selected by ${selected.source} overrides this directory selection. Remove that override to use account "${name}".`
285
+ );
286
+ }
287
+ }
288
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/lib/profiles.ts"],
4
+ "sourcesContent": ["import path from \"path\";\nimport { isDeepStrictEqual } from \"util\";\nimport { randomUUID } from \"crypto\";\nimport { TempPath } from \"../../bundler/fs.js\";\nimport * as dotenv from \"dotenv\";\nimport { z } from \"zod\";\nimport { BigBrainAuth, Context } from \"../../bundler/context.js\";\nimport { logFinishedStep, logWarning } from \"../../bundler/log.js\";\nimport { globalConfigPath, readGlobalConfig } from \"./utils/globalConfig.js\";\nimport { ENV_VAR_FILE_PATH, rootDirectory } from \"./utils/utils.js\";\n\nimport { CONVEX_ACCOUNT_ENV_VAR } from \"./envvars.js\";\n\nexport type ProfileSelection = {\n name: string;\n source: string;\n};\n\nconst settingsSchema = z\n .object({\n defaultProfile: z.string().optional(),\n directories: z.record(z.string()).optional(),\n revokeReplacedTokens: z.boolean().optional(),\n })\n .passthrough();\n\nconst credentialsSchema = z\n .object({\n accessToken: z.string().min(1),\n memberId: z.string().optional(),\n email: z.string().optional(),\n })\n .passthrough();\n\nexport type ProfileCredentials = z.infer<typeof credentialsSchema>;\n\nexport async function readProfileSettings(\n ctx: Context,\n): Promise<z.infer<typeof settingsSchema>> {\n if (!ctx.fs.exists(globalConfigPath())) return {};\n try {\n return settingsSchema.parse(\n JSON.parse(ctx.fs.readUtf8File(globalConfigPath())),\n );\n } catch {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Unable to read account settings from ${globalConfigPath()}. Check defaultProfile, directories, and revokeReplacedTokens.`,\n });\n }\n}\n\nfunction writeProfileSettings(ctx: Context, settings: Record<string, unknown>) {\n if (Object.keys(settings).length === 0) {\n if (ctx.fs.exists(globalConfigPath())) ctx.fs.unlink(globalConfigPath());\n return;\n }\n const temporary = `${globalConfigPath()}.${randomUUID()}.tmp` as TempPath;\n try {\n ctx.fs.writeUtf8File(temporary, JSON.stringify(settings, null, 2), 0o600);\n ctx.fs.swapTmpFile(temporary, globalConfigPath());\n } finally {\n if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);\n }\n}\n\nexport async function updateProfileSettings<T>(\n ctx: Context,\n update: (settings: z.infer<typeof settingsSchema>) => T | Promise<T>,\n afterWrite?: () => void,\n): Promise<T> {\n const lockPath = `${globalConfigPath()}.lock`;\n ctx.fs.mkdir(rootDirectory(), { allowExisting: true });\n const deadline = Date.now() + 5000;\n for (;;) {\n try {\n ctx.fs.mkdir(lockPath);\n break;\n } catch (err: any) {\n // Only the process that creates the directory owns the update lock.\n // eslint-disable-next-line no-restricted-syntax\n if (err.code !== \"EEXIST\") throw err;\n if (Date.now() >= deadline) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Another command is updating Convex accounts. Retry after it finishes. If it was interrupted, remove ${lockPath}.`,\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n let released = false;\n const release = () => {\n if (released) return;\n ctx.fs.rmdir(lockPath);\n released = true;\n };\n const cleanup = ctx.registerCleanup(async () => release());\n try {\n const settings = await readProfileSettings(ctx);\n const result = await update(settings);\n writeProfileSettings(ctx, settings);\n // Credential deletion follows persistence while sharing the lock with renewals.\n afterWrite?.();\n return result;\n } finally {\n ctx.removeCleanup(cleanup);\n release();\n }\n}\n\nexport function profileConfigPath(name: string): string {\n return path.join(\n rootDirectory(),\n \"profiles\",\n `${encodeURIComponent(name)}.json`,\n );\n}\n\nexport async function validateProfileName(\n ctx: Context,\n name: string,\n): Promise<void> {\n if (!/^[a-z0-9][a-z0-9_-]*$/.test(name)) {\n await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage:\n \"Account names must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, and underscores.\",\n });\n }\n}\n\nexport async function getProfileSelection(\n ctx: Context,\n options: { name?: string | undefined; envFile?: string | undefined } = {},\n): Promise<ProfileSelection | null> {\n let name = options.name;\n let source = \"--account\";\n if (name === undefined && process.env[CONVEX_ACCOUNT_ENV_VAR] !== undefined) {\n name = process.env[CONVEX_ACCOUNT_ENV_VAR];\n source = `${CONVEX_ACCOUNT_ENV_VAR} environment variable`;\n }\n if (name === undefined) {\n const files = options.envFile\n ? [options.envFile]\n : [ENV_VAR_FILE_PATH, \".env\"];\n for (const file of files) {\n if (!ctx.fs.exists(file)) continue;\n name = dotenv.parse(ctx.fs.readUtf8File(file))[CONVEX_ACCOUNT_ENV_VAR];\n if (name !== undefined) {\n source = `${CONVEX_ACCOUNT_ENV_VAR} in ${file}`;\n break;\n }\n }\n }\n if (name === undefined) {\n const config = await readProfileSettings(ctx);\n const binding = findProfileDirectory(\n config.directories ?? {},\n process.cwd(),\n );\n name = binding?.name ?? config.defaultProfile;\n source = binding\n ? `directory selection for ${binding.directory}`\n : `default account in ${globalConfigPath()}`;\n }\n if (name === undefined) return null;\n await validateProfileName(ctx, name);\n return { name, source };\n}\n\nexport async function readProfileAuth(\n ctx: Context,\n profile: ProfileSelection,\n allowMissing = false,\n): Promise<Extract<BigBrainAuth, { kind: \"accessToken\" }> | null> {\n const credentials = await readProfileCredentials(ctx, profile, allowMissing);\n return credentials === null\n ? null\n : {\n kind: \"accessToken\",\n accessToken: credentials.accessToken,\n header: `Bearer ${credentials.accessToken}`,\n profile,\n };\n}\n\nexport async function readProfileCredentials(\n ctx: Context,\n profile: ProfileSelection,\n allowMissing = false,\n): Promise<ProfileCredentials | null> {\n await validateProfileName(ctx, profile.name);\n const configPath = profileConfigPath(profile.name);\n if (!ctx.fs.exists(configPath)) {\n if (allowMissing) return null;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Account \"${profile.name}\" selected by ${profile.source} is not logged in. Run \\`npx convex login --account ${profile.name}\\`.`,\n });\n }\n try {\n return credentialsSchema.parse(JSON.parse(ctx.fs.readUtf8File(configPath)));\n } catch {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Unable to read credentials for account \"${profile.name}\" from ${configPath}.`,\n });\n }\n}\n\nexport function readProfileToken(ctx: Context, name: string): string | null {\n try {\n const token = JSON.parse(\n ctx.fs.readUtf8File(profileConfigPath(name)),\n ).accessToken;\n return typeof token === \"string\" && token.length > 0 ? token : null;\n } catch {\n return null;\n }\n}\n\nasync function writeCredentialsFile(\n ctx: Context,\n name: string,\n credentials: ProfileCredentials,\n) {\n const configPath = profileConfigPath(name);\n const directory = path.dirname(configPath);\n ctx.fs.mkdir(directory, { allowExisting: true });\n for (const dir of [rootDirectory(), directory]) {\n if (!ctx.fs.lstat(dir).isDirectory()) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n printedMessage: `Cannot save account credentials through a symlink or non-directory: ${dir}.`,\n });\n }\n }\n const temporary = `${configPath}.${randomUUID()}.tmp` as TempPath;\n try {\n ctx.fs.writeUtf8File(\n temporary,\n JSON.stringify(credentials, null, 2),\n 0o600,\n );\n ctx.fs.swapTmpFile(temporary, configPath);\n } finally {\n if (ctx.fs.exists(temporary)) ctx.fs.unlink(temporary);\n }\n}\n\nexport async function writeProfileCredentials(\n ctx: Context,\n name: string,\n accessToken: string,\n metadata: Omit<ProfileCredentials, \"accessToken\"> = {},\n expected?: ProfileCredentials | null,\n): Promise<void> {\n await validateProfileName(ctx, name);\n await updateProfileSettings(ctx, async (settings) => {\n if (expected !== undefined) {\n const current = await readProfileCredentials(\n ctx,\n { name, source: \"login\" },\n true,\n );\n if (!isDeepStrictEqual(current, expected)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Account \"${name}\" changed during login. Retry the login.`,\n });\n }\n }\n await writeCredentialsFile(ctx, name, { ...metadata, accessToken });\n if (settings.defaultProfile === name) settings.accessToken = accessToken;\n });\n}\n\nexport async function legacyAuthForFirstProfile(\n ctx: Context,\n profile: ProfileSelection,\n): Promise<Extract<BigBrainAuth, { kind: \"accessToken\" }> | null> {\n const settings = await readProfileSettings(ctx);\n const profilesDir = path.dirname(profileConfigPath(profile.name));\n if (\n settings.defaultProfile !== undefined ||\n (ctx.fs.exists(profilesDir) &&\n ctx.fs.listDir(profilesDir).some((entry) => entry.name.endsWith(\".json\")))\n ) {\n return null;\n }\n const config = readGlobalConfig(ctx);\n return config === null\n ? null\n : {\n kind: \"accessToken\",\n accessToken: config.accessToken,\n header: `Bearer ${config.accessToken}`,\n profile,\n };\n}\n\nexport async function initializeDefaultProfile(\n ctx: Context,\n profile: ProfileSelection,\n namingLegacyAccount: boolean,\n select = true,\n) {\n const defaultProfile = await updateProfileSettings(ctx, async (settings) => {\n if (settings.defaultProfile !== undefined) return undefined;\n const credentials = await readProfileCredentials(ctx, profile);\n const accessToken = credentials!.accessToken;\n const legacyToken = settings.accessToken;\n if (\n !select &&\n (savedProfileNames(ctx).some((name) => name !== profile.name) ||\n (!namingLegacyAccount &&\n typeof legacyToken === \"string\" &&\n legacyToken.length > 0 &&\n legacyToken !== accessToken))\n )\n return undefined;\n if (\n !namingLegacyAccount &&\n typeof legacyToken === \"string\" &&\n legacyToken.length > 0 &&\n legacyToken !== accessToken\n ) {\n // An explicitly new login keeps the previous account as the default for\n // directories that haven't selected an account.\n let legacyName = \"default\";\n for (\n let suffix = 2;\n ctx.fs.exists(profileConfigPath(legacyName));\n suffix++\n ) {\n legacyName = `default-${suffix}`;\n }\n await writeCredentialsFile(ctx, legacyName, { accessToken: legacyToken });\n settings.defaultProfile = legacyName;\n } else {\n settings.defaultProfile = profile.name;\n settings.accessToken = accessToken;\n }\n\n return settings.defaultProfile;\n });\n if (defaultProfile !== undefined)\n logFinishedStep(`Default account: ${defaultProfile}`);\n}\n\nexport function findProfileDirectory(\n directories: Record<string, string>,\n cwd: string,\n): { directory: string; name: string } | null {\n let directory = path.resolve(cwd);\n for (;;) {\n if (Object.hasOwn(directories, directory)) {\n return { directory, name: directories[directory] };\n }\n const parent = path.dirname(directory);\n if (parent === directory) return null;\n directory = parent;\n }\n}\n\nexport function savedProfileNames(ctx: Context): string[] {\n const directory = path.join(rootDirectory(), \"profiles\");\n if (!ctx.fs.exists(directory)) return [];\n return ctx.fs\n .listDir(directory)\n .filter((entry) => entry.name.endsWith(\".json\"))\n .map((entry) => entry.name.slice(0, -5))\n .sort();\n}\n\nexport async function writeProfileDirectory(ctx: Context, name: string) {\n await validateProfileName(ctx, name);\n await updateProfileSettings(ctx, (settings) => {\n settings.directories = { ...settings.directories, [process.cwd()]: name };\n });\n logFinishedStep(\n `Saved directory selection: ${name} (applies to this directory and its subdirectories).`,\n );\n const selected = await getProfileSelection(ctx);\n if (selected !== null && selected.name !== name) {\n logWarning(\n `Account \"${selected.name}\" selected by ${selected.source} overrides this directory selection. Remove that override to use account \"${name}\".`,\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -364,6 +364,10 @@ export async function pushToDeployment(ctx, args) {
364
364
  pushAllModules: false,
365
365
  largeIndexDeletionCheck: "no verification",
366
366
  // `convex run` can’t push to prod
367
+ largeIndexBackfillCheck: "no verification",
368
+ // ditto
369
+ stagedValidatorDeletionCheck: "no verification",
370
+ // ditto
367
371
  warnOnSlowSchemaValidation: true,
368
372
  message: null
369
373
  },