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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "convex",
3
3
  "description": "Client for the Convex Cloud",
4
- "version": "1.46.0",
4
+ "version": "1.47.0",
5
5
  "author": "Convex, Inc. <no-reply@convex.dev>",
6
6
  "homepage": "https://convex.dev",
7
7
  "repository": {
@@ -204,7 +204,7 @@
204
204
  "@babel/types": "^7.27.1",
205
205
  "@clerk/react": "^6.4.3",
206
206
  "@commander-js/extra-typings": "^14.0.0",
207
- "@convex-dev/platform": "0.1.10",
207
+ "@convex-dev/platform": "0.1.11",
208
208
  "@eslint/compat": "~2.0.0",
209
209
  "@eslint/eslintrc": "^3",
210
210
  "@eslint/js": "~9.39.0",
@@ -228,7 +228,7 @@
228
228
  "@types/serve-handler": "~6.1.4",
229
229
  "@types/ws": "^8.5.13",
230
230
  "@vitest/eslint-plugin": "~1.6.0",
231
- "adm-zip": "^0.6.0",
231
+ "adm-zip": "^0.6.1",
232
232
  "bufferutil": "^4.0.7",
233
233
  "chalk": "5",
234
234
  "chokidar": "3.6.0",
@@ -269,7 +269,7 @@
269
269
  "typedoc": "^0.24.6",
270
270
  "typescript": "~5.0.3",
271
271
  "typescript-eslint": "~8.57.0",
272
- "undici": "7.29.0",
272
+ "undici": "7.29.1",
273
273
  "vitest": "^4.1.0",
274
274
  "wait-for-expect": "~4.0.0",
275
275
  "zod": "^3.24.0",
@@ -280,7 +280,7 @@
280
280
  "node": ">=20.0.0"
281
281
  },
282
282
  "scripts": {
283
- "build": "npm run generateApiSpec && python3 scripts/build.py 2>&1",
283
+ "build": "npm run generateApiSpec && uv run --script scripts/build.py 2>&1",
284
284
  "bundle-server": "node scripts/bundle-server.mjs",
285
285
  "clean": "shx rm -rf dist tmpDist*",
286
286
  "lint": "eslint . --cache",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "description": "Configuration schema for Convex project settings.\n\nDocumentation: https://docs.convex.dev/production/project-configuration#convexjson",
3
+ "description": "Configuration schema for Convex project settings.\n\nDocumentation: https://docs.convex.dev/config/convex.json",
4
4
  "type": "object",
5
5
  "definitions": {
6
6
  "authKitConfigureSettings": {
@@ -123,7 +123,7 @@
123
123
  },
124
124
  "nodeVersion": {
125
125
  "type": "string",
126
- "description": "The Node.js version to use for Node.js actions. The currently supported values are '20', '22', and '24'.\n\nDocumentation: https://docs.convex.dev/production/project-configuration#configuring-the-nodejs-version",
126
+ "description": "The Node.js version to use for Node.js actions. The currently supported values are '20', '22', and '24'.\n\nDocumentation: https://docs.convex.dev/config/convex.json#configuring-the-nodejs-version",
127
127
  "default": "20"
128
128
  }
129
129
  }
@@ -135,7 +135,7 @@
135
135
  },
136
136
  "functions": {
137
137
  "type": "string",
138
- "description": "Path to the directory containing Convex functions. You can customize this to use a different location than the default 'convex/' directory.\n\nDocumentation: https://docs.convex.dev/production/project-configuration#changing-the-convex-folder-name-or-location",
138
+ "description": "Path to the directory containing Convex functions. You can customize this to use a different location than the default 'convex/' directory.\n\nDocumentation: https://docs.convex.dev/config/convex.json#changing-the-convex-folder-name-or-location",
139
139
  "default": "convex/"
140
140
  },
141
141
  "codegen": {
@@ -155,12 +155,12 @@
155
155
  },
