wrangler 2.7.1 → 2.8.1

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 (63) hide show
  1. package/package.json +1 -1
  2. package/src/__tests__/d1/d1.test.ts +12 -8
  3. package/src/__tests__/deployments.test.ts +4 -4
  4. package/src/__tests__/helpers/mock-dialogs.ts +2 -0
  5. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  6. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  7. package/src/__tests__/helpers/mock-kv.ts +29 -16
  8. package/src/__tests__/helpers/mock-oauth-flow.ts +90 -98
  9. package/src/__tests__/helpers/msw/handlers/deployments.ts +20 -10
  10. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  11. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  12. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  13. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  14. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  15. package/src/__tests__/helpers/msw/index.ts +30 -1
  16. package/src/__tests__/init.test.ts +3 -14
  17. package/src/__tests__/jest.setup.ts +0 -23
  18. package/src/__tests__/pages-deployment-tail.test.ts +72 -1
  19. package/src/__tests__/pages.test.ts +52 -53
  20. package/src/__tests__/publish.test.ts +870 -522
  21. package/src/__tests__/r2.test.ts +11 -35
  22. package/src/__tests__/secret.test.ts +1 -9
  23. package/src/__tests__/tail.test.ts +72 -19
  24. package/src/__tests__/tsconfig.tsbuildinfo +1 -1
  25. package/src/__tests__/user.test.ts +5 -16
  26. package/src/__tests__/whoami.test.tsx +6 -17
  27. package/src/__tests__/worker-namespace.test.ts +56 -48
  28. package/src/api/index.ts +1 -0
  29. package/src/api/pages/index.ts +5 -0
  30. package/src/api/pages/publish.tsx +321 -0
  31. package/src/bundle.ts +62 -10
  32. package/src/cfetch/internal.ts +0 -3
  33. package/src/cli.ts +2 -2
  34. package/src/config/environment.ts +12 -10
  35. package/src/d1/backups.tsx +1 -5
  36. package/src/d1/utils.ts +1 -1
  37. package/src/deployments.ts +16 -6
  38. package/src/dev/local.tsx +1 -10
  39. package/src/dev/remote.tsx +2 -0
  40. package/src/dev/start-server.ts +5 -10
  41. package/src/dev/use-esbuild.ts +1 -0
  42. package/src/docs/index.ts +2 -1
  43. package/src/entry.ts +1 -2
  44. package/src/index.ts +1 -1
  45. package/src/init.ts +1 -1
  46. package/src/metrics/send-event.ts +2 -1
  47. package/src/pages/build.ts +4 -124
  48. package/src/pages/buildFunctions.ts +129 -0
  49. package/src/pages/dev.ts +68 -63
  50. package/src/pages/functions/buildPlugin.ts +3 -20
  51. package/src/pages/functions/buildWorker.ts +143 -21
  52. package/src/pages/functions/tsconfig.tsbuildinfo +1 -1
  53. package/src/pages/publish.tsx +21 -220
  54. package/src/publish/publish.ts +30 -4
  55. package/src/tail/createTail.ts +28 -1
  56. package/src/tail/printing.ts +15 -0
  57. package/templates/checked-fetch.js +1 -3
  58. package/templates/d1-beta-facade.js +1 -1
  59. package/templates/middleware/loader-modules.ts +2 -0
  60. package/templates/tsconfig.tsbuildinfo +1 -1
  61. package/wrangler-dist/cli.d.ts +132 -10
  62. package/wrangler-dist/cli.js +3532 -3330
  63. package/src/__tests__/helpers/mock-cfetch.ts +0 -278
