@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.
- package/dist/cjs/build-config/build-environment.js +7 -5
- package/dist/cjs/build-config/internal-effect-discovery.js +94 -6
- package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +24 -3
- package/dist/cjs/native-type-checker.js +66 -20
- package/dist/cjs/release-identity.js +1 -1
- package/dist/cjs/renderer-build-identity.js +13 -3
- package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
- package/dist/esm/build-config/build-environment.mjs +7 -5
- package/dist/esm/build-config/internal-effect-discovery.mjs +90 -5
- package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +24 -3
- package/dist/esm/native-type-checker.mjs +68 -22
- package/dist/esm/release-identity.mjs +1 -1
- package/dist/esm/renderer-build-identity.mjs +13 -3
- package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
- package/dist/esm-node/build-config/build-environment.mjs +7 -5
- package/dist/esm-node/build-config/internal-effect-discovery.mjs +90 -5
- package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +24 -3
- package/dist/esm-node/native-type-checker.mjs +68 -22
- package/dist/esm-node/release-identity.mjs +1 -1
- package/dist/esm-node/renderer-build-identity.mjs +13 -3
- package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +18 -1
- package/dist/types/build-config/build-environment.d.ts +3 -1
- package/dist/types/build-config/internal-effect-discovery.d.ts +3 -1
- package/dist/types/cloudflare/worker-manifest.d.ts +3 -2
- package/dist/types/config.d.ts +4 -0
- package/dist/types/native-type-checker.d.ts +4 -2
- package/dist/types/release-identity.d.ts +10 -0
- package/dist/types/renderer-build-identity.d.ts +12 -1
- package/package.json +27 -27
- package/src/build-config/build-environment.ts +11 -9
- package/src/build-config/internal-effect-discovery.ts +238 -19
- package/src/cloudflare/worker-manifest.ts +7 -3
- package/src/cloudflare-output-verifier/mutation-policy.ts +41 -3
- package/src/config.ts +4 -0
- package/src/native-type-checker.ts +87 -43
- package/src/release-identity.ts +11 -2
- package/src/renderer-build-identity.ts +51 -11
- 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
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
129
|
-
|
|
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]
|
|
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
|
-
|
|
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(
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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')
|
|
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
|
|
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
|
-
|
|
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
|
-
?
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
96
|
-
|
|
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 };
|