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,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, sanitizeClusterSize, waitForDatabaseReady, } from "./utils.js";
|
|
4
4
|
/**
|
|
5
5
|
* Create, manage and delete PlanetScale databases
|
|
6
6
|
*
|
|
@@ -36,58 +36,88 @@ 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);
|
|
41
|
+
const clusterSize = sanitizeClusterSize({
|
|
42
|
+
size: props.clusterSize,
|
|
43
|
+
kind: props.kind,
|
|
44
|
+
arch: props.arch,
|
|
45
|
+
region: props.region?.slug,
|
|
46
|
+
});
|
|
46
47
|
if (this.phase === "update" && this.output.name !== databaseName) {
|
|
47
|
-
await api.
|
|
48
|
+
await api.organizations.databases.patch({
|
|
49
|
+
path: {
|
|
50
|
+
organization: props.organizationId,
|
|
51
|
+
name: this.output.name,
|
|
52
|
+
},
|
|
53
|
+
body: { new_name: databaseName },
|
|
54
|
+
});
|
|
48
55
|
}
|
|
49
56
|
if (this.phase === "delete") {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
57
|
+
if (this.output?.name) {
|
|
58
|
+
const response = await api.organizations.databases.delete({
|
|
59
|
+
path: {
|
|
60
|
+
organization: props.organizationId,
|
|
61
|
+
name: this.output.name,
|
|
62
|
+
},
|
|
63
|
+
result: "full",
|
|
64
|
+
});
|
|
65
|
+
if (response.error && response.error.status !== 404) {
|
|
66
|
+
throw new Error(`Failed to delete database "${this.output.name}"`, {
|
|
67
|
+
cause: response.error,
|
|
68
|
+
});
|
|
56
69
|
}
|
|
57
70
|
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error("Error deleting database:", error);
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
71
|
return this.destroy();
|
|
63
72
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
// Check if database exists
|
|
74
|
+
const getResponse = await api.organizations.databases.get({
|
|
75
|
+
path: {
|
|
76
|
+
organization: props.organizationId,
|
|
77
|
+
name: databaseName,
|
|
78
|
+
},
|
|
79
|
+
result: "full",
|
|
80
|
+
});
|
|
81
|
+
if (this.phase === "update" || (props.adopt && getResponse.data)) {
|
|
82
|
+
if (!getResponse.data) {
|
|
83
|
+
throw new Error(`Database "${databaseName}" not found`, {
|
|
84
|
+
cause: getResponse.error,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Update database settings
|
|
88
|
+
// If updating to a non-'main' default branch, create it first
|
|
89
|
+
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
90
|
+
const branchResponse = await api.organizations.databases.branches.get({
|
|
91
|
+
path: {
|
|
92
|
+
organization: props.organizationId,
|
|
93
|
+
database: databaseName,
|
|
94
|
+
name: props.defaultBranch,
|
|
95
|
+
},
|
|
96
|
+
result: "full",
|
|
97
|
+
});
|
|
98
|
+
if (!branchResponse.data) {
|
|
99
|
+
await waitForDatabaseReady(api, props.organizationId, databaseName);
|
|
71
100
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Create the branch
|
|
81
|
-
const createBranchResponse = await api.post(`/organizations/${props.organizationId}/databases/${databaseName}/branches`, {
|
|
101
|
+
if (branchResponse.error && branchResponse.error.status === 404) {
|
|
102
|
+
// Create the branch
|
|
103
|
+
await api.organizations.databases.branches.post({
|
|
104
|
+
path: {
|
|
105
|
+
organization: props.organizationId,
|
|
106
|
+
database: databaseName,
|
|
107
|
+
},
|
|
108
|
+
body: {
|
|
82
109
|
name: props.defaultBranch,
|
|
83
110
|
parent_branch: "main",
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
throw new Error(`Failed to create default branch: ${createBranchResponse.statusText} ${await createBranchResponse.text()}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
111
|
+
},
|
|
112
|
+
});
|
|
89
113
|
}
|
|
90
|
-
|
|
114
|
+
}
|
|
115
|
+
const updateResponse = await api.organizations.databases.patch({
|
|
116
|
+
path: {
|
|
117
|
+
organization: props.organizationId,
|
|
118
|
+
name: databaseName,
|
|
119
|
+
},
|
|
120
|
+
body: {
|
|
91
121
|
automatic_migrations: props.automaticMigrations,
|
|
92
122
|
migration_framework: props.migrationFramework,
|
|
93
123
|
migration_table_name: props.migrationTableName,
|
|
@@ -97,31 +127,43 @@ export const Database = Resource("planetscale::Database", async function (id, pr
|
|
|
97
127
|
insights_raw_queries: props.insightsRawQueries,
|
|
98
128
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
99
129
|
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`, {
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
await ensureProductionBranchClusterSize(api, props.organizationId, databaseName, props.defaultBranch || "main", updateResponse.kind, clusterSize);
|
|
133
|
+
return this({
|
|
134
|
+
...props,
|
|
135
|
+
id: updateResponse.id,
|
|
123
136
|
name: databaseName,
|
|
124
|
-
|
|
137
|
+
state: updateResponse.state,
|
|
138
|
+
defaultBranch: updateResponse.default_branch,
|
|
139
|
+
plan: updateResponse.plan,
|
|
140
|
+
createdAt: updateResponse.created_at,
|
|
141
|
+
updatedAt: updateResponse.updated_at,
|
|
142
|
+
htmlUrl: updateResponse.html_url,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (getResponse.data) {
|
|
146
|
+
throw new Error(`Database with name "${databaseName}" already exists`);
|
|
147
|
+
}
|
|
148
|
+
// Create new database
|
|
149
|
+
let data = await api.organizations.databases.post({
|
|
150
|
+
path: {
|
|
151
|
+
organization: props.organizationId,
|
|
152
|
+
},
|
|
153
|
+
body: {
|
|
154
|
+
name: databaseName,
|
|
155
|
+
region: props.region?.slug,
|
|
156
|
+
kind: props.kind,
|
|
157
|
+
cluster_size: clusterSize,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
// These settings can't be set on creation, so we need to patch them after creation.
|
|
161
|
+
data = await api.organizations.databases.patch({
|
|
162
|
+
path: {
|
|
163
|
+
organization: props.organizationId,
|
|
164
|
+
name: databaseName,
|
|
165
|
+
},
|
|
166
|
+
body: {
|
|
125
167
|
require_approval_for_deploy: props.requireApprovalForDeploy,
|
|
126
168
|
allow_data_branching: props.allowDataBranching,
|
|
127
169
|
automatic_migrations: props.automaticMigrations,
|
|
@@ -130,63 +172,66 @@ export const Database = Resource("planetscale::Database", async function (id, pr
|
|
|
130
172
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
131
173
|
migration_framework: props.migrationFramework,
|
|
132
174
|
migration_table_name: props.migrationTableName,
|
|
133
|
-
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
// If a non-'main' default branch is specified, create it
|
|
178
|
+
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
179
|
+
await waitForDatabaseReady(api, props.organizationId, databaseName);
|
|
180
|
+
// Check if branch exists
|
|
181
|
+
const branchResponse = await api.organizations.databases.branches.get({
|
|
182
|
+
path: {
|
|
183
|
+
organization: props.organizationId,
|
|
184
|
+
database: databaseName,
|
|
185
|
+
name: props.defaultBranch,
|
|
186
|
+
},
|
|
187
|
+
result: "full",
|
|
134
188
|
});
|
|
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`, {
|
|
189
|
+
if (branchResponse.error && branchResponse.error.status === 404) {
|
|
190
|
+
// Create the branch
|
|
191
|
+
await api.organizations.databases.branches.post({
|
|
192
|
+
path: {
|
|
193
|
+
organization: props.organizationId,
|
|
194
|
+
database: databaseName,
|
|
195
|
+
},
|
|
196
|
+
body: {
|
|
147
197
|
name: props.defaultBranch,
|
|
148
198
|
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,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
await ensureProductionBranchClusterSize(api, props.organizationId, databaseName, props.defaultBranch || "main", data.kind, clusterSize);
|
|
202
|
+
// Update database to use new branch as default
|
|
203
|
+
const updatedData = await api.organizations.databases.patch({
|
|
204
|
+
path: {
|
|
205
|
+
organization: props.organizationId,
|
|
165
206
|
name: databaseName,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
207
|
+
},
|
|
208
|
+
body: {
|
|
209
|
+
default_branch: props.defaultBranch,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
return this({
|
|
213
|
+
...props,
|
|
214
|
+
id: data.id,
|
|
215
|
+
name: databaseName,
|
|
216
|
+
state: updatedData.state,
|
|
217
|
+
defaultBranch: updatedData.default_branch,
|
|
218
|
+
plan: updatedData.plan,
|
|
219
|
+
createdAt: updatedData.created_at,
|
|
220
|
+
updatedAt: updatedData.updated_at,
|
|
221
|
+
htmlUrl: updatedData.html_url,
|
|
222
|
+
});
|
|
174
223
|
}
|
|
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
224
|
}
|
|
225
|
+
return this({
|
|
226
|
+
...props,
|
|
227
|
+
id: data.id,
|
|
228
|
+
name: databaseName,
|
|
229
|
+
state: data.state,
|
|
230
|
+
defaultBranch: data.default_branch || "main",
|
|
231
|
+
plan: data.plan,
|
|
232
|
+
createdAt: data.created_at,
|
|
233
|
+
updatedAt: data.updated_at,
|
|
234
|
+
htmlUrl: data.html_url,
|
|
235
|
+
});
|
|
191
236
|
});
|
|
192
237
|
//# sourceMappingURL=database.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/planetscale/database.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/planetscale/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
|
package/lib/planetscale/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { Resource } from "../resource.ts";
|
|
3
3
|
import type { Secret } from "../secret.ts";
|
|
4
|
+
import { type PlanetScaleProps } from "./api/client.gen.ts";
|
|
4
5
|
import type { Branch } from "./branch.ts";
|
|
5
6
|
import type { Database } from "./database.ts";
|
|
6
7
|
/**
|
|
7
8
|
* Properties for creating or updating a PlanetScale Branch
|
|
8
9
|
*/
|
|
9
|
-
export interface PasswordProps {
|
|
10
|
+
export interface PasswordProps extends PlanetScaleProps {
|
|
10
11
|
/**
|
|
11
12
|
* The name of the password
|
|
12
13
|
*
|
|
@@ -15,7 +16,7 @@ export interface PasswordProps {
|
|
|
15
16
|
name?: string;
|
|
16
17
|
/**
|
|
17
18
|
* The organization ID where the password will be created
|
|
18
|
-
* Required when using string database name, optional when using Database resource
|
|
19
|
+
* Required when using string database name, optional when using Database or Branch resource
|
|
19
20
|
*/
|
|
20
21
|
organizationId?: string;
|
|
21
22
|
/**
|
|
@@ -26,13 +27,9 @@ export interface PasswordProps {
|
|
|
26
27
|
/**
|
|
27
28
|
* The branch where the password will be created
|
|
28
29
|
* Can be either a branch name (string) or Branch resource
|
|
29
|
-
*
|
|
30
|
+
* @default "main"
|
|
30
31
|
*/
|
|
31
32
|
branch?: string | Branch;
|
|
32
|
-
/**
|
|
33
|
-
* PlanetScale API token (overrides environment variable)
|
|
34
|
-
*/
|
|
35
|
-
apiKey?: Secret;
|
|
36
33
|
/**
|
|
37
34
|
* The password
|
|
38
35
|
*/
|
|
@@ -84,7 +81,9 @@ export interface Password extends Resource<"planetscale::Password">, PasswordPro
|
|
|
84
81
|
nameSlug: string;
|
|
85
82
|
}
|
|
86
83
|
/**
|
|
87
|
-
* Create and manage database passwords for PlanetScale branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
84
|
+
* Create and manage database passwords for PlanetScale MySQL branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
85
|
+
*
|
|
86
|
+
* For Postgres, use [Roles](./role.ts) instead.
|
|
88
87
|
*
|
|
89
88
|
* @example
|
|
90
89
|
* ## Basic Reader Password
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/planetscale/password.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/planetscale/password.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IAE5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;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,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyJG;AACH,eAAO,MAAM,QAAQ,yFAGX,OAAO,CAAC,QAAQ,CAAC,MACnB,MAAM,SACH,aAAa,KACnB,OAAO,CAAC,QAAQ,CAAC,CAmGrB,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
1
2
|
import { alchemy } from "../alchemy.js";
|
|
2
3
|
import { Resource } from "../resource.js";
|
|
3
|
-
import { logger } from "../util/logger.js";
|
|
4
4
|
import { lowercaseId } from "../util/nanoid.js";
|
|
5
|
-
import {
|
|
5
|
+
import { PlanetScaleClient } from "./api/client.gen.js";
|
|
6
6
|
/**
|
|
7
|
-
* Create and manage database passwords for PlanetScale branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
7
|
+
* Create and manage database passwords for PlanetScale MySQL branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
8
|
+
*
|
|
9
|
+
* For Postgres, use [Roles](./role.ts) instead.
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ## Basic Reader Password
|
|
@@ -156,83 +158,98 @@ import { PlanetScaleApi } from "./api.js";
|
|
|
156
158
|
* ```
|
|
157
159
|
*/
|
|
158
160
|
export const Password = Resource("planetscale::Password", async function (id, props) {
|
|
159
|
-
const apiKey = props.apiKey?.unencrypted || process.env.PLANETSCALE_API_TOKEN;
|
|
160
|
-
if (!apiKey) {
|
|
161
|
-
throw new Error("PLANETSCALE_API_TOKEN environment variable is required");
|
|
162
|
-
}
|
|
163
161
|
const nameSlug = this.isReplacement
|
|
164
162
|
? lowercaseId()
|
|
165
163
|
: (this.output?.nameSlug ?? lowercaseId());
|
|
166
164
|
const name = `${(props.name ?? this.output?.name ?? this.scope.createPhysicalName(id)).toLowerCase()}-${nameSlug}`;
|
|
167
|
-
const api = new
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
const api = new PlanetScaleClient(props);
|
|
166
|
+
const database = typeof props.database === "string" ? props.database : props.database.name;
|
|
167
|
+
const branch = typeof props.branch === "string"
|
|
168
|
+
? props.branch
|
|
169
|
+
: (props.branch?.name ?? "main");
|
|
170
|
+
const organization = props.organizationId ??
|
|
171
|
+
((typeof props.branch !== "string" && props.branch?.organizationId) ||
|
|
172
|
+
(typeof props.database !== "string" && props.database.organizationId));
|
|
173
|
+
if (!organization) {
|
|
174
|
+
throw new Error("Organization ID is required");
|
|
175
|
+
}
|
|
174
176
|
if (this.phase === "delete") {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
177
|
+
if (this.output?.id) {
|
|
178
|
+
const res = await api.organizations.databases.branches.passwords.delete({
|
|
179
|
+
path: {
|
|
180
|
+
organization,
|
|
181
|
+
database,
|
|
182
|
+
branch,
|
|
183
|
+
id: this.output.id,
|
|
184
|
+
},
|
|
185
|
+
result: "full",
|
|
186
|
+
});
|
|
187
|
+
if (res.error && res.error.status !== 404) {
|
|
188
|
+
throw new Error(`Failed to delete branch "${branch}"`, {
|
|
189
|
+
cause: res.error,
|
|
190
|
+
});
|
|
181
191
|
}
|
|
182
192
|
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
logger.error("Error deleting password:", error);
|
|
185
|
-
throw error;
|
|
186
|
-
}
|
|
187
193
|
return this.destroy();
|
|
188
194
|
}
|
|
189
195
|
if (this.phase === "update") {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
(Array.isArray(this.output?.cidrs) &&
|
|
193
|
-
Array.isArray(props.cidrs) &&
|
|
194
|
-
this.output.cidrs.length === props.cidrs.length &&
|
|
195
|
-
this.output.cidrs.every((cidr, i) => cidr === props.cidrs[i])))) {
|
|
196
|
+
// Only name and cidrs can be updated in place; all other properties require replacement.
|
|
197
|
+
if (diff({ ...props, name }, this.output).some((prop) => prop !== "name" && prop !== "cidrs")) {
|
|
196
198
|
return this.replace();
|
|
197
199
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
200
|
+
await api.organizations.databases.branches.passwords.patch({
|
|
201
|
+
path: {
|
|
202
|
+
organization,
|
|
203
|
+
database,
|
|
204
|
+
branch,
|
|
205
|
+
id: this.output.id,
|
|
206
|
+
},
|
|
207
|
+
body: {
|
|
208
|
+
name,
|
|
209
|
+
cidrs: props.cidrs,
|
|
210
|
+
},
|
|
201
211
|
});
|
|
202
|
-
if (!updateResponse.ok) {
|
|
203
|
-
throw new Error(`Failed to update password: ${updateResponse.statusText} ${await updateResponse.text()}`);
|
|
204
|
-
}
|
|
205
212
|
return this({
|
|
206
213
|
...this.output,
|
|
207
214
|
...props,
|
|
215
|
+
name,
|
|
208
216
|
});
|
|
209
217
|
}
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
const data = await api.organizations.databases.branches.passwords.post({
|
|
219
|
+
path: {
|
|
220
|
+
organization,
|
|
221
|
+
database,
|
|
222
|
+
branch,
|
|
223
|
+
},
|
|
224
|
+
body: {
|
|
212
225
|
name,
|
|
213
226
|
role: props.role,
|
|
214
227
|
replica: props.replica,
|
|
215
228
|
ttl: props.ttl,
|
|
216
229
|
cidrs: props.cidrs,
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
return this({
|
|
233
|
+
id: data.id,
|
|
234
|
+
expiresAt: data.expires_at,
|
|
235
|
+
host: data.access_host_url,
|
|
236
|
+
username: data.username,
|
|
237
|
+
password: alchemy.secret(data.plain_text),
|
|
238
|
+
nameSlug,
|
|
239
|
+
...props,
|
|
240
|
+
name: `${props.name}-${nameSlug}`,
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
/**
|
|
244
|
+
* Returns an array of keys in `b` that are different from `a`.
|
|
245
|
+
*/
|
|
246
|
+
const diff = (a, b) => {
|
|
247
|
+
const keys = [];
|
|
248
|
+
for (const key in a) {
|
|
249
|
+
if (!isDeepStrictEqual(a[key], b[key])) {
|
|
250
|
+
keys.push(key);
|
|
220
251
|
}
|
|
221
|
-
const data = await createResponse.json();
|
|
222
|
-
return this({
|
|
223
|
-
id: data.id,
|
|
224
|
-
expiresAt: data.expires_at,
|
|
225
|
-
host: data.access_host_url,
|
|
226
|
-
username: data.username,
|
|
227
|
-
password: alchemy.secret(data.plain_text),
|
|
228
|
-
nameSlug,
|
|
229
|
-
...props,
|
|
230
|
-
name: `${props.name}-${nameSlug}`,
|
|
231
|
-
});
|
|
232
252
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
throw error;
|
|
236
|
-
}
|
|
237
|
-
});
|
|
253
|
+
return keys;
|
|
254
|
+
};
|
|
238
255
|
//# sourceMappingURL=password.js.map
|