convex 1.31.6 → 1.31.8-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/bin/main-dev +1 -1
  3. package/dist/browser.bundle.js +1 -1
  4. package/dist/browser.bundle.js.map +1 -1
  5. package/dist/cjs/cli/configure.js +21 -15
  6. package/dist/cjs/cli/configure.js.map +2 -2
  7. package/dist/cjs/cli/convexImport.js +1 -1
  8. package/dist/cjs/cli/convexImport.js.map +2 -2
  9. package/dist/cjs/cli/dashboard.js +5 -4
  10. package/dist/cjs/cli/dashboard.js.map +2 -2
  11. package/dist/cjs/cli/deploy.js +4 -2
  12. package/dist/cjs/cli/deploy.js.map +2 -2
  13. package/dist/cjs/cli/dev.js +5 -0
  14. package/dist/cjs/cli/dev.js.map +2 -2
  15. package/dist/cjs/cli/integration.js +8 -1
  16. package/dist/cjs/cli/integration.js.map +2 -2
  17. package/dist/cjs/cli/lib/api.js +2 -4
  18. package/dist/cjs/cli/lib/api.js.map +2 -2
  19. package/dist/cjs/cli/lib/command.js +8 -2
  20. package/dist/cjs/cli/lib/command.js.map +2 -2
  21. package/dist/cjs/cli/lib/components.js +53 -1
  22. package/dist/cjs/cli/lib/components.js.map +2 -2
  23. package/dist/cjs/cli/lib/config.js.map +2 -2
  24. package/dist/cjs/cli/lib/dashboard.js +8 -2
  25. package/dist/cjs/cli/lib/dashboard.js.map +2 -2
  26. package/dist/cjs/cli/lib/deploy2.js +21 -6
  27. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  28. package/dist/cjs/cli/lib/deployApi/componentDefinition.js +3 -2
  29. package/dist/cjs/cli/lib/deployApi/componentDefinition.js.map +2 -2
  30. package/dist/cjs/cli/lib/deployApi/definitionConfig.js +2 -1
  31. package/dist/cjs/cli/lib/deployApi/definitionConfig.js.map +2 -2
  32. package/dist/cjs/cli/lib/deployApi/modules.js +6 -0
  33. package/dist/cjs/cli/lib/deployApi/modules.js.map +2 -2
  34. package/dist/cjs/cli/lib/deployment.js.map +2 -2
  35. package/dist/cjs/cli/lib/dev.js +3 -1
  36. package/dist/cjs/cli/lib/dev.js.map +2 -2
  37. package/dist/cjs/cli/lib/env.js +13 -1
  38. package/dist/cjs/cli/lib/env.js.map +2 -2
  39. package/dist/cjs/cli/lib/envvars.js +100 -39
  40. package/dist/cjs/cli/lib/envvars.js.map +2 -2
  41. package/dist/cjs/cli/lib/init.js +12 -6
  42. package/dist/cjs/cli/lib/init.js.map +2 -2
  43. package/dist/cjs/cli/lib/localDeployment/anonymous.js +1 -1
  44. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
  45. package/dist/cjs/cli/lib/run.js +1 -0
  46. package/dist/cjs/cli/lib/run.js.map +2 -2
  47. package/dist/cjs/cli/lib/typecheck.js +30 -0
  48. package/dist/cjs/cli/lib/typecheck.js.map +2 -2
  49. package/dist/cjs/cli/lib/watch.js +3 -1
  50. package/dist/cjs/cli/lib/watch.js.map +2 -2
  51. package/dist/cjs/cli/lib/workos/workos.js +1 -1
  52. package/dist/cjs/cli/lib/workos/workos.js.map +2 -2
  53. package/dist/cjs/index.js +1 -1
  54. package/dist/cjs/index.js.map +1 -1
  55. package/dist/cjs/server/pagination.js.map +2 -2
  56. package/dist/cjs/values/index.js +3 -0
  57. package/dist/cjs/values/index.js.map +2 -2
  58. package/dist/cjs/values/size.js +108 -0
  59. package/dist/cjs/values/size.js.map +7 -0
  60. package/dist/cjs-types/cli/configure.d.ts +2 -7
  61. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  62. package/dist/cjs-types/cli/dashboard.d.ts +0 -1
  63. package/dist/cjs-types/cli/dashboard.d.ts.map +1 -1
  64. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  65. package/dist/cjs-types/cli/dev.d.ts +1 -0
  66. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  67. package/dist/cjs-types/cli/integration.d.ts.map +1 -1
  68. package/dist/cjs-types/cli/lib/api.d.ts +2 -2
  69. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  70. package/dist/cjs-types/cli/lib/command.d.ts +2 -0
  71. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  72. package/dist/cjs-types/cli/lib/components.d.ts +8 -0
  73. package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
  74. package/dist/cjs-types/cli/lib/components.test.d.ts +2 -0
  75. package/dist/cjs-types/cli/lib/components.test.d.ts.map +1 -0
  76. package/dist/cjs-types/cli/lib/config.d.ts +1 -1
  77. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  78. package/dist/cjs-types/cli/lib/dashboard.d.ts +1 -1
  79. package/dist/cjs-types/cli/lib/dashboard.d.ts.map +1 -1
  80. package/dist/cjs-types/cli/lib/deploy2.d.ts +1 -0
  81. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  82. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +16 -15
  83. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  84. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +26 -3
  85. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts.map +1 -1
  86. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +14 -0
  87. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts.map +1 -1
  88. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +38 -5
  89. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  90. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  91. package/dist/cjs-types/cli/lib/dev.d.ts +1 -0
  92. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  93. package/dist/cjs-types/cli/lib/env.d.ts +4 -0
  94. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  95. package/dist/cjs-types/cli/lib/envvars.d.ts +32 -5
  96. package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
  97. package/dist/cjs-types/cli/lib/init.d.ts +1 -0
  98. package/dist/cjs-types/cli/lib/init.d.ts.map +1 -1
  99. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
  101. package/dist/cjs-types/cli/lib/typecheck.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/lib/watch.d.ts +2 -1
  103. package/dist/cjs-types/cli/lib/watch.d.ts.map +1 -1
  104. package/dist/cjs-types/index.d.ts +1 -1
  105. package/dist/cjs-types/index.d.ts.map +1 -1
  106. package/dist/cjs-types/server/pagination.d.ts +34 -0
  107. package/dist/cjs-types/server/pagination.d.ts.map +1 -1
  108. package/dist/cjs-types/values/index.d.ts +1 -0
  109. package/dist/cjs-types/values/index.d.ts.map +1 -1
  110. package/dist/cjs-types/values/size.d.ts +53 -0
  111. package/dist/cjs-types/values/size.d.ts.map +1 -0
  112. package/dist/cjs-types/values/size.test.d.ts +2 -0
  113. package/dist/cjs-types/values/size.test.d.ts.map +1 -0
  114. package/dist/cli.bundle.cjs +655 -4297
  115. package/dist/cli.bundle.cjs.map +4 -4
  116. package/dist/esm/cli/configure.js +24 -17
  117. package/dist/esm/cli/configure.js.map +2 -2
  118. package/dist/esm/cli/convexImport.js +2 -2
  119. package/dist/esm/cli/convexImport.js.map +2 -2
  120. package/dist/esm/cli/dashboard.js +5 -3
  121. package/dist/esm/cli/dashboard.js.map +2 -2
  122. package/dist/esm/cli/deploy.js +5 -3
  123. package/dist/esm/cli/deploy.js.map +2 -2
  124. package/dist/esm/cli/dev.js +5 -0
  125. package/dist/esm/cli/dev.js.map +2 -2
  126. package/dist/esm/cli/integration.js +8 -1
  127. package/dist/esm/cli/integration.js.map +2 -2
  128. package/dist/esm/cli/lib/api.js +1 -3
  129. package/dist/esm/cli/lib/api.js.map +2 -2
  130. package/dist/esm/cli/lib/command.js +8 -2
  131. package/dist/esm/cli/lib/command.js.map +2 -2
  132. package/dist/esm/cli/lib/components.js +51 -1
  133. package/dist/esm/cli/lib/components.js.map +2 -2
  134. package/dist/esm/cli/lib/config.js.map +2 -2
  135. package/dist/esm/cli/lib/dashboard.js +8 -2
  136. package/dist/esm/cli/lib/dashboard.js.map +2 -2
  137. package/dist/esm/cli/lib/deploy2.js +22 -7
  138. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  139. package/dist/esm/cli/lib/deployApi/componentDefinition.js +3 -2
  140. package/dist/esm/cli/lib/deployApi/componentDefinition.js.map +2 -2
  141. package/dist/esm/cli/lib/deployApi/definitionConfig.js +3 -2
  142. package/dist/esm/cli/lib/deployApi/definitionConfig.js.map +2 -2
  143. package/dist/esm/cli/lib/deployApi/modules.js +5 -0
  144. package/dist/esm/cli/lib/deployApi/modules.js.map +2 -2
  145. package/dist/esm/cli/lib/deployment.js.map +2 -2
  146. package/dist/esm/cli/lib/dev.js +3 -1
  147. package/dist/esm/cli/lib/dev.js.map +2 -2
  148. package/dist/esm/cli/lib/env.js +11 -0
  149. package/dist/esm/cli/lib/env.js.map +2 -2
  150. package/dist/esm/cli/lib/envvars.js +98 -37
  151. package/dist/esm/cli/lib/envvars.js.map +2 -2
  152. package/dist/esm/cli/lib/init.js +13 -7
  153. package/dist/esm/cli/lib/init.js.map +2 -2
  154. package/dist/esm/cli/lib/localDeployment/anonymous.js +2 -2
  155. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
  156. package/dist/esm/cli/lib/run.js +1 -0
  157. package/dist/esm/cli/lib/run.js.map +2 -2
  158. package/dist/esm/cli/lib/typecheck.js +37 -2
  159. package/dist/esm/cli/lib/typecheck.js.map +2 -2
  160. package/dist/esm/cli/lib/watch.js +3 -1
  161. package/dist/esm/cli/lib/watch.js.map +2 -2
  162. package/dist/esm/cli/lib/workos/workos.js +2 -2
  163. package/dist/esm/cli/lib/workos/workos.js.map +2 -2
  164. package/dist/esm/index.js +1 -1
  165. package/dist/esm/index.js.map +1 -1
  166. package/dist/esm/server/pagination.js.map +2 -2
  167. package/dist/esm/values/index.js +1 -0
  168. package/dist/esm/values/index.js.map +2 -2
  169. package/dist/esm/values/size.js +83 -0
  170. package/dist/esm/values/size.js.map +7 -0
  171. package/dist/esm-types/cli/configure.d.ts +2 -7
  172. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  173. package/dist/esm-types/cli/dashboard.d.ts +0 -1
  174. package/dist/esm-types/cli/dashboard.d.ts.map +1 -1
  175. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  176. package/dist/esm-types/cli/dev.d.ts +1 -0
  177. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  178. package/dist/esm-types/cli/integration.d.ts.map +1 -1
  179. package/dist/esm-types/cli/lib/api.d.ts +2 -2
  180. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  181. package/dist/esm-types/cli/lib/command.d.ts +2 -0
  182. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  183. package/dist/esm-types/cli/lib/components.d.ts +8 -0
  184. package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
  185. package/dist/esm-types/cli/lib/components.test.d.ts +2 -0
  186. package/dist/esm-types/cli/lib/components.test.d.ts.map +1 -0
  187. package/dist/esm-types/cli/lib/config.d.ts +1 -1
  188. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  189. package/dist/esm-types/cli/lib/dashboard.d.ts +1 -1
  190. package/dist/esm-types/cli/lib/dashboard.d.ts.map +1 -1
  191. package/dist/esm-types/cli/lib/deploy2.d.ts +1 -0
  192. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  193. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +16 -15
  194. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  195. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +26 -3
  196. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts.map +1 -1
  197. package/dist/esm-types/cli/lib/deployApi/modules.d.ts +14 -0
  198. package/dist/esm-types/cli/lib/deployApi/modules.d.ts.map +1 -1
  199. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +38 -5
  200. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  201. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  202. package/dist/esm-types/cli/lib/dev.d.ts +1 -0
  203. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  204. package/dist/esm-types/cli/lib/env.d.ts +4 -0
  205. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  206. package/dist/esm-types/cli/lib/envvars.d.ts +32 -5
  207. package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
  208. package/dist/esm-types/cli/lib/init.d.ts +1 -0
  209. package/dist/esm-types/cli/lib/init.d.ts.map +1 -1
  210. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  211. package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
  212. package/dist/esm-types/cli/lib/typecheck.d.ts.map +1 -1
  213. package/dist/esm-types/cli/lib/watch.d.ts +2 -1
  214. package/dist/esm-types/cli/lib/watch.d.ts.map +1 -1
  215. package/dist/esm-types/index.d.ts +1 -1
  216. package/dist/esm-types/index.d.ts.map +1 -1
  217. package/dist/esm-types/server/pagination.d.ts +34 -0
  218. package/dist/esm-types/server/pagination.d.ts.map +1 -1
  219. package/dist/esm-types/values/index.d.ts +1 -0
  220. package/dist/esm-types/values/index.d.ts.map +1 -1
  221. package/dist/esm-types/values/size.d.ts +53 -0
  222. package/dist/esm-types/values/size.d.ts.map +1 -0
  223. package/dist/esm-types/values/size.test.d.ts +2 -0
  224. package/dist/esm-types/values/size.test.d.ts.map +1 -0
  225. package/dist/react.bundle.js +1 -1
  226. package/dist/react.bundle.js.map +1 -1
  227. package/package.json +1 -1
  228. package/src/cli/configure.ts +44 -25
  229. package/src/cli/convexImport.ts +2 -2
  230. package/src/cli/dashboard.ts +5 -6
  231. package/src/cli/deploy.ts +8 -4
  232. package/src/cli/dev.ts +8 -0
  233. package/src/cli/integration.ts +11 -3
  234. package/src/cli/lib/api.ts +3 -14
  235. package/src/cli/lib/command.ts +12 -1
  236. package/src/cli/lib/components.test.ts +227 -0
  237. package/src/cli/lib/components.ts +83 -1
  238. package/src/cli/lib/config.ts +4 -1
  239. package/src/cli/lib/dashboard.ts +9 -3
  240. package/src/cli/lib/deploy2.ts +24 -8
  241. package/src/cli/lib/deployApi/componentDefinition.ts +4 -2
  242. package/src/cli/lib/deployApi/definitionConfig.ts +3 -2
  243. package/src/cli/lib/deployApi/modules.ts +7 -0
  244. package/src/cli/lib/deployment.ts +1 -0
  245. package/src/cli/lib/dev.ts +3 -0
  246. package/src/cli/lib/env.ts +15 -0
  247. package/src/cli/lib/envvars.ts +164 -51
  248. package/src/cli/lib/init.ts +16 -7
  249. package/src/cli/lib/localDeployment/anonymous.ts +7 -6
  250. package/src/cli/lib/run.ts +1 -0
  251. package/src/cli/lib/typecheck.ts +44 -2
  252. package/src/cli/lib/watch.ts +7 -1
  253. package/src/cli/lib/workos/workos.ts +2 -2
  254. package/src/index.ts +1 -1
  255. package/src/server/pagination.ts +16 -17
  256. package/src/values/index.ts +1 -0
  257. package/src/values/size.test.ts +86 -0
  258. package/src/values/size.ts +191 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/deployment.ts"],
