wrangler 0.0.0-e7a0cd5b → 0.0.0-e87ad068

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 (255) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +254 -128
  4. package/package.json +27 -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 +797 -98
  9. package/src/__tests__/constellation.test.ts +371 -0
  10. package/src/__tests__/d1/d1.test.ts +82 -0
  11. package/src/__tests__/d1/execute.test.ts +66 -0
  12. package/src/__tests__/d1/migrate.test.ts +257 -0
  13. package/src/__tests__/d1/splitter.test.ts +255 -0
  14. package/src/__tests__/delete.test.ts +91 -49
  15. package/src/__tests__/deployments.test.ts +330 -56
  16. package/src/__tests__/dev.test.tsx +198 -90
  17. package/src/__tests__/generate.test.ts +12 -10
  18. package/src/__tests__/guess-worker-format.test.ts +35 -0
  19. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  20. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  21. package/src/__tests__/helpers/mock-console.ts +6 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  23. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  24. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  25. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  26. package/src/__tests__/helpers/mock-kv.ts +29 -16
  27. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  28. package/src/__tests__/helpers/mock-process.ts +8 -13
  29. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  30. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  31. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  33. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  34. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  35. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  36. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  37. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  38. package/src/__tests__/helpers/msw/index.ts +32 -1
  39. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  40. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  41. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  42. package/src/__tests__/index.test.ts +92 -72
  43. package/src/__tests__/init.test.ts +1033 -631
  44. package/src/__tests__/jest.setup.ts +19 -42
  45. package/src/__tests__/kv.test.ts +355 -231
  46. package/src/__tests__/logger.test.ts +68 -2
  47. package/src/__tests__/logout.test.ts +47 -0
  48. package/src/__tests__/metrics.test.ts +94 -51
  49. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  50. package/src/__tests__/middleware.test.ts +212 -122
  51. package/src/__tests__/mtls-certificates.test.ts +589 -0
  52. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  53. package/src/__tests__/pages/functions-build.test.ts +529 -0
  54. package/src/__tests__/pages/pages.test.ts +81 -0
  55. package/src/__tests__/pages/project-create.test.ts +63 -0
  56. package/src/__tests__/pages/project-list.test.ts +110 -0
  57. package/src/__tests__/pages/project-upload.test.ts +500 -0
  58. package/src/__tests__/pages/publish.test.ts +2864 -0
  59. package/src/__tests__/pages-deployment-tail.test.ts +957 -0
  60. package/src/__tests__/parse.test.ts +106 -0
  61. package/src/__tests__/publish.test.ts +2227 -1005
  62. package/src/__tests__/pubsub.test.ts +226 -100
  63. package/src/__tests__/queues.test.ts +238 -77
  64. package/src/__tests__/r2.test.ts +55 -57
  65. package/src/__tests__/secret.test.ts +179 -130
  66. package/src/__tests__/tail.test.ts +313 -113
  67. package/src/__tests__/test-old-node-version.js +3 -3
  68. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  69. package/src/__tests__/tsconfig-sanity.ts +12 -0
  70. package/src/__tests__/tsconfig.json +8 -0
  71. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  72. package/src/__tests__/type-generation.test.ts +43 -26
  73. package/src/__tests__/unstableDev.test.ts +61 -0
  74. package/src/__tests__/user.test.ts +35 -72
  75. package/src/__tests__/whoami.test.tsx +8 -114
  76. package/src/__tests__/worker-namespace.test.ts +83 -69
  77. package/src/api/dev.ts +180 -60
  78. package/src/api/index.ts +10 -1
  79. package/src/api/mtls-certificate.ts +148 -0
  80. package/src/api/pages/create-worker-bundle-contents.ts +80 -0
  81. package/src/api/pages/index.ts +5 -0
  82. package/src/api/pages/publish.tsx +371 -0
  83. package/src/bundle.ts +315 -148
  84. package/src/cfetch/index.ts +0 -2
  85. package/src/cfetch/internal.ts +33 -33
  86. package/src/cli.ts +4 -4
  87. package/src/config/config.ts +14 -7
  88. package/src/config/environment.ts +120 -24
  89. package/src/config/index.ts +117 -35
  90. package/src/config/validation-helpers.ts +1 -1
  91. package/src/config/validation.ts +430 -19
  92. package/src/constellation/createProject.tsx +51 -0
  93. package/src/constellation/deleteProject.ts +51 -0
  94. package/src/constellation/deleteProjectModel.ts +76 -0
  95. package/src/constellation/index.ts +75 -0
  96. package/src/constellation/listCatalog.tsx +35 -0
  97. package/src/constellation/listModel.tsx +49 -0
  98. package/src/constellation/listProject.tsx +28 -0
  99. package/src/constellation/listRuntime.tsx +28 -0
  100. package/src/constellation/options.ts +17 -0
  101. package/src/constellation/types.ts +17 -0
  102. package/src/constellation/uploadModel.tsx +84 -0
  103. package/src/constellation/utils.ts +90 -0
  104. package/src/create-worker-preview.ts +19 -8
  105. package/src/create-worker-upload-form.ts +81 -18
  106. package/src/d1/backups.tsx +47 -46
  107. package/src/d1/constants.ts +5 -0
  108. package/src/d1/create.tsx +85 -37
  109. package/src/d1/{delete.tsx → delete.ts} +12 -15
  110. package/src/d1/execute.tsx +228 -156
  111. package/src/d1/index.ts +31 -7
  112. package/src/d1/list.tsx +27 -13
  113. package/src/d1/migrations/apply.tsx +235 -0
  114. package/src/d1/migrations/create.tsx +79 -0
  115. package/src/d1/migrations/helpers.ts +171 -0
  116. package/src/d1/migrations/index.ts +3 -0
  117. package/src/d1/migrations/list.tsx +95 -0
  118. package/src/d1/migrations/options.ts +23 -0
  119. package/src/d1/options.ts +12 -2
  120. package/src/d1/splitter.ts +161 -0
  121. package/src/d1/types.ts +32 -0
  122. package/src/d1/utils.ts +12 -2
  123. package/src/delete.ts +8 -16
  124. package/src/deployments.ts +340 -46
  125. package/src/deprecated/index.ts +8 -302
  126. package/src/dev/dev.tsx +66 -46
  127. package/src/dev/local.tsx +339 -104
  128. package/src/dev/remote.tsx +36 -3
  129. package/src/dev/start-server.ts +146 -101
  130. package/src/dev/use-esbuild.ts +82 -56
  131. package/src/dev/validate-dev-props.ts +9 -0
  132. package/src/{dev-registry.tsx → dev-registry.ts} +13 -1
  133. package/src/dev.tsx +202 -125
  134. package/src/dialogs.ts +136 -0
  135. package/src/dispatch-namespace.ts +21 -17
  136. package/src/docs/helpers.ts +50 -0
  137. package/src/docs/index.ts +54 -0
  138. package/src/entry.ts +26 -11
  139. package/src/environment-variables/factory.ts +89 -0
  140. package/src/environment-variables/misc-variables.ts +30 -0
  141. package/src/generate/index.ts +303 -0
  142. package/src/git-client.ts +15 -4
  143. package/src/{index.tsx → index.ts} +148 -63
  144. package/src/init.ts +301 -197
  145. package/src/inspect.ts +122 -6
  146. package/src/jest.d.ts +4 -0
  147. package/src/kv/helpers.ts +7 -4
  148. package/src/kv/index.ts +15 -17
  149. package/src/logger.ts +36 -5
  150. package/src/metrics/metrics-config.ts +3 -3
  151. package/src/metrics/send-event.ts +6 -1
  152. package/src/miniflare-cli/assets.ts +64 -28
  153. package/src/miniflare-cli/index.ts +6 -9
  154. package/src/miniflare-cli/tsconfig.json +9 -0
  155. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  156. package/src/miniflare-cli/types.ts +11 -0
  157. package/src/module-collection.ts +92 -26
  158. package/src/mtls-certificate/cli.ts +155 -0
  159. package/src/pages/build.ts +423 -0
  160. package/src/pages/buildFunctions.ts +140 -0
  161. package/src/pages/deployment-tails.ts +281 -0
  162. package/src/pages/deployments.tsx +11 -33
  163. package/src/pages/{dev.tsx → dev.ts} +192 -126
  164. package/src/pages/errors.ts +1 -0
  165. package/src/pages/functions/buildPlugin.ts +73 -69
  166. package/src/pages/functions/buildWorker.ts +342 -117
  167. package/src/pages/functions/tsconfig.json +8 -0
  168. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  169. package/src/pages/{functions.tsx → functions.ts} +8 -4
  170. package/src/pages/{index.tsx → index.ts} +11 -3
  171. package/src/pages/projects.tsx +12 -22
  172. package/src/pages/prompt-select-project.tsx +31 -0
  173. package/src/pages/publish.tsx +45 -214
  174. package/src/pages/types.ts +6 -9
  175. package/src/pages/upload.tsx +58 -14
  176. package/src/pages/utils.ts +14 -3
  177. package/src/parse.ts +23 -1
  178. package/src/paths.ts +1 -1
  179. package/src/proxy.ts +5 -0
  180. package/src/publish/index.ts +20 -16
  181. package/src/publish/publish.ts +81 -48
  182. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  183. package/src/queues/cli/commands/consumer/add.ts +24 -24
  184. package/src/queues/cli/commands/consumer/index.ts +3 -6
  185. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  186. package/src/queues/cli/commands/create.ts +8 -8
  187. package/src/queues/cli/commands/delete.ts +8 -8
  188. package/src/queues/cli/commands/index.ts +6 -4
  189. package/src/queues/cli/commands/list.ts +8 -8
  190. package/src/queues/client.ts +1 -0
  191. package/src/queues/utils.ts +18 -0
  192. package/src/r2/constants.ts +4 -0
  193. package/src/r2/helpers.ts +1 -0
  194. package/src/r2/index.ts +40 -28
  195. package/src/secret/index.ts +18 -17
  196. package/src/{sites.tsx → sites.ts} +165 -53
  197. package/src/tail/createTail.ts +103 -3
  198. package/src/tail/filters.ts +1 -1
  199. package/src/tail/index.ts +8 -11
  200. package/src/tail/printing.ts +27 -0
  201. package/src/traverse-module-graph.ts +54 -0
  202. package/src/tsconfig-sanity.ts +16 -0
  203. package/src/type-generation.ts +85 -57
  204. package/src/user/access.ts +0 -1
  205. package/src/user/auth-variables.ts +113 -0
  206. package/src/user/choose-account.tsx +1 -31
  207. package/src/user/index.ts +0 -1
  208. package/src/user/{user.tsx → user.ts} +124 -82
  209. package/src/utils/render.ts +93 -0
  210. package/src/{whoami.tsx → whoami.ts} +37 -71
  211. package/src/worker.ts +61 -3
  212. package/src/yargs-types.ts +22 -5
  213. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  214. package/templates/__tests__/tsconfig.json +8 -0
  215. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  216. package/templates/checked-fetch.js +9 -3
  217. package/templates/d1-beta-facade.js +95 -25
  218. package/templates/facade.d.ts +14 -0
  219. package/templates/first-party-worker-module-facade.ts +4 -3
  220. package/templates/format-dev-errors.ts +8 -6
  221. package/templates/gitignore +1 -0
  222. package/templates/init-tests/test-jest-new-worker.js +3 -5
  223. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  224. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  225. package/templates/middleware/loader-modules.ts +2 -2
  226. package/templates/middleware/loader-sw.ts +51 -31
  227. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  228. package/templates/new-worker.ts +3 -0
  229. package/templates/pages-dev-pipeline.ts +4 -1
  230. package/templates/pages-dev-util.ts +4 -1
  231. package/templates/pages-shim.ts +4 -1
  232. package/templates/pages-template-plugin.ts +19 -10
  233. package/templates/serve-static-assets.ts +17 -14
  234. package/templates/service-bindings-module-facade.js +1 -0
  235. package/templates/tsconfig-sanity.ts +11 -0
  236. package/templates/tsconfig.init.json +105 -0
  237. package/templates/tsconfig.json +5 -103
  238. package/templates/tsconfig.tsbuildinfo +1 -0
  239. package/wrangler-dist/cli.d.ts +902 -77
  240. package/wrangler-dist/cli.js +131685 -140615
  241. package/wrangler-dist/wasm-sync.wasm +0 -0
  242. package/src/__tests__/api-devregistry.test.js +0 -57
  243. package/src/__tests__/d1.test.ts +0 -72
  244. package/src/__tests__/dialogs.test.tsx +0 -40
  245. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  246. package/src/__tests__/pages.test.ts +0 -2223
  247. package/src/d1/types.tsx +0 -14
  248. package/src/dialogs.tsx +0 -163
  249. package/src/environment-variables.ts +0 -50
  250. package/src/pages/build.tsx +0 -238
  251. package/src/user/env-vars.ts +0 -46
  252. package/templates/experimental-local-cache-stubs.js +0 -27
  253. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  254. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  255. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,5 +1,4 @@
