wrangler 0.0.0-e178d6fb → 0.0.0-e1c2f5b9

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 (239) hide show
  1. package/README.md +16 -2
  2. package/bin/wrangler.js +31 -11
  3. package/miniflare-dist/index.mjs +1340 -330
  4. package/package.json +40 -13
  5. package/src/__tests__/access.test.ts +25 -0
  6. package/src/__tests__/api-dev.test.ts +238 -0
  7. package/src/__tests__/api-devregistry.test.js +64 -0
  8. package/src/__tests__/api.test.ts +80 -0
  9. package/src/__tests__/configuration.test.ts +683 -470
  10. package/src/__tests__/d1.test.ts +123 -0
  11. package/src/__tests__/delete.test.ts +263 -0
  12. package/src/__tests__/deployments.test.ts +105 -0
  13. package/src/__tests__/dev.test.tsx +453 -70
  14. package/src/__tests__/dialogs.test.tsx +40 -0
  15. package/src/__tests__/generate.test.ts +235 -0
  16. package/src/__tests__/get-host-from-url.test.ts +16 -0
  17. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  18. package/src/__tests__/helpers/mock-cfetch.ts +92 -26
  19. package/src/__tests__/helpers/mock-console.ts +11 -2
  20. package/src/__tests__/helpers/mock-dialogs.ts +1 -1
  21. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
  22. package/src/__tests__/helpers/mock-known-routes.ts +7 -0
  23. package/src/__tests__/helpers/mock-kv.ts +1 -1
  24. package/src/__tests__/helpers/mock-oauth-flow.ts +74 -53
  25. package/src/__tests__/helpers/mock-process.ts +8 -13
  26. package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
  27. package/src/__tests__/helpers/msw/handlers/deployments.ts +59 -0
  28. package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
  29. package/src/__tests__/helpers/msw/handlers/oauth.ts +31 -0
  30. package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
  31. package/src/__tests__/helpers/msw/handlers/script.ts +75 -0
  32. package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
  33. package/src/__tests__/helpers/msw/handlers/zones.ts +22 -0
  34. package/src/__tests__/helpers/msw/index.ts +21 -0
  35. package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
  36. package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
  37. package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
  38. package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
  39. package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
  40. package/src/__tests__/index.test.ts +103 -97
  41. package/src/__tests__/init.test.ts +1484 -382
  42. package/src/__tests__/jest.setup.ts +88 -5
  43. package/src/__tests__/kv.test.ts +655 -540
  44. package/src/__tests__/logout.test.ts +47 -0
  45. package/src/__tests__/metrics.test.ts +95 -45
  46. package/src/__tests__/middleware.scheduled.test.ts +145 -0
  47. package/src/__tests__/middleware.test.ts +750 -0
  48. package/src/__tests__/pages-deployment-tail.test.ts +884 -0
  49. package/src/__tests__/pages.test.ts +1301 -119
  50. package/src/__tests__/paths.test.ts +39 -0
  51. package/src/__tests__/publish.test.ts +2266 -1180
  52. package/src/__tests__/pubsub.test.ts +211 -88
  53. package/src/__tests__/queues.test.ts +522 -0
  54. package/src/__tests__/r2.test.ts +363 -203
  55. package/src/__tests__/secret.test.ts +261 -59
  56. package/src/__tests__/tail.test.ts +352 -151
  57. package/src/__tests__/test-old-node-version.js +3 -3
  58. package/src/__tests__/tsconfig-sanity.ts +12 -0
  59. package/src/__tests__/tsconfig.json +8 -0
  60. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  61. package/src/__tests__/type-generation.test.ts +233 -0
  62. package/src/__tests__/user.test.ts +59 -73
  63. package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
  64. package/src/__tests__/validate-dev-props.test.ts +56 -0
  65. package/src/__tests__/whoami.test.tsx +114 -66
  66. package/src/__tests__/worker-namespace.test.ts +154 -155
  67. package/src/api/dev.ts +170 -38
  68. package/src/api/index.ts +1 -0
  69. package/src/bundle-reporter.tsx +41 -2
  70. package/src/bundle.ts +668 -81
  71. package/src/cfetch/index.ts +40 -3
  72. package/src/cfetch/internal.ts +144 -32
  73. package/src/cli.ts +4 -3
  74. package/src/config/config.ts +27 -3
  75. package/src/config/environment.ts +131 -7
  76. package/src/config/index.ts +128 -8
  77. package/src/config/validation-helpers.ts +19 -6
  78. package/src/config/validation.ts +411 -14
  79. package/src/config-cache.ts +3 -2
  80. package/src/create-worker-preview.ts +31 -6
  81. package/src/create-worker-upload-form.ts +84 -22
  82. package/src/d1/backups.tsx +223 -0
  83. package/src/d1/constants.ts +2 -0
  84. package/src/d1/create.tsx +63 -0
  85. package/src/d1/delete.tsx +56 -0
  86. package/src/d1/execute.tsx +352 -0
  87. package/src/d1/formatTimeAgo.ts +14 -0
  88. package/src/d1/index.ts +101 -0
  89. package/src/d1/list.tsx +48 -0
  90. package/src/d1/migrations/apply.tsx +196 -0
  91. package/src/d1/migrations/create.tsx +77 -0
  92. package/src/d1/migrations/helpers.ts +147 -0
  93. package/src/d1/migrations/index.tsx +3 -0
  94. package/src/d1/migrations/list.tsx +79 -0
  95. package/src/d1/migrations/options.ts +18 -0
  96. package/src/d1/options.ts +22 -0
  97. package/src/d1/types.tsx +24 -0
  98. package/src/d1/utils.ts +48 -0
  99. package/src/delete.ts +108 -0
  100. package/src/deployments.ts +83 -0
  101. package/src/deprecated/index.ts +145 -0
  102. package/src/dev/dev-vars.ts +11 -8
  103. package/src/dev/dev.tsx +220 -58
  104. package/src/dev/get-local-persistence-path.tsx +31 -0
  105. package/src/dev/local.tsx +740 -181
  106. package/src/dev/remote.tsx +340 -123
  107. package/src/dev/start-server.ts +543 -0
  108. package/src/dev/use-esbuild.ts +61 -7
  109. package/src/dev/validate-dev-props.ts +31 -0
  110. package/src/dev-registry.tsx +201 -0
  111. package/src/dev.tsx +614 -258
  112. package/src/dialogs.tsx +41 -8
  113. package/src/{worker-namespace.ts → dispatch-namespace.ts} +23 -22
  114. package/src/docs/index.ts +97 -0
  115. package/src/entry.ts +3 -2
  116. package/src/environment-variables/factory.ts +88 -0
  117. package/src/environment-variables/misc-variables.ts +30 -0
  118. package/src/generate/index.ts +300 -0
  119. package/src/git-client.ts +100 -7
  120. package/src/index.tsx +249 -1560
  121. package/src/init.ts +626 -150
  122. package/src/inspect.ts +137 -32
  123. package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
  124. package/src/is-interactive.ts +4 -0
  125. package/src/jest.d.ts +4 -0
  126. package/src/{kv.ts → kv/helpers.ts} +3 -3
  127. package/src/kv/index.ts +596 -0
  128. package/src/logger.ts +27 -8
  129. package/src/metrics/index.ts +1 -0
  130. package/src/metrics/metrics-config.ts +4 -4
  131. package/src/metrics/metrics-dispatcher.ts +1 -0
  132. package/src/metrics/metrics-usage-headers.ts +24 -0
  133. package/src/metrics/send-event.ts +13 -8
  134. package/src/miniflare-cli/assets.ts +172 -465
  135. package/src/miniflare-cli/index.ts +149 -24
  136. package/src/miniflare-cli/tsconfig.json +9 -0
  137. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  138. package/src/miniflare-cli/types.ts +11 -0
  139. package/src/module-collection.ts +12 -3
  140. package/src/pages/build.tsx +108 -42
  141. package/src/pages/constants.ts +11 -0
  142. package/src/pages/deployment-tails.tsx +284 -0
  143. package/src/pages/deployments.tsx +9 -31
  144. package/src/pages/dev.tsx +417 -108
  145. package/src/pages/errors.ts +66 -0
  146. package/src/pages/functions/buildPlugin.ts +86 -84
  147. package/src/pages/functions/buildWorker.ts +121 -106
  148. package/src/pages/functions/routes-consolidation.test.ts +250 -0
  149. package/src/pages/functions/routes-consolidation.ts +73 -0
  150. package/src/pages/functions/routes-transformation.test.ts +282 -0
  151. package/src/pages/functions/routes-transformation.ts +115 -0
  152. package/src/pages/functions/routes-validation.test.ts +403 -0
  153. package/src/pages/functions/routes-validation.ts +202 -0
  154. package/src/pages/functions/tsconfig.json +8 -0
  155. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  156. package/src/pages/functions.tsx +82 -0
  157. package/src/pages/hash.tsx +13 -0
  158. package/src/pages/index.tsx +73 -55
  159. package/src/pages/projects.tsx +9 -3
  160. package/src/pages/prompt-select-project.tsx +31 -0
  161. package/src/pages/publish.tsx +183 -60
  162. package/src/pages/types.ts +1 -0
  163. package/src/pages/upload.tsx +107 -56
  164. package/src/pages/utils.ts +13 -2
  165. package/src/paths.ts +49 -4
  166. package/src/proxy.ts +375 -157
  167. package/src/publish/index.ts +270 -0
  168. package/src/{publish.ts → publish/publish.ts} +431 -188
  169. package/src/pubsub/pubsub-commands.tsx +4 -3
  170. package/src/queues/cli/commands/consumer/add.ts +71 -0
  171. package/src/queues/cli/commands/consumer/index.ts +22 -0
  172. package/src/queues/cli/commands/consumer/remove.ts +38 -0
  173. package/src/queues/cli/commands/create.ts +25 -0
  174. package/src/queues/cli/commands/delete.ts +26 -0
  175. package/src/queues/cli/commands/index.ts +36 -0
  176. package/src/queues/cli/commands/list.ts +25 -0
  177. package/src/queues/client.ts +135 -0
  178. package/src/queues/utils.ts +18 -0
  179. package/src/r2/constants.ts +4 -0
  180. package/src/r2/helpers.ts +131 -0
  181. package/src/r2/index.ts +289 -0
  182. package/src/routes.ts +140 -0
  183. package/src/secret/index.ts +379 -0
  184. package/src/sites.tsx +3 -3
  185. package/src/tail/createTail.ts +379 -0
  186. package/src/tail/filters.ts +4 -6
  187. package/src/tail/index.ts +199 -284
  188. package/src/tail/printing.ts +43 -3
  189. package/src/tsconfig-sanity.ts +16 -0
  190. package/src/type-generation.ts +181 -0
  191. package/src/user/access.ts +68 -0
  192. package/src/user/auth-variables.ts +113 -0
  193. package/src/user/choose-account.tsx +1 -1
  194. package/src/user/index.ts +0 -1
  195. package/src/user/user.tsx +116 -49
  196. package/src/utils/collectKeyValues.ts +14 -0
  197. package/src/whoami.tsx +80 -2
  198. package/src/worker.ts +69 -9
  199. package/src/yargs-types.ts +24 -0
  200. package/src/zones.ts +124 -9
  201. package/templates/__tests__/pages-dev-util.test.ts +128 -0
  202. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  203. package/templates/__tests__/tsconfig.json +8 -0
  204. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  205. package/templates/d1-beta-facade.js +205 -0
  206. package/templates/facade.d.ts +14 -0
  207. package/templates/first-party-worker-module-facade.ts +19 -0
  208. package/templates/format-dev-errors.ts +33 -0
  209. package/templates/init-tests/test-jest-new-worker.js +23 -0
  210. package/templates/init-tests/test-vitest-new-worker.js +24 -0
  211. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  212. package/templates/middleware/common.ts +62 -0
  213. package/templates/middleware/loader-modules.ts +82 -0
  214. package/templates/middleware/loader-sw.ts +233 -0
  215. package/templates/middleware/middleware-miniflare3-json-error.ts +20 -0
  216. package/templates/middleware/middleware-pretty-error.ts +40 -0
  217. package/templates/middleware/middleware-scheduled.ts +15 -0
  218. package/templates/new-worker.js +1 -1
  219. package/templates/pages-dev-pipeline.ts +31 -0
  220. package/templates/pages-dev-util.ts +52 -0
  221. package/templates/pages-shim.ts +4 -1
  222. package/templates/pages-template-plugin.ts +21 -5
  223. package/templates/pages-template-worker.ts +37 -9
  224. package/templates/{static-asset-facade.js → serve-static-assets.ts} +23 -7
  225. package/templates/service-bindings-module-facade.js +54 -0
  226. package/templates/service-bindings-sw-facade.js +42 -0
  227. package/templates/tsconfig-sanity.ts +11 -0
  228. package/templates/tsconfig.init.json +106 -0
  229. package/templates/tsconfig.json +5 -102
  230. package/templates/tsconfig.tsbuildinfo +1 -0
  231. package/wrangler-dist/cli.d.ts +621 -42
  232. package/wrangler-dist/cli.js +144441 -102606
  233. package/src/environment-variables.ts +0 -35
  234. package/src/faye-websocket.d.ts +0 -6
  235. package/src/generate.ts +0 -33
  236. package/src/miniflare-cli/enum-keys.ts +0 -17
  237. package/src/preview.ts +0 -31
  238. package/src/r2.ts +0 -50
  239. package/src/user/env-vars.ts +0 -46
