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

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 +30 -165
  6. package/dist/cjs/build-config/internal-effect-discovery.js +231 -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 +180 -17
  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 +9 -6
  46. package/dist/cjs/renderer-build-identity.js +144 -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 +547 -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 +31 -163
  58. package/dist/esm/build-config/internal-effect-discovery.mjs +187 -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 +175 -18
  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 +9 -6
  98. package/dist/esm/renderer-build-identity.mjs +92 -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 +547 -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 +31 -163
  110. package/dist/esm-node/build-config/internal-effect-discovery.mjs +188 -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 +175 -18
  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 +9 -6
  150. package/dist/esm-node/renderer-build-identity.mjs +93 -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 +547 -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 +4 -10
  163. package/dist/types/build-config/internal-effect-discovery.d.ts +6 -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 +20 -4
  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 +102 -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 +28 -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 +13 -2
  199. package/dist/types/renderer-build-identity.d.ts +41 -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 +69 -293
  208. package/src/build-config/internal-effect-discovery.ts +458 -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 +115 -13
  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 +105 -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 +284 -27
  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 +30 -4
  248. package/src/renderer-build-identity.ts +208 -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 +547 -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
@@ -0,0 +1,458 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { lstatSync, readFileSync, realpathSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import { dirname, join, resolve } from 'node:path';
5
+ import { fileURLToPath, type URL } from 'node:url';
6
+
7
+ const EFFECT_TSGO_PACKAGE = '@effect/tsgo';
8
+ const EFFECT_TSGO_BIN = 'effect-tsgo';
9
+ const NATIVE_TYPESCRIPT_PACKAGES = ['typescript', '@typescript/native'];
10
+ // @effect/tsgo@0.59.0 exports no tsrs capability API. Keep this exact contract
11
+ // aligned with its CLI's tsrsReplacementTargets / resolveTsrs, not tsrs's list.
12
+ const EFFECT_TSRS_PROVIDER_VERSION = '0.59.0';
13
+ const EFFECT_TSRS_TARGETS = new Set([
14
+ '@tsrs/darwin-arm64',
15
+ '@tsrs/linux-x64-gnu',
16
+ '@tsrs/linux-arm64-gnu',
17
+ ]);
18
+ type PackageJson = {
19
+ name?: string;
20
+ bin?: Record<string, string> | string;
21
+ version?: string;
22
+ gitHead?: string;
23
+ tsrs?: { typescriptVersion?: string; typescriptCommit?: string };
24
+ optionalDependencies?: Record<string, string>;
25
+ };
26
+ type TsrsPackageJson = PackageJson & {
27
+ version: string;
28
+ tsrs: { typescriptVersion: string; typescriptCommit: string };
29
+ };
30
+ const failureStages = new WeakMap<object, string>();
31
+ const reportedUnsupportedTsrsTargets = new Set<string>();
32
+ export function effectCompilerDiscoveryFailureStage(
33
+ error: unknown,
34
+ ): string | undefined {
35
+ return error && typeof error === 'object'
36
+ ? failureStages.get(error)
37
+ : undefined;
38
+ }
39
+
40
+ function resolveEffectTsgoPackage(from: string | URL): {
41
+ packageJsonPath: string;
42
+ packageJson: PackageJson;
43
+ cliPath: string;
44
+ } {
45
+ const projectRequire = createRequire(from);
46
+ const packageJsonPath = projectRequire.resolve(
47
+ `${EFFECT_TSGO_PACKAGE}/package.json`,
48
+ );
49
+ const packageJson = JSON.parse(
50
+ readFileSync(packageJsonPath, 'utf-8'),
51
+ ) as PackageJson;
52
+ const bin =
53
+ typeof packageJson.bin === 'string'
54
+ ? packageJson.bin
55
+ : packageJson.bin?.[EFFECT_TSGO_BIN];
56
+
57
+ if (!bin) {
58
+ throw new Error(
59
+ `Resolved ${EFFECT_TSGO_PACKAGE} package has no ${EFFECT_TSGO_BIN} bin: ${packageJsonPath}`,
60
+ );
61
+ }
62
+
63
+ const cliPath = realpathSync(resolve(dirname(packageJsonPath), bin));
64
+ if (!lstatSync(cliPath).isFile())
65
+ throw new Error(`Effect TS-Go CLI is not a regular file: ${cliPath}`);
66
+ return { packageJsonPath, packageJson, cliPath };
67
+ }
68
+
69
+ function isAbsentPackage(
70
+ projectRequire: NodeJS.Require,
71
+ from: string | URL,
72
+ packageName: string,
73
+ error: unknown,
74
+ ): boolean {
75
+ const filename =
76
+ typeof from === 'string' && !from.startsWith('file:')
77
+ ? from
78
+ : fileURLToPath(from);
79
+ if (
80
+ !(error instanceof Error) ||
81
+ !('code' in error) ||
82
+ error.code !== 'MODULE_NOT_FOUND' ||
83
+ ('path' in error && error.path !== undefined) ||
84
+ error.message.split('\n')[0] !==
85
+ `Cannot find module '${packageName}/package.json'` ||
86
+ !('requireStack' in error) ||
87
+ !Array.isArray(error.requireStack) ||
88
+ error.requireStack[0] !== filename
89
+ ) {
90
+ return false;
91
+ }
92
+ for (const searchDirectory of projectRequire.resolve.paths(packageName) ??
93
+ []) {
94
+ try {
95
+ lstatSync(join(searchDirectory, packageName));
96
+ return false;
97
+ } catch (presenceError) {
98
+ if (
99
+ !(presenceError instanceof Error) ||
100
+ !('code' in presenceError) ||
101
+ !['ENOENT', 'ENOTDIR'].includes(String(presenceError.code))
102
+ ) {
103
+ throw presenceError;
104
+ }
105
+ }
106
+ }
107
+ return true;
108
+ }
109
+
110
+ function resolveNativeTypeScriptPackage(from: string | URL): string {
111
+ const projectRequire = createRequire(from);
112
+ for (const packageName of NATIVE_TYPESCRIPT_PACKAGES) {
113
+ let packageJsonPath: string;
114
+ try {
115
+ packageJsonPath = projectRequire.resolve(`${packageName}/package.json`);
116
+ } catch (error) {
117
+ if (isAbsentPackage(projectRequire, from, packageName, error)) {
118
+ continue;
119
+ }
120
+ throw error;
121
+ }
122
+ const packageJson = JSON.parse(
123
+ readFileSync(packageJsonPath, 'utf-8'),
124
+ ) as PackageJson;
125
+ const major = packageJson.version?.match(
126
+ /^(\d+)\.\d+\.\d+(?:[-+].*)?$/u,
127
+ )?.[1];
128
+ if (!major) {
129
+ throw new Error(
130
+ `Resolved TypeScript package has no valid version: ${packageJsonPath}`,
131
+ );
132
+ }
133
+ if (Number(major) >= 7) {
134
+ return packageJsonPath;
135
+ }
136
+ }
137
+ throw new Error(
138
+ `No native TypeScript backend is installed for ${String(from)}. Install typescript >=7 or @typescript/native.`,
139
+ );
140
+ }
141
+
142
+ function resolveNativeTypeScriptManifest(from: string | URL): string {
143
+ const packageJsonPath = resolveNativeTypeScriptPackage(from);
144
+ const directory = dirname(packageJsonPath);
145
+ // Keep the selected backend bound to its own installation, including the
146
+ // canonical-package precedence used by the provider.
147
+ const discoveryPackage = resolveNativeTypeScriptPackage(
148
+ join(directory, '__ultramodern_effect_backend__.cjs'),
149
+ );
150
+ if (realpathSync(discoveryPackage) !== realpathSync(packageJsonPath)) {
151
+ throw new Error(
152
+ `Effect discovery would select a different native TypeScript installation from ${directory}: ${discoveryPackage}`,
153
+ );
154
+ }
155
+ return packageJsonPath;
156
+ }
157
+
158
+ function readCompilerArtifact(filename: string): string {
159
+ const canonicalPath = realpathSync(filename);
160
+ const stats = lstatSync(canonicalPath);
161
+ if (!stats.isFile())
162
+ throw new Error(`Compiler artifact is not a regular file: ${filename}`);
163
+ if (stats.size === 0)
164
+ throw new Error(`Compiler artifact is empty: ${filename}`);
165
+ return canonicalPath;
166
+ }
167
+
168
+ function resolveTsrsManifest(from: string | URL): string | undefined {
169
+ const projectRequire = createRequire(from);
170
+ try {
171
+ return projectRequire.resolve('tsrs/package.json');
172
+ } catch (error) {
173
+ if (isAbsentPackage(projectRequire, from, 'tsrs', error)) return undefined;
174
+ throw error;
175
+ }
176
+ }
177
+
178
+ function compilerVersion(compiler: string): string {
179
+ return execFileSync(compiler, ['--version'], {
180
+ encoding: 'utf8',
181
+ env: {
182
+ ...process.env,
183
+ TSRS_CHECKER_ASSIGNMENT: process.env.TSRS_CHECKER_ASSIGNMENT || 'go',
184
+ },
185
+ timeout: 10_000,
186
+ maxBuffer: 1024 * 1024,
187
+ }).trim();
188
+ }
189
+
190
+ function tsrsPlatform(manifestPath: string): {
191
+ manifest: TsrsPackageJson;
192
+ nativeName: string;
193
+ supported: boolean;
194
+ } {
195
+ const manifest = JSON.parse(
196
+ readFileSync(manifestPath, 'utf8'),
197
+ ) as PackageJson;
198
+ const { getPlatformPackageName } = createRequire(manifestPath)(
199
+ join(dirname(manifestPath), 'lib/platform.js'),
200
+ ) as { getPlatformPackageName: () => string };
201
+ const nativeName = getPlatformPackageName();
202
+ const embedded = manifest.tsrs;
203
+ if (
204
+ typeof nativeName !== 'string' ||
205
+ !nativeName ||
206
+ !manifest.optionalDependencies ||
207
+ typeof manifest.optionalDependencies !== 'object' ||
208
+ Array.isArray(manifest.optionalDependencies) ||
209
+ Object.keys(manifest.optionalDependencies).length === 0
210
+ ) {
211
+ throw new Error(`Invalid native tsrs capability metadata: ${manifestPath}`);
212
+ }
213
+ if (
214
+ typeof manifest.name !== 'string' ||
215
+ !manifest.name ||
216
+ typeof manifest.version !== 'string' ||
217
+ !/^\d+\.\d+\.\d+-ts[\w.-]+$/u.test(manifest.version) ||
218
+ typeof embedded?.typescriptVersion !== 'string' ||
219
+ !/^7\.\d+\.\d+(?:[-+][\w.-]+)?$/u.test(embedded.typescriptVersion) ||
220
+ !manifest.version.endsWith(`-ts${embedded.typescriptVersion}`) ||
221
+ typeof embedded.typescriptCommit !== 'string' ||
222
+ !/^[a-f\d]{40}$/u.test(embedded.typescriptCommit)
223
+ ) {
224
+ throw new Error(`Invalid native tsrs metadata: ${manifestPath}`);
225
+ }
226
+ const supported = Object.hasOwn(manifest.optionalDependencies, nativeName);
227
+ if (
228
+ supported &&
229
+ manifest.optionalDependencies[nativeName] !== manifest.version
230
+ ) {
231
+ throw new Error(
232
+ `Native tsrs target version does not match its selected package: ${manifestPath}`,
233
+ );
234
+ }
235
+ return { manifest: manifest as TsrsPackageJson, nativeName, supported };
236
+ }
237
+
238
+ function resolveTsrsCompiler(
239
+ manifestPath: string,
240
+ effect: ReturnType<typeof resolveEffectTsgoPackage>,
241
+ configuredCompiler?: string,
242
+ configuredVersion?: string,
243
+ ): string {
244
+ const { manifest } = tsrsPlatform(manifestPath);
245
+ const embedded = manifest.tsrs;
246
+ const effectName = `@effect/tsgo-${process.platform}-${process.arch}`;
247
+ const effectManifest = createRequire(effect.cliPath).resolve(
248
+ `${effectName}/package.json`,
249
+ );
250
+ const platform = JSON.parse(
251
+ readFileSync(effectManifest, 'utf8'),
252
+ ) as PackageJson;
253
+ const metadataPath = join(dirname(effectManifest), 'lib/upstream.json');
254
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf8')) as {
255
+ schemaVersion?: number;
256
+ components?: {
257
+ tsrs?: Record<
258
+ string,
259
+ {
260
+ gitHead?: string;
261
+ typescript?: { version?: string; gitHead?: string };
262
+ }
263
+ >;
264
+ };
265
+ };
266
+ const component = metadata.components?.tsrs?.[manifest.version];
267
+ if (
268
+ platform.name !== effectName ||
269
+ platform.version !== effect.packageJson.version ||
270
+ metadata.schemaVersion !== 5 ||
271
+ !/^[a-f\d]{40}$/u.test(component?.gitHead ?? '') ||
272
+ component?.typescript?.version !== embedded.typescriptVersion ||
273
+ component.typescript.gitHead !== embedded.typescriptCommit
274
+ ) {
275
+ throw new Error(
276
+ `Effect replacement metadata does not match tsrs: ${metadataPath}`,
277
+ );
278
+ }
279
+ // This is the same metadata-bound artifact used by `effect-tsgo tsrs`.
280
+ // The installed @tsrs binary need not be patched or written to.
281
+ const compiler = readCompilerArtifact(
282
+ configuredCompiler ??
283
+ join(
284
+ dirname(effectManifest),
285
+ 'artifacts/tsrs',
286
+ manifest.version,
287
+ process.platform === 'win32' ? 'tsrs.exe' : 'tsrs',
288
+ ),
289
+ );
290
+ const version = configuredVersion ?? compilerVersion(compiler);
291
+ // Check the selected executable itself, including TSRS_BINARY and explicit
292
+ // EFFECT_TSGO_BIN paths. A package name alone cannot prove it was patched.
293
+ const stamp =
294
+ /\+effect-tsgo\.([\d.]+)\s+\(tsrs ([^,]+), microsoft\/TypeScript@([a-f\d]+)\)$/u.exec(
295
+ version,
296
+ );
297
+ if (
298
+ !stamp ||
299
+ stamp[1] !== effect.packageJson.version ||
300
+ stamp[2] !== manifest.version ||
301
+ stamp[3].length < 12 ||
302
+ !embedded.typescriptCommit.startsWith(stamp[3])
303
+ ) {
304
+ throw new Error(
305
+ `Effect-enabled tsrs matching ${manifest.version} and @effect/tsgo@${effect.packageJson.version} is required: ${compiler}. Install matching packages or select a matching Effect-enabled candidate with EFFECT_TSGO_BIN.`,
306
+ );
307
+ }
308
+ return compiler;
309
+ }
310
+
311
+ /** Explicit native binaries must still report Effect diagnostics support. */
312
+ export function validateConfiguredEffectCompiler(
313
+ compiler: string,
314
+ from: string | URL,
315
+ ): void {
316
+ const version = compilerVersion(compiler);
317
+ if (
318
+ !/^Version \d+\.\d+\.\d+[\w.-]*\+effect-tsgo\.\d+\.\d+\.\d+(?:\s|$)/u.test(
319
+ version,
320
+ )
321
+ ) {
322
+ throw new Error(
323
+ `EFFECT_TSGO_BIN must select an Effect-enabled native compiler: ${compiler}`,
324
+ );
325
+ }
326
+ if (version.includes('(tsrs ')) {
327
+ const manifest = resolveTsrsManifest(from);
328
+ if (!manifest)
329
+ throw new Error(
330
+ `Cannot validate tsrs without its installed package metadata for ${String(from)}`,
331
+ );
332
+ resolveTsrsCompiler(
333
+ manifest,
334
+ resolveEffectTsgoPackage(from),
335
+ compiler,
336
+ version,
337
+ );
338
+ }
339
+ }
340
+
341
+ /** Selects the exact native replacement without invoking the provider CLI. */
342
+ export function resolveInstalledEffectCompiler(from: string | URL): string {
343
+ let stage = 'Package CLI resolution';
344
+ try {
345
+ const effect = resolveEffectTsgoPackage(from);
346
+ stage = 'Native tsrs package resolution';
347
+ const tsrsManifest = resolveTsrsManifest(from);
348
+ const tsrsTarget = tsrsManifest ? tsrsPlatform(tsrsManifest) : undefined;
349
+ if (
350
+ tsrsTarget &&
351
+ effect.packageJson.version !== EFFECT_TSRS_PROVIDER_VERSION
352
+ ) {
353
+ throw new Error(
354
+ `Unreviewed Effect tsrs capability contract: ${effect.packageJson.version}`,
355
+ );
356
+ }
357
+ const configuredTsrsCompiler = process.env.TSRS_BINARY || undefined;
358
+ if (
359
+ tsrsManifest &&
360
+ tsrsTarget?.supported &&
361
+ (configuredTsrsCompiler || EFFECT_TSRS_TARGETS.has(tsrsTarget.nativeName))
362
+ ) {
363
+ stage = 'Native tsrs validation';
364
+ // TSRS_BINARY remains an explicit candidate selection. Automatic
365
+ // discovery uses the Effect provider's bundled native replacement.
366
+ return resolveTsrsCompiler(tsrsManifest, effect, configuredTsrsCompiler);
367
+ }
368
+ if (
369
+ tsrsTarget &&
370
+ !reportedUnsupportedTsrsTargets.has(tsrsTarget.nativeName)
371
+ ) {
372
+ reportedUnsupportedTsrsTargets.add(tsrsTarget.nativeName);
373
+ console.warn(
374
+ `[UltraModern] ${tsrsTarget.supported ? `@effect/tsgo@${effect.packageJson.version} does not provide a tsrs replacement for ${tsrsTarget.nativeName}` : `tsrs does not declare ${tsrsTarget.nativeName}`}; selecting the Effect-enabled TypeScript-Go compiler.`,
375
+ );
376
+ }
377
+ stage = 'Native TypeScript package resolution';
378
+ const typeScriptManifest = resolveNativeTypeScriptManifest(from);
379
+ const typeScript = JSON.parse(
380
+ readFileSync(typeScriptManifest, 'utf8'),
381
+ ) as PackageJson;
382
+ const nativeName = `@typescript/typescript-${process.platform}-${process.arch}`;
383
+ const nativeManifest = createRequire(typeScriptManifest).resolve(
384
+ `${nativeName}/package.json`,
385
+ );
386
+ const native = JSON.parse(
387
+ readFileSync(nativeManifest, 'utf8'),
388
+ ) as PackageJson;
389
+ if (
390
+ native.name !== nativeName ||
391
+ native.version !== typeScript.version ||
392
+ typeof native.version !== 'string' ||
393
+ !/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/u.test(native.version) ||
394
+ typeof native.gitHead !== 'string' ||
395
+ !/^[a-f\d]{40}$/u.test(native.gitHead) ||
396
+ native.gitHead !== typeScript.gitHead
397
+ ) {
398
+ throw new Error(
399
+ `Native TypeScript platform does not match its selected package: ${nativeManifest}`,
400
+ );
401
+ }
402
+ const binaryName = process.platform === 'win32' ? 'tsc.exe' : 'tsc';
403
+ readCompilerArtifact(join(dirname(nativeManifest), 'lib', binaryName));
404
+ stage = 'Compiler backend lookup';
405
+ const effectName = `@effect/tsgo-${process.platform}-${process.arch}`;
406
+ const effectManifest = createRequire(effect.cliPath).resolve(
407
+ `${effectName}/package.json`,
408
+ );
409
+ const platform = JSON.parse(
410
+ readFileSync(effectManifest, 'utf8'),
411
+ ) as PackageJson;
412
+ if (
413
+ platform.name !== effectName ||
414
+ typeof effect.packageJson.version !== 'string' ||
415
+ platform.version !== effect.packageJson.version
416
+ ) {
417
+ throw new Error(
418
+ `Effect platform does not match its selected provider: ${effectManifest}`,
419
+ );
420
+ }
421
+ const metadataPath = join(dirname(effectManifest), 'lib', 'upstream.json');
422
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf8')) as {
423
+ schemaVersion?: number;
424
+ tags?: { typescript?: { latest?: string } };
425
+ components?: {
426
+ typescript?: Record<string, { gitHead?: string; provider?: string }>;
427
+ };
428
+ };
429
+ const component = metadata.components?.typescript?.[native.version];
430
+ const latestTypeScript = metadata.tags?.typescript?.latest;
431
+ if (
432
+ metadata.schemaVersion !== 5 ||
433
+ typeof latestTypeScript !== 'string' ||
434
+ component?.provider !== 'typescript-go' ||
435
+ component.gitHead !== native.gitHead
436
+ ) {
437
+ throw new Error(
438
+ `Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`,
439
+ );
440
+ }
441
+ // Same layout rule as @effect/tsgo's getExePath: the latest TypeScript
442
+ // replacement ships in lib/, every other version under artifacts/.
443
+ const compilerDirectory =
444
+ native.version === latestTypeScript
445
+ ? join(dirname(effectManifest), 'lib')
446
+ : join(
447
+ dirname(effectManifest),
448
+ 'artifacts',
449
+ 'typescript',
450
+ native.version,
451
+ );
452
+ return readCompilerArtifact(join(compilerDirectory, binaryName));
453
+ } catch (error) {
454
+ if (error && typeof error === 'object' && !failureStages.has(error))
455
+ failureStages.set(error, stage);
456
+ throw error;
457
+ }
458
+ }
@@ -2,5 +2,4 @@ export type { ResolveEffectTsgoCompilerOptions } from './build-environment';
2
2
  export {
3
3
  getBuildConfigEnvironment,
4
4
  resolveEffectTsgoCompiler,
5
- withBuildConfigEnvironment,
6
5
  } from './build-environment';
