@bleedingdev/modern-js-create 3.4.0-ultramodern.12 → 3.4.0-ultramodern.14
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 +13 -11
- package/dist/cjs/index.cjs +36 -3
- package/dist/cjs/locale/en.cjs +10 -0
- package/dist/cjs/locale/zh.cjs +10 -0
- package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
- package/dist/cjs/ultramodern-tooling/config.cjs +248 -0
- package/dist/cjs/ultramodern-workspace/add-vertical.cjs +64 -25
- 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 +119 -653
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/fs-io.cjs +117 -0
- package/dist/cjs/ultramodern-workspace/generation-result.cjs +1 -1
- package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/mf-validation.cjs +572 -0
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +14 -0
- package/dist/cjs/ultramodern-workspace/package-json.cjs +26 -12
- package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +74 -44
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +55 -15
- package/dist/esm/index.js +36 -3
- package/dist/esm/locale/en.js +10 -0
- package/dist/esm/locale/zh.js +10 -0
- package/dist/esm/ultramodern-tooling/commands.js +132 -0
- package/dist/esm/ultramodern-tooling/config.js +196 -0
- package/dist/esm/ultramodern-workspace/add-vertical.js +65 -29
- 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 +122 -608
- package/dist/esm/ultramodern-workspace/descriptors.js +2 -1
- package/dist/esm/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm/ultramodern-workspace/generation-result.js +2 -2
- package/dist/esm/ultramodern-workspace/index.js +1 -0
- package/dist/esm/ultramodern-workspace/mf-validation.js +517 -0
- package/dist/esm/ultramodern-workspace/module-federation.js +14 -0
- package/dist/esm/ultramodern-workspace/package-json.js +26 -12
- package/dist/esm/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +75 -27
- package/dist/esm/ultramodern-workspace/write-workspace.js +56 -19
- package/dist/esm-node/index.js +36 -3
- package/dist/esm-node/locale/en.js +10 -0
- package/dist/esm-node/locale/zh.js +10 -0
- package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
- package/dist/esm-node/ultramodern-tooling/config.js +197 -0
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +65 -29
- 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 +122 -608
- package/dist/esm-node/ultramodern-workspace/descriptors.js +2 -1
- package/dist/esm-node/ultramodern-workspace/fs-io.js +116 -2
- package/dist/esm-node/ultramodern-workspace/generation-result.js +2 -2
- package/dist/esm-node/ultramodern-workspace/index.js +1 -0
- package/dist/esm-node/ultramodern-workspace/mf-validation.js +518 -0
- package/dist/esm-node/ultramodern-workspace/module-federation.js +14 -0
- package/dist/esm-node/ultramodern-workspace/package-json.js +26 -12
- package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +75 -27
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +56 -19
- 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/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 +1 -0
- 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 +4 -3
- package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
- package/dist/types/ultramodern-workspace/types.d.ts +2 -0
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -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/.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/scripts/bootstrap-agent-skills.mjs +77 -67
- package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +56 -3
- package/templates/workspace-scripts/generate-public-surface-assets.mjs +239 -4
- package/templates/workspace-scripts/proof-cloudflare-version.mjs +282 -4
- package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +172 -1
- package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +783 -26
- /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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import node_fs from "node:fs";
|
|
3
|
+
import node_os from "node:os";
|
|
4
|
+
import node_path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { resolveCreatePackageRoot } from "../create-package-root.js";
|
|
7
|
+
import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
|
|
8
|
+
import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
|
|
9
|
+
import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
|
|
10
|
+
const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const createPackageRoot = resolveCreatePackageRoot(commands_dirname);
|
|
12
|
+
function printHelp() {
|
|
13
|
+
process.stdout.write(`Usage:
|
|
14
|
+
modern-js-create ultramodern <command> [args]
|
|
15
|
+
|
|
16
|
+
Commands:
|
|
17
|
+
validate
|
|
18
|
+
typecheck
|
|
19
|
+
mf-types
|
|
20
|
+
public-surface
|
|
21
|
+
cloudflare-proof
|
|
22
|
+
performance-readiness
|
|
23
|
+
skills install
|
|
24
|
+
skills check
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
function spawnNodeScript(relativeScriptPath, args, context, options = {}) {
|
|
28
|
+
const scriptPath = node_path.join(createPackageRoot, relativeScriptPath);
|
|
29
|
+
const result = spawnSync(process.execPath, [
|
|
30
|
+
scriptPath,
|
|
31
|
+
...args
|
|
32
|
+
], {
|
|
33
|
+
cwd: options.cwd ?? context.workspaceRoot,
|
|
34
|
+
env: {
|
|
35
|
+
...process.env,
|
|
36
|
+
ULTRAMODERN_WORKSPACE_ROOT: context.workspaceRoot
|
|
37
|
+
},
|
|
38
|
+
stdio: 'inherit'
|
|
39
|
+
});
|
|
40
|
+
if (result.error) throw result.error;
|
|
41
|
+
return result.status ?? 1;
|
|
42
|
+
}
|
|
43
|
+
function runRenderedModule(source, context) {
|
|
44
|
+
const tempDir = node_fs.mkdtempSync(node_path.join(node_os.tmpdir(), 'ultramodern-tool-'));
|
|
45
|
+
const tempFile = node_path.join(tempDir, 'command.mjs');
|
|
46
|
+
try {
|
|
47
|
+
node_fs.writeFileSync(tempFile, source, 'utf-8');
|
|
48
|
+
const result = spawnSync(process.execPath, [
|
|
49
|
+
tempFile
|
|
50
|
+
], {
|
|
51
|
+
cwd: context.workspaceRoot,
|
|
52
|
+
stdio: 'inherit'
|
|
53
|
+
});
|
|
54
|
+
if (result.error) throw result.error;
|
|
55
|
+
return result.status ?? 1;
|
|
56
|
+
} finally{
|
|
57
|
+
node_fs.rmSync(tempDir, {
|
|
58
|
+
force: true,
|
|
59
|
+
recursive: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function runValidate(context) {
|
|
64
|
+
const config = readUltramodernConfig(context.workspaceRoot);
|
|
65
|
+
const apps = workspaceAppsFromToolingConfig(config);
|
|
66
|
+
const remotes = apps.filter((app)=>'shell' !== app.kind);
|
|
67
|
+
const source = createWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes);
|
|
68
|
+
return runRenderedModule(source, context);
|
|
69
|
+
}
|
|
70
|
+
function runMfTypes(args, context) {
|
|
71
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
72
|
+
process.stdout.write(`Usage:
|
|
73
|
+
modern-js-create ultramodern mf-types [app-dir...]
|
|
74
|
+
|
|
75
|
+
Checks real Module Federation config files and DTS archives for exposed apps.
|
|
76
|
+
`);
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
validateModuleFederationTypes({
|
|
80
|
+
workspaceRoot: context.workspaceRoot,
|
|
81
|
+
appDirs: args.length > 0 ? args : void 0
|
|
82
|
+
});
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
function runSkills(args, context) {
|
|
86
|
+
const [subcommand, ...rest] = args;
|
|
87
|
+
if ('install' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", rest, context);
|
|
88
|
+
if ('check' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", [
|
|
89
|
+
'--check',
|
|
90
|
+
...rest
|
|
91
|
+
], context);
|
|
92
|
+
throw new Error('Usage: modern-js-create ultramodern skills <install|check>');
|
|
93
|
+
}
|
|
94
|
+
async function runUltramodernToolingCli(args, workspaceRoot = process.env.ULTRAMODERN_WORKSPACE_ROOT ?? process.cwd()) {
|
|
95
|
+
try {
|
|
96
|
+
const [command, ...rest] = args;
|
|
97
|
+
const context = {
|
|
98
|
+
workspaceRoot: node_path.resolve(workspaceRoot),
|
|
99
|
+
invocationCwd: process.cwd()
|
|
100
|
+
};
|
|
101
|
+
switch(command){
|
|
102
|
+
case void 0:
|
|
103
|
+
case '--help':
|
|
104
|
+
case '-h':
|
|
105
|
+
printHelp();
|
|
106
|
+
return 0;
|
|
107
|
+
case 'validate':
|
|
108
|
+
return runValidate(context);
|
|
109
|
+
case 'typecheck':
|
|
110
|
+
return spawnNodeScript("templates/workspace-scripts/ultramodern-typecheck.mjs", rest, context, {
|
|
111
|
+
cwd: context.invocationCwd
|
|
112
|
+
});
|
|
113
|
+
case 'mf-types':
|
|
114
|
+
return runMfTypes(rest, context);
|
|
115
|
+
case 'public-surface':
|
|
116
|
+
return spawnNodeScript("templates/workspace-scripts/generate-public-surface-assets.mjs", rest, context);
|
|
117
|
+
case 'cloudflare-proof':
|
|
118
|
+
return spawnNodeScript("templates/workspace-scripts/proof-cloudflare-version.mjs", rest, context);
|
|
119
|
+
case 'performance-readiness':
|
|
120
|
+
return spawnNodeScript("templates/workspace-scripts/ultramodern-performance-readiness.mjs", rest, context);
|
|
121
|
+
case 'skills':
|
|
122
|
+
return runSkills(rest, context);
|
|
123
|
+
default:
|
|
124
|
+
throw new Error(`Unknown UltraModern command: ${command}`);
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
128
|
+
process.stderr.write(`[ultramodern] ${message}\n`);
|
|
129
|
+
return 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export { runUltramodernToolingCli };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import node_fs from "node:fs";
|
|
2
|
+
import node_path from "node:path";
|
|
3
|
+
import { normalizeUltramodernBridgeConfig } from "../ultramodern-workspace/bridge-config.js";
|
|
4
|
+
import { GENERATED_CONTRACT_PATH, ULTRAMODERN_CONFIG_PATH, createNeutralOwnership, shellApp } from "../ultramodern-workspace/descriptors.js";
|
|
5
|
+
import { toKebabCase } from "../ultramodern-workspace/naming.js";
|
|
6
|
+
const PACKAGE_SOURCE_METADATA_PATH = '.modernjs/ultramodern-package-source.json';
|
|
7
|
+
const DEVELOPMENT_OVERLAY_PATH = 'topology/local-overlays/development.json';
|
|
8
|
+
function readJsonObject(filePath) {
|
|
9
|
+
const value = JSON.parse(node_fs.readFileSync(filePath, 'utf-8'));
|
|
10
|
+
if (null === value || 'object' != typeof value || Array.isArray(value)) throw new Error(`UltraModern config must contain a JSON object: ${filePath}`);
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function readOptionalJsonObject(filePath) {
|
|
14
|
+
return node_fs.existsSync(filePath) ? readJsonObject(filePath) : {};
|
|
15
|
+
}
|
|
16
|
+
function packageScopeFromRoot(workspaceRoot) {
|
|
17
|
+
const rootPackage = readOptionalJsonObject(node_path.join(workspaceRoot, 'package.json'));
|
|
18
|
+
return 'string' == typeof rootPackage.name && rootPackage.name.length > 0 ? rootPackage.name : node_path.basename(workspaceRoot);
|
|
19
|
+
}
|
|
20
|
+
function packageSourceFromMetadata(workspaceRoot) {
|
|
21
|
+
const metadataPath = node_path.join(workspaceRoot, PACKAGE_SOURCE_METADATA_PATH);
|
|
22
|
+
if (!node_fs.existsSync(metadataPath)) return;
|
|
23
|
+
const metadata = readJsonObject(metadataPath);
|
|
24
|
+
const aliases = metadata.modernPackages?.aliases ?? {};
|
|
25
|
+
const firstAlias = Object.values(aliases).find((value)=>'string' == typeof value);
|
|
26
|
+
const firstPackage = Object.keys(aliases)[0];
|
|
27
|
+
const aliasScope = firstAlias?.match(/^@([^/]+)\//)?.[1];
|
|
28
|
+
const unscopedName = firstPackage?.split('/').at(-1) ?? '';
|
|
29
|
+
const aliasUnscopedName = firstAlias?.split('/').at(-1) ?? '';
|
|
30
|
+
const aliasPackageNamePrefix = aliasUnscopedName && unscopedName && aliasUnscopedName.endsWith(unscopedName) ? aliasUnscopedName.slice(0, -unscopedName.length) : void 0;
|
|
31
|
+
return {
|
|
32
|
+
strategy: 'install' === metadata.strategy ? 'install' : 'workspace',
|
|
33
|
+
modernPackageVersion: 'string' == typeof metadata.modernPackages?.specifier ? metadata.modernPackages.specifier : 'workspace:*',
|
|
34
|
+
registry: 'string' == typeof metadata.modernPackages?.registry ? metadata.modernPackages.registry : void 0,
|
|
35
|
+
aliasScope,
|
|
36
|
+
aliasPackageNamePrefix
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function readOverlayPorts(workspaceRoot) {
|
|
40
|
+
const overlayPath = node_path.join(workspaceRoot, DEVELOPMENT_OVERLAY_PATH);
|
|
41
|
+
if (!node_fs.existsSync(overlayPath)) return {};
|
|
42
|
+
const overlay = readJsonObject(overlayPath);
|
|
43
|
+
const ports = overlay.ports;
|
|
44
|
+
if (null === ports || 'object' != typeof ports || Array.isArray(ports)) return {};
|
|
45
|
+
return Object.fromEntries(Object.entries(ports).filter((entry)=>'number' == typeof entry[1]));
|
|
46
|
+
}
|
|
47
|
+
function normalizeCompactConfig(workspaceRoot, sourcePath, config) {
|
|
48
|
+
const packageSource = config.packageSource && 'object' == typeof config.packageSource ? {
|
|
49
|
+
strategy: 'install' === config.packageSource.strategy ? 'install' : 'workspace',
|
|
50
|
+
modernPackageVersion: 'string' == typeof config.packageSource.modernPackageVersion ? config.packageSource.modernPackageVersion : 'workspace:*',
|
|
51
|
+
registry: 'string' == typeof config.packageSource.registry ? config.packageSource.registry : void 0,
|
|
52
|
+
aliasScope: 'string' == typeof config.packageSource.aliasScope ? config.packageSource.aliasScope : void 0,
|
|
53
|
+
aliasPackageNamePrefix: 'string' == typeof config.packageSource.aliasPackageNamePrefix ? config.packageSource.aliasPackageNamePrefix : void 0
|
|
54
|
+
} : packageSourceFromMetadata(workspaceRoot);
|
|
55
|
+
return {
|
|
56
|
+
schemaVersion: 'number' == typeof config.schemaVersion ? config.schemaVersion : 1,
|
|
57
|
+
profile: 'string' == typeof config.profile ? config.profile : void 0,
|
|
58
|
+
source: 'compact',
|
|
59
|
+
sourcePath,
|
|
60
|
+
workspace: {
|
|
61
|
+
packageScope: 'string' == typeof config.workspace?.packageScope ? config.workspace.packageScope : packageScopeFromRoot(workspaceRoot)
|
|
62
|
+
},
|
|
63
|
+
packageSource,
|
|
64
|
+
features: {
|
|
65
|
+
tailwind: config.features?.tailwind !== false
|
|
66
|
+
},
|
|
67
|
+
bridge: normalizeUltramodernBridgeConfig(config.bridge),
|
|
68
|
+
topology: {
|
|
69
|
+
apps: Array.isArray(config.topology?.apps) ? config.topology.apps.map((app)=>({
|
|
70
|
+
id: String(app.id),
|
|
71
|
+
kind: 'vertical' === app.kind ? 'vertical' : 'shell',
|
|
72
|
+
path: 'string' == typeof app.path ? app.path : '.',
|
|
73
|
+
package: 'string' == typeof app.package ? app.package : void 0,
|
|
74
|
+
packageSuffix: 'string' == typeof app.packageSuffix ? app.packageSuffix : void 0,
|
|
75
|
+
displayName: 'string' == typeof app.displayName ? app.displayName : void 0,
|
|
76
|
+
domain: 'string' == typeof app.domain ? app.domain : void 0,
|
|
77
|
+
port: 'number' == typeof app.port ? app.port : void 0,
|
|
78
|
+
portEnv: 'string' == typeof app.portEnv ? app.portEnv : void 0,
|
|
79
|
+
moduleFederation: app.moduleFederation && 'object' == typeof app.moduleFederation ? {
|
|
80
|
+
role: 'remote' === app.moduleFederation.role ? 'remote' : 'host',
|
|
81
|
+
name: 'string' == typeof app.moduleFederation.name ? app.moduleFederation.name : void 0,
|
|
82
|
+
exposes: Array.isArray(app.moduleFederation.exposes) ? app.moduleFederation.exposes.filter((expose)=>'string' == typeof expose) : void 0,
|
|
83
|
+
verticalRefs: Array.isArray(app.moduleFederation.verticalRefs) ? app.moduleFederation.verticalRefs.filter((ref)=>'string' == typeof ref) : void 0,
|
|
84
|
+
hostOnly: true === app.moduleFederation.hostOnly,
|
|
85
|
+
noExposes: true === app.moduleFederation.noExposes
|
|
86
|
+
} : void 0,
|
|
87
|
+
effectApi: app.effectApi && 'object' == typeof app.effectApi ? {
|
|
88
|
+
stem: 'string' == typeof app.effectApi.stem ? app.effectApi.stem : String(app.id),
|
|
89
|
+
prefix: 'string' == typeof app.effectApi.prefix ? app.effectApi.prefix : `/${String(app.id)}-api`,
|
|
90
|
+
consumedBy: Array.isArray(app.effectApi.consumedBy) ? app.effectApi.consumedBy.filter((consumer)=>'string' == typeof consumer) : [
|
|
91
|
+
shellApp.id,
|
|
92
|
+
String(app.id)
|
|
93
|
+
]
|
|
94
|
+
} : void 0
|
|
95
|
+
})) : []
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function adaptLegacyContract(workspaceRoot, sourcePath, contract) {
|
|
100
|
+
const ports = readOverlayPorts(workspaceRoot);
|
|
101
|
+
const apps = Array.isArray(contract.apps) ? contract.apps : [];
|
|
102
|
+
const shell = apps.find((app)=>app?.id === shellApp.id);
|
|
103
|
+
return {
|
|
104
|
+
schemaVersion: 'number' == typeof contract.schemaVersion ? contract.schemaVersion : 1,
|
|
105
|
+
profile: 'string' == typeof contract.profile ? contract.profile : void 0,
|
|
106
|
+
source: 'legacy',
|
|
107
|
+
sourcePath,
|
|
108
|
+
workspace: {
|
|
109
|
+
packageScope: packageScopeFromRoot(workspaceRoot)
|
|
110
|
+
},
|
|
111
|
+
packageSource: packageSourceFromMetadata(workspaceRoot),
|
|
112
|
+
features: {
|
|
113
|
+
tailwind: shell?.styling?.tailwind !== false
|
|
114
|
+
},
|
|
115
|
+
topology: {
|
|
116
|
+
apps: apps.map((app)=>{
|
|
117
|
+
const id = String(app.id);
|
|
118
|
+
const appPath = 'string' == typeof app.path ? app.path : id === shellApp.id ? shellApp.directory : `verticals/${toKebabCase(id)}`;
|
|
119
|
+
const domain = 'string' == typeof app.i18n?.namespace && 'shell' !== app.i18n.namespace ? app.i18n.namespace : appPath.split('/').at(-1);
|
|
120
|
+
return {
|
|
121
|
+
id,
|
|
122
|
+
kind: 'vertical' === app.kind ? 'vertical' : 'shell',
|
|
123
|
+
path: appPath,
|
|
124
|
+
package: 'string' == typeof app.package ? app.package : void 0,
|
|
125
|
+
packageSuffix: 'string' == typeof app.package ? app.package.split('/').at(-1) : appPath.split('/').at(-1),
|
|
126
|
+
displayName: id === shellApp.id ? shellApp.displayName : void 0,
|
|
127
|
+
domain,
|
|
128
|
+
port: ports[id],
|
|
129
|
+
moduleFederation: app.moduleFederation && 'object' == typeof app.moduleFederation ? {
|
|
130
|
+
role: 'vertical' === app.kind ? 'remote' : 'host',
|
|
131
|
+
name: 'string' == typeof app.moduleFederation.name ? app.moduleFederation.name : void 0,
|
|
132
|
+
exposes: Array.isArray(app.moduleFederation.exposes) ? app.moduleFederation.exposes.filter((expose)=>'string' == typeof expose) : void 0,
|
|
133
|
+
verticalRefs: Array.isArray(app.moduleFederation.verticalRefs) ? app.moduleFederation.verticalRefs.filter((ref)=>'string' == typeof ref) : void 0,
|
|
134
|
+
hostOnly: 'vertical' !== app.kind
|
|
135
|
+
} : void 0,
|
|
136
|
+
effectApi: app.effect && 'object' == typeof app.effect ? {
|
|
137
|
+
stem: 'string' == typeof app.effect.prefix ? app.effect.prefix.split('/').filter(Boolean).at(-1) ?? domain ?? id : domain ?? id,
|
|
138
|
+
prefix: 'string' == typeof app.effect.prefix ? app.effect.prefix : `/${domain ?? id}-api`,
|
|
139
|
+
consumedBy: [
|
|
140
|
+
shellApp.id,
|
|
141
|
+
id
|
|
142
|
+
]
|
|
143
|
+
} : void 0
|
|
144
|
+
};
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
legacyContract: contract
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function readUltramodernConfig(workspaceRoot = process.cwd()) {
|
|
151
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
152
|
+
if (node_fs.existsSync(compactPath)) return normalizeCompactConfig(workspaceRoot, compactPath, readJsonObject(compactPath));
|
|
153
|
+
const legacyPath = node_path.join(workspaceRoot, GENERATED_CONTRACT_PATH);
|
|
154
|
+
if (node_fs.existsSync(legacyPath)) return adaptLegacyContract(workspaceRoot, legacyPath, readJsonObject(legacyPath));
|
|
155
|
+
throw new Error(`Missing UltraModern config. Expected ${ULTRAMODERN_CONFIG_PATH} or ${GENERATED_CONTRACT_PATH}.`);
|
|
156
|
+
}
|
|
157
|
+
function workspaceAppsFromToolingConfig(config) {
|
|
158
|
+
return config.topology.apps.map((app)=>{
|
|
159
|
+
if ('shell' === app.kind) return {
|
|
160
|
+
...shellApp,
|
|
161
|
+
directory: app.path,
|
|
162
|
+
packageSuffix: app.packageSuffix ?? shellApp.packageSuffix,
|
|
163
|
+
displayName: app.displayName ?? shellApp.displayName,
|
|
164
|
+
port: app.port ?? shellApp.port,
|
|
165
|
+
portEnv: app.portEnv ?? shellApp.portEnv,
|
|
166
|
+
mfName: app.moduleFederation?.name ?? shellApp.mfName,
|
|
167
|
+
verticalRefs: app.moduleFederation?.verticalRefs ?? []
|
|
168
|
+
};
|
|
169
|
+
const domain = app.domain ?? app.id;
|
|
170
|
+
const packageSuffix = app.packageSuffix ?? domain;
|
|
171
|
+
const exposes = Object.fromEntries((app.moduleFederation?.exposes ?? []).map((expose)=>[
|
|
172
|
+
expose,
|
|
173
|
+
'./Route' === expose ? './src/federation-entry.tsx' : './Widget' === expose ? `./src/components/${domain}-widget.tsx` : ''
|
|
174
|
+
]));
|
|
175
|
+
return {
|
|
176
|
+
id: app.id,
|
|
177
|
+
directory: app.path,
|
|
178
|
+
packageSuffix,
|
|
179
|
+
displayName: app.displayName ?? `${domain} Vertical`,
|
|
180
|
+
kind: 'vertical',
|
|
181
|
+
domain,
|
|
182
|
+
portEnv: app.portEnv ?? `VERTICAL_${domain.replace(/[^a-zA-Z0-9]+/g, '_').toUpperCase()}_PORT`,
|
|
183
|
+
port: app.port ?? 0,
|
|
184
|
+
mfName: app.moduleFederation?.name ?? app.id,
|
|
185
|
+
exposes,
|
|
186
|
+
...app.moduleFederation?.verticalRefs ? {
|
|
187
|
+
verticalRefs: app.moduleFederation.verticalRefs
|
|
188
|
+
} : {},
|
|
189
|
+
...app.effectApi ? {
|
|
190
|
+
effectApi: app.effectApi
|
|
191
|
+
} : {},
|
|
192
|
+
ownership: createNeutralOwnership(app.id)
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
export { readUltramodernConfig, workspaceAppsFromToolingConfig };
|
|
@@ -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";
|
|
5
6
|
import { createAppEnvDts, createAppRuntimeConfig, createShellFrameComponent } from "./app-files.js";
|
|
6
|
-
import { createGeneratedContract } from "./contracts.js";
|
|
7
7
|
import { createShellPage, createShellRemoteComponents } from "./demo-components.js";
|
|
8
|
-
import { GENERATED_CONTRACT_PATH, appHasEffectApi, appI18nNamespace, createModuleFederationRemoteContracts, createNeutralOwnership, createRemoteManifestEnv, createShellHost, createVerticalDescriptor, effectApiPrefix, remoteDependencyAlias, shellApp, zephyrRemoteDependency } from "./descriptors.js";
|
|
8
|
+
import { GENERATED_CONTRACT_PATH, ULTRAMODERN_CONFIG_PATH, appHasEffectApi, appI18nNamespace, createModuleFederationRemoteContracts, createNeutralOwnership, createRemoteManifestEnv, createShellHost, createVerticalDescriptor, effectApiPrefix, remoteDependencyAlias, shellApp, zephyrRemoteDependency } from "./descriptors.js";
|
|
9
9
|
import { createShellEffectClient, effectApiTopologyMetadata } from "./effect-api.js";
|
|
10
|
-
import { readJsonFile, writeFileReplacing, writeJsonFile } from "./fs-io.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,7 +19,7 @@ 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';
|
|
@@ -32,7 +32,12 @@ function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
|
32
32
|
modernVersion,
|
|
33
33
|
packageSource
|
|
34
34
|
});
|
|
35
|
-
const
|
|
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
|
+
const metadataPath = node_path.join(workspaceRoot, PACKAGE_SOURCE_METADATA_PATH);
|
|
36
41
|
if (!node_fs.existsSync(metadataPath)) return resolvePackageSource({
|
|
37
42
|
targetDir: workspaceRoot,
|
|
38
43
|
packageName: node_path.basename(workspaceRoot),
|
|
@@ -55,6 +60,8 @@ function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
62
|
function existingTailwindEnabled(workspaceRoot) {
|
|
63
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
64
|
+
if (node_fs.existsSync(compactPath)) return readUltramodernConfig(workspaceRoot).features.tailwind;
|
|
58
65
|
const contractPath = node_path.join(workspaceRoot, GENERATED_CONTRACT_PATH);
|
|
59
66
|
if (!node_fs.existsSync(contractPath)) return true;
|
|
60
67
|
const contract = readJsonFile(contractPath);
|
|
@@ -62,6 +69,10 @@ function existingTailwindEnabled(workspaceRoot) {
|
|
|
62
69
|
const shell = apps.find((app)=>isRecord(app) && app.id === shellApp.id);
|
|
63
70
|
return shell?.styling && isRecord(shell.styling) ? false !== shell.styling.tailwind : true;
|
|
64
71
|
}
|
|
72
|
+
function existingBridgeConfig(workspaceRoot) {
|
|
73
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
74
|
+
return node_fs.existsSync(compactPath) ? readUltramodernConfig(workspaceRoot).bridge : void 0;
|
|
75
|
+
}
|
|
65
76
|
function assertValidVerticalName(name) {
|
|
66
77
|
const normalized = toKebabCase(name);
|
|
67
78
|
if (!normalized || normalized !== name) throw new Error(`Invalid Vertical name "${name}". Use lowercase kebab-case.`);
|
|
@@ -74,17 +85,17 @@ function nextAvailablePort(ports) {
|
|
|
74
85
|
function assertCanCreate(workspaceRoot, relativePath) {
|
|
75
86
|
if (node_fs.existsSync(node_path.join(workspaceRoot, relativePath))) throw new Error(`Refusing to overwrite existing path: ${relativePath}`);
|
|
76
87
|
}
|
|
77
|
-
function updateRootWorkspaceScripts(workspaceRoot, scope, packageSource, remotes) {
|
|
88
|
+
function updateRootWorkspaceScripts(workspaceRoot, scope, packageSource, remotes, bridge) {
|
|
78
89
|
const packagePath = node_path.join(workspaceRoot, 'package.json');
|
|
79
90
|
const rootPackage = readJsonFile(packagePath);
|
|
80
|
-
const generatedRootPackage = createRootPackageJson(scope, packageSource, remotes);
|
|
91
|
+
const generatedRootPackage = createRootPackageJson(scope, packageSource, remotes, bridge);
|
|
81
92
|
rootPackage.scripts = generatedRootPackage.scripts;
|
|
82
93
|
writeJsonFile(packagePath, rootPackage);
|
|
83
94
|
}
|
|
84
|
-
function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwind, remotes) {
|
|
95
|
+
function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwind, remotes, bridge) {
|
|
85
96
|
const shellHost = createShellHost(remotes);
|
|
86
97
|
const publicWeb = createPublicWebAppArtifacts(shellHost);
|
|
87
|
-
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/package.json`), createAppPackage(scope, shellHost, packageSource, enableTailwind, remotes));
|
|
98
|
+
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/package.json`), createAppPackage(scope, shellHost, packageSource, enableTailwind, remotes, bridge));
|
|
88
99
|
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/tsconfig.json`), createAppTsConfig(shellHost, remotes));
|
|
89
100
|
writeJsonFile(node_path.join(workspaceRoot, `${shellApp.directory}/tsconfig.mf-types.json`), createAppMfTypesTsConfig(shellHost));
|
|
90
101
|
writeFileReplacing(workspaceRoot, `${shellApp.directory}/src/modern-app-env.d.ts`, createAppEnvDts(shellHost, remotes));
|
|
@@ -203,8 +214,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
203
214
|
const topology = readRequiredJsonObject(topologyPath);
|
|
204
215
|
const ownership = readRequiredJsonObject(ownershipPath);
|
|
205
216
|
const overlay = readRequiredJsonObject(overlayPath);
|
|
206
|
-
|
|
207
|
-
readRequiredJsonObject(node_path.join(options.workspaceRoot, PACKAGE_SOURCE_METADATA_PATH));
|
|
217
|
+
readRequiredWorkspaceConfig(options.workspaceRoot);
|
|
208
218
|
assertOptionalJsonObject(topology.shell, 'topology.shell', topologyPath);
|
|
209
219
|
assertOptionalJsonArray(topology.verticals, 'topology.verticals', topologyPath);
|
|
210
220
|
assertOptionalJsonArray(ownership.owners, 'ownership.owners', ownershipPath);
|
|
@@ -215,6 +225,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
215
225
|
const scope = toPackageScope(String(rootPackage.name ?? node_path.basename(options.workspaceRoot)));
|
|
216
226
|
const packageSource = existingPackageSource(options.workspaceRoot, options.modernVersion, options.packageSource);
|
|
217
227
|
const enableTailwind = options.enableTailwind ?? existingTailwindEnabled(options.workspaceRoot);
|
|
228
|
+
const bridge = existingBridgeConfig(options.workspaceRoot);
|
|
218
229
|
const existingVerticals = verticalsFromTopology(topology, overlay.ports);
|
|
219
230
|
const port = nextAvailablePort(overlay.ports);
|
|
220
231
|
const vertical = createVerticalDescriptor(name, port);
|
|
@@ -242,6 +253,7 @@ function prepareAddUltramodernVertical(options) {
|
|
|
242
253
|
overlay,
|
|
243
254
|
packageSource,
|
|
244
255
|
enableTailwind,
|
|
256
|
+
bridge,
|
|
245
257
|
vertical,
|
|
246
258
|
updatedVerticals
|
|
247
259
|
};
|
|
@@ -252,6 +264,12 @@ function readRequiredJsonObject(filePath) {
|
|
|
252
264
|
if (!isRecord(value)) throw new Error(`UltraModern workspace file must contain a JSON object: ${filePath}`);
|
|
253
265
|
return value;
|
|
254
266
|
}
|
|
267
|
+
function readRequiredWorkspaceConfig(workspaceRoot) {
|
|
268
|
+
const compactPath = node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH);
|
|
269
|
+
if (node_fs.existsSync(compactPath)) return void readRequiredJsonObject(compactPath);
|
|
270
|
+
readRequiredJsonObject(node_path.join(workspaceRoot, GENERATED_CONTRACT_PATH));
|
|
271
|
+
readRequiredJsonObject(node_path.join(workspaceRoot, PACKAGE_SOURCE_METADATA_PATH));
|
|
272
|
+
}
|
|
255
273
|
function assertOptionalJsonObject(value, label, filePath) {
|
|
256
274
|
if (void 0 !== value && !isRecord(value)) throw new Error(`${label} in ${filePath} must be a JSON object`);
|
|
257
275
|
}
|
|
@@ -356,7 +374,7 @@ function createVerticalPlan(preflight, result) {
|
|
|
356
374
|
shellDependencyChanges: createShellDependencyChanges(scope, vertical),
|
|
357
375
|
generatedContractChanges: [
|
|
358
376
|
{
|
|
359
|
-
path:
|
|
377
|
+
path: ULTRAMODERN_CONFIG_PATH,
|
|
360
378
|
addedAppIds: [
|
|
361
379
|
vertical.id
|
|
362
380
|
],
|
|
@@ -443,9 +461,9 @@ function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
|
443
461
|
description: 'Keep shell Module Federation DTS compilation scoped'
|
|
444
462
|
},
|
|
445
463
|
{
|
|
446
|
-
path:
|
|
447
|
-
pointer: '/apps',
|
|
448
|
-
description: `Regenerate
|
|
464
|
+
path: ULTRAMODERN_CONFIG_PATH,
|
|
465
|
+
pointer: '/topology/apps',
|
|
466
|
+
description: `Regenerate compact config with ${vertical.id}`
|
|
449
467
|
}
|
|
450
468
|
];
|
|
451
469
|
}
|
|
@@ -469,8 +487,8 @@ function createShellDependencyChanges(scope, vertical) {
|
|
|
469
487
|
}
|
|
470
488
|
function addUltramodernVertical(options) {
|
|
471
489
|
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);
|
|
490
|
+
const { scope, topologyPath, ownershipPath, overlayPath, topology, ownership, overlay, packageSource, enableTailwind, bridge, vertical, updatedVerticals } = prepareAddUltramodernVertical(options);
|
|
491
|
+
writeApp(options.workspaceRoot, scope, vertical, packageSource, enableTailwind, updatedVerticals, bridge);
|
|
474
492
|
topology.shell ??= {};
|
|
475
493
|
topology.shell.verticalRefs ??= [];
|
|
476
494
|
topology.shell.verticalRefs.push(vertical.id);
|
|
@@ -493,18 +511,18 @@ function addUltramodernVertical(options) {
|
|
|
493
511
|
writeJsonFile(topologyPath, topology);
|
|
494
512
|
writeJsonFile(ownershipPath, ownership);
|
|
495
513
|
writeJsonFile(overlayPath, overlay);
|
|
496
|
-
writeJsonFile(node_path.join(options.workspaceRoot,
|
|
514
|
+
writeJsonFile(node_path.join(options.workspaceRoot, ULTRAMODERN_CONFIG_PATH), createCompactUltramodernConfig(scope, options.modernVersion, packageSource, [
|
|
497
515
|
{
|
|
498
516
|
...shellApp,
|
|
499
517
|
verticalRefs: updatedVerticals.map((vertical)=>vertical.id)
|
|
500
518
|
},
|
|
501
519
|
...updatedVerticals
|
|
502
|
-
], enableTailwind));
|
|
503
|
-
rewriteShellAppFiles(options.workspaceRoot, scope, packageSource, enableTailwind, updatedVerticals);
|
|
520
|
+
], enableTailwind, bridge));
|
|
521
|
+
rewriteShellAppFiles(options.workspaceRoot, scope, packageSource, enableTailwind, updatedVerticals, bridge);
|
|
504
522
|
writeGeneratedWorkspaceScripts(options.workspaceRoot, scope, enableTailwind, updatedVerticals);
|
|
505
523
|
addShellZephyrDependency(options.workspaceRoot, scope, vertical);
|
|
506
524
|
addShellWorkspaceDependency(options.workspaceRoot, scope, vertical);
|
|
507
|
-
updateRootWorkspaceScripts(options.workspaceRoot, scope, packageSource, updatedVerticals);
|
|
525
|
+
updateRootWorkspaceScripts(options.workspaceRoot, scope, packageSource, updatedVerticals, bridge);
|
|
508
526
|
writeJsonFile(node_path.join(options.workspaceRoot, 'tsconfig.json'), createRootTsConfig([
|
|
509
527
|
{
|
|
510
528
|
...shellApp,
|
|
@@ -512,9 +530,9 @@ function addUltramodernVertical(options) {
|
|
|
512
530
|
},
|
|
513
531
|
...updatedVerticals
|
|
514
532
|
]));
|
|
515
|
-
const
|
|
516
|
-
const
|
|
517
|
-
const
|
|
533
|
+
const preliminaryAfterFiles = createFileSnapshot(options.workspaceRoot);
|
|
534
|
+
const preliminaryDiff = diffFileSnapshots(beforeFiles, preliminaryAfterFiles);
|
|
535
|
+
const preliminaryResult = createGenerationResult({
|
|
518
536
|
operation: 'vertical',
|
|
519
537
|
workspaceRoot: options.workspaceRoot,
|
|
520
538
|
packageScope: scope,
|
|
@@ -522,14 +540,32 @@ function addUltramodernVertical(options) {
|
|
|
522
540
|
createdApps: [
|
|
523
541
|
vertical
|
|
524
542
|
],
|
|
525
|
-
createdPaths,
|
|
526
|
-
rewrittenPaths
|
|
543
|
+
createdPaths: preliminaryDiff.createdPaths,
|
|
544
|
+
rewrittenPaths: preliminaryDiff.rewrittenPaths
|
|
527
545
|
});
|
|
528
546
|
runCodeSmithOverlays({
|
|
529
547
|
workspaceRoot: options.workspaceRoot,
|
|
530
548
|
overlays: options.overlays,
|
|
531
|
-
result
|
|
549
|
+
result: preliminaryResult
|
|
550
|
+
});
|
|
551
|
+
const afterOverlaysFiles = createFileSnapshot(options.workspaceRoot);
|
|
552
|
+
const changedPaths = diffFileSnapshots(beforeFiles, afterOverlaysFiles);
|
|
553
|
+
formatGeneratedWorkspaceFiles(options.workspaceRoot, [
|
|
554
|
+
...changedPaths.createdPaths,
|
|
555
|
+
...changedPaths.rewrittenPaths
|
|
556
|
+
]);
|
|
557
|
+
const afterFiles = createFileSnapshot(options.workspaceRoot);
|
|
558
|
+
const { createdPaths, rewrittenPaths } = diffFileSnapshots(beforeFiles, afterFiles);
|
|
559
|
+
return createGenerationResult({
|
|
560
|
+
operation: 'vertical',
|
|
561
|
+
workspaceRoot: options.workspaceRoot,
|
|
562
|
+
packageScope: scope,
|
|
563
|
+
packageSource,
|
|
564
|
+
createdApps: [
|
|
565
|
+
vertical
|
|
566
|
+
],
|
|
567
|
+
createdPaths,
|
|
568
|
+
rewrittenPaths
|
|
532
569
|
});
|
|
533
|
-
return result;
|
|
534
570
|
}
|
|
535
|
-
export { addShellWorkspaceDependency, addShellZephyrDependency, addUltramodernVertical, assertCanCreate, assertValidVerticalName, existingPackageSource, existingTailwindEnabled, nextAvailablePort, ownershipEntry, planUltramodernVertical, prepareAddUltramodernVertical, rewriteShellAppFiles, updateRootWorkspaceScripts, verticalTopologyEntry, verticalsFromTopology };
|
|
571
|
+
export { addShellWorkspaceDependency, addShellZephyrDependency, addUltramodernVertical, assertCanCreate, assertValidVerticalName, existingBridgeConfig, existingPackageSource, existingTailwindEnabled, nextAvailablePort, ownershipEntry, planUltramodernVertical, prepareAddUltramodernVertical, rewriteShellAppFiles, updateRootWorkspaceScripts, verticalTopologyEntry, verticalsFromTopology };
|