@@ -0,0 +1,543 @@
1
+ import { fork } from "node:child_process";
2
+ import { realpathSync } from "node:fs";
3
+ import { writeFile } from "node:fs/promises";
4
+ import * as path from "node:path";
5
+ import * as util from "node:util";
6
+ import onExit from "signal-exit";
7
+ import tmp from "tmp-promise";
8
+ import { bundleWorker } from "../bundle";
9
+ import {
10
+ getBoundRegisteredWorkers,
11
+ registerWorker,
12
+ startWorkerRegistry,
13
+ stopWorkerRegistry,
14
+ } from "../dev-registry";
15
+ import { runCustomBuild } from "../entry";
16
+ import { logger } from "../logger";
17
+ import { waitForPortToBeAvailable } from "../proxy";
18
+ import {
19
+ setupBindings,
20
+ getMiniflare3,
21
+ buildMiniflare3Logger,
22
+ setupMiniflareOptions,
23
+ setupNodeOptions,
24
+ transformMf2OptionsToMf3Options,
25
+ } from "./local";
26
+ import { startRemoteServer } from "./remote";
27
+ import { validateDevProps } from "./validate-dev-props";
28
+
29
+ import type { Config } from "../config";
30
+ import type { WorkerRegistry } from "../dev-registry";
31
+ import type { Entry } from "../entry";
32
+ import type { DevProps, DirectorySyncResult } from "./dev";
33
+ import type { LocalProps } from "./local";
34
+ import type { EsbuildBundle } from "./use-esbuild";
35
+ import type { Miniflare as Miniflare3Type } from "@miniflare/tre";
36
+
37
+ import type { ChildProcess } from "node:child_process";
38
+
39
+ export async function startDevServer(
40
+ props: DevProps & {
41
+ local: boolean;
42
+ disableDevRegistry: boolean;
43
+ }
44
+ ) {
45
+ try {
46
+ let workerDefinitions: WorkerRegistry = {};
47
+ validateDevProps(props);
48
+
49
+ if (props.build.command) {
50
+ const relativeFile =
51
+ path.relative(props.entry.directory, props.entry.file) || ".";
52
+ await runCustomBuild(props.entry.file, relativeFile, props.build).catch(
53
+ (err) => {
54
+ logger.error("Custom build failed:", err);
55
+ }
56
+ );
57
+ }
58
+
59
+ //implement a react-free version of useTmpDir
60
+ const directory = setupTempDir();
61
+ if (!directory) {
62
+ throw new Error("Failed to create temporary directory.");
63
+ }
64
+
65
+ //start the worker registry
66
+ logger.log("disableDevRegistry: ", props.disableDevRegistry);
67
+ if (!props.disableDevRegistry) {
68
+ try {
69
+ await startWorkerRegistry();
70
+ if (props.local) {
71
+ const boundRegisteredWorkers = await getBoundRegisteredWorkers({
72
+ services: props.bindings.services,
73
+ durableObjects: props.bindings.durable_objects,
74
+ });
75
+
76
+ if (
77
+ !util.isDeepStrictEqual(boundRegisteredWorkers, workerDefinitions)
78
+ ) {
79
+ workerDefinitions = boundRegisteredWorkers || {};
80
+ }
81
+ }
82
+ } catch (err) {
83
+ logger.error("failed to start worker registry", err);
84
+ }
85
+ }
86
+
87
+ const betaD1Shims = props.bindings.d1_databases?.map((db) => db.binding);
88
+
89
+ //implement a react-free version of useEsbuild
90
+ const bundle = await runEsbuild({
91
+ entry: props.entry,
92
+ destination: directory.name,
93
+ jsxFactory: props.jsxFactory,
94
+ rules: props.rules,
95
+ jsxFragment: props.jsxFragment,
96
+ serveAssetsFromWorker: Boolean(
97
+ props.assetPaths && !props.isWorkersSite && props.local
98
+ ),
99
+ tsconfig: props.tsconfig,
100
+ minify: props.minify,
101
+ nodeCompat: props.nodeCompat,
102
+ define: props.define,
103
+ noBundle: props.noBundle,
104
+ assets: props.assetsConfig,
105
+ betaD1Shims,
106
+ workerDefinitions,
107
+ services: props.bindings.services,
108
+ firstPartyWorkerDevFacade: props.firstPartyWorker,
109
+ testScheduled: props.testScheduled,
110
+ local: props.local,
111
+ experimentalLocal: props.experimentalLocal,
112
+ });
113
+
114
+ if (props.local) {
115
+ const { stop, inspectorUrl } = await startLocalServer({
116
+ name: props.name,
117
+ bundle: bundle,
118
+ format: props.entry.format,
119
+ compatibilityDate: props.compatibilityDate,
120
+ compatibilityFlags: props.compatibilityFlags,
121
+ bindings: props.bindings,
122
+ assetPaths: props.assetPaths,
123
+ initialPort: props.initialPort,
124
+ initialIp: props.initialIp,
125
+ rules: props.rules,
126
+ inspectorPort: props.inspectorPort,
127
+ localPersistencePath: props.localPersistencePath,
128
+ liveReload: props.liveReload,
129
+ crons: props.crons,
130
+ queueConsumers: props.queueConsumers,
131
+ localProtocol: props.localProtocol,
132
+ localUpstream: props.localUpstream,
133
+ logPrefix: props.logPrefix,
134
+ inspect: props.inspect,
135
+ onReady: props.onReady,
136
+ enablePagesAssetsServiceBinding: props.enablePagesAssetsServiceBinding,
137
+ usageModel: props.usageModel,
138
+ workerDefinitions,
139
+ experimentalLocal: props.experimentalLocal,
140
+ accountId: props.accountId,
141
+ experimentalLocalRemoteKv: props.experimentalLocalRemoteKv,
142
+ });
143
+
144
+ return {
145
+ stop: async () => {
146
+ stop();
147
+ await stopWorkerRegistry();
148
+ },
149
+ inspectorUrl,
150
+ };
151
+ } else {
152
+ const { stop } = await startRemoteServer({
153
+ name: props.name,
154
+ bundle: bundle,
155
+ format: props.entry.format,
156
+ accountId: props.accountId,
157
+ bindings: props.bindings,
158
+ assetPaths: props.assetPaths,
159
+ isWorkersSite: props.isWorkersSite,
160
+ port: props.initialPort,
161
+ ip: props.initialIp,
162
+ localProtocol: props.localProtocol,
163
+ inspectorPort: props.inspectorPort,
164
+ inspect: props.inspect,
165
+ compatibilityDate: props.compatibilityDate,
166
+ compatibilityFlags: props.compatibilityFlags,
167
+ usageModel: props.usageModel,
168
+ env: props.env,
169
+ legacyEnv: props.legacyEnv,
170
+ zone: props.zone,
171
+ host: props.host,
172
+ routes: props.routes,
173
+ onReady: props.onReady,
174
+ sourceMapPath: bundle?.sourceMapPath,
175
+ sendMetrics: props.sendMetrics,
176
+ });
177
+ return {
178
+ stop: async () => {
179
+ stop();
180
+ await stopWorkerRegistry();
181
+ },
182
+ // TODO: inspectorUrl,
183
+ };
184
+ }
185
+ } catch (err) {
186
+ logger.error(err);
187
+ }
188
+ }
189
+
190
+ function setupTempDir(): DirectorySyncResult | undefined {
191
+ let dir: DirectorySyncResult | undefined;
192
+ try {
193
+ dir = tmp.dirSync({ unsafeCleanup: true });
194
+
195
+ return dir;
196
+ } catch (err) {
197
+ logger.error("Failed to create temporary directory to store built files.");
198
+ }
199
+ }
200
+
201
+ async function runEsbuild({
202
+ entry,
203
+ destination,
204
+ jsxFactory,
205
+ jsxFragment,
206
+ rules,
207
+ assets,
208
+ betaD1Shims,
209
+ serveAssetsFromWorker,
210
+ tsconfig,
211
+ minify,
212
+ nodeCompat,
213
+ define,
214
+ noBundle,
215
+ workerDefinitions,
216
+ services,
217
+ firstPartyWorkerDevFacade,
218
+ testScheduled,
219
+ local,
220
+ experimentalLocal,
221
+ }: {
222
+ entry: Entry;
223
+ destination: string | undefined;
224
+ jsxFactory: string | undefined;
225
+ jsxFragment: string | undefined;
226
+ rules: Config["rules"];
227
+ assets: Config["assets"];
228
+ betaD1Shims?: string[];
229
+ define: Config["define"];
230
+ services: Config["services"];
231
+ serveAssetsFromWorker: boolean;
232
+ tsconfig: string | undefined;
233
+ minify: boolean | undefined;
234
+ nodeCompat: boolean | undefined;
235
+ noBundle: boolean;
236
+ workerDefinitions: WorkerRegistry;
237
+ firstPartyWorkerDevFacade: boolean | undefined;
238
+ testScheduled?: boolean;
239
+ local: boolean;
240
+ experimentalLocal: boolean | undefined;
241
+ }): Promise<EsbuildBundle | undefined> {
242
+ if (!destination) return;
243
+
244
+ const {
245
+ resolvedEntryPointPath,
246
+ bundleType,
247
+ modules,
248
+ dependencies,
249
+ sourceMapPath,
250
+ }: Awaited<ReturnType<typeof bundleWorker>> = noBundle
251
+ ? {
252
+ modules: [],
253
+ dependencies: {},
254
+ resolvedEntryPointPath: entry.file,
255
+ bundleType: entry.format === "modules" ? "esm" : "commonjs",
256
+ stop: undefined,
257
+ sourceMapPath: undefined,
258
+ }
259
+ : await bundleWorker(entry, destination, {
260
+ serveAssetsFromWorker,
261
+ jsxFactory,
262
+ jsxFragment,
263
+ rules,
264
+ tsconfig,
265
+ minify,
266
+ nodeCompat,
267
+ define,
268
+ checkFetch: true,
269
+ assets: assets && {
270
+ ...assets,
271
+ // disable the cache in dev
272
+ bypassCache: true,
273
+ },
274
+ betaD1Shims,
275
+ workerDefinitions,
276
+ services,
277
+ firstPartyWorkerDevFacade,
278
+ targetConsumer: "dev", // We are starting a dev server
279
+ testScheduled,
280
+ local,
281
+ experimentalLocal,
282
+ });
283
+
284
+ return {
285
+ id: 0,
286
+ entry,
287
+ path: resolvedEntryPointPath,
288
+ type: bundleType,
289
+ modules,
290
+ dependencies,
291
+ sourceMapPath,
292
+ };
293
+ }
294
+
295
+ export async function startLocalServer({
296
+ name: workerName,
297
+ bundle,
298
+ format,
299
+ compatibilityDate,
300
+ compatibilityFlags,
301
+ usageModel,
302
+ bindings,
303
+ workerDefinitions,
304
+ assetPaths,
305
+ initialPort,
306
+ inspectorPort,
307
+ rules,
308
+ localPersistencePath,
309
+ liveReload,
310
+ initialIp,
311
+ crons,
312
+ queueConsumers,
313
+ localProtocol,
314
+ localUpstream,
315
+ inspect,
316
+ onReady,
317
+ logPrefix,
318
+ enablePagesAssetsServiceBinding,
319
+ experimentalLocal,
320
+ accountId,
321
+ experimentalLocalRemoteKv,
322
+ }: LocalProps) {
323
+ let local: ChildProcess | undefined;
324
+ let experimentalLocalRef: Miniflare3Type | undefined;
325
+ let removeSignalExitListener: (() => void) | undefined;
326
+ let inspectorUrl: string | undefined;
327
+ const setInspectorUrl = (url: string) => {
328
+ inspectorUrl = url;
329
+ };
330
+
331
+ const abortController = new AbortController();
332
+ async function startLocalWorker() {
333
+ if (!bundle || !format) return;
334
+
335
+ // port for the worker
336
+ await waitForPortToBeAvailable(initialPort, {
337
+ retryPeriod: 200,
338
+ timeout: 2000,
339
+ abortSignal: abortController.signal,
340
+ });
341
+
342
+ if (bindings.services && bindings.services.length > 0) {
343
+ logger.warn(
344
+ "⎔ Support for service bindings in local mode is experimental and may change."
345
+ );
346
+ }
347
+
348
+ // In local mode, we want to copy all referenced modules into
349
+ // the output bundle directory before starting up
350
+ for (const module of bundle.modules) {
351
+ await writeFile(
352
+ path.join(path.dirname(bundle.path), module.name),
353
+ module.content
354
+ );
355
+ }
356
+
357
+ const scriptPath = realpathSync(bundle.path);
358
+
359
+ const upstream =
360
+ typeof localUpstream === "string"
361
+ ? `${localProtocol}://${localUpstream}`
362
+ : undefined;
363
+
364
+ const {
365
+ externalDurableObjects,
366
+ internalDurableObjects,
367
+ wasmBindings,
368
+ textBlobBindings,
369
+ dataBlobBindings,
370
+ } = setupBindings({
371
+ wasm_modules: bindings.wasm_modules,
372
+ text_blobs: bindings.text_blobs,
373
+ data_blobs: bindings.data_blobs,
374
+ durable_objects: bindings.durable_objects,
375
+ format,
376
+ bundle,
377
+ });
378
+
379
+ const { forkOptions, miniflareCLIPath, options } = setupMiniflareOptions({
380
+ workerName,
381
+ port: initialPort,
382
+ scriptPath,
383
+ localProtocol,
384
+ ip: initialIp,
385
+ format,
386
+ rules,
387
+ compatibilityDate,
388
+ compatibilityFlags,
389
+ usageModel,
390
+ kv_namespaces: bindings?.kv_namespaces,
391
+ queueBindings: bindings?.queues,
392
+ queueConsumers,
393
+ r2_buckets: bindings?.r2_buckets,
394
+ d1_databases: bindings?.d1_databases,
395
+ internalDurableObjects,
396
+ externalDurableObjects,
397
+ localPersistencePath,
398
+ liveReload,
399
+ assetPaths,
400
+ vars: bindings?.vars,
401
+ wasmBindings,
402
+ textBlobBindings,
403
+ dataBlobBindings,
404
+ crons,
405
+ upstream,
406
+ logPrefix,
407
+ workerDefinitions,
408
+ enablePagesAssetsServiceBinding,
409
+ });
410
+
411
+ if (experimentalLocal) {
412
+ const log = await buildMiniflare3Logger(logPrefix);
413
+ const mf3Options = await transformMf2OptionsToMf3Options({
414
+ miniflare2Options: options,
415
+ format,
416
+ bundle,
417
+ log,
418
+ kvNamespaces: bindings?.kv_namespaces,
419
+ r2Buckets: bindings?.r2_buckets,
420
+ authenticatedAccountId: accountId,
421
+ kvRemote: experimentalLocalRemoteKv,
422
+ inspectorPort,
423
+ });
424
+ const { Miniflare } = await getMiniflare3();
425
+ const mf = new Miniflare(mf3Options);
426
+ const runtimeURL = await mf.ready;
427
+ experimentalLocalRef = mf;
428
+ removeSignalExitListener = onExit((_code, _signal) => {
429
+ logger.log("⎔ Shutting down experimental local server.");
430
+ void mf.dispose();
431
+ experimentalLocalRef = undefined;
432
+ });
433
+ onReady?.(runtimeURL.hostname, parseInt(runtimeURL.port ?? 8787));
434
+ return;
435
+ }
436
+
437
+ const nodeOptions = setupNodeOptions({ inspect, inspectorPort });
438
+ logger.log("⎔ Starting a local server...");
439
+
440
+ const child = (local = fork(miniflareCLIPath, forkOptions, {
441
+ cwd: path.dirname(scriptPath),
442
+ execArgv: nodeOptions,
443
+ stdio: "pipe",
444
+ }));
445
+
446
+ child.on("message", async (messageString) => {
447
+ const message = JSON.parse(messageString as string);
448
+ if (message.ready) {
449
+ // Let's register our presence in the dev registry
450
+ if (workerName) {
451
+ await registerWorker(workerName, {
452
+ protocol: localProtocol,
453
+ mode: "local",
454
+ port: message.port,
455
+ host: initialIp,
456
+ durableObjects: internalDurableObjects.map((binding) => ({
457
+ name: binding.name,
458
+ className: binding.class_name,
459
+ })),
460
+ ...(message.durableObjectsPort
461
+ ? {
462
+ durableObjectsHost: initialIp,
463
+ durableObjectsPort: message.durableObjectsPort,
464
+ }
465
+ : {}),
466
+ });
467
+ }
468
+ onReady?.(initialIp, message.port);
469
+ }
470
+ });
471
+
472
+ child.on("close", (code) => {
473
+ if (code) {
474
+ logger.log(`Miniflare process exited with code ${code}`);
475
+ }
476
+ });
477
+
478
+ child.stdout?.on("data", (data: Buffer) => {
479
+ process.stdout.write(data);
480
+ });
481
+
482
+ // parse the node inspector url (which may be received in chunks) from stderr
483
+ let stderrData = "";
484
+ let inspectorUrlFound = false;
485
+ child.stderr?.on("data", (data: Buffer) => {
486
+ if (!inspectorUrlFound) {
487
+ stderrData += data.toString();
488
+ const matches =
489
+ /Debugger listening on (ws:\/\/127\.0\.0\.1:\d+\/[A-Za-z0-9-]+)[\r|\n]/.exec(
490
+ stderrData
491
+ );
492
+ if (matches) {
493
+ inspectorUrlFound = true;
494
+ setInspectorUrl(matches[1]);
495
+ }
496
+ }
497
+
498
+ process.stderr.write(data);
499
+ });
500
+
501
+ child.on("exit", (code) => {
502
+ if (code) {
503
+ logger.error(`Miniflare process exited with code ${code}`);
504
+ }
505
+ });
506
+
507
+ child.on("error", (error: Error) => {
508
+ logger.error(`Miniflare process failed to spawn`);
509
+ logger.error(error);
510
+ });
511
+
512
+ removeSignalExitListener = onExit((_code, _signal) => {
513
+ logger.log("⎔ Shutting down local server.");
514
+ child.kill();
515
+ local = undefined;
516
+ });
517
+ }
518
+
519
+ startLocalWorker().catch((err) => {
520
+ logger.error("local worker:", err);
521
+ });
522
+
523
+ return {
524
+ inspectorUrl,
525
+ stop: () => {
526
+ abortController.abort();
527
+ if (local) {
528
+ logger.log("⎔ Shutting down local server.");
529
+ local.kill();
530
+ local = undefined;
531
+ }
532
+ if (experimentalLocalRef) {
533
+ logger.log("⎔ Shutting down experimental local server.");
534
+ // Initialisation errors are also thrown asynchronously by dispose().
535
+ // The catch() above should've caught them though.
536
+ experimentalLocalRef?.dispose().catch(() => {});
537
+ experimentalLocalRef = undefined;
538
+ }
539
+ removeSignalExitListener?.();
540
+ removeSignalExitListener = undefined;
541
+ },
542
+ };
543
+ }
@@ -2,12 +2,13 @@ import assert from "node:assert";
2
2
  import { watch } from "chokidar";
