@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21

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 (217) hide show
  1. package/dist/cjs/backend-federation-build/codegen.js +267 -0
  2. package/dist/cjs/backend-federation-build/config.js +239 -0
  3. package/dist/cjs/backend-federation-build/emit.js +154 -0
  4. package/dist/cjs/backend-federation-build/index.js +53 -0
  5. package/dist/cjs/build-config/build-environment.js +129 -0
  6. package/dist/cjs/build-config/precompress/plugin.js +124 -0
  7. package/dist/cjs/build-config/precompress/types.js +18 -0
  8. package/dist/cjs/build-config/public.js +43 -0
  9. package/dist/cjs/build-config/remote-address.js +58 -0
  10. package/dist/cjs/cloudflare/artifacts.js +8 -19
  11. package/dist/cjs/cloudflare/constants.js +1 -1
  12. package/dist/cjs/cloudflare/delivery-unit.js +23 -42
  13. package/dist/cjs/cloudflare/index.js +10 -2
  14. package/dist/cjs/cloudflare/worker-manifest.js +13 -4
  15. package/dist/cjs/cloudflare/wrangler-config.js +35 -7
  16. package/dist/cjs/cloudflare-builder.js +252 -75
  17. package/dist/cjs/cloudflare-output-contract.js +69 -3
  18. package/dist/cjs/cloudflare-output-verifier/identity.js +29 -27
  19. package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
  20. package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
  21. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
  22. package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +14 -6
  23. package/dist/cjs/config.js +34 -1
  24. package/dist/cjs/deploy-output/npmAliases.js +251 -0
  25. package/dist/cjs/deploy-output/plugin.js +97 -0
  26. package/dist/cjs/deploy-output/public-assets.js +146 -0
  27. package/dist/cjs/deploy-output/target.js +104 -0
  28. package/dist/cjs/deploy-output/trace-files.js +90 -0
  29. package/dist/cjs/native-type-checker.js +193 -0
  30. package/dist/cjs/policy-defaults.js +101 -0
  31. package/dist/cjs/release-envelope/framework-output.js +153 -79
  32. package/dist/cjs/release-envelope/index.js +10 -4
  33. package/dist/cjs/release-envelope/plugin.js +18 -13
  34. package/dist/cjs/release-identity.js +5 -6
  35. package/dist/cjs/runtime-package-resolution.js +118 -0
  36. package/dist/cjs/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
  37. package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  38. package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  39. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  40. package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  41. package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
  42. package/dist/esm/backend-federation-build/codegen.mjs +216 -0
  43. package/dist/esm/backend-federation-build/config.mjs +163 -0
  44. package/dist/esm/backend-federation-build/emit.mjs +103 -0
  45. package/dist/esm/backend-federation-build/index.mjs +1 -0
  46. package/dist/esm/build-config/build-environment.mjs +88 -0
  47. package/dist/esm/build-config/precompress/plugin.mjs +76 -0
  48. package/dist/esm/build-config/precompress/types.mjs +0 -0
  49. package/dist/esm/build-config/public.mjs +1 -0
  50. package/dist/esm/build-config/remote-address.mjs +20 -0
  51. package/dist/esm/cloudflare/artifacts.mjs +8 -19
  52. package/dist/esm/cloudflare/constants.mjs +1 -1
  53. package/dist/esm/cloudflare/delivery-unit.mjs +17 -36
  54. package/dist/esm/cloudflare/index.mjs +10 -2
  55. package/dist/esm/cloudflare/worker-manifest.mjs +13 -4
  56. package/dist/esm/cloudflare/wrangler-config.mjs +35 -7
  57. package/dist/esm/cloudflare-builder.mjs +246 -75
  58. package/dist/esm/cloudflare-output-contract.mjs +59 -2
  59. package/dist/esm/cloudflare-output-verifier/identity.mjs +27 -25
  60. package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
  61. package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
  62. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  63. package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +15 -7
  64. package/dist/esm/config.mjs +3 -0
  65. package/dist/esm/deploy-output/npmAliases.mjs +199 -0
  66. package/dist/esm/deploy-output/plugin.mjs +46 -0
  67. package/dist/esm/deploy-output/public-assets.mjs +82 -0
  68. package/dist/esm/deploy-output/target.mjs +57 -0
  69. package/dist/esm/deploy-output/trace-files.mjs +38 -0
  70. package/dist/esm/native-type-checker.mjs +142 -0
  71. package/dist/esm/policy-defaults.mjs +45 -0
  72. package/dist/esm/release-envelope/framework-output.mjs +130 -56
  73. package/dist/esm/release-envelope/index.mjs +10 -4
  74. package/dist/esm/release-envelope/plugin.mjs +18 -13
  75. package/dist/esm/release-identity.mjs +5 -6
  76. package/dist/esm/runtime-package-resolution.mjs +60 -0
  77. package/dist/esm/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
  78. package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  79. package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  80. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  81. package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  82. package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
  83. package/dist/esm-node/backend-federation-build/codegen.mjs +217 -0
  84. package/dist/esm-node/backend-federation-build/config.mjs +164 -0
  85. package/dist/esm-node/backend-federation-build/emit.mjs +104 -0
  86. package/dist/esm-node/backend-federation-build/index.mjs +2 -0
  87. package/dist/esm-node/build-config/build-environment.mjs +89 -0
  88. package/dist/esm-node/build-config/precompress/plugin.mjs +77 -0
  89. package/dist/esm-node/build-config/precompress/types.mjs +1 -0
  90. package/dist/esm-node/build-config/public.mjs +2 -0
  91. package/dist/esm-node/build-config/remote-address.mjs +21 -0
  92. package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
  93. package/dist/esm-node/cloudflare/constants.mjs +1 -1
  94. package/dist/esm-node/cloudflare/delivery-unit.mjs +17 -36
  95. package/dist/esm-node/cloudflare/index.mjs +10 -2
  96. package/dist/esm-node/cloudflare/worker-manifest.mjs +13 -4
  97. package/dist/esm-node/cloudflare/wrangler-config.mjs +35 -7
  98. package/dist/esm-node/cloudflare-builder.mjs +246 -75
  99. package/dist/esm-node/cloudflare-output-contract.mjs +59 -2
  100. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +27 -25
  101. package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
  102. package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
  103. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  104. package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +15 -7
  105. package/dist/esm-node/config.mjs +3 -0
  106. package/dist/esm-node/deploy-output/npmAliases.mjs +200 -0
  107. package/dist/esm-node/deploy-output/plugin.mjs +49 -0
  108. package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
  109. package/dist/esm-node/deploy-output/target.mjs +58 -0
  110. package/dist/esm-node/deploy-output/trace-files.mjs +39 -0
  111. package/dist/esm-node/native-type-checker.mjs +143 -0
  112. package/dist/esm-node/policy-defaults.mjs +46 -0
  113. package/dist/esm-node/release-envelope/framework-output.mjs +130 -56
  114. package/dist/esm-node/release-envelope/index.mjs +10 -4
  115. package/dist/esm-node/release-envelope/plugin.mjs +18 -13
  116. package/dist/esm-node/release-identity.mjs +5 -6
  117. package/dist/esm-node/runtime-package-resolution.mjs +61 -0
  118. package/dist/esm-node/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
  119. package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  120. package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  121. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  122. package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  123. package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
  124. package/dist/types/backend-federation-build/codegen.d.ts +116 -0
  125. package/dist/types/backend-federation-build/config.d.ts +121 -0
  126. package/dist/types/backend-federation-build/emit.d.ts +21 -0
  127. package/dist/types/backend-federation-build/index.d.ts +2 -0
  128. package/dist/types/build-config/build-environment.d.ts +14 -0
  129. package/dist/types/build-config/precompress/plugin.d.ts +4 -0
  130. package/dist/types/build-config/precompress/types.d.ts +19 -0
  131. package/dist/types/build-config/public.d.ts +2 -0
  132. package/dist/types/build-config/remote-address.d.ts +3 -0
  133. package/dist/types/cloudflare/artifacts.d.ts +7 -6
  134. package/dist/types/cloudflare/constants.d.ts +1 -1
  135. package/dist/types/cloudflare/delivery-unit.d.ts +3 -3
  136. package/dist/types/cloudflare/worker-manifest.d.ts +2 -2
  137. package/dist/types/cloudflare/wrangler-config.d.ts +6 -0
  138. package/dist/types/cloudflare-builder.d.ts +49 -9
  139. package/dist/types/cloudflare-output-contract.d.ts +4 -1
  140. package/dist/types/cloudflare-output-verifier/identity.d.ts +1 -1
  141. package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
  142. package/dist/types/config.d.ts +29 -1
  143. package/dist/types/deploy-output/npmAliases.d.ts +14 -0
  144. package/dist/types/deploy-output/plugin.d.ts +35 -0
  145. package/dist/types/deploy-output/public-assets.d.ts +51 -0
  146. package/dist/types/deploy-output/target.d.ts +29 -0
  147. package/dist/types/deploy-output/trace-files.d.ts +17 -0
  148. package/dist/types/native-type-checker.d.ts +15 -0
  149. package/dist/types/policy-defaults.d.ts +46 -0
  150. package/dist/types/precompress/LICENSE +20 -0
  151. package/dist/types/precompress/index.d.ts +76 -0
  152. package/dist/types/release-envelope/framework-output.d.ts +8 -3
  153. package/dist/types/release-envelope/plugin.d.ts +7 -7
  154. package/dist/types/runtime-package-resolution.d.ts +28 -0
  155. package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
  156. package/package.json +97 -15
  157. package/src/backend-federation-build/codegen.ts +254 -0
  158. package/src/backend-federation-build/config.ts +492 -0
  159. package/src/backend-federation-build/emit.ts +213 -0
  160. package/src/backend-federation-build/index.ts +2 -0
  161. package/src/build-config/build-environment.ts +160 -0
  162. package/src/build-config/precompress/plugin.ts +140 -0
  163. package/src/build-config/precompress/types.ts +26 -0
  164. package/src/build-config/public.ts +5 -0
  165. package/src/build-config/remote-address.ts +33 -0
  166. package/src/cloudflare/artifacts.ts +22 -43
  167. package/src/cloudflare/constants.ts +1 -1
  168. package/src/cloudflare/delivery-unit.ts +42 -53
  169. package/src/cloudflare/index.ts +24 -11
  170. package/src/cloudflare/worker-manifest.ts +20 -3
  171. package/src/cloudflare/wrangler-config.ts +86 -10
  172. package/src/cloudflare-builder.ts +475 -151
  173. package/src/cloudflare-output-contract.ts +70 -0
  174. package/src/cloudflare-output-verifier/identity.ts +5 -1
  175. package/src/cloudflare-output-verifier/index.ts +20 -0
  176. package/src/cloudflare-output-verifier/manifest.ts +77 -0
  177. package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
  178. package/src/cloudflare-output-verifier/worker-bundles.ts +32 -14
  179. package/src/config.ts +34 -6
  180. package/src/deploy-output/npmAliases.ts +382 -0
  181. package/src/deploy-output/plugin.ts +86 -0
  182. package/src/deploy-output/public-assets.ts +224 -0
  183. package/src/deploy-output/target.ts +106 -0
  184. package/src/deploy-output/trace-files.ts +67 -0
  185. package/src/native-type-checker.ts +183 -0
  186. package/src/policy-defaults.ts +127 -0
  187. package/src/release-envelope/framework-output.ts +346 -94
  188. package/src/release-envelope/index.ts +26 -5
  189. package/src/release-envelope/plugin.ts +43 -40
  190. package/src/release-identity.ts +13 -2
  191. package/src/runtime-package-resolution.ts +115 -0
  192. package/src/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
  193. package/src/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  194. package/src/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  195. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  196. package/src/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  197. package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
  198. package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
  199. package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
  200. package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  201. package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
  202. package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
  203. package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
  204. package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  205. package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
  206. package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
  207. package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
  208. package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  209. package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
  210. package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
  211. package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
  212. package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
  213. package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
  214. package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
  215. package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
  216. package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  217. package/src/templates/cloudflare-worker-path.mjs +0 -98
