convex 1.45.0 → 1.46.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 (319) hide show
  1. package/CHANGELOG.md +48 -6
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +2 -2
  4. package/dist/cjs/browser/http_client.js.map +2 -2
  5. package/dist/cjs/browser/query_options.js.map +2 -2
  6. package/dist/cjs/browser/simple_client.js.map +2 -2
  7. package/dist/cjs/browser/sync/optimistic_updates.js.map +1 -1
  8. package/dist/cjs/browser/sync/optimistic_updates_impl.js.map +2 -2
  9. package/dist/cjs/cli/codegen.js +2 -0
  10. package/dist/cjs/cli/codegen.js.map +2 -2
  11. package/dist/cjs/cli/deploy.js +1 -0
  12. package/dist/cjs/cli/deploy.js.map +2 -2
  13. package/dist/cjs/cli/docs.js +3 -36
  14. package/dist/cjs/cli/docs.js.map +2 -2
  15. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js +101 -60
  16. package/dist/cjs/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  17. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js +107 -0
  18. package/dist/cjs/cli/lib/checkForSlowSchemaValidation.js.map +7 -0
  19. package/dist/cjs/cli/lib/codegen.js.map +2 -2
  20. package/dist/cjs/cli/lib/components.js +12 -0
  21. package/dist/cjs/cli/lib/components.js.map +2 -2
  22. package/dist/cjs/cli/lib/deploy2.js +29 -2
  23. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  24. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js +73 -0
  25. package/dist/cjs/cli/lib/deployApi/evaluateSchema.js.map +7 -0
  26. package/dist/cjs/cli/lib/deployApi/finishPush.js +1 -0
  27. package/dist/cjs/cli/lib/deployApi/finishPush.js.map +2 -2
  28. package/dist/cjs/cli/lib/deployApi/startPush.js +1 -1
  29. package/dist/cjs/cli/lib/deployApi/startPush.js.map +2 -2
  30. package/dist/cjs/cli/lib/dev.js +1 -0
  31. package/dist/cjs/cli/lib/dev.js.map +2 -2
  32. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  33. package/dist/cjs/cli/lib/localDeployment/run.js +30 -1
  34. package/dist/cjs/cli/lib/localDeployment/run.js.map +2 -2
  35. package/dist/cjs/cli/lib/localDeployment/upgrade.js +6 -5
  36. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +2 -2
  37. package/dist/cjs/cli/lib/localDeployment/utils.js +5 -1
  38. package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
  39. package/dist/cjs/cli/lib/run.js +1 -0
  40. package/dist/cjs/cli/lib/run.js.map +2 -2
  41. package/dist/cjs/cli/lib/utils/utils.js +36 -29
  42. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  43. package/dist/cjs/index.js +1 -1
  44. package/dist/cjs/index.js.map +1 -1
  45. package/dist/cjs/nextjs/index.js.map +2 -2
  46. package/dist/cjs/react/client.js.map +2 -2
  47. package/dist/cjs/react/hydration.js.map +2 -2
  48. package/dist/cjs/react/queries_observer.js.map +2 -2
  49. package/dist/cjs/react/use_paginated_query2.js.map +2 -2
  50. package/dist/cjs/react/use_queries.js.map +2 -2
  51. package/dist/cjs/server/api.js.map +2 -2
  52. package/dist/cjs/server/components/index.js.map +2 -2
  53. package/dist/cjs/server/cron.js +10 -10
  54. package/dist/cjs/server/cron.js.map +2 -2
  55. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  56. package/dist/cjs/server/impl/meta_impl.js +8 -2
  57. package/dist/cjs/server/impl/meta_impl.js.map +2 -2
  58. package/dist/cjs/server/impl/scheduler_impl.js.map +2 -2
  59. package/dist/cjs/server/index.js.map +2 -2
  60. package/dist/cjs/server/meta.js.map +1 -1
  61. package/dist/cjs/server/registration.js.map +1 -1
  62. package/dist/cjs/server/scheduler.js.map +1 -1
  63. package/dist/cjs/server/schema.js +50 -3
  64. package/dist/cjs/server/schema.js.map +2 -2
  65. package/dist/cjs/values/validator.js +1 -1
  66. package/dist/cjs/values/validator.js.map +2 -2
  67. package/dist/cjs/values/validators.js +81 -25
  68. package/dist/cjs/values/validators.js.map +2 -2
  69. package/dist/cjs-types/browser/http_client.d.ts +5 -5
  70. package/dist/cjs-types/browser/http_client.d.ts.map +1 -1
  71. package/dist/cjs-types/browser/query_options.d.ts +2 -2
  72. package/dist/cjs-types/browser/query_options.d.ts.map +1 -1
  73. package/dist/cjs-types/browser/simple_client.d.ts +6 -6
  74. package/dist/cjs-types/browser/simple_client.d.ts.map +1 -1
  75. package/dist/cjs-types/browser/sync/optimistic_updates.d.ts +4 -4
  76. package/dist/cjs-types/browser/sync/optimistic_updates.d.ts.map +1 -1
  77. package/dist/cjs-types/browser/sync/optimistic_updates_impl.d.ts.map +1 -1
  78. package/dist/cjs-types/cli/codegen.d.ts.map +1 -1
  79. package/dist/cjs-types/cli/docs.d.ts.map +1 -1
  80. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts +26 -5
  81. package/dist/cjs-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  82. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts +14 -0
  83. package/dist/cjs-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -0
  84. package/dist/cjs-types/cli/lib/codegen.d.ts +1 -0
  85. package/dist/cjs-types/cli/lib/codegen.d.ts.map +1 -1
  86. package/dist/cjs-types/cli/lib/components.d.ts +1 -0
  87. package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
  88. package/dist/cjs-types/cli/lib/deploy2.d.ts +6 -0
  89. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  90. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts +453 -0
  91. package/dist/cjs-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -0
  92. package/dist/cjs-types/cli/lib/deployApi/finishPush.d.ts +1 -2
  93. package/dist/cjs-types/cli/lib/deployApi/finishPush.d.ts.map +1 -1
  94. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  95. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  96. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  97. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts +2 -0
  98. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  99. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +1 -0
  101. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/lib/run.d.ts.map +1 -1
  103. package/dist/cjs-types/cli/lib/utils/utils.d.ts +5 -5
  104. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  105. package/dist/cjs-types/index.d.ts +1 -1
  106. package/dist/cjs-types/nextjs/index.d.ts +6 -6
  107. package/dist/cjs-types/nextjs/index.d.ts.map +1 -1
  108. package/dist/cjs-types/react/client.d.ts +15 -15
  109. package/dist/cjs-types/react/client.d.ts.map +1 -1
  110. package/dist/cjs-types/react/hydration.d.ts +3 -3
  111. package/dist/cjs-types/react/hydration.d.ts.map +1 -1
  112. package/dist/cjs-types/react/queries_observer.d.ts +9 -9
  113. package/dist/cjs-types/react/queries_observer.d.ts.map +1 -1
  114. package/dist/cjs-types/react/use_paginated_query2.d.ts.map +1 -1
  115. package/dist/cjs-types/react/use_queries.d.ts +14 -6
  116. package/dist/cjs-types/react/use_queries.d.ts.map +1 -1
  117. package/dist/cjs-types/server/api.d.ts +157 -7
  118. package/dist/cjs-types/server/api.d.ts.map +1 -1
  119. package/dist/cjs-types/server/components/index.d.ts +2 -2
  120. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  121. package/dist/cjs-types/server/cron.d.ts +21 -20
  122. package/dist/cjs-types/server/cron.d.ts.map +1 -1
  123. package/dist/cjs-types/server/impl/actions_impl.d.ts +4 -4
  124. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  125. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -1
  126. package/dist/cjs-types/server/impl/scheduler_impl.d.ts.map +1 -1
  127. package/dist/cjs-types/server/index.d.ts +1 -1
  128. package/dist/cjs-types/server/index.d.ts.map +1 -1
  129. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  130. package/dist/cjs-types/server/registration.d.ts +7 -7
  131. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  132. package/dist/cjs-types/server/scheduler.d.ts +9 -7
  133. package/dist/cjs-types/server/scheduler.d.ts.map +1 -1
  134. package/dist/cjs-types/server/schema.d.ts +1 -0
  135. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  136. package/dist/cjs-types/values/validator.d.ts.map +1 -1
  137. package/dist/cjs-types/values/validators.d.ts +30 -0
  138. package/dist/cjs-types/values/validators.d.ts.map +1 -1
  139. package/dist/cli.bundle.cjs +347 -133
  140. package/dist/cli.bundle.cjs.map +4 -4
  141. package/dist/esm/browser/http_client.js.map +2 -2
  142. package/dist/esm/browser/query_options.js.map +2 -2
  143. package/dist/esm/browser/simple_client.js.map +2 -2
  144. package/dist/esm/browser/sync/optimistic_updates_impl.js.map +2 -2
  145. package/dist/esm/cli/codegen.js +2 -0
  146. package/dist/esm/cli/codegen.js.map +2 -2
  147. package/dist/esm/cli/deploy.js +1 -0
  148. package/dist/esm/cli/deploy.js.map +2 -2
  149. package/dist/esm/cli/docs.js +3 -43
  150. package/dist/esm/cli/docs.js.map +2 -2
  151. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js +100 -60
  152. package/dist/esm/cli/lib/checkForLargeIndexDeletion.js.map +2 -2
  153. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js +85 -0
  154. package/dist/esm/cli/lib/checkForSlowSchemaValidation.js.map +7 -0
  155. package/dist/esm/cli/lib/codegen.js.map +2 -2
  156. package/dist/esm/cli/lib/components.js +12 -0
  157. package/dist/esm/cli/lib/components.js.map +2 -2
  158. package/dist/esm/cli/lib/deploy2.js +30 -2
  159. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  160. package/dist/esm/cli/lib/deployApi/evaluateSchema.js +46 -0
  161. package/dist/esm/cli/lib/deployApi/evaluateSchema.js.map +7 -0
  162. package/dist/esm/cli/lib/deployApi/finishPush.js +1 -1
  163. package/dist/esm/cli/lib/deployApi/finishPush.js.map +2 -2
  164. package/dist/esm/cli/lib/deployApi/startPush.js +1 -1
  165. package/dist/esm/cli/lib/deployApi/startPush.js.map +2 -2
  166. package/dist/esm/cli/lib/dev.js +1 -0
  167. package/dist/esm/cli/lib/dev.js.map +2 -2
  168. package/dist/esm/cli/lib/localDeployment/run.js +30 -2
  169. package/dist/esm/cli/lib/localDeployment/run.js.map +2 -2
  170. package/dist/esm/cli/lib/localDeployment/upgrade.js +4 -3
  171. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  172. package/dist/esm/cli/lib/localDeployment/utils.js +3 -0
  173. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  174. package/dist/esm/cli/lib/run.js +1 -0
  175. package/dist/esm/cli/lib/run.js.map +2 -2
  176. package/dist/esm/cli/lib/utils/utils.js +36 -30
  177. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  178. package/dist/esm/index.js +1 -1
  179. package/dist/esm/index.js.map +1 -1
  180. package/dist/esm/nextjs/index.js.map +2 -2
  181. package/dist/esm/react/client.js.map +2 -2
  182. package/dist/esm/react/hydration.js +3 -1
  183. package/dist/esm/react/hydration.js.map +2 -2
  184. package/dist/esm/react/queries_observer.js +3 -1
  185. package/dist/esm/react/queries_observer.js.map +2 -2
  186. package/dist/esm/react/use_paginated_query2.js +3 -1
  187. package/dist/esm/react/use_paginated_query2.js.map +2 -2
  188. package/dist/esm/react/use_queries.js.map +2 -2
  189. package/dist/esm/server/api.js.map +2 -2
  190. package/dist/esm/server/components/index.js.map +2 -2
  191. package/dist/esm/server/cron.js +13 -11
  192. package/dist/esm/server/cron.js.map +2 -2
  193. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  194. package/dist/esm/server/impl/meta_impl.js +9 -3
  195. package/dist/esm/server/impl/meta_impl.js.map +2 -2
  196. package/dist/esm/server/impl/scheduler_impl.js.map +2 -2
  197. package/dist/esm/server/index.js.map +2 -2
  198. package/dist/esm/server/schema.js +50 -3
  199. package/dist/esm/server/schema.js.map +2 -2
  200. package/dist/esm/values/validator.js +1 -1
  201. package/dist/esm/values/validator.js.map +2 -2
  202. package/dist/esm/values/validators.js +81 -25
  203. package/dist/esm/values/validators.js.map +2 -2
  204. package/dist/esm-types/browser/http_client.d.ts +5 -5
  205. package/dist/esm-types/browser/http_client.d.ts.map +1 -1
  206. package/dist/esm-types/browser/query_options.d.ts +2 -2
  207. package/dist/esm-types/browser/query_options.d.ts.map +1 -1
  208. package/dist/esm-types/browser/simple_client.d.ts +6 -6
  209. package/dist/esm-types/browser/simple_client.d.ts.map +1 -1
  210. package/dist/esm-types/browser/sync/optimistic_updates.d.ts +4 -4
  211. package/dist/esm-types/browser/sync/optimistic_updates.d.ts.map +1 -1
  212. package/dist/esm-types/browser/sync/optimistic_updates_impl.d.ts.map +1 -1
  213. package/dist/esm-types/cli/codegen.d.ts.map +1 -1
  214. package/dist/esm-types/cli/docs.d.ts.map +1 -1
  215. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts +26 -5
  216. package/dist/esm-types/cli/lib/checkForLargeIndexDeletion.d.ts.map +1 -1
  217. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts +14 -0
  218. package/dist/esm-types/cli/lib/checkForSlowSchemaValidation.d.ts.map +1 -0
  219. package/dist/esm-types/cli/lib/codegen.d.ts +1 -0
  220. package/dist/esm-types/cli/lib/codegen.d.ts.map +1 -1
  221. package/dist/esm-types/cli/lib/components.d.ts +1 -0
  222. package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
  223. package/dist/esm-types/cli/lib/deploy2.d.ts +6 -0
  224. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  225. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts +453 -0
  226. package/dist/esm-types/cli/lib/deployApi/evaluateSchema.d.ts.map +1 -0
  227. package/dist/esm-types/cli/lib/deployApi/finishPush.d.ts +1 -2
  228. package/dist/esm-types/cli/lib/deployApi/finishPush.d.ts.map +1 -1
  229. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  230. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +2 -0
  231. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  232. package/dist/esm-types/cli/lib/localDeployment/run.d.ts +2 -0
  233. package/dist/esm-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  234. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  235. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +1 -0
  236. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  237. package/dist/esm-types/cli/lib/run.d.ts.map +1 -1
  238. package/dist/esm-types/cli/lib/utils/utils.d.ts +5 -5
  239. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  240. package/dist/esm-types/index.d.ts +1 -1
  241. package/dist/esm-types/nextjs/index.d.ts +6 -6
  242. package/dist/esm-types/nextjs/index.d.ts.map +1 -1
  243. package/dist/esm-types/react/client.d.ts +15 -15
  244. package/dist/esm-types/react/client.d.ts.map +1 -1
  245. package/dist/esm-types/react/hydration.d.ts +3 -3
  246. package/dist/esm-types/react/hydration.d.ts.map +1 -1
  247. package/dist/esm-types/react/queries_observer.d.ts +9 -9
  248. package/dist/esm-types/react/queries_observer.d.ts.map +1 -1
  249. package/dist/esm-types/react/use_paginated_query2.d.ts.map +1 -1
  250. package/dist/esm-types/react/use_queries.d.ts +14 -6
  251. package/dist/esm-types/react/use_queries.d.ts.map +1 -1
  252. package/dist/esm-types/server/api.d.ts +157 -7
  253. package/dist/esm-types/server/api.d.ts.map +1 -1
  254. package/dist/esm-types/server/components/index.d.ts +2 -2
  255. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  256. package/dist/esm-types/server/cron.d.ts +21 -20
  257. package/dist/esm-types/server/cron.d.ts.map +1 -1
  258. package/dist/esm-types/server/impl/actions_impl.d.ts +4 -4
  259. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  260. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -1
  261. package/dist/esm-types/server/impl/scheduler_impl.d.ts.map +1 -1
  262. package/dist/esm-types/server/index.d.ts +1 -1
  263. package/dist/esm-types/server/index.d.ts.map +1 -1
  264. package/dist/esm-types/server/meta.d.ts.map +1 -1
  265. package/dist/esm-types/server/registration.d.ts +7 -7
  266. package/dist/esm-types/server/registration.d.ts.map +1 -1
  267. package/dist/esm-types/server/scheduler.d.ts +9 -7
  268. package/dist/esm-types/server/scheduler.d.ts.map +1 -1
  269. package/dist/esm-types/server/schema.d.ts +1 -0
  270. package/dist/esm-types/server/schema.d.ts.map +1 -1
  271. package/dist/esm-types/values/validator.d.ts.map +1 -1
  272. package/dist/esm-types/values/validators.d.ts +30 -0
  273. package/dist/esm-types/values/validators.d.ts.map +1 -1
  274. package/dist/react.bundle.js +1 -1
  275. package/dist/react.bundle.js.map +2 -2
  276. package/package.json +5 -5
  277. package/src/browser/http_client.ts +43 -10
  278. package/src/browser/query_options.ts +11 -5
  279. package/src/browser/simple_client.ts +35 -14
  280. package/src/browser/sync/optimistic_updates.ts +17 -4
  281. package/src/browser/sync/optimistic_updates_impl.ts +17 -4
  282. package/src/cli/codegen.ts +1 -0
  283. package/src/cli/deploy.ts +1 -0
  284. package/src/cli/docs.ts +3 -44
  285. package/src/cli/lib/checkForLargeIndexDeletion.ts +154 -82
  286. package/src/cli/lib/checkForSlowSchemaValidation.ts +130 -0
  287. package/src/cli/lib/codegen.ts +1 -0
  288. package/src/cli/lib/components.ts +17 -0
  289. package/src/cli/lib/deploy2.ts +56 -1
  290. package/src/cli/lib/deployApi/evaluateSchema.ts +62 -0
  291. package/src/cli/lib/deployApi/finishPush.ts +1 -1
  292. package/src/cli/lib/deployApi/startPush.ts +1 -1
  293. package/src/cli/lib/dev.ts +1 -0
  294. package/src/cli/lib/generatedFunctionLogsApi.ts +2 -0
  295. package/src/cli/lib/localDeployment/run.ts +44 -2
  296. package/src/cli/lib/localDeployment/upgrade.ts +4 -6
  297. package/src/cli/lib/localDeployment/utils.ts +6 -0
  298. package/src/cli/lib/run.ts +1 -0
  299. package/src/cli/lib/utils/utils.ts +63 -35
  300. package/src/index.ts +1 -1
  301. package/src/nextjs/index.ts +19 -8
  302. package/src/react/client.ts +73 -30
  303. package/src/react/hydration.tsx +14 -6
  304. package/src/react/queries_observer.ts +19 -16
  305. package/src/react/use_paginated_query2.ts +10 -6
  306. package/src/react/use_queries.ts +23 -7
  307. package/src/server/api.ts +220 -14
  308. package/src/server/components/index.ts +4 -6
  309. package/src/server/cron.ts +34 -24
  310. package/src/server/impl/actions_impl.ts +13 -4
  311. package/src/server/impl/meta_impl.ts +8 -1
  312. package/src/server/impl/scheduler_impl.ts +13 -6
  313. package/src/server/index.ts +1 -0
  314. package/src/server/meta.ts +25 -0
  315. package/src/server/registration.ts +28 -7
  316. package/src/server/scheduler.ts +22 -7
  317. package/src/server/schema.ts +55 -0
  318. package/src/values/validator.ts +3 -1
  319. package/src/values/validators.ts +84 -26
