wrangler 0.0.0-e30d1013 → 0.0.0-e311bbbf

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 (236) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +126 -74
  4. package/package.json +26 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +567 -39
  9. package/src/__tests__/d1/d1.test.ts +82 -0
  10. package/src/__tests__/d1/execute.test.ts +66 -0
  11. package/src/__tests__/d1/migrate.test.ts +157 -0
  12. package/src/__tests__/d1/splitter.test.ts +255 -0
  13. package/src/__tests__/delete.test.ts +91 -49
  14. package/src/__tests__/deployments.test.ts +330 -52
  15. package/src/__tests__/dev.test.tsx +198 -90
  16. package/src/__tests__/generate.test.ts +8 -5
  17. package/src/__tests__/guess-worker-format.test.ts +35 -0
  18. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  19. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  20. package/src/__tests__/helpers/mock-console.ts +6 -0
  21. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  22. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  23. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  24. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  25. package/src/__tests__/helpers/mock-kv.ts +29 -16
  26. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  27. package/src/__tests__/helpers/mock-process.ts +8 -13
  28. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  29. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  30. package/src/__tests__/helpers/msw/handlers/deployments.ts +127 -26
  31. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  32. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  33. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  34. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  35. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  36. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  37. package/src/__tests__/helpers/msw/index.ts +32 -1
  38. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  39. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  40. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  41. package/src/__tests__/index.test.ts +90 -72
  42. package/src/__tests__/init.test.ts +927 -631
  43. package/src/__tests__/jest.setup.ts +19 -42
  44. package/src/__tests__/kv.test.ts +355 -231
  45. package/src/__tests__/logger.test.ts +68 -2
  46. package/src/__tests__/logout.test.ts +47 -0
  47. package/src/__tests__/metrics.test.ts +94 -51
  48. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  49. package/src/__tests__/middleware.test.ts +212 -122
  50. package/src/__tests__/mtls-certificates.test.ts +588 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +452 -0
  53. package/src/__tests__/pages/pages.test.ts +81 -0
  54. package/src/__tests__/pages/project-create.test.ts +63 -0
  55. package/src/__tests__/pages/project-list.test.ts +110 -0
  56. package/src/__tests__/pages/project-upload.test.ts +500 -0
  57. package/src/__tests__/pages/publish.test.ts +2864 -0
  58. package/src/__tests__/pages-deployment-tail.test.ts +955 -0
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +1620 -830
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +237 -76
  63. package/src/__tests__/r2.test.ts +37 -56
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +267 -109
  66. package/src/__tests__/test-old-node-version.js +3 -3
  67. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  68. package/src/__tests__/tsconfig-sanity.ts +12 -0
  69. package/src/__tests__/tsconfig.json +8 -0
  70. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  71. package/src/__tests__/type-generation.test.ts +11 -2
  72. package/src/__tests__/user.test.ts +35 -72
  73. package/src/__tests__/whoami.test.tsx +8 -114
  74. package/src/__tests__/worker-namespace.test.ts +83 -69
  75. package/src/api/dev.ts +168 -60
  76. package/src/api/index.ts +10 -1
  77. package/src/api/mtls-certificate.ts +148 -0
  78. package/src/api/pages/create-worker-bundle-contents.ts +76 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +355 -0
  81. package/src/bundle.ts +221 -128
  82. package/src/cfetch/index.ts +0 -2
  83. package/src/cfetch/internal.ts +16 -21
  84. package/src/cli.ts +4 -4
  85. package/src/config/config.ts +14 -7
  86. package/src/config/environment.ts +73 -16
  87. package/src/config/index.ts +99 -30
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +248 -9
  90. package/src/create-worker-preview.ts +19 -8
  91. package/src/create-worker-upload-form.ts +48 -5
  92. package/src/d1/backups.tsx +43 -42
  93. package/src/d1/create.tsx +26 -21
  94. package/src/d1/{delete.tsx → delete.ts} +11 -14
  95. package/src/d1/execute.tsx +183 -170
  96. package/src/d1/index.ts +7 -6
  97. package/src/d1/list.tsx +22 -10
  98. package/src/d1/migrations/apply.tsx +212 -0
  99. package/src/d1/migrations/create.tsx +79 -0
  100. package/src/d1/migrations/helpers.ts +172 -0
  101. package/src/d1/migrations/index.ts +3 -0
  102. package/src/d1/migrations/list.tsx +95 -0
  103. package/src/d1/migrations/options.ts +23 -0
  104. package/src/d1/options.ts +3 -3
  105. package/src/d1/splitter.ts +161 -0
  106. package/src/d1/{types.tsx → types.ts} +1 -0
  107. package/src/d1/utils.ts +2 -1
  108. package/src/delete.ts +8 -16
  109. package/src/deployments.ts +333 -42
  110. package/src/deprecated/index.ts +8 -302
  111. package/src/dev/dev.tsx +57 -44
  112. package/src/dev/local.tsx +248 -74
  113. package/src/dev/remote.tsx +32 -3
  114. package/src/dev/start-server.ts +81 -66
  115. package/src/dev/use-esbuild.ts +17 -18
  116. package/src/dev/validate-dev-props.ts +9 -0
  117. package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
  118. package/src/dev.tsx +178 -117
  119. package/src/dialogs.ts +136 -0
  120. package/src/dispatch-namespace.ts +21 -17
  121. package/src/docs/index.ts +97 -0
  122. package/src/entry.ts +19 -11
  123. package/src/environment-variables/factory.ts +88 -0
  124. package/src/environment-variables/misc-variables.ts +30 -0
  125. package/src/generate/index.ts +298 -0
  126. package/src/git-client.ts +15 -4
  127. package/src/{index.tsx → index.ts} +134 -59
  128. package/src/init.ts +249 -187
  129. package/src/inspect.ts +16 -1
  130. package/src/jest.d.ts +4 -0
  131. package/src/kv/index.ts +15 -17
  132. package/src/logger.ts +32 -5
  133. package/src/metrics/metrics-config.ts +3 -3
  134. package/src/metrics/send-event.ts +6 -1
  135. package/src/miniflare-cli/assets.ts +64 -28
  136. package/src/miniflare-cli/index.ts +4 -7
  137. package/src/miniflare-cli/tsconfig.json +9 -0
  138. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  139. package/src/miniflare-cli/types.ts +11 -0
  140. package/src/module-collection.ts +91 -25
  141. package/src/mtls-certificate/cli.ts +155 -0
  142. package/src/pages/build.ts +410 -0
  143. package/src/pages/buildFunctions.ts +140 -0
  144. package/src/pages/deployment-tails.ts +281 -0
  145. package/src/pages/deployments.tsx +11 -33
  146. package/src/pages/{dev.tsx → dev.ts} +147 -139
  147. package/src/pages/errors.ts +1 -0
  148. package/src/pages/functions/buildPlugin.ts +61 -54
  149. package/src/pages/functions/buildWorker.ts +159 -33
  150. package/src/pages/functions/tsconfig.json +8 -0
  151. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  152. package/src/pages/{functions.tsx → functions.ts} +8 -4
  153. package/src/pages/{index.tsx → index.ts} +11 -3
  154. package/src/pages/projects.tsx +12 -22
  155. package/src/pages/prompt-select-project.tsx +31 -0
  156. package/src/pages/publish.tsx +46 -225
  157. package/src/pages/types.ts +6 -9
  158. package/src/pages/upload.tsx +58 -14
  159. package/src/pages/utils.ts +12 -1
  160. package/src/parse.ts +23 -1
  161. package/src/paths.ts +1 -1
  162. package/src/proxy.ts +5 -0
  163. package/src/publish/index.ts +20 -16
  164. package/src/publish/publish.ts +71 -46
  165. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  166. package/src/queues/cli/commands/consumer/add.ts +24 -24
  167. package/src/queues/cli/commands/consumer/index.ts +3 -6
  168. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  169. package/src/queues/cli/commands/create.ts +8 -8
  170. package/src/queues/cli/commands/delete.ts +8 -8
  171. package/src/queues/cli/commands/index.ts +6 -4
  172. package/src/queues/cli/commands/list.ts +8 -8
  173. package/src/queues/client.ts +1 -0
  174. package/src/queues/utils.ts +18 -0
  175. package/src/r2/helpers.ts +1 -0
  176. package/src/r2/index.ts +28 -28
  177. package/src/secret/index.ts +14 -16
  178. package/src/{sites.tsx → sites.ts} +1 -1
  179. package/src/tail/createTail.ts +94 -3
  180. package/src/tail/filters.ts +1 -1
  181. package/src/tail/index.ts +8 -11
  182. package/src/tail/printing.ts +15 -0
  183. package/src/traverse-module-graph.ts +53 -0
  184. package/src/tsconfig-sanity.ts +16 -0
  185. package/src/type-generation.ts +28 -20
  186. package/src/user/access.ts +0 -1
  187. package/src/user/auth-variables.ts +113 -0
  188. package/src/user/choose-account.tsx +1 -31
  189. package/src/user/index.ts +0 -1
  190. package/src/user/{user.tsx → user.ts} +123 -82
  191. package/src/utils/render.ts +93 -0
  192. package/src/{whoami.tsx → whoami.ts} +37 -71
  193. package/src/worker.ts +30 -1
  194. package/src/yargs-types.ts +22 -5
  195. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  196. package/templates/__tests__/tsconfig.json +8 -0
  197. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  198. package/templates/checked-fetch.js +9 -3
  199. package/templates/d1-beta-facade.js +51 -3
  200. package/templates/facade.d.ts +14 -0
  201. package/templates/first-party-worker-module-facade.ts +4 -3
  202. package/templates/format-dev-errors.ts +8 -6
  203. package/templates/gitignore +1 -0
  204. package/templates/init-tests/test-jest-new-worker.js +3 -5
  205. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  206. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  207. package/templates/middleware/loader-modules.ts +2 -2
  208. package/templates/middleware/loader-sw.ts +51 -31
  209. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  210. package/templates/new-worker.ts +3 -0
  211. package/templates/pages-dev-pipeline.ts +4 -1
  212. package/templates/pages-shim.ts +4 -1
  213. package/templates/pages-template-plugin.ts +19 -10
  214. package/templates/serve-static-assets.ts +17 -14
  215. package/templates/service-bindings-module-facade.js +1 -0
  216. package/templates/tsconfig-sanity.ts +11 -0
  217. package/templates/tsconfig.init.json +105 -0
  218. package/templates/tsconfig.json +5 -103
  219. package/templates/tsconfig.tsbuildinfo +1 -0
  220. package/wrangler-dist/cli.d.ts +820 -70
  221. package/wrangler-dist/cli.js +68161 -78780
  222. package/wrangler-dist/wasm-sync.wasm +0 -0
  223. package/src/__tests__/api-devregistry.test.js +0 -56
  224. package/src/__tests__/d1.test.ts +0 -74
  225. package/src/__tests__/dialogs.test.tsx +0 -40
  226. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  227. package/src/__tests__/pages.test.ts +0 -2387
  228. package/src/d1/migrations.tsx +0 -446
  229. package/src/dialogs.tsx +0 -169
  230. package/src/environment-variables.ts +0 -50
  231. package/src/pages/build.tsx +0 -270
  232. package/src/user/env-vars.ts +0 -46
  233. package/templates/experimental-local-cache-stubs.js +0 -27
  234. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  235. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  236. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,12 +1,8 @@
