convex 1.37.0 → 1.38.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 (218) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/bundler/debugBundle.js +2 -1
  5. package/dist/cjs/bundler/debugBundle.js.map +2 -2
  6. package/dist/cjs/bundler/index.js +6 -3
  7. package/dist/cjs/bundler/index.js.map +2 -2
  8. package/dist/cjs/bundler/serverOnly.js +37 -0
  9. package/dist/cjs/bundler/serverOnly.js.map +7 -0
  10. package/dist/cjs/cli/configure.js +5 -32
  11. package/dist/cjs/cli/configure.js.map +2 -2
  12. package/dist/cjs/cli/deploy.js +1 -1
  13. package/dist/cjs/cli/deploy.js.map +1 -1
  14. package/dist/cjs/cli/deploymentCreate.js +21 -9
  15. package/dist/cjs/cli/deploymentCreate.js.map +2 -2
  16. package/dist/cjs/cli/deploymentSelect.js +25 -0
  17. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  18. package/dist/cjs/cli/deploymentTokenCreate.js +1 -1
  19. package/dist/cjs/cli/deploymentTokenCreate.js.map +2 -2
  20. package/dist/cjs/cli/deploymentTokenDelete.js +1 -1
  21. package/dist/cjs/cli/deploymentTokenDelete.js.map +2 -2
  22. package/dist/cjs/cli/index.js +5 -2
  23. package/dist/cjs/cli/index.js.map +2 -2
  24. package/dist/cjs/cli/lib/deploymentSelection.js +4 -7
  25. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  26. package/dist/cjs/cli/lib/env.js +1 -0
  27. package/dist/cjs/cli/lib/env.js.map +2 -2
  28. package/dist/cjs/cli/lib/localDeployment/anonymous.js +4 -4
  29. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
  30. package/dist/cjs/cli/lib/localDeployment/errors.js +1 -1
  31. package/dist/cjs/cli/lib/localDeployment/errors.js.map +2 -2
  32. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +64 -9
  33. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +2 -2
  34. package/dist/cjs/cli/lib/localDeployment/utils.js +19 -7
  35. package/dist/cjs/cli/lib/localDeployment/utils.js.map +3 -3
  36. package/dist/cjs/cli/lib/utils/globalConfig.js +1 -2
  37. package/dist/cjs/cli/lib/utils/globalConfig.js.map +2 -2
  38. package/dist/cjs/cli/lib/utils/utils.js +8 -0
  39. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  40. package/dist/cjs/index.js +1 -1
  41. package/dist/cjs/index.js.map +1 -1
  42. package/dist/cjs/server/audit_logging.js +3 -1
  43. package/dist/cjs/server/audit_logging.js.map +2 -2
  44. package/dist/cjs/server/components/index.js +1 -12
  45. package/dist/cjs/server/components/index.js.map +2 -2
  46. package/dist/cjs/server/impl/registration_impl.js +8 -5
  47. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  48. package/dist/cjs/server/index.js.map +2 -2
  49. package/dist/cjs/server/log.js.map +2 -2
  50. package/dist/cjs/server/logVars.js.map +2 -2
  51. package/dist/cjs/server/meta.js.map +1 -1
  52. package/dist/cjs-types/bundler/debugBundle.d.ts.map +1 -1
  53. package/dist/cjs-types/bundler/index.d.ts.map +1 -1
  54. package/dist/cjs-types/bundler/serverOnly.d.ts +3 -0
  55. package/dist/cjs-types/bundler/serverOnly.d.ts.map +1 -0
  56. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  57. package/dist/cjs-types/cli/deploymentCreate.d.ts +4 -0
  58. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  59. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  60. package/dist/cjs-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  61. package/dist/cjs-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  62. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +6 -6
  63. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +6 -6
  64. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +8 -8
  65. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  66. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  67. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  68. package/dist/cjs-types/cli/lib/localDeployment/errors.d.ts.map +1 -1
  69. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts +8 -0
  70. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  71. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +13 -4
  72. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  73. package/dist/cjs-types/cli/lib/utils/globalConfig.d.ts +0 -1
  74. package/dist/cjs-types/cli/lib/utils/globalConfig.d.ts.map +1 -1
  75. package/dist/cjs-types/cli/lib/utils/utils.d.ts +7 -0
  76. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  77. package/dist/cjs-types/index.d.ts +1 -1
  78. package/dist/cjs-types/server/audit_logging.d.ts +1 -0
  79. package/dist/cjs-types/server/audit_logging.d.ts.map +1 -1
  80. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  81. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  82. package/dist/cjs-types/server/index.d.ts +2 -0
  83. package/dist/cjs-types/server/index.d.ts.map +1 -1
  84. package/dist/cjs-types/server/log.d.ts +28 -0
  85. package/dist/cjs-types/server/log.d.ts.map +1 -1
  86. package/dist/cjs-types/server/logVars.d.ts +1 -0
  87. package/dist/cjs-types/server/logVars.d.ts.map +1 -1
  88. package/dist/cjs-types/server/meta.d.ts +2 -0
  89. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  90. package/dist/cli.bundle.cjs +1583 -1520
  91. package/dist/cli.bundle.cjs.map +4 -4
  92. package/dist/esm/bundler/debugBundle.js +2 -1
  93. package/dist/esm/bundler/debugBundle.js.map +2 -2
  94. package/dist/esm/bundler/index.js +6 -3
  95. package/dist/esm/bundler/index.js.map +2 -2
  96. package/dist/esm/bundler/serverOnly.js +15 -0
  97. package/dist/esm/bundler/serverOnly.js.map +7 -0
  98. package/dist/esm/cli/configure.js +5 -32
  99. package/dist/esm/cli/configure.js.map +2 -2
  100. package/dist/esm/cli/deploy.js +1 -1
  101. package/dist/esm/cli/deploy.js.map +1 -1
  102. package/dist/esm/cli/deploymentCreate.js +21 -10
  103. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  104. package/dist/esm/cli/deploymentSelect.js +25 -0
  105. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  106. package/dist/esm/cli/deploymentTokenCreate.js +2 -1
  107. package/dist/esm/cli/deploymentTokenCreate.js.map +2 -2
  108. package/dist/esm/cli/deploymentTokenDelete.js +2 -1
  109. package/dist/esm/cli/deploymentTokenDelete.js.map +2 -2
  110. package/dist/esm/cli/index.js +5 -2
  111. package/dist/esm/cli/index.js.map +2 -2
  112. package/dist/esm/cli/lib/deploymentSelection.js +5 -7
  113. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  114. package/dist/esm/cli/lib/env.js +2 -0
  115. package/dist/esm/cli/lib/env.js.map +2 -2
  116. package/dist/esm/cli/lib/localDeployment/anonymous.js +4 -4
  117. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
  118. package/dist/esm/cli/lib/localDeployment/errors.js +1 -1
  119. package/dist/esm/cli/lib/localDeployment/errors.js.map +2 -2
  120. package/dist/esm/cli/lib/localDeployment/localDeployment.js +70 -11
  121. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +2 -2
  122. package/dist/esm/cli/lib/localDeployment/utils.js +19 -7
  123. package/dist/esm/cli/lib/localDeployment/utils.js.map +3 -3
  124. package/dist/esm/cli/lib/utils/globalConfig.js +1 -2
  125. package/dist/esm/cli/lib/utils/globalConfig.js.map +2 -2
  126. package/dist/esm/cli/lib/utils/utils.js +6 -0
  127. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  128. package/dist/esm/index.js +1 -1
  129. package/dist/esm/index.js.map +1 -1
  130. package/dist/esm/server/audit_logging.js +3 -1
  131. package/dist/esm/server/audit_logging.js.map +2 -2
  132. package/dist/esm/server/components/index.js +1 -12
  133. package/dist/esm/server/components/index.js.map +2 -2
  134. package/dist/esm/server/impl/registration_impl.js +8 -5
  135. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  136. package/dist/esm/server/index.js.map +2 -2
  137. package/dist/esm/server/log.js.map +2 -2
  138. package/dist/esm/server/logVars.js.map +2 -2
  139. package/dist/esm-types/bundler/debugBundle.d.ts.map +1 -1
  140. package/dist/esm-types/bundler/index.d.ts.map +1 -1
  141. package/dist/esm-types/bundler/serverOnly.d.ts +3 -0
  142. package/dist/esm-types/bundler/serverOnly.d.ts.map +1 -0
  143. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  144. package/dist/esm-types/cli/deploymentCreate.d.ts +4 -0
  145. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  146. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  147. package/dist/esm-types/cli/deploymentTokenCreate.d.ts.map +1 -1
  148. package/dist/esm-types/cli/deploymentTokenDelete.d.ts.map +1 -1
  149. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +6 -6
  150. package/dist/esm-types/cli/lib/deployApi/modules.d.ts +6 -6
  151. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +8 -8
  152. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  153. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  154. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  155. package/dist/esm-types/cli/lib/localDeployment/errors.d.ts.map +1 -1
  156. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts +8 -0
  157. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  158. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +13 -4
  159. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  160. package/dist/esm-types/cli/lib/utils/globalConfig.d.ts +0 -1
  161. package/dist/esm-types/cli/lib/utils/globalConfig.d.ts.map +1 -1
  162. package/dist/esm-types/cli/lib/utils/utils.d.ts +7 -0
  163. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  164. package/dist/esm-types/index.d.ts +1 -1
  165. package/dist/esm-types/server/audit_logging.d.ts +1 -0
  166. package/dist/esm-types/server/audit_logging.d.ts.map +1 -1
  167. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  168. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  169. package/dist/esm-types/server/index.d.ts +2 -0
  170. package/dist/esm-types/server/index.d.ts.map +1 -1
  171. package/dist/esm-types/server/log.d.ts +28 -0
  172. package/dist/esm-types/server/log.d.ts.map +1 -1
  173. package/dist/esm-types/server/logVars.d.ts +1 -0
  174. package/dist/esm-types/server/logVars.d.ts.map +1 -1
  175. package/dist/esm-types/server/meta.d.ts +2 -0
  176. package/dist/esm-types/server/meta.d.ts.map +1 -1
  177. package/dist/react.bundle.js +1 -1
  178. package/dist/react.bundle.js.map +1 -1
  179. package/package.json +1 -1
  180. package/schemas/convex.schema.json +1 -1
  181. package/src/bundler/debugBundle.ts +2 -1
  182. package/src/bundler/index.ts +7 -3
  183. package/src/bundler/serverOnly.ts +18 -0
  184. package/src/cli/configure.ts +2 -35
  185. package/src/cli/deploy.ts +1 -1
  186. package/src/cli/deploymentCreate.test.ts +4 -0
  187. package/src/cli/deploymentCreate.ts +23 -9
  188. package/src/cli/deploymentSelect.test.ts +60 -6
  189. package/src/cli/deploymentSelect.ts +34 -0
  190. package/src/cli/deploymentSelection.test.ts +72 -19
  191. package/src/cli/deploymentTokenCreate.ts +4 -1
  192. package/src/cli/deploymentTokenDelete.ts +9 -1
  193. package/src/cli/index.ts +6 -2
  194. package/src/cli/lib/deploymentSelection.ts +5 -7
  195. package/src/cli/lib/env.ts +2 -0
  196. package/src/cli/lib/localDeployment/anonymous.ts +5 -4
  197. package/src/cli/lib/localDeployment/errors.ts +1 -3
  198. package/src/cli/lib/localDeployment/localDeployment.ts +85 -10
  199. package/src/cli/lib/localDeployment/utils.ts +31 -7
  200. package/src/cli/lib/utils/globalConfig.ts +0 -3
  201. package/src/cli/lib/utils/utils.ts +15 -0
  202. package/src/index.ts +1 -1
  203. package/src/server/audit_logging.ts +2 -3
  204. package/src/server/components/index.ts +3 -15
  205. package/src/server/impl/registration_impl.ts +13 -7
  206. package/src/server/index.ts +0 -6
  207. package/src/server/log.ts +21 -3
  208. package/src/server/logVars.ts +0 -3
  209. package/src/server/meta.ts +0 -7
  210. package/dist/cjs/cli/disableLocalDev.js +0 -121
  211. package/dist/cjs/cli/disableLocalDev.js.map +0 -7
  212. package/dist/cjs-types/cli/disableLocalDev.d.ts +0 -6
  213. package/dist/cjs-types/cli/disableLocalDev.d.ts.map +0 -1
  214. package/dist/esm/cli/disableLocalDev.js +0 -105
  215. package/dist/esm/cli/disableLocalDev.js.map +0 -7
  216. package/dist/esm-types/cli/disableLocalDev.d.ts +0 -6
  217. package/dist/esm-types/cli/disableLocalDev.d.ts.map +0 -1
  218. package/src/cli/disableLocalDev.ts +0 -134
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var localDeployment_exports = {};
20
20
  __export(localDeployment_exports, {
21
21
  handleLocalDeployment: () => handleLocalDeployment,
22
+ importDefaultEnvVars: () => importDefaultEnvVars,
22
23
  loadLocalDeploymentCredentials: () => loadLocalDeploymentCredentials
23
24
  });
