wrangler 0.0.0-e322475 → 0.0.0-e33294b0

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 (324) hide show
  1. package/README.md +24 -4
  2. package/bin/wrangler.js +170 -62
  3. package/miniflare-dist/index.mjs +1499 -34
  4. package/package.json +193 -156
  5. package/src/__tests__/access.test.ts +25 -0
  6. package/src/__tests__/api-dev.test.ts +238 -0
  7. package/src/__tests__/api-devregistry.test.js +64 -0
  8. package/src/__tests__/api.test.ts +80 -0
  9. package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
  10. package/src/__tests__/config-cache.test.ts +30 -24
  11. package/src/__tests__/configuration.test.ts +4222 -3537
  12. package/src/__tests__/d1/d1.test.ts +82 -0
  13. package/src/__tests__/d1/execute.test.ts +64 -0
  14. package/src/__tests__/d1/migrate.test.ts +155 -0
  15. package/src/__tests__/d1/splitter.test.ts +255 -0
  16. package/src/__tests__/delete.test.ts +266 -0
  17. package/src/__tests__/deployments.test.ts +129 -0
  18. package/src/__tests__/dev.test.tsx +1560 -1028
  19. package/src/__tests__/generate.test.ts +238 -0
  20. package/src/__tests__/get-host-from-url.test.ts +16 -0
  21. package/src/__tests__/guess-worker-format.test.ts +68 -68
  22. package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
  23. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  24. package/src/__tests__/helpers/mock-account-id.ts +24 -24
  25. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  26. package/src/__tests__/helpers/mock-bin.ts +20 -20
  27. package/src/__tests__/helpers/mock-console.ts +51 -42
  28. package/src/__tests__/helpers/mock-dialogs.ts +88 -102
  29. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  30. package/src/__tests__/helpers/mock-get-zone-from-host.ts +11 -0
  31. package/src/__tests__/helpers/mock-http-server.ts +30 -30
  32. package/src/__tests__/helpers/mock-istty.ts +65 -18
  33. package/src/__tests__/helpers/mock-known-routes.ts +12 -0
  34. package/src/__tests__/helpers/mock-kv.ts +41 -28
  35. package/src/__tests__/helpers/mock-oauth-flow.ts +241 -233
  36. package/src/__tests__/helpers/mock-process.ts +23 -13
  37. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  38. package/src/__tests__/helpers/mock-stdin.ts +82 -77
  39. package/src/__tests__/helpers/mock-web-socket.ts +21 -21
  40. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  41. package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
  42. package/src/__tests__/helpers/msw/handlers/deployments.ts +93 -0
  43. package/src/__tests__/helpers/msw/handlers/namespaces.ts +81 -0
  44. package/src/__tests__/helpers/msw/handlers/oauth.ts +31 -0
  45. package/src/__tests__/helpers/msw/handlers/r2.ts +60 -0
  46. package/src/__tests__/helpers/msw/handlers/script.ts +56 -0
  47. package/src/__tests__/helpers/msw/handlers/user.ts +52 -0
  48. package/src/__tests__/helpers/msw/handlers/zones.ts +20 -0
  49. package/src/__tests__/helpers/msw/index.ts +50 -0
  50. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  51. package/src/__tests__/helpers/run-in-tmp.ts +27 -28
  52. package/src/__tests__/helpers/run-wrangler.ts +8 -8
  53. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  54. package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
  55. package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
  56. package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
  57. package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
  58. package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
  59. package/src/__tests__/helpers/write-worker-source.ts +16 -16
  60. package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
  61. package/src/__tests__/https-options.test.ts +142 -109
  62. package/src/__tests__/index.test.ts +254 -238
  63. package/src/__tests__/init.test.ts +3097 -1925
  64. package/src/__tests__/jest.setup.ts +143 -75
  65. package/src/__tests__/kv.test.ts +1788 -1509
  66. package/src/__tests__/logger.test.ts +96 -96
  67. package/src/__tests__/logout.test.ts +47 -0
  68. package/src/__tests__/metrics.test.ts +493 -0
  69. package/src/__tests__/middleware.scheduled.test.ts +145 -0
  70. package/src/__tests__/middleware.test.ts +815 -0
  71. package/src/__tests__/mtls-certificates.test.ts +585 -0
  72. package/src/__tests__/package-manager.test.ts +303 -303
  73. package/src/__tests__/pages/deployment-list.test.ts +78 -0
  74. package/src/__tests__/pages/functions-build.test.ts +402 -0
  75. package/src/__tests__/pages/pages.test.ts +81 -0
  76. package/src/__tests__/pages/project-create.test.ts +63 -0
  77. package/src/__tests__/pages/project-list.test.ts +108 -0
  78. package/src/__tests__/pages/project-upload.test.ts +481 -0
  79. package/src/__tests__/pages/publish.test.ts +2745 -0
  80. package/src/__tests__/pages-deployment-tail.test.ts +955 -0
  81. package/src/__tests__/parse.test.ts +358 -252
  82. package/src/__tests__/paths.test.ts +39 -0
  83. package/src/__tests__/publish.test.ts +8002 -6010
  84. package/src/__tests__/pubsub.test.ts +493 -0
  85. package/src/__tests__/queues.test.ts +529 -0
  86. package/src/__tests__/r2.test.ts +369 -228
  87. package/src/__tests__/route.test.ts +18 -18
  88. package/src/__tests__/secret.test.ts +681 -469
  89. package/src/__tests__/tail.test.ts +835 -567
  90. package/src/__tests__/test-old-node-version.js +31 -0
  91. package/src/__tests__/tsconfig-sanity.ts +12 -0
  92. package/src/__tests__/tsconfig.json +8 -0
  93. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  94. package/src/__tests__/type-generation.test.ts +233 -0
  95. package/src/__tests__/user.test.ts +107 -121
  96. package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
  97. package/src/__tests__/validate-dev-props.test.ts +56 -0
  98. package/src/__tests__/version.test.ts +35 -0
  99. package/src/__tests__/whoami.test.tsx +165 -132
  100. package/src/__tests__/worker-namespace.test.ts +339 -0
  101. package/src/abort.d.ts +1 -1
  102. package/src/api/dev.ts +328 -0
  103. package/src/api/index.ts +11 -0
  104. package/src/api/mtls-certificate.ts +148 -0
  105. package/src/api/pages/create-worker-bundle-contents.ts +75 -0
  106. package/src/api/pages/index.ts +5 -0
  107. package/src/api/pages/publish.tsx +368 -0
  108. package/src/bundle-reporter.ts +68 -0
  109. package/src/bundle.ts +839 -167
  110. package/src/cfetch/index.ts +120 -83
  111. package/src/cfetch/internal.ts +208 -92
  112. package/src/cli.ts +23 -8
  113. package/src/config/config.ts +244 -205
  114. package/src/config/diagnostics.ts +61 -61
  115. package/src/config/environment.ts +523 -357
  116. package/src/config/index.ts +346 -196
  117. package/src/config/validation-helpers.ts +379 -366
  118. package/src/config/validation.ts +2020 -1402
  119. package/src/config-cache.ts +81 -41
  120. package/src/create-worker-preview.ts +239 -142
  121. package/src/create-worker-upload-form.ts +318 -238
  122. package/src/d1/backups.tsx +215 -0
  123. package/src/d1/constants.ts +2 -0
  124. package/src/d1/create.tsx +64 -0
  125. package/src/d1/delete.ts +53 -0
  126. package/src/d1/execute.tsx +354 -0
  127. package/src/d1/formatTimeAgo.ts +14 -0
  128. package/src/d1/index.ts +100 -0
  129. package/src/d1/list.tsx +60 -0
  130. package/src/d1/migrations/apply.tsx +206 -0
  131. package/src/d1/migrations/create.tsx +76 -0
  132. package/src/d1/migrations/helpers.ts +172 -0
  133. package/src/d1/migrations/index.ts +3 -0
  134. package/src/d1/migrations/list.tsx +92 -0
  135. package/src/d1/migrations/options.ts +23 -0
  136. package/src/d1/options.ts +22 -0
  137. package/src/d1/splitter.ts +161 -0
  138. package/src/d1/types.ts +25 -0
  139. package/src/d1/utils.ts +49 -0
  140. package/src/delete.ts +100 -0
  141. package/src/deployments.ts +116 -0
  142. package/src/deprecated/index.ts +144 -0
  143. package/src/dev/dev-vars.ts +20 -17
  144. package/src/dev/dev.tsx +530 -329
  145. package/src/dev/get-local-persistence-path.ts +31 -0
  146. package/src/dev/local.tsx +903 -301
  147. package/src/dev/remote.tsx +619 -236
  148. package/src/dev/start-server.ts +538 -0
  149. package/src/dev/use-esbuild.ts +184 -91
  150. package/src/dev/validate-dev-props.ts +31 -0
  151. package/src/dev-registry.ts +201 -0
  152. package/src/dev.tsx +914 -0
  153. package/src/dialogs.ts +136 -0
  154. package/src/dispatch-namespace.ts +211 -0
  155. package/src/docs/index.ts +97 -0
  156. package/src/durable.ts +87 -87
  157. package/src/entry.ts +236 -236
  158. package/src/environment-variables/factory.ts +88 -0
  159. package/src/environment-variables/misc-variables.ts +30 -0
  160. package/src/errors.ts +6 -6
  161. package/src/generate/index.ts +298 -0
  162. package/src/git-client.ts +112 -19
  163. package/src/global-wrangler-config-path.ts +26 -0
  164. package/src/https-options.ts +84 -80
  165. package/src/index.ts +705 -0
  166. package/src/init.ts +1022 -0
  167. package/src/inspect.ts +698 -593
  168. package/src/intl-polyfill.d.ts +123 -123
  169. package/src/is-ci.ts +14 -0
  170. package/src/is-interactive.ts +16 -0
  171. package/src/jest.d.ts +4 -0
  172. package/src/kv/helpers.ts +430 -0
  173. package/src/kv/index.ts +594 -0
  174. package/src/logger.ts +77 -46
  175. package/src/metrics/index.ts +5 -0
  176. package/src/metrics/metrics-config.ts +239 -0
  177. package/src/metrics/metrics-dispatcher.ts +96 -0
  178. package/src/metrics/metrics-usage-headers.ts +24 -0
  179. package/src/metrics/send-event.ts +98 -0
  180. package/src/miniflare-cli/assets.ts +250 -0
  181. package/src/miniflare-cli/index.ts +202 -33
  182. package/src/miniflare-cli/request-context.ts +18 -18
  183. package/src/miniflare-cli/tsconfig.json +9 -0
  184. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  185. package/src/miniflare-cli/types.ts +11 -0
  186. package/src/module-collection.ts +221 -212
  187. package/src/mtls-certificate/cli.ts +155 -0
  188. package/src/open-in-browser.ts +4 -4
  189. package/src/package-manager.ts +173 -128
  190. package/src/pages/build.ts +232 -0
  191. package/src/pages/buildFunctions.ts +130 -0
  192. package/src/pages/constants.ts +18 -0
  193. package/src/pages/deployment-tails.ts +281 -0
  194. package/src/pages/deployments.tsx +86 -0
  195. package/src/pages/dev.ts +716 -0
  196. package/src/pages/errors.ts +66 -0
  197. package/src/pages/functions/buildPlugin.ts +90 -0
  198. package/src/pages/functions/buildWorker.ts +288 -0
  199. package/{pages → src/pages}/functions/filepath-routing.test.ts +113 -113
  200. package/src/pages/functions/filepath-routing.ts +189 -0
  201. package/src/pages/functions/identifiers.ts +78 -0
  202. package/src/pages/functions/routes-consolidation.test.ts +250 -0
  203. package/src/pages/functions/routes-consolidation.ts +73 -0
  204. package/src/pages/functions/routes-transformation.test.ts +282 -0
  205. package/src/pages/functions/routes-transformation.ts +115 -0
  206. package/src/pages/functions/routes-validation.test.ts +403 -0
  207. package/src/pages/functions/routes-validation.ts +202 -0
  208. package/src/pages/functions/routes.ts +151 -0
  209. package/src/pages/functions/tsconfig.json +8 -0
  210. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  211. package/src/pages/functions.ts +86 -0
  212. package/src/pages/hash.ts +13 -0
  213. package/src/pages/index.ts +102 -0
  214. package/src/pages/projects.tsx +162 -0
  215. package/src/pages/prompt-select-project.tsx +31 -0
  216. package/src/pages/publish.tsx +276 -0
  217. package/src/pages/types.ts +46 -0
  218. package/src/pages/upload.tsx +449 -0
  219. package/src/pages/utils.ts +23 -0
  220. package/src/parse.ts +225 -139
  221. package/src/paths.ts +53 -8
  222. package/src/proxy.ts +623 -405
  223. package/src/publish/index.ts +274 -0
  224. package/src/publish/publish.ts +1065 -0
  225. package/src/pubsub/index.ts +286 -0
  226. package/src/pubsub/pubsub-commands.ts +623 -0
  227. package/src/queues/cli/commands/consumer/add.ts +65 -0
  228. package/src/queues/cli/commands/consumer/index.ts +19 -0
  229. package/src/queues/cli/commands/consumer/remove.ts +31 -0
  230. package/src/queues/cli/commands/create.ts +25 -0
  231. package/src/queues/cli/commands/delete.ts +26 -0
  232. package/src/queues/cli/commands/index.ts +35 -0
  233. package/src/queues/cli/commands/list.ts +25 -0
  234. package/src/queues/client.ts +135 -0
  235. package/src/queues/utils.ts +18 -0
  236. package/src/r2/constants.ts +4 -0
  237. package/src/r2/helpers.ts +131 -0
  238. package/src/r2/index.ts +289 -0
  239. package/src/routes.ts +140 -0
  240. package/src/secret/index.ts +375 -0
  241. package/src/selfsigned.d.ts +23 -23
  242. package/src/sites.ts +372 -0
  243. package/src/tail/createTail.ts +406 -0
  244. package/src/tail/filters.ts +109 -111
  245. package/src/tail/index.ts +208 -296
  246. package/src/tail/printing.ts +101 -46
  247. package/src/tsconfig-sanity.ts +16 -0
  248. package/src/type-generation.ts +181 -0
  249. package/src/update-check.ts +11 -11
  250. package/src/user/access.ts +68 -0
  251. package/src/user/auth-variables.ts +113 -0
  252. package/src/user/choose-account.tsx +39 -0
  253. package/src/user/generate-auth-url.ts +33 -0
  254. package/src/user/generate-random-state.ts +16 -0
  255. package/src/user/index.ts +2 -0
  256. package/src/user/user.ts +1233 -0
  257. package/src/utils/collectKeyValues.ts +14 -0
  258. package/src/whoami.ts +135 -0
  259. package/src/worker.ts +183 -107
  260. package/src/yargs-types.ts +37 -0
  261. package/src/zones.ts +158 -40
  262. package/templates/__tests__/pages-dev-util.test.ts +128 -0
  263. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  264. package/templates/__tests__/tsconfig.json +8 -0
  265. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  266. package/templates/checked-fetch.js +23 -0
  267. package/templates/d1-beta-facade.js +241 -0
  268. package/templates/facade.d.ts +14 -0
  269. package/templates/first-party-worker-module-facade.ts +19 -0
  270. package/templates/format-dev-errors.ts +34 -0
  271. package/templates/init-tests/test-jest-new-worker.js +23 -0
  272. package/templates/init-tests/test-vitest-new-worker.js +24 -0
  273. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  274. package/templates/middleware/common.ts +62 -0
  275. package/templates/middleware/loader-modules.ts +84 -0
  276. package/templates/middleware/loader-sw.ts +233 -0
  277. package/templates/middleware/middleware-miniflare3-json-error.ts +20 -0
  278. package/templates/middleware/middleware-pretty-error.ts +40 -0
  279. package/templates/middleware/middleware-scheduled.ts +15 -0
  280. package/templates/new-worker-scheduled.js +3 -3
  281. package/templates/new-worker-scheduled.ts +15 -15
  282. package/templates/new-worker.js +3 -3
  283. package/templates/new-worker.ts +18 -15
  284. package/templates/no-op-worker.js +8 -8
  285. package/templates/pages-dev-pipeline.ts +31 -0
  286. package/templates/pages-dev-util.ts +52 -0
  287. package/templates/pages-shim.ts +12 -0
  288. package/templates/pages-template-plugin.ts +176 -0
  289. package/templates/pages-template-worker.ts +189 -0
  290. package/templates/serve-static-assets.ts +66 -0
  291. package/templates/service-bindings-module-facade.js +55 -0
  292. package/templates/service-bindings-sw-facade.js +42 -0
  293. package/templates/tsconfig-sanity.ts +11 -0
  294. package/templates/tsconfig.init.json +106 -0
  295. package/templates/tsconfig.json +6 -103
  296. package/templates/tsconfig.tsbuildinfo +1 -0
  297. package/wrangler-dist/cli.d.ts +1108 -0
  298. package/wrangler-dist/cli.js +131192 -112380
  299. package/wrangler-dist/wasm-sync.wasm +0 -0
  300. package/pages/functions/buildPlugin.ts +0 -105
  301. package/pages/functions/buildWorker.ts +0 -151
  302. package/pages/functions/filepath-routing.ts +0 -189
  303. package/pages/functions/identifiers.ts +0 -78
  304. package/pages/functions/routes.ts +0 -156
  305. package/pages/functions/template-plugin.ts +0 -147
  306. package/pages/functions/template-worker.ts +0 -143
  307. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  308. package/src/__tests__/helpers/mock-cfetch.ts +0 -211
  309. package/src/__tests__/pages.test.ts +0 -754
  310. package/src/bundle-reporter.tsx +0 -29
  311. package/src/dialogs.tsx +0 -135
  312. package/src/environment-variables.ts +0 -35
  313. package/src/generate-auth-url.ts +0 -33
  314. package/src/generate-random-state.ts +0 -16
  315. package/src/index.tsx +0 -2896
  316. package/src/kv.ts +0 -408
  317. package/src/miniflare-cli/enum-keys.ts +0 -17
  318. package/src/pages.tsx +0 -2093
  319. package/src/publish.ts +0 -739
  320. package/src/r2.ts +0 -50
  321. package/src/sites.tsx +0 -368
  322. package/src/user.tsx +0 -1202
  323. package/src/whoami.tsx +0 -71
  324. package/templates/static-asset-facade.js +0 -43
