wrangler 0.0.0-ece06ea → 0.0.0-ef13735
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/bin/wrangler.js +2 -2
- package/package.json +35 -21
- package/pages/functions/buildWorker.ts +62 -0
- package/pages/functions/filepath-routing.test.ts +66 -0
- package/pages/functions/filepath-routing.ts +219 -0
- package/pages/functions/identifiers.ts +78 -0
- package/pages/functions/routes.ts +151 -0
- package/pages/functions/template-worker.ts +130 -0
- package/src/__tests__/dev.test.tsx +73 -0
- package/src/__tests__/guess-worker-format.test.ts +51 -0
- package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
- package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
- package/src/__tests__/helpers/mock-account-id.ts +30 -0
- package/src/__tests__/helpers/mock-bin.ts +33 -0
- package/src/__tests__/helpers/mock-cfetch.ts +207 -0
- package/src/__tests__/helpers/mock-console.ts +56 -0
- package/src/__tests__/helpers/mock-dialogs.ts +65 -0
- package/src/__tests__/helpers/mock-kv.ts +40 -0
- package/src/__tests__/helpers/mock-user.ts +27 -0
- package/src/__tests__/helpers/run-in-tmp.ts +29 -0
- package/src/__tests__/helpers/run-wrangler.ts +14 -0
- package/src/__tests__/index.test.ts +715 -119
- package/src/__tests__/jest.setup.ts +37 -0
- package/src/__tests__/kv.test.ts +1139 -0
- package/src/__tests__/logout.test.ts +50 -0
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/publish.test.ts +1381 -0
- package/src/__tests__/secret.test.ts +210 -0
- package/src/__tests__/whoami.test.tsx +86 -0
- package/src/api/form_data.ts +93 -100
- package/src/api/preview.ts +29 -24
- package/src/api/worker.ts +55 -47
- package/src/cfetch/index.ts +102 -0
- package/src/cfetch/internal.ts +101 -0
- package/src/cli.ts +6 -7
- package/src/config.ts +641 -112
- package/src/dev.tsx +476 -355
- package/src/dialogs.tsx +6 -14
- package/src/guess-worker-format.ts +66 -0
- package/src/index.tsx +828 -496
- package/src/inspect.ts +596 -0
- package/src/kv.tsx +118 -45
- package/src/module-collection.ts +63 -0
- package/src/open-in-browser.ts +13 -0
- package/src/package-manager.ts +120 -0
- package/src/pages.tsx +915 -215
- package/src/paths.ts +26 -0
- package/src/proxy.ts +370 -0
- package/src/publish.ts +349 -290
- package/src/sites.tsx +184 -55
- package/src/tail.tsx +5 -3
- package/src/user.tsx +81 -91
- package/src/whoami.tsx +69 -0
- package/templates/new-worker.js +15 -0
- package/templates/new-worker.ts +15 -0
- package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
- package/wrangler-dist/cli.js +119231 -130682
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/fixtures/init/.gitkeep +0 -0
- package/src/__tests__/mock-cfetch.js +0 -46
- package/src/api/inspect.ts +0 -441
- package/src/cfetch.ts +0 -72
- package/src/util/fetch.ts +0 -74
|
@@ -0,0 +1,1381 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as TOML from "@iarna/toml";
|
|
4
|
+
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
5
|
+
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
|
|
6
|
+
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
7
|
+
import { mockKeyListRequest } from "./helpers/mock-kv";
|
|
8
|
+
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
9
|
+
import { runWrangler } from "./helpers/run-wrangler";
|
|
10
|
+
import type { WorkerMetadata } from "../api/form_data";
|
|
11
|
+
import type { Config } from "../config";
|
|
12
|
+
import type { KVNamespaceInfo } from "../kv";
|
|
13
|
+
import type { FormData, File } from "undici";
|
|
14
|
+
|
|
15
|
+
describe("publish", () => {
|
|
16
|
+
mockAccountId();
|
|
17
|
+
mockApiToken();
|
|
18
|
+
runInTempDir();
|
|
19
|
+
const std = mockConsoleMethods();
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
unsetAllMocks();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("entry-points", () => {
|
|
26
|
+
it("should be able to use `index` with no extension as the entry-point (esm)", async () => {
|
|
27
|
+
writeWranglerToml();
|
|
28
|
+
writeWorkerSource();
|
|
29
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
30
|
+
mockSubDomainRequest();
|
|
31
|
+
|
|
32
|
+
await runWrangler("publish ./index");
|
|
33
|
+
|
|
34
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
35
|
+
"Uploaded
|
|
36
|
+
test-name
|
|
37
|
+
(TIMINGS)
|
|
38
|
+
Deployed
|
|
39
|
+
test-name
|
|
40
|
+
(TIMINGS)
|
|
41
|
+
|
|
42
|
+
test-name.test-sub-domain.workers.dev"
|
|
43
|
+
`);
|
|
44
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should be able to use `index` with no extension as the entry-point (sw)", async () => {
|
|
48
|
+
writeWranglerToml();
|
|
49
|
+
writeWorkerSource({ type: "sw" });
|
|
50
|
+
mockUploadWorkerRequest({ expectedType: "sw" });
|
|
51
|
+
mockSubDomainRequest();
|
|
52
|
+
|
|
53
|
+
await runWrangler("publish ./index");
|
|
54
|
+
|
|
55
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
56
|
+
"Uploaded
|
|
57
|
+
test-name
|
|
58
|
+
(TIMINGS)
|
|
59
|
+
Deployed
|
|
60
|
+
test-name
|
|
61
|
+
(TIMINGS)
|
|
62
|
+
|
|
63
|
+
test-name.test-sub-domain.workers.dev"
|
|
64
|
+
`);
|
|
65
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should be able to use the `build.upload.main` config as the entry-point for ESM sources", async () => {
|
|
69
|
+
writeWranglerToml({ build: { upload: { main: "./index.js" } } });
|
|
70
|
+
writeWorkerSource();
|
|
71
|
+
mockUploadWorkerRequest();
|
|
72
|
+
mockSubDomainRequest();
|
|
73
|
+
|
|
74
|
+
await runWrangler("publish");
|
|
75
|
+
|
|
76
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
77
|
+
"Uploaded
|
|
78
|
+
test-name
|
|
79
|
+
(TIMINGS)
|
|
80
|
+
Deployed
|
|
81
|
+
test-name
|
|
82
|
+
(TIMINGS)
|
|
83
|
+
|
|
84
|
+
test-name.test-sub-domain.workers.dev"
|
|
85
|
+
`);
|
|
86
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should use `build.upload.main` relative to the wrangler.toml not cwd", async () => {
|
|
90
|
+
writeWranglerToml({
|
|
91
|
+
build: {
|
|
92
|
+
upload: {
|
|
93
|
+
main: "./foo/index.js",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
writeWorkerSource({ basePath: "foo" });
|
|
98
|
+
mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
|
|
99
|
+
mockSubDomainRequest();
|
|
100
|
+
process.chdir("foo");
|
|
101
|
+
await runWrangler("publish");
|
|
102
|
+
|
|
103
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
104
|
+
"Uploaded
|
|
105
|
+
test-name
|
|
106
|
+
(TIMINGS)
|
|
107
|
+
Deployed
|
|
108
|
+
test-name
|
|
109
|
+
(TIMINGS)
|
|
110
|
+
|
|
111
|
+
test-name.test-sub-domain.workers.dev"
|
|
112
|
+
`);
|
|
113
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("should use `build.upload.main` relative to `build.upload.dir` if format is `modules`", async () => {
|
|
117
|
+
writeWranglerToml({
|
|
118
|
+
build: {
|
|
119
|
+
upload: {
|
|
120
|
+
format: "modules",
|
|
121
|
+
main: "./index.js",
|
|
122
|
+
dir: "./foo",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
writeWorkerSource({ basePath: "./foo" });
|
|
127
|
+
mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
|
|
128
|
+
mockSubDomainRequest();
|
|
129
|
+
process.chdir("foo");
|
|
130
|
+
await runWrangler("publish");
|
|
131
|
+
|
|
132
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
133
|
+
"Uploaded
|
|
134
|
+
test-name
|
|
135
|
+
(TIMINGS)
|
|
136
|
+
Deployed
|
|
137
|
+
test-name
|
|
138
|
+
(TIMINGS)
|
|
139
|
+
|
|
140
|
+
test-name.test-sub-domain.workers.dev"
|
|
141
|
+
`);
|
|
142
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should be able to transpile TypeScript (esm)", async () => {
|
|
146
|
+
writeWranglerToml();
|
|
147
|
+
writeWorkerSource({ format: "ts" });
|
|
148
|
+
mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
|
|
149
|
+
mockSubDomainRequest();
|
|
150
|
+
await runWrangler("publish index.ts");
|
|
151
|
+
|
|
152
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
153
|
+
"Uploaded
|
|
154
|
+
test-name
|
|
155
|
+
(TIMINGS)
|
|
156
|
+
Deployed
|
|
157
|
+
test-name
|
|
158
|
+
(TIMINGS)
|
|
159
|
+
|
|
160
|
+
test-name.test-sub-domain.workers.dev"
|
|
161
|
+
`);
|
|
162
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("should be able to transpile TypeScript (sw)", async () => {
|
|
166
|
+
writeWranglerToml();
|
|
167
|
+
writeWorkerSource({ format: "ts", type: "sw" });
|
|
168
|
+
mockUploadWorkerRequest({
|
|
169
|
+
expectedEntry: "var foo = 100;",
|
|
170
|
+
expectedType: "sw",
|
|
171
|
+
});
|
|
172
|
+
mockSubDomainRequest();
|
|
173
|
+
await runWrangler("publish index.ts");
|
|
174
|
+
|
|
175
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
176
|
+
"Uploaded
|
|
177
|
+
test-name
|
|
178
|
+
(TIMINGS)
|
|
179
|
+
Deployed
|
|
180
|
+
test-name
|
|
181
|
+
(TIMINGS)
|
|
182
|
+
|
|
183
|
+
test-name.test-sub-domain.workers.dev"
|
|
184
|
+
`);
|
|
185
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("should inline referenced text modules into the worker", async () => {
|
|
189
|
+
writeWranglerToml();
|
|
190
|
+
fs.writeFileSync(
|
|
191
|
+
"./index.js",
|
|
192
|
+
`
|
|
193
|
+
import txt from './textfile.txt';
|
|
194
|
+
export default{
|
|
195
|
+
fetch(){
|
|
196
|
+
return new Response(txt);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
`
|
|
200
|
+
);
|
|
201
|
+
fs.writeFileSync("./textfile.txt", "Hello, World!");
|
|
202
|
+
mockUploadWorkerRequest({ expectedEntry: "Hello, World!" });
|
|
203
|
+
mockSubDomainRequest();
|
|
204
|
+
await runWrangler("publish index.js");
|
|
205
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
206
|
+
"Uploaded
|
|
207
|
+
test-name
|
|
208
|
+
(TIMINGS)
|
|
209
|
+
Deployed
|
|
210
|
+
test-name
|
|
211
|
+
(TIMINGS)
|
|
212
|
+
|
|
213
|
+
test-name.test-sub-domain.workers.dev"
|
|
214
|
+
`);
|
|
215
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("should be able to transpile entry-points in sub-directories (esm)", async () => {
|
|
219
|
+
writeWranglerToml();
|
|
220
|
+
writeWorkerSource({ basePath: "./src" });
|
|
221
|
+
mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
|
|
222
|
+
mockSubDomainRequest();
|
|
223
|
+
|
|
224
|
+
await runWrangler("publish ./src/index.js");
|
|
225
|
+
|
|
226
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
227
|
+
"Uploaded
|
|
228
|
+
test-name
|
|
229
|
+
(TIMINGS)
|
|
230
|
+
Deployed
|
|
231
|
+
test-name
|
|
232
|
+
(TIMINGS)
|
|
233
|
+
|
|
234
|
+
test-name.test-sub-domain.workers.dev"
|
|
235
|
+
`);
|
|
236
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("should be able to transpile entry-points in sub-directories (sw)", async () => {
|
|
240
|
+
writeWranglerToml();
|
|
241
|
+
writeWorkerSource({ basePath: "./src", type: "sw" });
|
|
242
|
+
mockUploadWorkerRequest({
|
|
243
|
+
expectedEntry: "var foo = 100;",
|
|
244
|
+
expectedType: "sw",
|
|
245
|
+
});
|
|
246
|
+
mockSubDomainRequest();
|
|
247
|
+
|
|
248
|
+
await runWrangler("publish ./src/index.js");
|
|
249
|
+
|
|
250
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
251
|
+
"Uploaded
|
|
252
|
+
test-name
|
|
253
|
+
(TIMINGS)
|
|
254
|
+
Deployed
|
|
255
|
+
test-name
|
|
256
|
+
(TIMINGS)
|
|
257
|
+
|
|
258
|
+
test-name.test-sub-domain.workers.dev"
|
|
259
|
+
`);
|
|
260
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should error if a site definition doesn\'t have a "bucket" field', async () => {
|
|
264
|
+
writeWranglerToml({
|
|
265
|
+
// @ts-expect-error we're purposely missing the required `site.bucket` field
|
|
266
|
+
site: {
|
|
267
|
+
"entry-point": "./index.js",
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
writeWorkerSource();
|
|
271
|
+
mockUploadWorkerRequest();
|
|
272
|
+
mockSubDomainRequest();
|
|
273
|
+
|
|
274
|
+
await expect(
|
|
275
|
+
runWrangler("publish ./index.js")
|
|
276
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
277
|
+
`"A [site] definition requires a \`bucket\` field with a path to the site's public directory."`
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
281
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
282
|
+
"A [site] definition requires a \`bucket\` field with a path to the site's public directory.
|
|
283
|
+
|
|
284
|
+
[32m%s[0m
|
|
285
|
+
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
286
|
+
`);
|
|
287
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
288
|
+
"Deprecation notice: The \`site.entry-point\` config field is no longer used.
|
|
289
|
+
The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.
|
|
290
|
+
Please remove the \`site.entry-point\` field from the \`wrangler.toml\` file."
|
|
291
|
+
`);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("should warn if there is a `site.entry-point` configuration", async () => {
|
|
295
|
+
const assets = [
|
|
296
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
297
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
298
|
+
];
|
|
299
|
+
const kvNamespace = {
|
|
300
|
+
title: "__test-name-workers_sites_assets",
|
|
301
|
+
id: "__test-name-workers_sites_assets-id",
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
writeWranglerToml({
|
|
305
|
+
site: {
|
|
306
|
+
"entry-point": "./index.js",
|
|
307
|
+
bucket: "assets",
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
writeWorkerSource();
|
|
311
|
+
writeAssets(assets);
|
|
312
|
+
mockUploadWorkerRequest();
|
|
313
|
+
mockSubDomainRequest();
|
|
314
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
315
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
316
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
317
|
+
|
|
318
|
+
await runWrangler("publish ./index.js");
|
|
319
|
+
|
|
320
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
321
|
+
"reading assets/file-1.txt...
|
|
322
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
323
|
+
reading assets/file-2.txt...
|
|
324
|
+
uploading as assets/file-2.5938485188.txt...
|
|
325
|
+
Uploaded
|
|
326
|
+
test-name
|
|
327
|
+
(TIMINGS)
|
|
328
|
+
Deployed
|
|
329
|
+
test-name
|
|
330
|
+
(TIMINGS)
|
|
331
|
+
|
|
332
|
+
test-name.test-sub-domain.workers.dev"
|
|
333
|
+
`);
|
|
334
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
335
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
336
|
+
"Deprecation notice: The \`site.entry-point\` config field is no longer used.
|
|
337
|
+
The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.
|
|
338
|
+
Please remove the \`site.entry-point\` field from the \`wrangler.toml\` file."
|
|
339
|
+
`);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("should error if there is no entry-point specified", async () => {
|
|
343
|
+
writeWranglerToml();
|
|
344
|
+
writeWorkerSource();
|
|
345
|
+
mockUploadWorkerRequest();
|
|
346
|
+
mockSubDomainRequest();
|
|
347
|
+
await expect(
|
|
348
|
+
runWrangler("publish")
|
|
349
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
350
|
+
`"Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field."`
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
354
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
355
|
+
"Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`build.upload.main\` config field.
|
|
356
|
+
|
|
357
|
+
[32m%s[0m
|
|
358
|
+
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
359
|
+
`);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe("asset upload", () => {
|
|
364
|
+
it("should upload all the files in the directory specified by `config.site.bucket`", async () => {
|
|
365
|
+
const assets = [
|
|
366
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
367
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
368
|
+
];
|
|
369
|
+
const kvNamespace = {
|
|
370
|
+
title: "__test-name-workers_sites_assets",
|
|
371
|
+
id: "__test-name-workers_sites_assets-id",
|
|
372
|
+
};
|
|
373
|
+
writeWranglerToml({
|
|
374
|
+
build: { upload: { main: "./index.js" } },
|
|
375
|
+
site: {
|
|
376
|
+
bucket: "assets",
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
writeWorkerSource();
|
|
380
|
+
writeAssets(assets);
|
|
381
|
+
mockUploadWorkerRequest();
|
|
382
|
+
mockSubDomainRequest();
|
|
383
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
384
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
385
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
386
|
+
await runWrangler("publish");
|
|
387
|
+
|
|
388
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
389
|
+
"reading assets/file-1.txt...
|
|
390
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
391
|
+
reading assets/file-2.txt...
|
|
392
|
+
uploading as assets/file-2.5938485188.txt...
|
|
393
|
+
Uploaded
|
|
394
|
+
test-name
|
|
395
|
+
(TIMINGS)
|
|
396
|
+
Deployed
|
|
397
|
+
test-name
|
|
398
|
+
(TIMINGS)
|
|
399
|
+
|
|
400
|
+
test-name.test-sub-domain.workers.dev"
|
|
401
|
+
`);
|
|
402
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
it("when using a service worker type, it should inline an asset manifest, and bind to a namespace", async () => {
|
|
406
|
+
const assets = [
|
|
407
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
408
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
409
|
+
];
|
|
410
|
+
const kvNamespace = {
|
|
411
|
+
title: "__test-name-workers_sites_assets",
|
|
412
|
+
id: "__test-name-workers_sites_assets-id",
|
|
413
|
+
};
|
|
414
|
+
writeWranglerToml({
|
|
415
|
+
build: { upload: { main: "./index.js" } },
|
|
416
|
+
site: {
|
|
417
|
+
bucket: "assets",
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
writeWorkerSource({ type: "sw" });
|
|
421
|
+
writeAssets(assets);
|
|
422
|
+
mockUploadWorkerRequest({
|
|
423
|
+
expectedType: "sw",
|
|
424
|
+
expectedEntry: `const __STATIC_CONTENT_MANIFEST = {"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"};`,
|
|
425
|
+
expectedBindings: [
|
|
426
|
+
{
|
|
427
|
+
name: "__STATIC_CONTENT",
|
|
428
|
+
namespace_id: "__test-name-workers_sites_assets-id",
|
|
429
|
+
type: "kv_namespace",
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
});
|
|
433
|
+
mockSubDomainRequest();
|
|
434
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
435
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
436
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
437
|
+
|
|
438
|
+
await runWrangler("publish");
|
|
439
|
+
|
|
440
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
441
|
+
"reading assets/file-1.txt...
|
|
442
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
443
|
+
reading assets/file-2.txt...
|
|
444
|
+
uploading as assets/file-2.5938485188.txt...
|
|
445
|
+
Uploaded
|
|
446
|
+
test-name
|
|
447
|
+
(TIMINGS)
|
|
448
|
+
Deployed
|
|
449
|
+
test-name
|
|
450
|
+
(TIMINGS)
|
|
451
|
+
|
|
452
|
+
test-name.test-sub-domain.workers.dev"
|
|
453
|
+
`);
|
|
454
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
|
|
458
|
+
const assets = [
|
|
459
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
460
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
461
|
+
];
|
|
462
|
+
const kvNamespace = {
|
|
463
|
+
title: "__test-name-workers_sites_assets",
|
|
464
|
+
id: "__test-name-workers_sites_assets-id",
|
|
465
|
+
};
|
|
466
|
+
writeWranglerToml({
|
|
467
|
+
build: { upload: { main: "./index.js" } },
|
|
468
|
+
site: {
|
|
469
|
+
bucket: "assets",
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
writeWorkerSource({ type: "esm" });
|
|
473
|
+
writeAssets(assets);
|
|
474
|
+
mockUploadWorkerRequest({
|
|
475
|
+
expectedBindings: [
|
|
476
|
+
{
|
|
477
|
+
name: "__STATIC_CONTENT",
|
|
478
|
+
namespace_id: "__test-name-workers_sites_assets-id",
|
|
479
|
+
type: "kv_namespace",
|
|
480
|
+
},
|
|
481
|
+
],
|
|
482
|
+
expectedModules: {
|
|
483
|
+
__STATIC_CONTENT_MANIFEST:
|
|
484
|
+
'{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
mockSubDomainRequest();
|
|
488
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
489
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
490
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
491
|
+
|
|
492
|
+
await runWrangler("publish");
|
|
493
|
+
|
|
494
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
495
|
+
"reading assets/file-1.txt...
|
|
496
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
497
|
+
reading assets/file-2.txt...
|
|
498
|
+
uploading as assets/file-2.5938485188.txt...
|
|
499
|
+
Uploaded
|
|
500
|
+
test-name
|
|
501
|
+
(TIMINGS)
|
|
502
|
+
Deployed
|
|
503
|
+
test-name
|
|
504
|
+
(TIMINGS)
|
|
505
|
+
|
|
506
|
+
test-name.test-sub-domain.workers.dev"
|
|
507
|
+
`);
|
|
508
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
it("should make environment specific kv namespace for assets", async () => {
|
|
512
|
+
// This is the same test as the one before this, but with an env arg
|
|
513
|
+
const assets = [
|
|
514
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
515
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
516
|
+
];
|
|
517
|
+
const kvNamespace = {
|
|
518
|
+
title: "__test-name-some-env-workers_sites_assets",
|
|
519
|
+
id: "__test-name-some-env-workers_sites_assets-id",
|
|
520
|
+
};
|
|
521
|
+
writeWranglerToml({
|
|
522
|
+
build: { upload: { main: "./index.js" } },
|
|
523
|
+
site: {
|
|
524
|
+
bucket: "assets",
|
|
525
|
+
},
|
|
526
|
+
});
|
|
527
|
+
writeWorkerSource();
|
|
528
|
+
writeAssets(assets);
|
|
529
|
+
mockUploadWorkerRequest({
|
|
530
|
+
env: "some-env",
|
|
531
|
+
expectedBindings: [
|
|
532
|
+
{
|
|
533
|
+
name: "__STATIC_CONTENT",
|
|
534
|
+
namespace_id: "__test-name-some-env-workers_sites_assets-id",
|
|
535
|
+
type: "kv_namespace",
|
|
536
|
+
},
|
|
537
|
+
],
|
|
538
|
+
});
|
|
539
|
+
mockSubDomainRequest();
|
|
540
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
541
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
542
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
543
|
+
await runWrangler("publish --env some-env");
|
|
544
|
+
|
|
545
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
546
|
+
"reading assets/file-1.txt...
|
|
547
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
548
|
+
reading assets/file-2.txt...
|
|
549
|
+
uploading as assets/file-2.5938485188.txt...
|
|
550
|
+
Uploaded
|
|
551
|
+
test-name (some-env)
|
|
552
|
+
(TIMINGS)
|
|
553
|
+
Deployed
|
|
554
|
+
test-name (some-env)
|
|
555
|
+
(TIMINGS)
|
|
556
|
+
|
|
557
|
+
some-env.test-name.test-sub-domain.workers.dev"
|
|
558
|
+
`);
|
|
559
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it("should only upload files that are not already in the KV namespace", async () => {
|
|
563
|
+
const assets = [
|
|
564
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
565
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
566
|
+
];
|
|
567
|
+
const kvNamespace = {
|
|
568
|
+
title: "__test-name-workers_sites_assets",
|
|
569
|
+
id: "__test-name-workers_sites_assets-id",
|
|
570
|
+
};
|
|
571
|
+
writeWranglerToml({
|
|
572
|
+
build: { upload: { main: "./index.js" } },
|
|
573
|
+
site: {
|
|
574
|
+
bucket: "assets",
|
|
575
|
+
},
|
|
576
|
+
});
|
|
577
|
+
writeWorkerSource();
|
|
578
|
+
writeAssets(assets);
|
|
579
|
+
mockUploadWorkerRequest();
|
|
580
|
+
mockSubDomainRequest();
|
|
581
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
582
|
+
// Put file-1 in the KV namespace
|
|
583
|
+
mockKeyListRequest(kvNamespace.id, ["assets/file-1.2ca234f380.txt"]);
|
|
584
|
+
// Check we do not upload file-1
|
|
585
|
+
mockUploadAssetsToKVRequest(
|
|
586
|
+
kvNamespace.id,
|
|
587
|
+
assets.filter((a) => a.filePath !== "assets/file-1.txt")
|
|
588
|
+
);
|
|
589
|
+
await runWrangler("publish");
|
|
590
|
+
|
|
591
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
592
|
+
"reading assets/file-1.txt...
|
|
593
|
+
skipping - already uploaded
|
|
594
|
+
reading assets/file-2.txt...
|
|
595
|
+
uploading as assets/file-2.5938485188.txt...
|
|
596
|
+
Uploaded
|
|
597
|
+
test-name
|
|
598
|
+
(TIMINGS)
|
|
599
|
+
Deployed
|
|
600
|
+
test-name
|
|
601
|
+
(TIMINGS)
|
|
602
|
+
|
|
603
|
+
test-name.test-sub-domain.workers.dev"
|
|
604
|
+
`);
|
|
605
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
it("should only upload files that match the `site-include` arg", async () => {
|
|
609
|
+
const assets = [
|
|
610
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
611
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
612
|
+
];
|
|
613
|
+
const kvNamespace = {
|
|
614
|
+
title: "__test-name-workers_sites_assets",
|
|
615
|
+
id: "__test-name-workers_sites_assets-id",
|
|
616
|
+
};
|
|
617
|
+
writeWranglerToml({
|
|
618
|
+
build: { upload: { main: "./index.js" } },
|
|
619
|
+
site: {
|
|
620
|
+
bucket: "assets",
|
|
621
|
+
},
|
|
622
|
+
});
|
|
623
|
+
writeWorkerSource();
|
|
624
|
+
writeAssets(assets);
|
|
625
|
+
mockUploadWorkerRequest();
|
|
626
|
+
mockSubDomainRequest();
|
|
627
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
628
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
629
|
+
// Check we only upload file-1
|
|
630
|
+
mockUploadAssetsToKVRequest(
|
|
631
|
+
kvNamespace.id,
|
|
632
|
+
assets.filter((a) => a.filePath === "assets/file-1.txt")
|
|
633
|
+
);
|
|
634
|
+
await runWrangler("publish --site-include file-1.txt");
|
|
635
|
+
|
|
636
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
637
|
+
"reading assets/file-1.txt...
|
|
638
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
639
|
+
Uploaded
|
|
640
|
+
test-name
|
|
641
|
+
(TIMINGS)
|
|
642
|
+
Deployed
|
|
643
|
+
test-name
|
|
644
|
+
(TIMINGS)
|
|
645
|
+
|
|
646
|
+
test-name.test-sub-domain.workers.dev"
|
|
647
|
+
`);
|
|
648
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it("should not upload files that match the `site-exclude` arg", async () => {
|
|
652
|
+
const assets = [
|
|
653
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
654
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
655
|
+
];
|
|
656
|
+
const kvNamespace = {
|
|
657
|
+
title: "__test-name-workers_sites_assets",
|
|
658
|
+
id: "__test-name-workers_sites_assets-id",
|
|
659
|
+
};
|
|
660
|
+
writeWranglerToml({
|
|
661
|
+
build: { upload: { main: "./index.js" } },
|
|
662
|
+
site: {
|
|
663
|
+
bucket: "assets",
|
|
664
|
+
},
|
|
665
|
+
});
|
|
666
|
+
writeWorkerSource();
|
|
667
|
+
writeAssets(assets);
|
|
668
|
+
mockUploadWorkerRequest();
|
|
669
|
+
mockSubDomainRequest();
|
|
670
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
671
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
672
|
+
// Check we only upload file-1
|
|
673
|
+
mockUploadAssetsToKVRequest(
|
|
674
|
+
kvNamespace.id,
|
|
675
|
+
assets.filter((a) => a.filePath === "assets/file-1.txt")
|
|
676
|
+
);
|
|
677
|
+
await runWrangler("publish --site-exclude file-2.txt");
|
|
678
|
+
|
|
679
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
680
|
+
"reading assets/file-1.txt...
|
|
681
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
682
|
+
Uploaded
|
|
683
|
+
test-name
|
|
684
|
+
(TIMINGS)
|
|
685
|
+
Deployed
|
|
686
|
+
test-name
|
|
687
|
+
(TIMINGS)
|
|
688
|
+
|
|
689
|
+
test-name.test-sub-domain.workers.dev"
|
|
690
|
+
`);
|
|
691
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it("should only upload files that match the `site.include` config", async () => {
|
|
695
|
+
const assets = [
|
|
696
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
697
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
698
|
+
];
|
|
699
|
+
const kvNamespace = {
|
|
700
|
+
title: "__test-name-workers_sites_assets",
|
|
701
|
+
id: "__test-name-workers_sites_assets-id",
|
|
702
|
+
};
|
|
703
|
+
writeWranglerToml({
|
|
704
|
+
build: { upload: { main: "./index.js" } },
|
|
705
|
+
site: {
|
|
706
|
+
bucket: "assets",
|
|
707
|
+
include: ["file-1.txt"],
|
|
708
|
+
},
|
|
709
|
+
});
|
|
710
|
+
writeWorkerSource();
|
|
711
|
+
writeAssets(assets);
|
|
712
|
+
mockUploadWorkerRequest();
|
|
713
|
+
mockSubDomainRequest();
|
|
714
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
715
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
716
|
+
// Check we only upload file-1
|
|
717
|
+
mockUploadAssetsToKVRequest(
|
|
718
|
+
kvNamespace.id,
|
|
719
|
+
assets.filter((a) => a.filePath === "assets/file-1.txt")
|
|
720
|
+
);
|
|
721
|
+
await runWrangler("publish");
|
|
722
|
+
|
|
723
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
724
|
+
"reading assets/file-1.txt...
|
|
725
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
726
|
+
Uploaded
|
|
727
|
+
test-name
|
|
728
|
+
(TIMINGS)
|
|
729
|
+
Deployed
|
|
730
|
+
test-name
|
|
731
|
+
(TIMINGS)
|
|
732
|
+
|
|
733
|
+
test-name.test-sub-domain.workers.dev"
|
|
734
|
+
`);
|
|
735
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
it("should not upload files that match the `site.exclude` config", async () => {
|
|
739
|
+
const assets = [
|
|
740
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
741
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
742
|
+
];
|
|
743
|
+
const kvNamespace = {
|
|
744
|
+
title: "__test-name-workers_sites_assets",
|
|
745
|
+
id: "__test-name-workers_sites_assets-id",
|
|
746
|
+
};
|
|
747
|
+
writeWranglerToml({
|
|
748
|
+
build: { upload: { main: "./index.js" } },
|
|
749
|
+
site: {
|
|
750
|
+
bucket: "assets",
|
|
751
|
+
exclude: ["file-2.txt"],
|
|
752
|
+
},
|
|
753
|
+
});
|
|
754
|
+
writeWorkerSource();
|
|
755
|
+
writeAssets(assets);
|
|
756
|
+
mockUploadWorkerRequest();
|
|
757
|
+
mockSubDomainRequest();
|
|
758
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
759
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
760
|
+
// Check we only upload file-1
|
|
761
|
+
mockUploadAssetsToKVRequest(
|
|
762
|
+
kvNamespace.id,
|
|
763
|
+
assets.filter((a) => a.filePath === "assets/file-1.txt")
|
|
764
|
+
);
|
|
765
|
+
await runWrangler("publish");
|
|
766
|
+
|
|
767
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
768
|
+
"reading assets/file-1.txt...
|
|
769
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
770
|
+
Uploaded
|
|
771
|
+
test-name
|
|
772
|
+
(TIMINGS)
|
|
773
|
+
Deployed
|
|
774
|
+
test-name
|
|
775
|
+
(TIMINGS)
|
|
776
|
+
|
|
777
|
+
test-name.test-sub-domain.workers.dev"
|
|
778
|
+
`);
|
|
779
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it("should use `site-include` arg over `site.include` config", async () => {
|
|
783
|
+
const assets = [
|
|
784
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
785
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
786
|
+
];
|
|
787
|
+
const kvNamespace = {
|
|
788
|
+
title: "__test-name-workers_sites_assets",
|
|
789
|
+
id: "__test-name-workers_sites_assets-id",
|
|
790
|
+
};
|
|
791
|
+
writeWranglerToml({
|
|
792
|
+
build: { upload: { main: "./index.js" } },
|
|
793
|
+
site: {
|
|
794
|
+
bucket: "assets",
|
|
795
|
+
include: ["file-2.txt"],
|
|
796
|
+
},
|
|
797
|
+
});
|
|
798
|
+
writeWorkerSource();
|
|
799
|
+
writeAssets(assets);
|
|
800
|
+
mockUploadWorkerRequest();
|
|
801
|
+
mockSubDomainRequest();
|
|
802
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
803
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
804
|
+
// Check we only upload file-1
|
|
805
|
+
mockUploadAssetsToKVRequest(
|
|
806
|
+
kvNamespace.id,
|
|
807
|
+
assets.filter((a) => a.filePath === "assets/file-1.txt")
|
|
808
|
+
);
|
|
809
|
+
await runWrangler("publish --site-include file-1.txt");
|
|
810
|
+
|
|
811
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
812
|
+
"reading assets/file-1.txt...
|
|
813
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
814
|
+
Uploaded
|
|
815
|
+
test-name
|
|
816
|
+
(TIMINGS)
|
|
817
|
+
Deployed
|
|
818
|
+
test-name
|
|
819
|
+
(TIMINGS)
|
|
820
|
+
|
|
821
|
+
test-name.test-sub-domain.workers.dev"
|
|
822
|
+
`);
|
|
823
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
it("should use `site-exclude` arg over `site.exclude` config", async () => {
|
|
827
|
+
const assets = [
|
|
828
|
+
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
|
|
829
|
+
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
|
|
830
|
+
];
|
|
831
|
+
const kvNamespace = {
|
|
832
|
+
title: "__test-name-workers_sites_assets",
|
|
833
|
+
id: "__test-name-workers_sites_assets-id",
|
|
834
|
+
};
|
|
835
|
+
writeWranglerToml({
|
|
836
|
+
build: { upload: { main: "./index.js" } },
|
|
837
|
+
site: {
|
|
838
|
+
bucket: "assets",
|
|
839
|
+
exclude: ["assets/file-1.txt"],
|
|
840
|
+
},
|
|
841
|
+
});
|
|
842
|
+
writeWorkerSource();
|
|
843
|
+
writeAssets(assets);
|
|
844
|
+
mockUploadWorkerRequest();
|
|
845
|
+
mockSubDomainRequest();
|
|
846
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
847
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
848
|
+
// Check we only upload file-1
|
|
849
|
+
mockUploadAssetsToKVRequest(
|
|
850
|
+
kvNamespace.id,
|
|
851
|
+
assets.filter((a) => a.filePath.endsWith("assets/file-1.txt"))
|
|
852
|
+
);
|
|
853
|
+
await runWrangler("publish --site-exclude file-2.txt");
|
|
854
|
+
|
|
855
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
856
|
+
"reading assets/file-1.txt...
|
|
857
|
+
uploading as assets/file-1.2ca234f380.txt...
|
|
858
|
+
Uploaded
|
|
859
|
+
test-name
|
|
860
|
+
(TIMINGS)
|
|
861
|
+
Deployed
|
|
862
|
+
test-name
|
|
863
|
+
(TIMINGS)
|
|
864
|
+
|
|
865
|
+
test-name.test-sub-domain.workers.dev"
|
|
866
|
+
`);
|
|
867
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it("should walk directories except node_modules", async () => {
|
|
871
|
+
const assets = [
|
|
872
|
+
{
|
|
873
|
+
filePath: "assets/directory-1/file-1.txt",
|
|
874
|
+
content: "Content of file-1",
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
filePath: "assets/node_modules/file-2.txt",
|
|
878
|
+
content: "Content of file-2",
|
|
879
|
+
},
|
|
880
|
+
];
|
|
881
|
+
const kvNamespace = {
|
|
882
|
+
title: "__test-name-workers_sites_assets",
|
|
883
|
+
id: "__test-name-workers_sites_assets-id",
|
|
884
|
+
};
|
|
885
|
+
writeWranglerToml({
|
|
886
|
+
build: { upload: { main: "./index.js" } },
|
|
887
|
+
site: {
|
|
888
|
+
bucket: "assets",
|
|
889
|
+
},
|
|
890
|
+
});
|
|
891
|
+
writeWorkerSource();
|
|
892
|
+
writeAssets(assets);
|
|
893
|
+
mockUploadWorkerRequest();
|
|
894
|
+
mockSubDomainRequest();
|
|
895
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
896
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
897
|
+
// Only expect file-1 to be uploaded
|
|
898
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(0, 1));
|
|
899
|
+
await runWrangler("publish");
|
|
900
|
+
|
|
901
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
902
|
+
"reading assets/directory-1/file-1.txt...
|
|
903
|
+
uploading as assets/directory-1/file-1.2ca234f380.txt...
|
|
904
|
+
Uploaded
|
|
905
|
+
test-name
|
|
906
|
+
(TIMINGS)
|
|
907
|
+
Deployed
|
|
908
|
+
test-name
|
|
909
|
+
(TIMINGS)
|
|
910
|
+
|
|
911
|
+
test-name.test-sub-domain.workers.dev"
|
|
912
|
+
`);
|
|
913
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it("should skip hidden files and directories except `.well-known`", async () => {
|
|
917
|
+
const assets = [
|
|
918
|
+
{
|
|
919
|
+
filePath: "assets/.hidden-file.txt",
|
|
920
|
+
content: "Content of hidden-file",
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
filePath: "assets/.hidden/file-1.txt",
|
|
924
|
+
content: "Content of file-1",
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
filePath: "assets/.well-known/file-2.txt",
|
|
928
|
+
content: "Content of file-2",
|
|
929
|
+
},
|
|
930
|
+
];
|
|
931
|
+
const kvNamespace = {
|
|
932
|
+
title: "__test-name-workers_sites_assets",
|
|
933
|
+
id: "__test-name-workers_sites_assets-id",
|
|
934
|
+
};
|
|
935
|
+
writeWranglerToml({
|
|
936
|
+
build: { upload: { main: "./index.js" } },
|
|
937
|
+
site: {
|
|
938
|
+
bucket: "assets",
|
|
939
|
+
},
|
|
940
|
+
});
|
|
941
|
+
writeWorkerSource();
|
|
942
|
+
writeAssets(assets);
|
|
943
|
+
mockUploadWorkerRequest();
|
|
944
|
+
mockSubDomainRequest();
|
|
945
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
946
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
947
|
+
// Only expect file-2 to be uploaded
|
|
948
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(2));
|
|
949
|
+
await runWrangler("publish");
|
|
950
|
+
|
|
951
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
952
|
+
"reading assets/.well-known/file-2.txt...
|
|
953
|
+
uploading as assets/.well-known/file-2.5938485188.txt...
|
|
954
|
+
Uploaded
|
|
955
|
+
test-name
|
|
956
|
+
(TIMINGS)
|
|
957
|
+
Deployed
|
|
958
|
+
test-name
|
|
959
|
+
(TIMINGS)
|
|
960
|
+
|
|
961
|
+
test-name.test-sub-domain.workers.dev"
|
|
962
|
+
`);
|
|
963
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
it("should error if the asset is over 25Mb", async () => {
|
|
967
|
+
const assets = [
|
|
968
|
+
{
|
|
969
|
+
filePath: "assets/large-file.txt",
|
|
970
|
+
// This file is greater than 25MiB when base64 encoded but small enough to be uploaded.
|
|
971
|
+
content: "X".repeat(25 * 1024 * 1024 * 0.8 + 1),
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
filePath: "assets/too-large-file.txt",
|
|
975
|
+
content: "X".repeat(25 * 1024 * 1024 + 1),
|
|
976
|
+
},
|
|
977
|
+
];
|
|
978
|
+
const kvNamespace = {
|
|
979
|
+
title: "__test-name-workers_sites_assets",
|
|
980
|
+
id: "__test-name-workers_sites_assets-id",
|
|
981
|
+
};
|
|
982
|
+
writeWranglerToml({
|
|
983
|
+
build: { upload: { main: "./index.js" } },
|
|
984
|
+
site: {
|
|
985
|
+
bucket: "assets",
|
|
986
|
+
exclude: ["assets/file-1.txt"],
|
|
987
|
+
},
|
|
988
|
+
});
|
|
989
|
+
writeWorkerSource();
|
|
990
|
+
writeAssets(assets);
|
|
991
|
+
mockUploadWorkerRequest();
|
|
992
|
+
mockSubDomainRequest();
|
|
993
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
994
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
995
|
+
|
|
996
|
+
await expect(
|
|
997
|
+
runWrangler("publish")
|
|
998
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
999
|
+
`"File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits"`
|
|
1000
|
+
);
|
|
1001
|
+
|
|
1002
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1003
|
+
"reading assets/large-file.txt...
|
|
1004
|
+
uploading as assets/large-file.0ea0637a45.txt..."
|
|
1005
|
+
`);
|
|
1006
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1007
|
+
"File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits
|
|
1008
|
+
|
|
1009
|
+
[32m%s[0m
|
|
1010
|
+
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1011
|
+
`);
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
it("should error if the asset key is over 512 characters", async () => {
|
|
1015
|
+
const longFilePathAsset = {
|
|
1016
|
+
filePath: "assets/" + "folder/".repeat(100) + "file.txt",
|
|
1017
|
+
content: "content of file",
|
|
1018
|
+
};
|
|
1019
|
+
const kvNamespace = {
|
|
1020
|
+
title: "__test-name-workers_sites_assets",
|
|
1021
|
+
id: "__test-name-workers_sites_assets-id",
|
|
1022
|
+
};
|
|
1023
|
+
writeWranglerToml({
|
|
1024
|
+
build: { upload: { main: "./index.js" } },
|
|
1025
|
+
site: {
|
|
1026
|
+
bucket: "assets",
|
|
1027
|
+
},
|
|
1028
|
+
});
|
|
1029
|
+
writeWorkerSource();
|
|
1030
|
+
writeAssets([longFilePathAsset]);
|
|
1031
|
+
mockUploadWorkerRequest();
|
|
1032
|
+
mockSubDomainRequest();
|
|
1033
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
1034
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
1035
|
+
|
|
1036
|
+
await expect(
|
|
1037
|
+
runWrangler("publish")
|
|
1038
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1039
|
+
`"The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\","`
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1043
|
+
`"reading assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.txt..."`
|
|
1044
|
+
);
|
|
1045
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1046
|
+
"The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\",
|
|
1047
|
+
|
|
1048
|
+
[32m%s[0m
|
|
1049
|
+
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1050
|
+
`);
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
describe("custom builds", () => {
|
|
1055
|
+
it("should run a custom build before publishing", async () => {
|
|
1056
|
+
writeWranglerToml({
|
|
1057
|
+
build: {
|
|
1058
|
+
command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
|
|
1059
|
+
},
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
mockUploadWorkerRequest({
|
|
1063
|
+
expectedEntry: "return new Response(123)",
|
|
1064
|
+
});
|
|
1065
|
+
mockSubDomainRequest();
|
|
1066
|
+
|
|
1067
|
+
await runWrangler("publish index.js");
|
|
1068
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1069
|
+
"running:
|
|
1070
|
+
node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\"
|
|
1071
|
+
Uploaded
|
|
1072
|
+
test-name
|
|
1073
|
+
(TIMINGS)
|
|
1074
|
+
Deployed
|
|
1075
|
+
test-name
|
|
1076
|
+
(TIMINGS)
|
|
1077
|
+
|
|
1078
|
+
test-name.test-sub-domain.workers.dev"
|
|
1079
|
+
`);
|
|
1080
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1081
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
if (process.platform !== "win32") {
|
|
1085
|
+
it("should run a custom build of multiple steps combined by && before publishing", async () => {
|
|
1086
|
+
writeWranglerToml({
|
|
1087
|
+
build: {
|
|
1088
|
+
command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
|
|
1089
|
+
},
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
mockUploadWorkerRequest({
|
|
1093
|
+
expectedEntry: "return new Response(123)",
|
|
1094
|
+
});
|
|
1095
|
+
mockSubDomainRequest();
|
|
1096
|
+
|
|
1097
|
+
await runWrangler("publish index.js");
|
|
1098
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1099
|
+
"running:
|
|
1100
|
+
echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js
|
|
1101
|
+
Uploaded
|
|
1102
|
+
test-name
|
|
1103
|
+
(TIMINGS)
|
|
1104
|
+
Deployed
|
|
1105
|
+
test-name
|
|
1106
|
+
(TIMINGS)
|
|
1107
|
+
|
|
1108
|
+
test-name.test-sub-domain.workers.dev"
|
|
1109
|
+
`);
|
|
1110
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1111
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
|
|
1116
|
+
describe("[wasm_modules]", () => {
|
|
1117
|
+
it("should be able to define wasm modules for service-worker format workers", async () => {
|
|
1118
|
+
writeWranglerToml({
|
|
1119
|
+
wasm_modules: {
|
|
1120
|
+
TESTWASMNAME: "./path/to/test.wasm",
|
|
1121
|
+
},
|
|
1122
|
+
});
|
|
1123
|
+
writeWorkerSource({ type: "sw" });
|
|
1124
|
+
fs.mkdirSync("./path/to", { recursive: true });
|
|
1125
|
+
fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
|
|
1126
|
+
mockUploadWorkerRequest({
|
|
1127
|
+
expectedType: "sw",
|
|
1128
|
+
expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
|
|
1129
|
+
expectedBindings: [
|
|
1130
|
+
{ name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
|
|
1131
|
+
],
|
|
1132
|
+
});
|
|
1133
|
+
mockSubDomainRequest();
|
|
1134
|
+
await runWrangler("publish index.js");
|
|
1135
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1136
|
+
"Uploaded
|
|
1137
|
+
test-name
|
|
1138
|
+
(TIMINGS)
|
|
1139
|
+
Deployed
|
|
1140
|
+
test-name
|
|
1141
|
+
(TIMINGS)
|
|
1142
|
+
|
|
1143
|
+
test-name.test-sub-domain.workers.dev"
|
|
1144
|
+
`);
|
|
1145
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1146
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
it("should error when defining wasm modules for modules format workers", async () => {
|
|
1150
|
+
writeWranglerToml({
|
|
1151
|
+
wasm_modules: {
|
|
1152
|
+
TESTWASMNAME: "./path/to/test.wasm",
|
|
1153
|
+
},
|
|
1154
|
+
});
|
|
1155
|
+
writeWorkerSource({ type: "esm" });
|
|
1156
|
+
fs.mkdirSync("./path/to", { recursive: true });
|
|
1157
|
+
fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
|
|
1158
|
+
|
|
1159
|
+
await expect(
|
|
1160
|
+
runWrangler("publish index.js")
|
|
1161
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1162
|
+
`"You cannot configure [wasm_modules] with an ES Module worker. Instead, import the .wasm module directly in your code"`
|
|
1163
|
+
);
|
|
1164
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1165
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1166
|
+
"You cannot configure [wasm_modules] with an ES Module worker. Instead, import the .wasm module directly in your code
|
|
1167
|
+
|
|
1168
|
+
[32m%s[0m
|
|
1169
|
+
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1170
|
+
`);
|
|
1171
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1172
|
+
});
|
|
1173
|
+
|
|
1174
|
+
it("should resolve wasm modules relative to the wrangler.toml file", async () => {
|
|
1175
|
+
fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
|
|
1176
|
+
fs.writeFileSync(
|
|
1177
|
+
"./path/to/wrangler.toml",
|
|
1178
|
+
TOML.stringify({
|
|
1179
|
+
compatibility_date: "2022-01-12",
|
|
1180
|
+
name: "test-name",
|
|
1181
|
+
wasm_modules: {
|
|
1182
|
+
TESTWASMNAME: "./and/the/path/to/test.wasm",
|
|
1183
|
+
},
|
|
1184
|
+
}),
|
|
1185
|
+
|
|
1186
|
+
"utf-8"
|
|
1187
|
+
);
|
|
1188
|
+
|
|
1189
|
+
writeWorkerSource({ type: "sw" });
|
|
1190
|
+
fs.writeFileSync(
|
|
1191
|
+
"./path/to/and/the/path/to/test.wasm",
|
|
1192
|
+
"SOME WASM CONTENT"
|
|
1193
|
+
);
|
|
1194
|
+
mockUploadWorkerRequest({
|
|
1195
|
+
expectedType: "sw",
|
|
1196
|
+
expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
|
|
1197
|
+
expectedBindings: [
|
|
1198
|
+
{ name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
|
|
1199
|
+
],
|
|
1200
|
+
});
|
|
1201
|
+
mockSubDomainRequest();
|
|
1202
|
+
await runWrangler("publish index.js --config ./path/to/wrangler.toml");
|
|
1203
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1204
|
+
"Uploaded
|
|
1205
|
+
test-name
|
|
1206
|
+
(TIMINGS)
|
|
1207
|
+
Deployed
|
|
1208
|
+
test-name
|
|
1209
|
+
(TIMINGS)
|
|
1210
|
+
|
|
1211
|
+
test-name.test-sub-domain.workers.dev"
|
|
1212
|
+
`);
|
|
1213
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1214
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1215
|
+
});
|
|
1216
|
+
});
|
|
1217
|
+
});
|
|
1218
|
+
|
|
1219
|
+
/** Write a mock wrangler.toml file to disk. */
|
|
1220
|
+
function writeWranglerToml(config: Omit<Config, "env"> = {}) {
|
|
1221
|
+
// We Omit `env` from config because TOML.stringify() appears to
|
|
1222
|
+
// have a weird type signature that appears to fail. We'll revisit this
|
|
1223
|
+
// when we write tests for publishing environments
|
|
1224
|
+
fs.writeFileSync(
|
|
1225
|
+
"./wrangler.toml",
|
|
1226
|
+
TOML.stringify({
|
|
1227
|
+
compatibility_date: "2022-01-12",
|
|
1228
|
+
name: "test-name",
|
|
1229
|
+
...config,
|
|
1230
|
+
}),
|
|
1231
|
+
|
|
1232
|
+
"utf-8"
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
/** Write a mock Worker script to disk. */
|
|
1237
|
+
function writeWorkerSource({
|
|
1238
|
+
basePath = ".",
|
|
1239
|
+
format = "js",
|
|
1240
|
+
type = "esm",
|
|
1241
|
+
}: {
|
|
1242
|
+
basePath?: string;
|
|
1243
|
+
format?: "js" | "ts" | "jsx" | "tsx" | "mjs";
|
|
1244
|
+
type?: "esm" | "sw";
|
|
1245
|
+
} = {}) {
|
|
1246
|
+
if (basePath !== ".") {
|
|
1247
|
+
fs.mkdirSync(basePath, { recursive: true });
|
|
1248
|
+
}
|
|
1249
|
+
fs.writeFileSync(
|
|
1250
|
+
`${basePath}/index.${format}`,
|
|
1251
|
+
type === "esm"
|
|
1252
|
+
? `import { foo } from "./another";
|
|
1253
|
+
export default {
|
|
1254
|
+
async fetch(request) {
|
|
1255
|
+
return new Response('Hello' + foo);
|
|
1256
|
+
},
|
|
1257
|
+
};`
|
|
1258
|
+
: `import { foo } from "./another";
|
|
1259
|
+
addEventListener('fetch', event => {
|
|
1260
|
+
event.respondWith(new Response('Hello' + foo));
|
|
1261
|
+
})`
|
|
1262
|
+
);
|
|
1263
|
+
fs.writeFileSync(`${basePath}/another.${format}`, `export const foo = 100;`);
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/** Write mock assets to the file system so they can be uploaded. */
|
|
1267
|
+
function writeAssets(assets: { filePath: string; content: string }[]) {
|
|
1268
|
+
for (const asset of assets) {
|
|
1269
|
+
fs.mkdirSync(path.dirname(asset.filePath), { recursive: true });
|
|
1270
|
+
fs.writeFileSync(asset.filePath, asset.content);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
/** Create a mock handler for the request to upload a worker script. */
|
|
1275
|
+
function mockUploadWorkerRequest({
|
|
1276
|
+
available_on_subdomain = true,
|
|
1277
|
+
expectedEntry,
|
|
1278
|
+
expectedType = "esm",
|
|
1279
|
+
expectedBindings,
|
|
1280
|
+
expectedModules = {},
|
|
1281
|
+
env = undefined,
|
|
1282
|
+
}: {
|
|
1283
|
+
available_on_subdomain?: boolean;
|
|
1284
|
+
expectedEntry?: string;
|
|
1285
|
+
expectedType?: "esm" | "sw";
|
|
1286
|
+
expectedBindings?: unknown;
|
|
1287
|
+
expectedModules?: Record<string, string>;
|
|
1288
|
+
env?: string | undefined;
|
|
1289
|
+
} = {}) {
|
|
1290
|
+
setMockResponse(
|
|
1291
|
+
env
|
|
1292
|
+
? `/accounts/:accountId/workers/services/:scriptName/environments/:envName`
|
|
1293
|
+
: "/accounts/:accountId/workers/scripts/:scriptName",
|
|
1294
|
+
"PUT",
|
|
1295
|
+
async ([_url, accountId, scriptName], { body }, queryParams) => {
|
|
1296
|
+
expect(accountId).toEqual("some-account-id");
|
|
1297
|
+
expect(scriptName).toEqual("test-name");
|
|
1298
|
+
expect(queryParams.get("available_on_subdomains")).toEqual("true");
|
|
1299
|
+
const formBody = body as FormData;
|
|
1300
|
+
if (expectedEntry !== undefined) {
|
|
1301
|
+
expect(await (formBody.get("index.js") as File).text()).toMatch(
|
|
1302
|
+
expectedEntry
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const metadata = JSON.parse(
|
|
1307
|
+
formBody.get("metadata") as string
|
|
1308
|
+
) as WorkerMetadata;
|
|
1309
|
+
if (expectedType === "esm") {
|
|
1310
|
+
expect(metadata.main_module).toEqual("index.js");
|
|
1311
|
+
} else {
|
|
1312
|
+
expect(metadata.body_part).toEqual("index.js");
|
|
1313
|
+
}
|
|
1314
|
+
if (expectedBindings !== undefined) {
|
|
1315
|
+
expect(metadata.bindings).toEqual(expectedBindings);
|
|
1316
|
+
}
|
|
1317
|
+
for (const [name, content] of Object.entries(expectedModules)) {
|
|
1318
|
+
expect(await (formBody.get(name) as File).text()).toMatch(content);
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
return { available_on_subdomain };
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/** Create a mock handler for the request to get the account's subdomain. */
|
|
1327
|
+
function mockSubDomainRequest(subdomain = "test-sub-domain") {
|
|
1328
|
+
setMockResponse("/accounts/:accountId/workers/subdomain", () => {
|
|
1329
|
+
return { subdomain };
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/** Create a mock handler for the request to get a list of all KV namespaces. */
|
|
1334
|
+
function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
|
|
1335
|
+
setMockResponse(
|
|
1336
|
+
"/accounts/:accountId/storage/kv/namespaces",
|
|
1337
|
+
"GET",
|
|
1338
|
+
([_url, accountId]) => {
|
|
1339
|
+
expect(accountId).toEqual("some-account-id");
|
|
1340
|
+
return namespaces;
|
|
1341
|
+
}
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
/** Create a mock handler for the request that tries to do a bulk upload of assets to a KV namespace. */
|
|
1346
|
+
function mockUploadAssetsToKVRequest(
|
|
1347
|
+
expectedNamespaceId: string,
|
|
1348
|
+
assets: { filePath: string; content: string }[]
|
|
1349
|
+
) {
|
|
1350
|
+
setMockResponse(
|
|
1351
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1352
|
+
"PUT",
|
|
1353
|
+
([_url, accountId, namespaceId], { body }) => {
|
|
1354
|
+
expect(accountId).toEqual("some-account-id");
|
|
1355
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1356
|
+
const uploads = JSON.parse(body as string);
|
|
1357
|
+
expect(assets.length).toEqual(uploads.length);
|
|
1358
|
+
for (let i = 0; i < uploads.length; i++) {
|
|
1359
|
+
const asset = assets[i];
|
|
1360
|
+
const upload = uploads[i];
|
|
1361
|
+
// The asset key consists of:
|
|
1362
|
+
// - the basename of the filepath
|
|
1363
|
+
// - some hash value
|
|
1364
|
+
// - the extension
|
|
1365
|
+
const keyMatcher = new RegExp(
|
|
1366
|
+
"^" +
|
|
1367
|
+
asset.filePath
|
|
1368
|
+
.replace(/(\.[^.]+)$/, ".[a-z0-9]+$1")
|
|
1369
|
+
.replace(/\./g, "\\.")
|
|
1370
|
+
);
|
|
1371
|
+
expect(upload.key).toMatch(keyMatcher);
|
|
1372
|
+
// The asset value is base64 encoded.
|
|
1373
|
+
expect(upload.base64).toBe(true);
|
|
1374
|
+
expect(Buffer.from(upload.value, "base64").toString()).toEqual(
|
|
1375
|
+
asset.content
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
return null;
|
|
1379
|
+
}
|
|
1380
|
+
);
|
|
1381
|
+
}
|