heroku 11.10.0 → 12.0.0-alpha.0
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/CHANGELOG.md +214 -0
- package/dist/commands/accounts/add.js +3 -1
- package/dist/commands/addons/attach.d.ts +2 -1
- package/dist/commands/addons/attach.js +13 -7
- package/dist/commands/addons/create.js +1 -1
- package/dist/commands/addons/destroy.d.ts +3 -1
- package/dist/commands/addons/destroy.js +55 -5
- package/dist/commands/addons/detach.js +7 -5
- package/dist/commands/addons/docs.d.ts +1 -1
- package/dist/commands/addons/docs.js +6 -4
- package/dist/commands/addons/index.js +23 -16
- package/dist/commands/addons/info.js +11 -11
- package/dist/commands/addons/open.js +48 -7
- package/dist/commands/addons/plans.js +9 -6
- package/dist/commands/addons/rename.js +4 -2
- package/dist/commands/addons/services.js +3 -1
- package/dist/commands/addons/upgrade.d.ts +7 -3
- package/dist/commands/addons/upgrade.js +35 -48
- package/dist/commands/addons/wait.d.ts +6 -1
- package/dist/commands/addons/wait.js +10 -7
- package/dist/commands/apps/create.d.ts +7 -3
- package/dist/commands/apps/create.js +26 -58
- package/dist/commands/apps/destroy.d.ts +1 -1
- package/dist/commands/apps/destroy.js +6 -2
- package/dist/commands/apps/diff.d.ts +2 -1
- package/dist/commands/apps/diff.js +6 -99
- package/dist/commands/apps/errors.js +16 -15
- package/dist/commands/apps/index.js +21 -18
- package/dist/commands/apps/info.js +21 -34
- package/dist/commands/apps/open.d.ts +1 -1
- package/dist/commands/apps/open.js +5 -2
- package/dist/commands/apps/rename.js +3 -2
- package/dist/commands/apps/stacks/set.js +3 -3
- package/dist/commands/apps/transfer.d.ts +2 -2
- package/dist/commands/apps/transfer.js +18 -15
- package/dist/commands/auth/2fa/index.d.ts +1 -1
- package/dist/commands/auth/2fa/index.js +4 -1
- package/dist/commands/auth/login.js +3 -1
- package/dist/commands/auth/token.d.ts +1 -1
- package/dist/commands/auth/token.js +6 -3
- package/dist/commands/auth/whoami.d.ts +2 -1
- package/dist/commands/auth/whoami.js +4 -1
- package/dist/commands/authorizations/create.js +7 -7
- package/dist/commands/authorizations/index.js +3 -1
- package/dist/commands/authorizations/info.js +3 -1
- package/dist/commands/authorizations/revoke.js +3 -1
- package/dist/commands/authorizations/rotate.js +3 -1
- package/dist/commands/authorizations/update.js +5 -5
- package/dist/commands/certs/add.d.ts +2 -4
- package/dist/commands/certs/add.js +32 -59
- package/dist/commands/certs/auto/disable.d.ts +2 -1
- package/dist/commands/certs/auto/disable.js +4 -1
- package/dist/commands/certs/auto/enable.d.ts +2 -1
- package/dist/commands/certs/auto/enable.js +29 -6
- package/dist/commands/certs/auto/index.d.ts +2 -1
- package/dist/commands/certs/auto/index.js +17 -7
- package/dist/commands/certs/auto/refresh.d.ts +2 -1
- package/dist/commands/certs/auto/refresh.js +4 -1
- package/dist/commands/certs/generate.d.ts +1 -1
- package/dist/commands/certs/generate.js +4 -1
- package/dist/commands/certs/index.d.ts +1 -1
- package/dist/commands/certs/index.js +6 -3
- package/dist/commands/certs/info.d.ts +2 -1
- package/dist/commands/certs/info.js +6 -3
- package/dist/commands/certs/remove.d.ts +2 -1
- package/dist/commands/certs/remove.js +5 -2
- package/dist/commands/certs/update.d.ts +2 -1
- package/dist/commands/certs/update.js +8 -7
- package/dist/commands/config/edit.js +11 -11
- package/dist/commands/config/get.js +3 -1
- package/dist/commands/config/index.js +3 -1
- package/dist/commands/config/set.js +16 -11
- package/dist/commands/config/unset.js +14 -9
- package/dist/commands/container/pull.js +4 -2
- package/dist/commands/container/push.js +4 -2
- package/dist/commands/container/release.js +7 -17
- package/dist/commands/container/rm.js +14 -11
- package/dist/commands/container/run.js +4 -2
- package/dist/commands/dashboard.d.ts +14 -1
- package/dist/commands/dashboard.js +32 -29
- package/dist/commands/data/maintenances/index.d.ts +2 -2
- package/dist/commands/data/maintenances/index.js +6 -5
- package/dist/commands/data/maintenances/info.d.ts +6 -7
- package/dist/commands/data/maintenances/info.js +20 -19
- package/dist/commands/data/maintenances/run.js +4 -1
- package/dist/commands/data/maintenances/schedule.d.ts +5 -4
- package/dist/commands/data/maintenances/schedule.js +12 -16
- package/dist/commands/data/maintenances/wait.js +4 -1
- package/dist/commands/data/maintenances/window/index.d.ts +2 -2
- package/dist/commands/data/maintenances/window/index.js +5 -4
- package/dist/commands/data/maintenances/window/update.d.ts +2 -2
- package/dist/commands/data/maintenances/window/update.js +7 -9
- package/dist/commands/data/pg/create.js +1 -1
- package/dist/commands/data/pg/fork.js +1 -1
- package/dist/commands/data/pg/migrate.js +1 -1
- package/dist/commands/domains/add.d.ts +2 -2
- package/dist/commands/domains/add.js +35 -49
- package/dist/commands/domains/clear.js +4 -5
- package/dist/commands/domains/index.js +3 -2
- package/dist/commands/domains/info.js +3 -1
- package/dist/commands/domains/remove.js +3 -1
- package/dist/commands/domains/update.js +3 -3
- package/dist/commands/domains/wait.js +12 -13
- package/dist/commands/features/disable.js +4 -4
- package/dist/commands/features/enable.js +4 -4
- package/dist/commands/features/index.js +3 -1
- package/dist/commands/features/info.js +3 -1
- package/dist/commands/git/clone.js +3 -1
- package/dist/commands/git/remote.js +3 -1
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +4 -5
- package/dist/commands/maintenance/index.js +3 -2
- package/dist/commands/maintenance/off.js +4 -1
- package/dist/commands/maintenance/on.js +4 -1
- package/dist/commands/pg/backups/index.js +5 -2
- package/dist/commands/pg/credentials.d.ts +3 -3
- package/dist/commands/pg/credentials.js +4 -6
- package/dist/commands/pg/info.js +4 -4
- package/dist/commands/pg/long-running-queries.js +5 -0
- package/dist/commands/pg/upgrade/cancel.js +12 -5
- package/dist/commands/pg/upgrade/dryrun.js +12 -6
- package/dist/commands/pg/upgrade/prepare.js +12 -6
- package/dist/commands/pg/upgrade/run.js +8 -7
- package/dist/commands/pg/upgrade/wait.js +13 -7
- package/dist/commands/pipelines/create.js +17 -8
- package/dist/commands/pipelines/destroy.js +3 -2
- package/dist/commands/pipelines/diff.js +5 -2
- package/dist/commands/pipelines/index.js +3 -1
- package/dist/commands/pipelines/info.js +4 -2
- package/dist/commands/pipelines/promote.d.ts +2 -1
- package/dist/commands/pipelines/promote.js +30 -107
- package/dist/commands/pipelines/transfer.js +5 -2
- package/dist/commands/pipelines/update.js +5 -4
- package/dist/commands/ps/index.js +26 -20
- package/dist/commands/ps/restart.js +9 -15
- package/dist/commands/ps/scale.js +15 -25
- package/dist/commands/redis/cli.js +10 -13
- package/dist/commands/redis/credentials.js +6 -4
- package/dist/commands/redis/info.js +50 -2
- package/dist/commands/redis/keyspace-notifications.js +6 -5
- package/dist/commands/redis/maxmemory.js +5 -4
- package/dist/commands/redis/promote.js +18 -16
- package/dist/commands/redis/stats-reset.js +6 -6
- package/dist/commands/redis/timeout.js +5 -4
- package/dist/commands/redis/upgrade.js +5 -4
- package/dist/commands/redis/wait.js +22 -37
- package/dist/commands/regions.d.ts +1 -1
- package/dist/commands/regions.js +4 -1
- package/dist/commands/releases/index.js +20 -8
- package/dist/commands/releases/info.js +4 -2
- package/dist/commands/releases/output.js +3 -1
- package/dist/commands/releases/retry.js +7 -7
- package/dist/commands/releases/rollback.js +4 -9
- package/dist/commands/reviewapps/create.js +0 -2
- package/dist/commands/reviewapps/disable.d.ts +1 -1
- package/dist/commands/reviewapps/disable.js +21 -30
- package/dist/commands/reviewapps/enable.d.ts +1 -1
- package/dist/commands/reviewapps/enable.js +21 -30
- package/dist/commands/run/detached.d.ts +2 -0
- package/dist/commands/run/detached.js +3 -3
- package/dist/commands/run/index.js +5 -1
- package/dist/commands/spaces/create.js +14 -17
- package/dist/commands/spaces/destroy.js +5 -3
- package/dist/commands/spaces/drains/get.js +3 -1
- package/dist/commands/spaces/drains/set.js +4 -5
- package/dist/commands/spaces/hosts.js +3 -3
- package/dist/commands/spaces/index.js +5 -5
- package/dist/commands/spaces/info.js +6 -9
- package/dist/commands/spaces/peerings/accept.js +3 -4
- package/dist/commands/spaces/peerings/destroy.js +3 -1
- package/dist/commands/spaces/peerings/index.js +3 -1
- package/dist/commands/spaces/peerings/info.js +3 -1
- package/dist/commands/spaces/rename.js +3 -1
- package/dist/commands/spaces/topology.js +7 -5
- package/dist/commands/spaces/transfer.js +4 -3
- package/dist/commands/spaces/trusted-ips/add.js +5 -4
- package/dist/commands/spaces/trusted-ips/index.js +3 -1
- package/dist/commands/spaces/trusted-ips/remove.js +9 -8
- package/dist/commands/spaces/vpn/config.js +4 -2
- package/dist/commands/spaces/vpn/connect.js +7 -7
- package/dist/commands/spaces/vpn/connections.d.ts +4 -4
- package/dist/commands/spaces/vpn/connections.js +6 -4
- package/dist/commands/spaces/vpn/destroy.js +3 -1
- package/dist/commands/spaces/vpn/info.js +7 -5
- package/dist/commands/spaces/vpn/update.js +3 -1
- package/dist/commands/spaces/vpn/wait.js +13 -22
- package/dist/commands/status.js +19 -11
- package/dist/commands/telemetry/add.js +5 -10
- package/dist/commands/telemetry/index.d.ts +2 -2
- package/dist/commands/telemetry/index.js +7 -15
- package/dist/commands/telemetry/info.js +4 -6
- package/dist/commands/telemetry/remove.d.ts +0 -2
- package/dist/commands/telemetry/remove.js +6 -25
- package/dist/commands/telemetry/update.js +4 -7
- package/dist/lib/addons/addons-wait.d.ts +48 -1
- package/dist/lib/addons/addons-wait.js +46 -7
- package/dist/lib/addons/create-addon.d.ts +1 -2
- package/dist/lib/addons/create-addon.js +62 -37
- package/dist/lib/analytics-telemetry/backboard-otel-client.js +10 -15
- package/dist/lib/api.d.ts +1 -7
- package/dist/lib/api.js +0 -22
- package/dist/lib/apps/client-options.d.ts +29 -0
- package/dist/lib/apps/client-options.js +30 -0
- package/dist/lib/authorizations/authorizations.d.ts +2 -2
- package/dist/lib/certs/flags.d.ts +4 -3
- package/dist/lib/certs/flags.js +4 -4
- package/dist/lib/container/helpers.d.ts +6 -3
- package/dist/lib/container/helpers.js +15 -11
- package/dist/lib/domains/domains.d.ts +0 -4
- package/dist/lib/domains/domains.js +0 -62
- package/dist/lib/local/load-foreman-procfile.js +1 -1
- package/dist/lib/pg/types.d.ts +0 -9
- package/dist/lib/pipelines/disambiguate.js +4 -3
- package/dist/lib/pipelines/ownership.d.ts +1 -1
- package/dist/lib/pipelines/render-pipeline.d.ts +1 -1
- package/dist/lib/releases/releases.d.ts +8 -6
- package/dist/lib/releases/releases.js +12 -20
- package/dist/lib/run/dyno.d.ts +8 -5
- package/dist/lib/run/dyno.js +47 -53
- package/dist/lib/run/log-displayer.d.ts +2 -16
- package/dist/lib/run/log-displayer.js +47 -125
- package/dist/lib/spaces/peering.d.ts +1 -1
- package/dist/lib/spaces/vpn-connections.d.ts +2 -2
- package/dist/lib/spaces/vpn-connections.js +7 -7
- package/dist/lib/telemetry/util.d.ts +6 -4
- package/dist/lib/telemetry/util.js +3 -11
- package/oclif.manifest.json +2776 -2766
- package/package.json +18 -14
- package/dist/lib/apps/app-transfer.d.ts +0 -10
- package/dist/lib/apps/app-transfer.js +0 -32
- package/dist/lib/certs/domains.d.ts +0 -3
- package/dist/lib/certs/domains.js +0 -27
- package/dist/lib/domains/wait-for-domain.d.ts +0 -3
- package/dist/lib/domains/wait-for-domain.js +0 -14
- package/dist/lib/redis/api.d.ts +0 -65
- package/dist/lib/redis/api.js +0 -116
- package/dist/lib/utils/paginator.d.ts +0 -2
- package/dist/lib/utils/paginator.js +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,220 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
## [12.0.0-alpha.0](https://github.com/heroku/cli/compare/v11.10.0...v12.0.0-alpha.0) (2026-09-10)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* migrate spaces mechanical commands to @heroku/sdk (#3881)
|
|
13
|
+
* spaces:info --json output shape changes. `generation`
|
|
14
|
+
becomes a bare string (was an object {id, name}); the object form is
|
|
15
|
+
preserved under a new `generation_object` key. Additional 3.sdk fields
|
|
16
|
+
(channel_name, features, supported_features, eks_version) may appear.
|
|
17
|
+
No field is removed.
|
|
18
|
+
* **node:** bump baseline to >=22 and bundled Node 24.19.0, retarget CI to [22.x, 24.x] (#3877)
|
|
19
|
+
* exclude backups from long running queries (#3790)
|
|
20
|
+
|
|
21
|
+
* Task 9: refactor(spaces:info)!: drop 3.fir override for 3.sdk default ([07c4253](https://github.com/heroku/cli/commit/07c4253a9f80ba6a885845eb33f5dfb879d58b1c))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
* exclude backups from long running queries ([#3790](https://github.com/heroku/cli/issues/3790)) ([0b72bfc](https://github.com/heroku/cli/commit/0b72bfcf7af2e62e5d46fbe9771effc5a793aaa3))
|
|
27
|
+
* heroku sdk integration ps commands ([#3732](https://github.com/heroku/cli/issues/3732)) ([66cd833](https://github.com/heroku/cli/commit/66cd833551e24823b7e403616f3881d1e80528c2)), closes [#3716](https://github.com/heroku/cli/issues/3716) [#3724](https://github.com/heroku/cli/issues/3724) [#3721](https://github.com/heroku/cli/issues/3721) [#3727](https://github.com/heroku/cli/issues/3727)
|
|
28
|
+
* implement sdk pagination in list commands ([#3739](https://github.com/heroku/cli/issues/3739)) ([1272838](https://github.com/heroku/cli/commit/1272838b6f40e5a168c4f5d3341ee6993bf3da6b))
|
|
29
|
+
* integrate @heroku/sdk from github main ([e779292](https://github.com/heroku/cli/commit/e77929202ca76be234f14fabd92f803a6b598870))
|
|
30
|
+
* integrate @heroku/sdk into the CLI (v12 foundation) ([#3803](https://github.com/heroku/cli/issues/3803)) ([192d869](https://github.com/heroku/cli/commit/192d869ea61c9cbb32208b18e9114b5e3cd9c5c6))
|
|
31
|
+
* migrate adapters to sdk ([#3735](https://github.com/heroku/cli/issues/3735)) ([9be770f](https://github.com/heroku/cli/commit/9be770f1ee399894f11b88d1e34eae9bce90a708))
|
|
32
|
+
* migrate run commands to @heroku/sdk ([#3819](https://github.com/heroku/cli/issues/3819)) ([b3bf021](https://github.com/heroku/cli/commit/b3bf0211a333fa25bf2599580dd8e7a9ddfe8ff4))
|
|
33
|
+
* refactor pg commands to leverage sdk ([#3728](https://github.com/heroku/cli/issues/3728)) ([a2dad85](https://github.com/heroku/cli/commit/a2dad85e51c64d69592ffb2bfafa43b1ec3f46d8))
|
|
34
|
+
* use sdk for reviewapps enable and disable commands ([#3897](https://github.com/heroku/cli/issues/3897)) ([9f958c8](https://github.com/heroku/cli/commit/9f958c889691a03530ee25368eb60e1f931193f8))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Bug Fixes
|
|
38
|
+
|
|
39
|
+
* **deps:** bump fast-uri to 3.1.7 (closes 4 advisories) ([#3908](https://github.com/heroku/cli/issues/3908)) ([ffe207d](https://github.com/heroku/cli/commit/ffe207dc6e50fd1d6fcfddf345dde94deb1db5b3)), closes [#391](https://github.com/heroku/cli/issues/391) [#392](https://github.com/heroku/cli/issues/392) [#399](https://github.com/heroku/cli/issues/399) [#400](https://github.com/heroku/cli/issues/400)
|
|
40
|
+
* **deps:** pin @heroku/sdk to ^0.6.1 and resync lockfile ([e789717](https://github.com/heroku/cli/commit/e789717c2b57ea554188352b9c2b668f8e555588))
|
|
41
|
+
* **deps:** regenerate lockfile with CI's npm (10.9.8) to fix ci sync ([81fa93e](https://github.com/heroku/cli/commit/81fa93e9c7818e3b542a18f8bbf3607fea7d5e0a))
|
|
42
|
+
* **deps:** resolve GHSA-73wf-gq98-2v4g in browserslist ([#3909](https://github.com/heroku/cli/issues/3909)) ([fe3cd8b](https://github.com/heroku/cli/commit/fe3cd8b5f88b3b22491319879bdb9568db42486a)), closes [#396](https://github.com/heroku/cli/issues/396)
|
|
43
|
+
* fix misleading config output when 2FA fails ([#3887](https://github.com/heroku/cli/issues/3887)) ([e0fd81f](https://github.com/heroku/cli/commit/e0fd81f0b4bafc5d2919c5e3cf83a39279299b20))
|
|
44
|
+
* parse Procfile process types containing dashes in heroku local ([#3883](https://github.com/heroku/cli/issues/3883)) ([5118f40](https://github.com/heroku/cli/commit/5118f40a868e7c07604e2986efc68ea45e9feaee))
|
|
45
|
+
* resolve test failures from the main-merge ([edf0f5f](https://github.com/heroku/cli/commit/edf0f5f1d3cd4030f3fedafae6cc0e36b5f94396))
|
|
46
|
+
* updates opentelemetry deps to match sentry's peer deps ([#3900](https://github.com/heroku/cli/issues/3900)) ([f66d998](https://github.com/heroku/cli/commit/f66d9984b2dd1b8c0cc6c1e4d0f1819340fc4b63))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Documentation
|
|
50
|
+
|
|
51
|
+
* add SDK command migration guide ([#3811](https://github.com/heroku/cli/issues/3811)) ([e268ed3](https://github.com/heroku/cli/commit/e268ed3cb77957a88983ba507c75ddaec1b419c3))
|
|
52
|
+
* check in-flight branches before SDK command migration ([#3813](https://github.com/heroku/cli/issues/3813)) ([e64d16e](https://github.com/heroku/cli/commit/e64d16e65887883819d6fd53f8d530b87367f2c3))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Miscellaneous Chores
|
|
56
|
+
|
|
57
|
+
* add SDK command migration tooling ([#3723](https://github.com/heroku/cli/issues/3723)) ([5e710b2](https://github.com/heroku/cli/commit/5e710b288f2fbc756f7944293167cf29f84f4a4f))
|
|
58
|
+
* add setup-node to pack-upload and release-homebrew workflows ([#3879](https://github.com/heroku/cli/issues/3879)) ([d3150a2](https://github.com/heroku/cli/commit/d3150a241a037481199386b6d4a0a34f3e69d53f))
|
|
59
|
+
* fix eslint errors in spaces SDK migration ([f9251fb](https://github.com/heroku/cli/commit/f9251fb459a4996297322dcb59a83fd8d64eedf9))
|
|
60
|
+
* merge main into feat/heroku-sdk-integration ([6c3fe9b](https://github.com/heroku/cli/commit/6c3fe9b6ebdf72ab7e3b65b8d614dc4030c04b58))
|
|
61
|
+
* merge updates from 'main' branch back into the long-lived branch (W-23866240) ([#3868](https://github.com/heroku/cli/issues/3868)) ([a55ad1a](https://github.com/heroku/cli/commit/a55ad1a1394ee051619014b44c039a4bf0e02412))
|
|
62
|
+
* merge updates from 'main' into v12.0.0 (W-23971696) ([#3913](https://github.com/heroku/cli/issues/3913)) ([e360a72](https://github.com/heroku/cli/commit/e360a72e9385fa9f33175dbe1afdfbf8faadb3c3))
|
|
63
|
+
* migrate to published @heroku/sdk and @heroku/types packages ([#3745](https://github.com/heroku/cli/issues/3745)) ([4b248bc](https://github.com/heroku/cli/commit/4b248bcffcb61097f683bf150448bcb93ee18ff0))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Code Refactoring
|
|
67
|
+
|
|
68
|
+
* adopt heroku/sdk in domains topic ([#3812](https://github.com/heroku/cli/issues/3812)) ([471ac62](https://github.com/heroku/cli/commit/471ac62ed6a455b903edc4bd8f2e1579eaaf055e))
|
|
69
|
+
* **config:** use @heroku/sdk ([#3893](https://github.com/heroku/cli/issues/3893)) ([7309f0f](https://github.com/heroku/cli/commit/7309f0f4205f364a63821d663771ed6e8defe929))
|
|
70
|
+
* drop redundant spaces:hosts 3.dogwood override for 3.sdk default ([5436b6a](https://github.com/heroku/cli/commit/5436b6a22cdcdc9d1803780b9be6f4406a3720b6))
|
|
71
|
+
* **features:** use @heroku/sdk ([#3890](https://github.com/heroku/cli/issues/3890)) ([0069cea](https://github.com/heroku/cli/commit/0069cea0cb350bd8d6b87d591085cb8387f2a6c7))
|
|
72
|
+
* **git:** use @heroku/sdk ([#3889](https://github.com/heroku/cli/issues/3889)) ([48a2fa8](https://github.com/heroku/cli/commit/48a2fa857b7b16c1b620a9a2524ee92857b53fc2))
|
|
73
|
+
* migrate LogDisplayer to @heroku/sdk streamLogs ([#3722](https://github.com/heroku/cli/issues/3722)) ([3b54ace](https://github.com/heroku/cli/commit/3b54ace5cff1068de3aab50d8c5ae00ddd8e437a)), closes [heroku/heroku-sdk#28](https://github.com/heroku/heroku-sdk/issues/28)
|
|
74
|
+
* migrate spaces mechanical commands to @heroku/sdk ([#3881](https://github.com/heroku/cli/issues/3881)) ([4914448](https://github.com/heroku/cli/commit/49144489df3c3bc1cd0fcf7780800d69b4a7af63))
|
|
75
|
+
* **releases:** use @heroku/sdk ([#3888](https://github.com/heroku/cli/issues/3888)) ([a645c81](https://github.com/heroku/cli/commit/a645c81fff4de8089b8e05459ab85a948e35cefd))
|
|
76
|
+
* **run:** use SDK waitForInfo for the post-creation 404 race ([#3746](https://github.com/heroku/cli/issues/3746)) ([ee9124e](https://github.com/heroku/cli/commit/ee9124efb235d23b07a92fcd89cbfdc123c4467e)), closes [heroku/heroku-sdk#49](https://github.com/heroku/heroku-sdk/issues/49)
|
|
77
|
+
* **spaces:vpn:** use @heroku/sdk ([#3882](https://github.com/heroku/cli/issues/3882)) ([8f91994](https://github.com/heroku/cli/commit/8f91994fd0b9d93e10558fab1fde1f980338d32f))
|
|
78
|
+
* **spaces:** adopt @heroku/types 4.6.0 and drop redundant create casts ([45fd0a8](https://github.com/heroku/cli/commit/45fd0a87c6c7f7b8966d71974eeac2cfdba27023))
|
|
79
|
+
* **spaces:** adopt @heroku/types 4.6.0 and remove redundant space casts ([#3884](https://github.com/heroku/cli/issues/3884)) ([d002a7f](https://github.com/heroku/cli/commit/d002a7f12f16ff50239e3528d39f411be25e2f15))
|
|
80
|
+
* **status:** use @heroku/heroku-fetch instead of @heroku/http-call ([#3917](https://github.com/heroku/cli/issues/3917)) ([895cb7f](https://github.com/heroku/cli/commit/895cb7fb3dc020bca11a1a54972e4ea5e7740763))
|
|
81
|
+
* update container:rm message ([#3851](https://github.com/heroku/cli/issues/3851)) ([4c44655](https://github.com/heroku/cli/commit/4c446552b9dfe4406b5618f85347a32c973cc78e))
|
|
82
|
+
* update domains:wait message ([#3823](https://github.com/heroku/cli/issues/3823)) ([6a85865](https://github.com/heroku/cli/commit/6a858657a6a4687cd43b23281dd246d7be6e2191))
|
|
83
|
+
* updates apps and apps:create commands to use sdk ([#3720](https://github.com/heroku/cli/issues/3720)) ([47bea82](https://github.com/heroku/cli/commit/47bea828a49309313207cf1c25b8d4be628e51e1))
|
|
84
|
+
* use @heroku/sdk for accounts:add command ([#3814](https://github.com/heroku/cli/issues/3814)) ([5c5d9ef](https://github.com/heroku/cli/commit/5c5d9ef5543f959daa971e8dea07d61e5e0beda8))
|
|
85
|
+
* use @heroku/sdk for addons commands ([#3718](https://github.com/heroku/cli/issues/3718)) ([5407005](https://github.com/heroku/cli/commit/54070054da6dec24c480f8120afd0c67f9b90782)), closes [heroku/sdk#26](https://github.com/heroku/sdk/issues/26) [#3717](https://github.com/heroku/cli/issues/3717) [heroku-sdk#26](https://github.com/heroku/heroku-sdk/issues/26) [heroku-sdk#27](https://github.com/heroku/heroku-sdk/issues/27) [#27](https://github.com/heroku/cli/issues/27)
|
|
86
|
+
* use @heroku/sdk for apps:info command ([#3749](https://github.com/heroku/cli/issues/3749)) ([3ec2f64](https://github.com/heroku/cli/commit/3ec2f64aaa1b1a332d1ce8f40c8db54eb66ba5a1))
|
|
87
|
+
* use @heroku/sdk for apps:rename and apps:stacks:set commands ([#3753](https://github.com/heroku/cli/issues/3753)) ([0d9830d](https://github.com/heroku/cli/commit/0d9830d2db226a865f737a964a58394a6e5d5600))
|
|
88
|
+
* use @heroku/sdk for auth commands ([#3815](https://github.com/heroku/cli/issues/3815)) ([3504145](https://github.com/heroku/cli/commit/3504145f0c45f1f6a8addf4c1163d14b743310e2))
|
|
89
|
+
* use @heroku/sdk for authorizations commands ([#3855](https://github.com/heroku/cli/issues/3855)) ([ff30230](https://github.com/heroku/cli/commit/ff30230a3493d8f7cdd7179d043d00bea641bc11))
|
|
90
|
+
* use @heroku/sdk for container commands ([#3831](https://github.com/heroku/cli/issues/3831)) ([1faf4e0](https://github.com/heroku/cli/commit/1faf4e0cd0a7cc1cdbfba9a28efe7397e5e860e9))
|
|
91
|
+
* use @heroku/sdk for dashboard command ([#3915](https://github.com/heroku/cli/issues/3915)) ([13e590c](https://github.com/heroku/cli/commit/13e590c9259a304f17628ab04b4f61c14603fbef))
|
|
92
|
+
* use @heroku/sdk for maintenance commands ([#3713](https://github.com/heroku/cli/issues/3713)) ([2cdc0fa](https://github.com/heroku/cli/commit/2cdc0faac46977b9c87b0ccf317599ff19e0a41d))
|
|
93
|
+
* use @heroku/sdk for pipelines commands ([#3717](https://github.com/heroku/cli/issues/3717)) ([b15f593](https://github.com/heroku/cli/commit/b15f593ef7c059e29ac8a771b60c9cc18f1bfd69)), closes [#17](https://github.com/heroku/cli/issues/17)
|
|
94
|
+
* use @heroku/sdk for redis commands ([#3829](https://github.com/heroku/cli/issues/3829)) ([68e5ec5](https://github.com/heroku/cli/commit/68e5ec53357178c225b291577a42f8b00779c9f3))
|
|
95
|
+
* use @heroku/sdk for regions command ([#3914](https://github.com/heroku/cli/issues/3914)) ([5ab1cc6](https://github.com/heroku/cli/commit/5ab1cc6caa0ca0a881e72d2dac1b021ceaff3728))
|
|
96
|
+
* use @heroku/sdk for spaces subcommands ([#3876](https://github.com/heroku/cli/issues/3876)) ([86b87c9](https://github.com/heroku/cli/commit/86b87c9b243ab742d5ebab9e2f848443ae492bad))
|
|
97
|
+
* use @heroku/sdk for telemetry commands ([#3818](https://github.com/heroku/cli/issues/3818)) ([e8dcd4d](https://github.com/heroku/cli/commit/e8dcd4dad05089cb02247f693ab4104566495b81))
|
|
98
|
+
* use sdk for addons commands ([#3850](https://github.com/heroku/cli/issues/3850)) ([ce3fa27](https://github.com/heroku/cli/commit/ce3fa27440cc1b8dddd9ff4ce333bbf24b5803de))
|
|
99
|
+
* use sdk for apps commands ([#3862](https://github.com/heroku/cli/issues/3862)) ([1001e1e](https://github.com/heroku/cli/commit/1001e1e2192a26821c6330fc6ae4592c48f8a011))
|
|
100
|
+
* use sdk poller to restore status messages ([#3857](https://github.com/heroku/cli/issues/3857)) ([d247d10](https://github.com/heroku/cli/commit/d247d106301ef7f07414019067a15b21e1db1e8f))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### Tests
|
|
104
|
+
|
|
105
|
+
* **auth/2fa:** stub @heroku/sdk directly, drop nock ([#3822](https://github.com/heroku/cli/issues/3822)) ([a341ed3](https://github.com/heroku/cli/commit/a341ed340c8659e075027fdf0faa20e59e15c8d9))
|
|
106
|
+
* **spaces:** add hyperschema to cspell dictionary ([40389a9](https://github.com/heroku/cli/commit/40389a9b4a4a86f25dbd150461dec963dbea92c9)), closes [#3884](https://github.com/heroku/cli/issues/3884)
|
|
107
|
+
* **spaces:** pin spaces:info --json generation_object shape ([c2a78eb](https://github.com/heroku/cli/commit/c2a78ebdde1efbea4d6f30d7b1a16edc3a297062)), closes [#3881](https://github.com/heroku/cli/issues/3881) [#5](https://github.com/heroku/cli/issues/5)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
### Build System
|
|
111
|
+
|
|
112
|
+
* **node:** bump baseline to >=22 and bundled Node 24.19.0, retarget CI to [22.x, 24.x] ([#3877](https://github.com/heroku/cli/issues/3877)) ([4950341](https://github.com/heroku/cli/commit/4950341abd1b4a3ad6b04c9db753852191ee54d9))
|
|
113
|
+
|
|
114
|
+
## [12.0.0-beta.0](https://github.com/heroku/cli/compare/v11.10.0...v12.0.0-beta.0) (2026-09-10)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
### ⚠ BREAKING CHANGES
|
|
118
|
+
|
|
119
|
+
* migrate spaces mechanical commands to @heroku/sdk (#3881)
|
|
120
|
+
* spaces:info --json output shape changes. `generation`
|
|
121
|
+
becomes a bare string (was an object {id, name}); the object form is
|
|
122
|
+
preserved under a new `generation_object` key. Additional 3.sdk fields
|
|
123
|
+
(channel_name, features, supported_features, eks_version) may appear.
|
|
124
|
+
No field is removed.
|
|
125
|
+
* **node:** bump baseline to >=22 and bundled Node 24.19.0, retarget CI to [22.x, 24.x] (#3877)
|
|
126
|
+
* exclude backups from long running queries (#3790)
|
|
127
|
+
|
|
128
|
+
* Task 9: refactor(spaces:info)!: drop 3.fir override for 3.sdk default ([07c4253](https://github.com/heroku/cli/commit/07c4253a9f80ba6a885845eb33f5dfb879d58b1c))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
### Features
|
|
132
|
+
|
|
133
|
+
* exclude backups from long running queries ([#3790](https://github.com/heroku/cli/issues/3790)) ([0b72bfc](https://github.com/heroku/cli/commit/0b72bfcf7af2e62e5d46fbe9771effc5a793aaa3))
|
|
134
|
+
* heroku sdk integration ps commands ([#3732](https://github.com/heroku/cli/issues/3732)) ([66cd833](https://github.com/heroku/cli/commit/66cd833551e24823b7e403616f3881d1e80528c2)), closes [#3716](https://github.com/heroku/cli/issues/3716) [#3724](https://github.com/heroku/cli/issues/3724) [#3721](https://github.com/heroku/cli/issues/3721) [#3727](https://github.com/heroku/cli/issues/3727)
|
|
135
|
+
* implement sdk pagination in list commands ([#3739](https://github.com/heroku/cli/issues/3739)) ([1272838](https://github.com/heroku/cli/commit/1272838b6f40e5a168c4f5d3341ee6993bf3da6b))
|
|
136
|
+
* integrate @heroku/sdk from github main ([e779292](https://github.com/heroku/cli/commit/e77929202ca76be234f14fabd92f803a6b598870))
|
|
137
|
+
* integrate @heroku/sdk into the CLI (v12 foundation) ([#3803](https://github.com/heroku/cli/issues/3803)) ([192d869](https://github.com/heroku/cli/commit/192d869ea61c9cbb32208b18e9114b5e3cd9c5c6))
|
|
138
|
+
* migrate adapters to sdk ([#3735](https://github.com/heroku/cli/issues/3735)) ([9be770f](https://github.com/heroku/cli/commit/9be770f1ee399894f11b88d1e34eae9bce90a708))
|
|
139
|
+
* migrate run commands to @heroku/sdk ([#3819](https://github.com/heroku/cli/issues/3819)) ([b3bf021](https://github.com/heroku/cli/commit/b3bf0211a333fa25bf2599580dd8e7a9ddfe8ff4))
|
|
140
|
+
* refactor pg commands to leverage sdk ([#3728](https://github.com/heroku/cli/issues/3728)) ([a2dad85](https://github.com/heroku/cli/commit/a2dad85e51c64d69592ffb2bfafa43b1ec3f46d8))
|
|
141
|
+
* use sdk for reviewapps enable and disable commands ([#3897](https://github.com/heroku/cli/issues/3897)) ([9f958c8](https://github.com/heroku/cli/commit/9f958c889691a03530ee25368eb60e1f931193f8))
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
### Bug Fixes
|
|
145
|
+
|
|
146
|
+
* **deps:** bump fast-uri to 3.1.7 (closes 4 advisories) ([#3908](https://github.com/heroku/cli/issues/3908)) ([ffe207d](https://github.com/heroku/cli/commit/ffe207dc6e50fd1d6fcfddf345dde94deb1db5b3)), closes [#391](https://github.com/heroku/cli/issues/391) [#392](https://github.com/heroku/cli/issues/392) [#399](https://github.com/heroku/cli/issues/399) [#400](https://github.com/heroku/cli/issues/400)
|
|
147
|
+
* **deps:** pin @heroku/sdk to ^0.6.1 and resync lockfile ([e789717](https://github.com/heroku/cli/commit/e789717c2b57ea554188352b9c2b668f8e555588))
|
|
148
|
+
* **deps:** regenerate lockfile with CI's npm (10.9.8) to fix ci sync ([81fa93e](https://github.com/heroku/cli/commit/81fa93e9c7818e3b542a18f8bbf3607fea7d5e0a))
|
|
149
|
+
* **deps:** resolve GHSA-73wf-gq98-2v4g in browserslist ([#3909](https://github.com/heroku/cli/issues/3909)) ([fe3cd8b](https://github.com/heroku/cli/commit/fe3cd8b5f88b3b22491319879bdb9568db42486a)), closes [#396](https://github.com/heroku/cli/issues/396)
|
|
150
|
+
* fix misleading config output when 2FA fails ([#3887](https://github.com/heroku/cli/issues/3887)) ([e0fd81f](https://github.com/heroku/cli/commit/e0fd81f0b4bafc5d2919c5e3cf83a39279299b20))
|
|
151
|
+
* parse Procfile process types containing dashes in heroku local ([#3883](https://github.com/heroku/cli/issues/3883)) ([5118f40](https://github.com/heroku/cli/commit/5118f40a868e7c07604e2986efc68ea45e9feaee))
|
|
152
|
+
* resolve test failures from the main-merge ([edf0f5f](https://github.com/heroku/cli/commit/edf0f5f1d3cd4030f3fedafae6cc0e36b5f94396))
|
|
153
|
+
* updates opentelemetry deps to match sentry's peer deps ([#3900](https://github.com/heroku/cli/issues/3900)) ([f66d998](https://github.com/heroku/cli/commit/f66d9984b2dd1b8c0cc6c1e4d0f1819340fc4b63))
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
### Documentation
|
|
157
|
+
|
|
158
|
+
* add SDK command migration guide ([#3811](https://github.com/heroku/cli/issues/3811)) ([e268ed3](https://github.com/heroku/cli/commit/e268ed3cb77957a88983ba507c75ddaec1b419c3))
|
|
159
|
+
* check in-flight branches before SDK command migration ([#3813](https://github.com/heroku/cli/issues/3813)) ([e64d16e](https://github.com/heroku/cli/commit/e64d16e65887883819d6fd53f8d530b87367f2c3))
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
### Miscellaneous Chores
|
|
163
|
+
|
|
164
|
+
* add SDK command migration tooling ([#3723](https://github.com/heroku/cli/issues/3723)) ([5e710b2](https://github.com/heroku/cli/commit/5e710b288f2fbc756f7944293167cf29f84f4a4f))
|
|
165
|
+
* add setup-node to pack-upload and release-homebrew workflows ([#3879](https://github.com/heroku/cli/issues/3879)) ([d3150a2](https://github.com/heroku/cli/commit/d3150a241a037481199386b6d4a0a34f3e69d53f))
|
|
166
|
+
* fix eslint errors in spaces SDK migration ([f9251fb](https://github.com/heroku/cli/commit/f9251fb459a4996297322dcb59a83fd8d64eedf9))
|
|
167
|
+
* merge main into feat/heroku-sdk-integration ([6c3fe9b](https://github.com/heroku/cli/commit/6c3fe9b6ebdf72ab7e3b65b8d614dc4030c04b58))
|
|
168
|
+
* merge updates from 'main' branch back into the long-lived branch (W-23866240) ([#3868](https://github.com/heroku/cli/issues/3868)) ([a55ad1a](https://github.com/heroku/cli/commit/a55ad1a1394ee051619014b44c039a4bf0e02412))
|
|
169
|
+
* merge updates from 'main' into v12.0.0 (W-23971696) ([#3913](https://github.com/heroku/cli/issues/3913)) ([e360a72](https://github.com/heroku/cli/commit/e360a72e9385fa9f33175dbe1afdfbf8faadb3c3))
|
|
170
|
+
* migrate to published @heroku/sdk and @heroku/types packages ([#3745](https://github.com/heroku/cli/issues/3745)) ([4b248bc](https://github.com/heroku/cli/commit/4b248bcffcb61097f683bf150448bcb93ee18ff0))
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
### Code Refactoring
|
|
174
|
+
|
|
175
|
+
* adopt heroku/sdk in domains topic ([#3812](https://github.com/heroku/cli/issues/3812)) ([471ac62](https://github.com/heroku/cli/commit/471ac62ed6a455b903edc4bd8f2e1579eaaf055e))
|
|
176
|
+
* **config:** use @heroku/sdk ([#3893](https://github.com/heroku/cli/issues/3893)) ([7309f0f](https://github.com/heroku/cli/commit/7309f0f4205f364a63821d663771ed6e8defe929))
|
|
177
|
+
* drop redundant spaces:hosts 3.dogwood override for 3.sdk default ([5436b6a](https://github.com/heroku/cli/commit/5436b6a22cdcdc9d1803780b9be6f4406a3720b6))
|
|
178
|
+
* **features:** use @heroku/sdk ([#3890](https://github.com/heroku/cli/issues/3890)) ([0069cea](https://github.com/heroku/cli/commit/0069cea0cb350bd8d6b87d591085cb8387f2a6c7))
|
|
179
|
+
* **git:** use @heroku/sdk ([#3889](https://github.com/heroku/cli/issues/3889)) ([48a2fa8](https://github.com/heroku/cli/commit/48a2fa857b7b16c1b620a9a2524ee92857b53fc2))
|
|
180
|
+
* migrate LogDisplayer to @heroku/sdk streamLogs ([#3722](https://github.com/heroku/cli/issues/3722)) ([3b54ace](https://github.com/heroku/cli/commit/3b54ace5cff1068de3aab50d8c5ae00ddd8e437a)), closes [heroku/heroku-sdk#28](https://github.com/heroku/heroku-sdk/issues/28)
|
|
181
|
+
* migrate spaces mechanical commands to @heroku/sdk ([#3881](https://github.com/heroku/cli/issues/3881)) ([4914448](https://github.com/heroku/cli/commit/49144489df3c3bc1cd0fcf7780800d69b4a7af63))
|
|
182
|
+
* **releases:** use @heroku/sdk ([#3888](https://github.com/heroku/cli/issues/3888)) ([a645c81](https://github.com/heroku/cli/commit/a645c81fff4de8089b8e05459ab85a948e35cefd))
|
|
183
|
+
* **run:** use SDK waitForInfo for the post-creation 404 race ([#3746](https://github.com/heroku/cli/issues/3746)) ([ee9124e](https://github.com/heroku/cli/commit/ee9124efb235d23b07a92fcd89cbfdc123c4467e)), closes [heroku/heroku-sdk#49](https://github.com/heroku/heroku-sdk/issues/49)
|
|
184
|
+
* **spaces:vpn:** use @heroku/sdk ([#3882](https://github.com/heroku/cli/issues/3882)) ([8f91994](https://github.com/heroku/cli/commit/8f91994fd0b9d93e10558fab1fde1f980338d32f))
|
|
185
|
+
* **spaces:** adopt @heroku/types 4.6.0 and drop redundant create casts ([45fd0a8](https://github.com/heroku/cli/commit/45fd0a87c6c7f7b8966d71974eeac2cfdba27023))
|
|
186
|
+
* **spaces:** adopt @heroku/types 4.6.0 and remove redundant space casts ([#3884](https://github.com/heroku/cli/issues/3884)) ([d002a7f](https://github.com/heroku/cli/commit/d002a7f12f16ff50239e3528d39f411be25e2f15))
|
|
187
|
+
* **status:** use @heroku/heroku-fetch instead of @heroku/http-call ([#3917](https://github.com/heroku/cli/issues/3917)) ([895cb7f](https://github.com/heroku/cli/commit/895cb7fb3dc020bca11a1a54972e4ea5e7740763))
|
|
188
|
+
* update container:rm message ([#3851](https://github.com/heroku/cli/issues/3851)) ([4c44655](https://github.com/heroku/cli/commit/4c446552b9dfe4406b5618f85347a32c973cc78e))
|
|
189
|
+
* update domains:wait message ([#3823](https://github.com/heroku/cli/issues/3823)) ([6a85865](https://github.com/heroku/cli/commit/6a858657a6a4687cd43b23281dd246d7be6e2191))
|
|
190
|
+
* updates apps and apps:create commands to use sdk ([#3720](https://github.com/heroku/cli/issues/3720)) ([47bea82](https://github.com/heroku/cli/commit/47bea828a49309313207cf1c25b8d4be628e51e1))
|
|
191
|
+
* use @heroku/sdk for accounts:add command ([#3814](https://github.com/heroku/cli/issues/3814)) ([5c5d9ef](https://github.com/heroku/cli/commit/5c5d9ef5543f959daa971e8dea07d61e5e0beda8))
|
|
192
|
+
* use @heroku/sdk for addons commands ([#3718](https://github.com/heroku/cli/issues/3718)) ([5407005](https://github.com/heroku/cli/commit/54070054da6dec24c480f8120afd0c67f9b90782)), closes [heroku/sdk#26](https://github.com/heroku/sdk/issues/26) [#3717](https://github.com/heroku/cli/issues/3717) [heroku-sdk#26](https://github.com/heroku/heroku-sdk/issues/26) [heroku-sdk#27](https://github.com/heroku/heroku-sdk/issues/27) [#27](https://github.com/heroku/cli/issues/27)
|
|
193
|
+
* use @heroku/sdk for apps:info command ([#3749](https://github.com/heroku/cli/issues/3749)) ([3ec2f64](https://github.com/heroku/cli/commit/3ec2f64aaa1b1a332d1ce8f40c8db54eb66ba5a1))
|
|
194
|
+
* use @heroku/sdk for apps:rename and apps:stacks:set commands ([#3753](https://github.com/heroku/cli/issues/3753)) ([0d9830d](https://github.com/heroku/cli/commit/0d9830d2db226a865f737a964a58394a6e5d5600))
|
|
195
|
+
* use @heroku/sdk for auth commands ([#3815](https://github.com/heroku/cli/issues/3815)) ([3504145](https://github.com/heroku/cli/commit/3504145f0c45f1f6a8addf4c1163d14b743310e2))
|
|
196
|
+
* use @heroku/sdk for authorizations commands ([#3855](https://github.com/heroku/cli/issues/3855)) ([ff30230](https://github.com/heroku/cli/commit/ff30230a3493d8f7cdd7179d043d00bea641bc11))
|
|
197
|
+
* use @heroku/sdk for container commands ([#3831](https://github.com/heroku/cli/issues/3831)) ([1faf4e0](https://github.com/heroku/cli/commit/1faf4e0cd0a7cc1cdbfba9a28efe7397e5e860e9))
|
|
198
|
+
* use @heroku/sdk for dashboard command ([#3915](https://github.com/heroku/cli/issues/3915)) ([13e590c](https://github.com/heroku/cli/commit/13e590c9259a304f17628ab04b4f61c14603fbef))
|
|
199
|
+
* use @heroku/sdk for maintenance commands ([#3713](https://github.com/heroku/cli/issues/3713)) ([2cdc0fa](https://github.com/heroku/cli/commit/2cdc0faac46977b9c87b0ccf317599ff19e0a41d))
|
|
200
|
+
* use @heroku/sdk for pipelines commands ([#3717](https://github.com/heroku/cli/issues/3717)) ([b15f593](https://github.com/heroku/cli/commit/b15f593ef7c059e29ac8a771b60c9cc18f1bfd69)), closes [#17](https://github.com/heroku/cli/issues/17)
|
|
201
|
+
* use @heroku/sdk for redis commands ([#3829](https://github.com/heroku/cli/issues/3829)) ([68e5ec5](https://github.com/heroku/cli/commit/68e5ec53357178c225b291577a42f8b00779c9f3))
|
|
202
|
+
* use @heroku/sdk for regions command ([#3914](https://github.com/heroku/cli/issues/3914)) ([5ab1cc6](https://github.com/heroku/cli/commit/5ab1cc6caa0ca0a881e72d2dac1b021ceaff3728))
|
|
203
|
+
* use @heroku/sdk for spaces subcommands ([#3876](https://github.com/heroku/cli/issues/3876)) ([86b87c9](https://github.com/heroku/cli/commit/86b87c9b243ab742d5ebab9e2f848443ae492bad))
|
|
204
|
+
* use @heroku/sdk for telemetry commands ([#3818](https://github.com/heroku/cli/issues/3818)) ([e8dcd4d](https://github.com/heroku/cli/commit/e8dcd4dad05089cb02247f693ab4104566495b81))
|
|
205
|
+
* use sdk for addons commands ([#3850](https://github.com/heroku/cli/issues/3850)) ([ce3fa27](https://github.com/heroku/cli/commit/ce3fa27440cc1b8dddd9ff4ce333bbf24b5803de))
|
|
206
|
+
* use sdk for apps commands ([#3862](https://github.com/heroku/cli/issues/3862)) ([1001e1e](https://github.com/heroku/cli/commit/1001e1e2192a26821c6330fc6ae4592c48f8a011))
|
|
207
|
+
* use sdk poller to restore status messages ([#3857](https://github.com/heroku/cli/issues/3857)) ([d247d10](https://github.com/heroku/cli/commit/d247d106301ef7f07414019067a15b21e1db1e8f))
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
### Tests
|
|
211
|
+
|
|
212
|
+
* **auth/2fa:** stub @heroku/sdk directly, drop nock ([#3822](https://github.com/heroku/cli/issues/3822)) ([a341ed3](https://github.com/heroku/cli/commit/a341ed340c8659e075027fdf0faa20e59e15c8d9))
|
|
213
|
+
* **spaces:** add hyperschema to cspell dictionary ([40389a9](https://github.com/heroku/cli/commit/40389a9b4a4a86f25dbd150461dec963dbea92c9)), closes [#3884](https://github.com/heroku/cli/issues/3884)
|
|
214
|
+
* **spaces:** pin spaces:info --json generation_object shape ([c2a78eb](https://github.com/heroku/cli/commit/c2a78ebdde1efbea4d6f30d7b1a16edc3a297062)), closes [#3881](https://github.com/heroku/cli/issues/3881) [#5](https://github.com/heroku/cli/issues/5)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
### Build System
|
|
218
|
+
|
|
219
|
+
* **node:** bump baseline to >=22 and bundled Node 24.19.0, retarget CI to [22.x, 24.x] ([#3877](https://github.com/heroku/cli/issues/3877)) ([4950341](https://github.com/heroku/cli/commit/4950341abd1b4a3ad6b04c9db753852191ee54d9))
|
|
220
|
+
|
|
7
221
|
## [11.10.0](https://github.com/heroku/cli/compare/v11.9.0...v11.10.0) (2026-08-18)
|
|
8
222
|
|
|
9
223
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from '@heroku-cli/command';
|
|
2
2
|
import * as color from '@heroku/heroku-cli-util/color';
|
|
3
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
3
4
|
import { Args, ux } from '@oclif/core';
|
|
4
5
|
import AccountsModule from '../../lib/accounts/accounts.js';
|
|
5
6
|
export default class Add extends Command {
|
|
@@ -9,13 +10,14 @@ export default class Add extends Command {
|
|
|
9
10
|
static description = 'add the current Heroku account to your accounts cache';
|
|
10
11
|
static example = `${color.command('heroku accounts:add my-account')}`;
|
|
11
12
|
async run() {
|
|
13
|
+
const { platform } = new HerokuSDK();
|
|
12
14
|
const { args } = await this.parse(Add);
|
|
13
15
|
const { name } = args;
|
|
14
16
|
const accounts = await AccountsModule.list();
|
|
15
17
|
if (accounts.some(account => account.name === name)) {
|
|
16
18
|
ux.error(`${name} already exists`);
|
|
17
19
|
}
|
|
18
|
-
const
|
|
20
|
+
const account = await platform.account.info();
|
|
19
21
|
const email = account.email;
|
|
20
22
|
const existingAlias = accounts.find(account => account.name && account.username === email);
|
|
21
23
|
if (existingAlias) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AddOnAttachment } from '@heroku/types/3.sdk';
|
|
1
2
|
import { Command } from '@heroku-cli/command';
|
|
2
3
|
export default class Attach extends Command {
|
|
3
4
|
static args: {
|
|
@@ -12,5 +13,5 @@ export default class Attach extends Command {
|
|
|
12
13
|
remote: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
};
|
|
14
15
|
static topic: string;
|
|
15
|
-
run(): Promise<
|
|
16
|
+
run(): Promise<AddOnAttachment>;
|
|
16
17
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Command, flags } from '@heroku-cli/command';
|
|
2
2
|
import * as color from '@heroku/heroku-cli-util/color';
|
|
3
|
+
import { HerokuApiClient } from '@heroku/heroku-fetch';
|
|
4
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
3
5
|
import { Args, ux } from '@oclif/core';
|
|
4
6
|
import { trapConfirmationRequired } from '../../lib/addons/util.js';
|
|
5
7
|
export default class Attach extends Command {
|
|
@@ -18,18 +20,19 @@ export default class Attach extends Command {
|
|
|
18
20
|
async run() {
|
|
19
21
|
const { args, flags } = await this.parse(Attach);
|
|
20
22
|
const { app, as, confirm, credential } = flags;
|
|
21
|
-
const {
|
|
23
|
+
const { platform } = new HerokuSDK();
|
|
24
|
+
const addon = await platform.addOn.info(args.addon_name);
|
|
22
25
|
const createAttachment = async (confirmed) => {
|
|
23
26
|
let namespace;
|
|
24
27
|
if (credential && credential !== 'default') {
|
|
25
28
|
namespace = 'credential:' + credential;
|
|
26
29
|
}
|
|
27
30
|
const body = {
|
|
28
|
-
addon:
|
|
31
|
+
addon: addon.name, app, confirm: confirmed, name: as, namespace,
|
|
29
32
|
};
|
|
30
33
|
try {
|
|
31
34
|
ux.action.start(`Attaching ${credential ? color.name(credential) + ' of ' : ''}${color.datastore(addon.name || '')}${as ? ' as ' + color.attachment(as) : ''} to ${color.app(app)}`);
|
|
32
|
-
const
|
|
35
|
+
const attachment = await platform.addOnAttachment.create(body);
|
|
33
36
|
ux.action.stop();
|
|
34
37
|
return attachment;
|
|
35
38
|
}
|
|
@@ -39,16 +42,19 @@ export default class Attach extends Command {
|
|
|
39
42
|
}
|
|
40
43
|
};
|
|
41
44
|
if (credential && credential !== 'default') {
|
|
42
|
-
const
|
|
45
|
+
const client = new HerokuApiClient();
|
|
46
|
+
const response = await client.get(`/addons/${addon.name}/config/credential:${encodeURIComponent(credential)}`);
|
|
47
|
+
const credentialConfig = await response.json();
|
|
43
48
|
if (credentialConfig.length === 0) {
|
|
44
49
|
throw new Error(`Could not find credential ${color.name(credential)} for database ${color.datastore(addon.name || '')}`);
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
const attachment = await trapConfirmationRequired(app, confirm, (confirmed) => createAttachment(confirmed));
|
|
48
53
|
ux.action.start(`Setting ${color.attachment(attachment.name || '')} config vars and restarting ${color.app(app)}`);
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
const releases = await platform
|
|
55
|
+
.withHeaders({ Range: 'version ..; max=1, order=desc' })
|
|
56
|
+
.release.list(app);
|
|
52
57
|
ux.action.stop(`done, v${releases[0].version}`);
|
|
58
|
+
return attachment;
|
|
53
59
|
}
|
|
54
60
|
}
|
|
@@ -50,7 +50,7 @@ export default class Create extends Command {
|
|
|
50
50
|
const config = parseConfig(argv);
|
|
51
51
|
let addon;
|
|
52
52
|
try {
|
|
53
|
-
addon = await createAddon(
|
|
53
|
+
addon = await createAddon(app, servicePlan, confirm, wait, { as, config, name });
|
|
54
54
|
if (wait) {
|
|
55
55
|
Create.notifier(`heroku addons:create ${addon.name}`, 'Add-on successfully provisioned');
|
|
56
56
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AddOn } from '@heroku/types/3.sdk';
|
|
1
2
|
import { Command } from '@heroku-cli/command';
|
|
2
3
|
export default class Destroy extends Command {
|
|
3
4
|
static args: {
|
|
@@ -16,5 +17,6 @@ export default class Destroy extends Command {
|
|
|
16
17
|
static notifier: (subtitle: string, message: string, success?: boolean) => void;
|
|
17
18
|
static strict: boolean;
|
|
18
19
|
static topic: string;
|
|
19
|
-
run(): Promise<
|
|
20
|
+
run(): Promise<AddOn[]>;
|
|
21
|
+
private toDestroyError;
|
|
20
22
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Command, flags } from '@heroku-cli/command';
|
|
2
2
|
import { color, utils } from '@heroku/heroku-cli-util';
|
|
3
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
4
|
+
import { addOnExtensions } from '@heroku/sdk/extensions/platform';
|
|
5
|
+
import { AddonProvisioningFailedError } from '@heroku/sdk/resources/platform/add-on';
|
|
3
6
|
import { Args } from '@oclif/core';
|
|
7
|
+
import { ux } from '@oclif/core/ux';
|
|
4
8
|
import _ from 'lodash';
|
|
5
|
-
import destroyAddon from '../../lib/addons/destroy-addon.js';
|
|
6
9
|
import ConfirmCommand from '../../lib/confirm-command.js';
|
|
7
10
|
import notify from '../../lib/notify.js';
|
|
8
11
|
export default class Destroy extends Command {
|
|
@@ -27,6 +30,7 @@ export default class Destroy extends Command {
|
|
|
27
30
|
const { app, confirm, wait } = flags;
|
|
28
31
|
const force = flags.force || process.env.HEROKU_FORCE === '1';
|
|
29
32
|
const addonResolver = new utils.AddonResolver(this.heroku);
|
|
33
|
+
const { platform } = new HerokuSDK({ extensions: [addOnExtensions] });
|
|
30
34
|
const addons = await Promise.all(argv.map((name) => addonResolver.resolve(name, app)));
|
|
31
35
|
for (const addon of addons) {
|
|
32
36
|
// prevent deletion of add-on when context.app is set but the addon is attached to a different app
|
|
@@ -35,24 +39,70 @@ export default class Destroy extends Command {
|
|
|
35
39
|
throw new Error(`${color.addon(addon.name ?? '')} is on ${color.app(addonApp ?? '')} not ${color.app(app)}`);
|
|
36
40
|
}
|
|
37
41
|
}
|
|
42
|
+
const destroyed = [];
|
|
38
43
|
for (const addonApps of Object.entries(_.groupBy(addons, 'app.name'))) {
|
|
39
44
|
const currentAddons = addonApps[1];
|
|
40
45
|
const appName = addonApps[0];
|
|
41
46
|
await new ConfirmCommand().confirm(appName, confirm);
|
|
42
47
|
for (const addon of currentAddons) {
|
|
48
|
+
const addonName = addon.name ?? '';
|
|
49
|
+
const appIdentity = addon.app?.name ?? '';
|
|
43
50
|
try {
|
|
44
|
-
|
|
51
|
+
ux.action.start(`Destroying ${color.addon(addonName)} on ${color.app(appIdentity)}`);
|
|
52
|
+
const result = await platform.addOn.destroyAndWait(appIdentity, addonName, {
|
|
53
|
+
force,
|
|
54
|
+
onDeprovisioning() {
|
|
55
|
+
// Two-phase UX: stop the "Destroying … on <app>" spinner as pending,
|
|
56
|
+
// then surface a dedicated wait spinner while the SDK polls.
|
|
57
|
+
ux.action.stop(color.info('pending'));
|
|
58
|
+
ux.stdout(`Waiting for ${color.addon(addonName)}...`);
|
|
59
|
+
ux.action.start(`Destroying ${color.addon(addonName)}`);
|
|
60
|
+
},
|
|
61
|
+
wait,
|
|
62
|
+
});
|
|
63
|
+
const resultState = result.state;
|
|
64
|
+
if (resultState === 'deprovisioning') {
|
|
65
|
+
// Async deprovisioning without --wait: leave the destruction running in the background.
|
|
66
|
+
ux.action.stop(color.info('pending'));
|
|
67
|
+
ux.stdout(`${color.addon(addonName)} is being destroyed in the background. The app will restart when complete...`);
|
|
68
|
+
ux.stdout(`Run ${color.code('heroku addons:info ' + addonName)} to check destruction progress`);
|
|
69
|
+
}
|
|
70
|
+
else if (resultState === 'deprovisioned') {
|
|
71
|
+
ux.action.stop();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// A synchronous delete that settled into an unexpected terminal state.
|
|
75
|
+
ux.action.stop();
|
|
76
|
+
throw new AddonProvisioningFailedError(result);
|
|
77
|
+
}
|
|
45
78
|
if (wait) {
|
|
46
|
-
Destroy.notifier(`heroku addons:destroy ${
|
|
79
|
+
Destroy.notifier(`heroku addons:destroy ${addonName}`, 'Add-on successfully deprovisioned');
|
|
47
80
|
}
|
|
81
|
+
destroyed.push(result);
|
|
48
82
|
}
|
|
49
83
|
catch (error) {
|
|
50
84
|
if (wait) {
|
|
51
|
-
Destroy.notifier(`heroku addons:destroy ${
|
|
85
|
+
Destroy.notifier(`heroku addons:destroy ${addonName}`, 'Add-on failed to deprovision', false);
|
|
52
86
|
}
|
|
53
|
-
throw error;
|
|
87
|
+
throw this.toDestroyError(addon, error);
|
|
54
88
|
}
|
|
55
89
|
}
|
|
56
90
|
}
|
|
91
|
+
return destroyed;
|
|
92
|
+
}
|
|
93
|
+
// The SDK's destroyAndWait surfaces platform/HTTP errors verbatim; the CLI owns the
|
|
94
|
+
// friendly "can't destroy your database" / "add-on was unable to be destroyed" copy.
|
|
95
|
+
toDestroyError(addon, error) {
|
|
96
|
+
const isAdvancedDatabase = utils.pg.isAdvancedDatabase(addon);
|
|
97
|
+
if (error instanceof AddonProvisioningFailedError) {
|
|
98
|
+
const { state } = error.addon;
|
|
99
|
+
return isAdvancedDatabase
|
|
100
|
+
? new Error(`You can't destroy a database with a ${state} status.`)
|
|
101
|
+
: new Error(`The add-on was unable to be destroyed, with status ${state}.`);
|
|
102
|
+
}
|
|
103
|
+
const errorMessage = (error instanceof Error ? error.message : undefined) ?? error;
|
|
104
|
+
return isAdvancedDatabase
|
|
105
|
+
? new Error(`We can't destroy your database due to an error: ${errorMessage}. Try again or open a ticket with Heroku Support: https://help.heroku.com/`)
|
|
106
|
+
: new Error(`The add-on was unable to be destroyed: ${errorMessage}.`);
|
|
57
107
|
}
|
|
58
108
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command, flags } from '@heroku-cli/command';
|
|
2
2
|
import * as color from '@heroku/heroku-cli-util/color';
|
|
3
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
3
4
|
import { Args, ux } from '@oclif/core';
|
|
4
5
|
export default class Detach extends Command {
|
|
5
6
|
static args = {
|
|
@@ -14,14 +15,15 @@ export default class Detach extends Command {
|
|
|
14
15
|
async run() {
|
|
15
16
|
const { args, flags } = await this.parse(Detach);
|
|
16
17
|
const { app } = flags;
|
|
17
|
-
const {
|
|
18
|
+
const { platform } = new HerokuSDK();
|
|
19
|
+
const attachment = await platform.addOnAttachment.infoByApp(app, args.attachment_name);
|
|
18
20
|
ux.action.start(`Detaching ${color.attachment(attachment.name || '')} to ${color.addon(attachment.addon?.name || '')} from ${color.app(app)}`);
|
|
19
|
-
await
|
|
21
|
+
await platform.addOnAttachment.delete(attachment.id);
|
|
20
22
|
ux.action.stop();
|
|
21
23
|
ux.action.start(`Unsetting ${color.attachment(attachment.name || '')} config vars and restarting ${color.app(app)}`);
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
const releases = await platform
|
|
25
|
+
.withHeaders({ Range: 'version ..; max=1, order=desc' })
|
|
26
|
+
.release.list(app);
|
|
25
27
|
ux.action.stop(`done, v${releases[0]?.version || ''}`);
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Command, flags } from '@heroku-cli/command';
|
|
2
2
|
import * as color from '@heroku/heroku-cli-util/color';
|
|
3
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
4
|
+
import { addOnExtensions } from '@heroku/sdk/extensions/platform';
|
|
3
5
|
import { Args, ux } from '@oclif/core';
|
|
4
6
|
import open from 'open';
|
|
5
|
-
import { resolveAddon } from '../../lib/addons/resolve.js';
|
|
6
7
|
export default class Docs extends Command {
|
|
7
8
|
static args = {
|
|
8
9
|
addon: Args.string({ description: 'unique identifier or globally unique name of the add-on', required: true }),
|
|
@@ -18,10 +19,10 @@ export default class Docs extends Command {
|
|
|
18
19
|
async run() {
|
|
19
20
|
const { args, flags } = await this.parse(Docs);
|
|
20
21
|
const { app } = flags;
|
|
22
|
+
const { platform } = new HerokuSDK({ extensions: [addOnExtensions] });
|
|
21
23
|
const id = args.addon.split(':')[0];
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const addon = addonResponse?.body ?? (await resolveAddon(this.heroku, app, id)).addon_service;
|
|
24
|
+
const addonService = await platform.addOnService.info(id).catch(() => null);
|
|
25
|
+
const addon = addonService ?? (await platform.addOn.resolve(id, { appIdentity: app })).addon_service;
|
|
25
26
|
const url = `https://devcenter.heroku.com/articles/${addon.name}`;
|
|
26
27
|
if (flags['show-url']) {
|
|
27
28
|
ux.stdout(url);
|
|
@@ -30,5 +31,6 @@ export default class Docs extends Command {
|
|
|
30
31
|
ux.stdout(`Opening ${color.info(url)}...`);
|
|
31
32
|
await Docs.urlOpener(url);
|
|
32
33
|
}
|
|
34
|
+
return url;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { Command, flags } from '@heroku-cli/command';
|
|
2
2
|
import { color, hux } from '@heroku/heroku-cli-util';
|
|
3
|
+
import { HerokuSDK } from '@heroku/sdk';
|
|
3
4
|
import { ux } from '@oclif/core/ux';
|
|
4
5
|
import _ from 'lodash';
|
|
5
6
|
import { formatPrice, formatState, grandfatheredPrice } from '../../lib/addons/util.js';
|
|
6
7
|
import { huxTableNoWrapOptions } from '../../lib/utils/table-utils.js';
|
|
8
|
+
// The Platform expands nested addon_service and plan when this header is set.
|
|
9
|
+
const ADDON_EXPANSION_HEADERS = {
|
|
10
|
+
Accept: 'application/vnd.heroku+json; version=3.sdk',
|
|
11
|
+
'Accept-Expansion': 'addon_service,plan',
|
|
12
|
+
};
|
|
13
|
+
// SDK resource types use required fields while @heroku-cli/schema uses
|
|
14
|
+
// optional fields for the same shapes. This cast bridges the gap until
|
|
15
|
+
// the codebase fully migrates off @heroku-cli/schema.
|
|
16
|
+
function asSchemaBased(value) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
7
19
|
const topic = 'addons';
|
|
8
20
|
export default class Addons extends Command {
|
|
9
21
|
static description = `Lists your add-ons and attachments.
|
|
@@ -51,43 +63,38 @@ export function renderAttachment(attachment, app, isLast = false) {
|
|
|
51
63
|
return ` ${color.gray(line)} ${attName}`;
|
|
52
64
|
}
|
|
53
65
|
async function addonGetter(api, app) {
|
|
66
|
+
const { platform } = new HerokuSDK();
|
|
67
|
+
// Apply Accept-Expansion only on add-on list calls (the global list
|
|
68
|
+
// endpoint rejects it; the attachments endpoints don't need it).
|
|
69
|
+
const platformWithExpansion = platform.withHeaders(ADDON_EXPANSION_HEADERS);
|
|
54
70
|
let attachmentsResponse = null;
|
|
55
71
|
let addonsResponse;
|
|
56
72
|
if (app) { // don't display attachments globally
|
|
57
|
-
addonsResponse =
|
|
58
|
-
headers: {
|
|
59
|
-
Accept: 'application/vnd.heroku+json; version=3.sdk',
|
|
60
|
-
'Accept-Expansion': 'addon_service,plan',
|
|
61
|
-
},
|
|
62
|
-
});
|
|
73
|
+
addonsResponse = platformWithExpansion.addOn.listByApp(app).then((asSchemaBased));
|
|
63
74
|
const sudoHeaders = JSON.parse(process.env.HEROKU_HEADERS || '{}');
|
|
64
75
|
// eslint-disable-next-line unicorn/prefer-ternary
|
|
65
76
|
if (sudoHeaders['X-Heroku-Sudo'] && !sudoHeaders['X-Heroku-Sudo-User']) {
|
|
66
77
|
// because the root /addon-attachments endpoint won't include relevant
|
|
67
78
|
// attachments when sudo-ing for another app, we will use the more
|
|
68
79
|
// specific API call and sacrifice listing foreign attachments.
|
|
69
|
-
attachmentsResponse =
|
|
80
|
+
attachmentsResponse = platform.addOnAttachment.listByApp(app).then((asSchemaBased));
|
|
70
81
|
}
|
|
71
82
|
else {
|
|
72
83
|
// In order to display all foreign attachments, we'll get out entire
|
|
73
84
|
// attachment list
|
|
74
|
-
attachmentsResponse =
|
|
85
|
+
attachmentsResponse = platform.addOnAttachment.list().then((asSchemaBased));
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
else {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Accept: 'application/vnd.heroku+json; version=3.sdk',
|
|
81
|
-
'Accept-Expansion': 'addon_service,plan',
|
|
82
|
-
},
|
|
83
|
-
});
|
|
89
|
+
// The global /addons endpoint doesn't support Accept-Expansion.
|
|
90
|
+
addonsResponse = platform.addOn.list().then((asSchemaBased));
|
|
84
91
|
}
|
|
85
92
|
// Get addons and attachments in parallel
|
|
86
|
-
const [
|
|
93
|
+
const [addonsRaw, potentialAttachments] = await Promise.all([addonsResponse, attachmentsResponse]);
|
|
87
94
|
function isRelevantToApp(addon) {
|
|
88
95
|
return !app || addon.app?.name === app || _.some(addon.attachments, att => att.app.name === app);
|
|
89
96
|
}
|
|
90
|
-
const groupedAttachments = _.groupBy(potentialAttachments
|
|
97
|
+
const groupedAttachments = _.groupBy(potentialAttachments ?? [], 'addon.id');
|
|
91
98
|
const addons = [];
|
|
92
99
|
addonsRaw.forEach((addon) => {
|
|
93
100
|
addon.attachments = groupedAttachments[addon.id] || [];
|