wrangler 2.0.24 → 2.0.27
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.
- package/miniflare-dist/index.mjs +142 -16
- package/package.json +3 -3
- package/src/__tests__/configuration.test.ts +7 -3
- package/src/__tests__/dev.test.tsx +26 -4
- package/src/__tests__/generate.test.ts +2 -4
- package/src/__tests__/helpers/mock-cfetch.ts +35 -2
- package/src/__tests__/init.test.ts +537 -359
- package/src/__tests__/jest.setup.ts +7 -0
- package/src/__tests__/metrics.test.ts +1 -1
- package/src/__tests__/pages.test.ts +14 -0
- package/src/__tests__/r2.test.ts +22 -3
- package/src/__tests__/tail.test.ts +112 -42
- package/src/__tests__/user.test.ts +11 -0
- package/src/api/dev.ts +7 -0
- package/src/bundle.ts +3 -2
- package/src/cfetch/internal.ts +56 -0
- package/src/config/config.ts +1 -1
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +9 -3
- package/src/config-cache.ts +2 -1
- package/src/dev/dev.tsx +16 -2
- package/src/dev/local.tsx +69 -5
- package/src/dev/use-esbuild.ts +3 -0
- package/src/dev-registry.tsx +3 -0
- package/src/dev.tsx +28 -19
- package/src/generate.ts +1 -1
- package/src/index.tsx +51 -21
- package/src/init.ts +111 -38
- package/src/inspect.ts +1 -4
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/metrics/metrics-config.ts +1 -1
- package/src/miniflare-cli/assets.ts +27 -16
- package/src/miniflare-cli/index.ts +124 -2
- package/src/pages/build.tsx +75 -41
- package/src/pages/constants.ts +4 -0
- package/src/pages/deployments.tsx +9 -9
- package/src/pages/dev.tsx +178 -64
- package/src/pages/errors.ts +22 -0
- package/src/pages/functions/buildPlugin.ts +4 -0
- package/src/pages/functions/buildWorker.ts +4 -0
- package/src/pages/functions/routes-consolidation.test.ts +250 -0
- package/src/pages/functions/routes-consolidation.ts +73 -0
- package/src/pages/functions/routes-transformation.test.ts +271 -0
- package/src/pages/functions/routes-transformation.ts +122 -0
- package/src/pages/functions.tsx +96 -0
- package/src/pages/index.tsx +65 -55
- package/src/pages/projects.tsx +9 -3
- package/src/pages/publish.tsx +75 -22
- package/src/pages/types.ts +9 -0
- package/src/pages/upload.tsx +6 -8
- package/src/proxy.ts +10 -0
- package/src/r2.ts +17 -4
- package/src/tail/filters.ts +3 -1
- package/src/tail/index.ts +15 -2
- package/src/tail/printing.ts +43 -3
- package/src/user/user.tsx +6 -4
- package/src/whoami.tsx +5 -5
- package/templates/pages-template-plugin.ts +16 -4
- package/templates/pages-template-worker.ts +16 -5
- package/templates/service-bindings-module-facade.js +10 -7
- package/templates/service-bindings-sw-facade.js +10 -7
- package/wrangler-dist/cli.d.ts +7 -0
- package/wrangler-dist/cli.js +1681 -1091
package/src/pages/constants.ts
CHANGED
|
@@ -6,3 +6,7 @@ export const MAX_UPLOAD_ATTEMPTS = 5;
|
|
|
6
6
|
export const MAX_CHECK_MISSING_ATTEMPTS = 5;
|
|
7
7
|
export const SECONDS_TO_WAIT_FOR_PROXY = 5;
|
|
8
8
|
export const isInPagesCI = !!process.env.CF_PAGES;
|
|
9
|
+
/** The max number of rules in _routes.json */
|
|
10
|
+
export const MAX_FUNCTIONS_ROUTES_RULES = 100;
|
|
11
|
+
export const MAX_FUNCTIONS_ROUTES_RULE_LENGTH = 100;
|
|
12
|
+
export const ROUTES_SPEC_VERSION = 1;
|
|
@@ -11,14 +11,16 @@ import { requireAuth } from "../user";
|
|
|
11
11
|
import { PAGES_CONFIG_CACHE_FILENAME } from "./constants";
|
|
12
12
|
import { listProjects } from "./projects";
|
|
13
13
|
import { pagesBetaWarning } from "./utils";
|
|
14
|
-
import type {
|
|
15
|
-
|
|
14
|
+
import type {
|
|
15
|
+
Deployment,
|
|
16
|
+
PagesConfigCache,
|
|
17
|
+
YargsOptionsToInterface,
|
|
18
|
+
} from "./types";
|
|
19
|
+
import type { Argv } from "yargs";
|
|
16
20
|
|
|
17
|
-
type ListArgs =
|
|
18
|
-
"project-name"?: string;
|
|
19
|
-
};
|
|
21
|
+
type ListArgs = YargsOptionsToInterface<typeof ListOptions>;
|
|
20
22
|
|
|
21
|
-
export function ListOptions(yargs: Argv)
|
|
23
|
+
export function ListOptions(yargs: Argv) {
|
|
22
24
|
return yargs
|
|
23
25
|
.options({
|
|
24
26
|
"project-name": {
|
|
@@ -30,9 +32,7 @@ export function ListOptions(yargs: Argv): Argv<ListArgs> {
|
|
|
30
32
|
.epilogue(pagesBetaWarning);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
export async function ListHandler({
|
|
34
|
-
projectName,
|
|
35
|
-
}: ArgumentsCamelCase<ListArgs>) {
|
|
35
|
+
export async function ListHandler({ projectName }: ListArgs) {
|
|
36
36
|
const config = getConfigCache<PagesConfigCache>(PAGES_CONFIG_CACHE_FILENAME);
|
|
37
37
|
const accountId = await requireAuth(config);
|
|
38
38
|
|
package/src/pages/dev.tsx
CHANGED
|
@@ -1,34 +1,29 @@
|
|
|
1
1
|
import { execSync, spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
3
|
+
import { homedir, tmpdir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { watch } from "chokidar";
|
|
6
|
+
import { build as workerJsBuild } from "esbuild";
|
|
6
7
|
import { unstable_dev } from "../api";
|
|
7
8
|
import { FatalError } from "../errors";
|
|
8
9
|
import { logger } from "../logger";
|
|
9
10
|
import * as metrics from "../metrics";
|
|
10
11
|
import { buildFunctions } from "./build";
|
|
11
12
|
import { SECONDS_TO_WAIT_FOR_PROXY } from "./constants";
|
|
13
|
+
import { FunctionsNoRoutesError, getFunctionsNoRoutesWarning } from "./errors";
|
|
12
14
|
import { CLEANUP, CLEANUP_CALLBACKS, pagesBetaWarning } from "./utils";
|
|
13
|
-
import type {
|
|
14
|
-
|
|
15
|
-
type
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"script-path": string;
|
|
22
|
-
binding?: (string | number)[];
|
|
23
|
-
kv?: (string | number)[];
|
|
24
|
-
do?: (string | number)[];
|
|
25
|
-
"live-reload": boolean;
|
|
26
|
-
"local-protocol"?: "https" | "http";
|
|
27
|
-
"experimental-enable-local-persistence": boolean;
|
|
28
|
-
"node-compat": boolean;
|
|
29
|
-
};
|
|
15
|
+
import type { AdditionalDevProps } from "../dev";
|
|
16
|
+
import type { YargsOptionsToInterface } from "./types";
|
|
17
|
+
import type { Plugin } from "esbuild";
|
|
18
|
+
import type { Argv } from "yargs";
|
|
19
|
+
|
|
20
|
+
const DURABLE_OBJECTS_BINDING_REGEXP = new RegExp(
|
|
21
|
+
/^(?<binding>[^=]+)=(?<className>[^@\s]+)(@(?<scriptName>.*)$)?$/
|
|
22
|
+
);
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
type PagesDevArgs = YargsOptionsToInterface<typeof Options>;
|
|
25
|
+
|
|
26
|
+
export function Options(yargs: Argv) {
|
|
32
27
|
return yargs
|
|
33
28
|
.positional("directory", {
|
|
34
29
|
type: "string",
|
|
@@ -46,11 +41,41 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
46
41
|
default: true,
|
|
47
42
|
description: "Run on my machine",
|
|
48
43
|
},
|
|
44
|
+
"compatibility-date": {
|
|
45
|
+
describe: "Date to use for compatibility checks",
|
|
46
|
+
type: "string",
|
|
47
|
+
},
|
|
48
|
+
"compatibility-flags": {
|
|
49
|
+
describe: "Flags to use for compatibility checks",
|
|
50
|
+
alias: "compatibility-flag",
|
|
51
|
+
type: "string",
|
|
52
|
+
array: true,
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// TODO
|
|
56
|
+
// For now, all Pages projects are set to 2021-11-02. We're adding compat date soon, and we can then adopt `wrangler dev`'s `default: true`.
|
|
57
|
+
// However, it looks like it isn't actually connected up properly in `wrangler dev` at the moment, hence commenting this out for now.
|
|
58
|
+
|
|
59
|
+
// latest: {
|
|
60
|
+
// describe: "Use the latest version of the worker runtime",
|
|
61
|
+
// type: "boolean",
|
|
62
|
+
// default: false,
|
|
63
|
+
// },
|
|
64
|
+
|
|
65
|
+
ip: {
|
|
66
|
+
type: "string",
|
|
67
|
+
default: "0.0.0.0",
|
|
68
|
+
description: "The IP address to listen on",
|
|
69
|
+
},
|
|
49
70
|
port: {
|
|
50
71
|
type: "number",
|
|
51
72
|
default: 8788,
|
|
52
73
|
description: "The port to listen on (serve from)",
|
|
53
74
|
},
|
|
75
|
+
"inspector-port": {
|
|
76
|
+
type: "number",
|
|
77
|
+
describe: "Port for devtools to connect to",
|
|
78
|
+
},
|
|
54
79
|
proxy: {
|
|
55
80
|
type: "number",
|
|
56
81
|
description: "The port to proxy (where the static assets are served)",
|
|
@@ -68,14 +93,18 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
68
93
|
},
|
|
69
94
|
kv: {
|
|
70
95
|
type: "array",
|
|
71
|
-
description: "KV namespace to bind",
|
|
96
|
+
description: "KV namespace to bind (--kv KV_BINDING)",
|
|
72
97
|
alias: "k",
|
|
73
98
|
},
|
|
74
99
|
do: {
|
|
75
100
|
type: "array",
|
|
76
|
-
description: "Durable Object to bind (NAME=CLASS)",
|
|
101
|
+
description: "Durable Object to bind (--do NAME=CLASS)",
|
|
77
102
|
alias: "o",
|
|
78
103
|
},
|
|
104
|
+
r2: {
|
|
105
|
+
type: "array",
|
|
106
|
+
description: "R2 bucket to bind (--r2 R2_BINDING)",
|
|
107
|
+
},
|
|
79
108
|
"live-reload": {
|
|
80
109
|
type: "boolean",
|
|
81
110
|
default: false,
|
|
@@ -108,19 +137,24 @@ export function Options(yargs: Argv): Argv<PagesDevArgs> {
|
|
|
108
137
|
export const Handler = async ({
|
|
109
138
|
local,
|
|
110
139
|
directory,
|
|
140
|
+
"compatibility-date": compatibilityDate = "2021-11-02",
|
|
141
|
+
"compatibility-flags": compatibilityFlags,
|
|
142
|
+
ip,
|
|
111
143
|
port,
|
|
144
|
+
"inspector-port": inspectorPort,
|
|
112
145
|
proxy: requestedProxyPort,
|
|
113
146
|
"script-path": singleWorkerScriptPath,
|
|
114
147
|
binding: bindings = [],
|
|
115
148
|
kv: kvs = [],
|
|
116
149
|
do: durableObjects = [],
|
|
150
|
+
r2: r2s = [],
|
|
117
151
|
"live-reload": liveReload,
|
|
118
152
|
"local-protocol": localProtocol,
|
|
119
153
|
"experimental-enable-local-persistence": experimentalEnableLocalPersistence,
|
|
120
154
|
"node-compat": nodeCompat,
|
|
121
155
|
config: config,
|
|
122
156
|
_: [_pages, _dev, ...remaining],
|
|
123
|
-
}:
|
|
157
|
+
}: PagesDevArgs) => {
|
|
124
158
|
// Beta message for `wrangler pages <commands>` usage
|
|
125
159
|
logger.log(pagesBetaWarning);
|
|
126
160
|
|
|
@@ -133,7 +167,7 @@ export const Handler = async ({
|
|
|
133
167
|
}
|
|
134
168
|
|
|
135
169
|
const functionsDirectory = "./functions";
|
|
136
|
-
|
|
170
|
+
let usingFunctions = existsSync(functionsDirectory);
|
|
137
171
|
|
|
138
172
|
const command = remaining;
|
|
139
173
|
|
|
@@ -159,8 +193,9 @@ export const Handler = async ({
|
|
|
159
193
|
(promiseResolve) => (scriptReadyResolve = promiseResolve)
|
|
160
194
|
);
|
|
161
195
|
|
|
162
|
-
let scriptPath
|
|
196
|
+
let scriptPath = "";
|
|
163
197
|
|
|
198
|
+
// Try to use Functions
|
|
164
199
|
if (usingFunctions) {
|
|
165
200
|
const outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`);
|
|
166
201
|
scriptPath = outfile;
|
|
@@ -172,36 +207,63 @@ export const Handler = async ({
|
|
|
172
207
|
}
|
|
173
208
|
|
|
174
209
|
logger.log(`Compiling worker to "${outfile}"...`);
|
|
175
|
-
|
|
210
|
+
const onEnd = () => scriptReadyResolve();
|
|
176
211
|
try {
|
|
177
212
|
await buildFunctions({
|
|
178
213
|
outfile,
|
|
179
214
|
functionsDirectory,
|
|
180
215
|
sourcemap: true,
|
|
181
216
|
watch: true,
|
|
182
|
-
onEnd
|
|
217
|
+
onEnd,
|
|
183
218
|
buildOutputDirectory: directory,
|
|
184
219
|
nodeCompat,
|
|
185
220
|
});
|
|
186
221
|
await metrics.sendMetricsEvent("build pages functions");
|
|
187
|
-
} catch {}
|
|
188
222
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
223
|
+
// If Functions found routes, continue using Functions
|
|
224
|
+
watch([functionsDirectory], {
|
|
225
|
+
persistent: true,
|
|
226
|
+
ignoreInitial: true,
|
|
227
|
+
}).on("all", async () => {
|
|
228
|
+
try {
|
|
229
|
+
await buildFunctions({
|
|
230
|
+
outfile,
|
|
231
|
+
functionsDirectory,
|
|
232
|
+
sourcemap: true,
|
|
233
|
+
watch: true,
|
|
234
|
+
onEnd,
|
|
235
|
+
buildOutputDirectory: directory,
|
|
236
|
+
nodeCompat,
|
|
237
|
+
});
|
|
238
|
+
await metrics.sendMetricsEvent("build pages functions");
|
|
239
|
+
} catch (e) {
|
|
240
|
+
if (e instanceof FunctionsNoRoutesError) {
|
|
241
|
+
logger.warn(
|
|
242
|
+
getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
|
|
243
|
+
);
|
|
244
|
+
} else {
|
|
245
|
+
throw e;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
201
248
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
249
|
+
} catch (e) {
|
|
250
|
+
// If there are no Functions, then Pages will only serve assets.
|
|
251
|
+
if (e instanceof FunctionsNoRoutesError) {
|
|
252
|
+
logger.warn(
|
|
253
|
+
getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
|
|
254
|
+
);
|
|
255
|
+
// Resolve anyway and run without Functions
|
|
256
|
+
onEnd();
|
|
257
|
+
// Turn off Functions
|
|
258
|
+
usingFunctions = false;
|
|
259
|
+
} else {
|
|
260
|
+
throw e;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Depending on the result of building Functions, we may not actually be using
|
|
265
|
+
// Functions even if the directory exists.
|
|
266
|
+
if (!usingFunctions) {
|
|
205
267
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
206
268
|
scriptReadyResolve!();
|
|
207
269
|
|
|
@@ -213,20 +275,48 @@ export const Handler = async ({
|
|
|
213
275
|
if (!existsSync(scriptPath)) {
|
|
214
276
|
logger.log("No functions. Shimming...");
|
|
215
277
|
scriptPath = resolve(__dirname, "../templates/pages-shim.ts");
|
|
278
|
+
} else {
|
|
279
|
+
const runBuild = async () => {
|
|
280
|
+
try {
|
|
281
|
+
await workerJsBuild({
|
|
282
|
+
entryPoints: [scriptPath],
|
|
283
|
+
write: false,
|
|
284
|
+
plugins: [blockWorkerJsImports],
|
|
285
|
+
});
|
|
286
|
+
} catch {}
|
|
287
|
+
};
|
|
288
|
+
await runBuild();
|
|
289
|
+
watch([scriptPath], {
|
|
290
|
+
persistent: true,
|
|
291
|
+
ignoreInitial: true,
|
|
292
|
+
}).on("all", async () => {
|
|
293
|
+
await runBuild();
|
|
294
|
+
});
|
|
216
295
|
}
|
|
217
296
|
}
|
|
218
297
|
|
|
219
298
|
await scriptReadyPromise;
|
|
220
299
|
|
|
300
|
+
if (scriptPath === "") {
|
|
301
|
+
// Failed to get a script with or without Functions,
|
|
302
|
+
// something really bad must have happend.
|
|
303
|
+
throw new FatalError(
|
|
304
|
+
"Failed to start wrangler pages dev due to an unknown error",
|
|
305
|
+
1
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
221
309
|
const { stop, waitUntilExit } = await unstable_dev(
|
|
222
310
|
scriptPath,
|
|
223
311
|
{
|
|
312
|
+
ip,
|
|
224
313
|
port,
|
|
314
|
+
inspectorPort,
|
|
225
315
|
watch: true,
|
|
226
316
|
localProtocol,
|
|
227
317
|
liveReload,
|
|
228
|
-
|
|
229
|
-
|
|
318
|
+
compatibilityDate,
|
|
319
|
+
compatibilityFlags,
|
|
230
320
|
nodeCompat,
|
|
231
321
|
vars: Object.fromEntries(
|
|
232
322
|
bindings
|
|
@@ -237,12 +327,29 @@ export const Handler = async ({
|
|
|
237
327
|
binding: val.toString(),
|
|
238
328
|
id: "",
|
|
239
329
|
})),
|
|
240
|
-
durableObjects: durableObjects
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
330
|
+
durableObjects: durableObjects
|
|
331
|
+
.map((durableObject) => {
|
|
332
|
+
const { binding, className, scriptName } =
|
|
333
|
+
DURABLE_OBJECTS_BINDING_REGEXP.exec(durableObject.toString())
|
|
334
|
+
?.groups || {};
|
|
335
|
+
|
|
336
|
+
if (!binding || !className) {
|
|
337
|
+
logger.warn(
|
|
338
|
+
"Could not parse Durable Object binding:",
|
|
339
|
+
durableObject.toString()
|
|
340
|
+
);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return {
|
|
345
|
+
name: binding,
|
|
346
|
+
class_name: className,
|
|
347
|
+
script_name: scriptName,
|
|
348
|
+
};
|
|
349
|
+
})
|
|
350
|
+
.filter(Boolean) as AdditionalDevProps["durableObjects"],
|
|
351
|
+
r2: r2s.map((binding) => {
|
|
352
|
+
return { binding: binding.toString(), bucket_name: "" };
|
|
246
353
|
}),
|
|
247
354
|
|
|
248
355
|
enablePagesAssetsServiceBinding: {
|
|
@@ -260,24 +367,16 @@ export const Handler = async ({
|
|
|
260
367
|
);
|
|
261
368
|
await metrics.sendMetricsEvent("run pages dev");
|
|
262
369
|
|
|
370
|
+
CLEANUP_CALLBACKS.push(stop);
|
|
371
|
+
|
|
263
372
|
waitUntilExit().then(() => {
|
|
264
373
|
CLEANUP();
|
|
265
|
-
stop();
|
|
266
374
|
process.exit(0);
|
|
267
375
|
});
|
|
268
376
|
|
|
269
|
-
process.on("exit",
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
});
|
|
273
|
-
process.on("SIGINT", () => {
|
|
274
|
-
CLEANUP();
|
|
275
|
-
stop();
|
|
276
|
-
});
|
|
277
|
-
process.on("SIGTERM", () => {
|
|
278
|
-
CLEANUP();
|
|
279
|
-
stop();
|
|
280
|
-
});
|
|
377
|
+
process.on("exit", CLEANUP);
|
|
378
|
+
process.on("SIGINT", CLEANUP);
|
|
379
|
+
process.on("SIGTERM", CLEANUP);
|
|
281
380
|
};
|
|
282
381
|
|
|
283
382
|
function isWindows() {
|
|
@@ -319,7 +418,8 @@ function getPort(pid: number) {
|
|
|
319
418
|
let command: string, regExp: RegExp;
|
|
320
419
|
|
|
321
420
|
if (isWindows()) {
|
|
322
|
-
|
|
421
|
+
const drive = homedir().split(":\\")[0];
|
|
422
|
+
command = drive + ":\\windows\\system32\\netstat.exe -nao";
|
|
323
423
|
regExp = new RegExp(`TCP\\s+.*:(\\d+)\\s+.*:\\d+\\s+LISTENING\\s+${pid}`);
|
|
324
424
|
} else {
|
|
325
425
|
command = "lsof -nPi";
|
|
@@ -383,6 +483,8 @@ async function spawnProxyProcess({
|
|
|
383
483
|
|
|
384
484
|
proxy.on("close", (code) => {
|
|
385
485
|
logger.error(`Proxy exited with status ${code}.`);
|
|
486
|
+
CLEANUP();
|
|
487
|
+
process.exitCode = code ?? 0;
|
|
386
488
|
});
|
|
387
489
|
|
|
388
490
|
// Wait for proxy process to start...
|
|
@@ -412,3 +514,15 @@ async function spawnProxyProcess({
|
|
|
412
514
|
|
|
413
515
|
return port;
|
|
414
516
|
}
|
|
517
|
+
|
|
518
|
+
const blockWorkerJsImports: Plugin = {
|
|
519
|
+
name: "block-worker-js-imports",
|
|
520
|
+
setup(build) {
|
|
521
|
+
build.onResolve({ filter: /.*/g }, (_args) => {
|
|
522
|
+
logger.error(
|
|
523
|
+
`_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.`
|
|
524
|
+
);
|
|
525
|
+
return null;
|
|
526
|
+
});
|
|
527
|
+
},
|
|
528
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pages error when no routes are found in the functions directory
|
|
3
|
+
*/
|
|
4
|
+
export class FunctionsNoRoutesError extends Error {
|
|
5
|
+
constructor(message: string) {
|
|
6
|
+
super(message);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Exit code for `pages functions build` when no routes are found.
|
|
11
|
+
*/
|
|
12
|
+
export const EXIT_CODE_FUNCTIONS_NO_ROUTES_ERROR = 156;
|
|
13
|
+
|
|
14
|
+
/** Warning message for when buildFunctions throws FunctionsNoRoutesError */
|
|
15
|
+
export function getFunctionsNoRoutesWarning(
|
|
16
|
+
functionsDirectory: string,
|
|
17
|
+
suffix?: string
|
|
18
|
+
) {
|
|
19
|
+
return `No routes found when building Functions directory: ${functionsDirectory}${
|
|
20
|
+
suffix ? " - " + suffix : ""
|
|
21
|
+
}`;
|
|
22
|
+
}
|