1
1
  import { execSync } from "node:child_process";
2
- import { existsSync, readFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { dirname, join } from "node:path";
5
- import { cwd } from "node:process";
6
2
  import { render, Text } from "ink";
7
3
  import SelectInput from "ink-select-input";
8
4
  import React from "react";
9
- import { File, FormData } from "undici";
5
+ import { publish } from "../api/pages/publish";
10
6
  import { fetchResult } from "../cfetch";
11
7
  import { getConfigCache, saveToConfigCache } from "../config-cache";
12
8
  import { prompt } from "../dialogs";
@@ -14,20 +10,20 @@ import { FatalError } from "../errors";
14
10
  import { logger } from "../logger";
15
11
  import * as metrics from "../metrics";
16
12
  import { requireAuth } from "../user";
17
- import { buildFunctions } from "./build";
18
13
  import { PAGES_CONFIG_CACHE_FILENAME } from "./constants";
19
- import { FunctionsNoRoutesError, getFunctionsNoRoutesWarning } from "./errors";
20
- import { validateRoutes } from "./functions/routes-validation";
21
14
  import { listProjects } from "./projects";
22
- import { upload } from "./upload";
15
+ import { promptSelectProject } from "./prompt-select-project";
23
16
  import { pagesBetaWarning } from "./utils";
24
- import type { PagesConfigCache, YargsOptionsToInterface } from "./types";
25
- import type { Project, Deployment } from "@cloudflare/types";
26
- import type { Argv } from "yargs";
17
+ import type {
18
+ CommonYargsArgv,
19
+ StrictYargsOptionsToInterface,
20
+ } from "../yargs-types";
21
+ import type { PagesConfigCache } from "./types";
22
+ import type { Project } from "@cloudflare/types";
27
23
 
28
- type PublishArgs = YargsOptionsToInterface<typeof Options>;
24
+ type PublishArgs = StrictYargsOptionsToInterface<typeof Options>;
29
25
 
30
- export function Options(yargs: Argv) {
26
+ export function Options(yargs: CommonYargsArgv) {
31
27
  return yargs
32
28
  .positional("directory", {
33
29
  type: "string",
@@ -56,6 +52,20 @@ export function Options(yargs: Argv) {
56
52
  description:
57
53
  "Whether or not the workspace should be considered dirty for this deployment",
58
54
  },
55
+ "skip-caching": {
56
+ type: "boolean",
57
+ description: "Skip asset caching which speeds up builds",
58
+ },
59
+ bundle: {
60
+ type: "boolean",
61
+ default: undefined,
62
+ hidden: true,
63
+ },
64
+ "no-bundle": {
65
+ type: "boolean",
66
+ default: false,
67
+ description: "Whether to run bundling on `_worker.js` before deploying",
68
+ },
59
69
  config: {
60
70
  describe: "Pages does not support wrangler.toml",
61
71
  type: "string",
@@ -72,6 +82,9 @@ export const Handler = async ({
72
82
  commitHash,
73
83
  commitMessage,
74
84
  commitDirty,
85
+ skipCaching,
86
+ bundle,
87
+ noBundle,
75
88
  config: wranglerConfig,
76
89
  }: PublishArgs) => {
77
90
  if (wranglerConfig) {
@@ -128,24 +141,7 @@ export const Handler = async ({
128
141
 
129
142
  switch (existingOrNew) {
130
143
  case "existing": {
131
- projectName = await new Promise((resolve) => {
132
- const { unmount } = render(
133
- <>
134
- <Text>Select a project:</Text>
135
- <SelectInput
136
- items={projects.map((project) => ({
137
- key: project.name,
138
- label: project.name,
139
- value: project,
140
- }))}
141
- onSelect={async (selected) => {
142
- resolve(selected.value.name);
143
- unmount();
144
- }}
145
- />
146
- </>
147
- );
148
- });
144
+ projectName = await promptSelectProject({ accountId });
149
145
  break;
150
146
  }
151
147
  case "new": {
@@ -166,10 +162,11 @@ export const Handler = async ({
166
162
 
167
163
  const productionBranch = await prompt(
168
164
  "Enter the production branch name:",
169
- "text",
170
- isGitDir
171
- ? execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim()
172
- : "production"
165
+ {
166
+ defaultValue: isGitDir
167
+ ? execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim()
168
+ : "production",
169
+ }
173
170
  );
174
171
 
175
172
  if (!productionBranch) {
@@ -244,195 +241,19 @@ export const Handler = async ({
244
241
  }
245
242
  }
246
243
 
247
- let _headers: string | undefined,
248
- _redirects: string | undefined,
249
- _routesGenerated: string | undefined,
250
- _routesCustom: string | undefined,
251
- _workerJS: string | undefined;
252
-
253
- try {
254
- _headers = readFileSync(join(directory, "_headers"), "utf-8");
255
- } catch {}
256
-
257
- try {
258
- _redirects = readFileSync(join(directory, "_redirects"), "utf-8");
259
- } catch {}
260
-
261
- try {
262
- /**
263
- * Developers can specify a custom _routes.json file, for projects with Pages
264
- * Functions or projects in Advanced Mode
265
- */
266
- _routesCustom = readFileSync(join(directory, "_routes.json"), "utf-8");
267
- } catch {}
268
-
269
- try {
270
- _workerJS = readFileSync(join(directory, "_worker.js"), "utf-8");
271
- } catch {}
272
-
273
- // Grab the bindings from the API, we need these for shims and other such hacky inserts
274
- const project = await fetchResult<Project>(
275
- `/accounts/${accountId}/pages/projects/${projectName}`
276
- );
277
- let isProduction = true;
278
- if (branch) {
279
- isProduction = project.production_branch === branch;
280
- }
281
-
282
- /**
283
- * Evaluate if this is an Advanced Mode or Pages Functions project. If Advanced Mode, we'll
284
- * go ahead and upload `_worker.js` as is, but if Pages Functions, we need to attempt to build
285
- * Functions first and exit if it failed
286
- */
287
- let builtFunctions: string | undefined = undefined;
288
- const functionsDirectory = join(cwd(), "functions");
289
- const routesOutputPath = !existsSync(join(directory, "_routes.json"))
290
- ? join(tmpdir(), `_routes-${Math.random()}.json`)
291
- : undefined;
292
-
293
- if (!_workerJS && existsSync(functionsDirectory)) {
294
- const outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`);
295
- try {
296
- await buildFunctions({
297
- outfile,
298
- functionsDirectory,
299
- onEnd: () => {},
300
- buildOutputDirectory: dirname(outfile),
301
- routesOutputPath,
302
- local: false,
303
- d1Databases: Object.keys(
304
- project.deployment_configs[isProduction ? "production" : "preview"]
305
- .d1_databases ?? {}
306
- ),
307
- });
308
-
309
- builtFunctions = readFileSync(outfile, "utf-8");
310
- } catch (e) {
311
- if (e instanceof FunctionsNoRoutesError) {
312
- logger.warn(
313
- getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
314
- );
315
- } else {
316
- throw e;
317
- }
318
- }
319
- }
320
-
321
- const manifest = await upload({ directory, accountId, projectName });
322
-
323
- const formData = new FormData();
324
-
325
- formData.append("manifest", JSON.stringify(manifest));
326
-
327
- if (branch) {
328
- formData.append("branch", branch);
329
- }
330
-
331
- if (commitMessage) {
332
- formData.append("commit_message", commitMessage);
333
- }
334
-
335
- if (commitHash) {
336
- formData.append("commit_hash", commitHash);
337
- }
338
-
339
- if (commitDirty !== undefined) {
340
- formData.append("commit_dirty", commitDirty);
341
- }
342
-
343
- if (_headers) {
344
- formData.append("_headers", new File([_headers], "_headers"));
345
- logger.log(`✨ Uploading _headers`);
346
- }
347
-
348
- if (_redirects) {
349
- formData.append("_redirects", new File([_redirects], "_redirects"));
350
- logger.log(`✨ Uploading _redirects`);
351
- }
352
-
353
- /**
354
- * Advanced Mode
355
- * https://developers.cloudflare.com/pages/platform/functions/#advanced-mode
356
- *
357
- * When using a _worker.js file, the entire /functions directory is ignored
358
- * – this includes its routing and middleware characteristics.
359
- */
360
- if (_workerJS) {
361
- formData.append("_worker.js", new File([_workerJS], "_worker.js"));
362
- logger.log(`✨ Uploading _worker.js`);
363
-
364
- if (_routesCustom) {
365
- // user provided a custom _routes.json file
366
- try {
367
- const routesCustomJSON = JSON.parse(_routesCustom);
368
- validateRoutes(routesCustomJSON, join(directory, "_routes.json"));
369
-
370
- formData.append(
371
- "_routes.json",
372
- new File([_routesCustom], "_routes.json")
373
- );
374
- logger.log(`✨ Uploading _routes.json`);
375
- logger.warn(
376
- `_routes.json is an experimental feature and is subject to change. Please use with care.`
377
- );
378
- } catch (err) {
379
- if (err instanceof FatalError) {
380
- throw err;
381
- }
382
- }
383
- }
384
- }
385
-
386
- /**
387
- * Pages Functions
388
- * https://developers.cloudflare.com/pages/platform/functions/
389
- */
390
- if (builtFunctions && !_workerJS) {
391
- // if Functions were build successfully, proceed to uploading the build file
392
- formData.append("_worker.js", new File([builtFunctions], "_worker.js"));
393
- logger.log(`✨ Uploading Functions`);
394
-
395
- if (_routesCustom) {
396
- // user provided a custom _routes.json file
397
- try {
398
- const routesCustomJSON = JSON.parse(_routesCustom);
399
- validateRoutes(routesCustomJSON, join(directory, "_routes.json"));
400
-
401
- formData.append(
402
- "_routes.json",
403
- new File([_routesCustom], "_routes.json")
404
- );
405
- logger.log(`✨ Uploading _routes.json`);
406
- logger.warn(
407
- `_routes.json is an experimental feature and is subject to change. Please use with care.`
408
- );
409
- } catch (err) {
410
- if (err instanceof FatalError) {
411
- throw err;
412
- }
413
- }
414
- } else if (routesOutputPath) {
415
- // no custom _routes.json file found, so fallback to the generated one
416
- try {
417
- _routesGenerated = readFileSync(routesOutputPath, "utf-8");
418
-
419
- if (_routesGenerated) {
420
- formData.append(
421
- "_routes.json",
422
- new File([_routesGenerated], "_routes.json")
423
- );
424
- }
425
- } catch {}
426
- }
427
- }
428
-
429
- const deploymentResponse = await fetchResult<Deployment>(
430
- `/accounts/${accountId}/pages/projects/${projectName}/deployments`,
431
- {
432
- method: "POST",
433
- body: formData,
434
- }
435
- );
244
+ const deploymentResponse = await publish({
245
+ directory,
246
+ accountId,
247
+ projectName,
248
+ branch,
249
+ skipCaching,
250
+ commitMessage,
251
+ commitHash,
252
+ commitDirty,
253
+ // TODO: Here lies a known bug. If you specify both `--bundle` and `--no-bundle`, this behavior is undefined and you will get unexpected results.
254
+ // There is no sane way to get the true value out of yargs, so here we are.
255
+ bundle: bundle ?? !noBundle,
256
+ });
436
257
 
437
258
  saveToConfigCache<PagesConfigCache>(PAGES_CONFIG_CACHE_FILENAME, {
438
259
  account_id: accountId,
@@ -1,12 +1,3 @@
1
- import type { ArgumentsCamelCase, Argv } from "yargs";
2
-
3
- /**
4
- * Given some Yargs Options function factory, extract the interface
5
- * that corresponds to the yargs arguments
6
- */
7
- export type YargsOptionsToInterface<T extends (yargs: Argv) => Argv> =
8
- T extends (yargs: Argv) => Argv<infer P> ? ArgumentsCamelCase<P> : never;
9
-
10
1
  export type Project = {
11
2
  name: string;
12
3
  subdomain: string;
@@ -19,9 +10,15 @@ export type Project = {
19
10
  };
20
11
  created_on: string;
21
12
  production_branch: string;
13
+ deployment_configs?: {
14
+ production?: {
15
+ d1_databases?: Record<string, { id: string }>;
16
+ };
17
+ };
22
18
  };
23
19
  export type Deployment = {
24
20
  id: string;
21
+ created_on: string;
25
22
  environment: string;
26
23
  deployment_trigger: {
27
24
  metadata: {
@@ -22,12 +22,15 @@ import {
22
22
  } from "./constants";
23
23
  import { hashFile } from "./hash";
24
24
  import { pagesBetaWarning } from "./utils";
25
- import type { UploadPayloadFile, YargsOptionsToInterface } from "./types";
26
- import type { Argv } from "yargs";
25
+ import type {
26
+ CommonYargsArgv,
27
+ StrictYargsOptionsToInterface,
28
+ } from "../yargs-types";
29
+ import type { UploadPayloadFile } from "./types";
27
30
 
28
- type UploadArgs = YargsOptionsToInterface<typeof Options>;
31
+ type UploadArgs = StrictYargsOptionsToInterface<typeof Options>;
29
32
 
30
- export function Options(yargs: Argv) {
33
+ export function Options(yargs: CommonYargsArgv) {
31
34
  return yargs
32
35
  .positional("directory", {
33
36
  type: "string",
@@ -39,6 +42,10 @@ export function Options(yargs: Argv) {
39
42
  type: "string",
40
43
  description: "The name of the project you want to deploy to",
41
44
  },
45
+ "skip-caching": {
46
+ type: "boolean",
47
+ description: "Skip asset caching which speeds up builds",
48
+ },
42
49
  })
43
50
  .epilogue(pagesBetaWarning);
44
51
  }
@@ -46,6 +53,7 @@ export function Options(yargs: Argv) {
46
53
  export const Handler = async ({
47
54
  directory,
48
55
  outputManifestPath,
56
+ skipCaching,
49
57
  }: UploadArgs) => {
50
58
  if (!directory) {
51
59
  throw new FatalError("Must specify a directory.", 1);
@@ -58,6 +66,7 @@ export const Handler = async ({
58
66
  const manifest = await upload({
59
67
  directory,
60
68
  jwt: process.env.CF_PAGES_UPLOAD_JWT,
69
+ skipCaching: skipCaching ?? false,
61
70
  });
62
71
 
63
72
  if (outputManifestPath) {
@@ -73,8 +82,14 @@ export const upload = async (
73
82
  | {
74
83
  directory: string;
75
84
  jwt: string;
85
+ skipCaching: boolean;
86
+ }
87
+ | {
88
+ directory: string;
89
+ accountId: string;
90
+ projectName: string;
91
+ skipCaching: boolean;
76
92
  }
77
- | { directory: string; accountId: string; projectName: string }
78
93
  ) => {
79
94
  async function fetchJwt(): Promise<string> {
80
95
  if ("jwt" in args) {
@@ -183,7 +198,12 @@ export const upload = async (
183
198
  const start = Date.now();
184
199
 
185
200
  let attempts = 0;
186
- const getMissingHashes = async (): Promise<string[]> => {
201
+ const getMissingHashes = async (skipCaching: boolean): Promise<string[]> => {
202
+ if (skipCaching) {
203
+ logger.debug("Force skipping cache");
204
+ return files.map(({ hash }) => hash);
205
+ }
206
+
187
207
  try {
188
208
  return await fetchResult<string[]>(`/pages/assets/check-missing`, {
189
209
  method: "POST",
@@ -206,13 +226,13 @@ export const upload = async (
206
226
  // Looks like the JWT expired, fetch another one
207
227
  jwt = await fetchJwt();
208
228
  }
209
- return getMissingHashes();
229
+ return getMissingHashes(skipCaching);
210
230
  } else {
211
231
  throw e;
212
232
  }
213
233
  }
214
234
  };
215
- const missingHashes = await getMissingHashes();
235
+ const missingHashes = await getMissingHashes(args.skipCaching);
216
236
 
217
237
  const sortedFiles = files
218
238
  .filter((file) => missingHashes.includes(file.hash))
@@ -256,9 +276,7 @@ export const upload = async (
256
276
  }
257
277
 
258
278
  let counter = fileMap.size - sortedFiles.length;
259
- const { rerender, unmount } = render(
260
- <Progress done={counter} total={fileMap.size} />
261
- );
279
+ const { rerender, unmount } = renderProgress(counter, fileMap.size);
262
280
 
263
281
  const queue = new PQueue({ concurrency: BULK_UPLOAD_CONCURRENCY });
264
282
 
@@ -282,7 +300,8 @@ export const upload = async (
282
300
  );
283
301
 
284
302
  try {
285
- return await fetchResult(`/pages/assets/upload`, {
303
+ logger.debug("POST /pages/assets/upload");
304
+ const res = await fetchResult(`/pages/assets/upload`, {
286
305
  method: "POST",
287
306
  headers: {
288
307
  "Content-Type": "application/json",
@@ -290,8 +309,10 @@ export const upload = async (
290
309
  },
291
310
  body: JSON.stringify(payload),
292
311
  });
312
+ logger.debug("result:", res);
293
313
  } catch (e) {
294
314
  if (attempts < MAX_UPLOAD_ATTEMPTS) {
315
+ logger.debug("failed:", e, "retrying...");
295
316
  // Exponential backoff, 1 second first time, then 2 second, then 4 second etc.
296
317
  await new Promise((resolvePromise) =>
297
318
  setTimeout(resolvePromise, Math.pow(2, attempts++) * 1000)
@@ -303,16 +324,17 @@ export const upload = async (
303
324
  }
304
325
  return doUpload();
305
326
  } else {
327
+ logger.debug("failed:", e);
306
328
  throw e;
307
329
  }
308
330
  }
309
331
  };
310
332
 
311
- queue.add(() =>
333
+ void queue.add(() =>
312
334
  doUpload().then(
313
335
  () => {
314
336
  counter += bucket.files.length;
315
- rerender(<Progress done={counter} total={fileMap.size} />);
337
+ rerender(counter, fileMap.size);
316
338
  },
317
339
  (error) => {
318
340
  return Promise.reject(
@@ -413,6 +435,28 @@ function formatTime(duration: number) {
413
435
  return `(${(duration / 1000).toFixed(2)} sec)`;
414
436
  }
415
437
 
438
+ function renderProgress(done: number, total: number) {
439
+ if (isInteractive()) {
440
+ const { rerender, unmount } = render(
441
+ <Progress done={done} total={total} />
442
+ );
443
+ return {
444
+ // eslint-disable-next-line no-shadow
445
+ rerender(done: number, total: number) {
446
+ rerender(<Progress done={done} total={total} />);
447
+ },
448
+ unmount,
449
+ };
450
+ } else {
451
+ // eslint-disable-next-line no-shadow
452
+ const rerender = (done: number, total: number) => {
453
+ logger.log(`Uploading... (${done}/${total})`);
454
+ };
455
+ rerender(done, total);
456
+ return { rerender, unmount() {} };
457
+ }
458
+ }
459
+
416
460
  function Progress({ done, total }: { done: number; total: number }) {
417
461
  return (
418
462
  <>
@@ -9,4 +9,15 @@ export const CLEANUP = () => {
9
9
  };
10
10
 
11
11
  export const pagesBetaWarning =
12
- "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
12
+ "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose";
13
+
14
+ export function isUrl(maybeUrl?: string): maybeUrl is string {
15
+ if (!maybeUrl) return false;
16
+
17
+ try {
18
+ new URL(maybeUrl);
19
+ return true;
20
+ } catch (e) {
21
+ return false;
22
+ }
23
+ }
package/src/parse.ts CHANGED
@@ -2,8 +2,12 @@ import * as fs from "node:fs";
2
2
  import { resolve } from "node:path";
3
3
  import TOML from "@iarna/toml";
4
4
  import { formatMessagesSync } from "esbuild";
5
+ import {
6
+ parse as jsoncParse,
7
+ printParseErrorCode,
8
+ type ParseError as JsoncParseError,
9
+ } from "jsonc-parser";
5
10
  import { logger } from "./logger";
6
-
7
11
  export type Message = {
8
12
  text: string;
9
13
  location?: Location;
@@ -139,6 +143,24 @@ export function parseJSON<T>(input: string, file?: string): T {
139
143
  }
140
144
  }
141
145
 
146
+ /**
147
+ * A wrapper around `JSONC.parse` that throws a `ParseError`.
148
+ */
149
+ export function parseJSONC<T>(input: string, file?: string): T {
150
+ const errors: JsoncParseError[] = [];
151
+ const data = jsoncParse(input, errors);
152
+ if (errors.length) {
153
+ throw new ParseError({
154
+ text: printParseErrorCode(errors[0].error),
155
+ location: {
156
+ ...indexLocation({ file, fileText: input }, errors[0].offset + 1),
157
+ length: errors[0].length,
158
+ },
159
+ });
160
+ }
161
+ return data;
162
+ }
163
+
142
164
  /**
143
165
  * Reads a file into a node Buffer.
144
166
  */
package/src/paths.ts CHANGED
@@ -59,7 +59,7 @@ export function readableRelative(to: string) {
59
59
  declare const __RELATIVE_PACKAGE_PATH__: string;
60
60
 
61
61
  /**
62
- * Use this function (rather than node.js constants like `__dirname`) to specify
62
+ * Use this function (rather than Node.js constants like `__dirname`) to specify
63
63
  * paths that are relative to the base path of the Wrangler package.
64
64
  *
65
65
  * It is important to use this function because it reliably maps to the root of the package
package/src/proxy.ts CHANGED
@@ -651,6 +651,11 @@ export async function waitForPortToBeAvailable(
651
651
  }
652
652
 
653
653
  function checkPort() {
654
+ if (port === 0) {
655
+ doResolve();
656
+ return;
657
+ }
658
+
654
659
  // Testing whether a port is 'available' involves simply
655
660
  // trying to make a server listen on that port, and retrying
656
661
  // until it succeeds.
@@ -13,14 +13,12 @@ import { getAssetPaths, getSiteAssetPaths } from "../sites";
13
13
  import { requireAuth } from "../user";
14
14
  import { collectKeyValues } from "../utils/collectKeyValues";
15
15
  import publish from "./publish";
16
- import type { ConfigPath } from "../index";
17
16
  import type {
18
- CommonYargsOptions,
19
- YargsOptionsToInterface,
17
+ CommonYargsArgv,
18
+ StrictYargsOptionsToInterface,
20
19
  } from "../yargs-types";
21
- import type { Argv, ArgumentsCamelCase } from "yargs";
22
20
 
23
- export function publishOptions(yargs: Argv<CommonYargsOptions>) {
21
+ export function publishOptions(yargs: CommonYargsArgv) {
24
22
  return (
25
23
  yargs
26
24
  .positional("script", {
@@ -82,6 +80,13 @@ export function publishOptions(yargs: Argv<CommonYargsOptions>) {
82
80
  deprecated: true,
83
81
  hidden: true,
84
82
  })
83
+ .option("public", {
84
+ describe: "Static assets to be served",
85
+ type: "string",
86
+ requiresArg: true,
87
+ deprecated: true,
88
+ hidden: true,
89
+ })
85
90
  .option("assets", {
86
91
  describe: "Static assets to be served",
87
92
  type: "string",
@@ -153,7 +158,7 @@ export function publishOptions(yargs: Argv<CommonYargsOptions>) {
153
158
  type: "boolean",
154
159
  })
155
160
  .option("node-compat", {
156
- describe: "Enable node.js compatibility",
161
+ describe: "Enable Node.js compatibility",
157
162
  type: "boolean",
158
163
  })
159
164
  .option("dry-run", {
@@ -179,14 +184,13 @@ export function publishOptions(yargs: Argv<CommonYargsOptions>) {
179
184
  );
180
185
  }
181
186
 
182
- type PublishArgs = YargsOptionsToInterface<typeof publishOptions>;
183
-
184
- export async function publishHandler(args: ArgumentsCamelCase<PublishArgs>) {
187
+ export async function publishHandler(
188
+ args: StrictYargsOptionsToInterface<typeof publishOptions>
189
+ ) {
185
190
  await printWranglerBanner();
186
191
 
187
192
  const configPath =
188
- (args.config as ConfigPath) ||
189
- (args.script && findWranglerToml(path.dirname(args.script)));
193
+ args.config || (args.script && findWranglerToml(path.dirname(args.script)));
190
194
  const config = readConfig(configPath, args);
191
195
  const entry = await getEntry(args, config, "publish");
192
196
  await metrics.sendMetricsEvent(
@@ -202,7 +206,7 @@ export async function publishHandler(args: ArgumentsCamelCase<PublishArgs>) {
202
206
  if (args.public) {
203
207
  throw new Error("The --public field has been renamed to --assets");
204
208
  }
205
- if (args["experimental-public"]) {
209
+ if (args.experimentalPublic) {
206
210
  throw new Error(
207
211
  "The --experimental-public field has been renamed to --assets"
208
212
  );
@@ -247,13 +251,13 @@ export async function publishHandler(args: ArgumentsCamelCase<PublishArgs>) {
247
251
  env: args.env,
248
252
  compatibilityDate: args.latest
249
253
  ? new Date().toISOString().substring(0, 10)
250
- : args["compatibility-date"],
251
- compatibilityFlags: args["compatibility-flags"],
254
+ : args.compatibilityDate,
255
+ compatibilityFlags: args.compatibilityFlags,
252
256
  vars: cliVars,
253
257
  defines: cliDefines,
254
258
  triggers: args.triggers,
255
- jsxFactory: args["jsx-factory"],
256
- jsxFragment: args["jsx-fragment"],
259
+ jsxFactory: args.jsxFactory,
260
+ jsxFragment: args.jsxFragment,
257
261
  tsconfig: args.tsconfig,
258
262
  routes: args.routes,
259
263
  assetPaths,