convex 1.36.0 → 1.37.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 (240) hide show
  1. package/CHANGELOG.md +50 -27
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/codegen_templates/agentsmd.js +8 -2
  5. package/dist/cjs/cli/codegen_templates/agentsmd.js.map +2 -2
  6. package/dist/cjs/cli/codegen_templates/claudemd.js +2 -0
  7. package/dist/cjs/cli/codegen_templates/claudemd.js.map +2 -2
  8. package/dist/cjs/cli/configure.js +0 -8
  9. package/dist/cjs/cli/configure.js.map +2 -2
  10. package/dist/cjs/cli/deployment.js +2 -1
  11. package/dist/cjs/cli/deployment.js.map +2 -2
  12. package/dist/cjs/cli/deploymentToken.js +30 -0
  13. package/dist/cjs/cli/deploymentToken.js.map +7 -0
  14. package/dist/cjs/cli/deploymentTokenCreate.js +109 -0
  15. package/dist/cjs/cli/deploymentTokenCreate.js.map +7 -0
  16. package/dist/cjs/cli/deploymentTokenDelete.js +87 -0
  17. package/dist/cjs/cli/deploymentTokenDelete.js.map +7 -0
  18. package/dist/cjs/cli/envDefault.js +130 -41
  19. package/dist/cjs/cli/envDefault.js.map +3 -3
  20. package/dist/cjs/cli/generatedApi.js.map +1 -1
  21. package/dist/cjs/cli/lib/command.js +1 -1
  22. package/dist/cjs/cli/lib/command.js.map +1 -1
  23. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  24. package/dist/cjs/cli/lib/login.js +51 -0
  25. package/dist/cjs/cli/lib/login.js.map +3 -3
  26. package/dist/cjs/cli/lib/usage.js +13 -6
  27. package/dist/cjs/cli/lib/usage.js.map +2 -2
  28. package/dist/cjs/cli/lib/workos/environmentApi.js +6 -12
  29. package/dist/cjs/cli/lib/workos/environmentApi.js.map +3 -3
  30. package/dist/cjs/index.js +1 -1
  31. package/dist/cjs/index.js.map +1 -1
  32. package/dist/cjs/react/client.js +40 -42
  33. package/dist/cjs/react/client.js.map +2 -2
  34. package/dist/cjs/react/index.js +1 -0
  35. package/dist/cjs/react/index.js.map +2 -2
  36. package/dist/cjs/react/use_paginated_query.js +5 -46
  37. package/dist/cjs/react/use_paginated_query.js.map +2 -2
  38. package/dist/cjs/react/use_paginated_query2.js.map +2 -2
  39. package/dist/cjs/server/audit_logging.js +67 -0
  40. package/dist/cjs/server/audit_logging.js.map +7 -0
  41. package/dist/cjs/server/impl/meta_impl.js +27 -3
  42. package/dist/cjs/server/impl/meta_impl.js.map +2 -2
  43. package/dist/cjs/server/impl/registration_impl.js +2 -0
  44. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  45. package/dist/cjs/server/index.js +2 -0
  46. package/dist/cjs/server/index.js.map +2 -2
  47. package/dist/cjs/server/log.js +30 -0
  48. package/dist/cjs/server/log.js.map +7 -0
  49. package/dist/cjs/server/logVars.js +48 -0
  50. package/dist/cjs/server/logVars.js.map +7 -0
  51. package/dist/cjs/server/meta.js.map +1 -1
  52. package/dist/cjs/server/registration.js.map +1 -1
  53. package/dist/cjs-types/cli/codegen_templates/agentsmd.d.ts.map +1 -1
  54. package/dist/cjs-types/cli/codegen_templates/claudemd.d.ts.map +1 -1
  55. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  56. package/dist/cjs-types/cli/deployment.d.ts.map +1 -1
  57. package/dist/cjs-types/cli/deploymentToken.d.ts +3 -0
  58. package/dist/cjs-types/cli/deploymentToken.d.ts.map +1 -0
  59. package/dist/cjs-types/cli/deploymentToken.test.d.ts +2 -0
  60. package/dist/cjs-types/cli/deploymentToken.test.d.ts.map +1 -0
  61. package/dist/cjs-types/cli/deploymentTokenCreate.d.ts +13 -0
  62. package/dist/cjs-types/cli/deploymentTokenCreate.d.ts.map +1 -0
  63. package/dist/cjs-types/cli/deploymentTokenDelete.d.ts +11 -0
  64. package/dist/cjs-types/cli/deploymentTokenDelete.d.ts.map +1 -0
  65. package/dist/cjs-types/cli/envDefault.d.ts +2 -2
  66. package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
  67. package/dist/cjs-types/cli/envDefault.test.d.ts +2 -0
  68. package/dist/cjs-types/cli/envDefault.test.d.ts.map +1 -0
  69. package/dist/cjs-types/cli/generatedApi.d.ts +1 -1
  70. package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
  71. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +1 -0
  72. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  73. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  74. package/dist/cjs-types/cli/lib/usage.d.ts.map +1 -1
  75. package/dist/cjs-types/cli/lib/workos/environmentApi.d.ts.map +1 -1
  76. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts +2 -0
  77. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts.map +1 -0
  78. package/dist/cjs-types/index.d.ts +1 -1
  79. package/dist/cjs-types/react/client.d.ts +52 -0
  80. package/dist/cjs-types/react/client.d.ts.map +1 -1
  81. package/dist/cjs-types/react/index.d.ts +2 -2
  82. package/dist/cjs-types/react/index.d.ts.map +1 -1
  83. package/dist/cjs-types/react/use_paginated_query.d.ts.map +1 -1
  84. package/dist/cjs-types/react/use_paginated_query2.d.ts +63 -1
  85. package/dist/cjs-types/react/use_paginated_query2.d.ts.map +1 -1
  86. package/dist/cjs-types/server/api.intersect.test.d.ts +2 -0
  87. package/dist/cjs-types/server/api.intersect.test.d.ts.map +1 -0
  88. package/dist/cjs-types/server/audit_logging.d.ts +19 -0
  89. package/dist/cjs-types/server/audit_logging.d.ts.map +1 -0
  90. package/dist/cjs-types/server/audit_logging.test.d.ts +2 -0
  91. package/dist/cjs-types/server/audit_logging.test.d.ts.map +1 -0
  92. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -1
  93. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  94. package/dist/cjs-types/server/index.d.ts +2 -2
  95. package/dist/cjs-types/server/index.d.ts.map +1 -1
  96. package/dist/cjs-types/server/log.d.ts +2 -0
  97. package/dist/cjs-types/server/log.d.ts.map +1 -0
  98. package/dist/cjs-types/server/logVars.d.ts +20 -0
  99. package/dist/cjs-types/server/logVars.d.ts.map +1 -0
  100. package/dist/cjs-types/server/meta.d.ts +40 -0
  101. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  102. package/dist/cjs-types/server/registration.d.ts +5 -2
  103. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  104. package/dist/cli.bundle.cjs +362 -74
  105. package/dist/cli.bundle.cjs.map +4 -4
  106. package/dist/esm/cli/codegen_templates/agentsmd.js +8 -2
  107. package/dist/esm/cli/codegen_templates/agentsmd.js.map +2 -2
  108. package/dist/esm/cli/codegen_templates/claudemd.js +2 -0
  109. package/dist/esm/cli/codegen_templates/claudemd.js.map +2 -2
  110. package/dist/esm/cli/configure.js +0 -8
  111. package/dist/esm/cli/configure.js.map +2 -2
  112. package/dist/esm/cli/deployment.js +2 -1
  113. package/dist/esm/cli/deployment.js.map +2 -2
  114. package/dist/esm/cli/deploymentToken.js +8 -0
  115. package/dist/esm/cli/deploymentToken.js.map +7 -0
  116. package/dist/esm/cli/deploymentTokenCreate.js +91 -0
  117. package/dist/esm/cli/deploymentTokenCreate.js.map +7 -0
  118. package/dist/esm/cli/deploymentTokenDelete.js +68 -0
  119. package/dist/esm/cli/deploymentTokenDelete.js.map +7 -0
  120. package/dist/esm/cli/envDefault.js +131 -42
  121. package/dist/esm/cli/envDefault.js.map +3 -3
  122. package/dist/esm/cli/lib/command.js +1 -1
  123. package/dist/esm/cli/lib/command.js.map +1 -1
  124. package/dist/esm/cli/lib/login.js +52 -0
  125. package/dist/esm/cli/lib/login.js.map +3 -3
  126. package/dist/esm/cli/lib/usage.js +15 -8
  127. package/dist/esm/cli/lib/usage.js.map +2 -2
  128. package/dist/esm/cli/lib/workos/environmentApi.js +6 -12
  129. package/dist/esm/cli/lib/workos/environmentApi.js.map +3 -3
  130. package/dist/esm/index.js +1 -1
  131. package/dist/esm/index.js.map +1 -1
  132. package/dist/esm/react/client.js +38 -41
  133. package/dist/esm/react/client.js.map +2 -2
  134. package/dist/esm/react/index.js +4 -1
  135. package/dist/esm/react/index.js.map +2 -2
  136. package/dist/esm/react/use_paginated_query.js +5 -46
  137. package/dist/esm/react/use_paginated_query.js.map +2 -2
  138. package/dist/esm/react/use_paginated_query2.js.map +2 -2
  139. package/dist/esm/server/audit_logging.js +44 -0
  140. package/dist/esm/server/audit_logging.js.map +7 -0
  141. package/dist/esm/server/impl/meta_impl.js +27 -3
  142. package/dist/esm/server/impl/meta_impl.js.map +2 -2
  143. package/dist/esm/server/impl/registration_impl.js +2 -0
  144. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  145. package/dist/esm/server/index.js +1 -0
  146. package/dist/esm/server/index.js.map +2 -2
  147. package/dist/esm/server/log.js +8 -0
  148. package/dist/esm/server/log.js.map +7 -0
  149. package/dist/esm/server/logVars.js +25 -0
  150. package/dist/esm/server/logVars.js.map +7 -0
  151. package/dist/esm-types/cli/codegen_templates/agentsmd.d.ts.map +1 -1
  152. package/dist/esm-types/cli/codegen_templates/claudemd.d.ts.map +1 -1
  153. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  154. package/dist/esm-types/cli/deployment.d.ts.map +1 -1
  155. package/dist/esm-types/cli/deploymentToken.d.ts +3 -0
  156. package/dist/esm-types/cli/deploymentToken.d.ts.map +1 -0
  157. package/dist/esm-types/cli/deploymentToken.test.d.ts +2 -0
  158. package/dist/esm-types/cli/deploymentToken.test.d.ts.map +1 -0
  159. package/dist/esm-types/cli/deploymentTokenCreate.d.ts +13 -0
  160. package/dist/esm-types/cli/deploymentTokenCreate.d.ts.map +1 -0
  161. package/dist/esm-types/cli/deploymentTokenDelete.d.ts +11 -0
  162. package/dist/esm-types/cli/deploymentTokenDelete.d.ts.map +1 -0
  163. package/dist/esm-types/cli/envDefault.d.ts +2 -2
  164. package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
  165. package/dist/esm-types/cli/envDefault.test.d.ts +2 -0
  166. package/dist/esm-types/cli/envDefault.test.d.ts.map +1 -0
  167. package/dist/esm-types/cli/generatedApi.d.ts +1 -1
  168. package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
  169. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +1 -0
  170. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  171. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  172. package/dist/esm-types/cli/lib/usage.d.ts.map +1 -1
  173. package/dist/esm-types/cli/lib/workos/environmentApi.d.ts.map +1 -1
  174. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts +2 -0
  175. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts.map +1 -0
  176. package/dist/esm-types/index.d.ts +1 -1
  177. package/dist/esm-types/react/client.d.ts +52 -0
  178. package/dist/esm-types/react/client.d.ts.map +1 -1
  179. package/dist/esm-types/react/index.d.ts +2 -2
  180. package/dist/esm-types/react/index.d.ts.map +1 -1
  181. package/dist/esm-types/react/use_paginated_query.d.ts.map +1 -1
  182. package/dist/esm-types/react/use_paginated_query2.d.ts +63 -1
  183. package/dist/esm-types/react/use_paginated_query2.d.ts.map +1 -1
  184. package/dist/esm-types/server/api.intersect.test.d.ts +2 -0
  185. package/dist/esm-types/server/api.intersect.test.d.ts.map +1 -0
  186. package/dist/esm-types/server/audit_logging.d.ts +19 -0
  187. package/dist/esm-types/server/audit_logging.d.ts.map +1 -0
  188. package/dist/esm-types/server/audit_logging.test.d.ts +2 -0
  189. package/dist/esm-types/server/audit_logging.test.d.ts.map +1 -0
  190. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -1
  191. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  192. package/dist/esm-types/server/index.d.ts +2 -2
  193. package/dist/esm-types/server/index.d.ts.map +1 -1
  194. package/dist/esm-types/server/log.d.ts +2 -0
  195. package/dist/esm-types/server/log.d.ts.map +1 -0
  196. package/dist/esm-types/server/logVars.d.ts +20 -0
  197. package/dist/esm-types/server/logVars.d.ts.map +1 -0
  198. package/dist/esm-types/server/meta.d.ts +40 -0
  199. package/dist/esm-types/server/meta.d.ts.map +1 -1
  200. package/dist/esm-types/server/registration.d.ts +5 -2
  201. package/dist/esm-types/server/registration.d.ts.map +1 -1
  202. package/dist/react.bundle.js +45 -88
  203. package/dist/react.bundle.js.map +2 -2
  204. package/package.json +4 -4
  205. package/src/cli/codegen_templates/agentsmd.ts +8 -2
  206. package/src/cli/codegen_templates/claudemd.ts +2 -0
  207. package/src/cli/configure.ts +0 -9
  208. package/src/cli/deployment.ts +3 -1
  209. package/src/cli/deploymentToken.test.ts +372 -0
  210. package/src/cli/deploymentToken.ts +11 -0
  211. package/src/cli/deploymentTokenCreate.ts +113 -0
  212. package/src/cli/deploymentTokenDelete.ts +91 -0
  213. package/src/cli/envDefault.test.ts +495 -0
  214. package/src/cli/envDefault.ts +222 -107
  215. package/src/cli/generatedApi.ts +1 -1
  216. package/src/cli/lib/command.ts +1 -1
  217. package/src/cli/lib/generatedFunctionLogsApi.ts +1 -0
  218. package/src/cli/lib/login.ts +67 -0
  219. package/src/cli/lib/usage.ts +18 -8
  220. package/src/cli/lib/workos/environmentApi.test.ts +107 -0
  221. package/src/cli/lib/workos/environmentApi.ts +12 -19
  222. package/src/index.ts +1 -1
  223. package/src/react/client.test.tsx +10 -8
  224. package/src/react/client.ts +88 -96
  225. package/src/react/index.ts +6 -1
  226. package/src/react/use_paginated_query.test.tsx +215 -132
  227. package/src/react/use_paginated_query.ts +8 -142
  228. package/src/react/use_paginated_query2.ts +78 -5
  229. package/src/react/use_query_object_options.test.ts +8 -7
  230. package/src/react/use_query_result.test.ts +40 -7
  231. package/src/server/api.intersect.test.ts +109 -0
  232. package/src/server/audit_logging.test.ts +129 -0
  233. package/src/server/audit_logging.ts +75 -0
  234. package/src/server/impl/meta_impl.ts +28 -0
  235. package/src/server/impl/registration_impl.ts +2 -0
  236. package/src/server/index.ts +12 -0
  237. package/src/server/log.ts +16 -0
  238. package/src/server/logVars.ts +34 -0
  239. package/src/server/meta.ts +53 -1
  240. package/src/server/registration.ts +10 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/generatedFunctionLogsApi.ts"],