24
25
  module.exports = __toCommonJS(localDeployment_exports);
@@ -31,6 +32,9 @@ var import_prompts = require("../utils/prompts.js");
31
32
  var import_errors = require("./errors.js");
32
33
  var import_utils = require("./utils.js");
33
34
  var import_download = require("./download.js");
35
+ var import_defaultEnv = require("../defaultEnv.js");
36
+ var import_env = require("../env.js");
37
+ var import_deploymentSelection = require("../deploymentSelection.js");
34
38
  async function handleLocalDeployment(ctx, options) {
35
39
  if (await (0, import_utils.isOffline)()) {
36
40
  return handleOffline(ctx, options);
@@ -39,7 +43,8 @@ async function handleLocalDeployment(ctx, options) {
39
43
  projectSlug: options.projectSlug,
40
44
  teamSlug: options.teamSlug
41
45
  });
42
- if (existingDeploymentForProject === null) {
46
+ const isFirstTime = existingDeploymentForProject === null;
47
+ if (isFirstTime) {
43
48
  (0, import_utils.printLocalDeploymentWelcomeMessage)();
44
49
  }
45
50
  ctx.registerCleanup(async (_exitCode, err) => {
@@ -65,10 +70,10 @@ async function handleLocalDeployment(ctx, options) {
65
70
  allowedVersion: existingDeploymentForProject?.config.backendVersion
66
71
  } : { kind: "version", version: options.backendVersion }
67
72
  );
68
- const { cloudPort, sitePort } = await (0, import_utils.chooseLocalBackendPorts)(
69
- ctx,
70
- options.ports
71
- );
73
+ const { cloudPort, sitePort } = await (0, import_utils.chooseLocalBackendPorts)(ctx, {
74
+ requestedPorts: options.ports,
75
+ suggestedPorts: existingDeploymentForProject?.config.ports
76
+ });
72
77
  const { deploymentName, adminKey } = await (0, import_bigBrain.bigBrainStart)(ctx, {
73
78
  port: cloudPort,
74
79
  projectSlug: options.projectSlug,
@@ -99,6 +104,15 @@ async function handleLocalDeployment(ctx, options) {
99
104
  instanceSecret: import_utils.LOCAL_BACKEND_INSTANCE_SECRET,
100
105
  forceUpgrade: options.forceUpgrade
101
106
  });
107
+ if (isFirstTime) {
108
+ await importDefaultEnvVars(ctx, {
109
+ teamSlug: options.teamSlug,
110
+ projectSlug: options.projectSlug,
111
+ deploymentName,
112
+ deploymentUrl: (0, import_run.localDeploymentUrl)(cloudPort),
113
+ adminKey
114
+ });
115
+ }
102
116
  let activityTimeout = null;
103
117
  const scheduleActivityPing = () => {
104
118
  activityTimeout = setTimeout(async () => {
@@ -153,10 +167,11 @@ async function handleOffline(ctx, options) {
153
167
  kind: "version",
154
168
  version: config.backendVersion
155
169
  });
156
- const { cloudPort, sitePort } = await (0, import_utils.chooseLocalBackendPorts)(
157
- ctx,
158
- options.ports
159
- );
170
+ const { cloudPort, sitePort } = await (0, import_utils.chooseLocalBackendPorts)(ctx, {
171
+ requestedPorts: options.ports
172
+ // FIXME: This doesn’t try to reuse the ports already assigned in the config.
173
+ // Please update this if we ever support offline mode (currently this is dead code).
174
+ });
160
175
  (0, import_filePaths.saveDeploymentConfig)(ctx, "local", deploymentName, config);
161
176
  await (0, import_run.runLocalBackend)(ctx, {
162
177
  binaryPath,
@@ -270,4 +285,44 @@ async function chooseFromExistingLocalDeployments(ctx) {
270
285
  }))
271
286
  });
272
287
  }
288
+ async function importDefaultEnvVars(ctx, {
289
+ teamSlug,
290
+ projectSlug,
291
+ deploymentName,
292
+ deploymentUrl,
293
+ adminKey
294
+ }) {
295
+ (0, import_log.showSpinner)("Importing default env vars...");
296
+ const project = await (0, import_deploymentSelection.getProjectDetails)(ctx, {
297
+ kind: "teamAndProjectSlugs",
298
+ teamSlug,
299
+ projectSlug
300
+ });
301
+ const defaults = await (0, import_defaultEnv.defaultEnvBackend)(ctx, project.id, "dev").list();
302
+ if (defaults.length === 0) {
303
+ (0, import_log.logFinishedStep)("No default env vars to import.");
304
+ return;
305
+ }
306
+ const deployment = {
307
+ deploymentUrl,
308
+ deploymentFields: {
309
+ deploymentName,
310
+ deploymentType: "local",
311
+ projectSlug,
312
+ teamSlug
313
+ }
314
+ };
315
+ await (0, import_run.withRunningBackend)({
316
+ ctx,
317
+ deployment,
318
+ action: async () => {
319
+ await (0, import_env.deploymentEnvBackend)(ctx, { deploymentUrl, adminKey }).update(
320
+ defaults.map((v) => ({ name: v.name, value: v.value }))
321
+ );
322
+ (0, import_log.logFinishedStep)(
323
+ `Imported ${defaults.length} environment ${defaults.length === 1 ? "variable" : "variables"} from default environment variables: ${defaults.map((v) => v.name).join(", ")}`
324
+ );
325
+ }
326
+ });
327
+ }
273
328
  //# sourceMappingURL=localDeployment.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/localDeployment.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logVerbose } from \"../../../bundler/log.js\";\nimport {\n bigBrainPause,\n bigBrainRecordActivity,\n bigBrainStart,\n} from \"./bigBrain.js\";\nimport {\n LocalDeploymentConfig,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n legacyDeploymentStateDir,\n rootDeploymentStateDir,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport {\n ensureBackendRunning,\n ensureBackendStopped,\n localDeploymentUrl,\n runLocalBackend,\n} from \"./run.js\";\nimport { handlePotentialUpgrade } from \"./upgrade.js\";\nimport { OnDeploymentActivityFunc } from \"../deployment.js\";\nimport { promptSearch } from \"../utils/prompts.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n chooseLocalBackendPorts,\n printLocalDeploymentWelcomeMessage,\n isOffline,\n LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./utils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n onActivity: OnDeploymentActivityFunc;\n};\n\nexport async function handleLocalDeployment(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports?:\n | {\n cloud: number;\n site: number;\n }\n | undefined;\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n },\n): Promise<DeploymentDetails> {\n if (await isOffline()) {\n return handleOffline(ctx, options);\n }\n\n const existingDeploymentForProject = await getExistingDeployment(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n if (existingDeploymentForProject === null) {\n printLocalDeploymentWelcomeMessage();\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n if (existingDeploymentForProject !== null) {\n logVerbose(`Found existing deployment for project ${options.projectSlug}`);\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: existingDeploymentForProject.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: existingDeploymentForProject.deploymentName,\n allowOtherDeployments: true,\n });\n }\n\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n allowedVersion: existingDeploymentForProject?.config.backendVersion,\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(\n ctx,\n options.ports,\n );\n const { deploymentName, adminKey } = await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: existingDeploymentForProject?.deploymentName ?? null,\n });\n const onActivity = async (isOffline: boolean, _wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n };\n\n const { cleanupHandle } = await handlePotentialUpgrade(ctx, {\n deploymentKind: \"local\",\n deploymentName,\n oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n adminKey,\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n forceUpgrade: options.forceUpgrade,\n });\n\n // Periodically report activity to BigBrain every 60 seconds.\n // Uses self-scheduling setTimeout to avoid overlapping requests.\n let activityTimeout: ReturnType<typeof setTimeout> | null = null;\n const scheduleActivityPing = () => {\n activityTimeout = setTimeout(async () => {\n try {\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n } catch {\n // Best-effort: don't crash on failed pings\n }\n scheduleActivityPing();\n }, 60_000);\n };\n scheduleActivityPing();\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n if (activityTimeout !== null) {\n clearTimeout(activityTimeout);\n }\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n await bigBrainPause(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n });\n\n return {\n adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n onActivity,\n };\n}\n\nexport async function loadLocalDeploymentCredentials(\n ctx: Context,\n deploymentName: string,\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n}> {\n const config = loadDeploymentConfig(ctx, \"local\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n return {\n deploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n adminKey: config.adminKey,\n };\n}\n\nasync function handleOffline(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports?: { cloud: number; site: number } | undefined;\n },\n): Promise<DeploymentDetails> {\n const { deploymentName, config } =\n await chooseFromExistingLocalDeployments(ctx);\n const { binaryPath } = await ensureBackendBinaryDownloaded(ctx, {\n kind: \"version\",\n version: config.backendVersion,\n });\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(\n ctx,\n options.ports,\n );\n saveDeploymentConfig(ctx, \"local\", deploymentName, config);\n await runLocalBackend(ctx, {\n binaryPath,\n ports: { cloud: cloudPort, site: sitePort },\n deploymentName,\n deploymentKind: \"local\",\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n isLatestVersion: false,\n });\n return {\n adminKey: config.adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n onActivity: async (isOffline: boolean, wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n if (wasOffline) {\n await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: deploymentName,\n });\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n },\n };\n}\n\nasync function getExistingDeployment(\n ctx: Context,\n options: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<{ deploymentName: string; config: LocalDeploymentConfig } | null> {\n const { projectSlug, teamSlug } = options;\n\n // Check project-local storage first - this is the new default location\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n // Verify this deployment is for the expected project (matches the naming pattern)\n const expectedPrefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n if (projectLocal.deploymentName.startsWith(expectedPrefix)) {\n return projectLocal;\n }\n logVerbose(\n `Project-local deployment ${projectLocal.deploymentName} doesn't match expected prefix ${expectedPrefix}`,\n );\n }\n\n // Fall back to checking legacy home directory\n const prefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n const existingDeploymentForProject = legacyDeployments.find((d) =>\n d.deploymentName.startsWith(prefix),\n );\n if (existingDeploymentForProject === undefined) {\n return null;\n }\n return {\n deploymentName: existingDeploymentForProject.deploymentName,\n config: existingDeploymentForProject.config,\n };\n}\n\n/**\n * Get local deployments from the legacy home directory location.\n * This is used for backward compatibility and for listing deployments in offline mode.\n */\nasync function getLegacyLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const dir = rootDeploymentStateDir(\"local\");\n if (!ctx.fs.exists(dir)) {\n return [];\n }\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => d.startsWith(\"local-\"));\n return deploymentNames.flatMap((deploymentName) => {\n const legacyDir = legacyDeploymentStateDir(\"local\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n return [{ deploymentName, config }];\n }\n return [];\n });\n}\n\n/**\n * Get all local deployments from both project-local and legacy locations.\n */\nasync function getLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n // Check project-local storage\n const projectLocal = loadProjectLocalConfig(ctx);\n if (\n projectLocal !== null &&\n projectLocal.deploymentName.startsWith(\"local-\")\n ) {\n deployments.push(projectLocal);\n }\n\n // Also include legacy deployments (but avoid duplicates)\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n for (const legacy of legacyDeployments) {\n if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {\n deployments.push(legacy);\n }\n }\n\n return deployments;\n}\n\nasync function chooseFromExistingLocalDeployments(ctx: Context): Promise<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n}> {\n const localDeployments = await getLocalDeployments(ctx);\n\n if (localDeployments.length === 0) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"No local deployments found. Please run `npx convex dev` while online first.\",\n });\n }\n\n // Auto-select if there's only one deployment\n if (localDeployments.length === 1) {\n logVerbose(\n `Auto-selecting the only local deployment: ${localDeployments[0].deploymentName}`,\n );\n return localDeployments[0];\n }\n\n // Multiple deployments (legacy) - prompt user to choose\n return promptSearch(ctx, {\n message: \"Choose from an existing local deployment:\",\n choices: localDeployments.map((d) => ({\n name: d.deploymentName,\n value: d,\n })),\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport {\n logFinishedStep,\n logVerbose,\n showSpinner,\n} from \"../../../bundler/log.js\";\nimport {\n bigBrainPause,\n bigBrainRecordActivity,\n bigBrainStart,\n} from \"./bigBrain.js\";\nimport {\n LocalDeploymentConfig,\n loadDeploymentConfig,\n loadDeploymentConfigFromDir,\n loadProjectLocalConfig,\n legacyDeploymentStateDir,\n rootDeploymentStateDir,\n saveDeploymentConfig,\n} from \"./filePaths.js\";\nimport {\n ensureBackendRunning,\n ensureBackendStopped,\n localDeploymentUrl,\n runLocalBackend,\n withRunningBackend,\n} from \"./run.js\";\nimport { handlePotentialUpgrade } from \"./upgrade.js\";\nimport { OnDeploymentActivityFunc } from \"../deployment.js\";\nimport { promptSearch } from \"../utils/prompts.js\";\nimport { LocalDeploymentError, printLocalDeploymentOnError } from \"./errors.js\";\nimport {\n chooseLocalBackendPorts,\n printLocalDeploymentWelcomeMessage,\n isOffline,\n LOCAL_BACKEND_INSTANCE_SECRET,\n} from \"./utils.js\";\nimport { ensureBackendBinaryDownloaded } from \"./download.js\";\nimport { defaultEnvBackend } from \"../defaultEnv.js\";\nimport { deploymentEnvBackend } from \"../env.js\";\nimport { getProjectDetails } from \"../deploymentSelection.js\";\n\nexport type DeploymentDetails = {\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n onActivity: OnDeploymentActivityFunc;\n};\n\nexport async function handleLocalDeployment(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports?:\n | {\n cloud: number;\n site: number;\n }\n | undefined;\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n },\n): Promise<DeploymentDetails> {\n if (await isOffline()) {\n return handleOffline(ctx, options);\n }\n\n const existingDeploymentForProject = await getExistingDeployment(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n const isFirstTime = existingDeploymentForProject === null;\n if (isFirstTime) {\n printLocalDeploymentWelcomeMessage();\n }\n ctx.registerCleanup(async (_exitCode, err) => {\n if (err instanceof LocalDeploymentError) {\n printLocalDeploymentOnError();\n }\n });\n if (existingDeploymentForProject !== null) {\n logVerbose(`Found existing deployment for project ${options.projectSlug}`);\n // If it's still running for some reason, exit and tell the user to kill it.\n // It's fine if a different backend is running on these ports though since we'll\n // pick new ones.\n await ensureBackendStopped(ctx, {\n ports: {\n cloud: existingDeploymentForProject.config.ports.cloud,\n },\n maxTimeSecs: 5,\n deploymentName: existingDeploymentForProject.deploymentName,\n allowOtherDeployments: true,\n });\n }\n\n const { binaryPath, version } = await ensureBackendBinaryDownloaded(\n ctx,\n options.backendVersion === undefined\n ? {\n kind: \"latest\",\n allowedVersion: existingDeploymentForProject?.config.backendVersion,\n }\n : { kind: \"version\", version: options.backendVersion },\n );\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n suggestedPorts: existingDeploymentForProject?.config.ports,\n });\n const { deploymentName, adminKey } = await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: existingDeploymentForProject?.deploymentName ?? null,\n });\n const onActivity = async (isOffline: boolean, _wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n };\n\n const { cleanupHandle } = await handlePotentialUpgrade(ctx, {\n deploymentKind: \"local\",\n deploymentName,\n oldVersion: existingDeploymentForProject?.config.backendVersion ?? null,\n newBinaryPath: binaryPath,\n newVersion: version,\n ports: { cloud: cloudPort, site: sitePort },\n adminKey,\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n forceUpgrade: options.forceUpgrade,\n });\n\n if (isFirstTime) {\n await importDefaultEnvVars(ctx, {\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n adminKey,\n });\n }\n\n // Periodically report activity to BigBrain every 60 seconds.\n // Uses self-scheduling setTimeout to avoid overlapping requests.\n let activityTimeout: ReturnType<typeof setTimeout> | null = null;\n const scheduleActivityPing = () => {\n activityTimeout = setTimeout(async () => {\n try {\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n } catch {\n // Best-effort: don't crash on failed pings\n }\n scheduleActivityPing();\n }, 60_000);\n };\n scheduleActivityPing();\n\n const cleanupFunc = ctx.removeCleanup(cleanupHandle);\n ctx.registerCleanup(async (exitCode, err) => {\n if (activityTimeout !== null) {\n clearTimeout(activityTimeout);\n }\n if (cleanupFunc !== null) {\n await cleanupFunc(exitCode, err);\n }\n await bigBrainPause(ctx, {\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n });\n });\n\n return {\n adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n onActivity,\n };\n}\n\nexport async function loadLocalDeploymentCredentials(\n ctx: Context,\n deploymentName: string,\n): Promise<{\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n}> {\n const config = loadDeploymentConfig(ctx, \"local\", deploymentName);\n if (config === null) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Failed to load deployment config - try running `npx convex dev --configure`\",\n });\n }\n return {\n deploymentName,\n deploymentUrl: localDeploymentUrl(config.ports.cloud),\n adminKey: config.adminKey,\n };\n}\n\nasync function handleOffline(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n ports?: { cloud: number; site: number } | undefined;\n },\n): Promise<DeploymentDetails> {\n const { deploymentName, config } =\n await chooseFromExistingLocalDeployments(ctx);\n const { binaryPath } = await ensureBackendBinaryDownloaded(ctx, {\n kind: \"version\",\n version: config.backendVersion,\n });\n const { cloudPort, sitePort } = await chooseLocalBackendPorts(ctx, {\n requestedPorts: options.ports,\n // FIXME: This doesn\u2019t try to reuse the ports already assigned in the config.\n // Please update this if we ever support offline mode (currently this is dead code).\n });\n saveDeploymentConfig(ctx, \"local\", deploymentName, config);\n await runLocalBackend(ctx, {\n binaryPath,\n ports: { cloud: cloudPort, site: sitePort },\n deploymentName,\n deploymentKind: \"local\",\n instanceSecret: LOCAL_BACKEND_INSTANCE_SECRET,\n isLatestVersion: false,\n });\n return {\n adminKey: config.adminKey,\n deploymentName,\n deploymentUrl: localDeploymentUrl(cloudPort),\n onActivity: async (isOffline: boolean, wasOffline: boolean) => {\n await ensureBackendRunning(ctx, {\n cloudPort,\n deploymentName,\n maxTimeSecs: 5,\n });\n if (isOffline) {\n return;\n }\n if (wasOffline) {\n await bigBrainStart(ctx, {\n port: cloudPort,\n projectSlug: options.projectSlug,\n teamSlug: options.teamSlug,\n instanceName: deploymentName,\n });\n }\n await bigBrainRecordActivity(ctx, {\n instanceName: deploymentName,\n });\n },\n };\n}\n\nasync function getExistingDeployment(\n ctx: Context,\n options: {\n projectSlug: string;\n teamSlug: string;\n },\n): Promise<{ deploymentName: string; config: LocalDeploymentConfig } | null> {\n const { projectSlug, teamSlug } = options;\n\n // Check project-local storage first - this is the new default location\n const projectLocal = loadProjectLocalConfig(ctx);\n if (projectLocal !== null) {\n // Verify this deployment is for the expected project (matches the naming pattern)\n const expectedPrefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n if (projectLocal.deploymentName.startsWith(expectedPrefix)) {\n return projectLocal;\n }\n logVerbose(\n `Project-local deployment ${projectLocal.deploymentName} doesn't match expected prefix ${expectedPrefix}`,\n );\n }\n\n // Fall back to checking legacy home directory\n const prefix = `local-${teamSlug.replace(/-/g, \"_\")}-${projectSlug.replace(/-/g, \"_\")}`;\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n const existingDeploymentForProject = legacyDeployments.find((d) =>\n d.deploymentName.startsWith(prefix),\n );\n if (existingDeploymentForProject === undefined) {\n return null;\n }\n return {\n deploymentName: existingDeploymentForProject.deploymentName,\n config: existingDeploymentForProject.config,\n };\n}\n\n/**\n * Get local deployments from the legacy home directory location.\n * This is used for backward compatibility and for listing deployments in offline mode.\n */\nasync function getLegacyLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const dir = rootDeploymentStateDir(\"local\");\n if (!ctx.fs.exists(dir)) {\n return [];\n }\n const deploymentNames = ctx.fs\n .listDir(dir)\n .map((d) => d.name)\n .filter((d) => d.startsWith(\"local-\"));\n return deploymentNames.flatMap((deploymentName) => {\n const legacyDir = legacyDeploymentStateDir(\"local\", deploymentName);\n const config = loadDeploymentConfigFromDir(ctx, legacyDir);\n if (config !== null) {\n return [{ deploymentName, config }];\n }\n return [];\n });\n}\n\n/**\n * Get all local deployments from both project-local and legacy locations.\n */\nasync function getLocalDeployments(ctx: Context): Promise<\n Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }>\n> {\n const deployments: Array<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n }> = [];\n\n // Check project-local storage\n const projectLocal = loadProjectLocalConfig(ctx);\n if (\n projectLocal !== null &&\n projectLocal.deploymentName.startsWith(\"local-\")\n ) {\n deployments.push(projectLocal);\n }\n\n // Also include legacy deployments (but avoid duplicates)\n const legacyDeployments = await getLegacyLocalDeployments(ctx);\n for (const legacy of legacyDeployments) {\n if (!deployments.some((d) => d.deploymentName === legacy.deploymentName)) {\n deployments.push(legacy);\n }\n }\n\n return deployments;\n}\n\nasync function chooseFromExistingLocalDeployments(ctx: Context): Promise<{\n deploymentName: string;\n config: LocalDeploymentConfig;\n}> {\n const localDeployments = await getLocalDeployments(ctx);\n\n if (localDeployments.length === 0) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"No local deployments found. Please run `npx convex dev` while online first.\",\n });\n }\n\n // Auto-select if there's only one deployment\n if (localDeployments.length === 1) {\n logVerbose(\n `Auto-selecting the only local deployment: ${localDeployments[0].deploymentName}`,\n );\n return localDeployments[0];\n }\n\n // Multiple deployments (legacy) - prompt user to choose\n return promptSearch(ctx, {\n message: \"Choose from an existing local deployment:\",\n choices: localDeployments.map((d) => ({\n name: d.deploymentName,\n value: d,\n })),\n });\n}\n\n/** Copies the default dev env vars from big brain the first time the local dev backend is started */\nexport async function importDefaultEnvVars(\n ctx: Context,\n {\n teamSlug,\n projectSlug,\n deploymentName,\n deploymentUrl,\n adminKey,\n }: {\n teamSlug: string;\n projectSlug: string;\n deploymentName: string;\n deploymentUrl: string;\n adminKey: string;\n },\n) {\n showSpinner(\"Importing default env vars...\");\n\n const project = await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug,\n projectSlug,\n });\n const defaults = await defaultEnvBackend(ctx, project.id, \"dev\").list();\n if (defaults.length === 0) {\n logFinishedStep(\"No default env vars to import.\");\n return;\n }\n\n const deployment = {\n deploymentUrl,\n deploymentFields: {\n deploymentName,\n deploymentType: \"local\" as const,\n projectSlug,\n teamSlug,\n },\n };\n\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n await deploymentEnvBackend(ctx, { deploymentUrl, adminKey }).update(\n defaults.map((v) => ({ name: v.name, value: v.value })),\n );\n logFinishedStep(\n `Imported ${defaults.length} environment ${defaults.length === 1 ? \"variable\" : \"variables\"} from default environment variables: ${defaults.map((v) => v.name).join(\", \")}`,\n );\n },\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["isOffline"]
7
7
  }
@@ -43,6 +43,7 @@ var import_chalk = require("chalk");
43
43
  async function choosePorts(ctx, {
44
44
  count,
45
45
  requestedPorts,
46
+ suggestedPorts,
46
47
  startPort
47
48
  }) {
48
49
  const ports = [];
@@ -59,6 +60,14 @@ async function choosePorts(ctx, {
59
60
  }
60
61
  ports.push(port);
61
62
  } else {
63
+ const suggestedPort = suggestedPorts?.[ports.length] ?? null;
64
+ if (suggestedPort !== null) {
65
+ const port2 = await (0, import_detect_port.detect)(suggestedPort);
66
+ if (port2 === suggestedPort) {
67
+ ports.push(suggestedPort);
68
+ continue;
69
+ }
70
+ }
62
71
  const portToTry = ports.length > 0 ? ports[ports.length - 1] + 1 : startPort;
63
72
  const port = await (0, import_detect_port.detect)(portToTry);
64
73
  ports.push(port);
@@ -66,11 +75,19 @@ async function choosePorts(ctx, {
66
75
  }
67
76
  return ports;
68
77
  }
69
- async function chooseLocalBackendPorts(ctx, ports) {
78
+ async function chooseLocalBackendPorts(ctx, options) {
79
+ const { suggestedPorts, requestedPorts } = options ?? {};
70
80
  const [cloudPort, sitePort] = await choosePorts(ctx, {
71
81
  count: 2,
72
82
  startPort: 3210,
73
- requestedPorts: [ports?.cloud ?? null, ports?.site ?? null]
83
+ requestedPorts: [
84
+ requestedPorts?.cloud ?? null,
85
+ requestedPorts?.site ?? null
86
+ ],
87
+ suggestedPorts: [
88
+ suggestedPorts?.cloud ?? null,
89
+ suggestedPorts?.site ?? null
90
+ ]
74
91
  });
75
92
  return { cloudPort, sitePort };
76
93
  }
@@ -86,11 +103,6 @@ function printLocalDeploymentWelcomeMessage() {
86
103
  "To learn more, read the docs: https://docs.convex.dev/cli/local-deployments"
87
104
  )
88
105
  );
89
- (0, import_log.logMessage)(
90
- import_chalk.chalkStderr.cyan(
91
- "To opt out at any time, run `npx convex disable-local-deployments`"
92
- )
93
- );
94
106
  }
95
107
  function generateInstanceSecret() {
96
108
  return import_crypto.default.randomBytes(32).toString("hex");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/localDeployment/utils.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { detect } from \"detect-port\";\nimport crypto from \"crypto\";\nimport { chalkStderr } from \"chalk\";\n\nexport async function choosePorts(\n ctx: Context,\n {\n count,\n requestedPorts,\n startPort,\n }: {\n count: number;\n requestedPorts?: Array<number | null>;\n startPort: number;\n },\n): Promise<Array<number>> {\n const ports: Array<number> = [];\n for (let i = 0; i < count; i++) {\n const requestedPort = requestedPorts?.[i];\n if (requestedPort !== null) {\n const port = await detect(requestedPort);\n if (port !== requestedPort) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Requested port ${requestedPort} is not available`,\n });\n }\n ports.push(port);\n } else {\n const portToTry =\n ports.length > 0 ? ports[ports.length - 1] + 1 : startPort;\n const port = await detect(portToTry);\n ports.push(port);\n }\n }\n return ports;\n}\n\nexport async function chooseLocalBackendPorts(\n ctx: Context,\n ports?: { cloud?: number | null; site?: number | null },\n): Promise<{ cloudPort: number; sitePort: number }> {\n const [cloudPort, sitePort] = await choosePorts(ctx, {\n count: 2,\n startPort: 3210,\n requestedPorts: [ports?.cloud ?? null, ports?.site ?? null],\n });\n return { cloudPort, sitePort };\n}\n\nexport async function isOffline(): Promise<boolean> {\n // TODO(ENG-7080) -- implement this for real\n return false;\n}\n\nexport function printLocalDeploymentWelcomeMessage() {\n logMessage(\n chalkStderr.cyan(\"You're trying out the beta local deployment feature!\"),\n );\n logMessage(\n chalkStderr.cyan(\n \"To learn more, read the docs: https://docs.convex.dev/cli/local-deployments\",\n ),\n );\n logMessage(\n chalkStderr.cyan(\n \"To opt out at any time, run `npx convex disable-local-deployments`\",\n ),\n );\n}\n\nexport function generateInstanceSecret(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\nexport const LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAA2B;AAC3B,yBAAuB;AACvB,oBAAmB;AACnB,mBAA4B;AAE5B,eAAsB,YACpB,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AACF,GAKwB;AACxB,QAAM,QAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,gBAAgB,iBAAiB,CAAC;AACxC,QAAI,kBAAkB,MAAM;AAC1B,YAAM,OAAO,UAAM,2BAAO,aAAa;AACvC,UAAI,SAAS,eAAe;AAC1B,eAAO,IAAI,MAAM;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,kBAAkB,aAAa;AAAA,QACjD,CAAC;AAAA,MACH;AACA,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,YAAM,YACJ,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI;AACnD,YAAM,OAAO,UAAM,2BAAO,SAAS;AACnC,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,wBACpB,KACA,OACkD;AAClD,QAAM,CAAC,WAAW,QAAQ,IAAI,MAAM,YAAY,KAAK;AAAA,IACnD,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB,CAAC,OAAO,SAAS,MAAM,OAAO,QAAQ,IAAI;AAAA,EAC5D,CAAC;AACD,SAAO,EAAE,WAAW,SAAS;AAC/B;AAEA,eAAsB,YAA8B;AAElD,SAAO;AACT;AAEO,SAAS,qCAAqC;AACnD;AAAA,IACE,yBAAY,KAAK,sDAAsD;AAAA,EACzE;AACA;AAAA,IACE,yBAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA;AAAA,IACE,yBAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,yBAAiC;AAC/C,SAAO,cAAAA,QAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AAEO,MAAM,gCACX;",
6
- "names": ["crypto"]
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { detect } from \"detect-port\";\nimport crypto from \"crypto\";\nimport { chalkStderr } from \"chalk\";\n\nexport async function choosePorts(\n ctx: Context,\n {\n count,\n requestedPorts,\n suggestedPorts,\n startPort,\n }: {\n count: number;\n /** Ports that must mandatorily be used when provided. */\n requestedPorts?: Array<number | null>;\n /** Ports that will be tried preferentially when provided, but are not required. */\n suggestedPorts?: Array<number | null>;\n startPort: number;\n },\n): Promise<Array<number>> {\n const ports: Array<number> = [];\n for (let i = 0; i < count; i++) {\n const requestedPort = requestedPorts?.[i];\n if (requestedPort !== null) {\n const port = await detect(requestedPort);\n if (port !== requestedPort) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Requested port ${requestedPort} is not available`,\n });\n }\n ports.push(port);\n } else {\n const suggestedPort = suggestedPorts?.[ports.length] ?? null;\n if (suggestedPort !== null) {\n const port = await detect(suggestedPort);\n if (port === suggestedPort) {\n ports.push(suggestedPort);\n continue;\n }\n }\n\n const portToTry =\n ports.length > 0 ? ports[ports.length - 1] + 1 : startPort;\n const port = await detect(portToTry);\n ports.push(port);\n }\n }\n return ports;\n}\n\nexport async function chooseLocalBackendPorts(\n ctx: Context,\n options?: {\n suggestedPorts?:\n | { cloud?: number | null; site?: number | null }\n | undefined;\n requestedPorts?:\n | { cloud?: number | null; site?: number | null }\n | undefined;\n },\n): Promise<{ cloudPort: number; sitePort: number }> {\n const { suggestedPorts, requestedPorts } = options ?? {};\n\n const [cloudPort, sitePort] = await choosePorts(ctx, {\n count: 2,\n startPort: 3210,\n requestedPorts: [\n requestedPorts?.cloud ?? null,\n requestedPorts?.site ?? null,\n ],\n suggestedPorts: [\n suggestedPorts?.cloud ?? null,\n suggestedPorts?.site ?? null,\n ],\n });\n return { cloudPort, sitePort };\n}\n\nexport async function isOffline(): Promise<boolean> {\n // TODO(ENG-7080) -- implement this for real\n return false;\n}\n\nexport function printLocalDeploymentWelcomeMessage() {\n logMessage(\n chalkStderr.cyan(\"You're trying out the beta local deployment feature!\"),\n );\n logMessage(\n chalkStderr.cyan(\n \"To learn more, read the docs: https://docs.convex.dev/cli/local-deployments\",\n ),\n );\n}\n\nexport function generateInstanceSecret(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\nexport const LOCAL_BACKEND_INSTANCE_SECRET =\n \"4361726e697461732c206c69746572616c6c79206d65616e696e6720226c6974\";\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAA2B;AAC3B,yBAAuB;AACvB,oBAAmB;AACnB,mBAA4B;AAE5B,eAAsB,YACpB,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQwB;AACxB,QAAM,QAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,gBAAgB,iBAAiB,CAAC;AACxC,QAAI,kBAAkB,MAAM;AAC1B,YAAM,OAAO,UAAM,2BAAO,aAAa;AACvC,UAAI,SAAS,eAAe;AAC1B,eAAO,IAAI,MAAM;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,kBAAkB,aAAa;AAAA,QACjD,CAAC;AAAA,MACH;AACA,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,YAAM,gBAAgB,iBAAiB,MAAM,MAAM,KAAK;AACxD,UAAI,kBAAkB,MAAM;AAC1B,cAAMA,QAAO,UAAM,2BAAO,aAAa;AACvC,YAAIA,UAAS,eAAe;AAC1B,gBAAM,KAAK,aAAa;AACxB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YACJ,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI;AACnD,YAAM,OAAO,UAAM,2BAAO,SAAS;AACnC,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,wBACpB,KACA,SAQkD;AAClD,QAAM,EAAE,gBAAgB,eAAe,IAAI,WAAW,CAAC;AAEvD,QAAM,CAAC,WAAW,QAAQ,IAAI,MAAM,YAAY,KAAK;AAAA,IACnD,OAAO;AAAA,IACP,WAAW;AAAA,IACX,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,IACA,gBAAgB;AAAA,MACd,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF,CAAC;AACD,SAAO,EAAE,WAAW,SAAS;AAC/B;AAEA,eAAsB,YAA8B;AAElD,SAAO;AACT;AAEO,SAAS,qCAAqC;AACnD;AAAA,IACE,yBAAY,KAAK,sDAAsD;AAAA,EACzE;AACA;AAAA,IACE,yBAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,yBAAiC;AAC/C,SAAO,cAAAC,QAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AAEO,MAAM,gCACX;",
6
+ "names": ["port", "crypto"]
7
7
  }
@@ -44,8 +44,7 @@ function globalConfigPath() {
44
44
  return import_path.default.join((0, import_utils.rootDirectory)(), "config.json");
45
45
  }
46
46
  const schema = import_zod.z.object({
47
- accessToken: import_zod.z.string().min(1),
48
- optOutOfLocalDevDeploymentsUntilBetaOver: import_zod.z.boolean().optional()
47
+ accessToken: import_zod.z.string().min(1)
49
48
  });
50
49
  function readGlobalConfig(ctx) {
51
50
  const configPath = globalConfigPath();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/utils/globalConfig.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport os from \"os\";\nimport path from \"path\";\nimport { rootDirectory } from \"./utils.js\";\nimport { Context } from \"../../../bundler/context.js\";\nimport { logError, logVerbose } from \"../../../bundler/log.js\";\nimport { z } from \"zod\";\n\nexport function globalConfigPath(): string {\n return path.join(rootDirectory(), \"config.json\");\n}\n\n// GlobalConfig is stored in a file that very old versions of Convex also need to access.\n// Everything besides accessToken must be optional forever.\n// GlobalConfig is deleted on logout. It is primarily used for the accessToken.\nexport type GlobalConfig = {\n accessToken: string;\n // Means \"Don't use local dev unless CLI version is at least 1.19\" (actual version TBD)\n optOutOfLocalDevDeploymentsUntilBetaOver?: boolean | undefined;\n};\n\nconst schema = z.object({\n accessToken: z.string().min(1),\n optOutOfLocalDevDeploymentsUntilBetaOver: z.boolean().optional(),\n});\n\nexport function readGlobalConfig(ctx: Context): GlobalConfig | null {\n const configPath = globalConfigPath();\n let configFile;\n try {\n configFile = ctx.fs.readUtf8File(configPath);\n } catch {\n return null;\n }\n try {\n const storedConfig = JSON.parse(configFile);\n const config: GlobalConfig = schema.parse(storedConfig);\n return config;\n } catch (err) {\n // Print an error and act as if the file does not exist.\n logError(\n chalkStderr.red(\n `Failed to parse global config in ${configPath} with error ${\n err as any\n }.`,\n ),\n );\n return null;\n }\n}\n\n/** Write the global config, preserving existing properties we don't understand. */\nexport async function modifyGlobalConfig(ctx: Context, config: GlobalConfig) {\n const configPath = globalConfigPath();\n let configFile;\n try {\n configFile = ctx.fs.readUtf8File(configPath);\n // totally fine for it not to exist\n // eslint-disable-next-line no-empty\n } catch {}\n // storedConfig may contain properties this version of the CLI doesn't understand.\n let storedConfig = {};\n if (configFile) {\n try {\n storedConfig = JSON.parse(configFile);\n schema.parse(storedConfig);\n } catch (err) {\n logError(\n chalkStderr.red(\n `Failed to parse global config in ${configPath} with error ${\n err as any\n }.`,\n ),\n );\n storedConfig = {};\n }\n }\n const newConfig: GlobalConfig = { ...storedConfig, ...config };\n await overrwriteGlobalConfig(ctx, newConfig);\n}\n\n/** Write global config, overwriting any existing settings. */\nasync function overrwriteGlobalConfig(ctx: Context, config: GlobalConfig) {\n const dirName = rootDirectory();\n ctx.fs.mkdir(dirName, { allowExisting: true });\n const path = globalConfigPath();\n try {\n ctx.fs.writeUtf8File(path, JSON.stringify(config, null, 2));\n } catch (err) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: chalkStderr.red(\n `Failed to write auth config to ${path} with error: ${err as any}`,\n ),\n });\n }\n logVerbose(`Saved credentials to ${formatPathForPrinting(path)}`);\n}\n\nexport function formatPathForPrinting(path: string) {\n const homedir = os.homedir();\n if (process.platform === \"darwin\" && path.startsWith(homedir)) {\n return path.replace(homedir, \"~\");\n }\n return path;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAC5B,gBAAe;AACf,kBAAiB;AACjB,mBAA8B;AAE9B,iBAAqC;AACrC,iBAAkB;AAEX,SAAS,mBAA2B;AACzC,SAAO,YAAAA,QAAK,SAAK,4BAAc,GAAG,aAAa;AACjD;AAWA,MAAM,SAAS,aAAE,OAAO;AAAA,EACtB,aAAa,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,0CAA0C,aAAE,QAAQ,EAAE,SAAS;AACjE,CAAC;AAEM,SAAS,iBAAiB,KAAmC;AAClE,QAAM,aAAa,iBAAiB;AACpC,MAAI;AACJ,MAAI;AACF,iBAAa,IAAI,GAAG,aAAa,UAAU;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,eAAe,KAAK,MAAM,UAAU;AAC1C,UAAM,SAAuB,OAAO,MAAM,YAAY;AACtD,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ;AAAA,MACE,yBAAY;AAAA,QACV,oCAAoC,UAAU,eAC5C,GACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,mBAAmB,KAAc,QAAsB;AAC3E,QAAM,aAAa,iBAAiB;AACpC,MAAI;AACJ,MAAI;AACF,iBAAa,IAAI,GAAG,aAAa,UAAU;AAAA,EAG7C,QAAQ;AAAA,EAAC;AAET,MAAI,eAAe,CAAC;AACpB,MAAI,YAAY;AACd,QAAI;AACF,qBAAe,KAAK,MAAM,UAAU;AACpC,aAAO,MAAM,YAAY;AAAA,IAC3B,SAAS,KAAK;AACZ;AAAA,QACE,yBAAY;AAAA,UACV,oCAAoC,UAAU,eAC5C,GACF;AAAA,QACF;AAAA,MACF;AACA,qBAAe,CAAC;AAAA,IAClB;AAAA,EACF;AACA,QAAM,YAA0B,EAAE,GAAG,cAAc,GAAG,OAAO;AAC7D,QAAM,uBAAuB,KAAK,SAAS;AAC7C;AAGA,eAAe,uBAAuB,KAAc,QAAsB;AACxE,QAAM,cAAU,4BAAc;AAC9B,MAAI,GAAG,MAAM,SAAS,EAAE,eAAe,KAAK,CAAC;AAC7C,QAAMA,QAAO,iBAAiB;AAC9B,MAAI;AACF,QAAI,GAAG,cAAcA,OAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC5D,SAAS,KAAK;AACZ,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,cAAc;AAAA,MACd,gBAAgB,yBAAY;AAAA,QAC1B,kCAAkCA,KAAI,gBAAgB,GAAU;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AACA,6BAAW,wBAAwB,sBAAsBA,KAAI,CAAC,EAAE;AAClE;AAEO,SAAS,sBAAsBA,OAAc;AAClD,QAAM,UAAU,UAAAC,QAAG,QAAQ;AAC3B,MAAI,QAAQ,aAAa,YAAYD,MAAK,WAAW,OAAO,GAAG;AAC7D,WAAOA,MAAK,QAAQ,SAAS,GAAG;AAAA,EAClC;AACA,SAAOA;AACT;",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport os from \"os\";\nimport path from \"path\";\nimport { rootDirectory } from \"./utils.js\";\nimport { Context } from \"../../../bundler/context.js\";\nimport { logError, logVerbose } from \"../../../bundler/log.js\";\nimport { z } from \"zod\";\n\nexport function globalConfigPath(): string {\n return path.join(rootDirectory(), \"config.json\");\n}\n\n// GlobalConfig is stored in a file that very old versions of Convex also need to access.\n// Everything besides accessToken must be optional forever.\n// GlobalConfig is deleted on logout. It is primarily used for the accessToken.\nexport type GlobalConfig = {\n accessToken: string;\n};\n\nconst schema = z.object({\n accessToken: z.string().min(1),\n});\n\nexport function readGlobalConfig(ctx: Context): GlobalConfig | null {\n const configPath = globalConfigPath();\n let configFile;\n try {\n configFile = ctx.fs.readUtf8File(configPath);\n } catch {\n return null;\n }\n try {\n const storedConfig = JSON.parse(configFile);\n const config: GlobalConfig = schema.parse(storedConfig);\n return config;\n } catch (err) {\n // Print an error and act as if the file does not exist.\n logError(\n chalkStderr.red(\n `Failed to parse global config in ${configPath} with error ${\n err as any\n }.`,\n ),\n );\n return null;\n }\n}\n\n/** Write the global config, preserving existing properties we don't understand. */\nexport async function modifyGlobalConfig(ctx: Context, config: GlobalConfig) {\n const configPath = globalConfigPath();\n let configFile;\n try {\n configFile = ctx.fs.readUtf8File(configPath);\n // totally fine for it not to exist\n // eslint-disable-next-line no-empty\n } catch {}\n // storedConfig may contain properties this version of the CLI doesn't understand.\n let storedConfig = {};\n if (configFile) {\n try {\n storedConfig = JSON.parse(configFile);\n schema.parse(storedConfig);\n } catch (err) {\n logError(\n chalkStderr.red(\n `Failed to parse global config in ${configPath} with error ${\n err as any\n }.`,\n ),\n );\n storedConfig = {};\n }\n }\n const newConfig: GlobalConfig = { ...storedConfig, ...config };\n await overrwriteGlobalConfig(ctx, newConfig);\n}\n\n/** Write global config, overwriting any existing settings. */\nasync function overrwriteGlobalConfig(ctx: Context, config: GlobalConfig) {\n const dirName = rootDirectory();\n ctx.fs.mkdir(dirName, { allowExisting: true });\n const path = globalConfigPath();\n try {\n ctx.fs.writeUtf8File(path, JSON.stringify(config, null, 2));\n } catch (err) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: chalkStderr.red(\n `Failed to write auth config to ${path} with error: ${err as any}`,\n ),\n });\n }\n logVerbose(`Saved credentials to ${formatPathForPrinting(path)}`);\n}\n\nexport function formatPathForPrinting(path: string) {\n const homedir = os.homedir();\n if (process.platform === \"darwin\" && path.startsWith(homedir)) {\n return path.replace(homedir, \"~\");\n }\n return path;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAC5B,gBAAe;AACf,kBAAiB;AACjB,mBAA8B;AAE9B,iBAAqC;AACrC,iBAAkB;AAEX,SAAS,mBAA2B;AACzC,SAAO,YAAAA,QAAK,SAAK,4BAAc,GAAG,aAAa;AACjD;AASA,MAAM,SAAS,aAAE,OAAO;AAAA,EACtB,aAAa,aAAE,OAAO,EAAE,IAAI,CAAC;AAC/B,CAAC;AAEM,SAAS,iBAAiB,KAAmC;AAClE,QAAM,aAAa,iBAAiB;AACpC,MAAI;AACJ,MAAI;AACF,iBAAa,IAAI,GAAG,aAAa,UAAU;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,eAAe,KAAK,MAAM,UAAU;AAC1C,UAAM,SAAuB,OAAO,MAAM,YAAY;AACtD,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ;AAAA,MACE,yBAAY;AAAA,QACV,oCAAoC,UAAU,eAC5C,GACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,mBAAmB,KAAc,QAAsB;AAC3E,QAAM,aAAa,iBAAiB;AACpC,MAAI;AACJ,MAAI;AACF,iBAAa,IAAI,GAAG,aAAa,UAAU;AAAA,EAG7C,QAAQ;AAAA,EAAC;AAET,MAAI,eAAe,CAAC;AACpB,MAAI,YAAY;AACd,QAAI;AACF,qBAAe,KAAK,MAAM,UAAU;AACpC,aAAO,MAAM,YAAY;AAAA,IAC3B,SAAS,KAAK;AACZ;AAAA,QACE,yBAAY;AAAA,UACV,oCAAoC,UAAU,eAC5C,GACF;AAAA,QACF;AAAA,MACF;AACA,qBAAe,CAAC;AAAA,IAClB;AAAA,EACF;AACA,QAAM,YAA0B,EAAE,GAAG,cAAc,GAAG,OAAO;AAC7D,QAAM,uBAAuB,KAAK,SAAS;AAC7C;AAGA,eAAe,uBAAuB,KAAc,QAAsB;AACxE,QAAM,cAAU,4BAAc;AAC9B,MAAI,GAAG,MAAM,SAAS,EAAE,eAAe,KAAK,CAAC;AAC7C,QAAMA,QAAO,iBAAiB;AAC9B,MAAI;AACF,QAAI,GAAG,cAAcA,OAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC5D,SAAS,KAAK;AACZ,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,cAAc;AAAA,MACd,gBAAgB,yBAAY;AAAA,QAC1B,kCAAkCA,KAAI,gBAAgB,GAAU;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AACA,6BAAW,wBAAwB,sBAAsBA,KAAI,CAAC,EAAE;AAClE;AAEO,SAAS,sBAAsBA,OAAc;AAClD,QAAM,UAAU,UAAAC,QAAG,QAAQ;AAC3B,MAAI,QAAQ,aAAa,YAAYD,MAAK,WAAW,OAAO,GAAG;AAC7D,WAAOA,MAAK,QAAQ,SAAS,GAAG;AAAA,EAClC;AACA,SAAOA;AACT;",
6
6
  "names": ["path", "os"]
7
7
  }
@@ -32,6 +32,7 @@ var utils_exports = {};
32
32
  __export(utils_exports, {
33
33
  BIG_BRAIN_URL: () => BIG_BRAIN_URL,
34
34
  CONVEX_DEPLOYMENT_ENV_VAR_NAME: () => CONVEX_DEPLOYMENT_ENV_VAR_NAME,
35
+ CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME: () => CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME,
35
36
  CONVEX_DEPLOY_KEY_ENV_VAR_NAME: () => CONVEX_DEPLOY_KEY_ENV_VAR_NAME,
36
37
  CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME: () => CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME,
37
38
  CONVEX_SELF_HOSTED_URL_VAR_NAME: () => CONVEX_SELF_HOSTED_URL_VAR_NAME,
@@ -65,6 +66,7 @@ __export(utils_exports, {
65
66
  processDeployKeyValue: () => processDeployKeyValue,
66
67
  productionProvisionHost: () => productionProvisionHost,
67
68
  provisionHost: () => provisionHost,
69
+ readDeployKeyFromEnv: () => readDeployKeyFromEnv,
68
70
  rootDirectory: () => rootDirectory,
69
71
  selectDevDeploymentType: () => selectDevDeploymentType,
70
72
  selectRegion: () => selectRegion,
@@ -99,6 +101,7 @@ const BIG_BRAIN_URL = `${provisionHost}/api/`;
99
101
  const PLATFORM_MANAGEMENT_API_URL = `${provisionHost}/v1/`;
100
102
  const ENV_VAR_FILE_PATH = ".env.local";
101
103
  const CONVEX_DEPLOY_KEY_ENV_VAR_NAME = "CONVEX_DEPLOY_KEY";
104
+ const CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME = "CONVEX_DEPLOYMENT_TOKEN";
102
105
  const CONVEX_DEPLOYMENT_ENV_VAR_NAME = "CONVEX_DEPLOYMENT";
103
106
  const CONVEX_SELF_HOSTED_URL_VAR_NAME = "CONVEX_SELF_HOSTED_URL";
104
107
  const CONVEX_SELF_HOSTED_ADMIN_KEY_VAR_NAME = "CONVEX_SELF_HOSTED_ADMIN_KEY";
@@ -123,6 +126,11 @@ async function processDeployKeyValue(ctx, deployKey) {
123
126
  }
124
127
  return deployKey;
125
128
  }
129
+ function readDeployKeyFromEnv(getEnv) {
130
+ const fromDeployKey = getEnv(CONVEX_DEPLOY_KEY_ENV_VAR_NAME);
131
+ const fromToken = getEnv(CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME);
132
+ return fromDeployKey || fromToken || void 0;
133
+ }
126
134
  function parsePositiveInteger(value) {
127
135
  const parsedValue = parseInteger(value);
128
136
  if (parsedValue <= 0) {