4
- "sourcesContent": ["import * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport { changedEnvVarFile, getEnvVarRegex } from \"./envvars.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n ENV_VAR_FILE_PATH,\n} from \"./utils/utils.js\";\nimport { DeploymentType } from \"./api.js\";\n\n// Given a deployment string like \"dev:tall-forest-1234\"\n// returns only the slug \"tall-forest-1234\".\n// If there's no prefix returns the original string.\nexport function stripDeploymentTypePrefix(deployment: string) {\n return deployment.split(\":\").at(-1)!;\n}\n\n// Handling legacy CONVEX_DEPLOYMENT without type prefix as well\nexport function getDeploymentTypeFromConfiguredDeployment(raw: string) {\n const typeRaw = raw.split(\":\")[0];\n const type =\n typeRaw === \"prod\" ||\n typeRaw === \"dev\" ||\n typeRaw === \"preview\" ||\n typeRaw === \"local\"\n ? typeRaw\n : null;\n return type;\n}\n\nexport function isAnonymousDeployment(deploymentName: string) {\n return deploymentName.startsWith(\"anonymous-\");\n}\n\nexport function removeAnonymousPrefix(deploymentName: string) {\n if (isAnonymousDeployment(deploymentName)) {\n return deploymentName.slice(\"anonymous-\".length);\n }\n return deploymentName;\n}\n\nexport async function writeDeploymentEnvVar(\n ctx: Context,\n deploymentType: DeploymentType,\n deployment: {\n team: string | null;\n project: string | null;\n deploymentName: string;\n },\n existingValue: string | null,\n): Promise<{ wroteToGitIgnore: boolean; changedDeploymentEnvVar: boolean }> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n const changedFile = changesToEnvVarFile(\n existingFile,\n deploymentType,\n deployment,\n );\n const deploymentEnvVarValue =\n deploymentType + \":\" + deployment.deploymentName;\n // The `existingValue` that reaches this function is at least sometimes is missing its prefix.\n // Until this is cleaned up consider either of these values not a change.\n // Otherwise we spam the init instructions (Welcome to Convex etc.) on every run of `npx convex dev`.\n const changedDeploymentEnvVar =\n existingValue !== deployment.deploymentName &&\n existingValue !== deploymentEnvVarValue;\n\n if (changedFile !== null) {\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n // Only do this if we're not reinitializing an existing setup\n return {\n wroteToGitIgnore: await gitIgnoreEnvVarFile(ctx),\n changedDeploymentEnvVar,\n };\n }\n return {\n wroteToGitIgnore: false,\n changedDeploymentEnvVar,\n };\n}\n\n// Only used in the internal --url flow\nexport async function eraseDeploymentEnvVar(ctx: Context): Promise<boolean> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n if (existingFile === null) {\n return false;\n }\n const config = dotenv.parse(existingFile);\n const existing = config[CONVEX_DEPLOYMENT_ENV_VAR_NAME];\n if (existing === undefined) {\n return false;\n }\n const changedFile = existingFile.replace(\n getEnvVarRegex(CONVEX_DEPLOYMENT_ENV_VAR_NAME),\n \"\",\n );\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n return true;\n}\n\nasync function gitIgnoreEnvVarFile(ctx: Context): Promise<boolean> {\n const gitIgnorePath = \".gitignore\";\n const gitIgnoreContents = ctx.fs.exists(gitIgnorePath)\n ? ctx.fs.readUtf8File(gitIgnorePath)\n : \"\";\n const changedGitIgnore = changesToGitIgnore(gitIgnoreContents);\n if (changedGitIgnore !== null) {\n ctx.fs.writeUtf8File(gitIgnorePath, changedGitIgnore);\n return true;\n }\n return false;\n}\n\n// exported for tests\nexport function changesToEnvVarFile(\n existingFile: string | null,\n deploymentType: DeploymentType,\n {\n team,\n project,\n deploymentName,\n }: { team: string | null; project: string | null; deploymentName: string },\n): string | null {\n const deploymentValue = deploymentType + \":\" + deploymentName;\n const commentOnPreviousLine = \"# Deployment used by `npx convex dev`\";\n const commentAfterValue =\n team !== null && project !== null\n ? `team: ${team}, project: ${project}`\n : null;\n return changedEnvVarFile({\n existingFileContent: existingFile,\n envVarName: CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n envVarValue: deploymentValue,\n commentAfterValue,\n commentOnPreviousLine,\n });\n}\n\n// exported for tests\nexport function changesToGitIgnore(existingFile: string | null): string | null {\n if (existingFile === null) {\n return `${ENV_VAR_FILE_PATH}\\n`;\n }\n const gitIgnoreLines = existingFile.split(\"\\n\");\n const envVarFileIgnored = gitIgnoreLines.some((line) => {\n if (line.startsWith(\"#\")) return false;\n if (line.startsWith(\"!\")) return false;\n\n // .gitignore ignores trailing whitespace, and also we need to remove\n // the trailing `\\r` from Windows-style newline since we split on `\\n`.\n const trimmedLine = line.trimEnd();\n\n const envIgnorePatterns = [\n /^\\.env\\.local$/,\n /^\\.env\\.\\*$/,\n /^\\.env\\*$/,\n /^.*\\.local$/,\n /^\\.env\\*\\.local$/,\n ];\n\n return envIgnorePatterns.some((pattern) => pattern.test(trimmedLine));\n });\n if (!envVarFileIgnored) {\n return `${existingFile}\\n${ENV_VAR_FILE_PATH}\\n`;\n } else {\n return null;\n }\n}\n\nexport async function deploymentNameFromAdminKeyOrCrash(\n ctx: Context,\n adminKey: string,\n) {\n const deploymentName = deploymentNameFromAdminKey(adminKey);\n if (deploymentName === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Please set ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} to a new key which you can find on your Convex dashboard.`,\n });\n }\n return deploymentName;\n}\n\nfunction deploymentNameFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return null;\n }\n if (isPreviewDeployKey(adminKey)) {\n // Preview deploy keys do not contain a deployment name.\n return null;\n }\n return stripDeploymentTypePrefix(parts[0]);\n}\n\n// Needed to differentiate a preview deploy key\n// from a concrete preview deployment's deploy key.\n// preview deploy key: `preview:team:project|key`\n// preview deployment's deploy key: `preview:deploymentName|key`\nexport function isPreviewDeployKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return false;\n }\n const [prefix] = parts;\n const prefixParts = prefix.split(\":\");\n return prefixParts[0] === \"preview\" && prefixParts.length === 3;\n}\n\nexport function isProjectKey(adminKey: string) {\n return /^project:.*\\|/.test(adminKey);\n}\n\n// \"dev deploy keys\" and \"prod deploy keys\" are deployment keys.\n// On the client these are also known as admin keys.\nexport function isDeploymentKey(adminKey: string) {\n return /^(dev|prod):.*\\|/.test(adminKey);\n}\n\n// For current keys returns prod|dev|preview,\n// for legacy keys returns \"prod\".\n// Examples:\n// \"prod:deploymentName|key\" -> \"prod\"\n// \"preview:deploymentName|key\" -> \"preview\"\n// \"dev:deploymentName|key\" -> \"dev\"\n// \"key\" -> \"prod\"\nexport function deploymentTypeFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\":\");\n if (parts.length === 1) {\n return \"prod\";\n }\n return parts.at(0)! as DeploymentType;\n}\n\nexport async function getTeamAndProjectFromPreviewAdminKey(\n ctx: Context,\n adminKey: string,\n) {\n const parts = adminKey.split(\"|\")[0].split(\":\");\n if (parts.length !== 3) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Malformed preview CONVEX_DEPLOY_KEY, get a new key from Project Settings.\",\n });\n }\n const [_preview, teamSlug, projectSlug] = parts;\n return { teamSlug, projectSlug };\n}\n\nexport type OnDeploymentActivityFunc = (\n isOffline: boolean,\n wasOffline: boolean,\n) => Promise<void>;\nexport type CleanupDeploymentFunc = () => Promise<void>;\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n onActivity: OnDeploymentActivityFunc | null;\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as dotenv from \"dotenv\";\nimport { Context } from \"../../bundler/context.js\";\nimport { changedEnvVarFile, getEnvVarRegex } from \"./envvars.js\";\nimport {\n CONVEX_DEPLOY_KEY_ENV_VAR_NAME,\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n ENV_VAR_FILE_PATH,\n} from \"./utils/utils.js\";\nimport { DeploymentType } from \"./api.js\";\n\n// Given a deployment string like \"dev:tall-forest-1234\"\n// returns only the slug \"tall-forest-1234\".\n// If there's no prefix returns the original string.\nexport function stripDeploymentTypePrefix(deployment: string) {\n return deployment.split(\":\").at(-1)!;\n}\n\n// Handling legacy CONVEX_DEPLOYMENT without type prefix as well\nexport function getDeploymentTypeFromConfiguredDeployment(raw: string) {\n const typeRaw = raw.split(\":\")[0];\n const type =\n typeRaw === \"prod\" ||\n typeRaw === \"dev\" ||\n typeRaw === \"preview\" ||\n typeRaw === \"local\"\n ? typeRaw\n : null;\n return type;\n}\n\nexport function isAnonymousDeployment(deploymentName: string) {\n return deploymentName.startsWith(\"anonymous-\");\n}\n\nexport function removeAnonymousPrefix(deploymentName: string) {\n if (isAnonymousDeployment(deploymentName)) {\n return deploymentName.slice(\"anonymous-\".length);\n }\n return deploymentName;\n}\n\nexport async function writeDeploymentEnvVar(\n ctx: Context,\n deploymentType: DeploymentType,\n deployment: {\n team: string | null;\n project: string | null;\n deploymentName: string;\n },\n existingValue: string | null,\n): Promise<{ wroteToGitIgnore: boolean; changedDeploymentEnvVar: boolean }> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n const changedFile = changesToEnvVarFile(\n existingFile,\n deploymentType,\n deployment,\n );\n const deploymentEnvVarValue =\n deploymentType + \":\" + deployment.deploymentName;\n // The `existingValue` that reaches this function is at least sometimes is missing its prefix.\n // Until this is cleaned up consider either of these values not a change.\n // Otherwise we spam the init instructions (Welcome to Convex etc.) on every run of `npx convex dev`.\n const changedDeploymentEnvVar =\n existingValue !== deployment.deploymentName &&\n existingValue !== deploymentEnvVarValue;\n\n if (changedFile !== null) {\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n // Only do this if we're not reinitializing an existing setup\n return {\n wroteToGitIgnore: await gitIgnoreEnvVarFile(ctx),\n changedDeploymentEnvVar,\n };\n }\n return {\n wroteToGitIgnore: false,\n changedDeploymentEnvVar,\n };\n}\n\n// Only used in the internal --url flow\nexport async function eraseDeploymentEnvVar(ctx: Context): Promise<boolean> {\n const existingFile = ctx.fs.exists(ENV_VAR_FILE_PATH)\n ? ctx.fs.readUtf8File(ENV_VAR_FILE_PATH)\n : null;\n if (existingFile === null) {\n return false;\n }\n const config = dotenv.parse(existingFile);\n const existing = config[CONVEX_DEPLOYMENT_ENV_VAR_NAME];\n if (existing === undefined) {\n return false;\n }\n const changedFile = existingFile.replace(\n getEnvVarRegex(CONVEX_DEPLOYMENT_ENV_VAR_NAME),\n \"\",\n );\n ctx.fs.writeUtf8File(ENV_VAR_FILE_PATH, changedFile);\n return true;\n}\n\nasync function gitIgnoreEnvVarFile(ctx: Context): Promise<boolean> {\n const gitIgnorePath = \".gitignore\";\n const gitIgnoreContents = ctx.fs.exists(gitIgnorePath)\n ? ctx.fs.readUtf8File(gitIgnorePath)\n : \"\";\n const changedGitIgnore = changesToGitIgnore(gitIgnoreContents);\n if (changedGitIgnore !== null) {\n ctx.fs.writeUtf8File(gitIgnorePath, changedGitIgnore);\n return true;\n }\n return false;\n}\n\n// exported for tests\nexport function changesToEnvVarFile(\n existingFile: string | null,\n deploymentType: DeploymentType,\n {\n team,\n project,\n deploymentName,\n }: { team: string | null; project: string | null; deploymentName: string },\n): string | null {\n const deploymentValue = deploymentType + \":\" + deploymentName;\n const commentOnPreviousLine = \"# Deployment used by `npx convex dev`\";\n const commentAfterValue =\n team !== null && project !== null\n ? `team: ${team}, project: ${project}`\n : null;\n return changedEnvVarFile({\n existingFileContent: existingFile,\n envVarName: CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n envVarValue: deploymentValue,\n commentAfterValue,\n commentOnPreviousLine,\n });\n}\n\n// exported for tests\nexport function changesToGitIgnore(existingFile: string | null): string | null {\n if (existingFile === null) {\n return `${ENV_VAR_FILE_PATH}\\n`;\n }\n const gitIgnoreLines = existingFile.split(\"\\n\");\n const envVarFileIgnored = gitIgnoreLines.some((line) => {\n if (line.startsWith(\"#\")) return false;\n if (line.startsWith(\"!\")) return false;\n\n // .gitignore ignores trailing whitespace, and also we need to remove\n // the trailing `\\r` from Windows-style newline since we split on `\\n`.\n const trimmedLine = line.trimEnd();\n\n const envIgnorePatterns = [\n /^\\.env\\.local$/,\n /^\\.env\\.\\*$/,\n /^\\.env\\*$/,\n /^.*\\.local$/,\n /^\\.env\\*\\.local$/,\n ];\n\n return envIgnorePatterns.some((pattern) => pattern.test(trimmedLine));\n });\n if (!envVarFileIgnored) {\n return `${existingFile}\\n${ENV_VAR_FILE_PATH}\\n`;\n } else {\n return null;\n }\n}\n\nexport async function deploymentNameFromAdminKeyOrCrash(\n ctx: Context,\n adminKey: string,\n) {\n const deploymentName = deploymentNameFromAdminKey(adminKey);\n if (deploymentName === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Please set ${CONVEX_DEPLOY_KEY_ENV_VAR_NAME} to a new key which you can find on your Convex dashboard.`,\n });\n }\n return deploymentName;\n}\n\nfunction deploymentNameFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return null;\n }\n if (isPreviewDeployKey(adminKey)) {\n // Preview deploy keys do not contain a deployment name.\n return null;\n }\n return stripDeploymentTypePrefix(parts[0]);\n}\n\n// Needed to differentiate a preview deploy key\n// from a concrete preview deployment's deploy key.\n// preview deploy key: `preview:team:project|key`\n// preview deployment's deploy key: `preview:deploymentName|key`\nexport function isPreviewDeployKey(adminKey: string) {\n const parts = adminKey.split(\"|\");\n if (parts.length === 1) {\n return false;\n }\n const [prefix] = parts;\n const prefixParts = prefix.split(\":\");\n return prefixParts[0] === \"preview\" && prefixParts.length === 3;\n}\n\nexport function isProjectKey(adminKey: string) {\n return /^project:.*\\|/.test(adminKey);\n}\n\n// \"dev deploy keys\" and \"prod deploy keys\" are deployment keys.\n// On the client these are also known as admin keys.\nexport function isDeploymentKey(adminKey: string) {\n return /^(dev|prod):.*\\|/.test(adminKey);\n}\n\n// For current keys returns prod|dev|preview,\n// for legacy keys returns \"prod\".\n// Examples:\n// \"prod:deploymentName|key\" -> \"prod\"\n// \"preview:deploymentName|key\" -> \"preview\"\n// \"dev:deploymentName|key\" -> \"dev\"\n// \"custom:deploymentName|key\" -> \"custom\"\n// \"key\" -> \"prod\"\nexport function deploymentTypeFromAdminKey(adminKey: string) {\n const parts = adminKey.split(\":\");\n if (parts.length === 1) {\n return \"prod\";\n }\n return parts.at(0)! as DeploymentType;\n}\n\nexport async function getTeamAndProjectFromPreviewAdminKey(\n ctx: Context,\n adminKey: string,\n) {\n const parts = adminKey.split(\"|\")[0].split(\":\");\n if (parts.length !== 3) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Malformed preview CONVEX_DEPLOY_KEY, get a new key from Project Settings.\",\n });\n }\n const [_preview, teamSlug, projectSlug] = parts;\n return { teamSlug, projectSlug };\n}\n\nexport type OnDeploymentActivityFunc = (\n isOffline: boolean,\n wasOffline: boolean,\n) => Promise<void>;\nexport type CleanupDeploymentFunc = () => Promise<void>;\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n onActivity: OnDeploymentActivityFunc | null;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -82,6 +82,7 @@ async function devAgainstDeployment(ctx, credentials, devOptions) {
82
82
  debugNodeApis: devOptions.debugNodeApis,
83
83
  codegen: devOptions.codegen,
84
84
  liveComponentSources: devOptions.liveComponentSources,
85
+ pushAllModules: devOptions.pushAllModules,
85
86
  logManager,
86
87
  // Pass logManager to control logs during deploy
87
88
  largeIndexDeletionCheck: "no verification"
@@ -110,7 +111,8 @@ async function watchAndPush(outerCtx, options, cmdOptions) {
110
111
  shouldRetryOnDeploymentEnvVarChange = false;
111
112
  const ctx = new import_watch.WatchContext(
112
113
  cmdOptions.traceEvents,
113
- outerCtx.bigBrainAuth()
114
+ outerCtx.bigBrainAuth(),
115
+ isFirstPush
114
116
  );
115
117
  options.logManager?.beginDeploy();
116
118
  (0, import_log.showSpinner)("Preparing Convex functions...");
@@ -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 },\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 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 );\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 { 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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",
6
6
  "names": ["path", "result"]
7
7
  }
