wrangler 0.0.0-e043479 → 0.0.0-e0489587

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/README.md +47 -16
  2. package/bin/wrangler.js +95 -32
  3. package/config-schema.json +3059 -0
  4. package/kv-asset-handler.js +1 -0
  5. package/package.json +148 -89
  6. package/templates/__tests__/pages-dev-util.test.ts +128 -0
  7. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  8. package/templates/__tests__/tsconfig.json +8 -0
  9. package/templates/checked-fetch.js +30 -0
  10. package/templates/facade.d.ts +19 -0
  11. package/templates/gitignore +170 -0
  12. package/templates/init-tests/test-jest-new-worker.js +23 -0
  13. package/templates/init-tests/test-vitest-new-worker.js +24 -0
  14. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  15. package/templates/middleware/common.ts +67 -0
  16. package/templates/middleware/loader-modules.ts +134 -0
  17. package/templates/middleware/loader-sw.ts +229 -0
  18. package/templates/middleware/middleware-ensure-req-body-drained.ts +18 -0
  19. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  20. package/templates/middleware/middleware-pretty-error.ts +40 -0
  21. package/templates/middleware/middleware-scheduled.ts +15 -0
  22. package/templates/middleware/middleware-serve-static-assets.d.ts +6 -0
  23. package/templates/middleware/middleware-serve-static-assets.ts +56 -0
  24. package/templates/modules-watch-stub.js +4 -0
  25. package/templates/new-worker-scheduled.js +17 -0
  26. package/templates/new-worker-scheduled.ts +32 -0
  27. package/templates/new-worker.js +3 -3
  28. package/templates/new-worker.ts +22 -4
  29. package/templates/no-op-worker.js +10 -0
  30. package/templates/pages-dev-pipeline.ts +32 -0
  31. package/templates/pages-dev-util.ts +55 -0
  32. package/templates/pages-shim.ts +9 -0
  33. package/templates/pages-template-plugin.ts +190 -0
  34. package/templates/pages-template-worker.ts +198 -0
  35. package/templates/startDevWorker/InspectorProxyWorker.ts +664 -0
  36. package/templates/startDevWorker/ProxyWorker.ts +334 -0
  37. package/templates/tsconfig-sanity.ts +11 -0
  38. package/templates/tsconfig.init.json +105 -0
  39. package/templates/tsconfig.json +6 -103
  40. package/wrangler-dist/InspectorProxyWorker.js +464 -0
  41. package/wrangler-dist/InspectorProxyWorker.js.map +6 -0
  42. package/wrangler-dist/ProxyWorker.js +240 -0
  43. package/wrangler-dist/ProxyWorker.js.map +6 -0
  44. package/wrangler-dist/cli.d.ts +26375 -0
  45. package/wrangler-dist/cli.js +202160 -132057
  46. package/wrangler-dist/wasm-sync.wasm +0 -0
  47. package/import_meta_url.js +0 -3
  48. package/miniflare-config-stubs/.env.empty +0 -0
  49. package/miniflare-config-stubs/package.empty.json +0 -1
  50. package/miniflare-config-stubs/wrangler.empty.toml +0 -0
  51. package/pages/functions/buildWorker.ts +0 -62
  52. package/pages/functions/filepath-routing.test.ts +0 -123
  53. package/pages/functions/filepath-routing.ts +0 -178
  54. package/pages/functions/identifiers.ts +0 -78
  55. package/pages/functions/routes.ts +0 -151
  56. package/pages/functions/template-worker.ts +0 -130
  57. package/src/__tests__/configuration.test.ts +0 -2186
  58. package/src/__tests__/dev.test.tsx +0 -247
  59. package/src/__tests__/guess-worker-format.test.ts +0 -66
  60. package/src/__tests__/helpers/clipboardy-mock.js +0 -4
  61. package/src/__tests__/helpers/cmd-shim.d.ts +0 -11
  62. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  63. package/src/__tests__/helpers/mock-account-id.ts +0 -44
  64. package/src/__tests__/helpers/mock-bin.ts +0 -36
  65. package/src/__tests__/helpers/mock-cfetch.ts +0 -207
  66. package/src/__tests__/helpers/mock-console.ts +0 -70
  67. package/src/__tests__/helpers/mock-dialogs.ts +0 -65
  68. package/src/__tests__/helpers/mock-kv.ts +0 -40
  69. package/src/__tests__/helpers/mock-stdin.ts +0 -103
  70. package/src/__tests__/helpers/mock-user.ts +0 -27
  71. package/src/__tests__/helpers/mock-web-socket.ts +0 -29
  72. package/src/__tests__/helpers/run-in-tmp.ts +0 -29
  73. package/src/__tests__/helpers/run-wrangler.ts +0 -16
  74. package/src/__tests__/helpers/write-wrangler-toml.ts +0 -17
  75. package/src/__tests__/index.test.ts +0 -866
  76. package/src/__tests__/jest.setup.ts +0 -69
  77. package/src/__tests__/kv.test.ts +0 -1408
  78. package/src/__tests__/logout.test.ts +0 -50
  79. package/src/__tests__/package-manager.test.ts +0 -206
  80. package/src/__tests__/parse.test.ts +0 -322
  81. package/src/__tests__/publish.test.ts +0 -2139
  82. package/src/__tests__/r2.test.ts +0 -198
  83. package/src/__tests__/secret.test.ts +0 -425
  84. package/src/__tests__/sentry.test.ts +0 -146
  85. package/src/__tests__/tail.test.ts +0 -564
  86. package/src/__tests__/whoami.test.tsx +0 -86
  87. package/src/api/form_data.ts +0 -217
  88. package/src/api/preview.ts +0 -147
  89. package/src/api/worker.ts +0 -186
  90. package/src/bundle.ts +0 -133
  91. package/src/cfetch/index.ts +0 -104
  92. package/src/cfetch/internal.ts +0 -133
  93. package/src/cli.ts +0 -19
  94. package/src/config/README.md +0 -107
  95. package/src/config/config.ts +0 -270
  96. package/src/config/diagnostics.ts +0 -80
  97. package/src/config/environment.ts +0 -305
  98. package/src/config/index.ts +0 -52
  99. package/src/config/validation-helpers.ts +0 -370
  100. package/src/config/validation.ts +0 -1019
  101. package/src/dev.tsx +0 -960
  102. package/src/dialogs.tsx +0 -77
  103. package/src/entry.ts +0 -57
  104. package/src/environment-variables.ts +0 -33
  105. package/src/guess-worker-format.ts +0 -68
  106. package/src/index.tsx +0 -2302
  107. package/src/inspect.ts +0 -609
  108. package/src/kv.tsx +0 -339
  109. package/src/module-collection.ts +0 -170
  110. package/src/open-in-browser.ts +0 -13
  111. package/src/package-manager.ts +0 -126
  112. package/src/pages.tsx +0 -1045
  113. package/src/parse.ts +0 -183
  114. package/src/paths.ts +0 -26
  115. package/src/proxy.ts +0 -376
  116. package/src/publish.ts +0 -363
  117. package/src/r2.ts +0 -50
  118. package/src/reporting.ts +0 -115
  119. package/src/sites.tsx +0 -238
  120. package/src/tail/filters.ts +0 -279
  121. package/src/tail/index.ts +0 -299
  122. package/src/tail/printing.ts +0 -62
  123. package/src/user.tsx +0 -1063
  124. package/src/whoami.tsx +0 -69
  125. package/templates/static-asset-facade.js +0 -47
  126. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  127. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  128. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  129. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  130. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  131. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  132. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  133. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  134. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  135. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  136. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  137. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  138. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  139. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  140. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  141. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  142. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  143. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  144. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  145. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  146. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  147. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  148. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  149. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  150. package/vendor/wrangler-mime/LICENSE +0 -21
  151. package/vendor/wrangler-mime/Mime.js +0 -97
  152. package/vendor/wrangler-mime/README.md +0 -187
  153. package/vendor/wrangler-mime/cli.js +0 -46
  154. package/vendor/wrangler-mime/index.js +0 -4
  155. package/vendor/wrangler-mime/lite.js +0 -4
  156. package/vendor/wrangler-mime/package.json +0 -52
  157. package/vendor/wrangler-mime/types/other.js +0 -1
  158. package/vendor/wrangler-mime/types/standard.js +0 -1
  159. package/wrangler-dist/cli.js.map +0 -7
