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,6 +1,6 @@
|
|
|
1
1
|
import { Resource } from "../resource.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { PlanetScaleClient } from "./api/client.gen.js";
|
|
3
|
+
import { ensureProductionBranchClusterSize, waitForDatabaseReady, } from "./utils.js";
|
|
4
4
|
/**
|
|
5
5
|
* Create or manage a PlanetScale database branch
|
|
6
6
|
*
|
|
@@ -42,126 +42,140 @@ import { fixClusterSize, waitForDatabaseReady, } from "./utils.js";
|
|
|
42
42
|
*/
|
|
43
43
|
export const Branch = Resource("planetscale::Branch", async function (id, props) {
|
|
44
44
|
const adopt = props.adopt ?? this.scope.adopt;
|
|
45
|
-
const
|
|
46
|
-
if (!apiKey) {
|
|
47
|
-
throw new Error("PLANETSCALE_API_TOKEN environment variable is required");
|
|
48
|
-
}
|
|
49
|
-
const api = new PlanetScaleApi({ apiKey });
|
|
45
|
+
const api = new PlanetScaleClient(props);
|
|
50
46
|
const branchName = props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
51
47
|
if (this.phase === "update" && this.output.name !== branchName) {
|
|
52
48
|
// TODO(sam): maybe we don't need to replace? just branch again? or rename?
|
|
53
49
|
this.replace();
|
|
54
50
|
}
|
|
55
51
|
if (this.phase === "delete") {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
if (this.output?.name) {
|
|
53
|
+
const response = await api.organizations.databases.branches.delete({
|
|
54
|
+
path: {
|
|
55
|
+
organization: props.organizationId,
|
|
56
|
+
database: props.databaseName,
|
|
57
|
+
name: this.output.name,
|
|
58
|
+
},
|
|
59
|
+
result: "full",
|
|
60
|
+
});
|
|
61
|
+
if (response.error && response.error.status !== 404) {
|
|
62
|
+
throw new Error(`Failed to delete branch: ${response.error.message}`, {
|
|
63
|
+
cause: response.error,
|
|
64
|
+
});
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.error("Error deleting branch:", error);
|
|
66
|
-
throw error;
|
|
67
|
-
}
|
|
68
67
|
return this.destroy();
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
const parentBranchName = !props.parentBranch
|
|
70
|
+
? "main"
|
|
71
|
+
: typeof props.parentBranch === "string"
|
|
72
|
+
? props.parentBranch
|
|
73
|
+
: props.parentBranch.name;
|
|
74
|
+
if (typeof props.parentBranch !== "string" && props.parentBranch) {
|
|
75
|
+
await waitForDatabaseReady(api, props.organizationId, props.databaseName, props.parentBranch.name);
|
|
76
|
+
}
|
|
77
|
+
// Check if branch exists
|
|
78
|
+
const getResponse = await api.organizations.databases.branches.get({
|
|
79
|
+
path: {
|
|
80
|
+
organization: props.organizationId,
|
|
81
|
+
database: props.databaseName,
|
|
82
|
+
name: branchName,
|
|
83
|
+
},
|
|
84
|
+
result: "full",
|
|
85
|
+
});
|
|
86
|
+
if (getResponse.error && getResponse.error.status !== 404) {
|
|
87
|
+
// Error getting branch
|
|
88
|
+
throw new Error(`Failed to get branch: ${getResponse.error.message}`, {
|
|
89
|
+
cause: getResponse.error,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (getResponse.data) {
|
|
93
|
+
// Branch exists
|
|
94
|
+
if (!adopt) {
|
|
95
|
+
throw new Error(`Branch ${branchName} already exists and adopt is false`);
|
|
78
96
|
}
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
throw new Error(`
|
|
97
|
+
const data = getResponse.data;
|
|
98
|
+
const currentParentBranch = data.parent_branch || "main";
|
|
99
|
+
// Check immutable properties
|
|
100
|
+
if (props.parentBranch && parentBranchName !== currentParentBranch) {
|
|
101
|
+
throw new Error(`Cannot change parent branch from ${currentParentBranch} to ${parentBranchName}`);
|
|
84
102
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
if (!adopt) {
|
|
88
|
-
throw new Error(`Branch ${branchName} already exists and adopt is false`);
|
|
89
|
-
}
|
|
90
|
-
const data = await getResponse.json();
|
|
91
|
-
const currentParentBranch = data.parent_branch || "main";
|
|
92
|
-
// Check immutable properties
|
|
93
|
-
if (props.parentBranch && parentBranchName !== currentParentBranch) {
|
|
94
|
-
throw new Error(`Cannot change parent branch from ${currentParentBranch} to ${parentBranchName}`);
|
|
95
|
-
}
|
|
96
|
-
if (this.output?.backupId) {
|
|
97
|
-
console.warn("BackupID is set, but branch already exists, so it will be ignored");
|
|
98
|
-
}
|
|
99
|
-
if (this.output?.seedData) {
|
|
100
|
-
console.warn("SeedData is set, but branch already exists, so it will be ignored");
|
|
101
|
-
}
|
|
102
|
-
// Update mutable properties if they've changed
|
|
103
|
-
if (props.safeMigrations !== undefined) {
|
|
104
|
-
const safeMigrationsResponse = await api[props.safeMigrations ? "post" : "delete"](`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}/safe-migrations`);
|
|
105
|
-
if (!safeMigrationsResponse.ok) {
|
|
106
|
-
throw new Error(`Failed to ${props.safeMigrations ? "enable" : "disable"} safe migrations: ${safeMigrationsResponse.statusText}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (props.clusterSize && data.cluster_size !== props.clusterSize) {
|
|
110
|
-
const clusterResponse = await api.patch(`/organizations/${props.organizationId}/databases/${props.databaseName}/branches/${branchName}/cluster`, {
|
|
111
|
-
cluster_size: props.clusterSize,
|
|
112
|
-
});
|
|
113
|
-
if (!clusterResponse.ok) {
|
|
114
|
-
throw new Error(`Failed to update cluster size: ${clusterResponse.statusText}`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return this({
|
|
118
|
-
...props,
|
|
119
|
-
name: branchName,
|
|
120
|
-
parentBranch: currentParentBranch,
|
|
121
|
-
createdAt: data.created_at,
|
|
122
|
-
updatedAt: data.updated_at,
|
|
123
|
-
htmlUrl: data.html_url,
|
|
124
|
-
});
|
|
103
|
+
if (this.output?.backupId) {
|
|
104
|
+
console.warn("BackupID is set, but branch already exists, so it will be ignored");
|
|
125
105
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const createResponse = await api.post(`/organizations/${props.organizationId}/databases/${props.databaseName}/branches`, {
|
|
129
|
-
name: branchName,
|
|
130
|
-
parent_branch: parentBranchName,
|
|
131
|
-
backup_id: props.backupId,
|
|
132
|
-
seed_data: props.seedData,
|
|
133
|
-
cluster_size: props.clusterSize,
|
|
134
|
-
});
|
|
135
|
-
if (!createResponse.ok) {
|
|
136
|
-
throw new Error(`Failed to create branch: ${createResponse.statusText} ${await createResponse.text()}`);
|
|
106
|
+
if (this.output?.seedData) {
|
|
107
|
+
console.warn("SeedData is set, but branch already exists, so it will be ignored");
|
|
137
108
|
}
|
|
138
|
-
|
|
139
|
-
// Handle safe migrations if specified
|
|
109
|
+
// Update mutable properties if they've changed
|
|
140
110
|
if (props.safeMigrations !== undefined) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
111
|
+
await api.organizations.databases.branches.safeMigrations[props.safeMigrations ? "post" : "delete"]({
|
|
112
|
+
path: {
|
|
113
|
+
organization: props.organizationId,
|
|
114
|
+
database: props.databaseName,
|
|
115
|
+
name: branchName,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
147
118
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
119
|
+
if (props.clusterSize && data.cluster_name !== props.clusterSize) {
|
|
120
|
+
await api.organizations.databases.branches.cluster.patch({
|
|
121
|
+
path: {
|
|
122
|
+
organization: props.organizationId,
|
|
123
|
+
database: props.databaseName,
|
|
124
|
+
name: branchName,
|
|
125
|
+
},
|
|
126
|
+
body: {
|
|
127
|
+
cluster_size: props.clusterSize,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
152
130
|
}
|
|
153
131
|
return this({
|
|
154
132
|
...props,
|
|
155
133
|
name: branchName,
|
|
156
|
-
parentBranch:
|
|
134
|
+
parentBranch: currentParentBranch,
|
|
157
135
|
createdAt: data.created_at,
|
|
158
136
|
updatedAt: data.updated_at,
|
|
159
137
|
htmlUrl: data.html_url,
|
|
160
138
|
});
|
|
161
139
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
140
|
+
await waitForDatabaseReady(api, props.organizationId, props.databaseName);
|
|
141
|
+
// Branch doesn't exist, create it
|
|
142
|
+
const data = await api.organizations.databases.branches.post({
|
|
143
|
+
path: {
|
|
144
|
+
organization: props.organizationId,
|
|
145
|
+
database: props.databaseName,
|
|
146
|
+
},
|
|
147
|
+
body: {
|
|
148
|
+
name: branchName,
|
|
149
|
+
parent_branch: parentBranchName,
|
|
150
|
+
backup_id: props.backupId,
|
|
151
|
+
seed_data: props.seedData,
|
|
152
|
+
cluster_size: props.clusterSize,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
// Handle safe migrations if specified
|
|
156
|
+
if (props.safeMigrations !== undefined) {
|
|
157
|
+
// We can't change the migrations mode if the database is not ready
|
|
158
|
+
await waitForDatabaseReady(api, props.organizationId, props.databaseName, branchName);
|
|
159
|
+
await api.organizations.databases.branches.safeMigrations[props.safeMigrations ? "post" : "delete"]({
|
|
160
|
+
path: {
|
|
161
|
+
organization: props.organizationId,
|
|
162
|
+
database: props.databaseName,
|
|
163
|
+
name: branchName,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// Handle cluster size update if specified
|
|
168
|
+
if (props.clusterSize) {
|
|
169
|
+
// Wait for database to be ready before modifying cluster size
|
|
170
|
+
await ensureProductionBranchClusterSize(api, props.organizationId, props.databaseName, branchName, props.clusterSize, true);
|
|
165
171
|
}
|
|
172
|
+
return this({
|
|
173
|
+
...props,
|
|
174
|
+
name: branchName,
|
|
175
|
+
parentBranch: data.parent_branch,
|
|
176
|
+
createdAt: data.created_at,
|
|
177
|
+
updatedAt: data.updated_at,
|
|
178
|
+
htmlUrl: data.html_url,
|
|
179
|
+
});
|
|
166
180
|
});
|
|
167
181
|
//# sourceMappingURL=branch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/planetscale/branch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/planetscale/branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { Resource } from "../resource.ts";
|
|
3
|
-
import type {
|
|
3
|
+
import type { PlanetScaleProps } from "./api/client.gen.ts";
|
|
4
4
|
import { type PlanetScaleClusterSize } from "./utils.ts";
|
|
5
5
|
/**
|
|
6
6
|
* Properties for creating or updating a PlanetScale Database
|
|
7
7
|
*/
|
|
8
|
-
export interface DatabaseProps {
|
|
8
|
+
export interface DatabaseProps extends PlanetScaleProps {
|
|
9
9
|
/**
|
|
10
10
|
* The name of the database
|
|
11
11
|
*
|
|
@@ -16,10 +16,6 @@ export interface DatabaseProps {
|
|
|
16
16
|
* The organization ID where the database will be created
|
|
17
17
|
*/
|
|
18
18
|
organizationId: string;
|
|
19
|
-
/**
|
|
20
|
-
* PlanetScale API token (overrides environment variable)
|
|
21
|
-
*/
|
|
22
|
-
apiKey?: Secret;
|
|
23
19
|
/**
|
|
24
20
|
* Whether to adopt the database if it already exists in Planetscale
|
|
25
21
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/planetscale/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/planetscale/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAEL,KAAK,sBAAsB,EAE5B,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAEF;;OAEG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAErC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,WAAW,EAAE,sBAAsB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,QACf,SAAQ,QAAQ,CAAC,uBAAuB,CAAC,EACvC,aAAa;IACf;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,QAAQ,yFAGX,OAAO,CAAC,QAAQ,CAAC,MACnB,MAAM,SACH,aAAa,KACnB,OAAO,CAAC,QAAQ,CAAC,CAkOrB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Resource } from "../resource.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { PlanetScaleClient } from "./api/client.gen.js";
|
|
3
|
+
import { ensureProductionBranchClusterSize, waitForDatabaseReady, } from "./utils.js";
|
|
4
4
|
/**
|
|
5
5
|
* Create, manage and delete PlanetScale databases
|
|
6
6
|
*
|
|
@@ -36,58 +36,82 @@ import { fixClusterSize, waitForDatabaseReady, } from "./utils.js";
|
|
|
36
36
|
* });
|
|
37
37
|
*/
|
|
38
38
|
export const Database = Resource("planetscale::Database", async function (id, props) {
|
|
39
|
-
const
|
|
40
|
-
const apiKey = props.apiKey?.unencrypted || process.env.PLANETSCALE_API_TOKEN;
|
|
41
|
-
if (!apiKey) {
|
|
42
|
-
throw new Error("PLANETSCALE_API_TOKEN environment variable is required");
|
|
43
|
-
}
|
|
44
|
-
const api = new PlanetScaleApi({ apiKey });
|
|
39
|
+
const api = new PlanetScaleClient(props);
|
|
45
40
|
const databaseName = props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
46
41
|
if (this.phase === "update" && this.output.name !== databaseName) {
|
|
47
|
-
await api.
|
|
42
|
+
await api.organizations.databases.patch({
|
|
43
|
+
path: {
|
|
44
|
+
organization: props.organizationId,
|
|
45
|
+
name: this.output.name,
|
|
46
|
+
},
|
|
47
|
+
body: { new_name: databaseName },
|
|
48
|
+
});
|
|
48
49
|
}
|
|
49
50
|
if (this.phase === "delete") {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
51
|
+
if (this.output?.name) {
|
|
52
|
+
const response = await api.organizations.databases.delete({
|
|
53
|
+
path: {
|
|
54
|
+
organization: props.organizationId,
|
|
55
|
+
name: this.output.name,
|
|
56
|
+
},
|
|
57
|
+
result: "full",
|
|
58
|
+
});
|
|
59
|
+
if (response.error && response.error.status !== 404) {
|
|
60
|
+
throw new Error(`Failed to delete database "${this.output.name}"`, {
|
|
61
|
+
cause: response.error,
|
|
62
|
+
});
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error("Error deleting database:", error);
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
65
|
return this.destroy();
|
|
63
66
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
// Check if database exists
|
|
68
|
+
const getResponse = await api.organizations.databases.get({
|
|
69
|
+
path: {
|
|
70
|
+
organization: props.organizationId,
|
|
71
|
+
name: databaseName,
|
|
72
|
+
},
|
|
73
|
+
result: "full",
|
|
74
|
+
});
|
|
75
|
+
if (this.phase === "update" || (props.adopt && getResponse.data)) {
|
|
76
|
+
if (!getResponse.data) {
|
|
77
|
+
throw new Error(`Database "${databaseName}" not found`, {
|
|
78
|
+
cause: getResponse.error,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Update database settings
|
|
82
|
+
// If updating to a non-'main' default branch, create it first
|
|
83
|
+
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
84
|
+
const branchResponse = await api.organizations.databases.branches.get({
|
|
85
|
+
path: {
|
|
86
|
+
organization: props.organizationId,
|
|
87
|
+
database: databaseName,
|
|
88
|
+
name: props.defaultBranch,
|
|
89
|
+
},
|
|
90
|
+
result: "full",
|
|
91
|
+
});
|
|
92
|
+
if (!branchResponse.data) {
|
|
93
|
+
await waitForDatabaseReady(api, props.organizationId, databaseName);
|
|
71
94
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Create the branch
|
|
81
|
-
const createBranchResponse = await api.post(`/organizations/${props.organizationId}/databases/${databaseName}/branches`, {
|
|
95
|
+
if (branchResponse.error && branchResponse.error.status === 404) {
|
|
96
|
+
// Create the branch
|
|
97
|
+
await api.organizations.databases.branches.post({
|
|
98
|
+
path: {
|
|
99
|
+
organization: props.organizationId,
|
|
100
|
+
database: databaseName,
|
|
101
|
+
},
|
|
102
|
+
body: {
|
|
82
103
|
name: props.defaultBranch,
|
|
83
104
|
parent_branch: "main",
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
throw new Error(`Failed to create default branch: ${createBranchResponse.statusText} ${await createBranchResponse.text()}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
105
|
+
},
|
|
106
|
+
});
|
|
89
107
|
}
|
|
90
|
-
|
|
108
|
+
}
|
|
109
|
+
const updateResponse = await api.organizations.databases.patch({
|
|
110
|
+
path: {
|
|
111
|
+
organization: props.organizationId,
|
|
112
|
+
name: databaseName,
|
|
113
|
+
},
|
|
114
|
+
body: {
|
|
91
115
|
automatic_migrations: props.automaticMigrations,
|
|
92
116
|
migration_framework: props.migrationFramework,
|
|
93
117
|
migration_table_name: props.migrationTableName,
|
|
@@ -97,31 +121,43 @@ export const Database = Resource("planetscale::Database", async function (id, pr
|
|
|
97
121
|
insights_raw_queries: props.insightsRawQueries,
|
|
98
122
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
99
123
|
default_branch: props.defaultBranch,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return this({
|
|
107
|
-
...props,
|
|
108
|
-
id: data.id,
|
|
109
|
-
name: databaseName,
|
|
110
|
-
state: data.state,
|
|
111
|
-
defaultBranch: data.default_branch,
|
|
112
|
-
plan: data.plan,
|
|
113
|
-
createdAt: data.created_at,
|
|
114
|
-
updatedAt: data.updated_at,
|
|
115
|
-
htmlUrl: data.html_url,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
if (getResponse.ok) {
|
|
119
|
-
throw new Error(`Database with name ${databaseName} already exists`);
|
|
120
|
-
}
|
|
121
|
-
// Create new database
|
|
122
|
-
const createResponse = await api.post(`/organizations/${props.organizationId}/databases`, {
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
await ensureProductionBranchClusterSize(api, props.organizationId, databaseName, props.defaultBranch || "main", props.clusterSize, updateResponse.ready);
|
|
127
|
+
return this({
|
|
128
|
+
...props,
|
|
129
|
+
id: updateResponse.id,
|
|
123
130
|
name: databaseName,
|
|
124
|
-
|
|
131
|
+
state: updateResponse.state,
|
|
132
|
+
defaultBranch: updateResponse.default_branch,
|
|
133
|
+
plan: updateResponse.plan,
|
|
134
|
+
createdAt: updateResponse.created_at,
|
|
135
|
+
updatedAt: updateResponse.updated_at,
|
|
136
|
+
htmlUrl: updateResponse.html_url,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (getResponse.data) {
|
|
140
|
+
throw new Error(`Database with name "${databaseName}" already exists`);
|
|
141
|
+
}
|
|
142
|
+
// Create new database
|
|
143
|
+
let data = await api.organizations.databases.post({
|
|
144
|
+
path: {
|
|
145
|
+
organization: props.organizationId,
|
|
146
|
+
},
|
|
147
|
+
body: {
|
|
148
|
+
name: databaseName,
|
|
149
|
+
region: props.region?.slug,
|
|
150
|
+
kind: "mysql",
|
|
151
|
+
cluster_size: props.clusterSize,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
// These settings can't be set on creation, so we need to patch them after creation.
|
|
155
|
+
data = await api.organizations.databases.patch({
|
|
156
|
+
path: {
|
|
157
|
+
organization: props.organizationId,
|
|
158
|
+
name: databaseName,
|
|
159
|
+
},
|
|
160
|
+
body: {
|
|
125
161
|
require_approval_for_deploy: props.requireApprovalForDeploy,
|
|
126
162
|
allow_data_branching: props.allowDataBranching,
|
|
127
163
|
automatic_migrations: props.automaticMigrations,
|
|
@@ -130,63 +166,66 @@ export const Database = Resource("planetscale::Database", async function (id, pr
|
|
|
130
166
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
131
167
|
migration_framework: props.migrationFramework,
|
|
132
168
|
migration_table_name: props.migrationTableName,
|
|
133
|
-
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
// If a non-'main' default branch is specified, create it
|
|
172
|
+
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
173
|
+
await waitForDatabaseReady(api, props.organizationId, databaseName);
|
|
174
|
+
// Check if branch exists
|
|
175
|
+
const branchResponse = await api.organizations.databases.branches.get({
|
|
176
|
+
path: {
|
|
177
|
+
organization: props.organizationId,
|
|
178
|
+
database: databaseName,
|
|
179
|
+
name: props.defaultBranch,
|
|
180
|
+
},
|
|
181
|
+
result: "full",
|
|
134
182
|
});
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const branchResponse = await api.get(`/organizations/${props.organizationId}/databases/${databaseName}/branches/${props.defaultBranch}`);
|
|
144
|
-
if (!branchResponse.ok && branchResponse.status === 404) {
|
|
145
|
-
// Create the branch
|
|
146
|
-
const createBranchResponse = await api.post(`/organizations/${props.organizationId}/databases/${databaseName}/branches`, {
|
|
183
|
+
if (branchResponse.error && branchResponse.error.status === 404) {
|
|
184
|
+
// Create the branch
|
|
185
|
+
await api.organizations.databases.branches.post({
|
|
186
|
+
path: {
|
|
187
|
+
organization: props.organizationId,
|
|
188
|
+
database: databaseName,
|
|
189
|
+
},
|
|
190
|
+
body: {
|
|
147
191
|
name: props.defaultBranch,
|
|
148
192
|
parent_branch: "main",
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
default_branch: props.defaultBranch,
|
|
157
|
-
});
|
|
158
|
-
if (!updateResponse.ok) {
|
|
159
|
-
throw new Error(`Failed to set default branch: ${updateResponse.statusText} ${await updateResponse.text()}`);
|
|
160
|
-
}
|
|
161
|
-
const updatedData = await updateResponse.json();
|
|
162
|
-
return this({
|
|
163
|
-
...props,
|
|
164
|
-
id: data.id,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
await ensureProductionBranchClusterSize(api, props.organizationId, databaseName, props.defaultBranch || "main", props.clusterSize, false);
|
|
196
|
+
// Update database to use new branch as default
|
|
197
|
+
const updatedData = await api.organizations.databases.patch({
|
|
198
|
+
path: {
|
|
199
|
+
organization: props.organizationId,
|
|
165
200
|
name: databaseName,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
201
|
+
},
|
|
202
|
+
body: {
|
|
203
|
+
default_branch: props.defaultBranch,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
return this({
|
|
207
|
+
...props,
|
|
208
|
+
id: data.id,
|
|
209
|
+
name: databaseName,
|
|
210
|
+
state: updatedData.state,
|
|
211
|
+
defaultBranch: updatedData.default_branch,
|
|
212
|
+
plan: updatedData.plan,
|
|
213
|
+
createdAt: updatedData.created_at,
|
|
214
|
+
updatedAt: updatedData.updated_at,
|
|
215
|
+
htmlUrl: updatedData.html_url,
|
|
216
|
+
});
|
|
174
217
|
}
|
|
175
|
-
return this({
|
|
176
|
-
...props,
|
|
177
|
-
id: data.id,
|
|
178
|
-
name: databaseName,
|
|
179
|
-
state: data.state,
|
|
180
|
-
defaultBranch: data.default_branch || "main",
|
|
181
|
-
plan: data.plan,
|
|
182
|
-
createdAt: data.created_at,
|
|
183
|
-
updatedAt: data.updated_at,
|
|
184
|
-
htmlUrl: data.html_url,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
console.error("Error managing database:", error);
|
|
189
|
-
throw error;
|
|
190
218
|
}
|
|
219
|
+
return this({
|
|
220
|
+
...props,
|
|
221
|
+
id: data.id,
|
|
222
|
+
name: databaseName,
|
|
223
|
+
state: data.state,
|
|
224
|
+
defaultBranch: data.default_branch || "main",
|
|
225
|
+
plan: data.plan,
|
|
226
|
+
createdAt: data.created_at,
|
|
227
|
+
updatedAt: data.updated_at,
|
|
228
|
+
htmlUrl: data.html_url,
|
|
229
|
+
});
|
|
191
230
|
});
|
|
192
231
|
//# sourceMappingURL=database.js.map
|