convex 1.34.1 → 1.35.1

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 (453) hide show
  1. package/CHANGELOG.md +86 -43
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/aiFiles.js +31 -13
  5. package/dist/cjs/cli/aiFiles.js.map +3 -3
  6. package/dist/cjs/cli/configure.js +21 -24
  7. package/dist/cjs/cli/configure.js.map +2 -2
  8. package/dist/cjs/cli/deploy.js +8 -9
  9. package/dist/cjs/cli/deploy.js.map +2 -2
  10. package/dist/cjs/cli/deploymentCreate.js +225 -40
  11. package/dist/cjs/cli/deploymentCreate.js.map +3 -3
  12. package/dist/cjs/cli/deploymentSelect.js +14 -13
  13. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  14. package/dist/cjs/cli/dev.js +30 -11
  15. package/dist/cjs/cli/dev.js.map +2 -2
  16. package/dist/cjs/cli/docs.js +1 -1
  17. package/dist/cjs/cli/docs.js.map +2 -2
  18. package/dist/cjs/cli/init.js +1 -1
  19. package/dist/cjs/cli/init.js.map +2 -2
  20. package/dist/cjs/cli/lib/aiFiles/agentsmd.js +14 -10
  21. package/dist/cjs/cli/lib/aiFiles/agentsmd.js.map +2 -2
  22. package/dist/cjs/cli/lib/aiFiles/claudemd.js +14 -10
  23. package/dist/cjs/cli/lib/aiFiles/claudemd.js.map +2 -2
  24. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +10 -3
  25. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  26. package/dist/cjs/cli/lib/aiFiles/index.js +70 -86
  27. package/dist/cjs/cli/lib/aiFiles/index.js.map +3 -3
  28. package/dist/cjs/cli/lib/aiFiles/skills.js +28 -12
  29. package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
  30. package/dist/cjs/cli/lib/aiFiles/state.js +96 -0
  31. package/dist/cjs/cli/lib/aiFiles/state.js.map +7 -0
  32. package/dist/cjs/cli/lib/aiFiles/status.js +31 -28
  33. package/dist/cjs/cli/lib/aiFiles/status.js.map +2 -2
  34. package/dist/cjs/cli/lib/aiFiles/utils.js +31 -14
  35. package/dist/cjs/cli/lib/aiFiles/utils.js.map +2 -2
  36. package/dist/cjs/cli/lib/api.js +70 -7
  37. package/dist/cjs/cli/lib/api.js.map +2 -2
  38. package/dist/cjs/cli/lib/command.js +4 -5
  39. package/dist/cjs/cli/lib/command.js.map +2 -2
  40. package/dist/cjs/cli/lib/config.js +41 -4
  41. package/dist/cjs/cli/lib/config.js.map +3 -3
  42. package/dist/cjs/cli/lib/deploy2.js +9 -26
  43. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  44. package/dist/cjs/cli/lib/deployApi/componentDefinition.js +4 -1
  45. package/dist/cjs/cli/lib/deployApi/componentDefinition.js.map +2 -2
  46. package/dist/cjs/cli/lib/deploymentSelection.js +45 -2
  47. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  48. package/dist/cjs/cli/lib/deploymentSelector.js +1 -0
  49. package/dist/cjs/cli/lib/deploymentSelector.js.map +2 -2
  50. package/dist/cjs/cli/lib/dev.js +162 -117
  51. package/dist/cjs/cli/lib/dev.js.map +2 -2
  52. package/dist/cjs/cli/lib/env.js +1 -13
  53. package/dist/cjs/cli/lib/env.js.map +2 -2
  54. package/dist/cjs/cli/lib/envvars.js +8 -1
  55. package/dist/cjs/cli/lib/envvars.js.map +2 -2
  56. package/dist/cjs/cli/lib/expiration.js +104 -0
  57. package/dist/cjs/cli/lib/expiration.js.map +7 -0
  58. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  59. package/dist/cjs/cli/lib/init.js +4 -3
  60. package/dist/cjs/cli/lib/init.js.map +2 -2
  61. package/dist/cjs/cli/lib/insights.js +1 -1
  62. package/dist/cjs/cli/lib/insights.js.map +2 -2
  63. package/dist/cjs/cli/lib/localDeployment/anonymous.js +14 -7
  64. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
  65. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +8 -10
  66. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +2 -2
  67. package/dist/cjs/cli/lib/localDeployment/run.js +1 -0
  68. package/dist/cjs/cli/lib/localDeployment/run.js.map +2 -2
  69. package/dist/cjs/cli/lib/localDeployment/upgrade.js +2 -2
  70. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +2 -2
  71. package/dist/cjs/cli/lib/localDeployment/utils.js +9 -0
  72. package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
  73. package/dist/cjs/cli/lib/mcp/tools/status.js +1 -1
  74. package/dist/cjs/cli/lib/mcp/tools/status.js.map +2 -2
  75. package/dist/cjs/cli/lib/updates.js +8 -9
  76. package/dist/cjs/cli/lib/updates.js.map +2 -2
  77. package/dist/cjs/cli/lib/usage.js +2 -1
  78. package/dist/cjs/cli/lib/usage.js.map +2 -2
  79. package/dist/cjs/cli/lib/utils/prompts.js +2 -1
  80. package/dist/cjs/cli/lib/utils/prompts.js.map +2 -2
  81. package/dist/cjs/cli/lib/utils/utils.js +46 -20
  82. package/dist/cjs/cli/lib/utils/utils.js.map +3 -3
  83. package/dist/cjs/index.js +1 -1
  84. package/dist/cjs/index.js.map +1 -1
  85. package/dist/cjs/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  86. package/dist/cjs/server/components/definition.js.map +1 -1
  87. package/dist/cjs/server/components/index.js +40 -4
  88. package/dist/cjs/server/components/index.js.map +2 -2
  89. package/dist/cjs/server/data_model.js.map +1 -1
  90. package/dist/cjs/server/impl/meta_impl.js +78 -0
  91. package/dist/cjs/server/impl/meta_impl.js.map +7 -0
  92. package/dist/cjs/server/impl/registration_impl.js +16 -11
  93. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  94. package/dist/cjs/server/index.js.map +2 -2
  95. package/dist/cjs/server/meta.js +17 -0
  96. package/dist/cjs/server/meta.js.map +7 -0
  97. package/dist/cjs/server/registration.js.map +1 -1
  98. package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
  99. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/configure.test.d.ts +2 -0
  101. package/dist/cjs-types/cli/configure.test.d.ts.map +1 -0
  102. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  103. package/dist/cjs-types/cli/deploymentCreate.d.ts +1 -0
  104. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  105. package/dist/cjs-types/cli/deploymentSelect.d.ts +2 -1
  106. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  107. package/dist/cjs-types/cli/dev.d.ts +3 -1
  108. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  109. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts +5 -5
  110. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -1
  111. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts +5 -5
  112. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -1
  113. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -3
  114. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  115. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +20 -18
  116. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  117. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +6 -4
  118. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  119. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts +38 -0
  120. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  121. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  122. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  123. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts +4 -1
  124. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts.map +1 -1
  125. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts +13 -3
  126. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts.map +1 -1
  127. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  128. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  129. package/dist/cjs-types/cli/lib/api.d.ts +3 -3
  130. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  131. package/dist/cjs-types/cli/lib/command.d.ts +2 -1
  132. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  133. package/dist/cjs-types/cli/lib/config.d.ts +17 -6
  134. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  135. package/dist/cjs-types/cli/lib/deploy2.d.ts +5 -2
  136. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  137. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  138. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  139. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +12 -12
  140. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +25 -16
  141. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  142. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  143. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts +2 -0
  144. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  145. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  146. package/dist/cjs-types/cli/lib/env.d.ts +0 -4
  147. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  148. package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
  149. package/dist/cjs-types/cli/lib/expiration.d.ts +35 -0
  150. package/dist/cjs-types/cli/lib/expiration.d.ts.map +1 -0
  151. package/dist/cjs-types/cli/lib/expiration.test.d.ts +2 -0
  152. package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +1 -0
  153. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  154. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  155. package/dist/cjs-types/cli/lib/init.d.ts.map +1 -1
  156. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  157. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  158. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts +15 -0
  159. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  160. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  161. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +7 -0
  162. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  163. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts +3 -3
  164. package/dist/cjs-types/cli/lib/updates.d.ts +4 -3
  165. package/dist/cjs-types/cli/lib/updates.d.ts.map +1 -1
  166. package/dist/cjs-types/cli/lib/usage.d.ts.map +1 -1
  167. package/dist/cjs-types/cli/lib/utils/prompts.d.ts +1 -0
  168. package/dist/cjs-types/cli/lib/utils/prompts.d.ts.map +1 -1
  169. package/dist/cjs-types/cli/lib/utils/utils.d.ts +16 -2
  170. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  171. package/dist/cjs-types/index.d.ts +1 -1
  172. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  173. package/dist/cjs-types/server/components/definition.d.ts +1 -0
  174. package/dist/cjs-types/server/components/definition.d.ts.map +1 -1
  175. package/dist/cjs-types/server/components/index.d.ts +5 -1
  176. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  177. package/dist/cjs-types/server/data_model.d.ts +2 -1
  178. package/dist/cjs-types/server/data_model.d.ts.map +1 -1
  179. package/dist/cjs-types/server/impl/meta_impl.d.ts +5 -0
  180. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -0
  181. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  182. package/dist/cjs-types/server/index.d.ts +1 -0
  183. package/dist/cjs-types/server/index.d.ts.map +1 -1
  184. package/dist/cjs-types/server/meta.d.ts +72 -0
  185. package/dist/cjs-types/server/meta.d.ts.map +1 -0
  186. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  187. package/dist/cli.bundle.cjs +1665 -1215
  188. package/dist/cli.bundle.cjs.map +4 -4
  189. package/dist/esm/cli/aiFiles.js +33 -15
  190. package/dist/esm/cli/aiFiles.js.map +2 -2
  191. package/dist/esm/cli/configure.js +23 -26
  192. package/dist/esm/cli/configure.js.map +2 -2
  193. package/dist/esm/cli/deploy.js +12 -11
  194. package/dist/esm/cli/deploy.js.map +2 -2
  195. package/dist/esm/cli/deploymentCreate.js +238 -42
  196. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  197. package/dist/esm/cli/deploymentSelect.js +13 -12
  198. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  199. package/dist/esm/cli/dev.js +34 -13
  200. package/dist/esm/cli/dev.js.map +2 -2
  201. package/dist/esm/cli/docs.js +1 -1
  202. package/dist/esm/cli/docs.js.map +2 -2
  203. package/dist/esm/cli/init.js +2 -2
  204. package/dist/esm/cli/init.js.map +2 -2
  205. package/dist/esm/cli/lib/aiFiles/agentsmd.js +13 -9
  206. package/dist/esm/cli/lib/aiFiles/agentsmd.js.map +2 -2
  207. package/dist/esm/cli/lib/aiFiles/claudemd.js +13 -9
  208. package/dist/esm/cli/lib/aiFiles/claudemd.js.map +2 -2
  209. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +12 -5
  210. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  211. package/dist/esm/cli/lib/aiFiles/index.js +72 -89
  212. package/dist/esm/cli/lib/aiFiles/index.js.map +2 -2
  213. package/dist/esm/cli/lib/aiFiles/skills.js +29 -13
  214. package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
  215. package/dist/esm/cli/lib/aiFiles/state.js +60 -0
  216. package/dist/esm/cli/lib/aiFiles/state.js.map +7 -0
  217. package/dist/esm/cli/lib/aiFiles/status.js +32 -29
  218. package/dist/esm/cli/lib/aiFiles/status.js.map +2 -2
  219. package/dist/esm/cli/lib/aiFiles/utils.js +25 -10
  220. package/dist/esm/cli/lib/aiFiles/utils.js.map +2 -2
  221. package/dist/esm/cli/lib/api.js +70 -7
  222. package/dist/esm/cli/lib/api.js.map +2 -2
  223. package/dist/esm/cli/lib/command.js +4 -5
  224. package/dist/esm/cli/lib/command.js.map +2 -2
  225. package/dist/esm/cli/lib/config.js +39 -3
  226. package/dist/esm/cli/lib/config.js.map +2 -2
  227. package/dist/esm/cli/lib/deploy2.js +13 -26
  228. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  229. package/dist/esm/cli/lib/deployApi/componentDefinition.js +4 -1
  230. package/dist/esm/cli/lib/deployApi/componentDefinition.js.map +2 -2
  231. package/dist/esm/cli/lib/deploymentSelection.js +46 -2
  232. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  233. package/dist/esm/cli/lib/deploymentSelector.js +1 -0
  234. package/dist/esm/cli/lib/deploymentSelector.js.map +2 -2
  235. package/dist/esm/cli/lib/dev.js +162 -118
  236. package/dist/esm/cli/lib/dev.js.map +2 -2
  237. package/dist/esm/cli/lib/env.js +0 -11
  238. package/dist/esm/cli/lib/env.js.map +2 -2
  239. package/dist/esm/cli/lib/envvars.js +8 -1
  240. package/dist/esm/cli/lib/envvars.js.map +2 -2
  241. package/dist/esm/cli/lib/expiration.js +80 -0
  242. package/dist/esm/cli/lib/expiration.js.map +7 -0
  243. package/dist/esm/cli/lib/init.js +4 -3
  244. package/dist/esm/cli/lib/init.js.map +2 -2
  245. package/dist/esm/cli/lib/insights.js +1 -1
  246. package/dist/esm/cli/lib/insights.js.map +2 -2
  247. package/dist/esm/cli/lib/localDeployment/anonymous.js +16 -9
  248. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
  249. package/dist/esm/cli/lib/localDeployment/localDeployment.js +9 -11
  250. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +2 -2
  251. package/dist/esm/cli/lib/localDeployment/run.js +1 -1
  252. package/dist/esm/cli/lib/localDeployment/run.js.map +2 -2
  253. package/dist/esm/cli/lib/localDeployment/upgrade.js +2 -2
  254. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  255. package/dist/esm/cli/lib/localDeployment/utils.js +8 -0
  256. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  257. package/dist/esm/cli/lib/mcp/tools/status.js +1 -1
  258. package/dist/esm/cli/lib/mcp/tools/status.js.map +2 -2
  259. package/dist/esm/cli/lib/updates.js +11 -9
  260. package/dist/esm/cli/lib/updates.js.map +2 -2
  261. package/dist/esm/cli/lib/usage.js +2 -1
  262. package/dist/esm/cli/lib/usage.js.map +2 -2
  263. package/dist/esm/cli/lib/utils/prompts.js +2 -1
  264. package/dist/esm/cli/lib/utils/prompts.js.map +2 -2
  265. package/dist/esm/cli/lib/utils/utils.js +45 -20
  266. package/dist/esm/cli/lib/utils/utils.js.map +3 -3
  267. package/dist/esm/index.js +1 -1
  268. package/dist/esm/index.js.map +1 -1
  269. package/dist/esm/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  270. package/dist/esm/server/components/index.js +40 -4
  271. package/dist/esm/server/components/index.js.map +2 -2
  272. package/dist/esm/server/impl/meta_impl.js +54 -0
  273. package/dist/esm/server/impl/meta_impl.js.map +7 -0
  274. package/dist/esm/server/impl/registration_impl.js +20 -11
  275. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  276. package/dist/esm/server/index.js.map +2 -2
  277. package/dist/esm/server/meta.js +2 -0
  278. package/dist/esm/server/meta.js.map +7 -0
  279. package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
  280. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  281. package/dist/esm-types/cli/configure.test.d.ts +2 -0
  282. package/dist/esm-types/cli/configure.test.d.ts.map +1 -0
  283. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  284. package/dist/esm-types/cli/deploymentCreate.d.ts +1 -0
  285. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  286. package/dist/esm-types/cli/deploymentSelect.d.ts +2 -1
  287. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  288. package/dist/esm-types/cli/dev.d.ts +3 -1
  289. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  290. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts +5 -5
  291. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -1
  292. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts +5 -5
  293. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -1
  294. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -3
  295. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  296. package/dist/esm-types/cli/lib/aiFiles/index.d.ts +20 -18
  297. package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  298. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +6 -4
  299. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  300. package/dist/esm-types/cli/lib/aiFiles/state.d.ts +38 -0
  301. package/dist/esm-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  302. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  303. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  304. package/dist/esm-types/cli/lib/aiFiles/status.d.ts +4 -1
  305. package/dist/esm-types/cli/lib/aiFiles/status.d.ts.map +1 -1
  306. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts +13 -3
  307. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts.map +1 -1
  308. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  309. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  310. package/dist/esm-types/cli/lib/api.d.ts +3 -3
  311. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  312. package/dist/esm-types/cli/lib/command.d.ts +2 -1
  313. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  314. package/dist/esm-types/cli/lib/config.d.ts +17 -6
  315. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  316. package/dist/esm-types/cli/lib/deploy2.d.ts +5 -2
  317. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  318. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  319. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  320. package/dist/esm-types/cli/lib/deployApi/modules.d.ts +12 -12
  321. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +25 -16
  322. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  323. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  324. package/dist/esm-types/cli/lib/deploymentSelector.d.ts +2 -0
  325. package/dist/esm-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  326. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  327. package/dist/esm-types/cli/lib/env.d.ts +0 -4
  328. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  329. package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
  330. package/dist/esm-types/cli/lib/expiration.d.ts +35 -0
  331. package/dist/esm-types/cli/lib/expiration.d.ts.map +1 -0
  332. package/dist/esm-types/cli/lib/expiration.test.d.ts +2 -0
  333. package/dist/esm-types/cli/lib/expiration.test.d.ts.map +1 -0
  334. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  335. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  336. package/dist/esm-types/cli/lib/init.d.ts.map +1 -1
  337. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  338. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  339. package/dist/esm-types/cli/lib/localDeployment/run.d.ts +15 -0
  340. package/dist/esm-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  341. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  342. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +7 -0
  343. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  344. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts +3 -3
  345. package/dist/esm-types/cli/lib/updates.d.ts +4 -3
  346. package/dist/esm-types/cli/lib/updates.d.ts.map +1 -1
  347. package/dist/esm-types/cli/lib/usage.d.ts.map +1 -1
  348. package/dist/esm-types/cli/lib/utils/prompts.d.ts +1 -0
  349. package/dist/esm-types/cli/lib/utils/prompts.d.ts.map +1 -1
  350. package/dist/esm-types/cli/lib/utils/utils.d.ts +16 -2
  351. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  352. package/dist/esm-types/index.d.ts +1 -1
  353. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  354. package/dist/esm-types/server/components/definition.d.ts +1 -0
  355. package/dist/esm-types/server/components/definition.d.ts.map +1 -1
  356. package/dist/esm-types/server/components/index.d.ts +5 -1
  357. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  358. package/dist/esm-types/server/data_model.d.ts +2 -1
  359. package/dist/esm-types/server/data_model.d.ts.map +1 -1
  360. package/dist/esm-types/server/impl/meta_impl.d.ts +5 -0
  361. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -0
  362. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  363. package/dist/esm-types/server/index.d.ts +1 -0
  364. package/dist/esm-types/server/index.d.ts.map +1 -1
  365. package/dist/esm-types/server/meta.d.ts +72 -0
  366. package/dist/esm-types/server/meta.d.ts.map +1 -0
  367. package/dist/esm-types/server/registration.d.ts.map +1 -1
  368. package/dist/react.bundle.js +1 -1
  369. package/dist/react.bundle.js.map +1 -1
  370. package/package.json +11 -7
  371. package/schemas/convex.schema.json +15 -2
  372. package/src/cli/aiFiles.ts +44 -14
  373. package/src/cli/configure.test.ts +138 -0
  374. package/src/cli/configure.ts +48 -47
  375. package/src/cli/deploy.ts +13 -10
  376. package/src/cli/deploymentCreate.test.ts +349 -14
  377. package/src/cli/deploymentCreate.ts +268 -41
  378. package/src/cli/deploymentSelect.test.ts +136 -27
  379. package/src/cli/deploymentSelect.ts +50 -41
  380. package/src/cli/deploymentSelection.test.ts +343 -35
  381. package/src/cli/dev.ts +49 -14
  382. package/src/cli/docs.ts +1 -1
  383. package/src/cli/init.ts +2 -2
  384. package/src/cli/lib/aiFiles/agentsmd.ts +15 -11
  385. package/src/cli/lib/aiFiles/claudemd.ts +15 -11
  386. package/src/cli/lib/aiFiles/guidelinesmd.test.ts +12 -2
  387. package/src/cli/lib/aiFiles/guidelinesmd.ts +15 -7
  388. package/src/cli/lib/aiFiles/index.test.ts +188 -222
  389. package/src/cli/lib/aiFiles/index.ts +119 -125
  390. package/src/cli/lib/aiFiles/integration.test.ts +112 -45
  391. package/src/cli/lib/aiFiles/prompt.test.ts +6 -6
  392. package/src/cli/lib/aiFiles/skills.ts +46 -16
  393. package/src/cli/lib/aiFiles/state.test.ts +280 -0
  394. package/src/cli/lib/aiFiles/state.ts +82 -0
  395. package/src/cli/lib/aiFiles/status.ts +45 -39
  396. package/src/cli/lib/aiFiles/utils.test.ts +50 -0
  397. package/src/cli/lib/aiFiles/utils.ts +38 -10
  398. package/src/cli/lib/api.ts +88 -7
  399. package/src/cli/lib/command.ts +12 -7
  400. package/src/cli/lib/config.test.ts +184 -7
  401. package/src/cli/lib/config.ts +67 -7
  402. package/src/cli/lib/deploy2.ts +14 -27
  403. package/src/cli/lib/deployApi/componentDefinition.ts +4 -1
  404. package/src/cli/lib/deploymentSelection.ts +59 -6
  405. package/src/cli/lib/deploymentSelector.test.ts +6 -0
  406. package/src/cli/lib/deploymentSelector.ts +2 -0
  407. package/src/cli/lib/dev.ts +202 -153
  408. package/src/cli/lib/env.ts +0 -15
  409. package/src/cli/lib/envvars.ts +16 -1
  410. package/src/cli/lib/expiration.test.ts +159 -0
  411. package/src/cli/lib/expiration.ts +124 -0
  412. package/src/cli/lib/generatedFunctionLogsApi.ts +16 -1
  413. package/src/cli/lib/init.ts +6 -2
  414. package/src/cli/lib/insights.ts +1 -1
  415. package/src/cli/lib/localDeployment/anonymous.ts +19 -9
  416. package/src/cli/lib/localDeployment/localDeployment.ts +9 -11
  417. package/src/cli/lib/localDeployment/run.ts +1 -1
  418. package/src/cli/lib/localDeployment/upgrade.ts +12 -10
  419. package/src/cli/lib/localDeployment/utils.ts +12 -0
  420. package/src/cli/lib/mcp/tools/status.ts +1 -1
  421. package/src/cli/lib/updates.test.ts +102 -75
  422. package/src/cli/lib/updates.ts +14 -12
  423. package/src/cli/lib/usage.ts +3 -1
  424. package/src/cli/lib/utils/prompts.ts +2 -0
  425. package/src/cli/lib/utils/utils.test.ts +6 -6
  426. package/src/cli/lib/utils/utils.ts +66 -27
  427. package/src/index.ts +1 -1
  428. package/src/react-clerk/ConvexProviderWithClerk.test.tsx +1 -1
  429. package/src/react-clerk/ConvexProviderWithClerk.tsx +1 -1
  430. package/src/server/components/definition.ts +3 -0
  431. package/src/server/components/index.ts +62 -5
  432. package/src/server/data_model.ts +2 -1
  433. package/src/server/impl/meta_impl.ts +74 -0
  434. package/src/server/impl/registration_impl.ts +21 -9
  435. package/src/server/index.ts +8 -0
  436. package/src/server/meta.ts +76 -0
  437. package/src/server/registration.ts +10 -0
  438. package/src/server/schema.test.ts +78 -1
  439. package/dist/cjs/cli/lib/aiFiles/config.js +0 -171
  440. package/dist/cjs/cli/lib/aiFiles/config.js.map +0 -7
  441. package/dist/cjs-types/cli/lib/aiFiles/config.d.ts +0 -46
  442. package/dist/cjs-types/cli/lib/aiFiles/config.d.ts.map +0 -1
  443. package/dist/cjs-types/cli/lib/aiFiles/config.test.d.ts +0 -2
  444. package/dist/cjs-types/cli/lib/aiFiles/config.test.d.ts.map +0 -1
  445. package/dist/esm/cli/lib/aiFiles/config.js +0 -135
  446. package/dist/esm/cli/lib/aiFiles/config.js.map +0 -7
  447. package/dist/esm-types/cli/lib/aiFiles/config.d.ts +0 -46
  448. package/dist/esm-types/cli/lib/aiFiles/config.d.ts.map +0 -1
  449. package/dist/esm-types/cli/lib/aiFiles/config.test.d.ts +0 -2
  450. package/dist/esm-types/cli/lib/aiFiles/config.test.d.ts.map +0 -1
  451. package/src/cli/lib/aiFiles/config.test.ts +0 -460
  452. package/src/cli/lib/aiFiles/config.ts +0 -188
  453. package/src/values/.claude/settings.local.json +0 -10
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/dev.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { OneoffCtx } from \"../../bundler/context.js\";\nimport {\n logError,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n showSpinnerIfSlow,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { runPush } from \"./components.js\";\nimport { performance } from \"perf_hooks\";\nimport path from \"path\";\nimport { LogManager, LogMode, watchLogs } from \"./logs.js\";\nimport { PushOptions } from \"./components.js\";\nimport {\n formatDuration,\n getCurrentTimeString,\n spawnAsync,\n waitForever,\n waitUntilCalled,\n} from \"./utils/utils.js\";\nimport { Crash, WatchContext, Watcher } from \"./watch.js\";\nimport { runFunctionAndLog, subscribe } from \"./run.js\";\nimport { Value } from \"../../values/index.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { readProjectConfig, getAuthKitConfig } from \"./config.js\";\nimport {\n syncAuthKitConfigAfterPush,\n ensureAuthKitProvisionedBeforeBuild,\n} from \"./workos/workos.js\";\n\nexport async function devAgainstDeployment(\n ctx: OneoffCtx,\n credentials: {\n url: string;\n adminKey: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n },\n devOptions: {\n verbose: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n codegen: boolean;\n once: boolean;\n untilSuccess: boolean;\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n tailLogs: LogMode;\n traceEvents: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n },\n) {\n const logManager = new LogManager(devOptions.tailLogs);\n\n // Pre-flight check: Ensure AuthKit is provisioned before starting dev\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n if (authKitConfig && credentials.deploymentName) {\n // Only provision for cloud deployments (dev/preview/prod)\n // Skip for local and anonymous deployments\n const deploymentType = credentials.deploymentType;\n if (\n deploymentType === \"dev\" ||\n deploymentType === \"preview\" ||\n deploymentType === \"prod\"\n ) {\n await ensureAuthKitProvisionedBeforeBuild(\n ctx,\n credentials.deploymentName,\n { deploymentUrl: credentials.url, adminKey: credentials.adminKey },\n deploymentType,\n );\n }\n }\n\n const promises = [];\n if (devOptions.tailLogs !== \"disable\") {\n promises.push(\n watchLogs(ctx, credentials.url, credentials.adminKey, \"stderr\", {\n logManager,\n success: false,\n }),\n );\n }\n\n promises.push(\n watchAndPush(\n ctx,\n {\n ...credentials,\n verbose: devOptions.verbose,\n dryRun: false,\n typecheck: devOptions.typecheck,\n typecheckComponents: devOptions.typecheckComponents,\n debug: false,\n debugBundlePath: devOptions.debugBundlePath,\n debugNodeApis: devOptions.debugNodeApis,\n codegen: devOptions.codegen,\n liveComponentSources: devOptions.liveComponentSources,\n pushAllModules: devOptions.pushAllModules,\n logManager, // Pass logManager to control logs during deploy\n largeIndexDeletionCheck: \"no verification\", // `convex dev` can\u2019t push to prod\n },\n devOptions,\n ),\n );\n await Promise.race(promises);\n await ctx.flushAndExit(0);\n}\n\nexport async function watchAndPush(\n outerCtx: OneoffCtx,\n options: PushOptions,\n cmdOptions: {\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n once: boolean;\n untilSuccess: boolean;\n traceEvents: boolean;\n },\n) {\n const watch: { watcher: Watcher | undefined } = { watcher: undefined };\n const authKitCache: { lastAppliedConfig: string | undefined } = {\n lastAppliedConfig: undefined,\n };\n let numFailures = 0;\n let ran = false;\n let pushed = false;\n let tableNameTriggeringRetry;\n let shouldRetryOnDeploymentEnvVarChange;\n let isFirstPush = true; // Track if this is the first push in the session\n\n while (true) {\n const start = performance.now();\n tableNameTriggeringRetry = null;\n shouldRetryOnDeploymentEnvVarChange = false;\n\n const ctx = new WatchContext(\n cmdOptions.traceEvents,\n outerCtx.bigBrainAuth(),\n isFirstPush,\n );\n options.logManager?.beginDeploy();\n showSpinner(\"Preparing Convex functions...\");\n try {\n await runPush(ctx, options);\n const end = performance.now();\n // NOTE: If `runPush` throws, `endDeploy` will not be called.\n // This allows you to see the output from the failed deploy without\n // logs getting in the way.\n options.logManager?.endDeploy();\n numFailures = 0;\n logFinishedStep(\n `${getCurrentTimeString()} Convex functions ready! (${formatDuration(\n end - start,\n )})`,\n );\n\n // Sync AuthKit configuration if it has changed\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n // Check if config has changed by comparing stringified versions\n const currentConfigString = authKitConfig\n ? JSON.stringify(authKitConfig)\n : undefined;\n\n // Skip sync on first push since ensureAuthKitProvisionedBeforeBuild already configured WorkOS\n if (\n !isFirstPush &&\n currentConfigString !== authKitCache.lastAppliedConfig\n ) {\n // Config has changed, sync it\n await syncAuthKitConfigAfterPush(ctx, projectConfig, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n });\n }\n\n // Always update cache after push (even if we skipped sync)\n authKitCache.lastAppliedConfig = currentConfigString;\n isFirstPush = false;\n if (cmdOptions.run !== undefined && !ran) {\n switch (cmdOptions.run.kind) {\n case \"function\":\n await runFunctionInDev(\n ctx,\n options,\n cmdOptions.run.name,\n cmdOptions.run.component,\n );\n break;\n case \"shell\":\n try {\n await spawnAsync(ctx, cmdOptions.run.command, [], {\n stdio: \"inherit\",\n shell: true,\n });\n } catch (e) {\n // `spawnAsync` throws an error like `{ status: 1, error: Error }`\n // when the command fails.\n const errorMessage =\n e === null || e === undefined\n ? null\n : (e as any).error instanceof Error\n ? ((e as any).error.message ?? null)\n : null;\n const printedMessage = `Failed to run command \\`${cmdOptions.run.command}\\`: ${errorMessage ?? \"Unknown error\"}`;\n // Don't return this since it'll bypass the `catch` below.\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage,\n });\n }\n break;\n default: {\n cmdOptions.run satisfies never;\n // Don't return this since it'll bypass the `catch` below.\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected arguments for --run`,\n errForSentry: `Unexpected arguments for --run: ${JSON.stringify(\n cmdOptions.run,\n )}`,\n });\n }\n }\n ran = true;\n }\n pushed = true;\n } catch (e: any) {\n // Crash the app on unexpected errors.\n if (!(e instanceof Crash) || !e.errorType) {\n // eslint-disable-next-line no-restricted-syntax\n throw e;\n }\n if (e.errorType === \"fatal\") {\n break;\n }\n // Retry after an exponential backoff if we hit a transient error.\n if (e.errorType === \"transient\" || e.errorType === \"already handled\") {\n const delay = nextBackoff(numFailures);\n numFailures += 1;\n if (e.errorType === \"transient\") {\n logWarning(\n chalkStderr.yellow(\n `Failed due to network error, retrying in ${formatDuration(\n delay,\n )}...`,\n ),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n // Fall through if we had a filesystem-based error.\n // TODO(sarah): Replace this with `logError`.\n // eslint-disable-next-line no-console\n console.assert(\n e.errorType === \"invalid filesystem data\" ||\n e.errorType === \"invalid filesystem or env vars\" ||\n e.errorType[\"invalid filesystem or db data\"] !== undefined,\n );\n if (e.errorType === \"invalid filesystem or env vars\") {\n shouldRetryOnDeploymentEnvVarChange = true;\n } else if (\n e.errorType !== \"invalid filesystem data\" &&\n e.errorType[\"invalid filesystem or db data\"] !== undefined\n ) {\n tableNameTriggeringRetry = e.errorType[\"invalid filesystem or db data\"];\n }\n if (cmdOptions.once) {\n await outerCtx.flushAndExit(1, e.errorType);\n }\n // Make sure that we don't spin if this push failed\n // in any edge cases that didn't call `logFailure`\n // before throwing.\n stopSpinner();\n }\n if (cmdOptions.once) {\n return;\n }\n if (pushed && cmdOptions.untilSuccess) {\n return;\n }\n const fileSystemWatch = getFileSystemWatch(ctx, watch, cmdOptions);\n const tableWatch = getTableWatch(\n ctx,\n options,\n tableNameTriggeringRetry?.tableName ?? null,\n tableNameTriggeringRetry?.componentPath,\n );\n const envVarWatch = getDeplymentEnvVarWatch(\n ctx,\n options,\n shouldRetryOnDeploymentEnvVarChange,\n );\n await Promise.race([\n fileSystemWatch.watch(),\n tableWatch.watch(),\n envVarWatch.watch(),\n ]);\n fileSystemWatch.stop();\n void tableWatch.stop();\n void envVarWatch.stop();\n }\n}\n\nasync function runFunctionInDev(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n functionName: string,\n componentPath: string | undefined,\n) {\n await runFunctionAndLog(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n functionName,\n argsString: \"{}\",\n componentPath,\n callbacks: {\n onSuccess: () => {\n logFinishedStep(`Finished running function \"${functionName}\"`);\n },\n },\n });\n}\n\nfunction getTableWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n tableName: string | null,\n componentPath: string | undefined,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryTable\",\n getArgs: () => (tableName !== null ? { tableName } : null),\n componentPath,\n });\n}\n\nfunction getDeplymentEnvVarWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n shouldRetryOnDeploymentEnvVarChange: boolean,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryEnvironmentVariables\",\n getArgs: () => (shouldRetryOnDeploymentEnvVarChange ? {} : null),\n componentPath: undefined,\n });\n}\n\nfunction getFunctionWatch(\n ctx: WatchContext,\n args: {\n deploymentUrl: string;\n adminKey: string;\n parsedFunctionName: string;\n getArgs: () => Record<string, Value> | null;\n componentPath: string | undefined;\n },\n) {\n const [stopPromise, stop] = waitUntilCalled();\n return {\n watch: async () => {\n const functionArgs = args.getArgs();\n if (functionArgs === null) {\n return waitForever();\n }\n let changes = 0;\n return subscribe(ctx, {\n deploymentUrl: args.deploymentUrl,\n adminKey: args.adminKey,\n parsedFunctionName: args.parsedFunctionName,\n parsedFunctionArgs: functionArgs,\n componentPath: args.componentPath,\n until: stopPromise,\n callbacks: {\n onChange: () => {\n changes++;\n // First bump is just the initial results reporting\n if (changes > 1) {\n stop();\n }\n },\n },\n });\n },\n stop: () => {\n stop();\n },\n };\n}\n\nfunction getFileSystemWatch(\n ctx: WatchContext,\n watch: { watcher: Watcher | undefined },\n cmdOptions: { traceEvents: boolean },\n) {\n let hasStopped = false;\n return {\n watch: async () => {\n const observations = ctx.fs.finalize();\n if (observations === \"invalidated\") {\n logMessage(\"Filesystem changed during push, retrying...\");\n return;\n }\n // Initialize the watcher if we haven't done it already. Chokidar expects to have a\n // nonempty watch set at initialization, so we can't do it before running our first\n // push.\n if (!watch.watcher) {\n watch.watcher = new Watcher(observations);\n await showSpinnerIfSlow(\n \"Preparing to watch files...\",\n 500,\n async () => {\n await watch.watcher!.ready();\n },\n );\n stopSpinner();\n }\n // Watch new directories if needed.\n watch.watcher.update(observations);\n\n // Process events until we find one that overlaps with our previous observations.\n let anyChanges = false;\n do {\n await watch.watcher.waitForEvent();\n if (hasStopped) {\n return;\n }\n for (const event of watch.watcher.drainEvents()) {\n if (cmdOptions.traceEvents) {\n logMessage(\n \"Processing\",\n event.name,\n path.relative(\"\", event.absPath),\n );\n }\n const result = observations.overlaps(event);\n if (result.overlaps) {\n const relPath = path.relative(\"\", event.absPath);\n if (cmdOptions.traceEvents) {\n logMessage(`${relPath} ${result.reason}, rebuilding...`);\n }\n anyChanges = true;\n break;\n }\n }\n } while (!anyChanges);\n\n // Wait for the filesystem to quiesce before starting a new push. It's okay to\n // drop filesystem events at this stage since we're already committed to doing\n // a push and resubscribing based on that push's observations.\n let deadline = performance.now() + quiescenceDelay;\n while (true) {\n const now = performance.now();\n if (now >= deadline) {\n break;\n }\n const remaining = deadline - now;\n if (cmdOptions.traceEvents) {\n logMessage(`Waiting for ${formatDuration(remaining)} to quiesce...`);\n }\n const remainingWait = new Promise<\"timeout\">((resolve) =>\n setTimeout(() => resolve(\"timeout\"), deadline - now),\n );\n const result = await Promise.race([\n remainingWait,\n watch.watcher.waitForEvent().then<\"newEvents\">(() => \"newEvents\"),\n ]);\n if (result === \"newEvents\") {\n for (const event of watch.watcher.drainEvents()) {\n const result = observations.overlaps(event);\n // Delay another `quiescenceDelay` since we had an overlapping event.\n if (result.overlaps) {\n if (cmdOptions.traceEvents) {\n logMessage(\n `Received an overlapping event at ${event.absPath}, delaying push.`,\n );\n }\n deadline = performance.now() + quiescenceDelay;\n }\n }\n } else {\n // Let the check above `break` from the loop if we're past our deadlne.\n if (result !== \"timeout\") {\n logError(\n \"Assertion failed: Unexpected result from watcher: \" + result,\n );\n }\n }\n }\n },\n stop: () => {\n hasStopped = true;\n },\n };\n}\n\nconst initialBackoff = 500;\nconst maxBackoff = 16000;\nconst quiescenceDelay = 500;\n\nexport function nextBackoff(prevFailures: number): number {\n const baseBackoff = initialBackoff * Math.pow(2, prevFailures);\n const actualBackoff = Math.min(baseBackoff, maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { spawn, ChildProcess } from \"child_process\";\nimport { OneoffCtx } from \"../../bundler/context.js\";\nimport {\n logError,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n showSpinnerIfSlow,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { runPush } from \"./components.js\";\nimport { performance } from \"perf_hooks\";\nimport path from \"path\";\nimport { LogManager, LogMode, watchLogs } from \"./logs.js\";\nimport { PushOptions } from \"./components.js\";\nimport {\n formatDuration,\n getCurrentTimeString,\n waitForever,\n waitUntilCalled,\n} from \"./utils/utils.js\";\nimport { Crash, WatchContext, Watcher } from \"./watch.js\";\nimport { runFunctionAndLog, subscribe } from \"./run.js\";\nimport { Value } from \"../../values/index.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { readProjectConfig, getAuthKitConfig } from \"./config.js\";\nimport {\n syncAuthKitConfigAfterPush,\n ensureAuthKitProvisionedBeforeBuild,\n} from \"./workos/workos.js\";\n\nexport async function devAgainstDeployment(\n ctx: OneoffCtx,\n credentials: {\n url: string;\n adminKey: string;\n deploymentName: string | null;\n deploymentType?: DeploymentType;\n },\n devOptions: {\n verbose: boolean;\n typecheck: \"enable\" | \"try\" | \"disable\";\n typecheckComponents: boolean;\n codegen: boolean;\n once: boolean;\n untilSuccess: boolean;\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n tailLogs: LogMode;\n traceEvents: boolean;\n debugBundlePath?: string | undefined;\n debugNodeApis: boolean;\n liveComponentSources: boolean;\n pushAllModules: boolean;\n },\n) {\n const logManager = new LogManager(devOptions.tailLogs);\n\n // Pre-flight check: Ensure AuthKit is provisioned before starting dev\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n if (authKitConfig && credentials.deploymentName) {\n // Only provision for cloud deployments (dev/preview/prod)\n // Skip for local and anonymous deployments\n const deploymentType = credentials.deploymentType;\n if (\n deploymentType === \"dev\" ||\n deploymentType === \"preview\" ||\n deploymentType === \"prod\"\n ) {\n await ensureAuthKitProvisionedBeforeBuild(\n ctx,\n credentials.deploymentName,\n { deploymentUrl: credentials.url, adminKey: credentials.adminKey },\n deploymentType,\n );\n }\n }\n\n const promises = [];\n if (devOptions.tailLogs !== \"disable\") {\n promises.push(\n watchLogs(ctx, credentials.url, credentials.adminKey, \"stderr\", {\n logManager,\n success: false,\n }),\n );\n }\n\n promises.push(\n watchAndPush(\n ctx,\n {\n ...credentials,\n verbose: devOptions.verbose,\n dryRun: false,\n typecheck: devOptions.typecheck,\n typecheckComponents: devOptions.typecheckComponents,\n debug: false,\n debugBundlePath: devOptions.debugBundlePath,\n debugNodeApis: devOptions.debugNodeApis,\n codegen: devOptions.codegen,\n liveComponentSources: devOptions.liveComponentSources,\n pushAllModules: devOptions.pushAllModules,\n logManager, // Pass logManager to control logs during deploy\n largeIndexDeletionCheck: \"no verification\", // `convex dev` can\u2019t push to prod\n },\n devOptions,\n ),\n );\n await Promise.race(promises);\n await ctx.flushAndExit(0);\n}\n\nexport async function watchAndPush(\n outerCtx: OneoffCtx,\n options: PushOptions,\n cmdOptions: {\n run?:\n | { kind: \"function\"; name: string; component?: string | undefined }\n | { kind: \"shell\"; command: string }\n | undefined;\n once: boolean;\n untilSuccess: boolean;\n traceEvents: boolean;\n },\n) {\n const watch: { watcher: Watcher | undefined } = { watcher: undefined };\n const authKitCache: { lastAppliedConfig: string | undefined } = {\n lastAppliedConfig: undefined,\n };\n let numFailures = 0;\n let ran = false;\n let pushed = false;\n let shellChild: ChildProcess | undefined;\n let shellExited: Promise<void> | undefined;\n let shellCleanupHandle: string | undefined;\n let tableNameTriggeringRetry;\n let shouldRetryOnDeploymentEnvVarChange;\n let isFirstPush = true; // Track if this is the first push in the session\n\n try {\n while (true) {\n const start = performance.now();\n tableNameTriggeringRetry = null;\n shouldRetryOnDeploymentEnvVarChange = false;\n\n const ctx = new WatchContext(\n cmdOptions.traceEvents,\n outerCtx.bigBrainAuth(),\n isFirstPush,\n );\n options.logManager?.beginDeploy();\n showSpinner(\"Preparing Convex functions...\");\n try {\n await runPush(ctx, options);\n const end = performance.now();\n // NOTE: If `runPush` throws, `endDeploy` will not be called.\n // This allows you to see the output from the failed deploy without\n // logs getting in the way.\n options.logManager?.endDeploy();\n numFailures = 0;\n logFinishedStep(\n `${getCurrentTimeString()} Convex functions ready! (${formatDuration(\n end - start,\n )})`,\n );\n\n // Sync AuthKit configuration if it has changed\n const { projectConfig } = await readProjectConfig(ctx);\n const authKitConfig = await getAuthKitConfig(ctx, projectConfig);\n\n // Check if config has changed by comparing stringified versions\n const currentConfigString = authKitConfig\n ? JSON.stringify(authKitConfig)\n : undefined;\n\n // Skip sync on first push since ensureAuthKitProvisionedBeforeBuild already configured WorkOS\n if (\n !isFirstPush &&\n currentConfigString !== authKitCache.lastAppliedConfig\n ) {\n // Config has changed, sync it\n await syncAuthKitConfigAfterPush(ctx, projectConfig, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n });\n }\n\n // Always update cache after push (even if we skipped sync)\n authKitCache.lastAppliedConfig = currentConfigString;\n isFirstPush = false;\n if (cmdOptions.run !== undefined && !ran) {\n switch (cmdOptions.run.kind) {\n case \"function\":\n await runFunctionInDev(\n ctx,\n options,\n cmdOptions.run.name,\n cmdOptions.run.component,\n );\n break;\n case \"shell\": {\n // Spawn the shell command as a long-running child process,\n // piping stdin/stdout/stderr. It runs alongside dev and is\n // waited on during clean exit or killed on signal exit.\n const shellCommand = cmdOptions.run.command;\n shellChild = spawn(shellCommand, [], {\n shell: true,\n stdio: \"inherit\",\n detached: true,\n });\n shellCleanupHandle = outerCtx.registerCleanup(async () => {\n if (shellChild) {\n const child = shellChild;\n shellChild = undefined;\n // Kill the entire process group so children of the shell\n // are also killed.\n if (child.pid !== undefined) {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n // Process group may already be dead.\n child.kill();\n }\n } else {\n child.kill();\n }\n }\n await shellExited;\n });\n shellExited = new Promise<void>((resolve) => {\n shellChild!.on(\"error\", (error) => {\n logError(\n `Failed to run command \\`${shellCommand}\\`: ${error.message}`,\n );\n shellChild = undefined;\n resolve();\n void outerCtx.flushAndExit(1);\n });\n shellChild!.on(\"exit\", (code, signal) => {\n shellChild = undefined;\n resolve();\n // If killed by a signal (e.g. from cleanup on shutdown),\n // don't treat it as a failure \u2014 convex dev is already\n // shutting down.\n if (signal) {\n return;\n }\n if (code !== null && code !== 0) {\n logError(\n `Command \\`${shellCommand}\\` exited with code ${code}`,\n );\n void outerCtx.flushAndExit(1);\n }\n });\n });\n break;\n }\n default: {\n cmdOptions.run satisfies never;\n // Don't return this since it'll bypass the `catch` below.\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Unexpected arguments for --run`,\n errForSentry: `Unexpected arguments for --run: ${JSON.stringify(\n cmdOptions.run,\n )}`,\n });\n }\n }\n ran = true;\n }\n pushed = true;\n } catch (e: any) {\n // Crash the app on unexpected errors.\n if (!(e instanceof Crash) || !e.errorType) {\n // eslint-disable-next-line no-restricted-syntax\n throw e;\n }\n if (e.errorType === \"fatal\") {\n break;\n }\n // Retry after an exponential backoff if we hit a transient error.\n if (e.errorType === \"transient\" || e.errorType === \"already handled\") {\n const delay = nextBackoff(numFailures);\n numFailures += 1;\n if (e.errorType === \"transient\") {\n logWarning(\n chalkStderr.yellow(\n `Failed due to network error, retrying in ${formatDuration(\n delay,\n )}...`,\n ),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n\n // Fall through if we had a filesystem-based error.\n // TODO(sarah): Replace this with `logError`.\n // eslint-disable-next-line no-console\n console.assert(\n e.errorType === \"invalid filesystem data\" ||\n e.errorType === \"invalid filesystem or env vars\" ||\n e.errorType[\"invalid filesystem or db data\"] !== undefined,\n );\n if (e.errorType === \"invalid filesystem or env vars\") {\n shouldRetryOnDeploymentEnvVarChange = true;\n } else if (\n e.errorType !== \"invalid filesystem data\" &&\n e.errorType[\"invalid filesystem or db data\"] !== undefined\n ) {\n tableNameTriggeringRetry =\n e.errorType[\"invalid filesystem or db data\"];\n }\n if (cmdOptions.once) {\n await outerCtx.flushAndExit(1, e.errorType);\n }\n // Make sure that we don't spin if this push failed\n // in any edge cases that didn't call `logFailure`\n // before throwing.\n stopSpinner();\n }\n if (cmdOptions.once) {\n return;\n }\n if (pushed && cmdOptions.untilSuccess) {\n return;\n }\n const fileSystemWatch = getFileSystemWatch(ctx, watch, cmdOptions);\n const tableWatch = getTableWatch(\n ctx,\n options,\n tableNameTriggeringRetry?.tableName ?? null,\n tableNameTriggeringRetry?.componentPath,\n );\n const envVarWatch = getDeplymentEnvVarWatch(\n ctx,\n options,\n shouldRetryOnDeploymentEnvVarChange,\n );\n await Promise.race([\n fileSystemWatch.watch(),\n tableWatch.watch(),\n envVarWatch.watch(),\n ]);\n fileSystemWatch.stop();\n void tableWatch.stop();\n void envVarWatch.stop();\n }\n } finally {\n // On clean exit (e.g. --once, --until-success), wait for the shell\n // command to finish naturally. On signal exit (e.g. Ctrl+C), the\n // registered cleanup handler will have already killed it.\n if (shellExited) {\n await shellExited;\n }\n if (shellCleanupHandle) {\n outerCtx.removeCleanup(shellCleanupHandle);\n }\n }\n}\n\nasync function runFunctionInDev(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n functionName: string,\n componentPath: string | undefined,\n) {\n await runFunctionAndLog(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n functionName,\n argsString: \"{}\",\n componentPath,\n callbacks: {\n onSuccess: () => {\n logFinishedStep(`Finished running function \"${functionName}\"`);\n },\n },\n });\n}\n\nfunction getTableWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n tableName: string | null,\n componentPath: string | undefined,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryTable\",\n getArgs: () => (tableName !== null ? { tableName } : null),\n componentPath,\n });\n}\n\nfunction getDeplymentEnvVarWatch(\n ctx: WatchContext,\n credentials: {\n url: string;\n adminKey: string;\n },\n shouldRetryOnDeploymentEnvVarChange: boolean,\n) {\n return getFunctionWatch(ctx, {\n deploymentUrl: credentials.url,\n adminKey: credentials.adminKey,\n parsedFunctionName: \"_system/cli/queryEnvironmentVariables\",\n getArgs: () => (shouldRetryOnDeploymentEnvVarChange ? {} : null),\n componentPath: undefined,\n });\n}\n\nfunction getFunctionWatch(\n ctx: WatchContext,\n args: {\n deploymentUrl: string;\n adminKey: string;\n parsedFunctionName: string;\n getArgs: () => Record<string, Value> | null;\n componentPath: string | undefined;\n },\n) {\n const [stopPromise, stop] = waitUntilCalled();\n return {\n watch: async () => {\n const functionArgs = args.getArgs();\n if (functionArgs === null) {\n return waitForever();\n }\n let changes = 0;\n return subscribe(ctx, {\n deploymentUrl: args.deploymentUrl,\n adminKey: args.adminKey,\n parsedFunctionName: args.parsedFunctionName,\n parsedFunctionArgs: functionArgs,\n componentPath: args.componentPath,\n until: stopPromise,\n callbacks: {\n onChange: () => {\n changes++;\n // First bump is just the initial results reporting\n if (changes > 1) {\n stop();\n }\n },\n },\n });\n },\n stop: () => {\n stop();\n },\n };\n}\n\nfunction getFileSystemWatch(\n ctx: WatchContext,\n watch: { watcher: Watcher | undefined },\n cmdOptions: { traceEvents: boolean },\n) {\n let hasStopped = false;\n return {\n watch: async () => {\n const observations = ctx.fs.finalize();\n if (observations === \"invalidated\") {\n logMessage(\"Filesystem changed during push, retrying...\");\n return;\n }\n // Initialize the watcher if we haven't done it already. Chokidar expects to have a\n // nonempty watch set at initialization, so we can't do it before running our first\n // push.\n if (!watch.watcher) {\n watch.watcher = new Watcher(observations);\n await showSpinnerIfSlow(\n \"Preparing to watch files...\",\n 500,\n async () => {\n await watch.watcher!.ready();\n },\n );\n stopSpinner();\n }\n // Watch new directories if needed.\n watch.watcher.update(observations);\n\n // Process events until we find one that overlaps with our previous observations.\n let anyChanges = false;\n do {\n await watch.watcher.waitForEvent();\n if (hasStopped) {\n return;\n }\n for (const event of watch.watcher.drainEvents()) {\n if (cmdOptions.traceEvents) {\n logMessage(\n \"Processing\",\n event.name,\n path.relative(\"\", event.absPath),\n );\n }\n const result = observations.overlaps(event);\n if (result.overlaps) {\n const relPath = path.relative(\"\", event.absPath);\n if (cmdOptions.traceEvents) {\n logMessage(`${relPath} ${result.reason}, rebuilding...`);\n }\n anyChanges = true;\n break;\n }\n }\n } while (!anyChanges);\n\n // Wait for the filesystem to quiesce before starting a new push. It's okay to\n // drop filesystem events at this stage since we're already committed to doing\n // a push and resubscribing based on that push's observations.\n let deadline = performance.now() + quiescenceDelay;\n while (true) {\n const now = performance.now();\n if (now >= deadline) {\n break;\n }\n const remaining = deadline - now;\n if (cmdOptions.traceEvents) {\n logMessage(`Waiting for ${formatDuration(remaining)} to quiesce...`);\n }\n const remainingWait = new Promise<\"timeout\">((resolve) =>\n setTimeout(() => resolve(\"timeout\"), deadline - now),\n );\n const result = await Promise.race([\n remainingWait,\n watch.watcher.waitForEvent().then<\"newEvents\">(() => \"newEvents\"),\n ]);\n if (result === \"newEvents\") {\n for (const event of watch.watcher.drainEvents()) {\n const result = observations.overlaps(event);\n // Delay another `quiescenceDelay` since we had an overlapping event.\n if (result.overlaps) {\n if (cmdOptions.traceEvents) {\n logMessage(\n `Received an overlapping event at ${event.absPath}, delaying push.`,\n );\n }\n deadline = performance.now() + quiescenceDelay;\n }\n }\n } else {\n // Let the check above `break` from the loop if we're past our deadlne.\n if (result !== \"timeout\") {\n logError(\n \"Assertion failed: Unexpected result from watcher: \" + result,\n );\n }\n }\n }\n },\n stop: () => {\n hasStopped = true;\n },\n };\n}\n\nconst initialBackoff = 500;\nconst maxBackoff = 16000;\nconst quiescenceDelay = 500;\n\nexport function nextBackoff(prevFailures: number): number {\n const baseBackoff = initialBackoff * Math.pow(2, prevFailures);\n const actualBackoff = Math.min(baseBackoff, maxBackoff);\n const jitter = actualBackoff * (Math.random() - 0.5);\n return actualBackoff + jitter;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["result"]
7
7
  }
