alchemy 0.63.1 → 0.65.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 +7664 -5857
- package/bin/commands/init.ts +130 -9
- package/bin/constants.ts +4 -0
- package/bin/services/cdp-manager/cdp-proxy.ts +69 -0
- package/bin/services/cdp-manager/server.ts +173 -0
- package/bin/services/execute-alchemy.ts +83 -4
- package/bin/types.ts +1 -0
- 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/bundle/plugin-wasm.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.js +20 -11
- package/lib/cloudflare/bundle/plugin-wasm.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/durable-object-namespace.js.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +7 -2
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +39 -57
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/index.d.ts +1 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/next.d.ts +13 -0
- package/lib/cloudflare/next.d.ts.map +1 -0
- package/lib/cloudflare/next.js +91 -0
- package/lib/cloudflare/next.js.map +1 -0
- 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-assets.d.ts +3 -3
- package/lib/cloudflare/worker-assets.d.ts.map +1 -1
- package/lib/cloudflare/worker-assets.js +22 -47
- package/lib/cloudflare/worker-assets.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 +1 -0
- 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 +4 -6
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +20 -15
- 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/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 +122 -97
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +24 -11
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +163 -118
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/index.d.ts +2 -1
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +2 -1
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +7 -8
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +74 -57
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/role.d.ts +126 -0
- package/lib/planetscale/role.d.ts.map +1 -0
- package/lib/planetscale/role.js +144 -0
- package/lib/planetscale/role.js.map +1 -0
- package/lib/planetscale/utils.d.ts +23 -7
- package/lib/planetscale/utils.d.ts.map +1 -1
- package/lib/planetscale/utils.js +169 -75
- 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/secret.d.ts +0 -3
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +0 -2
- package/lib/secret.js.map +1 -1
- package/lib/state/cloudflare-state-store.js +3 -3
- package/lib/state/cloudflare-state-store.js.map +1 -1
- package/lib/test/bun.d.ts +2 -2
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/vitest.d.ts +2 -2
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +4 -4
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/content-type.js +2 -2
- package/lib/util/content-type.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 +33 -45
- package/lib/util/dedent.js.map +1 -1
- package/lib/util/memoize.d.ts.map +1 -1
- package/lib/util/memoize.js +11 -1
- package/lib/util/memoize.js.map +1 -1
- package/package.json +8 -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/bundle/plugin-wasm.ts +34 -14
- 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 -0
- package/src/cloudflare/hyperdrive.ts +136 -95
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/next.ts +123 -0
- package/src/cloudflare/website.ts +88 -89
- package/src/cloudflare/worker-assets.ts +43 -105
- package/src/cloudflare/worker-bundle.ts +46 -9
- package/src/cloudflare/worker-metadata.ts +2 -0
- package/src/cloudflare/worker.ts +35 -7
- package/src/cloudflare/wrangler.json.ts +114 -113
- package/src/context.ts +5 -3
- package/src/destroy.ts +26 -8
- 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 +170 -162
- package/src/planetscale/database.ts +263 -243
- package/src/planetscale/index.ts +2 -1
- package/src/planetscale/password.ts +89 -86
- package/src/planetscale/role.ts +278 -0
- package/src/planetscale/utils.ts +289 -128
- package/src/scope.ts +12 -3
- package/src/secret.ts +0 -4
- package/src/state/cloudflare-state-store.ts +4 -4
- package/src/test/bun.ts +2 -2
- package/src/test/vitest.ts +6 -6
- package/src/util/content-type.ts +2 -2
- package/src/util/dedent.ts +34 -50
- package/src/util/memoize.ts +13 -1
- package/templates/astro/alchemy.run.ts +1 -3
- package/templates/hono/alchemy.run.ts +0 -1
- package/templates/nextjs/README.md +85 -0
- package/templates/nextjs/_env +1 -0
- package/templates/nextjs/_env.example +1 -0
- package/templates/nextjs/_gitignore +46 -0
- package/templates/nextjs/alchemy.run.ts +16 -0
- package/templates/nextjs/eslint.config.mjs +16 -0
- package/templates/nextjs/next-env.d.ts +5 -0
- package/templates/nextjs/next.config.ts +10 -0
- package/templates/nextjs/open-next.config.ts +5 -0
- package/templates/nextjs/package.json +31 -0
- package/templates/nextjs/src/app/api/hello/route.ts +19 -0
- package/templates/nextjs/src/app/favicon.ico +0 -0
- package/templates/nextjs/src/app/globals.css +72 -0
- package/templates/nextjs/src/app/layout.tsx +19 -0
- package/templates/nextjs/src/app/page.tsx +55 -0
- package/templates/nextjs/tsconfig.json +33 -0
- package/templates/nextjs/types/env.d.ts +14 -0
- 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,17 +1,18 @@
|
|
|
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
|
-
|
|
7
|
-
|
|
6
|
+
ensureProductionBranchClusterSize,
|
|
7
|
+
sanitizeClusterSize,
|
|
8
|
+
waitForBranchReady,
|
|
8
9
|
type PlanetScaleClusterSize,
|
|
9
10
|
} from "./utils.ts";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Properties for creating or updating a PlanetScale Branch
|
|
13
14
|
*/
|
|
14
|
-
export interface BranchProps {
|
|
15
|
+
export interface BranchProps extends PlanetScaleProps {
|
|
15
16
|
/**
|
|
16
17
|
* The name of the branch
|
|
17
18
|
*
|
|
@@ -29,11 +30,6 @@ export interface BranchProps {
|
|
|
29
30
|
*/
|
|
30
31
|
databaseName: string;
|
|
31
32
|
|
|
32
|
-
/**
|
|
33
|
-
* PlanetScale API token (overrides environment variable)
|
|
34
|
-
*/
|
|
35
|
-
apiKey?: Secret;
|
|
36
|
-
|
|
37
33
|
/**
|
|
38
34
|
* Whether or not the branch should be set to a production branch or not.
|
|
39
35
|
*/
|
|
@@ -49,6 +45,7 @@ export interface BranchProps {
|
|
|
49
45
|
|
|
50
46
|
/**
|
|
51
47
|
* The parent branch name or Branch object
|
|
48
|
+
* @default "main"
|
|
52
49
|
*/
|
|
53
50
|
parentBranch?: string | Branch;
|
|
54
51
|
|
|
@@ -64,11 +61,11 @@ export interface BranchProps {
|
|
|
64
61
|
* If provided, restores the last successful backup's schema and data to the new branch.
|
|
65
62
|
* Must have restore_production_branch_backup(s) or restore_backup(s) access,
|
|
66
63
|
* in addition to Data Branching being enabled for the branch.
|
|
67
|
-
* Use 'last_successful_backup' or
|
|
64
|
+
* Use 'last_successful_backup' or undefined.
|
|
68
65
|
*
|
|
69
66
|
* Ignored if the branch already exists.
|
|
70
67
|
*/
|
|
71
|
-
seedData?:
|
|
68
|
+
seedData?: "last_successful_backup";
|
|
72
69
|
|
|
73
70
|
/**
|
|
74
71
|
* 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,16 +155,16 @@ export const Branch = Resource(
|
|
|
158
155
|
props: BranchProps,
|
|
159
156
|
): Promise<Branch> {
|
|
160
157
|
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
158
|
|
|
167
|
-
const api = new
|
|
159
|
+
const api = new PlanetScaleClient(props);
|
|
168
160
|
|
|
169
161
|
const branchName =
|
|
170
162
|
props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
163
|
+
const parentBranchName = !props.parentBranch
|
|
164
|
+
? "main"
|
|
165
|
+
: typeof props.parentBranch === "string"
|
|
166
|
+
? props.parentBranch
|
|
167
|
+
: props.parentBranch.name;
|
|
171
168
|
|
|
172
169
|
if (this.phase === "update" && this.output.name !== branchName) {
|
|
173
170
|
// TODO(sam): maybe we don't need to replace? just branch again? or rename?
|
|
@@ -175,189 +172,200 @@ export const Branch = Resource(
|
|
|
175
172
|
}
|
|
176
173
|
|
|
177
174
|
if (this.phase === "delete") {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
175
|
+
if (this.output?.name) {
|
|
176
|
+
const response = await api.organizations.databases.branches.delete({
|
|
177
|
+
path: {
|
|
178
|
+
organization: props.organizationId,
|
|
179
|
+
database: props.databaseName,
|
|
180
|
+
name: this.output.name,
|
|
181
|
+
},
|
|
182
|
+
result: "full",
|
|
183
|
+
});
|
|
183
184
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
if (response.error && response.error.status !== 404) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`Failed to delete branch: ${response.error.message}`,
|
|
188
|
+
{
|
|
189
|
+
cause: response.error,
|
|
190
|
+
},
|
|
191
|
+
);
|
|
189
192
|
}
|
|
190
|
-
} catch (error) {
|
|
191
|
-
console.error("Error deleting branch:", error);
|
|
192
|
-
throw error;
|
|
193
193
|
}
|
|
194
194
|
return this.destroy();
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
if (typeof props.parentBranch !== "string" && props.parentBranch) {
|
|
198
|
+
await waitForBranchReady(
|
|
199
|
+
api,
|
|
200
|
+
props.organizationId,
|
|
201
|
+
props.databaseName,
|
|
202
|
+
props.parentBranch.name,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
203
205
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
+
}
|
|
222
|
+
|
|
223
|
+
if (getResponse.data) {
|
|
224
|
+
// Branch exists
|
|
225
|
+
if (!adopt) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Branch ${branchName} already exists and adopt is false`,
|
|
210
228
|
);
|
|
211
229
|
}
|
|
212
230
|
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}`,
|
|
216
|
-
);
|
|
231
|
+
const data = getResponse.data;
|
|
232
|
+
const currentParentBranch = data.parent_branch || "main";
|
|
217
233
|
|
|
218
|
-
|
|
219
|
-
|
|
234
|
+
// Check immutable properties
|
|
235
|
+
if (props.parentBranch && parentBranchName !== currentParentBranch) {
|
|
220
236
|
throw new Error(
|
|
221
|
-
`
|
|
237
|
+
`Cannot change parent branch from ${currentParentBranch} to ${parentBranchName}`,
|
|
222
238
|
);
|
|
223
239
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
});
|
|
240
|
+
if (this.output?.backupId) {
|
|
241
|
+
console.warn(
|
|
242
|
+
"BackupID is set, but branch already exists, so it will be ignored",
|
|
243
|
+
);
|
|
292
244
|
}
|
|
293
|
-
await waitForDatabaseReady(api, props.organizationId, props.databaseName);
|
|
294
245
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
);
|
|
306
|
-
|
|
307
|
-
if (!createResponse.ok) {
|
|
308
|
-
throw new Error(
|
|
309
|
-
`Failed to create branch: ${createResponse.statusText} ${await createResponse.text()}`,
|
|
246
|
+
if (this.output?.seedData) {
|
|
247
|
+
console.warn(
|
|
248
|
+
"SeedData is set, but branch already exists, so it will be ignored",
|
|
310
249
|
);
|
|
311
250
|
}
|
|
312
251
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
// Handle safe migrations if specified
|
|
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
|
-
|
|
256
|
+
]({
|
|
257
|
+
path: {
|
|
258
|
+
organization: props.organizationId,
|
|
259
|
+
database: props.databaseName,
|
|
260
|
+
name: branchName,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
}
|
|
329
264
|
|
|
330
|
-
|
|
265
|
+
const clusterSize = props.clusterSize
|
|
266
|
+
? sanitizeClusterSize({
|
|
267
|
+
size: props.clusterSize,
|
|
268
|
+
kind: data.kind,
|
|
269
|
+
arch: data.cluster_architecture === "aarch64" ? "arm" : "x86",
|
|
270
|
+
region: data.region.slug,
|
|
271
|
+
})
|
|
272
|
+
: undefined;
|
|
273
|
+
if (clusterSize && data.cluster_name !== clusterSize) {
|
|
274
|
+
if (!props.isProduction) {
|
|
331
275
|
throw new Error(
|
|
332
|
-
`
|
|
276
|
+
`Cannot change cluster size of non-production branch ${branchName}`,
|
|
333
277
|
);
|
|
334
278
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
// Handle cluster size update if specified
|
|
338
|
-
if (props.clusterSize) {
|
|
339
|
-
// Wait for database to be ready before modifying cluster size
|
|
340
|
-
await fixClusterSize(
|
|
279
|
+
await ensureProductionBranchClusterSize(
|
|
341
280
|
api,
|
|
342
281
|
props.organizationId,
|
|
343
282
|
props.databaseName,
|
|
344
283
|
branchName,
|
|
345
|
-
|
|
346
|
-
|
|
284
|
+
data.kind,
|
|
285
|
+
clusterSize,
|
|
347
286
|
);
|
|
348
287
|
}
|
|
349
288
|
|
|
350
289
|
return this({
|
|
351
290
|
...props,
|
|
352
291
|
name: branchName,
|
|
353
|
-
parentBranch:
|
|
292
|
+
parentBranch: currentParentBranch,
|
|
354
293
|
createdAt: data.created_at,
|
|
355
294
|
updatedAt: data.updated_at,
|
|
356
295
|
htmlUrl: data.html_url,
|
|
357
296
|
});
|
|
358
|
-
} catch (error) {
|
|
359
|
-
console.error("Error managing branch:", error);
|
|
360
|
-
throw error;
|
|
361
297
|
}
|
|
298
|
+
let clusterSize: string | undefined;
|
|
299
|
+
const parent = await waitForBranchReady(
|
|
300
|
+
api,
|
|
301
|
+
props.organizationId,
|
|
302
|
+
props.databaseName,
|
|
303
|
+
parentBranchName,
|
|
304
|
+
);
|
|
305
|
+
if (props.clusterSize) {
|
|
306
|
+
clusterSize = sanitizeClusterSize({
|
|
307
|
+
size: props.clusterSize,
|
|
308
|
+
kind: parent.kind,
|
|
309
|
+
arch: parent.cluster_architecture === "aarch64" ? "arm" : "x86",
|
|
310
|
+
region: parent.region.slug,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Branch doesn't exist, create it
|
|
315
|
+
const data = await api.organizations.databases.branches.post({
|
|
316
|
+
path: {
|
|
317
|
+
organization: props.organizationId,
|
|
318
|
+
database: props.databaseName,
|
|
319
|
+
},
|
|
320
|
+
body: {
|
|
321
|
+
name: branchName,
|
|
322
|
+
parent_branch: parentBranchName,
|
|
323
|
+
backup_id: props.backupId,
|
|
324
|
+
seed_data: props.seedData,
|
|
325
|
+
// This is ignored unless props.backupId is provided
|
|
326
|
+
cluster_size: clusterSize,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// Handle safe migrations if specified
|
|
331
|
+
if (props.safeMigrations !== undefined) {
|
|
332
|
+
// We can't change the migrations mode if the branch is not ready
|
|
333
|
+
await waitForBranchReady(
|
|
334
|
+
api,
|
|
335
|
+
props.organizationId,
|
|
336
|
+
props.databaseName,
|
|
337
|
+
branchName,
|
|
338
|
+
);
|
|
339
|
+
await api.organizations.databases.branches.safeMigrations[
|
|
340
|
+
props.safeMigrations ? "post" : "delete"
|
|
341
|
+
]({
|
|
342
|
+
path: {
|
|
343
|
+
organization: props.organizationId,
|
|
344
|
+
database: props.databaseName,
|
|
345
|
+
name: branchName,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Handle cluster size update if specified
|
|
351
|
+
if (clusterSize) {
|
|
352
|
+
await ensureProductionBranchClusterSize(
|
|
353
|
+
api,
|
|
354
|
+
props.organizationId,
|
|
355
|
+
props.databaseName,
|
|
356
|
+
branchName,
|
|
357
|
+
data.kind,
|
|
358
|
+
clusterSize,
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return this({
|
|
363
|
+
...props,
|
|
364
|
+
name: branchName,
|
|
365
|
+
parentBranch: data.parent_branch,
|
|
366
|
+
createdAt: data.created_at,
|
|
367
|
+
updatedAt: data.updated_at,
|
|
368
|
+
htmlUrl: data.html_url,
|
|
369
|
+
});
|
|
362
370
|
},
|
|
363
371
|
);
|