@bleedingdev/modern-js-create 3.4.0-ultramodern.8 → 3.5.0-ultramodern.0

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