@bleedingdev/modern-js-app-tools-extensions 3.9.3-ultramodern.1 → 3.9.3-ultramodern.11

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 (38) hide show
  1. package/dist/cjs/build-config/build-environment.js +7 -5
  2. package/dist/cjs/build-config/internal-effect-discovery.js +94 -6
  3. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +24 -3
  4. package/dist/cjs/native-type-checker.js +66 -20
  5. package/dist/cjs/release-identity.js +1 -1
  6. package/dist/cjs/renderer-build-identity.js +13 -3
  7. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
  8. package/dist/esm/build-config/build-environment.mjs +7 -5
  9. package/dist/esm/build-config/internal-effect-discovery.mjs +90 -5
  10. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +24 -3
  11. package/dist/esm/native-type-checker.mjs +68 -22
  12. package/dist/esm/release-identity.mjs +1 -1
  13. package/dist/esm/renderer-build-identity.mjs +13 -3
  14. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
  15. package/dist/esm-node/build-config/build-environment.mjs +7 -5
  16. package/dist/esm-node/build-config/internal-effect-discovery.mjs +90 -5
  17. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +24 -3
  18. package/dist/esm-node/native-type-checker.mjs +68 -22
  19. package/dist/esm-node/release-identity.mjs +1 -1
  20. package/dist/esm-node/renderer-build-identity.mjs +13 -3
  21. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
  22. package/dist/types/build-config/build-environment.d.ts +3 -1
  23. package/dist/types/build-config/internal-effect-discovery.d.ts +3 -1
  24. package/dist/types/cloudflare/worker-manifest.d.ts +3 -2
  25. package/dist/types/config.d.ts +4 -0
  26. package/dist/types/native-type-checker.d.ts +4 -2
  27. package/dist/types/release-identity.d.ts +10 -0
  28. package/dist/types/renderer-build-identity.d.ts +12 -1
  29. package/package.json +27 -27
  30. package/src/build-config/build-environment.ts +11 -9
  31. package/src/build-config/internal-effect-discovery.ts +238 -19
  32. package/src/cloudflare/worker-manifest.ts +7 -3
  33. package/src/cloudflare-output-verifier/mutation-policy.ts +41 -3
  34. package/src/config.ts +4 -0
  35. package/src/native-type-checker.ts +87 -43
  36. package/src/release-identity.ts +11 -2
  37. package/src/renderer-build-identity.ts +51 -11
  38. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
@@ -42,8 +42,8 @@ const owningManifest = (0, external_node_module_namespaceObject.findPackageJSON)
42
42
  if (!owningManifest) throw new Error('Cannot find owning build-config package manifest');
43
43
  const owningName = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(owningManifest, 'utf8')).name;
44
44
  if ('string' != typeof owningName || 0 === owningName.length) throw new Error(`Invalid owning build-config package name: ${owningManifest}`);
45
- const { effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler } = (0, external_node_module_namespaceObject.createRequire)(owningModuleUrl)(`${owningName}/internal-effect-discovery`);
46
- const EFFECT_TSGO_RESOLUTION_ERROR = 'Unable to resolve the Effect TS-Go compiler. Install "@effect/tsgo" and a native TypeScript backend for this build config, or set EFFECT_TSGO_BIN.';
45
+ const { effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler, validateConfiguredEffectCompiler } = (0, external_node_module_namespaceObject.createRequire)(owningModuleUrl)(`${owningName}/internal-effect-discovery`);
46
+ const EFFECT_TSGO_RESOLUTION_ERROR = 'Unable to resolve the Effect TS-Go compiler. Install "@effect/tsgo" and a native TypeScript backend for this build config, or set EFFECT_TSGO_BIN. Bundled tsrs requires matching installed tsrs metadata.';
47
47
  const executableEffectTsgoCompilers = new Map();
48
48
  function effectTsgoResolutionError(cause, stage, from) {
49
49
  const detail = cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause);
@@ -52,10 +52,10 @@ function effectTsgoResolutionError(cause, stage, from) {
52
52
  });
53
53
  }