@@ -0,0 +1,33 @@
1
+ import {
2
+ type BrowserManifestAddressOptions,
3
+ resolveBrowserManifestAddress,
4
+ } from '@modern-js/surface-resolution';
5
+ import { resolveDeployTarget } from '../deploy-output/target';
6
+ import { getBuildConfigEnvironment } from './build-environment';
7
+
8
+ /** Adapt build environment leases and MF's name@URL syntax to discovery policy. */
9
+ export function createRemoteManifestUrl(
10
+ options: BrowserManifestAddressOptions,
11
+ ): string {
12
+ const env: Record<string, string | undefined> = {
13
+ ...Object.fromEntries(
14
+ [
15
+ options.manifestEnv,
16
+ options.publicUrlEnv,
17
+ 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
18
+ ].map(name => [name, getBuildConfigEnvironment(name)]),
19
+ ),
20
+ MODERNJS_DEPLOY: resolveDeployTarget().target,
21
+ };
22
+ const address = resolveBrowserManifestAddress(
23
+ env,
24
+ options,
25
+ getBuildConfigEnvironment('NODE_ENV') ?? 'production',
26
+ );
27
+ if (!address.ok)
28
+ throw new Error(`Remote ${options.mfName}: ${address.reason}`);
29
+ return (
30
+ env[options.manifestEnv]?.trim() ||
31
+ `${options.mfName}@${address.manifestUrl}`
32
+ );
33
+ }
@@ -1,9 +1,11 @@
1
1
  import path from 'node:path';