4
- "sourcesContent": ["/**\n * This file was auto-generated by openapi-typescript.\n * Do not make direct changes to the file.\n */\n\nexport type paths = Record<string, never>;\nexport type webhooks = Record<string, never>;\nexport interface components {\n schemas: {\n FunctionExecutionJson: {\n cachedResult: boolean;\n caller: string;\n componentPath?: string | null;\n environment: string;\n error?: string | null;\n executionId: string;\n /** Format: double */\n executionTime: number;\n /** Format: double */\n executionTimestamp: number;\n identifier: string;\n identityType: string;\n /** @enum {string} */\n kind: \"Completion\";\n logLines: components[\"schemas\"][\"Value\"][];\n occInfo?: null | components[\"schemas\"][\"OccInfoJson\"];\n parentExecutionId?: string | null;\n requestId: string;\n /** Format: double */\n returnBytes?: number | null;\n success?: null | components[\"schemas\"][\"Value\"];\n /** Format: double */\n timestamp: number;\n udfType: components[\"schemas\"][\"UdfTypeJson\"];\n usageStats: components[\"schemas\"][\"UsageStatsJson\"];\n /** Format: double */\n userExecutionTime?: number | null;\n } | {\n componentPath?: string | null;\n executionId: string;\n identifier: string;\n /** @enum {string} */\n kind: \"Progress\";\n logLines: components[\"schemas\"][\"Value\"][];\n requestId: string;\n /** Format: double */\n timestamp: number;\n udfType: components[\"schemas\"][\"UdfTypeJson\"];\n };\n /** @enum {string} */\n LogLevelJson: \"DEBUG\" | \"ERROR\" | \"WARN\" | \"INFO\" | \"LOG\";\n LogLineJson: {\n componentPath?: string | null;\n isTruncated: boolean;\n level: components[\"schemas\"][\"LogLevelJson\"];\n messages: string[];\n systemMetadata?: null | components[\"schemas\"][\"SystemLogMetadataJson\"];\n /** Format: int64 */\n timestamp: number;\n udfPath?: string | null;\n };\n OccInfoJson: {\n componentPath?: string | null;\n documentId?: string | null;\n /** Format: int64 */\n retryCount?: number | null;\n tableName?: string | null;\n writeSource?: string | null;\n };\n StreamFunctionLogs: {\n /** Format: int32 */\n clientRequestCounter?: number | null;\n /** Format: double */\n cursor: number;\n sessionId?: string | null;\n };\n StreamUdfExecutionQueryArgs: {\n /** Format: double */\n cursor: number;\n };\n StreamUdfExecutionResponse: {\n entries: components[\"schemas\"][\"FunctionExecutionJson\"][];\n /** Format: double */\n newCursor: number;\n };\n SystemLogMetadataJson: {\n code: string;\n };\n /** @enum {string} */\n UdfTypeJson: \"Query\" | \"Mutation\" | \"Action\" | \"HttpAction\";\n UsageStatsJson: {\n /** Format: int64 */\n databaseIoReadBytes: number;\n /** Format: int64 */\n databaseIoWriteBytes: number;\n /** Format: int64 */\n databaseReadBytes: number;\n /** Format: int64 */\n databaseReadDocuments: number;\n /** Format: int64 */\n databaseWriteBytes: number;\n /** Format: int64 */\n memoryUsedMb: number;\n /** Format: int64 */\n networkEgressBytes: number;\n /** Format: int64 */\n storageReadBytes: number;\n /** Format: int64 */\n storageWriteBytes: number;\n /** Format: int64 */\n textIndexQueryBytes: number;\n /** Format: int64 */\n textIndexWriteQueryBytes: number;\n /** Format: int64 */\n vectorIndexReadBytes: number;\n /** Format: int64 */\n vectorIndexReadQueryBytes: number;\n /** Format: int64 */\n vectorIndexWriteBytes: number;\n /** Format: int64 */\n vectorIndexWriteQueryBytes: number;\n };\n Value: unknown;\n };\n responses: never;\n parameters: never;\n requestBodies: never;\n headers: never;\n pathItems: never;\n}\nexport type FunctionExecutionJson = components['schemas']['FunctionExecutionJson'];\nexport type LogLevelJson = components['schemas']['LogLevelJson'];\nexport type LogLineJson = components['schemas']['LogLineJson'];\nexport type OccInfoJson = components['schemas']['OccInfoJson'];\nexport type StreamFunctionLogs = components['schemas']['StreamFunctionLogs'];\nexport type StreamUdfExecutionQueryArgs = components['schemas']['StreamUdfExecutionQueryArgs'];\nexport type StreamUdfExecutionResponse = components['schemas']['StreamUdfExecutionResponse'];\nexport type SystemLogMetadataJson = components['schemas']['SystemLogMetadataJson'];\nexport type UdfTypeJson = components['schemas']['UdfTypeJson'];\nexport type UsageStatsJson = components['schemas']['UsageStatsJson'];\nexport type Value = components['schemas']['Value'];\nexport type $defs = Record<string, never>;\nexport type operations = Record<string, never>;\n"],
4
+ "sourcesContent": ["/**\n * This file was auto-generated by openapi-typescript.\n * Do not make direct changes to the file.\n */\n\nexport type paths = Record<string, never>;\nexport type webhooks = Record<string, never>;\nexport interface components {\n schemas: {\n FunctionExecutionJson: {\n cachedResult: boolean;\n caller: string;\n componentPath?: string | null;\n environment: string;\n error?: string | null;\n executionId: string;\n /** Format: double */\n executionTime: number;\n /** Format: double */\n executionTimestamp: number;\n identifier: string;\n identityType: string;\n /** @enum {string} */\n kind: \"Completion\";\n logLines: components[\"schemas\"][\"Value\"][];\n occInfo?: null | components[\"schemas\"][\"OccInfoJson\"];\n parentExecutionId?: string | null;\n requestId: string;\n /** Format: double */\n returnBytes?: number | null;\n success?: null | components[\"schemas\"][\"Value\"];\n /** Format: double */\n timestamp: number;\n udfType: components[\"schemas\"][\"UdfTypeJson\"];\n usageStats: components[\"schemas\"][\"UsageStatsJson\"];\n /** Format: double */\n userExecutionTime?: number | null;\n willRetry: boolean;\n } | {\n componentPath?: string | null;\n executionId: string;\n identifier: string;\n /** @enum {string} */\n kind: \"Progress\";\n logLines: components[\"schemas\"][\"Value\"][];\n requestId: string;\n /** Format: double */\n timestamp: number;\n udfType: components[\"schemas\"][\"UdfTypeJson\"];\n };\n /** @enum {string} */\n LogLevelJson: \"DEBUG\" | \"ERROR\" | \"WARN\" | \"INFO\" | \"LOG\";\n LogLineJson: {\n componentPath?: string | null;\n isTruncated: boolean;\n level: components[\"schemas\"][\"LogLevelJson\"];\n messages: string[];\n systemMetadata?: null | components[\"schemas\"][\"SystemLogMetadataJson\"];\n /** Format: int64 */\n timestamp: number;\n udfPath?: string | null;\n };\n OccInfoJson: {\n componentPath?: string | null;\n documentId?: string | null;\n /** Format: int64 */\n retryCount?: number | null;\n tableName?: string | null;\n writeSource?: string | null;\n };\n StreamFunctionLogs: {\n /** Format: int32 */\n clientRequestCounter?: number | null;\n /** Format: double */\n cursor: number;\n sessionId?: string | null;\n };\n StreamUdfExecutionQueryArgs: {\n /** Format: double */\n cursor: number;\n };\n StreamUdfExecutionResponse: {\n entries: components[\"schemas\"][\"FunctionExecutionJson\"][];\n /** Format: double */\n newCursor: number;\n };\n SystemLogMetadataJson: {\n code: string;\n };\n /** @enum {string} */\n UdfTypeJson: \"Query\" | \"Mutation\" | \"Action\" | \"HttpAction\";\n UsageStatsJson: {\n /** Format: int64 */\n databaseIoReadBytes: number;\n /** Format: int64 */\n databaseIoWriteBytes: number;\n /** Format: int64 */\n databaseReadBytes: number;\n /** Format: int64 */\n databaseReadDocuments: number;\n /** Format: int64 */\n databaseWriteBytes: number;\n /** Format: int64 */\n memoryUsedMb: number;\n /** Format: int64 */\n networkEgressBytes: number;\n /** Format: int64 */\n storageReadBytes: number;\n /** Format: int64 */\n storageWriteBytes: number;\n /** Format: int64 */\n textIndexQueryBytes: number;\n /** Format: int64 */\n textIndexWriteQueryBytes: number;\n /** Format: int64 */\n vectorIndexReadBytes: number;\n /** Format: int64 */\n vectorIndexReadQueryBytes: number;\n /** Format: int64 */\n vectorIndexWriteBytes: number;\n /** Format: int64 */\n vectorIndexWriteQueryBytes: number;\n };\n Value: unknown;\n };\n responses: never;\n parameters: never;\n requestBodies: never;\n headers: never;\n pathItems: never;\n}\nexport type FunctionExecutionJson = components['schemas']['FunctionExecutionJson'];\nexport type LogLevelJson = components['schemas']['LogLevelJson'];\nexport type LogLineJson = components['schemas']['LogLineJson'];\nexport type OccInfoJson = components['schemas']['OccInfoJson'];\nexport type StreamFunctionLogs = components['schemas']['StreamFunctionLogs'];\nexport type StreamUdfExecutionQueryArgs = components['schemas']['StreamUdfExecutionQueryArgs'];\nexport type StreamUdfExecutionResponse = components['schemas']['StreamUdfExecutionResponse'];\nexport type SystemLogMetadataJson = components['schemas']['SystemLogMetadataJson'];\nexport type UdfTypeJson = components['schemas']['UdfTypeJson'];\nexport type UsageStatsJson = components['schemas']['UsageStatsJson'];\nexport type Value = components['schemas']['Value'];\nexport type $defs = Record<string, never>;\nexport type operations = Record<string, never>;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -318,6 +318,57 @@ async function performLogin(ctx, {
318
318
  printedMessage: null
319
319
  });
