@heroku/sdk 0.1.0-alpha.0 → 0.2.0-beta.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/dist/resources/data/database.d.ts +1 -1
- package/dist/resources/data/maintenance.d.ts +1 -1
- package/dist/resources/data/postgres-database.d.ts +1 -1
- package/dist/resources/data/transfer.d.ts +1 -1
- package/dist/resources/platform/add-on/index.d.ts +1 -1
- package/dist/resources/platform/app/index.d.ts +1 -1
- package/dist/resources/platform/dyno/index.d.ts +1 -1
- package/dist/resources/platform/log-session/index.d.ts +1 -1
- package/dist/resources/platform/pipeline/coupling.d.ts +1 -1
- package/dist/resources/platform/pipeline/index.d.ts +1 -1
- package/dist/resources/platform/pipeline/promotion.d.ts +1 -1
- package/package.json +7 -25
- package/dist/compositions/add-on.d.ts +0 -7
- package/dist/compositions/add-on.js +0 -6
- package/dist/compositions/app.d.ts +0 -8
- package/dist/compositions/app.js +0 -11
- package/dist/compositions/dyno.d.ts +0 -17
- package/dist/compositions/dyno.js +0 -23
- package/dist/compositions/pg.d.ts +0 -15
- package/dist/compositions/pg.js +0 -56
- package/dist/compositions/pipeline.d.ts +0 -33
- package/dist/compositions/pipeline.js +0 -146
- package/dist/resources/data/backup.d.ts +0 -9
- package/dist/resources/data/backup.js +0 -10
- package/dist/resources/data/internal/resolve-addon-id.d.ts +0 -2
- package/dist/resources/data/internal/resolve-addon-id.js +0 -13
- package/dist/resources/data/postgres-credential.d.ts +0 -11
- package/dist/resources/data/postgres-credential.js +0 -16
- package/dist/resources/data/postgres.d.ts +0 -9
- package/dist/resources/data/postgres.js +0 -10
- package/dist/resources/data/transfer-schedule.d.ts +0 -9
- package/dist/resources/data/transfer-schedule.js +0 -10
- package/dist/resources/platform/add-on.d.ts +0 -211
- package/dist/resources/platform/add-on.js +0 -354
- package/dist/resources/platform/app.d.ts +0 -56
- package/dist/resources/platform/app.js +0 -50
- package/dist/resources/platform/dyno.d.ts +0 -45
- package/dist/resources/platform/dyno.js +0 -26
- package/dist/resources/platform/log-session.d.ts +0 -81
- package/dist/resources/platform/log-session.js +0 -167
- package/dist/resources/platform/pipeline-coupling.d.ts +0 -27
- package/dist/resources/platform/pipeline-coupling.js +0 -55
- package/dist/resources/platform/pipeline-promotion.d.ts +0 -21
- package/dist/resources/platform/pipeline-promotion.js +0 -128
- package/dist/resources/platform/pipeline.d.ts +0 -53
- package/dist/resources/platform/pipeline.js +0 -75
|
@@ -43,7 +43,7 @@ export declare function dryRunUpgrade(ctx: DatabaseCtx, appIdentity: string, add
|
|
|
43
43
|
export declare function runUpgrade(ctx: DatabaseCtx, appIdentity: string, addonIdentity?: string, body?: DatabaseUpgradeBody, options?: DatabaseOptions): Promise<DatabaseUpgradeResponse>;
|
|
44
44
|
export declare function prepareUpgrade(ctx: DatabaseCtx, appIdentity: string, addonIdentity?: string, body?: DatabaseUpgradeBody, options?: DatabaseOptions): Promise<DatabaseUpgradeResponse>;
|
|
45
45
|
export declare function cancelUpgrade(ctx: DatabaseCtx, appIdentity: string, addonIdentity?: string, options?: DatabaseOptions): Promise<DatabaseUpgradeResponse>;
|
|
46
|
-
export declare const databaseExtensions: import("../../
|
|
46
|
+
export declare const databaseExtensions: import("../../index.js").ResourceExtension<"data", "database", {
|
|
47
47
|
cancelUpgrade: (appIdentity: string, addonIdentity?: string, options?: DatabaseOptions) => Promise<DatabaseUpgradeResponse>;
|
|
48
48
|
describe: (appIdentity: string, addonIdentity?: string, options?: DatabaseOptions) => Promise<DatabaseDescribeResult>;
|
|
49
49
|
dryRunUpgrade: (appIdentity: string, addonIdentity?: string, body?: DatabaseUpgradeBody, options?: DatabaseOptions) => Promise<DatabaseUpgradeResponse>;
|
|
@@ -4,6 +4,6 @@ export type MaintenanceInfoOptions = {
|
|
|
4
4
|
signal?: AbortSignal;
|
|
5
5
|
};
|
|
6
6
|
export declare function info(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: MaintenanceInfoOptions): Promise<MaintenanceInfoResult>;
|
|
7
|
-
export declare const maintenanceExtensions: import("../../
|
|
7
|
+
export declare const maintenanceExtensions: import("../../index.js").ResourceExtension<"data", "maintenance", {
|
|
8
8
|
info: (appIdentity: string, addonIdentity?: string, options?: MaintenanceInfoOptions) => Promise<MaintenanceInfoResult>;
|
|
9
9
|
}>;
|
|
@@ -26,7 +26,7 @@ type CredentialsCtx = {
|
|
|
26
26
|
platform: ResourceCtx['platform'];
|
|
27
27
|
};
|
|
28
28
|
export declare function listCredentials(ctx: CredentialsCtx, appIdentity: string, addonIdentity?: string, options?: ListCredentialsOptions): Promise<CredentialInfo[]>;
|
|
29
|
-
export declare const postgresDatabaseExtensions: import("../../
|
|
29
|
+
export declare const postgresDatabaseExtensions: import("../../index.js").ResourceExtension<"data", "postgresDatabase", {
|
|
30
30
|
listCredentials: (appIdentity: string, addonIdentity?: string, options?: ListCredentialsOptions) => Promise<CredentialInfo[]>;
|
|
31
31
|
}>;
|
|
32
32
|
export {};
|
|
@@ -43,7 +43,7 @@ type TransferCtx = {
|
|
|
43
43
|
platform: ResourceCtx['platform'];
|
|
44
44
|
};
|
|
45
45
|
export declare function listByApp(ctx: TransferCtx, appIdentity: string, addonIdentity?: string, options?: TransferOptions): Promise<BackupTransfer[]>;
|
|
46
|
-
export declare const transferExtensions: import("../../
|
|
46
|
+
export declare const transferExtensions: import("../../index.js").ResourceExtension<"data", "transfer", {
|
|
47
47
|
listByApp: (appIdentity: string, addonIdentity?: string, options?: TransferOptions) => Promise<BackupTransfer[]>;
|
|
48
48
|
}>;
|
|
49
49
|
export {};
|
|
@@ -10,7 +10,7 @@ export { formatPlanPriceLabel, type FormatPlanPriceLabelOptions, type PlanPriceB
|
|
|
10
10
|
export { resolveAddon, resolveAddonByAttachment } from './resolve.js';
|
|
11
11
|
export type { AddOnOptions, CreateAndWaitOptions, DescribedAddOn, ResolveAddonOptions, ResolvedAddOn, UpgradeAddOnOptions, } from './types.js';
|
|
12
12
|
export { upgrade } from './upgrade.js';
|
|
13
|
-
export declare const addOnExtensions: import("../../../
|
|
13
|
+
export declare const addOnExtensions: import("../../../index.js").ResourceExtension<"platform", "addOn", {
|
|
14
14
|
createAndWait: (appIdentity: string, body: AddOnCreateOpts, options?: CreateAndWaitOptions) => Promise<import("@heroku/types/3.sdk").AddOn>;
|
|
15
15
|
describe: (addonIdentity: string, options?: ResolveAddonOptions) => Promise<import("./types.js").DescribedAddOn>;
|
|
16
16
|
formatPlanPriceLabel: typeof formatPlanPriceLabel;
|
|
@@ -48,7 +48,7 @@ export declare function isShielded(ctx: {
|
|
|
48
48
|
export declare function getProcessTier(ctx: {
|
|
49
49
|
platform: AppInfoPlatform;
|
|
50
50
|
}, appIdentity: string, options?: GetProcessTierOptions): Promise<ProcessTier | undefined>;
|
|
51
|
-
export declare const appExtensions: import("../../../
|
|
51
|
+
export declare const appExtensions: import("../../../index.js").ResourceExtension<"platform", "app", {
|
|
52
52
|
describe: (appIdentity: string, options?: DescribeAppOptions) => Promise<import("./info.js").AppInfo>;
|
|
53
53
|
disableMaintenance: (appIdentity: string, options?: AppMaintenanceOptions) => Promise<App>;
|
|
54
54
|
enableMaintenance: (appIdentity: string, options?: AppMaintenanceOptions) => Promise<App>;
|
|
@@ -35,7 +35,7 @@ export declare function scaleDynos(ctx: {
|
|
|
35
35
|
platform: ScalePlatform;
|
|
36
36
|
}, appIdentity: string, updates: ScaleDynosUpdate[], options?: DynoOptions): Promise<Formation[]>;
|
|
37
37
|
export declare function restartDynos(ctx: Pick<ResourceCtx, 'platform'>, appIdentity: string, target?: RestartDynosTarget, options?: DynoOptions): Promise<void>;
|
|
38
|
-
export declare const dynoExtensions: import("../../../
|
|
38
|
+
export declare const dynoExtensions: import("../../../index.js").ResourceExtension<"platform", "dyno", {
|
|
39
39
|
restart: (appIdentity: string, target?: RestartDynosTarget, options?: DynoOptions) => Promise<void>;
|
|
40
40
|
scale: {
|
|
41
41
|
(appIdentity: string, updates: ScaleDynosUpdate, options?: DynoOptions): Promise<Formation>;
|
|
@@ -96,7 +96,7 @@ export type StreamLogsOptions = {
|
|
|
96
96
|
* - errors thrown by `logSession.create` (auth, app-not-found, etc.)
|
|
97
97
|
*/
|
|
98
98
|
export declare function streamLogs(ctx: Pick<ResourceCtx, 'platform'>, appIdentity: string, options?: StreamLogsOptions): AsyncGenerator<string, void, unknown>;
|
|
99
|
-
export declare const logSessionExtensions: import("../../../
|
|
99
|
+
export declare const logSessionExtensions: import("../../../index.js").ResourceExtension<"platform", "logSession", {
|
|
100
100
|
parseHerokuLogLine: typeof parseHerokuLogLine;
|
|
101
101
|
streamLogs: (appIdentity: string, options?: StreamLogsOptions) => AsyncGenerator<string, void, unknown>;
|
|
102
102
|
}>;
|
|
@@ -22,6 +22,6 @@ export type AppWithPipelineCoupling = TeamApp & {
|
|
|
22
22
|
* result; otherwise this throws.
|
|
23
23
|
*/
|
|
24
24
|
export declare function listPipelineApps(ctx: Pick<ResourceCtx, 'platform'>, pipelineId: string, options?: ListPipelineAppsOptions): Promise<AppWithPipelineCoupling[]>;
|
|
25
|
-
export declare const pipelineCouplingExtensions: import("../../../
|
|
25
|
+
export declare const pipelineCouplingExtensions: import("../../../index.js").ResourceExtension<"platform", "pipelineCoupling", {
|
|
26
26
|
listApps: (pipelineId: string, options?: ListPipelineAppsOptions) => Promise<AppWithPipelineCoupling[]>;
|
|
27
27
|
}>;
|
|
@@ -48,6 +48,6 @@ export declare class PipelineAmbiguousError extends Error {
|
|
|
48
48
|
* `error.matches`.
|
|
49
49
|
*/
|
|
50
50
|
export declare function resolvePipeline(ctx: Pick<ResourceCtx, 'platform'>, identity: string, options?: ResolvePipelineOptions): Promise<Pipeline>;
|
|
51
|
-
export declare const pipelineExtensions: import("../../../
|
|
51
|
+
export declare const pipelineExtensions: import("../../../index.js").ResourceExtension<"platform", "pipeline", {
|
|
52
52
|
resolve: (identity: string, options?: ResolvePipelineOptions) => Promise<Pipeline>;
|
|
53
53
|
}>;
|
|
@@ -16,6 +16,6 @@ export type PromotePipelineResult = {
|
|
|
16
16
|
targets: PipelinePromotionTarget[];
|
|
17
17
|
};
|
|
18
18
|
export declare function promotePipeline(ctx: Pick<ResourceCtx, 'platform'>, body: PipelinePromotionCreateOpts, options?: PromotePipelineOptions): Promise<PromotePipelineResult>;
|
|
19
|
-
export declare const pipelinePromotionExtensions: import("../../../
|
|
19
|
+
export declare const pipelinePromotionExtensions: import("../../../index.js").ResourceExtension<"platform", "pipelinePromotion", {
|
|
20
20
|
promote: (body: PipelinePromotionCreateOpts, options?: PromotePipelineOptions) => Promise<PromotePipelineResult>;
|
|
21
21
|
}>;
|
package/package.json
CHANGED
|
@@ -1,35 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroku/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-beta.0",
|
|
4
4
|
"description": "Heroku SDK",
|
|
5
5
|
"author": "Heroku",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"exports": {
|
|
9
|
-
".":
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"./
|
|
14
|
-
|
|
15
|
-
"default": "./dist/services/platform.js"
|
|
16
|
-
},
|
|
17
|
-
"./data": {
|
|
18
|
-
"types": "./dist/services/data.d.ts",
|
|
19
|
-
"default": "./dist/services/data.js"
|
|
20
|
-
},
|
|
21
|
-
"./extensions/platform": {
|
|
22
|
-
"types": "./dist/resources/extensions/platform.d.ts",
|
|
23
|
-
"default": "./dist/resources/extensions/platform.js"
|
|
24
|
-
},
|
|
25
|
-
"./extensions/data": {
|
|
26
|
-
"types": "./dist/resources/extensions/data.d.ts",
|
|
27
|
-
"default": "./dist/resources/extensions/data.js"
|
|
28
|
-
},
|
|
29
|
-
"./resources/*": {
|
|
30
|
-
"types": "./dist/resources/*.d.ts",
|
|
31
|
-
"default": "./dist/resources/*.js"
|
|
32
|
-
}
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./platform": "./dist/services/platform.js",
|
|
11
|
+
"./data": "./dist/services/data.js",
|
|
12
|
+
"./extensions/platform": "./dist/resources/extensions/platform.js",
|
|
13
|
+
"./extensions/data": "./dist/resources/extensions/data.js",
|
|
14
|
+
"./resources/*": "./dist/resources/*.js"
|
|
33
15
|
},
|
|
34
16
|
"sideEffects": false,
|
|
35
17
|
"repository": {
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HerokuApiClientOptions } from '@heroku/api-client';
|
|
2
|
-
import type { AddOn } from '@heroku/types/3.sdk';
|
|
3
|
-
export type AddOnOptions = {
|
|
4
|
-
clientOptions?: HerokuApiClientOptions;
|
|
5
|
-
signal?: AbortSignal;
|
|
6
|
-
};
|
|
7
|
-
export declare function upgrade(appIdentity: string, addOnIdentity: string, plan: string, options?: AddOnOptions): Promise<AddOn>;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { createPlatformClient } from '../services/platform.js';
|
|
2
|
-
export async function upgrade(appIdentity, addOnIdentity, plan, options = {}) {
|
|
3
|
-
options.signal?.throwIfAborted();
|
|
4
|
-
const client = createPlatformClient(options.clientOptions);
|
|
5
|
-
return client.addOn.update(appIdentity, addOnIdentity, { plan });
|
|
6
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { HerokuApiClientOptions } from '@heroku/api-client';
|
|
2
|
-
import type { App } from '@heroku/types/3.sdk';
|
|
3
|
-
export type AppOptions = {
|
|
4
|
-
clientOptions?: HerokuApiClientOptions;
|
|
5
|
-
signal?: AbortSignal;
|
|
6
|
-
};
|
|
7
|
-
export declare function enableMaintenanceMode(appIdentity: string, options?: AppOptions): Promise<App>;
|
|
8
|
-
export declare function disableMaintenanceMode(appIdentity: string, options?: AppOptions): Promise<App>;
|
package/dist/compositions/app.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { createPlatformClient } from '../services/platform.js';
|
|
2
|
-
export async function enableMaintenanceMode(appIdentity, options = {}) {
|
|
3
|
-
options.signal?.throwIfAborted();
|
|
4
|
-
const client = createPlatformClient(options.clientOptions);
|
|
5
|
-
return client.app.update(appIdentity, { maintenance: true });
|
|
6
|
-
}
|
|
7
|
-
export async function disableMaintenanceMode(appIdentity, options = {}) {
|
|
8
|
-
options.signal?.throwIfAborted();
|
|
9
|
-
const client = createPlatformClient(options.clientOptions);
|
|
10
|
-
return client.app.update(appIdentity, { maintenance: false });
|
|
11
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { HerokuApiClientOptions } from '@heroku/api-client';
|
|
2
|
-
import type { Formation, FormationBatchUpdateOpts, FormationUpdateOpts } from '@heroku/types/3.sdk';
|
|
3
|
-
export type DynoOptions = {
|
|
4
|
-
clientOptions?: HerokuApiClientOptions;
|
|
5
|
-
signal?: AbortSignal;
|
|
6
|
-
};
|
|
7
|
-
export type ScaleDynosUpdate = FormationUpdateOpts & {
|
|
8
|
-
type: string;
|
|
9
|
-
};
|
|
10
|
-
export type RestartDynosTarget = {
|
|
11
|
-
dyno: string;
|
|
12
|
-
} | {
|
|
13
|
-
type: string;
|
|
14
|
-
};
|
|
15
|
-
export declare function scaleDynos(appIdentity: string, updates: ScaleDynosUpdate, options?: DynoOptions): Promise<Formation>;
|
|
16
|
-
export declare function scaleDynos(appIdentity: string, updates: FormationBatchUpdateOpts['updates'], options?: DynoOptions): Promise<Formation[]>;
|
|
17
|
-
export declare function restartDynos(appIdentity: string, target?: RestartDynosTarget, options?: DynoOptions): Promise<void>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { createPlatformClient } from '../services/platform.js';
|
|
2
|
-
export async function scaleDynos(appIdentity, updates, options = {}) {
|
|
3
|
-
options.signal?.throwIfAborted();
|
|
4
|
-
const client = createPlatformClient(options.clientOptions);
|
|
5
|
-
if (Array.isArray(updates)) {
|
|
6
|
-
return client.formation.batchUpdate(appIdentity, { updates });
|
|
7
|
-
}
|
|
8
|
-
const { type, ...body } = updates;
|
|
9
|
-
return client.formation.update(appIdentity, type, body);
|
|
10
|
-
}
|
|
11
|
-
export async function restartDynos(appIdentity, target, options = {}) {
|
|
12
|
-
options.signal?.throwIfAborted();
|
|
13
|
-
const client = createPlatformClient(options.clientOptions);
|
|
14
|
-
if (!target) {
|
|
15
|
-
await client.dyno.restartAll(appIdentity);
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
if ('dyno' in target) {
|
|
19
|
-
await client.dyno.restart(appIdentity, target.dyno);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
await client.dyno.restartFormation(appIdentity, target.type);
|
|
23
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { HerokuApiClientOptions } from '@heroku/api-client';
|
|
2
|
-
import type { DatabaseInfoResult, DatabasePrepareUpgradeResult, DatabaseRunUpgradeResult, MaintenanceInfoResult, PostgresDatabaseListCredentialsResult, TransferListByAppResult } from '@heroku/types/data';
|
|
3
|
-
export type PgOptions = {
|
|
4
|
-
clientOptions?: HerokuApiClientOptions;
|
|
5
|
-
signal?: AbortSignal;
|
|
6
|
-
};
|
|
7
|
-
export type PgUpgradeOpts = {
|
|
8
|
-
version?: string;
|
|
9
|
-
};
|
|
10
|
-
export declare function describePgDatabase(appIdentity: string, addonIdentity?: string, options?: PgOptions): Promise<DatabaseInfoResult>;
|
|
11
|
-
export declare function listPgCredentials(appIdentity: string, addonIdentity?: string, options?: PgOptions): Promise<PostgresDatabaseListCredentialsResult>;
|
|
12
|
-
export declare function describePgMaintenance(appIdentity: string, addonIdentity?: string, options?: PgOptions): Promise<MaintenanceInfoResult>;
|
|
13
|
-
export declare function listPgTransfers(appIdentity: string, options?: PgOptions): Promise<TransferListByAppResult>;
|
|
14
|
-
export declare function runPgUpgrade(appIdentity: string, addonIdentity: string | undefined, body?: PgUpgradeOpts, options?: PgOptions): Promise<DatabaseRunUpgradeResult>;
|
|
15
|
-
export declare function preparePgUpgrade(appIdentity: string, addonIdentity: string | undefined, body?: PgUpgradeOpts, options?: PgOptions): Promise<DatabasePrepareUpgradeResult>;
|
package/dist/compositions/pg.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { createDataClient } from '../services/data.js';
|
|
2
|
-
import { createPlatformClient } from '../services/platform.js';
|
|
3
|
-
export async function describePgDatabase(appIdentity, addonIdentity, options = {}) {
|
|
4
|
-
options.signal?.throwIfAborted();
|
|
5
|
-
const addonId = await resolveAddonId(appIdentity, addonIdentity, options.clientOptions);
|
|
6
|
-
const data = createDataClient(options.clientOptions);
|
|
7
|
-
return data.database.info(addonId);
|
|
8
|
-
}
|
|
9
|
-
export async function listPgCredentials(appIdentity, addonIdentity, options = {}) {
|
|
10
|
-
options.signal?.throwIfAborted();
|
|
11
|
-
const addonId = await resolveAddonId(appIdentity, addonIdentity, options.clientOptions);
|
|
12
|
-
const data = createDataClient(options.clientOptions);
|
|
13
|
-
return data.postgresDatabase.listCredentials(addonId);
|
|
14
|
-
}
|
|
15
|
-
export async function describePgMaintenance(appIdentity, addonIdentity, options = {}) {
|
|
16
|
-
options.signal?.throwIfAborted();
|
|
17
|
-
const addonId = await resolveAddonId(appIdentity, addonIdentity, options.clientOptions);
|
|
18
|
-
const data = createDataClient(options.clientOptions);
|
|
19
|
-
return data.maintenance.info(addonId);
|
|
20
|
-
}
|
|
21
|
-
export async function listPgTransfers(appIdentity, options = {}) {
|
|
22
|
-
options.signal?.throwIfAborted();
|
|
23
|
-
const data = createDataClient(options.clientOptions);
|
|
24
|
-
return data.transfer.listByApp(appIdentity);
|
|
25
|
-
}
|
|
26
|
-
export async function runPgUpgrade(appIdentity, addonIdentity, body = {}, options = {}) {
|
|
27
|
-
options.signal?.throwIfAborted();
|
|
28
|
-
const addonId = await resolveAddonId(appIdentity, addonIdentity, options.clientOptions);
|
|
29
|
-
const data = createDataClient(options.clientOptions);
|
|
30
|
-
// Cast: routes.js declares hasRequestBody for runUpgrade but the generated
|
|
31
|
-
// HerokuClient interface omits the body param (Shogun spec lacks a request schema).
|
|
32
|
-
const runUpgrade = data.database.runUpgrade;
|
|
33
|
-
return runUpgrade(addonId, body);
|
|
34
|
-
}
|
|
35
|
-
export async function preparePgUpgrade(appIdentity, addonIdentity, body = {}, options = {}) {
|
|
36
|
-
options.signal?.throwIfAborted();
|
|
37
|
-
const addonId = await resolveAddonId(appIdentity, addonIdentity, options.clientOptions);
|
|
38
|
-
const data = createDataClient(options.clientOptions);
|
|
39
|
-
// See note on runPgUpgrade.
|
|
40
|
-
const prepareUpgrade = data.database.prepareUpgrade;
|
|
41
|
-
return prepareUpgrade(addonId, body);
|
|
42
|
-
}
|
|
43
|
-
async function resolveAddonId(appIdentity, addonIdentity, clientOptions) {
|
|
44
|
-
const platform = createPlatformClient(clientOptions);
|
|
45
|
-
const matches = await platform.addOnAttachment.resolution({
|
|
46
|
-
// eslint-disable-next-line camelcase
|
|
47
|
-
addon_attachment: addonIdentity ?? 'DATABASE_URL',
|
|
48
|
-
app: appIdentity,
|
|
49
|
-
});
|
|
50
|
-
const attachment = matches[0];
|
|
51
|
-
const addonId = attachment?.addon?.id;
|
|
52
|
-
if (!addonId) {
|
|
53
|
-
throw new Error(`Could not resolve add-on for ${appIdentity}${addonIdentity ? `::${addonIdentity}` : ''}`);
|
|
54
|
-
}
|
|
55
|
-
return addonId;
|
|
56
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { HerokuApiClientOptions } from '@heroku/api-client';
|
|
2
|
-
import type { App, PipelineCoupling, PipelinePromotion, PipelinePromotionCreateOpts, PipelinePromotionTarget } from '@heroku/types/3.sdk';
|
|
3
|
-
export type PipelineWarning = {
|
|
4
|
-
limit: number;
|
|
5
|
-
pipelineId: string;
|
|
6
|
-
type: 'apps_truncated';
|
|
7
|
-
};
|
|
8
|
-
export type ListPipelineAppsOptions = {
|
|
9
|
-
clientOptions?: HerokuApiClientOptions;
|
|
10
|
-
onWarning?: (warning: PipelineWarning) => void;
|
|
11
|
-
signal?: AbortSignal;
|
|
12
|
-
};
|
|
13
|
-
export type AppWithPipelineCoupling = App & {
|
|
14
|
-
pipelineCoupling: PipelineCoupling;
|
|
15
|
-
};
|
|
16
|
-
export type ReleaseStreamContext = {
|
|
17
|
-
stream: ReadableStream<Uint8Array>;
|
|
18
|
-
target: PipelinePromotionTarget;
|
|
19
|
-
};
|
|
20
|
-
export type PromotePipelineOptions = {
|
|
21
|
-
clientOptions?: HerokuApiClientOptions;
|
|
22
|
-
intervalMs?: number;
|
|
23
|
-
onReleaseStream?: (context: ReleaseStreamContext) => Promise<void> | void;
|
|
24
|
-
releaseStreamMaxAttempts?: number;
|
|
25
|
-
signal?: AbortSignal;
|
|
26
|
-
timeoutMs?: number;
|
|
27
|
-
};
|
|
28
|
-
export type PromotePipelineResult = {
|
|
29
|
-
promotion: PipelinePromotion;
|
|
30
|
-
targets: PipelinePromotionTarget[];
|
|
31
|
-
};
|
|
32
|
-
export declare function promotePipeline(body: PipelinePromotionCreateOpts, options?: PromotePipelineOptions): Promise<PromotePipelineResult>;
|
|
33
|
-
export declare function listPipelineApps(pipelineId: string, options?: ListPipelineAppsOptions): Promise<AppWithPipelineCoupling[]>;
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { HerokuApiClient } from '@heroku/api-client';
|
|
2
|
-
import { createPlatformClient } from '../services/platform.js';
|
|
3
|
-
const APPS_FILTER_LIMIT = 1000;
|
|
4
|
-
const DEFAULT_INTERVAL_MS = 1000;
|
|
5
|
-
const DEFAULT_RELEASE_STREAM_MAX_ATTEMPTS = 100;
|
|
6
|
-
export async function promotePipeline(body, options = {}) {
|
|
7
|
-
const { clientOptions, intervalMs = DEFAULT_INTERVAL_MS, onReleaseStream, releaseStreamMaxAttempts = DEFAULT_RELEASE_STREAM_MAX_ATTEMPTS, signal, timeoutMs, } = options;
|
|
8
|
-
const platformClient = createPlatformClient(clientOptions);
|
|
9
|
-
const promotion = await platformClient.pipelinePromotion.create(body);
|
|
10
|
-
if (!promotion.id) {
|
|
11
|
-
throw new Error('Pipeline promotion response did not include an id');
|
|
12
|
-
}
|
|
13
|
-
const deadline = timeoutMs === undefined ? undefined : Date.now() + timeoutMs;
|
|
14
|
-
let streamHandled = false;
|
|
15
|
-
while (true) {
|
|
16
|
-
signal?.throwIfAborted();
|
|
17
|
-
// eslint-disable-next-line no-await-in-loop
|
|
18
|
-
const targets = await platformClient.pipelinePromotionTarget.list(promotion.id);
|
|
19
|
-
if (targets.every(target => target.status !== 'pending')) {
|
|
20
|
-
return { promotion, targets };
|
|
21
|
-
}
|
|
22
|
-
if (onReleaseStream
|
|
23
|
-
&& !streamHandled
|
|
24
|
-
&& targets.length === 1
|
|
25
|
-
&& targets[0].release?.id
|
|
26
|
-
&& targets[0].app?.id) {
|
|
27
|
-
streamHandled = true;
|
|
28
|
-
const target = targets[0];
|
|
29
|
-
// eslint-disable-next-line no-await-in-loop
|
|
30
|
-
const release = await platformClient.release.info(target.app.id, target.release.id);
|
|
31
|
-
if (release.output_stream_url) {
|
|
32
|
-
// eslint-disable-next-line no-await-in-loop
|
|
33
|
-
const stream = await fetchReleaseOutput(release.output_stream_url, releaseStreamMaxAttempts, intervalMs, signal);
|
|
34
|
-
// eslint-disable-next-line no-await-in-loop
|
|
35
|
-
await onReleaseStream({ stream, target });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (deadline !== undefined && Date.now() >= deadline) {
|
|
39
|
-
throw new Error(`Pipeline promotion ${promotion.id} did not reach a terminal state within ${timeoutMs}ms`);
|
|
40
|
-
}
|
|
41
|
-
// eslint-disable-next-line no-await-in-loop
|
|
42
|
-
await wait(intervalMs, signal);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
export async function listPipelineApps(pipelineId, options = {}) {
|
|
46
|
-
options.signal?.throwIfAborted();
|
|
47
|
-
const platformClient = createPlatformClient(options.clientOptions);
|
|
48
|
-
const allCouplings = await platformClient.pipelineCoupling.listByPipeline(pipelineId);
|
|
49
|
-
// Drop malformed couplings (no app id) before issuing the bulk filter call.
|
|
50
|
-
const couplings = allCouplings.filter(coupling => coupling.app?.id);
|
|
51
|
-
if (couplings.length === 0) {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
let couplingsToResolve = couplings;
|
|
55
|
-
if (couplings.length > APPS_FILTER_LIMIT) {
|
|
56
|
-
if (!options.onWarning) {
|
|
57
|
-
throw new Error(`Pipeline ${pipelineId} has more than ${APPS_FILTER_LIMIT} apps. `
|
|
58
|
-
+ 'Pass an onWarning handler to opt into a truncated result.');
|
|
59
|
-
}
|
|
60
|
-
options.onWarning({ limit: APPS_FILTER_LIMIT, pipelineId, type: 'apps_truncated' });
|
|
61
|
-
couplingsToResolve = couplings.slice(0, APPS_FILTER_LIMIT);
|
|
62
|
-
}
|
|
63
|
-
options.signal?.throwIfAborted();
|
|
64
|
-
// /filters/apps is a Platform bulk endpoint that's not in the SDK route
|
|
65
|
-
// registry, so call it through a raw HerokuApiClient. It accepts the
|
|
66
|
-
// standard platform Accept header but uses a different `.filters` suffix.
|
|
67
|
-
const apiClient = new HerokuApiClient({
|
|
68
|
-
...options.clientOptions,
|
|
69
|
-
service: 'platform',
|
|
70
|
-
});
|
|
71
|
-
const ids = couplingsToResolve.map(coupling => coupling.app.id);
|
|
72
|
-
const response = await apiClient.post('/filters/apps', { in: { id: ids } }, {
|
|
73
|
-
headers: {
|
|
74
|
-
Accept: 'application/vnd.heroku+json; version=3.filters',
|
|
75
|
-
Range: `id ..; max=${APPS_FILTER_LIMIT};`,
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
const apps = (await response.json());
|
|
79
|
-
const couplingByAppId = new Map();
|
|
80
|
-
for (const coupling of couplingsToResolve) {
|
|
81
|
-
couplingByAppId.set(coupling.app.id, coupling);
|
|
82
|
-
}
|
|
83
|
-
return apps.map(app => ({
|
|
84
|
-
...app,
|
|
85
|
-
pipelineCoupling: couplingByAppId.get(app.id),
|
|
86
|
-
}));
|
|
87
|
-
}
|
|
88
|
-
async function fetchReleaseOutput(url, maxAttempts, intervalMs, signal) {
|
|
89
|
-
const parsed = new URL(url);
|
|
90
|
-
const path = `${parsed.pathname}${parsed.search}`;
|
|
91
|
-
// The release output URL points at a third-party stream host (e.g. busl).
|
|
92
|
-
// Use a custom-service client so the platform prefixUrl and bearer token
|
|
93
|
-
// don't leak across origins.
|
|
94
|
-
const buslClient = new HerokuApiClient({
|
|
95
|
-
baseUrl: parsed.origin,
|
|
96
|
-
service: 'custom',
|
|
97
|
-
token: '',
|
|
98
|
-
});
|
|
99
|
-
let attempt = 0;
|
|
100
|
-
while (true) {
|
|
101
|
-
signal?.throwIfAborted();
|
|
102
|
-
attempt++;
|
|
103
|
-
let response;
|
|
104
|
-
try {
|
|
105
|
-
// eslint-disable-next-line no-await-in-loop
|
|
106
|
-
response = await buslClient.stream(path, { headers: { Accept: '*/*' } });
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
// Treat HTTP errors thrown by the api-client as a retryable miss.
|
|
110
|
-
response = undefined;
|
|
111
|
-
}
|
|
112
|
-
if (response?.ok && response.body) {
|
|
113
|
-
return response.body;
|
|
114
|
-
}
|
|
115
|
-
if (response?.body) {
|
|
116
|
-
// Drain so the connection can be reused.
|
|
117
|
-
// eslint-disable-next-line no-await-in-loop
|
|
118
|
-
await response.body.cancel().catch(() => { });
|
|
119
|
-
}
|
|
120
|
-
if (attempt >= maxAttempts) {
|
|
121
|
-
throw new Error('stream release output not available');
|
|
122
|
-
}
|
|
123
|
-
// eslint-disable-next-line no-await-in-loop
|
|
124
|
-
await wait(intervalMs, signal);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
function wait(ms, signal) {
|
|
128
|
-
return new Promise((resolve, reject) => {
|
|
129
|
-
function onAbort() {
|
|
130
|
-
clearTimeout(timer);
|
|
131
|
-
reject(signal.reason ?? new Error('Aborted'));
|
|
132
|
-
}
|
|
133
|
-
const timer = setTimeout(() => {
|
|
134
|
-
signal?.removeEventListener('abort', onAbort);
|
|
135
|
-
resolve();
|
|
136
|
-
}, ms);
|
|
137
|
-
if (signal) {
|
|
138
|
-
if (signal.aborted) {
|
|
139
|
-
clearTimeout(timer);
|
|
140
|
-
reject(signal.reason ?? new Error('Aborted'));
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
signal.addEventListener('abort', onAbort, { once: true });
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { BackupCreateResult } from '@heroku/types/data';
|
|
2
|
-
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
3
|
-
export type BackupOptions = {
|
|
4
|
-
signal?: AbortSignal;
|
|
5
|
-
};
|
|
6
|
-
export declare function create(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: BackupOptions): Promise<BackupCreateResult>;
|
|
7
|
-
export declare const backupExtensions: import("../../index.js").ResourceExtension<"data", "backup", {
|
|
8
|
-
create: (appIdentity: string, addonIdentity?: string, options?: BackupOptions) => Promise<BackupCreateResult>;
|
|
9
|
-
}>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
-
import { resolvePgDatabase } from './internal/resolve-pg-database.js';
|
|
3
|
-
export async function create(ctx, appIdentity, addonIdentity, options = {}) {
|
|
4
|
-
options.signal?.throwIfAborted();
|
|
5
|
-
const addon = await resolvePgDatabase(ctx, { appIdentity, input: addonIdentity, ...options });
|
|
6
|
-
return ctx.data.backup.create(addon.id);
|
|
7
|
-
}
|
|
8
|
-
export const backupExtensions = extendResource('data', 'backup', ctx => ({
|
|
9
|
-
create: (appIdentity, addonIdentity, options) => create(ctx, appIdentity, addonIdentity, options),
|
|
10
|
-
}));
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export async function resolveAddonId(platform, appIdentity, addonIdentity) {
|
|
2
|
-
const matches = await platform.addOnAttachment.resolution({
|
|
3
|
-
// eslint-disable-next-line camelcase
|
|
4
|
-
addon_attachment: addonIdentity ?? 'DATABASE_URL',
|
|
5
|
-
app: appIdentity,
|
|
6
|
-
});
|
|
7
|
-
const attachment = matches[0];
|
|
8
|
-
const addonId = attachment?.addon?.id;
|
|
9
|
-
if (!addonId) {
|
|
10
|
-
throw new Error(`Could not resolve add-on for ${appIdentity}${addonIdentity ? `::${addonIdentity}` : ''}`);
|
|
11
|
-
}
|
|
12
|
-
return addonId;
|
|
13
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { PostgresCredentialInfoResult, PostgresCredentialListResult } from '@heroku/types/data';
|
|
2
|
-
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
3
|
-
export type PostgresCredentialOptions = {
|
|
4
|
-
signal?: AbortSignal;
|
|
5
|
-
};
|
|
6
|
-
export declare function list(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: PostgresCredentialOptions): Promise<PostgresCredentialListResult>;
|
|
7
|
-
export declare function info(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, credName: string, addonIdentity?: string, options?: PostgresCredentialOptions): Promise<PostgresCredentialInfoResult>;
|
|
8
|
-
export declare const postgresCredentialExtensions: import("../../index.js").ResourceExtension<"data", "postgresCredential", {
|
|
9
|
-
info: (appIdentity: string, credName: string, addonIdentity?: string, options?: PostgresCredentialOptions) => Promise<PostgresCredentialInfoResult>;
|
|
10
|
-
list: (appIdentity: string, addonIdentity?: string, options?: PostgresCredentialOptions) => Promise<PostgresCredentialListResult>;
|
|
11
|
-
}>;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
-
import { resolvePgDatabase } from './internal/resolve-pg-database.js';
|
|
3
|
-
export async function list(ctx, appIdentity, addonIdentity, options = {}) {
|
|
4
|
-
options.signal?.throwIfAborted();
|
|
5
|
-
const addon = await resolvePgDatabase(ctx, { appIdentity, input: addonIdentity, ...options });
|
|
6
|
-
return ctx.data.postgresCredential.list(addon.id);
|
|
7
|
-
}
|
|
8
|
-
export async function info(ctx, appIdentity, credName, addonIdentity, options = {}) {
|
|
9
|
-
options.signal?.throwIfAborted();
|
|
10
|
-
const addon = await resolvePgDatabase(ctx, { appIdentity, input: addonIdentity, ...options });
|
|
11
|
-
return ctx.data.postgresCredential.info(addon.id, credName);
|
|
12
|
-
}
|
|
13
|
-
export const postgresCredentialExtensions = extendResource('data', 'postgresCredential', ctx => ({
|
|
14
|
-
info: (appIdentity, credName, addonIdentity, options) => info(ctx, appIdentity, credName, addonIdentity, options),
|
|
15
|
-
list: (appIdentity, addonIdentity, options) => list(ctx, appIdentity, addonIdentity, options),
|
|
16
|
-
}));
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { PostgresInfoResult } from '@heroku/types/data';
|
|
2
|
-
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
3
|
-
export type PostgresOptions = {
|
|
4
|
-
signal?: AbortSignal;
|
|
5
|
-
};
|
|
6
|
-
export declare function info(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: PostgresOptions): Promise<PostgresInfoResult>;
|
|
7
|
-
export declare const postgresExtensions: import("../../index.js").ResourceExtension<"data", "postgres", {
|
|
8
|
-
info: (appIdentity: string, addonIdentity?: string, options?: PostgresOptions) => Promise<PostgresInfoResult>;
|
|
9
|
-
}>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
-
import { resolvePgDatabase } from './internal/resolve-pg-database.js';
|
|
3
|
-
export async function info(ctx, appIdentity, addonIdentity, options = {}) {
|
|
4
|
-
options.signal?.throwIfAborted();
|
|
5
|
-
const addon = await resolvePgDatabase(ctx, { appIdentity, input: addonIdentity, ...options });
|
|
6
|
-
return ctx.data.postgres.info(addon.id);
|
|
7
|
-
}
|
|
8
|
-
export const postgresExtensions = extendResource('data', 'postgres', ctx => ({
|
|
9
|
-
info: (appIdentity, addonIdentity, options) => info(ctx, appIdentity, addonIdentity, options),
|
|
10
|
-
}));
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { TransferScheduleListResult } from '@heroku/types/data';
|
|
2
|
-
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
3
|
-
export type TransferScheduleOptions = {
|
|
4
|
-
signal?: AbortSignal;
|
|
5
|
-
};
|
|
6
|
-
export declare function list(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: TransferScheduleOptions): Promise<TransferScheduleListResult>;
|
|
7
|
-
export declare const transferScheduleExtensions: import("../../index.js").ResourceExtension<"data", "transferSchedule", {
|
|
8
|
-
list: (appIdentity: string, addonIdentity?: string, options?: TransferScheduleOptions) => Promise<TransferScheduleListResult>;
|
|
9
|
-
}>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
-
import { resolvePgDatabase } from './internal/resolve-pg-database.js';
|
|
3
|
-
export async function list(ctx, appIdentity, addonIdentity, options = {}) {
|
|
4
|
-
options.signal?.throwIfAborted();
|
|
5
|
-
const addon = await resolvePgDatabase(ctx, { appIdentity, input: addonIdentity, ...options });
|
|
6
|
-
return ctx.data.transferSchedule.list(addon.id);
|
|
7
|
-
}
|
|
8
|
-
export const transferScheduleExtensions = extendResource('data', 'transferSchedule', ctx => ({
|
|
9
|
-
list: (appIdentity, addonIdentity, options) => list(ctx, appIdentity, addonIdentity, options),
|
|
10
|
-
}));
|