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
package/lib/commands/push.ts
CHANGED
|
@@ -4,21 +4,23 @@ 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 { EXECUTABLE_NAME } from "../constants.js";
|
|
7
8
|
import {
|
|
8
9
|
localConfig,
|
|
9
10
|
globalConfig,
|
|
10
|
-
KeysAttributes,
|
|
11
11
|
KeysFunction,
|
|
12
12
|
KeysSite,
|
|
13
|
-
whitelistKeys,
|
|
14
13
|
KeysTopics,
|
|
15
14
|
KeysStorage,
|
|
16
15
|
KeysTeams,
|
|
17
16
|
KeysCollection,
|
|
18
17
|
KeysTable,
|
|
19
18
|
} from "../config.js";
|
|
20
|
-
import {
|
|
19
|
+
import type { SettingsType, ConfigType } from "./config.js";
|
|
20
|
+
import { createSettingsObject } from "../utils.js";
|
|
21
|
+
import { Spinner, SPINNER_DOTS } from "../spinner.js";
|
|
21
22
|
import { paginate } from "../paginate.js";
|
|
23
|
+
import { pushDeployment } from "./utils/deployment.js";
|
|
22
24
|
import {
|
|
23
25
|
questionsPushBuckets,
|
|
24
26
|
questionsPushTeams,
|
|
@@ -27,8 +29,6 @@ import {
|
|
|
27
29
|
questionsGetEntrypoint,
|
|
28
30
|
questionsPushCollections,
|
|
29
31
|
questionsPushTables,
|
|
30
|
-
questionPushChanges,
|
|
31
|
-
questionPushChangesConfirmation,
|
|
32
32
|
questionsPushMessagingTopics,
|
|
33
33
|
questionsPushResources,
|
|
34
34
|
} from "../questions.js";
|
|
@@ -55,44 +55,53 @@ import {
|
|
|
55
55
|
getTeamsService,
|
|
56
56
|
getProjectsService,
|
|
57
57
|
} from "../services.js";
|
|
58
|
-
import {
|
|
58
|
+
import { sdkForProject, sdkForConsole } from "../sdks.js";
|
|
59
|
+
import {
|
|
60
|
+
ApiService,
|
|
61
|
+
AuthMethod,
|
|
62
|
+
AppwriteException,
|
|
63
|
+
Client,
|
|
64
|
+
Query,
|
|
65
|
+
} from "@appwrite.io/console";
|
|
59
66
|
import { checkDeployConditions } from "../utils.js";
|
|
67
|
+
import { Pools } from "./utils/pools.js";
|
|
68
|
+
import { Attributes, Collection } from "./utils/attributes.js";
|
|
69
|
+
import {
|
|
70
|
+
getConfirmation,
|
|
71
|
+
approveChanges,
|
|
72
|
+
getObjectChanges,
|
|
73
|
+
} from "./utils/change-approval.js";
|
|
74
|
+
import { checkAndApplyTablesDBChanges } from "./utils/database-sync.js";
|
|
60
75
|
|
|
61
|
-
const STEP_SIZE = 100; // Resources
|
|
62
76
|
const POLL_DEBOUNCE = 2000; // Milliseconds
|
|
63
77
|
const POLL_DEFAULT_VALUE = 30;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
interface ObjectChange {
|
|
79
|
-
group: string;
|
|
80
|
-
setting: string;
|
|
81
|
-
remote: string;
|
|
82
|
-
local: string;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
type ComparableValue = boolean | number | string | any[] | undefined;
|
|
86
|
-
|
|
87
|
-
interface AttributeChange {
|
|
88
|
-
key: string;
|
|
89
|
-
attribute: any;
|
|
90
|
-
reason: string;
|
|
91
|
-
action: string;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
interface PushResourcesOptions {
|
|
78
|
+
const DEPLOYMENT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
|
|
79
|
+
|
|
80
|
+
export interface PushOptions {
|
|
81
|
+
all?: boolean;
|
|
82
|
+
settings?: boolean;
|
|
83
|
+
functions?: boolean;
|
|
84
|
+
sites?: boolean;
|
|
85
|
+
collections?: boolean;
|
|
86
|
+
tables?: boolean;
|
|
87
|
+
buckets?: boolean;
|
|
88
|
+
teams?: boolean;
|
|
89
|
+
topics?: boolean;
|
|
95
90
|
skipDeprecated?: boolean;
|
|
91
|
+
skipConfirmation?: boolean;
|
|
92
|
+
functionOptions?: {
|
|
93
|
+
async?: boolean;
|
|
94
|
+
code?: boolean;
|
|
95
|
+
withVariables?: boolean;
|
|
96
|
+
};
|
|
97
|
+
siteOptions?: {
|
|
98
|
+
async?: boolean;
|
|
99
|
+
code?: boolean;
|
|
100
|
+
withVariables?: boolean;
|
|
101
|
+
};
|
|
102
|
+
tableOptions?: {
|
|
103
|
+
attempts?: number;
|
|
104
|
+
};
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
interface PushSiteOptions {
|
|
@@ -109,1473 +118,890 @@ interface PushFunctionOptions {
|
|
|
109
118
|
withVariables?: boolean;
|
|
110
119
|
}
|
|
111
120
|
|
|
112
|
-
interface TablesDBChangesResult {
|
|
113
|
-
applied: boolean;
|
|
114
|
-
resyncNeeded: boolean;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
121
|
interface PushTableOptions {
|
|
118
122
|
attempts?: number;
|
|
123
|
+
skipConfirmation?: boolean;
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
iteration?: number,
|
|
126
|
-
) => Promise<boolean>;
|
|
127
|
-
|
|
128
|
-
wipeIndexes: (
|
|
129
|
-
databaseId: string,
|
|
130
|
-
collectionId: string,
|
|
131
|
-
iteration?: number,
|
|
132
|
-
) => Promise<boolean>;
|
|
133
|
-
|
|
134
|
-
deleteAttributes: (
|
|
135
|
-
databaseId: string,
|
|
136
|
-
collectionId: string,
|
|
137
|
-
attributeKeys: any[],
|
|
138
|
-
iteration?: number,
|
|
139
|
-
) => Promise<boolean>;
|
|
140
|
-
|
|
141
|
-
expectAttributes: (
|
|
142
|
-
databaseId: string,
|
|
143
|
-
collectionId: string,
|
|
144
|
-
attributeKeys: string[],
|
|
145
|
-
iteration?: number,
|
|
146
|
-
) => Promise<boolean>;
|
|
147
|
-
|
|
148
|
-
deleteIndexes: (
|
|
149
|
-
databaseId: string,
|
|
150
|
-
collectionId: string,
|
|
151
|
-
indexesKeys: any[],
|
|
152
|
-
iteration?: number,
|
|
153
|
-
) => Promise<boolean>;
|
|
154
|
-
|
|
155
|
-
expectIndexes: (
|
|
156
|
-
databaseId: string,
|
|
157
|
-
collectionId: string,
|
|
158
|
-
indexKeys: string[],
|
|
159
|
-
iteration?: number,
|
|
160
|
-
) => Promise<boolean>;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const awaitPools: AwaitPools = {
|
|
164
|
-
wipeAttributes: async (
|
|
165
|
-
databaseId: string,
|
|
166
|
-
collectionId: string,
|
|
167
|
-
iteration: number = 1,
|
|
168
|
-
): Promise<boolean> => {
|
|
169
|
-
if (iteration > pollMaxDebounces) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
126
|
+
export class Push {
|
|
127
|
+
private projectClient: Client;
|
|
128
|
+
private consoleClient: Client;
|
|
129
|
+
private silent: boolean;
|
|
172
130
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
);
|
|
179
|
-
const { total } = response;
|
|
131
|
+
constructor(projectClient: Client, consoleClient: Client, silent = false) {
|
|
132
|
+
this.projectClient = projectClient;
|
|
133
|
+
this.consoleClient = consoleClient;
|
|
134
|
+
this.silent = silent;
|
|
135
|
+
}
|
|
180
136
|
|
|
181
|
-
|
|
182
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Log a message (respects silent mode)
|
|
139
|
+
*/
|
|
140
|
+
private log(message: string): void {
|
|
141
|
+
if (!this.silent) {
|
|
142
|
+
log(message);
|
|
183
143
|
}
|
|
144
|
+
}
|
|
184
145
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
"Found a large number of attributes, increasing timeout to " +
|
|
192
|
-
(pollMaxDebounces * POLL_DEBOUNCE) / 1000 / 60 +
|
|
193
|
-
" minutes",
|
|
194
|
-
);
|
|
195
|
-
}
|
|
146
|
+
/**
|
|
147
|
+
* Log a success message (respects silent mode)
|
|
148
|
+
*/
|
|
149
|
+
private success(message: string): void {
|
|
150
|
+
if (!this.silent) {
|
|
151
|
+
success(message);
|
|
196
152
|
}
|
|
153
|
+
}
|
|
197
154
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
);
|
|
205
|
-
},
|
|
206
|
-
wipeIndexes: async (
|
|
207
|
-
databaseId: string,
|
|
208
|
-
collectionId: string,
|
|
209
|
-
iteration: number = 1,
|
|
210
|
-
): Promise<boolean> => {
|
|
211
|
-
if (iteration > pollMaxDebounces) {
|
|
212
|
-
return false;
|
|
155
|
+
/**
|
|
156
|
+
* Log a warning message (respects silent mode)
|
|
157
|
+
*/
|
|
158
|
+
private warn(message: string): void {
|
|
159
|
+
if (!this.silent) {
|
|
160
|
+
warn(message);
|
|
213
161
|
}
|
|
162
|
+
}
|
|
214
163
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const { total } = response;
|
|
222
|
-
|
|
223
|
-
if (total === 0) {
|
|
224
|
-
return true;
|
|
164
|
+
/**
|
|
165
|
+
* Log an error message (respects silent mode)
|
|
166
|
+
*/
|
|
167
|
+
private error(message: string): void {
|
|
168
|
+
if (!this.silent) {
|
|
169
|
+
error(message);
|
|
225
170
|
}
|
|
171
|
+
}
|
|
226
172
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
173
|
+
public async pushResources(
|
|
174
|
+
config: ConfigType,
|
|
175
|
+
options: PushOptions = { all: true, skipDeprecated: true },
|
|
176
|
+
): Promise<{
|
|
177
|
+
results: Record<string, any>;
|
|
178
|
+
errors: any[];
|
|
179
|
+
}> {
|
|
180
|
+
const { skipDeprecated = true } = options;
|
|
181
|
+
const results: Record<string, any> = {};
|
|
182
|
+
const allErrors: any[] = [];
|
|
183
|
+
const shouldPushAll = options.all === true;
|
|
231
184
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
185
|
+
// Push settings
|
|
186
|
+
if (
|
|
187
|
+
(shouldPushAll || options.settings) &&
|
|
188
|
+
(config.projectName || config.settings)
|
|
189
|
+
) {
|
|
190
|
+
try {
|
|
191
|
+
this.log("Pushing settings ...");
|
|
192
|
+
await this.pushSettings({
|
|
193
|
+
projectId: config.projectId,
|
|
194
|
+
projectName: config.projectName,
|
|
195
|
+
settings: config.settings,
|
|
196
|
+
});
|
|
197
|
+
this.success(
|
|
198
|
+
`Successfully pushed ${chalk.bold("all")} project settings.`,
|
|
236
199
|
);
|
|
200
|
+
results.settings = { success: true };
|
|
201
|
+
} catch (e: any) {
|
|
202
|
+
allErrors.push(e);
|
|
203
|
+
results.settings = { success: false, error: e.message };
|
|
237
204
|
}
|
|
238
205
|
}
|
|
239
206
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
attributeKeys: any[],
|
|
252
|
-
iteration: number = 1,
|
|
253
|
-
): Promise<boolean> => {
|
|
254
|
-
if (iteration > pollMaxDebounces) {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
|
|
259
|
-
let steps = Math.max(1, Math.ceil(attributeKeys.length / STEP_SIZE));
|
|
260
|
-
if (steps > 1 && iteration === 1) {
|
|
261
|
-
pollMaxDebounces *= steps;
|
|
262
|
-
|
|
263
|
-
log(
|
|
264
|
-
"Found a large number of attributes to be deleted. Increasing timeout to " +
|
|
265
|
-
(pollMaxDebounces * POLL_DEBOUNCE) / 1000 / 60 +
|
|
266
|
-
" minutes",
|
|
207
|
+
// Push buckets
|
|
208
|
+
if (
|
|
209
|
+
(shouldPushAll || options.buckets) &&
|
|
210
|
+
config.buckets &&
|
|
211
|
+
config.buckets.length > 0
|
|
212
|
+
) {
|
|
213
|
+
try {
|
|
214
|
+
this.log("Pushing buckets ...");
|
|
215
|
+
const result = await this.pushBuckets(config.buckets);
|
|
216
|
+
this.success(
|
|
217
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} buckets.`,
|
|
267
218
|
);
|
|
219
|
+
results.buckets = result;
|
|
220
|
+
allErrors.push(...result.errors);
|
|
221
|
+
} catch (e: any) {
|
|
222
|
+
allErrors.push(e);
|
|
223
|
+
results.buckets = { successfullyPushed: 0, errors: [e] };
|
|
268
224
|
}
|
|
269
225
|
}
|
|
270
226
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
227
|
+
// Push teams
|
|
228
|
+
if (
|
|
229
|
+
(shouldPushAll || options.teams) &&
|
|
230
|
+
config.teams &&
|
|
231
|
+
config.teams.length > 0
|
|
232
|
+
) {
|
|
233
|
+
try {
|
|
234
|
+
this.log("Pushing teams ...");
|
|
235
|
+
const result = await this.pushTeams(config.teams);
|
|
236
|
+
this.success(
|
|
237
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} teams.`,
|
|
278
238
|
);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
"attributes",
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
const ready = attributeKeys.filter((attribute: any) =>
|
|
289
|
-
attributes.includes(attribute.key),
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
if (ready.length === 0) {
|
|
293
|
-
return true;
|
|
239
|
+
results.teams = result;
|
|
240
|
+
allErrors.push(...result.errors);
|
|
241
|
+
} catch (e: any) {
|
|
242
|
+
allErrors.push(e);
|
|
243
|
+
results.teams = { successfullyPushed: 0, errors: [e] };
|
|
244
|
+
}
|
|
294
245
|
}
|
|
295
246
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
247
|
+
// Push messaging topics
|
|
248
|
+
if (
|
|
249
|
+
(shouldPushAll || options.topics) &&
|
|
250
|
+
config.topics &&
|
|
251
|
+
config.topics.length > 0
|
|
252
|
+
) {
|
|
253
|
+
try {
|
|
254
|
+
this.log("Pushing topics ...");
|
|
255
|
+
const result = await this.pushMessagingTopics(config.topics);
|
|
256
|
+
this.success(
|
|
257
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} topics.`,
|
|
258
|
+
);
|
|
259
|
+
results.topics = result;
|
|
260
|
+
allErrors.push(...result.errors);
|
|
261
|
+
} catch (e: any) {
|
|
262
|
+
allErrors.push(e);
|
|
263
|
+
results.topics = { successfullyPushed: 0, errors: [e] };
|
|
264
|
+
}
|
|
313
265
|
}
|
|
314
266
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
267
|
+
// Push functions
|
|
268
|
+
if (
|
|
269
|
+
(shouldPushAll || options.functions) &&
|
|
270
|
+
config.functions &&
|
|
271
|
+
config.functions.length > 0
|
|
272
|
+
) {
|
|
273
|
+
try {
|
|
274
|
+
this.log("Pushing functions ...");
|
|
275
|
+
const result = await this.pushFunctions(
|
|
276
|
+
config.functions,
|
|
277
|
+
options.functionOptions,
|
|
324
278
|
);
|
|
279
|
+
this.success(
|
|
280
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} functions.`,
|
|
281
|
+
);
|
|
282
|
+
results.functions = result;
|
|
283
|
+
allErrors.push(...result.errors);
|
|
284
|
+
} catch (e: any) {
|
|
285
|
+
allErrors.push(e);
|
|
286
|
+
results.functions = {
|
|
287
|
+
successfullyPushed: 0,
|
|
288
|
+
successfullyDeployed: 0,
|
|
289
|
+
failedDeployments: [],
|
|
290
|
+
errors: [e],
|
|
291
|
+
};
|
|
325
292
|
}
|
|
326
293
|
}
|
|
327
294
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
295
|
+
// Push sites
|
|
296
|
+
if (
|
|
297
|
+
(shouldPushAll || options.sites) &&
|
|
298
|
+
config.sites &&
|
|
299
|
+
config.sites.length > 0
|
|
300
|
+
) {
|
|
301
|
+
try {
|
|
302
|
+
this.log("Pushing sites ...");
|
|
303
|
+
const result = await this.pushSites(config.sites, options.siteOptions);
|
|
304
|
+
this.success(
|
|
305
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} sites.`,
|
|
335
306
|
);
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
if (attributeKeys.includes(attribute.key)) {
|
|
348
|
-
if (["stuck", "failed"].includes(attribute.status)) {
|
|
349
|
-
throw new Error(`Attribute '${attribute.key}' failed!`);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return attribute.status === "available";
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return false;
|
|
356
|
-
})
|
|
357
|
-
.map((attribute: any) => attribute.key);
|
|
358
|
-
|
|
359
|
-
if (ready.length === attributeKeys.length) {
|
|
360
|
-
return true;
|
|
307
|
+
results.sites = result;
|
|
308
|
+
allErrors.push(...result.errors);
|
|
309
|
+
} catch (e: any) {
|
|
310
|
+
allErrors.push(e);
|
|
311
|
+
results.sites = {
|
|
312
|
+
successfullyPushed: 0,
|
|
313
|
+
successfullyDeployed: 0,
|
|
314
|
+
failedDeployments: [],
|
|
315
|
+
errors: [e],
|
|
316
|
+
};
|
|
317
|
+
}
|
|
361
318
|
}
|
|
362
319
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
320
|
+
// Push tables
|
|
321
|
+
if (
|
|
322
|
+
(shouldPushAll || options.tables) &&
|
|
323
|
+
config.tables &&
|
|
324
|
+
config.tables.length > 0
|
|
325
|
+
) {
|
|
326
|
+
try {
|
|
327
|
+
this.log("Pushing tables ...");
|
|
328
|
+
const result = await this.pushTables(config.tables, {
|
|
329
|
+
attempts: options.tableOptions?.attempts,
|
|
330
|
+
skipConfirmation: options.skipConfirmation,
|
|
331
|
+
});
|
|
332
|
+
this.success(
|
|
333
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} tables.`,
|
|
334
|
+
);
|
|
335
|
+
results.tables = result;
|
|
336
|
+
allErrors.push(...result.errors);
|
|
337
|
+
} catch (e: any) {
|
|
338
|
+
allErrors.push(e);
|
|
339
|
+
results.tables = { successfullyPushed: 0, errors: [e] };
|
|
340
|
+
}
|
|
380
341
|
}
|
|
381
342
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
343
|
+
// Push collections (skipDeprecated only applies when pushing all, explicit collections option takes precedence)
|
|
344
|
+
if (
|
|
345
|
+
(options.collections || (shouldPushAll && !skipDeprecated)) &&
|
|
346
|
+
config.collections &&
|
|
347
|
+
config.collections.length > 0
|
|
348
|
+
) {
|
|
349
|
+
try {
|
|
350
|
+
this.log("Pushing collections ...");
|
|
351
|
+
// Add database names to collections
|
|
352
|
+
const collectionsWithDbNames = config.collections.map(
|
|
353
|
+
(collection: any) => {
|
|
354
|
+
const database = config.databases?.find(
|
|
355
|
+
(db: any) => db.$id === collection.databaseId,
|
|
356
|
+
);
|
|
357
|
+
return {
|
|
358
|
+
...collection,
|
|
359
|
+
databaseName: database?.name ?? collection.databaseId,
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
);
|
|
363
|
+
const result = await this.pushCollections(collectionsWithDbNames, {
|
|
364
|
+
skipConfirmation: options.skipConfirmation,
|
|
365
|
+
});
|
|
366
|
+
this.success(
|
|
367
|
+
`Successfully pushed ${chalk.bold(result.successfullyPushed)} collections.`,
|
|
391
368
|
);
|
|
369
|
+
results.collections = result;
|
|
370
|
+
allErrors.push(...result.errors);
|
|
371
|
+
} catch (e: any) {
|
|
372
|
+
allErrors.push(e);
|
|
373
|
+
results.collections = { successfullyPushed: 0, errors: [e] };
|
|
392
374
|
}
|
|
393
375
|
}
|
|
394
376
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
args.collectionId,
|
|
401
|
-
args.queries || [],
|
|
402
|
-
);
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
databaseId,
|
|
406
|
-
collectionId,
|
|
407
|
-
},
|
|
408
|
-
100,
|
|
409
|
-
"indexes",
|
|
410
|
-
);
|
|
377
|
+
return {
|
|
378
|
+
results,
|
|
379
|
+
errors: allErrors,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
411
382
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
383
|
+
public async pushSettings(config: {
|
|
384
|
+
projectId: string;
|
|
385
|
+
projectName?: string;
|
|
386
|
+
settings?: SettingsType;
|
|
387
|
+
}): Promise<void> {
|
|
388
|
+
const projectsService = await getProjectsService(this.consoleClient);
|
|
389
|
+
const projectId = config.projectId;
|
|
390
|
+
const projectName = config.projectName;
|
|
391
|
+
const settings = config.settings ?? {};
|
|
415
392
|
|
|
416
|
-
if (
|
|
417
|
-
|
|
393
|
+
if (projectName) {
|
|
394
|
+
this.log("Applying project name ...");
|
|
395
|
+
await projectsService.update({
|
|
396
|
+
projectId: projectId,
|
|
397
|
+
name: projectName,
|
|
398
|
+
});
|
|
418
399
|
}
|
|
419
400
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
expectIndexes: async (
|
|
430
|
-
databaseId: string,
|
|
431
|
-
collectionId: string,
|
|
432
|
-
indexKeys: string[],
|
|
433
|
-
iteration: number = 1,
|
|
434
|
-
): Promise<boolean> => {
|
|
435
|
-
if (iteration > pollMaxDebounces) {
|
|
436
|
-
return false;
|
|
401
|
+
if (settings.services) {
|
|
402
|
+
this.log("Applying service statuses ...");
|
|
403
|
+
for (let [service, status] of Object.entries(settings.services)) {
|
|
404
|
+
await projectsService.updateServiceStatus({
|
|
405
|
+
projectId: projectId,
|
|
406
|
+
service: service as ApiService,
|
|
407
|
+
status: status,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
437
410
|
}
|
|
438
411
|
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
412
|
+
if (settings.auth) {
|
|
413
|
+
if (settings.auth.security) {
|
|
414
|
+
this.log("Applying auth security settings ...");
|
|
415
|
+
await projectsService.updateAuthDuration({
|
|
416
|
+
projectId,
|
|
417
|
+
duration: settings.auth.security.duration,
|
|
418
|
+
});
|
|
419
|
+
await projectsService.updateAuthLimit({
|
|
420
|
+
projectId,
|
|
421
|
+
limit: settings.auth.security.limit,
|
|
422
|
+
});
|
|
423
|
+
await projectsService.updateAuthSessionsLimit({
|
|
424
|
+
projectId,
|
|
425
|
+
limit: settings.auth.security.sessionsLimit,
|
|
426
|
+
});
|
|
427
|
+
await projectsService.updateAuthPasswordDictionary({
|
|
428
|
+
projectId,
|
|
429
|
+
enabled: settings.auth.security.passwordDictionary,
|
|
430
|
+
});
|
|
431
|
+
await projectsService.updateAuthPasswordHistory({
|
|
432
|
+
projectId,
|
|
433
|
+
limit: settings.auth.security.passwordHistory,
|
|
434
|
+
});
|
|
435
|
+
await projectsService.updatePersonalDataCheck({
|
|
436
|
+
projectId,
|
|
437
|
+
enabled: settings.auth.security.personalDataCheck,
|
|
438
|
+
});
|
|
439
|
+
await projectsService.updateSessionAlerts({
|
|
440
|
+
projectId,
|
|
441
|
+
alerts: settings.auth.security.sessionAlerts,
|
|
442
|
+
});
|
|
443
|
+
await projectsService.updateMockNumbers({
|
|
444
|
+
projectId,
|
|
445
|
+
numbers: settings.auth.security.mockNumbers,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
443
448
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
+
if (settings.auth.methods) {
|
|
450
|
+
this.log("Applying auth methods statuses ...");
|
|
451
|
+
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
452
|
+
await projectsService.updateAuthStatus({
|
|
453
|
+
projectId,
|
|
454
|
+
method: method as AuthMethod,
|
|
455
|
+
status: status,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
449
458
|
}
|
|
450
459
|
}
|
|
460
|
+
}
|
|
451
461
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
args.queries || [],
|
|
459
|
-
);
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
databaseId,
|
|
463
|
-
collectionId,
|
|
464
|
-
},
|
|
465
|
-
100,
|
|
466
|
-
"indexes",
|
|
467
|
-
);
|
|
462
|
+
public async pushBuckets(buckets: any[]): Promise<{
|
|
463
|
+
successfullyPushed: number;
|
|
464
|
+
errors: any[];
|
|
465
|
+
}> {
|
|
466
|
+
let successfullyPushed = 0;
|
|
467
|
+
const errors: any[] = [];
|
|
468
468
|
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
throw new Error(`Index '${index.key}' failed!`);
|
|
474
|
-
}
|
|
469
|
+
for (const bucket of buckets) {
|
|
470
|
+
try {
|
|
471
|
+
this.log(`Pushing bucket ${chalk.bold(bucket["name"])} ...`);
|
|
472
|
+
const storageService = await getStorageService(this.projectClient);
|
|
475
473
|
|
|
476
|
-
|
|
474
|
+
try {
|
|
475
|
+
await storageService.getBucket(bucket["$id"]);
|
|
476
|
+
await storageService.updateBucket({
|
|
477
|
+
bucketId: bucket["$id"],
|
|
478
|
+
name: bucket.name,
|
|
479
|
+
permissions: bucket["$permissions"],
|
|
480
|
+
fileSecurity: bucket.fileSecurity,
|
|
481
|
+
enabled: bucket.enabled,
|
|
482
|
+
maximumFileSize: bucket.maximumFileSize,
|
|
483
|
+
allowedFileExtensions: bucket.allowedFileExtensions,
|
|
484
|
+
encryption: bucket.encryption,
|
|
485
|
+
antivirus: bucket.antivirus,
|
|
486
|
+
compression: bucket.compression,
|
|
487
|
+
});
|
|
488
|
+
} catch (e: unknown) {
|
|
489
|
+
if (e instanceof AppwriteException && Number(e.code) === 404) {
|
|
490
|
+
await storageService.createBucket({
|
|
491
|
+
bucketId: bucket["$id"],
|
|
492
|
+
name: bucket.name,
|
|
493
|
+
permissions: bucket["$permissions"],
|
|
494
|
+
fileSecurity: bucket.fileSecurity,
|
|
495
|
+
enabled: bucket.enabled,
|
|
496
|
+
maximumFileSize: bucket.maximumFileSize,
|
|
497
|
+
allowedFileExtensions: bucket.allowedFileExtensions,
|
|
498
|
+
compression: bucket.compression,
|
|
499
|
+
encryption: bucket.encryption,
|
|
500
|
+
antivirus: bucket.antivirus,
|
|
501
|
+
});
|
|
502
|
+
} else {
|
|
503
|
+
throw e;
|
|
504
|
+
}
|
|
477
505
|
}
|
|
478
506
|
|
|
479
|
-
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
return true;
|
|
507
|
+
successfullyPushed++;
|
|
508
|
+
} catch (e: any) {
|
|
509
|
+
errors.push(e);
|
|
510
|
+
this.error(`Failed to push bucket ${bucket["name"]}: ${e.message}`);
|
|
511
|
+
}
|
|
485
512
|
}
|
|
486
513
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
collectionId,
|
|
492
|
-
indexKeys,
|
|
493
|
-
iteration + 1,
|
|
494
|
-
);
|
|
495
|
-
},
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
const getConfirmation = async (): Promise<boolean> => {
|
|
499
|
-
if (cliConfig.force) {
|
|
500
|
-
return true;
|
|
514
|
+
return {
|
|
515
|
+
successfullyPushed,
|
|
516
|
+
errors,
|
|
517
|
+
};
|
|
501
518
|
}
|
|
502
519
|
|
|
503
|
-
async
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
520
|
+
public async pushTeams(teams: any[]): Promise<{
|
|
521
|
+
successfullyPushed: number;
|
|
522
|
+
errors: any[];
|
|
523
|
+
}> {
|
|
524
|
+
let successfullyPushed = 0;
|
|
525
|
+
const errors: any[] = [];
|
|
508
526
|
|
|
509
|
-
|
|
510
|
-
|
|
527
|
+
for (const team of teams) {
|
|
528
|
+
try {
|
|
529
|
+
this.log(`Pushing team ${chalk.bold(team["name"])} ...`);
|
|
530
|
+
const teamsService = await getTeamsService(this.projectClient);
|
|
511
531
|
|
|
512
|
-
|
|
532
|
+
try {
|
|
533
|
+
await teamsService.get(team["$id"]);
|
|
534
|
+
await teamsService.updateName({
|
|
535
|
+
teamId: team["$id"],
|
|
536
|
+
name: team.name,
|
|
537
|
+
});
|
|
538
|
+
} catch (e: unknown) {
|
|
539
|
+
if (e instanceof AppwriteException && Number(e.code) === 404) {
|
|
540
|
+
await teamsService.create({
|
|
541
|
+
teamId: team["$id"],
|
|
542
|
+
name: team.name,
|
|
543
|
+
});
|
|
544
|
+
} else {
|
|
545
|
+
throw e;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
513
548
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
549
|
+
successfullyPushed++;
|
|
550
|
+
} catch (e: any) {
|
|
551
|
+
errors.push(e);
|
|
552
|
+
this.error(`Failed to push team ${team["name"]}: ${e.message}`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
517
555
|
|
|
518
|
-
|
|
519
|
-
|
|
556
|
+
return {
|
|
557
|
+
successfullyPushed,
|
|
558
|
+
errors,
|
|
559
|
+
};
|
|
520
560
|
}
|
|
521
561
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const approveChanges = async (
|
|
532
|
-
resource: any[],
|
|
533
|
-
resourceGetFunction: Function,
|
|
534
|
-
keys: Set<string>,
|
|
535
|
-
resourceName: string,
|
|
536
|
-
resourcePlural: string,
|
|
537
|
-
skipKeys: string[] = [],
|
|
538
|
-
secondId: string = "",
|
|
539
|
-
secondResourceName: string = "",
|
|
540
|
-
): Promise<boolean> => {
|
|
541
|
-
log("Checking for changes ...");
|
|
542
|
-
const changes: any[] = [];
|
|
543
|
-
|
|
544
|
-
await Promise.all(
|
|
545
|
-
resource.map(async (localResource) => {
|
|
562
|
+
public async pushMessagingTopics(topics: any[]): Promise<{
|
|
563
|
+
successfullyPushed: number;
|
|
564
|
+
errors: any[];
|
|
565
|
+
}> {
|
|
566
|
+
let successfullyPushed = 0;
|
|
567
|
+
const errors: any[] = [];
|
|
568
|
+
|
|
569
|
+
for (const topic of topics) {
|
|
546
570
|
try {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
};
|
|
571
|
+
this.log(`Pushing topic ${chalk.bold(topic["name"])} ...`);
|
|
572
|
+
const messagingService = await getMessagingService(this.projectClient);
|
|
550
573
|
|
|
551
|
-
|
|
552
|
-
|
|
574
|
+
try {
|
|
575
|
+
await messagingService.getTopic(topic["$id"]);
|
|
576
|
+
await messagingService.updateTopic({
|
|
577
|
+
topicId: topic["$id"],
|
|
578
|
+
name: topic.name,
|
|
579
|
+
subscribe: topic.subscribe,
|
|
580
|
+
});
|
|
581
|
+
} catch (e: unknown) {
|
|
582
|
+
if (e instanceof AppwriteException && Number(e.code) === 404) {
|
|
583
|
+
await messagingService.createTopic({
|
|
584
|
+
topicId: topic["$id"],
|
|
585
|
+
name: topic.name,
|
|
586
|
+
subscribe: topic.subscribe,
|
|
587
|
+
});
|
|
588
|
+
} else {
|
|
589
|
+
throw e;
|
|
590
|
+
}
|
|
553
591
|
}
|
|
554
592
|
|
|
555
|
-
|
|
593
|
+
this.success(`Pushed ${topic.name} ( ${topic["$id"]} )`);
|
|
594
|
+
successfullyPushed++;
|
|
595
|
+
} catch (e: any) {
|
|
596
|
+
errors.push(e);
|
|
597
|
+
this.error(`Failed to push topic ${topic["name"]}: ${e.message}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return {
|
|
602
|
+
successfullyPushed,
|
|
603
|
+
errors,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
public async pushFunctions(
|
|
608
|
+
functions: any[],
|
|
609
|
+
options: {
|
|
610
|
+
async?: boolean;
|
|
611
|
+
code?: boolean;
|
|
612
|
+
withVariables?: boolean;
|
|
613
|
+
} = {},
|
|
614
|
+
): Promise<{
|
|
615
|
+
successfullyPushed: number;
|
|
616
|
+
successfullyDeployed: number;
|
|
617
|
+
failedDeployments: any[];
|
|
618
|
+
errors: any[];
|
|
619
|
+
}> {
|
|
620
|
+
const { async: asyncDeploy, code, withVariables } = options;
|
|
621
|
+
|
|
622
|
+
Spinner.start(false);
|
|
623
|
+
let successfullyPushed = 0;
|
|
624
|
+
let successfullyDeployed = 0;
|
|
625
|
+
const failedDeployments: any[] = [];
|
|
626
|
+
const errors: any[] = [];
|
|
556
627
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
628
|
+
await Promise.all(
|
|
629
|
+
functions.map(async (func: any) => {
|
|
630
|
+
let response: any = {};
|
|
631
|
+
|
|
632
|
+
const ignore = func.ignore ? "appwrite.config.json" : ".gitignore";
|
|
633
|
+
let functionExists = false;
|
|
634
|
+
let deploymentCreated = false;
|
|
635
|
+
|
|
636
|
+
const updaterRow = new Spinner({
|
|
637
|
+
status: "",
|
|
638
|
+
resource: func.name,
|
|
639
|
+
id: func["$id"],
|
|
640
|
+
end: `Ignoring using: ${ignore}`,
|
|
641
|
+
});
|
|
563
642
|
|
|
564
|
-
|
|
565
|
-
|
|
643
|
+
updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
|
|
644
|
+
const functionsService = await getFunctionsService(this.projectClient);
|
|
645
|
+
try {
|
|
646
|
+
response = await functionsService.get({ functionId: func["$id"] });
|
|
647
|
+
functionExists = true;
|
|
648
|
+
if (response.runtime !== func.runtime) {
|
|
649
|
+
updaterRow.fail({
|
|
650
|
+
errorMessage: `Runtime mismatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.config.json`,
|
|
651
|
+
});
|
|
652
|
+
return;
|
|
566
653
|
}
|
|
567
654
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
655
|
+
updaterRow
|
|
656
|
+
.update({ status: "Updating" })
|
|
657
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
658
|
+
|
|
659
|
+
response = await functionsService.update({
|
|
660
|
+
functionId: func["$id"],
|
|
661
|
+
name: func.name,
|
|
662
|
+
runtime: func.runtime,
|
|
663
|
+
execute: func.execute,
|
|
664
|
+
events: func.events,
|
|
665
|
+
schedule: func.schedule,
|
|
666
|
+
timeout: func.timeout,
|
|
667
|
+
enabled: func.enabled,
|
|
668
|
+
logging: func.logging,
|
|
669
|
+
entrypoint: func.entrypoint,
|
|
670
|
+
commands: func.commands,
|
|
671
|
+
scopes: func.scopes,
|
|
672
|
+
specification: func.specification,
|
|
673
|
+
});
|
|
674
|
+
} catch (e: any) {
|
|
675
|
+
if (Number(e.code) === 404) {
|
|
676
|
+
functionExists = false;
|
|
677
|
+
} else {
|
|
678
|
+
errors.push(e);
|
|
679
|
+
updaterRow.fail({
|
|
680
|
+
errorMessage:
|
|
681
|
+
e.message ?? "General error occurs please try again",
|
|
583
682
|
});
|
|
683
|
+
return;
|
|
584
684
|
}
|
|
585
685
|
}
|
|
586
|
-
} catch (e: any) {
|
|
587
|
-
if (Number(e.code) !== 404) {
|
|
588
|
-
throw e;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}),
|
|
592
|
-
);
|
|
593
686
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
687
|
+
if (!functionExists) {
|
|
688
|
+
updaterRow
|
|
689
|
+
.update({ status: "Creating" })
|
|
690
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
597
691
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
692
|
+
try {
|
|
693
|
+
response = await functionsService.create({
|
|
694
|
+
functionId: func.$id,
|
|
695
|
+
name: func.name,
|
|
696
|
+
runtime: func.runtime,
|
|
697
|
+
execute: func.execute,
|
|
698
|
+
events: func.events,
|
|
699
|
+
schedule: func.schedule,
|
|
700
|
+
timeout: func.timeout,
|
|
701
|
+
enabled: func.enabled,
|
|
702
|
+
logging: func.logging,
|
|
703
|
+
entrypoint: func.entrypoint,
|
|
704
|
+
commands: func.commands,
|
|
705
|
+
scopes: func.scopes,
|
|
706
|
+
specification: func.specification,
|
|
707
|
+
});
|
|
602
708
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
709
|
+
let domain = "";
|
|
710
|
+
try {
|
|
711
|
+
const consoleService = await getConsoleService(
|
|
712
|
+
this.consoleClient,
|
|
713
|
+
);
|
|
714
|
+
const variables = await consoleService.variables();
|
|
715
|
+
domain = ID.unique() + "." + variables["_APP_DOMAIN_FUNCTIONS"];
|
|
716
|
+
} catch (err) {
|
|
717
|
+
this.error("Error fetching console variables.");
|
|
718
|
+
throw err;
|
|
719
|
+
}
|
|
606
720
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
721
|
+
try {
|
|
722
|
+
const proxyService = await getProxyService(this.projectClient);
|
|
723
|
+
await proxyService.createFunctionRule(domain, func.$id);
|
|
724
|
+
} catch (err) {
|
|
725
|
+
this.error("Error creating function rule.");
|
|
726
|
+
throw err;
|
|
727
|
+
}
|
|
614
728
|
|
|
615
|
-
|
|
616
|
-
|
|
729
|
+
updaterRow.update({ status: "Created" });
|
|
730
|
+
} catch (e: any) {
|
|
731
|
+
errors.push(e);
|
|
732
|
+
updaterRow.fail({
|
|
733
|
+
errorMessage:
|
|
734
|
+
e.message ?? "General error occurs please try again",
|
|
735
|
+
});
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
617
739
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
!Array.isArray(remoteNested) &&
|
|
623
|
-
typeof localNested === "object" &&
|
|
624
|
-
!Array.isArray(localNested)
|
|
625
|
-
) {
|
|
626
|
-
const remoteObj = remoteNested as Record<string, ComparableValue>;
|
|
627
|
-
const localObj = localNested as Record<string, ComparableValue>;
|
|
740
|
+
if (withVariables) {
|
|
741
|
+
updaterRow
|
|
742
|
+
.update({ status: "Updating variables" })
|
|
743
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
628
744
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
745
|
+
const functionsServiceForVars = await getFunctionsService(
|
|
746
|
+
this.projectClient,
|
|
747
|
+
);
|
|
748
|
+
const { variables } = await paginate(
|
|
749
|
+
async (args: any) => {
|
|
750
|
+
return await functionsServiceForVars.listVariables({
|
|
751
|
+
functionId: args.functionId,
|
|
752
|
+
});
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
functionId: func["$id"],
|
|
756
|
+
},
|
|
757
|
+
100,
|
|
758
|
+
"variables",
|
|
759
|
+
);
|
|
632
760
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
761
|
+
await Promise.all(
|
|
762
|
+
variables.map(async (variable: any) => {
|
|
763
|
+
const functionsServiceDel = await getFunctionsService(
|
|
764
|
+
this.projectClient,
|
|
765
|
+
);
|
|
766
|
+
await functionsServiceDel.deleteVariable({
|
|
767
|
+
functionId: func["$id"],
|
|
768
|
+
variableId: variable["$id"],
|
|
769
|
+
});
|
|
770
|
+
}),
|
|
771
|
+
);
|
|
638
772
|
|
|
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
|
-
collectionId,
|
|
666
|
-
key: attribute.key,
|
|
667
|
-
required: attribute.required,
|
|
668
|
-
xdefault: attribute.default,
|
|
669
|
-
array: attribute.array,
|
|
670
|
-
});
|
|
671
|
-
case "url":
|
|
672
|
-
return databasesService.createUrlAttribute({
|
|
673
|
-
databaseId,
|
|
674
|
-
collectionId,
|
|
675
|
-
key: attribute.key,
|
|
676
|
-
required: attribute.required,
|
|
677
|
-
xdefault: attribute.default,
|
|
678
|
-
array: attribute.array,
|
|
679
|
-
});
|
|
680
|
-
case "ip":
|
|
681
|
-
return databasesService.createIpAttribute({
|
|
682
|
-
databaseId,
|
|
683
|
-
collectionId,
|
|
684
|
-
key: attribute.key,
|
|
685
|
-
required: attribute.required,
|
|
686
|
-
xdefault: attribute.default,
|
|
687
|
-
array: attribute.array,
|
|
688
|
-
});
|
|
689
|
-
case "enum":
|
|
690
|
-
return databasesService.createEnumAttribute({
|
|
691
|
-
databaseId,
|
|
692
|
-
collectionId,
|
|
693
|
-
key: attribute.key,
|
|
694
|
-
elements: attribute.elements,
|
|
695
|
-
required: attribute.required,
|
|
696
|
-
xdefault: attribute.default,
|
|
697
|
-
array: attribute.array,
|
|
698
|
-
});
|
|
699
|
-
default:
|
|
700
|
-
return databasesService.createStringAttribute({
|
|
701
|
-
databaseId,
|
|
702
|
-
collectionId,
|
|
703
|
-
key: attribute.key,
|
|
704
|
-
size: attribute.size,
|
|
705
|
-
required: attribute.required,
|
|
706
|
-
xdefault: attribute.default,
|
|
707
|
-
array: attribute.array,
|
|
708
|
-
encrypt: attribute.encrypt,
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
case "integer":
|
|
712
|
-
return databasesService.createIntegerAttribute({
|
|
713
|
-
databaseId,
|
|
714
|
-
collectionId,
|
|
715
|
-
key: attribute.key,
|
|
716
|
-
required: attribute.required,
|
|
717
|
-
min: attribute.min,
|
|
718
|
-
max: attribute.max,
|
|
719
|
-
xdefault: attribute.default,
|
|
720
|
-
array: attribute.array,
|
|
721
|
-
});
|
|
722
|
-
case "double":
|
|
723
|
-
return databasesService.createFloatAttribute({
|
|
724
|
-
databaseId,
|
|
725
|
-
collectionId,
|
|
726
|
-
key: attribute.key,
|
|
727
|
-
required: attribute.required,
|
|
728
|
-
min: attribute.min,
|
|
729
|
-
max: attribute.max,
|
|
730
|
-
xdefault: attribute.default,
|
|
731
|
-
array: attribute.array,
|
|
732
|
-
});
|
|
733
|
-
case "boolean":
|
|
734
|
-
return databasesService.createBooleanAttribute({
|
|
735
|
-
databaseId,
|
|
736
|
-
collectionId,
|
|
737
|
-
key: attribute.key,
|
|
738
|
-
required: attribute.required,
|
|
739
|
-
xdefault: attribute.default,
|
|
740
|
-
array: attribute.array,
|
|
741
|
-
});
|
|
742
|
-
case "datetime":
|
|
743
|
-
return databasesService.createDatetimeAttribute({
|
|
744
|
-
databaseId,
|
|
745
|
-
collectionId,
|
|
746
|
-
key: attribute.key,
|
|
747
|
-
required: attribute.required,
|
|
748
|
-
xdefault: attribute.default,
|
|
749
|
-
array: attribute.array,
|
|
750
|
-
});
|
|
751
|
-
case "relationship":
|
|
752
|
-
return databasesService.createRelationshipAttribute({
|
|
753
|
-
databaseId,
|
|
754
|
-
collectionId,
|
|
755
|
-
relatedCollectionId:
|
|
756
|
-
attribute.relatedTable ?? attribute.relatedCollection,
|
|
757
|
-
type: attribute.relationType,
|
|
758
|
-
twoWay: attribute.twoWay,
|
|
759
|
-
key: attribute.key,
|
|
760
|
-
twoWayKey: attribute.twoWayKey,
|
|
761
|
-
onDelete: attribute.onDelete,
|
|
762
|
-
});
|
|
763
|
-
case "point":
|
|
764
|
-
return databasesService.createPointAttribute({
|
|
765
|
-
databaseId,
|
|
766
|
-
collectionId,
|
|
767
|
-
key: attribute.key,
|
|
768
|
-
required: attribute.required,
|
|
769
|
-
xdefault: attribute.default,
|
|
770
|
-
});
|
|
771
|
-
case "linestring":
|
|
772
|
-
return databasesService.createLineAttribute({
|
|
773
|
-
databaseId,
|
|
774
|
-
collectionId,
|
|
775
|
-
key: attribute.key,
|
|
776
|
-
required: attribute.required,
|
|
777
|
-
xdefault: attribute.default,
|
|
778
|
-
});
|
|
779
|
-
case "polygon":
|
|
780
|
-
return databasesService.createPolygonAttribute({
|
|
781
|
-
databaseId,
|
|
782
|
-
collectionId,
|
|
783
|
-
key: attribute.key,
|
|
784
|
-
required: attribute.required,
|
|
785
|
-
xdefault: attribute.default,
|
|
786
|
-
});
|
|
787
|
-
default:
|
|
788
|
-
throw new Error(`Unsupported attribute type: ${attribute.type}`);
|
|
789
|
-
}
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
const updateAttribute = async (
|
|
793
|
-
databaseId: string,
|
|
794
|
-
collectionId: string,
|
|
795
|
-
attribute: any,
|
|
796
|
-
): Promise<any> => {
|
|
797
|
-
const databasesService = await getDatabasesService();
|
|
798
|
-
switch (attribute.type) {
|
|
799
|
-
case "string":
|
|
800
|
-
switch (attribute.format) {
|
|
801
|
-
case "email":
|
|
802
|
-
return databasesService.updateEmailAttribute({
|
|
803
|
-
databaseId,
|
|
804
|
-
collectionId,
|
|
805
|
-
key: attribute.key,
|
|
806
|
-
required: attribute.required,
|
|
807
|
-
xdefault: attribute.default,
|
|
808
|
-
});
|
|
809
|
-
case "url":
|
|
810
|
-
return databasesService.updateUrlAttribute({
|
|
811
|
-
databaseId,
|
|
812
|
-
collectionId,
|
|
813
|
-
key: attribute.key,
|
|
814
|
-
required: attribute.required,
|
|
815
|
-
xdefault: attribute.default,
|
|
816
|
-
});
|
|
817
|
-
case "ip":
|
|
818
|
-
return databasesService.updateIpAttribute({
|
|
819
|
-
databaseId,
|
|
820
|
-
collectionId,
|
|
821
|
-
key: attribute.key,
|
|
822
|
-
required: attribute.required,
|
|
823
|
-
xdefault: attribute.default,
|
|
824
|
-
});
|
|
825
|
-
case "enum":
|
|
826
|
-
return databasesService.updateEnumAttribute({
|
|
827
|
-
databaseId,
|
|
828
|
-
collectionId,
|
|
829
|
-
key: attribute.key,
|
|
830
|
-
elements: attribute.elements,
|
|
831
|
-
required: attribute.required,
|
|
832
|
-
xdefault: attribute.default,
|
|
833
|
-
});
|
|
834
|
-
default:
|
|
835
|
-
return databasesService.updateStringAttribute({
|
|
836
|
-
databaseId,
|
|
837
|
-
collectionId,
|
|
838
|
-
key: attribute.key,
|
|
839
|
-
required: attribute.required,
|
|
840
|
-
xdefault: attribute.default,
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
case "integer":
|
|
844
|
-
return databasesService.updateIntegerAttribute({
|
|
845
|
-
databaseId,
|
|
846
|
-
collectionId,
|
|
847
|
-
key: attribute.key,
|
|
848
|
-
required: attribute.required,
|
|
849
|
-
min: attribute.min,
|
|
850
|
-
max: attribute.max,
|
|
851
|
-
xdefault: attribute.default,
|
|
852
|
-
});
|
|
853
|
-
case "double":
|
|
854
|
-
return databasesService.updateFloatAttribute({
|
|
855
|
-
databaseId,
|
|
856
|
-
collectionId,
|
|
857
|
-
key: attribute.key,
|
|
858
|
-
required: attribute.required,
|
|
859
|
-
min: attribute.min,
|
|
860
|
-
max: attribute.max,
|
|
861
|
-
xdefault: attribute.default,
|
|
862
|
-
});
|
|
863
|
-
case "boolean":
|
|
864
|
-
return databasesService.updateBooleanAttribute({
|
|
865
|
-
databaseId,
|
|
866
|
-
collectionId,
|
|
867
|
-
key: attribute.key,
|
|
868
|
-
required: attribute.required,
|
|
869
|
-
xdefault: attribute.default,
|
|
870
|
-
});
|
|
871
|
-
case "datetime":
|
|
872
|
-
return databasesService.updateDatetimeAttribute({
|
|
873
|
-
databaseId,
|
|
874
|
-
collectionId,
|
|
875
|
-
key: attribute.key,
|
|
876
|
-
required: attribute.required,
|
|
877
|
-
xdefault: attribute.default,
|
|
878
|
-
});
|
|
879
|
-
case "relationship":
|
|
880
|
-
return databasesService.updateRelationshipAttribute({
|
|
881
|
-
databaseId,
|
|
882
|
-
collectionId,
|
|
883
|
-
key: attribute.key,
|
|
884
|
-
onDelete: attribute.onDelete,
|
|
885
|
-
});
|
|
886
|
-
case "point":
|
|
887
|
-
return databasesService.updatePointAttribute({
|
|
888
|
-
databaseId,
|
|
889
|
-
collectionId,
|
|
890
|
-
key: attribute.key,
|
|
891
|
-
required: attribute.required,
|
|
892
|
-
xdefault: attribute.default,
|
|
893
|
-
});
|
|
894
|
-
case "linestring":
|
|
895
|
-
return databasesService.updateLineAttribute({
|
|
896
|
-
databaseId,
|
|
897
|
-
collectionId,
|
|
898
|
-
key: attribute.key,
|
|
899
|
-
required: attribute.required,
|
|
900
|
-
xdefault: attribute.default,
|
|
901
|
-
});
|
|
902
|
-
case "polygon":
|
|
903
|
-
return databasesService.updatePolygonAttribute({
|
|
904
|
-
databaseId,
|
|
905
|
-
collectionId,
|
|
906
|
-
key: attribute.key,
|
|
907
|
-
required: attribute.required,
|
|
908
|
-
xdefault: attribute.default,
|
|
909
|
-
});
|
|
910
|
-
default:
|
|
911
|
-
throw new Error(`Unsupported attribute type: ${attribute.type}`);
|
|
912
|
-
}
|
|
913
|
-
};
|
|
914
|
-
const deleteAttribute = async (
|
|
915
|
-
collection: any,
|
|
916
|
-
attribute: any,
|
|
917
|
-
isIndex: boolean = false,
|
|
918
|
-
): Promise<void> => {
|
|
919
|
-
log(
|
|
920
|
-
`Deleting ${isIndex ? "index" : "attribute"} ${attribute.key} of ${collection.name} ( ${collection["$id"]} )`,
|
|
921
|
-
);
|
|
922
|
-
|
|
923
|
-
const databasesService = await getDatabasesService();
|
|
924
|
-
if (isIndex) {
|
|
925
|
-
await databasesService.deleteIndex(
|
|
926
|
-
collection["databaseId"],
|
|
927
|
-
collection["$id"],
|
|
928
|
-
attribute.key,
|
|
929
|
-
);
|
|
930
|
-
return;
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
await databasesService.deleteAttribute(
|
|
934
|
-
collection["databaseId"],
|
|
935
|
-
collection["$id"],
|
|
936
|
-
attribute.key,
|
|
937
|
-
);
|
|
938
|
-
};
|
|
939
|
-
|
|
940
|
-
const isEqual = (a: any, b: any): boolean => {
|
|
941
|
-
if (a === b) return true;
|
|
942
|
-
|
|
943
|
-
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
944
|
-
if (
|
|
945
|
-
a.constructor &&
|
|
946
|
-
a.constructor.name === "BigNumber" &&
|
|
947
|
-
b.constructor &&
|
|
948
|
-
b.constructor.name === "BigNumber"
|
|
949
|
-
) {
|
|
950
|
-
return a.eq(b);
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
if (typeof a.equals === "function") {
|
|
954
|
-
return a.equals(b);
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
if (typeof a.eq === "function") {
|
|
958
|
-
return a.eq(b);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
if (typeof a === "number" && typeof b === "number") {
|
|
963
|
-
if (isNaN(a) && isNaN(b)) return true;
|
|
964
|
-
if (!isFinite(a) && !isFinite(b)) return a === b;
|
|
965
|
-
return Math.abs(a - b) < Number.EPSILON;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
return false;
|
|
969
|
-
};
|
|
970
|
-
|
|
971
|
-
const compareAttribute = (
|
|
972
|
-
remote: any,
|
|
973
|
-
local: any,
|
|
974
|
-
reason: string,
|
|
975
|
-
key: string,
|
|
976
|
-
): string => {
|
|
977
|
-
if (isEmpty(remote) && isEmpty(local)) {
|
|
978
|
-
return reason;
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
if (Array.isArray(remote) && Array.isArray(local)) {
|
|
982
|
-
if (JSON.stringify(remote) !== JSON.stringify(local)) {
|
|
983
|
-
const bol = reason === "" ? "" : "\n";
|
|
984
|
-
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
985
|
-
}
|
|
986
|
-
} else if (!isEqual(remote, local)) {
|
|
987
|
-
const bol = reason === "" ? "" : "\n";
|
|
988
|
-
reason += `${bol}${key} changed from ${chalk.red(remote)} to ${chalk.green(local)}`;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
return reason;
|
|
992
|
-
};
|
|
993
|
-
|
|
994
|
-
/**
|
|
995
|
-
* Check if attribute non-changeable fields has been changed
|
|
996
|
-
* If so return the differences as an object.
|
|
997
|
-
*/
|
|
998
|
-
const checkAttributeChanges = (
|
|
999
|
-
remote: any,
|
|
1000
|
-
local: any,
|
|
1001
|
-
collection: any,
|
|
1002
|
-
recreating: boolean = true,
|
|
1003
|
-
): AttributeChange | undefined => {
|
|
1004
|
-
if (local === undefined) {
|
|
1005
|
-
return undefined;
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
const keyName = `${chalk.yellow(local.key)} in ${collection.name} (${collection["$id"]})`;
|
|
1009
|
-
const action = chalk.cyan(recreating ? "recreating" : "changing");
|
|
1010
|
-
let reason = "";
|
|
1011
|
-
let attribute = recreating ? remote : local;
|
|
1012
|
-
|
|
1013
|
-
for (let key of Object.keys(remote)) {
|
|
1014
|
-
if (!KeysAttributes.has(key)) {
|
|
1015
|
-
continue;
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
if (changeableKeys.includes(key)) {
|
|
1019
|
-
if (!recreating) {
|
|
1020
|
-
reason = compareAttribute(remote[key], local[key], reason, key);
|
|
1021
|
-
}
|
|
1022
|
-
continue;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
if (!recreating) {
|
|
1026
|
-
continue;
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
reason = compareAttribute(remote[key], local[key], reason, key);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
return reason === ""
|
|
1033
|
-
? undefined
|
|
1034
|
-
: { key: keyName, attribute, reason, action };
|
|
1035
|
-
};
|
|
1036
|
-
|
|
1037
|
-
/**
|
|
1038
|
-
* Check if attributes contain the given attribute
|
|
1039
|
-
*/
|
|
1040
|
-
const attributesContains = (attribute: any, attributes: any[]): any =>
|
|
1041
|
-
attributes.find((attr) => attr.key === attribute.key);
|
|
1042
|
-
|
|
1043
|
-
const generateChangesObject = (
|
|
1044
|
-
attribute: any,
|
|
1045
|
-
collection: any,
|
|
1046
|
-
isAdding: boolean,
|
|
1047
|
-
): AttributeChange => {
|
|
1048
|
-
return {
|
|
1049
|
-
key: `${chalk.yellow(attribute.key)} in ${collection.name} (${collection["$id"]})`,
|
|
1050
|
-
attribute: attribute,
|
|
1051
|
-
reason: isAdding
|
|
1052
|
-
? "Field isn't present on the remote server"
|
|
1053
|
-
: "Field isn't present on the appwrite.config.json file",
|
|
1054
|
-
action: isAdding ? chalk.green("adding") : chalk.red("deleting"),
|
|
1055
|
-
};
|
|
1056
|
-
};
|
|
1057
|
-
|
|
1058
|
-
/**
|
|
1059
|
-
* Filter deleted and recreated attributes,
|
|
1060
|
-
* return list of attributes to create
|
|
1061
|
-
*/
|
|
1062
|
-
const attributesToCreate = async (
|
|
1063
|
-
remoteAttributes: any[],
|
|
1064
|
-
localAttributes: any[],
|
|
1065
|
-
collection: any,
|
|
1066
|
-
isIndex: boolean = false,
|
|
1067
|
-
): Promise<any[]> => {
|
|
1068
|
-
const deleting = remoteAttributes
|
|
1069
|
-
.filter((attribute) => !attributesContains(attribute, localAttributes))
|
|
1070
|
-
.map((attr) => generateChangesObject(attr, collection, false));
|
|
1071
|
-
const adding = localAttributes
|
|
1072
|
-
.filter((attribute) => !attributesContains(attribute, remoteAttributes))
|
|
1073
|
-
.map((attr) => generateChangesObject(attr, collection, true));
|
|
1074
|
-
const conflicts = remoteAttributes
|
|
1075
|
-
.map((attribute) =>
|
|
1076
|
-
checkAttributeChanges(
|
|
1077
|
-
attribute,
|
|
1078
|
-
attributesContains(attribute, localAttributes),
|
|
1079
|
-
collection,
|
|
1080
|
-
),
|
|
1081
|
-
)
|
|
1082
|
-
.filter((attribute) => attribute !== undefined) as AttributeChange[];
|
|
1083
|
-
const changes = remoteAttributes
|
|
1084
|
-
.map((attribute) =>
|
|
1085
|
-
checkAttributeChanges(
|
|
1086
|
-
attribute,
|
|
1087
|
-
attributesContains(attribute, localAttributes),
|
|
1088
|
-
collection,
|
|
1089
|
-
false,
|
|
1090
|
-
),
|
|
1091
|
-
)
|
|
1092
|
-
.filter((attribute) => attribute !== undefined)
|
|
1093
|
-
.filter(
|
|
1094
|
-
(attribute) =>
|
|
1095
|
-
conflicts.filter((attr) => attribute!.key === attr.key).length !== 1,
|
|
1096
|
-
) as AttributeChange[];
|
|
1097
|
-
|
|
1098
|
-
let changedAttributes: any[] = [];
|
|
1099
|
-
const changing = [...deleting, ...adding, ...conflicts, ...changes];
|
|
1100
|
-
if (changing.length === 0) {
|
|
1101
|
-
return changedAttributes;
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
log(
|
|
1105
|
-
!cliConfig.force
|
|
1106
|
-
? "There are pending changes in your collection deployment"
|
|
1107
|
-
: "List of applied changes",
|
|
1108
|
-
);
|
|
1109
|
-
|
|
1110
|
-
drawTable(
|
|
1111
|
-
changing.map((change) => {
|
|
1112
|
-
return { Key: change.key, Action: change.action, Reason: change.reason };
|
|
1113
|
-
}),
|
|
1114
|
-
);
|
|
1115
|
-
|
|
1116
|
-
if (!cliConfig.force) {
|
|
1117
|
-
if (deleting.length > 0 && !isIndex) {
|
|
1118
|
-
console.log(
|
|
1119
|
-
`${chalk.red("------------------------------------------------------")}`,
|
|
1120
|
-
);
|
|
1121
|
-
console.log(
|
|
1122
|
-
`${chalk.red("| WARNING: Attribute deletion may cause loss of data |")}`,
|
|
1123
|
-
);
|
|
1124
|
-
console.log(
|
|
1125
|
-
`${chalk.red("------------------------------------------------------")}`,
|
|
1126
|
-
);
|
|
1127
|
-
console.log();
|
|
1128
|
-
}
|
|
1129
|
-
if (conflicts.length > 0 && !isIndex) {
|
|
1130
|
-
console.log(
|
|
1131
|
-
`${chalk.red("--------------------------------------------------------")}`,
|
|
1132
|
-
);
|
|
1133
|
-
console.log(
|
|
1134
|
-
`${chalk.red("| WARNING: Attribute recreation may cause loss of data |")}`,
|
|
1135
|
-
);
|
|
1136
|
-
console.log(
|
|
1137
|
-
`${chalk.red("--------------------------------------------------------")}`,
|
|
1138
|
-
);
|
|
1139
|
-
console.log();
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
if ((await getConfirmation()) !== true) {
|
|
1143
|
-
return changedAttributes;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
if (conflicts.length > 0) {
|
|
1148
|
-
changedAttributes = conflicts.map((change) => change.attribute);
|
|
1149
|
-
await Promise.all(
|
|
1150
|
-
changedAttributes.map((changed) =>
|
|
1151
|
-
deleteAttribute(collection, changed, isIndex),
|
|
1152
|
-
),
|
|
1153
|
-
);
|
|
1154
|
-
remoteAttributes = remoteAttributes.filter(
|
|
1155
|
-
(attribute) => !attributesContains(attribute, changedAttributes),
|
|
1156
|
-
);
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
if (changes.length > 0) {
|
|
1160
|
-
changedAttributes = changes.map((change) => change.attribute);
|
|
1161
|
-
await Promise.all(
|
|
1162
|
-
changedAttributes.map((changed) =>
|
|
1163
|
-
updateAttribute(collection["databaseId"], collection["$id"], changed),
|
|
1164
|
-
),
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
const deletingAttributes = deleting.map((change) => change.attribute);
|
|
1169
|
-
await Promise.all(
|
|
1170
|
-
deletingAttributes.map((attribute) =>
|
|
1171
|
-
deleteAttribute(collection, attribute, isIndex),
|
|
1172
|
-
),
|
|
1173
|
-
);
|
|
1174
|
-
const attributeKeys = [
|
|
1175
|
-
...remoteAttributes.map((attribute: any) => attribute.key),
|
|
1176
|
-
...deletingAttributes.map((attribute: any) => attribute.key),
|
|
1177
|
-
];
|
|
1178
|
-
|
|
1179
|
-
if (attributeKeys.length) {
|
|
1180
|
-
const deleteAttributesPoolStatus = await awaitPools.deleteAttributes(
|
|
1181
|
-
collection["databaseId"],
|
|
1182
|
-
collection["$id"],
|
|
1183
|
-
attributeKeys,
|
|
1184
|
-
);
|
|
1185
|
-
|
|
1186
|
-
if (!deleteAttributesPoolStatus) {
|
|
1187
|
-
throw new Error("Attribute deletion timed out.");
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
return localAttributes.filter(
|
|
1192
|
-
(attribute) => !attributesContains(attribute, remoteAttributes),
|
|
1193
|
-
);
|
|
1194
|
-
};
|
|
1195
|
-
|
|
1196
|
-
const createIndexes = async (
|
|
1197
|
-
indexes: any[],
|
|
1198
|
-
collection: any,
|
|
1199
|
-
): Promise<void> => {
|
|
1200
|
-
log(`Creating indexes ...`);
|
|
1201
|
-
|
|
1202
|
-
const databasesService = await getDatabasesService();
|
|
1203
|
-
for (let index of indexes) {
|
|
1204
|
-
await databasesService.createIndex(
|
|
1205
|
-
collection["databaseId"],
|
|
1206
|
-
collection["$id"],
|
|
1207
|
-
index.key,
|
|
1208
|
-
index.type,
|
|
1209
|
-
index.columns ?? index.attributes,
|
|
1210
|
-
index.orders,
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
const result = await awaitPools.expectIndexes(
|
|
1215
|
-
collection["databaseId"],
|
|
1216
|
-
collection["$id"],
|
|
1217
|
-
indexes.map((index: any) => index.key),
|
|
1218
|
-
);
|
|
1219
|
-
|
|
1220
|
-
if (!result) {
|
|
1221
|
-
throw new Error("Index creation timed out.");
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
success(`Created ${indexes.length} indexes`);
|
|
1225
|
-
};
|
|
1226
|
-
|
|
1227
|
-
const createAttributes = async (
|
|
1228
|
-
attributes: any[],
|
|
1229
|
-
collection: any,
|
|
1230
|
-
): Promise<void> => {
|
|
1231
|
-
for (let attribute of attributes) {
|
|
1232
|
-
if (attribute.side !== "child") {
|
|
1233
|
-
await createAttribute(
|
|
1234
|
-
collection["databaseId"],
|
|
1235
|
-
collection["$id"],
|
|
1236
|
-
attribute,
|
|
1237
|
-
);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
const result = await awaitPools.expectAttributes(
|
|
1242
|
-
collection["databaseId"],
|
|
1243
|
-
collection["$id"],
|
|
1244
|
-
collection.attributes
|
|
1245
|
-
.filter((attribute: any) => attribute.side !== "child")
|
|
1246
|
-
.map((attribute: any) => attribute.key),
|
|
1247
|
-
);
|
|
1248
|
-
|
|
1249
|
-
if (!result) {
|
|
1250
|
-
throw new Error(`Attribute creation timed out.`);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
success(`Created ${attributes.length} attributes`);
|
|
1254
|
-
};
|
|
1255
|
-
|
|
1256
|
-
const createColumns = async (columns: any[], table: any): Promise<void> => {
|
|
1257
|
-
for (let column of columns) {
|
|
1258
|
-
if (column.side !== "child") {
|
|
1259
|
-
await createAttribute(table["databaseId"], table["$id"], column);
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
const result = await awaitPools.expectAttributes(
|
|
1264
|
-
table["databaseId"],
|
|
1265
|
-
table["$id"],
|
|
1266
|
-
table.columns
|
|
1267
|
-
.filter((column: any) => column.side !== "child")
|
|
1268
|
-
.map((column: any) => column.key),
|
|
1269
|
-
);
|
|
1270
|
-
|
|
1271
|
-
if (!result) {
|
|
1272
|
-
throw new Error(`Column creation timed out.`);
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
success(`Created ${columns.length} columns`);
|
|
1276
|
-
};
|
|
1277
|
-
|
|
1278
|
-
const pushResources = async ({
|
|
1279
|
-
skipDeprecated = false,
|
|
1280
|
-
}: PushResourcesOptions = {}): Promise<void> => {
|
|
1281
|
-
const actions: Record<string, (options?: any) => Promise<void>> = {
|
|
1282
|
-
settings: pushSettings,
|
|
1283
|
-
functions: pushFunction,
|
|
1284
|
-
sites: pushSite,
|
|
1285
|
-
collections: pushCollection,
|
|
1286
|
-
tables: pushTable,
|
|
1287
|
-
buckets: pushBucket,
|
|
1288
|
-
teams: pushTeam,
|
|
1289
|
-
messages: pushMessagingTopic,
|
|
1290
|
-
};
|
|
1291
|
-
|
|
1292
|
-
if (skipDeprecated) {
|
|
1293
|
-
delete actions.collections;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
if (cliConfig.all) {
|
|
1297
|
-
for (let action of Object.values(actions)) {
|
|
1298
|
-
await action();
|
|
1299
|
-
}
|
|
1300
|
-
} else {
|
|
1301
|
-
const answers = await inquirer.prompt(questionsPushResources);
|
|
1302
|
-
|
|
1303
|
-
const action = actions[answers.resource];
|
|
1304
|
-
if (action !== undefined) {
|
|
1305
|
-
await action();
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
};
|
|
1309
|
-
|
|
1310
|
-
const pushSettings = async (): Promise<void> => {
|
|
1311
|
-
checkDeployConditions(localConfig);
|
|
1312
|
-
|
|
1313
|
-
try {
|
|
1314
|
-
const projectsService = await getProjectsService();
|
|
1315
|
-
let response = await projectsService.get(
|
|
1316
|
-
localConfig.getProject().projectId,
|
|
1317
|
-
);
|
|
1318
|
-
|
|
1319
|
-
const remoteSettings = localConfig.createSettingsObject(response ?? {});
|
|
1320
|
-
const localSettings = localConfig.getProject().projectSettings ?? {};
|
|
1321
|
-
|
|
1322
|
-
log("Checking for changes ...");
|
|
1323
|
-
const changes: any[] = [];
|
|
1324
|
-
|
|
1325
|
-
changes.push(
|
|
1326
|
-
...getObjectChanges(remoteSettings, localSettings, "services", "Service"),
|
|
1327
|
-
);
|
|
1328
|
-
changes.push(
|
|
1329
|
-
...getObjectChanges(
|
|
1330
|
-
remoteSettings["auth"] ?? {},
|
|
1331
|
-
localSettings["auth"] ?? {},
|
|
1332
|
-
"methods",
|
|
1333
|
-
"Auth method",
|
|
1334
|
-
),
|
|
1335
|
-
);
|
|
1336
|
-
changes.push(
|
|
1337
|
-
...getObjectChanges(
|
|
1338
|
-
remoteSettings["auth"] ?? {},
|
|
1339
|
-
localSettings["auth"] ?? {},
|
|
1340
|
-
"security",
|
|
1341
|
-
"Auth security",
|
|
1342
|
-
),
|
|
1343
|
-
);
|
|
1344
|
-
|
|
1345
|
-
if (changes.length > 0) {
|
|
1346
|
-
drawTable(changes);
|
|
1347
|
-
if ((await getConfirmation()) !== true) {
|
|
1348
|
-
success(`Successfully pushed 0 project settings.`);
|
|
1349
|
-
return;
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
} catch (e) {}
|
|
1353
|
-
|
|
1354
|
-
try {
|
|
1355
|
-
log("Pushing project settings ...");
|
|
1356
|
-
|
|
1357
|
-
const projectsService = await getProjectsService();
|
|
1358
|
-
const projectId = localConfig.getProject().projectId;
|
|
1359
|
-
const projectName = localConfig.getProject().projectName;
|
|
1360
|
-
const settings = localConfig.getProject().projectSettings ?? {};
|
|
1361
|
-
|
|
1362
|
-
if (projectName) {
|
|
1363
|
-
log("Applying project name ...");
|
|
1364
|
-
await projectsService.update(projectId, projectName);
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
if (settings.services) {
|
|
1368
|
-
log("Applying service statuses ...");
|
|
1369
|
-
for (let [service, status] of Object.entries(settings.services)) {
|
|
1370
|
-
await projectsService.updateServiceStatus(
|
|
1371
|
-
projectId,
|
|
1372
|
-
service as ApiService,
|
|
1373
|
-
status,
|
|
1374
|
-
);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
if (settings.auth) {
|
|
1379
|
-
if (settings.auth.security) {
|
|
1380
|
-
log("Applying auth security settings ...");
|
|
1381
|
-
await projectsService.updateAuthDuration(
|
|
1382
|
-
projectId,
|
|
1383
|
-
settings.auth.security.duration,
|
|
1384
|
-
);
|
|
1385
|
-
await projectsService.updateAuthLimit(
|
|
1386
|
-
projectId,
|
|
1387
|
-
settings.auth.security.limit,
|
|
1388
|
-
);
|
|
1389
|
-
await projectsService.updateAuthSessionsLimit(
|
|
1390
|
-
projectId,
|
|
1391
|
-
settings.auth.security.sessionsLimit,
|
|
1392
|
-
);
|
|
1393
|
-
await projectsService.updateAuthPasswordDictionary(
|
|
1394
|
-
projectId,
|
|
1395
|
-
settings.auth.security.passwordDictionary,
|
|
1396
|
-
);
|
|
1397
|
-
await projectsService.updateAuthPasswordHistory(
|
|
1398
|
-
projectId,
|
|
1399
|
-
settings.auth.security.passwordHistory,
|
|
1400
|
-
);
|
|
1401
|
-
await projectsService.updatePersonalDataCheck(
|
|
1402
|
-
projectId,
|
|
1403
|
-
settings.auth.security.personalDataCheck,
|
|
1404
|
-
);
|
|
1405
|
-
await projectsService.updateSessionAlerts(
|
|
1406
|
-
projectId,
|
|
1407
|
-
settings.auth.security.sessionAlerts,
|
|
1408
|
-
);
|
|
1409
|
-
await projectsService.updateMockNumbers(
|
|
1410
|
-
projectId,
|
|
1411
|
-
settings.auth.security.mockNumbers,
|
|
1412
|
-
);
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
if (settings.auth.methods) {
|
|
1416
|
-
log("Applying auth methods statuses ...");
|
|
1417
|
-
|
|
1418
|
-
for (let [method, status] of Object.entries(settings.auth.methods)) {
|
|
1419
|
-
await projectsService.updateAuthStatus(
|
|
1420
|
-
projectId,
|
|
1421
|
-
method as AuthMethod,
|
|
1422
|
-
status,
|
|
773
|
+
const envFileLocation = `${func["path"]}/.env`;
|
|
774
|
+
let envVariables: Array<{ key: string; value: string }> = [];
|
|
775
|
+
try {
|
|
776
|
+
if (fs.existsSync(envFileLocation)) {
|
|
777
|
+
const envObject = parseDotenv(
|
|
778
|
+
fs.readFileSync(envFileLocation, "utf8"),
|
|
779
|
+
);
|
|
780
|
+
envVariables = Object.entries(envObject || {}).map(
|
|
781
|
+
([key, value]) => ({ key, value }),
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
} catch (error) {
|
|
785
|
+
envVariables = [];
|
|
786
|
+
}
|
|
787
|
+
await Promise.all(
|
|
788
|
+
envVariables.map(async (variable) => {
|
|
789
|
+
const functionsServiceCreate = await getFunctionsService(
|
|
790
|
+
this.projectClient,
|
|
791
|
+
);
|
|
792
|
+
await functionsServiceCreate.createVariable({
|
|
793
|
+
functionId: func["$id"],
|
|
794
|
+
key: variable.key,
|
|
795
|
+
value: variable.value,
|
|
796
|
+
secret: false,
|
|
797
|
+
});
|
|
798
|
+
}),
|
|
1423
799
|
);
|
|
1424
800
|
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
801
|
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
siteId,
|
|
1436
|
-
async: asyncDeploy,
|
|
1437
|
-
code,
|
|
1438
|
-
withVariables,
|
|
1439
|
-
}: PushSiteOptions = {}): Promise<void> => {
|
|
1440
|
-
process.chdir(localConfig.configDirectoryPath);
|
|
1441
|
-
|
|
1442
|
-
const siteIds: string[] = [];
|
|
1443
|
-
|
|
1444
|
-
if (siteId) {
|
|
1445
|
-
siteIds.push(siteId);
|
|
1446
|
-
} else if (cliConfig.all) {
|
|
1447
|
-
checkDeployConditions(localConfig);
|
|
1448
|
-
const sites = localConfig.getSites();
|
|
1449
|
-
siteIds.push(
|
|
1450
|
-
...sites.map((site: any) => {
|
|
1451
|
-
return site.$id;
|
|
1452
|
-
}),
|
|
1453
|
-
);
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
if (siteIds.length <= 0) {
|
|
1457
|
-
const answers = await inquirer.prompt(questionsPushSites);
|
|
1458
|
-
if (answers.sites) {
|
|
1459
|
-
siteIds.push(...answers.sites);
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
if (siteIds.length === 0) {
|
|
1464
|
-
log("No sites found.");
|
|
1465
|
-
hint(
|
|
1466
|
-
"Use 'appwrite pull sites' to synchronize existing one, or use 'appwrite init site' to create a new one.",
|
|
1467
|
-
);
|
|
1468
|
-
return;
|
|
1469
|
-
}
|
|
802
|
+
if (code === false) {
|
|
803
|
+
successfullyPushed++;
|
|
804
|
+
successfullyDeployed++;
|
|
805
|
+
updaterRow.update({ status: "Pushed" });
|
|
806
|
+
updaterRow.stopSpinner();
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
1470
809
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
810
|
+
try {
|
|
811
|
+
updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_DOTS);
|
|
812
|
+
const functionsServiceDeploy = await getFunctionsService(
|
|
813
|
+
this.projectClient,
|
|
814
|
+
);
|
|
1474
815
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
816
|
+
const result = await pushDeployment({
|
|
817
|
+
resourcePath: func.path,
|
|
818
|
+
createDeployment: async (codeFile) => {
|
|
819
|
+
return await functionsServiceDeploy.createDeployment({
|
|
820
|
+
functionId: func["$id"],
|
|
821
|
+
entrypoint: func.entrypoint,
|
|
822
|
+
commands: func.commands,
|
|
823
|
+
code: codeFile,
|
|
824
|
+
activate: true,
|
|
825
|
+
});
|
|
826
|
+
},
|
|
827
|
+
pollForStatus: false,
|
|
828
|
+
});
|
|
1478
829
|
|
|
1479
|
-
|
|
1480
|
-
|
|
830
|
+
response = result.deployment;
|
|
831
|
+
updaterRow.update({ status: "Pushed" });
|
|
1481
832
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
log(`Site ${site.name} is missing build command.`);
|
|
1487
|
-
const answers = await inquirer.prompt(questionsGetEntrypoint);
|
|
1488
|
-
site.buildCommand = answers.entrypoint;
|
|
1489
|
-
localConfig.addSite(site);
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
833
|
+
deploymentCreated = true;
|
|
834
|
+
successfullyPushed++;
|
|
835
|
+
} catch (e: any) {
|
|
836
|
+
errors.push(e);
|
|
1492
837
|
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
return;
|
|
1507
|
-
}
|
|
838
|
+
switch (e.code) {
|
|
839
|
+
case "ENOENT":
|
|
840
|
+
updaterRow.fail({
|
|
841
|
+
errorMessage: "Not found in the current directory. Skipping...",
|
|
842
|
+
});
|
|
843
|
+
break;
|
|
844
|
+
default:
|
|
845
|
+
updaterRow.fail({
|
|
846
|
+
errorMessage:
|
|
847
|
+
e.message ?? "An unknown error occurred. Please try again.",
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
}
|
|
1508
851
|
|
|
1509
|
-
|
|
852
|
+
if (deploymentCreated && !asyncDeploy) {
|
|
853
|
+
try {
|
|
854
|
+
const deploymentId = response["$id"];
|
|
855
|
+
updaterRow.update({
|
|
856
|
+
status: "Deploying",
|
|
857
|
+
end: "Checking deployment status...",
|
|
858
|
+
});
|
|
1510
859
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
const updaterRow = new Spinner({
|
|
1526
|
-
status: "",
|
|
1527
|
-
resource: site.name,
|
|
1528
|
-
id: site["$id"],
|
|
1529
|
-
end: `Ignoring using: ${ignore}`,
|
|
1530
|
-
});
|
|
860
|
+
const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
|
|
861
|
+
|
|
862
|
+
while (true) {
|
|
863
|
+
if (Date.now() > timeoutDeadline) {
|
|
864
|
+
failedDeployments.push({
|
|
865
|
+
name: func["name"],
|
|
866
|
+
$id: func["$id"],
|
|
867
|
+
deployment: deploymentId,
|
|
868
|
+
});
|
|
869
|
+
updaterRow.fail({
|
|
870
|
+
errorMessage: "Deployment timed out after 10 minutes",
|
|
871
|
+
});
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
1531
874
|
|
|
1532
|
-
|
|
875
|
+
const functionsServicePoll = await getFunctionsService(
|
|
876
|
+
this.projectClient,
|
|
877
|
+
);
|
|
878
|
+
response = await functionsServicePoll.getDeployment({
|
|
879
|
+
functionId: func["$id"],
|
|
880
|
+
deploymentId: deploymentId,
|
|
881
|
+
});
|
|
1533
882
|
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
883
|
+
const status = response["status"];
|
|
884
|
+
if (status === "ready") {
|
|
885
|
+
successfullyDeployed++;
|
|
886
|
+
|
|
887
|
+
let url = "";
|
|
888
|
+
const proxyServiceUrl = await getProxyService(
|
|
889
|
+
this.projectClient,
|
|
890
|
+
);
|
|
891
|
+
const res = await proxyServiceUrl.listRules({
|
|
892
|
+
queries: [
|
|
893
|
+
Query.limit(1),
|
|
894
|
+
Query.equal("deploymentResourceType", "function"),
|
|
895
|
+
Query.equal("deploymentResourceId", func["$id"]),
|
|
896
|
+
Query.equal("trigger", "manual"),
|
|
897
|
+
],
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
if (Number(res.total) === 1) {
|
|
901
|
+
url = `https://${res.rules[0].domain}`;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
updaterRow.update({ status: "Deployed", end: url });
|
|
905
|
+
|
|
906
|
+
break;
|
|
907
|
+
} else if (status === "failed") {
|
|
908
|
+
failedDeployments.push({
|
|
909
|
+
name: func["name"],
|
|
910
|
+
$id: func["$id"],
|
|
911
|
+
deployment: response["$id"],
|
|
912
|
+
});
|
|
913
|
+
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
914
|
+
|
|
915
|
+
break;
|
|
916
|
+
} else {
|
|
917
|
+
updaterRow.update({
|
|
918
|
+
status: "Deploying",
|
|
919
|
+
end: `Current status: ${status}`,
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
await new Promise((resolve) =>
|
|
924
|
+
setTimeout(resolve, POLL_DEBOUNCE),
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
} catch (e: any) {
|
|
928
|
+
errors.push(e);
|
|
929
|
+
updaterRow.fail({
|
|
930
|
+
errorMessage:
|
|
931
|
+
e.message ?? "Unknown error occurred. Please try again",
|
|
932
|
+
});
|
|
933
|
+
}
|
|
1543
934
|
}
|
|
1544
935
|
|
|
1545
|
-
updaterRow.
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
936
|
+
updaterRow.stopSpinner();
|
|
937
|
+
}),
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
Spinner.stop();
|
|
941
|
+
|
|
942
|
+
return {
|
|
943
|
+
successfullyPushed,
|
|
944
|
+
successfullyDeployed,
|
|
945
|
+
failedDeployments,
|
|
946
|
+
errors,
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
public async pushSites(
|
|
951
|
+
sites: any[],
|
|
952
|
+
options: {
|
|
953
|
+
async?: boolean;
|
|
954
|
+
code?: boolean;
|
|
955
|
+
withVariables?: boolean;
|
|
956
|
+
} = {},
|
|
957
|
+
): Promise<{
|
|
958
|
+
successfullyPushed: number;
|
|
959
|
+
successfullyDeployed: number;
|
|
960
|
+
failedDeployments: any[];
|
|
961
|
+
errors: any[];
|
|
962
|
+
}> {
|
|
963
|
+
const { async: asyncDeploy, code, withVariables } = options;
|
|
964
|
+
|
|
965
|
+
Spinner.start(false);
|
|
966
|
+
let successfullyPushed = 0;
|
|
967
|
+
let successfullyDeployed = 0;
|
|
968
|
+
const failedDeployments: any[] = [];
|
|
969
|
+
const errors: any[] = [];
|
|
970
|
+
|
|
971
|
+
await Promise.all(
|
|
972
|
+
sites.map(async (site: any) => {
|
|
973
|
+
let response: any = {};
|
|
974
|
+
|
|
975
|
+
const ignore = site.ignore ? "appwrite.config.json" : ".gitignore";
|
|
976
|
+
let siteExists = false;
|
|
977
|
+
let deploymentCreated = false;
|
|
978
|
+
|
|
979
|
+
const updaterRow = new Spinner({
|
|
980
|
+
status: "",
|
|
981
|
+
resource: site.name,
|
|
982
|
+
id: site["$id"],
|
|
983
|
+
end: `Ignoring using: ${ignore}`,
|
|
1560
984
|
});
|
|
1561
|
-
} catch (e: any) {
|
|
1562
|
-
if (Number(e.code) === 404) {
|
|
1563
|
-
siteExists = false;
|
|
1564
|
-
} else {
|
|
1565
|
-
errors.push(e);
|
|
1566
|
-
updaterRow.fail({
|
|
1567
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
1568
|
-
});
|
|
1569
|
-
return;
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
985
|
|
|
1573
|
-
|
|
1574
|
-
updaterRow.update({ status: "Creating" }).replaceSpinner(SPINNER_DOTS);
|
|
986
|
+
updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
|
|
1575
987
|
|
|
988
|
+
const sitesService = await getSitesService(this.projectClient);
|
|
1576
989
|
try {
|
|
1577
|
-
response = await sitesService.
|
|
1578
|
-
|
|
990
|
+
response = await sitesService.get({ siteId: site["$id"] });
|
|
991
|
+
siteExists = true;
|
|
992
|
+
if (response.framework !== site.framework) {
|
|
993
|
+
updaterRow.fail({
|
|
994
|
+
errorMessage: `Framework mismatch! (local=${site.framework},remote=${response.framework}) Please delete remote site or update your appwrite.config.json`,
|
|
995
|
+
});
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
updaterRow
|
|
1000
|
+
.update({ status: "Updating" })
|
|
1001
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
1002
|
+
|
|
1003
|
+
response = await sitesService.update({
|
|
1004
|
+
siteId: site["$id"],
|
|
1579
1005
|
name: site.name,
|
|
1580
1006
|
framework: site.framework,
|
|
1581
1007
|
enabled: site.enabled,
|
|
@@ -1588,617 +1014,774 @@ const pushSite = async ({
|
|
|
1588
1014
|
adapter: site.adapter,
|
|
1589
1015
|
specification: site.specification,
|
|
1590
1016
|
});
|
|
1017
|
+
} catch (e: any) {
|
|
1018
|
+
if (Number(e.code) === 404) {
|
|
1019
|
+
siteExists = false;
|
|
1020
|
+
} else {
|
|
1021
|
+
errors.push(e);
|
|
1022
|
+
updaterRow.fail({
|
|
1023
|
+
errorMessage:
|
|
1024
|
+
e.message ?? "General error occurs please try again",
|
|
1025
|
+
});
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
if (!siteExists) {
|
|
1031
|
+
updaterRow
|
|
1032
|
+
.update({ status: "Creating" })
|
|
1033
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
1591
1034
|
|
|
1592
|
-
let domain = "";
|
|
1593
1035
|
try {
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1036
|
+
response = await sitesService.create({
|
|
1037
|
+
siteId: site.$id,
|
|
1038
|
+
name: site.name,
|
|
1039
|
+
framework: site.framework,
|
|
1040
|
+
enabled: site.enabled,
|
|
1041
|
+
logging: site.logging,
|
|
1042
|
+
timeout: site.timeout,
|
|
1043
|
+
installCommand: site.installCommand,
|
|
1044
|
+
buildCommand: site.buildCommand,
|
|
1045
|
+
outputDirectory: site.outputDirectory,
|
|
1046
|
+
buildRuntime: site.buildRuntime,
|
|
1047
|
+
adapter: site.adapter,
|
|
1048
|
+
specification: site.specification,
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
let domain = "";
|
|
1052
|
+
try {
|
|
1053
|
+
const consoleService = await getConsoleService(
|
|
1054
|
+
this.consoleClient,
|
|
1055
|
+
);
|
|
1056
|
+
const variables = await consoleService.variables();
|
|
1057
|
+
domain = ID.unique() + "." + variables["_APP_DOMAIN_SITES"];
|
|
1058
|
+
} catch (err) {
|
|
1059
|
+
this.error("Error fetching console variables.");
|
|
1060
|
+
throw err;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
try {
|
|
1064
|
+
const proxyService = await getProxyService(this.projectClient);
|
|
1065
|
+
await proxyService.createSiteRule(domain, site.$id);
|
|
1066
|
+
} catch (err) {
|
|
1067
|
+
this.error("Error creating site rule.");
|
|
1068
|
+
throw err;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
updaterRow.update({ status: "Created" });
|
|
1072
|
+
} catch (e: any) {
|
|
1073
|
+
errors.push(e);
|
|
1074
|
+
updaterRow.fail({
|
|
1075
|
+
errorMessage:
|
|
1076
|
+
e.message ?? "General error occurs please try again",
|
|
1077
|
+
});
|
|
1078
|
+
return;
|
|
1600
1079
|
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
if (withVariables) {
|
|
1083
|
+
updaterRow
|
|
1084
|
+
.update({ status: "Creating variables" })
|
|
1085
|
+
.replaceSpinner(SPINNER_DOTS);
|
|
1086
|
+
|
|
1087
|
+
const sitesServiceForVars = await getSitesService(this.projectClient);
|
|
1088
|
+
const { variables } = await paginate(
|
|
1089
|
+
async (args: any) => {
|
|
1090
|
+
return await sitesServiceForVars.listVariables({
|
|
1091
|
+
siteId: args.siteId,
|
|
1092
|
+
});
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
siteId: site["$id"],
|
|
1096
|
+
},
|
|
1097
|
+
100,
|
|
1098
|
+
"variables",
|
|
1099
|
+
);
|
|
1100
|
+
|
|
1101
|
+
await Promise.all(
|
|
1102
|
+
variables.map(async (variable: any) => {
|
|
1103
|
+
const sitesServiceDel = await getSitesService(this.projectClient);
|
|
1104
|
+
await sitesServiceDel.deleteVariable({
|
|
1105
|
+
siteId: site["$id"],
|
|
1106
|
+
variableId: variable["$id"],
|
|
1107
|
+
});
|
|
1108
|
+
}),
|
|
1109
|
+
);
|
|
1601
1110
|
|
|
1111
|
+
const envFileLocation = `${site["path"]}/.env`;
|
|
1112
|
+
let envVariables: Array<{ key: string; value: string }> = [];
|
|
1602
1113
|
try {
|
|
1603
|
-
|
|
1604
|
-
|
|
1114
|
+
if (fs.existsSync(envFileLocation)) {
|
|
1115
|
+
const envObject = parseDotenv(
|
|
1116
|
+
fs.readFileSync(envFileLocation, "utf8"),
|
|
1117
|
+
);
|
|
1118
|
+
envVariables = Object.entries(envObject || {}).map(
|
|
1119
|
+
([key, value]) => ({ key, value }),
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1605
1122
|
} catch (error) {
|
|
1606
|
-
|
|
1607
|
-
throw error;
|
|
1123
|
+
envVariables = [];
|
|
1608
1124
|
}
|
|
1125
|
+
await Promise.all(
|
|
1126
|
+
envVariables.map(async (variable) => {
|
|
1127
|
+
const sitesServiceCreate = await getSitesService(
|
|
1128
|
+
this.projectClient,
|
|
1129
|
+
);
|
|
1130
|
+
await sitesServiceCreate.createVariable({
|
|
1131
|
+
siteId: site["$id"],
|
|
1132
|
+
key: variable.key,
|
|
1133
|
+
value: variable.value,
|
|
1134
|
+
secret: false,
|
|
1135
|
+
});
|
|
1136
|
+
}),
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
if (code === false) {
|
|
1141
|
+
successfullyPushed++;
|
|
1142
|
+
successfullyDeployed++;
|
|
1143
|
+
updaterRow.update({ status: "Pushed" });
|
|
1144
|
+
updaterRow.stopSpinner();
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
try {
|
|
1149
|
+
updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_DOTS);
|
|
1150
|
+
const sitesServiceDeploy = await getSitesService(this.projectClient);
|
|
1151
|
+
|
|
1152
|
+
const result = await pushDeployment({
|
|
1153
|
+
resourcePath: site.path,
|
|
1154
|
+
createDeployment: async (codeFile) => {
|
|
1155
|
+
return await sitesServiceDeploy.createDeployment({
|
|
1156
|
+
siteId: site["$id"],
|
|
1157
|
+
installCommand: site.installCommand,
|
|
1158
|
+
buildCommand: site.buildCommand,
|
|
1159
|
+
outputDirectory: site.outputDirectory,
|
|
1160
|
+
code: codeFile,
|
|
1161
|
+
activate: true,
|
|
1162
|
+
});
|
|
1163
|
+
},
|
|
1164
|
+
pollForStatus: false,
|
|
1165
|
+
});
|
|
1609
1166
|
|
|
1610
|
-
|
|
1167
|
+
response = result.deployment;
|
|
1168
|
+
updaterRow.update({ status: "Pushed" });
|
|
1169
|
+
deploymentCreated = true;
|
|
1170
|
+
successfullyPushed++;
|
|
1611
1171
|
} catch (e: any) {
|
|
1612
1172
|
errors.push(e);
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1173
|
+
|
|
1174
|
+
switch (e.code) {
|
|
1175
|
+
case "ENOENT":
|
|
1176
|
+
updaterRow.fail({
|
|
1177
|
+
errorMessage: "Not found in the current directory. Skipping...",
|
|
1178
|
+
});
|
|
1179
|
+
break;
|
|
1180
|
+
default:
|
|
1181
|
+
updaterRow.fail({
|
|
1182
|
+
errorMessage:
|
|
1183
|
+
e.message ?? "An unknown error occurred. Please try again.",
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1617
1186
|
}
|
|
1618
|
-
}
|
|
1619
1187
|
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1188
|
+
if (deploymentCreated && !asyncDeploy) {
|
|
1189
|
+
try {
|
|
1190
|
+
const deploymentId = response["$id"];
|
|
1191
|
+
updaterRow.update({
|
|
1192
|
+
status: "Deploying",
|
|
1193
|
+
end: "Checking deployment status...",
|
|
1194
|
+
});
|
|
1624
1195
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1196
|
+
const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
|
|
1197
|
+
|
|
1198
|
+
while (true) {
|
|
1199
|
+
if (Date.now() > timeoutDeadline) {
|
|
1200
|
+
failedDeployments.push({
|
|
1201
|
+
name: site["name"],
|
|
1202
|
+
$id: site["$id"],
|
|
1203
|
+
deployment: deploymentId,
|
|
1204
|
+
});
|
|
1205
|
+
updaterRow.fail({
|
|
1206
|
+
errorMessage: "Deployment timed out after 10 minutes",
|
|
1207
|
+
});
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1636
1210
|
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1211
|
+
const sitesServicePoll = await getSitesService(
|
|
1212
|
+
this.projectClient,
|
|
1213
|
+
);
|
|
1214
|
+
response = await sitesServicePoll.getDeployment({
|
|
1215
|
+
siteId: site["$id"],
|
|
1216
|
+
deploymentId: deploymentId,
|
|
1217
|
+
});
|
|
1218
|
+
|
|
1219
|
+
const status = response["status"];
|
|
1220
|
+
if (status === "ready") {
|
|
1221
|
+
successfullyDeployed++;
|
|
1222
|
+
|
|
1223
|
+
let url = "";
|
|
1224
|
+
const proxyServiceUrl = await getProxyService(
|
|
1225
|
+
this.projectClient,
|
|
1226
|
+
);
|
|
1227
|
+
const res = await proxyServiceUrl.listRules({
|
|
1228
|
+
queries: [
|
|
1229
|
+
Query.limit(1),
|
|
1230
|
+
Query.equal("deploymentResourceType", "site"),
|
|
1231
|
+
Query.equal("deploymentResourceId", site["$id"]),
|
|
1232
|
+
Query.equal("trigger", "manual"),
|
|
1233
|
+
],
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
if (Number(res.total) === 1) {
|
|
1237
|
+
url = `https://${res.rules[0].domain}`;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
updaterRow.update({ status: "Deployed", end: url });
|
|
1241
|
+
|
|
1242
|
+
break;
|
|
1243
|
+
} else if (status === "failed") {
|
|
1244
|
+
failedDeployments.push({
|
|
1245
|
+
name: site["name"],
|
|
1246
|
+
$id: site["$id"],
|
|
1247
|
+
deployment: response["$id"],
|
|
1248
|
+
});
|
|
1249
|
+
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
1250
|
+
|
|
1251
|
+
break;
|
|
1252
|
+
} else {
|
|
1253
|
+
updaterRow.update({
|
|
1254
|
+
status: "Deploying",
|
|
1255
|
+
end: `Current status: ${status}`,
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
await new Promise((resolve) =>
|
|
1260
|
+
setTimeout(resolve, POLL_DEBOUNCE),
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
} catch (e: any) {
|
|
1264
|
+
errors.push(e);
|
|
1265
|
+
updaterRow.fail({
|
|
1266
|
+
errorMessage:
|
|
1267
|
+
e.message ?? "Unknown error occurred. Please try again",
|
|
1643
1268
|
});
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
updaterRow.stopSpinner();
|
|
1273
|
+
}),
|
|
1274
|
+
);
|
|
1275
|
+
|
|
1276
|
+
Spinner.stop();
|
|
1277
|
+
|
|
1278
|
+
return {
|
|
1279
|
+
successfullyPushed,
|
|
1280
|
+
successfullyDeployed,
|
|
1281
|
+
failedDeployments,
|
|
1282
|
+
errors,
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
public async pushTables(
|
|
1287
|
+
tables: any[],
|
|
1288
|
+
options: PushTableOptions = {},
|
|
1289
|
+
): Promise<{
|
|
1290
|
+
successfullyPushed: number;
|
|
1291
|
+
errors: any[];
|
|
1292
|
+
}> {
|
|
1293
|
+
const { attempts, skipConfirmation = false } = options;
|
|
1294
|
+
const pollMaxDebounces = attempts ?? POLL_DEFAULT_VALUE;
|
|
1295
|
+
const pools = new Pools(pollMaxDebounces);
|
|
1296
|
+
const attributes = new Attributes(pools, skipConfirmation);
|
|
1646
1297
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1298
|
+
let tablesChanged = new Set();
|
|
1299
|
+
const errors: any[] = [];
|
|
1300
|
+
|
|
1301
|
+
// Parallel tables actions
|
|
1302
|
+
await Promise.all(
|
|
1303
|
+
tables.map(async (table: any) => {
|
|
1649
1304
|
try {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1305
|
+
const tablesService = await getTablesDBService(this.projectClient);
|
|
1306
|
+
const remoteTable = await tablesService.getTable({
|
|
1307
|
+
databaseId: table["databaseId"],
|
|
1308
|
+
tableId: table["$id"],
|
|
1309
|
+
});
|
|
1310
|
+
|
|
1311
|
+
const changes: string[] = [];
|
|
1312
|
+
if (remoteTable.name !== table.name) changes.push("name");
|
|
1313
|
+
if (remoteTable.rowSecurity !== table.rowSecurity)
|
|
1314
|
+
changes.push("rowSecurity");
|
|
1315
|
+
if (remoteTable.enabled !== table.enabled) changes.push("enabled");
|
|
1316
|
+
if (
|
|
1317
|
+
JSON.stringify(remoteTable["$permissions"]) !==
|
|
1318
|
+
JSON.stringify(table["$permissions"])
|
|
1319
|
+
)
|
|
1320
|
+
changes.push("permissions");
|
|
1321
|
+
|
|
1322
|
+
if (changes.length > 0) {
|
|
1323
|
+
await tablesService.updateTable({
|
|
1324
|
+
databaseId: table["databaseId"],
|
|
1325
|
+
tableId: table["$id"],
|
|
1326
|
+
name: table.name,
|
|
1327
|
+
rowSecurity: table.rowSecurity,
|
|
1328
|
+
permissions: table["$permissions"],
|
|
1329
|
+
});
|
|
1330
|
+
|
|
1331
|
+
this.success(
|
|
1332
|
+
`Updated ${table.name} ( ${table["$id"]} ) - ${changes.join(", ")}`,
|
|
1653
1333
|
);
|
|
1654
|
-
|
|
1655
|
-
|
|
1334
|
+
tablesChanged.add(table["$id"]);
|
|
1335
|
+
}
|
|
1336
|
+
table.remoteVersion = remoteTable;
|
|
1337
|
+
|
|
1338
|
+
table.isExisted = true;
|
|
1339
|
+
} catch (e: any) {
|
|
1340
|
+
if (Number(e.code) === 404) {
|
|
1341
|
+
this.log(
|
|
1342
|
+
`Table ${table.name} does not exist in the project. Creating ... `,
|
|
1656
1343
|
);
|
|
1344
|
+
const tablesService = await getTablesDBService(this.projectClient);
|
|
1345
|
+
await tablesService.createTable({
|
|
1346
|
+
databaseId: table["databaseId"],
|
|
1347
|
+
tableId: table["$id"],
|
|
1348
|
+
name: table.name,
|
|
1349
|
+
rowSecurity: table.rowSecurity,
|
|
1350
|
+
permissions: table["$permissions"]
|
|
1351
|
+
? [...table["$permissions"]]
|
|
1352
|
+
: undefined,
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
this.success(`Created ${table.name} ( ${table["$id"]} )`);
|
|
1356
|
+
tablesChanged.add(table["$id"]);
|
|
1357
|
+
} else {
|
|
1358
|
+
errors.push(e);
|
|
1359
|
+
throw e;
|
|
1657
1360
|
}
|
|
1658
|
-
} catch (error) {
|
|
1659
|
-
// Handle parsing errors gracefully
|
|
1660
|
-
envVariables = [];
|
|
1661
1361
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1362
|
+
}),
|
|
1363
|
+
);
|
|
1364
|
+
|
|
1365
|
+
// Serialize attribute actions
|
|
1366
|
+
for (let table of tables) {
|
|
1367
|
+
let columns = table.columns;
|
|
1368
|
+
let indexes = table.indexes;
|
|
1369
|
+
|
|
1370
|
+
if (table.isExisted) {
|
|
1371
|
+
columns = await attributes.attributesToCreate(
|
|
1372
|
+
table.remoteVersion.columns,
|
|
1373
|
+
table.columns,
|
|
1374
|
+
table as Collection,
|
|
1375
|
+
);
|
|
1376
|
+
indexes = await attributes.attributesToCreate(
|
|
1377
|
+
table.remoteVersion.indexes,
|
|
1378
|
+
table.indexes,
|
|
1379
|
+
table as Collection,
|
|
1380
|
+
true,
|
|
1672
1381
|
);
|
|
1673
|
-
}
|
|
1674
1382
|
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1383
|
+
if (
|
|
1384
|
+
Array.isArray(columns) &&
|
|
1385
|
+
columns.length <= 0 &&
|
|
1386
|
+
Array.isArray(indexes) &&
|
|
1387
|
+
indexes.length <= 0
|
|
1388
|
+
) {
|
|
1389
|
+
continue;
|
|
1390
|
+
}
|
|
1681
1391
|
}
|
|
1682
1392
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
response = await sitesService.createDeployment({
|
|
1687
|
-
siteId: site["$id"],
|
|
1688
|
-
installCommand: site.installCommand,
|
|
1689
|
-
buildCommand: site.buildCommand,
|
|
1690
|
-
outputDirectory: site.outputDirectory,
|
|
1691
|
-
code: site.path,
|
|
1692
|
-
activate: true,
|
|
1693
|
-
});
|
|
1393
|
+
this.log(
|
|
1394
|
+
`Pushing table ${table.name} ( ${table["databaseId"]} - ${table["$id"]} ) attributes`,
|
|
1395
|
+
);
|
|
1694
1396
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
} catch (e: any) {
|
|
1397
|
+
try {
|
|
1398
|
+
await attributes.createColumns(columns, table as Collection);
|
|
1399
|
+
} catch (e) {
|
|
1699
1400
|
errors.push(e);
|
|
1401
|
+
throw e;
|
|
1402
|
+
}
|
|
1700
1403
|
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
break;
|
|
1707
|
-
default:
|
|
1708
|
-
updaterRow.fail({
|
|
1709
|
-
errorMessage:
|
|
1710
|
-
e.message ?? "An unknown error occurred. Please try again.",
|
|
1711
|
-
});
|
|
1712
|
-
}
|
|
1404
|
+
try {
|
|
1405
|
+
await attributes.createIndexes(indexes, table as Collection);
|
|
1406
|
+
} catch (e) {
|
|
1407
|
+
errors.push(e);
|
|
1408
|
+
throw e;
|
|
1713
1409
|
}
|
|
1410
|
+
tablesChanged.add(table["$id"]);
|
|
1411
|
+
this.success(`Successfully pushed ${table.name} ( ${table["$id"]} )`);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
return {
|
|
1415
|
+
successfullyPushed: tablesChanged.size,
|
|
1416
|
+
errors,
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
public async pushCollections(
|
|
1421
|
+
collections: any[],
|
|
1422
|
+
options: { skipConfirmation?: boolean } = {},
|
|
1423
|
+
): Promise<{
|
|
1424
|
+
successfullyPushed: number;
|
|
1425
|
+
errors: any[];
|
|
1426
|
+
}> {
|
|
1427
|
+
const { skipConfirmation = false } = options;
|
|
1428
|
+
const pools = new Pools(POLL_DEFAULT_VALUE);
|
|
1429
|
+
const attributes = new Attributes(pools, skipConfirmation);
|
|
1430
|
+
|
|
1431
|
+
const errors: any[] = [];
|
|
1432
|
+
|
|
1433
|
+
const databases = Array.from(
|
|
1434
|
+
new Set(collections.map((collection: any) => collection["databaseId"])),
|
|
1435
|
+
);
|
|
1714
1436
|
|
|
1715
|
-
|
|
1437
|
+
// Parallel db actions
|
|
1438
|
+
await Promise.all(
|
|
1439
|
+
databases.map(async (databaseId: any) => {
|
|
1440
|
+
const databasesService = await getDatabasesService(this.projectClient);
|
|
1716
1441
|
try {
|
|
1717
|
-
const
|
|
1718
|
-
updaterRow.update({
|
|
1719
|
-
status: "Deploying",
|
|
1720
|
-
end: "Checking deployment status...",
|
|
1721
|
-
});
|
|
1722
|
-
let pollChecks = 0;
|
|
1442
|
+
const database = await databasesService.get(databaseId);
|
|
1723
1443
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
});
|
|
1444
|
+
// Note: We can't get the local database name here since we don't have access to localConfig
|
|
1445
|
+
// This will need to be handled by the caller if needed
|
|
1446
|
+
const localDatabaseName =
|
|
1447
|
+
collections.find((c: any) => c.databaseId === databaseId)
|
|
1448
|
+
?.databaseName ?? databaseId;
|
|
1730
1449
|
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
successfullyDeployed++;
|
|
1734
|
-
|
|
1735
|
-
let url = "";
|
|
1736
|
-
const proxyService = await getProxyService();
|
|
1737
|
-
const res = await proxyService.listRules([
|
|
1738
|
-
JSON.stringify({ method: "limit", values: [1] }),
|
|
1739
|
-
JSON.stringify({
|
|
1740
|
-
method: "equal",
|
|
1741
|
-
attribute: "deploymentResourceType",
|
|
1742
|
-
values: ["site"],
|
|
1743
|
-
}),
|
|
1744
|
-
JSON.stringify({
|
|
1745
|
-
method: "equal",
|
|
1746
|
-
attribute: "deploymentResourceId",
|
|
1747
|
-
values: [site["$id"]],
|
|
1748
|
-
}),
|
|
1749
|
-
JSON.stringify({
|
|
1750
|
-
method: "equal",
|
|
1751
|
-
attribute: "trigger",
|
|
1752
|
-
values: ["manual"],
|
|
1753
|
-
}),
|
|
1754
|
-
]);
|
|
1755
|
-
|
|
1756
|
-
if (Number(res.total) === 1) {
|
|
1757
|
-
url = res.rules[0].domain;
|
|
1758
|
-
}
|
|
1450
|
+
if (database.name !== localDatabaseName) {
|
|
1451
|
+
await databasesService.update(databaseId, localDatabaseName);
|
|
1759
1452
|
|
|
1760
|
-
|
|
1453
|
+
this.success(`Updated ${localDatabaseName} ( ${databaseId} ) name`);
|
|
1454
|
+
}
|
|
1455
|
+
} catch (err: any) {
|
|
1456
|
+
if (Number(err.code) === 404) {
|
|
1457
|
+
this.log(`Database ${databaseId} not found. Creating it now ...`);
|
|
1761
1458
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
name: site["name"],
|
|
1766
|
-
$id: site["$id"],
|
|
1767
|
-
deployment: response["$id"],
|
|
1768
|
-
});
|
|
1769
|
-
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
1459
|
+
const localDatabaseName =
|
|
1460
|
+
collections.find((c: any) => c.databaseId === databaseId)
|
|
1461
|
+
?.databaseName ?? databaseId;
|
|
1770
1462
|
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1463
|
+
await databasesService.create(databaseId, localDatabaseName);
|
|
1464
|
+
} else {
|
|
1465
|
+
throw err;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}),
|
|
1469
|
+
);
|
|
1778
1470
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1471
|
+
// Parallel collection actions
|
|
1472
|
+
await Promise.all(
|
|
1473
|
+
collections.map(async (collection: any) => {
|
|
1474
|
+
try {
|
|
1475
|
+
const databasesService = await getDatabasesService(
|
|
1476
|
+
this.projectClient,
|
|
1477
|
+
);
|
|
1478
|
+
const remoteCollection = await databasesService.getCollection(
|
|
1479
|
+
collection["databaseId"],
|
|
1480
|
+
collection["$id"],
|
|
1481
|
+
);
|
|
1482
|
+
|
|
1483
|
+
if (remoteCollection.name !== collection.name) {
|
|
1484
|
+
await databasesService.updateCollection(
|
|
1485
|
+
collection["databaseId"],
|
|
1486
|
+
collection["$id"],
|
|
1487
|
+
collection.name,
|
|
1488
|
+
);
|
|
1489
|
+
|
|
1490
|
+
this.success(
|
|
1491
|
+
`Updated ${collection.name} ( ${collection["$id"]} ) name`,
|
|
1782
1492
|
);
|
|
1783
1493
|
}
|
|
1494
|
+
collection.remoteVersion = remoteCollection;
|
|
1495
|
+
|
|
1496
|
+
collection.isExisted = true;
|
|
1784
1497
|
} catch (e: any) {
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1498
|
+
if (Number(e.code) === 404) {
|
|
1499
|
+
this.log(
|
|
1500
|
+
`Collection ${collection.name} does not exist in the project. Creating ... `,
|
|
1501
|
+
);
|
|
1502
|
+
const databasesService = await getDatabasesService(
|
|
1503
|
+
this.projectClient,
|
|
1504
|
+
);
|
|
1505
|
+
await databasesService.createCollection({
|
|
1506
|
+
databaseId: collection["databaseId"],
|
|
1507
|
+
collectionId: collection["$id"],
|
|
1508
|
+
name: collection.name,
|
|
1509
|
+
documentSecurity: collection.documentSecurity,
|
|
1510
|
+
permissions: collection["$permissions"],
|
|
1511
|
+
});
|
|
1512
|
+
} else {
|
|
1513
|
+
errors.push(e);
|
|
1514
|
+
throw e;
|
|
1515
|
+
}
|
|
1790
1516
|
}
|
|
1517
|
+
}),
|
|
1518
|
+
);
|
|
1519
|
+
|
|
1520
|
+
let numberOfCollections = 0;
|
|
1521
|
+
// Serialize attribute actions
|
|
1522
|
+
for (let collection of collections) {
|
|
1523
|
+
let collectionAttributes = collection.attributes;
|
|
1524
|
+
let indexes = collection.indexes;
|
|
1525
|
+
|
|
1526
|
+
if (collection.isExisted) {
|
|
1527
|
+
collectionAttributes = await attributes.attributesToCreate(
|
|
1528
|
+
collection.remoteVersion.attributes,
|
|
1529
|
+
collection.attributes,
|
|
1530
|
+
collection as Collection,
|
|
1531
|
+
);
|
|
1532
|
+
indexes = await attributes.attributesToCreate(
|
|
1533
|
+
collection.remoteVersion.indexes,
|
|
1534
|
+
collection.indexes,
|
|
1535
|
+
collection as Collection,
|
|
1536
|
+
true,
|
|
1537
|
+
);
|
|
1538
|
+
|
|
1539
|
+
if (
|
|
1540
|
+
Array.isArray(collectionAttributes) &&
|
|
1541
|
+
collectionAttributes.length <= 0 &&
|
|
1542
|
+
Array.isArray(indexes) &&
|
|
1543
|
+
indexes.length <= 0
|
|
1544
|
+
) {
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
this.log(
|
|
1550
|
+
`Pushing collection ${collection.name} ( ${collection["databaseId"]} - ${collection["$id"]} ) attributes`,
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
try {
|
|
1554
|
+
await attributes.createAttributes(
|
|
1555
|
+
collectionAttributes,
|
|
1556
|
+
collection as Collection,
|
|
1557
|
+
);
|
|
1558
|
+
} catch (e) {
|
|
1559
|
+
errors.push(e);
|
|
1560
|
+
throw e;
|
|
1791
1561
|
}
|
|
1792
1562
|
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1563
|
+
try {
|
|
1564
|
+
await attributes.createIndexes(indexes, collection as Collection);
|
|
1565
|
+
} catch (e) {
|
|
1566
|
+
errors.push(e);
|
|
1567
|
+
throw e;
|
|
1568
|
+
}
|
|
1569
|
+
numberOfCollections++;
|
|
1570
|
+
this.success(
|
|
1571
|
+
`Successfully pushed ${collection.name} ( ${collection["$id"]} )`,
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
return {
|
|
1576
|
+
successfullyPushed: numberOfCollections,
|
|
1577
|
+
errors,
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
async function createPushInstance(silent = false): Promise<Push> {
|
|
1583
|
+
const projectClient = await sdkForProject();
|
|
1584
|
+
const consoleClient = await sdkForConsole();
|
|
1585
|
+
return new Push(projectClient, consoleClient, silent);
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
const pushResources = async ({
|
|
1589
|
+
skipDeprecated = false,
|
|
1590
|
+
}: {
|
|
1591
|
+
skipDeprecated?: boolean;
|
|
1592
|
+
} = {}): Promise<void> => {
|
|
1593
|
+
if (cliConfig.all) {
|
|
1594
|
+
checkDeployConditions(localConfig);
|
|
1595
|
+
|
|
1596
|
+
const pushInstance = await createPushInstance();
|
|
1597
|
+
const config = localConfig.getProject() as ConfigType;
|
|
1598
|
+
|
|
1599
|
+
await pushInstance.pushResources(config, {
|
|
1600
|
+
skipDeprecated,
|
|
1601
|
+
functionOptions: { code: true, withVariables: false },
|
|
1602
|
+
siteOptions: { code: true, withVariables: false },
|
|
1603
|
+
});
|
|
1604
|
+
} else {
|
|
1605
|
+
const actions: Record<string, (options?: any) => Promise<void>> = {
|
|
1606
|
+
settings: pushSettings,
|
|
1607
|
+
functions: pushFunction,
|
|
1608
|
+
sites: pushSite,
|
|
1609
|
+
collections: pushCollection,
|
|
1610
|
+
tables: pushTable,
|
|
1611
|
+
buckets: pushBucket,
|
|
1612
|
+
teams: pushTeam,
|
|
1613
|
+
messages: pushMessagingTopic,
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
if (skipDeprecated) {
|
|
1617
|
+
delete actions.collections;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
const answers = await inquirer.prompt(questionsPushResources);
|
|
1621
|
+
|
|
1622
|
+
const action = actions[answers.resource];
|
|
1623
|
+
if (action !== undefined) {
|
|
1624
|
+
await action();
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1628
|
+
|
|
1629
|
+
const pushSettings = async (): Promise<void> => {
|
|
1630
|
+
checkDeployConditions(localConfig);
|
|
1796
1631
|
|
|
1797
|
-
|
|
1632
|
+
try {
|
|
1633
|
+
const projectsService = await getProjectsService();
|
|
1634
|
+
let response = await projectsService.get(
|
|
1635
|
+
localConfig.getProject().projectId,
|
|
1636
|
+
);
|
|
1798
1637
|
|
|
1799
|
-
|
|
1800
|
-
const
|
|
1801
|
-
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/sites/site-${$id}/deployments/deployment-${deployment}`;
|
|
1638
|
+
const remoteSettings = createSettingsObject(response);
|
|
1639
|
+
const localSettings = localConfig.getProject().projectSettings ?? {};
|
|
1802
1640
|
|
|
1803
|
-
|
|
1804
|
-
|
|
1641
|
+
log("Checking for changes ...");
|
|
1642
|
+
const changes: any[] = [];
|
|
1643
|
+
|
|
1644
|
+
changes.push(
|
|
1645
|
+
...getObjectChanges(remoteSettings, localSettings, "services", "Service"),
|
|
1646
|
+
);
|
|
1647
|
+
changes.push(
|
|
1648
|
+
...getObjectChanges(
|
|
1649
|
+
remoteSettings["auth"] ?? {},
|
|
1650
|
+
localSettings["auth"] ?? {},
|
|
1651
|
+
"methods",
|
|
1652
|
+
"Auth method",
|
|
1653
|
+
),
|
|
1654
|
+
);
|
|
1655
|
+
changes.push(
|
|
1656
|
+
...getObjectChanges(
|
|
1657
|
+
remoteSettings["auth"] ?? {},
|
|
1658
|
+
localSettings["auth"] ?? {},
|
|
1659
|
+
"security",
|
|
1660
|
+
"Auth security",
|
|
1661
|
+
),
|
|
1805
1662
|
);
|
|
1806
|
-
});
|
|
1807
1663
|
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
);
|
|
1815
|
-
} else {
|
|
1816
|
-
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
1664
|
+
if (changes.length > 0) {
|
|
1665
|
+
drawTable(changes);
|
|
1666
|
+
if ((await getConfirmation()) !== true) {
|
|
1667
|
+
success(`Successfully pushed 0 project settings.`);
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1817
1670
|
}
|
|
1818
|
-
}
|
|
1819
|
-
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
1820
|
-
}
|
|
1671
|
+
} catch (e) {}
|
|
1821
1672
|
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1673
|
+
try {
|
|
1674
|
+
log("Pushing project settings ...");
|
|
1675
|
+
|
|
1676
|
+
const pushInstance = await createPushInstance();
|
|
1677
|
+
const config = localConfig.getProject();
|
|
1678
|
+
|
|
1679
|
+
await pushInstance.pushSettings({
|
|
1680
|
+
projectId: config.projectId,
|
|
1681
|
+
projectName: config.projectName,
|
|
1682
|
+
settings: config.projectSettings,
|
|
1825
1683
|
});
|
|
1684
|
+
|
|
1685
|
+
success(`Successfully pushed ${chalk.bold("all")} project settings.`);
|
|
1686
|
+
} catch (e) {
|
|
1687
|
+
throw e;
|
|
1826
1688
|
}
|
|
1827
1689
|
};
|
|
1828
1690
|
|
|
1829
|
-
const
|
|
1830
|
-
|
|
1691
|
+
const pushSite = async ({
|
|
1692
|
+
siteId,
|
|
1831
1693
|
async: asyncDeploy,
|
|
1832
1694
|
code,
|
|
1833
1695
|
withVariables,
|
|
1834
|
-
}:
|
|
1696
|
+
}: PushSiteOptions = {}): Promise<void> => {
|
|
1835
1697
|
process.chdir(localConfig.configDirectoryPath);
|
|
1836
1698
|
|
|
1837
|
-
const
|
|
1699
|
+
const siteIds: string[] = [];
|
|
1838
1700
|
|
|
1839
|
-
if (
|
|
1840
|
-
|
|
1701
|
+
if (siteId) {
|
|
1702
|
+
siteIds.push(siteId);
|
|
1841
1703
|
} else if (cliConfig.all) {
|
|
1842
1704
|
checkDeployConditions(localConfig);
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
...
|
|
1846
|
-
return
|
|
1705
|
+
const sites = localConfig.getSites();
|
|
1706
|
+
siteIds.push(
|
|
1707
|
+
...sites.map((site: any) => {
|
|
1708
|
+
return site.$id;
|
|
1847
1709
|
}),
|
|
1848
1710
|
);
|
|
1849
1711
|
}
|
|
1850
1712
|
|
|
1851
|
-
if (
|
|
1852
|
-
const answers = await inquirer.prompt(
|
|
1853
|
-
if (answers.
|
|
1854
|
-
|
|
1713
|
+
if (siteIds.length <= 0) {
|
|
1714
|
+
const answers = await inquirer.prompt(questionsPushSites);
|
|
1715
|
+
if (answers.sites) {
|
|
1716
|
+
siteIds.push(...answers.sites);
|
|
1855
1717
|
}
|
|
1856
1718
|
}
|
|
1857
1719
|
|
|
1858
|
-
if (
|
|
1859
|
-
log("No
|
|
1720
|
+
if (siteIds.length === 0) {
|
|
1721
|
+
log("No sites found.");
|
|
1860
1722
|
hint(
|
|
1861
|
-
|
|
1723
|
+
`Use '${EXECUTABLE_NAME} pull sites' to synchronize existing one, or use '${EXECUTABLE_NAME} init site' to create a new one.`,
|
|
1862
1724
|
);
|
|
1863
1725
|
return;
|
|
1864
1726
|
}
|
|
1865
1727
|
|
|
1866
|
-
let
|
|
1867
|
-
const
|
|
1868
|
-
const
|
|
1728
|
+
let sites = siteIds.map((id: string) => {
|
|
1729
|
+
const sites = localConfig.getSites();
|
|
1730
|
+
const site = sites.find((s: any) => s.$id === id);
|
|
1869
1731
|
|
|
1870
|
-
if (!
|
|
1871
|
-
throw new Error("
|
|
1732
|
+
if (!site) {
|
|
1733
|
+
throw new Error("Site '" + id + "' not found.");
|
|
1872
1734
|
}
|
|
1873
1735
|
|
|
1874
|
-
return
|
|
1736
|
+
return site;
|
|
1875
1737
|
});
|
|
1876
1738
|
|
|
1877
|
-
log("Validating
|
|
1739
|
+
log("Validating sites ...");
|
|
1878
1740
|
// Validation is done BEFORE pushing so the deployment process can be run in async with progress update
|
|
1879
|
-
for (let
|
|
1880
|
-
if (!
|
|
1881
|
-
log(`
|
|
1741
|
+
for (let site of sites) {
|
|
1742
|
+
if (!site.buildCommand) {
|
|
1743
|
+
log(`Site ${site.name} is missing build command.`);
|
|
1882
1744
|
const answers = await inquirer.prompt(questionsGetEntrypoint);
|
|
1883
|
-
|
|
1884
|
-
localConfig.
|
|
1745
|
+
site.buildCommand = answers.entrypoint;
|
|
1746
|
+
localConfig.addSite(site);
|
|
1885
1747
|
}
|
|
1886
1748
|
}
|
|
1887
1749
|
|
|
1888
1750
|
if (
|
|
1889
1751
|
!(await approveChanges(
|
|
1890
|
-
|
|
1752
|
+
sites,
|
|
1891
1753
|
async (args: any) => {
|
|
1892
|
-
const
|
|
1893
|
-
return await
|
|
1754
|
+
const sitesService = await getSitesService();
|
|
1755
|
+
return await sitesService.get({ siteId: args.siteId });
|
|
1894
1756
|
},
|
|
1895
|
-
|
|
1896
|
-
"
|
|
1897
|
-
"
|
|
1757
|
+
KeysSite,
|
|
1758
|
+
"siteId",
|
|
1759
|
+
"sites",
|
|
1898
1760
|
["vars"],
|
|
1899
1761
|
))
|
|
1900
1762
|
) {
|
|
1901
1763
|
return;
|
|
1902
1764
|
}
|
|
1903
1765
|
|
|
1904
|
-
log("Pushing
|
|
1905
|
-
|
|
1906
|
-
Spinner.start(false);
|
|
1907
|
-
let successfullyPushed = 0;
|
|
1908
|
-
let successfullyDeployed = 0;
|
|
1909
|
-
const failedDeployments: any[] = [];
|
|
1910
|
-
const errors: any[] = [];
|
|
1911
|
-
|
|
1912
|
-
await Promise.all(
|
|
1913
|
-
functions.map(async (func: any) => {
|
|
1914
|
-
let response: any = {};
|
|
1915
|
-
|
|
1916
|
-
const ignore = func.ignore ? "appwrite.config.json" : ".gitignore";
|
|
1917
|
-
let functionExists = false;
|
|
1918
|
-
let deploymentCreated = false;
|
|
1919
|
-
|
|
1920
|
-
const updaterRow = new Spinner({
|
|
1921
|
-
status: "",
|
|
1922
|
-
resource: func.name,
|
|
1923
|
-
id: func["$id"],
|
|
1924
|
-
end: `Ignoring using: ${ignore}`,
|
|
1925
|
-
});
|
|
1926
|
-
|
|
1927
|
-
updaterRow.update({ status: "Getting" }).startSpinner(SPINNER_DOTS);
|
|
1928
|
-
const functionsService = await getFunctionsService();
|
|
1929
|
-
try {
|
|
1930
|
-
response = await functionsService.get({ functionId: func["$id"] });
|
|
1931
|
-
functionExists = true;
|
|
1932
|
-
if (response.runtime !== func.runtime) {
|
|
1933
|
-
updaterRow.fail({
|
|
1934
|
-
errorMessage: `Runtime mismatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.config.json`,
|
|
1935
|
-
});
|
|
1936
|
-
return;
|
|
1937
|
-
}
|
|
1938
|
-
|
|
1939
|
-
updaterRow.update({ status: "Updating" }).replaceSpinner(SPINNER_ARC);
|
|
1940
|
-
|
|
1941
|
-
response = await functionsService.update({
|
|
1942
|
-
functionId: func["$id"],
|
|
1943
|
-
name: func.name,
|
|
1944
|
-
runtime: func.runtime,
|
|
1945
|
-
execute: func.execute,
|
|
1946
|
-
events: func.events,
|
|
1947
|
-
schedule: func.schedule,
|
|
1948
|
-
timeout: func.timeout,
|
|
1949
|
-
enabled: func.enabled,
|
|
1950
|
-
logging: func.logging,
|
|
1951
|
-
entrypoint: func.entrypoint,
|
|
1952
|
-
commands: func.commands,
|
|
1953
|
-
scopes: func.scopes,
|
|
1954
|
-
specification: func.specification,
|
|
1955
|
-
});
|
|
1956
|
-
} catch (e: any) {
|
|
1957
|
-
if (Number(e.code) === 404) {
|
|
1958
|
-
functionExists = false;
|
|
1959
|
-
} else {
|
|
1960
|
-
errors.push(e);
|
|
1961
|
-
updaterRow.fail({
|
|
1962
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
1963
|
-
});
|
|
1964
|
-
return;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
|
|
1968
|
-
if (!functionExists) {
|
|
1969
|
-
updaterRow.update({ status: "Creating" }).replaceSpinner(SPINNER_DOTS);
|
|
1970
|
-
|
|
1971
|
-
try {
|
|
1972
|
-
response = await functionsService.create({
|
|
1973
|
-
functionId: func.$id,
|
|
1974
|
-
name: func.name,
|
|
1975
|
-
runtime: func.runtime,
|
|
1976
|
-
execute: func.execute,
|
|
1977
|
-
events: func.events,
|
|
1978
|
-
schedule: func.schedule,
|
|
1979
|
-
timeout: func.timeout,
|
|
1980
|
-
enabled: func.enabled,
|
|
1981
|
-
logging: func.logging,
|
|
1982
|
-
entrypoint: func.entrypoint,
|
|
1983
|
-
commands: func.commands,
|
|
1984
|
-
scopes: func.scopes,
|
|
1985
|
-
specification: func.specification,
|
|
1986
|
-
});
|
|
1987
|
-
|
|
1988
|
-
let domain = "";
|
|
1989
|
-
try {
|
|
1990
|
-
const consoleService = await getConsoleService();
|
|
1991
|
-
const variables = await consoleService.variables();
|
|
1992
|
-
domain = ID.unique() + "." + variables["_APP_DOMAIN_FUNCTIONS"];
|
|
1993
|
-
} catch (error) {
|
|
1994
|
-
console.error("Error fetching console variables.");
|
|
1995
|
-
throw error;
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
try {
|
|
1999
|
-
const proxyService = await getProxyService();
|
|
2000
|
-
const rule = await proxyService.createFunctionRule(
|
|
2001
|
-
domain,
|
|
2002
|
-
func.$id,
|
|
2003
|
-
);
|
|
2004
|
-
} catch (error) {
|
|
2005
|
-
console.error("Error creating function rule.");
|
|
2006
|
-
throw error;
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
updaterRow.update({ status: "Created" });
|
|
2010
|
-
} catch (e: any) {
|
|
2011
|
-
errors.push(e);
|
|
2012
|
-
updaterRow.fail({
|
|
2013
|
-
errorMessage: e.message ?? "General error occurs please try again",
|
|
2014
|
-
});
|
|
2015
|
-
return;
|
|
2016
|
-
}
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
if (withVariables) {
|
|
2020
|
-
updaterRow
|
|
2021
|
-
.update({ status: "Updating variables" })
|
|
2022
|
-
.replaceSpinner(SPINNER_ARC);
|
|
2023
|
-
|
|
2024
|
-
const functionsService = await getFunctionsService();
|
|
2025
|
-
const { variables } = await paginate(
|
|
2026
|
-
async (args: any) => {
|
|
2027
|
-
return await functionsService.listVariables({
|
|
2028
|
-
functionId: args.functionId,
|
|
2029
|
-
});
|
|
2030
|
-
},
|
|
2031
|
-
{
|
|
2032
|
-
functionId: func["$id"],
|
|
2033
|
-
},
|
|
2034
|
-
100,
|
|
2035
|
-
"variables",
|
|
2036
|
-
);
|
|
2037
|
-
|
|
2038
|
-
await Promise.all(
|
|
2039
|
-
variables.map(async (variable: any) => {
|
|
2040
|
-
const functionsService = await getFunctionsService();
|
|
2041
|
-
await functionsService.deleteVariable({
|
|
2042
|
-
functionId: func["$id"],
|
|
2043
|
-
variableId: variable["$id"],
|
|
2044
|
-
});
|
|
2045
|
-
}),
|
|
2046
|
-
);
|
|
2047
|
-
|
|
2048
|
-
const envFileLocation = `${func["path"]}/.env`;
|
|
2049
|
-
let envVariables: Array<{ key: string; value: string }> = [];
|
|
2050
|
-
try {
|
|
2051
|
-
if (fs.existsSync(envFileLocation)) {
|
|
2052
|
-
const envObject = parseDotenv(
|
|
2053
|
-
fs.readFileSync(envFileLocation, "utf8"),
|
|
2054
|
-
);
|
|
2055
|
-
envVariables = Object.entries(envObject || {}).map(
|
|
2056
|
-
([key, value]) => ({ key, value }),
|
|
2057
|
-
);
|
|
2058
|
-
}
|
|
2059
|
-
} catch (error) {
|
|
2060
|
-
// Handle parsing errors gracefully
|
|
2061
|
-
envVariables = [];
|
|
2062
|
-
}
|
|
2063
|
-
await Promise.all(
|
|
2064
|
-
envVariables.map(async (variable) => {
|
|
2065
|
-
const functionsService = await getFunctionsService();
|
|
2066
|
-
await functionsService.createVariable({
|
|
2067
|
-
functionId: func["$id"],
|
|
2068
|
-
key: variable.key,
|
|
2069
|
-
value: variable.value,
|
|
2070
|
-
secret: false,
|
|
2071
|
-
});
|
|
2072
|
-
}),
|
|
2073
|
-
);
|
|
2074
|
-
}
|
|
2075
|
-
|
|
2076
|
-
if (code === false) {
|
|
2077
|
-
successfullyPushed++;
|
|
2078
|
-
successfullyDeployed++;
|
|
2079
|
-
updaterRow.update({ status: "Pushed" });
|
|
2080
|
-
updaterRow.stopSpinner();
|
|
2081
|
-
return;
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
try {
|
|
2085
|
-
updaterRow.update({ status: "Pushing" }).replaceSpinner(SPINNER_ARC);
|
|
2086
|
-
const functionsService = await getFunctionsService();
|
|
2087
|
-
response = await functionsService.createDeployment({
|
|
2088
|
-
functionId: func["$id"],
|
|
2089
|
-
entrypoint: func.entrypoint,
|
|
2090
|
-
commands: func.commands,
|
|
2091
|
-
code: func.path,
|
|
2092
|
-
activate: true,
|
|
2093
|
-
});
|
|
2094
|
-
|
|
2095
|
-
updaterRow.update({ status: "Pushed" });
|
|
2096
|
-
deploymentCreated = true;
|
|
2097
|
-
successfullyPushed++;
|
|
2098
|
-
} catch (e: any) {
|
|
2099
|
-
errors.push(e);
|
|
2100
|
-
|
|
2101
|
-
switch (e.code) {
|
|
2102
|
-
case "ENOENT":
|
|
2103
|
-
updaterRow.fail({
|
|
2104
|
-
errorMessage: "Not found in the current directory. Skipping...",
|
|
2105
|
-
});
|
|
2106
|
-
break;
|
|
2107
|
-
default:
|
|
2108
|
-
updaterRow.fail({
|
|
2109
|
-
errorMessage:
|
|
2110
|
-
e.message ?? "An unknown error occurred. Please try again.",
|
|
2111
|
-
});
|
|
2112
|
-
}
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
if (deploymentCreated && !asyncDeploy) {
|
|
2116
|
-
try {
|
|
2117
|
-
const deploymentId = response["$id"];
|
|
2118
|
-
updaterRow.update({
|
|
2119
|
-
status: "Deploying",
|
|
2120
|
-
end: "Checking deployment status...",
|
|
2121
|
-
});
|
|
2122
|
-
let pollChecks = 0;
|
|
2123
|
-
|
|
2124
|
-
while (true) {
|
|
2125
|
-
const functionsService = await getFunctionsService();
|
|
2126
|
-
response = await functionsService.getDeployment({
|
|
2127
|
-
functionId: func["$id"],
|
|
2128
|
-
deploymentId: deploymentId,
|
|
2129
|
-
});
|
|
2130
|
-
|
|
2131
|
-
const status = response["status"];
|
|
2132
|
-
if (status === "ready") {
|
|
2133
|
-
successfullyDeployed++;
|
|
2134
|
-
|
|
2135
|
-
let url = "";
|
|
2136
|
-
const proxyService = await getProxyService();
|
|
2137
|
-
const res = await proxyService.listRules([
|
|
2138
|
-
JSON.stringify({ method: "limit", values: [1] }),
|
|
2139
|
-
JSON.stringify({
|
|
2140
|
-
method: "equal",
|
|
2141
|
-
attribute: "deploymentResourceType",
|
|
2142
|
-
values: ["function"],
|
|
2143
|
-
}),
|
|
2144
|
-
JSON.stringify({
|
|
2145
|
-
method: "equal",
|
|
2146
|
-
attribute: "deploymentResourceId",
|
|
2147
|
-
values: [func["$id"]],
|
|
2148
|
-
}),
|
|
2149
|
-
JSON.stringify({
|
|
2150
|
-
method: "equal",
|
|
2151
|
-
attribute: "trigger",
|
|
2152
|
-
values: ["manual"],
|
|
2153
|
-
}),
|
|
2154
|
-
]);
|
|
2155
|
-
|
|
2156
|
-
if (Number(res.total) === 1) {
|
|
2157
|
-
url = res.rules[0].domain;
|
|
2158
|
-
}
|
|
2159
|
-
|
|
2160
|
-
updaterRow.update({ status: "Deployed", end: url });
|
|
2161
|
-
|
|
2162
|
-
break;
|
|
2163
|
-
} else if (status === "failed") {
|
|
2164
|
-
failedDeployments.push({
|
|
2165
|
-
name: func["name"],
|
|
2166
|
-
$id: func["$id"],
|
|
2167
|
-
deployment: response["$id"],
|
|
2168
|
-
});
|
|
2169
|
-
updaterRow.fail({ errorMessage: `Failed to deploy` });
|
|
2170
|
-
|
|
2171
|
-
break;
|
|
2172
|
-
} else {
|
|
2173
|
-
updaterRow.update({
|
|
2174
|
-
status: "Deploying",
|
|
2175
|
-
end: `Current status: ${status}`,
|
|
2176
|
-
});
|
|
2177
|
-
}
|
|
2178
|
-
|
|
2179
|
-
pollChecks++;
|
|
2180
|
-
await new Promise((resolve) =>
|
|
2181
|
-
setTimeout(resolve, POLL_DEBOUNCE * 1.5),
|
|
2182
|
-
);
|
|
2183
|
-
}
|
|
2184
|
-
} catch (e: any) {
|
|
2185
|
-
errors.push(e);
|
|
2186
|
-
updaterRow.fail({
|
|
2187
|
-
errorMessage:
|
|
2188
|
-
e.message ?? "Unknown error occurred. Please try again",
|
|
2189
|
-
});
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
1766
|
+
log("Pushing sites ...");
|
|
2192
1767
|
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
1768
|
+
const pushInstance = await createPushInstance();
|
|
1769
|
+
const result = await pushInstance.pushSites(sites, {
|
|
1770
|
+
async: asyncDeploy,
|
|
1771
|
+
code,
|
|
1772
|
+
withVariables,
|
|
1773
|
+
});
|
|
2196
1774
|
|
|
2197
|
-
|
|
1775
|
+
const {
|
|
1776
|
+
successfullyPushed,
|
|
1777
|
+
successfullyDeployed,
|
|
1778
|
+
failedDeployments,
|
|
1779
|
+
errors,
|
|
1780
|
+
} = result;
|
|
2198
1781
|
|
|
2199
1782
|
failedDeployments.forEach((failed) => {
|
|
2200
1783
|
const { name, deployment, $id } = failed;
|
|
2201
|
-
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/
|
|
1784
|
+
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/sites/site-${$id}/deployments/deployment-${deployment}`;
|
|
2202
1785
|
|
|
2203
1786
|
error(
|
|
2204
1787
|
`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`,
|
|
@@ -2207,16 +1790,16 @@ const pushFunction = async ({
|
|
|
2207
1790
|
|
|
2208
1791
|
if (!asyncDeploy) {
|
|
2209
1792
|
if (successfullyPushed === 0) {
|
|
2210
|
-
error("No
|
|
1793
|
+
error("No sites were pushed.");
|
|
2211
1794
|
} else if (successfullyDeployed !== successfullyPushed) {
|
|
2212
1795
|
warn(
|
|
2213
|
-
`Successfully pushed ${successfullyDeployed} of ${successfullyPushed}
|
|
1796
|
+
`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} sites`,
|
|
2214
1797
|
);
|
|
2215
1798
|
} else {
|
|
2216
|
-
success(`Successfully pushed ${successfullyPushed}
|
|
1799
|
+
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
2217
1800
|
}
|
|
2218
1801
|
} else {
|
|
2219
|
-
success(`Successfully pushed ${successfullyPushed}
|
|
1802
|
+
success(`Successfully pushed ${successfullyPushed} sites.`);
|
|
2220
1803
|
}
|
|
2221
1804
|
|
|
2222
1805
|
if (cliConfig.verbose) {
|
|
@@ -2226,194 +1809,140 @@ const pushFunction = async ({
|
|
|
2226
1809
|
}
|
|
2227
1810
|
};
|
|
2228
1811
|
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
|
|
1812
|
+
const pushFunction = async ({
|
|
1813
|
+
functionId,
|
|
1814
|
+
async: asyncDeploy,
|
|
1815
|
+
code,
|
|
1816
|
+
withVariables,
|
|
1817
|
+
}: PushFunctionOptions = {}): Promise<void> => {
|
|
1818
|
+
process.chdir(localConfig.configDirectoryPath);
|
|
1819
|
+
|
|
1820
|
+
const functionIds: string[] = [];
|
|
2232
1821
|
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
{
|
|
2240
|
-
|
|
2241
|
-
|
|
1822
|
+
if (functionId) {
|
|
1823
|
+
functionIds.push(functionId);
|
|
1824
|
+
} else if (cliConfig.all) {
|
|
1825
|
+
checkDeployConditions(localConfig);
|
|
1826
|
+
const functions = localConfig.getFunctions();
|
|
1827
|
+
functionIds.push(
|
|
1828
|
+
...functions.map((func: any) => {
|
|
1829
|
+
return func.$id;
|
|
1830
|
+
}),
|
|
2242
1831
|
);
|
|
1832
|
+
}
|
|
2243
1833
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
const changes: any[] = [];
|
|
2249
|
-
const toCreate: any[] = [];
|
|
2250
|
-
const toUpdate: any[] = [];
|
|
2251
|
-
const toDelete: any[] = [];
|
|
2252
|
-
|
|
2253
|
-
// Check for deletions - remote DBs that aren't in local config
|
|
2254
|
-
for (const remoteDB of remoteTablesDBs) {
|
|
2255
|
-
const localDB = localTablesDBs.find((db: any) => db.$id === remoteDB.$id);
|
|
2256
|
-
if (!localDB) {
|
|
2257
|
-
toDelete.push(remoteDB);
|
|
2258
|
-
changes.push({
|
|
2259
|
-
id: remoteDB.$id,
|
|
2260
|
-
action: chalk.red("deleting"),
|
|
2261
|
-
key: "Database",
|
|
2262
|
-
remote: remoteDB.name,
|
|
2263
|
-
local: "(deleted locally)",
|
|
2264
|
-
});
|
|
2265
|
-
}
|
|
1834
|
+
if (functionIds.length <= 0) {
|
|
1835
|
+
const answers = await inquirer.prompt(questionsPushFunctions);
|
|
1836
|
+
if (answers.functions) {
|
|
1837
|
+
functionIds.push(...answers.functions);
|
|
2266
1838
|
}
|
|
1839
|
+
}
|
|
2267
1840
|
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
toCreate.push(localDB);
|
|
2276
|
-
changes.push({
|
|
2277
|
-
id: localDB.$id,
|
|
2278
|
-
action: chalk.green("creating"),
|
|
2279
|
-
key: "Database",
|
|
2280
|
-
remote: "(does not exist)",
|
|
2281
|
-
local: localDB.name,
|
|
2282
|
-
});
|
|
2283
|
-
} else {
|
|
2284
|
-
let hasChanges = false;
|
|
2285
|
-
|
|
2286
|
-
if (remoteDB.name !== localDB.name) {
|
|
2287
|
-
hasChanges = true;
|
|
2288
|
-
changes.push({
|
|
2289
|
-
id: localDB.$id,
|
|
2290
|
-
action: chalk.yellow("updating"),
|
|
2291
|
-
key: "Name",
|
|
2292
|
-
remote: remoteDB.name,
|
|
2293
|
-
local: localDB.name,
|
|
2294
|
-
});
|
|
2295
|
-
}
|
|
1841
|
+
if (functionIds.length === 0) {
|
|
1842
|
+
log("No functions found.");
|
|
1843
|
+
hint(
|
|
1844
|
+
`Use '${EXECUTABLE_NAME} pull functions' to synchronize existing one, or use '${EXECUTABLE_NAME} init function' to create a new one.`,
|
|
1845
|
+
);
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
2296
1848
|
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
id: localDB.$id,
|
|
2301
|
-
action: chalk.yellow("updating"),
|
|
2302
|
-
key: "Enabled",
|
|
2303
|
-
remote: remoteDB.enabled,
|
|
2304
|
-
local: localDB.enabled,
|
|
2305
|
-
});
|
|
2306
|
-
}
|
|
1849
|
+
let functions = functionIds.map((id: string) => {
|
|
1850
|
+
const functions = localConfig.getFunctions();
|
|
1851
|
+
const func = functions.find((f: any) => f.$id === id);
|
|
2307
1852
|
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
}
|
|
2311
|
-
}
|
|
1853
|
+
if (!func) {
|
|
1854
|
+
throw new Error("Function '" + id + "' not found.");
|
|
2312
1855
|
}
|
|
2313
1856
|
|
|
2314
|
-
|
|
2315
|
-
|
|
1857
|
+
return func;
|
|
1858
|
+
});
|
|
1859
|
+
|
|
1860
|
+
log("Validating functions ...");
|
|
1861
|
+
for (let func of functions) {
|
|
1862
|
+
if (!func.entrypoint) {
|
|
1863
|
+
log(`Function ${func.name} is missing an entrypoint.`);
|
|
1864
|
+
const answers = await inquirer.prompt(questionsGetEntrypoint);
|
|
1865
|
+
func.entrypoint = answers.entrypoint;
|
|
1866
|
+
localConfig.addFunction(func);
|
|
2316
1867
|
}
|
|
1868
|
+
}
|
|
2317
1869
|
|
|
2318
|
-
|
|
2319
|
-
|
|
1870
|
+
if (
|
|
1871
|
+
!(await approveChanges(
|
|
1872
|
+
functions,
|
|
1873
|
+
async (args: any) => {
|
|
1874
|
+
const functionsService = await getFunctionsService();
|
|
1875
|
+
return await functionsService.get({ functionId: args.functionId });
|
|
1876
|
+
},
|
|
1877
|
+
KeysFunction,
|
|
1878
|
+
"functionId",
|
|
1879
|
+
"functions",
|
|
1880
|
+
["vars"],
|
|
1881
|
+
))
|
|
1882
|
+
) {
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
2320
1885
|
|
|
2321
|
-
|
|
2322
|
-
console.log(
|
|
2323
|
-
`${chalk.red("------------------------------------------------------------------")}`,
|
|
2324
|
-
);
|
|
2325
|
-
console.log(
|
|
2326
|
-
`${chalk.red("| WARNING: Database deletion will also delete all related tables |")}`,
|
|
2327
|
-
);
|
|
2328
|
-
console.log(
|
|
2329
|
-
`${chalk.red("------------------------------------------------------------------")}`,
|
|
2330
|
-
);
|
|
2331
|
-
console.log();
|
|
2332
|
-
}
|
|
1886
|
+
log("Pushing functions ...");
|
|
2333
1887
|
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
1888
|
+
const pushInstance = await createPushInstance();
|
|
1889
|
+
const result = await pushInstance.pushFunctions(functions, {
|
|
1890
|
+
async: asyncDeploy,
|
|
1891
|
+
code,
|
|
1892
|
+
withVariables,
|
|
1893
|
+
});
|
|
2337
1894
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
await tablesDBService.delete(db.$id);
|
|
2345
|
-
success(`Deleted ${db.name} ( ${db.$id} )`);
|
|
2346
|
-
needsResync = true;
|
|
2347
|
-
} catch (e: any) {
|
|
2348
|
-
error(
|
|
2349
|
-
`Failed to delete database ${db.name} ( ${db.$id} ): ${e.message}`,
|
|
2350
|
-
);
|
|
2351
|
-
throw new Error(
|
|
2352
|
-
`Database sync failed during deletion of ${db.$id}. Some changes may have been applied.`,
|
|
2353
|
-
);
|
|
2354
|
-
}
|
|
2355
|
-
}
|
|
1895
|
+
const {
|
|
1896
|
+
successfullyPushed,
|
|
1897
|
+
successfullyDeployed,
|
|
1898
|
+
failedDeployments,
|
|
1899
|
+
errors,
|
|
1900
|
+
} = result;
|
|
2356
1901
|
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
log(`Creating database ${db.name} ( ${db.$id} ) ...`);
|
|
2361
|
-
const tablesDBService = await getTablesDBService();
|
|
2362
|
-
await tablesDBService.create(db.$id, db.name, db.enabled);
|
|
2363
|
-
success(`Created ${db.name} ( ${db.$id} )`);
|
|
2364
|
-
} catch (e: any) {
|
|
2365
|
-
error(
|
|
2366
|
-
`Failed to create database ${db.name} ( ${db.$id} ): ${e.message}`,
|
|
2367
|
-
);
|
|
2368
|
-
throw new Error(
|
|
2369
|
-
`Database sync failed during creation of ${db.$id}. Some changes may have been applied.`,
|
|
2370
|
-
);
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
1902
|
+
failedDeployments.forEach((failed) => {
|
|
1903
|
+
const { name, deployment, $id } = failed;
|
|
1904
|
+
const failUrl = `${globalConfig.getEndpoint().slice(0, -3)}/console/project-${localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
|
|
2373
1905
|
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
const tablesDBService = await getTablesDBService();
|
|
2379
|
-
await tablesDBService.update(db.$id, db.name, db.enabled);
|
|
2380
|
-
success(`Updated ${db.name} ( ${db.$id} )`);
|
|
2381
|
-
} catch (e: any) {
|
|
2382
|
-
error(
|
|
2383
|
-
`Failed to update database ${db.name} ( ${db.$id} ): ${e.message}`,
|
|
2384
|
-
);
|
|
2385
|
-
throw new Error(
|
|
2386
|
-
`Database sync failed during update of ${db.$id}. Some changes may have been applied.`,
|
|
2387
|
-
);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
1906
|
+
error(
|
|
1907
|
+
`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`,
|
|
1908
|
+
);
|
|
1909
|
+
});
|
|
2390
1910
|
|
|
2391
|
-
|
|
2392
|
-
|
|
1911
|
+
if (!asyncDeploy) {
|
|
1912
|
+
if (successfullyPushed === 0) {
|
|
1913
|
+
error("No functions were pushed.");
|
|
1914
|
+
} else if (successfullyDeployed !== successfullyPushed) {
|
|
1915
|
+
warn(
|
|
1916
|
+
`Successfully pushed ${successfullyDeployed} of ${successfullyPushed} functions`,
|
|
1917
|
+
);
|
|
1918
|
+
} else {
|
|
1919
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
2393
1920
|
}
|
|
1921
|
+
} else {
|
|
1922
|
+
success(`Successfully pushed ${successfullyPushed} functions.`);
|
|
1923
|
+
}
|
|
2394
1924
|
|
|
2395
|
-
|
|
2396
|
-
|
|
1925
|
+
if (cliConfig.verbose) {
|
|
1926
|
+
errors.forEach((e) => {
|
|
1927
|
+
console.error(e);
|
|
1928
|
+
});
|
|
1929
|
+
}
|
|
1930
|
+
};
|
|
2397
1931
|
|
|
2398
1932
|
const pushTable = async ({
|
|
2399
1933
|
attempts,
|
|
2400
1934
|
}: PushTableOptions = {}): Promise<void> => {
|
|
2401
1935
|
const tables: any[] = [];
|
|
2402
1936
|
|
|
2403
|
-
|
|
2404
|
-
pollMaxDebounces = attempts;
|
|
2405
|
-
}
|
|
2406
|
-
|
|
2407
|
-
const { applied: tablesDBApplied, resyncNeeded } =
|
|
2408
|
-
await checkAndApplyTablesDBChanges();
|
|
1937
|
+
const { resyncNeeded } = await checkAndApplyTablesDBChanges();
|
|
2409
1938
|
if (resyncNeeded) {
|
|
2410
|
-
log("Resyncing configuration due to
|
|
1939
|
+
log("Resyncing configuration due to tables deletions ...");
|
|
2411
1940
|
|
|
2412
1941
|
const remoteTablesDBs = (
|
|
2413
1942
|
await paginate(
|
|
2414
1943
|
async (args: any) => {
|
|
2415
|
-
const
|
|
2416
|
-
return await
|
|
1944
|
+
const tablesService = await getTablesDBService();
|
|
1945
|
+
return await tablesService.list(args.queries || []);
|
|
2417
1946
|
},
|
|
2418
1947
|
{},
|
|
2419
1948
|
100,
|
|
@@ -2448,8 +1977,8 @@ const pushTable = async ({
|
|
|
2448
1977
|
try {
|
|
2449
1978
|
const { tables: remoteTables } = await paginate(
|
|
2450
1979
|
async (args: any) => {
|
|
2451
|
-
const
|
|
2452
|
-
return await
|
|
1980
|
+
const tablesService = await getTablesDBService();
|
|
1981
|
+
return await tablesService.listTables(
|
|
2453
1982
|
args.databaseId,
|
|
2454
1983
|
args.queries || [],
|
|
2455
1984
|
);
|
|
@@ -2496,8 +2025,8 @@ const pushTable = async ({
|
|
|
2496
2025
|
log(
|
|
2497
2026
|
`Deleting table ${table.name} ( ${table.$id} ) from database ${table.databaseName} ...`,
|
|
2498
2027
|
);
|
|
2499
|
-
const
|
|
2500
|
-
await
|
|
2028
|
+
const tablesService = await getTablesDBService();
|
|
2029
|
+
await tablesService.deleteTable(table.databaseId, table.$id);
|
|
2501
2030
|
success(`Deleted ${table.name} ( ${table.$id} )`);
|
|
2502
2031
|
} catch (e: any) {
|
|
2503
2032
|
error(
|
|
@@ -2528,7 +2057,7 @@ const pushTable = async ({
|
|
|
2528
2057
|
if (tables.length === 0) {
|
|
2529
2058
|
log("No tables found.");
|
|
2530
2059
|
hint(
|
|
2531
|
-
|
|
2060
|
+
`Use '${EXECUTABLE_NAME} pull tables' to synchronize existing one, or use '${EXECUTABLE_NAME} init table' to create a new one.`,
|
|
2532
2061
|
);
|
|
2533
2062
|
return;
|
|
2534
2063
|
}
|
|
@@ -2537,8 +2066,8 @@ const pushTable = async ({
|
|
|
2537
2066
|
!(await approveChanges(
|
|
2538
2067
|
tables,
|
|
2539
2068
|
async (args: any) => {
|
|
2540
|
-
const
|
|
2541
|
-
return await
|
|
2069
|
+
const tablesService = await getTablesDBService();
|
|
2070
|
+
return await tablesService.getTable(args.databaseId, args.tableId);
|
|
2542
2071
|
},
|
|
2543
2072
|
KeysTable,
|
|
2544
2073
|
"tableId",
|
|
@@ -2550,129 +2079,31 @@ const pushTable = async ({
|
|
|
2550
2079
|
) {
|
|
2551
2080
|
return;
|
|
2552
2081
|
}
|
|
2553
|
-
let tablesChanged = new Set();
|
|
2554
|
-
|
|
2555
|
-
// Parallel tables actions
|
|
2556
|
-
await Promise.all(
|
|
2557
|
-
tables.map(async (table: any) => {
|
|
2558
|
-
try {
|
|
2559
|
-
const tablesDBService = await getTablesDBService();
|
|
2560
|
-
const remoteTable = await tablesDBService.getTable(
|
|
2561
|
-
table["databaseId"],
|
|
2562
|
-
table["$id"],
|
|
2563
|
-
);
|
|
2564
|
-
|
|
2565
|
-
const changes: string[] = [];
|
|
2566
|
-
if (remoteTable.name !== table.name) changes.push("name");
|
|
2567
|
-
if (remoteTable.rowSecurity !== table.rowSecurity)
|
|
2568
|
-
changes.push("rowSecurity");
|
|
2569
|
-
if (remoteTable.enabled !== table.enabled) changes.push("enabled");
|
|
2570
|
-
if (
|
|
2571
|
-
JSON.stringify(remoteTable["$permissions"]) !==
|
|
2572
|
-
JSON.stringify(table["$permissions"])
|
|
2573
|
-
)
|
|
2574
|
-
changes.push("permissions");
|
|
2575
|
-
|
|
2576
|
-
if (changes.length > 0) {
|
|
2577
|
-
await tablesDBService.updateTable(
|
|
2578
|
-
table["databaseId"],
|
|
2579
|
-
table["$id"],
|
|
2580
|
-
table.name,
|
|
2581
|
-
table.rowSecurity,
|
|
2582
|
-
table["$permissions"],
|
|
2583
|
-
);
|
|
2584
|
-
|
|
2585
|
-
success(
|
|
2586
|
-
`Updated ${table.name} ( ${table["$id"]} ) - ${changes.join(", ")}`,
|
|
2587
|
-
);
|
|
2588
|
-
tablesChanged.add(table["$id"]);
|
|
2589
|
-
}
|
|
2590
|
-
table.remoteVersion = remoteTable;
|
|
2591
|
-
|
|
2592
|
-
table.isExisted = true;
|
|
2593
|
-
} catch (e: any) {
|
|
2594
|
-
if (Number(e.code) === 404) {
|
|
2595
|
-
log(
|
|
2596
|
-
`Table ${table.name} does not exist in the project. Creating ... `,
|
|
2597
|
-
);
|
|
2598
|
-
const tablesDBService = await getTablesDBService();
|
|
2599
|
-
await tablesDBService.createTable(
|
|
2600
|
-
table["databaseId"],
|
|
2601
|
-
table["$id"],
|
|
2602
|
-
table.name,
|
|
2603
|
-
table.rowSecurity,
|
|
2604
|
-
table["$permissions"],
|
|
2605
|
-
);
|
|
2606
|
-
|
|
2607
|
-
success(`Created ${table.name} ( ${table["$id"]} )`);
|
|
2608
|
-
tablesChanged.add(table["$id"]);
|
|
2609
|
-
} else {
|
|
2610
|
-
throw e;
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
}),
|
|
2614
|
-
);
|
|
2615
|
-
|
|
2616
|
-
// Serialize attribute actions
|
|
2617
|
-
for (let table of tables) {
|
|
2618
|
-
let columns = table.columns;
|
|
2619
|
-
let indexes = table.indexes;
|
|
2620
2082
|
|
|
2621
|
-
|
|
2622
|
-
columns = await attributesToCreate(
|
|
2623
|
-
table.remoteVersion.columns,
|
|
2624
|
-
table.columns,
|
|
2625
|
-
table,
|
|
2626
|
-
);
|
|
2627
|
-
indexes = await attributesToCreate(
|
|
2628
|
-
table.remoteVersion.indexes,
|
|
2629
|
-
table.indexes,
|
|
2630
|
-
table,
|
|
2631
|
-
true,
|
|
2632
|
-
);
|
|
2633
|
-
|
|
2634
|
-
if (
|
|
2635
|
-
Array.isArray(columns) &&
|
|
2636
|
-
columns.length <= 0 &&
|
|
2637
|
-
Array.isArray(indexes) &&
|
|
2638
|
-
indexes.length <= 0
|
|
2639
|
-
) {
|
|
2640
|
-
continue;
|
|
2641
|
-
}
|
|
2642
|
-
}
|
|
2083
|
+
log("Pushing tables ...");
|
|
2643
2084
|
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
);
|
|
2085
|
+
const pushInstance = await createPushInstance();
|
|
2086
|
+
const result = await pushInstance.pushTables(tables, { attempts });
|
|
2647
2087
|
|
|
2648
|
-
|
|
2649
|
-
await createColumns(columns, table);
|
|
2650
|
-
} catch (e) {
|
|
2651
|
-
throw e;
|
|
2652
|
-
}
|
|
2088
|
+
const { successfullyPushed, errors } = result;
|
|
2653
2089
|
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
}
|
|
2659
|
-
tablesChanged.add(table["$id"]);
|
|
2660
|
-
success(`Successfully pushed ${table.name} ( ${table["$id"]} )`);
|
|
2090
|
+
if (successfullyPushed === 0) {
|
|
2091
|
+
error("No tables were pushed.");
|
|
2092
|
+
} else {
|
|
2093
|
+
success(`Successfully pushed ${successfullyPushed} tables.`);
|
|
2661
2094
|
}
|
|
2662
2095
|
|
|
2663
|
-
|
|
2096
|
+
if (cliConfig.verbose) {
|
|
2097
|
+
errors.forEach((e) => console.error(e));
|
|
2098
|
+
}
|
|
2664
2099
|
};
|
|
2665
2100
|
|
|
2666
|
-
const pushCollection = async (
|
|
2101
|
+
const pushCollection = async (): Promise<void> => {
|
|
2667
2102
|
warn(
|
|
2668
|
-
|
|
2103
|
+
`${EXECUTABLE_NAME} push collection has been deprecated. Please consider using '${EXECUTABLE_NAME} push tables' instead`,
|
|
2669
2104
|
);
|
|
2670
2105
|
const collections: any[] = [];
|
|
2671
2106
|
|
|
2672
|
-
if (attempts) {
|
|
2673
|
-
pollMaxDebounces = attempts;
|
|
2674
|
-
}
|
|
2675
|
-
|
|
2676
2107
|
if (cliConfig.all) {
|
|
2677
2108
|
checkDeployConditions(localConfig);
|
|
2678
2109
|
collections.push(...localConfig.getCollections());
|
|
@@ -2693,42 +2124,16 @@ const pushCollection = async ({ attempts }): Promise<void> => {
|
|
|
2693
2124
|
if (collections.length === 0) {
|
|
2694
2125
|
log("No collections found.");
|
|
2695
2126
|
hint(
|
|
2696
|
-
|
|
2127
|
+
`Use '${EXECUTABLE_NAME} pull collections' to synchronize existing one, or use '${EXECUTABLE_NAME} init collection' to create a new one.`,
|
|
2697
2128
|
);
|
|
2698
2129
|
return;
|
|
2699
2130
|
}
|
|
2700
2131
|
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
await Promise.all(
|
|
2707
|
-
databases.map(async (databaseId: any) => {
|
|
2708
|
-
const localDatabase = localConfig.getDatabase(databaseId);
|
|
2709
|
-
|
|
2710
|
-
const databasesService = await getDatabasesService();
|
|
2711
|
-
try {
|
|
2712
|
-
const database = await databasesService.get(databaseId);
|
|
2713
|
-
|
|
2714
|
-
if (database.name !== (localDatabase.name ?? databaseId)) {
|
|
2715
|
-
await databasesService.update(
|
|
2716
|
-
databaseId,
|
|
2717
|
-
localDatabase.name ?? databaseId,
|
|
2718
|
-
);
|
|
2719
|
-
|
|
2720
|
-
success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
|
|
2721
|
-
}
|
|
2722
|
-
} catch (err) {
|
|
2723
|
-
log(`Database ${databaseId} not found. Creating it now ...`);
|
|
2724
|
-
|
|
2725
|
-
await databasesService.create(
|
|
2726
|
-
databaseId,
|
|
2727
|
-
localDatabase.name ?? databaseId,
|
|
2728
|
-
);
|
|
2729
|
-
}
|
|
2730
|
-
}),
|
|
2731
|
-
);
|
|
2132
|
+
// Add database names to collections for the class method
|
|
2133
|
+
collections.forEach((collection: any) => {
|
|
2134
|
+
const localDatabase = localConfig.getDatabase(collection.databaseId);
|
|
2135
|
+
collection.databaseName = localDatabase.name ?? collection.databaseId;
|
|
2136
|
+
});
|
|
2732
2137
|
|
|
2733
2138
|
if (
|
|
2734
2139
|
!(await approveChanges(
|
|
@@ -2750,101 +2155,26 @@ const pushCollection = async ({ attempts }): Promise<void> => {
|
|
|
2750
2155
|
) {
|
|
2751
2156
|
return;
|
|
2752
2157
|
}
|
|
2753
|
-
// Parallel collection actions
|
|
2754
|
-
await Promise.all(
|
|
2755
|
-
collections.map(async (collection: any) => {
|
|
2756
|
-
try {
|
|
2757
|
-
const databasesService = await getDatabasesService();
|
|
2758
|
-
const remoteCollection = await databasesService.getCollection(
|
|
2759
|
-
collection["databaseId"],
|
|
2760
|
-
collection["$id"],
|
|
2761
|
-
);
|
|
2762
|
-
|
|
2763
|
-
if (remoteCollection.name !== collection.name) {
|
|
2764
|
-
await databasesService.updateCollection(
|
|
2765
|
-
collection["databaseId"],
|
|
2766
|
-
collection["$id"],
|
|
2767
|
-
collection.name,
|
|
2768
|
-
);
|
|
2769
|
-
|
|
2770
|
-
success(`Updated ${collection.name} ( ${collection["$id"]} ) name`);
|
|
2771
|
-
}
|
|
2772
|
-
collection.remoteVersion = remoteCollection;
|
|
2773
|
-
|
|
2774
|
-
collection.isExisted = true;
|
|
2775
|
-
} catch (e: any) {
|
|
2776
|
-
if (Number(e.code) === 404) {
|
|
2777
|
-
log(
|
|
2778
|
-
`Collection ${collection.name} does not exist in the project. Creating ... `,
|
|
2779
|
-
);
|
|
2780
|
-
const databasesService = await getDatabasesService();
|
|
2781
|
-
await databasesService.createCollection(
|
|
2782
|
-
collection["databaseId"],
|
|
2783
|
-
collection["$id"],
|
|
2784
|
-
collection.name,
|
|
2785
|
-
collection.documentSecurity,
|
|
2786
|
-
collection["$permissions"],
|
|
2787
|
-
);
|
|
2788
|
-
} else {
|
|
2789
|
-
throw e;
|
|
2790
|
-
}
|
|
2791
|
-
}
|
|
2792
|
-
}),
|
|
2793
|
-
);
|
|
2794
|
-
let numberOfCollections = 0;
|
|
2795
|
-
// Serialize attribute actions
|
|
2796
|
-
for (let collection of collections) {
|
|
2797
|
-
let attributes = collection.attributes;
|
|
2798
|
-
let indexes = collection.indexes;
|
|
2799
|
-
|
|
2800
|
-
if (collection.isExisted) {
|
|
2801
|
-
attributes = await attributesToCreate(
|
|
2802
|
-
collection.remoteVersion.attributes,
|
|
2803
|
-
collection.attributes,
|
|
2804
|
-
collection,
|
|
2805
|
-
);
|
|
2806
|
-
indexes = await attributesToCreate(
|
|
2807
|
-
collection.remoteVersion.indexes,
|
|
2808
|
-
collection.indexes,
|
|
2809
|
-
collection,
|
|
2810
|
-
true,
|
|
2811
|
-
);
|
|
2812
2158
|
|
|
2813
|
-
|
|
2814
|
-
Array.isArray(attributes) &&
|
|
2815
|
-
attributes.length <= 0 &&
|
|
2816
|
-
Array.isArray(indexes) &&
|
|
2817
|
-
indexes.length <= 0
|
|
2818
|
-
) {
|
|
2819
|
-
continue;
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2159
|
+
log("Pushing collections ...");
|
|
2822
2160
|
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
);
|
|
2161
|
+
const pushInstance = await createPushInstance();
|
|
2162
|
+
const result = await pushInstance.pushCollections(collections);
|
|
2826
2163
|
|
|
2827
|
-
|
|
2828
|
-
await createAttributes(attributes, collection);
|
|
2829
|
-
} catch (e) {
|
|
2830
|
-
throw e;
|
|
2831
|
-
}
|
|
2164
|
+
const { successfullyPushed, errors } = result;
|
|
2832
2165
|
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
}
|
|
2838
|
-
numberOfCollections++;
|
|
2839
|
-
success(`Successfully pushed ${collection.name} ( ${collection["$id"]} )`);
|
|
2166
|
+
if (successfullyPushed === 0) {
|
|
2167
|
+
error("No collections were pushed.");
|
|
2168
|
+
} else {
|
|
2169
|
+
success(`Successfully pushed ${successfullyPushed} collections.`);
|
|
2840
2170
|
}
|
|
2841
2171
|
|
|
2842
|
-
|
|
2172
|
+
if (cliConfig.verbose) {
|
|
2173
|
+
errors.forEach((e) => console.error(e));
|
|
2174
|
+
}
|
|
2843
2175
|
};
|
|
2844
2176
|
|
|
2845
2177
|
const pushBucket = async (): Promise<void> => {
|
|
2846
|
-
let response: any = {};
|
|
2847
|
-
|
|
2848
2178
|
let bucketIds: string[] = [];
|
|
2849
2179
|
const configBuckets = localConfig.getBuckets();
|
|
2850
2180
|
|
|
@@ -2863,7 +2193,7 @@ const pushBucket = async (): Promise<void> => {
|
|
|
2863
2193
|
if (bucketIds.length === 0) {
|
|
2864
2194
|
log("No buckets found.");
|
|
2865
2195
|
hint(
|
|
2866
|
-
|
|
2196
|
+
`Use '${EXECUTABLE_NAME} pull buckets' to synchronize existing one, or use '${EXECUTABLE_NAME} init bucket' to create a new one.`,
|
|
2867
2197
|
);
|
|
2868
2198
|
return;
|
|
2869
2199
|
}
|
|
@@ -2892,55 +2222,23 @@ const pushBucket = async (): Promise<void> => {
|
|
|
2892
2222
|
|
|
2893
2223
|
log("Pushing buckets ...");
|
|
2894
2224
|
|
|
2895
|
-
|
|
2896
|
-
|
|
2225
|
+
const pushInstance = await createPushInstance();
|
|
2226
|
+
const result = await pushInstance.pushBuckets(buckets);
|
|
2897
2227
|
|
|
2898
|
-
|
|
2899
|
-
try {
|
|
2900
|
-
response = await storageService.getBucket(bucket["$id"]);
|
|
2901
|
-
|
|
2902
|
-
await storageService.updateBucket(
|
|
2903
|
-
bucket["$id"],
|
|
2904
|
-
bucket.name,
|
|
2905
|
-
bucket["$permissions"],
|
|
2906
|
-
bucket.fileSecurity,
|
|
2907
|
-
bucket.enabled,
|
|
2908
|
-
bucket.maximumFileSize,
|
|
2909
|
-
bucket.allowedFileExtensions,
|
|
2910
|
-
bucket.encryption,
|
|
2911
|
-
bucket.antivirus,
|
|
2912
|
-
bucket.compression,
|
|
2913
|
-
);
|
|
2914
|
-
} catch (e: any) {
|
|
2915
|
-
if (Number(e.code) === 404) {
|
|
2916
|
-
log(
|
|
2917
|
-
`Bucket ${bucket.name} does not exist in the project. Creating ... `,
|
|
2918
|
-
);
|
|
2228
|
+
const { successfullyPushed, errors } = result;
|
|
2919
2229
|
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
bucket.fileSecurity,
|
|
2925
|
-
bucket.enabled,
|
|
2926
|
-
bucket.maximumFileSize,
|
|
2927
|
-
bucket.allowedFileExtensions,
|
|
2928
|
-
bucket.compression,
|
|
2929
|
-
bucket.encryption,
|
|
2930
|
-
bucket.antivirus,
|
|
2931
|
-
);
|
|
2932
|
-
} else {
|
|
2933
|
-
throw e;
|
|
2934
|
-
}
|
|
2935
|
-
}
|
|
2230
|
+
if (successfullyPushed === 0) {
|
|
2231
|
+
error("No buckets were pushed.");
|
|
2232
|
+
} else {
|
|
2233
|
+
success(`Successfully pushed ${successfullyPushed} buckets.`);
|
|
2936
2234
|
}
|
|
2937
2235
|
|
|
2938
|
-
|
|
2236
|
+
if (cliConfig.verbose) {
|
|
2237
|
+
errors.forEach((e) => console.error(e));
|
|
2238
|
+
}
|
|
2939
2239
|
};
|
|
2940
2240
|
|
|
2941
2241
|
const pushTeam = async (): Promise<void> => {
|
|
2942
|
-
let response: any = {};
|
|
2943
|
-
|
|
2944
2242
|
let teamIds: string[] = [];
|
|
2945
2243
|
const configTeams = localConfig.getTeams();
|
|
2946
2244
|
|
|
@@ -2959,7 +2257,7 @@ const pushTeam = async (): Promise<void> => {
|
|
|
2959
2257
|
if (teamIds.length === 0) {
|
|
2960
2258
|
log("No teams found.");
|
|
2961
2259
|
hint(
|
|
2962
|
-
|
|
2260
|
+
`Use '${EXECUTABLE_NAME} pull teams' to synchronize existing one, or use '${EXECUTABLE_NAME} init team' to create a new one.`,
|
|
2963
2261
|
);
|
|
2964
2262
|
return;
|
|
2965
2263
|
}
|
|
@@ -2988,31 +2286,23 @@ const pushTeam = async (): Promise<void> => {
|
|
|
2988
2286
|
|
|
2989
2287
|
log("Pushing teams ...");
|
|
2990
2288
|
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
const teamsService = await getTeamsService();
|
|
2995
|
-
try {
|
|
2996
|
-
response = await teamsService.get(team["$id"]);
|
|
2289
|
+
const pushInstance = await createPushInstance();
|
|
2290
|
+
const result = await pushInstance.pushTeams(teams);
|
|
2997
2291
|
|
|
2998
|
-
|
|
2999
|
-
} catch (e: any) {
|
|
3000
|
-
if (Number(e.code) === 404) {
|
|
3001
|
-
log(`Team ${team.name} does not exist in the project. Creating ... `);
|
|
2292
|
+
const { successfullyPushed, errors } = result;
|
|
3002
2293
|
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
}
|
|
2294
|
+
if (successfullyPushed === 0) {
|
|
2295
|
+
error("No teams were pushed.");
|
|
2296
|
+
} else {
|
|
2297
|
+
success(`Successfully pushed ${successfullyPushed} teams.`);
|
|
3008
2298
|
}
|
|
3009
2299
|
|
|
3010
|
-
|
|
2300
|
+
if (cliConfig.verbose) {
|
|
2301
|
+
errors.forEach((e) => console.error(e));
|
|
2302
|
+
}
|
|
3011
2303
|
};
|
|
3012
2304
|
|
|
3013
2305
|
const pushMessagingTopic = async (): Promise<void> => {
|
|
3014
|
-
let response: any = {};
|
|
3015
|
-
|
|
3016
2306
|
let topicsIds: string[] = [];
|
|
3017
2307
|
const configTopics = localConfig.getMessagingTopics();
|
|
3018
2308
|
|
|
@@ -3031,7 +2321,7 @@ const pushMessagingTopic = async (): Promise<void> => {
|
|
|
3031
2321
|
if (topicsIds.length === 0) {
|
|
3032
2322
|
log("No topics found.");
|
|
3033
2323
|
hint(
|
|
3034
|
-
|
|
2324
|
+
`Use '${EXECUTABLE_NAME} pull topics' to synchronize existing one, or use '${EXECUTABLE_NAME} init topic' to create a new one.`,
|
|
3035
2325
|
);
|
|
3036
2326
|
return;
|
|
3037
2327
|
}
|
|
@@ -3060,37 +2350,20 @@ const pushMessagingTopic = async (): Promise<void> => {
|
|
|
3060
2350
|
|
|
3061
2351
|
log("Pushing topics ...");
|
|
3062
2352
|
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
const messagingService = await getMessagingService();
|
|
3067
|
-
try {
|
|
3068
|
-
response = await messagingService.getTopic(topic["$id"]);
|
|
3069
|
-
log(`Topic ${topic.name} ( ${topic["$id"]} ) already exists.`);
|
|
2353
|
+
const pushInstance = await createPushInstance();
|
|
2354
|
+
const result = await pushInstance.pushMessagingTopics(topics);
|
|
3070
2355
|
|
|
3071
|
-
|
|
3072
|
-
topic["$id"],
|
|
3073
|
-
topic.name,
|
|
3074
|
-
topic.subscribe,
|
|
3075
|
-
);
|
|
3076
|
-
} catch (e: any) {
|
|
3077
|
-
if (Number(e.code) === 404) {
|
|
3078
|
-
log(`Topic ${topic.name} does not exist in the project. Creating ... `);
|
|
3079
|
-
|
|
3080
|
-
response = await messagingService.createTopic(
|
|
3081
|
-
topic["$id"],
|
|
3082
|
-
topic.name,
|
|
3083
|
-
topic.subscribe,
|
|
3084
|
-
);
|
|
2356
|
+
const { successfullyPushed, errors } = result;
|
|
3085
2357
|
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
}
|
|
2358
|
+
if (successfullyPushed === 0) {
|
|
2359
|
+
error("No topics were pushed.");
|
|
2360
|
+
} else {
|
|
2361
|
+
success(`Successfully pushed ${successfullyPushed} topics.`);
|
|
3091
2362
|
}
|
|
3092
2363
|
|
|
3093
|
-
|
|
2364
|
+
if (cliConfig.verbose) {
|
|
2365
|
+
errors.forEach((e) => console.error(e));
|
|
2366
|
+
}
|
|
3094
2367
|
};
|
|
3095
2368
|
|
|
3096
2369
|
export const push = new Command("push")
|
|
@@ -3173,11 +2446,11 @@ push
|
|
|
3173
2446
|
.action(actionRunner(pushMessagingTopic));
|
|
3174
2447
|
|
|
3175
2448
|
export const deploy = new Command("deploy")
|
|
3176
|
-
.description(
|
|
2449
|
+
.description(`Removed. Use ${EXECUTABLE_NAME} push instead`)
|
|
3177
2450
|
.action(
|
|
3178
2451
|
actionRunner(async () => {
|
|
3179
2452
|
warn(
|
|
3180
|
-
|
|
2453
|
+
`${EXECUTABLE_NAME} deploy has been removed. Please use '${EXECUTABLE_NAME} push' instead`,
|
|
3181
2454
|
);
|
|
3182
2455
|
}),
|
|
3183
2456
|
);
|