convex 1.43.0 → 1.44.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 (90) hide show
  1. package/CHANGELOG.md +130 -113
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/codegen_templates/component_server.js +4 -3
  5. package/dist/cjs/cli/codegen_templates/component_server.js.map +2 -2
  6. package/dist/cjs/cli/codegen_templates/server.js +24 -12
  7. package/dist/cjs/cli/codegen_templates/server.js.map +2 -2
  8. package/dist/cjs/cli/lib/login.js +12 -8
  9. package/dist/cjs/cli/lib/login.js.map +2 -2
  10. package/dist/cjs/cli/login.js +52 -7
  11. package/dist/cjs/cli/login.js.map +2 -2
  12. package/dist/cjs/index.js +1 -1
  13. package/dist/cjs/index.js.map +1 -1
  14. package/dist/cjs/react/ConvexAuthState.js +30 -32
  15. package/dist/cjs/react/ConvexAuthState.js.map +2 -2
  16. package/dist/cjs/server/impl/actions_impl.js +12 -0
  17. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  18. package/dist/cjs/server/index.js +3 -0
  19. package/dist/cjs/server/index.js.map +2 -2
  20. package/dist/cjs/server/schema.js +69 -1
  21. package/dist/cjs/server/schema.js.map +2 -2
  22. package/dist/cjs-types/cli/codegen_templates/component_server.d.ts.map +1 -1
  23. package/dist/cjs-types/cli/codegen_templates/server.d.ts +1 -0
  24. package/dist/cjs-types/cli/codegen_templates/server.d.ts.map +1 -1
  25. package/dist/cjs-types/cli/lib/login.d.ts +5 -0
  26. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  27. package/dist/cjs-types/cli/login.d.ts.map +1 -1
  28. package/dist/cjs-types/cli/login.test.d.ts +2 -0
  29. package/dist/cjs-types/cli/login.test.d.ts.map +1 -0
  30. package/dist/cjs-types/index.d.ts +1 -1
  31. package/dist/cjs-types/react/ConvexAuthState.d.ts.map +1 -1
  32. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  33. package/dist/cjs-types/server/impl/actions_impl.test.d.ts +2 -0
  34. package/dist/cjs-types/server/impl/actions_impl.test.d.ts.map +1 -0
  35. package/dist/cjs-types/server/index.d.ts +2 -2
  36. package/dist/cjs-types/server/index.d.ts.map +1 -1
  37. package/dist/cjs-types/server/schema.d.ts +83 -5
  38. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  39. package/dist/cli.bundle.cjs +1277 -570
  40. package/dist/cli.bundle.cjs.map +4 -4
  41. package/dist/esm/cli/codegen_templates/component_server.js +8 -4
  42. package/dist/esm/cli/codegen_templates/component_server.js.map +2 -2
  43. package/dist/esm/cli/codegen_templates/server.js +22 -11
  44. package/dist/esm/cli/codegen_templates/server.js.map +2 -2
  45. package/dist/esm/cli/lib/login.js +11 -8
  46. package/dist/esm/cli/lib/login.js.map +2 -2
  47. package/dist/esm/cli/login.js +54 -10
  48. package/dist/esm/cli/login.js.map +2 -2
  49. package/dist/esm/index.js +1 -1
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/react/ConvexAuthState.js +31 -32
  52. package/dist/esm/react/ConvexAuthState.js.map +2 -2
  53. package/dist/esm/server/impl/actions_impl.js +11 -0
  54. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  55. package/dist/esm/server/index.js +2 -1
  56. package/dist/esm/server/index.js.map +2 -2
  57. package/dist/esm/server/schema.js +67 -0
  58. package/dist/esm/server/schema.js.map +2 -2
  59. package/dist/esm-types/cli/codegen_templates/component_server.d.ts.map +1 -1
  60. package/dist/esm-types/cli/codegen_templates/server.d.ts +1 -0
  61. package/dist/esm-types/cli/codegen_templates/server.d.ts.map +1 -1
  62. package/dist/esm-types/cli/lib/login.d.ts +5 -0
  63. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  64. package/dist/esm-types/cli/login.d.ts.map +1 -1
  65. package/dist/esm-types/cli/login.test.d.ts +2 -0
  66. package/dist/esm-types/cli/login.test.d.ts.map +1 -0
  67. package/dist/esm-types/index.d.ts +1 -1
  68. package/dist/esm-types/react/ConvexAuthState.d.ts.map +1 -1
  69. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  70. package/dist/esm-types/server/impl/actions_impl.test.d.ts +2 -0
  71. package/dist/esm-types/server/impl/actions_impl.test.d.ts.map +1 -0
  72. package/dist/esm-types/server/index.d.ts +2 -2
  73. package/dist/esm-types/server/index.d.ts.map +1 -1
  74. package/dist/esm-types/server/schema.d.ts +83 -5
  75. package/dist/esm-types/server/schema.d.ts.map +1 -1
  76. package/dist/react.bundle.js +31 -33
  77. package/dist/react.bundle.js.map +2 -2
  78. package/package.json +3 -4
  79. package/src/cli/codegen_templates/component_server.ts +12 -6
  80. package/src/cli/codegen_templates/server.ts +36 -19
  81. package/src/cli/lib/login.ts +20 -9
  82. package/src/cli/login.test.ts +261 -0
  83. package/src/cli/login.ts +88 -13
  84. package/src/index.ts +1 -1
  85. package/src/react/ConvexAuthState.tsx +15 -7
  86. package/src/server/impl/actions_impl.test.ts +59 -0
  87. package/src/server/impl/actions_impl.ts +23 -0
  88. package/src/server/index.ts +7 -1
  89. package/src/server/schema.test.ts +98 -0
  90. package/src/server/schema.ts +178 -1
@@ -24,8 +24,9 @@ module.exports = __toCommonJS(component_server_exports);
24
24
  var import_common = require("./common.js");
25
25
  var import_server = require("./server.js");
