alchemy 0.90.1 → 0.92.1

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 (133) hide show
  1. package/bin/alchemy.js +3 -13
  2. package/bin/commands/util.ts +0 -3
  3. package/lib/cloudflare/astro/astro.d.ts +4 -4
  4. package/lib/cloudflare/astro/astro.d.ts.map +1 -1
  5. package/lib/cloudflare/astro/astro.js +2 -2
  6. package/lib/cloudflare/astro/astro.js.map +1 -1
  7. package/lib/cloudflare/auth.d.ts +0 -3
  8. package/lib/cloudflare/auth.d.ts.map +1 -1
  9. package/lib/cloudflare/auth.js +0 -3
  10. package/lib/cloudflare/auth.js.map +1 -1
  11. package/lib/cloudflare/bindings.d.ts +10 -2
  12. package/lib/cloudflare/bindings.d.ts.map +1 -1
  13. package/lib/cloudflare/bindings.js.map +1 -1
  14. package/lib/cloudflare/bound.d.ts +2 -1
  15. package/lib/cloudflare/bound.d.ts.map +1 -1
  16. package/lib/cloudflare/bucket.d.ts.map +1 -1
  17. package/lib/cloudflare/bucket.js +3 -1
  18. package/lib/cloudflare/bucket.js.map +1 -1
  19. package/lib/cloudflare/bun-spa/bun-spa.d.ts +3 -3
  20. package/lib/cloudflare/bun-spa/bun-spa.d.ts.map +1 -1
  21. package/lib/cloudflare/bun-spa/bun-spa.js.map +1 -1
  22. package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
  23. package/lib/cloudflare/bundle/plugin-wasm.js +20 -2
  24. package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
  25. package/lib/cloudflare/container.d.ts +7 -0
  26. package/lib/cloudflare/container.d.ts.map +1 -1
  27. package/lib/cloudflare/container.js +1 -1
  28. package/lib/cloudflare/container.js.map +1 -1
  29. package/lib/cloudflare/custom-domain.d.ts +7 -0
  30. package/lib/cloudflare/custom-domain.d.ts.map +1 -1
  31. package/lib/cloudflare/custom-domain.js +3 -1
  32. package/lib/cloudflare/custom-domain.js.map +1 -1
  33. package/lib/cloudflare/email-address.d.ts +11 -2
  34. package/lib/cloudflare/email-address.d.ts.map +1 -1
  35. package/lib/cloudflare/email-address.js +20 -8
  36. package/lib/cloudflare/email-address.js.map +1 -1
  37. package/lib/cloudflare/email-catch-all.d.ts +13 -5
  38. package/lib/cloudflare/email-catch-all.d.ts.map +1 -1
  39. package/lib/cloudflare/email-catch-all.js +21 -4
  40. package/lib/cloudflare/email-catch-all.js.map +1 -1
  41. package/lib/cloudflare/email-common.d.ts +4 -0
  42. package/lib/cloudflare/email-common.d.ts.map +1 -0
  43. package/lib/cloudflare/email-common.js +7 -0
  44. package/lib/cloudflare/email-common.js.map +1 -0
  45. package/lib/cloudflare/email-routing.d.ts +1 -0
  46. package/lib/cloudflare/email-routing.d.ts.map +1 -1
  47. package/lib/cloudflare/email-routing.js +6 -2
  48. package/lib/cloudflare/email-routing.js.map +1 -1
  49. package/lib/cloudflare/email-rule.d.ts +4 -3
  50. package/lib/cloudflare/email-rule.d.ts.map +1 -1
  51. package/lib/cloudflare/email-rule.js +33 -4
  52. package/lib/cloudflare/email-rule.js.map +1 -1
  53. package/lib/cloudflare/email-sender.d.ts +38 -0
  54. package/lib/cloudflare/email-sender.d.ts.map +1 -0
  55. package/lib/cloudflare/email-sender.js +23 -0
  56. package/lib/cloudflare/email-sender.js.map +1 -0
  57. package/lib/cloudflare/index.d.ts +1 -0
  58. package/lib/cloudflare/index.d.ts.map +1 -1
  59. package/lib/cloudflare/index.js +1 -0
  60. package/lib/cloudflare/index.js.map +1 -1
  61. package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
  62. package/lib/cloudflare/miniflare/build-worker-options.js +29 -0
  63. package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
  64. package/lib/cloudflare/miniflare/miniflare-controller.js +14 -1
  65. package/lib/cloudflare/miniflare/miniflare-controller.js.map +1 -1
  66. package/lib/cloudflare/nuxt/nuxt.d.ts +4 -4
  67. package/lib/cloudflare/nuxt/nuxt.d.ts.map +1 -1
  68. package/lib/cloudflare/nuxt/nuxt.js.map +1 -1
  69. package/lib/cloudflare/react-router/react-router.d.ts +4 -4
  70. package/lib/cloudflare/react-router/react-router.d.ts.map +1 -1
  71. package/lib/cloudflare/react-router/react-router.js.map +1 -1
  72. package/lib/cloudflare/redwood/redwood.d.ts +4 -4
  73. package/lib/cloudflare/redwood/redwood.d.ts.map +1 -1
  74. package/lib/cloudflare/redwood/redwood.js.map +1 -1
  75. package/lib/cloudflare/route.d.ts +7 -0
  76. package/lib/cloudflare/route.d.ts.map +1 -1
  77. package/lib/cloudflare/route.js +1 -1
  78. package/lib/cloudflare/route.js.map +1 -1
  79. package/lib/cloudflare/sveltekit/sveltekit.d.ts +4 -4
  80. package/lib/cloudflare/sveltekit/sveltekit.d.ts.map +1 -1
  81. package/lib/cloudflare/sveltekit/sveltekit.js.map +1 -1
  82. package/lib/cloudflare/tanstack-start/tanstack-start.d.ts +4 -4
  83. package/lib/cloudflare/tanstack-start/tanstack-start.d.ts.map +1 -1
  84. package/lib/cloudflare/tanstack-start/tanstack-start.js.map +1 -1
  85. package/lib/cloudflare/vite/vite.d.ts +4 -4
  86. package/lib/cloudflare/vite/vite.d.ts.map +1 -1
  87. package/lib/cloudflare/vite/vite.js.map +1 -1
  88. package/lib/cloudflare/website.d.ts +4 -4
  89. package/lib/cloudflare/website.d.ts.map +1 -1
  90. package/lib/cloudflare/website.js.map +1 -1
  91. package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
  92. package/lib/cloudflare/worker-metadata.js +9 -0
  93. package/lib/cloudflare/worker-metadata.js.map +1 -1
  94. package/lib/cloudflare/worker.d.ts +15 -0
  95. package/lib/cloudflare/worker.d.ts.map +1 -1
  96. package/lib/cloudflare/worker.js +14 -2
  97. package/lib/cloudflare/worker.js.map +1 -1
  98. package/lib/cloudflare/wrangler.json.js +13 -0
  99. package/lib/cloudflare/wrangler.json.js.map +1 -1
  100. package/package.json +4 -4
  101. package/src/cloudflare/astro/astro.ts +14 -13
  102. package/src/cloudflare/auth.ts +0 -3
  103. package/src/cloudflare/bindings.ts +11 -0
  104. package/src/cloudflare/bound.ts +56 -53
  105. package/src/cloudflare/bucket.ts +1 -0
  106. package/src/cloudflare/bun-spa/bun-spa.ts +15 -6
  107. package/src/cloudflare/bundle/plugin-wasm.ts +21 -2
  108. package/src/cloudflare/container.ts +9 -1
  109. package/src/cloudflare/custom-domain.ts +11 -1
  110. package/src/cloudflare/email-address.ts +39 -12
  111. package/src/cloudflare/email-catch-all.ts +41 -10
  112. package/src/cloudflare/email-common.ts +11 -0
  113. package/src/cloudflare/email-routing.ts +7 -2
  114. package/src/cloudflare/email-rule.ts +43 -7
  115. package/src/cloudflare/email-sender.ts +49 -0
  116. package/src/cloudflare/index.ts +1 -0
  117. package/src/cloudflare/miniflare/build-worker-options.ts +69 -1
  118. package/src/cloudflare/miniflare/miniflare-controller.ts +18 -1
  119. package/src/cloudflare/nuxt/nuxt.ts +12 -8
  120. package/src/cloudflare/react-router/react-router.ts +14 -7
  121. package/src/cloudflare/redwood/redwood.ts +12 -8
  122. package/src/cloudflare/route.ts +9 -1
  123. package/src/cloudflare/sveltekit/sveltekit.ts +14 -7
  124. package/src/cloudflare/tanstack-start/tanstack-start.ts +14 -7
  125. package/src/cloudflare/vite/vite.ts +12 -8
  126. package/src/cloudflare/website.ts +13 -12
  127. package/src/cloudflare/worker-metadata.ts +8 -0
  128. package/src/cloudflare/worker.ts +36 -2
  129. package/src/cloudflare/wrangler.json.ts +17 -0
  130. package/workers/cloudflare-state-store.js +57 -57
  131. package/workers/remote-binding-proxy.js +7 -3
  132. package/workers/remote-binding-proxy.ts +20 -3
  133. package/workers/tunnel-proxy.js +1 -1
