appwrite-cli 13.0.0-rc.1 → 13.0.0-rc.3

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 (430) hide show
  1. package/.github/workflows/publish.yml +68 -0
  2. package/CHANGELOG.md +10 -1
  3. package/LICENSE.md +1 -1
  4. package/README.md +3 -3
  5. package/cli.ts +152 -0
  6. package/dist/bundle.cjs +95813 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +145 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/index.d.ts +10 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +7 -142
  14. package/dist/index.js.map +1 -1
  15. package/dist/lib/client.d.ts +2 -3
  16. package/dist/lib/client.d.ts.map +1 -1
  17. package/dist/lib/client.js +57 -45
  18. package/dist/lib/client.js.map +1 -1
  19. package/dist/lib/commands/config.d.ts +562 -0
  20. package/dist/lib/commands/config.d.ts.map +1 -0
  21. package/dist/lib/commands/config.js +416 -0
  22. package/dist/lib/commands/config.js.map +1 -0
  23. package/dist/lib/commands/db.d.ts +34 -0
  24. package/dist/lib/commands/db.d.ts.map +1 -0
  25. package/dist/lib/commands/db.js +247 -0
  26. package/dist/lib/commands/db.js.map +1 -0
  27. package/dist/lib/commands/errors.d.ts +68 -0
  28. package/dist/lib/commands/errors.d.ts.map +1 -0
  29. package/dist/lib/commands/errors.js +72 -0
  30. package/dist/lib/commands/errors.js.map +1 -0
  31. package/dist/lib/commands/generic.d.ts +2 -2
  32. package/dist/lib/commands/generic.d.ts.map +1 -1
  33. package/dist/lib/commands/generic.js +170 -157
  34. package/dist/lib/commands/generic.js.map +1 -1
  35. package/dist/lib/commands/init.d.ts +1 -1
  36. package/dist/lib/commands/init.d.ts.map +1 -1
  37. package/dist/lib/commands/init.js +201 -192
  38. package/dist/lib/commands/init.js.map +1 -1
  39. package/dist/lib/commands/pull.d.ts +105 -3
  40. package/dist/lib/commands/pull.d.ts.map +1 -1
  41. package/dist/lib/commands/pull.js +530 -370
  42. package/dist/lib/commands/pull.js.map +1 -1
  43. package/dist/lib/commands/push.d.ts +106 -0
  44. package/dist/lib/commands/push.d.ts.map +1 -1
  45. package/dist/lib/commands/push.js +1432 -1830
  46. package/dist/lib/commands/push.js.map +1 -1
  47. package/dist/lib/commands/run.d.ts +1 -1
  48. package/dist/lib/commands/run.d.ts.map +1 -1
  49. package/dist/lib/commands/run.js +129 -127
  50. package/dist/lib/commands/run.js.map +1 -1
  51. package/dist/lib/commands/schema.d.ts +59 -0
  52. package/dist/lib/commands/schema.d.ts.map +1 -0
  53. package/dist/lib/commands/schema.js +86 -0
  54. package/dist/lib/commands/schema.js.map +1 -0
  55. package/dist/lib/commands/services/account.d.ts +3 -0
  56. package/dist/lib/commands/services/account.d.ts.map +1 -0
  57. package/dist/lib/commands/services/account.js +328 -0
  58. package/dist/lib/commands/services/account.js.map +1 -0
  59. package/dist/lib/commands/services/console.d.ts +3 -0
  60. package/dist/lib/commands/services/console.d.ts.map +1 -0
  61. package/dist/lib/commands/services/console.js +28 -0
  62. package/dist/lib/commands/services/console.js.map +1 -0
  63. package/dist/lib/commands/services/databases.d.ts +3 -0
  64. package/dist/lib/commands/services/databases.d.ts.map +1 -0
  65. package/dist/lib/commands/services/databases.js +620 -0
  66. package/dist/lib/commands/services/databases.js.map +1 -0
  67. package/dist/lib/commands/services/functions.d.ts +3 -0
  68. package/dist/lib/commands/services/functions.d.ts.map +1 -0
  69. package/dist/lib/commands/services/functions.js +266 -0
  70. package/dist/lib/commands/services/functions.js.map +1 -0
  71. package/dist/lib/commands/services/graphql.d.ts +3 -0
  72. package/dist/lib/commands/services/graphql.d.ts.map +1 -0
  73. package/dist/lib/commands/services/graphql.js +28 -0
  74. package/dist/lib/commands/services/graphql.js.map +1 -0
  75. package/dist/lib/commands/services/health.d.ts +3 -0
  76. package/dist/lib/commands/services/health.d.ts.map +1 -0
  77. package/dist/lib/commands/services/health.js +123 -0
  78. package/dist/lib/commands/services/health.js.map +1 -0
  79. package/dist/lib/commands/services/locale.d.ts +3 -0
  80. package/dist/lib/commands/services/locale.d.ts.map +1 -0
  81. package/dist/lib/commands/services/locale.js +52 -0
  82. package/dist/lib/commands/services/locale.js.map +1 -0
  83. package/dist/lib/commands/services/messaging.d.ts +3 -0
  84. package/dist/lib/commands/services/messaging.d.ts.map +1 -0
  85. package/dist/lib/commands/services/messaging.js +505 -0
  86. package/dist/lib/commands/services/messaging.js.map +1 -0
  87. package/dist/lib/commands/services/migrations.d.ts +3 -0
  88. package/dist/lib/commands/services/migrations.d.ts.map +1 -0
  89. package/dist/lib/commands/services/migrations.js +135 -0
  90. package/dist/lib/commands/services/migrations.js.map +1 -0
  91. package/dist/lib/commands/services/project.d.ts +3 -0
  92. package/dist/lib/commands/services/project.d.ts.map +1 -0
  93. package/dist/lib/commands/services/project.js +54 -0
  94. package/dist/lib/commands/services/project.js.map +1 -0
  95. package/dist/lib/commands/services/projects.d.ts +3 -0
  96. package/dist/lib/commands/services/projects.d.ts.map +1 -0
  97. package/dist/lib/commands/services/projects.js +415 -0
  98. package/dist/lib/commands/services/projects.js.map +1 -0
  99. package/dist/lib/commands/services/proxy.d.ts +3 -0
  100. package/dist/lib/commands/services/proxy.d.ts.map +1 -0
  101. package/dist/lib/commands/services/proxy.js +68 -0
  102. package/dist/lib/commands/services/proxy.js.map +1 -0
  103. package/dist/lib/commands/services/sites.d.ts +3 -0
  104. package/dist/lib/commands/services/sites.d.ts.map +1 -0
  105. package/dist/lib/commands/services/sites.js +250 -0
  106. package/dist/lib/commands/services/sites.js.map +1 -0
  107. package/dist/lib/commands/services/storage.d.ts +3 -0
  108. package/dist/lib/commands/services/storage.d.ts.map +1 -0
  109. package/dist/lib/commands/services/storage.js +175 -0
  110. package/dist/lib/commands/services/storage.js.map +1 -0
  111. package/dist/lib/commands/services/tables-db.d.ts +3 -0
  112. package/dist/lib/commands/services/tables-db.d.ts.map +1 -0
  113. package/dist/lib/commands/services/tables-db.js +613 -0
  114. package/dist/lib/commands/services/tables-db.js.map +1 -0
  115. package/dist/lib/commands/services/teams.d.ts +3 -0
  116. package/dist/lib/commands/services/teams.d.ts.map +1 -0
  117. package/dist/lib/commands/services/teams.js +123 -0
  118. package/dist/lib/commands/services/teams.js.map +1 -0
  119. package/dist/lib/commands/services/tokens.d.ts +3 -0
  120. package/dist/lib/commands/services/tokens.d.ts.map +1 -0
  121. package/dist/lib/commands/services/tokens.js +49 -0
  122. package/dist/lib/commands/services/tokens.js.map +1 -0
  123. package/dist/lib/commands/services/users.d.ts +3 -0
  124. package/dist/lib/commands/services/users.d.ts.map +1 -0
  125. package/dist/lib/commands/services/users.js +312 -0
  126. package/dist/lib/commands/services/users.js.map +1 -0
  127. package/dist/lib/commands/services/vcs.d.ts +3 -0
  128. package/dist/lib/commands/services/vcs.d.ts.map +1 -0
  129. package/dist/lib/commands/services/vcs.js +87 -0
  130. package/dist/lib/commands/services/vcs.js.map +1 -0
  131. package/dist/lib/commands/types.d.ts +1 -1
  132. package/dist/lib/commands/types.d.ts.map +1 -1
  133. package/dist/lib/commands/types.js +53 -57
  134. package/dist/lib/commands/types.js.map +1 -1
  135. package/dist/lib/commands/update.d.ts +1 -1
  136. package/dist/lib/commands/update.d.ts.map +1 -1
  137. package/dist/lib/commands/update.js +69 -69
  138. package/dist/lib/commands/update.js.map +1 -1
  139. package/dist/lib/commands/utils/attributes.d.ts +47 -0
  140. package/dist/lib/commands/utils/attributes.d.ts.map +1 -0
  141. package/dist/lib/commands/utils/attributes.js +514 -0
  142. package/dist/lib/commands/utils/attributes.js.map +1 -0
  143. package/dist/lib/commands/utils/change-approval.d.ts +25 -0
  144. package/dist/lib/commands/utils/change-approval.d.ts.map +1 -0
  145. package/dist/lib/commands/utils/change-approval.js +129 -0
  146. package/dist/lib/commands/utils/change-approval.js.map +1 -0
  147. package/dist/lib/commands/utils/database-sync.d.ts +10 -0
  148. package/dist/lib/commands/utils/database-sync.d.ts.map +1 -0
  149. package/dist/lib/commands/utils/database-sync.js +136 -0
  150. package/dist/lib/commands/utils/database-sync.js.map +1 -0
  151. package/dist/lib/commands/utils/deployment.d.ts +34 -0
  152. package/dist/lib/commands/utils/deployment.d.ts.map +1 -0
  153. package/dist/lib/commands/utils/deployment.js +109 -0
  154. package/dist/lib/commands/utils/deployment.js.map +1 -0
  155. package/dist/lib/commands/utils/error-formatter.d.ts +19 -0
  156. package/dist/lib/commands/utils/error-formatter.d.ts.map +1 -0
  157. package/dist/lib/commands/utils/error-formatter.js +333 -0
  158. package/dist/lib/commands/utils/error-formatter.js.map +1 -0
  159. package/dist/lib/commands/utils/pools.d.ts +16 -0
  160. package/dist/lib/commands/utils/pools.d.ts.map +1 -0
  161. package/dist/lib/commands/utils/pools.js +198 -0
  162. package/dist/lib/commands/utils/pools.js.map +1 -0
  163. package/dist/lib/config.d.ts +41 -40
  164. package/dist/lib/config.d.ts.map +1 -1
  165. package/dist/lib/config.js +264 -239
  166. package/dist/lib/config.js.map +1 -1
  167. package/dist/lib/constants.d.ts +14 -0
  168. package/dist/lib/constants.d.ts.map +1 -0
  169. package/dist/lib/constants.js +19 -0
  170. package/dist/lib/constants.js.map +1 -0
  171. package/dist/lib/emulation/docker.d.ts +4 -12
  172. package/dist/lib/emulation/docker.d.ts.map +1 -1
  173. package/dist/lib/emulation/docker.js +159 -142
  174. package/dist/lib/emulation/docker.js.map +1 -1
  175. package/dist/lib/emulation/utils.d.ts +1 -1
  176. package/dist/lib/emulation/utils.d.ts.map +1 -1
  177. package/dist/lib/emulation/utils.js +55 -58
  178. package/dist/lib/emulation/utils.js.map +1 -1
  179. package/dist/lib/id.d.ts +1 -1
  180. package/dist/lib/id.d.ts.map +1 -1
  181. package/dist/lib/id.js +13 -18
  182. package/dist/lib/id.js.map +1 -1
  183. package/dist/lib/paginate.d.ts +3 -4
  184. package/dist/lib/paginate.d.ts.map +1 -1
  185. package/dist/lib/paginate.js +7 -10
  186. package/dist/lib/paginate.js.map +1 -1
  187. package/dist/lib/parser.d.ts +1 -1
  188. package/dist/lib/parser.d.ts.map +1 -1
  189. package/dist/lib/parser.js +92 -103
  190. package/dist/lib/parser.js.map +1 -1
  191. package/dist/lib/questions.d.ts +1 -1
  192. package/dist/lib/questions.d.ts.map +1 -1
  193. package/dist/lib/questions.js +381 -385
  194. package/dist/lib/questions.js.map +1 -1
  195. package/dist/lib/sdks.d.ts +1 -1
  196. package/dist/lib/sdks.d.ts.map +1 -1
  197. package/dist/lib/sdks.js +39 -30
  198. package/dist/lib/sdks.js.map +1 -1
  199. package/dist/lib/services.d.ts +13 -0
  200. package/dist/lib/services.d.ts.map +1 -0
  201. package/dist/lib/services.js +47 -0
  202. package/dist/lib/services.js.map +1 -0
  203. package/dist/lib/spinner.d.ts +1 -1
  204. package/dist/lib/spinner.d.ts.map +1 -1
  205. package/dist/lib/spinner.js +25 -27
  206. package/dist/lib/spinner.js.map +1 -1
  207. package/dist/lib/type-generation/attribute.d.ts +1 -1
  208. package/dist/lib/type-generation/attribute.d.ts.map +1 -1
  209. package/dist/lib/type-generation/attribute.js +14 -17
  210. package/dist/lib/type-generation/attribute.js.map +1 -1
  211. package/dist/lib/type-generation/languages/csharp.d.ts +1 -1
  212. package/dist/lib/type-generation/languages/csharp.d.ts.map +1 -1
  213. package/dist/lib/type-generation/languages/csharp.js +34 -34
  214. package/dist/lib/type-generation/languages/csharp.js.map +1 -1
  215. package/dist/lib/type-generation/languages/dart.d.ts +1 -1
  216. package/dist/lib/type-generation/languages/dart.d.ts.map +1 -1
  217. package/dist/lib/type-generation/languages/dart.js +57 -57
  218. package/dist/lib/type-generation/languages/dart.js.map +1 -1
  219. package/dist/lib/type-generation/languages/java.d.ts +1 -1
  220. package/dist/lib/type-generation/languages/java.d.ts.map +1 -1
  221. package/dist/lib/type-generation/languages/java.js +35 -35
  222. package/dist/lib/type-generation/languages/java.js.map +1 -1
  223. package/dist/lib/type-generation/languages/javascript.d.ts +1 -1
  224. package/dist/lib/type-generation/languages/javascript.d.ts.map +1 -1
  225. package/dist/lib/type-generation/languages/javascript.js +45 -44
  226. package/dist/lib/type-generation/languages/javascript.js.map +1 -1
  227. package/dist/lib/type-generation/languages/kotlin.d.ts +1 -1
  228. package/dist/lib/type-generation/languages/kotlin.d.ts.map +1 -1
  229. package/dist/lib/type-generation/languages/kotlin.js +35 -35
  230. package/dist/lib/type-generation/languages/kotlin.js.map +1 -1
  231. package/dist/lib/type-generation/languages/language.d.ts.map +1 -1
  232. package/dist/lib/type-generation/languages/language.js +32 -37
  233. package/dist/lib/type-generation/languages/language.js.map +1 -1
  234. package/dist/lib/type-generation/languages/php.d.ts +1 -1
  235. package/dist/lib/type-generation/languages/php.d.ts.map +1 -1
  236. package/dist/lib/type-generation/languages/php.js +34 -34
  237. package/dist/lib/type-generation/languages/php.js.map +1 -1
  238. package/dist/lib/type-generation/languages/swift.d.ts +1 -1
  239. package/dist/lib/type-generation/languages/swift.d.ts.map +1 -1
  240. package/dist/lib/type-generation/languages/swift.js +35 -35
  241. package/dist/lib/type-generation/languages/swift.js.map +1 -1
  242. package/dist/lib/type-generation/languages/typescript.d.ts +1 -1
  243. package/dist/lib/type-generation/languages/typescript.d.ts.map +1 -1
  244. package/dist/lib/type-generation/languages/typescript.js +49 -46
  245. package/dist/lib/type-generation/languages/typescript.js.map +1 -1
  246. package/dist/lib/types.d.ts +38 -108
  247. package/dist/lib/types.d.ts.map +1 -1
  248. package/dist/lib/types.js +1 -2
  249. package/dist/lib/utils.d.ts +3 -0
  250. package/dist/lib/utils.d.ts.map +1 -1
  251. package/dist/lib/utils.js +142 -98
  252. package/dist/lib/utils.js.map +1 -1
  253. package/dist/lib/validations.d.ts.map +1 -1
  254. package/dist/lib/validations.js +2 -6
  255. package/dist/lib/validations.js.map +1 -1
  256. package/dist/package.json +68 -0
  257. package/index.ts +25 -149
  258. package/install.ps1 +2 -2
  259. package/install.sh +1 -1
  260. package/lib/client.ts +261 -220
  261. package/lib/commands/config.ts +494 -0
  262. package/lib/commands/db.ts +324 -0
  263. package/lib/commands/errors.ts +93 -0
  264. package/lib/commands/generic.ts +371 -269
  265. package/lib/commands/init.ts +631 -519
  266. package/lib/commands/pull.ts +827 -453
  267. package/lib/commands/push.ts +2191 -2349
  268. package/lib/commands/run.ts +382 -302
  269. package/lib/commands/schema.ts +122 -0
  270. package/lib/commands/services/account.ts +647 -0
  271. package/lib/commands/services/console.ts +52 -0
  272. package/lib/commands/services/databases.ts +1163 -0
  273. package/lib/commands/services/functions.ts +536 -0
  274. package/lib/commands/services/graphql.ts +50 -0
  275. package/lib/commands/services/health.ts +260 -0
  276. package/lib/commands/services/locale.ts +102 -0
  277. package/lib/commands/services/messaging.ts +1052 -0
  278. package/lib/commands/services/migrations.ts +249 -0
  279. package/lib/commands/services/project.ts +112 -0
  280. package/lib/commands/services/projects.ts +785 -0
  281. package/lib/commands/services/proxy.ts +135 -0
  282. package/lib/commands/services/sites.ts +505 -0
  283. package/lib/commands/services/storage.ts +338 -0
  284. package/lib/commands/services/tables-db.ts +1150 -0
  285. package/lib/commands/services/teams.ts +232 -0
  286. package/lib/commands/services/tokens.ts +94 -0
  287. package/lib/commands/services/users.ts +616 -0
  288. package/lib/commands/services/vcs.ts +165 -0
  289. package/lib/commands/types.ts +145 -118
  290. package/lib/commands/update.ts +189 -159
  291. package/lib/commands/utils/attributes.ts +719 -0
  292. package/lib/commands/utils/change-approval.ts +186 -0
  293. package/lib/commands/utils/database-sync.ts +180 -0
  294. package/lib/commands/utils/deployment.ts +184 -0
  295. package/lib/commands/utils/error-formatter.ts +417 -0
  296. package/lib/commands/utils/pools.ts +355 -0
  297. package/lib/config.ts +766 -687
  298. package/lib/constants.ts +22 -0
  299. package/lib/emulation/docker.ts +277 -216
  300. package/lib/emulation/utils.ts +188 -174
  301. package/lib/id.ts +23 -23
  302. package/lib/paginate.ts +69 -55
  303. package/lib/parser.ts +220 -189
  304. package/lib/questions.ts +1024 -948
  305. package/lib/sdks.ts +84 -51
  306. package/lib/services.ts +72 -0
  307. package/lib/spinner.ts +112 -99
  308. package/lib/type-generation/attribute.ts +15 -14
  309. package/lib/type-generation/languages/csharp.ts +71 -60
  310. package/lib/type-generation/languages/dart.ts +106 -93
  311. package/lib/type-generation/languages/java.ts +69 -58
  312. package/lib/type-generation/languages/javascript.ts +84 -73
  313. package/lib/type-generation/languages/kotlin.ts +71 -60
  314. package/lib/type-generation/languages/language.ts +103 -95
  315. package/lib/type-generation/languages/php.ts +67 -56
  316. package/lib/type-generation/languages/swift.ts +71 -60
  317. package/lib/type-generation/languages/typescript.ts +93 -76
  318. package/lib/types.ts +50 -125
  319. package/lib/utils.ts +304 -233
  320. package/lib/validations.ts +17 -14
  321. package/package.json +31 -22
  322. package/scoop/appwrite.config.json +3 -3
  323. package/tsconfig.json +7 -13
  324. package/.github/workflows/autoclose.yml +0 -11
  325. package/.github/workflows/npm-publish.yml +0 -49
  326. package/dist/lib/commands/account.d.ts +0 -379
  327. package/dist/lib/commands/account.d.ts.map +0 -1
  328. package/dist/lib/commands/account.js +0 -1228
  329. package/dist/lib/commands/account.js.map +0 -1
  330. package/dist/lib/commands/console.d.ts +0 -20
  331. package/dist/lib/commands/console.d.ts.map +0 -1
  332. package/dist/lib/commands/console.js +0 -78
  333. package/dist/lib/commands/console.js.map +0 -1
  334. package/dist/lib/commands/databases.d.ts +0 -732
  335. package/dist/lib/commands/databases.d.ts.map +0 -1
  336. package/dist/lib/commands/databases.js +0 -2196
  337. package/dist/lib/commands/databases.js.map +0 -1
  338. package/dist/lib/commands/functions.d.ts +0 -310
  339. package/dist/lib/commands/functions.d.ts.map +0 -1
  340. package/dist/lib/commands/functions.js +0 -1100
  341. package/dist/lib/commands/functions.js.map +0 -1
  342. package/dist/lib/commands/graphql.d.ts +0 -19
  343. package/dist/lib/commands/graphql.d.ts.map +0 -1
  344. package/dist/lib/commands/graphql.js +0 -77
  345. package/dist/lib/commands/graphql.js.map +0 -1
  346. package/dist/lib/commands/health.d.ts +0 -153
  347. package/dist/lib/commands/health.d.ts.map +0 -1
  348. package/dist/lib/commands/health.js +0 -464
  349. package/dist/lib/commands/health.js.map +0 -1
  350. package/dist/lib/commands/locale.d.ts +0 -53
  351. package/dist/lib/commands/locale.d.ts.map +0 -1
  352. package/dist/lib/commands/locale.js +0 -165
  353. package/dist/lib/commands/locale.js.map +0 -1
  354. package/dist/lib/commands/messaging.d.ts +0 -588
  355. package/dist/lib/commands/messaging.d.ts.map +0 -1
  356. package/dist/lib/commands/messaging.js +0 -2042
  357. package/dist/lib/commands/messaging.js.map +0 -1
  358. package/dist/lib/commands/migrations.d.ts +0 -150
  359. package/dist/lib/commands/migrations.d.ts.map +0 -1
  360. package/dist/lib/commands/migrations.js +0 -524
  361. package/dist/lib/commands/migrations.js.map +0 -1
  362. package/dist/lib/commands/organizations.d.ts +0 -11
  363. package/dist/lib/commands/organizations.d.ts.map +0 -1
  364. package/dist/lib/commands/organizations.js +0 -31
  365. package/dist/lib/commands/organizations.js.map +0 -1
  366. package/dist/lib/commands/project.d.ts +0 -53
  367. package/dist/lib/commands/project.d.ts.map +0 -1
  368. package/dist/lib/commands/project.js +0 -176
  369. package/dist/lib/commands/project.js.map +0 -1
  370. package/dist/lib/commands/projects.d.ts +0 -516
  371. package/dist/lib/commands/projects.d.ts.map +0 -1
  372. package/dist/lib/commands/projects.js +0 -1590
  373. package/dist/lib/commands/projects.js.map +0 -1
  374. package/dist/lib/commands/proxy.d.ts +0 -71
  375. package/dist/lib/commands/proxy.d.ts.map +0 -1
  376. package/dist/lib/commands/proxy.js +0 -240
  377. package/dist/lib/commands/proxy.js.map +0 -1
  378. package/dist/lib/commands/sites.d.ts +0 -296
  379. package/dist/lib/commands/sites.d.ts.map +0 -1
  380. package/dist/lib/commands/sites.js +0 -1046
  381. package/dist/lib/commands/sites.js.map +0 -1
  382. package/dist/lib/commands/storage.d.ts +0 -170
  383. package/dist/lib/commands/storage.d.ts.map +0 -1
  384. package/dist/lib/commands/storage.js +0 -651
  385. package/dist/lib/commands/storage.js.map +0 -1
  386. package/dist/lib/commands/tables-db.d.ts +0 -728
  387. package/dist/lib/commands/tables-db.d.ts.map +0 -1
  388. package/dist/lib/commands/tables-db.js +0 -2198
  389. package/dist/lib/commands/tables-db.js.map +0 -1
  390. package/dist/lib/commands/teams.d.ts +0 -129
  391. package/dist/lib/commands/teams.d.ts.map +0 -1
  392. package/dist/lib/commands/teams.js +0 -403
  393. package/dist/lib/commands/teams.js.map +0 -1
  394. package/dist/lib/commands/tokens.d.ts +0 -48
  395. package/dist/lib/commands/tokens.d.ts.map +0 -1
  396. package/dist/lib/commands/tokens.js +0 -156
  397. package/dist/lib/commands/tokens.js.map +0 -1
  398. package/dist/lib/commands/users.d.ts +0 -382
  399. package/dist/lib/commands/users.d.ts.map +0 -1
  400. package/dist/lib/commands/users.js +0 -1195
  401. package/dist/lib/commands/users.js.map +0 -1
  402. package/dist/lib/commands/vcs.d.ts +0 -92
  403. package/dist/lib/commands/vcs.d.ts.map +0 -1
  404. package/dist/lib/commands/vcs.js +0 -276
  405. package/dist/lib/commands/vcs.js.map +0 -1
  406. package/dist/lib/exception.d.ts +0 -8
  407. package/dist/lib/exception.d.ts.map +0 -1
  408. package/dist/lib/exception.js +0 -16
  409. package/dist/lib/exception.js.map +0 -1
  410. package/lib/commands/account.ts +0 -1867
  411. package/lib/commands/console.ts +0 -112
  412. package/lib/commands/databases.ts +0 -3272
  413. package/lib/commands/functions.ts +0 -1587
  414. package/lib/commands/graphql.ts +0 -110
  415. package/lib/commands/health.ts +0 -753
  416. package/lib/commands/locale.ts +0 -270
  417. package/lib/commands/messaging.ts +0 -2878
  418. package/lib/commands/migrations.ts +0 -754
  419. package/lib/commands/organizations.ts +0 -46
  420. package/lib/commands/project.ts +0 -266
  421. package/lib/commands/projects.ts +0 -2370
  422. package/lib/commands/proxy.ts +0 -357
  423. package/lib/commands/sites.ts +0 -1514
  424. package/lib/commands/storage.ts +0 -919
  425. package/lib/commands/tables-db.ts +0 -3260
  426. package/lib/commands/teams.ts +0 -609
  427. package/lib/commands/tokens.ts +0 -232
  428. package/lib/commands/users.ts +0 -1804
  429. package/lib/commands/vcs.ts +0 -428
  430. package/lib/exception.ts +0 -20