320
320
  }
321
+ if (vercel) {
322
+ await promptJoinVercelTeams(ctx);
323
+ }
324
+ }
325
+ async function promptJoinVercelTeams(ctx) {
326
+ const fetch2 = (0, import_utils.bigBrainFetch)(ctx);
327
+ let teams;
328
+ try {
329
+ const res = await fetch2(
330
+ new URL("vercel/potential_teams", `${import_config.provisionHost}/`)
331
+ );
332
+ if (!res.ok) {
333
+ (0, import_log.logVerbose)(
334
+ `vercel/potential_teams returned ${res.status}; skipping team-join prompt`
335
+ );
336
+ return;
337
+ }
338
+ teams = await res.json();
339
+ } catch (err) {
340
+ (0, import_log.logVerbose)(`Failed to fetch potential Vercel teams: ${String(err)}`);
341
+ return;
342
+ }
343
+ if (teams.length === 0) return;
344
+ for (const [index, team] of teams.entries()) {
345
+ const displayName = team.teamName.replace(/ \(Vercel\)$/, "");
346
+ const counter = teams.length > 1 ? `[${index + 1}/${teams.length}] ` : "";
347
+ const lines = [
348
+ import_chalk.chalkStderr.bold(`${counter}You've been invited to join ${displayName}`) + ` (${team.planName}) through the Vercel marketplace.`
349
+ ];
350
+ if (team.pricingNotice) {
351
+ lines.push(import_chalk.chalkStderr.yellow(team.pricingNotice));
352
+ }
353
+ lines.push(`Join "${displayName}"?`);
354
+ const join = await (0, import_prompts.promptYesNo)(ctx, {
355
+ message: `${lines.join("\n")}`,
356
+ default: true
357
+ });
358
+ if (!join) continue;
359
+ try {
360
+ await fetch2(
361
+ new URL(
362
+ `vercel/potential_teams/${team.teamId}/join`,
363
+ `${import_config.provisionHost}/`
364
+ ),
365
+ { method: "POST" }
366
+ );
367
+ (0, import_log.logFinishedStep)(`Joined ${displayName}`);
368
+ } catch (err) {
369
+ (0, import_log.logFailure)(`Failed to join ${displayName}: ${String(err)}`);
370
+ }
371
+ }
321
372
  }
