convex 1.44.0 → 1.45.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 (594) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/convexExport.js +1 -1
  5. package/dist/cjs/cli/convexExport.js.map +1 -1
  6. package/dist/cjs/cli/index.js +2 -32
  7. package/dist/cjs/cli/index.js.map +2 -2
  8. package/dist/cjs/cli/lib/api.js +11 -5
  9. package/dist/cjs/cli/lib/api.js.map +2 -2
  10. package/dist/cjs/cli/lib/convexExport.js +12 -1
  11. package/dist/cjs/cli/lib/convexExport.js.map +2 -2
  12. package/dist/cjs/cli/lib/dashboard.js.map +2 -2
  13. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  14. package/dist/cjs/cli/lib/indexes.js +1 -1
  15. package/dist/cjs/cli/lib/indexes.js.map +1 -1
  16. package/dist/cjs/cli/lib/localDeployment/upgrade.js +23 -188
  17. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +3 -3
  18. package/dist/cjs/cli/lib/mcp/tools/index.js.map +1 -1
  19. package/dist/cjs/cli/mcp.js +76 -69
  20. package/dist/cjs/cli/mcp.js.map +2 -2
  21. package/dist/cjs/index.js +1 -1
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  24. package/dist/cjs/server/index.js.map +2 -2
  25. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  26. package/dist/cjs-types/cli/lib/convexExport.d.ts +1 -0
  27. package/dist/cjs-types/cli/lib/convexExport.d.ts.map +1 -1
  28. package/dist/cjs-types/cli/lib/dashboard.d.ts.map +1 -1
  29. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  30. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  31. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts +2 -0
  32. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  33. package/dist/cjs-types/cli/lib/mcp/tools/index.d.ts +1 -1
  34. package/dist/cjs-types/cli/lib/mcp/tools/index.d.ts.map +1 -1
  35. package/dist/cjs-types/cli/mcp.d.ts +3 -0
  36. package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
  37. package/dist/cjs-types/index.d.ts +1 -1
  38. package/dist/cjs-types/server/impl/actions_impl.d.ts +14 -0
  39. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  40. package/dist/cjs-types/server/index.d.ts +1 -0
  41. package/dist/cjs-types/server/index.d.ts.map +1 -1
  42. package/dist/cli.bundle.cjs +31210 -25495
  43. package/dist/cli.bundle.cjs.map +4 -4
  44. package/dist/esm/cli/convexExport.js +1 -1
  45. package/dist/esm/cli/convexExport.js.map +1 -1
  46. package/dist/esm/cli/index.js +2 -32
  47. package/dist/esm/cli/index.js.map +2 -2
  48. package/dist/esm/cli/lib/api.js +11 -5
  49. package/dist/esm/cli/lib/api.js.map +2 -2
  50. package/dist/esm/cli/lib/convexExport.js +16 -3
  51. package/dist/esm/cli/lib/convexExport.js.map +2 -2
  52. package/dist/esm/cli/lib/dashboard.js.map +2 -2
  53. package/dist/esm/cli/lib/indexes.js +1 -1
  54. package/dist/esm/cli/lib/indexes.js.map +1 -1
  55. package/dist/esm/cli/lib/localDeployment/upgrade.js +22 -190
  56. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  57. package/dist/esm/cli/lib/mcp/tools/index.js.map +1 -1
  58. package/dist/esm/cli/mcp.js +75 -72
  59. package/dist/esm/cli/mcp.js.map +2 -2
  60. package/dist/esm/index.js +1 -1
  61. package/dist/esm/index.js.map +1 -1
  62. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  63. package/dist/esm/server/index.js.map +2 -2
  64. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  65. package/dist/esm-types/cli/lib/convexExport.d.ts +1 -0
  66. package/dist/esm-types/cli/lib/convexExport.d.ts.map +1 -1
  67. package/dist/esm-types/cli/lib/dashboard.d.ts.map +1 -1
  68. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  69. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  70. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts +2 -0
  71. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  72. package/dist/esm-types/cli/lib/mcp/tools/index.d.ts +1 -1
  73. package/dist/esm-types/cli/lib/mcp/tools/index.d.ts.map +1 -1
  74. package/dist/esm-types/cli/mcp.d.ts +3 -0
  75. package/dist/esm-types/cli/mcp.d.ts.map +1 -1
  76. package/dist/esm-types/index.d.ts +1 -1
  77. package/dist/esm-types/server/impl/actions_impl.d.ts +14 -0
  78. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  79. package/dist/esm-types/server/index.d.ts +1 -0
  80. package/dist/esm-types/server/index.d.ts.map +1 -1
  81. package/dist/react.bundle.js +1 -1
  82. package/dist/react.bundle.js.map +1 -1
  83. package/package.json +3 -3
  84. package/src/cli/convexExport.ts +1 -1
  85. package/src/cli/index.ts +2 -35
  86. package/src/cli/lib/api.ts +11 -5
  87. package/src/cli/lib/convexExport.ts +21 -0
  88. package/src/cli/lib/dashboard.ts +2 -0
  89. package/src/cli/lib/generatedFunctionLogsApi.ts +2 -0
  90. package/src/cli/lib/indexes.ts +1 -1
  91. package/src/cli/lib/localDeployment/upgrade.ts +34 -207
  92. package/src/cli/lib/mcp/tools/index.ts +1 -1
  93. package/src/cli/mcp.ts +91 -77
  94. package/src/index.ts +1 -1
  95. package/src/server/impl/actions_impl.ts +3 -1
  96. package/src/server/index.ts +0 -3
  97. package/dist/cjs-types/browser/http_client.test.d.ts +0 -2
  98. package/dist/cjs-types/browser/http_client.test.d.ts.map +0 -1
  99. package/dist/cjs-types/browser/query_options.test.d.ts +0 -2
  100. package/dist/cjs-types/browser/query_options.test.d.ts.map +0 -1
  101. package/dist/cjs-types/browser/simple_client.test.d.ts +0 -2
  102. package/dist/cjs-types/browser/simple_client.test.d.ts.map +0 -1
  103. package/dist/cjs-types/browser/sync/client.test.d.ts +0 -5
  104. package/dist/cjs-types/browser/sync/client.test.d.ts.map +0 -1
  105. package/dist/cjs-types/browser/sync/client_node.test.d.ts +0 -2
  106. package/dist/cjs-types/browser/sync/client_node.test.d.ts.map +0 -1
  107. package/dist/cjs-types/browser/sync/client_node_test_helpers.d.ts +0 -44
  108. package/dist/cjs-types/browser/sync/client_node_test_helpers.d.ts.map +0 -1
  109. package/dist/cjs-types/browser/sync/local_state.test.d.ts +0 -2
  110. package/dist/cjs-types/browser/sync/local_state.test.d.ts.map +0 -1
  111. package/dist/cjs-types/browser/sync/optimistic_query_set.test.d.ts +0 -2
  112. package/dist/cjs-types/browser/sync/optimistic_query_set.test.d.ts.map +0 -1
  113. package/dist/cjs-types/browser/sync/paginated_query_client.test.d.ts +0 -2
  114. package/dist/cjs-types/browser/sync/paginated_query_client.test.d.ts.map +0 -1
  115. package/dist/cjs-types/browser/sync/protocol.test.d.ts +0 -5
  116. package/dist/cjs-types/browser/sync/protocol.test.d.ts.map +0 -1
  117. package/dist/cjs-types/browser/sync/request_manager.test.d.ts +0 -2
  118. package/dist/cjs-types/browser/sync/request_manager.test.d.ts.map +0 -1
  119. package/dist/cjs-types/bundler/fs.test.d.ts +0 -2
  120. package/dist/cjs-types/bundler/fs.test.d.ts.map +0 -1
  121. package/dist/cjs-types/bundler/index.test.d.ts +0 -2
  122. package/dist/cjs-types/bundler/index.test.d.ts.map +0 -1
  123. package/dist/cjs-types/cli/codegen_templates/api.test.d.ts +0 -2
  124. package/dist/cjs-types/cli/codegen_templates/api.test.d.ts.map +0 -1
  125. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts +0 -2
  126. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts.map +0 -1
  127. package/dist/cjs-types/cli/codegen_templates/templates.test.d.ts +0 -2
  128. package/dist/cjs-types/cli/codegen_templates/templates.test.d.ts.map +0 -1
  129. package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts +0 -2
  130. package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts.map +0 -1
  131. package/dist/cjs-types/cli/configure.test.d.ts +0 -2
  132. package/dist/cjs-types/cli/configure.test.d.ts.map +0 -1
  133. package/dist/cjs-types/cli/deploymentCreate.test.d.ts +0 -2
  134. package/dist/cjs-types/cli/deploymentCreate.test.d.ts.map +0 -1
  135. package/dist/cjs-types/cli/deploymentSelect.test.d.ts +0 -2
  136. package/dist/cjs-types/cli/deploymentSelect.test.d.ts.map +0 -1
  137. package/dist/cjs-types/cli/deploymentSelection.test.d.ts +0 -2
  138. package/dist/cjs-types/cli/deploymentSelection.test.d.ts.map +0 -1
  139. package/dist/cjs-types/cli/deploymentToken.test.d.ts +0 -2
  140. package/dist/cjs-types/cli/deploymentToken.test.d.ts.map +0 -1
  141. package/dist/cjs-types/cli/dev.test.d.ts +0 -2
  142. package/dist/cjs-types/cli/dev.test.d.ts.map +0 -1
  143. package/dist/cjs-types/cli/envDefault.test.d.ts +0 -2
  144. package/dist/cjs-types/cli/envDefault.test.d.ts.map +0 -1
  145. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts +0 -2
  146. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +0 -1
  147. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts +0 -2
  148. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts.map +0 -1
  149. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +0 -2
  150. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +0 -1
  151. package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts +0 -2
  152. package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts.map +0 -1
  153. package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts +0 -2
  154. package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts.map +0 -1
  155. package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts +0 -2
  156. package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts.map +0 -1
  157. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +0 -2
  158. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +0 -1
  159. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +0 -2
  160. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +0 -1
  161. package/dist/cjs-types/cli/lib/codegen.test.d.ts +0 -2
  162. package/dist/cjs-types/cli/lib/codegen.test.d.ts.map +0 -1
  163. package/dist/cjs-types/cli/lib/components.test.d.ts +0 -2
  164. package/dist/cjs-types/cli/lib/components.test.d.ts.map +0 -1
  165. package/dist/cjs-types/cli/lib/config.test.d.ts +0 -2
  166. package/dist/cjs-types/cli/lib/config.test.d.ts.map +0 -1
  167. package/dist/cjs-types/cli/lib/deployment.test.d.ts +0 -2
  168. package/dist/cjs-types/cli/lib/deployment.test.d.ts.map +0 -1
  169. package/dist/cjs-types/cli/lib/deploymentSelector.test.d.ts +0 -2
  170. package/dist/cjs-types/cli/lib/deploymentSelector.test.d.ts.map +0 -1
  171. package/dist/cjs-types/cli/lib/env.test.d.ts +0 -2
  172. package/dist/cjs-types/cli/lib/env.test.d.ts.map +0 -1
  173. package/dist/cjs-types/cli/lib/expiration.test.d.ts +0 -2
  174. package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +0 -1
  175. package/dist/cjs-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts +0 -2
  176. package/dist/cjs-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts.map +0 -1
  177. package/dist/cjs-types/cli/lib/formatEnvValueForDotfile.test.d.ts +0 -2
  178. package/dist/cjs-types/cli/lib/formatEnvValueForDotfile.test.d.ts.map +0 -1
  179. package/dist/cjs-types/cli/lib/formatTargetedDeployment.test.d.ts +0 -2
  180. package/dist/cjs-types/cli/lib/formatTargetedDeployment.test.d.ts.map +0 -1
  181. package/dist/cjs-types/cli/lib/fsUtils.test.d.ts +0 -2
  182. package/dist/cjs-types/cli/lib/fsUtils.test.d.ts.map +0 -1
  183. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts +0 -2
  184. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts.map +0 -1
  185. package/dist/cjs-types/cli/lib/indexes.test.d.ts +0 -2
  186. package/dist/cjs-types/cli/lib/indexes.test.d.ts.map +0 -1
  187. package/dist/cjs-types/cli/lib/localDeployment/run.test.d.ts +0 -2
  188. package/dist/cjs-types/cli/lib/localDeployment/run.test.d.ts.map +0 -1
  189. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts +0 -2
  190. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts.map +0 -1
  191. package/dist/cjs-types/cli/lib/run.test.d.ts +0 -2
  192. package/dist/cjs-types/cli/lib/run.test.d.ts.map +0 -1
  193. package/dist/cjs-types/cli/lib/runTestFunction.test.d.ts +0 -2
  194. package/dist/cjs-types/cli/lib/runTestFunction.test.d.ts.map +0 -1
  195. package/dist/cjs-types/cli/lib/typecheck.test.d.ts +0 -2
  196. package/dist/cjs-types/cli/lib/typecheck.test.d.ts.map +0 -1
  197. package/dist/cjs-types/cli/lib/updates.test.d.ts +0 -2
  198. package/dist/cjs-types/cli/lib/updates.test.d.ts.map +0 -1
  199. package/dist/cjs-types/cli/lib/utils/hash.test.d.ts +0 -2
  200. package/dist/cjs-types/cli/lib/utils/hash.test.d.ts.map +0 -1
  201. package/dist/cjs-types/cli/lib/utils/utils.test.d.ts +0 -2
  202. package/dist/cjs-types/cli/lib/utils/utils.test.d.ts.map +0 -1
  203. package/dist/cjs-types/cli/lib/versionApi.test.d.ts +0 -2
  204. package/dist/cjs-types/cli/lib/versionApi.test.d.ts.map +0 -1
  205. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts +0 -2
  206. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts.map +0 -1
  207. package/dist/cjs-types/cli/lib/workos/workos.test.d.ts +0 -2
  208. package/dist/cjs-types/cli/lib/workos/workos.test.d.ts.map +0 -1
  209. package/dist/cjs-types/cli/login.test.d.ts +0 -2
  210. package/dist/cjs-types/cli/login.test.d.ts.map +0 -1
  211. package/dist/cjs-types/common/index.test.d.ts +0 -2
  212. package/dist/cjs-types/common/index.test.d.ts.map +0 -1
  213. package/dist/cjs-types/nextjs/nextjs.test.d.ts +0 -2
  214. package/dist/cjs-types/nextjs/nextjs.test.d.ts.map +0 -1
  215. package/dist/cjs-types/react/ConvexAuthState.test.d.ts +0 -2
  216. package/dist/cjs-types/react/ConvexAuthState.test.d.ts.map +0 -1
  217. package/dist/cjs-types/react/auth_helpers.test.d.ts +0 -2
  218. package/dist/cjs-types/react/auth_helpers.test.d.ts.map +0 -1
  219. package/dist/cjs-types/react/auth_websocket.test.d.ts +0 -2
  220. package/dist/cjs-types/react/auth_websocket.test.d.ts.map +0 -1
  221. package/dist/cjs-types/react/client.test.d.ts +0 -2
  222. package/dist/cjs-types/react/client.test.d.ts.map +0 -1
  223. package/dist/cjs-types/react/client_provided_base_client.test.d.ts +0 -2
  224. package/dist/cjs-types/react/client_provided_base_client.test.d.ts.map +0 -1
  225. package/dist/cjs-types/react/queries_observer.test.d.ts +0 -2
  226. package/dist/cjs-types/react/queries_observer.test.d.ts.map +0 -1
  227. package/dist/cjs-types/react/react_node.test.d.ts +0 -2
  228. package/dist/cjs-types/react/react_node.test.d.ts.map +0 -1
  229. package/dist/cjs-types/react/use_paginated_query.test.d.ts +0 -2
  230. package/dist/cjs-types/react/use_paginated_query.test.d.ts.map +0 -1
  231. package/dist/cjs-types/react/use_queries.test.d.ts +0 -5
  232. package/dist/cjs-types/react/use_queries.test.d.ts.map +0 -1
  233. package/dist/cjs-types/react/use_query.test.d.ts +0 -5
  234. package/dist/cjs-types/react/use_query.test.d.ts.map +0 -1
  235. package/dist/cjs-types/react/use_query_object_options.test.d.ts +0 -5
  236. package/dist/cjs-types/react/use_query_object_options.test.d.ts.map +0 -1
  237. package/dist/cjs-types/react/use_query_result.test.d.ts +0 -5
  238. package/dist/cjs-types/react/use_query_result.test.d.ts.map +0 -1
  239. package/dist/cjs-types/react-auth0/ConvexProviderWithAuth0.test.d.ts +0 -2
  240. package/dist/cjs-types/react-auth0/ConvexProviderWithAuth0.test.d.ts.map +0 -1
  241. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.test.d.ts +0 -2
  242. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.test.d.ts.map +0 -1
  243. package/dist/cjs-types/server/api.intersect.test.d.ts +0 -2
  244. package/dist/cjs-types/server/api.intersect.test.d.ts.map +0 -1
  245. package/dist/cjs-types/server/api.test.d.ts +0 -2
  246. package/dist/cjs-types/server/api.test.d.ts.map +0 -1
  247. package/dist/cjs-types/server/audit_logging.test.d.ts +0 -2
  248. package/dist/cjs-types/server/audit_logging.test.d.ts.map +0 -1
  249. package/dist/cjs-types/server/components/index.test.d.ts +0 -2
  250. package/dist/cjs-types/server/components/index.test.d.ts.map +0 -1
  251. package/dist/cjs-types/server/cron.test.d.ts +0 -2
  252. package/dist/cjs-types/server/cron.test.d.ts.map +0 -1
  253. package/dist/cjs-types/server/data_model.test.d.ts +0 -2
  254. package/dist/cjs-types/server/data_model.test.d.ts.map +0 -1
  255. package/dist/cjs-types/server/database.test.d.ts +0 -2
  256. package/dist/cjs-types/server/database.test.d.ts.map +0 -1
  257. package/dist/cjs-types/server/database_api.test.d.ts +0 -2
  258. package/dist/cjs-types/server/database_api.test.d.ts.map +0 -1
  259. package/dist/cjs-types/server/filter_builder.test.d.ts +0 -2
  260. package/dist/cjs-types/server/filter_builder.test.d.ts.map +0 -1
  261. package/dist/cjs-types/server/impl/actions_impl.test.d.ts +0 -2
  262. package/dist/cjs-types/server/impl/actions_impl.test.d.ts.map +0 -1
  263. package/dist/cjs-types/server/impl/filter_builder_impl.test.d.ts +0 -2
  264. package/dist/cjs-types/server/impl/filter_builder_impl.test.d.ts.map +0 -1
  265. package/dist/cjs-types/server/impl/query_impl.test.d.ts +0 -2
  266. package/dist/cjs-types/server/impl/query_impl.test.d.ts.map +0 -1
  267. package/dist/cjs-types/server/pagination.test.d.ts +0 -2
  268. package/dist/cjs-types/server/pagination.test.d.ts.map +0 -1
  269. package/dist/cjs-types/server/query.test.d.ts +0 -2
  270. package/dist/cjs-types/server/query.test.d.ts.map +0 -1
  271. package/dist/cjs-types/server/registration.test.d.ts +0 -2
  272. package/dist/cjs-types/server/registration.test.d.ts.map +0 -1
  273. package/dist/cjs-types/server/router.test.d.ts +0 -2
  274. package/dist/cjs-types/server/router.test.d.ts.map +0 -1
  275. package/dist/cjs-types/server/scheduler.test.d.ts +0 -2
  276. package/dist/cjs-types/server/scheduler.test.d.ts.map +0 -1
  277. package/dist/cjs-types/server/schema.test.d.ts +0 -2
  278. package/dist/cjs-types/server/schema.test.d.ts.map +0 -1
  279. package/dist/cjs-types/test/fake_watch.d.ts +0 -16
  280. package/dist/cjs-types/test/fake_watch.d.ts.map +0 -1
  281. package/dist/cjs-types/test/type_testing.d.ts +0 -9
  282. package/dist/cjs-types/test/type_testing.d.ts.map +0 -1
  283. package/dist/cjs-types/type_utils.test.d.ts +0 -2
  284. package/dist/cjs-types/type_utils.test.d.ts.map +0 -1
  285. package/dist/cjs-types/values/size.test.d.ts +0 -2
  286. package/dist/cjs-types/values/size.test.d.ts.map +0 -1
  287. package/dist/cjs-types/values/validator.test.d.ts +0 -2
  288. package/dist/cjs-types/values/validator.test.d.ts.map +0 -1
  289. package/dist/cjs-types/values/value.test.d.ts +0 -2
  290. package/dist/cjs-types/values/value.test.d.ts.map +0 -1
  291. package/dist/esm-types/browser/http_client.test.d.ts +0 -2
  292. package/dist/esm-types/browser/http_client.test.d.ts.map +0 -1
  293. package/dist/esm-types/browser/query_options.test.d.ts +0 -2
  294. package/dist/esm-types/browser/query_options.test.d.ts.map +0 -1
  295. package/dist/esm-types/browser/simple_client.test.d.ts +0 -2
  296. package/dist/esm-types/browser/simple_client.test.d.ts.map +0 -1
  297. package/dist/esm-types/browser/sync/client.test.d.ts +0 -5
  298. package/dist/esm-types/browser/sync/client.test.d.ts.map +0 -1
  299. package/dist/esm-types/browser/sync/client_node.test.d.ts +0 -2
  300. package/dist/esm-types/browser/sync/client_node.test.d.ts.map +0 -1
  301. package/dist/esm-types/browser/sync/client_node_test_helpers.d.ts +0 -44
  302. package/dist/esm-types/browser/sync/client_node_test_helpers.d.ts.map +0 -1
  303. package/dist/esm-types/browser/sync/local_state.test.d.ts +0 -2
  304. package/dist/esm-types/browser/sync/local_state.test.d.ts.map +0 -1
  305. package/dist/esm-types/browser/sync/optimistic_query_set.test.d.ts +0 -2
  306. package/dist/esm-types/browser/sync/optimistic_query_set.test.d.ts.map +0 -1
  307. package/dist/esm-types/browser/sync/paginated_query_client.test.d.ts +0 -2
  308. package/dist/esm-types/browser/sync/paginated_query_client.test.d.ts.map +0 -1
  309. package/dist/esm-types/browser/sync/protocol.test.d.ts +0 -5
  310. package/dist/esm-types/browser/sync/protocol.test.d.ts.map +0 -1
  311. package/dist/esm-types/browser/sync/request_manager.test.d.ts +0 -2
  312. package/dist/esm-types/browser/sync/request_manager.test.d.ts.map +0 -1
  313. package/dist/esm-types/bundler/fs.test.d.ts +0 -2
  314. package/dist/esm-types/bundler/fs.test.d.ts.map +0 -1
  315. package/dist/esm-types/bundler/index.test.d.ts +0 -2
  316. package/dist/esm-types/bundler/index.test.d.ts.map +0 -1
  317. package/dist/esm-types/cli/codegen_templates/api.test.d.ts +0 -2
  318. package/dist/esm-types/cli/codegen_templates/api.test.d.ts.map +0 -1
  319. package/dist/esm-types/cli/codegen_templates/common.test.d.ts +0 -2
  320. package/dist/esm-types/cli/codegen_templates/common.test.d.ts.map +0 -1
  321. package/dist/esm-types/cli/codegen_templates/templates.test.d.ts +0 -2
  322. package/dist/esm-types/cli/codegen_templates/templates.test.d.ts.map +0 -1
  323. package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts +0 -2
  324. package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts.map +0 -1
  325. package/dist/esm-types/cli/configure.test.d.ts +0 -2
  326. package/dist/esm-types/cli/configure.test.d.ts.map +0 -1
  327. package/dist/esm-types/cli/deploymentCreate.test.d.ts +0 -2
  328. package/dist/esm-types/cli/deploymentCreate.test.d.ts.map +0 -1
  329. package/dist/esm-types/cli/deploymentSelect.test.d.ts +0 -2
  330. package/dist/esm-types/cli/deploymentSelect.test.d.ts.map +0 -1
  331. package/dist/esm-types/cli/deploymentSelection.test.d.ts +0 -2
  332. package/dist/esm-types/cli/deploymentSelection.test.d.ts.map +0 -1
  333. package/dist/esm-types/cli/deploymentToken.test.d.ts +0 -2
  334. package/dist/esm-types/cli/deploymentToken.test.d.ts.map +0 -1
  335. package/dist/esm-types/cli/dev.test.d.ts +0 -2
  336. package/dist/esm-types/cli/dev.test.d.ts.map +0 -1
  337. package/dist/esm-types/cli/envDefault.test.d.ts +0 -2
  338. package/dist/esm-types/cli/envDefault.test.d.ts.map +0 -1
  339. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts +0 -2
  340. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +0 -1
  341. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts +0 -2
  342. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts.map +0 -1
  343. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +0 -2
  344. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +0 -1
  345. package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts +0 -2
  346. package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts.map +0 -1
  347. package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts +0 -2
  348. package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts.map +0 -1
  349. package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts +0 -2
  350. package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts.map +0 -1
  351. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +0 -2
  352. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +0 -1
  353. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +0 -2
  354. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +0 -1
  355. package/dist/esm-types/cli/lib/codegen.test.d.ts +0 -2
  356. package/dist/esm-types/cli/lib/codegen.test.d.ts.map +0 -1
  357. package/dist/esm-types/cli/lib/components.test.d.ts +0 -2
  358. package/dist/esm-types/cli/lib/components.test.d.ts.map +0 -1
  359. package/dist/esm-types/cli/lib/config.test.d.ts +0 -2
  360. package/dist/esm-types/cli/lib/config.test.d.ts.map +0 -1
  361. package/dist/esm-types/cli/lib/deployment.test.d.ts +0 -2
  362. package/dist/esm-types/cli/lib/deployment.test.d.ts.map +0 -1
  363. package/dist/esm-types/cli/lib/deploymentSelector.test.d.ts +0 -2
  364. package/dist/esm-types/cli/lib/deploymentSelector.test.d.ts.map +0 -1
  365. package/dist/esm-types/cli/lib/env.test.d.ts +0 -2
  366. package/dist/esm-types/cli/lib/env.test.d.ts.map +0 -1
  367. package/dist/esm-types/cli/lib/expiration.test.d.ts +0 -2
  368. package/dist/esm-types/cli/lib/expiration.test.d.ts.map +0 -1
  369. package/dist/esm-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts +0 -2
  370. package/dist/esm-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts.map +0 -1
  371. package/dist/esm-types/cli/lib/formatEnvValueForDotfile.test.d.ts +0 -2
  372. package/dist/esm-types/cli/lib/formatEnvValueForDotfile.test.d.ts.map +0 -1
  373. package/dist/esm-types/cli/lib/formatTargetedDeployment.test.d.ts +0 -2
  374. package/dist/esm-types/cli/lib/formatTargetedDeployment.test.d.ts.map +0 -1
  375. package/dist/esm-types/cli/lib/fsUtils.test.d.ts +0 -2
  376. package/dist/esm-types/cli/lib/fsUtils.test.d.ts.map +0 -1
  377. package/dist/esm-types/cli/lib/generateDocs.test.d.ts +0 -2
  378. package/dist/esm-types/cli/lib/generateDocs.test.d.ts.map +0 -1
  379. package/dist/esm-types/cli/lib/indexes.test.d.ts +0 -2
  380. package/dist/esm-types/cli/lib/indexes.test.d.ts.map +0 -1
  381. package/dist/esm-types/cli/lib/localDeployment/run.test.d.ts +0 -2
  382. package/dist/esm-types/cli/lib/localDeployment/run.test.d.ts.map +0 -1
  383. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts +0 -2
  384. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts.map +0 -1
  385. package/dist/esm-types/cli/lib/run.test.d.ts +0 -2
  386. package/dist/esm-types/cli/lib/run.test.d.ts.map +0 -1
  387. package/dist/esm-types/cli/lib/runTestFunction.test.d.ts +0 -2
  388. package/dist/esm-types/cli/lib/runTestFunction.test.d.ts.map +0 -1
  389. package/dist/esm-types/cli/lib/typecheck.test.d.ts +0 -2
  390. package/dist/esm-types/cli/lib/typecheck.test.d.ts.map +0 -1
  391. package/dist/esm-types/cli/lib/updates.test.d.ts +0 -2
  392. package/dist/esm-types/cli/lib/updates.test.d.ts.map +0 -1
  393. package/dist/esm-types/cli/lib/utils/hash.test.d.ts +0 -2
  394. package/dist/esm-types/cli/lib/utils/hash.test.d.ts.map +0 -1
  395. package/dist/esm-types/cli/lib/utils/utils.test.d.ts +0 -2
  396. package/dist/esm-types/cli/lib/utils/utils.test.d.ts.map +0 -1
  397. package/dist/esm-types/cli/lib/versionApi.test.d.ts +0 -2
  398. package/dist/esm-types/cli/lib/versionApi.test.d.ts.map +0 -1
  399. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts +0 -2
  400. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts.map +0 -1
  401. package/dist/esm-types/cli/lib/workos/workos.test.d.ts +0 -2
  402. package/dist/esm-types/cli/lib/workos/workos.test.d.ts.map +0 -1
  403. package/dist/esm-types/cli/login.test.d.ts +0 -2
  404. package/dist/esm-types/cli/login.test.d.ts.map +0 -1
  405. package/dist/esm-types/common/index.test.d.ts +0 -2
  406. package/dist/esm-types/common/index.test.d.ts.map +0 -1
  407. package/dist/esm-types/nextjs/nextjs.test.d.ts +0 -2
  408. package/dist/esm-types/nextjs/nextjs.test.d.ts.map +0 -1
  409. package/dist/esm-types/react/ConvexAuthState.test.d.ts +0 -2
  410. package/dist/esm-types/react/ConvexAuthState.test.d.ts.map +0 -1
  411. package/dist/esm-types/react/auth_helpers.test.d.ts +0 -2
  412. package/dist/esm-types/react/auth_helpers.test.d.ts.map +0 -1
  413. package/dist/esm-types/react/auth_websocket.test.d.ts +0 -2
  414. package/dist/esm-types/react/auth_websocket.test.d.ts.map +0 -1
  415. package/dist/esm-types/react/client.test.d.ts +0 -2
  416. package/dist/esm-types/react/client.test.d.ts.map +0 -1
  417. package/dist/esm-types/react/client_provided_base_client.test.d.ts +0 -2
  418. package/dist/esm-types/react/client_provided_base_client.test.d.ts.map +0 -1
  419. package/dist/esm-types/react/queries_observer.test.d.ts +0 -2
  420. package/dist/esm-types/react/queries_observer.test.d.ts.map +0 -1
  421. package/dist/esm-types/react/react_node.test.d.ts +0 -2
  422. package/dist/esm-types/react/react_node.test.d.ts.map +0 -1
  423. package/dist/esm-types/react/use_paginated_query.test.d.ts +0 -2
  424. package/dist/esm-types/react/use_paginated_query.test.d.ts.map +0 -1
  425. package/dist/esm-types/react/use_queries.test.d.ts +0 -5
  426. package/dist/esm-types/react/use_queries.test.d.ts.map +0 -1
  427. package/dist/esm-types/react/use_query.test.d.ts +0 -5
  428. package/dist/esm-types/react/use_query.test.d.ts.map +0 -1
  429. package/dist/esm-types/react/use_query_object_options.test.d.ts +0 -5
  430. package/dist/esm-types/react/use_query_object_options.test.d.ts.map +0 -1
  431. package/dist/esm-types/react/use_query_result.test.d.ts +0 -5
  432. package/dist/esm-types/react/use_query_result.test.d.ts.map +0 -1
  433. package/dist/esm-types/react-auth0/ConvexProviderWithAuth0.test.d.ts +0 -2
  434. package/dist/esm-types/react-auth0/ConvexProviderWithAuth0.test.d.ts.map +0 -1
  435. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.test.d.ts +0 -2
  436. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.test.d.ts.map +0 -1
  437. package/dist/esm-types/server/api.intersect.test.d.ts +0 -2
  438. package/dist/esm-types/server/api.intersect.test.d.ts.map +0 -1
  439. package/dist/esm-types/server/api.test.d.ts +0 -2
  440. package/dist/esm-types/server/api.test.d.ts.map +0 -1
  441. package/dist/esm-types/server/audit_logging.test.d.ts +0 -2
  442. package/dist/esm-types/server/audit_logging.test.d.ts.map +0 -1
  443. package/dist/esm-types/server/components/index.test.d.ts +0 -2
  444. package/dist/esm-types/server/components/index.test.d.ts.map +0 -1
  445. package/dist/esm-types/server/cron.test.d.ts +0 -2
  446. package/dist/esm-types/server/cron.test.d.ts.map +0 -1
  447. package/dist/esm-types/server/data_model.test.d.ts +0 -2
  448. package/dist/esm-types/server/data_model.test.d.ts.map +0 -1
  449. package/dist/esm-types/server/database.test.d.ts +0 -2
  450. package/dist/esm-types/server/database.test.d.ts.map +0 -1
  451. package/dist/esm-types/server/database_api.test.d.ts +0 -2
  452. package/dist/esm-types/server/database_api.test.d.ts.map +0 -1
  453. package/dist/esm-types/server/filter_builder.test.d.ts +0 -2
  454. package/dist/esm-types/server/filter_builder.test.d.ts.map +0 -1
  455. package/dist/esm-types/server/impl/actions_impl.test.d.ts +0 -2
  456. package/dist/esm-types/server/impl/actions_impl.test.d.ts.map +0 -1
  457. package/dist/esm-types/server/impl/filter_builder_impl.test.d.ts +0 -2
  458. package/dist/esm-types/server/impl/filter_builder_impl.test.d.ts.map +0 -1
  459. package/dist/esm-types/server/impl/query_impl.test.d.ts +0 -2
  460. package/dist/esm-types/server/impl/query_impl.test.d.ts.map +0 -1
  461. package/dist/esm-types/server/pagination.test.d.ts +0 -2
  462. package/dist/esm-types/server/pagination.test.d.ts.map +0 -1
  463. package/dist/esm-types/server/query.test.d.ts +0 -2
  464. package/dist/esm-types/server/query.test.d.ts.map +0 -1
  465. package/dist/esm-types/server/registration.test.d.ts +0 -2
  466. package/dist/esm-types/server/registration.test.d.ts.map +0 -1
  467. package/dist/esm-types/server/router.test.d.ts +0 -2
  468. package/dist/esm-types/server/router.test.d.ts.map +0 -1
  469. package/dist/esm-types/server/scheduler.test.d.ts +0 -2
  470. package/dist/esm-types/server/scheduler.test.d.ts.map +0 -1
  471. package/dist/esm-types/server/schema.test.d.ts +0 -2
  472. package/dist/esm-types/server/schema.test.d.ts.map +0 -1
  473. package/dist/esm-types/test/fake_watch.d.ts +0 -16
  474. package/dist/esm-types/test/fake_watch.d.ts.map +0 -1
  475. package/dist/esm-types/test/type_testing.d.ts +0 -9
  476. package/dist/esm-types/test/type_testing.d.ts.map +0 -1
  477. package/dist/esm-types/type_utils.test.d.ts +0 -2
  478. package/dist/esm-types/type_utils.test.d.ts.map +0 -1
  479. package/dist/esm-types/values/size.test.d.ts +0 -2
  480. package/dist/esm-types/values/size.test.d.ts.map +0 -1
  481. package/dist/esm-types/values/validator.test.d.ts +0 -2
  482. package/dist/esm-types/values/validator.test.d.ts.map +0 -1
  483. package/dist/esm-types/values/value.test.d.ts +0 -2
  484. package/dist/esm-types/values/value.test.d.ts.map +0 -1
  485. package/src/browser/http_client.test.ts +0 -202
  486. package/src/browser/query_options.test.ts +0 -43
  487. package/src/browser/simple_client.test.ts +0 -104
  488. package/src/browser/sync/client.test.ts +0 -44
  489. package/src/browser/sync/client_node.test.ts +0 -1207
  490. package/src/browser/sync/client_node_test_helpers.ts +0 -200
  491. package/src/browser/sync/local_state.test.ts +0 -128
  492. package/src/browser/sync/optimistic_query_set.test.ts +0 -253
  493. package/src/browser/sync/paginated_query_client.test.ts +0 -597
  494. package/src/browser/sync/protocol.test.ts +0 -14
  495. package/src/browser/sync/request_manager.test.ts +0 -273
  496. package/src/bundler/fs.test.ts +0 -86
  497. package/src/bundler/index.test.ts +0 -210
  498. package/src/bundler/test_fixtures/js/project01/bar.js +0 -4
  499. package/src/bundler/test_fixtures/js/project01/file with spaces.js +0 -1
  500. package/src/bundler/test_fixtures/js/project01/foo.js +0 -9
  501. package/src/bundler/test_fixtures/js/project_with_https/https.js +0 -9
  502. package/src/bundler/test_fixtures/js/project_with_https_not_at_top_level/default.js +0 -3
  503. package/src/bundler/test_fixtures/js/project_with_https_not_at_top_level/more_code/https.js +0 -5
  504. package/src/bundler/test_fixtures/js/project_with_https_without_router/https.js +0 -1
  505. package/src/bundler/test_fixtures/js/project_with_node_shims/uses_node_shims.js +0 -4
  506. package/src/cli/codegen_templates/api.test.ts +0 -18
  507. package/src/cli/codegen_templates/common.test.ts +0 -52
  508. package/src/cli/codegen_templates/templates.test.ts +0 -16
  509. package/src/cli/codegen_templates/validator_helpers.test.ts +0 -31
  510. package/src/cli/configure.test.ts +0 -138
  511. package/src/cli/deploymentCreate.test.ts +0 -1376
  512. package/src/cli/deploymentSelect.test.ts +0 -1291
  513. package/src/cli/deploymentSelection.test.ts +0 -2546
  514. package/src/cli/deploymentToken.test.ts +0 -397
  515. package/src/cli/dev.test.ts +0 -157
  516. package/src/cli/envDefault.test.ts +0 -495
  517. package/src/cli/lib/__snapshots__/formatTargetedDeployment.test.ts.snap +0 -94
  518. package/src/cli/lib/aiFiles/agentsmd.test.ts +0 -133
  519. package/src/cli/lib/aiFiles/claudemd.test.ts +0 -92
  520. package/src/cli/lib/aiFiles/guidelinesmd.test.ts +0 -50
  521. package/src/cli/lib/aiFiles/index.test.ts +0 -986
  522. package/src/cli/lib/aiFiles/integration.test.ts +0 -692
  523. package/src/cli/lib/aiFiles/prompt.test.ts +0 -202
  524. package/src/cli/lib/aiFiles/state.test.ts +0 -305
  525. package/src/cli/lib/aiFiles/utils.test.ts +0 -50
  526. package/src/cli/lib/codegen.test.ts +0 -49
  527. package/src/cli/lib/components.test.ts +0 -227
  528. package/src/cli/lib/config.test.ts +0 -1026
  529. package/src/cli/lib/deployment.test.ts +0 -85
  530. package/src/cli/lib/deploymentSelector.test.ts +0 -107
  531. package/src/cli/lib/env.test.ts +0 -60
  532. package/src/cli/lib/expiration.test.ts +0 -159
  533. package/src/cli/lib/extractDeploymentNameForWorkOS.test.ts +0 -30
  534. package/src/cli/lib/formatEnvValueForDotfile.test.ts +0 -294
  535. package/src/cli/lib/formatTargetedDeployment.test.ts +0 -281
  536. package/src/cli/lib/fsUtils.test.ts +0 -67
  537. package/src/cli/lib/generateDocs.test.ts +0 -326
  538. package/src/cli/lib/indexes.test.ts +0 -77
  539. package/src/cli/lib/localDeployment/run.test.ts +0 -104
  540. package/src/cli/lib/localDeployment/secrets.test.ts +0 -53
  541. package/src/cli/lib/run.test.ts +0 -54
  542. package/src/cli/lib/runTestFunction.test.ts +0 -84
  543. package/src/cli/lib/typecheck.test.ts +0 -71
  544. package/src/cli/lib/updates.test.ts +0 -157
  545. package/src/cli/lib/utils/hash.test.ts +0 -25
  546. package/src/cli/lib/utils/utils.test.ts +0 -340
  547. package/src/cli/lib/versionApi.test.ts +0 -471
  548. package/src/cli/lib/workos/environmentApi.test.ts +0 -107
  549. package/src/cli/lib/workos/workos.test.ts +0 -242
  550. package/src/cli/login.test.ts +0 -261
  551. package/src/common/README.md +0 -2
  552. package/src/common/index.test.ts +0 -35
  553. package/src/nextjs/nextjs.test.tsx +0 -94
  554. package/src/react/ConvexAuthState.test.tsx +0 -702
  555. package/src/react/auth_helpers.test.tsx +0 -45
  556. package/src/react/auth_websocket.test.tsx +0 -1177
  557. package/src/react/client.test.tsx +0 -261
  558. package/src/react/client_provided_base_client.test.tsx +0 -174
  559. package/src/react/queries_observer.test.ts +0 -176
  560. package/src/react/react_node.test.ts +0 -78
  561. package/src/react/use_paginated_query.test.tsx +0 -1420
  562. package/src/react/use_queries.test.ts +0 -140
  563. package/src/react/use_query.test.ts +0 -71
  564. package/src/react/use_query_object_options.test.ts +0 -51
  565. package/src/react/use_query_result.test.ts +0 -75
  566. package/src/react-auth0/ConvexProviderWithAuth0.test.tsx +0 -17
  567. package/src/react-clerk/ConvexProviderWithClerk.test.tsx +0 -18
  568. package/src/server/README.md +0 -15
  569. package/src/server/api.intersect.test.ts +0 -109
  570. package/src/server/api.test.ts +0 -447
  571. package/src/server/audit_logging.test.ts +0 -131
  572. package/src/server/components/index.test.ts +0 -48
  573. package/src/server/cron.test.ts +0 -58
  574. package/src/server/data_model.test.ts +0 -221
  575. package/src/server/database.test.ts +0 -184
  576. package/src/server/database_api.test.ts +0 -439
  577. package/src/server/filter_builder.test.ts +0 -102
  578. package/src/server/impl/actions_impl.test.ts +0 -59
  579. package/src/server/impl/filter_builder_impl.test.ts +0 -13
  580. package/src/server/impl/query_impl.test.ts +0 -46
  581. package/src/server/pagination.test.ts +0 -49
  582. package/src/server/query.test.ts +0 -112
  583. package/src/server/registration.test.ts +0 -589
  584. package/src/server/router.test.ts +0 -148
  585. package/src/server/scheduler.test.ts +0 -31
  586. package/src/server/schema.test.ts +0 -1081
  587. package/src/test/fake_watch.ts +0 -54
  588. package/src/test/type_testing.ts +0 -21
  589. package/src/type_utils.test.ts +0 -62
  590. package/src/values/size.test.ts +0 -95
  591. package/src/values/validator.test.ts +0 -619
  592. package/src/values/value.test.ts +0 -232
  593. package/src/vendor/README.md +0 -18
  594. package/src/vendor/jwt-decode/README.md +0 -1