@@ -1,1630 +1,1440 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.deploy = exports.push = void 0;
7
- const fs = require("fs");
8
- const dotenv_1 = require("dotenv");
9
- const chalk_1 = __importDefault(require("chalk"));
10
- const inquirer_1 = __importDefault(require("inquirer"));
11
- const json_bigint_1 = __importDefault(require("json-bigint"));
12
- const commander_1 = require("commander");
13
- const id_1 = __importDefault(require("../id"));
14
- const config_1 = require("../config");
15
- const spinner_1 = require("../spinner");
16
- const paginate_1 = require("../paginate");
17
- const questions_1 = require("../questions");
18
- const parser_1 = require("../parser");
19
- const proxy_1 = require("./proxy");
20
- const console_1 = require("./console");
21
- const sdks_1 = require("../sdks");
22
- const functions_1 = require("./functions");
23
- const sites_1 = require("./sites");
24
- const databases_1 = require("./databases");
25
- const tables_db_1 = require("./tables-db");
26
- const storage_1 = require("./storage");
27
- const messaging_1 = require("./messaging");
28
- const teams_1 = require("./teams");
29
- const projects_1 = require("./projects");
30
- const utils_1 = require("../utils");
31
- const JSONbigNative = (0, json_bigint_1.default)({ storeAsString: false });
32
- const STEP_SIZE = 100; // Resources
1
+ import fs from "fs";
2
+ import { parse as parseDotenv } from "dotenv";
3
+ import chalk from "chalk";
4
+ import inquirer from "inquirer";
5
+ import { Command } from "commander";
6
+ import ID from "../id.js";
7
+ import { EXECUTABLE_NAME } from "../constants.js";
8
+ import { localConfig, globalConfig, KeysFunction, KeysSite, KeysTopics, KeysStorage, KeysTeams, KeysCollection, KeysTable, } from "../config.js";
9
+ import { createSettingsObject } from "../utils.js";
10
+ import { Spinner, SPINNER_DOTS } from "../spinner.js";
11
+ import { paginate } from "../paginate.js";
12
+ import { pushDeployment } from "./utils/deployment.js";
13
+ import { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionsPushTables, questionsPushMessagingTopics, questionsPushResources, } from "../questions.js";
14
+ import { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable, } from "../parser.js";
15
+ import { getProxyService, getConsoleService, getFunctionsService, getSitesService, getDatabasesService, getTablesDBService, getStorageService, getMessagingService, getTeamsService, getProjectsService, } from "../services.js";
16
+ import { sdkForProject, sdkForConsole } from "../sdks.js";
17
+ import { AppwriteException, Query, } from "@appwrite.io/console";
18
+ import { checkDeployConditions } from "../utils.js";
19
+ import { Pools } from "./utils/pools.js";
20
+ import { Attributes } from "./utils/attributes.js";
21
+ import { getConfirmation, approveChanges, getObjectChanges, } from "./utils/change-approval.js";
22
+ import { checkAndApplyTablesDBChanges } from "./utils/database-sync.js";
33
23
  const POLL_DEBOUNCE = 2000; // Milliseconds
34
- const POLL_MAX_DEBOUNCE = 1800; // Times of POLL_DEBOUNCE (1 hour)
35
24
  const POLL_DEFAULT_VALUE = 30;
