alchemy 0.84.0 → 0.85.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 +1 -1
- package/lib/cloudflare/api-error.d.ts +11 -0
- package/lib/cloudflare/api-error.d.ts.map +1 -1
- package/lib/cloudflare/api-error.js +11 -0
- package/lib/cloudflare/api-error.js.map +1 -1
- package/lib/cloudflare/api.js +1 -1
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +12 -2
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bindings.js.map +1 -1
- package/lib/cloudflare/bound.d.ts +2 -1
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +9 -1
- package/lib/cloudflare/d1-database.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/miniflare/build-worker-options.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.js +15 -0
- package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts +1 -1
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +41 -3
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
- package/lib/cloudflare/vpc-service.d.ts +288 -0
- package/lib/cloudflare/vpc-service.d.ts.map +1 -0
- package/lib/cloudflare/vpc-service.js +238 -0
- package/lib/cloudflare/vpc-service.js.map +1 -0
- package/lib/cloudflare/worker-metadata.d.ts +1 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +8 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +9 -0
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +9 -0
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/planetscale/api/sdk.gen.d.ts +874 -190
- package/lib/planetscale/api/sdk.gen.d.ts.map +1 -1
- package/lib/planetscale/api/sdk.gen.js +1250 -306
- package/lib/planetscale/api/sdk.gen.js.map +1 -1
- package/lib/planetscale/api/types.gen.d.ts +8241 -4128
- package/lib/planetscale/api/types.gen.d.ts.map +1 -1
- package/lib/planetscale/branch.js +4 -4
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +43 -24
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +39 -18
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/default-role.d.ts +51 -0
- package/lib/planetscale/default-role.d.ts.map +1 -0
- package/lib/planetscale/default-role.js +100 -0
- package/lib/planetscale/default-role.js.map +1 -0
- package/lib/planetscale/index.d.ts +1 -0
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +1 -0
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/organization.js +1 -1
- package/lib/planetscale/organization.js.map +1 -1
- package/lib/planetscale/role.d.ts +1 -1
- package/lib/planetscale/role.d.ts.map +1 -1
- package/lib/planetscale/role.js +1 -1
- package/lib/planetscale/role.js.map +1 -1
- package/lib/planetscale/utils.d.ts +1 -1
- package/lib/planetscale/utils.d.ts.map +1 -1
- package/lib/planetscale/utils.js +9 -10
- package/lib/planetscale/utils.js.map +1 -1
- package/lib/state/sqlite-state-store.js +2 -0
- package/lib/state/sqlite-state-store.js.map +1 -1
- package/package.json +2 -2
- package/src/cloudflare/api-error.ts +19 -0
- package/src/cloudflare/api.ts +1 -1
- package/src/cloudflare/bindings.ts +15 -2
- package/src/cloudflare/bound.ts +6 -3
- package/src/cloudflare/d1-database.ts +11 -4
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/miniflare/build-worker-options.ts +30 -18
- package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +47 -2
- package/src/cloudflare/vpc-service.ts +466 -0
- package/src/cloudflare/worker-metadata.ts +8 -0
- package/src/cloudflare/worker.ts +9 -0
- package/src/cloudflare/wrangler.json.ts +8 -0
- package/src/planetscale/api/sdk.gen.ts +2331 -987
- package/src/planetscale/api/types.gen.ts +8980 -4574
- package/src/planetscale/branch.ts +4 -4
- package/src/planetscale/database.ts +87 -46
- package/src/planetscale/default-role.ts +162 -0
- package/src/planetscale/index.ts +1 -0
- package/src/planetscale/organization.ts +1 -1
- package/src/planetscale/role.ts +3 -2
- package/src/planetscale/utils.ts +10 -10
- package/src/state/sqlite-state-store.ts +2 -0
- package/workers/tunnel-proxy.js +1 -1
|
@@ -205,7 +205,7 @@ export const Branch = Resource(
|
|
|
205
205
|
path: {
|
|
206
206
|
organization,
|
|
207
207
|
database,
|
|
208
|
-
|
|
208
|
+
branch: this.output.name,
|
|
209
209
|
},
|
|
210
210
|
throwOnError: false,
|
|
211
211
|
});
|
|
@@ -236,7 +236,7 @@ export const Branch = Resource(
|
|
|
236
236
|
path: {
|
|
237
237
|
organization,
|
|
238
238
|
database,
|
|
239
|
-
|
|
239
|
+
branch: branchName,
|
|
240
240
|
},
|
|
241
241
|
throwOnError: false,
|
|
242
242
|
});
|
|
@@ -287,7 +287,7 @@ export const Branch = Resource(
|
|
|
287
287
|
path: {
|
|
288
288
|
organization,
|
|
289
289
|
database,
|
|
290
|
-
|
|
290
|
+
branch: branchName,
|
|
291
291
|
},
|
|
292
292
|
});
|
|
293
293
|
}
|
|
@@ -367,7 +367,7 @@ export const Branch = Resource(
|
|
|
367
367
|
path: {
|
|
368
368
|
organization,
|
|
369
369
|
database,
|
|
370
|
-
|
|
370
|
+
branch: branchName,
|
|
371
371
|
},
|
|
372
372
|
});
|
|
373
373
|
}
|
|
@@ -46,63 +46,93 @@ interface BaseDatabaseProps extends PlanetScaleProps {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* The number of replicas for the database. 0 for non-HA, 2+ for HA. (create only)
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
replicas?: number;
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
54
|
+
* The database cluster size (required)
|
|
55
55
|
*/
|
|
56
|
-
|
|
56
|
+
clusterSize: PlanetScaleClusterSize;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The engine kind for the database (create only)
|
|
60
|
+
* @default "mysql"
|
|
61
|
+
*/
|
|
62
|
+
kind?: "mysql" | "postgresql";
|
|
57
63
|
|
|
58
64
|
/**
|
|
59
|
-
* Whether
|
|
65
|
+
* Whether or not deploy requests must be approved by a database administrator other than the request creator
|
|
60
66
|
*/
|
|
61
|
-
|
|
67
|
+
requireApprovalForDeploy?: boolean;
|
|
62
68
|
|
|
63
69
|
/**
|
|
64
|
-
* Whether to
|
|
70
|
+
* Whether or not to limit branch creation to the same region as the one selected during database creation.
|
|
65
71
|
*/
|
|
66
72
|
restrictBranchRegion?: boolean;
|
|
67
73
|
|
|
68
74
|
/**
|
|
69
|
-
* Whether
|
|
75
|
+
* Whether or not full queries should be collected from the database
|
|
70
76
|
*/
|
|
71
77
|
insightsRawQueries?: boolean;
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
|
-
* Whether web console can be used on production branch
|
|
80
|
+
* Whether or not the web console can be used on the production branch of the database
|
|
75
81
|
*/
|
|
76
82
|
productionBranchWebConsole?: boolean;
|
|
77
83
|
|
|
78
84
|
/**
|
|
79
85
|
* The default branch of the database
|
|
86
|
+
* @default "main"
|
|
80
87
|
*/
|
|
81
88
|
defaultBranch?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Properties for creating or updating a PlanetScale MySQL database
|
|
93
|
+
*/
|
|
94
|
+
interface MySQLDatabaseProps extends BaseDatabaseProps {
|
|
95
|
+
kind?: "mysql";
|
|
82
96
|
|
|
83
97
|
/**
|
|
84
|
-
*
|
|
98
|
+
* Whether or not to copy migration data to new branches and in deploy requests. (Vitess only)
|
|
99
|
+
*/
|
|
100
|
+
automaticMigrations?: boolean;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A migration framework to use on the database. (Vitess only)
|
|
85
104
|
*/
|
|
86
105
|
migrationFramework?: string;
|
|
87
106
|
|
|
88
107
|
/**
|
|
89
|
-
* Name of table to use as migration table
|
|
108
|
+
* Name of table to use as migration table for the database. (Vitess only)
|
|
90
109
|
*/
|
|
91
110
|
migrationTableName?: string;
|
|
92
111
|
|
|
93
112
|
/**
|
|
94
|
-
*
|
|
113
|
+
* Whether or not data branching is allowed on the database. (Vitess only)
|
|
95
114
|
*/
|
|
96
|
-
|
|
115
|
+
allowDataBranching?: boolean;
|
|
97
116
|
|
|
98
117
|
/**
|
|
99
|
-
*
|
|
100
|
-
* @default "mysql"
|
|
118
|
+
* Whether or not foreign key constraints are allowed on the database. (Vitess only)
|
|
101
119
|
*/
|
|
102
|
-
|
|
120
|
+
allowForeignKeyConstraints?: boolean;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Properties for creating or updating a PlanetScale PostgreSQL database
|
|
125
|
+
*/
|
|
126
|
+
interface PostgreSQLDatabaseProps extends BaseDatabaseProps {
|
|
127
|
+
kind: "postgresql";
|
|
103
128
|
|
|
104
129
|
/**
|
|
105
|
-
* The
|
|
130
|
+
* The PostgreSQL major version to use for the database. Defaults to the latest available major version. (PostgreSQL only)
|
|
131
|
+
*/
|
|
132
|
+
majorVersion?: string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The CPU architecture for the database (PostgreSQL only)
|
|
106
136
|
*/
|
|
107
137
|
arch?: "x86" | "arm";
|
|
108
138
|
}
|
|
@@ -110,17 +140,7 @@ interface BaseDatabaseProps extends PlanetScaleProps {
|
|
|
110
140
|
/**
|
|
111
141
|
* Properties for creating or updating a PlanetScale Database
|
|
112
142
|
*/
|
|
113
|
-
export type DatabaseProps =
|
|
114
|
-
(
|
|
115
|
-
| {
|
|
116
|
-
kind?: "mysql";
|
|
117
|
-
arch?: undefined;
|
|
118
|
-
}
|
|
119
|
-
| {
|
|
120
|
-
kind: "postgresql";
|
|
121
|
-
arch?: "x86" | "arm";
|
|
122
|
-
}
|
|
123
|
-
);
|
|
143
|
+
export type DatabaseProps = MySQLDatabaseProps | PostgreSQLDatabaseProps;
|
|
124
144
|
|
|
125
145
|
/**
|
|
126
146
|
* Represents a PlanetScale Database
|
|
@@ -220,7 +240,11 @@ export const Database = Resource(
|
|
|
220
240
|
const clusterSize = sanitizeClusterSize({
|
|
221
241
|
size: props.clusterSize,
|
|
222
242
|
kind: props.kind,
|
|
223
|
-
|
|
243
|
+
...(props.kind === "postgresql"
|
|
244
|
+
? {
|
|
245
|
+
arch: props.arch,
|
|
246
|
+
}
|
|
247
|
+
: {}),
|
|
224
248
|
region: props.region?.slug,
|
|
225
249
|
});
|
|
226
250
|
const organization =
|
|
@@ -234,13 +258,14 @@ export const Database = Resource(
|
|
|
234
258
|
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
235
259
|
);
|
|
236
260
|
}
|
|
261
|
+
const adopt = props.adopt ?? this.scope.adopt;
|
|
237
262
|
const shouldDelete = props.delete ?? false;
|
|
238
263
|
|
|
239
264
|
if (this.phase === "update" && this.output.name !== databaseName) {
|
|
240
265
|
await api.updateDatabaseSettings({
|
|
241
266
|
path: {
|
|
242
267
|
organization,
|
|
243
|
-
|
|
268
|
+
database: this.output.name,
|
|
244
269
|
},
|
|
245
270
|
body: { new_name: databaseName },
|
|
246
271
|
});
|
|
@@ -251,7 +276,7 @@ export const Database = Resource(
|
|
|
251
276
|
const response = await api.deleteDatabase({
|
|
252
277
|
path: {
|
|
253
278
|
organization,
|
|
254
|
-
|
|
279
|
+
database: this.output.name,
|
|
255
280
|
},
|
|
256
281
|
throwOnError: false,
|
|
257
282
|
});
|
|
@@ -269,11 +294,11 @@ export const Database = Resource(
|
|
|
269
294
|
const getResponse = await api.getDatabase({
|
|
270
295
|
path: {
|
|
271
296
|
organization,
|
|
272
|
-
|
|
297
|
+
database: databaseName,
|
|
273
298
|
},
|
|
274
299
|
throwOnError: false,
|
|
275
300
|
});
|
|
276
|
-
if (this.phase === "update" || (
|
|
301
|
+
if (this.phase === "update" || (adopt && getResponse.data)) {
|
|
277
302
|
if (!getResponse.data) {
|
|
278
303
|
throw new Error(`Database "${databaseName}" not found`, {
|
|
279
304
|
cause: getResponse.error,
|
|
@@ -286,7 +311,7 @@ export const Database = Resource(
|
|
|
286
311
|
path: {
|
|
287
312
|
organization,
|
|
288
313
|
database: databaseName,
|
|
289
|
-
|
|
314
|
+
branch: props.defaultBranch,
|
|
290
315
|
},
|
|
291
316
|
throwOnError: false,
|
|
292
317
|
});
|
|
@@ -311,15 +336,20 @@ export const Database = Resource(
|
|
|
311
336
|
const { data } = await api.updateDatabaseSettings({
|
|
312
337
|
path: {
|
|
313
338
|
organization,
|
|
314
|
-
|
|
339
|
+
database: databaseName,
|
|
315
340
|
},
|
|
316
341
|
body: {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
342
|
+
...(props.kind !== "postgresql"
|
|
343
|
+
? {
|
|
344
|
+
automatic_migrations: props.automaticMigrations,
|
|
345
|
+
migration_framework: props.migrationFramework,
|
|
346
|
+
migration_table_name: props.migrationTableName,
|
|
347
|
+
allow_foreign_key_constraints: props.allowForeignKeyConstraints,
|
|
348
|
+
allow_data_branching: props.allowDataBranching,
|
|
349
|
+
}
|
|
350
|
+
: {}),
|
|
320
351
|
require_approval_for_deploy: props.requireApprovalForDeploy,
|
|
321
352
|
restrict_branch_region: props.restrictBranchRegion,
|
|
322
|
-
allow_data_branching: props.allowDataBranching,
|
|
323
353
|
insights_raw_queries: props.insightsRawQueries,
|
|
324
354
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
325
355
|
default_branch: props.defaultBranch,
|
|
@@ -363,6 +393,12 @@ export const Database = Resource(
|
|
|
363
393
|
region: props.region?.slug,
|
|
364
394
|
kind: props.kind,
|
|
365
395
|
cluster_size: clusterSize,
|
|
396
|
+
replicas: props.replicas,
|
|
397
|
+
...(props.kind === "postgresql"
|
|
398
|
+
? {
|
|
399
|
+
major_version: props.majorVersion,
|
|
400
|
+
}
|
|
401
|
+
: {}),
|
|
366
402
|
},
|
|
367
403
|
});
|
|
368
404
|
|
|
@@ -370,17 +406,22 @@ export const Database = Resource(
|
|
|
370
406
|
const { data } = await api.updateDatabaseSettings({
|
|
371
407
|
path: {
|
|
372
408
|
organization,
|
|
373
|
-
|
|
409
|
+
database: databaseName,
|
|
374
410
|
},
|
|
375
411
|
body: {
|
|
412
|
+
...(props.kind !== "postgresql"
|
|
413
|
+
? {
|
|
414
|
+
automatic_migrations: props.automaticMigrations,
|
|
415
|
+
migration_framework: props.migrationFramework,
|
|
416
|
+
migration_table_name: props.migrationTableName,
|
|
417
|
+
allow_foreign_key_constraints: props.allowForeignKeyConstraints,
|
|
418
|
+
allow_data_branching: props.allowDataBranching,
|
|
419
|
+
}
|
|
420
|
+
: {}),
|
|
376
421
|
require_approval_for_deploy: props.requireApprovalForDeploy,
|
|
377
|
-
allow_data_branching: props.allowDataBranching,
|
|
378
|
-
automatic_migrations: props.automaticMigrations,
|
|
379
422
|
restrict_branch_region: props.restrictBranchRegion,
|
|
380
423
|
insights_raw_queries: props.insightsRawQueries,
|
|
381
424
|
production_branch_web_console: props.productionBranchWebConsole,
|
|
382
|
-
migration_framework: props.migrationFramework,
|
|
383
|
-
migration_table_name: props.migrationTableName,
|
|
384
425
|
},
|
|
385
426
|
});
|
|
386
427
|
|
|
@@ -393,7 +434,7 @@ export const Database = Resource(
|
|
|
393
434
|
path: {
|
|
394
435
|
organization,
|
|
395
436
|
database: databaseName,
|
|
396
|
-
|
|
437
|
+
branch: props.defaultBranch,
|
|
397
438
|
},
|
|
398
439
|
throwOnError: false,
|
|
399
440
|
});
|
|
@@ -424,7 +465,7 @@ export const Database = Resource(
|
|
|
424
465
|
const { data: updatedData } = await api.updateDatabaseSettings({
|
|
425
466
|
path: {
|
|
426
467
|
organization,
|
|
427
|
-
|
|
468
|
+
database: databaseName,
|
|
428
469
|
},
|
|
429
470
|
body: {
|
|
430
471
|
default_branch: props.defaultBranch,
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { alchemy } from "../alchemy.ts";
|
|
2
|
+
import type { Context } from "../context.ts";
|
|
3
|
+
import { Resource } from "../resource.ts";
|
|
4
|
+
import { createPlanetScaleClient, type PlanetScaleProps } from "./api.ts";
|
|
5
|
+
import type { Branch } from "./branch.ts";
|
|
6
|
+
import type { Database } from "./database.ts";
|
|
7
|
+
import type { Role } from "./role.ts";
|
|
8
|
+
import { waitForBranchReady } from "./utils.ts";
|
|
9
|
+
|
|
10
|
+
export interface DefaultRoleProps extends PlanetScaleProps {
|
|
11
|
+
/**
|
|
12
|
+
* The organization where the role will be created
|
|
13
|
+
* Required when using string database name, optional when using Database resource
|
|
14
|
+
* @default process.env.PLANETSCALE_ORGANIZATION
|
|
15
|
+
*/
|
|
16
|
+
organization?: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The database where the role will be created
|
|
20
|
+
* Can be either a database name (string) or Database resource
|
|
21
|
+
*/
|
|
22
|
+
database: string | Database;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The branch where the role will be created
|
|
26
|
+
* Can be either a branch name (string) or Branch resource
|
|
27
|
+
* @default "main"
|
|
28
|
+
*/
|
|
29
|
+
branch?: string | Branch;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Whether to force reset the default role if it already exists.
|
|
33
|
+
* This will delete the existing role and create a new one.
|
|
34
|
+
*
|
|
35
|
+
* Note: Adopting an existing role is not supported because the password is only returned after create.
|
|
36
|
+
*
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
forceReset?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type DefaultRole = Omit<Role, "successor">;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create and manage the default role for a PlanetScale PostgreSQL database branch.
|
|
46
|
+
*
|
|
47
|
+
* If a default role already exists for this database and branch combination, you may need to use the `forceReset` property to reset the role.
|
|
48
|
+
*
|
|
49
|
+
* For MySQL, use [Passwords](./password.ts) instead.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const database = await Database("my-database", {
|
|
53
|
+
* kind: "postgresql",
|
|
54
|
+
* });
|
|
55
|
+
* const defaultRole = await DefaultRole("my-default-role", {
|
|
56
|
+
* database,
|
|
57
|
+
* });
|
|
58
|
+
*/
|
|
59
|
+
export const DefaultRole = Resource(
|
|
60
|
+
"planetscale::DefaultRole",
|
|
61
|
+
async function (
|
|
62
|
+
this: Context<DefaultRole, DefaultRoleProps>,
|
|
63
|
+
_id: string,
|
|
64
|
+
props: DefaultRoleProps,
|
|
65
|
+
): Promise<DefaultRole> {
|
|
66
|
+
const api = createPlanetScaleClient(props);
|
|
67
|
+
const organization =
|
|
68
|
+
props.organization ??
|
|
69
|
+
(typeof props.database !== "string"
|
|
70
|
+
? props.database.organization
|
|
71
|
+
: (process.env.PLANETSCALE_ORGANIZATION ??
|
|
72
|
+
process.env.PLANETSCALE_ORG_ID));
|
|
73
|
+
if (!organization) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const database =
|
|
80
|
+
typeof props.database === "string" ? props.database : props.database.name;
|
|
81
|
+
const branch =
|
|
82
|
+
typeof props.branch === "string"
|
|
83
|
+
? props.branch
|
|
84
|
+
: (props.branch?.name ?? "main");
|
|
85
|
+
|
|
86
|
+
switch (this.phase) {
|
|
87
|
+
case "create": {
|
|
88
|
+
if (!props.forceReset) {
|
|
89
|
+
const existing = await api.getDefaultRole({
|
|
90
|
+
path: {
|
|
91
|
+
organization,
|
|
92
|
+
database,
|
|
93
|
+
branch,
|
|
94
|
+
},
|
|
95
|
+
throwOnError: false,
|
|
96
|
+
});
|
|
97
|
+
if (existing.data) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Default role already exists for database "${database}" branch "${branch}". Use forceReset to reset the role.`,
|
|
100
|
+
);
|
|
101
|
+
} else if (existing.error && existing.response.status !== 404) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Failed to check for default role in database "${database}" branch "${branch}".`,
|
|
104
|
+
{
|
|
105
|
+
cause: existing.error,
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await waitForBranchReady(api, organization, database, branch);
|
|
111
|
+
const { data } = await api.resetDefaultRole({
|
|
112
|
+
path: {
|
|
113
|
+
organization,
|
|
114
|
+
database,
|
|
115
|
+
branch,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
id: data.id,
|
|
120
|
+
name: data.name,
|
|
121
|
+
expiresAt: data.expires_at,
|
|
122
|
+
host: data.access_host_url,
|
|
123
|
+
username: data.username,
|
|
124
|
+
ttl: data.ttl,
|
|
125
|
+
password: alchemy.secret(data.password),
|
|
126
|
+
databaseName: data.database_name,
|
|
127
|
+
connectionUrl: alchemy.secret(
|
|
128
|
+
`postgresql://${data.username}:${data.password}@${data.access_host_url}:5432/${data.database_name}?sslmode=verify-full`,
|
|
129
|
+
),
|
|
130
|
+
connectionUrlPooled: alchemy.secret(
|
|
131
|
+
`postgresql://${data.username}:${data.password}@${data.access_host_url}:6432/${data.database_name}?sslmode=verify-full`,
|
|
132
|
+
),
|
|
133
|
+
inheritedRoles: data.inherited_roles,
|
|
134
|
+
database,
|
|
135
|
+
branch,
|
|
136
|
+
organization,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
case "update": {
|
|
140
|
+
if (
|
|
141
|
+
database !== this.output.database ||
|
|
142
|
+
branch !== this.output.branch
|
|
143
|
+
) {
|
|
144
|
+
return this.replace();
|
|
145
|
+
}
|
|
146
|
+
return this.output;
|
|
147
|
+
}
|
|
148
|
+
case "delete": {
|
|
149
|
+
// reset default role - even though we don't need new credentials,
|
|
150
|
+
// it's best to invalidate existing ones, and there's no delete endpoint
|
|
151
|
+
await api.resetDefaultRole({
|
|
152
|
+
path: {
|
|
153
|
+
organization,
|
|
154
|
+
database,
|
|
155
|
+
branch,
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
return this.destroy();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
);
|
package/src/planetscale/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ export async function OrganizationRef(
|
|
|
10
10
|
const api = createPlanetScaleClient(options);
|
|
11
11
|
const organization = await api.getOrganization({
|
|
12
12
|
path: {
|
|
13
|
-
|
|
13
|
+
organization: typeof name === "string" ? name : name.id,
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
return organization.data;
|
package/src/planetscale/role.ts
CHANGED
|
@@ -63,7 +63,7 @@ export interface RoleProps extends PlanetScaleProps {
|
|
|
63
63
|
* Roles that can be inherited from.
|
|
64
64
|
*/
|
|
65
65
|
export type InheritedRole =
|
|
66
|
-
| "
|
|
66
|
+
| "pscale_managed"
|
|
67
67
|
| "pg_checkpoint"
|
|
68
68
|
| "pg_create_subscription"
|
|
69
69
|
| "pg_maintain"
|
|
@@ -75,6 +75,7 @@ export type InheritedRole =
|
|
|
75
75
|
| "pg_stat_scan_tables"
|
|
76
76
|
| "pg_use_reserved_connections"
|
|
77
77
|
| "pg_write_all_data"
|
|
78
|
+
| "postgres"
|
|
78
79
|
| (string & {});
|
|
79
80
|
|
|
80
81
|
export interface Role extends Omit<RoleProps, "inheritedRoles"> {
|
|
@@ -261,7 +262,7 @@ export const Role = Resource(
|
|
|
261
262
|
path: {
|
|
262
263
|
organization,
|
|
263
264
|
database,
|
|
264
|
-
|
|
265
|
+
branch,
|
|
265
266
|
},
|
|
266
267
|
});
|
|
267
268
|
if (kind !== "postgresql") {
|
package/src/planetscale/utils.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { DatabaseBranch } from "./api/types.gen.ts";
|
|
|
4
4
|
|
|
5
5
|
export type PlanetScaleClusterSize =
|
|
6
6
|
| "PS_DEV"
|
|
7
|
+
| "PS_5"
|
|
7
8
|
| "PS_10"
|
|
8
9
|
| "PS_20"
|
|
9
10
|
| "PS_40"
|
|
@@ -59,7 +60,7 @@ export async function waitForBranchReady(
|
|
|
59
60
|
description: `branch "${branch}" ready`,
|
|
60
61
|
fn: () =>
|
|
61
62
|
api.getBranch({
|
|
62
|
-
path: { organization, database,
|
|
63
|
+
path: { organization, database, branch },
|
|
63
64
|
}),
|
|
64
65
|
predicate: ({ data }) => data.ready,
|
|
65
66
|
});
|
|
@@ -78,7 +79,7 @@ export async function waitForDatabaseReady(
|
|
|
78
79
|
description: `database "${database}" ready`,
|
|
79
80
|
fn: () =>
|
|
80
81
|
api.getDatabase({
|
|
81
|
-
path: { organization,
|
|
82
|
+
path: { organization, database },
|
|
82
83
|
}),
|
|
83
84
|
predicate: ({ data }) => data.ready,
|
|
84
85
|
});
|
|
@@ -134,7 +135,7 @@ export async function ensureProductionBranchClusterSize(
|
|
|
134
135
|
break;
|
|
135
136
|
}
|
|
136
137
|
case "postgresql": {
|
|
137
|
-
// Postgres databases
|
|
138
|
+
// Postgres databases do not need to be promoted; PS_DEV is development and all others are production
|
|
138
139
|
await ensurePostgresClusterSize(
|
|
139
140
|
api,
|
|
140
141
|
organization,
|
|
@@ -142,7 +143,6 @@ export async function ensureProductionBranchClusterSize(
|
|
|
142
143
|
branch,
|
|
143
144
|
expectedClusterSize,
|
|
144
145
|
);
|
|
145
|
-
await ensureProductionBranch(api, organization, database, branch);
|
|
146
146
|
break;
|
|
147
147
|
}
|
|
148
148
|
}
|
|
@@ -155,21 +155,21 @@ async function ensureProductionBranch(
|
|
|
155
155
|
api: PlanetScaleClient,
|
|
156
156
|
organization: string,
|
|
157
157
|
database: string,
|
|
158
|
-
|
|
158
|
+
branch: string,
|
|
159
159
|
): Promise<void> {
|
|
160
160
|
const { data } = await api.getBranch({
|
|
161
161
|
path: {
|
|
162
162
|
organization,
|
|
163
163
|
database,
|
|
164
|
-
|
|
164
|
+
branch,
|
|
165
165
|
},
|
|
166
166
|
});
|
|
167
167
|
if (!data.production) {
|
|
168
168
|
if (!data.ready) {
|
|
169
|
-
await waitForBranchReady(api, organization, database,
|
|
169
|
+
await waitForBranchReady(api, organization, database, branch);
|
|
170
170
|
}
|
|
171
171
|
await api.promoteBranch({
|
|
172
|
-
path: { organization, database,
|
|
172
|
+
path: { organization, database, branch },
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -213,7 +213,7 @@ async function ensureMySQLClusterSize(
|
|
|
213
213
|
path: {
|
|
214
214
|
organization,
|
|
215
215
|
database,
|
|
216
|
-
|
|
216
|
+
branch,
|
|
217
217
|
},
|
|
218
218
|
body: { cluster_size: expectedClusterSize },
|
|
219
219
|
});
|
|
@@ -243,7 +243,7 @@ async function ensurePostgresClusterSize(
|
|
|
243
243
|
path: {
|
|
244
244
|
organization,
|
|
245
245
|
database,
|
|
246
|
-
|
|
246
|
+
branch,
|
|
247
247
|
},
|
|
248
248
|
});
|
|
249
249
|
if (data.cluster_name === expectedClusterSize) {
|
|
@@ -162,6 +162,7 @@ async function createBunSQLiteDatabase(
|
|
|
162
162
|
create: true,
|
|
163
163
|
...bunOptions,
|
|
164
164
|
});
|
|
165
|
+
client.exec("PRAGMA busy_timeout = 5000;");
|
|
165
166
|
client.exec("PRAGMA journal_mode = WAL;");
|
|
166
167
|
const db = drizzle(client, {
|
|
167
168
|
schema,
|
|
@@ -192,6 +193,7 @@ async function createLibSQLDatabase(
|
|
|
192
193
|
const { migrate } = await import("drizzle-orm/libsql/migrator");
|
|
193
194
|
const schema = await import("./schema.js");
|
|
194
195
|
const client = createClient({ url, ...options });
|
|
196
|
+
await client.execute("PRAGMA busy_timeout = 5000;");
|
|
195
197
|
await client.execute("PRAGMA journal_mode = WAL;");
|
|
196
198
|
const db = drizzle(client, {
|
|
197
199
|
schema,
|
package/workers/tunnel-proxy.js
CHANGED
|
@@ -83,7 +83,7 @@ const renderErrorHtml = (props) => `
|
|
|
83
83
|
Alchemy</a>.</p>
|
|
84
84
|
</div>
|
|
85
85
|
<div class="bg-slate-200 px-5 py-3 flex flex-col w-full max-w-lg">
|
|
86
|
-
<p class="text-sm text-slate-500">Alchemy 0.
|
|
86
|
+
<p class="text-sm text-slate-500">Alchemy 0.85.0</p>
|
|
87
87
|
</div>
|
|
88
88
|
</div>
|
|
89
89
|
</body>
|