@@ -1,2546 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach, test } from "vitest";
2
- import { nodeFs } from "../bundler/fs.js";
3
- import { env } from "./env.js";
4
- import { deploy } from "./deploy.js";
5
- import { dev } from "./dev.js";
6
- import {
7
- deploymentFetch,
8
- bigBrainAPI,
9
- bigBrainAPIMaybeThrows,
10
- } from "./lib/utils/utils.js";
11
- import { readGlobalConfig } from "./lib/utils/globalConfig.js";
12
- import { deployToDeployment } from "./lib/deploy2.js";
13
- import { runPush } from "./lib/components.js";
14
- import { readProjectConfig, getAuthKitConfig } from "./lib/config.js";
15
- import { gitBranchFromEnvironment } from "./lib/envvars.js";
16
- import { devAgainstDeployment } from "./lib/dev.js";
17
- import {
18
- handleLocalDeployment,
19
- loadLocalDeploymentCredentials,
20
- } from "./lib/localDeployment/localDeployment.js";
21
- import { handleAnonymousDeployment } from "./lib/localDeployment/anonymous.js";
22
- import { loadProjectLocalConfig } from "./lib/localDeployment/filePaths.js";
23
- import {
24
- validateOrSelectTeam,
25
- validateOrSelectProject,
26
- } from "./lib/utils/utils.js";
27
- import { ensureLoggedIn } from "./lib/login.js";
28
-
29
- vi.mock("../bundler/fs.js", async (importOriginal) => {
30
- const actual = await importOriginal<typeof import("../bundler/fs.js")>();
31
- return {
32
- ...actual,
33
- nodeFs: {
34
- ...actual.nodeFs,
35
- exists: vi.fn().mockImplementation(() => {
36
- throw new Error("nodeFs.exists should be mocked in test");
37
- }),
38
- readUtf8File: vi.fn().mockImplementation(() => {
39
- throw new Error("nodeFs.readUtf8File should be mocked in test");
40
- }),
41
- },
42
- };
43
- });
44
-
45
- // Mock typedPlatformClient GET function — can be configured per test
46
- const mockPlatformGet = vi.fn();
47
-
48
- vi.mock("./lib/utils/utils.js", async (importOriginal) => {
49
- const actual = await importOriginal<typeof import("./lib/utils/utils.js")>();
50
- return {
51
- ...actual,
52
- deploymentFetch: vi.fn(),
53
- ensureHasConvexDependency: vi.fn(),
54
- bigBrainAPI: vi.fn(),
55
- bigBrainAPIMaybeThrows: vi.fn(),
56
- validateOrSelectTeam: vi.fn(),
57
- validateOrSelectProject: vi.fn(),
58
- typedPlatformClient: vi.fn(() => ({ GET: mockPlatformGet })),
59
- };
60
- });
61
-
62
- vi.mock("./lib/localDeployment/run.js", async (importOriginal) => {
63
- const actual =
64
- await importOriginal<typeof import("./lib/localDeployment/run.js")>();
65
- return {
66
- ...actual,
67
- withRunningBackend: vi.fn(
68
- async ({ action }: { action: () => Promise<void> }) => {
69
- await action();
70
- },
71
- ),
72
- fetchLocalBackendStatus: vi.fn().mockResolvedValue({ kind: "running" }),
73
- };
74
- });
75
-
76
- vi.mock("./lib/utils/globalConfig.js", async (importOriginal) => {
77
- const actual =
78
- await importOriginal<typeof import("./lib/utils/globalConfig.js")>();
79
- return {
80
- ...actual,
81
- readGlobalConfig: vi.fn().mockReturnValue(null),
82
- };
83
- });
84
-
85
- vi.mock("dotenv", async (importOriginal) => {
86
- const actual = await importOriginal<typeof import("dotenv")>();
87
- return {
88
- ...actual,
89
- config: vi.fn(),
90
- };
91
- });
92
-
93
- vi.mock("@sentry/node", () => ({
94
- captureException: vi.fn(),
95
- close: vi.fn(),
96
- }));
97
-
98
- // Deploy-specific mocks
99
- vi.mock("./lib/deploy2.js", async (importOriginal) => {
100
- const actual = await importOriginal<typeof import("./lib/deploy2.js")>();
101
- return {
102
- ...actual,
103
- deployToDeployment: vi.fn(),
104
- };
105
- });
106
-
107
- vi.mock("./lib/components.js", async (importOriginal) => {
108
- const actual = await importOriginal<typeof import("./lib/components.js")>();
109
- return {
110
- ...actual,
111
- runPush: vi.fn(),
112
- };
113
- });
114
-
115
- vi.mock("./lib/config.js", async (importOriginal) => {
116
- const actual = await importOriginal<typeof import("./lib/config.js")>();
117
- return {
118
- ...actual,
119
- readProjectConfig: vi.fn().mockResolvedValue({
120
- projectConfig: { functions: "convex" },
121
- configPath: "convex.json",
122
- modules: [],
123
- }),
124
- getAuthKitConfig: vi.fn().mockResolvedValue(null),
125
- };
126
- });
127
-
128
- vi.mock("./lib/usage.js", async (importOriginal) => {
129
- const actual = await importOriginal<typeof import("./lib/usage.js")>();
130
- return {
131
- ...actual,
132
- usageStateWarning: vi.fn(),
133
- };
134
- });
135
-
136
- vi.mock("./lib/updates.js", async (importOriginal) => {
137
- const actual = await importOriginal<typeof import("./lib/updates.js")>();
138
- return {
139
- ...actual,
140
- checkVersionAndAiFilesStaleness: vi.fn(),
141
- };
142
- });
143
-
144
- vi.mock("./lib/dev.js", async (importOriginal) => {
145
- const actual = await importOriginal<typeof import("./lib/dev.js")>();
146
- return { ...actual, devAgainstDeployment: vi.fn() };
147
- });
148
-
149
- vi.mock("./lib/localDeployment/localDeployment.js", async (importOriginal) => {
150
- const actual =
151
- await importOriginal<
152
- typeof import("./lib/localDeployment/localDeployment.js")
153
- >();
154
- return {
155
- ...actual,
156
- handleLocalDeployment: vi.fn(),
157
- loadLocalDeploymentCredentials: vi.fn(),
158
- };
159
- });
160
-
161
- vi.mock("./lib/localDeployment/filePaths.js", async (importOriginal) => {
162
- const actual =
163
- await importOriginal<typeof import("./lib/localDeployment/filePaths.js")>();
164
- return {
165
- ...actual,
166
- loadProjectLocalConfig: vi.fn().mockReturnValue(null),
167
- };
168
- });
169
-
170
- vi.mock("./lib/localDeployment/anonymous.js", async (importOriginal) => {
171
- const actual =
172
- await importOriginal<typeof import("./lib/localDeployment/anonymous.js")>();
173
- return {
174
- ...actual,
175
- handleAnonymousDeployment: vi.fn(),
176
- };
177
- });
178
-
179
- vi.mock("./lib/login.js", async (importOriginal) => {
180
- const actual = await importOriginal<typeof import("./lib/login.js")>();
181
- return { ...actual, ensureLoggedIn: vi.fn() };
182
- });
183
-
184
- vi.mock("./lib/aiFiles/index.js", async (importOriginal) => {
185
- const actual =
186
- await importOriginal<typeof import("./lib/aiFiles/index.js")>();
187
- return { ...actual, attemptSetupAiFiles: vi.fn() };
188
- });
189
-
190
- vi.mock("./configure.js", async (importOriginal) => {
191
- const actual = await importOriginal<typeof import("./configure.js")>();
192
- return {
193
- ...actual,
194
- // Override to skip fetchDeploymentCanonicalSiteUrl and file-writing side
195
- // effects, while still exercising _deploymentCredentialsOrConfigure (which
196
- // routes through the BigBrain mocks, handleLocalDeployment, etc.).
197
- deploymentCredentialsOrConfigure: async (
198
- ctx: any,
199
- deploymentSelection: any,
200
- chosenConfiguration: any,
201
- cmdOptions: any,
202
- ) => {
203
- const selected = await actual._deploymentCredentialsOrConfigure(
204
- ctx,
205
- deploymentSelection,
206
- chosenConfiguration,
207
- cmdOptions,
208
- );
209
- return {
210
- url: selected.url,
211
- adminKey: selected.adminKey,
212
- deploymentFields:
213
- selected.deploymentFields !== null
214
- ? { ...selected.deploymentFields, siteUrl: null }
215
- : null,
216
- };
217
- },
218
- };
219
- });
220
-
221
- vi.mock("./lib/envvars.js", async (importOriginal) => {
222
- const actual = await importOriginal<typeof import("./lib/envvars.js")>();
223
- return {
224
- ...actual,
225
- gitBranchFromEnvironment: vi.fn().mockReturnValue(null),
226
- isNonProdBuildEnvironment: vi.fn().mockReturnValue(false),
227
- };
228
- });
229
-
230
- /**
231
- * Routes mock Big Brain API calls by path.
232
- * Both `bigBrainAPI` and `bigBrainAPIMaybeThrows` delegate to this.
233
- */
234
- function setupBigBrainRoutes(routes: Record<string, (data?: any) => any>) {
235
- const handler = (args: { path: string; data?: any }) => {
236
- // Match by exact path or by path prefix (for paths like `deployment/foo/team_and_project`)
237
- for (const [routePath, routeHandler] of Object.entries(routes)) {
238
- if (args.path === routePath || args.path.startsWith(routePath)) {
239
- return routeHandler(args.data);
240
- }
241
- }
242
- throw new Error(`Unmocked Big Brain route: ${args.path}`);
243
- };
244
- vi.mocked(bigBrainAPI).mockImplementation(handler as any);
245
- vi.mocked(bigBrainAPIMaybeThrows).mockImplementation(handler as any);
246
- }
247
-
248
- describe("deployment selection flows", () => {
249
- let savedEnv: NodeJS.ProcessEnv;
250
- let savedIsTTY: boolean | undefined;
251
-
252
- beforeEach(() => {
253
- savedEnv = { ...process.env };
254
- savedIsTTY = process.stdin.isTTY;
255
- process.env = {};
256
- // Default to interactive TTY for existing tests
257
- process.stdin.isTTY = true as any;
258
-
259
- vi.resetAllMocks();
260
- vi.mocked(readGlobalConfig).mockReturnValue(null);
261
- vi.mocked(nodeFs.exists).mockReturnValue(false);
262
- // Re-apply deploy-specific mocks after resetAllMocks
263
- vi.mocked(readProjectConfig).mockResolvedValue({
264
- projectConfig: { functions: "convex" } as any,
265
- configPath: "convex.json",
266
- });
267
- vi.mocked(getAuthKitConfig).mockResolvedValue(undefined);
268
- vi.mocked(gitBranchFromEnvironment).mockReturnValue(null);
269
- vi.mocked(devAgainstDeployment).mockResolvedValue(undefined);
270
- vi.mocked(handleLocalDeployment).mockResolvedValue({
271
- deploymentName: "local-test",
272
- deploymentUrl: "http://127.0.0.1:3210",
273
- adminKey: "local|admin|key",
274
- } as any);
275
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
276
- deploymentName: "local-test",
277
- deploymentUrl: "http://127.0.0.1:3210",
278
- adminKey: "local|admin|key",
279
- });
280
- vi.mocked(validateOrSelectTeam).mockRejectedValue(
281
- new Error("validateOrSelectTeam should be mocked"),
282
- );
283
- vi.mocked(validateOrSelectProject).mockRejectedValue(
284
- new Error("validateOrSelectProject should be mocked"),
285
- );
286
- vi.mocked(ensureLoggedIn).mockResolvedValue(undefined);
287
- vi.mocked(handleAnonymousDeployment).mockResolvedValue({
288
- deploymentName: "anon-test",
289
- deploymentUrl: "http://127.0.0.1:3210",
290
- adminKey: "anon|admin|key",
291
- reference: null,
292
- isDefault: false,
293
- });
294
- });
295
-
296
- afterEach(() => {
297
- process.env = savedEnv;
298
- process.stdin.isTTY = savedIsTTY as any;
299
- });
300
-
301
- // Suppress process.exit and stderr
302
- beforeEach(() => {
303
- vi.spyOn(process, "exit").mockImplementation((() => {
304
- throw new Error("process.exit called");
305
- }) as any);
306
- vi.spyOn(process.stderr, "write").mockImplementation(() => true);
307
- });
308
-
309
- afterEach(() => {
310
- vi.restoreAllMocks();
311
- });
312
-
313
- describe("regular command (npx convex env)", () => {
314
- it("uses --url and --admin-key directly", async () => {
315
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
316
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
317
-
318
- await env.parseAsync(
319
- [
320
- "set",
321
- "ABC",
322
- "DEF",
323
- "--url",
324
- "https://joyful-capybara-123.convex.cloud",
325
- "--admin-key",
326
- "my-admin-key",
327
- ],
328
- { from: "user" },
329
- );
330
-
331
- expect(deploymentFetch).toHaveBeenCalledWith(
332
- expect.anything(),
333
- expect.objectContaining({
334
- deploymentUrl: "https://joyful-capybara-123.convex.cloud",
335
- adminKey: "my-admin-key",
336
- }),
337
- );
338
-
339
- expect(mockFetch).toHaveBeenCalledWith(
340
- "/api/update_environment_variables",
341
- expect.objectContaining({
342
- method: "POST",
343
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
344
- }),
345
- );
346
-
347
- // No Big Brain calls
348
- expect(bigBrainAPI).not.toHaveBeenCalled();
349
- expect(bigBrainAPIMaybeThrows).not.toHaveBeenCalled();
350
- });
351
-
352
- it("resolves CONVEX_DEPLOY_KEY with deployment deploy key via Big Brain", async () => {
353
- process.env.CONVEX_DEPLOY_KEY = "prod:joyful-capybara-123|secretkey";
354
-
355
- setupBigBrainRoutes({
356
- "deployment/url_for_key": () =>
357
- "https://joyful-capybara-123.eu-west-1.convex.cloud",
358
- "deployment/team_and_project_for_key": () => ({
359
- team: "my-team",
360
- project: "my-project",
361
- teamId: 1,
362
- projectId: 1,
363
- }),
364
- });
365
-
366
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
367
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
368
-
369
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
370
-
371
- expect(deploymentFetch).toHaveBeenCalledWith(
372
- expect.anything(),
373
- expect.objectContaining({
374
- deploymentUrl: "https://joyful-capybara-123.eu-west-1.convex.cloud",
375
- adminKey: "prod:joyful-capybara-123|secretkey",
376
- }),
377
- );
378
-
379
- expect(mockFetch).toHaveBeenCalledWith(
380
- "/api/update_environment_variables",
381
- expect.objectContaining({
382
- method: "POST",
383
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
384
- }),
385
- );
386
-
387
- expect(bigBrainAPI).toHaveBeenCalledWith(
388
- expect.objectContaining({ path: "deployment/url_for_key" }),
389
- );
390
- expect(bigBrainAPI).toHaveBeenCalledWith(
391
- expect.objectContaining({
392
- path: "deployment/team_and_project_for_key",
393
- }),
394
- );
395
- });
396
-
397
- it("resolves CONVEX_DEPLOYMENT_TOKEN as an alias for CONVEX_DEPLOY_KEY", async () => {
398
- process.env.CONVEX_DEPLOYMENT_TOKEN =
399
- "prod:joyful-capybara-123|secretkey";
400
-
401
- setupBigBrainRoutes({
402
- "deployment/url_for_key": () =>
403
- "https://joyful-capybara-123.eu-west-1.convex.cloud",
404
- "deployment/team_and_project_for_key": () => ({
405
- team: "my-team",
406
- project: "my-project",
407
- teamId: 1,
408
- projectId: 1,
409
- }),
410
- });
411
-
412
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
413
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
414
-
415
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
416
-
417
- expect(deploymentFetch).toHaveBeenCalledWith(
418
- expect.anything(),
419
- expect.objectContaining({
420
- deploymentUrl: "https://joyful-capybara-123.eu-west-1.convex.cloud",
421
- adminKey: "prod:joyful-capybara-123|secretkey",
422
- }),
423
- );
424
- });
425
-
426
- it("CONVEX_DEPLOY_KEY takes precedence over CONVEX_DEPLOYMENT_TOKEN", async () => {
427
- process.env.CONVEX_DEPLOY_KEY = "prod:joyful-capybara-123|secretkey";
428
- process.env.CONVEX_DEPLOYMENT_TOKEN =
429
- "prod:other-deployment-456|otherkey";
430
-
431
- setupBigBrainRoutes({
432
- "deployment/url_for_key": () =>
433
- "https://joyful-capybara-123.eu-west-1.convex.cloud",
434
- "deployment/team_and_project_for_key": () => ({
435
- team: "my-team",
436
- project: "my-project",
437
- teamId: 1,
438
- projectId: 1,
439
- }),
440
- });
441
-
442
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
443
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
444
-
445
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
446
-
447
- expect(deploymentFetch).toHaveBeenCalledWith(
448
- expect.anything(),
449
- expect.objectContaining({
450
- deploymentUrl: "https://joyful-capybara-123.eu-west-1.convex.cloud",
451
- adminKey: "prod:joyful-capybara-123|secretkey",
452
- }),
453
- );
454
- });
455
-
456
- it("resolves CONVEX_DEPLOY_KEY with project deploy key to dev deployment by default", async () => {
457
- process.env.CONVEX_DEPLOY_KEY = "project:identifier|secretkey";
458
-
459
- setupBigBrainRoutes({
460
- "deployment/provision_and_authorize": () => ({
461
- adminKey: "dev-admin-key",
462
- url: "https://swift-squirrel-234.convex.cloud",
463
- deploymentName: "swift-squirrel-234",
464
- }),
465
- });
466
-
467
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
468
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
469
-
470
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
471
-
472
- expect(deploymentFetch).toHaveBeenCalledWith(
473
- expect.anything(),
474
- expect.objectContaining({
475
- deploymentUrl: "https://swift-squirrel-234.convex.cloud",
476
- adminKey: "dev-admin-key",
477
- }),
478
- );
479
-
480
- expect(mockFetch).toHaveBeenCalledWith(
481
- "/api/update_environment_variables",
482
- expect.objectContaining({
483
- method: "POST",
484
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
485
- }),
486
- );
487
-
488
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
489
- expect.objectContaining({
490
- path: "deployment/provision_and_authorize",
491
- }),
492
- );
493
- });
494
-
495
- it("resolves CONVEX_DEPLOY_KEY with project deploy key to prod deployment with --prod", async () => {
496
- process.env.CONVEX_DEPLOY_KEY = "project:identifier|secretkey";
497
-
498
- setupBigBrainRoutes({
499
- "deployment/provision_and_authorize": (_data: any) => ({
500
- adminKey: "prod-admin-key",
501
- url: "https://graceful-puffin-456.convex.cloud",
502
- deploymentName: "graceful-puffin-456",
503
- }),
504
- });
505
-
506
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
507
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
508
-
509
- await env.parseAsync(["set", "ABC", "DEF", "--prod"], { from: "user" });
510
-
511
- expect(deploymentFetch).toHaveBeenCalledWith(
512
- expect.anything(),
513
- expect.objectContaining({
514
- deploymentUrl: "https://graceful-puffin-456.convex.cloud",
515
- adminKey: "prod-admin-key",
516
- }),
517
- );
518
-
519
- expect(mockFetch).toHaveBeenCalledWith(
520
- "/api/update_environment_variables",
521
- expect.objectContaining({
522
- method: "POST",
523
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
524
- }),
525
- );
526
-
527
- // provision_and_authorize is called with prod deploymentType
528
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
529
- expect.objectContaining({
530
- path: "deployment/provision_and_authorize",
531
- data: expect.objectContaining({
532
- deploymentType: "prod",
533
- }),
534
- }),
535
- );
536
- });
537
-
538
- it("uses CONVEX_SELF_HOSTED_URL and CONVEX_SELF_HOSTED_ADMIN_KEY directly", async () => {
539
- process.env.CONVEX_SELF_HOSTED_URL = "http://localhost:3210";
540
- process.env.CONVEX_SELF_HOSTED_ADMIN_KEY = "self-hosted-key";
541
-
542
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
543
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
544
-
545
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
546
-
547
- expect(deploymentFetch).toHaveBeenCalledWith(
548
- expect.anything(),
549
- expect.objectContaining({
550
- deploymentUrl: "http://localhost:3210",
551
- adminKey: "self-hosted-key",
552
- }),
553
- );
554
-
555
- expect(mockFetch).toHaveBeenCalledWith(
556
- "/api/update_environment_variables",
557
- expect.objectContaining({
558
- method: "POST",
559
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
560
- }),
561
- );
562
-
563
- // No Big Brain calls
564
- expect(bigBrainAPI).not.toHaveBeenCalled();
565
- expect(bigBrainAPIMaybeThrows).not.toHaveBeenCalled();
566
- });
567
-
568
- it("resolves CONVEX_DEPLOYMENT to CONVEX_DEPLOYMENT by default", async () => {
569
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
570
- vi.mocked(readGlobalConfig).mockReturnValue({
571
- accessToken: "test-token",
572
- });
573
-
574
- setupBigBrainRoutes({
575
- "deployment/joyful-capybara-123/team_and_project": () => ({
576
- team: "my-team",
577
- project: "my-project",
578
- teamId: 1,
579
- projectId: 1,
580
- }),
581
- "deployment/authorize_within_current_project": () => ({
582
- adminKey: "dev-key",
583
- url: "https://joyful-capybara-123.convex.cloud",
584
- deploymentName: "joyful-capybara-123",
585
- deploymentType: "dev",
586
- }),
587
- });
588
-
589
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
590
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
591
-
592
- await env.parseAsync(["set", "ABC", "DEF"], { from: "user" });
593
-
594
- expect(deploymentFetch).toHaveBeenCalledWith(
595
- expect.anything(),
596
- expect.objectContaining({
597
- deploymentUrl: "https://joyful-capybara-123.convex.cloud",
598
- adminKey: "dev-key",
599
- }),
600
- );
601
-
602
- expect(mockFetch).toHaveBeenCalledWith(
603
- "/api/update_environment_variables",
604
- expect.objectContaining({
605
- method: "POST",
606
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
607
- }),
608
- );
609
-
610
- expect(bigBrainAPI).toHaveBeenCalledWith(
611
- expect.objectContaining({
612
- path: "deployment/authorize_within_current_project",
613
- data: expect.objectContaining({
614
- selectedDeploymentName: "joyful-capybara-123",
615
- projectSelection: expect.objectContaining({
616
- kind: "deploymentName",
617
- deploymentName: "joyful-capybara-123",
618
- }),
619
- }),
620
- }),
621
- );
622
- });
623
-
624
- it("resolves CONVEX_DEPLOYMENT with --prod to prod deployment", async () => {
625
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
626
- vi.mocked(readGlobalConfig).mockReturnValue({
627
- accessToken: "test-token",
628
- });
629
-
630
- setupBigBrainRoutes({
631
- "deployment/joyful-capybara-123/team_and_project": () => ({
632
- team: "my-team",
633
- project: "my-project",
634
- teamId: 1,
635
- projectId: 1,
636
- }),
637
- "deployment/authorize_prod": () => ({
638
- adminKey: "prod-key",
639
- url: "https://graceful-puffin-456.convex.cloud",
640
- deploymentName: "graceful-puffin-456",
641
- deploymentType: "prod",
642
- }),
643
- });
644
-
645
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
646
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
647
-
648
- await env.parseAsync(["set", "ABC", "DEF", "--prod"], { from: "user" });
649
-
650
- expect(deploymentFetch).toHaveBeenCalledWith(
651
- expect.anything(),
652
- expect.objectContaining({
653
- deploymentUrl: "https://graceful-puffin-456.convex.cloud",
654
- adminKey: "prod-key",
655
- }),
656
- );
657
-
658
- expect(mockFetch).toHaveBeenCalledWith(
659
- "/api/update_environment_variables",
660
- expect.objectContaining({
661
- method: "POST",
662
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
663
- }),
664
- );
665
-
666
- expect(bigBrainAPI).toHaveBeenCalledWith(
667
- expect.objectContaining({
668
- path: "deployment/authorize_prod",
669
- }),
670
- );
671
- });
672
-
673
- it("resolves CONVEX_DEPLOYMENT with --preview-name to preview deployment", async () => {
674
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
675
- vi.mocked(readGlobalConfig).mockReturnValue({
676
- accessToken: "test-token",
677
- });
678
-
679
- setupBigBrainRoutes({
680
- "deployment/joyful-capybara-123/team_and_project": () => ({
681
- team: "my-team",
682
- project: "my-project",
683
- teamId: 1,
684
- projectId: 1,
685
- }),
686
- "deployment/authorize_preview": () => ({
687
- adminKey: "preview-key",
688
- url: "https://nimble-penguin-234.convex.cloud",
689
- deploymentName: "nimble-penguin-234",
690
- deploymentType: "preview",
691
- }),
692
- });
693
-
694
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
695
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
696
-
697
- await env.parseAsync(
698
- ["set", "ABC", "DEF", "--preview-name", "my-preview"],
699
- { from: "user" },
700
- );
701
-
702
- expect(deploymentFetch).toHaveBeenCalledWith(
703
- expect.anything(),
704
- expect.objectContaining({
705
- deploymentUrl: "https://nimble-penguin-234.convex.cloud",
706
- adminKey: "preview-key",
707
- }),
708
- );
709
-
710
- expect(mockFetch).toHaveBeenCalledWith(
711
- "/api/update_environment_variables",
712
- expect.objectContaining({
713
- method: "POST",
714
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
715
- }),
716
- );
717
-
718
- expect(bigBrainAPI).toHaveBeenCalledWith(
719
- expect.objectContaining({
720
- path: "deployment/authorize_preview",
721
- }),
722
- );
723
- });
724
-
725
- it("resolves CONVEX_DEPLOYMENT with --deployment-name to named deployment", async () => {
726
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
727
- vi.mocked(readGlobalConfig).mockReturnValue({
728
- accessToken: "test-token",
729
- });
730
-
731
- setupBigBrainRoutes({
732
- "deployment/limitless-wolf-571/team_and_project": () => ({
733
- team: "my-team",
734
- project: "my-project",
735
- teamId: 1,
736
- projectId: 1,
737
- }),
738
- "deployment/authorize_within_current_project": () => ({
739
- adminKey: "staging-key",
740
- url: "https://clever-otter-890.convex.cloud",
741
- deploymentName: "clever-otter-890",
742
- deploymentType: "dev",
743
- }),
744
- });
745
-
746
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
747
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
748
-
749
- await env.parseAsync(
750
- ["set", "ABC", "DEF", "--deployment-name", "limitless-wolf-571"],
751
- { from: "user" },
752
- );
753
-
754
- expect(deploymentFetch).toHaveBeenCalledWith(
755
- expect.anything(),
756
- expect.objectContaining({
757
- deploymentUrl: "https://clever-otter-890.convex.cloud",
758
- adminKey: "staging-key",
759
- }),
760
- );
761
-
762
- expect(mockFetch).toHaveBeenCalledWith(
763
- "/api/update_environment_variables",
764
- expect.objectContaining({
765
- method: "POST",
766
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
767
- }),
768
- );
769
-
770
- expect(bigBrainAPI).toHaveBeenCalledWith(
771
- expect.objectContaining({
772
- path: "deployment/authorize_within_current_project",
773
- data: expect.objectContaining({
774
- projectSelection: expect.objectContaining({
775
- kind: "deploymentName",
776
- deploymentName: "limitless-wolf-571",
777
- deploymentType: null,
778
- }),
779
- }),
780
- }),
781
- );
782
- });
783
-
784
- it("resolves --deployment-name targeting a deployment in a different project from CONVEX_DEPLOYMENT", async () => {
785
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
786
- vi.mocked(readGlobalConfig).mockReturnValue({
787
- accessToken: "test-token",
788
- });
789
-
790
- setupBigBrainRoutes({
791
- "deployment/cross-project-deploy/team_and_project": () => ({
792
- team: "other-team",
793
- project: "other-project",
794
- teamId: 2,
795
- projectId: 2,
796
- }),
797
- "deployment/authorize_within_current_project": () => ({
798
- adminKey: "cross-project-key",
799
- url: "https://cross-project-deploy.convex.cloud",
800
- deploymentName: "cross-project-deploy",
801
- deploymentType: "dev",
802
- }),
803
- });
804
-
805
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
806
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
807
-
808
- await env.parseAsync(
809
- ["set", "ABC", "DEF", "--deployment-name", "cross-project-deploy"],
810
- { from: "user" },
811
- );
812
-
813
- expect(deploymentFetch).toHaveBeenCalledWith(
814
- expect.anything(),
815
- expect.objectContaining({
816
- deploymentUrl: "https://cross-project-deploy.convex.cloud",
817
- adminKey: "cross-project-key",
818
- }),
819
- );
820
-
821
- // Verify authorize_within_current_project was called with the
822
- // --deployment-name deployment as the project selector, not CONVEX_DEPLOYMENT
823
- expect(bigBrainAPI).toHaveBeenCalledWith(
824
- expect.objectContaining({
825
- path: "deployment/authorize_within_current_project",
826
- data: expect.objectContaining({
827
- projectSelection: expect.objectContaining({
828
- kind: "deploymentName",
829
- deploymentName: "cross-project-deploy",
830
- deploymentType: null,
831
- }),
832
- selectedDeploymentName: "cross-project-deploy",
833
- }),
834
- }),
835
- );
836
- });
837
-
838
- it("resolves --deployment-name with cloud deployment name without CONVEX_DEPLOYMENT", async () => {
839
- delete process.env.CONVEX_DEPLOYMENT;
840
-
841
- setupBigBrainRoutes({
842
- "deployment/clever-otter-890/team_and_project": () => ({
843
- team: "my-team",
844
- project: "my-project",
845
- teamId: 1,
846
- projectId: 1,
847
- }),
848
- "deployment/authorize_within_current_project": () => ({
849
- adminKey: "other-key",
850
- url: "https://clever-otter-890.convex.cloud",
851
- deploymentName: "clever-otter-890",
852
- deploymentType: "dev",
853
- }),
854
- });
855
-
856
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
857
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
858
-
859
- await env.parseAsync(
860
- ["set", "ABC", "DEF", "--deployment-name", "clever-otter-890"],
861
- { from: "user" },
862
- );
863
-
864
- // The project was resolved using clever-otter-890 as the anchor, not
865
- // joyful-capybara-123 (which isn't set in this test).
866
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
867
- expect.objectContaining({
868
- path: "deployment/clever-otter-890/team_and_project",
869
- }),
870
- );
871
- expect(bigBrainAPI).toHaveBeenCalledWith(
872
- expect.objectContaining({
873
- path: "deployment/authorize_within_current_project",
874
- }),
875
- );
876
- expect(deploymentFetch).toHaveBeenCalledWith(
877
- expect.anything(),
878
- expect.objectContaining({
879
- deploymentUrl: "https://clever-otter-890.convex.cloud",
880
- adminKey: "other-key",
881
- }),
882
- );
883
- });
884
-
885
- it("resolves deployment deploy key from --env-file", async () => {
886
- const fakeEnvFilePath = "/fake/convex-test.env";
887
- vi.mocked(nodeFs.exists).mockReturnValue(true);
888
- vi.mocked(nodeFs.readUtf8File).mockReturnValue(
889
- "CONVEX_DEPLOY_KEY=prod:joyful-capybara-123|secretkey\n",
890
- );
891
-
892
- setupBigBrainRoutes({
893
- "deployment/url_for_key": () =>
894
- "https://joyful-capybara-123.convex.cloud",
895
- "deployment/team_and_project_for_key": () => ({
896
- team: "my-team",
897
- project: "my-project",
898
- teamId: 1,
899
- projectId: 1,
900
- }),
901
- });
902
-
903
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
904
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
905
-
906
- await env.parseAsync(
907
- ["set", "ABC", "DEF", "--env-file", fakeEnvFilePath],
908
- {
909
- from: "user",
910
- },
911
- );
912
-
913
- expect(deploymentFetch).toHaveBeenCalledWith(
914
- expect.anything(),
915
- expect.objectContaining({
916
- deploymentUrl: "https://joyful-capybara-123.convex.cloud",
917
- adminKey: "prod:joyful-capybara-123|secretkey",
918
- }),
919
- );
920
-
921
- expect(mockFetch).toHaveBeenCalledWith(
922
- "/api/update_environment_variables",
923
- expect.objectContaining({
924
- method: "POST",
925
- body: JSON.stringify({ changes: [{ name: "ABC", value: "DEF" }] }),
926
- }),
927
- );
928
-
929
- expect(bigBrainAPI).toHaveBeenCalledWith(
930
- expect.objectContaining({ path: "deployment/url_for_key" }),
931
- );
932
- expect(bigBrainAPI).toHaveBeenCalledWith(
933
- expect.objectContaining({
934
- path: "deployment/team_and_project_for_key",
935
- }),
936
- );
937
- });
938
-
939
- describe("--deployment flag", () => {
940
- beforeEach(() => {
941
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
942
- vi.mocked(readGlobalConfig).mockReturnValue({
943
- accessToken: "test-token",
944
- });
945
- });
946
-
947
- it("resolves --deployment prod to production deployment", async () => {
948
- setupBigBrainRoutes({
949
- "deployment/joyful-capybara-123/team_and_project": () => ({
950
- team: "my-team",
951
- project: "my-project",
952
- teamId: 1,
953
- projectId: 1,
954
- }),
955
- "deployment/authorize_prod": () => ({
956
- adminKey: "prod-key",
957
- url: "https://graceful-puffin-456.convex.cloud",
958
- deploymentName: "graceful-puffin-456",
959
- deploymentType: "prod",
960
- }),
961
- });
962
-
963
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
964
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
965
-
966
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "prod"], {
967
- from: "user",
968
- });
969
-
970
- expect(bigBrainAPI).toHaveBeenCalledWith(
971
- expect.objectContaining({ path: "deployment/authorize_prod" }),
972
- );
973
- expect(deploymentFetch).toHaveBeenCalledWith(
974
- expect.anything(),
975
- expect.objectContaining({
976
- deploymentUrl: "https://graceful-puffin-456.convex.cloud",
977
- adminKey: "prod-key",
978
- }),
979
- );
980
- });
981
-
982
- it("resolves --deployment dev to dev deployment", async () => {
983
- setupBigBrainRoutes({
984
- "deployment/joyful-capybara-123/team_and_project": () => ({
985
- team: "my-team",
986
- project: "my-project",
987
- teamId: 1,
988
- projectId: 1,
989
- }),
990
- "teams/my-team/projects/my-project/deployments": () => true,
991
- "deployment/authorize_within_current_project": () => ({
992
- adminKey: "dev-key",
993
- url: "https://joyful-capybara-123.convex.cloud",
994
- deploymentName: "joyful-capybara-123",
995
- deploymentType: "dev",
996
- }),
997
- });
998
- mockPlatformGet.mockResolvedValue({
999
- data: { name: "joyful-capybara-123" },
1000
- error: undefined,
1001
- });
1002
-
1003
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1004
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1005
-
1006
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "dev"], {
1007
- from: "user",
1008
- });
1009
-
1010
- expect(mockPlatformGet).toHaveBeenCalledWith(
1011
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1012
- expect.objectContaining({
1013
- params: expect.objectContaining({
1014
- path: {
1015
- team_id_or_slug: "my-team",
1016
- project_slug: "my-project",
1017
- },
1018
- query: { defaultDev: true },
1019
- }),
1020
- }),
1021
- );
1022
- expect(bigBrainAPI).toHaveBeenCalledWith(
1023
- expect.objectContaining({
1024
- path: "deployment/authorize_within_current_project",
1025
- data: expect.objectContaining({
1026
- selectedDeploymentName: "joyful-capybara-123",
1027
- }),
1028
- }),
1029
- );
1030
- });
1031
-
1032
- it("resolves --deployment with cloud deployment name (abc-xyz-123)", async () => {
1033
- setupBigBrainRoutes({
1034
- "deployment/clever-otter-890/team_and_project": () => ({
1035
- team: "my-team",
1036
- project: "my-project",
1037
- teamId: 1,
1038
- projectId: 1,
1039
- }),
1040
- "deployment/authorize_within_current_project": () => ({
1041
- adminKey: "other-key",
1042
- url: "https://clever-otter-890.convex.cloud",
1043
- deploymentName: "clever-otter-890",
1044
- deploymentType: "dev",
1045
- }),
1046
- });
1047
-
1048
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1049
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1050
-
1051
- await env.parseAsync(
1052
- ["set", "ABC", "DEF", "--deployment", "clever-otter-890"],
1053
- { from: "user" },
1054
- );
1055
-
1056
- expect(bigBrainAPI).toHaveBeenCalledWith(
1057
- expect.objectContaining({
1058
- path: "deployment/authorize_within_current_project",
1059
- data: expect.objectContaining({
1060
- selectedDeploymentName: "clever-otter-890",
1061
- }),
1062
- }),
1063
- );
1064
- });
1065
-
1066
- it("resolves --deployment with cloud deployment name without CONVEX_DEPLOYMENT", async () => {
1067
- // No CONVEX_DEPLOYMENT set — the deployment name itself must be used as the
1068
- // project anchor (team_and_project is looked up via clever-otter-890, not
1069
- // via some pre-existing CONVEX_DEPLOYMENT).
1070
- delete process.env.CONVEX_DEPLOYMENT;
1071
-
1072
- setupBigBrainRoutes({
1073
- "deployment/clever-otter-890/team_and_project": () => ({
1074
- team: "my-team",
1075
- project: "my-project",
1076
- teamId: 1,
1077
- projectId: 1,
1078
- }),
1079
- "deployment/authorize_within_current_project": () => ({
1080
- adminKey: "other-key",
1081
- url: "https://clever-otter-890.convex.cloud",
1082
- deploymentName: "clever-otter-890",
1083
- deploymentType: "dev",
1084
- }),
1085
- });
1086
-
1087
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1088
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1089
-
1090
- await env.parseAsync(
1091
- ["set", "ABC", "DEF", "--deployment", "clever-otter-890"],
1092
- { from: "user" },
1093
- );
1094
-
1095
- // The project was resolved using clever-otter-890 as the anchor, not
1096
- // joyful-capybara-123 (which isn't set in this test).
1097
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
1098
- expect.objectContaining({
1099
- path: "deployment/clever-otter-890/team_and_project",
1100
- }),
1101
- );
1102
- expect(bigBrainAPI).toHaveBeenCalledWith(
1103
- expect.objectContaining({
1104
- path: "deployment/authorize_within_current_project",
1105
- data: expect.objectContaining({
1106
- selectedDeploymentName: "clever-otter-890",
1107
- }),
1108
- }),
1109
- );
1110
- expect(deploymentFetch).toHaveBeenCalledWith(
1111
- expect.anything(),
1112
- expect.objectContaining({
1113
- deploymentUrl: "https://clever-otter-890.convex.cloud",
1114
- adminKey: "other-key",
1115
- }),
1116
- );
1117
- });
1118
-
1119
- it("resolves --deployment with a reference", async () => {
1120
- setupBigBrainRoutes({
1121
- "deployment/joyful-capybara-123/team_and_project": () => ({
1122
- team: "my-team",
1123
- project: "my-project",
1124
- teamId: 1,
1125
- projectId: 1,
1126
- }),
1127
- "teams/my-team/projects/my-project/deployments": () => true,
1128
- "deployment/authorize_within_current_project": () => ({
1129
- adminKey: "staging-key",
1130
- url: "https://clever-otter-890.convex.cloud",
1131
- deploymentName: "clever-otter-890",
1132
- deploymentType: "dev",
1133
- }),
1134
- });
1135
- mockPlatformGet.mockResolvedValue({
1136
- data: { name: "clever-otter-890" },
1137
- error: undefined,
1138
- });
1139
-
1140
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1141
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1142
-
1143
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "staging"], {
1144
- from: "user",
1145
- });
1146
-
1147
- expect(mockPlatformGet).toHaveBeenCalledWith(
1148
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1149
- expect.objectContaining({
1150
- params: expect.objectContaining({
1151
- path: { team_id_or_slug: "my-team", project_slug: "my-project" },
1152
- query: { reference: "staging" },
1153
- }),
1154
- }),
1155
- );
1156
- expect(bigBrainAPI).toHaveBeenCalledWith(
1157
- expect.objectContaining({
1158
- path: "deployment/authorize_within_current_project",
1159
- data: expect.objectContaining({
1160
- selectedDeploymentName: "clever-otter-890",
1161
- }),
1162
- }),
1163
- );
1164
- });
1165
-
1166
- it("resolves --deployment with project:reference format", async () => {
1167
- setupBigBrainRoutes({
1168
- "deployment/joyful-capybara-123/team_and_project": () => ({
1169
- team: "my-team",
1170
- project: "my-project",
1171
- teamId: 1,
1172
- projectId: 1,
1173
- }),
1174
- "teams/my-team/projects/other-project/deployments": () => true,
1175
- "deployment/authorize_within_current_project": () => ({
1176
- adminKey: "other-proj-key",
1177
- url: "https://other-deploy-123.convex.cloud",
1178
- deploymentName: "other-deploy-123",
1179
- deploymentType: "dev",
1180
- }),
1181
- });
1182
- mockPlatformGet.mockResolvedValue({
1183
- data: { name: "other-deploy-123" },
1184
- error: undefined,
1185
- });
1186
-
1187
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1188
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1189
-
1190
- await env.parseAsync(
1191
- ["set", "ABC", "DEF", "--deployment", "other-project:staging"],
1192
- { from: "user" },
1193
- );
1194
-
1195
- expect(mockPlatformGet).toHaveBeenCalledWith(
1196
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1197
- expect.objectContaining({
1198
- params: expect.objectContaining({
1199
- path: {
1200
- team_id_or_slug: "my-team",
1201
- project_slug: "other-project",
1202
- },
1203
- query: { reference: "staging" },
1204
- }),
1205
- }),
1206
- );
1207
- expect(bigBrainAPI).toHaveBeenCalledWith(
1208
- expect.objectContaining({
1209
- path: "deployment/authorize_within_current_project",
1210
- data: expect.objectContaining({
1211
- selectedDeploymentName: "other-deploy-123",
1212
- }),
1213
- }),
1214
- );
1215
- });
1216
-
1217
- it("resolves --deployment with team:project:reference format without CONVEX_DEPLOYMENT", async () => {
1218
- // No CONVEX_DEPLOYMENT set
1219
- delete process.env.CONVEX_DEPLOYMENT;
1220
- setupBigBrainRoutes({
1221
- "deployment/authorize_within_current_project": () => ({
1222
- adminKey: "fq-key",
1223
- url: "https://fully-qualified-123.convex.cloud",
1224
- deploymentName: "fully-qualified-123",
1225
- deploymentType: "dev",
1226
- }),
1227
- "teams/myteam/projects/myproj/deployments": () => true,
1228
- });
1229
- mockPlatformGet.mockResolvedValue({
1230
- data: { name: "fully-qualified-123" },
1231
- error: undefined,
1232
- });
1233
-
1234
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1235
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1236
-
1237
- await env.parseAsync(
1238
- ["set", "ABC", "DEF", "--deployment", "myteam:myproj:staging"],
1239
- { from: "user" },
1240
- );
1241
-
1242
- expect(mockPlatformGet).toHaveBeenCalledWith(
1243
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1244
- expect.objectContaining({
1245
- params: expect.objectContaining({
1246
- path: { team_id_or_slug: "myteam", project_slug: "myproj" },
1247
- query: { reference: "staging" },
1248
- }),
1249
- }),
1250
- );
1251
- expect(bigBrainAPI).toHaveBeenCalledWith(
1252
- expect.objectContaining({
1253
- path: "deployment/authorize_within_current_project",
1254
- data: expect.objectContaining({
1255
- selectedDeploymentName: "fully-qualified-123",
1256
- }),
1257
- }),
1258
- );
1259
- });
1260
-
1261
- it("resolves --deployment project:dev to dev deployment in another project", async () => {
1262
- setupBigBrainRoutes({
1263
- "deployment/joyful-capybara-123/team_and_project": () => ({
1264
- team: "my-team",
1265
- project: "my-project",
1266
- teamId: 1,
1267
- projectId: 1,
1268
- }),
1269
- "teams/my-team/projects/other-project/deployments": () => true,
1270
- "deployment/authorize_within_current_project": () => ({
1271
- adminKey: "other-project-dev-key",
1272
- url: "https://other-project-dev.convex.cloud",
1273
- deploymentName: "other-project-dev",
1274
- deploymentType: "dev",
1275
- }),
1276
- });
1277
- mockPlatformGet.mockResolvedValue({
1278
- data: { name: "other-project-dev" },
1279
- error: undefined,
1280
- });
1281
-
1282
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1283
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1284
-
1285
- await env.parseAsync(
1286
- ["set", "ABC", "DEF", "--deployment", "other-project:dev"],
1287
- { from: "user" },
1288
- );
1289
-
1290
- expect(mockPlatformGet).toHaveBeenCalledWith(
1291
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1292
- expect.objectContaining({
1293
- params: expect.objectContaining({
1294
- path: {
1295
- team_id_or_slug: "my-team",
1296
- project_slug: "other-project",
1297
- },
1298
- query: { defaultDev: true },
1299
- }),
1300
- }),
1301
- );
1302
- expect(bigBrainAPI).toHaveBeenCalledWith(
1303
- expect.objectContaining({
1304
- path: "deployment/authorize_within_current_project",
1305
- data: expect.objectContaining({
1306
- selectedDeploymentName: "other-project-dev",
1307
- }),
1308
- }),
1309
- );
1310
- expect(deploymentFetch).toHaveBeenCalledWith(
1311
- expect.anything(),
1312
- expect.objectContaining({
1313
- deploymentUrl: "https://other-project-dev.convex.cloud",
1314
- adminKey: "other-project-dev-key",
1315
- }),
1316
- );
1317
- });
1318
-
1319
- it("resolves --deployment project:prod to prod deployment in another project", async () => {
1320
- setupBigBrainRoutes({
1321
- "deployment/joyful-capybara-123/team_and_project": () => ({
1322
- team: "my-team",
1323
- project: "my-project",
1324
- teamId: 1,
1325
- projectId: 1,
1326
- }),
1327
- "deployment/provision_and_authorize": () => ({
1328
- adminKey: "other-project-prod-key",
1329
- url: "https://other-project-prod.convex.cloud",
1330
- deploymentName: "other-project-prod",
1331
- }),
1332
- });
1333
-
1334
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1335
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1336
-
1337
- await env.parseAsync(
1338
- ["set", "ABC", "DEF", "--deployment", "other-project:prod"],
1339
- { from: "user" },
1340
- );
1341
-
1342
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
1343
- expect.objectContaining({
1344
- path: "deployment/provision_and_authorize",
1345
- data: expect.objectContaining({
1346
- teamSlug: "my-team",
1347
- projectSlug: "other-project",
1348
- deploymentType: "prod",
1349
- }),
1350
- }),
1351
- );
1352
- expect(deploymentFetch).toHaveBeenCalledWith(
1353
- expect.anything(),
1354
- expect.objectContaining({
1355
- deploymentUrl: "https://other-project-prod.convex.cloud",
1356
- adminKey: "other-project-prod-key",
1357
- }),
1358
- );
1359
- });
1360
-
1361
- it("resolves --deployment team:project:prod to prod deployment in fully qualified team/project", async () => {
1362
- setupBigBrainRoutes({
1363
- "teams/myteam/projects/myproject/deployments": () => true,
1364
- "deployment/provision_and_authorize": () => ({
1365
- adminKey: "fq-prod-key",
1366
- url: "https://fq-prod-deploy.convex.cloud",
1367
- deploymentName: "fq-prod-deploy",
1368
- }),
1369
- });
1370
-
1371
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1372
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1373
-
1374
- await env.parseAsync(
1375
- ["set", "ABC", "DEF", "--deployment", "myteam:myproject:prod"],
1376
- { from: "user" },
1377
- );
1378
-
1379
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
1380
- expect.objectContaining({
1381
- path: "deployment/provision_and_authorize",
1382
- data: expect.objectContaining({
1383
- teamSlug: "myteam",
1384
- projectSlug: "myproject",
1385
- deploymentType: "prod",
1386
- }),
1387
- }),
1388
- );
1389
- expect(deploymentFetch).toHaveBeenCalledWith(
1390
- expect.anything(),
1391
- expect.objectContaining({
1392
- deploymentUrl: "https://fq-prod-deploy.convex.cloud",
1393
- adminKey: "fq-prod-key",
1394
- }),
1395
- );
1396
- });
1397
-
1398
- it("resolves --deployment team:project:dev to dev deployment in fully qualified team/project", async () => {
1399
- setupBigBrainRoutes({
1400
- "teams/myteam/projects/myproject/deployments": () => true,
1401
- "deployment/authorize_within_current_project": () => ({
1402
- adminKey: "fq-dev-key",
1403
- url: "https://fq-dev-deploy.convex.cloud",
1404
- deploymentName: "fq-dev-deploy",
1405
- deploymentType: "dev",
1406
- }),
1407
- });
1408
- mockPlatformGet.mockResolvedValue({
1409
- data: { name: "fq-dev-deploy" },
1410
- error: undefined,
1411
- });
1412
-
1413
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1414
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1415
-
1416
- await env.parseAsync(
1417
- ["set", "ABC", "DEF", "--deployment", "myteam:myproject:dev"],
1418
- { from: "user" },
1419
- );
1420
-
1421
- expect(mockPlatformGet).toHaveBeenCalledWith(
1422
- "/teams/{team_id_or_slug}/projects/{project_slug}/deployment",
1423
- expect.objectContaining({
1424
- params: expect.objectContaining({
1425
- path: {
1426
- team_id_or_slug: "myteam",
1427
- project_slug: "myproject",
1428
- },
1429
- query: { defaultDev: true },
1430
- }),
1431
- }),
1432
- );
1433
- expect(bigBrainAPI).toHaveBeenCalledWith(
1434
- expect.objectContaining({
1435
- path: "deployment/authorize_within_current_project",
1436
- data: expect.objectContaining({
1437
- selectedDeploymentName: "fq-dev-deploy",
1438
- }),
1439
- }),
1440
- );
1441
- expect(deploymentFetch).toHaveBeenCalledWith(
1442
- expect.anything(),
1443
- expect.objectContaining({
1444
- deploymentUrl: "https://fq-dev-deploy.convex.cloud",
1445
- adminKey: "fq-dev-key",
1446
- }),
1447
- );
1448
- });
1449
-
1450
- it("errors when --deployment used with self-hosted deployment", async () => {
1451
- delete process.env.CONVEX_DEPLOYMENT;
1452
- process.env.CONVEX_SELF_HOSTED_URL = "http://localhost:3210";
1453
- process.env.CONVEX_SELF_HOSTED_ADMIN_KEY = "self-hosted-key";
1454
-
1455
- await expect(
1456
- env.parseAsync(["set", "ABC", "DEF", "--deployment", "prod"], {
1457
- from: "user",
1458
- }),
1459
- ).rejects.toThrow();
1460
-
1461
- expect(deploymentFetch).not.toHaveBeenCalled();
1462
- });
1463
-
1464
- it("errors when --deployment used with --url and --admin-key", async () => {
1465
- await expect(
1466
- env.parseAsync(
1467
- [
1468
- "set",
1469
- "ABC",
1470
- "DEF",
1471
- "--deployment",
1472
- "prod",
1473
- "--url",
1474
- "https://example.convex.cloud",
1475
- "--admin-key",
1476
- "mykey",
1477
- ],
1478
- { from: "user" },
1479
- ),
1480
- ).rejects.toThrow();
1481
- });
1482
-
1483
- it("resolves --deployment local to local deployment credentials", async () => {
1484
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1485
- deploymentName: "local-my_team-my_project-abc",
1486
- config: {
1487
- ports: { cloud: 3210, site: 3211 },
1488
- adminKey: "local-key",
1489
- backendVersion: "1.0.0",
1490
- cloudProjectId: 42,
1491
- },
1492
- });
1493
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1494
- deploymentName: "local-my_team-my_project-abc",
1495
- deploymentUrl: "http://127.0.0.1:3210",
1496
- adminKey: "local-key",
1497
- });
1498
- // The local deployment name is resolved via Big Brain for project
1499
- // access checks (checkAccessToSelectedProject)
1500
- setupBigBrainRoutes({
1501
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1502
- team: "my-team",
1503
- project: "my-project",
1504
- teamId: 1,
1505
- projectId: 42,
1506
- }),
1507
- "deployment/joyful-capybara-123/team_and_project": () => ({
1508
- team: "my-team",
1509
- project: "my-project",
1510
- teamId: 1,
1511
- projectId: 42,
1512
- }),
1513
- });
1514
- mockPlatformGet.mockImplementation((path: string) => {
1515
- if (path === "/deployments/{deployment_name}") {
1516
- return { data: { projectId: 42 } };
1517
- }
1518
- if (path === "/projects/{project_id}") {
1519
- return {
1520
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1521
- };
1522
- }
1523
- return { data: undefined };
1524
- });
1525
-
1526
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1527
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1528
-
1529
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1530
- from: "user",
1531
- });
1532
-
1533
- expect(loadLocalDeploymentCredentials).toHaveBeenCalledWith(
1534
- expect.anything(),
1535
- "local-my_team-my_project-abc",
1536
- );
1537
- expect(deploymentFetch).toHaveBeenCalledWith(
1538
- expect.anything(),
1539
- expect.objectContaining({
1540
- deploymentUrl: "http://127.0.0.1:3210",
1541
- adminKey: "local-key",
1542
- }),
1543
- );
1544
- });
1545
-
1546
- it("resolves --deployment local without CONVEX_DEPLOYMENT set", async () => {
1547
- delete process.env.CONVEX_DEPLOYMENT;
1548
-
1549
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1550
- deploymentName: "local-my_team-my_project-abc",
1551
- config: {
1552
- ports: { cloud: 3210, site: 3211 },
1553
- adminKey: "local-key",
1554
- backendVersion: "1.0.0",
1555
- cloudProjectId: 1,
1556
- },
1557
- });
1558
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1559
- deploymentName: "local-my_team-my_project-abc",
1560
- deploymentUrl: "http://127.0.0.1:3210",
1561
- adminKey: "local-key",
1562
- });
1563
- setupBigBrainRoutes({
1564
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1565
- team: "my-team",
1566
- project: "my-project",
1567
- teamId: 1,
1568
- projectId: 1,
1569
- }),
1570
- });
1571
-
1572
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1573
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1574
-
1575
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1576
- from: "user",
1577
- });
1578
-
1579
- expect(deploymentFetch).toHaveBeenCalledWith(
1580
- expect.anything(),
1581
- expect.objectContaining({
1582
- deploymentUrl: "http://127.0.0.1:3210",
1583
- adminKey: "local-key",
1584
- }),
1585
- );
1586
- });
1587
-
1588
- it("errors when --deployment local but no local deployment exists", async () => {
1589
- vi.mocked(loadProjectLocalConfig).mockReturnValue(null);
1590
-
1591
- await expect(
1592
- env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1593
- from: "user",
1594
- }),
1595
- ).rejects.toThrow();
1596
-
1597
- expect(process.stderr.write).toHaveBeenCalledWith(
1598
- expect.stringContaining("No local deployment found"),
1599
- );
1600
- expect(process.stderr.write).toHaveBeenCalledWith(
1601
- expect.stringContaining("npx convex deployment create local"),
1602
- );
1603
- });
1604
-
1605
- it("--deployment local with matching cloudProjectId resolves to local credentials", async () => {
1606
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1607
- deploymentName: "local-my_team-my_project-abc",
1608
- config: {
1609
- ports: { cloud: 3210, site: 3211 },
1610
- adminKey: "local-key",
1611
- backendVersion: "1.0.0",
1612
- cloudProjectId: 42,
1613
- },
1614
- });
1615
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1616
- deploymentName: "local-my_team-my_project-abc",
1617
- deploymentUrl: "http://127.0.0.1:3210",
1618
- adminKey: "local-key",
1619
- });
1620
- setupBigBrainRoutes({
1621
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1622
- team: "my-team",
1623
- project: "my-project",
1624
- teamId: 1,
1625
- projectId: 42,
1626
- }),
1627
- "deployment/joyful-capybara-123/team_and_project": () => ({
1628
- team: "my-team",
1629
- project: "my-project",
1630
- teamId: 1,
1631
- projectId: 42,
1632
- }),
1633
- });
1634
- mockPlatformGet.mockImplementation((path: string) => {
1635
- if (path === "/deployments/{deployment_name}") {
1636
- return { data: { projectId: 42 } };
1637
- }
1638
- if (path === "/projects/{project_id}") {
1639
- return {
1640
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1641
- };
1642
- }
1643
- return { data: undefined };
1644
- });
1645
-
1646
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1647
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1648
-
1649
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1650
- from: "user",
1651
- });
1652
-
1653
- expect(deploymentFetch).toHaveBeenCalledWith(
1654
- expect.anything(),
1655
- expect.objectContaining({
1656
- deploymentUrl: "http://127.0.0.1:3210",
1657
- adminKey: "local-key",
1658
- }),
1659
- );
1660
- });
1661
-
1662
- it("--deployment local with mismatching cloudProjectId crashes with helpful message", async () => {
1663
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1664
- deploymentName: "local-old_team-old_project-abc",
1665
- config: {
1666
- ports: { cloud: 3210, site: 3211 },
1667
- adminKey: "local-key",
1668
- backendVersion: "1.0.0",
1669
- cloudProjectId: 999, // mismatches
1670
- },
1671
- });
1672
- setupBigBrainRoutes({
1673
- "deployment/joyful-capybara-123/team_and_project": () => ({
1674
- team: "my-team",
1675
- project: "my-project",
1676
- teamId: 1,
1677
- projectId: 42,
1678
- }),
1679
- });
1680
- mockPlatformGet.mockImplementation((path: string) => {
1681
- if (path === "/deployments/{deployment_name}") {
1682
- return { data: { projectId: 42 } };
1683
- }
1684
- if (path === "/projects/{project_id}") {
1685
- return {
1686
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1687
- };
1688
- }
1689
- return { data: undefined };
1690
- });
1691
-
1692
- await expect(
1693
- env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1694
- from: "user",
1695
- }),
1696
- ).rejects.toThrow();
1697
-
1698
- expect(process.stderr.write).toHaveBeenCalledWith(
1699
- expect.stringContaining("different project"),
1700
- );
1701
- // Did not call bigBrainPause or bigBrainStart (read-only path)
1702
- expect(bigBrainAPI).not.toHaveBeenCalledWith(
1703
- expect.objectContaining({ path: "local_deployment/pause" }),
1704
- );
1705
- expect(bigBrainAPI).not.toHaveBeenCalledWith(
1706
- expect.objectContaining({ path: "local_deployment/start" }),
1707
- );
1708
- });
1709
-
1710
- it("--deployment local with missing cloudProjectId skips check and resolves", async () => {
1711
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1712
- deploymentName: "local-my_team-my_project-abc",
1713
- config: {
1714
- ports: { cloud: 3210, site: 3211 },
1715
- adminKey: "local-key",
1716
- backendVersion: "1.0.0",
1717
- cloudProjectId: undefined,
1718
- },
1719
- });
1720
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1721
- deploymentName: "local-my_team-my_project-abc",
1722
- deploymentUrl: "http://127.0.0.1:3210",
1723
- adminKey: "local-key",
1724
- });
1725
- setupBigBrainRoutes({
1726
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1727
- team: "my-team",
1728
- project: "my-project",
1729
- teamId: 1,
1730
- projectId: 42,
1731
- }),
1732
- });
1733
-
1734
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1735
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1736
-
1737
- await env.parseAsync(["set", "ABC", "DEF", "--deployment", "local"], {
1738
- from: "user",
1739
- });
1740
-
1741
- expect(deploymentFetch).toHaveBeenCalledWith(
1742
- expect.anything(),
1743
- expect.objectContaining({
1744
- deploymentUrl: "http://127.0.0.1:3210",
1745
- }),
1746
- );
1747
- });
1748
-
1749
- it("--deployment project:local with matching cloudProjectId resolves to local credentials", async () => {
1750
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1751
- deploymentName: "local-my_team-my_project-abc",
1752
- config: {
1753
- ports: { cloud: 3210, site: 3211 },
1754
- adminKey: "local-key",
1755
- backendVersion: "1.0.0",
1756
- cloudProjectId: 42,
1757
- },
1758
- });
1759
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1760
- deploymentName: "local-my_team-my_project-abc",
1761
- deploymentUrl: "http://127.0.0.1:3210",
1762
- adminKey: "local-key",
1763
- });
1764
- setupBigBrainRoutes({
1765
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1766
- team: "my-team",
1767
- project: "my-project",
1768
- teamId: 1,
1769
- projectId: 42,
1770
- }),
1771
- "deployment/joyful-capybara-123/team_and_project": () => ({
1772
- team: "my-team",
1773
- project: "my-project",
1774
- teamId: 1,
1775
- projectId: 42,
1776
- }),
1777
- });
1778
- mockPlatformGet.mockImplementation((path: string) => {
1779
- if (path === "/deployments/{deployment_name}") {
1780
- return { data: { projectId: 42 } };
1781
- }
1782
- if (path === "/projects/{project_id}") {
1783
- return {
1784
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1785
- };
1786
- }
1787
- if (path === "/teams/{team_id_or_slug}/projects/{project_slug}") {
1788
- return {
1789
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1790
- };
1791
- }
1792
- return { data: undefined };
1793
- });
1794
-
1795
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1796
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1797
-
1798
- await env.parseAsync(
1799
- ["set", "ABC", "DEF", "--deployment", "my-project:local"],
1800
- { from: "user" },
1801
- );
1802
-
1803
- expect(deploymentFetch).toHaveBeenCalledWith(
1804
- expect.anything(),
1805
- expect.objectContaining({
1806
- deploymentUrl: "http://127.0.0.1:3210",
1807
- adminKey: "local-key",
1808
- }),
1809
- );
1810
- });
1811
-
1812
- it("--deployment project:local with missing cloudProjectId resolves", async () => {
1813
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1814
- deploymentName: "local-my_team-my_project-abc",
1815
- config: {
1816
- ports: { cloud: 3210, site: 3211 },
1817
- adminKey: "local-key",
1818
- backendVersion: "1.0.0",
1819
- cloudProjectId: undefined,
1820
- },
1821
- });
1822
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1823
- deploymentName: "local-my_team-my_project-abc",
1824
- deploymentUrl: "http://127.0.0.1:3210",
1825
- adminKey: "local-key",
1826
- });
1827
- setupBigBrainRoutes({
1828
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1829
- team: "my-team",
1830
- project: "my-project",
1831
- teamId: 1,
1832
- projectId: 42,
1833
- }),
1834
- });
1835
-
1836
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1837
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1838
-
1839
- await env.parseAsync(
1840
- ["set", "ABC", "DEF", "--deployment", "my-project:local"],
1841
- { from: "user" },
1842
- );
1843
-
1844
- expect(deploymentFetch).toHaveBeenCalledWith(
1845
- expect.anything(),
1846
- expect.objectContaining({
1847
- deploymentUrl: "http://127.0.0.1:3210",
1848
- adminKey: "local-key",
1849
- }),
1850
- );
1851
- });
1852
-
1853
- it("--deployment project:local with mismatching cloudProjectId crashes", async () => {
1854
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1855
- deploymentName: "local-old_team-old_project-abc",
1856
- config: {
1857
- ports: { cloud: 3210, site: 3211 },
1858
- adminKey: "local-key",
1859
- backendVersion: "1.0.0",
1860
- cloudProjectId: 999,
1861
- },
1862
- });
1863
- setupBigBrainRoutes({
1864
- "deployment/joyful-capybara-123/team_and_project": () => ({
1865
- team: "my-team",
1866
- project: "my-project",
1867
- teamId: 1,
1868
- projectId: 42,
1869
- }),
1870
- });
1871
- mockPlatformGet.mockImplementation((path: string) => {
1872
- if (path === "/deployments/{deployment_name}") {
1873
- return { data: { projectId: 42 } };
1874
- }
1875
- if (path === "/projects/{project_id}") {
1876
- return {
1877
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1878
- };
1879
- }
1880
- if (path === "/teams/{team_id_or_slug}/projects/{project_slug}") {
1881
- return {
1882
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1883
- };
1884
- }
1885
- return { data: undefined };
1886
- });
1887
-
1888
- await expect(
1889
- env.parseAsync(
1890
- ["set", "ABC", "DEF", "--deployment", "my-project:local"],
1891
- { from: "user" },
1892
- ),
1893
- ).rejects.toThrow();
1894
-
1895
- expect(process.stderr.write).toHaveBeenCalledWith(
1896
- expect.stringContaining("different project"),
1897
- );
1898
- });
1899
-
1900
- it("--deployment team:project:local with matching cloudProjectId resolves", async () => {
1901
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1902
- deploymentName: "local-my_team-my_project-abc",
1903
- config: {
1904
- ports: { cloud: 3210, site: 3211 },
1905
- adminKey: "local-key",
1906
- backendVersion: "1.0.0",
1907
- cloudProjectId: 42,
1908
- },
1909
- });
1910
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1911
- deploymentName: "local-my_team-my_project-abc",
1912
- deploymentUrl: "http://127.0.0.1:3210",
1913
- adminKey: "local-key",
1914
- });
1915
- setupBigBrainRoutes({
1916
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1917
- team: "my-team",
1918
- project: "my-project",
1919
- teamId: 1,
1920
- projectId: 42,
1921
- }),
1922
- });
1923
- mockPlatformGet.mockImplementation((path: string) => {
1924
- if (path === "/teams/{team_id_or_slug}/projects/{project_slug}") {
1925
- return {
1926
- data: { id: 42, teamSlug: "my-team", slug: "my-project" },
1927
- };
1928
- }
1929
- return { data: undefined };
1930
- });
1931
-
1932
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1933
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1934
-
1935
- await env.parseAsync(
1936
- ["set", "ABC", "DEF", "--deployment", "my-team:my-project:local"],
1937
- { from: "user" },
1938
- );
1939
-
1940
- expect(deploymentFetch).toHaveBeenCalledWith(
1941
- expect.anything(),
1942
- expect.objectContaining({
1943
- deploymentUrl: "http://127.0.0.1:3210",
1944
- adminKey: "local-key",
1945
- }),
1946
- );
1947
- });
1948
-
1949
- it("--deployment team:project:local with missing cloudProjectId resolves", async () => {
1950
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1951
- deploymentName: "local-my_team-my_project-abc",
1952
- config: {
1953
- ports: { cloud: 3210, site: 3211 },
1954
- adminKey: "local-key",
1955
- backendVersion: "1.0.0",
1956
- cloudProjectId: undefined,
1957
- },
1958
- });
1959
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
1960
- deploymentName: "local-my_team-my_project-abc",
1961
- deploymentUrl: "http://127.0.0.1:3210",
1962
- adminKey: "local-key",
1963
- });
1964
- setupBigBrainRoutes({
1965
- "deployment/local-my_team-my_project-abc/team_and_project": () => ({
1966
- team: "my-team",
1967
- project: "my-project",
1968
- teamId: 1,
1969
- projectId: 42,
1970
- }),
1971
- });
1972
-
1973
- const mockFetch = vi.fn().mockResolvedValue({ ok: true });
1974
- vi.mocked(deploymentFetch).mockReturnValue(mockFetch as any);
1975
-
1976
- await env.parseAsync(
1977
- ["set", "ABC", "DEF", "--deployment", "my-team:my-project:local"],
1978
- { from: "user" },
1979
- );
1980
-
1981
- expect(deploymentFetch).toHaveBeenCalledWith(
1982
- expect.anything(),
1983
- expect.objectContaining({
1984
- deploymentUrl: "http://127.0.0.1:3210",
1985
- adminKey: "local-key",
1986
- }),
1987
- );
1988
- });
1989
-
1990
- it("--deployment team:project:local with mismatching cloudProjectId crashes", async () => {
1991
- vi.mocked(loadProjectLocalConfig).mockReturnValue({
1992
- deploymentName: "local-old_team-old_project-abc",
1993
- config: {
1994
- ports: { cloud: 3210, site: 3211 },
1995
- adminKey: "local-key",
1996
- backendVersion: "1.0.0",
1997
- cloudProjectId: 999,
1998
- },
1999
- });
2000
- mockPlatformGet.mockImplementation((path: string) => {
2001
- if (path === "/teams/{team_id_or_slug}/projects/{project_slug}") {
2002
- return {
2003
- data: {
2004
- id: 42,
2005
- teamSlug: "other-team",
2006
- slug: "other-project",
2007
- },
2008
- };
2009
- }
2010
- return { data: undefined };
2011
- });
2012
-
2013
- await expect(
2014
- env.parseAsync(
2015
- [
2016
- "set",
2017
- "ABC",
2018
- "DEF",
2019
- "--deployment",
2020
- "other-team:other-project:local",
2021
- ],
2022
- { from: "user" },
2023
- ),
2024
- ).rejects.toThrow();
2025
-
2026
- expect(process.stderr.write).toHaveBeenCalledWith(
2027
- expect.stringContaining("different project"),
2028
- );
2029
- });
2030
- });
2031
- });
2032
-
2033
- describe("deploy command (npx convex deploy)", () => {
2034
- it("defaults to prod with CONVEX_DEPLOYMENT (implicitProd)", async () => {
2035
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
2036
- vi.mocked(readGlobalConfig).mockReturnValue({
2037
- accessToken: "test-token",
2038
- });
2039
-
2040
- setupBigBrainRoutes({
2041
- "deployment/joyful-capybara-123/team_and_project": () => ({
2042
- team: "my-team",
2043
- project: "my-project",
2044
- teamId: 1,
2045
- projectId: 1,
2046
- }),
2047
- "deployment/authorize_prod": () => ({
2048
- adminKey: "prod-key",
2049
- url: "https://graceful-puffin-456.convex.cloud",
2050
- deploymentName: "graceful-puffin-456",
2051
- deploymentType: "prod",
2052
- }),
2053
- });
2054
-
2055
- await deploy.parseAsync(["--yes"], { from: "user" });
2056
-
2057
- expect(bigBrainAPI).toHaveBeenCalledWith(
2058
- expect.objectContaining({
2059
- path: "deployment/authorize_prod",
2060
- }),
2061
- );
2062
-
2063
- expect(deployToDeployment).toHaveBeenCalledWith(
2064
- expect.anything(),
2065
- expect.objectContaining({
2066
- url: "https://graceful-puffin-456.convex.cloud",
2067
- adminKey: "prod-key",
2068
- }),
2069
- expect.anything(),
2070
- );
2071
- });
2072
-
2073
- it("defaults to prod with project deploy key", async () => {
2074
- process.env.CONVEX_DEPLOY_KEY = "project:identifier|secretkey";
2075
-
2076
- setupBigBrainRoutes({
2077
- "deployment/provision_and_authorize": () => ({
2078
- adminKey: "prod-admin-key",
2079
- url: "https://graceful-puffin-456.convex.cloud",
2080
- deploymentName: "graceful-puffin-456",
2081
- }),
2082
- });
2083
-
2084
- await deploy.parseAsync([], { from: "user" });
2085
-
2086
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
2087
- expect.objectContaining({
2088
- path: "deployment/provision_and_authorize",
2089
- data: expect.objectContaining({
2090
- deploymentType: "prod",
2091
- }),
2092
- }),
2093
- );
2094
-
2095
- expect(deployToDeployment).toHaveBeenCalledWith(
2096
- expect.anything(),
2097
- expect.objectContaining({
2098
- url: "https://graceful-puffin-456.convex.cloud",
2099
- adminKey: "prod-admin-key",
2100
- }),
2101
- expect.anything(),
2102
- );
2103
- });
2104
-
2105
- it("deploys to preview with preview deploy key and --preview-create", async () => {
2106
- process.env.CONVEX_DEPLOY_KEY = "preview:my-team:my-project|secretkey";
2107
-
2108
- setupBigBrainRoutes({
2109
- claim_preview_deployment: () => ({
2110
- adminKey: "preview-admin-key",
2111
- instanceUrl: "https://nimble-penguin-234.convex.cloud",
2112
- }),
2113
- });
2114
-
2115
- await deploy.parseAsync(["--preview-create", "my-preview"], {
2116
- from: "user",
2117
- });
2118
-
2119
- expect(bigBrainAPI).toHaveBeenCalledWith(
2120
- expect.objectContaining({
2121
- path: "claim_preview_deployment",
2122
- data: expect.objectContaining({
2123
- identifier: "my-preview",
2124
- reuse: false,
2125
- projectSelection: {
2126
- kind: "teamAndProjectSlugs",
2127
- teamSlug: "my-team",
2128
- projectSlug: "my-project",
2129
- },
2130
- }),
2131
- }),
2132
- );
2133
-
2134
- expect(runPush).toHaveBeenCalledWith(
2135
- expect.anything(),
2136
- expect.objectContaining({
2137
- url: "https://nimble-penguin-234.convex.cloud",
2138
- adminKey: "preview-admin-key",
2139
- }),
2140
- );
2141
- });
2142
-
2143
- it("deploys to preview with preview deploy key using git branch fallback", async () => {
2144
- process.env.CONVEX_DEPLOY_KEY = "preview:my-team:my-project|secretkey";
2145
- vi.mocked(gitBranchFromEnvironment).mockReturnValue("feature/my-branch");
2146
-
2147
- setupBigBrainRoutes({
2148
- claim_preview_deployment: () => ({
2149
- adminKey: "preview-admin-key",
2150
- instanceUrl: "https://nimble-penguin-234.convex.cloud",
2151
- }),
2152
- });
2153
-
2154
- await deploy.parseAsync([], { from: "user" });
2155
-
2156
- expect(bigBrainAPI).toHaveBeenCalledWith(
2157
- expect.objectContaining({
2158
- path: "claim_preview_deployment",
2159
- data: expect.objectContaining({
2160
- identifier: "feature/my-branch",
2161
- reuse: true,
2162
- }),
2163
- }),
2164
- );
2165
-
2166
- expect(runPush).toHaveBeenCalled();
2167
- });
2168
-
2169
- it("suggests --preview-name when preview name cannot be determined", async () => {
2170
- process.env.CONVEX_DEPLOY_KEY = "preview:my-team:my-project|secretkey";
2171
-
2172
- await expect(deploy.parseAsync([], { from: "user" })).rejects.toThrow();
2173
-
2174
- expect(process.stderr.write).toHaveBeenCalledWith(
2175
- expect.stringContaining("Provide one using `--preview-name`"),
2176
- );
2177
- expect(bigBrainAPI).not.toHaveBeenCalled();
2178
- expect(runPush).not.toHaveBeenCalled();
2179
- });
2180
-
2181
- it("deploys to existing preview with CONVEX_DEPLOYMENT and --preview-name", async () => {
2182
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
2183
- vi.mocked(readGlobalConfig).mockReturnValue({
2184
- accessToken: "test-token",
2185
- });
2186
-
2187
- setupBigBrainRoutes({
2188
- "deployment/joyful-capybara-123/team_and_project": () => ({
2189
- team: "my-team",
2190
- project: "my-project",
2191
- teamId: 1,
2192
- projectId: 1,
2193
- }),
2194
- "deployment/authorize_preview": () => ({
2195
- adminKey: "preview-key",
2196
- url: "https://nimble-penguin-234.convex.cloud",
2197
- deploymentName: "nimble-penguin-234",
2198
- deploymentType: "preview",
2199
- }),
2200
- });
2201
-
2202
- await deploy.parseAsync(["--preview-name", "my-preview", "--yes"], {
2203
- from: "user",
2204
- });
2205
-
2206
- expect(bigBrainAPI).toHaveBeenCalledWith(
2207
- expect.objectContaining({
2208
- path: "deployment/authorize_preview",
2209
- }),
2210
- );
2211
-
2212
- expect(deployToDeployment).toHaveBeenCalledWith(
2213
- expect.anything(),
2214
- expect.objectContaining({
2215
- url: "https://nimble-penguin-234.convex.cloud",
2216
- adminKey: "preview-key",
2217
- }),
2218
- expect.anything(),
2219
- );
2220
- });
2221
-
2222
- it("reuses preview deployment with preview deploy key and --preview-name", async () => {
2223
- process.env.CONVEX_DEPLOY_KEY = "preview:my-team:my-project|secretkey";
2224
-
2225
- setupBigBrainRoutes({
2226
- claim_preview_deployment: () => ({
2227
- adminKey: "preview-admin-key",
2228
- instanceUrl: "https://nimble-penguin-234.convex.cloud",
2229
- }),
2230
- });
2231
-
2232
- await deploy.parseAsync(["--preview-name", "my-preview"], {
2233
- from: "user",
2234
- });
2235
-
2236
- expect(bigBrainAPI).toHaveBeenCalledWith(
2237
- expect.objectContaining({
2238
- path: "claim_preview_deployment",
2239
- data: expect.objectContaining({
2240
- identifier: "my-preview",
2241
- reuse: true,
2242
- projectSelection: {
2243
- kind: "teamAndProjectSlugs",
2244
- teamSlug: "my-team",
2245
- projectSlug: "my-project",
2246
- },
2247
- }),
2248
- }),
2249
- );
2250
-
2251
- expect(runPush).toHaveBeenCalledWith(
2252
- expect.anything(),
2253
- expect.objectContaining({
2254
- url: "https://nimble-penguin-234.convex.cloud",
2255
- adminKey: "preview-admin-key",
2256
- }),
2257
- );
2258
- });
2259
- });
2260
-
2261
- describe("dev command (npx convex dev)", () => {
2262
- test("dev --local is deprecated and points users to `deployment select local`", async () => {
2263
- await expect(
2264
- dev.parseAsync(["--local"], { from: "user" }),
2265
- ).rejects.toThrow();
2266
-
2267
- expect(process.stderr.write).toHaveBeenCalledWith(
2268
- expect.stringContaining("`--local` is deprecated"),
2269
- );
2270
- expect(process.stderr.write).toHaveBeenCalledWith(
2271
- expect.stringContaining("npx convex deployment select local"),
2272
- );
2273
- expect(devAgainstDeployment).not.toHaveBeenCalled();
2274
- });
2275
-
2276
- it("dev with CONVEX_DEPLOYMENT=local:... uses fresh credentials from handleLocalDeployment", async () => {
2277
- process.env.CONVEX_DEPLOYMENT = "local:my-local-deployment";
2278
- vi.mocked(readGlobalConfig).mockReturnValue({
2279
- accessToken: "test-token",
2280
- });
2281
-
2282
- // loadLocalDeploymentCredentials returns stale saved config (e.g. from a
2283
- // previous run on a different port).
2284
- vi.mocked(loadLocalDeploymentCredentials).mockResolvedValue({
2285
- deploymentName: "my-local-deployment",
2286
- deploymentUrl: "http://127.0.0.1:3212",
2287
- adminKey: "stale|admin|key",
2288
- });
2289
-
2290
- // handleLocalDeployment starts a new backend, potentially on different
2291
- // ports, and returns the actual credentials.
2292
- vi.mocked(handleLocalDeployment).mockResolvedValue({
2293
- deploymentName: "my-local-deployment",
2294
- deploymentUrl: "http://127.0.0.1:3210",
2295
- adminKey: "fresh|admin|key",
2296
- } as any);
2297
-
2298
- setupBigBrainRoutes({
2299
- "deployment/my-local-deployment/team_and_project": () => ({
2300
- team: "my-team",
2301
- project: "my-project",
2302
- teamId: 1,
2303
- projectId: 1,
2304
- }),
2305
- });
2306
-
2307
- await dev.parseAsync([], { from: "user" });
2308
-
2309
- expect(handleLocalDeployment).toHaveBeenCalledWith(
2310
- expect.anything(),
2311
- expect.objectContaining({
2312
- teamSlug: "my-team",
2313
- projectSlug: "my-project",
2314
- }),
2315
- );
2316
- // Must use the fresh credentials from handleLocalDeployment, not the
2317
- // stale ones from loadLocalDeploymentCredentials.
2318
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2319
- expect.anything(),
2320
- expect.objectContaining({
2321
- url: "http://127.0.0.1:3210",
2322
- adminKey: "fresh|admin|key",
2323
- }),
2324
- expect.anything(),
2325
- );
2326
- });
2327
-
2328
- it("resolves CONVEX_DEPLOYMENT to the configured deployment", async () => {
2329
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
2330
- vi.mocked(readGlobalConfig).mockReturnValue({
2331
- accessToken: "test-token",
2332
- });
2333
-
2334
- setupBigBrainRoutes({
2335
- "deployment/joyful-capybara-123/team_and_project": () => ({
2336
- team: "my-team",
2337
- project: "my-project",
2338
- teamId: 1,
2339
- projectId: 1,
2340
- }),
2341
- "deployment/authorize_within_current_project": () => ({
2342
- adminKey: "dev-key",
2343
- url: "https://joyful-capybara-123.convex.cloud",
2344
- deploymentName: "joyful-capybara-123",
2345
- deploymentType: "dev",
2346
- }),
2347
- });
2348
-
2349
- await dev.parseAsync([], { from: "user" });
2350
-
2351
- expect(bigBrainAPI).toHaveBeenCalledWith(
2352
- expect.objectContaining({
2353
- path: "deployment/authorize_within_current_project",
2354
- data: expect.objectContaining({
2355
- selectedDeploymentName: "joyful-capybara-123",
2356
- }),
2357
- }),
2358
- );
2359
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2360
- expect.anything(),
2361
- expect.objectContaining({
2362
- url: "https://joyful-capybara-123.convex.cloud",
2363
- adminKey: "dev-key",
2364
- }),
2365
- expect.anything(),
2366
- );
2367
- });
2368
-
2369
- it("defaults to dev deployment with project deploy key", async () => {
2370
- process.env.CONVEX_DEPLOY_KEY = "project:identifier|secretkey";
2371
-
2372
- setupBigBrainRoutes({
2373
- "deployment/provision_and_authorize": () => ({
2374
- adminKey: "dev-key",
2375
- url: "https://swift-squirrel-234.convex.cloud",
2376
- deploymentName: "swift-squirrel-234",
2377
- deploymentType: "dev",
2378
- }),
2379
- });
2380
-
2381
- await dev.parseAsync([], { from: "user" });
2382
-
2383
- expect(bigBrainAPIMaybeThrows).toHaveBeenCalledWith(
2384
- expect.objectContaining({
2385
- path: "deployment/provision_and_authorize",
2386
- data: expect.objectContaining({ deploymentType: "dev" }),
2387
- }),
2388
- );
2389
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2390
- expect.anything(),
2391
- expect.objectContaining({
2392
- url: "https://swift-squirrel-234.convex.cloud",
2393
- adminKey: "dev-key",
2394
- }),
2395
- expect.anything(),
2396
- );
2397
- });
2398
-
2399
- it("uses CONVEX_SELF_HOSTED_URL and CONVEX_SELF_HOSTED_ADMIN_KEY directly", async () => {
2400
- process.env.CONVEX_SELF_HOSTED_URL = "http://localhost:3210";
2401
- process.env.CONVEX_SELF_HOSTED_ADMIN_KEY = "self-hosted-key";
2402
-
2403
- await dev.parseAsync([], { from: "user" });
2404
-
2405
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2406
- expect.anything(),
2407
- expect.objectContaining({
2408
- url: "http://localhost:3210",
2409
- adminKey: "self-hosted-key",
2410
- }),
2411
- expect.anything(),
2412
- );
2413
- expect(bigBrainAPI).not.toHaveBeenCalled();
2414
- expect(bigBrainAPIMaybeThrows).not.toHaveBeenCalled();
2415
- });
2416
-
2417
- test("dev --cloud is deprecated and points users to `deployment select dev`", async () => {
2418
- await expect(
2419
- dev.parseAsync(["--cloud"], { from: "user" }),
2420
- ).rejects.toThrow();
2421
-
2422
- expect(process.stderr.write).toHaveBeenCalledWith(
2423
- expect.stringContaining("`--cloud` is deprecated"),
2424
- );
2425
- expect(process.stderr.write).toHaveBeenCalledWith(
2426
- expect.stringContaining("npx convex deployment select dev"),
2427
- );
2428
- expect(devAgainstDeployment).not.toHaveBeenCalled();
2429
- });
2430
-
2431
- describe("non-interactive terminal", () => {
2432
- beforeEach(() => {
2433
- process.stdin.isTTY = false as any;
2434
- });
2435
-
2436
- it("non-interactive, not logged in, no config → uses anonymous deployment", async () => {
2437
- await dev.parseAsync(["--once"], { from: "user" });
2438
-
2439
- expect(handleAnonymousDeployment).toHaveBeenCalled();
2440
- expect(bigBrainAPI).not.toHaveBeenCalled();
2441
- expect(bigBrainAPIMaybeThrows).not.toHaveBeenCalled();
2442
- expect(validateOrSelectTeam).not.toHaveBeenCalled();
2443
- expect(validateOrSelectProject).not.toHaveBeenCalled();
2444
- });
2445
-
2446
- it("non-interactive, logged in, no CONVEX_DEPLOYMENT → uses anonymous deployment", async () => {
2447
- vi.mocked(readGlobalConfig).mockReturnValue({
2448
- accessToken: "test-token",
2449
- });
2450
-
2451
- await dev.parseAsync(["--once"], { from: "user" });
2452
-
2453
- expect(handleAnonymousDeployment).toHaveBeenCalled();
2454
- expect(validateOrSelectTeam).not.toHaveBeenCalled();
2455
- expect(validateOrSelectProject).not.toHaveBeenCalled();
2456
- });
2457
-
2458
- it("non-interactive with CONVEX_DEPLOYMENT → resolves to the configured deployment", async () => {
2459
- process.env.CONVEX_DEPLOYMENT = "dev:joyful-capybara-123";
2460
- vi.mocked(readGlobalConfig).mockReturnValue({
2461
- accessToken: "test-token",
2462
- });
2463
-
2464
- setupBigBrainRoutes({
2465
- "deployment/joyful-capybara-123/team_and_project": () => ({
2466
- team: "my-team",
2467
- project: "my-project",
2468
- teamId: 1,
2469
- projectId: 1,
2470
- }),
2471
- "deployment/authorize_within_current_project": () => ({
2472
- adminKey: "dev-key",
2473
- url: "https://joyful-capybara-123.convex.cloud",
2474
- deploymentName: "joyful-capybara-123",
2475
- deploymentType: "dev",
2476
- }),
2477
- });
2478
-
2479
- await dev.parseAsync([], { from: "user" });
2480
-
2481
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2482
- expect.anything(),
2483
- expect.objectContaining({
2484
- url: "https://joyful-capybara-123.convex.cloud",
2485
- adminKey: "dev-key",
2486
- }),
2487
- expect.anything(),
2488
- );
2489
- expect(handleAnonymousDeployment).not.toHaveBeenCalled();
2490
- });
2491
-
2492
- it("non-interactive with CONVEX_DEPLOY_KEY → uses deploy key", async () => {
2493
- process.env.CONVEX_DEPLOY_KEY = "project:identifier|secretkey";
2494
-
2495
- setupBigBrainRoutes({
2496
- "deployment/provision_and_authorize": () => ({
2497
- adminKey: "dev-key",
2498
- url: "https://swift-squirrel-234.convex.cloud",
2499
- deploymentName: "swift-squirrel-234",
2500
- deploymentType: "dev",
2501
- }),
2502
- });
2503
-
2504
- await dev.parseAsync([], { from: "user" });
2505
-
2506
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2507
- expect.anything(),
2508
- expect.objectContaining({
2509
- url: "https://swift-squirrel-234.convex.cloud",
2510
- adminKey: "dev-key",
2511
- }),
2512
- expect.anything(),
2513
- );
2514
- expect(handleAnonymousDeployment).not.toHaveBeenCalled();
2515
- });
2516
-
2517
- it("non-interactive with CONVEX_SELF_HOSTED_URL → uses self-hosted", async () => {
2518
- process.env.CONVEX_SELF_HOSTED_URL = "http://localhost:3210";
2519
- process.env.CONVEX_SELF_HOSTED_ADMIN_KEY = "self-hosted-key";
2520
-
2521
- await dev.parseAsync([], { from: "user" });
2522
-
2523
- expect(devAgainstDeployment).toHaveBeenCalledWith(
2524
- expect.anything(),
2525
- expect.objectContaining({
2526
- url: "http://localhost:3210",
2527
- adminKey: "self-hosted-key",
2528
- }),
2529
- expect.anything(),
2530
- );
2531
- expect(handleAnonymousDeployment).not.toHaveBeenCalled();
2532
- });
2533
- });
2534
- });
2535
-
2536
- it("dev --deployment crashes with helpful message pointing to deployment select", async () => {
2537
- await expect(
2538
- dev.parseAsync(["--deployment", "happy-animal-123"], { from: "user" }),
2539
- ).rejects.toThrow();
2540
-
2541
- expect(process.stderr.write).toHaveBeenCalledWith(
2542
- expect.stringContaining("npx convex deployment select happy-animal-123"),
2543
- );
2544
- expect(devAgainstDeployment).not.toHaveBeenCalled();
2545
- });
2546
- });