1
1
  import { execSync } from "node:child_process";
2
- import { render } from "ink";
3
2
  import Table from "ink-table";
4
3
  import React from "react";
5
4
  import { format as timeagoFormat } from "timeago.js";
@@ -10,15 +9,16 @@ import { FatalError } from "../errors";
10
9
  import { logger } from "../logger";
11
10
  import * as metrics from "../metrics";
12
11
  import { requireAuth } from "../user";
12
+ import { renderToString } from "../utils/render";
13
13
  import { PAGES_CONFIG_CACHE_FILENAME } from "./constants";
14
14
  import { pagesBetaWarning } from "./utils";
15
+ import type {
16
+ CommonYargsArgv,
17
+ StrictYargsOptionsToInterface,
18
+ } from "../yargs-types";
15
19
  import type { PagesConfigCache, Project } from "./types";
16
- import type { ArgumentsCamelCase, Argv } from "yargs";
17
20
 
18
- // Empty object, as per eslint
19
- type ListArgs = Record<string, never>;
20
-
21
- export function ListOptions(yargs: Argv): Argv<ListArgs> {
21
+ export function ListOptions(yargs: CommonYargsArgv) {
22
22
  return yargs.epilogue(pagesBetaWarning);
23
23
  }
24
24
 
@@ -44,10 +44,7 @@ export async function ListHandler() {
44
44
  account_id: accountId,
45
45
  });