26
26
  function componentServerTS(isRoot, envVars) {
27
- const hasEnv = !!envVars && envVars.length > 0;
28
- const envInterface = hasEnv ? (0, import_server.generateEnvInterface)(envVars) : "";
27
+ const emittedEnvVars = envVars === void 0 ? void 0 : (0, import_server.withPlatformEnvVars)(envVars);
28
+ const hasEnv = emittedEnvVars !== void 0;
29
+ const envInterface = hasEnv ? (0, import_server.generateEnvInterface)(emittedEnvVars) : "";
29
30
  const result = `
30
31
  ${(0, import_common.header)(
31
32
  "Generated utilities for implementing server-side Convex query and mutation functions."
@@ -128,7 +129,7 @@ function componentServerTS(isRoot, envVars) {
128
129
  * @returns The wrapped function. Import this function from \`convex/http.js\` and route it to hook it up.
129
130
  */
130
131
  export const httpAction: HttpActionBuilder = httpActionGeneric;
131
- ${hasEnv ? "export const env: Env = process.env as unknown as Env;" : envVars === void 0 ? "export const env: Record<string, string | undefined> = process.env as unknown as Record<string, string | undefined>;" : ""}
132
+ ${hasEnv ? "export const env: Env = (globalThis as unknown as { process: { env: Env } }).process.env;" : "export const env: Record<string, string | undefined> = (globalThis as unknown as { process: { env: Record<string, string | undefined> } }).process.env;"}
132
133
 
133
134
  /**
134
135
  * A set of services for use within Convex query functions.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/codegen_templates/component_server.ts"],
4
- "sourcesContent": ["import { header } from \"./common.js\";\nimport { EnvVarMeta, generateEnvInterface } from \"./server.js\";\n\nexport function componentServerTS(\n isRoot: boolean,\n // - undefined: not yet known (initial codegen). Emits an untyped `env` stub.\n // - non-empty array: emit typed `Env` interface and typed `env` export.\n // - empty array: no env vars declared. Omit `env` from generated code.\n envVars: EnvVarMeta[] | undefined,\n): string {\n const hasEnv = !!envVars && envVars.length > 0;\n const envInterface = hasEnv ? generateEnvInterface(envVars!) : \"\";\n\n const result = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import type {\n ActionBuilder,\n ${isRoot ? \"AnyComponents,\" : \"\"}\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n } from \"convex/server\";\n import {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n ${isRoot ? \"componentsGeneric,\" : \"\"}\n } from \"convex/server\";\n import type { DataModel } from \"./dataModel.js\";\n ${envInterface}\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalQuery: QueryBuilder<DataModel, \"internal\"> = internalQueryGeneric;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalMutation: MutationBuilder<DataModel, \"internal\"> = internalMutationGeneric;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalAction: ActionBuilder<DataModel, \"internal\"> = internalActionGeneric;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export const httpAction: HttpActionBuilder = httpActionGeneric;\n ${hasEnv ? \"export const env: Env = process.env as unknown as Env;\" : envVars === undefined ? \"export const env: Record<string, string | undefined> = process.env as unknown as Record<string, string | undefined>;\" : \"\"}\n\n /**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * If you're using code generation, use the \\`QueryCtx\\` type in \\`convex/_generated/server.d.ts\\` instead.\n */\n export type QueryCtx = GenericQueryCtx<DataModel>;\n\n /**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n *\n * If you're using code generation, use the \\`MutationCtx\\` type in \\`convex/_generated/server.d.ts\\` instead.\n */\n export type MutationCtx = GenericMutationCtx<DataModel>;\n\n /**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\n export type ActionCtx = GenericActionCtx<DataModel>;\n\n /**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\n export type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n /**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\n export type DatabaseWriter = GenericDatabaseWriter<DataModel>;\n ${\n isRoot\n ? `\n /**\n * Load the API for calling functions from this Convex deployment's components.\n */\n export const components: AnyComponents = componentsGeneric();`\n : \"\"\n }\n `;\n return result;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AACvB,oBAAiD;AAE1C,SAAS,kBACd,QAIA,SACQ;AACR,QAAM,SAAS,CAAC,CAAC,WAAW,QAAQ,SAAS;AAC7C,QAAM,eAAe,aAAS,oCAAqB,OAAQ,IAAI;AAE/D,QAAM,SAAS;AAAA,QACb;AAAA,IACA;AAAA,EACF,CAAC;AAAA;AAAA;AAAA,MAGG,SAAS,mBAAmB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkB9B,SAAS,uBAAuB,EAAE;AAAA;AAAA;AAAA,IAGpC,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2EZ,SAAS,2DAA2D,YAAY,SAAY,yHAAyH,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkDvN,SACI;AAAA;AAAA;AAAA;AAAA,mEAKA,EACN;AAAA;AAEA,SAAO;AACT;",
4
+ "sourcesContent": ["import { header } from \"./common.js\";\nimport {\n EnvVarMeta,\n generateEnvInterface,\n withPlatformEnvVars,\n} from \"./server.js\";\n\nexport function componentServerTS(\n isRoot: boolean,\n // - undefined: not yet known (initial codegen). Emits an untyped `env` stub.\n // - array (empty or not): emit a typed `Env` interface and typed `env`\n // export. The interface always includes the platform-provided env vars.\n envVars: EnvVarMeta[] | undefined,\n): string {\n const emittedEnvVars =\n envVars === undefined ? undefined : withPlatformEnvVars(envVars);\n const hasEnv = emittedEnvVars !== undefined;\n const envInterface = hasEnv ? generateEnvInterface(emittedEnvVars!) : \"\";\n\n const result = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import type {\n ActionBuilder,\n ${isRoot ? \"AnyComponents,\" : \"\"}\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n } from \"convex/server\";\n import {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n ${isRoot ? \"componentsGeneric,\" : \"\"}\n } from \"convex/server\";\n import type { DataModel } from \"./dataModel.js\";\n ${envInterface}\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalQuery: QueryBuilder<DataModel, \"internal\"> = internalQueryGeneric;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalMutation: MutationBuilder<DataModel, \"internal\"> = internalMutationGeneric;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalAction: ActionBuilder<DataModel, \"internal\"> = internalActionGeneric;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export const httpAction: HttpActionBuilder = httpActionGeneric;\n ${hasEnv ? \"export const env: Env = (globalThis as unknown as { process: { env: Env } }).process.env;\" : \"export const env: Record<string, string | undefined> = (globalThis as unknown as { process: { env: Record<string, string | undefined> } }).process.env;\"}\n\n /**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * If you're using code generation, use the \\`QueryCtx\\` type in \\`convex/_generated/server.d.ts\\` instead.\n */\n export type QueryCtx = GenericQueryCtx<DataModel>;\n\n /**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n *\n * If you're using code generation, use the \\`MutationCtx\\` type in \\`convex/_generated/server.d.ts\\` instead.\n */\n export type MutationCtx = GenericMutationCtx<DataModel>;\n\n /**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\n export type ActionCtx = GenericActionCtx<DataModel>;\n\n /**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\n export type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n /**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\n export type DatabaseWriter = GenericDatabaseWriter<DataModel>;\n ${\n isRoot\n ? `\n /**\n * Load the API for calling functions from this Convex deployment's components.\n */\n export const components: AnyComponents = componentsGeneric();`\n : \"\"\n }\n `;\n return result;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AACvB,oBAIO;AAEA,SAAS,kBACd,QAIA,SACQ;AACR,QAAM,iBACJ,YAAY,SAAY,aAAY,mCAAoB,OAAO;AACjE,QAAM,SAAS,mBAAmB;AAClC,QAAM,eAAe,aAAS,oCAAqB,cAAe,IAAI;AAEtE,QAAM,SAAS;AAAA,QACb;AAAA,IACA;AAAA,EACF,CAAC;AAAA;AAAA;AAAA,MAGG,SAAS,mBAAmB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkB9B,SAAS,uBAAuB,EAAE;AAAA;AAAA;AAAA,IAGpC,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2EZ,SAAS,8FAA8F,yJAAyJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkDhQ,SACI;AAAA;AAAA;AAAA;AAAA,mEAKA,EACN;AAAA;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -19,38 +19,50 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var server_exports = {};
20
20
  __export(server_exports, {
21
21
  generateEnvInterface: () => generateEnvInterface,
22
- serverCodegen: () => serverCodegen
22
+ serverCodegen: () => serverCodegen,
23
+ withPlatformEnvVars: () => withPlatformEnvVars
23
24
  });
24
25
  module.exports = __toCommonJS(server_exports);
25
26
  var import_common = require("./common.js");
26
27
  var import_validator_helpers = require("./validator_helpers.js");
28
+ const PLATFORM_ENV_VARS = [
29
+ ["CONVEX_CLOUD_URL", { type: "value", value: '{"type":"string"}' }],
30
+ ["CONVEX_SITE_URL", { type: "value", value: '{"type":"string"}' }]
31
+ ];
32
+ function withPlatformEnvVars(envVars) {
33
+ return [...PLATFORM_ENV_VARS, ...envVars];
34
+ }
27
35
  const ENV_DOCSTRING = `/**
28
- * Typesafe environment variables declared in \`convex.config.ts\`.
36
+ * Typesafe environment variables.
37
+ *
38
+ * This includes platform-provided env vars and any variables declared in
39
+ * \`convex.config.ts\`.
29
40
  */`;
30
41
  function serverCodegen({
31
42
  useTypeScript,
32
43
  envVars
33
44
  }) {
34
- const hasEnv = !!envVars && envVars.length > 0;
35
- const envInterface = hasEnv ? generateEnvInterface(envVars) : "";
45
+ const emittedEnvVars = envVars === void 0 ? void 0 : withPlatformEnvVars(envVars);
46
+ const hasEnv = emittedEnvVars !== void 0;
47
+ const envInterface = hasEnv ? generateEnvInterface(emittedEnvVars) : "";
36
48
  const envDeclDTS = hasEnv ? `
37
49
  ${ENV_DOCSTRING}
38
50
  export declare const env: Env;
39
- ` : envVars === void 0 ? `
51
+ ` : `
40
52
  export declare const env: Record<string, string | undefined>;
41
- ` : "";
53
+ `;
42
54
  const envDeclTS = hasEnv ? `
43
55
  ${ENV_DOCSTRING}
44
- export const env: Env = process.env as unknown as Env;
45
- ` : envVars === void 0 ? `
46
- export const env: Record<string, string | undefined> = process.env as unknown as Record<string, string | undefined>;
47
- ` : "";
56
+ export const env: Env = (globalThis as unknown as { process: { env: Env } }).process.env;
57
+ ` : `
58
+ export const env: Record<string, string | undefined> = (globalThis as unknown as { process: { env: Record<string, string | undefined> } }).process.env;
59
+ `;
48
60
  const envDeclJS = hasEnv ? `
49
61
  ${ENV_DOCSTRING}
50
62
  export const env = process.env;
51
- ` : envVars === void 0 ? `
63
+ ` : `
52
64
  export const env = process.env;
53
- ` : "";
65
+ `;
54
66
  if (!useTypeScript) {
55
67
  const serverDTS = `
56
68
  ${(0, import_common.header)(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/codegen_templates/server.ts"],
4
- "sourcesContent": ["import { header } from \"./common.js\";\nimport { parseValidator, validatorToType } from \"./validator_helpers.js\";\n\nexport type EnvVarMeta = [\n string,\n { type: \"value\"; value: string; optional?: boolean | undefined },\n];\n\nconst ENV_DOCSTRING = `/**\n * Typesafe environment variables declared in \\`convex.config.ts\\`.\n */`;\n\nexport function serverCodegen({\n useTypeScript,\n envVars,\n}: {\n useTypeScript: boolean;\n // - undefined: env var declarations not yet known (initial codegen before\n // server analysis). Emits an untyped `env` stub so imports don't break.\n // - non-empty array: emit a typed `Env` interface and typed `env` export.\n // - empty array: no env vars declared. Omit `env` from generated code.\n envVars: EnvVarMeta[] | undefined;\n}) {\n const hasEnv = !!envVars && envVars.length > 0;\n const envInterface = hasEnv ? generateEnvInterface(envVars!) : \"\";\n const envDeclDTS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport declare const env: Env;\n`\n : envVars === undefined\n ? `\nexport declare const env: Record<string, string | undefined>;\n`\n : \"\";\n const envDeclTS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport const env: Env = process.env as unknown as Env;\n`\n : envVars === undefined\n ? `\nexport const env: Record<string, string | undefined> = process.env as unknown as Record<string, string | undefined>;\n`\n : \"\";\n const envDeclJS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport const env = process.env;\n`\n : envVars === undefined\n ? `\nexport const env = process.env;\n`\n : \"\";\n\n if (!useTypeScript) {\n // Generate separate .js and .d.ts files\n const serverDTS = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n } from \"convex/server\";\n import type { DataModel } from \"./dataModel.js\";\n ${envInterface}\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const query: QueryBuilder<DataModel, \"public\">;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalQuery: QueryBuilder<DataModel, \"internal\">;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const mutation: MutationBuilder<DataModel, \"public\">;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalMutation: MutationBuilder<DataModel, \"internal\">;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const action: ActionBuilder<DataModel, \"public\">;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalAction: ActionBuilder<DataModel, \"internal\">;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export declare const httpAction: HttpActionBuilder;\n${envDeclDTS}\n /**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * This differs from the {@link MutationCtx} because all of the services are\n * read-only.\n */\n export type QueryCtx = GenericQueryCtx<DataModel>;\n\n /**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n */\n export type MutationCtx = GenericMutationCtx<DataModel>;\n\n /**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\n export type ActionCtx = GenericActionCtx<DataModel>;\n\n /**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\n export type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n /**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\n export type DatabaseWriter = GenericDatabaseWriter<DataModel>;`;\n\n const serverJS = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n } from \"convex/server\";\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const query = queryGeneric;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalQuery = internalQueryGeneric;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const mutation = mutationGeneric;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalMutation = internalMutationGeneric;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const action = actionGeneric;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalAction = internalActionGeneric;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export const httpAction = httpActionGeneric;\n${envDeclJS}\n `;\n\n return {\n DTS: serverDTS,\n JS: serverJS,\n };\n } else {\n // Generate combined .ts file\n const serverTS = `${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\nimport {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n} from \"convex/server\";\nimport type {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n} from \"convex/server\";\nimport type { DataModel } from \"./dataModel.js\";\n${envInterface}\n\n/**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n/**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalQuery: QueryBuilder<DataModel, \"internal\"> = internalQueryGeneric;\n\n/**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n/**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalMutation: MutationBuilder<DataModel, \"internal\"> = internalMutationGeneric;\n\n/**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n/**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalAction: ActionBuilder<DataModel, \"internal\"> = internalActionGeneric;\n\n/**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\nexport const httpAction: HttpActionBuilder = httpActionGeneric;\n${envDeclTS}\n/**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * This differs from the {@link MutationCtx} because all of the services are\n * read-only.\n */\nexport type QueryCtx = GenericQueryCtx<DataModel>;\n\n/**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n */\nexport type MutationCtx = GenericMutationCtx<DataModel>;\n\n/**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\nexport type ActionCtx = GenericActionCtx<DataModel>;\n\n/**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\nexport type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n/**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\nexport type DatabaseWriter = GenericDatabaseWriter<DataModel>;`;\n\n return {\n TS: serverTS,\n };\n }\n}\n\nexport function generateEnvInterface(envVars: EnvVarMeta[]): string {\n const lines: string[] = [];\n for (const [name, decl] of envVars) {\n const parsed = parseValidator(decl.value);\n let tsType = parsed ? validatorToType(parsed, false) : \"unknown\";\n if (decl.optional) {\n tsType += \" | undefined\";\n }\n lines.push(` readonly ${name}: ${tsType};`);\n }\n return `\n${ENV_DOCSTRING}\ntype Env = {\n${lines.join(\"\\n\")}\n};`;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { header } from \"./common.js\";\nimport { parseValidator, validatorToType } from \"./validator_helpers.js\";\n\nexport type EnvVarMeta = [\n string,\n { type: \"value\"; value: string; optional?: boolean | undefined },\n];\n\n// Environment variables the platform always injects into every deployment,\n// independent of the user's `convex.config.ts` declarations. Both are always\n// present, so they're typed as required `string`.\nconst PLATFORM_ENV_VARS: EnvVarMeta[] = [\n [\"CONVEX_CLOUD_URL\", { type: \"value\", value: '{\"type\":\"string\"}' }],\n [\"CONVEX_SITE_URL\", { type: \"value\", value: '{\"type\":\"string\"}' }],\n];\n\n// Prepend the always-present platform env vars. Users can't declare env vars\n// with these names \u2014 the backend rejects overriding built-in system env vars \u2014\n// so there's no collision to worry about.\nexport function withPlatformEnvVars(envVars: EnvVarMeta[]): EnvVarMeta[] {\n return [...PLATFORM_ENV_VARS, ...envVars];\n}\n\nconst ENV_DOCSTRING = `/**\n * Typesafe environment variables.\n *\n * This includes platform-provided env vars and any variables declared in\n * \\`convex.config.ts\\`.\n */`;\n\nexport function serverCodegen({\n useTypeScript,\n envVars,\n}: {\n useTypeScript: boolean;\n // - undefined: env var declarations not yet known (initial codegen before\n // server analysis). Emits an untyped `env` stub so imports don't break.\n // - array (empty or not): emit a typed `Env` interface and typed `env`\n // export. The interface always includes the platform-provided env vars, so\n // an empty array still yields a typed `env` with just those.\n envVars: EnvVarMeta[] | undefined;\n}) {\n const emittedEnvVars =\n envVars === undefined ? undefined : withPlatformEnvVars(envVars);\n const hasEnv = emittedEnvVars !== undefined;\n const envInterface = hasEnv ? generateEnvInterface(emittedEnvVars!) : \"\";\n const envDeclDTS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport declare const env: Env;\n`\n : `\nexport declare const env: Record<string, string | undefined>;\n`;\n // Route through `globalThis` rather than the bare `process` global so the\n // generated file typechecks even in projects without `@types/node`.\n const envDeclTS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport const env: Env = (globalThis as unknown as { process: { env: Env } }).process.env;\n`\n : `\nexport const env: Record<string, string | undefined> = (globalThis as unknown as { process: { env: Record<string, string | undefined> } }).process.env;\n`;\n const envDeclJS = hasEnv\n ? `\n${ENV_DOCSTRING}\nexport const env = process.env;\n`\n : `\nexport const env = process.env;\n`;\n\n if (!useTypeScript) {\n // Generate separate .js and .d.ts files\n const serverDTS = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n } from \"convex/server\";\n import type { DataModel } from \"./dataModel.js\";\n ${envInterface}\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const query: QueryBuilder<DataModel, \"public\">;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalQuery: QueryBuilder<DataModel, \"internal\">;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const mutation: MutationBuilder<DataModel, \"public\">;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalMutation: MutationBuilder<DataModel, \"internal\">;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const action: ActionBuilder<DataModel, \"public\">;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export declare const internalAction: ActionBuilder<DataModel, \"internal\">;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export declare const httpAction: HttpActionBuilder;\n${envDeclDTS}\n /**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * This differs from the {@link MutationCtx} because all of the services are\n * read-only.\n */\n export type QueryCtx = GenericQueryCtx<DataModel>;\n\n /**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n */\n export type MutationCtx = GenericMutationCtx<DataModel>;\n\n /**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\n export type ActionCtx = GenericActionCtx<DataModel>;\n\n /**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\n export type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n /**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\n export type DatabaseWriter = GenericDatabaseWriter<DataModel>;`;\n\n const serverJS = `\n ${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\n import {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n } from \"convex/server\";\n\n /**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const query = queryGeneric;\n\n /**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalQuery = internalQueryGeneric;\n\n /**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const mutation = mutationGeneric;\n\n /**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalMutation = internalMutationGeneric;\n\n /**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const action = actionGeneric;\n\n /**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\n export const internalAction = internalActionGeneric;\n\n /**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\n export const httpAction = httpActionGeneric;\n${envDeclJS}\n `;\n\n return {\n DTS: serverDTS,\n JS: serverJS,\n };\n } else {\n // Generate combined .ts file\n const serverTS = `${header(\n \"Generated utilities for implementing server-side Convex query and mutation functions.\",\n )}\nimport {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n} from \"convex/server\";\nimport type {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n} from \"convex/server\";\nimport type { DataModel } from \"./dataModel.js\";\n${envInterface}\n\n/**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n/**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalQuery: QueryBuilder<DataModel, \"internal\"> = internalQueryGeneric;\n\n/**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n/**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalMutation: MutationBuilder<DataModel, \"internal\"> = internalMutationGeneric;\n\n/**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n/**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an \\`export\\` to name it and make it accessible.\n */\nexport const internalAction: ActionBuilder<DataModel, \"internal\"> = internalActionGeneric;\n\n/**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in \\`convex/http.js\\`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API \\`Request\\` object as its second.\n * @returns The wrapped function. Import this function from \\`convex/http.js\\` and route it to hook it up.\n */\nexport const httpAction: HttpActionBuilder = httpActionGeneric;\n${envDeclTS}\n/**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * This differs from the {@link MutationCtx} because all of the services are\n * read-only.\n */\nexport type QueryCtx = GenericQueryCtx<DataModel>;\n\n/**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n */\nexport type MutationCtx = GenericMutationCtx<DataModel>;\n\n/**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\nexport type ActionCtx = GenericActionCtx<DataModel>;\n\n/**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\nexport type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n/**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\nexport type DatabaseWriter = GenericDatabaseWriter<DataModel>;`;\n\n return {\n TS: serverTS,\n };\n }\n}\n\nexport function generateEnvInterface(envVars: EnvVarMeta[]): string {\n const lines: string[] = [];\n for (const [name, decl] of envVars) {\n const parsed = parseValidator(decl.value);\n let tsType = parsed ? validatorToType(parsed, false) : \"unknown\";\n if (decl.optional) {\n tsType += \" | undefined\";\n }\n lines.push(` readonly ${name}: ${tsType};`);\n }\n return `\n${ENV_DOCSTRING}\ntype Env = {\n${lines.join(\"\\n\")}\n};`;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -30,6 +30,7 @@ var login_exports = {};
30
30
  __export(login_exports, {
31
31
  checkAuthorization: () => checkAuthorization,
32
32
  ensureLoggedIn: () => ensureLoggedIn,
33
+ isAuthorizedHeader: () => isAuthorizedHeader,
33
34
  performLogin: () => performLogin
34
35
  });
35
36
  module.exports = __toCommonJS(login_exports);
@@ -49,11 +50,7 @@ var import_deploymentSelection = require("./deploymentSelection.js");
49
50
  import_openid_client.custom.setHttpOptionsDefaults({
50
51
  timeout: parseInt(process.env.OPENID_CLIENT_TIMEOUT || "10000")
51
52
  });
52
- async function checkAuthorization(ctx, acceptOptIns) {
53
- const header = ctx.bigBrainAuth()?.header ?? null;
54
- if (header === null) {
55
- return false;
56
- }
53
+ async function isAuthorizedHeader(ctx, header) {
57
54
  try {
58
55
  const resp = await fetch(`${import_config.provisionHost}/api/authorize`, {
59
56
  method: "HEAD",
@@ -62,15 +59,22 @@ async function checkAuthorization(ctx, acceptOptIns) {
62
59
  "Convex-Client": `npm-cli-${import_version.version}`
63
60
  }
64
61
  });
65
- if (resp.status !== 200) {
66
- return false;
67
- }
62
+ return resp.status === 200;
68
63
  } catch (e) {
69
64
  (0, import_log.logError)(
70
65
  `Unexpected error when authorizing - are you connected to the internet?`
71
66
  );
72
67
  return await (0, import_utils.logAndHandleFetchError)(ctx, e);
73
68
  }
69
+ }
70
+ async function checkAuthorization(ctx, acceptOptIns) {
71
+ const header = ctx.bigBrainAuth()?.header ?? null;
72
+ if (header === null) {
73
+ return false;
74
+ }
75
+ if (!await isAuthorizedHeader(ctx, header)) {
76
+ return false;
77
+ }
74
78
  const shouldContinue = await optins(ctx, acceptOptIns);
75
79
  if (!shouldContinue) {
76
80
  return await ctx.crash({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/login.ts"],
4
- "sourcesContent": ["import { errors, BaseClient, custom } from \"openid-client\";\nimport {\n bigBrainAPI,\n bigBrainFetch,\n logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\n typedPlatformClient,\n} from \"./utils/utils.js\";\nimport open from \"open\";\nimport { chalkStderr } from \"chalk\";\nimport { provisionHost } from \"./config.js\";\nimport { version } from \"../version.js\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logError,\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n logVerbose,\n showSpinner,\n} from \"../../bundler/log.js\";\nimport { Issuer } from \"openid-client\";\nimport { hostname } from \"os\";\nimport { execSync } from \"child_process\";\nimport { promptString, promptYesNo } from \"./utils/prompts.js\";\nimport {\n formatPathForPrinting,\n globalConfigPath,\n modifyGlobalConfig,\n} from \"./utils/globalConfig.js\";\nimport { updateBigBrainAuthAfterLogin } from \"./deploymentSelection.js\";\n\n// Per https://github.com/panva/node-openid-client/tree/main/docs#customizing\ncustom.setHttpOptionsDefaults({\n timeout: parseInt(process.env.OPENID_CLIENT_TIMEOUT || \"10000\"),\n});\n\nexport async function checkAuthorization(\n ctx: Context,\n acceptOptIns: boolean,\n): Promise<boolean> {\n const header = ctx.bigBrainAuth()?.header ?? null;\n if (header === null) {\n return false;\n }\n try {\n const resp = await fetch(`${provisionHost}/api/authorize`, {\n method: \"HEAD\",\n headers: {\n Authorization: header,\n \"Convex-Client\": `npm-cli-${version}`,\n },\n });\n // Don't throw an error if this request returns a non-200 status.\n // Big Brain responds with a variety of error codes -- 401 if the token is correctly-formed but not valid, and either 400 or 500 if the token is ill-formed.\n // We only care if this check returns a 200 code (so we can skip logging in again) -- any other errors should be silently skipped and we'll run the whole login flow again.\n if (resp.status !== 200) {\n return false;\n }\n } catch (e: any) {\n // This `catch` block should only be hit if a network error was encountered\n logError(\n `Unexpected error when authorizing - are you connected to the internet?`,\n );\n return await logAndHandleFetchError(ctx, e);\n }\n\n // Check that we have optin as well\n const shouldContinue = await optins(ctx, acceptOptIns);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n return true;\n}\n\nasync function performDeviceAuthorization(\n ctx: Context,\n authClient: BaseClient,\n shouldOpen: boolean,\n vercel?: boolean,\n vercelOverride?: string,\n): Promise<string> {\n // Device authorization flow follows this guide: https://github.com/auth0/auth0-device-flow-cli-sample/blob/9f0f3b76a6cd56ea8d99e76769187ea5102d519d/cli.js\n // License: MIT License\n // Copyright (c) 2019 Auth0 Samples\n /*\n The MIT License (MIT)\n\n Copyright (c) 2019 Auth0 Samples\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n */\n\n // Device Authorization Request - https://tools.ietf.org/html/rfc8628#section-3.1\n // Get authentication URL\n let handle;\n try {\n handle = await authClient.deviceAuthorization();\n } catch {\n // We couldn't get verification URL from the auth provider, proceed with manual auth\n return promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n\n // Device Authorization Response - https://tools.ietf.org/html/rfc8628#section-3.2\n // Open authentication URL\n const { verification_uri_complete, user_code, expires_in } = handle;\n\n // Construct Vercel URL if --vercel flag is used\n const urlToOpen = vercel\n ? `https://vercel.com/sso/integrations/${vercelOverride || \"convex\"}?url=${verification_uri_complete}`\n : verification_uri_complete;\n\n logMessage(\n `Visit ${urlToOpen} to finish logging in.\\n` +\n `You should see the following code which expires in ${\n expires_in % 60 === 0\n ? `${expires_in / 60} minutes`\n : `${expires_in} seconds`\n }: ${user_code}`,\n );\n if (shouldOpen) {\n shouldOpen = await promptYesNo(ctx, {\n message: `Open the browser?`,\n default: true,\n });\n }\n\n if (shouldOpen) {\n showSpinner(`Opening ${urlToOpen} in your browser to log in...\\n`);\n try {\n const p = await open(urlToOpen);\n p.once(\"error\", () => {\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n });\n changeSpinner(\"Waiting for the confirmation...\");\n } catch {\n logError(chalkStderr.red(`Unable to open browser.`));\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n }\n } else {\n showSpinner(`Open ${urlToOpen} in your browser to log in.`);\n }\n\n // Device Access Token Request - https://tools.ietf.org/html/rfc8628#section-3.4\n // Device Access Token Response - https://tools.ietf.org/html/rfc8628#section-3.5\n try {\n const tokens = await handle.poll();\n if (typeof tokens.access_token === \"string\") {\n return tokens.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n switch (err.error) {\n case \"access_denied\": // end-user declined the device confirmation prompt, consent or rules failed\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Access denied.\",\n errForSentry: err,\n });\n case \"expired_token\": // end-user did not complete the interaction in time\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Device flow expired.\",\n errForSentry: err,\n });\n default: {\n const message =\n err instanceof errors.OPError\n ? `Error = ${err.error}; error_description = ${err.error_description}`\n : `Login failed with error: ${err}`;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: err,\n });\n }\n }\n }\n}\n\nasync function performPasswordAuthentication(\n ctx: Context,\n clientId: string,\n username: string,\n password: string,\n): Promise<string> {\n if (!process.env.WORKOS_API_SECRET) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"WORKOS_API_SECRET environment variable is not set\",\n });\n }\n\n // Unfortunately, `openid-client` doesn't support the resource owner password credentials flow so we need to manually send the requests.\n const options: Parameters<typeof throwingFetch>[1] = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"password\",\n email: username,\n password: password,\n client_id: clientId,\n client_secret: process.env.WORKOS_API_SECRET,\n }),\n };\n\n try {\n const response = await throwingFetch(\n \"https://apiauth.convex.dev/user_management/authenticate\",\n options,\n );\n const data = await response.json();\n if (typeof data.access_token === \"string\") {\n return data.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n logFailure(`Password flow failed: ${err}`);\n if (err.response) {\n logError(chalkStderr.red(`${JSON.stringify(err.response.data)}`));\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n}\n\nexport async function performLogin(\n ctx: Context,\n {\n overrideAuthUrl,\n overrideAuthClient,\n overrideAuthUsername,\n overrideAuthPassword,\n overrideAccessToken,\n loginFlow,\n open,\n acceptOptIns,\n dumpAccessToken,\n deviceName: deviceNameOverride,\n anonymousId,\n vercel,\n vercelOverride,\n }: {\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n overrideAccessToken?: string | undefined;\n loginFlow?: \"auto\" | \"paste\" | \"poll\" | undefined;\n // default `true`\n open?: boolean | undefined;\n // default `false`\n acceptOptIns?: boolean | undefined;\n dumpAccessToken?: boolean | undefined;\n deviceName?: string | undefined;\n anonymousId?: string | undefined;\n vercel?: boolean | undefined;\n vercelOverride?: string | undefined;\n } = {},\n) {\n loginFlow = loginFlow || \"auto\";\n // Get access token from big-brain\n // Default the device name to the hostname, but allow the user to change this if the terminal is interactive.\n // On Macs, the `hostname()` may be a weirdly-truncated form of the computer name. Attempt to read the \"real\" name before falling back to hostname.\n let deviceName = deviceNameOverride ?? \"\";\n if (!deviceName && process.platform === \"darwin\") {\n try {\n deviceName = execSync(\"scutil --get ComputerName\").toString().trim();\n } catch {\n // Just fall back to the hostname default below.\n }\n }\n if (!deviceName) {\n deviceName = hostname();\n }\n if (!deviceNameOverride) {\n logMessage(\n chalkStderr.bold(\n `Welcome to developing with Convex, let's get you logged in.`,\n ),\n );\n deviceName = await promptString(ctx, {\n message: \"Device name:\",\n default: deviceName,\n });\n }\n\n const issuer = overrideAuthUrl ?? \"https://auth.convex.dev\";\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\n let accessToken: string;\n\n if (overrideAccessToken) {\n // Access token was supplied directly.\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n // Username/Password auth\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else if (\n loginFlow === \"paste\" ||\n (loginFlow === \"auto\" && isWebContainer())\n ) {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n } else {\n // Device authorization flow. Contact OIDC issuer.\n let authIssuer;\n try {\n authIssuer = await Issuer.discover(issuer);\n } catch {\n // Couldn't contact https://auth.convex.dev/.well-known/openid-configuration,\n // proceed with manual auth.\n authIssuer = undefined;\n }\n if (authIssuer) {\n const authClient = new authIssuer.Client({\n client_id: clientId,\n token_endpoint_auth_method: \"none\",\n id_token_signed_response_alg: \"RS256\",\n });\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\n );\n } else {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n }\n\n if (dumpAccessToken) {\n logOutput(`${accessToken}`);\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n // Exchange the WorkOS access token for a Convex personal access token.\n ctx._updateBigBrainAuth({\n accessToken: accessToken,\n kind: \"accessToken\",\n header: `Bearer ${accessToken}`,\n });\n const response = await typedPlatformClient(ctx).POST(\n \"/create_personal_access_token\",\n {\n // `anonymousId` links a prior anonymous session to this account. It's\n // intentionally absent from the generated platform API types,\n // so cast to pass it through.\n body: { name: deviceName, anonymousId } as { name: string },\n },\n );\n const newAccessToken = response.data!.accessToken;\n const globalConfig = { accessToken: newAccessToken };\n try {\n await modifyGlobalConfig(ctx, globalConfig);\n const path = globalConfigPath();\n logFinishedStep(`Saved credentials to ${formatPathForPrinting(path)}`);\n } catch (err: unknown) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n\n logVerbose(`performLogin: updating big brain auth after login`);\n await updateBigBrainAuthAfterLogin(ctx, newAccessToken);\n\n logVerbose(`performLogin: checking opt ins, acceptOptIns: ${acceptOptIns}`);\n // Do opt in to TOS and Privacy Policy stuff\n const shouldContinue = await optins(ctx, acceptOptIns ?? false);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n if (vercel) {\n await promptJoinVercelTeams(ctx);\n }\n}\n\ntype PotentialVercelTeam = {\n teamId: number;\n teamName: string;\n teamSlug: string;\n planId: string;\n planName: string;\n pricingNotice: string | null;\n};\n\n// After `--vercel` login, surface any Vercel-marketplace teams the user has\n// access to but isn't yet a member of, and prompt to join each.\nasync function promptJoinVercelTeams(ctx: Context): Promise<void> {\n const fetch = bigBrainFetch(ctx);\n let teams: PotentialVercelTeam[];\n try {\n const res = await fetch(\n new URL(\"vercel/potential_teams\", `${provisionHost}/`),\n );\n if (!res.ok) {\n logVerbose(\n `vercel/potential_teams returned ${res.status}; skipping team-join prompt`,\n );\n return;\n }\n teams = await res.json();\n } catch (err) {\n logVerbose(`Failed to fetch potential Vercel teams: ${String(err)}`);\n return;\n }\n if (teams.length === 0) return;\n\n for (const [index, team] of teams.entries()) {\n const displayName = team.teamName.replace(/ \\(Vercel\\)$/, \"\");\n const counter = teams.length > 1 ? `[${index + 1}/${teams.length}] ` : \"\";\n const lines = [\n chalkStderr.bold(`${counter}You've been invited to join ${displayName}`) +\n ` (${team.planName}) through the Vercel marketplace.`,\n ];\n if (team.pricingNotice) {\n lines.push(chalkStderr.yellow(team.pricingNotice));\n }\n lines.push(`Join \"${displayName}\"?`);\n const join = await promptYesNo(ctx, {\n message: `${lines.join(\"\\n\")}`,\n default: true,\n });\n if (!join) continue;\n try {\n await fetch(\n new URL(\n `vercel/potential_teams/${team.teamId}/join`,\n `${provisionHost}/`,\n ),\n { method: \"POST\" },\n );\n logFinishedStep(`Joined ${displayName}`);\n } catch (err) {\n logFailure(`Failed to join ${displayName}: ${String(err)}`);\n }\n }\n}\n\n/// There are fields like version, but we keep them opaque\ntype OptIn = Record<string, unknown>;\n\ntype OptInToAccept = {\n optIn: OptIn;\n message: string;\n};\n\ntype AcceptOptInsArgs = {\n optInsAccepted: OptIn[];\n};\n\n// Returns whether we can proceed or not.\nasync function optins(ctx: Context, acceptOptIns: boolean): Promise<boolean> {\n const bbAuth = ctx.bigBrainAuth();\n if (bbAuth === null) {\n // This should never happen, but if we're not even logged in, we can't proceed.\n return false;\n }\n switch (bbAuth.kind) {\n case \"accessToken\":\n break;\n case \"deploymentKey\":\n case \"projectKey\":\n case \"previewDeployKey\":\n // If we have a key configured as auth, we do not need to check opt ins.\n return true;\n default: {\n bbAuth satisfies never;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: `Unexpected auth kind ${(bbAuth as any).kind}`,\n printedMessage: \"Hit an unexpected error while logging in.\",\n });\n }\n }\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"check_opt_ins\",\n });\n if (data.optInsToAccept.length === 0) {\n return true;\n }\n for (const optInToAccept of data.optInsToAccept) {\n const confirmed =\n acceptOptIns ||\n (await promptYesNo(ctx, {\n message: optInToAccept.message,\n }));\n if (!confirmed) {\n logFailure(\"Please accept the Terms of Service to use Convex.\");\n return Promise.resolve(false);\n }\n }\n\n const optInsAccepted = data.optInsToAccept.map((o: OptInToAccept) => o.optIn);\n const args: AcceptOptInsArgs = { optInsAccepted };\n await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"accept_opt_ins\",\n data: args,\n });\n return true;\n}\n\nexport async function ensureLoggedIn(\n ctx: Context,\n options?: {\n message?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n },\n) {\n const isLoggedIn = await checkAuthorization(ctx, false);\n if (!isLoggedIn) {\n if (options?.message) {\n logMessage(options.message);\n }\n await performLogin(ctx, {\n acceptOptIns: false,\n overrideAuthUrl: options?.overrideAuthUrl,\n overrideAuthClient: options?.overrideAuthClient,\n overrideAuthUsername: options?.overrideAuthUsername,\n overrideAuthPassword: options?.overrideAuthPassword,\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { errors, BaseClient, custom } from \"openid-client\";\nimport {\n bigBrainAPI,\n bigBrainFetch,\n logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\n typedPlatformClient,\n} from \"./utils/utils.js\";\nimport open from \"open\";\nimport { chalkStderr } from \"chalk\";\nimport { provisionHost } from \"./config.js\";\nimport { version } from \"../version.js\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logError,\n logFailure,\n logFinishedStep,\n logMessage,\n logOutput,\n logVerbose,\n showSpinner,\n} from \"../../bundler/log.js\";\nimport { Issuer } from \"openid-client\";\nimport { hostname } from \"os\";\nimport { execSync } from \"child_process\";\nimport { promptString, promptYesNo } from \"./utils/prompts.js\";\nimport {\n formatPathForPrinting,\n globalConfigPath,\n modifyGlobalConfig,\n} from \"./utils/globalConfig.js\";\nimport { updateBigBrainAuthAfterLogin } from \"./deploymentSelection.js\";\n\n// Per https://github.com/panva/node-openid-client/tree/main/docs#customizing\ncustom.setHttpOptionsDefaults({\n timeout: parseInt(process.env.OPENID_CLIENT_TIMEOUT || \"10000\"),\n});\n\n/**\n * Whether Big Brain accepts this credential. Takes the header explicitly so\n * callers can check a credential other than the one `ctx` resolved to.\n */\nexport async function isAuthorizedHeader(\n ctx: Context,\n header: string,\n): Promise<boolean> {\n try {\n const resp = await fetch(`${provisionHost}/api/authorize`, {\n method: \"HEAD\",\n headers: {\n Authorization: header,\n \"Convex-Client\": `npm-cli-${version}`,\n },\n });\n // Don't throw an error if this request returns a non-200 status.\n // Big Brain responds with a variety of error codes -- 401 if the token is correctly-formed but not valid, and either 400 or 500 if the token is ill-formed.\n // We only care if this check returns a 200 code (so we can skip logging in again) -- any other errors should be silently skipped and we'll run the whole login flow again.\n return resp.status === 200;\n } catch (e: any) {\n // This `catch` block should only be hit if a network error was encountered\n logError(\n `Unexpected error when authorizing - are you connected to the internet?`,\n );\n return await logAndHandleFetchError(ctx, e);\n }\n}\n\nexport async function checkAuthorization(\n ctx: Context,\n acceptOptIns: boolean,\n): Promise<boolean> {\n const header = ctx.bigBrainAuth()?.header ?? null;\n if (header === null) {\n return false;\n }\n if (!(await isAuthorizedHeader(ctx, header))) {\n return false;\n }\n\n // Check that we have optin as well\n const shouldContinue = await optins(ctx, acceptOptIns);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n return true;\n}\n\nasync function performDeviceAuthorization(\n ctx: Context,\n authClient: BaseClient,\n shouldOpen: boolean,\n vercel?: boolean,\n vercelOverride?: string,\n): Promise<string> {\n // Device authorization flow follows this guide: https://github.com/auth0/auth0-device-flow-cli-sample/blob/9f0f3b76a6cd56ea8d99e76769187ea5102d519d/cli.js\n // License: MIT License\n // Copyright (c) 2019 Auth0 Samples\n /*\n The MIT License (MIT)\n\n Copyright (c) 2019 Auth0 Samples\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n */\n\n // Device Authorization Request - https://tools.ietf.org/html/rfc8628#section-3.1\n // Get authentication URL\n let handle;\n try {\n handle = await authClient.deviceAuthorization();\n } catch {\n // We couldn't get verification URL from the auth provider, proceed with manual auth\n return promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n\n // Device Authorization Response - https://tools.ietf.org/html/rfc8628#section-3.2\n // Open authentication URL\n const { verification_uri_complete, user_code, expires_in } = handle;\n\n // Construct Vercel URL if --vercel flag is used\n const urlToOpen = vercel\n ? `https://vercel.com/sso/integrations/${vercelOverride || \"convex\"}?url=${verification_uri_complete}`\n : verification_uri_complete;\n\n logMessage(\n `Visit ${urlToOpen} to finish logging in.\\n` +\n `You should see the following code which expires in ${\n expires_in % 60 === 0\n ? `${expires_in / 60} minutes`\n : `${expires_in} seconds`\n }: ${user_code}`,\n );\n if (shouldOpen) {\n shouldOpen = await promptYesNo(ctx, {\n message: `Open the browser?`,\n default: true,\n });\n }\n\n if (shouldOpen) {\n showSpinner(`Opening ${urlToOpen} in your browser to log in...\\n`);\n try {\n const p = await open(urlToOpen);\n p.once(\"error\", () => {\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n });\n changeSpinner(\"Waiting for the confirmation...\");\n } catch {\n logError(chalkStderr.red(`Unable to open browser.`));\n changeSpinner(`Manually open ${urlToOpen} in your browser to log in.`);\n }\n } else {\n showSpinner(`Open ${urlToOpen} in your browser to log in.`);\n }\n\n // Device Access Token Request - https://tools.ietf.org/html/rfc8628#section-3.4\n // Device Access Token Response - https://tools.ietf.org/html/rfc8628#section-3.5\n try {\n const tokens = await handle.poll();\n if (typeof tokens.access_token === \"string\") {\n return tokens.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n switch (err.error) {\n case \"access_denied\": // end-user declined the device confirmation prompt, consent or rules failed\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Access denied.\",\n errForSentry: err,\n });\n case \"expired_token\": // end-user did not complete the interaction in time\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Device flow expired.\",\n errForSentry: err,\n });\n default: {\n const message =\n err instanceof errors.OPError\n ? `Error = ${err.error}; error_description = ${err.error_description}`\n : `Login failed with error: ${err}`;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: message,\n errForSentry: err,\n });\n }\n }\n }\n}\n\nasync function performPasswordAuthentication(\n ctx: Context,\n clientId: string,\n username: string,\n password: string,\n): Promise<string> {\n if (!process.env.WORKOS_API_SECRET) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"WORKOS_API_SECRET environment variable is not set\",\n });\n }\n\n // Unfortunately, `openid-client` doesn't support the resource owner password credentials flow so we need to manually send the requests.\n const options: Parameters<typeof throwingFetch>[1] = {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n grant_type: \"password\",\n email: username,\n password: password,\n client_id: clientId,\n client_secret: process.env.WORKOS_API_SECRET,\n }),\n };\n\n try {\n const response = await throwingFetch(\n \"https://apiauth.convex.dev/user_management/authenticate\",\n options,\n );\n const data = await response.json();\n if (typeof data.access_token === \"string\") {\n return data.access_token;\n } else {\n // Unexpected error\n // eslint-disable-next-line no-restricted-syntax\n throw Error(\"Access token is missing\");\n }\n } catch (err: any) {\n logFailure(`Password flow failed: ${err}`);\n if (err.response) {\n logError(chalkStderr.red(`${JSON.stringify(err.response.data)}`));\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n}\n\nexport async function performLogin(\n ctx: Context,\n {\n overrideAuthUrl,\n overrideAuthClient,\n overrideAuthUsername,\n overrideAuthPassword,\n overrideAccessToken,\n loginFlow,\n open,\n acceptOptIns,\n dumpAccessToken,\n deviceName: deviceNameOverride,\n anonymousId,\n vercel,\n vercelOverride,\n }: {\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n overrideAccessToken?: string | undefined;\n loginFlow?: \"auto\" | \"paste\" | \"poll\" | undefined;\n // default `true`\n open?: boolean | undefined;\n // default `false`\n acceptOptIns?: boolean | undefined;\n dumpAccessToken?: boolean | undefined;\n deviceName?: string | undefined;\n anonymousId?: string | undefined;\n vercel?: boolean | undefined;\n vercelOverride?: string | undefined;\n } = {},\n) {\n loginFlow = loginFlow || \"auto\";\n // Get access token from big-brain\n // Default the device name to the hostname, but allow the user to change this if the terminal is interactive.\n // On Macs, the `hostname()` may be a weirdly-truncated form of the computer name. Attempt to read the \"real\" name before falling back to hostname.\n let deviceName = deviceNameOverride ?? \"\";\n if (!deviceName && process.platform === \"darwin\") {\n try {\n deviceName = execSync(\"scutil --get ComputerName\").toString().trim();\n } catch {\n // Just fall back to the hostname default below.\n }\n }\n if (!deviceName) {\n deviceName = hostname();\n }\n if (!deviceNameOverride) {\n logMessage(\n chalkStderr.bold(\n `Welcome to developing with Convex, let's get you logged in.`,\n ),\n );\n deviceName = await promptString(ctx, {\n message: \"Device name:\",\n default: deviceName,\n });\n }\n\n const issuer = overrideAuthUrl ?? \"https://auth.convex.dev\";\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\n let accessToken: string;\n\n if (overrideAccessToken) {\n // Access token was supplied directly.\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n // Username/Password auth\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else if (\n loginFlow === \"paste\" ||\n (loginFlow === \"auto\" && isWebContainer())\n ) {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n } else {\n // Device authorization flow. Contact OIDC issuer.\n let authIssuer;\n try {\n authIssuer = await Issuer.discover(issuer);\n } catch {\n // Couldn't contact https://auth.convex.dev/.well-known/openid-configuration,\n // proceed with manual auth.\n authIssuer = undefined;\n }\n if (authIssuer) {\n const authClient = new authIssuer.Client({\n client_id: clientId,\n token_endpoint_auth_method: \"none\",\n id_token_signed_response_alg: \"RS256\",\n });\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\n );\n } else {\n accessToken = await promptString(ctx, {\n message:\n \"Open https://dashboard.convex.dev/auth, log in and paste the token here:\",\n });\n }\n }\n\n if (dumpAccessToken) {\n logOutput(`${accessToken}`);\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n // Exchange the WorkOS access token for a Convex personal access token.\n ctx._updateBigBrainAuth({\n accessToken: accessToken,\n kind: \"accessToken\",\n header: `Bearer ${accessToken}`,\n });\n const response = await typedPlatformClient(ctx).POST(\n \"/create_personal_access_token\",\n {\n // `anonymousId` links a prior anonymous session to this account. It's\n // intentionally absent from the generated platform API types,\n // so cast to pass it through.\n body: { name: deviceName, anonymousId } as { name: string },\n },\n );\n const newAccessToken = response.data!.accessToken;\n const globalConfig = { accessToken: newAccessToken };\n try {\n await modifyGlobalConfig(ctx, globalConfig);\n const path = globalConfigPath();\n logFinishedStep(`Saved credentials to ${formatPathForPrinting(path)}`);\n } catch (err: unknown) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"invalid filesystem data\",\n errForSentry: err,\n printedMessage: null,\n });\n }\n\n logVerbose(`performLogin: updating big brain auth after login`);\n await updateBigBrainAuthAfterLogin(ctx, newAccessToken);\n\n logVerbose(`performLogin: checking opt ins, acceptOptIns: ${acceptOptIns}`);\n // Do opt in to TOS and Privacy Policy stuff\n const shouldContinue = await optins(ctx, acceptOptIns ?? false);\n if (!shouldContinue) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: null,\n });\n }\n\n if (vercel) {\n await promptJoinVercelTeams(ctx);\n }\n}\n\ntype PotentialVercelTeam = {\n teamId: number;\n teamName: string;\n teamSlug: string;\n planId: string;\n planName: string;\n pricingNotice: string | null;\n};\n\n// After `--vercel` login, surface any Vercel-marketplace teams the user has\n// access to but isn't yet a member of, and prompt to join each.\nasync function promptJoinVercelTeams(ctx: Context): Promise<void> {\n const fetch = bigBrainFetch(ctx);\n let teams: PotentialVercelTeam[];\n try {\n const res = await fetch(\n new URL(\"vercel/potential_teams\", `${provisionHost}/`),\n );\n if (!res.ok) {\n logVerbose(\n `vercel/potential_teams returned ${res.status}; skipping team-join prompt`,\n );\n return;\n }\n teams = await res.json();\n } catch (err) {\n logVerbose(`Failed to fetch potential Vercel teams: ${String(err)}`);\n return;\n }\n if (teams.length === 0) return;\n\n for (const [index, team] of teams.entries()) {\n const displayName = team.teamName.replace(/ \\(Vercel\\)$/, \"\");\n const counter = teams.length > 1 ? `[${index + 1}/${teams.length}] ` : \"\";\n const lines = [\n chalkStderr.bold(`${counter}You've been invited to join ${displayName}`) +\n ` (${team.planName}) through the Vercel marketplace.`,\n ];\n if (team.pricingNotice) {\n lines.push(chalkStderr.yellow(team.pricingNotice));\n }\n lines.push(`Join \"${displayName}\"?`);\n const join = await promptYesNo(ctx, {\n message: `${lines.join(\"\\n\")}`,\n default: true,\n });\n if (!join) continue;\n try {\n await fetch(\n new URL(\n `vercel/potential_teams/${team.teamId}/join`,\n `${provisionHost}/`,\n ),\n { method: \"POST\" },\n );\n logFinishedStep(`Joined ${displayName}`);\n } catch (err) {\n logFailure(`Failed to join ${displayName}: ${String(err)}`);\n }\n }\n}\n\n/// There are fields like version, but we keep them opaque\ntype OptIn = Record<string, unknown>;\n\ntype OptInToAccept = {\n optIn: OptIn;\n message: string;\n};\n\ntype AcceptOptInsArgs = {\n optInsAccepted: OptIn[];\n};\n\n// Returns whether we can proceed or not.\nasync function optins(ctx: Context, acceptOptIns: boolean): Promise<boolean> {\n const bbAuth = ctx.bigBrainAuth();\n if (bbAuth === null) {\n // This should never happen, but if we're not even logged in, we can't proceed.\n return false;\n }\n switch (bbAuth.kind) {\n case \"accessToken\":\n break;\n case \"deploymentKey\":\n case \"projectKey\":\n case \"previewDeployKey\":\n // If we have a key configured as auth, we do not need to check opt ins.\n return true;\n default: {\n bbAuth satisfies never;\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n errForSentry: `Unexpected auth kind ${(bbAuth as any).kind}`,\n printedMessage: \"Hit an unexpected error while logging in.\",\n });\n }\n }\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"check_opt_ins\",\n });\n if (data.optInsToAccept.length === 0) {\n return true;\n }\n for (const optInToAccept of data.optInsToAccept) {\n const confirmed =\n acceptOptIns ||\n (await promptYesNo(ctx, {\n message: optInToAccept.message,\n }));\n if (!confirmed) {\n logFailure(\"Please accept the Terms of Service to use Convex.\");\n return Promise.resolve(false);\n }\n }\n\n const optInsAccepted = data.optInsToAccept.map((o: OptInToAccept) => o.optIn);\n const args: AcceptOptInsArgs = { optInsAccepted };\n await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"accept_opt_ins\",\n data: args,\n });\n return true;\n}\n\nexport async function ensureLoggedIn(\n ctx: Context,\n options?: {\n message?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n },\n) {\n const isLoggedIn = await checkAuthorization(ctx, false);\n if (!isLoggedIn) {\n if (options?.message) {\n logMessage(options.message);\n }\n await performLogin(ctx, {\n acceptOptIns: false,\n overrideAuthUrl: options?.overrideAuthUrl,\n overrideAuthClient: options?.overrideAuthClient,\n overrideAuthUsername: options?.overrideAuthUsername,\n overrideAuthPassword: options?.overrideAuthPassword,\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_openid_client", "open", "fetch"]
7
7
  }
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var login_exports = {};
20
30
  __export(login_exports, {
@@ -22,6 +32,7 @@ __export(login_exports, {
22
32
  });
23
33
  module.exports = __toCommonJS(login_exports);
24
34
  var import_extra_typings = require("@commander-js/extra-typings");
35
+ var dotenv = __toESM(require("dotenv"), 1);
25
36
  var import_context = require("../bundler/context.js");
26
37
  var import_log = require("../bundler/log.js");
27
38
  var import_login = require("./lib/login.js");
@@ -35,26 +46,59 @@ var import_deploymentSelection = require("./lib/deploymentSelection.js");
35
46
  var import_deployment = require("./lib/deployment.js");
36
47
  var import_globalConfig = require("./lib/utils/globalConfig.js");
37
48
  var import_api = require("./lib/api.js");
49
+ function deployKeyEnvFile(ctx, envVarName, value) {
50
+ for (const file of [import_utils.ENV_VAR_FILE_PATH, ".env"]) {
51
+ if (!ctx.fs.exists(file)) {
52
+ continue;
53
+ }
54
+ if (dotenv.parse(ctx.fs.readUtf8File(file))[envVarName] === value) {
55
+ return file;
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+ async function reportDeployKeyInWorkingDirectory(ctx, auth) {
61
+ if (auth === null || auth.kind === "accessToken" || auth.kind === "previewDeployKey") {
62
+ return;
63
+ }
64
+ const key = auth.kind === "projectKey" ? auth.projectKey : auth.deploymentKey;
65
+ const envVarName = process.env[import_utils.CONVEX_DEPLOY_KEY_ENV_VAR_NAME] ? import_utils.CONVEX_DEPLOY_KEY_ENV_VAR_NAME : import_utils.CONVEX_DEPLOYMENT_TOKEN_ENV_VAR_NAME;
66
+ const envFile = deployKeyEnvFile(ctx, envVarName, key);
67
+ const source = envFile ?? "shell environment";
68
+ const secret = key.slice(key.indexOf("|") + 1);
69
+ if (await (0, import_login.isAuthorizedHeader)(ctx, `Bearer ${secret}`)) {
70
+ (0, import_log.logMessage)(`Working Directory: Valid ${envVarName} in ${source}`);
71
+ return;
72
+ }
73
+ (0, import_log.logWarning)(`Working Directory: Invalid ${envVarName} in ${source}`);
74
+ }
38
75
  const loginStatus = new import_extra_typings.Command("status").description("Check login status and list accessible teams").allowExcessArguments(false).action(async () => {
39
76
  const ctx = await (0, import_context.oneoffContext)({
40
77
  url: void 0,
41
78
  adminKey: void 0,
42
79
  envFile: void 0
43
80
  });
81
+ const auth = ctx.bigBrainAuth();
44
82
  const globalConfig = (0, import_globalConfig.readGlobalConfig)(ctx);
45
- const hasToken = globalConfig?.accessToken !== null;
46
- if (hasToken) {
47
- (0, import_log.logMessage)(`Convex account token found in: ${(0, import_globalConfig.globalConfigPath)()}`);
48
- } else {
49
- (0, import_log.logMessage)("No token found locally");
83
+ if (globalConfig === null) {
84
+ (0, import_log.logMessage)(`No Convex account token found in: ${(0, import_globalConfig.globalConfigPath)()}`);
85
+ (0, import_log.logMessage)("Status: Not logged in");
86
+ await reportDeployKeyInWorkingDirectory(ctx, auth);
50
87
  return;
51
88
  }
52
- const isLoggedIn = await (0, import_login.checkAuthorization)(ctx, false);
53
- if (!isLoggedIn) {
89
+ (0, import_log.logMessage)(`Convex account token found in: ${(0, import_globalConfig.globalConfigPath)()}`);
90
+ const accessToken = globalConfig.accessToken;
91
+ if (!await (0, import_login.isAuthorizedHeader)(ctx, `Bearer ${accessToken}`)) {
54
92
  (0, import_log.logMessage)("Status: Not logged in");
93
+ await reportDeployKeyInWorkingDirectory(ctx, auth);
55
94
  return;
56
95
  }
57
96
  (0, import_log.logMessage)("Status: Logged in");
97
+ ctx._updateBigBrainAuth({
98
+ kind: "accessToken",
99
+ header: `Bearer ${accessToken}`,
100
+ accessToken
101
+ });
58
102
  const teams = await (0, import_api.getTeamsForUser)(ctx);
59
103
  (0, import_log.logMessage)(
60
104
  `Teams: ${teams.length} team${teams.length === 1 ? "" : "s"} accessible`
@@ -62,6 +106,7 @@ const loginStatus = new import_extra_typings.Command("status").description("Chec
62
106
  for (const team of teams) {
63
107
  (0, import_log.logMessage)(` - ${team.name} (${team.slug})`);
64
108
  }
109
+ await reportDeployKeyInWorkingDirectory(ctx, auth);
65
110
  });
66
111
  const login = new import_extra_typings.Command("login").description("Login to Convex").allowExcessArguments(false).option(
67
112
  "--device-name <name>",