@@ -257,15 +257,4 @@ export async function callUpdateEnvironmentVariables(ctx, deployment, changes) {
257
257
  return await logAndHandleFetchError(ctx, e);
258
258
  }
259
259
  }
260
- export async function fetchDeploymentCanonicalSiteUrl(ctx, options) {
261
- const result = await envGetInDeployment(ctx, options, "CONVEX_SITE_URL");
262
- if (typeof result !== "string") {
263
- return await ctx.crash({
264
- exitCode: 1,
265
- errorType: "invalid filesystem or env vars",
266
- printedMessage: "Invalid process.env.CONVEX_SITE_URL"
267
- });
268
- }
269
- return result;
270
- }
271
260
  //# sourceMappingURL=env.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/env.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n} from \"../../bundler/log.js\";\nimport { runSystemQuery } from \"./run.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"./utils/utils.js\";\nimport { readFromStdin } from \"./utils/stdin.js\";\nimport { promptSecret } from \"./utils/prompts.js\";\nimport {\n EXPECTED_CONVEX_URL_NAMES,\n EXPECTED_SITE_URL_NAMES,\n} from \"./envvars.js\";\nimport { formatEnvValueForDotfile } from \"./formatEnvValueForDotfile.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n} from \"./utils/utils.js\";\n\nfunction formatList(items: string[]): string {\n if (items.length === 0) return \"\";\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} and ${items[1]}`;\n return `${items.slice(0, -1).join(\", \")}, and ${items[items.length - 1]}`;\n}\n\nexport async function envSetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n originalName: string | undefined,\n originalValue: string | undefined,\n options?: {\n fromFile?: string;\n force?: boolean;\n secret?: boolean;\n },\n) {\n const { fromFile, force = false } = options ?? {};\n if (originalName) {\n let name = originalName,\n value: string;\n const parsed = await allowEqualsSyntax(ctx, originalName, originalValue);\n if (parsed) {\n [name, value] = parsed;\n } else if (fromFile) {\n value = await getFileContents(ctx, fromFile);\n } else if (!process.stdin.isTTY) {\n value = await getStdIn(ctx);\n } else {\n value = await promptSecret(ctx, {\n message: `Enter value for ${name}:`,\n });\n }\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name, value }]);\n if (options?.secret) {\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)} to ${chalkStderr.bold(formatted)}${deployment.deploymentNotice}`,\n );\n } else {\n logFinishedStep(`Successfully set ${chalkStderr.bold(name)}`);\n }\n return true;\n }\n let content: string, source: string;\n if (fromFile) {\n content = await getFileContents(ctx, fromFile);\n source = fromFile;\n } else if (!process.stdin.isTTY) {\n content = await getStdIn(ctx);\n source = \"stdin\";\n } else {\n return false;\n }\n await envSetFromContentInDeployment(ctx, deployment, {\n content,\n source,\n force,\n });\n return true;\n}\n\nasync function getFileContents(\n ctx: Context,\n filePath: string,\n): Promise<string> {\n if (!ctx.fs.exists(filePath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: file not found: ${filePath}`,\n });\n }\n return ctx.fs.readUtf8File(filePath);\n}\n\nasync function getStdIn(ctx: Context): Promise<string> {\n try {\n return await readFromStdin();\n } catch (error) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: failed to read from stdin: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n}\n\nasync function envSetFromContentInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n options: {\n content: string;\n source: string;\n force: boolean;\n },\n) {\n const { content, source, force } = options;\n const parsedEnv = dotenv.parse(content);\n\n // Filter out CLI-managed environment variables\n const envVars = Object.entries(parsedEnv);\n const filteredVars: string[] = [];\n\n const envVarsToSet: [string, string][] = [];\n const managedVars = new Set<string>([\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n ...EXPECTED_CONVEX_URL_NAMES,\n ...EXPECTED_SITE_URL_NAMES,\n ]);\n for (const [name, value] of envVars) {\n if (managedVars.has(name)) {\n filteredVars.push(name);\n } else {\n envVarsToSet.push([name, value]);\n }\n }\n\n if (filteredVars.length > 0) {\n const varNames = filteredVars.map((n) => chalkStderr.bold(n));\n const formattedNames = formatList(varNames);\n logMessage(\n `Skipping ${filteredVars.length} CLI-managed environment variable${filteredVars.length === 1 ? \"\" : \"s\"}: ${formattedNames}`,\n );\n }\n\n if (envVarsToSet.length === 0) {\n if (envVars.length === 0) {\n logMessage(`No environment variables found in ${source}.`);\n }\n return;\n }\n\n // Fetch existing environment variables\n const existingEnvVars = await getEnvVars(ctx, deployment);\n\n const existingEnvMap = new Map(\n existingEnvVars.map((env) => [env.name, env.value]),\n );\n\n // Categorize the environment variables\n const newVars: [string, string][] = [];\n const updatedVars: [string, string][] = [];\n const unchangedVars: [string, string][] = [];\n const conflicts: { name: string; existing: string; new: string }[] = [];\n\n for (const [name, value] of envVarsToSet) {\n const existingValue = existingEnvMap.get(name);\n if (existingValue === undefined) {\n newVars.push([name, value]);\n } else if (existingValue === value) {\n unchangedVars.push([name, value]);\n } else if (force) {\n updatedVars.push([name, value]);\n } else {\n conflicts.push({ name, existing: existingValue, new: value });\n }\n }\n\n // Check for conflicts if not replacing\n if (conflicts.length > 0) {\n const varNames = conflicts.map((c) => chalkStderr.bold(c.name));\n const formattedNames = formatList(varNames);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `error: environment variable${conflicts.length === 1 ? \"\" : \"s\"} ${formattedNames} already exist${conflicts.length === 1 ? \"s\" : \"\"} with different value${conflicts.length === 1 ? \"\" : \"s\"}.\\n\\n` +\n `Use ${chalkStderr.bold(\"--force\")} to overwrite existing values.`,\n });\n }\n\n // Build the changes: only new vars when not replacing, new + updated when replacing\n const varsToUpdate = force ? [...newVars, ...updatedVars] : newVars;\n const changes: EnvVarChange[] = varsToUpdate.map(([name, value]) => ({\n name,\n value,\n }));\n\n if (changes.length > 0) {\n await callUpdateEnvironmentVariables(ctx, deployment, changes);\n }\n\n const newCount = newVars.length;\n const updatedCount = updatedVars.length;\n const unchangedCount = unchangedVars.length;\n\n const parts = [];\n if (newCount > 0) parts.push(`${newCount} new`);\n if (updatedCount > 0) parts.push(`${updatedCount} updated`);\n if (unchangedCount > 0) parts.push(`${unchangedCount} unchanged`);\n\n const totalProcessed = newCount + updatedCount + unchangedCount;\n if (changes.length === 0) {\n logMessage(\n `All ${totalProcessed} environment variable${totalProcessed === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} already set${deployment.deploymentNotice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${changes.length} environment variable${changes.length === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} (${parts.join(\", \")})${deployment.deploymentNotice}`,\n );\n }\n}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n): Promise<[string, string] | null> {\n if (/^[a-zA-Z][a-zA-Z0-9_]*=/.test(name)) {\n const [n, ...values] = name.split(\"=\");\n if (value === undefined) {\n return [n, values.join(\"=\")];\n } else {\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `When setting an environment variable, you can either set a value with 'NAME=value', or with NAME value, but not both. Are you missing quotes around the CLI argument? Try: \\n npx convex env set '${name} ${value}'`,\n });\n }\n }\n if (value === undefined) return null;\n return [name, value];\n}\n\nexport async function envGetInDeploymentAction(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n name: string,\n) {\n const envVar = await envGetInDeployment(ctx, deployment, name);\n if (envVar === null) {\n logFailure(`Environment variable \"${name}\" not found.`);\n return;\n }\n logOutput(`${envVar}`);\n}\n\nexport async function envGetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n name: string,\n): Promise<string | null> {\n const envVar = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables:get\",\n componentPath: undefined,\n args: { name },\n })) as EnvVar | null;\n return envVar === null ? null : envVar.value;\n}\n\nexport async function envRemoveInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n name: string,\n) {\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name }]);\n logFinishedStep(\n `Successfully unset ${chalkStderr.bold(name)}${deployment.deploymentNotice}`,\n );\n}\n\nasync function getEnvVars(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n): Promise<EnvVar[]> {\n return (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n}\n\nexport async function envListInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n const envs = await getEnvVars(ctx, deployment);\n if (envs.length === 0) {\n logMessage(\"No environment variables set.\");\n return;\n }\n for (const { name, value } of envs) {\n const { formatted, warning } = formatEnvValueForDotfile(value);\n if (warning) {\n logMessage(`Warning (${name}): ${warning}`);\n }\n logOutput(`${name}=${formatted}`);\n }\n}\n\nexport type EnvVarChange = {\n name: string;\n value?: string;\n};\n\nexport type EnvVar = {\n name: string;\n value: string;\n};\n\nexport async function callUpdateEnvironmentVariables(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n changes: EnvVarChange[],\n) {\n const fetch = deploymentFetch(ctx, deployment);\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes }),\n method: \"POST\",\n });\n } catch (e) {\n return await logAndHandleFetchError(ctx, e);\n }\n}\n\nexport async function fetchDeploymentCanonicalSiteUrl(\n ctx: Context,\n options: { deploymentUrl: string; adminKey: string },\n): Promise<string> {\n const result = await envGetInDeployment(ctx, options, \"CONVEX_SITE_URL\");\n if (typeof result !== \"string\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem or env vars\",\n printedMessage: \"Invalid process.env.CONVEX_SITE_URL\",\n });\n }\n return result;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n} from \"../../bundler/log.js\";\nimport { runSystemQuery } from \"./run.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"./utils/utils.js\";\nimport { readFromStdin } from \"./utils/stdin.js\";\nimport { promptSecret } from \"./utils/prompts.js\";\nimport {\n EXPECTED_CONVEX_URL_NAMES,\n EXPECTED_SITE_URL_NAMES,\n} from \"./envvars.js\";\nimport { formatEnvValueForDotfile } from \"./formatEnvValueForDotfile.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n} from \"./utils/utils.js\";\n\nfunction formatList(items: string[]): string {\n if (items.length === 0) return \"\";\n if (items.length === 1) return items[0];\n if (items.length === 2) return `${items[0]} and ${items[1]}`;\n return `${items.slice(0, -1).join(\", \")}, and ${items[items.length - 1]}`;\n}\n\nexport async function envSetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n originalName: string | undefined,\n originalValue: string | undefined,\n options?: {\n fromFile?: string;\n force?: boolean;\n secret?: boolean;\n },\n) {\n const { fromFile, force = false } = options ?? {};\n if (originalName) {\n let name = originalName,\n value: string;\n const parsed = await allowEqualsSyntax(ctx, originalName, originalValue);\n if (parsed) {\n [name, value] = parsed;\n } else if (fromFile) {\n value = await getFileContents(ctx, fromFile);\n } else if (!process.stdin.isTTY) {\n value = await getStdIn(ctx);\n } else {\n value = await promptSecret(ctx, {\n message: `Enter value for ${name}:`,\n });\n }\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name, value }]);\n if (options?.secret) {\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n logFinishedStep(\n `Successfully set ${chalkStderr.bold(name)} to ${chalkStderr.bold(formatted)}${deployment.deploymentNotice}`,\n );\n } else {\n logFinishedStep(`Successfully set ${chalkStderr.bold(name)}`);\n }\n return true;\n }\n let content: string, source: string;\n if (fromFile) {\n content = await getFileContents(ctx, fromFile);\n source = fromFile;\n } else if (!process.stdin.isTTY) {\n content = await getStdIn(ctx);\n source = \"stdin\";\n } else {\n return false;\n }\n await envSetFromContentInDeployment(ctx, deployment, {\n content,\n source,\n force,\n });\n return true;\n}\n\nasync function getFileContents(\n ctx: Context,\n filePath: string,\n): Promise<string> {\n if (!ctx.fs.exists(filePath)) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: file not found: ${filePath}`,\n });\n }\n return ctx.fs.readUtf8File(filePath);\n}\n\nasync function getStdIn(ctx: Context): Promise<string> {\n try {\n return await readFromStdin();\n } catch (error) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: failed to read from stdin: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n}\n\nasync function envSetFromContentInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n options: {\n content: string;\n source: string;\n force: boolean;\n },\n) {\n const { content, source, force } = options;\n const parsedEnv = dotenv.parse(content);\n\n // Filter out CLI-managed environment variables\n const envVars = Object.entries(parsedEnv);\n const filteredVars: string[] = [];\n\n const envVarsToSet: [string, string][] = [];\n const managedVars = new Set<string>([\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n CONVEX_SELF_HOSTED_URL_VAR_NAME,\n CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,\n ...EXPECTED_CONVEX_URL_NAMES,\n ...EXPECTED_SITE_URL_NAMES,\n ]);\n for (const [name, value] of envVars) {\n if (managedVars.has(name)) {\n filteredVars.push(name);\n } else {\n envVarsToSet.push([name, value]);\n }\n }\n\n if (filteredVars.length > 0) {\n const varNames = filteredVars.map((n) => chalkStderr.bold(n));\n const formattedNames = formatList(varNames);\n logMessage(\n `Skipping ${filteredVars.length} CLI-managed environment variable${filteredVars.length === 1 ? \"\" : \"s\"}: ${formattedNames}`,\n );\n }\n\n if (envVarsToSet.length === 0) {\n if (envVars.length === 0) {\n logMessage(`No environment variables found in ${source}.`);\n }\n return;\n }\n\n // Fetch existing environment variables\n const existingEnvVars = await getEnvVars(ctx, deployment);\n\n const existingEnvMap = new Map(\n existingEnvVars.map((env) => [env.name, env.value]),\n );\n\n // Categorize the environment variables\n const newVars: [string, string][] = [];\n const updatedVars: [string, string][] = [];\n const unchangedVars: [string, string][] = [];\n const conflicts: { name: string; existing: string; new: string }[] = [];\n\n for (const [name, value] of envVarsToSet) {\n const existingValue = existingEnvMap.get(name);\n if (existingValue === undefined) {\n newVars.push([name, value]);\n } else if (existingValue === value) {\n unchangedVars.push([name, value]);\n } else if (force) {\n updatedVars.push([name, value]);\n } else {\n conflicts.push({ name, existing: existingValue, new: value });\n }\n }\n\n // Check for conflicts if not replacing\n if (conflicts.length > 0) {\n const varNames = conflicts.map((c) => chalkStderr.bold(c.name));\n const formattedNames = formatList(varNames);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n `error: environment variable${conflicts.length === 1 ? \"\" : \"s\"} ${formattedNames} already exist${conflicts.length === 1 ? \"s\" : \"\"} with different value${conflicts.length === 1 ? \"\" : \"s\"}.\\n\\n` +\n `Use ${chalkStderr.bold(\"--force\")} to overwrite existing values.`,\n });\n }\n\n // Build the changes: only new vars when not replacing, new + updated when replacing\n const varsToUpdate = force ? [...newVars, ...updatedVars] : newVars;\n const changes: EnvVarChange[] = varsToUpdate.map(([name, value]) => ({\n name,\n value,\n }));\n\n if (changes.length > 0) {\n await callUpdateEnvironmentVariables(ctx, deployment, changes);\n }\n\n const newCount = newVars.length;\n const updatedCount = updatedVars.length;\n const unchangedCount = unchangedVars.length;\n\n const parts = [];\n if (newCount > 0) parts.push(`${newCount} new`);\n if (updatedCount > 0) parts.push(`${updatedCount} updated`);\n if (unchangedCount > 0) parts.push(`${unchangedCount} unchanged`);\n\n const totalProcessed = newCount + updatedCount + unchangedCount;\n if (changes.length === 0) {\n logMessage(\n `All ${totalProcessed} environment variable${totalProcessed === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} already set${deployment.deploymentNotice}`,\n );\n } else {\n logFinishedStep(\n `Successfully set ${changes.length} environment variable${changes.length === 1 ? \"\" : \"s\"} from ${chalkStderr.bold(source)} (${parts.join(\", \")})${deployment.deploymentNotice}`,\n );\n }\n}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n): Promise<[string, string] | null> {\n if (/^[a-zA-Z][a-zA-Z0-9_]*=/.test(name)) {\n const [n, ...values] = name.split(\"=\");\n if (value === undefined) {\n return [n, values.join(\"=\")];\n } else {\n await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `When setting an environment variable, you can either set a value with 'NAME=value', or with NAME value, but not both. Are you missing quotes around the CLI argument? Try: \\n npx convex env set '${name} ${value}'`,\n });\n }\n }\n if (value === undefined) return null;\n return [name, value];\n}\n\nexport async function envGetInDeploymentAction(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n name: string,\n) {\n const envVar = await envGetInDeployment(ctx, deployment, name);\n if (envVar === null) {\n logFailure(`Environment variable \"${name}\" not found.`);\n return;\n }\n logOutput(`${envVar}`);\n}\n\nexport async function envGetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n name: string,\n): Promise<string | null> {\n const envVar = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables:get\",\n componentPath: undefined,\n args: { name },\n })) as EnvVar | null;\n return envVar === null ? null : envVar.value;\n}\n\nexport async function envRemoveInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n name: string,\n) {\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name }]);\n logFinishedStep(\n `Successfully unset ${chalkStderr.bold(name)}${deployment.deploymentNotice}`,\n );\n}\n\nasync function getEnvVars(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n): Promise<EnvVar[]> {\n return (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n}\n\nexport async function envListInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n const envs = await getEnvVars(ctx, deployment);\n if (envs.length === 0) {\n logMessage(\"No environment variables set.\");\n return;\n }\n for (const { name, value } of envs) {\n const { formatted, warning } = formatEnvValueForDotfile(value);\n if (warning) {\n logMessage(`Warning (${name}): ${warning}`);\n }\n logOutput(`${name}=${formatted}`);\n }\n}\n\nexport type EnvVarChange = {\n name: string;\n value?: string;\n};\n\nexport type EnvVar = {\n name: string;\n value: string;\n};\n\nexport async function callUpdateEnvironmentVariables(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n changes: EnvVarChange[],\n) {\n const fetch = deploymentFetch(ctx, deployment);\n try {\n await fetch(\"/api/update_environment_variables\", {\n body: JSON.stringify({ changes }),\n method: \"POST\",\n });\n } catch (e) {\n return await logAndHandleFetchError(ctx, e);\n }\n}\n"],
