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

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 (275) hide show
  1. package/README.md +23 -0
  2. package/dist/cjs/backend-federation-build/codegen.js +29 -18
  3. package/dist/cjs/backend-federation-build/config.js +84 -45
  4. package/dist/cjs/backend-federation-build/emit.js +63 -22
  5. package/dist/cjs/build-config/build-environment.js +25 -162
  6. package/dist/cjs/build-config/internal-effect-discovery.js +143 -0
  7. package/dist/cjs/build-config/public.js +2 -5
  8. package/dist/cjs/build-config/remote-address.js +58 -0
  9. package/dist/cjs/cloudflare/artifacts.js +8 -19
  10. package/dist/cjs/cloudflare/delivery-unit.js +125 -43
  11. package/dist/cjs/cloudflare/index.js +14 -4
  12. package/dist/cjs/cloudflare/native-renderer.js +100 -0
  13. package/dist/cjs/cloudflare/renderer-identity.js +106 -0
  14. package/dist/cjs/cloudflare/worker-manifest.js +54 -13
  15. package/dist/cjs/cloudflare/worker-options.js +48 -0
  16. package/dist/cjs/cloudflare/wrangler-config.js +210 -13
  17. package/dist/cjs/cloudflare-builder.js +307 -89
  18. package/dist/cjs/cloudflare-output-contract.js +36 -4
  19. package/dist/cjs/cloudflare-output-verifier/identity.js +112 -23
  20. package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
  21. package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
  22. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
  23. package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +10 -5
  24. package/dist/cjs/config.js +10 -5
  25. package/dist/cjs/deploy-output/npmAliases.js +92 -6
  26. package/dist/cjs/deploy-output/plugin.js +27 -6
  27. package/dist/cjs/deploy-output/public-assets.js +146 -0
  28. package/dist/cjs/deploy-output/target.js +57 -1
  29. package/dist/cjs/deploy-output/trace-files.js +99 -0
  30. package/dist/cjs/module-federation-config/exposes.js +70 -0
  31. package/dist/cjs/module-federation-config/index.js +73 -0
  32. package/dist/cjs/module-federation-config/inspect.js +103 -0
  33. package/dist/cjs/module-federation-config/object-literal.js +87 -0
  34. package/dist/cjs/module-federation-config/syntax.js +151 -0
  35. package/dist/cjs/module-federation-config/types.js +18 -0
  36. package/dist/cjs/native-type-checker.js +130 -13
  37. package/dist/cjs/policy-defaults.js +38 -29
  38. package/dist/cjs/release-envelope/canonical.js +2 -9
  39. package/dist/cjs/release-envelope/contract.js +68 -0
  40. package/dist/cjs/release-envelope/framework-output.js +296 -105
  41. package/dist/cjs/release-envelope/index.js +150 -36
  42. package/dist/cjs/release-envelope/plugin.js +24 -15
  43. package/dist/cjs/release-envelope/renderer-output-stamp.js +170 -0
  44. package/dist/cjs/release-envelope/types.js +10 -8
  45. package/dist/cjs/release-identity.js +8 -5
  46. package/dist/cjs/renderer-build-identity.js +134 -0
  47. package/dist/cjs/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  48. package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  49. package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  50. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
  51. package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  52. package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
  53. package/dist/cjs/workspace-topology.js +84 -0
  54. package/dist/esm/backend-federation-build/codegen.mjs +29 -18
  55. package/dist/esm/backend-federation-build/config.mjs +74 -38
  56. package/dist/esm/backend-federation-build/emit.mjs +64 -23
  57. package/dist/esm/build-config/build-environment.mjs +26 -160
  58. package/dist/esm/build-config/internal-effect-discovery.mjs +102 -0
  59. package/dist/esm/build-config/public.mjs +1 -1
  60. package/dist/esm/build-config/remote-address.mjs +20 -0
  61. package/dist/esm/cloudflare/artifacts.mjs +8 -19
  62. package/dist/esm/cloudflare/delivery-unit.mjs +124 -45
  63. package/dist/esm/cloudflare/index.mjs +15 -5
  64. package/dist/esm/cloudflare/native-renderer.mjs +48 -0
  65. package/dist/esm/cloudflare/renderer-identity.mjs +57 -0
  66. package/dist/esm/cloudflare/worker-manifest.mjs +55 -14
  67. package/dist/esm/cloudflare/worker-options.mjs +10 -0
  68. package/dist/esm/cloudflare/wrangler-config.mjs +203 -12
  69. package/dist/esm/cloudflare-builder.mjs +301 -89
  70. package/dist/esm/cloudflare-output-contract.mjs +29 -3
  71. package/dist/esm/cloudflare-output-verifier/identity.mjs +113 -24
  72. package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
  73. package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
  74. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  75. package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  76. package/dist/esm/config.mjs +3 -1
  77. package/dist/esm/deploy-output/npmAliases.mjs +92 -6
  78. package/dist/esm/deploy-output/plugin.mjs +24 -6
  79. package/dist/esm/deploy-output/public-assets.mjs +82 -0
  80. package/dist/esm/deploy-output/target.mjs +50 -3
  81. package/dist/esm/deploy-output/trace-files.mjs +47 -0
  82. package/dist/esm/module-federation-config/exposes.mjs +18 -0
  83. package/dist/esm/module-federation-config/index.mjs +4 -0
  84. package/dist/esm/module-federation-config/inspect.mjs +65 -0
  85. package/dist/esm/module-federation-config/object-literal.mjs +43 -0
  86. package/dist/esm/module-federation-config/syntax.mjs +101 -0
  87. package/dist/esm/module-federation-config/types.mjs +0 -0
  88. package/dist/esm/native-type-checker.mjs +124 -13
  89. package/dist/esm/policy-defaults.mjs +36 -30
  90. package/dist/esm/release-envelope/canonical.mjs +2 -9
  91. package/dist/esm/release-envelope/contract.mjs +21 -0
  92. package/dist/esm/release-envelope/framework-output.mjs +297 -106
  93. package/dist/esm/release-envelope/index.mjs +149 -38
  94. package/dist/esm/release-envelope/plugin.mjs +24 -15
  95. package/dist/esm/release-envelope/renderer-output-stamp.mjs +112 -0
  96. package/dist/esm/release-envelope/types.mjs +2 -3
  97. package/dist/esm/release-identity.mjs +8 -5
  98. package/dist/esm/renderer-build-identity.mjs +82 -0
  99. package/dist/esm/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  100. package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  101. package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  102. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
  103. package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  104. package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
  105. package/dist/esm/workspace-topology.mjs +21 -0
  106. package/dist/esm-node/backend-federation-build/codegen.mjs +29 -18
  107. package/dist/esm-node/backend-federation-build/config.mjs +74 -38
  108. package/dist/esm-node/backend-federation-build/emit.mjs +64 -23
  109. package/dist/esm-node/build-config/build-environment.mjs +26 -160
  110. package/dist/esm-node/build-config/internal-effect-discovery.mjs +103 -0
  111. package/dist/esm-node/build-config/public.mjs +1 -1
  112. package/dist/esm-node/build-config/remote-address.mjs +21 -0
  113. package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
  114. package/dist/esm-node/cloudflare/delivery-unit.mjs +124 -45
  115. package/dist/esm-node/cloudflare/index.mjs +15 -5
  116. package/dist/esm-node/cloudflare/native-renderer.mjs +49 -0
  117. package/dist/esm-node/cloudflare/renderer-identity.mjs +58 -0
  118. package/dist/esm-node/cloudflare/worker-manifest.mjs +55 -14
  119. package/dist/esm-node/cloudflare/worker-options.mjs +11 -0
  120. package/dist/esm-node/cloudflare/wrangler-config.mjs +203 -12
  121. package/dist/esm-node/cloudflare-builder.mjs +301 -89
  122. package/dist/esm-node/cloudflare-output-contract.mjs +29 -3
  123. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +113 -24
  124. package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
  125. package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
  126. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  127. package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +11 -6
  128. package/dist/esm-node/config.mjs +3 -1
  129. package/dist/esm-node/deploy-output/npmAliases.mjs +92 -6
  130. package/dist/esm-node/deploy-output/plugin.mjs +24 -6
  131. package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
  132. package/dist/esm-node/deploy-output/target.mjs +50 -3
  133. package/dist/esm-node/deploy-output/trace-files.mjs +48 -0
  134. package/dist/esm-node/module-federation-config/exposes.mjs +19 -0
  135. package/dist/esm-node/module-federation-config/index.mjs +5 -0
  136. package/dist/esm-node/module-federation-config/inspect.mjs +66 -0
  137. package/dist/esm-node/module-federation-config/object-literal.mjs +44 -0
  138. package/dist/esm-node/module-federation-config/syntax.mjs +102 -0
  139. package/dist/esm-node/module-federation-config/types.mjs +1 -0
  140. package/dist/esm-node/native-type-checker.mjs +124 -13
  141. package/dist/esm-node/policy-defaults.mjs +36 -30
  142. package/dist/esm-node/release-envelope/canonical.mjs +2 -9
  143. package/dist/esm-node/release-envelope/contract.mjs +22 -0
  144. package/dist/esm-node/release-envelope/framework-output.mjs +297 -106
  145. package/dist/esm-node/release-envelope/index.mjs +149 -38
  146. package/dist/esm-node/release-envelope/plugin.mjs +24 -15
  147. package/dist/esm-node/release-envelope/renderer-output-stamp.mjs +113 -0
  148. package/dist/esm-node/release-envelope/types.mjs +2 -3
  149. package/dist/esm-node/release-identity.mjs +8 -5
  150. package/dist/esm-node/renderer-build-identity.mjs +83 -0
  151. package/dist/esm-node/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  152. package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  153. package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  154. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
  155. package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  156. package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
  157. package/dist/esm-node/workspace-topology.mjs +22 -0
  158. package/dist/types/backend-federation-build/codegen.d.ts +30 -0
  159. package/dist/types/backend-federation-build/config.d.ts +10 -57
  160. package/dist/types/backend-federation-build/emit.d.ts +12 -2
  161. package/dist/types/backend-federation-build/index.d.ts +1 -1
  162. package/dist/types/build-config/build-environment.d.ts +1 -9
  163. package/dist/types/build-config/internal-effect-discovery.d.ts +4 -0
  164. package/dist/types/build-config/public.d.ts +1 -1
  165. package/dist/types/build-config/remote-address.d.ts +3 -0
  166. package/dist/types/cloudflare/artifacts.d.ts +7 -6
  167. package/dist/types/cloudflare/constants.d.ts +1 -1
  168. package/dist/types/cloudflare/delivery-unit.d.ts +38 -7
  169. package/dist/types/cloudflare/native-renderer.d.ts +30 -0
  170. package/dist/types/cloudflare/renderer-identity.d.ts +25 -0
  171. package/dist/types/cloudflare/worker-manifest.d.ts +17 -2
  172. package/dist/types/cloudflare/worker-options.d.ts +20 -0
  173. package/dist/types/cloudflare/wrangler-config.d.ts +55 -2
  174. package/dist/types/cloudflare-builder.d.ts +51 -8
  175. package/dist/types/cloudflare-output-contract.d.ts +5 -3
  176. package/dist/types/cloudflare-output-verifier/identity.d.ts +7 -3
  177. package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
  178. package/dist/types/config.d.ts +98 -13
  179. package/dist/types/deploy-output/plugin.d.ts +29 -9
  180. package/dist/types/deploy-output/public-assets.d.ts +51 -0
  181. package/dist/types/deploy-output/target.d.ts +28 -5
  182. package/dist/types/deploy-output/trace-files.d.ts +17 -0
  183. package/dist/types/module-federation-config/exposes.d.ts +11 -0
  184. package/dist/types/module-federation-config/index.d.ts +5 -0
  185. package/dist/types/module-federation-config/inspect.d.ts +2 -0
  186. package/dist/types/module-federation-config/object-literal.d.ts +4 -0
  187. package/dist/types/module-federation-config/syntax.d.ts +7 -0
  188. package/dist/types/module-federation-config/types.d.ts +20 -0
  189. package/dist/types/native-type-checker.d.ts +26 -3
  190. package/dist/types/policy-defaults.d.ts +12 -2
  191. package/dist/types/release-envelope/canonical.d.ts +5 -5
  192. package/dist/types/release-envelope/contract.d.mts +8 -0
  193. package/dist/types/release-envelope/framework-output.d.ts +23 -13
  194. package/dist/types/release-envelope/index.d.ts +17 -5
  195. package/dist/types/release-envelope/plugin.d.ts +10 -6
  196. package/dist/types/release-envelope/renderer-output-stamp.d.ts +34 -0
  197. package/dist/types/release-envelope/types.d.ts +42 -4
  198. package/dist/types/release-identity.d.ts +3 -2
  199. package/dist/types/renderer-build-identity.d.ts +30 -0
  200. package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
  201. package/dist/types/workspace-topology.d.ts +91 -0
  202. package/package.json +87 -27
  203. package/src/backend-federation-build/codegen.ts +28 -19
  204. package/src/backend-federation-build/config.ts +189 -123
  205. package/src/backend-federation-build/emit.ts +119 -38
  206. package/src/backend-federation-build/index.ts +4 -1
  207. package/src/build-config/build-environment.ts +59 -285
  208. package/src/build-config/internal-effect-discovery.ts +239 -0
  209. package/src/build-config/public.ts +0 -1
  210. package/src/build-config/remote-address.ts +33 -0
  211. package/src/cloudflare/artifacts.ts +22 -43
  212. package/src/cloudflare/delivery-unit.ts +283 -60
  213. package/src/cloudflare/index.ts +35 -19
  214. package/src/cloudflare/native-renderer.ts +117 -0
  215. package/src/cloudflare/renderer-identity.ts +171 -0
  216. package/src/cloudflare/worker-manifest.ts +108 -10
  217. package/src/cloudflare/worker-options.ts +60 -0
  218. package/src/cloudflare/wrangler-config.ts +390 -14
  219. package/src/cloudflare-builder.ts +543 -170
  220. package/src/cloudflare-output-contract.ts +45 -2
  221. package/src/cloudflare-output-verifier/identity.ts +138 -7
  222. package/src/cloudflare-output-verifier/index.ts +20 -0
  223. package/src/cloudflare-output-verifier/manifest.ts +77 -0
  224. package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
  225. package/src/cloudflare-output-verifier/worker-bundles.ts +27 -11
  226. package/src/config.ts +101 -19
  227. package/src/deploy-output/npmAliases.ts +141 -4
  228. package/src/deploy-output/plugin.ts +55 -18
  229. package/src/deploy-output/public-assets.ts +224 -0
  230. package/src/deploy-output/target.ts +97 -14
  231. package/src/deploy-output/trace-files.ts +80 -0
  232. package/src/module-federation-config/exposes.ts +46 -0
  233. package/src/module-federation-config/index.ts +22 -0
  234. package/src/module-federation-config/inspect.ts +157 -0
  235. package/src/module-federation-config/object-literal.ts +76 -0
  236. package/src/module-federation-config/syntax.ts +212 -0
  237. package/src/module-federation-config/types.ts +22 -0
  238. package/src/native-type-checker.ts +233 -20
  239. package/src/policy-defaults.ts +47 -17
  240. package/src/release-envelope/canonical.ts +6 -18
  241. package/src/release-envelope/contract.mjs +28 -0
  242. package/src/release-envelope/framework-output.ts +681 -156
  243. package/src/release-envelope/index.ts +315 -60
  244. package/src/release-envelope/plugin.ts +54 -38
  245. package/src/release-envelope/renderer-output-stamp.ts +210 -0
  246. package/src/release-envelope/types.ts +75 -6
  247. package/src/release-identity.ts +19 -2
  248. package/src/renderer-build-identity.ts +168 -0
  249. package/src/templates/cloudflare-entry.001-bootstrap-security.mjs +14 -6
  250. package/src/templates/cloudflare-entry.002-assets-routes.mjs +10 -2
  251. package/src/templates/cloudflare-entry.004-rendering-css.mjs +403 -96
  252. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +530 -103
  253. package/src/templates/cloudflare-entry.006-fetch-handler.mjs +26 -7
  254. package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
  255. package/src/workspace-topology.ts +125 -0
  256. package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
  257. package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
  258. package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  259. package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
  260. package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
  261. package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
  262. package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  263. package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
  264. package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
  265. package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
  266. package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  267. package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
  268. package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
  269. package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
  270. package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
  271. package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
  272. package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
  273. package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
  274. package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  275. package/src/templates/cloudflare-worker-path.mjs +0 -98
