wrangler 0.0.0-e30d1013 → 0.0.0-e311bbbf

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 (236) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +126 -74
  4. package/package.json +26 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +567 -39
  9. package/src/__tests__/d1/d1.test.ts +82 -0
  10. package/src/__tests__/d1/execute.test.ts +66 -0
  11. package/src/__tests__/d1/migrate.test.ts +157 -0
  12. package/src/__tests__/d1/splitter.test.ts +255 -0
  13. package/src/__tests__/delete.test.ts +91 -49
  14. package/src/__tests__/deployments.test.ts +330 -52
  15. package/src/__tests__/dev.test.tsx +198 -90
  16. package/src/__tests__/generate.test.ts +8 -5
  17. package/src/__tests__/guess-worker-format.test.ts +35 -0
  18. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  19. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  20. package/src/__tests__/helpers/mock-console.ts +6 -0
  21. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  22. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  23. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  24. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  25. package/src/__tests__/helpers/mock-kv.ts +29 -16
  26. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  27. package/src/__tests__/helpers/mock-process.ts +8 -13
  28. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  29. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  30. package/src/__tests__/helpers/msw/handlers/deployments.ts +127 -26
  31. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  32. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  33. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  34. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  35. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  36. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  37. package/src/__tests__/helpers/msw/index.ts +32 -1
  38. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  39. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  40. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  41. package/src/__tests__/index.test.ts +90 -72
  42. package/src/__tests__/init.test.ts +927 -631
  43. package/src/__tests__/jest.setup.ts +19 -42
  44. package/src/__tests__/kv.test.ts +355 -231
  45. package/src/__tests__/logger.test.ts +68 -2
  46. package/src/__tests__/logout.test.ts +47 -0
  47. package/src/__tests__/metrics.test.ts +94 -51
  48. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  49. package/src/__tests__/middleware.test.ts +212 -122
  50. package/src/__tests__/mtls-certificates.test.ts +588 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +452 -0
  53. package/src/__tests__/pages/pages.test.ts +81 -0
  54. package/src/__tests__/pages/project-create.test.ts +63 -0
  55. package/src/__tests__/pages/project-list.test.ts +110 -0
  56. package/src/__tests__/pages/project-upload.test.ts +500 -0
  57. package/src/__tests__/pages/publish.test.ts +2864 -0
  58. package/src/__tests__/pages-deployment-tail.test.ts +955 -0
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +1620 -830
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +237 -76
  63. package/src/__tests__/r2.test.ts +37 -56
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +267 -109
  66. package/src/__tests__/test-old-node-version.js +3 -3
  67. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  68. package/src/__tests__/tsconfig-sanity.ts +12 -0
  69. package/src/__tests__/tsconfig.json +8 -0
  70. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  71. package/src/__tests__/type-generation.test.ts +11 -2
  72. package/src/__tests__/user.test.ts +35 -72
  73. package/src/__tests__/whoami.test.tsx +8 -114
  74. package/src/__tests__/worker-namespace.test.ts +83 -69
  75. package/src/api/dev.ts +168 -60
  76. package/src/api/index.ts +10 -1
  77. package/src/api/mtls-certificate.ts +148 -0
  78. package/src/api/pages/create-worker-bundle-contents.ts +76 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +355 -0
  81. package/src/bundle.ts +221 -128
  82. package/src/cfetch/index.ts +0 -2
  83. package/src/cfetch/internal.ts +16 -21
  84. package/src/cli.ts +4 -4
  85. package/src/config/config.ts +14 -7
  86. package/src/config/environment.ts +73 -16
  87. package/src/config/index.ts +99 -30
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +248 -9
  90. package/src/create-worker-preview.ts +19 -8
  91. package/src/create-worker-upload-form.ts +48 -5
  92. package/src/d1/backups.tsx +43 -42
  93. package/src/d1/create.tsx +26 -21
  94. package/src/d1/{delete.tsx → delete.ts} +11 -14
  95. package/src/d1/execute.tsx +183 -170
  96. package/src/d1/index.ts +7 -6
  97. package/src/d1/list.tsx +22 -10
  98. package/src/d1/migrations/apply.tsx +212 -0
  99. package/src/d1/migrations/create.tsx +79 -0
  100. package/src/d1/migrations/helpers.ts +172 -0
  101. package/src/d1/migrations/index.ts +3 -0
  102. package/src/d1/migrations/list.tsx +95 -0
  103. package/src/d1/migrations/options.ts +23 -0
  104. package/src/d1/options.ts +3 -3
  105. package/src/d1/splitter.ts +161 -0
  106. package/src/d1/{types.tsx → types.ts} +1 -0
  107. package/src/d1/utils.ts +2 -1
  108. package/src/delete.ts +8 -16
  109. package/src/deployments.ts +333 -42
  110. package/src/deprecated/index.ts +8 -302
  111. package/src/dev/dev.tsx +57 -44
  112. package/src/dev/local.tsx +248 -74
  113. package/src/dev/remote.tsx +32 -3
  114. package/src/dev/start-server.ts +81 -66
  115. package/src/dev/use-esbuild.ts +17 -18
  116. package/src/dev/validate-dev-props.ts +9 -0
  117. package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
  118. package/src/dev.tsx +178 -117
  119. package/src/dialogs.ts +136 -0
  120. package/src/dispatch-namespace.ts +21 -17
  121. package/src/docs/index.ts +97 -0
  122. package/src/entry.ts +19 -11
  123. package/src/environment-variables/factory.ts +88 -0
  124. package/src/environment-variables/misc-variables.ts +30 -0
  125. package/src/generate/index.ts +298 -0
  126. package/src/git-client.ts +15 -4
  127. package/src/{index.tsx → index.ts} +134 -59
  128. package/src/init.ts +249 -187
  129. package/src/inspect.ts +16 -1
  130. package/src/jest.d.ts +4 -0
  131. package/src/kv/index.ts +15 -17
  132. package/src/logger.ts +32 -5
  133. package/src/metrics/metrics-config.ts +3 -3
  134. package/src/metrics/send-event.ts +6 -1
  135. package/src/miniflare-cli/assets.ts +64 -28
  136. package/src/miniflare-cli/index.ts +4 -7
  137. package/src/miniflare-cli/tsconfig.json +9 -0
  138. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  139. package/src/miniflare-cli/types.ts +11 -0
  140. package/src/module-collection.ts +91 -25
  141. package/src/mtls-certificate/cli.ts +155 -0
  142. package/src/pages/build.ts +410 -0
  143. package/src/pages/buildFunctions.ts +140 -0
  144. package/src/pages/deployment-tails.ts +281 -0
  145. package/src/pages/deployments.tsx +11 -33
  146. package/src/pages/{dev.tsx → dev.ts} +147 -139
  147. package/src/pages/errors.ts +1 -0
  148. package/src/pages/functions/buildPlugin.ts +61 -54
  149. package/src/pages/functions/buildWorker.ts +159 -33
  150. package/src/pages/functions/tsconfig.json +8 -0
  151. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  152. package/src/pages/{functions.tsx → functions.ts} +8 -4
  153. package/src/pages/{index.tsx → index.ts} +11 -3
  154. package/src/pages/projects.tsx +12 -22
  155. package/src/pages/prompt-select-project.tsx +31 -0
  156. package/src/pages/publish.tsx +46 -225
  157. package/src/pages/types.ts +6 -9
  158. package/src/pages/upload.tsx +58 -14
  159. package/src/pages/utils.ts +12 -1
  160. package/src/parse.ts +23 -1
  161. package/src/paths.ts +1 -1
  162. package/src/proxy.ts +5 -0
  163. package/src/publish/index.ts +20 -16
  164. package/src/publish/publish.ts +71 -46
  165. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  166. package/src/queues/cli/commands/consumer/add.ts +24 -24
  167. package/src/queues/cli/commands/consumer/index.ts +3 -6
  168. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  169. package/src/queues/cli/commands/create.ts +8 -8
  170. package/src/queues/cli/commands/delete.ts +8 -8
  171. package/src/queues/cli/commands/index.ts +6 -4
  172. package/src/queues/cli/commands/list.ts +8 -8
  173. package/src/queues/client.ts +1 -0
  174. package/src/queues/utils.ts +18 -0
  175. package/src/r2/helpers.ts +1 -0
  176. package/src/r2/index.ts +28 -28
  177. package/src/secret/index.ts +14 -16
  178. package/src/{sites.tsx → sites.ts} +1 -1
  179. package/src/tail/createTail.ts +94 -3
  180. package/src/tail/filters.ts +1 -1
  181. package/src/tail/index.ts +8 -11
  182. package/src/tail/printing.ts +15 -0
  183. package/src/traverse-module-graph.ts +53 -0
  184. package/src/tsconfig-sanity.ts +16 -0
  185. package/src/type-generation.ts +28 -20
  186. package/src/user/access.ts +0 -1
  187. package/src/user/auth-variables.ts +113 -0
  188. package/src/user/choose-account.tsx +1 -31
  189. package/src/user/index.ts +0 -1
  190. package/src/user/{user.tsx → user.ts} +123 -82
  191. package/src/utils/render.ts +93 -0
  192. package/src/{whoami.tsx → whoami.ts} +37 -71
  193. package/src/worker.ts +30 -1
  194. package/src/yargs-types.ts +22 -5
  195. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  196. package/templates/__tests__/tsconfig.json +8 -0
  197. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  198. package/templates/checked-fetch.js +9 -3
  199. package/templates/d1-beta-facade.js +51 -3
  200. package/templates/facade.d.ts +14 -0
  201. package/templates/first-party-worker-module-facade.ts +4 -3
  202. package/templates/format-dev-errors.ts +8 -6
  203. package/templates/gitignore +1 -0
  204. package/templates/init-tests/test-jest-new-worker.js +3 -5
  205. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  206. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  207. package/templates/middleware/loader-modules.ts +2 -2
  208. package/templates/middleware/loader-sw.ts +51 -31
  209. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  210. package/templates/new-worker.ts +3 -0
  211. package/templates/pages-dev-pipeline.ts +4 -1
  212. package/templates/pages-shim.ts +4 -1
  213. package/templates/pages-template-plugin.ts +19 -10
  214. package/templates/serve-static-assets.ts +17 -14
  215. package/templates/service-bindings-module-facade.js +1 -0
  216. package/templates/tsconfig-sanity.ts +11 -0
  217. package/templates/tsconfig.init.json +105 -0
  218. package/templates/tsconfig.json +5 -103
  219. package/templates/tsconfig.tsbuildinfo +1 -0
  220. package/wrangler-dist/cli.d.ts +820 -70
  221. package/wrangler-dist/cli.js +68161 -78780
  222. package/wrangler-dist/wasm-sync.wasm +0 -0
  223. package/src/__tests__/api-devregistry.test.js +0 -56
  224. package/src/__tests__/d1.test.ts +0 -74
  225. package/src/__tests__/dialogs.test.tsx +0 -40
  226. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  227. package/src/__tests__/pages.test.ts +0 -2387
  228. package/src/d1/migrations.tsx +0 -446
  229. package/src/dialogs.tsx +0 -169
  230. package/src/environment-variables.ts +0 -50
  231. package/src/pages/build.tsx +0 -270
  232. package/src/user/env-vars.ts +0 -46
  233. package/templates/experimental-local-cache-stubs.js +0 -27
  234. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  235. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  236. /package/src/pages/{hash.tsx → hash.ts} +0 -0
