@bleedingdev/modern-js-app-tools-extensions 3.9.3-ultramodern.1 → 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.
- package/dist/cjs/build-config/build-environment.js +7 -5
- package/dist/cjs/build-config/internal-effect-discovery.js +94 -6
- 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/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/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/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
|
@@ -8,6 +8,16 @@ export declare const createUltramodernReleaseBuildMarker: ({ generationBuildMark
|
|
|
8
8
|
unitId: string;
|
|
9
9
|
}) => string;
|
|
10
10
|
export declare const resolveUltramodernSourceRevision: (workspaceRoot?: string, configuredSourceRevision?: string, environment?: Readonly<NodeJS.ProcessEnv>) => string;
|
|
11
|
+
/**
|
|
12
|
+
* The one release identity of a delivery unit, resolvable before its build.
|
|
13
|
+
*
|
|
14
|
+
* For a clean source revision the build marker is a 64-hex digest of the unit
|
|
15
|
+
* id, its generation marker and the revision. API bundles carry it, and a UI
|
|
16
|
+
* unit's renderer adopts it as its `buildId`, so contracts, release plans and
|
|
17
|
+
* Worker names derived from it before the build match the built
|
|
18
|
+
* `ultramodern-build.json`, `renderer-build.json`, chunk banners and envelope.
|
|
19
|
+
* A dirty or non-Git checkout yields the non-promotable `workspace` identity.
|
|
20
|
+
*/
|
|
11
21
|
export declare const resolveUltramodernReleaseIdentity: ({ generationBuildMarker, sourceRevision: configuredSourceRevision, unitId, workspaceRoot, environment, }: {
|
|
12
22
|
generationBuildMarker: string;
|
|
13
23
|
sourceRevision?: string;
|
|
@@ -10,7 +10,18 @@ export interface RendererBuildIdentityOptions {
|
|
|
10
10
|
mode: 'development' | 'production';
|
|
11
11
|
/** Delivery-unit app id; defaults to the application package name. */
|
|
12
12
|
appId?: string;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* The declared delivery unit's release identity, resolved before the build
|
|
15
|
+
* by `resolveUltramodernReleaseIdentity`. A promotable production build
|
|
16
|
+
* adopts its buildMarker as the buildId, so consumers that resolve the unit
|
|
17
|
+
* identity before compiling see the marker the built artifacts carry.
|
|
18
|
+
*/
|
|
19
|
+
deliveryUnit?: {
|
|
20
|
+
readonly unitId: string;
|
|
21
|
+
readonly buildMarker: string;
|
|
22
|
+
readonly sourceRevision: string;
|
|
23
|
+
};
|
|
24
|
+
/** Externally authenticated source revision (CI) for an undeclared app. */
|
|
14
25
|
sourceRevision?: string;
|
|
15
26
|
/** Actual final entry ownership, supplied by the selected renderer composition. */
|
|
16
27
|
routerBindings: RendererRouterBindings;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"directory": "packages/solutions/app-tools-extensions"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"version": "3.9.3-ultramodern.
|
|
14
|
+
"version": "3.9.3-ultramodern.10",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
17
|
"src"
|
|
@@ -172,21 +172,21 @@
|
|
|
172
172
|
}
|
|
173
173
|
},
|
|
174
174
|
"engines": {
|
|
175
|
-
"node": ">=26.
|
|
175
|
+
"node": ">=26.12.0"
|
|
176
176
|
},
|
|
177
177
|
"dependencies": {
|
|
178
|
-
"@babel/parser": "^8.0.
|
|
179
|
-
"@babel/traverse": "^8.0.
|
|
180
|
-
"@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.
|
|
181
|
-
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.
|
|
182
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.
|
|
183
|
-
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.
|
|
184
|
-
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.
|
|
185
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.
|
|
186
|
-
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.
|
|
187
|
-
"@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.3-ultramodern.
|
|
188
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.
|
|
189
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.
|
|
178
|
+
"@babel/parser": "^8.0.7",
|
|
179
|
+
"@babel/traverse": "^8.0.7",
|
|
180
|
+
"@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.10",
|
|
181
|
+
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.10",
|
|
182
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.10",
|
|
183
|
+
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.10",
|
|
184
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.10",
|
|
185
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.10",
|
|
186
|
+
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.10",
|
|
187
|
+
"@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.3-ultramodern.10",
|
|
188
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.10",
|
|
189
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.10",
|
|
190
190
|
"@swc/helpers": "^0.5.23",
|
|
191
191
|
"@vercel/nft": "^1.11.0",
|
|
192
192
|
"compression-webpack-plugin": "^12.0.0",
|
|
@@ -196,9 +196,9 @@
|
|
|
196
196
|
},
|
|
197
197
|
"peerDependencies": {
|
|
198
198
|
"@loadable/component": "5.16.7",
|
|
199
|
-
"@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.
|
|
200
|
-
"@rsbuild/core": "2.2.
|
|
201
|
-
"react": "^19.
|
|
199
|
+
"@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.10",
|
|
200
|
+
"@rsbuild/core": "2.2.13",
|
|
201
|
+
"react": "^19.3.1"
|
|
202
202
|
},
|
|
203
203
|
"peerDependenciesMeta": {
|
|
204
204
|
"@loadable/component": {
|
|
@@ -213,24 +213,24 @@
|
|
|
213
213
|
},
|
|
214
214
|
"devDependencies": {
|
|
215
215
|
"@loadable/component": "5.16.7",
|
|
216
|
-
"@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.3-ultramodern.
|
|
217
|
-
"@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.3-ultramodern.
|
|
218
|
-
"@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.3-ultramodern.
|
|
219
|
-
"@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.
|
|
216
|
+
"@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.3-ultramodern.10",
|
|
217
|
+
"@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.3-ultramodern.10",
|
|
218
|
+
"@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.3-ultramodern.10",
|
|
219
|
+
"@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.10",
|
|
220
220
|
"@module-federation/modern-js-v3": "2.9.2",
|
|
221
221
|
"@module-federation/runtime-tools": "2.9.2",
|
|
222
|
-
"@rsbuild/core": "2.2.
|
|
222
|
+
"@rsbuild/core": "2.2.13",
|
|
223
223
|
"@rslib/core": "1.0.3",
|
|
224
224
|
"@scripts/rstest-config": "2.66.0",
|
|
225
225
|
"@types/babel__traverse": "7.28.0",
|
|
226
|
-
"@types/node": "^26.6.
|
|
226
|
+
"@types/node": "^26.6.5",
|
|
227
227
|
"core-js": "^3.50.0",
|
|
228
|
-
"effect": "4.0.
|
|
229
|
-
"miniflare": "5.
|
|
228
|
+
"effect": "4.0.5",
|
|
229
|
+
"miniflare": "5.20261012.0-beta",
|
|
230
230
|
"ndepe": "^0.1.13",
|
|
231
231
|
"pg": "8.23.1",
|
|
232
|
-
"react": "^19.3.
|
|
233
|
-
"react-dom": "^19.3.
|
|
232
|
+
"react": "^19.3.1",
|
|
233
|
+
"react-dom": "^19.3.1"
|
|
234
234
|
},
|
|
235
235
|
"sideEffects": false,
|
|
236
236
|
"publishConfig": {
|
|
@@ -36,12 +36,13 @@ if (typeof owningName !== 'string' || owningName.length === 0) {
|
|
|
36
36
|
const {
|
|
37
37
|
effectCompilerDiscoveryFailureStage,
|
|
38
38
|
resolveInstalledEffectCompiler,
|
|
39
|
+
validateConfiguredEffectCompiler,
|
|
39
40
|
}: typeof import('./internal-effect-discovery') = createRequire(
|
|
40
41
|
owningModuleUrl,
|
|
41
42
|
)(`${owningName}/internal-effect-discovery`);
|
|
42
43
|
|
|
43
44
|
const EFFECT_TSGO_RESOLUTION_ERROR =
|
|
44
|
-
'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
|
+
'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.';
|
|
45
46
|
const executableEffectTsgoCompilers = new Map<string, string>();
|
|
46
47
|
|
|
47
48
|
function effectTsgoResolutionError(
|
|
@@ -58,17 +59,14 @@ function effectTsgoResolutionError(
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
function resolveExecutableEffectTsgoCompiler(compilerPath: string): string {
|
|
61
|
-
if (process.platform === 'win32') {
|
|
62
|
-
return compilerPath;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
62
|
const sourcePath = realpathSync(compilerPath);
|
|
66
63
|
const source = lstatSync(sourcePath);
|
|
67
|
-
if (!source.isFile()) {
|
|
64
|
+
if (!source.isFile() || source.size === 0) {
|
|
68
65
|
throw new Error(
|
|
69
|
-
`Effect TS-Go compiler path is not a regular file: ${sourcePath}`,
|
|
66
|
+
`Effect TS-Go compiler path is not a nonempty regular file: ${sourcePath}`,
|
|
70
67
|
);
|
|
71
68
|
}
|
|
69
|
+
if (process.platform === 'win32') return compilerPath;
|
|
72
70
|
|
|
73
71
|
try {
|
|
74
72
|
accessSync(sourcePath, constants.X_OK);
|
|
@@ -138,7 +136,9 @@ export type ResolveEffectTsgoCompilerOptions = {
|
|
|
138
136
|
};
|
|
139
137
|
|
|
140
138
|
/**
|
|
141
|
-
* Resolves the Effect
|
|
139
|
+
* Resolves the Effect-enabled native executable for checking and DTS builds.
|
|
140
|
+
* Use metadata-bound tsrs where both tsrs and the Effect provider support it.
|
|
141
|
+
* Unsupported targets use Effect-Go. Missing supported artifacts remain fatal.
|
|
142
142
|
*/
|
|
143
143
|
export function resolveEffectTsgoCompiler(
|
|
144
144
|
options: ResolveEffectTsgoCompilerOptions,
|
|
@@ -148,7 +148,9 @@ export function resolveEffectTsgoCompiler(
|
|
|
148
148
|
|
|
149
149
|
if (configuredCompiler) {
|
|
150
150
|
try {
|
|
151
|
-
|
|
151
|
+
const compiler = resolveExecutableEffectTsgoCompiler(configuredCompiler);
|
|
152
|
+
validateConfiguredEffectCompiler(compiler, options.from);
|
|
153
|
+
return compiler;
|
|
152
154
|
} catch (cause) {
|
|
153
155
|
throw effectTsgoResolutionError(
|
|
154
156
|
cause,
|
|
@@ -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';
|
|
@@ -6,13 +7,28 @@ import { fileURLToPath, type URL } from 'node:url';
|
|
|
6
7
|
const EFFECT_TSGO_PACKAGE = '@effect/tsgo';
|
|
7
8
|
const EFFECT_TSGO_BIN = 'effect-tsgo';
|
|
8
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
|
+
]);
|
|
9
18
|
type PackageJson = {
|
|
10
19
|
name?: string;
|
|
11
20
|
bin?: Record<string, string> | string;
|
|
12
21
|
version?: string;
|
|
13
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 };
|
|
14
29
|
};
|
|
15
30
|
const failureStages = new WeakMap<object, string>();
|
|
31
|
+
const reportedUnsupportedTsrsTargets = new Set<string>();
|
|
16
32
|
export function effectCompilerDiscoveryFailureStage(
|
|
17
33
|
error: unknown,
|
|
18
34
|
): string | undefined {
|
|
@@ -50,7 +66,7 @@ function resolveEffectTsgoPackage(from: string | URL): {
|
|
|
50
66
|
return { packageJsonPath, packageJson, cliPath };
|
|
51
67
|
}
|
|
52
68
|
|
|
53
|
-
function
|
|
69
|
+
function isAbsentPackage(
|
|
54
70
|
projectRequire: NodeJS.Require,
|
|
55
71
|
from: string | URL,
|
|
56
72
|
packageName: string,
|
|
@@ -98,14 +114,7 @@ function resolveNativeTypeScriptPackage(from: string | URL): string {
|
|
|
98
114
|
try {
|
|
99
115
|
packageJsonPath = projectRequire.resolve(`${packageName}/package.json`);
|
|
100
116
|
} catch (error) {
|
|
101
|
-
if (
|
|
102
|
-
isAbsentNativeTypeScriptPackage(
|
|
103
|
-
projectRequire,
|
|
104
|
-
from,
|
|
105
|
-
packageName,
|
|
106
|
-
error,
|
|
107
|
-
)
|
|
108
|
-
) {
|
|
117
|
+
if (isAbsentPackage(projectRequire, from, packageName, error)) {
|
|
109
118
|
continue;
|
|
110
119
|
}
|
|
111
120
|
throw error;
|
|
@@ -156,11 +165,215 @@ function readCompilerArtifact(filename: string): string {
|
|
|
156
165
|
return canonicalPath;
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
|
|
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. */
|
|
160
342
|
export function resolveInstalledEffectCompiler(from: string | URL): string {
|
|
161
343
|
let stage = 'Package CLI resolution';
|
|
162
344
|
try {
|
|
163
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
|
+
}
|
|
164
377
|
stage = 'Native TypeScript package resolution';
|
|
165
378
|
const typeScriptManifest = resolveNativeTypeScriptManifest(from);
|
|
166
379
|
const typeScript = JSON.parse(
|
|
@@ -208,13 +421,16 @@ export function resolveInstalledEffectCompiler(from: string | URL): string {
|
|
|
208
421
|
const metadataPath = join(dirname(effectManifest), 'lib', 'upstream.json');
|
|
209
422
|
const metadata = JSON.parse(readFileSync(metadataPath, 'utf8')) as {
|
|
210
423
|
schemaVersion?: number;
|
|
424
|
+
tags?: { typescript?: { latest?: string } };
|
|
211
425
|
components?: {
|
|
212
426
|
typescript?: Record<string, { gitHead?: string; provider?: string }>;
|
|
213
427
|
};
|
|
214
428
|
};
|
|
215
429
|
const component = metadata.components?.typescript?.[native.version];
|
|
430
|
+
const latestTypeScript = metadata.tags?.typescript?.latest;
|
|
216
431
|
if (
|
|
217
432
|
metadata.schemaVersion !== 5 ||
|
|
433
|
+
typeof latestTypeScript !== 'string' ||
|
|
218
434
|
component?.provider !== 'typescript-go' ||
|
|
219
435
|
component.gitHead !== native.gitHead
|
|
220
436
|
) {
|
|
@@ -222,15 +438,18 @@ export function resolveInstalledEffectCompiler(from: string | URL): string {
|
|
|
222
438
|
`Effect replacement metadata does not match the selected native TypeScript backend: ${metadataPath}`,
|
|
223
439
|
);
|
|
224
440
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
'
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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));
|
|
234
453
|
} catch (error) {
|
|
235
454
|
if (error && typeof error === 'object' && !failureStages.has(error))
|
|
236
455
|
failureStages.set(error, stage);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
BffEffectDataPlatformUserConfig,
|
|
4
|
+
BffEffectOpenApiUserConfig,
|
|
5
|
+
} from '@modern-js/server-runtime-extensions/server-config';
|
|
3
6
|
import { fs as fse } from '@modern-js/utils';
|
|
4
7
|
import { getCloudflareWorkerRouteDataEntryName } from '../cloudflare-output-contract';
|
|
5
8
|
import { readRouteSpec } from './artifacts';
|
|
@@ -71,8 +74,9 @@ const createEffectBffWorkerManifest = (
|
|
|
71
74
|
},
|
|
72
75
|
};
|
|
73
76
|
|
|
74
|
-
const openapi = bff?.effect?.openapi;
|
|
75
|
-
const dataPlatform =
|
|
77
|
+
const openapi: BffEffectOpenApiUserConfig | undefined = bff?.effect?.openapi;
|
|
78
|
+
const dataPlatform: BffEffectDataPlatformUserConfig | undefined =
|
|
79
|
+
bff?.effect?.dataPlatform;
|
|
76
80
|
|
|
77
81
|
return {
|
|
78
82
|
...(openapi === undefined ? {} : { openapi }),
|
package/src/config.ts
CHANGED
|
@@ -247,6 +247,10 @@ export interface CloudflareWorkerDeployConfig {
|
|
|
247
247
|
* `env[binding].fetch(request)`.
|
|
248
248
|
*/
|
|
249
249
|
services?: CloudflareWorkerServiceBindingConfig[];
|
|
250
|
+
/** Native Worker context profiles, registered before federated exposes load. */
|
|
251
|
+
federation?: {
|
|
252
|
+
contextProfiles?: readonly string[];
|
|
253
|
+
};
|
|
250
254
|
/**
|
|
251
255
|
* First-class Workers VPC service bindings to private origins reached
|
|
252
256
|
* through a Cloudflare Tunnel. Modern.js writes these to `wrangler.json`
|