@@ -1,12 +1,15 @@
1
1
  import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { fs } from "@modern-js/utils";
4
+ import { getCloudflareWorkerRouteDataEntryName } from "../cloudflare-output-contract.mjs";
4
5
  import { readRouteSpec } from "./artifacts.mjs";
5
6
  import { ASSETS_BINDING, BFF_EFFECT_WORKER_DISPATCHER_EXPORT, BFF_EFFECT_WORKER_ENTRY, CLOUDFLARE_RUNTIME_TYPE, CLOUDFLARE_WORKER_BUNDLE_FORMAT, DEFAULT_SERVER_ONLY_PUBLIC_ASSET_EXCLUDES, EFFECT_BFF_CLOUDFLARE_IMPORT_GUIDANCE, LOADABLE_STATS_FILE, PUBLIC_ASSETS_DIRECTORY, ROUTE_MANIFEST_FILE, ROUTE_SPEC_FILE, ROUTE_SPEC_OUTPUT, SERVER_BUNDLE_DIRECTORY, WORKER_BUNDLE_DIRECTORY, WORKER_ENTRY } from "./constants.mjs";
6
7
  import { createI18nWorkerManifest } from "./i18n-worker.mjs";
8
+ import { readNativeRendererWorkerResources } from "./native-renderer.mjs";
9
+ import { readWorkerRendererBuild } from "./renderer-identity.mjs";
7
10
  import { createCloudflareWorkerSecurityPolicy } from "./security-policies.mjs";
