wrangler 0.0.0-e7a0cd5b → 0.0.0-e87ad068

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 (255) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +254 -128
  4. package/package.json +27 -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 +797 -98
  9. package/src/__tests__/constellation.test.ts +371 -0
  10. package/src/__tests__/d1/d1.test.ts +82 -0
  11. package/src/__tests__/d1/execute.test.ts +66 -0
  12. package/src/__tests__/d1/migrate.test.ts +257 -0
  13. package/src/__tests__/d1/splitter.test.ts +255 -0
  14. package/src/__tests__/delete.test.ts +91 -49
  15. package/src/__tests__/deployments.test.ts +330 -56
  16. package/src/__tests__/dev.test.tsx +198 -90
  17. package/src/__tests__/generate.test.ts +12 -10
  18. package/src/__tests__/guess-worker-format.test.ts +35 -0
  19. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  20. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  21. package/src/__tests__/helpers/mock-console.ts +6 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  23. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  24. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  25. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  26. package/src/__tests__/helpers/mock-kv.ts +29 -16
  27. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  28. package/src/__tests__/helpers/mock-process.ts +8 -13
  29. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  30. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  31. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  33. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  34. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  35. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  36. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  37. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  38. package/src/__tests__/helpers/msw/index.ts +32 -1
  39. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  40. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  41. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  42. package/src/__tests__/index.test.ts +92 -72
  43. package/src/__tests__/init.test.ts +1033 -631
  44. package/src/__tests__/jest.setup.ts +19 -42
  45. package/src/__tests__/kv.test.ts +355 -231
  46. package/src/__tests__/logger.test.ts +68 -2
  47. package/src/__tests__/logout.test.ts +47 -0
  48. package/src/__tests__/metrics.test.ts +94 -51
  49. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  50. package/src/__tests__/middleware.test.ts +212 -122
  51. package/src/__tests__/mtls-certificates.test.ts +589 -0
  52. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  53. package/src/__tests__/pages/functions-build.test.ts +529 -0
  54. package/src/__tests__/pages/pages.test.ts +81 -0
  55. package/src/__tests__/pages/project-create.test.ts +63 -0
  56. package/src/__tests__/pages/project-list.test.ts +110 -0
  57. package/src/__tests__/pages/project-upload.test.ts +500 -0
  58. package/src/__tests__/pages/publish.test.ts +2864 -0
  59. package/src/__tests__/pages-deployment-tail.test.ts +957 -0
  60. package/src/__tests__/parse.test.ts +106 -0
  61. package/src/__tests__/publish.test.ts +2227 -1005
  62. package/src/__tests__/pubsub.test.ts +226 -100
  63. package/src/__tests__/queues.test.ts +238 -77
  64. package/src/__tests__/r2.test.ts +55 -57
  65. package/src/__tests__/secret.test.ts +179 -130
  66. package/src/__tests__/tail.test.ts +313 -113
  67. package/src/__tests__/test-old-node-version.js +3 -3
  68. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  69. package/src/__tests__/tsconfig-sanity.ts +12 -0
  70. package/src/__tests__/tsconfig.json +8 -0
  71. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  72. package/src/__tests__/type-generation.test.ts +43 -26
  73. package/src/__tests__/unstableDev.test.ts +61 -0
  74. package/src/__tests__/user.test.ts +35 -72
  75. package/src/__tests__/whoami.test.tsx +8 -114
  76. package/src/__tests__/worker-namespace.test.ts +83 -69
  77. package/src/api/dev.ts +180 -60
  78. package/src/api/index.ts +10 -1
  79. package/src/api/mtls-certificate.ts +148 -0
  80. package/src/api/pages/create-worker-bundle-contents.ts +80 -0
  81. package/src/api/pages/index.ts +5 -0
  82. package/src/api/pages/publish.tsx +371 -0
  83. package/src/bundle.ts +315 -148
  84. package/src/cfetch/index.ts +0 -2
  85. package/src/cfetch/internal.ts +33 -33
  86. package/src/cli.ts +4 -4
  87. package/src/config/config.ts +14 -7
  88. package/src/config/environment.ts +120 -24
  89. package/src/config/index.ts +117 -35
  90. package/src/config/validation-helpers.ts +1 -1
  91. package/src/config/validation.ts +430 -19
  92. package/src/constellation/createProject.tsx +51 -0
  93. package/src/constellation/deleteProject.ts +51 -0
  94. package/src/constellation/deleteProjectModel.ts +76 -0
  95. package/src/constellation/index.ts +75 -0
  96. package/src/constellation/listCatalog.tsx +35 -0
  97. package/src/constellation/listModel.tsx +49 -0
  98. package/src/constellation/listProject.tsx +28 -0
  99. package/src/constellation/listRuntime.tsx +28 -0
  100. package/src/constellation/options.ts +17 -0
  101. package/src/constellation/types.ts +17 -0
  102. package/src/constellation/uploadModel.tsx +84 -0
  103. package/src/constellation/utils.ts +90 -0
  104. package/src/create-worker-preview.ts +19 -8
  105. package/src/create-worker-upload-form.ts +81 -18
  106. package/src/d1/backups.tsx +47 -46
  107. package/src/d1/constants.ts +5 -0
  108. package/src/d1/create.tsx +85 -37
  109. package/src/d1/{delete.tsx → delete.ts} +12 -15
  110. package/src/d1/execute.tsx +228 -156
  111. package/src/d1/index.ts +31 -7
  112. package/src/d1/list.tsx +27 -13
  113. package/src/d1/migrations/apply.tsx +235 -0
  114. package/src/d1/migrations/create.tsx +79 -0
  115. package/src/d1/migrations/helpers.ts +171 -0
  116. package/src/d1/migrations/index.ts +3 -0
  117. package/src/d1/migrations/list.tsx +95 -0
  118. package/src/d1/migrations/options.ts +23 -0
  119. package/src/d1/options.ts +12 -2
  120. package/src/d1/splitter.ts +161 -0
  121. package/src/d1/types.ts +32 -0
  122. package/src/d1/utils.ts +12 -2
  123. package/src/delete.ts +8 -16
  124. package/src/deployments.ts +340 -46
  125. package/src/deprecated/index.ts +8 -302
  126. package/src/dev/dev.tsx +66 -46
  127. package/src/dev/local.tsx +339 -104
  128. package/src/dev/remote.tsx +36 -3
  129. package/src/dev/start-server.ts +146 -101
  130. package/src/dev/use-esbuild.ts +82 -56
  131. package/src/dev/validate-dev-props.ts +9 -0
  132. package/src/{dev-registry.tsx → dev-registry.ts} +13 -1
  133. package/src/dev.tsx +202 -125
  134. package/src/dialogs.ts +136 -0
  135. package/src/dispatch-namespace.ts +21 -17
  136. package/src/docs/helpers.ts +50 -0
  137. package/src/docs/index.ts +54 -0
  138. package/src/entry.ts +26 -11
  139. package/src/environment-variables/factory.ts +89 -0
  140. package/src/environment-variables/misc-variables.ts +30 -0
  141. package/src/generate/index.ts +303 -0
  142. package/src/git-client.ts +15 -4
  143. package/src/{index.tsx → index.ts} +148 -63
  144. package/src/init.ts +301 -197
  145. package/src/inspect.ts +122 -6
  146. package/src/jest.d.ts +4 -0
  147. package/src/kv/helpers.ts +7 -4
  148. package/src/kv/index.ts +15 -17
  149. package/src/logger.ts +36 -5
  150. package/src/metrics/metrics-config.ts +3 -3
  151. package/src/metrics/send-event.ts +6 -1
  152. package/src/miniflare-cli/assets.ts +64 -28
  153. package/src/miniflare-cli/index.ts +6 -9
  154. package/src/miniflare-cli/tsconfig.json +9 -0
  155. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  156. package/src/miniflare-cli/types.ts +11 -0
  157. package/src/module-collection.ts +92 -26
  158. package/src/mtls-certificate/cli.ts +155 -0
  159. package/src/pages/build.ts +423 -0
  160. package/src/pages/buildFunctions.ts +140 -0
  161. package/src/pages/deployment-tails.ts +281 -0
  162. package/src/pages/deployments.tsx +11 -33
  163. package/src/pages/{dev.tsx → dev.ts} +192 -126
  164. package/src/pages/errors.ts +1 -0
  165. package/src/pages/functions/buildPlugin.ts +73 -69
  166. package/src/pages/functions/buildWorker.ts +342 -117
  167. package/src/pages/functions/tsconfig.json +8 -0
  168. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  169. package/src/pages/{functions.tsx → functions.ts} +8 -4
  170. package/src/pages/{index.tsx → index.ts} +11 -3
  171. package/src/pages/projects.tsx +12 -22
  172. package/src/pages/prompt-select-project.tsx +31 -0
  173. package/src/pages/publish.tsx +45 -214
  174. package/src/pages/types.ts +6 -9
  175. package/src/pages/upload.tsx +58 -14
  176. package/src/pages/utils.ts +14 -3
  177. package/src/parse.ts +23 -1
  178. package/src/paths.ts +1 -1
  179. package/src/proxy.ts +5 -0
  180. package/src/publish/index.ts +20 -16
  181. package/src/publish/publish.ts +81 -48
  182. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  183. package/src/queues/cli/commands/consumer/add.ts +24 -24
  184. package/src/queues/cli/commands/consumer/index.ts +3 -6
  185. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  186. package/src/queues/cli/commands/create.ts +8 -8
  187. package/src/queues/cli/commands/delete.ts +8 -8
  188. package/src/queues/cli/commands/index.ts +6 -4
  189. package/src/queues/cli/commands/list.ts +8 -8
  190. package/src/queues/client.ts +1 -0
  191. package/src/queues/utils.ts +18 -0
  192. package/src/r2/constants.ts +4 -0
  193. package/src/r2/helpers.ts +1 -0
  194. package/src/r2/index.ts +40 -28
  195. package/src/secret/index.ts +18 -17
  196. package/src/{sites.tsx → sites.ts} +165 -53
  197. package/src/tail/createTail.ts +103 -3
  198. package/src/tail/filters.ts +1 -1
  199. package/src/tail/index.ts +8 -11
  200. package/src/tail/printing.ts +27 -0
  201. package/src/traverse-module-graph.ts +54 -0
  202. package/src/tsconfig-sanity.ts +16 -0
  203. package/src/type-generation.ts +85 -57
  204. package/src/user/access.ts +0 -1
  205. package/src/user/auth-variables.ts +113 -0
  206. package/src/user/choose-account.tsx +1 -31
  207. package/src/user/index.ts +0 -1
  208. package/src/user/{user.tsx → user.ts} +124 -82
  209. package/src/utils/render.ts +93 -0
  210. package/src/{whoami.tsx → whoami.ts} +37 -71
  211. package/src/worker.ts +61 -3
  212. package/src/yargs-types.ts +22 -5
  213. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  214. package/templates/__tests__/tsconfig.json +8 -0
  215. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  216. package/templates/checked-fetch.js +9 -3
  217. package/templates/d1-beta-facade.js +95 -25
  218. package/templates/facade.d.ts +14 -0
  219. package/templates/first-party-worker-module-facade.ts +4 -3
  220. package/templates/format-dev-errors.ts +8 -6
  221. package/templates/gitignore +1 -0
  222. package/templates/init-tests/test-jest-new-worker.js +3 -5
  223. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  224. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  225. package/templates/middleware/loader-modules.ts +2 -2
  226. package/templates/middleware/loader-sw.ts +51 -31
  227. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  228. package/templates/new-worker.ts +3 -0
  229. package/templates/pages-dev-pipeline.ts +4 -1
  230. package/templates/pages-dev-util.ts +4 -1
  231. package/templates/pages-shim.ts +4 -1
  232. package/templates/pages-template-plugin.ts +19 -10
  233. package/templates/serve-static-assets.ts +17 -14
  234. package/templates/service-bindings-module-facade.js +1 -0
  235. package/templates/tsconfig-sanity.ts +11 -0
  236. package/templates/tsconfig.init.json +105 -0
  237. package/templates/tsconfig.json +5 -103
  238. package/templates/tsconfig.tsbuildinfo +1 -0
  239. package/wrangler-dist/cli.d.ts +902 -77
  240. package/wrangler-dist/cli.js +131685 -140615
  241. package/wrangler-dist/wasm-sync.wasm +0 -0
  242. package/src/__tests__/api-devregistry.test.js +0 -57
  243. package/src/__tests__/d1.test.ts +0 -72
  244. package/src/__tests__/dialogs.test.tsx +0 -40
  245. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  246. package/src/__tests__/pages.test.ts +0 -2223
  247. package/src/d1/types.tsx +0 -14
  248. package/src/dialogs.tsx +0 -163
  249. package/src/environment-variables.ts +0 -50
  250. package/src/pages/build.tsx +0 -238
  251. package/src/user/env-vars.ts +0 -46
  252. package/templates/experimental-local-cache-stubs.js +0 -27
  253. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  254. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  255. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { execSync, spawn } from "node:child_process";
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync, lstatSync, readFileSync } from "node:fs";
3
3
  import { homedir, tmpdir } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
