appwrite-cli 13.0.0-rc.2 → 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/{npm-publish.yml → publish.yml} +1 -1
- package/CHANGELOG.md +106 -101
- package/LICENSE.md +2 -2
- package/README.md +36 -59
- package/cli.ts +152 -0
- package/dist/bundle.cjs +4613 -3653
- 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.map +1 -1
- package/dist/lib/client.js +7 -6
- 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/init.d.ts.map +1 -1
- package/dist/lib/commands/init.js +15 -14
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/pull.d.ts +104 -2
- package/dist/lib/commands/pull.d.ts.map +1 -1
- package/dist/lib/commands/pull.js +470 -281
- 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 +1257 -1628
- package/dist/lib/commands/push.js.map +1 -1
- package/dist/lib/commands/run.js +1 -1
- 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.map +1 -1
- package/dist/lib/commands/services/account.js +86 -64
- package/dist/lib/commands/services/account.js.map +1 -1
- package/dist/lib/commands/services/console.d.ts.map +1 -1
- package/dist/lib/commands/services/console.js +4 -17
- package/dist/lib/commands/services/console.js.map +1 -1
- package/dist/lib/commands/services/databases.d.ts.map +1 -1
- package/dist/lib/commands/services/databases.js +160 -152
- package/dist/lib/commands/services/databases.js.map +1 -1
- package/dist/lib/commands/services/functions.d.ts.map +1 -1
- package/dist/lib/commands/services/functions.js +41 -33
- package/dist/lib/commands/services/functions.js.map +1 -1
- package/dist/lib/commands/services/graphql.d.ts.map +1 -1
- package/dist/lib/commands/services/graphql.js +3 -3
- package/dist/lib/commands/services/graphql.js.map +1 -1
- package/dist/lib/commands/services/health.d.ts.map +1 -1
- package/dist/lib/commands/services/health.js +24 -24
- package/dist/lib/commands/services/health.js.map +1 -1
- package/dist/lib/commands/services/locale.d.ts.map +1 -1
- package/dist/lib/commands/services/locale.js +9 -9
- package/dist/lib/commands/services/locale.js.map +1 -1
- package/dist/lib/commands/services/messaging.d.ts.map +1 -1
- package/dist/lib/commands/services/messaging.js +59 -59
- package/dist/lib/commands/services/messaging.js.map +1 -1
- package/dist/lib/commands/services/migrations.d.ts.map +1 -1
- package/dist/lib/commands/services/migrations.js +19 -19
- package/dist/lib/commands/services/migrations.js.map +1 -1
- package/dist/lib/commands/services/project.d.ts.map +1 -1
- package/dist/lib/commands/services/project.js +8 -8
- package/dist/lib/commands/services/project.js.map +1 -1
- package/dist/lib/commands/services/projects.d.ts.map +1 -1
- package/dist/lib/commands/services/projects.js +64 -64
- package/dist/lib/commands/services/projects.js.map +1 -1
- package/dist/lib/commands/services/proxy.d.ts.map +1 -1
- package/dist/lib/commands/services/proxy.js +11 -11
- package/dist/lib/commands/services/proxy.js.map +1 -1
- package/dist/lib/commands/services/sites.d.ts.map +1 -1
- package/dist/lib/commands/services/sites.js +41 -33
- package/dist/lib/commands/services/sites.js.map +1 -1
- package/dist/lib/commands/services/storage.d.ts.map +1 -1
- package/dist/lib/commands/services/storage.js +38 -16
- package/dist/lib/commands/services/storage.js.map +1 -1
- 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/{tablesdb.js → tables-db.js} +171 -163
- package/dist/lib/commands/services/tables-db.js.map +1 -0
- package/dist/lib/commands/services/teams.d.ts.map +1 -1
- package/dist/lib/commands/services/teams.js +16 -16
- package/dist/lib/commands/services/teams.js.map +1 -1
- package/dist/lib/commands/services/tokens.d.ts.map +1 -1
- package/dist/lib/commands/services/tokens.js +6 -6
- package/dist/lib/commands/services/tokens.js.map +1 -1
- package/dist/lib/commands/services/users.d.ts.map +1 -1
- package/dist/lib/commands/services/users.js +54 -54
- package/dist/lib/commands/services/users.js.map +1 -1
- package/dist/lib/commands/services/vcs.d.ts.map +1 -1
- package/dist/lib/commands/services/vcs.js +13 -13
- package/dist/lib/commands/services/vcs.js.map +1 -1
- package/dist/lib/commands/types.d.ts.map +1 -1
- package/dist/lib/commands/types.js +1 -1
- package/dist/lib/commands/types.js.map +1 -1
- package/dist/lib/commands/update.d.ts.map +1 -1
- package/dist/lib/commands/update.js +9 -8
- 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 +27 -26
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +8 -45
- 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 -4
- package/dist/lib/emulation/docker.d.ts.map +1 -1
- package/dist/lib/emulation/docker.js +80 -67
- package/dist/lib/emulation/docker.js.map +1 -1
- package/dist/lib/parser.d.ts.map +1 -1
- package/dist/lib/parser.js +11 -10
- package/dist/lib/parser.js.map +1 -1
- package/dist/lib/questions.d.ts.map +1 -1
- package/dist/lib/questions.js +20 -20
- package/dist/lib/questions.js.map +1 -1
- package/dist/lib/sdks.d.ts.map +1 -1
- package/dist/lib/sdks.js +10 -11
- package/dist/lib/sdks.js.map +1 -1
- package/dist/lib/types.d.ts +0 -214
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +42 -2
- package/dist/lib/utils.js.map +1 -1
- package/dist/package.json +12 -11
- package/docs/examples/account/create-anonymous-session.md +1 -0
- package/docs/examples/account/create-email-password-session.md +3 -0
- package/docs/examples/account/create-email-token.md +3 -0
- package/docs/examples/account/create-email-verification.md +2 -0
- package/docs/examples/account/create-jwt.md +1 -0
- package/docs/examples/account/create-magic-url-token.md +3 -0
- package/docs/examples/account/create-mfa-authenticator.md +2 -0
- package/docs/examples/account/create-mfa-challenge.md +2 -0
- package/docs/examples/account/create-mfa-recovery-codes.md +1 -0
- package/docs/examples/account/create-o-auth-2-session.md +2 -0
- package/docs/examples/account/create-o-auth-2-token.md +2 -0
- package/docs/examples/account/create-phone-token.md +3 -0
- package/docs/examples/account/create-phone-verification.md +1 -0
- package/docs/examples/account/create-push-target.md +3 -0
- package/docs/examples/account/create-recovery.md +3 -0
- package/docs/examples/account/create-session.md +3 -0
- package/docs/examples/account/create-verification.md +2 -0
- package/docs/examples/account/create.md +4 -0
- package/docs/examples/account/delete-identity.md +2 -0
- package/docs/examples/account/delete-mfa-authenticator.md +2 -0
- package/docs/examples/account/delete-push-target.md +2 -0
- package/docs/examples/account/delete-session.md +2 -0
- package/docs/examples/account/delete-sessions.md +1 -0
- package/docs/examples/account/delete.md +1 -0
- package/docs/examples/account/get-mfa-recovery-codes.md +1 -0
- package/docs/examples/account/get-prefs.md +1 -0
- package/docs/examples/account/get-session.md +2 -0
- package/docs/examples/account/get.md +1 -0
- package/docs/examples/account/list-identities.md +1 -0
- package/docs/examples/account/list-logs.md +1 -0
- package/docs/examples/account/list-mfa-factors.md +1 -0
- package/docs/examples/account/list-sessions.md +1 -0
- package/docs/examples/account/update-email-verification.md +3 -0
- package/docs/examples/account/update-email.md +3 -0
- package/docs/examples/account/update-magic-url-session.md +3 -0
- package/docs/examples/account/update-mfa-authenticator.md +3 -0
- package/docs/examples/account/update-mfa-challenge.md +3 -0
- package/docs/examples/account/update-mfa-recovery-codes.md +1 -0
- package/docs/examples/account/update-mfa.md +2 -0
- package/docs/examples/account/update-name.md +2 -0
- package/docs/examples/account/update-password.md +2 -0
- package/docs/examples/account/update-phone-session.md +3 -0
- package/docs/examples/account/update-phone-verification.md +3 -0
- package/docs/examples/account/update-phone.md +3 -0
- package/docs/examples/account/update-prefs.md +2 -0
- package/docs/examples/account/update-push-target.md +3 -0
- package/docs/examples/account/update-recovery.md +4 -0
- package/docs/examples/account/update-session.md +2 -0
- package/docs/examples/account/update-status.md +1 -0
- package/docs/examples/account/update-verification.md +3 -0
- package/docs/examples/console/get-resource.md +3 -0
- package/docs/examples/console/variables.md +1 -0
- package/docs/examples/databases/create-boolean-attribute.md +5 -0
- package/docs/examples/databases/create-collection.md +4 -0
- package/docs/examples/databases/create-datetime-attribute.md +5 -0
- package/docs/examples/databases/create-document.md +5 -0
- package/docs/examples/databases/create-documents.md +4 -0
- package/docs/examples/databases/create-email-attribute.md +5 -0
- package/docs/examples/databases/create-enum-attribute.md +6 -0
- package/docs/examples/databases/create-float-attribute.md +5 -0
- package/docs/examples/databases/create-index.md +6 -0
- package/docs/examples/databases/create-integer-attribute.md +5 -0
- package/docs/examples/databases/create-ip-attribute.md +5 -0
- package/docs/examples/databases/create-line-attribute.md +5 -0
- package/docs/examples/databases/create-operations.md +2 -0
- package/docs/examples/databases/create-point-attribute.md +5 -0
- package/docs/examples/databases/create-polygon-attribute.md +5 -0
- package/docs/examples/databases/create-relationship-attribute.md +5 -0
- package/docs/examples/databases/create-string-attribute.md +6 -0
- package/docs/examples/databases/create-transaction.md +1 -0
- package/docs/examples/databases/create-url-attribute.md +5 -0
- package/docs/examples/databases/create.md +3 -0
- package/docs/examples/databases/decrement-document-attribute.md +5 -0
- package/docs/examples/databases/delete-attribute.md +4 -0
- package/docs/examples/databases/delete-collection.md +3 -0
- package/docs/examples/databases/delete-document.md +4 -0
- package/docs/examples/databases/delete-documents.md +3 -0
- package/docs/examples/databases/delete-index.md +4 -0
- package/docs/examples/databases/delete-transaction.md +2 -0
- package/docs/examples/databases/delete.md +2 -0
- package/docs/examples/databases/get-attribute.md +4 -0
- package/docs/examples/databases/get-collection-usage.md +3 -0
- package/docs/examples/databases/get-collection.md +3 -0
- package/docs/examples/databases/get-document.md +4 -0
- package/docs/examples/databases/get-index.md +4 -0
- package/docs/examples/databases/get-transaction.md +2 -0
- package/docs/examples/databases/get-usage.md +2 -0
- package/docs/examples/databases/get.md +2 -0
- package/docs/examples/databases/increment-document-attribute.md +5 -0
- package/docs/examples/databases/list-attributes.md +3 -0
- package/docs/examples/databases/list-collection-logs.md +3 -0
- package/docs/examples/databases/list-collections.md +2 -0
- package/docs/examples/databases/list-document-logs.md +4 -0
- package/docs/examples/databases/list-documents.md +3 -0
- package/docs/examples/databases/list-indexes.md +3 -0
- package/docs/examples/databases/list-logs.md +2 -0
- package/docs/examples/databases/list-transactions.md +1 -0
- package/docs/examples/databases/list-usage.md +1 -0
- package/docs/examples/databases/list.md +1 -0
- package/docs/examples/databases/update-boolean-attribute.md +6 -0
- package/docs/examples/databases/update-collection.md +4 -0
- package/docs/examples/databases/update-datetime-attribute.md +6 -0
- package/docs/examples/databases/update-document.md +4 -0
- package/docs/examples/databases/update-documents.md +3 -0
- package/docs/examples/databases/update-email-attribute.md +6 -0
- package/docs/examples/databases/update-enum-attribute.md +7 -0
- package/docs/examples/databases/update-float-attribute.md +6 -0
- package/docs/examples/databases/update-integer-attribute.md +6 -0
- package/docs/examples/databases/update-ip-attribute.md +6 -0
- package/docs/examples/databases/update-line-attribute.md +5 -0
- package/docs/examples/databases/update-point-attribute.md +5 -0
- package/docs/examples/databases/update-polygon-attribute.md +5 -0
- package/docs/examples/databases/update-relationship-attribute.md +4 -0
- package/docs/examples/databases/update-string-attribute.md +6 -0
- package/docs/examples/databases/update-transaction.md +2 -0
- package/docs/examples/databases/update-url-attribute.md +6 -0
- package/docs/examples/databases/update.md +3 -0
- package/docs/examples/databases/upsert-document.md +4 -0
- package/docs/examples/databases/upsert-documents.md +4 -0
- package/docs/examples/functions/create-deployment.md +4 -0
- package/docs/examples/functions/create-duplicate-deployment.md +3 -0
- package/docs/examples/functions/create-execution.md +2 -0
- package/docs/examples/functions/create-template-deployment.md +7 -0
- package/docs/examples/functions/create-variable.md +4 -0
- package/docs/examples/functions/create-vcs-deployment.md +4 -0
- package/docs/examples/functions/create.md +4 -0
- package/docs/examples/functions/delete-deployment.md +3 -0
- package/docs/examples/functions/delete-execution.md +3 -0
- package/docs/examples/functions/delete-variable.md +3 -0
- package/docs/examples/functions/delete.md +2 -0
- package/docs/examples/functions/get-deployment-download.md +3 -0
- package/docs/examples/functions/get-deployment.md +3 -0
- package/docs/examples/functions/get-execution.md +3 -0
- package/docs/examples/functions/get-template.md +2 -0
- package/docs/examples/functions/get-usage.md +2 -0
- package/docs/examples/functions/get-variable.md +3 -0
- package/docs/examples/functions/get.md +2 -0
- package/docs/examples/functions/list-deployments.md +2 -0
- package/docs/examples/functions/list-executions.md +2 -0
- package/docs/examples/functions/list-runtimes.md +1 -0
- package/docs/examples/functions/list-specifications.md +1 -0
- package/docs/examples/functions/list-templates.md +1 -0
- package/docs/examples/functions/list-usage.md +1 -0
- package/docs/examples/functions/list-variables.md +2 -0
- package/docs/examples/functions/list.md +1 -0
- package/docs/examples/functions/update-deployment-status.md +3 -0
- package/docs/examples/functions/update-function-deployment.md +3 -0
- package/docs/examples/functions/update-variable.md +4 -0
- package/docs/examples/functions/update.md +3 -0
- package/docs/examples/graphql/mutation.md +2 -0
- package/docs/examples/graphql/query.md +2 -0
- package/docs/examples/health/get-antivirus.md +1 -0
- package/docs/examples/health/get-cache.md +1 -0
- package/docs/examples/health/get-certificate.md +1 -0
- package/docs/examples/health/get-db.md +1 -0
- package/docs/examples/health/get-failed-jobs.md +2 -0
- package/docs/examples/health/get-pub-sub.md +1 -0
- package/docs/examples/health/get-queue-builds.md +1 -0
- package/docs/examples/health/get-queue-certificates.md +1 -0
- package/docs/examples/health/get-queue-databases.md +1 -0
- package/docs/examples/health/get-queue-deletes.md +1 -0
- package/docs/examples/health/get-queue-functions.md +1 -0
- package/docs/examples/health/get-queue-logs.md +1 -0
- package/docs/examples/health/get-queue-mails.md +1 -0
- package/docs/examples/health/get-queue-messaging.md +1 -0
- package/docs/examples/health/get-queue-migrations.md +1 -0
- package/docs/examples/health/get-queue-stats-resources.md +1 -0
- package/docs/examples/health/get-queue-usage.md +1 -0
- package/docs/examples/health/get-queue-webhooks.md +1 -0
- package/docs/examples/health/get-storage-local.md +1 -0
- package/docs/examples/health/get-storage.md +1 -0
- package/docs/examples/health/get-time.md +1 -0
- package/docs/examples/health/get.md +1 -0
- package/docs/examples/locale/get.md +1 -0
- package/docs/examples/locale/list-codes.md +1 -0
- package/docs/examples/locale/list-continents.md +1 -0
- package/docs/examples/locale/list-countries-eu.md +1 -0
- package/docs/examples/locale/list-countries-phones.md +1 -0
- package/docs/examples/locale/list-countries.md +1 -0
- package/docs/examples/locale/list-currencies.md +1 -0
- package/docs/examples/locale/list-languages.md +1 -0
- package/docs/examples/messaging/create-apns-provider.md +3 -0
- package/docs/examples/messaging/create-email.md +4 -0
- package/docs/examples/messaging/create-fcm-provider.md +3 -0
- package/docs/examples/messaging/create-mailgun-provider.md +3 -0
- package/docs/examples/messaging/create-msg-91-provider.md +3 -0
- package/docs/examples/messaging/create-push.md +2 -0
- package/docs/examples/messaging/create-resend-provider.md +3 -0
- package/docs/examples/messaging/create-sendgrid-provider.md +3 -0
- package/docs/examples/messaging/create-sms.md +3 -0
- package/docs/examples/messaging/create-smtp-provider.md +4 -0
- package/docs/examples/messaging/create-subscriber.md +4 -0
- package/docs/examples/messaging/create-telesign-provider.md +3 -0
- package/docs/examples/messaging/create-textmagic-provider.md +3 -0
- package/docs/examples/messaging/create-topic.md +3 -0
- package/docs/examples/messaging/create-twilio-provider.md +3 -0
- package/docs/examples/messaging/create-vonage-provider.md +3 -0
- package/docs/examples/messaging/delete-provider.md +2 -0
- package/docs/examples/messaging/delete-subscriber.md +3 -0
- package/docs/examples/messaging/delete-topic.md +2 -0
- package/docs/examples/messaging/delete.md +2 -0
- package/docs/examples/messaging/get-message.md +2 -0
- package/docs/examples/messaging/get-provider.md +2 -0
- package/docs/examples/messaging/get-subscriber.md +3 -0
- package/docs/examples/messaging/get-topic.md +2 -0
- package/docs/examples/messaging/list-message-logs.md +2 -0
- package/docs/examples/messaging/list-messages.md +1 -0
- package/docs/examples/messaging/list-provider-logs.md +2 -0
- package/docs/examples/messaging/list-providers.md +1 -0
- package/docs/examples/messaging/list-subscriber-logs.md +2 -0
- package/docs/examples/messaging/list-subscribers.md +2 -0
- package/docs/examples/messaging/list-targets.md +2 -0
- package/docs/examples/messaging/list-topic-logs.md +2 -0
- package/docs/examples/messaging/list-topics.md +1 -0
- package/docs/examples/messaging/update-apns-provider.md +2 -0
- package/docs/examples/messaging/update-email.md +2 -0
- package/docs/examples/messaging/update-fcm-provider.md +2 -0
- package/docs/examples/messaging/update-mailgun-provider.md +2 -0
- package/docs/examples/messaging/update-msg-91-provider.md +2 -0
- package/docs/examples/messaging/update-push.md +2 -0
- package/docs/examples/messaging/update-resend-provider.md +2 -0
- package/docs/examples/messaging/update-sendgrid-provider.md +2 -0
- package/docs/examples/messaging/update-sms.md +2 -0
- package/docs/examples/messaging/update-smtp-provider.md +2 -0
- package/docs/examples/messaging/update-telesign-provider.md +2 -0
- package/docs/examples/messaging/update-textmagic-provider.md +2 -0
- package/docs/examples/messaging/update-topic.md +2 -0
- package/docs/examples/messaging/update-twilio-provider.md +2 -0
- package/docs/examples/messaging/update-vonage-provider.md +2 -0
- package/docs/examples/migrations/create-appwrite-migration.md +5 -0
- package/docs/examples/migrations/create-csv-export.md +3 -0
- package/docs/examples/migrations/create-csv-import.md +4 -0
- package/docs/examples/migrations/create-firebase-migration.md +3 -0
- package/docs/examples/migrations/create-n-host-migration.md +8 -0
- package/docs/examples/migrations/create-supabase-migration.md +7 -0
- package/docs/examples/migrations/delete.md +2 -0
- package/docs/examples/migrations/get-appwrite-report.md +5 -0
- package/docs/examples/migrations/get-firebase-report.md +3 -0
- package/docs/examples/migrations/get-n-host-report.md +8 -0
- package/docs/examples/migrations/get-supabase-report.md +7 -0
- package/docs/examples/migrations/get.md +2 -0
- package/docs/examples/migrations/list.md +1 -0
- package/docs/examples/migrations/retry.md +2 -0
- package/docs/examples/project/create-variable.md +3 -0
- package/docs/examples/project/delete-variable.md +2 -0
- package/docs/examples/project/get-usage.md +3 -0
- package/docs/examples/project/get-variable.md +2 -0
- package/docs/examples/project/list-variables.md +1 -0
- package/docs/examples/project/update-variable.md +3 -0
- package/docs/examples/projects/create-dev-key.md +4 -0
- package/docs/examples/projects/create-jwt.md +3 -0
- package/docs/examples/projects/create-key.md +4 -0
- package/docs/examples/projects/create-platform.md +4 -0
- package/docs/examples/projects/create-smtp-test.md +6 -0
- package/docs/examples/projects/create-webhook.md +6 -0
- package/docs/examples/projects/create.md +4 -0
- package/docs/examples/projects/delete-dev-key.md +3 -0
- package/docs/examples/projects/delete-email-template.md +4 -0
- package/docs/examples/projects/delete-key.md +3 -0
- package/docs/examples/projects/delete-platform.md +3 -0
- package/docs/examples/projects/delete-sms-template.md +4 -0
- package/docs/examples/projects/delete-webhook.md +3 -0
- package/docs/examples/projects/delete.md +2 -0
- package/docs/examples/projects/get-dev-key.md +3 -0
- package/docs/examples/projects/get-email-template.md +4 -0
- package/docs/examples/projects/get-key.md +3 -0
- package/docs/examples/projects/get-platform.md +3 -0
- package/docs/examples/projects/get-sms-template.md +4 -0
- package/docs/examples/projects/get-webhook.md +3 -0
- package/docs/examples/projects/get.md +2 -0
- package/docs/examples/projects/list-dev-keys.md +2 -0
- package/docs/examples/projects/list-keys.md +2 -0
- package/docs/examples/projects/list-platforms.md +2 -0
- package/docs/examples/projects/list-webhooks.md +2 -0
- package/docs/examples/projects/list.md +1 -0
- package/docs/examples/projects/update-api-status-all.md +3 -0
- package/docs/examples/projects/update-api-status.md +4 -0
- package/docs/examples/projects/update-auth-duration.md +3 -0
- package/docs/examples/projects/update-auth-limit.md +3 -0
- package/docs/examples/projects/update-auth-password-dictionary.md +3 -0
- package/docs/examples/projects/update-auth-password-history.md +3 -0
- package/docs/examples/projects/update-auth-sessions-limit.md +3 -0
- package/docs/examples/projects/update-auth-status.md +4 -0
- package/docs/examples/projects/update-dev-key.md +5 -0
- package/docs/examples/projects/update-email-template.md +6 -0
- package/docs/examples/projects/update-key.md +5 -0
- package/docs/examples/projects/update-memberships-privacy.md +5 -0
- package/docs/examples/projects/update-mock-numbers.md +3 -0
- package/docs/examples/projects/update-o-auth-2.md +3 -0
- package/docs/examples/projects/update-personal-data-check.md +3 -0
- package/docs/examples/projects/update-platform.md +4 -0
- package/docs/examples/projects/update-service-status-all.md +3 -0
- package/docs/examples/projects/update-service-status.md +4 -0
- package/docs/examples/projects/update-session-alerts.md +3 -0
- package/docs/examples/projects/update-session-invalidation.md +3 -0
- package/docs/examples/projects/update-sms-template.md +5 -0
- package/docs/examples/projects/update-smtp.md +3 -0
- package/docs/examples/projects/update-team.md +3 -0
- package/docs/examples/projects/update-webhook-signature.md +3 -0
- package/docs/examples/projects/update-webhook.md +7 -0
- package/docs/examples/projects/update.md +3 -0
- package/docs/examples/proxy/create-api-rule.md +2 -0
- package/docs/examples/proxy/create-function-rule.md +3 -0
- package/docs/examples/proxy/create-redirect-rule.md +6 -0
- package/docs/examples/proxy/create-site-rule.md +3 -0
- package/docs/examples/proxy/delete-rule.md +2 -0
- package/docs/examples/proxy/get-rule.md +2 -0
- package/docs/examples/proxy/list-rules.md +1 -0
- package/docs/examples/proxy/update-rule-verification.md +2 -0
- package/docs/examples/sites/create-deployment.md +4 -0
- package/docs/examples/sites/create-duplicate-deployment.md +3 -0
- package/docs/examples/sites/create-template-deployment.md +7 -0
- package/docs/examples/sites/create-variable.md +4 -0
- package/docs/examples/sites/create-vcs-deployment.md +4 -0
- package/docs/examples/sites/create.md +5 -0
- package/docs/examples/sites/delete-deployment.md +3 -0
- package/docs/examples/sites/delete-log.md +3 -0
- package/docs/examples/sites/delete-variable.md +3 -0
- package/docs/examples/sites/delete.md +2 -0
- package/docs/examples/sites/get-deployment-download.md +3 -0
- package/docs/examples/sites/get-deployment.md +3 -0
- package/docs/examples/sites/get-log.md +3 -0
- package/docs/examples/sites/get-template.md +2 -0
- package/docs/examples/sites/get-usage.md +2 -0
- package/docs/examples/sites/get-variable.md +3 -0
- package/docs/examples/sites/get.md +2 -0
- package/docs/examples/sites/list-deployments.md +2 -0
- package/docs/examples/sites/list-frameworks.md +1 -0
- package/docs/examples/sites/list-logs.md +2 -0
- package/docs/examples/sites/list-specifications.md +1 -0
- package/docs/examples/sites/list-templates.md +1 -0
- package/docs/examples/sites/list-usage.md +1 -0
- package/docs/examples/sites/list-variables.md +2 -0
- package/docs/examples/sites/list.md +1 -0
- package/docs/examples/sites/update-deployment-status.md +3 -0
- package/docs/examples/sites/update-site-deployment.md +3 -0
- package/docs/examples/sites/update-variable.md +4 -0
- package/docs/examples/sites/update.md +4 -0
- package/docs/examples/storage/create-bucket.md +3 -0
- package/docs/examples/storage/create-file.md +4 -0
- package/docs/examples/storage/delete-bucket.md +2 -0
- package/docs/examples/storage/delete-file.md +3 -0
- package/docs/examples/storage/get-bucket-usage.md +2 -0
- package/docs/examples/storage/get-bucket.md +2 -0
- package/docs/examples/storage/get-file-download.md +3 -0
- package/docs/examples/storage/get-file-preview.md +3 -0
- package/docs/examples/storage/get-file-view.md +3 -0
- package/docs/examples/storage/get-file.md +3 -0
- package/docs/examples/storage/get-usage.md +1 -0
- package/docs/examples/storage/list-buckets.md +1 -0
- package/docs/examples/storage/list-files.md +2 -0
- package/docs/examples/storage/update-bucket.md +3 -0
- package/docs/examples/storage/update-file.md +3 -0
- package/docs/examples/tablesdb/create-boolean-column.md +5 -0
- package/docs/examples/tablesdb/create-datetime-column.md +5 -0
- package/docs/examples/tablesdb/create-email-column.md +5 -0
- package/docs/examples/tablesdb/create-enum-column.md +6 -0
- package/docs/examples/tablesdb/create-float-column.md +5 -0
- package/docs/examples/tablesdb/create-index.md +6 -0
- package/docs/examples/tablesdb/create-integer-column.md +5 -0
- package/docs/examples/tablesdb/create-ip-column.md +5 -0
- package/docs/examples/tablesdb/create-line-column.md +5 -0
- package/docs/examples/tablesdb/create-operations.md +2 -0
- package/docs/examples/tablesdb/create-point-column.md +5 -0
- package/docs/examples/tablesdb/create-polygon-column.md +5 -0
- package/docs/examples/tablesdb/create-relationship-column.md +5 -0
- package/docs/examples/tablesdb/create-row.md +5 -0
- package/docs/examples/tablesdb/create-rows.md +4 -0
- package/docs/examples/tablesdb/create-string-column.md +6 -0
- package/docs/examples/tablesdb/create-table.md +4 -0
- package/docs/examples/tablesdb/create-transaction.md +1 -0
- package/docs/examples/tablesdb/create-url-column.md +5 -0
- package/docs/examples/tablesdb/create.md +3 -0
- package/docs/examples/tablesdb/decrement-row-column.md +5 -0
- package/docs/examples/tablesdb/delete-column.md +4 -0
- package/docs/examples/tablesdb/delete-index.md +4 -0
- package/docs/examples/tablesdb/delete-row.md +4 -0
- package/docs/examples/tablesdb/delete-rows.md +3 -0
- package/docs/examples/tablesdb/delete-table.md +3 -0
- package/docs/examples/tablesdb/delete-transaction.md +2 -0
- package/docs/examples/tablesdb/delete.md +2 -0
- package/docs/examples/tablesdb/get-column.md +4 -0
- package/docs/examples/tablesdb/get-index.md +4 -0
- package/docs/examples/tablesdb/get-row.md +4 -0
- package/docs/examples/tablesdb/get-table-usage.md +3 -0
- package/docs/examples/tablesdb/get-table.md +3 -0
- package/docs/examples/tablesdb/get-transaction.md +2 -0
- package/docs/examples/tablesdb/get-usage.md +2 -0
- package/docs/examples/tablesdb/get.md +2 -0
- package/docs/examples/tablesdb/increment-row-column.md +5 -0
- package/docs/examples/tablesdb/list-columns.md +3 -0
- package/docs/examples/tablesdb/list-indexes.md +3 -0
- package/docs/examples/tablesdb/list-row-logs.md +4 -0
- package/docs/examples/tablesdb/list-rows.md +3 -0
- package/docs/examples/tablesdb/list-table-logs.md +3 -0
- package/docs/examples/tablesdb/list-tables.md +2 -0
- package/docs/examples/tablesdb/list-transactions.md +1 -0
- package/docs/examples/tablesdb/list-usage.md +1 -0
- package/docs/examples/tablesdb/list.md +1 -0
- package/docs/examples/tablesdb/update-boolean-column.md +6 -0
- package/docs/examples/tablesdb/update-datetime-column.md +6 -0
- package/docs/examples/tablesdb/update-email-column.md +6 -0
- package/docs/examples/tablesdb/update-enum-column.md +7 -0
- package/docs/examples/tablesdb/update-float-column.md +6 -0
- package/docs/examples/tablesdb/update-integer-column.md +6 -0
- package/docs/examples/tablesdb/update-ip-column.md +6 -0
- package/docs/examples/tablesdb/update-line-column.md +5 -0
- package/docs/examples/tablesdb/update-point-column.md +5 -0
- package/docs/examples/tablesdb/update-polygon-column.md +5 -0
- package/docs/examples/tablesdb/update-relationship-column.md +4 -0
- package/docs/examples/tablesdb/update-row.md +4 -0
- package/docs/examples/tablesdb/update-rows.md +3 -0
- package/docs/examples/tablesdb/update-string-column.md +6 -0
- package/docs/examples/tablesdb/update-table.md +4 -0
- package/docs/examples/tablesdb/update-transaction.md +2 -0
- package/docs/examples/tablesdb/update-url-column.md +6 -0
- package/docs/examples/tablesdb/update.md +3 -0
- package/docs/examples/tablesdb/upsert-row.md +4 -0
- package/docs/examples/tablesdb/upsert-rows.md +4 -0
- package/docs/examples/teams/create-membership.md +3 -0
- package/docs/examples/teams/create.md +3 -0
- package/docs/examples/teams/delete-membership.md +3 -0
- package/docs/examples/teams/delete.md +2 -0
- package/docs/examples/teams/get-membership.md +3 -0
- package/docs/examples/teams/get-prefs.md +2 -0
- package/docs/examples/teams/get.md +2 -0
- package/docs/examples/teams/list-logs.md +2 -0
- package/docs/examples/teams/list-memberships.md +2 -0
- package/docs/examples/teams/list.md +1 -0
- package/docs/examples/teams/update-membership-status.md +5 -0
- package/docs/examples/teams/update-membership.md +4 -0
- package/docs/examples/teams/update-name.md +3 -0
- package/docs/examples/teams/update-prefs.md +3 -0
- package/docs/examples/tokens/create-file-token.md +3 -0
- package/docs/examples/tokens/delete.md +2 -0
- package/docs/examples/tokens/get.md +2 -0
- package/docs/examples/tokens/list.md +3 -0
- package/docs/examples/tokens/update.md +2 -0
- package/docs/examples/users/create-argon-2-user.md +4 -0
- package/docs/examples/users/create-bcrypt-user.md +4 -0
- package/docs/examples/users/create-jwt.md +2 -0
- package/docs/examples/users/create-md-5-user.md +4 -0
- package/docs/examples/users/create-mfa-recovery-codes.md +2 -0
- package/docs/examples/users/create-ph-pass-user.md +4 -0
- package/docs/examples/users/create-scrypt-modified-user.md +7 -0
- package/docs/examples/users/create-scrypt-user.md +9 -0
- package/docs/examples/users/create-session.md +2 -0
- package/docs/examples/users/create-sha-user.md +4 -0
- package/docs/examples/users/create-target.md +5 -0
- package/docs/examples/users/create-token.md +2 -0
- package/docs/examples/users/create.md +2 -0
- package/docs/examples/users/delete-identity.md +2 -0
- package/docs/examples/users/delete-mfa-authenticator.md +3 -0
- package/docs/examples/users/delete-session.md +3 -0
- package/docs/examples/users/delete-sessions.md +2 -0
- package/docs/examples/users/delete-target.md +3 -0
- package/docs/examples/users/delete.md +2 -0
- package/docs/examples/users/get-mfa-recovery-codes.md +2 -0
- package/docs/examples/users/get-prefs.md +2 -0
- package/docs/examples/users/get-target.md +3 -0
- package/docs/examples/users/get-usage.md +1 -0
- package/docs/examples/users/get.md +2 -0
- package/docs/examples/users/list-identities.md +1 -0
- package/docs/examples/users/list-logs.md +2 -0
- package/docs/examples/users/list-memberships.md +2 -0
- package/docs/examples/users/list-mfa-factors.md +2 -0
- package/docs/examples/users/list-sessions.md +2 -0
- package/docs/examples/users/list-targets.md +2 -0
- package/docs/examples/users/list.md +1 -0
- package/docs/examples/users/update-email-verification.md +3 -0
- package/docs/examples/users/update-email.md +3 -0
- package/docs/examples/users/update-labels.md +3 -0
- package/docs/examples/users/update-mfa-recovery-codes.md +2 -0
- package/docs/examples/users/update-mfa.md +3 -0
- package/docs/examples/users/update-name.md +3 -0
- package/docs/examples/users/update-password.md +3 -0
- package/docs/examples/users/update-phone-verification.md +3 -0
- package/docs/examples/users/update-phone.md +3 -0
- package/docs/examples/users/update-prefs.md +3 -0
- package/docs/examples/users/update-status.md +3 -0
- package/docs/examples/users/update-target.md +3 -0
- package/docs/examples/vcs/create-repository-detection.md +4 -0
- package/docs/examples/vcs/create-repository.md +4 -0
- package/docs/examples/vcs/delete-installation.md +2 -0
- package/docs/examples/vcs/get-installation.md +2 -0
- package/docs/examples/vcs/get-repository-contents.md +3 -0
- package/docs/examples/vcs/get-repository.md +3 -0
- package/docs/examples/vcs/list-installations.md +1 -0
- package/docs/examples/vcs/list-repositories.md +3 -0
- package/docs/examples/vcs/list-repository-branches.md +3 -0
- package/docs/examples/vcs/update-external-deployments.md +4 -0
- package/index.ts +25 -165
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.ts +14 -6
- package/lib/commands/config.ts +494 -0
- package/lib/commands/db.ts +324 -0
- package/lib/commands/errors.ts +93 -0
- package/lib/commands/init.ts +25 -14
- package/lib/commands/pull.ts +683 -420
- package/lib/commands/push.ts +1677 -2404
- package/lib/commands/run.ts +1 -1
- package/lib/commands/schema.ts +122 -0
- package/lib/commands/services/account.ts +200 -385
- package/lib/commands/services/console.ts +13 -34
- package/lib/commands/services/databases.ts +298 -1215
- package/lib/commands/services/functions.ts +115 -434
- package/lib/commands/services/graphql.ts +5 -2
- package/lib/commands/services/health.ts +87 -149
- package/lib/commands/services/locale.ts +36 -33
- package/lib/commands/services/messaging.ts +180 -999
- package/lib/commands/services/migrations.ts +54 -226
- package/lib/commands/services/project.ts +19 -23
- package/lib/commands/services/projects.ts +182 -714
- package/lib/commands/services/proxy.ts +30 -58
- package/lib/commands/services/sites.ts +107 -379
- package/lib/commands/services/storage.ts +93 -302
- package/lib/commands/services/tables-db.ts +1150 -0
- package/lib/commands/services/teams.ts +48 -110
- package/lib/commands/services/tokens.ts +16 -28
- package/lib/commands/services/users.ts +133 -403
- package/lib/commands/services/vcs.ts +48 -151
- package/lib/commands/types.ts +1 -1
- package/lib/commands/update.ts +13 -22
- 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 +46 -82
- package/lib/constants.ts +22 -0
- package/lib/emulation/docker.ts +101 -87
- package/lib/parser.ts +16 -11
- package/lib/questions.ts +20 -21
- package/lib/sdks.ts +15 -11
- package/lib/types.ts +0 -229
- package/lib/utils.ts +45 -4
- package/package.json +12 -11
- package/scoop/appwrite.config.json +29 -19
- package/.github/workflows/build-verify.yml +0 -71
- package/bun.lock +0 -625
- package/dist/lib/commands/services/avatars.d.ts +0 -3
- package/dist/lib/commands/services/avatars.d.ts.map +0 -1
- package/dist/lib/commands/services/avatars.js +0 -118
- package/dist/lib/commands/services/avatars.js.map +0 -1
- package/dist/lib/commands/services/tablesdb.d.ts +0 -3
- package/dist/lib/commands/services/tablesdb.d.ts.map +0 -1
- package/dist/lib/commands/services/tablesdb.js.map +0 -1
- package/dist/scripts/generate-commands.d.ts +0 -2
- package/dist/scripts/generate-commands.d.ts.map +0 -1
- package/dist/scripts/generate-commands.js +0 -398
- package/dist/scripts/generate-commands.js.map +0 -1
- package/lib/commands/services/avatars.ts +0 -400
- package/lib/commands/services/tablesdb.ts +0 -1928
- package/scripts/generate-commands.ts +0 -539
|
@@ -4,790 +4,1195 @@ import chalk from "chalk";
|
|
|
4
4
|
import inquirer from "inquirer";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import ID from "../id.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
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";
|
|
9
11
|
import { paginate } from "../paginate.js";
|
|
10
|
-
import {
|
|
12
|
+
import { pushDeployment } from "./utils/deployment.js";
|
|
13
|
+
import { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionsPushTables, questionsPushMessagingTopics, questionsPushResources, } from "../questions.js";
|
|
11
14
|
import { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable, } from "../parser.js";
|
|
12
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";
|
|
13
18
|
import { checkDeployConditions } from "../utils.js";
|
|
14
|
-
|
|
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";
|
|
15
23
|
const POLL_DEBOUNCE = 2000; // Milliseconds
|
|
16
24
|
const POLL_DEFAULT_VALUE = 30;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 };
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
allErrors.push(e);
|
|
87
|
+
results.settings = { success: false, error: e.message };
|
|
88
|
+
}
|
|
38
89
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
allErrors.push(e);
|
|
103
|
+
results.buckets = { successfullyPushed: 0, errors: [e] };
|
|
46
104
|
}
|
|
47
105
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
allErrors.push(e);
|
|
119
|
+
results.teams = { successfullyPushed: 0, errors: [e] };
|
|
120
|
+
}
|
|
54
121
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
allErrors.push(e);
|
|
135
|
+
results.topics = { successfullyPushed: 0, errors: [e] };
|
|
136
|
+
}
|
|
60
137
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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);
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
allErrors.push(e);
|
|
151
|
+
results.functions = {
|
|
152
|
+
successfullyPushed: 0,
|
|
153
|
+
successfullyDeployed: 0,
|
|
154
|
+
failedDeployments: [],
|
|
155
|
+
errors: [e],
|
|
156
|
+
};
|
|
68
157
|
}
|
|
69
158
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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);
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
allErrors.push(e);
|
|
172
|
+
results.sites = {
|
|
173
|
+
successfullyPushed: 0,
|
|
174
|
+
successfullyDeployed: 0,
|
|
175
|
+
failedDeployments: [],
|
|
176
|
+
errors: [e],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
76
179
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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);
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
allErrors.push(e);
|
|
196
|
+
results.tables = { successfullyPushed: 0, errors: [e] };
|
|
84
197
|
}
|
|
85
198
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
allErrors.push(e);
|
|
222
|
+
results.collections = { successfullyPushed: 0, errors: [e] };
|
|
223
|
+
}
|
|
96
224
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
225
|
+
return {
|
|
226
|
+
results,
|
|
227
|
+
errors: allErrors,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
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 ?? {};
|
|
235
|
+
if (projectName) {
|
|
236
|
+
this.log("Applying project name ...");
|
|
237
|
+
await projectsService.update({
|
|
238
|
+
projectId: projectId,
|
|
239
|
+
name: projectName,
|
|
240
|
+
});
|
|
103
241
|
}
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
242
|
+
if (settings.services) {
|
|
243
|
+
this.log("Applying service statuses ...");
|
|
244
|
+
for (let [service, status] of Object.entries(settings.services)) {
|
|
245
|
+
await projectsService.updateServiceStatus({
|
|
246
|
+
projectId: projectId,
|
|
247
|
+
service: service,
|
|
248
|
+
status: status,
|
|
249
|
+
});
|
|
111
250
|
}
|
|
112
251
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
252
|
+
if (settings.auth) {
|
|
253
|
+
if (settings.auth.security) {
|
|
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
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (settings.auth.methods) {
|
|
289
|
+
this.log("Applying auth methods statuses ...");
|
|
290
|
+
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
291
|
+
await projectsService.updateAuthStatus({
|
|
292
|
+
projectId,
|
|
293
|
+
method: method,
|
|
294
|
+
status: status,
|
|
295
|
+
});
|
|
125
296
|
}
|
|
126
|
-
return attribute.status === "available";
|
|
127
297
|
}
|
|
128
|
-
return false;
|
|
129
|
-
})
|
|
130
|
-
.map((attribute) => attribute.key);
|
|
131
|
-
if (ready.length === attributeKeys.length) {
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE));
|
|
135
|
-
return await awaitPools.expectAttributes(databaseId, collectionId, attributeKeys, iteration + 1);
|
|
136
|
-
},
|
|
137
|
-
deleteIndexes: async (databaseId, collectionId, indexesKeys, iteration = 1) => {
|
|
138
|
-
if (iteration > pollMaxDebounces) {
|
|
139
|
-
return false;
|
|
140
298
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
299
|
+
}
|
|
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++;
|
|
148
342
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return await databasesService.listIndexes(args.databaseId, args.collectionId, args.queries || []);
|
|
153
|
-
}, {
|
|
154
|
-
databaseId,
|
|
155
|
-
collectionId,
|
|
156
|
-
}, 100, "indexes");
|
|
157
|
-
const ready = indexesKeys.filter((index) => indexes.includes(index.key));
|
|
158
|
-
if (ready.length === 0) {
|
|
159
|
-
return true;
|
|
160
|
-
}
|
|
161
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE));
|
|
162
|
-
return await awaitPools.expectIndexes(databaseId, collectionId, indexesKeys, iteration + 1);
|
|
163
|
-
},
|
|
164
|
-
expectIndexes: async (databaseId, collectionId, indexKeys, iteration = 1) => {
|
|
165
|
-
if (iteration > pollMaxDebounces) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
|
|
169
|
-
let steps = Math.max(1, Math.ceil(indexKeys.length / STEP_SIZE));
|
|
170
|
-
if (steps > 1 && iteration === 1) {
|
|
171
|
-
pollMaxDebounces *= steps;
|
|
172
|
-
log("Creating a large number of indexes, increasing timeout to " +
|
|
173
|
-
(pollMaxDebounces * POLL_DEBOUNCE) / 1000 / 60 +
|
|
174
|
-
" minutes");
|
|
343
|
+
catch (e) {
|
|
344
|
+
errors.push(e);
|
|
345
|
+
this.error(`Failed to push bucket ${bucket["name"]}: ${e.message}`);
|
|
175
346
|
}
|
|
176
347
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
348
|
+
return {
|
|
349
|
+
successfullyPushed,
|
|
350
|
+
errors,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
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
|
+
}
|
|
189
377
|
}
|
|
190
|
-
|
|
378
|
+
successfullyPushed++;
|
|
379
|
+
}
|
|
380
|
+
catch (e) {
|
|
381
|
+
errors.push(e);
|
|
382
|
+
this.error(`Failed to push team ${team["name"]}: ${e.message}`);
|
|
191
383
|
}
|
|
192
|
-
return false;
|
|
193
|
-
})
|
|
194
|
-
.map((index) => index.key);
|
|
195
|
-
if (ready.length >= indexKeys.length) {
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE));
|
|
199
|
-
return await awaitPools.expectIndexes(databaseId, collectionId, indexKeys, iteration + 1);
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
const getConfirmation = async () => {
|
|
203
|
-
if (cliConfig.force) {
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
async function fixConfirmation() {
|
|
207
|
-
const answers = await inquirer.prompt(questionPushChangesConfirmation);
|
|
208
|
-
if (answers.changes !== "YES" && answers.changes !== "NO") {
|
|
209
|
-
return await fixConfirmation();
|
|
210
384
|
}
|
|
211
|
-
return
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
answers.changes = await fixConfirmation();
|
|
216
|
-
}
|
|
217
|
-
if (answers.changes === "YES") {
|
|
218
|
-
return true;
|
|
385
|
+
return {
|
|
386
|
+
successfullyPushed,
|
|
387
|
+
errors,
|
|
388
|
+
};
|
|
219
389
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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++;
|
|
237
419
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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}`,
|
|
447
|
+
});
|
|
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;
|
|
242
458
|
}
|
|
243
|
-
|
|
244
|
-
|
|
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;
|
|
245
481
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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;
|
|
254
527
|
}
|
|
528
|
+
updaterRow.update({ status: "Created" });
|
|
255
529
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
remote: chalk.red(value),
|
|
261
|
-
local: chalk.green(localResource[key]),
|
|
530
|
+
catch (e) {
|
|
531
|
+
errors.push(e);
|
|
532
|
+
updaterRow.fail({
|
|
533
|
+
errorMessage: e.message ?? "General error occurs please try again",
|
|
262
534
|
});
|
|
535
|
+
return;
|
|
263
536
|
}
|
|
264
537
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
+
}));
|
|
269
577
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if ((await getConfirmation()) === true) {
|
|
277
|
-
return true;
|
|
278
|
-
}
|
|
279
|
-
success(`Successfully pushed 0 ${resourcePlural}.`);
|
|
280
|
-
return false;
|
|
281
|
-
};
|
|
282
|
-
const getObjectChanges = (remote, local, index, what) => {
|
|
283
|
-
const changes = [];
|
|
284
|
-
const remoteNested = remote[index];
|
|
285
|
-
const localNested = local[index];
|
|
286
|
-
if (remoteNested &&
|
|
287
|
-
localNested &&
|
|
288
|
-
typeof remoteNested === "object" &&
|
|
289
|
-
!Array.isArray(remoteNested) &&
|
|
290
|
-
typeof localNested === "object" &&
|
|
291
|
-
!Array.isArray(localNested)) {
|
|
292
|
-
const remoteObj = remoteNested;
|
|
293
|
-
const localObj = localNested;
|
|
294
|
-
for (const [service, status] of Object.entries(remoteObj)) {
|
|
295
|
-
const localValue = localObj[service];
|
|
296
|
-
let valuesEqual = false;
|
|
297
|
-
if (Array.isArray(status) && Array.isArray(localValue)) {
|
|
298
|
-
valuesEqual = JSON.stringify(status) === JSON.stringify(localValue);
|
|
578
|
+
if (code === false) {
|
|
579
|
+
successfullyPushed++;
|
|
580
|
+
successfullyDeployed++;
|
|
581
|
+
updaterRow.update({ status: "Pushed" });
|
|
582
|
+
updaterRow.stopSpinner();
|
|
583
|
+
return;
|
|
299
584
|
}
|
|
300
|
-
|
|
301
|
-
|
|
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++;
|
|
605
|
+
}
|
|
606
|
+
catch (e) {
|
|
607
|
+
errors.push(e);
|
|
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
|
+
}
|
|
302
619
|
}
|
|
303
|
-
if (!
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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);
|
|
719
|
+
try {
|
|
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"],
|
|
733
|
+
name: site.name,
|
|
734
|
+
framework: site.framework,
|
|
735
|
+
enabled: site.enabled,
|
|
736
|
+
logging: site.logging,
|
|
737
|
+
timeout: site.timeout,
|
|
738
|
+
installCommand: site.installCommand,
|
|
739
|
+
buildCommand: site.buildCommand,
|
|
740
|
+
outputDirectory: site.outputDirectory,
|
|
741
|
+
buildRuntime: site.buildRuntime,
|
|
742
|
+
adapter: site.adapter,
|
|
743
|
+
specification: site.specification,
|
|
309
744
|
});
|
|
310
745
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
switch (attribute.format) {
|
|
320
|
-
case "email":
|
|
321
|
-
return databasesService.createEmailAttribute({
|
|
322
|
-
databaseId,
|
|
323
|
-
collectionId,
|
|
324
|
-
key: attribute.key,
|
|
325
|
-
required: attribute.required,
|
|
326
|
-
xdefault: attribute.default,
|
|
327
|
-
array: attribute.array,
|
|
746
|
+
catch (e) {
|
|
747
|
+
if (Number(e.code) === 404) {
|
|
748
|
+
siteExists = false;
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
errors.push(e);
|
|
752
|
+
updaterRow.fail({
|
|
753
|
+
errorMessage: e.message ?? "General error occurs please try again",
|
|
328
754
|
});
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
if (!siteExists) {
|
|
759
|
+
updaterRow
|
|
760
|
+
.update({ status: "Creating" })
|
|
761
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
762
|
+
try {
|
|
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,
|
|
337
776
|
});
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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",
|
|
346
801
|
});
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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,
|
|
356
813
|
});
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
array: attribute.array,
|
|
366
|
-
encrypt: attribute.encrypt,
|
|
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"],
|
|
367
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
|
+
}
|
|
831
|
+
}
|
|
832
|
+
catch (error) {
|
|
833
|
+
envVariables = [];
|
|
834
|
+
}
|
|
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
|
+
}));
|
|
368
844
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
onDelete: attribute.onDelete,
|
|
419
|
-
});
|
|
420
|
-
case "point":
|
|
421
|
-
return databasesService.createPointAttribute({
|
|
422
|
-
databaseId,
|
|
423
|
-
collectionId,
|
|
424
|
-
key: attribute.key,
|
|
425
|
-
required: attribute.required,
|
|
426
|
-
xdefault: attribute.default,
|
|
427
|
-
});
|
|
428
|
-
case "linestring":
|
|
429
|
-
return databasesService.createLineAttribute({
|
|
430
|
-
databaseId,
|
|
431
|
-
collectionId,
|
|
432
|
-
key: attribute.key,
|
|
433
|
-
required: attribute.required,
|
|
434
|
-
xdefault: attribute.default,
|
|
435
|
-
});
|
|
436
|
-
case "polygon":
|
|
437
|
-
return databasesService.createPolygonAttribute({
|
|
438
|
-
databaseId,
|
|
439
|
-
collectionId,
|
|
440
|
-
key: attribute.key,
|
|
441
|
-
required: attribute.required,
|
|
442
|
-
xdefault: attribute.default,
|
|
443
|
-
});
|
|
444
|
-
default:
|
|
445
|
-
throw new Error(`Unsupported attribute type: ${attribute.type}`);
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
const updateAttribute = async (databaseId, collectionId, attribute) => {
|
|
449
|
-
const databasesService = await getDatabasesService();
|
|
450
|
-
switch (attribute.type) {
|
|
451
|
-
case "string":
|
|
452
|
-
switch (attribute.format) {
|
|
453
|
-
case "email":
|
|
454
|
-
return databasesService.updateEmailAttribute({
|
|
455
|
-
databaseId,
|
|
456
|
-
collectionId,
|
|
457
|
-
key: attribute.key,
|
|
458
|
-
required: attribute.required,
|
|
459
|
-
xdefault: attribute.default,
|
|
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++;
|
|
873
|
+
}
|
|
874
|
+
catch (e) {
|
|
875
|
+
errors.push(e);
|
|
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
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (deploymentCreated && !asyncDeploy) {
|
|
889
|
+
try {
|
|
890
|
+
const deploymentId = response["$id"];
|
|
891
|
+
updaterRow.update({
|
|
892
|
+
status: "Deploying",
|
|
893
|
+
end: "Checking deployment status...",
|
|
460
894
|
});
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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",
|
|
468
954
|
});
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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"],
|
|
981
|
+
});
|
|
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"],
|
|
476
999
|
});
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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,
|
|
485
1018
|
});
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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) => {
|
|
1099
|
+
try {
|
|
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`);
|
|
1105
|
+
}
|
|
1106
|
+
collection.remoteVersion = remoteCollection;
|
|
1107
|
+
collection.isExisted = true;
|
|
1108
|
+
}
|
|
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"],
|
|
493
1119
|
});
|
|
1120
|
+
}
|
|
1121
|
+
else {
|
|
1122
|
+
errors.push(e);
|
|
1123
|
+
throw e;
|
|
1124
|
+
}
|
|
494
1125
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
required: attribute.required,
|
|
511
|
-
min: attribute.min,
|
|
512
|
-
max: attribute.max,
|
|
513
|
-
xdefault: attribute.default,
|
|
514
|
-
});
|
|
515
|
-
case "boolean":
|
|
516
|
-
return databasesService.updateBooleanAttribute({
|
|
517
|
-
databaseId,
|
|
518
|
-
collectionId,
|
|
519
|
-
key: attribute.key,
|
|
520
|
-
required: attribute.required,
|
|
521
|
-
xdefault: attribute.default,
|
|
522
|
-
});
|
|
523
|
-
case "datetime":
|
|
524
|
-
return databasesService.updateDatetimeAttribute({
|
|
525
|
-
databaseId,
|
|
526
|
-
collectionId,
|
|
527
|
-
key: attribute.key,
|
|
528
|
-
required: attribute.required,
|
|
529
|
-
xdefault: attribute.default,
|
|
530
|
-
});
|
|
531
|
-
case "relationship":
|
|
532
|
-
return databasesService.updateRelationshipAttribute({
|
|
533
|
-
databaseId,
|
|
534
|
-
collectionId,
|
|
535
|
-
key: attribute.key,
|
|
536
|
-
onDelete: attribute.onDelete,
|
|
537
|
-
});
|
|
538
|
-
case "point":
|
|
539
|
-
return databasesService.updatePointAttribute({
|
|
540
|
-
databaseId,
|
|
541
|
-
collectionId,
|
|
542
|
-
key: attribute.key,
|
|
543
|
-
required: attribute.required,
|
|
544
|
-
xdefault: attribute.default,
|
|
545
|
-
});
|
|
546
|
-
case "linestring":
|
|
547
|
-
return databasesService.updateLineAttribute({
|
|
548
|
-
databaseId,
|
|
549
|
-
collectionId,
|
|
550
|
-
key: attribute.key,
|
|
551
|
-
required: attribute.required,
|
|
552
|
-
xdefault: attribute.default,
|
|
553
|
-
});
|
|
554
|
-
case "polygon":
|
|
555
|
-
return databasesService.updatePolygonAttribute({
|
|
556
|
-
databaseId,
|
|
557
|
-
collectionId,
|
|
558
|
-
key: attribute.key,
|
|
559
|
-
required: attribute.required,
|
|
560
|
-
xdefault: attribute.default,
|
|
561
|
-
});
|
|
562
|
-
default:
|
|
563
|
-
throw new Error(`Unsupported attribute type: ${attribute.type}`);
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
const deleteAttribute = async (collection, attribute, isIndex = false) => {
|
|
567
|
-
log(`Deleting ${isIndex ? "index" : "attribute"} ${attribute.key} of ${collection.name} ( ${collection["$id"]} )`);
|
|
568
|
-
const databasesService = await getDatabasesService();
|
|
569
|
-
if (isIndex) {
|
|
570
|
-
await databasesService.deleteIndex(collection["databaseId"], collection["$id"], attribute.key);
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
await databasesService.deleteAttribute(collection["databaseId"], collection["$id"], attribute.key);
|
|
574
|
-
};
|
|
575
|
-
const isEqual = (a, b) => {
|
|
576
|
-
if (a === b)
|
|
577
|
-
return true;
|
|
578
|
-
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
579
|
-
if (a.constructor &&
|
|
580
|
-
a.constructor.name === "BigNumber" &&
|
|
581
|
-
b.constructor &&
|
|
582
|
-
b.constructor.name === "BigNumber") {
|
|
583
|
-
return a.eq(b);
|
|
584
|
-
}
|
|
585
|
-
if (typeof a.equals === "function") {
|
|
586
|
-
return a.equals(b);
|
|
587
|
-
}
|
|
588
|
-
if (typeof a.eq === "function") {
|
|
589
|
-
return a.eq(b);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
if (typeof a === "number" && typeof b === "number") {
|
|
593
|
-
if (isNaN(a) && isNaN(b))
|
|
594
|
-
return true;
|
|
595
|
-
if (!isFinite(a) && !isFinite(b))
|
|
596
|
-
return a === b;
|
|
597
|
-
return Math.abs(a - b) < Number.EPSILON;
|
|
598
|
-
}
|
|
599
|
-
return false;
|
|
600
|
-
};
|
|
601
|
-
const compareAttribute = (remote, local, reason, key) => {
|
|
602
|
-
if (isEmpty(remote) && isEmpty(local)) {
|
|
603
|
-
return reason;
|
|
604
|
-
}
|
|
605
|
-
if (Array.isArray(remote) && Array.isArray(local)) {
|
|
606
|
-
if (JSON.stringify(remote) !== JSON.stringify(local)) {
|
|
607
|
-
const bol = reason === "" ? "" : "\n";
|
|
608
|
-
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
else if (!isEqual(remote, local)) {
|
|
612
|
-
const bol = reason === "" ? "" : "\n";
|
|
613
|
-
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
614
|
-
}
|
|
615
|
-
return reason;
|
|
616
|
-
};
|
|
617
|
-
/**
|
|
618
|
-
* Check if attribute non-changeable fields has been changed
|
|
619
|
-
* If so return the differences as an object.
|
|
620
|
-
*/
|
|
621
|
-
const checkAttributeChanges = (remote, local, collection, recreating = true) => {
|
|
622
|
-
if (local === undefined) {
|
|
623
|
-
return undefined;
|
|
624
|
-
}
|
|
625
|
-
const keyName = `${chalk.yellow(local.key)} in ${collection.name} (${collection["$id"]})`;
|
|
626
|
-
const action = chalk.cyan(recreating ? "recreating" : "changing");
|
|
627
|
-
let reason = "";
|
|
628
|
-
let attribute = recreating ? remote : local;
|
|
629
|
-
for (let key of Object.keys(remote)) {
|
|
630
|
-
if (!KeysAttributes.has(key)) {
|
|
631
|
-
continue;
|
|
632
|
-
}
|
|
633
|
-
if (changeableKeys.includes(key)) {
|
|
634
|
-
if (!recreating) {
|
|
635
|
-
reason = compareAttribute(remote[key], local[key], reason, key);
|
|
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
|
+
}
|
|
636
1141
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const attributesToCreate = async (remoteAttributes, localAttributes, collection, isIndex = false) => {
|
|
667
|
-
const deleting = remoteAttributes
|
|
668
|
-
.filter((attribute) => !attributesContains(attribute, localAttributes))
|
|
669
|
-
.map((attr) => generateChangesObject(attr, collection, false));
|
|
670
|
-
const adding = localAttributes
|
|
671
|
-
.filter((attribute) => !attributesContains(attribute, remoteAttributes))
|
|
672
|
-
.map((attr) => generateChangesObject(attr, collection, true));
|
|
673
|
-
const conflicts = remoteAttributes
|
|
674
|
-
.map((attribute) => checkAttributeChanges(attribute, attributesContains(attribute, localAttributes), collection))
|
|
675
|
-
.filter((attribute) => attribute !== undefined);
|
|
676
|
-
const changes = remoteAttributes
|
|
677
|
-
.map((attribute) => checkAttributeChanges(attribute, attributesContains(attribute, localAttributes), collection, false))
|
|
678
|
-
.filter((attribute) => attribute !== undefined)
|
|
679
|
-
.filter((attribute) => conflicts.filter((attr) => attribute.key === attr.key).length !== 1);
|
|
680
|
-
let changedAttributes = [];
|
|
681
|
-
const changing = [...deleting, ...adding, ...conflicts, ...changes];
|
|
682
|
-
if (changing.length === 0) {
|
|
683
|
-
return changedAttributes;
|
|
684
|
-
}
|
|
685
|
-
log(!cliConfig.force
|
|
686
|
-
? "There are pending changes in your collection deployment"
|
|
687
|
-
: "List of applied changes");
|
|
688
|
-
drawTable(changing.map((change) => {
|
|
689
|
-
return { Key: change.key, Action: change.action, Reason: change.reason };
|
|
690
|
-
}));
|
|
691
|
-
if (!cliConfig.force) {
|
|
692
|
-
if (deleting.length > 0 && !isIndex) {
|
|
693
|
-
console.log(`${chalk.red("------------------------------------------------------")}`);
|
|
694
|
-
console.log(`${chalk.red("| WARNING: Attribute deletion may cause loss of data |")}`);
|
|
695
|
-
console.log(`${chalk.red("------------------------------------------------------")}`);
|
|
696
|
-
console.log();
|
|
697
|
-
}
|
|
698
|
-
if (conflicts.length > 0 && !isIndex) {
|
|
699
|
-
console.log(`${chalk.red("--------------------------------------------------------")}`);
|
|
700
|
-
console.log(`${chalk.red("| WARNING: Attribute recreation may cause loss of data |")}`);
|
|
701
|
-
console.log(`${chalk.red("--------------------------------------------------------")}`);
|
|
702
|
-
console.log();
|
|
703
|
-
}
|
|
704
|
-
if ((await getConfirmation()) !== true) {
|
|
705
|
-
return changedAttributes;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
if (conflicts.length > 0) {
|
|
709
|
-
changedAttributes = conflicts.map((change) => change.attribute);
|
|
710
|
-
await Promise.all(changedAttributes.map((changed) => deleteAttribute(collection, changed, isIndex)));
|
|
711
|
-
remoteAttributes = remoteAttributes.filter((attribute) => !attributesContains(attribute, changedAttributes));
|
|
712
|
-
}
|
|
713
|
-
if (changes.length > 0) {
|
|
714
|
-
changedAttributes = changes.map((change) => change.attribute);
|
|
715
|
-
await Promise.all(changedAttributes.map((changed) => updateAttribute(collection["databaseId"], collection["$id"], changed)));
|
|
716
|
-
}
|
|
717
|
-
const deletingAttributes = deleting.map((change) => change.attribute);
|
|
718
|
-
await Promise.all(deletingAttributes.map((attribute) => deleteAttribute(collection, attribute, isIndex)));
|
|
719
|
-
const attributeKeys = [
|
|
720
|
-
...remoteAttributes.map((attribute) => attribute.key),
|
|
721
|
-
...deletingAttributes.map((attribute) => attribute.key),
|
|
722
|
-
];
|
|
723
|
-
if (attributeKeys.length) {
|
|
724
|
-
const deleteAttributesPoolStatus = await awaitPools.deleteAttributes(collection["databaseId"], collection["$id"], attributeKeys);
|
|
725
|
-
if (!deleteAttributesPoolStatus) {
|
|
726
|
-
throw new Error("Attribute deletion timed out.");
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
return localAttributes.filter((attribute) => !attributesContains(attribute, remoteAttributes));
|
|
730
|
-
};
|
|
731
|
-
const createIndexes = async (indexes, collection) => {
|
|
732
|
-
log(`Creating indexes ...`);
|
|
733
|
-
const databasesService = await getDatabasesService();
|
|
734
|
-
for (let index of indexes) {
|
|
735
|
-
await databasesService.createIndex(collection["databaseId"], collection["$id"], index.key, index.type, index.columns ?? index.attributes, index.orders);
|
|
736
|
-
}
|
|
737
|
-
const result = await awaitPools.expectIndexes(collection["databaseId"], collection["$id"], indexes.map((index) => index.key));
|
|
738
|
-
if (!result) {
|
|
739
|
-
throw new Error("Index creation timed out.");
|
|
740
|
-
}
|
|
741
|
-
success(`Created ${indexes.length} indexes`);
|
|
742
|
-
};
|
|
743
|
-
const createAttributes = async (attributes, collection) => {
|
|
744
|
-
for (let attribute of attributes) {
|
|
745
|
-
if (attribute.side !== "child") {
|
|
746
|
-
await createAttribute(collection["databaseId"], collection["$id"], attribute);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
const result = await awaitPools.expectAttributes(collection["databaseId"], collection["$id"], collection.attributes
|
|
750
|
-
.filter((attribute) => attribute.side !== "child")
|
|
751
|
-
.map((attribute) => attribute.key));
|
|
752
|
-
if (!result) {
|
|
753
|
-
throw new Error(`Attribute creation timed out.`);
|
|
754
|
-
}
|
|
755
|
-
success(`Created ${attributes.length} attributes`);
|
|
756
|
-
};
|
|
757
|
-
const createColumns = async (columns, table) => {
|
|
758
|
-
for (let column of columns) {
|
|
759
|
-
if (column.side !== "child") {
|
|
760
|
-
await createAttribute(table["databaseId"], table["$id"], column);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
const result = await awaitPools.expectAttributes(table["databaseId"], table["$id"], table.columns
|
|
764
|
-
.filter((column) => column.side !== "child")
|
|
765
|
-
.map((column) => column.key));
|
|
766
|
-
if (!result) {
|
|
767
|
-
throw new Error(`Column creation timed out.`);
|
|
768
|
-
}
|
|
769
|
-
success(`Created ${columns.length} columns`);
|
|
770
|
-
};
|
|
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
|
+
}
|
|
771
1171
|
const pushResources = async ({ skipDeprecated = false, } = {}) => {
|
|
772
|
-
const actions = {
|
|
773
|
-
settings: pushSettings,
|
|
774
|
-
functions: pushFunction,
|
|
775
|
-
sites: pushSite,
|
|
776
|
-
collections: pushCollection,
|
|
777
|
-
tables: pushTable,
|
|
778
|
-
buckets: pushBucket,
|
|
779
|
-
teams: pushTeam,
|
|
780
|
-
messages: pushMessagingTopic,
|
|
781
|
-
};
|
|
782
|
-
if (skipDeprecated) {
|
|
783
|
-
delete actions.collections;
|
|
784
|
-
}
|
|
785
1172
|
if (cliConfig.all) {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
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
|
+
});
|
|
789
1181
|
}
|
|
790
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
|
+
}
|
|
791
1196
|
const answers = await inquirer.prompt(questionsPushResources);
|
|
792
1197
|
const action = actions[answers.resource];
|
|
793
1198
|
if (action !== undefined) {
|
|
@@ -800,7 +1205,7 @@ const pushSettings = async () => {
|
|
|
800
1205
|
try {
|
|
801
1206
|
const projectsService = await getProjectsService();
|
|
802
1207
|
let response = await projectsService.get(localConfig.getProject().projectId);
|
|
803
|
-
const remoteSettings =
|
|
1208
|
+
const remoteSettings = createSettingsObject(response);
|
|
804
1209
|
const localSettings = localConfig.getProject().projectSettings ?? {};
|
|
805
1210
|
log("Checking for changes ...");
|
|
806
1211
|
const changes = [];
|
|
@@ -818,39 +1223,13 @@ const pushSettings = async () => {
|
|
|
818
1223
|
catch (e) { }
|
|
819
1224
|
try {
|
|
820
1225
|
log("Pushing project settings ...");
|
|
821
|
-
const
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
}
|
|
829
|
-
if (settings.services) {
|
|
830
|
-
log("Applying service statuses ...");
|
|
831
|
-
for (let [service, status] of Object.entries(settings.services)) {
|
|
832
|
-
await projectsService.updateServiceStatus(projectId, service, status);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
if (settings.auth) {
|
|
836
|
-
if (settings.auth.security) {
|
|
837
|
-
log("Applying auth security settings ...");
|
|
838
|
-
await projectsService.updateAuthDuration(projectId, settings.auth.security.duration);
|
|
839
|
-
await projectsService.updateAuthLimit(projectId, settings.auth.security.limit);
|
|
840
|
-
await projectsService.updateAuthSessionsLimit(projectId, settings.auth.security.sessionsLimit);
|
|
841
|
-
await projectsService.updateAuthPasswordDictionary(projectId, settings.auth.security.passwordDictionary);
|
|
842
|
-
await projectsService.updateAuthPasswordHistory(projectId, settings.auth.security.passwordHistory);
|
|
843
|
-
await projectsService.updatePersonalDataCheck(projectId, settings.auth.security.personalDataCheck);
|
|
844
|
-
await projectsService.updateSessionAlerts(projectId, settings.auth.security.sessionAlerts);
|
|
845
|
-
await projectsService.updateMockNumbers(projectId, settings.auth.security.mockNumbers);
|
|
846
|
-
}
|
|
847
|
-
if (settings.auth.methods) {
|
|
848
|
-
log("Applying auth methods statuses ...");
|
|
849
|
-
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
850
|
-
await projectsService.updateAuthStatus(projectId, method, status);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
}
|
|
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
|
+
});
|
|
854
1233
|
success(`Successfully pushed ${chalk.bold("all")} project settings.`);
|
|
855
1234
|
}
|
|
856
1235
|
catch (e) {
|
|
@@ -878,281 +1257,41 @@ const pushSite = async ({ siteId, async: asyncDeploy, code, withVariables, } = {
|
|
|
878
1257
|
}
|
|
879
1258
|
if (siteIds.length === 0) {
|
|
880
1259
|
log("No sites found.");
|
|
881
|
-
hint(
|
|
1260
|
+
hint(`Use '${EXECUTABLE_NAME} pull sites' to synchronize existing one, or use '${EXECUTABLE_NAME} init site' to create a new one.`);
|
|
882
1261
|
return;
|
|
883
1262
|
}
|
|
884
|
-
let sites = siteIds.map((id) => {
|
|
885
|
-
const sites = localConfig.getSites();
|
|
886
|
-
const site = sites.find((s) => s.$id === id);
|
|
887
|
-
if (!site) {
|
|
888
|
-
throw new Error("Site '" + id + "' not found.");
|
|
889
|
-
}
|
|
890
|
-
return site;
|
|
891
|
-
});
|
|
892
|
-
log("Validating sites ...");
|
|
893
|
-
// Validation is done BEFORE pushing so the deployment process can be run in async with progress update
|
|
894
|
-
for (let site of sites) {
|
|
895
|
-
if (!site.buildCommand) {
|
|
896
|
-
log(`Site ${site.name} is missing build command.`);
|
|
897
|
-
const answers = await inquirer.prompt(questionsGetEntrypoint);
|
|
898
|
-
site.buildCommand = answers.entrypoint;
|
|
899
|
-
localConfig.addSite(site);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
if (!(await approveChanges(sites, async (args) => {
|
|
903
|
-
const sitesService = await getSitesService();
|
|
904
|
-
return await sitesService.get({ siteId: args.siteId });
|
|
905
|
-
}, KeysSite, "siteId", "sites", ["vars"]))) {
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
log("Pushing sites ...");
|
|
909
|
-
Spinner.start(false);
|
|
910
|
-
let successfullyPushed = 0;
|
|
911
|
-
let successfullyDeployed = 0;
|
|
912
|
-
const failedDeployments = [];
|
|
913
|
-
const errors = [];
|
|
914
|
-
await Promise.all(sites.map(async (site) => {
|
|
915
|
-
let response = {};
|
|
916
|
-
const ignore = site.ignore ? "appwrite.config.json" : ".gitignore";
|
|
917
|
-
let siteExists = false;
|
|
918
|
-
let deploymentCreated = false;
|
|
919
|
-
const updaterRow = new Spinner({
|
|
920
|
-
status: "",
|
|
921
|
-
resource: site.name,
|
|
922
|
-
id: site["$id"],
|
|
923
|
-
end: `Ignoring using: ${ignore}`,
|
|
924
|
-
});
|
|
925
|
-
updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
|
|
926
|
-
const sitesService = await getSitesService();
|
|
927
|
-
try {
|
|
928
|
-
response = await sitesService.get({ siteId: site["$id"] });
|
|
929
|
-
siteExists = true;
|
|
930
|
-
if (response.framework !== site.framework) {
|
|
931
|
-
updaterRow.fail({
|
|
932
|
-
errorMessage: `Framework mismatch! (local=${site.framework},remote=${response.framework}) Please delete remote site or update your appwrite.config.json`,
|
|
933
|
-
});
|
|
934
|
-
return;
|
|
935
|
-
}
|
|
936
|
-
updaterRow.update({ status: "Updating" }).replaceSpinner(SPINNER_ARC);
|
|
937
|
-
response = await sitesService.update({
|
|
938
|
-
siteId: site["$id"],
|
|
939
|
-
name: site.name,
|
|
940
|
-
framework: site.framework,
|
|
941
|
-
enabled: site.enabled,
|
|
942
|
-
logging: site.logging,
|
|
943
|
-
timeout: site.timeout,
|
|
944
|
-
installCommand: site.installCommand,
|
|
945
|
-
buildCommand: site.buildCommand,
|
|
946
|
-
outputDirectory: site.outputDirectory,
|
|
947
|
-
buildRuntime: site.buildRuntime,
|
|
948
|
-
adapter: site.adapter,
|
|
949
|
-
specification: site.specification,
|
|
950
|
-
});
|
|
951
|
-
}
|
|
952
|
-
catch (e) {
|
|
953
|
-
if (Number(e.code) === 404) {
|
|
954
|
-
siteExists = false;
|
|
955
|
-
}
|
|
956
|
-
else {
|
|
957
|
-
errors.push(e);
|
|
958
|
-
updaterRow.fail({
|
|
959
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
960
|
-
});
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
if (!siteExists) {
|
|
965
|
-
updaterRow.update({ status: "Creating" }).replaceSpinner(SPINNER_DOTS);
|
|
966
|
-
try {
|
|
967
|
-
response = await sitesService.create({
|
|
968
|
-
siteId: site.$id,
|
|
969
|
-
name: site.name,
|
|
970
|
-
framework: site.framework,
|
|
971
|
-
enabled: site.enabled,
|
|
972
|
-
logging: site.logging,
|
|
973
|
-
timeout: site.timeout,
|
|
974
|
-
installCommand: site.installCommand,
|
|
975
|
-
buildCommand: site.buildCommand,
|
|
976
|
-
outputDirectory: site.outputDirectory,
|
|
977
|
-
buildRuntime: site.buildRuntime,
|
|
978
|
-
adapter: site.adapter,
|
|
979
|
-
specification: site.specification,
|
|
980
|
-
});
|
|
981
|
-
let domain = "";
|
|
982
|
-
try {
|
|
983
|
-
const consoleService = await getConsoleService();
|
|
984
|
-
const variables = await consoleService.variables();
|
|
985
|
-
domain = ID.unique() + "." + variables["_APP_DOMAIN_SITES"];
|
|
986
|
-
}
|
|
987
|
-
catch (error) {
|
|
988
|
-
console.error("Error fetching console variables.");
|
|
989
|
-
throw error;
|
|
990
|
-
}
|
|
991
|
-
try {
|
|
992
|
-
const proxyService = await getProxyService();
|
|
993
|
-
const rule = await proxyService.createSiteRule(domain, site.$id);
|
|
994
|
-
}
|
|
995
|
-
catch (error) {
|
|
996
|
-
console.error("Error creating site rule.");
|
|
997
|
-
throw error;
|
|
998
|
-
}
|
|
999
|
-
updaterRow.update({ status: "Created" });
|
|
1000
|
-
}
|
|
1001
|
-
catch (e) {
|
|
1002
|
-
errors.push(e);
|
|
1003
|
-
updaterRow.fail({
|
|
1004
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
1005
|
-
});
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
if (withVariables) {
|
|
1010
|
-
updaterRow
|
|
1011
|
-
.update({ status: "Creating variables" })
|
|
1012
|
-
.replaceSpinner(SPINNER_ARC);
|
|
1013
|
-
const sitesService = await getSitesService();
|
|
1014
|
-
const { variables } = await paginate(async (args) => {
|
|
1015
|
-
return await sitesService.listVariables({ siteId: args.siteId });
|
|
1016
|
-
}, {
|
|
1017
|
-
siteId: site["$id"],
|
|
1018
|
-
}, 100, "variables");
|
|
1019
|
-
await Promise.all(variables.map(async (variable) => {
|
|
1020
|
-
const sitesService = await getSitesService();
|
|
1021
|
-
await sitesService.deleteVariable({
|
|
1022
|
-
siteId: site["$id"],
|
|
1023
|
-
variableId: variable["$id"],
|
|
1024
|
-
});
|
|
1025
|
-
}));
|
|
1026
|
-
const envFileLocation = `${site["path"]}/.env`;
|
|
1027
|
-
let envVariables = [];
|
|
1028
|
-
try {
|
|
1029
|
-
if (fs.existsSync(envFileLocation)) {
|
|
1030
|
-
const envObject = parseDotenv(fs.readFileSync(envFileLocation, "utf8"));
|
|
1031
|
-
envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
catch (error) {
|
|
1035
|
-
// Handle parsing errors gracefully
|
|
1036
|
-
envVariables = [];
|
|
1037
|
-
}
|
|
1038
|
-
await Promise.all(envVariables.map(async (variable) => {
|
|
1039
|
-
const sitesService = await getSitesService();
|
|
1040
|
-
await sitesService.createVariable({
|
|
1041
|
-
siteId: site["$id"],
|
|
1042
|
-
key: variable.key,
|
|
1043
|
-
value: variable.value,
|
|
1044
|
-
secret: false,
|
|
1045
|
-
});
|
|
1046
|
-
}));
|
|
1047
|
-
}
|
|
1048
|
-
if (code === false) {
|
|
1049
|
-
successfullyPushed++;
|
|
1050
|
-
successfullyDeployed++;
|
|
1051
|
-
updaterRow.update({ status: "Pushed" });
|
|
1052
|
-
updaterRow.stopSpinner();
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
try {
|
|
1056
|
-
updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_ARC);
|
|
1057
|
-
const sitesService = await getSitesService();
|
|
1058
|
-
response = await sitesService.createDeployment({
|
|
1059
|
-
siteId: site["$id"],
|
|
1060
|
-
installCommand: site.installCommand,
|
|
1061
|
-
buildCommand: site.buildCommand,
|
|
1062
|
-
outputDirectory: site.outputDirectory,
|
|
1063
|
-
code: site.path,
|
|
1064
|
-
activate: true,
|
|
1065
|
-
});
|
|
1066
|
-
updaterRow.update({ status: "Pushed" });
|
|
1067
|
-
deploymentCreated = true;
|
|
1068
|
-
successfullyPushed++;
|
|
1069
|
-
}
|
|
1070
|
-
catch (e) {
|
|
1071
|
-
errors.push(e);
|
|
1072
|
-
switch (e.code) {
|
|
1073
|
-
case "ENOENT":
|
|
1074
|
-
updaterRow.fail({
|
|
1075
|
-
errorMessage: "Not found in the current directory. Skipping...",
|
|
1076
|
-
});
|
|
1077
|
-
break;
|
|
1078
|
-
default:
|
|
1079
|
-
updaterRow.fail({
|
|
1080
|
-
errorMessage: e.message ?? "An unknown error occurred. Please try again.",
|
|
1081
|
-
});
|
|
1082
|
-
}
|
|
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.");
|
|
1083
1268
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
response = await sitesService.getDeployment({
|
|
1095
|
-
siteId: site["$id"],
|
|
1096
|
-
deploymentId: deploymentId,
|
|
1097
|
-
});
|
|
1098
|
-
const status = response["status"];
|
|
1099
|
-
if (status === "ready") {
|
|
1100
|
-
successfullyDeployed++;
|
|
1101
|
-
let url = "";
|
|
1102
|
-
const proxyService = await getProxyService();
|
|
1103
|
-
const res = await proxyService.listRules([
|
|
1104
|
-
JSON.stringify({ method: "limit", values: [1] }),
|
|
1105
|
-
JSON.stringify({
|
|
1106
|
-
method: "equal",
|
|
1107
|
-
attribute: "deploymentResourceType",
|
|
1108
|
-
values: ["site"],
|
|
1109
|
-
}),
|
|
1110
|
-
JSON.stringify({
|
|
1111
|
-
method: "equal",
|
|
1112
|
-
attribute: "deploymentResourceId",
|
|
1113
|
-
values: [site["$id"]],
|
|
1114
|
-
}),
|
|
1115
|
-
JSON.stringify({
|
|
1116
|
-
method: "equal",
|
|
1117
|
-
attribute: "trigger",
|
|
1118
|
-
values: ["manual"],
|
|
1119
|
-
}),
|
|
1120
|
-
]);
|
|
1121
|
-
if (Number(res.total) === 1) {
|
|
1122
|
-
url = res.rules[0].domain;
|
|
1123
|
-
}
|
|
1124
|
-
updaterRow.update({ status: "Deployed", end: url });
|
|
1125
|
-
break;
|
|
1126
|
-
}
|
|
1127
|
-
else if (status === "failed") {
|
|
1128
|
-
failedDeployments.push({
|
|
1129
|
-
name: site["name"],
|
|
1130
|
-
$id: site["$id"],
|
|
1131
|
-
deployment: response["$id"],
|
|
1132
|
-
});
|
|
1133
|
-
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
1134
|
-
break;
|
|
1135
|
-
}
|
|
1136
|
-
else {
|
|
1137
|
-
updaterRow.update({
|
|
1138
|
-
status: "Deploying",
|
|
1139
|
-
end: `Current status: ${status}`,
|
|
1140
|
-
});
|
|
1141
|
-
}
|
|
1142
|
-
pollChecks++;
|
|
1143
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE * 1.5));
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
catch (e) {
|
|
1147
|
-
errors.push(e);
|
|
1148
|
-
updaterRow.fail({
|
|
1149
|
-
errorMessage: e.message ?? "Unknown error occurred. Please try again",
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
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);
|
|
1152
1279
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
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;
|
|
1156
1295
|
failedDeployments.forEach((failed) => {
|
|
1157
1296
|
const { name, deployment, $id } = failed;
|
|
1158
1297
|
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/sites/site-${$id}/deployments/deployment-${deployment}`;
|
|
@@ -1199,7 +1338,7 @@ const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariable
|
|
|
1199
1338
|
}
|
|
1200
1339
|
if (functionIds.length === 0) {
|
|
1201
1340
|
log("No functions found.");
|
|
1202
|
-
hint(
|
|
1341
|
+
hint(`Use '${EXECUTABLE_NAME} pull functions' to synchronize existing one, or use '${EXECUTABLE_NAME} init function' to create a new one.`);
|
|
1203
1342
|
return;
|
|
1204
1343
|
}
|
|
1205
1344
|
let functions = functionIds.map((id) => {
|
|
@@ -1211,7 +1350,6 @@ const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariable
|
|
|
1211
1350
|
return func;
|
|
1212
1351
|
});
|
|
1213
1352
|
log("Validating functions ...");
|
|
1214
|
-
// Validation is done BEFORE pushing so the deployment process can be run in async with progress update
|
|
1215
1353
|
for (let func of functions) {
|
|
1216
1354
|
if (!func.entrypoint) {
|
|
1217
1355
|
log(`Function ${func.name} is missing an entrypoint.`);
|
|
@@ -1227,256 +1365,13 @@ const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariable
|
|
|
1227
1365
|
return;
|
|
1228
1366
|
}
|
|
1229
1367
|
log("Pushing functions ...");
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
const ignore = func.ignore ? "appwrite.config.json" : ".gitignore";
|
|
1238
|
-
let functionExists = false;
|
|
1239
|
-
let deploymentCreated = false;
|
|
1240
|
-
const updaterRow = new Spinner({
|
|
1241
|
-
status: "",
|
|
1242
|
-
resource: func.name,
|
|
1243
|
-
id: func["$id"],
|
|
1244
|
-
end: `Ignoring using: ${ignore}`,
|
|
1245
|
-
});
|
|
1246
|
-
updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
|
|
1247
|
-
const functionsService = await getFunctionsService();
|
|
1248
|
-
try {
|
|
1249
|
-
response = await functionsService.get({ functionId: func["$id"] });
|
|
1250
|
-
functionExists = true;
|
|
1251
|
-
if (response.runtime !== func.runtime) {
|
|
1252
|
-
updaterRow.fail({
|
|
1253
|
-
errorMessage: `Runtime mismatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.config.json`,
|
|
1254
|
-
});
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
|
-
updaterRow.update({ status: "Updating" }).replaceSpinner(SPINNER_ARC);
|
|
1258
|
-
response = await functionsService.update({
|
|
1259
|
-
functionId: func["$id"],
|
|
1260
|
-
name: func.name,
|
|
1261
|
-
runtime: func.runtime,
|
|
1262
|
-
execute: func.execute,
|
|
1263
|
-
events: func.events,
|
|
1264
|
-
schedule: func.schedule,
|
|
1265
|
-
timeout: func.timeout,
|
|
1266
|
-
enabled: func.enabled,
|
|
1267
|
-
logging: func.logging,
|
|
1268
|
-
entrypoint: func.entrypoint,
|
|
1269
|
-
commands: func.commands,
|
|
1270
|
-
scopes: func.scopes,
|
|
1271
|
-
specification: func.specification,
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
catch (e) {
|
|
1275
|
-
if (Number(e.code) === 404) {
|
|
1276
|
-
functionExists = false;
|
|
1277
|
-
}
|
|
1278
|
-
else {
|
|
1279
|
-
errors.push(e);
|
|
1280
|
-
updaterRow.fail({
|
|
1281
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
1282
|
-
});
|
|
1283
|
-
return;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
if (!functionExists) {
|
|
1287
|
-
updaterRow.update({ status: "Creating" }).replaceSpinner(SPINNER_DOTS);
|
|
1288
|
-
try {
|
|
1289
|
-
response = await functionsService.create({
|
|
1290
|
-
functionId: func.$id,
|
|
1291
|
-
name: func.name,
|
|
1292
|
-
runtime: func.runtime,
|
|
1293
|
-
execute: func.execute,
|
|
1294
|
-
events: func.events,
|
|
1295
|
-
schedule: func.schedule,
|
|
1296
|
-
timeout: func.timeout,
|
|
1297
|
-
enabled: func.enabled,
|
|
1298
|
-
logging: func.logging,
|
|
1299
|
-
entrypoint: func.entrypoint,
|
|
1300
|
-
commands: func.commands,
|
|
1301
|
-
scopes: func.scopes,
|
|
1302
|
-
specification: func.specification,
|
|
1303
|
-
});
|
|
1304
|
-
let domain = "";
|
|
1305
|
-
try {
|
|
1306
|
-
const consoleService = await getConsoleService();
|
|
1307
|
-
const variables = await consoleService.variables();
|
|
1308
|
-
domain = ID.unique() + "." + variables["_APP_DOMAIN_FUNCTIONS"];
|
|
1309
|
-
}
|
|
1310
|
-
catch (error) {
|
|
1311
|
-
console.error("Error fetching console variables.");
|
|
1312
|
-
throw error;
|
|
1313
|
-
}
|
|
1314
|
-
try {
|
|
1315
|
-
const proxyService = await getProxyService();
|
|
1316
|
-
const rule = await proxyService.createFunctionRule(domain, func.$id);
|
|
1317
|
-
}
|
|
1318
|
-
catch (error) {
|
|
1319
|
-
console.error("Error creating function rule.");
|
|
1320
|
-
throw error;
|
|
1321
|
-
}
|
|
1322
|
-
updaterRow.update({ status: "Created" });
|
|
1323
|
-
}
|
|
1324
|
-
catch (e) {
|
|
1325
|
-
errors.push(e);
|
|
1326
|
-
updaterRow.fail({
|
|
1327
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
1328
|
-
});
|
|
1329
|
-
return;
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
if (withVariables) {
|
|
1333
|
-
updaterRow
|
|
1334
|
-
.update({ status: "Updating variables" })
|
|
1335
|
-
.replaceSpinner(SPINNER_ARC);
|
|
1336
|
-
const functionsService = await getFunctionsService();
|
|
1337
|
-
const { variables } = await paginate(async (args) => {
|
|
1338
|
-
return await functionsService.listVariables({
|
|
1339
|
-
functionId: args.functionId,
|
|
1340
|
-
});
|
|
1341
|
-
}, {
|
|
1342
|
-
functionId: func["$id"],
|
|
1343
|
-
}, 100, "variables");
|
|
1344
|
-
await Promise.all(variables.map(async (variable) => {
|
|
1345
|
-
const functionsService = await getFunctionsService();
|
|
1346
|
-
await functionsService.deleteVariable({
|
|
1347
|
-
functionId: func["$id"],
|
|
1348
|
-
variableId: variable["$id"],
|
|
1349
|
-
});
|
|
1350
|
-
}));
|
|
1351
|
-
const envFileLocation = `${func["path"]}/.env`;
|
|
1352
|
-
let envVariables = [];
|
|
1353
|
-
try {
|
|
1354
|
-
if (fs.existsSync(envFileLocation)) {
|
|
1355
|
-
const envObject = parseDotenv(fs.readFileSync(envFileLocation, "utf8"));
|
|
1356
|
-
envVariables = Object.entries(envObject || {}).map(([key, value]) => ({ key, value }));
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
catch (error) {
|
|
1360
|
-
// Handle parsing errors gracefully
|
|
1361
|
-
envVariables = [];
|
|
1362
|
-
}
|
|
1363
|
-
await Promise.all(envVariables.map(async (variable) => {
|
|
1364
|
-
const functionsService = await getFunctionsService();
|
|
1365
|
-
await functionsService.createVariable({
|
|
1366
|
-
functionId: func["$id"],
|
|
1367
|
-
key: variable.key,
|
|
1368
|
-
value: variable.value,
|
|
1369
|
-
secret: false,
|
|
1370
|
-
});
|
|
1371
|
-
}));
|
|
1372
|
-
}
|
|
1373
|
-
if (code === false) {
|
|
1374
|
-
successfullyPushed++;
|
|
1375
|
-
successfullyDeployed++;
|
|
1376
|
-
updaterRow.update({ status: "Pushed" });
|
|
1377
|
-
updaterRow.stopSpinner();
|
|
1378
|
-
return;
|
|
1379
|
-
}
|
|
1380
|
-
try {
|
|
1381
|
-
updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_ARC);
|
|
1382
|
-
const functionsService = await getFunctionsService();
|
|
1383
|
-
response = await functionsService.createDeployment({
|
|
1384
|
-
functionId: func["$id"],
|
|
1385
|
-
entrypoint: func.entrypoint,
|
|
1386
|
-
commands: func.commands,
|
|
1387
|
-
code: func.path,
|
|
1388
|
-
activate: true,
|
|
1389
|
-
});
|
|
1390
|
-
updaterRow.update({ status: "Pushed" });
|
|
1391
|
-
deploymentCreated = true;
|
|
1392
|
-
successfullyPushed++;
|
|
1393
|
-
}
|
|
1394
|
-
catch (e) {
|
|
1395
|
-
errors.push(e);
|
|
1396
|
-
switch (e.code) {
|
|
1397
|
-
case "ENOENT":
|
|
1398
|
-
updaterRow.fail({
|
|
1399
|
-
errorMessage: "Not found in the current directory. Skipping...",
|
|
1400
|
-
});
|
|
1401
|
-
break;
|
|
1402
|
-
default:
|
|
1403
|
-
updaterRow.fail({
|
|
1404
|
-
errorMessage: e.message ?? "An unknown error occurred. Please try again.",
|
|
1405
|
-
});
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
if (deploymentCreated && !asyncDeploy) {
|
|
1409
|
-
try {
|
|
1410
|
-
const deploymentId = response["$id"];
|
|
1411
|
-
updaterRow.update({
|
|
1412
|
-
status: "Deploying",
|
|
1413
|
-
end: "Checking deployment status...",
|
|
1414
|
-
});
|
|
1415
|
-
let pollChecks = 0;
|
|
1416
|
-
while (true) {
|
|
1417
|
-
const functionsService = await getFunctionsService();
|
|
1418
|
-
response = await functionsService.getDeployment({
|
|
1419
|
-
functionId: func["$id"],
|
|
1420
|
-
deploymentId: deploymentId,
|
|
1421
|
-
});
|
|
1422
|
-
const status = response["status"];
|
|
1423
|
-
if (status === "ready") {
|
|
1424
|
-
successfullyDeployed++;
|
|
1425
|
-
let url = "";
|
|
1426
|
-
const proxyService = await getProxyService();
|
|
1427
|
-
const res = await proxyService.listRules([
|
|
1428
|
-
JSON.stringify({ method: "limit", values: [1] }),
|
|
1429
|
-
JSON.stringify({
|
|
1430
|
-
method: "equal",
|
|
1431
|
-
attribute: "deploymentResourceType",
|
|
1432
|
-
values: ["function"],
|
|
1433
|
-
}),
|
|
1434
|
-
JSON.stringify({
|
|
1435
|
-
method: "equal",
|
|
1436
|
-
attribute: "deploymentResourceId",
|
|
1437
|
-
values: [func["$id"]],
|
|
1438
|
-
}),
|
|
1439
|
-
JSON.stringify({
|
|
1440
|
-
method: "equal",
|
|
1441
|
-
attribute: "trigger",
|
|
1442
|
-
values: ["manual"],
|
|
1443
|
-
}),
|
|
1444
|
-
]);
|
|
1445
|
-
if (Number(res.total) === 1) {
|
|
1446
|
-
url = res.rules[0].domain;
|
|
1447
|
-
}
|
|
1448
|
-
updaterRow.update({ status: "Deployed", end: url });
|
|
1449
|
-
break;
|
|
1450
|
-
}
|
|
1451
|
-
else if (status === "failed") {
|
|
1452
|
-
failedDeployments.push({
|
|
1453
|
-
name: func["name"],
|
|
1454
|
-
$id: func["$id"],
|
|
1455
|
-
deployment: response["$id"],
|
|
1456
|
-
});
|
|
1457
|
-
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
1458
|
-
break;
|
|
1459
|
-
}
|
|
1460
|
-
else {
|
|
1461
|
-
updaterRow.update({
|
|
1462
|
-
status: "Deploying",
|
|
1463
|
-
end: `Current status: ${status}`,
|
|
1464
|
-
});
|
|
1465
|
-
}
|
|
1466
|
-
pollChecks++;
|
|
1467
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_DEBOUNCE * 1.5));
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
catch (e) {
|
|
1471
|
-
errors.push(e);
|
|
1472
|
-
updaterRow.fail({
|
|
1473
|
-
errorMessage: e.message ?? "Unknown error occurred. Please try again",
|
|
1474
|
-
});
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
updaterRow.stopSpinner();
|
|
1478
|
-
}));
|
|
1479
|
-
Spinner.stop();
|
|
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;
|
|
1480
1375
|
failedDeployments.forEach((failed) => {
|
|
1481
1376
|
const { name, deployment, $id } = failed;
|
|
1482
1377
|
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
|
|
@@ -1502,145 +1397,14 @@ const pushFunction = async ({ functionId, async: asyncDeploy, code, withVariable
|
|
|
1502
1397
|
});
|
|
1503
1398
|
}
|
|
1504
1399
|
};
|
|
1505
|
-
const checkAndApplyTablesDBChanges = async () => {
|
|
1506
|
-
log("Checking for tablesDB changes ...");
|
|
1507
|
-
const localTablesDBs = localConfig.getTablesDBs();
|
|
1508
|
-
const { databases: remoteTablesDBs } = await paginate(async (args) => {
|
|
1509
|
-
const tablesDBService = await getTablesDBService();
|
|
1510
|
-
return await tablesDBService.list(args.queries || []);
|
|
1511
|
-
}, {}, 100, "databases");
|
|
1512
|
-
if (localTablesDBs.length === 0 && remoteTablesDBs.length === 0) {
|
|
1513
|
-
return { applied: false, resyncNeeded: false };
|
|
1514
|
-
}
|
|
1515
|
-
const changes = [];
|
|
1516
|
-
const toCreate = [];
|
|
1517
|
-
const toUpdate = [];
|
|
1518
|
-
const toDelete = [];
|
|
1519
|
-
// Check for deletions - remote DBs that aren't in local config
|
|
1520
|
-
for (const remoteDB of remoteTablesDBs) {
|
|
1521
|
-
const localDB = localTablesDBs.find((db) => db.$id === remoteDB.$id);
|
|
1522
|
-
if (!localDB) {
|
|
1523
|
-
toDelete.push(remoteDB);
|
|
1524
|
-
changes.push({
|
|
1525
|
-
id: remoteDB.$id,
|
|
1526
|
-
action: chalk.red("deleting"),
|
|
1527
|
-
key: "Database",
|
|
1528
|
-
remote: remoteDB.name,
|
|
1529
|
-
local: "(deleted locally)",
|
|
1530
|
-
});
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
// Check for additions and updates
|
|
1534
|
-
for (const localDB of localTablesDBs) {
|
|
1535
|
-
const remoteDB = remoteTablesDBs.find((db) => db.$id === localDB.$id);
|
|
1536
|
-
if (!remoteDB) {
|
|
1537
|
-
toCreate.push(localDB);
|
|
1538
|
-
changes.push({
|
|
1539
|
-
id: localDB.$id,
|
|
1540
|
-
action: chalk.green("creating"),
|
|
1541
|
-
key: "Database",
|
|
1542
|
-
remote: "(does not exist)",
|
|
1543
|
-
local: localDB.name,
|
|
1544
|
-
});
|
|
1545
|
-
}
|
|
1546
|
-
else {
|
|
1547
|
-
let hasChanges = false;
|
|
1548
|
-
if (remoteDB.name !== localDB.name) {
|
|
1549
|
-
hasChanges = true;
|
|
1550
|
-
changes.push({
|
|
1551
|
-
id: localDB.$id,
|
|
1552
|
-
action: chalk.yellow("updating"),
|
|
1553
|
-
key: "Name",
|
|
1554
|
-
remote: remoteDB.name,
|
|
1555
|
-
local: localDB.name,
|
|
1556
|
-
});
|
|
1557
|
-
}
|
|
1558
|
-
if (remoteDB.enabled !== localDB.enabled) {
|
|
1559
|
-
hasChanges = true;
|
|
1560
|
-
changes.push({
|
|
1561
|
-
id: localDB.$id,
|
|
1562
|
-
action: chalk.yellow("updating"),
|
|
1563
|
-
key: "Enabled",
|
|
1564
|
-
remote: remoteDB.enabled,
|
|
1565
|
-
local: localDB.enabled,
|
|
1566
|
-
});
|
|
1567
|
-
}
|
|
1568
|
-
if (hasChanges) {
|
|
1569
|
-
toUpdate.push(localDB);
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
if (changes.length === 0) {
|
|
1574
|
-
return { applied: false, resyncNeeded: false };
|
|
1575
|
-
}
|
|
1576
|
-
log("Found changes in tablesDB resource:");
|
|
1577
|
-
drawTable(changes);
|
|
1578
|
-
if (toDelete.length > 0) {
|
|
1579
|
-
console.log(`${chalk.red("------------------------------------------------------------------")}`);
|
|
1580
|
-
console.log(`${chalk.red("| WARNING: Database deletion will also delete all related tables |")}`);
|
|
1581
|
-
console.log(`${chalk.red("------------------------------------------------------------------")}`);
|
|
1582
|
-
console.log();
|
|
1583
|
-
}
|
|
1584
|
-
if ((await getConfirmation()) !== true) {
|
|
1585
|
-
return { applied: false, resyncNeeded: false };
|
|
1586
|
-
}
|
|
1587
|
-
// Apply deletions first
|
|
1588
|
-
let needsResync = false;
|
|
1589
|
-
for (const db of toDelete) {
|
|
1590
|
-
try {
|
|
1591
|
-
log(`Deleting database ${db.name} ( ${db.$id} ) ...`);
|
|
1592
|
-
const tablesDBService = await getTablesDBService();
|
|
1593
|
-
await tablesDBService.delete(db.$id);
|
|
1594
|
-
success(`Deleted ${db.name} ( ${db.$id} )`);
|
|
1595
|
-
needsResync = true;
|
|
1596
|
-
}
|
|
1597
|
-
catch (e) {
|
|
1598
|
-
error(`Failed to delete database ${db.name} ( ${db.$id} ): ${e.message}`);
|
|
1599
|
-
throw new Error(`Database sync failed during deletion of ${db.$id}. Some changes may have been applied.`);
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
// Apply creations
|
|
1603
|
-
for (const db of toCreate) {
|
|
1604
|
-
try {
|
|
1605
|
-
log(`Creating database ${db.name} ( ${db.$id} ) ...`);
|
|
1606
|
-
const tablesDBService = await getTablesDBService();
|
|
1607
|
-
await tablesDBService.create(db.$id, db.name, db.enabled);
|
|
1608
|
-
success(`Created ${db.name} ( ${db.$id} )`);
|
|
1609
|
-
}
|
|
1610
|
-
catch (e) {
|
|
1611
|
-
error(`Failed to create database ${db.name} ( ${db.$id} ): ${e.message}`);
|
|
1612
|
-
throw new Error(`Database sync failed during creation of ${db.$id}. Some changes may have been applied.`);
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
// Apply updates
|
|
1616
|
-
for (const db of toUpdate) {
|
|
1617
|
-
try {
|
|
1618
|
-
log(`Updating database ${db.name} ( ${db.$id} ) ...`);
|
|
1619
|
-
const tablesDBService = await getTablesDBService();
|
|
1620
|
-
await tablesDBService.update(db.$id, db.name, db.enabled);
|
|
1621
|
-
success(`Updated ${db.name} ( ${db.$id} )`);
|
|
1622
|
-
}
|
|
1623
|
-
catch (e) {
|
|
1624
|
-
error(`Failed to update database ${db.name} ( ${db.$id} ): ${e.message}`);
|
|
1625
|
-
throw new Error(`Database sync failed during update of ${db.$id}. Some changes may have been applied.`);
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
if (toDelete.length === 0) {
|
|
1629
|
-
console.log();
|
|
1630
|
-
}
|
|
1631
|
-
return { applied: true, resyncNeeded: needsResync };
|
|
1632
|
-
};
|
|
1633
1400
|
const pushTable = async ({ attempts, } = {}) => {
|
|
1634
1401
|
const tables = [];
|
|
1635
|
-
|
|
1636
|
-
pollMaxDebounces = attempts;
|
|
1637
|
-
}
|
|
1638
|
-
const { applied: tablesDBApplied, resyncNeeded } = await checkAndApplyTablesDBChanges();
|
|
1402
|
+
const { resyncNeeded } = await checkAndApplyTablesDBChanges();
|
|
1639
1403
|
if (resyncNeeded) {
|
|
1640
|
-
log("Resyncing configuration due to
|
|
1404
|
+
log("Resyncing configuration due to tables deletions ...");
|
|
1641
1405
|
const remoteTablesDBs = (await paginate(async (args) => {
|
|
1642
|
-
const
|
|
1643
|
-
return await
|
|
1406
|
+
const tablesService = await getTablesDBService();
|
|
1407
|
+
return await tablesService.list(args.queries || []);
|
|
1644
1408
|
}, {}, 100, "databases")).databases;
|
|
1645
1409
|
const localTablesDBs = localConfig.getTablesDBs();
|
|
1646
1410
|
const remoteDatabaseIds = new Set(remoteTablesDBs.map((db) => db.$id));
|
|
@@ -1659,8 +1423,8 @@ const pushTable = async ({ attempts, } = {}) => {
|
|
|
1659
1423
|
for (const db of localTablesDBs) {
|
|
1660
1424
|
try {
|
|
1661
1425
|
const { tables: remoteTables } = await paginate(async (args) => {
|
|
1662
|
-
const
|
|
1663
|
-
return await
|
|
1426
|
+
const tablesService = await getTablesDBService();
|
|
1427
|
+
return await tablesService.listTables(args.databaseId, args.queries || []);
|
|
1664
1428
|
}, {
|
|
1665
1429
|
databaseId: db.$id,
|
|
1666
1430
|
}, 100, "tables");
|
|
@@ -1694,8 +1458,8 @@ const pushTable = async ({ attempts, } = {}) => {
|
|
|
1694
1458
|
for (const table of tablesToDelete) {
|
|
1695
1459
|
try {
|
|
1696
1460
|
log(`Deleting table ${table.name} ( ${table.$id} ) from database ${table.databaseName} ...`);
|
|
1697
|
-
const
|
|
1698
|
-
await
|
|
1461
|
+
const tablesService = await getTablesDBService();
|
|
1462
|
+
await tablesService.deleteTable(table.databaseId, table.$id);
|
|
1699
1463
|
success(`Deleted ${table.name} ( ${table.$id} )`);
|
|
1700
1464
|
}
|
|
1701
1465
|
catch (e) {
|
|
@@ -1723,90 +1487,32 @@ const pushTable = async ({ attempts, } = {}) => {
|
|
|
1723
1487
|
}
|
|
1724
1488
|
if (tables.length === 0) {
|
|
1725
1489
|
log("No tables found.");
|
|
1726
|
-
hint(
|
|
1490
|
+
hint(`Use '${EXECUTABLE_NAME} pull tables' to synchronize existing one, or use '${EXECUTABLE_NAME} init table' to create a new one.`);
|
|
1727
1491
|
return;
|
|
1728
1492
|
}
|
|
1729
1493
|
if (!(await approveChanges(tables, async (args) => {
|
|
1730
|
-
const
|
|
1731
|
-
return await
|
|
1494
|
+
const tablesService = await getTablesDBService();
|
|
1495
|
+
return await tablesService.getTable(args.databaseId, args.tableId);
|
|
1732
1496
|
}, KeysTable, "tableId", "tables", ["columns", "indexes"], "databaseId", "databaseId"))) {
|
|
1733
1497
|
return;
|
|
1734
1498
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
await
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
changes.push("enabled");
|
|
1748
|
-
if (JSON.stringify(remoteTable["$permissions"]) !==
|
|
1749
|
-
JSON.stringify(table["$permissions"]))
|
|
1750
|
-
changes.push("permissions");
|
|
1751
|
-
if (changes.length > 0) {
|
|
1752
|
-
await tablesDBService.updateTable(table["databaseId"], table["$id"], table.name, table.rowSecurity, table["$permissions"]);
|
|
1753
|
-
success(`Updated ${table.name} ( ${table["$id"]} ) - ${changes.join(", ")}`);
|
|
1754
|
-
tablesChanged.add(table["$id"]);
|
|
1755
|
-
}
|
|
1756
|
-
table.remoteVersion = remoteTable;
|
|
1757
|
-
table.isExisted = true;
|
|
1758
|
-
}
|
|
1759
|
-
catch (e) {
|
|
1760
|
-
if (Number(e.code) === 404) {
|
|
1761
|
-
log(`Table ${table.name} does not exist in the project. Creating ... `);
|
|
1762
|
-
const tablesDBService = await getTablesDBService();
|
|
1763
|
-
await tablesDBService.createTable(table["databaseId"], table["$id"], table.name, table.rowSecurity, table["$permissions"]);
|
|
1764
|
-
success(`Created ${table.name} ( ${table["$id"]} )`);
|
|
1765
|
-
tablesChanged.add(table["$id"]);
|
|
1766
|
-
}
|
|
1767
|
-
else {
|
|
1768
|
-
throw e;
|
|
1769
|
-
}
|
|
1770
|
-
}
|
|
1771
|
-
}));
|
|
1772
|
-
// Serialize attribute actions
|
|
1773
|
-
for (let table of tables) {
|
|
1774
|
-
let columns = table.columns;
|
|
1775
|
-
let indexes = table.indexes;
|
|
1776
|
-
if (table.isExisted) {
|
|
1777
|
-
columns = await attributesToCreate(table.remoteVersion.columns, table.columns, table);
|
|
1778
|
-
indexes = await attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
|
|
1779
|
-
if (Array.isArray(columns) &&
|
|
1780
|
-
columns.length <= 0 &&
|
|
1781
|
-
Array.isArray(indexes) &&
|
|
1782
|
-
indexes.length <= 0) {
|
|
1783
|
-
continue;
|
|
1784
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
log(`Pushing table ${table.name} ( ${table["databaseId"]} - ${table["$id"]} ) attributes`);
|
|
1787
|
-
try {
|
|
1788
|
-
await createColumns(columns, table);
|
|
1789
|
-
}
|
|
1790
|
-
catch (e) {
|
|
1791
|
-
throw e;
|
|
1792
|
-
}
|
|
1793
|
-
try {
|
|
1794
|
-
await createIndexes(indexes, table);
|
|
1795
|
-
}
|
|
1796
|
-
catch (e) {
|
|
1797
|
-
throw e;
|
|
1798
|
-
}
|
|
1799
|
-
tablesChanged.add(table["$id"]);
|
|
1800
|
-
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));
|
|
1801
1511
|
}
|
|
1802
|
-
success(`Successfully pushed ${tablesChanged.size} tables`);
|
|
1803
1512
|
};
|
|
1804
|
-
const pushCollection = async (
|
|
1805
|
-
warn(
|
|
1513
|
+
const pushCollection = async () => {
|
|
1514
|
+
warn(`${EXECUTABLE_NAME} push collection has been deprecated. Please consider using '${EXECUTABLE_NAME} push tables' instead`);
|
|
1806
1515
|
const collections = [];
|
|
1807
|
-
if (attempts) {
|
|
1808
|
-
pollMaxDebounces = attempts;
|
|
1809
|
-
}
|
|
1810
1516
|
if (cliConfig.all) {
|
|
1811
1517
|
checkDeployConditions(localConfig);
|
|
1812
1518
|
collections.push(...localConfig.getCollections());
|
|
@@ -1826,90 +1532,35 @@ const pushCollection = async ({ attempts }) => {
|
|
|
1826
1532
|
}
|
|
1827
1533
|
if (collections.length === 0) {
|
|
1828
1534
|
log("No collections found.");
|
|
1829
|
-
hint(
|
|
1535
|
+
hint(`Use '${EXECUTABLE_NAME} pull collections' to synchronize existing one, or use '${EXECUTABLE_NAME} init collection' to create a new one.`);
|
|
1830
1536
|
return;
|
|
1831
1537
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
try {
|
|
1838
|
-
const database = await databasesService.get(databaseId);
|
|
1839
|
-
if (database.name !== (localDatabase.name ?? databaseId)) {
|
|
1840
|
-
await databasesService.update(databaseId, localDatabase.name ?? databaseId);
|
|
1841
|
-
success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
catch (err) {
|
|
1845
|
-
log(`Database ${databaseId} not found. Creating it now ...`);
|
|
1846
|
-
await databasesService.create(databaseId, localDatabase.name ?? databaseId);
|
|
1847
|
-
}
|
|
1848
|
-
}));
|
|
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
|
+
});
|
|
1849
1543
|
if (!(await approveChanges(collections, async (args) => {
|
|
1850
1544
|
const databasesService = await getDatabasesService();
|
|
1851
1545
|
return await databasesService.getCollection(args.databaseId, args.collectionId);
|
|
1852
1546
|
}, KeysCollection, "collectionId", "collections", ["attributes", "indexes"], "databaseId", "databaseId"))) {
|
|
1853
1547
|
return;
|
|
1854
1548
|
}
|
|
1855
|
-
|
|
1856
|
-
await
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
catch (e) {
|
|
1868
|
-
if (Number(e.code) === 404) {
|
|
1869
|
-
log(`Collection ${collection.name} does not exist in the project. Creating ... `);
|
|
1870
|
-
const databasesService = await getDatabasesService();
|
|
1871
|
-
await databasesService.createCollection(collection["databaseId"], collection["$id"], collection.name, collection.documentSecurity, collection["$permissions"]);
|
|
1872
|
-
}
|
|
1873
|
-
else {
|
|
1874
|
-
throw e;
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
}));
|
|
1878
|
-
let numberOfCollections = 0;
|
|
1879
|
-
// Serialize attribute actions
|
|
1880
|
-
for (let collection of collections) {
|
|
1881
|
-
let attributes = collection.attributes;
|
|
1882
|
-
let indexes = collection.indexes;
|
|
1883
|
-
if (collection.isExisted) {
|
|
1884
|
-
attributes = await attributesToCreate(collection.remoteVersion.attributes, collection.attributes, collection);
|
|
1885
|
-
indexes = await attributesToCreate(collection.remoteVersion.indexes, collection.indexes, collection, true);
|
|
1886
|
-
if (Array.isArray(attributes) &&
|
|
1887
|
-
attributes.length <= 0 &&
|
|
1888
|
-
Array.isArray(indexes) &&
|
|
1889
|
-
indexes.length <= 0) {
|
|
1890
|
-
continue;
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
log(`Pushing collection ${collection.name} ( ${collection["databaseId"]} - ${collection["$id"]} ) attributes`);
|
|
1894
|
-
try {
|
|
1895
|
-
await createAttributes(attributes, collection);
|
|
1896
|
-
}
|
|
1897
|
-
catch (e) {
|
|
1898
|
-
throw e;
|
|
1899
|
-
}
|
|
1900
|
-
try {
|
|
1901
|
-
await createIndexes(indexes, collection);
|
|
1902
|
-
}
|
|
1903
|
-
catch (e) {
|
|
1904
|
-
throw e;
|
|
1905
|
-
}
|
|
1906
|
-
numberOfCollections++;
|
|
1907
|
-
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));
|
|
1908
1561
|
}
|
|
1909
|
-
success(`Successfully pushed ${numberOfCollections} collections`);
|
|
1910
1562
|
};
|
|
1911
1563
|
const pushBucket = async () => {
|
|
1912
|
-
let response = {};
|
|
1913
1564
|
let bucketIds = [];
|
|
1914
1565
|
const configBuckets = localConfig.getBuckets();
|
|
1915
1566
|
if (cliConfig.all) {
|
|
@@ -1924,7 +1575,7 @@ const pushBucket = async () => {
|
|
|
1924
1575
|
}
|
|
1925
1576
|
if (bucketIds.length === 0) {
|
|
1926
1577
|
log("No buckets found.");
|
|
1927
|
-
hint(
|
|
1578
|
+
hint(`Use '${EXECUTABLE_NAME} pull buckets' to synchronize existing one, or use '${EXECUTABLE_NAME} init bucket' to create a new one.`);
|
|
1928
1579
|
return;
|
|
1929
1580
|
}
|
|
1930
1581
|
let buckets = [];
|
|
@@ -1939,27 +1590,20 @@ const pushBucket = async () => {
|
|
|
1939
1590
|
return;
|
|
1940
1591
|
}
|
|
1941
1592
|
log("Pushing buckets ...");
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
}
|
|
1954
|
-
else {
|
|
1955
|
-
throw e;
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
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));
|
|
1958
1604
|
}
|
|
1959
|
-
success(`Successfully pushed ${buckets.length} buckets.`);
|
|
1960
1605
|
};
|
|
1961
1606
|
const pushTeam = async () => {
|
|
1962
|
-
let response = {};
|
|
1963
1607
|
let teamIds = [];
|
|
1964
1608
|
const configTeams = localConfig.getTeams();
|
|
1965
1609
|
if (cliConfig.all) {
|
|
@@ -1974,7 +1618,7 @@ const pushTeam = async () => {
|
|
|
1974
1618
|
}
|
|
1975
1619
|
if (teamIds.length === 0) {
|
|
1976
1620
|
log("No teams found.");
|
|
1977
|
-
hint(
|
|
1621
|
+
hint(`Use '${EXECUTABLE_NAME} pull teams' to synchronize existing one, or use '${EXECUTABLE_NAME} init team' to create a new one.`);
|
|
1978
1622
|
return;
|
|
1979
1623
|
}
|
|
1980
1624
|
let teams = [];
|
|
@@ -1989,27 +1633,20 @@ const pushTeam = async () => {
|
|
|
1989
1633
|
return;
|
|
1990
1634
|
}
|
|
1991
1635
|
log("Pushing teams ...");
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
}
|
|
2004
|
-
else {
|
|
2005
|
-
throw e;
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
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));
|
|
2008
1647
|
}
|
|
2009
|
-
success(`Successfully pushed ${teams.length} teams.`);
|
|
2010
1648
|
};
|
|
2011
1649
|
const pushMessagingTopic = async () => {
|
|
2012
|
-
let response = {};
|
|
2013
1650
|
let topicsIds = [];
|
|
2014
1651
|
const configTopics = localConfig.getMessagingTopics();
|
|
2015
1652
|
if (cliConfig.all) {
|
|
@@ -2024,7 +1661,7 @@ const pushMessagingTopic = async () => {
|
|
|
2024
1661
|
}
|
|
2025
1662
|
if (topicsIds.length === 0) {
|
|
2026
1663
|
log("No topics found.");
|
|
2027
|
-
hint(
|
|
1664
|
+
hint(`Use '${EXECUTABLE_NAME} pull topics' to synchronize existing one, or use '${EXECUTABLE_NAME} init topic' to create a new one.`);
|
|
2028
1665
|
return;
|
|
2029
1666
|
}
|
|
2030
1667
|
let topics = [];
|
|
@@ -2039,26 +1676,18 @@ const pushMessagingTopic = async () => {
|
|
|
2039
1676
|
return;
|
|
2040
1677
|
}
|
|
2041
1678
|
log("Pushing topics ...");
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
response = await messagingService.createTopic(topic["$id"], topic.name, topic.subscribe);
|
|
2054
|
-
success(`Created ${topic.name} ( ${topic["$id"]} )`);
|
|
2055
|
-
}
|
|
2056
|
-
else {
|
|
2057
|
-
throw e;
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
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));
|
|
2060
1690
|
}
|
|
2061
|
-
success(`Successfully pushed ${topics.length} topics.`);
|
|
2062
1691
|
};
|
|
2063
1692
|
export const push = new Command("push")
|
|
2064
1693
|
.description(commandDescriptions["push"])
|
|
@@ -2120,8 +1749,8 @@ push
|
|
|
2120
1749
|
.description("Push messaging topics in the current project.")
|
|
2121
1750
|
.action(actionRunner(pushMessagingTopic));
|
|
2122
1751
|
export const deploy = new Command("deploy")
|
|
2123
|
-
.description(
|
|
1752
|
+
.description(`Removed. Use ${EXECUTABLE_NAME} push instead`)
|
|
2124
1753
|
.action(actionRunner(async () => {
|
|
2125
|
-
warn(
|
|
1754
|
+
warn(`${EXECUTABLE_NAME} deploy has been removed. Please use '${EXECUTABLE_NAME} push' instead`);
|
|
2126
1755
|
}));
|
|
2127
1756
|
//# sourceMappingURL=push.js.map
|