wrangler 0.0.0-e2f9bb2 → 0.0.0-e305903a

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 (258) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +30 -4
  3. package/bin/wrangler.js +154 -34
  4. package/kv-asset-handler.js +1 -0
  5. package/miniflare-dist/index.mjs +1437 -21
  6. package/package.json +185 -148
  7. package/src/__tests__/api-dev.test.ts +209 -0
  8. package/src/__tests__/api-devregistry.test.js +56 -0
  9. package/src/__tests__/api.test.ts +80 -0
  10. package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
  11. package/src/__tests__/config-cache.test.ts +30 -24
  12. package/src/__tests__/configuration.test.ts +4121 -3114
  13. package/src/__tests__/dev.test.tsx +1331 -738
  14. package/src/__tests__/dialogs.test.tsx +40 -0
  15. package/src/__tests__/generate.test.ts +91 -0
  16. package/src/__tests__/guess-worker-format.test.ts +68 -68
  17. package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
  18. package/src/__tests__/helpers/mock-account-id.ts +24 -24
  19. package/src/__tests__/helpers/mock-bin.ts +20 -20
  20. package/src/__tests__/helpers/mock-cfetch.ts +199 -94
  21. package/src/__tests__/helpers/mock-console.ts +58 -39
  22. package/src/__tests__/helpers/mock-dialogs.ts +115 -51
  23. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
  24. package/src/__tests__/helpers/mock-http-server.ts +30 -30
  25. package/src/__tests__/helpers/mock-istty.ts +65 -18
  26. package/src/__tests__/helpers/mock-known-routes.ts +7 -0
  27. package/src/__tests__/helpers/mock-kv.ts +26 -26
  28. package/src/__tests__/helpers/mock-oauth-flow.ts +225 -228
  29. package/src/__tests__/helpers/mock-process.ts +39 -0
  30. package/src/__tests__/helpers/mock-stdin.ts +82 -77
  31. package/src/__tests__/helpers/mock-web-socket.ts +21 -21
  32. package/src/__tests__/helpers/msw/handlers/index.ts +13 -0
  33. package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
  34. package/src/__tests__/helpers/msw/handlers/oauth.ts +36 -0
  35. package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
  36. package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
  37. package/src/__tests__/helpers/msw/index.ts +4 -0
  38. package/src/__tests__/helpers/run-in-tmp.ts +27 -28
  39. package/src/__tests__/helpers/run-wrangler.ts +8 -8
  40. package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
  41. package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
  42. package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
  43. package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
  44. package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
  45. package/src/__tests__/helpers/write-worker-source.ts +16 -16
  46. package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
  47. package/src/__tests__/https-options.test.ts +142 -109
  48. package/src/__tests__/index.test.ts +231 -231
  49. package/src/__tests__/init.test.ts +2689 -1014
  50. package/src/__tests__/jest.setup.ts +147 -30
  51. package/src/__tests__/kv.test.ts +1311 -1094
  52. package/src/__tests__/logger.test.ts +100 -74
  53. package/src/__tests__/metrics.test.ts +450 -0
  54. package/src/__tests__/middleware.scheduled.test.ts +135 -0
  55. package/src/__tests__/middleware.test.ts +726 -0
  56. package/src/__tests__/package-manager.test.ts +312 -165
  57. package/src/__tests__/pages.test.ts +1988 -322
  58. package/src/__tests__/parse.test.ts +253 -245
  59. package/src/__tests__/paths.test.ts +39 -0
  60. package/src/__tests__/publish.test.ts +6955 -4743
  61. package/src/__tests__/pubsub.test.ts +367 -0
  62. package/src/__tests__/r2.test.ts +363 -206
  63. package/src/__tests__/route.test.ts +18 -18
  64. package/src/__tests__/secret.test.ts +624 -426
  65. package/src/__tests__/tail.test.ts +650 -565
  66. package/src/__tests__/test-old-node-version.js +31 -0
  67. package/src/__tests__/user.test.ts +140 -116
  68. package/src/__tests__/validate-dev-props.test.ts +56 -0
  69. package/src/__tests__/version.test.ts +35 -0
  70. package/src/__tests__/whoami.test.tsx +259 -91
  71. package/src/__tests__/worker-namespace.test.ts +319 -0
  72. package/src/abort.d.ts +3 -0
  73. package/src/api/dev.ts +206 -0
  74. package/src/api/index.ts +2 -0
  75. package/src/bundle-reporter.tsx +29 -0
  76. package/src/bundle.ts +721 -134
  77. package/src/cfetch/index.ts +83 -66
  78. package/src/cfetch/internal.ts +267 -90
  79. package/src/cli.ts +23 -7
  80. package/src/config/config.ts +236 -195
  81. package/src/config/diagnostics.ts +61 -61
  82. package/src/config/environment.ts +450 -339
  83. package/src/config/index.ts +258 -38
  84. package/src/config/validation-helpers.ts +379 -357
  85. package/src/config/validation.ts +1769 -1263
  86. package/src/config-cache.ts +81 -41
  87. package/src/create-worker-preview.ts +232 -132
  88. package/src/create-worker-upload-form.ts +285 -224
  89. package/src/d1/backups.tsx +212 -0
  90. package/src/d1/create.tsx +54 -0
  91. package/src/d1/delete.tsx +56 -0
  92. package/src/d1/execute.tsx +294 -0
  93. package/src/d1/formatTimeAgo.ts +14 -0
  94. package/src/d1/index.ts +75 -0
  95. package/src/d1/list.tsx +48 -0
  96. package/src/d1/options.ts +12 -0
  97. package/src/d1/types.tsx +14 -0
  98. package/src/d1/utils.ts +39 -0
  99. package/src/dev/dev-vars.ts +13 -13
  100. package/src/dev/dev.tsx +500 -353
  101. package/src/dev/get-local-persistence-path.tsx +31 -0
  102. package/src/dev/local.tsx +628 -290
  103. package/src/dev/remote.tsx +397 -197
  104. package/src/dev/start-server.ts +443 -0
  105. package/src/dev/use-esbuild.ts +173 -94
  106. package/src/dev/validate-dev-props.ts +31 -0
  107. package/src/dev-registry.tsx +190 -0
  108. package/src/dev.tsx +869 -0
  109. package/src/dialogs.tsx +134 -63
  110. package/src/dispatch-namespace.ts +206 -0
  111. package/src/durable.ts +102 -0
  112. package/src/entry.ts +248 -186
  113. package/src/environment-variables.ts +38 -23
  114. package/src/errors.ts +6 -6
  115. package/src/faye-websocket.d.ts +6 -0
  116. package/src/generate.ts +131 -0
  117. package/src/git-client.ts +42 -0
  118. package/src/global-wrangler-config-path.ts +26 -0
  119. package/src/https-options.ts +84 -80
  120. package/src/index.tsx +2288 -2534
  121. package/src/init.ts +967 -0
  122. package/src/inspect.ts +686 -562
  123. package/src/intl-polyfill.d.ts +123 -123
  124. package/src/is-ci.ts +14 -0
  125. package/src/is-interactive.ts +12 -0
  126. package/src/kv.ts +353 -242
  127. package/src/logger.ts +53 -39
  128. package/src/metrics/index.ts +5 -0
  129. package/src/metrics/metrics-config.ts +239 -0
  130. package/src/metrics/metrics-dispatcher.ts +96 -0
  131. package/src/metrics/metrics-usage-headers.ts +24 -0
  132. package/src/metrics/send-event.ts +93 -0
  133. package/src/miniflare-cli/assets.ts +215 -0
  134. package/src/miniflare-cli/index.ts +200 -33
  135. package/src/miniflare-cli/request-context.ts +18 -18
  136. package/src/module-collection.ts +212 -212
  137. package/src/open-in-browser.ts +5 -14
  138. package/src/package-manager.ts +182 -90
  139. package/src/pages/build.tsx +238 -0
  140. package/src/pages/constants.ts +16 -0
  141. package/src/pages/deployments.tsx +106 -0
  142. package/src/pages/dev.tsx +684 -0
  143. package/src/pages/errors.ts +66 -0
  144. package/src/pages/functions/buildPlugin.ts +110 -0
  145. package/src/pages/functions/buildWorker.ts +156 -0
  146. package/{pages → src/pages}/functions/filepath-routing.test.ts +113 -113
  147. package/src/pages/functions/filepath-routing.ts +189 -0
  148. package/src/pages/functions/identifiers.ts +78 -0
  149. package/src/pages/functions/routes-consolidation.test.ts +250 -0
  150. package/src/pages/functions/routes-consolidation.ts +73 -0
  151. package/src/pages/functions/routes-transformation.test.ts +282 -0
  152. package/src/pages/functions/routes-transformation.ts +115 -0
  153. package/src/pages/functions/routes-validation.test.ts +403 -0
  154. package/src/pages/functions/routes-validation.ts +202 -0
  155. package/src/pages/functions/routes.ts +151 -0
  156. package/src/pages/functions.tsx +82 -0
  157. package/src/pages/hash.tsx +13 -0
  158. package/src/pages/index.tsx +94 -0
  159. package/src/pages/projects.tsx +169 -0
  160. package/src/pages/publish.tsx +419 -0
  161. package/src/pages/types.ts +49 -0
  162. package/src/pages/upload.tsx +398 -0
  163. package/src/pages/utils.ts +12 -0
  164. package/src/parse.ts +223 -120
  165. package/src/paths.ts +53 -8
  166. package/src/preview.ts +31 -0
  167. package/src/proxy.ts +435 -383
  168. package/src/publish.ts +837 -441
  169. package/src/pubsub/index.ts +286 -0
  170. package/src/pubsub/pubsub-commands.tsx +623 -0
  171. package/src/r2.ts +100 -19
  172. package/src/selfsigned.d.ts +23 -23
  173. package/src/sites.tsx +279 -200
  174. package/src/tail/filters.ts +108 -110
  175. package/src/tail/index.ts +234 -218
  176. package/src/tail/printing.ts +86 -46
  177. package/src/update-check.ts +11 -11
  178. package/src/user/choose-account.tsx +69 -0
  179. package/src/user/env-vars.ts +46 -0
  180. package/src/user/generate-auth-url.ts +33 -0
  181. package/src/user/generate-random-state.ts +16 -0
  182. package/src/user/index.ts +3 -0
  183. package/src/user/user.tsx +1192 -0
  184. package/src/whoami.tsx +141 -42
  185. package/src/worker.ts +163 -101
  186. package/src/zones.ts +167 -0
  187. package/templates/checked-fetch.js +17 -0
  188. package/templates/d1-beta-facade.js +174 -0
  189. package/templates/experimental-local-cache-stubs.js +27 -0
  190. package/templates/first-party-worker-module-facade.ts +18 -0
  191. package/templates/format-dev-errors.ts +32 -0
  192. package/templates/init-tests/test-jest-new-worker.js +25 -0
  193. package/templates/init-tests/test-vitest-new-worker.js +26 -0
  194. package/templates/middleware/common.ts +62 -0
  195. package/templates/middleware/loader-modules.ts +84 -0
  196. package/templates/middleware/loader-sw.ts +213 -0
  197. package/templates/middleware/middleware-pretty-error.ts +40 -0
  198. package/templates/middleware/middleware-scheduled.ts +15 -0
  199. package/templates/new-worker-scheduled.js +17 -0
  200. package/templates/new-worker-scheduled.ts +32 -0
  201. package/templates/new-worker.js +3 -3
  202. package/templates/new-worker.ts +18 -3
  203. package/templates/no-op-worker.js +10 -0
  204. package/templates/pages-dev-pipeline.ts +35 -0
  205. package/templates/pages-shim.ts +9 -0
  206. package/templates/pages-template-plugin.ts +167 -0
  207. package/templates/pages-template-worker.ts +172 -0
  208. package/templates/serve-static-assets.ts +63 -0
  209. package/templates/service-bindings-module-facade.js +54 -0
  210. package/templates/service-bindings-sw-facade.js +42 -0
  211. package/templates/tsconfig.json +95 -95
  212. package/wrangler-dist/cli.d.ts +841 -0
  213. package/wrangler-dist/cli.js +120834 -70331
  214. package/pages/functions/buildPlugin.ts +0 -92
  215. package/pages/functions/buildWorker.ts +0 -138
  216. package/pages/functions/filepath-routing.ts +0 -189
  217. package/pages/functions/identifiers.ts +0 -78
  218. package/pages/functions/routes.ts +0 -156
  219. package/pages/functions/template-plugin.ts +0 -146
  220. package/pages/functions/template-worker.ts +0 -143
  221. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  222. package/src/miniflare-cli/enum-keys.ts +0 -17
  223. package/src/pages.tsx +0 -1866
  224. package/src/user.tsx +0 -1193
  225. package/templates/static-asset-facade.js +0 -47
  226. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  227. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  228. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  229. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  230. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  231. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  232. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  233. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  234. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  235. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  236. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  237. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  238. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  239. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  240. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  241. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  242. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  243. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  244. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  245. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  246. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  247. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  248. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  249. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  250. package/vendor/wrangler-mime/LICENSE +0 -21
  251. package/vendor/wrangler-mime/Mime.js +0 -97
  252. package/vendor/wrangler-mime/README.md +0 -187
  253. package/vendor/wrangler-mime/cli.js +0 -46
  254. package/vendor/wrangler-mime/index.js +0 -4
  255. package/vendor/wrangler-mime/lite.js +0 -4
  256. package/vendor/wrangler-mime/package.json +0 -52
  257. package/vendor/wrangler-mime/types/other.js +0 -1
  258. package/vendor/wrangler-mime/types/standard.js +0 -1
