@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.4 → 3.9.0-ultramodern.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/cjs/backend-federation-build/codegen.js +256 -0
  2. package/dist/cjs/backend-federation-build/config.js +189 -0
  3. package/dist/cjs/backend-federation-build/emit.js +150 -0
  4. package/dist/cjs/backend-federation-build/index.js +53 -0
  5. package/dist/cjs/build-config/build-environment.js +268 -0
  6. package/dist/cjs/build-config/precompress/plugin.js +124 -0
  7. package/dist/cjs/build-config/precompress/types.js +18 -0
  8. package/dist/cjs/build-config/public.js +46 -0
  9. package/dist/cjs/cloudflare/constants.js +1 -1
  10. package/dist/cjs/cloudflare/delivery-unit.js +7 -16
  11. package/dist/cjs/cloudflare-output-verifier/identity.js +6 -6
  12. package/dist/cjs/config.js +29 -1
  13. package/dist/cjs/deploy-output/npmAliases.js +226 -0
  14. package/dist/cjs/deploy-output/plugin.js +76 -0
  15. package/dist/cjs/deploy-output/target.js +48 -0
  16. package/dist/cjs/native-type-checker.js +6 -3
  17. package/dist/cjs/release-envelope/framework-output.js +27 -27
  18. package/dist/cjs/release-envelope/plugin.js +2 -1
  19. package/dist/esm/backend-federation-build/codegen.mjs +205 -0
  20. package/dist/esm/backend-federation-build/config.mjs +116 -0
  21. package/dist/esm/backend-federation-build/emit.mjs +99 -0
  22. package/dist/esm/backend-federation-build/index.mjs +1 -0
  23. package/dist/esm/build-config/build-environment.mjs +224 -0
  24. package/dist/esm/build-config/precompress/plugin.mjs +76 -0
  25. package/dist/esm/build-config/precompress/types.mjs +0 -0
  26. package/dist/esm/build-config/public.mjs +1 -0
  27. package/dist/esm/cloudflare/constants.mjs +1 -1
  28. package/dist/esm/cloudflare/delivery-unit.mjs +1 -10
  29. package/dist/esm/cloudflare-output-verifier/identity.mjs +1 -1
  30. package/dist/esm/config.mjs +1 -0
  31. package/dist/esm/deploy-output/npmAliases.mjs +174 -0
  32. package/dist/esm/deploy-output/plugin.mjs +28 -0
  33. package/dist/esm/deploy-output/target.mjs +10 -0
  34. package/dist/esm/native-type-checker.mjs +6 -3
  35. package/dist/esm/release-envelope/framework-output.mjs +1 -1
  36. package/dist/esm/release-envelope/plugin.mjs +2 -1
  37. package/dist/esm-node/backend-federation-build/codegen.mjs +206 -0
  38. package/dist/esm-node/backend-federation-build/config.mjs +117 -0
  39. package/dist/esm-node/backend-federation-build/emit.mjs +100 -0
  40. package/dist/esm-node/backend-federation-build/index.mjs +2 -0
  41. package/dist/esm-node/build-config/build-environment.mjs +225 -0
  42. package/dist/esm-node/build-config/precompress/plugin.mjs +77 -0
  43. package/dist/esm-node/build-config/precompress/types.mjs +1 -0
  44. package/dist/esm-node/build-config/public.mjs +2 -0
  45. package/dist/esm-node/cloudflare/constants.mjs +1 -1
  46. package/dist/esm-node/cloudflare/delivery-unit.mjs +1 -10
  47. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +1 -1
  48. package/dist/esm-node/config.mjs +1 -0
  49. package/dist/esm-node/deploy-output/npmAliases.mjs +175 -0
  50. package/dist/esm-node/deploy-output/plugin.mjs +31 -0
  51. package/dist/esm-node/deploy-output/target.mjs +11 -0
  52. package/dist/esm-node/native-type-checker.mjs +6 -3
  53. package/dist/esm-node/release-envelope/framework-output.mjs +1 -1
  54. package/dist/esm-node/release-envelope/plugin.mjs +2 -1
  55. package/dist/types/backend-federation-build/codegen.d.ts +86 -0
  56. package/dist/types/backend-federation-build/config.d.ts +102 -0
  57. package/dist/types/backend-federation-build/emit.d.ts +21 -0
  58. package/dist/types/backend-federation-build/index.d.ts +2 -0
  59. package/dist/types/build-config/build-environment.d.ts +22 -0
  60. package/dist/types/build-config/precompress/plugin.d.ts +4 -0
  61. package/dist/types/build-config/precompress/types.d.ts +19 -0
  62. package/dist/types/build-config/public.d.ts +2 -0
  63. package/dist/types/cloudflare/constants.d.ts +1 -1
  64. package/dist/types/cloudflare/delivery-unit.d.ts +2 -2
  65. package/dist/types/cloudflare/worker-manifest.d.ts +2 -2
  66. package/dist/types/cloudflare-output-verifier/identity.d.ts +1 -1
  67. package/dist/types/config.d.ts +2 -0
  68. package/dist/types/deploy-output/npmAliases.d.ts +14 -0
  69. package/dist/types/deploy-output/plugin.d.ts +15 -0
  70. package/dist/types/deploy-output/target.d.ts +6 -0
  71. package/dist/types/precompress/LICENSE +20 -0
  72. package/dist/types/precompress/index.d.ts +76 -0
  73. package/package.json +50 -8
  74. package/src/backend-federation-build/codegen.ts +245 -0
  75. package/src/backend-federation-build/config.ts +356 -0
  76. package/src/backend-federation-build/emit.ts +202 -0
  77. package/src/backend-federation-build/index.ts +2 -0
  78. package/src/build-config/build-environment.ts +404 -0
  79. package/src/build-config/precompress/plugin.ts +140 -0
  80. package/src/build-config/precompress/types.ts +26 -0
  81. package/src/build-config/public.ts +6 -0
  82. package/src/cloudflare/constants.ts +1 -1
  83. package/src/cloudflare/delivery-unit.ts +3 -20
  84. package/src/cloudflare/worker-manifest.ts +1 -0
  85. package/src/cloudflare-builder.ts +1 -0
  86. package/src/cloudflare-output-verifier/identity.ts +1 -1
  87. package/src/config.ts +7 -0
  88. package/src/deploy-output/npmAliases.ts +333 -0
  89. package/src/deploy-output/plugin.ts +49 -0
  90. package/src/deploy-output/target.ts +23 -0
  91. package/src/native-type-checker.ts +11 -3
  92. package/src/release-envelope/framework-output.ts +1 -1
  93. package/src/release-envelope/plugin.ts +5 -1
