convex 1.46.0 → 1.47.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 (332) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/dist/browser.bundle.js +7 -1
  3. package/dist/browser.bundle.js.map +2 -2
  4. package/dist/cjs/bundler/index.js +5 -4
  5. package/dist/cjs/bundler/index.js.map +2 -2
  6. package/dist/cjs/cli/codegen.js +0 -4
  7. package/dist/cjs/cli/codegen.js.map +2 -2
  8. package/dist/cjs/cli/configure.js +13 -4
  9. package/dist/cjs/cli/configure.js.map +2 -2
  10. package/dist/cjs/cli/deploy.js +27 -2
  11. package/dist/cjs/cli/deploy.js.map +2 -2
  12. package/dist/cjs/cli/deploymentSelect.js +2 -2
  13. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  14. package/dist/cjs/cli/dev.js +6 -0
  15. package/dist/cjs/cli/dev.js.map +2 -2
  16. package/dist/cjs/cli/env.js +10 -5
  17. package/dist/cjs/cli/env.js.map +2 -2
  18. package/dist/cjs/cli/envDefault.js +7 -2
  19. package/dist/cjs/cli/envDefault.js.map +2 -2
  20. package/dist/cjs/cli/generatedApi.js.map +1 -1
  21. package/dist/cjs/cli/lib/api.js +2 -0
  22. package/dist/cjs/cli/lib/api.js.map +2 -2
  23. package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js +113 -0
  24. package/dist/cjs/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
  25. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js +36 -47
  26. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  27. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js +58 -39
  28. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
  29. package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js +90 -0
  30. package/dist/cjs/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
  31. package/dist/cjs/cli/lib/codegen.js.map +2 -2
  32. package/dist/cjs/cli/lib/command.js +2 -1
  33. package/dist/cjs/cli/lib/command.js.map +2 -2
  34. package/dist/cjs/cli/lib/components/definition/bundle.js +37 -11
  35. package/dist/cjs/cli/lib/components/definition/bundle.js.map +2 -2
  36. package/dist/cjs/cli/lib/components.js +48 -5
  37. package/dist/cjs/cli/lib/components.js.map +2 -2
  38. package/dist/cjs/cli/lib/config.js +56 -17
  39. package/dist/cjs/cli/lib/config.js.map +2 -2
  40. package/dist/cjs/cli/lib/deploy2.js +3 -1
  41. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  42. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js +30 -2
  43. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js.map +2 -2
  44. package/dist/cjs/cli/lib/dev.js +5 -0
  45. package/dist/cjs/cli/lib/dev.js.map +2 -2
  46. package/dist/cjs/cli/lib/formatValidationProgress.js +47 -0
  47. package/dist/cjs/cli/lib/formatValidationProgress.js.map +7 -0
  48. package/dist/cjs/cli/lib/indexes.js.map +1 -1
  49. package/dist/cjs/cli/lib/mcp/tools/env.js +10 -3
  50. package/dist/cjs/cli/lib/mcp/tools/env.js.map +2 -2
  51. package/dist/cjs/cli/lib/run.js +4 -0
  52. package/dist/cjs/cli/lib/run.js.map +2 -2
  53. package/dist/cjs/cli/lib/schemaEvaluation.js +62 -0
  54. package/dist/cjs/cli/lib/schemaEvaluation.js.map +7 -0
  55. package/dist/cjs/cli/lib/usageLimits.js +4 -2
  56. package/dist/cjs/cli/lib/usageLimits.js.map +2 -2
  57. package/dist/cjs/cli/lib/utils/mutex.js +9 -24
  58. package/dist/cjs/cli/lib/utils/mutex.js.map +2 -2
  59. package/dist/cjs/cli/lib/utils/utils.js +48 -18
  60. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  61. package/dist/cjs/cli/projectCreate.js +1 -1
  62. package/dist/cjs/cli/projectCreate.js.map +1 -1
  63. package/dist/cjs/index.js +1 -1
  64. package/dist/cjs/index.js.map +1 -1
  65. package/dist/cjs/server/impl/actions_impl.js +8 -3
  66. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  67. package/dist/cjs/server/impl/storage_impl.js +29 -0
  68. package/dist/cjs/server/impl/storage_impl.js.map +2 -2
  69. package/dist/cjs/server/index.js +1 -0
  70. package/dist/cjs/server/index.js.map +2 -2
  71. package/dist/cjs/server/meta.js.map +1 -1
  72. package/dist/cjs/server/registration.js.map +1 -1
  73. package/dist/cjs/server/schema.js +34 -12
  74. package/dist/cjs/server/schema.js.map +2 -2
  75. package/dist/cjs/server/storage.js.map +1 -1
  76. package/dist/cjs/values/validators.js +1 -1
  77. package/dist/cjs/values/validators.js.map +2 -2
  78. package/dist/cjs/values/value.js +6 -0
  79. package/dist/cjs/values/value.js.map +2 -2
  80. package/dist/cjs-types/bundler/index.d.ts +9 -2
  81. package/dist/cjs-types/bundler/index.d.ts.map +1 -1
  82. package/dist/cjs-types/cli/codegen.d.ts.map +1 -1
  83. package/dist/cjs-types/cli/configure.d.ts +6 -0
  84. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  85. package/dist/cjs-types/cli/deploy.d.ts +2 -0
  86. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  87. package/dist/cjs-types/cli/deploymentCreate.d.ts +6 -6
  88. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  89. package/dist/cjs-types/cli/dev.d.ts +1 -0
  90. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  91. package/dist/cjs-types/cli/env.d.ts.map +1 -1
  92. package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
  93. package/dist/cjs-types/cli/generatedApi.d.ts +1 -1
  94. package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
  95. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  96. package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
  97. package/dist/cjs-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
  98. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
  99. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
  101. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
  103. package/dist/cjs-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
  104. package/dist/cjs-types/cli/lib/codegen.d.ts +0 -3
  105. package/dist/cjs-types/cli/lib/codegen.d.ts.map +1 -1
  106. package/dist/cjs-types/cli/lib/command.d.ts +2 -0
  107. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  108. package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts +13 -0
  109. package/dist/cjs-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
  110. package/dist/cjs-types/cli/lib/components.d.ts +4 -0
  111. package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
  112. package/dist/cjs-types/cli/lib/config.d.ts +2 -1
  113. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  114. package/dist/cjs-types/cli/lib/deploy2.d.ts +2 -0
  115. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  116. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
  117. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
  118. package/dist/cjs-types/cli/lib/dev.d.ts +1 -0
  119. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  120. package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts +8 -0
  121. package/dist/cjs-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
  122. package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts +8 -5
  123. package/dist/cjs-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
  124. package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
  125. package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts +33 -0
  126. package/dist/cjs-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
  127. package/dist/cjs-types/cli/lib/usageLimits.d.ts +1 -1
  128. package/dist/cjs-types/cli/lib/usageLimits.d.ts.map +1 -1
  129. package/dist/cjs-types/cli/lib/utils/mutex.d.ts +1 -3
  130. package/dist/cjs-types/cli/lib/utils/mutex.d.ts.map +1 -1
  131. package/dist/cjs-types/cli/lib/utils/utils.d.ts +10 -2
  132. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  133. package/dist/cjs-types/index.d.ts +1 -1
  134. package/dist/cjs-types/server/impl/actions_impl.d.ts +18 -3
  135. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  136. package/dist/cjs-types/server/impl/storage_impl.d.ts.map +1 -1
  137. package/dist/cjs-types/server/index.d.ts +1 -1
  138. package/dist/cjs-types/server/index.d.ts.map +1 -1
  139. package/dist/cjs-types/server/meta.d.ts +63 -0
  140. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  141. package/dist/cjs-types/server/registration.d.ts +10 -0
  142. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  143. package/dist/cjs-types/server/schema.d.ts +33 -0
  144. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  145. package/dist/cjs-types/server/storage.d.ts.map +1 -1
  146. package/dist/cjs-types/values/value.d.ts.map +1 -1
  147. package/dist/cli.bundle.cjs +2935 -2048
  148. package/dist/cli.bundle.cjs.map +4 -4
  149. package/dist/esm/bundler/index.js +5 -4
  150. package/dist/esm/bundler/index.js.map +2 -2
  151. package/dist/esm/cli/codegen.js +0 -4
  152. package/dist/esm/cli/codegen.js.map +2 -2
  153. package/dist/esm/cli/configure.js +12 -4
  154. package/dist/esm/cli/configure.js.map +2 -2
  155. package/dist/esm/cli/deploy.js +27 -2
  156. package/dist/esm/cli/deploy.js.map +2 -2
  157. package/dist/esm/cli/deploymentSelect.js +6 -3
  158. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  159. package/dist/esm/cli/dev.js +6 -0
  160. package/dist/esm/cli/dev.js.map +2 -2
  161. package/dist/esm/cli/env.js +11 -6
  162. package/dist/esm/cli/env.js.map +2 -2
  163. package/dist/esm/cli/envDefault.js +7 -2
  164. package/dist/esm/cli/envDefault.js.map +2 -2
  165. package/dist/esm/cli/lib/api.js +2 -0
  166. package/dist/esm/cli/lib/api.js.map +2 -2
  167. package/dist/esm/cli/lib/checkForLargeIndexBackfill.js +95 -0
  168. package/dist/esm/cli/lib/checkForLargeIndexBackfill.js.map +7 -0
  169. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js +37 -48
  170. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  171. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js +63 -41
  172. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js.map +2 -2
  173. package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js +68 -0
  174. package/dist/esm/cli/lib/checkForStagedValidatorDeletion.js.map +7 -0
  175. package/dist/esm/cli/lib/codegen.js.map +2 -2
  176. package/dist/esm/cli/lib/command.js +2 -1
  177. package/dist/esm/cli/lib/command.js.map +2 -2
  178. package/dist/esm/cli/lib/components/definition/bundle.js +37 -11
  179. package/dist/esm/cli/lib/components/definition/bundle.js.map +2 -2
  180. package/dist/esm/cli/lib/components.js +55 -5
  181. package/dist/esm/cli/lib/components.js.map +2 -2
  182. package/dist/esm/cli/lib/config.js +55 -17
  183. package/dist/esm/cli/lib/config.js.map +2 -2
  184. package/dist/esm/cli/lib/deploy2.js +3 -1
  185. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  186. package/dist/esm/cli/lib/deployApi/evaluateSchema.js +28 -2
  187. package/dist/esm/cli/lib/deployApi/evaluateSchema.js.map +2 -2
  188. package/dist/esm/cli/lib/dev.js +5 -0
  189. package/dist/esm/cli/lib/dev.js.map +2 -2
  190. package/dist/esm/cli/lib/formatValidationProgress.js +24 -0
  191. package/dist/esm/cli/lib/formatValidationProgress.js.map +7 -0
  192. package/dist/esm/cli/lib/indexes.js.map +1 -1
  193. package/dist/esm/cli/lib/mcp/tools/env.js +10 -3
  194. package/dist/esm/cli/lib/mcp/tools/env.js.map +2 -2
  195. package/dist/esm/cli/lib/run.js +4 -0
  196. package/dist/esm/cli/lib/run.js.map +2 -2
  197. package/dist/esm/cli/lib/schemaEvaluation.js +39 -0
  198. package/dist/esm/cli/lib/schemaEvaluation.js.map +7 -0
  199. package/dist/esm/cli/lib/usageLimits.js +4 -2
  200. package/dist/esm/cli/lib/usageLimits.js.map +2 -2
  201. package/dist/esm/cli/lib/utils/mutex.js +9 -24
  202. package/dist/esm/cli/lib/utils/mutex.js.map +2 -2
  203. package/dist/esm/cli/lib/utils/utils.js +47 -18
  204. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  205. package/dist/esm/cli/projectCreate.js +1 -1
  206. package/dist/esm/cli/projectCreate.js.map +1 -1
  207. package/dist/esm/index.js +1 -1
  208. package/dist/esm/index.js.map +1 -1
  209. package/dist/esm/server/impl/actions_impl.js +7 -3
  210. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  211. package/dist/esm/server/impl/storage_impl.js +29 -0
  212. package/dist/esm/server/impl/storage_impl.js.map +2 -2
  213. package/dist/esm/server/index.js +4 -1
  214. package/dist/esm/server/index.js.map +2 -2
  215. package/dist/esm/server/schema.js +34 -12
  216. package/dist/esm/server/schema.js.map +2 -2
  217. package/dist/esm/values/validators.js +1 -1
  218. package/dist/esm/values/validators.js.map +2 -2
  219. package/dist/esm/values/value.js +6 -0
  220. package/dist/esm/values/value.js.map +2 -2
  221. package/dist/esm-types/bundler/index.d.ts +9 -2
  222. package/dist/esm-types/bundler/index.d.ts.map +1 -1
  223. package/dist/esm-types/cli/codegen.d.ts.map +1 -1
  224. package/dist/esm-types/cli/configure.d.ts +6 -0
  225. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  226. package/dist/esm-types/cli/deploy.d.ts +2 -0
  227. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  228. package/dist/esm-types/cli/deploymentCreate.d.ts +6 -6
  229. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  230. package/dist/esm-types/cli/dev.d.ts +1 -0
  231. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  232. package/dist/esm-types/cli/env.d.ts.map +1 -1
  233. package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
  234. package/dist/esm-types/cli/generatedApi.d.ts +1 -1
  235. package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
  236. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  237. package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts +30 -0
  238. package/dist/esm-types/cli/lib/checkForLargeIndexBackfill.d.ts.map +1 -0
  239. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts +5 -7
  240. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  241. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts +4 -10
  242. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -1
  243. package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts +17 -0
  244. package/dist/esm-types/cli/lib/checkForStagedValidatorDeletion.d.ts.map +1 -0
  245. package/dist/esm-types/cli/lib/codegen.d.ts +0 -3
  246. package/dist/esm-types/cli/lib/codegen.d.ts.map +1 -1
  247. package/dist/esm-types/cli/lib/command.d.ts +2 -0
  248. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  249. package/dist/esm-types/cli/lib/components/definition/bundle.d.ts +13 -0
  250. package/dist/esm-types/cli/lib/components/definition/bundle.d.ts.map +1 -1
  251. package/dist/esm-types/cli/lib/components.d.ts +4 -0
  252. package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
  253. package/dist/esm-types/cli/lib/config.d.ts +2 -1
  254. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  255. package/dist/esm-types/cli/lib/deploy2.d.ts +2 -0
  256. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  257. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts +460 -16
  258. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -1
  259. package/dist/esm-types/cli/lib/dev.d.ts +1 -0
  260. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  261. package/dist/esm-types/cli/lib/formatValidationProgress.d.ts +8 -0
  262. package/dist/esm-types/cli/lib/formatValidationProgress.d.ts.map +1 -0
  263. package/dist/esm-types/cli/lib/mcp/tools/env.d.ts +8 -5
  264. package/dist/esm-types/cli/lib/mcp/tools/env.d.ts.map +1 -1
  265. package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
  266. package/dist/esm-types/cli/lib/schemaEvaluation.d.ts +33 -0
  267. package/dist/esm-types/cli/lib/schemaEvaluation.d.ts.map +1 -0
  268. package/dist/esm-types/cli/lib/usageLimits.d.ts +1 -1
  269. package/dist/esm-types/cli/lib/usageLimits.d.ts.map +1 -1
  270. package/dist/esm-types/cli/lib/utils/mutex.d.ts +1 -3
  271. package/dist/esm-types/cli/lib/utils/mutex.d.ts.map +1 -1
  272. package/dist/esm-types/cli/lib/utils/utils.d.ts +10 -2
  273. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  274. package/dist/esm-types/index.d.ts +1 -1
  275. package/dist/esm-types/server/impl/actions_impl.d.ts +18 -3
  276. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  277. package/dist/esm-types/server/impl/storage_impl.d.ts.map +1 -1
  278. package/dist/esm-types/server/index.d.ts +1 -1
  279. package/dist/esm-types/server/index.d.ts.map +1 -1
  280. package/dist/esm-types/server/meta.d.ts +63 -0
  281. package/dist/esm-types/server/meta.d.ts.map +1 -1
  282. package/dist/esm-types/server/registration.d.ts +10 -0
  283. package/dist/esm-types/server/registration.d.ts.map +1 -1
  284. package/dist/esm-types/server/schema.d.ts +33 -0
  285. package/dist/esm-types/server/schema.d.ts.map +1 -1
  286. package/dist/esm-types/server/storage.d.ts.map +1 -1
  287. package/dist/esm-types/values/value.d.ts.map +1 -1
  288. package/dist/react.bundle.js +7 -1
  289. package/dist/react.bundle.js.map +2 -2
  290. package/package.json +5 -5
  291. package/schemas/convex.schema.json +5 -5
  292. package/src/bundler/index.ts +9 -4
  293. package/src/cli/codegen.ts +0 -2
  294. package/src/cli/configure.ts +27 -7
  295. package/src/cli/deploy.ts +36 -5
  296. package/src/cli/deploymentSelect.ts +7 -4
  297. package/src/cli/dev.ts +9 -0
  298. package/src/cli/env.ts +12 -6
  299. package/src/cli/envDefault.ts +8 -2
  300. package/src/cli/generatedApi.ts +1 -1
  301. package/src/cli/lib/api.ts +5 -1
  302. package/src/cli/lib/checkForLargeIndexBackfill.ts +173 -0
  303. package/src/cli/lib/checkForLargeIndexDeletion.ts +45 -58
  304. package/src/cli/lib/checkForSlowSchemaValidation.ts +76 -65
  305. package/src/cli/lib/checkForStagedValidatorDeletion.ts +104 -0
  306. package/src/cli/lib/codegen.ts +0 -3
  307. package/src/cli/lib/command.ts +3 -0
  308. package/src/cli/lib/components/definition/bundle.ts +68 -14
  309. package/src/cli/lib/components.ts +71 -4
  310. package/src/cli/lib/config.ts +85 -18
  311. package/src/cli/lib/deploy2.ts +10 -1
  312. package/src/cli/lib/deployApi/evaluateSchema.ts +35 -0
  313. package/src/cli/lib/dev.ts +14 -0
  314. package/src/cli/lib/formatValidationProgress.ts +35 -0
  315. package/src/cli/lib/indexes.ts +1 -1
  316. package/src/cli/lib/mcp/tools/env.ts +17 -3
  317. package/src/cli/lib/run.ts +2 -0
  318. package/src/cli/lib/schemaEvaluation.ts +88 -0
  319. package/src/cli/lib/usageLimits.ts +2 -0
  320. package/src/cli/lib/utils/mutex.ts +9 -27
  321. package/src/cli/lib/utils/utils.ts +64 -21
  322. package/src/cli/projectCreate.ts +1 -1
  323. package/src/index.ts +1 -1
  324. package/src/server/impl/actions_impl.ts +26 -6
  325. package/src/server/impl/storage_impl.ts +30 -0
  326. package/src/server/index.ts +5 -1
  327. package/src/server/meta.ts +56 -2
  328. package/src/server/registration.ts +10 -0
  329. package/src/server/schema.ts +37 -15
  330. package/src/server/storage.ts +17 -0
  331. package/src/values/validators.ts +1 -1
  332. package/src/values/value.ts +9 -5