36
- let pollMaxDebounces = POLL_DEFAULT_VALUE;
37
- const changeableKeys = ['status', 'required', 'xdefault', 'elements', 'min', 'max', 'default', 'error'];
38
- const awaitPools = {
39
- wipeAttributes: async (databaseId, collectionId, iteration = 1) => {
40
- if (iteration > pollMaxDebounces) {
41
- return false;
42
- }
43
- const { total } = await (0, databases_1.databasesListAttributes)({
44
- databaseId,
45
- collectionId,
46
- queries: [JSON.stringify({ method: 'limit', values: [1] })],
47
- parseOutput: false
48
- });
49
- if (total === 0) {
50
- return true;
51
- }
52
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
53
- let steps = Math.max(1, Math.ceil(total / STEP_SIZE));
54
- if (steps > 1 && iteration === 1) {
55
- pollMaxDebounces *= steps;
56
- (0, parser_1.log)('Found a large number of attributes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
25
+ const DEPLOYMENT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
26
+ export class Push {
27
+ projectClient;
28
+ consoleClient;
29
+ silent;
30
+ constructor(projectClient, consoleClient, silent = false) {
31
+ this.projectClient = projectClient;
32
+ this.consoleClient = consoleClient;
33
+ this.silent = silent;
34
+ }
35
+ /**
36
+ * Log a message (respects silent mode)
37
+ */
38
+ log(message) {
39
+ if (!this.silent) {
40
+ log(message);
41
+ }
42
+ }
43
+ /**
44
+ * Log a success message (respects silent mode)
45
+ */
46
+ success(message) {
47
+ if (!this.silent) {
48
+ success(message);
49
+ }
50
+ }
51
+ /**
52
+ * Log a warning message (respects silent mode)
53
+ */
54
+ warn(message) {
55
+ if (!this.silent) {
56
+ warn(message);
57
+ }
58
+ }
59
+ /**
60
+ * Log an error message (respects silent mode)
61
+ */
62
+ error(message) {
63
+ if (!this.silent) {
64
+ error(message);
65
+ }
66
+ }
67
+ async pushResources(config, options = { all: true, skipDeprecated: true }) {
68
+ const { skipDeprecated = true } = options;
69
+ const results = {};
70
+ const allErrors = [];
71
+ const shouldPushAll = options.all === true;
72
+ // Push settings
73
+ if ((shouldPushAll || options.settings) &&
74
+ (config.projectName || config.settings)) {
75
+ try {
76
+ this.log("Pushing settings ...");
77
+ await this.pushSettings({
78
+ projectId: config.projectId,
79
+ projectName: config.projectName,
80
+ settings: config.settings,
81
+ });
82
+ this.success(`Successfully pushed ${chalk.bold("all")} project settings.`);
83
+ results.settings = { success: true };
57
84
  }
58
- }
59
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
60
- return await awaitPools.wipeAttributes(databaseId, collectionId, iteration + 1);
61
- },
62
- wipeIndexes: async (databaseId, collectionId, iteration = 1) => {
63
- if (iteration > pollMaxDebounces) {
64
- return false;
65
- }
66
- const { total } = await (0, databases_1.databasesListIndexes)({
67
- databaseId,
68
- collectionId,
69
- queries: [JSON.stringify({ method: 'limit', values: [1] })],
70
- parseOutput: false
71
- });
72
- if (total === 0) {
73
- return true;
74
- }
75
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
76
- let steps = Math.max(1, Math.ceil(total / STEP_SIZE));
77
- if (steps > 1 && iteration === 1) {
78
- pollMaxDebounces *= steps;
79
- (0, parser_1.log)('Found a large number of indexes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
85
+ catch (e) {
86
+ allErrors.push(e);
87
+ results.settings = { success: false, error: e.message };
80
88
  }
81
89
  }
82
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
83
- return await awaitPools.wipeIndexes(databaseId, collectionId, iteration + 1);
84
- },
85
- deleteAttributes: async (databaseId, collectionId, attributeKeys, iteration = 1) => {
86
- if (iteration > pollMaxDebounces) {
87
- return false;
88
- }
89
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
90
- let steps = Math.max(1, Math.ceil(attributeKeys.length / STEP_SIZE));
91
- if (steps > 1 && iteration === 1) {
92
- pollMaxDebounces *= steps;
93
- (0, parser_1.log)('Found a large number of attributes to be deleted. Increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
90
+ // Push buckets
91
+ if ((shouldPushAll || options.buckets) &&
92
+ config.buckets &&
93
+ config.buckets.length > 0) {
94
+ try {
95
+ this.log("Pushing buckets ...");
96
+ const result = await this.pushBuckets(config.buckets);
97
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} buckets.`);
98
+ results.buckets = result;
99
+ allErrors.push(...result.errors);
94
100
  }
95
- }
96
- const { attributes } = await (0, paginate_1.paginate)(databases_1.databasesListAttributes, {
97
- databaseId,
98
- collectionId,
99
- parseOutput: false
100
- }, 100, 'attributes');
101
- const ready = attributeKeys.filter((attribute) => attributes.includes(attribute.key));
102
- if (ready.length === 0) {
103
- return true;
104
- }
105
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
106
- return await awaitPools.expectAttributes(databaseId, collectionId, attributeKeys, iteration + 1);
107
- },
108
- expectAttributes: async (databaseId, collectionId, attributeKeys, iteration = 1) => {
109
- if (iteration > pollMaxDebounces) {
110
- return false;
111
- }
112
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
113
- let steps = Math.max(1, Math.ceil(attributeKeys.length / STEP_SIZE));
114
- if (steps > 1 && iteration === 1) {
115
- pollMaxDebounces *= steps;
116
- (0, parser_1.log)('Creating a large number of attributes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
101
+ catch (e) {
102
+ allErrors.push(e);
103
+ results.buckets = { successfullyPushed: 0, errors: [e] };
117
104
  }
118
105
  }
119
- const { attributes } = await (0, paginate_1.paginate)(databases_1.databasesListAttributes, {
120
- databaseId,
121
- collectionId,
122
- parseOutput: false
123
- }, 100, 'attributes');
124
- const ready = attributes
125
- .filter((attribute) => {
126
- if (attributeKeys.includes(attribute.key)) {
127
- if (['stuck', 'failed'].includes(attribute.status)) {
128
- throw new Error(`Attribute '${attribute.key}' failed!`);
129
- }
130
- return attribute.status === 'available';
106
+ // Push teams
107
+ if ((shouldPushAll || options.teams) &&
108
+ config.teams &&
109
+ config.teams.length > 0) {
110
+ try {
111
+ this.log("Pushing teams ...");
112
+ const result = await this.pushTeams(config.teams);
113
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} teams.`);
114
+ results.teams = result;
115
+ allErrors.push(...result.errors);
131
116
  }
132
- return false;
133
- })
134
- .map((attribute) => attribute.key);
135
- if (ready.length === attributeKeys.length) {
136
- return true;
137
- }
138
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
139
- return await awaitPools.expectAttributes(databaseId, collectionId, attributeKeys, iteration + 1);
140
- },
141
- deleteIndexes: async (databaseId, collectionId, indexesKeys, iteration = 1) => {
142
- if (iteration > pollMaxDebounces) {
143
- return false;
144
- }
145
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
146
- let steps = Math.max(1, Math.ceil(indexesKeys.length / STEP_SIZE));
147
- if (steps > 1 && iteration === 1) {
148
- pollMaxDebounces *= steps;
149
- (0, parser_1.log)('Found a large number of indexes to be deleted. Increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
117
+ catch (e) {
118
+ allErrors.push(e);
119
+ results.teams = { successfullyPushed: 0, errors: [e] };
150
120
  }
151
121
  }
152
- const { indexes } = await (0, paginate_1.paginate)(databases_1.databasesListIndexes, {
153
- databaseId,
154
- collectionId,
155
- parseOutput: false
156
- }, 100, 'indexes');
157
- const ready = indexesKeys.filter((index) => indexes.includes(index.key));
158
- if (ready.length === 0) {
159
- return true;
160
- }
161
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
162
- return await awaitPools.expectIndexes(databaseId, collectionId, indexesKeys, iteration + 1);
163
- },
164
- expectIndexes: async (databaseId, collectionId, indexKeys, iteration = 1) => {
165
- if (iteration > pollMaxDebounces) {
166
- return false;
167
- }
168
- if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
169
- let steps = Math.max(1, Math.ceil(indexKeys.length / STEP_SIZE));
170
- if (steps > 1 && iteration === 1) {
171
- pollMaxDebounces *= steps;
172
- (0, parser_1.log)('Creating a large number of indexes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes');
122
+ // Push messaging topics
123
+ if ((shouldPushAll || options.topics) &&
124
+ config.topics &&
125
+ config.topics.length > 0) {
126
+ try {
127
+ this.log("Pushing topics ...");
128
+ const result = await this.pushMessagingTopics(config.topics);
129
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} topics.`);
130
+ results.topics = result;
131
+ allErrors.push(...result.errors);
173
132
  }
174
- }
175
- const { indexes } = await (0, paginate_1.paginate)(databases_1.databasesListIndexes, {
176
- databaseId,
177
- collectionId,
178
- parseOutput: false
179
- }, 100, 'indexes');
180
- const ready = indexes
181
- .filter((index) => {
182
- if (indexKeys.includes(index.key)) {
183
- if (['stuck', 'failed'].includes(index.status)) {
184
- throw new Error(`Index '${index.key}' failed!`);
185
- }
186
- return index.status === 'available';
133
+ catch (e) {
134
+ allErrors.push(e);
135
+ results.topics = { successfullyPushed: 0, errors: [e] };
187
136
  }
188
- return false;
189
- })
190
- .map((index) => index.key);
191
- if (ready.length >= indexKeys.length) {
192
- return true;
193
- }
194
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
195
- return await awaitPools.expectIndexes(databaseId, collectionId, indexKeys, iteration + 1);
196
- },
197
- };
198
- const getConfirmation = async () => {
199
- if (parser_1.cliConfig.force) {
200
- return true;
201
- }
202
- async function fixConfirmation() {
203
- const answers = await inquirer_1.default.prompt(questions_1.questionPushChangesConfirmation);
204
- if (answers.changes !== 'YES' && answers.changes !== 'NO') {
205
- return await fixConfirmation();
206
137
  }
207
- return answers.changes;
208
- }
209
- let answers = await inquirer_1.default.prompt(questions_1.questionPushChanges);
210
- if (answers.changes !== 'YES' && answers.changes !== 'NO') {
211
- answers.changes = await fixConfirmation();
212
- }
213
- if (answers.changes === 'YES') {
214
- return true;
215
- }
216
- (0, parser_1.warn)('Skipping push action. Changes were not applied.');
217
- return false;
218
- };
219
- const isEmpty = (value) => (value === null || value === undefined || (typeof value === "string" && value.trim().length === 0) || (Array.isArray(value) && value.length === 0));
220
- const approveChanges = async (resource, resourceGetFunction, keys, resourceName, resourcePlural, skipKeys = [], secondId = '', secondResourceName = '') => {
221
- (0, parser_1.log)('Checking for changes ...');
222
- const changes = [];
223
- await Promise.all(resource.map(async (localResource) => {
224
- try {
225
- const options = {
226
- [resourceName]: localResource['$id'],
227
- parseOutput: false,
228
- };
229
- if (secondId !== '' && secondResourceName !== '') {
230
- options[secondResourceName] = localResource[secondId];
231
- }
232
- const remoteResource = await resourceGetFunction(options);
233
- for (let [key, value] of Object.entries((0, config_1.whitelistKeys)(remoteResource, keys))) {
234
- if (skipKeys.includes(key)) {
235
- continue;
236
- }
237
- if (isEmpty(value) && isEmpty(localResource[key])) {
238
- continue;
239
- }
240
- if (Array.isArray(value) && Array.isArray(localResource[key])) {
241
- if (JSON.stringify(value) !== JSON.stringify(localResource[key])) {
242
- changes.push({
243
- id: localResource['$id'],
244
- key,
245
- remote: chalk_1.default.red(value.join('\n')),
246
- local: chalk_1.default.green(localResource[key].join('\n'))
247
- });
248
- }
249
- }
250
- else if (value !== localResource[key]) {
251
- changes.push({
252
- id: localResource['$id'],
253
- key,
254
- remote: chalk_1.default.red(value),
255
- local: chalk_1.default.green(localResource[key])
256
- });
257
- }
138
+ // Push functions
139
+ if ((shouldPushAll || options.functions) &&
140
+ config.functions &&
141
+ config.functions.length > 0) {
142
+ try {
143
+ this.log("Pushing functions ...");
144
+ const result = await this.pushFunctions(config.functions, options.functionOptions);
145
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} functions.`);
146
+ results.functions = result;
147
+ allErrors.push(...result.errors);
258
148
  }
259
- }
260
- catch (e) {
261
- if (Number(e.code) !== 404) {
262
- throw e;
149
+ catch (e) {
150
+ allErrors.push(e);
151
+ results.functions = {
152
+ successfullyPushed: 0,
153
+ successfullyDeployed: 0,
154
+ failedDeployments: [],
155
+ errors: [e],
156
+ };
263
157
  }
264
158
  }
265
- }));
266
- if (changes.length === 0) {
267
- return true;
268
- }
269
- (0, parser_1.drawTable)(changes);
270
- if ((await getConfirmation()) === true) {
271
- return true;
272
- }
273
- (0, parser_1.success)(`Successfully pushed 0 ${resourcePlural}.`);
274
- return false;
275
- };
276
- const getObjectChanges = (remote, local, index, what) => {
277
- const changes = [];
278
- if (remote[index] && local[index]) {
279
- for (let [service, status] of Object.entries(remote[index])) {
280
- const localValue = local[index][service];
281
- let valuesEqual = false;
282
- if (Array.isArray(status) && Array.isArray(localValue)) {
283
- valuesEqual = JSON.stringify(status) === JSON.stringify(localValue);
284
- }
285
- else {
286
- valuesEqual = status === localValue;
159
+ // Push sites
160
+ if ((shouldPushAll || options.sites) &&
161
+ config.sites &&
162
+ config.sites.length > 0) {
163
+ try {
164
+ this.log("Pushing sites ...");
165
+ const result = await this.pushSites(config.sites, options.siteOptions);
166
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} sites.`);
167
+ results.sites = result;
168
+ allErrors.push(...result.errors);
287
169
  }
288
- if (!valuesEqual) {
289
- changes.push({ group: what, setting: service, remote: chalk_1.default.red(status), local: chalk_1.default.green(localValue) });
170
+ catch (e) {
171
+ allErrors.push(e);
172
+ results.sites = {
173
+ successfullyPushed: 0,
174
+ successfullyDeployed: 0,
175
+ failedDeployments: [],
176
+ errors: [e],
177
+ };
290
178
  }
291
179
  }
292
- }
293
- return changes;
294
- };
295
- const createAttribute = (databaseId, collectionId, attribute) => {
296
- switch (attribute.type) {
297
- case 'string':
298
- switch (attribute.format) {
299
- case 'email':
300
- return (0, databases_1.databasesCreateEmailAttribute)({
301
- databaseId,
302
- collectionId,
303
- key: attribute.key,
304
- required: attribute.required,
305
- xdefault: attribute.default,
306
- array: attribute.array,
307
- parseOutput: false
308
- });
309
- case 'url':
310
- return (0, databases_1.databasesCreateUrlAttribute)({
311
- databaseId,
312
- collectionId,
313
- key: attribute.key,
314
- required: attribute.required,
315
- xdefault: attribute.default,
316
- array: attribute.array,
317
- parseOutput: false
318
- });
319
- case 'ip':
320
- return (0, databases_1.databasesCreateIpAttribute)({
321
- databaseId,
322
- collectionId,
323
- key: attribute.key,
324
- required: attribute.required,
325
- xdefault: attribute.default,
326
- array: attribute.array,
327
- parseOutput: false
328
- });
329
- case 'enum':
330
- return (0, databases_1.databasesCreateEnumAttribute)({
331
- databaseId,
332
- collectionId,
333
- key: attribute.key,
334
- elements: attribute.elements,
335
- required: attribute.required,
336
- xdefault: attribute.default,
337
- array: attribute.array,
338
- parseOutput: false
339
- });
340
- default:
341
- return (0, databases_1.databasesCreateStringAttribute)({
342
- databaseId,
343
- collectionId,
344
- key: attribute.key,
345
- size: attribute.size,
346
- required: attribute.required,
347
- xdefault: attribute.default,
348
- array: attribute.array,
349
- encrypt: attribute.encrypt,
350
- parseOutput: false
351
- });
180
+ // Push tables
181
+ if ((shouldPushAll || options.tables) &&
182
+ config.tables &&
183
+ config.tables.length > 0) {
184
+ try {
185
+ this.log("Pushing tables ...");
186
+ const result = await this.pushTables(config.tables, {
187
+ attempts: options.tableOptions?.attempts,
188
+ skipConfirmation: options.skipConfirmation,
189
+ });
190
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} tables.`);
191
+ results.tables = result;
192
+ allErrors.push(...result.errors);
352
193
  }
353
- case 'integer':
354
- return (0, databases_1.databasesCreateIntegerAttribute)({
355
- databaseId,
356
- collectionId,
357
- key: attribute.key,
358
- required: attribute.required,
359
- min: attribute.min,
360
- max: attribute.max,
361
- xdefault: attribute.default,
362
- array: attribute.array,
363
- parseOutput: false
364
- });
365
- case 'double':
366
- return (0, databases_1.databasesCreateFloatAttribute)({
367
- databaseId,
368
- collectionId,
369
- key: attribute.key,
370
- required: attribute.required,
371
- min: attribute.min,
372
- max: attribute.max,
373
- xdefault: attribute.default,
374
- array: attribute.array,
375
- parseOutput: false
376
- });
377
- case 'boolean':
378
- return (0, databases_1.databasesCreateBooleanAttribute)({
379
- databaseId,
380
- collectionId,
381
- key: attribute.key,
382
- required: attribute.required,
383
- xdefault: attribute.default,
384
- array: attribute.array,
385
- parseOutput: false
386
- });
387
- case 'datetime':
388
- return (0, databases_1.databasesCreateDatetimeAttribute)({
389
- databaseId,
390
- collectionId,
391
- key: attribute.key,
392
- required: attribute.required,
393
- xdefault: attribute.default,
394
- array: attribute.array,
395
- parseOutput: false
396
- });
397
- case 'relationship':
398
- return (0, databases_1.databasesCreateRelationshipAttribute)({
399
- databaseId,
400
- collectionId,
401
- relatedCollectionId: attribute.relatedTable ?? attribute.relatedCollection,
402
- type: attribute.relationType,
403
- twoWay: attribute.twoWay,
404
- key: attribute.key,
405
- twoWayKey: attribute.twoWayKey,
406
- onDelete: attribute.onDelete,
407
- parseOutput: false
408
- });
409
- case 'point':
410
- return (0, databases_1.databasesCreatePointAttribute)({
411
- databaseId,
412
- collectionId,
413
- key: attribute.key,
414
- required: attribute.required,
415
- xdefault: attribute.default,
416
- parseOutput: false
417
- });
418
- case 'linestring':
419
- return (0, databases_1.databasesCreateLineAttribute)({
420
- databaseId,
421
- collectionId,
422
- key: attribute.key,
423
- required: attribute.required,
424
- xdefault: attribute.default,
425
- parseOutput: false
426
- });
427
- case 'polygon':
428
- return (0, databases_1.databasesCreatePolygonAttribute)({
429
- databaseId,
430
- collectionId,
431
- key: attribute.key,
432
- required: attribute.required,
433
- xdefault: attribute.default,
434
- parseOutput: false
435
- });
436
- default:
437
- throw new Error(`Unsupported attribute type: ${attribute.type}`);
438
- }
439
- };
440
- const updateAttribute = (databaseId, collectionId, attribute) => {
441
- switch (attribute.type) {
442
- case 'string':
443
- switch (attribute.format) {
444
- case 'email':
445
- return (0, databases_1.databasesUpdateEmailAttribute)({
446
- databaseId,
447
- collectionId,
448
- key: attribute.key,
449
- required: attribute.required,
450
- xdefault: attribute.default,
451
- array: attribute.array,
452
- parseOutput: false
453
- });
454
- case 'url':
455
- return (0, databases_1.databasesUpdateUrlAttribute)({
456
- databaseId,
457
- collectionId,
458
- key: attribute.key,
459
- required: attribute.required,
460
- xdefault: attribute.default,
461
- array: attribute.array,
462
- parseOutput: false
463
- });
464
- case 'ip':
465
- return (0, databases_1.databasesUpdateIpAttribute)({
466
- databaseId,
467
- collectionId,
468
- key: attribute.key,
469
- required: attribute.required,
470
- xdefault: attribute.default,
471
- array: attribute.array,
472
- parseOutput: false
473
- });
474
- case 'enum':
475
- return (0, databases_1.databasesUpdateEnumAttribute)({
476
- databaseId,
477
- collectionId,
478
- key: attribute.key,
479
- elements: attribute.elements,
480
- required: attribute.required,
481
- xdefault: attribute.default,
482
- array: attribute.array,
483
- parseOutput: false
484
- });
485
- default:
486
- return (0, databases_1.databasesUpdateStringAttribute)({
487
- databaseId,
488
- collectionId,
489
- key: attribute.key,
490
- size: attribute.size,
491
- required: attribute.required,
492
- xdefault: attribute.default,
493
- array: attribute.array,
494
- parseOutput: false
495
- });
194
+ catch (e) {
195
+ allErrors.push(e);
196
+ results.tables = { successfullyPushed: 0, errors: [e] };
496
197
  }
497
- case 'integer':
498
- return (0, databases_1.databasesUpdateIntegerAttribute)({
499
- databaseId,
500
- collectionId,
501
- key: attribute.key,
502
- required: attribute.required,
503
- min: attribute.min,
504
- max: attribute.max,
505
- xdefault: attribute.default,
506
- array: attribute.array,
507
- parseOutput: false
508
- });
509
- case 'double':
510
- return (0, databases_1.databasesUpdateFloatAttribute)({
511
- databaseId,
512
- collectionId,
513
- key: attribute.key,
514
- required: attribute.required,
515
- min: attribute.min,
516
- max: attribute.max,
517
- xdefault: attribute.default,
518
- array: attribute.array,
519
- parseOutput: false
520
- });
521
- case 'boolean':
522
- return (0, databases_1.databasesUpdateBooleanAttribute)({
523
- databaseId,
524
- collectionId,
525
- key: attribute.key,
526
- required: attribute.required,
527
- xdefault: attribute.default,
528
- array: attribute.array,
529
- parseOutput: false
530
- });
531
- case 'datetime':
532
- return (0, databases_1.databasesUpdateDatetimeAttribute)({
533
- databaseId,
534
- collectionId,
535
- key: attribute.key,
536
- required: attribute.required,
537
- xdefault: attribute.default,
538
- array: attribute.array,
539
- parseOutput: false
540
- });
541
- case 'relationship':
542
- return (0, databases_1.databasesUpdateRelationshipAttribute)({
543
- databaseId,
544
- collectionId,
545
- relatedCollectionId: attribute.relatedTable ?? attribute.relatedCollection,
546
- type: attribute.relationType,
547
- twoWay: attribute.twoWay,
548
- key: attribute.key,
549
- twoWayKey: attribute.twoWayKey,
550
- onDelete: attribute.onDelete,
551
- parseOutput: false
552
- });
553
- case 'point':
554
- return (0, databases_1.databasesUpdatePointAttribute)({
555
- databaseId,
556
- collectionId,
557
- key: attribute.key,
558
- required: attribute.required,
559
- xdefault: attribute.default,
560
- parseOutput: false
561
- });
562
- case 'linestring':
563
- return (0, databases_1.databasesUpdateLineAttribute)({
564
- databaseId,
565
- collectionId,
566
- key: attribute.key,
567
- required: attribute.required,
568
- xdefault: attribute.default,
569
- parseOutput: false
570
- });
571
- case 'polygon':
572
- return (0, databases_1.databasesUpdatePolygonAttribute)({
573
- databaseId,
574
- collectionId,
575
- key: attribute.key,
576
- required: attribute.required,
577
- xdefault: attribute.default,
578
- parseOutput: false
579
- });
580
- default:
581
- throw new Error(`Unsupported attribute type: ${attribute.type}`);
582
- }
583
- };
584
- const deleteAttribute = async (collection, attribute, isIndex = false) => {
585
- (0, parser_1.log)(`Deleting ${isIndex ? 'index' : 'attribute'} ${attribute.key} of ${collection.name} ( ${collection['$id']} )`);
586
- if (isIndex) {
587
- await (0, databases_1.databasesDeleteIndex)({
588
- databaseId: collection['databaseId'],
589
- collectionId: collection['$id'],
590
- key: attribute.key,
591
- parseOutput: false
592
- });
593
- return;
594
- }
595
- await (0, databases_1.databasesDeleteAttribute)({
596
- databaseId: collection['databaseId'],
597
- collectionId: collection['$id'],
598
- key: attribute.key,
599
- parseOutput: false
600
- });
601
- };
602
- const isEqual = (a, b) => {
603
- if (a === b)
604
- return true;
605
- if (a && b && typeof a === 'object' && typeof b === 'object') {
606
- if (a.constructor && a.constructor.name === 'BigNumber' &&
607
- b.constructor && b.constructor.name === 'BigNumber') {
608
- return a.eq(b);
609
- }
610
- if (typeof a.equals === 'function') {
611
- return a.equals(b);
612
- }
613
- if (typeof a.eq === 'function') {
614
- return a.eq(b);
615
- }
616
- }
617
- if (typeof a === 'number' && typeof b === 'number') {
618
- if (isNaN(a) && isNaN(b))
619
- return true;
620
- if (!isFinite(a) && !isFinite(b))
621
- return a === b;
622
- return Math.abs(a - b) < Number.EPSILON;
623
- }
624
- return false;
625
- };
626
- const compareAttribute = (remote, local, reason, key) => {
627
- if (isEmpty(remote) && isEmpty(local)) {
628
- return reason;
629
- }
630
- if (Array.isArray(remote) && Array.isArray(local)) {
631
- if (JSON.stringify(remote) !== JSON.stringify(local)) {
632
- const bol = reason === '' ? '' : '\n';
633
- reason += `${bol}${key} changed from ${chalk_1.default.red(remote)} to ${chalk_1.default.green(local)}`;
634
198
  }
635
- }
636
- else if (!isEqual(remote, local)) {
637
- const bol = reason === '' ? '' : '\n';
638
- reason += `${bol}${key} changed from ${chalk_1.default.red(remote)} to ${chalk_1.default.green(local)}`;
639
- }
640
- return reason;
641
- };
642
- /**
643
- * Check if attribute non-changeable fields has been changed
644
- * If so return the differences as an object.
645
- */
646
- const checkAttributeChanges = (remote, local, collection, recreating = true) => {
647
- if (local === undefined) {
648
- return undefined;
649
- }
650
- const keyName = `${chalk_1.default.yellow(local.key)} in ${collection.name} (${collection['$id']})`;
651
- const action = chalk_1.default.cyan(recreating ? 'recreating' : 'changing');
652
- let reason = '';
653
- let attribute = recreating ? remote : local;
654
- for (let key of Object.keys(remote)) {
655
- if (!config_1.KeysAttributes.has(key)) {
656
- continue;
657
- }
658
- if (changeableKeys.includes(key)) {
659
- if (!recreating) {
660
- reason = compareAttribute(remote[key], local[key], reason, key);
199
+ // Push collections (skipDeprecated only applies when pushing all, explicit collections option takes precedence)
200
+ if ((options.collections || (shouldPushAll && !skipDeprecated)) &&
201
+ config.collections &&
202
+ config.collections.length > 0) {
203
+ try {
204
+ this.log("Pushing collections ...");
205
+ // Add database names to collections
206
+ const collectionsWithDbNames = config.collections.map((collection) => {
207
+ const database = config.databases?.find((db) => db.$id === collection.databaseId);
208
+ return {
209
+ ...collection,
210
+ databaseName: database?.name ?? collection.databaseId,
211
+ };
212
+ });
213
+ const result = await this.pushCollections(collectionsWithDbNames, {
214
+ skipConfirmation: options.skipConfirmation,
215
+ });
216
+ this.success(`Successfully pushed ${chalk.bold(result.successfullyPushed)} collections.`);
217
+ results.collections = result;
218
+ allErrors.push(...result.errors);
661
219
  }
662
- continue;
663
- }
664
- if (!recreating) {
665
- continue;
666
- }
667
- reason = compareAttribute(remote[key], local[key], reason, key);
668
- }
669
- return reason === '' ? undefined : { key: keyName, attribute, reason, action };
670
- };
671
- /**
672
- * Check if attributes contain the given attribute
673
- */
674
- const attributesContains = (attribute, attributes) => attributes.find((attr) => attr.key === attribute.key);
675
- const generateChangesObject = (attribute, collection, isAdding) => {
676
- return {
677
- key: `${chalk_1.default.yellow(attribute.key)} in ${collection.name} (${collection['$id']})`,
678
- attribute: attribute,
679
- reason: isAdding ? 'Field isn\'t present on the remote server' : 'Field isn\'t present on the appwrite.config.json file',
680
- action: isAdding ? chalk_1.default.green('adding') : chalk_1.default.red('deleting')
681
- };
682
- };
683
- /**
684
- * Filter deleted and recreated attributes,
685
- * return list of attributes to create
686
- */
687
- const attributesToCreate = async (remoteAttributes, localAttributes, collection, isIndex = false) => {
688
- const deleting = remoteAttributes.filter((attribute) => !attributesContains(attribute, localAttributes)).map((attr) => generateChangesObject(attr, collection, false));
689
- const adding = localAttributes.filter((attribute) => !attributesContains(attribute, remoteAttributes)).map((attr) => generateChangesObject(attr, collection, true));
690
- const conflicts = remoteAttributes.map((attribute) => checkAttributeChanges(attribute, attributesContains(attribute, localAttributes), collection)).filter(attribute => attribute !== undefined);
691
- const changes = remoteAttributes.map((attribute) => checkAttributeChanges(attribute, attributesContains(attribute, localAttributes), collection, false))
692
- .filter(attribute => attribute !== undefined)
693
- .filter(attribute => conflicts.filter(attr => attribute.key === attr.key).length !== 1);
694
- let changedAttributes = [];
695
- const changing = [...deleting, ...adding, ...conflicts, ...changes];
696
- if (changing.length === 0) {
697
- return changedAttributes;
698
- }
699
- (0, parser_1.log)(!parser_1.cliConfig.force ? 'There are pending changes in your collection deployment' : 'List of applied changes');
700
- (0, parser_1.drawTable)(changing.map((change) => {
701
- return { Key: change.key, Action: change.action, Reason: change.reason, };
702
- }));
703
- if (!parser_1.cliConfig.force) {
704
- if (deleting.length > 0 && !isIndex) {
705
- console.log(`${chalk_1.default.red('------------------------------------------------------')}`);
706
- console.log(`${chalk_1.default.red('| WARNING: Attribute deletion may cause loss of data |')}`);
707
- console.log(`${chalk_1.default.red('------------------------------------------------------')}`);
708
- console.log();
709
- }
710
- if (conflicts.length > 0 && !isIndex) {
711
- console.log(`${chalk_1.default.red('--------------------------------------------------------')}`);
712
- console.log(`${chalk_1.default.red('| WARNING: Attribute recreation may cause loss of data |')}`);
713
- console.log(`${chalk_1.default.red('--------------------------------------------------------')}`);
714
- console.log();
715
- }
716
- if ((await getConfirmation()) !== true) {
717
- return changedAttributes;
718
- }
719
- }
720
- if (conflicts.length > 0) {
721
- changedAttributes = conflicts.map((change) => change.attribute);
722
- await Promise.all(changedAttributes.map((changed) => deleteAttribute(collection, changed, isIndex)));
723
- remoteAttributes = remoteAttributes.filter((attribute) => !attributesContains(attribute, changedAttributes));
724
- }
725
- if (changes.length > 0) {
726
- changedAttributes = changes.map((change) => change.attribute);
727
- await Promise.all(changedAttributes.map((changed) => updateAttribute(collection['databaseId'], collection['$id'], changed)));
728
- }
729
- const deletingAttributes = deleting.map((change) => change.attribute);
730
- await Promise.all(deletingAttributes.map((attribute) => deleteAttribute(collection, attribute, isIndex)));
731
- const attributeKeys = [...remoteAttributes.map((attribute) => attribute.key), ...deletingAttributes.map((attribute) => attribute.key)];
732
- if (attributeKeys.length) {
733
- const deleteAttributesPoolStatus = await awaitPools.deleteAttributes(collection['databaseId'], collection['$id'], attributeKeys);
734
- if (!deleteAttributesPoolStatus) {
735
- throw new Error("Attribute deletion timed out.");
736
- }
737
- }
738
- return localAttributes.filter((attribute) => !attributesContains(attribute, remoteAttributes));
739
- };
740
- const createIndexes = async (indexes, collection) => {
741
- (0, parser_1.log)(`Creating indexes ...`);
742
- for (let index of indexes) {
743
- await (0, databases_1.databasesCreateIndex)({
744
- databaseId: collection['databaseId'],
745
- collectionId: collection['$id'],
746
- key: index.key,
747
- type: index.type,
748
- attributes: index.columns ?? index.attributes,
749
- orders: index.orders,
750
- parseOutput: false
751
- });
752
- }
753
- const result = await awaitPools.expectIndexes(collection['databaseId'], collection['$id'], indexes.map((index) => index.key));
754
- if (!result) {
755
- throw new Error('Index creation timed out.');
756
- }
757
- (0, parser_1.success)(`Created ${indexes.length} indexes`);
758
- };
759
- const createAttributes = async (attributes, collection) => {
760
- for (let attribute of attributes) {
761
- if (attribute.side !== 'child') {
762
- await createAttribute(collection['databaseId'], collection['$id'], attribute);
763
- }
764
- }
765
- const result = await awaitPools.expectAttributes(collection['databaseId'], collection['$id'], collection.attributes.filter((attribute) => attribute.side !== 'child').map((attribute) => attribute.key));
766
- if (!result) {
767
- throw new Error(`Attribute creation timed out.`);
768
- }
769
- (0, parser_1.success)(`Created ${attributes.length} attributes`);
770
- };
771
- const createColumns = async (columns, table) => {
772
- for (let column of columns) {
773
- if (column.side !== 'child') {
774
- await createAttribute(table['databaseId'], table['$id'], column);
775
- }
776
- }
777
- const result = await awaitPools.expectAttributes(table['databaseId'], table['$id'], table.columns.filter((column) => column.side !== 'child').map((column) => column.key));
778
- if (!result) {
779
- throw new Error(`Column creation timed out.`);
780
- }
781
- (0, parser_1.success)(`Created ${columns.length} columns`);
782
- };
783
- const pushResources = async () => {
784
- const actions = {
785
- settings: pushSettings,
786
- functions: pushFunction,
787
- sites: pushSite,
788
- collections: pushCollection,
789
- tables: pushTable,
790
- buckets: pushBucket,
791
- teams: pushTeam,
792
- messages: pushMessagingTopic
793
- };
794
- if (parser_1.cliConfig.all) {
795
- for (let action of Object.values(actions)) {
796
- await action({ returnOnZero: true });
797
- }
798
- }
799
- else {
800
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushResources[0]);
801
- const action = actions[answers.resource];
802
- if (action !== undefined) {
803
- await action({ returnOnZero: true });
804
- }
805
- }
806
- };
807
- const pushSettings = async () => {
808
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
809
- try {
810
- let response = await (0, projects_1.projectsGet)({
811
- parseOutput: false,
812
- projectId: config_1.localConfig.getProject().projectId
813
- });
814
- const remoteSettings = config_1.localConfig.createSettingsObject(response ?? {});
815
- const localSettings = config_1.localConfig.getProject().projectSettings ?? {};
816
- (0, parser_1.log)('Checking for changes ...');
817
- const changes = [];
818
- changes.push(...(getObjectChanges(remoteSettings, localSettings, 'services', 'Service')));
819
- changes.push(...(getObjectChanges(remoteSettings['auth'] ?? {}, localSettings['auth'] ?? {}, 'methods', 'Auth method')));
820
- changes.push(...(getObjectChanges(remoteSettings['auth'] ?? {}, localSettings['auth'] ?? {}, 'security', 'Auth security')));
821
- if (changes.length > 0) {
822
- (0, parser_1.drawTable)(changes);
823
- if ((await getConfirmation()) !== true) {
824
- (0, parser_1.success)(`Successfully pushed 0 project settings.`);
825
- return;
220
+ catch (e) {
221
+ allErrors.push(e);
222
+ results.collections = { successfullyPushed: 0, errors: [e] };
826
223
  }
827
224
  }
225
+ return {
226
+ results,
227
+ errors: allErrors,
228
+ };
828
229
  }
829
- catch (e) {
830
- }
831
- try {
832
- (0, parser_1.log)("Pushing project settings ...");
833
- const projectId = config_1.localConfig.getProject().projectId;
834
- const projectName = config_1.localConfig.getProject().projectName;
835
- const settings = config_1.localConfig.getProject().projectSettings ?? {};
230
+ async pushSettings(config) {
231
+ const projectsService = await getProjectsService(this.consoleClient);
232
+ const projectId = config.projectId;
233
+ const projectName = config.projectName;
234
+ const settings = config.settings ?? {};
836
235
  if (projectName) {
837
- (0, parser_1.log)("Applying project name ...");
838
- await (0, projects_1.projectsUpdate)({
839
- projectId,
236
+ this.log("Applying project name ...");
237
+ await projectsService.update({
238
+ projectId: projectId,
840
239
  name: projectName,
841
- parseOutput: false
842
240
  });
843
241
  }
844
242
  if (settings.services) {
845
- (0, parser_1.log)("Applying service statuses ...");
243
+ this.log("Applying service statuses ...");
846
244
  for (let [service, status] of Object.entries(settings.services)) {
847
- await (0, projects_1.projectsUpdateServiceStatus)({
848
- projectId,
849
- service,
850
- status,
851
- parseOutput: false
245
+ await projectsService.updateServiceStatus({
246
+ projectId: projectId,
247
+ service: service,
248
+ status: status,
852
249
  });
853
250
  }
854
251
  }
855
252
  if (settings.auth) {
856
253
  if (settings.auth.security) {
857
- (0, parser_1.log)("Applying auth security settings ...");
858
- await (0, projects_1.projectsUpdateAuthDuration)({ projectId, duration: settings.auth.security.duration, parseOutput: false });
859
- await (0, projects_1.projectsUpdateAuthLimit)({ projectId, limit: settings.auth.security.limit, parseOutput: false });
860
- await (0, projects_1.projectsUpdateAuthSessionsLimit)({ projectId, limit: settings.auth.security.sessionsLimit, parseOutput: false });
861
- await (0, projects_1.projectsUpdateAuthPasswordDictionary)({ projectId, enabled: settings.auth.security.passwordDictionary, parseOutput: false });
862
- await (0, projects_1.projectsUpdateAuthPasswordHistory)({ projectId, limit: settings.auth.security.passwordHistory, parseOutput: false });
863
- await (0, projects_1.projectsUpdatePersonalDataCheck)({ projectId, enabled: settings.auth.security.personalDataCheck, parseOutput: false });
864
- await (0, projects_1.projectsUpdateSessionAlerts)({ projectId, alerts: settings.auth.security.sessionAlerts, parseOutput: false });
865
- await (0, projects_1.projectsUpdateMockNumbers)({ projectId, numbers: settings.auth.security.mockNumbers, parseOutput: false });
254
+ this.log("Applying auth security settings ...");
255
+ await projectsService.updateAuthDuration({
256
+ projectId,
257
+ duration: settings.auth.security.duration,
258
+ });
259
+ await projectsService.updateAuthLimit({
260
+ projectId,
261
+ limit: settings.auth.security.limit,
262
+ });
263
+ await projectsService.updateAuthSessionsLimit({
264
+ projectId,
265
+ limit: settings.auth.security.sessionsLimit,
266
+ });
267
+ await projectsService.updateAuthPasswordDictionary({
268
+ projectId,
269
+ enabled: settings.auth.security.passwordDictionary,
270
+ });
271
+ await projectsService.updateAuthPasswordHistory({
272
+ projectId,
273
+ limit: settings.auth.security.passwordHistory,
274
+ });
275
+ await projectsService.updatePersonalDataCheck({
276
+ projectId,
277
+ enabled: settings.auth.security.personalDataCheck,
278
+ });
279
+ await projectsService.updateSessionAlerts({
280
+ projectId,
281
+ alerts: settings.auth.security.sessionAlerts,
282
+ });
283
+ await projectsService.updateMockNumbers({
284
+ projectId,
285
+ numbers: settings.auth.security.mockNumbers,
286
+ });
866
287
  }
867
288
  if (settings.auth.methods) {
868
- (0, parser_1.log)("Applying auth methods statuses ...");
289
+ this.log("Applying auth methods statuses ...");
869
290
  for (let [method, status] of Object.entries(settings.auth.methods)) {
870
- await (0, projects_1.projectsUpdateAuthStatus)({
291
+ await projectsService.updateAuthStatus({
871
292
  projectId,
872
- method,
873
- status,
874
- parseOutput: false
293
+ method: method,
294
+ status: status,
875
295
  });
876
296
  }
877
297
  }
878
298
  }
879
- (0, parser_1.success)(`Successfully pushed ${chalk_1.default.bold('all')} project settings.`);
880
299
  }
881
- catch (e) {
882
- throw e;
883
- }
884
- };
885
- const pushSite = async ({ siteId, async: asyncDeploy, code, withVariables } = { returnOnZero: false }) => {
886
- process.chdir(config_1.localConfig.configDirectoryPath);
887
- const siteIds = [];
888
- if (siteId) {
889
- siteIds.push(siteId);
890
- }
891
- else if (parser_1.cliConfig.all) {
892
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
893
- const sites = config_1.localConfig.getSites();
894
- siteIds.push(...sites.map((site) => {
895
- return site.$id;
896
- }));
897
- }
898
- if (siteIds.length <= 0) {
899
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushSites[0]);
900
- if (answers.sites) {
901
- siteIds.push(...answers.sites);
300
+ async pushBuckets(buckets) {
301
+ let successfullyPushed = 0;
302
+ const errors = [];
303
+ for (const bucket of buckets) {
304
+ try {
305
+ this.log(`Pushing bucket ${chalk.bold(bucket["name"])} ...`);
306
+ const storageService = await getStorageService(this.projectClient);
307
+ try {
308
+ await storageService.getBucket(bucket["$id"]);
309
+ await storageService.updateBucket({
310
+ bucketId: bucket["$id"],
311
+ name: bucket.name,
312
+ permissions: bucket["$permissions"],
313
+ fileSecurity: bucket.fileSecurity,
314
+ enabled: bucket.enabled,
315
+ maximumFileSize: bucket.maximumFileSize,
316
+ allowedFileExtensions: bucket.allowedFileExtensions,
317
+ encryption: bucket.encryption,
318
+ antivirus: bucket.antivirus,
319
+ compression: bucket.compression,
320
+ });
321
+ }
322
+ catch (e) {
323
+ if (e instanceof AppwriteException && Number(e.code) === 404) {
324
+ await storageService.createBucket({
325
+ bucketId: bucket["$id"],
326
+ name: bucket.name,
327
+ permissions: bucket["$permissions"],
328
+ fileSecurity: bucket.fileSecurity,
329
+ enabled: bucket.enabled,
330
+ maximumFileSize: bucket.maximumFileSize,
331
+ allowedFileExtensions: bucket.allowedFileExtensions,
332
+ compression: bucket.compression,
333
+ encryption: bucket.encryption,
334
+ antivirus: bucket.antivirus,
335
+ });
336
+ }
337
+ else {
338
+ throw e;
339
+ }
340
+ }
341
+ successfullyPushed++;
342
+ }
343
+ catch (e) {
344
+ errors.push(e);
345
+ this.error(`Failed to push bucket ${bucket["name"]}: ${e.message}`);
346
+ }
902
347
  }
348
+ return {
349
+ successfullyPushed,
350
+ errors,
351
+ };
903
352
  }
904
- if (siteIds.length === 0) {
905
- (0, parser_1.log)("No sites found.");
906
- (0, parser_1.hint)("Use 'appwrite pull sites' to synchronize existing one, or use 'appwrite init site' to create a new one.");
907
- return;
908
- }
909
- let sites = siteIds.map((id) => {
910
- const sites = config_1.localConfig.getSites();
911
- const site = sites.find((s) => s.$id === id);
912
- if (!site) {
913
- throw new Error("Site '" + id + "' not found.");
914
- }
915
- return site;
916
- });
917
- (0, parser_1.log)('Validating sites ...');
918
- // Validation is done BEFORE pushing so the deployment process can be run in async with progress update
919
- for (let site of sites) {
920
- if (!site.buildCommand) {
921
- (0, parser_1.log)(`Site ${site.name} is missing build command.`);
922
- const answers = await inquirer_1.default.prompt(questions_1.questionsGetEntrypoint);
923
- site.buildCommand = answers.entrypoint;
924
- config_1.localConfig.addSite(site);
353
+ async pushTeams(teams) {
354
+ let successfullyPushed = 0;
355
+ const errors = [];
356
+ for (const team of teams) {
357
+ try {
358
+ this.log(`Pushing team ${chalk.bold(team["name"])} ...`);
359
+ const teamsService = await getTeamsService(this.projectClient);
360
+ try {
361
+ await teamsService.get(team["$id"]);
362
+ await teamsService.updateName({
363
+ teamId: team["$id"],
364
+ name: team.name,
365
+ });
366
+ }
367
+ catch (e) {
368
+ if (e instanceof AppwriteException && Number(e.code) === 404) {
369
+ await teamsService.create({
370
+ teamId: team["$id"],
371
+ name: team.name,
372
+ });
373
+ }
374
+ else {
375
+ throw e;
376
+ }
377
+ }
378
+ successfullyPushed++;
379
+ }
380
+ catch (e) {
381
+ errors.push(e);
382
+ this.error(`Failed to push team ${team["name"]}: ${e.message}`);
383
+ }
925
384
  }
385
+ return {
386
+ successfullyPushed,
387
+ errors,
388
+ };
926
389
  }
927
- if (!(await approveChanges(sites, sites_1.sitesGet, config_1.KeysSite, 'siteId', 'sites', ['vars']))) {
928
- return;
929
- }
930
- (0, parser_1.log)('Pushing sites ...');
931
- spinner_1.Spinner.start(false);
932
- let successfullyPushed = 0;
933
- let successfullyDeployed = 0;
934
- const failedDeployments = [];
935
- const errors = [];
936
- await Promise.all(sites.map(async (site) => {
937
- let response = {};
938
- const ignore = site.ignore ? 'appwrite.config.json' : '.gitignore';
939
- let siteExists = false;
940
- let deploymentCreated = false;
941
- const updaterRow = new spinner_1.Spinner({ status: '', resource: site.name, id: site['$id'], end: `Ignoring using: ${ignore}` });
942
- updaterRow.update({ status: 'Getting' }).startSpinner(spinner_1.SPINNER_DOTS);
943
- try {
944
- response = await (0, sites_1.sitesGet)({
945
- siteId: site['$id'],
946
- parseOutput: false,
390
+ async pushMessagingTopics(topics) {
391
+ let successfullyPushed = 0;
392
+ const errors = [];
393
+ for (const topic of topics) {
394
+ try {
395
+ this.log(`Pushing topic ${chalk.bold(topic["name"])} ...`);
396
+ const messagingService = await getMessagingService(this.projectClient);
397
+ try {
398
+ await messagingService.getTopic(topic["$id"]);
399
+ await messagingService.updateTopic({
400
+ topicId: topic["$id"],
401
+ name: topic.name,
402
+ subscribe: topic.subscribe,
403
+ });
404
+ }
405
+ catch (e) {
406
+ if (e instanceof AppwriteException && Number(e.code) === 404) {
407
+ await messagingService.createTopic({
408
+ topicId: topic["$id"],
409
+ name: topic.name,
410
+ subscribe: topic.subscribe,
411
+ });
412
+ }
413
+ else {
414
+ throw e;
415
+ }
416
+ }
417
+ this.success(`Pushed ${topic.name} ( ${topic["$id"]} )`);
418
+ successfullyPushed++;
419
+ }
420
+ catch (e) {
421
+ errors.push(e);
422
+ this.error(`Failed to push topic ${topic["name"]}: ${e.message}`);
423
+ }
424
+ }
425
+ return {
426
+ successfullyPushed,
427
+ errors,
428
+ };
429
+ }
430
+ async pushFunctions(functions, options = {}) {
431
+ const { async: asyncDeploy, code, withVariables } = options;
432
+ Spinner.start(false);
433
+ let successfullyPushed = 0;
434
+ let successfullyDeployed = 0;
435
+ const failedDeployments = [];
436
+ const errors = [];
437
+ await Promise.all(functions.map(async (func) => {
438
+ let response = {};
439
+ const ignore = func.ignore ? "appwrite.config.json" : ".gitignore";
440
+ let functionExists = false;
441
+ let deploymentCreated = false;
442
+ const updaterRow = new Spinner({
443
+ status: "",
444
+ resource: func.name,
445
+ id: func["$id"],
446
+ end: `Ignoring using: ${ignore}`,
947
447
  });
948
- siteExists = true;
949
- if (response.framework !== site.framework) {
950
- updaterRow.fail({ errorMessage: `Framework mismatch! (local=${site.framework},remote=${response.framework}) Please delete remote site or update your appwrite.config.json` });
448
+ updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
449
+ const functionsService = await getFunctionsService(this.projectClient);
450
+ try {
451
+ response = await functionsService.get({ functionId: func["$id"] });
452
+ functionExists = true;
453
+ if (response.runtime !== func.runtime) {
454
+ updaterRow.fail({
455
+ errorMessage: `Runtime mismatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.config.json`,
456
+ });
457
+ return;
458
+ }
459
+ updaterRow
460
+ .update({ status: "Updating" })
461
+ .replaceSpinner(SPINNER_DOTS);
462
+ response = await functionsService.update({
463
+ functionId: func["$id"],
464
+ name: func.name,
465
+ runtime: func.runtime,
466
+ execute: func.execute,
467
+ events: func.events,
468
+ schedule: func.schedule,
469
+ timeout: func.timeout,
470
+ enabled: func.enabled,
471
+ logging: func.logging,
472
+ entrypoint: func.entrypoint,
473
+ commands: func.commands,
474
+ scopes: func.scopes,
475
+ specification: func.specification,
476
+ });
477
+ }
478
+ catch (e) {
479
+ if (Number(e.code) === 404) {
480
+ functionExists = false;
481
+ }
482
+ else {
483
+ errors.push(e);
484
+ updaterRow.fail({
485
+ errorMessage: e.message ?? "General error occurs please try again",
486
+ });
487
+ return;
488
+ }
489
+ }
490
+ if (!functionExists) {
491
+ updaterRow
492
+ .update({ status: "Creating" })
493
+ .replaceSpinner(SPINNER_DOTS);
494
+ try {
495
+ response = await functionsService.create({
496
+ functionId: func.$id,
497
+ name: func.name,
498
+ runtime: func.runtime,
499
+ execute: func.execute,
500
+ events: func.events,
501
+ schedule: func.schedule,
502
+ timeout: func.timeout,
503
+ enabled: func.enabled,
504
+ logging: func.logging,
505
+ entrypoint: func.entrypoint,
506
+ commands: func.commands,
507
+ scopes: func.scopes,
508
+ specification: func.specification,
509
+ });
510
+ let domain = "";
511
+ try {
512
+ const consoleService = await getConsoleService(this.consoleClient);
513
+ const variables = await consoleService.variables();
514
+ domain = ID.unique() + "." + variables["_APP_DOMAIN_FUNCTIONS"];
515
+ }
516
+ catch (err) {
517
+ this.error("Error fetching console variables.");
518
+ throw err;
519
+ }
520
+ try {
521
+ const proxyService = await getProxyService(this.projectClient);
522
+ await proxyService.createFunctionRule(domain, func.$id);
523
+ }
524
+ catch (err) {
525
+ this.error("Error creating function rule.");
526
+ throw err;
527
+ }
528
+ updaterRow.update({ status: "Created" });
529
+ }
530
+ catch (e) {
531
+ errors.push(e);
532
+ updaterRow.fail({
533
+ errorMessage: e.message ?? "General error occurs please try again",
534
+ });
535
+ return;
536
+ }
537
+ }
538
+ if (withVariables) {
539
+ updaterRow
540
+ .update({ status: "Updating variables" })
541
+ .replaceSpinner(SPINNER_DOTS);
542
+ const functionsServiceForVars = await getFunctionsService(this.projectClient);
543
+ const { variables } = await paginate(async (args) => {
544
+ return await functionsServiceForVars.listVariables({
545
+ functionId: args.functionId,
546
+ });
547
+ }, {
548
+ functionId: func["$id"],
549
+ }, 100, "variables");
550
+ await Promise.all(variables.map(async (variable) => {
551
+ const functionsServiceDel = await getFunctionsService(this.projectClient);
552
+ await functionsServiceDel.deleteVariable({
553
+ functionId: func["$id"],
554
+ variableId: variable["$id"],
555
+ });
556
+ }));
557
+ const envFileLocation = `${func["path"]}/.env`;
558
+ let envVariables = [];
559
+ try {
560
+ if (fs.existsSync(envFileLocation)) {
561
+ const envObject = parseDotenv(fs.readFileSync(envFileLocation, "utf8"));
562
+ envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
563
+ }
564
+ }
565
+ catch (error) {
566
+ envVariables = [];
567
+ }
568
+ await Promise.all(envVariables.map(async (variable) => {
569
+ const functionsServiceCreate = await getFunctionsService(this.projectClient);
570
+ await functionsServiceCreate.createVariable({
571
+ functionId: func["$id"],
572
+ key: variable.key,
573
+ value: variable.value,
574
+ secret: false,
575
+ });
576
+ }));
577
+ }
578
+ if (code === false) {
579
+ successfullyPushed++;
580
+ successfullyDeployed++;
581
+ updaterRow.update({ status: "Pushed" });
582
+ updaterRow.stopSpinner();
951
583
  return;
952
584
  }
953
- updaterRow.update({ status: 'Updating' }).replaceSpinner(spinner_1.SPINNER_ARC);
954
- response = await (0, sites_1.sitesUpdate)({
955
- siteId: site['$id'],
956
- name: site.name,
957
- framework: site.framework,
958
- buildRuntime: site.buildRuntime,
959
- specification: site.specification,
960
- timeout: site.timeout,
961
- enabled: site.enabled,
962
- logging: site.logging,
963
- adapter: site.adapter,
964
- buildCommand: site.buildCommand,
965
- installCommand: site.installCommand,
966
- outputDirectory: site.outputDirectory,
967
- fallbackFile: site.fallbackFile,
968
- vars: JSON.stringify(response.vars),
969
- parseOutput: false
970
- });
971
- }
972
- catch (e) {
973
- if (Number(e.code) === 404) {
974
- siteExists = false;
585
+ try {
586
+ updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_DOTS);
587
+ const functionsServiceDeploy = await getFunctionsService(this.projectClient);
588
+ const result = await pushDeployment({
589
+ resourcePath: func.path,
590
+ createDeployment: async (codeFile) => {
591
+ return await functionsServiceDeploy.createDeployment({
592
+ functionId: func["$id"],
593
+ entrypoint: func.entrypoint,
594
+ commands: func.commands,
595
+ code: codeFile,
596
+ activate: true,
597
+ });
598
+ },
599
+ pollForStatus: false,
600
+ });
601
+ response = result.deployment;
602
+ updaterRow.update({ status: "Pushed" });
603
+ deploymentCreated = true;
604
+ successfullyPushed++;
975
605
  }
976
- else {
606
+ catch (e) {
977
607
  errors.push(e);
978
- updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
979
- return;
608
+ switch (e.code) {
609
+ case "ENOENT":
610
+ updaterRow.fail({
611
+ errorMessage: "Not found in the current directory. Skipping...",
612
+ });
613
+ break;
614
+ default:
615
+ updaterRow.fail({
616
+ errorMessage: e.message ?? "An unknown error occurred. Please try again.",
617
+ });
618
+ }
980
619
  }
981
- }
982
- if (!siteExists) {
983
- updaterRow.update({ status: 'Creating' }).replaceSpinner(spinner_1.SPINNER_DOTS);
620
+ if (deploymentCreated && !asyncDeploy) {
621
+ try {
622
+ const deploymentId = response["$id"];
623
+ updaterRow.update({
624
+ status: "Deploying",
625
+ end: "Checking deployment status...",
626
+ });
627
+ const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
628
+ while (true) {
629
+ if (Date.now() > timeoutDeadline) {
630
+ failedDeployments.push({
631
+ name: func["name"],
632
+ $id: func["$id"],
633
+ deployment: deploymentId,
634
+ });
635
+ updaterRow.fail({
636
+ errorMessage: "Deployment timed out after 10 minutes",
637
+ });
638
+ break;
639
+ }
640
+ const functionsServicePoll = await getFunctionsService(this.projectClient);
641
+ response = await functionsServicePoll.getDeployment({
642
+ functionId: func["$id"],
643
+ deploymentId: deploymentId,
644
+ });
645
+ const status = response["status"];
646
+ if (status === "ready") {
647
+ successfullyDeployed++;
648
+ let url = "";
649
+ const proxyServiceUrl = await getProxyService(this.projectClient);
650
+ const res = await proxyServiceUrl.listRules({
651
+ queries: [
652
+ Query.limit(1),
653
+ Query.equal("deploymentResourceType", "function"),
654
+ Query.equal("deploymentResourceId", func["$id"]),
655
+ Query.equal("trigger", "manual"),
656
+ ],
657
+ });
658
+ if (Number(res.total) === 1) {
659
+ url = `https://${res.rules[0].domain}`;
660
+ }
661
+ updaterRow.update({ status: "Deployed", end: url });
662
+ break;
663
+ }
664
+ else if (status === "failed") {
665
+ failedDeployments.push({
666
+ name: func["name"],
667
+ $id: func["$id"],
668
+ deployment: response["$id"],
669
+ });
670
+ updaterRow.fail({ errorMessage: `Failed to deploy` });
671
+ break;
672
+ }
673
+ else {
674
+ updaterRow.update({
675
+ status: "Deploying",
676
+ end: `Current status: ${status}`,
677
+ });
678
+ }
679
+ await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE));
680
+ }
681
+ }
682
+ catch (e) {
683
+ errors.push(e);
684
+ updaterRow.fail({
685
+ errorMessage: e.message ?? "Unknown error occurred. Please try again",
686
+ });
687
+ }
688
+ }
689
+ updaterRow.stopSpinner();
690
+ }));
691
+ Spinner.stop();
692
+ return {
693
+ successfullyPushed,
694
+ successfullyDeployed,
695
+ failedDeployments,
696
+ errors,
697
+ };
698
+ }
699
+ async pushSites(sites, options = {}) {
700
+ const { async: asyncDeploy, code, withVariables } = options;
701
+ Spinner.start(false);
702
+ let successfullyPushed = 0;
703
+ let successfullyDeployed = 0;
704
+ const failedDeployments = [];
705
+ const errors = [];
706
+ await Promise.all(sites.map(async (site) => {
707
+ let response = {};
708
+ const ignore = site.ignore ? "appwrite.config.json" : ".gitignore";
709
+ let siteExists = false;
710
+ let deploymentCreated = false;
711
+ const updaterRow = new Spinner({
712
+ status: "",
713
+ resource: site.name,
714
+ id: site["$id"],
715
+ end: `Ignoring using: ${ignore}`,
716
+ });
717
+ updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
718
+ const sitesService = await getSitesService(this.projectClient);
984
719
  try {
985
- response = await (0, sites_1.sitesCreate)({
986
- siteId: site.$id,
720
+ response = await sitesService.get({ siteId: site["$id"] });
721
+ siteExists = true;
722
+ if (response.framework !== site.framework) {
723
+ updaterRow.fail({
724
+ errorMessage: `Framework mismatch! (local=${site.framework},remote=${response.framework}) Please delete remote site or update your appwrite.config.json`,
725
+ });
726
+ return;
727
+ }
728
+ updaterRow
729
+ .update({ status: "Updating" })
730
+ .replaceSpinner(SPINNER_DOTS);
731
+ response = await sitesService.update({
732
+ siteId: site["$id"],
987
733
  name: site.name,
988
734
  framework: site.framework,
989
- specification: site.specification,
990
- buildRuntime: site.buildRuntime,
991
- buildCommand: site.buildCommand,
735
+ enabled: site.enabled,
736
+ logging: site.logging,
737
+ timeout: site.timeout,
992
738
  installCommand: site.installCommand,
739
+ buildCommand: site.buildCommand,
993
740
  outputDirectory: site.outputDirectory,
994
- fallbackFile: site.fallbackFile,
741
+ buildRuntime: site.buildRuntime,
995
742
  adapter: site.adapter,
996
- timeout: site.timeout,
997
- enabled: site.enabled,
998
- logging: site.logging,
999
- parseOutput: false
743
+ specification: site.specification,
1000
744
  });
1001
- let domain = '';
1002
- try {
1003
- const variables = await (0, console_1.consoleVariables)({ parseOutput: false, sdk: await (0, sdks_1.sdkForConsole)() });
1004
- domain = id_1.default.unique() + '.' + variables['_APP_DOMAIN_SITES'];
745
+ }
746
+ catch (e) {
747
+ if (Number(e.code) === 404) {
748
+ siteExists = false;
1005
749
  }
1006
- catch (error) {
1007
- console.error('Error fetching console variables.');
1008
- throw error;
750
+ else {
751
+ errors.push(e);
752
+ updaterRow.fail({
753
+ errorMessage: e.message ?? "General error occurs please try again",
754
+ });
755
+ return;
1009
756
  }
757
+ }
758
+ if (!siteExists) {
759
+ updaterRow
760
+ .update({ status: "Creating" })
761
+ .replaceSpinner(SPINNER_DOTS);
1010
762
  try {
1011
- const rule = await (0, proxy_1.proxyCreateSiteRule)({
1012
- domain: domain,
1013
- siteId: site.$id
763
+ response = await sitesService.create({
764
+ siteId: site.$id,
765
+ name: site.name,
766
+ framework: site.framework,
767
+ enabled: site.enabled,
768
+ logging: site.logging,
769
+ timeout: site.timeout,
770
+ installCommand: site.installCommand,
771
+ buildCommand: site.buildCommand,
772
+ outputDirectory: site.outputDirectory,
773
+ buildRuntime: site.buildRuntime,
774
+ adapter: site.adapter,
775
+ specification: site.specification,
776
+ });
777
+ let domain = "";
778
+ try {
779
+ const consoleService = await getConsoleService(this.consoleClient);
780
+ const variables = await consoleService.variables();
781
+ domain = ID.unique() + "." + variables["_APP_DOMAIN_SITES"];
782
+ }
783
+ catch (err) {
784
+ this.error("Error fetching console variables.");
785
+ throw err;
786
+ }
787
+ try {
788
+ const proxyService = await getProxyService(this.projectClient);
789
+ await proxyService.createSiteRule(domain, site.$id);
790
+ }
791
+ catch (err) {
792
+ this.error("Error creating site rule.");
793
+ throw err;
794
+ }
795
+ updaterRow.update({ status: "Created" });
796
+ }
797
+ catch (e) {
798
+ errors.push(e);
799
+ updaterRow.fail({
800
+ errorMessage: e.message ?? "General error occurs please try again",
1014
801
  });
802
+ return;
803
+ }
804
+ }
805
+ if (withVariables) {
806
+ updaterRow
807
+ .update({ status: "Creating variables" })
808
+ .replaceSpinner(SPINNER_DOTS);
809
+ const sitesServiceForVars = await getSitesService(this.projectClient);
810
+ const { variables } = await paginate(async (args) => {
811
+ return await sitesServiceForVars.listVariables({
812
+ siteId: args.siteId,
813
+ });
814
+ }, {
815
+ siteId: site["$id"],
816
+ }, 100, "variables");
817
+ await Promise.all(variables.map(async (variable) => {
818
+ const sitesServiceDel = await getSitesService(this.projectClient);
819
+ await sitesServiceDel.deleteVariable({
820
+ siteId: site["$id"],
821
+ variableId: variable["$id"],
822
+ });
823
+ }));
824
+ const envFileLocation = `${site["path"]}/.env`;
825
+ let envVariables = [];
826
+ try {
827
+ if (fs.existsSync(envFileLocation)) {
828
+ const envObject = parseDotenv(fs.readFileSync(envFileLocation, "utf8"));
829
+ envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
830
+ }
1015
831
  }
1016
832
  catch (error) {
1017
- console.error('Error creating site rule.');
1018
- throw error;
833
+ envVariables = [];
1019
834
  }
1020
- updaterRow.update({ status: 'Created' });
835
+ await Promise.all(envVariables.map(async (variable) => {
836
+ const sitesServiceCreate = await getSitesService(this.projectClient);
837
+ await sitesServiceCreate.createVariable({
838
+ siteId: site["$id"],
839
+ key: variable.key,
840
+ value: variable.value,
841
+ secret: false,
842
+ });
843
+ }));
844
+ }
845
+ if (code === false) {
846
+ successfullyPushed++;
847
+ successfullyDeployed++;
848
+ updaterRow.update({ status: "Pushed" });
849
+ updaterRow.stopSpinner();
850
+ return;
851
+ }
852
+ try {
853
+ updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_DOTS);
854
+ const sitesServiceDeploy = await getSitesService(this.projectClient);
855
+ const result = await pushDeployment({
856
+ resourcePath: site.path,
857
+ createDeployment: async (codeFile) => {
858
+ return await sitesServiceDeploy.createDeployment({
859
+ siteId: site["$id"],
860
+ installCommand: site.installCommand,
861
+ buildCommand: site.buildCommand,
862
+ outputDirectory: site.outputDirectory,
863
+ code: codeFile,
864
+ activate: true,
865
+ });
866
+ },
867
+ pollForStatus: false,
868
+ });
869
+ response = result.deployment;
870
+ updaterRow.update({ status: "Pushed" });
871
+ deploymentCreated = true;
872
+ successfullyPushed++;
1021
873
  }
1022
874
  catch (e) {
1023
875
  errors.push(e);
1024
- updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
1025
- return;
876
+ switch (e.code) {
877
+ case "ENOENT":
878
+ updaterRow.fail({
879
+ errorMessage: "Not found in the current directory. Skipping...",
880
+ });
881
+ break;
882
+ default:
883
+ updaterRow.fail({
884
+ errorMessage: e.message ?? "An unknown error occurred. Please try again.",
885
+ });
886
+ }
1026
887
  }
1027
- }
1028
- if (withVariables) {
1029
- updaterRow.update({ status: 'Creating variables' }).replaceSpinner(spinner_1.SPINNER_ARC);
1030
- const { variables } = await (0, paginate_1.paginate)(sites_1.sitesListVariables, {
1031
- siteId: site['$id'],
1032
- parseOutput: false
1033
- }, 100, 'variables');
1034
- await Promise.all(variables.map(async (variable) => {
1035
- await (0, sites_1.sitesDeleteVariable)({
1036
- siteId: site['$id'],
1037
- variableId: variable['$id'],
1038
- parseOutput: false
888
+ if (deploymentCreated && !asyncDeploy) {
889
+ try {
890
+ const deploymentId = response["$id"];
891
+ updaterRow.update({
892
+ status: "Deploying",
893
+ end: "Checking deployment status...",
894
+ });
895
+ const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
896
+ while (true) {
897
+ if (Date.now() > timeoutDeadline) {
898
+ failedDeployments.push({
899
+ name: site["name"],
900
+ $id: site["$id"],
901
+ deployment: deploymentId,
902
+ });
903
+ updaterRow.fail({
904
+ errorMessage: "Deployment timed out after 10 minutes",
905
+ });
906
+ break;
907
+ }
908
+ const sitesServicePoll = await getSitesService(this.projectClient);
909
+ response = await sitesServicePoll.getDeployment({
910
+ siteId: site["$id"],
911
+ deploymentId: deploymentId,
912
+ });
913
+ const status = response["status"];
914
+ if (status === "ready") {
915
+ successfullyDeployed++;
916
+ let url = "";
917
+ const proxyServiceUrl = await getProxyService(this.projectClient);
918
+ const res = await proxyServiceUrl.listRules({
919
+ queries: [
920
+ Query.limit(1),
921
+ Query.equal("deploymentResourceType", "site"),
922
+ Query.equal("deploymentResourceId", site["$id"]),
923
+ Query.equal("trigger", "manual"),
924
+ ],
925
+ });
926
+ if (Number(res.total) === 1) {
927
+ url = `https://${res.rules[0].domain}`;
928
+ }
929
+ updaterRow.update({ status: "Deployed", end: url });
930
+ break;
931
+ }
932
+ else if (status === "failed") {
933
+ failedDeployments.push({
934
+ name: site["name"],
935
+ $id: site["$id"],
936
+ deployment: response["$id"],
937
+ });
938
+ updaterRow.fail({ errorMessage: `Failed to deploy` });
939
+ break;
940
+ }
941
+ else {
942
+ updaterRow.update({
943
+ status: "Deploying",
944
+ end: `Current status: ${status}`,
945
+ });
946
+ }
947
+ await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE));
948
+ }
949
+ }
950
+ catch (e) {
951
+ errors.push(e);
952
+ updaterRow.fail({
953
+ errorMessage: e.message ?? "Unknown error occurred. Please try again",
954
+ });
955
+ }
956
+ }
957
+ updaterRow.stopSpinner();
958
+ }));
959
+ Spinner.stop();
960
+ return {
961
+ successfullyPushed,
962
+ successfullyDeployed,
963
+ failedDeployments,
964
+ errors,
965
+ };
966
+ }
967
+ async pushTables(tables, options = {}) {
968
+ const { attempts, skipConfirmation = false } = options;
969
+ const pollMaxDebounces = attempts ?? POLL_DEFAULT_VALUE;
970
+ const pools = new Pools(pollMaxDebounces);
971
+ const attributes = new Attributes(pools, skipConfirmation);
972
+ let tablesChanged = new Set();
973
+ const errors = [];
974
+ // Parallel tables actions
975
+ await Promise.all(tables.map(async (table) => {
976
+ try {
977
+ const tablesService = await getTablesDBService(this.projectClient);
978
+ const remoteTable = await tablesService.getTable({
979
+ databaseId: table["databaseId"],
980
+ tableId: table["$id"],
1039
981
  });
1040
- }));
1041
- const envFileLocation = `${site['path']}/.env`;
1042
- let envVariables = [];
982
+ const changes = [];
983
+ if (remoteTable.name !== table.name)
984
+ changes.push("name");
985
+ if (remoteTable.rowSecurity !== table.rowSecurity)
986
+ changes.push("rowSecurity");
987
+ if (remoteTable.enabled !== table.enabled)
988
+ changes.push("enabled");
989
+ if (JSON.stringify(remoteTable["$permissions"]) !==
990
+ JSON.stringify(table["$permissions"]))
991
+ changes.push("permissions");
992
+ if (changes.length > 0) {
993
+ await tablesService.updateTable({
994
+ databaseId: table["databaseId"],
995
+ tableId: table["$id"],
996
+ name: table.name,
997
+ rowSecurity: table.rowSecurity,
998
+ permissions: table["$permissions"],
999
+ });
1000
+ this.success(`Updated ${table.name} ( ${table["$id"]} ) - ${changes.join(", ")}`);
1001
+ tablesChanged.add(table["$id"]);
1002
+ }
1003
+ table.remoteVersion = remoteTable;
1004
+ table.isExisted = true;
1005
+ }
1006
+ catch (e) {
1007
+ if (Number(e.code) === 404) {
1008
+ this.log(`Table ${table.name} does not exist in the project. Creating ... `);
1009
+ const tablesService = await getTablesDBService(this.projectClient);
1010
+ await tablesService.createTable({
1011
+ databaseId: table["databaseId"],
1012
+ tableId: table["$id"],
1013
+ name: table.name,
1014
+ rowSecurity: table.rowSecurity,
1015
+ permissions: table["$permissions"]
1016
+ ? [...table["$permissions"]]
1017
+ : undefined,
1018
+ });
1019
+ this.success(`Created ${table.name} ( ${table["$id"]} )`);
1020
+ tablesChanged.add(table["$id"]);
1021
+ }
1022
+ else {
1023
+ errors.push(e);
1024
+ throw e;
1025
+ }
1026
+ }
1027
+ }));
1028
+ // Serialize attribute actions
1029
+ for (let table of tables) {
1030
+ let columns = table.columns;
1031
+ let indexes = table.indexes;
1032
+ if (table.isExisted) {
1033
+ columns = await attributes.attributesToCreate(table.remoteVersion.columns, table.columns, table);
1034
+ indexes = await attributes.attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
1035
+ if (Array.isArray(columns) &&
1036
+ columns.length <= 0 &&
1037
+ Array.isArray(indexes) &&
1038
+ indexes.length <= 0) {
1039
+ continue;
1040
+ }
1041
+ }
1042
+ this.log(`Pushing table ${table.name} ( ${table["databaseId"]} - ${table["$id"]} ) attributes`);
1043
+ try {
1044
+ await attributes.createColumns(columns, table);
1045
+ }
1046
+ catch (e) {
1047
+ errors.push(e);
1048
+ throw e;
1049
+ }
1050
+ try {
1051
+ await attributes.createIndexes(indexes, table);
1052
+ }
1053
+ catch (e) {
1054
+ errors.push(e);
1055
+ throw e;
1056
+ }
1057
+ tablesChanged.add(table["$id"]);
1058
+ this.success(`Successfully pushed ${table.name} ( ${table["$id"]} )`);
1059
+ }
1060
+ return {
1061
+ successfullyPushed: tablesChanged.size,
1062
+ errors,
1063
+ };
1064
+ }
1065
+ async pushCollections(collections, options = {}) {
1066
+ const { skipConfirmation = false } = options;
1067
+ const pools = new Pools(POLL_DEFAULT_VALUE);
1068
+ const attributes = new Attributes(pools, skipConfirmation);
1069
+ const errors = [];
1070
+ const databases = Array.from(new Set(collections.map((collection) => collection["databaseId"])));
1071
+ // Parallel db actions
1072
+ await Promise.all(databases.map(async (databaseId) => {
1073
+ const databasesService = await getDatabasesService(this.projectClient);
1074
+ try {
1075
+ const database = await databasesService.get(databaseId);
1076
+ // Note: We can't get the local database name here since we don't have access to localConfig
1077
+ // This will need to be handled by the caller if needed
1078
+ const localDatabaseName = collections.find((c) => c.databaseId === databaseId)
1079
+ ?.databaseName ?? databaseId;
1080
+ if (database.name !== localDatabaseName) {
1081
+ await databasesService.update(databaseId, localDatabaseName);
1082
+ this.success(`Updated ${localDatabaseName} ( ${databaseId} ) name`);
1083
+ }
1084
+ }
1085
+ catch (err) {
1086
+ if (Number(err.code) === 404) {
1087
+ this.log(`Database ${databaseId} not found. Creating it now ...`);
1088
+ const localDatabaseName = collections.find((c) => c.databaseId === databaseId)
1089
+ ?.databaseName ?? databaseId;
1090
+ await databasesService.create(databaseId, localDatabaseName);
1091
+ }
1092
+ else {
1093
+ throw err;
1094
+ }
1095
+ }
1096
+ }));
1097
+ // Parallel collection actions
1098
+ await Promise.all(collections.map(async (collection) => {
1043
1099
  try {
1044
- if (fs.existsSync(envFileLocation)) {
1045
- const envObject = (0, dotenv_1.parse)(fs.readFileSync(envFileLocation, 'utf8'));
1046
- envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
1100
+ const databasesService = await getDatabasesService(this.projectClient);
1101
+ const remoteCollection = await databasesService.getCollection(collection["databaseId"], collection["$id"]);
1102
+ if (remoteCollection.name !== collection.name) {
1103
+ await databasesService.updateCollection(collection["databaseId"], collection["$id"], collection.name);
1104
+ this.success(`Updated ${collection.name} ( ${collection["$id"]} ) name`);
1047
1105
  }
1106
+ collection.remoteVersion = remoteCollection;
1107
+ collection.isExisted = true;
1048
1108
  }
1049
- catch (error) {
1050
- // Handle parsing errors gracefully
1051
- envVariables = [];
1109
+ catch (e) {
1110
+ if (Number(e.code) === 404) {
1111
+ this.log(`Collection ${collection.name} does not exist in the project. Creating ... `);
1112
+ const databasesService = await getDatabasesService(this.projectClient);
1113
+ await databasesService.createCollection({
1114
+ databaseId: collection["databaseId"],
1115
+ collectionId: collection["$id"],
1116
+ name: collection.name,
1117
+ documentSecurity: collection.documentSecurity,
1118
+ permissions: collection["$permissions"],
1119
+ });
1120
+ }
1121
+ else {
1122
+ errors.push(e);
1123
+ throw e;
1124
+ }
1052
1125
  }
1053
- await Promise.all(envVariables.map(async (variable) => {
1054
- await (0, sites_1.sitesCreateVariable)({
1055
- siteId: site['$id'],
1056
- key: variable.key,
1057
- value: variable.value,
1058
- parseOutput: false,
1059
- secret: false
1060
- });
1061
- }));
1126
+ }));
1127
+ let numberOfCollections = 0;
1128
+ // Serialize attribute actions
1129
+ for (let collection of collections) {
1130
+ let collectionAttributes = collection.attributes;
1131
+ let indexes = collection.indexes;
1132
+ if (collection.isExisted) {
1133
+ collectionAttributes = await attributes.attributesToCreate(collection.remoteVersion.attributes, collection.attributes, collection);
1134
+ indexes = await attributes.attributesToCreate(collection.remoteVersion.indexes, collection.indexes, collection, true);
1135
+ if (Array.isArray(collectionAttributes) &&
1136
+ collectionAttributes.length <= 0 &&
1137
+ Array.isArray(indexes) &&
1138
+ indexes.length <= 0) {
1139
+ continue;
1140
+ }
1141
+ }
1142
+ this.log(`Pushing collection ${collection.name} ( ${collection["databaseId"]} - ${collection["$id"]} ) attributes`);
1143
+ try {
1144
+ await attributes.createAttributes(collectionAttributes, collection);
1145
+ }
1146
+ catch (e) {
1147
+ errors.push(e);
1148
+ throw e;
1149
+ }
1150
+ try {
1151
+ await attributes.createIndexes(indexes, collection);
1152
+ }
1153
+ catch (e) {
1154
+ errors.push(e);
1155
+ throw e;
1156
+ }
1157
+ numberOfCollections++;
1158
+ this.success(`Successfully pushed ${collection.name} ( ${collection["$id"]} )`);
1159
+ }
1160
+ return {
1161
+ successfullyPushed: numberOfCollections,
1162
+ errors,
1163
+ };
1164
+ }
1165
+ }
1166
+ async function createPushInstance(silent = false) {
1167
+ const projectClient = await sdkForProject();
1168
+ const consoleClient = await sdkForConsole();
1169
+ return new Push(projectClient, consoleClient, silent);
1170
+ }
1171
+ const pushResources = async ({ skipDeprecated = false, } = {}) => {
1172
+ if (cliConfig.all) {
1173
+ checkDeployConditions(localConfig);
1174
+ const pushInstance = await createPushInstance();
1175
+ const config = localConfig.getProject();
1176
+ await pushInstance.pushResources(config, {
1177
+ skipDeprecated,
1178
+ functionOptions: { code: true, withVariables: false },
1179
+ siteOptions: { code: true, withVariables: false },
1180
+ });
1181
+ }
1182
+ else {
1183
+ const actions = {
1184
+ settings: pushSettings,
1185
+ functions: pushFunction,
1186
+ sites: pushSite,
1187
+ collections: pushCollection,
1188
+ tables: pushTable,
1189
+ buckets: pushBucket,
1190
+ teams: pushTeam,
1191
+ messages: pushMessagingTopic,
1192
+ };
1193
+ if (skipDeprecated) {
1194
+ delete actions.collections;
1195
+ }
1196
+ const answers = await inquirer.prompt(questionsPushResources);
1197
+ const action = actions[answers.resource];
1198
+ if (action !== undefined) {
1199
+ await action();
1062
1200
  }
1063
- if (code === false) {
1064
- successfullyPushed++;
1065
- successfullyDeployed++;
1066
- updaterRow.update({ status: 'Pushed' });
1067
- updaterRow.stopSpinner();
1068
- return;
1201
+ }
1202
+ };
1203
+ const pushSettings = async () => {
1204
+ checkDeployConditions(localConfig);
1205
+ try {
1206
+ const projectsService = await getProjectsService();
1207
+ let response = await projectsService.get(localConfig.getProject().projectId);
1208
+ const remoteSettings = createSettingsObject(response);
1209
+ const localSettings = localConfig.getProject().projectSettings ?? {};
1210
+ log("Checking for changes ...");
1211
+ const changes = [];
1212
+ changes.push(...getObjectChanges(remoteSettings, localSettings, "services", "Service"));
1213
+ changes.push(...getObjectChanges(remoteSettings["auth"] ?? {}, localSettings["auth"] ?? {}, "methods", "Auth method"));
1214
+ changes.push(...getObjectChanges(remoteSettings["auth"] ?? {}, localSettings["auth"] ?? {}, "security", "Auth security"));
1215
+ if (changes.length > 0) {
1216
+ drawTable(changes);
1217
+ if ((await getConfirmation()) !== true) {
1218
+ success(`Successfully pushed 0 project settings.`);
1219
+ return;
1220
+ }
1069
1221
  }
1070
- try {
1071
- updaterRow.update({ status: 'Pushing' }).replaceSpinner(spinner_1.SPINNER_ARC);
1072
- response = await (0, sites_1.sitesCreateDeployment)({
1073
- siteId: site['$id'],
1074
- buildCommand: site.buildCommand,
1075
- installCommand: site.installCommand,
1076
- outputDirectory: site.outputDirectory,
1077
- fallbackFile: site.fallbackFile,
1078
- code: site.path,
1079
- activate: true,
1080
- parseOutput: false
1081
- });
1082
- updaterRow.update({ status: 'Pushed' });
1083
- deploymentCreated = true;
1084
- successfullyPushed++;
1222
+ }
1223
+ catch (e) { }
1224
+ try {
1225
+ log("Pushing project settings ...");
1226
+ const pushInstance = await createPushInstance();
1227
+ const config = localConfig.getProject();
1228
+ await pushInstance.pushSettings({
1229
+ projectId: config.projectId,
1230
+ projectName: config.projectName,
1231
+ settings: config.projectSettings,
1232
+ });
1233
+ success(`Successfully pushed ${chalk.bold("all")} project settings.`);
1234
+ }
1235
+ catch (e) {
1236
+ throw e;
1237
+ }
1238
+ };
1239
+ const pushSite = async ({ siteId, async: asyncDeploy, code, withVariables, } = {}) => {
1240
+ process.chdir(localConfig.configDirectoryPath);
1241
+ const siteIds = [];
1242
+ if (siteId) {
1243
+ siteIds.push(siteId);
1244
+ }
1245
+ else if (cliConfig.all) {
1246
+ checkDeployConditions(localConfig);
1247
+ const sites = localConfig.getSites();
1248
+ siteIds.push(...sites.map((site) => {
1249
+ return site.$id;
1250
+ }));
1251
+ }
1252
+ if (siteIds.length <= 0) {
1253
+ const answers = await inquirer.prompt(questionsPushSites);
1254
+ if (answers.sites) {
1255
+ siteIds.push(...answers.sites);
1085
1256
  }
1086
- catch (e) {
1087
- errors.push(e);
1088
- switch (e.code) {
1089
- case 'ENOENT':
1090
- updaterRow.fail({ errorMessage: 'Not found in the current directory. Skipping...' });
1091
- break;
1092
- default:
1093
- updaterRow.fail({ errorMessage: e.message ?? 'An unknown error occurred. Please try again.' });
1094
- }
1257
+ }
1258
+ if (siteIds.length === 0) {
1259
+ log("No sites found.");
1260
+ hint(`Use '${EXECUTABLE_NAME} pull sites' to synchronize existing one, or use '${EXECUTABLE_NAME} init site' to create a new one.`);
1261
+ return;
1262
+ }
1263
+ let sites = siteIds.map((id) => {
1264
+ const sites = localConfig.getSites();
1265
+ const site = sites.find((s) => s.$id === id);
1266
+ if (!site) {
1267
+ throw new Error("Site '" + id + "' not found.");
1095
1268
  }
1096
- if (deploymentCreated && !asyncDeploy) {
1097
- try {
1098
- const deploymentId = response['$id'];
1099
- updaterRow.update({ status: 'Deploying', end: 'Checking deployment status...' });
1100
- let pollChecks = 0;
1101
- while (true) {
1102
- response = await (0, sites_1.sitesGetDeployment)({
1103
- siteId: site['$id'],
1104
- deploymentId: deploymentId,
1105
- parseOutput: false
1106
- });
1107
- const status = response['status'];
1108
- if (status === 'ready') {
1109
- successfullyDeployed++;
1110
- let url = '';
1111
- const res = await (0, proxy_1.proxyListRules)({
1112
- parseOutput: false,
1113
- queries: [
1114
- JSON.stringify({ method: 'limit', values: [1] }),
1115
- JSON.stringify({ method: 'equal', "attribute": "deploymentResourceType", "values": ["site"] }),
1116
- JSON.stringify({ method: 'equal', "attribute": "deploymentResourceId", "values": [site['$id']] }),
1117
- JSON.stringify({ method: 'equal', "attribute": "trigger", "values": ["manual"] }),
1118
- ],
1119
- });
1120
- if (Number(res.total) === 1) {
1121
- url = res.rules[0].domain;
1122
- }
1123
- updaterRow.update({ status: 'Deployed', end: url });
1124
- break;
1125
- }
1126
- else if (status === 'failed') {
1127
- failedDeployments.push({ name: site['name'], $id: site['$id'], deployment: response['$id'] });
1128
- updaterRow.fail({ errorMessage: `Failed to deploy` });
1129
- break;
1130
- }
1131
- else {
1132
- updaterRow.update({ status: 'Deploying', end: `Current status: ${status}` });
1133
- }
1134
- pollChecks++;
1135
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE * 1.5));
1136
- }
1137
- }
1138
- catch (e) {
1139
- errors.push(e);
1140
- updaterRow.fail({ errorMessage: e.message ?? 'Unknown error occurred. Please try again' });
1141
- }
1269
+ return site;
1270
+ });
1271
+ log("Validating sites ...");
1272
+ // Validation is done BEFORE pushing so the deployment process can be run in async with progress update
1273
+ for (let site of sites) {
1274
+ if (!site.buildCommand) {
1275
+ log(`Site ${site.name} is missing build command.`);
1276
+ const answers = await inquirer.prompt(questionsGetEntrypoint);
1277
+ site.buildCommand = answers.entrypoint;
1278
+ localConfig.addSite(site);
1142
1279
  }
1143
- updaterRow.stopSpinner();
1144
- }));
1145
- spinner_1.Spinner.stop();
1280
+ }
1281
+ if (!(await approveChanges(sites, async (args) => {
1282
+ const sitesService = await getSitesService();
1283
+ return await sitesService.get({ siteId: args.siteId });
1284
+ }, KeysSite, "siteId", "sites", ["vars"]))) {
1285
+ return;
1286
+ }
1287
+ log("Pushing sites ...");
1288
+ const pushInstance = await createPushInstance();
1289
+ const result = await pushInstance.pushSites(sites, {
1290
+ async: asyncDeploy,
1291
+ code,
1292
+ withVariables,
1293
+ });
1294
+ const { successfullyPushed, successfullyDeployed, failedDeployments, errors, } = result;
1146
1295
  failedDeployments.forEach((failed) => {
1147
1296
  const { name, deployment, $id } = failed;
1148
- const failUrl = `${config_1.globalConfig.getEndpoint().slice(0, -3)}/console/project-${config_1.localConfig.getProject().projectId}/sites/site-${$id}/deployments/deployment-${deployment}`;
1149
- (0, parser_1.error)(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
1297
+ const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/sites/site-${$id}/deployments/deployment-${deployment}`;
1298
+ error(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
1150
1299
  });
1151
1300
  if (!asyncDeploy) {
1152
1301
  if (successfullyPushed === 0) {
1153
- (0, parser_1.error)('No sites were pushed.');
1302
+ error("No sites were pushed.");
1154
1303
  }
1155
1304
  else if (successfullyDeployed !== successfullyPushed) {
1156
- (0, parser_1.warn)(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} sites`);
1305
+ warn(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} sites`);
1157
1306
  }
1158
1307
  else {
1159
- (0, parser_1.success)(`Successfully pushed ${successfullyPushed} sites.`);
1308
+ success(`Successfully pushed ${successfullyPushed} sites.`);
1160
1309
  }
1161
1310
  }
1162
1311
  else {
1163
- (0, parser_1.success)(`Successfully pushed ${successfullyPushed} sites.`);
1312
+ success(`Successfully pushed ${successfullyPushed} sites.`);
1164
1313
  }
1165
- if (parser_1.cliConfig.verbose) {
1166
- errors.forEach(e => {
1314
+ if (cliConfig.verbose) {
1315
+ errors.forEach((e) => {
1167
1316
  console.error(e);
1168
1317
  });
1169
1318
  }
1170
1319
  };
1171
- const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariables } = { returnOnZero: false }) => {
1172
- process.chdir(config_1.localConfig.configDirectoryPath);
1320
+ const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariables, } = {}) => {
1321
+ process.chdir(localConfig.configDirectoryPath);
1173
1322
  const functionIds = [];
1174
1323
  if (functionId) {
1175
1324
  functionIds.push(functionId);
1176
1325
  }
1177
- else if (parser_1.cliConfig.all) {
1178
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1179
- const functions = config_1.localConfig.getFunctions();
1326
+ else if (cliConfig.all) {
1327
+ checkDeployConditions(localConfig);
1328
+ const functions = localConfig.getFunctions();
1180
1329
  functionIds.push(...functions.map((func) => {
1181
1330
  return func.$id;
1182
1331
  }));
1183
1332
  }
1184
1333
  if (functionIds.length <= 0) {
1185
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushFunctions[0]);
1334
+ const answers = await inquirer.prompt(questionsPushFunctions);
1186
1335
  if (answers.functions) {
1187
1336
  functionIds.push(...answers.functions);
1188
1337
  }
1189
1338
  }
1190
1339
  if (functionIds.length === 0) {
1191
- (0, parser_1.log)("No functions found.");
1192
- (0, parser_1.hint)("Use 'appwrite pull functions' to synchronize existing one, or use 'appwrite init function' to create a new one.");
1340
+ log("No functions found.");
1341
+ hint(`Use '${EXECUTABLE_NAME} pull functions' to synchronize existing one, or use '${EXECUTABLE_NAME} init function' to create a new one.`);
1193
1342
  return;
1194
1343
  }
1195
1344
  let functions = functionIds.map((id) => {
1196
- const functions = config_1.localConfig.getFunctions();
1345
+ const functions = localConfig.getFunctions();
1197
1346
  const func = functions.find((f) => f.$id === id);
1198
1347
  if (!func) {
1199
1348
  throw new Error("Function '" + id + "' not found.");
1200
1349
  }
1201
1350
  return func;
1202
1351
  });
1203
- (0, parser_1.log)('Validating functions ...');
1204
- // Validation is done BEFORE pushing so the deployment process can be run in async with progress update
1352
+ log("Validating functions ...");
1205
1353
  for (let func of functions) {
1206
1354
  if (!func.entrypoint) {
1207
- (0, parser_1.log)(`Function ${func.name} is missing an entrypoint.`);
1208
- const answers = await inquirer_1.default.prompt(questions_1.questionsGetEntrypoint);
1355
+ log(`Function ${func.name} is missing an entrypoint.`);
1356
+ const answers = await inquirer.prompt(questionsGetEntrypoint);
1209
1357
  func.entrypoint = answers.entrypoint;
1210
- config_1.localConfig.addFunction(func);
1358
+ localConfig.addFunction(func);
1211
1359
  }
1212
1360
  }
1213
- if (!(await approveChanges(functions, functions_1.functionsGet, config_1.KeysFunction, 'functionId', 'functions', ['vars']))) {
1361
+ if (!(await approveChanges(functions, async (args) => {
1362
+ const functionsService = await getFunctionsService();
1363
+ return await functionsService.get({ functionId: args.functionId });
1364
+ }, KeysFunction, "functionId", "functions", ["vars"]))) {
1214
1365
  return;
1215
1366
  }
1216
- (0, parser_1.log)('Pushing functions ...');
1217
- spinner_1.Spinner.start(false);
1218
- let successfullyPushed = 0;
1219
- let successfullyDeployed = 0;
1220
- const failedDeployments = [];
1221
- const errors = [];
1222
- await Promise.all(functions.map(async (func) => {
1223
- let response = {};
1224
- const ignore = func.ignore ? 'appwrite.config.json' : '.gitignore';
1225
- let functionExists = false;
1226
- let deploymentCreated = false;
1227
- const updaterRow = new spinner_1.Spinner({ status: '', resource: func.name, id: func['$id'], end: `Ignoring using: ${ignore}` });
1228
- updaterRow.update({ status: 'Getting' }).startSpinner(spinner_1.SPINNER_DOTS);
1229
- try {
1230
- response = await (0, functions_1.functionsGet)({
1231
- functionId: func['$id'],
1232
- parseOutput: false,
1233
- });
1234
- functionExists = true;
1235
- if (response.runtime !== func.runtime) {
1236
- updaterRow.fail({ errorMessage: `Runtime mismatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.config.json` });
1237
- return;
1238
- }
1239
- updaterRow.update({ status: 'Updating' }).replaceSpinner(spinner_1.SPINNER_ARC);
1240
- response = await (0, functions_1.functionsUpdate)({
1241
- functionId: func['$id'],
1242
- name: func.name,
1243
- specification: func.specification,
1244
- execute: func.execute,
1245
- events: func.events,
1246
- schedule: func.schedule,
1247
- timeout: func.timeout,
1248
- enabled: func.enabled,
1249
- logging: func.logging,
1250
- entrypoint: func.entrypoint,
1251
- commands: func.commands,
1252
- scopes: func.scopes,
1253
- vars: JSON.stringify(response.vars),
1254
- parseOutput: false
1255
- });
1256
- }
1257
- catch (e) {
1258
- if (Number(e.code) === 404) {
1259
- functionExists = false;
1260
- }
1261
- else {
1262
- errors.push(e);
1263
- updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
1264
- return;
1265
- }
1266
- }
1267
- if (!functionExists) {
1268
- updaterRow.update({ status: 'Creating' }).replaceSpinner(spinner_1.SPINNER_DOTS);
1269
- try {
1270
- response = await (0, functions_1.functionsCreate)({
1271
- functionId: func.$id,
1272
- name: func.name,
1273
- runtime: func.runtime,
1274
- specification: func.specification,
1275
- execute: func.execute,
1276
- events: func.events,
1277
- schedule: func.schedule,
1278
- timeout: func.timeout,
1279
- enabled: func.enabled,
1280
- logging: func.logging,
1281
- entrypoint: func.entrypoint,
1282
- commands: func.commands,
1283
- scopes: func.scopes,
1284
- parseOutput: false
1285
- });
1286
- let domain = '';
1287
- try {
1288
- const variables = await (0, console_1.consoleVariables)({ parseOutput: false, sdk: await (0, sdks_1.sdkForConsole)() });
1289
- domain = id_1.default.unique() + '.' + variables['_APP_DOMAIN_FUNCTIONS'];
1290
- }
1291
- catch (error) {
1292
- console.error('Error fetching console variables.');
1293
- throw error;
1294
- }
1295
- try {
1296
- const rule = await (0, proxy_1.proxyCreateFunctionRule)({
1297
- domain: domain,
1298
- functionId: func.$id
1299
- });
1300
- }
1301
- catch (error) {
1302
- console.error('Error creating function rule.');
1303
- throw error;
1304
- }
1305
- updaterRow.update({ status: 'Created' });
1306
- }
1307
- catch (e) {
1308
- errors.push(e);
1309
- updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' });
1310
- return;
1311
- }
1312
- }
1313
- if (withVariables) {
1314
- updaterRow.update({ status: 'Updating variables' }).replaceSpinner(spinner_1.SPINNER_ARC);
1315
- const { variables } = await (0, paginate_1.paginate)(functions_1.functionsListVariables, {
1316
- functionId: func['$id'],
1317
- parseOutput: false
1318
- }, 100, 'variables');
1319
- await Promise.all(variables.map(async (variable) => {
1320
- await (0, functions_1.functionsDeleteVariable)({
1321
- functionId: func['$id'],
1322
- variableId: variable['$id'],
1323
- parseOutput: false
1324
- });
1325
- }));
1326
- const envFileLocation = `${func['path']}/.env`;
1327
- let envVariables = [];
1328
- try {
1329
- if (fs.existsSync(envFileLocation)) {
1330
- const envObject = (0, dotenv_1.parse)(fs.readFileSync(envFileLocation, 'utf8'));
1331
- envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
1332
- }
1333
- }
1334
- catch (error) {
1335
- // Handle parsing errors gracefully
1336
- envVariables = [];
1337
- }
1338
- await Promise.all(envVariables.map(async (variable) => {
1339
- await (0, functions_1.functionsCreateVariable)({
1340
- functionId: func['$id'],
1341
- variableId: id_1.default.unique(),
1342
- key: variable.key,
1343
- value: variable.value,
1344
- parseOutput: false,
1345
- secret: false
1346
- });
1347
- }));
1348
- }
1349
- if (code === false) {
1350
- successfullyPushed++;
1351
- successfullyDeployed++;
1352
- updaterRow.update({ status: 'Pushed' });
1353
- updaterRow.stopSpinner();
1354
- return;
1355
- }
1356
- try {
1357
- updaterRow.update({ status: 'Pushing' }).replaceSpinner(spinner_1.SPINNER_ARC);
1358
- response = await (0, functions_1.functionsCreateDeployment)({
1359
- functionId: func['$id'],
1360
- entrypoint: func.entrypoint,
1361
- commands: func.commands,
1362
- code: func.path,
1363
- activate: true,
1364
- parseOutput: false
1365
- });
1366
- updaterRow.update({ status: 'Pushed' });
1367
- deploymentCreated = true;
1368
- successfullyPushed++;
1369
- }
1370
- catch (e) {
1371
- errors.push(e);
1372
- switch (e.code) {
1373
- case 'ENOENT':
1374
- updaterRow.fail({ errorMessage: 'Not found in the current directory. Skipping...' });
1375
- break;
1376
- default:
1377
- updaterRow.fail({ errorMessage: e.message ?? 'An unknown error occurred. Please try again.' });
1378
- }
1379
- }
1380
- if (deploymentCreated && !asyncDeploy) {
1381
- try {
1382
- const deploymentId = response['$id'];
1383
- updaterRow.update({ status: 'Deploying', end: 'Checking deployment status...' });
1384
- let pollChecks = 0;
1385
- while (true) {
1386
- response = await (0, functions_1.functionsGetDeployment)({
1387
- functionId: func['$id'],
1388
- deploymentId: deploymentId,
1389
- parseOutput: false
1390
- });
1391
- const status = response['status'];
1392
- if (status === 'ready') {
1393
- successfullyDeployed++;
1394
- let url = '';
1395
- const res = await (0, proxy_1.proxyListRules)({
1396
- parseOutput: false,
1397
- queries: [
1398
- JSON.stringify({ method: 'limit', values: [1] }),
1399
- JSON.stringify({ method: 'equal', "attribute": "deploymentResourceType", "values": ["function"] }),
1400
- JSON.stringify({ method: 'equal', "attribute": "deploymentResourceId", "values": [func['$id']] }),
1401
- JSON.stringify({ method: 'equal', "attribute": "trigger", "values": ["manual"] }),
1402
- ],
1403
- });
1404
- if (Number(res.total) === 1) {
1405
- url = res.rules[0].domain;
1406
- }
1407
- updaterRow.update({ status: 'Deployed', end: url });
1408
- break;
1409
- }
1410
- else if (status === 'failed') {
1411
- failedDeployments.push({ name: func['name'], $id: func['$id'], deployment: response['$id'] });
1412
- updaterRow.fail({ errorMessage: `Failed to deploy` });
1413
- break;
1414
- }
1415
- else {
1416
- updaterRow.update({ status: 'Deploying', end: `Current status: ${status}` });
1417
- }
1418
- pollChecks++;
1419
- await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE * 1.5));
1420
- }
1421
- }
1422
- catch (e) {
1423
- errors.push(e);
1424
- updaterRow.fail({ errorMessage: e.message ?? 'Unknown error occurred. Please try again' });
1425
- }
1426
- }
1427
- updaterRow.stopSpinner();
1428
- }));
1429
- spinner_1.Spinner.stop();
1367
+ log("Pushing functions ...");
1368
+ const pushInstance = await createPushInstance();
1369
+ const result = await pushInstance.pushFunctions(functions, {
1370
+ async: asyncDeploy,
1371
+ code,
1372
+ withVariables,
1373
+ });
1374
+ const { successfullyPushed, successfullyDeployed, failedDeployments, errors, } = result;
1430
1375
  failedDeployments.forEach((failed) => {
1431
1376
  const { name, deployment, $id } = failed;
1432
- const failUrl = `${config_1.globalConfig.getEndpoint().slice(0, -3)}/console/project-${config_1.localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
1433
- (0, parser_1.error)(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
1377
+ const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
1378
+ error(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
1434
1379
  });
1435
1380
  if (!asyncDeploy) {
1436
1381
  if (successfullyPushed === 0) {
1437
- (0, parser_1.error)('No functions were pushed.');
1382
+ error("No functions were pushed.");
1438
1383
  }
1439
1384
  else if (successfullyDeployed !== successfullyPushed) {
1440
- (0, parser_1.warn)(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} functions`);
1385
+ warn(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} functions`);
1441
1386
  }
1442
1387
  else {
1443
- (0, parser_1.success)(`Successfully pushed ${successfullyPushed} functions.`);
1388
+ success(`Successfully pushed ${successfullyPushed} functions.`);
1444
1389
  }
1445
1390
  }
1446
1391
  else {
1447
- (0, parser_1.success)(`Successfully pushed ${successfullyPushed} functions.`);
1392
+ success(`Successfully pushed ${successfullyPushed} functions.`);
1448
1393
  }
1449
- if (parser_1.cliConfig.verbose) {
1450
- errors.forEach(e => {
1394
+ if (cliConfig.verbose) {
1395
+ errors.forEach((e) => {
1451
1396
  console.error(e);
1452
1397
  });
1453
1398
  }
1454
1399
  };
1455
- const checkAndApplyTablesDBChanges = async () => {
1456
- (0, parser_1.log)('Checking for tablesDB changes ...');
1457
- const localTablesDBs = config_1.localConfig.getTablesDBs();
1458
- const { databases: remoteTablesDBs } = await (0, paginate_1.paginate)(tables_db_1.tablesDBList, { parseOutput: false }, 100, 'databases');
1459
- if (localTablesDBs.length === 0 && remoteTablesDBs.length === 0) {
1460
- return { applied: false, resyncNeeded: false };
1461
- }
1462
- const changes = [];
1463
- const toCreate = [];
1464
- const toUpdate = [];
1465
- const toDelete = [];
1466
- // Check for deletions - remote DBs that aren't in local config
1467
- for (const remoteDB of remoteTablesDBs) {
1468
- const localDB = localTablesDBs.find((db) => db.$id === remoteDB.$id);
1469
- if (!localDB) {
1470
- toDelete.push(remoteDB);
1471
- changes.push({
1472
- id: remoteDB.$id,
1473
- action: chalk_1.default.red('deleting'),
1474
- key: 'Database',
1475
- remote: remoteDB.name,
1476
- local: '(deleted locally)'
1477
- });
1478
- }
1479
- }
1480
- // Check for additions and updates
1481
- for (const localDB of localTablesDBs) {
1482
- const remoteDB = remoteTablesDBs.find((db) => db.$id === localDB.$id);
1483
- if (!remoteDB) {
1484
- toCreate.push(localDB);
1485
- changes.push({
1486
- id: localDB.$id,
1487
- action: chalk_1.default.green('creating'),
1488
- key: 'Database',
1489
- remote: '(does not exist)',
1490
- local: localDB.name
1491
- });
1492
- }
1493
- else {
1494
- let hasChanges = false;
1495
- if (remoteDB.name !== localDB.name) {
1496
- hasChanges = true;
1497
- changes.push({
1498
- id: localDB.$id,
1499
- action: chalk_1.default.yellow('updating'),
1500
- key: 'Name',
1501
- remote: remoteDB.name,
1502
- local: localDB.name
1503
- });
1504
- }
1505
- if (remoteDB.enabled !== localDB.enabled) {
1506
- hasChanges = true;
1507
- changes.push({
1508
- id: localDB.$id,
1509
- action: chalk_1.default.yellow('updating'),
1510
- key: 'Enabled',
1511
- remote: remoteDB.enabled,
1512
- local: localDB.enabled
1513
- });
1514
- }
1515
- if (hasChanges) {
1516
- toUpdate.push(localDB);
1517
- }
1518
- }
1519
- }
1520
- if (changes.length === 0) {
1521
- console.log('No changes found in tablesDB resource');
1522
- console.log();
1523
- return { applied: false, resyncNeeded: false };
1524
- }
1525
- (0, parser_1.log)('Found changes in tablesDB resource:');
1526
- (0, parser_1.drawTable)(changes);
1527
- if (toDelete.length > 0) {
1528
- console.log(`${chalk_1.default.red('------------------------------------------------------------------')}`);
1529
- console.log(`${chalk_1.default.red('| WARNING: Database deletion will also delete all related tables |')}`);
1530
- console.log(`${chalk_1.default.red('------------------------------------------------------------------')}`);
1531
- console.log();
1532
- }
1533
- if ((await getConfirmation()) !== true) {
1534
- return { applied: false, resyncNeeded: false };
1535
- }
1536
- // Apply deletions first
1537
- let needsResync = false;
1538
- for (const db of toDelete) {
1539
- try {
1540
- (0, parser_1.log)(`Deleting database ${db.name} ( ${db.$id} ) ...`);
1541
- await (0, tables_db_1.tablesDBDelete)({
1542
- databaseId: db.$id,
1543
- parseOutput: false
1544
- });
1545
- (0, parser_1.success)(`Deleted ${db.name} ( ${db.$id} )`);
1546
- needsResync = true;
1547
- }
1548
- catch (e) {
1549
- (0, parser_1.error)(`Failed to delete database ${db.name} ( ${db.$id} ): ${e.message}`);
1550
- throw new Error(`Database sync failed during deletion of ${db.$id}. Some changes may have been applied.`);
1551
- }
1552
- }
1553
- // Apply creations
1554
- for (const db of toCreate) {
1555
- try {
1556
- (0, parser_1.log)(`Creating database ${db.name} ( ${db.$id} ) ...`);
1557
- await (0, tables_db_1.tablesDBCreate)({
1558
- databaseId: db.$id,
1559
- name: db.name,
1560
- enabled: db.enabled,
1561
- parseOutput: false
1562
- });
1563
- (0, parser_1.success)(`Created ${db.name} ( ${db.$id} )`);
1564
- }
1565
- catch (e) {
1566
- (0, parser_1.error)(`Failed to create database ${db.name} ( ${db.$id} ): ${e.message}`);
1567
- throw new Error(`Database sync failed during creation of ${db.$id}. Some changes may have been applied.`);
1568
- }
1569
- }
1570
- // Apply updates
1571
- for (const db of toUpdate) {
1572
- try {
1573
- (0, parser_1.log)(`Updating database ${db.name} ( ${db.$id} ) ...`);
1574
- await (0, tables_db_1.tablesDBUpdate)({
1575
- databaseId: db.$id,
1576
- name: db.name,
1577
- enabled: db.enabled,
1578
- parseOutput: false
1579
- });
1580
- (0, parser_1.success)(`Updated ${db.name} ( ${db.$id} )`);
1581
- }
1582
- catch (e) {
1583
- (0, parser_1.error)(`Failed to update database ${db.name} ( ${db.$id} ): ${e.message}`);
1584
- throw new Error(`Database sync failed during update of ${db.$id}. Some changes may have been applied.`);
1585
- }
1586
- }
1587
- if (toDelete.length === 0) {
1588
- console.log();
1589
- }
1590
- return { applied: true, resyncNeeded: needsResync };
1591
- };
1592
- const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1400
+ const pushTable = async ({ attempts, } = {}) => {
1593
1401
  const tables = [];
1594
- if (attempts) {
1595
- pollMaxDebounces = attempts;
1596
- }
1597
- const { applied: tablesDBApplied, resyncNeeded } = await checkAndApplyTablesDBChanges();
1402
+ const { resyncNeeded } = await checkAndApplyTablesDBChanges();
1598
1403
  if (resyncNeeded) {
1599
- (0, parser_1.log)('Resyncing configuration due to tablesDB deletions ...');
1600
- const remoteTablesDBs = (await (0, paginate_1.paginate)(tables_db_1.tablesDBList, { parseOutput: false }, 100, 'databases')).databases;
1601
- const localTablesDBs = config_1.localConfig.getTablesDBs();
1404
+ log("Resyncing configuration due to tables deletions ...");
1405
+ const remoteTablesDBs = (await paginate(async (args) => {
1406
+ const tablesService = await getTablesDBService();
1407
+ return await tablesService.list(args.queries || []);
1408
+ }, {}, 100, "databases")).databases;
1409
+ const localTablesDBs = localConfig.getTablesDBs();
1602
1410
  const remoteDatabaseIds = new Set(remoteTablesDBs.map((db) => db.$id));
1603
- const localTables = config_1.localConfig.getTables();
1411
+ const localTables = localConfig.getTables();
1604
1412
  const validTables = localTables.filter((table) => remoteDatabaseIds.has(table.databaseId));
1605
- config_1.localConfig.set('tables', validTables);
1413
+ localConfig.set("tables", validTables);
1606
1414
  const validTablesDBs = localTablesDBs.filter((db) => remoteDatabaseIds.has(db.$id));
1607
- config_1.localConfig.set('tablesDB', validTablesDBs);
1608
- (0, parser_1.success)('Configuration resynced successfully.');
1415
+ localConfig.set("tablesDB", validTablesDBs);
1416
+ success("Configuration resynced successfully.");
1609
1417
  console.log();
1610
1418
  }
1611
- (0, parser_1.log)('Checking for deleted tables ...');
1612
- const localTablesDBs = config_1.localConfig.getTablesDBs();
1613
- const localTables = config_1.localConfig.getTables();
1419
+ log("Checking for deleted tables ...");
1420
+ const localTablesDBs = localConfig.getTablesDBs();
1421
+ const localTables = localConfig.getTables();
1614
1422
  const tablesToDelete = [];
1615
1423
  for (const db of localTablesDBs) {
1616
1424
  try {
1617
- const { tables: remoteTables } = await (0, paginate_1.paginate)(tables_db_1.tablesDBListTables, {
1425
+ const { tables: remoteTables } = await paginate(async (args) => {
1426
+ const tablesService = await getTablesDBService();
1427
+ return await tablesService.listTables(args.databaseId, args.queries || []);
1428
+ }, {
1618
1429
  databaseId: db.$id,
1619
- parseOutput: false
1620
- }, 100, 'tables');
1430
+ }, 100, "tables");
1621
1431
  for (const remoteTable of remoteTables) {
1622
1432
  const localTable = localTables.find((t) => t.$id === remoteTable.$id && t.databaseId === db.$id);
1623
1433
  if (!localTable) {
1624
1434
  tablesToDelete.push({
1625
1435
  ...remoteTable,
1626
1436
  databaseId: db.$id,
1627
- databaseName: db.name
1437
+ databaseName: db.name,
1628
1438
  });
1629
1439
  }
1630
1440
  }
@@ -1634,47 +1444,40 @@ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) =
1634
1444
  }
1635
1445
  }
1636
1446
  if (tablesToDelete.length > 0) {
1637
- (0, parser_1.log)('Found tables that exist remotely but not locally:');
1447
+ log("Found tables that exist remotely but not locally:");
1638
1448
  const deletionChanges = tablesToDelete.map((table) => ({
1639
1449
  id: table.$id,
1640
- action: chalk_1.default.red('deleting'),
1641
- key: 'Table',
1450
+ action: chalk.red("deleting"),
1451
+ key: "Table",
1642
1452
  database: table.databaseName,
1643
1453
  remote: table.name,
1644
- local: '(deleted locally)'
1454
+ local: "(deleted locally)",
1645
1455
  }));
1646
- (0, parser_1.drawTable)(deletionChanges);
1456
+ drawTable(deletionChanges);
1647
1457
  if ((await getConfirmation()) === true) {
1648
1458
  for (const table of tablesToDelete) {
1649
1459
  try {
1650
- (0, parser_1.log)(`Deleting table ${table.name} ( ${table.$id} ) from database ${table.databaseName} ...`);
1651
- await (0, tables_db_1.tablesDBDeleteTable)({
1652
- databaseId: table.databaseId,
1653
- tableId: table.$id,
1654
- parseOutput: false
1655
- });
1656
- (0, parser_1.success)(`Deleted ${table.name} ( ${table.$id} )`);
1460
+ log(`Deleting table ${table.name} ( ${table.$id} ) from database ${table.databaseName} ...`);
1461
+ const tablesService = await getTablesDBService();
1462
+ await tablesService.deleteTable(table.databaseId, table.$id);
1463
+ success(`Deleted ${table.name} ( ${table.$id} )`);
1657
1464
  }
1658
1465
  catch (e) {
1659
- (0, parser_1.error)(`Failed to delete table ${table.name} ( ${table.$id} ): ${e.message}`);
1466
+ error(`Failed to delete table ${table.name} ( ${table.$id} ): ${e.message}`);
1660
1467
  }
1661
1468
  }
1662
1469
  }
1663
1470
  }
1664
- else {
1665
- console.log('No tables found to delete');
1666
- }
1667
- console.log();
1668
- if (parser_1.cliConfig.all) {
1669
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1670
- tables.push(...config_1.localConfig.getTables());
1471
+ if (cliConfig.all) {
1472
+ checkDeployConditions(localConfig);
1473
+ tables.push(...localConfig.getTables());
1671
1474
  }
1672
1475
  else {
1673
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushTables);
1476
+ const answers = await inquirer.prompt(questionsPushTables);
1674
1477
  if (answers.tables) {
1675
1478
  const configTables = new Map();
1676
- config_1.localConfig.getTables().forEach((c) => {
1677
- configTables.set(`${c['databaseId']}|${c['$id']}`, c);
1479
+ localConfig.getTables().forEach((c) => {
1480
+ configTables.set(`${c["databaseId"]}|${c["$id"]}`, c);
1678
1481
  });
1679
1482
  answers.tables.forEach((a) => {
1680
1483
  const table = configTables.get(a);
@@ -1683,110 +1486,43 @@ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) =
1683
1486
  }
1684
1487
  }
1685
1488
  if (tables.length === 0) {
1686
- (0, parser_1.log)("No tables found.");
1687
- (0, parser_1.hint)("Use 'appwrite pull tables' to synchronize existing one, or use 'appwrite init table' to create a new one.");
1489
+ log("No tables found.");
1490
+ hint(`Use '${EXECUTABLE_NAME} pull tables' to synchronize existing one, or use '${EXECUTABLE_NAME} init table' to create a new one.`);
1688
1491
  return;
1689
1492
  }
1690
- if (!(await approveChanges(tables, tables_db_1.tablesDBGetTable, config_1.KeysTable, 'tableId', 'tables', ['columns', 'indexes'], 'databaseId', 'databaseId'))) {
1493
+ if (!(await approveChanges(tables, async (args) => {
1494
+ const tablesService = await getTablesDBService();
1495
+ return await tablesService.getTable(args.databaseId, args.tableId);
1496
+ }, KeysTable, "tableId", "tables", ["columns", "indexes"], "databaseId", "databaseId"))) {
1691
1497
  return;
1692
1498
  }
1693
- let tablesChanged = new Set();
1694
- // Parallel tables actions
1695
- await Promise.all(tables.map(async (table) => {
1696
- try {
1697
- const remoteTable = await (0, tables_db_1.tablesDBGetTable)({
1698
- databaseId: table['databaseId'],
1699
- tableId: table['$id'],
1700
- parseOutput: false,
1701
- });
1702
- const changes = [];
1703
- if (remoteTable.name !== table.name)
1704
- changes.push('name');
1705
- if (remoteTable.rowSecurity !== table.rowSecurity)
1706
- changes.push('rowSecurity');
1707
- if (remoteTable.enabled !== table.enabled)
1708
- changes.push('enabled');
1709
- if (JSON.stringify(remoteTable['$permissions']) !== JSON.stringify(table['$permissions']))
1710
- changes.push('permissions');
1711
- if (changes.length > 0) {
1712
- await (0, tables_db_1.tablesDBUpdateTable)({
1713
- databaseId: table['databaseId'],
1714
- tableId: table['$id'],
1715
- name: table.name,
1716
- parseOutput: false,
1717
- rowSecurity: table.rowSecurity,
1718
- permissions: table['$permissions']
1719
- });
1720
- (0, parser_1.success)(`Updated ${table.name} ( ${table['$id']} ) - ${changes.join(', ')}`);
1721
- tablesChanged.add(table['$id']);
1722
- }
1723
- table.remoteVersion = remoteTable;
1724
- table.isExisted = true;
1725
- }
1726
- catch (e) {
1727
- if (Number(e.code) === 404) {
1728
- (0, parser_1.log)(`Table ${table.name} does not exist in the project. Creating ... `);
1729
- await (0, tables_db_1.tablesDBCreateTable)({
1730
- databaseId: table['databaseId'],
1731
- tableId: table['$id'],
1732
- name: table.name,
1733
- rowSecurity: table.rowSecurity,
1734
- permissions: table['$permissions'],
1735
- parseOutput: false
1736
- });
1737
- (0, parser_1.success)(`Created ${table.name} ( ${table['$id']} )`);
1738
- tablesChanged.add(table['$id']);
1739
- }
1740
- else {
1741
- throw e;
1742
- }
1743
- }
1744
- }));
1745
- // Serialize attribute actions
1746
- for (let table of tables) {
1747
- let columns = table.columns;
1748
- let indexes = table.indexes;
1749
- if (table.isExisted) {
1750
- columns = await attributesToCreate(table.remoteVersion.columns, table.columns, table);
1751
- indexes = await attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
1752
- if ((Array.isArray(columns) && columns.length <= 0) && (Array.isArray(indexes) && indexes.length <= 0)) {
1753
- continue;
1754
- }
1755
- }
1756
- (0, parser_1.log)(`Pushing table ${table.name} ( ${table['databaseId']} - ${table['$id']} ) attributes`);
1757
- try {
1758
- await createColumns(columns, table);
1759
- }
1760
- catch (e) {
1761
- throw e;
1762
- }
1763
- try {
1764
- await createIndexes(indexes, table);
1765
- }
1766
- catch (e) {
1767
- throw e;
1768
- }
1769
- tablesChanged.add(table['$id']);
1770
- (0, parser_1.success)(`Successfully pushed ${table.name} ( ${table['$id']} )`);
1499
+ log("Pushing tables ...");
1500
+ const pushInstance = await createPushInstance();
1501
+ const result = await pushInstance.pushTables(tables, { attempts });
1502
+ const { successfullyPushed, errors } = result;
1503
+ if (successfullyPushed === 0) {
1504
+ error("No tables were pushed.");
1505
+ }
1506
+ else {
1507
+ success(`Successfully pushed ${successfullyPushed} tables.`);
1508
+ }
1509
+ if (cliConfig.verbose) {
1510
+ errors.forEach((e) => console.error(e));
1771
1511
  }
1772
- (0, parser_1.success)(`Successfully pushed ${tablesChanged.size} tables`);
1773
1512
  };
1774
- const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1775
- (0, parser_1.warn)("appwrite push collection has been deprecated. Please consider using 'appwrite push tables' instead");
1513
+ const pushCollection = async () => {
1514
+ warn(`${EXECUTABLE_NAME} push collection has been deprecated. Please consider using '${EXECUTABLE_NAME} push tables' instead`);
1776
1515
  const collections = [];
1777
- if (attempts) {
1778
- pollMaxDebounces = attempts;
1779
- }
1780
- if (parser_1.cliConfig.all) {
1781
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1782
- collections.push(...config_1.localConfig.getCollections());
1516
+ if (cliConfig.all) {
1517
+ checkDeployConditions(localConfig);
1518
+ collections.push(...localConfig.getCollections());
1783
1519
  }
1784
1520
  else {
1785
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushCollections);
1521
+ const answers = await inquirer.prompt(questionsPushCollections);
1786
1522
  if (answers.collections) {
1787
1523
  const configCollections = new Map();
1788
- config_1.localConfig.getCollections().forEach((c) => {
1789
- configCollections.set(`${c['databaseId']}|${c['$id']}`, c);
1524
+ localConfig.getCollections().forEach((c) => {
1525
+ configCollections.set(`${c["databaseId"]}|${c["$id"]}`, c);
1790
1526
  });
1791
1527
  answers.collections.forEach((a) => {
1792
1528
  const collection = configCollections.get(a);
@@ -1795,124 +1531,51 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
1795
1531
  }
1796
1532
  }
1797
1533
  if (collections.length === 0) {
1798
- (0, parser_1.log)("No collections found.");
1799
- (0, parser_1.hint)("Use 'appwrite pull collections' to synchronize existing one, or use 'appwrite init collection' to create a new one.");
1534
+ log("No collections found.");
1535
+ hint(`Use '${EXECUTABLE_NAME} pull collections' to synchronize existing one, or use '${EXECUTABLE_NAME} init collection' to create a new one.`);
1800
1536
  return;
1801
1537
  }
1802
- const databases = Array.from(new Set(collections.map((collection) => collection['databaseId'])));
1803
- // Parallel db actions
1804
- await Promise.all(databases.map(async (databaseId) => {
1805
- const localDatabase = config_1.localConfig.getDatabase(databaseId);
1806
- try {
1807
- const database = await (0, databases_1.databasesGet)({
1808
- databaseId: databaseId,
1809
- parseOutput: false,
1810
- });
1811
- if (database.name !== (localDatabase.name ?? databaseId)) {
1812
- await (0, databases_1.databasesUpdate)({
1813
- databaseId: databaseId,
1814
- name: localDatabase.name ?? databaseId,
1815
- parseOutput: false
1816
- });
1817
- (0, parser_1.success)(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
1818
- }
1819
- }
1820
- catch (err) {
1821
- (0, parser_1.log)(`Database ${databaseId} not found. Creating it now ...`);
1822
- await (0, databases_1.databasesCreate)({
1823
- databaseId: databaseId,
1824
- name: localDatabase.name ?? databaseId,
1825
- parseOutput: false,
1826
- });
1827
- }
1828
- }));
1829
- if (!(await approveChanges(collections, databases_1.databasesGetCollection, config_1.KeysCollection, 'collectionId', 'collections', ['attributes', 'indexes'], 'databaseId', 'databaseId'))) {
1538
+ // Add database names to collections for the class method
1539
+ collections.forEach((collection) => {
1540
+ const localDatabase = localConfig.getDatabase(collection.databaseId);
1541
+ collection.databaseName = localDatabase.name ?? collection.databaseId;
1542
+ });
1543
+ if (!(await approveChanges(collections, async (args) => {
1544
+ const databasesService = await getDatabasesService();
1545
+ return await databasesService.getCollection(args.databaseId, args.collectionId);
1546
+ }, KeysCollection, "collectionId", "collections", ["attributes", "indexes"], "databaseId", "databaseId"))) {
1830
1547
  return;
1831
1548
  }
1832
- // Parallel collection actions
1833
- await Promise.all(collections.map(async (collection) => {
1834
- try {
1835
- const remoteCollection = await (0, databases_1.databasesGetCollection)({
1836
- databaseId: collection['databaseId'],
1837
- collectionId: collection['$id'],
1838
- parseOutput: false,
1839
- });
1840
- if (remoteCollection.name !== collection.name) {
1841
- await (0, databases_1.databasesUpdateCollection)({
1842
- databaseId: collection['databaseId'],
1843
- collectionId: collection['$id'],
1844
- name: collection.name,
1845
- parseOutput: false
1846
- });
1847
- (0, parser_1.success)(`Updated ${collection.name} ( ${collection['$id']} ) name`);
1848
- }
1849
- collection.remoteVersion = remoteCollection;
1850
- collection.isExisted = true;
1851
- }
1852
- catch (e) {
1853
- if (Number(e.code) === 404) {
1854
- (0, parser_1.log)(`Collection ${collection.name} does not exist in the project. Creating ... `);
1855
- await (0, databases_1.databasesCreateCollection)({
1856
- databaseId: collection['databaseId'],
1857
- collectionId: collection['$id'],
1858
- name: collection.name,
1859
- documentSecurity: collection.documentSecurity,
1860
- permissions: collection['$permissions'],
1861
- parseOutput: false
1862
- });
1863
- }
1864
- else {
1865
- throw e;
1866
- }
1867
- }
1868
- }));
1869
- let numberOfCollections = 0;
1870
- // Serialize attribute actions
1871
- for (let collection of collections) {
1872
- let attributes = collection.attributes;
1873
- let indexes = collection.indexes;
1874
- if (collection.isExisted) {
1875
- attributes = await attributesToCreate(collection.remoteVersion.attributes, collection.attributes, collection);
1876
- indexes = await attributesToCreate(collection.remoteVersion.indexes, collection.indexes, collection, true);
1877
- if ((Array.isArray(attributes) && attributes.length <= 0) && (Array.isArray(indexes) && indexes.length <= 0)) {
1878
- continue;
1879
- }
1880
- }
1881
- (0, parser_1.log)(`Pushing collection ${collection.name} ( ${collection['databaseId']} - ${collection['$id']} ) attributes`);
1882
- try {
1883
- await createAttributes(attributes, collection);
1884
- }
1885
- catch (e) {
1886
- throw e;
1887
- }
1888
- try {
1889
- await createIndexes(indexes, collection);
1890
- }
1891
- catch (e) {
1892
- throw e;
1893
- }
1894
- numberOfCollections++;
1895
- (0, parser_1.success)(`Successfully pushed ${collection.name} ( ${collection['$id']} )`);
1549
+ log("Pushing collections ...");
1550
+ const pushInstance = await createPushInstance();
1551
+ const result = await pushInstance.pushCollections(collections);
1552
+ const { successfullyPushed, errors } = result;
1553
+ if (successfullyPushed === 0) {
1554
+ error("No collections were pushed.");
1555
+ }
1556
+ else {
1557
+ success(`Successfully pushed ${successfullyPushed} collections.`);
1558
+ }
1559
+ if (cliConfig.verbose) {
1560
+ errors.forEach((e) => console.error(e));
1896
1561
  }
1897
- (0, parser_1.success)(`Successfully pushed ${numberOfCollections} collections`);
1898
1562
  };
1899
- const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
1900
- let response = {};
1563
+ const pushBucket = async () => {
1901
1564
  let bucketIds = [];
1902
- const configBuckets = config_1.localConfig.getBuckets();
1903
- if (parser_1.cliConfig.all) {
1904
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1565
+ const configBuckets = localConfig.getBuckets();
1566
+ if (cliConfig.all) {
1567
+ checkDeployConditions(localConfig);
1905
1568
  bucketIds.push(...configBuckets.map((b) => b.$id));
1906
1569
  }
1907
1570
  if (bucketIds.length === 0) {
1908
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushBuckets[0]);
1571
+ const answers = await inquirer.prompt(questionsPushBuckets);
1909
1572
  if (answers.buckets) {
1910
1573
  bucketIds.push(...answers.buckets);
1911
1574
  }
1912
1575
  }
1913
1576
  if (bucketIds.length === 0) {
1914
- (0, parser_1.log)("No buckets found.");
1915
- (0, parser_1.hint)("Use 'appwrite pull buckets' to synchronize existing one, or use 'appwrite init bucket' to create a new one.");
1577
+ log("No buckets found.");
1578
+ hint(`Use '${EXECUTABLE_NAME} pull buckets' to synchronize existing one, or use '${EXECUTABLE_NAME} init bucket' to create a new one.`);
1916
1579
  return;
1917
1580
  }
1918
1581
  let buckets = [];
@@ -1920,72 +1583,42 @@ const pushBucket = async ({ returnOnZero } = { returnOnZero: false }) => {
1920
1583
  const idBuckets = configBuckets.filter((b) => b.$id === bucketId);
1921
1584
  buckets.push(...idBuckets);
1922
1585
  }
1923
- if (!(await approveChanges(buckets, storage_1.storageGetBucket, config_1.KeysStorage, 'bucketId', 'buckets'))) {
1586
+ if (!(await approveChanges(buckets, async (args) => {
1587
+ const storageService = await getStorageService();
1588
+ return await storageService.getBucket(args.bucketId);
1589
+ }, KeysStorage, "bucketId", "buckets"))) {
1924
1590
  return;
1925
1591
  }
1926
- (0, parser_1.log)('Pushing buckets ...');
1927
- for (let bucket of buckets) {
1928
- (0, parser_1.log)(`Pushing bucket ${chalk_1.default.bold(bucket['name'])} ...`);
1929
- try {
1930
- response = await (0, storage_1.storageGetBucket)({
1931
- bucketId: bucket['$id'],
1932
- parseOutput: false,
1933
- });
1934
- await (0, storage_1.storageUpdateBucket)({
1935
- bucketId: bucket['$id'],
1936
- name: bucket.name,
1937
- permissions: bucket['$permissions'],
1938
- fileSecurity: bucket.fileSecurity,
1939
- enabled: bucket.enabled,
1940
- maximumFileSize: bucket.maximumFileSize,
1941
- allowedFileExtensions: bucket.allowedFileExtensions,
1942
- encryption: bucket.encryption,
1943
- antivirus: bucket.antivirus,
1944
- compression: bucket.compression,
1945
- parseOutput: false
1946
- });
1947
- }
1948
- catch (e) {
1949
- if (Number(e.code) === 404) {
1950
- (0, parser_1.log)(`Bucket ${bucket.name} does not exist in the project. Creating ... `);
1951
- response = await (0, storage_1.storageCreateBucket)({
1952
- bucketId: bucket['$id'],
1953
- name: bucket.name,
1954
- permissions: bucket['$permissions'],
1955
- fileSecurity: bucket.fileSecurity,
1956
- enabled: bucket.enabled,
1957
- maximumFileSize: bucket.maximumFileSize,
1958
- allowedFileExtensions: bucket.allowedFileExtensions,
1959
- compression: bucket.compression,
1960
- encryption: bucket.encryption,
1961
- antivirus: bucket.antivirus,
1962
- parseOutput: false
1963
- });
1964
- }
1965
- else {
1966
- throw e;
1967
- }
1968
- }
1592
+ log("Pushing buckets ...");
1593
+ const pushInstance = await createPushInstance();
1594
+ const result = await pushInstance.pushBuckets(buckets);
1595
+ const { successfullyPushed, errors } = result;
1596
+ if (successfullyPushed === 0) {
1597
+ error("No buckets were pushed.");
1598
+ }
1599
+ else {
1600
+ success(`Successfully pushed ${successfullyPushed} buckets.`);
1601
+ }
1602
+ if (cliConfig.verbose) {
1603
+ errors.forEach((e) => console.error(e));
1969
1604
  }
1970
- (0, parser_1.success)(`Successfully pushed ${buckets.length} buckets.`);
1971
1605
  };
1972
- const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
1973
- let response = {};
1606
+ const pushTeam = async () => {
1974
1607
  let teamIds = [];
1975
- const configTeams = config_1.localConfig.getTeams();
1976
- if (parser_1.cliConfig.all) {
1977
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1608
+ const configTeams = localConfig.getTeams();
1609
+ if (cliConfig.all) {
1610
+ checkDeployConditions(localConfig);
1978
1611
  teamIds.push(...configTeams.map((t) => t.$id));
1979
1612
  }
1980
1613
  if (teamIds.length === 0) {
1981
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushTeams[0]);
1614
+ const answers = await inquirer.prompt(questionsPushTeams);
1982
1615
  if (answers.teams) {
1983
1616
  teamIds.push(...answers.teams);
1984
1617
  }
1985
1618
  }
1986
1619
  if (teamIds.length === 0) {
1987
- (0, parser_1.log)("No teams found.");
1988
- (0, parser_1.hint)("Use 'appwrite pull teams' to synchronize existing one, or use 'appwrite init team' to create a new one.");
1620
+ log("No teams found.");
1621
+ hint(`Use '${EXECUTABLE_NAME} pull teams' to synchronize existing one, or use '${EXECUTABLE_NAME} init team' to create a new one.`);
1989
1622
  return;
1990
1623
  }
1991
1624
  let teams = [];
@@ -1993,56 +1626,42 @@ const pushTeam = async ({ returnOnZero } = { returnOnZero: false }) => {
1993
1626
  const idTeams = configTeams.filter((t) => t.$id === teamId);
1994
1627
  teams.push(...idTeams);
1995
1628
  }
1996
- if (!(await approveChanges(teams, teams_1.teamsGet, config_1.KeysTeams, 'teamId', 'teams'))) {
1629
+ if (!(await approveChanges(teams, async (args) => {
1630
+ const teamsService = await getTeamsService();
1631
+ return await teamsService.get(args.teamId);
1632
+ }, KeysTeams, "teamId", "teams"))) {
1997
1633
  return;
1998
1634
  }
1999
- (0, parser_1.log)('Pushing teams ...');
2000
- for (let team of teams) {
2001
- (0, parser_1.log)(`Pushing team ${chalk_1.default.bold(team['name'])} ...`);
2002
- try {
2003
- response = await (0, teams_1.teamsGet)({
2004
- teamId: team['$id'],
2005
- parseOutput: false,
2006
- });
2007
- await (0, teams_1.teamsUpdateName)({
2008
- teamId: team['$id'],
2009
- name: team.name,
2010
- parseOutput: false
2011
- });
2012
- }
2013
- catch (e) {
2014
- if (Number(e.code) === 404) {
2015
- (0, parser_1.log)(`Team ${team.name} does not exist in the project. Creating ... `);
2016
- response = await (0, teams_1.teamsCreate)({
2017
- teamId: team['$id'],
2018
- name: team.name,
2019
- parseOutput: false
2020
- });
2021
- }
2022
- else {
2023
- throw e;
2024
- }
2025
- }
1635
+ log("Pushing teams ...");
1636
+ const pushInstance = await createPushInstance();
1637
+ const result = await pushInstance.pushTeams(teams);
1638
+ const { successfullyPushed, errors } = result;
1639
+ if (successfullyPushed === 0) {
1640
+ error("No teams were pushed.");
1641
+ }
1642
+ else {
1643
+ success(`Successfully pushed ${successfullyPushed} teams.`);
1644
+ }
1645
+ if (cliConfig.verbose) {
1646
+ errors.forEach((e) => console.error(e));
2026
1647
  }
2027
- (0, parser_1.success)(`Successfully pushed ${teams.length} teams.`);
2028
1648
  };
2029
- const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) => {
2030
- let response = {};
1649
+ const pushMessagingTopic = async () => {
2031
1650
  let topicsIds = [];
2032
- const configTopics = config_1.localConfig.getMessagingTopics();
2033
- if (parser_1.cliConfig.all) {
2034
- (0, utils_1.checkDeployConditions)(config_1.localConfig);
1651
+ const configTopics = localConfig.getMessagingTopics();
1652
+ if (cliConfig.all) {
1653
+ checkDeployConditions(localConfig);
2035
1654
  topicsIds.push(...configTopics.map((b) => b.$id));
2036
1655
  }
2037
1656
  if (topicsIds.length === 0) {
2038
- const answers = await inquirer_1.default.prompt(questions_1.questionsPushMessagingTopics[0]);
1657
+ const answers = await inquirer.prompt(questionsPushMessagingTopics);
2039
1658
  if (answers.topics) {
2040
1659
  topicsIds.push(...answers.topics);
2041
1660
  }
2042
1661
  }
2043
1662
  if (topicsIds.length === 0) {
2044
- (0, parser_1.log)("No topics found.");
2045
- (0, parser_1.hint)("Use 'appwrite pull topics' to synchronize existing one, or use 'appwrite init topic' to create a new one.");
1663
+ log("No topics found.");
1664
+ hint(`Use '${EXECUTABLE_NAME} pull topics' to synchronize existing one, or use '${EXECUTABLE_NAME} init topic' to create a new one.`);
2046
1665
  return;
2047
1666
  }
2048
1667
  let topics = [];
@@ -2050,58 +1669,41 @@ const pushMessagingTopic = async ({ returnOnZero } = { returnOnZero: false }) =>
2050
1669
  const idTopic = configTopics.filter((b) => b.$id === topicId);
2051
1670
  topics.push(...idTopic);
2052
1671
  }
2053
- if (!(await approveChanges(topics, messaging_1.messagingGetTopic, config_1.KeysTopics, 'topicId', 'topics'))) {
1672
+ if (!(await approveChanges(topics, async (args) => {
1673
+ const messagingService = await getMessagingService();
1674
+ return await messagingService.getTopic(args.topicId);
1675
+ }, KeysTopics, "topicId", "topics"))) {
2054
1676
  return;
2055
1677
  }
2056
- (0, parser_1.log)('Pushing topics ...');
2057
- for (let topic of topics) {
2058
- (0, parser_1.log)(`Pushing topic ${chalk_1.default.bold(topic['name'])} ...`);
2059
- try {
2060
- response = await (0, messaging_1.messagingGetTopic)({
2061
- topicId: topic['$id'],
2062
- parseOutput: false
2063
- });
2064
- (0, parser_1.log)(`Topic ${topic.name} ( ${topic['$id']} ) already exists.`);
2065
- await (0, messaging_1.messagingUpdateTopic)({
2066
- topicId: topic['$id'],
2067
- name: topic.name,
2068
- subscribe: topic.subscribe,
2069
- parseOutput: false
2070
- });
2071
- }
2072
- catch (e) {
2073
- if (Number(e.code) === 404) {
2074
- (0, parser_1.log)(`Topic ${topic.name} does not exist in the project. Creating ... `);
2075
- response = await (0, messaging_1.messagingCreateTopic)({
2076
- topicId: topic['$id'],
2077
- name: topic.name,
2078
- subscribe: topic.subscribe,
2079
- parseOutput: false
2080
- });
2081
- (0, parser_1.success)(`Created ${topic.name} ( ${topic['$id']} )`);
2082
- }
2083
- else {
2084
- throw e;
2085
- }
2086
- }
1678
+ log("Pushing topics ...");
1679
+ const pushInstance = await createPushInstance();
1680
+ const result = await pushInstance.pushMessagingTopics(topics);
1681
+ const { successfullyPushed, errors } = result;
1682
+ if (successfullyPushed === 0) {
1683
+ error("No topics were pushed.");
1684
+ }
1685
+ else {
1686
+ success(`Successfully pushed ${successfullyPushed} topics.`);
1687
+ }
1688
+ if (cliConfig.verbose) {
1689
+ errors.forEach((e) => console.error(e));
2087
1690
  }
2088
- (0, parser_1.success)(`Successfully pushed ${topics.length} topics.`);
2089
1691
  };
2090
- exports.push = new commander_1.Command("push")
2091
- .description(parser_1.commandDescriptions['push'])
2092
- .action((0, parser_1.actionRunner)(pushResources));
2093
- exports.push
1692
+ export const push = new Command("push")
1693
+ .description(commandDescriptions["push"])
1694
+ .action(actionRunner(() => pushResources({ skipDeprecated: true })));
1695
+ push
2094
1696
  .command("all")
2095
1697
  .description("Push all resource.")
2096
- .action((0, parser_1.actionRunner)(() => {
2097
- parser_1.cliConfig.all = true;
2098
- return pushResources();
1698
+ .action(actionRunner(() => {
1699
+ cliConfig.all = true;
1700
+ return pushResources({ skipDeprecated: true });
2099
1701
  }));
2100
- exports.push
1702
+ push
2101
1703
  .command("settings")
2102
1704
  .description("Push project name, services and auth settings")
2103
- .action((0, parser_1.actionRunner)(pushSettings));
2104
- exports.push
1705
+ .action(actionRunner(pushSettings));
1706
+ push
2105
1707
  .command("function")
2106
1708
  .alias("functions")
2107
1709
  .description("Push functions in the current directory.")
@@ -2109,8 +1711,8 @@ exports.push
2109
1711
  .option(`-A, --async`, `Don't wait for functions deployments status`)
2110
1712
  .option("--no-code", "Don't push the function's code")
2111
1713
  .option("--with-variables", `Push function variables.`)
2112
- .action((0, parser_1.actionRunner)(pushFunction));
2113
- exports.push
1714
+ .action(actionRunner(pushFunction));
1715
+ push
2114
1716
  .command("site")
2115
1717
  .alias("sites")
2116
1718
  .description("Push sites in the current directory.")
@@ -2118,37 +1720,37 @@ exports.push
2118
1720
  .option(`-A, --async`, `Don't wait for sites deployments status`)
2119
1721
  .option("--no-code", "Don't push the site's code")
2120
1722
  .option("--with-variables", `Push site variables.`)
2121
- .action((0, parser_1.actionRunner)(pushSite));
2122
- exports.push
1723
+ .action(actionRunner(pushSite));
1724
+ push
2123
1725
  .command("collection")
2124
1726
  .alias("collections")
2125
1727
  .description("Push collections in the current project. (deprecated, please use 'push tables' instead)")
2126
1728
  .option(`-a, --attempts <numberOfAttempts>`, `Max number of attempts before timing out. default: 30.`)
2127
- .action((0, parser_1.actionRunner)(pushCollection));
2128
- exports.push
1729
+ .action(actionRunner(pushCollection));
1730
+ push
2129
1731
  .command("table")
2130
1732
  .alias("tables")
2131
1733
  .description("Push tables in the current project.")
2132
1734
  .option(`-a, --attempts <numberOfAttempts>`, `Max number of attempts before timing out. default: 30.`)
2133
- .action((0, parser_1.actionRunner)(pushTable));
2134
- exports.push
1735
+ .action(actionRunner(pushTable));
1736
+ push
2135
1737
  .command("bucket")
2136
1738
  .alias("buckets")
2137
1739
  .description("Push buckets in the current project.")
2138
- .action((0, parser_1.actionRunner)(pushBucket));
2139
- exports.push
1740
+ .action(actionRunner(pushBucket));
1741
+ push
2140
1742
  .command("team")
2141
1743
  .alias("teams")
2142
1744
  .description("Push teams in the current project.")
2143
- .action((0, parser_1.actionRunner)(pushTeam));
2144
- exports.push
1745
+ .action(actionRunner(pushTeam));
1746
+ push
2145
1747
  .command("topic")
2146
1748
  .alias("topics")
2147
1749
  .description("Push messaging topics in the current project.")
2148
- .action((0, parser_1.actionRunner)(pushMessagingTopic));
2149
- exports.deploy = new commander_1.Command("deploy")
2150
- .description('Removed. Use appwrite push instead')
2151
- .action((0, parser_1.actionRunner)(async () => {
2152
- (0, parser_1.warn)("appwrite deploy has been removed. Please use 'appwrite push' instead");
1750
+ .action(actionRunner(pushMessagingTopic));
1751
+ export const deploy = new Command("deploy")
1752
+ .description(`Removed. Use ${EXECUTABLE_NAME} push instead`)
1753
+ .action(actionRunner(async () => {
1754
+ warn(`${EXECUTABLE_NAME} deploy has been removed. Please use '${EXECUTABLE_NAME} push' instead`);
2153
1755
  }));
2154
1756
  //# sourceMappingURL=push.js.map