@bleedingdev/modern-js-create 3.4.0-ultramodern.8 → 3.5.0-ultramodern.0
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/README.md +25 -23
- package/dist/cjs/index.cjs +37 -4
- package/dist/cjs/locale/en.cjs +12 -2
- package/dist/cjs/locale/zh.cjs +12 -2
- package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
- package/dist/cjs/ultramodern-tooling/config.cjs +172 -0
- package/dist/cjs/ultramodern-workspace/add-vertical.cjs +87 -75
- package/dist/cjs/ultramodern-workspace/{effect-api.cjs → api.cjs} +207 -208
- package/dist/cjs/ultramodern-workspace/bridge-config.cjs +327 -0
- package/dist/cjs/ultramodern-workspace/codesmith.cjs +1 -0
- package/dist/cjs/ultramodern-workspace/contracts.cjs +127 -657
- package/dist/cjs/ultramodern-workspace/demo-components.cjs +12 -12
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +25 -25
- package/dist/cjs/ultramodern-workspace/fs-io.cjs +117 -0
- package/dist/cjs/ultramodern-workspace/generation-result.cjs +5 -5
- package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/mf-validation.cjs +571 -0
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +33 -18
- package/dist/cjs/ultramodern-workspace/overlays.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/package-json.cjs +57 -41
- package/dist/cjs/ultramodern-workspace/policy.cjs +4 -4
- package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/public-surface.cjs +2 -2
- package/dist/cjs/ultramodern-workspace/versions.cjs +5 -0
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +119 -50
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +62 -21
- package/dist/esm/index.js +37 -4
- package/dist/esm/locale/en.js +12 -2
- package/dist/esm/locale/zh.js +12 -2
- package/dist/esm/ultramodern-tooling/commands.js +132 -0
- package/dist/esm/ultramodern-tooling/config.js +120 -0
- package/dist/esm/ultramodern-workspace/add-vertical.js +88 -79
- package/dist/esm/ultramodern-workspace/{effect-api.js → api.js} +146 -147
- package/dist/esm/ultramodern-workspace/bridge-config.js +270 -0
- package/dist/esm/ultramodern-workspace/codesmith.js +1 -0
- package/dist/esm/ultramodern-workspace/contracts.js +129 -611
- package/dist/esm/ultramodern-workspace/demo-components.js +13 -13
- package/dist/esm/ultramodern-workspace/descriptors.js +11 -11
- package/dist/esm/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm/ultramodern-workspace/generation-result.js +6 -6
- package/dist/esm/ultramodern-workspace/index.js +1 -0
- package/dist/esm/ultramodern-workspace/mf-validation.js +516 -0
- package/dist/esm/ultramodern-workspace/module-federation.js +34 -19
- package/dist/esm/ultramodern-workspace/overlays.js +2 -2
- package/dist/esm/ultramodern-workspace/package-json.js +56 -40
- package/dist/esm/ultramodern-workspace/policy.js +5 -5
- package/dist/esm/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm/ultramodern-workspace/public-surface.js +2 -2
- package/dist/esm/ultramodern-workspace/versions.js +3 -1
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +107 -34
- package/dist/esm/ultramodern-workspace/write-workspace.js +64 -26
- package/dist/esm-node/index.js +37 -4
- package/dist/esm-node/locale/en.js +12 -2
- package/dist/esm-node/locale/zh.js +12 -2
- package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
- package/dist/esm-node/ultramodern-tooling/config.js +121 -0
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +88 -79
- package/dist/esm-node/ultramodern-workspace/{effect-api.js → api.js} +146 -147
- package/dist/esm-node/ultramodern-workspace/bridge-config.js +271 -0
- package/dist/esm-node/ultramodern-workspace/codesmith.js +1 -0
- package/dist/esm-node/ultramodern-workspace/contracts.js +129 -611
- package/dist/esm-node/ultramodern-workspace/demo-components.js +13 -13
- package/dist/esm-node/ultramodern-workspace/descriptors.js +11 -11
- package/dist/esm-node/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm-node/ultramodern-workspace/generation-result.js +6 -6
- package/dist/esm-node/ultramodern-workspace/index.js +1 -0
- package/dist/esm-node/ultramodern-workspace/mf-validation.js +517 -0
- package/dist/esm-node/ultramodern-workspace/module-federation.js +34 -19
- package/dist/esm-node/ultramodern-workspace/overlays.js +2 -2
- package/dist/esm-node/ultramodern-workspace/package-json.js +56 -40
- package/dist/esm-node/ultramodern-workspace/policy.js +5 -5
- package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm-node/ultramodern-workspace/public-surface.js +2 -2
- package/dist/esm-node/ultramodern-workspace/versions.js +3 -1
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +107 -34
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +64 -26
- package/dist/types/locale/en.d.ts +10 -0
- package/dist/types/locale/index.d.ts +20 -0
- package/dist/types/locale/zh.d.ts +10 -0
- package/dist/types/ultramodern-tooling/commands.d.ts +1 -0
- package/dist/types/ultramodern-tooling/config.d.ts +43 -0
- package/dist/types/ultramodern-workspace/add-vertical.d.ts +5 -2
- package/dist/types/ultramodern-workspace/api.d.ts +73 -0
- package/dist/types/ultramodern-workspace/bridge-config.d.ts +64 -0
- package/dist/types/ultramodern-workspace/codesmith.d.ts +1 -0
- package/dist/types/ultramodern-workspace/contracts.d.ts +2 -17
- package/dist/types/ultramodern-workspace/descriptors.d.ts +10 -10
- package/dist/types/ultramodern-workspace/fs-io.d.ts +1 -0
- package/dist/types/ultramodern-workspace/index.d.ts +2 -0
- package/dist/types/ultramodern-workspace/mf-validation.d.ts +27 -0
- package/dist/types/ultramodern-workspace/package-json.d.ts +5 -4
- package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
- package/dist/types/ultramodern-workspace/types.d.ts +9 -7
- package/dist/types/ultramodern-workspace/versions.d.ts +2 -0
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +2 -7
- package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -2
- package/package.json +5 -3
- package/template-workspace/{.agents → .codex}/skills-lock.json +12 -12
- package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +2 -0
- package/template-workspace/.gitignore.handlebars +3 -0
- package/template-workspace/AGENTS.md.handlebars +11 -5
- package/template-workspace/README.md.handlebars +15 -12
- package/template-workspace/oxfmt.config.ts +1 -0
- package/template-workspace/oxlint.config.ts +1 -0
- package/template-workspace/patches/@tanstack__router-core@1.171.13.patch +51 -0
- package/template-workspace/pnpm-workspace.yaml.handlebars +4 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +77 -67
- package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +51 -8
- package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +344 -0
- package/templates/workspace-scripts/{check-ultramodern-i18n-boundaries.mjs → check-ultramodern-i18n-boundaries.mts} +1 -1
- package/templates/workspace-scripts/generate-public-surface-assets.mjs +246 -9
- package/templates/workspace-scripts/proof-cloudflare-version.mjs +277 -9
- package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +35 -10
- package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +165 -2
- package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +840 -84
- package/dist/types/ultramodern-workspace/effect-api.d.ts +0 -73
- /package/template-workspace/{.agents → .codex}/rstackjs-agent-skills-LICENSE +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsbuild-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/command-map.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/common-analysis-patterns.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rslib-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rslib-modern-package/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-best-practices/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/SKILL.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/bottlenecks.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/tracing-guide.md +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/scripts/analyze_trace.js +0 -0
- /package/template-workspace/{.agents → .codex}/skills/rstest-best-practices/SKILL.md +0 -0
|
@@ -3,12 +3,12 @@ import node_fs from "node:fs";
|
|
|
3
3
|
import node_os from "node:os";
|
|
4
4
|
import node_path from "node:path";
|
|
5
5
|
import { WORKSPACE_PACKAGE_VERSION } from "../ultramodern-package-source.js";
|
|
6
|
+
import { readUltramodernConfig } from "../ultramodern-tooling/config.js";
|
|
7
|
+
import { apiTopologyMetadata, createShellApiClient } from "./api.js";
|
|
6
8
|
import { createAppEnvDts, createAppRuntimeConfig, createShellFrameComponent } from "./app-files.js";
|
|
7
|
-
import { createGeneratedContract } from "./contracts.js";
|
|
8
9
|
import { createShellPage, createShellRemoteComponents } from "./demo-components.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { readJsonFile, writeFileReplacing, writeJsonFile } from "./fs-io.js";
|
|
10
|
+
import { ULTRAMODERN_CONFIG_PATH, appHasApi, appI18nNamespace, createModuleFederationRemoteContracts, createNeutralOwnership, createRemoteManifestEnv, createShellHost, createVerticalDescriptor, remoteDependencyAlias, resolveApiPrefix, shellApp, zephyrRemoteDependency } from "./descriptors.js";
|
|
11
|
+
import { formatGeneratedWorkspaceFiles, readJsonFile, writeFileReplacing, writeJsonFile } from "./fs-io.js";
|
|
12
12
|
import { createFileSnapshot, createGenerationResult, diffFileSnapshots } from "./generation-result.js";
|
|
13
13
|
import { createAppPublicLocaleMessages } from "./locales.js";
|
|
14
14
|
import { createShellModuleFederationConfig } from "./module-federation.js";
|
|
@@ -20,12 +20,11 @@ import { createCloudflareDeployContract } from "./policy.js";
|
|
|
20
20
|
import { createPublicWebAppArtifacts, rewriteWorkspaceAssetsForApp } from "./public-surface.js";
|
|
21
21
|
import { isRecord } from "./types.js";
|
|
22
22
|
import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
|
|
23
|
-
import { writeApp } from "./write-workspace.js";
|
|
23
|
+
import { createCompactUltramodernConfig, writeApp } from "./write-workspace.js";
|
|
24
24
|
const FIRST_VERTICAL_PORT = 4101;
|
|
25
25
|
const TOPOLOGY_PATH = 'topology/reference-topology.json';
|
|
26
26
|
const OWNERSHIP_PATH = 'topology/ownership.json';
|
|
27
27
|
const DEVELOPMENT_OVERLAY_PATH = 'topology/local-overlays/development.json';
|
|
28
|
-
const PACKAGE_SOURCE_METADATA_PATH = '.modernjs/ultramodern-package-source.json';
|
|
29
28
|
function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
30
29
|
if (packageSource) return resolvePackageSource({
|
|
31
30
|
targetDir: workspaceRoot,
|
|
@@ -33,35 +32,21 @@ function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
|
33
32
|
modernVersion,
|
|
34
33
|
packageSource
|
|
35
34
|
});
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
const metadata = readJsonFile(metadataPath);
|
|
43
|
-
const aliases = metadata.modernPackages?.aliases ?? {};
|
|
44
|
-
const firstAlias = Object.values(aliases).find((value)=>'string' == typeof value);
|
|
45
|
-
const firstPackage = Object.keys(aliases)[0];
|
|
46
|
-
const aliasScope = firstAlias?.match(/^@([^/]+)\//)?.[1];
|
|
47
|
-
const unscopedName = firstPackage?.split('/').at(-1) ?? '';
|
|
48
|
-
const aliasUnscopedName = firstAlias?.split('/').at(-1) ?? '';
|
|
49
|
-
const aliasPackageNamePrefix = aliasUnscopedName && unscopedName && aliasUnscopedName.endsWith(unscopedName) ? aliasUnscopedName.slice(0, -unscopedName.length) : void 0;
|
|
50
|
-
return {
|
|
51
|
-
strategy: 'install' === metadata.strategy ? 'install' : 'workspace',
|
|
52
|
-
modernPackageVersion: 'string' == typeof metadata.modernPackages?.specifier ? metadata.modernPackages.specifier : modernVersion,
|
|
53
|
-
registry: metadata.modernPackages?.registry,
|
|
54
|
-
aliasScope,
|
|
55
|
-
aliasPackageNamePrefix
|
|
56
|
-
};
|
|
35
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
36
|
+
if (node_fs.existsSync(compactPath)) {
|
|
37
|
+
const compactConfig = readUltramodernConfig(workspaceRoot);
|
|
38
|
+
if (compactConfig.packageSource) return compactConfig.packageSource;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
|
|
57
41
|
}
|
|
58
42
|
function existingTailwindEnabled(workspaceRoot) {
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
43
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
44
|
+
if (node_fs.existsSync(compactPath)) return readUltramodernConfig(workspaceRoot).features.tailwind;
|
|
45
|
+
throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
|
|
46
|
+
}
|
|
47
|
+
function existingBridgeConfig(workspaceRoot) {
|
|
48
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
49
|
+
return node_fs.existsSync(compactPath) ? readUltramodernConfig(workspaceRoot).bridge : void 0;
|
|
65
50
|
}
|
|
66
51
|
function assertValidVerticalName(name) {
|
|
67
52
|
const normalized = toKebabCase(name);
|
|
@@ -75,17 +60,17 @@ function nextAvailablePort(ports) {
|
|
|
75
60
|
function assertCanCreate(workspaceRoot, relativePath) {
|
|
76
61
|
if (node_fs.existsSync(node_path.join(workspaceRoot, relativePath))) throw new Error(`Refusing to overwrite existing path: ${relativePath}`);
|
|
77
62
|
}
|
|
78
|
-
function updateRootWorkspaceScripts(workspaceRoot, scope, packageSource, remotes) {
|
|
63
|
+
function updateRootWorkspaceScripts(workspaceRoot, scope, packageSource, remotes, bridge) {
|
|
79
64
|
const packagePath = node_path.join(workspaceRoot, 'package.json');
|
|
80
65
|
const rootPackage = readJsonFile(packagePath);
|
|
81
|
-
const generatedRootPackage = createRootPackageJson(scope, packageSource, remotes);
|
|
66
|
+
const generatedRootPackage = createRootPackageJson(scope, packageSource, remotes, bridge);
|
|
82
67
|
rootPackage.scripts = generatedRootPackage.scripts;
|
|
83
68
|
writeJsonFile(packagePath, rootPackage);
|
|
84
69
|
}
|
|
85
|
-
function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwind, remotes) {
|
|
70
|
+
function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwind, remotes, bridge) {
|
|
86
71
|
const shellHost = createShellHost(remotes);
|
|
87
72
|
const publicWeb = createPublicWebAppArtifacts(shellHost);
|
|
88
|
-
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/package.json`), createAppPackage(scope, shellHost, packageSource, enableTailwind, remotes));
|
|
73
|
+
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/package.json`), createAppPackage(scope, shellHost, packageSource, enableTailwind, remotes, bridge));
|
|
89
74
|
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/tsconfig.json`), createAppTsConfig(shellHost, remotes));
|
|
90
75
|
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/tsconfig.mf-types.json`), createAppMfTypesTsConfig(shellHost));
|
|
91
76
|
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/modern-app-env.d.ts`, createAppEnvDts(shellHost, remotes));
|
|
@@ -103,7 +88,7 @@ function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwin
|
|
|
103
88
|
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/routes/[lang]/page.tsx`, createShellPage(remotes));
|
|
104
89
|
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/routes/vertical-components.tsx`, createShellRemoteComponents(scope, remotes));
|
|
105
90
|
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/routes/shell-frame.tsx`, createShellFrameComponent());
|
|
106
|
-
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/
|
|
91
|
+
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/api/vertical-clients.ts`, createShellApiClient(scope, remotes));
|
|
107
92
|
}
|
|
108
93
|
function addShellZephyrDependency(workspaceRoot, scope, remote) {
|
|
109
94
|
const packagePath = node_path.join(workspaceRoot, shellApp.directory, 'package.json');
|
|
@@ -113,7 +98,7 @@ function addShellZephyrDependency(workspaceRoot, scope, remote) {
|
|
|
113
98
|
writeJsonFile(packagePath, shellPackage);
|
|
114
99
|
}
|
|
115
100
|
function addShellWorkspaceDependency(workspaceRoot, scope, remote) {
|
|
116
|
-
if (!
|
|
101
|
+
if (!appHasApi(remote)) return;
|
|
117
102
|
const packagePath = node_path.join(workspaceRoot, shellApp.directory, 'package.json');
|
|
118
103
|
const shellPackage = readJsonFile(packagePath);
|
|
119
104
|
shellPackage.dependencies ??= {};
|
|
@@ -140,8 +125,8 @@ function verticalTopologyEntry(scope, vertical, remotes = []) {
|
|
|
140
125
|
fallbackTelemetryEvent: 'modernjs:mv-runtime-parity',
|
|
141
126
|
sharedContractVersion: 'mf-ssr-contract-v1'
|
|
142
127
|
},
|
|
143
|
-
...
|
|
144
|
-
api:
|
|
128
|
+
...apiTopologyMetadata(vertical) ? {
|
|
129
|
+
api: apiTopologyMetadata(vertical)
|
|
145
130
|
} : {},
|
|
146
131
|
cloudflare: createCloudflareDeployContract(scope, vertical),
|
|
147
132
|
ownership: vertical.ownership
|
|
@@ -159,10 +144,11 @@ function verticalsFromTopology(topology, ports) {
|
|
|
159
144
|
return (topology.verticals ?? []).map((vertical)=>{
|
|
160
145
|
const domain = vertical.domain ?? String(vertical.id);
|
|
161
146
|
const packageSuffix = vertical.package?.split('/').at(-1) ?? domain;
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
const apiTopology = vertical.api;
|
|
148
|
+
const api = apiTopology?.runtime === 'effect' ? {
|
|
149
|
+
stem: 'string' == typeof apiTopology.basePath ? apiTopology.basePath.split('/').filter(Boolean).at(-1) ?? domain : domain,
|
|
150
|
+
prefix: apiTopology.bff?.prefix ?? `/${domain}-api`,
|
|
151
|
+
consumedBy: Array.isArray(apiTopology.consumedBy) ? apiTopology.consumedBy : [
|
|
166
152
|
shellApp.id,
|
|
167
153
|
vertical.id
|
|
168
154
|
]
|
|
@@ -188,8 +174,8 @@ function verticalsFromTopology(topology, ports) {
|
|
|
188
174
|
} : Array.isArray(vertical.moduleFederation?.remotes) ? {
|
|
189
175
|
verticalRefs: vertical.moduleFederation.remotes.map((entry)=>entry.id).filter((id)=>'string' == typeof id)
|
|
190
176
|
} : {},
|
|
191
|
-
...
|
|
192
|
-
|
|
177
|
+
...api ? {
|
|
178
|
+
api
|
|
193
179
|
} : {},
|
|
194
180
|
ownership: vertical.ownership ?? createNeutralOwnership(vertical.id)
|
|
195
181
|
};
|
|
@@ -204,8 +190,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
204
190
|
const topology = readRequiredJsonObject(topologyPath);
|
|
205
191
|
const ownership = readRequiredJsonObject(ownershipPath);
|
|
206
192
|
const overlay = readRequiredJsonObject(overlayPath);
|
|
207
|
-
|
|
208
|
-
readRequiredJsonObject(node_path.join(options.workspaceRoot, PACKAGE_SOURCE_METADATA_PATH));
|
|
193
|
+
readRequiredWorkspaceConfig(options.workspaceRoot);
|
|
209
194
|
assertOptionalJsonObject(topology.shell, 'topology.shell', topologyPath);
|
|
210
195
|
assertOptionalJsonArray(topology.verticals, 'topology.verticals', topologyPath);
|
|
211
196
|
assertOptionalJsonArray(ownership.owners, 'ownership.owners', ownershipPath);
|
|
@@ -216,6 +201,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
216
201
|
const scope = toPackageScope(String(rootPackage.name ?? node_path.basename(options.workspaceRoot)));
|
|
217
202
|
const packageSource = existingPackageSource(options.workspaceRoot, options.modernVersion, options.packageSource);
|
|
218
203
|
const enableTailwind = options.enableTailwind ?? existingTailwindEnabled(options.workspaceRoot);
|
|
204
|
+
const bridge = existingBridgeConfig(options.workspaceRoot);
|
|
219
205
|
const existingVerticals = verticalsFromTopology(topology, overlay.ports);
|
|
220
206
|
const port = nextAvailablePort(overlay.ports);
|
|
221
207
|
const vertical = createVerticalDescriptor(name, port);
|
|
@@ -243,6 +229,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
243
229
|
overlay,
|
|
244
230
|
packageSource,
|
|
245
231
|
enableTailwind,
|
|
232
|
+
bridge,
|
|
246
233
|
vertical,
|
|
247
234
|
updatedVerticals
|
|
248
235
|
};
|
|
@@ -253,6 +240,10 @@ function readRequiredJsonObject(filePath) {
|
|
|
253
240
|
if (!isRecord(value)) throw new Error(`UltraModern workspace file must contain a JSON object: ${filePath}`);
|
|
254
241
|
return value;
|
|
255
242
|
}
|
|
243
|
+
function readRequiredWorkspaceConfig(workspaceRoot) {
|
|
244
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
245
|
+
readRequiredJsonObject(compactPath);
|
|
246
|
+
}
|
|
256
247
|
function assertOptionalJsonObject(value, label, filePath) {
|
|
257
248
|
if (void 0 !== value && !isRecord(value)) throw new Error(`${label} in ${filePath} must be a JSON object`);
|
|
258
249
|
}
|
|
@@ -271,9 +262,9 @@ function validateWorkspaceAppDescriptors(apps) {
|
|
|
271
262
|
assertNonEmptyString(app.portEnv, `port env for ${appLabel}`);
|
|
272
263
|
if ('number' != typeof app.port || !Number.isFinite(app.port) || app.port <= 0) throw new Error(`Invalid development port for ${appLabel}`);
|
|
273
264
|
assertNonEmptyString(app.mfName, `Module Federation name for ${appLabel}`);
|
|
274
|
-
if (app.
|
|
275
|
-
assertNonEmptyString(app.
|
|
276
|
-
if (!app.
|
|
265
|
+
if (app.api) {
|
|
266
|
+
assertNonEmptyString(app.api.prefix, `API prefix for ${appLabel}`);
|
|
267
|
+
if (!app.api.prefix.startsWith('/')) throw new Error(`API prefix for ${appLabel} must start with "/"`);
|
|
277
268
|
}
|
|
278
269
|
}
|
|
279
270
|
}
|
|
@@ -283,7 +274,7 @@ function validateUniqueWorkspaceAppDescriptors(apps) {
|
|
|
283
274
|
assertUniqueAppField(apps, 'output path', (app)=>normalizePath(app.directory));
|
|
284
275
|
assertUniqueAppField(apps, 'Module Federation name', (app)=>app.mfName);
|
|
285
276
|
assertUniqueAppField(apps, 'development port', (app)=>String(app.port));
|
|
286
|
-
assertUniqueAppField(apps, '
|
|
277
|
+
assertUniqueAppField(apps, 'API prefix', (app)=>app.api?.prefix);
|
|
287
278
|
assertUniqueAppField(apps, 'manifest environment name', (app)=>'vertical' === app.kind ? createRemoteManifestEnv(app) : void 0);
|
|
288
279
|
}
|
|
289
280
|
function assertUniqueAppField(apps, label, readValue) {
|
|
@@ -350,14 +341,14 @@ function createVerticalPlan(preflight, result) {
|
|
|
350
341
|
name: vertical.mfName,
|
|
351
342
|
manifestUrl
|
|
352
343
|
},
|
|
353
|
-
...vertical.
|
|
354
|
-
|
|
344
|
+
...vertical.api ? {
|
|
345
|
+
apiPrefix: resolveApiPrefix(vertical)
|
|
355
346
|
} : {},
|
|
356
347
|
jsonMutations: createDryRunJsonMutations(preflight, manifestUrl),
|
|
357
348
|
shellDependencyChanges: createShellDependencyChanges(scope, vertical),
|
|
358
349
|
generatedContractChanges: [
|
|
359
350
|
{
|
|
360
|
-
path:
|
|
351
|
+
path: ULTRAMODERN_CONFIG_PATH,
|
|
361
352
|
addedAppIds: [
|
|
362
353
|
vertical.id
|
|
363
354
|
],
|
|
@@ -368,12 +359,12 @@ function createVerticalPlan(preflight, result) {
|
|
|
368
359
|
}
|
|
369
360
|
function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
370
361
|
const { scope, vertical } = preflight;
|
|
371
|
-
const
|
|
362
|
+
const apiMutation = appHasApi(vertical) ? [
|
|
372
363
|
{
|
|
373
364
|
path: DEVELOPMENT_OVERLAY_PATH,
|
|
374
365
|
pointer: `/apis/${vertical.id}`,
|
|
375
|
-
description: `Add local
|
|
376
|
-
value: `http://localhost:${vertical.port}${
|
|
366
|
+
description: `Add local API URL for ${vertical.id}`,
|
|
367
|
+
value: `http://localhost:${vertical.port}${resolveApiPrefix(vertical)}`
|
|
377
368
|
}
|
|
378
369
|
] : [];
|
|
379
370
|
return [
|
|
@@ -417,7 +408,7 @@ function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
|
417
408
|
description: `Add local Module Federation manifest URL for ${vertical.id}`,
|
|
418
409
|
value: manifestUrl
|
|
419
410
|
},
|
|
420
|
-
...
|
|
411
|
+
...apiMutation,
|
|
421
412
|
{
|
|
422
413
|
path: 'package.json',
|
|
423
414
|
pointer: "/scripts",
|
|
@@ -444,9 +435,9 @@ function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
|
444
435
|
description: 'Keep shell Module Federation DTS compilation scoped'
|
|
445
436
|
},
|
|
446
437
|
{
|
|
447
|
-
path:
|
|
448
|
-
pointer: '/apps',
|
|
449
|
-
description: `Regenerate
|
|
438
|
+
path: ULTRAMODERN_CONFIG_PATH,
|
|
439
|
+
pointer: '/topology/apps',
|
|
440
|
+
description: `Regenerate compact config with ${vertical.id}`
|
|
450
441
|
}
|
|
451
442
|
];
|
|
452
443
|
}
|
|
@@ -458,7 +449,7 @@ function createShellDependencyChanges(scope, vertical) {
|
|
|
458
449
|
packageName: remoteDependencyAlias(vertical),
|
|
459
450
|
version: zephyrRemoteDependency(scope, vertical)
|
|
460
451
|
},
|
|
461
|
-
...
|
|
452
|
+
...appHasApi(vertical) ? [
|
|
462
453
|
{
|
|
463
454
|
path: `${shellApp.directory}/package.json`,
|
|
464
455
|
section: 'dependencies',
|
|
@@ -470,8 +461,8 @@ function createShellDependencyChanges(scope, vertical) {
|
|
|
470
461
|
}
|
|
471
462
|
function addUltramodernVertical(options) {
|
|
472
463
|
const beforeFiles = createFileSnapshot(options.workspaceRoot);
|
|
473
|
-
const { scope, topologyPath, ownershipPath, overlayPath, topology, ownership, overlay, packageSource, enableTailwind, vertical, updatedVerticals } = prepareAddUltramodernVertical(options);
|
|
474
|
-
writeApp(options.workspaceRoot, scope, vertical, packageSource, enableTailwind);
|
|
464
|
+
const { scope, topologyPath, ownershipPath, overlayPath, topology, ownership, overlay, packageSource, enableTailwind, bridge, vertical, updatedVerticals } = prepareAddUltramodernVertical(options);
|
|
465
|
+
writeApp(options.workspaceRoot, scope, vertical, packageSource, enableTailwind, updatedVerticals, bridge);
|
|
475
466
|
topology.shell ??= {};
|
|
476
467
|
topology.shell.verticalRefs ??= [];
|
|
477
468
|
topology.shell.verticalRefs.push(vertical.id);
|
|
@@ -490,22 +481,22 @@ function addUltramodernVertical(options) {
|
|
|
490
481
|
overlay.manifests ??= {};
|
|
491
482
|
overlay.manifests[vertical.id] = `http://localhost:${vertical.port}/mf-manifest.json`;
|
|
492
483
|
overlay.apis ??= {};
|
|
493
|
-
overlay.apis[vertical.id] = `http://localhost:${vertical.port}${
|
|
484
|
+
overlay.apis[vertical.id] = `http://localhost:${vertical.port}${resolveApiPrefix(vertical)}`;
|
|
494
485
|
writeJsonFile(topologyPath, topology);
|
|
495
486
|
writeJsonFile(ownershipPath, ownership);
|
|
496
487
|
writeJsonFile(overlayPath, overlay);
|
|
497
|
-
writeJsonFile(node_path.join(options.workspaceRoot,
|
|
488
|
+
writeJsonFile(node_path.join(options.workspaceRoot, ULTRAMODERN_CONFIG_PATH), createCompactUltramodernConfig(scope, options.modernVersion, packageSource, [
|
|
498
489
|
{
|
|
499
490
|
...shellApp,
|
|
500
491
|
verticalRefs: updatedVerticals.map((vertical)=>vertical.id)
|
|
501
492
|
},
|
|
502
493
|
...updatedVerticals
|
|
503
|
-
], enableTailwind));
|
|
504
|
-
rewriteShellAppFiles(options.workspaceRoot, scope, packageSource, enableTailwind, updatedVerticals);
|
|
494
|
+
], enableTailwind, bridge));
|
|
495
|
+
rewriteShellAppFiles(options.workspaceRoot, scope, packageSource, enableTailwind, updatedVerticals, bridge);
|
|
505
496
|
writeGeneratedWorkspaceScripts(options.workspaceRoot, scope, enableTailwind, updatedVerticals);
|
|
506
497
|
addShellZephyrDependency(options.workspaceRoot, scope, vertical);
|
|
507
498
|
addShellWorkspaceDependency(options.workspaceRoot, scope, vertical);
|
|
508
|
-
updateRootWorkspaceScripts(options.workspaceRoot, scope, packageSource, updatedVerticals);
|
|
499
|
+
updateRootWorkspaceScripts(options.workspaceRoot, scope, packageSource, updatedVerticals, bridge);
|
|
509
500
|
writeJsonFile(node_path.join(options.workspaceRoot, 'tsconfig.json'), createRootTsConfig([
|
|
510
501
|
{
|
|
511
502
|
...shellApp,
|
|
@@ -513,9 +504,9 @@ function addUltramodernVertical(options) {
|
|
|
513
504
|
},
|
|
514
505
|
...updatedVerticals
|
|
515
506
|
]));
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
const
|
|
507
|
+
const preliminaryAfterFiles = createFileSnapshot(options.workspaceRoot);
|
|
508
|
+
const preliminaryDiff = diffFileSnapshots(beforeFiles, preliminaryAfterFiles);
|
|
509
|
+
const preliminaryResult = createGenerationResult({
|
|
519
510
|
operation: 'vertical',
|
|
520
511
|
workspaceRoot: options.workspaceRoot,
|
|
521
512
|
packageScope: scope,
|
|
@@ -523,14 +514,32 @@ function addUltramodernVertical(options) {
|
|
|
523
514
|
createdApps: [
|
|
524
515
|
vertical
|
|
525
516
|
],
|
|
526
|
-
createdPaths,
|
|
527
|
-
rewrittenPaths
|
|
517
|
+
createdPaths: preliminaryDiff.createdPaths,
|
|
518
|
+
rewrittenPaths: preliminaryDiff.rewrittenPaths
|
|
528
519
|
});
|
|
529
520
|
runCodeSmithOverlays({
|
|
530
521
|
workspaceRoot: options.workspaceRoot,
|
|
531
522
|
overlays: options.overlays,
|
|
532
|
-
result
|
|
523
|
+
result: preliminaryResult
|
|
524
|
+
});
|
|
525
|
+
const afterOverlaysFiles = createFileSnapshot(options.workspaceRoot);
|
|
526
|
+
const changedPaths = diffFileSnapshots(beforeFiles, afterOverlaysFiles);
|
|
527
|
+
formatGeneratedWorkspaceFiles(options.workspaceRoot, [
|
|
528
|
+
...changedPaths.createdPaths,
|
|
529
|
+
...changedPaths.rewrittenPaths
|
|
530
|
+
]);
|
|
531
|
+
const afterFiles = createFileSnapshot(options.workspaceRoot);
|
|
532
|
+
const { createdPaths, rewrittenPaths } = diffFileSnapshots(beforeFiles, afterFiles);
|
|
533
|
+
return createGenerationResult({
|
|
534
|
+
operation: 'vertical',
|
|
535
|
+
workspaceRoot: options.workspaceRoot,
|
|
536
|
+
packageScope: scope,
|
|
537
|
+
packageSource,
|
|
538
|
+
createdApps: [
|
|
539
|
+
vertical
|
|
540
|
+
],
|
|
541
|
+
createdPaths,
|
|
542
|
+
rewrittenPaths
|
|
533
543
|
});
|
|
534
|
-
return result;
|
|
535
544
|
}
|
|
536
|
-
export { addShellWorkspaceDependency, addShellZephyrDependency, addUltramodernVertical, assertCanCreate, assertValidVerticalName, existingPackageSource, existingTailwindEnabled, nextAvailablePort, ownershipEntry, planUltramodernVertical, prepareAddUltramodernVertical, rewriteShellAppFiles, updateRootWorkspaceScripts, verticalTopologyEntry, verticalsFromTopology };
|
|
545
|
+
export { addShellWorkspaceDependency, addShellZephyrDependency, addUltramodernVertical, assertCanCreate, assertValidVerticalName, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort, ownershipEntry, planUltramodernVertical, prepareAddUltramodernVertical, rewriteShellAppFiles, updateRootWorkspaceScripts, verticalTopologyEntry, verticalsFromTopology };
|