alchemy 0.71.0 → 0.72.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/README.md +1 -1
- package/bin/alchemy.js +119 -44
- package/bin/services/execute-alchemy.ts +12 -3
- package/bin/trpc.ts +12 -12
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +21 -6
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.js +1 -1
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +1 -1
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/health-check.d.ts +261 -0
- package/lib/cloudflare/health-check.d.ts.map +1 -0
- package/lib/cloudflare/health-check.js +277 -0
- package/lib/cloudflare/health-check.js.map +1 -0
- 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/wrangler.json.d.ts +8 -8
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +9 -11
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/cloudflare/zone.js +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +27 -0
- package/lib/destroy.js.map +1 -1
- package/lib/docker/image.js +1 -1
- package/lib/docker/image.js.map +1 -1
- package/lib/planetscale/api.d.ts +0 -4
- package/lib/planetscale/api.d.ts.map +1 -1
- package/lib/planetscale/api.js.map +1 -1
- package/lib/planetscale/branch.d.ts +12 -11
- package/lib/planetscale/branch.d.ts.map +1 -1
- package/lib/planetscale/branch.js +40 -23
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +10 -5
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +30 -18
- package/lib/planetscale/database.js.map +1 -1
- 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.d.ts +5 -0
- package/lib/planetscale/organization.d.ts.map +1 -0
- package/lib/planetscale/organization.js +11 -0
- package/lib/planetscale/organization.js.map +1 -0
- package/lib/planetscale/password.d.ts +10 -9
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +28 -13
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/role.d.ts +2 -1
- package/lib/planetscale/role.d.ts.map +1 -1
- package/lib/planetscale/role.js +11 -8
- package/lib/planetscale/role.js.map +1 -1
- package/lib/resource.js +1 -1
- package/lib/resource.js.map +1 -1
- package/lib/scope.d.ts +6 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +16 -15
- package/lib/scope.js.map +1 -1
- package/lib/state/instrumented-state-store.js +1 -1
- package/lib/state/instrumented-state-store.js.map +1 -1
- package/lib/util/cli-args.d.ts +3 -0
- package/lib/util/cli-args.d.ts.map +1 -0
- package/lib/util/cli-args.js +6 -0
- package/lib/util/cli-args.js.map +1 -0
- package/lib/util/telemetry.d.ts +1 -0
- package/lib/util/telemetry.d.ts.map +1 -1
- package/lib/util/telemetry.js +47 -2
- package/lib/util/telemetry.js.map +1 -1
- package/package.json +10 -8
- package/src/alchemy.ts +25 -11
- package/src/apply.ts +1 -1
- package/src/cloudflare/d1-database.ts +2 -2
- package/src/cloudflare/health-check.ts +617 -0
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/wrangler.json.ts +21 -23
- package/src/cloudflare/zone.ts +1 -1
- package/src/destroy.ts +32 -0
- package/src/docker/image.ts +1 -1
- package/src/planetscale/api.ts +0 -4
- package/src/planetscale/branch.ts +51 -35
- package/src/planetscale/database.ts +40 -20
- package/src/planetscale/index.ts +1 -0
- package/src/planetscale/organization.ts +17 -0
- package/src/planetscale/password.ts +34 -16
- package/src/planetscale/role.ts +16 -9
- package/src/resource.ts +1 -1
- package/src/scope.ts +25 -15
- package/src/state/instrumented-state-store.ts +1 -1
- package/src/util/cli-args.ts +11 -0
- package/src/util/telemetry.ts +68 -2
- package/workers/tunnel-proxy.js +1 -1
|
@@ -4,7 +4,6 @@ import type { Context } from "../context.ts";
|
|
|
4
4
|
import { Resource } from "../resource.ts";
|
|
5
5
|
import { Scope } from "../scope.ts";
|
|
6
6
|
import { isSecret } from "../secret.ts";
|
|
7
|
-
import { unencryptSecrets } from "./util/filter-env-bindings.ts";
|
|
8
7
|
import { assertNever } from "../util/assert-never.ts";
|
|
9
8
|
import type { Bindings, WorkerBindingRateLimit } from "./bindings.ts";
|
|
10
9
|
import type { R2BucketJurisdiction } from "./bucket.ts";
|
|
@@ -12,6 +11,7 @@ import type { DurableObjectNamespace } from "./durable-object-namespace.ts";
|
|
|
12
11
|
import type { EventSource } from "./event-source.ts";
|
|
13
12
|
import { isQueueEventSource } from "./event-source.ts";
|
|
14
13
|
import { isQueue } from "./queue.ts";
|
|
14
|
+
import { unencryptSecrets } from "./util/filter-env-bindings.ts";
|
|
15
15
|
import { isWorker, type Worker, type WorkerProps } from "./worker.ts";
|
|
16
16
|
|
|
17
17
|
type WranglerJsonRateLimit = Omit<WorkerBindingRateLimit, "type"> & {
|
|
@@ -301,7 +301,7 @@ export interface WranglerJsonSpec {
|
|
|
301
301
|
*/
|
|
302
302
|
ai?: {
|
|
303
303
|
binding: string;
|
|
304
|
-
|
|
304
|
+
remote?: boolean;
|
|
305
305
|
};
|
|
306
306
|
|
|
307
307
|
/**
|
|
@@ -309,7 +309,7 @@ export interface WranglerJsonSpec {
|
|
|
309
309
|
*/
|
|
310
310
|
browser?: {
|
|
311
311
|
binding: string;
|
|
312
|
-
|
|
312
|
+
remote?: boolean;
|
|
313
313
|
};
|
|
314
314
|
|
|
315
315
|
/**
|
|
@@ -317,7 +317,7 @@ export interface WranglerJsonSpec {
|
|
|
317
317
|
*/
|
|
318
318
|
images?: {
|
|
319
319
|
binding: string;
|
|
320
|
-
|
|
320
|
+
remote?: boolean;
|
|
321
321
|
};
|
|
322
322
|
|
|
323
323
|
/**
|
|
@@ -330,7 +330,7 @@ export interface WranglerJsonSpec {
|
|
|
330
330
|
* The ID of the KV namespace used during `wrangler dev`
|
|
331
331
|
*/
|
|
332
332
|
preview_id?: string;
|
|
333
|
-
|
|
333
|
+
remote?: boolean;
|
|
334
334
|
}[];
|
|
335
335
|
|
|
336
336
|
/**
|
|
@@ -355,7 +355,7 @@ export interface WranglerJsonSpec {
|
|
|
355
355
|
* The preview name of this R2 bucket at the edge.
|
|
356
356
|
*/
|
|
357
357
|
preview_bucket_name?: string;
|
|
358
|
-
|
|
358
|
+
remote?: boolean;
|
|
359
359
|
}[];
|
|
360
360
|
|
|
361
361
|
/**
|
|
@@ -396,7 +396,7 @@ export interface WranglerJsonSpec {
|
|
|
396
396
|
vectorize?: {
|
|
397
397
|
binding: string;
|
|
398
398
|
index_name: string;
|
|
399
|
-
|
|
399
|
+
remote?: boolean;
|
|
400
400
|
}[];
|
|
401
401
|
|
|
402
402
|
/**
|
|
@@ -416,7 +416,7 @@ export interface WranglerJsonSpec {
|
|
|
416
416
|
* The ID of the D1 database used during `wrangler dev`
|
|
417
417
|
*/
|
|
418
418
|
preview_database_id?: string;
|
|
419
|
-
|
|
419
|
+
remote?: boolean;
|
|
420
420
|
}[];
|
|
421
421
|
|
|
422
422
|
/**
|
|
@@ -499,7 +499,7 @@ export interface WranglerJsonSpec {
|
|
|
499
499
|
dispatch_namespaces?: {
|
|
500
500
|
binding: string;
|
|
501
501
|
namespace: string;
|
|
502
|
-
|
|
502
|
+
remote?: boolean;
|
|
503
503
|
}[];
|
|
504
504
|
|
|
505
505
|
/**
|
|
@@ -559,7 +559,7 @@ function processBindings(
|
|
|
559
559
|
binding: string;
|
|
560
560
|
id: string;
|
|
561
561
|
preview_id: string;
|
|
562
|
-
|
|
562
|
+
remote?: boolean;
|
|
563
563
|
}[] = [];
|
|
564
564
|
const durableObjects: {
|
|
565
565
|
name: string;
|
|
@@ -592,7 +592,7 @@ function processBindings(
|
|
|
592
592
|
database_name: string;
|
|
593
593
|
migrations_dir?: string;
|
|
594
594
|
preview_database_id: string;
|
|
595
|
-
|
|
595
|
+
remote?: boolean;
|
|
596
596
|
}[] = [];
|
|
597
597
|
const queues: {
|
|
598
598
|
producers: { queue: string; binding: string }[];
|
|
@@ -608,7 +608,7 @@ function processBindings(
|
|
|
608
608
|
const vectorizeIndexes: {
|
|
609
609
|
binding: string;
|
|
610
610
|
index_name: string;
|
|
611
|
-
|
|
611
|
+
remote?: boolean;
|
|
612
612
|
}[] = [];
|
|
613
613
|
const analyticsEngineDatasets: { binding: string; dataset: string }[] = [];
|
|
614
614
|
const hyperdrive: {
|
|
@@ -625,7 +625,7 @@ function processBindings(
|
|
|
625
625
|
const dispatchNamespaces: {
|
|
626
626
|
binding: string;
|
|
627
627
|
namespace: string;
|
|
628
|
-
|
|
628
|
+
remote?: boolean;
|
|
629
629
|
}[] = [];
|
|
630
630
|
const unsafeBindings: WranglerJsonRateLimit[] = [];
|
|
631
631
|
const containers: {
|
|
@@ -693,9 +693,7 @@ function processBindings(
|
|
|
693
693
|
binding: bindingName,
|
|
694
694
|
id: id,
|
|
695
695
|
preview_id: id,
|
|
696
|
-
...("dev" in binding && binding.dev?.remote
|
|
697
|
-
? { experimental_remote: true }
|
|
698
|
-
: {}),
|
|
696
|
+
...("dev" in binding && binding.dev?.remote ? { remote: true } : {}),
|
|
699
697
|
});
|
|
700
698
|
} else if (
|
|
701
699
|
typeof binding === "object" &&
|
|
@@ -725,7 +723,7 @@ function processBindings(
|
|
|
725
723
|
preview_bucket_name: name,
|
|
726
724
|
jurisdiction:
|
|
727
725
|
binding.jurisdiction === "default" ? undefined : binding.jurisdiction,
|
|
728
|
-
...(binding.dev?.remote ? {
|
|
726
|
+
...(binding.dev?.remote ? { remote: true } : {}),
|
|
729
727
|
});
|
|
730
728
|
} else if (binding.type === "secret") {
|
|
731
729
|
// Secret binding
|
|
@@ -753,7 +751,7 @@ function processBindings(
|
|
|
753
751
|
database_name: binding.name,
|
|
754
752
|
migrations_dir: binding.migrationsDir,
|
|
755
753
|
preview_database_id: id,
|
|
756
|
-
...(binding.dev?.remote ? {
|
|
754
|
+
...(binding.dev?.remote ? { remote: true } : {}),
|
|
757
755
|
});
|
|
758
756
|
} else if (binding.type === "queue") {
|
|
759
757
|
const id =
|
|
@@ -769,7 +767,7 @@ function processBindings(
|
|
|
769
767
|
binding: bindingName,
|
|
770
768
|
index_name: binding.name,
|
|
771
769
|
// https://developers.cloudflare.com/workers/development-testing/#recommended-remote-bindings
|
|
772
|
-
|
|
770
|
+
remote: true,
|
|
773
771
|
});
|
|
774
772
|
} else if (binding.type === "browser") {
|
|
775
773
|
if (spec.browser) {
|
|
@@ -778,7 +776,7 @@ function processBindings(
|
|
|
778
776
|
spec.browser = {
|
|
779
777
|
binding: bindingName,
|
|
780
778
|
// https://developers.cloudflare.com/workers/development-testing/#recommended-remote-bindings
|
|
781
|
-
|
|
779
|
+
remote: true,
|
|
782
780
|
};
|
|
783
781
|
} else if (binding.type === "ai") {
|
|
784
782
|
if (spec.ai) {
|
|
@@ -787,7 +785,7 @@ function processBindings(
|
|
|
787
785
|
spec.ai = {
|
|
788
786
|
binding: bindingName,
|
|
789
787
|
// https://developers.cloudflare.com/workers/development-testing/#recommended-remote-bindings
|
|
790
|
-
|
|
788
|
+
remote: true,
|
|
791
789
|
};
|
|
792
790
|
} else if (binding.type === "images") {
|
|
793
791
|
if (spec.images) {
|
|
@@ -796,7 +794,7 @@ function processBindings(
|
|
|
796
794
|
spec.images = {
|
|
797
795
|
binding: bindingName,
|
|
798
796
|
// https://developers.cloudflare.com/workers/development-testing/#recommended-remote-bindings
|
|
799
|
-
|
|
797
|
+
remote: true,
|
|
800
798
|
};
|
|
801
799
|
} else if (binding.type === "analytics_engine") {
|
|
802
800
|
analyticsEngineDatasets.push({
|
|
@@ -837,7 +835,7 @@ function processBindings(
|
|
|
837
835
|
dispatchNamespaces.push({
|
|
838
836
|
binding: bindingName,
|
|
839
837
|
namespace: binding.namespaceName,
|
|
840
|
-
|
|
838
|
+
remote: true,
|
|
841
839
|
});
|
|
842
840
|
} else if (binding.type === "ratelimit") {
|
|
843
841
|
unsafeBindings.push({
|
package/src/cloudflare/zone.ts
CHANGED
|
@@ -414,7 +414,7 @@ export const Zone = Resource(
|
|
|
414
414
|
|
|
415
415
|
// Add a small delay to ensure settings are propagated
|
|
416
416
|
// TODO(michael): do we need this?
|
|
417
|
-
// https://github.com/
|
|
417
|
+
// https://github.com/alchemy-run/alchemy/issues/681
|
|
418
418
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
419
419
|
|
|
420
420
|
// Update Bot Management configuration if provided
|
package/src/destroy.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { isScope, type PendingDeletions, Scope } from "./scope.ts";
|
|
|
14
14
|
import type { State } from "./state.ts";
|
|
15
15
|
import { formatFQN } from "./util/cli.ts";
|
|
16
16
|
import { logger } from "./util/logger.ts";
|
|
17
|
+
import { createAndSendEvent } from "./util/telemetry.ts";
|
|
17
18
|
|
|
18
19
|
export function isDestroyedSignal(error: any): error is DestroyedSignal {
|
|
19
20
|
return error instanceof Error && (error as any).kind === "DestroyedSignal";
|
|
@@ -109,6 +110,7 @@ export async function destroy(
|
|
|
109
110
|
logger.warn(`Resource "${instance[ResourceFQN]}" has no scope`);
|
|
110
111
|
}
|
|
111
112
|
const quiet = options?.quiet ?? scope.quiet;
|
|
113
|
+
const start = performance.now();
|
|
112
114
|
|
|
113
115
|
try {
|
|
114
116
|
if (!quiet && !options?.noop) {
|
|
@@ -122,6 +124,15 @@ export async function destroy(
|
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
126
|
|
|
127
|
+
await createAndSendEvent({
|
|
128
|
+
event: "resource.start",
|
|
129
|
+
resource: instance[ResourceKind],
|
|
130
|
+
status: "deleting",
|
|
131
|
+
phase: "destroy",
|
|
132
|
+
duration: performance.now() - start,
|
|
133
|
+
replaced: !!options?.replace,
|
|
134
|
+
});
|
|
135
|
+
|
|
125
136
|
let state: State;
|
|
126
137
|
let props: ResourceProps | undefined;
|
|
127
138
|
if (options?.replace) {
|
|
@@ -224,7 +235,28 @@ export async function destroy(
|
|
|
224
235
|
status: "success",
|
|
225
236
|
});
|
|
226
237
|
}
|
|
238
|
+
|
|
239
|
+
await createAndSendEvent({
|
|
240
|
+
event: "resource.success",
|
|
241
|
+
resource: instance[ResourceKind],
|
|
242
|
+
status: "deleted",
|
|
243
|
+
phase: "destroy",
|
|
244
|
+
duration: performance.now() - start,
|
|
245
|
+
replaced: !!options?.replace,
|
|
246
|
+
});
|
|
227
247
|
} catch (error) {
|
|
248
|
+
let errorToSend = error instanceof Error ? error : new Error(String(error));
|
|
249
|
+
await createAndSendEvent(
|
|
250
|
+
{
|
|
251
|
+
event: "resource.error",
|
|
252
|
+
resource: instance[ResourceKind],
|
|
253
|
+
duration: performance.now() - start,
|
|
254
|
+
phase: "destroy",
|
|
255
|
+
status: "deleting",
|
|
256
|
+
replaced: !!options?.replace,
|
|
257
|
+
},
|
|
258
|
+
errorToSend,
|
|
259
|
+
);
|
|
228
260
|
logger.error(error);
|
|
229
261
|
throw error;
|
|
230
262
|
}
|
package/src/docker/image.ts
CHANGED
|
@@ -190,7 +190,7 @@ export const Image = Resource(
|
|
|
190
190
|
|
|
191
191
|
// Add build arguments
|
|
192
192
|
for (const [key, value] of Object.entries(buildOptions)) {
|
|
193
|
-
buildArgs.push("--build-arg", `${key}
|
|
193
|
+
buildArgs.push("--build-arg", `${key}=${value}`);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
buildArgs.push("-f", dockerfile);
|
package/src/planetscale/api.ts
CHANGED
|
@@ -28,10 +28,6 @@ export interface PlanetScaleProps {
|
|
|
28
28
|
* @deprecated Use serviceTokenId and serviceToken instead.
|
|
29
29
|
*/
|
|
30
30
|
apiKey?: Secret;
|
|
31
|
-
/**
|
|
32
|
-
* The organization to use for authentication. Defaults to the value of the PLANETSCALE_ORGANIZATION or PLANETSCALE_ORG_ID environment variable.
|
|
33
|
-
*/
|
|
34
|
-
organizationId?: string;
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
export class PlanetScaleError extends Error {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { Resource } from "../resource.ts";
|
|
3
3
|
import { createPlanetScaleClient, type PlanetScaleProps } from "./api.ts";
|
|
4
|
+
import type { Database } from "./database.ts";
|
|
4
5
|
import {
|
|
5
6
|
ensureProductionBranchClusterSize,
|
|
6
7
|
sanitizeClusterSize,
|
|
@@ -20,14 +21,14 @@ export interface BranchProps extends PlanetScaleProps {
|
|
|
20
21
|
name?: string;
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* The organization
|
|
24
|
+
* The organization name. Automatically inferred from the database if the database is provided as an object.
|
|
24
25
|
*/
|
|
25
|
-
|
|
26
|
+
organization?: string;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* The database name
|
|
29
30
|
*/
|
|
30
|
-
|
|
31
|
+
database: string | Database;
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Whether or not the branch should be set to a production branch or not.
|
|
@@ -114,8 +115,8 @@ export interface Branch extends BranchProps {
|
|
|
114
115
|
* // Create a branch from 'main'
|
|
115
116
|
* const branch = await Branch("feature-123", {
|
|
116
117
|
* name: "feature-123",
|
|
117
|
-
*
|
|
118
|
-
*
|
|
118
|
+
* organization: "my-org",
|
|
119
|
+
* database: "my-database",
|
|
119
120
|
* parentBranch: "main"
|
|
120
121
|
* });
|
|
121
122
|
*
|
|
@@ -123,15 +124,15 @@ export interface Branch extends BranchProps {
|
|
|
123
124
|
* // Create a branch from another branch object
|
|
124
125
|
* const parentBranch = await Branch("staging", {
|
|
125
126
|
* name: "staging",
|
|
126
|
-
*
|
|
127
|
-
*
|
|
127
|
+
* organization: "my-org",
|
|
128
|
+
* database: "my-database",
|
|
128
129
|
* parentBranch: "main"
|
|
129
130
|
* });
|
|
130
131
|
*
|
|
131
132
|
* const featureBranch = await Branch("feature-456", {
|
|
132
133
|
* name: "feature-456",
|
|
133
|
-
*
|
|
134
|
-
*
|
|
134
|
+
* organization: "my-org",
|
|
135
|
+
* database: "my-database",
|
|
135
136
|
* parentBranch: parentBranch // Using Branch object instead of string
|
|
136
137
|
* });
|
|
137
138
|
*
|
|
@@ -139,8 +140,8 @@ export interface Branch extends BranchProps {
|
|
|
139
140
|
* // Create a branch from a backup
|
|
140
141
|
* const branch = await Branch("restored-branch", {
|
|
141
142
|
* name: "restored-branch",
|
|
142
|
-
*
|
|
143
|
-
*
|
|
143
|
+
* organization: "my-org",
|
|
144
|
+
* database: "my-database",
|
|
144
145
|
* parentBranch: "main",
|
|
145
146
|
* backupId: "backup-123",
|
|
146
147
|
* clusterSize: "PS_10"
|
|
@@ -164,6 +165,26 @@ export const Branch = Resource(
|
|
|
164
165
|
: typeof props.parentBranch === "string"
|
|
165
166
|
? props.parentBranch
|
|
166
167
|
: props.parentBranch.name;
|
|
168
|
+
const organization =
|
|
169
|
+
// @ts-expect-error - organizationId is a legacy thing, we keep this so we can destroy
|
|
170
|
+
this.output?.organizationId ??
|
|
171
|
+
props.organization ??
|
|
172
|
+
(typeof props.database !== "string"
|
|
173
|
+
? props.database.organization
|
|
174
|
+
: (process.env.PLANETSCALE_ORGANIZATION ??
|
|
175
|
+
process.env.PLANETSCALE_ORG_ID));
|
|
176
|
+
const database =
|
|
177
|
+
// @ts-expect-error - databaseName is a legacy thing, we keep this so we can destroy
|
|
178
|
+
this.output?.databaseName ??
|
|
179
|
+
(typeof props.database === "string"
|
|
180
|
+
? props.database
|
|
181
|
+
: props.database.name);
|
|
182
|
+
|
|
183
|
+
if (!organization) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
167
188
|
|
|
168
189
|
if (this.phase === "update" && this.output.name !== branchName) {
|
|
169
190
|
// TODO(sam): maybe we don't need to replace? just branch again? or rename?
|
|
@@ -174,8 +195,8 @@ export const Branch = Resource(
|
|
|
174
195
|
if (this.output?.name) {
|
|
175
196
|
const response = await api.deleteBranch({
|
|
176
197
|
path: {
|
|
177
|
-
organization
|
|
178
|
-
database
|
|
198
|
+
organization,
|
|
199
|
+
database,
|
|
179
200
|
name: this.output.name,
|
|
180
201
|
},
|
|
181
202
|
throwOnError: false,
|
|
@@ -196,8 +217,8 @@ export const Branch = Resource(
|
|
|
196
217
|
if (typeof props.parentBranch !== "string" && props.parentBranch) {
|
|
197
218
|
await waitForBranchReady(
|
|
198
219
|
api,
|
|
199
|
-
|
|
200
|
-
|
|
220
|
+
organization,
|
|
221
|
+
database,
|
|
201
222
|
props.parentBranch.name,
|
|
202
223
|
);
|
|
203
224
|
}
|
|
@@ -205,8 +226,8 @@ export const Branch = Resource(
|
|
|
205
226
|
// Check if branch exists
|
|
206
227
|
const getResponse = await api.getBranch({
|
|
207
228
|
path: {
|
|
208
|
-
organization
|
|
209
|
-
database
|
|
229
|
+
organization,
|
|
230
|
+
database,
|
|
210
231
|
name: branchName,
|
|
211
232
|
},
|
|
212
233
|
throwOnError: false,
|
|
@@ -256,8 +277,8 @@ export const Branch = Resource(
|
|
|
256
277
|
: "disableSafeMigrations"
|
|
257
278
|
]({
|
|
258
279
|
path: {
|
|
259
|
-
organization
|
|
260
|
-
database
|
|
280
|
+
organization,
|
|
281
|
+
database,
|
|
261
282
|
name: branchName,
|
|
262
283
|
},
|
|
263
284
|
});
|
|
@@ -279,8 +300,8 @@ export const Branch = Resource(
|
|
|
279
300
|
}
|
|
280
301
|
await ensureProductionBranchClusterSize(
|
|
281
302
|
api,
|
|
282
|
-
|
|
283
|
-
|
|
303
|
+
organization,
|
|
304
|
+
database,
|
|
284
305
|
branchName,
|
|
285
306
|
data.kind,
|
|
286
307
|
clusterSize,
|
|
@@ -299,8 +320,8 @@ export const Branch = Resource(
|
|
|
299
320
|
let clusterSize: string | undefined;
|
|
300
321
|
const parent = await waitForBranchReady(
|
|
301
322
|
api,
|
|
302
|
-
|
|
303
|
-
|
|
323
|
+
organization,
|
|
324
|
+
database,
|
|
304
325
|
parentBranchName,
|
|
305
326
|
);
|
|
306
327
|
if (props.clusterSize) {
|
|
@@ -315,8 +336,8 @@ export const Branch = Resource(
|
|
|
315
336
|
// Branch doesn't exist, create it
|
|
316
337
|
const { data } = await api.createBranch({
|
|
317
338
|
path: {
|
|
318
|
-
organization
|
|
319
|
-
database
|
|
339
|
+
organization,
|
|
340
|
+
database,
|
|
320
341
|
},
|
|
321
342
|
body: {
|
|
322
343
|
name: branchName,
|
|
@@ -331,18 +352,13 @@ export const Branch = Resource(
|
|
|
331
352
|
// Handle safe migrations if specified
|
|
332
353
|
if (props.safeMigrations !== undefined) {
|
|
333
354
|
// We can't change the migrations mode if the branch is not ready
|
|
334
|
-
await waitForBranchReady(
|
|
335
|
-
api,
|
|
336
|
-
props.organizationId,
|
|
337
|
-
props.databaseName,
|
|
338
|
-
branchName,
|
|
339
|
-
);
|
|
355
|
+
await waitForBranchReady(api, organization, database, branchName);
|
|
340
356
|
await api[
|
|
341
357
|
props.safeMigrations ? "enableSafeMigrations" : "disableSafeMigrations"
|
|
342
358
|
]({
|
|
343
359
|
path: {
|
|
344
|
-
organization
|
|
345
|
-
database
|
|
360
|
+
organization,
|
|
361
|
+
database,
|
|
346
362
|
name: branchName,
|
|
347
363
|
},
|
|
348
364
|
});
|
|
@@ -352,8 +368,8 @@ export const Branch = Resource(
|
|
|
352
368
|
if (clusterSize) {
|
|
353
369
|
await ensureProductionBranchClusterSize(
|
|
354
370
|
api,
|
|
355
|
-
|
|
356
|
-
|
|
371
|
+
organization,
|
|
372
|
+
database,
|
|
357
373
|
branchName,
|
|
358
374
|
data.kind,
|
|
359
375
|
clusterSize,
|
|
@@ -18,9 +18,10 @@ interface BaseDatabaseProps extends PlanetScaleProps {
|
|
|
18
18
|
name?: string;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* The organization
|
|
21
|
+
* The organization name where the database will be created
|
|
22
|
+
* @default process.env.PLANETSCALE_ORGANIZATION
|
|
22
23
|
*/
|
|
23
|
-
|
|
24
|
+
organization?: string;
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Whether to adopt the database if it already exists in Planetscale
|
|
@@ -157,6 +158,11 @@ export type Database = DatabaseProps & {
|
|
|
157
158
|
* HTML URL to access the database
|
|
158
159
|
*/
|
|
159
160
|
htmlUrl: string;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The organization of the database
|
|
164
|
+
*/
|
|
165
|
+
organization: string;
|
|
160
166
|
};
|
|
161
167
|
|
|
162
168
|
/**
|
|
@@ -166,7 +172,7 @@ export type Database = DatabaseProps & {
|
|
|
166
172
|
* // Create a basic database in a specific organization
|
|
167
173
|
* const db = await Database("my-app-db", {
|
|
168
174
|
* name: "my-app-db",
|
|
169
|
-
*
|
|
175
|
+
* organization: "my-org",
|
|
170
176
|
* clusterSize: "PS_10"
|
|
171
177
|
* });
|
|
172
178
|
*
|
|
@@ -174,7 +180,7 @@ export type Database = DatabaseProps & {
|
|
|
174
180
|
* // Create a database with specific region and settings
|
|
175
181
|
* const db = await Database("my-app-db", {
|
|
176
182
|
* name: "my-app-db",
|
|
177
|
-
*
|
|
183
|
+
* organization: "my-org",
|
|
178
184
|
* region: {
|
|
179
185
|
* slug: "us-east"
|
|
180
186
|
* },
|
|
@@ -188,7 +194,7 @@ export type Database = DatabaseProps & {
|
|
|
188
194
|
* // Create a database with custom API key
|
|
189
195
|
* const db = await Database("my-app-db", {
|
|
190
196
|
* name: "my-app-db",
|
|
191
|
-
*
|
|
197
|
+
* organization: "my-org",
|
|
192
198
|
* apiKey: alchemy.secret(process.env.CUSTOM_PLANETSCALE_TOKEN),
|
|
193
199
|
* clusterSize: "PS_10"
|
|
194
200
|
* });
|
|
@@ -210,11 +216,22 @@ export const Database = Resource(
|
|
|
210
216
|
arch: props.arch,
|
|
211
217
|
region: props.region?.slug,
|
|
212
218
|
});
|
|
219
|
+
const organization =
|
|
220
|
+
// @ts-expect-error - organizationId is a legacy thing, we keep this so we can destroy
|
|
221
|
+
this.output?.organizationId ??
|
|
222
|
+
props.organization ??
|
|
223
|
+
process.env.PLANETSCALE_ORGANIZATION ??
|
|
224
|
+
process.env.PLANETSCALE_ORG_ID;
|
|
225
|
+
if (!organization) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
228
|
+
);
|
|
229
|
+
}
|
|
213
230
|
|
|
214
231
|
if (this.phase === "update" && this.output.name !== databaseName) {
|
|
215
232
|
await api.updateDatabaseSettings({
|
|
216
233
|
path: {
|
|
217
|
-
organization
|
|
234
|
+
organization,
|
|
218
235
|
name: this.output.name,
|
|
219
236
|
},
|
|
220
237
|
body: { new_name: databaseName },
|
|
@@ -225,7 +242,7 @@ export const Database = Resource(
|
|
|
225
242
|
if (this.output?.name) {
|
|
226
243
|
const response = await api.deleteDatabase({
|
|
227
244
|
path: {
|
|
228
|
-
organization
|
|
245
|
+
organization,
|
|
229
246
|
name: this.output.name,
|
|
230
247
|
},
|
|
231
248
|
throwOnError: false,
|
|
@@ -243,7 +260,7 @@ export const Database = Resource(
|
|
|
243
260
|
// Check if database exists
|
|
244
261
|
const getResponse = await api.getDatabase({
|
|
245
262
|
path: {
|
|
246
|
-
organization
|
|
263
|
+
organization,
|
|
247
264
|
name: databaseName,
|
|
248
265
|
},
|
|
249
266
|
throwOnError: false,
|
|
@@ -259,20 +276,20 @@ export const Database = Resource(
|
|
|
259
276
|
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
260
277
|
const branchResponse = await api.getBranch({
|
|
261
278
|
path: {
|
|
262
|
-
organization
|
|
279
|
+
organization,
|
|
263
280
|
database: databaseName,
|
|
264
281
|
name: props.defaultBranch,
|
|
265
282
|
},
|
|
266
283
|
throwOnError: false,
|
|
267
284
|
});
|
|
268
285
|
if (!branchResponse.data) {
|
|
269
|
-
await waitForDatabaseReady(api,
|
|
286
|
+
await waitForDatabaseReady(api, organization, databaseName);
|
|
270
287
|
}
|
|
271
288
|
if (branchResponse.error && branchResponse.response.status === 404) {
|
|
272
289
|
// Create the branch
|
|
273
290
|
await api.createBranch({
|
|
274
291
|
path: {
|
|
275
|
-
organization
|
|
292
|
+
organization,
|
|
276
293
|
database: databaseName,
|
|
277
294
|
},
|
|
278
295
|
body: {
|
|
@@ -285,7 +302,7 @@ export const Database = Resource(
|
|
|
285
302
|
|
|
286
303
|
const { data } = await api.updateDatabaseSettings({
|
|
287
304
|
path: {
|
|
288
|
-
organization
|
|
305
|
+
organization,
|
|
289
306
|
name: databaseName,
|
|
290
307
|
},
|
|
291
308
|
body: {
|
|
@@ -303,7 +320,7 @@ export const Database = Resource(
|
|
|
303
320
|
|
|
304
321
|
await ensureProductionBranchClusterSize(
|
|
305
322
|
api,
|
|
306
|
-
|
|
323
|
+
organization,
|
|
307
324
|
databaseName,
|
|
308
325
|
props.defaultBranch || "main",
|
|
309
326
|
data.kind,
|
|
@@ -320,6 +337,7 @@ export const Database = Resource(
|
|
|
320
337
|
createdAt: data.created_at,
|
|
321
338
|
updatedAt: data.updated_at,
|
|
322
339
|
htmlUrl: data.html_url,
|
|
340
|
+
organization,
|
|
323
341
|
};
|
|
324
342
|
}
|
|
325
343
|
|
|
@@ -330,7 +348,7 @@ export const Database = Resource(
|
|
|
330
348
|
// Create new database
|
|
331
349
|
await api.createDatabase({
|
|
332
350
|
path: {
|
|
333
|
-
organization
|
|
351
|
+
organization,
|
|
334
352
|
},
|
|
335
353
|
body: {
|
|
336
354
|
name: databaseName,
|
|
@@ -343,7 +361,7 @@ export const Database = Resource(
|
|
|
343
361
|
// These settings can't be set on creation, so we need to patch them after creation.
|
|
344
362
|
const { data } = await api.updateDatabaseSettings({
|
|
345
363
|
path: {
|
|
346
|
-
organization
|
|
364
|
+
organization,
|
|
347
365
|
name: databaseName,
|
|
348
366
|
},
|
|
349
367
|
body: {
|
|
@@ -360,12 +378,12 @@ export const Database = Resource(
|
|
|
360
378
|
|
|
361
379
|
// If a non-'main' default branch is specified, create it
|
|
362
380
|
if (props.defaultBranch && props.defaultBranch !== "main") {
|
|
363
|
-
await waitForDatabaseReady(api,
|
|
381
|
+
await waitForDatabaseReady(api, organization, databaseName);
|
|
364
382
|
|
|
365
383
|
// Check if branch exists
|
|
366
384
|
const branchResponse = await api.getBranch({
|
|
367
385
|
path: {
|
|
368
|
-
organization
|
|
386
|
+
organization,
|
|
369
387
|
database: databaseName,
|
|
370
388
|
name: props.defaultBranch,
|
|
371
389
|
},
|
|
@@ -376,7 +394,7 @@ export const Database = Resource(
|
|
|
376
394
|
// Create the branch
|
|
377
395
|
await api.createBranch({
|
|
378
396
|
path: {
|
|
379
|
-
organization
|
|
397
|
+
organization,
|
|
380
398
|
database: databaseName,
|
|
381
399
|
},
|
|
382
400
|
body: {
|
|
@@ -387,7 +405,7 @@ export const Database = Resource(
|
|
|
387
405
|
|
|
388
406
|
await ensureProductionBranchClusterSize(
|
|
389
407
|
api,
|
|
390
|
-
|
|
408
|
+
organization,
|
|
391
409
|
databaseName,
|
|
392
410
|
props.defaultBranch || "main",
|
|
393
411
|
data.kind,
|
|
@@ -397,7 +415,7 @@ export const Database = Resource(
|
|
|
397
415
|
// Update database to use new branch as default
|
|
398
416
|
const { data: updatedData } = await api.updateDatabaseSettings({
|
|
399
417
|
path: {
|
|
400
|
-
organization
|
|
418
|
+
organization,
|
|
401
419
|
name: databaseName,
|
|
402
420
|
},
|
|
403
421
|
body: {
|
|
@@ -415,6 +433,7 @@ export const Database = Resource(
|
|
|
415
433
|
createdAt: updatedData.created_at,
|
|
416
434
|
updatedAt: updatedData.updated_at,
|
|
417
435
|
htmlUrl: updatedData.html_url,
|
|
436
|
+
organization,
|
|
418
437
|
};
|
|
419
438
|
}
|
|
420
439
|
}
|
|
@@ -429,6 +448,7 @@ export const Database = Resource(
|
|
|
429
448
|
createdAt: data.created_at,
|
|
430
449
|
updatedAt: data.updated_at,
|
|
431
450
|
htmlUrl: data.html_url,
|
|
451
|
+
organization,
|
|
432
452
|
};
|
|
433
453
|
},
|
|
434
454
|
);
|