@heroku/sdk 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/create-client.d.ts +9 -1
- package/dist/core/create-client.js +4 -2
- package/dist/resources/data/redis/errors.d.ts +8 -0
- package/dist/resources/data/redis/errors.js +15 -0
- package/dist/resources/data/redis/index.d.ts +9 -0
- package/dist/resources/data/redis/index.js +10 -0
- package/dist/resources/data/redis/resolve-by-app.d.ts +35 -0
- package/dist/resources/data/redis/resolve-by-app.js +56 -0
- package/dist/resources/data/redis/wait-for-ready.d.ts +32 -0
- package/dist/resources/data/redis/wait-for-ready.js +46 -0
- package/dist/resources/extensions/data.d.ts +1 -0
- package/dist/resources/extensions/data.js +1 -0
- package/dist/resources/extensions/platform.d.ts +5 -1
- package/dist/resources/extensions/platform.js +5 -1
- package/dist/resources/platform/add-on/destroy-and-wait.d.ts +22 -0
- package/dist/resources/platform/add-on/destroy-and-wait.js +62 -0
- package/dist/resources/platform/add-on/index.d.ts +9 -5
- package/dist/resources/platform/add-on/index.js +6 -0
- package/dist/resources/platform/add-on/types.d.ts +35 -0
- package/dist/resources/platform/add-on/wait-for-provisioning.d.ts +19 -0
- package/dist/resources/platform/add-on/wait-for-provisioning.js +37 -0
- package/dist/resources/platform/app/index.d.ts +3 -0
- package/dist/resources/platform/app/index.js +3 -0
- package/dist/resources/platform/app/wait-for-acm-certificates.d.ts +34 -0
- package/dist/resources/platform/app/wait-for-acm-certificates.js +51 -0
- package/dist/resources/platform/container/ensure-container-stack.d.ts +18 -0
- package/dist/resources/platform/container/ensure-container-stack.js +32 -0
- package/dist/resources/platform/container/index.d.ts +13 -0
- package/dist/resources/platform/container/index.js +12 -0
- package/dist/resources/platform/container/release-images.d.ts +21 -0
- package/dist/resources/platform/container/release-images.js +23 -0
- package/dist/resources/platform/container/remove-process-types.d.ts +22 -0
- package/dist/resources/platform/container/remove-process-types.js +20 -0
- package/dist/resources/platform/dyno/index.d.ts +3 -0
- package/dist/resources/platform/dyno/index.js +3 -0
- package/dist/resources/platform/dyno/run.d.ts +76 -0
- package/dist/resources/platform/dyno/run.js +74 -0
- package/dist/resources/platform/log-session/index.js +71 -12
- package/dist/resources/platform/sni-endpoint/create-and-associate.d.ts +38 -0
- package/dist/resources/platform/sni-endpoint/create-and-associate.js +86 -0
- package/dist/resources/platform/sni-endpoint/index.d.ts +5 -0
- package/dist/resources/platform/sni-endpoint/index.js +6 -0
- package/dist/resources/platform/telemetry-drain/index.d.ts +6 -0
- package/dist/resources/platform/telemetry-drain/index.js +6 -0
- package/dist/resources/platform/telemetry-drain/remove-drains-for-target.d.ts +13 -0
- package/dist/resources/platform/telemetry-drain/remove-drains-for-target.js +25 -0
- package/dist/resources/platform/telemetry-drain/types.d.ts +13 -0
- package/dist/resources/platform/telemetry-drain/types.js +1 -0
- package/dist/resources/platform/test-run/index.d.ts +5 -0
- package/dist/resources/platform/test-run/index.js +9 -0
- package/dist/resources/platform/test-run/wait-for-state.d.ts +68 -0
- package/dist/resources/platform/test-run/wait-for-state.js +65 -0
- package/package.json +10 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { extendResource } from '../../../core/extend-resource.js';
|
|
2
|
+
import { createAndAssociate } from './create-and-associate.js';
|
|
3
|
+
export { createAndAssociate } from './create-and-associate.js';
|
|
4
|
+
export const sniEndpointExtensions = extendResource('platform', 'sniEndpoint', ctx => ({
|
|
5
|
+
createAndAssociate: (appIdentity, certificateChain, privateKey, options) => createAndAssociate(ctx, appIdentity, certificateChain, privateKey, options),
|
|
6
|
+
}));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TelemetryDrainOptions, TelemetryDrainTarget } from './types.js';
|
|
2
|
+
export { removeDrainsForTarget } from './remove-drains-for-target.js';
|
|
3
|
+
export type { TelemetryDrainOptions, TelemetryDrainTarget } from './types.js';
|
|
4
|
+
export declare const telemetryDrainExtensions: import("../../../core/extend-resource.js").ResourceExtension<"platform", "telemetryDrain", {
|
|
5
|
+
removeDrains: (target: TelemetryDrainTarget, options?: TelemetryDrainOptions) => Promise<import("@heroku/types/3.sdk").TelemetryDrain[]>;
|
|
6
|
+
}>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { extendResource } from '../../../core/extend-resource.js';
|
|
2
|
+
import { removeDrainsForTarget } from './remove-drains-for-target.js';
|
|
3
|
+
export { removeDrainsForTarget } from './remove-drains-for-target.js';
|
|
4
|
+
export const telemetryDrainExtensions = extendResource('platform', 'telemetryDrain', ctx => ({
|
|
5
|
+
removeDrains: (target, options) => removeDrainsForTarget(ctx, target, options),
|
|
6
|
+
}));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TelemetryDrain } from '@heroku/types/3.sdk';
|
|
2
|
+
import type { ResourceCtx } from '../../../core/extend-resource.js';
|
|
3
|
+
import type { TelemetryDrainOptions, TelemetryDrainTarget } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Remove all telemetry drains for a given app or space.
|
|
6
|
+
*
|
|
7
|
+
* Behavior:
|
|
8
|
+
* - Dispatches to listByApp or listBySpace based on target discriminant
|
|
9
|
+
* - Deletes all drains in parallel via Promise.all
|
|
10
|
+
* - Returns empty array if no drains exist
|
|
11
|
+
* - Rejects if any individual delete fails
|
|
12
|
+
*/
|
|
13
|
+
export declare function removeDrainsForTarget(ctx: Pick<ResourceCtx, 'platform'>, target: TelemetryDrainTarget, options?: TelemetryDrainOptions): Promise<TelemetryDrain[]>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove all telemetry drains for a given app or space.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* - Dispatches to listByApp or listBySpace based on target discriminant
|
|
6
|
+
* - Deletes all drains in parallel via Promise.all
|
|
7
|
+
* - Returns empty array if no drains exist
|
|
8
|
+
* - Rejects if any individual delete fails
|
|
9
|
+
*/
|
|
10
|
+
export async function removeDrainsForTarget(ctx, target, options = {}) {
|
|
11
|
+
const { signal } = options;
|
|
12
|
+
const { app, space } = target;
|
|
13
|
+
signal?.throwIfAborted();
|
|
14
|
+
const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
|
|
15
|
+
let drains = [];
|
|
16
|
+
if (app) {
|
|
17
|
+
drains = await platform.telemetryDrain.listByApp(app);
|
|
18
|
+
}
|
|
19
|
+
else if (space) {
|
|
20
|
+
drains = await platform.telemetryDrain.listBySpace(space);
|
|
21
|
+
}
|
|
22
|
+
signal?.throwIfAborted();
|
|
23
|
+
const deletedDrains = await Promise.all(drains.map(drain => platform.telemetryDrain.delete(drain.id)));
|
|
24
|
+
return deletedDrains;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type TestRunStatus, type WaitForStateOptions } from './wait-for-state.js';
|
|
2
|
+
export { TestRunNotReadyError, type TestRunStatus, waitForState, type WaitForStateOptions, } from './wait-for-state.js';
|
|
3
|
+
export declare const testRunExtensions: import("../../../core/extend-resource.js").ResourceExtension<"platform", "testRun", {
|
|
4
|
+
waitForState: (pipelineId: string, testRunNumber: number, targetStates: ReadonlyArray<string | TestRunStatus>, options?: WaitForStateOptions) => Promise<import("@heroku/types/3.sdk").TestRun>;
|
|
5
|
+
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { extendResource } from '../../../core/extend-resource.js';
|
|
2
|
+
import { waitForState } from './wait-for-state.js';
|
|
3
|
+
export { TestRunNotReadyError, waitForState, } from './wait-for-state.js';
|
|
4
|
+
// Resource key MUST be the camelCase `'testRun'` — it matches the generated
|
|
5
|
+
// route-group export name that `mergeExtensions` looks up on the platform
|
|
6
|
+
// client. The directory stays kebab (`test-run/`).
|
|
7
|
+
export const testRunExtensions = extendResource('platform', 'testRun', ctx => ({
|
|
8
|
+
waitForState: (pipelineId, testRunNumber, targetStates, options) => waitForState(ctx, pipelineId, testRunNumber, targetStates, options),
|
|
9
|
+
}));
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { TestRun } from '@heroku/types/3.sdk';
|
|
2
|
+
import type { ResourceCtx } from '../../../core/extend-resource.js';
|
|
3
|
+
/**
|
|
4
|
+
* The documented `TestRun.status` values from the Platform API. Provided
|
|
5
|
+
* for autocomplete in {@link waitForState}'s `targetStates`; the runtime
|
|
6
|
+
* comparison is plain string membership (`targetStates.includes(run.status)`),
|
|
7
|
+
* so any string is accepted.
|
|
8
|
+
*/
|
|
9
|
+
export type TestRunStatus = TestRun['status'];
|
|
10
|
+
/**
|
|
11
|
+
* Thrown by {@link waitForState} when the test run did not reach one of
|
|
12
|
+
* `targetStates` within `timeoutMs`. Carries the last observed run so
|
|
13
|
+
* callers can branch on its terminal `status` (e.g. distinguish a
|
|
14
|
+
* `failed` run from one still `building`). Mirrors `DynoNotReadyError`.
|
|
15
|
+
*/
|
|
16
|
+
export declare class TestRunNotReadyError extends Error {
|
|
17
|
+
readonly testRun: TestRun;
|
|
18
|
+
readonly expectedStates: ReadonlyArray<string>;
|
|
19
|
+
readonly timeoutMs: number;
|
|
20
|
+
readonly id = "test_run_not_ready";
|
|
21
|
+
constructor(testRun: TestRun, expectedStates: ReadonlyArray<string>, timeoutMs: number);
|
|
22
|
+
}
|
|
23
|
+
export type WaitForStateOptions = {
|
|
24
|
+
/**
|
|
25
|
+
* Delay between polls in milliseconds. Defaults to 1000.
|
|
26
|
+
*/
|
|
27
|
+
intervalMs?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Fires after every successful `testRun.infoByPipeline` call, including
|
|
30
|
+
* runs whose `status` does not yet match `targetStates` (and trigger
|
|
31
|
+
* another poll) AND the final matching run before it is returned. Use
|
|
32
|
+
* this to surface live state transitions in a UI. Exceptions thrown from
|
|
33
|
+
* this callback propagate and end the wait — there is no implicit catch.
|
|
34
|
+
*/
|
|
35
|
+
onPoll?: (run: TestRun) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Cancels the wait early. If already aborted, {@link waitForState}
|
|
38
|
+
* rejects before the first poll; if aborted mid-wait, the pending delay
|
|
39
|
+
* rejects with `signal.reason`.
|
|
40
|
+
*/
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
/**
|
|
43
|
+
* Wall-clock budget in milliseconds before {@link TestRunNotReadyError}
|
|
44
|
+
* is thrown. Defaults to 600000 (10 minutes) — a finite default so a
|
|
45
|
+
* stuck run can't hang forever. Pass a larger value for long CI runs.
|
|
46
|
+
*/
|
|
47
|
+
timeoutMs?: number;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Poll `testRun.infoByPipeline` until the run's `status` is one of
|
|
51
|
+
* `targetStates`, then return that run. Reuses the SDK's cancellable
|
|
52
|
+
* `wait()` helper to space polls — no bare `setTimeout` loop.
|
|
53
|
+
*
|
|
54
|
+
* Transient-error handling: errors from `infoByPipeline` **propagate**;
|
|
55
|
+
* there is no 404/429/503 retry. This matches the closest precedent,
|
|
56
|
+
* `promotePipeline`, and the original CLI `waitForStates`, which had no
|
|
57
|
+
* retry either — adopting `waitForInfo`'s transient retry would be behavior
|
|
58
|
+
* the eventual CLI caller never had.
|
|
59
|
+
*
|
|
60
|
+
* On exceeding `timeoutMs` without a match, throws {@link TestRunNotReadyError}
|
|
61
|
+
* carrying the last observed run.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const run = await platform.testRun.waitForState(pipelineId, 42, ['debugging', 'errored'])
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function waitForState(ctx: Pick<ResourceCtx, 'platform'>, pipelineId: string, testRunNumber: number, targetStates: ReadonlyArray<string | TestRunStatus>, options?: WaitForStateOptions): Promise<TestRun>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { wait } from '../../../utils/wait.js';
|
|
2
|
+
const DEFAULT_INTERVAL_MS = 1000;
|
|
3
|
+
// Finite default so a stuck CI test run can't hang a caller forever.
|
|
4
|
+
// Diverges deliberately from `promotePipeline`, which leaves `timeoutMs`
|
|
5
|
+
// unbounded; callers that need longer can pass an explicit `timeoutMs`.
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 600_000;
|
|
7
|
+
/**
|
|
8
|
+
* Thrown by {@link waitForState} when the test run did not reach one of
|
|
9
|
+
* `targetStates` within `timeoutMs`. Carries the last observed run so
|
|
10
|
+
* callers can branch on its terminal `status` (e.g. distinguish a
|
|
11
|
+
* `failed` run from one still `building`). Mirrors `DynoNotReadyError`.
|
|
12
|
+
*/
|
|
13
|
+
export class TestRunNotReadyError extends Error {
|
|
14
|
+
testRun;
|
|
15
|
+
expectedStates;
|
|
16
|
+
timeoutMs;
|
|
17
|
+
id = 'test_run_not_ready';
|
|
18
|
+
constructor(testRun, expectedStates, timeoutMs) {
|
|
19
|
+
super(`Test run #${testRun.number} did not reach status ${expectedStates.join('/')} `
|
|
20
|
+
+ `within ${timeoutMs}ms (last status: ${testRun.status}).`);
|
|
21
|
+
this.testRun = testRun;
|
|
22
|
+
this.expectedStates = expectedStates;
|
|
23
|
+
this.timeoutMs = timeoutMs;
|
|
24
|
+
this.name = 'TestRunNotReadyError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Poll `testRun.infoByPipeline` until the run's `status` is one of
|
|
29
|
+
* `targetStates`, then return that run. Reuses the SDK's cancellable
|
|
30
|
+
* `wait()` helper to space polls — no bare `setTimeout` loop.
|
|
31
|
+
*
|
|
32
|
+
* Transient-error handling: errors from `infoByPipeline` **propagate**;
|
|
33
|
+
* there is no 404/429/503 retry. This matches the closest precedent,
|
|
34
|
+
* `promotePipeline`, and the original CLI `waitForStates`, which had no
|
|
35
|
+
* retry either — adopting `waitForInfo`'s transient retry would be behavior
|
|
36
|
+
* the eventual CLI caller never had.
|
|
37
|
+
*
|
|
38
|
+
* On exceeding `timeoutMs` without a match, throws {@link TestRunNotReadyError}
|
|
39
|
+
* carrying the last observed run.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const run = await platform.testRun.waitForState(pipelineId, 42, ['debugging', 'errored'])
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export async function waitForState(ctx, pipelineId, testRunNumber, targetStates, options = {}) {
|
|
47
|
+
const { intervalMs = DEFAULT_INTERVAL_MS, onPoll, signal, timeoutMs = DEFAULT_TIMEOUT_MS, } = options;
|
|
48
|
+
signal?.throwIfAborted();
|
|
49
|
+
// Scope the in-flight info call to the caller's signal so an abort takes
|
|
50
|
+
// effect during the API call, not just during the backoff.
|
|
51
|
+
const platform = signal ? ctx.platform.withOptions({ signal }) : ctx.platform;
|
|
52
|
+
const deadline = Date.now() + timeoutMs;
|
|
53
|
+
while (true) {
|
|
54
|
+
signal?.throwIfAborted();
|
|
55
|
+
const run = await platform.testRun.infoByPipeline(pipelineId, testRunNumber);
|
|
56
|
+
onPoll?.(run);
|
|
57
|
+
if (targetStates.includes(run.status)) {
|
|
58
|
+
return run;
|
|
59
|
+
}
|
|
60
|
+
if (Date.now() >= deadline) {
|
|
61
|
+
throw new TestRunNotReadyError(run, targetStates, timeoutMs);
|
|
62
|
+
}
|
|
63
|
+
await wait(intervalMs, signal);
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroku/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Heroku SDK",
|
|
5
5
|
"author": "Heroku",
|
|
6
6
|
"type": "module",
|
|
@@ -50,6 +50,14 @@
|
|
|
50
50
|
"types": "./dist/resources/platform/pipeline/*.d.ts",
|
|
51
51
|
"default": "./dist/resources/platform/pipeline/*.js"
|
|
52
52
|
},
|
|
53
|
+
"./resources/platform/test-run": {
|
|
54
|
+
"types": "./dist/resources/platform/test-run/index.d.ts",
|
|
55
|
+
"default": "./dist/resources/platform/test-run/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./resources/data/redis": {
|
|
58
|
+
"types": "./dist/resources/data/redis/index.d.ts",
|
|
59
|
+
"default": "./dist/resources/data/redis/index.js"
|
|
60
|
+
},
|
|
53
61
|
"./resources/*": {
|
|
54
62
|
"types": "./dist/resources/*.d.ts",
|
|
55
63
|
"default": "./dist/resources/*.js"
|
|
@@ -92,7 +100,7 @@
|
|
|
92
100
|
},
|
|
93
101
|
"dependencies": {
|
|
94
102
|
"@heroku/heroku-fetch": "^0.1.1-beta",
|
|
95
|
-
"@heroku/types": "^
|
|
103
|
+
"@heroku/types": "^4.0.1",
|
|
96
104
|
"debug": "^4.4.0"
|
|
97
105
|
}
|
|
98
106
|
}
|