2
2
  import { fs as fse } from '@modern-js/utils';
3
- import type {
4
- CloudflareWorkerArtifactConfig,
5
- CloudflareWorkerPublicAssetConfig,
6
- } from '../config';
3
+ import type { CloudflareWorkerArtifactConfig } from '../config';
4
+ import {
5
+ CLOUDFLARE_PUBLIC_ASSET_SCOPE,
6
+ normalizeDeclaredPublicAssets,
7
+ stageDeclaredPublicAssets,
8
+ } from '../deploy-output/public-assets';
7
9
  import {
8
10
  RESERVED_ARTIFACT_DESTINATION_DIRECTORIES,
9
11
  RESERVED_ARTIFACT_DESTINATION_FILES,
@@ -54,34 +56,12 @@ export const getCloudflareArtifacts = (modernConfig: CloudflareModernConfig) =>
54
56
  normalizeCloudflareArtifact,
55
57
  );
56
58
 
57
- const normalizeCloudflarePublicAsset = (
58
- asset: CloudflareWorkerPublicAssetConfig,
59
- index: number,
60
- ) => {
61
- const from = normalizeRelativePath(
62
- asset.from,
63
- `deploy.worker.publicAssets[${index}].from`,
64
- 'app root',
65
- );
66
- const to = normalizeRelativePath(
67
- asset.to,
68
- `deploy.worker.publicAssets[${index}].to`,
69
- 'Cloudflare public output',
70
- { allowRoot: true },
71
- );
72
-
73
- return {
74
- from,
75
- to,
76
- index,
77
- };
78
- };
79
-
80
59
  export const getCloudflarePublicAssets = (
81
60
  modernConfig: CloudflareModernConfig,
82
61
  ) =>
