@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.
Files changed (104) hide show
  1. package/README.md +13 -11
  2. package/dist/cjs/index.cjs +36 -3
  3. package/dist/cjs/locale/en.cjs +10 -0
  4. package/dist/cjs/locale/zh.cjs +10 -0
  5. package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
  6. package/dist/cjs/ultramodern-tooling/config.cjs +248 -0
  7. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +39 -18
  8. package/dist/cjs/ultramodern-workspace/bridge-config.cjs +327 -0
  9. package/dist/cjs/ultramodern-workspace/codesmith.cjs +1 -0
  10. package/dist/cjs/ultramodern-workspace/contracts.cjs +119 -653
  11. package/dist/cjs/ultramodern-workspace/descriptors.cjs +4 -0
  12. package/dist/cjs/ultramodern-workspace/generation-result.cjs +1 -1
  13. package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
  14. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +572 -0
  15. package/dist/cjs/ultramodern-workspace/module-federation.cjs +14 -0
  16. package/dist/cjs/ultramodern-workspace/package-json.cjs +26 -12
  17. package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
  18. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +74 -44
  19. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +37 -8
  20. package/dist/esm/index.js +36 -3
  21. package/dist/esm/locale/en.js +10 -0
  22. package/dist/esm/locale/zh.js +10 -0
  23. package/dist/esm/ultramodern-tooling/commands.js +132 -0
  24. package/dist/esm/ultramodern-tooling/config.js +196 -0
  25. package/dist/esm/ultramodern-workspace/add-vertical.js +39 -21
  26. package/dist/esm/ultramodern-workspace/bridge-config.js +270 -0
  27. package/dist/esm/ultramodern-workspace/codesmith.js +1 -0
  28. package/dist/esm/ultramodern-workspace/contracts.js +122 -608
  29. package/dist/esm/ultramodern-workspace/descriptors.js +2 -1
  30. package/dist/esm/ultramodern-workspace/generation-result.js +2 -2
  31. package/dist/esm/ultramodern-workspace/index.js +1 -0
  32. package/dist/esm/ultramodern-workspace/mf-validation.js +517 -0
  33. package/dist/esm/ultramodern-workspace/module-federation.js +14 -0
  34. package/dist/esm/ultramodern-workspace/package-json.js +26 -12
  35. package/dist/esm/ultramodern-workspace/public-api.js +1 -0
  36. package/dist/esm/ultramodern-workspace/workspace-scripts.js +75 -27
  37. package/dist/esm/ultramodern-workspace/write-workspace.js +38 -12
  38. package/dist/esm-node/index.js +36 -3
  39. package/dist/esm-node/locale/en.js +10 -0
  40. package/dist/esm-node/locale/zh.js +10 -0
  41. package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
  42. package/dist/esm-node/ultramodern-tooling/config.js +197 -0
  43. package/dist/esm-node/ultramodern-workspace/add-vertical.js +39 -21
  44. package/dist/esm-node/ultramodern-workspace/bridge-config.js +271 -0
  45. package/dist/esm-node/ultramodern-workspace/codesmith.js +1 -0
  46. package/dist/esm-node/ultramodern-workspace/contracts.js +122 -608
  47. package/dist/esm-node/ultramodern-workspace/descriptors.js +2 -1
  48. package/dist/esm-node/ultramodern-workspace/generation-result.js +2 -2
  49. package/dist/esm-node/ultramodern-workspace/index.js +1 -0
  50. package/dist/esm-node/ultramodern-workspace/mf-validation.js +518 -0
  51. package/dist/esm-node/ultramodern-workspace/module-federation.js +14 -0
  52. package/dist/esm-node/ultramodern-workspace/package-json.js +26 -12
  53. package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
  54. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +75 -27
  55. package/dist/esm-node/ultramodern-workspace/write-workspace.js +38 -12
  56. package/dist/types/locale/en.d.ts +10 -0
  57. package/dist/types/locale/index.d.ts +20 -0
  58. package/dist/types/locale/zh.d.ts +10 -0
  59. package/dist/types/ultramodern-tooling/commands.d.ts +1 -0
  60. package/dist/types/ultramodern-tooling/config.d.ts +43 -0
  61. package/dist/types/ultramodern-workspace/add-vertical.d.ts +5 -2
  62. package/dist/types/ultramodern-workspace/bridge-config.d.ts +64 -0
  63. package/dist/types/ultramodern-workspace/codesmith.d.ts +1 -0
  64. package/dist/types/ultramodern-workspace/contracts.d.ts +2 -17
  65. package/dist/types/ultramodern-workspace/descriptors.d.ts +1 -0
  66. package/dist/types/ultramodern-workspace/index.d.ts +2 -0
  67. package/dist/types/ultramodern-workspace/mf-validation.d.ts +27 -0
  68. package/dist/types/ultramodern-workspace/package-json.d.ts +4 -3
  69. package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
  70. package/dist/types/ultramodern-workspace/types.d.ts +2 -0
  71. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -7
  72. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -2
  73. package/package.json +3 -3
  74. package/template-workspace/{.agents → .codex}/skills-lock.json +12 -12
  75. package/template-workspace/.gitignore.handlebars +3 -0
  76. package/template-workspace/AGENTS.md.handlebars +11 -5
  77. package/template-workspace/README.md.handlebars +15 -12
  78. package/template-workspace/oxfmt.config.ts +1 -0
  79. package/template-workspace/oxlint.config.ts +1 -0
  80. package/template-workspace/scripts/bootstrap-agent-skills.mjs +77 -67
  81. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +56 -3
  82. package/templates/workspace-scripts/generate-public-surface-assets.mjs +239 -4
  83. package/templates/workspace-scripts/proof-cloudflare-version.mjs +282 -4
  84. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +172 -1
  85. package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
  86. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +783 -26
  87. /package/template-workspace/{.agents → .codex}/rstackjs-agent-skills-LICENSE +0 -0
  88. /package/template-workspace/{.agents → .codex}/skills/rsbuild-best-practices/SKILL.md +0 -0
  89. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/SKILL.md +0 -0
  90. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/command-map.md +0 -0
  91. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/common-analysis-patterns.md +0 -0
  92. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +0 -0
  93. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +0 -0
  94. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +0 -0
  95. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor.md +0 -0
  96. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +0 -0
  97. /package/template-workspace/{.agents → .codex}/skills/rslib-best-practices/SKILL.md +0 -0
  98. /package/template-workspace/{.agents → .codex}/skills/rslib-modern-package/SKILL.md +0 -0
  99. /package/template-workspace/{.agents → .codex}/skills/rspack-best-practices/SKILL.md +0 -0
  100. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/SKILL.md +0 -0
  101. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/bottlenecks.md +0 -0
  102. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/tracing-guide.md +0 -0
  103. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/scripts/analyze_trace.js +0 -0
  104. /package/template-workspace/{.agents → .codex}/skills/rstest-best-practices/SKILL.md +0 -0
