alchemy 0.83.3 → 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.
Files changed (111) hide show
  1. package/bin/alchemy.js +1 -1
  2. package/lib/cloudflare/api-error.d.ts +11 -0
  3. package/lib/cloudflare/api-error.d.ts.map +1 -1
  4. package/lib/cloudflare/api-error.js +11 -0
  5. package/lib/cloudflare/api-error.js.map +1 -1
  6. package/lib/cloudflare/api.js +1 -1
  7. package/lib/cloudflare/api.js.map +1 -1
  8. package/lib/cloudflare/bindings.d.ts +12 -2
  9. package/lib/cloudflare/bindings.d.ts.map +1 -1
  10. package/lib/cloudflare/bindings.js.map +1 -1
  11. package/lib/cloudflare/bound.d.ts +2 -1
  12. package/lib/cloudflare/bound.d.ts.map +1 -1
  13. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  14. package/lib/cloudflare/d1-database.js +9 -1
  15. package/lib/cloudflare/d1-database.js.map +1 -1
  16. package/lib/cloudflare/index.d.ts +1 -0
  17. package/lib/cloudflare/index.d.ts.map +1 -1
  18. package/lib/cloudflare/index.js +1 -0
  19. package/lib/cloudflare/index.js.map +1 -1
  20. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  21. package/lib/cloudflare/kv-namespace.js +2 -2
  22. package/lib/cloudflare/kv-namespace.js.map +1 -1
  23. package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
  24. package/lib/cloudflare/miniflare/build-worker-options.js +15 -0
  25. package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
  26. package/lib/cloudflare/miniflare/miniflare-controller.d.ts +1 -1
  27. package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -1
  28. package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
  29. package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +41 -3
  30. package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
  31. package/lib/cloudflare/vpc-service.d.ts +288 -0
  32. package/lib/cloudflare/vpc-service.d.ts.map +1 -0
  33. package/lib/cloudflare/vpc-service.js +238 -0
  34. package/lib/cloudflare/vpc-service.js.map +1 -0
  35. package/lib/cloudflare/worker-metadata.d.ts +1 -0
  36. package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
  37. package/lib/cloudflare/worker-metadata.js +8 -0
  38. package/lib/cloudflare/worker-metadata.js.map +1 -1
  39. package/lib/cloudflare/worker-stub.d.ts.map +1 -1
  40. package/lib/cloudflare/worker-stub.js +8 -10
  41. package/lib/cloudflare/worker-stub.js.map +1 -1
  42. package/lib/cloudflare/worker-subdomain.d.ts +11 -8
  43. package/lib/cloudflare/worker-subdomain.d.ts.map +1 -1
  44. package/lib/cloudflare/worker-subdomain.js +16 -25
  45. package/lib/cloudflare/worker-subdomain.js.map +1 -1
  46. package/lib/cloudflare/worker.d.ts +16 -0
  47. package/lib/cloudflare/worker.d.ts.map +1 -1
  48. package/lib/cloudflare/worker.js +50 -24
  49. package/lib/cloudflare/worker.js.map +1 -1
  50. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  51. package/lib/cloudflare/wrangler.json.js +9 -0
  52. package/lib/cloudflare/wrangler.json.js.map +1 -1
  53. package/lib/planetscale/api/sdk.gen.d.ts +874 -190
  54. package/lib/planetscale/api/sdk.gen.d.ts.map +1 -1
  55. package/lib/planetscale/api/sdk.gen.js +1250 -306
  56. package/lib/planetscale/api/sdk.gen.js.map +1 -1
  57. package/lib/planetscale/api/types.gen.d.ts +8241 -4128
  58. package/lib/planetscale/api/types.gen.d.ts.map +1 -1
  59. package/lib/planetscale/branch.js +4 -4
  60. package/lib/planetscale/branch.js.map +1 -1
  61. package/lib/planetscale/database.d.ts +43 -24
  62. package/lib/planetscale/database.d.ts.map +1 -1
  63. package/lib/planetscale/database.js +39 -18
  64. package/lib/planetscale/database.js.map +1 -1
  65. package/lib/planetscale/default-role.d.ts +51 -0
  66. package/lib/planetscale/default-role.d.ts.map +1 -0
  67. package/lib/planetscale/default-role.js +100 -0
  68. package/lib/planetscale/default-role.js.map +1 -0
  69. package/lib/planetscale/index.d.ts +1 -0
  70. package/lib/planetscale/index.d.ts.map +1 -1
  71. package/lib/planetscale/index.js +1 -0
  72. package/lib/planetscale/index.js.map +1 -1
  73. package/lib/planetscale/organization.js +1 -1
  74. package/lib/planetscale/organization.js.map +1 -1
  75. package/lib/planetscale/role.d.ts +1 -1
  76. package/lib/planetscale/role.d.ts.map +1 -1
  77. package/lib/planetscale/role.js +1 -1
  78. package/lib/planetscale/role.js.map +1 -1
  79. package/lib/planetscale/utils.d.ts +1 -1
  80. package/lib/planetscale/utils.d.ts.map +1 -1
  81. package/lib/planetscale/utils.js +9 -10
  82. package/lib/planetscale/utils.js.map +1 -1
  83. package/lib/state/sqlite-state-store.js +2 -0
  84. package/lib/state/sqlite-state-store.js.map +1 -1
  85. package/package.json +2 -2
  86. package/src/cloudflare/api-error.ts +19 -0
  87. package/src/cloudflare/api.ts +1 -1
  88. package/src/cloudflare/bindings.ts +15 -2
  89. package/src/cloudflare/bound.ts +6 -3
  90. package/src/cloudflare/d1-database.ts +11 -4
  91. package/src/cloudflare/index.ts +1 -0
  92. package/src/cloudflare/kv-namespace.ts +6 -2
  93. package/src/cloudflare/miniflare/build-worker-options.ts +30 -18
  94. package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +47 -2
  95. package/src/cloudflare/vpc-service.ts +466 -0
  96. package/src/cloudflare/worker-metadata.ts +8 -0
  97. package/src/cloudflare/worker-stub.ts +9 -11
  98. package/src/cloudflare/worker-subdomain.ts +29 -34
  99. package/src/cloudflare/worker.ts +170 -98
  100. package/src/cloudflare/wrangler.json.ts +8 -0
  101. package/src/planetscale/api/sdk.gen.ts +2331 -987
  102. package/src/planetscale/api/types.gen.ts +8980 -4574
  103. package/src/planetscale/branch.ts +4 -4
  104. package/src/planetscale/database.ts +87 -46
  105. package/src/planetscale/default-role.ts +162 -0
  106. package/src/planetscale/index.ts +1 -0
  107. package/src/planetscale/organization.ts +1 -1
  108. package/src/planetscale/role.ts +3 -2
  109. package/src/planetscale/utils.ts +10 -10
  110. package/src/state/sqlite-state-store.ts +2 -0
  111. package/workers/tunnel-proxy.js +1 -1