@@ -0,0 +1,175 @@
1
+ import "node:module";
2
+ import promises from "node:fs/promises";
3
+ import node_path from "node:path";
4
+ const dependencyKeys = [
5
+ 'dependencies',
6
+ 'optionalDependencies'
7
+ ];
8
+ const exactVersionPattern = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u;
9
+ async function readPackageJson(filePath) {
10
+ return JSON.parse(await promises.readFile(filePath, 'utf8'));
11
+ }
12
+ function parseNpmAlias(aliasName, specifier) {
13
+ if (!specifier.startsWith('npm:')) return;
14
+ const target = specifier.slice(4);
15
+ const versionSeparator = target.lastIndexOf('@');
16
+ if (versionSeparator <= 0 || versionSeparator === target.length - 1) throw new Error(`Invalid npm alias specifier for ${aliasName}: ${specifier}`);
17
+ return {
18
+ aliasName,
19
+ targetName: target.slice(0, versionSeparator),
20
+ targetVersion: target.slice(versionSeparator + 1)
21
+ };
22
+ }
23
+ function aliasesFromPackageJson(packageJson) {
24
+ const aliases = [];
25
+ for (const dependencyKey of dependencyKeys)for (const [aliasName, specifier] of Object.entries(packageJson[dependencyKey] ?? {})){
26
+ const alias = parseNpmAlias(aliasName, specifier);
27
+ if (alias) aliases.push(alias);
28
+ }
29
+ return aliases;
30
+ }
31
+ async function collectPackageRecords(nodeModulesDirectory) {
32
+ const records = [];
33
+ const visitedNodeModules = new Set();
34
+ const visitPackage = async (directory)=>{
35
+ const packageJsonPath = node_path.join(directory, 'package.json');
36
+ try {
37
+ const packageJson = await readPackageJson(packageJsonPath);
38
+ if (packageJson.name && packageJson.version) records.push({
39
+ directory,
40
+ packageJson
41
+ });
42
+ } catch (error) {
43
+ if ('ENOENT' !== error.code) throw error;
44
+ }
45
+ await visitNodeModules(node_path.join(directory, 'node_modules'));
46
+ };
47
+ const visitScope = async (scopeDirectory)=>{
48
+ const entries = await promises.readdir(scopeDirectory, {
49
+ withFileTypes: true
50
+ });
51
+ for (const entry of entries)if (entry.isDirectory()) await visitPackage(node_path.join(scopeDirectory, entry.name));
52
+ };
53
+ const visitNdepeStore = async (storeDirectory)=>{
54
+ const entries = await promises.readdir(storeDirectory, {
55
+ withFileTypes: true
56
+ });
57
+ for (const entry of entries)if (entry.isDirectory()) {
58
+ const entryPath = node_path.join(storeDirectory, entry.name);
59
+ if (entry.name.startsWith('@')) await visitScope(entryPath);
60
+ else await visitNodeModules(node_path.join(entryPath, 'node_modules'));
61
+ }
62
+ };
63
+ const visitNodeModules = async (directory)=>{
64
+ const resolvedDirectory = node_path.resolve(directory);
65
+ if (visitedNodeModules.has(resolvedDirectory)) return;
66
+ visitedNodeModules.add(resolvedDirectory);
67
+ let entries;
68
+ try {
69
+ entries = await promises.readdir(directory, {
70
+ withFileTypes: true
71
+ });
72
+ } catch (error) {
73
+ if ('ENOENT' === error.code) return;
74
+ throw error;
75
+ }
76
+ for (const entry of entries){
77
+ if (!entry.isDirectory()) continue;
78
+ const entryPath = node_path.join(directory, entry.name);
79
+ if ('.ndepe' === entry.name) await visitNdepeStore(entryPath);
80
+ else if (entry.name.startsWith('@')) await visitScope(entryPath);
81
+ else await visitPackage(entryPath);
82
+ }
83
+ };
84
+ await visitNodeModules(nodeModulesDirectory);
85
+ return records;
86
+ }
87
+ async function resolveAliasTarget(ownerDirectory, alias, outputDirectory) {
88
+ let directory = ownerDirectory;
89
+ const outputRoot = node_path.resolve(outputDirectory);
90
+ const resolvedOutputRoot = await promises.realpath(outputRoot);
91
+ while(directory === outputRoot || directory.startsWith(`${outputRoot}${node_path.sep}`)){
92
+ const candidate = node_path.join(directory, 'node_modules', alias.targetName);
93
+ try {
94
+ const resolvedCandidate = await promises.realpath(candidate);
95
+ if (resolvedCandidate !== resolvedOutputRoot && !resolvedCandidate.startsWith(`${resolvedOutputRoot}${node_path.sep}`)) throw new Error(`Cannot preserve npm alias ${alias.aliasName}: emitted target ${candidate} resolves outside deployment output to ${resolvedCandidate}`);
96
+ const packageJson = await readPackageJson(node_path.join(candidate, 'package.json'));
97
+ if (packageJson.name !== alias.targetName || !packageJson.version) throw new Error(`npm alias ${alias.aliasName} resolved ${candidate} to unexpected package ${String(packageJson.name)}`);
98
+ if (exactVersionPattern.test(alias.targetVersion) && packageJson.version !== alias.targetVersion) return;
99
+ return {
100
+ directory: candidate,
101
+ packageJson
102
+ };
103
+ } catch (error) {
104
+ if ('ENOENT' !== error.code) throw error;
105
+ }
106
+ if (directory === outputRoot) break;
107
+ directory = node_path.dirname(directory);
108
+ }
109
+ }
110
+ async function ensureAliasLink(ownerDirectory, alias, target) {
111
+ const aliasPath = node_path.join(ownerDirectory, 'node_modules', alias.aliasName);
112
+ await promises.mkdir(node_path.dirname(aliasPath), {
113
+ recursive: true
114
+ });
115
+ try {
116
+ const [existing, expected] = await Promise.all([
117
+ promises.realpath(aliasPath),
118
+ promises.realpath(target.directory)
119
+ ]);
120
+ if (existing === expected) return;
121
+ throw new Error(`Cannot preserve npm alias ${alias.aliasName}: ${aliasPath} already resolves to ${existing}, expected ${expected}`);
122
+ } catch (error) {
123
+ if ('ENOENT' !== error.code) throw error;
124
+ }
125
+ const linkTarget = node_path.relative(node_path.dirname(aliasPath), target.directory);
126
+ await promises.symlink(linkTarget, aliasPath, 'dir');
127
+ }
128
+ function aliasSpecifier(alias) {
129
+ return `npm:${alias.targetName}@${alias.targetVersion}`;
130
+ }
131
+ async function readPackageIdentity(entryPath) {
132
+ let directory = node_path.dirname(entryPath);
133
+ const root = node_path.parse(directory).root;
134
+ while(directory !== root){
135
+ try {
136
+ const packageJson = await readPackageJson(node_path.join(directory, 'package.json'));
137
+ if (packageJson.name && packageJson.version) return {
138
+ name: packageJson.name,
139
+ version: packageJson.version
140
+ };
141
+ } catch (error) {
142
+ if ('ENOENT' !== error.code) throw error;
143
+ }
144
+ directory = node_path.dirname(directory);
145
+ }
146
+ throw new Error(`Cannot find owning package for deployment entry ${entryPath}`);
147
+ }
148
+ async function preserveNpmAliases({ appDirectory, outputDirectory, implicitAliases = [] }) {
149
+ const records = await collectPackageRecords(node_path.join(outputDirectory, 'node_modules'));
150
+ const appPackageJson = await readPackageJson(node_path.join(appDirectory, 'package.json'));
151
+ const rootAliases = [
152
+ ...aliasesFromPackageJson(appPackageJson),
153
+ ...implicitAliases
154
+ ].filter((alias)=>alias.aliasName !== alias.targetName);
155
+ const emittedRootAliases = [];
156
+ for (const alias of rootAliases){
157
+ const target = await resolveAliasTarget(outputDirectory, alias, outputDirectory);
158
+ if (!target) {
159
+ if (implicitAliases.includes(alias)) throw new Error(`Cannot preserve implicit npm alias ${alias.aliasName}: emitted target ${alias.targetName}@${alias.targetVersion} is missing`);
160
+ continue;
161
+ }
162
+ await ensureAliasLink(outputDirectory, alias, target);
163
+ emittedRootAliases.push(alias);
164
+ }
165
+ for (const record of records)for (const alias of aliasesFromPackageJson(record.packageJson).filter((candidate)=>candidate.aliasName !== candidate.targetName)){
166
+ const target = await resolveAliasTarget(record.directory, alias, outputDirectory);
167
+ if (target) await ensureAliasLink(record.directory, alias, target);
168
+ }
169
+ const outputPackageJsonPath = node_path.join(outputDirectory, 'package.json');
170
+ const outputPackageJson = await readPackageJson(outputPackageJsonPath);
171
+ outputPackageJson.dependencies ??= {};
172
+ for (const alias of emittedRootAliases)outputPackageJson.dependencies[alias.aliasName] = aliasSpecifier(alias);
173
+ await promises.writeFile(outputPackageJsonPath, `${JSON.stringify(outputPackageJson, null, 2)}\n`);
174
+ }
175
+ export { preserveNpmAliases, readPackageIdentity };
@@ -0,0 +1,31 @@
1
+ import "node:module";
2
+ import { createRequire } from "node:module";
3
+ import node_path from "node:path";
4
+ import { preserveNpmAliases, readPackageIdentity } from "./npmAliases.mjs";
5
+ import { resolveDeployTarget as external_target_mjs_resolveDeployTarget } from "./target.mjs";
6
+ import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
7
+ var __rspack_import_meta_filename__ = __rspack_fileURLToPath(import.meta.url);
8
+ const createDeployOutputAliasesPlugin = ({ resolveDeployTarget = external_target_mjs_resolveDeployTarget } = {})=>({
9
+ name: '@modern-js/deploy-output-aliases',
10
+ setup (api) {
11
+ api.onAfterDeploy(async ()=>{
12
+ const { appDirectory, metaName } = api.getAppContext();
13
+ const config = api.getNormalizedConfig();
14
+ if ('modern-js' !== metaName && !config.deploy?.target && !process.env.MODERNJS_DEPLOY || 'node' !== resolveDeployTarget(config)) return;
15
+ const entry = createRequire(__rspack_import_meta_filename__).resolve('@modern-js/prod-server');
16
+ const identity = await readPackageIdentity(entry);
17
+ await preserveNpmAliases({
18
+ appDirectory,
19
+ outputDirectory: node_path.join(appDirectory, '.output'),
20
+ implicitAliases: [
21
+ {
22
+ aliasName: '@modern-js/prod-server',
23
+ targetName: identity.name,
24
+ targetVersion: identity.version
25
+ }
26
+ ]
27
+ });
28
+ });
29
+ }
30
+ });
31
+ export { createDeployOutputAliasesPlugin };
@@ -0,0 +1,11 @@
1
+ import "node:module";
2
+ import { provider } from "std-env";
3
+ const providerDeployTargets = {
4
+ vercel: 'vercel',
5
+ netlify: 'netlify',
6
+ cloudflare: 'cloudflare',
7
+ cloudflare_pages: 'cloudflare',
8
+ cloudflare_workers: 'cloudflare'
9
+ };
10
+ const resolveDeployTarget = (config, envDeployTarget = process.env.MODERNJS_DEPLOY, detectedProvider = provider)=>config.deploy?.target || envDeployTarget || (detectedProvider ? providerDeployTargets[detectedProvider] : void 0) || 'node';
11
+ export { resolveDeployTarget };
@@ -1,9 +1,11 @@
1
1
  import "node:module";
