@bleedingdev/modern-js-create 3.4.0-ultramodern.19 → 3.4.0-ultramodern.20
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/dist/cjs/index.cjs +1 -1
- package/dist/cjs/locale/en.cjs +2 -2
- package/dist/cjs/locale/zh.cjs +2 -2
- package/dist/cjs/ultramodern-tooling/config.cjs +9 -91
- package/dist/cjs/ultramodern-workspace/add-vertical.cjs +13 -40
- package/dist/cjs/ultramodern-workspace/contracts.cjs +2 -0
- package/dist/cjs/ultramodern-workspace/demo-components.cjs +12 -12
- package/dist/cjs/ultramodern-workspace/descriptors.cjs +0 -4
- package/dist/cjs/ultramodern-workspace/effect-api.cjs +74 -75
- package/dist/cjs/ultramodern-workspace/mf-validation.cjs +1 -2
- package/dist/cjs/ultramodern-workspace/module-federation.cjs +3 -2
- package/dist/cjs/ultramodern-workspace/package-json.cjs +6 -5
- package/dist/cjs/ultramodern-workspace/policy.cjs +1 -1
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +7 -0
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +4 -4
- package/dist/esm/index.js +1 -1
- package/dist/esm/locale/en.js +2 -2
- package/dist/esm/locale/zh.js +2 -2
- package/dist/esm/ultramodern-tooling/config.js +10 -92
- package/dist/esm/ultramodern-workspace/add-vertical.js +14 -41
- package/dist/esm/ultramodern-workspace/contracts.js +2 -0
- package/dist/esm/ultramodern-workspace/demo-components.js +12 -12
- package/dist/esm/ultramodern-workspace/descriptors.js +1 -2
- package/dist/esm/ultramodern-workspace/effect-api.js +74 -75
- package/dist/esm/ultramodern-workspace/mf-validation.js +1 -2
- package/dist/esm/ultramodern-workspace/module-federation.js +3 -2
- package/dist/esm/ultramodern-workspace/package-json.js +6 -5
- package/dist/esm/ultramodern-workspace/policy.js +1 -1
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -1
- package/dist/esm/ultramodern-workspace/write-workspace.js +4 -4
- package/dist/esm-node/index.js +1 -1
- package/dist/esm-node/locale/en.js +2 -2
- package/dist/esm-node/locale/zh.js +2 -2
- package/dist/esm-node/ultramodern-tooling/config.js +10 -92
- package/dist/esm-node/ultramodern-workspace/add-vertical.js +14 -41
- package/dist/esm-node/ultramodern-workspace/contracts.js +2 -0
- package/dist/esm-node/ultramodern-workspace/demo-components.js +12 -12
- package/dist/esm-node/ultramodern-workspace/descriptors.js +1 -2
- package/dist/esm-node/ultramodern-workspace/effect-api.js +74 -75
- package/dist/esm-node/ultramodern-workspace/mf-validation.js +1 -2
- package/dist/esm-node/ultramodern-workspace/module-federation.js +3 -2
- package/dist/esm-node/ultramodern-workspace/package-json.js +6 -5
- package/dist/esm-node/ultramodern-workspace/policy.js +1 -1
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -1
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +4 -4
- package/dist/types/ultramodern-tooling/config.d.ts +1 -2
- package/dist/types/ultramodern-workspace/descriptors.d.ts +0 -1
- package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -0
- package/package.json +3 -3
- package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +1 -11
- package/templates/workspace-scripts/check-ultramodern-api-boundaries.mjs +339 -0
- package/templates/workspace-scripts/generate-public-surface-assets.mjs +14 -12
- package/templates/workspace-scripts/proof-cloudflare-version.mjs +3 -13
- package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +3 -3
- package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +1 -9
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +82 -86
package/dist/cjs/index.cjs
CHANGED
|
@@ -217,7 +217,7 @@ function detectBffRuntime(args) {
|
|
|
217
217
|
process.exit(1);
|
|
218
218
|
}
|
|
219
219
|
if (!SUPPORTED_BFF_RUNTIMES.includes(runtime)) {
|
|
220
|
-
console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold
|
|
220
|
+
console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold a strict Effect API runtime for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
|
|
221
221
|
process.exit(1);
|
|
222
222
|
}
|
|
223
223
|
return runtime;
|
package/dist/cjs/locale/en.cjs
CHANGED
|
@@ -47,7 +47,7 @@ const EN_LOCALE = {
|
|
|
47
47
|
step1: 'cd {projectName}',
|
|
48
48
|
step2: 'pnpm install',
|
|
49
49
|
step3: 'pnpm dev',
|
|
50
|
-
legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\
|
|
50
|
+
legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nBRUTAL WARNING: YOU ARE OPTING OUT OF ULTRAMODERN.JS DEFAULTS.\nThe unattended default is the best UltraModern.js configuration:\na structured SuperApp workspace, presetUltramodern, TanStack Router,\na strict Effect API runtime, Tailwind CSS v4, and the BleedingDev package cohort.\nThe original Modern.js setup is a dangerous opt-in path.\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
51
51
|
},
|
|
52
52
|
help: {
|
|
53
53
|
title: '🚀 UltraModern.js Project Creator',
|
|
@@ -59,7 +59,7 @@ const EN_LOCALE = {
|
|
|
59
59
|
optionVersion: ' -v, --version Display version information',
|
|
60
60
|
optionLang: ' -l, --lang Set the language (en default; zh opt-in)',
|
|
61
61
|
optionTailwind: ' --no-tailwind Disable default Tailwind CSS v4 workspace styling',
|
|
62
|
-
optionBff: ' --bff Keep the default Effect
|
|
62
|
+
optionBff: ' --bff Keep the default strict Effect API runtime (every MicroVertical ships one)',
|
|
63
63
|
optionBffRuntime: ' --bff-runtime Select the BFF runtime for scaffolded MicroVerticals (supported: effect; default: effect)',
|
|
64
64
|
optionWorkspace: ' --workspace Use workspace protocol for @modern-js dependencies (for local monorepo testing)',
|
|
65
65
|
optionUltramodernPackageSource: ' --ultramodern-package-source Select UltraModern package source (workspace or install; BleedingDev defaults to install aliases)',
|
package/dist/cjs/locale/zh.cjs
CHANGED
|
@@ -47,7 +47,7 @@ const ZH_LOCALE = {
|
|
|
47
47
|
step1: 'cd {projectName}',
|
|
48
48
|
step2: 'pnpm install',
|
|
49
49
|
step3: 'pnpm dev',
|
|
50
|
-
legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n严重警告:你正在退出 ULTRAMODERN.JS 默认配置。\n免交互默认值是最佳 UltraModern.js 配置:\n结构化 SuperApp 工作区、presetUltramodern、TanStack Router、\
|
|
50
|
+
legacyModernJsWarning: "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n严重警告:你正在退出 ULTRAMODERN.JS 默认配置。\n免交互默认值是最佳 UltraModern.js 配置:\n结构化 SuperApp 工作区、presetUltramodern、TanStack Router、\n严格 Effect API 运行时、Tailwind CSS v4,以及 BleedingDev 包版本队列。\n原始 Modern.js 初始化是危险的显式选择路径。\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
51
51
|
},
|
|
52
52
|
help: {
|
|
53
53
|
title: '🚀 UltraModern.js 项目创建工具',
|
|
@@ -59,7 +59,7 @@ const ZH_LOCALE = {
|
|
|
59
59
|
optionVersion: ' -v, --version 显示版本信息',
|
|
60
60
|
optionLang: ' -l, --lang 设置语言 (默认 en;zh 需显式选择)',
|
|
61
61
|
optionTailwind: ' --no-tailwind 禁用默认 Tailwind CSS v4 工作区样式',
|
|
62
|
-
optionBff: ' --bff
|
|
62
|
+
optionBff: ' --bff 保留默认的严格 Effect API 运行时(每个 MicroVertical 自带一个)',
|
|
63
63
|
optionBffRuntime: ' --bff-runtime 选择 MicroVertical 脚手架的 BFF 运行时(支持: effect;默认: effect)',
|
|
64
64
|
optionWorkspace: ' --workspace 对 @modern-js 依赖使用 workspace 协议(用于本地 monorepo 联调)',
|
|
65
65
|
optionUltramodernPackageSource: ' --ultramodern-package-source 选择 UltraModern 依赖来源(workspace 或 install;BleedingDev 默认使用 install alias)',
|
|
@@ -47,8 +47,6 @@ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_no
|
|
|
47
47
|
const bridge_config_cjs_namespaceObject = require("../ultramodern-workspace/bridge-config.cjs");
|
|
48
48
|
const descriptors_cjs_namespaceObject = require("../ultramodern-workspace/descriptors.cjs");
|
|
49
49
|
const naming_cjs_namespaceObject = require("../ultramodern-workspace/naming.cjs");
|
|
50
|
-
const PACKAGE_SOURCE_METADATA_PATH = '.modernjs/ultramodern-package-source.json';
|
|
51
|
-
const DEVELOPMENT_OVERLAY_PATH = 'topology/local-overlays/development.json';
|
|
52
50
|
function readJsonObject(filePath) {
|
|
53
51
|
const value = JSON.parse(external_node_fs_default().readFileSync(filePath, 'utf-8'));
|
|
54
52
|
if (null === value || 'object' != typeof value || Array.isArray(value)) throw new Error(`UltraModern config must contain a JSON object: ${filePath}`);
|
|
@@ -57,45 +55,18 @@ function readJsonObject(filePath) {
|
|
|
57
55
|
function readOptionalJsonObject(filePath) {
|
|
58
56
|
return external_node_fs_default().existsSync(filePath) ? readJsonObject(filePath) : {};
|
|
59
57
|
}
|
|
60
|
-
function packageScopeFromRoot(
|
|
61
|
-
const rootPackage = readOptionalJsonObject(external_node_path_default().join(
|
|
62
|
-
return 'string' == typeof rootPackage.name && rootPackage.name.length > 0 ? rootPackage.name : external_node_path_default().basename(
|
|
58
|
+
function packageScopeFromRoot(workspaceRoot1) {
|
|
59
|
+
const rootPackage = readOptionalJsonObject(external_node_path_default().join(workspaceRoot1, 'package.json'));
|
|
60
|
+
return 'string' == typeof rootPackage.name && rootPackage.name.length > 0 ? rootPackage.name : external_node_path_default().basename(workspaceRoot1);
|
|
63
61
|
}
|
|
64
|
-
function
|
|
65
|
-
const metadataPath = external_node_path_default().join(workspaceRoot, PACKAGE_SOURCE_METADATA_PATH);
|
|
66
|
-
if (!external_node_fs_default().existsSync(metadataPath)) return;
|
|
67
|
-
const metadata = readJsonObject(metadataPath);
|
|
68
|
-
const aliases = metadata.modernPackages?.aliases ?? {};
|
|
69
|
-
const firstAlias = Object.values(aliases).find((value)=>'string' == typeof value);
|
|
70
|
-
const firstPackage = Object.keys(aliases)[0];
|
|
71
|
-
const aliasScope = firstAlias?.match(/^@([^/]+)\//)?.[1];
|
|
72
|
-
const unscopedName = firstPackage?.split('/').at(-1) ?? '';
|
|
73
|
-
const aliasUnscopedName = firstAlias?.split('/').at(-1) ?? '';
|
|
74
|
-
const aliasPackageNamePrefix = aliasUnscopedName && unscopedName && aliasUnscopedName.endsWith(unscopedName) ? aliasUnscopedName.slice(0, -unscopedName.length) : void 0;
|
|
75
|
-
return {
|
|
76
|
-
strategy: 'install' === metadata.strategy ? 'install' : 'workspace',
|
|
77
|
-
modernPackageVersion: 'string' == typeof metadata.modernPackages?.specifier ? metadata.modernPackages.specifier : 'workspace:*',
|
|
78
|
-
registry: 'string' == typeof metadata.modernPackages?.registry ? metadata.modernPackages.registry : void 0,
|
|
79
|
-
aliasScope,
|
|
80
|
-
aliasPackageNamePrefix
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function readOverlayPorts(workspaceRoot) {
|
|
84
|
-
const overlayPath = external_node_path_default().join(workspaceRoot, DEVELOPMENT_OVERLAY_PATH);
|
|
85
|
-
if (!external_node_fs_default().existsSync(overlayPath)) return {};
|
|
86
|
-
const overlay = readJsonObject(overlayPath);
|
|
87
|
-
const ports = overlay.ports;
|
|
88
|
-
if (null === ports || 'object' != typeof ports || Array.isArray(ports)) return {};
|
|
89
|
-
return Object.fromEntries(Object.entries(ports).filter((entry)=>'number' == typeof entry[1]));
|
|
90
|
-
}
|
|
91
|
-
function normalizeCompactConfig(workspaceRoot, sourcePath, config) {
|
|
62
|
+
function normalizeCompactConfig(sourcePath, config) {
|
|
92
63
|
const packageSource = config.packageSource && 'object' == typeof config.packageSource ? {
|
|
93
64
|
strategy: 'install' === config.packageSource.strategy ? 'install' : 'workspace',
|
|
94
65
|
modernPackageVersion: 'string' == typeof config.packageSource.modernPackageVersion ? config.packageSource.modernPackageVersion : 'workspace:*',
|
|
95
66
|
registry: 'string' == typeof config.packageSource.registry ? config.packageSource.registry : void 0,
|
|
96
67
|
aliasScope: 'string' == typeof config.packageSource.aliasScope ? config.packageSource.aliasScope : void 0,
|
|
97
68
|
aliasPackageNamePrefix: 'string' == typeof config.packageSource.aliasPackageNamePrefix ? config.packageSource.aliasPackageNamePrefix : void 0
|
|
98
|
-
} :
|
|
69
|
+
} : void 0;
|
|
99
70
|
return {
|
|
100
71
|
schemaVersion: 'number' == typeof config.schemaVersion ? config.schemaVersion : 1,
|
|
101
72
|
profile: 'string' == typeof config.profile ? config.profile : void 0,
|
|
@@ -141,63 +112,10 @@ function normalizeCompactConfig(workspaceRoot, sourcePath, config) {
|
|
|
141
112
|
}
|
|
142
113
|
};
|
|
143
114
|
}
|
|
144
|
-
function
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
schemaVersion: 'number' == typeof contract.schemaVersion ? contract.schemaVersion : 1,
|
|
150
|
-
profile: 'string' == typeof contract.profile ? contract.profile : void 0,
|
|
151
|
-
source: 'legacy',
|
|
152
|
-
sourcePath,
|
|
153
|
-
workspace: {
|
|
154
|
-
packageScope: packageScopeFromRoot(workspaceRoot)
|
|
155
|
-
},
|
|
156
|
-
packageSource: packageSourceFromMetadata(workspaceRoot),
|
|
157
|
-
features: {
|
|
158
|
-
tailwind: shell?.styling?.tailwind !== false
|
|
159
|
-
},
|
|
160
|
-
topology: {
|
|
161
|
-
apps: apps.map((app)=>{
|
|
162
|
-
const id = String(app.id);
|
|
163
|
-
const appPath = 'string' == typeof app.path ? app.path : id === descriptors_cjs_namespaceObject.shellApp.id ? descriptors_cjs_namespaceObject.shellApp.directory : `verticals/${(0, naming_cjs_namespaceObject.toKebabCase)(id)}`;
|
|
164
|
-
const domain = 'string' == typeof app.i18n?.namespace && 'shell' !== app.i18n.namespace ? app.i18n.namespace : appPath.split('/').at(-1);
|
|
165
|
-
return {
|
|
166
|
-
id,
|
|
167
|
-
kind: 'vertical' === app.kind ? 'vertical' : 'shell',
|
|
168
|
-
path: appPath,
|
|
169
|
-
package: 'string' == typeof app.package ? app.package : void 0,
|
|
170
|
-
packageSuffix: 'string' == typeof app.package ? app.package.split('/').at(-1) : appPath.split('/').at(-1),
|
|
171
|
-
displayName: id === descriptors_cjs_namespaceObject.shellApp.id ? descriptors_cjs_namespaceObject.shellApp.displayName : void 0,
|
|
172
|
-
domain,
|
|
173
|
-
port: ports[id],
|
|
174
|
-
moduleFederation: app.moduleFederation && 'object' == typeof app.moduleFederation ? {
|
|
175
|
-
role: 'vertical' === app.kind ? 'remote' : 'host',
|
|
176
|
-
name: 'string' == typeof app.moduleFederation.name ? app.moduleFederation.name : void 0,
|
|
177
|
-
exposes: Array.isArray(app.moduleFederation.exposes) ? app.moduleFederation.exposes.filter((expose)=>'string' == typeof expose) : void 0,
|
|
178
|
-
verticalRefs: Array.isArray(app.moduleFederation.verticalRefs) ? app.moduleFederation.verticalRefs.filter((ref)=>'string' == typeof ref) : void 0,
|
|
179
|
-
hostOnly: 'vertical' !== app.kind
|
|
180
|
-
} : void 0,
|
|
181
|
-
effectApi: app.effect && 'object' == typeof app.effect ? {
|
|
182
|
-
stem: 'string' == typeof app.effect.prefix ? app.effect.prefix.split('/').filter(Boolean).at(-1) ?? domain ?? id : domain ?? id,
|
|
183
|
-
prefix: 'string' == typeof app.effect.prefix ? app.effect.prefix : `/${domain ?? id}-api`,
|
|
184
|
-
consumedBy: [
|
|
185
|
-
descriptors_cjs_namespaceObject.shellApp.id,
|
|
186
|
-
id
|
|
187
|
-
]
|
|
188
|
-
} : void 0
|
|
189
|
-
};
|
|
190
|
-
})
|
|
191
|
-
},
|
|
192
|
-
legacyContract: contract
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
function readUltramodernConfig(workspaceRoot = process.cwd()) {
|
|
196
|
-
const compactPath = external_node_path_default().join(workspaceRoot, descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH);
|
|
197
|
-
if (external_node_fs_default().existsSync(compactPath)) return normalizeCompactConfig(workspaceRoot, compactPath, readJsonObject(compactPath));
|
|
198
|
-
const legacyPath = external_node_path_default().join(workspaceRoot, descriptors_cjs_namespaceObject.GENERATED_CONTRACT_PATH);
|
|
199
|
-
if (external_node_fs_default().existsSync(legacyPath)) return adaptLegacyContract(workspaceRoot, legacyPath, readJsonObject(legacyPath));
|
|
200
|
-
throw new Error(`Missing UltraModern config. Expected ${descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH} or ${descriptors_cjs_namespaceObject.GENERATED_CONTRACT_PATH}.`);
|
|
115
|
+
function readUltramodernConfig(workspaceRoot1 = process.cwd()) {
|
|
116
|
+
const compactPath = external_node_path_default().join(workspaceRoot1, descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH);
|
|
117
|
+
if (external_node_fs_default().existsSync(compactPath)) return normalizeCompactConfig(compactPath, readJsonObject(compactPath));
|
|
118
|
+
throw new Error(`Missing UltraModern config. Expected ${descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH}.`);
|
|
201
119
|
}
|
|
202
120
|
function workspaceAppsFromToolingConfig(config) {
|
|
203
121
|
return config.topology.apps.map((app)=>{
|
|
@@ -83,7 +83,6 @@ const FIRST_VERTICAL_PORT = 4101;
|
|
|
83
83
|
const TOPOLOGY_PATH = 'topology/reference-topology.json';
|
|
84
84
|
const OWNERSHIP_PATH = 'topology/ownership.json';
|
|
85
85
|
const DEVELOPMENT_OVERLAY_PATH = 'topology/local-overlays/development.json';
|
|
86
|
-
const PACKAGE_SOURCE_METADATA_PATH = '.modernjs/ultramodern-package-source.json';
|
|
87
86
|
function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
88
87
|
if (packageSource) return (0, external_package_source_cjs_namespaceObject.resolvePackageSource)({
|
|
89
88
|
targetDir: workspaceRoot,
|
|
@@ -96,37 +95,12 @@ function existingPackageSource(workspaceRoot, modernVersion, packageSource) {
|
|
|
96
95
|
const compactConfig = (0, config_cjs_namespaceObject.readUltramodernConfig)(workspaceRoot);
|
|
97
96
|
if (compactConfig.packageSource) return compactConfig.packageSource;
|
|
98
97
|
}
|
|
99
|
-
|
|
100
|
-
if (!external_node_fs_default().existsSync(metadataPath)) return (0, external_package_source_cjs_namespaceObject.resolvePackageSource)({
|
|
101
|
-
targetDir: workspaceRoot,
|
|
102
|
-
packageName: external_node_path_default().basename(workspaceRoot),
|
|
103
|
-
modernVersion
|
|
104
|
-
});
|
|
105
|
-
const metadata = (0, external_fs_io_cjs_namespaceObject.readJsonFile)(metadataPath);
|
|
106
|
-
const aliases = metadata.modernPackages?.aliases ?? {};
|
|
107
|
-
const firstAlias = Object.values(aliases).find((value)=>'string' == typeof value);
|
|
108
|
-
const firstPackage = Object.keys(aliases)[0];
|
|
109
|
-
const aliasScope = firstAlias?.match(/^@([^/]+)\//)?.[1];
|
|
110
|
-
const unscopedName = firstPackage?.split('/').at(-1) ?? '';
|
|
111
|
-
const aliasUnscopedName = firstAlias?.split('/').at(-1) ?? '';
|
|
112
|
-
const aliasPackageNamePrefix = aliasUnscopedName && unscopedName && aliasUnscopedName.endsWith(unscopedName) ? aliasUnscopedName.slice(0, -unscopedName.length) : void 0;
|
|
113
|
-
return {
|
|
114
|
-
strategy: 'install' === metadata.strategy ? 'install' : 'workspace',
|
|
115
|
-
modernPackageVersion: 'string' == typeof metadata.modernPackages?.specifier ? metadata.modernPackages.specifier : modernVersion,
|
|
116
|
-
registry: metadata.modernPackages?.registry,
|
|
117
|
-
aliasScope,
|
|
118
|
-
aliasPackageNamePrefix
|
|
119
|
-
};
|
|
98
|
+
throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
|
|
120
99
|
}
|
|
121
100
|
function existingTailwindEnabled(workspaceRoot) {
|
|
122
101
|
const compactPath = external_node_path_default().join(workspaceRoot, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH);
|
|
123
102
|
if (external_node_fs_default().existsSync(compactPath)) return (0, config_cjs_namespaceObject.readUltramodernConfig)(workspaceRoot).features.tailwind;
|
|
124
|
-
|
|
125
|
-
if (!external_node_fs_default().existsSync(contractPath)) return true;
|
|
126
|
-
const contract = (0, external_fs_io_cjs_namespaceObject.readJsonFile)(contractPath);
|
|
127
|
-
const apps = (0, external_types_cjs_namespaceObject.isRecord)(contract) && Array.isArray(contract.apps) ? contract.apps : [];
|
|
128
|
-
const shell = apps.find((app)=>(0, external_types_cjs_namespaceObject.isRecord)(app) && app.id === external_descriptors_cjs_namespaceObject.shellApp.id);
|
|
129
|
-
return shell?.styling && (0, external_types_cjs_namespaceObject.isRecord)(shell.styling) ? false !== shell.styling.tailwind : true;
|
|
103
|
+
throw new Error(`Missing UltraModern workspace file: ${compactPath}`);
|
|
130
104
|
}
|
|
131
105
|
function existingBridgeConfig(workspaceRoot) {
|
|
132
106
|
const compactPath = external_node_path_default().join(workspaceRoot, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH);
|
|
@@ -172,7 +146,7 @@ function rewriteShellAppFiles(workspaceRoot, scope, packageSource, enableTailwin
|
|
|
172
146
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/routes/[lang]/page.tsx`, (0, external_demo_components_cjs_namespaceObject.createShellPage)(remotes));
|
|
173
147
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/routes/vertical-components.tsx`, (0, external_demo_components_cjs_namespaceObject.createShellRemoteComponents)(scope, remotes));
|
|
174
148
|
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/routes/shell-frame.tsx`, (0, external_app_files_cjs_namespaceObject.createShellFrameComponent)());
|
|
175
|
-
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/
|
|
149
|
+
(0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(workspaceRoot, `${external_descriptors_cjs_namespaceObject.shellApp.directory}/src/api/vertical-clients.ts`, (0, external_effect_api_cjs_namespaceObject.createShellEffectClient)(scope, remotes));
|
|
176
150
|
}
|
|
177
151
|
function addShellZephyrDependency(workspaceRoot, scope, remote) {
|
|
178
152
|
const packagePath = external_node_path_default().join(workspaceRoot, external_descriptors_cjs_namespaceObject.shellApp.directory, 'package.json');
|
|
@@ -228,10 +202,11 @@ function verticalsFromTopology(topology, ports) {
|
|
|
228
202
|
return (topology.verticals ?? []).map((vertical)=>{
|
|
229
203
|
const domain = vertical.domain ?? String(vertical.id);
|
|
230
204
|
const packageSuffix = vertical.package?.split('/').at(-1) ?? domain;
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
205
|
+
const apiTopology = vertical.api;
|
|
206
|
+
const effectApi = apiTopology?.runtime === 'effect' ? {
|
|
207
|
+
stem: 'string' == typeof apiTopology.basePath ? apiTopology.basePath.split('/').filter(Boolean).at(-1) ?? domain : domain,
|
|
208
|
+
prefix: apiTopology.bff?.prefix ?? `/${domain}-api`,
|
|
209
|
+
consumedBy: Array.isArray(apiTopology.consumedBy) ? apiTopology.consumedBy : [
|
|
235
210
|
external_descriptors_cjs_namespaceObject.shellApp.id,
|
|
236
211
|
vertical.id
|
|
237
212
|
]
|
|
@@ -325,9 +300,7 @@ function readRequiredJsonObject(filePath) {
|
|
|
325
300
|
}
|
|
326
301
|
function readRequiredWorkspaceConfig(workspaceRoot) {
|
|
327
302
|
const compactPath = external_node_path_default().join(workspaceRoot, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH);
|
|
328
|
-
|
|
329
|
-
readRequiredJsonObject(external_node_path_default().join(workspaceRoot, external_descriptors_cjs_namespaceObject.GENERATED_CONTRACT_PATH));
|
|
330
|
-
readRequiredJsonObject(external_node_path_default().join(workspaceRoot, PACKAGE_SOURCE_METADATA_PATH));
|
|
303
|
+
readRequiredJsonObject(compactPath);
|
|
331
304
|
}
|
|
332
305
|
function assertOptionalJsonObject(value, label, filePath) {
|
|
333
306
|
if (void 0 !== value && !(0, external_types_cjs_namespaceObject.isRecord)(value)) throw new Error(`${label} in ${filePath} must be a JSON object`);
|
|
@@ -348,8 +321,8 @@ function validateWorkspaceAppDescriptors(apps) {
|
|
|
348
321
|
if ('number' != typeof app.port || !Number.isFinite(app.port) || app.port <= 0) throw new Error(`Invalid development port for ${appLabel}`);
|
|
349
322
|
assertNonEmptyString(app.mfName, `Module Federation name for ${appLabel}`);
|
|
350
323
|
if (app.effectApi) {
|
|
351
|
-
assertNonEmptyString(app.effectApi.prefix, `
|
|
352
|
-
if (!app.effectApi.prefix.startsWith('/')) throw new Error(`
|
|
324
|
+
assertNonEmptyString(app.effectApi.prefix, `API prefix for ${appLabel}`);
|
|
325
|
+
if (!app.effectApi.prefix.startsWith('/')) throw new Error(`API prefix for ${appLabel} must start with "/"`);
|
|
353
326
|
}
|
|
354
327
|
}
|
|
355
328
|
}
|
|
@@ -359,7 +332,7 @@ function validateUniqueWorkspaceAppDescriptors(apps) {
|
|
|
359
332
|
assertUniqueAppField(apps, 'output path', (app)=>(0, external_naming_cjs_namespaceObject.normalizePath)(app.directory));
|
|
360
333
|
assertUniqueAppField(apps, 'Module Federation name', (app)=>app.mfName);
|
|
361
334
|
assertUniqueAppField(apps, 'development port', (app)=>String(app.port));
|
|
362
|
-
assertUniqueAppField(apps, '
|
|
335
|
+
assertUniqueAppField(apps, 'API prefix', (app)=>app.effectApi?.prefix);
|
|
363
336
|
assertUniqueAppField(apps, 'manifest environment name', (app)=>'vertical' === app.kind ? (0, external_descriptors_cjs_namespaceObject.createRemoteManifestEnv)(app) : void 0);
|
|
364
337
|
}
|
|
365
338
|
function assertUniqueAppField(apps, label, readValue) {
|
|
@@ -448,7 +421,7 @@ function createDryRunJsonMutations(preflight, manifestUrl) {
|
|
|
448
421
|
{
|
|
449
422
|
path: DEVELOPMENT_OVERLAY_PATH,
|
|
450
423
|
pointer: `/apis/${vertical.id}`,
|
|
451
|
-
description: `Add local
|
|
424
|
+
description: `Add local API URL for ${vertical.id}`,
|
|
452
425
|
value: `http://localhost:${vertical.port}${(0, external_descriptors_cjs_namespaceObject.effectApiPrefix)(vertical)}`
|
|
453
426
|
}
|
|
454
427
|
] : [];
|
|
@@ -95,6 +95,7 @@ function createTopology(scope, remotes = []) {
|
|
|
95
95
|
script: "scripts/validate-ultramodern-workspace.mjs",
|
|
96
96
|
commands: [
|
|
97
97
|
'pnpm i18n:boundaries',
|
|
98
|
+
'pnpm api:check',
|
|
98
99
|
'pnpm contract:check'
|
|
99
100
|
]
|
|
100
101
|
}
|
|
@@ -288,6 +289,7 @@ function createUltramodernConfig(scope, modernVersion, packageSource, apps = [
|
|
|
288
289
|
publicSurface: "scripts/generate-public-surface-assets.mjs",
|
|
289
290
|
cloudflareProof: "scripts/proof-cloudflare-version.mjs",
|
|
290
291
|
performanceReadiness: "scripts/ultramodern-performance-readiness.mjs",
|
|
292
|
+
apiBoundaries: "scripts/check-ultramodern-api-boundaries.mjs",
|
|
291
293
|
skills: "scripts/bootstrap-agent-skills.mjs"
|
|
292
294
|
}
|
|
293
295
|
}
|
|
@@ -248,36 +248,36 @@ ${showcaseItems}
|
|
|
248
248
|
}
|
|
249
249
|
function createRemotePage(app) {
|
|
250
250
|
const tw = (0, external_naming_cjs_namespaceObject.createTw)((0, external_naming_cjs_namespaceObject.tailwindPrefixForApp)(app));
|
|
251
|
-
const
|
|
252
|
-
const
|
|
251
|
+
const listApiItems = `list${(0, external_naming_cjs_namespaceObject.toPascalCase)((0, external_descriptors_cjs_namespaceObject.effectApiStem)(app))}`;
|
|
252
|
+
const apiImport = (0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
253
253
|
import { Link } from '@modern-js/plugin-tanstack/runtime';
|
|
254
254
|
import { useEffect, useState } from 'react';
|
|
255
255
|
import {
|
|
256
256
|
Effect,
|
|
257
|
-
${
|
|
257
|
+
${listApiItems},
|
|
258
258
|
runEffectRequest,
|
|
259
|
-
} from '../../
|
|
259
|
+
} from '../../api/${(0, external_descriptors_cjs_namespaceObject.effectApiStem)(app)}-client';
|
|
260
260
|
import { UltramodernRouteHead } from '../ultramodern-route-head';
|
|
261
261
|
import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
262
262
|
` : "import { useModernI18n } from '@modern-js/plugin-i18n/runtime';\nimport { Link } from '@modern-js/plugin-tanstack/runtime';\nimport { UltramodernRouteHead } from '../ultramodern-route-head';\nimport { ultramodernUiMarker } from '../../ultramodern-build';\n";
|
|
263
|
-
const
|
|
263
|
+
const apiState = (0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? ` const [apiStatus, setApiStatus] = useState('pending');
|
|
264
264
|
|
|
265
265
|
useEffect(() => {
|
|
266
266
|
let cancelled = false;
|
|
267
267
|
void runEffectRequest(
|
|
268
|
-
${
|
|
268
|
+
${listApiItems}({ limit: 1 }).pipe(
|
|
269
269
|
Effect.match({
|
|
270
270
|
onFailure: () => {
|
|
271
271
|
if (cancelled) {
|
|
272
272
|
return;
|
|
273
273
|
}
|
|
274
|
-
|
|
274
|
+
setApiStatus('unavailable');
|
|
275
275
|
},
|
|
276
276
|
onSuccess: data => {
|
|
277
277
|
if (cancelled) {
|
|
278
278
|
return;
|
|
279
279
|
}
|
|
280
|
-
|
|
280
|
+
setApiStatus(data.items.at(0)?.title ?? 'empty');
|
|
281
281
|
},
|
|
282
282
|
}),
|
|
283
283
|
),
|
|
@@ -289,12 +289,12 @@ import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
|
289
289
|
}, []);
|
|
290
290
|
|
|
291
291
|
` : '';
|
|
292
|
-
const
|
|
292
|
+
const apiMarkup = (0, external_descriptors_cjs_namespaceObject.appHasEffectApi)(app) ? ` <p data-testid="api-status">{apiStatus}</p>
|
|
293
293
|
` : '';
|
|
294
|
-
return `${
|
|
294
|
+
return `${apiImport}
|
|
295
295
|
export default function ${(0, external_naming_cjs_namespaceObject.toPascalCase)(app.id)}Home() {
|
|
296
296
|
const { language, supportedLanguages, t } = useModernI18n();
|
|
297
|
-
${
|
|
297
|
+
${apiState} return (
|
|
298
298
|
<main className="${tw('min-h-screen bg-um-canvas px-4 py-6 text-um-foreground sm:px-8')}">
|
|
299
299
|
<UltramodernRouteHead />
|
|
300
300
|
<nav aria-label={t('${app.domain}.language.switcher')} className="${tw('flex gap-3')}">
|
|
@@ -315,7 +315,7 @@ ${effectBffState} return (
|
|
|
315
315
|
<p className="${tw('sr-only')}" data-build-marker={ultramodernUiMarker.build} data-testid="ultramodern-ui-marker">
|
|
316
316
|
{ultramodernUiMarker.appId}:{ultramodernUiMarker.version}
|
|
317
317
|
</p>
|
|
318
|
-
${
|
|
318
|
+
${apiMarkup} </main>
|
|
319
319
|
);
|
|
320
320
|
}
|
|
321
321
|
`;
|
|
@@ -28,7 +28,6 @@ var __webpack_require__ = {};
|
|
|
28
28
|
var __webpack_exports__ = {};
|
|
29
29
|
__webpack_require__.r(__webpack_exports__);
|
|
30
30
|
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
-
GENERATED_CONTRACT_PATH: ()=>GENERATED_CONTRACT_PATH,
|
|
32
31
|
ULTRAMODERN_CONFIG_PATH: ()=>ULTRAMODERN_CONFIG_PATH,
|
|
33
32
|
appHasEffectApi: ()=>appHasEffectApi,
|
|
34
33
|
appI18nNamespace: ()=>appI18nNamespace,
|
|
@@ -49,7 +48,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
49
48
|
zephyrRemoteDependency: ()=>zephyrRemoteDependency
|
|
50
49
|
});
|
|
51
50
|
const external_naming_cjs_namespaceObject = require("./naming.cjs");
|
|
52
|
-
const GENERATED_CONTRACT_PATH = '.modernjs/ultramodern-generated-contract.json';
|
|
53
51
|
const ULTRAMODERN_CONFIG_PATH = '.modernjs/ultramodern.json';
|
|
54
52
|
const shellApp = {
|
|
55
53
|
id: 'shell-super-app',
|
|
@@ -181,7 +179,6 @@ function createCloudflarePublicUrlEnv(app) {
|
|
|
181
179
|
function appI18nNamespace(app) {
|
|
182
180
|
return 'shell' === app.kind ? 'shell' : app.domain ?? app.id;
|
|
183
181
|
}
|
|
184
|
-
exports.GENERATED_CONTRACT_PATH = __webpack_exports__.GENERATED_CONTRACT_PATH;
|
|
185
182
|
exports.ULTRAMODERN_CONFIG_PATH = __webpack_exports__.ULTRAMODERN_CONFIG_PATH;
|
|
186
183
|
exports.appHasEffectApi = __webpack_exports__.appHasEffectApi;
|
|
187
184
|
exports.appI18nNamespace = __webpack_exports__.appI18nNamespace;
|
|
@@ -201,7 +198,6 @@ exports.shellApp = __webpack_exports__.shellApp;
|
|
|
201
198
|
exports.verticalEffectApps = __webpack_exports__.verticalEffectApps;
|
|
202
199
|
exports.zephyrRemoteDependency = __webpack_exports__.zephyrRemoteDependency;
|
|
203
200
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
204
|
-
"GENERATED_CONTRACT_PATH",
|
|
205
201
|
"ULTRAMODERN_CONFIG_PATH",
|
|
206
202
|
"appHasEffectApi",
|
|
207
203
|
"appI18nNamespace",
|