5
+ "mappings": ";AAAA,SAAS,mBAAmB;AAC5B,YAAY,YAAY;AAExB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,gCAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,WAAW,OAAyB;AAC3C,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,CAAC;AACtC,MAAI,MAAM,WAAW,EAAG,QAAO,GAAG,MAAM,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC;AAC1D,SAAO,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,SAAS,MAAM,MAAM,SAAS,CAAC,CAAC;AACzE;AAEA,sBAAsB,mBACpB,KACA,YAKA,cACA,eACA,SAKA;AACA,QAAM,EAAE,UAAU,QAAQ,MAAM,IAAI,WAAW,CAAC;AAChD,MAAI,cAAc;AAChB,QAAI,OAAO,cACT;AACF,UAAM,SAAS,MAAM,kBAAkB,KAAK,cAAc,aAAa;AACvE,QAAI,QAAQ;AACV,OAAC,MAAM,KAAK,IAAI;AAAA,IAClB,WAAW,UAAU;AACnB,cAAQ,MAAM,gBAAgB,KAAK,QAAQ;AAAA,IAC7C,WAAW,CAAC,QAAQ,MAAM,OAAO;AAC/B,cAAQ,MAAM,SAAS,GAAG;AAAA,IAC5B,OAAO;AACL,cAAQ,MAAM,aAAa,KAAK;AAAA,QAC9B,SAAS,mBAAmB,IAAI;AAAA,MAClC,CAAC;AAAA,IACH;AACA,UAAM,+BAA+B,KAAK,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,CAAC;AACvE,QAAI,SAAS,QAAQ;AACnB,YAAM,YAAY,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM;AACpD;AAAA,QACE,oBAAoB,YAAY,KAAK,IAAI,CAAC,OAAO,YAAY,KAAK,SAAS,CAAC,GAAG,WAAW,gBAAgB;AAAA,MAC5G;AAAA,IACF,OAAO;AACL,sBAAgB,oBAAoB,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AACA,MAAI,SAAiB;AACrB,MAAI,UAAU;AACZ,cAAU,MAAM,gBAAgB,KAAK,QAAQ;AAC7C,aAAS;AAAA,EACX,WAAW,CAAC,QAAQ,MAAM,OAAO;AAC/B,cAAU,MAAM,SAAS,GAAG;AAC5B,aAAS;AAAA,EACX,OAAO;AACL,WAAO;AAAA,EACT;AACA,QAAM,8BAA8B,KAAK,YAAY;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,eAAe,gBACb,KACA,UACiB;AACjB,MAAI,CAAC,IAAI,GAAG,OAAO,QAAQ,GAAG;AAC5B,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,0BAA0B,QAAQ;AAAA,IACpD,CAAC;AAAA,EACH;AACA,SAAO,IAAI,GAAG,aAAa,QAAQ;AACrC;AAEA,eAAe,SAAS,KAA+B;AACrD,MAAI;AACF,WAAO,MAAM,cAAc;AAAA,EAC7B,SAAS,OAAO;AACd,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC7G,CAAC;AAAA,EACH;AACF;AAEA,eAAe,8BACb,KACA,YAKA,SAKA;AACA,QAAM,EAAE,SAAS,QAAQ,MAAM,IAAI;AACnC,QAAM,YAAY,OAAO,MAAM,OAAO;AAGtC,QAAM,UAAU,OAAO,QAAQ,SAAS;AACxC,QAAM,eAAyB,CAAC;AAEhC,QAAM,eAAmC,CAAC;AAC1C,QAAM,cAAc,oBAAI,IAAY;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AACD,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,QAAI,YAAY,IAAI,IAAI,GAAG;AACzB,mBAAa,KAAK,IAAI;AAAA,IACxB,OAAO;AACL,mBAAa,KAAK,CAAC,MAAM,KAAK,CAAC;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,WAAW,aAAa,IAAI,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC;AAC5D,UAAM,iBAAiB,WAAW,QAAQ;AAC1C;AAAA,MACE,YAAY,aAAa,MAAM,oCAAoC,aAAa,WAAW,IAAI,KAAK,GAAG,KAAK,cAAc;AAAA,IAC5H;AAAA,EACF;AAEA,MAAI,aAAa,WAAW,GAAG;AAC7B,QAAI,QAAQ,WAAW,GAAG;AACxB,iBAAW,qCAAqC,MAAM,GAAG;AAAA,IAC3D;AACA;AAAA,EACF;AAGA,QAAM,kBAAkB,MAAM,WAAW,KAAK,UAAU;AAExD,QAAM,iBAAiB,IAAI;AAAA,IACzB,gBAAgB,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,EACpD;AAGA,QAAM,UAA8B,CAAC;AACrC,QAAM,cAAkC,CAAC;AACzC,QAAM,gBAAoC,CAAC;AAC3C,QAAM,YAA+D,CAAC;AAEtE,aAAW,CAAC,MAAM,KAAK,KAAK,cAAc;AACxC,UAAM,gBAAgB,eAAe,IAAI,IAAI;AAC7C,QAAI,kBAAkB,QAAW;AAC/B,cAAQ,KAAK,CAAC,MAAM,KAAK,CAAC;AAAA,IAC5B,WAAW,kBAAkB,OAAO;AAClC,oBAAc,KAAK,CAAC,MAAM,KAAK,CAAC;AAAA,IAClC,WAAW,OAAO;AAChB,kBAAY,KAAK,CAAC,MAAM,KAAK,CAAC;AAAA,IAChC,OAAO;AACL,gBAAU,KAAK,EAAE,MAAM,UAAU,eAAe,KAAK,MAAM,CAAC;AAAA,IAC9D;AAAA,EACF;AAGA,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,WAAW,UAAU,IAAI,CAAC,MAAM,YAAY,KAAK,EAAE,IAAI,CAAC;AAC9D,UAAM,iBAAiB,WAAW,QAAQ;AAC1C,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBACE,8BAA8B,UAAU,WAAW,IAAI,KAAK,GAAG,IAAI,cAAc,iBAAiB,UAAU,WAAW,IAAI,MAAM,EAAE,wBAAwB,UAAU,WAAW,IAAI,KAAK,GAAG;AAAA;AAAA,MACrL,YAAY,KAAK,SAAS,CAAC;AAAA,IACtC,CAAC;AAAA,EACH;AAGA,QAAM,eAAe,QAAQ,CAAC,GAAG,SAAS,GAAG,WAAW,IAAI;AAC5D,QAAM,UAA0B,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,IACnE;AAAA,IACA;AAAA,EACF,EAAE;AAEF,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,+BAA+B,KAAK,YAAY,OAAO;AAAA,EAC/D;AAEA,QAAM,WAAW,QAAQ;AACzB,QAAM,eAAe,YAAY;AACjC,QAAM,iBAAiB,cAAc;AAErC,QAAM,QAAQ,CAAC;AACf,MAAI,WAAW,EAAG,OAAM,KAAK,GAAG,QAAQ,MAAM;AAC9C,MAAI,eAAe,EAAG,OAAM,KAAK,GAAG,YAAY,UAAU;AAC1D,MAAI,iBAAiB,EAAG,OAAM,KAAK,GAAG,cAAc,YAAY;AAEhE,QAAM,iBAAiB,WAAW,eAAe;AACjD,MAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,MACE,OAAO,cAAc,wBAAwB,mBAAmB,IAAI,KAAK,GAAG,SAAS,YAAY,KAAK,MAAM,CAAC,eAAe,WAAW,gBAAgB;AAAA,IACzJ;AAAA,EACF,OAAO;AACL;AAAA,MACE,oBAAoB,QAAQ,MAAM,wBAAwB,QAAQ,WAAW,IAAI,KAAK,GAAG,SAAS,YAAY,KAAK,MAAM,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,WAAW,gBAAgB;AAAA,IAChL;AAAA,EACF;AACF;AAEA,eAAe,kBACb,KACA,MACA,OACkC;AAClC,MAAI,0BAA0B,KAAK,IAAI,GAAG;AACxC,UAAM,CAAC,GAAG,GAAG,MAAM,IAAI,KAAK,MAAM,GAAG;AACrC,QAAI,UAAU,QAAW;AACvB,aAAO,CAAC,GAAG,OAAO,KAAK,GAAG,CAAC;AAAA,IAC7B,OAAO;AACL,YAAM,IAAI,MAAM;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB;AAAA,wBAAsM,IAAI,IAAI,KAAK;AAAA,MACrO,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,CAAC,MAAM,KAAK;AACrB;AAEA,sBAAsB,yBACpB,KACA,YAIA,MACA;AACA,QAAM,SAAS,MAAM,mBAAmB,KAAK,YAAY,IAAI;AAC7D,MAAI,WAAW,MAAM;AACnB,eAAW,yBAAyB,IAAI,cAAc;AACtD;AAAA,EACF;AACA,YAAU,GAAG,MAAM,EAAE;AACvB;AAEA,sBAAsB,mBACpB,KACA,YAIA,MACwB;AACxB,QAAM,SAAU,MAAM,eAAe,KAAK;AAAA,IACxC,GAAG;AAAA,IACH,cAAc;AAAA,IACd,eAAe;AAAA,IACf,MAAM,EAAE,KAAK;AAAA,EACf,CAAC;AACD,SAAO,WAAW,OAAO,OAAO,OAAO;AACzC;AAEA,sBAAsB,sBACpB,KACA,YAKA,MACA;AACA,QAAM,+BAA+B,KAAK,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC;AAChE;AAAA,IACE,sBAAsB,YAAY,KAAK,IAAI,CAAC,GAAG,WAAW,gBAAgB;AAAA,EAC5E;AACF;AAEA,eAAe,WACb,KACA,YAImB;AACnB,SAAQ,MAAM,eAAe,KAAK;AAAA,IAChC,GAAG;AAAA,IACH,cAAc;AAAA,IACd,eAAe;AAAA,IACf,MAAM,CAAC;AAAA,EACT,CAAC;AACH;AAEA,sBAAsB,oBACpB,KACA,YAIA;AACA,QAAM,OAAO,MAAM,WAAW,KAAK,UAAU;AAC7C,MAAI,KAAK,WAAW,GAAG;AACrB,eAAW,+BAA+B;AAC1C;AAAA,EACF;AACA,aAAW,EAAE,MAAM,MAAM,KAAK,MAAM;AAClC,UAAM,EAAE,WAAW,QAAQ,IAAI,yBAAyB,KAAK;AAC7D,QAAI,SAAS;AACX,iBAAW,YAAY,IAAI,MAAM,OAAO,EAAE;AAAA,IAC5C;AACA,cAAU,GAAG,IAAI,IAAI,SAAS,EAAE;AAAA,EAClC;AACF;AAYA,sBAAsB,+BACpB,KACA,YAKA,SACA;AACA,QAAM,QAAQ,gBAAgB,KAAK,UAAU;AAC7C,MAAI;AACF,UAAM,MAAM,qCAAqC;AAAA,MAC/C,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAChC,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,SAAS,GAAG;AACV,WAAO,MAAM,uBAAuB,KAAK,CAAC;AAAA,EAC5C;AACF;",
6
6
  "names": []
