alchemy 0.53.0 → 0.55.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 (214) hide show
  1. package/bin/alchemy.js +196353 -0
  2. package/bin/alchemy.ts +2 -2
  3. package/bin/commands/init.ts +1190 -0
  4. package/bin/constants.ts +18 -0
  5. package/bin/services/execute-alchemy.ts +7 -2
  6. package/bin/services/package-manager.ts +1 -1
  7. package/bin/types.ts +14 -5
  8. package/lib/aws/ec2/index.d.ts +10 -0
  9. package/lib/aws/ec2/index.d.ts.map +1 -0
  10. package/lib/aws/ec2/index.js +10 -0
  11. package/lib/aws/ec2/index.js.map +1 -0
  12. package/lib/aws/ec2/internet-gateway-attachment.d.ts +150 -0
  13. package/lib/aws/ec2/internet-gateway-attachment.d.ts.map +1 -0
  14. package/lib/aws/ec2/internet-gateway-attachment.js +248 -0
  15. package/lib/aws/ec2/internet-gateway-attachment.js.map +1 -0
  16. package/lib/aws/ec2/internet-gateway.d.ts +132 -0
  17. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
  18. package/lib/aws/ec2/internet-gateway.js +311 -0
  19. package/lib/aws/ec2/internet-gateway.js.map +1 -0
  20. package/lib/aws/ec2/nat-gateway.d.ts +145 -0
  21. package/lib/aws/ec2/nat-gateway.d.ts.map +1 -0
  22. package/lib/aws/ec2/nat-gateway.js +618 -0
  23. package/lib/aws/ec2/nat-gateway.js.map +1 -0
  24. package/lib/aws/ec2/route-table-association.d.ts +134 -0
  25. package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
  26. package/lib/aws/ec2/route-table-association.js +364 -0
  27. package/lib/aws/ec2/route-table-association.js.map +1 -0
  28. package/lib/aws/ec2/route-table.d.ts +94 -0
  29. package/lib/aws/ec2/route-table.d.ts.map +1 -0
  30. package/lib/aws/ec2/route-table.js +253 -0
  31. package/lib/aws/ec2/route-table.js.map +1 -0
  32. package/lib/aws/ec2/route.d.ts +130 -0
  33. package/lib/aws/ec2/route.d.ts.map +1 -0
  34. package/lib/aws/ec2/route.js +253 -0
  35. package/lib/aws/ec2/route.js.map +1 -0
  36. package/lib/aws/ec2/security-group-rule.d.ts +84 -0
  37. package/lib/aws/ec2/security-group-rule.d.ts.map +1 -0
  38. package/lib/aws/ec2/security-group-rule.js +123 -0
  39. package/lib/aws/ec2/security-group-rule.js.map +1 -0
  40. package/lib/aws/ec2/security-group.d.ts +84 -0
  41. package/lib/aws/ec2/security-group.d.ts.map +1 -0
  42. package/lib/aws/ec2/security-group.js +207 -0
  43. package/lib/aws/ec2/security-group.js.map +1 -0
  44. package/lib/aws/ec2/subnet.d.ts +110 -0
  45. package/lib/aws/ec2/subnet.d.ts.map +1 -0
  46. package/lib/aws/ec2/subnet.js +336 -0
  47. package/lib/aws/ec2/subnet.js.map +1 -0
  48. package/lib/aws/ec2/utils.d.ts +15 -0
  49. package/lib/aws/ec2/utils.d.ts.map +1 -0
  50. package/lib/aws/ec2/utils.js +79 -0
  51. package/lib/aws/ec2/utils.js.map +1 -0
  52. package/lib/aws/ec2/vpc.d.ts +160 -0
  53. package/lib/aws/ec2/vpc.d.ts.map +1 -0
  54. package/lib/aws/ec2/vpc.js +453 -0
  55. package/lib/aws/ec2/vpc.js.map +1 -0
  56. package/lib/aws/index.d.ts +7 -0
  57. package/lib/aws/index.d.ts.map +1 -1
  58. package/lib/aws/index.js +8 -0
  59. package/lib/aws/index.js.map +1 -1
  60. package/lib/aws/utils.d.ts +25 -0
  61. package/lib/aws/utils.d.ts.map +1 -0
  62. package/lib/aws/utils.js +89 -0
  63. package/lib/aws/utils.js.map +1 -0
  64. package/lib/build-date.d.ts +6 -0
  65. package/lib/build-date.d.ts.map +1 -0
  66. package/lib/build-date.js +8 -0
  67. package/lib/build-date.js.map +1 -0
  68. package/lib/cloudflare/astro.d.ts.map +1 -1
  69. package/lib/cloudflare/astro.js +4 -3
  70. package/lib/cloudflare/astro.js.map +1 -1
  71. package/lib/cloudflare/bundle/externals.d.ts +3 -0
  72. package/lib/cloudflare/bundle/externals.d.ts.map +1 -0
  73. package/lib/cloudflare/bundle/externals.js +35 -0
  74. package/lib/cloudflare/bundle/externals.js.map +1 -0
  75. package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +8 -1
  76. package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -1
  77. package/lib/cloudflare/bundle/internal-worker-bundle.js +11 -4
  78. package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -1
  79. package/lib/cloudflare/bundle/plugin-hot-reload.d.ts +4 -1
  80. package/lib/cloudflare/bundle/plugin-hot-reload.d.ts.map +1 -1
  81. package/lib/cloudflare/bundle/plugin-hot-reload.js +27 -11
  82. package/lib/cloudflare/bundle/plugin-hot-reload.js.map +1 -1
  83. package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js +5 -1
  84. package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js.map +1 -1
  85. package/lib/cloudflare/bundle/plugin-wasm.d.ts +6 -2
  86. package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
  87. package/lib/cloudflare/bundle/plugin-wasm.js +21 -47
  88. package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
  89. package/lib/cloudflare/bundle/validate-node-compat.d.ts +2 -1
  90. package/lib/cloudflare/bundle/validate-node-compat.d.ts.map +1 -1
  91. package/lib/cloudflare/bundle/validate-node-compat.js +5 -4
  92. package/lib/cloudflare/bundle/validate-node-compat.js.map +1 -1
  93. package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
  94. package/lib/cloudflare/compatibility-date.gen.js +1 -1
  95. package/lib/cloudflare/d1-database.js +1 -1
  96. package/lib/cloudflare/d1-database.js.map +1 -1
  97. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  98. package/lib/cloudflare/d1-migrations.js +8 -10
  99. package/lib/cloudflare/d1-migrations.js.map +1 -1
  100. package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts +3 -3
  101. package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts.map +1 -1
  102. package/lib/cloudflare/miniflare/miniflare-worker-options.js +23 -6
  103. package/lib/cloudflare/miniflare/miniflare-worker-options.js.map +1 -1
  104. package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
  105. package/lib/cloudflare/miniflare/miniflare.js +2 -4
  106. package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
  107. package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
  108. package/lib/cloudflare/miniflare/remote-binding-proxy.js +4 -6
  109. package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
  110. package/lib/cloudflare/react-router.d.ts +4 -0
  111. package/lib/cloudflare/react-router.d.ts.map +1 -1
  112. package/lib/cloudflare/react-router.js +8 -5
  113. package/lib/cloudflare/react-router.js.map +1 -1
  114. package/lib/cloudflare/worker-bundle.d.ts +80 -0
  115. package/lib/cloudflare/worker-bundle.d.ts.map +1 -0
  116. package/lib/cloudflare/worker-bundle.js +266 -0
  117. package/lib/cloudflare/worker-bundle.js.map +1 -0
  118. package/lib/cloudflare/worker.d.ts +1 -1
  119. package/lib/cloudflare/worker.d.ts.map +1 -1
  120. package/lib/cloudflare/worker.js +81 -195
  121. package/lib/cloudflare/worker.js.map +1 -1
  122. package/lib/esbuild/bundle.d.ts +1 -0
  123. package/lib/esbuild/bundle.d.ts.map +1 -1
  124. package/lib/state/cloudflare-state-store.js +1 -5
  125. package/lib/state/cloudflare-state-store.js.map +1 -1
  126. package/lib/state/dofs-state-store/store.d.ts.map +1 -1
  127. package/lib/state/dofs-state-store/store.js +4 -4
  128. package/lib/state/dofs-state-store/store.js.map +1 -1
  129. package/lib/util/params.d.ts +5 -0
  130. package/lib/util/params.d.ts.map +1 -0
  131. package/lib/util/params.js +30 -0
  132. package/lib/util/params.js.map +1 -0
  133. package/lib/util/timeout.d.ts +31 -0
  134. package/lib/util/timeout.d.ts.map +1 -0
  135. package/lib/util/timeout.js +109 -0
  136. package/lib/util/timeout.js.map +1 -0
  137. package/lib/util/xml.d.ts +5 -0
  138. package/lib/util/xml.d.ts.map +1 -0
  139. package/lib/util/xml.js +8 -0
  140. package/lib/util/xml.js.map +1 -0
  141. package/package.json +12 -5
  142. package/src/aws/ec2/index.ts +9 -0
  143. package/src/aws/ec2/internet-gateway-attachment.ts +468 -0
  144. package/src/aws/ec2/internet-gateway.ts +557 -0
  145. package/src/aws/ec2/nat-gateway.ts +1123 -0
  146. package/src/aws/ec2/route-table-association.ts +747 -0
  147. package/src/aws/ec2/route-table.ts +452 -0
  148. package/src/aws/ec2/route.ts +447 -0
  149. package/src/aws/ec2/security-group-rule.ts +229 -0
  150. package/src/aws/ec2/security-group.ts +418 -0
  151. package/src/aws/ec2/subnet.ts +625 -0
  152. package/src/aws/ec2/utils.ts +102 -0
  153. package/src/aws/ec2/vpc.ts +969 -0
  154. package/src/aws/index.ts +9 -0
  155. package/src/aws/utils.ts +137 -0
  156. package/src/build-date.ts +8 -0
  157. package/src/cloudflare/astro.ts +4 -3
  158. package/src/cloudflare/bundle/externals.ts +36 -0
  159. package/src/cloudflare/bundle/internal-worker-bundle.ts +12 -3
  160. package/src/cloudflare/bundle/plugin-hot-reload.ts +32 -12
  161. package/src/cloudflare/bundle/plugin-hybrid-node-compat.ts +6 -1
  162. package/src/cloudflare/bundle/plugin-wasm.ts +26 -54
  163. package/src/cloudflare/bundle/validate-node-compat.ts +6 -5
  164. package/src/cloudflare/compatibility-date.gen.ts +1 -1
  165. package/src/cloudflare/d1-database.ts +1 -1
  166. package/src/cloudflare/d1-migrations.ts +19 -18
  167. package/src/cloudflare/miniflare/miniflare-worker-options.ts +27 -13
  168. package/src/cloudflare/miniflare/miniflare.ts +2 -4
  169. package/src/cloudflare/miniflare/remote-binding-proxy.ts +5 -7
  170. package/src/cloudflare/react-router.ts +14 -6
  171. package/src/cloudflare/worker-bundle.ts +364 -0
  172. package/src/cloudflare/worker.ts +104 -241
  173. package/src/state/cloudflare-state-store.ts +1 -5
  174. package/src/state/dofs-state-store/store.ts +4 -4
  175. package/src/util/params.ts +33 -0
  176. package/src/util/timeout.ts +178 -0
  177. package/src/util/xml.ts +7 -0
  178. package/templates/nuxt/package.json +1 -1
  179. package/templates/nuxt/types/env.d.ts +11 -0
  180. package/templates/react-router/workers/app.ts +2 -2
  181. package/templates/rwsdk/.cursor/rules/alchemy_cloudflare.mdc +385 -0
  182. package/templates/rwsdk/wrangler.jsonc +10 -7
  183. package/templates/typescript/tsconfig.json +1 -2
  184. package/bin/alchemy.mjs +0 -51766
  185. package/lib/cloudflare/bundle/esbuild.d.ts +0 -16
  186. package/lib/cloudflare/bundle/esbuild.d.ts.map +0 -1
  187. package/lib/cloudflare/bundle/esbuild.js +0 -159
  188. package/lib/cloudflare/bundle/esbuild.js.map +0 -1
  189. package/lib/cloudflare/bundle/fs.d.ts +0 -18
  190. package/lib/cloudflare/bundle/fs.d.ts.map +0 -1
  191. package/lib/cloudflare/bundle/fs.js +0 -78
  192. package/lib/cloudflare/bundle/fs.js.map +0 -1
  193. package/lib/cloudflare/bundle/index.d.ts +0 -3
  194. package/lib/cloudflare/bundle/index.d.ts.map +0 -1
  195. package/lib/cloudflare/bundle/index.js +0 -2
  196. package/lib/cloudflare/bundle/index.js.map +0 -1
  197. package/lib/cloudflare/bundle/inline.d.ts +0 -12
  198. package/lib/cloudflare/bundle/inline.d.ts.map +0 -1
  199. package/lib/cloudflare/bundle/inline.js +0 -32
  200. package/lib/cloudflare/bundle/inline.js.map +0 -1
  201. package/lib/cloudflare/bundle/normalize.d.ts +0 -21
  202. package/lib/cloudflare/bundle/normalize.d.ts.map +0 -1
  203. package/lib/cloudflare/bundle/normalize.js +0 -49
  204. package/lib/cloudflare/bundle/normalize.js.map +0 -1
  205. package/lib/cloudflare/bundle/shared.d.ts +0 -30
  206. package/lib/cloudflare/bundle/shared.d.ts.map +0 -1
  207. package/lib/cloudflare/bundle/shared.js +0 -34
  208. package/lib/cloudflare/bundle/shared.js.map +0 -1
  209. package/src/cloudflare/bundle/esbuild.ts +0 -194
  210. package/src/cloudflare/bundle/fs.ts +0 -103
  211. package/src/cloudflare/bundle/index.ts +0 -6
  212. package/src/cloudflare/bundle/inline.ts +0 -42
  213. package/src/cloudflare/bundle/normalize.ts +0 -76
  214. package/src/cloudflare/bundle/shared.ts +0 -73
