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