alchemy 0.71.1 → 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.
Files changed (37) hide show
  1. package/bin/alchemy.js +1 -1
  2. package/lib/planetscale/api.d.ts +0 -4
  3. package/lib/planetscale/api.d.ts.map +1 -1
  4. package/lib/planetscale/api.js.map +1 -1
  5. package/lib/planetscale/branch.d.ts +12 -11
  6. package/lib/planetscale/branch.d.ts.map +1 -1
  7. package/lib/planetscale/branch.js +40 -23
  8. package/lib/planetscale/branch.js.map +1 -1
  9. package/lib/planetscale/database.d.ts +10 -5
  10. package/lib/planetscale/database.d.ts.map +1 -1
  11. package/lib/planetscale/database.js +30 -18
  12. package/lib/planetscale/database.js.map +1 -1
  13. package/lib/planetscale/index.d.ts +1 -0
  14. package/lib/planetscale/index.d.ts.map +1 -1
  15. package/lib/planetscale/index.js +1 -0
  16. package/lib/planetscale/index.js.map +1 -1
  17. package/lib/planetscale/organization.d.ts +5 -0
  18. package/lib/planetscale/organization.d.ts.map +1 -0
  19. package/lib/planetscale/organization.js +11 -0
  20. package/lib/planetscale/organization.js.map +1 -0
  21. package/lib/planetscale/password.d.ts +10 -9
  22. package/lib/planetscale/password.d.ts.map +1 -1
  23. package/lib/planetscale/password.js +28 -13
  24. package/lib/planetscale/password.js.map +1 -1
  25. package/lib/planetscale/role.d.ts +2 -1
  26. package/lib/planetscale/role.d.ts.map +1 -1
  27. package/lib/planetscale/role.js +11 -8
  28. package/lib/planetscale/role.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/planetscale/api.ts +0 -4
  31. package/src/planetscale/branch.ts +51 -35
  32. package/src/planetscale/database.ts +40 -20
  33. package/src/planetscale/index.ts +1 -0
  34. package/src/planetscale/organization.ts +17 -0
  35. package/src/planetscale/password.ts +34 -16
  36. package/src/planetscale/role.ts +16 -9
  37. package/workers/tunnel-proxy.js +1 -1
@@ -18,9 +18,10 @@ interface BaseDatabaseProps extends PlanetScaleProps {
18
18
  name?: string;
19
19
 
20
20
  /**
21
- * The organization ID where the database will be created
21
+ * The organization name where the database will be created
22
+ * @default process.env.PLANETSCALE_ORGANIZATION
22
23
  */
23
- organizationId: string;
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
- * organizationId: "my-org",
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
- * organizationId: "my-org",
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
- * organizationId: "my-org",
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: props.organizationId,
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: props.organizationId,
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: props.organizationId,
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: props.organizationId,
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, props.organizationId, databaseName);
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: props.organizationId,
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: props.organizationId,
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
- props.organizationId,
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: props.organizationId,
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: props.organizationId,
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, props.organizationId, databaseName);
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: props.organizationId,
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: props.organizationId,
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
- props.organizationId,
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: props.organizationId,
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
  );
@@ -1,6 +1,7 @@
1
1
  export * from "./api.ts";
2
2
  export * from "./branch.ts";
3
3
  export * from "./database.ts";
4
+ export * from "./organization.ts";
4
5
  export * from "./password.ts";
5
6
  export * from "./role.ts";
6
7
  export * from "./utils.ts";