@@ -18,10 +18,10 @@ import { computeWorkerDevDomain } from "./worker-subdomain.ts";
18
18
  import { type AssetsConfig, Worker, type WorkerProps } from "./worker.ts";
19
19
  import { WranglerJson, type WranglerJsonSpec } from "./wrangler.json.ts";
20
20
 
21
- export interface WebsiteProps<B extends Bindings> extends Omit<
22
- WorkerProps<B>,
23
- "assets" | "dev"
24
- > {
21
+ export interface WebsiteProps<
22
+ B extends Bindings,
23
+ RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
24
+ > extends Omit<WorkerProps<B, RPC>, "assets" | "dev"> {
25
25
  /**
26
26
  * Configuration for the build command
27
27
  *
@@ -149,14 +149,15 @@ export interface WebsiteProps<B extends Bindings> extends Omit<
149
149
  memoize?: boolean | { patterns: string[] };
150
150
  }
151
151
 
152
- export type Website<B extends Bindings> = B extends { ASSETS: any }
153
- ? never
154
- : Worker<B & { ASSETS: Assets }>;
152
+ export type Website<
153
+ B extends Bindings,
154
+ RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
155
+ > = B extends { ASSETS: any } ? never : Worker<B & { ASSETS: Assets }, RPC>;
155
156
 
156
- export async function Website<B extends Bindings>(
157
- id: string,
158
- props: WebsiteProps<B>,
159
- ) {
157
+ export async function Website<
158
+ B extends Bindings,
159
+ RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
160
+ >(id: string, props: WebsiteProps<B, RPC>) {
160
161
  const {
161
162
  name = Scope.current.createPhysicalName(id).toLowerCase(),
162
163
  build: buildProps,
@@ -377,7 +378,7 @@ export async function Website<B extends Bindings>(
377
378
  : {}),
378
379
  },
379
380
  dev: url ? { url } : undefined,
380
- })) as Website<B>;
381
+ })) as Website<B, RPC>;
381
382
  }
382
383
 
383
384
  export const spreadBuildProps = (
@@ -492,6 +492,14 @@ export async function prepareWorkerMetadata(
492
492
  jurisdiction:
493
493
  binding.jurisdiction === "default" ? undefined : binding.jurisdiction,
494
494
  });
495
+ } else if (binding.type === "send_email") {
496
+ meta.bindings.push({
497
+ type: "send_email",
498
+ name: bindingName,
499
+ destination_address: binding.destinationAddress,
500
+ allowed_destination_addresses: binding.allowedDestinationAddresses,
501
+ allowed_sender_addresses: binding.allowedSenderAddresses,
502
+ });
495
503
  } else if (binding.type === "secrets_store_secret") {
496
504
  meta.bindings.push({
497
505
  type: "secrets_store_secret",
@@ -6,7 +6,11 @@ import type { type } from "../type.ts";
6
6
  import { DeferredPromise } from "../util/deferred-promise.ts";
7
7
  import { logger } from "../util/logger.ts";
8
8
  import { withExponentialBackoff } from "../util/retry.ts";
9
- import { CloudflareApiError, handleApiError } from "./api-error.ts";
9
+ import {
10
+ CloudflareApiError,
11
+ handleApiError,
12
+ isCloudflareApiError,
13
+ } from "./api-error.ts";
10
14
  import {
11
15
  type CloudflareApi,
12
16
  type CloudflareApiOptions,
@@ -207,6 +211,14 @@ export interface BaseWorkerProps<
207
211
  */
208
212
  logpush?: boolean;
209
213
 
214
+ /**
215
+ * Whether to delete the worker when removed from Alchemy.
216
+ * If set to false, the worker will remain but the resource will be removed from state.
217
+ *
218
+ * @default true
219
+ */
220
+ delete?: boolean;
221
+
210
222
  /**
211
223
  * Whether to adopt the Worker if it already exists when creating
212
224
  */
@@ -939,6 +951,14 @@ export type Worker<
939
951
  * // The worker will have a preview URL for testing:
940
952
  * console.log(`Preview URL: ${previewWorker.url}`);
941
953
  * // Output: Preview URL: https://pr-123-my-worker.subdomain.workers.dev
954
+ *
955
+ * @example
956
+ * // Prevent deletion of the worker when removed from Alchemy:
957
+ * const worker = await Worker("critical-api", {
958
+ * name: "critical-api",
959
+ * entrypoint: "./src/api.ts",
960
+ * delete: false
961
+ * });
942
962
  */
943
963
  export function Worker<
944
964
  const B extends Bindings,
@@ -1104,7 +1124,7 @@ const _Worker = Resource(
1104
1124
  durableObjects: options.durableObjects,
1105
1125
  workflows: options.workflows,
1106
1126
  });
1107
- if (this.output?.dev?.hasRemote !== false) {
1127
+ if (props.delete !== false && this.output?.dev?.hasRemote !== false) {
1108
1128
  const api = await createCloudflareApi(props);
1109
1129
  if (props.version) {
1110
1130
  //* if the worker exists we deploy an empty version so we can destroy
@@ -1544,6 +1564,7 @@ async function provisionResources<B extends Bindings>(
1544
1564
  durableObjects: {
1545
1565
  namespaceId: await getContainerNamespaceId(container),
1546
1566
  },
1567
+ delete: props.delete,
1547
1568
  dev: options.local,
1548
1569
  ...input.api,
1549
1570
  });
@@ -1557,6 +1578,7 @@ async function provisionResources<B extends Bindings>(
1557
1578
  name: domain.name,
1558
1579
  zoneId: domain.zoneId,
1559
1580
  adopt: domain.adopt,
1581
+ delete: props.delete,
1560
1582
  workerName: options.name,
1561
1583
  dev: options.local,
1562
1584
  ...input.api,
@@ -1579,6 +1601,7 @@ async function provisionResources<B extends Bindings>(
1579
1601
  scriptName: options.name,
1580
1602
  settings: eventSource.settings,
1581
1603
  adopt: props.adopt,
1604
+ delete: props.delete,
1582
1605
  dev: options.local,
1583
1606
  ...input.api,
1584
1607
  });
@@ -1593,6 +1616,7 @@ async function provisionResources<B extends Bindings>(
1593
1616
  script: options.name,
1594
1617
  zoneId: route.zoneId,
1595
1618
  adopt: route.adopt,
1619
+ delete: props.delete,
1596
1620
  dev: options.local,
1597
1621
  ...input.api,
1598
1622
  });
@@ -1843,6 +1867,16 @@ export async function putWorker(
1843
1867
  });
1844
1868
  }
