@bleedingdev/modern-js-create 3.4.0-ultramodern.12 → 3.4.0-ultramodern.13
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 +39 -18
- 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/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 +37 -8
- 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 +39 -21
- 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/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 +38 -12
- 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 +39 -21
- 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/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 +38 -12
- 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/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 +3 -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
|
@@ -80,7 +80,7 @@ const effectDiagnostics = [
|
|
|
80
80
|
'unnecessaryPipe',
|
|
81
81
|
'unnecessaryPipeChain'
|
|
82
82
|
];
|
|
83
|
-
function appDependencies(scope, packageSource, app, remotes = []) {
|
|
83
|
+
function appDependencies(scope, packageSource, app, remotes = [], bridge) {
|
|
84
84
|
const dependencies = {
|
|
85
85
|
'@modern-js/plugin-tanstack': modernPackageSpecifier('@modern-js/plugin-tanstack', packageSource),
|
|
86
86
|
'@modern-js/plugin-i18n': modernPackageSpecifier('@modern-js/plugin-i18n', packageSource),
|
|
@@ -97,6 +97,7 @@ function appDependencies(scope, packageSource, app, remotes = []) {
|
|
|
97
97
|
'react-dom': REACT_DOM_VERSION,
|
|
98
98
|
'react-router': REACT_ROUTER_VERSION
|
|
99
99
|
};
|
|
100
|
+
for (const dependency of bridge?.dependencies ?? [])dependencies[dependency] = WORKSPACE_PACKAGE_VERSION;
|
|
100
101
|
if ('shell' === app.kind) {
|
|
101
102
|
dependencies['@modern-js/plugin-bff'] = modernPackageSpecifier('@modern-js/plugin-bff', packageSource);
|
|
102
103
|
for (const remote of verticalEffectApps(remotes))dependencies[packageName(scope, remote.packageSuffix)] = WORKSPACE_PACKAGE_VERSION;
|
|
@@ -123,12 +124,28 @@ function appDevDependencies(packageSource, enableTailwind) {
|
|
|
123
124
|
wrangler: WRANGLER_VERSION
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
|
-
function createRootPackageJson(scope, packageSource, remotes = []) {
|
|
127
|
+
function createRootPackageJson(scope, packageSource, remotes = [], bridge) {
|
|
127
128
|
const shellFilter = `--filter ${packageName(scope, shellApp.packageSuffix)}`;
|
|
128
129
|
const remoteFilters = remotes.map((remote)=>`--filter ${packageName(scope, remote.packageSuffix)}`);
|
|
129
130
|
const remoteBuildPrefix = remotes.length > 0 ? 'ULTRAMODERN_ZEPHYR=false pnpm -r --filter "./verticals/*" run build && ' : '';
|
|
130
131
|
const remoteCloudflareBuildPrefix = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:build && ' : '';
|
|
131
132
|
const remoteCloudflareDeployPrefix = remotes.length > 0 ? 'pnpm -r --filter "./verticals/*" run cloudflare:deploy && ' : '';
|
|
133
|
+
const generatedPackageTypecheck = 'pnpm -r --filter "./apps/*" --filter "./verticals/*" --filter "./packages/*" run typecheck';
|
|
134
|
+
const typecheck = bridge ? generatedPackageTypecheck : "node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json";
|
|
135
|
+
const bridgeScripts = bridge ? {
|
|
136
|
+
...Object.fromEntries(bridge.gates.map((gate)=>[
|
|
137
|
+
`bridge:${gate.name}`,
|
|
138
|
+
`${gate.cwd ? `cd ${gate.cwd} && ` : ''}${gate.command}`
|
|
139
|
+
])),
|
|
140
|
+
'bridge:check': bridge.gates.map((gate)=>`pnpm run bridge:${gate.name}`).join(' && ')
|
|
141
|
+
} : {};
|
|
142
|
+
const bridgeCheck = bridge ? ' && pnpm bridge:check' : '';
|
|
143
|
+
const workspacePackages = [
|
|
144
|
+
'apps/*',
|
|
145
|
+
'verticals/*',
|
|
146
|
+
'packages/*',
|
|
147
|
+
...bridge?.workspacePackages.map((entry)=>entry.pattern) ?? []
|
|
148
|
+
];
|
|
132
149
|
return {
|
|
133
150
|
private: true,
|
|
134
151
|
name: scope,
|
|
@@ -150,7 +167,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
|
|
|
150
167
|
'format:check': "oxfmt --check . '!repos/**'",
|
|
151
168
|
lint: 'oxlint apps verticals packages',
|
|
152
169
|
'lint:fix': 'oxlint apps verticals packages --fix',
|
|
153
|
-
typecheck
|
|
170
|
+
typecheck,
|
|
154
171
|
'cloudflare:build': `${remoteCloudflareBuildPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm mf:types`,
|
|
155
172
|
'cloudflare:deploy': `${remoteCloudflareDeployPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:deploy`,
|
|
156
173
|
'cloudflare:proof': "node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json",
|
|
@@ -162,18 +179,15 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
|
|
|
162
179
|
'performance:readiness': "node ./scripts/ultramodern-performance-readiness.mjs",
|
|
163
180
|
'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
|
|
164
181
|
'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
|
|
182
|
+
...bridgeScripts,
|
|
165
183
|
postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall",
|
|
166
|
-
check:
|
|
184
|
+
check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
|
|
167
185
|
},
|
|
168
186
|
engines: {
|
|
169
187
|
node: '>=26',
|
|
170
188
|
pnpm: '>=11'
|
|
171
189
|
},
|
|
172
|
-
workspaces:
|
|
173
|
-
'apps/*',
|
|
174
|
-
'verticals/*',
|
|
175
|
-
'packages/*'
|
|
176
|
-
],
|
|
190
|
+
workspaces: workspacePackages,
|
|
177
191
|
modernjs: {
|
|
178
192
|
preset: 'presetUltramodern',
|
|
179
193
|
workspace: 'ultramodern-superapp',
|
|
@@ -181,7 +195,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
|
|
|
181
195
|
ownership: './topology/ownership.json',
|
|
182
196
|
packageSource: {
|
|
183
197
|
strategy: packageSource.strategy,
|
|
184
|
-
config: './.modernjs/ultramodern
|
|
198
|
+
config: './.modernjs/ultramodern.json#packageSource'
|
|
185
199
|
}
|
|
186
200
|
},
|
|
187
201
|
devDependencies: {
|
|
@@ -339,7 +353,7 @@ function createRootTsConfig(apps = []) {
|
|
|
339
353
|
]
|
|
340
354
|
};
|
|
341
355
|
}
|
|
342
|
-
function createAppPackage(scope, app, packageSource, enableTailwind, remotes = []) {
|
|
356
|
+
function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
|
|
343
357
|
const publicSurfaceBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
|
|
344
358
|
const publicSurfaceCloudflareBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
|
|
345
359
|
const publicSurfaceCloudflareOutputCommand = createPublicSurfaceGenerationCommand(app, 'cloudflare');
|
|
@@ -371,7 +385,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
|
|
|
371
385
|
} : {}
|
|
372
386
|
},
|
|
373
387
|
'zephyr:dependencies': createZephyrDependencies(scope, app, remotes),
|
|
374
|
-
dependencies: appDependencies(scope, packageSource, app, remotes),
|
|
388
|
+
dependencies: appDependencies(scope, packageSource, app, remotes, bridge),
|
|
375
389
|
devDependencies: appDevDependencies(packageSource, enableTailwind)
|
|
376
390
|
};
|
|
377
391
|
if (appHasEffectApi(app)) Object.assign(packageExports, {
|
|
@@ -7,10 +7,73 @@ import { createCloudflareSecurityContract } from "./policy.js";
|
|
|
7
7
|
import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
|
|
8
8
|
import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
|
|
9
9
|
import { CLOUDFLARE_COMPATIBILITY_DATE, NODE_VERSION, PNPM_VERSION } from "./versions.js";
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function createToolWrapperScript(command, extraArgs = []) {
|
|
11
|
+
const commandJson = JSON.stringify(command);
|
|
12
|
+
const extraArgsJson = JSON.stringify(extraArgs);
|
|
13
|
+
return `#!/usr/bin/env node
|
|
14
|
+
import { spawnSync } from 'node:child_process';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
|
|
18
|
+
const createBin = process.env.ULTRAMODERN_CREATE_BIN;
|
|
19
|
+
const forwardedArgs = process.argv.slice(2);
|
|
20
|
+
const workspaceRoot =
|
|
21
|
+
process.env.ULTRAMODERN_WORKSPACE_ROOT ??
|
|
22
|
+
path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
23
|
+
const ultramodernArgs = ['ultramodern', ${commandJson}, ...${extraArgsJson}, ...forwardedArgs];
|
|
24
|
+
const result = createBin
|
|
25
|
+
? spawnSync(process.execPath, [createBin, ...ultramodernArgs], {
|
|
26
|
+
env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
|
|
27
|
+
stdio: 'inherit',
|
|
28
|
+
})
|
|
29
|
+
: spawnSync('modern-js-create', ultramodernArgs, {
|
|
30
|
+
env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
|
|
31
|
+
shell: process.platform === 'win32',
|
|
32
|
+
stdio: 'inherit',
|
|
13
33
|
});
|
|
34
|
+
|
|
35
|
+
if (result.error) {
|
|
36
|
+
console.error(result.error.message);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process.exit(result.status ?? 1);
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
function createSkillsToolWrapperScript() {
|
|
44
|
+
return `#!/usr/bin/env node
|
|
45
|
+
import { spawnSync } from 'node:child_process';
|
|
46
|
+
import path from 'node:path';
|
|
47
|
+
import { fileURLToPath } from 'node:url';
|
|
48
|
+
|
|
49
|
+
const createBin = process.env.ULTRAMODERN_CREATE_BIN;
|
|
50
|
+
const forwardedArgs = process.argv.slice(2);
|
|
51
|
+
const workspaceRoot =
|
|
52
|
+
process.env.ULTRAMODERN_WORKSPACE_ROOT ??
|
|
53
|
+
path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
54
|
+
const checkOnly = forwardedArgs.includes('--check');
|
|
55
|
+
const skillArgs = checkOnly
|
|
56
|
+
? ['skills', 'check', ...forwardedArgs.filter(arg => arg !== '--check')]
|
|
57
|
+
: ['skills', 'install', ...forwardedArgs];
|
|
58
|
+
const ultramodernArgs = ['ultramodern', ...skillArgs];
|
|
59
|
+
const result = createBin
|
|
60
|
+
? spawnSync(process.execPath, [createBin, ...ultramodernArgs], {
|
|
61
|
+
env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
|
|
62
|
+
stdio: 'inherit',
|
|
63
|
+
})
|
|
64
|
+
: spawnSync('modern-js-create', ultramodernArgs, {
|
|
65
|
+
env: { ...process.env, ULTRAMODERN_WORKSPACE_ROOT: workspaceRoot },
|
|
66
|
+
shell: process.platform === 'win32',
|
|
67
|
+
stdio: 'inherit',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (result.error) {
|
|
71
|
+
console.error(result.error.message);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
process.exit(result.status ?? 1);
|
|
76
|
+
`;
|
|
14
77
|
}
|
|
15
78
|
function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
|
|
16
79
|
const verticals = remotes.filter(appHasEffectApi).map((remote)=>({
|
|
@@ -64,33 +127,18 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
|
|
|
64
127
|
function createWorkspaceI18nBoundaryValidationScript() {
|
|
65
128
|
return readFileTemplate("workspace-scripts/check-ultramodern-i18n-boundaries.mjs");
|
|
66
129
|
}
|
|
67
|
-
function createPublicSurfaceAssetsScript() {
|
|
68
|
-
return readFileTemplate("workspace-scripts/generate-public-surface-assets.mjs");
|
|
69
|
-
}
|
|
70
|
-
function createCloudflareProofHelperScript() {
|
|
71
|
-
return readFileTemplate("workspace-scripts/ultramodern-cloudflare-proof.mjs");
|
|
72
|
-
}
|
|
73
|
-
function createCloudflareVersionProofScript() {
|
|
74
|
-
return readFileTemplate("workspace-scripts/proof-cloudflare-version.mjs");
|
|
75
|
-
}
|
|
76
130
|
function createPerformanceReadinessConfigScript() {
|
|
77
131
|
return readFileTemplate("workspace-scripts/ultramodern-performance-readiness.config.mjs");
|
|
78
132
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
function createUltramodernTypecheckScript() {
|
|
83
|
-
return readFileTemplate("workspace-scripts/ultramodern-typecheck.mjs");
|
|
84
|
-
}
|
|
85
|
-
function writeGeneratedWorkspaceScripts(targetDir, scope, enableTailwind, remotes = []) {
|
|
86
|
-
writeFileReplacing(targetDir, "scripts/assert-mf-types.mjs", createAssertMfTypesScript(remotes));
|
|
87
|
-
writeFileReplacing(targetDir, "scripts/validate-ultramodern-workspace.mjs", createWorkspaceValidationScript(scope, enableTailwind, remotes));
|
|
133
|
+
function writeGeneratedWorkspaceScripts(targetDir, _scope, _enableTailwind, _remotes = []) {
|
|
134
|
+
writeFileReplacing(targetDir, "scripts/assert-mf-types.mjs", createToolWrapperScript('mf-types'));
|
|
135
|
+
writeFileReplacing(targetDir, "scripts/validate-ultramodern-workspace.mjs", createToolWrapperScript('validate'));
|
|
88
136
|
writeFileReplacing(targetDir, "scripts/check-ultramodern-i18n-boundaries.mjs", createWorkspaceI18nBoundaryValidationScript());
|
|
89
|
-
writeFileReplacing(targetDir, "scripts/generate-public-surface-assets.mjs",
|
|
90
|
-
writeFileReplacing(targetDir, "scripts/
|
|
91
|
-
writeFileReplacing(targetDir, "scripts/proof-cloudflare-version.mjs", createCloudflareVersionProofScript());
|
|
137
|
+
writeFileReplacing(targetDir, "scripts/generate-public-surface-assets.mjs", createToolWrapperScript('public-surface'));
|
|
138
|
+
writeFileReplacing(targetDir, "scripts/proof-cloudflare-version.mjs", createToolWrapperScript('cloudflare-proof'));
|
|
92
139
|
writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.config.mjs", createPerformanceReadinessConfigScript());
|
|
93
|
-
writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.mjs",
|
|
94
|
-
writeFileReplacing(targetDir, "scripts/ultramodern-typecheck.mjs",
|
|
140
|
+
writeFileReplacing(targetDir, "scripts/ultramodern-performance-readiness.mjs", createToolWrapperScript('performance-readiness'));
|
|
141
|
+
writeFileReplacing(targetDir, "scripts/ultramodern-typecheck.mjs", createToolWrapperScript('typecheck'));
|
|
142
|
+
writeFileReplacing(targetDir, "scripts/bootstrap-agent-skills.mjs", createSkillsToolWrapperScript());
|
|
95
143
|
}
|
|
96
|
-
export {
|
|
144
|
+
export { createPerformanceReadinessConfigScript, createWorkspaceI18nBoundaryValidationScript, createWorkspaceValidationScript, writeGeneratedWorkspaceScripts };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import node_fs from "node:fs";
|
|
2
2
|
import { createAppEnvDts, createAppRuntimeConfig, createAppStyles, createPostcssConfig, createSharedDesignTokensCss, createShellFrameComponent, createTailwindConfig } from "./app-files.js";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeUltramodernBridgeConfig } from "./bridge-config.js";
|
|
4
|
+
import { createDevelopmentOverlay, createOwnership, createTopology, createUltramodernConfig } from "./contracts.js";
|
|
4
5
|
import { createLayout, createRemoteEntry, createRemoteExposeComponent, createRemotePage, createShellPage, createShellRemoteComponents, remoteComponentOutputPath } from "./demo-components.js";
|
|
5
|
-
import {
|
|
6
|
+
import { ULTRAMODERN_CONFIG_PATH, appHasEffectApi, appI18nNamespace, createShellHost, sharedPackages, shellApp } from "./descriptors.js";
|
|
6
7
|
import { createEffectClient, createEffectServiceEntry, createEffectSharedApi, createShellEffectClient } from "./effect-api.js";
|
|
7
|
-
import { copyRootTemplate, writeFile, writeJson } from "./fs-io.js";
|
|
8
|
+
import { copyRootTemplate, writeFile, writeFileReplacing, writeJson } from "./fs-io.js";
|
|
8
9
|
import { createFileSnapshot, createGenerationResult, diffFileSnapshots } from "./generation-result.js";
|
|
9
10
|
import { createAppPublicLocaleMessages } from "./locales.js";
|
|
10
11
|
import { createAppModernConfig, createRemoteModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule, createUltramodernBuildReexportModule } from "./module-federation.js";
|
|
@@ -15,13 +16,13 @@ import { resolvePackageSource } from "./package-source.js";
|
|
|
15
16
|
import { createPublicWebAppArtifacts } from "./public-surface.js";
|
|
16
17
|
import { NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
|
|
17
18
|
import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
|
|
18
|
-
function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = []) {
|
|
19
|
+
function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
|
|
19
20
|
const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
|
|
20
21
|
const publicWeb = createPublicWebAppArtifacts(resolvedApp);
|
|
21
22
|
const writeAppFile = (relativePath, content)=>{
|
|
22
23
|
writeFile(targetDir, `${resolvedApp.directory}/${relativePath}`, content);
|
|
23
24
|
};
|
|
24
|
-
writeJson(targetDir, `${resolvedApp.directory}/package.json`, createAppPackage(scope, resolvedApp, packageSource, enableTailwind, remotes));
|
|
25
|
+
writeJson(targetDir, `${resolvedApp.directory}/package.json`, createAppPackage(scope, resolvedApp, packageSource, enableTailwind, remotes, bridge));
|
|
25
26
|
writeJson(targetDir, `${resolvedApp.directory}/tsconfig.json`, createAppTsConfig(resolvedApp, remotes));
|
|
26
27
|
writeJson(targetDir, `${resolvedApp.directory}/tsconfig.mf-types.json`, createAppMfTypesTsConfig(resolvedApp));
|
|
27
28
|
writeFile(targetDir, `${resolvedApp.directory}/src/modern-app-env.d.ts`, createAppEnvDts(resolvedApp, remotes));
|
|
@@ -80,10 +81,36 @@ function writeSharedPackages(targetDir, scope) {
|
|
|
80
81
|
`);
|
|
81
82
|
writeFile(targetDir, 'packages/shared-design-tokens/src/tokens.css', createSharedDesignTokensCss());
|
|
82
83
|
}
|
|
84
|
+
function createCompactRootPackageJson(scope, packageSource, remotes, bridge) {
|
|
85
|
+
const rootPackage = createRootPackageJson(scope, packageSource, remotes, bridge);
|
|
86
|
+
if (rootPackage.modernjs?.packageSource && 'object' == typeof rootPackage.modernjs.packageSource) rootPackage.modernjs.packageSource.config = `./${ULTRAMODERN_CONFIG_PATH}`;
|
|
87
|
+
return rootPackage;
|
|
88
|
+
}
|
|
89
|
+
function createCompactUltramodernConfig(scope, modernVersion, packageSource, apps = [
|
|
90
|
+
createShellHost()
|
|
91
|
+
], enableTailwind = true, bridge) {
|
|
92
|
+
const config = createUltramodernConfig(scope, modernVersion, packageSource, apps, enableTailwind, bridge);
|
|
93
|
+
if (config.packageSource && 'object' == typeof config.packageSource && !Array.isArray(config.packageSource)) delete config.packageSource.metadata;
|
|
94
|
+
return config;
|
|
95
|
+
}
|
|
96
|
+
function writePnpmWorkspacePackages(targetDir, bridge) {
|
|
97
|
+
if (!bridge) return;
|
|
98
|
+
const pnpmWorkspacePath = `${targetDir}/pnpm-workspace.yaml`;
|
|
99
|
+
const pnpmWorkspace = node_fs.readFileSync(pnpmWorkspacePath, 'utf-8');
|
|
100
|
+
const packages = [
|
|
101
|
+
'apps/*',
|
|
102
|
+
'verticals/*',
|
|
103
|
+
'packages/*',
|
|
104
|
+
...bridge.workspacePackages.map((entry)=>entry.pattern)
|
|
105
|
+
];
|
|
106
|
+
const renderedPackages = packages.map((pattern)=>` - ${pattern}`).join('\n');
|
|
107
|
+
writeFileReplacing(targetDir, 'pnpm-workspace.yaml', pnpmWorkspace.replace(/^packages:\n(?: {2}- .+\n)+/u, `packages:\n${renderedPackages}\n`));
|
|
108
|
+
}
|
|
83
109
|
function generateUltramodernWorkspace(options) {
|
|
84
110
|
const beforeFiles = createFileSnapshot(options.targetDir);
|
|
85
111
|
const scope = toPackageScope(options.packageName);
|
|
86
112
|
const packageSource = resolvePackageSource(options);
|
|
113
|
+
const bridge = normalizeUltramodernBridgeConfig(options.bridge);
|
|
87
114
|
const enableTailwind = false !== options.enableTailwind;
|
|
88
115
|
const initialVerticals = [];
|
|
89
116
|
const createdApps = [
|
|
@@ -108,17 +135,16 @@ function generateUltramodernWorkspace(options) {
|
|
|
108
135
|
typescriptVersion: TYPESCRIPT_VERSION,
|
|
109
136
|
tailwindEnabled: String(enableTailwind)
|
|
110
137
|
});
|
|
111
|
-
|
|
138
|
+
writePnpmWorkspacePackages(options.targetDir, bridge);
|
|
139
|
+
writeJson(options.targetDir, 'package.json', createCompactRootPackageJson(scope, packageSource, initialVerticals, bridge));
|
|
112
140
|
writeJson(options.targetDir, 'tsconfig.base.json', createTsConfigBase());
|
|
113
141
|
writeJson(options.targetDir, 'tsconfig.json', createRootTsConfig(createdApps));
|
|
114
142
|
writeJson(options.targetDir, 'topology/reference-topology.json', createTopology(scope, initialVerticals));
|
|
115
143
|
writeJson(options.targetDir, 'topology/ownership.json', createOwnership(scope, initialVerticals));
|
|
116
144
|
writeJson(options.targetDir, 'topology/local-overlays/development.json', createDevelopmentOverlay(initialVerticals));
|
|
117
|
-
writeJson(options.targetDir,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
writeApp(options.targetDir, scope, shellApp, packageSource, enableTailwind, initialVerticals);
|
|
121
|
-
for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals);
|
|
145
|
+
writeJson(options.targetDir, ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
|
|
146
|
+
writeApp(options.targetDir, scope, shellApp, packageSource, enableTailwind, initialVerticals, bridge);
|
|
147
|
+
for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
|
|
122
148
|
writeSharedPackages(options.targetDir, scope);
|
|
123
149
|
writeGeneratedWorkspaceScripts(options.targetDir, scope, enableTailwind, initialVerticals);
|
|
124
150
|
const afterFiles = createFileSnapshot(options.targetDir);
|
|
@@ -139,4 +165,4 @@ function generateUltramodernWorkspace(options) {
|
|
|
139
165
|
});
|
|
140
166
|
return result;
|
|
141
167
|
}
|
|
142
|
-
export { generateUltramodernWorkspace, writeApp, writeSharedPackages };
|
|
168
|
+
export { createCompactUltramodernConfig, generateUltramodernWorkspace, writeApp, writeSharedPackages };
|
package/dist/esm-node/index.js
CHANGED
|
@@ -7,7 +7,9 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { resolveCreatePackageRoot } from "./create-package-root.js";
|
|
8
8
|
import { i18n, localeKeys } from "./locale/index.js";
|
|
9
9
|
import { BLEEDINGDEV_CREATE_PACKAGE, BLEEDINGDEV_FRAMEWORK_VERSION_ENV, BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, WORKSPACE_PACKAGE_VERSION } from "./ultramodern-package-source.js";
|
|
10
|
+
import { runUltramodernToolingCli } from "./ultramodern-tooling/commands.js";
|
|
10
11
|
import { addUltramodernVertical, generateUltramodernWorkspace, planUltramodernVertical } from "./ultramodern-workspace/index.js";
|
|
12
|
+
import { hasUltramodernBridgeCliOptions, parseUltramodernBridgeCliOptions, ultramodernBridgeCliBooleanFlags, ultramodernBridgeCliValueFlags } from "./ultramodern-workspace/bridge-config.js";
|
|
11
13
|
const src_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
12
14
|
const createPackageRoot = resolveCreatePackageRoot(src_dirname);
|
|
13
15
|
const semverPattern = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
@@ -85,6 +87,16 @@ function showHelp() {
|
|
|
85
87
|
console.log(i18n.t(localeKeys.help.optionUltramodernPackageRegistry));
|
|
86
88
|
console.log(i18n.t(localeKeys.help.optionUltramodernPackageScope));
|
|
87
89
|
console.log(i18n.t(localeKeys.help.optionUltramodernPackageNamePrefix));
|
|
90
|
+
console.log(i18n.t(localeKeys.help.optionBridge));
|
|
91
|
+
console.log(i18n.t(localeKeys.help.optionBridgeParentRoot));
|
|
92
|
+
console.log(i18n.t(localeKeys.help.optionBridgeWorkspacePackage));
|
|
93
|
+
console.log(i18n.t(localeKeys.help.optionBridgeWorkspacePackageName));
|
|
94
|
+
console.log(i18n.t(localeKeys.help.optionBridgeTestAlias));
|
|
95
|
+
console.log(i18n.t(localeKeys.help.optionBridgeDependency));
|
|
96
|
+
console.log(i18n.t(localeKeys.help.optionBridgeLockfilePolicy));
|
|
97
|
+
console.log(i18n.t(localeKeys.help.optionBridgeGate));
|
|
98
|
+
console.log(i18n.t(localeKeys.help.optionBridgeGateCwd));
|
|
99
|
+
console.log(i18n.t(localeKeys.help.optionBridgeReactSingleton));
|
|
88
100
|
console.log(i18n.t(localeKeys.help.optionVertical));
|
|
89
101
|
console.log(i18n.t(localeKeys.help.optionVerticalName));
|
|
90
102
|
console.log(i18n.t(localeKeys.help.optionDryRun));
|
|
@@ -198,7 +210,8 @@ function collectPositionalArgs(args) {
|
|
|
198
210
|
'--ultramodern-package-scope',
|
|
199
211
|
'--ultramodern-package-name-prefix',
|
|
200
212
|
VERTICAL_NAME_FLAG,
|
|
201
|
-
CODESMITH_OVERLAY_FLAG
|
|
213
|
+
CODESMITH_OVERLAY_FLAG,
|
|
214
|
+
...ultramodernBridgeCliValueFlags
|
|
202
215
|
]);
|
|
203
216
|
const optionWithoutValue = new Set([
|
|
204
217
|
'--help',
|
|
@@ -211,7 +224,8 @@ function collectPositionalArgs(args) {
|
|
|
211
224
|
WORKSPACE_PROTOCOL_FLAG,
|
|
212
225
|
DRY_RUN_FLAG,
|
|
213
226
|
VERTICAL_FLAG,
|
|
214
|
-
LEGACY_MODERN_JS_FLAG
|
|
227
|
+
LEGACY_MODERN_JS_FLAG,
|
|
228
|
+
...ultramodernBridgeCliBooleanFlags
|
|
215
229
|
]);
|
|
216
230
|
const positionalArgs = [];
|
|
217
231
|
for(let i = 0; i < args.length; i++){
|
|
@@ -221,7 +235,7 @@ function collectPositionalArgs(args) {
|
|
|
221
235
|
i += 1;
|
|
222
236
|
continue;
|
|
223
237
|
}
|
|
224
|
-
if (!(arg.startsWith('--lang=') || arg.startsWith(`${BFF_RUNTIME_OPTION}=`) || arg.startsWith('--ultramodern-package-source=') || arg.startsWith('--ultramodern-package-version=') || arg.startsWith('--ultramodern-package-registry=') || arg.startsWith('--ultramodern-package-scope=') || arg.startsWith('--ultramodern-package-name-prefix=') || arg.startsWith(`${VERTICAL_FLAG}=`) || arg.startsWith(`${VERTICAL_NAME_FLAG}=`) || arg.startsWith(`${CODESMITH_OVERLAY_FLAG}=`))) positionalArgs.push(arg);
|
|
238
|
+
if (!(arg.startsWith('--lang=') || arg.startsWith(`${BFF_RUNTIME_OPTION}=`) || arg.startsWith('--ultramodern-package-source=') || arg.startsWith('--ultramodern-package-version=') || arg.startsWith('--ultramodern-package-registry=') || arg.startsWith('--ultramodern-package-scope=') || arg.startsWith('--ultramodern-package-name-prefix=') || arg.startsWith(`${VERTICAL_FLAG}=`) || arg.startsWith(`${VERTICAL_NAME_FLAG}=`) || arg.startsWith(`${CODESMITH_OVERLAY_FLAG}=`) || ultramodernBridgeCliBooleanFlags.some((flag)=>arg.startsWith(`${flag}=`)) || ultramodernBridgeCliValueFlags.some((flag)=>arg.startsWith(`${flag}=`)))) positionalArgs.push(arg);
|
|
225
239
|
}
|
|
226
240
|
}
|
|
227
241
|
return positionalArgs;
|
|
@@ -337,6 +351,14 @@ function detectCodeSmithOverlays(args) {
|
|
|
337
351
|
}
|
|
338
352
|
return overlays.length > 0 ? overlays : void 0;
|
|
339
353
|
}
|
|
354
|
+
function readBridgeCliOptions(args) {
|
|
355
|
+
try {
|
|
356
|
+
return parseUltramodernBridgeCliOptions(args);
|
|
357
|
+
} catch (error) {
|
|
358
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
340
362
|
function detectUltramodernPackageSource(args, defaultPackageVersion, createPackage) {
|
|
341
363
|
const bleedingDevDefaults = isBleedingDevCreatePackage(createPackage);
|
|
342
364
|
const strategy = getOptionValue(args, [
|
|
@@ -546,6 +568,10 @@ async function getProjectName() {
|
|
|
546
568
|
}
|
|
547
569
|
async function main() {
|
|
548
570
|
const args = process.argv.slice(2);
|
|
571
|
+
if ('ultramodern' === args[0]) {
|
|
572
|
+
process.exitCode = await runUltramodernToolingCli(args.slice(1));
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
549
575
|
if (args.includes('--help') || args.includes('-h')) return void showHelp();
|
|
550
576
|
if (args.includes('--version') || args.includes('-v')) return void showVersion();
|
|
551
577
|
if (detectLegacyModernJsFlag(args)) {
|
|
@@ -557,10 +583,16 @@ async function main() {
|
|
|
557
583
|
const dryRun = detectDryRunFlag(args);
|
|
558
584
|
const verticalInput = resolveVerticalCliInput(args);
|
|
559
585
|
const overlays = detectCodeSmithOverlays(args);
|
|
586
|
+
const bridgeRequested = hasUltramodernBridgeCliOptions(args);
|
|
560
587
|
if (dryRun && !verticalInput.addVertical) {
|
|
561
588
|
console.error(`${DRY_RUN_FLAG} is currently supported only with ${VERTICAL_FLAG}`);
|
|
562
589
|
process.exit(1);
|
|
563
590
|
}
|
|
591
|
+
if (verticalInput.addVertical && bridgeRequested) {
|
|
592
|
+
console.error('Bridge options are supported only when creating a new UltraModern workspace.');
|
|
593
|
+
process.exit(1);
|
|
594
|
+
}
|
|
595
|
+
const bridge = readBridgeCliOptions(args);
|
|
564
596
|
if (!dryRun) console.log(`\n${i18n.t(localeKeys.message.welcome)}\n`);
|
|
565
597
|
const createPackage = readCreatePackageJson();
|
|
566
598
|
const version = createPackage.version || 'latest';
|
|
@@ -601,6 +633,7 @@ async function main() {
|
|
|
601
633
|
packageName: generatedPackageName,
|
|
602
634
|
modernVersion: version,
|
|
603
635
|
enableTailwind: detectTailwindFlag(),
|
|
636
|
+
bridge,
|
|
604
637
|
overlays,
|
|
605
638
|
packageSource
|
|
606
639
|
});
|
|
@@ -39,6 +39,16 @@ const EN_LOCALE = {
|
|
|
39
39
|
optionUltramodernPackageRegistry: ' --ultramodern-package-registry npm registry URL used for install package sources',
|
|
40
40
|
optionUltramodernPackageScope: ' --ultramodern-package-scope Publish scope for npm alias installs (for example bleedingdev)',
|
|
41
41
|
optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix Prefix for npm alias package names (default: modern-js-)',
|
|
42
|
+
optionBridge: ' --bridge Enable explicit nested parent-monorepo bridge mode for new workspaces',
|
|
43
|
+
optionBridgeParentRoot: ' --bridge-parent-root <path> Parent monorepo root for bridge mode',
|
|
44
|
+
optionBridgeWorkspacePackage: ' --bridge-workspace-package <glob> Parent workspace package glob consumed by generated apps',
|
|
45
|
+
optionBridgeWorkspacePackageName: ' --bridge-workspace-package-name <glob=package[,package]> Package names covered by a bridge workspace glob',
|
|
46
|
+
optionBridgeTestAlias: ' --bridge-test-alias <glob:alias=target> Test/source alias for a bridge workspace package glob',
|
|
47
|
+
optionBridgeDependency: ' --bridge-dependency <package[,package]> Explicit parent package dependency consumed by generated apps',
|
|
48
|
+
optionBridgeLockfilePolicy: ' --bridge-lockfile-policy <nested|parent> Bridge lockfile ownership policy (default: nested)',
|
|
49
|
+
optionBridgeGate: ' --bridge-gate <name=command> Delegated parent workspace gate command for bridge packages',
|
|
50
|
+
optionBridgeGateCwd: ' --bridge-gate-cwd <name=cwd> Working directory for a named bridge gate',
|
|
51
|
+
optionBridgeReactSingleton: ' --bridge-react-singleton <package[,package]> React singleton package expectation (default: react,react-dom)',
|
|
42
52
|
optionVertical: ' --vertical[=<name>] Mutate the current existing UltraModern workspace and wire a MicroVertical',
|
|
43
53
|
optionVerticalName: ' --vertical-name <name> Explicit MicroVertical name for automation-friendly workspace mutation',
|
|
44
54
|
optionDryRun: ' --dry-run Preview a MicroVertical mutation plan without writing files (supported with --vertical)',
|
|
@@ -39,6 +39,16 @@ const ZH_LOCALE = {
|
|
|
39
39
|
optionUltramodernPackageRegistry: ' --ultramodern-package-registry install 依赖来源使用的 npm registry 地址',
|
|
40
40
|
optionUltramodernPackageScope: ' --ultramodern-package-scope npm alias 安装使用的发布 scope(例如 bleedingdev)',
|
|
41
41
|
optionUltramodernPackageNamePrefix: ' --ultramodern-package-name-prefix npm alias 包名前缀(默认:modern-js-)',
|
|
42
|
+
optionBridge: ' --bridge 为新工作区启用显式的嵌套父 monorepo 桥接模式',
|
|
43
|
+
optionBridgeParentRoot: ' --bridge-parent-root <路径> 桥接模式使用的父 monorepo 根目录',
|
|
44
|
+
optionBridgeWorkspacePackage: ' --bridge-workspace-package <glob> 生成应用消费的父工作区包 glob',
|
|
45
|
+
optionBridgeWorkspacePackageName: ' --bridge-workspace-package-name <glob=包名[,包名]> 桥接工作区 glob 覆盖的包名',
|
|
46
|
+
optionBridgeTestAlias: ' --bridge-test-alias <glob:别名=目标> 桥接工作区包 glob 的测试/源码 alias',
|
|
47
|
+
optionBridgeDependency: ' --bridge-dependency <包名[,包名]> 生成应用显式消费的父包依赖',
|
|
48
|
+
optionBridgeLockfilePolicy: ' --bridge-lockfile-policy <nested|parent> 桥接 lockfile 归属策略(默认:nested)',
|
|
49
|
+
optionBridgeGate: ' --bridge-gate <名称=命令> 桥接包委托给父工作区执行的 gate 命令',
|
|
50
|
+
optionBridgeGateCwd: ' --bridge-gate-cwd <名称=目录> 指定桥接 gate 的工作目录',
|
|
51
|
+
optionBridgeReactSingleton: ' --bridge-react-singleton <包名[,包名]> React 单例包预期(默认:react,react-dom)',
|
|
42
52
|
optionVertical: ' --vertical[=<名称>] 修改当前已有的 UltraModern 工作区,并接入 MicroVertical',
|
|
43
53
|
optionVerticalName: ' --vertical-name <名称> 为自动化工作流显式指定 MicroVertical 名称',
|
|
44
54
|
optionDryRun: ' --dry-run 预览 MicroVertical 修改计划但不写入文件(与 --vertical 一起使用)',
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import node_fs from "node:fs";
|
|
4
|
+
import node_os from "node:os";
|
|
5
|
+
import node_path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { resolveCreatePackageRoot } from "../create-package-root.js";
|
|
8
|
+
import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
|
|
9
|
+
import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
|
|
10
|
+
import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
|
|
11
|
+
const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const createPackageRoot = resolveCreatePackageRoot(commands_dirname);
|
|
13
|
+
function printHelp() {
|
|
14
|
+
process.stdout.write(`Usage:
|
|
15
|
+
modern-js-create ultramodern <command> [args]
|
|
16
|
+
|
|
17
|
+
Commands:
|
|
18
|
+
validate
|
|
19
|
+
typecheck
|
|
20
|
+
mf-types
|
|
21
|
+
public-surface
|
|
22
|
+
cloudflare-proof
|
|
23
|
+
performance-readiness
|
|
24
|
+
skills install
|
|
25
|
+
skills check
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
function spawnNodeScript(relativeScriptPath, args, context, options = {}) {
|
|
29
|
+
const scriptPath = node_path.join(createPackageRoot, relativeScriptPath);
|
|
30
|
+
const result = spawnSync(process.execPath, [
|
|
31
|
+
scriptPath,
|
|
32
|
+
...args
|
|
33
|
+
], {
|
|
34
|
+
cwd: options.cwd ?? context.workspaceRoot,
|
|
35
|
+
env: {
|
|
36
|
+
...process.env,
|
|
37
|
+
ULTRAMODERN_WORKSPACE_ROOT: context.workspaceRoot
|
|
38
|
+
},
|
|
39
|
+
stdio: 'inherit'
|
|
40
|
+
});
|
|
41
|
+
if (result.error) throw result.error;
|
|
42
|
+
return result.status ?? 1;
|
|
43
|
+
}
|
|
44
|
+
function runRenderedModule(source, context) {
|
|
45
|
+
const tempDir = node_fs.mkdtempSync(node_path.join(node_os.tmpdir(), 'ultramodern-tool-'));
|
|
46
|
+
const tempFile = node_path.join(tempDir, 'command.mjs');
|
|
47
|
+
try {
|
|
48
|
+
node_fs.writeFileSync(tempFile, source, 'utf-8');
|
|
49
|
+
const result = spawnSync(process.execPath, [
|
|
50
|
+
tempFile
|
|
51
|
+
], {
|
|
52
|
+
cwd: context.workspaceRoot,
|
|
53
|
+
stdio: 'inherit'
|
|
54
|
+
});
|
|
55
|
+
if (result.error) throw result.error;
|
|
56
|
+
return result.status ?? 1;
|
|
57
|
+
} finally{
|
|
58
|
+
node_fs.rmSync(tempDir, {
|
|
59
|
+
force: true,
|
|
60
|
+
recursive: true
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function runValidate(context) {
|
|
65
|
+
const config = readUltramodernConfig(context.workspaceRoot);
|
|
66
|
+
const apps = workspaceAppsFromToolingConfig(config);
|
|
67
|
+
const remotes = apps.filter((app)=>'shell' !== app.kind);
|
|
68
|
+
const source = createWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes);
|
|
69
|
+
return runRenderedModule(source, context);
|
|
70
|
+
}
|
|
71
|
+
function runMfTypes(args, context) {
|
|
72
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
73
|
+
process.stdout.write(`Usage:
|
|
74
|
+
modern-js-create ultramodern mf-types [app-dir...]
|
|
75
|
+
|
|
76
|
+
Checks real Module Federation config files and DTS archives for exposed apps.
|
|
77
|
+
`);
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
validateModuleFederationTypes({
|
|
81
|
+
workspaceRoot: context.workspaceRoot,
|
|
82
|
+
appDirs: args.length > 0 ? args : void 0
|
|
83
|
+
});
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
function runSkills(args, context) {
|
|
87
|
+
const [subcommand, ...rest] = args;
|
|
88
|
+
if ('install' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", rest, context);
|
|
89
|
+
if ('check' === subcommand) return spawnNodeScript("template-workspace/scripts/bootstrap-agent-skills.mjs", [
|
|
90
|
+
'--check',
|
|
91
|
+
...rest
|
|
92
|
+
], context);
|
|
93
|
+
throw new Error('Usage: modern-js-create ultramodern skills <install|check>');
|
|
94
|
+
}
|
|
95
|
+
async function runUltramodernToolingCli(args, workspaceRoot = process.env.ULTRAMODERN_WORKSPACE_ROOT ?? process.cwd()) {
|
|
96
|
+
try {
|
|
97
|
+
const [command, ...rest] = args;
|
|
98
|
+
const context = {
|
|
99
|
+
workspaceRoot: node_path.resolve(workspaceRoot),
|
|
100
|
+
invocationCwd: process.cwd()
|
|
101
|
+
};
|
|
102
|
+
switch(command){
|
|
103
|
+
case void 0:
|
|
104
|
+
case '--help':
|
|
105
|
+
case '-h':
|
|
106
|
+
printHelp();
|
|
107
|
+
return 0;
|
|
108
|
+
case 'validate':
|
|
109
|
+
return runValidate(context);
|
|
110
|
+
case 'typecheck':
|
|
111
|
+
return spawnNodeScript("templates/workspace-scripts/ultramodern-typecheck.mjs", rest, context, {
|
|
112
|
+
cwd: context.invocationCwd
|
|
113
|
+
});
|
|
114
|
+
case 'mf-types':
|
|
115
|
+
return runMfTypes(rest, context);
|
|
116
|
+
case 'public-surface':
|
|
117
|
+
return spawnNodeScript("templates/workspace-scripts/generate-public-surface-assets.mjs", rest, context);
|
|
118
|
+
case 'cloudflare-proof':
|
|
119
|
+
return spawnNodeScript("templates/workspace-scripts/proof-cloudflare-version.mjs", rest, context);
|
|
120
|
+
case 'performance-readiness':
|
|
121
|
+
return spawnNodeScript("templates/workspace-scripts/ultramodern-performance-readiness.mjs", rest, context);
|
|
122
|
+
case 'skills':
|
|
123
|
+
return runSkills(rest, context);
|
|
124
|
+
default:
|
|
125
|
+
throw new Error(`Unknown UltraModern command: ${command}`);
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
+
process.stderr.write(`[ultramodern] ${message}\n`);
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export { runUltramodernToolingCli };
|