alchemy 0.63.0 → 0.64.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/bin/alchemy.js +97 -87
- package/bin/commands/init.ts +1 -1
- package/bin/services/github-workflow.ts +2 -2
- package/lib/alchemy.d.ts +4 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +10 -4
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts +3 -0
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +11 -1
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +3 -1
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts +2 -1
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/cloudflare-internal.d.ts +6 -0
- package/lib/cloudflare/bundle/cloudflare-internal.d.ts.map +1 -0
- package/lib/cloudflare/bundle/cloudflare-internal.js +39 -0
- package/lib/cloudflare/bundle/cloudflare-internal.js.map +1 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.d.ts +2 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.d.ts.map +1 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.js +9 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.js.map +1 -0
- package/lib/cloudflare/bundle/plugin-als-external.d.ts +6 -0
- package/lib/cloudflare/bundle/plugin-als-external.d.ts.map +1 -0
- package/lib/cloudflare/bundle/plugin-als-external.js +12 -0
- package/lib/cloudflare/bundle/plugin-als-external.js.map +1 -0
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.d.ts +4 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js +23 -23
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-node-compat.d.ts +11 -0
- package/lib/cloudflare/bundle/plugin-node-compat.d.ts.map +1 -0
- package/lib/cloudflare/bundle/plugin-node-compat.js +93 -0
- package/lib/cloudflare/bundle/plugin-node-compat.js.map +1 -0
- package/lib/cloudflare/cloudflare-env-proxy.js +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/d1-local-migrations.js.map +1 -1
- package/lib/cloudflare/durable-object-namespace.d.ts +1 -0
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +1 -1
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +80 -82
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-bundle.d.ts +6 -0
- package/lib/cloudflare/worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/worker-bundle.js +34 -10
- package/lib/cloudflare/worker-bundle.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +2 -1
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +24 -6
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +2 -4
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +16 -14
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/context.d.ts +3 -1
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +2 -2
- package/lib/context.js.map +1 -1
- package/lib/destroy.d.ts +8 -0
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +20 -4
- package/lib/destroy.js.map +1 -1
- package/lib/neon/project.d.ts.map +1 -1
- package/lib/neon/project.js +4 -5
- package/lib/neon/project.js.map +1 -1
- package/lib/planetscale/api/client.gen.d.ts +1750 -0
- package/lib/planetscale/api/client.gen.d.ts.map +1 -0
- package/lib/planetscale/api/client.gen.js +2401 -0
- package/lib/planetscale/api/client.gen.js.map +1 -0
- package/lib/planetscale/api/index.d.ts +3 -0
- package/lib/planetscale/api/index.d.ts.map +1 -0
- package/lib/planetscale/api/index.js +4 -0
- package/lib/planetscale/api/index.js.map +1 -0
- package/lib/planetscale/api/types.gen.d.ts +12156 -0
- package/lib/planetscale/api/types.gen.d.ts.map +1 -0
- package/lib/planetscale/api/types.gen.js +2 -0
- package/lib/planetscale/api/types.gen.js.map +1 -0
- package/lib/planetscale/branch.d.ts +5 -8
- package/lib/planetscale/branch.d.ts.map +1 -1
- package/lib/planetscale/branch.js +111 -97
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +2 -6
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +157 -118
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/index.d.ts +1 -1
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +1 -1
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +4 -7
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +71 -56
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/utils.d.ts +8 -6
- package/lib/planetscale/utils.d.ts.map +1 -1
- package/lib/planetscale/utils.js +85 -70
- package/lib/planetscale/utils.js.map +1 -1
- package/lib/scope.d.ts +5 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +11 -3
- package/lib/scope.js.map +1 -1
- package/lib/upstash/redis.js +1 -1
- package/lib/upstash/redis.js.map +1 -1
- package/lib/util/dedent.d.ts +3 -14
- package/lib/util/dedent.d.ts.map +1 -1
- package/lib/util/dedent.js +28 -52
- package/lib/util/dedent.js.map +1 -1
- package/lib/util/idempotent-spawn.d.ts.map +1 -1
- package/lib/util/idempotent-spawn.js +21 -2
- package/lib/util/idempotent-spawn.js.map +1 -1
- package/lib/util/xml.js +1 -1
- package/lib/util/xml.js.map +1 -1
- package/package.json +4 -3
- package/src/alchemy.ts +14 -6
- package/src/apply.ts +13 -1
- package/src/cloudflare/bindings.ts +3 -1
- package/src/cloudflare/bucket.ts +3 -1
- package/src/cloudflare/bundle/cloudflare-internal.ts +42 -0
- package/src/cloudflare/bundle/nodejs-builtin-modules.ts +14 -0
- package/src/cloudflare/bundle/plugin-als-external.ts +13 -0
- package/src/cloudflare/bundle/plugin-hybrid-node-compat.ts +29 -28
- package/src/cloudflare/bundle/plugin-node-compat.ts +114 -0
- package/src/cloudflare/cloudflare-env-proxy.ts +1 -1
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/d1-local-migrations.ts +2 -2
- package/src/cloudflare/durable-object-namespace.ts +1 -1
- package/src/cloudflare/hyperdrive.ts +1 -1
- package/src/cloudflare/website.ts +88 -89
- package/src/cloudflare/worker-bundle.ts +46 -9
- package/src/cloudflare/worker-metadata.ts +3 -1
- package/src/cloudflare/worker.ts +35 -7
- package/src/cloudflare/wrangler.json.ts +108 -110
- package/src/context.ts +5 -3
- package/src/destroy.ts +26 -8
- package/src/neon/project.ts +4 -5
- package/src/planetscale/api/client.gen.ts +2882 -0
- package/src/planetscale/api/index.ts +4 -0
- package/src/planetscale/api/types.gen.ts +13041 -0
- package/src/planetscale/branch.ts +152 -169
- package/src/planetscale/database.ts +195 -204
- package/src/planetscale/index.ts +1 -1
- package/src/planetscale/password.ts +86 -85
- package/src/planetscale/utils.ts +141 -122
- package/src/scope.ts +12 -3
- package/src/upstash/redis.ts +1 -1
- package/src/util/dedent.ts +33 -61
- package/src/util/idempotent-spawn.ts +23 -2
- package/src/util/xml.ts +1 -1
- package/templates/astro/alchemy.run.ts +1 -3
- package/templates/hono/alchemy.run.ts +0 -1
- package/templates/nuxt/alchemy.run.ts +1 -3
- package/templates/react-router/alchemy.run.ts +1 -3
- package/templates/rwsdk/alchemy.run.ts +0 -2
- package/templates/sveltekit/alchemy.run.ts +1 -3
- package/templates/tanstack-start/alchemy.run.ts +1 -3
- package/templates/typescript/alchemy.run.ts +0 -1
- package/templates/vite/alchemy.run.ts +0 -1
- package/workers/cloudflare-state-store.js +58 -58
- package/lib/cloudflare/bundle/externals.d.ts +0 -3
- package/lib/cloudflare/bundle/externals.d.ts.map +0 -1
- package/lib/cloudflare/bundle/externals.js +0 -35
- package/lib/cloudflare/bundle/externals.js.map +0 -1
- package/lib/cloudflare/bundle/plugin-compat-warning.d.ts +0 -10
- package/lib/cloudflare/bundle/plugin-compat-warning.d.ts.map +0 -1
- package/lib/cloudflare/bundle/plugin-compat-warning.js +0 -67
- package/lib/cloudflare/bundle/plugin-compat-warning.js.map +0 -1
- package/lib/planetscale/api.d.ts +0 -53
- package/lib/planetscale/api.d.ts.map +0 -1
- package/lib/planetscale/api.js +0 -84
- package/lib/planetscale/api.js.map +0 -1
- package/src/cloudflare/bundle/externals.ts +0 -36
- package/src/cloudflare/bundle/plugin-compat-warning.ts +0 -94
- package/src/planetscale/api.ts +0 -115
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { Resource } from "../resource.ts";
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
3
|
+
import type { PlanetScaleProps } from "./api/client.gen.ts";
|
|
4
|
+
import { PlanetScaleClient } from "./api/client.gen.ts";
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
ensureProductionBranchClusterSize,
|
|
7
7
|
waitForDatabaseReady,
|
|
8
8
|
type PlanetScaleClusterSize,
|
|
9
9
|
} from "./utils.ts";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
/**
|
|
12
12
|
* Properties for creating or updating a PlanetScale Branch
|
|
13
13
|
*/
|
|
14
|
-
export interface BranchProps {
|
|
14
|
+
export interface BranchProps extends PlanetScaleProps {
|
|
15
15
|
/**
|
|
16
16
|
* The name of the branch
|
|
17
17
|
*
|
|
@@ -29,11 +29,6 @@ export interface BranchProps {
|
|
|
29
29
|
*/
|
|
30
30
|
databaseName: string;
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* PlanetScale API token (overrides environment variable)
|
|
34
|
-
*/
|
|
35
|
-
apiKey?: Secret;
|
|
36
|
-
|
|
37
32
|
/**
|
|
38
33
|
* Whether or not the branch should be set to a production branch or not.
|
|
39
34
|
*/
|
|
@@ -49,6 +44,7 @@ export interface BranchProps {
|
|
|
49
44
|
|
|
50
45
|
/**
|
|
51
46
|
* The parent branch name or Branch object
|
|
47
|
+
* @default "main"
|
|
52
48
|
*/
|
|
53
49
|
parentBranch?: string | Branch;
|
|
54
50
|
|
|
@@ -64,11 +60,11 @@ export interface BranchProps {
|
|
|
64
60
|
* If provided, restores the last successful backup's schema and data to the new branch.
|
|
65
61
|
* Must have restore_production_branch_backup(s) or restore_backup(s) access,
|
|
66
62
|
* in addition to Data Branching being enabled for the branch.
|
|
67
|
-
* Use 'last_successful_backup' or
|
|
63
|
+
* Use 'last_successful_backup' or undefined.
|
|
68
64
|
*
|
|
69
65
|
* Ignored if the branch already exists.
|
|
70
66
|
*/
|
|
71
|
-
seedData?:
|
|
67
|
+
seedData?: "last_successful_backup";
|
|
72
68
|
|
|
73
69
|
/**
|
|
74
70
|
* The database cluster size is required if a backup_id is provided. If the branch is not a production branch, the cluster size MUST be "PS_DEV".
|
|
@@ -158,13 +154,8 @@ export const Branch = Resource(
|
|
|
158
154
|
props: BranchProps,
|
|
159
155
|
): Promise<Branch> {
|
|
160
156
|
const adopt = props.adopt ?? this.scope.adopt;
|
|
161
|
-
const apiKey =
|
|
162
|
-
props.apiKey?.unencrypted || process.env.PLANETSCALE_API_TOKEN;
|
|
163
|
-
if (!apiKey) {
|
|
164
|
-
throw new Error("PLANETSCALE_API_TOKEN environment variable is required");
|
|
165
|
-
}
|
|
166
157
|
|
|
167
|
-
const api = new
|
|
158
|
+
const api = new PlanetScaleClient(props);
|
|
168
159
|
|
|
169
160
|
const branchName =
|
|
170
161
|
props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
@@ -175,189 +166,181 @@ export const Branch = Resource(
|
|
|
175
166
|
}
|
|
176
167
|
|
|
177
168
|
if (this.phase === "delete") {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
if (this.output?.name) {
|
|
170
|
+
const response = await api.organizations.databases.branches.delete({
|
|
171
|
+
path: {
|
|
172
|
+
organization: props.organizationId,
|
|
173
|
+
database: props.databaseName,
|
|
174
|
+
name: this.output.name,
|
|
175
|
+
},
|
|
176
|
+
result: "full",
|
|
177
|
+
});
|
|
183
178
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
if (response.error && response.error.status !== 404) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Failed to delete branch: ${response.error.message}`,
|
|
182
|
+
{
|
|
183
|
+
cause: response.error,
|
|
184
|
+
},
|
|
185
|
+
);
|
|
189
186
|
}
|
|
190
|
-
} catch (error) {
|
|
191
|
-
console.error("Error deleting branch:", error);
|
|
192
|
-
throw error;
|
|
193
187
|
}
|
|
194
188
|
return this.destroy();
|
|
195
189
|
}
|
|
196
190
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
props.parentBranch.name,
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Check if branch exists
|
|
214
|
-
const getResponse = await api.get(
|
|
215
|
-
`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}`,
|
|
191
|
+
const parentBranchName = !props.parentBranch
|
|
192
|
+
? "main"
|
|
193
|
+
: typeof props.parentBranch === "string"
|
|
194
|
+
? props.parentBranch
|
|
195
|
+
: props.parentBranch.name;
|
|
196
|
+
|
|
197
|
+
if (typeof props.parentBranch !== "string" && props.parentBranch) {
|
|
198
|
+
await waitForDatabaseReady(
|
|
199
|
+
api,
|
|
200
|
+
props.organizationId,
|
|
201
|
+
props.databaseName,
|
|
202
|
+
props.parentBranch.name,
|
|
216
203
|
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Check if branch exists
|
|
207
|
+
const getResponse = await api.organizations.databases.branches.get({
|
|
208
|
+
path: {
|
|
209
|
+
organization: props.organizationId,
|
|
210
|
+
database: props.databaseName,
|
|
211
|
+
name: branchName,
|
|
212
|
+
},
|
|
213
|
+
result: "full",
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
if (getResponse.error && getResponse.error.status !== 404) {
|
|
217
|
+
// Error getting branch
|
|
218
|
+
throw new Error(`Failed to get branch: ${getResponse.error.message}`, {
|
|
219
|
+
cause: getResponse.error,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
217
222
|
|
|
218
|
-
|
|
219
|
-
|
|
223
|
+
if (getResponse.data) {
|
|
224
|
+
// Branch exists
|
|
225
|
+
if (!adopt) {
|
|
220
226
|
throw new Error(
|
|
221
|
-
`
|
|
227
|
+
`Branch ${branchName} already exists and adopt is false`,
|
|
222
228
|
);
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (!adopt) {
|
|
228
|
-
throw new Error(
|
|
229
|
-
`Branch ${branchName} already exists and adopt is false`,
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const data = await getResponse.json<any>();
|
|
234
|
-
const currentParentBranch = data.parent_branch || "main";
|
|
235
|
-
|
|
236
|
-
// Check immutable properties
|
|
237
|
-
if (props.parentBranch && parentBranchName !== currentParentBranch) {
|
|
238
|
-
throw new Error(
|
|
239
|
-
`Cannot change parent branch from ${currentParentBranch} to ${parentBranchName}`,
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
if (this.output?.backupId) {
|
|
243
|
-
console.warn(
|
|
244
|
-
"BackupID is set, but branch already exists, so it will be ignored",
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (this.output?.seedData) {
|
|
249
|
-
console.warn(
|
|
250
|
-
"SeedData is set, but branch already exists, so it will be ignored",
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Update mutable properties if they've changed
|
|
255
|
-
if (props.safeMigrations !== undefined) {
|
|
256
|
-
const safeMigrationsResponse = await api[
|
|
257
|
-
props.safeMigrations ? "post" : "delete"
|
|
258
|
-
](
|
|
259
|
-
`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}/safe-migrations`,
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
if (!safeMigrationsResponse.ok) {
|
|
263
|
-
throw new Error(
|
|
264
|
-
`Failed to ${props.safeMigrations ? "enable" : "disable"} safe migrations: ${safeMigrationsResponse.statusText}`,
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (props.clusterSize && data.cluster_size !== props.clusterSize) {
|
|
270
|
-
const clusterResponse = await api.patch(
|
|
271
|
-
`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}/cluster`,
|
|
272
|
-
{
|
|
273
|
-
cluster_size: props.clusterSize,
|
|
274
|
-
},
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
if (!clusterResponse.ok) {
|
|
278
|
-
throw new Error(
|
|
279
|
-
`Failed to update cluster size: ${clusterResponse.statusText}`,
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return this({
|
|
285
|
-
...props,
|
|
286
|
-
name: branchName,
|
|
287
|
-
parentBranch: currentParentBranch,
|
|
288
|
-
createdAt: data.created_at,
|
|
289
|
-
updatedAt: data.updated_at,
|
|
290
|
-
htmlUrl: data.html_url,
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
await waitForDatabaseReady(api, props.organizationId, props.databaseName);
|
|
294
|
-
|
|
295
|
-
// Branch doesn't exist, create it
|
|
296
|
-
const createResponse = await api.post(
|
|
297
|
-
`/organizations/${props.organizationId}/databases/${props.databaseName}/branches`,
|
|
298
|
-
{
|
|
299
|
-
name: branchName,
|
|
300
|
-
parent_branch: parentBranchName,
|
|
301
|
-
backup_id: props.backupId,
|
|
302
|
-
seed_data: props.seedData,
|
|
303
|
-
cluster_size: props.clusterSize,
|
|
304
|
-
},
|
|
305
|
-
);
|
|
231
|
+
const data = getResponse.data;
|
|
232
|
+
const currentParentBranch = data.parent_branch || "main";
|
|
306
233
|
|
|
307
|
-
|
|
234
|
+
// Check immutable properties
|
|
235
|
+
if (props.parentBranch && parentBranchName !== currentParentBranch) {
|
|
308
236
|
throw new Error(
|
|
309
|
-
`
|
|
237
|
+
`Cannot change parent branch from ${currentParentBranch} to ${parentBranchName}`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
if (this.output?.backupId) {
|
|
241
|
+
console.warn(
|
|
242
|
+
"BackupID is set, but branch already exists, so it will be ignored",
|
|
310
243
|
);
|
|
311
244
|
}
|
|
312
245
|
|
|
313
|
-
|
|
246
|
+
if (this.output?.seedData) {
|
|
247
|
+
console.warn(
|
|
248
|
+
"SeedData is set, but branch already exists, so it will be ignored",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
314
251
|
|
|
315
|
-
//
|
|
252
|
+
// Update mutable properties if they've changed
|
|
316
253
|
if (props.safeMigrations !== undefined) {
|
|
317
|
-
|
|
318
|
-
await waitForDatabaseReady(
|
|
319
|
-
api,
|
|
320
|
-
props.organizationId,
|
|
321
|
-
props.databaseName,
|
|
322
|
-
branchName,
|
|
323
|
-
);
|
|
324
|
-
const safeMigrationsResponse = await api[
|
|
254
|
+
await api.organizations.databases.branches.safeMigrations[
|
|
325
255
|
props.safeMigrations ? "post" : "delete"
|
|
326
|
-
](
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
);
|
|
334
|
-
}
|
|
256
|
+
]({
|
|
257
|
+
path: {
|
|
258
|
+
organization: props.organizationId,
|
|
259
|
+
database: props.databaseName,
|
|
260
|
+
name: branchName,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
335
263
|
}
|
|
336
264
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
);
|
|
265
|
+
if (props.clusterSize && data.cluster_name !== props.clusterSize) {
|
|
266
|
+
await api.organizations.databases.branches.cluster.patch({
|
|
267
|
+
path: {
|
|
268
|
+
organization: props.organizationId,
|
|
269
|
+
database: props.databaseName,
|
|
270
|
+
name: branchName,
|
|
271
|
+
},
|
|
272
|
+
body: {
|
|
273
|
+
cluster_size: props.clusterSize,
|
|
274
|
+
},
|
|
275
|
+
});
|
|
348
276
|
}
|
|
349
277
|
|
|
350
278
|
return this({
|
|
351
279
|
...props,
|
|
352
280
|
name: branchName,
|
|
353
|
-
parentBranch:
|
|
281
|
+
parentBranch: currentParentBranch,
|
|
354
282
|
createdAt: data.created_at,
|
|
355
283
|
updatedAt: data.updated_at,
|
|
356
284
|
htmlUrl: data.html_url,
|
|
357
285
|
});
|
|
358
|
-
} catch (error) {
|
|
359
|
-
console.error("Error managing branch:", error);
|
|
360
|
-
throw error;
|
|
361
286
|
}
|
|
287
|
+
await waitForDatabaseReady(api, props.organizationId, props.databaseName);
|
|
288
|
+
|
|
289
|
+
// Branch doesn't exist, create it
|
|
290
|
+
const data = await api.organizations.databases.branches.post({
|
|
291
|
+
path: {
|
|
292
|
+
organization: props.organizationId,
|
|
293
|
+
database: props.databaseName,
|
|
294
|
+
},
|
|
295
|
+
body: {
|
|
296
|
+
name: branchName,
|
|
297
|
+
parent_branch: parentBranchName,
|
|
298
|
+
backup_id: props.backupId,
|
|
299
|
+
seed_data: props.seedData,
|
|
300
|
+
cluster_size: props.clusterSize,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Handle safe migrations if specified
|
|
305
|
+
if (props.safeMigrations !== undefined) {
|
|
306
|
+
// We can't change the migrations mode if the database is not ready
|
|
307
|
+
await waitForDatabaseReady(
|
|
308
|
+
api,
|
|
309
|
+
props.organizationId,
|
|
310
|
+
props.databaseName,
|
|
311
|
+
branchName,
|
|
312
|
+
);
|
|
313
|
+
await api.organizations.databases.branches.safeMigrations[
|
|
314
|
+
props.safeMigrations ? "post" : "delete"
|
|
315
|
+
]({
|
|
316
|
+
path: {
|
|
317
|
+
organization: props.organizationId,
|
|
318
|
+
database: props.databaseName,
|
|
319
|
+
name: branchName,
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Handle cluster size update if specified
|
|
325
|
+
if (props.clusterSize) {
|
|
326
|
+
// Wait for database to be ready before modifying cluster size
|
|
327
|
+
await ensureProductionBranchClusterSize(
|
|
328
|
+
api,
|
|
329
|
+
props.organizationId,
|
|
330
|
+
props.databaseName,
|
|
331
|
+
branchName,
|
|
332
|
+
props.clusterSize,
|
|
333
|
+
true,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return this({
|
|
338
|
+
...props,
|
|
339
|
+
name: branchName,
|
|
340
|
+
parentBranch: data.parent_branch,
|
|
341
|
+
createdAt: data.created_at,
|
|
342
|
+
updatedAt: data.updated_at,
|
|
343
|
+
htmlUrl: data.html_url,
|
|
344
|
+
});
|
|
362
345
|
},
|
|
363
346
|
);
|