convex 1.44.0 → 1.45.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 (594) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/cli/convexExport.js +1 -1
  5. package/dist/cjs/cli/convexExport.js.map +1 -1
  6. package/dist/cjs/cli/index.js +2 -32
  7. package/dist/cjs/cli/index.js.map +2 -2
  8. package/dist/cjs/cli/lib/api.js +11 -5
  9. package/dist/cjs/cli/lib/api.js.map +2 -2
  10. package/dist/cjs/cli/lib/convexExport.js +12 -1
  11. package/dist/cjs/cli/lib/convexExport.js.map +2 -2
  12. package/dist/cjs/cli/lib/dashboard.js.map +2 -2
  13. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  14. package/dist/cjs/cli/lib/indexes.js +1 -1
  15. package/dist/cjs/cli/lib/indexes.js.map +1 -1
  16. package/dist/cjs/cli/lib/localDeployment/upgrade.js +23 -188
  17. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +3 -3
  18. package/dist/cjs/cli/lib/mcp/tools/index.js.map +1 -1
  19. package/dist/cjs/cli/mcp.js +76 -69
  20. package/dist/cjs/cli/mcp.js.map +2 -2
  21. package/dist/cjs/index.js +1 -1
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  24. package/dist/cjs/server/index.js.map +2 -2
  25. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  26. package/dist/cjs-types/cli/lib/convexExport.d.ts +1 -0
  27. package/dist/cjs-types/cli/lib/convexExport.d.ts.map +1 -1
  28. package/dist/cjs-types/cli/lib/dashboard.d.ts.map +1 -1
  29. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  30. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  31. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts +2 -0
  32. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  33. package/dist/cjs-types/cli/lib/mcp/tools/index.d.ts +1 -1
  34. package/dist/cjs-types/cli/lib/mcp/tools/index.d.ts.map +1 -1
  35. package/dist/cjs-types/cli/mcp.d.ts +3 -0
  36. package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
  37. package/dist/cjs-types/index.d.ts +1 -1
  38. package/dist/cjs-types/server/impl/actions_impl.d.ts +14 -0
  39. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  40. package/dist/cjs-types/server/index.d.ts +1 -0
  41. package/dist/cjs-types/server/index.d.ts.map +1 -1
  42. package/dist/cli.bundle.cjs +31210 -25495
  43. package/dist/cli.bundle.cjs.map +4 -4
  44. package/dist/esm/cli/convexExport.js +1 -1
  45. package/dist/esm/cli/convexExport.js.map +1 -1
  46. package/dist/esm/cli/index.js +2 -32
  47. package/dist/esm/cli/index.js.map +2 -2
  48. package/dist/esm/cli/lib/api.js +11 -5
  49. package/dist/esm/cli/lib/api.js.map +2 -2
  50. package/dist/esm/cli/lib/convexExport.js +16 -3
  51. package/dist/esm/cli/lib/convexExport.js.map +2 -2
  52. package/dist/esm/cli/lib/dashboard.js.map +2 -2
  53. package/dist/esm/cli/lib/indexes.js +1 -1
  54. package/dist/esm/cli/lib/indexes.js.map +1 -1
  55. package/dist/esm/cli/lib/localDeployment/upgrade.js +22 -190
  56. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  57. package/dist/esm/cli/lib/mcp/tools/index.js.map +1 -1
  58. package/dist/esm/cli/mcp.js +75 -72
  59. package/dist/esm/cli/mcp.js.map +2 -2
  60. package/dist/esm/index.js +1 -1
  61. package/dist/esm/index.js.map +1 -1
  62. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  63. package/dist/esm/server/index.js.map +2 -2
  64. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  65. package/dist/esm-types/cli/lib/convexExport.d.ts +1 -0
  66. package/dist/esm-types/cli/lib/convexExport.d.ts.map +1 -1
  67. package/dist/esm-types/cli/lib/dashboard.d.ts.map +1 -1
  68. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  69. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  70. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts +2 -0
  71. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  72. package/dist/esm-types/cli/lib/mcp/tools/index.d.ts +1 -1
  73. package/dist/esm-types/cli/lib/mcp/tools/index.d.ts.map +1 -1
  74. package/dist/esm-types/cli/mcp.d.ts +3 -0
  75. package/dist/esm-types/cli/mcp.d.ts.map +1 -1
  76. package/dist/esm-types/index.d.ts +1 -1
  77. package/dist/esm-types/server/impl/actions_impl.d.ts +14 -0
  78. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  79. package/dist/esm-types/server/index.d.ts +1 -0
  80. package/dist/esm-types/server/index.d.ts.map +1 -1
  81. package/dist/react.bundle.js +1 -1
  82. package/dist/react.bundle.js.map +1 -1
  83. package/package.json +3 -3
  84. package/src/cli/convexExport.ts +1 -1
  85. package/src/cli/index.ts +2 -35
  86. package/src/cli/lib/api.ts +11 -5
  87. package/src/cli/lib/convexExport.ts +21 -0
  88. package/src/cli/lib/dashboard.ts +2 -0
  89. package/src/cli/lib/generatedFunctionLogsApi.ts +2 -0
  90. package/src/cli/lib/indexes.ts +1 -1
  91. package/src/cli/lib/localDeployment/upgrade.ts +34 -207
  92. package/src/cli/lib/mcp/tools/index.ts +1 -1
  93. package/src/cli/mcp.ts +91 -77
  94. package/src/index.ts +1 -1
  95. package/src/server/impl/actions_impl.ts +3 -1
  96. package/src/server/index.ts +0 -3
  97. package/dist/cjs-types/browser/http_client.test.d.ts +0 -2
  98. package/dist/cjs-types/browser/http_client.test.d.ts.map +0 -1
  99. package/dist/cjs-types/browser/query_options.test.d.ts +0 -2
  100. package/dist/cjs-types/browser/query_options.test.d.ts.map +0 -1
  101. package/dist/cjs-types/browser/simple_client.test.d.ts +0 -2
  102. package/dist/cjs-types/browser/simple_client.test.d.ts.map +0 -1
  103. package/dist/cjs-types/browser/sync/client.test.d.ts +0 -5
  104. package/dist/cjs-types/browser/sync/client.test.d.ts.map +0 -1
  105. package/dist/cjs-types/browser/sync/client_node.test.d.ts +0 -2
  106. package/dist/cjs-types/browser/sync/client_node.test.d.ts.map +0 -1
  107. package/dist/cjs-types/browser/sync/client_node_test_helpers.d.ts +0 -44
  108. package/dist/cjs-types/browser/sync/client_node_test_helpers.d.ts.map +0 -1
  109. package/dist/cjs-types/browser/sync/local_state.test.d.ts +0 -2
  110. package/dist/cjs-types/browser/sync/local_state.test.d.ts.map +0 -1
  111. package/dist/cjs-types/browser/sync/optimistic_query_set.test.d.ts +0 -2
  112. package/dist/cjs-types/browser/sync/optimistic_query_set.test.d.ts.map +0 -1
  113. package/dist/cjs-types/browser/sync/paginated_query_client.test.d.ts +0 -2
  114. package/dist/cjs-types/browser/sync/paginated_query_client.test.d.ts.map +0 -1
  115. package/dist/cjs-types/browser/sync/protocol.test.d.ts +0 -5
  116. package/dist/cjs-types/browser/sync/protocol.test.d.ts.map +0 -1
  117. package/dist/cjs-types/browser/sync/request_manager.test.d.ts +0 -2
  118. package/dist/cjs-types/browser/sync/request_manager.test.d.ts.map +0 -1
  119. package/dist/cjs-types/bundler/fs.test.d.ts +0 -2
  120. package/dist/cjs-types/bundler/fs.test.d.ts.map +0 -1
  121. package/dist/cjs-types/bundler/index.test.d.ts +0 -2
  122. package/dist/cjs-types/bundler/index.test.d.ts.map +0 -1
  123. package/dist/cjs-types/cli/codegen_templates/api.test.d.ts +0 -2
  124. package/dist/cjs-types/cli/codegen_templates/api.test.d.ts.map +0 -1
  125. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts +0 -2
  126. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts.map +0 -1
  127. package/dist/cjs-types/cli/codegen_templates/templates.test.d.ts +0 -2
  128. package/dist/cjs-types/cli/codegen_templates/templates.test.d.ts.map +0 -1
  129. package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts +0 -2
  130. package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts.map +0 -1
  131. package/dist/cjs-types/cli/configure.test.d.ts +0 -2
  132. package/dist/cjs-types/cli/configure.test.d.ts.map +0 -1
  133. package/dist/cjs-types/cli/deploymentCreate.test.d.ts +0 -2
  134. package/dist/cjs-types/cli/deploymentCreate.test.d.ts.map +0 -1
  135. package/dist/cjs-types/cli/deploymentSelect.test.d.ts +0 -2
  136. package/dist/cjs-types/cli/deploymentSelect.test.d.ts.map +0 -1
  137. package/dist/cjs-types/cli/deploymentSelection.test.d.ts +0 -2
  138. package/dist/cjs-types/cli/deploymentSelection.test.d.ts.map +0 -1
  139. package/dist/cjs-types/cli/deploymentToken.test.d.ts +0 -2
  140. package/dist/cjs-types/cli/deploymentToken.test.d.ts.map +0 -1
  141. package/dist/cjs-types/cli/dev.test.d.ts +0 -2
  142. package/dist/cjs-types/cli/dev.test.d.ts.map +0 -1
  143. package/dist/cjs-types/cli/envDefault.test.d.ts +0 -2
  144. package/dist/cjs-types/cli/envDefault.test.d.ts.map +0 -1
  145. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts +0 -2
  146. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +0 -1
  147. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts +0 -2
  148. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts.map +0 -1
  149. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +0 -2
  150. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +0 -1
  151. package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts +0 -2
  152. package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts.map +0 -1
  153. package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts +0 -2
  154. package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts.map +0 -1
  155. package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts +0 -2
  156. package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts.map +0 -1
  157. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +0 -2
  158. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +0 -1
  159. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +0 -2
  160. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +0 -1
  161. package/dist/cjs-types/cli/lib/codegen.test.d.ts +0 -2
  162. package/dist/cjs-types/cli/lib/codegen.test.d.ts.map +0 -1
  163. package/dist/cjs-types/cli/lib/components.test.d.ts +0 -2
  164. package/dist/cjs-types/cli/lib/components.test.d.ts.map +0 -1
  165. package/dist/cjs-types/cli/lib/config.test.d.ts +0 -2
  166. package/dist/cjs-types/cli/lib/config.test.d.ts.map +0 -1
  167. package/dist/cjs-types/cli/lib/deployment.test.d.ts +0 -2
  168. package/dist/cjs-types/cli/lib/deployment.test.d.ts.map +0 -1
  169. package/dist/cjs-types/cli/lib/deploymentSelector.test.d.ts +0 -2
  170. package/dist/cjs-types/cli/lib/deploymentSelector.test.d.ts.map +0 -1
  171. package/dist/cjs-types/cli/lib/env.test.d.ts +0 -2
  172. package/dist/cjs-types/cli/lib/env.test.d.ts.map +0 -1
  173. package/dist/cjs-types/cli/lib/expiration.test.d.ts +0 -2
  174. package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +0 -1
  175. package/dist/cjs-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts +0 -2
  176. package/dist/cjs-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts.map +0 -1
  177. package/dist/cjs-types/cli/lib/formatEnvValueForDotfile.test.d.ts +0 -2
  178. package/dist/cjs-types/cli/lib/formatEnvValueForDotfile.test.d.ts.map +0 -1
  179. package/dist/cjs-types/cli/lib/formatTargetedDeployment.test.d.ts +0 -2
  180. package/dist/cjs-types/cli/lib/formatTargetedDeployment.test.d.ts.map +0 -1
  181. package/dist/cjs-types/cli/lib/fsUtils.test.d.ts +0 -2
  182. package/dist/cjs-types/cli/lib/fsUtils.test.d.ts.map +0 -1
  183. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts +0 -2
  184. package/dist/cjs-types/cli/lib/generateDocs.test.d.ts.map +0 -1
  185. package/dist/cjs-types/cli/lib/indexes.test.d.ts +0 -2
  186. package/dist/cjs-types/cli/lib/indexes.test.d.ts.map +0 -1
  187. package/dist/cjs-types/cli/lib/localDeployment/run.test.d.ts +0 -2
  188. package/dist/cjs-types/cli/lib/localDeployment/run.test.d.ts.map +0 -1
  189. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts +0 -2
  190. package/dist/cjs-types/cli/lib/localDeployment/secrets.test.d.ts.map +0 -1
  191. package/dist/cjs-types/cli/lib/run.test.d.ts +0 -2
  192. package/dist/cjs-types/cli/lib/run.test.d.ts.map +0 -1
  193. package/dist/cjs-types/cli/lib/runTestFunction.test.d.ts +0 -2
  194. package/dist/cjs-types/cli/lib/runTestFunction.test.d.ts.map +0 -1
  195. package/dist/cjs-types/cli/lib/typecheck.test.d.ts +0 -2
  196. package/dist/cjs-types/cli/lib/typecheck.test.d.ts.map +0 -1
  197. package/dist/cjs-types/cli/lib/updates.test.d.ts +0 -2
  198. package/dist/cjs-types/cli/lib/updates.test.d.ts.map +0 -1
  199. package/dist/cjs-types/cli/lib/utils/hash.test.d.ts +0 -2
  200. package/dist/cjs-types/cli/lib/utils/hash.test.d.ts.map +0 -1
  201. package/dist/cjs-types/cli/lib/utils/utils.test.d.ts +0 -2
  202. package/dist/cjs-types/cli/lib/utils/utils.test.d.ts.map +0 -1
  203. package/dist/cjs-types/cli/lib/versionApi.test.d.ts +0 -2
  204. package/dist/cjs-types/cli/lib/versionApi.test.d.ts.map +0 -1
  205. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts +0 -2
  206. package/dist/cjs-types/cli/lib/workos/environmentApi.test.d.ts.map +0 -1
  207. package/dist/cjs-types/cli/lib/workos/workos.test.d.ts +0 -2
  208. package/dist/cjs-types/cli/lib/workos/workos.test.d.ts.map +0 -1
  209. package/dist/cjs-types/cli/login.test.d.ts +0 -2
  210. package/dist/cjs-types/cli/login.test.d.ts.map +0 -1
  211. package/dist/cjs-types/common/index.test.d.ts +0 -2
  212. package/dist/cjs-types/common/index.test.d.ts.map +0 -1
  213. package/dist/cjs-types/nextjs/nextjs.test.d.ts +0 -2
  214. package/dist/cjs-types/nextjs/nextjs.test.d.ts.map +0 -1
  215. package/dist/cjs-types/react/ConvexAuthState.test.d.ts +0 -2
  216. package/dist/cjs-types/react/ConvexAuthState.test.d.ts.map +0 -1
  217. package/dist/cjs-types/react/auth_helpers.test.d.ts +0 -2
  218. package/dist/cjs-types/react/auth_helpers.test.d.ts.map +0 -1
  219. package/dist/cjs-types/react/auth_websocket.test.d.ts +0 -2
  220. package/dist/cjs-types/react/auth_websocket.test.d.ts.map +0 -1
  221. package/dist/cjs-types/react/client.test.d.ts +0 -2
  222. package/dist/cjs-types/react/client.test.d.ts.map +0 -1
  223. package/dist/cjs-types/react/client_provided_base_client.test.d.ts +0 -2
  224. package/dist/cjs-types/react/client_provided_base_client.test.d.ts.map +0 -1
  225. package/dist/cjs-types/react/queries_observer.test.d.ts +0 -2
  226. package/dist/cjs-types/react/queries_observer.test.d.ts.map +0 -1
  227. package/dist/cjs-types/react/react_node.test.d.ts +0 -2
  228. package/dist/cjs-types/react/react_node.test.d.ts.map +0 -1
  229. package/dist/cjs-types/react/use_paginated_query.test.d.ts +0 -2
  230. package/dist/cjs-types/react/use_paginated_query.test.d.ts.map +0 -1
  231. package/dist/cjs-types/react/use_queries.test.d.ts +0 -5
  232. package/dist/cjs-types/react/use_queries.test.d.ts.map +0 -1
  233. package/dist/cjs-types/react/use_query.test.d.ts +0 -5
  234. package/dist/cjs-types/react/use_query.test.d.ts.map +0 -1
  235. package/dist/cjs-types/react/use_query_object_options.test.d.ts +0 -5
  236. package/dist/cjs-types/react/use_query_object_options.test.d.ts.map +0 -1
  237. package/dist/cjs-types/react/use_query_result.test.d.ts +0 -5
  238. package/dist/cjs-types/react/use_query_result.test.d.ts.map +0 -1
  239. package/dist/cjs-types/react-auth0/ConvexProviderWithAuth0.test.d.ts +0 -2
  240. package/dist/cjs-types/react-auth0/ConvexProviderWithAuth0.test.d.ts.map +0 -1
  241. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.test.d.ts +0 -2
  242. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.test.d.ts.map +0 -1
  243. package/dist/cjs-types/server/api.intersect.test.d.ts +0 -2
  244. package/dist/cjs-types/server/api.intersect.test.d.ts.map +0 -1
  245. package/dist/cjs-types/server/api.test.d.ts +0 -2
  246. package/dist/cjs-types/server/api.test.d.ts.map +0 -1
  247. package/dist/cjs-types/server/audit_logging.test.d.ts +0 -2
  248. package/dist/cjs-types/server/audit_logging.test.d.ts.map +0 -1
  249. package/dist/cjs-types/server/components/index.test.d.ts +0 -2
  250. package/dist/cjs-types/server/components/index.test.d.ts.map +0 -1
  251. package/dist/cjs-types/server/cron.test.d.ts +0 -2
  252. package/dist/cjs-types/server/cron.test.d.ts.map +0 -1
  253. package/dist/cjs-types/server/data_model.test.d.ts +0 -2
  254. package/dist/cjs-types/server/data_model.test.d.ts.map +0 -1
  255. package/dist/cjs-types/server/database.test.d.ts +0 -2
  256. package/dist/cjs-types/server/database.test.d.ts.map +0 -1
  257. package/dist/cjs-types/server/database_api.test.d.ts +0 -2
  258. package/dist/cjs-types/server/database_api.test.d.ts.map +0 -1
  259. package/dist/cjs-types/server/filter_builder.test.d.ts +0 -2
  260. package/dist/cjs-types/server/filter_builder.test.d.ts.map +0 -1
  261. package/dist/cjs-types/server/impl/actions_impl.test.d.ts +0 -2
  262. package/dist/cjs-types/server/impl/actions_impl.test.d.ts.map +0 -1
  263. package/dist/cjs-types/server/impl/filter_builder_impl.test.d.ts +0 -2
  264. package/dist/cjs-types/server/impl/filter_builder_impl.test.d.ts.map +0 -1
  265. package/dist/cjs-types/server/impl/query_impl.test.d.ts +0 -2
  266. package/dist/cjs-types/server/impl/query_impl.test.d.ts.map +0 -1
  267. package/dist/cjs-types/server/pagination.test.d.ts +0 -2
  268. package/dist/cjs-types/server/pagination.test.d.ts.map +0 -1
  269. package/dist/cjs-types/server/query.test.d.ts +0 -2
  270. package/dist/cjs-types/server/query.test.d.ts.map +0 -1
  271. package/dist/cjs-types/server/registration.test.d.ts +0 -2
  272. package/dist/cjs-types/server/registration.test.d.ts.map +0 -1
  273. package/dist/cjs-types/server/router.test.d.ts +0 -2
  274. package/dist/cjs-types/server/router.test.d.ts.map +0 -1
  275. package/dist/cjs-types/server/scheduler.test.d.ts +0 -2
  276. package/dist/cjs-types/server/scheduler.test.d.ts.map +0 -1
  277. package/dist/cjs-types/server/schema.test.d.ts +0 -2
  278. package/dist/cjs-types/server/schema.test.d.ts.map +0 -1
  279. package/dist/cjs-types/test/fake_watch.d.ts +0 -16
  280. package/dist/cjs-types/test/fake_watch.d.ts.map +0 -1
  281. package/dist/cjs-types/test/type_testing.d.ts +0 -9
  282. package/dist/cjs-types/test/type_testing.d.ts.map +0 -1
  283. package/dist/cjs-types/type_utils.test.d.ts +0 -2
  284. package/dist/cjs-types/type_utils.test.d.ts.map +0 -1
  285. package/dist/cjs-types/values/size.test.d.ts +0 -2
  286. package/dist/cjs-types/values/size.test.d.ts.map +0 -1
  287. package/dist/cjs-types/values/validator.test.d.ts +0 -2
  288. package/dist/cjs-types/values/validator.test.d.ts.map +0 -1
  289. package/dist/cjs-types/values/value.test.d.ts +0 -2
  290. package/dist/cjs-types/values/value.test.d.ts.map +0 -1
  291. package/dist/esm-types/browser/http_client.test.d.ts +0 -2
  292. package/dist/esm-types/browser/http_client.test.d.ts.map +0 -1
  293. package/dist/esm-types/browser/query_options.test.d.ts +0 -2
  294. package/dist/esm-types/browser/query_options.test.d.ts.map +0 -1
  295. package/dist/esm-types/browser/simple_client.test.d.ts +0 -2
  296. package/dist/esm-types/browser/simple_client.test.d.ts.map +0 -1
  297. package/dist/esm-types/browser/sync/client.test.d.ts +0 -5
  298. package/dist/esm-types/browser/sync/client.test.d.ts.map +0 -1
  299. package/dist/esm-types/browser/sync/client_node.test.d.ts +0 -2
  300. package/dist/esm-types/browser/sync/client_node.test.d.ts.map +0 -1
  301. package/dist/esm-types/browser/sync/client_node_test_helpers.d.ts +0 -44
  302. package/dist/esm-types/browser/sync/client_node_test_helpers.d.ts.map +0 -1
  303. package/dist/esm-types/browser/sync/local_state.test.d.ts +0 -2
  304. package/dist/esm-types/browser/sync/local_state.test.d.ts.map +0 -1
  305. package/dist/esm-types/browser/sync/optimistic_query_set.test.d.ts +0 -2
  306. package/dist/esm-types/browser/sync/optimistic_query_set.test.d.ts.map +0 -1
  307. package/dist/esm-types/browser/sync/paginated_query_client.test.d.ts +0 -2
  308. package/dist/esm-types/browser/sync/paginated_query_client.test.d.ts.map +0 -1
  309. package/dist/esm-types/browser/sync/protocol.test.d.ts +0 -5
  310. package/dist/esm-types/browser/sync/protocol.test.d.ts.map +0 -1
  311. package/dist/esm-types/browser/sync/request_manager.test.d.ts +0 -2
  312. package/dist/esm-types/browser/sync/request_manager.test.d.ts.map +0 -1
  313. package/dist/esm-types/bundler/fs.test.d.ts +0 -2
  314. package/dist/esm-types/bundler/fs.test.d.ts.map +0 -1
  315. package/dist/esm-types/bundler/index.test.d.ts +0 -2
  316. package/dist/esm-types/bundler/index.test.d.ts.map +0 -1
  317. package/dist/esm-types/cli/codegen_templates/api.test.d.ts +0 -2
  318. package/dist/esm-types/cli/codegen_templates/api.test.d.ts.map +0 -1
  319. package/dist/esm-types/cli/codegen_templates/common.test.d.ts +0 -2
  320. package/dist/esm-types/cli/codegen_templates/common.test.d.ts.map +0 -1
  321. package/dist/esm-types/cli/codegen_templates/templates.test.d.ts +0 -2
  322. package/dist/esm-types/cli/codegen_templates/templates.test.d.ts.map +0 -1
  323. package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts +0 -2
  324. package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts.map +0 -1
  325. package/dist/esm-types/cli/configure.test.d.ts +0 -2
  326. package/dist/esm-types/cli/configure.test.d.ts.map +0 -1
  327. package/dist/esm-types/cli/deploymentCreate.test.d.ts +0 -2
  328. package/dist/esm-types/cli/deploymentCreate.test.d.ts.map +0 -1
  329. package/dist/esm-types/cli/deploymentSelect.test.d.ts +0 -2
  330. package/dist/esm-types/cli/deploymentSelect.test.d.ts.map +0 -1
  331. package/dist/esm-types/cli/deploymentSelection.test.d.ts +0 -2
  332. package/dist/esm-types/cli/deploymentSelection.test.d.ts.map +0 -1
  333. package/dist/esm-types/cli/deploymentToken.test.d.ts +0 -2
  334. package/dist/esm-types/cli/deploymentToken.test.d.ts.map +0 -1
  335. package/dist/esm-types/cli/dev.test.d.ts +0 -2
  336. package/dist/esm-types/cli/dev.test.d.ts.map +0 -1
  337. package/dist/esm-types/cli/envDefault.test.d.ts +0 -2
  338. package/dist/esm-types/cli/envDefault.test.d.ts.map +0 -1
  339. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts +0 -2
  340. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +0 -1
  341. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts +0 -2
  342. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts.map +0 -1
  343. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +0 -2
  344. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +0 -1
  345. package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts +0 -2
  346. package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts.map +0 -1
  347. package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts +0 -2
  348. package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts.map +0 -1
  349. package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts +0 -2
  350. package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts.map +0 -1
  351. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +0 -2
  352. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +0 -1
  353. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +0 -2
  354. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +0 -1
  355. package/dist/esm-types/cli/lib/codegen.test.d.ts +0 -2
  356. package/dist/esm-types/cli/lib/codegen.test.d.ts.map +0 -1
  357. package/dist/esm-types/cli/lib/components.test.d.ts +0 -2
  358. package/dist/esm-types/cli/lib/components.test.d.ts.map +0 -1
  359. package/dist/esm-types/cli/lib/config.test.d.ts +0 -2
  360. package/dist/esm-types/cli/lib/config.test.d.ts.map +0 -1
  361. package/dist/esm-types/cli/lib/deployment.test.d.ts +0 -2
  362. package/dist/esm-types/cli/lib/deployment.test.d.ts.map +0 -1
  363. package/dist/esm-types/cli/lib/deploymentSelector.test.d.ts +0 -2
  364. package/dist/esm-types/cli/lib/deploymentSelector.test.d.ts.map +0 -1
  365. package/dist/esm-types/cli/lib/env.test.d.ts +0 -2
  366. package/dist/esm-types/cli/lib/env.test.d.ts.map +0 -1
  367. package/dist/esm-types/cli/lib/expiration.test.d.ts +0 -2
  368. package/dist/esm-types/cli/lib/expiration.test.d.ts.map +0 -1
  369. package/dist/esm-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts +0 -2
  370. package/dist/esm-types/cli/lib/extractDeploymentNameForWorkOS.test.d.ts.map +0 -1
  371. package/dist/esm-types/cli/lib/formatEnvValueForDotfile.test.d.ts +0 -2
  372. package/dist/esm-types/cli/lib/formatEnvValueForDotfile.test.d.ts.map +0 -1
  373. package/dist/esm-types/cli/lib/formatTargetedDeployment.test.d.ts +0 -2
  374. package/dist/esm-types/cli/lib/formatTargetedDeployment.test.d.ts.map +0 -1
  375. package/dist/esm-types/cli/lib/fsUtils.test.d.ts +0 -2
  376. package/dist/esm-types/cli/lib/fsUtils.test.d.ts.map +0 -1
  377. package/dist/esm-types/cli/lib/generateDocs.test.d.ts +0 -2
  378. package/dist/esm-types/cli/lib/generateDocs.test.d.ts.map +0 -1
  379. package/dist/esm-types/cli/lib/indexes.test.d.ts +0 -2
  380. package/dist/esm-types/cli/lib/indexes.test.d.ts.map +0 -1
  381. package/dist/esm-types/cli/lib/localDeployment/run.test.d.ts +0 -2
  382. package/dist/esm-types/cli/lib/localDeployment/run.test.d.ts.map +0 -1
  383. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts +0 -2
  384. package/dist/esm-types/cli/lib/localDeployment/secrets.test.d.ts.map +0 -1
  385. package/dist/esm-types/cli/lib/run.test.d.ts +0 -2
  386. package/dist/esm-types/cli/lib/run.test.d.ts.map +0 -1
  387. package/dist/esm-types/cli/lib/runTestFunction.test.d.ts +0 -2
  388. package/dist/esm-types/cli/lib/runTestFunction.test.d.ts.map +0 -1
  389. package/dist/esm-types/cli/lib/typecheck.test.d.ts +0 -2
  390. package/dist/esm-types/cli/lib/typecheck.test.d.ts.map +0 -1
  391. package/dist/esm-types/cli/lib/updates.test.d.ts +0 -2
  392. package/dist/esm-types/cli/lib/updates.test.d.ts.map +0 -1
  393. package/dist/esm-types/cli/lib/utils/hash.test.d.ts +0 -2
  394. package/dist/esm-types/cli/lib/utils/hash.test.d.ts.map +0 -1
  395. package/dist/esm-types/cli/lib/utils/utils.test.d.ts +0 -2
  396. package/dist/esm-types/cli/lib/utils/utils.test.d.ts.map +0 -1
  397. package/dist/esm-types/cli/lib/versionApi.test.d.ts +0 -2
  398. package/dist/esm-types/cli/lib/versionApi.test.d.ts.map +0 -1
  399. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts +0 -2
  400. package/dist/esm-types/cli/lib/workos/environmentApi.test.d.ts.map +0 -1
  401. package/dist/esm-types/cli/lib/workos/workos.test.d.ts +0 -2
  402. package/dist/esm-types/cli/lib/workos/workos.test.d.ts.map +0 -1
  403. package/dist/esm-types/cli/login.test.d.ts +0 -2
  404. package/dist/esm-types/cli/login.test.d.ts.map +0 -1
  405. package/dist/esm-types/common/index.test.d.ts +0 -2
  406. package/dist/esm-types/common/index.test.d.ts.map +0 -1
  407. package/dist/esm-types/nextjs/nextjs.test.d.ts +0 -2
  408. package/dist/esm-types/nextjs/nextjs.test.d.ts.map +0 -1
  409. package/dist/esm-types/react/ConvexAuthState.test.d.ts +0 -2
  410. package/dist/esm-types/react/ConvexAuthState.test.d.ts.map +0 -1
  411. package/dist/esm-types/react/auth_helpers.test.d.ts +0 -2
  412. package/dist/esm-types/react/auth_helpers.test.d.ts.map +0 -1
  413. package/dist/esm-types/react/auth_websocket.test.d.ts +0 -2
  414. package/dist/esm-types/react/auth_websocket.test.d.ts.map +0 -1
  415. package/dist/esm-types/react/client.test.d.ts +0 -2
  416. package/dist/esm-types/react/client.test.d.ts.map +0 -1
  417. package/dist/esm-types/react/client_provided_base_client.test.d.ts +0 -2
  418. package/dist/esm-types/react/client_provided_base_client.test.d.ts.map +0 -1
  419. package/dist/esm-types/react/queries_observer.test.d.ts +0 -2
  420. package/dist/esm-types/react/queries_observer.test.d.ts.map +0 -1
  421. package/dist/esm-types/react/react_node.test.d.ts +0 -2
  422. package/dist/esm-types/react/react_node.test.d.ts.map +0 -1
  423. package/dist/esm-types/react/use_paginated_query.test.d.ts +0 -2
  424. package/dist/esm-types/react/use_paginated_query.test.d.ts.map +0 -1
  425. package/dist/esm-types/react/use_queries.test.d.ts +0 -5
  426. package/dist/esm-types/react/use_queries.test.d.ts.map +0 -1
  427. package/dist/esm-types/react/use_query.test.d.ts +0 -5
  428. package/dist/esm-types/react/use_query.test.d.ts.map +0 -1
  429. package/dist/esm-types/react/use_query_object_options.test.d.ts +0 -5
  430. package/dist/esm-types/react/use_query_object_options.test.d.ts.map +0 -1
  431. package/dist/esm-types/react/use_query_result.test.d.ts +0 -5
  432. package/dist/esm-types/react/use_query_result.test.d.ts.map +0 -1
  433. package/dist/esm-types/react-auth0/ConvexProviderWithAuth0.test.d.ts +0 -2
  434. package/dist/esm-types/react-auth0/ConvexProviderWithAuth0.test.d.ts.map +0 -1
  435. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.test.d.ts +0 -2
  436. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.test.d.ts.map +0 -1
  437. package/dist/esm-types/server/api.intersect.test.d.ts +0 -2
  438. package/dist/esm-types/server/api.intersect.test.d.ts.map +0 -1
  439. package/dist/esm-types/server/api.test.d.ts +0 -2
  440. package/dist/esm-types/server/api.test.d.ts.map +0 -1
  441. package/dist/esm-types/server/audit_logging.test.d.ts +0 -2
  442. package/dist/esm-types/server/audit_logging.test.d.ts.map +0 -1
  443. package/dist/esm-types/server/components/index.test.d.ts +0 -2
  444. package/dist/esm-types/server/components/index.test.d.ts.map +0 -1
  445. package/dist/esm-types/server/cron.test.d.ts +0 -2
  446. package/dist/esm-types/server/cron.test.d.ts.map +0 -1
  447. package/dist/esm-types/server/data_model.test.d.ts +0 -2
  448. package/dist/esm-types/server/data_model.test.d.ts.map +0 -1
  449. package/dist/esm-types/server/database.test.d.ts +0 -2
  450. package/dist/esm-types/server/database.test.d.ts.map +0 -1
  451. package/dist/esm-types/server/database_api.test.d.ts +0 -2
  452. package/dist/esm-types/server/database_api.test.d.ts.map +0 -1
  453. package/dist/esm-types/server/filter_builder.test.d.ts +0 -2
  454. package/dist/esm-types/server/filter_builder.test.d.ts.map +0 -1
  455. package/dist/esm-types/server/impl/actions_impl.test.d.ts +0 -2
  456. package/dist/esm-types/server/impl/actions_impl.test.d.ts.map +0 -1
  457. package/dist/esm-types/server/impl/filter_builder_impl.test.d.ts +0 -2
  458. package/dist/esm-types/server/impl/filter_builder_impl.test.d.ts.map +0 -1
  459. package/dist/esm-types/server/impl/query_impl.test.d.ts +0 -2
  460. package/dist/esm-types/server/impl/query_impl.test.d.ts.map +0 -1
  461. package/dist/esm-types/server/pagination.test.d.ts +0 -2
  462. package/dist/esm-types/server/pagination.test.d.ts.map +0 -1
  463. package/dist/esm-types/server/query.test.d.ts +0 -2
  464. package/dist/esm-types/server/query.test.d.ts.map +0 -1
  465. package/dist/esm-types/server/registration.test.d.ts +0 -2
  466. package/dist/esm-types/server/registration.test.d.ts.map +0 -1
  467. package/dist/esm-types/server/router.test.d.ts +0 -2
  468. package/dist/esm-types/server/router.test.d.ts.map +0 -1
  469. package/dist/esm-types/server/scheduler.test.d.ts +0 -2
  470. package/dist/esm-types/server/scheduler.test.d.ts.map +0 -1
  471. package/dist/esm-types/server/schema.test.d.ts +0 -2
  472. package/dist/esm-types/server/schema.test.d.ts.map +0 -1
  473. package/dist/esm-types/test/fake_watch.d.ts +0 -16
  474. package/dist/esm-types/test/fake_watch.d.ts.map +0 -1
  475. package/dist/esm-types/test/type_testing.d.ts +0 -9
  476. package/dist/esm-types/test/type_testing.d.ts.map +0 -1
  477. package/dist/esm-types/type_utils.test.d.ts +0 -2
  478. package/dist/esm-types/type_utils.test.d.ts.map +0 -1
  479. package/dist/esm-types/values/size.test.d.ts +0 -2
  480. package/dist/esm-types/values/size.test.d.ts.map +0 -1
  481. package/dist/esm-types/values/validator.test.d.ts +0 -2
  482. package/dist/esm-types/values/validator.test.d.ts.map +0 -1
  483. package/dist/esm-types/values/value.test.d.ts +0 -2
  484. package/dist/esm-types/values/value.test.d.ts.map +0 -1
  485. package/src/browser/http_client.test.ts +0 -202
  486. package/src/browser/query_options.test.ts +0 -43
  487. package/src/browser/simple_client.test.ts +0 -104
  488. package/src/browser/sync/client.test.ts +0 -44
  489. package/src/browser/sync/client_node.test.ts +0 -1207
  490. package/src/browser/sync/client_node_test_helpers.ts +0 -200
  491. package/src/browser/sync/local_state.test.ts +0 -128
  492. package/src/browser/sync/optimistic_query_set.test.ts +0 -253
  493. package/src/browser/sync/paginated_query_client.test.ts +0 -597
  494. package/src/browser/sync/protocol.test.ts +0 -14
  495. package/src/browser/sync/request_manager.test.ts +0 -273
  496. package/src/bundler/fs.test.ts +0 -86
  497. package/src/bundler/index.test.ts +0 -210
  498. package/src/bundler/test_fixtures/js/project01/bar.js +0 -4
  499. package/src/bundler/test_fixtures/js/project01/file with spaces.js +0 -1
  500. package/src/bundler/test_fixtures/js/project01/foo.js +0 -9
  501. package/src/bundler/test_fixtures/js/project_with_https/https.js +0 -9
  502. package/src/bundler/test_fixtures/js/project_with_https_not_at_top_level/default.js +0 -3
  503. package/src/bundler/test_fixtures/js/project_with_https_not_at_top_level/more_code/https.js +0 -5
  504. package/src/bundler/test_fixtures/js/project_with_https_without_router/https.js +0 -1
  505. package/src/bundler/test_fixtures/js/project_with_node_shims/uses_node_shims.js +0 -4
  506. package/src/cli/codegen_templates/api.test.ts +0 -18
  507. package/src/cli/codegen_templates/common.test.ts +0 -52
  508. package/src/cli/codegen_templates/templates.test.ts +0 -16
  509. package/src/cli/codegen_templates/validator_helpers.test.ts +0 -31
  510. package/src/cli/configure.test.ts +0 -138
  511. package/src/cli/deploymentCreate.test.ts +0 -1376
  512. package/src/cli/deploymentSelect.test.ts +0 -1291
  513. package/src/cli/deploymentSelection.test.ts +0 -2546
  514. package/src/cli/deploymentToken.test.ts +0 -397
  515. package/src/cli/dev.test.ts +0 -157
  516. package/src/cli/envDefault.test.ts +0 -495
  517. package/src/cli/lib/__snapshots__/formatTargetedDeployment.test.ts.snap +0 -94
  518. package/src/cli/lib/aiFiles/agentsmd.test.ts +0 -133
  519. package/src/cli/lib/aiFiles/claudemd.test.ts +0 -92
  520. package/src/cli/lib/aiFiles/guidelinesmd.test.ts +0 -50
  521. package/src/cli/lib/aiFiles/index.test.ts +0 -986
  522. package/src/cli/lib/aiFiles/integration.test.ts +0 -692
  523. package/src/cli/lib/aiFiles/prompt.test.ts +0 -202
  524. package/src/cli/lib/aiFiles/state.test.ts +0 -305
  525. package/src/cli/lib/aiFiles/utils.test.ts +0 -50
  526. package/src/cli/lib/codegen.test.ts +0 -49
  527. package/src/cli/lib/components.test.ts +0 -227
  528. package/src/cli/lib/config.test.ts +0 -1026
  529. package/src/cli/lib/deployment.test.ts +0 -85
  530. package/src/cli/lib/deploymentSelector.test.ts +0 -107
  531. package/src/cli/lib/env.test.ts +0 -60
  532. package/src/cli/lib/expiration.test.ts +0 -159
  533. package/src/cli/lib/extractDeploymentNameForWorkOS.test.ts +0 -30
  534. package/src/cli/lib/formatEnvValueForDotfile.test.ts +0 -294
  535. package/src/cli/lib/formatTargetedDeployment.test.ts +0 -281
  536. package/src/cli/lib/fsUtils.test.ts +0 -67
  537. package/src/cli/lib/generateDocs.test.ts +0 -326
  538. package/src/cli/lib/indexes.test.ts +0 -77
  539. package/src/cli/lib/localDeployment/run.test.ts +0 -104
  540. package/src/cli/lib/localDeployment/secrets.test.ts +0 -53
  541. package/src/cli/lib/run.test.ts +0 -54
  542. package/src/cli/lib/runTestFunction.test.ts +0 -84
  543. package/src/cli/lib/typecheck.test.ts +0 -71
  544. package/src/cli/lib/updates.test.ts +0 -157
  545. package/src/cli/lib/utils/hash.test.ts +0 -25
  546. package/src/cli/lib/utils/utils.test.ts +0 -340
  547. package/src/cli/lib/versionApi.test.ts +0 -471
  548. package/src/cli/lib/workos/environmentApi.test.ts +0 -107
  549. package/src/cli/lib/workos/workos.test.ts +0 -242
  550. package/src/cli/login.test.ts +0 -261
  551. package/src/common/README.md +0 -2
  552. package/src/common/index.test.ts +0 -35
  553. package/src/nextjs/nextjs.test.tsx +0 -94
  554. package/src/react/ConvexAuthState.test.tsx +0 -702
  555. package/src/react/auth_helpers.test.tsx +0 -45
  556. package/src/react/auth_websocket.test.tsx +0 -1177
  557. package/src/react/client.test.tsx +0 -261
  558. package/src/react/client_provided_base_client.test.tsx +0 -174
  559. package/src/react/queries_observer.test.ts +0 -176
  560. package/src/react/react_node.test.ts +0 -78
  561. package/src/react/use_paginated_query.test.tsx +0 -1420
  562. package/src/react/use_queries.test.ts +0 -140
  563. package/src/react/use_query.test.ts +0 -71
  564. package/src/react/use_query_object_options.test.ts +0 -51
  565. package/src/react/use_query_result.test.ts +0 -75
  566. package/src/react-auth0/ConvexProviderWithAuth0.test.tsx +0 -17
  567. package/src/react-clerk/ConvexProviderWithClerk.test.tsx +0 -18
  568. package/src/server/README.md +0 -15
  569. package/src/server/api.intersect.test.ts +0 -109
  570. package/src/server/api.test.ts +0 -447
  571. package/src/server/audit_logging.test.ts +0 -131
  572. package/src/server/components/index.test.ts +0 -48
  573. package/src/server/cron.test.ts +0 -58
  574. package/src/server/data_model.test.ts +0 -221
  575. package/src/server/database.test.ts +0 -184
  576. package/src/server/database_api.test.ts +0 -439
  577. package/src/server/filter_builder.test.ts +0 -102
  578. package/src/server/impl/actions_impl.test.ts +0 -59
  579. package/src/server/impl/filter_builder_impl.test.ts +0 -13
  580. package/src/server/impl/query_impl.test.ts +0 -46
  581. package/src/server/pagination.test.ts +0 -49
  582. package/src/server/query.test.ts +0 -112
  583. package/src/server/registration.test.ts +0 -589
  584. package/src/server/router.test.ts +0 -148
  585. package/src/server/scheduler.test.ts +0 -31
  586. package/src/server/schema.test.ts +0 -1081
  587. package/src/test/fake_watch.ts +0 -54
  588. package/src/test/type_testing.ts +0 -21
  589. package/src/type_utils.test.ts +0 -62
  590. package/src/values/size.test.ts +0 -95
  591. package/src/values/validator.test.ts +0 -619
  592. package/src/values/value.test.ts +0 -232
  593. package/src/vendor/README.md +0 -18
  594. package/src/vendor/jwt-decode/README.md +0 -1