7
7
  }
@@ -281,7 +281,7 @@ export async function detectSuspiciousEnvironmentVariables(ctx, ignoreSuspicious
281
281
  }
282
282
  }
283
283
  export function getBuildEnvironment() {
284
- return process.env.VERCEL ? "Vercel" : process.env.NETLIFY ? "Netlify" : false;
284
+ return process.env.VERCEL ? "Vercel" : process.env.NETLIFY ? "Netlify" : process.env.CF_PAGES || process.env.WORKERS_CI ? "Cloudflare" : false;
285
285
  }
286
286
  export function gitBranchFromEnvironment() {
287
287
  if (process.env.VERCEL) {
@@ -290,6 +290,9 @@ export function gitBranchFromEnvironment() {
290
290
  if (process.env.NETLIFY) {
291
291
  return process.env.HEAD ?? null;
292
292
  }
293
+ if (process.env.CF_PAGES || process.env.WORKERS_CI) {
294
+ return process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH ?? null;
295
+ }
293
296
  if (process.env.CI) {
294
297
  return process.env.GITHUB_HEAD_REF ?? process.env.CI_COMMIT_REF_NAME ?? null;
295
298
  }
@@ -302,6 +305,10 @@ export function isNonProdBuildEnvironment() {
302
305
  if (process.env.NETLIFY) {
303
306
  return process.env.CONTEXT !== "production";
304
307
  }
308
+ if (process.env.CF_PAGES || process.env.WORKERS_CI) {
309
+ const branch = process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH;
310
+ return branch !== "main";
311
+ }
305
312
  return false;
306
313
  }
307
314
  //# sourceMappingURL=envvars.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/envvars.ts"],
4
- "sourcesContent": ["/**\n * Help the developer store the CONVEX_URL environment variable.\n */\nimport { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\n\nimport { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport { loadPackageJson } from \"./utils/utils.js\";\n\nconst _FRAMEWORKS = [\n \"create-react-app\",\n \"Next.js\",\n \"Vite\",\n \"Remix\",\n \"SvelteKit\",\n \"Expo\",\n \"TanStackStart\",\n] as const;\ntype Framework = (typeof _FRAMEWORKS)[number];\n\n/**\n * A configuration for writing the actual (framework specific) `CONVEX_URL`\n * and `CONVEX_SITE_URL` environment variables to a \".env\" type file.\n *\n * May be `null` if there was an error determining any of the field values.\n */\ntype EnvFileUrlConfig = {\n /** The name of the file - typically `.env.local` */\n envFile: string;\n /**\n * The framework specific `CONVEX_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n convexUrlEnvVar: string | null;\n /**\n * The framework specific `CONVEX_SITE_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n siteUrlEnvVar: string | null;\n /** Existing content loaded from the `envFile`, if it exists */\n existingFileContent: string | null;\n} | null;\n\nexport async function writeUrlsToEnvFile(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const envFileConfig = await loadEnvFileUrlConfig(ctx, options);\n\n if (envFileConfig === null) {\n return null;\n }\n\n const { envFile, convexUrlEnvVar, siteUrlEnvVar, existingFileContent } =\n envFileConfig;\n let updatedFileContent: string | null = null;\n if (convexUrlEnvVar) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent,\n envVarName: convexUrlEnvVar,\n envVarValue: options.convexUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (siteUrlEnvVar && options.siteUrl) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent: updatedFileContent ?? existingFileContent,\n envVarName: siteUrlEnvVar,\n envVarValue: options.siteUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (updatedFileContent) {\n ctx.fs.writeUtf8File(envFile, updatedFileContent);\n }\n\n return envFileConfig;\n}\n\nexport function changedEnvVarFile({\n existingFileContent,\n envVarName,\n envVarValue,\n commentAfterValue,\n commentOnPreviousLine,\n}: {\n existingFileContent: string | null;\n envVarName: string;\n envVarValue: string;\n commentAfterValue: string | null;\n commentOnPreviousLine: string | null;\n}): string | null {\n const varAssignment = `${envVarName}=${envVarValue}${\n commentAfterValue === null ? \"\" : ` # ${commentAfterValue}`\n }`;\n const commentOnPreviousLineWithLineBreak =\n commentOnPreviousLine === null ? \"\" : `${commentOnPreviousLine}\\n`;\n if (existingFileContent === null) {\n return `${commentOnPreviousLineWithLineBreak}${varAssignment}\\n`;\n }\n const config = dotenv.parse(existingFileContent);\n const existing = config[envVarName];\n if (existing === envVarValue) {\n return null;\n }\n if (existing !== undefined) {\n return existingFileContent.replace(\n getEnvVarRegex(envVarName),\n `${varAssignment}`,\n );\n } else {\n const doubleLineBreak = existingFileContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return (\n existingFileContent +\n doubleLineBreak +\n commentOnPreviousLineWithLineBreak +\n varAssignment +\n \"\\n\"\n );\n }\n}\n\nexport function getEnvVarRegex(envVarName: string) {\n return new RegExp(`^${envVarName}.*$`, \"m\");\n}\n\nexport async function suggestedEnvVarNames(ctx: Context): Promise<{\n detectedFramework?: Framework;\n convexUrlEnvVar: ConvexUrlEnvVar;\n convexSiteEnvVar: ConvexSiteUrlEnvVar;\n frontendDevUrl?: string;\n publicPrefix?: string;\n}> {\n // no package.json, that's fine, just guess\n if (!ctx.fs.exists(\"package.json\")) {\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n }\n\n const packages = await loadPackageJson(ctx);\n\n // Is it create-react-app?\n const isCreateReactApp = \"react-scripts\" in packages;\n if (isCreateReactApp) {\n return {\n detectedFramework: \"create-react-app\",\n convexUrlEnvVar: \"REACT_APP_CONVEX_URL\",\n convexSiteEnvVar: \"REACT_APP_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"REACT_APP_\",\n };\n }\n\n const isNextJs = \"next\" in packages;\n if (isNextJs) {\n return {\n detectedFramework: \"Next.js\",\n convexUrlEnvVar: \"NEXT_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"NEXT_PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"NEXT_PUBLIC_\",\n };\n }\n\n const isExpo = \"expo\" in packages;\n if (isExpo) {\n return {\n detectedFramework: \"Expo\",\n convexUrlEnvVar: \"EXPO_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n publicPrefix: \"EXPO_PUBLIC_\",\n };\n }\n\n const isSvelteKit = \"@sveltejs/kit\" in packages;\n if (isSvelteKit) {\n return {\n detectedFramework: \"SvelteKit\",\n convexUrlEnvVar: \"PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"PUBLIC_\",\n };\n }\n\n // TanStackStart currently supports VITE_FOO for browser-side envvars.\n const isTanStackStart =\n \"@tanstack/start\" in packages || \"@tanstack/react-start\" in packages;\n\n if (isTanStackStart) {\n return {\n detectedFramework: \"TanStackStart\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // Vite is a dependency of a lot of things; vite appearing in dependencies is not a strong indicator.\n const isVite = \"vite\" in packages;\n\n if (isVite) {\n return {\n detectedFramework: \"Vite\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // We detect Remix after Vite because when using Remix as a plugin of Vite\n // (Remix Vite), we want to use Vite-style environment variables.\n const isRemix = \"@remix-run/dev\" in packages;\n if (isRemix) {\n return {\n detectedFramework: \"Remix\",\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n };\n }\n\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n}\n\nasync function loadEnvFileUrlConfig(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const { detectedFramework, convexUrlEnvVar, convexSiteEnvVar } =\n await suggestedEnvVarNames(ctx);\n\n const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);\n\n if (!existing) {\n return {\n envFile,\n convexUrlEnvVar,\n siteUrlEnvVar: convexSiteEnvVar,\n existingFileContent: null,\n };\n }\n\n const existingFileContent = ctx.fs.readUtf8File(envFile);\n const config = dotenv.parse(existingFileContent);\n\n const resolvedConvexUrlEnvVar = resolveEnvVarName(\n convexUrlEnvVar,\n options.convexUrl,\n envFile,\n config,\n EXPECTED_CONVEX_URL_NAMES,\n );\n const resolvedSiteUrlEnvVar = resolveEnvVarName(\n convexSiteEnvVar,\n options.siteUrl ?? \"\",\n envFile,\n config,\n EXPECTED_SITE_URL_NAMES,\n );\n if (\n resolvedConvexUrlEnvVar.kind === \"invalid\" ||\n resolvedSiteUrlEnvVar.kind === \"invalid\"\n ) {\n return null;\n }\n return {\n envFile,\n convexUrlEnvVar: resolvedConvexUrlEnvVar.envVarName,\n siteUrlEnvVar: resolvedSiteUrlEnvVar.envVarName,\n existingFileContent,\n };\n}\n\nfunction resolveEnvVarName(\n envVarName: string,\n envVarValue: string,\n envFile: string,\n config: dotenv.DotenvParseOutput,\n expectedNames: Set<string>,\n):\n | {\n kind: \"invalid\";\n }\n | {\n kind: \"valid\";\n envVarName: string | null;\n } {\n const matching = Object.keys(config).filter((key) => expectedNames.has(key));\n if (matching.length > 1) {\n logWarning(\n chalkStderr.yellow(\n `Found multiple ${envVarName} environment variables in ${envFile} so cannot update automatically.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n if (matching.length === 1) {\n const [existingEnvVarName, oldValue] = [matching[0], config[matching[0]]];\n if (oldValue === envVarValue) {\n // Set envVarName to null to indicate that it shouldn't be updated.\n return { kind: \"valid\", envVarName: null };\n }\n if (\n oldValue !== \"\" &&\n Object.values(config).filter((v) => v === oldValue).length !== 1\n ) {\n logWarning(\n chalkStderr.yellow(\n `Can't safely modify ${envFile} for ${envVarName}, please edit manually.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n return { kind: \"valid\", envVarName: existingEnvVarName };\n }\n return { kind: \"valid\", envVarName };\n}\n\nfunction suggestedDevEnvFile(\n ctx: Context,\n framework?: Framework,\n): {\n existing: boolean;\n envFile: string;\n} {\n // If a .env.local file exists, that's unequivocally the right file\n if (ctx.fs.exists(\".env.local\")) {\n return {\n existing: true,\n envFile: \".env.local\",\n };\n }\n\n // Remix is on team \"don't commit the .env file,\" so .env is for dev.\n if (framework === \"Remix\") {\n return {\n existing: ctx.fs.exists(\".env\"),\n envFile: \".env\",\n };\n }\n\n // The most dev-looking env file that exists, or .env.local\n return {\n existing: ctx.fs.exists(\".env.local\"),\n envFile: \".env.local\",\n };\n}\n\nexport const EXPECTED_CONVEX_URL_NAMES = new Set([\n \"CONVEX_URL\" as const,\n \"PUBLIC_CONVEX_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_URL\" as const,\n \"VITE_CONVEX_URL\" as const,\n \"REACT_APP_CONVEX_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_URL\" as const,\n]);\ntype ConvexUrlEnvVar =\n typeof EXPECTED_CONVEX_URL_NAMES extends Set<infer T> ? T : never;\n\nexport const EXPECTED_SITE_URL_NAMES = new Set([\n \"CONVEX_SITE_URL\" as const,\n \"PUBLIC_CONVEX_SITE_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_SITE_URL\" as const,\n \"VITE_CONVEX_SITE_URL\" as const,\n \"REACT_APP_CONVEX_SITE_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_SITE_URL\" as const,\n]);\ntype ConvexSiteUrlEnvVar =\n typeof EXPECTED_SITE_URL_NAMES extends Set<infer T> ? T : never;\n\n// Crash or warn on\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// which parses as\n// CONVEX_DEPLOY_KEY=project:me:new-project | eyABCD0='' npx convex\n// when what was intended was\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// This only fails so catastrophically when the key ends with `=`.\nexport async function detectSuspiciousEnvironmentVariables(\n ctx: Context,\n ignoreSuspiciousEnvVars = false,\n) {\n for (const [key, value] of Object.entries(process.env)) {\n if (value === \"\" && key.startsWith(\"ey\")) {\n try {\n // add a \"=\" to the end and try to base64 decode (expected format of Convex keys)\n const decoded = JSON.parse(\n Buffer.from(key + \"=\", \"base64\").toString(\"utf8\"),\n );\n // Only parseable v2 tokens to be sure this is a Convex token before complaining.\n if (!(\"v2\" in decoded)) {\n continue;\n }\n } catch {\n continue;\n }\n\n if (ignoreSuspiciousEnvVars) {\n logWarning(\n `ignoring suspicious environment variable ${key}, did you mean to use quotes like CONVEX_DEPLOY_KEY='...'?`,\n );\n } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Quotes are required around environment variable values by your shell: CONVEX_DEPLOY_KEY='project:name:project|${key.slice(0, 4)}...${key.slice(key.length - 4)}=' npx convex dev`,\n });\n }\n }\n }\n}\n\nexport function getBuildEnvironment(): string | false {\n return process.env.VERCEL\n ? \"Vercel\"\n : process.env.NETLIFY\n ? \"Netlify\"\n : false;\n}\n\nexport function gitBranchFromEnvironment(): string | null {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_GIT_COMMIT_REF ?? null;\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.HEAD ?? null;\n }\n\n if (process.env.CI) {\n // https://docs.github.com/en/actions/learn-github-actions/variables\n // https://docs.gitlab.com/ee/ci/variables/predefined_variables.html\n return (\n process.env.GITHUB_HEAD_REF ?? process.env.CI_COMMIT_REF_NAME ?? null\n );\n }\n\n return null;\n}\n\nexport function isNonProdBuildEnvironment(): boolean {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_ENV !== \"production\";\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.CONTEXT !== \"production\";\n }\n return false;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Help the developer store the CONVEX_URL environment variable.\n */\nimport { chalkStderr } from \"chalk\";\nimport * as dotenv from \"dotenv\";\n\nimport { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport { loadPackageJson } from \"./utils/utils.js\";\n\nconst _FRAMEWORKS = [\n \"create-react-app\",\n \"Next.js\",\n \"Vite\",\n \"Remix\",\n \"SvelteKit\",\n \"Expo\",\n \"TanStackStart\",\n] as const;\ntype Framework = (typeof _FRAMEWORKS)[number];\n\n/**\n * A configuration for writing the actual (framework specific) `CONVEX_URL`\n * and `CONVEX_SITE_URL` environment variables to a \".env\" type file.\n *\n * May be `null` if there was an error determining any of the field values.\n */\ntype EnvFileUrlConfig = {\n /** The name of the file - typically `.env.local` */\n envFile: string;\n /**\n * The framework specific `CONVEX_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n convexUrlEnvVar: string | null;\n /**\n * The framework specific `CONVEX_SITE_URL`\n *\n * If `null`, ignore and don't update that environment variable.\n */\n siteUrlEnvVar: string | null;\n /** Existing content loaded from the `envFile`, if it exists */\n existingFileContent: string | null;\n} | null;\n\nexport async function writeUrlsToEnvFile(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const envFileConfig = await loadEnvFileUrlConfig(ctx, options);\n\n if (envFileConfig === null) {\n return null;\n }\n\n const { envFile, convexUrlEnvVar, siteUrlEnvVar, existingFileContent } =\n envFileConfig;\n let updatedFileContent: string | null = null;\n if (convexUrlEnvVar) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent,\n envVarName: convexUrlEnvVar,\n envVarValue: options.convexUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (siteUrlEnvVar && options.siteUrl) {\n updatedFileContent = changedEnvVarFile({\n existingFileContent: updatedFileContent ?? existingFileContent,\n envVarName: siteUrlEnvVar,\n envVarValue: options.siteUrl,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n }\n if (updatedFileContent) {\n ctx.fs.writeUtf8File(envFile, updatedFileContent);\n }\n\n return envFileConfig;\n}\n\nexport function changedEnvVarFile({\n existingFileContent,\n envVarName,\n envVarValue,\n commentAfterValue,\n commentOnPreviousLine,\n}: {\n existingFileContent: string | null;\n envVarName: string;\n envVarValue: string;\n commentAfterValue: string | null;\n commentOnPreviousLine: string | null;\n}): string | null {\n const varAssignment = `${envVarName}=${envVarValue}${\n commentAfterValue === null ? \"\" : ` # ${commentAfterValue}`\n }`;\n const commentOnPreviousLineWithLineBreak =\n commentOnPreviousLine === null ? \"\" : `${commentOnPreviousLine}\\n`;\n if (existingFileContent === null) {\n return `${commentOnPreviousLineWithLineBreak}${varAssignment}\\n`;\n }\n const config = dotenv.parse(existingFileContent);\n const existing = config[envVarName];\n if (existing === envVarValue) {\n return null;\n }\n if (existing !== undefined) {\n return existingFileContent.replace(\n getEnvVarRegex(envVarName),\n `${varAssignment}`,\n );\n } else {\n const doubleLineBreak = existingFileContent.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return (\n existingFileContent +\n doubleLineBreak +\n commentOnPreviousLineWithLineBreak +\n varAssignment +\n \"\\n\"\n );\n }\n}\n\nexport function getEnvVarRegex(envVarName: string) {\n return new RegExp(`^${envVarName}.*$`, \"m\");\n}\n\nexport async function suggestedEnvVarNames(ctx: Context): Promise<{\n detectedFramework?: Framework;\n convexUrlEnvVar: ConvexUrlEnvVar;\n convexSiteEnvVar: ConvexSiteUrlEnvVar;\n frontendDevUrl?: string;\n publicPrefix?: string;\n}> {\n // no package.json, that's fine, just guess\n if (!ctx.fs.exists(\"package.json\")) {\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n }\n\n const packages = await loadPackageJson(ctx);\n\n // Is it create-react-app?\n const isCreateReactApp = \"react-scripts\" in packages;\n if (isCreateReactApp) {\n return {\n detectedFramework: \"create-react-app\",\n convexUrlEnvVar: \"REACT_APP_CONVEX_URL\",\n convexSiteEnvVar: \"REACT_APP_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"REACT_APP_\",\n };\n }\n\n const isNextJs = \"next\" in packages;\n if (isNextJs) {\n return {\n detectedFramework: \"Next.js\",\n convexUrlEnvVar: \"NEXT_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"NEXT_PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"NEXT_PUBLIC_\",\n };\n }\n\n const isExpo = \"expo\" in packages;\n if (isExpo) {\n return {\n detectedFramework: \"Expo\",\n convexUrlEnvVar: \"EXPO_PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n publicPrefix: \"EXPO_PUBLIC_\",\n };\n }\n\n const isSvelteKit = \"@sveltejs/kit\" in packages;\n if (isSvelteKit) {\n return {\n detectedFramework: \"SvelteKit\",\n convexUrlEnvVar: \"PUBLIC_CONVEX_URL\",\n convexSiteEnvVar: \"PUBLIC_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"PUBLIC_\",\n };\n }\n\n // TanStackStart currently supports VITE_FOO for browser-side envvars.\n const isTanStackStart =\n \"@tanstack/start\" in packages || \"@tanstack/react-start\" in packages;\n\n if (isTanStackStart) {\n return {\n detectedFramework: \"TanStackStart\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // Vite is a dependency of a lot of things; vite appearing in dependencies is not a strong indicator.\n const isVite = \"vite\" in packages;\n\n if (isVite) {\n return {\n detectedFramework: \"Vite\",\n convexUrlEnvVar: \"VITE_CONVEX_URL\",\n convexSiteEnvVar: \"VITE_CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"VITE_\",\n };\n }\n\n // We detect Remix after Vite because when using Remix as a plugin of Vite\n // (Remix Vite), we want to use Vite-style environment variables.\n const isRemix = \"@remix-run/dev\" in packages;\n if (isRemix) {\n return {\n detectedFramework: \"Remix\",\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n };\n }\n\n return {\n convexUrlEnvVar: \"CONVEX_URL\",\n convexSiteEnvVar: \"CONVEX_SITE_URL\",\n };\n}\n\nasync function loadEnvFileUrlConfig(\n ctx: Context,\n options: {\n convexUrl: string;\n siteUrl?: string | null | undefined;\n },\n): Promise<EnvFileUrlConfig> {\n const { detectedFramework, convexUrlEnvVar, convexSiteEnvVar } =\n await suggestedEnvVarNames(ctx);\n\n const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);\n\n if (!existing) {\n return {\n envFile,\n convexUrlEnvVar,\n siteUrlEnvVar: convexSiteEnvVar,\n existingFileContent: null,\n };\n }\n\n const existingFileContent = ctx.fs.readUtf8File(envFile);\n const config = dotenv.parse(existingFileContent);\n\n const resolvedConvexUrlEnvVar = resolveEnvVarName(\n convexUrlEnvVar,\n options.convexUrl,\n envFile,\n config,\n EXPECTED_CONVEX_URL_NAMES,\n );\n const resolvedSiteUrlEnvVar = resolveEnvVarName(\n convexSiteEnvVar,\n options.siteUrl ?? \"\",\n envFile,\n config,\n EXPECTED_SITE_URL_NAMES,\n );\n if (\n resolvedConvexUrlEnvVar.kind === \"invalid\" ||\n resolvedSiteUrlEnvVar.kind === \"invalid\"\n ) {\n return null;\n }\n return {\n envFile,\n convexUrlEnvVar: resolvedConvexUrlEnvVar.envVarName,\n siteUrlEnvVar: resolvedSiteUrlEnvVar.envVarName,\n existingFileContent,\n };\n}\n\nfunction resolveEnvVarName(\n envVarName: string,\n envVarValue: string,\n envFile: string,\n config: dotenv.DotenvParseOutput,\n expectedNames: Set<string>,\n):\n | {\n kind: \"invalid\";\n }\n | {\n kind: \"valid\";\n envVarName: string | null;\n } {\n const matching = Object.keys(config).filter((key) => expectedNames.has(key));\n if (matching.length > 1) {\n logWarning(\n chalkStderr.yellow(\n `Found multiple ${envVarName} environment variables in ${envFile} so cannot update automatically.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n if (matching.length === 1) {\n const [existingEnvVarName, oldValue] = [matching[0], config[matching[0]]];\n if (oldValue === envVarValue) {\n // Set envVarName to null to indicate that it shouldn't be updated.\n return { kind: \"valid\", envVarName: null };\n }\n if (\n oldValue !== \"\" &&\n Object.values(config).filter((v) => v === oldValue).length !== 1\n ) {\n logWarning(\n chalkStderr.yellow(\n `Can't safely modify ${envFile} for ${envVarName}, please edit manually.`,\n ),\n );\n return { kind: \"invalid\" };\n }\n return { kind: \"valid\", envVarName: existingEnvVarName };\n }\n return { kind: \"valid\", envVarName };\n}\n\nfunction suggestedDevEnvFile(\n ctx: Context,\n framework?: Framework,\n): {\n existing: boolean;\n envFile: string;\n} {\n // If a .env.local file exists, that's unequivocally the right file\n if (ctx.fs.exists(\".env.local\")) {\n return {\n existing: true,\n envFile: \".env.local\",\n };\n }\n\n // Remix is on team \"don't commit the .env file,\" so .env is for dev.\n if (framework === \"Remix\") {\n return {\n existing: ctx.fs.exists(\".env\"),\n envFile: \".env\",\n };\n }\n\n // The most dev-looking env file that exists, or .env.local\n return {\n existing: ctx.fs.exists(\".env.local\"),\n envFile: \".env.local\",\n };\n}\n\nexport const EXPECTED_CONVEX_URL_NAMES = new Set([\n \"CONVEX_URL\" as const,\n \"PUBLIC_CONVEX_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_URL\" as const,\n \"VITE_CONVEX_URL\" as const,\n \"REACT_APP_CONVEX_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_URL\" as const,\n]);\ntype ConvexUrlEnvVar =\n typeof EXPECTED_CONVEX_URL_NAMES extends Set<infer T> ? T : never;\n\nexport const EXPECTED_SITE_URL_NAMES = new Set([\n \"CONVEX_SITE_URL\" as const,\n \"PUBLIC_CONVEX_SITE_URL\" as const,\n \"NEXT_PUBLIC_CONVEX_SITE_URL\" as const,\n \"VITE_CONVEX_SITE_URL\" as const,\n \"REACT_APP_CONVEX_SITE_URL\" as const,\n \"EXPO_PUBLIC_CONVEX_SITE_URL\" as const,\n]);\ntype ConvexSiteUrlEnvVar =\n typeof EXPECTED_SITE_URL_NAMES extends Set<infer T> ? T : never;\n\n// Crash or warn on\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// which parses as\n// CONVEX_DEPLOY_KEY=project:me:new-project | eyABCD0='' npx convex\n// when what was intended was\n// CONVEX_DEPLOY_KEY=project:me:new-project|eyABCD0= npx convex\n// This only fails so catastrophically when the key ends with `=`.\nexport async function detectSuspiciousEnvironmentVariables(\n ctx: Context,\n ignoreSuspiciousEnvVars = false,\n) {\n for (const [key, value] of Object.entries(process.env)) {\n if (value === \"\" && key.startsWith(\"ey\")) {\n try {\n // add a \"=\" to the end and try to base64 decode (expected format of Convex keys)\n const decoded = JSON.parse(\n Buffer.from(key + \"=\", \"base64\").toString(\"utf8\"),\n );\n // Only parseable v2 tokens to be sure this is a Convex token before complaining.\n if (!(\"v2\" in decoded)) {\n continue;\n }\n } catch {\n continue;\n }\n\n if (ignoreSuspiciousEnvVars) {\n logWarning(\n `ignoring suspicious environment variable ${key}, did you mean to use quotes like CONVEX_DEPLOY_KEY='...'?`,\n );\n } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Quotes are required around environment variable values by your shell: CONVEX_DEPLOY_KEY='project:name:project|${key.slice(0, 4)}...${key.slice(key.length - 4)}=' npx convex dev`,\n });\n }\n }\n }\n}\n\nexport function getBuildEnvironment(): string | false {\n return process.env.VERCEL\n ? \"Vercel\"\n : process.env.NETLIFY\n ? \"Netlify\"\n : process.env.CF_PAGES || process.env.WORKERS_CI\n ? \"Cloudflare\"\n : false;\n}\n\nexport function gitBranchFromEnvironment(): string | null {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_GIT_COMMIT_REF ?? null;\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.HEAD ?? null;\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n return process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH ?? null;\n }\n\n if (process.env.CI) {\n // https://docs.github.com/en/actions/learn-github-actions/variables\n // https://docs.gitlab.com/ee/ci/variables/predefined_variables.html\n return (\n process.env.GITHUB_HEAD_REF ?? process.env.CI_COMMIT_REF_NAME ?? null\n );\n }\n\n return null;\n}\n\nexport function isNonProdBuildEnvironment(): boolean {\n if (process.env.VERCEL) {\n // https://vercel.com/docs/projects/environment-variables/system-environment-variables\n return process.env.VERCEL_ENV !== \"production\";\n }\n if (process.env.NETLIFY) {\n // https://docs.netlify.com/configure-builds/environment-variables/\n return process.env.CONTEXT !== \"production\";\n }\n if (process.env.CF_PAGES || process.env.WORKERS_CI) {\n // https://developers.cloudflare.com/pages/configuration/build-configuration/#environment-variables\n // https://developers.cloudflare.com/workers/ci-cd/builds/configuration/#environment-variables\n // Branch !== \"main\" is the closest heuristic; Cloudflare Pages\n // does not expose a dedicated production/preview flag.\n const branch = process.env.CF_PAGES_BRANCH ?? process.env.WORKERS_CI_BRANCH;\n return branch !== \"main\";\n }\n return false;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ const PARSE_ERROR_MESSAGE = `Supported formats:
3
+ "none" \u2014 no expiration
4
+ "in 7 days" \u2014 relative (minutes, hours, days)
5
+ "2026-04-01T00:00:00Z" \u2014 UTC datetime
6
+ "1711828382" \u2014 Unix timestamp (seconds)
7
+ "1711828382000" \u2014 Unix timestamp (milliseconds)`;
8
+ const UNIT_MS = {
9
+ minute: 60 * 1e3,
10
+ hour: 60 * 60 * 1e3,
11
+ day: 24 * 60 * 60 * 1e3
12
+ };
13
+ export function parseExpiration(input) {
14
+ const trimmed = input.trim();
15
+ if (trimmed.toLowerCase() === "none") {
16
+ return { kind: "none" };
17
+ }
18
+ if (/^\d+$/.test(trimmed)) {
19
+ const n = Number(trimmed);
20
+ return {
21
+ kind: "absolute",
22
+ timestampMs: n < 1e12 ? n * 1e3 : n
23
+ // already milliseconds
24
+ };
25
+ }
26
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/.test(trimmed)) {
27
+ const date = new Date(trimmed);
28
+ if (isNaN(date.getTime())) {
29
+ return {
30
+ kind: "error",
31
+ message: `Invalid UTC datetime: "${trimmed}". ${PARSE_ERROR_MESSAGE}`
32
+ };
33
+ }
34
+ return { kind: "absolute", timestampMs: date.getTime() };
35
+ }
36
+ const relativeMatch = trimmed.match(/^in\s+(\d+)\s+(minute|hour|day)s?$/i);
37
+ if (relativeMatch) {
38
+ const amount = Number(relativeMatch[1]);
39
+ const unit = relativeMatch[2].toLowerCase();
40
+ return { kind: "relative", amount, unit };
41
+ }
42
+ return {
43
+ kind: "error",
44
+ message: `Invalid expiration format: "${trimmed}". ${PARSE_ERROR_MESSAGE}`
45
+ };
46
+ }
47
+ export function resolveExpiration(parsed, now) {
48
+ switch (parsed.kind) {
49
+ case "none":
50
+ return null;
51
+ case "absolute":
52
+ return parsed.timestampMs;
53
+ case "relative": {
54
+ const base = now ?? Date.now();
55
+ return base + parsed.amount * UNIT_MS[parsed.unit];
56
+ }
57
+ }
58
+ }
59
+ export function validateExpiration(timestampMs, now) {
60
+ const base = now ?? Date.now();
61
+ const thirtyMinutes = 30 * 60 * 1e3;
62
+ const oneYear = 365 * 24 * 60 * 60 * 1e3;
63
+ if (timestampMs <= base) {
64
+ return { kind: "error", message: "Expiration must be in the future." };
65
+ }
66
+ if (timestampMs - base < thirtyMinutes) {
67
+ return {
68
+ kind: "error",
69
+ message: "Expiration must be at least 30 minutes from now."
70
+ };
71
+ }
72
+ if (timestampMs - base > oneYear) {
73
+ return {
74
+ kind: "error",
75
+ message: "Expiration must be at most 1 year from now."
76
+ };
77
+ }
78
+ return { kind: "success" };
79
+ }
80
+ //# sourceMappingURL=expiration.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/lib/expiration.ts"],
4
+ "sourcesContent": ["type ParsedExpirationSuccess =\n | { kind: \"none\" }\n | { kind: \"absolute\"; timestampMs: number }\n | { kind: \"relative\"; amount: number; unit: \"minute\" | \"hour\" | \"day\" };\n\ntype ParsedExpiration =\n | ParsedExpirationSuccess\n | { kind: \"error\"; message: string };\n\nconst PARSE_ERROR_MESSAGE =\n `Supported formats:\\n` +\n ` \"none\" \u2014 no expiration\\n` +\n ` \"in 7 days\" \u2014 relative (minutes, hours, days)\\n` +\n ` \"2026-04-01T00:00:00Z\" \u2014 UTC datetime\\n` +\n ` \"1711828382\" \u2014 Unix timestamp (seconds)\\n` +\n ` \"1711828382000\" \u2014 Unix timestamp (milliseconds)`;\n\nconst UNIT_MS = {\n minute: 60 * 1000,\n hour: 60 * 60 * 1000,\n day: 24 * 60 * 60 * 1000,\n} as const;\n\n/**\n * Parse an expiration input string into a structured representation.\n * Does not depend on the current time.\n */\nexport function parseExpiration(input: string): ParsedExpiration {\n const trimmed = input.trim();\n\n if (trimmed.toLowerCase() === \"none\") {\n return { kind: \"none\" };\n }\n\n // All digits \u2192 Unix timestamp\n if (/^\\d+$/.test(trimmed)) {\n const n = Number(trimmed);\n\n return {\n kind: \"absolute\",\n timestampMs:\n n < 1e12 // 1e12 milliseconds is a date in 2001 \u2192 unambiguous\n ? n * 1000 // seconds \u2192 convert to ms\n : n, // already milliseconds\n };\n }\n\n // UTC datetime: \"2026-04-01T00:00:00Z\"\n if (/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/.test(trimmed)) {\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) {\n return {\n kind: \"error\",\n message: `Invalid UTC datetime: \"${trimmed}\". ${PARSE_ERROR_MESSAGE}`,\n };\n }\n return { kind: \"absolute\", timestampMs: date.getTime() };\n }\n\n // Relative: \"in 3 hours\", \"in 1 day\", \"in 45 minutes\"\n const relativeMatch = trimmed.match(/^in\\s+(\\d+)\\s+(minute|hour|day)s?$/i);\n if (relativeMatch) {\n const amount = Number(relativeMatch[1]);\n const unit = relativeMatch[2].toLowerCase() as \"minute\" | \"hour\" | \"day\";\n return { kind: \"relative\", amount, unit };\n }\n\n return {\n kind: \"error\",\n message: `Invalid expiration format: \"${trimmed}\". ${PARSE_ERROR_MESSAGE}`,\n };\n}\n\n/**\n * Resolve a parsed expiration into a timestamp in milliseconds, or null for \"none\".\n */\nexport function resolveExpiration(\n parsed: ParsedExpirationSuccess,\n now?: number,\n): number | null {\n switch (parsed.kind) {\n case \"none\":\n return null;\n case \"absolute\":\n return parsed.timestampMs;\n case \"relative\": {\n const base = now ?? Date.now();\n return base + parsed.amount * UNIT_MS[parsed.unit];\n }\n }\n}\n\ntype ValidationResult =\n | { kind: \"success\" }\n | { kind: \"error\"; message: string };\n\n/**\n * Validate that a resolved expiration timestamp is acceptable.\n */\nexport function validateExpiration(\n timestampMs: number,\n now?: number,\n): ValidationResult {\n const base = now ?? Date.now();\n const thirtyMinutes = 30 * 60 * 1000;\n const oneYear = 365 * 24 * 60 * 60 * 1000;\n\n if (timestampMs <= base) {\n return { kind: \"error\", message: \"Expiration must be in the future.\" };\n }\n if (timestampMs - base < thirtyMinutes) {\n return {\n kind: \"error\",\n message: \"Expiration must be at least 30 minutes from now.\",\n };\n }\n if (timestampMs - base > oneYear) {\n return {\n kind: \"error\",\n message: \"Expiration must be at most 1 year from now.\",\n };\n }\n return { kind: \"success\" };\n}\n"],
5
+ "mappings": ";AASA,MAAM,sBACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAOF,MAAM,UAAU;AAAA,EACd,QAAQ,KAAK;AAAA,EACb,MAAM,KAAK,KAAK;AAAA,EAChB,KAAK,KAAK,KAAK,KAAK;AACtB;AAMO,gBAAS,gBAAgB,OAAiC;AAC/D,QAAM,UAAU,MAAM,KAAK;AAE3B,MAAI,QAAQ,YAAY,MAAM,QAAQ;AACpC,WAAO,EAAE,MAAM,OAAO;AAAA,EACxB;AAGA,MAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,UAAM,IAAI,OAAO,OAAO;AAExB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE,IAAI,OACA,IAAI,MACJ;AAAA;AAAA,IACR;AAAA,EACF;AAGA,MAAI,yCAAyC,KAAK,OAAO,GAAG;AAC1D,UAAM,OAAO,IAAI,KAAK,OAAO;AAC7B,QAAI,MAAM,KAAK,QAAQ,CAAC,GAAG;AACzB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,0BAA0B,OAAO,MAAM,mBAAmB;AAAA,MACrE;AAAA,IACF;AACA,WAAO,EAAE,MAAM,YAAY,aAAa,KAAK,QAAQ,EAAE;AAAA,EACzD;AAGA,QAAM,gBAAgB,QAAQ,MAAM,qCAAqC;AACzE,MAAI,eAAe;AACjB,UAAM,SAAS,OAAO,cAAc,CAAC,CAAC;AACtC,UAAM,OAAO,cAAc,CAAC,EAAE,YAAY;AAC1C,WAAO,EAAE,MAAM,YAAY,QAAQ,KAAK;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,+BAA+B,OAAO,MAAM,mBAAmB;AAAA,EAC1E;AACF;AAKO,gBAAS,kBACd,QACA,KACe;AACf,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK,YAAY;AACf,YAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,aAAO,OAAO,OAAO,SAAS,QAAQ,OAAO,IAAI;AAAA,IACnD;AAAA,EACF;AACF;AASO,gBAAS,mBACd,aACA,KACkB;AAClB,QAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,QAAM,gBAAgB,KAAK,KAAK;AAChC,QAAM,UAAU,MAAM,KAAK,KAAK,KAAK;AAErC,MAAI,eAAe,MAAM;AACvB,WAAO,EAAE,MAAM,SAAS,SAAS,oCAAoC;AAAA,EACvE;AACA,MAAI,cAAc,OAAO,eAAe;AACtC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,cAAc,OAAO,SAAS;AAChC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO,EAAE,MAAM,UAAU;AAC3B;",
6
+ "names": []
7
+ }
@@ -10,6 +10,8 @@ export async function finalizeConfiguration(ctx, options) {
10
10
  });
11
11
  const isEnvFileConfigChanged = envFileConfig !== null && (envFileConfig.convexUrlEnvVar || envFileConfig.siteUrlEnvVar);
12
12
  if (isEnvFileConfigChanged) {
13
+ const deploymentEnvVarMessage = options.changedDeploymentEnvVar ? ` name as CONVEX_DEPLOYMENT
14
+ ` : "";
13
15
  const urlUpdateMessages = [];
14
16
  if (envFileConfig.convexUrlEnvVar) {
15
17
  urlUpdateMessages.push(
@@ -25,8 +27,7 @@ export async function finalizeConfiguration(ctx, options) {
25
27
  }
26
28
  logFinishedStep(
27
29
  `${messageForDeploymentType(options.deploymentType, options.url)} and saved its:
28
- name as CONVEX_DEPLOYMENT
29
- ` + urlUpdateMessages.join("") + ` to ${envFileConfig.envFile}`
30
+ ` + deploymentEnvVarMessage + urlUpdateMessages.join("") + ` to ${envFileConfig.envFile}`
30
31
  );
31
32
  } else if (options.changedDeploymentEnvVar) {
32
33
  logFinishedStep(
@@ -36,7 +37,7 @@ export async function finalizeConfiguration(ctx, options) {
36
37
  if (options.wroteToGitIgnore) {
37
38
  logMessage(chalkStderr.gray(` Added ".env.local" to .gitignore`));
38
39
  }
39
- if (options.deploymentType === "anonymous" && process.env.CONVEX_AGENT_MODE !== "anonymous") {
40
+ if (options.deploymentType === "anonymous" && process.env.CONVEX_AGENT_MODE !== "anonymous" && ctx.bigBrainAuth() === null) {
40
41
  logMessage(
41
42
  `Run \`npx convex login\` at any time to create an account and link this deployment.`
42
43
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/init.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logFinishedStep, logMessage } from \"../../bundler/log.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { writeUrlsToEnvFile } from \"./envvars.js\";\nimport { getDashboardUrl } from \"./dashboard.js\";\n\nexport async function finalizeConfiguration(\n ctx: Context,\n options: {\n functionsPath: string;\n deploymentType: DeploymentType;\n deploymentName: string;\n url: string;\n siteUrl: string | null | undefined;\n wroteToGitIgnore: boolean;\n changedDeploymentEnvVar: boolean;\n },\n) {\n const envFileConfig = await writeUrlsToEnvFile(ctx, {\n convexUrl: options.url,\n siteUrl: options.siteUrl,\n });\n const isEnvFileConfigChanged =\n envFileConfig !== null &&\n (envFileConfig.convexUrlEnvVar || envFileConfig.siteUrlEnvVar);\n\n if (isEnvFileConfigChanged) {\n const urlUpdateMessages = [];\n if (envFileConfig.convexUrlEnvVar) {\n urlUpdateMessages.push(\n ` client URL as ${envFileConfig.convexUrlEnvVar}\\n`,\n );\n }\n if (envFileConfig.siteUrlEnvVar) {\n urlUpdateMessages.push(\n ` HTTP actions URL as ${envFileConfig.siteUrlEnvVar}\\n`,\n );\n }\n logFinishedStep(\n `${messageForDeploymentType(options.deploymentType, options.url)} and saved its:\\n` +\n ` name as CONVEX_DEPLOYMENT\\n` +\n urlUpdateMessages.join(\"\") +\n ` to ${envFileConfig.envFile}`,\n );\n } else if (options.changedDeploymentEnvVar) {\n logFinishedStep(\n `${messageForDeploymentType(options.deploymentType, options.url)} and saved its name as CONVEX_DEPLOYMENT to .env.local`,\n );\n }\n if (options.wroteToGitIgnore) {\n logMessage(chalkStderr.gray(` Added \".env.local\" to .gitignore`));\n }\n if (\n options.deploymentType === \"anonymous\" &&\n process.env.CONVEX_AGENT_MODE !== \"anonymous\"\n ) {\n logMessage(\n `Run \\`npx convex login\\` at any time to create an account and link this deployment.`,\n );\n }\n\n const anyChanges =\n options.wroteToGitIgnore ||\n options.changedDeploymentEnvVar ||\n isEnvFileConfigChanged;\n if (anyChanges) {\n const dashboardUrl = await getDashboardUrl(ctx, {\n deploymentName: options.deploymentName,\n deploymentType: options.deploymentType,\n });\n logMessage(\n `\\nWrite your Convex functions in ${chalkStderr.bold(options.functionsPath)}\\n` +\n \"Give us feedback at https://convex.dev/community or support@convex.dev\\n\" +\n `View the Convex dashboard at ${dashboardUrl}\\n`,\n );\n }\n}\n\nfunction messageForDeploymentType(deploymentType: DeploymentType, url: string) {\n switch (deploymentType) {\n case \"anonymous\":\n return `Configured a local deployment for ${url}`;\n case \"local\":\n return `Configured a local deployment for ${url}`;\n case \"dev\":\n case \"prod\":\n case \"preview\":\n case \"custom\":\n return `Provisioned a ${deploymentType} deployment`;\n default: {\n deploymentType satisfies never;\n return `Provisioned a ${deploymentType as any} deployment`;\n }\n }\n}\n"],
5
- "mappings": ";AAAA,SAAS,mBAAmB;AAE5B,SAAS,iBAAiB,kBAAkB;AAE5C,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAEhC,sBAAsB,sBACpB,KACA,SASA;AACA,QAAM,gBAAgB,MAAM,mBAAmB,KAAK;AAAA,IAClD,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,EACnB,CAAC;AACD,QAAM,yBACJ,kBAAkB,SACjB,cAAc,mBAAmB,cAAc;AAElD,MAAI,wBAAwB;AAC1B,UAAM,oBAAoB,CAAC;AAC3B,QAAI,cAAc,iBAAiB;AACjC,wBAAkB;AAAA,QAChB,qBAAqB,cAAc,eAAe;AAAA;AAAA,MACpD;AAAA,IACF;AACA,QAAI,cAAc,eAAe;AAC/B,wBAAkB;AAAA,QAChB,2BAA2B,cAAc,aAAa;AAAA;AAAA,MACxD;AAAA,IACF;AACA;AAAA,MACE,GAAG,yBAAyB,QAAQ,gBAAgB,QAAQ,GAAG,CAAC;AAAA;AAAA,IAE9D,kBAAkB,KAAK,EAAE,IACzB,OAAO,cAAc,OAAO;AAAA,IAChC;AAAA,EACF,WAAW,QAAQ,yBAAyB;AAC1C;AAAA,MACE,GAAG,yBAAyB,QAAQ,gBAAgB,QAAQ,GAAG,CAAC;AAAA,IAClE;AAAA,EACF;AACA,MAAI,QAAQ,kBAAkB;AAC5B,eAAW,YAAY,KAAK,oCAAoC,CAAC;AAAA,EACnE;AACA,MACE,QAAQ,mBAAmB,eAC3B,QAAQ,IAAI,sBAAsB,aAClC;AACA;AAAA,MACE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aACJ,QAAQ,oBACR,QAAQ,2BACR;AACF,MAAI,YAAY;AACd,UAAM,eAAe,MAAM,gBAAgB,KAAK;AAAA,MAC9C,gBAAgB,QAAQ;AAAA,MACxB,gBAAgB,QAAQ;AAAA,IAC1B,CAAC;AACD;AAAA,MACE;AAAA,iCAAoC,YAAY,KAAK,QAAQ,aAAa,CAAC;AAAA;AAAA,+BAEzC,YAAY;AAAA;AAAA,IAChD;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,gBAAgC,KAAa;AAC7E,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AACH,aAAO,qCAAqC,GAAG;AAAA,IACjD,KAAK;AACH,aAAO,qCAAqC,GAAG;AAAA,IACjD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,iBAAiB,cAAc;AAAA,IACxC,SAAS;AACP;AACA,aAAO,iBAAiB,cAAqB;AAAA,IAC/C;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logFinishedStep, logMessage } from \"../../bundler/log.js\";\nimport { DeploymentType } from \"./api.js\";\nimport { writeUrlsToEnvFile } from \"./envvars.js\";\nimport { getDashboardUrl } from \"./dashboard.js\";\n\nexport async function finalizeConfiguration(\n ctx: Context,\n options: {\n functionsPath: string;\n deploymentType: DeploymentType;\n deploymentName: string;\n url: string;\n siteUrl: string | null | undefined;\n wroteToGitIgnore: boolean;\n changedDeploymentEnvVar: boolean;\n },\n) {\n const envFileConfig = await writeUrlsToEnvFile(ctx, {\n convexUrl: options.url,\n siteUrl: options.siteUrl,\n });\n const isEnvFileConfigChanged =\n envFileConfig !== null &&\n (envFileConfig.convexUrlEnvVar || envFileConfig.siteUrlEnvVar);\n\n if (isEnvFileConfigChanged) {\n const deploymentEnvVarMessage = options.changedDeploymentEnvVar\n ? ` name as CONVEX_DEPLOYMENT\\n`\n : \"\";\n const urlUpdateMessages = [];\n if (envFileConfig.convexUrlEnvVar) {\n urlUpdateMessages.push(\n ` client URL as ${envFileConfig.convexUrlEnvVar}\\n`,\n );\n }\n if (envFileConfig.siteUrlEnvVar) {\n urlUpdateMessages.push(\n ` HTTP actions URL as ${envFileConfig.siteUrlEnvVar}\\n`,\n );\n }\n logFinishedStep(\n `${messageForDeploymentType(options.deploymentType, options.url)} and saved its:\\n` +\n deploymentEnvVarMessage +\n urlUpdateMessages.join(\"\") +\n ` to ${envFileConfig.envFile}`,\n );\n } else if (options.changedDeploymentEnvVar) {\n logFinishedStep(\n `${messageForDeploymentType(options.deploymentType, options.url)} and saved its name as CONVEX_DEPLOYMENT to .env.local`,\n );\n }\n if (options.wroteToGitIgnore) {\n logMessage(chalkStderr.gray(` Added \".env.local\" to .gitignore`));\n }\n if (\n options.deploymentType === \"anonymous\" &&\n process.env.CONVEX_AGENT_MODE !== \"anonymous\" &&\n ctx.bigBrainAuth() === null\n ) {\n logMessage(\n `Run \\`npx convex login\\` at any time to create an account and link this deployment.`,\n );\n }\n\n const anyChanges =\n options.wroteToGitIgnore ||\n options.changedDeploymentEnvVar ||\n isEnvFileConfigChanged;\n if (anyChanges) {\n const dashboardUrl = await getDashboardUrl(ctx, {\n deploymentName: options.deploymentName,\n deploymentType: options.deploymentType,\n });\n logMessage(\n `\\nWrite your Convex functions in ${chalkStderr.bold(options.functionsPath)}\\n` +\n \"Give us feedback at https://convex.dev/community or support@convex.dev\\n\" +\n `View the Convex dashboard at ${dashboardUrl}\\n`,\n );\n }\n}\n\nfunction messageForDeploymentType(deploymentType: DeploymentType, url: string) {\n switch (deploymentType) {\n case \"anonymous\":\n return `Configured a local deployment for ${url}`;\n case \"local\":\n return `Configured a local deployment for ${url}`;\n case \"dev\":\n case \"prod\":\n case \"preview\":\n case \"custom\":\n return `Provisioned a ${deploymentType} deployment`;\n default: {\n deploymentType satisfies never;\n return `Provisioned a ${deploymentType as any} deployment`;\n }\n }\n}\n"],
5
+ "mappings": ";AAAA,SAAS,mBAAmB;AAE5B,SAAS,iBAAiB,kBAAkB;AAE5C,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAEhC,sBAAsB,sBACpB,KACA,SASA;AACA,QAAM,gBAAgB,MAAM,mBAAmB,KAAK;AAAA,IAClD,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,EACnB,CAAC;AACD,QAAM,yBACJ,kBAAkB,SACjB,cAAc,mBAAmB,cAAc;AAElD,MAAI,wBAAwB;AAC1B,UAAM,0BAA0B,QAAQ,0BACpC;AAAA,IACA;AACJ,UAAM,oBAAoB,CAAC;AAC3B,QAAI,cAAc,iBAAiB;AACjC,wBAAkB;AAAA,QAChB,qBAAqB,cAAc,eAAe;AAAA;AAAA,MACpD;AAAA,IACF;AACA,QAAI,cAAc,eAAe;AAC/B,wBAAkB;AAAA,QAChB,2BAA2B,cAAc,aAAa;AAAA;AAAA,MACxD;AAAA,IACF;AACA;AAAA,MACE,GAAG,yBAAyB,QAAQ,gBAAgB,QAAQ,GAAG,CAAC;AAAA,IAC9D,0BACA,kBAAkB,KAAK,EAAE,IACzB,OAAO,cAAc,OAAO;AAAA,IAChC;AAAA,EACF,WAAW,QAAQ,yBAAyB;AAC1C;AAAA,MACE,GAAG,yBAAyB,QAAQ,gBAAgB,QAAQ,GAAG,CAAC;AAAA,IAClE;AAAA,EACF;AACA,MAAI,QAAQ,kBAAkB;AAC5B,eAAW,YAAY,KAAK,oCAAoC,CAAC;AAAA,EACnE;AACA,MACE,QAAQ,mBAAmB,eAC3B,QAAQ,IAAI,sBAAsB,eAClC,IAAI,aAAa,MAAM,MACvB;AACA;AAAA,MACE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aACJ,QAAQ,oBACR,QAAQ,2BACR;AACF,MAAI,YAAY;AACd,UAAM,eAAe,MAAM,gBAAgB,KAAK;AAAA,MAC9C,gBAAgB,QAAQ;AAAA,MACxB,gBAAgB,QAAQ;AAAA,IAC1B,CAAC;AACD;AAAA,MACE;AAAA,iCAAoC,YAAY,KAAK,QAAQ,aAAa,CAAC;AAAA;AAAA,+BAEzC,YAAY;AAAA;AAAA,IAChD;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,gBAAgC,KAAa;AAC7E,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AACH,aAAO,qCAAqC,GAAG;AAAA,IACjD,KAAK;AACH,aAAO,qCAAqC,GAAG;AAAA,IACjD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,iBAAiB,cAAc;AAAA,IACxC,SAAS;AACP;AACA,aAAO,iBAAiB,cAAqB;AAAA,IAC/C;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -95,7 +95,7 @@ export async function fetchRawInsightsData(ctx, deploymentName) {
95
95
  from: fromDate,
96
96
  to: toDate
97
97
  });
98
- const bbFetch = await bigBrainFetch(ctx);
98
+ const bbFetch = bigBrainFetch(ctx);
99
99
  const res = await bbFetch(
100
100
  new URL(
101
101
  `dashboard/teams/${teamId}/usage/query?${queryParams.toString()}`,