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.
- package/.github/workflows/publish.yml +68 -0
- package/CHANGELOG.md +10 -1
- package/LICENSE.md +1 -1
- package/README.md +3 -3
- package/cli.ts +152 -0
- package/dist/bundle.cjs +95813 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -142
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +2 -3
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +57 -45
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/commands/config.d.ts +562 -0
- package/dist/lib/commands/config.d.ts.map +1 -0
- package/dist/lib/commands/config.js +416 -0
- package/dist/lib/commands/config.js.map +1 -0
- package/dist/lib/commands/db.d.ts +34 -0
- package/dist/lib/commands/db.d.ts.map +1 -0
- package/dist/lib/commands/db.js +247 -0
- package/dist/lib/commands/db.js.map +1 -0
- package/dist/lib/commands/errors.d.ts +68 -0
- package/dist/lib/commands/errors.d.ts.map +1 -0
- package/dist/lib/commands/errors.js +72 -0
- package/dist/lib/commands/errors.js.map +1 -0
- package/dist/lib/commands/generic.d.ts +2 -2
- package/dist/lib/commands/generic.d.ts.map +1 -1
- package/dist/lib/commands/generic.js +170 -157
- package/dist/lib/commands/generic.js.map +1 -1
- package/dist/lib/commands/init.d.ts +1 -1
- package/dist/lib/commands/init.d.ts.map +1 -1
- package/dist/lib/commands/init.js +201 -192
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/pull.d.ts +105 -3
- package/dist/lib/commands/pull.d.ts.map +1 -1
- package/dist/lib/commands/pull.js +530 -370
- package/dist/lib/commands/pull.js.map +1 -1
- package/dist/lib/commands/push.d.ts +106 -0
- package/dist/lib/commands/push.d.ts.map +1 -1
- package/dist/lib/commands/push.js +1432 -1830
- package/dist/lib/commands/push.js.map +1 -1
- package/dist/lib/commands/run.d.ts +1 -1
- package/dist/lib/commands/run.d.ts.map +1 -1
- package/dist/lib/commands/run.js +129 -127
- package/dist/lib/commands/run.js.map +1 -1
- package/dist/lib/commands/schema.d.ts +59 -0
- package/dist/lib/commands/schema.d.ts.map +1 -0
- package/dist/lib/commands/schema.js +86 -0
- package/dist/lib/commands/schema.js.map +1 -0
- package/dist/lib/commands/services/account.d.ts +3 -0
- package/dist/lib/commands/services/account.d.ts.map +1 -0
- package/dist/lib/commands/services/account.js +328 -0
- package/dist/lib/commands/services/account.js.map +1 -0
- package/dist/lib/commands/services/console.d.ts +3 -0
- package/dist/lib/commands/services/console.d.ts.map +1 -0
- package/dist/lib/commands/services/console.js +28 -0
- package/dist/lib/commands/services/console.js.map +1 -0
- package/dist/lib/commands/services/databases.d.ts +3 -0
- package/dist/lib/commands/services/databases.d.ts.map +1 -0
- package/dist/lib/commands/services/databases.js +620 -0
- package/dist/lib/commands/services/databases.js.map +1 -0
- package/dist/lib/commands/services/functions.d.ts +3 -0
- package/dist/lib/commands/services/functions.d.ts.map +1 -0
- package/dist/lib/commands/services/functions.js +266 -0
- package/dist/lib/commands/services/functions.js.map +1 -0
- package/dist/lib/commands/services/graphql.d.ts +3 -0
- package/dist/lib/commands/services/graphql.d.ts.map +1 -0
- package/dist/lib/commands/services/graphql.js +28 -0
- package/dist/lib/commands/services/graphql.js.map +1 -0
- package/dist/lib/commands/services/health.d.ts +3 -0
- package/dist/lib/commands/services/health.d.ts.map +1 -0
- package/dist/lib/commands/services/health.js +123 -0
- package/dist/lib/commands/services/health.js.map +1 -0
- package/dist/lib/commands/services/locale.d.ts +3 -0
- package/dist/lib/commands/services/locale.d.ts.map +1 -0
- package/dist/lib/commands/services/locale.js +52 -0
- package/dist/lib/commands/services/locale.js.map +1 -0
- package/dist/lib/commands/services/messaging.d.ts +3 -0
- package/dist/lib/commands/services/messaging.d.ts.map +1 -0
- package/dist/lib/commands/services/messaging.js +505 -0
- package/dist/lib/commands/services/messaging.js.map +1 -0
- package/dist/lib/commands/services/migrations.d.ts +3 -0
- package/dist/lib/commands/services/migrations.d.ts.map +1 -0
- package/dist/lib/commands/services/migrations.js +135 -0
- package/dist/lib/commands/services/migrations.js.map +1 -0
- package/dist/lib/commands/services/project.d.ts +3 -0
- package/dist/lib/commands/services/project.d.ts.map +1 -0
- package/dist/lib/commands/services/project.js +54 -0
- package/dist/lib/commands/services/project.js.map +1 -0
- package/dist/lib/commands/services/projects.d.ts +3 -0
- package/dist/lib/commands/services/projects.d.ts.map +1 -0
- package/dist/lib/commands/services/projects.js +415 -0
- package/dist/lib/commands/services/projects.js.map +1 -0
- package/dist/lib/commands/services/proxy.d.ts +3 -0
- package/dist/lib/commands/services/proxy.d.ts.map +1 -0
- package/dist/lib/commands/services/proxy.js +68 -0
- package/dist/lib/commands/services/proxy.js.map +1 -0
- package/dist/lib/commands/services/sites.d.ts +3 -0
- package/dist/lib/commands/services/sites.d.ts.map +1 -0
- package/dist/lib/commands/services/sites.js +250 -0
- package/dist/lib/commands/services/sites.js.map +1 -0
- package/dist/lib/commands/services/storage.d.ts +3 -0
- package/dist/lib/commands/services/storage.d.ts.map +1 -0
- package/dist/lib/commands/services/storage.js +175 -0
- package/dist/lib/commands/services/storage.js.map +1 -0
- package/dist/lib/commands/services/tables-db.d.ts +3 -0
- package/dist/lib/commands/services/tables-db.d.ts.map +1 -0
- package/dist/lib/commands/services/tables-db.js +613 -0
- package/dist/lib/commands/services/tables-db.js.map +1 -0
- package/dist/lib/commands/services/teams.d.ts +3 -0
- package/dist/lib/commands/services/teams.d.ts.map +1 -0
- package/dist/lib/commands/services/teams.js +123 -0
- package/dist/lib/commands/services/teams.js.map +1 -0
- package/dist/lib/commands/services/tokens.d.ts +3 -0
- package/dist/lib/commands/services/tokens.d.ts.map +1 -0
- package/dist/lib/commands/services/tokens.js +49 -0
- package/dist/lib/commands/services/tokens.js.map +1 -0
- package/dist/lib/commands/services/users.d.ts +3 -0
- package/dist/lib/commands/services/users.d.ts.map +1 -0
- package/dist/lib/commands/services/users.js +312 -0
- package/dist/lib/commands/services/users.js.map +1 -0
- package/dist/lib/commands/services/vcs.d.ts +3 -0
- package/dist/lib/commands/services/vcs.d.ts.map +1 -0
- package/dist/lib/commands/services/vcs.js +87 -0
- package/dist/lib/commands/services/vcs.js.map +1 -0
- package/dist/lib/commands/types.d.ts +1 -1
- package/dist/lib/commands/types.d.ts.map +1 -1
- package/dist/lib/commands/types.js +53 -57
- package/dist/lib/commands/types.js.map +1 -1
- package/dist/lib/commands/update.d.ts +1 -1
- package/dist/lib/commands/update.d.ts.map +1 -1
- package/dist/lib/commands/update.js +69 -69
- package/dist/lib/commands/update.js.map +1 -1
- package/dist/lib/commands/utils/attributes.d.ts +47 -0
- package/dist/lib/commands/utils/attributes.d.ts.map +1 -0
- package/dist/lib/commands/utils/attributes.js +514 -0
- package/dist/lib/commands/utils/attributes.js.map +1 -0
- package/dist/lib/commands/utils/change-approval.d.ts +25 -0
- package/dist/lib/commands/utils/change-approval.d.ts.map +1 -0
- package/dist/lib/commands/utils/change-approval.js +129 -0
- package/dist/lib/commands/utils/change-approval.js.map +1 -0
- package/dist/lib/commands/utils/database-sync.d.ts +10 -0
- package/dist/lib/commands/utils/database-sync.d.ts.map +1 -0
- package/dist/lib/commands/utils/database-sync.js +136 -0
- package/dist/lib/commands/utils/database-sync.js.map +1 -0
- package/dist/lib/commands/utils/deployment.d.ts +34 -0
- package/dist/lib/commands/utils/deployment.d.ts.map +1 -0
- package/dist/lib/commands/utils/deployment.js +109 -0
- package/dist/lib/commands/utils/deployment.js.map +1 -0
- package/dist/lib/commands/utils/error-formatter.d.ts +19 -0
- package/dist/lib/commands/utils/error-formatter.d.ts.map +1 -0
- package/dist/lib/commands/utils/error-formatter.js +333 -0
- package/dist/lib/commands/utils/error-formatter.js.map +1 -0
- package/dist/lib/commands/utils/pools.d.ts +16 -0
- package/dist/lib/commands/utils/pools.d.ts.map +1 -0
- package/dist/lib/commands/utils/pools.js +198 -0
- package/dist/lib/commands/utils/pools.js.map +1 -0
- package/dist/lib/config.d.ts +41 -40
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +264 -239
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +14 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +19 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/emulation/docker.d.ts +4 -12
- package/dist/lib/emulation/docker.d.ts.map +1 -1
- package/dist/lib/emulation/docker.js +159 -142
- package/dist/lib/emulation/docker.js.map +1 -1
- package/dist/lib/emulation/utils.d.ts +1 -1
- package/dist/lib/emulation/utils.d.ts.map +1 -1
- package/dist/lib/emulation/utils.js +55 -58
- package/dist/lib/emulation/utils.js.map +1 -1
- package/dist/lib/id.d.ts +1 -1
- package/dist/lib/id.d.ts.map +1 -1
- package/dist/lib/id.js +13 -18
- package/dist/lib/id.js.map +1 -1
- package/dist/lib/paginate.d.ts +3 -4
- package/dist/lib/paginate.d.ts.map +1 -1
- package/dist/lib/paginate.js +7 -10
- package/dist/lib/paginate.js.map +1 -1
- package/dist/lib/parser.d.ts +1 -1
- package/dist/lib/parser.d.ts.map +1 -1
- package/dist/lib/parser.js +92 -103
- package/dist/lib/parser.js.map +1 -1
- package/dist/lib/questions.d.ts +1 -1
- package/dist/lib/questions.d.ts.map +1 -1
- package/dist/lib/questions.js +381 -385
- package/dist/lib/questions.js.map +1 -1
- package/dist/lib/sdks.d.ts +1 -1
- package/dist/lib/sdks.d.ts.map +1 -1
- package/dist/lib/sdks.js +39 -30
- package/dist/lib/sdks.js.map +1 -1
- package/dist/lib/services.d.ts +13 -0
- package/dist/lib/services.d.ts.map +1 -0
- package/dist/lib/services.js +47 -0
- package/dist/lib/services.js.map +1 -0
- package/dist/lib/spinner.d.ts +1 -1
- package/dist/lib/spinner.d.ts.map +1 -1
- package/dist/lib/spinner.js +25 -27
- package/dist/lib/spinner.js.map +1 -1
- package/dist/lib/type-generation/attribute.d.ts +1 -1
- package/dist/lib/type-generation/attribute.d.ts.map +1 -1
- package/dist/lib/type-generation/attribute.js +14 -17
- package/dist/lib/type-generation/attribute.js.map +1 -1
- package/dist/lib/type-generation/languages/csharp.d.ts +1 -1
- package/dist/lib/type-generation/languages/csharp.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/csharp.js +34 -34
- package/dist/lib/type-generation/languages/csharp.js.map +1 -1
- package/dist/lib/type-generation/languages/dart.d.ts +1 -1
- package/dist/lib/type-generation/languages/dart.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/dart.js +57 -57
- package/dist/lib/type-generation/languages/dart.js.map +1 -1
- package/dist/lib/type-generation/languages/java.d.ts +1 -1
- package/dist/lib/type-generation/languages/java.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/java.js +35 -35
- package/dist/lib/type-generation/languages/java.js.map +1 -1
- package/dist/lib/type-generation/languages/javascript.d.ts +1 -1
- package/dist/lib/type-generation/languages/javascript.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/javascript.js +45 -44
- package/dist/lib/type-generation/languages/javascript.js.map +1 -1
- package/dist/lib/type-generation/languages/kotlin.d.ts +1 -1
- package/dist/lib/type-generation/languages/kotlin.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/kotlin.js +35 -35
- package/dist/lib/type-generation/languages/kotlin.js.map +1 -1
- package/dist/lib/type-generation/languages/language.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/language.js +32 -37
- package/dist/lib/type-generation/languages/language.js.map +1 -1
- package/dist/lib/type-generation/languages/php.d.ts +1 -1
- package/dist/lib/type-generation/languages/php.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/php.js +34 -34
- package/dist/lib/type-generation/languages/php.js.map +1 -1
- package/dist/lib/type-generation/languages/swift.d.ts +1 -1
- package/dist/lib/type-generation/languages/swift.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/swift.js +35 -35
- package/dist/lib/type-generation/languages/swift.js.map +1 -1
- package/dist/lib/type-generation/languages/typescript.d.ts +1 -1
- package/dist/lib/type-generation/languages/typescript.d.ts.map +1 -1
- package/dist/lib/type-generation/languages/typescript.js +49 -46
- package/dist/lib/type-generation/languages/typescript.js.map +1 -1
- package/dist/lib/types.d.ts +38 -108
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +1 -2
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +142 -98
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/validations.d.ts.map +1 -1
- package/dist/lib/validations.js +2 -6
- package/dist/lib/validations.js.map +1 -1
- package/dist/package.json +68 -0
- package/index.ts +25 -149
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.ts +261 -220
- package/lib/commands/config.ts +494 -0
- package/lib/commands/db.ts +324 -0
- package/lib/commands/errors.ts +93 -0
- package/lib/commands/generic.ts +371 -269
- package/lib/commands/init.ts +631 -519
- package/lib/commands/pull.ts +827 -453
- package/lib/commands/push.ts +2191 -2349
- package/lib/commands/run.ts +382 -302
- package/lib/commands/schema.ts +122 -0
- package/lib/commands/services/account.ts +647 -0
- package/lib/commands/services/console.ts +52 -0
- package/lib/commands/services/databases.ts +1163 -0
- package/lib/commands/services/functions.ts +536 -0
- package/lib/commands/services/graphql.ts +50 -0
- package/lib/commands/services/health.ts +260 -0
- package/lib/commands/services/locale.ts +102 -0
- package/lib/commands/services/messaging.ts +1052 -0
- package/lib/commands/services/migrations.ts +249 -0
- package/lib/commands/services/project.ts +112 -0
- package/lib/commands/services/projects.ts +785 -0
- package/lib/commands/services/proxy.ts +135 -0
- package/lib/commands/services/sites.ts +505 -0
- package/lib/commands/services/storage.ts +338 -0
- package/lib/commands/services/tables-db.ts +1150 -0
- package/lib/commands/services/teams.ts +232 -0
- package/lib/commands/services/tokens.ts +94 -0
- package/lib/commands/services/users.ts +616 -0
- package/lib/commands/services/vcs.ts +165 -0
- package/lib/commands/types.ts +145 -118
- package/lib/commands/update.ts +189 -159
- package/lib/commands/utils/attributes.ts +719 -0
- package/lib/commands/utils/change-approval.ts +186 -0
- package/lib/commands/utils/database-sync.ts +180 -0
- package/lib/commands/utils/deployment.ts +184 -0
- package/lib/commands/utils/error-formatter.ts +417 -0
- package/lib/commands/utils/pools.ts +355 -0
- package/lib/config.ts +766 -687
- package/lib/constants.ts +22 -0
- package/lib/emulation/docker.ts +277 -216
- package/lib/emulation/utils.ts +188 -174
- package/lib/id.ts +23 -23
- package/lib/paginate.ts +69 -55
- package/lib/parser.ts +220 -189
- package/lib/questions.ts +1024 -948
- package/lib/sdks.ts +84 -51
- package/lib/services.ts +72 -0
- package/lib/spinner.ts +112 -99
- package/lib/type-generation/attribute.ts +15 -14
- package/lib/type-generation/languages/csharp.ts +71 -60
- package/lib/type-generation/languages/dart.ts +106 -93
- package/lib/type-generation/languages/java.ts +69 -58
- package/lib/type-generation/languages/javascript.ts +84 -73
- package/lib/type-generation/languages/kotlin.ts +71 -60
- package/lib/type-generation/languages/language.ts +103 -95
- package/lib/type-generation/languages/php.ts +67 -56
- package/lib/type-generation/languages/swift.ts +71 -60
- package/lib/type-generation/languages/typescript.ts +93 -76
- package/lib/types.ts +50 -125
- package/lib/utils.ts +304 -233
- package/lib/validations.ts +17 -14
- package/package.json +31 -22
- package/scoop/appwrite.config.json +3 -3
- package/tsconfig.json +7 -13
- package/.github/workflows/autoclose.yml +0 -11
- package/.github/workflows/npm-publish.yml +0 -49
- package/dist/lib/commands/account.d.ts +0 -379
- package/dist/lib/commands/account.d.ts.map +0 -1
- package/dist/lib/commands/account.js +0 -1228
- package/dist/lib/commands/account.js.map +0 -1
- package/dist/lib/commands/console.d.ts +0 -20
- package/dist/lib/commands/console.d.ts.map +0 -1
- package/dist/lib/commands/console.js +0 -78
- package/dist/lib/commands/console.js.map +0 -1
- package/dist/lib/commands/databases.d.ts +0 -732
- package/dist/lib/commands/databases.d.ts.map +0 -1
- package/dist/lib/commands/databases.js +0 -2196
- package/dist/lib/commands/databases.js.map +0 -1
- package/dist/lib/commands/functions.d.ts +0 -310
- package/dist/lib/commands/functions.d.ts.map +0 -1
- package/dist/lib/commands/functions.js +0 -1100
- package/dist/lib/commands/functions.js.map +0 -1
- package/dist/lib/commands/graphql.d.ts +0 -19
- package/dist/lib/commands/graphql.d.ts.map +0 -1
- package/dist/lib/commands/graphql.js +0 -77
- package/dist/lib/commands/graphql.js.map +0 -1
- package/dist/lib/commands/health.d.ts +0 -153
- package/dist/lib/commands/health.d.ts.map +0 -1
- package/dist/lib/commands/health.js +0 -464
- package/dist/lib/commands/health.js.map +0 -1
- package/dist/lib/commands/locale.d.ts +0 -53
- package/dist/lib/commands/locale.d.ts.map +0 -1
- package/dist/lib/commands/locale.js +0 -165
- package/dist/lib/commands/locale.js.map +0 -1
- package/dist/lib/commands/messaging.d.ts +0 -588
- package/dist/lib/commands/messaging.d.ts.map +0 -1
- package/dist/lib/commands/messaging.js +0 -2042
- package/dist/lib/commands/messaging.js.map +0 -1
- package/dist/lib/commands/migrations.d.ts +0 -150
- package/dist/lib/commands/migrations.d.ts.map +0 -1
- package/dist/lib/commands/migrations.js +0 -524
- package/dist/lib/commands/migrations.js.map +0 -1
- package/dist/lib/commands/organizations.d.ts +0 -11
- package/dist/lib/commands/organizations.d.ts.map +0 -1
- package/dist/lib/commands/organizations.js +0 -31
- package/dist/lib/commands/organizations.js.map +0 -1
- package/dist/lib/commands/project.d.ts +0 -53
- package/dist/lib/commands/project.d.ts.map +0 -1
- package/dist/lib/commands/project.js +0 -176
- package/dist/lib/commands/project.js.map +0 -1
- package/dist/lib/commands/projects.d.ts +0 -516
- package/dist/lib/commands/projects.d.ts.map +0 -1
- package/dist/lib/commands/projects.js +0 -1590
- package/dist/lib/commands/projects.js.map +0 -1
- package/dist/lib/commands/proxy.d.ts +0 -71
- package/dist/lib/commands/proxy.d.ts.map +0 -1
- package/dist/lib/commands/proxy.js +0 -240
- package/dist/lib/commands/proxy.js.map +0 -1
- package/dist/lib/commands/sites.d.ts +0 -296
- package/dist/lib/commands/sites.d.ts.map +0 -1
- package/dist/lib/commands/sites.js +0 -1046
- package/dist/lib/commands/sites.js.map +0 -1
- package/dist/lib/commands/storage.d.ts +0 -170
- package/dist/lib/commands/storage.d.ts.map +0 -1
- package/dist/lib/commands/storage.js +0 -651
- package/dist/lib/commands/storage.js.map +0 -1
- package/dist/lib/commands/tables-db.d.ts +0 -728
- package/dist/lib/commands/tables-db.d.ts.map +0 -1
- package/dist/lib/commands/tables-db.js +0 -2198
- package/dist/lib/commands/tables-db.js.map +0 -1
- package/dist/lib/commands/teams.d.ts +0 -129
- package/dist/lib/commands/teams.d.ts.map +0 -1
- package/dist/lib/commands/teams.js +0 -403
- package/dist/lib/commands/teams.js.map +0 -1
- package/dist/lib/commands/tokens.d.ts +0 -48
- package/dist/lib/commands/tokens.d.ts.map +0 -1
- package/dist/lib/commands/tokens.js +0 -156
- package/dist/lib/commands/tokens.js.map +0 -1
- package/dist/lib/commands/users.d.ts +0 -382
- package/dist/lib/commands/users.d.ts.map +0 -1
- package/dist/lib/commands/users.js +0 -1195
- package/dist/lib/commands/users.js.map +0 -1
- package/dist/lib/commands/vcs.d.ts +0 -92
- package/dist/lib/commands/vcs.d.ts.map +0 -1
- package/dist/lib/commands/vcs.js +0 -276
- package/dist/lib/commands/vcs.js.map +0 -1
- package/dist/lib/exception.d.ts +0 -8
- package/dist/lib/exception.d.ts.map +0 -1
- package/dist/lib/exception.js +0 -16
- package/dist/lib/exception.js.map +0 -1
- package/lib/commands/account.ts +0 -1867
- package/lib/commands/console.ts +0 -112
- package/lib/commands/databases.ts +0 -3272
- package/lib/commands/functions.ts +0 -1587
- package/lib/commands/graphql.ts +0 -110
- package/lib/commands/health.ts +0 -753
- package/lib/commands/locale.ts +0 -270
- package/lib/commands/messaging.ts +0 -2878
- package/lib/commands/migrations.ts +0 -754
- package/lib/commands/organizations.ts +0 -46
- package/lib/commands/project.ts +0 -266
- package/lib/commands/projects.ts +0 -2370
- package/lib/commands/proxy.ts +0 -357
- package/lib/commands/sites.ts +0 -1514
- package/lib/commands/storage.ts +0 -919
- package/lib/commands/tables-db.ts +0 -3260
- package/lib/commands/teams.ts +0 -609
- package/lib/commands/tokens.ts +0 -232
- package/lib/commands/users.ts +0 -1804
- package/lib/commands/vcs.ts +0 -428
- package/lib/exception.ts +0 -20
|
@@ -1,1630 +1,1440 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
176
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
289
|
-
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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
|
-
|
|
663
|
-
|
|
664
|
-
|
|
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
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
const
|
|
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
|
-
|
|
838
|
-
await
|
|
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
|
-
|
|
243
|
+
this.log("Applying service statuses ...");
|
|
846
244
|
for (let [service, status] of Object.entries(settings.services)) {
|
|
847
|
-
await
|
|
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
|
-
|
|
858
|
-
await
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
await
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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
|
-
|
|
289
|
+
this.log("Applying auth methods statuses ...");
|
|
869
290
|
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
870
|
-
await
|
|
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
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
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
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
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
|
-
|
|
949
|
-
|
|
950
|
-
|
|
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
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
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
|
-
|
|
606
|
+
catch (e) {
|
|
977
607
|
errors.push(e);
|
|
978
|
-
|
|
979
|
-
|
|
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
|
-
|
|
983
|
-
|
|
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 (
|
|
986
|
-
|
|
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
|
-
|
|
990
|
-
|
|
991
|
-
|
|
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
|
-
|
|
741
|
+
buildRuntime: site.buildRuntime,
|
|
995
742
|
adapter: site.adapter,
|
|
996
|
-
|
|
997
|
-
enabled: site.enabled,
|
|
998
|
-
logging: site.logging,
|
|
999
|
-
parseOutput: false
|
|
743
|
+
specification: site.specification,
|
|
1000
744
|
});
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
745
|
+
}
|
|
746
|
+
catch (e) {
|
|
747
|
+
if (Number(e.code) === 404) {
|
|
748
|
+
siteExists = false;
|
|
1005
749
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
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
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
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
|
-
|
|
1018
|
-
throw error;
|
|
833
|
+
envVariables = [];
|
|
1019
834
|
}
|
|
1020
|
-
|
|
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
|
-
|
|
1025
|
-
|
|
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
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
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
|
-
|
|
1042
|
-
|
|
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
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
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 (
|
|
1050
|
-
|
|
1051
|
-
|
|
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
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
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
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
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
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
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
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
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 = `${
|
|
1149
|
-
|
|
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
|
-
|
|
1302
|
+
error("No sites were pushed.");
|
|
1154
1303
|
}
|
|
1155
1304
|
else if (successfullyDeployed !== successfullyPushed) {
|
|
1156
|
-
|
|
1305
|
+
warn(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} sites`);
|
|
1157
1306
|
}
|
|
1158
1307
|
else {
|
|
1159
|
-
|
|
1308
|
+
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
1160
1309
|
}
|
|
1161
1310
|
}
|
|
1162
1311
|
else {
|
|
1163
|
-
|
|
1312
|
+
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
1164
1313
|
}
|
|
1165
|
-
if (
|
|
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 } = {
|
|
1172
|
-
process.chdir(
|
|
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 (
|
|
1178
|
-
|
|
1179
|
-
const functions =
|
|
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
|
|
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
|
-
|
|
1192
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
1208
|
-
const answers = await
|
|
1355
|
+
log(`Function ${func.name} is missing an entrypoint.`);
|
|
1356
|
+
const answers = await inquirer.prompt(questionsGetEntrypoint);
|
|
1209
1357
|
func.entrypoint = answers.entrypoint;
|
|
1210
|
-
|
|
1358
|
+
localConfig.addFunction(func);
|
|
1211
1359
|
}
|
|
1212
1360
|
}
|
|
1213
|
-
if (!(await approveChanges(functions,
|
|
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
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
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 = `${
|
|
1433
|
-
|
|
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
|
-
|
|
1382
|
+
error("No functions were pushed.");
|
|
1438
1383
|
}
|
|
1439
1384
|
else if (successfullyDeployed !== successfullyPushed) {
|
|
1440
|
-
|
|
1385
|
+
warn(`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} functions`);
|
|
1441
1386
|
}
|
|
1442
1387
|
else {
|
|
1443
|
-
|
|
1388
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1444
1389
|
}
|
|
1445
1390
|
}
|
|
1446
1391
|
else {
|
|
1447
|
-
|
|
1392
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1448
1393
|
}
|
|
1449
|
-
if (
|
|
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
|
|
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
|
-
|
|
1595
|
-
pollMaxDebounces = attempts;
|
|
1596
|
-
}
|
|
1597
|
-
const { applied: tablesDBApplied, resyncNeeded } = await checkAndApplyTablesDBChanges();
|
|
1402
|
+
const { resyncNeeded } = await checkAndApplyTablesDBChanges();
|
|
1598
1403
|
if (resyncNeeded) {
|
|
1599
|
-
|
|
1600
|
-
const remoteTablesDBs = (await (
|
|
1601
|
-
|
|
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 =
|
|
1411
|
+
const localTables = localConfig.getTables();
|
|
1604
1412
|
const validTables = localTables.filter((table) => remoteDatabaseIds.has(table.databaseId));
|
|
1605
|
-
|
|
1413
|
+
localConfig.set("tables", validTables);
|
|
1606
1414
|
const validTablesDBs = localTablesDBs.filter((db) => remoteDatabaseIds.has(db.$id));
|
|
1607
|
-
|
|
1608
|
-
|
|
1415
|
+
localConfig.set("tablesDB", validTablesDBs);
|
|
1416
|
+
success("Configuration resynced successfully.");
|
|
1609
1417
|
console.log();
|
|
1610
1418
|
}
|
|
1611
|
-
|
|
1612
|
-
const localTablesDBs =
|
|
1613
|
-
const localTables =
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
1447
|
+
log("Found tables that exist remotely but not locally:");
|
|
1638
1448
|
const deletionChanges = tablesToDelete.map((table) => ({
|
|
1639
1449
|
id: table.$id,
|
|
1640
|
-
action:
|
|
1641
|
-
key:
|
|
1450
|
+
action: chalk.red("deleting"),
|
|
1451
|
+
key: "Table",
|
|
1642
1452
|
database: table.databaseName,
|
|
1643
1453
|
remote: table.name,
|
|
1644
|
-
local:
|
|
1454
|
+
local: "(deleted locally)",
|
|
1645
1455
|
}));
|
|
1646
|
-
|
|
1456
|
+
drawTable(deletionChanges);
|
|
1647
1457
|
if ((await getConfirmation()) === true) {
|
|
1648
1458
|
for (const table of tablesToDelete) {
|
|
1649
1459
|
try {
|
|
1650
|
-
|
|
1651
|
-
await (
|
|
1652
|
-
|
|
1653
|
-
|
|
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
|
-
|
|
1466
|
+
error(`Failed to delete table ${table.name} ( ${table.$id} ): ${e.message}`);
|
|
1660
1467
|
}
|
|
1661
1468
|
}
|
|
1662
1469
|
}
|
|
1663
1470
|
}
|
|
1664
|
-
|
|
1665
|
-
|
|
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
|
|
1476
|
+
const answers = await inquirer.prompt(questionsPushTables);
|
|
1674
1477
|
if (answers.tables) {
|
|
1675
1478
|
const configTables = new Map();
|
|
1676
|
-
|
|
1677
|
-
configTables.set(`${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
|
-
|
|
1687
|
-
|
|
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,
|
|
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
|
-
|
|
1694
|
-
|
|
1695
|
-
await
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
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 (
|
|
1775
|
-
|
|
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 (
|
|
1778
|
-
|
|
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
|
|
1521
|
+
const answers = await inquirer.prompt(questionsPushCollections);
|
|
1786
1522
|
if (answers.collections) {
|
|
1787
1523
|
const configCollections = new Map();
|
|
1788
|
-
|
|
1789
|
-
configCollections.set(`${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
|
-
|
|
1799
|
-
|
|
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
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
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
|
-
|
|
1833
|
-
await
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
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 (
|
|
1900
|
-
let response = {};
|
|
1563
|
+
const pushBucket = async () => {
|
|
1901
1564
|
let bucketIds = [];
|
|
1902
|
-
const configBuckets =
|
|
1903
|
-
if (
|
|
1904
|
-
|
|
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
|
|
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
|
-
|
|
1915
|
-
|
|
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,
|
|
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
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
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 (
|
|
1973
|
-
let response = {};
|
|
1606
|
+
const pushTeam = async () => {
|
|
1974
1607
|
let teamIds = [];
|
|
1975
|
-
const configTeams =
|
|
1976
|
-
if (
|
|
1977
|
-
|
|
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
|
|
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
|
-
|
|
1988
|
-
|
|
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,
|
|
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
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
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 (
|
|
2030
|
-
let response = {};
|
|
1649
|
+
const pushMessagingTopic = async () => {
|
|
2031
1650
|
let topicsIds = [];
|
|
2032
|
-
const configTopics =
|
|
2033
|
-
if (
|
|
2034
|
-
|
|
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
|
|
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
|
-
|
|
2045
|
-
|
|
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,
|
|
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
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
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
|
-
|
|
2091
|
-
.description(
|
|
2092
|
-
.action((
|
|
2093
|
-
|
|
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(
|
|
2097
|
-
|
|
2098
|
-
return pushResources();
|
|
1698
|
+
.action(actionRunner(() => {
|
|
1699
|
+
cliConfig.all = true;
|
|
1700
|
+
return pushResources({ skipDeprecated: true });
|
|
2099
1701
|
}));
|
|
2100
|
-
|
|
1702
|
+
push
|
|
2101
1703
|
.command("settings")
|
|
2102
1704
|
.description("Push project name, services and auth settings")
|
|
2103
|
-
.action(
|
|
2104
|
-
|
|
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(
|
|
2113
|
-
|
|
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(
|
|
2122
|
-
|
|
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(
|
|
2128
|
-
|
|
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(
|
|
2134
|
-
|
|
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(
|
|
2139
|
-
|
|
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(
|
|
2144
|
-
|
|
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(
|
|
2149
|
-
|
|
2150
|
-
.description(
|
|
2151
|
-
.action(
|
|
2152
|
-
|
|
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
|