322
373
  async function optins(ctx, acceptOptIns) {
323
374
  const bbAuth = ctx.bigBrainAuth();
@@ -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 logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\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\ninterface AuthorizeArgs {\n authnToken: string;\n deviceName: string;\n anonymousId?: string | undefined;\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 let authIssuer;\n let accessToken: string;\n\n if (loginFlow === \"paste\" || (loginFlow === \"auto\" && isWebContainer())) {\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 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 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 // typical path\n if (authIssuer) {\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\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\n if (overrideAccessToken) {\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else {\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\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 const authorizeArgs: AuthorizeArgs = {\n authnToken: accessToken!,\n deviceName: deviceName,\n anonymousId: anonymousId,\n };\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"authorize\",\n data: authorizeArgs,\n });\n const globalConfig = { accessToken: data.accessToken };\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, data.accessToken);\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\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
- "names": ["import_openid_client", "open"]
4
+ "sourcesContent": ["import { errors, BaseClient, custom } from \"openid-client\";\nimport {\n bigBrainAPI,\n bigBrainFetch,\n logAndHandleFetchError,\n throwingFetch,\n isWebContainer,\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\ninterface AuthorizeArgs {\n authnToken: string;\n deviceName: string;\n anonymousId?: string | undefined;\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 let authIssuer;\n let accessToken: string;\n\n if (loginFlow === \"paste\" || (loginFlow === \"auto\" && isWebContainer())) {\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 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 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 // typical path\n if (authIssuer) {\n const clientId = overrideAuthClient ?? \"HFtA247jp9iNs08NTLIB7JsNPMmRIyfi\";\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\n if (overrideAccessToken) {\n accessToken = overrideAccessToken;\n } else if (overrideAuthUsername && overrideAuthPassword) {\n accessToken = await performPasswordAuthentication(\n ctx,\n clientId,\n overrideAuthUsername,\n overrideAuthPassword,\n );\n } else {\n accessToken = await performDeviceAuthorization(\n ctx,\n authClient,\n open ?? true,\n vercel,\n vercelOverride,\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 const authorizeArgs: AuthorizeArgs = {\n authnToken: accessToken!,\n deviceName: deviceName,\n anonymousId: anonymousId,\n };\n const data = await bigBrainAPI({\n ctx,\n method: \"POST\",\n path: \"authorize\",\n data: authorizeArgs,\n });\n const globalConfig = { accessToken: data.accessToken };\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, data.accessToken);\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
+ "names": ["import_openid_client", "open", "fetch"]
7
7
  }
@@ -36,7 +36,7 @@ async function warn(ctx, options) {
36
36
  );
37
37
  }
38
38
  async function teamUsageState(ctx, teamId) {
39
- const { usageState } = await (0, import_utils.bigBrainAPI)({
39
+ const { usageState } = await (0, import_utils.bigBrainAPIMaybeThrows)({
40
40
  ctx,
41
41
  method: "GET",
42
42
  path: "dashboard/teams/" + teamId + "/usage/team_usage_state"
@@ -44,7 +44,7 @@ async function teamUsageState(ctx, teamId) {
44
44
  return usageState;
45
45
  }
46
46
  async function teamSpendingLimitsState(ctx, teamId) {
47
- const response = await (0, import_utils.bigBrainAPI)({
47
+ const response = await (0, import_utils.bigBrainAPIMaybeThrows)({
48
48
  ctx,
49
49
  method: "GET",
50
50
  path: "dashboard/teams/" + teamId + "/get_spending_limits"
@@ -57,10 +57,17 @@ async function usageStateWarning(ctx, targetDeployment) {
57
57
  return;
58
58
  }
59
59
  const { teamId, team } = await (0, import_api.fetchTeamAndProject)(ctx, targetDeployment);
60
- const [usageState, spendingLimitsState] = await Promise.all([
61
- teamUsageState(ctx, teamId),
62
- teamSpendingLimitsState(ctx, teamId)
63
- ]);
60
+ let usageState;
61
+ let spendingLimitsState;
62
+ try {
63
+ [usageState, spendingLimitsState] = await Promise.all([
64
+ teamUsageState(ctx, teamId),
65
+ teamSpendingLimitsState(ctx, teamId)
66
+ ]);
67
+ } catch (err) {
68
+ (0, import_log.logVerbose)("Skipping usage state warning:", err);
69
+ return;
70
+ }
64
71
  if (spendingLimitsState === "Disabled") {
65
72
  await warn(ctx, {
66
73
  title: "Your projects are disabled because you exceeded your spending limit.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/usage.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logWarning } from \"../../bundler/log.js\";\nimport { teamDashboardUrl } from \"./dashboard.js\";\nimport { fetchTeamAndProject } from \"./api.js\";\nimport { isAnonymousDeployment } from \"./deployment.js\";\nimport { bigBrainAPI } from \"./utils/utils.js\";\n\nasync function warn(\n ctx: Context,\n options: { title: string; subtitle: string; teamSlug: string },\n) {\n const { title, subtitle, teamSlug } = options;\n logWarning(chalkStderr.bold.yellow(title));\n logWarning(chalkStderr.yellow(subtitle));\n logWarning(\n chalkStderr.yellow(`Visit ${teamDashboardUrl(teamSlug)} to learn more.`),\n );\n}\n\nasync function teamUsageState(ctx: Context, teamId: number) {\n const { usageState } = (await bigBrainAPI({\n ctx,\n method: \"GET\",\n path: \"dashboard/teams/\" + teamId + \"/usage/team_usage_state\",\n })) as {\n usageState: \"Default\" | \"Approaching\" | \"Exceeded\" | \"Disabled\" | \"Paused\";\n };\n\n return usageState;\n}\n\nasync function teamSpendingLimitsState(ctx: Context, teamId: number) {\n const response = (await bigBrainAPI({\n ctx,\n method: \"GET\",\n path: \"dashboard/teams/\" + teamId + \"/get_spending_limits\",\n })) as {\n disableThresholdCents: number | null;\n state: null | \"Running\" | \"Disabled\" | \"Warning\";\n };\n\n return response.state;\n}\n\nexport async function usageStateWarning(\n ctx: Context,\n targetDeployment: string,\n) {\n // Skip the warning if the user doesn\u2019t have an auth token\n // (which can happen for instance when using a deploy key)\n const auth = ctx.bigBrainAuth();\n if (\n auth === null ||\n auth.kind === \"projectKey\" ||\n auth.kind === \"deploymentKey\" ||\n process.env.CONVEX_AGENT_MODE === \"anonymous\" ||\n isAnonymousDeployment(targetDeployment)\n ) {\n return;\n }\n const { teamId, team } = await fetchTeamAndProject(ctx, targetDeployment);\n\n const [usageState, spendingLimitsState] = await Promise.all([\n teamUsageState(ctx, teamId),\n teamSpendingLimitsState(ctx, teamId),\n ]);\n if (spendingLimitsState === \"Disabled\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because you exceeded your spending limit.\",\n subtitle: \"Increase it from the dashboard to re-enable your projects.\",\n teamSlug: team,\n });\n } else if (usageState === \"Approaching\") {\n await warn(ctx, {\n title: \"Your projects are approaching the Free plan limits.\",\n subtitle: \"Consider upgrading to avoid service interruption.\",\n teamSlug: team,\n });\n } else if (usageState === \"Exceeded\") {\n await warn(ctx, {\n title: \"Your projects are above the Free plan limits.\",\n subtitle: \"Decrease your usage or upgrade to avoid service interruption.\",\n teamSlug: team,\n });\n } else if (usageState === \"Disabled\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because the team exceeded Free plan limits.\",\n subtitle: \"Decrease your usage or upgrade to reenable your projects.\",\n teamSlug: team,\n });\n } else if (usageState === \"Paused\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because the team previously exceeded Free plan limits.\",\n subtitle: \"Restore your projects by going to the dashboard.\",\n teamSlug: team,\n });\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAE5B,iBAA2B;AAC3B,uBAAiC;AACjC,iBAAoC;AACpC,wBAAsC;AACtC,mBAA4B;AAE5B,eAAe,KACb,KACA,SACA;AACA,QAAM,EAAE,OAAO,UAAU,SAAS,IAAI;AACtC,6BAAW,yBAAY,KAAK,OAAO,KAAK,CAAC;AACzC,6BAAW,yBAAY,OAAO,QAAQ,CAAC;AACvC;AAAA,IACE,yBAAY,OAAO,aAAS,mCAAiB,QAAQ,CAAC,iBAAiB;AAAA,EACzE;AACF;AAEA,eAAe,eAAe,KAAc,QAAgB;AAC1D,QAAM,EAAE,WAAW,IAAK,UAAM,0BAAY;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,qBAAqB,SAAS;AAAA,EACtC,CAAC;AAID,SAAO;AACT;AAEA,eAAe,wBAAwB,KAAc,QAAgB;AACnE,QAAM,WAAY,UAAM,0BAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,qBAAqB,SAAS;AAAA,EACtC,CAAC;AAKD,SAAO,SAAS;AAClB;AAEA,eAAsB,kBACpB,KACA,kBACA;AAGA,QAAM,OAAO,IAAI,aAAa;AAC9B,MACE,SAAS,QACT,KAAK,SAAS,gBACd,KAAK,SAAS,mBACd,QAAQ,IAAI,sBAAsB,mBAClC,yCAAsB,gBAAgB,GACtC;AACA;AAAA,EACF;AACA,QAAM,EAAE,QAAQ,KAAK,IAAI,UAAM,gCAAoB,KAAK,gBAAgB;AAExE,QAAM,CAAC,YAAY,mBAAmB,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC1D,eAAe,KAAK,MAAM;AAAA,IAC1B,wBAAwB,KAAK,MAAM;AAAA,EACrC,CAAC;AACD,MAAI,wBAAwB,YAAY;AACtC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,eAAe;AACvC,UAAM,KAAK,KAAK;AAAA,MACd,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,YAAY;AACpC,UAAM,KAAK,KAAK;AAAA,MACd,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,YAAY;AACpC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,UAAU;AAClC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACF;",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logVerbose, logWarning } from \"../../bundler/log.js\";\nimport { teamDashboardUrl } from \"./dashboard.js\";\nimport { fetchTeamAndProject } from \"./api.js\";\nimport { isAnonymousDeployment } from \"./deployment.js\";\nimport { bigBrainAPIMaybeThrows } from \"./utils/utils.js\";\n\nasync function warn(\n ctx: Context,\n options: { title: string; subtitle: string; teamSlug: string },\n) {\n const { title, subtitle, teamSlug } = options;\n logWarning(chalkStderr.bold.yellow(title));\n logWarning(chalkStderr.yellow(subtitle));\n logWarning(\n chalkStderr.yellow(`Visit ${teamDashboardUrl(teamSlug)} to learn more.`),\n );\n}\n\nasync function teamUsageState(ctx: Context, teamId: number) {\n const { usageState } = (await bigBrainAPIMaybeThrows({\n ctx,\n method: \"GET\",\n path: \"dashboard/teams/\" + teamId + \"/usage/team_usage_state\",\n })) as {\n usageState: \"Default\" | \"Approaching\" | \"Exceeded\" | \"Disabled\" | \"Paused\";\n };\n\n return usageState;\n}\n\nasync function teamSpendingLimitsState(ctx: Context, teamId: number) {\n const response = (await bigBrainAPIMaybeThrows({\n ctx,\n method: \"GET\",\n path: \"dashboard/teams/\" + teamId + \"/get_spending_limits\",\n })) as {\n disableThresholdCents: number | null;\n state: null | \"Running\" | \"Disabled\" | \"Warning\";\n };\n\n return response.state;\n}\n\nexport async function usageStateWarning(\n ctx: Context,\n targetDeployment: string,\n) {\n // Skip the warning if the user doesn\u2019t have an auth token\n // (which can happen for instance when using a deploy key)\n const auth = ctx.bigBrainAuth();\n if (\n auth === null ||\n auth.kind === \"projectKey\" ||\n auth.kind === \"deploymentKey\" ||\n process.env.CONVEX_AGENT_MODE === \"anonymous\" ||\n isAnonymousDeployment(targetDeployment)\n ) {\n return;\n }\n\n const { teamId, team } = await fetchTeamAndProject(ctx, targetDeployment);\n\n let usageState: Awaited<ReturnType<typeof teamUsageState>>;\n let spendingLimitsState: Awaited<ReturnType<typeof teamSpendingLimitsState>>;\n try {\n [usageState, spendingLimitsState] = await Promise.all([\n teamUsageState(ctx, teamId),\n teamSpendingLimitsState(ctx, teamId),\n ]);\n } catch (err) {\n // Non-fatal: usage warnings are advisory, so don't block `convex dev`\n // if these endpoints error.\n logVerbose(\"Skipping usage state warning:\", err);\n return;\n }\n if (spendingLimitsState === \"Disabled\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because you exceeded your spending limit.\",\n subtitle: \"Increase it from the dashboard to re-enable your projects.\",\n teamSlug: team,\n });\n } else if (usageState === \"Approaching\") {\n await warn(ctx, {\n title: \"Your projects are approaching the Free plan limits.\",\n subtitle: \"Consider upgrading to avoid service interruption.\",\n teamSlug: team,\n });\n } else if (usageState === \"Exceeded\") {\n await warn(ctx, {\n title: \"Your projects are above the Free plan limits.\",\n subtitle: \"Decrease your usage or upgrade to avoid service interruption.\",\n teamSlug: team,\n });\n } else if (usageState === \"Disabled\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because the team exceeded Free plan limits.\",\n subtitle: \"Decrease your usage or upgrade to reenable your projects.\",\n teamSlug: team,\n });\n } else if (usageState === \"Paused\") {\n await warn(ctx, {\n title:\n \"Your projects are disabled because the team previously exceeded Free plan limits.\",\n subtitle: \"Restore your projects by going to the dashboard.\",\n teamSlug: team,\n });\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAE5B,iBAAuC;AACvC,uBAAiC;AACjC,iBAAoC;AACpC,wBAAsC;AACtC,mBAAuC;AAEvC,eAAe,KACb,KACA,SACA;AACA,QAAM,EAAE,OAAO,UAAU,SAAS,IAAI;AACtC,6BAAW,yBAAY,KAAK,OAAO,KAAK,CAAC;AACzC,6BAAW,yBAAY,OAAO,QAAQ,CAAC;AACvC;AAAA,IACE,yBAAY,OAAO,aAAS,mCAAiB,QAAQ,CAAC,iBAAiB;AAAA,EACzE;AACF;AAEA,eAAe,eAAe,KAAc,QAAgB;AAC1D,QAAM,EAAE,WAAW,IAAK,UAAM,qCAAuB;AAAA,IACnD;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,qBAAqB,SAAS;AAAA,EACtC,CAAC;AAID,SAAO;AACT;AAEA,eAAe,wBAAwB,KAAc,QAAgB;AACnE,QAAM,WAAY,UAAM,qCAAuB;AAAA,IAC7C;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,qBAAqB,SAAS;AAAA,EACtC,CAAC;AAKD,SAAO,SAAS;AAClB;AAEA,eAAsB,kBACpB,KACA,kBACA;AAGA,QAAM,OAAO,IAAI,aAAa;AAC9B,MACE,SAAS,QACT,KAAK,SAAS,gBACd,KAAK,SAAS,mBACd,QAAQ,IAAI,sBAAsB,mBAClC,yCAAsB,gBAAgB,GACtC;AACA;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,KAAK,IAAI,UAAM,gCAAoB,KAAK,gBAAgB;AAExE,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,KAAC,YAAY,mBAAmB,IAAI,MAAM,QAAQ,IAAI;AAAA,MACpD,eAAe,KAAK,MAAM;AAAA,MAC1B,wBAAwB,KAAK,MAAM;AAAA,IACrC,CAAC;AAAA,EACH,SAAS,KAAK;AAGZ,+BAAW,iCAAiC,GAAG;AAC/C;AAAA,EACF;AACA,MAAI,wBAAwB,YAAY;AACtC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,eAAe;AACvC,UAAM,KAAK,KAAK;AAAA,MACd,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,YAAY;AACpC,UAAM,KAAK,KAAK;AAAA,MACd,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,YAAY;AACpC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,WAAW,eAAe,UAAU;AAClC,UAAM,KAAK,KAAK;AAAA,MACd,OACE;AAAA,MACF,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACF;",
6
6
  "names": []
7
7
  }
@@ -36,13 +36,10 @@ async function createRedirectURI(ctx, apiKey, uri) {
36
36
  }
37
37
  );
38
38
  if (!response.ok) {
39
- if (response.status === 422) {
40
- const errorText2 = await response.text();
41
- if (errorText2.includes("already exists")) {
42
- return { modified: false };
43
- }
44
- }
45
39
  const errorText = await response.text();
40
+ if (response.status === 422 && errorText.includes("already exists")) {
41
+ return { modified: false };
42
+ }
46
43
  return await ctx.crash({
47
44
  exitCode: 1,
48
45
  errorType: "fatal",
@@ -89,13 +86,10 @@ async function createCORSOrigin(ctx, apiKey, origin) {
89
86
  }
90
87
  );
91
88
  if (!response.ok) {
92
- if (response.status === 409) {
93
- const errorText2 = await response.text();
94
- if (errorText2.includes("duplicate_cors_origin") || errorText2.includes("already exists")) {
95
- return { modified: false };
96
- }
97
- }
98
89
  const errorText = await response.text();
90
+ if (response.status === 409 && (errorText.includes("duplicate_cors_origin") || errorText.includes("already exists"))) {
91
+ return { modified: false };
92
+ }
99
93
  return await ctx.crash({
100
94
  exitCode: 1,
101
95
  errorType: "fatal",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/workos/environmentApi.ts"],
4
- "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\n\nexport interface RedirectUriResponse {\n object: \"redirect_uri\";\n id: string;\n uri: string;\n default: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CorsOriginResponse {\n object: \"cors_origin\";\n id: string;\n origin: string;\n created_at: string;\n updated_at: string;\n}\n\nexport async function createRedirectURI(\n ctx: Context,\n apiKey: string,\n uri: string,\n): Promise<{ modified: boolean }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/redirect_uris\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ uri }),\n },\n );\n\n if (!response.ok) {\n if (response.status === 422) {\n const errorText = await response.text();\n if (errorText.includes(\"already exists\")) {\n // This redirect URI already exists.\n return { modified: false };\n }\n }\n\n const errorText = await response.text();\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to create redirect URI: ${response.status} ${errorText}`,\n });\n }\n\n return { modified: true };\n}\n\nexport async function updateAppHomepageUrl(\n ctx: Context,\n apiKey: string,\n url: string,\n): Promise<{ modified: boolean; previousUrl?: string }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/app_homepage_url\",\n {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ url }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 422) {\n // Validation error - likely localhost URL or other invalid format\n // Don't crash, just return that we couldn't modify it\n return { modified: false };\n }\n\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to update app homepage URL: ${response.status} ${errorText}`,\n });\n }\n\n // Always returns modified: true since PUT always updates (or sets the same value)\n return { modified: true };\n}\n\nexport async function createCORSOrigin(\n ctx: Context,\n apiKey: string,\n origin: string,\n): Promise<{ modified: boolean }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/cors_origins\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ origin }),\n },\n );\n\n if (!response.ok) {\n if (response.status === 409) {\n const errorText = await response.text();\n if (\n errorText.includes(\"duplicate_cors_origin\") ||\n errorText.includes(\"already exists\")\n ) {\n // This CORS origin already exists.\n return { modified: false };\n }\n }\n\n const errorText = await response.text();\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to create CORS origin: ${response.status} ${errorText}`,\n });\n }\n return { modified: true };\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,eAAsB,kBACpB,KACA,QACA,KACgC;AAChC,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAMA,aAAY,MAAM,SAAS,KAAK;AACtC,UAAIA,WAAU,SAAS,gBAAgB,GAAG;AAExC,eAAO,EAAE,UAAU,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,kCAAkC,SAAS,MAAM,IAAI,SAAS;AAAA,IAChF,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,qBACpB,KACA,QACA,KACsD;AACtD,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AAEtC,QAAI,SAAS,WAAW,KAAK;AAG3B,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B;AAEA,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,sCAAsC,SAAS,MAAM,IAAI,SAAS;AAAA,IACpF,CAAC;AAAA,EACH;AAGA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,iBACpB,KACA,QACA,QACgC;AAChC,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAMA,aAAY,MAAM,SAAS,KAAK;AACtC,UACEA,WAAU,SAAS,uBAAuB,KAC1CA,WAAU,SAAS,gBAAgB,GACnC;AAEA,eAAO,EAAE,UAAU,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,iCAAiC,SAAS,MAAM,IAAI,SAAS;AAAA,IAC/E,CAAC;AAAA,EACH;AACA,SAAO,EAAE,UAAU,KAAK;AAC1B;",
6
- "names": ["errorText"]
4
+ "sourcesContent": ["import { Context } from \"../../../bundler/context.js\";\n\nexport interface RedirectUriResponse {\n object: \"redirect_uri\";\n id: string;\n uri: string;\n default: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CorsOriginResponse {\n object: \"cors_origin\";\n id: string;\n origin: string;\n created_at: string;\n updated_at: string;\n}\n\nexport async function createRedirectURI(\n ctx: Context,\n apiKey: string,\n uri: string,\n): Promise<{ modified: boolean }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/redirect_uris\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ uri }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 422 && errorText.includes(\"already exists\")) {\n // This redirect URI already exists.\n return { modified: false };\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to create redirect URI: ${response.status} ${errorText}`,\n });\n }\n\n return { modified: true };\n}\n\nexport async function updateAppHomepageUrl(\n ctx: Context,\n apiKey: string,\n url: string,\n): Promise<{ modified: boolean; previousUrl?: string }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/app_homepage_url\",\n {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ url }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 422) {\n // Validation error - likely localhost URL or other invalid format\n // Don't crash, just return that we couldn't modify it\n return { modified: false };\n }\n\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to update app homepage URL: ${response.status} ${errorText}`,\n });\n }\n\n // Always returns modified: true since PUT always updates (or sets the same value)\n return { modified: true };\n}\n\nexport async function createCORSOrigin(\n ctx: Context,\n apiKey: string,\n origin: string,\n): Promise<{ modified: boolean }> {\n const response = await fetch(\n \"https://api.workos.com/user_management/cors_origins\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ origin }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (\n response.status === 409 &&\n (errorText.includes(\"duplicate_cors_origin\") ||\n errorText.includes(\"already exists\"))\n ) {\n // This CORS origin already exists.\n return { modified: false };\n }\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Failed to create CORS origin: ${response.status} ${errorText}`,\n });\n }\n return { modified: true };\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,eAAsB,kBACpB,KACA,QACA,KACgC;AAChC,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,QAAI,SAAS,WAAW,OAAO,UAAU,SAAS,gBAAgB,GAAG;AAEnE,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B;AACA,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,kCAAkC,SAAS,MAAM,IAAI,SAAS;AAAA,IAChF,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,qBACpB,KACA,QACA,KACsD;AACtD,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AAEtC,QAAI,SAAS,WAAW,KAAK;AAG3B,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B;AAEA,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,sCAAsC,SAAS,MAAM,IAAI,SAAS;AAAA,IACpF,CAAC;AAAA,EACH;AAGA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,iBACpB,KACA,QACA,QACgC;AAChC,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,QACE,SAAS,WAAW,QACnB,UAAU,SAAS,uBAAuB,KACzC,UAAU,SAAS,gBAAgB,IACrC;AAEA,aAAO,EAAE,UAAU,MAAM;AAAA,IAC3B;AACA,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,iCAAiC,SAAS,MAAM,IAAI,SAAS;AAAA,IAC/E,CAAC;AAAA,EACH;AACA,SAAO,EAAE,UAAU,KAAK;AAC1B;",
6
+ "names": []
7
7
  }
package/dist/cjs/index.js CHANGED
@@ -21,5 +21,5 @@ __export(index_exports, {
21
21
  version: () => version
22
22
  });
23
23
  module.exports = __toCommonJS(index_exports);
24
- const version = "1.36.0";
24
+ const version = "1.37.0";
25
25
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export const version = \"1.36.0\";\n"],
4
+ "sourcesContent": ["export const version = \"1.37.0\";\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,UAAU;",
6
6
  "names": []
7
7
  }
@@ -37,7 +37,8 @@ __export(client_exports, {
37
37
  useConvex: () => useConvex,
38
38
  useConvexConnectionState: () => useConvexConnectionState,
39
39
  useMutation: () => useMutation,
40
- useQuery: () => useQuery
40
+ useQuery: () => useQuery,
41
+ useQuery_experimental: () => useQuery_experimental
41
42
  });
42
43
  module.exports = __toCommonJS(client_exports);
43
44
  var import_browser = require("../browser/index.js");
@@ -475,26 +476,33 @@ const ConvexProvider = ({ client, children }) => {
475
476
  children
476
477
  );
477
478
  };
478
- function useQuery(queryOrOptions, ...args) {
479
- const isObjectOptions = typeof queryOrOptions === "object" && queryOrOptions !== null && "query" in queryOrOptions;
480
- const throwOnError = isObjectOptions ? queryOrOptions.throwOnError ?? false : true;
481
- let queryReference;
482
- let argsObject = {};
483
- if (isObjectOptions) {
484
- const query = queryOrOptions.query;
485
- queryReference = typeof query === "string" ? (0, import_api.makeFunctionReference)(query) : query;
486
- if (queryOrOptions.args !== "skip") {
487
- argsObject = (0, import_common.parseArgs)(queryOrOptions.args);
488
- }
489
- } else {
490
- const query = queryOrOptions;
491
- queryReference = typeof query === "string" ? (0, import_api.makeFunctionReference)(query) : query;
492
- argsObject = args[0] === "skip" ? {} : (0, import_common.parseArgs)(args[0]);
479
+ function useQuery(query, ...args) {
480
+ const skip = args[0] === "skip";
481
+ const argsObject = args[0] === "skip" ? {} : (0, import_common.parseArgs)(args[0]);
482
+ const queryReference = typeof query === "string" ? (0, import_api.makeFunctionReference)(query) : query;
483
+ const queryName = (0, import_api.getFunctionName)(queryReference);
484
+ const queries = (0, import_react.useMemo)(
485
+ () => skip ? {} : { query: { query: queryReference, args: argsObject } },
486
+ // Stringify args so args that are semantically the same don't trigger a
487
+ // rerender. Saves developers from adding `useMemo` on every args usage.
488
+ // eslint-disable-next-line react-hooks/exhaustive-deps
489
+ [JSON.stringify((0, import_values.convexToJson)(argsObject)), queryName, skip]
490
+ );
491
+ const results = (0, import_use_queries.useQueries)(queries);
492
+ const result = results["query"];
493
+ if (result instanceof Error) {
494
+ throw result;
493
495
  }
494
- const queryName = queryReference ? (0, import_api.getFunctionName)(queryReference) : void 0;
495
- const skip = isObjectOptions && queryOrOptions.args === "skip" || !isObjectOptions && args[0] === "skip";
496
+ return result;
497
+ }
498
+ function useQuery_experimental(options) {
499
+ const throwOnError = options.throwOnError ?? false;
500
+ const queryReference = typeof options.query === "string" ? (0, import_api.makeFunctionReference)(options.query) : options.query;
501
+ const skip = options.args === "skip";
502
+ const argsObject = !skip ? (0, import_common.parseArgs)(options.args) : {};
503
+ const queryName = (0, import_api.getFunctionName)(queryReference);
496
504
  const queries = (0, import_react.useMemo)(
497
- () => skip || !queryReference ? {} : { query: { query: queryReference, args: argsObject } },
505
+ () => skip ? {} : { query: { query: queryReference, args: argsObject } },
498
506
  // Stringify args so args that are semantically the same don't trigger a
499
507
  // rerender. Saves developers from adding `useMemo` on every args usage.
500
508
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -502,34 +510,24 @@ function useQuery(queryOrOptions, ...args) {
502
510
  );
503
511
  const results = (0, import_use_queries.useQueries)(queries);
504
512
  const result = results["query"];
505
- if (isObjectOptions) {
506
- if (result instanceof Error) {
507
- if (throwOnError) {
508
- throw result;
509
- }
510
- return {
511
- data: void 0,
512
- error: result,
513
- status: "error"
514
- };
515
- }
516
- if (result === void 0) {
517
- return {
518
- data: void 0,
519
- error: void 0,
520
- status: "pending"
521
- };
513
+ if (result instanceof Error) {
514
+ if (throwOnError) {
515
+ throw result;
522
516
  }
523
517
  return {
524
- data: result,
525
- error: void 0,
526
- status: "success"
518
+ error: result,
519
+ status: "error"
527
520
  };
528
521
  }
529
- if (result instanceof Error) {
530
- throw result;
522
+ if (result === void 0) {
523
+ return {
524
+ status: "pending"
525
+ };
531
526
  }
532
- return result;
527
+ return {
528
+ data: result,
529
+ status: "success"
530
+ };
533
531
  }
534
532
  function useMutation(mutation) {
535
533
  const mutationReference = typeof mutation === "string" ? (0, import_api.makeFunctionReference)(mutation) : mutation;