46
46
 
47
- const { unmount } = render(<Table data={data}></Table>, {
48
- patchConsole: false,
49
- });
50
- unmount();
47
+ logger.log(renderToString(<Table data={data}></Table>));
51
48
  await metrics.sendMetricsEvent("list pages projects");
52
49
  }
53
50
 
@@ -77,12 +74,7 @@ export const listProjects = async ({
77
74
  return results;
78
75
  };
79
76
 
80
- type CreateArgs = {
81
- "project-name": string;
82
- "production-branch"?: string;
83
- };
84
-
85
- export function CreateOptions(yargs: Argv): Argv<CreateArgs> {
77
+ export function CreateOptions(yargs: CommonYargsArgv) {
86
78
  return yargs
87
79
  .positional("project-name", {
88
80
  type: "string",
@@ -101,7 +93,7 @@ export function CreateOptions(yargs: Argv): Argv<CreateArgs> {
101
93
  export async function CreateHandler({
102
94
  productionBranch,
103
95
  projectName,
104
- }: ArgumentsCamelCase<CreateArgs>) {
96
+ }: StrictYargsOptionsToInterface<typeof CreateOptions>) {
105
97
  const config = getConfigCache<PagesConfigCache>(PAGES_CONFIG_CACHE_FILENAME);
106
98
  const accountId = await requireAuth(config);
107
99
 
@@ -132,11 +124,9 @@ export async function CreateHandler({
132
124
  } catch (err) {}
133
125
  }
134
126
 
135
- productionBranch = await prompt(
136
- "Enter the production branch name:",
137
- "text",
138
- productionBranch ?? "production"
139
- );
127
+ productionBranch = await prompt("Enter the production branch name:", {
128
+ defaultValue: productionBranch ?? "production",
129
+ });
140
130
  }
141
131
 
142
132
  if (!productionBranch) {
@@ -0,0 +1,31 @@
1
+ import { render, Text } from "ink";
2
+ import SelectInput from "ink-select-input";
3
+ import React from "react";
4
+ import { listProjects } from "./projects";
5
+
6
+ export async function promptSelectProject({
7
+ accountId,
8
+ }: {
9
+ accountId: string;
10
+ }): Promise<string> {
11
+ const projects = await listProjects({ accountId });
12
+
13
+ return new Promise((resolve) => {
14
+ const { unmount } = render(
15
+ <>
16
+ <Text>Select a project:</Text>
17
+ <SelectInput
18
+ items={projects.map((project) => ({
19
+ key: project.name,
20
+ label: project.name,
21
+ value: project,
22
+ }))}
23
+ onSelect={async (selected) => {
24
+ resolve(selected.value.name);
25
+ unmount();
26
+ }}
27
+ />
28
+ </>
29
+ );
30
+ });
31
+ }
@@ -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,24 +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
17
  import type {
25
- Deployment,
26
- PagesConfigCache,
27
- Project,
28
- YargsOptionsToInterface,
29
- } from "./types";
30
- import type { Argv } from "yargs";
18
+ CommonYargsArgv,
19
+ StrictYargsOptionsToInterface,
20
+ } from "../yargs-types";
21
+ import type { PagesConfigCache } from "./types";
22
+ import type { Project } from "@cloudflare/types";
31
23
 
32
- type PublishArgs = YargsOptionsToInterface<typeof Options>;
24
+ type PublishArgs = StrictYargsOptionsToInterface<typeof Options>;
33
25
 
34
- export function Options(yargs: Argv) {
26
+ export function Options(yargs: CommonYargsArgv) {
35
27
  return yargs
36
28
  .positional("directory", {
37
29
  type: "string",
@@ -60,6 +52,20 @@ export function Options(yargs: Argv) {
60
52
  description:
61
53
  "Whether or not the workspace should be considered dirty for this deployment",
62
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
+ },
63
69
  config: {
64
70
  describe: "Pages does not support wrangler.toml",
65
71
  type: "string",
@@ -76,6 +82,9 @@ export const Handler = async ({
76
82
  commitHash,
77
83
  commitMessage,
78
84
  commitDirty,
85
+ skipCaching,
86
+ bundle,
87
+ noBundle,
79
88
  config: wranglerConfig,
80
89
  }: PublishArgs) => {
81
90
  if (wranglerConfig) {
@@ -132,24 +141,7 @@ export const Handler = async ({
132
141
 
133
142
  switch (existingOrNew) {
134
143
  case "existing": {
135
- projectName = await new Promise((resolve) => {
136
- const { unmount } = render(
137
- <>
138
- <Text>Select a project:</Text>
139
- <SelectInput
140
- items={projects.map((project) => ({
141
- key: project.name,
142
- label: project.name,
143
- value: project,
144
- }))}
145
- onSelect={async (selected) => {
146
- resolve(selected.value.name);
147
- unmount();
148
- }}
149
- />
150
- </>
151
- );
152
- });
144
+ projectName = await promptSelectProject({ accountId });
153
145
  break;
154
146
  }
155
147
  case "new": {
@@ -170,10 +162,11 @@ export const Handler = async ({
170
162
 
171
163
  const productionBranch = await prompt(
172
164
  "Enter the production branch name:",
173
- "text",
174
- isGitDir
175
- ? execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim()
176
- : "production"
165
+ {
166
+ defaultValue: isGitDir
167
+ ? execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim()
168
+ : "production",
169
+ }
177
170
  );
178
171
 
179
172
  if (!productionBranch) {
@@ -248,181 +241,19 @@ export const Handler = async ({
248
241
  }
249
242
  }
250
243
 
251
- let _headers: string | undefined,
252
- _redirects: string | undefined,
253
- _routesGenerated: string | undefined,
254
- _routesCustom: string | undefined,
255
- _workerJS: string | undefined;
256
-
257
- try {
258
- _headers = readFileSync(join(directory, "_headers"), "utf-8");
259
- } catch {}
260
-
261
- try {
262
- _redirects = readFileSync(join(directory, "_redirects"), "utf-8");
263
- } catch {}
264
-
265
- try {
266
- /**
267
- * Developers can specify a custom _routes.json file, for projects with Pages
268
- * Functions or projects in Advanced Mode
269
- */
270
- _routesCustom = readFileSync(join(directory, "_routes.json"), "utf-8");
271
- } catch {}
272
-
273
- try {
274
- _workerJS = readFileSync(join(directory, "_worker.js"), "utf-8");
275
- } catch {}
276
-
277
- /**
278
- * Evaluate if this is an Advanced Mode or Pages Functions project. If Advanced Mode, we'll
279
- * go ahead and upload `_worker.js` as is, but if Pages Functions, we need to attempt to build
280
- * Functions first and exit if it failed
281
- */
282
- let builtFunctions: string | undefined = undefined;
283
- const functionsDirectory = join(cwd(), "functions");
284
- const routesOutputPath = !existsSync(join(directory, "_routes.json"))
285
- ? join(tmpdir(), `_routes-${Math.random()}.json`)
286
- : undefined;
287
-
288
- if (!_workerJS && existsSync(functionsDirectory)) {
289
- const outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`);
290
- try {
291
- await buildFunctions({
292
- outfile,
293
- functionsDirectory,
294
- onEnd: () => {},
295
- buildOutputDirectory: dirname(outfile),
296
- routesOutputPath,
297
- });
298
-
299
- builtFunctions = readFileSync(outfile, "utf-8");
300
- } catch (e) {
301
- if (e instanceof FunctionsNoRoutesError) {
302
- logger.warn(
303
- getFunctionsNoRoutesWarning(functionsDirectory, "skipping")
304
- );
305
- } else {
306
- throw e;
307
- }
308
- }
309
- }
310
-
311
- const manifest = await upload({ directory, accountId, projectName });
312
-
313
- const formData = new FormData();
314
-
315
- formData.append("manifest", JSON.stringify(manifest));
316
-
317
- if (branch) {
318
- formData.append("branch", branch);
319
- }
320
-
321
- if (commitMessage) {
322
- formData.append("commit_message", commitMessage);
323
- }
324
-
325
- if (commitHash) {
326
- formData.append("commit_hash", commitHash);
327
- }
328
-
329
- if (commitDirty !== undefined) {
330
- formData.append("commit_dirty", commitDirty);
331
- }
332
-
333
- if (_headers) {
334
- formData.append("_headers", new File([_headers], "_headers"));
335
- logger.log(`✨ Uploading _headers`);
336
- }
337
-
338
- if (_redirects) {
339
- formData.append("_redirects", new File([_redirects], "_redirects"));
340
- logger.log(`✨ Uploading _redirects`);
341
- }
342
-
343
- /**
344
- * Advanced Mode
345
- * https://developers.cloudflare.com/pages/platform/functions/#advanced-mode
346
- *
347
- * When using a _worker.js file, the entire /functions directory is ignored
348
- * – this includes its routing and middleware characteristics.
349
- */
350
- if (_workerJS) {
351
- formData.append("_worker.js", new File([_workerJS], "_worker.js"));
352
- logger.log(`✨ Uploading _worker.js`);
353
-
354
- if (_routesCustom) {
355
- // user provided a custom _routes.json file
356
- try {
357
- const routesCustomJSON = JSON.parse(_routesCustom);
358
- validateRoutes(routesCustomJSON, join(directory, "_routes.json"));
359
-
360
- formData.append(
361
- "_routes.json",
362
- new File([_routesCustom], "_routes.json")
363
- );
364
- logger.log(`✨ Uploading _routes.json`);
365
- logger.warn(
366
- `_routes.json is an experimental feature and is subject to change. Please use with care.`
367
- );
368
- } catch (err) {
369
- if (err instanceof FatalError) {
370
- throw err;
371
- }
372
- }
373
- }
374
- }
375
-
376
- /**
377
- * Pages Functions
378
- * https://developers.cloudflare.com/pages/platform/functions/
379
- */
380
- if (builtFunctions && !_workerJS) {
381
- // if Functions were build successfully, proceed to uploading the build file
382
- formData.append("_worker.js", new File([builtFunctions], "_worker.js"));
383
- logger.log(`✨ Uploading Functions`);
384
-
385
- if (_routesCustom) {
386
- // user provided a custom _routes.json file
387
- try {
388
- const routesCustomJSON = JSON.parse(_routesCustom);
389
- validateRoutes(routesCustomJSON, join(directory, "_routes.json"));
390
-
391
- formData.append(
392
- "_routes.json",
393
- new File([_routesCustom], "_routes.json")
394
- );
395
- logger.log(`✨ Uploading _routes.json`);
396
- logger.warn(
397
- `_routes.json is an experimental feature and is subject to change. Please use with care.`
398
- );
399
- } catch (err) {
400
- if (err instanceof FatalError) {
401
- throw err;
402
- }
403
- }
404
- } else if (routesOutputPath) {
405
- // no custom _routes.json file found, so fallback to the generated one
406
- try {
407
- _routesGenerated = readFileSync(routesOutputPath, "utf-8");
408
-
409
- if (_routesGenerated) {
410
- formData.append(
411
- "_routes.json",
412
- new File([_routesGenerated], "_routes.json")
413
- );
414
- }
415
- } catch {}
416
- }
417
- }
418
-
419
- const deploymentResponse = await fetchResult<Deployment>(
420
- `/accounts/${accountId}/pages/projects/${projectName}/deployments`,
421
- {
422
- method: "POST",
423
- body: formData,
424
- }
425
- );
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
+ });
426
257
 
427
258
  saveToConfigCache<PagesConfigCache>(PAGES_CONFIG_CACHE_FILENAME, {
428
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
  <>
@@ -1,6 +1,6 @@
1
- import type { BuildResult } from "esbuild";
1
+ import type { BundleResult } from "../bundle";
2
2
 
3
- export const RUNNING_BUILDERS: BuildResult[] = [];
3
+ export const RUNNING_BUILDERS: BundleResult[] = [];
4
4
 
5
5
  export const CLEANUP_CALLBACKS: (() => void)[] = [];
6
6
  export const CLEANUP = () => {
@@ -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