@@ -6,6 +6,8 @@ const root = process.cwd();
6
6
  const defaultReportPath =
7
7
  '.codex/reports/performance-readiness/ultramodern-performance-readiness.json';
8
8
  const configPath = 'scripts/ultramodern-performance-readiness.config.mjs';
9
+ const compactConfigPath = '.modernjs/ultramodern.json';
10
+ const legacyContractPath = '.modernjs/ultramodern-generated-contract.json';
9
11
  const optOutEnv = 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS';
10
12
  const signalIds = [
11
13
  'bfcache',
@@ -60,6 +62,175 @@ const createSignal = (id, status, evidence) => ({
60
62
 
61
63
  const unique = values => new Set(values).size === values.length;
62
64
 
65
+ const toKebabCase = value =>
66
+ String(value)
67
+ .trim()
68
+ .replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
69
+ .replace(/[^a-zA-Z0-9._-]+/gu, '-')
70
+ .replace(/[._]+/gu, '-')
71
+ .toLowerCase()
72
+ .replace(/-+/gu, '-')
73
+ .replace(/^-+|-+$/gu, '');
74
+
75
+ const toPascalCase = value =>
76
+ toKebabCase(value)
77
+ .split('-')
78
+ .filter(Boolean)
79
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
80
+ .join('');
81
+
82
+ const normalizeRelativePath = value =>
83
+ String(value ?? '').replace(/\\/gu, '/').replace(/^\.\/+/u, '');
84
+
85
+ const appNamespace = app => (app.kind === 'shell' ? 'shell' : (app.domain ?? app.id));
86
+
87
+ const normalizeCompactApp = rawApp => {
88
+ const id = String(rawApp.id);
89
+ const kind = rawApp.kind === 'vertical' ? 'vertical' : 'shell';
90
+ const appPath =
91
+ typeof rawApp.path === 'string'
92
+ ? normalizeRelativePath(rawApp.path)
93
+ : kind === 'shell'
94
+ ? 'apps/shell-super-app'
95
+ : `verticals/${toKebabCase(id)}`;
96
+ const packageSuffix =
97
+ typeof rawApp.packageSuffix === 'string'
98
+ ? rawApp.packageSuffix
99
+ : appPath.split('/').at(-1) ?? id;
100
+ const domain =
101
+ typeof rawApp.domain === 'string'
102
+ ? rawApp.domain
103
+ : kind === 'vertical'
104
+ ? packageSuffix
105
+ : undefined;
106
+ const moduleFederation =
107
+ rawApp.moduleFederation && typeof rawApp.moduleFederation === 'object'
108
+ ? rawApp.moduleFederation
109
+ : {};
110
+
111
+ return {
112
+ id,
113
+ kind,
114
+ path: appPath,
115
+ packageSuffix,
116
+ domain,
117
+ port:
118
+ typeof rawApp.port === 'number'
119
+ ? rawApp.port
120
+ : kind === 'shell'
121
+ ? 3020
122
+ : 3030,
123
+ mfName:
124
+ typeof moduleFederation.name === 'string'
125
+ ? moduleFederation.name
126
+ : kind === 'shell'
127
+ ? 'shellSuperApp'
128
+ : `vertical${toPascalCase(domain ?? id)}`,
129
+ moduleFederation: {
130
+ remotes: [],
131
+ verticalRefs: Array.isArray(moduleFederation.verticalRefs)
132
+ ? moduleFederation.verticalRefs.filter(ref => typeof ref === 'string')
133
+ : [],
134
+ },
135
+ };
136
+ };
137
+
138
+ const createRemoteContracts = (app, apps) =>
139
+ (app.moduleFederation?.verticalRefs ?? [])
140
+ .map(ref => apps.find(candidate => candidate.id === ref))
141
+ .filter(Boolean)
142
+ .map(remote => ({
143
+ id: remote.id,
144
+ name: remote.mfName,
145
+ manifestUrl: `http://localhost:${remote.port ?? 3030}/mf-manifest.json`,
146
+ }));
147
+
148
+ const createPerformanceReadinessContract = () => ({
149
+ schemaVersion: 1,
150
+ default: 'enabled',
151
+ mode: 'diagnostic',
152
+ scope: 'ultramodern-generated-and-framework-owned',
153
+ report: {
154
+ script: 'scripts/ultramodern-performance-readiness.mjs',
155
+ config: 'scripts/ultramodern-performance-readiness.config.mjs',
156
+ defaultPath: defaultReportPath,
157
+ deterministic: true,
158
+ },
159
+ signals: signalIds.map(id => ({ id })),
160
+ });
161
+
162
+ const createContractApp = (config, app, apps) => {
163
+ const compatibilityDate =
164
+ typeof config.deploy?.worker?.compatibilityDate === 'string'
165
+ ? config.deploy.worker.compatibilityDate
166
+ : '2026-06-02';
167
+
168
+ return {
169
+ id: app.id,
170
+ path: app.path,
171
+ config: {
172
+ plugins: [
173
+ 'appTools',
174
+ 'tanstackRouterPlugin',
175
+ 'i18nPlugin',
176
+ ...(app.kind === 'vertical' ? ['bffPlugin'] : []),
177
+ 'moduleFederationPlugin',
178
+ 'zephyrRspackPlugin',
179
+ ],
180
+ },
181
+ deploy: {
182
+ cloudflare: {
183
+ compatibilityDate,
184
+ compatibilityFlags: ['nodejs_compat', 'global_fetch_strictly_public'],
185
+ routes: {
186
+ ssr: '/en',
187
+ mfManifest: '/mf-manifest.json',
188
+ locale: `/locales/en/${appNamespace(app)}.json`,
189
+ },
190
+ qualityGates: {
191
+ assets: {
192
+ cacheControlRequiredForCss: true,
193
+ },
194
+ },
195
+ },
196
+ },
197
+ moduleFederation: {
198
+ remotes: createRemoteContracts(app, apps),
199
+ },
200
+ routes: {
201
+ localisedUrls: {},
202
+ publicSurface: {
203
+ artifactLifecycle: 'build-and-deploy-output',
204
+ },
205
+ },
206
+ };
207
+ };
208
+
209
+ const readGeneratedContractView = () => {
210
+ if (exists(compactConfigPath)) {
211
+ const compactConfig = readJson(compactConfigPath);
212
+ const apps = Array.isArray(compactConfig.topology?.apps)
213
+ ? compactConfig.topology.apps.map(normalizeCompactApp)
214
+ : [];
215
+ return {
216
+ sourcePath: compactConfigPath,
217
+ performanceReadiness: createPerformanceReadinessContract(),
218
+ apps: apps.map(app => createContractApp(compactConfig, app, apps)),
219
+ };
220
+ }
221
+
222
+ if (exists(legacyContractPath)) {
223
+ return {
224
+ sourcePath: legacyContractPath,
225
+ ...readJson(legacyContractPath),
226
+ };
227
+ }
228
+
229
+ throw new Error(
230
+ `Missing UltraModern config. Expected ${compactConfigPath} or ${legacyContractPath}.`,
231
+ );
232
+ };
233
+
63
234
  const appGeneratedFiles = app => [
64
235
  `${app.path}/modern.config.ts`,
65
236
  `${app.path}/module-federation.config.ts`,
@@ -181,7 +352,7 @@ const main = async () => {
181
352
  return;
182
353
  }
183
354
 
184
- const contract = readJson('.modernjs/ultramodern-generated-contract.json');
355
+ const contract = readGeneratedContractView();
185
356
  assert(
186
357
  contract.performanceReadiness?.default === 'enabled',
187
358
  'Generated contract must keep performance readiness diagnostics default-on',
@@ -9,11 +9,13 @@ import {
9
9
  mkdirSync,
10
10
  } from 'node:fs';
11
11
  import os from 'node:os';
12
- import { dirname, join } from 'node:path';
12
+ import { dirname, join, resolve } from 'node:path';
13
13
  import { fileURLToPath } from 'node:url';
14
14
 
15
15
  const args = process.argv.slice(2);
16
- const workspaceRoot = join(dirname(fileURLToPath(import.meta.url)), '..');
16
+ const workspaceRoot = process.env.ULTRAMODERN_WORKSPACE_ROOT
17
+ ? resolve(process.env.ULTRAMODERN_WORKSPACE_ROOT)
18
+ : join(dirname(fileURLToPath(import.meta.url)), '..');
17
19
  const cpuCount = Math.max(
18
20
  1,
19
21
  typeof os.availableParallelism === 'function'