wrangler 0.0.0-e88a54e → 0.0.0-e95e5a0
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/README.md +25 -14
- package/bin/wrangler.js +13 -1
- package/miniflare-dist/index.mjs +4828 -21
- package/package.json +29 -24
- package/pages/functions/buildPlugin.ts +92 -0
- package/pages/functions/buildWorker.ts +80 -4
- package/pages/functions/filepath-routing.test.ts +11 -0
- package/pages/functions/filepath-routing.ts +8 -0
- package/pages/functions/routes.ts +6 -1
- package/pages/functions/template-plugin.ts +146 -0
- package/pages/functions/template-worker.ts +21 -8
- package/src/__tests__/config-cache.test.ts +36 -0
- package/src/__tests__/configuration.test.ts +530 -201
- package/src/__tests__/dev.test.tsx +284 -18
- package/src/__tests__/guess-worker-format.test.ts +28 -1
- package/src/__tests__/helpers/mock-cfetch.ts +5 -1
- package/src/__tests__/helpers/mock-console.ts +20 -3
- package/src/__tests__/helpers/mock-dialogs.ts +26 -1
- package/src/__tests__/helpers/mock-http-server.ts +46 -0
- package/src/__tests__/helpers/mock-istty.ts +27 -0
- package/src/__tests__/helpers/mock-oauth-flow.ts +255 -0
- package/src/__tests__/helpers/run-in-tmp.ts +7 -0
- package/src/__tests__/helpers/write-worker-source.ts +31 -0
- package/src/__tests__/https-options.test.ts +5 -2
- package/src/__tests__/index.test.ts +27 -769
- package/src/__tests__/init.test.ts +1516 -0
- package/src/__tests__/jest.setup.ts +4 -4
- package/src/__tests__/kv.test.ts +133 -61
- package/src/__tests__/logger.test.ts +115 -0
- package/src/__tests__/pages.test.ts +311 -26
- package/src/__tests__/publish.test.ts +2789 -618
- package/src/__tests__/r2.test.ts +26 -10
- package/src/__tests__/route.test.ts +4 -4
- package/src/__tests__/secret.test.ts +55 -34
- package/src/__tests__/tail.test.ts +146 -20
- package/src/__tests__/user.test.ts +131 -0
- package/src/__tests__/whoami.test.tsx +14 -9
- package/src/bundle.ts +30 -3
- package/src/cfetch/internal.ts +0 -2
- package/src/cli.ts +5 -11
- package/src/config/README.md +1 -1
- package/src/config/config.ts +20 -4
- package/src/config/environment.ts +32 -4
- package/src/config/index.ts +4 -3
- package/src/config/validation-helpers.ts +96 -7
- package/src/config/validation.ts +388 -54
- package/src/config-cache.ts +45 -0
- package/src/create-worker-preview.ts +22 -13
- package/src/create-worker-upload-form.ts +32 -9
- package/src/dev/dev-vars.ts +36 -0
- package/src/dev/dev.tsx +132 -78
- package/src/dev/local.tsx +101 -21
- package/src/dev/remote.tsx +23 -13
- package/src/dev/use-esbuild.ts +23 -5
- package/src/dialogs.tsx +16 -6
- package/src/entry.ts +83 -24
- package/src/environment-variables.ts +3 -1
- package/src/errors.ts +11 -0
- package/src/https-options.ts +3 -2
- package/src/index.tsx +689 -394
- package/src/inspect.ts +17 -11
- package/src/intl-polyfill.d.ts +139 -0
- package/src/logger.ts +66 -0
- package/src/miniflare-cli/index.ts +4 -0
- package/src/miniflare-cli/request-context.ts +40 -0
- package/src/module-collection.ts +7 -7
- package/src/open-in-browser.ts +5 -4
- package/src/package-manager.ts +9 -8
- package/src/pages.tsx +875 -56
- package/src/parse.ts +1 -1
- package/src/proxy.ts +28 -19
- package/src/publish.ts +263 -141
- package/src/sites.tsx +27 -14
- package/src/tail/index.ts +2 -2
- package/src/tail/printing.ts +13 -8
- package/src/update-check.ts +19 -0
- package/src/user.tsx +116 -41
- package/src/whoami.tsx +2 -1
- package/src/worker.ts +15 -6
- package/templates/gitignore +171 -0
- package/templates/static-asset-facade.js +1 -1
- package/wrangler-dist/cli.js +21162 -50227
- package/miniflare-dist/index.mjs.map +0 -7
- package/src/__tests__/dev2.test.tsx +0 -154
- package/src/__tests__/logout.test.ts +0 -52
- package/src/__tests__/sentry.test.ts +0 -146
- package/src/reporting.ts +0 -131
- package/wrangler-dist/cli.js.map +0 -7
|
@@ -1,44 +1,329 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
3
|
+
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
|
|
2
4
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
3
5
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
4
6
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
5
|
-
import type {
|
|
7
|
+
import type { Project, Deployment } from "../pages";
|
|
8
|
+
import type { File, FormData } from "undici";
|
|
6
9
|
|
|
7
|
-
describe("
|
|
8
|
-
let mockPackageManager: PackageManager;
|
|
10
|
+
describe("pages", () => {
|
|
9
11
|
runInTempDir();
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
mockPackageManager = {
|
|
13
|
-
cwd: process.cwd(),
|
|
14
|
-
// @ts-expect-error we're making a fake package manager here
|
|
15
|
-
type: "mockpm",
|
|
16
|
-
addDevDeps: jest.fn(),
|
|
17
|
-
install: jest.fn(),
|
|
18
|
-
};
|
|
19
|
-
(getPackageManager as jest.Mock).mockResolvedValue(mockPackageManager);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
12
|
const std = mockConsoleMethods();
|
|
23
13
|
function endEventLoop() {
|
|
24
14
|
return new Promise((resolve) => setImmediate(resolve));
|
|
25
15
|
}
|
|
26
|
-
|
|
16
|
+
|
|
17
|
+
it("should should display a list of available subcommands, for pages with no subcommand", async () => {
|
|
27
18
|
await runWrangler("pages");
|
|
28
19
|
await endEventLoop();
|
|
20
|
+
|
|
29
21
|
expect(std.out).toMatchInlineSnapshot(`
|
|
30
|
-
|
|
22
|
+
"wrangler pages
|
|
23
|
+
|
|
24
|
+
⚡️ Configure Cloudflare Pages
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
Commands:
|
|
27
|
+
wrangler pages dev [directory] [-- command] 🧑💻 Develop your full-stack Pages application locally
|
|
28
|
+
wrangler pages project ⚡️ Interact with your Pages projects
|
|
29
|
+
wrangler pages deployment 🚀 Interact with the deployments of a project
|
|
30
|
+
wrangler pages publish [directory] 🆙 Publish a directory of static assets as a Pages deployment
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
Flags:
|
|
33
|
+
-c, --config Path to .toml configuration file [string]
|
|
34
|
+
-h, --help Show help [boolean]
|
|
35
|
+
-v, --version Show version number [boolean]
|
|
36
|
+
--legacy-env Use legacy environments [boolean]
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
-c, --config Path to .toml configuration file [string]
|
|
39
|
-
-h, --help Show help [boolean]
|
|
40
|
-
-v, --version Show version number [boolean]
|
|
41
|
-
--legacy-env Use legacy environments [boolean]"
|
|
38
|
+
🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
42
39
|
`);
|
|
43
40
|
});
|
|
41
|
+
|
|
42
|
+
describe("beta message for subcommands", () => {
|
|
43
|
+
it("should display for pages:dev", async () => {
|
|
44
|
+
await expect(
|
|
45
|
+
runWrangler("pages dev")
|
|
46
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
47
|
+
`"Must specify a directory of static assets to serve or a command to run."`
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
51
|
+
"🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
|
|
52
|
+
|
|
53
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
54
|
+
`);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should display for pages:functions:build", async () => {
|
|
58
|
+
await expect(runWrangler("pages functions build")).rejects.toThrowError();
|
|
59
|
+
|
|
60
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
61
|
+
"🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
|
|
62
|
+
|
|
63
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
64
|
+
`);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe("project list", () => {
|
|
69
|
+
mockAccountId();
|
|
70
|
+
mockApiToken();
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
unsetAllMocks();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
function mockListRequest(projects: unknown[]) {
|
|
77
|
+
const requests = { count: 0 };
|
|
78
|
+
setMockResponse(
|
|
79
|
+
"/accounts/:accountId/pages/projects",
|
|
80
|
+
([_url, accountId], init, query) => {
|
|
81
|
+
requests.count++;
|
|
82
|
+
expect(accountId).toEqual("some-account-id");
|
|
83
|
+
expect(query.get("per_page")).toEqual("10");
|
|
84
|
+
expect(query.get("page")).toEqual(`${requests.count}`);
|
|
85
|
+
expect(init).toEqual({});
|
|
86
|
+
const pageSize = Number(query.get("per_page"));
|
|
87
|
+
const page = Number(query.get("page"));
|
|
88
|
+
return projects.slice((page - 1) * pageSize, page * pageSize);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
return requests;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
it("should make request to list projects", async () => {
|
|
95
|
+
const projects: Project[] = [
|
|
96
|
+
{
|
|
97
|
+
name: "dogs",
|
|
98
|
+
subdomain: "docs.pages.dev",
|
|
99
|
+
domains: ["dogs.pages.dev"],
|
|
100
|
+
source: {
|
|
101
|
+
type: "github",
|
|
102
|
+
},
|
|
103
|
+
latest_deployment: {
|
|
104
|
+
modified_on: "2021-11-17T14:52:26.133835Z",
|
|
105
|
+
},
|
|
106
|
+
created_on: "2021-11-17T14:52:26.133835Z",
|
|
107
|
+
production_branch: "main",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "cats",
|
|
111
|
+
subdomain: "cats.pages.dev",
|
|
112
|
+
domains: ["cats.pages.dev", "kitten.com"],
|
|
113
|
+
latest_deployment: {
|
|
114
|
+
modified_on: "2021-11-17T14:52:26.133835Z",
|
|
115
|
+
},
|
|
116
|
+
created_on: "2021-11-17T14:52:26.133835Z",
|
|
117
|
+
production_branch: "main",
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
const requests = mockListRequest(projects);
|
|
122
|
+
await runWrangler("pages project list");
|
|
123
|
+
|
|
124
|
+
expect(requests.count).toBe(1);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("should make multiple requests for paginated results", async () => {
|
|
128
|
+
const projects: Project[] = [];
|
|
129
|
+
for (let i = 0; i < 15; i++) {
|
|
130
|
+
projects.push({
|
|
131
|
+
name: "dogs" + i,
|
|
132
|
+
subdomain: i + "dogs.pages.dev",
|
|
133
|
+
domains: [i + "dogs.pages.dev"],
|
|
134
|
+
source: {
|
|
135
|
+
type: "github",
|
|
136
|
+
},
|
|
137
|
+
latest_deployment: {
|
|
138
|
+
modified_on: "2021-11-17T14:52:26.133835Z",
|
|
139
|
+
},
|
|
140
|
+
created_on: "2021-11-17T14:52:26.133835Z",
|
|
141
|
+
production_branch: "main",
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const requests = mockListRequest(projects);
|
|
145
|
+
await runWrangler("pages project list");
|
|
146
|
+
expect(requests.count).toEqual(2);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("project create", () => {
|
|
151
|
+
mockAccountId();
|
|
152
|
+
mockApiToken();
|
|
153
|
+
|
|
154
|
+
afterEach(() => {
|
|
155
|
+
unsetAllMocks();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("should create a project with a production branch", async () => {
|
|
159
|
+
setMockResponse(
|
|
160
|
+
"/accounts/:accountId/pages/projects",
|
|
161
|
+
([_url, accountId], init) => {
|
|
162
|
+
expect(accountId).toEqual("some-account-id");
|
|
163
|
+
expect(init.method).toEqual("POST");
|
|
164
|
+
const body = JSON.parse(init.body as string);
|
|
165
|
+
expect(body).toEqual({
|
|
166
|
+
name: "a-new-project",
|
|
167
|
+
production_branch: "main",
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
name: "a-new-project",
|
|
171
|
+
subdomain: "a-new-project.pages.dev",
|
|
172
|
+
production_branch: "main",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
await runWrangler(
|
|
177
|
+
"pages project create a-new-project --production-branch=main"
|
|
178
|
+
);
|
|
179
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
180
|
+
"✨ Successfully created the 'a-new-project' project. It will be available at https://a-new-project.pages.dev/ once you create your first deployment.
|
|
181
|
+
To deploy a folder of assets, run 'wrangler pages publish [directory]'."
|
|
182
|
+
`);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe("deployment list", () => {
|
|
187
|
+
mockAccountId();
|
|
188
|
+
mockApiToken();
|
|
189
|
+
|
|
190
|
+
afterEach(() => {
|
|
191
|
+
unsetAllMocks();
|
|
192
|
+
});
|
|
193
|
+
function mockListRequest(deployments: unknown[]) {
|
|
194
|
+
const requests = { count: 0 };
|
|
195
|
+
setMockResponse(
|
|
196
|
+
"/accounts/:accountId/pages/projects/:project/deployments",
|
|
197
|
+
([_url, accountId, project]) => {
|
|
198
|
+
requests.count++;
|
|
199
|
+
expect(project).toEqual("images");
|
|
200
|
+
expect(accountId).toEqual("some-account-id");
|
|
201
|
+
return deployments;
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
return requests;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
it("should make request to list deployments", async () => {
|
|
208
|
+
const deployments: Deployment[] = [
|
|
209
|
+
{
|
|
210
|
+
id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf",
|
|
211
|
+
url: "https://87bbc8fe.images.pages.dev",
|
|
212
|
+
environment: "preview",
|
|
213
|
+
latest_stage: {
|
|
214
|
+
ended_on: "2021-11-17T14:52:26.133835Z",
|
|
215
|
+
status: "success",
|
|
216
|
+
},
|
|
217
|
+
deployment_trigger: {
|
|
218
|
+
metadata: {
|
|
219
|
+
branch: "main",
|
|
220
|
+
commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
project_name: "images",
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const requests = mockListRequest(deployments);
|
|
228
|
+
await runWrangler("pages deployment list --project-name=images");
|
|
229
|
+
|
|
230
|
+
expect(requests.count).toBe(1);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe("deployment create", () => {
|
|
235
|
+
let actualProcessEnvCI: string | undefined;
|
|
236
|
+
|
|
237
|
+
mockAccountId();
|
|
238
|
+
mockApiToken();
|
|
239
|
+
runInTempDir();
|
|
240
|
+
|
|
241
|
+
beforeEach(() => {
|
|
242
|
+
actualProcessEnvCI = process.env.CI;
|
|
243
|
+
process.env.CI = "true";
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
afterEach(() => {
|
|
247
|
+
unsetAllMocks();
|
|
248
|
+
process.env.CI = actualProcessEnvCI;
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("should be aliased with 'wrangler pages publish'", async () => {
|
|
252
|
+
await runWrangler("pages publish --help");
|
|
253
|
+
await endEventLoop();
|
|
254
|
+
|
|
255
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
256
|
+
"wrangler pages publish [directory]
|
|
257
|
+
|
|
258
|
+
🆙 Publish a directory of static assets as a Pages deployment
|
|
259
|
+
|
|
260
|
+
Positionals:
|
|
261
|
+
directory The directory of Pages Functions [string] [default: \\"functions\\"]
|
|
262
|
+
|
|
263
|
+
Flags:
|
|
264
|
+
-c, --config Path to .toml configuration file [string]
|
|
265
|
+
-h, --help Show help [boolean]
|
|
266
|
+
-v, --version Show version number [boolean]
|
|
267
|
+
--legacy-env Use legacy environments [boolean]
|
|
268
|
+
|
|
269
|
+
Options:
|
|
270
|
+
--project-name The name of the project you want to list deployments for [string]
|
|
271
|
+
--branch The branch of the project you want to list deployments for [string]
|
|
272
|
+
--commit-hash The branch of the project you want to list deployments for [string]
|
|
273
|
+
--commit-message The branch of the project you want to list deployments for [string]
|
|
274
|
+
--commit-dirty The branch of the project you want to list deployments for [boolean]
|
|
275
|
+
|
|
276
|
+
🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
277
|
+
`);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it("should upload a directory of files", async () => {
|
|
281
|
+
writeFileSync("logo.png", "foobar");
|
|
282
|
+
|
|
283
|
+
setMockResponse(
|
|
284
|
+
"/accounts/:accountId/pages/projects/foo/file",
|
|
285
|
+
async ([_url, accountId], init) => {
|
|
286
|
+
expect(accountId).toEqual("some-account-id");
|
|
287
|
+
expect(init.method).toEqual("POST");
|
|
288
|
+
const body = init.body as FormData;
|
|
289
|
+
const logoPNGFile = body.get("file") as File;
|
|
290
|
+
expect(await logoPNGFile.text()).toEqual("foobar");
|
|
291
|
+
expect(logoPNGFile.name).toEqual("logo.png");
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
id: "2082190357cfd3617ccfe04f340c6247",
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
setMockResponse(
|
|
300
|
+
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
301
|
+
async ([_url, accountId], init) => {
|
|
302
|
+
expect(accountId).toEqual("some-account-id");
|
|
303
|
+
expect(init.method).toEqual("POST");
|
|
304
|
+
const body = init.body as FormData;
|
|
305
|
+
const manifest = JSON.parse(body.get("manifest") as string);
|
|
306
|
+
expect(manifest).toMatchInlineSnapshot(`
|
|
307
|
+
Object {
|
|
308
|
+
"/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
309
|
+
}
|
|
310
|
+
`);
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
await runWrangler("pages publish . --project-name=foo");
|
|
319
|
+
|
|
320
|
+
// TODO: Unmounting somehow loses this output
|
|
321
|
+
|
|
322
|
+
// expect(std.out).toMatchInlineSnapshot(`
|
|
323
|
+
// "✨ Success! Uploaded 1 files (TIMINGS)
|
|
324
|
+
|
|
325
|
+
// ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
|
|
326
|
+
// `);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
44
329
|
});
|