@estifanos-sh/convex-auth 0.0.5-alpha.0 → 0.0.6

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 (135) hide show
  1. package/dist/bin.js +198 -142
  2. package/dist/component/_generated/component.d.ts +20 -20
  3. package/dist/component/_generated/component.d.ts.map +1 -1
  4. package/dist/component/account.d.ts +30 -30
  5. package/dist/component/account.d.ts.map +1 -1
  6. package/dist/component/connection/audit.d.ts +8 -8
  7. package/dist/component/connection/cache.d.ts +6 -6
  8. package/dist/component/connection/domain/verification.d.ts +15 -15
  9. package/dist/component/connection/domain.d.ts +18 -18
  10. package/dist/component/connection/saml/assertion.d.ts +4 -4
  11. package/dist/component/connection/saml/request.d.ts +7 -7
  12. package/dist/component/connection/saml/request.d.ts.map +1 -1
  13. package/dist/component/connection/scim/config.d.ts +11 -11
  14. package/dist/component/connection/scim/identity.d.ts +47 -47
  15. package/dist/component/connection/secret.d.ts +13 -13
  16. package/dist/component/connection/webhook/delivery.d.ts +11 -11
  17. package/dist/component/connection/webhook/endpoint.d.ts +21 -21
  18. package/dist/component/connection.d.ts +25 -25
  19. package/dist/component/connection.d.ts.map +1 -1
  20. package/dist/component/context.d.ts +18 -18
  21. package/dist/component/context.d.ts.map +1 -1
  22. package/dist/component/crons.d.ts +2 -2
  23. package/dist/component/documents.d.ts +4 -4
  24. package/dist/component/event.d.ts +12 -12
  25. package/dist/component/factor/device.d.ts +21 -21
  26. package/dist/component/factor/device.d.ts.map +1 -1
  27. package/dist/component/factor/passkey.d.ts +71 -71
  28. package/dist/component/factor/passkey.d.ts.map +1 -1
  29. package/dist/component/factor/totp.d.ts +44 -44
  30. package/dist/component/factor/totp.d.ts.map +1 -1
  31. package/dist/component/group/active.d.ts +82 -82
  32. package/dist/component/group/active.d.ts.map +1 -1
  33. package/dist/component/group/invite.d.ts +28 -28
  34. package/dist/component/group/invite.d.ts.map +1 -1
  35. package/dist/component/group/member.d.ts +34 -34
  36. package/dist/component/group/member.d.ts.map +1 -1
  37. package/dist/component/group.d.ts +33 -33
  38. package/dist/component/group.d.ts.map +1 -1
  39. package/dist/component/http.d.ts +2 -2
  40. package/dist/component/limits.d.ts +4 -4
  41. package/dist/component/limits.d.ts.map +1 -1
  42. package/dist/component/maintenance.d.ts +3 -30
  43. package/dist/component/maintenance.d.ts.map +1 -1
  44. package/dist/component/maintenance.js +1 -73
  45. package/dist/component/maintenance.js.map +1 -1
  46. package/dist/component/model.d.ts +438 -438
  47. package/dist/component/model.js +1 -1
  48. package/dist/component/model.js.map +1 -1
  49. package/dist/component/oauth/client.d.ts +19 -19
  50. package/dist/component/oauth/client.js +1 -1
  51. package/dist/component/oauth/client.js.map +1 -1
  52. package/dist/component/oauth/code.d.ts +11 -11
  53. package/dist/component/oauth/refresh.d.ts +16 -16
  54. package/dist/component/schema.d.ts +623 -623
  55. package/dist/component/schema.js +2 -2
  56. package/dist/component/schema.js.map +1 -1
  57. package/dist/component/session.d.ts +31 -32
  58. package/dist/component/session.d.ts.map +1 -1
  59. package/dist/component/session.js +8 -17
  60. package/dist/component/session.js.map +1 -1
  61. package/dist/component/token/continuation.d.ts +14 -14
  62. package/dist/component/token/enrollment.d.ts +7 -7
  63. package/dist/component/token/pkce.d.ts +23 -23
  64. package/dist/component/token/pkce.d.ts.map +1 -1
  65. package/dist/component/token/pkce.js +2 -2
  66. package/dist/component/token/pkce.js.map +1 -1
  67. package/dist/component/token/refresh.d.ts +33 -33
  68. package/dist/component/token/refresh.d.ts.map +1 -1
  69. package/dist/component/token/refresh.js +2 -3
  70. package/dist/component/token/refresh.js.map +1 -1
  71. package/dist/component/token/verification.d.ts +26 -26
  72. package/dist/component/user/email.d.ts +17 -17
  73. package/dist/component/user/email.d.ts.map +1 -1
  74. package/dist/component/user/key.d.ts +26 -26
  75. package/dist/component/user/key.d.ts.map +1 -1
  76. package/dist/component/user.d.ts +28 -28
  77. package/dist/component/user.d.ts.map +1 -1
  78. package/dist/server/auth.d.ts +1 -1
  79. package/dist/server/auth.js +1 -1
  80. package/dist/server/auth.js.map +1 -1
  81. package/dist/server/component/factor/db.js +3 -3
  82. package/dist/server/component/factor/db.js.map +1 -1
  83. package/dist/server/connection/domain.d.ts.map +1 -1
  84. package/dist/server/connection/saml/dom/select.js +1 -5
  85. package/dist/server/connection/saml/dom/select.js.map +1 -1
  86. package/dist/server/connection/saml/encryption.js +2 -2
  87. package/dist/server/connection/saml/encryption.js.map +1 -1
  88. package/dist/server/connection/saml/signature.js +7 -7
  89. package/dist/server/connection/saml/signature.js.map +1 -1
  90. package/dist/server/context.d.ts.map +1 -1
  91. package/dist/server/context.js +1 -2
  92. package/dist/server/context.js.map +1 -1
  93. package/dist/server/core.js +96 -106
  94. package/dist/server/core.js.map +1 -1
  95. package/dist/server/domains/account.d.ts.map +1 -1
  96. package/dist/server/domains/account.js +3 -3
  97. package/dist/server/domains/account.js.map +1 -1
  98. package/dist/server/domains/group.js +1 -1
  99. package/dist/server/domains/group.js.map +1 -1
  100. package/dist/server/domains/member.js +10 -10
  101. package/dist/server/domains/member.js.map +1 -1
  102. package/dist/server/domains/session.js +2 -2
  103. package/dist/server/domains/session.js.map +1 -1
  104. package/dist/server/events.d.ts.map +1 -1
  105. package/dist/server/mutations/account.js +6 -6
  106. package/dist/server/mutations/account.js.map +1 -1
  107. package/dist/server/mutations/calls.js +4 -4
  108. package/dist/server/mutations/{retrieve.js → get.js} +8 -8
  109. package/dist/server/mutations/get.js.map +1 -0
  110. package/dist/server/mutations/{invalidate.js → revoke.js} +8 -8
  111. package/dist/server/mutations/revoke.js.map +1 -0
  112. package/dist/server/mutations/store.js +12 -12
  113. package/dist/server/mutations/store.js.map +1 -1
  114. package/dist/server/oauth/domain.d.ts +0 -2
  115. package/dist/server/oauth/domain.d.ts.map +1 -1
  116. package/dist/server/runtime.d.ts +27 -27
  117. package/dist/server/runtime.d.ts.map +1 -1
  118. package/dist/server/runtime.js +10 -10
  119. package/dist/server/runtime.js.map +1 -1
  120. package/dist/server/services/factors.js +8 -8
  121. package/dist/server/services/factors.js.map +1 -1
  122. package/dist/server/session/lifecycle.d.ts.map +1 -1
  123. package/dist/server/session/lifecycle.js +1 -2
  124. package/dist/server/session/lifecycle.js.map +1 -1
  125. package/dist/server/types.d.ts +34 -20
  126. package/dist/server/types.d.ts.map +1 -1
  127. package/dist/server/validators.d.ts +14 -14
  128. package/dist/server/webauthn.js +4 -4
  129. package/dist/server/webauthn.js.map +1 -1
  130. package/dist/test.d.ts +4 -4
  131. package/package.json +1 -1
  132. package/dist/server/mutations/invalidate.js.map +0 -1
  133. package/dist/server/mutations/retrieve.js.map +0 -1
  134. package/dist/shared/epoch.js +0 -13
  135. package/dist/shared/epoch.js.map +0 -1