package/src/bundle.ts CHANGED
@@ -9,10 +9,17 @@ import tmp from "tmp-promise";
9
9
  import createModuleCollector from "./module-collection";
10
10
  import { getBasePath, toUrlPath } from "./paths";
11
11
  import type { Config } from "./config";
12
+ import type { DurableObjectBindings } from "./config/environment";
12
13
  import type { WorkerRegistry } from "./dev-registry";
13
14
  import type { Entry } from "./entry";
14
15
  import type { CfModule } from "./worker";
15
16
 
17
+ export const COMMON_ESBUILD_OPTIONS = {
18
+ // Our workerd runtime uses the same V8 version as recent Chrome, which is highly ES2022 compliant: https://kangax.github.io/compat-table/es2016plus/
19
+ target: "es2022",
20
+ loader: { ".js": "jsx", ".mjs": "jsx", ".cjs": "jsx" },
21
+ } as const;
22
+
16
23
  export type BundleResult = {
17
24
  modules: CfModule[];
18
25
  dependencies: esbuild.Metafile["outputs"][string]["inputs"];
@@ -28,6 +35,19 @@ type StaticAssetsConfig =
28
35
  })
29
36
  | undefined;
30
37
 
38
+ /**
39
+ * When applying the middleware facade for service workers, we need to inject
40
+ * some code at the top of the final output bundle. Applying an inject too early
41
+ * will allow esbuild to reorder the code. Additionally, we need to make sure
42
+ * user code is bundled in the final esbuild step with `watch` correctly
43
+ * configured, so code changes are detected.
44
+ *
45
+ * This type is used as the return type for the `MiddlewareFn` type representing
46
+ * a facade-applying function. Returned injects should be injected with the
47
+ * final esbuild step.
48
+ */
49
+ type EntryWithInject = Entry & { inject?: string[] };
50
+
31
51
  /**
32
52
  * RegExp matching against esbuild's error text when it is unable to resolve
33
53
  * a Node built-in module. If we detect this when node_compat is disabled,
@@ -72,6 +92,24 @@ Add "node_compat = true" to your wrangler.toml file to enable Node compatibility
72
92
  }
73
93
  }
74
94
 
95
+ const nodejsCompatPlugin: esbuild.Plugin = {
96
+ name: "nodejs_compat Plugin",
97
+ setup(pluginBuild) {
98
+ pluginBuild.onResolve({ filter: /node:.*/ }, () => {
99
+ return { external: true };
100
+ });
101
+ },
102
+ };
103
+
104
+ const cloudflareJsPlugin: esbuild.Plugin = {
105
+ name: "cloudflare javascript Plugin",
106
+ setup(pluginBuild) {
107
+ pluginBuild.onResolve({ filter: /^cloudflare:.*/ }, () => {
108
+ return { external: true };
109
+ });
110
+ },
111
+ };
112
+
75
113
  /**
76
114
  * Generate a bundle for the worker identified by the arguments passed in.
77
115
  */