@@ -53,6 +53,18 @@ import { deploymentDashboardUrlPage } from "./dashboard.js";
53
53
  import { formatIndex, LargeIndexDeletionCheck } from "./indexes.js";
54
54
  import { checkForLargeIndexDeletion } from "./checkForLargeIndexDeletion.js";
55
55
  import { checkForSlowSchemaValidation } from "./checkForSlowSchemaValidation.js";
56
+ import {
57
+ checkForLargeIndexBackfill,
58
+ LargeIndexBackfillCheck,
59
+ } from "./checkForLargeIndexBackfill.js";
60
+ import {
61
+ pushStagesValidators,
62
+ sharedSchemaEvaluation,
63
+ } from "./schemaEvaluation.js";
64
+ import {
65
+ checkForStagedValidatorDeletion,
66
+ StagedValidatorDeletionCheck,
67
+ } from "./checkForStagedValidatorDeletion.js";
56
68
  import { LogManager } from "./logs.js";
57
69
  import { createHash } from "crypto";
58
70
  import { Bundle, BundleHash } from "../../bundler/index.js";
@@ -76,6 +88,8 @@ export type PushOptions = {
76
88
  pushAllModules: boolean;
77
89
  logManager?: LogManager | undefined;
78
90
  largeIndexDeletionCheck: LargeIndexDeletionCheck;
91
+ largeIndexBackfillCheck: LargeIndexBackfillCheck;
92
+ stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;
79
93
  // Whether a dry run should warn when the schema change would block the
80
94
  // deploy on a slow table walk. On for deploys; off for commands whose dry
81
95
  // runs never deploy (e.g. codegen).
@@ -125,6 +139,11 @@ export async function runCodegen(
125
139
  liveComponentSources: options.liveComponentSources,
126
140
  typecheckComponents: false,
127
141
  debugNodeApis: options.debugNodeApis,
142
+ // Code generation uses the source schema independently of deployment data.
143
+ largeIndexDeletionCheck: "no verification",
144
+ largeIndexBackfillCheck: "no verification",
145
+ stagedValidatorDeletionCheck: "no verification",
146
+ warnOnSlowSchemaValidation: false,
128
147
  },
129
148
  );