@@ -0,0 +1,250 @@
1
+ import { existsSync, lstatSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { createMetadataObject } from "@cloudflare/pages-shared/metadata-generator/createMetadataObject";
4
+ import { parseHeaders } from "@cloudflare/pages-shared/metadata-generator/parseHeaders";
5
+ import { parseRedirects } from "@cloudflare/pages-shared/metadata-generator/parseRedirects";
6
+ import { watch } from "chokidar";
7
+ import { getType } from "mime";
8
+ import { hashFile } from "../pages/hash";
9
+ import type { Metadata } from "@cloudflare/pages-shared/asset-server/metadata";
10
+ import type {
11
+ ParsedRedirects,
12
+ ParsedHeaders,
13
+ } from "@cloudflare/pages-shared/metadata-generator/types";
14
+ import type {
15
+ RequestInfo as TreRequestInfo,
16
+ RequestInit as TreRequestInit,
17
+ } from "@miniflare/tre";
18
+
19
+ interface Logger {
20
+ log: (message: string) => void;
21
+ warn: (message: string) => void;
22
+ error: (error: Error) => void;
23
+ }
24
+
25
+ export interface Options {
26
+ log: Logger;
27
+ proxyPort?: number;
28
+ directory?: string;
29
+ tre: boolean;
30
+ }
31
+
32
+ export default async function generateASSETSBinding(options: Options) {
33
+ const assetsFetch =
34
+ options.directory !== undefined
35
+ ? await generateAssetsFetch(options.directory, options.log, options.tre)
36
+ : invalidAssetsFetch;
37
+
38
+ const miniflare = options.tre
39
+ ? await import("@miniflare/tre")
40
+ : await import("@miniflare/core");
41
+
42
+ const Request = miniflare.Request;
43
+ const Response = miniflare.Response;
44
+ // WebSockets won't work with `--experimental-local` until we expose something like `upgradingFetch` from `@miniflare/tre`.
45
+ const fetch = (
46
+ options.tre
47
+ ? miniflare.fetch
48
+ : (await import("@miniflare/web-sockets")).upgradingFetch
49
+ ) as (request: Request) => Promise<Response>;
50
+
51
+ return async function (miniflareRequest: Request) {
52
+ if (options.proxyPort) {
53
+ try {
54
+ const url = new URL(miniflareRequest.url);
55
+ url.host = `localhost:${options.proxyPort}`;
56
+ const proxyRequest = new Request(url, miniflareRequest);
57
+ if (proxyRequest.headers.get("Upgrade") === "websocket") {
58
+ proxyRequest.headers.delete("Sec-WebSocket-Accept");
59
+ proxyRequest.headers.delete("Sec-WebSocket-Key");
60
+ }
61
+ return await fetch(proxyRequest as Request);
62
+ } catch (thrown) {
63
+ options.log.error(new Error(`Could not proxy request: ${thrown}`));
64
+
65
+ // TODO: Pretty error page
66
+ return new Response(`[wrangler] Could not proxy request: ${thrown}`, {
67
+ status: 502,
68
+ });
69
+ }
70
+ } else {
71
+ try {
72
+ return await assetsFetch(miniflareRequest);
73
+ } catch (thrown) {
74
+ options.log.error(new Error(`Could not serve static asset: ${thrown}`));
75
+
76
+ // TODO: Pretty error page
77
+ return new Response(
78
+ `[wrangler] Could not serve static asset: ${thrown}`,
79
+ { status: 502 }
80
+ );
81
+ }
82
+ }
83
+ };
84
+ }
85
+
86
+ async function generateAssetsFetch(
87
+ directory: string,
88
+ log: Logger,
89
+ tre: boolean
90
+ ): Promise<typeof fetch> {
91
+ // Defer importing miniflare until we really need it
92
+
93
+ // NOTE: These dynamic imports bring in `global` type augmentations from
94
+ // `@cloudflare/pages-shared/environment-polyfills/types.ts`, allowing us to
95
+ // use `fetch`, `Headers`, `Request` and `Response` as globals in this file
96
+ // and the *entire* `miniflare-cli` TypeScript project.
97
+ const polyfill = tre
98
+ ? (
99
+ await import(
100
+ "@cloudflare/pages-shared/environment-polyfills/miniflare-tre"
101
+ )
102
+ ).default
103
+ : (await import("@cloudflare/pages-shared/environment-polyfills/miniflare"))
104
+ .default;
105
+
106
+ await polyfill();
107
+
108
+ const miniflare = tre
109
+ ? await import("@miniflare/tre")
110
+ : await import("@miniflare/core");
111
+ const Request = miniflare.Request;
112
+
113
+ const { generateHandler, parseQualityWeightedList } = await import(
114
+ "@cloudflare/pages-shared/asset-server/handler"
115
+ );
116
+
117
+ const headersFile = join(directory, "_headers");
118
+ const redirectsFile = join(directory, "_redirects");
119
+ const workerFile = join(directory, "_worker.js");
120
+
121
+ const ignoredFiles = [headersFile, redirectsFile, workerFile];
122
+
123
+ let redirects: ParsedRedirects | undefined;
124
+ if (existsSync(redirectsFile)) {
125
+ const contents = readFileSync(redirectsFile, "utf-8");
126
+ redirects = parseRedirects(contents);
127
+ }
128
+
129
+ let headers: ParsedHeaders | undefined;
130
+ if (existsSync(headersFile)) {
131
+ const contents = readFileSync(headersFile, "utf-8");
132
+ headers = parseHeaders(contents);
133
+ }
134
+
135
+ let metadata = createMetadataObject({
136
+ redirects,
137
+ headers,
138
+ logger: log.warn.bind(log),
139
+ });
140
+
141
+ watch([headersFile, redirectsFile], { persistent: true }).on(
142
+ "change",
143
+ (path) => {
144
+ switch (path) {
145
+ case headersFile: {
146
+ log.log("_headers modified. Re-evaluating...");
147
+ const contents = readFileSync(headersFile).toString();
148
+ headers = parseHeaders(contents);
149
+ break;
150
+ }
151
+ case redirectsFile: {
152
+ log.log("_redirects modified. Re-evaluating...");
153
+ const contents = readFileSync(redirectsFile).toString();
154
+ redirects = parseRedirects(contents);
155
+ break;
156
+ }
157
+ }
158
+
159
+ metadata = createMetadataObject({
160
+ redirects,
161
+ headers,
162
+ logger: log.warn,
163
+ });
164
+ }
165
+ );
166
+
167
+ const generateResponse = async (request: Request) => {
168
+ const assetKeyEntryMap = new Map<string, string>();
169
+
170
+ return await generateHandler<string>({
171
+ request,
172
+ metadata: metadata as Metadata,
173
+ xServerEnvHeader: "dev",
174
+ logError: console.error,
175
+ findAssetEntryForPath: async (path) => {
176
+ const filepath = join(directory, path);
177
+
178
+ if (
179
+ existsSync(filepath) &&
180
+ lstatSync(filepath).isFile() &&
181
+ !ignoredFiles.includes(filepath)
182
+ ) {
183
+ const hash = hashFile(filepath);
184
+ assetKeyEntryMap.set(hash, filepath);
185
+ return hash;
186
+ }
187
+
188
+ return null;
189
+ },
190
+ getAssetKey: (assetEntry) => {
191
+ return assetEntry;
192
+ },
193
+ negotiateContent: (contentRequest) => {
194
+ let rawAcceptEncoding: string | undefined;
195
+ if (
196
+ contentRequest.cf &&
197
+ "clientAcceptEncoding" in contentRequest.cf &&
198
+ contentRequest.cf.clientAcceptEncoding
199
+ ) {
200
+ rawAcceptEncoding = contentRequest.cf.clientAcceptEncoding as string;
201
+ } else {
202
+ rawAcceptEncoding =
203
+ contentRequest.headers.get("Accept-Encoding") || undefined;
204
+ }
205
+
206
+ const acceptEncoding = parseQualityWeightedList(rawAcceptEncoding);
207
+
208
+ if (
209
+ acceptEncoding["identity"] === 0 ||
210
+ (acceptEncoding["*"] === 0 &&
211
+ acceptEncoding["identity"] === undefined)
212
+ ) {
213
+ throw new Error("No acceptable encodings available");
214
+ }
215
+
216
+ return { encoding: null };
217
+ },
218
+ fetchAsset: async (assetKey) => {
219
+ const filepath = assetKeyEntryMap.get(assetKey);
220
+ if (!filepath) {
221
+ throw new Error(
222
+ "Could not fetch asset. Please file an issue on GitHub (https://github.com/cloudflare/workers-sdk/issues/new/choose) with reproduction steps."
223
+ );
224
+ }
225
+ const body = readFileSync(filepath) as unknown as ReadableStream;
226
+
227
+ let contentType = getType(filepath) || "application/octet-stream";
228
+ if (
229
+ contentType.startsWith("text/") &&
230
+ !contentType.includes("charset")
231
+ ) {
232
+ contentType = `${contentType}; charset=utf-8`;
233
+ }
234
+
235
+ return { body, contentType };
236
+ },
237
+ });
238
+ };
239
+
240
+ return (async (input: TreRequestInfo, init?: TreRequestInit) => {
241
+ const request = new Request(input, init);
242
+ return await generateResponse(request as unknown as Request);
243
+ }) as typeof fetch;
244
+ }
245
+
246
+ const invalidAssetsFetch: typeof fetch = () => {
247
+ throw new Error(
248
+ "Trying to fetch assets directly when there is no `directory` option specified."
249
+ );
250
+ };
@@ -1,41 +1,210 @@
1
- import { Log, LogLevel, Miniflare } from "miniflare";
1
+ import { fetch } from "@miniflare/core";
2
+ import {
3
+ DurableObjectNamespace,
4
+ DurableObjectStub,
5
+ } from "@miniflare/durable-objects";
6
+ import {
7
+ Log as MiniflareLog,
8
+ LogLevel as MiniflareLogLevel,
9
+ Miniflare,
10
+ Request as MiniflareRequest,
11
+ Response as MiniflareResponse,
12
+ } from "miniflare";
2
13
  import yargs from "yargs";
3
14
  import { hideBin } from "yargs/helpers";
4
- import { enumKeys } from "./enum-keys";
15
+ import { FatalError } from "../errors";
16
+ import generateASSETSBinding from "./assets";
5
17
  import { getRequestContextCheckOptions } from "./request-context";
18
+ import type { LoggerLevel } from "../logger";
19
+ import type { Options } from "./assets";
20
+ import type { EnablePagesAssetsServiceBindingOptions } from "./types";
21
+ import type { AddressInfo } from "net";
22
+
23
+ // miniflare defines this but importing it throws:
24
+ // Dynamic require of "path" is not supported
25
+ class MiniflareNoOpLog extends MiniflareLog {
26
+ log(): void {}
27
+
28
+ error(message: Error): void {
29
+ throw message;
30
+ }
31
+ }
6
32
 
7
33
  async function main() {
8
- const args = await yargs(hideBin(process.argv))
9
- .help(false)
10
- .version(false)
11
- .option("log", {
12
- choices: enumKeys(LogLevel),
13
- }).argv;
14
-
15
- const logLevel = LogLevel[args.log ?? "INFO"];
16
- const requestContextCheckOptions = await getRequestContextCheckOptions();
17
- const config = {
18
- ...JSON.parse((args._[0] as string) ?? "{}"),
19
- ...requestContextCheckOptions,
20
- log: new Log(logLevel),
21
- };
22
-
23
- if (logLevel > LogLevel.INFO) {
24
- console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
25
- }
26
-
27
- const mf = new Miniflare(config);
28
-
29
- try {
30
- // Start Miniflare development server
31
- await mf.startServer();
32
- await mf.startScheduler();
33
- } catch (e) {
34
- mf.log.error(e as Error);
35
- process.exitCode = 1;
36
- // Unmount any mounted workers
37
- await mf.dispose();
38
- }
34
+ const args = await yargs(hideBin(process.argv)).help(false).version(false)
35
+ .argv;
36
+
37
+ const requestContextCheckOptions = await getRequestContextCheckOptions();
38
+ const config = {
39
+ ...JSON.parse((args._[0] as string) ?? "{}"),
40
+ ...requestContextCheckOptions,
41
+ };
42
+
43
+ let logLevelString: Uppercase<LoggerLevel> = config.logLevel.toUpperCase();
44
+ if (logLevelString === "LOG") logLevelString = "INFO";
45
+ const logLevel = MiniflareLogLevel[logLevelString];
46
+
47
+ config.log =
48
+ logLevel === MiniflareLogLevel.NONE
49
+ ? new MiniflareNoOpLog()
50
+ : new MiniflareLog(logLevel, config.logOptions);
51
+
52
+ if (logLevel === MiniflareLogLevel.DEBUG) {
53
+ console.log("MINIFLARE OPTIONS:\n", JSON.stringify(config, null, 2));
54
+ }
55
+
56
+ config.bindings = {
57
+ ...config.bindings,
58
+ ...(config.externalDurableObjects &&
59
+ Object.fromEntries(
60
+ Object.entries(
61
+ config.externalDurableObjects as Record<
62
+ string,
63
+ { name: string; host: string; port: number }
64
+ >
65
+ ).map(([binding, { name, host, port }]) => {
66
+ const factory = () => {
67
+ throw new FatalError(
68
+ "An external Durable Object instance's state has somehow been attempted to be accessed.",
69
+ 1
70
+ );
71
+ };
72
+ const namespace = new DurableObjectNamespace(name as string, factory);
73
+ namespace.get = (id) => {
74
+ const stub = new DurableObjectStub(factory, id);
75
+ stub.fetch = (...reqArgs) => {
76
+ const requestFromArgs = new MiniflareRequest(...reqArgs);
77
+ const url = new URL(requestFromArgs.url);
78
+ url.host = host;
79
+ if (port !== undefined) url.port = port.toString();
80
+ const request = new MiniflareRequest(
81
+ url.toString(),
82
+ requestFromArgs
83
+ );
84
+ request.headers.set("x-miniflare-durable-object-name", name);
85
+ request.headers.set(
86
+ "x-miniflare-durable-object-id",
87
+ id.toString()
88
+ );
89
+
90
+ return fetch(request);
91
+ };
92
+ return stub;
93
+ };
94
+ return [binding, namespace];
95
+ })
96
+ )),
97
+ };
98
+
99
+ let mf: Miniflare | undefined;
100
+ let durableObjectsMf: Miniflare | undefined = undefined;
101
+ let durableObjectsMfPort: number | undefined = undefined;
102
+
103
+ try {
104
+ if (args._[1]) {
105
+ const opts: EnablePagesAssetsServiceBindingOptions = JSON.parse(
106
+ args._[1] as string
107
+ );
108
+
109
+ if (isNaN(opts.proxyPort || NaN) && !opts.directory) {
110
+ throw new Error(
111
+ "MiniflareCLIOptions: built in service bindings set to true, but no port or directory provided"
112
+ );
113
+ }
114
+
115
+ const options: Options = {
116
+ log: config.log,
117
+ proxyPort: opts.proxyPort,
118
+ directory: opts.directory,
119
+ tre: false,
120
+ };
121
+
122
+ config.serviceBindings = {
123
+ ...config.serviceBindings,
124
+ ASSETS: await generateASSETSBinding(options),
125
+ };
126
+ }
127
+ mf = new Miniflare(config);
128
+ // Start Miniflare development server
129
+ const mfServer = await mf.startServer();
130
+ const mfPort = (mfServer.address() as AddressInfo).port;
131
+ await mf.startScheduler();
132
+
133
+ const internalDurableObjectClassNames = Object.values(
134
+ config.durableObjects as Record<string, string>
135
+ );
136
+
137
+ if (internalDurableObjectClassNames.length > 0) {
138
+ durableObjectsMf = new Miniflare({
139
+ host: config.host,
140
+ port: 0,
141
+ script: `
142
+ export default {
143
+ fetch(request, env) {
144
+ return env.DO.fetch(request)
145
+ }
146
+ }`,
147
+ serviceBindings: {
148
+ DO: async (request: MiniflareRequest) => {
149
+ request = new MiniflareRequest(request);
150
+
151
+ const name = request.headers.get("x-miniflare-durable-object-name");
152
+ const idString = request.headers.get(
153
+ "x-miniflare-durable-object-id"
154
+ );
155
+ request.headers.delete("x-miniflare-durable-object-name");
156
+ request.headers.delete("x-miniflare-durable-object-id");
157
+
158
+ if (!name || !idString) {
159
+ return new MiniflareResponse(
160
+ "[durable-object-proxy-err] Missing `x-miniflare-durable-object-name` or `x-miniflare-durable-object-id` headers.",
161
+ { status: 400 }
162
+ );
163
+ }
164
+
165
+ const namespace = await mf?.getDurableObjectNamespace(name);
166
+ const id = namespace?.idFromString(idString);
167
+
168
+ if (!id) {
169
+ return new MiniflareResponse(
170
+ "[durable-object-proxy-err] Could not generate an ID. Possibly due to a mismatched DO name and ID?",
171
+ { status: 500 }
172
+ );
173
+ }
174
+
175
+ const stub = namespace?.get(id);
176
+
177
+ if (!stub) {
178
+ return new MiniflareResponse(
179
+ "[durable-object-proxy-err] Could not generate a stub. Possibly due to a mismatched DO name and ID?",
180
+ { status: 500 }
181
+ );
182
+ }
183
+
184
+ return stub.fetch(request);
185
+ },
186
+ },
187
+ modules: true,
188
+ });
189
+ const server = await durableObjectsMf.startServer();
190
+ durableObjectsMfPort = (server.address() as AddressInfo).port;
191
+ }
192
+
193
+ process.send &&
194
+ process.send(
195
+ JSON.stringify({
196
+ port: mfPort,
197
+ ready: true,
198
+ durableObjectsPort: durableObjectsMfPort,
199
+ })
200
+ );
201
+ } catch (e) {
202
+ mf?.log.error(e as Error);
203
+ process.exitCode = 1;
204
+ // Unmount any mounted workers
205
+ await mf?.dispose();
206
+ await durableObjectsMf?.dispose();
207
+ }
39
208
  }
40
209
 
41
210
  await main();
@@ -16,25 +16,25 @@ import type { MiniflareOptions } from "miniflare";
16
16
  * that indicate to miniflare whether to run the checks or not.
17
17
  */
18
18
  export const getRequestContextCheckOptions = async (): Promise<
19
- Pick<MiniflareOptions, "globalAsyncIO" | "globalTimers" | "globalRandom">
19
+ Pick<MiniflareOptions, "globalAsyncIO" | "globalTimers" | "globalRandom">
20
20
  > => {
21
- // check that there's an implementation of AsyncLocalStorage
22
- let hasAsyncLocalStorage = true;
23
- try {
24
- // ripped from the example here https://nodejs.org/api/async_context.html#class-asynclocalstorage
25
- const { AsyncLocalStorage } = await import("node:async_hooks");
26
- const storage = new AsyncLocalStorage<string>();
21
+ // check that there's an implementation of AsyncLocalStorage
22
+ let hasAsyncLocalStorage = true;
23
+ try {
24
+ // ripped from the example here https://nodejs.org/api/async_context.html#class-asynclocalstorage
25
+ const { AsyncLocalStorage } = await import("node:async_hooks");
26
+ const storage = new AsyncLocalStorage<string>();
27
27
 
28
- hasAsyncLocalStorage = storage.run("some-value", () => {
29
- return storage.getStore() === "some-value";
30
- });
31
- } catch (e) {
32
- hasAsyncLocalStorage = false;
33
- }
28
+ hasAsyncLocalStorage = storage.run("some-value", () => {
29
+ return storage.getStore() === "some-value";
30
+ });
31
+ } catch (e) {
32
+ hasAsyncLocalStorage = false;
33
+ }
34
34
 
35
- return {
36
- globalAsyncIO: hasAsyncLocalStorage,
37
- globalRandom: hasAsyncLocalStorage,
38
- globalTimers: hasAsyncLocalStorage,
39
- };
35
+ return {
36
+ globalAsyncIO: hasAsyncLocalStorage,
37
+ globalRandom: hasAsyncLocalStorage,
38
+ globalTimers: hasAsyncLocalStorage,
39
+ };
40
40
  };
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["node"],
5
+ "module": "esnext"
6
+ },
7
+ "include": ["**/*.ts"],
8
+ "exclude": []
9
+ }