@@ -82,13 +120,16 @@ export async function bundleWorker(
82
120
  serveAssetsFromWorker: boolean;
83
121
  assets?: StaticAssetsConfig;
84
122
  betaD1Shims?: string[];
123
+ doBindings: DurableObjectBindings;
85
124
  jsxFactory?: string;
86
125
  jsxFragment?: string;
126
+ entryName?: string;
87
127
  rules: Config["rules"];
88
128
  watch?: esbuild.WatchMode | boolean;
89
129
  tsconfig?: string;
90
130
  minify?: boolean;
91
- nodeCompat?: boolean;
131
+ legacyNodeCompat?: boolean;
132
+ nodejsCompat?: boolean;
92
133
  define: Config["define"];
93
134
  checkFetch: boolean;
94
135
  services?: Config["services"];
@@ -97,12 +138,12 @@ export async function bundleWorker(
97
138
  targetConsumer: "dev" | "publish";
98
139
  local: boolean;
99
140
  testScheduled?: boolean;
100
- experimentalLocalStubCache?: boolean;
141
+ experimentalLocal?: boolean;
101
142
  inject?: string[];
102
143
  loader?: Record<string, string>;
103
144
  sourcemap?: esbuild.CommonOptions["sourcemap"];
104
145
  plugins?: esbuild.Plugin[];
105
- // TODO: Rip these out https://github.com/cloudflare/wrangler2/issues/2153
146
+ // TODO: Rip these out https://github.com/cloudflare/workers-sdk/issues/2153
106
147
  disableModuleCollection?: boolean;
107
148
  isOutfile?: boolean;
108
149
  }
@@ -110,13 +151,16 @@ export async function bundleWorker(
110
151
  const {
111
152
  serveAssetsFromWorker,
112
153
  betaD1Shims,
154
+ doBindings,
113
155
  jsxFactory,
114
156
  jsxFragment,
157
+ entryName,
115
158
  rules,
116
159
  watch,
117
160
  tsconfig,
118
161
  minify,
119
- nodeCompat,
162
+ legacyNodeCompat,
163
+ nodejsCompat,
120
164
  checkFetch,
121
165
  local,
122
166
  assets,
@@ -125,7 +169,7 @@ export async function bundleWorker(
125
169
  firstPartyWorkerDevFacade,
126
170
  targetConsumer,
127
171
  testScheduled,
128
- experimentalLocalStubCache,
172
+ experimentalLocal,
129
173
  inject: injectOption,
130
174
  loader,
131
175
  sourcemap,
@@ -199,8 +243,29 @@ export async function bundleWorker(
199
243
  path: "templates/middleware/middleware-scheduled.ts",
200
244
  });
201
245
  }
246
+ if (experimentalLocal) {
247
+ // In Miniflare 3, we bind the user's worker as a service binding in a
248
+ // special entry worker that handles things like injecting `Request.cf`,
249
+ // live-reload, and the pretty-error page.
250
+ //
251
+ // Unfortunately, due to a bug in `workerd`, errors thrown asynchronously by
252
+ // native APIs don't have `stack`s. This means Miniflare can't extract the
253
+ // `stack` trace from dispatching to the user worker service binding by
254
+ // `try/catch`.
255
+ //
256
+ // As a stop-gap solution, if the `MF-Experimental-Error-Stack` header is
257
+ // truthy on responses, the body will be interpreted as a JSON-error of the
258
+ // form `{ message?: string, name?: string, stack?: string }`.
259
+ //
260
+ // This middleware wraps the user's worker in a `try/catch`, and rewrites
261
+ // errors in this format so a pretty-error page can be shown.
262
+ middlewareToLoad.push({
263
+ path: "templates/middleware/middleware-miniflare3-json-error.ts",
264
+ dev: true,
265
+ });
266
+ }
202
267
 
203
- type MiddlewareFn = (arg0: Entry) => Promise<Entry>;
268
+ type MiddlewareFn = (currentEntry: Entry) => Promise<EntryWithInject>;
204
269
  const middleware: (false | undefined | MiddlewareFn)[] = [
205
270
  // serve static assets
206
271
  serveAssetsFromWorker &&
@@ -237,7 +302,13 @@ export async function bundleWorker(
237
302
  Array.isArray(betaD1Shims) &&
238
303
  betaD1Shims.length > 0 &&
239
304
  ((currentEntry: Entry) => {
240
- return applyD1BetaFacade(currentEntry, tmpDir.path, betaD1Shims, local);
305
+ return applyD1BetaFacade(
306
+ currentEntry,
307
+ tmpDir.path,
308
+ betaD1Shims,
309
+ local && !experimentalLocal,
310
+ doBindings
311
+ );
241
312
  }),
242
313
 
243
314
  // Middleware loader: to add middleware, we add the path to the middleware
@@ -261,75 +332,67 @@ export async function bundleWorker(
261
332
  (m) =>
262
333
  (targetConsumer === "dev" && m.dev !== false) ||
263
334
  (m.publish && targetConsumer === "publish")
264
- ),
265
- moduleCollector.plugin
335
+ )
266
336
  );
267
337
  }),
