heroku 9.0.0-alpha.0 → 9.0.0-alpha.2
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/README.md +9 -11
- package/lib/commands/access/add.d.ts +14 -0
- package/lib/commands/access/add.js +55 -0
- package/lib/commands/access/index.d.ts +11 -0
- package/lib/commands/access/index.js +86 -0
- package/lib/commands/access/remove.d.ts +12 -0
- package/lib/commands/access/remove.js +25 -0
- package/lib/commands/access/update.d.ts +14 -0
- package/lib/commands/access/update.js +39 -0
- package/lib/commands/addons/attach.d.ts +16 -0
- package/lib/commands/addons/attach.js +51 -0
- package/lib/commands/addons/create.d.ts +19 -0
- package/lib/commands/addons/create.js +84 -0
- package/lib/commands/addons/destroy.d.ts +19 -0
- package/lib/commands/addons/destroy.js +61 -0
- package/lib/commands/addons/detach.d.ts +13 -0
- package/lib/commands/addons/detach.js +31 -0
- package/lib/commands/addons/docs.d.ts +14 -0
- package/lib/commands/addons/docs.js +36 -0
- package/lib/commands/addons/index.d.ts +16 -0
- package/lib/commands/addons/index.js +246 -0
- package/lib/commands/addons/info.d.ts +14 -0
- package/lib/commands/addons/info.js +44 -0
- package/lib/commands/addons/open.d.ts +75 -0
- package/lib/commands/addons/open.js +87 -0
- package/lib/commands/addons/plans.d.ts +12 -0
- package/lib/commands/addons/plans.js +47 -0
- package/lib/commands/addons/rename.d.ts +10 -0
- package/lib/commands/addons/rename.js +20 -0
- package/lib/commands/addons/services.d.ts +9 -0
- package/lib/commands/addons/services.js +34 -0
- package/lib/commands/addons/upgrade.d.ts +28 -0
- package/lib/commands/addons/upgrade.js +145 -0
- package/lib/commands/addons/wait.d.ts +14 -0
- package/lib/commands/addons/wait.js +70 -0
- package/lib/commands/apps/create.d.ts +28 -0
- package/lib/commands/apps/create.js +201 -0
- package/lib/commands/apps/destroy.d.ts +15 -0
- package/lib/commands/apps/destroy.js +47 -0
- package/lib/commands/apps/errors.d.ts +13 -0
- package/lib/commands/apps/errors.js +120 -0
- package/lib/commands/apps/favorites/add.d.ts +10 -0
- package/lib/commands/apps/favorites/add.js +38 -0
- package/lib/commands/apps/favorites/index.d.ts +9 -0
- package/lib/commands/apps/favorites/index.js +25 -0
- package/lib/commands/apps/favorites/remove.d.ts +10 -0
- package/lib/commands/apps/favorites/remove.js +28 -0
- package/lib/commands/apps/index.d.ts +16 -0
- package/lib/commands/apps/index.js +119 -0
- package/lib/commands/apps/info.d.ts +19 -0
- package/lib/commands/apps/info.js +162 -0
- package/lib/commands/apps/join.d.ts +11 -0
- package/lib/commands/apps/join.js +25 -0
- package/lib/commands/apps/leave.d.ts +12 -0
- package/lib/commands/apps/leave.js +25 -0
- package/lib/commands/apps/lock.d.ts +11 -0
- package/lib/commands/apps/lock.js +30 -0
- package/lib/commands/apps/open.d.ts +15 -0
- package/lib/commands/apps/open.js +30 -0
- package/lib/commands/apps/rename.d.ts +16 -0
- package/lib/commands/apps/rename.js +51 -0
- package/lib/commands/apps/stacks/index.d.ts +11 -0
- package/lib/commands/apps/stacks/index.js +44 -0
- package/lib/commands/apps/stacks/set.d.ts +14 -0
- package/lib/commands/apps/stacks/set.js +41 -0
- package/lib/commands/apps/transfer.d.ts +17 -0
- package/lib/commands/apps/transfer.js +91 -0
- package/lib/commands/apps/unlock.d.ts +11 -0
- package/lib/commands/apps/unlock.js +30 -0
- package/lib/commands/auth/logout.js +1 -0
- package/lib/commands/auth/token.js +2 -1
- package/lib/commands/authorizations/create.js +5 -1
- package/lib/commands/authorizations/info.js +5 -1
- package/lib/commands/authorizations/revoke.js +5 -1
- package/lib/commands/authorizations/rotate.js +5 -1
- package/lib/commands/authorizations/update.js +5 -1
- package/lib/commands/autocomplete/doctor.js +2 -2
- package/lib/commands/autocomplete/options.js +2 -2
- package/lib/commands/certs/add.d.ts +16 -0
- package/lib/commands/certs/add.js +98 -0
- package/lib/commands/certs/auto/disable.d.ts +11 -0
- package/lib/commands/certs/auto/disable.js +34 -0
- package/lib/commands/certs/auto/enable.d.ts +11 -0
- package/lib/commands/certs/auto/enable.js +51 -0
- package/lib/commands/certs/auto/index.d.ts +12 -0
- package/lib/commands/certs/auto/index.js +94 -0
- package/lib/commands/certs/auto/refresh.d.ts +10 -0
- package/lib/commands/certs/auto/refresh.js +19 -0
- package/lib/commands/certs/generate.d.ts +26 -0
- package/lib/commands/certs/generate.js +111 -0
- package/lib/commands/certs/index.d.ts +10 -0
- package/lib/commands/certs/index.js +26 -0
- package/lib/commands/certs/info.d.ts +13 -0
- package/lib/commands/certs/info.js +43 -0
- package/lib/commands/certs/remove.d.ts +13 -0
- package/lib/commands/certs/remove.js +32 -0
- package/lib/commands/certs/update.d.ts +18 -0
- package/lib/commands/certs/update.js +54 -0
- package/lib/commands/ci/config/get.d.ts +1 -0
- package/lib/commands/ci/config/get.js +1 -0
- package/lib/commands/ci/config/index.d.ts +12 -0
- package/lib/commands/ci/config/index.js +43 -0
- package/lib/commands/ci/config/set.d.ts +3 -2
- package/lib/commands/ci/config/set.js +3 -6
- package/lib/commands/ci/config/unset.d.ts +14 -0
- package/lib/commands/ci/config/unset.js +36 -0
- package/lib/commands/ci/index.d.ts +1 -0
- package/lib/commands/ci/index.js +1 -0
- package/lib/commands/ci/info.d.ts +1 -0
- package/lib/commands/ci/info.js +1 -0
- package/lib/commands/ci/last.d.ts +1 -0
- package/lib/commands/ci/last.js +1 -0
- package/lib/commands/ci/migrate-manifest.d.ts +7 -0
- package/lib/commands/ci/migrate-manifest.js +74 -0
- package/lib/commands/ci/open.d.ts +1 -0
- package/lib/commands/ci/open.js +1 -0
- package/lib/commands/ci/rerun.d.ts +1 -0
- package/lib/commands/ci/rerun.js +1 -0
- package/lib/commands/config/set.d.ts +12 -0
- package/lib/commands/config/set.js +60 -0
- package/lib/commands/container/index.d.ts +6 -0
- package/lib/commands/container/index.js +13 -0
- package/lib/commands/container/login.d.ts +9 -0
- package/lib/commands/container/login.js +57 -0
- package/lib/commands/container/logout.d.ts +9 -0
- package/lib/commands/container/logout.js +37 -0
- package/lib/commands/container/pull.d.ts +14 -0
- package/lib/commands/container/pull.js +40 -0
- package/lib/commands/container/push.d.ts +16 -0
- package/lib/commands/container/push.js +101 -0
- package/lib/commands/container/release.d.ts +14 -0
- package/lib/commands/container/release.js +89 -0
- package/lib/commands/container/rm.d.ts +13 -0
- package/lib/commands/container/rm.js +36 -0
- package/lib/commands/container/run.d.ts +15 -0
- package/lib/commands/container/run.js +63 -0
- package/lib/commands/dashboard.d.ts +7 -0
- package/lib/commands/dashboard.js +164 -0
- package/lib/commands/domains/index.d.ts +3 -3
- package/lib/commands/drains/add.d.ts +12 -0
- package/lib/commands/drains/add.js +23 -0
- package/lib/commands/drains/index.d.ts +11 -0
- package/lib/commands/drains/index.js +50 -0
- package/lib/commands/drains/remove.d.ts +13 -0
- package/lib/commands/drains/remove.js +22 -0
- package/lib/commands/features/disable.d.ts +12 -0
- package/lib/commands/features/disable.js +30 -0
- package/lib/commands/features/enable.d.ts +12 -0
- package/lib/commands/features/enable.js +29 -0
- package/lib/commands/features/index.d.ts +10 -0
- package/lib/commands/features/index.js +37 -0
- package/lib/commands/features/info.d.ts +13 -0
- package/lib/commands/features/info.js +33 -0
- package/lib/commands/keys/add.d.ts +14 -0
- package/lib/commands/keys/add.js +101 -0
- package/lib/commands/keys/clear.d.ts +5 -0
- package/lib/commands/keys/clear.js +17 -0
- package/lib/commands/keys/index.d.ts +9 -0
- package/lib/commands/keys/index.js +36 -0
- package/lib/commands/keys/remove.d.ts +9 -0
- package/lib/commands/keys/remove.js +29 -0
- package/lib/commands/labs/enable.d.ts +13 -0
- package/lib/commands/labs/enable.js +47 -0
- package/lib/commands/labs/index.d.ts +11 -0
- package/lib/commands/labs/index.js +71 -0
- package/lib/commands/labs/info.d.ts +14 -0
- package/lib/commands/labs/info.js +49 -0
- package/lib/commands/local/index.d.ts +1 -1
- package/lib/commands/local/index.js +8 -3
- package/lib/commands/local/run.d.ts +1 -1
- package/lib/commands/local/run.js +8 -3
- package/lib/commands/maintenance/index.d.ts +10 -0
- package/lib/commands/maintenance/index.js +19 -0
- package/lib/commands/maintenance/off.d.ts +10 -0
- package/lib/commands/maintenance/off.js +20 -0
- package/lib/commands/maintenance/on.d.ts +10 -0
- package/lib/commands/maintenance/on.js +20 -0
- package/lib/commands/members/add.d.ts +13 -0
- package/lib/commands/members/add.js +33 -0
- package/lib/commands/members/index.d.ts +12 -0
- package/lib/commands/members/index.js +76 -0
- package/lib/commands/members/remove.d.ts +10 -0
- package/lib/commands/members/remove.js +58 -0
- package/lib/commands/members/set.d.ts +11 -0
- package/lib/commands/members/set.js +21 -0
- package/lib/commands/notifications/index.d.ts +13 -0
- package/lib/commands/notifications/index.js +62 -0
- package/lib/commands/orgs/index.d.ts +11 -0
- package/lib/commands/orgs/index.js +27 -0
- package/lib/commands/orgs/open.d.ts +10 -0
- package/lib/commands/orgs/open.js +24 -0
- package/lib/commands/pg/backups/cancel.d.ts +15 -0
- package/lib/commands/pg/backups/cancel.js +49 -0
- package/lib/commands/pg/backups/capture.d.ts +15 -0
- package/lib/commands/pg/backups/capture.js +65 -0
- package/lib/commands/pg/backups/delete.d.ts +15 -0
- package/lib/commands/pg/backups/delete.js +38 -0
- package/lib/commands/pg/backups/download.d.ts +14 -0
- package/lib/commands/pg/backups/download.js +58 -0
- package/lib/commands/pg/backups/index.d.ts +20 -0
- package/lib/commands/pg/backups/index.js +129 -0
- package/lib/commands/pg/backups/info.d.ts +17 -0
- package/lib/commands/pg/backups/info.js +92 -0
- package/lib/commands/pg/backups/restore.d.ts +19 -0
- package/lib/commands/pg/backups/restore.js +107 -0
- package/lib/commands/pg/backups/schedule.d.ts +21 -0
- package/lib/commands/pg/backups/schedule.js +82 -0
- package/lib/commands/pg/backups/schedules.d.ts +10 -0
- package/lib/commands/pg/backups/schedules.js +31 -0
- package/lib/commands/pg/backups/unschedule.d.ts +13 -0
- package/lib/commands/pg/backups/unschedule.js +44 -0
- package/lib/commands/pg/backups/url.d.ts +13 -0
- package/lib/commands/pg/backups/url.js +41 -0
- package/lib/commands/pg/bloat.d.ts +13 -0
- package/lib/commands/pg/bloat.js +87 -0
- package/lib/commands/pg/blocking.d.ts +13 -0
- package/lib/commands/pg/blocking.js +42 -0
- package/lib/commands/pg/connection-pooling/attach.d.ts +15 -0
- package/lib/commands/pg/connection-pooling/attach.js +41 -0
- package/lib/commands/pg/copy.d.ts +18 -0
- package/lib/commands/pg/copy.js +86 -0
- package/lib/commands/pg/credentials/create.d.ts +14 -0
- package/lib/commands/pg/credentials/create.js +40 -0
- package/lib/commands/pg/credentials/destroy.d.ts +16 -0
- package/lib/commands/pg/credentials/destroy.js +48 -0
- package/lib/commands/pg/credentials/repair-default.d.ts +15 -0
- package/lib/commands/pg/credentials/repair-default.js +39 -0
- package/lib/commands/pg/credentials/rotate.d.ts +16 -0
- package/lib/commands/pg/credentials/rotate.js +82 -0
- package/lib/commands/pg/credentials/url.d.ts +14 -0
- package/lib/commands/pg/credentials/url.js +64 -0
- package/lib/commands/pg/credentials.d.ts +16 -0
- package/lib/commands/pg/credentials.js +61 -0
- package/lib/commands/pg/diagnose.d.ts +18 -0
- package/lib/commands/pg/diagnose.js +109 -0
- package/lib/commands/pg/info.d.ts +14 -0
- package/lib/commands/pg/info.js +92 -0
- package/lib/commands/pg/kill.d.ts +15 -0
- package/lib/commands/pg/kill.js +32 -0
- package/lib/commands/pg/killall.d.ts +13 -0
- package/lib/commands/pg/killall.js +26 -0
- package/lib/commands/pg/links/create.d.ts +15 -0
- package/lib/commands/pg/links/create.js +58 -0
- package/lib/commands/pg/links/destroy.d.ts +16 -0
- package/lib/commands/pg/links/destroy.js +42 -0
- package/lib/commands/pg/links/index.d.ts +13 -0
- package/lib/commands/pg/links/index.js +59 -0
- package/lib/commands/pg/locks.d.ts +15 -0
- package/lib/commands/pg/locks.js +53 -0
- package/lib/commands/pg/maintenance/index.d.ts +13 -0
- package/lib/commands/pg/maintenance/index.js +29 -0
- package/lib/commands/pg/maintenance/run.d.ts +14 -0
- package/lib/commands/pg/maintenance/run.js +37 -0
- package/lib/commands/pg/maintenance/window.d.ts +15 -0
- package/lib/commands/pg/maintenance/window.js +41 -0
- package/lib/commands/pg/outliers.d.ts +19 -0
- package/lib/commands/pg/outliers.js +97 -0
- package/lib/commands/pg/promote.d.ts +14 -0
- package/lib/commands/pg/promote.js +169 -0
- package/lib/commands/pg/ps.d.ts +14 -0
- package/lib/commands/pg/ps.js +52 -0
- package/lib/commands/pg/psql.d.ts +16 -0
- package/lib/commands/pg/psql.js +49 -0
- package/lib/commands/pg/pull.d.ts +18 -0
- package/lib/commands/pg/pull.js +87 -0
- package/lib/commands/pg/push.d.ts +18 -0
- package/lib/commands/pg/push.js +84 -0
- package/lib/commands/pg/reset.d.ts +15 -0
- package/lib/commands/pg/reset.js +44 -0
- package/lib/commands/pg/settings/auto-explain/log-analyze.d.ts +13 -0
- package/lib/commands/pg/settings/auto-explain/log-analyze.js +32 -0
- package/lib/commands/pg/settings/auto-explain/log-buffers.d.ts +13 -0
- package/lib/commands/pg/settings/auto-explain/log-buffers.js +30 -0
- package/lib/commands/pg/settings/auto-explain/log-min-duration.d.ts +16 -0
- package/lib/commands/pg/settings/auto-explain/log-min-duration.js +33 -0
- package/lib/commands/pg/settings/auto-explain/log-nested-statements.d.ts +12 -0
- package/lib/commands/pg/settings/auto-explain/log-nested-statements.js +25 -0
- package/lib/commands/pg/settings/auto-explain/log-triggers.d.ts +13 -0
- package/lib/commands/pg/settings/auto-explain/log-triggers.js +30 -0
- package/lib/commands/pg/settings/auto-explain/log-verbose.d.ts +17 -0
- package/lib/commands/pg/settings/auto-explain/log-verbose.js +33 -0
- package/lib/commands/pg/settings/auto-explain.d.ts +18 -0
- package/lib/commands/pg/settings/auto-explain.js +38 -0
- package/lib/commands/pg/settings/index.d.ts +13 -0
- package/lib/commands/pg/settings/index.js +34 -0
- package/lib/commands/pg/settings/log-connections.d.ts +17 -0
- package/lib/commands/pg/settings/log-connections.js +34 -0
- package/lib/commands/pg/settings/log-lock-waits.d.ts +13 -0
- package/lib/commands/pg/settings/log-lock-waits.js +31 -0
- package/lib/commands/pg/settings/log-min-duration-statement.d.ts +15 -0
- package/lib/commands/pg/settings/log-min-duration-statement.js +33 -0
- package/lib/commands/pg/settings/log-statement.d.ts +12 -0
- package/lib/commands/pg/settings/log-statement.js +30 -0
- package/lib/commands/pg/settings/track-functions.d.ts +12 -0
- package/lib/commands/pg/settings/track-functions.js +29 -0
- package/lib/commands/pg/unfollow.d.ts +14 -0
- package/lib/commands/pg/unfollow.js +40 -0
- package/lib/commands/pg/upgrade.d.ts +15 -0
- package/lib/commands/pg/upgrade.js +58 -0
- package/lib/commands/pg/vacuum-stats.d.ts +13 -0
- package/lib/commands/pg/vacuum-stats.js +65 -0
- package/lib/commands/pg/wait.d.ts +15 -0
- package/lib/commands/pg/wait.js +79 -0
- package/lib/commands/pipelines/connect.js +1 -1
- package/lib/commands/pipelines/diff.js +1 -1
- package/lib/commands/ps/index.d.ts +15 -0
- package/lib/commands/ps/index.js +195 -0
- package/lib/commands/ps/restart.d.ts +17 -0
- package/lib/commands/ps/restart.js +38 -0
- package/lib/commands/ps/scale.d.ts +13 -0
- package/lib/commands/ps/scale.js +108 -0
- package/lib/commands/ps/stop.d.ts +17 -0
- package/lib/commands/ps/stop.js +33 -0
- package/lib/commands/ps/type.d.ts +12 -0
- package/lib/commands/ps/type.js +163 -0
- package/lib/commands/redis/cli.d.ts +15 -0
- package/lib/commands/redis/cli.js +204 -0
- package/lib/commands/redis/credentials.d.ts +14 -0
- package/lib/commands/redis/credentials.js +32 -0
- package/lib/commands/redis/info.d.ts +15 -0
- package/lib/commands/redis/info.js +25 -0
- package/lib/commands/redis/keyspace-notifications.d.ts +14 -0
- package/lib/commands/redis/keyspace-notifications.js +47 -0
- package/lib/commands/redis/maintenance.d.ts +16 -0
- package/lib/commands/redis/maintenance.js +63 -0
- package/lib/commands/redis/maxmemory.d.ts +14 -0
- package/lib/commands/redis/maxmemory.js +40 -0
- package/lib/commands/redis/promote.d.ts +13 -0
- package/lib/commands/redis/promote.js +39 -0
- package/lib/commands/redis/stats-reset.d.ts +14 -0
- package/lib/commands/redis/stats-reset.js +36 -0
- package/lib/commands/redis/timeout.d.ts +14 -0
- package/lib/commands/redis/timeout.js +35 -0
- package/lib/commands/redis/upgrade.d.ts +15 -0
- package/lib/commands/redis/upgrade.js +37 -0
- package/lib/commands/redis/wait.d.ts +14 -0
- package/lib/commands/redis/wait.js +60 -0
- package/lib/commands/releases/index.d.ts +14 -0
- package/lib/commands/releases/index.js +124 -0
- package/lib/commands/releases/info.d.ts +15 -0
- package/lib/commands/releases/info.js +56 -0
- package/lib/commands/releases/output.d.ts +13 -0
- package/lib/commands/releases/output.js +37 -0
- package/lib/commands/releases/rollback.d.ts +14 -0
- package/lib/commands/releases/rollback.js +48 -0
- package/lib/commands/run/detached.d.ts +7 -8
- package/lib/commands/run/detached.js +16 -20
- package/lib/commands/run/index.d.ts +10 -11
- package/lib/commands/run/index.js +16 -17
- package/lib/commands/run/inside.d.ts +5 -7
- package/lib/commands/run/inside.js +10 -14
- package/lib/commands/spaces/create.d.ts +22 -0
- package/lib/commands/spaces/create.js +73 -0
- package/lib/commands/spaces/destroy.d.ts +14 -0
- package/lib/commands/spaces/destroy.js +49 -0
- package/lib/commands/spaces/drains/get.d.ts +12 -0
- package/lib/commands/spaces/drains/get.js +27 -0
- package/lib/commands/spaces/drains/set.d.ts +14 -0
- package/lib/commands/spaces/drains/set.js +29 -0
- package/lib/commands/spaces/hosts.d.ts +14 -0
- package/lib/commands/spaces/hosts.js +37 -0
- package/lib/commands/spaces/index.d.ts +16 -0
- package/lib/commands/spaces/index.js +55 -0
- package/lib/commands/spaces/info.d.ts +14 -0
- package/lib/commands/spaces/info.js +47 -0
- package/lib/commands/spaces/outbound-rules/add.d.ts +15 -0
- package/lib/commands/spaces/outbound-rules/add.js +81 -0
- package/lib/commands/spaces/outbound-rules/index.d.ts +15 -0
- package/lib/commands/spaces/outbound-rules/index.js +49 -0
- package/lib/commands/spaces/outbound-rules/remove.d.ts +17 -0
- package/lib/commands/spaces/outbound-rules/remove.js +53 -0
- package/lib/commands/spaces/peerings/accept.d.ts +15 -0
- package/lib/commands/spaces/peerings/accept.js +36 -0
- package/lib/commands/spaces/peerings/destroy.d.ts +15 -0
- package/lib/commands/spaces/peerings/destroy.js +45 -0
- package/lib/commands/spaces/peerings/index.d.ts +13 -0
- package/lib/commands/spaces/peerings/index.js +33 -0
- package/lib/commands/spaces/peerings/info.d.ts +15 -0
- package/lib/commands/spaces/peerings/info.js +59 -0
- package/lib/commands/spaces/ps.d.ts +15 -0
- package/lib/commands/spaces/ps.js +82 -0
- package/lib/commands/spaces/rename.d.ts +11 -0
- package/lib/commands/spaces/rename.js +26 -0
- package/lib/commands/spaces/topology.d.ts +32 -0
- package/lib/commands/spaces/topology.js +89 -0
- package/lib/commands/spaces/transfer.d.ts +11 -0
- package/lib/commands/spaces/transfer.js +35 -0
- package/lib/commands/spaces/trusted-ips/add.d.ts +16 -0
- package/lib/commands/spaces/trusted-ips/add.js +43 -0
- package/lib/commands/spaces/trusted-ips/index.d.ts +15 -0
- package/lib/commands/spaces/trusted-ips/index.js +52 -0
- package/lib/commands/spaces/trusted-ips/remove.d.ts +15 -0
- package/lib/commands/spaces/trusted-ips/remove.js +44 -0
- package/lib/commands/spaces/vpn/config.d.ts +14 -0
- package/lib/commands/spaces/vpn/config.js +54 -0
- package/lib/commands/spaces/vpn/connect.d.ts +15 -0
- package/lib/commands/spaces/vpn/connect.js +45 -0
- package/lib/commands/spaces/vpn/connections.d.ts +17 -0
- package/lib/commands/spaces/vpn/connections.js +57 -0
- package/lib/commands/spaces/vpn/destroy.d.ts +14 -0
- package/lib/commands/spaces/vpn/destroy.js +35 -0
- package/lib/commands/spaces/vpn/info.d.ts +16 -0
- package/lib/commands/spaces/vpn/info.js +82 -0
- package/lib/commands/spaces/vpn/update.d.ts +14 -0
- package/lib/commands/spaces/vpn/update.js +36 -0
- package/lib/commands/spaces/vpn/wait.d.ts +13 -0
- package/lib/commands/spaces/vpn/wait.js +53 -0
- package/lib/commands/spaces/wait.d.ts +17 -0
- package/lib/commands/spaces/wait.js +89 -0
- package/lib/commands/status.js +4 -4
- package/lib/commands/teams/index.d.ts +9 -0
- package/lib/commands/teams/index.js +29 -0
- package/lib/global_telemetry.js +10 -4
- package/lib/hooks/postrun/performance_analytics.js +5 -4
- package/lib/hooks/prerun/analytics.js +3 -0
- package/lib/lib/addons/addons_wait.d.ts +78 -0
- package/lib/lib/addons/addons_wait.js +56 -0
- package/lib/lib/addons/create_addon.d.ts +7 -0
- package/lib/lib/addons/create_addon.js +59 -0
- package/lib/lib/addons/destroy_addon.d.ts +3 -0
- package/lib/lib/addons/destroy_addon.js +48 -0
- package/lib/lib/addons/resolve.d.ts +38 -0
- package/lib/lib/addons/resolve.js +179 -0
- package/lib/lib/addons/util.d.ts +9 -0
- package/lib/lib/addons/util.js +72 -0
- package/lib/lib/api.d.ts +1 -1
- package/lib/lib/apps/app-transfer.d.ts +10 -0
- package/lib/lib/apps/app-transfer.js +35 -0
- package/lib/lib/apps/error_info.d.ts +7 -0
- package/lib/lib/apps/error_info.js +185 -0
- package/lib/lib/autocomplete/completions.d.ts +4 -0
- package/lib/lib/autocomplete/completions.js +6 -1
- package/lib/lib/buildpacks/buildpacks.js +3 -4
- package/lib/lib/certs/certificate_details.d.ts +2 -0
- package/lib/lib/certs/certificate_details.js +37 -0
- package/lib/lib/certs/display_table.d.ts +2 -0
- package/lib/lib/certs/display_table.js +51 -0
- package/lib/lib/certs/domains.d.ts +3 -0
- package/lib/lib/certs/domains.js +45 -0
- package/lib/lib/certs/flags.d.ts +7 -0
- package/lib/lib/certs/flags.js +42 -0
- package/lib/lib/certs/format_date.d.ts +1 -0
- package/lib/lib/certs/format_date.js +11 -0
- package/lib/lib/certs/get_cert_and_key.d.ts +9 -0
- package/lib/lib/certs/get_cert_and_key.js +11 -0
- package/lib/lib/ci/git.d.ts +7 -1
- package/lib/lib/ci/git.js +44 -1
- package/lib/lib/ci/interfaces/kolkrabbi.d.ts +1 -1
- package/lib/lib/ci/source.js +3 -3
- package/lib/lib/ci/test-run.js +2 -2
- package/lib/lib/ci/validate.d.ts +2 -0
- package/lib/lib/ci/validate.js +10 -0
- package/lib/lib/config/quote.js +1 -1
- package/lib/lib/confirmCommand.d.ts +1 -0
- package/lib/lib/confirmCommand.js +23 -0
- package/lib/lib/container/debug.d.ts +2 -0
- package/lib/lib/container/debug.js +5 -0
- package/lib/lib/container/docker_helper.d.ts +24 -0
- package/lib/lib/container/docker_helper.js +168 -0
- package/lib/lib/container/streamer.d.ts +1 -0
- package/lib/lib/container/streamer.js +31 -0
- package/lib/lib/domains/domains.d.ts +6 -0
- package/lib/lib/domains/domains.js +104 -0
- package/lib/lib/git/git.d.ts +3 -0
- package/lib/lib/git/git.js +19 -0
- package/lib/lib/git/push.d.ts +1 -0
- package/lib/lib/git/push.js +6 -0
- package/lib/lib/local/run-foreman.d.ts +1 -0
- package/lib/lib/local/run-foreman.js +229 -1
- package/lib/lib/members/util.d.ts +3 -0
- package/lib/lib/members/util.js +25 -0
- package/lib/lib/members/utils.d.ts +2 -0
- package/lib/lib/members/utils.js +14 -0
- package/lib/lib/notify.d.ts +1 -0
- package/lib/lib/notify.js +23 -0
- package/lib/lib/orgs/utils.d.ts +5 -0
- package/lib/lib/orgs/utils.js +24 -0
- package/lib/lib/pg/backups.d.ts +17 -0
- package/lib/lib/pg/backups.js +164 -0
- package/lib/lib/pg/bastion.d.ts +29 -0
- package/lib/lib/pg/bastion.js +121 -0
- package/lib/lib/pg/config.d.ts +2 -0
- package/lib/lib/pg/config.js +13 -0
- package/lib/lib/pg/download.d.ts +5 -0
- package/lib/lib/pg/download.js +34 -0
- package/lib/lib/pg/fetcher.d.ts +39 -0
- package/lib/lib/pg/fetcher.js +137 -0
- package/lib/lib/pg/host.d.ts +1 -0
- package/lib/lib/pg/host.js +7 -0
- package/lib/lib/pg/psql.d.ts +48 -0
- package/lib/lib/pg/psql.js +252 -0
- package/lib/lib/pg/push_pull.d.ts +13 -0
- package/lib/lib/pg/push_pull.js +118 -0
- package/lib/lib/pg/setter.d.ts +16 -0
- package/lib/lib/pg/setter.js +65 -0
- package/lib/lib/pg/types.d.ts +230 -0
- package/lib/lib/pg/types.js +2 -0
- package/lib/lib/pg/util.d.ts +36 -0
- package/lib/lib/pg/util.js +183 -0
- package/lib/lib/redis/api.d.ts +65 -0
- package/lib/lib/redis/api.js +122 -0
- package/lib/lib/releases/output.d.ts +1 -0
- package/lib/lib/releases/output.js +14 -0
- package/lib/lib/releases/releases.d.ts +6 -0
- package/lib/lib/releases/releases.js +32 -0
- package/lib/lib/releases/status_helper.d.ts +5 -0
- package/lib/lib/releases/status_helper.js +25 -0
- package/lib/lib/run/dyno.js +2 -2
- package/lib/lib/run/log-displayer.d.ts +1 -1
- package/lib/lib/spaces/format.d.ts +4 -0
- package/lib/lib/spaces/format.js +60 -0
- package/lib/lib/spaces/hosts.d.ts +9 -0
- package/lib/lib/spaces/hosts.js +34 -0
- package/lib/lib/spaces/outbound-rules.d.ts +4 -0
- package/lib/lib/spaces/outbound-rules.js +78 -0
- package/lib/lib/spaces/parsers.d.ts +8 -0
- package/lib/lib/spaces/parsers.js +17 -0
- package/lib/lib/spaces/peering.d.ts +4 -0
- package/lib/lib/spaces/peering.js +53 -0
- package/lib/lib/spaces/spaces.d.ts +4 -0
- package/lib/lib/spaces/spaces.js +37 -0
- package/lib/lib/spaces/vpn-connections.d.ts +2 -0
- package/lib/lib/spaces/vpn-connections.js +22 -0
- package/lib/lib/teamUtils.d.ts +3 -0
- package/lib/lib/teamUtils.js +18 -0
- package/lib/lib/time.d.ts +2 -0
- package/lib/lib/time.js +29 -0
- package/lib/lib/types/app_errors.d.ts +6 -0
- package/lib/lib/types/app_errors.js +2 -0
- package/lib/lib/types/domain.d.ts +61 -0
- package/lib/lib/types/domain.js +5 -0
- package/lib/lib/types/favorites.d.ts +7 -0
- package/lib/lib/types/favorites.js +2 -0
- package/lib/lib/types/notifications.d.ts +20 -0
- package/lib/lib/types/notifications.js +2 -0
- package/lib/lib/utils/multisort.d.ts +32 -0
- package/lib/lib/utils/multisort.js +66 -0
- package/lib/lib/utils/uuid-validate.d.ts +1 -0
- package/lib/lib/utils/uuid-validate.js +7 -0
- package/lib/user-config.js +2 -2
- package/oclif.manifest.json +12920 -2534
- package/package.json +111 -60
- package/lib/lib/buildpacks/push.d.ts +0 -0
- package/lib/lib/buildpacks/push.js +0 -4
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchConfig = exports.sshTunnel = exports.getConfigs = exports.tunnelConfig = exports.env = exports.getBastion = void 0;
|
|
4
|
+
const debug = require('debug')('pg');
|
|
5
|
+
const EventEmitter = require("node:events");
|
|
6
|
+
const createTunnel = require("tunnel-ssh");
|
|
7
|
+
const util_1 = require("util");
|
|
8
|
+
const host_1 = require("./host");
|
|
9
|
+
const core_1 = require("@oclif/core");
|
|
10
|
+
const getBastion = function (config, baseName) {
|
|
11
|
+
// If there are bastions, extract a host and a key
|
|
12
|
+
// otherwise, return an empty Object
|
|
13
|
+
// If there are bastions:
|
|
14
|
+
// * there should be one *_BASTION_KEY
|
|
15
|
+
// * pick one host from the comma-separated list in *_BASTIONS
|
|
16
|
+
// We assert that _BASTIONS and _BASTION_KEY always exist together
|
|
17
|
+
// If either is falsy, pretend neither exist
|
|
18
|
+
const bastionKey = config[`${baseName}_BASTION_KEY`];
|
|
19
|
+
const bastions = (config[`${baseName}_BASTIONS`] || '').split(',');
|
|
20
|
+
const bastionHost = bastions[Math.floor(Math.random() * bastions.length)];
|
|
21
|
+
return (bastionKey && bastionHost) ? { bastionHost, bastionKey } : {};
|
|
22
|
+
};
|
|
23
|
+
exports.getBastion = getBastion;
|
|
24
|
+
const env = (db) => {
|
|
25
|
+
const baseEnv = Object.assign({
|
|
26
|
+
PGAPPNAME: 'psql non-interactive',
|
|
27
|
+
PGSSLMODE: (!db.host || db.host === 'localhost') ? 'prefer' : 'require',
|
|
28
|
+
}, process.env);
|
|
29
|
+
const mapping = {
|
|
30
|
+
PGUSER: 'user',
|
|
31
|
+
PGPASSWORD: 'password',
|
|
32
|
+
PGDATABASE: 'database',
|
|
33
|
+
PGPORT: 'port',
|
|
34
|
+
PGHOST: 'host',
|
|
35
|
+
};
|
|
36
|
+
Object.keys(mapping).forEach(envVar => {
|
|
37
|
+
const val = db[mapping[envVar]];
|
|
38
|
+
if (val) {
|
|
39
|
+
baseEnv[envVar] = val;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return baseEnv;
|
|
43
|
+
};
|
|
44
|
+
exports.env = env;
|
|
45
|
+
function tunnelConfig(db) {
|
|
46
|
+
const localHost = '127.0.0.1';
|
|
47
|
+
const localPort = Math.floor((Math.random() * (65535 - 49152)) + 49152);
|
|
48
|
+
return {
|
|
49
|
+
username: 'bastion',
|
|
50
|
+
host: db.bastionHost,
|
|
51
|
+
privateKey: db.bastionKey,
|
|
52
|
+
dstHost: db.host || undefined,
|
|
53
|
+
dstPort: (db.port && Number.parseInt(db.port, 10)) || undefined,
|
|
54
|
+
localHost,
|
|
55
|
+
localPort,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
exports.tunnelConfig = tunnelConfig;
|
|
59
|
+
function getConfigs(db) {
|
|
60
|
+
const dbEnv = (0, exports.env)(db);
|
|
61
|
+
const dbTunnelConfig = tunnelConfig(db);
|
|
62
|
+
if (db.bastionKey) {
|
|
63
|
+
Object.assign(dbEnv, {
|
|
64
|
+
PGPORT: dbTunnelConfig.localPort,
|
|
65
|
+
PGHOST: dbTunnelConfig.localHost,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
dbEnv,
|
|
70
|
+
dbTunnelConfig,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
exports.getConfigs = getConfigs;
|
|
74
|
+
class Timeout {
|
|
75
|
+
constructor(timeout, message) {
|
|
76
|
+
this.events = new EventEmitter();
|
|
77
|
+
this.timeout = timeout;
|
|
78
|
+
this.message = message;
|
|
79
|
+
}
|
|
80
|
+
async promise() {
|
|
81
|
+
this.timer = setTimeout(() => {
|
|
82
|
+
this.events.emit('error', new Error(this.message));
|
|
83
|
+
}, this.timeout);
|
|
84
|
+
try {
|
|
85
|
+
await EventEmitter.once(this.events, 'cancelled');
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
clearTimeout(this.timer);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
cancel() {
|
|
92
|
+
this.events.emit('cancelled');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function sshTunnel(db, dbTunnelConfig, timeout = 10000) {
|
|
96
|
+
if (!db.bastionKey) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const timeoutInstance = new Timeout(timeout, 'Establishing a secure tunnel timed out');
|
|
100
|
+
const createSSHTunnel = (0, util_1.promisify)(createTunnel);
|
|
101
|
+
try {
|
|
102
|
+
return await Promise.race([
|
|
103
|
+
timeoutInstance.promise(),
|
|
104
|
+
createSSHTunnel(dbTunnelConfig),
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
debug(error);
|
|
109
|
+
core_1.ux.error('Unable to establish a secure tunnel to your database.');
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
timeoutInstance.cancel();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.sshTunnel = sshTunnel;
|
|
116
|
+
async function fetchConfig(heroku, db) {
|
|
117
|
+
return heroku.get(`/client/v11/databases/${encodeURIComponent(db.id)}/bastion`, {
|
|
118
|
+
hostname: (0, host_1.default)(),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
exports.fetchConfig = fetchConfig;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getConfig = void 0;
|
|
4
|
+
const responseByAppId = new Map();
|
|
5
|
+
async function getConfig(heroku, app) {
|
|
6
|
+
if (!responseByAppId.has(app)) {
|
|
7
|
+
const promise = heroku.get(`/apps/${app}/config-vars`);
|
|
8
|
+
responseByAppId.set(app, promise);
|
|
9
|
+
}
|
|
10
|
+
const result = await responseByAppId.get(app);
|
|
11
|
+
return result === null || result === void 0 ? void 0 : result.body;
|
|
12
|
+
}
|
|
13
|
+
exports.getConfig = getConfig;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs = require("fs-extra");
|
|
4
|
+
const Path = require("path");
|
|
5
|
+
const https = require('https');
|
|
6
|
+
const bytes = require('bytes');
|
|
7
|
+
const progress = require('smooth-progress');
|
|
8
|
+
function download(url, path, opts) {
|
|
9
|
+
const tty = process.stderr.isTTY && process.env.TERM !== 'dumb';
|
|
10
|
+
function showProgress(rsp) {
|
|
11
|
+
const bar = progress({
|
|
12
|
+
tmpl: `Downloading ${path}... :bar :percent :eta :data`,
|
|
13
|
+
width: 25,
|
|
14
|
+
total: Number.parseInt(rsp.headers['content-length'], 10),
|
|
15
|
+
});
|
|
16
|
+
let total = 0;
|
|
17
|
+
rsp.on('data', function (chunk) {
|
|
18
|
+
total += chunk.length;
|
|
19
|
+
bar.tick(chunk.length, { data: bytes(total, { decimalPlaces: 2, fixedDecimals: 2 }) });
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return new Promise(function (resolve, reject) {
|
|
23
|
+
fs.mkdirSync(Path.dirname(path), { recursive: true });
|
|
24
|
+
const file = fs.createWriteStream(path);
|
|
25
|
+
https.get(url, function (rsp) {
|
|
26
|
+
if (tty && opts.progress)
|
|
27
|
+
showProgress(rsp);
|
|
28
|
+
rsp.pipe(file)
|
|
29
|
+
.on('error', reject)
|
|
30
|
+
.on('close', resolve);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.default = download;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { APIClient } from '@heroku-cli/command';
|
|
2
|
+
import type { AddOnAttachment } from '@heroku-cli/schema';
|
|
3
|
+
import * as Heroku from '@heroku-cli/schema';
|
|
4
|
+
import type { AddOnAttachmentWithConfigVarsAndPlan, AddOnWithRelatedData } from './types';
|
|
5
|
+
export declare function arbitraryAppDB(heroku: APIClient, app: string): Promise<Heroku.AddOn>;
|
|
6
|
+
export declare function all(heroku: APIClient, app_id: string): Promise<AddOnWithRelatedData[]>;
|
|
7
|
+
export declare function getAttachment(heroku: APIClient, app: string, db?: string, namespace?: string): Promise<Required<AddOnAttachment & {
|
|
8
|
+
addon: AddOnAttachmentWithConfigVarsAndPlan;
|
|
9
|
+
}>>;
|
|
10
|
+
export declare function getAddon(heroku: APIClient, app: string, db?: string): Promise<{
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
app: {
|
|
14
|
+
[k: string]: any;
|
|
15
|
+
id?: string | undefined;
|
|
16
|
+
name?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
} & Required<AddOnAttachment> & {
|
|
19
|
+
config_vars: string[] | undefined;
|
|
20
|
+
addon: Required<{
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
app: {
|
|
24
|
+
[k: string]: any;
|
|
25
|
+
id?: string | undefined;
|
|
26
|
+
name?: string | undefined;
|
|
27
|
+
};
|
|
28
|
+
}> & {
|
|
29
|
+
attachment_names?: string[] | undefined;
|
|
30
|
+
links?: import("./types").Link[] | undefined;
|
|
31
|
+
plan: Required<{
|
|
32
|
+
[k: string]: any;
|
|
33
|
+
id?: string | undefined;
|
|
34
|
+
name?: string | undefined;
|
|
35
|
+
} | undefined>;
|
|
36
|
+
};
|
|
37
|
+
}>;
|
|
38
|
+
export declare function database(heroku: APIClient, app: string, db?: string, namespace?: string): Promise<import("./util").ConnectionDetailsWithAttachment>;
|
|
39
|
+
export declare function getRelease(heroku: APIClient, appName: string, id: string): Promise<Heroku.Release>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRelease = exports.database = exports.getAddon = exports.getAttachment = exports.all = exports.arbitraryAppDB = void 0;
|
|
4
|
+
const debug_1 = require("debug");
|
|
5
|
+
const resolve_1 = require("../addons/resolve");
|
|
6
|
+
const bastion_1 = require("./bastion");
|
|
7
|
+
const config_1 = require("./config");
|
|
8
|
+
const color_1 = require("@heroku-cli/color");
|
|
9
|
+
const util_1 = require("./util");
|
|
10
|
+
const pgDebug = (0, debug_1.default)('pg');
|
|
11
|
+
async function arbitraryAppDB(heroku, app) {
|
|
12
|
+
// Since Postgres backups are tied to the app and not the add-on, but
|
|
13
|
+
// we require *an* add-on to interact with, make sure that add-on is
|
|
14
|
+
// attached to the right app.
|
|
15
|
+
pgDebug(`fetching arbitrary app db on ${app}`);
|
|
16
|
+
const { body: addons } = await heroku.get(`/apps/${app}/addons`);
|
|
17
|
+
const addon = addons.find(a => { var _a, _b, _c; return ((_a = a === null || a === void 0 ? void 0 : a.app) === null || _a === void 0 ? void 0 : _a.name) === app && ((_c = (_b = a === null || a === void 0 ? void 0 : a.plan) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.startsWith('heroku-postgresql')); });
|
|
18
|
+
if (!addon)
|
|
19
|
+
throw new Error(`No heroku-postgresql databases on ${app}`);
|
|
20
|
+
return addon;
|
|
21
|
+
}
|
|
22
|
+
exports.arbitraryAppDB = arbitraryAppDB;
|
|
23
|
+
function getAttachmentNamesByAddon(attachments) {
|
|
24
|
+
return attachments.reduce((results, a) => {
|
|
25
|
+
results[a.addon.id] = (results[a.addon.id] || []).concat(a.name);
|
|
26
|
+
return results;
|
|
27
|
+
}, {});
|
|
28
|
+
}
|
|
29
|
+
async function all(heroku, app_id) {
|
|
30
|
+
const { uniqBy } = require('lodash');
|
|
31
|
+
pgDebug(`fetching all DBs on ${app_id}`);
|
|
32
|
+
const attachments = await allAttachments(heroku, app_id);
|
|
33
|
+
let addons = attachments.map(a => a.addon);
|
|
34
|
+
// Get the list of attachment names per addon here and add to each addon obj
|
|
35
|
+
const attachmentNamesByAddon = getAttachmentNamesByAddon(attachments);
|
|
36
|
+
addons = uniqBy(addons, 'id');
|
|
37
|
+
addons.forEach(addon => {
|
|
38
|
+
addon.attachment_names = attachmentNamesByAddon[addon.id];
|
|
39
|
+
});
|
|
40
|
+
return addons;
|
|
41
|
+
}
|
|
42
|
+
exports.all = all;
|
|
43
|
+
async function matchesHelper(heroku, app, db, namespace) {
|
|
44
|
+
var _a;
|
|
45
|
+
(0, debug_1.default)(`fetching ${db} on ${app}`);
|
|
46
|
+
const addonService = process.env.HEROKU_POSTGRESQL_ADDON_NAME || 'heroku-postgresql';
|
|
47
|
+
(0, debug_1.default)(`addon service: ${addonService}`);
|
|
48
|
+
try {
|
|
49
|
+
const attached = await (0, resolve_1.appAttachment)(heroku, app, db, { addon_service: addonService, namespace });
|
|
50
|
+
return ({ matches: [attached] });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error instanceof resolve_1.AmbiguousError && ((_a = error.body) === null || _a === void 0 ? void 0 : _a.id) === 'multiple_matches' && error.matches) {
|
|
54
|
+
return { matches: error.matches, error };
|
|
55
|
+
}
|
|
56
|
+
if (error instanceof resolve_1.NotFound) {
|
|
57
|
+
return { matches: null, error };
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function getAttachment(heroku, app, db = 'DATABASE_URL', namespace = '') {
|
|
63
|
+
var _a;
|
|
64
|
+
const matchesOrError = await matchesHelper(heroku, app, db, namespace);
|
|
65
|
+
let { matches } = matchesOrError;
|
|
66
|
+
const { error } = matchesOrError;
|
|
67
|
+
// happy path where the resolver matches just one
|
|
68
|
+
if (matches && matches.length === 1) {
|
|
69
|
+
return matches[0];
|
|
70
|
+
}
|
|
71
|
+
// case for 404 where there are implicit attachments
|
|
72
|
+
if (!matches) {
|
|
73
|
+
const appConfigMatch = /^(.+?)::(.+)/.exec(db);
|
|
74
|
+
if (appConfigMatch) {
|
|
75
|
+
app = appConfigMatch[1];
|
|
76
|
+
db = appConfigMatch[2];
|
|
77
|
+
}
|
|
78
|
+
if (!db.endsWith('_URL')) {
|
|
79
|
+
db += '_URL';
|
|
80
|
+
}
|
|
81
|
+
const [config = {}, attachments] = await Promise.all([
|
|
82
|
+
(0, config_1.getConfig)(heroku, app),
|
|
83
|
+
allAttachments(heroku, app),
|
|
84
|
+
]);
|
|
85
|
+
if (attachments.length === 0) {
|
|
86
|
+
throw new Error(`${color_1.default.app(app)} has no databases`);
|
|
87
|
+
}
|
|
88
|
+
console.log('hi', JSON.stringify(attachments));
|
|
89
|
+
matches = attachments.filter(attachment => config[db] && config[db] === config[(0, util_1.getConfigVarName)(attachment.config_vars)]);
|
|
90
|
+
if (matches.length === 0) {
|
|
91
|
+
const validOptions = attachments.map(attachment => (0, util_1.getConfigVarName)(attachment.config_vars));
|
|
92
|
+
throw new Error(`Unknown database: ${db}. Valid options are: ${validOptions.join(', ')}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// case for multiple attachments with passedDb
|
|
96
|
+
const first = matches[0];
|
|
97
|
+
// case for 422 where there are ambiguous attachments that are equivalent
|
|
98
|
+
if (matches.every(match => { var _a, _b, _c, _d; return ((_a = first.addon) === null || _a === void 0 ? void 0 : _a.id) === ((_b = match.addon) === null || _b === void 0 ? void 0 : _b.id) && ((_c = first.app) === null || _c === void 0 ? void 0 : _c.id) === ((_d = match.app) === null || _d === void 0 ? void 0 : _d.id); })) {
|
|
99
|
+
const config = (_a = await (0, config_1.getConfig)(heroku, first.app.name)) !== null && _a !== void 0 ? _a : {};
|
|
100
|
+
if (matches.every(match => config[(0, util_1.getConfigVarName)(first.config_vars)] === config[(0, util_1.getConfigVarName)(match.config_vars)])) {
|
|
101
|
+
return first;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
exports.getAttachment = getAttachment;
|
|
107
|
+
async function allAttachments(heroku, app_id) {
|
|
108
|
+
const { body: attachments } = await heroku.get(`/apps/${app_id}/addon-attachments`, {
|
|
109
|
+
headers: { 'Accept-Inclusion': 'addon:plan,config_vars' },
|
|
110
|
+
});
|
|
111
|
+
return attachments.filter((a) => { var _a, _b; return (_b = (_a = a.addon.plan) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.startsWith('heroku-postgresql'); });
|
|
112
|
+
}
|
|
113
|
+
async function getAddon(heroku, app, db = 'DATABASE_URL') {
|
|
114
|
+
return (await getAttachment(heroku, app, db)).addon;
|
|
115
|
+
}
|
|
116
|
+
exports.getAddon = getAddon;
|
|
117
|
+
async function database(heroku, app, db, namespace) {
|
|
118
|
+
const attached = await getAttachment(heroku, app, db, namespace);
|
|
119
|
+
// would inline this as well but in some cases attachment pulls down config
|
|
120
|
+
// as well, and we would request twice at the same time but I did not want
|
|
121
|
+
// to push this down into attachment because we do not always need config
|
|
122
|
+
const config = await (0, config_1.getConfig)(heroku, attached.app.name);
|
|
123
|
+
const database = (0, util_1.getConnectionDetails)(attached, config);
|
|
124
|
+
if ((0, util_1.bastionKeyPlan)(attached.addon) && !database.bastionKey) {
|
|
125
|
+
const { body: bastionConfig } = await (0, bastion_1.fetchConfig)(heroku, attached.addon);
|
|
126
|
+
const bastionHost = bastionConfig.host;
|
|
127
|
+
const bastionKey = bastionConfig.private_key;
|
|
128
|
+
Object.assign(database, { bastionHost, bastionKey });
|
|
129
|
+
}
|
|
130
|
+
return database;
|
|
131
|
+
}
|
|
132
|
+
exports.database = database;
|
|
133
|
+
async function getRelease(heroku, appName, id) {
|
|
134
|
+
const { body: release } = await heroku.get(`/apps/${appName}/releases/${id}`);
|
|
135
|
+
return release;
|
|
136
|
+
}
|
|
137
|
+
exports.getRelease = getRelease;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function (): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
5
|
+
/// <reference types="node" />
|
|
6
|
+
import { SpawnOptions, type SpawnOptionsWithStdioTuple } from 'child_process';
|
|
7
|
+
import type { ChildProcess } from 'node:child_process';
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
import type { Server } from 'node:net';
|
|
10
|
+
import { Stream } from 'node:stream';
|
|
11
|
+
import { getConfigs, TunnelConfig } from './bastion';
|
|
12
|
+
import { ConnectionDetails, getConnectionDetails } from './util';
|
|
13
|
+
export declare function psqlQueryOptions(query: string, dbEnv: NodeJS.ProcessEnv, cmdArgs?: string[]): {
|
|
14
|
+
dbEnv: NodeJS.ProcessEnv;
|
|
15
|
+
psqlArgs: string[];
|
|
16
|
+
childProcessOptions: SpawnOptionsWithStdioTuple<"ignore", "pipe", "inherit">;
|
|
17
|
+
};
|
|
18
|
+
export declare function psqlFileOptions(file: string, dbEnv: NodeJS.ProcessEnv): {
|
|
19
|
+
dbEnv: NodeJS.ProcessEnv;
|
|
20
|
+
psqlArgs: string[];
|
|
21
|
+
childProcessOptions: SpawnOptions;
|
|
22
|
+
};
|
|
23
|
+
export declare function psqlInteractiveOptions(prompt: string, dbEnv: NodeJS.ProcessEnv): {
|
|
24
|
+
dbEnv: NodeJS.ProcessEnv;
|
|
25
|
+
psqlArgs: string[];
|
|
26
|
+
childProcessOptions: SpawnOptions;
|
|
27
|
+
};
|
|
28
|
+
export declare function execPSQL({ dbEnv, psqlArgs, childProcessOptions }: {
|
|
29
|
+
dbEnv: NodeJS.ProcessEnv;
|
|
30
|
+
psqlArgs: string[];
|
|
31
|
+
childProcessOptions: SpawnOptions;
|
|
32
|
+
}): ChildProcess;
|
|
33
|
+
export declare function waitForPSQLExit(psql: EventEmitter): Promise<void>;
|
|
34
|
+
export declare const trapAndForwardSignalsToChildProcess: (childProcess: ChildProcess) => () => void;
|
|
35
|
+
export declare function consumeStream(inputStream: Stream): Promise<unknown>;
|
|
36
|
+
export declare function runWithTunnel(db: ConnectionDetails, tunnelConfig: TunnelConfig, options: Parameters<typeof execPSQL>[0]): Promise<string>;
|
|
37
|
+
export declare class Tunnel {
|
|
38
|
+
private readonly bastionTunnel;
|
|
39
|
+
private readonly events;
|
|
40
|
+
constructor(bastionTunnel: Server);
|
|
41
|
+
waitForClose(): Promise<void>;
|
|
42
|
+
close(): void;
|
|
43
|
+
static connect(db: ConnectionDetails, tunnelConfig: TunnelConfig): Promise<Tunnel>;
|
|
44
|
+
}
|
|
45
|
+
export declare function fetchVersion(db: Parameters<typeof exec>[0]): Promise<string | undefined>;
|
|
46
|
+
export declare function exec(db: ConnectionDetails, query: string, cmdArgs?: string[]): Promise<string>;
|
|
47
|
+
export declare function execFile(db: Parameters<typeof getConfigs>[0], file: string): Promise<string>;
|
|
48
|
+
export declare function interactive(db: ReturnType<typeof getConnectionDetails>): Promise<string>;
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interactive = exports.execFile = exports.exec = exports.fetchVersion = exports.Tunnel = exports.runWithTunnel = exports.consumeStream = exports.trapAndForwardSignalsToChildProcess = exports.waitForPSQLExit = exports.execPSQL = exports.psqlInteractiveOptions = exports.psqlFileOptions = exports.psqlQueryOptions = void 0;
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const debug_1 = require("debug");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
const node_events_1 = require("node:events");
|
|
9
|
+
const path = require("node:path");
|
|
10
|
+
const node_stream_1 = require("node:stream");
|
|
11
|
+
const promises_1 = require("node:stream/promises");
|
|
12
|
+
const bastion_1 = require("./bastion");
|
|
13
|
+
const pgDebug = (0, debug_1.default)('pg');
|
|
14
|
+
function psqlQueryOptions(query, dbEnv, cmdArgs = []) {
|
|
15
|
+
pgDebug('Running query: %s', query.trim());
|
|
16
|
+
const psqlArgs = ['-c', query, '--set', 'sslmode=require', ...cmdArgs];
|
|
17
|
+
const childProcessOptions = {
|
|
18
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
dbEnv,
|
|
22
|
+
psqlArgs,
|
|
23
|
+
childProcessOptions,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.psqlQueryOptions = psqlQueryOptions;
|
|
27
|
+
function psqlFileOptions(file, dbEnv) {
|
|
28
|
+
pgDebug('Running sql file: %s', file.trim());
|
|
29
|
+
const childProcessOptions = {
|
|
30
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
31
|
+
};
|
|
32
|
+
const psqlArgs = ['-f', file, '--set', 'sslmode=require'];
|
|
33
|
+
return {
|
|
34
|
+
dbEnv,
|
|
35
|
+
psqlArgs,
|
|
36
|
+
childProcessOptions,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
exports.psqlFileOptions = psqlFileOptions;
|
|
40
|
+
function psqlInteractiveOptions(prompt, dbEnv) {
|
|
41
|
+
let psqlArgs = ['--set', `PROMPT1=${prompt}`, '--set', `PROMPT2=${prompt}`];
|
|
42
|
+
const psqlHistoryPath = process.env.HEROKU_PSQL_HISTORY;
|
|
43
|
+
if (psqlHistoryPath) {
|
|
44
|
+
if (fs.existsSync(psqlHistoryPath) && fs.statSync(psqlHistoryPath).isDirectory()) {
|
|
45
|
+
const appLogFile = `${psqlHistoryPath}/${prompt.split(':')[0]}`;
|
|
46
|
+
pgDebug('Logging psql history to %s', appLogFile);
|
|
47
|
+
psqlArgs = psqlArgs.concat(['--set', `HISTFILE=${appLogFile}`]);
|
|
48
|
+
}
|
|
49
|
+
else if (fs.existsSync(path.dirname(psqlHistoryPath))) {
|
|
50
|
+
pgDebug('Logging psql history to %s', psqlHistoryPath);
|
|
51
|
+
psqlArgs = psqlArgs.concat(['--set', `HISTFILE=${psqlHistoryPath}`]);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
core_1.ux.warn(`HEROKU_PSQL_HISTORY is set but is not a valid path (${psqlHistoryPath})`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
psqlArgs = psqlArgs.concat(['--set', 'sslmode=require']);
|
|
58
|
+
const childProcessOptions = {
|
|
59
|
+
stdio: 'inherit',
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
dbEnv,
|
|
63
|
+
psqlArgs,
|
|
64
|
+
childProcessOptions,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
exports.psqlInteractiveOptions = psqlInteractiveOptions;
|
|
68
|
+
function execPSQL({ dbEnv, psqlArgs, childProcessOptions }) {
|
|
69
|
+
const options = Object.assign({ env: dbEnv }, childProcessOptions);
|
|
70
|
+
pgDebug('opening psql process');
|
|
71
|
+
const psql = (0, child_process_1.spawn)('psql', psqlArgs, options);
|
|
72
|
+
psql.once('spawn', () => pgDebug('psql process spawned'));
|
|
73
|
+
return psql;
|
|
74
|
+
}
|
|
75
|
+
exports.execPSQL = execPSQL;
|
|
76
|
+
async function waitForPSQLExit(psql) {
|
|
77
|
+
let errorToThrow = null;
|
|
78
|
+
try {
|
|
79
|
+
const [exitCode] = await (0, node_events_1.once)(psql, 'close');
|
|
80
|
+
pgDebug(`psql exited with code ${exitCode}`);
|
|
81
|
+
if (exitCode > 0) {
|
|
82
|
+
errorToThrow = new Error(`psql exited with code ${exitCode}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
pgDebug('psql process error', error);
|
|
87
|
+
const { code } = error;
|
|
88
|
+
if (code === 'ENOENT') {
|
|
89
|
+
errorToThrow = new Error('The local psql command could not be located. For help installing psql, see https://devcenter.heroku.com/articles/heroku-postgresql#local-setup');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (errorToThrow) {
|
|
93
|
+
throw errorToThrow;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.waitForPSQLExit = waitForPSQLExit;
|
|
97
|
+
// According to node.js docs, sending a kill to a process won't cause an error
|
|
98
|
+
// but could have unintended consequences if the PID gets reassigned:
|
|
99
|
+
// https://nodejs.org/docs/latest-v14.x/api/child_process.html#child_process_subprocess_kill_signal
|
|
100
|
+
// To be on the safe side, check if the process was already killed before sending the signal
|
|
101
|
+
function kill(childProcess, signal) {
|
|
102
|
+
if (!childProcess.killed) {
|
|
103
|
+
pgDebug('killing psql child process');
|
|
104
|
+
childProcess.kill(signal);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// trap SIGINT so that ctrl+c can be used by psql without killing the
|
|
108
|
+
// parent node process.
|
|
109
|
+
// you can use ctrl+c in psql to kill running queries
|
|
110
|
+
// while keeping the psql process open.
|
|
111
|
+
// This code is to stop the parent node process (heroku CLI)
|
|
112
|
+
// from exiting. If the parent Heroku CLI node process exits, then psql will exit as it
|
|
113
|
+
// is a child process of the Heroku CLI node process.
|
|
114
|
+
const trapAndForwardSignalsToChildProcess = (childProcess) => {
|
|
115
|
+
const signalsToTrap = ['SIGINT'];
|
|
116
|
+
const signalTraps = signalsToTrap.map(signal => {
|
|
117
|
+
process.removeAllListeners(signal);
|
|
118
|
+
const listener = () => kill(childProcess, signal);
|
|
119
|
+
process.on(signal, listener);
|
|
120
|
+
return [signal, listener];
|
|
121
|
+
});
|
|
122
|
+
// restores the built-in node ctrl+c and other handlers
|
|
123
|
+
return () => {
|
|
124
|
+
signalTraps.forEach(([signal, listener]) => {
|
|
125
|
+
process.removeListener(signal, listener);
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
exports.trapAndForwardSignalsToChildProcess = trapAndForwardSignalsToChildProcess;
|
|
130
|
+
function consumeStream(inputStream) {
|
|
131
|
+
let result = '';
|
|
132
|
+
const throughStream = new node_stream_1.Stream.PassThrough();
|
|
133
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
134
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
135
|
+
try {
|
|
136
|
+
await (0, promises_1.finished)(throughStream);
|
|
137
|
+
resolve(result);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
reject(error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// eslint-disable-next-line no-return-assign
|
|
144
|
+
throughStream.on('data', chunk => result += chunk.toString());
|
|
145
|
+
inputStream.pipe(throughStream);
|
|
146
|
+
return promise;
|
|
147
|
+
}
|
|
148
|
+
exports.consumeStream = consumeStream;
|
|
149
|
+
async function runWithTunnel(db, tunnelConfig, options) {
|
|
150
|
+
const tunnel = await Tunnel.connect(db, tunnelConfig);
|
|
151
|
+
pgDebug('after create tunnel');
|
|
152
|
+
const psql = execPSQL(options);
|
|
153
|
+
// interactive opens with stdio: 'inherit'
|
|
154
|
+
// which gives the child process the same stdin,stdout,stderr of the node process (global `process`)
|
|
155
|
+
// https://nodejs.org/api/child_process.html#child_process_options_stdio
|
|
156
|
+
// psql.stdout will be null in this case
|
|
157
|
+
// return a string for consistency but ideally we should return the child process from this function
|
|
158
|
+
// and let the caller decide what to do with stdin/stdout/stderr
|
|
159
|
+
const stdoutPromise = psql.stdout ? consumeStream(psql.stdout) : Promise.resolve('');
|
|
160
|
+
const cleanupSignalTraps = (0, exports.trapAndForwardSignalsToChildProcess)(psql);
|
|
161
|
+
try {
|
|
162
|
+
pgDebug('waiting for psql or tunnel to exit');
|
|
163
|
+
// wait for either psql or tunnel to exit;
|
|
164
|
+
// the important bit is that we ensure both processes are
|
|
165
|
+
// always cleaned up in the `finally` block below
|
|
166
|
+
await Promise.race([
|
|
167
|
+
waitForPSQLExit(psql),
|
|
168
|
+
tunnel.waitForClose(),
|
|
169
|
+
]);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
pgDebug('wait for psql or tunnel error', error);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
pgDebug('begin tunnel cleanup');
|
|
177
|
+
cleanupSignalTraps();
|
|
178
|
+
tunnel.close();
|
|
179
|
+
kill(psql, 'SIGKILL');
|
|
180
|
+
pgDebug('end tunnel cleanup');
|
|
181
|
+
}
|
|
182
|
+
return stdoutPromise;
|
|
183
|
+
}
|
|
184
|
+
exports.runWithTunnel = runWithTunnel;
|
|
185
|
+
// a small wrapper around tunnel-ssh
|
|
186
|
+
// so that other code doesn't have to worry about
|
|
187
|
+
// whether there is or is not a tunnel
|
|
188
|
+
class Tunnel {
|
|
189
|
+
constructor(bastionTunnel) {
|
|
190
|
+
this.bastionTunnel = bastionTunnel;
|
|
191
|
+
this.events = new node_events_1.EventEmitter();
|
|
192
|
+
}
|
|
193
|
+
async waitForClose() {
|
|
194
|
+
if (this.bastionTunnel) {
|
|
195
|
+
try {
|
|
196
|
+
pgDebug('wait for tunnel close');
|
|
197
|
+
await (0, node_events_1.once)(this.bastionTunnel, 'close');
|
|
198
|
+
pgDebug('tunnel closed');
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
pgDebug('tunnel close error', error);
|
|
202
|
+
throw new Error('Secure tunnel to your database failed');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
pgDebug('no bastion required; waiting for fake close event');
|
|
207
|
+
await (0, node_events_1.once)(this.events, 'close');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
close() {
|
|
211
|
+
if (this.bastionTunnel) {
|
|
212
|
+
pgDebug('close tunnel');
|
|
213
|
+
this.bastionTunnel.close();
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
pgDebug('no tunnel necessary; sending fake close event');
|
|
217
|
+
this.events.emit('close', 0);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
static async connect(db, tunnelConfig) {
|
|
221
|
+
const tunnel = await (0, bastion_1.sshTunnel)(db, tunnelConfig);
|
|
222
|
+
return new Tunnel(tunnel);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.Tunnel = Tunnel;
|
|
226
|
+
async function fetchVersion(db) {
|
|
227
|
+
var _a;
|
|
228
|
+
const output = await exec(db, 'SHOW server_version', ['-X', '-q']);
|
|
229
|
+
return (_a = output.match(/[0-9]{1,}\.[0-9]{1,}/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
230
|
+
}
|
|
231
|
+
exports.fetchVersion = fetchVersion;
|
|
232
|
+
async function exec(db, query, cmdArgs = []) {
|
|
233
|
+
const configs = (0, bastion_1.getConfigs)(db);
|
|
234
|
+
const options = psqlQueryOptions(query, configs.dbEnv, cmdArgs);
|
|
235
|
+
return runWithTunnel(db, configs.dbTunnelConfig, options);
|
|
236
|
+
}
|
|
237
|
+
exports.exec = exec;
|
|
238
|
+
async function execFile(db, file) {
|
|
239
|
+
const configs = (0, bastion_1.getConfigs)(db);
|
|
240
|
+
const options = psqlFileOptions(file, configs.dbEnv);
|
|
241
|
+
return runWithTunnel(db, configs.dbTunnelConfig, options);
|
|
242
|
+
}
|
|
243
|
+
exports.execFile = execFile;
|
|
244
|
+
async function interactive(db) {
|
|
245
|
+
const name = db.attachment.name;
|
|
246
|
+
const prompt = `${db.attachment.app.name}::${name}%R%# `;
|
|
247
|
+
const configs = (0, bastion_1.getConfigs)(db);
|
|
248
|
+
configs.dbEnv.PGAPPNAME = 'psql interactive'; // default was 'psql non-interactive`
|
|
249
|
+
const options = psqlInteractiveOptions(prompt, configs.dbEnv);
|
|
250
|
+
return runWithTunnel(db, configs.dbTunnelConfig, options);
|
|
251
|
+
}
|
|
252
|
+
exports.interactive = interactive;
|