8
11
  import { isRecord, normalizeRelativePath } from "./utils.mjs";
9
- import { createWorkerManifestServiceBindings, createWorkerServiceBindings } from "./wrangler-config.mjs";
12
+ import { createWorkerManifestServiceBindings, createWorkerServiceBindings, createWorkerVpcServiceBindings, getWorkerEffectBffPrefix } from "./wrangler-config.mjs";
10
13
  const createMissingEffectBffWorkerError = (outputDirectory, worker)=>new Error(`Cloudflare Effect API runtime is configured, but the BFF worker bundle is missing: ${node_path.join(outputDirectory, worker)}. ${EFFECT_BFF_CLOUDFLARE_IMPORT_GUIDANCE}`);
11
14
  const createEffectBffWorkerManifest = (modernConfig)=>{
12
15
  const bff = modernConfig.bff;
@@ -57,31 +60,59 @@ const createModuleFederationWorkerManifest = async (outputDirectory)=>{
57
60
  }
58
61
  ];
59
62
  });
60
- return name && exposes.length > 0 ? {
63
+ if (!name || 0 === exposes.length) return;
64
+ const routeManifestPath = node_path.join(outputDirectory, PUBLIC_ASSETS_DIRECTORY, ROUTE_MANIFEST_FILE);
65
+ const routeManifest = await fs.pathExists(routeManifestPath) ? await fs.readJson(routeManifestPath) : void 0;
66
+ const routeAssets = isRecord(routeManifest) && isRecord(routeManifest.routeAssets) ? Object.values(routeManifest.routeAssets).filter(isRecord) : [];
67
+ const routeCss = [
68
+ ...new Set(routeAssets.flatMap((routeAsset)=>[
69
+ routeAsset.referenceCssAssets,
70
+ routeAsset.assets
71
+ ].flatMap((value)=>Array.isArray(value) ? value : []).filter((asset)=>'string' == typeof asset && asset.endsWith('.css'))))
72
+ ];
73
+ return {
61
74
  name,
62
- exposes
63
- } : void 0;
75
+ exposes,
76
+ routeCss
77
+ };
64
78
  };