package/src/bundle.ts CHANGED
@@ -9,10 +9,10 @@ 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
16
  export type BundleResult = {
17
17
  modules: CfModule[];
18
18
  dependencies: esbuild.Metafile["outputs"][string]["inputs"];
@@ -95,6 +95,7 @@ export async function bundleWorker(
95
95
  serveAssetsFromWorker: boolean;
96
96
  assets?: StaticAssetsConfig;
97
97
  betaD1Shims?: string[];
98
+ doBindings: DurableObjectBindings;
98
99
  jsxFactory?: string;
99
100
  jsxFragment?: string;
100
101
  rules: Config["rules"];
@@ -123,6 +124,7 @@ export async function bundleWorker(
123
124
  const {
124
125
  serveAssetsFromWorker,
125
126
  betaD1Shims,
127
+ doBindings,
126
128
  jsxFactory,
127
129
  jsxFragment,
128
130
  rules,
@@ -271,7 +273,13 @@ export async function bundleWorker(
271
273
  Array.isArray(betaD1Shims) &&
272
274
  betaD1Shims.length > 0 &&
273
275
  ((currentEntry: Entry) => {
274
- return applyD1BetaFacade(currentEntry, tmpDir.path, betaD1Shims, local);
276
+ return applyD1BetaFacade(
277
+ currentEntry,
278
+ tmpDir.path,
279
+ betaD1Shims,
280
+ local,
281
+ doBindings
282
+ );
275
283
  }),
276
284
 
277
285
  // Middleware loader: to add middleware, we add the path to the middleware
@@ -395,13 +403,23 @@ export async function bundleWorker(
395
403
  _path.includes(".map")
396
404
  )[0];
397
405
 
406
+ const resolvedEntryPointPath = path.resolve(
407
+ entry.directory,
408
+ entryPointOutputs[0][0]
409
+ );
410
+
411
+ // copy all referenced modules into the output bundle directory
412
+ for (const module of moduleCollector.modules) {
413
+ fs.writeFileSync(
414
+ path.join(path.dirname(resolvedEntryPointPath), module.name),
415
+ module.content
416
+ );
417
+ }
418
+
398
419
  return {
399
420
  modules: moduleCollector.modules,
400
421
  dependencies,
401
- resolvedEntryPointPath: path.resolve(
402
- entry.directory,
403
- entryPointOutputs[0][0]
404
- ),
422
+ resolvedEntryPointPath,
405
423
  bundleType,
406
424
  stop: result.stop,
407
425
  sourceMapPath,
@@ -779,17 +797,51 @@ async function applyFirstPartyWorkerDevFacade(
779
797
  * This code be removed from here when the API is in Workers core,
780
798
  * but moved inside Miniflare for simulating D1.
781
799
  */
782
-
783
800
  async function applyD1BetaFacade(
784
801
  entry: Entry,
785
802
  tmpDirPath: string,
786
803
  betaD1Shims: string[],
787
- local: boolean
804
+ local: boolean,
805
+ doBindings: DurableObjectBindings
788
806
  ): Promise<Entry> {
807
+ let entrypointPath = path.resolve(
808
+ getBasePath(),
809
+ "templates/d1-beta-facade.js"
810
+ );
811
+ if (Array.isArray(doBindings) && doBindings.length > 0) {
812
+ //we have DO bindings, so we need to shim them
813
+ const maskedDoBindings = doBindings
814
+ // Don't shim anything not local to this worker
815
+ .filter((b) => !b.script_name)
816
+ // Reexport the DO classnames
817
+ .map(
818
+ (b) =>
819
+ `export const ${b.class_name} = maskDurableObjectDefinition(OTHER_EXPORTS.${b.class_name});`
820
+ )
821
+ .join("\n");
822
+ const baseFile = fs.readFileSync(
823
+ path.resolve(getBasePath(), "templates/d1-beta-facade.js"),
824
+ "utf8"
825
+ );
826
+ //getMaskedEnv is already used to shim regular Workers
827
+ const contents = `
828
+ ${baseFile}
829
+
830
+ var maskDurableObjectDefinition = (cls) =>
831
+ class extends cls {
832
+ constructor(state, env) {
833
+ super(state, getMaskedEnv(env));
834
+ }
835
+ };
836
+ ${maskedDoBindings}`;
837
+ const doD1FacadePath = path.join(tmpDirPath, "d1-do-facade.js");
838
+ //write our shim so we can build it
839
+ fs.writeFileSync(doD1FacadePath, contents);
840
+ entrypointPath = doD1FacadePath;
841
+ }
789
842
  const targetPath = path.join(tmpDirPath, "d1-beta-facade.entry.js");
790
-
791
843
  await esbuild.build({
792
- entryPoints: [path.resolve(getBasePath(), "templates/d1-beta-facade.js")],
844
+ entryPoints: [entrypointPath],
793
845
  bundle: true,
794
846
  format: "esm",
795
847
  sourcemap: true,
@@ -252,9 +252,6 @@ export async function fetchDashboardScript(
252
252
  }
253
253
 
254
254
  return file ?? "";
255
-
256
- // Follow up on issue in Undici about multipart/form-data support & replace the workaround: https://github.com/nodejs/undici/issues/974
257
- // This should be using a builtin formData() parser pattern.
258
255
  } else {
259
256
  return response.text();
260
257
  }
package/src/cli.ts CHANGED
@@ -1,6 +1,6 @@
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
 
@@ -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 };
27
+ export { unstable_dev, unstable_pages };
28
28
  export type { UnstableDevWorker, UnstableDevOptions };
@@ -261,6 +261,17 @@ interface EnvironmentInheritable {
261
261
  logpush: boolean | undefined;
262
262
  }
263
263
 
264
+ export type DurableObjectBindings = {
265
+ /** The name of the binding used to refer to the Durable Object */
266
+ name: string;
267
+ /** The exported class name of the Durable Object */
268
+ class_name: string;
269
+ /** The script where the Durable Object is defined (if it's external to this worker) */
270
+ script_name?: string;
271
+ /** The service environment of the script_name to bind to */
272
+ environment?: string;
273
+ }[];
274
+
264
275
  /**
265
276
  * The `EnvironmentNonInheritable` interface declares all the configuration fields for an environment
266
277
  * that cannot be inherited from the top-level environment, and must be defined specifically.
@@ -303,16 +314,7 @@ interface EnvironmentNonInheritable {
303
314
  * @nonInheritable
304
315
  */
305
316
  durable_objects: {
306
- bindings: {
307
- /** The name of the binding used to refer to the Durable Object */
308
- name: string;
309
- /** The exported class name of the Durable Object */
310
- class_name: string;
311
- /** The script where the Durable Object is defined (if it's external to this worker) */
312
- script_name?: string;
313
- /** The service environment of the script_name to bind to */
314
- environment?: string;
315
- }[];
317
+ bindings: DurableObjectBindings;
316
318
  };
317
319
 
318
320
  /**
@@ -191,11 +191,7 @@ export const DownloadHandler = withConfig<BackupDownloadArgs>(
191
191
  name
192
192
  );
193
193
  const filename =
194
- output ||
195
- path.join(
196
- process.env.INIT_CWD as string,
197
- `${name}.${backupId.slice(0, 8)}.sqlite3`
198
- );
194
+ output || path.resolve(`${name}.${backupId.slice(0, 8)}.sqlite3`);
199
195
 
200
196
  logger.log(`🌀 Downloading backup ${backupId} from '${name}'`);
201
197
  const response = await getBackupResponse(accountId, db.uuid, backupId);
package/src/d1/utils.ts CHANGED
@@ -45,4 +45,4 @@ export const getDatabaseByNameOrBinding = async (
45
45
 
46
46
  export const d1BetaWarning = process.env.NO_D1_WARNING
47
47
  ? ""
48
- : "🚧 D1 is currently in open alpha and is not recommended for production data and traffic.\nPlease report any bugs to https://github.com/cloudflare/wrangler2/issues/new/choose.\nTo request features, visit https://community.cloudflare.com/c/developers/d1.\nTo give feedback, visit https://discord.gg/cloudflaredev";
48
+ : "--------------------\n🚧 D1 is currently in open alpha and is not recommended for production data and traffic\n🚧 Please report any bugs to https://github.com/cloudflare/wrangler2/issues/new/choose\n🚧 To request features, visit https://community.cloudflare.com/c/developers/d1\n🚧 To give feedback, visit https://discord.gg/cloudflaredev\n--------------------\n";
@@ -1,6 +1,8 @@
1
1
  import { URLSearchParams } from "url";
2
2
  import { fetchResult } from "./cfetch";
3
3
  import { logger } from "./logger";
4
+ import * as metrics from "./metrics";
5
+ import type { Config } from "./config";
4
6
  import type { ServiceMetadataRes } from "./init";
5
7
 
6
8
  export type DeploymentListRes = {
@@ -34,7 +36,8 @@ export type DeploymentListRes = {
34
36
 
35
37
  export async function deployments(
36
38
  accountId: string,
37
- scriptName: string | undefined
39
+ scriptName: string | undefined,
40
+ { send_metrics: sendMetrics }: { send_metrics?: Config["send_metrics"] } = {}
38
41
  ) {
39
42
  if (!scriptName) {
40
43
  throw new Error(
@@ -42,6 +45,14 @@ export async function deployments(
42
45
  );
43
46
  }
44
47
 
48
+ await metrics.sendMetricsEvent(
49
+ "view deployments",
50
+ { view: scriptName ? "single" : "all" },
51
+ {
52
+ sendMetrics,
53
+ }
54
+ );
55
+
45
56
  const scriptMetadata = await fetchResult<ServiceMetadataRes>(
46
57
  `/accounts/${accountId}/workers/services/${scriptName}`
47
58
  );
@@ -66,17 +77,16 @@ Source: ${sourceStr(versions.metadata.source)}\n`
66
77
  logger.log(...versionMessages);
67
78
  }
68
79
 
69
- // TODO Include emoji/icon for each source
70
80
  function sourceStr(source: string): string {
71
81
  switch (source) {
72
82
  case "api":
73
- return "API";
83
+ return "📡 API";
74
84
  case "dash":
75
- return "Dashboard";
85
+ return "🖥️ Dashboard";
76
86
  case "wrangler":
77
- return "Wrangler";
87
+ return "🤠 Wrangler";
78
88
  case "terraform":
79
- return "Terraform";
89
+ return "🏗️ Terraform";
80
90
  default:
81
91
  return "Other";
82
92
  }
package/src/dev/local.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import { fork } from "node:child_process";
3
3
  import { realpathSync } from "node:fs";
4
- import { readFile, writeFile } from "node:fs/promises";
4
+ import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import chalk from "chalk";
7
7
  import getPort from "get-port";
@@ -165,15 +165,6 @@ function useLocalWorker({
165
165
  async function startLocalWorker() {
166
166
  if (!bundle || !format) return;
167
167
 
168
- // In local mode, we want to copy all referenced modules into
169
- // the output bundle directory before starting up
170
- for (const module of bundle.modules) {
171
- await writeFile(
172
- path.join(path.dirname(bundle.path), module.name),
173
- module.content
174
- );
175
- }
176
-
177
168
  const scriptPath = realpathSync(bundle.path);
178
169
 
179
170
  const upstream =
@@ -12,6 +12,7 @@ import {
12
12
  import useInspector from "../inspect";
13
13
  import { logger } from "../logger";
14
14
  import { startPreviewServer, usePreviewServer } from "../proxy";
15
+ import { helpIfErrorIsSizeOrScriptStartup } from "../publish/publish";
15
16
  import { syncAssets } from "../sites";
16
17
  import {
17
18
  getAccountChoices,
@@ -494,6 +495,7 @@ export async function getRemotePreviewToken(props: RemoteProps) {
494
495
  // code 10049 happens when the preview token expires
495
496
  logger.log("Preview token expired, restart server to fetch a new one");
496
497
  } else {
498
+ helpIfErrorIsSizeOrScriptStartup(err, props.bundle?.dependencies || {});
497
499
  logger.error("Error on remote worker:", err);
498
500
  }
499
501
  }
@@ -1,6 +1,5 @@
1
1
  import { fork } from "node:child_process";
2
2
  import { realpathSync } from "node:fs";
3
- import { writeFile } from "node:fs/promises";
4
3
  import * as path from "node:path";
5
4
  import * as util from "node:util";
6
5
  import onExit from "signal-exit";
@@ -27,6 +26,7 @@ import { startRemoteServer } from "./remote";
27
26
  import { validateDevProps } from "./validate-dev-props";
28
27
 
29
28
  import type { Config } from "../config";
29
+ import type { DurableObjectBindings } from "../config/environment";
30
30
  import type { WorkerRegistry } from "../dev-registry";
31
31
  import type { Entry } from "../entry";
32
32
  import type { DevProps, DirectorySyncResult } from "./dev";
@@ -109,6 +109,7 @@ export async function startDevServer(
109
109
  testScheduled: props.testScheduled,
110
110
  local: props.local,
111
111
  experimentalLocal: props.experimentalLocal,
112
+ doBindings: props.bindings.durable_objects?.bindings ?? [],
112
113
  });
113
114
 
114
115
  if (props.local) {
@@ -218,6 +219,7 @@ async function runEsbuild({
218
219
  testScheduled,
219
220
  local,
220
221
  experimentalLocal,
222
+ doBindings,
221
223
  }: {
222
224
  entry: Entry;
223
225
  destination: string | undefined;
@@ -238,6 +240,7 @@ async function runEsbuild({
238
240
  testScheduled?: boolean;
239
241
  local: boolean;
240
242
  experimentalLocal: boolean | undefined;
243
+ doBindings: DurableObjectBindings;
241
244
  }): Promise<EsbuildBundle | undefined> {
242
245
  if (!destination) return;
243
246
 
@@ -279,6 +282,7 @@ async function runEsbuild({
279
282
  testScheduled,
280
283
  local,
281
284
  experimentalLocal,
285
+ doBindings,
282
286
  });
283
287
 
284
288
  return {
@@ -345,15 +349,6 @@ export async function startLocalServer({
345
349
  );
346
350
  }
347
351
 
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
352
  const scriptPath = realpathSync(bundle.path);
358
353
 
359
354
  const upstream =
@@ -123,6 +123,7 @@ export function useEsbuild({
123
123
  minify,
124
124
  nodeCompat,
125
125
  betaD1Shims,
126
+ doBindings: durableObjects.bindings,
126
127
  define,
127
128
  checkFetch: true,
128
129
  assets: assets && {
package/src/docs/index.ts CHANGED
@@ -11,6 +11,7 @@ import type {
11
11
  import type { ArgumentsCamelCase, Argv } from "yargs";
12
12
 
13
13
  const argToUrlHash = {
14
+ d1: "d1",
14
15
  docs: "docs",
15
16
  init: "init",
16
17
  generate: "generate",
@@ -56,7 +57,7 @@ export function docsOptions(yargs: Argv<CommonYargsOptions>) {
56
57
  "r2 object",
57
58
  "r2 bucket",
58
59
  // "dispatch-namespace", // TODO: Undocumented - Workers for Platforms
59
- // "d1", //TODO: Undocumented
60
+ "d1",
60
61
  // "pubsub", //TODO: Undocumented
61
62
  "login",
62
63
  "logout",
package/src/entry.ts CHANGED
@@ -6,6 +6,7 @@ import { execaCommand } from "execa";
6
6
  import { logger } from "./logger";
7
7
  import { getBasePath } from "./paths";
8
8
  import type { Config } from "./config";
9
+ import type { DurableObjectBindings } from "./config/environment";
9
10
  import type { CfScriptFormat } from "./worker";
10
11
  import type { Metafile } from "esbuild";
11
12
 
@@ -236,8 +237,6 @@ export function fileExists(filePath: string): boolean {
236
237
  return false;
237
238
  }
238
239
 
239
- type DurableObjectBindings = Config["durable_objects"]["bindings"];
240
-
241
240
  /**
242
241
  * Groups the durable object bindings into two lists:
243
242
  * those that are defined locally and those that refer to a durable object defined in another script.
package/src/index.ts CHANGED
@@ -588,7 +588,7 @@ export function createCLIParser(argv: string[]) {
588
588
  );
589
589
 
590
590
  logger.log(`${deploymentsWarning}\n`);
591
- await deployments(accountId, scriptName);
591
+ await deployments(accountId, scriptName, config);
592
592
  }
593
593
  );
594
594
 
package/src/init.ts CHANGED
@@ -599,7 +599,7 @@ export async function initHandler(args: InitArgs) {
599
599
  isWritingScripts: shouldWritePackageJsonScripts,
600
600
  isCreatingWranglerToml: justCreatedWranglerToml,
601
601
  packagePath: pathToPackageJson,
602
- scriptPath: "src/index.ts",
602
+ scriptPath: "src/index.js",
603
603
  //? Should we have Environment argument for `wrangler init --from-dash` - Jacob
604
604
  extraToml: (await getWorkerConfig(accountId, fromDashScriptName, {
605
605
  defaultEnvironment,
@@ -56,7 +56,8 @@ export type EventNames =
56
56
  | "run dev"
57
57
  | "run dev (api)"
58
58
  | "run pages dev"
59
- | "view docs";
59
+ | "view docs"
60
+ | "view deployments";
60
61
 
61
62
  /**
62
63
  * Send a metrics event, with no extra properties, to Cloudflare, if usage tracking is enabled.
@@ -1,27 +1,19 @@
1
- import { writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { dirname, join, resolve } from "node:path";
1
+ import { dirname } from "node:path";
4
2
  import { FatalError } from "../errors";
5
3
  import { logger } from "../logger";
6
4
  import * as metrics from "../metrics";
7
- import { toUrlPath } from "../paths";
5
+ import { buildFunctions } from "./buildFunctions";
8
6
  import { isInPagesCI } from "./constants";
9
7
  import {
10
8
  EXIT_CODE_FUNCTIONS_NO_ROUTES_ERROR,
11
9
  FunctionsNoRoutesError,
12
10
  getFunctionsNoRoutesWarning,
13
11
  } from "./errors";
14
- import { buildPlugin } from "./functions/buildPlugin";
15
- import { buildWorker } from "./functions/buildWorker";
16
- import { generateConfigFromFileTree } from "./functions/filepath-routing";
17
- import { writeRoutesModule } from "./functions/routes";
18
- import { convertRoutesToRoutesJSONSpec } from "./functions/routes-transformation";
19
- import { pagesBetaWarning, RUNNING_BUILDERS } from "./utils";
12
+ import { pagesBetaWarning } from "./utils";
20
13
  import type { YargsOptionsToInterface } from "../yargs-types";
21
- import type { Config } from "./functions/routes";
22
14
  import type { Argv } from "yargs";
23
15
 
24
- type PagesBuildArgs = YargsOptionsToInterface<typeof Options>;
16
+ export type PagesBuildArgs = YargsOptionsToInterface<typeof Options>;
25
17
 
26
18
  export function Options(yargs: Argv) {
27
19
  return yargs
@@ -156,115 +148,3 @@ export const Handler = async ({
156
148
  }
157
149
  await metrics.sendMetricsEvent("build pages functions");
158
150
  };
159
-
160
- /**
161
- * Builds a Functions worker based on the functions directory, with filepath and handler based routing.
162
- * @throws FunctionsNoRoutesError when there are no routes found in the functions directory
163
- */
164
- export async function buildFunctions({
165
- outfile,
166
- outputConfigPath,
167
- functionsDirectory,
168
- minify = false,
169
- sourcemap = false,
170
- fallbackService = "ASSETS",
171
- watch = false,
172
- onEnd,
173
- plugin = false,
174
- buildOutputDirectory,
175
- routesOutputPath,
176
- nodeCompat,
177
- local,
178
- d1Databases,
179
- }: Partial<
180
- Pick<
181
- PagesBuildArgs,
182
- | "outputConfigPath"
183
- | "minify"
184
- | "sourcemap"
185
- | "fallbackService"
186
- | "watch"
187
- | "plugin"
188
- | "buildOutputDirectory"
189
- | "nodeCompat"
190
- >
191
- > & {
192
- functionsDirectory: string;
193
- onEnd?: () => void;
194
- outfile: Required<PagesBuildArgs>["outfile"];
195
- routesOutputPath?: PagesBuildArgs["outputRoutesPath"];
196
- local: boolean;
197
- d1Databases?: string[];
198
- }) {
199
- RUNNING_BUILDERS.forEach(
200
- (runningBuilder) => runningBuilder.stop && runningBuilder.stop()
201
- );
202
-
203
- const routesModule = join(tmpdir(), `./functionsRoutes-${Math.random()}.mjs`);
204
- const baseURL = toUrlPath("/");
205
-
206
- const config: Config = await generateConfigFromFileTree({
207
- baseDir: functionsDirectory,
208
- baseURL,
209
- });
210
-
211
- if (!config.routes || config.routes.length === 0) {
212
- throw new FunctionsNoRoutesError(
213
- `Failed to find any routes while compiling Functions in: ${functionsDirectory}`
214
- );
215
- }
216
-
217
- if (routesOutputPath) {
218
- const routesJSON = convertRoutesToRoutesJSONSpec(config.routes);
219
- writeFileSync(routesOutputPath, JSON.stringify(routesJSON, null, 2));
220
- }
221
-
222
- if (outputConfigPath) {
223
- writeFileSync(
224
- outputConfigPath,
225
- JSON.stringify({ ...config, baseURL }, null, 2)
226
- );
227
- }
228
-
229
- await writeRoutesModule({
230
- config,
231
- srcDir: functionsDirectory,
232
- outfile: routesModule,
233
- });
234
-
235
- const absoluteFunctionsDirectory = resolve(functionsDirectory);
236
-
237
- if (plugin) {
238
- RUNNING_BUILDERS.push(
239
- await buildPlugin({
240
- routesModule,
241
- outfile,
242
- minify,
243
- sourcemap,
244
- watch,
245
- nodeCompat,
246
- functionsDirectory: absoluteFunctionsDirectory,
247
- local,
248
- betaD1Shims: d1Databases,
249
- onEnd,
250
- })
251
- );
252
- } else {
253
- RUNNING_BUILDERS.push(
254
- await buildWorker({
255
- routesModule,
256
- outfile,
257
- minify,
258
- sourcemap,
259
- fallbackService,
260
- watch,
261
- functionsDirectory: absoluteFunctionsDirectory,
262
- local,
263
- betaD1Shims: d1Databases,
264
- onEnd,
265
- buildOutputDirectory,
266
- nodeCompat,
267
- })
268
- );
269
- }
270
- }