1845
1869
  }
1870
+ if (
1871
+ isCloudflareApiError(error, { code: 11001 }) &&
1872
+ !props.eventSources?.length
1873
+ ) {
1874
+ // Error code 11001 means that the worker has event sources, but no `queue` handler is defined.
1875
+ // Normally, queue consumers are removed automatically since we're using the `QueueConsumer` resource,
1876
+ // but if no `queue` handler is defined, we need to remove them for Cloudflare to let us deploy.
1877
+ await deleteQueueConsumers(api, workerName);
1878
+ return await putWorker(api, props);
1879
+ }
1846
1880
  throw error;
1847
1881
  }
1848
1882
  },
@@ -263,6 +263,7 @@ async function processBindings(
263
263
  const durableObjects: WranglerJsonConfig["durable_objects"]["bindings"] = [];
264
264
  const r2Buckets: WranglerJsonConfig["r2_buckets"] = [];
265
265
  const services: WranglerJsonConfig["services"] = [];
266
+ const sendEmailBindings: WranglerJsonConfig["send_email"] = [];
266
267
  const secrets: string[] = [];
267
268
  const workflows: WranglerJsonConfig["workflows"] = [];
268
269
  const d1Databases: WranglerJsonConfig["d1_databases"] = [];
@@ -389,6 +390,14 @@ async function processBindings(
389
390
  binding.jurisdiction === "default" ? undefined : binding.jurisdiction,
390
391
  ...(binding.dev?.remote ? { remote: true } : {}),
391
392
  });
393
+ } else if (binding.type === "send_email") {
394
+ sendEmailBindings.push({
395
+ name: bindingName,
396
+ destination_address: binding.destinationAddress,
397
+ allowed_destination_addresses: binding.allowedDestinationAddresses,
398
+ allowed_sender_addresses: binding.allowedSenderAddresses,
399
+ ...(binding.dev?.remote ? { remote: true } : {}),
400
+ });
392
401
  } else if (binding.type === "secret") {
393
402
  // Secret binding
394
403
  secrets.push(bindingName);
@@ -569,6 +578,14 @@ async function processBindings(
569
578
  spec.services = services;
570
579
  }
571
580
 
581
+ if (sendEmailBindings.length > 0) {
582
+ (
583
+ spec as WranglerJsonSpec & {
584
+ send_email?: typeof sendEmailBindings;
585
+ }
586
+ ).send_email = sendEmailBindings;
587
+ }
588
+
572
589
  if (d1Databases.length > 0) {
573
590
  spec.d1_databases = d1Databases;
574
591
  }