package/src/dev/local.tsx CHANGED
@@ -1,312 +1,650 @@
1
- import { spawn } from "node:child_process";
1
+ import { fork } from "node:child_process";
2
2
  import { realpathSync } from "node:fs";
3
3
  import { writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
+ import { npxImport } from "npx-import";
5
6
  import { useState, useEffect, useRef } from "react";
6
7
  import onExit from "signal-exit";
8
+ import { registerWorker } from "../dev-registry";
7
9
  import useInspector from "../inspect";
8
10
  import { logger } from "../logger";
9
11
  import { DEFAULT_MODULE_RULES } from "../module-collection";
12
+ import { getBasePath } from "../paths";
10
13
  import { waitForPortToBeAvailable } from "../proxy";
11
14
  import type { Config } from "../config";
15
+ import type { WorkerRegistry } from "../dev-registry";
16
+ import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
12
17
  import type { AssetPaths } from "../sites";
13
- import type { CfWorkerInit, CfScriptFormat } from "../worker";
18
+ import type {
19
+ CfWorkerInit,
20
+ CfScriptFormat,
21
+ CfWasmModuleBindings,
22
+ CfTextBlobBindings,
23
+ CfDataBlobBindings,
24
+ CfDurableObject,
25
+ CfKvNamespace,
26
+ CfR2Bucket,
27
+ CfVars,
28
+ CfD1Database,
29
+ } from "../worker";
14
30
  import type { EsbuildBundle } from "./use-esbuild";
31
+ import type {
32
+ Miniflare as Miniflare3Type,
33
+ MiniflareOptions as Miniflare3Options,
34
+ } from "@miniflare/tre";
15
35
  import type { MiniflareOptions } from "miniflare";
36
+ import type { ChildProcess } from "node:child_process";
16
37
 
17
- interface LocalProps {
18
- name: string | undefined;
19
- bundle: EsbuildBundle | undefined;
20
- format: CfScriptFormat | undefined;
21
- compatibilityDate: string;
22
- compatibilityFlags: string[] | undefined;
23
- bindings: CfWorkerInit["bindings"];
24
- assetPaths: AssetPaths | undefined;
25
- public: string | undefined;
26
- port: number;
27
- ip: string;
28
- rules: Config["rules"];
29
- inspectorPort: number;
30
- enableLocalPersistence: boolean;
31
- crons: Config["triggers"]["crons"];
38
+ // caching of the miniflare package
39
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
40
+ let Miniflare: typeof import("@miniflare/tre")["Miniflare"];
41
+
42
+ export interface LocalProps {
43
+ name: string | undefined;
44
+ bundle: EsbuildBundle | undefined;
45
+ format: CfScriptFormat | undefined;
46
+ compatibilityDate: string;
47
+ compatibilityFlags: string[] | undefined;
48
+ usageModel: "bundled" | "unbound" | undefined;
49
+ bindings: CfWorkerInit["bindings"];
50
+ workerDefinitions: WorkerRegistry | undefined;
51
+ assetPaths: AssetPaths | undefined;
52
+ port: number;
53
+ ip: string;
54
+ rules: Config["rules"];
55
+ inspectorPort: number;
56
+ localPersistencePath: string | null;
57
+ liveReload: boolean;
58
+ crons: Config["triggers"]["crons"];
59
+ localProtocol: "http" | "https";
60
+ localUpstream: string | undefined;
61
+ inspect: boolean;
62
+ onReady: ((ip: string, port: number) => void) | undefined;
63
+ logPrefix?: string;
64
+ enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
65
+ testScheduled?: boolean;
66
+ experimentalLocal?: boolean;
32
67
  }
33
68
 
34
69
  export function Local(props: LocalProps) {
35
- const { inspectorUrl } = useLocalWorker(props);
36
- useInspector({
37
- inspectorUrl,
38
- port: props.inspectorPort,
39
- logToTerminal: false,
40
- });
41
- return null;
70
+ const { inspectorUrl } = useLocalWorker(props);
71
+ useInspector({
72
+ inspectorUrl,
73
+ port: props.inspectorPort,
74
+ logToTerminal: false,
75
+ });
76
+ return null;
77
+ }
78
+
79
+ function arrayToObject(values: string[] = []): Record<string, string> {
80
+ return Object.fromEntries(values.map((value) => [value, value]));
42
81
  }
43
82
 
44
83
  function useLocalWorker({
45
- name: workerName,
46
- bundle,
47
- format,
48
- compatibilityDate,
49
- compatibilityFlags,
50
- bindings,
51
- assetPaths,
52
- public: publicDirectory,
53
- port,
54
- rules,
55
- enableLocalPersistence,
56
- ip,
57
- crons,
84
+ name: workerName,
85
+ bundle,
86
+ format,
87
+ compatibilityDate,
88
+ compatibilityFlags,
89
+ usageModel,
90
+ bindings,
91
+ workerDefinitions,
92
+ assetPaths,
93
+ port,
94
+ inspectorPort,
95
+ rules,
96
+ localPersistencePath,
97
+ liveReload,
98
+ ip,
99
+ crons,
100
+ localProtocol,
101
+ localUpstream,
102
+ inspect,
103
+ onReady,
104
+ logPrefix,
105
+ enablePagesAssetsServiceBinding,
106
+ experimentalLocal,
58
107
  }: LocalProps) {
59
- // TODO: pass vars via command line
60
- const local = useRef<ReturnType<typeof spawn>>();
61
- const removeSignalExitListener = useRef<() => void>();
62
- const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
63
- // if we're using local persistence for data, we should use the cwd
64
- // as an explicit path, or else it'll use the temp dir
65
- // which disappears when dev ends
66
- const localPersistencePath = enableLocalPersistence
67
- ? // Maybe we could make the path configurable as well?
68
- path.join(process.cwd(), "wrangler-local-state")
69
- : // We otherwise choose null, but choose true later
70
- // so that it's persisted in the temp dir across a dev session
71
- // even when we change source and reload
72
- null;
73
- useEffect(() => {
74
- const abortController = new AbortController();
75
- async function startLocalWorker() {
76
- if (!bundle || !format) return;
77
-
78
- // port for the worker
79
- await waitForPortToBeAvailable(port, {
80
- retryPeriod: 200,
81
- timeout: 2000,
82
- abortSignal: abortController.signal,
83
- });
84
-
85
- if (publicDirectory) {
86
- throw new Error(
87
- '⎔ A "public" folder is not yet supported in local mode.'
88
- );
89
- }
90
-
91
- // In local mode, we want to copy all referenced modules into
92
- // the output bundle directory before starting up
93
- for (const module of bundle.modules) {
94
- await writeFile(
95
- path.join(path.dirname(bundle.path), module.name),
96
- module.content
97
- );
98
- }
99
-
100
- const scriptPath = realpathSync(bundle.path);
101
-
102
- // the wasm_modules/text_blobs/data_blobs bindings are
103
- // relative to process.cwd(), but the actual worker bundle
104
- // is in the temp output directory; so we rewrite the paths to be absolute,
105
- // letting miniflare resolve them correctly
106
-
107
- // wasm
108
- const wasmBindings: Record<string, string> = {};
109
- for (const [name, filePath] of Object.entries(
110
- bindings.wasm_modules || {}
111
- )) {
112
- wasmBindings[name] = path.join(process.cwd(), filePath);
113
- }
114
-
115
- // text
116
- const textBlobBindings: Record<string, string> = {};
117
- for (const [name, filePath] of Object.entries(
118
- bindings.text_blobs || {}
119
- )) {
120
- textBlobBindings[name] = path.join(process.cwd(), filePath);
121
- }
122
-
123
- // data
124
- const dataBlobBindings: Record<string, string> = {};
125
- for (const [name, filePath] of Object.entries(
126
- bindings.data_blobs || {}
127
- )) {
128
- dataBlobBindings[name] = path.join(process.cwd(), filePath);
129
- }
130
-
131
- if (format === "service-worker") {
132
- for (const { type, name } of bundle.modules) {
133
- if (type === "compiled-wasm") {
134
- // In service-worker format, .wasm modules are referenced by global identifiers,
135
- // so we convert it here.
136
- // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
137
- // characters with an underscore.
138
- const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
139
- wasmBindings[identifier] = name;
140
- } else if (type === "text") {
141
- // In service-worker format, text modules are referenced by global identifiers,
142
- // so we convert it here.
143
- // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
144
- // characters with an underscore.
145
- const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
146
- textBlobBindings[identifier] = name;
147
- } else if (type === "buffer") {
148
- // In service-worker format, data blobs are referenced by global identifiers,
149
- // so we convert it here.
150
- // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
151
- // characters with an underscore.
152
- const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
153
- dataBlobBindings[identifier] = name;
154
- }
155
- }
156
- }
157
-
158
- const options: MiniflareOptions = {
159
- name: workerName,
160
- port,
161
- scriptPath,
162
- host: ip,
163
- modules: format === "modules",
164
- modulesRules: (rules || [])
165
- .concat(DEFAULT_MODULE_RULES)
166
- .map(({ type, globs: include, fallthrough }) => ({
167
- type,
168
- include,
169
- fallthrough,
170
- })),
171
- compatibilityDate,
172
- compatibilityFlags,
173
- kvNamespaces: bindings.kv_namespaces?.map((kv) => kv.binding),
174
- durableObjects: Object.fromEntries(
175
- (bindings.durable_objects?.bindings ?? []).map<[string, string]>(
176
- (value) => [value.name, value.class_name]
177
- )
178
- ),
179
- ...(localPersistencePath
180
- ? {
181
- kvPersist: path.join(localPersistencePath, "kv"),
182
- durableObjectsPersist: path.join(localPersistencePath, "do"),
183
- cachePersist: path.join(localPersistencePath, "cache"),
184
- }
185
- : {
186
- // We mark these as true, so that they'll
187
- // persist in the temp directory.
188
- // This means they'll persist across a dev session,
189
- // even if we change source and reload,
190
- // and be deleted when the dev session ends
191
- durableObjectsPersist: true,
192
- cachePersist: true,
193
- kvPersist: true,
194
- }),
195
-
196
- sitePath: assetPaths?.assetDirectory
197
- ? path.join(assetPaths.baseDirectory, assetPaths.assetDirectory)
198
- : undefined,
199
- siteInclude: assetPaths?.includePatterns.length
200
- ? assetPaths?.includePatterns
201
- : undefined,
202
- siteExclude: assetPaths?.excludePatterns.length
203
- ? assetPaths.excludePatterns
204
- : undefined,
205
- bindings: bindings.vars,
206
- wasmBindings,
207
- textBlobBindings,
208
- dataBlobBindings,
209
- sourceMap: true,
210
- logUnhandledRejections: true,
211
- crons,
212
- };
213
-
214
- // The path to the Miniflare CLI assumes that this file is being run from
215
- // `wrangler-dist` and that the CLI is found in `miniflare-dist`.
216
- // If either of those paths change this line needs updating.
217
- const miniflareCLIPath = path.resolve(
218
- __dirname,
219
- "../miniflare-dist/index.mjs"
220
- );
221
- const optionsArg = JSON.stringify(options, null);
222
-
223
- logger.log("⎔ Starting a local server...");
224
- local.current = spawn(
225
- "node",
226
- [
227
- "--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
228
- "--no-warnings", // hide annoying Node warnings
229
- "--inspect", // start Miniflare listening for a debugger to attach
230
- miniflareCLIPath,
231
- optionsArg,
232
- // "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
233
- ],
234
- {
235
- cwd: path.dirname(scriptPath),
236
- }
237
- );
238
-
239
- local.current.on("close", (code) => {
240
- if (code) {
241
- logger.log(`Miniflare process exited with code ${code}`);
242
- }
243
- });
244
-
245
- local.current.stdout?.on("data", (data: Buffer) => {
246
- process.stdout.write(data);
247
- });
248
-
249
- local.current.stderr?.on("data", (data: Buffer) => {
250
- const matches =
251
- /Debugger listening on (ws:\/\/127\.0\.0\.1:\d+\/[A-Za-z0-9-]+)/.exec(
252
- data.toString()
253
- );
254
- if (matches) {
255
- setInspectorUrl(matches[1]);
256
- }
257
- });
258
-
259
- local.current.on("exit", (code) => {
260
- if (code) {
261
- logger.error(`Miniflare process exited with code ${code}`);
262
- }
263
- });
264
-
265
- local.current.on("error", (error: Error) => {
266
- logger.error(`Miniflare process failed to spawn`);
267
- logger.error(error);
268
- });
269
-
270
- removeSignalExitListener.current = onExit((_code, _signal) => {
271
- logger.log("⎔ Shutting down local server.");
272
- local.current?.kill();
273
- local.current = undefined;
274
- });
275
- }
276
-
277
- startLocalWorker().catch((err) => {
278
- logger.error("local worker:", err);
279
- });
280
-
281
- return () => {
282
- abortController.abort();
283
- if (local.current) {
284
- logger.log("⎔ Shutting down local server.");
285
- local.current?.kill();
286
- local.current = undefined;
287
- removeSignalExitListener.current && removeSignalExitListener.current();
288
- removeSignalExitListener.current = undefined;
289
- }
290
- };
291
- }, [
292
- bundle,
293
- workerName,
294
- format,
295
- port,
296
- ip,
297
- bindings.durable_objects?.bindings,
298
- bindings.kv_namespaces,
299
- bindings.vars,
300
- compatibilityDate,
301
- compatibilityFlags,
302
- localPersistencePath,
303
- assetPaths,
304
- publicDirectory,
305
- rules,
306
- bindings.wasm_modules,
307
- bindings.text_blobs,
308
- bindings.data_blobs,
309
- crons,
310
- ]);
311
- return { inspectorUrl };
108
+ // TODO: pass vars via command line
109
+ const local = useRef<ChildProcess>();
110
+ const experimentalLocalRef = useRef<Miniflare3Type>();
111
+ const removeSignalExitListener = useRef<() => void>();
112
+ const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
113
+
114
+ useEffect(() => {
115
+ if (bindings.services && bindings.services.length > 0) {
116
+ logger.warn(
117
+ "⎔ Support for service bindings in local mode is experimental and may change."
118
+ );
119
+ }
120
+ }, [bindings.services]);
121
+
122
+ useEffect(() => {
123
+ const externalDurableObjects = (
124
+ bindings.durable_objects?.bindings || []
125
+ ).filter((binding) => binding.script_name);
126
+
127
+ if (externalDurableObjects.length > 0) {
128
+ logger.warn(
129
+ "⎔ Support for external Durable Objects in local mode is experimental and may change."
130
+ );
131
+ }
132
+ }, [bindings.durable_objects?.bindings]);
133
+
134
+ useEffect(() => {
135
+ const abortController = new AbortController();
136
+ async function startLocalWorker() {
137
+ if (!bundle || !format) return;
138
+
139
+ // port for the worker
140
+ await waitForPortToBeAvailable(port, {
141
+ retryPeriod: 200,
142
+ timeout: 2000,
143
+ abortSignal: abortController.signal,
144
+ });
145
+
146
+ // In local mode, we want to copy all referenced modules into
147
+ // the output bundle directory before starting up
148
+ for (const module of bundle.modules) {
149
+ await writeFile(
150
+ path.join(path.dirname(bundle.path), module.name),
151
+ module.content
152
+ );
153
+ }
154
+
155
+ const scriptPath = realpathSync(bundle.path);
156
+
157
+ const upstream =
158
+ typeof localUpstream === "string"
159
+ ? `${localProtocol}://${localUpstream}`
160
+ : undefined;
161
+
162
+ const {
163
+ externalDurableObjects,
164
+ internalDurableObjects,
165
+ wasmBindings,
166
+ textBlobBindings,
167
+ dataBlobBindings,
168
+ } = setupBindings({
169
+ wasm_modules: bindings.wasm_modules,
170
+ text_blobs: bindings.text_blobs,
171
+ data_blobs: bindings.data_blobs,
172
+ durable_objects: bindings.durable_objects,
173
+ format,
174
+ bundle,
175
+ });
176
+
177
+ const { forkOptions, miniflareCLIPath } = setupMiniflareOptions({
178
+ workerName,
179
+ port,
180
+ scriptPath,
181
+ localProtocol,
182
+ ip,
183
+ format,
184
+ rules,
185
+ compatibilityDate,
186
+ compatibilityFlags,
187
+ usageModel,
188
+ kv_namespaces: bindings?.kv_namespaces,
189
+ r2_buckets: bindings?.r2_buckets,
190
+ d1_databases: bindings?.d1_databases,
191
+ internalDurableObjects,
192
+ externalDurableObjects,
193
+ localPersistencePath,
194
+ liveReload,
195
+ assetPaths,
196
+ vars: bindings?.vars,
197
+ wasmBindings,
198
+ textBlobBindings,
199
+ dataBlobBindings,
200
+ crons,
201
+ upstream,
202
+ logPrefix,
203
+ workerDefinitions,
204
+ enablePagesAssetsServiceBinding,
205
+ });
206
+
207
+ if (experimentalLocal) {
208
+ // TODO: refactor setupMiniflareOptions so we don't need to parse here
209
+ const miniflare2Options: MiniflareOptions = JSON.parse(forkOptions[0]);
210
+ const options: Miniflare3Options = {
211
+ ...miniflare2Options,
212
+ // Miniflare 3 distinguishes between binding name and namespace/bucket
213
+ // IDs. For now, just use the same value as we did in Miniflare 2.
214
+ // TODO: use defined KV preview ID if any
215
+ kvNamespaces: arrayToObject(miniflare2Options.kvNamespaces),
216
+ r2Buckets: arrayToObject(miniflare2Options.r2Buckets),
217
+ // TODO: pass-through collected modules instead of getting Miniflare
218
+ // to collect them again
219
+ };
220
+
221
+ logger.log("⎔ Starting an experimental local server...");
222
+
223
+ if (Miniflare === undefined) {
224
+ ({ Miniflare } = await npxImport<
225
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
226
+ typeof import("@miniflare/tre")
227
+ >("@miniflare/tre"));
228
+ }
229
+
230
+ const mf = new Miniflare(options);
231
+ experimentalLocalRef.current = mf;
232
+ removeSignalExitListener.current = onExit((_code, _signal) => {
233
+ logger.log("⎔ Shutting down experimental local server.");
234
+ mf.dispose();
235
+ experimentalLocalRef.current = undefined;
236
+ });
237
+ await mf.ready;
238
+ return;
239
+ }
240
+
241
+ const nodeOptions = setupNodeOptions({ inspect, ip, inspectorPort });
242
+ logger.log("⎔ Starting a local server...");
243
+
244
+ const child = (local.current = fork(miniflareCLIPath, forkOptions, {
245
+ cwd: path.dirname(scriptPath),
246
+ execArgv: nodeOptions,
247
+ stdio: "pipe",
248
+ }));
249
+
250
+ child.on("message", async (messageString) => {
251
+ const message = JSON.parse(messageString as string);
252
+ if (message.ready) {
253
+ // Let's register our presence in the dev registry
254
+ if (workerName) {
255
+ await registerWorker(workerName, {
256
+ protocol: localProtocol,
257
+ mode: "local",
258
+ port,
259
+ host: ip,
260
+ durableObjects: internalDurableObjects.map((binding) => ({
261
+ name: binding.name,
262
+ className: binding.class_name,
263
+ })),
264
+ ...(message.durableObjectsPort
265
+ ? {
266
+ durableObjectsHost: ip,
267
+ durableObjectsPort: message.durableObjectsPort,
268
+ }
269
+ : {}),
270
+ });
271
+ }
272
+ onReady?.(ip, message.mfPort);
273
+ }
274
+ });
275
+
276
+ child.on("close", (code) => {
277
+ if (code) {
278
+ logger.log(`Miniflare process exited with code ${code}`);
279
+ }
280
+ });
281
+
282
+ child.stdout?.on("data", (data: Buffer) => {
283
+ process.stdout.write(data);
284
+ });
285
+
286
+ // parse the node inspector url (which may be received in chunks) from stderr
287
+ let stderrData = "";
288
+ let inspectorUrlFound = false;
289
+ child.stderr?.on("data", (data: Buffer) => {
290
+ if (!inspectorUrlFound) {
291
+ stderrData += data.toString();
292
+ const matches =
293
+ /Debugger listening on (ws:\/\/127\.0\.0\.1:\d+\/[A-Za-z0-9-]+)[\r|\n]/.exec(
294
+ stderrData
295
+ );
296
+ if (matches) {
297
+ inspectorUrlFound = true;
298
+ setInspectorUrl(matches[1]);
299
+ }
300
+ }
301
+
302
+ process.stderr.write(data);
303
+ });
304
+
305
+ child.on("exit", (code) => {
306
+ if (code) {
307
+ logger.error(`Miniflare process exited with code ${code}`);
308
+ }
309
+ });
310
+
311
+ child.on("error", (error: Error) => {
312
+ logger.error(`Miniflare process failed to spawn`);
313
+ logger.error(error);
314
+ });
315
+
316
+ removeSignalExitListener.current = onExit((_code, _signal) => {
317
+ logger.log("⎔ Shutting down local server.");
318
+ child.kill();
319
+ local.current = undefined;
320
+ });
321
+ }
322
+
323
+ startLocalWorker().catch((err) => {
324
+ logger.error("local worker:", err);
325
+ });
326
+
327
+ return () => {
328
+ abortController.abort();
329
+ if (local.current) {
330
+ logger.log("⎔ Shutting down local server.");
331
+ local.current?.kill();
332
+ local.current = undefined;
333
+ }
334
+ if (experimentalLocalRef.current) {
335
+ logger.log("⎔ Shutting down experimental local server.");
336
+ // Initialisation errors are also thrown asynchronously by dispose().
337
+ // The catch() above should've caught them though.
338
+ experimentalLocalRef.current?.dispose().catch(() => {});
339
+ experimentalLocalRef.current = undefined;
340
+ }
341
+ removeSignalExitListener.current?.();
342
+ removeSignalExitListener.current = undefined;
343
+ };
344
+ }, [
345
+ bundle,
346
+ workerName,
347
+ format,
348
+ port,
349
+ inspectorPort,
350
+ ip,
351
+ bindings.durable_objects,
352
+ bindings.kv_namespaces,
353
+ bindings.r2_buckets,
354
+ bindings.d1_databases,
355
+ bindings.vars,
356
+ bindings.services,
357
+ workerDefinitions,
358
+ compatibilityDate,
359
+ compatibilityFlags,
360
+ usageModel,
361
+ localPersistencePath,
362
+ liveReload,
363
+ assetPaths,
364
+ rules,
365
+ bindings.wasm_modules,
366
+ bindings.text_blobs,
367
+ bindings.data_blobs,
368
+ crons,
369
+ localProtocol,
370
+ localUpstream,
371
+ inspect,
372
+ logPrefix,
373
+ onReady,
374
+ enablePagesAssetsServiceBinding,
375
+ experimentalLocal,
376
+ ]);
377
+ return { inspectorUrl };
378
+ }
379
+
380
+ interface SetupBindingsProps {
381
+ wasm_modules: CfWasmModuleBindings | undefined;
382
+ text_blobs: CfTextBlobBindings | undefined;
383
+ data_blobs: CfDataBlobBindings | undefined;
384
+ durable_objects: { bindings: CfDurableObject[] } | undefined;
385
+ bundle: EsbuildBundle;
386
+ format: CfScriptFormat;
387
+ }
388
+
389
+ export function setupBindings({
390
+ wasm_modules,
391
+ text_blobs,
392
+ data_blobs,
393
+ durable_objects,
394
+ format,
395
+ bundle,
396
+ }: SetupBindingsProps) {
397
+ // the wasm_modules/text_blobs/data_blobs bindings are
398
+ // relative to process.cwd(), but the actual worker bundle
399
+ // is in the temp output directory; so we rewrite the paths to be absolute,
400
+ // letting miniflare resolve them correctly
401
+
402
+ // wasm
403
+ const wasmBindings: Record<string, string> = {};
404
+ for (const [name, filePath] of Object.entries(wasm_modules || {})) {
405
+ wasmBindings[name] = path.join(process.cwd(), filePath);
406
+ }
407
+
408
+ // text
409
+ const textBlobBindings: Record<string, string> = {};
410
+ for (const [name, filePath] of Object.entries(text_blobs || {})) {
411
+ textBlobBindings[name] = path.join(process.cwd(), filePath);
412
+ }
413
+
414
+ // data
415
+ const dataBlobBindings: Record<string, string> = {};
416
+ for (const [name, filePath] of Object.entries(data_blobs || {})) {
417
+ dataBlobBindings[name] = path.join(process.cwd(), filePath);
418
+ }
419
+
420
+ if (format === "service-worker") {
421
+ for (const { type, name } of bundle.modules) {
422
+ if (type === "compiled-wasm") {
423
+ // In service-worker format, .wasm modules are referenced by global identifiers,
424
+ // so we convert it here.
425
+ // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
426
+ // characters with an underscore.
427
+ const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
428
+ wasmBindings[identifier] = name;
429
+ } else if (type === "text") {
430
+ // In service-worker format, text modules are referenced by global identifiers,
431
+ // so we convert it here.
432
+ // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
433
+ // characters with an underscore.
434
+ const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
435
+ textBlobBindings[identifier] = name;
436
+ } else if (type === "buffer") {
437
+ // In service-worker format, data blobs are referenced by global identifiers,
438
+ // so we convert it here.
439
+ // This identifier has to be a valid JS identifier, so we replace all non alphanumeric
440
+ // characters with an underscore.
441
+ const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
442
+ dataBlobBindings[identifier] = name;
443
+ }
444
+ }
445
+ }
446
+
447
+ const internalDurableObjects = (durable_objects?.bindings || []).filter(
448
+ (binding) => !binding.script_name
449
+ );
450
+ const externalDurableObjects = (durable_objects?.bindings || []).filter(
451
+ (binding) => binding.script_name
452
+ );
453
+ return {
454
+ internalDurableObjects,
455
+ externalDurableObjects,
456
+ wasmBindings,
457
+ textBlobBindings,
458
+ dataBlobBindings,
459
+ };
460
+ }
461
+
462
+ interface SetupMiniflareOptionsProps {
463
+ workerName: string | undefined;
464
+ port: number;
465
+ scriptPath: string;
466
+ localProtocol: "http" | "https";
467
+ ip: string;
468
+ format: CfScriptFormat;
469
+ rules: Config["rules"];
470
+ compatibilityDate: string;
471
+ compatibilityFlags: string[] | undefined;
472
+ usageModel: "bundled" | "unbound" | undefined;
473
+ kv_namespaces: CfKvNamespace[] | undefined;
474
+ r2_buckets: CfR2Bucket[] | undefined;
475
+ d1_databases: CfD1Database[] | undefined;
476
+ internalDurableObjects: CfDurableObject[];
477
+ externalDurableObjects: CfDurableObject[];
478
+ localPersistencePath: string | null;
479
+ liveReload: boolean;
480
+ assetPaths: AssetPaths | undefined;
481
+ vars: CfVars | undefined;
482
+ wasmBindings: Record<string, string>;
483
+ textBlobBindings: Record<string, string>;
484
+ dataBlobBindings: Record<string, string>;
485
+ crons: Config["triggers"]["crons"];
486
+ upstream: string | undefined;
487
+ logPrefix: string | undefined;
488
+ workerDefinitions: WorkerRegistry | undefined;
489
+ enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
490
+ }
491
+
492
+ export function setupMiniflareOptions({
493
+ workerName,
494
+ port,
495
+ scriptPath,
496
+ localProtocol,
497
+ ip,
498
+ format,
499
+ rules,
500
+ compatibilityDate,
501
+ compatibilityFlags,
502
+ usageModel,
503
+ kv_namespaces,
504
+ r2_buckets,
505
+ d1_databases,
506
+ internalDurableObjects,
507
+ externalDurableObjects,
508
+ localPersistencePath,
509
+ liveReload,
510
+ assetPaths,
511
+ vars,
512
+ wasmBindings,
513
+ textBlobBindings,
514
+ dataBlobBindings,
515
+ crons,
516
+ upstream,
517
+ logPrefix,
518
+ workerDefinitions,
519
+ enablePagesAssetsServiceBinding,
520
+ }: SetupMiniflareOptionsProps): {
521
+ miniflareCLIPath: string;
522
+ forkOptions: string[];
523
+ } {
524
+ // It's now getting _really_ messy now with Pages ASSETS binding outside and the external Durable Objects inside.
525
+ const options = {
526
+ name: workerName,
527
+ port,
528
+ scriptPath,
529
+ https: localProtocol === "https",
530
+ host: ip,
531
+ modules: format === "modules",
532
+ modulesRules: (rules || [])
533
+ .concat(DEFAULT_MODULE_RULES)
534
+ .map(({ type, globs: include, fallthrough }) => ({
535
+ type,
536
+ include,
537
+ fallthrough,
538
+ })),
539
+ compatibilityDate,
540
+ compatibilityFlags,
541
+ usageModel,
542
+ kvNamespaces: kv_namespaces?.map((kv) => kv.binding),
543
+ r2Buckets: r2_buckets?.map((r2) => r2.binding),
544
+ durableObjects: Object.fromEntries(
545
+ internalDurableObjects.map((binding) => [
546
+ binding.name,
547
+ binding.class_name,
548
+ ])
549
+ ),
550
+ externalDurableObjects: Object.fromEntries(
551
+ externalDurableObjects
552
+ .map((binding) => {
553
+ const service =
554
+ workerDefinitions &&
555
+ workerDefinitions[binding.script_name as string];
556
+ if (!service) return [binding.name, undefined];
557
+
558
+ const name = service.durableObjects.find(
559
+ (durableObject) => durableObject.className === binding.class_name
560
+ )?.name;
561
+ if (!name) return [binding.name, undefined];
562
+
563
+ return [
564
+ binding.name,
565
+ {
566
+ name,
567
+ host: service.durableObjectsHost,
568
+ port: service.durableObjectsPort,
569
+ },
570
+ ];
571
+ })
572
+ .filter(([_, details]) => !!details)
573
+ ),
574
+ d1Databases: d1_databases?.map((db) => db.binding),
575
+ ...(localPersistencePath
576
+ ? {
577
+ cachePersist: path.join(localPersistencePath, "cache"),
578
+ durableObjectsPersist: path.join(localPersistencePath, "do"),
579
+ kvPersist: path.join(localPersistencePath, "kv"),
580
+ r2Persist: path.join(localPersistencePath, "r2"),
581
+ d1Persist: path.join(localPersistencePath, "d1"),
582
+ }
583
+ : {
584
+ // We mark these as true, so that they'll
585
+ // persist in the temp directory.
586
+ // This means they'll persist across a dev session,
587
+ // even if we change source and reload,
588
+ // and be deleted when the dev session ends
589
+ cachePersist: true,
590
+ durableObjectsPersist: true,
591
+ kvPersist: true,
592
+ r2Persist: true,
593
+ }),
594
+
595
+ liveReload,
596
+ sitePath: assetPaths?.assetDirectory
597
+ ? path.join(assetPaths.baseDirectory, assetPaths.assetDirectory)
598
+ : undefined,
599
+ siteInclude: assetPaths?.includePatterns.length
600
+ ? assetPaths?.includePatterns
601
+ : undefined,
602
+ siteExclude: assetPaths?.excludePatterns.length
603
+ ? assetPaths.excludePatterns
604
+ : undefined,
605
+ bindings: vars,
606
+ wasmBindings,
607
+ textBlobBindings,
608
+ dataBlobBindings,
609
+ sourceMap: true,
610
+ logUnhandledRejections: true,
611
+ crons,
612
+ upstream,
613
+ logLevel: logger.loggerLevel,
614
+ logOptions: logPrefix ? { prefix: logPrefix } : undefined,
615
+ enablePagesAssetsServiceBinding,
616
+ };
617
+ // The path to the Miniflare CLI assumes that this file is being run from
618
+ // `wrangler-dist` and that the CLI is found in `miniflare-dist`.
619
+ // If either of those paths change this line needs updating.
620
+ const miniflareCLIPath = path.resolve(
621
+ getBasePath(),
622
+ "miniflare-dist/index.mjs"
623
+ );
624
+ const miniflareOptions = JSON.stringify(options, null);
625
+ const forkOptions = [miniflareOptions];
626
+ if (enablePagesAssetsServiceBinding) {
627
+ forkOptions.push(JSON.stringify(enablePagesAssetsServiceBinding));
628
+ }
629
+ return { miniflareCLIPath, forkOptions };
630
+ }
631
+
632
+ export function setupNodeOptions({
633
+ inspect,
634
+ ip,
635
+ inspectorPort,
636
+ }: {
637
+ inspect: boolean;
638
+ ip: string;
639
+ inspectorPort: number;
640
+ }) {
641
+ const nodeOptions = [
642
+ "--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
643
+ "--no-warnings", // hide annoying Node warnings
644
+ // "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
645
+ ];
646
+ if (inspect) {
647
+ nodeOptions.push("--inspect=" + `${ip}:${inspectorPort}`); // start Miniflare listening for a debugger to attach
648
+ }
649
+ return nodeOptions;
312
650
  }