156
156
  "staticApi": {
157
157
  "type": "boolean",
158
- "description": "When true, generates static `api.d.ts` files, which improves autocomplete and incremental typechecking performance in large codebases.\n\nDocumentation: https://docs.convex.dev/production/project-configuration#using-static-code-generation-beta",
158
+ "description": "When true, generates static `api.d.ts` files, which improves autocomplete and incremental typechecking performance in large codebases.\n\nDocumentation: https://docs.convex.dev/config/convex.json#using-static-code-generation-beta",
159
159
  "default": false
160
160
  },
161
161
  "staticDataModel": {
162
162
  "type": "boolean",
163
- "description": "When true, generates static `dataModel.d.ts` files, which improves autocomplete and incremental typechecking performance in large codebases.\n\nDocumentation: https://docs.convex.dev/production/project-configuration#using-static-code-generation-beta",
163
+ "description": "When true, generates static `dataModel.d.ts` files, which improves autocomplete and incremental typechecking performance in large codebases.\n\nDocumentation: https://docs.convex.dev/config/convex.json#using-static-code-generation-beta",
164
164
  "default": false
165
165
  }
166
166
  }
@@ -205,6 +205,7 @@ export async function bundle({
205
205
  modules: Bundle[];
206
206
  externalDependencies: Map<string, string>;
207
207
  bundledModuleNames: Set<string>;
208
+ metafile: esbuild.Metafile | null;
208
209
  }> {
209
210
  const availableExternalPackages = await computeExternalPackages(
210
211
  ctx,
@@ -264,6 +265,7 @@ export async function bundle({
264
265
  result.externalModuleNames,
265
266
  ),
266
267
  bundledModuleNames: result.bundledModuleNames,
268
+ metafile: result.metafile ?? null,
267
269
  };
268
270
  }
269
271
 
@@ -321,10 +323,13 @@ export async function bundleSchema(
321
323
  platform: "browser",
322
324
  extraConditions,
323
325
  });
324
- return result.modules;
326
+ return { modules: result.modules, metafile: result.metafile };
325
327
  }
326
328
 