@@ -0,0 +1,61 @@
1
+ import "node:module";
2
+ import node_fs from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import node_path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ const findHostingModuleDirectory = (packageName, fromDirectory)=>{
7
+ let directory = node_path.resolve(fromDirectory);
8
+ for(;;){
9
+ const candidate = node_path.join(directory, 'node_modules');
10
+ if (node_fs.existsSync(node_path.join(candidate, packageName))) return candidate;
11
+ const parent = node_path.dirname(directory);
12
+ if (parent === directory) return;
13
+ directory = parent;
14
+ }
15
+ };
16
+ const collectRuntimePackageModuleDirectories = (packageNames, registrarUrl)=>{
17
+ const registrarDirectory = node_path.dirname(fileURLToPath(registrarUrl));
18
+ const directories = [];
19
+ for (const packageName of packageNames){
20
+ const directory = findHostingModuleDirectory(packageName, registrarDirectory);
21
+ if (directory && !directories.includes(directory)) directories.push(directory);
22
+ }
23
+ return directories;
24
+ };
25
+ const appendModuleDirectories = (config, directories)=>{
26
+ if (0 === directories.length) return;
27
+ config.resolve ??= {};
28
+ const existing = config.resolve.modules ?? [
29
+ 'node_modules'
30
+ ];
31
+ config.resolve.modules = [
32
+ ...existing,
33
+ ...directories.filter((directory)=>!existing.includes(directory))
34
+ ];
35
+ };
36
+ const createRuntimePackageResolutionPlugin = (directories)=>({
37
+ name: 'ultramodern:runtime-package-resolution',
38
+ setup (api) {
39
+ api.modifyRspackConfig({
40
+ order: 'post',
41
+ handler (config) {
42
+ appendModuleDirectories(config, directories);
43
+ }
44
+ });
45
+ api.onBeforeCreateCompiler({
46
+ order: 'post',
47
+ handler ({ bundlerConfigs }) {
48
+ for (const config of bundlerConfigs)appendModuleDirectories(config, directories);
49
+ }
50
+ });
51
+ }
52
+ });
53
+ const canResolveRuntimePackage = (packageName, registrarUrl)=>{
54
+ try {
55
+ createRequire(registrarUrl).resolve(packageName);
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ };
61
+ export { canResolveRuntimePackage, collectRuntimePackageModuleDirectories, createRuntimePackageResolutionPlugin, findHostingModuleDirectory };
@@ -24,9 +24,6 @@ const ASSET_CORS_HEADERS = {
24
24
  'access-control-allow-origin': '*',
25
25
  };
26
26
 
27
- globalThis.__dirname ??= '/';
28
- globalThis.__filename ??= '/index.js';
29
-
30
27
  function getAllowedAppCorsOrigin(request) {
31
28
  if (APP_CORS_ALLOWED_ORIGINS.length === 0) {
32
29
  return null;
@@ -20,7 +20,7 @@ function withAssetHeaders(response, request) {
20
20
  });
21
21
  }
22
22
 
23
- async function createCorsPreflightResponse(request, env) {
23
+ async function createCorsPreflightResponse(request, _env) {
24
24
  if (request.method !== 'OPTIONS') {
25
25
  return null;
26
26
  }
@@ -2,9 +2,13 @@ function createNoopMonitors() {
2
2
  const noop = () => {};
3
3
 
4
4
  return {
5
+ counter: noop,
5
6
  debug: noop,
6
7
  error: noop,
7
8
  info: noop,
9
+ push: noop,
10
+ timing: noop,
11
+ trace: noop,
8
12
  warn: noop,
9
13
  };
10
14
  }
@@ -1134,7 +1138,7 @@ async function withRouteCssLinks(
1134
1138
  seenCssHrefs.add(entry.preloadHref);
1135
1139
  return true;
1136
1140
  });
1137
- for (const { href, preloadHref } of uniqueCssEntries) {
1141
+ for (const { preloadHref } of uniqueCssEntries) {
1138
1142
  const preloadUrl = new URL(preloadHref);
1139
1143
  const preloadReference =
1140
1144
  preloadUrl.origin === requestOrigin
@@ -52,6 +52,52 @@ async function getRequestHandler(workerModule) {
52
52
  );
53
53
  }
54
54
 
55
+ const ROUTE_DATA_REQUEST_PARAM = '__loader';
56
+
57
+ // Route data requests (`?__loader=`) are answered by the entry's route data
58
+ // worker, like the Node server's data handler. Without a match the request
59
+ // falls through to page rendering, as it does on Node.
60
+ async function dispatchRouteDataRequest(route, request) {
61
+ const routeDataWorkerPath = route.routeDataWorker;
62
+ if (
63
+ !routeDataWorkerPath ||
64
+ !new URL(request.url).searchParams.has(ROUTE_DATA_REQUEST_PARAM)
65
+ ) {
66
+ return undefined;
67
+ }
68
+
69
+ const routeDataWorkerModule = await loadWorkerModule(routeDataWorkerPath);
70
+ const handleRouteDataRequest = routeDataWorkerModule
71
+ ? getRuntimeModule(routeDataWorkerModule).handleRouteDataRequest
72
+ : undefined;
73
+
74
+ if (typeof handleRouteDataRequest !== 'function') {
75
+ return new Response(
76
+ `Route data worker bundle has no handleRouteDataRequest export: ${routeDataWorkerPath}`,
77
+ {
78
+ status: 500,
79
+ headers: {
80
+ 'content-type': 'text/plain; charset=utf-8',
81
+ 'x-modern-js-route-data-worker': routeDataWorkerPath,
82
+ },
83
+ },
84
+ );
85
+ }
86
+
87
+ return handleRouteDataRequest({
88
+ request,
89
+ serverRoutes: MODERN_WORKER_MANIFEST.routeSpec.routes,
90
+ context: {
91
+ loaderContext: new Map(),
92
+ monitors: createNoopMonitors(),
93
+ reporter: {
94
+ reportTiming: () => {},
95
+ },
96
+ },
97
+ onTiming() {},
98
+ });
99
+ }
100
+
55
101
  async function dispatchRouteWorker(route, request, env, ctx) {
56
102
  const workerPath = route.worker;
57
103
  if (!workerPath) {
@@ -114,14 +160,46 @@ async function dispatchRouteWorker(route, request, env, ctx) {
114
160
  );
115
161
  }
116
162
 
117
- function matchesPrefix(pathname, prefix) {
163
+ // Worker Static Assets decode percent-encoded paths, so an encoded spelling
164
+ // of a mounted prefix (`/%70refix/...`, `/prefix%2F...`) would otherwise skip
165
+ // the BFF or service binding that owns the prefix and reach ASSETS directly.
166
+ // Resolve such spellings to the canonical pathname the owner sees; a
167
+ // backslash or undecodable spelling becomes a path the owner rejects.
168
+ function resolvePrefixPathname(pathname, prefix) {
118
169
  if (!prefix || prefix === '/') {
119
- return true;
170
+ return pathname;
120
171
  }
121
172
 
122
173
  const normalized = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
174
+ let candidate = pathname;
175
+
176
+ for (let attempt = 0; attempt < 4; attempt += 1) {
177
+ if (candidate === normalized || candidate.startsWith(`${normalized}/`)) {
178
+ return candidate;
179
+ }
180
+ if (candidate.startsWith(`${normalized}\\`)) {
181
+ return `${normalized}/__invalid_encoded_path__`;
182
+ }
123
183
 
124
- return pathname === normalized || pathname.startsWith(`${normalized}/`);
184
+ let decoded;
185
+ try {
186
+ decoded = decodeURIComponent(candidate);
187
+ } catch {
188
+ return candidate.toLowerCase().startsWith(normalized.toLowerCase())
189
+ ? `${normalized}/__invalid_encoded_path__`
190
+ : null;
191
+ }
192
+ if (decoded === candidate) {
193
+ return null;
194
+ }
195
+ candidate = decoded;
196
+ }
197
+
198
+ return null;
199
+ }
200
+
201
+ function matchesPrefix(pathname, prefix) {
202
+ return resolvePrefixPathname(pathname, prefix) !== null;
125
203
  }
126
204
 
127
205
  function createRequestForMountedPrefix(request, prefix) {
@@ -131,12 +209,13 @@ function createRequestForMountedPrefix(request, prefix) {
131
209
 
132
210
  const url = new URL(request.url);
133
211
  const normalized = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
212
+ const matchedPathname = resolvePrefixPathname(url.pathname, normalized);
134
213
 
135
- if (!matchesPrefix(url.pathname, normalized)) {
214
+ if (matchedPathname === null) {
136
215
  return request;
137
216
  }
138
217
 
139
- const nextPath = url.pathname.slice(normalized.length) || '/';
218
+ const nextPath = matchedPathname.slice(normalized.length) || '/';
140
219
  url.pathname = nextPath.startsWith('/') ? nextPath : `/${nextPath}`;
141
220
 
142
221
  return new Request(url, request);
@@ -263,12 +342,21 @@ function getEffectBffDispatcher(bff, runtime) {
263
342
  async function dispatchBffRequest(request, env) {
264
343
  const bff = MODERN_WORKER_MANIFEST.bff;
265
344
 
266
- if (
267
- !bff?.worker ||
268
- !matchesPrefix(new URL(request.url).pathname, bff.prefix)
269
- ) {
345
+ const requestUrl = new URL(request.url);
346
+ const matchedPathname = resolvePrefixPathname(
347
+ requestUrl.pathname,
348
+ bff?.prefix,
349
+ );
350
+ if (!bff?.worker || matchedPathname === null) {
270
351
  return null;
271
352
  }
353
+ const canonicalRequest =
354
+ matchedPathname === requestUrl.pathname
355
+ ? request
356
+ : new Request(
357
+ Object.assign(requestUrl, { pathname: matchedPathname }),
358
+ request,
359
+ );
272
360
  if (bff.runtimeFramework !== 'effect') {
273
361
  return createEffectBffDispatcherErrorResponse(
274
362
  bff,
@@ -301,7 +389,7 @@ async function dispatchBffRequest(request, env) {
301
389
  return createEffectBffDispatcherErrorResponse(bff, error);
302
390
  }
303
391
 
304
- return effectDispatcher.dispatch(request, { env });
392
+ return effectDispatcher.dispatch(canonicalRequest, { env });
305
393
  }
306
394
 
307
395
  const directHandler =
@@ -62,11 +62,18 @@ export default {
62
62
  }
63
63
 
64
64
  if (route?.worker) {
65
- const renderableRequest = createRenderableRequest(request);
65
+ // Route data requests keep their method, as on the Node server.
66
+ const routeDataResponse = await dispatchRouteDataRequest(route, request);
66
67
 
67
68
  return finalizeResponseForRequest(
68
69
  withAppCorsHeaders(
69
- await dispatchRouteWorker(route, renderableRequest, env, ctx),
70
+ routeDataResponse ??
71
+ (await dispatchRouteWorker(
72
+ route,
73
+ createRenderableRequest(request),
74
+ env,
75
+ ctx,
76
+ )),
70
77
  request,
71
78
  ),
72
79
  request,