2
2
  import { execFile } from "node:child_process";
3
+ import { realpathSync } from "node:fs";
3
4
  import node_path from "node:path";
4
5
  import { promisify } from "node:util";
5
6
  const execute = promisify(execFile);
6
7
  const native_type_checker_name = 'UltramodernNativeTypeChecker';
8
+ const watchDependencyPath = (file)=>'win32' === process.platform ? realpathSync.native(file) : file;
7
9
  class UltramodernNativeTypeChecker {
8
10
  async check() {
9
11
  const { configFile, build } = this.options;
@@ -31,7 +33,8 @@ class UltramodernNativeTypeChecker {
31
33
  return result.stdout;
32
34
  } catch (cause) {
33
35
  const output = cause;
34
- throw new Error(`${native_type_checker_name} failed:\n${output.stdout ?? ''}${output.stderr ?? ''}`, {
36
+ const diagnostics = `${output.stdout ?? ''}${output.stderr ?? ''}`;
37
+ throw new Error(`${native_type_checker_name} failed:\n${diagnostics || (cause instanceof Error ? cause.message : String(cause))}`, {
35
38
  cause
36
39
  });
37
40
  }
@@ -62,10 +65,10 @@ class UltramodernNativeTypeChecker {
62
65
  }
63
66
  apply(compiler) {
64
67
  compiler.hooks.thisCompilation.tap(native_type_checker_name, (compilation)=>{
65
- compilation.fileDependencies.add(this.options.configFile);
66
68
  compilation.hooks.processAssets.tapPromise(native_type_checker_name, async ()=>{
67
69
  try {
68
- for (const file of (await this.watchInputs()))compilation.fileDependencies.add(file);
70
+ compilation.fileDependencies.add(watchDependencyPath(this.options.configFile));
71
+ for (const file of (await this.watchInputs()))compilation.fileDependencies.add(watchDependencyPath(file));
69
72
  await this.check();
70
73
  } catch (cause) {
71
74
  compilation.errors.push(new Error(cause instanceof Error ? cause.message : String(cause), {
@@ -2,7 +2,7 @@ import "node:module";
2
2
  import { createHash } from "node:crypto";
3
3
  import promises from "node:fs/promises";
4
4
  import node_path from "node:path";
5
- import { BACKEND_FEDERATION_MANIFEST_FILE, BACKEND_FEDERATION_REMOTE_ENTRY_FILE, ULTRAMODERN_BUILD_ARTIFACT_FILE, isUltramodernBuildArtifact } from "@modern-js/utils/universal";
5
+ import { BACKEND_FEDERATION_MANIFEST_FILE, BACKEND_FEDERATION_REMOTE_ENTRY_FILE, ULTRAMODERN_BUILD_ARTIFACT_FILE, isUltramodernBuildArtifact } from "@modern-js/backend-federation-contracts";
6
6
  import { canonicalSerializeMicroVerticalReleaseEnvelope, createMicroVerticalReleaseEnvelope, verifyMicroVerticalReleaseEnvelope } from "./index.mjs";
7
7
  const MICROVERTICAL_RELEASE_ENVELOPE_PATH = 'release/microvertical-release-envelope.json';
8
8
  const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = 'release/microvertical-release-identity-carriers.json';
@@ -11,7 +11,8 @@ const createUltramodernReleaseEnvelopePlugin = ({ resolveDeployTarget })=>({
11
11
  name: '@modern-js/ultramodern-release-envelope',
12
12
  pre: [
13
13
  '@modern-js/backend-federation-build',
14
- '@modern-js/plugin-bff'
14
+ '@modern-js/plugin-bff',
15
+ '@modern-js/deploy-output-aliases'
15
16
  ],
16
17
  post: [
17
18
  '@modern-js/plugin-deploy'
@@ -0,0 +1,86 @@
1
+ import type { BackendFederationEntryIntegrity } from '@modern-js/server-runtime-extensions/backend-federation-security';
2
+ import { type BackendFederationApp } from './config.js';
3
+ export declare const createBackendRemoteEntrySource: (workspaceRoot: string, app: BackendFederationApp, effectApiPath: string, entryPath: string) => Promise<string>;
4
+ export declare const createBackendManifest: (workspaceRoot: string, distDirectory: string, app: BackendFederationApp, entryIntegrity: BackendFederationEntryIntegrity) => {
5
+ schemaVersion: number;
6
+ id: string;
7
+ name: string;
8
+ version: string | undefined;
9
+ buildVersion: string | undefined;
10
+ metaData: {
11
+ name: string;
12
+ type: string;
13
+ buildInfo: {
14
+ buildVersion: string | undefined;
15
+ buildName: string | undefined;
16
+ };
17
+ remoteEntry: {
18
+ name: string;
19
+ path: string;
20
+ type: string;
21
+ };
22
+ globalName: string;
23
+ publicPath: string;
24
+ ssrRemoteEntry: {
25
+ name: string;
26
+ path: string;
27
+ type: string;
28
+ };
29
+ ssrPublicPath: string;
30
+ };
31
+ entry: {
32
+ byteLength: number;
33
+ sha256: string;
34
+ file: string;
35
+ path: string;
36
+ type: string;
37
+ url: string;
38
+ };
39
+ exposes: {
40
+ id: string;
41
+ name: string;
42
+ path: string;
43
+ assets: {
44
+ js: {
45
+ async: never[];
46
+ sync: string[];
47
+ };
48
+ css: {
49
+ async: never[];
50
+ sync: never[];
51
+ };
52
+ };
53
+ }[];
54
+ shared: never[];
55
+ backendFederation: {
56
+ role: string;
57
+ appId: string;
58
+ name: string;
59
+ runtimeFramework: string;
60
+ strictEffectApproach: boolean;
61
+ contractVersion: string;
62
+ nodeAdapterVersion: string;
63
+ remoteType: string;
64
+ expose: string;
65
+ manifestUrl: string;
66
+ containerEntry: string;
67
+ source: {
68
+ module: string;
69
+ };
70
+ readinessPath: string;
71
+ openapiPath: string;
72
+ deliveryUnit?: import("@modern-js/backend-federation-contracts").DeliveryUnitContractBlock | undefined;
73
+ versionBoundary: {
74
+ invariant: string;
75
+ packageName: string | undefined;
76
+ version: string | undefined;
77
+ buildVersion: string | undefined;
78
+ uiManifestUrl?: string | undefined;
79
+ deliveryUnit?: {
80
+ unitId: string;
81
+ buildMarker: string;
82
+ sourceRevision: string;
83
+ } | undefined;
84
+ };
85
+ };
86
+ };
@@ -0,0 +1,102 @@
1
+ import { type DeliveryUnitContractBlock, type UltramodernBuildArtifact } from '@modern-js/backend-federation-contracts';
2
+ export declare const COMPACT_CONFIG_PATH = ".modernjs/ultramodern.json";
3
+ export type CompactApp = {
4
+ id?: unknown;
5
+ kind?: unknown;
6
+ path?: unknown;
7
+ package?: unknown;
8
+ port?: unknown;
9
+ api?: {
10
+ prefix?: unknown;
11
+ stem?: unknown;
12
+ };
13
+ moduleFederation?: {
14
+ name?: unknown;
15
+ manifestUrl?: unknown;
16
+ };
17
+ backendFederation?: {
18
+ name?: unknown;
19
+ versionBoundary?: {
20
+ ui?: {
21
+ manifestUrl?: unknown;
22
+ };
23
+ };
24
+ executionSurfaces?: {
25
+ node?: {
26
+ remoteName?: unknown;
27
+ manifestUrl?: unknown;
28
+ containerEntry?: unknown;
29
+ remoteType?: unknown;
30
+ };
31
+ };
32
+ };
33
+ deliveryUnit?: {
34
+ unitId?: unknown;
35
+ buildMarker?: unknown;
36
+ sourceRevision?: unknown;
37
+ packageName?: unknown;
38
+ version?: unknown;
39
+ };
40
+ serverExecution?: {
41
+ node?: {
42
+ remoteName?: unknown;
43
+ manifestUrl?: unknown;
44
+ containerEntry?: unknown;
45
+ remoteType?: unknown;
46
+ };
47
+ };
48
+ };
49
+ export type CompactConfig = {
50
+ topology?: {
51
+ apps?: CompactApp[];
52
+ };
53
+ };
54
+ export type BackendFederationApp = {
55
+ id: string;
56
+ directory: string;
57
+ packageName?: string;
58
+ version?: string;
59
+ buildVersion?: string;
60
+ unitId?: string;
61
+ sourceRevision?: string;
62
+ deliveryUnit?: DeliveryUnitContractBlock;
63
+ port: number;
64
+ apiPrefix: string;
65
+ apiStem: string;
66
+ backendName: string;
67
+ manifestUrl: string;
68
+ containerEntry: string;
69
+ remoteType: string;
70
+ uiManifestUrl?: string;
71
+ compactDeliveryUnit?: {
72
+ unitId?: string;
73
+ buildMarker?: string;
74
+ sourceRevision?: string;
75
+ packageName?: string;
76
+ version?: string;
77
+ };
78
+ };
79
+ export type BackendFederationBuildIdentity = {
80
+ appId?: string;
81
+ packageName?: string;
82
+ version?: string;
83
+ buildVersion?: string;
84
+ unitId?: string;
85
+ sourceRevision?: string;
86
+ artifact?: UltramodernBuildArtifact;
87
+ };
88
+ export declare const normalizeRelativePath: (value: string) => string;
89
+ export declare const buildArtifactPathFor: (appDirectory: string) => string;
90
+ export declare const readBuildIdentity: (appDirectory: string) => Promise<BackendFederationBuildIdentity>;
91
+ export declare const findWorkspaceRoot: (appDirectory: string) => string | undefined;
92
+ export declare const resolveWorkspaceSourceRevision: (workspaceRoot: string) => Promise<string>;
93
+ export declare const createStampedDeliveryUnit: (input: {
94
+ appId: string;
95
+ unitId?: string;
96
+ buildMarker?: string;
97
+ packageName?: string;
98
+ version?: string;
99
+ sourceRevision: string;
100
+ }) => DeliveryUnitContractBlock | undefined;
101
+ export declare const createAppFromCompactMetadata: (workspaceRoot: string, appDirectory: string, compactApp: CompactApp) => BackendFederationApp | undefined;
102
+ export declare const findBackendFederationApp: (workspaceRoot: string, appDirectory: string) => Promise<BackendFederationApp | undefined>;
@@ -0,0 +1,21 @@
1
+ export type { BackendFederationBuildIdentity } from './config.js';
2
+ export type BackendFederationArtifactResult = {
3
+ appId: string;
4
+ manifestPath: string;
5
+ containerPath: string;
6
+ deliveryUnitArtifactPath?: string;
7
+ remoteName: string;
8
+ remoteType: string;
9
+ };
10
+ export declare const emitBackendFederationArtifacts: (appDirectory: string, distDirectory: string) => Promise<BackendFederationArtifactResult | undefined>;
11
+ export default _default;
12
+ declare function _default(): {
13
+ name: string;
14
+ setup(api: {
15
+ getAppContext(): {
16
+ appDirectory: string;
17
+ distDirectory: string;
18
+ };
19
+ onAfterBuild(handler: () => Promise<void>): void;
20
+ }): void;
21
+ };
@@ -0,0 +1,2 @@
1
+ export type { BackendFederationArtifactResult } from './emit.js';
2
+ export { default, emitBackendFederationArtifacts } from './emit.js';
@@ -0,0 +1,22 @@
1
+ import type { URL } from 'node:url';
2
+ import type { Rspack } from '@rsbuild/core';
3
+ /**
4
+ * Reads an environment variable while keeping generated build configs free of
5
+ * direct process access.
6
+ */
7
+ export declare function getBuildConfigEnvironment(name: string): string | undefined;
8
+ /**
9
+ * Runs a Rspack config setup under a leased environment value. The lease is
10
+ * restored when that compiler reaches any supported terminal hook.
11
+ */
12
+ export declare function withBuildConfigEnvironment<Config extends {
13
+ plugins?: Rspack.Plugin[];
14
+ }, SetupArguments extends unknown[]>(name: string, value: string, setup: (config: Config, ...args: SetupArguments) => Config | void | Promise<Config | void>): (config: Config, ...args: SetupArguments) => Promise<Config>;
15
+ export type ResolveEffectTsgoCompilerOptions = {
16
+ /** Module URL or absolute filename used to resolve the consumer's compiler. */
17
+ from: string | URL;
18
+ };
19
+ /**
20
+ * Resolves the Effect TS-Go executable used by Module Federation DTS builds.
21
+ */
22
+ export declare function resolveEffectTsgoCompiler(options: ResolveEffectTsgoCompilerOptions): string;
@@ -0,0 +1,4 @@
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ import type { PrecompressConfig } from './types.js';
3
+ export type { PrecompressCodecOptions, PrecompressConfig } from './types.js';
4
+ export declare const builderPluginAdapterPrecompress: (precompress: boolean | PrecompressConfig | undefined) => RsbuildPlugin;
@@ -0,0 +1,19 @@
1
+ import type { CompressionPluginOptions } from '../../precompress/index.js';
2
+ export type PrecompressCodecOptions = boolean | Partial<CompressionPluginOptions>;
3
+ export interface PrecompressConfig {
4
+ /**
5
+ * Configure gzip precompression options.
6
+ * `true` means using default options.
7
+ * `false` means disabling gzip precompression.
8
+ * @default true
9
+ */
10
+ gzip?: PrecompressCodecOptions;
11
+ /**
12
+ * Configure brotli precompression options.
13
+ * `true` means using default options.
14
+ * `false` means disabling brotli precompression.
15
+ * @default true
16
+ */
17
+ brotli?: PrecompressCodecOptions;
18
+ }
19
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { ResolveEffectTsgoCompilerOptions } from './build-environment.js';
2
+ export { getBuildConfigEnvironment, resolveEffectTsgoCompiler, withBuildConfigEnvironment, } from './build-environment.js';
@@ -16,7 +16,7 @@ export declare const SERVER_OUTPUT_DIRECTORY = "server";
16
16
  export declare const DEFAULT_SERVER_ONLY_PUBLIC_ASSET_EXCLUDES: readonly ['api', 'shared'];
17
17
  export declare const BFF_EFFECT_WORKER_ENTRY = "worker/__modern_bff_effect.js";
18
18
  export declare const BFF_EFFECT_WORKER_DISPATCHER_EXPORT = "__modern_create_effect_bff_dispatcher";
19
- export declare const EFFECT_BFF_CLOUDFLARE_IMPORT_GUIDANCE = "Ensure the Effect API entry exists at api/index.ts or bff.effect.entry, and import Cloudflare edge handlers from @modern-js/plugin-bff/effect-edge instead of lambda/Hono server helpers.";
19
+ export declare const EFFECT_BFF_CLOUDFLARE_IMPORT_GUIDANCE = "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.";
20
20
  export declare const DEFAULT_COMPATIBILITY_DATE = "2026-06-02";
21
21
  export declare const COMPATIBILITY_DATE_PATTERN: RegExp;
22
22
  export declare const REQUIRED_COMPATIBILITY_FLAGS: readonly ["nodejs_compat", "global_fetch_strictly_public"];
@@ -1,4 +1,4 @@
1
- import { type DeliveryUnitIdentity } from '@modern-js/utils/universal';
1
+ import { type DeliveryUnitIdentity } from '@modern-js/backend-federation-contracts';
2
2
  export type DeliveryUnitStamp = DeliveryUnitIdentity & {
3
3
  surfaces: {
4
4
  ui?: DeliveryUnitIdentity & {
@@ -17,7 +17,7 @@ export type DeliveryUnitStamp = DeliveryUnitIdentity & {
17
17
  export declare const resolveTopologyDeliveryUnit: (appDirectory: string) => Promise<DeliveryUnitStamp | undefined>;
18
18
  /**
19
19
  * Resolve the delivery-unit identity actually bundled into the worker by
20
- * parsing the generated `shared/ultramodern-build.ts` module. This is the
20
+ * reading the generated `shared/ultramodern-build.json` artifact. This is the
21
21
  * worker snapshot / declared surface source that gets stamped into the manifest.
22
22
  */
23
23
  export declare const resolveWorkerDeliveryUnitStamp: (appDirectory: string) => Promise<DeliveryUnitStamp | undefined>;
@@ -108,8 +108,8 @@ export declare const createWorkerManifest: (outputDirectory: string, modernConfi
108
108
  prefix: string;
109
109
  worker: string;
110
110
  effect: {
111
- openapi?: import("@modern-js/server-core").BffEffectOpenApiUserConfig | undefined;
112
- dataPlatform?: import("@modern-js/server-core").BffEffectDataPlatformUserConfig | undefined;
111
+ openapi?: import("@modern-js/runtime-extensions/server-config").BffEffectOpenApiUserConfig | undefined;
112
+ dataPlatform?: import("@modern-js/runtime-extensions/server-config").BffEffectDataPlatformUserConfig | undefined;
113
113
  crossProjectPolicy: {
114
114
  allowedNamespaces?: string[];
115
115
  verifyProducerIdentity?: (headers: Record<string, unknown>) => string | undefined;
@@ -1,4 +1,4 @@
1
- import { type DeliveryUnitIdentity } from '@modern-js/utils/universal';
1
+ import { type DeliveryUnitIdentity } from '@modern-js/backend-federation-contracts';
2
2
  import type { CloudflareOutputVerifierIssue, JsonObject } from './issues.js';
3
3
  export type CloudflareDeliveryUnitIdentity = DeliveryUnitIdentity & {
4
4
  surfaces?: Partial<Record<'api' | 'ui', DeliveryUnitIdentity & {
@@ -1,3 +1,5 @@
1
+ export type { ResolveEffectTsgoCompilerOptions } from './build-config/public.js';
2
+ export { getBuildConfigEnvironment, resolveEffectTsgoCompiler, withBuildConfigEnvironment, } from './build-config/public.js';
1
3
  export type DeployTarget = 'node' | 'vercel' | 'netlify' | 'ghPages' | 'cloudflare';
2
4
  export type CloudflareWorkerSecurityCspMode = 'enforce' | 'report-only' | 'off';
3
5
  export type JsonValue = string | number | boolean | null | JsonValue[] | {
@@ -0,0 +1,14 @@
1
+ export type NpmAlias = {
2
+ aliasName: string;
3
+ targetName: string;
4
+ targetVersion: string;
5
+ };
6
+ export declare function readPackageIdentity(entryPath: string): Promise<{
7
+ name: string;
8
+ version: string;
9
+ }>;
10
+ export declare function preserveNpmAliases({ appDirectory, outputDirectory, implicitAliases, }: {
11
+ appDirectory: string;
12
+ outputDirectory: string;
13
+ implicitAliases?: NpmAlias[];
14
+ }): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import { type DeployOutputConfig } from './target.js';
2
+ export interface DeployOutputPluginApi {
3
+ getAppContext(): {
4
+ appDirectory: string;
5
+ metaName: string;
6
+ };
7
+ getNormalizedConfig(): DeployOutputConfig;
8
+ onAfterDeploy(handler: () => Promise<void>): void;
9
+ }
10
+ export declare const createDeployOutputAliasesPlugin: ({ resolveDeployTarget, }?: {
11
+ resolveDeployTarget?: (config: DeployOutputConfig) => string;
12
+ }) => {
13
+ name: string;
14
+ setup(api: DeployOutputPluginApi): void;
15
+ };
@@ -0,0 +1,6 @@
1
+ export interface DeployOutputConfig {
2
+ deploy?: {
3
+ target?: string;
4
+ };
5
+ }
6
+ export declare const resolveDeployTarget: (config: DeployOutputConfig, envDeployTarget?: string | undefined, detectedProvider?: import("std-env").ProviderName) => string;
@@ -0,0 +1,20 @@
1
+ Copyright JS Foundation and other contributors
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.