130
149
  } else {
@@ -234,6 +253,8 @@ async function startComponentsPushAndCodegen(
234
253
  pushAllModules?: boolean;
235
254
  debugNodeApis: boolean;
236
255
  largeIndexDeletionCheck: LargeIndexDeletionCheck;
256
+ largeIndexBackfillCheck: LargeIndexBackfillCheck;
257
+ stagedValidatorDeletionCheck: StagedValidatorDeletionCheck;
237
258
  warnOnSlowSchemaValidation: boolean;
238
259
  codegenOnlyThisComponent?: string | undefined;
239
260
  },
@@ -451,6 +472,11 @@ async function startComponentsPushAndCodegen(
451
472
  }
452
473
  logStartPushSizes(parentSpan, startPushRequest);
453
474
 
475
+ const schemaEvaluation = sharedSchemaEvaluation(
476
+ ctx,
477
+ startPushRequest,
478
+ options,
479
+ );
454
480
  if (options.largeIndexDeletionCheck !== "no verification") {
455
481
  await parentSpan.enterAsync("checkForLargeIndexDeletion", (span) =>
456
482
  checkForLargeIndexDeletion({
@@ -458,19 +484,60 @@ async function startComponentsPushAndCodegen(
458
484
  span,
459
485
  request: startPushRequest,
460
486
  options,
487
+ schemaEvaluation,
461
488
  askForConfirmation:
462
489
  options.largeIndexDeletionCheck === "ask for confirmation",
463
490
  }),
464
491
  );
465
492
  }
466
493
 
467
- if (options.dryRun && options.warnOnSlowSchemaValidation) {
468
- await parentSpan.enterAsync("checkForSlowSchemaValidation", (span) =>
469
- checkForSlowSchemaValidation({
494
+ const largeIndexBackfillCheck = options.largeIndexBackfillCheck;
495
+ if (largeIndexBackfillCheck !== "no verification") {
496
+ await parentSpan.enterAsync("checkForLargeIndexBackfill", (span) =>
497
+ checkForLargeIndexBackfill({
470
498
  ctx,
471
499
  span,
472
- request: startPushRequest,
500
+ schemaEvaluation,
473
501
  options,
502
+ // A dry run never blocks on a backfill, so it only reports.
503
+ mode: options.dryRun ? "warn" : largeIndexBackfillCheck,
504
+ }),
505
+ );
506
+ }
507
+
508
+ const stagedValidatorDeletionCheck = options.stagedValidatorDeletionCheck;
509
+ if (stagedValidatorDeletionCheck !== "no verification") {
510
+ await parentSpan.enterAsync(
511
+ "checkForStagedValidatorDeletion",
512
+ async (span) => {
513
+ const response = await schemaEvaluation(span);
514
+ await checkForStagedValidatorDeletion({
515
+ ctx,
516
+ response,
517
+ askForConfirmation:
518
+ stagedValidatorDeletionCheck === "ask for confirmation",
519
+ // A dry run previews the confirmation required by a real push.
520
+ dryRun: options.dryRun,
521
+ });
522
+ },
523
+ );
524
+ }
525
+
526
+ // A real push evaluates the schema only when the evaluation is already
527
+ // paid for by the unstaging check or the pushed schema stages a validator,
528
+ // so `dev` pushes of ordinary schemas skip the isolate evaluation and round
529
+ // trip that the status report would otherwise add on every save.
530
+ if (
531
+ options.warnOnSlowSchemaValidation &&
532
+ (options.dryRun ||
533
+ stagedValidatorDeletionCheck !== "no verification" ||
534
+ pushStagesValidators(startPushRequest))
535
+ ) {
536
+ await parentSpan.enterAsync("checkForSlowSchemaValidation", (span) =>
537
+ checkForSlowSchemaValidation({
538
+ span,
539
+ schemaEvaluation,
540
+ dryRun: options.dryRun,
474
541
  }),
475
542
  );
476
543
  }
@@ -42,6 +42,7 @@ import {
42
42
  } from "./localDeployment/errors.js";
43
43
  import { debugIsolateBundlesSerially } from "../../bundler/debugBundle.js";
44
44
  import { DeploymentType } from "./api.js";
45
+ import { isAnonymousDeployment } from "./deployment.js";
45
46
  export { productionProvisionHost, provisionHost } from "./utils/utils.js";
46
47
 
47
48
  /** Type representing WorkOS AuthKit integration configuration. */
@@ -672,7 +673,7 @@ export async function configFromProjectConfig(
672
673
  }
673
674
  const modules = convexResult.modules;
674
675
  modules.push(...nodeResult.modules);
675
- modules.push(...(await bundleAuthConfig(ctx, baseDir)));
676
+ modules.push(...(await bundleAuthConfig(ctx, baseDir)).modules);
676
677
 
677
678
  const nodeDependencies: NodeDependency[] = [];
678
679
  for (const [moduleName, moduleVersion] of nodeResult.externalDependencies) {
@@ -911,6 +912,49 @@ export function diffConfig(
911
912
  return { diffString: diff };
912
913
  }
913
914
 
915
+ export function setEnvVarsInstructions(
916
+ names: string[],
917
+ deploymentName: string | null,
918
+ deploymentType: DeploymentType | undefined,
919
+ deploymentUrl: string | undefined,
920
+ ): string {
921
+ // Name cloud deployments explicitly: without a flag `env set` targets the
922
+ // project's default dev deployment, which may not be where this push went
923
+ // (e.g. `npx convex dev --deployment <other dev deployment>`). Local and
924
+ // anonymous deployments are always the default target.
925
+ let deploymentFlag = "";
926
+ if (
927
+ deploymentName !== null &&
928
+ deploymentType !== "local" &&
929
+ deploymentType !== "anonymous"
930
+ ) {
931
+ deploymentFlag = ` --deployment ${deploymentName}`;
932
+ } else if (deploymentType === "prod") {
933
+ deploymentFlag = " --prod";
934
+ } else if (deploymentName === null && deploymentUrl !== undefined) {
935
+ // Pushes via `--url`/`--admin-key` or self-hosted env vars have no
936
+ // deployment name. The admin key stays a placeholder to keep it out of
937
+ // terminal output.
938
+ deploymentFlag = ` --url ${deploymentUrl} --admin-key <admin key>`;
939
+ }
940
+ const commands = (names.length > 0 ? names : ["<NAME>"]).map(
941
+ (name) =>
942
+ ` ${chalkStderr.bold(`npx convex env set${deploymentFlag} ${name} <value>`)}`,
943
+ );
944
+ let instructions = `Set ${names.length > 1 ? "them" : "it"} with:\n\n${commands.join("\n")}\n`;
945
+ // Anonymous deployments are only reachable from the local dashboard, which
946
+ // `deploymentDashboardUrlPage` can't address.
947
+ if (deploymentName !== null && !isAnonymousDeployment(deploymentName)) {
948
+ const variableQuery = names.length === 1 ? `?var=${names[0]}` : "";
949
+ const dashboardUrl = deploymentDashboardUrlPage(
950
+ deploymentName,
951
+ `/settings/environment-variables${variableQuery}`,
952
+ );
953
+ instructions += `\nor in the dashboard:\n\n ${chalkStderr.bold(dashboardUrl)}\n`;
954
+ }
955
+ return instructions;
956
+ }
957
+
914
958
  /** Handle an error from
915
959
  * legacy push path:
916
960
  * - /api/push_config
@@ -934,7 +978,7 @@ export async function handlePushConfigError(
934
978
  deploymentNotice: string;
935
979
  }
936
980
  | undefined,
937
- _deploymentType: DeploymentType | undefined,
981
+ deploymentType: DeploymentType | undefined,
938
982
  ): Promise<never> {
939
983
  const data: ErrorData | undefined =
940
984
  error instanceof ThrowingFetchError ? error.serverErrorData : undefined;
@@ -965,26 +1009,49 @@ export async function handlePushConfigError(
965
1009
  `Environment variable ${chalkStderr.bold(
966
1010
  variableName,
967
1011
  )} is used in auth config file but ` + `its value was not set.`;
968
- let setEnvVarInstructions =
969
- "Go set it in the dashboard or using `npx convex env set`";
970
-
971
- // If `npx convex dev` is running using --url there might not be a configured deployment
972
- if (deploymentName !== null) {
973
- const variableQuery =
974
- variableName !== undefined ? `?var=${variableName}` : "";
975
- const dashboardUrl = deploymentDashboardUrlPage(
976
- deploymentName,
977
- `/settings/environment-variables${variableQuery}`,
978
- );
979
- setEnvVarInstructions = `Go to:\n\n ${chalkStderr.bold(
980
- dashboardUrl,
981
- )}\n\n to set it up. `;
982
- }
983
1012
  await ctx.crash({
984
1013
  exitCode: 1,
985
1014
  errorType: "invalid filesystem or env vars",
986
1015
  errForSentry: error,
987
- printedMessage: envVarMessage + "\n" + setEnvVarInstructions,
1016
+ printedMessage:
1017
+ envVarMessage +
1018
+ "\n" +
1019
+ setEnvVarsInstructions(
1020
+ variableName !== undefined ? [variableName] : [],
1021
+ deploymentName,
1022
+ deploymentType,
1023
+ deployment?.deploymentUrl,
1024
+ ),
1025
+ });
1026
+ }
1027
+
1028
+ if (data?.code === "MissingEnvironmentVariables") {
1029
+ const errorMessage = data.message || "(no error message given)";
1030
+ const [, namesList] = errorMessage.match(/are not set: ([^.]+)\./) ?? [];
1031
+ const names = namesList?.split(", ") ?? [];
1032
+ const envVarMessage =
1033
+ names.length === 0
1034
+ ? errorMessage
1035
+ : names.length === 1
1036
+ ? `Environment variable ${chalkStderr.bold(names[0])} is ` +
1037
+ `declared as required in convex.config.ts but its value was not set.`
1038
+ : `Environment variables ${names
1039
+ .map((name) => chalkStderr.bold(name))
1040
+ .join(", ")} are declared as required in convex.config.ts ` +
1041
+ `but their values were not set.`;
1042
+ await ctx.crash({
1043
+ exitCode: 1,
1044
+ errorType: "invalid filesystem or env vars",
1045
+ errForSentry: error,
1046
+ printedMessage:
1047
+ envVarMessage +
1048
+ "\n" +
1049
+ setEnvVarsInstructions(
1050
+ names,
1051
+ deploymentName,
1052
+ deploymentType,
1053
+ deployment?.deploymentUrl,
1054
+ ),
988
1055
  });
989
1056
  }
990
1057
 
@@ -457,7 +457,9 @@ export async function deployToDeployment(
457
457
  writePushRequest?: string | undefined;
458
458
  liveComponentSources?: boolean | undefined;
459
459
  skipWorkosCheck?: boolean | undefined;
460
+ skipLargeIndexesCheck: boolean;
460
461
  allowDeletingLargeIndexes: boolean;
462
+ allowUnstagingSchema: boolean;
461
463
  message: string | null;
462
464
  },
463
465
  ) {
@@ -504,7 +506,14 @@ export async function deployToDeployment(
504
506
  writePushRequest: options.writePushRequest,
505
507
  liveComponentSources: !!options.liveComponentSources,
506
508
  pushAllModules: !!options.pushAllModules,
507
- largeIndexDeletionCheck: options.allowDeletingLargeIndexes
509
+ largeIndexDeletionCheck:
510
+ options.skipLargeIndexesCheck || options.allowDeletingLargeIndexes
511
+ ? "has confirmation"
512
+ : "ask for confirmation",
513
+ largeIndexBackfillCheck: options.skipLargeIndexesCheck
514
+ ? "has confirmation"
515
+ : "ask for confirmation",
516
+ stagedValidatorDeletionCheck: options.allowUnstagingSchema
508
517
  ? "has confirmation"
509
518
  : "ask for confirmation",
510
519
  warnOnSlowSchemaValidation: true,
@@ -10,6 +10,7 @@ import { looseObject } from "./utils.js";
10
10
  export const tableValidationOutcome = z.enum([
11
11
  "notValidated",
12
12
  "supersetOfEnforced",
13
+ "supersetOfStagedValidated",
13
14
  "supersetOfShape",
14
15
  "mustWalk",
15
16
  ]);
@@ -24,11 +25,26 @@ export const indexChangePrediction = z.enum([
24
25
  ]);
25
26
  export type IndexChangePrediction = z.infer<typeof indexChangePrediction>;
26
27
 
28
+ // Mirrors `StagedValidatorState` in
29
+ // `crates/application/src/deploy_config.rs`.
30
+ export const stagedValidatorState = z.union([
31
+ looseObject({
32
+ state: z.literal("pending"),
33
+ numDocsValidated: z.number(),
34
+ totalDocs: z.number().nullable().optional(),
35
+ }),
36
+ looseObject({ state: z.literal("valid") }),
37
+ looseObject({ state: z.literal("failed"), error: z.string() }),
38
+ ]);
39
+ export type StagedValidatorState = z.infer<typeof stagedValidatorState>;
40
+
27
41
  export const tablePrediction = looseObject({
28
42
  name: z.string(),
29
43
  outcome: tableValidationOutcome,
30
44
  numDocs: z.number(),
31
45
  sizeBytes: z.number(),
46
+ staged: stagedValidatorState.optional(),
47
+ canSkipAfterStagedValidation: z.boolean().optional(),
32
48
  });
33
49
  export type TablePrediction = z.infer<typeof tablePrediction>;
34
50
 
@@ -42,11 +58,30 @@ export const indexPrediction = z.intersection(
42
58
  );
43
59
  export type IndexPrediction = z.infer<typeof indexPrediction>;
44
60
 
61
+ // Mirrors `SerializedDiscardedStagedValidator` in
62
+ // `crates/local_backend/src/deploy_config2.rs`. The backend never discards a
63
+ // failed validator, since a redeploy retries it anyway.
64
+ export const discardedStagedValidator = looseObject({
65
+ tableName: z.string(),
66
+ state: z.union([
67
+ looseObject({
68
+ state: z.literal("pending"),
69
+ numDocsValidated: z.number(),
70
+ totalDocs: z.number().nullable().optional(),
71
+ }),
72
+ looseObject({ state: z.literal("valid") }),
73
+ ]),
74
+ replaced: z.boolean(),
75
+ });
76
+ export type DiscardedStagedValidator = z.infer<typeof discardedStagedValidator>;
77
+
45
78
  export const componentSchemaPrediction = looseObject({
46
79
  definitionPath: z.string(),
47
80
  schemaValidation: z.boolean(),
48
81
  tables: z.array(tablePrediction),
49
82
  indexes: z.array(indexPrediction),
83
+ // Optional: responses from backends predating the field.
84
+ discardedStagedValidators: z.array(discardedStagedValidator).optional(),
50
85
  });
51
86
  export type ComponentSchemaPrediction = z.infer<
52
87
  typeof componentSchemaPrediction
@@ -60,6 +60,7 @@ export async function devAgainstDeployment(
60
60
  debugNodeApis: boolean;
61
61
  liveComponentSources: boolean;
62
62
  pushAllModules: boolean;
63
+ allowUnstagingSchema: boolean;
63
64
  },
64
65
  ) {
65
66
  const logManager = new LogManager(devOptions.tailLogs);
@@ -148,6 +149,19 @@ export async function devAgainstDeployment(
148
149
  pushAllModules: devOptions.pushAllModules,
149
150
  logManager, // Pass logManager to control logs during deploy
150
151
  largeIndexDeletionCheck: "no verification", // `convex dev` can’t push to prod
152
+ // `convex dev --prod` pushes straight to production, where an
153
+ // unstaged index on a large table blocks the push for the whole
154
+ // backfill; dev deployments are small enough to let it through.
155
+ largeIndexBackfillCheck:
156
+ credentials.deploymentType === "prod"
157
+ ? "ask for confirmation"
158
+ : "no verification",
159
+ stagedValidatorDeletionCheck:
160
+ credentials.deploymentType === "prod"
161
+ ? devOptions.allowUnstagingSchema
162
+ ? "has confirmation"
163
+ : "ask for confirmation"
164
+ : "no verification",
151
165
  warnOnSlowSchemaValidation: true,
152
166
  message: null,
153
167
  },
@@ -0,0 +1,35 @@
1
+ import { chalkStderr } from "chalk";
2
+ import { DiscardedStagedValidator } from "./deployApi/evaluateSchema.js";
3
+
4
+ export function formatValidationProgress({
5
+ numDocsValidated,
6
+ totalDocs,
7
+ }: {
8
+ numDocsValidated: number;
9
+ totalDocs?: number | null | undefined;
10
+ }): string {
11
+ const checked = numDocsValidated.toLocaleString();
12
+ return totalDocs === null || totalDocs === undefined
13
+ ? `${checked} documents checked`
14
+ : `${checked} of approximately ${totalDocs.toLocaleString()} documents checked`;
15
+ }
16
+
17
+ /** "validated; the push removes the staged validator" */
18
+ export function formatDiscardedStagedValidator(
19
+ validator: DiscardedStagedValidator,
20
+ ): string {
21
+ let status;
22
+ switch (validator.state.state) {
23
+ case "pending": {
24
+ status = `validating in the background (${formatValidationProgress(validator.state)})`;
25
+ break;
26
+ }
27
+ case "valid":
28
+ status = chalkStderr.green("validated");
29
+ break;
30
+ }
31
+ const action = validator.replaced
32
+ ? "the push stages a different validator"
33
+ : "the push removes the staged validator";
34
+ return `${status}; ${action}`;
35
+ }
@@ -27,7 +27,7 @@ export type LargeIndexDeletionCheck =
27
27
  | "no verification"
28
28
  // If large indexes are being deleted, ask for confirmation (and fail in non-interactive envs)
29
29
  | "ask for confirmation"
30
- // If large indexes are being deleted, confirm (the user has used --allow-deleting-large-indexes)
30
+ // If large indexes are being deleted, confirm (the user has used --skip-large-indexes-check)
31
31
  | "has confirmation";
32
32
 
33
33
  export function addProgressLinkIfSlow(
@@ -12,13 +12,22 @@ const envListInputSchema = z.object({
12
12
  .describe(
13
13
  "Deployment selector (from the status tool) to list environment variables from.",
14
14
  ),
15
+ includeValues: z
16
+ .boolean()
17
+ .optional()
18
+ .describe(
19
+ "Also return each variable's value. Values are often secrets like API keys, so leave this off unless you need every value, and use envGet to read a single variable instead.",
20
+ ),
15
21
  });
16
22
 
17
23
  const envListOutputSchema = z.object({
18
24
  variables: z.array(
19
25
  z.object({
20
26
  name: z.string(),
21
- value: z.string(),
27
+ value: z
28
+ .string()
29
+ .optional()
30
+ .describe("Only present when includeValues is true."),
22
31
  }),
23
32
  ),
24
33
  });
@@ -28,7 +37,8 @@ export const EnvListTool: ConvexTool<
28
37
  typeof envListOutputSchema
29
38
  > = {
30
39
  name: "envList",
31
- description: "List all environment variables in your Convex deployment.",
40
+ description:
41
+ "List the names of all environment variables in your Convex deployment. Values are left out unless includeValues is true.",
32
42
  inputSchema: envListInputSchema,
33
43
  outputSchema: envListOutputSchema,
34
44
  handler: async (ctx, args) => {
@@ -51,7 +61,11 @@ export const EnvListTool: ConvexTool<
51
61
  componentPath: undefined,
52
62
  args: {},
53
63
  })) as EnvVar[];
54
- return { variables };
64
+ return {
65
+ variables: variables.map(({ name, value }) =>
66
+ args.includeValues ? { name, value } : { name },
67
+ ),
68
+ };
55
69
  },
56
70
  };
57
71
 
@@ -535,6 +535,8 @@ export async function pushToDeployment(
535
535
  liveComponentSources: args.liveComponentSources,
536
536
  pushAllModules: false,
537
537
  largeIndexDeletionCheck: "no verification", // `convex run` can’t push to prod
538
+ largeIndexBackfillCheck: "no verification", // ditto
539
+ stagedValidatorDeletionCheck: "no verification", // ditto
538
540
  warnOnSlowSchemaValidation: true,
539
541
  message: null,
540
542
  },
@@ -0,0 +1,88 @@
1
+ import { Context } from "../../bundler/context.js";
2
+ import { logVerbose } from "../../bundler/log.js";
3
+ import { EvaluateSchemaResponse } from "./deployApi/evaluateSchema.js";
4
+ import { StartPushRequest } from "./deployApi/startPush.js";
5
+ import { evaluateSchema } from "./deploy2.js";
6
+ import { Span } from "./tracing.js";
7
+
8
+ type EvaluateOptions = {
9
+ url: string;
10
+ deploymentName: string | null;
11
+ adminKey: string;
12
+ };
13
+
14
+ /**
15
+ * A schema evaluation shared by the pre-push checks. Resolves to `null` when
16
+ * the deployment doesn't support `evaluate_schema` or the request failed, in
17
+ * which case each check skips itself.
18
+ */
19
+ export type SchemaEvaluation = (
20
+ span: Span,
21
+ ) => Promise<EvaluateSchemaResponse | null>;
22
+
23
+ /**
24
+ * Evaluate the schema at most once per push however many checks consume it:
25
+ * the first check to call sends the request under its own span, and the rest
26
+ * await the same promise. Each request makes the backend evaluate the schema
27
+ * module in an isolate and predict against a fresh snapshot, so repeating it
28
+ * per check would add that work and a round trip to the deploy's critical
29
+ * path for every check.
30
+ */
31
+ /**
32
+ * Whether a schema module in the push calls `.staged(`. Bundles aren't
33
+ * minified, so the call survives bundling. A false positive from a comment or
34
+ * string costs one evaluation, while a push without staged validators skips
35
+ * the evaluation round trip on its critical path.
36
+ */
37
+ export function pushStagesValidators(request: StartPushRequest): boolean {
38
+ return [
39
+ request.appDefinition.schema,
40
+ ...request.componentDefinitions.map((definition) => definition.schema),
41
+ ].some((schema) => schema?.source.includes(".staged(") ?? false);
42
+ }
43
+
44
+ export function sharedSchemaEvaluation(
45
+ ctx: Context,
46
+ request: StartPushRequest,
47
+ options: EvaluateOptions,
48
+ ): SchemaEvaluation {
49
+ let evaluation: Promise<EvaluateSchemaResponse | null> | undefined;
50
+ return (span) => {
51
+ evaluation ??= evaluateSchemaBestEffort({ ctx, span, request, options });
52
+ return evaluation;
53
+ };
54
+ }
55
+
56
+ // The checks are advisory: if evaluation fails, fall back to skipping them
57
+ // rather than aborting the push over a check that isn't required for
58
+ // correctness. Plausibly transient failures — network errors and 5xx
59
+ // responses (e.g. table summaries still bootstrapping) — are retried with
60
+ // backoff by the shared fetch wrapper (see `pushCode`); anything else is
61
+ // deterministic, including a 2xx whose shape the CLI doesn't recognize, so
62
+ // it skips the checks immediately.
63
+ async function evaluateSchemaBestEffort({
64
+ ctx,
65
+ span,
66
+ request,
67
+ options,
68
+ }: {
69
+ ctx: Context;
70
+ span: Span;
71
+ request: StartPushRequest;
72
+ options: EvaluateOptions;
73
+ }): Promise<EvaluateSchemaResponse | null> {
74
+ try {
75
+ return await evaluateSchema(
76
+ ctx,
77
+ span,
78
+ request,
79
+ options,
80
+ /* bestEffort */ true,
81
+ );
82
+ } catch (error: unknown) {
83
+ logVerbose(
84
+ `Skipping schema evaluation checks: ${error instanceof Error ? error.message : String(error)}`,
85
+ );
86
+ return null;
87
+ }
88
+ }
@@ -21,6 +21,7 @@ export const USAGE_LIMIT_METRICS = [
21
21
  "databaseIoGb",
22
22
  "searchQueryGb",
23
23
  "dataEgressGb",
24
+ "aiGatewayCostDollars",
24
25
  ] as const satisfies readonly UsageLimitMetric[];
25
26
 
26
27
  // Fails to compile if the backend's `UsageLimitMetric` gains a metric not listed
@@ -47,6 +48,7 @@ export const METRIC_LABELS: Record<UsageLimitMetric, string> = {
47
48
  databaseIoGb: "Database I/O",
48
49
  searchQueryGb: "Search queries",
49
50
  dataEgressGb: "Data egress",
51
+ aiGatewayCostDollars: "AI Gateway",
50
52
  };
51
53
 
52
54
  export function metricLabel(metric: string): string {
@@ -1,32 +1,14 @@
1
1
  export class Mutex {
2
- currentlyRunning: Promise<void> | null = null;
3
- waiting: Array<() => Promise<void>> = [];
2
+ private tail: Promise<void> = Promise.resolve();
4
3
 
5
4
  async runExclusive<T>(fn: () => Promise<T>): Promise<T> {
6
- const outerPromise = new Promise<T>((resolve, reject) => {
7
- const wrappedCallback: () => Promise<void> = () => {
8
- return fn()
9
- .then((v: T) => resolve(v))
10
- .catch((e: any) => reject(e));
11
- };
12
- this.enqueueCallbackForMutex(wrappedCallback);
13
- });
14
- return outerPromise;
15
- }
16
-
17
- private enqueueCallbackForMutex(callback: () => Promise<void>) {
18
- if (this.currentlyRunning === null) {
19
- this.currentlyRunning = callback().finally(() => {
20
- const nextCb = this.waiting.shift();
21
- if (nextCb === undefined) {
22
- this.currentlyRunning = null;
23
- } else {
24
- this.enqueueCallbackForMutex(nextCb);
25
- }
26
- });
27
- this.waiting.length = 0;
28
- } else {
29
- this.waiting.push(callback);
30
- }
5
+ const result = this.tail.then(fn);
6
+ // Reserve the next position before running fn, and allow the queue to
7
+ // continue even if fn rejects or throws synchronously.
8
+ this.tail = result.then(
9
+ () => {},
10
+ () => {},
11
+ );
12
+ return result;
31
13
  }
32
14
  }