54
54
  function resolveExecutableEffectTsgoCompiler(compilerPath) {
55
- if ('win32' === process.platform) return compilerPath;
56
55
  const sourcePath = (0, external_node_fs_namespaceObject.realpathSync)(compilerPath);
57
56
  const source = (0, external_node_fs_namespaceObject.lstatSync)(sourcePath);
58
- if (!source.isFile()) throw new Error(`Effect TS-Go compiler path is not a regular file: ${sourcePath}`);
57
+ if (!source.isFile() || 0 === source.size) throw new Error(`Effect TS-Go compiler path is not a nonempty regular file: ${sourcePath}`);
58
+ if ('win32' === process.platform) return compilerPath;
59
59
  try {
60
60
  (0, external_node_fs_namespaceObject.accessSync)(sourcePath, external_node_fs_namespaceObject.constants.X_OK);
61
61
  return compilerPath;
@@ -105,7 +105,9 @@ function getBuildConfigEnvironment(name) {
105
105
  function resolveEffectTsgoCompiler(options) {
106
106
  const configuredCompiler = getBuildConfigEnvironment('EFFECT_TSGO_BIN')?.trim();
107
107
  if (configuredCompiler) try {
108
- return resolveExecutableEffectTsgoCompiler(configuredCompiler);
108
+ const compiler = resolveExecutableEffectTsgoCompiler(configuredCompiler);
109
+ validateConfiguredEffectCompiler(compiler, options.from);
110
+ return compiler;
109
111
  } catch (cause) {
110
112
  throw effectTsgoResolutionError(cause, 'Configured compiler validation', options.from);
111
113
  }
@@ -29,8 +29,10 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  effectCompilerDiscoveryFailureStage: ()=>effectCompilerDiscoveryFailureStage,
32
- resolveInstalledEffectCompiler: ()=>resolveInstalledEffectCompiler
32
+ resolveInstalledEffectCompiler: ()=>resolveInstalledEffectCompiler,
33
+ validateConfiguredEffectCompiler: ()=>validateConfiguredEffectCompiler
33
34
  });
35
+ const external_node_child_process_namespaceObject = require("node:child_process");
34
36
  const external_node_fs_namespaceObject = require("node:fs");
35
37
  const external_node_module_namespaceObject = require("node:module");
36
38
  const external_node_path_namespaceObject = require("node:path");
@@ -41,7 +43,14 @@ const NATIVE_TYPESCRIPT_PACKAGES = [
41
43
  "typescript",
42
44
  "@typescript/native"
43
45
  ];
46
+ const EFFECT_TSRS_PROVIDER_VERSION = '0.59.0';
47
+ const EFFECT_TSRS_TARGETS = new Set([
48
+ '@tsrs/darwin-arm64',
49
+ '@tsrs/linux-x64-gnu',
50
+ '@tsrs/linux-arm64-gnu'
51
+ ]);
44
52
  const failureStages = new WeakMap();
53
+ const reportedUnsupportedTsrsTargets = new Set();
45
54
  function effectCompilerDiscoveryFailureStage(error) {
46
55
  return error && 'object' == typeof error ? failureStages.get(error) : void 0;
47
56
  }
@@ -59,7 +68,7 @@ function resolveEffectTsgoPackage(from) {
59
68
  cliPath
60
69
  };
61
70
  }
62
- function isAbsentNativeTypeScriptPackage(projectRequire, from, packageName, error) {
71
+ function isAbsentPackage(projectRequire, from, packageName, error) {
63
72
  const filename = 'string' != typeof from || from.startsWith('file:') ? (0, external_node_url_namespaceObject.fileURLToPath)(from) : from;
64
73
  if (!(error instanceof Error) || !('code' in error) || 'MODULE_NOT_FOUND' !== error.code || 'path' in error && void 0 !== error.path || error.message.split('\n')[0] !== `Cannot find module '${packageName}/package.json'` || !('requireStack' in error) || !Array.isArray(error.requireStack) || error.requireStack[0] !== filename) return false;
65
74
  for (const searchDirectory of projectRequire.resolve.paths(packageName) ?? [])try {
@@ -80,7 +89,7 @@ function resolveNativeTypeScriptPackage(from) {
80
89
  try {
81
90
  packageJsonPath = projectRequire.resolve(`${packageName}/package.json`);
82
91
  } catch (error) {
83
- if (isAbsentNativeTypeScriptPackage(projectRequire, from, packageName, error)) continue;
92
+ if (isAbsentPackage(projectRequire, from, packageName, error)) continue;
84
93
  throw error;
85
94
  }
86
95
  const packageJson = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(packageJsonPath, 'utf-8'));
@@ -104,10 +113,85 @@ function readCompilerArtifact(filename) {
104
113
  if (0 === stats.size) throw new Error(`Compiler artifact is empty: ${filename}`);
105
114
  return canonicalPath;
106
115
  }
116
+ function resolveTsrsManifest(from) {
117
+ const projectRequire = (0, external_node_module_namespaceObject.createRequire)(from);
118
+ try {
119
+ return projectRequire.resolve('tsrs/package.json');
120
+ } catch (error) {
121
+ if (isAbsentPackage(projectRequire, from, 'tsrs', error)) return;
122
+ throw error;
123
+ }
124
+ }
125
+ function compilerVersion(compiler) {
126
+ return (0, external_node_child_process_namespaceObject.execFileSync)(compiler, [
127
+ '--version'
128
+ ], {
129
+ encoding: 'utf8',
130
+ env: {
131
+ ...process.env,
132
+ TSRS_CHECKER_ASSIGNMENT: process.env.TSRS_CHECKER_ASSIGNMENT || 'go'
133
+ },
134
+ timeout: 10000,
135
+ maxBuffer: 1048576
136
+ }).trim();
137
+ }
138
+ function tsrsPlatform(manifestPath) {
139
+ const manifest = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(manifestPath, 'utf8'));
140
+ const { getPlatformPackageName } = (0, external_node_module_namespaceObject.createRequire)(manifestPath)((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(manifestPath), 'lib/platform.js'));
141
+ const nativeName = getPlatformPackageName();
142
+ const embedded = manifest.tsrs;
143
+ if ('string' != typeof nativeName || !nativeName || !manifest.optionalDependencies || 'object' != typeof manifest.optionalDependencies || Array.isArray(manifest.optionalDependencies) || 0 === Object.keys(manifest.optionalDependencies).length) throw new Error(`Invalid native tsrs capability metadata: ${manifestPath}`);
144
+ if ('string' != typeof manifest.name || !manifest.name || 'string' != typeof manifest.version || !/^\d+\.\d+\.\d+-ts[\w.-]+$/u.test(manifest.version) || 'string' != typeof embedded?.typescriptVersion || !/^7\.\d+\.\d+(?:[-+][\w.-]+)?$/u.test(embedded.typescriptVersion) || !manifest.version.endsWith(`-ts${embedded.typescriptVersion}`) || 'string' != typeof embedded.typescriptCommit || !/^[a-f\d]{40}$/u.test(embedded.typescriptCommit)) throw new Error(`Invalid native tsrs metadata: ${manifestPath}`);
145
+ const supported = Object.hasOwn(manifest.optionalDependencies, nativeName);
146
+ if (supported && manifest.optionalDependencies[nativeName] !== manifest.version) throw new Error(`Native tsrs target version does not match its selected package: ${manifestPath}`);
147
+ return {
148
+ manifest: manifest,
149
+ nativeName,
150
+ supported
151
+ };
152
+ }
153
+ function resolveTsrsCompiler(manifestPath, effect, configuredCompiler, configuredVersion) {
154
+ const { manifest } = tsrsPlatform(manifestPath);
155
+ const embedded = manifest.tsrs;
156
+ const effectName = `@effect/tsgo-${process.platform}-${process.arch}`;
157
+ const effectManifest = (0, external_node_module_namespaceObject.createRequire)(effect.cliPath).resolve(`${effectName}/package.json`);
158
+ const platform = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(effectManifest, 'utf8'));
159
+ const metadataPath = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'lib/upstream.json');
160
+ const metadata = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(metadataPath, 'utf8'));
161
+ const component = metadata.components?.tsrs?.[manifest.version];
162
+ if (platform.name !== effectName || platform.version !== effect.packageJson.version || 5 !== metadata.schemaVersion || !/^[a-f\d]{40}$/u.test(component?.gitHead ?? '') || component?.typescript?.version !== embedded.typescriptVersion || component.typescript.gitHead !== embedded.typescriptCommit) throw new Error(`Effect replacement metadata does not match tsrs: ${metadataPath}`);
163
+ const compiler = readCompilerArtifact(configuredCompiler ?? (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'artifacts/tsrs', manifest.version, 'win32' === process.platform ? 'tsrs.exe' : 'tsrs'));
164
+ const version = configuredVersion ?? compilerVersion(compiler);
165
+ const stamp = /\+effect-tsgo\.([\d.]+)\s+\(tsrs ([^,]+), microsoft\/TypeScript@([a-f\d]+)\)$/u.exec(version);
166
+ if (!stamp || stamp[1] !== effect.packageJson.version || stamp[2] !== manifest.version || stamp[3].length < 12 || !embedded.typescriptCommit.startsWith(stamp[3])) throw new Error(`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.`);
167
+ return compiler;
168
+ }
169
+ function validateConfiguredEffectCompiler(compiler, from) {
170
+ const version = compilerVersion(compiler);
171
+ if (!/^Version \d+\.\d+\.\d+[\w.-]*\+effect-tsgo\.\d+\.\d+\.\d+(?:\s|$)/u.test(version)) throw new Error(`EFFECT_TSGO_BIN must select an Effect-enabled native compiler: ${compiler}`);
172
+ if (version.includes('(tsrs ')) {
173
+ const manifest = resolveTsrsManifest(from);
174
+ if (!manifest) throw new Error(`Cannot validate tsrs without its installed package metadata for ${String(from)}`);
175
+ resolveTsrsCompiler(manifest, resolveEffectTsgoPackage(from), compiler, version);
176
+ }
177
+ }
107
178
  function resolveInstalledEffectCompiler(from) {
108
179
  let stage = 'Package CLI resolution';
109
180
  try {
110
181
  const effect = resolveEffectTsgoPackage(from);
182
+ stage = 'Native tsrs package resolution';
183
+ const tsrsManifest = resolveTsrsManifest(from);
184
+ const tsrsTarget = tsrsManifest ? tsrsPlatform(tsrsManifest) : void 0;
185
+ if (tsrsTarget && effect.packageJson.version !== EFFECT_TSRS_PROVIDER_VERSION) throw new Error(`Unreviewed Effect tsrs capability contract: ${effect.packageJson.version}`);
186
+ const configuredTsrsCompiler = process.env.TSRS_BINARY || void 0;
187
+ if (tsrsManifest && tsrsTarget?.supported && (configuredTsrsCompiler || EFFECT_TSRS_TARGETS.has(tsrsTarget.nativeName))) {
188
+ stage = 'Native tsrs validation';
189
+ return resolveTsrsCompiler(tsrsManifest, effect, configuredTsrsCompiler);
190
+ }
191
+ if (tsrsTarget && !reportedUnsupportedTsrsTargets.has(tsrsTarget.nativeName)) {
192
+ reportedUnsupportedTsrsTargets.add(tsrsTarget.nativeName);
193
+ console.warn(`[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.`);
194
+ }
111
195
  stage = 'Native TypeScript package resolution';
112
196
  const typeScriptManifest = resolveNativeTypeScriptManifest(from);
113
197
  const typeScript = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(typeScriptManifest, 'utf8'));
@@ -125,8 +209,10 @@ function resolveInstalledEffectCompiler(from) {
125
209
  const metadataPath = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'lib', 'upstream.json');
126
210
  const metadata = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(metadataPath, 'utf8'));
