@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21
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/backend-federation-build/codegen.js +267 -0
- package/dist/cjs/backend-federation-build/config.js +239 -0
- package/dist/cjs/backend-federation-build/emit.js +154 -0
- package/dist/cjs/backend-federation-build/index.js +53 -0
- package/dist/cjs/build-config/build-environment.js +129 -0
- package/dist/cjs/build-config/precompress/plugin.js +124 -0
- package/dist/cjs/build-config/precompress/types.js +18 -0
- package/dist/cjs/build-config/public.js +43 -0
- package/dist/cjs/build-config/remote-address.js +58 -0
- package/dist/cjs/cloudflare/artifacts.js +8 -19
- package/dist/cjs/cloudflare/constants.js +1 -1
- package/dist/cjs/cloudflare/delivery-unit.js +23 -42
- package/dist/cjs/cloudflare/index.js +10 -2
- package/dist/cjs/cloudflare/worker-manifest.js +13 -4
- package/dist/cjs/cloudflare/wrangler-config.js +35 -7
- package/dist/cjs/cloudflare-builder.js +252 -75
- package/dist/cjs/cloudflare-output-contract.js +69 -3
- package/dist/cjs/cloudflare-output-verifier/identity.js +29 -27
- package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
- package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
- package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
- package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +14 -6
- package/dist/cjs/config.js +34 -1
- package/dist/cjs/deploy-output/npmAliases.js +251 -0
- package/dist/cjs/deploy-output/plugin.js +97 -0
- package/dist/cjs/deploy-output/public-assets.js +146 -0
- package/dist/cjs/deploy-output/target.js +104 -0
- package/dist/cjs/deploy-output/trace-files.js +90 -0
- package/dist/cjs/native-type-checker.js +193 -0
- package/dist/cjs/policy-defaults.js +101 -0
- package/dist/cjs/release-envelope/framework-output.js +153 -79
- package/dist/cjs/release-envelope/index.js +10 -4
- package/dist/cjs/release-envelope/plugin.js +18 -13
- package/dist/cjs/release-identity.js +5 -6
- package/dist/cjs/runtime-package-resolution.js +118 -0
- package/dist/cjs/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
- package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
- package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
- package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
- package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm/backend-federation-build/codegen.mjs +216 -0
- package/dist/esm/backend-federation-build/config.mjs +163 -0
- package/dist/esm/backend-federation-build/emit.mjs +103 -0
- package/dist/esm/backend-federation-build/index.mjs +1 -0
- package/dist/esm/build-config/build-environment.mjs +88 -0
- package/dist/esm/build-config/precompress/plugin.mjs +76 -0
- package/dist/esm/build-config/precompress/types.mjs +0 -0
- package/dist/esm/build-config/public.mjs +1 -0
- package/dist/esm/build-config/remote-address.mjs +20 -0
- package/dist/esm/cloudflare/artifacts.mjs +8 -19
- package/dist/esm/cloudflare/constants.mjs +1 -1
- package/dist/esm/cloudflare/delivery-unit.mjs +17 -36
- package/dist/esm/cloudflare/index.mjs +10 -2
- package/dist/esm/cloudflare/worker-manifest.mjs +13 -4
- package/dist/esm/cloudflare/wrangler-config.mjs +35 -7
- package/dist/esm/cloudflare-builder.mjs +246 -75
- package/dist/esm/cloudflare-output-contract.mjs +59 -2
- package/dist/esm/cloudflare-output-verifier/identity.mjs +27 -25
- package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
- package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
- package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
- package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +15 -7
- package/dist/esm/config.mjs +3 -0
- package/dist/esm/deploy-output/npmAliases.mjs +199 -0
- package/dist/esm/deploy-output/plugin.mjs +46 -0
- package/dist/esm/deploy-output/public-assets.mjs +82 -0
- package/dist/esm/deploy-output/target.mjs +57 -0
- package/dist/esm/deploy-output/trace-files.mjs +38 -0
- package/dist/esm/native-type-checker.mjs +142 -0
- package/dist/esm/policy-defaults.mjs +45 -0
- package/dist/esm/release-envelope/framework-output.mjs +130 -56
- package/dist/esm/release-envelope/index.mjs +10 -4
- package/dist/esm/release-envelope/plugin.mjs +18 -13
- package/dist/esm/release-identity.mjs +5 -6
- package/dist/esm/runtime-package-resolution.mjs +60 -0
- package/dist/esm/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
- package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
- package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
- package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
- package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/esm-node/backend-federation-build/codegen.mjs +217 -0
- package/dist/esm-node/backend-federation-build/config.mjs +164 -0
- package/dist/esm-node/backend-federation-build/emit.mjs +104 -0
- package/dist/esm-node/backend-federation-build/index.mjs +2 -0
- package/dist/esm-node/build-config/build-environment.mjs +89 -0
- package/dist/esm-node/build-config/precompress/plugin.mjs +77 -0
- package/dist/esm-node/build-config/precompress/types.mjs +1 -0
- package/dist/esm-node/build-config/public.mjs +2 -0
- package/dist/esm-node/build-config/remote-address.mjs +21 -0
- package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
- package/dist/esm-node/cloudflare/constants.mjs +1 -1
- package/dist/esm-node/cloudflare/delivery-unit.mjs +17 -36
- package/dist/esm-node/cloudflare/index.mjs +10 -2
- package/dist/esm-node/cloudflare/worker-manifest.mjs +13 -4
- package/dist/esm-node/cloudflare/wrangler-config.mjs +35 -7
- package/dist/esm-node/cloudflare-builder.mjs +246 -75
- package/dist/esm-node/cloudflare-output-contract.mjs +59 -2
- package/dist/esm-node/cloudflare-output-verifier/identity.mjs +27 -25
- package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
- package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
- package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
- package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +15 -7
- package/dist/esm-node/config.mjs +3 -0
- package/dist/esm-node/deploy-output/npmAliases.mjs +200 -0
- package/dist/esm-node/deploy-output/plugin.mjs +49 -0
- package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
- package/dist/esm-node/deploy-output/target.mjs +58 -0
- package/dist/esm-node/deploy-output/trace-files.mjs +39 -0
- package/dist/esm-node/native-type-checker.mjs +143 -0
- package/dist/esm-node/policy-defaults.mjs +46 -0
- package/dist/esm-node/release-envelope/framework-output.mjs +130 -56
- package/dist/esm-node/release-envelope/index.mjs +10 -4
- package/dist/esm-node/release-envelope/plugin.mjs +18 -13
- package/dist/esm-node/release-identity.mjs +5 -6
- package/dist/esm-node/runtime-package-resolution.mjs +61 -0
- package/dist/esm-node/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
- package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
- package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
- package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
- package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/types/backend-federation-build/codegen.d.ts +116 -0
- package/dist/types/backend-federation-build/config.d.ts +121 -0
- package/dist/types/backend-federation-build/emit.d.ts +21 -0
- package/dist/types/backend-federation-build/index.d.ts +2 -0
- package/dist/types/build-config/build-environment.d.ts +14 -0
- package/dist/types/build-config/precompress/plugin.d.ts +4 -0
- package/dist/types/build-config/precompress/types.d.ts +19 -0
- package/dist/types/build-config/public.d.ts +2 -0
- package/dist/types/build-config/remote-address.d.ts +3 -0
- package/dist/types/cloudflare/artifacts.d.ts +7 -6
- package/dist/types/cloudflare/constants.d.ts +1 -1
- package/dist/types/cloudflare/delivery-unit.d.ts +3 -3
- package/dist/types/cloudflare/worker-manifest.d.ts +2 -2
- package/dist/types/cloudflare/wrangler-config.d.ts +6 -0
- package/dist/types/cloudflare-builder.d.ts +49 -9
- package/dist/types/cloudflare-output-contract.d.ts +4 -1
- package/dist/types/cloudflare-output-verifier/identity.d.ts +1 -1
- package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
- package/dist/types/config.d.ts +29 -1
- package/dist/types/deploy-output/npmAliases.d.ts +14 -0
- package/dist/types/deploy-output/plugin.d.ts +35 -0
- package/dist/types/deploy-output/public-assets.d.ts +51 -0
- package/dist/types/deploy-output/target.d.ts +29 -0
- package/dist/types/deploy-output/trace-files.d.ts +17 -0
- package/dist/types/native-type-checker.d.ts +15 -0
- package/dist/types/policy-defaults.d.ts +46 -0
- package/dist/types/precompress/LICENSE +20 -0
- package/dist/types/precompress/index.d.ts +76 -0
- package/dist/types/release-envelope/framework-output.d.ts +8 -3
- package/dist/types/release-envelope/plugin.d.ts +7 -7
- package/dist/types/runtime-package-resolution.d.ts +28 -0
- package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
- package/package.json +97 -15
- package/src/backend-federation-build/codegen.ts +254 -0
- package/src/backend-federation-build/config.ts +492 -0
- package/src/backend-federation-build/emit.ts +213 -0
- package/src/backend-federation-build/index.ts +2 -0
- package/src/build-config/build-environment.ts +160 -0
- package/src/build-config/precompress/plugin.ts +140 -0
- package/src/build-config/precompress/types.ts +26 -0
- package/src/build-config/public.ts +5 -0
- package/src/build-config/remote-address.ts +33 -0
- package/src/cloudflare/artifacts.ts +22 -43
- package/src/cloudflare/constants.ts +1 -1
- package/src/cloudflare/delivery-unit.ts +42 -53
- package/src/cloudflare/index.ts +24 -11
- package/src/cloudflare/worker-manifest.ts +20 -3
- package/src/cloudflare/wrangler-config.ts +86 -10
- package/src/cloudflare-builder.ts +475 -151
- package/src/cloudflare-output-contract.ts +70 -0
- package/src/cloudflare-output-verifier/identity.ts +5 -1
- package/src/cloudflare-output-verifier/index.ts +20 -0
- package/src/cloudflare-output-verifier/manifest.ts +77 -0
- package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
- package/src/cloudflare-output-verifier/worker-bundles.ts +32 -14
- package/src/config.ts +34 -6
- package/src/deploy-output/npmAliases.ts +382 -0
- package/src/deploy-output/plugin.ts +86 -0
- package/src/deploy-output/public-assets.ts +224 -0
- package/src/deploy-output/target.ts +106 -0
- package/src/deploy-output/trace-files.ts +67 -0
- package/src/native-type-checker.ts +183 -0
- package/src/policy-defaults.ts +127 -0
- package/src/release-envelope/framework-output.ts +346 -94
- package/src/release-envelope/index.ts +26 -5
- package/src/release-envelope/plugin.ts +43 -40
- package/src/release-identity.ts +13 -2
- package/src/runtime-package-resolution.ts +115 -0
- package/src/templates/cloudflare-entry.001-bootstrap-security.mjs +0 -3
- package/src/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
- package/src/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
- package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
- package/src/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
- package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
- package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
- package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
- package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
- package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
- package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
- package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
- package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
- package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
- package/src/templates/cloudflare-worker-path.mjs +0 -98
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import {
|
|
4
|
+
accessSync,
|
|
5
|
+
chmodSync,
|
|
6
|
+
constants,
|
|
7
|
+
lstatSync,
|
|
8
|
+
mkdirSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
realpathSync,
|
|
11
|
+
renameSync,
|
|
12
|
+
rmSync,
|
|
13
|
+
writeFileSync,
|
|
14
|
+
} from 'node:fs';
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
import { tmpdir } from 'node:os';
|
|
17
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
18
|
+
import type { URL } from 'node:url';
|
|
19
|
+
|
|
20
|
+
const EFFECT_TSGO_PACKAGE = '@effect/tsgo';
|
|
21
|
+
const EFFECT_TSGO_BIN = 'effect-tsgo';
|
|
22
|
+
const EFFECT_TSGO_RESOLUTION_ERROR =
|
|
23
|
+
'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.';
|
|
24
|
+
const executableEffectTsgoCompilers = new Map<string, string>();
|
|
25
|
+
|
|
26
|
+
type PackageJson = {
|
|
27
|
+
bin?: Record<string, string> | string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function resolveEffectTsgoCli(from: string | URL): string {
|
|
31
|
+
const projectRequire = createRequire(from);
|
|
32
|
+
const packageJsonPath = projectRequire.resolve(
|
|
33
|
+
`${EFFECT_TSGO_PACKAGE}/package.json`,
|
|
34
|
+
);
|
|
35
|
+
const packageJson = JSON.parse(
|
|
36
|
+
readFileSync(packageJsonPath, 'utf-8'),
|
|
37
|
+
) as PackageJson;
|
|
38
|
+
const bin =
|
|
39
|
+
typeof packageJson.bin === 'string'
|
|
40
|
+
? packageJson.bin
|
|
41
|
+
: packageJson.bin?.[EFFECT_TSGO_BIN];
|
|
42
|
+
|
|
43
|
+
if (!bin) {
|
|
44
|
+
throw new Error(EFFECT_TSGO_RESOLUTION_ERROR);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return resolve(dirname(packageJsonPath), bin);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function resolveExecutableEffectTsgoCompiler(compilerPath: string): string {
|
|
51
|
+
if (process.platform === 'win32') {
|
|
52
|
+
return compilerPath;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const sourcePath = realpathSync(compilerPath);
|
|
56
|
+
const source = lstatSync(sourcePath);
|
|
57
|
+
if (!source.isFile()) {
|
|
58
|
+
throw new Error(EFFECT_TSGO_RESOLUTION_ERROR);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
accessSync(sourcePath, constants.X_OK);
|
|
63
|
+
return compilerPath;
|
|
64
|
+
} catch {
|
|
65
|
+
// npm currently publishes Effect TS-Go's native Unix files without an
|
|
66
|
+
// execute bit. Keep node_modules immutable and materialize a private copy.
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const cachedCompiler = executableEffectTsgoCompilers.get(sourcePath);
|
|
70
|
+
if (cachedCompiler) {
|
|
71
|
+
try {
|
|
72
|
+
accessSync(cachedCompiler, constants.X_OK);
|
|
73
|
+
return cachedCompiler;
|
|
74
|
+
} catch {
|
|
75
|
+
executableEffectTsgoCompilers.delete(sourcePath);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const compilerBytes = readFileSync(sourcePath);
|
|
80
|
+
const compilerDigest = createHash('sha256')
|
|
81
|
+
.update(compilerBytes)
|
|
82
|
+
.digest('hex');
|
|
83
|
+
const compilerDirectory = join(
|
|
84
|
+
tmpdir(),
|
|
85
|
+
'modern-js',
|
|
86
|
+
'effect-tsgo',
|
|
87
|
+
compilerDigest,
|
|
88
|
+
);
|
|
89
|
+
mkdirSync(compilerDirectory, { recursive: true, mode: 0o700 });
|
|
90
|
+
const executableCompiler = join(compilerDirectory, basename(sourcePath));
|
|
91
|
+
try {
|
|
92
|
+
accessSync(executableCompiler, constants.X_OK);
|
|
93
|
+
} catch {
|
|
94
|
+
const temporaryCompiler = join(
|
|
95
|
+
compilerDirectory,
|
|
96
|
+
`.${basename(sourcePath)}.${process.pid}.tmp`,
|
|
97
|
+
);
|
|
98
|
+
rmSync(temporaryCompiler, { force: true });
|
|
99
|
+
try {
|
|
100
|
+
writeFileSync(temporaryCompiler, compilerBytes, {
|
|
101
|
+
flag: 'wx',
|
|
102
|
+
mode: 0o700,
|
|
103
|
+
});
|
|
104
|
+
chmodSync(temporaryCompiler, 0o700);
|
|
105
|
+
renameSync(temporaryCompiler, executableCompiler);
|
|
106
|
+
} finally {
|
|
107
|
+
rmSync(temporaryCompiler, { force: true });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
accessSync(executableCompiler, constants.X_OK);
|
|
111
|
+
executableEffectTsgoCompilers.set(sourcePath, executableCompiler);
|
|
112
|
+
return executableCompiler;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Reads an environment variable while keeping generated build configs free of
|
|
117
|
+
* direct process access.
|
|
118
|
+
*/
|
|
119
|
+
export function getBuildConfigEnvironment(name: string): string | undefined {
|
|
120
|
+
return process.env[name];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type ResolveEffectTsgoCompilerOptions = {
|
|
124
|
+
/** Module URL or absolute filename used to resolve the consumer's compiler. */
|
|
125
|
+
from: string | URL;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Resolves the Effect TS-Go executable used by Module Federation DTS builds.
|
|
130
|
+
*/
|
|
131
|
+
export function resolveEffectTsgoCompiler(
|
|
132
|
+
options: ResolveEffectTsgoCompilerOptions,
|
|
133
|
+
): string {
|
|
134
|
+
const configuredCompiler =
|
|
135
|
+
getBuildConfigEnvironment('EFFECT_TSGO_BIN')?.trim();
|
|
136
|
+
|
|
137
|
+
if (configuredCompiler) {
|
|
138
|
+
try {
|
|
139
|
+
return resolveExecutableEffectTsgoCompiler(configuredCompiler);
|
|
140
|
+
} catch {
|
|
141
|
+
throw new Error(EFFECT_TSGO_RESOLUTION_ERROR);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const compiler = execFileSync(
|
|
147
|
+
process.execPath,
|
|
148
|
+
[resolveEffectTsgoCli(options.from), 'get-exe-path'],
|
|
149
|
+
{ encoding: 'utf-8' },
|
|
150
|
+
).trim();
|
|
151
|
+
|
|
152
|
+
if (compiler) {
|
|
153
|
+
return resolveExecutableEffectTsgoCompiler(compiler);
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
// Use one stable error for package, platform-binary, and CLI failures.
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
throw new Error(EFFECT_TSGO_RESOLUTION_ERROR);
|
|
160
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { constants as zlibConstants } from 'node:zlib';
|
|
2
|
+
import type { RsbuildPlugin } from '@rsbuild/core';
|
|
3
|
+
import CompressionPlugin from 'compression-webpack-plugin';
|
|
4
|
+
import type { PrecompressConfig } from './types';
|
|
5
|
+
|
|
6
|
+
export type { PrecompressCodecOptions, PrecompressConfig } from './types';
|
|
7
|
+
|
|
8
|
+
type CompressionPluginOptions = NonNullable<
|
|
9
|
+
ConstructorParameters<typeof CompressionPlugin>[0]
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
const DEFAULT_PRECOMPRESS_TEST = /\.(js|mjs|cjs|css|html|svg|json|map)$/i;
|
|
13
|
+
const DEFAULT_PRECOMPRESS_THRESHOLD = 10 * 1024;
|
|
14
|
+
const DEFAULT_PRECOMPRESS_MIN_RATIO = 0.8;
|
|
15
|
+
|
|
16
|
+
const createDefaultGzipOptions = (): CompressionPluginOptions => ({
|
|
17
|
+
algorithm: 'gzip',
|
|
18
|
+
filename: '[path][base].gz',
|
|
19
|
+
test: DEFAULT_PRECOMPRESS_TEST,
|
|
20
|
+
threshold: DEFAULT_PRECOMPRESS_THRESHOLD,
|
|
21
|
+
minRatio: DEFAULT_PRECOMPRESS_MIN_RATIO,
|
|
22
|
+
compressionOptions: {
|
|
23
|
+
level: 6,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const createDefaultBrotliOptions = (): CompressionPluginOptions => ({
|
|
28
|
+
algorithm: 'brotliCompress',
|
|
29
|
+
filename: '[path][base].br',
|
|
30
|
+
test: DEFAULT_PRECOMPRESS_TEST,
|
|
31
|
+
threshold: DEFAULT_PRECOMPRESS_THRESHOLD,
|
|
32
|
+
minRatio: DEFAULT_PRECOMPRESS_MIN_RATIO,
|
|
33
|
+
compressionOptions: {
|
|
34
|
+
params: {
|
|
35
|
+
[zlibConstants.BROTLI_PARAM_QUALITY]: 9,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const mergeCompressionOptions = (
|
|
41
|
+
base: CompressionPluginOptions,
|
|
42
|
+
next: Partial<CompressionPluginOptions>,
|
|
43
|
+
): CompressionPluginOptions => {
|
|
44
|
+
const merged = {
|
|
45
|
+
...base,
|
|
46
|
+
...next,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
if (base.compressionOptions || next.compressionOptions) {
|
|
50
|
+
const baseCompressionOptions = base.compressionOptions as
|
|
51
|
+
| Record<string, unknown>
|
|
52
|
+
| undefined;
|
|
53
|
+
const nextCompressionOptions = next.compressionOptions as
|
|
54
|
+
| Record<string, unknown>
|
|
55
|
+
| undefined;
|
|
56
|
+
const mergedCompressionOptions = {
|
|
57
|
+
...baseCompressionOptions,
|
|
58
|
+
...nextCompressionOptions,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (baseCompressionOptions?.params || nextCompressionOptions?.params) {
|
|
62
|
+
mergedCompressionOptions.params = {
|
|
63
|
+
...(baseCompressionOptions?.params as Record<string, unknown>),
|
|
64
|
+
...(nextCompressionOptions?.params as Record<string, unknown>),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
merged.compressionOptions = mergedCompressionOptions;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return merged;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const resolveCodecOptions = (
|
|
75
|
+
codecConfig: PrecompressConfig['gzip'] | PrecompressConfig['brotli'],
|
|
76
|
+
createDefaultOptions: () => CompressionPluginOptions,
|
|
77
|
+
): CompressionPluginOptions | null => {
|
|
78
|
+
if (codecConfig === false) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (codecConfig === undefined || codecConfig === true) {
|
|
83
|
+
return createDefaultOptions();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return mergeCompressionOptions(createDefaultOptions(), codecConfig);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const resolvePrecompressConfig = (
|
|
90
|
+
precompress: boolean | PrecompressConfig | undefined,
|
|
91
|
+
): PrecompressConfig | false => {
|
|
92
|
+
if (precompress === false || precompress === undefined) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (precompress === true) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return precompress;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const builderPluginAdapterPrecompress = (
|
|
104
|
+
precompress: boolean | PrecompressConfig | undefined,
|
|
105
|
+
): RsbuildPlugin => ({
|
|
106
|
+
name: 'builder-plugin-adapter-modern-precompress',
|
|
107
|
+
|
|
108
|
+
setup(api) {
|
|
109
|
+
api.modifyBundlerChain((chain, { isProd, target }) => {
|
|
110
|
+
if (!isProd || target !== 'web') {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const precompressConfig = resolvePrecompressConfig(precompress);
|
|
115
|
+
if (precompressConfig === false) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const gzipOptions = resolveCodecOptions(
|
|
120
|
+
precompressConfig.gzip,
|
|
121
|
+
createDefaultGzipOptions,
|
|
122
|
+
);
|
|
123
|
+
if (gzipOptions) {
|
|
124
|
+
chain
|
|
125
|
+
.plugin('modern-precompress-gzip')
|
|
126
|
+
.use(CompressionPlugin, [gzipOptions]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const brotliOptions = resolveCodecOptions(
|
|
130
|
+
precompressConfig.brotli,
|
|
131
|
+
createDefaultBrotliOptions,
|
|
132
|
+
);
|
|
133
|
+
if (brotliOptions) {
|
|
134
|
+
chain
|
|
135
|
+
.plugin('modern-precompress-brotli')
|
|
136
|
+
.use(CompressionPlugin, [brotliOptions]);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type CompressionPlugin from 'compression-webpack-plugin';
|
|
2
|
+
|
|
3
|
+
type CompressionPluginOptions = NonNullable<
|
|
4
|
+
ConstructorParameters<typeof CompressionPlugin>[0]
|
|
5
|
+
>;
|
|
6
|
+
|
|
7
|
+
export type PrecompressCodecOptions =
|
|
8
|
+
| boolean
|
|
9
|
+
| Partial<CompressionPluginOptions>;
|
|
10
|
+
|
|
11
|
+
export interface PrecompressConfig {
|
|
12
|
+
/**
|
|
13
|
+
* Configure gzip precompression options.
|
|
14
|
+
* `true` means using default options.
|
|
15
|
+
* `false` means disabling gzip precompression.
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
gzip?: PrecompressCodecOptions;
|
|
19
|
+
/**
|
|
20
|
+
* Configure brotli precompression options.
|
|
21
|
+
* `true` means using default options.
|
|
22
|
+
* `false` means disabling brotli precompression.
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
brotli?: PrecompressCodecOptions;
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BrowserManifestAddressOptions,
|
|
3
|
+
resolveBrowserManifestAddress,
|
|
4
|
+
} from '@modern-js/surface-resolution';
|
|
5
|
+
import { resolveDeployTarget } from '../deploy-output/target';
|
|
6
|
+
import { getBuildConfigEnvironment } from './build-environment';
|
|
7
|
+
|
|
8
|
+
/** Adapt build environment leases and MF's name@URL syntax to discovery policy. */
|
|
9
|
+
export function createRemoteManifestUrl(
|
|
10
|
+
options: BrowserManifestAddressOptions,
|
|
11
|
+
): string {
|
|
12
|
+
const env: Record<string, string | undefined> = {
|
|
13
|
+
...Object.fromEntries(
|
|
14
|
+
[
|
|
15
|
+
options.manifestEnv,
|
|
16
|
+
options.publicUrlEnv,
|
|
17
|
+
'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
|
|
18
|
+
].map(name => [name, getBuildConfigEnvironment(name)]),
|
|
19
|
+
),
|
|
20
|
+
MODERNJS_DEPLOY: resolveDeployTarget().target,
|
|
21
|
+
};
|
|
22
|
+
const address = resolveBrowserManifestAddress(
|
|
23
|
+
env,
|
|
24
|
+
options,
|
|
25
|
+
getBuildConfigEnvironment('NODE_ENV') ?? 'production',
|
|
26
|
+
);
|
|
27
|
+
if (!address.ok)
|
|
28
|
+
throw new Error(`Remote ${options.mfName}: ${address.reason}`);
|
|
29
|
+
return (
|
|
30
|
+
env[options.manifestEnv]?.trim() ||
|
|
31
|
+
`${options.mfName}@${address.manifestUrl}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { fs as fse } from '@modern-js/utils';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import type { CloudflareWorkerArtifactConfig } from '../config';
|
|
4
|
+
import {
|
|
5
|
+
CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
6
|
+
normalizeDeclaredPublicAssets,
|
|
7
|
+
stageDeclaredPublicAssets,
|
|
8
|
+
} from '../deploy-output/public-assets';
|
|
7
9
|
import {
|
|
8
10
|
RESERVED_ARTIFACT_DESTINATION_DIRECTORIES,
|
|
9
11
|
RESERVED_ARTIFACT_DESTINATION_FILES,
|
|
@@ -54,34 +56,12 @@ export const getCloudflareArtifacts = (modernConfig: CloudflareModernConfig) =>
|
|
|
54
56
|
normalizeCloudflareArtifact,
|
|
55
57
|
);
|
|
56
58
|
|
|
57
|
-
const normalizeCloudflarePublicAsset = (
|
|
58
|
-
asset: CloudflareWorkerPublicAssetConfig,
|
|
59
|
-
index: number,
|
|
60
|
-
) => {
|
|
61
|
-
const from = normalizeRelativePath(
|
|
62
|
-
asset.from,
|
|
63
|
-
`deploy.worker.publicAssets[${index}].from`,
|
|
64
|
-
'app root',
|
|
65
|
-
);
|
|
66
|
-
const to = normalizeRelativePath(
|
|
67
|
-
asset.to,
|
|
68
|
-
`deploy.worker.publicAssets[${index}].to`,
|
|
69
|
-
'Cloudflare public output',
|
|
70
|
-
{ allowRoot: true },
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
from,
|
|
75
|
-
to,
|
|
76
|
-
index,
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
|
|
80
59
|
export const getCloudflarePublicAssets = (
|
|
81
60
|
modernConfig: CloudflareModernConfig,
|
|
82
61
|
) =>
|
|
83
|
-
(
|
|
84
|
-
|
|
62
|
+
normalizeDeclaredPublicAssets(
|
|
63
|
+
modernConfig.deploy?.worker?.publicAssets,
|
|
64
|
+
CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
85
65
|
);
|
|
86
66
|
|
|
87
67
|
export const copyCloudflareArtifacts = async (
|
|
@@ -102,23 +82,22 @@ export const copyCloudflareArtifacts = async (
|
|
|
102
82
|
}
|
|
103
83
|
};
|
|
104
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Stage `deploy.worker.publicAssets` into Worker Static Assets.
|
|
87
|
+
*
|
|
88
|
+
* @returns the staged files relative to the Cloudflare output root.
|
|
89
|
+
*/
|
|
105
90
|
export const copyCloudflarePublicAssets = async (
|
|
106
91
|
appDirectory: string,
|
|
107
|
-
|
|
92
|
+
outputDirectory: string,
|
|
108
93
|
publicAssets: ReturnType<typeof getCloudflarePublicAssets>,
|
|
109
|
-
) =>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await fse.copy(sourcePath, path.join(publicDirectory, asset.to));
|
|
120
|
-
}
|
|
121
|
-
};
|
|
94
|
+
) =>
|
|
95
|
+
stageDeclaredPublicAssets({
|
|
96
|
+
appDirectory,
|
|
97
|
+
outputDirectory,
|
|
98
|
+
assets: publicAssets,
|
|
99
|
+
scope: CLOUDFLARE_PUBLIC_ASSET_SCOPE,
|
|
100
|
+
});
|
|
122
101
|
|
|
123
102
|
export const copyCloudflareD1Migrations = async (
|
|
124
103
|
appDirectory: string,
|
|
@@ -34,7 +34,7 @@ export const BFF_EFFECT_WORKER_ENTRY = `${WORKER_BUNDLE_DIRECTORY}/__modern_bff_
|
|
|
34
34
|
export const BFF_EFFECT_WORKER_DISPATCHER_EXPORT =
|
|
35
35
|
'__modern_create_effect_bff_dispatcher';
|
|
36
36
|
export const EFFECT_BFF_CLOUDFLARE_IMPORT_GUIDANCE =
|
|
37
|
-
'Ensure the Effect API entry exists at api/index.ts or bff.effect.entry, and import Cloudflare edge handlers from @modern-js/
|
|
37
|
+
'Ensure the Effect API entry exists at api/index.ts or bff.effect.entry, and import Cloudflare edge handlers from @modern-js/bff-effect/effect-edge instead of lambda/Hono server helpers.';
|
|
38
38
|
export const DEFAULT_COMPATIBILITY_DATE = '2026-06-02';
|
|
39
39
|
export const COMPATIBILITY_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
|
|
40
40
|
export const REQUIRED_COMPATIBILITY_FLAGS =
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { fs as fse } from '@modern-js/utils';
|
|
3
2
|
import {
|
|
4
3
|
type DeliveryUnitIdentity,
|
|
5
4
|
isUltramodernBuildArtifact,
|
|
6
5
|
nonEmptyString,
|
|
7
6
|
toDeliveryUnitIdentity,
|
|
8
7
|
ULTRAMODERN_BUILD_ARTIFACT_PATH,
|
|
9
|
-
|
|
10
|
-
} from '@modern-js/utils
|
|
8
|
+
} from '@modern-js/backend-federation-contracts';
|
|
9
|
+
import { fs as fse } from '@modern-js/utils';
|
|
11
10
|
import { resolveUltramodernReleaseIdentity } from '../release-identity';
|
|
12
11
|
import { isRecord } from './utils';
|
|
13
12
|
|
|
14
|
-
const
|
|
13
|
+
const TOPOLOGY_PATH = 'topology/reference-topology.json';
|
|
15
14
|
|
|
16
15
|
export type DeliveryUnitStamp = DeliveryUnitIdentity & {
|
|
17
16
|
surfaces: {
|
|
@@ -20,7 +19,7 @@ export type DeliveryUnitStamp = DeliveryUnitIdentity & {
|
|
|
20
19
|
};
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
type
|
|
22
|
+
type TopologyAppResolution = {
|
|
24
23
|
app?: Record<string, unknown>;
|
|
25
24
|
workspaceRoot: string;
|
|
26
25
|
};
|
|
@@ -31,7 +30,7 @@ const findWorkspaceRoot = async (
|
|
|
31
30
|
let current = path.resolve(appDirectory);
|
|
32
31
|
|
|
33
32
|
for (;;) {
|
|
34
|
-
if (await fse.pathExists(path.join(current,
|
|
33
|
+
if (await fse.pathExists(path.join(current, TOPOLOGY_PATH))) {
|
|
35
34
|
return current;
|
|
36
35
|
}
|
|
37
36
|
|
|
@@ -61,34 +60,32 @@ const stampReleaseIdentity = (
|
|
|
61
60
|
};
|
|
62
61
|
};
|
|
63
62
|
|
|
64
|
-
const
|
|
63
|
+
const resolveTopologyApp = async (
|
|
65
64
|
appDirectory: string,
|
|
66
|
-
): Promise<
|
|
65
|
+
): Promise<TopologyAppResolution | undefined> => {
|
|
67
66
|
const workspaceRoot = await findWorkspaceRoot(appDirectory);
|
|
68
67
|
if (!workspaceRoot) {
|
|
69
68
|
return undefined;
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
const topology: unknown = await fse.readJSON(
|
|
72
|
+
path.join(workspaceRoot, TOPOLOGY_PATH),
|
|
73
|
+
);
|
|
74
|
+
if (
|
|
75
|
+
!isRecord(topology) ||
|
|
76
|
+
!isRecord(topology.shell) ||
|
|
77
|
+
!Array.isArray(topology.verticals) ||
|
|
78
|
+
(topology.shells !== undefined && !Array.isArray(topology.shells))
|
|
79
|
+
) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'[cloudflare-delivery-unit] Invalid declared reference topology.',
|
|
76
82
|
);
|
|
77
|
-
} catch {
|
|
78
|
-
return { workspaceRoot };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!isRecord(compactConfig)) {
|
|
82
|
-
return { workspaceRoot };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const topology = isRecord(compactConfig.topology)
|
|
86
|
-
? compactConfig.topology
|
|
87
|
-
: undefined;
|
|
88
|
-
const apps = Array.isArray(topology?.apps) ? topology.apps : undefined;
|
|
89
|
-
if (!apps) {
|
|
90
|
-
return { app: compactConfig, workspaceRoot };
|
|
91
83
|
}
|
|
84
|
+
const apps = [
|
|
85
|
+
topology.shell,
|
|
86
|
+
...topology.verticals,
|
|
87
|
+
...(Array.isArray(topology.shells) ? topology.shells : []),
|
|
88
|
+
];
|
|
92
89
|
|
|
93
90
|
const resolvedAppDirectory = path.resolve(appDirectory);
|
|
94
91
|
const app = apps.find(candidate => {
|
|
@@ -102,8 +99,13 @@ const resolveCompactApp = async (
|
|
|
102
99
|
resolvedAppDirectory
|
|
103
100
|
);
|
|
104
101
|
});
|
|
102
|
+
if (!isRecord(app)) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`[cloudflare-delivery-unit] ${appDirectory} is missing from the declared reference topology.`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
105
107
|
return {
|
|
106
|
-
|
|
108
|
+
app,
|
|
107
109
|
workspaceRoot,
|
|
108
110
|
};
|
|
109
111
|
};
|
|
@@ -127,28 +129,31 @@ const createDeliveryUnitStamp = (
|
|
|
127
129
|
|
|
128
130
|
/**
|
|
129
131
|
* Resolve the delivery-unit record declared for this app by the workspace
|
|
130
|
-
*
|
|
132
|
+
* reference topology. This is the topology source
|
|
131
133
|
* of truth the Cloudflare worker snapshot is verified against.
|
|
132
134
|
*/
|
|
133
135
|
export const resolveTopologyDeliveryUnit = async (
|
|
134
136
|
appDirectory: string,
|
|
135
137
|
): Promise<DeliveryUnitStamp | undefined> => {
|
|
136
|
-
const resolved = await
|
|
138
|
+
const resolved = await resolveTopologyApp(appDirectory);
|
|
137
139
|
if (!resolved?.app) {
|
|
138
140
|
return undefined;
|
|
139
141
|
}
|
|
140
142
|
const identity = toDeliveryUnitIdentity(resolved.app.deliveryUnit);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
if (!identity) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
'[cloudflare-delivery-unit] Declared app is missing a valid delivery-unit identity.',
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return createDeliveryUnitStamp(
|
|
149
|
+
stampReleaseIdentity(identity, resolved.workspaceRoot),
|
|
150
|
+
resolved.app,
|
|
151
|
+
);
|
|
147
152
|
};
|
|
148
153
|
|
|
149
154
|
/**
|
|
150
155
|
* Resolve the delivery-unit identity actually bundled into the worker by
|
|
151
|
-
*
|
|
156
|
+
* reading the generated `shared/ultramodern-build.json` artifact. This is the
|
|
152
157
|
* worker snapshot / declared surface source that gets stamped into the manifest.
|
|
153
158
|
*/
|
|
154
159
|
export const resolveWorkerDeliveryUnitStamp = async (
|
|
@@ -158,10 +163,6 @@ export const resolveWorkerDeliveryUnitStamp = async (
|
|
|
158
163
|
appDirectory,
|
|
159
164
|
ULTRAMODERN_BUILD_ARTIFACT_PATH,
|
|
160
165
|
);
|
|
161
|
-
const buildModulePath = path.join(
|
|
162
|
-
appDirectory,
|
|
163
|
-
ULTRAMODERN_BUILD_MODULE_PATH,
|
|
164
|
-
);
|
|
165
166
|
let identity: DeliveryUnitIdentity | undefined;
|
|
166
167
|
|
|
167
168
|
if (await fse.pathExists(buildArtifactPath)) {
|
|
@@ -170,24 +171,12 @@ export const resolveWorkerDeliveryUnitStamp = async (
|
|
|
170
171
|
return undefined;
|
|
171
172
|
}
|
|
172
173
|
identity = toDeliveryUnitIdentity(artifact.deliveryUnit);
|
|
173
|
-
} else if (await fse.pathExists(buildModulePath)) {
|
|
174
|
-
console.warn(
|
|
175
|
-
`[cloudflare] ${buildArtifactPath} missing; falling back to legacy regex parsing of ${buildModulePath}. Regenerate the workspace to emit ultramodern-build.json.`,
|
|
176
|
-
);
|
|
177
|
-
const source = await fse.readFile(buildModulePath, 'utf8');
|
|
178
|
-
identity = toDeliveryUnitIdentity({
|
|
179
|
-
buildMarker: source.match(/\bbuild:\s*['"]([^'"]+)['"]/u)?.[1],
|
|
180
|
-
unitId: source.match(/\bunitId:\s*['"]([^'"]+)['"]/u)?.[1],
|
|
181
|
-
sourceRevision: source.match(
|
|
182
|
-
/\bsourceRevision:\s*['"]([^'"]+)['"]/u,
|
|
183
|
-
)?.[1],
|
|
184
|
-
});
|
|
185
174
|
}
|
|
186
175
|
|
|
187
176
|
if (!identity) {
|
|
188
177
|
return undefined;
|
|
189
178
|
}
|
|
190
|
-
const resolved = await
|
|
179
|
+
const resolved = await resolveTopologyApp(appDirectory);
|
|
191
180
|
if (resolved) {
|
|
192
181
|
identity = stampReleaseIdentity(identity, resolved.workspaceRoot);
|
|
193
182
|
}
|