65
79
  const createWorkerManifest = async (outputDirectory, modernConfig, appContext, deliveryUnitStamp)=>{
66
80
  const routeSpec = await readRouteSpec(outputDirectory);
67
81
  const routes = await Promise.all(routeSpec.routes.map(async (route)=>{
68
82
  const worker = 'string' == typeof route.worker ? route.worker : void 0;
83
+ const routeDataWorker = route.isSSR && 'string' == typeof route.entryName ? `${WORKER_BUNDLE_DIRECTORY}/${getCloudflareWorkerRouteDataEntryName(route.entryName)}.js` : void 0;
84
+ const hasRouteDataWorker = routeDataWorker ? await fs.pathExists(node_path.join(outputDirectory, routeDataWorker)) : false;
69
85
  return {
70
86
  urlPath: route.urlPath,
71
87
  entryName: route.entryName,
72
88
  entryPath: route.entryPath,
73
89
  isSSR: Boolean(route.isSSR),
74
90
  worker,
75
- workerExists: worker ? await fs.pathExists(node_path.join(outputDirectory, worker)) : false
91
+ workerExists: worker ? await fs.pathExists(node_path.join(outputDirectory, worker)) : false,
92
+ ...hasRouteDataWorker ? {
93
+ routeDataWorker
94
+ } : {},
95
+ ...route.responseHeaders && 'object' == typeof route.responseHeaders ? {
96
+ responseHeaders: route.responseHeaders
97
+ } : {}
76
98
  };
77
99
  }));
78
- const bffPrefix = modernConfig.bff?.prefix;
79
- const primaryBffPrefix = Array.isArray(bffPrefix) ? bffPrefix[0] : bffPrefix;
100
+ const rendererBuild = await readWorkerRendererBuild(appContext.distDirectory, routeSpec.routes, deliveryUnitStamp);
101
+ const rendererIdentities = rendererBuild?.identities;
102
+ const nativeRenderer = await readNativeRendererWorkerResources(appContext.distDirectory, rendererBuild);
103
+ for (const route of routes){
104
+ const renderer = 'string' == typeof route.entryName && rendererIdentities && Object.hasOwn(rendererIdentities, route.entryName) ? rendererIdentities[route.entryName].renderer : void 0;
105
+ if (void 0 !== renderer && rendererBuild?.renderer.nativeDocuments && (nativeRenderer?.renderer !== renderer || !route.workerExists)) throw new Error(`Cloudflare worker deploy of the ${renderer} renderer requires its native worker build for entry ${route.entryName}. Set deploy.worker.ssr: true and rebuild with the Cloudflare deploy target.`);
106
+ }
80
107
  const isEffectApi = Boolean(modernConfig.bff) && modernConfig.bff?.runtimeFramework !== 'hono';
108
+ const effectBffPrefix = getWorkerEffectBffPrefix(modernConfig);
81
109
  const effectApiWorkerExists = await fs.pathExists(node_path.join(outputDirectory, BFF_EFFECT_WORKER_ENTRY));
82
- const serviceBindings = createWorkerManifestServiceBindings(createWorkerServiceBindings(modernConfig, void 0));
110
+ const typedServiceBindings = createWorkerServiceBindings(modernConfig, void 0);
111
+ const serviceBindings = createWorkerManifestServiceBindings(typedServiceBindings, createWorkerVpcServiceBindings(modernConfig, void 0, typedServiceBindings, new Set([
112
+ ASSETS_BINDING
113
+ ])));
83
114
  const moduleFederation = await createModuleFederationWorkerManifest(outputDirectory);
84
- if (isEffectApi && primaryBffPrefix && !effectApiWorkerExists) throw createMissingEffectBffWorkerError(outputDirectory, BFF_EFFECT_WORKER_ENTRY);
115
+ if (void 0 !== effectBffPrefix && !effectApiWorkerExists) throw createMissingEffectBffWorkerError(outputDirectory, BFF_EFFECT_WORKER_ENTRY);
85
116
  const effectBffManifest = isEffectApi ? createEffectBffWorkerManifest(modernConfig) : void 0;
86
117
  return {
87
118
  version: 1,
@@ -117,11 +148,18 @@ const createWorkerManifest = async (outputDirectory, modernConfig, appContext, d
117
148
  ...deliveryUnitStamp ? {
118
149
  deliveryUnit: deliveryUnitStamp
119
150
  } : {},
151
+ ...rendererBuild ? {
152
+ renderer: rendererBuild.renderer,
153
+ rendererIdentities
154
+ } : {},
155
+ ...nativeRenderer ? {
156
+ nativeRenderer
157
+ } : {},
120
158
  i18n: createI18nWorkerManifest(routeSpec, appContext),
121
- bff: isEffectApi && primaryBffPrefix && effectApiWorkerExists ? {
159
+ bff: void 0 !== effectBffPrefix && effectApiWorkerExists ? {
122
160
  dispatcherExport: BFF_EFFECT_WORKER_DISPATCHER_EXPORT,
123
161
  runtimeFramework: 'effect',
124
- prefix: primaryBffPrefix,
162
+ prefix: effectBffPrefix,
125
163
  worker: BFF_EFFECT_WORKER_ENTRY,
126
164
  effect: effectBffManifest
127
165
  } : void 0,
@@ -132,9 +170,12 @@ const createWorkerManifest = async (outputDirectory, modernConfig, appContext, d
132
170
  };
133
171
  const createWorkerModuleLoaders = (manifest)=>{
134
172
  const imports = new Map();
135
- for (const route of manifest.routeSpec.routes)if (route.worker && route.workerExists) {
136
- const importPath = `../${String(route.worker).replace(/^\/+/u, '')}`;
137
- imports.set(route.worker, `() => import(${JSON.stringify(importPath)})`);
173
+ for (const route of manifest.routeSpec.routes)for (const worker of [
174
+ route.workerExists ? route.worker : void 0,
175
+ route.routeDataWorker
176
+ ])if (worker) {
177
+ const importPath = `../${String(worker).replace(/^\/+/u, '')}`;
178
+ imports.set(worker, `() => import(${JSON.stringify(importPath)})`);
138
179
  }
139
180
  if (manifest.bff?.worker) {
140
181
  const importPath = `../${String(manifest.bff.worker).replace(/^\/+/u, '')}`;
@@ -0,0 +1,11 @@
1
+ import "node:module";
2
+ function isCloudflareWorkerRequestHandlerOptions(options) {
3
+ if (!('platform' in options) || !('executionContext' in options)) return false;
4
+ const platform = options.platform;
5
+ if (null === platform || 'object' != typeof platform || !('kind' in platform) || 'worker' !== platform.kind || !('bindings' in platform)) return false;
6
+ const bindings = platform.bindings;
7
+ if (void 0 !== bindings && (null === bindings || 'object' != typeof bindings || Array.isArray(bindings))) return false;
8
+ const context = options.executionContext;
9
+ return void 0 === context || null !== context && 'object' == typeof context && 'waitUntil' in context && 'function' == typeof context.waitUntil && 'passThroughOnException' in context && 'function' == typeof context.passThroughOnException;
10
+ }
11
+ export { isCloudflareWorkerRequestHandlerOptions };
@@ -2,12 +2,16 @@ import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { ASSETS_BINDING, COMPATIBILITY_DATE_PATTERN, DEFAULT_COMPATIBILITY_DATE, PUBLIC_ASSETS_DIRECTORY, REQUIRED_COMPATIBILITY_FLAGS, WORKER_ENTRY } from "./constants.mjs";
4
4
  import { isJsonRecord, normalizeRelativePath } from "./utils.mjs";
5
- const getCompatibilityDate = (modernConfig)=>{
6
- const configuredDate = modernConfig.deploy?.worker?.compatibilityDate?.trim();
7
- const compatibilityDate = configuredDate || DEFAULT_COMPATIBILITY_DATE;
8
- if (!COMPATIBILITY_DATE_PATTERN.test(compatibilityDate)) throw new Error(`deploy.worker.compatibilityDate must use YYYY-MM-DD, received ${JSON.stringify(compatibilityDate)}.`);
5
+ const assertSupportedCompatibilityDate = (compatibilityDate, label)=>{
6
+ if ('string' != typeof compatibilityDate) throw new Error(`${label} must be a YYYY-MM-DD string.`);
7
+ if (!COMPATIBILITY_DATE_PATTERN.test(compatibilityDate)) throw new Error(`${label} must use YYYY-MM-DD, received ${JSON.stringify(compatibilityDate)}.`);
8
+ if (compatibilityDate < DEFAULT_COMPATIBILITY_DATE) throw new Error(`${label} must be ${DEFAULT_COMPATIBILITY_DATE} or later, the date the Cloudflare worker Node.js built-in contract is verified against; received ${JSON.stringify(compatibilityDate)}.`);
9
9
  return compatibilityDate;
10
10
  };
11
+ const getCompatibilityDate = (modernConfig, wranglerCompatibilityDate)=>{
12
+ if (void 0 !== wranglerCompatibilityDate) return assertSupportedCompatibilityDate(wranglerCompatibilityDate, 'deploy.worker.wrangler.compatibility_date');
13
+ return assertSupportedCompatibilityDate(modernConfig.deploy?.worker?.compatibilityDate?.trim() || DEFAULT_COMPATIBILITY_DATE, 'deploy.worker.compatibilityDate');
14
+ };
11
15
  const getWorkerName = (appDirectory)=>{
12
16
  const basename = node_path.basename(appDirectory);
13
17
  return basename.replace(/[^a-zA-Z0-9-_]/g, '-') || 'modern-cloudflare-worker';
@@ -22,11 +26,11 @@ const getConfiguredWrangler = (modernConfig)=>{
22
26
  if (!isJsonRecord(wrangler)) throw new Error('deploy.worker.wrangler must be a JSON object.');
23
27
  return wrangler;
24
28
  };
25
- const createWranglerCompatibilityFlags = (configuredFlags)=>{
29
+ const createWranglerCompatibilityFlags = (configuredFlags, label = 'deploy.worker.wrangler.compatibility_flags')=>{
26
30
  if (void 0 === configuredFlags) return [
27
31
  ...REQUIRED_COMPATIBILITY_FLAGS
28
32
  ];
29
- if (!Array.isArray(configuredFlags) || configuredFlags.some((flag)=>'string' != typeof flag)) throw new Error('deploy.worker.wrangler.compatibility_flags must be an array of strings.');
33
+ if (!Array.isArray(configuredFlags) || configuredFlags.some((flag)=>'string' != typeof flag)) throw new Error(`${label} must be an array of strings.`);
30
34
  return [
31
35
  ...new Set([
32
36
  ...configuredFlags,
@@ -34,6 +38,26 @@ const createWranglerCompatibilityFlags = (configuredFlags)=>{
34
38
  ])
35
39
  ];
36
40
  };
41
+ const createWranglerEnvironments = (wranglerEnv)=>{
42
+ if (void 0 === wranglerEnv) return;
43
+ if (!isJsonRecord(wranglerEnv)) throw new Error('deploy.worker.wrangler.env must be an object.');
44
+ return Object.fromEntries(Object.entries(wranglerEnv).map(([name, environment])=>{
45
+ const label = `deploy.worker.wrangler.env.${name}`;
46
+ if (!isJsonRecord(environment)) throw new Error(`${label} must be an object.`);
47
+ return [
48
+ name,
49
+ {
50
+ ...environment,
51
+ ...void 0 === environment.compatibility_date ? {} : {
52
+ compatibility_date: assertSupportedCompatibilityDate(environment.compatibility_date, `${label}.compatibility_date`)
53
+ },
54
+ ...void 0 === environment.compatibility_flags ? {} : {
55
+ compatibility_flags: createWranglerCompatibilityFlags(environment.compatibility_flags, `${label}.compatibility_flags`)
56
+ }
57
+ }
58
+ ];
59
+ }));
60
+ };
37
61
  const createWranglerAssetsConfig = (configuredAssets)=>{
38
62
  if (void 0 !== configuredAssets && !isJsonRecord(configuredAssets)) throw new Error('deploy.worker.wrangler.assets must be an object.');
39
63
  return {
@@ -104,6 +128,129 @@ const createWorkerServiceBindings = (modernConfig, configuredWranglerServices)=>
104
128
  if (!Array.isArray(services)) throw new Error('deploy.worker.services must be an array.');
105
129
  return services.map(normalizeServiceBinding);
106
130
  };
131
+ const normalizeVpcService = (vpcService, index)=>{
132
+ const binding = assertNonEmptyString(vpcService.binding, `deploy.worker.vpcServices[${index}].binding`);
133
+ const serviceId = assertNonEmptyString(vpcService.serviceId, `deploy.worker.vpcServices[${index}].serviceId`);
134
+ const prefix = void 0 === vpcService.prefix ? void 0 : assertNonEmptyString(vpcService.prefix, `deploy.worker.vpcServices[${index}].prefix`);
135
+ return {
136
+ binding,
137
+ serviceId,
138
+ ...void 0 === prefix ? {} : {
139
+ prefix
140
+ }
141
+ };
142
+ };
143
+ const decodeRoutePrefix = (prefix)=>{
144
+ let decoded = prefix;
145
+ for(let round = 0; round < 4; round += 1){
146
+ let next;
147
+ try {
148
+ next = decodeURIComponent(decoded);
149
+ } catch {
150
+ break;
151
+ }
152
+ if (next === decoded) break;
153
+ decoded = next;
154
+ }
155
+ return decoded;
156
+ };
157
+ const normalizeRoutePrefix = (prefix)=>{
158
+ const decoded = decodeRoutePrefix(prefix);
159
+ return '/' === decoded ? decoded : decoded.replace(/\/+$/u, '');
160
+ };
161
+ const isCanonicalRoutePrefix = (prefix)=>prefix.startsWith('/') && !prefix.includes('\\') && decodeRoutePrefix(prefix) === prefix && new URL(prefix, 'https://route.invalid').pathname === prefix;
162
+ const collectWorkerBindingNames = (config)=>{
163
+ const names = new Set();
164
+ const visit = (value, inArray)=>{
165
+ if (Array.isArray(value)) {
166
+ for (const item of value)visit(item, true);
167
+ return;
168
+ }
169
+ if (!isJsonRecord(value)) return;
170
+ for (const field of inArray ? [
171
+ 'binding',
172
+ 'name'
173
+ ] : [
174
+ 'binding'
175
+ ]){
176
+ const name = value[field];
177
+ if ('string' == typeof name) names.add(name.trim());
178
+ }
179
+ for (const child of Object.values(value))visit(child, false);
180
+ };
181
+ for (const [key, value] of Object.entries(config))if ('env' !== key && 'services' !== key && 'vpc_services' !== key) {
182
+ if ('vars' === key && isJsonRecord(value)) {
183
+ for (const name of Object.keys(value))names.add(name);
184
+ continue;
185
+ }
186
+ visit(value, false);
187
+ }
188
+ return names;
189
+ };
190
+ const prefixesOverlap = (left, right)=>{
191
+ const [first, second] = [
192
+ normalizeRoutePrefix(left),
193
+ normalizeRoutePrefix(right)
194
+ ];
195
+ return '/' === first || '/' === second || first === second || first.startsWith(`${second}/`) || second.startsWith(`${first}/`);
196
+ };
197
+ const getWorkerEffectBffPrefix = (modernConfig)=>{
198
+ const bffPrefix = modernConfig.bff?.prefix;
199
+ const primaryBffPrefix = Array.isArray(bffPrefix) ? bffPrefix[0] : bffPrefix;
200
+ const isEffectApi = Boolean(modernConfig.bff) && modernConfig.bff?.runtimeFramework !== 'hono';
201
+ return isEffectApi && primaryBffPrefix ? primaryBffPrefix : void 0;
202
+ };
203
+ const effectiveServiceBindings = (serviceBindings)=>{
204
+ const bindings = Array.isArray(serviceBindings) ? serviceBindings : [];
205
+ return bindings.flatMap((service)=>isJsonRecord(service) && 'string' == typeof service.binding ? [
206
+ {
207
+ binding: service.binding.trim(),
208
+ prefix: 'string' == typeof service.prefix ? service.prefix : void 0
209
+ }
210
+ ] : []);
211
+ };
212
+ const createWorkerVpcServiceBindings = (modernConfig, configuredWranglerVpcServices, serviceBindings, workerBindingNames)=>{
213
+ const vpcServices = modernConfig.deploy?.worker?.vpcServices;
214
+ if (void 0 === vpcServices) return;
215
+ if (void 0 !== configuredWranglerVpcServices) throw new Error('Use deploy.worker.vpcServices or deploy.worker.wrangler.vpc_services, not both.');
216
+ if (!Array.isArray(vpcServices)) throw new Error('deploy.worker.vpcServices must be an array.');
217
+ const services = effectiveServiceBindings(serviceBindings);
218
+ const serviceBindingNames = new Set(services.map(({ binding })=>binding));
219
+ const effectBffPrefix = getWorkerEffectBffPrefix(modernConfig);
220
+ const routes = [
221
+ ...void 0 === effectBffPrefix ? [] : [
222
+ {
223
+ owner: 'the Effect BFF',
224
+ prefix: effectBffPrefix
225
+ }
226
+ ],
227
+ ...services.flatMap(({ binding, prefix })=>void 0 === prefix ? [] : [
228
+ {
229
+ owner: `binding "${binding}"`,
230
+ prefix
231
+ }
232
+ ])
233
+ ];
234
+ const vpcBindingNames = new Set();
235
+ return vpcServices.map((vpcService, index)=>{
236
+ const normalized = normalizeVpcService(vpcService, index);
237
+ if (serviceBindingNames.has(normalized.binding)) throw new Error(`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is already declared by deploy.worker.services.`);
238
+ if (workerBindingNames.has(normalized.binding)) throw new Error(`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is already a binding of this Worker.`);
239
+ if (vpcBindingNames.has(normalized.binding)) throw new Error(`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is declared more than once.`);
240
+ vpcBindingNames.add(normalized.binding);
241
+ if (void 0 !== normalized.prefix) {
242
+ const { prefix } = normalized;
243
+ if (!isCanonicalRoutePrefix(prefix)) throw new Error(`deploy.worker.vpcServices[${index}].prefix "${prefix}" must be a decoded URL path that starts with "/" (no query, fragment, "." or ".." segments).`);
244
+ const shadow = routes.find((route)=>prefixesOverlap(route.prefix, prefix));
245
+ if (void 0 !== shadow) throw new Error(`deploy.worker.vpcServices[${index}].prefix "${prefix}" overlaps the prefix "${shadow.prefix}" of ${shadow.owner}; the worker dispatcher would route one of them ambiguously.`);
246
+ routes.push({
247
+ owner: `binding "${normalized.binding}"`,
248
+ prefix
249
+ });
250
+ }
251
+ return normalized;
252
+ });
253
+ };
107
254
  const createWranglerServices = (serviceBindings)=>{
108
255
  if (!Array.isArray(serviceBindings)) return serviceBindings;
109
256
  if (!serviceBindings.every(isJsonRecord)) return serviceBindings;
@@ -112,8 +259,16 @@ const createWranglerServices = (serviceBindings)=>{
112
259
  return wranglerService;
113
260
  });
114
261
  };
115
- const createWorkerManifestServiceBindings = (serviceBindings)=>{
116
- if (!Array.isArray(serviceBindings)) return;
262
+ const createWorkerManifestServiceBindings = (serviceBindings, vpcServiceBindings)=>{
263
+ const vpcManifestBindings = (vpcServiceBindings ?? []).flatMap(({ binding, prefix, serviceId })=>void 0 === prefix ? [] : [
264
+ {
265
+ binding,
266
+ interface: 'fetch',
267
+ prefix,
268
+ vpcServiceId: serviceId
269
+ }
270
+ ]);
271
+ if (!Array.isArray(serviceBindings)) return vpcManifestBindings.length > 0 ? vpcManifestBindings : void 0;
117
272
  const bindings = serviceBindings;
118
273
  const manifestBindings = bindings.filter((service)=>isJsonRecord(service) && 'string' == typeof service.binding && 'string' == typeof service.service && ('string' == typeof service.prefix || Array.isArray(service.fragments) && service.fragments.length > 0)).map((service)=>({
119
274
  binding: service.binding,
@@ -126,21 +281,29 @@ const createWorkerManifestServiceBindings = (serviceBindings)=>{
126
281
  fragments: service.fragments
127
282
  }
128
283
  }));
129
- return manifestBindings.length > 0 ? manifestBindings : void 0;
284
+ const allBindings = [
285
+ ...manifestBindings,
286
+ ...vpcManifestBindings
287
+ ];
288
+ return allBindings.length > 0 ? allBindings : void 0;
130
289
  };
131
290
  const createWranglerConfig = (appDirectory, modernConfig)=>{
132
291
  const wrangler = getConfiguredWrangler(modernConfig);
292
+ const environments = createWranglerEnvironments(wrangler.env);
133
293
  const d1Databases = createWranglerD1Databases(modernConfig, wrangler.d1_databases);
134
294
  const serviceBindings = createWorkerServiceBindings(modernConfig, wrangler.services);
135
295
  const wranglerServices = createWranglerServices(serviceBindings);
136
- return {
296
+ const workerConfig = {
137
297
  $schema: 'node_modules/wrangler/config-schema.json',
138
298
  name: getConfiguredWorkerName(appDirectory, modernConfig),
139
- compatibility_date: getCompatibilityDate(modernConfig),
140
299
  ...wrangler,
300
+ compatibility_date: getCompatibilityDate(modernConfig, wrangler.compatibility_date),
141
301
  main: WORKER_ENTRY,
142
302
  compatibility_flags: createWranglerCompatibilityFlags(wrangler.compatibility_flags),
143
303
  assets: createWranglerAssetsConfig(wrangler.assets),
304
+ ...void 0 === environments ? {} : {
305
+ env: environments
306
+ },
144
307
  ...void 0 === d1Databases ? {} : {
145
308
  d1_databases: d1Databases
146
309
  },
@@ -148,5 +311,33 @@ const createWranglerConfig = (appDirectory, modernConfig)=>{
148
311
  services: wranglerServices
149
312
  }
150
313
  };
314
+ const vpcServiceBindings = createWorkerVpcServiceBindings(modernConfig, wrangler.vpc_services, serviceBindings, collectWorkerBindingNames(workerConfig));
315
+ if (void 0 === vpcServiceBindings) return workerConfig;
316
+ const vpcServicesConfig = vpcServiceBindings.map(({ binding, serviceId })=>({
317
+ binding,
318
+ service_id: serviceId
319
+ }));
320
+ return {
321
+ ...workerConfig,
322
+ ...void 0 === environments ? {} : {
323
+ env: Object.fromEntries(Object.entries(environments).map(([name, environment])=>{
324
+ if (void 0 !== environment.vpc_services) throw new Error(`Use deploy.worker.vpcServices or deploy.worker.wrangler.env.${name}.vpc_services, not both.`);
325
+ const environmentBindingNames = new Set([
326
+ ...collectWorkerBindingNames(environment),
327
+ ...effectiveServiceBindings(environment.services).map(({ binding })=>binding)
328
+ ]);
329
+ const collision = vpcServiceBindings.find(({ binding })=>environmentBindingNames.has(binding));
330
+ if (void 0 !== collision) throw new Error(`deploy.worker.vpcServices binding "${collision.binding}" is already a binding of deploy.worker.wrangler.env.${name}.`);
331
+ return [
332
+ name,
333
+ {
334
+ ...environment,
335
+ vpc_services: vpcServicesConfig
336
+ }
337
+ ];
338
+ }))
339
+ },
340
+ vpc_services: vpcServicesConfig
341
+ };
151
342
  };
152
- export { createWorkerManifestServiceBindings, createWorkerServiceBindings, createWranglerConfig };
343
+ export { createWorkerManifestServiceBindings, createWorkerServiceBindings, createWorkerVpcServiceBindings, createWranglerConfig, getWorkerEffectBffPrefix };