5
  import { watch } from "chokidar";
@@ -10,23 +10,29 @@ import { FatalError } from "../errors";
10
10
  import { logger } from "../logger";
11
11
  import * as metrics from "../metrics";
12
12
  import { getBasePath } from "../paths";
13
- import { buildFunctions } from "./build";
13
+ import { buildFunctions } from "./buildFunctions";
14
14
  import { ROUTES_SPEC_VERSION, SECONDS_TO_WAIT_FOR_PROXY } from "./constants";
15
15
  import { FunctionsNoRoutesError, getFunctionsNoRoutesWarning } from "./errors";
16
+ import {
17
+ buildRawWorker,
18
+ checkRawWorker,
19
+ traverseAndBuildWorkerJSDirectory,
20
+ } from "./functions/buildWorker";
16
21
  import { validateRoutes } from "./functions/routes-validation";
17
22
  import { CLEANUP, CLEANUP_CALLBACKS, pagesBetaWarning } from "./utils";
18
23
  import type { AdditionalDevProps } from "../dev";
24
+ import type { CfModule } from "../worker";
25
+ import type {
26
+ CommonYargsArgv,
27
+ StrictYargsOptionsToInterface,
28
+ } from "../yargs-types";
19
29
  import type { RoutesJSONSpec } from "./functions/routes-transformation";