@@ -0,0 +1,17 @@
1
+ import { createPlanetScaleClient, type PlanetScaleProps } from "./api.ts";
2
+ import type { Organization } from "./api/types.gen.ts";
3
+
4
+ export type OrganizationRef = Organization;
5
+
6
+ export async function OrganizationRef(
7
+ name: string | Organization,
8
+ options: PlanetScaleProps = {},
9
+ ) {
10
+ const api = createPlanetScaleClient(options);
11
+ const organization = await api.getOrganization({
12
+ path: {
13
+ name: typeof name === "string" ? name : name.id,
14
+ },
15
+ });
16
+ return organization.data;
17
+ }
@@ -22,8 +22,9 @@ export interface PasswordProps extends PlanetScaleProps {
22
22
  /**
23
23
  * The organization ID where the password will be created
24
24
  * Required when using string database name, optional when using Database or Branch resource
25
+ * @default process.env.PLANETSCALE_ORGANIZATION
25
26
  */
26
- organizationId?: string;
27
+ organization?: string;
27
28
 
28
29
  /**
29
30
  * The database where the password will be created
@@ -114,7 +115,7 @@ export interface Password extends PasswordProps {
114
115
  *
115
116
  * const readerPassword = await Password("app-reader", {
116
117
  * name: "app-reader",
117
- * organizationId: "my-org",
118
+ * organization: "my-org",
118
119
  * database: "my-app-db",
119
120
  * branch: "main",
120
121
  * role: "reader"
@@ -136,7 +137,7 @@ export interface Password extends PasswordProps {
136
137
  *
137
138
  * const writerPassword = await Password("app-writer", {
138
139
  * name: "app-writer",
139
- * organizationId: "my-org",
140
+ * organization: "my-org",
140
141
  * database: "my-app-db",
141
142
  * branch: "development",
142
143
  * role: "writer",
@@ -157,7 +158,7 @@ export interface Password extends PasswordProps {
157
158
  *
158
159
  * const adminPassword = await Password("admin-access", {
159
160
  * name: "admin-access",
160
- * organizationId: "my-org",
161
+ * organization: "my-org",
161
162
  * database: "my-app-db",
162
163
  * branch: "main",
163
164
  * role: "admin",
@@ -176,7 +177,7 @@ export interface Password extends PasswordProps {
176
177
  *
177
178
  * const password = await Password("custom-auth", {
178
179
  * name: "custom-auth",
179
- * organizationId: "my-org",
180
+ * organization: "my-org",
180
181
  * database: "my-app-db",
181
182
  * branch: "main",
182
183
  * role: "readwriter",
@@ -194,7 +195,7 @@ export interface Password extends PasswordProps {
194
195
  *
195
196
  * const replicaPassword = await Password("replica-reader", {
196
197
  * name: "replica-reader",
197
- * organizationId: "my-org",
198
+ * organization: "my-org",
198
199
  * database: "my-app-db",
199
200
  * branch: "main",
200
201
  * role: "reader",
@@ -211,7 +212,7 @@ export interface Password extends PasswordProps {
211
212
  *
212
213
  * const database = await Database("my-db", {
213
214
  * name: "my-app-db",
214
- * organizationId: "my-org",
215
+ * organization: "my-org",
215
216
  * clusterSize: "PS_10"
216
217
  * });
217
218
  *
@@ -232,13 +233,13 @@ export interface Password extends PasswordProps {
232
233
  *
233
234
  * const database = await Database("my-db", {
234
235
  * name: "my-app-db",
235
- * organizationId: "my-org",
236
+ * organization: "my-org",
236
237
  * clusterSize: "PS_10"
237
238
  * });
238
239
  *
239
240
  * const branch = await Branch("feature-branch", {
240
241
  * name: "feature-branch",
241
- * organizationId: "my-org",
242
+ * organization: "my-org",
242
243
  * databaseName: "my-app-db",
243
244
  * parentBranch: "main",
244
245
  * isProduction: false
@@ -266,19 +267,36 @@ export const Password = Resource(
266
267
  const name = `${(props.name ?? this.output?.name ?? this.scope.createPhysicalName(id)).toLowerCase()}-${nameSlug}`;
267
268
 
268
269
  const api = createPlanetScaleClient(props);
270
+ if (!props.organization && typeof props.database === "string") {
271
+ throw new Error(
272
+ "Organization ID is required when using string database name",
273
+ );
274
+ }
275
+
276
+ const organization =
277
+ // @ts-expect-error - organizationId is a legacy thing, we keep this so we can destroy
278
+ this.output?.organizationId ??
279
+ props.organization ??
280
+ (typeof props.database !== "string"
281
+ ? props.database.organization
282
+ : typeof props.branch !== "string" && props.branch
283
+ ? props.branch.organization
284
+ : (process.env.PLANETSCALE_ORGANIZATION ??
285
+ process.env.PLANETSCALE_ORG_ID));
269
286
  const database =
270
- typeof props.database === "string" ? props.database : props.database.name;
287
+ // @ts-expect-error - databaseName is a legacy thing, we keep this so we can destroy
288
+ this.output?.databaseName ??
289
+ (typeof props.database === "string"
290
+ ? props.database
291
+ : props.database.name);
271
292
  const branch =
272
293
  typeof props.branch === "string"
273
294
  ? props.branch
274
295
  : (props.branch?.name ?? "main");
275
- const organization =
276
- props.organizationId ??
277
- ((typeof props.branch !== "string" && props.branch?.organizationId) ||
278
- (typeof props.database !== "string" && props.database.organizationId));
279
-
280
296
  if (!organization) {
281
- throw new Error("Organization ID is required");
297
+ throw new Error(
298
+ "PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
299
+ );
282
300
  }
283
301
 
284
302
  if (this.phase === "delete") {
@@ -16,8 +16,9 @@ export interface RoleProps extends PlanetScaleProps {
16
16
  /**
17
17
  * The organization ID where the role will be created
18
18
  * Required when using string database name, optional when using Database resource
19
+ * @default process.env.PLANETSCALE_ORGANIZATION
19
20
  */
20
- organizationId?: string;
21
+ organization?: string;
21
22
 
22
23
  /**
23
24
  * The database where the role will be created
@@ -164,12 +165,21 @@ export const Role = Resource(
164
165
  props: RoleProps,
165
166
  ): Promise<Role> {
166
167
  const api = createPlanetScaleClient(props);
168
+
167
169
  const organization =
168
- typeof props.branch === "object"
169
- ? props.branch.organizationId
170
- : typeof props.database === "object"
171
- ? props.database.organizationId
172
- : props.organizationId;
170
+ // @ts-expect-error - organizationId is a legacy thing, we keep this so we can destroy
171
+ this.output?.organizationId ??
172
+ props.organization ??
173
+ (typeof props.database !== "string"
174
+ ? props.database.organization
175
+ : (process.env.PLANETSCALE_ORGANIZATION ??
176
+ process.env.PLANETSCALE_ORG_ID));
177
+ if (!organization) {
178
+ throw new Error(
179
+ "PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
180
+ );
181
+ }
182
+
173
183
  const database =
174
184
  typeof props.database === "string" ? props.database : props.database.name;
175
185
  const branch =
@@ -179,9 +189,6 @@ export const Role = Resource(
179
189
  const inheritedRoles = Array.isArray(props.inheritedRoles)
180
190
  ? props.inheritedRoles
181
191
  : props.inheritedRoles.inheritedRoles;
182
- if (!organization) {
183
- throw new Error("Organization ID is required");
184
- }
185
192
 
186
193
  switch (this.phase) {
187
194
  case "delete": {
@@ -34,7 +34,7 @@ var h={async fetch(e,r){let n=new URL(e.url);n.host=r.TUNNEL_HOST;let l=new Head
34
34
  Alchemy</a>.</p>
35
35
  </div>
36
36
  <div class="bg-slate-200 px-5 py-3 flex flex-col w-full max-w-lg">
37
- <p class="text-sm text-slate-500">Alchemy 0.71.1</p>
37
+ <p class="text-sm text-slate-500">Alchemy 0.72.0</p>
38
38
  </div>
39
39
  </div>
40
40
  </body>