package/dist/bin.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
3
  import { execFileSync } from "node:child_process";
4
- import { existsSync, lstatSync, mkdtempSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
4
+ import { existsSync, lstatSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import os, { tmpdir } from "node:os";
6
6
  import path, { dirname, join } from "node:path";
7
7
  import process$1, { stdin, stdout } from "node:process";
8
8
  import { fileURLToPath } from "node:url";
9
- import { stripVTControlCharacters, styleText } from "node:util";
9
+ import { parseArgs, stripVTControlCharacters, styleText } from "node:util";
10
10
  import * as _ from "node:readline";
11
11
  import P from "node:readline";
12
12
  import tty, { ReadStream } from "node:tty";
@@ -6251,6 +6251,49 @@ gradient.summer = summer;
6251
6251
  gradient.rainbow = rainbow;
6252
6252
  gradient.pastel = pastel;
6253
6253
 
6254
+ //#endregion
6255
+ //#region src/cli/convex.ts
6256
+ const cliPathByProject = /* @__PURE__ */ new Map();
6257
+ /** Resolve the Convex CLI installed for a project without invoking its package manager. */
6258
+ function resolveConvexCliPath(projectDirectory = process$1.cwd()) {
6259
+ const projectPath = path.resolve(projectDirectory);
6260
+ const cached = cliPathByProject.get(projectPath);
6261
+ if (cached !== void 0) return cached;
6262
+ const requireFromProject = createRequire(path.join(projectPath, "package.json"));
6263
+ let packagePath;
6264
+ try {
6265
+ packagePath = requireFromProject.resolve("convex/package.json");
6266
+ } catch (cause) {
6267
+ if (typeof cause === "object" && cause !== null && "code" in cause && cause.code !== "MODULE_NOT_FOUND") throw new Error("Could not resolve the project-local Convex package metadata.", { cause });
6268
+ throw new Error("Could not find the project-local \"convex\" package. Install Convex in this project before running convex-auth.", { cause });
6269
+ }
6270
+ let parsedPackageJson;
6271
+ try {
6272
+ parsedPackageJson = JSON.parse(readFileSync(packagePath, "utf8"));
6273
+ } catch (cause) {
6274
+ throw new Error(`Could not read Convex package metadata at ${packagePath}.`, { cause });
6275
+ }
6276
+ if (typeof parsedPackageJson !== "object" || parsedPackageJson === null || Array.isArray(parsedPackageJson)) throw new Error(`Convex package metadata at ${packagePath} is not a JSON object.`);
6277
+ const packageJson = parsedPackageJson;
6278
+ const bin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.convex;
6279
+ if (typeof bin !== "string" || bin.length === 0) throw new Error("The installed \"convex\" package does not expose a convex CLI executable.");
6280
+ const cliPath = path.resolve(path.dirname(packagePath), bin);
6281
+ try {
6282
+ if (!statSync(cliPath).isFile()) throw new Error("not a file");
6283
+ } catch (cause) {
6284
+ throw new Error(`The installed "convex" package points to a missing or invalid CLI file: ${cliPath}`, { cause });
6285
+ }
6286
+ cliPathByProject.set(projectPath, cliPath);
6287
+ return cliPath;
6288
+ }
6289
+ /** Build a shell-free command for the project-local Convex CLI. */
6290
+ function convexCommand(...args) {
6291
+ return {
6292
+ file: process$1.execPath,
6293
+ args: [resolveConvexCliPath(), ...args]
6294
+ };
6295
+ }
6296
+
6254
6297
  //#endregion
6255
6298
  //#region src/shared/keyring.ts
6256
6299
  /** Version of the serialized auth keyring stored in `AUTH_KEYS`. */
@@ -6321,59 +6364,6 @@ function getPackageVersion() {
6321
6364
  return "unknown";
6322
6365
  }
6323
6366
  const version = getPackageVersion();
6324
- function detectPackageRunner() {
6325
- let dir = process$1.cwd();
6326
- const root = path.parse(dir).root;
6327
- while (dir !== root) {
6328
- const pkgPath = path.join(dir, "package.json");
6329
- if (existsSync(pkgPath)) try {
6330
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
6331
- if (typeof pkg.packageManager === "string") {
6332
- const name = pkg.packageManager.split("@")[0];
6333
- if (name === "pnpm") return {
6334
- cmd: "pnpm",
6335
- args: ["exec"]
6336
- };
6337
- if (name === "bun") return {
6338
- cmd: "bunx",
6339
- args: []
6340
- };
6341
- if (name === "yarn") return {
6342
- cmd: "yarn",
6343
- args: ["dlx"]
6344
- };
6345
- }
6346
- } catch {}
6347
- if (existsSync(path.join(dir, "pnpm-lock.yaml"))) return {
6348
- cmd: "pnpm",
6349
- args: ["exec"]
6350
- };
6351
- if (existsSync(path.join(dir, "bun.lockb")) || existsSync(path.join(dir, "bun.lock"))) return {
6352
- cmd: "bunx",
6353
- args: []
6354
- };
6355
- if (existsSync(path.join(dir, "yarn.lock"))) return {
6356
- cmd: "yarn",
6357
- args: ["dlx"]
6358
- };
6359
- dir = path.dirname(dir);
6360
- }
6361
- return {
6362
- cmd: "npx",
6363
- args: []
6364
- };
6365
- }
6366
- const runner = detectPackageRunner();
6367
- function convexCmd(...subArgs) {
6368
- return {
6369
- file: runner.cmd,
6370
- args: [
6371
- ...runner.args,
6372
- "convex",
6373
- ...subArgs
6374
- ]
6375
- };
6376
- }
6377
6367
  const flagDefs = new Map([
6378
6368
  ["app-url", {
6379
6369
  type: "string",
@@ -6395,6 +6385,10 @@ const flagDefs = new Map([
6395
6385
  type: "string",
6396
6386
  description: "Convex deployment URL."
6397
6387
  }],
6388
+ ["site-url", {
6389
+ type: "string",
6390
+ description: "Convex HTTP actions URL (required when it cannot be derived)."
6391
+ }],
6398
6392
  ["admin-key", {
6399
6393
  type: "string",
6400
6394
  description: "Convex admin key."
@@ -6403,13 +6397,9 @@ const flagDefs = new Map([
6403
6397
  type: "boolean",
6404
6398
  description: "Set environment variables on this project's production deployment."
6405
6399
  }],
6406
- ["preview-name", {
6407
- type: "string",
6408
- description: "Set environment variables on the preview deployment with the given name."
6409
- }],
6410
- ["deployment-name", {
6400
+ ["deployment", {
6411
6401
  type: "string",
6412
- description: "Set environment variables on the specified deployment."
6402
+ description: "Target a Convex deployment selector."
6413
6403
  }],
6414
6404
  ["help", {
6415
6405
  type: "boolean",
@@ -6437,73 +6427,58 @@ function printHelp() {
6437
6427
  }
6438
6428
  console.log();
6439
6429
  }
6440
- function parseArgs(argv) {
6441
- const rawArgs = argv.slice(2);
6442
- const knownCommands = new Set([
6430
+ /** @internal */
6431
+ function parseCliOptions(argv) {
6432
+ let parsed;
6433
+ try {
6434
+ parsed = parseArgs({
6435
+ args: argv.slice(2),
6436
+ options: Object.fromEntries([...flagDefs].map(([name, definition]) => [name, { type: definition.type }])),
6437
+ allowPositionals: true,
6438
+ strict: true
6439
+ });
6440
+ } catch (error) {
6441
+ logErrorAndExit(error instanceof Error ? error.message : String(error));
6442
+ }
6443
+ const [commandName, ...extraPositionals] = parsed.positionals;
6444
+ if (commandName !== void 0 && !new Set([
6443
6445
  "setup",
6444
6446
  "doctor",
6445
6447
  "urls",
6446
6448
  "keys"
6447
- ]);
6448
- const firstArg = rawArgs[0];
6449
- const command = knownCommands.has(firstArg ?? "") ? firstArg : "setup";
6450
- const args = command === "setup" && !knownCommands.has(firstArg ?? "") ? rawArgs : rawArgs.slice(1);
6451
- const strings = /* @__PURE__ */ new Map();
6452
- const booleans = /* @__PURE__ */ new Set();
6453
- let i = 0;
6454
- while (i < args.length) {
6455
- const arg = args[i];
6456
- if (!arg.startsWith("--")) {
6457
- i++;
6458
- continue;
6459
- }
6460
- const name = arg.slice(2);
6461
- const def = flagDefs.get(name);
6462
- if (def === void 0) {
6463
- O.error(`Unknown flag: ${arg}`);
6464
- process$1.exit(1);
6465
- }
6466
- if (def.type === "boolean") {
6467
- booleans.add(name);
6468
- i++;
6469
- } else {
6470
- const value = args[i + 1];
6471
- if (value === void 0 || value.startsWith("--")) {
6472
- O.error(`Flag --${name} requires a value.`);
6473
- process$1.exit(1);
6474
- }
6475
- strings.set(name, value);
6476
- i += 2;
6477
- }
6478
- }
6479
- if (booleans.has("help")) {
6449
+ ]).has(commandName)) logErrorAndExit(`Unknown command: ${commandName}`);
6450
+ if (extraPositionals.length > 0) logErrorAndExit(`Unexpected arguments: ${extraPositionals.join(" ")}`);
6451
+ if (parsed.values.help === true) {
6480
6452
  printHelp();
6481
6453
  process$1.exit(0);
6482
6454
  }
6483
- if (booleans.has("version")) {
6455
+ if (parsed.values.version === true) {
6484
6456
  console.log(version);
6485
6457
  process$1.exit(0);
6486
6458
  }
6459
+ const stringValue = (name) => {
6460
+ const value = parsed.values[name];
6461
+ return typeof value === "string" ? value : void 0;
6462
+ };
6487
6463
  return {
6488
- command,
6489
- appUrl: strings.get("app-url"),
6490
- variables: strings.get("variables"),
6491
- skipGitCheck: booleans.has("skip-git-check"),
6492
- allowDirtyGitState: booleans.has("allow-dirty-git-state"),
6493
- url: strings.get("url"),
6494
- adminKey: strings.get("admin-key"),
6495
- prod: booleans.has("prod"),
6496
- previewName: strings.get("preview-name"),
6497
- deploymentName: strings.get("deployment-name")
6464
+ command: commandName ?? "setup",
6465
+ appUrl: stringValue("app-url"),
6466
+ variables: stringValue("variables"),
6467
+ skipGitCheck: parsed.values["skip-git-check"] === true,
6468
+ allowDirtyGitState: parsed.values["allow-dirty-git-state"] === true,
6469
+ url: stringValue("url"),
6470
+ siteUrl: stringValue("site-url"),
6471
+ adminKey: stringValue("admin-key"),
6472
+ prod: parsed.values.prod === true,
6473
+ deployment: stringValue("deployment")
6498
6474
  };
6499
6475
  }
6500
6476
  function validateDeploymentSelectionOptions(options) {
6501
6477
  if ([
6502
6478
  options.url !== void 0,
6503
6479
  options.prod,
6504
- options.previewName !== void 0,
6505
- options.deploymentName !== void 0
6506
- ].filter(Boolean).length > 1) logErrorAndExit("Choose only one of --url, --prod, --preview-name, or --deployment-name.");
6480
+ options.deployment !== void 0
6481
+ ].filter(Boolean).length > 1) logErrorAndExit("Choose only one of --url, --prod, or --deployment.");
6507
6482
  }
6508
6483
  function handleCancel(value) {
6509
6484
  if (q(value)) {
@@ -6550,18 +6525,70 @@ async function runDoctor(options) {
6550
6525
  const configPath = existingNonEmptySourcePath(path.join(convexFolderPath, "convex.config"));
6551
6526
  const authPath = existingNonEmptySourcePath(path.join(convexFolderPath, "auth"));
6552
6527
  const authConfigPath = existingNonEmptySourcePath(path.join(convexFolderPath, "auth.config"));
6553
- if (configPath === null) O.warn("Missing convex.config.ts/js.");
6554
- else O.success(`Found ${configPath}`);
6555
- if (authPath === null) O.warn("Missing auth.ts/js.");
6556
- else O.success(`Found ${authPath}`);
6557
- if (authConfigPath === null) O.warn("Missing auth.config.ts/js.");
6558
- else O.success(`Found ${authConfigPath}`);
6559
- gt("Doctor checks complete.");
6528
+ let healthy = true;
6529
+ if (configPath === null) {
6530
+ healthy = false;
6531
+ O.warn("Missing convex.config.ts/js.");
6532
+ } else O.success(`Found ${configPath}`);
6533
+ if (authPath === null) {
6534
+ healthy = false;
6535
+ O.warn("Missing auth.ts/js.");
6536
+ } else O.success(`Found ${authPath}`);
6537
+ if (authConfigPath === null) {
6538
+ healthy = false;
6539
+ O.warn("Missing auth.config.ts/js.");
6540
+ } else O.success(`Found ${authConfigPath}`);
6541
+ const deployment = readConvexDeployment(options);
6542
+ const config = {
6543
+ isExpo: false,
6544
+ isNextjs: false,
6545
+ isVite: false,
6546
+ usesTypeScript: true,
6547
+ convexFolderPath,
6548
+ deployment,
6549
+ step: 1
6550
+ };
6551
+ for (const name of ["AUTH_KEYS", "APP_URL"]) if (hasBackendEnvVar(config, name)) O.success(`${name} is configured.`);
6552
+ else {
6553
+ healthy = false;
6554
+ O.warn(`${name} is missing or unreadable.`);
6555
+ }
6556
+ const siteUrl = resolveConvexSiteUrl(deployment);
6557
+ if (siteUrl === null) {
6558
+ healthy = false;
6559
+ O.warn("Could not derive the HTTP actions URL. Pass --site-url.");
6560
+ } else {
6561
+ const authSiteUrl = `${siteUrl}/auth`;
6562
+ healthy = await checkAuthEndpoint(`${authSiteUrl}/.well-known/openid-configuration`, "OpenID configuration") && healthy;
6563
+ healthy = await checkAuthEndpoint(`${authSiteUrl}/.well-known/jwks.json`, "JWKS") && healthy;
6564
+ }
6565
+ if (!healthy) process$1.exitCode = 1;
6566
+ gt(healthy ? "Convex Auth is healthy." : "Convex Auth needs attention.");
6567
+ }
6568
+ async function checkAuthEndpoint(url, label) {
6569
+ try {
6570
+ const response = await fetch(url, {
6571
+ headers: { Accept: "application/json" },
6572
+ redirect: "error"
6573
+ });
6574
+ if (!response.ok) {
6575
+ O.warn(`${label} returned HTTP ${response.status}: ${url}`);
6576
+ return false;
6577
+ }
6578
+ await response.json();
6579
+ O.success(`${label} is reachable.`);
6580
+ return true;
6581
+ } catch (error) {
6582
+ O.warn(`${label} is unreachable: ${error instanceof Error ? error.message : String(error)}`);
6583
+ return false;
6584
+ }
6560
6585
  }
6561
6586
  async function runUrls(options) {
6562
6587
  validateDeploymentSelectionOptions(options);
6563
6588
  printBanner();
6564
- const authSiteUrl = `${(readConvexDeployment(options).options.url ?? "https://<deployment>.convex.site").replace(/\/$/, "")}/auth`;
6589
+ const convexSiteUrl = resolveConvexSiteUrl(readConvexDeployment(options));
6590
+ if (convexSiteUrl === null) logErrorAndExit("Could not derive the HTTP actions URL. Pass --site-url.");
6591
+ const authSiteUrl = `${convexSiteUrl.replace(/\/$/, "")}/auth`;
6565
6592
  O.info("Convex Auth URLs:");
6566
6593
  O.message([
6567
6594
  `Issuer: ${authSiteUrl}`,
@@ -6598,7 +6625,7 @@ async function runKeys(options) {
6598
6625
  * @returns A promise that resolves when setup completes successfully.
6599
6626
  */
6600
6627
  const runCli = async (argv = process$1.argv) => {
6601
- const options = parseArgs(argv);
6628
+ const options = parseCliOptions(argv);
6602
6629
  if (options.command === "setup") await runSetup(options);
6603
6630
  else if (options.command === "doctor") await runDoctor(options);
6604
6631
  else if (options.command === "urls") await runUrls(options);
@@ -6683,14 +6710,25 @@ async function configureKeys(config) {
6683
6710
  s2.stop("Keys configured.");
6684
6711
  }
6685
6712
  function backendEnvVar(config, name) {
6686
- const { file, args } = convexCmd("env", "get", ...deploymentArgs(config), name);
6687
- return execFileSync(file, args, {
6713
+ const { file, args } = convexCommand("env", "get", ...deploymentArgs(config), name);
6714
+ return stripTrailingLineBreak(execFileSync(file, args, {
6688
6715
  stdio: "pipe",
6689
6716
  encoding: "utf-8"
6690
- }).slice(0, -1);
6717
+ }));
6718
+ }
6719
+ /** @internal */
6720
+ function stripTrailingLineBreak(output) {
6721
+ return output.replace(/\r?\n$/, "");
6722
+ }
6723
+ function hasBackendEnvVar(config, name) {
6724
+ try {
6725
+ return backendEnvVar(config, name).trim() !== "";
6726
+ } catch {
6727
+ return false;
6728
+ }
6691
6729
  }
6692
6730
  async function setEnvVar(config, name, value, options) {
6693
- const { file, args } = convexCmd("env", "set", ...deploymentArgs(config), "--", name, value);
6731
+ const { file, args } = convexCommand("env", "set", ...deploymentArgs(config), "--", name, value);
6694
6732
  execFileSync(file, args, { stdio: options?.hideValue ? "ignore" : "inherit" });
6695
6733
  if (options?.hideValue) O.success(`Set ${name} on ${printDeployment(config)}`);
6696
6734
  }
@@ -6698,25 +6736,28 @@ async function setEnvVarFromFile(config, name, value) {
6698
6736
  const tmpDir = mkdtempSync(path.join(tmpdir(), "convex-auth-"));
6699
6737
  const tmpFile = path.join(tmpDir, `${name}.tmp`);
6700
6738
  try {
6701
- writeFileSync(tmpFile, value, "utf-8");
6702
- const { file, args } = convexCmd("env", "set", ...deploymentArgs(config), name, "--from-file", tmpFile);
6739
+ writeFileSync(tmpFile, value, {
6740
+ encoding: "utf8",
6741
+ mode: 384
6742
+ });
6743
+ const { file, args } = convexCommand("env", "set", ...deploymentArgs(config), name, "--from-file", tmpFile);
6703
6744
  execFileSync(file, args, { stdio: "ignore" });
6704
6745
  O.success(`Set ${name} on ${printDeployment(config)}`);
6705
6746
  } finally {
6706
- try {
6707
- unlinkSync(tmpFile);
6708
- } catch {}
6747
+ rmSync(tmpDir, {
6748
+ recursive: true,
6749
+ force: true
6750
+ });
6709
6751
  }
6710
6752
  }
6711
6753
  function deploymentArgs(config) {
6712
- const { deployment: { options: { adminKey, url, prod, previewName, deploymentName } } } = config;
6754
+ const { deployment: { options: { adminKey, url, prod, deployment } } } = config;
6713
6755
  const args = [];
6714
6756
  if (adminKey !== void 0) args.push("--admin-key", adminKey);
6715
6757
  const selectionArgs = [
6716
6758
  url ? ["--url", url] : null,
6717
6759
  prod ? ["--prod"] : null,
6718
- previewName ? ["--preview-name", previewName] : null,
6719
- deploymentName ? ["--deployment-name", deploymentName] : null
6760
+ deployment ? ["--deployment", deployment] : null
6720
6761
  ].find((s) => s !== null) ?? [];
6721
6762
  args.push(...selectionArgs);
6722
6763
  return args;
@@ -6754,7 +6795,7 @@ const validTsConfig = `\
6754
6795
  }
6755
6796
  `;
6756
6797
  async function modifyTsConfig(config) {
6757
- logStep(config, "Modify tsconfig file");
6798
+ logStep(config, "Update tsconfig file");
6758
6799
  const projectLevelTsConfigPath = "tsconfig.json";
6759
6800
  const tsConfigPath = path.join(config.convexFolderPath, "tsconfig.json");
6760
6801
  if (!existsSync(tsConfigPath)) {
@@ -6778,7 +6819,7 @@ async function modifyTsConfig(config) {
6778
6819
  return;
6779
6820
  }
6780
6821
  if (!compilerOptionsPattern.test(existingTsConfig)) {
6781
- O.info(`Modify your ${tsConfigPath} to include the following:`);
6822
+ O.info(`Update your ${tsConfigPath} to include the following:`);
6782
6823
  O.message(indent(`\n"moduleResolution": "Bundler",\n"skipLibCheck": true\n`));
6783
6824
  const ready = await ot({ message: "Ready to continue?" });
6784
6825
  handleCancel(ready);
@@ -7061,7 +7102,7 @@ function loadEnvFiles() {
7061
7102
  }
7062
7103
  /** @internal */
7063
7104
  function readConvexDeployment(options) {
7064
- const { adminKey, url, prod, previewName, deploymentName } = options;
7105
+ const { adminKey, url, prod, deployment } = options;
7065
7106
  if (url) return {
7066
7107
  name: url,
7067
7108
  type: null,
@@ -7074,13 +7115,9 @@ function readConvexDeployment(options) {
7074
7115
  name: adminKeyName,
7075
7116
  type: "prod"
7076
7117
  } : null,
7077
- previewName ? {
7078
- name: previewName,
7079
- type: "preview"
7080
- } : null,
7081
- deploymentName ? {
7082
- name: deploymentName,
7083
- type: adminKeyType
7118
+ deployment ? {
7119
+ name: deployment,
7120
+ type: adminKeyType ?? (deployment === "prod" ? "prod" : deployment === "dev" || deployment === "local" ? "dev" : null)
7084
7121
  } : null,
7085
7122
  adminKey ? {
7086
7123
  name: adminKeyName,
@@ -7103,6 +7140,25 @@ function readConvexDeployment(options) {
7103
7140
  logErrorAndExit("Could not find a configured CONVEX_DEPLOYMENT. Did you forget to run `npx convex dev` first?");
7104
7141
  }
7105
7142
  /** @internal */
7143
+ function resolveConvexSiteUrl(deployment) {
7144
+ const explicitSiteUrl = deployment.options.siteUrl;
7145
+ if (explicitSiteUrl !== void 0) return normalizedHttpUrl(explicitSiteUrl);
7146
+ const cloudUrl = deployment.options.url;
7147
+ if (cloudUrl !== void 0) {
7148
+ const parsed = new URL(cloudUrl);
7149
+ if (parsed.hostname.endsWith(".convex.cloud")) parsed.hostname = `${parsed.hostname.slice(0, -13)}.convex.site`;
7150
+ else if ((parsed.hostname === "127.0.0.1" || parsed.hostname === "localhost") && parsed.port === "3210") parsed.port = "3211";
7151
+ return parsed.toString().replace(/\/$/, "");
7152
+ }
7153
+ if (deployment.name !== null && /^[a-z0-9]+(?:-[a-z0-9]+)+$/.test(deployment.name)) return `https://${deployment.name}.convex.site`;
7154
+ return null;
7155
+ }
7156
+ function normalizedHttpUrl(value) {
7157
+ const parsed = new URL(value);
7158
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") logErrorAndExit("Invalid --site-url.", "Expected an HTTP or HTTPS URL.");
7159
+ return parsed.toString().replace(/\/$/, "");
7160
+ }
7161
+ /** @internal */
7106
7162
  function stripDeploymentTypePrefix(deployment) {
7107
7163
  const [type, name] = deployment.split(":");
7108
7164
  if (type !== "prod" && type !== "dev" && type !== "preview" || !name) logErrorAndExit("Invalid CONVEX_DEPLOYMENT.", "Expected a typed deployment like \"dev:my-deployment\", \"prod:my-deployment\", or \"preview:my-deployment\".");
@@ -56,7 +56,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
56
56
  name?: string;
57
57
  phone?: string;
58
58
  phoneVerificationTime?: number;
59
- sessionEpoch?: number;
59
+ sessionEpoch: number;
60
60
  };
61
61
  }, Name>;
62
62
  completeCredentialsSignIn: FunctionReference<"mutation", "internal", {
@@ -94,7 +94,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
94
94
  name?: string;
95
95
  phone?: string;
96
96
  phoneVerificationTime?: number;
97
- sessionEpoch?: number;
97
+ sessionEpoch: number;
98
98
  };
99
99
  }, Name>;
100
100
  create: FunctionReference<"mutation", "internal", {
@@ -888,7 +888,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
888
888
  session: {
889
889
  _creationTime: number;
890
890
  _id: string;
891
- epoch?: number;
891
+ epoch: number;
892
892
  expirationTime: number;
893
893
  userId: string;
894
894
  } | null;
@@ -906,7 +906,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
906
906
  name?: string;
907
907
  phone?: string;
908
908
  phoneVerificationTime?: number;
909
- sessionEpoch?: number;
909
+ sessionEpoch: number;
910
910
  } | null;
911
911
  }, Name>;
912
912
  };
@@ -1527,7 +1527,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1527
1527
  name?: string;
1528
1528
  phone?: string;
1529
1529
  phoneVerificationTime?: number;
1530
- sessionEpoch?: number;
1530
+ sessionEpoch: number;
1531
1531
  };
1532
1532
  }, Name>;
1533
1533
  completeEnrollment: FunctionReference<"mutation", "internal", {
@@ -1581,7 +1581,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1581
1581
  name?: string;
1582
1582
  phone?: string;
1583
1583
  phoneVerificationTime?: number;
1584
- sessionEpoch?: number;
1584
+ sessionEpoch: number;
1585
1585
  };
1586
1586
  }, Name>;
1587
1587
  completeRegistration: FunctionReference<"mutation", "internal", {
@@ -1629,7 +1629,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1629
1629
  name?: string;
1630
1630
  phone?: string;
1631
1631
  phoneVerificationTime?: number;
1632
- sessionEpoch?: number;
1632
+ sessionEpoch: number;
1633
1633
  };
1634
1634
  }, Name>;
1635
1635
  completeRotation: FunctionReference<"mutation", "internal", {
@@ -1680,7 +1680,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1680
1680
  name?: string;
1681
1681
  phone?: string;
1682
1682
  phoneVerificationTime?: number;
1683
- sessionEpoch?: number;
1683
+ sessionEpoch: number;
1684
1684
  };
1685
1685
  }, Name>;
1686
1686
  create: FunctionReference<"mutation", "internal", {
@@ -1837,7 +1837,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1837
1837
  name?: string;
1838
1838
  phone?: string;
1839
1839
  phoneVerificationTime?: number;
1840
- sessionEpoch?: number;
1840
+ sessionEpoch: number;
1841
1841
  };
1842
1842
  }, Name>;
1843
1843
  create: FunctionReference<"mutation", "internal", {
@@ -1872,7 +1872,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1872
1872
  name?: string;
1873
1873
  phone?: string;
1874
1874
  phoneVerificationTime?: number;
1875
- sessionEpoch?: number;
1875
+ sessionEpoch: number;
1876
1876
  };
1877
1877
  verifierId: string;
1878
1878
  }, Name>;
@@ -2689,7 +2689,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2689
2689
  name?: string;
2690
2690
  phone?: string;
2691
2691
  phoneVerificationTime?: number;
2692
- sessionEpoch?: number;
2692
+ sessionEpoch: number;
2693
2693
  };
2694
2694
  userId: string;
2695
2695
  }, Name>;
@@ -2698,7 +2698,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2698
2698
  }, {
2699
2699
  _creationTime: number;
2700
2700
  _id: string;
2701
- epoch?: number;
2701
+ epoch: number;
2702
2702
  expirationTime: number;
2703
2703
  userId: string;
2704
2704
  } | null, Name>;
@@ -2707,7 +2707,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2707
2707
  }, Array<{
2708
2708
  _creationTime: number;
2709
2709
  _id: string;
2710
- epoch?: number;
2710
+ epoch: number;
2711
2711
  expirationTime: number;
2712
2712
  userId: string;
2713
2713
  }>, Name>;
@@ -2802,7 +2802,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2802
2802
  } | null, Name>;
2803
2803
  };
2804
2804
  pkce: {
2805
- consume: FunctionReference<"mutation", "internal", {
2805
+ accept: FunctionReference<"mutation", "internal", {
2806
2806
  expectedSignature?: string;
2807
2807
  selector: {
2808
2808
  id: string;
@@ -2883,7 +2883,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2883
2883
  name?: string;
2884
2884
  phone?: string;
2885
2885
  phoneVerificationTime?: number;
2886
- sessionEpoch?: number;
2886
+ sessionEpoch: number;
2887
2887
  };
2888
2888
  userId: string;
2889
2889
  } | {
@@ -2993,7 +2993,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2993
2993
  name?: string;
2994
2994
  phone?: string;
2995
2995
  phoneVerificationTime?: number;
2996
- sessionEpoch?: number;
2996
+ sessionEpoch: number;
2997
2997
  };
2998
2998
  } | {
2999
2999
  refreshTokenId?: string;
@@ -3015,7 +3015,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
3015
3015
  name?: string;
3016
3016
  phone?: string;
3017
3017
  phoneVerificationTime?: number;
3018
- sessionEpoch?: number;
3018
+ sessionEpoch: number;
3019
3019
  };
3020
3020
  }, Name>;
3021
3021
  create: FunctionReference<"mutation", "internal", {
@@ -3119,7 +3119,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
3119
3119
  name?: string;
3120
3120
  phone?: string;
3121
3121
  phoneVerificationTime?: number;
3122
- sessionEpoch?: number;
3122
+ sessionEpoch: number;
3123
3123
  } | null | Array<{
3124
3124
  _creationTime: number;
3125
3125
  _id: string;
@@ -3134,7 +3134,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
3134
3134
  name?: string;
3135
3135
  phone?: string;
3136
3136
  phoneVerificationTime?: number;
3137
- sessionEpoch?: number;
3137
+ sessionEpoch: number;
3138
3138
  } | null>, Name>;
3139
3139
  key: {
3140
3140
  create: FunctionReference<"mutation", "internal", {
@@ -3320,7 +3320,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
3320
3320
  name?: string;
3321
3321
  phone?: string;
3322
3322
  phoneVerificationTime?: number;
3323
- sessionEpoch?: number;
3323
+ sessionEpoch: number;
3324
3324
  }>;
3325
3325
  pageStatus?: "SplitRecommended" | "SplitRequired" | null;
3326
3326
  splitCursor?: string | null;