@@ -23,7 +23,8 @@ __export(env_exports, {
23
23
  envGetInDeploymentAction: () => envGetInDeploymentAction,
24
24
  envListInDeployment: () => envListInDeployment,
25
25
  envRemoveInDeployment: () => envRemoveInDeployment,
26
- envSetInDeployment: () => envSetInDeployment
26
+ envSetInDeployment: () => envSetInDeployment,
27
+ fetchDeploymentCanonicalSiteUrl: () => fetchDeploymentCanonicalSiteUrl
27
28
  });
28
29
  module.exports = __toCommonJS(env_exports);
29
30
  var import_chalk = require("chalk");
@@ -117,4 +118,15 @@ async function callUpdateEnvironmentVariables(ctx, deployment, changes) {
117
118
  return await (0, import_utils.logAndHandleFetchError)(ctx, e);
118
119
  }
119
120
  }
121
+ async function fetchDeploymentCanonicalSiteUrl(ctx, options) {
122
+ const result = await envGetInDeployment(ctx, options, "CONVEX_SITE_URL");
123
+ if (typeof result !== "string") {
124
+ return await ctx.crash({
125
+ exitCode: 1,
126
+ errorType: "invalid filesystem or env vars",
127
+ printedMessage: "Invalid process.env.CONVEX_SITE_URL"
128
+ });
129
+ }
130
+ return result;
131
+ }
120
132
  //# 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 { 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\";\n\nexport async function envSetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n rawName: string,\n rawValue: string | undefined,\n options?: {\n secret?: boolean;\n },\n) {\n const [name, value] = await allowEqualsSyntax(ctx, rawName, rawValue);\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name, value }]);\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n if (options?.secret) {\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}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n) {\n if (value === undefined) {\n if (/^[a-zA-Z][a-zA-Z0-9_]+=/.test(name)) {\n return name.split(\"=\", 2);\n } else if (!process.stdin.isTTY) {\n // Read from stdin when piped input is available\n try {\n const stdinValue = await readFromStdin();\n return [name, stdinValue];\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 } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: missing required argument 'value'\",\n });\n }\n }\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\nexport async function envListInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n const envs = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n if (envs.length === 0) {\n logMessage(\"No environment variables set.\");\n return;\n }\n for (const { name, value } of envs) {\n logOutput(`${name}=${value}`);\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": "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",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\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\";\n\nexport async function envSetInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n },\n rawName: string,\n rawValue: string | undefined,\n options?: {\n secret?: boolean;\n },\n) {\n const [name, value] = await allowEqualsSyntax(ctx, rawName, rawValue);\n await callUpdateEnvironmentVariables(ctx, deployment, [{ name, value }]);\n const formatted = /\\s/.test(value) ? `\"${value}\"` : value;\n if (options?.secret) {\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}\n\nasync function allowEqualsSyntax(\n ctx: Context,\n name: string,\n value: string | undefined,\n) {\n if (value === undefined) {\n if (/^[a-zA-Z][a-zA-Z0-9_]+=/.test(name)) {\n return name.split(\"=\", 2);\n } else if (!process.stdin.isTTY) {\n // Read from stdin when piped input is available\n try {\n const stdinValue = await readFromStdin();\n return [name, stdinValue];\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 } else {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: missing required argument 'value'\",\n });\n }\n }\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\nexport async function envListInDeployment(\n ctx: Context,\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n const envs = (await runSystemQuery(ctx, {\n ...deployment,\n functionName: \"_system/cli/queryEnvironmentVariables\",\n componentPath: undefined,\n args: {},\n })) as EnvVar[];\n if (envs.length === 0) {\n logMessage(\"No environment variables set.\");\n return;\n }\n for (const { name, value } of envs) {\n logOutput(`${name}=${value}`);\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": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAE5B,iBAKO;AACP,iBAA+B;AAC/B,mBAAwD;AACxD,mBAA8B;AAE9B,eAAsB,mBACpB,KACA,YAKA,SACA,UACA,SAGA;AACA,QAAM,CAAC,MAAM,KAAK,IAAI,MAAM,kBAAkB,KAAK,SAAS,QAAQ;AACpE,QAAM,+BAA+B,KAAK,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,CAAC;AACvE,QAAM,YAAY,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM;AACpD,MAAI,SAAS,QAAQ;AACnB;AAAA,MACE,oBAAoB,yBAAY,KAAK,IAAI,CAAC,OAAO,yBAAY,KAAK,SAAS,CAAC,GAAG,WAAW,gBAAgB;AAAA,IAC5G;AAAA,EACF,OAAO;AACL,oCAAgB,oBAAoB,yBAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9D;AACF;AAEA,eAAe,kBACb,KACA,MACA,OACA;AACA,MAAI,UAAU,QAAW;AACvB,QAAI,0BAA0B,KAAK,IAAI,GAAG;AACxC,aAAO,KAAK,MAAM,KAAK,CAAC;AAAA,IAC1B,WAAW,CAAC,QAAQ,MAAM,OAAO;AAE/B,UAAI;AACF,cAAM,aAAa,UAAM,4BAAc;AACvC,eAAO,CAAC,MAAM,UAAU;AAAA,MAC1B,SAAS,OAAO;AACd,eAAO,MAAM,IAAI,MAAM;AAAA,UACrB,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC7G,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,aAAO,MAAM,IAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,CAAC,MAAM,KAAK;AACrB;AAEA,eAAsB,yBACpB,KACA,YAIA,MACA;AACA,QAAM,SAAS,MAAM,mBAAmB,KAAK,YAAY,IAAI;AAC7D,MAAI,WAAW,MAAM;AACnB,+BAAW,yBAAyB,IAAI,cAAc;AACtD;AAAA,EACF;AACA,4BAAU,GAAG,MAAM,EAAE;AACvB;AAEA,eAAsB,mBACpB,KACA,YAIA,MACwB;AACxB,QAAM,SAAU,UAAM,2BAAe,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,eAAsB,sBACpB,KACA,YAKA,MACA;AACA,QAAM,+BAA+B,KAAK,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC;AAChE;AAAA,IACE,sBAAsB,yBAAY,KAAK,IAAI,CAAC,GAAG,WAAW,gBAAgB;AAAA,EAC5E;AACF;AAEA,eAAsB,oBACpB,KACA,YAIA;AACA,QAAM,OAAQ,UAAM,2BAAe,KAAK;AAAA,IACtC,GAAG;AAAA,IACH,cAAc;AAAA,IACd,eAAe;AAAA,IACf,MAAM,CAAC;AAAA,EACT,CAAC;AACD,MAAI,KAAK,WAAW,GAAG;AACrB,+BAAW,+BAA+B;AAC1C;AAAA,EACF;AACA,aAAW,EAAE,MAAM,MAAM,KAAK,MAAM;AAClC,8BAAU,GAAG,IAAI,IAAI,KAAK,EAAE;AAAA,EAC9B;AACF;AAYA,eAAsB,+BACpB,KACA,YAKA,SACA;AACA,QAAM,YAAQ,8BAAgB,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,UAAM,qCAAuB,KAAK,CAAC;AAAA,EAC5C;AACF;AAEA,eAAsB,gCACpB,KACA,SACiB;AACjB,QAAM,SAAS,MAAM,mBAAmB,KAAK,SAAS,iBAAiB;AACvE,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -34,8 +34,8 @@ __export(envvars_exports, {