@@ -1,1177 +0,0 @@
1
- /**
2
- * @vitest-environment custom-vitest-environment.ts
3
- */
4
- import { expect, vi, test, describe } from "vitest";
5
- import { jwtEncode } from "../vendor/jwt-encode/index.js";
6
- import {
7
- nodeWebSocket,
8
- withInMemoryWebSocket,
9
- } from "../browser/sync/client_node_test_helpers.js";
10
- import { ConvexReactClient, ConvexReactClientOptions } from "./index.js";
11
- import { BaseConvexClient } from "../browser/index.js";
12
- import waitForExpect from "wait-for-expect";
13
- import { anyApi } from "../server/index.js";
14
- import { Long } from "../vendor/long.js";
15
- import {
16
- AuthError,
17
- ClientMessage,
18
- WireServerMessage,
19
- } from "../browser/sync/protocol.js";
20
-
21
- const testReactClient = (
22
- address: string,
23
- options?: ConvexReactClientOptions,
24
- ) => {
25
- const client = new ConvexReactClient(address, {
26
- webSocketConstructor: nodeWebSocket,
27
- unsavedChangesWarning: false,
28
- ...options,
29
- });
30
- const baseClient = client.sync;
31
- if (!(baseClient instanceof BaseConvexClient)) {
32
- throw new Error("Expected `sync` to be a `BaseConvexClient`");
33
- }
34
- return { client, baseClient };
35
- };
36
-
37
- // Disabled due to flakes in CI
38
- // https://linear.app/convex/issue/ENG-7052/re-enable-auth-websocket-client-tests
39
-
40
- // On Linux these can retry forever due to EADDRINUSE so run then sequentially.
41
- describe.sequential.skip("auth websocket tests", () => {
42
- // This is the path usually taken on page load after a user logged in,
43
- // with a constant token provider.
44
- test("Authenticate via valid static token", async () => {
45
- await withInMemoryWebSocket(async ({ address, receive, send }) => {
46
- const { client, baseClient } = testReactClient(address);
47
-
48
- const tokenFetcher = vi.fn(async () =>
49
- jwtEncode({ iat: 1234500, exp: 1244500 }, "secret"),
50
- );
51
- const onAuthChange = vi.fn();
52
- client.setAuth(tokenFetcher, onAuthChange);
53
-
54
- expect((await receive()).type).toEqual("Connect");
55
- expect((await receive()).type).toEqual("Authenticate");
56
- expect((await receive()).type).toEqual("ModifyQuerySet");
57
-
58
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
59
-
60
- send({
61
- type: "Transition",
62
- startVersion: querySetVersion,
63
- endVersion: {
64
- ...querySetVersion,
65
- // Client started at 0
66
- // Good token advanced to 1
67
- identity: 1,
68
- },
69
- modifications: [],
70
- });
71
-
72
- await waitForExpect(() => {
73
- expect(onAuthChange).toHaveBeenCalledTimes(1);
74
- });
75
- await client.close();
76
-
77
- expect(tokenFetcher).toHaveBeenCalledWith({ forceRefreshToken: false });
78
- expect(onAuthChange).toHaveBeenCalledTimes(1);
79
- expect(onAuthChange).toHaveBeenCalledWith(true);
80
- });
81
- });
82
-
83
- // This happens when a user opens a page after their cached token expired
84
- test("Reauthenticate after token expiration with versioning", async () => {
85
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
86
- const { client, baseClient } = testReactClient(address);
87
-
88
- let token = jwtEncode({ iat: 1234500, exp: 1244500 }, "wobabloobla");
89
- const fetchToken = async () => token;
90
- const tokenFetcher = vi.fn(fetchToken);
91
- const onAuthChange = vi.fn();
92
- client.setAuth(tokenFetcher, onAuthChange);
93
-
94
- await assertReconnectWithAuth(receive, {
95
- baseVersion: 0,
96
- token: token,
97
- });
98
-
99
- // Token must change, otherwise client will not try to reauthenticate
100
- token = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret");
101
-
102
- await simulateAuthError({
103
- send,
104
- close,
105
- authError: {
106
- type: "AuthError",
107
- error: "bla",
108
- baseVersion: 0,
109
- authUpdateAttempted: true,
110
- },
111
- });
112
-
113
- // The client reconnects automatically
114
- await assertReconnectWithAuth(receive, {
115
- baseVersion: 0,
116
- token: token,
117
- });
118
-
119
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
120
-
121
- // Server accepts new token
122
- send({
123
- type: "Transition",
124
- startVersion: querySetVersion,
125
- endVersion: {
126
- ...querySetVersion,
127
- identity: 1,
128
- },
129
- modifications: [],
130
- });
131
-
132
- await waitForExpect(() => {
133
- expect(onAuthChange).toHaveBeenCalledTimes(1);
134
- });
135
- await client.close();
136
-
137
- expect(tokenFetcher).toHaveBeenNthCalledWith(1, {
138
- forceRefreshToken: false,
139
- });
140
- expect(tokenFetcher).toHaveBeenNthCalledWith(2, {
141
- forceRefreshToken: true,
142
- });
143
- expect(onAuthChange).toHaveBeenCalledWith(true);
144
- });
145
- });
146
-
147
- // This happens when a user opens a page and they cannot
148
- // fetch from a cache (say due to Prevent Cross Site tracking)
149
- test("Reauthenticate after token cache failure", async () => {
150
- await withInMemoryWebSocket(async ({ address, receive, send }) => {
151
- const { client, baseClient } = testReactClient(address);
152
-
153
- const freshToken = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret");
154
- const tokenFetcher = vi.fn(
155
- async (args: { forceRefreshToken: boolean }) => {
156
- if (args.forceRefreshToken) {
157
- return freshToken;
158
- }
159
- return null;
160
- },
161
- );
162
- const onAuthChange = vi.fn();
163
- void client.setAuth(tokenFetcher, onAuthChange);
164
-
165
- // The client authenticates after the token refetch
166
- await assertReconnectWithAuth(receive, {
167
- baseVersion: 0,
168
- token: freshToken,
169
- });
170
-
171
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
172
-
173
- // Server accepts new token
174
- send({
175
- type: "Transition",
176
- startVersion: querySetVersion,
177
- endVersion: {
178
- ...querySetVersion,
179
- identity: 1,
180
- },
181
- modifications: [],
182
- });
183
-
184
- await waitForExpect(() => {
185
- expect(onAuthChange).toHaveBeenCalledTimes(1);
186
- });
187
- await client.close();
188
-
189
- expect(tokenFetcher).toHaveBeenNthCalledWith(1, {
190
- forceRefreshToken: false,
191
- });
192
- expect(tokenFetcher).toHaveBeenNthCalledWith(2, {
193
- forceRefreshToken: true,
194
- });
195
- expect(onAuthChange).toHaveBeenCalledWith(true);
196
- });
197
- });
198
-
199
- // This is usually a misconfigured server rejecting any token
200
- test("Fail when tokens are always rejected", async () => {
201
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
202
- const { client } = testReactClient(address);
203
-
204
- const consoleSpy = vi
205
- .spyOn(global.console, "error")
206
- .mockImplementation(() => {
207
- // Do nothing
208
- });
209
-
210
- const token1 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret1");
211
- const token2 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret2");
212
- const token3 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret3");
213
- const token4 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret4");
214
-
215
- const tokens = [token1, token2, token3, token4];
216
-
217
- const tokenFetcher = vi.fn(async () => tokens.shift());
218
- const onAuthChange = vi.fn();
219
- client.setAuth(tokenFetcher, onAuthChange);
220
-
221
- expect((await receive()).type).toEqual("Connect");
222
- assertAuthenticateMessage(await receive(), {
223
- baseVersion: 0,
224
- token: token1,
225
- });
226
- expect((await receive()).type).toEqual("ModifyQuerySet");
227
-
228
- send({
229
- type: "AuthError",
230
- error: "bla",
231
- baseVersion: 0,
232
- authUpdateAttempted: true,
233
- });
234
- close();
235
-
236
- // The client reconnects automatically and retries twice
237
- expect((await receive()).type).toEqual("Connect");
238
- assertAuthenticateMessage(await receive(), {
239
- baseVersion: 0,
240
- token: token2,
241
- });
242
- expect((await receive()).type).toEqual("ModifyQuerySet");
243
-
244
- const AUTH_ERROR_MESSAGE = "bada boom";
245
- send({
246
- type: "AuthError",
247
- error: AUTH_ERROR_MESSAGE,
248
- baseVersion: 0,
249
- authUpdateAttempted: true,
250
- });
251
- close();
252
-
253
- expect((await receive()).type).toEqual("Connect");
254
- assertAuthenticateMessage(await receive(), {
255
- baseVersion: 0,
256
- token: token3,
257
- });
258
- expect((await receive()).type).toEqual("ModifyQuerySet");
259
-
260
- send({
261
- type: "AuthError",
262
- error: AUTH_ERROR_MESSAGE,
263
- baseVersion: 0,
264
- authUpdateAttempted: true,
265
- });
266
- close();
267
-
268
- expect((await receive()).type).toEqual("Connect");
269
- assertAuthenticateMessage(await receive(), {
270
- baseVersion: 0,
271
- token: token4,
272
- });
273
- expect((await receive()).type).toEqual("ModifyQuerySet");
274
-
275
- send({
276
- type: "AuthError",
277
- error: AUTH_ERROR_MESSAGE,
278
- baseVersion: 0,
279
- authUpdateAttempted: true,
280
- });
281
- close();
282
-
283
- // The client reconnects automatically (but without auth)
284
- expect((await receive()).type).toEqual("Connect");
285
- expect((await receive()).type).toEqual("ModifyQuerySet");
286
- await client.close();
287
-
288
- expect(onAuthChange).toHaveBeenCalledTimes(1);
289
- expect(onAuthChange).toHaveBeenCalledWith(false);
290
- expect(consoleSpy).toHaveBeenCalledWith(
291
- `Failed to authenticate: "${AUTH_ERROR_MESSAGE}", check your server auth config`,
292
- );
293
- });
294
- });
295
-
296
- // This happens when "refresh token"s expired - auth provider client thinks
297
- // it's authed but it cannot fetch a token at all.
298
- test("Fail when tokens cannot be fetched", async () => {
299
- await withInMemoryWebSocket(async ({ address, receive }) => {
300
- const { client } = testReactClient(address);
301
- const tokenFetcher = vi.fn(async () => null);
302
- const onAuthChange = vi.fn();
303
- void client.setAuth(tokenFetcher, onAuthChange);
304
-
305
- expect((await receive()).type).toEqual("Connect");
306
- expect((await receive()).type).toEqual("ModifyQuerySet");
307
-
308
- await waitForExpect(() => {
309
- expect(onAuthChange).toHaveBeenCalledTimes(1);
310
- });
311
- await client.close();
312
-
313
- expect(onAuthChange).toHaveBeenCalledTimes(1);
314
- expect(onAuthChange).toHaveBeenCalledWith(false);
315
- });
316
- });
317
-
318
- test("Client is protected against token rejection race", async () => {
319
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
320
- const { client, baseClient } = testReactClient(address);
321
-
322
- const badToken = jwtEncode({ iat: 1234500, exp: 1244500 }, "wobalooba");
323
- const badTokenFetcher = vi.fn(async () => badToken);
324
- const firstOnChange = vi.fn();
325
- client.setAuth(badTokenFetcher, firstOnChange);
326
-
327
- await assertReconnectWithAuth(receive, {
328
- baseVersion: 0,
329
- token: badToken,
330
- });
331
-
332
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
333
-
334
- const goodToken = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret");
335
- const goodTokenFetcher = vi.fn(async () => goodToken);
336
-
337
- const secondOnChange = vi.fn();
338
- client.setAuth(goodTokenFetcher, secondOnChange);
339
-
340
- assertAuthenticateMessage(await receive(), {
341
- baseVersion: 1,
342
- token: goodToken,
343
- });
344
-
345
- // This is the current server AuthError sequence:
346
- // send a message and close the connection.
347
- await simulateAuthError({
348
- send,
349
- close,
350
- authError: {
351
- type: "AuthError",
352
- error: "bla",
353
- baseVersion: 0,
354
- authUpdateAttempted: true,
355
- },
356
- });
357
-
358
- await assertReconnectWithAuth(receive, {
359
- baseVersion: 0,
360
- token: goodToken,
361
- });
362
-
363
- send({
364
- type: "Transition",
365
- startVersion: {
366
- ...querySetVersion,
367
- // Client started at 0 after reconnect
368
- identity: 0,
369
- },
370
- endVersion: {
371
- ...querySetVersion,
372
- // Good token advanced to 1
373
- identity: 1,
374
- },
375
- modifications: [],
376
- });
377
-
378
- await waitForExpect(() => {
379
- expect(secondOnChange).toHaveBeenCalledTimes(1);
380
- });
381
- await client.close();
382
-
383
- expect(firstOnChange).toHaveBeenCalledTimes(0);
384
- expect(secondOnChange).toHaveBeenCalledWith(true);
385
- });
386
- });
387
-
388
- // This is a race condition where a delayed auth error from a non-auth message
389
- // comes back while the client is waiting for server validation of the new token.
390
- test("Client ignores non-auth responses for token validation", async () => {
391
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
392
- const { client, baseClient } = testReactClient(address);
393
- const ts = Math.ceil(Date.now() / 1000);
394
- const initialToken = jwtEncode({ iat: ts, exp: ts + 1000 }, "token1");
395
- const freshToken = jwtEncode({ iat: ts, exp: ts + 1000 }, "token2");
396
- const tokens = [initialToken, freshToken];
397
- const tokenFetcher = vi.fn(async (_opts) => tokens.shift()!);
398
- const onChange = vi.fn();
399
- // This will immediately send the `initialToken` to the server (treating it as
400
- // a token cached in local storage / other memory), and then asynchronously
401
- // fetch `freshToken`, as a "fresh" token, and send that in a future `Authenticate`
402
- // message.
403
- client.setAuth(tokenFetcher, onChange);
404
-
405
- // Messages for initial connection + handling `initialToken`
406
- await assertReconnectWithAuth(receive, {
407
- baseVersion: 0,
408
- token: initialToken,
409
- });
410
-
411
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
412
-
413
- send({
414
- type: "Transition",
415
- startVersion: {
416
- ...querySetVersion,
417
- identity: 0,
418
- },
419
- endVersion: {
420
- ...querySetVersion,
421
- identity: 1,
422
- },
423
- modifications: [],
424
- });
425
-
426
- // Message from the client containing `freshToken`
427
- assertAuthenticateMessage(await receive(), {
428
- baseVersion: 1,
429
- token: freshToken,
430
- });
431
-
432
- // The client's sync state should still be on version 1, because we haven't transitioned
433
- // to the new token yet. But the AuthenticationManager should be in the state `waitingForServerConfirmationOfFreshToken`
434
-
435
- // The server may send an auth error for version 1 before it has processed the
436
- // `Authenticate` message for version 2.
437
-
438
- // One way this can happen is a query re-executing (i.e. because the data changed) and noticing
439
- // that the current auth has expired. This should have `authUpdateAttempted: false` because
440
- // the server has not yet processed the `Authenticate` message for version 2.
441
- await simulateAuthError({
442
- send,
443
- close,
444
- authError: {
445
- type: "AuthError",
446
- error: "bla",
447
- baseVersion: 1,
448
- authUpdateAttempted: false,
449
- },
450
- });
451
-
452
- // However, on the next reconnect, it should send `freshToken` to complete the token exchange.
453
- await assertReconnectWithAuth(receive, {
454
- baseVersion: 0,
455
- token: freshToken,
456
- });
457
-
458
- const querySetVersion2 = baseClient["remoteQuerySet"]["version"];
459
-
460
- send({
461
- type: "Transition",
462
- startVersion: {
463
- ...querySetVersion2,
464
- identity: 0,
465
- },
466
- endVersion: {
467
- ...querySetVersion2,
468
- identity: 1,
469
- },
470
- modifications: [],
471
- });
472
-
473
- // Flush
474
- await new Promise((resolve) => setTimeout(resolve));
475
- await client.close();
476
-
477
- expect(onChange).toHaveBeenCalledTimes(2);
478
- expect(onChange).toHaveBeenNthCalledWith(1, true);
479
- // Without proper handling, this second call will be false
480
- expect(onChange).toHaveBeenNthCalledWith(2, true);
481
- }, true);
482
- });
483
-
484
- // This is a race condition where a connection stopped by reauthentication
485
- // never restarts due to reauthentication exiting early. This happens when
486
- // an additional refetch begins while reauthentication is still running,
487
- // such as with a scheduled refetch.
488
- test("Client maintains connection when refetch occurs during reauth attempt", async () => {
489
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
490
- vi.useFakeTimers();
491
- const { client, baseClient } = testReactClient(address);
492
- // In this test we're going to simulate `fetchToken` taking a long time (1s)
493
- // so we can test race conditions, so the issued time will be 1s after the
494
- // fetched time.
495
-
496
- // Tokens in this test will expire 3s after they are issued, and we're relying
497
- // on the default 2s refresh leeway which means the scheduled refetch will
498
- // start 1s after the token is issued.
499
-
500
- const nowInSeconds = Math.ceil(Date.now() / 1000);
501
- // existing token, the times shouldn't matter since we immediately fetch a fresh token
502
- const initialToken = jwtEncode(
503
- { iat: nowInSeconds - 10, exp: nowInSeconds + 10 },
504
- "initialToken",
505
- );
506
- // fresh token, fetched at ts=1
507
- const freshToken = jwtEncode(
508
- { iat: nowInSeconds + 1, exp: nowInSeconds + 4 },
509
- "freshToken",
510
- );
511
- // scheduled refetch at ts=2 (2s before freshToken expires), but with a 1s delay
512
- const scheduledRefetchToken = jwtEncode(
513
- { iat: nowInSeconds + 3, exp: nowInSeconds + 6 },
514
- "scheduledRefetchToken",
515
- );
516
- // fetched at ts 1.5 in response to an auth error, issued at ts=2.5
517
- const reauthToken = jwtEncode(
518
- { iat: nowInSeconds + 2.5, exp: nowInSeconds + 5.5 },
519
- "reauthToken",
520
- );
521
- const tokens = [
522
- initialToken,
523
- freshToken,
524
- reauthToken,
525
- scheduledRefetchToken,
526
- ];
527
- const tokenFetcher = vi.fn(
528
- async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => {
529
- const token = tokens.shift();
530
- if (forceRefreshToken === false) {
531
- if (token !== initialToken) {
532
- throw new Error(
533
- "scheduledRefetchToken should be fetched with forceRefreshToken=true",
534
- );
535
- }
536
- return token;
537
- }
538
-
539
- vi.advanceTimersByTime(1000);
540
- return token;
541
- },
542
- );
543
- const onChange = vi.fn((isAuthenticated: boolean) => {
544
- if (!isAuthenticated) {
545
- throw new Error("Client is unexpectedly unauthenticated");
546
- }
547
- });
548
- client.setAuth(tokenFetcher, onChange);
549
-
550
- // Initial connection, sending `initialToken`
551
- // ts=0
552
- await assertReconnectWithAuth(receive, {
553
- baseVersion: 0,
554
- token: initialToken,
555
- });
556
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
557
-
558
- send({
559
- type: "Transition",
560
- startVersion: {
561
- ...querySetVersion,
562
- identity: 0,
563
- },
564
- endVersion: {
565
- ...querySetVersion,
566
- identity: 1,
567
- },
568
- modifications: [],
569
- });
570
-
571
- // Immediately fetch a a fresh token (`freshToken`).
572
- // `freshToken` expires at ts=4
573
- // We will also schedule a refetch at ts=2 (2s before `freshToken` expires)
574
- assertAuthenticateMessage(await receive(), {
575
- baseVersion: 1,
576
- token: freshToken,
577
- });
578
-
579
- // Server confirms `freshToken` and transitions to version 2
580
- send({
581
- type: "Transition",
582
- startVersion: {
583
- ...querySetVersion,
584
- identity: 1,
585
- },
586
- endVersion: {
587
- ...querySetVersion,
588
- identity: 2,
589
- },
590
- modifications: [],
591
- });
592
-
593
- vi.advanceTimersByTime(500);
594
-
595
- // ts=1.5
596
- // `freshToken` becomes stale before the client has a chance to fetch and send
597
- // `scheduledRefetchToken` (e.g. because the page is backgrounded or because `fetchToken` is slow
598
- // for some reason), so the server hits an AuthError.
599
- await simulateAuthError({
600
- send,
601
- close,
602
- authError: {
603
- type: "AuthError",
604
- error: "bla",
605
- baseVersion: 2,
606
- authUpdateAttempted: false,
607
- },
608
- });
609
-
610
- // In response to this error, we call `tryToReauthenticate`.
611
- // Let's say `this.configVersion` is X
612
- // This will first stop the websocket, which bumps the configVersion to X+1
613
- // This'll call `fetchAndGuardAgainstRace`, which bumps `this.configVersion` to X+2
614
- // and sets `originalConfigVersion=X+2` locally
615
- // Then it starts fetching `reauthToken` at ts=1.5 and it will finish at ts=2.5.
616
-
617
- // At ts=2, we expect the scheduled token fetch to start.
618
- // This calls `fetchAndGuardAgainstRace`, which bumps `this.configVersion` to X+3
619
- // and sets `originalConfigVersion=X+3` locally
620
-
621
- // At ts=2.5, we get a result from `fetchToken` from the `fetchAndGuardAgainstRace` call
622
- // in tryToReauthenticate.
623
- // However, the config version no longer matches, so we return { isFromOutdatedConfig: true }
624
- // and exit from tryToReauthenticate early. Notably, before `tryRestartSocket` is called,
625
- // so the connection is still stopped.
626
-
627
- // At ts=3, we get a result from `fetchToken` from the scheduled refetch.
628
- // This time we return the token since the config version matches.
629
-
630
- // Previously, `refetchToken` would not call `tryRestartSocket`, so the WS would
631
- // stay stopped.
632
-
633
- // Now that `tryRestartSocket` is called, we should expect to see an Authenticate
634
- // message with `scheduledRefetchToken`
635
- await assertReconnectWithAuth(receive, {
636
- baseVersion: 0,
637
- token: scheduledRefetchToken,
638
- });
639
-
640
- send({
641
- type: "Transition",
642
- startVersion: {
643
- ...querySetVersion,
644
- identity: 0,
645
- },
646
- endVersion: {
647
- ...querySetVersion,
648
- identity: 1,
649
- },
650
- modifications: [],
651
- });
652
-
653
- await client.close();
654
- vi.useRealTimers();
655
-
656
- expect(onChange).toHaveBeenCalledTimes(2);
657
- expect(onChange).toHaveBeenNthCalledWith(1, true);
658
- expect(onChange).toHaveBeenNthCalledWith(2, true);
659
- });
660
- });
661
-
662
- // When awaiting server confirmation of a fresh token, a subsequent
663
- // auth error (from an Authenticate request) will cause the client to go to
664
- // an unauthenticated state. This test covers a race condition where an
665
- // Authenticate request for a fresh token is sent, and then the client app
666
- // goes to background and misses the Transition response. If the client
667
- // becomes active after the new token has expired, a new Authenticate request
668
- // will be sent with the expired token, leading to an error response and
669
- // unauthenticated state.
670
- test("Client retries token validation on error", async () => {
671
- await withInMemoryWebSocket(async ({ address, receive, send, close }) => {
672
- const { client, baseClient } = testReactClient(address);
673
- const ts = Math.ceil(Date.now() / 1000);
674
- const token1 = jwtEncode({ iat: ts, exp: ts + 60 }, "token1");
675
- const token2 = jwtEncode({ iat: ts, exp: ts + 60 }, "token2");
676
- const token3 = jwtEncode({ iat: ts, exp: ts + 60 }, "token3");
677
- const tokens = [token1, token2, token3];
678
- const tokenFetcher = vi.fn(async (_opts) => tokens.shift()!);
679
- const onChange = vi.fn();
680
- client.setAuth(tokenFetcher, onChange);
681
-
682
- await assertReconnectWithAuth(receive, {
683
- baseVersion: 0,
684
- token: token1,
685
- });
686
-
687
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
688
-
689
- send({
690
- type: "Transition",
691
- startVersion: {
692
- ...querySetVersion,
693
- identity: 0,
694
- },
695
- endVersion: {
696
- ...querySetVersion,
697
- identity: 1,
698
- },
699
- modifications: [],
700
- });
701
-
702
- assertAuthenticateMessage(await receive(), {
703
- baseVersion: 1,
704
- token: token2,
705
- });
706
-
707
- // Simulating an auth error while waiting for server confirmation of a
708
- // fresh token.
709
- await simulateAuthError({
710
- send,
711
- close,
712
- authError: {
713
- type: "AuthError",
714
- error: "bla",
715
- baseVersion: 1,
716
- authUpdateAttempted: true,
717
- },
718
- });
719
- // The client should reattempt reauthentication.
720
- await assertReconnectWithAuth(receive, {
721
- baseVersion: 0,
722
- token: token3,
723
- });
724
- send({
725
- type: "Transition",
726
- startVersion: {
727
- ...querySetVersion,
728
- identity: 0,
729
- },
730
- endVersion: {
731
- ...querySetVersion,
732
- identity: 1,
733
- },
734
- modifications: [],
735
- });
736
-
737
- // Flush
738
- await new Promise((resolve) => setTimeout(resolve));
739
- await client.close();
740
-
741
- expect(tokenFetcher).toHaveBeenCalledTimes(3);
742
- // Initial setConfig
743
- expect(tokenFetcher).toHaveBeenNthCalledWith(1, {
744
- forceRefreshToken: false,
745
- });
746
- // Initial fresh token fetch
747
- expect(tokenFetcher).toHaveBeenNthCalledWith(2, {
748
- forceRefreshToken: true,
749
- });
750
- // Reauth second attempt
751
- expect(tokenFetcher).toHaveBeenNthCalledWith(3, {
752
- forceRefreshToken: true,
753
- });
754
- expect(onChange).toHaveBeenCalledTimes(2);
755
- // Initial setConfig
756
- expect(onChange).toHaveBeenNthCalledWith(1, true);
757
- // Reauth second attempt
758
- expect(onChange).toHaveBeenNthCalledWith(2, true);
759
- });
760
- });
761
-
762
- test("Authentication runs first", async () => {
763
- await withInMemoryWebSocket(async ({ address, receive, send }) => {
764
- const { client, baseClient } = testReactClient(address);
765
-
766
- const token1 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret");
767
- const tokenFetcher = vi.fn(async () => token1);
768
- client.setAuth(tokenFetcher);
769
-
770
- await assertReconnectWithAuth(receive, {
771
- baseVersion: 0,
772
- token: token1,
773
- });
774
-
775
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
776
-
777
- send({
778
- type: "Transition",
779
- startVersion: querySetVersion,
780
- endVersion: {
781
- ...querySetVersion,
782
- // Client started at 0
783
- // Good token advanced to 1
784
- identity: 1,
785
- },
786
- modifications: [],
787
- });
788
-
789
- const token2 = jwtEncode({ iat: 1234550, exp: 1244550 }, "secret");
790
- const tokenFetcher2 = vi.fn(async () => token2);
791
- client.setAuth(tokenFetcher2);
792
- client.watchQuery(anyApi.myQuery.default).onUpdate(() => {});
793
-
794
- // Crucially Authenticate comes first!
795
- assertAuthenticateMessage(await receive(), {
796
- baseVersion: 1,
797
- token: token2,
798
- });
799
- expect((await receive()).type).toEqual("ModifyQuerySet");
800
- });
801
- });
802
-
803
- test("Auth pause doesn't prevent unsubscribing from queries", async () => {
804
- await withInMemoryWebSocket(async ({ address, receive, send }) => {
805
- const { client, baseClient } = testReactClient(address);
806
-
807
- const token1 = jwtEncode({ iat: 1234500, exp: 1244500 }, "secret");
808
- const tokenFetcher = vi.fn(async () => token1);
809
- client.setAuth(tokenFetcher);
810
-
811
- const unsubscribe = client
812
- .watchQuery(anyApi.myQuery.default)
813
- .onUpdate(() => {});
814
-
815
- await assertReconnectWithAuth(receive, {
816
- baseVersion: 0,
817
- token: token1,
818
- });
819
-
820
- const querySetVersion = baseClient["remoteQuerySet"]["version"];
821
-
822
- send({
823
- type: "Transition",
824
- startVersion: querySetVersion,
825
- endVersion: {
826
- querySet: 1,
827
- identity: 1,
828
- ts: Long.fromNumber(1),
829
- },
830
- modifications: [
831
- {
832
- type: "QueryUpdated",
833
- queryId: 0,
834
- value: 42,
835
- logLines: [],
836
- journal: null,
837
- },
838
- ],
839
- });
840
-
841
- await waitForExpect(() => {
842
- expect(baseClient["remoteQuerySet"]["version"].identity).toEqual(1);
843
- });
844
-
845
- let resolve: (value: string) => void;
846
- const tokenFetcher2 = vi.fn(
847
- () =>
848
- new Promise<string>((r) => {
849
- resolve = r;
850
- }),
851
- );
852
- // Set new auth
853
- client.setAuth(tokenFetcher2);
854
-
855
- // Unsubscribe
856
- unsubscribe();
857
-
858
- // Finish fetching the token
859
- const token2 = jwtEncode({ iat: 1234550, exp: 1244550 }, "secret");
860
- resolve!(token2);
861
-
862
- // Crucially Authenticate comes first!
863
- assertAuthenticateMessage(await receive(), {
864
- baseVersion: 1,
865
- token: token2,
866
- });
867
- expect(await receive()).toMatchObject({
868
- type: "ModifyQuerySet",
869
- modifications: [{ type: "Remove", queryId: 0 }],
870
- baseVersion: 1,
871
- });
872
-
873
- // Make sure we are now unpaused
874
-
875
- client.watchQuery(anyApi.myQuery.default).onUpdate(() => {});
876
-
877
- expect(await receive()).toMatchObject({
878
- type: "ModifyQuerySet",
879
- modifications: [{ type: "Add", queryId: 1 }],
880
- baseVersion: 2,
881
- });
882
-
883
- client.watchQuery(anyApi.myQuery.foo).onUpdate(() => {});
884
-
885
- expect(await receive()).toMatchObject({
886
- type: "ModifyQuerySet",
887
- modifications: [{ type: "Add", queryId: 2 }],
888
- baseVersion: 3,
889
- });
890
- });
891
- });
892
-
893
- test("Local state resume doesn't cause duplicate AddQuery", async () => {
894
- await withInMemoryWebSocket(async ({ address, receive }) => {
895
- const { client } = testReactClient(address);
896
-
897
- // First we subscribe
898
- client.watchQuery(anyApi.myQuery.default).onUpdate(() => {});
899
-
900
- expect((await receive()).type).toEqual("Connect");
901
- expect(await receive()).toMatchObject({
902
- type: "ModifyQuerySet",
903
- modifications: [{ type: "Add", queryId: 0 }],
904
- baseVersion: 0,
905
- });
906
-
907
- // Before the server confirms, we set auth, leading to pause
908
- // and unpause.
909
- const tokenFetcher = vi.fn(async () =>
910
- jwtEncode({ iat: 1234500, exp: 1244500 }, "secret"),
911
- );
912
- client.setAuth(tokenFetcher);
913
-
914
- // We should only send Authenticate, since we already
915
- // sent the Add modification
916
- expect(await receive()).toMatchObject({
917
- type: "Authenticate",
918
- baseVersion: 0,
919
- });
920
-
921
- // Subscribe again
922
- client
923
- .watchQuery(anyApi.myQuery.default, { foo: "bla" })
924
- .onUpdate(() => {});
925
- // Now we're sending the second query, not the first!
926
- expect(await receive()).toMatchObject({
927
- type: "ModifyQuerySet",
928
- modifications: [{ type: "Add", queryId: 1 }],
929
- baseVersion: 1,
930
- });
931
- });
932
- });
933
-
934
- test("Local state resume doesn't send both Add and Remove", async () => {
935
- await withInMemoryWebSocket(async ({ address, receive }) => {
936
- const { client } = testReactClient(address);
937
-
938
- // First we subscribe to kick off connect.
939
- client.watchQuery(anyApi.myQuery.default).onUpdate(() => {});
940
-
941
- expect((await receive()).type).toEqual("Connect");
942
- expect(await receive()).toMatchObject({
943
- type: "ModifyQuerySet",
944
- modifications: [{ type: "Add", queryId: 0 }],
945
- baseVersion: 0,
946
- });
947
-
948
- // Set slow auth, causing pause
949
- let resolve: (value: string) => void;
950
- const tokenFetcher2 = vi.fn(
951
- () =>
952
- new Promise<string>((r) => {
953
- resolve = r;
954
- }),
955
- );
956
- client.setAuth(tokenFetcher2);
957
-
958
- // Subscribe to second query, while paused
959
- const unsubscribe = client
960
- .watchQuery(anyApi.myQuery.default, { foo: "bla" })
961
- .onUpdate(() => {});
962
-
963
- // Subscribe third query, while paused
964
- client
965
- .watchQuery(anyApi.myQuery.default, { foo: "da" })
966
- .onUpdate(() => {});
967
-
968
- // Unsubscribe from second query, while paused
969
- unsubscribe();
970
-
971
- // Unpause ie resume
972
- resolve!(jwtEncode({ iat: 1234550, exp: 1244550 }, "secret"));
973
-
974
- // We authenticate first
975
- expect(await receive()).toMatchObject({
976
- type: "Authenticate",
977
- baseVersion: 0,
978
- });
979
-
980
- // We subscribe to the third query only!
981
- expect(await receive()).toMatchObject({
982
- type: "ModifyQuerySet",
983
- modifications: [{ type: "Add", queryId: 2 }],
984
- baseVersion: 1,
985
- });
986
- });
987
- });
988
-
989
- test("Local state resume refcounts", async () => {
990
- await withInMemoryWebSocket(async ({ address, receive }) => {
991
- const { client } = testReactClient(address);
992
-
993
- // First we subscribe to kick off connect.
994
- client.watchQuery(anyApi.myQuery.default).onUpdate(() => {});
995
-
996
- expect((await receive()).type).toEqual("Connect");
997
- expect(await receive()).toMatchObject({
998
- type: "ModifyQuerySet",
999
- modifications: [{ type: "Add", queryId: 0 }],
1000
- baseVersion: 0,
1001
- });
1002
-
1003
- // Set slow auth, causing pause
1004
- let resolve: (value: string) => void;
1005
- const tokenFetcher2 = vi.fn(
1006
- () =>
1007
- new Promise<string>((r) => {
1008
- resolve = r;
1009
- }),
1010
- );
1011
- client.setAuth(tokenFetcher2);
1012
-
1013
- // Subscribe to second query, while paused
1014
- const unsubscribe = client
1015
- .watchQuery(anyApi.myQuery.default, { foo: "bla" })
1016
- .onUpdate(() => {});
1017
-
1018
- // Subscribe to the same query, while paused
1019
- client
1020
- .watchQuery(anyApi.myQuery.default, { foo: "bla" })
1021
- .onUpdate(() => {});
1022
-
1023
- // Unsubscribe once from the second query, while paused
1024
- unsubscribe();
1025
-
1026
- // Unpause ie resume
1027
- resolve!(jwtEncode({ iat: 1234550, exp: 1244550 }, "secret"));
1028
-
1029
- // We authenticate first
1030
- expect(await receive()).toMatchObject({
1031
- type: "Authenticate",
1032
- baseVersion: 0,
1033
- });
1034
-
1035
- // We subscribe to the second query, because there's still one subscriber
1036
- // on it.
1037
- expect(await receive()).toMatchObject({
1038
- type: "ModifyQuerySet",
1039
- modifications: [{ type: "Add", queryId: 1 }],
1040
- baseVersion: 1,
1041
- });
1042
- });
1043
- });
1044
-
1045
- test("Local state restart doesn't send both Add and Remove", async () => {
1046
- await withInMemoryWebSocket(async ({ address, receive }) => {
1047
- const { client } = testReactClient(address);
1048
-
1049
- // Set slow auth, causing pause while connecting
1050
- let resolve: (value: string) => void;
1051
- const tokenFetcher2 = vi.fn(
1052
- () =>
1053
- new Promise<string>((r) => {
1054
- resolve = r;
1055
- }),
1056
- );
1057
- client.setAuth(tokenFetcher2);
1058
-
1059
- // Subscribe while paused and connecting
1060
- const unsubscribe = client
1061
- .watchQuery(anyApi.myQuery.default)
1062
- .onUpdate(() => {});
1063
-
1064
- // Unsubscribe while paused and connecting
1065
- unsubscribe();
1066
-
1067
- // Unpause
1068
- resolve!(jwtEncode({ iat: 1234550, exp: 1244550 }, "secret"));
1069
-
1070
- expect((await receive()).type).toEqual("Connect");
1071
- expect((await receive()).type).toEqual("Authenticate");
1072
- expect(await receive()).toMatchObject({
1073
- type: "ModifyQuerySet",
1074
- baseVersion: 0,
1075
- modifications: [],
1076
- });
1077
- });
1078
- });
1079
- });
1080
-
1081
- // When a client is created it can't necessarily have setAuth called
1082
- // on it right away: often that library needs some setup.
1083
- describe.sequential("authMode WebSocket", () => {
1084
- test.each([false, true])("expectAuth: %s", async (expectAuth: boolean) => {
1085
- await withInMemoryWebSocket(async ({ address, receive, close }) => {
1086
- const { client } = testReactClient(
1087
- address,
1088
- expectAuth ? { expectAuth: true } : {},
1089
- );
1090
-
1091
- // ConvexReactClient connect is lazy, you have to subscribe to
1092
- // a query or otherwise make a request before anything happens.
1093
- const _mutP = client.mutation(anyApi.myMutation.default, {});
1094
-
1095
- // If expectAuth isn't enabled, this kicks off connect etc.
1096
- if (!expectAuth) {
1097
- expect((await receive()).type).toBe("Connect");
1098
- expect((await receive()).type).toBe("ModifyQuerySet");
1099
- expect((await receive()).type).toBe("Mutation");
1100
- } else {
1101
- // but *nothing* happens if expectAuth is set.
1102
- }
1103
-
1104
- let resolve: (value: string) => void;
1105
- const tokenFetcher2 = vi.fn(
1106
- () =>
1107
- new Promise<string>((r) => {
1108
- resolve = r;
1109
- }),
1110
- );
1111
- const onAuthChange = vi.fn();
1112
- client.setAuth(tokenFetcher2, onAuthChange);
1113
-
1114
- resolve!(jwtEncode({ iat: 1234550, exp: 1244550 }, "secret"));
1115
-
1116
- if (!expectAuth) {
1117
- expect((await receive()).type).toBe("Authenticate");
1118
- } else {
1119
- // We're still paused until auth is returned
1120
- expect((await receive()).type).toBe("Connect");
1121
- expect((await receive()).type).toBe("Authenticate");
1122
- expect((await receive()).type).toBe("ModifyQuerySet");
1123
- expect((await receive()).type).toBe("Mutation");
1124
- }
1125
-
1126
- await client.close();
1127
- close();
1128
- }, true);
1129
- });
1130
- });
1131
-
1132
- function assertAuthenticateMessage(
1133
- message: ClientMessage,
1134
- expected: {
1135
- baseVersion: number;
1136
- token: string;
1137
- },
1138
- ) {
1139
- expect(message.type).toEqual("Authenticate");
1140
- // (These errors are redundant, but are necessary for type narrowing)
1141
- if (message.type !== "Authenticate") {
1142
- throw new Error("Expected an Authenticate message");
1143
- }
1144
- expect(message.baseVersion).toEqual(expected.baseVersion);
1145
- expect(message.tokenType).toEqual("User");
1146
- if (message.tokenType !== "User") {
1147
- throw new Error("Expected a User token");
1148
- }
1149
- expect(message.value).toEqual(expected.token);
1150
- }
1151
-
1152
- async function assertReconnectWithAuth(
1153
- receive: () => Promise<ClientMessage>,
1154
- expectedAuth: {
1155
- baseVersion: number;
1156
- token: string;
1157
- },
1158
- ) {
1159
- expect((await receive()).type).toEqual("Connect");
1160
- assertAuthenticateMessage(await receive(), expectedAuth);
1161
- expect((await receive()).type).toEqual("ModifyQuerySet");
1162
- }
1163
-
1164
- async function simulateAuthError(args: {
1165
- send: (message: WireServerMessage) => void;
1166
- close: () => void;
1167
- authError: AuthError;
1168
- }) {
1169
- args.send({
1170
- type: "AuthError",
1171
- error: args.authError.error,
1172
- baseVersion: args.authError.baseVersion,
1173
- authUpdateAttempted: args.authError.authUpdateAttempted,
1174
- });
1175
- // The server always closes the connection after an AuthError
1176
- args.close();
1177
- }