@@ -54,7 +54,11 @@ import {
54
54
  getWorkerSettings,
55
55
  prepareWorkerMetadata,
56
56
  } from "./worker-metadata.ts";
57
- import { WorkerSubdomain, disableWorkerSubdomain } from "./worker-subdomain.ts";
57
+ import {
58
+ createWorkerUrl,
59
+ disableWorkerSubdomain,
60
+ enableWorkerSubdomain,
61
+ } from "./worker-subdomain.ts";
58
62
  import { createTail } from "./worker-tail.ts";
59
63
  import {
60
64
  Workflow,
@@ -176,6 +180,14 @@ export interface BaseWorkerProps<
176
180
  */
177
181
  url?: boolean;
178
182
 
183
+ /**
184
+ * Whether to enable preview subdomains for this worker
185
+ *
186
+ * If true, the worker will be available at {name}-preview.{subdomain}.workers.dev
187
+ * @default false if durable objects are used, otherwise true
188
+ */
189
+ previewSubdomains?: boolean;
190
+
179
191
  /**
180
192
  * Specify the observability behavior of the Worker.
181
193
  *
@@ -384,6 +396,15 @@ export interface BaseWorkerProps<
384
396
  * @default 30_000 (30 seconds)
385
397
  */
386
398
  cpu_ms?: number;
399
+ /**
400
+ * The maximum number of subrequests allowed per invocation.
401
+ * Defaults to 50 for free accounts and 10,000 for paid accounts.
402
+ * Paid accounts can increase up to 10,000,000.
403
+ *
404
+ * @see https://developers.cloudflare.com/workers/platform/limits/#subrequests
405
+ * @see https://developers.cloudflare.com/workers/wrangler/configuration/#limits
406
+ */
407
+ subrequests?: number;
387
408
  };
388
409
 
