wrangler 2.0.1 → 2.0.5
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/Cloudflare_CA.pem +18 -0
- package/bin/wrangler.js +23 -3
- package/package.json +4 -2
- package/pages/functions/buildWorker.ts +1 -1
- package/pages/functions/template-plugin.ts +3 -2
- package/src/__tests__/configuration.test.ts +1 -1
- package/src/__tests__/dev.test.tsx +77 -10
- package/src/__tests__/index.test.ts +51 -58
- package/src/__tests__/jest.setup.ts +8 -0
- package/src/__tests__/kv.test.ts +75 -48
- package/src/__tests__/pages.test.ts +12 -14
- package/src/__tests__/publish.test.ts +127 -6
- package/src/__tests__/r2.test.ts +12 -16
- package/src/bundle.ts +1 -1
- package/src/cfetch/internal.ts +3 -0
- package/src/config/config.ts +1 -1
- package/src/config/validation.ts +1 -1
- package/src/dev/dev.tsx +5 -2
- package/src/entry.ts +64 -9
- package/src/index.tsx +81 -55
- package/src/kv.ts +38 -13
- package/src/pages.tsx +19 -12
- package/src/sites.tsx +10 -10
- package/src/user.tsx +11 -1
- package/wrangler-dist/cli.js +1022 -791
|
@@ -30,10 +30,9 @@ describe("pages", () => {
|
|
|
30
30
|
wrangler pages publish [directory] 🆙 Publish a directory of static assets as a Pages deployment
|
|
31
31
|
|
|
32
32
|
Flags:
|
|
33
|
-
-c, --config
|
|
34
|
-
-h, --help
|
|
35
|
-
-v, --version
|
|
36
|
-
--legacy-env Use legacy environments [boolean]
|
|
33
|
+
-c, --config Path to .toml configuration file [string]
|
|
34
|
+
-h, --help Show help [boolean]
|
|
35
|
+
-v, --version Show version number [boolean]
|
|
37
36
|
|
|
38
37
|
🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
39
38
|
`);
|
|
@@ -258,20 +257,19 @@ describe("pages", () => {
|
|
|
258
257
|
🆙 Publish a directory of static assets as a Pages deployment
|
|
259
258
|
|
|
260
259
|
Positionals:
|
|
261
|
-
directory The directory of
|
|
260
|
+
directory The directory of static files to upload [string]
|
|
262
261
|
|
|
263
262
|
Flags:
|
|
264
|
-
-c, --config
|
|
265
|
-
-h, --help
|
|
266
|
-
-v, --version
|
|
267
|
-
--legacy-env Use legacy environments [boolean]
|
|
263
|
+
-c, --config Path to .toml configuration file [string]
|
|
264
|
+
-h, --help Show help [boolean]
|
|
265
|
+
-v, --version Show version number [boolean]
|
|
268
266
|
|
|
269
267
|
Options:
|
|
270
|
-
--project-name The name of the project you want to
|
|
271
|
-
--branch The
|
|
272
|
-
--commit-hash The
|
|
273
|
-
--commit-message The
|
|
274
|
-
--commit-dirty
|
|
268
|
+
--project-name The name of the project you want to deploy to [string]
|
|
269
|
+
--branch The name of the branch you want to deploy to [string]
|
|
270
|
+
--commit-hash The SHA to attach to this deployment [string]
|
|
271
|
+
--commit-message The commit message to attach to this deployment [string]
|
|
272
|
+
--commit-dirty Whether or not the workspace should be considered dirty for this deployment [boolean]
|
|
275
273
|
|
|
276
274
|
🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
277
275
|
`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import * as TOML from "@iarna/toml";
|
|
4
|
+
import * as esbuild from "esbuild";
|
|
4
5
|
import { writeAuthConfigFile } from "../user";
|
|
5
6
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
6
7
|
import {
|
|
@@ -878,6 +879,78 @@ export default{
|
|
|
878
879
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
879
880
|
});
|
|
880
881
|
|
|
882
|
+
it("should preserve exports on a module format worker", async () => {
|
|
883
|
+
writeWranglerToml();
|
|
884
|
+
fs.writeFileSync(
|
|
885
|
+
"index.js",
|
|
886
|
+
`
|
|
887
|
+
export const abc = 123;
|
|
888
|
+
export const def = "show me the money";
|
|
889
|
+
export default {};`
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
await runWrangler("publish index.js --dry-run --outdir out");
|
|
893
|
+
|
|
894
|
+
expect(
|
|
895
|
+
(
|
|
896
|
+
await esbuild.build({
|
|
897
|
+
entryPoints: [path.resolve("./out/index.js")],
|
|
898
|
+
metafile: true,
|
|
899
|
+
write: false,
|
|
900
|
+
})
|
|
901
|
+
).metafile?.outputs["index.js"].exports
|
|
902
|
+
).toMatchInlineSnapshot(`
|
|
903
|
+
Array [
|
|
904
|
+
"abc",
|
|
905
|
+
"def",
|
|
906
|
+
"default",
|
|
907
|
+
]
|
|
908
|
+
`);
|
|
909
|
+
|
|
910
|
+
expect(std).toMatchInlineSnapshot(`
|
|
911
|
+
Object {
|
|
912
|
+
"debug": "",
|
|
913
|
+
"err": "",
|
|
914
|
+
"out": "--dry-run: exiting now.",
|
|
915
|
+
"warn": "",
|
|
916
|
+
}
|
|
917
|
+
`);
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
it("should not preserve exports on a service-worker format worker", async () => {
|
|
921
|
+
writeWranglerToml();
|
|
922
|
+
fs.writeFileSync(
|
|
923
|
+
"index.js",
|
|
924
|
+
`
|
|
925
|
+
export const abc = 123;
|
|
926
|
+
export const def = "show me the money";
|
|
927
|
+
addEventListener('fetch', event => {});`
|
|
928
|
+
);
|
|
929
|
+
|
|
930
|
+
await runWrangler("publish index.js --dry-run --outdir out");
|
|
931
|
+
|
|
932
|
+
expect(
|
|
933
|
+
(
|
|
934
|
+
await esbuild.build({
|
|
935
|
+
entryPoints: [path.resolve("./out/index.js")],
|
|
936
|
+
metafile: true,
|
|
937
|
+
write: false,
|
|
938
|
+
})
|
|
939
|
+
).metafile?.outputs["index.js"].exports
|
|
940
|
+
).toMatchInlineSnapshot(`Array []`);
|
|
941
|
+
|
|
942
|
+
expect(std).toMatchInlineSnapshot(`
|
|
943
|
+
Object {
|
|
944
|
+
"debug": "",
|
|
945
|
+
"err": "",
|
|
946
|
+
"out": "--dry-run: exiting now.",
|
|
947
|
+
"warn": "[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe entrypoint index.js has exports like an ES Module, but hasn't defined a default export like a module worker normally would. Building the worker using \\"service-worker\\" format...[0m
|
|
948
|
+
|
|
949
|
+
",
|
|
950
|
+
}
|
|
951
|
+
`);
|
|
952
|
+
});
|
|
953
|
+
|
|
881
954
|
it("should be able to transpile entry-points in sub-directories (sw)", async () => {
|
|
882
955
|
writeWranglerToml();
|
|
883
956
|
writeWorkerSource({ basePath: "./src", type: "sw" });
|
|
@@ -2476,18 +2549,66 @@ export default{
|
|
|
2476
2549
|
},
|
|
2477
2550
|
});
|
|
2478
2551
|
|
|
2479
|
-
await expect(
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2552
|
+
await expect(runWrangler("publish index.js")).rejects
|
|
2553
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
2554
|
+
"The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
2555
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build."
|
|
2556
|
+
`);
|
|
2484
2557
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2485
2558
|
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
2486
2559
|
|
|
2487
2560
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
2488
2561
|
`);
|
|
2489
2562
|
expect(std.err).toMatchInlineSnapshot(`
|
|
2490
|
-
"[31mX [41;31m[[41;97mERROR[41;31m][0m [
|
|
2563
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".[0m
|
|
2564
|
+
|
|
2565
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2566
|
+
|
|
2567
|
+
"
|
|
2568
|
+
`);
|
|
2569
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
2570
|
+
});
|
|
2571
|
+
|
|
2572
|
+
it("should throw an error if the entry is a directory after the build finishes", async () => {
|
|
2573
|
+
writeWranglerToml({
|
|
2574
|
+
main: "./",
|
|
2575
|
+
build: {
|
|
2576
|
+
command: `node -e "console.log('custom build');"`,
|
|
2577
|
+
},
|
|
2578
|
+
});
|
|
2579
|
+
|
|
2580
|
+
fs.writeFileSync("./worker.js", "some content", "utf-8");
|
|
2581
|
+
fs.mkdirSync("./dist");
|
|
2582
|
+
fs.writeFileSync("./dist/index.ts", "some content", "utf-8");
|
|
2583
|
+
|
|
2584
|
+
await expect(runWrangler("publish")).rejects
|
|
2585
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
2586
|
+
"The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
2587
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2588
|
+
The provided entry-point path, \\".\\", points to a directory, rather than a file.
|
|
2589
|
+
|
|
2590
|
+
Did you mean to set the main field to one of:
|
|
2591
|
+
\`\`\`
|
|
2592
|
+
main = \\"./worker.js\\"
|
|
2593
|
+
main = \\"./dist/index.ts\\"
|
|
2594
|
+
\`\`\`"
|
|
2595
|
+
`);
|
|
2596
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
2597
|
+
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
2598
|
+
|
|
2599
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
2600
|
+
`);
|
|
2601
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
2602
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".[0m
|
|
2603
|
+
|
|
2604
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2605
|
+
The provided entry-point path, \\".\\", points to a directory, rather than a file.
|
|
2606
|
+
|
|
2607
|
+
Did you mean to set the main field to one of:
|
|
2608
|
+
\`\`\`
|
|
2609
|
+
main = \\"./worker.js\\"
|
|
2610
|
+
main = \\"./dist/index.ts\\"
|
|
2611
|
+
\`\`\`
|
|
2491
2612
|
|
|
2492
2613
|
"
|
|
2493
2614
|
`);
|
package/src/__tests__/r2.test.ts
CHANGED
|
@@ -80,10 +80,9 @@ describe("wrangler", () => {
|
|
|
80
80
|
name The name of the new bucket [string] [required]
|
|
81
81
|
|
|
82
82
|
Flags:
|
|
83
|
-
-c, --config
|
|
84
|
-
-h, --help
|
|
85
|
-
-v, --version
|
|
86
|
-
--legacy-env Use legacy environments [boolean]
|
|
83
|
+
-c, --config Path to .toml configuration file [string]
|
|
84
|
+
-h, --help Show help [boolean]
|
|
85
|
+
-v, --version Show version number [boolean]
|
|
87
86
|
[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
88
87
|
|
|
89
88
|
"
|
|
@@ -109,10 +108,9 @@ describe("wrangler", () => {
|
|
|
109
108
|
name The name of the new bucket [string] [required]
|
|
110
109
|
|
|
111
110
|
Flags:
|
|
112
|
-
-c, --config
|
|
113
|
-
-h, --help
|
|
114
|
-
-v, --version
|
|
115
|
-
--legacy-env Use legacy environments [boolean]
|
|
111
|
+
-c, --config Path to .toml configuration file [string]
|
|
112
|
+
-h, --help Show help [boolean]
|
|
113
|
+
-v, --version Show version number [boolean]
|
|
116
114
|
[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown arguments: def, ghi[0m
|
|
117
115
|
|
|
118
116
|
"
|
|
@@ -164,10 +162,9 @@ describe("wrangler", () => {
|
|
|
164
162
|
name The name of the bucket to delete [string] [required]
|
|
165
163
|
|
|
166
164
|
Flags:
|
|
167
|
-
-c, --config
|
|
168
|
-
-h, --help
|
|
169
|
-
-v, --version
|
|
170
|
-
--legacy-env Use legacy environments [boolean]
|
|
165
|
+
-c, --config Path to .toml configuration file [string]
|
|
166
|
+
-h, --help Show help [boolean]
|
|
167
|
+
-v, --version Show version number [boolean]
|
|
171
168
|
[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
172
169
|
|
|
173
170
|
"
|
|
@@ -193,10 +190,9 @@ describe("wrangler", () => {
|
|
|
193
190
|
name The name of the bucket to delete [string] [required]
|
|
194
191
|
|
|
195
192
|
Flags:
|
|
196
|
-
-c, --config
|
|
197
|
-
-h, --help
|
|
198
|
-
-v, --version
|
|
199
|
-
--legacy-env Use legacy environments [boolean]
|
|
193
|
+
-c, --config Path to .toml configuration file [string]
|
|
194
|
+
-h, --help Show help [boolean]
|
|
195
|
+
-v, --version Show version number [boolean]
|
|
200
196
|
[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown arguments: def, ghi[0m
|
|
201
197
|
|
|
202
198
|
"
|
package/src/bundle.ts
CHANGED
|
@@ -66,7 +66,7 @@ export async function bundleWorker(
|
|
|
66
66
|
absWorkingDir: entry.directory,
|
|
67
67
|
outdir: destination,
|
|
68
68
|
external: ["__STATIC_CONTENT_MANIFEST"],
|
|
69
|
-
format: "esm",
|
|
69
|
+
format: entry.format === "modules" ? "esm" : "iife",
|
|
70
70
|
target: "es2020",
|
|
71
71
|
sourcemap: true,
|
|
72
72
|
minify,
|
package/src/cfetch/internal.ts
CHANGED
|
@@ -112,6 +112,9 @@ function addAuthorizationHeader(
|
|
|
112
112
|
* doesn't return json. We inline the implementation and try not to share
|
|
113
113
|
* any code with the other calls. We should push back on any new APIs that
|
|
114
114
|
* try to introduce non-"standard" response structures.
|
|
115
|
+
*
|
|
116
|
+
* Note: any calls to fetchKVGetValue must call encodeURIComponent on key
|
|
117
|
+
* before passing it
|
|
115
118
|
*/
|
|
116
119
|
|
|
117
120
|
export async function fetchKVGetValue(
|
package/src/config/config.ts
CHANGED
package/src/config/validation.ts
CHANGED
package/src/dev/dev.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import * as path from "node:path";
|
|
2
3
|
import { watch } from "chokidar";
|
|
3
4
|
import clipboardy from "clipboardy";
|
|
4
5
|
import commandExists from "command-exists";
|
|
@@ -242,9 +243,11 @@ function useCustomBuild(
|
|
|
242
243
|
persistent: true,
|
|
243
244
|
ignoreInitial: true,
|
|
244
245
|
}).on("all", (_event, filePath) => {
|
|
246
|
+
const relativeFile =
|
|
247
|
+
path.relative(expectedEntry.directory, expectedEntry.file) || ".";
|
|
245
248
|
//TODO: we should buffer requests to the proxy until this completes
|
|
246
249
|
logger.log(`The file ${filePath} changed, restarting build...`);
|
|
247
|
-
runCustomBuild(expectedEntry.file, build).catch((err) => {
|
|
250
|
+
runCustomBuild(expectedEntry.file, relativeFile, build).catch((err) => {
|
|
248
251
|
logger.error("Custom build failed:", err);
|
|
249
252
|
});
|
|
250
253
|
});
|
|
@@ -253,7 +256,7 @@ function useCustomBuild(
|
|
|
253
256
|
return () => {
|
|
254
257
|
watcher?.close();
|
|
255
258
|
};
|
|
256
|
-
}, [build, expectedEntry
|
|
259
|
+
}, [build, expectedEntry]);
|
|
257
260
|
}
|
|
258
261
|
|
|
259
262
|
function sleep(period: number) {
|
package/src/entry.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
2
|
+
import { existsSync, statSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import * as esbuild from "esbuild";
|
|
5
5
|
import { execaCommand } from "execa";
|
|
@@ -45,11 +45,16 @@ export async function getEntry(
|
|
|
45
45
|
file = path.resolve(directory, config.main);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const relativeFile = path.relative(directory, file) || ".";
|
|
49
|
+
await runCustomBuild(file, relativeFile, config.build);
|
|
49
50
|
|
|
50
51
|
if (fileExists(file) === false) {
|
|
51
52
|
throw new Error(
|
|
52
|
-
|
|
53
|
+
getMissingEntryPointMessage(
|
|
54
|
+
`The entry-point file at "${relativeFile}" was not found.`,
|
|
55
|
+
file,
|
|
56
|
+
relativeFile
|
|
57
|
+
)
|
|
53
58
|
);
|
|
54
59
|
}
|
|
55
60
|
const format = await guessWorkerFormat(
|
|
@@ -90,7 +95,8 @@ export async function getEntry(
|
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
export async function runCustomBuild(
|
|
93
|
-
|
|
98
|
+
expectedEntryAbsolute: string,
|
|
99
|
+
expectedEntryRelative: string,
|
|
94
100
|
build: Config["build"]
|
|
95
101
|
) {
|
|
96
102
|
if (build?.command) {
|
|
@@ -105,12 +111,14 @@ export async function runCustomBuild(
|
|
|
105
111
|
...(build.cwd && { cwd: build.cwd }),
|
|
106
112
|
});
|
|
107
113
|
|
|
108
|
-
if (fileExists(
|
|
114
|
+
if (fileExists(expectedEntryAbsolute) === false) {
|
|
109
115
|
throw new Error(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
getMissingEntryPointMessage(
|
|
117
|
+
`The expected output file at "${expectedEntryRelative}" was not found after running custom build: ${build.command}.\n` +
|
|
118
|
+
"The `main` property in wrangler.toml should point to the file generated by the custom build.",
|
|
119
|
+
expectedEntryAbsolute,
|
|
120
|
+
expectedEntryRelative
|
|
121
|
+
)
|
|
114
122
|
);
|
|
115
123
|
}
|
|
116
124
|
}
|
|
@@ -265,3 +273,50 @@ function generateAddScriptNameExamples(
|
|
|
265
273
|
})
|
|
266
274
|
.join("\n");
|
|
267
275
|
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Generate an appropriate message for when the entry-point is missing.
|
|
279
|
+
*
|
|
280
|
+
* To be more helpful to developers, we check whether there is a suitable file
|
|
281
|
+
* nearby to the expected file path.
|
|
282
|
+
*/
|
|
283
|
+
function getMissingEntryPointMessage(
|
|
284
|
+
message: string,
|
|
285
|
+
absoluteEntryPointPath: string,
|
|
286
|
+
relativeEntryPointPath: string
|
|
287
|
+
): string {
|
|
288
|
+
if (
|
|
289
|
+
existsSync(absoluteEntryPointPath) &&
|
|
290
|
+
statSync(absoluteEntryPointPath).isDirectory()
|
|
291
|
+
) {
|
|
292
|
+
// The expected entry-point is a directory, so offer further guidance.
|
|
293
|
+
message += `\nThe provided entry-point path, "${relativeEntryPointPath}", points to a directory, rather than a file.\n`;
|
|
294
|
+
|
|
295
|
+
// Perhaps we can even guess what the correct path should be...
|
|
296
|
+
const possiblePaths: string[] = [];
|
|
297
|
+
for (const basenamePath of [
|
|
298
|
+
"worker",
|
|
299
|
+
"dist/worker",
|
|
300
|
+
"index",
|
|
301
|
+
"dist/index",
|
|
302
|
+
]) {
|
|
303
|
+
for (const extension of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
304
|
+
const filePath = basenamePath + extension;
|
|
305
|
+
if (fileExists(path.resolve(absoluteEntryPointPath, filePath))) {
|
|
306
|
+
possiblePaths.push(path.join(relativeEntryPointPath, filePath));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (possiblePaths.length > 0) {
|
|
312
|
+
message +=
|
|
313
|
+
`\nDid you mean to set the main field to${
|
|
314
|
+
possiblePaths.length > 1 ? " one of" : ""
|
|
315
|
+
}:\n` +
|
|
316
|
+
"```\n" +
|
|
317
|
+
possiblePaths.map((filePath) => `main = "./${filePath}"\n`).join("") +
|
|
318
|
+
"```";
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return message;
|
|
322
|
+
}
|