@@ -2,52 +2,12 @@
2
2
  import { Command } from "@commander-js/extra-typings";
3
3
  import { chalkStderr } from "chalk";
4
4
  import open from "open";
5
- import { oneoffContext } from "../bundler/context.js";
6
5
  import { logMessage } from "../bundler/log.js";
7
- import {
8
- BIG_BRAIN_URL,
9
- bigBrainFetch,
10
- deprecationCheckWarning
11
- } from "./lib/utils/utils.js";
12
- import {
13
- getDeploymentSelection,
14
- deploymentNameFromSelection
15
- } from "./lib/deploymentSelection.js";
16
6
  export const docs = new Command("docs").description("Open the docs in the browser").allowExcessArguments(false).option("--no-open", "Print docs URL instead of opening it in your browser").action(async (options) => {
17
- const ctx = await oneoffContext({
18
- url: void 0,
19
- adminKey: void 0,
20
- envFile: void 0
21
- });
22
- const deploymentSelection = await getDeploymentSelection(ctx, {
23
- url: void 0,
24
- adminKey: void 0,
25
- envFile: void 0
26
- });
27
- const configuredDeployment = deploymentNameFromSelection(deploymentSelection);
28
- if (configuredDeployment === null) {
29
- await openDocs(ctx, options.open);
30
- return;
31
- }
32
- const getCookieUrl = new URL(
33
- `get_cookie/${configuredDeployment}`,
34
- BIG_BRAIN_URL
35
- );
36
- const fetch = bigBrainFetch(ctx);
37
- try {
38
- const res = await fetch(getCookieUrl);
39
- deprecationCheckWarning(ctx, res);
40
- const { cookie } = await res.json();
41
- await openDocs(ctx, options.open, cookie);
42
- } catch {
43
- await openDocs(ctx, options.open);
44
- }
7
+ await openDocs(options.open);
45
8
  });