389
410
  /**
@@ -1062,6 +1083,7 @@ const _Worker = Resource(
1062
1083
  durableObjects,
1063
1084
  };
1064
1085
  })();
1086
+ const scriptName = options.name;
1065
1087
 
1066
1088
  if (this.phase === "delete") {
1067
1089
  // Heuristic: we must detect the case where this is the Worker wrapped in the old Website nested scope and not delete it
@@ -1142,6 +1164,7 @@ const _Worker = Resource(
1142
1164
  local: true,
1143
1165
  dispatchNamespace: options.dispatchNamespace,
1144
1166
  containers: options.containers,
1167
+ hasDurableObjects: options.durableObjects.length > 0,
1145
1168
  },
1146
1169
  );
1147
1170
  return {
@@ -1224,6 +1247,7 @@ const _Worker = Resource(
1224
1247
  namespace: options.dispatchNamespace,
1225
1248
  })
1226
1249
  : undefined;
1250
+
1227
1251
  let result: PutWorkerResult;
1228
1252
 
1229
1253
  if (this.scope.watch) {
@@ -1245,15 +1269,58 @@ const _Worker = Resource(
1245
1269
  });
1246
1270
  this.onCleanup(() => tail?.close());
1247
1271
  } else {
1248
- result = await putWorker(api, {
1249
- ...props,
1250
- workerName: options.name,
1251
- scriptBundle: await bundle.create(),
1252
- dispatchNamespace: options.dispatchNamespace,
1253
- compatibilityDate: options.compatibilityDate,
1254
- compatibilityFlags: options.compatibilityFlags,
1255
- assetUploadResult: assets,
1256
- });
1272
+ // cloudflare has awkward sequencing requirements for modifying subdomains
1273
+ // because conflicts with Durable Objects and preview_enabled is stateful
1274
+ // to solve this, we try and do both in parallel and push them through
1275
+ const bruteForce = <T>(operation: () => Promise<T>) =>
1276
+ withExponentialBackoff(
1277
+ operation,
1278
+ (error) => {
1279
+ operation;
1280
+ return (
1281
+ error instanceof CloudflareApiError &&
1282
+ error.status === 400 &&
1283
+ error.message.includes(
1284
+ "Cannot use Durable Objects with Preview URLs",
1285
+ )
1286
+ );
1287
+ },
1288
+ 10,
1289
+ 100,
1290
+ 1000,
1291
+ );
1292
+ const scriptBundle = await bundle.create();
1293
+ const [_, _result] = await Promise.all([
1294
+ bruteForce(updateSubdomain),
1295
+ bruteForce(() =>
1296
+ putWorker(api, {
1297
+ ...props,
1298
+ workerName: options.name,
1299
+ scriptBundle,
1300
+ dispatchNamespace: options.dispatchNamespace,
1301
+ compatibilityDate: options.compatibilityDate,
1302
+ compatibilityFlags: options.compatibilityFlags,
1303
+ assetUploadResult: assets,
1304
+ }),
1305
+ ),
1306
+ ]);
1307
+ result = _result;
1308
+ }
1309
+
1310
+ async function updateSubdomain() {
1311
+ if (options.dispatchNamespace) {
1312
+ return;
1313
+ }
1314
+ if (props.url === false) {
1315
+ await disableWorkerSubdomain(api, scriptName);
1316
+ } else {
1317
+ const previewsEnabled = options.durableObjects.length === 0;
1318
+ await enableWorkerSubdomain(
1319
+ api,
1320
+ scriptName,
1321
+ props.previewSubdomains ?? previewsEnabled,
1322
+ );
1323
+ }
1257
1324
  }
1258
1325
 
1259
1326
  if (props.crons) {
@@ -1273,7 +1340,7 @@ const _Worker = Resource(
1273
1340
  ),
1274
1341
  );
1275
1342
 
1276
- const { domains, routes, subdomain } = await provisionResources(
1343
+ const { domains, routes } = await provisionResources(
1277
1344
  {
1278
1345
  ...props,
1279
1346
  adopt,
@@ -1283,6 +1350,7 @@ const _Worker = Resource(
1283
1350
  local: false,
1284
1351
  dispatchNamespace: options.dispatchNamespace,
1285
1352
  containers: options.containers,
1353
+ hasDurableObjects: options.durableObjects.length > 0,
1286
1354
  result,
1287
1355
  api,
1288
1356
  },
@@ -1305,7 +1373,14 @@ const _Worker = Resource(
1305
1373
  createdAt: this.output?.createdAt ?? now,
1306
1374
  updatedAt: now,
1307
1375
  eventSources: props.eventSources,
1308
- url: subdomain?.url,
1376
+ url:
1377
+ props.url !== false
1378
+ ? await createWorkerUrl(
1379
+ api,
1380
+ scriptName,
1381
+ props.version ? result?.id : undefined,
1382
+ )
1383
+ : undefined,
1309
1384
  assets: props.assets,
1310
1385
  crons: props.crons,
1311
1386
  tailConsumers: props.tailConsumers,
@@ -1359,27 +1434,31 @@ const assertUnique = <T, Key extends keyof T>(
1359
1434
  }
1360
1435
  };
1361
1436
 
1437
+ type ProvisionOptions =
1438
+ | {
1439
+ name: string;
1440
+ local: true;
1441
+ dispatchNamespace: string | undefined;
1442
+ containers: Container[] | undefined;
1443
+ hasDurableObjects: boolean;
1444
+ result?: undefined;
1445
+ api?: undefined;
1446
+ }
1447
+ | {
1448
+ name: string;
1449
+ local: false;
1450
+ dispatchNamespace: string | undefined;
1451
+ containers: Container[] | undefined;
1452
+ hasDurableObjects: boolean;
1453
+ result: PutWorkerResult;
1454
+ api: CloudflareApi;
1455
+ };
1456
+
1362
1457
  async function provisionResources<B extends Bindings>(
1363
1458
  props: WorkerProps<B> & {
1364
1459
  adopt: boolean;
1365
1460
  },
1366
- options:
1367
- | {
1368
- name: string;
1369
- local: true;
1370
- dispatchNamespace: string | undefined;
1371
- containers: Container[] | undefined;
1372
- result?: undefined;
1373
- api?: undefined;
1374
- }
1375
- | {
1376
- name: string;
1377
- local: false;
1378
- dispatchNamespace: string | undefined;
1379
- containers: Container[] | undefined;
1380
- result: PutWorkerResult;
1381
- api: CloudflareApi;
1382
- },
1461
+ options: ProvisionOptions,
1383
1462
  ) {
1384
1463
  let metadataPromise: ReturnType<typeof getVersionMetadata> | undefined;
1385
1464
 
@@ -1452,76 +1531,66 @@ async function provisionResources<B extends Bindings>(
1452
1531
  assertUnique(input.domains, "name", "Custom Domain");
1453
1532
  }
1454
1533
 
1455
- const [containers, domains, eventSources, routes, subdomain] =
1456
- await Promise.all([
1457
- input.containers
1458
- ? Promise.all(
1459
- input.containers.map(async (container) => {
1460
- return await ContainerApplication(container.id, {
1461
- ...container,
1462
- durableObjects: {
1463
- namespaceId: await getContainerNamespaceId(container),
1464
- },
1465
- dev: options.local,
1466
- ...input.api,
1467
- });
1468
- }),
1469
- )
1470
- : undefined,
1471
- input.domains
1472
- ? Promise.all(
1473
- input.domains.map(async (domain) => {
1474
- return await CustomDomain(domain.name, {
1475
- name: domain.name,
1476
- zoneId: domain.zoneId,
1477
- adopt: domain.adopt,
1478
- workerName: options.name,
1479
- dev: options.local,
1480
- ...input.api,
1481
- });
1482
- }),
1483
- )
1484
- : undefined,
1485
- input.eventSources
1486
- ? Promise.all(
1487
- input.eventSources.map(async (eventSource) => {
1488
- return await QueueConsumer(`${eventSource.queue.id}-consumer`, {
1489
- queue: eventSource.queue,
1490
- scriptName: options.name,
1491
- settings: eventSource.settings,
1492
- adopt: props.adopt,
1493
- dev: options.local,
1494
- ...input.api,
1495
- });
1496
- }),
1497
- )
1498
- : undefined,
1499
- input.routes
1500
- ? Promise.all(
1501
- input.routes.map(async (route) => {
1502
- return await Route(route.pattern, {
1503
- pattern: route.pattern,
1504
- script: options.name,
1505
- zoneId: route.zoneId,
1506
- adopt: route.adopt,
1507
- dev: options.local,
1508
- ...input.api,
1509
- });
1510
- }),
1511
- )
1512
- : undefined,
1513
- (props.url ?? !options.dispatchNamespace)
1514
- ? WorkerSubdomain("url", {
1515
- scriptName: options.name,
1516
- previewVersionId: props.version ? options.result?.id : undefined,
1517
- retain: !!props.version,
1518
- dev: options.local,
1519
- ...input.api,
1520
- })
1521
- : undefined,
1522
- ]);
1534
+ const [containers, domains, eventSources, routes] = await Promise.all([
1535
+ input.containers
1536
+ ? Promise.all(
1537
+ input.containers.map(async (container) => {
1538
+ return await ContainerApplication(container.id, {
1539
+ ...container,
1540
+ durableObjects: {
1541
+ namespaceId: await getContainerNamespaceId(container),
1542
+ },
1543
+ dev: options.local,
1544
+ ...input.api,
1545
+ });
1546
+ }),
1547
+ )
1548
+ : undefined,
1549
+ input.domains
1550
+ ? Promise.all(
1551
+ input.domains.map(async (domain) => {
1552
+ return await CustomDomain(domain.name, {
1553
+ name: domain.name,
1554
+ zoneId: domain.zoneId,
1555
+ adopt: domain.adopt,
1556
+ workerName: options.name,
1557
+ dev: options.local,
1558
+ ...input.api,
1559
+ });
1560
+ }),
1561
+ )
1562
+ : undefined,
1563
+ input.eventSources
1564
+ ? Promise.all(
1565
+ input.eventSources.map(async (eventSource) => {
1566
+ return await QueueConsumer(`${eventSource.queue.id}-consumer`, {
1567
+ queue: eventSource.queue,
1568
+ scriptName: options.name,
1569
+ settings: eventSource.settings,
1570
+ adopt: props.adopt,
1571
+ dev: options.local,
1572
+ ...input.api,
1573
+ });
1574
+ }),
1575
+ )
1576
+ : undefined,
1577
+ input.routes
1578
+ ? Promise.all(
1579
+ input.routes.map(async (route) => {
1580
+ return await Route(route.pattern, {
1581
+ pattern: route.pattern,
1582
+ script: options.name,
1583
+ zoneId: route.zoneId,
1584
+ adopt: route.adopt,
1585
+ dev: options.local,
1586
+ ...input.api,
1587
+ });
1588
+ }),
1589
+ )
1590
+ : undefined,
1591
+ ]);
1523
1592
 
1524
- return { containers, domains, routes, eventSources, subdomain };
1593
+ return { containers, domains, routes, eventSources };
1525
1594
 
1526
1595
  async function getContainerNamespaceId(container: Container) {
1527
1596
  if (options.local) {
@@ -1774,6 +1843,9 @@ export async function putWorker(
1774
1843
  (err instanceof CloudflareApiError &&
1775
1844
  err.status === 400 &&
1776
1845
  err.message.match(/binding.*failed to generate/)),
1846
+ // (err.status === 400 &&
1847
+ // err.message.includes("100331") &&
1848
+ // err.message.includes("Cannot use Durable Objects with Preview URLs")),
1777
1849
  10,
1778
1850
  100,
1779
1851
  );
@@ -164,6 +164,7 @@ export async function WranglerJson(
164
164
  limits: worker.limits
165
165
  ? {
166
166
  cpu_ms: worker.limits.cpu_ms ?? 30_000,
167
+ subrequests: worker.limits.subrequests,
167
168
  }
168
169
  : undefined,
169
170
  logpush: worker.logpush,
@@ -286,6 +287,7 @@ async function processBindings(
286
287
  const ratelimits: WranglerJsonConfig["ratelimits"] = [];
287
288
  const containers: WranglerJsonConfig["containers"] = [];
288
289
  const workerLoaders: WranglerJsonConfig["worker_loaders"] = [];
290
+ const vpcServices: WranglerJsonConfig["vpc_services"] = [];
289
291
 
290
292
  for (const eventSource of eventSources ?? []) {
291
293
  if (isQueueEventSource(eventSource)) {
@@ -535,6 +537,12 @@ async function processBindings(
535
537
  workerLoaders.push({
536
538
  binding: bindingName,
537
539
  });
540
+ } else if (binding.type === "vpc_service") {
541
+ vpcServices.push({
542
+ binding: bindingName,
543
+ service_id: binding.serviceId,
544
+ remote: true,
545
+ });
538
546
  } else {
539
547
  console.log("binding", binding);
540
548
  return assertNever(binding);