127
211
  const component = metadata.components?.typescript?.[native.version];
128
- if (5 !== metadata.schemaVersion || component?.provider !== "typescript-go" || component.gitHead !== native.gitHead) throw new Error(`Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`);
129
- return readCompilerArtifact((0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'artifacts', "typescript", native.version, binaryName));
212
+ const latestTypeScript = metadata.tags?.typescript?.latest;
213
+ if (5 !== metadata.schemaVersion || 'string' != typeof latestTypeScript || component?.provider !== "typescript-go" || component.gitHead !== native.gitHead) throw new Error(`Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`);
214
+ const compilerDirectory = native.version === latestTypeScript ? (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'lib') : (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(effectManifest), 'artifacts', "typescript", native.version);
215
+ return readCompilerArtifact((0, external_node_path_namespaceObject.join)(compilerDirectory, binaryName));
130
216
  } catch (error) {
131
217
  if (error && 'object' == typeof error && !failureStages.has(error)) failureStages.set(error, stage);
132
218
  throw error;
@@ -134,9 +220,11 @@ function resolveInstalledEffectCompiler(from) {
134
220
  }
135
221
  exports.effectCompilerDiscoveryFailureStage = __webpack_exports__.effectCompilerDiscoveryFailureStage;
136
222
  exports.resolveInstalledEffectCompiler = __webpack_exports__.resolveInstalledEffectCompiler;
223
+ exports.validateConfiguredEffectCompiler = __webpack_exports__.validateConfiguredEffectCompiler;
137
224
  for(var __rspack_i in __webpack_exports__)if (-1 === [
138
225
  "effectCompilerDiscoveryFailureStage",
139
- "resolveInstalledEffectCompiler"
226
+ "resolveInstalledEffectCompiler",
227
+ "validateConfiguredEffectCompiler"
140
228
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
141
229
  Object.defineProperty(exports, '__esModule', {
142
230
  value: true
@@ -45,7 +45,8 @@ var promises_default = /*#__PURE__*/ __webpack_require__.n(promises_namespaceObj
45
45
  const external_node_path_namespaceObject = require("node:path");
46
46
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
47
47
  const external_issues_js_namespaceObject = require("./issues.js");
48
- const SOURCE_SCAN_FILE_PATTERN = /\.(?:[cm]?[jt]s|json)$/u;
48
+ const SOURCE_SCAN_FILE_PATTERN = /\.(?:[cm]?[jt]sx?)$/u;
49
+ const DECLARATION_FILE_PATTERN = /\.d\.[cm]?ts$/u;
49
50
  const SOURCE_SCAN_IGNORED_DIRECTORY_NAMES = new Set([
50
51
  '.codex',
51
52
  '.fastcontext',
@@ -118,7 +119,7 @@ const walkFiles = async (root)=>{
118
119
  files.push(...await walkFiles(entryPath));
119
120
  continue;
120
121
  }
121
- if (SOURCE_SCAN_FILE_PATTERN.test(entry.name)) files.push(entryPath);
122
+ if ('package.json' === entry.name || SOURCE_SCAN_FILE_PATTERN.test(entry.name) && !DECLARATION_FILE_PATTERN.test(entry.name)) files.push(entryPath);
122
123
  }
123
124
  return files;
124
125
  };
@@ -135,7 +136,26 @@ const verifyCloudflareOutputMutationPolicy = async (options)=>{
135
136
  if ('ENOENT' === error.code) continue;
136
137
  throw error;
137
138
  }
138
- for (const forbidden of FORBIDDEN_MUTATION_PATTERNS)if (forbidden.pattern.test(source)) (0, external_issues_js_namespaceObject.addIssue)(issues, {
139
+ let executableSources = [
140
+ source
141
+ ];
142
+ if ('package.json' === external_node_path_default().basename(file)) try {
143
+ const manifest = JSON.parse(source);
144
+ if (!isRecord(manifest)) throw new TypeError('Package metadata must be an object.');
145
+ const scripts = Object.hasOwn(manifest, "scripts") ? manifest.scripts : {};
146
+ if (!isRecord(scripts)) throw new TypeError("Package scripts must be an object.");
147
+ const commands = Object.values(scripts);
148
+ if (!commands.every((value)=>'string' == typeof value)) throw new TypeError("Package scripts must contain only strings.");
149
+ executableSources = commands;
150
+ } catch {
151
+ (0, external_issues_js_namespaceObject.addIssue)(issues, {
152
+ code: 'invalid-package',
153
+ message: "Cannot verify executable package lifecycle scripts: invalid package metadata.",
154
+ path: file
155
+ });
156
+ continue;
157
+ }
158
+ for (const forbidden of FORBIDDEN_MUTATION_PATTERNS)if (executableSources.some((value)=>forbidden.pattern.test(value))) (0, external_issues_js_namespaceObject.addIssue)(issues, {
139
159
  code: forbidden.code,
140
160
  message: forbidden.message,
141
161
  path: file
@@ -146,6 +166,7 @@ const verifyCloudflareOutputMutationPolicy = async (options)=>{
146
166
  issues
147
167
  };
148
168
  };
169
+ const isRecord = (value)=>null !== value && 'object' == typeof value && !Array.isArray(value);
149
170
  exports.verifyCloudflareOutputMutationPolicy = __webpack_exports__.verifyCloudflareOutputMutationPolicy;
150
171
  exports.walkFiles = __webpack_exports__.walkFiles;
151
172
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -45,30 +45,60 @@ __webpack_require__.d(__webpack_exports__, {
45
45
  const external_node_child_process_namespaceObject = require("node:child_process");
46
46
  const external_node_crypto_namespaceObject = require("node:crypto");
47
47
  const external_node_fs_namespaceObject = require("node:fs");
48
+ const external_node_module_namespaceObject = require("node:module");
48
49
  const external_node_path_namespaceObject = require("node:path");
49
50
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
50
51
  const external_node_util_namespaceObject = require("node:util");
51
52
  const builder_namespaceObject = require("@modern-js/builder");
52
53
  const external_jsonc_parser_namespaceObject = require("jsonc-parser");
54
+ const build_environment_js_namespaceObject = require("./build-config/build-environment.js");
53
55
  const execute = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
54
56
  const native_type_checker_name = 'UltramodernNativeTypeChecker';
55
- function resolveNativeTypeCheckerCommand(packageJsonPath) {
56
- const manifestFile = (0, external_node_fs_namespaceObject.realpathSync)(packageJsonPath);
57
- const directory = external_node_path_default().dirname(manifestFile);
58
- const manifest = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(manifestFile, 'utf8'));
59
- if ("typescript" !== manifest.name || '7.0.2' !== manifest.version) throw new Error(`${native_type_checker_name} requires typescript@7.0.2; found ${String(manifest.name)}@${String(manifest.version)} at ${manifestFile}.`);
60
- const bin = manifest.bin?.tsc;
61
- if ('string' != typeof bin || !bin || external_node_path_default().isAbsolute(bin)) throw new Error(`${native_type_checker_name} requires the selected package's public tsc bin.`);
62
- const launcher = (0, external_node_fs_namespaceObject.realpathSync)(external_node_path_default().resolve(directory, bin));
63
- const relative = external_node_path_default().relative(directory, launcher);
64
- if (!relative || external_node_path_default().isAbsolute(relative) || '..' === relative || relative.startsWith(`..${external_node_path_default().sep}`) || !(0, external_node_fs_namespaceObject.statSync)(launcher).isFile()) throw new Error(`${native_type_checker_name} public tsc bin must belong to its selected package.`);
57
+ function resolveNativeTypeCheckerCommand(from) {
58
+ const executable = (0, build_environment_js_namespaceObject.resolveEffectTsgoCompiler)({
59
+ from
60
+ });
61
+ const version = (0, external_node_child_process_namespaceObject.execFileSync)(executable, [
62
+ '--version'
63
+ ], {
64
+ encoding: 'utf8',
65
+ env: {
66
+ ...process.env,
67
+ TSRS_CHECKER_ASSIGNMENT: process.env.TSRS_CHECKER_ASSIGNMENT || 'go'
68
+ },
69
+ timeout: 10000
70
+ });
71
+ if (version.includes('(tsrs ')) return {
72
+ executable,
73
+ args: [],
74
+ configApi: (0, external_node_module_namespaceObject.createRequire)(from).resolve('tsrs/sync')
75
+ };
65
76
  return {
66
- executable: process.execPath,
67
- args: [
68
- launcher
69
- ]
77
+ executable,
78
+ args: []
70
79
  };
71
80
  }
81
+ const inspectNativeConfig = `
82
+ import { pathToFileURL } from 'node:url';
83
+ const [modulePath, compiler, configFile] = process.argv.slice(1);
84
+ const { API, formatDiagnostics } = await import(pathToFileURL(modulePath).href);
85
+ const api = new API({ tsserverPath: compiler });
86
+ try {
87
+ const config = api.parseConfigFile(configFile);
88
+ if (config.errors.length) {
89
+ process.stdout.write(formatDiagnostics(config.errors, api));
90
+ process.exitCode = 1;
91
+ } else {
92
+ process.stdout.write(JSON.stringify({
93
+ compilerOptions: config.options,
94
+ files: config.fileNames,
95
+ references: config.projectReferences,
96
+ }));
97
+ }
98
+ } finally {
99
+ api.close();
100
+ }
101
+ `;
72
102
  const watchDependencyPath = (file)=>{
73
103
  if ('win32' !== process.platform) return file;
74
104
  try {
@@ -180,19 +210,37 @@ class UltramodernNativeTypeChecker {
180
210
  executable: selected,
181
211
  args: []
182
212
  } : selected;
183
- const result = await execute(command.executable, [
213
+ const inspect = '--showConfig' === args[0] && command.configApi;
214
+ const result = await execute(inspect ? process.execPath : command.executable, inspect ? [
215
+ '--input-type=module',
216
+ '--eval',
217
+ inspectNativeConfig,
218
+ command.configApi,
219
+ command.executable,
220
+ args[args.indexOf('--project') + 1]
221
+ ] : [
184
222
  ...command.args,
185
223
  ...args
186
224
  ], {
187
225
  cwd: external_node_path_default().dirname(this.options.configFile),
188
- maxBuffer: 16777216
226
+ env: {
227
+ ...process.env,
228
+ TSRS_CHECKER_ASSIGNMENT: process.env.TSRS_CHECKER_ASSIGNMENT || 'go'
229
+ },
230
+ maxBuffer: 16777216,
231
+ ...inspect ? {
232
+ timeout: 10000
233
+ } : {}
189
234
  });
190
235
  return result.stdout;
191
236
  } catch (cause) {
192
237
  const output = cause;
193
238
  const diagnostics = `${output.stdout ?? ''}${output.stderr ?? ''}`;
194
- throw new Error(`${native_type_checker_name} failed:\n${diagnostics || (cause instanceof Error ? cause.message : String(cause))}${missingJsxRuntimeHint(diagnostics)}`, {
239
+ throw Object.assign(new Error(`${native_type_checker_name} failed:\n${diagnostics || (cause instanceof Error ? cause.message : String(cause))}${missingJsxRuntimeHint(diagnostics)}`, {
195
240
  cause
241
+ }), {
242
+ code: output.code,
243
+ signal: output.signal
196
244
  });
197
245
  }
198
246
  }
@@ -254,9 +302,7 @@ class UltramodernNativeTypeChecker {
254
302
  this.removeProjection(configFile);
255
303
  }
256
304
  } catch (cause) {
257
- compilation.errors.push(new Error(cause instanceof Error ? cause.message : String(cause), {
258
- cause
259
- }));
305
+ compilation.errors.push(cause instanceof Error ? cause : new Error(String(cause)));
260
306
  }
261
307
  });
262
308
  });
@@ -54,7 +54,7 @@ const gitOutput = (workspaceRoot, args)=>{
54
54
  return;
55
55
  }
56
56
  };
57
- const createUltramodernReleaseBuildMarker = ({ generationBuildMarker, sourceRevision, unitId })=>(0, external_node_crypto_namespaceObject.createHash)('sha256').update(`${BUILD_MARKER_NAMESPACE}:${unitId}:${generationBuildMarker}:${sourceRevision}`).digest('hex').slice(0, 16);
57
+ const createUltramodernReleaseBuildMarker = ({ generationBuildMarker, sourceRevision, unitId })=>(0, external_node_crypto_namespaceObject.createHash)('sha256').update(`${BUILD_MARKER_NAMESPACE}:${unitId}:${generationBuildMarker}:${sourceRevision}`).digest('hex');
58
58
  const resolveUltramodernSourceRevision = (workspaceRoot = process.cwd(), configuredSourceRevision, environment = process.env)=>{
59
59
  const configuredArgumentValue = configuredSourceRevision?.trim();
60
60
  const configuredEnvironmentValue = environment.ULTRAMODERN_SOURCE_REVISION?.trim();
@@ -54,6 +54,7 @@ const LOCKFILES = [
54
54
  'bun.lock',
55
55
  'bun.lockb'
56
56
  ];
57
+ const RELEASE_BUILD_MARKER_PATTERN = /^[a-f0-9]{64}$/u;
57
58
  const processNonce = (0, external_node_crypto_namespaceObject.randomUUID)();
58
59
  const sha256 = (value)=>(0, external_node_crypto_namespaceObject.createHash)('sha256').update(value).digest('hex');
59
60
  function rendererProfileKey(profile) {
@@ -98,12 +99,21 @@ function resolveRendererBuildIdentities(options) {
98
99
  const projectRoot = external_node_path_default().resolve(options.projectRoot);
99
100
  const appId = options.appId ?? JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(projectRoot, 'package.json'), 'utf8')).name;
100
101
  if ('string' != typeof appId || !appId || appId.trim() !== appId) throw new Error('Renderer application identity requires a delivery artifact appId or a package name.');
102
+ const { deliveryUnit } = options;
103
+ if (void 0 !== deliveryUnit && ('string' != typeof deliveryUnit.unitId || !deliveryUnit.unitId || deliveryUnit.unitId.trim() !== deliveryUnit.unitId)) throw new Error('Renderer delivery-unit identity requires a nonempty trimmed unitId.');
101
104
  const profileKey = rendererProfileKey(options.profile);
102
- const sourceRevision = (0, external_release_identity_js_namespaceObject.resolveUltramodernSourceRevision)(projectRoot, options.sourceRevision);
103
- const buildId = sha256(JSON.stringify([
105
+ const sourceRevision = (0, external_release_identity_js_namespaceObject.resolveUltramodernSourceRevision)(projectRoot, deliveryUnit ? deliveryUnit.sourceRevision : options.sourceRevision);
106
+ const promotable = 'production' === options.mode && 'workspace' !== sourceRevision;
107
+ let buildId;
108
+ if (promotable && deliveryUnit) {
109
+ if (deliveryUnit.sourceRevision !== sourceRevision || !RELEASE_BUILD_MARKER_PATTERN.test(deliveryUnit.buildMarker)) throw new Error(`Renderer delivery unit ${deliveryUnit.unitId} must carry the release identity of source revision ${sourceRevision}.`);
110
+ buildId = deliveryUnit.buildMarker;
111
+ } else buildId = sha256(JSON.stringify([
112
+ appId,
113
+ deliveryUnit?.unitId ?? null,
104
114
  profileKey,
105
115
  lockfileHash(projectRoot),
106
- 'development' === options.mode || 'workspace' === sourceRevision ? processNonce : sourceRevision
116
+ promotable ? sourceRevision : processNonce
107
117
  ]));
108
118
  const identities = Object.fromEntries(entries.map((entryName)=>[
109
119
  entryName,
@@ -306,7 +306,24 @@ async function invokeNativeRouteWorker(route, identity, request, env, ctx) {
306
306
  const resources =
307
307
  nativeRenderer?.renderer === identity.renderer &&
308
308
  Object.hasOwn(nativeRenderer.entries, route.entryName)
309
- ? nativeRenderer.entries[route.entryName]
309
+ ? {
310
+ ...nativeRenderer.entries[route.entryName],
311
+ ...(Object.hasOwn(nativeRenderer, 'workerFederation')
312
+ ? { workerFederation: nativeRenderer.workerFederation }
313
+ : {}),
314
+ ...(Object.hasOwn(nativeRenderer, 'workerFederationManifestUrl')
315
+ ? {
316
+ workerFederationManifestUrl:
317
+ nativeRenderer.workerFederationManifestUrl,
318
+ }
319
+ : {}),
320
+ ...(Object.hasOwn(nativeRenderer, 'workerFederationServices')
321
+ ? {
322
+ workerFederationServices:
323
+ nativeRenderer.workerFederationServices,
324
+ }
325
+ : {}),
326
+ }
310
327
  : undefined;
311
328
  // Native renderers have no Flight transport. Reject before the bundle loads.
312
329
  if (
@@ -9,8 +9,8 @@ const owningManifest = findPackageJSON(owningModuleUrl, owningModuleUrl);
9
9
  if (!owningManifest) throw new Error('Cannot find owning build-config package manifest');
10
10
  const owningName = JSON.parse(readFileSync(owningManifest, 'utf8')).name;
11
11
  if ('string' != typeof owningName || 0 === owningName.length) throw new Error(`Invalid owning build-config package name: ${owningManifest}`);
12
- const { effectCompilerDiscoveryFailureStage: effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler: resolveInstalledEffectCompiler } = createRequire(owningModuleUrl)(`${owningName}/internal-effect-discovery`);
13
- const EFFECT_TSGO_RESOLUTION_ERROR = 'Unable to resolve the Effect TS-Go compiler. Install "@effect/tsgo" and a native TypeScript backend for this build config, or set EFFECT_TSGO_BIN.';
12
+ const { effectCompilerDiscoveryFailureStage: effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler: resolveInstalledEffectCompiler, validateConfiguredEffectCompiler: validateConfiguredEffectCompiler } = createRequire(owningModuleUrl)(`${owningName}/internal-effect-discovery`);
13
+ const EFFECT_TSGO_RESOLUTION_ERROR = 'Unable to resolve the Effect TS-Go compiler. Install "@effect/tsgo" and a native TypeScript backend for this build config, or set EFFECT_TSGO_BIN. Bundled tsrs requires matching installed tsrs metadata.';
14
14
  const executableEffectTsgoCompilers = new Map();
15
15
  function effectTsgoResolutionError(cause, stage, from) {
16
16
  const detail = cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause);
@@ -19,10 +19,10 @@ function effectTsgoResolutionError(cause, stage, from) {
19
19
  });
20
20
  }
21
21
  function resolveExecutableEffectTsgoCompiler(compilerPath) {
22
- if ('win32' === process.platform) return compilerPath;
23
22
  const sourcePath = realpathSync(compilerPath);
24
23
  const source = lstatSync(sourcePath);
25
- if (!source.isFile()) throw new Error(`Effect TS-Go compiler path is not a regular file: ${sourcePath}`);
24
+ if (!source.isFile() || 0 === source.size) throw new Error(`Effect TS-Go compiler path is not a nonempty regular file: ${sourcePath}`);
25
+ if ('win32' === process.platform) return compilerPath;
26
26
  try {
27
27
  accessSync(sourcePath, constants.X_OK);
28
28
  return compilerPath;
@@ -72,7 +72,9 @@ function getBuildConfigEnvironment(name) {
72
72
  function resolveEffectTsgoCompiler(options) {
73
73
  const configuredCompiler = getBuildConfigEnvironment('EFFECT_TSGO_BIN')?.trim();
74
74
  if (configuredCompiler) try {
75
- return resolveExecutableEffectTsgoCompiler(configuredCompiler);
75
+ const compiler = resolveExecutableEffectTsgoCompiler(configuredCompiler);
76
+ validateConfiguredEffectCompiler(compiler, options.from);
77
+ return compiler;
76
78
  } catch (cause) {
77
79
  throw effectTsgoResolutionError(cause, 'Configured compiler validation', options.from);
78
80
  }
@@ -1,3 +1,4 @@
1
+ import { execFileSync } from "node:child_process";
1
2
  import { lstatSync, readFileSync, realpathSync } from "node:fs";
2
3
  import { createRequire } from "node:module";
3
4
  import { dirname, join, resolve } from "node:path";
@@ -8,7 +9,14 @@ const NATIVE_TYPESCRIPT_PACKAGES = [
8
9
  "typescript",
9
10
  "@typescript/native"
10
11
  ];
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
+ ]);
11
18
  const failureStages = new WeakMap();
19
+ const reportedUnsupportedTsrsTargets = new Set();
12
20
  function effectCompilerDiscoveryFailureStage(error) {
13
21
  return error && 'object' == typeof error ? failureStages.get(error) : void 0;
14
22
  }
@@ -26,7 +34,7 @@ function resolveEffectTsgoPackage(from) {
26
34
  cliPath
27
35
  };
28
36
  }
29
- function isAbsentNativeTypeScriptPackage(projectRequire, from, packageName, error) {
37
+ function isAbsentPackage(projectRequire, from, packageName, error) {
30
38
  const filename = 'string' != typeof from || from.startsWith('file:') ? fileURLToPath(from) : from;
31
39
  if (!(error instanceof Error) || !('code' in error) || 'MODULE_NOT_FOUND' !== error.code || 'path' in error && void 0 !== error.path || error.message.split('\n')[0] !== `Cannot find module '${packageName}/package.json'` || !('requireStack' in error) || !Array.isArray(error.requireStack) || error.requireStack[0] !== filename) return false;
32
40
  for (const searchDirectory of projectRequire.resolve.paths(packageName) ?? [])try {
@@ -47,7 +55,7 @@ function resolveNativeTypeScriptPackage(from) {
47
55
  try {
48
56
  packageJsonPath = projectRequire.resolve(`${packageName}/package.json`);
49
57
  } catch (error) {
50
- if (isAbsentNativeTypeScriptPackage(projectRequire, from, packageName, error)) continue;
58
+ if (isAbsentPackage(projectRequire, from, packageName, error)) continue;
51
59
  throw error;
52
60
  }
53
61
  const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
@@ -71,10 +79,85 @@ function readCompilerArtifact(filename) {
71
79
  if (0 === stats.size) throw new Error(`Compiler artifact is empty: ${filename}`);
72
80
  return canonicalPath;
73
81
  }
82
+ function resolveTsrsManifest(from) {
83
+ const projectRequire = createRequire(from);
84
+ try {
85
+ return projectRequire.resolve('tsrs/package.json');
86
+ } catch (error) {
87
+ if (isAbsentPackage(projectRequire, from, 'tsrs', error)) return;
88
+ throw error;
89
+ }
90
+ }
91
+ function compilerVersion(compiler) {
92
+ return execFileSync(compiler, [
93
+ '--version'
94
+ ], {
95
+ encoding: 'utf8',
96
+ env: {
97
+ ...process.env,
98
+ TSRS_CHECKER_ASSIGNMENT: process.env.TSRS_CHECKER_ASSIGNMENT || 'go'
99
+ },
100
+ timeout: 10000,
101
+ maxBuffer: 1048576
102
+ }).trim();
103
+ }
104
+ function tsrsPlatform(manifestPath) {
105
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
106
+ const { getPlatformPackageName } = createRequire(manifestPath)(join(dirname(manifestPath), 'lib/platform.js'));
107
+ const nativeName = getPlatformPackageName();
108
+ const embedded = manifest.tsrs;
109
+ if ('string' != typeof nativeName || !nativeName || !manifest.optionalDependencies || 'object' != typeof manifest.optionalDependencies || Array.isArray(manifest.optionalDependencies) || 0 === Object.keys(manifest.optionalDependencies).length) throw new Error(`Invalid native tsrs capability metadata: ${manifestPath}`);
110
+ if ('string' != typeof manifest.name || !manifest.name || 'string' != typeof manifest.version || !/^\d+\.\d+\.\d+-ts[\w.-]+$/u.test(manifest.version) || 'string' != typeof embedded?.typescriptVersion || !/^7\.\d+\.\d+(?:[-+][\w.-]+)?$/u.test(embedded.typescriptVersion) || !manifest.version.endsWith(`-ts${embedded.typescriptVersion}`) || 'string' != typeof embedded.typescriptCommit || !/^[a-f\d]{40}$/u.test(embedded.typescriptCommit)) throw new Error(`Invalid native tsrs metadata: ${manifestPath}`);
111
+ const supported = Object.hasOwn(manifest.optionalDependencies, nativeName);
112
+ if (supported && manifest.optionalDependencies[nativeName] !== manifest.version) throw new Error(`Native tsrs target version does not match its selected package: ${manifestPath}`);
113
+ return {
114
+ manifest: manifest,
115
+ nativeName,
116
+ supported
117
+ };
118
+ }
119
+ function resolveTsrsCompiler(manifestPath, effect, configuredCompiler, configuredVersion) {
120
+ const { manifest } = tsrsPlatform(manifestPath);
121
+ const embedded = manifest.tsrs;
122
+ const effectName = `@effect/tsgo-${process.platform}-${process.arch}`;
123
+ const effectManifest = createRequire(effect.cliPath).resolve(`${effectName}/package.json`);
124
+ const platform = JSON.parse(readFileSync(effectManifest, 'utf8'));
125
+ const metadataPath = join(dirname(effectManifest), 'lib/upstream.json');
126
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf8'));
127
+ const component = metadata.components?.tsrs?.[manifest.version];
128
+ if (platform.name !== effectName || platform.version !== effect.packageJson.version || 5 !== metadata.schemaVersion || !/^[a-f\d]{40}$/u.test(component?.gitHead ?? '') || component?.typescript?.version !== embedded.typescriptVersion || component.typescript.gitHead !== embedded.typescriptCommit) throw new Error(`Effect replacement metadata does not match tsrs: ${metadataPath}`);
129
+ const compiler = readCompilerArtifact(configuredCompiler ?? join(dirname(effectManifest), 'artifacts/tsrs', manifest.version, 'win32' === process.platform ? 'tsrs.exe' : 'tsrs'));
130
+ const version = configuredVersion ?? compilerVersion(compiler);
131
+ const stamp = /\+effect-tsgo\.([\d.]+)\s+\(tsrs ([^,]+), microsoft\/TypeScript@([a-f\d]+)\)$/u.exec(version);
132
+ if (!stamp || stamp[1] !== effect.packageJson.version || stamp[2] !== manifest.version || stamp[3].length < 12 || !embedded.typescriptCommit.startsWith(stamp[3])) throw new Error(`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.`);
133
+ return compiler;
134
+ }
135
+ function validateConfiguredEffectCompiler(compiler, from) {
136
+ const version = compilerVersion(compiler);
137
+ if (!/^Version \d+\.\d+\.\d+[\w.-]*\+effect-tsgo\.\d+\.\d+\.\d+(?:\s|$)/u.test(version)) throw new Error(`EFFECT_TSGO_BIN must select an Effect-enabled native compiler: ${compiler}`);
138
+ if (version.includes('(tsrs ')) {
139
+ const manifest = resolveTsrsManifest(from);
140
+ if (!manifest) throw new Error(`Cannot validate tsrs without its installed package metadata for ${String(from)}`);
141
+ resolveTsrsCompiler(manifest, resolveEffectTsgoPackage(from), compiler, version);
142
+ }
143
+ }
74
144
  function resolveInstalledEffectCompiler(from) {
75
145
  let stage = 'Package CLI resolution';
76
146
  try {
77
147
  const effect = resolveEffectTsgoPackage(from);
148
+ stage = 'Native tsrs package resolution';
149
+ const tsrsManifest = resolveTsrsManifest(from);
150
+ const tsrsTarget = tsrsManifest ? tsrsPlatform(tsrsManifest) : void 0;
151
+ if (tsrsTarget && effect.packageJson.version !== EFFECT_TSRS_PROVIDER_VERSION) throw new Error(`Unreviewed Effect tsrs capability contract: ${effect.packageJson.version}`);
152
+ const configuredTsrsCompiler = process.env.TSRS_BINARY || void 0;
153
+ if (tsrsManifest && tsrsTarget?.supported && (configuredTsrsCompiler || EFFECT_TSRS_TARGETS.has(tsrsTarget.nativeName))) {
154
+ stage = 'Native tsrs validation';
155
+ return resolveTsrsCompiler(tsrsManifest, effect, configuredTsrsCompiler);
156
+ }
157
+ if (tsrsTarget && !reportedUnsupportedTsrsTargets.has(tsrsTarget.nativeName)) {
158
+ reportedUnsupportedTsrsTargets.add(tsrsTarget.nativeName);
159
+ console.warn(`[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.`);
160
+ }
78
161
  stage = 'Native TypeScript package resolution';
79
162
  const typeScriptManifest = resolveNativeTypeScriptManifest(from);
80
163
  const typeScript = JSON.parse(readFileSync(typeScriptManifest, 'utf8'));
@@ -92,11 +175,13 @@ function resolveInstalledEffectCompiler(from) {
92
175
  const metadataPath = join(dirname(effectManifest), 'lib', 'upstream.json');
93
176
  const metadata = JSON.parse(readFileSync(metadataPath, 'utf8'));
94
177
  const component = metadata.components?.typescript?.[native.version];
95
- if (5 !== metadata.schemaVersion || component?.provider !== "typescript-go" || component.gitHead !== native.gitHead) throw new Error(`Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`);
96
- return readCompilerArtifact(join(dirname(effectManifest), 'artifacts', "typescript", native.version, binaryName));
178
+ const latestTypeScript = metadata.tags?.typescript?.latest;
179
+ if (5 !== metadata.schemaVersion || 'string' != typeof latestTypeScript || component?.provider !== "typescript-go" || component.gitHead !== native.gitHead) throw new Error(`Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`);
180
+ const compilerDirectory = native.version === latestTypeScript ? join(dirname(effectManifest), 'lib') : join(dirname(effectManifest), 'artifacts', "typescript", native.version);
181
+ return readCompilerArtifact(join(compilerDirectory, binaryName));
97
182
  } catch (error) {
98
183
  if (error && 'object' == typeof error && !failureStages.has(error)) failureStages.set(error, stage);
99
184
  throw error;
100
185
  }
101
186
  }
102
- export { effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler };
187
+ export { effectCompilerDiscoveryFailureStage, resolveInstalledEffectCompiler, validateConfiguredEffectCompiler };