327
- export async function bundleAuthConfig(ctx: Context, dir: string) {
329
+ export async function bundleAuthConfig(
330
+ ctx: Context,
331
+ dir: string,
332
+ ): Promise<{ modules: Bundle[]; metafile: esbuild.Metafile | null }> {
328
333
  const authConfigPath = path.resolve(dir, "auth.config.js");
329
334
  const authConfigTsPath = path.resolve(dir, "auth.config.ts");
330
335
  if (ctx.fs.exists(authConfigPath) && ctx.fs.exists(authConfigTsPath)) {
@@ -343,7 +348,7 @@ export async function bundleAuthConfig(ctx: Context, dir: string) {
343
348
  `Found no auth config file at ${authConfigTsPath} or ${authConfigPath} so there are no configured auth providers`,
344
349
  ),
345
350
  );
346
- return [];
351
+ return { modules: [], metafile: null };
347
352
  }
348
353
  logVerbose(chalkStderr.yellow(`Bundling auth config found at ${chosenPath}`));
349
354
  const result = await bundle({
@@ -355,7 +360,7 @@ export async function bundleAuthConfig(ctx: Context, dir: string) {
355
360
  // The auth config must be one module
356
361
  splitting: false,
357
362
  });
358
- return result.modules;
363
+ return { modules: result.modules, metafile: result.metafile };
359
364
  }
360
365
 
361
366
  export async function doesImportConvexHttpRouter(source: string) {
@@ -67,8 +67,6 @@ export const codegen = new Command("codegen")
67
67
  liveComponentSources: !!options.liveComponentSources,
68
68
  debugNodeApis: false,
69
69
  systemUdfs: !!options.systemUdfs,
70
- largeIndexDeletionCheck: "no verification" as const, // `codegen` is a read-only operation
71
- warnOnSlowSchemaValidation: false, // ditto: a codegen dry run never deploys
72
70
  codegenOnlyThisComponent: options.componentDir,
73
71
  };
74
72
 
@@ -122,17 +122,22 @@ export async function deploymentCredentialsOrConfigure(
122
122
  chosenConfiguration,
123
123
  cmdOptions,
124
124
  );
125
- const { convexSiteUrl: siteUrl } = await fetchDeploymentCanonicalUrls(ctx, {
126
- adminKey: selectedDeployment.adminKey,
127
- deploymentUrl: selectedDeployment.url,
128
- });
125
+ const { convexCloudUrl, convexSiteUrl: siteUrl } =
126
+ await fetchDeploymentCanonicalUrls(ctx, {
127
+ adminKey: selectedDeployment.adminKey,
128
+ deploymentUrl: selectedDeployment.url,
129
+ });
130
+ const applicationUrl = deploymentUrlForApplicationEnv(
131
+ selectedDeployment,
132
+ convexCloudUrl,
133
+ );
129
134
 
130
135
  if (selectedDeployment.deploymentFields !== null) {
131
136
  // Set the `CONVEX_DEPLOYMENT` env var + the `CONVEX_URL` env var
132
137
  await updateEnvAndConfigForDeploymentSelection(
133
138
  ctx,
134
139
  {
135
- url: selectedDeployment.url,
140
+ url: applicationUrl,
136
141
  siteUrl,
137
142
  deploymentName: selectedDeployment.deploymentFields.deploymentName,
138
143
  teamSlug: selectedDeployment.deploymentFields.teamSlug,
@@ -160,6 +165,21 @@ export async function deploymentCredentialsOrConfigure(
160
165
  };
161
166
  }
162
167
 
168
+ export function deploymentUrlForApplicationEnv(
169
+ selectedDeployment: {
170
+ url: string;
171
+ deploymentFields: { deploymentType: DeploymentType } | null;
172
+ },
173
+ canonicalCloudUrl: string,
174
+ ): string {
175
+ const deploymentType = selectedDeployment.deploymentFields?.deploymentType;
176
+ return deploymentType !== undefined &&
177
+ deploymentType !== "local" &&
178
+ deploymentType !== "anonymous"
179
+ ? canonicalCloudUrl
180
+ : selectedDeployment.url;
181
+ }
182
+
163
183
  export async function _deploymentCredentialsOrConfigure(
164
184
  ctx: Context,
165
185
  deploymentSelection: DeploymentSelection,
@@ -608,14 +628,14 @@ async function selectExistingProject(
608
628
  devDeployment: "cloud" | "local";
609
629
  }> {
610
630
  const {
611
- team: { slug: teamSlug },
631
+ team: { id: teamId, slug: teamSlug },
612
632
  chosen,
613
633
  } = await validateOrSelectTeam(ctx, config.team, "Team:");
614
634
 
615
635
  const projectSlug = await validateOrSelectProject(
616
636
  ctx,
617
637
  config.project,
618
- teamSlug,
638
+ teamId,
619
639
  "Configure project",
620
640
  "Project:",
621
641
  );
package/src/cli/deploy.ts CHANGED
@@ -111,10 +111,23 @@ Same format as .env.local or .env files, and overrides them.`,
111
111
  ).hideHelp(),
112
112
  )
113
113
  .addOption(
114
- new Option("--allow-deleting-large-indexes")
115
- .hideHelp()
116
- .conflicts("preview-create")
117
- .conflicts("preview-name"),
114
+ new Option(
115
+ "--skip-large-indexes-check",
116
+ "Skip the confirmation prompt when this push creates, changes, or deletes an index on a large table. Creating or changing an index blocks the deploy until it is backfilled; consider staging it instead so it backfills in the background.",
117
+ ),
118
+ )
119
+ .addOption(
120
+ // Predecessor of --skip-large-indexes-check, kept hidden so existing
121
+ // deploy scripts keep working. It still skips only the deletion
122
+ // confirmation: scripts that opted into that never agreed to let a
123
+ // blocking backfill through.
124
+ new Option("--allow-deleting-large-indexes").hideHelp(),
125
+ )
126
+ .addOption(
127
+ new Option(
128
+ "--allow-unstaging-schema",
129
+ "Skip the confirmation prompt when this push discards a staged table validator that is validating or already validated.",
130
+ ),
118
131
  )
119
132
  .showHelpAfterError()
120
133
  .action(async (cmdOptions) => {
@@ -181,6 +194,7 @@ Same format as .env.local or .env files, and overrides them.`,
181
194
  ...cmdOptions,
182
195
  previewName: previewName ?? undefined,
183
196
  reuse,
197
+ skipLargeIndexesCheck: cmdOptions.skipLargeIndexesCheck ?? false,
184
198
  message: cmdOptions.message ?? getDefaultDeployMessage(),
185
199
  },
186
200
  );
@@ -204,8 +218,10 @@ Same format as .env.local or .env files, and overrides them.`,
204
218
  await deployToExistingDeployment(ctx, deploymentSelection, {
205
219
  ...cmdOptions,
206
220
  skipWorkosCheck: cmdOptions.skipWorkosCheck ?? false,
221
+ skipLargeIndexesCheck: cmdOptions.skipLargeIndexesCheck ?? false,
207
222
  allowDeletingLargeIndexes:
208
223
  cmdOptions.allowDeletingLargeIndexes ?? false,
224
+ allowUnstagingSchema: cmdOptions.allowUnstagingSchema ?? false,
209
225
  message: cmdOptions.message ?? getDefaultDeployMessage(),
210
226
  });
211
227
  }
@@ -237,6 +253,7 @@ async function deployToNewPreviewDeployment(
237
253
  debug?: boolean | undefined;
238
254
  debugBundlePath?: string | undefined;
239
255
  skipWorkosCheck?: boolean | undefined;
256
+ skipLargeIndexesCheck: boolean;
240
257
  message: string | null;
241
258
  },
242
259
  ) {
@@ -319,7 +336,8 @@ async function deployToNewPreviewDeployment(
319
336
  });
320
337
 
321
338
  const pushOptions: PushOptions = {
322
- deploymentName: null,
339
+ deploymentName: data.deploymentName,
340
+ deploymentType: "preview",
323
341
  adminKey: previewAdminKey,
324
342
  verbose: !!options.verbose,
325
343
  dryRun: false,
@@ -333,6 +351,17 @@ async function deployToNewPreviewDeployment(
333
351
  liveComponentSources: false,
334
352
  pushAllModules: !!options.pushAllModules,
335
353
  largeIndexDeletionCheck: "no verification", // fine for preview deployments
354
+ // A freshly claimed preview has no data to backfill. A reused one keeps
355
+ // the data earlier pushes wrote, so an unstaged index there can block
356
+ // the deploy like on any other deployment.
357
+ largeIndexBackfillCheck: data.isNewDeployment
358
+ ? "no verification"
359
+ : options.skipLargeIndexesCheck
360
+ ? "has confirmation"
361
+ : "ask for confirmation",
362
+ // Staged validation on throwaway preview data is cheap to redo, so
363
+ // discarding it needs no confirmation.
364
+ stagedValidatorDeletionCheck: "no verification",
336
365
  warnOnSlowSchemaValidation: true,
337
366
  message: options.message,
338
367
  };
@@ -378,7 +407,9 @@ async function deployToExistingDeployment(
378
407
  liveComponentSources?: boolean | undefined;
379
408
  envFile?: string | undefined;
380
409
  skipWorkosCheck?: boolean | undefined;
410
+ skipLargeIndexesCheck: boolean;
381
411
  allowDeletingLargeIndexes: boolean;
412
+ allowUnstagingSchema: boolean;
382
413
  message: string | null;
383
414
  },
384
415
  ) {
@@ -12,7 +12,10 @@ import {
12
12
  parseDeploymentSelector,
13
13
  ParsedDeploymentSelector,
14
14
  } from "./lib/deploymentSelector.js";
15
- import { updateEnvAndConfigForDeploymentSelection } from "./configure.js";
15
+ import {
16
+ deploymentUrlForApplicationEnv,
17
+ updateEnvAndConfigForDeploymentSelection,
18
+ } from "./configure.js";
16
19
  import { fetchDeploymentCanonicalUrls } from "./lib/deploy2.js";
17
20
  import {
18
21
  loadProjectLocalConfig,
@@ -267,9 +270,9 @@ export async function saveSelectedDeployment(
267
270
  });
268
271
  }
269
272
 
270
- const { convexSiteUrl: siteUrl } =
273
+ const { convexCloudUrl, convexSiteUrl: siteUrl } =
271
274
  deployment.deploymentFields.deploymentType === "local"
272
- ? { convexSiteUrl: null }
275
+ ? { convexCloudUrl: deployment.url, convexSiteUrl: null }
273
276
  : await fetchDeploymentCanonicalUrls(ctx, {
274
277
  adminKey: deployment.adminKey,
275
278
  deploymentUrl: deployment.url,
@@ -278,7 +281,7 @@ export async function saveSelectedDeployment(
278
281
  await updateEnvAndConfigForDeploymentSelection(
279
282
  ctx,
280
283
  {
281
- url: deployment.url,
284
+ url: deploymentUrlForApplicationEnv(deployment, convexCloudUrl),
282
285
  siteUrl,
283
286
  deploymentName: deployment.deploymentFields.deploymentName,
284
287
  teamSlug: deployment.deploymentFields.teamSlug,
package/src/cli/dev.ts CHANGED
@@ -143,6 +143,15 @@ export const dev = new Command("dev")
143
143
  .default(false)
144
144
  .hideHelp(),
145
145
  )
146
+ .addOption(
147
+ // Only `--prod` pushes check this; hidden alongside it.
148
+ new Option(
149
+ "--allow-unstaging-schema",
150
+ "Skip the confirmation prompt when a push to production discards a staged table validator that is validating or already validated.",
151
+ )
152
+ .default(false)
153
+ .hideHelp(),
154
+ )
146
155
  .addOption(
147
156
  new Option(
148
157
  "--env-file <envFile>",
package/src/cli/env.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Command } from "@commander-js/extra-typings";
1
+ import { Command, Option } from "@commander-js/extra-typings";
2
2
  import { chalkStderr } from "chalk";
3
3
  import { Context, oneoffContext } from "../bundler/context.js";
4
4
  import {
@@ -43,7 +43,7 @@ const envSetCmd = new Command("set")
43
43
  "• `pbpaste | npx convex env set API_KEY` (macOS)",
44
44
  "• `Get-Clipboard | npx convex env set API_KEY` (Windows PowerShell)",
45
45
  "",
46
- "To update many variables at once, save them with `npx convex env list > .env.convex`, edit the file, then reapply the changes with `npx convex env set --force < .env.convex`.",
46
+ "To update many variables at once, save them with `npx convex env list --include-values > .env.convex`, edit the file, then reapply the changes with `npx convex env set --force < .env.convex`.",
47
47
  ].join("\n"),
48
48
  )
49
49
  .option(
@@ -167,16 +167,22 @@ const envListCmd = new Command("list")
167
167
  .summary("List all environment variables and their values")
168
168
  .description(
169
169
  [
170
- "• List all variables and their values: `npx convex env list`",
171
170
  "• List only variable names (no values): `npx convex env list --names-only`",
172
- "• Save all variables to a file: `npx convex env list > .env.convex`",
173
- "• Append to a file: `npx convex env list >> .env.convex`",
171
+ "• List all variables and their values: `npx convex env list --include-values`",
172
+ "• Save all variables to a file: `npx convex env list --include-values > .env.convex`",
173
+ "• Append to a file: `npx convex env list --include-values >> .env.convex`",
174
174
  ].join("\n"),
175
175
  )
176
176
  .option(
177
177
  "--names-only",
178
178
  "List only the names of environment variables, without their values",
179
179
  )
180
+ .addOption(
181
+ new Option(
182
+ "--include-values",
183
+ "Print each variable's value alongside its name, in .env format (the default). Pass it explicitly in scripts that rely on the values.",
184
+ ).conflicts("namesOnly"),
185
+ )
180
186
  .configureHelp({ showGlobalOptions: true })
181
187
  .allowExcessArguments(false)
182
188
  .action(async (cmdOptions, cmd) => {
@@ -207,8 +213,8 @@ export const env = new Command("env")
207
213
  "• Set interactively: `npx convex env set NAME`",
208
214
  "• Set multiple from file: `npx convex env set --from-file .env`",
209
215
  "• Unset a variable: `npx convex env remove NAME`",
210
- "• List all variables and their values: `npx convex env list`",
211
216
  "• List only variable names (no values): `npx convex env list --names-only`",
217
+ "• List all variables and their values: `npx convex env list --include-values`",
212
218
  "• Print a variable's value: `npx convex env get NAME`",
213
219
  "",
214
220
  "By default, this sets and views variables on your dev deployment.",
@@ -144,8 +144,8 @@ const envDefaultList = addEnvDefaultOptions(
144
144
  .summary("List all default environment variables and their values")
145
145
  .description(
146
146
  [
147
- "• List all default variables and their values: `npx convex env default list`",
148
147
  "• List only default variable names (no values): `npx convex env default list --names-only`",
148
+ "• List all default variables and their values: `npx convex env default list --include-values`",
149
149
  "",
150
150
  "The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.",
151
151
  ].join("\n"),
@@ -154,6 +154,12 @@ const envDefaultList = addEnvDefaultOptions(
154
154
  "--names-only",
155
155
  "List only the names of environment variables, without their values",
156
156
  )
157
+ .addOption(
158
+ new Option(
159
+ "--include-values",
160
+ "Print each variable's value alongside its name, in .env format (the default). Pass it explicitly in scripts that rely on the values.",
161
+ ).conflicts("namesOnly"),
162
+ )
157
163
  .configureHelp({ showGlobalOptions: true })
158
164
  .allowExcessArguments(false),
159
165
  ).action(async (cmdOptions, cmd) => {
@@ -176,8 +182,8 @@ export const envDefault = new Command("default")
176
182
  "",
177
183
  "• Set a default variable: `npx convex env default set NAME 'value'`",
178
184
  "• Unset a default variable: `npx convex env default remove NAME`",
179
- "• List all default variables and their values: `npx convex env default list`",
180
185
  "• List only default variable names (no values): `npx convex env default list --names-only`",
186
+ "• List all default variables and their values: `npx convex env default list --include-values`",
181
187
  "• Print a default variable's value: `npx convex env default get NAME`",
182
188
  ].join("\n"),
183
189
  )
@@ -461,7 +461,7 @@ export interface components {
461
461
  };
462
462
  ReferralCode: string;
463
463
  /** @enum {string} */
464
- RegionName: "aws-us-east-1" | "aws-eu-west-1";
464
+ RegionName: "aws-us-east-1" | "aws-eu-west-1" | "aws-ca-central-1" | "aws-ap-southeast-2";
465
465
  /** Format: int64 */
466
466
  TeamId: number;
467
467
  TeamName: string;
@@ -26,6 +26,7 @@ import {
26
26
  import { loadProjectLocalConfig } from "./localDeployment/filePaths.js";
27
27
  import { chalkStderr } from "chalk";
28
28
  import { RegionName } from "../generatedApi.js";
29
+ import type { RegionName as PublishedRegionName } from "@convex-dev/platform/managementApi";
29
30
  export type DeploymentName = string;
30
31
  export type CloudDeploymentType = "prod" | "dev" | "preview" | "custom";
31
32
  export type AccountRequiredDeploymentType = CloudDeploymentType | "local";
@@ -66,7 +67,10 @@ export async function createProject(
66
67
  body: {
67
68
  projectName,
68
69
  deploymentType: deploymentToProvision?.deploymentType ?? null,
69
- deploymentRegion: deploymentToProvision?.region ?? null,
70
+ // The published platform types lag the CLI's own spec by a release,
71
+ // so the cast is deliberate: a new region needs no change here.
72
+ deploymentRegion: (deploymentToProvision?.region ??
73
+ null) as PublishedRegionName | null,
70
74
  },
71
75
  },
72
76
  );
@@ -0,0 +1,173 @@
1
+ import { chalkStderr } from "chalk";
2
+ import { Context } from "../../bundler/context.js";
3
+ import {
4
+ changeSpinner,
5
+ logFinishedStep,
6
+ logMessage,
7
+ stopSpinner,
8
+ } from "../../bundler/log.js";
9
+ import { formatIndex } from "./indexes.js";
10
+ import { promptYesNo } from "./utils/prompts.js";
11
+ import { Span } from "./tracing.js";
12
+ import {
13
+ EvaluateSchemaResponse,
14
+ IndexPrediction,
15
+ } from "./deployApi/evaluateSchema.js";
16
+ import { SchemaEvaluation } from "./schemaEvaluation.js";
17
+ import { integerFromEnv } from "./utils/utils.js";
18
+
19
+ // Same size as the large index deletion check, so both index guards fire at
20
+ // the same table size. Separate env override so tests can trigger one
21
+ // without the other.
22
+ const MIN_DOCUMENTS_FOR_INDEX_BACKFILL_WARNING = 100_000;
23
+
24
+ export type LargeIndexBackfillCheck =
25
+ // Don’t check whether the push creates indexes on large tables
26
+ | "no verification"
27
+ // If it does, ask for confirmation (and fail in non-interactive envs)
28
+ | "ask for confirmation"
29
+ // If it does, proceed (the user has used --skip-large-indexes-check)
30
+ | "has confirmation";
31
+
32
+ type BlockingIndex = {
33
+ // The component instance path ("" for the root component), matching the
34
+ // keys of `componentSchemaEvaluations`.
35
+ componentPath: string;
36
+ index: IndexPrediction;
37
+ };
38
+
39
+ /**
40
+ * Warn — and on a real deploy require confirmation — when a push creates or
41
+ * enables a non-staged index on a large table. `wait_for_schema` blocks the
42
+ * deploy until every such index is backfilled, which can take a long time on
43
+ * large tables; staging the index instead backfills it in the background.
44
+ *
45
+ * Skipped silently when the deployment doesn't support `evaluate_schema`:
46
+ * the check protects the developer's time, not correctness.
47
+ */
48
+ export async function checkForLargeIndexBackfill({
49
+ ctx,
50
+ span,
51
+ schemaEvaluation,
52
+ options,
53
+ mode,
54
+ }: {
55
+ ctx: Context;
56
+ span: Span;
57
+ schemaEvaluation: SchemaEvaluation;
58
+ options: { url: string };
59
+ // "warn" prints the warning without prompting, for dry runs.
60
+ mode: "warn" | "ask for confirmation" | "has confirmation";
61
+ }): Promise<void> {
62
+ changeSpinner("Verifying that the push isn’t creating large indexes...");
63
+ const response = await schemaEvaluation(span);
64
+ if (response === null) {
65
+ return;
66
+ }
67
+
68
+ const blockingIndexes = blockingIndexesFromSchemaEvaluation(
69
+ response,
70
+ minDocumentsForIndexBackfillWarning(),
71
+ );
72
+ if (blockingIndexes.length === 0) {
73
+ return;
74
+ }
75
+
76
+ const plural = blockingIndexes.length !== 1;
77
+ logMessage(`⚠️ This push will ${chalkStderr.bold("create")} the following ${plural ? "indexes on large tables" : "index on a large table"}
78
+ in your deployment (${options.url}). The deploy will block until ${plural ? "they finish" : "it finishes"} backfilling:
79
+
80
+ ${blockingIndexes.map(formatBlockingIndex).join("\n")}
81
+
82
+ Tip: stage the index (e.g. \`.index("by_field", { fields: ["field"], staged: true })\`) to backfill
83
+ it in the background without blocking the deploy, then remove \`staged\` in a later push once it’s ready.
84
+ Learn more at https://docs.convex.dev/database/reading-data/indexes#staged-indexes
85
+ `);
86
+
87
+ if (mode === "warn") {
88
+ return;
89
+ }
90
+
91
+ if (mode === "has confirmation") {
92
+ logFinishedStep(
93
+ "Proceeding with push since --skip-large-indexes-check is set",
94
+ );
95
+ return;
96
+ }
97
+
98
+ if (!process.stdin.isTTY) {
99
+ return ctx.crash({
100
+ exitCode: 1,
101
+ errorType: "fatal",
102
+ printedMessage: `To confirm the push:
103
+ • run the deploy command in an ${chalkStderr.bold("interactive terminal")}
104
+ • or run the deploy command with the ${chalkStderr.bold("--skip-large-indexes-check")} flag`,
105
+ });
106
+ }
107
+
108
+ stopSpinner();
109
+ if (
110
+ !(await promptYesNo(ctx, {
111
+ message: `Create ${plural ? "these indexes" : "this index"} now?`,
112
+ default: false,
113
+ }))
114
+ ) {
115
+ return ctx.crash({
116
+ exitCode: 1,
117
+ errorType: "fatal",
118
+ printedMessage: `Canceling push`,
119
+ });
120
+ }
121
+
122
+ logFinishedStep("Proceeding with push.");
123
+ }
124
+
125
+ // An index blocks the deploy when this push starts (`added`) or waits on
126
+ // (`enabled` before its staged backfill finished) a backfill that isn't
127
+ // staged. Added staged indexes report `needsBackfill` too but never block,
128
+ // and an in-progress backfill an earlier push started (`identical`) isn't
129
+ // this push's doing.
130
+ export function blockingIndexesFromSchemaEvaluation(
131
+ response: EvaluateSchemaResponse,
132
+ minDocuments: number,
133
+ ): BlockingIndex[] {
134
+ return Object.entries(response.componentSchemaEvaluations).flatMap(
135
+ ([componentPath, prediction]) =>
136
+ prediction.indexes
137
+ .filter(
138
+ (index) =>
139
+ index.needsBackfill &&
140
+ !index.staged &&
141
+ (index.change === "added" || index.change === "enabled") &&
142
+ index.numDocs >= minDocuments,
143
+ )
144
+ .map((index) => ({ componentPath, index })),
145
+ );
146
+ }
147
+
148
+ function formatBlockingIndex({ componentPath, index }: BlockingIndex) {
149
+ const componentNameFormatted =
150
+ componentPath !== "" ? `${chalkStderr.gray(componentPath)}:` : "";
151
+ const documentsCountFormatted = chalkStderr.yellowBright(
152
+ `⚠️ ${index.numDocs.toLocaleString()} documents`,
153
+ );
154
+ const enabledNote =
155
+ index.change === "enabled"
156
+ ? `\n ${chalkStderr.gray("enabled before its staged backfill finished")}`
157
+ : "";
158
+ return (
159
+ "⛔ " +
160
+ componentNameFormatted +
161
+ formatIndex(index) +
162
+ " " +
163
+ documentsCountFormatted +
164
+ enabledNote
165
+ );
166
+ }
167
+
168
+ function minDocumentsForIndexBackfillWarning(): number {
169
+ return integerFromEnv(
170
+ "CONVEX_MIN_DOCUMENTS_FOR_INDEX_BACKFILL_WARNING",
171
+ MIN_DOCUMENTS_FOR_INDEX_BACKFILL_WARNING,
172
+ );
173
+ }