@heroku/sdk 0.12.2 → 0.12.4
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-credential/index.d.ts +0 -1
- package/dist/resources/data/database-credential/index.js +0 -1
- package/dist/resources/data/database-credential/list.d.ts +0 -15
- package/dist/resources/data/database-credential/list.js +2 -20
- package/dist/resources/data/database-credential/rotate.d.ts +1 -3
- package/dist/resources/data/internal/postgres-utils.d.ts +27 -11
- package/dist/resources/data/internal/postgres-utils.js +19 -7
- package/dist/resources/data/internal/resolve-pg-database.js +2 -2
- package/dist/resources/data/postgres-database.d.ts +107 -1
- package/dist/resources/data/postgres-database.js +207 -1
- package/dist/resources/data/postgres-migration.d.ts +182 -0
- package/dist/resources/data/postgres-migration.js +313 -0
- package/dist/resources/data/postgres-pool.d.ts +77 -0
- package/dist/resources/data/postgres-pool.js +50 -0
- package/dist/resources/data/postgres-quota.d.ts +45 -0
- package/dist/resources/data/postgres-quota.js +61 -0
- package/dist/resources/data/postgres-settings.d.ts +33 -0
- package/dist/resources/data/postgres-settings.js +47 -0
- package/dist/resources/data/postgres.d.ts +229 -0
- package/dist/resources/data/postgres.js +273 -0
- package/dist/resources/data/redis/index.d.ts +1 -1
- package/dist/resources/extensions/data.d.ts +5 -0
- package/dist/resources/extensions/data.js +5 -0
- package/dist/resources/platform/add-on/destroy-and-wait.d.ts +2 -3
- package/dist/resources/platform/add-on/destroy-and-wait.js +7 -1
- package/dist/resources/platform/add-on/errors.d.ts +35 -2
- package/dist/resources/platform/add-on/errors.js +52 -0
- package/dist/resources/platform/add-on/index.d.ts +3 -3
- package/dist/resources/platform/add-on/index.js +1 -1
- package/dist/resources/platform/add-on/types.d.ts +14 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
+
import { withSignal } from '../../core/with-signal.js';
|
|
3
|
+
import { resolveAddonInternal } from '../platform/add-on/resolve.js';
|
|
4
|
+
import { getPostgresServiceName, isAdvancedDatabase, NotAdvancedDatabaseError } from './internal/postgres-utils.js';
|
|
5
|
+
async function resolveTieredAddon(ctx, addonIdentity, options) {
|
|
6
|
+
const { appIdentity, signal } = options;
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
// Bind the signal so the resolve request aborts in flight.
|
|
9
|
+
const platform = withSignal(ctx.platform, signal);
|
|
10
|
+
const addon = await resolveAddonInternal(platform, addonIdentity, {
|
|
11
|
+
addonService: getPostgresServiceName(), appIdentity,
|
|
12
|
+
});
|
|
13
|
+
if (!isAdvancedDatabase(addon)) {
|
|
14
|
+
throw new NotAdvancedDatabaseError(addon, `You can only manage quotas on Advanced-tier databases. ${addon.name} isn't an Advanced-tier database.`);
|
|
15
|
+
}
|
|
16
|
+
return addon;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Lists quotas on an Advanced-tier Postgres database.
|
|
20
|
+
*
|
|
21
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
22
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
23
|
+
*/
|
|
24
|
+
export async function list(ctx, addonIdentity, options = {}) {
|
|
25
|
+
const addon = await resolveTieredAddon(ctx, addonIdentity, options);
|
|
26
|
+
// Bind the signal so the list request aborts in flight.
|
|
27
|
+
const data = withSignal(ctx.data, options.signal);
|
|
28
|
+
const quotas = await data.postgresQuota.list(addon.id);
|
|
29
|
+
return { addon, quotas };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Looks up a single quota on an Advanced-tier Postgres database.
|
|
33
|
+
*
|
|
34
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
35
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
36
|
+
*/
|
|
37
|
+
export async function info(ctx, addonIdentity, quotaType, options = {}) {
|
|
38
|
+
const addon = await resolveTieredAddon(ctx, addonIdentity, options);
|
|
39
|
+
// Bind the signal so the info request aborts in flight.
|
|
40
|
+
const data = withSignal(ctx.data, options.signal);
|
|
41
|
+
const quota = await data.postgresQuota.info(addon.id, quotaType);
|
|
42
|
+
return { addon, quota };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Updates a quota's settings on an Advanced-tier Postgres database.
|
|
46
|
+
*
|
|
47
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
48
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
49
|
+
*/
|
|
50
|
+
export async function update(ctx, addonIdentity, quotaType, body, options = {}) {
|
|
51
|
+
const addon = await resolveTieredAddon(ctx, addonIdentity, options);
|
|
52
|
+
// Bind the signal so the update request aborts in flight.
|
|
53
|
+
const data = withSignal(ctx.data, options.signal);
|
|
54
|
+
const quota = await data.postgresQuota.update(addon.id, quotaType, body);
|
|
55
|
+
return { addon, quota };
|
|
56
|
+
}
|
|
57
|
+
export const postgresQuotaExtensions = extendResource('data', 'postgresQuota', ctx => ({
|
|
58
|
+
info: (addonIdentity, quotaType, options) => info(ctx, addonIdentity, quotaType, options),
|
|
59
|
+
list: (addonIdentity, options) => list(ctx, addonIdentity, options),
|
|
60
|
+
update: (addonIdentity, quotaType, body, options) => update(ctx, addonIdentity, quotaType, body, options),
|
|
61
|
+
}));
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { PostgresSettingsInfoResult, PostgresSettingsUpdateOpts, PostgresSettingsUpdateResult } from '@heroku/types/data';
|
|
2
|
+
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
3
|
+
import type { ResolvedAddOn } from '../platform/add-on/types.js';
|
|
4
|
+
export type PostgresSettingsOptions = {
|
|
5
|
+
appIdentity?: string;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
};
|
|
8
|
+
export type GetPostgresSettingsResult = {
|
|
9
|
+
addon: ResolvedAddOn;
|
|
10
|
+
settings: PostgresSettingsInfoResult;
|
|
11
|
+
};
|
|
12
|
+
export type UpdatePostgresSettingsResult = {
|
|
13
|
+
addon: ResolvedAddOn;
|
|
14
|
+
settings: PostgresSettingsUpdateResult;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Reads the settings of an Advanced-tier Postgres database.
|
|
18
|
+
*
|
|
19
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
20
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
21
|
+
*/
|
|
22
|
+
export declare function info(ctx: Pick<ResourceCtx, 'data' | 'platform'>, addonIdentity: string, options?: PostgresSettingsOptions): Promise<GetPostgresSettingsResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Updates the settings of an Advanced-tier Postgres database.
|
|
25
|
+
*
|
|
26
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
27
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
28
|
+
*/
|
|
29
|
+
export declare function update(ctx: Pick<ResourceCtx, 'data' | 'platform'>, addonIdentity: string, body: PostgresSettingsUpdateOpts, options?: PostgresSettingsOptions): Promise<UpdatePostgresSettingsResult>;
|
|
30
|
+
export declare const postgresSettingsExtensions: import("../../core/extend-resource.js").ResourceExtension<"data", "postgresSettings", {
|
|
31
|
+
info: (addonIdentity: string, options?: PostgresSettingsOptions) => Promise<GetPostgresSettingsResult>;
|
|
32
|
+
update: (addonIdentity: string, body: PostgresSettingsUpdateOpts, options?: PostgresSettingsOptions) => Promise<UpdatePostgresSettingsResult>;
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { extendResource } from '../../core/extend-resource.js';
|
|
2
|
+
import { withSignal } from '../../core/with-signal.js';
|
|
3
|
+
import { resolveAddonInternal } from '../platform/add-on/resolve.js';
|
|
4
|
+
import { getPostgresServiceName, isAdvancedDatabase, NotAdvancedDatabaseError } from './internal/postgres-utils.js';
|
|
5
|
+
async function resolveTieredAddon(ctx, addonIdentity, options) {
|
|
6
|
+
const { appIdentity, signal } = options;
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
// Bind the signal so the resolve request aborts in flight.
|
|
9
|
+
const platform = withSignal(ctx.platform, signal);
|
|
10
|
+
const addon = await resolveAddonInternal(platform, addonIdentity, {
|
|
11
|
+
addonService: getPostgresServiceName(), appIdentity,
|
|
12
|
+
});
|
|
13
|
+
if (!isAdvancedDatabase(addon)) {
|
|
14
|
+
throw new NotAdvancedDatabaseError(addon, `You can only manage settings on Advanced-tier databases. ${addon.name} isn't an Advanced-tier database.`);
|
|
15
|
+
}
|
|
16
|
+
return addon;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads the settings of an Advanced-tier Postgres database.
|
|
20
|
+
*
|
|
21
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
22
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
23
|
+
*/
|
|
24
|
+
export async function info(ctx, addonIdentity, options = {}) {
|
|
25
|
+
const addon = await resolveTieredAddon(ctx, addonIdentity, options);
|
|
26
|
+
// Bind the signal so the info request aborts in flight.
|
|
27
|
+
const data = withSignal(ctx.data, options.signal);
|
|
28
|
+
const settings = await data.postgresSettings.info(addon.id);
|
|
29
|
+
return { addon, settings };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Updates the settings of an Advanced-tier Postgres database.
|
|
33
|
+
*
|
|
34
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved addon) if
|
|
35
|
+
* `addonIdentity` doesn't resolve to an Advanced-tier database.
|
|
36
|
+
*/
|
|
37
|
+
export async function update(ctx, addonIdentity, body, options = {}) {
|
|
38
|
+
const addon = await resolveTieredAddon(ctx, addonIdentity, options);
|
|
39
|
+
// Bind the signal so the update request aborts in flight.
|
|
40
|
+
const data = withSignal(ctx.data, options.signal);
|
|
41
|
+
const settings = await data.postgresSettings.update(addon.id, body);
|
|
42
|
+
return { addon, settings };
|
|
43
|
+
}
|
|
44
|
+
export const postgresSettingsExtensions = extendResource('data', 'postgresSettings', ctx => ({
|
|
45
|
+
info: (addonIdentity, options) => info(ctx, addonIdentity, options),
|
|
46
|
+
update: (addonIdentity, body, options) => update(ctx, addonIdentity, body, options),
|
|
47
|
+
}));
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { AddOn } from '@heroku/types/3.sdk';
|
|
2
|
+
import type { PostgresPoolCreateResult, PostgresRunUpgradeOpts, PostgresRunUpgradeResult, PostgresWaitStatusResult } from '@heroku/types/data';
|
|
3
|
+
import type { ResourceCtx } from '../../core/extend-resource.js';
|
|
4
|
+
import type { ResolvedAddOn } from '../platform/add-on/types.js';
|
|
5
|
+
import type { ResolvedPgDatabase } from './internal/resolve-pg-database.js';
|
|
6
|
+
export type RunUpgradeOptions = {
|
|
7
|
+
beforeRunUpgrade?: (preview: {
|
|
8
|
+
addon: ResolvedPgDatabase;
|
|
9
|
+
currentVersion: string;
|
|
10
|
+
}) => Promise<void> | void;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
};
|
|
13
|
+
export type RunUpgradeResult = {
|
|
14
|
+
addon: ResolvedPgDatabase;
|
|
15
|
+
result: PostgresRunUpgradeResult;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Resolves a Postgres database by attachment identity and runs a version upgrade.
|
|
19
|
+
*
|
|
20
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved add-on) if the
|
|
21
|
+
* database isn't an Advanced-tier database. If provided, `beforeRunUpgrade`
|
|
22
|
+
* runs after resolution/tier-checking (and the current-version lookup) but
|
|
23
|
+
* before the upgrade request fires; an abort during the hook prevents the
|
|
24
|
+
* upgrade.
|
|
25
|
+
*/
|
|
26
|
+
export declare function runUpgrade(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, body?: PostgresRunUpgradeOpts, options?: RunUpgradeOptions): Promise<RunUpgradeResult>;
|
|
27
|
+
export type WaitForReadyOptions = {
|
|
28
|
+
/**
|
|
29
|
+
* How many 404s from `wait_status` to tolerate as "still provisioning"
|
|
30
|
+
* before rethrowing. Defaults to 20; this is a total budget across the whole
|
|
31
|
+
* wait, not reset between polls.
|
|
32
|
+
*/
|
|
33
|
+
notFoundRetries?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Fires once per poll with the latest status (including the synthetic
|
|
36
|
+
* "still provisioning" status produced while the endpoint 404s), letting
|
|
37
|
+
* callers surface a live progress message.
|
|
38
|
+
*/
|
|
39
|
+
onPoll?: (status: PostgresWaitStatusResult) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Fires once the database is resolved and tier-checked, before the wait
|
|
42
|
+
* poll begins, letting callers label a spinner with the resolved add-on
|
|
43
|
+
* (mirrors `provisionAdvanced`/`fork`'s `onProvisioning`). An abort during
|
|
44
|
+
* the hook prevents the poll.
|
|
45
|
+
*/
|
|
46
|
+
onResolved?: (addon: ResolvedPgDatabase) => Promise<void> | void;
|
|
47
|
+
/**
|
|
48
|
+
* Aborts the in-flight request and any pending poll delay.
|
|
49
|
+
*/
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
/**
|
|
52
|
+
* Maximum total time to wait before throwing. Defaults to 1 hour as a
|
|
53
|
+
* backstop against a `wait_status` that never reports ready; pass a larger
|
|
54
|
+
* value for a legitimately longer wait, or `Infinity` to poll until the
|
|
55
|
+
* database reports ready or `signal` aborts.
|
|
56
|
+
*/
|
|
57
|
+
timeoutMs?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Polling interval in milliseconds. Defaults to 5000 (5s), matching the
|
|
60
|
+
* CLI's historical `--wait-interval` default. Named `waitIntervalMs` to match
|
|
61
|
+
* the SDK-wide wait-tuning convention (`platform.addOn`, `platform.domain`,
|
|
62
|
+
* `data.postgresDatabase`).
|
|
63
|
+
*/
|
|
64
|
+
waitIntervalMs?: number;
|
|
65
|
+
};
|
|
66
|
+
export type WaitForReadyResult = {
|
|
67
|
+
addon: ResolvedPgDatabase;
|
|
68
|
+
result: PostgresWaitStatusResult;
|
|
69
|
+
};
|
|
70
|
+
export type ProvisionAdvancedBody = {
|
|
71
|
+
/** Attachment name (`--as`). */
|
|
72
|
+
as?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Extra provision options (parsed CLI `--provision-option` pairs). Merged
|
|
75
|
+
* last, so these override `level`/`version`/`high-availability`.
|
|
76
|
+
*/
|
|
77
|
+
config?: Record<string, boolean | string | undefined>;
|
|
78
|
+
/** Confirmation value for a `confirmation_required` retry. */
|
|
79
|
+
confirm?: string;
|
|
80
|
+
/** Number of follower pool instances to provision after the leader. */
|
|
81
|
+
followers?: number;
|
|
82
|
+
/** Provision the leader with a high-availability standby. */
|
|
83
|
+
highAvailability?: boolean;
|
|
84
|
+
/** Leader compute level (e.g. `advanced-0`). */
|
|
85
|
+
level: string;
|
|
86
|
+
/** Add-on name (`--name`). */
|
|
87
|
+
name?: string;
|
|
88
|
+
/** Private/Shield network variant; selects the `advanced[-private|-shield]` plan. */
|
|
89
|
+
network?: 'private' | 'shield';
|
|
90
|
+
/** Postgres version to provision. */
|
|
91
|
+
version?: string;
|
|
92
|
+
};
|
|
93
|
+
export type ForkBody = {
|
|
94
|
+
/** Attachment name (`--as`). */
|
|
95
|
+
as?: string;
|
|
96
|
+
/** Extra provision options (parsed CLI `--provision-option` pairs). Merged last. */
|
|
97
|
+
config?: Record<string, boolean | string | undefined>;
|
|
98
|
+
/** Confirmation value for a `confirmation_required` retry. */
|
|
99
|
+
confirm?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Leader compute level. When omitted, defaults to the source database's
|
|
102
|
+
* current leader pool level.
|
|
103
|
+
*/
|
|
104
|
+
level?: string;
|
|
105
|
+
/** Add-on name (`--name`). */
|
|
106
|
+
name?: string;
|
|
107
|
+
/**
|
|
108
|
+
* When set, provisions a point-in-time rollback instead of a live fork. A
|
|
109
|
+
* `Date` is formatted to the platform's UTC `YYYY-MM-DDTHH:MM:SS`; a string
|
|
110
|
+
* is passed through verbatim (matching the CLI's `--rollback-to`).
|
|
111
|
+
*/
|
|
112
|
+
recoveryTime?: Date | string;
|
|
113
|
+
};
|
|
114
|
+
export type ProvisionAdvancedOptions = Pick<WaitForReadyOptions, 'notFoundRetries' | 'onPoll' | 'signal' | 'timeoutMs' | 'waitIntervalMs'> & {
|
|
115
|
+
/**
|
|
116
|
+
* Fires once the leader add-on create request returns, before the wait
|
|
117
|
+
* poll begins (only when `wait` is set), letting callers switch to a
|
|
118
|
+
* "waiting for provisioning" display.
|
|
119
|
+
*/
|
|
120
|
+
onProvisioning?: (addon: AddOn) => Promise<void> | void;
|
|
121
|
+
/** Poll `wait_status` until the leader is ready before returning. */
|
|
122
|
+
wait?: boolean;
|
|
123
|
+
};
|
|
124
|
+
export type ForkOptions = ProvisionAdvancedOptions & {
|
|
125
|
+
/**
|
|
126
|
+
* Fires once the source database is resolved and tier-checked, before the
|
|
127
|
+
* fork create request is sent, letting callers defer a spinner until the
|
|
128
|
+
* tier check passes and label it with the resolved source add-on rather than
|
|
129
|
+
* the raw identity (mirrors `waitForReady`'s `onResolved`). An abort during
|
|
130
|
+
* the hook prevents the create.
|
|
131
|
+
*/
|
|
132
|
+
onResolved?: (source: ResolvedAddOn) => Promise<void> | void;
|
|
133
|
+
};
|
|
134
|
+
export type ProvisionAdvancedResult = {
|
|
135
|
+
/**
|
|
136
|
+
* The newly-created leader add-on. Always present: the leader is billed the
|
|
137
|
+
* moment creation succeeds, so it is reported even when a later step
|
|
138
|
+
* (`wait`/follower pool) fails, letting callers surface what was provisioned
|
|
139
|
+
* instead of retrying and provisioning a second leader.
|
|
140
|
+
*/
|
|
141
|
+
addon: AddOn;
|
|
142
|
+
/** The follower pool, when `followers` was provided and its creation succeeded. */
|
|
143
|
+
pool?: PostgresPoolCreateResult;
|
|
144
|
+
/**
|
|
145
|
+
* The error thrown while creating the follower pool, when `followers` was
|
|
146
|
+
* provided and creation failed. The leader (`addon`) still provisioned.
|
|
147
|
+
*/
|
|
148
|
+
poolError?: unknown;
|
|
149
|
+
/**
|
|
150
|
+
* The error thrown while waiting for the leader to become ready, when `wait`
|
|
151
|
+
* was set and the wait failed (timeout, abort, 404-budget exhaustion, or a
|
|
152
|
+
* transient API error). The leader (`addon`) still provisioned; the follower
|
|
153
|
+
* pool is not attempted in this case.
|
|
154
|
+
*/
|
|
155
|
+
waitError?: unknown;
|
|
156
|
+
/** The terminal wait status, when `wait` was set and the wait succeeded. */
|
|
157
|
+
waitStatus?: PostgresWaitStatusResult;
|
|
158
|
+
};
|
|
159
|
+
export type ForkResult = {
|
|
160
|
+
/**
|
|
161
|
+
* The newly-created fork/rollback add-on. Always present once creation
|
|
162
|
+
* succeeds, even if the subsequent `wait` fails (see
|
|
163
|
+
* {@link ProvisionAdvancedResult.addon}).
|
|
164
|
+
*/
|
|
165
|
+
addon: AddOn;
|
|
166
|
+
/** The resolved source database the fork was created from. */
|
|
167
|
+
source: ResolvedAddOn;
|
|
168
|
+
/**
|
|
169
|
+
* The error thrown while waiting for the fork to become ready, when `wait`
|
|
170
|
+
* was set and the wait failed. The fork (`addon`) still provisioned.
|
|
171
|
+
*/
|
|
172
|
+
waitError?: unknown;
|
|
173
|
+
/** The terminal wait status, when `wait` was set and the wait succeeded. */
|
|
174
|
+
waitStatus?: PostgresWaitStatusResult;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Resolves a Postgres database by attachment identity and polls its
|
|
178
|
+
* `wait_status` until it reports ready. `waiting: true` covers any in-progress
|
|
179
|
+
* operation (provisioning, migration, or update), not just initial provision.
|
|
180
|
+
*
|
|
181
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved add-on) if the
|
|
182
|
+
* database isn't an Advanced-tier database.
|
|
183
|
+
*/
|
|
184
|
+
export declare function waitForReady(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, addonIdentity?: string, options?: WaitForReadyOptions): Promise<WaitForReadyResult>;
|
|
185
|
+
/**
|
|
186
|
+
* Provisions a new Advanced-tier Postgres leader (and, when `followers` is
|
|
187
|
+
* given, a follower pool), replacing the CLI's `createAddon` + `createPool`
|
|
188
|
+
* sequence.
|
|
189
|
+
*
|
|
190
|
+
* A `confirmation_required` response surfaces as `AddonConfirmationRequiredError`
|
|
191
|
+
* — catch it, gather a confirmation value, and retry with `body.confirm` set
|
|
192
|
+
* (the CLI retries with `confirm = app`). When `wait` is set, polls the data
|
|
193
|
+
* `wait_status` endpoint (not the platform add-on state) until the leader is
|
|
194
|
+
* ready; the follower pool is then created against the ready leader, matching
|
|
195
|
+
* the CLI's ordering.
|
|
196
|
+
*
|
|
197
|
+
* **Partial failure.** Once the leader is created it is billed, so failures
|
|
198
|
+
* after creation are not thrown — they are reported on the result so the caller
|
|
199
|
+
* never loses track of what it provisioned. A failed `wait` sets `waitError`
|
|
200
|
+
* (and the follower pool is not attempted); a failed follower-pool create sets
|
|
201
|
+
* `poolError`. `addon` is always present on a returned result. A failure of the
|
|
202
|
+
* leader create itself still throws (nothing was provisioned). The wait polls
|
|
203
|
+
* the data `wait_status` endpoint rather than the platform add-on state, so it
|
|
204
|
+
* is bounded by a default `timeoutMs` (see {@link WaitForReadyOptions}) as a
|
|
205
|
+
* backstop against a platform-side provisioning failure that never surfaces on
|
|
206
|
+
* `wait_status`; pass a larger `timeoutMs` for a longer wait.
|
|
207
|
+
*/
|
|
208
|
+
export declare function provisionAdvanced(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, body: ProvisionAdvancedBody, options?: ProvisionAdvancedOptions): Promise<ProvisionAdvancedResult>;
|
|
209
|
+
/**
|
|
210
|
+
* Forks (or, when `recoveryTime` is set, rolls back) an existing Advanced-tier
|
|
211
|
+
* Postgres database into a new add-on on `appIdentity`.
|
|
212
|
+
*
|
|
213
|
+
* `sourceIdentity` is both resolved (to tier-check, default the level, and
|
|
214
|
+
* pick the plan) and passed verbatim into the `fork`/`rollback` config value,
|
|
215
|
+
* matching the CLI, which forks against the raw user-supplied identity. The
|
|
216
|
+
* new add-on inherits the source's plan.
|
|
217
|
+
*
|
|
218
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved source) if the
|
|
219
|
+
* source isn't an Advanced-tier database. `onResolved` fires after a
|
|
220
|
+
* successful tier check and before the create request. Confirmation and wait
|
|
221
|
+
* semantics match `provisionAdvanced`.
|
|
222
|
+
*/
|
|
223
|
+
export declare function fork(ctx: Pick<ResourceCtx, 'data' | 'platform'>, appIdentity: string, sourceIdentity: string, body?: ForkBody, options?: ForkOptions): Promise<ForkResult>;
|
|
224
|
+
export declare const postgresExtensions: import("../../core/extend-resource.js").ResourceExtension<"data", "postgres", {
|
|
225
|
+
fork: (appIdentity: string, sourceIdentity: string, body?: ForkBody, options?: ForkOptions) => Promise<ForkResult>;
|
|
226
|
+
provisionAdvanced: (appIdentity: string, body: ProvisionAdvancedBody, options?: ProvisionAdvancedOptions) => Promise<ProvisionAdvancedResult>;
|
|
227
|
+
runUpgrade: (appIdentity: string, addonIdentity?: string, body?: PostgresRunUpgradeOpts, options?: RunUpgradeOptions) => Promise<RunUpgradeResult>;
|
|
228
|
+
waitForReady: (appIdentity: string, addonIdentity?: string, options?: WaitForReadyOptions) => Promise<WaitForReadyResult>;
|
|
229
|
+
}>;
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { NotFoundError } from '@heroku/heroku-fetch';
|
|
2
|
+
import { extendResource } from '../../core/extend-resource.js';
|
|
3
|
+
import { withSignal } from '../../core/with-signal.js';
|
|
4
|
+
import { wait } from '../../utils/wait.js';
|
|
5
|
+
import { createAndWait } from '../platform/add-on/create-and-wait.js';
|
|
6
|
+
import { resolveAddonInternal } from '../platform/add-on/resolve.js';
|
|
7
|
+
import { getPostgresServiceName, isAdvancedDatabase, NotAdvancedDatabaseError } from './internal/postgres-utils.js';
|
|
8
|
+
import { resolvePgDatabase } from './internal/resolve-pg-database.js';
|
|
9
|
+
import { LEADER_POOL_NAME } from './postgres-pool.js';
|
|
10
|
+
const DEFAULT_WAIT_INTERVAL_MS = 5000;
|
|
11
|
+
/**
|
|
12
|
+
* Default upper bound on a single wait before it throws. A backstop against a
|
|
13
|
+
* `wait_status` that never flips to ready — e.g. a platform-side provisioning
|
|
14
|
+
* failure the data endpoint doesn't reflect, or an endpoint that keeps
|
|
15
|
+
* reporting `waiting: true` — so polling can't run unbounded. Generous enough
|
|
16
|
+
* (1 hour) to cover large provisions and forks; callers who legitimately need
|
|
17
|
+
* longer can pass a larger `timeoutMs`, and `Infinity` disables the bound.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_WAIT_TIMEOUT_MS = 60 * 60 * 1000;
|
|
20
|
+
/**
|
|
21
|
+
* Matches the CLI's historical 404 tolerance in `data:pg:wait`: the platform
|
|
22
|
+
* briefly 404s a freshly-provisioned database's `wait_status` before its row
|
|
23
|
+
* exists. We treat up to this many 404s as "still provisioning" (the budget is
|
|
24
|
+
* never reset), then rethrow.
|
|
25
|
+
*/
|
|
26
|
+
const DEFAULT_WAIT_NOT_FOUND_RETRIES = 20;
|
|
27
|
+
/**
|
|
28
|
+
* Synthetic wait message surfaced to `onPoll` while the `wait_status` endpoint
|
|
29
|
+
* is still 404ing during the initial provisioning window.
|
|
30
|
+
*/
|
|
31
|
+
const PROVISIONING_WAIT_MESSAGE = 'Waiting to provision...';
|
|
32
|
+
/**
|
|
33
|
+
* Resolves a Postgres database by attachment identity and runs a version upgrade.
|
|
34
|
+
*
|
|
35
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved add-on) if the
|
|
36
|
+
* database isn't an Advanced-tier database. If provided, `beforeRunUpgrade`
|
|
37
|
+
* runs after resolution/tier-checking (and the current-version lookup) but
|
|
38
|
+
* before the upgrade request fires; an abort during the hook prevents the
|
|
39
|
+
* upgrade.
|
|
40
|
+
*/
|
|
41
|
+
export async function runUpgrade(ctx, appIdentity, addonIdentity, body = {}, options = {}) {
|
|
42
|
+
const { beforeRunUpgrade, signal } = options;
|
|
43
|
+
signal?.throwIfAborted();
|
|
44
|
+
const addon = await resolvePgDatabase(ctx, appIdentity, { input: addonIdentity, signal });
|
|
45
|
+
if (!isAdvancedDatabase(addon)) {
|
|
46
|
+
throw new NotAdvancedDatabaseError(addon, `You can only use postgres.runUpgrade() on Advanced-tier databases. ${addon.name} isn't an Advanced-tier database.`);
|
|
47
|
+
}
|
|
48
|
+
// Bind the signal so the info and upgrade requests abort in flight.
|
|
49
|
+
const data = withSignal(ctx.data, signal);
|
|
50
|
+
const { version: currentVersion } = await data.postgres.info(addon.id);
|
|
51
|
+
await beforeRunUpgrade?.({ addon, currentVersion });
|
|
52
|
+
signal?.throwIfAborted();
|
|
53
|
+
const result = await data.postgres.runUpgrade(addon.id, body);
|
|
54
|
+
return { addon, result };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Polls `data.postgres.waitStatus` for an add-on id until it reports ready
|
|
58
|
+
* (`waiting: false`), tolerating a bounded number of 404s during the initial
|
|
59
|
+
* provisioning window (see `notFoundRetries`). Shared by `waitForReady`,
|
|
60
|
+
* `provisionAdvanced`, and `fork`.
|
|
61
|
+
*
|
|
62
|
+
* The caller's `signal` is threaded into both the in-flight request (via
|
|
63
|
+
* `withSignal`) and the poll-delay `wait()`, so aborting takes effect during
|
|
64
|
+
* either phase.
|
|
65
|
+
*/
|
|
66
|
+
async function pollPostgresReady(ctx, addonId, options = {}) {
|
|
67
|
+
const { notFoundRetries = DEFAULT_WAIT_NOT_FOUND_RETRIES, onPoll, signal, timeoutMs = DEFAULT_WAIT_TIMEOUT_MS, waitIntervalMs = DEFAULT_WAIT_INTERVAL_MS, } = options;
|
|
68
|
+
signal?.throwIfAborted();
|
|
69
|
+
const data = withSignal(ctx.data, signal);
|
|
70
|
+
// `Infinity` (deadline === Infinity) disables the bound — the check below is
|
|
71
|
+
// never true — letting callers opt out of the default timeout explicitly.
|
|
72
|
+
const deadline = Date.now() + timeoutMs;
|
|
73
|
+
let remainingNotFound = notFoundRetries;
|
|
74
|
+
/* eslint-disable no-await-in-loop */
|
|
75
|
+
while (true) {
|
|
76
|
+
signal?.throwIfAborted();
|
|
77
|
+
let status;
|
|
78
|
+
try {
|
|
79
|
+
status = await data.postgres.waitStatus(addonId);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// The platform briefly 404s a freshly-provisioned database before its
|
|
83
|
+
// row exists; absorb a bounded number of those as "still provisioning".
|
|
84
|
+
if (!(error instanceof NotFoundError) || remainingNotFound <= 0)
|
|
85
|
+
throw error;
|
|
86
|
+
remainingNotFound--;
|
|
87
|
+
status = { message: PROVISIONING_WAIT_MESSAGE, waiting: true };
|
|
88
|
+
}
|
|
89
|
+
onPoll?.(status);
|
|
90
|
+
if (!status.waiting)
|
|
91
|
+
return status;
|
|
92
|
+
if (Date.now() >= deadline) {
|
|
93
|
+
throw new Error(`Postgres database '${addonId}' did not become ready within ${timeoutMs}ms`);
|
|
94
|
+
}
|
|
95
|
+
await wait(waitIntervalMs, signal);
|
|
96
|
+
}
|
|
97
|
+
/* eslint-enable no-await-in-loop */
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolves a Postgres database by attachment identity and polls its
|
|
101
|
+
* `wait_status` until it reports ready. `waiting: true` covers any in-progress
|
|
102
|
+
* operation (provisioning, migration, or update), not just initial provision.
|
|
103
|
+
*
|
|
104
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved add-on) if the
|
|
105
|
+
* database isn't an Advanced-tier database.
|
|
106
|
+
*/
|
|
107
|
+
export async function waitForReady(ctx, appIdentity, addonIdentity, options = {}) {
|
|
108
|
+
const { onResolved, signal } = options;
|
|
109
|
+
signal?.throwIfAborted();
|
|
110
|
+
const addon = await resolvePgDatabase(ctx, appIdentity, { input: addonIdentity, signal });
|
|
111
|
+
if (!isAdvancedDatabase(addon)) {
|
|
112
|
+
throw new NotAdvancedDatabaseError(addon, `You can only use postgres.waitForReady() on Advanced-tier databases. ${addon.name} isn't an Advanced-tier database.`);
|
|
113
|
+
}
|
|
114
|
+
await onResolved?.(addon);
|
|
115
|
+
signal?.throwIfAborted();
|
|
116
|
+
const result = await pollPostgresReady(ctx, addon.id, options);
|
|
117
|
+
return { addon, result };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Builds a provision config body, dropping `undefined` values (the platform
|
|
121
|
+
* treats an absent key as unset) and letting `extra` options override the
|
|
122
|
+
* well-known keys. Booleans are preserved and serialized as-is.
|
|
123
|
+
*/
|
|
124
|
+
function buildProvisionConfig(base, extra = {}) {
|
|
125
|
+
const config = {};
|
|
126
|
+
for (const [key, value] of Object.entries({ ...base, ...extra })) {
|
|
127
|
+
if (value !== undefined)
|
|
128
|
+
config[key] = value;
|
|
129
|
+
}
|
|
130
|
+
// The platform accepts booleans here (e.g. `high-availability`), but the
|
|
131
|
+
// typed `AddOnCreateOpts.config` is `Record<string, string>`; cast through,
|
|
132
|
+
// matching the CLI's own `createAddon` helper.
|
|
133
|
+
return config;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The shared "wait for the freshly-created leader/fork to become ready" step
|
|
137
|
+
* used by {@link provisionAdvanced} and {@link fork}. Returns `{}` when `wait`
|
|
138
|
+
* isn't set.
|
|
139
|
+
*
|
|
140
|
+
* The add-on has already been created (and billed) by the time this runs, so a
|
|
141
|
+
* wait failure — timeout, abort, 404-budget exhaustion, or a transient API
|
|
142
|
+
* error — is captured as `waitError` and returned rather than thrown. That lets
|
|
143
|
+
* the caller still report the created add-on instead of losing track of it.
|
|
144
|
+
*/
|
|
145
|
+
async function waitAfterCreate(ctx, addon, options) {
|
|
146
|
+
const { notFoundRetries, onPoll, onProvisioning, signal, timeoutMs, wait: shouldWait, waitIntervalMs } = options;
|
|
147
|
+
if (!shouldWait)
|
|
148
|
+
return {};
|
|
149
|
+
try {
|
|
150
|
+
await onProvisioning?.(addon);
|
|
151
|
+
signal?.throwIfAborted();
|
|
152
|
+
const waitStatus = await pollPostgresReady(ctx, addon.id, {
|
|
153
|
+
notFoundRetries, onPoll, signal, timeoutMs, waitIntervalMs,
|
|
154
|
+
});
|
|
155
|
+
return { waitStatus };
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
return { waitError: error };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Provisions a new Advanced-tier Postgres leader (and, when `followers` is
|
|
163
|
+
* given, a follower pool), replacing the CLI's `createAddon` + `createPool`
|
|
164
|
+
* sequence.
|
|
165
|
+
*
|
|
166
|
+
* A `confirmation_required` response surfaces as `AddonConfirmationRequiredError`
|
|
167
|
+
* — catch it, gather a confirmation value, and retry with `body.confirm` set
|
|
168
|
+
* (the CLI retries with `confirm = app`). When `wait` is set, polls the data
|
|
169
|
+
* `wait_status` endpoint (not the platform add-on state) until the leader is
|
|
170
|
+
* ready; the follower pool is then created against the ready leader, matching
|
|
171
|
+
* the CLI's ordering.
|
|
172
|
+
*
|
|
173
|
+
* **Partial failure.** Once the leader is created it is billed, so failures
|
|
174
|
+
* after creation are not thrown — they are reported on the result so the caller
|
|
175
|
+
* never loses track of what it provisioned. A failed `wait` sets `waitError`
|
|
176
|
+
* (and the follower pool is not attempted); a failed follower-pool create sets
|
|
177
|
+
* `poolError`. `addon` is always present on a returned result. A failure of the
|
|
178
|
+
* leader create itself still throws (nothing was provisioned). The wait polls
|
|
179
|
+
* the data `wait_status` endpoint rather than the platform add-on state, so it
|
|
180
|
+
* is bounded by a default `timeoutMs` (see {@link WaitForReadyOptions}) as a
|
|
181
|
+
* backstop against a platform-side provisioning failure that never surfaces on
|
|
182
|
+
* `wait_status`; pass a larger `timeoutMs` for a longer wait.
|
|
183
|
+
*/
|
|
184
|
+
export async function provisionAdvanced(ctx, appIdentity, body, options = {}) {
|
|
185
|
+
const { signal } = options;
|
|
186
|
+
signal?.throwIfAborted();
|
|
187
|
+
const { as, config: extra, confirm, followers, highAvailability, level, name, network, version } = body;
|
|
188
|
+
const plan = `${getPostgresServiceName()}:advanced${network ? `-${network}` : ''}`;
|
|
189
|
+
const config = buildProvisionConfig({ 'high-availability': highAvailability, level, version }, extra);
|
|
190
|
+
const addon = await createAndWait(ctx, appIdentity, {
|
|
191
|
+
attachment: { name: as }, config, confirm, name, plan,
|
|
192
|
+
}, { signal });
|
|
193
|
+
const result = { addon };
|
|
194
|
+
const { waitError, waitStatus } = await waitAfterCreate(ctx, addon, options);
|
|
195
|
+
if (waitError !== undefined) {
|
|
196
|
+
result.waitError = waitError;
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
if (waitStatus !== undefined)
|
|
200
|
+
result.waitStatus = waitStatus;
|
|
201
|
+
if (followers && followers > 0) {
|
|
202
|
+
try {
|
|
203
|
+
result.pool = await withSignal(ctx.data, signal).postgresPool.create(addon.id, { count: followers, level });
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
result.poolError = error;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
const pad2 = (n) => String(n).padStart(2, '0');
|
|
212
|
+
/**
|
|
213
|
+
* Formats a rollback recovery time to the platform's UTC `YYYY-MM-DDTHH:MM:SS`
|
|
214
|
+
* (no `Z`, no milliseconds). A string is passed through unchanged.
|
|
215
|
+
*/
|
|
216
|
+
function formatRecoveryTime(value) {
|
|
217
|
+
if (typeof value === 'string')
|
|
218
|
+
return value;
|
|
219
|
+
return `${value.getUTCFullYear()}-${pad2(value.getUTCMonth() + 1)}-${pad2(value.getUTCDate())}T${pad2(value.getUTCHours())}:${pad2(value.getUTCMinutes())}:${pad2(value.getUTCSeconds())}`;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Forks (or, when `recoveryTime` is set, rolls back) an existing Advanced-tier
|
|
223
|
+
* Postgres database into a new add-on on `appIdentity`.
|
|
224
|
+
*
|
|
225
|
+
* `sourceIdentity` is both resolved (to tier-check, default the level, and
|
|
226
|
+
* pick the plan) and passed verbatim into the `fork`/`rollback` config value,
|
|
227
|
+
* matching the CLI, which forks against the raw user-supplied identity. The
|
|
228
|
+
* new add-on inherits the source's plan.
|
|
229
|
+
*
|
|
230
|
+
* Throws `NotAdvancedDatabaseError` (carrying the resolved source) if the
|
|
231
|
+
* source isn't an Advanced-tier database. `onResolved` fires after a
|
|
232
|
+
* successful tier check and before the create request. Confirmation and wait
|
|
233
|
+
* semantics match `provisionAdvanced`.
|
|
234
|
+
*/
|
|
235
|
+
export async function fork(ctx, appIdentity, sourceIdentity, body = {}, options = {}) {
|
|
236
|
+
const { onResolved, signal } = options;
|
|
237
|
+
signal?.throwIfAborted();
|
|
238
|
+
const { as, config: extra, confirm, name, recoveryTime } = body;
|
|
239
|
+
const platform = withSignal(ctx.platform, signal);
|
|
240
|
+
const source = await resolveAddonInternal(platform, sourceIdentity, { addonService: getPostgresServiceName(), appIdentity });
|
|
241
|
+
if (!isAdvancedDatabase(source)) {
|
|
242
|
+
throw new NotAdvancedDatabaseError(source, `You can only fork Advanced-tier databases with postgres.fork(). ${source.name} isn't an Advanced-tier database.`);
|
|
243
|
+
}
|
|
244
|
+
await onResolved?.(source);
|
|
245
|
+
let { level } = body;
|
|
246
|
+
if (level === undefined) {
|
|
247
|
+
const info = await withSignal(ctx.data, signal).postgres.info(source.id);
|
|
248
|
+
const leaderPool = info.pools.find(pool => pool.name === LEADER_POOL_NAME);
|
|
249
|
+
if (leaderPool === undefined) {
|
|
250
|
+
throw new Error(`Cannot default the fork level: source database '${source.name}' has no '${LEADER_POOL_NAME}' pool. Pass an explicit 'level'.`);
|
|
251
|
+
}
|
|
252
|
+
level = leaderPool.expected_level;
|
|
253
|
+
}
|
|
254
|
+
const config = recoveryTime === undefined
|
|
255
|
+
? buildProvisionConfig({ fork: sourceIdentity, level }, extra)
|
|
256
|
+
: buildProvisionConfig({ level, 'recovery-time': formatRecoveryTime(recoveryTime), rollback: sourceIdentity }, extra);
|
|
257
|
+
const addon = await createAndWait(ctx, appIdentity, {
|
|
258
|
+
attachment: { name: as }, config, confirm, name, plan: source.plan.name,
|
|
259
|
+
}, { signal });
|
|
260
|
+
const result = { addon, source };
|
|
261
|
+
const { waitError, waitStatus } = await waitAfterCreate(ctx, addon, options);
|
|
262
|
+
if (waitError !== undefined)
|
|
263
|
+
result.waitError = waitError;
|
|
264
|
+
else if (waitStatus !== undefined)
|
|
265
|
+
result.waitStatus = waitStatus;
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
export const postgresExtensions = extendResource('data', 'postgres', ctx => ({
|
|
269
|
+
fork: (appIdentity, sourceIdentity, body, options) => fork(ctx, appIdentity, sourceIdentity, body, options),
|
|
270
|
+
provisionAdvanced: (appIdentity, body, options) => provisionAdvanced(ctx, appIdentity, body, options),
|
|
271
|
+
runUpgrade: (appIdentity, addonIdentity, body, options) => runUpgrade(ctx, appIdentity, addonIdentity, body, options),
|
|
272
|
+
waitForReady: (appIdentity, addonIdentity, options) => waitForReady(ctx, appIdentity, addonIdentity, options),
|
|
273
|
+
}));
|
|
@@ -4,6 +4,6 @@ export { RedisAddonAmbiguousError, RedisAddonNotFoundError } from './errors.js';
|
|
|
4
4
|
export { resolveRedisByApp, type ResolveRedisByAppOptions } from './resolve-by-app.js';
|
|
5
5
|
export { waitForRedisReady, type WaitForRedisReadyOptions } from './wait-for-ready.js';
|
|
6
6
|
export declare const redisExtensions: import("../../../core/extend-resource.js").ResourceExtension<"data", "redis", {
|
|
7
|
-
resolveByApp: (appIdentity: string, options?: ResolveRedisByAppOptions) => Promise<import("
|
|
7
|
+
resolveByApp: (appIdentity: string, options?: ResolveRedisByAppOptions) => Promise<import("../postgres-database.js").ResolvedAddOn>;
|
|
8
8
|
waitForReady: (nameOrId: string, options?: WaitForRedisReadyOptions) => Promise<import("@heroku/types/data").RedisWaitResult>;
|
|
9
9
|
}>;
|
|
@@ -2,6 +2,11 @@ export { databaseCredentialExtensions } from '../data/database-credential/index.
|
|
|
2
2
|
export { databaseExtensions } from '../data/database.js';
|
|
3
3
|
export { maintenanceExtensions } from '../data/maintenance.js';
|
|
4
4
|
export { postgresDatabaseExtensions } from '../data/postgres-database.js';
|
|
5
|
+
export { isCancellable, isRunnable, type Migration, type MigrationContext, type MigrationCreateBody, MigrationInvalidError, type MigrationInvalidReason, MigrationNotCancellableError, MigrationNotRunnableError, type MigrationOptions, type MigrationSource, type MigrationStatus, type MigrationTarget, postgresMigrationExtensions, } from '../data/postgres-migration.js';
|
|
6
|
+
export { type AvailableLevel, LEADER_POOL_NAME, type LevelItem, type ListAvailableActionsOptions, MAX_POOL_INSTANCES, type PoolAction, postgresPoolExtensions, } from '../data/postgres-pool.js';
|
|
7
|
+
export { postgresQuotaExtensions } from '../data/postgres-quota.js';
|
|
8
|
+
export { postgresSettingsExtensions } from '../data/postgres-settings.js';
|
|
9
|
+
export { type ForkBody, type ForkResult, postgresExtensions, type WaitForReadyOptions as PostgresWaitForReadyOptions, type WaitForReadyResult as PostgresWaitForReadyResult, type ProvisionAdvancedBody, type ProvisionAdvancedOptions, type ProvisionAdvancedResult, type RunUpgradeOptions, type RunUpgradeResult, } from '../data/postgres.js';
|
|
5
10
|
export { redisExtensions } from '../data/redis/index.js';
|
|
6
11
|
export { type TransferSchedule, transferScheduleExtensions } from '../data/transfer-schedule.js';
|
|
7
12
|
export { backupExtensions, type CaptureAndWaitOptions, type RestoreAndWaitOptions, restoreExtensions, transferExtensions, TransferFailedError, TransferTimeoutError, type WaitForTransferOptions, } from '../data/transfer/index.js';
|