@@ -1,2139 +0,0 @@
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 writeWranglerToml from "./helpers/write-wrangler-toml";
11
- import type { WorkerMetadata } from "../api/form_data";
12
- import type { Config } from "../config";
13
- import type { KVNamespaceInfo } from "../kv";
14
- import type { FormData, File } from "undici";
15
-
16
- describe("publish", () => {
17
- beforeEach(() => {
18
- // @ts-expect-error we're using a very simple setTimeout mock here
19
- jest.spyOn(global, "setTimeout").mockImplementation((fn, _period) => {
20
- fn();
21
- });
22
- });
23
- mockAccountId();
24
- mockApiToken();
25
- runInTempDir();
26
- const std = mockConsoleMethods();
27
-
28
- afterEach(() => {
29
- unsetAllMocks();
30
- });
31
-
32
- describe("environments", () => {
33
- it("should use legacy environments by default", async () => {
34
- writeWranglerToml();
35
- writeWorkerSource();
36
- mockSubDomainRequest();
37
- mockUploadWorkerRequest({
38
- env: "some-env",
39
- legacyEnv: true,
40
- });
41
- await runWrangler("publish index.js --env some-env");
42
- expect(std.out).toMatchInlineSnapshot(`
43
- "Uploaded test-name-some-env (TIMINGS)
44
- Published test-name-some-env (TIMINGS)
45
- test-name-some-env.test-sub-domain.workers.dev"
46
- `);
47
- expect(std.err).toMatchInlineSnapshot(`""`);
48
- expect(std.warn).toMatchInlineSnapshot(`""`);
49
- });
50
-
51
- describe("legacy", () => {
52
- it("uses the script name when no environment is specified", async () => {
53
- writeWranglerToml();
54
- writeWorkerSource();
55
- mockSubDomainRequest();
56
- mockUploadWorkerRequest({
57
- legacyEnv: true,
58
- });
59
- await runWrangler("publish index.js --legacy-env true");
60
- expect(std.out).toMatchInlineSnapshot(`
61
- "Uploaded test-name (TIMINGS)
62
- Published test-name (TIMINGS)
63
- test-name.test-sub-domain.workers.dev"
64
- `);
65
- expect(std.err).toMatchInlineSnapshot(`""`);
66
- expect(std.warn).toMatchInlineSnapshot(`""`);
67
- });
68
-
69
- it("appends the environment name when provided", async () => {
70
- writeWranglerToml();
71
- writeWorkerSource();
72
- mockSubDomainRequest();
73
- mockUploadWorkerRequest({
74
- env: "some-env",
75
- legacyEnv: true,
76
- });
77
- await runWrangler("publish index.js --env some-env --legacy-env true");
78
- expect(std.out).toMatchInlineSnapshot(`
79
- "Uploaded test-name-some-env (TIMINGS)
80
- Published test-name-some-env (TIMINGS)
81
- test-name-some-env.test-sub-domain.workers.dev"
82
- `);
83
- expect(std.err).toMatchInlineSnapshot(`""`);
84
- expect(std.warn).toMatchInlineSnapshot(`""`);
85
- });
86
- });
87
-
88
- describe("services", () => {
89
- it("uses the script name when no environment is specified", async () => {
90
- writeWranglerToml();
91
- writeWorkerSource();
92
- mockSubDomainRequest();
93
- mockUploadWorkerRequest({
94
- legacyEnv: false,
95
- });
96
- await runWrangler("publish index.js");
97
- expect(std.out).toMatchInlineSnapshot(`
98
- "Uploaded test-name (TIMINGS)
99
- Published test-name (TIMINGS)
100
- test-name.test-sub-domain.workers.dev"
101
- `);
102
- expect(std.err).toMatchInlineSnapshot(`""`);
103
- expect(std.warn).toMatchInlineSnapshot(`""`);
104
- });
105
-
106
- it("publishes as an environment when provided", async () => {
107
- writeWranglerToml();
108
- writeWorkerSource();
109
- mockSubDomainRequest();
110
- mockUploadWorkerRequest({
111
- env: "some-env",
112
- legacyEnv: false,
113
- });
114
- await runWrangler("publish index.js --env some-env --legacy-env false");
115
- expect(std.out).toMatchInlineSnapshot(`
116
- "Uploaded test-name (some-env) (TIMINGS)
117
- Published test-name (some-env) (TIMINGS)
118
- some-env.test-name.test-sub-domain.workers.dev"
119
- `);
120
- expect(std.err).toMatchInlineSnapshot(`""`);
121
- expect(std.warn).toMatchInlineSnapshot(`""`);
122
- });
123
- });
124
- });
125
-
126
- it("should resolve wrangler.toml relative to the entrypoint", async () => {
127
- fs.mkdirSync("./some-path/worker", { recursive: true });
128
- fs.writeFileSync(
129
- "./some-path/wrangler.toml",
130
- TOML.stringify({
131
- name: "test-name",
132
- compatibility_date: "2022-01-12",
133
- vars: { xyz: 123 },
134
- }),
135
- "utf-8"
136
- );
137
- writeWorkerSource({ basePath: "./some-path/worker" });
138
- mockUploadWorkerRequest({
139
- expectedBindings: [
140
- {
141
- json: 123,
142
- name: "xyz",
143
- type: "json",
144
- },
145
- ],
146
- });
147
- mockSubDomainRequest();
148
- await runWrangler("publish ./some-path/worker/index.js");
149
- expect(std.out).toMatchInlineSnapshot(`
150
- "Uploaded test-name (TIMINGS)
151
- Published test-name (TIMINGS)
152
- test-name.test-sub-domain.workers.dev"
153
- `);
154
- expect(std.err).toMatchInlineSnapshot(`""`);
155
- });
156
-
157
- describe("routes", () => {
158
- it("should publish the worker to a route", async () => {
159
- writeWranglerToml({
160
- routes: ["example.com/some-route/*"],
161
- });
162
- writeWorkerSource();
163
- mockUpdateWorkerRequest({ enabled: false });
164
- mockUploadWorkerRequest({ expectedType: "esm" });
165
- mockPublishRoutesRequest({ routes: ["example.com/some-route/*"] });
166
- await runWrangler("publish ./index");
167
- });
168
-
169
- it("should publish to legacy environment specific routes", async () => {
170
- writeWranglerToml({
171
- routes: ["example.com/some-route/*"],
172
- env: {
173
- dev: {
174
- routes: ["dev-example.com/some-route/*"],
175
- },
176
- },
177
- });
178
- writeWorkerSource();
179
- mockUpdateWorkerRequest({ enabled: false, legacyEnv: true, env: "dev" });
180
- mockUploadWorkerRequest({
181
- expectedType: "esm",
182
- legacyEnv: true,
183
- env: "dev",
184
- });
185
- mockPublishRoutesRequest({
186
- routes: ["dev-example.com/some-route/*"],
187
- legacyEnv: true,
188
- env: "dev",
189
- });
190
- await runWrangler("publish ./index --env dev --legacy-env true");
191
- });
192
-
193
- it("services: should publish to service environment specific routes", async () => {
194
- writeWranglerToml({
195
- routes: ["example.com/some-route/*"],
196
- env: {
197
- dev: {
198
- routes: ["dev-example.com/some-route/*"],
199
- },
200
- },
201
- });
202
- writeWorkerSource();
203
- mockUpdateWorkerRequest({ enabled: false, env: "dev" });
204
- mockUploadWorkerRequest({
205
- expectedType: "esm",
206
- env: "dev",
207
- });
208
- mockPublishRoutesRequest({
209
- routes: ["dev-example.com/some-route/*"],
210
- env: "dev",
211
- });
212
- await runWrangler("publish ./index --env dev --legacy-env false");
213
- });
214
-
215
- it.todo("should error if it's a workers.dev route");
216
- });
217
-
218
- describe("entry-points", () => {
219
- it("should be able to use `index` with no extension as the entry-point (esm)", async () => {
220
- writeWranglerToml();
221
- writeWorkerSource();
222
- mockUploadWorkerRequest({ expectedType: "esm" });
223
- mockSubDomainRequest();
224
-
225
- await runWrangler("publish ./index");
226
-
227
- expect(std.out).toMatchInlineSnapshot(`
228
- "Uploaded test-name (TIMINGS)
229
- Published test-name (TIMINGS)
230
- test-name.test-sub-domain.workers.dev"
231
- `);
232
- expect(std.err).toMatchInlineSnapshot(`""`);
233
- });
234
-
235
- it("should be able to use `index` with no extension as the entry-point (sw)", async () => {
236
- writeWranglerToml();
237
- writeWorkerSource({ type: "sw" });
238
- mockUploadWorkerRequest({ expectedType: "sw" });
239
- mockSubDomainRequest();
240
-
241
- await runWrangler("publish ./index");
242
-
243
- expect(std.out).toMatchInlineSnapshot(`
244
- "Uploaded test-name (TIMINGS)
245
- Published test-name (TIMINGS)
246
- test-name.test-sub-domain.workers.dev"
247
- `);
248
- expect(std.err).toMatchInlineSnapshot(`""`);
249
- });
250
-
251
- it("should be able to use the `main` config as the entry-point for ESM sources", async () => {
252
- writeWranglerToml({ main: "./index.js" });
253
- writeWorkerSource();
254
- mockUploadWorkerRequest();
255
- mockSubDomainRequest();
256
-
257
- await runWrangler("publish");
258
-
259
- expect(std.out).toMatchInlineSnapshot(`
260
- "Uploaded test-name (TIMINGS)
261
- Published test-name (TIMINGS)
262
- test-name.test-sub-domain.workers.dev"
263
- `);
264
- expect(std.err).toMatchInlineSnapshot(`""`);
265
- });
266
-
267
- it("should use `main` relative to the wrangler.toml not cwd", async () => {
268
- writeWranglerToml({
269
- main: "./foo/index.js",
270
- });
271
- writeWorkerSource({ basePath: "foo" });
272
- mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
273
- mockSubDomainRequest();
274
- process.chdir("foo");
275
- await runWrangler("publish");
276
-
277
- expect(std.out).toMatchInlineSnapshot(`
278
- "Uploaded test-name (TIMINGS)
279
- Published test-name (TIMINGS)
280
- test-name.test-sub-domain.workers.dev"
281
- `);
282
- expect(std.err).toMatchInlineSnapshot(`""`);
283
- });
284
-
285
- it('should use `build.upload.main` as an entry point, where `build.upload.dir` defaults to "./dist", and log a deprecation warning', async () => {
286
- writeWranglerToml({ build: { upload: { main: "./index.js" } } });
287
- writeWorkerSource({ basePath: "./dist" });
288
- mockUploadWorkerRequest();
289
- mockSubDomainRequest();
290
-
291
- await runWrangler("publish");
292
-
293
- expect(std.out).toMatchInlineSnapshot(`
294
- "Uploaded test-name (TIMINGS)
295
- Published test-name (TIMINGS)
296
- test-name.test-sub-domain.workers.dev"
297
- `);
298
- expect(std.err).toMatchInlineSnapshot(`""`);
299
- expect(std.warn).toMatchInlineSnapshot(`
300
- "Processing wrangler.toml configuration:
301
- - DEPRECATION: \\"build.upload.main\\":
302
- Delete the \`build.upload.main\` and \`build.upload.dir\` fields.
303
- Then add the top level \`main\` field to your configuration file:
304
- \`\`\`
305
- main = \\"dist/index.js\\"
306
- \`\`\`"
307
- `);
308
- });
309
-
310
- it("should use `build.upload.main` relative to `build.upload.dir`", async () => {
311
- writeWranglerToml({
312
- build: {
313
- upload: {
314
- main: "./index.js",
315
- dir: "./foo",
316
- },
317
- },
318
- });
319
- writeWorkerSource({ basePath: "./foo" });
320
- mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
321
- mockSubDomainRequest();
322
- process.chdir("foo");
323
- await runWrangler("publish");
324
-
325
- expect(std.out).toMatchInlineSnapshot(`
326
- "Uploaded test-name (TIMINGS)
327
- Published test-name (TIMINGS)
328
- test-name.test-sub-domain.workers.dev"
329
- `);
330
- expect(std.err).toMatchInlineSnapshot(`""`);
331
- expect(std.warn).toMatchInlineSnapshot(`
332
- "Processing ../wrangler.toml configuration:
333
- - DEPRECATION: \\"build.upload.main\\":
334
- Delete the \`build.upload.main\` and \`build.upload.dir\` fields.
335
- Then add the top level \`main\` field to your configuration file:
336
- \`\`\`
337
- main = \\"foo/index.js\\"
338
- \`\`\`
339
- - DEPRECATION: \\"build.upload.dir\\":
340
- Use the top level \\"main\\" field or a command-line argument to specify the entry-point for the Worker."
341
- `);
342
- });
343
-
344
- it("should error when both `main` and `build.upload.main` are used", async () => {
345
- writeWranglerToml({
346
- main: "./index.js",
347
- build: {
348
- upload: {
349
- main: "./index.js",
350
- dir: "./foo",
351
- },
352
- },
353
- });
354
- await expect(runWrangler("publish")).rejects
355
- .toThrowErrorMatchingInlineSnapshot(`
356
- "Processing wrangler.toml configuration:
357
- - Don't define both the \`main\` and \`build.upload.main\` fields in your configuration.
358
- They serve the same purpose: to point to the entry-point of your worker.
359
- Delete the \`build.upload.main\` and \`build.upload.dir\` field from your config."
360
- `);
361
- });
362
-
363
- it("should be able to transpile TypeScript (esm)", async () => {
364
- writeWranglerToml();
365
- writeWorkerSource({ format: "ts" });
366
- mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
367
- mockSubDomainRequest();
368
- await runWrangler("publish index.ts");
369
-
370
- expect(std.out).toMatchInlineSnapshot(`
371
- "Uploaded test-name (TIMINGS)
372
- Published test-name (TIMINGS)
373
- test-name.test-sub-domain.workers.dev"
374
- `);
375
- expect(std.err).toMatchInlineSnapshot(`""`);
376
- });
377
-
378
- it("should be able to transpile TypeScript (sw)", async () => {
379
- writeWranglerToml();
380
- writeWorkerSource({ format: "ts", type: "sw" });
381
- mockUploadWorkerRequest({
382
- expectedEntry: "var foo = 100;",
383
- expectedType: "sw",
384
- });
385
- mockSubDomainRequest();
386
- await runWrangler("publish index.ts");
387
-
388
- expect(std.out).toMatchInlineSnapshot(`
389
- "Uploaded test-name (TIMINGS)
390
- Published test-name (TIMINGS)
391
- test-name.test-sub-domain.workers.dev"
392
- `);
393
- expect(std.err).toMatchInlineSnapshot(`""`);
394
- });
395
-
396
- it("should add referenced text modules into the form upload", async () => {
397
- writeWranglerToml();
398
- fs.writeFileSync(
399
- "./index.js",
400
- `
401
- import txt from './textfile.txt';
402
- export default{
403
- fetch(){
404
- return new Response(txt);
405
- }
406
- }
407
- `
408
- );
409
- fs.writeFileSync("./textfile.txt", "Hello, World!");
410
- mockUploadWorkerRequest({
411
- expectedModules: {
412
- "./0a0a9f2a6772942557ab5355d76af442f8f65e01-textfile.txt":
413
- "Hello, World!",
414
- },
415
- });
416
- mockSubDomainRequest();
417
- await runWrangler("publish index.js");
418
- expect(std.out).toMatchInlineSnapshot(`
419
- "Uploaded test-name (TIMINGS)
420
- Published test-name (TIMINGS)
421
- test-name.test-sub-domain.workers.dev"
422
- `);
423
- expect(std.err).toMatchInlineSnapshot(`""`);
424
- });
425
-
426
- it("should be able to transpile entry-points in sub-directories (esm)", async () => {
427
- writeWranglerToml();
428
- writeWorkerSource({ basePath: "./src" });
429
- mockUploadWorkerRequest({ expectedEntry: "var foo = 100;" });
430
- mockSubDomainRequest();
431
-
432
- await runWrangler("publish ./src/index.js");
433
-
434
- expect(std.out).toMatchInlineSnapshot(`
435
- "Uploaded test-name (TIMINGS)
436
- Published test-name (TIMINGS)
437
- test-name.test-sub-domain.workers.dev"
438
- `);
439
- expect(std.err).toMatchInlineSnapshot(`""`);
440
- });
441
-
442
- it("should be able to transpile entry-points in sub-directories (sw)", async () => {
443
- writeWranglerToml();
444
- writeWorkerSource({ basePath: "./src", type: "sw" });
445
- mockUploadWorkerRequest({
446
- expectedEntry: "var foo = 100;",
447
- expectedType: "sw",
448
- });
449
- mockSubDomainRequest();
450
-
451
- await runWrangler("publish ./src/index.js");
452
-
453
- expect(std.out).toMatchInlineSnapshot(`
454
- "Uploaded test-name (TIMINGS)
455
- Published test-name (TIMINGS)
456
- test-name.test-sub-domain.workers.dev"
457
- `);
458
- expect(std.err).toMatchInlineSnapshot(`""`);
459
- });
460
-
461
- it('should error if a site definition doesn\'t have a "bucket" field', async () => {
462
- writeWranglerToml({
463
- site: {
464
- "entry-point": "./index.js",
465
- } as Config["site"],
466
- });
467
- writeWorkerSource();
468
- mockUploadWorkerRequest();
469
- mockSubDomainRequest();
470
-
471
- await expect(runWrangler("publish ./index.js")).rejects
472
- .toThrowErrorMatchingInlineSnapshot(`
473
- "Processing wrangler.toml configuration:
474
- - ERROR: \\"site.bucket\\" is a required field."
475
- `);
476
-
477
- expect(std.out).toMatchInlineSnapshot(`""`);
478
- expect(std.err).toMatchInlineSnapshot(`
479
- "Processing wrangler.toml configuration:
480
- - ERROR: \\"site.bucket\\" is a required field.
481
-
482
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
483
- `);
484
- expect(std.warn).toMatchInlineSnapshot(`""`);
485
- });
486
-
487
- it("should warn if there is a `site.entry-point` configuration", async () => {
488
- const assets = [
489
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
490
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
491
- ];
492
- const kvNamespace = {
493
- title: "__test-name-workers_sites_assets",
494
- id: "__test-name-workers_sites_assets-id",
495
- };
496
-
497
- writeWranglerToml({
498
- site: {
499
- "entry-point": "./index.js",
500
- bucket: "assets",
501
- },
502
- });
503
- writeWorkerSource();
504
- writeAssets(assets);
505
- mockUploadWorkerRequest();
506
- mockSubDomainRequest();
507
- mockListKVNamespacesRequest(kvNamespace);
508
- mockKeyListRequest(kvNamespace.id, []);
509
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
510
-
511
- await runWrangler("publish ./index.js");
512
-
513
- expect(std.out).toMatchInlineSnapshot(`
514
- "reading assets/file-1.txt...
515
- uploading as assets/file-1.2ca234f380.txt...
516
- reading assets/file-2.txt...
517
- uploading as assets/file-2.5938485188.txt...
518
- Uploaded test-name (TIMINGS)
519
- Published test-name (TIMINGS)
520
- test-name.test-sub-domain.workers.dev"
521
- `);
522
- expect(std.err).toMatchInlineSnapshot(`""`);
523
- expect(std.warn).toMatchInlineSnapshot(`
524
- "Deprecation notice: The \`site.entry-point\` config field is no longer used.
525
- The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
526
- Please remove the \`site.entry-point\` field from the \`wrangler.toml\` file."
527
- `);
528
- });
529
-
530
- it("should error if there is no entry-point specified", async () => {
531
- writeWranglerToml();
532
- writeWorkerSource();
533
- mockUploadWorkerRequest();
534
- mockSubDomainRequest();
535
- await expect(
536
- runWrangler("publish")
537
- ).rejects.toThrowErrorMatchingInlineSnapshot(
538
- `"Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field."`
539
- );
540
-
541
- expect(std.out).toMatchInlineSnapshot(`""`);
542
- expect(std.err).toMatchInlineSnapshot(`
543
- "Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
544
-
545
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
546
- `);
547
- });
548
- });
549
-
550
- describe("asset upload", () => {
551
- it("should upload all the files in the directory specified by `config.site.bucket`", async () => {
552
- const assets = [
553
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
554
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
555
- ];
556
- const kvNamespace = {
557
- title: "__test-name-workers_sites_assets",
558
- id: "__test-name-workers_sites_assets-id",
559
- };
560
- writeWranglerToml({
561
- main: "./index.js",
562
- site: {
563
- bucket: "assets",
564
- },
565
- });
566
- writeWorkerSource();
567
- writeAssets(assets);
568
- mockUploadWorkerRequest();
569
- mockSubDomainRequest();
570
- mockListKVNamespacesRequest(kvNamespace);
571
- mockKeyListRequest(kvNamespace.id, []);
572
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
573
- await runWrangler("publish");
574
-
575
- expect(std.out).toMatchInlineSnapshot(`
576
- "reading assets/file-1.txt...
577
- uploading as assets/file-1.2ca234f380.txt...
578
- reading assets/file-2.txt...
579
- uploading as assets/file-2.5938485188.txt...
580
- Uploaded test-name (TIMINGS)
581
- Published test-name (TIMINGS)
582
- test-name.test-sub-domain.workers.dev"
583
- `);
584
- expect(std.err).toMatchInlineSnapshot(`""`);
585
- });
586
-
587
- it("when using a service worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
588
- const assets = [
589
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
590
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
591
- ];
592
- const kvNamespace = {
593
- title: "__test-name-workers_sites_assets",
594
- id: "__test-name-workers_sites_assets-id",
595
- };
596
- writeWranglerToml({
597
- main: "./index.js",
598
- site: {
599
- bucket: "assets",
600
- },
601
- });
602
- writeWorkerSource({ type: "sw" });
603
- writeAssets(assets);
604
- mockUploadWorkerRequest({
605
- expectedType: "sw",
606
- expectedModules: {
607
- __STATIC_CONTENT_MANIFEST:
608
- '{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
609
- },
610
- expectedBindings: [
611
- {
612
- name: "__STATIC_CONTENT",
613
- namespace_id: "__test-name-workers_sites_assets-id",
614
- type: "kv_namespace",
615
- },
616
- {
617
- name: "__STATIC_CONTENT_MANIFEST",
618
- part: "__STATIC_CONTENT_MANIFEST",
619
- type: "text_blob",
620
- },
621
- ],
622
- });
623
- mockSubDomainRequest();
624
- mockListKVNamespacesRequest(kvNamespace);
625
- mockKeyListRequest(kvNamespace.id, []);
626
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
627
-
628
- await runWrangler("publish");
629
-
630
- expect(std.out).toMatchInlineSnapshot(`
631
- "reading assets/file-1.txt...
632
- uploading as assets/file-1.2ca234f380.txt...
633
- reading assets/file-2.txt...
634
- uploading as assets/file-2.5938485188.txt...
635
- Uploaded test-name (TIMINGS)
636
- Published test-name (TIMINGS)
637
- test-name.test-sub-domain.workers.dev"
638
- `);
639
- expect(std.err).toMatchInlineSnapshot(`""`);
640
- });
641
-
642
- it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
643
- const assets = [
644
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
645
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
646
- ];
647
- const kvNamespace = {
648
- title: "__test-name-workers_sites_assets",
649
- id: "__test-name-workers_sites_assets-id",
650
- };
651
- writeWranglerToml({
652
- main: "./index.js",
653
- site: {
654
- bucket: "assets",
655
- },
656
- });
657
- writeWorkerSource({ type: "esm" });
658
- writeAssets(assets);
659
- mockUploadWorkerRequest({
660
- expectedBindings: [
661
- {
662
- name: "__STATIC_CONTENT",
663
- namespace_id: "__test-name-workers_sites_assets-id",
664
- type: "kv_namespace",
665
- },
666
- ],
667
- expectedModules: {
668
- __STATIC_CONTENT_MANIFEST:
669
- '{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
670
- },
671
- });
672
- mockSubDomainRequest();
673
- mockListKVNamespacesRequest(kvNamespace);
674
- mockKeyListRequest(kvNamespace.id, []);
675
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
676
-
677
- await runWrangler("publish");
678
-
679
- expect(std.out).toMatchInlineSnapshot(`
680
- "reading assets/file-1.txt...
681
- uploading as assets/file-1.2ca234f380.txt...
682
- reading assets/file-2.txt...
683
- uploading as assets/file-2.5938485188.txt...
684
- Uploaded test-name (TIMINGS)
685
- Published test-name (TIMINGS)
686
- test-name.test-sub-domain.workers.dev"
687
- `);
688
- expect(std.err).toMatchInlineSnapshot(`""`);
689
- });
690
-
691
- it("should make environment specific kv namespace for assets, even for service envs", async () => {
692
- // This is the same test as the one before this, but with an env arg
693
- const assets = [
694
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
695
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
696
- ];
697
- const kvNamespace = {
698
- title: "__test-name-some-env-workers_sites_assets",
699
- id: "__test-name-some-env-workers_sites_assets-id",
700
- };
701
- writeWranglerToml({
702
- main: "./index.js",
703
- site: {
704
- bucket: "assets",
705
- },
706
- });
707
- writeWorkerSource();
708
- writeAssets(assets);
709
- mockUploadWorkerRequest({
710
- env: "some-env",
711
- expectedBindings: [
712
- {
713
- name: "__STATIC_CONTENT",
714
- namespace_id: "__test-name-some-env-workers_sites_assets-id",
715
- type: "kv_namespace",
716
- },
717
- ],
718
- });
719
- mockSubDomainRequest();
720
- mockListKVNamespacesRequest(kvNamespace);
721
- mockKeyListRequest(kvNamespace.id, []);
722
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
723
- await runWrangler("publish --env some-env --legacy-env false");
724
-
725
- expect(std.out).toMatchInlineSnapshot(`
726
- "reading assets/file-1.txt...
727
- uploading as assets/file-1.2ca234f380.txt...
728
- reading assets/file-2.txt...
729
- uploading as assets/file-2.5938485188.txt...
730
- Uploaded test-name (some-env) (TIMINGS)
731
- Published test-name (some-env) (TIMINGS)
732
- some-env.test-name.test-sub-domain.workers.dev"
733
- `);
734
- expect(std.err).toMatchInlineSnapshot(`""`);
735
- });
736
-
737
- it("should make environment specific kv namespace for assets, even for legacy envs", async () => {
738
- // And this is the same test as the one before this, but with legacyEnv:true
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-some-env-workers_sites_assets",
745
- id: "__test-name-some-env-workers_sites_assets-id",
746
- };
747
- writeWranglerToml({
748
- main: "./index.js",
749
- site: {
750
- bucket: "assets",
751
- },
752
- });
753
- writeWorkerSource();
754
- writeAssets(assets);
755
- mockUploadWorkerRequest({
756
- legacyEnv: true,
757
- env: "some-env",
758
- expectedBindings: [
759
- {
760
- name: "__STATIC_CONTENT",
761
- namespace_id: "__test-name-some-env-workers_sites_assets-id",
762
- type: "kv_namespace",
763
- },
764
- ],
765
- });
766
- mockSubDomainRequest();
767
- mockListKVNamespacesRequest(kvNamespace);
768
- mockKeyListRequest(kvNamespace.id, []);
769
- mockUploadAssetsToKVRequest(kvNamespace.id, assets);
770
- await runWrangler("publish --env some-env --legacy-env true");
771
-
772
- expect(std.out).toMatchInlineSnapshot(`
773
- "reading assets/file-1.txt...
774
- uploading as assets/file-1.2ca234f380.txt...
775
- reading assets/file-2.txt...
776
- uploading as assets/file-2.5938485188.txt...
777
- Uploaded test-name-some-env (TIMINGS)
778
- Published test-name-some-env (TIMINGS)
779
- test-name-some-env.test-sub-domain.workers.dev"
780
- `);
781
- expect(std.err).toMatchInlineSnapshot(`""`);
782
- });
783
-
784
- it("should only upload files that are not already in the KV namespace", async () => {
785
- const assets = [
786
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
787
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
788
- ];
789
- const kvNamespace = {
790
- title: "__test-name-workers_sites_assets",
791
- id: "__test-name-workers_sites_assets-id",
792
- };
793
- writeWranglerToml({
794
- main: "./index.js",
795
- site: {
796
- bucket: "assets",
797
- },
798
- });
799
- writeWorkerSource();
800
- writeAssets(assets);
801
- mockUploadWorkerRequest();
802
- mockSubDomainRequest();
803
- mockListKVNamespacesRequest(kvNamespace);
804
- // Put file-1 in the KV namespace
805
- mockKeyListRequest(kvNamespace.id, ["assets/file-1.2ca234f380.txt"]);
806
- // Check we do not upload file-1
807
- mockUploadAssetsToKVRequest(
808
- kvNamespace.id,
809
- assets.filter((a) => a.filePath !== "assets/file-1.txt")
810
- );
811
- await runWrangler("publish");
812
-
813
- expect(std.out).toMatchInlineSnapshot(`
814
- "reading assets/file-1.txt...
815
- skipping - already uploaded
816
- reading assets/file-2.txt...
817
- uploading as assets/file-2.5938485188.txt...
818
- Uploaded test-name (TIMINGS)
819
- Published test-name (TIMINGS)
820
- test-name.test-sub-domain.workers.dev"
821
- `);
822
- expect(std.err).toMatchInlineSnapshot(`""`);
823
- });
824
-
825
- it("should only upload files that match the `site-include` arg", async () => {
826
- const assets = [
827
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
828
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
829
- ];
830
- const kvNamespace = {
831
- title: "__test-name-workers_sites_assets",
832
- id: "__test-name-workers_sites_assets-id",
833
- };
834
- writeWranglerToml({
835
- main: "./index.js",
836
- site: {
837
- bucket: "assets",
838
- },
839
- });
840
- writeWorkerSource();
841
- writeAssets(assets);
842
- mockUploadWorkerRequest();
843
- mockSubDomainRequest();
844
- mockListKVNamespacesRequest(kvNamespace);
845
- mockKeyListRequest(kvNamespace.id, []);
846
- // Check we only upload file-1
847
- mockUploadAssetsToKVRequest(
848
- kvNamespace.id,
849
- assets.filter((a) => a.filePath === "assets/file-1.txt")
850
- );
851
- await runWrangler("publish --site-include file-1.txt");
852
-
853
- expect(std.out).toMatchInlineSnapshot(`
854
- "reading assets/file-1.txt...
855
- uploading as assets/file-1.2ca234f380.txt...
856
- Uploaded test-name (TIMINGS)
857
- Published test-name (TIMINGS)
858
- test-name.test-sub-domain.workers.dev"
859
- `);
860
- expect(std.err).toMatchInlineSnapshot(`""`);
861
- });
862
-
863
- it("should not upload files that match the `site-exclude` arg", async () => {
864
- const assets = [
865
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
866
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
867
- ];
868
- const kvNamespace = {
869
- title: "__test-name-workers_sites_assets",
870
- id: "__test-name-workers_sites_assets-id",
871
- };
872
- writeWranglerToml({
873
- main: "./index.js",
874
- site: {
875
- bucket: "assets",
876
- },
877
- });
878
- writeWorkerSource();
879
- writeAssets(assets);
880
- mockUploadWorkerRequest();
881
- mockSubDomainRequest();
882
- mockListKVNamespacesRequest(kvNamespace);
883
- mockKeyListRequest(kvNamespace.id, []);
884
- // Check we only upload file-1
885
- mockUploadAssetsToKVRequest(
886
- kvNamespace.id,
887
- assets.filter((a) => a.filePath === "assets/file-1.txt")
888
- );
889
- await runWrangler("publish --site-exclude file-2.txt");
890
-
891
- expect(std.out).toMatchInlineSnapshot(`
892
- "reading assets/file-1.txt...
893
- uploading as assets/file-1.2ca234f380.txt...
894
- Uploaded test-name (TIMINGS)
895
- Published test-name (TIMINGS)
896
- test-name.test-sub-domain.workers.dev"
897
- `);
898
- expect(std.err).toMatchInlineSnapshot(`""`);
899
- });
900
-
901
- it("should only upload files that match the `site.include` config", async () => {
902
- const assets = [
903
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
904
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
905
- ];
906
- const kvNamespace = {
907
- title: "__test-name-workers_sites_assets",
908
- id: "__test-name-workers_sites_assets-id",
909
- };
910
- writeWranglerToml({
911
- main: "./index.js",
912
- site: {
913
- bucket: "assets",
914
- include: ["file-1.txt"],
915
- },
916
- });
917
- writeWorkerSource();
918
- writeAssets(assets);
919
- mockUploadWorkerRequest();
920
- mockSubDomainRequest();
921
- mockListKVNamespacesRequest(kvNamespace);
922
- mockKeyListRequest(kvNamespace.id, []);
923
- // Check we only upload file-1
924
- mockUploadAssetsToKVRequest(
925
- kvNamespace.id,
926
- assets.filter((a) => a.filePath === "assets/file-1.txt")
927
- );
928
- await runWrangler("publish");
929
-
930
- expect(std.out).toMatchInlineSnapshot(`
931
- "reading assets/file-1.txt...
932
- uploading as assets/file-1.2ca234f380.txt...
933
- Uploaded test-name (TIMINGS)
934
- Published test-name (TIMINGS)
935
- test-name.test-sub-domain.workers.dev"
936
- `);
937
- expect(std.err).toMatchInlineSnapshot(`""`);
938
- });
939
-
940
- it("should not upload files that match the `site.exclude` config", async () => {
941
- const assets = [
942
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
943
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
944
- ];
945
- const kvNamespace = {
946
- title: "__test-name-workers_sites_assets",
947
- id: "__test-name-workers_sites_assets-id",
948
- };
949
- writeWranglerToml({
950
- main: "./index.js",
951
- site: {
952
- bucket: "assets",
953
- exclude: ["file-2.txt"],
954
- },
955
- });
956
- writeWorkerSource();
957
- writeAssets(assets);
958
- mockUploadWorkerRequest();
959
- mockSubDomainRequest();
960
- mockListKVNamespacesRequest(kvNamespace);
961
- mockKeyListRequest(kvNamespace.id, []);
962
- // Check we only upload file-1
963
- mockUploadAssetsToKVRequest(
964
- kvNamespace.id,
965
- assets.filter((a) => a.filePath === "assets/file-1.txt")
966
- );
967
- await runWrangler("publish");
968
-
969
- expect(std.out).toMatchInlineSnapshot(`
970
- "reading assets/file-1.txt...
971
- uploading as assets/file-1.2ca234f380.txt...
972
- Uploaded test-name (TIMINGS)
973
- Published test-name (TIMINGS)
974
- test-name.test-sub-domain.workers.dev"
975
- `);
976
- expect(std.err).toMatchInlineSnapshot(`""`);
977
- });
978
-
979
- it("should use `site-include` arg over `site.include` config", async () => {
980
- const assets = [
981
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
982
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
983
- ];
984
- const kvNamespace = {
985
- title: "__test-name-workers_sites_assets",
986
- id: "__test-name-workers_sites_assets-id",
987
- };
988
- writeWranglerToml({
989
- main: "./index.js",
990
- site: {
991
- bucket: "assets",
992
- include: ["file-2.txt"],
993
- },
994
- });
995
- writeWorkerSource();
996
- writeAssets(assets);
997
- mockUploadWorkerRequest();
998
- mockSubDomainRequest();
999
- mockListKVNamespacesRequest(kvNamespace);
1000
- mockKeyListRequest(kvNamespace.id, []);
1001
- // Check we only upload file-1
1002
- mockUploadAssetsToKVRequest(
1003
- kvNamespace.id,
1004
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1005
- );
1006
- await runWrangler("publish --site-include file-1.txt");
1007
-
1008
- expect(std.out).toMatchInlineSnapshot(`
1009
- "reading assets/file-1.txt...
1010
- uploading as assets/file-1.2ca234f380.txt...
1011
- Uploaded test-name (TIMINGS)
1012
- Published test-name (TIMINGS)
1013
- test-name.test-sub-domain.workers.dev"
1014
- `);
1015
- expect(std.err).toMatchInlineSnapshot(`""`);
1016
- });
1017
-
1018
- it("should use `site-exclude` arg over `site.exclude` config", async () => {
1019
- const assets = [
1020
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1021
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1022
- ];
1023
- const kvNamespace = {
1024
- title: "__test-name-workers_sites_assets",
1025
- id: "__test-name-workers_sites_assets-id",
1026
- };
1027
- writeWranglerToml({
1028
- main: "./index.js",
1029
- site: {
1030
- bucket: "assets",
1031
- exclude: ["assets/file-1.txt"],
1032
- },
1033
- });
1034
- writeWorkerSource();
1035
- writeAssets(assets);
1036
- mockUploadWorkerRequest();
1037
- mockSubDomainRequest();
1038
- mockListKVNamespacesRequest(kvNamespace);
1039
- mockKeyListRequest(kvNamespace.id, []);
1040
- // Check we only upload file-1
1041
- mockUploadAssetsToKVRequest(
1042
- kvNamespace.id,
1043
- assets.filter((a) => a.filePath.endsWith("assets/file-1.txt"))
1044
- );
1045
- await runWrangler("publish --site-exclude file-2.txt");
1046
-
1047
- expect(std.out).toMatchInlineSnapshot(`
1048
- "reading assets/file-1.txt...
1049
- uploading as assets/file-1.2ca234f380.txt...
1050
- Uploaded test-name (TIMINGS)
1051
- Published test-name (TIMINGS)
1052
- test-name.test-sub-domain.workers.dev"
1053
- `);
1054
- expect(std.err).toMatchInlineSnapshot(`""`);
1055
- });
1056
-
1057
- it("should walk directories except node_modules", async () => {
1058
- const assets = [
1059
- {
1060
- filePath: "assets/directory-1/file-1.txt",
1061
- content: "Content of file-1",
1062
- },
1063
- {
1064
- filePath: "assets/node_modules/file-2.txt",
1065
- content: "Content of file-2",
1066
- },
1067
- ];
1068
- const kvNamespace = {
1069
- title: "__test-name-workers_sites_assets",
1070
- id: "__test-name-workers_sites_assets-id",
1071
- };
1072
- writeWranglerToml({
1073
- main: "./index.js",
1074
- site: {
1075
- bucket: "assets",
1076
- },
1077
- });
1078
- writeWorkerSource();
1079
- writeAssets(assets);
1080
- mockUploadWorkerRequest();
1081
- mockSubDomainRequest();
1082
- mockListKVNamespacesRequest(kvNamespace);
1083
- mockKeyListRequest(kvNamespace.id, []);
1084
- // Only expect file-1 to be uploaded
1085
- mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(0, 1));
1086
- await runWrangler("publish");
1087
-
1088
- expect(std.out).toMatchInlineSnapshot(`
1089
- "reading assets/directory-1/file-1.txt...
1090
- uploading as assets/directory-1/file-1.2ca234f380.txt...
1091
- Uploaded test-name (TIMINGS)
1092
- Published test-name (TIMINGS)
1093
- test-name.test-sub-domain.workers.dev"
1094
- `);
1095
- expect(std.err).toMatchInlineSnapshot(`""`);
1096
- });
1097
-
1098
- it("should skip hidden files and directories except `.well-known`", async () => {
1099
- const assets = [
1100
- {
1101
- filePath: "assets/.hidden-file.txt",
1102
- content: "Content of hidden-file",
1103
- },
1104
- {
1105
- filePath: "assets/.hidden/file-1.txt",
1106
- content: "Content of file-1",
1107
- },
1108
- {
1109
- filePath: "assets/.well-known/file-2.txt",
1110
- content: "Content of file-2",
1111
- },
1112
- ];
1113
- const kvNamespace = {
1114
- title: "__test-name-workers_sites_assets",
1115
- id: "__test-name-workers_sites_assets-id",
1116
- };
1117
- writeWranglerToml({
1118
- main: "./index.js",
1119
- site: {
1120
- bucket: "assets",
1121
- },
1122
- });
1123
- writeWorkerSource();
1124
- writeAssets(assets);
1125
- mockUploadWorkerRequest();
1126
- mockSubDomainRequest();
1127
- mockListKVNamespacesRequest(kvNamespace);
1128
- mockKeyListRequest(kvNamespace.id, []);
1129
- // Only expect file-2 to be uploaded
1130
- mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(2));
1131
- await runWrangler("publish");
1132
-
1133
- expect(std.out).toMatchInlineSnapshot(`
1134
- "reading assets/.well-known/file-2.txt...
1135
- uploading as assets/.well-known/file-2.5938485188.txt...
1136
- Uploaded test-name (TIMINGS)
1137
- Published test-name (TIMINGS)
1138
- test-name.test-sub-domain.workers.dev"
1139
- `);
1140
- expect(std.err).toMatchInlineSnapshot(`""`);
1141
- });
1142
-
1143
- it("should error if the asset is over 25Mb", async () => {
1144
- const assets = [
1145
- {
1146
- filePath: "assets/large-file.txt",
1147
- // This file is greater than 25MiB when base64 encoded but small enough to be uploaded.
1148
- content: "X".repeat(25 * 1024 * 1024 * 0.8 + 1),
1149
- },
1150
- {
1151
- filePath: "assets/too-large-file.txt",
1152
- content: "X".repeat(25 * 1024 * 1024 + 1),
1153
- },
1154
- ];
1155
- const kvNamespace = {
1156
- title: "__test-name-workers_sites_assets",
1157
- id: "__test-name-workers_sites_assets-id",
1158
- };
1159
- writeWranglerToml({
1160
- main: "./index.js",
1161
- site: {
1162
- bucket: "assets",
1163
- exclude: ["assets/file-1.txt"],
1164
- },
1165
- });
1166
- writeWorkerSource();
1167
- writeAssets(assets);
1168
- mockUploadWorkerRequest();
1169
- mockSubDomainRequest();
1170
- mockListKVNamespacesRequest(kvNamespace);
1171
- mockKeyListRequest(kvNamespace.id, []);
1172
-
1173
- await expect(
1174
- runWrangler("publish")
1175
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1176
- `"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"`
1177
- );
1178
-
1179
- expect(std.out).toMatchInlineSnapshot(`
1180
- "reading assets/large-file.txt...
1181
- uploading as assets/large-file.0ea0637a45.txt..."
1182
- `);
1183
- expect(std.err).toMatchInlineSnapshot(`
1184
- "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
1185
-
1186
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1187
- `);
1188
- });
1189
-
1190
- it("should error if the asset key is over 512 characters", async () => {
1191
- const longFilePathAsset = {
1192
- filePath: "assets/" + "folder/".repeat(100) + "file.txt",
1193
- content: "content of file",
1194
- };
1195
- const kvNamespace = {
1196
- title: "__test-name-workers_sites_assets",
1197
- id: "__test-name-workers_sites_assets-id",
1198
- };
1199
- writeWranglerToml({
1200
- main: "./index.js",
1201
- site: {
1202
- bucket: "assets",
1203
- },
1204
- });
1205
- writeWorkerSource();
1206
- writeAssets([longFilePathAsset]);
1207
- mockUploadWorkerRequest();
1208
- mockSubDomainRequest();
1209
- mockListKVNamespacesRequest(kvNamespace);
1210
- mockKeyListRequest(kvNamespace.id, []);
1211
-
1212
- await expect(
1213
- runWrangler("publish")
1214
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1215
- `"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\\","`
1216
- );
1217
-
1218
- expect(std.out).toMatchInlineSnapshot(
1219
- `"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..."`
1220
- );
1221
- expect(std.err).toMatchInlineSnapshot(`
1222
- "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\\",
1223
-
1224
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1225
- `);
1226
- });
1227
- });
1228
-
1229
- describe("workers_dev setting", () => {
1230
- it("should publish to a workers.dev domain if workers_dev is undefined", async () => {
1231
- writeWranglerToml();
1232
- writeWorkerSource();
1233
- mockUploadWorkerRequest();
1234
- mockSubDomainRequest();
1235
-
1236
- await runWrangler("publish ./index");
1237
-
1238
- expect(std.out).toMatchInlineSnapshot(`
1239
- "Uploaded test-name (TIMINGS)
1240
- Published test-name (TIMINGS)
1241
- test-name.test-sub-domain.workers.dev"
1242
- `);
1243
- expect(std.err).toMatchInlineSnapshot(`""`);
1244
- });
1245
-
1246
- it("should publish to the workers.dev domain if workers_dev is `true`", async () => {
1247
- writeWranglerToml({
1248
- workers_dev: true,
1249
- });
1250
- writeWorkerSource();
1251
- mockUploadWorkerRequest();
1252
- mockSubDomainRequest();
1253
-
1254
- await runWrangler("publish ./index");
1255
-
1256
- expect(std.out).toMatchInlineSnapshot(`
1257
- "Uploaded test-name (TIMINGS)
1258
- Published test-name (TIMINGS)
1259
- test-name.test-sub-domain.workers.dev"
1260
- `);
1261
- expect(std.err).toMatchInlineSnapshot(`""`);
1262
- });
1263
-
1264
- it("should disable the workers.dev domain if workers_dev is `false`", async () => {
1265
- writeWranglerToml({
1266
- workers_dev: false,
1267
- });
1268
- writeWorkerSource();
1269
- mockUploadWorkerRequest();
1270
- mockSubDomainRequest();
1271
- mockUpdateWorkerRequest({ enabled: false });
1272
-
1273
- await runWrangler("publish ./index");
1274
-
1275
- expect(std.out).toMatchInlineSnapshot(`
1276
- "Uploaded test-name (TIMINGS)
1277
- No publish targets for test-name (TIMINGS)"
1278
- `);
1279
- expect(std.err).toMatchInlineSnapshot(`""`);
1280
- });
1281
-
1282
- it("should enable the workers.dev domain if workers_dev is undefined and subdomain is not already available", async () => {
1283
- writeWranglerToml();
1284
- writeWorkerSource();
1285
- mockUploadWorkerRequest({ available_on_subdomain: false });
1286
- mockSubDomainRequest();
1287
- mockUpdateWorkerRequest({ enabled: true });
1288
-
1289
- await runWrangler("publish ./index");
1290
-
1291
- expect(std.out).toMatchInlineSnapshot(`
1292
- "Uploaded test-name (TIMINGS)
1293
- Published test-name (TIMINGS)
1294
- test-name.test-sub-domain.workers.dev"
1295
- `);
1296
- expect(std.err).toMatchInlineSnapshot(`""`);
1297
- });
1298
-
1299
- it("should enable the workers.dev domain if workers_dev is true and subdomain is not already available", async () => {
1300
- writeWranglerToml({ workers_dev: true });
1301
- writeWorkerSource();
1302
- mockUploadWorkerRequest({ available_on_subdomain: false });
1303
- mockSubDomainRequest();
1304
- mockUpdateWorkerRequest({ enabled: true });
1305
-
1306
- await runWrangler("publish ./index");
1307
-
1308
- expect(std.out).toMatchInlineSnapshot(`
1309
- "Uploaded test-name (TIMINGS)
1310
- Published test-name (TIMINGS)
1311
- test-name.test-sub-domain.workers.dev"
1312
- `);
1313
- expect(std.err).toMatchInlineSnapshot(`""`);
1314
- });
1315
- });
1316
-
1317
- describe("custom builds", () => {
1318
- beforeEach(() => {
1319
- // @ts-expect-error disable the mock we'd setup earlier
1320
- // or else custom builds will timeout immediately
1321
- global.setTimeout.mockRestore();
1322
- });
1323
- it("should run a custom build before publishing", async () => {
1324
- writeWranglerToml({
1325
- build: {
1326
- command: `node -e "console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')"`,
1327
- },
1328
- });
1329
-
1330
- mockUploadWorkerRequest({
1331
- expectedEntry: "return new Response(123)",
1332
- });
1333
- mockSubDomainRequest();
1334
-
1335
- await runWrangler("publish index.js");
1336
- expect(std.out).toMatchInlineSnapshot(`
1337
- "running: node -e \\"console.log('custom build'); require('fs').writeFileSync('index.js', 'export default { fetch(){ return new Response(123) } }')\\"
1338
- Uploaded test-name (TIMINGS)
1339
- Published test-name (TIMINGS)
1340
- test-name.test-sub-domain.workers.dev"
1341
- `);
1342
- expect(std.err).toMatchInlineSnapshot(`""`);
1343
- expect(std.warn).toMatchInlineSnapshot(`""`);
1344
- });
1345
-
1346
- if (process.platform !== "win32") {
1347
- it("should run a custom build of multiple steps combined by && before publishing", async () => {
1348
- writeWranglerToml({
1349
- build: {
1350
- command: `echo "custom build" && echo "export default { fetch(){ return new Response(123) } }" > index.js`,
1351
- },
1352
- });
1353
-
1354
- mockUploadWorkerRequest({
1355
- expectedEntry: "return new Response(123)",
1356
- });
1357
- mockSubDomainRequest();
1358
-
1359
- await runWrangler("publish index.js");
1360
- expect(std.out).toMatchInlineSnapshot(`
1361
- "running: echo \\"custom build\\" && echo \\"export default { fetch(){ return new Response(123) } }\\" > index.js
1362
- Uploaded test-name (TIMINGS)
1363
- Published test-name (TIMINGS)
1364
- test-name.test-sub-domain.workers.dev"
1365
- `);
1366
- expect(std.err).toMatchInlineSnapshot(`""`);
1367
- expect(std.warn).toMatchInlineSnapshot(`""`);
1368
- });
1369
- }
1370
- });
1371
-
1372
- describe("[wasm_modules]", () => {
1373
- it("should be able to define wasm modules for service-worker format workers", async () => {
1374
- writeWranglerToml({
1375
- wasm_modules: {
1376
- TESTWASMNAME: "./path/to/test.wasm",
1377
- },
1378
- });
1379
- writeWorkerSource({ type: "sw" });
1380
- fs.mkdirSync("./path/to", { recursive: true });
1381
- fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1382
- mockUploadWorkerRequest({
1383
- expectedType: "sw",
1384
- expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1385
- expectedBindings: [
1386
- { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1387
- ],
1388
- });
1389
- mockSubDomainRequest();
1390
- await runWrangler("publish index.js");
1391
- expect(std.out).toMatchInlineSnapshot(`
1392
- "Uploaded test-name (TIMINGS)
1393
- Published test-name (TIMINGS)
1394
- test-name.test-sub-domain.workers.dev"
1395
- `);
1396
- expect(std.err).toMatchInlineSnapshot(`""`);
1397
- expect(std.warn).toMatchInlineSnapshot(`""`);
1398
- });
1399
-
1400
- it("should error when defining wasm modules for modules format workers", async () => {
1401
- writeWranglerToml({
1402
- wasm_modules: {
1403
- TESTWASMNAME: "./path/to/test.wasm",
1404
- },
1405
- });
1406
- writeWorkerSource({ type: "esm" });
1407
- fs.mkdirSync("./path/to", { recursive: true });
1408
- fs.writeFileSync("./path/to/test.wasm", "SOME WASM CONTENT");
1409
-
1410
- await expect(
1411
- runWrangler("publish index.js")
1412
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1413
- `"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"`
1414
- );
1415
- expect(std.out).toMatchInlineSnapshot(`""`);
1416
- expect(std.err).toMatchInlineSnapshot(`
1417
- "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
1418
-
1419
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1420
- `);
1421
- expect(std.warn).toMatchInlineSnapshot(`""`);
1422
- });
1423
-
1424
- it("should resolve wasm modules relative to the wrangler.toml file", async () => {
1425
- fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
1426
- fs.writeFileSync(
1427
- "./path/to/wrangler.toml",
1428
- TOML.stringify({
1429
- compatibility_date: "2022-01-12",
1430
- name: "test-name",
1431
- wasm_modules: {
1432
- TESTWASMNAME: "./and/the/path/to/test.wasm",
1433
- },
1434
- }),
1435
-
1436
- "utf-8"
1437
- );
1438
-
1439
- writeWorkerSource({ type: "sw" });
1440
- fs.writeFileSync(
1441
- "./path/to/and/the/path/to/test.wasm",
1442
- "SOME WASM CONTENT"
1443
- );
1444
- mockUploadWorkerRequest({
1445
- expectedType: "sw",
1446
- expectedModules: { TESTWASMNAME: "SOME WASM CONTENT" },
1447
- expectedBindings: [
1448
- { name: "TESTWASMNAME", part: "TESTWASMNAME", type: "wasm_module" },
1449
- ],
1450
- });
1451
- mockSubDomainRequest();
1452
- await runWrangler("publish index.js --config ./path/to/wrangler.toml");
1453
- expect(std.out).toMatchInlineSnapshot(`
1454
- "Uploaded test-name (TIMINGS)
1455
- Published test-name (TIMINGS)
1456
- test-name.test-sub-domain.workers.dev"
1457
- `);
1458
- expect(std.err).toMatchInlineSnapshot(`""`);
1459
- expect(std.warn).toMatchInlineSnapshot(`""`);
1460
- });
1461
-
1462
- it("should be able to import .wasm modules from service-worker format workers", async () => {
1463
- writeWranglerToml();
1464
- fs.writeFileSync("./index.js", "import TESTWASMNAME from './test.wasm';");
1465
- fs.writeFileSync("./test.wasm", "SOME WASM CONTENT");
1466
- mockUploadWorkerRequest({
1467
- expectedType: "sw",
1468
- expectedModules: {
1469
- __94b240d0d692281e6467aa42043986e5c7eea034_test_wasm:
1470
- "SOME WASM CONTENT",
1471
- },
1472
- expectedBindings: [
1473
- {
1474
- name: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1475
- part: "__94b240d0d692281e6467aa42043986e5c7eea034_test_wasm",
1476
- type: "wasm_module",
1477
- },
1478
- ],
1479
- });
1480
- mockSubDomainRequest();
1481
- await runWrangler("publish index.js");
1482
- expect(std.out).toMatchInlineSnapshot(`
1483
- "Uploaded test-name (TIMINGS)
1484
- Published test-name (TIMINGS)
1485
- test-name.test-sub-domain.workers.dev"
1486
- `);
1487
- expect(std.err).toMatchInlineSnapshot(`""`);
1488
- expect(std.warn).toMatchInlineSnapshot(`""`);
1489
- });
1490
- });
1491
-
1492
- describe("[text_blobs]", () => {
1493
- it("should be able to define text blobs for service-worker format workers", async () => {
1494
- writeWranglerToml({
1495
- text_blobs: {
1496
- TESTTEXTBLOBNAME: "./path/to/text.file",
1497
- },
1498
- });
1499
- writeWorkerSource({ type: "sw" });
1500
- fs.mkdirSync("./path/to", { recursive: true });
1501
- fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
1502
- mockUploadWorkerRequest({
1503
- expectedType: "sw",
1504
- expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
1505
- expectedBindings: [
1506
- {
1507
- name: "TESTTEXTBLOBNAME",
1508
- part: "TESTTEXTBLOBNAME",
1509
- type: "text_blob",
1510
- },
1511
- ],
1512
- });
1513
- mockSubDomainRequest();
1514
- await runWrangler("publish index.js");
1515
- expect(std.out).toMatchInlineSnapshot(`
1516
- "Uploaded test-name (TIMINGS)
1517
- Published test-name (TIMINGS)
1518
- test-name.test-sub-domain.workers.dev"
1519
- `);
1520
- expect(std.err).toMatchInlineSnapshot(`""`);
1521
- expect(std.warn).toMatchInlineSnapshot(`""`);
1522
- });
1523
-
1524
- it("should error when defining text blobs for modules format workers", async () => {
1525
- writeWranglerToml({
1526
- text_blobs: {
1527
- TESTTEXTBLOBNAME: "./path/to/text.file",
1528
- },
1529
- });
1530
- writeWorkerSource({ type: "esm" });
1531
- fs.mkdirSync("./path/to", { recursive: true });
1532
- fs.writeFileSync("./path/to/text.file", "SOME TEXT CONTENT");
1533
-
1534
- await expect(
1535
- runWrangler("publish index.js")
1536
- ).rejects.toThrowErrorMatchingInlineSnapshot(
1537
- `"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml"`
1538
- );
1539
- expect(std.out).toMatchInlineSnapshot(`""`);
1540
- expect(std.err).toMatchInlineSnapshot(`
1541
- "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml
1542
-
1543
- %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1544
- `);
1545
- expect(std.warn).toMatchInlineSnapshot(`""`);
1546
- });
1547
-
1548
- it("should resolve text blobs relative to the wrangler.toml file", async () => {
1549
- fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true });
1550
- fs.writeFileSync(
1551
- "./path/to/wrangler.toml",
1552
- TOML.stringify({
1553
- compatibility_date: "2022-01-12",
1554
- name: "test-name",
1555
- text_blobs: {
1556
- TESTTEXTBLOBNAME: "./and/the/path/to/text.file",
1557
- },
1558
- }),
1559
-
1560
- "utf-8"
1561
- );
1562
-
1563
- writeWorkerSource({ type: "sw" });
1564
- fs.writeFileSync(
1565
- "./path/to/and/the/path/to/text.file",
1566
- "SOME TEXT CONTENT"
1567
- );
1568
- mockUploadWorkerRequest({
1569
- expectedType: "sw",
1570
- expectedModules: { TESTTEXTBLOBNAME: "SOME TEXT CONTENT" },
1571
- expectedBindings: [
1572
- {
1573
- name: "TESTTEXTBLOBNAME",
1574
- part: "TESTTEXTBLOBNAME",
1575
- type: "text_blob",
1576
- },
1577
- ],
1578
- });
1579
- mockSubDomainRequest();
1580
- await runWrangler("publish index.js --config ./path/to/wrangler.toml");
1581
- expect(std.out).toMatchInlineSnapshot(`
1582
- "Uploaded test-name (TIMINGS)
1583
- Published test-name (TIMINGS)
1584
- test-name.test-sub-domain.workers.dev"
1585
- `);
1586
- expect(std.err).toMatchInlineSnapshot(`""`);
1587
- expect(std.warn).toMatchInlineSnapshot(`""`);
1588
- });
1589
- });
1590
-
1591
- describe("vars bindings", () => {
1592
- it("should support json bindings", async () => {
1593
- writeWranglerToml({
1594
- vars: {
1595
- text: "plain ol' string",
1596
- count: 1,
1597
- complex: { enabled: true, id: 123 },
1598
- },
1599
- });
1600
- writeWorkerSource();
1601
- mockSubDomainRequest();
1602
- mockUploadWorkerRequest({
1603
- expectedBindings: [
1604
- { name: "text", type: "plain_text", text: "plain ol' string" },
1605
- { name: "count", type: "json", json: 1 },
1606
- {
1607
- name: "complex",
1608
- type: "json",
1609
- json: { enabled: true, id: 123 },
1610
- },
1611
- ],
1612
- });
1613
-
1614
- await runWrangler("publish index.js");
1615
- expect(std.out).toMatchInlineSnapshot(`
1616
- "Uploaded test-name (TIMINGS)
1617
- Published test-name (TIMINGS)
1618
- test-name.test-sub-domain.workers.dev"
1619
- `);
1620
- expect(std.err).toMatchInlineSnapshot(`""`);
1621
- expect(std.warn).toMatchInlineSnapshot(`""`);
1622
- });
1623
- });
1624
-
1625
- describe("r2 bucket bindings", () => {
1626
- it("should support r2 bucket bindings", async () => {
1627
- writeWranglerToml({
1628
- r2_buckets: [{ binding: "FOO", bucket_name: "foo-bucket" }],
1629
- });
1630
- writeWorkerSource();
1631
- mockSubDomainRequest();
1632
- mockUploadWorkerRequest({
1633
- expectedBindings: [
1634
- { bucket_name: "foo-bucket", name: "FOO", type: "r2_bucket" },
1635
- ],
1636
- });
1637
-
1638
- await runWrangler("publish index.js");
1639
- expect(std.out).toMatchInlineSnapshot(`
1640
- "Uploaded test-name (TIMINGS)
1641
- Published test-name (TIMINGS)
1642
- test-name.test-sub-domain.workers.dev"
1643
- `);
1644
- expect(std.err).toMatchInlineSnapshot(`""`);
1645
- expect(std.warn).toMatchInlineSnapshot(`""`);
1646
- });
1647
- });
1648
-
1649
- describe("unsafe bindings", () => {
1650
- it("should warn if using unsafe bindings", async () => {
1651
- writeWranglerToml({
1652
- unsafe: {
1653
- bindings: [
1654
- {
1655
- name: "my-binding",
1656
- type: "binding-type",
1657
- param: "binding-param",
1658
- },
1659
- ],
1660
- },
1661
- });
1662
- writeWorkerSource();
1663
- mockSubDomainRequest();
1664
- mockUploadWorkerRequest({
1665
- expectedBindings: [
1666
- {
1667
- name: "my-binding",
1668
- type: "binding-type",
1669
- param: "binding-param",
1670
- },
1671
- ],
1672
- });
1673
-
1674
- await runWrangler("publish index.js");
1675
- expect(std.out).toMatchInlineSnapshot(`
1676
- "Uploaded test-name (TIMINGS)
1677
- Published test-name (TIMINGS)
1678
- test-name.test-sub-domain.workers.dev"
1679
- `);
1680
- expect(std.err).toMatchInlineSnapshot(`""`);
1681
- expect(std.warn).toMatchInlineSnapshot(`
1682
- "Processing wrangler.toml configuration:
1683
- - \\"unsafe\\" fields are experimental and may change or break at any time."
1684
- `);
1685
- });
1686
- it("should warn if using unsafe bindings already handled by wrangler", async () => {
1687
- writeWranglerToml({
1688
- unsafe: {
1689
- bindings: [
1690
- {
1691
- name: "my-binding",
1692
- type: "plain_text",
1693
- text: "text",
1694
- },
1695
- ],
1696
- },
1697
- });
1698
- writeWorkerSource();
1699
- mockSubDomainRequest();
1700
- mockUploadWorkerRequest({
1701
- expectedBindings: [
1702
- {
1703
- name: "my-binding",
1704
- type: "plain_text",
1705
- text: "text",
1706
- },
1707
- ],
1708
- });
1709
-
1710
- await runWrangler("publish index.js");
1711
- expect(std.out).toMatchInlineSnapshot(`
1712
- "Uploaded test-name (TIMINGS)
1713
- Published test-name (TIMINGS)
1714
- test-name.test-sub-domain.workers.dev"
1715
- `);
1716
- expect(std.err).toMatchInlineSnapshot(`""`);
1717
- expect(std.warn).toMatchInlineSnapshot(`
1718
- "Processing wrangler.toml configuration:
1719
- - \\"unsafe\\" fields are experimental and may change or break at any time.
1720
- - \\"unsafe.bindings[0]\\": {\\"name\\":\\"my-binding\\",\\"type\\":\\"plain_text\\",\\"text\\":\\"text\\"}
1721
- - The binding type \\"plain_text\\" is directly supported by wrangler.
1722
- Consider migrating this unsafe binding to a format for 'plain_text' bindings that is supported by wrangler for optimal support.
1723
- For more details, see https://developers.cloudflare.com/workers/cli-wrangler/configuration"
1724
- `);
1725
- });
1726
- });
1727
-
1728
- describe("upload rules", () => {
1729
- it("should be able to define rules for uploading non-js modules (sw)", async () => {
1730
- writeWranglerToml({
1731
- rules: [{ type: "Text", globs: ["**/*.file"], fallthrough: true }],
1732
- });
1733
- fs.writeFileSync("./index.js", `import TEXT from './text.file';`);
1734
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1735
- mockSubDomainRequest();
1736
- mockUploadWorkerRequest({
1737
- expectedType: "sw",
1738
- expectedBindings: [
1739
- {
1740
- name: "__2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0_text_file",
1741
- part: "__2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0_text_file",
1742
- type: "text_blob",
1743
- },
1744
- ],
1745
- expectedModules: {
1746
- __2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0_text_file:
1747
- "SOME TEXT CONTENT",
1748
- },
1749
- });
1750
- await runWrangler("publish index.js");
1751
- expect(std.out).toMatchInlineSnapshot(`
1752
- "Uploaded test-name (TIMINGS)
1753
- Published test-name (TIMINGS)
1754
- test-name.test-sub-domain.workers.dev"
1755
- `);
1756
- expect(std.err).toMatchInlineSnapshot(`""`);
1757
- expect(std.warn).toMatchInlineSnapshot(`""`);
1758
- });
1759
-
1760
- it("should be able to define rules for uploading non-js modules (esm)", async () => {
1761
- writeWranglerToml({
1762
- rules: [{ type: "Text", globs: ["**/*.file"], fallthrough: true }],
1763
- });
1764
- fs.writeFileSync(
1765
- "./index.js",
1766
- `import TEXT from './text.file'; export default {};`
1767
- );
1768
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1769
- mockSubDomainRequest();
1770
- mockUploadWorkerRequest({
1771
- expectedType: "esm",
1772
- expectedBindings: [],
1773
- expectedModules: {
1774
- "./2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0-text.file":
1775
- "SOME TEXT CONTENT",
1776
- },
1777
- });
1778
- await runWrangler("publish index.js");
1779
- expect(std.out).toMatchInlineSnapshot(`
1780
- "Uploaded test-name (TIMINGS)
1781
- Published test-name (TIMINGS)
1782
- test-name.test-sub-domain.workers.dev"
1783
- `);
1784
- expect(std.err).toMatchInlineSnapshot(`""`);
1785
- expect(std.warn).toMatchInlineSnapshot(`""`);
1786
- });
1787
-
1788
- it("should log a deprecation warning when using `build.upload.rules`", async () => {
1789
- writeWranglerToml({
1790
- build: {
1791
- upload: {
1792
- rules: [{ type: "Text", globs: ["**/*.file"], fallthrough: true }],
1793
- },
1794
- },
1795
- });
1796
- fs.writeFileSync(
1797
- "./index.js",
1798
- `import TEXT from './text.file'; export default {};`
1799
- );
1800
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1801
- mockSubDomainRequest();
1802
- mockUploadWorkerRequest({
1803
- expectedType: "esm",
1804
- expectedBindings: [],
1805
- expectedModules: {
1806
- "./2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0-text.file":
1807
- "SOME TEXT CONTENT",
1808
- },
1809
- });
1810
- await runWrangler("publish index.js");
1811
- expect(std.out).toMatchInlineSnapshot(`
1812
- "Uploaded test-name (TIMINGS)
1813
- Published test-name (TIMINGS)
1814
- test-name.test-sub-domain.workers.dev"
1815
- `);
1816
- expect(std.err).toMatchInlineSnapshot(`""`);
1817
- expect(std.warn).toMatchInlineSnapshot(`
1818
- "Processing wrangler.toml configuration:
1819
- - DEPRECATION: The \`build.upload.rules\` config field is no longer used, the rules should be specified via the \`rules\` config field. Delete the \`build.upload\` field from the configuration file, and add this:
1820
- \`\`\`
1821
- [[rules]]
1822
- type = \\"Text\\"
1823
- globs = [ \\"**/*.file\\" ]
1824
- fallthrough = true
1825
- \`\`\`"
1826
- `);
1827
- });
1828
-
1829
- it("should be able to use fallthrough:true for multiple rules", async () => {
1830
- writeWranglerToml({
1831
- rules: [
1832
- { type: "Text", globs: ["**/*.file"], fallthrough: true },
1833
- { type: "Text", globs: ["**/*.other"], fallthrough: true },
1834
- ],
1835
- });
1836
- fs.writeFileSync(
1837
- "./index.js",
1838
- `import TEXT from './text.file'; import OTHER from './other.other'; export default {};`
1839
- );
1840
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1841
- fs.writeFileSync("./other.other", "SOME OTHER TEXT CONTENT");
1842
- mockSubDomainRequest();
1843
- mockUploadWorkerRequest({
1844
- expectedType: "esm",
1845
- expectedBindings: [],
1846
- expectedModules: {
1847
- "./2d91d1c4dd6e57d4f5432187ab7c25f45a8973f0-text.file":
1848
- "SOME TEXT CONTENT",
1849
- "./16347a01366873ed80fe45115119de3c92ab8db0-other.other":
1850
- "SOME OTHER TEXT CONTENT",
1851
- },
1852
- });
1853
- await runWrangler("publish index.js");
1854
- expect(std.out).toMatchInlineSnapshot(`
1855
- "Uploaded test-name (TIMINGS)
1856
- Published test-name (TIMINGS)
1857
- test-name.test-sub-domain.workers.dev"
1858
- `);
1859
- expect(std.err).toMatchInlineSnapshot(`""`);
1860
- expect(std.warn).toMatchInlineSnapshot(`""`);
1861
- });
1862
-
1863
- it("should be able to use fallthrough:false for multiple rules", async () => {
1864
- writeWranglerToml({
1865
- rules: [
1866
- { type: "Text", globs: ["**/*.file"], fallthrough: false },
1867
- { type: "Text", globs: ["**/*.other"] },
1868
- ],
1869
- });
1870
- fs.writeFileSync(
1871
- "./index.js",
1872
- `import TEXT from './text.file'; import OTHER from './other.other'; export default {};`
1873
- );
1874
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1875
- fs.writeFileSync("./other.other", "SOME OTHER TEXT CONTENT");
1876
-
1877
- // We throw an error when we come across a file that matched a rule
1878
- // but was skipped because of fallthrough = false
1879
- let err: Error | undefined;
1880
- try {
1881
- await runWrangler("publish index.js");
1882
- } catch (e) {
1883
- err = e as Error;
1884
- }
1885
- expect(err?.message).toMatch(
1886
- `The file ./other.other matched a module rule in your configuration ({"type":"Text","globs":["**/*.other"]}), but was ignored because a previous rule with the same type was not marked as \`fallthrough = true\`.`
1887
- );
1888
- });
1889
-
1890
- it("should warn when multiple rules for the same type do not have fallback defined", async () => {
1891
- writeWranglerToml({
1892
- rules: [
1893
- { type: "Text", globs: ["**/*.file"] },
1894
- { type: "Text", globs: ["**/*.other"] },
1895
- ],
1896
- });
1897
- fs.writeFileSync(
1898
- "./index.js",
1899
- `import TEXT from './text.file'; import OTHER from './other.other'; export default {};`
1900
- );
1901
- fs.writeFileSync("./text.file", "SOME TEXT CONTENT");
1902
- fs.writeFileSync("./other.other", "SOME OTHER TEXT CONTENT");
1903
-
1904
- // We throw an error when we come across a file that matched a rule
1905
- // but was skipped because of fallthrough = false
1906
- let err: Error | undefined;
1907
- try {
1908
- await runWrangler("publish index.js");
1909
- } catch (e) {
1910
- err = e as Error;
1911
- }
1912
- expect(err?.message).toMatch(
1913
- `The file ./other.other matched a module rule in your configuration ({"type":"Text","globs":["**/*.other"]}), but was ignored because a previous rule with the same type was not marked as \`fallthrough = true\`.`
1914
- );
1915
- // and the warnings because fallthrough was not explicitly set
1916
- expect(std.warn).toMatchInlineSnapshot(`
1917
- "The module rule at position 1 ({\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.other\\"]}) has the same type as a previous rule (at position 0, {\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.file\\"]}). This rule will be ignored. To the previous rule, add \`fallthrough = true\` to allow this one to also be used, or \`fallthrough = false\` to silence this warning.
1918
- The default module rule {\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.txt\\",\\"**/*.html\\"]} has the same type as a previous rule (at position 0, {\\"type\\":\\"Text\\",\\"globs\\":[\\"**/*.file\\"]}). This rule will be ignored. To the previous rule, add \`fallthrough = true\` to allow the default one to also be used, or \`fallthrough = false\` to silence this warning."
1919
- `);
1920
- });
1921
- });
1922
- });
1923
-
1924
- /** Write a mock Worker script to disk. */
1925
- function writeWorkerSource({
1926
- basePath = ".",
1927
- format = "js",
1928
- type = "esm",
1929
- }: {
1930
- basePath?: string;
1931
- format?: "js" | "ts" | "jsx" | "tsx" | "mjs";
1932
- type?: "esm" | "sw";
1933
- } = {}) {
1934
- if (basePath !== ".") {
1935
- fs.mkdirSync(basePath, { recursive: true });
1936
- }
1937
- fs.writeFileSync(
1938
- `${basePath}/index.${format}`,
1939
- type === "esm"
1940
- ? `import { foo } from "./another";
1941
- export default {
1942
- async fetch(request) {
1943
- return new Response('Hello' + foo);
1944
- },
1945
- };`
1946
- : `import { foo } from "./another";
1947
- addEventListener('fetch', event => {
1948
- event.respondWith(new Response('Hello' + foo));
1949
- })`
1950
- );
1951
- fs.writeFileSync(`${basePath}/another.${format}`, `export const foo = 100;`);
1952
- }
1953
-
1954
- /** Write mock assets to the file system so they can be uploaded. */
1955
- function writeAssets(assets: { filePath: string; content: string }[]) {
1956
- for (const asset of assets) {
1957
- fs.mkdirSync(path.dirname(asset.filePath), { recursive: true });
1958
- fs.writeFileSync(asset.filePath, asset.content);
1959
- }
1960
- }
1961
-
1962
- /** Create a mock handler for the request to upload a worker script. */
1963
- function mockUploadWorkerRequest({
1964
- available_on_subdomain = true,
1965
- expectedEntry,
1966
- expectedType = "esm",
1967
- expectedBindings,
1968
- expectedModules = {},
1969
- env = undefined,
1970
- legacyEnv = false,
1971
- }: {
1972
- available_on_subdomain?: boolean;
1973
- expectedEntry?: string;
1974
- expectedType?: "esm" | "sw";
1975
- expectedBindings?: unknown;
1976
- expectedModules?: Record<string, string>;
1977
- env?: string | undefined;
1978
- legacyEnv?: boolean | undefined;
1979
- } = {}) {
1980
- setMockResponse(
1981
- env && !legacyEnv
1982
- ? "/accounts/:accountId/workers/services/:scriptName/environments/:envName"
1983
- : "/accounts/:accountId/workers/scripts/:scriptName",
1984
- "PUT",
1985
- async ([_url, accountId, scriptName, envName], { body }, queryParams) => {
1986
- expect(accountId).toEqual("some-account-id");
1987
- expect(scriptName).toEqual(
1988
- legacyEnv && env ? `test-name-${env}` : "test-name"
1989
- );
1990
- if (!legacyEnv) {
1991
- expect(envName).toEqual(env);
1992
- }
1993
- expect(queryParams.get("available_on_subdomain")).toEqual("true");
1994
- const formBody = body as FormData;
1995
- if (expectedEntry !== undefined) {
1996
- expect(await (formBody.get("index.js") as File).text()).toMatch(
1997
- expectedEntry
1998
- );
1999
- }
2000
-
2001
- const metadata = JSON.parse(
2002
- formBody.get("metadata") as string
2003
- ) as WorkerMetadata;
2004
- if (expectedType === "esm") {
2005
- expect(metadata.main_module).toEqual("index.js");
2006
- } else {
2007
- expect(metadata.body_part).toEqual("index.js");
2008
- }
2009
- if (expectedBindings !== undefined) {
2010
- expect(metadata.bindings).toEqual(expectedBindings);
2011
- }
2012
- for (const [name, content] of Object.entries(expectedModules)) {
2013
- expect(await (formBody.get(name) as File).text()).toEqual(content);
2014
- }
2015
-
2016
- return { available_on_subdomain };
2017
- }
2018
- );
2019
- }
2020
-
2021
- /** Create a mock handler for the request to get the account's subdomain. */
2022
- function mockSubDomainRequest(subdomain = "test-sub-domain") {
2023
- setMockResponse("/accounts/:accountId/workers/subdomain", "GET", () => {
2024
- return { subdomain };
2025
- });
2026
- }
2027
-
2028
- /** Create a mock handler to toggle a <script>.<user>.workers.dev subdomain */
2029
- function mockUpdateWorkerRequest({
2030
- env,
2031
- enabled,
2032
- legacyEnv = false,
2033
- }: {
2034
- enabled: boolean;
2035
- env?: string | undefined;
2036
- legacyEnv?: boolean | undefined;
2037
- }) {
2038
- const requests = { count: 0 };
2039
- const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
2040
- const environment = env && !legacyEnv ? "/environments/:envName" : "";
2041
- setMockResponse(
2042
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/subdomain`,
2043
- "POST",
2044
- ([_url, accountId, scriptName, envName], { body }) => {
2045
- expect(accountId).toEqual("some-account-id");
2046
- expect(scriptName).toEqual(
2047
- legacyEnv && env ? `test-name-${env}` : "test-name"
2048
- );
2049
- if (!legacyEnv) {
2050
- expect(envName).toEqual(env);
2051
- }
2052
- expect(JSON.parse(body as string)).toEqual({ enabled });
2053
- return null;
2054
- }
2055
- );
2056
- return requests;
2057
- }
2058
-
2059
- function mockPublishRoutesRequest({
2060
- routes,
2061
- env = undefined,
2062
- legacyEnv = false,
2063
- }: {
2064
- routes: string[];
2065
- env?: string | undefined;
2066
- legacyEnv?: boolean | undefined;
2067
- }) {
2068
- const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
2069
- const environment = env && !legacyEnv ? "/environments/:envName" : "";
2070
-
2071
- setMockResponse(
2072
- `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/routes`,
2073
- "PUT",
2074
- ([_url, accountId, scriptName, envName], { body }) => {
2075
- expect(accountId).toEqual("some-account-id");
2076
- expect(scriptName).toEqual(
2077
- legacyEnv && env ? `test-name-${env}` : "test-name"
2078
- );
2079
- if (!legacyEnv) {
2080
- expect(envName).toEqual(env);
2081
- }
2082
-
2083
- expect(JSON.parse(body as string)).toEqual(
2084
- routes.map((pattern) => ({ pattern }))
2085
- );
2086
- return null;
2087
- }
2088
- );
2089
- }
2090
-
2091
- /** Create a mock handler for the request to get a list of all KV namespaces. */
2092
- function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
2093
- setMockResponse(
2094
- "/accounts/:accountId/storage/kv/namespaces",
2095
- "GET",
2096
- ([_url, accountId]) => {
2097
- expect(accountId).toEqual("some-account-id");
2098
- return namespaces;
2099
- }
2100
- );
2101
- }
2102
-
2103
- /** Create a mock handler for the request that tries to do a bulk upload of assets to a KV namespace. */
2104
- function mockUploadAssetsToKVRequest(
2105
- expectedNamespaceId: string,
2106
- assets: { filePath: string; content: string }[]
2107
- ) {
2108
- setMockResponse(
2109
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
2110
- "PUT",
2111
- ([_url, accountId, namespaceId], { body }) => {
2112
- expect(accountId).toEqual("some-account-id");
2113
- expect(namespaceId).toEqual(expectedNamespaceId);
2114
- const uploads = JSON.parse(body as string);
2115
- expect(assets.length).toEqual(uploads.length);
2116
- for (let i = 0; i < uploads.length; i++) {
2117
- const asset = assets[i];
2118
- const upload = uploads[i];
2119
- // The asset key consists of:
2120
- // - the basename of the filepath
2121
- // - some hash value
2122
- // - the extension
2123
- const keyMatcher = new RegExp(
2124
- "^" +
2125
- asset.filePath
2126
- .replace(/(\.[^.]+)$/, ".[a-z0-9]+$1")
2127
- .replace(/\./g, "\\.")
2128
- );
2129
- expect(upload.key).toMatch(keyMatcher);
2130
- // The asset value is base64 encoded.
2131
- expect(upload.base64).toBe(true);
2132
- expect(Buffer.from(upload.value, "base64").toString()).toEqual(
2133
- asset.content
2134
- );
2135
- }
2136
- return null;
2137
- }
2138
- );
2139
- }