@heroku/sdk 0.11.1 → 0.11.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.
Files changed (62) hide show
  1. package/dist/core/extensions-proxy.js +51 -1
  2. package/dist/core/with-signal.d.ts +19 -0
  3. package/dist/core/with-signal.js +20 -0
  4. package/dist/resources/data/database.js +19 -6
  5. package/dist/resources/data/internal/resolve-pg-database.js +4 -7
  6. package/dist/resources/data/maintenance.js +4 -1
  7. package/dist/resources/data/postgres-database.js +4 -1
  8. package/dist/resources/data/redis/resolve-by-app.js +2 -1
  9. package/dist/resources/data/redis/wait-for-ready.d.ts +1 -1
  10. package/dist/resources/data/redis/wait-for-ready.js +3 -2
  11. package/dist/resources/data/transfer/capture-and-wait.js +4 -1
  12. package/dist/resources/data/transfer/restore-and-wait.js +4 -1
  13. package/dist/resources/data/transfer/wait-for-transfer.js +8 -1
  14. package/dist/resources/data/transfer-schedule.js +10 -3
  15. package/dist/resources/extensions/platform.d.ts +3 -0
  16. package/dist/resources/extensions/platform.js +3 -0
  17. package/dist/resources/platform/account.d.ts +22 -0
  18. package/dist/resources/platform/account.js +34 -0
  19. package/dist/resources/platform/add-on/create-and-wait.js +5 -1
  20. package/dist/resources/platform/add-on/describe.js +5 -2
  21. package/dist/resources/platform/add-on/destroy-and-wait.js +2 -3
  22. package/dist/resources/platform/add-on/list-plans.js +8 -2
  23. package/dist/resources/platform/add-on/resolve.js +5 -1
  24. package/dist/resources/platform/add-on/upgrade.js +5 -2
  25. package/dist/resources/platform/add-on/wait-for-provisioning.js +4 -1
  26. package/dist/resources/platform/add-on-attachment/resolve.js +2 -3
  27. package/dist/resources/platform/app/create-and-setup.d.ts +3 -4
  28. package/dist/resources/platform/app/create-and-setup.js +5 -5
  29. package/dist/resources/platform/app/diff.js +2 -3
  30. package/dist/resources/platform/app/index.js +9 -3
  31. package/dist/resources/platform/app/info.d.ts +4 -0
  32. package/dist/resources/platform/app/info.js +21 -7
  33. package/dist/resources/platform/app/transfer.js +2 -1
  34. package/dist/resources/platform/app/wait-for-acm-certificates.js +2 -1
  35. package/dist/resources/platform/container/ensure-container-stack.js +2 -1
  36. package/dist/resources/platform/container/release-images.js +2 -1
  37. package/dist/resources/platform/container/remove-process-types.js +2 -1
  38. package/dist/resources/platform/delinquency.d.ts +23 -0
  39. package/dist/resources/platform/delinquency.js +41 -0
  40. package/dist/resources/platform/domain/clear-custom-domains.js +2 -1
  41. package/dist/resources/platform/domain/create-and-wait.js +2 -1
  42. package/dist/resources/platform/domain/wait-for-ready.js +2 -1
  43. package/dist/resources/platform/dyno/exec.js +4 -3
  44. package/dist/resources/platform/dyno/index.js +6 -3
  45. package/dist/resources/platform/dyno/run.js +2 -1
  46. package/dist/resources/platform/dyno/wait-for-info.js +2 -1
  47. package/dist/resources/platform/dyno/wait-for-release.js +2 -1
  48. package/dist/resources/platform/log-session/index.js +6 -1
  49. package/dist/resources/platform/pipeline/coupling.js +5 -2
  50. package/dist/resources/platform/pipeline/index.js +4 -1
  51. package/dist/resources/platform/pipeline/promotion.js +15 -7
  52. package/dist/resources/platform/review-app-config/resolve-repo-name.js +4 -3
  53. package/dist/resources/platform/sni-endpoint/create-and-associate.js +2 -1
  54. package/dist/resources/platform/space/wait-for-allocated.js +2 -4
  55. package/dist/resources/platform/team.d.ts +22 -0
  56. package/dist/resources/platform/team.js +34 -0
  57. package/dist/resources/platform/telemetry-drain/remove-drains-for-target.js +2 -1
  58. package/dist/resources/platform/test-run/wait-for-state.js +2 -1
  59. package/dist/resources/platform/vpn-connection/wait-for-active.js +2 -1
  60. package/dist/utils/is-abort-error.d.ts +11 -0
  61. package/dist/utils/is-abort-error.js +14 -0
  62. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  import { debug } from './debug.js';