20
- import type { YargsOptionsToInterface } from "./types";
21
- import type { Argv } from "yargs";
22
30
 
23
31
  const DURABLE_OBJECTS_BINDING_REGEXP = new RegExp(
24
32
  /^(?<binding>[^=]+)=(?<className>[^@\s]+)(@(?<scriptName>.*)$)?$/
25
33
  );
26
34
 
27
- type PagesDevArgs = YargsOptionsToInterface<typeof Options>;
28
-
29
- export function Options(yargs: Argv) {
35
+ export function Options(yargs: CommonYargsArgv) {
30
36
  return yargs
31
37
  .positional("directory", {
32
38
  type: "string",
@@ -78,6 +84,16 @@ export function Options(yargs: Argv) {
78
84
  description:
79
85
  "The location of the single Worker script if not using functions",
80
86
  },
87
+ bundle: {
88
+ type: "boolean",
89
+ default: undefined,
90
+ hidden: true,
91
+ },
92
+ "no-bundle": {
93
+ type: "boolean",
94
+ default: false,
95
+ description: "Whether to run bundling on `_worker.js`",
96
+ },
81
97
  binding: {
82
98
  type: "array",
83
99
  description: "Bind variable/secret (KEY=VALUE)",
@@ -129,11 +145,16 @@ export function Options(yargs: Argv) {
129
145
  requiresArg: true,
130
146
  },
131
147
  "node-compat": {
132
- describe: "Enable node.js compatibility",
148
+ describe: "Enable Node.js compatibility",
133
149
  default: false,
134
150
  type: "boolean",
135
151
  hidden: true,
136
152
  },
153
+ "experimental-local": {
154
+ describe: "Run on my machine using the Cloudflare Workers runtime",
155
+ type: "boolean",
156
+ default: false,
157
+ },
137
158
  config: {
138
159
  describe: "Pages does not support wrangler.toml",
139
160
  type: "string",
@@ -150,35 +171,36 @@ export function Options(yargs: Argv) {
150
171
  export const Handler = async ({
151
172
  local,
152
173
  directory,
153
- "compatibility-date": compatibilityDate,
154
- "compatibility-flags": compatibilityFlags,
174
+ compatibilityDate,
175
+ compatibilityFlags,
155
176
  ip,
156
177
  port,
157
- "inspector-port": inspectorPort,
178
+ inspectorPort,
158
179
  proxy: requestedProxyPort,
159
- "script-path": singleWorkerScriptPath,
180
+ bundle,
181
+ noBundle,
182
+ scriptPath: singleWorkerScriptPath,
160
183
  binding: bindings = [],
161
184
  kv: kvs = [],
162
185
  do: durableObjects = [],
163
186
  d1: d1s = [],
164
187
  r2: r2s = [],
165
- "live-reload": liveReload,
166
- "local-protocol": localProtocol,
188
+ liveReload,
189
+ localProtocol,
167
190
  experimentalEnableLocalPersistence,
168
191
  persist,
169
192
  persistTo,
170
- "node-compat": nodeCompat,
193
+ nodeCompat: legacyNodeCompat,
194
+ experimentalLocal,
171
195
  config: config,
172
196
  _: [_pages, _dev, ...remaining],
173
197
  logLevel,
174
- }: PagesDevArgs) => {
198
+ }: StrictYargsOptionsToInterface<typeof Options>) => {
175
199
  // Beta message for `wrangler pages <commands>` usage
176
200
  logger.log(pagesBetaWarning);
177
201
 
178
- type LogLevelArg = "debug" | "info" | "log" | "warn" | "error" | "none";
179
202
  if (logLevel) {
180
- // The YargsOptionsToInterface doesn't handle the passing in of Unions from choices in Yargs
181
- logger.loggerLevel = logLevel as LogLevelArg;
203
+ logger.loggerLevel = logLevel;
182
204
  }
183
205
 
184
206
  if (!local) {
@@ -238,31 +260,73 @@ export const Handler = async ({
238
260
  directory !== undefined
239
261
  ? join(directory, singleWorkerScriptPath)
240
262
  : singleWorkerScriptPath;
263
+ const usingWorkerDirectory =
264
+ existsSync(workerScriptPath) && lstatSync(workerScriptPath).isDirectory();
241
265
  const usingWorkerScript = existsSync(workerScriptPath);
266
+ // TODO: Here lies a known bug. If you specify both `--bundle` and `--no-bundle`, this behavior is undefined and you will get unexpected results.
267
+ // There is no sane way to get the true value out of yargs, so here we are.
268
+ const enableBundling = bundle ?? !noBundle;
242
269
 
243
270
  const functionsDirectory = "./functions";
244
271
  let usingFunctions = !usingWorkerScript && existsSync(functionsDirectory);
245
272
 
246
273
  let scriptPath = "";
247
274
 
248
- if (usingWorkerScript) {
249
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
250
- scriptReadyResolve!();
251
-
252
- scriptPath = workerScriptPath;
275
+ const nodejsCompat = compatibilityFlags?.includes("nodejs_compat");
276
+ let modules: CfModule[] = [];
253
277
 
278
+ if (usingWorkerDirectory) {
254
279
  const runBuild = async () => {
255
- try {
256
- await esbuild.build({
257
- entryPoints: [scriptPath],
258
- write: false,
259
- plugins: [blockWorkerJsImports],
260
- });
261
- } catch {}
280
+ const bundleResult = await traverseAndBuildWorkerJSDirectory({
281
+ workerJSDirectory: workerScriptPath,
282
+ buildOutputDirectory: directory ?? ".",
283
+ nodejsCompat,
284
+ });
285
+ modules = bundleResult.modules;
286
+ scriptPath = bundleResult.resolvedEntryPointPath;
262
287
  };
263
288
 
289
+ await runBuild().then(() => scriptReadyResolve());
290
+
291
+ watch([workerScriptPath], {
292
+ persistent: true,
293
+ ignoreInitial: true,
294
+ }).on("all", async () => {
295
+ await runBuild();
296
+ });
297
+ } else if (usingWorkerScript) {
298
+ scriptPath = workerScriptPath;
299
+ let runBuild = async () => {
300
+ await checkRawWorker(workerScriptPath, () => scriptReadyResolve());
301
+ };
302
+
303
+ if (enableBundling) {
304
+ // We want to actually run the `_worker.js` script through the bundler
305
+ // So update the final path to the script that will be uploaded and
306
+ // change the `runBuild()` function to bundle the `_worker.js`.
307
+ scriptPath = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`);
308
+ runBuild = async () => {
309
+ try {
310
+ await buildRawWorker({
311
+ workerScriptPath: usingWorkerDirectory
312
+ ? join(workerScriptPath, "index.js")
313
+ : workerScriptPath,
314
+ outfile: scriptPath,
315
+ directory: directory ?? ".",
316
+ nodejsCompat,
317
+ local: true,
318
+ sourcemap: true,
319
+ watch: true,
320
+ onEnd: () => scriptReadyResolve(),
321
+ });
322
+ } catch (e: unknown) {
323
+ logger.warn("Failed to bundle _worker.js.", e);
324
+ }
325
+ };
326
+ }
327
+
264
328
  await runBuild();
265
- watch([scriptPath], {
329
+ watch([workerScriptPath], {
266
330
  persistent: true,
267
331
  ignoreInitial: true,
268
332
  }).on("all", async () => {
@@ -270,45 +334,47 @@ export const Handler = async ({
270
334
  });
271
335
  } else if (usingFunctions) {
272
336
  // Try to use Functions
273
- const outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`);
274
- scriptPath = outfile;
337
+ scriptPath = join(tmpdir(), `./functionsWorker-${Math.random()}.mjs`);
275
338
 
276
- if (nodeCompat) {
339
+ if (legacyNodeCompat) {
277
340
  console.warn(
278
- "Enabling node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
341
+ "Enabling Node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
279
342
  );
280
343
  }
281
344
 
282
- logger.log(`Compiling worker to "${outfile}"...`);
345
+ if (legacyNodeCompat && nodejsCompat) {
346
+ throw new FatalError(
347
+ "The `nodejs_compat` compatibility flag cannot be used in conjunction with the legacy `--node-compat` flag. If you want to use the Workers runtime Node.js compatibility features, please remove the `--node-compat` argument from your CLI command or `node_compat = true` from your config file.",
348
+ 1
349
+ );
350
+ }
351
+
352
+ logger.log(`Compiling worker to "${scriptPath}"...`);
283
353
  const onEnd = () => scriptReadyResolve();
284
354
  try {
285
- await buildFunctions({
286
- outfile,
287
- functionsDirectory,
288
- sourcemap: true,
289
- watch: true,
290
- onEnd,
291
- buildOutputDirectory: directory,
292
- nodeCompat,
293
- });
294
- await metrics.sendMetricsEvent("build pages functions");
355
+ const buildFn = async () => {
356
+ await buildFunctions({
357
+ outfile: scriptPath,
358
+ functionsDirectory,
359
+ sourcemap: true,
360
+ watch: true,
361
+ onEnd,
362
+ buildOutputDirectory: directory,
363
+ legacyNodeCompat,
364
+ nodejsCompat,
365
+ local: true,
366
+ });
367
+ await metrics.sendMetricsEvent("build pages functions");
368
+ };
295
369
 
370
+ await buildFn();
296
371
  // If Functions found routes, continue using Functions
297
372
  watch([functionsDirectory], {
298
373
  persistent: true,
299
374
  ignoreInitial: true,
300
375
  }).on("all", async () => {
301
376
  try {
302
- await buildFunctions({
303
- outfile,
304
- functionsDirectory,
305
- sourcemap: true,
306
- watch: true,
307
- onEnd,
308
- buildOutputDirectory: directory,
309
- nodeCompat,
310
- });
311
- await metrics.sendMetricsEvent("build pages functions");
377
+ await buildFn();
312
378
  } catch (e) {
313
379
  if (e instanceof FunctionsNoRoutesError) {
314
380
  logger.warn(
@@ -349,7 +415,7 @@ export const Handler = async ({
349
415
 
350
416
  if (scriptPath === "") {
351
417
  // Failed to get a script with or without Functions,
352
- // something really bad must have happend.
418
+ // something really bad must have happened.
353
419
  throw new FatalError(
354
420
  "Failed to start wrangler pages dev due to an unknown error",
355
421
  1
@@ -359,7 +425,10 @@ export const Handler = async ({
359
425
  let entrypoint = scriptPath;
360
426
 
361
427
  // custom _routes.json apply only to Functions or Advanced Mode Pages projects
362
- if (directory && (usingFunctions || usingWorkerScript)) {
428
+ if (
429
+ directory &&
430
+ (usingFunctions || usingWorkerScript || usingWorkerDirectory)
431
+ ) {
363
432
  const routesJSONPath = join(directory, "_routes.json");
364
433
 
365
434
  if (existsSync(routesJSONPath)) {
@@ -431,7 +500,7 @@ export const Handler = async ({
431
500
  * If _routes.json is invalid, don't exit but instead fallback to a sensible default
432
501
  * and continue to serve the assets. At the same time make sure we warn users that we
433
502
  * we detected an invalid file and that we'll be using a default.
434
- * This basically equivalates to serving a Functions or _worker.js project as is,
503
+ * This basically equates to serving a Functions or _worker.js project as is,
435
504
  * without applying any additional routing rules on top.
436
505
  */
437
506
  const error =
@@ -460,77 +529,86 @@ export const Handler = async ({
460
529
  }
461
530
  }
462
531
 
463
- const { stop, waitUntilExit } = await unstable_dev(
464
- entrypoint,
465
- {
466
- ip,
467
- port,
468
- inspectorPort,
469
- watch: true,
470
- localProtocol,
471
- liveReload,
472
- compatibilityDate,
473
- compatibilityFlags,
474
- nodeCompat,
475
- vars: Object.fromEntries(
476
- bindings
477
- .map((binding) => binding.toString().split("="))
478
- .map(([key, ...values]) => [key, values.join("=")])
479
- ),
480
- kv: kvs.map((val) => ({
481
- binding: val.toString(),
482
- id: "",
483
- })),
484
- durableObjects: durableObjects
485
- .map((durableObject) => {
486
- const { binding, className, scriptName } =
487
- DURABLE_OBJECTS_BINDING_REGEXP.exec(durableObject.toString())
488
- ?.groups || {};
489
-
490
- if (!binding || !className) {
491
- logger.warn(
492
- "Could not parse Durable Object binding:",
493
- durableObject.toString()
494
- );
495
- return;
496
- }
497
-
498
- return {
499
- name: binding,
500
- class_name: className,
501
- script_name: scriptName,
502
- };
503
- })
504
- .filter(Boolean) as AdditionalDevProps["durableObjects"],
505
- r2: r2s.map((binding) => {
506
- return { binding: binding.toString(), bucket_name: "" };
507
- }),
532
+ const { stop, waitUntilExit } = await unstable_dev(entrypoint, {
533
+ ip,
534
+ port,
535
+ inspectorPort,
536
+ localProtocol,
537
+ compatibilityDate,
538
+ compatibilityFlags,
539
+ nodeCompat: legacyNodeCompat,
540
+ vars: Object.fromEntries(
541
+ bindings
542
+ .map((binding) => binding.toString().split("="))
543
+ .map(([key, ...values]) => [key, values.join("=")])
544
+ ),
545
+ kv: kvs.map((binding) => ({
546
+ binding: binding.toString(),
547
+ id: "",
548
+ })),
549
+ durableObjects: durableObjects
550
+ .map((durableObject) => {
551
+ const { binding, className, scriptName } =
552
+ DURABLE_OBJECTS_BINDING_REGEXP.exec(durableObject.toString())
553
+ ?.groups || {};
554
+
555
+ if (!binding || !className) {
556
+ logger.warn(
557
+ "Could not parse Durable Object binding:",
558
+ durableObject.toString()
559
+ );
560
+ return;
561
+ }
508
562
 
563
+ return {
564
+ name: binding,
565
+ class_name: className,
566
+ script_name: scriptName,
567
+ };
568
+ })
569
+ .filter(Boolean) as AdditionalDevProps["durableObjects"],
570
+ r2: r2s.map((binding) => {
571
+ return { binding: binding.toString(), bucket_name: "" };
572
+ }),
573
+ rules: usingWorkerDirectory
574
+ ? [
575
+ {
576
+ type: "ESModule",
577
+ globs: ["**/*.js"],
578
+ },
579
+ ]
580
+ : undefined,
581
+ bundle: enableBundling,
582
+ persist,
583
+ persistTo,
584
+ inspect: undefined,
585
+ logLevel,
586
+ experimental: {
587
+ processEntrypoint: true,
588
+ additionalModules: modules,
509
589
  d1Databases: d1s.map((binding) => ({
510
590
  binding: binding.toString(),
511
591
  database_id: "", // Required for types, but unused by dev
512
592
  database_name: `local-${binding}`,
513
593
  })),
514
-
594
+ disableExperimentalWarning: true,
515
595
  enablePagesAssetsServiceBinding: {
516
596
  proxyPort,
517
597
  directory,
518
598
  },
599
+ experimentalLocal,
600
+ liveReload,
519
601
  forceLocal: true,
520
- persist,
521
- persistTo,
522
602
  showInteractiveDevSession: undefined,
523
- inspect: true,
524
- logPrefix: "pages",
525
- logLevel: logLevel ?? "warn",
603
+ testMode: false,
604
+ watch: true,
526
605
  },
527
- { testMode: false, disableExperimentalWarning: true }
528
- );
606
+ });
529
607
  await metrics.sendMetricsEvent("run pages dev");
530
608
 
531
609
  CLEANUP_CALLBACKS.push(stop);
532
610
 
533
- waitUntilExit().then(() => {
611
+ void waitUntilExit().then(() => {
534
612
  CLEANUP();
535
613
  process.exit(0);
536
614
  });
@@ -679,15 +757,3 @@ async function spawnProxyProcess({
679
757
 
680
758
  return port;
681
759
  }
682
-
683
- const blockWorkerJsImports: esbuild.Plugin = {
684
- name: "block-worker-js-imports",
685
- setup(build: esbuild.PluginBuild) {
686
- build.onResolve({ filter: /.*/g }, (_args) => {
687
- logger.error(
688
- `_worker.js is importing from another file. This will throw an error if deployed.\nYou should bundle your Worker or remove the import if it is unused.`
689
- );
690
- return null;
691
- });
692
- },
693
- };
@@ -9,6 +9,7 @@ import { RoutesValidationError } from "./functions/routes-validation";
9
9
  * Exit code for `pages functions build` when no routes are found.
10
10
  */
11
11
  export const EXIT_CODE_FUNCTIONS_NO_ROUTES_ERROR = 156;
12
+ export const EXIT_CODE_FUNCTIONS_NOTHING_TO_BUILD_ERROR = 157;
12
13
 
13
14
  /**
14
15
  * Pages error when no routes are found in the functions directory
@@ -1,72 +1,57 @@
1
1
  import { access, lstat } from "node:fs/promises";
2
- import { dirname, relative, resolve } from "node:path";
3
- import NodeGlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
4
- import NodeModulesPolyfills from "@esbuild-plugins/node-modules-polyfill";
5
- import { build } from "esbuild";
2
+ import { relative, resolve } from "node:path";
3
+ import { bundleWorker } from "../../bundle";
6
4
  import { getBasePath } from "../../paths";
5
+ import { D1_BETA_PREFIX } from "../../worker";
6
+ import { buildNotifierPlugin } from "./buildWorker";
7
+ import type { Options as WorkerOptions } from "./buildWorker";
7
8
 
8
- type Options = {
9
- routesModule: string;
10
- outfile: string;
11
- minify?: boolean;
12
- sourcemap?: boolean;
13
- watch?: boolean;
14
- nodeCompat?: boolean;
15
- onEnd?: () => void;
16
- };
9
+ type Options = Omit<
10
+ WorkerOptions,
11
+ "outfile" | "fallbackService" | "buildOutputDirectory" | "nodejsCompat"
12
+ > & { outdir: string };
17
13
 
18
14
  export function buildPlugin({
19
15
  routesModule,
20
- outfile = "bundle.js",
16
+ outdir,
21
17
  minify = false,
22
18
  sourcemap = false,
23
19
  watch = false,
24
- nodeCompat,
25
20
  onEnd = () => {},
21
+ legacyNodeCompat,
22
+ functionsDirectory,
23
+ local,
24
+ betaD1Shims,
26
25
  }: Options) {
27
- return build({
28
- entryPoints: [resolve(getBasePath(), "templates/pages-template-plugin.ts")],
29
- inject: [routesModule],
30
- bundle: true,
31
- format: "esm",
32
- target: "esnext",
33
- loader: {
34
- ".html": "text",
35
- ".txt": "text",
26
+ return bundleWorker(
27
+ {
28
+ file: resolve(getBasePath(), "templates/pages-template-plugin.ts"),
29
+ directory: functionsDirectory,
30
+ format: "modules",
31
+ moduleRoot: functionsDirectory,
36
32
  },
37
- outfile,
38
- minify,
39
- sourcemap,
40
- watch,
41
- allowOverwrite: true,
42
- define: { ...(nodeCompat ? { global: "globalThis" } : {}) },
43
- plugins: [
44
- {
45
- name: "wrangler notifier and monitor",
46
- setup(pluginBuild) {
47
- pluginBuild.onEnd((result) => {
48
- if (result.errors.length > 0) {
49
- console.error(
50
- `${result.errors.length} error(s) and ${result.warnings.length} warning(s) when compiling Worker.`
51
- );
52
- } else if (result.warnings.length > 0) {
53
- console.warn(
54
- `${result.warnings.length} warning(s) when compiling Worker.`
55
- );
56
- onEnd();
57
- } else {
58
- console.log("Compiled Worker successfully.");
59
- onEnd();
60
- }
61
- });
62
- },
63
- },
64
- {
65
- name: "Assets",
66
- setup(pluginBuild) {
67
- if (pluginBuild.initialOptions.outfile) {
68
- const outdir = dirname(pluginBuild.initialOptions.outfile);
69
-
33
+ resolve(outdir),
34
+ {
35
+ inject: [routesModule],
36
+ entryName: "index",
37
+ minify,
38
+ sourcemap,
39
+ watch,
40
+ legacyNodeCompat,
41
+ // We don't currently have a mechanism for Plugins 'requiring' a specific compat date/flag,
42
+ // but if someone wants to publish a Plugin which does require this new `nodejs_compat` flag
43
+ // and they document that on their README.md, we should let them.
44
+ nodejsCompat: true,
45
+ define: {},
46
+ betaD1Shims: (betaD1Shims || []).map(
47
+ (binding) => `${D1_BETA_PREFIX}${binding}`
48
+ ),
49
+ doBindings: [], // Pages functions don't support internal Durable Objects
50
+ plugins: [
51
+ buildNotifierPlugin(onEnd),
52
+ {
53
+ name: "Assets",
54
+ setup(pluginBuild) {
70
55
  pluginBuild.onResolve({ filter: /^assets:/ }, async (args) => {
71
56
  const directory = resolve(
72
57
  args.resolveDir,
@@ -94,17 +79,36 @@ export function buildPlugin({
94
79
 
95
80
  return { path, external: true, namespace: "assets" };
96
81
  });
97
- }
82
+ },
83
+ },
84
+ // TODO: Replace this with a proper outdir solution for Plugins
85
+ // But for now, let's just mark all wasm/bin files as external
86
+ {
87
+ name: "Mark externals",
88
+ setup(pluginBuild) {
89
+ pluginBuild.onResolve(
90
+ { filter: /.*\.(wasm|bin)$/ },
91
+ async (args) => {
92
+ return {
93
+ external: true,
94
+ path: `./${relative(
95
+ outdir,
96
+ resolve(args.resolveDir, args.path)
97
+ )}`,
98
+ };
99
+ }
100
+ );
101
+ },
98
102
  },
99
- },
100
- ...(nodeCompat
101
- ? [
102
- NodeGlobalsPolyfills({
103
- buffer: true,
104
- }),
105
- NodeModulesPolyfills(),
106
- ]
107
- : []),
108
- ],
109
- });
103
+ ],
104
+ serveAssetsFromWorker: false,
105
+ disableModuleCollection: false,
106
+ rules: [],
107
+ checkFetch: local,
108
+ targetConsumer: local ? "dev" : "publish",
109
+ local,
110
+ experimentalLocal: false,
111
+ forPages: true,
112
+ }
113
+ );
110
114
  }