268
338
  ].filter(Boolean);
269
339
 
270
- let inputEntry = entry;
340
+ const inject: string[] = injectOption ?? [];
341
+ if (checkFetch) inject.push(checkedFetchFileToInject);
271
342
 
343
+ let inputEntry: EntryWithInject = entry;
272
344
  for (const middlewareFn of middleware as MiddlewareFn[]) {
273
345
  inputEntry = await middlewareFn(inputEntry);
346
+ if (inputEntry.inject !== undefined) inject.push(...inputEntry.inject);
274
347
  }
275
348
 
276
349
  // At this point, inputEntry points to the entry point we want to build.
277
350
 
278
- const inject: string[] = injectOption ?? [];
279
- if (checkFetch) inject.push(checkedFetchFileToInject);
280
- if (experimentalLocalStubCache) {
281
- inject.push(
282
- path.resolve(getBasePath(), "templates/experimental-local-cache-stubs.js")
283
- );
284
- }
285
-
286
351
  const buildOptions: esbuild.BuildOptions & { metafile: true } = {
287
352
  entryPoints: [inputEntry.file],
288
353
  bundle: true,
289
354
  absWorkingDir: entry.directory,
290
355
  outdir: destination,
356
+ entryNames: entryName || path.parse(entry.file).name,
291
357
  ...(isOutfile
292
358
  ? {
293
359
  outdir: undefined,
294
360
  outfile: destination,
361
+ entryNames: undefined,
295
362
  }
296
363
  : {}),
297
364
  inject,
298
365
  external: ["__STATIC_CONTENT_MANIFEST"],
299
366
  format: entry.format === "modules" ? "esm" : "iife",
300
- target: "es2020",
367
+ target: COMMON_ESBUILD_OPTIONS.target,
301
368
  sourcemap: sourcemap ?? true, // this needs to use ?? to accept false
302
369
  // Include a reference to the output folder in the sourcemap.
303
370
  // This is omitted by default, but we need it to properly resolve source paths in error output.
304
371
  sourceRoot: destination,
305
372
  minify,
306
373
  metafile: true,
307
- conditions: ["worker", "browser"],
374
+ conditions: ["workerd", "worker", "browser"],
308
375
  ...(process.env.NODE_ENV && {
309
376
  define: {
310
377
  // use process.env["NODE_ENV" + ""] so that esbuild doesn't replace it
311
- // when we do a build of wrangler. (re: https://github.com/cloudflare/wrangler2/issues/1477)
378
+ // when we do a build of wrangler. (re: https://github.com/cloudflare/workers-sdk/issues/1477)
312
379
  "process.env.NODE_ENV": `"${process.env["NODE_ENV" + ""]}"`,
313
- ...(nodeCompat ? { global: "globalThis" } : {}),
380
+ ...(legacyNodeCompat ? { global: "globalThis" } : {}),
314
381
  ...(checkFetch ? { fetch: "checkedFetch" } : {}),
315
382
  ...options.define,
316
383
  },
317
384
  }),
318
385
  loader: {
319
- ".js": "jsx",
320
- ".mjs": "jsx",
321
- ".cjs": "jsx",
386
+ ...COMMON_ESBUILD_OPTIONS.loader,
322
387
  ...(loader || {}),
323
388
  },
324
389
  plugins: [
325
- // We run the moduleCollector plugin for service workers as part of the middleware loader
326
- // so we only run here for modules or with no middleware to load
327
- ...(entry.format === "modules" || middlewareToLoad.length === 0
328
- ? [moduleCollector.plugin]
329
- : []),
330
- ...(nodeCompat
390
+ moduleCollector.plugin,
391
+ ...(legacyNodeCompat
331
392
  ? [NodeGlobalsPolyfills({ buffer: true }), NodeModulesPolyfills()]
332
393
  : []),
394
+ ...(nodejsCompat ? [nodejsCompatPlugin] : []),
395
+ ...[cloudflareJsPlugin],
333
396
  ...(plugins || []),
334
397
  ],
335
398
  ...(jsxFactory && { jsxFactory }),
@@ -345,7 +408,8 @@ export async function bundleWorker(
345
408
  try {
346
409
  result = await esbuild.build(buildOptions);
347
410
  } catch (e) {
348
- if (!nodeCompat && isBuildFailure(e)) rewriteNodeCompatBuildFailure(e);
411
+ if (!legacyNodeCompat && isBuildFailure(e))
412
+ rewriteNodeCompatBuildFailure(e);
349
413
  throw e;
350
414
  }
351
415
 
@@ -371,13 +435,23 @@ export async function bundleWorker(
371
435
  _path.includes(".map")
372
436
  )[0];
373
437
 
438
+ const resolvedEntryPointPath = path.resolve(
439
+ entry.directory,
440
+ entryPointOutputs[0][0]
441
+ );
442
+
443
+ // copy all referenced modules into the output bundle directory
444
+ for (const module of moduleCollector.modules) {
445
+ fs.writeFileSync(
446
+ path.join(path.dirname(resolvedEntryPointPath), module.name),
447
+ module.content
448
+ );
449
+ }
450
+
374
451
  return {
375
452
  modules: moduleCollector.modules,
376
453
  dependencies,
377
- resolvedEntryPointPath: path.resolve(
378
- entry.directory,
379
- entryPointOutputs[0][0]
380
- ),
454
+ resolvedEntryPointPath,
381
455
  bundleType,
382
456
  stop: result.stop,
383
457
  sourceMapPath,
@@ -463,14 +537,16 @@ interface MiddlewareLoader {
463
537
  async function applyMiddlewareLoaderFacade(
464
538
  entry: Entry,
465
539
  tmpDirPath: string,
466
- middleware: MiddlewareLoader[], // a list of paths to middleware files
467
- moduleCollectorPlugin: esbuild.Plugin
468
- ): Promise<Entry> {
540
+ middleware: MiddlewareLoader[] // a list of paths to middleware files
541
+ ): Promise<EntryWithInject> {
469
542
  // Firstly we need to insert the middleware array into the project,
470
543
  // and then we load the middleware - this insertion and loading is
471
544
  // different for each format.
472
545
 
473
- // STEP 1: Insert the middleware
546
+ // Make sure we resolve all files relative to the actual temporary directory,
547
+ // otherwise we'll have issues with source maps
548
+ tmpDirPath = fs.realpathSync(tmpDirPath);
549
+
474
550
  const targetPathInsertion = path.join(
475
551
  tmpDirPath,
476
552
  "middleware-insertion.entry.js"
@@ -513,7 +589,7 @@ async function applyMiddlewareLoaderFacade(
513
589
  );
514
590
 
515
591
  await esbuild.build({
516
- entryPoints: [path.resolve(getBasePath(), dynamicFacadePath)],
592
+ entryPoints: [dynamicFacadePath],
517
593
  bundle: true,
518
594
  sourcemap: true,
519
595
  format: "esm",
@@ -530,98 +606,81 @@ async function applyMiddlewareLoaderFacade(
530
606
  ],
531
607
  outfile: targetPathInsertion,
532
608
  });
533
- } else {
534
- // We handle service workers slightly differently as we have to overwrite
535
- // the event listeners and reimplement them
536
-
609
+ const targetPathLoader = path.join(
610
+ tmpDirPath,
611
+ "middleware-loader.entry.js"
612
+ );
613
+ const loaderPath = path.resolve(
614
+ getBasePath(),
615
+ "templates/middleware/loader-modules.ts"
616
+ );
537
617
  await esbuild.build({
538
- entryPoints: [entry.file],
618
+ entryPoints: [loaderPath],
539
619
  bundle: true,
540
620
  sourcemap: true,
541
- define: {
542
- "process.env.NODE_ENV": `"${process.env["NODE_ENV" + ""]}"`,
543
- },
544
621
  format: "esm",
545
- outfile: targetPathInsertion,
546
- plugins: [moduleCollectorPlugin],
622
+ plugins: [
623
+ esbuildAliasExternalPlugin({
624
+ __ENTRY_POINT__: targetPathInsertion,
625
+ "./common": path.resolve(
626
+ getBasePath(),
627
+ "templates/middleware/common.ts"
628
+ ),
629
+ }),
630
+ ],
631
+ outfile: targetPathLoader,
547
632
  });
548
-
633
+ return {
634
+ ...entry,
635
+ file: targetPathLoader,
636
+ };
637
+ } else {
549
638
  const imports = middlewareIdentifiers
550
- .map(
551
- (m, i) =>
552
- `import ${m} from "${toUrlPath(
553
- path.resolve(getBasePath(), middleware[i].path)
554
- )}";`
555
- )
639
+ .map((m) => `import ${m} from "${m}";`)
556
640
  .join("\n");
557
-
558
- // We add the new modules with imports and then register using the
559
- // addMiddleware function (which gets rewritten in the next build step)
560
-
561
- // We choose to run middleware inserted in wrangler before user inserted
562
- // middleware in the stack
563
- // To do this, we either need to execute the addMiddleware function first
564
- // before any user middleware, or use a separate handling function.
565
- // We choose to do the latter as to prepend, we would have to load the entire
566
- // script into memory as a prepend function doesn't exist or work in the same
567
- // way that an append function does.
568
-
569
- fs.copyFileSync(targetPathInsertion, dynamicFacadePath);
570
- fs.appendFileSync(
571
- dynamicFacadePath,
572
- `
641
+ const contents = `import { __facade_registerInternal__ } from "__LOADER__";
573
642
  ${imports}
574
- addMiddlewareInternal([${middlewareIdentifiers.join(",")}])
575
- `
576
- );
577
- }
643
+ __facade_registerInternal__([${middlewareIdentifiers.join(",")}]);`;
644
+ fs.writeFileSync(dynamicFacadePath, contents);
578
645
 
579
- // STEP 2: Load the middleware
580
- // We want to get the filename of the orginal entry point
581
- let targetPathLoader = path.join(tmpDirPath, path.basename(entry.file));
582
- if (path.extname(entry.file) === "") targetPathLoader += ".js";
583
-
584
- const loaderPath =
585
- entry.format === "modules"
586
- ? path.resolve(getBasePath(), "templates/middleware/loader-modules.ts")
587
- : dynamicFacadePath;
588
-
589
- await esbuild.build({
590
- entryPoints: [loaderPath],
591
- bundle: true,
592
- sourcemap: true,
593
- format: "esm",
594
- ...(entry.format === "service-worker"
595
- ? {
596
- inject: [
597
- path.resolve(getBasePath(), "templates/middleware/loader-sw.ts"),
598
- ],
599
- define: {
600
- addEventListener: "__facade_addEventListener__",
601
- removeEventListener: "__facade_removeEventListener__",
602
- dispatchEvent: "__facade_dispatchEvent__",
603
- addMiddleware: "__facade_register__",
604
- addMiddlewareInternal: "__facade_registerInternal__",
605
- },
606
- }
607
- : {
608
- plugins: [
609
- esbuildAliasExternalPlugin({
610
- __ENTRY_POINT__: targetPathInsertion,
611
- "./common": path.resolve(
646
+ await esbuild.build({
647
+ entryPoints: [dynamicFacadePath],
648
+ bundle: true,
649
+ sourcemap: true,
650
+ format: "iife",
651
+ plugins: [
652
+ {
653
+ name: "dynamic-facade-imports",
654
+ setup(build) {
655
+ build.onResolve({ filter: /^__LOADER__$/ }, () => {
656
+ const loaderPath = path.resolve(
612
657
  getBasePath(),
613
- "templates/middleware/common.ts"
614
- ),
615
- }),
616
- ],
617
- }),
618
- outfile: targetPathLoader,
619
- });
620
-
621
- return {
622
- ...entry,
623
- file: targetPathLoader,
624
- };
658
+ "templates/middleware/loader-sw.ts"
659
+ );
660
+ return { path: loaderPath };
661
+ });
662
+ const middlewareFilter = /^__MIDDLEWARE_(\d+)__$/;
663
+ build.onResolve({ filter: middlewareFilter }, (args) => {
664
+ const match = middlewareFilter.exec(args.path);
665
+ assert(match !== null);
666
+ const middlewareIndex = parseInt(match[1]);
667
+ return {
668
+ path: path.resolve(
669
+ getBasePath(),
670
+ middleware[middlewareIndex].path
671
+ ),
672
+ };
673
+ });
674
+ },
675
+ },
676
+ ],
677
+ outfile: targetPathInsertion,
678
+ });
679
+ return {
680
+ ...entry,
681
+ inject: [targetPathInsertion],
682
+ };
683
+ }
625
684
  }
626
685
 
627
686
  /**
@@ -771,17 +830,51 @@ async function applyFirstPartyWorkerDevFacade(
771
830
  * This code be removed from here when the API is in Workers core,
772
831
  * but moved inside Miniflare for simulating D1.
773
832
  */
774
-
775
833
  async function applyD1BetaFacade(
776
834
  entry: Entry,
777
835
  tmpDirPath: string,
778
836
  betaD1Shims: string[],
779
- local: boolean
837
+ miniflare2: boolean,
838
+ doBindings: DurableObjectBindings
780
839
  ): Promise<Entry> {
840
+ let entrypointPath = path.resolve(
841
+ getBasePath(),
842
+ "templates/d1-beta-facade.js"
843
+ );
844
+ if (Array.isArray(doBindings) && doBindings.length > 0) {
845
+ //we have DO bindings, so we need to shim them
846
+ const maskedDoBindings = doBindings
847
+ // Don't shim anything not local to this worker
848
+ .filter((b) => !b.script_name)
849
+ // Reexport the DO classnames
850
+ .map(
851
+ (b) =>
852
+ `export const ${b.class_name} = maskDurableObjectDefinition(OTHER_EXPORTS.${b.class_name});`
853
+ )
854
+ .join("\n");
855
+ const baseFile = fs.readFileSync(
856
+ path.resolve(getBasePath(), "templates/d1-beta-facade.js"),
857
+ "utf8"
858
+ );
859
+ //getMaskedEnv is already used to shim regular Workers
860
+ const contents = `
861
+ ${baseFile}
862
+
863
+ var maskDurableObjectDefinition = (cls) =>
864
+ class extends cls {
865
+ constructor(state, env) {
866
+ super(state, getMaskedEnv(env));
867
+ }
868
+ };
869
+ ${maskedDoBindings}`;
870
+ const doD1FacadePath = path.join(tmpDirPath, "d1-do-facade.js");
871
+ //write our shim so we can build it
872
+ fs.writeFileSync(doD1FacadePath, contents);
873
+ entrypointPath = doD1FacadePath;
874
+ }
781
875
  const targetPath = path.join(tmpDirPath, "d1-beta-facade.entry.js");
782
-
783
876
  await esbuild.build({
784
- entryPoints: [path.resolve(getBasePath(), "templates/d1-beta-facade.js")],
877
+ entryPoints: [entrypointPath],
785
878
  bundle: true,
786
879
  format: "esm",
787
880
  sourcemap: true,
@@ -792,7 +885,7 @@ async function applyD1BetaFacade(
792
885
  ],
793
886
  define: {
794
887
  __D1_IMPORTS__: JSON.stringify(betaD1Shims),
795
- __LOCAL_MODE__: JSON.stringify(local),
888
+ __LOCAL_MODE__: JSON.stringify(miniflare2),
796
889
  },
797
890
  outfile: targetPath,
798
891
  });
@@ -6,8 +6,6 @@ import type { RequestInit } from "undici";
6
6
 
7
7
  // Check out https://api.cloudflare.com/ for API docs.
8
8
 
9
- export { getCloudflareAPIBaseURL as getCloudflareApiBaseUrl } from "./internal";
10
-
11
9
  export interface FetchError {
12
10
  code: number;
13
11
  message: string;
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { fetch, File, Headers } from "undici";
3
3
  import { version as wranglerVersion } from "../../package.json";
4
- import { getEnvironmentVariableFactory } from "../environment-variables";
4
+ import { getCloudflareApiBaseUrl } from "../environment-variables/misc-variables";
5
5
  import { logger } from "../logger";
6
6
  import { ParseError, parseJSON } from "../parse";
7
7
  import { loginOrRefreshIfRequired, requireApiToken } from "../user";
@@ -9,15 +9,6 @@ import type { ApiCredentials } from "../user";
9
9
  import type { URLSearchParams } from "node:url";
10
10
  import type { RequestInit, HeadersInit, Response } from "undici";
11
11
 
12
- /**
13
- * Get the URL to use to access the Cloudflare API.
14
- */
15
- export const getCloudflareAPIBaseURL = getEnvironmentVariableFactory({
16
- variableName: "CLOUDFLARE_API_BASE_URL",
17
- deprecatedName: "CF_API_BASE_URL",
18
- defaultValue: "https://api.cloudflare.com/client/v4",
19
- });
20
-
21
12
  /*
22
13
  * performApiFetch does everything required to make a CF API request,
23
14
  * but doesn't parse the response as JSON. For normal V4 API responses,
@@ -42,12 +33,17 @@ export async function performApiFetch(
42
33
 
43
34
  const queryString = queryParams ? `?${queryParams.toString()}` : "";
44
35
  logger.debug(
45
- `-- START CF API REQUEST: ${method} ${getCloudflareAPIBaseURL()}${resource}${queryString}`
36
+ `-- START CF API REQUEST: ${method} ${getCloudflareApiBaseUrl()}${resource}${queryString}`
37
+ );
38
+ const logHeaders = cloneHeaders(headers);
39
+ delete logHeaders["Authorization"];
40
+ logger.debug("HEADERS:", JSON.stringify(logHeaders, null, 2));
41
+ logger.debug(
42
+ "INIT:",
43
+ JSON.stringify({ ...init, headers: logHeaders }, null, 2)
46
44
  );
47
- logger.debug("HEADERS:", JSON.stringify(headers, null, 2));
48
- logger.debug("INIT:", JSON.stringify(init, null, 2));
49
45
  logger.debug("-- END CF API REQUEST");
50
- return await fetch(`${getCloudflareAPIBaseURL()}${resource}${queryString}`, {
46
+ return await fetch(`${getCloudflareApiBaseUrl()}${resource}${queryString}`, {
51
47
  method,
52
48
  ...init,
53
49
  headers,
@@ -83,7 +79,9 @@ export async function fetchInternal<ResponseType>(
83
79
  response.statusText,
84
80
  response.status
85
81
  );
86
- logger.debug("HEADERS:", JSON.stringify(response.headers, null, 2));
82
+ const logHeaders = cloneHeaders(response.headers);
83
+ delete logHeaders["Authorization"];
84
+ logger.debug("HEADERS:", JSON.stringify(logHeaders, null, 2));
87
85
  logger.debug("RESPONSE:", jsonText);
88
86
  logger.debug("-- END CF API RESPONSE");
89
87
 
@@ -166,7 +164,7 @@ export async function fetchKVGetValue(
166
164
  const auth = requireApiToken();
167
165
  const headers: Record<string, string> = {};
168
166
  addAuthorizationHeaderIfUnspecified(headers, auth);
169
- const resource = `${getCloudflareAPIBaseURL()}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
167
+ const resource = `${getCloudflareApiBaseUrl()}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
170
168
  const response = await fetch(resource, {
171
169
  method: "GET",
172
170
  headers,
@@ -199,7 +197,7 @@ export async function fetchR2Objects(
199
197
  addAuthorizationHeaderIfUnspecified(headers, auth);
200
198
  addUserAgent(headers);
201
199
 
202
- const response = await fetch(`${getCloudflareAPIBaseURL()}${resource}`, {
200
+ const response = await fetch(`${getCloudflareApiBaseUrl()}${resource}`, {
203
201
  ...bodyInit,
204
202
  headers,
205
203
  });
@@ -226,7 +224,7 @@ export async function fetchDashboardScript(
226
224
  addAuthorizationHeaderIfUnspecified(headers, auth);
227
225
  addUserAgent(headers);
228
226
 
229
- const response = await fetch(`${getCloudflareAPIBaseURL()}${resource}`, {
227
+ const response = await fetch(`${getCloudflareApiBaseUrl()}${resource}`, {
230
228
  ...bodyInit,
231
229
  headers,
232
230
  });
@@ -254,9 +252,6 @@ export async function fetchDashboardScript(
254
252
  }
255
253
 
256
254
  return file ?? "";
257
-
258
- // Follow up on issue in Undici about multipart/form-data support & replace the workaround: https://github.com/nodejs/undici/issues/974
259
- // This should be using a builtin formData() parser pattern.
260
255
  } else {
261
256
  return response.text();
262
257
  }
package/src/cli.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import process from "process";
2
2
  import { hideBin } from "yargs/helpers";
3
- import { unstable_dev } from "./api";
3
+ import { unstable_dev, unstable_pages } from "./api";
4
4
  import { FatalError } from "./errors";
5
5
  import { main } from ".";
6
6
 
7
- import type { UnstableDevWorker } from "./api";
7
+ import type { UnstableDevWorker, UnstableDevOptions } from "./api";
8
8
  /**
9
9
  * The main entrypoint for the CLI.
10
10
  * main only gets called when the script is run directly, not when it's imported as a module.
@@ -24,5 +24,5 @@ if (typeof jest === "undefined" && require.main === module) {
24
24
  * It makes it possible to import wrangler from 'wrangler',
25
25
  * and call wrangler.unstable_dev().
26
26
  */
27
- export { unstable_dev };
28
- export type { UnstableDevWorker };
27
+ export { unstable_dev, unstable_pages };
28
+ export type { UnstableDevWorker, UnstableDevOptions };