3
3
  import { useApp } from "ink";
4
4
  import { useState, useEffect } from "react";
5
- import { bundleWorker } from "../bundle";
6
- import { logger } from "../logger";
5
+ import { bundleWorker, rewriteNodeCompatBuildFailure } from "../bundle";
6
+ import { logBuildFailure, logger } from "../logger";
7
7
  import type { Config } from "../config";
8
+ import type { WorkerRegistry } from "../dev-registry";
8
9
  import type { Entry } from "../entry";
9
10
  import type { CfModule } from "../worker";
10
- import type { WatchMode } from "esbuild";
11
+ import type { WatchMode, Metafile } from "esbuild";
11
12
 
12
13
  export type EsbuildBundle = {
13
14
  id: number;
@@ -15,6 +16,8 @@ export type EsbuildBundle = {
15
16
  entry: Entry;
16
17
  type: "esm" | "commonjs";
17
18
  modules: CfModule[];
19
+ dependencies: Metafile["outputs"][string]["inputs"];
20
+ sourceMapPath: string | undefined;
18
21
  };
19
22
 
20
23
  export function useEsbuild({
@@ -23,24 +26,44 @@ export function useEsbuild({
23
26
  jsxFactory,
24
27
  jsxFragment,
25
28
  rules,
29
+ assets,
26
30
  serveAssetsFromWorker,
27
31
  tsconfig,
28
32
  minify,
29
33
  nodeCompat,
34
+ betaD1Shims,
30
35
  define,
31
36
  noBundle,
37
+ workerDefinitions,
38
+ services,
39
+ durableObjects,
40
+ firstPartyWorkerDevFacade,
41
+ local,
42
+ targetConsumer,
43
+ testScheduled,
44
+ experimentalLocal,
32
45
  }: {
33
46
  entry: Entry;
34
47
  destination: string | undefined;
35
48
  jsxFactory: string | undefined;
36
49
  jsxFragment: string | undefined;
37
50
  rules: Config["rules"];
51
+ assets: Config["assets"];
38
52
  define: Config["define"];
53
+ services: Config["services"];
39
54
  serveAssetsFromWorker: boolean;
40
55
  tsconfig: string | undefined;
41
56
  minify: boolean | undefined;
42
57
  nodeCompat: boolean | undefined;
58
+ betaD1Shims?: string[];
43
59
  noBundle: boolean;
60
+ workerDefinitions: WorkerRegistry;
61
+ durableObjects: Config["durable_objects"];
62
+ firstPartyWorkerDevFacade: boolean | undefined;
63
+ local: boolean;
64
+ targetConsumer: "dev" | "publish";
65
+ testScheduled: boolean;
66
+ experimentalLocal: boolean | undefined;
44
67
  }): EsbuildBundle | undefined {
45
68
  const [bundle, setBundle] = useState<EsbuildBundle>();
46
69
  const { exit } = useApp();
@@ -61,8 +84,11 @@ export function useEsbuild({
61
84
 
62
85
  const watchMode: WatchMode = {
63
86
  async onRebuild(error) {
64
- if (error) logger.error("Watch build failed:", error);
65
- else {
87
+ if (error !== null) {
88
+ if (!nodeCompat) rewriteNodeCompatBuildFailure(error);
89
+ logBuildFailure(error);
90
+ logger.error("Watch build failed:", error.message);
91
+ } else {
66
92
  updateBundle();
67
93
  }
68
94
  },
@@ -75,13 +101,17 @@ export function useEsbuild({
75
101
  resolvedEntryPointPath,
76
102
  bundleType,
77
103
  modules,
104
+ dependencies,
78
105
  stop,
106
+ sourceMapPath,
79
107
  }: Awaited<ReturnType<typeof bundleWorker>> = noBundle
80
108
  ? {
81
109
  modules: [],
110
+ dependencies: {},
82
111
  resolvedEntryPointPath: entry.file,
83
112
  bundleType: entry.format === "modules" ? "esm" : "commonjs",
84
113
  stop: undefined,
114
+ sourceMapPath: undefined,
85
115
  }
86
116
  : await bundleWorker(entry, destination, {
87
117
  serveAssetsFromWorker,
@@ -92,8 +122,21 @@ export function useEsbuild({
92
122
  tsconfig,
93
123
  minify,
94
124
  nodeCompat,
125
+ betaD1Shims,
95
126
  define,
96
127
  checkFetch: true,
128
+ assets: assets && {
129
+ ...assets,
130
+ // disable the cache in dev
131
+ bypassCache: true,
132
+ },
133
+ workerDefinitions,
134
+ services,
135
+ firstPartyWorkerDevFacade,
136
+ local,
137
+ targetConsumer,
138
+ testScheduled,
139
+ experimentalLocal,
97
140
  });
98
141
 
99
142
  // Capture the `stop()` method to use as the `useEffect()` destructor.
@@ -109,16 +152,17 @@ export function useEsbuild({
109
152
  });
110
153
 
111
154
  stopWatching = () => {
112
- watcher.close();
155
+ void watcher.close();
113
156
  };
114
157
  }
115
-
116
158
  setBundle({
117
159
  id: 0,
118
160
  entry,
119
161
  path: resolvedEntryPointPath,
120
162
  type: bundleType,
121
163
  modules,
164
+ dependencies,
165
+ sourceMapPath,
122
166
  });
123
167
  }
124
168
 
@@ -145,6 +189,16 @@ export function useEsbuild({
145
189
  minify,
146
190
  nodeCompat,
147
191
  define,
192
+ assets,
193
+ services,
194
+ durableObjects,
195
+ workerDefinitions,
196
+ firstPartyWorkerDevFacade,
197
+ betaD1Shims,
198
+ local,
199
+ targetConsumer,
200
+ testScheduled,
201
+ experimentalLocal,
148
202
  ]);
149
203
  return bundle;
150
204
  }