@@ -1,4 +1,3 @@
1
- import type esbuild from "esbuild";
2
1
  import kleur from "kleur";
3
2
  import { spawn } from "node:child_process";
4
3
  import fs from "node:fs/promises";
@@ -26,13 +25,6 @@ import type {
26
25
  WorkerBindingSpec,
27
26
  } from "./bindings.ts";
28
27
  import type { Bound } from "./bound.ts";
29
- import {
30
- type WorkerBundle,
31
- type WorkerBundleChunk,
32
- type WorkerBundleProvider,
33
- normalizeWorkerBundle,
34
- } from "./bundle/index.ts";
35
- import { wrap } from "./bundle/normalize.ts";
36
28
  import { DEFAULT_COMPATIBILITY_DATE } from "./compatibility-date.gen.ts";
37
29
  import {
38
30
  type CompatibilityPreset,
@@ -56,6 +48,11 @@ import {
56
48
  import { isQueue } from "./queue.ts";
57
49
  import { Route } from "./route.ts";
58
50
  import { uploadAssets } from "./worker-assets.ts";
51
+ import {
52
+ WorkerBundle,
53
+ type WorkerBundleSource,
54
+ normalizeWorkerBundle,
55
+ } from "./worker-bundle.ts";
59
56
  import {
60
57
  type WorkerScriptMetadata,
61
58
  bumpMigrationTagVersion,
@@ -738,23 +735,21 @@ export const _Worker = Resource(
738
735
  ? props.namespace
739
736
  : props.namespace?.namespaceName;
740
737
 
741
- const [bundle, error] = wrap(() =>
742
- normalizeWorkerBundle({
743
- entrypoint: props.entrypoint,
744
- script: props.script,
745
- format: props.format,
746
- noBundle: props.noBundle,
747
- rules: "rules" in props ? props.rules : undefined,
748
- bundle: props.bundle,
749
- cwd,
750
- compatibilityDate,
751
- compatibilityFlags,
752
- outdir:
753
- props.bundle?.outdir ??
754
- path.join(process.cwd(), ".alchemy", ...this.scope.chain, id),
755
- sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
756
- }),
757
- );
738
+ const bundleSourceResult = normalizeWorkerBundle({
739
+ entrypoint: props.entrypoint,
740
+ script: props.script,
741
+ format: props.format,
742
+ noBundle: props.noBundle,
743
+ rules: "rules" in props ? props.rules : undefined,
744
+ bundle: props.bundle,
745
+ cwd,
746
+ compatibilityDate,
747
+ compatibilityFlags,
748
+ outdir:
749
+ props.bundle?.outdir ??
750
+ path.join(cwd, ".alchemy", ...this.scope.chain, id),
751
+ sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
752
+ });
758
753
 
759
754
  // run locally if
760
755
  const local = this.scope.local && !props.dev?.remote;
@@ -762,8 +757,8 @@ export const _Worker = Resource(
762
757
 
763
758
  if (local) {
764
759
  let url: string | undefined;
765
- if (error) {
766
- throw error;
760
+ if (bundleSourceResult.isErr()) {
761
+ throw bundleSourceResult.error;
767
762
  }
768
763
 
769
764
  if (props.dev?.command) {
@@ -793,7 +788,7 @@ export const _Worker = Resource(
793
788
  compatibilityDate,
794
789
  compatibilityFlags,
795
790
  bindings: props.bindings,
796
- bundle,
791
+ bundle: bundleSourceResult.value,
797
792
  port: props.dev?.port,
798
793
  assets: props.assets,
799
794
  });
@@ -832,7 +827,9 @@ export const _Worker = Resource(
832
827
  const api = await createCloudflareApi(props);
833
828
 
834
829
  if (this.phase === "delete") {
835
- await bundle?.delete?.();
830
+ if (bundleSourceResult.isOk()) {
831
+ await bundleSourceResult.value.delete?.();
832
+ }
836
833
  if (!props.version) {
837
834
  await deleteQueueConsumers(api, workerName);
838
835
  await deleteWorker(api, {
@@ -841,10 +838,12 @@ export const _Worker = Resource(
841
838
  });
842
839
  }
843
840
  return this.destroy();
844
- } else if (error) {
845
- throw error;
841
+ } else if (bundleSourceResult.isErr()) {
842
+ throw new Error(bundleSourceResult.error);
846
843
  }
847
844
 
845
+ const bundleSource = bundleSourceResult.value;
846
+
848
847
  if (this.phase === "update") {
849
848
  const oldName = this.output.name ?? this.output.id;
850
849
  const newName = workerName;
@@ -913,7 +912,10 @@ export const _Worker = Resource(
913
912
  if (!(await workerExists(api, workerName))) {
914
913
  // Create the base worker first if it doesn't exist
915
914
  const baseWorkerProps = { ...props, version: undefined };
916
- await putWorkerWithAssets(baseWorkerProps, await bundle.create());
915
+ await putWorkerWithAssets(
916
+ baseWorkerProps,
917
+ await bundleSource.create(),
918
+ );
917
919
  }
918
920
  // We always "adopt" when publishing versions
919
921
  } else if (!props.adopt) {
@@ -923,81 +925,54 @@ export const _Worker = Resource(
923
925
 
924
926
  let putWorkerResult: PutWorkerResult;
925
927
  if (watch) {
926
- // todo(john): clean this up and add log tail
927
928
  const controller = new AbortController();
928
929
  cleanups.push(() => controller.abort());
929
- const watcher = await bundle.watch(controller.signal);
930
930
  const promise = new DeferredPromise<PutWorkerResult>();
931
- void watcher.pipeTo(
932
- new WritableStream({
933
- async write(chunk) {
934
- switch (chunk.type) {
935
- case "start":
936
- logger.task("", {
937
- message: "start",
938
- status: "pending",
939
- resource: id,
940
- prefix: "build",
941
- prefixColor: "cyanBright",
942
- });
943
- break;
944
- case "end": {
945
- if (promise.status === "pending") {
946
- await putWorkerWithAssets(props, chunk.result)
947
- .then((result) => promise.resolve(result))
948
- .catch((error) => {
949
- controller.abort();
950
- promise.reject(error);
951
- });
952
- return;
953
- }
931
+ const runWatch = async () => {
932
+ for await (const bundle of bundleSource.watch(controller.signal)) {
933
+ if (promise.status === "pending") {
934
+ await putWorkerWithAssets(props, bundle)
935
+ .then((result) => promise.resolve(result))
936
+ .catch((error) => {
937
+ controller.abort();
938
+ promise.reject(error);
939
+ });
940
+ continue;
941
+ }
954
942
 
955
- logger.task("", {
956
- message: "reload",
957
- status: "success",
958
- resource: id,
959
- prefix: "build",
960
- prefixColor: "cyanBright",
961
- });
962
- await putWorker(api, {
963
- ...props,
964
- workerName,
965
- scriptBundle: chunk.result,
966
- dispatchNamespace,
967
- version: props.version,
968
- compatibilityDate,
969
- compatibilityFlags,
970
- assetUploadResult: assetsBinding
971
- ? {
972
- keepAssets: true,
973
- assetConfig: props.assets,
974
- }
975
- : undefined,
976
- unstable_cacheWorkerSettings: true,
977
- });
978
- logger.task("", {
979
- message: "updated",
980
- status: "success",
981
- resource: id,
982
- prefix: "build",
983
- prefixColor: "greenBright",
984
- });
985
- break;
986
- }
987
- case "error":
988
- logger.task("", {
989
- message: "error",
990
- status: "failure",
991
- resource: id,
992
- prefix: "build",
993
- prefixColor: "redBright",
994
- });
995
- logger.error(chunk.errors);
996
- break;
997
- }
998
- },
999
- }),
1000
- );
943
+ logger.task("", {
944
+ message: "reload",
945
+ status: "success",
946
+ resource: id,
947
+ prefix: "build",
948
+ prefixColor: "cyanBright",
949
+ });
950
+ await putWorker(api, {
951
+ ...props,
952
+ workerName,
953
+ scriptBundle: bundle,
954
+ dispatchNamespace,
955
+ version: props.version,
956
+ compatibilityDate,
957
+ compatibilityFlags,
958
+ assetUploadResult: assetsBinding
959
+ ? {
960
+ keepAssets: true,
961
+ assetConfig: props.assets,
962
+ }
963
+ : undefined,
964
+ unstable_cacheWorkerSettings: true,
965
+ });
966
+ logger.task("", {
967
+ message: "updated",
968
+ status: "success",
969
+ resource: id,
970
+ prefix: "build",
971
+ prefixColor: "greenBright",
972
+ });
973
+ }
974
+ };
975
+ void runWatch(); // this is not awaited because it's an ongoing process
1001
976
  putWorkerResult = await promise.value;
1002
977
  await createTail(api, id, workerName)
1003
978
  .then((tail) => {
@@ -1007,7 +982,8 @@ export const _Worker = Resource(
1007
982
  logger.error(`Failed to create tail for ${workerName}`, error);
1008
983
  });
1009
984
  } else {
1010
- putWorkerResult = await putWorkerWithAssets(props, await bundle.create());
985
+ const scriptBundle = await bundleSource.create();
986
+ putWorkerResult = await putWorkerWithAssets(props, scriptBundle);
1011
987
  }
1012
988
 
1013
989
  const tasks: Promise<unknown>[] = [];
@@ -1368,7 +1344,7 @@ async function createMiniflare(props: {
1368
1344
  compatibilityFlags: string[];
1369
1345
  bindings: Bindings | undefined;
1370
1346
  port: number | undefined;
1371
- bundle: WorkerBundleProvider;
1347
+ bundle: WorkerBundleSource;
1372
1348
  assets: AssetsConfig | undefined;
1373
1349
  }) {
1374
1350
  const sharedOptions: Omit<MiniflareWorkerOptions, "bundle"> = {
@@ -1381,137 +1357,27 @@ async function createMiniflare(props: {
1381
1357
  };
1382
1358
 
1383
1359
  const startPromise = new DeferredPromise<string>();
1384
- // todo(john): streamline and share logging logic with remote dev
1385
- type Events =
1386
- | {
1387
- type: "build-start" | "build-end";
1388
- }
1389
- | {
1390
- type: "build-error";
1391
- errors: esbuild.Message[];
1392
- }
1393
- | {
1394
- type: "miniflare-ready";
1395
- url: string;
1396
- }
1397
- | {
1398
- type: "miniflare-error";
1399
- error: Error;
1400
- };
1401
1360
  const controller = new AbortController();
1402
1361
  cleanups.push(() => controller.abort());
1403
- (await props.bundle.watch(controller.signal))
1404
- .pipeThrough(
1405
- new TransformStream<WorkerBundleChunk, Events>({
1406
- async transform(chunk, controller) {
1407
- switch (chunk.type) {
1408
- case "start": {
1409
- controller.enqueue({ type: "build-start" });
1410
- break;
1411
- }
1412
- case "end": {
1413
- controller.enqueue({ type: "build-end" });
1414
- try {
1415
- const server = await miniflareServer.push({
1416
- ...sharedOptions,
1417
- bundle: chunk.result,
1418
- });
1419
- controller.enqueue({
1420
- type: "miniflare-ready",
1421
- url: server.url,
1422
- });
1423
- } catch (error) {
1424
- controller.enqueue({
1425
- type: "miniflare-error",
1426
- error: error as Error,
1427
- });
1428
- }
1429
- break;
1430
- }
1431
- case "error": {
1432
- controller.enqueue({
1433
- type: "build-error",
1434
- errors: chunk.errors,
1435
- });
1436
- break;
1437
- }
1438
- }
1439
- },
1440
- }),
1441
- )
1442
- .pipeTo(
1443
- new WritableStream({
1444
- write: async (chunk) => {
1445
- switch (chunk.type) {
1446
- case "build-start": {
1447
- logger.task("", {
1448
- message: "start",
1449
- status: "pending",
1450
- resource: props.id,
1451
- prefix: "build",
1452
- prefixColor: "cyanBright",
1453
- });
1454
- break;
1455
- }
1456
- case "build-end": {
1457
- logger.task("", {
1458
- message: startPromise.status === "pending" ? "load" : "reload",
1459
- status: "success",
1460
- resource: props.id,
1461
- prefix: "build",
1462
- prefixColor: "greenBright",
1463
- });
1464
- break;
1465
- }
1466
- case "build-error": {
1467
- logger.task("", {
1468
- message: "error",
1469
- status: "failure",
1470
- resource: props.id,
1471
- prefix: "build",
1472
- prefixColor: "redBright",
1473
- });
1474
- if (startPromise.status === "pending") {
1475
- controller.abort();
1476
- startPromise.reject(chunk.errors);
1477
- } else {
1478
- logger.error(chunk.errors);
1479
- }
1480
- break;
1481
- }
1482
- case "miniflare-ready": {
1483
- logger.task("", {
1484
- message: `ready at ${chunk.url}`,
1485
- status: "success",
1486
- resource: props.id,
1487
- prefix: "miniflare",
1488
- prefixColor: "greenBright",
1489
- });
1490
- if (startPromise.status === "pending") {
1491
- startPromise.resolve(chunk.url);
1492
- }
1493
- break;
1494
- }
1495
- case "miniflare-error": {
1496
- logger.task("", {
1497
- message: "error",
1498
- status: "failure",
1499
- resource: props.id,
1500
- prefix: "miniflare",
1501
- prefixColor: "redBright",
1502
- });
1503
- if (startPromise.status === "pending") {
1504
- startPromise.reject(chunk.error);
1505
- } else {
1506
- logger.error(chunk.error);
1507
- }
1508
- break;
1509
- }
1510
- }
1511
- },
1512
- }),
1513
- );
1514
-
1362
+ const run = async () => {
1363
+ for await (const bundle of props.bundle.watch(controller.signal)) {
1364
+ const server = await miniflareServer.push({
1365
+ ...sharedOptions,
1366
+ bundle,
1367
+ });
1368
+ if (startPromise.status === "pending") {
1369
+ startPromise.resolve(server.url);
1370
+ }
1371
+ logger.task("", {
1372
+ message: `ready at ${server.url}`,
1373
+ status: "success",
1374
+ resource: props.id,
1375
+ prefix: "miniflare",
1376
+ prefixColor: "greenBright",
1377
+ });
1378
+ }
1379
+ };
1380
+ void run();
1515
1381
  return await startPromise.value;
1516
1382
  }
1517
1383
 
@@ -1537,8 +1403,10 @@ async function createDevCommand(props: {
1537
1403
  }
1538
1404
  }
1539
1405
  const command = props.command.split(" ");
1540
- const proc = spawn(command[0], command.slice(1), {
1406
+ const [cmd, ...args] = command;
1407
+ const proc = spawn(cmd, args, {
1541
1408
  cwd: props.cwd,
1409
+ shell: true,
1542
1410
  env: {
1543
1411
  ...process.env,
1544
1412
  ...props.env,
@@ -1632,12 +1500,7 @@ async function prepareWorkerUpload(
1632
1500
  } else {
1633
1501
  scriptMetadata.main_module = props.scriptBundle.entrypoint;
1634
1502
  }
1635
- const body = new FormData();
1636
-
1637
- for await (const file of props.scriptBundle.files) {
1638
- body.append(file.name, file);
1639
- }
1640
-
1503
+ const body = await WorkerBundle.toFormData(props.scriptBundle);
1641
1504
  // Prepare metadata - add version annotations if this is a version
1642
1505
  const finalMetadata = props.version
1643
1506
  ? {
@@ -129,11 +129,7 @@ const provision = memoize(
129
129
  workerName: scriptName,
130
130
  compatibilityDate: DEFAULT_COMPATIBILITY_DATE,
131
131
  format: "esm",
132
- scriptBundle: {
133
- entrypoint: bundle.file.name,
134
- files: [bundle.file],
135
- hash: bundle.tag,
136
- },
132
+ scriptBundle: bundle.bundle,
137
133
  compatibilityFlags: [],
138
134
  bindings: {
139
135
  STORE: DurableObjectNamespace(scriptName, {
@@ -1,6 +1,7 @@
1
1
  import { handleApiError } from "../../cloudflare/api-error.ts";
2
2
  import type { CloudflareApi } from "../../cloudflare/api.ts";
3
3
  import { getInternalWorkerBundle } from "../../cloudflare/bundle/internal-worker-bundle.ts";
4
+ import { WorkerBundle } from "../../cloudflare/worker-bundle.ts";
4
5
  import type { WorkerMetadata } from "../../cloudflare/worker-metadata.ts";
5
6
  import { logger } from "../../util/logger.ts";
6
7
  import { withExponentialBackoff } from "../../util/retry.ts";
@@ -140,14 +141,13 @@ export async function upsertStateStoreWorker(
140
141
  cache.set(key, TAG);
141
142
  return;
142
143
  }
143
- const formData = new FormData();
144
- const { file } = await getInternalWorkerBundle("dofs-state-store");
145
- formData.append(file.name, file);
144
+ const { bundle } = await getInternalWorkerBundle("dofs-state-store");
145
+ const formData = await WorkerBundle.toFormData(bundle);
146
146
  formData.append(
147
147
  "metadata",
148
148
  new Blob([
149
149
  JSON.stringify({
150
- main_module: file.name,
150
+ main_module: bundle.entrypoint,
151
151
  compatibility_date: "2025-06-01",
152
152
  compatibility_flags: ["nodejs_compat"],
153
153
  bindings: [
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Flatten nested parameters for API calls
3
+ */
4
+ export function flattenParams(
5
+ params: Record<string, any>,
6
+ prefix = "",
7
+ ): Record<string, string> {
8
+ const result: Record<string, string> = {};
9
+
10
+ for (const [key, value] of Object.entries(params)) {
11
+ const fullKey = prefix ? `${prefix}.${key}` : key;
12
+
13
+ if (value === null || value === undefined) {
14
+ continue;
15
+ }
16
+
17
+ if (Array.isArray(value)) {
18
+ value.forEach((item, index) => {
19
+ if (typeof item === "object") {
20
+ Object.assign(result, flattenParams(item, `${fullKey}.${index + 1}`));
21
+ } else {
22
+ result[`${fullKey}.${index + 1}`] = String(item);
23
+ }
24
+ });
25
+ } else if (typeof value === "object") {
26
+ Object.assign(result, flattenParams(value, fullKey));
27
+ } else {
28
+ result[fullKey] = String(value);
29
+ }
30
+ }
31
+
32
+ return result;
33
+ }