2
3
  /**
3
4
  * Resolves the GitHub repository name for a canonical pipeline ID.
@@ -9,7 +10,7 @@ import { debug } from './debug.js';
9
10
  export async function resolveRepoName(ctx, pipelineId, options = {}) {
10
11
  const { signal } = options;
11
12
  signal?.throwIfAborted();
12
- const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
13
+ const platform = withSignal(ctx.platform, signal);
13
14
  let useRepositoriesApi;
14
15
  try {
15
16
  const feature = await platform.accountFeature.info('dashboard-repositories-api');
@@ -22,7 +23,7 @@ export async function resolveRepoName(ctx, pipelineId, options = {}) {
22
23
  }
23
24
  if (useRepositoriesApi) {
24
25
  try {
25
- const repositoriesApi = signal ? ctx.repositoriesApi.withOptions({ signal }) : ctx.repositoriesApi;
26
+ const repositoriesApi = withSignal(ctx.repositoriesApi, signal);
26
27
  const repository = await repositoriesApi.githubRepository.info(pipelineId);
27
28
  signal?.throwIfAborted();
28
29
  const repositoryName = repository.full_name?.trim();
@@ -40,7 +41,7 @@ export async function resolveRepoName(ctx, pipelineId, options = {}) {
40
41
  signal?.throwIfAborted();
41
42
  debug('repositories API disabled; falling back');
42
43
  }
43
- const repositories = signal ? ctx.repositories.withOptions({ signal }) : ctx.repositories;
44
+ const repositories = withSignal(ctx.repositories, signal);
44
45
  const pipelineRepository = await repositories.pipelineRepository.info(pipelineId);
45
46
  signal?.throwIfAborted();
46
47
  const repositoryName = pipelineRepository.repository.name.trim();
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  import { waitForReady } from '../domain/wait-for-ready.js';
2
3
  const DEFAULT_WAIT_INTERVAL_MS = 1000;
3
4
  const DEFAULT_TIMEOUT_MS = 30_000;
@@ -35,7 +36,7 @@ const DEFAULT_TIMEOUT_MS = 30_000;
35
36
  export async function createAndAssociate(ctx, appIdentity, certificateChain, privateKey, options) {
36
37
  const { domainPoller, intervalMs = DEFAULT_WAIT_INTERVAL_MS, resolveDomains, signal, timeoutMs = DEFAULT_TIMEOUT_MS, } = options;
37
38
  signal?.throwIfAborted();
38
- const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
39
+ const platform = withSignal(ctx.platform, signal);
39
40
  const sniEndpoint = await platform.sniEndpoint.create(appIdentity, {
40
41
  certificate_chain: certificateChain,
41
42
  private_key: privateKey,
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  import { wait } from '../../../utils/wait.js';
2
3
  import { SpaceNotAllocatedError, SpaceNotReadyError } from './errors.js';
3
4
  const DEFAULT_INTERVAL_MS = 5000;
@@ -22,10 +23,7 @@ const DEFAULT_TIMEOUT_MS = 20 * 60 * 1000;
22
23
  export async function waitForAllocated(ctx, name, options = {}) {
23
24
  const { includeNat, intervalMs = DEFAULT_INTERVAL_MS, signal, timeoutMs = DEFAULT_TIMEOUT_MS, } = options;
24
25
  signal?.throwIfAborted();
25
- let platform = ctx.platform.withHeaders({ 'Accept-Expansion': 'region' });
26
- if (signal) {
27
- platform = platform.withOptions({ signal });
28
- }
26
+ const platform = withSignal(ctx.platform.withHeaders({ 'Accept-Expansion': 'region' }), signal);
29
27
  const deadline = Date.now() + timeoutMs;
30
28
  let space = await platform.space.info(name);
31
29
  while (space.state === 'allocating') {
@@ -0,0 +1,22 @@
1
+ import type { Team, TeamDelinquency } from '@heroku/types/3.sdk';
2
+ import type { ResourceCtx } from '../../core/extend-resource.js';
3
+ export type GetTeamWithDelinquencyOptions = {
4
+ signal?: AbortSignal;
5
+ };
6
+ export type TeamWithDelinquency = {
7
+ delinquency: null | TeamDelinquency;
8
+ team: Team;
9
+ };
10
+ /**
11
+ * Fetch a team together with its delinquency status.
12
+ *
13
+ * Runs the two reads concurrently. The team lookup hard-fails — there is no
14
+ * result without it. The delinquency lookup soft-fails to `null`: a hiccup on
15
+ * that secondary call must not sink an otherwise-successful team fetch. Callers
16
+ * decide whether and how to surface a warning from `delinquency` —
17
+ * `formatDelinquencyWarning` renders the sentence.
18
+ */
19
+ export declare function getTeamWithDelinquency(ctx: Pick<ResourceCtx, 'platform'>, teamIdentity: string, options?: GetTeamWithDelinquencyOptions): Promise<TeamWithDelinquency>;
20
+ export declare const teamExtensions: import("../../core/extend-resource.js").ResourceExtension<"platform", "team", {
21
+ getWithDelinquency: (teamIdentity: string, options?: GetTeamWithDelinquencyOptions) => Promise<TeamWithDelinquency>;
22
+ }>;
@@ -0,0 +1,34 @@
1
+ import createDebug from 'debug';
2
+ import { extendResource } from '../../core/extend-resource.js';
3
+ const debug = createDebug('heroku:sdk:resources:team');
4
+ /**
5
+ * Fetch a team together with its delinquency status.
6
+ *
7
+ * Runs the two reads concurrently. The team lookup hard-fails — there is no
8
+ * result without it. The delinquency lookup soft-fails to `null`: a hiccup on
9
+ * that secondary call must not sink an otherwise-successful team fetch. Callers
10
+ * decide whether and how to surface a warning from `delinquency` —
11
+ * `formatDelinquencyWarning` renders the sentence.
12
+ */
13
+ export async function getTeamWithDelinquency(ctx, teamIdentity, options = {}) {
14
+ options.signal?.throwIfAborted();
15
+ const platform = options.signal
16
+ ? ctx.platform.withOptions({ signal: options.signal })
17
+ : ctx.platform;
18
+ const [team, delinquency] = await Promise.all([
19
+ platform.team.info(teamIdentity),
20
+ platform.teamDelinquency.info(teamIdentity).catch((error) => {
21
+ // Soft-fail a secondary-call hiccup to null, but rethrow a cancellation:
22
+ // if the caller aborted, returning null would misreport a delinquent team
23
+ // as current. Anything else is logged and swallowed.
24
+ if (options.signal?.aborted)
25
+ throw error;
26
+ debug('team delinquency lookup failed; treating as not delinquent: %O', error);
27
+ return null;
28
+ }),
29
+ ]);
30
+ return { delinquency, team };
31
+ }
32
+ export const teamExtensions = extendResource('platform', 'team', ctx => ({
33
+ getWithDelinquency: (teamIdentity, options) => getTeamWithDelinquency(ctx, teamIdentity, options),
34
+ }));
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  /**
2
3
  * Remove all telemetry drains for a given app or space.
3
4
  *
@@ -11,7 +12,7 @@ export async function removeDrainsForTarget(ctx, target, options = {}) {
11
12
  const { signal } = options;
12
13
  const { app, space } = target;
13
14
  signal?.throwIfAborted();
14
- const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
15
+ const platform = withSignal(ctx.platform, signal);
15
16
  let drains = [];
16
17
  if (app) {
17
18
  drains = await platform.telemetryDrain.listByApp(app);
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  import { wait } from '../../../utils/wait.js';
2
3
  const DEFAULT_INTERVAL_MS = 1000;
3
4
  // Finite default so a stuck CI test run can't hang a caller forever.
@@ -48,7 +49,7 @@ export async function waitForState(ctx, pipelineId, testRunNumber, targetStates,
48
49
  signal?.throwIfAborted();
49
50
  // Scope the in-flight info call to the caller's signal so an abort takes
50
51
  // effect during the API call, not just during the backoff.
51
- const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
52
+ const platform = withSignal(ctx.platform, signal);
52
53
  const deadline = Date.now() + timeoutMs;
53
54
  while (true) {
54
55
  signal?.throwIfAborted();
@@ -1,3 +1,4 @@
1
+ import { withSignal } from '../../../core/with-signal.js';
1
2
  import { wait } from '../../../utils/wait.js';
2
3
  const DEFAULT_INTERVAL_MS = 10 * 1000;
3
4
  const DEFAULT_TIMEOUT_MS = 20 * 60 * 1000;
@@ -28,7 +29,7 @@ export class VpnConnectionNotReadyError extends Error {
28
29
  export async function waitForActive(ctx, spaceIdentity, vpnConnectionIdentity, options = {}) {
29
30
  const { intervalMs = DEFAULT_INTERVAL_MS, poller, signal, timeoutMs = DEFAULT_TIMEOUT_MS, } = options;
30
31
  signal?.throwIfAborted();
31
- const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
32
+ const platform = withSignal(ctx.platform, signal);
32
33
  const deadline = Date.now() + timeoutMs;
33
34
  let vpnConnection = await platform.vpnConnection.info(spaceIdentity, vpnConnectionIdentity);
34
35
  poller?.onStart?.(vpnConnection);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * True when `error` is the standard `AbortError` raised for a cancelled
3
+ * request: `fetch`/`ky` reject an aborted request with a `DOMException` named
4
+ * `AbortError`, and `signal.throwIfAborted()` throws the same shape by default.
5
+ *
6
+ * Used so soft-failure handling (broad `.catch` defaults, retry loops) can let
7
+ * cancellation propagate instead of swallowing it or treating it as retryable.
8
+ * Pair it with `signal?.aborted` at the call site to also catch a custom-reason
9
+ * abort (`controller.abort(reason)`) or an `AbortSignal.timeout()` deadline.
10
+ */
11
+ export declare function isAbortError(error: unknown): boolean;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * True when `error` is the standard `AbortError` raised for a cancelled
3
+ * request: `fetch`/`ky` reject an aborted request with a `DOMException` named
4
+ * `AbortError`, and `signal.throwIfAborted()` throws the same shape by default.
5
+ *
6
+ * Used so soft-failure handling (broad `.catch` defaults, retry loops) can let
7
+ * cancellation propagate instead of swallowing it or treating it as retryable.
8
+ * Pair it with `signal?.aborted` at the call site to also catch a custom-reason
9
+ * abort (`controller.abort(reason)`) or an `AbortSignal.timeout()` deadline.
10
+ */
11
+ export function isAbortError(error) {
12
+ return ((error instanceof Error || error instanceof DOMException)
13
+ && error.name === 'AbortError');
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heroku/sdk",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "Heroku SDK",
5
5
  "author": "Heroku",
6
6
  "type": "module",