34
34
  getEnvVarRegex: () => getEnvVarRegex,
35
35
  gitBranchFromEnvironment: () => gitBranchFromEnvironment,
36
36
  isNonProdBuildEnvironment: () => isNonProdBuildEnvironment,
37
- suggestedEnvVarName: () => suggestedEnvVarName,
38
- writeConvexUrlToEnvFile: () => writeConvexUrlToEnvFile
37
+ suggestedEnvVarNames: () => suggestedEnvVarNames,
38
+ writeUrlsToEnvFile: () => writeUrlsToEnvFile
39
39
  });
40
40
  module.exports = __toCommonJS(envvars_exports);
41
41
  var import_chalk = require("chalk");
@@ -51,21 +51,35 @@ const _FRAMEWORKS = [
51
51
  "Expo",
52
52
  "TanStackStart"
53
53
  ];
54
- async function writeConvexUrlToEnvFile(ctx, value) {
55
- const writeConfig = await envVarWriteConfig(ctx, value);
56
- if (writeConfig === null) {
54
+ async function writeUrlsToEnvFile(ctx, options) {
55
+ const envFileConfig = await loadEnvFileUrlConfig(ctx, options);
56
+ if (envFileConfig === null) {
57
57
  return null;
58
58
  }
59
- const { envFile, envVar, existingFileContent } = writeConfig;
60
- const modified = changedEnvVarFile({
61
- existingFileContent,
62
- envVarName: envVar,
63
- envVarValue: value,
64
- commentAfterValue: null,
65
- commentOnPreviousLine: null
66
- });
67
- ctx.fs.writeUtf8File(envFile, modified);
68
- return writeConfig;
59
+ const { envFile, convexUrlEnvVar, siteUrlEnvVar, existingFileContent } = envFileConfig;
60
+ let updatedFileContent = null;
61
+ if (convexUrlEnvVar) {
62
+ updatedFileContent = changedEnvVarFile({
63
+ existingFileContent,
64
+ envVarName: convexUrlEnvVar,
65
+ envVarValue: options.convexUrl,
66
+ commentAfterValue: null,
67
+ commentOnPreviousLine: null
68
+ });
69
+ }
70
+ if (siteUrlEnvVar && options.siteUrl) {
71
+ updatedFileContent = changedEnvVarFile({
72
+ existingFileContent: updatedFileContent ?? existingFileContent,
73
+ envVarName: siteUrlEnvVar,
74
+ envVarValue: options.siteUrl,
75
+ commentAfterValue: null,
76
+ commentOnPreviousLine: null
77
+ });
78
+ }
79
+ if (updatedFileContent) {
80
+ ctx.fs.writeUtf8File(envFile, updatedFileContent);
81
+ }
82
+ return envFileConfig;
69
83
  }
70
84
  function changedEnvVarFile({
71
85
  existingFileContent,
@@ -99,10 +113,11 @@ function changedEnvVarFile({
99
113
  function getEnvVarRegex(envVarName) {
100
114
  return new RegExp(`^${envVarName}.*$`, "m");
101
115
  }
102
- async function suggestedEnvVarName(ctx) {
116
+ async function suggestedEnvVarNames(ctx) {
103
117
  if (!ctx.fs.exists("package.json")) {
104
118
  return {
105
- envVar: "CONVEX_URL"
119
+ convexUrlEnvVar: "CONVEX_URL",
120
+ convexSiteEnvVar: "CONVEX_SITE_URL"
106
121
  };
107
122
  }
108
123
  const packages = await (0, import_utils.loadPackageJson)(ctx);
@@ -110,7 +125,8 @@ async function suggestedEnvVarName(ctx) {
110
125
  if (isCreateReactApp) {
111
126
  return {
112
127
  detectedFramework: "create-react-app",
113
- envVar: "REACT_APP_CONVEX_URL",
128
+ convexUrlEnvVar: "REACT_APP_CONVEX_URL",
129
+ convexSiteEnvVar: "REACT_APP_CONVEX_SITE_URL",
114
130
  frontendDevUrl: "http://localhost:3000",
115
131
  publicPrefix: "REACT_APP_"
116
132
  };
@@ -119,7 +135,8 @@ async function suggestedEnvVarName(ctx) {
119
135
  if (isNextJs) {
120
136
  return {
121
137
  detectedFramework: "Next.js",
122
- envVar: "NEXT_PUBLIC_CONVEX_URL",
138
+ convexUrlEnvVar: "NEXT_PUBLIC_CONVEX_URL",
139
+ convexSiteEnvVar: "NEXT_PUBLIC_CONVEX_SITE_URL",
123
140
  frontendDevUrl: "http://localhost:3000",
124
141
  publicPrefix: "NEXT_PUBLIC_"
125
142
  };
@@ -128,7 +145,8 @@ async function suggestedEnvVarName(ctx) {
128
145
  if (isExpo) {
129
146
  return {
130
147
  detectedFramework: "Expo",
131
- envVar: "EXPO_PUBLIC_CONVEX_URL",
148
+ convexUrlEnvVar: "EXPO_PUBLIC_CONVEX_URL",
149
+ convexSiteEnvVar: "EXPO_PUBLIC_CONVEX_SITE_URL",
132
150
  publicPrefix: "EXPO_PUBLIC_"
133
151
  };
134
152
  }
@@ -136,7 +154,8 @@ async function suggestedEnvVarName(ctx) {
136
154
  if (isRemix) {
137
155
  return {
138
156
  detectedFramework: "Remix",
139
- envVar: "CONVEX_URL",
157
+ convexUrlEnvVar: "CONVEX_URL",
158
+ convexSiteEnvVar: "CONVEX_SITE_URL",
140
159
  frontendDevUrl: "http://localhost:3000"
141
160
  };
142
161
  }
@@ -144,7 +163,8 @@ async function suggestedEnvVarName(ctx) {
144
163
  if (isSvelteKit) {
145
164
  return {
146
165
  detectedFramework: "SvelteKit",
147
- envVar: "PUBLIC_CONVEX_URL",
166
+ convexUrlEnvVar: "PUBLIC_CONVEX_URL",
167
+ convexSiteEnvVar: "PUBLIC_CONVEX_SITE_URL",
148
168
  frontendDevUrl: "http://localhost:5173",
149
169
  publicPrefix: "PUBLIC_"
150
170
  };
@@ -153,7 +173,8 @@ async function suggestedEnvVarName(ctx) {
153
173
  if (isTanStackStart) {
154
174
  return {
155
175
  detectedFramework: "TanStackStart",
156
- envVar: "VITE_CONVEX_URL",
176
+ convexUrlEnvVar: "VITE_CONVEX_URL",
177
+ convexSiteEnvVar: "VITE_CONVEX_SITE_URL",
157
178
  frontendDevUrl: "http://localhost:3000",
158
179
  publicPrefix: "VITE_"
159
180
  };
@@ -162,48 +183,80 @@ async function suggestedEnvVarName(ctx) {
162
183
  if (isVite) {
163
184
  return {
164
185
  detectedFramework: "Vite",
165
- envVar: "VITE_CONVEX_URL",
186
+ convexUrlEnvVar: "VITE_CONVEX_URL",
187
+ convexSiteEnvVar: "VITE_CONVEX_SITE_URL",
166
188
  frontendDevUrl: "http://localhost:5173",
167
189
  publicPrefix: "VITE_"
168
190
  };
169
191
  }
170
192
  return {
171
- envVar: "CONVEX_URL"
193
+ convexUrlEnvVar: "CONVEX_URL",
194
+ convexSiteEnvVar: "CONVEX_SITE_URL"
172
195
  };
173
196
  }
174
- async function envVarWriteConfig(ctx, value) {
175
- const { detectedFramework, envVar } = await suggestedEnvVarName(ctx);
197
+ async function loadEnvFileUrlConfig(ctx, options) {
198
+ const { detectedFramework, convexUrlEnvVar, convexSiteEnvVar } = await suggestedEnvVarNames(ctx);
176
199
  const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);
177
200
  if (!existing) {
178
- return { envFile, envVar, existingFileContent: null };
201
+ return {
202
+ envFile,
203
+ convexUrlEnvVar,
204
+ siteUrlEnvVar: convexSiteEnvVar,
205
+ existingFileContent: null
206
+ };
179
207
  }
180
208
  const existingFileContent = ctx.fs.readUtf8File(envFile);
181
209
  const config = dotenv.parse(existingFileContent);
182
- const matching = Object.keys(config).filter((key) => EXPECTED_NAMES.has(key));
210
+ const resolvedConvexUrlEnvVar = resolveEnvVarName(
211
+ convexUrlEnvVar,
212
+ options.convexUrl,
213
+ envFile,
214
+ config,
215
+ EXPECTED_CONVEX_URL_NAMES
216
+ );
217
+ const resolvedSiteUrlEnvVar = resolveEnvVarName(
218
+ convexSiteEnvVar,
219
+ options.siteUrl ?? "",
220
+ envFile,
221
+ config,
222
+ EXPECTED_SITE_URL_NAMES
223
+ );
224
+ if (resolvedConvexUrlEnvVar.kind === "invalid" || resolvedSiteUrlEnvVar.kind === "invalid") {
225
+ return null;
226
+ }
227
+ return {
228
+ envFile,
229
+ convexUrlEnvVar: resolvedConvexUrlEnvVar.envVarName,
230
+ siteUrlEnvVar: resolvedSiteUrlEnvVar.envVarName,
231
+ existingFileContent
232
+ };
233
+ }
234
+ function resolveEnvVarName(envVarName, envVarValue, envFile, config, expectedNames) {
235
+ const matching = Object.keys(config).filter((key) => expectedNames.has(key));
183
236
  if (matching.length > 1) {
184
237
  (0, import_log.logWarning)(
185
238
  import_chalk.chalkStderr.yellow(
186
- `Found multiple CONVEX_URL environment variables in ${envFile} so cannot update automatically.`
239
+ `Found multiple ${envVarName} environment variables in ${envFile} so cannot update automatically.`
187
240
  )
188
241
  );
189
- return null;
242
+ return { kind: "invalid" };
190
243
  }
191
244
  if (matching.length === 1) {
192
- const [existingEnvVar, oldValue] = [matching[0], config[matching[0]]];
193
- if (oldValue === value) {
194
- return null;
245
+ const [existingEnvVarName, oldValue] = [matching[0], config[matching[0]]];
246
+ if (oldValue === envVarValue) {
247
+ return { kind: "valid", envVarName: null };
195
248
  }
196
249
  if (oldValue !== "" && Object.values(config).filter((v) => v === oldValue).length !== 1) {
197
250
  (0, import_log.logWarning)(
198
251
  import_chalk.chalkStderr.yellow(
199
- `Can't safely modify ${envFile}, please edit manually.`
252
+ `Can't safely modify ${envFile} for ${envVarName}, please edit manually.`
200
253
  )
201
254
  );
202
- return null;
255
+ return { kind: "invalid" };
203
256
  }
204
- return { envFile, envVar: existingEnvVar, existingFileContent };
257
+ return { kind: "valid", envVarName: existingEnvVarName };
205
258
  }
206
- return { envFile, envVar, existingFileContent };
259
+ return { kind: "valid", envVarName };
207
260
  }
208
261
  function suggestedDevEnvFile(ctx, framework) {
209
262
  if (ctx.fs.exists(".env.local")) {
@@ -223,7 +276,7 @@ function suggestedDevEnvFile(ctx, framework) {
223
276
  envFile: ".env.local"
224
277
  };
225
278
  }
226
- const EXPECTED_NAMES = /* @__PURE__ */ new Set([
279
+ const EXPECTED_CONVEX_URL_NAMES = /* @__PURE__ */ new Set([
227
280
  "CONVEX_URL",
228
281
  "PUBLIC_CONVEX_URL",
229
282
  "NEXT_PUBLIC_CONVEX_URL",
@@ -231,6 +284,14 @@ const EXPECTED_NAMES = /* @__PURE__ */ new Set([
231
284
  "REACT_APP_CONVEX_URL",
232
285
  "EXPO_PUBLIC_CONVEX_URL"
233
286
  ]);
287
+ const EXPECTED_SITE_URL_NAMES = /* @__PURE__ */ new Set([
288
+ "CONVEX_SITE_URL",
289
+ "PUBLIC_CONVEX_SITE_URL",
290
+ "NEXT_PUBLIC_CONVEX_SITE_URL",
291
+ "VITE_CONVEX_SITE_URL",
292
+ "REACT_APP_CONVEX_SITE_URL",
293
+ "EXPO_PUBLIC_CONVEX_SITE_URL"
294
+ ]);
234
295
  async function detectSuspiciousEnvironmentVariables(ctx, ignoreSuspiciousEnvVars = false) {
235
296
  for (const [key, value] of Object.entries(process.env)) {
236
297
  if (value === "" && key.startsWith("ey")) {
@@ -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\ntype ConvexUrlWriteConfig = {\n envFile: string;\n envVar: string;\n existingFileContent: string | null;\n} | null;\n\nexport async function writeConvexUrlToEnvFile(\n ctx: Context,\n value: string,\n): Promise<ConvexUrlWriteConfig> {\n const writeConfig = await envVarWriteConfig(ctx, value);\n\n if (writeConfig === null) {\n return null;\n }\n\n const { envFile, envVar, existingFileContent } = writeConfig;\n const modified = changedEnvVarFile({\n existingFileContent,\n envVarName: envVar,\n envVarValue: value,\n commentAfterValue: null,\n commentOnPreviousLine: null,\n })!;\n ctx.fs.writeUtf8File(envFile, modified);\n return writeConfig;\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 suggestedEnvVarName(ctx: Context): Promise<{\n detectedFramework?: Framework;\n envVar: string;\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 envVar: \"CONVEX_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 envVar: \"REACT_APP_CONVEX_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 envVar: \"NEXT_PUBLIC_CONVEX_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 envVar: \"EXPO_PUBLIC_CONVEX_URL\",\n publicPrefix: \"EXPO_PUBLIC_\",\n };\n }\n\n const isRemix = \"@remix-run/dev\" in packages;\n if (isRemix) {\n return {\n detectedFramework: \"Remix\",\n envVar: \"CONVEX_URL\",\n frontendDevUrl: \"http://localhost:3000\",\n };\n }\n\n const isSvelteKit = \"@sveltejs/kit\" in packages;\n if (isSvelteKit) {\n return {\n detectedFramework: \"SvelteKit\",\n envVar: \"PUBLIC_CONVEX_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 envVar: \"VITE_CONVEX_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 envVar: \"VITE_CONVEX_URL\",\n frontendDevUrl: \"http://localhost:5173\",\n publicPrefix: \"VITE_\",\n };\n }\n\n return {\n envVar: \"CONVEX_URL\",\n };\n}\n\nasync function envVarWriteConfig(\n ctx: Context,\n value: string | null,\n): Promise<ConvexUrlWriteConfig> {\n const { detectedFramework, envVar } = await suggestedEnvVarName(ctx);\n\n const { envFile, existing } = suggestedDevEnvFile(ctx, detectedFramework);\n\n if (!existing) {\n return { envFile, envVar, existingFileContent: null };\n }\n\n const existingFileContent = ctx.fs.readUtf8File(envFile);\n const config = dotenv.parse(existingFileContent);\n\n const matching = Object.keys(config).filter((key) => EXPECTED_NAMES.has(key));\n if (matching.length > 1) {\n logWarning(\n chalkStderr.yellow(\n `Found multiple CONVEX_URL environment variables in ${envFile} so cannot update automatically.`,\n ),\n );\n return null;\n }\n if (matching.length === 1) {\n const [existingEnvVar, oldValue] = [matching[0], config[matching[0]]];\n if (oldValue === value) {\n return 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}, please edit manually.`,\n ),\n );\n return null;\n }\n return { envFile, envVar: existingEnvVar, existingFileContent };\n }\n return { envFile, envVar, existingFileContent };\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\nconst EXPECTED_NAMES = new Set([\n \"CONVEX_URL\",\n \"PUBLIC_CONVEX_URL\",\n \"NEXT_PUBLIC_CONVEX_URL\",\n \"VITE_CONVEX_URL\",\n \"REACT_APP_CONVEX_URL\",\n \"EXPO_PUBLIC_CONVEX_URL\",\n]);\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 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 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 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\nconst 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\nconst 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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",
6
6
  "names": []
7
7
  }