83
- (modernConfig.deploy?.worker?.publicAssets ?? []).map(
84
- normalizeCloudflarePublicAsset,
62
+ normalizeDeclaredPublicAssets(
63
+ modernConfig.deploy?.worker?.publicAssets,
64
+ CLOUDFLARE_PUBLIC_ASSET_SCOPE,
85
65
  );
86
66
 
87
67
  export const copyCloudflareArtifacts = async (
@@ -102,23 +82,22 @@ export const copyCloudflareArtifacts = async (
102
82
  }
103
83
  };
104
84
 
85
+ /**
86
+ * Stage `deploy.worker.publicAssets` into Worker Static Assets.
87
+ *
88
+ * @returns the staged files relative to the Cloudflare output root.
89
+ */
105
90
  export const copyCloudflarePublicAssets = async (
106
91
  appDirectory: string,
107
- publicDirectory: string,
92
+ outputDirectory: string,
108
93
  publicAssets: ReturnType<typeof getCloudflarePublicAssets>,
109
- ) => {
110
- for (const asset of publicAssets) {
111
- const sourcePath = path.join(appDirectory, asset.from);
112
-
113
- if (!(await fse.pathExists(sourcePath))) {
114
- throw new Error(
115
- `deploy.worker.publicAssets[${asset.index}].from does not exist: ${asset.from}`,
116
- );
117
- }
118
-
119
- await fse.copy(sourcePath, path.join(publicDirectory, asset.to));
120
- }
121
- };
94
+ ) =>
95
+ stageDeclaredPublicAssets({
96
+ appDirectory,
97
+ outputDirectory,
98
+ assets: publicAssets,
99
+ scope: CLOUDFLARE_PUBLIC_ASSET_SCOPE,
100
+ });
122
101
 
123
102
  export const copyCloudflareD1Migrations = async (
124
103
  appDirectory: string,