46
- async function openDocs(ctx, toOpen, cookie) {
47
- let docsUrl = "https://docs.convex.dev";
48
- if (cookie !== void 0) {
49
- docsUrl += "/?t=" + cookie;
50
- }
9
+ async function openDocs(toOpen) {
10
+ const docsUrl = "https://docs.convex.dev/?utm_source=convex-cli";
51
11
  if (toOpen) {
52
12
  await open(docsUrl);
53
13
  logMessage(chalkStderr.green("Docs have launched! Check your browser."));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/docs.ts"],
4
- "sourcesContent": ["import { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport open from \"open\";\nimport { Context, oneoffContext } from \"../bundler/context.js\";\nimport { logMessage } from \"../bundler/log.js\";\nimport {\n BIG_BRAIN_URL,\n bigBrainFetch,\n deprecationCheckWarning,\n} from \"./lib/utils/utils.js\";\nimport {\n getDeploymentSelection,\n deploymentNameFromSelection,\n} from \"./lib/deploymentSelection.js\";\n\nexport const docs = new Command(\"docs\")\n .description(\"Open the docs in the browser\")\n .allowExcessArguments(false)\n .option(\"--no-open\", \"Print docs URL instead of opening it in your browser\")\n .action(async (options) => {\n const ctx = await oneoffContext({\n url: undefined,\n adminKey: undefined,\n envFile: undefined,\n });\n const deploymentSelection = await getDeploymentSelection(ctx, {\n url: undefined,\n adminKey: undefined,\n envFile: undefined,\n });\n const configuredDeployment =\n deploymentNameFromSelection(deploymentSelection);\n if (configuredDeployment === null) {\n await openDocs(ctx, options.open);\n return;\n }\n const getCookieUrl = new URL(\n `get_cookie/${configuredDeployment}`,\n BIG_BRAIN_URL,\n );\n const fetch = bigBrainFetch(ctx);\n try {\n const res = await fetch(getCookieUrl);\n deprecationCheckWarning(ctx, res);\n const { cookie } = await res.json();\n await openDocs(ctx, options.open, cookie);\n } catch {\n await openDocs(ctx, options.open);\n }\n });\n\nasync function openDocs(ctx: Context, toOpen: boolean, cookie?: string) {\n let docsUrl = \"https://docs.convex.dev\";\n if (cookie !== undefined) {\n docsUrl += \"/?t=\" + cookie;\n }\n if (toOpen) {\n await open(docsUrl);\n logMessage(chalkStderr.green(\"Docs have launched! Check your browser.\"));\n } else {\n logMessage(chalkStderr.green(`Find Convex docs here: ${docsUrl}`));\n }\n}\n"],
5
- "mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,OAAO,UAAU;AACjB,SAAkB,qBAAqB;AACvC,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEA,aAAM,OAAO,IAAI,QAAQ,MAAM,EACnC,YAAY,8BAA8B,EAC1C,qBAAqB,KAAK,EAC1B,OAAO,aAAa,sDAAsD,EAC1E,OAAO,OAAO,YAAY;AACzB,QAAM,MAAM,MAAM,cAAc;AAAA,IAC9B,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX,CAAC;AACD,QAAM,sBAAsB,MAAM,uBAAuB,KAAK;AAAA,IAC5D,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX,CAAC;AACD,QAAM,uBACJ,4BAA4B,mBAAmB;AACjD,MAAI,yBAAyB,MAAM;AACjC,UAAM,SAAS,KAAK,QAAQ,IAAI;AAChC;AAAA,EACF;AACA,QAAM,eAAe,IAAI;AAAA,IACvB,cAAc,oBAAoB;AAAA,IAClC;AAAA,EACF;AACA,QAAM,QAAQ,cAAc,GAAG;AAC/B,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,YAAY;AACpC,4BAAwB,KAAK,GAAG;AAChC,UAAM,EAAE,OAAO,IAAI,MAAM,IAAI,KAAK;AAClC,UAAM,SAAS,KAAK,QAAQ,MAAM,MAAM;AAAA,EAC1C,QAAQ;AACN,UAAM,SAAS,KAAK,QAAQ,IAAI;AAAA,EAClC;AACF,CAAC;AAEH,eAAe,SAAS,KAAc,QAAiB,QAAiB;AACtE,MAAI,UAAU;AACd,MAAI,WAAW,QAAW;AACxB,eAAW,SAAS;AAAA,EACtB;AACA,MAAI,QAAQ;AACV,UAAM,KAAK,OAAO;AAClB,eAAW,YAAY,MAAM,yCAAyC,CAAC;AAAA,EACzE,OAAO;AACL,eAAW,YAAY,MAAM,0BAA0B,OAAO,EAAE,CAAC;AAAA,EACnE;AACF;",
4
+ "sourcesContent": ["import { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport open from \"open\";\nimport { logMessage } from \"../bundler/log.js\";\n\nexport const docs = new Command(\"docs\")\n .description(\"Open the docs in the browser\")\n .allowExcessArguments(false)\n .option(\"--no-open\", \"Print docs URL instead of opening it in your browser\")\n .action(async (options) => {\n await openDocs(options.open);\n });\n\nasync function openDocs(toOpen: boolean) {\n const docsUrl = \"https://docs.convex.dev/?utm_source=convex-cli\";\n if (toOpen) {\n await open(docsUrl);\n logMessage(chalkStderr.green(\"Docs have launched! Check your browser.\"));\n } else {\n logMessage(chalkStderr.green(`Find Convex docs here: ${docsUrl}`));\n }\n}\n"],
5
+ "mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,OAAO,UAAU;AACjB,SAAS,kBAAkB;AAEpB,aAAM,OAAO,IAAI,QAAQ,MAAM,EACnC,YAAY,8BAA8B,EAC1C,qBAAqB,KAAK,EAC1B,OAAO,aAAa,sDAAsD,EAC1E,OAAO,OAAO,YAAY;AACzB,QAAM,SAAS,QAAQ,IAAI;AAC7B,CAAC;AAEH,eAAe,SAAS,QAAiB;AACvC,QAAM,UAAU;AAChB,MAAI,QAAQ;AACV,UAAM,KAAK,OAAO;AAClB,eAAW,YAAY,MAAM,yCAAyC,CAAC;AAAA,EACzE,OAAO;AACL,eAAW,YAAY,MAAM,0BAA0B,OAAO,EAAE,CAAC;AAAA,EACnE;AACF;",
6
6
  "names": []
7
7
  }
@@ -4,11 +4,12 @@ import {
4
4
  changeSpinner,
5
5
  logFinishedStep,
6
6
  logMessage,
7
+ logVerbose,
7
8
  stopSpinner
8
9
  } from "../../bundler/log.js";
9
10
  import { formatIndex } from "./indexes.js";
10
11
  import { promptYesNo } from "./utils/prompts.js";
11
- import { evaluatePush } from "./deploy2.js";
12
+ import { evaluatePush, evaluateSchema } from "./deploy2.js";
12
13
  import { runSystemQuery } from "./run.js";
13
14
  const MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING = 1e5;
14
15
  export async function checkForLargeIndexDeletion({
@@ -19,71 +20,28 @@ export async function checkForLargeIndexDeletion({
19
20
  askForConfirmation
20
21
  }) {
21
22
  changeSpinner("Verifying that the push isn\u2019t deleting large indexes...");
22
- const { schemaChange } = await evaluatePush(ctx, span, request, options);
23
- const indexDiffs = schemaChange.indexDiffs ?? {};
24
- const deletedIndexes = Object.entries(indexDiffs).flatMap(
25
- ([componentDefinitionPath, indexDiff]) => indexDiff.removed_indexes.map((index) => ({
26
- componentDefinitionPath,
27
- index
28
- }))
29
- );
23
+ const deletedIndexes = await deletedIndexesFromSchemaEvaluation({
24
+ ctx,
25
+ span,
26
+ request,
27
+ options
28
+ }) ?? await deletedIndexesFromTableSizes({ ctx, span, request, options });
30
29
  if (deletedIndexes.length === 0) {
31
30
  logFinishedStep("No indexes are deleted by this push");
32
31
  return;
33
32
  }
34
- const tablesWithDeletedIndexes = [
35
- ...new Set(
36
- deletedIndexes.map(
37
- ({ componentDefinitionPath, index }) => `${componentDefinitionPath}:${getTableName(index)}`
38
- )
39
- )
40
- ].map((str) => {
41
- const [componentDefinitionPath, table] = str.split(":");
42
- return { componentDefinitionPath, table };
43
- });
44
- changeSpinner("Checking whether the deleted indexes are on large tables...");
45
- const documentCounts = await Promise.all(
46
- tablesWithDeletedIndexes.map(
47
- async ({ componentDefinitionPath, table }) => ({
48
- componentDefinitionPath,
49
- table,
50
- count: await runSystemQuery(ctx, {
51
- deploymentUrl: options.url,
52
- adminKey: options.adminKey,
53
- functionName: "_system/cli/tableSize:default",
54
- componentPath: componentDefinitionPath,
55
- args: { tableName: table }
56
- })
57
- })
58
- )
59
- );
60
- const deletedIndexesWithDocumentsCount = deletedIndexes.map(
61
- ({ componentDefinitionPath, index }) => ({
62
- componentDefinitionPath,
63
- index,
64
- count: documentCounts.find(
65
- (count) => count.table === getTableName(index) && count.componentDefinitionPath === componentDefinitionPath
66
- ).count
67
- })
68
- );
69
33
  const minDocumentsForWarning = minDocumentsForIndexDeleteWarning();
70
- if (!deletedIndexesWithDocumentsCount.some(
71
- ({ count }) => count >= minDocumentsForWarning
34
+ if (!deletedIndexes.some(
35
+ ({ documentsCount }) => documentsCount >= minDocumentsForWarning
72
36
  )) {
73
37
  logFinishedStep("No large indexes are deleted by this push");
74
38
  return;
75
39
  }
76
- logMessage(`\u26A0\uFE0F This code push will ${chalkStderr.bold("delete")} the following ${deletedIndexesWithDocumentsCount.length === 1 ? "index" : "indexes"}
40
+ logMessage(`\u26A0\uFE0F This code push will ${chalkStderr.bold("delete")} the following ${deletedIndexes.length === 1 ? "index" : "indexes"}
77
41
  from your production deployment (${options.url}):
78
42
 
79
- ${deletedIndexesWithDocumentsCount.map(
80
- ({ componentDefinitionPath, index, count }) => formatDeletedIndex({
81
- componentDefinitionPath,
82
- index,
83
- indexDiff: indexDiffs[componentDefinitionPath],
84
- documentsCount: count,
85
- minDocumentsForWarning
86
- })
43
+ ${deletedIndexes.map(
44
+ (deletedIndex) => formatDeletedIndex({ ...deletedIndex, minDocumentsForWarning })
87
45
  ).join("\n")}
88
46
 
89
47
  The documents that are in the index won\u2019t be deleted, but the index will need
@@ -106,7 +64,7 @@ to be backfilled again if you want to restore it later.
106
64
  }
107
65
  stopSpinner();
108
66
  if (!await promptYesNo(ctx, {
109
- message: `Delete ${deletedIndexesWithDocumentsCount.length === 1 ? "this index" : "these indexes"}?`,
67
+ message: `Delete ${deletedIndexes.length === 1 ? "this index" : "these indexes"}?`,
110
68
  default: false
111
69
  })) {
112
70
  return ctx.crash({
@@ -117,16 +75,98 @@ to be backfilled again if you want to restore it later.
117
75
  }
118
76
  logFinishedStep("Proceeding with push.");
119
77
  }
78
+ export async function deletedIndexesFromSchemaEvaluation({
79
+ ctx,
80
+ span,
81
+ request,
82
+ options
83
+ }) {
84
+ try {
85
+ const response = await evaluateSchema(
86
+ ctx,
87
+ span,
88
+ request,
89
+ options,
90
+ /* bestEffort */
91
+ true
92
+ );
93
+ return Object.entries(response.componentSchemaEvaluations).flatMap(
94
+ ([componentPath, prediction]) => prediction.indexes.filter((index) => index.change === "dropped").map((index) => ({
95
+ componentPath,
96
+ index,
97
+ documentsCount: index.numDocs,
98
+ replacedBy: prediction.indexes.find(
99
+ (other) => other.change === "added" && other.name === index.name
100
+ ) ?? null
101
+ }))
102
+ );
103
+ } catch (error) {
104
+ logVerbose(
105
+ `Schema evaluation unavailable, sizing deleted indexes per table: ${error instanceof Error ? error.message : String(error)}`
106
+ );
107
+ return null;
108
+ }
109
+ }
110
+ export async function deletedIndexesFromTableSizes({
111
+ ctx,
112
+ span,
113
+ request,
114
+ options
115
+ }) {
116
+ const { schemaChange } = await evaluatePush(ctx, span, request, options);
117
+ const indexDiffs = schemaChange.indexDiffs ?? {};
118
+ const deletedIndexes = Object.entries(indexDiffs).flatMap(
119
+ ([componentPath, indexDiff]) => indexDiff.removed_indexes.map((index) => ({
120
+ componentPath,
121
+ index,
122
+ replacedBy: indexDiff.added_indexes.find((other) => other.name === index.name) ?? null
123
+ }))
124
+ );
125
+ if (deletedIndexes.length === 0) {
126
+ return [];
127
+ }
128
+ const tablesWithDeletedIndexes = [
129
+ ...new Set(
130
+ deletedIndexes.map(
131
+ ({ componentPath, index }) => `${componentPath}:${getTableName(index)}`
132
+ )
133
+ )
134
+ ].map((str) => {
135
+ const [componentPath, table] = str.split(":");
136
+ return { componentPath, table };
137
+ });
138
+ changeSpinner("Checking whether the deleted indexes are on large tables...");
139
+ const documentCounts = await Promise.all(
140
+ tablesWithDeletedIndexes.map(async ({ componentPath, table }) => ({
141
+ componentPath,
142
+ table,
143
+ count: await runSystemQuery(ctx, {
144
+ deploymentUrl: options.url,
145
+ adminKey: options.adminKey,
146
+ functionName: "_system/cli/tableSize:default",
147
+ componentPath,
148
+ args: { tableName: table }
149
+ })
150
+ }))
151
+ );
152
+ return deletedIndexes.map(({ componentPath, index, replacedBy }) => ({
153
+ componentPath,
154
+ index,
155
+ replacedBy,
156
+ documentsCount: documentCounts.find(
157
+ (count) => count.table === getTableName(index) && count.componentPath === componentPath
158
+ ).count
159
+ }));
160
+ }
120
161
  function formatDeletedIndex({
121
- componentDefinitionPath,
162
+ componentPath,
122
163
  index,
123
- indexDiff,
124
164
  documentsCount,
165
+ replacedBy,
125
166
  minDocumentsForWarning
126
167
  }) {
127
- const componentNameFormatted = componentDefinitionPath !== "" ? `${chalkStderr.gray(componentDefinitionPath)}:` : "";
168
+ const componentNameFormatted = componentPath !== "" ? `${chalkStderr.gray(componentPath)}:` : "";
128
169
  const documentsCountFormatted = documentsCount >= minDocumentsForWarning ? ` ${chalkStderr.yellowBright(`\u26A0\uFE0F ${documentsCount.toLocaleString()} documents`)}` : ` ${documentsCount.toLocaleString()} ${documentsCount === 1 ? "document" : "documents"}`;
129
- const replacedBy = indexDiff.added_indexes.find((i) => i.name === index.name);
130
170
  const replacedByFormatted = replacedBy ? `
131
171
  ${chalkStderr.green("\u2192 replaced by:")} ${formatIndex(replacedBy)}` : "";
132
172
  return "\u26D4 " + componentNameFormatted + formatIndex(index) + documentsCountFormatted + replacedByFormatted;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lib/checkForLargeIndexDeletion.ts"],
4
- "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logFinishedStep,\n logMessage,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { formatIndex } from \"./indexes.js\";\nimport { promptYesNo } from \"./utils/prompts.js\";\nimport { Span } from \"./tracing.js\";\nimport { StartPushRequest } from \"./deployApi/startPush.js\";\nimport { evaluatePush } from \"./deploy2.js\";\nimport { DeveloperIndexConfig, IndexDiff } from \"./deployApi/finishPush.js\";\nimport { runSystemQuery } from \"./run.js\";\n\nconst MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING = 100_000;\n\nexport async function checkForLargeIndexDeletion({\n ctx,\n span,\n request,\n options,\n askForConfirmation,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: {\n url: string;\n deploymentName: string | null;\n adminKey: string;\n };\n askForConfirmation: boolean;\n}): Promise<void> {\n changeSpinner(\"Verifying that the push isn\u2019t deleting large indexes...\");\n\n const { schemaChange } = await evaluatePush(ctx, span, request, options);\n\n const indexDiffs = schemaChange.indexDiffs ?? {};\n const deletedIndexes = Object.entries(indexDiffs).flatMap(\n ([componentDefinitionPath, indexDiff]) =>\n indexDiff.removed_indexes.map((index) => ({\n componentDefinitionPath,\n index,\n })),\n );\n\n if (deletedIndexes.length === 0) {\n logFinishedStep(\"No indexes are deleted by this push\");\n return;\n }\n\n const tablesWithDeletedIndexes = [\n ...new Set(\n deletedIndexes.map(\n ({ componentDefinitionPath, index }) =>\n `${componentDefinitionPath}:${getTableName(index)}`,\n ),\n ),\n ].map((str) => {\n const [componentDefinitionPath, table] = str.split(\":\");\n return { componentDefinitionPath, table };\n });\n changeSpinner(\"Checking whether the deleted indexes are on large tables...\");\n const documentCounts = await Promise.all(\n tablesWithDeletedIndexes.map(\n async ({ componentDefinitionPath, table }) => ({\n componentDefinitionPath,\n table,\n count: (await runSystemQuery(ctx, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n functionName: \"_system/cli/tableSize:default\",\n componentPath: componentDefinitionPath,\n args: { tableName: table },\n })) as number,\n }),\n ),\n );\n const deletedIndexesWithDocumentsCount = deletedIndexes.map(\n ({ componentDefinitionPath, index }) => ({\n componentDefinitionPath,\n index,\n count: documentCounts.find(\n (count) =>\n count.table === getTableName(index) &&\n count.componentDefinitionPath === componentDefinitionPath,\n )!.count,\n }),\n );\n\n const minDocumentsForWarning = minDocumentsForIndexDeleteWarning();\n if (\n !deletedIndexesWithDocumentsCount.some(\n ({ count }) => count >= minDocumentsForWarning,\n )\n ) {\n logFinishedStep(\"No large indexes are deleted by this push\");\n return;\n }\n\n logMessage(`\u26A0\uFE0F This code push will ${chalkStderr.bold(\"delete\")} the following ${deletedIndexesWithDocumentsCount.length === 1 ? \"index\" : \"indexes\"}\nfrom your production deployment (${options.url}):\n\n${deletedIndexesWithDocumentsCount\n .map(({ componentDefinitionPath, index, count }) =>\n formatDeletedIndex({\n componentDefinitionPath,\n index,\n indexDiff: indexDiffs[componentDefinitionPath],\n documentsCount: count,\n minDocumentsForWarning,\n }),\n )\n .join(\"\\n\")}\n\nThe documents that are in the index won\u2019t be deleted, but the index will need\nto be backfilled again if you want to restore it later.\n`);\n\n if (!askForConfirmation) {\n logFinishedStep(\n \"Proceeding with push since --allow-deleting-large-indexes is set\",\n );\n return;\n }\n\n if (!process.stdin.isTTY) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `To confirm the push:\n\u2022 run the deploy command in an ${chalkStderr.bold(\"interactive terminal\")}\n\u2022 or run the deploy command with the ${chalkStderr.bold(\"--allow-deleting-large-indexes\")} flag`,\n });\n }\n\n stopSpinner();\n if (\n !(await promptYesNo(ctx, {\n message: `Delete ${deletedIndexesWithDocumentsCount.length === 1 ? \"this index\" : \"these indexes\"}?`,\n default: false,\n }))\n ) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Canceling push`,\n });\n }\n\n logFinishedStep(\"Proceeding with push.\");\n}\n\nfunction formatDeletedIndex({\n componentDefinitionPath,\n index,\n indexDiff,\n documentsCount,\n minDocumentsForWarning,\n}: {\n componentDefinitionPath: string;\n index: DeveloperIndexConfig;\n indexDiff: IndexDiff;\n documentsCount: number;\n minDocumentsForWarning: number;\n}) {\n const componentNameFormatted =\n componentDefinitionPath !== \"\"\n ? `${chalkStderr.gray(componentDefinitionPath)}:`\n : \"\";\n\n const documentsCountFormatted =\n documentsCount >= minDocumentsForWarning\n ? ` ${chalkStderr.yellowBright(`\u26A0\uFE0F ${documentsCount.toLocaleString()} documents`)}`\n : ` ${documentsCount.toLocaleString()} ${documentsCount === 1 ? \"document\" : \"documents\"}`;\n\n const replacedBy = indexDiff.added_indexes.find((i) => i.name === index.name);\n const replacedByFormatted = replacedBy\n ? `\\n ${chalkStderr.green(\"\u2192 replaced by:\")} ${formatIndex(replacedBy)}`\n : \"\";\n\n return (\n \"\u26D4 \" +\n componentNameFormatted +\n formatIndex(index) +\n documentsCountFormatted +\n replacedByFormatted\n );\n}\n\nfunction getTableName(index: DeveloperIndexConfig) {\n const [tableName, _indexName] = index.name.split(\".\");\n return tableName;\n}\n\nfunction minDocumentsForIndexDeleteWarning(): number {\n const envValue = process.env.CONVEX_MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING;\n if (envValue !== undefined) {\n const parsed = parseInt(envValue, 10);\n if (!isNaN(parsed)) {\n return parsed;\n }\n }\n return MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport {\n changeSpinner,\n logFinishedStep,\n logMessage,\n logVerbose,\n stopSpinner,\n} from \"../../bundler/log.js\";\nimport { formatIndex } from \"./indexes.js\";\nimport { promptYesNo } from \"./utils/prompts.js\";\nimport { Span } from \"./tracing.js\";\nimport { StartPushRequest } from \"./deployApi/startPush.js\";\nimport { evaluatePush, evaluateSchema } from \"./deploy2.js\";\nimport { DeveloperIndexConfig } from \"./deployApi/finishPush.js\";\nimport { runSystemQuery } from \"./run.js\";\n\nconst MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING = 100_000;\n\ntype CheckOptions = {\n url: string;\n deploymentName: string | null;\n adminKey: string;\n};\n\ntype DeletedIndex = {\n // The component instance path (\"\" for the root component), matching the\n // keys of both `componentSchemaEvaluations` and `indexDiffs`.\n componentPath: string;\n index: DeveloperIndexConfig;\n documentsCount: number;\n replacedBy: DeveloperIndexConfig | null;\n};\n\nexport async function checkForLargeIndexDeletion({\n ctx,\n span,\n request,\n options,\n askForConfirmation,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: CheckOptions;\n askForConfirmation: boolean;\n}): Promise<void> {\n changeSpinner(\"Verifying that the push isn\u2019t deleting large indexes...\");\n\n const deletedIndexes =\n (await deletedIndexesFromSchemaEvaluation({\n ctx,\n span,\n request,\n options,\n })) ??\n (await deletedIndexesFromTableSizes({ ctx, span, request, options }));\n\n if (deletedIndexes.length === 0) {\n logFinishedStep(\"No indexes are deleted by this push\");\n return;\n }\n\n const minDocumentsForWarning = minDocumentsForIndexDeleteWarning();\n if (\n !deletedIndexes.some(\n ({ documentsCount }) => documentsCount >= minDocumentsForWarning,\n )\n ) {\n logFinishedStep(\"No large indexes are deleted by this push\");\n return;\n }\n\n logMessage(`\u26A0\uFE0F This code push will ${chalkStderr.bold(\"delete\")} the following ${deletedIndexes.length === 1 ? \"index\" : \"indexes\"}\nfrom your production deployment (${options.url}):\n\n${deletedIndexes\n .map((deletedIndex) =>\n formatDeletedIndex({ ...deletedIndex, minDocumentsForWarning }),\n )\n .join(\"\\n\")}\n\nThe documents that are in the index won\u2019t be deleted, but the index will need\nto be backfilled again if you want to restore it later.\n`);\n\n if (!askForConfirmation) {\n logFinishedStep(\n \"Proceeding with push since --allow-deleting-large-indexes is set\",\n );\n return;\n }\n\n if (!process.stdin.isTTY) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `To confirm the push:\n\u2022 run the deploy command in an ${chalkStderr.bold(\"interactive terminal\")}\n\u2022 or run the deploy command with the ${chalkStderr.bold(\"--allow-deleting-large-indexes\")} flag`,\n });\n }\n\n stopSpinner();\n if (\n !(await promptYesNo(ctx, {\n message: `Delete ${deletedIndexes.length === 1 ? \"this index\" : \"these indexes\"}?`,\n default: false,\n }))\n ) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Canceling push`,\n });\n }\n\n logFinishedStep(\"Proceeding with push.\");\n}\n\n// Preferred source: one schema evaluation reports every dropped index\n// together with its table's document count, requiring only the\n// `deployment:deploy` permission the push itself needs. Returns null when the\n// deployment doesn't support the endpoint, in which case the caller falls\n// back to sizing tables one system query at a time.\nexport async function deletedIndexesFromSchemaEvaluation({\n ctx,\n span,\n request,\n options,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: CheckOptions;\n}): Promise<DeletedIndex[] | null> {\n try {\n const response = await evaluateSchema(\n ctx,\n span,\n request,\n options,\n /* bestEffort */ true,\n );\n return Object.entries(response.componentSchemaEvaluations).flatMap(\n ([componentPath, prediction]) =>\n prediction.indexes\n .filter((index) => index.change === \"dropped\")\n .map((index) => ({\n componentPath,\n index,\n documentsCount: index.numDocs,\n replacedBy:\n prediction.indexes.find(\n (other) =>\n other.change === \"added\" && other.name === index.name,\n ) ?? null,\n })),\n );\n } catch (error: unknown) {\n logVerbose(\n `Schema evaluation unavailable, sizing deleted indexes per table: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n }\n}\n\n// Fallback for deployments without `evaluate_schema`: diff indexes with\n// `evaluate_push`, then size each affected table with a system query. The\n// system query needs the `deployment:data:view` permission, which a\n// deploy-scoped key may lack.\nexport async function deletedIndexesFromTableSizes({\n ctx,\n span,\n request,\n options,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: CheckOptions;\n}): Promise<DeletedIndex[]> {\n const { schemaChange } = await evaluatePush(ctx, span, request, options);\n\n const indexDiffs = schemaChange.indexDiffs ?? {};\n const deletedIndexes = Object.entries(indexDiffs).flatMap(\n ([componentPath, indexDiff]) =>\n indexDiff.removed_indexes.map((index) => ({\n componentPath,\n index,\n replacedBy:\n indexDiff.added_indexes.find((other) => other.name === index.name) ??\n null,\n })),\n );\n\n if (deletedIndexes.length === 0) {\n return [];\n }\n\n const tablesWithDeletedIndexes = [\n ...new Set(\n deletedIndexes.map(\n ({ componentPath, index }) => `${componentPath}:${getTableName(index)}`,\n ),\n ),\n ].map((str) => {\n const [componentPath, table] = str.split(\":\");\n return { componentPath, table };\n });\n changeSpinner(\"Checking whether the deleted indexes are on large tables...\");\n const documentCounts = await Promise.all(\n tablesWithDeletedIndexes.map(async ({ componentPath, table }) => ({\n componentPath,\n table,\n count: (await runSystemQuery(ctx, {\n deploymentUrl: options.url,\n adminKey: options.adminKey,\n functionName: \"_system/cli/tableSize:default\",\n componentPath,\n args: { tableName: table },\n })) as number,\n })),\n );\n return deletedIndexes.map(({ componentPath, index, replacedBy }) => ({\n componentPath,\n index,\n replacedBy,\n documentsCount: documentCounts.find(\n (count) =>\n count.table === getTableName(index) &&\n count.componentPath === componentPath,\n )!.count,\n }));\n}\n\nfunction formatDeletedIndex({\n componentPath,\n index,\n documentsCount,\n replacedBy,\n minDocumentsForWarning,\n}: DeletedIndex & { minDocumentsForWarning: number }) {\n const componentNameFormatted =\n componentPath !== \"\" ? `${chalkStderr.gray(componentPath)}:` : \"\";\n\n const documentsCountFormatted =\n documentsCount >= minDocumentsForWarning\n ? ` ${chalkStderr.yellowBright(`\u26A0\uFE0F ${documentsCount.toLocaleString()} documents`)}`\n : ` ${documentsCount.toLocaleString()} ${documentsCount === 1 ? \"document\" : \"documents\"}`;\n\n const replacedByFormatted = replacedBy\n ? `\\n ${chalkStderr.green(\"\u2192 replaced by:\")} ${formatIndex(replacedBy)}`\n : \"\";\n\n return (\n \"\u26D4 \" +\n componentNameFormatted +\n formatIndex(index) +\n documentsCountFormatted +\n replacedByFormatted\n );\n}\n\nfunction getTableName(index: DeveloperIndexConfig) {\n const [tableName, _indexName] = index.name.split(\".\");\n return tableName;\n}\n\nfunction minDocumentsForIndexDeleteWarning(): number {\n const envValue = process.env.CONVEX_MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING;\n if (envValue !== undefined) {\n const parsed = parseInt(envValue, 10);\n if (!isNaN(parsed)) {\n return parsed;\n }\n }\n return MIN_DOCUMENTS_FOR_INDEX_DELETE_WARNING;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ import { chalkStderr } from "chalk";
3
+ import { logMessage, logVerbose } from "../../bundler/log.js";
4
+ import { evaluateSchema } from "./deploy2.js";
5
+ import { formatSize } from "./utils/utils.js";
6
+ const MIN_BYTES_FOR_SCHEMA_WALK_WARNING = 1 << 27;
7
+ export async function checkForSlowSchemaValidation({
8
+ ctx,
9
+ span,
10
+ request,
11
+ options
12
+ }) {
13
+ const response = await evaluateSchemaBestEffort({
14
+ ctx,
15
+ span,
16
+ request,
17
+ options
18
+ });
19
+ if (response === null) {
20
+ return;
21
+ }
22
+ const walkedTables = Object.entries(
23
+ response.componentSchemaEvaluations
24
+ ).flatMap(
25
+ ([componentPath, prediction]) => prediction.tables.filter((table) => table.outcome === "mustWalk").map((table) => ({ componentPath, table }))
26
+ );
27
+ if (walkedTables.length === 0) {
28
+ return;
29
+ }
30
+ const totalBytes = walkedTables.reduce(
31
+ (sum, { table }) => sum + table.sizeBytes,
32
+ 0
33
+ );
34
+ if (totalBytes < minBytesForSchemaWalkWarning()) {
35
+ return;
36
+ }
37
+ logMessage(`\u26A0\uFE0F This schema change requires checking every document in the following ${walkedTables.length === 1 ? "table" : "tables"} against your new schema, totaling ${chalkStderr.yellowBright(formatSize(totalBytes))}. This deploy may take a while:
38
+
39
+ ${walkedTables.map(
40
+ ({ componentPath, table }) => formatWalkedTable({ componentPath, table })
41
+ ).join("\n")}
42
+ `);
43
+ }
44
+ async function evaluateSchemaBestEffort({
45
+ ctx,
46
+ span,
47
+ request,
48
+ options
49
+ }) {
50
+ try {
51
+ return await evaluateSchema(
52
+ ctx,
53
+ span,
54
+ request,
55
+ options,
56
+ /* bestEffort */
57
+ true
58
+ );
59
+ } catch (error) {
60
+ logVerbose(
61
+ `Skipping slow schema validation check: ${error instanceof Error ? error.message : String(error)}`
62
+ );
63
+ return null;
64
+ }
65
+ }
66
+ function formatWalkedTable({
67
+ componentPath,
68
+ table
69
+ }) {
70
+ const componentPrefix = componentPath !== "" ? `${chalkStderr.gray(componentPath)}: ` : "";
71
+ const docsFormatted = `${table.numDocs.toLocaleString()} documents, `;
72
+ const sizeFormatted = formatSize(table.sizeBytes);
73
+ return ` ${componentPrefix}${table.name} (${docsFormatted}${sizeFormatted})`;
74
+ }
75
+ function minBytesForSchemaWalkWarning() {
76
+ const envValue = process.env.CONVEX_MIN_BYTES_FOR_SCHEMA_WALK_WARNING;
77
+ if (envValue !== void 0) {
78
+ const parsed = parseInt(envValue, 10);
79
+ if (!isNaN(parsed)) {
80
+ return parsed;
81
+ }
82
+ }
83
+ return MIN_BYTES_FOR_SCHEMA_WALK_WARNING;
84
+ }
85
+ //# sourceMappingURL=checkForSlowSchemaValidation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/lib/checkForSlowSchemaValidation.ts"],
4
+ "sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../../bundler/context.js\";\nimport { logMessage, logVerbose } from \"../../bundler/log.js\";\nimport { Span } from \"./tracing.js\";\nimport { StartPushRequest } from \"./deployApi/startPush.js\";\nimport {\n EvaluateSchemaResponse,\n TablePrediction,\n} from \"./deployApi/evaluateSchema.js\";\nimport { evaluateSchema } from \"./deploy2.js\";\nimport { formatSize } from \"./utils/utils.js\";\n\nconst MIN_BYTES_FOR_SCHEMA_WALK_WARNING = 1 << 27; // 128 MiB\n\nexport async function checkForSlowSchemaValidation({\n ctx,\n span,\n request,\n options,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: {\n url: string;\n deploymentName: string | null;\n adminKey: string;\n };\n}): Promise<void> {\n const response = await evaluateSchemaBestEffort({\n ctx,\n span,\n request,\n options,\n });\n if (response === null) {\n return;\n }\n\n const walkedTables = Object.entries(\n response.componentSchemaEvaluations,\n ).flatMap(([componentPath, prediction]) =>\n prediction.tables\n .filter((table) => table.outcome === \"mustWalk\")\n .map((table) => ({ componentPath, table })),\n );\n if (walkedTables.length === 0) {\n return;\n }\n\n const totalBytes = walkedTables.reduce(\n (sum, { table }) => sum + table.sizeBytes,\n 0,\n );\n if (totalBytes < minBytesForSchemaWalkWarning()) {\n return;\n }\n\n logMessage(`\u26A0\uFE0F This schema change requires checking every document in the following ${walkedTables.length === 1 ? \"table\" : \"tables\"} against your new schema, totaling ${chalkStderr.yellowBright(formatSize(totalBytes))}. This deploy may take a while:\n\n${walkedTables\n .map(({ componentPath, table }) =>\n formatWalkedTable({ componentPath, table }),\n )\n .join(\"\\n\")}\n`);\n}\n\n// This warning is advisory: if evaluation fails, fall back to skipping it\n// rather than aborting the push over a check that isn't required for\n// correctness. Plausibly transient failures \u2014 network errors and 5xx\n// responses (e.g. table summaries still bootstrapping) \u2014 are retried with\n// backoff by the shared fetch wrapper (see `pushCode`); anything else is\n// deterministic, including a 2xx whose shape the CLI doesn't recognize, so\n// it skips the check immediately.\nasync function evaluateSchemaBestEffort({\n ctx,\n span,\n request,\n options,\n}: {\n ctx: Context;\n span: Span;\n request: StartPushRequest;\n options: {\n url: string;\n deploymentName: string | null;\n adminKey: string;\n };\n}): Promise<EvaluateSchemaResponse | null> {\n try {\n return await evaluateSchema(\n ctx,\n span,\n request,\n options,\n /* bestEffort */ true,\n );\n } catch (error: unknown) {\n logVerbose(\n `Skipping slow schema validation check: ${error instanceof Error ? error.message : String(error)}`,\n );\n return null;\n }\n}\n\nfunction formatWalkedTable({\n componentPath,\n table,\n}: {\n componentPath: string;\n table: TablePrediction;\n}) {\n const componentPrefix =\n componentPath !== \"\" ? `${chalkStderr.gray(componentPath)}: ` : \"\";\n const docsFormatted = `${table.numDocs.toLocaleString()} documents, `;\n const sizeFormatted = formatSize(table.sizeBytes);\n return ` ${componentPrefix}${table.name} (${docsFormatted}${sizeFormatted})`;\n}\n\nfunction minBytesForSchemaWalkWarning(): number {\n const envValue = process.env.CONVEX_MIN_BYTES_FOR_SCHEMA_WALK_WARNING;\n if (envValue !== undefined) {\n const parsed = parseInt(envValue, 10);\n if (!isNaN(parsed)) {\n return parsed;\n }\n }\n return MIN_BYTES_FOR_SCHEMA_WALK_WARNING;\n}\n"],
5
+ "mappings": ";AAAA,SAAS,mBAAmB;AAE5B,SAAS,YAAY,kBAAkB;AAOvC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAE3B,MAAM,oCAAoC,KAAK;AAE/C,sBAAsB,6BAA6B;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASkB;AAChB,QAAM,WAAW,MAAM,yBAAyB;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,aAAa,MAAM;AACrB;AAAA,EACF;AAEA,QAAM,eAAe,OAAO;AAAA,IAC1B,SAAS;AAAA,EACX,EAAE;AAAA,IAAQ,CAAC,CAAC,eAAe,UAAU,MACnC,WAAW,OACR,OAAO,CAAC,UAAU,MAAM,YAAY,UAAU,EAC9C,IAAI,CAAC,WAAW,EAAE,eAAe,MAAM,EAAE;AAAA,EAC9C;AACA,MAAI,aAAa,WAAW,GAAG;AAC7B;AAAA,EACF;AAEA,QAAM,aAAa,aAAa;AAAA,IAC9B,CAAC,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM;AAAA,IAChC;AAAA,EACF;AACA,MAAI,aAAa,6BAA6B,GAAG;AAC/C;AAAA,EACF;AAEA,aAAW,sFAA4E,aAAa,WAAW,IAAI,UAAU,QAAQ,sCAAsC,YAAY,aAAa,WAAW,UAAU,CAAC,CAAC;AAAA;AAAA,EAE3N,aACC;AAAA,IAAI,CAAC,EAAE,eAAe,MAAM,MAC3B,kBAAkB,EAAE,eAAe,MAAM,CAAC;AAAA,EAC5C,EACC,KAAK,IAAI,CAAC;AAAA,CACZ;AACD;AASA,eAAe,yBAAyB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAS2C;AACzC,MAAI;AACF,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACiB;AAAA,IACnB;AAAA,EACF,SAAS,OAAgB;AACvB;AAAA,MACE,0CAA0C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAClG;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AACF,GAGG;AACD,QAAM,kBACJ,kBAAkB,KAAK,GAAG,YAAY,KAAK,aAAa,CAAC,OAAO;AAClE,QAAM,gBAAgB,GAAG,MAAM,QAAQ,eAAe,CAAC;AACvD,QAAM,gBAAgB,WAAW,MAAM,SAAS;AAChD,SAAO,KAAK,eAAe,GAAG,MAAM,IAAI,KAAK,aAAa,GAAG,aAAa;AAC5E;AAEA,SAAS,+BAAuC;AAC9C,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,aAAa,QAAW;AAC1B,UAAM,SAAS,SAAS,UAAU,EAAE;AACpC,QAAI,CAAC,MAAM,MAAM,GAAG;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }