@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.7 → 3.9.0-ultramodern.8

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 (44) hide show
  1. package/dist/cjs/ultramodern-tooling/commands/cloudflare-output-verify.cjs +1 -1
  2. package/dist/cjs/ultramodern-tooling/commands/routes-generate.cjs +1 -1
  3. package/dist/cjs/ultramodern-tooling/commands/validate.cjs +2 -2
  4. package/dist/cjs/ultramodern-tooling/config/normalize.cjs +7 -5
  5. package/dist/cjs/ultramodern-workspace/add-shell.cjs +1 -1
  6. package/dist/cjs/ultramodern-workspace/add-vertical/execute.cjs +1 -1
  7. package/dist/cjs/ultramodern-workspace/delivery-unit-sync.cjs +1 -1
  8. package/dist/cjs/ultramodern-workspace/mf-validation/exposes.cjs +63 -0
  9. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +19 -4
  10. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +4 -0
  11. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +2 -2
  12. package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +10 -5
  13. package/dist/esm/ultramodern-tooling/commands/cloudflare-output-verify.js +1 -1
  14. package/dist/esm/ultramodern-tooling/commands/routes-generate.js +1 -1
  15. package/dist/esm/ultramodern-tooling/commands/validate.js +2 -2
  16. package/dist/esm/ultramodern-tooling/config/normalize.js +7 -5
  17. package/dist/esm/ultramodern-workspace/add-shell.js +1 -1
  18. package/dist/esm/ultramodern-workspace/add-vertical/execute.js +1 -1
  19. package/dist/esm/ultramodern-workspace/delivery-unit-sync.js +1 -1
  20. package/dist/esm/ultramodern-workspace/mf-validation/exposes.js +14 -0
  21. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +19 -4
  22. package/dist/esm/ultramodern-workspace/mf-validation.js +1 -0
  23. package/dist/esm/ultramodern-workspace/workspace-scripts.js +2 -2
  24. package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +10 -5
  25. package/dist/esm-node/ultramodern-tooling/commands/cloudflare-output-verify.js +1 -1
  26. package/dist/esm-node/ultramodern-tooling/commands/routes-generate.js +1 -1
  27. package/dist/esm-node/ultramodern-tooling/commands/validate.js +2 -2
  28. package/dist/esm-node/ultramodern-tooling/config/normalize.js +7 -5
  29. package/dist/esm-node/ultramodern-workspace/add-shell.js +1 -1
  30. package/dist/esm-node/ultramodern-workspace/add-vertical/execute.js +1 -1
  31. package/dist/esm-node/ultramodern-workspace/delivery-unit-sync.js +1 -1
  32. package/dist/esm-node/ultramodern-workspace/mf-validation/exposes.js +15 -0
  33. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +19 -4
  34. package/dist/esm-node/ultramodern-workspace/mf-validation.js +1 -0
  35. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +2 -2
  36. package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +10 -5
  37. package/dist/types/ultramodern-tooling/config/normalize.d.ts +7 -2
  38. package/dist/types/ultramodern-workspace/mf-validation/exposes.d.ts +11 -0
  39. package/dist/types/ultramodern-workspace/mf-validation/types.d.ts +1 -0
  40. package/dist/types/ultramodern-workspace/mf-validation.d.ts +1 -0
  41. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +1 -1
  42. package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +1 -1
  43. package/package.json +9 -9
  44. package/template-workspace/.modernjs/release-cohort.json +48 -48
@@ -53,7 +53,7 @@ const resolveCloudflareOutputVerifyTargets = (args, context)=>{
53
53
  label: outputDirectory,
54
54
  outputDirectory: external_node_path_default().resolve(context.invocationCwd, outputDirectory)
55
55
  }
56
- ] : (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)((0, external_config_cjs_namespaceObject.readUltramodernConfig)(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
56
+ ] : (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)((0, external_config_cjs_namespaceObject.readUltramodernConfig)(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
57
57
  label: app.id,
58
58
  outputDirectory: external_node_path_default().join(context.workspaceRoot, app.directory, '.output')
59
59
  }));
@@ -46,7 +46,7 @@ const external_context_cjs_namespaceObject = require("./context.cjs");
46
46
  const external_options_cjs_namespaceObject = require("./options.cjs");
47
47
  const resolveRoutesGenerateTargets = (args, context)=>{
48
48
  const appId = (0, external_options_cjs_namespaceObject.readOption)(args, '--app');
49
- const targets = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)((0, external_config_cjs_namespaceObject.readUltramodernConfig)(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
49
+ const targets = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)((0, external_config_cjs_namespaceObject.readUltramodernConfig)(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
50
50
  label: app.id,
51
51
  appDirectory: external_node_path_default().join(context.workspaceRoot, app.directory)
52
52
  }));
@@ -52,7 +52,7 @@ function runValidate(context) {
52
52
  overlay: (0, external_config_cjs_namespaceObject.readJsonObject)(external_node_path_default().join(context.workspaceRoot, 'topology/local-overlays/development.json'))
53
53
  });
54
54
  const { config, verticals: remotes, primaryShell, additionalShells } = workspace;
55
- const compactApps = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(config);
55
+ const compactApps = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(config, context.workspaceRoot);
56
56
  const compactPrimaryShell = compactApps.find((app)=>'shell' === app.kind) ?? (0, descriptors_cjs_namespaceObject.createShellHost)(remotes);
57
57
  const compactConfig = (0, contracts_cjs_namespaceObject.createUltramodernConfig)(config.workspace.packageScope, 'workspace-validation-contract', {
58
58
  strategy: 'workspace',
@@ -69,7 +69,7 @@ function runValidate(context) {
69
69
  ])if (declared && Object.hasOwn(declared, key)) app.deploy.cloudflare[key] = declared[key];
70
70
  }
71
71
  const releaseCohort = config.packageSource?.strategy === 'install' ? (0, external_ultramodern_release_cohort_cjs_namespaceObject.readWorkspaceReleaseCohort)(context.workspaceRoot) : void 0;
72
- const source = (0, workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, (0, external_config_cjs_namespaceObject.readJsonObject)(external_node_path_default().join(context.workspaceRoot, 'topology/ownership.json')));
72
+ const source = (0, workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, (0, external_config_cjs_namespaceObject.readJsonObject)(external_node_path_default().join(context.workspaceRoot, 'topology/ownership.json')), void 0, context.workspaceRoot);
73
73
  return (0, external_context_cjs_namespaceObject.runRenderedModule)(source, context);
74
74
  }
75
75
  exports.runValidate = __webpack_exports__.runValidate;
@@ -52,6 +52,7 @@ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_no
52
52
  const topology_cjs_namespaceObject = require("../../ultramodern-workspace/add-vertical/topology.cjs");
53
53
  const bridge_config_cjs_namespaceObject = require("../../ultramodern-workspace/bridge-config.cjs");
54
54
  const descriptors_cjs_namespaceObject = require("../../ultramodern-workspace/descriptors.cjs");
55
+ const mf_validation_cjs_namespaceObject = require("../../ultramodern-workspace/mf-validation.cjs");
55
56
  const naming_cjs_namespaceObject = require("../../ultramodern-workspace/naming.cjs");
56
57
  const shells_cjs_namespaceObject = require("../../ultramodern-workspace/shells.cjs");
57
58
  const types_cjs_namespaceObject = require("../../ultramodern-workspace/types.cjs");
@@ -165,7 +166,7 @@ function formatSchemaVersionError(sourcePath, reason, value) {
165
166
  function normalizeCompactUltramodernConfig(workspaceRoot, compact) {
166
167
  return normalizeCompactConfig(workspaceRoot, external_node_path_default().join(workspaceRoot, descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH), compact);
167
168
  }
168
- function workspaceAppsFromToolingConfig(config) {
169
+ function workspaceAppsFromToolingConfig(config, workspaceRoot) {
169
170
  return config.topology.apps.map((app)=>{
170
171
  if ('shell' === app.kind) return {
171
172
  ...descriptors_cjs_namespaceObject.shellApp,
@@ -183,8 +184,9 @@ function workspaceAppsFromToolingConfig(config) {
183
184
  const domain = app.domain ?? app.id;
184
185
  const packageSuffix = app.packageSuffix ?? domain;
185
186
  const exposePaths = app.moduleFederation?.exposePaths ?? {};
187
+ const federatedPaths = void 0 === workspaceRoot ? void 0 : (0, mf_validation_cjs_namespaceObject.readModuleFederationExposePaths)(workspaceRoot, app.path);
186
188
  const exposes = Object.fromEntries((app.moduleFederation?.exposes ?? []).map((expose)=>{
187
- const configuredPath = exposePaths[expose];
189
+ const configuredPath = federatedPaths?.[expose] ?? exposePaths[expose];
188
190
  const inferredPath = './Route' === expose ? './src/federation-entry.tsx' : './Widget' === expose ? `./src/components/${domain}-widget.tsx` : `./src/components/${(0, naming_cjs_namespaceObject.toKebabCase)(expose.replace(/^\.\//u, ''))}.tsx`;
189
191
  return [
190
192
  expose,
@@ -224,9 +226,9 @@ function workspaceAppsFromToolingConfig(config) {
224
226
  function additionalShellsFromToolingConfig(config) {
225
227
  return (0, shells_cjs_namespaceObject.resolveConfiguredAdditionalShells)(config);
226
228
  }
227
- function allWorkspaceAppsFromToolingConfig(config) {
229
+ function allWorkspaceAppsFromToolingConfig(config, workspaceRoot) {
228
230
  return [
229
- ...workspaceAppsFromToolingConfig(config),
231
+ ...workspaceAppsFromToolingConfig(config, workspaceRoot),
230
232
  ...additionalShellsFromToolingConfig(config)
231
233
  ];
232
234
  }
@@ -237,7 +239,7 @@ function normalizeWorkspaceInputs(workspaceRoot, inputs, sourcePath = external_n
237
239
  const topologyApps = inputs.topology ? [
238
240
  (0, topology_cjs_namespaceObject.createPrimaryShellDescriptor)(inputs.topology, inputs.config),
239
241
  ...(0, topology_cjs_namespaceObject.verticalsFromTopology)(inputs.topology, ports)
240
- ] : workspaceAppsFromToolingConfig(config);
242
+ ] : workspaceAppsFromToolingConfig(config, workspaceRoot);
241
243
  const apps = [
242
244
  ...topologyApps.map((app)=>({
243
245
  ...app,
@@ -175,7 +175,7 @@ function executeAddUltramodernShell(options, logicalWorkspaceRoot = options.work
175
175
  {
176
176
  relativePath: "scripts/validate-ultramodern-workspace.mts",
177
177
  generatedDataBinding: 'workspaceValidationContract',
178
- content: (0, external_workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(scope, enableTailwind, existingVerticals, void 0, existingAdditionalShells, primaryShell)
178
+ content: (0, external_workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(scope, enableTailwind, existingVerticals, void 0, existingAdditionalShells, primaryShell, void 0, void 0, void 0, logicalWorkspaceRoot)
179
179
  },
180
180
  {
181
181
  relativePath: 'zerops.yaml',
@@ -95,7 +95,7 @@ function executeAddUltramodernVertical(options, logicalWorkspaceRoot = options.w
95
95
  {
96
96
  relativePath: "scripts/validate-ultramodern-workspace.mts",
97
97
  generatedDataBinding: 'workspaceValidationContract',
98
- content: (0, external_workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(scope, enableTailwind, existingVerticals, void 0, previousApps.filter((app)=>'shell' === app.kind && app.id !== primaryShell.id), previousApps.find((app)=>app.id === primaryShell.id))
98
+ content: (0, external_workspace_scripts_cjs_namespaceObject.createPackagedWorkspaceValidationScript)(scope, enableTailwind, existingVerticals, void 0, previousApps.filter((app)=>'shell' === app.kind && app.id !== primaryShell.id), previousApps.find((app)=>app.id === primaryShell.id), void 0, void 0, void 0, logicalWorkspaceRoot)
99
99
  },
100
100
  {
101
101
  relativePath: 'zerops.yaml',
@@ -96,7 +96,7 @@ nothing.
96
96
  if (!external_node_fs_default().existsSync(compactPath)) throw new Error(`Missing ${external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH}. sync-delivery-unit needs the compact UltraModern config. Create a workspace with the current generator.`);
97
97
  const config = (0, config_cjs_namespaceObject.readUltramodernConfig)(workspaceRoot);
98
98
  const scope = config.workspace.packageScope;
99
- const workspaceApps = (0, config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(config);
99
+ const workspaceApps = (0, config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(config, workspaceRoot);
100
100
  const written = [];
101
101
  const unchanged = [];
102
102
  const track = (relativePath, changed)=>{
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ readModuleFederationExposePaths: ()=>readModuleFederationExposePaths
41
+ });
42
+ const external_node_fs_namespaceObject = require("node:fs");
43
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
44
+ const external_node_path_namespaceObject = require("node:path");
45
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const external_constants_cjs_namespaceObject = require("./constants.cjs");
47
+ const external_inspect_cjs_namespaceObject = require("./inspect.cjs");
48
+ function readModuleFederationExposePaths(workspaceRoot, appDirectory) {
49
+ const configPath = external_node_path_default().join(workspaceRoot, appDirectory, external_constants_cjs_namespaceObject.moduleFederationConfigFile);
50
+ if (!external_node_fs_default().existsSync(configPath)) return;
51
+ try {
52
+ return (0, external_inspect_cjs_namespaceObject.inspectModuleFederationConfigSource)(external_node_fs_default().readFileSync(configPath, 'utf-8'), appDirectory, external_node_path_default().join(appDirectory, external_constants_cjs_namespaceObject.moduleFederationConfigFile)).exposePaths;
53
+ } catch {
54
+ return;
55
+ }
56
+ }
57
+ exports.readModuleFederationExposePaths = __webpack_exports__.readModuleFederationExposePaths;
58
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
59
+ "readModuleFederationExposePaths"
60
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
61
+ Object.defineProperty(exports, '__esModule', {
62
+ value: true
63
+ });
@@ -33,14 +33,28 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  const external_object_literal_cjs_namespaceObject = require("./object-literal.cjs");
34
34
  const external_syntax_cjs_namespaceObject = require("./syntax.cjs");
35
35
  function extractExposes(configPath, value) {
36
- if (void 0 === value) return [];
36
+ if (void 0 === value) return {
37
+ exposePaths: {},
38
+ exposes: []
39
+ };
37
40
  const object = (0, external_object_literal_cjs_namespaceObject.parseObjectLiteral)(value);
38
41
  if (object) {
39
42
  if (object.hasSpread) throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object without spreads.`);
40
- return Array.from(object.properties.keys()).sort();
43
+ const exposePaths = {};
44
+ for (const [expose, source] of object.properties){
45
+ const exposePath = (0, external_object_literal_cjs_namespaceObject.parseLiteralString)(source);
46
+ if (void 0 !== exposePath) exposePaths[expose] = exposePath;
47
+ }
48
+ return {
49
+ exposePaths,
50
+ exposes: Array.from(object.properties.keys()).sort()
51
+ };
41
52
  }
42
53
  const array = (0, external_object_literal_cjs_namespaceObject.parseArrayLiteral)(value);
43
- if (array) return array.sort();
54
+ if (array) return {
55
+ exposePaths: {},
56
+ exposes: array.sort()
57
+ };
44
58
  throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object or string array.`);
45
59
  }
46
60
  function extractDtsSettings(configPath, value, exposes) {
@@ -68,13 +82,14 @@ function inspectModuleFederationConfigSource(source, appDir, configPath) {
68
82
  const properties = (0, external_object_literal_cjs_namespaceObject.parseObjectLiteral)(configObject);
69
83
  if (!properties) throw new Error(`Cannot statically inspect Module Federation config ${configPath}; expected a literal config object.`);
70
84
  if (properties.hasSpread) throw new Error(`Cannot statically inspect Module Federation config ${configPath}; top-level config spreads are not supported.`);
71
- const exposes = extractExposes(configPath, properties.properties.get('exposes'));
85
+ const { exposePaths, exposes } = extractExposes(configPath, properties.properties.get('exposes'));
72
86
  const hostOnlyNoExposes = hasHostOnlyNoExposesDeclaration(source);
73
87
  if (hostOnlyNoExposes && exposes.length > 0) throw new Error(`Module Federation host-only/no-exposes declaration conflicts with actual exposes in ${configPath}.`);
74
88
  return {
75
89
  appDir,
76
90
  configPath,
77
91
  dts: extractDtsSettings(configPath, properties.properties.get('dts'), exposes),
92
+ exposePaths,
78
93
  exposes,
79
94
  hostOnlyNoExposes
80
95
  };
@@ -30,17 +30,21 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  discoverModuleFederationConfigs: ()=>discovery_cjs_namespaceObject.discoverModuleFederationConfigs,
32
32
  inspectModuleFederationConfigSource: ()=>inspect_cjs_namespaceObject.inspectModuleFederationConfigSource,
33
+ readModuleFederationExposePaths: ()=>exposes_cjs_namespaceObject.readModuleFederationExposePaths,
33
34
  validateModuleFederationTypes: ()=>validate_cjs_namespaceObject.validateModuleFederationTypes
34
35
  });
35
36
  const discovery_cjs_namespaceObject = require("./mf-validation/discovery.cjs");
37
+ const exposes_cjs_namespaceObject = require("./mf-validation/exposes.cjs");
36
38
  const inspect_cjs_namespaceObject = require("./mf-validation/inspect.cjs");
37
39
  const validate_cjs_namespaceObject = require("./mf-validation/validate.cjs");
38
40
  exports.discoverModuleFederationConfigs = __webpack_exports__.discoverModuleFederationConfigs;
39
41
  exports.inspectModuleFederationConfigSource = __webpack_exports__.inspectModuleFederationConfigSource;
42
+ exports.readModuleFederationExposePaths = __webpack_exports__.readModuleFederationExposePaths;
40
43
  exports.validateModuleFederationTypes = __webpack_exports__.validateModuleFederationTypes;
41
44
  for(var __rspack_i in __webpack_exports__)if (-1 === [
42
45
  "discoverModuleFederationConfigs",
43
46
  "inspectModuleFederationConfigSource",
47
+ "readModuleFederationExposePaths",
44
48
  "validateModuleFederationTypes"
45
49
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
46
50
  Object.defineProperty(exports, '__esModule', {
@@ -125,8 +125,8 @@ const result = createBin
125
125
  });
126
126
  ${toolWrapperResultHandling}`;
127
127
  }
128
- function createPackagedWorkspaceValidationScript(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride) {
129
- const contract = (0, external_workspace_validation_contract_cjs_namespaceObject.createWorkspaceValidationContract)(scope, enableTailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride);
128
+ function createPackagedWorkspaceValidationScript(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot) {
129
+ const contract = (0, external_workspace_validation_contract_cjs_namespaceObject.createWorkspaceValidationContract)(scope, enableTailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot);
130
130
  return (0, external_fs_io_cjs_namespaceObject.renderFileTemplate)("workspace-scripts/validate-ultramodern-workspace.mjs", {
131
131
  workspaceValidationContractJson: JSON.stringify(contract, null, 2),
132
132
  workspaceScriptSegmentPattern: JSON.stringify(external_workspace_script_plan_cjs_namespaceObject.WORKSPACE_SCRIPT_SEGMENT_PATTERN.source)
@@ -36,6 +36,7 @@ const external_backend_federation_cjs_namespaceObject = require("./backend-feder
36
36
  const external_contracts_cjs_namespaceObject = require("./contracts.cjs");
37
37
  const external_delivery_unit_cjs_namespaceObject = require("./delivery-unit.cjs");
38
38
  const external_descriptors_cjs_namespaceObject = require("./descriptors.cjs");
39
+ const external_mf_validation_cjs_namespaceObject = require("./mf-validation.cjs");
39
40
  const external_naming_cjs_namespaceObject = require("./naming.cjs");
40
41
  const external_policy_cjs_namespaceObject = require("./policy.cjs");
41
42
  const external_public_surface_cjs_namespaceObject = require("./public-surface.cjs");
@@ -177,7 +178,14 @@ function createFederatedCompositionPolicy(scope, hosts, remotes) {
177
178
  }))
178
179
  };
179
180
  }
180
- function createWorkspaceValidationContract(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride) {
181
+ function federatedSurfacePaths(remote, workspaceRoot) {
182
+ const declared = void 0 === workspaceRoot ? void 0 : (0, external_mf_validation_cjs_namespaceObject.readModuleFederationExposePaths)(workspaceRoot, remote.directory);
183
+ return Object.keys(remote.exposes ?? {}).map((expose)=>{
184
+ const source = declared?.[expose] ?? remote.exposes?.[expose];
185
+ return source ? `${remote.directory}/${source.replace(/^\.\//u, '')}` : void 0;
186
+ }).filter((componentPath)=>Boolean(componentPath));
187
+ }
188
+ function createWorkspaceValidationContract(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot) {
181
189
  const resolvedPrimaryShell = primaryShell ?? (0, external_descriptors_cjs_namespaceObject.createShellHost)(remotes);
182
190
  const workspaceApps = [
183
191
  resolvedPrimaryShell,
@@ -216,10 +224,7 @@ function createWorkspaceValidationContract(scope, enableTailwind, remotes = [],
216
224
  packageName: (0, external_naming_cjs_namespaceObject.packageName)(scope, remote.packageSuffix),
217
225
  deliveryUnit: (0, external_delivery_unit_cjs_namespaceObject.createDeliveryUnitRecord)(scope, remote),
218
226
  exposes: Object.keys(remote.exposes ?? {}),
219
- componentPaths: Object.keys(remote.exposes ?? {}).map((expose)=>{
220
- const source = remote.exposes?.[expose];
221
- return source ? `${remote.directory}/${source.replace(/^\.\//u, '')}` : void 0;
222
- }).filter((componentPath)=>Boolean(componentPath)),
227
+ componentPaths: federatedSurfacePaths(remote, workspaceRoot),
223
228
  namespace: (0, external_descriptors_cjs_namespaceObject.appI18nNamespace)(remote),
224
229
  routePagePaths: (0, external_routes_cjs_namespaceObject.createRouteOwnedI18nPaths)(remote).filter((route)=>'/' !== route.canonicalPath).map((route)=>(0, external_routes_cjs_namespaceObject.createRoutePageFilePath)(remote, route.canonicalPath)),
225
230
  routeMetaPaths: (0, external_routes_cjs_namespaceObject.createRouteOwnedI18nPaths)(remote).map((route)=>(0, external_routes_cjs_namespaceObject.createRouteMetaFilePath)(remote, route.canonicalPath)),
@@ -11,7 +11,7 @@ const resolveCloudflareOutputVerifyTargets = (args, context)=>{
11
11
  label: outputDirectory,
12
12
  outputDirectory: node_path.resolve(context.invocationCwd, outputDirectory)
13
13
  }
14
- ] : workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
14
+ ] : workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
15
15
  label: app.id,
16
16
  outputDirectory: node_path.join(context.workspaceRoot, app.directory, '.output')
17
17
  }));
@@ -4,7 +4,7 @@ import { runRenderedModule } from "./context.js";
4
4
  import { readOption } from "./options.js";
5
5
  const resolveRoutesGenerateTargets = (args, context)=>{
6
6
  const appId = readOption(args, '--app');
7
- const targets = workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
7
+ const targets = workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
8
8
  label: app.id,
9
9
  appDirectory: node_path.join(context.workspaceRoot, app.directory)
10
10
  }));
@@ -10,7 +10,7 @@ function runValidate(context) {
10
10
  overlay: readJsonObject(node_path.join(context.workspaceRoot, 'topology/local-overlays/development.json'))
11
11
  });
12
12
  const { config, verticals: remotes, primaryShell, additionalShells } = workspace;
13
- const compactApps = workspaceAppsFromToolingConfig(config);
13
+ const compactApps = workspaceAppsFromToolingConfig(config, context.workspaceRoot);
14
14
  const compactPrimaryShell = compactApps.find((app)=>'shell' === app.kind) ?? createShellHost(remotes);
15
15
  const compactConfig = createUltramodernConfig(config.workspace.packageScope, 'workspace-validation-contract', {
16
16
  strategy: 'workspace',
@@ -27,7 +27,7 @@ function runValidate(context) {
27
27
  ])if (declared && Object.hasOwn(declared, key)) app.deploy.cloudflare[key] = declared[key];
28
28
  }
29
29
  const releaseCohort = config.packageSource?.strategy === 'install' ? readWorkspaceReleaseCohort(context.workspaceRoot) : void 0;
30
- const source = createPackagedWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, readJsonObject(node_path.join(context.workspaceRoot, 'topology/ownership.json')));
30
+ const source = createPackagedWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, readJsonObject(node_path.join(context.workspaceRoot, 'topology/ownership.json')), void 0, context.workspaceRoot);
31
31
  return runRenderedModule(source, context);
32
32
  }
33
33
  export { runValidate };
@@ -2,6 +2,7 @@ import node_path from "node:path";
2
2
  import { createPrimaryShellDescriptor, verticalsFromTopology } from "../../ultramodern-workspace/add-vertical/topology.js";
3
3
  import { normalizeUltramodernBridgeConfig } from "../../ultramodern-workspace/bridge-config.js";
4
4
  import { ULTRAMODERN_CONFIG_PATH, createNeutralOwnership, shellApp } from "../../ultramodern-workspace/descriptors.js";
5
+ import { readModuleFederationExposePaths } from "../../ultramodern-workspace/mf-validation.js";
5
6
  import { toKebabCase } from "../../ultramodern-workspace/naming.js";
6
7
  import { resolveConfiguredAdditionalShells } from "../../ultramodern-workspace/shells.js";
7
8
  import { isVerticalApiProtocol, isVerticalPreset, isWorkspaceDeliveryUnitKind } from "../../ultramodern-workspace/types.js";
@@ -115,7 +116,7 @@ function formatSchemaVersionError(sourcePath, reason, value) {
115
116
  function normalizeCompactUltramodernConfig(workspaceRoot, compact) {
116
117
  return normalizeCompactConfig(workspaceRoot, node_path.join(workspaceRoot, ULTRAMODERN_CONFIG_PATH), compact);
117
118
  }
118
- function workspaceAppsFromToolingConfig(config) {
119
+ function workspaceAppsFromToolingConfig(config, workspaceRoot) {
119
120
  return config.topology.apps.map((app)=>{
120
121
  if ('shell' === app.kind) return {
121
122
  ...shellApp,
@@ -133,8 +134,9 @@ function workspaceAppsFromToolingConfig(config) {
133
134
  const domain = app.domain ?? app.id;
134
135
  const packageSuffix = app.packageSuffix ?? domain;
135
136
  const exposePaths = app.moduleFederation?.exposePaths ?? {};
137
+ const federatedPaths = void 0 === workspaceRoot ? void 0 : readModuleFederationExposePaths(workspaceRoot, app.path);
136
138
  const exposes = Object.fromEntries((app.moduleFederation?.exposes ?? []).map((expose)=>{
137
- const configuredPath = exposePaths[expose];
139
+ const configuredPath = federatedPaths?.[expose] ?? exposePaths[expose];
138
140
  const inferredPath = './Route' === expose ? './src/federation-entry.tsx' : './Widget' === expose ? `./src/components/${domain}-widget.tsx` : `./src/components/${toKebabCase(expose.replace(/^\.\//u, ''))}.tsx`;
139
141
  return [
140
142
  expose,
@@ -174,9 +176,9 @@ function workspaceAppsFromToolingConfig(config) {
174
176
  function additionalShellsFromToolingConfig(config) {
175
177
  return resolveConfiguredAdditionalShells(config);
176
178
  }
177
- function allWorkspaceAppsFromToolingConfig(config) {
179
+ function allWorkspaceAppsFromToolingConfig(config, workspaceRoot) {
178
180
  return [
179
- ...workspaceAppsFromToolingConfig(config),
181
+ ...workspaceAppsFromToolingConfig(config, workspaceRoot),
180
182
  ...additionalShellsFromToolingConfig(config)
181
183
  ];
182
184
  }
@@ -187,7 +189,7 @@ function normalizeWorkspaceInputs(workspaceRoot, inputs, sourcePath = node_path.
187
189
  const topologyApps = inputs.topology ? [
188
190
  createPrimaryShellDescriptor(inputs.topology, inputs.config),
189
191
  ...verticalsFromTopology(inputs.topology, ports)
190
- ] : workspaceAppsFromToolingConfig(config);
192
+ ] : workspaceAppsFromToolingConfig(config, workspaceRoot);
191
193
  const apps = [
192
194
  ...topologyApps.map((app)=>({
193
195
  ...app,
@@ -130,7 +130,7 @@ function executeAddUltramodernShell(options, logicalWorkspaceRoot = options.work
130
130
  {
131
131
  relativePath: "scripts/validate-ultramodern-workspace.mts",
132
132
  generatedDataBinding: 'workspaceValidationContract',
133
- content: createPackagedWorkspaceValidationScript(scope, enableTailwind, existingVerticals, void 0, existingAdditionalShells, primaryShell)
133
+ content: createPackagedWorkspaceValidationScript(scope, enableTailwind, existingVerticals, void 0, existingAdditionalShells, primaryShell, void 0, void 0, void 0, logicalWorkspaceRoot)
134
134
  },
135
135
  {
136
136
  relativePath: 'zerops.yaml',
@@ -53,7 +53,7 @@ function executeAddUltramodernVertical(options, logicalWorkspaceRoot = options.w
53
53
  {
54
54
  relativePath: "scripts/validate-ultramodern-workspace.mts",
55
55
  generatedDataBinding: 'workspaceValidationContract',
56
- content: createPackagedWorkspaceValidationScript(scope, enableTailwind, existingVerticals, void 0, previousApps.filter((app)=>'shell' === app.kind && app.id !== primaryShell.id), previousApps.find((app)=>app.id === primaryShell.id))
56
+ content: createPackagedWorkspaceValidationScript(scope, enableTailwind, existingVerticals, void 0, previousApps.filter((app)=>'shell' === app.kind && app.id !== primaryShell.id), previousApps.find((app)=>app.id === primaryShell.id), void 0, void 0, void 0, logicalWorkspaceRoot)
57
57
  },
58
58
  {
59
59
  relativePath: 'zerops.yaml',
@@ -53,7 +53,7 @@ nothing.
53
53
  if (!node_fs.existsSync(compactPath)) throw new Error(`Missing ${ULTRAMODERN_CONFIG_PATH}. sync-delivery-unit needs the compact UltraModern config. Create a workspace with the current generator.`);
54
54
  const config = readUltramodernConfig(workspaceRoot);
55
55
  const scope = config.workspace.packageScope;
56
- const workspaceApps = workspaceAppsFromToolingConfig(config);
56
+ const workspaceApps = workspaceAppsFromToolingConfig(config, workspaceRoot);
57
57
  const written = [];
58
58
  const unchanged = [];
59
59
  const track = (relativePath, changed)=>{
@@ -0,0 +1,14 @@
1
+ import node_fs from "node:fs";
2
+ import node_path from "node:path";
3
+ import { moduleFederationConfigFile } from "./constants.js";
4
+ import { inspectModuleFederationConfigSource } from "./inspect.js";
5
+ function readModuleFederationExposePaths(workspaceRoot, appDirectory) {
6
+ const configPath = node_path.join(workspaceRoot, appDirectory, moduleFederationConfigFile);
7
+ if (!node_fs.existsSync(configPath)) return;
8
+ try {
9
+ return inspectModuleFederationConfigSource(node_fs.readFileSync(configPath, 'utf-8'), appDirectory, node_path.join(appDirectory, moduleFederationConfigFile)).exposePaths;
10
+ } catch {
11
+ return;
12
+ }
13
+ }
14
+ export { readModuleFederationExposePaths };
@@ -1,14 +1,28 @@
1
1
  import { parseArrayLiteral, parseLiteralString, parseObjectLiteral } from "./object-literal.js";
2
2
  import { findCreateModuleFederationConfigObject, findExportDefaultObject, parseConfigModule } from "./syntax.js";
3
3
  function extractExposes(configPath, value) {
4
- if (void 0 === value) return [];
4
+ if (void 0 === value) return {
5
+ exposePaths: {},
6
+ exposes: []
7
+ };
5
8
  const object = parseObjectLiteral(value);
6
9
  if (object) {
7
10
  if (object.hasSpread) throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object without spreads.`);
8
- return Array.from(object.properties.keys()).sort();
11
+ const exposePaths = {};
12
+ for (const [expose, source] of object.properties){
13
+ const exposePath = parseLiteralString(source);
14
+ if (void 0 !== exposePath) exposePaths[expose] = exposePath;
15
+ }
16
+ return {
17
+ exposePaths,
18
+ exposes: Array.from(object.properties.keys()).sort()
19
+ };
9
20
  }
10
21
  const array = parseArrayLiteral(value);
11
- if (array) return array.sort();
22
+ if (array) return {
23
+ exposePaths: {},
24
+ exposes: array.sort()
25
+ };
12
26
  throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object or string array.`);
13
27
  }
14
28
  function extractDtsSettings(configPath, value, exposes) {
@@ -36,13 +50,14 @@ function inspectModuleFederationConfigSource(source, appDir, configPath) {
36
50
  const properties = parseObjectLiteral(configObject);
37
51
  if (!properties) throw new Error(`Cannot statically inspect Module Federation config ${configPath}; expected a literal config object.`);
38
52
  if (properties.hasSpread) throw new Error(`Cannot statically inspect Module Federation config ${configPath}; top-level config spreads are not supported.`);
39
- const exposes = extractExposes(configPath, properties.properties.get('exposes'));
53
+ const { exposePaths, exposes } = extractExposes(configPath, properties.properties.get('exposes'));
40
54
  const hostOnlyNoExposes = hasHostOnlyNoExposesDeclaration(source);
41
55
  if (hostOnlyNoExposes && exposes.length > 0) throw new Error(`Module Federation host-only/no-exposes declaration conflicts with actual exposes in ${configPath}.`);
42
56
  return {
43
57
  appDir,
44
58
  configPath,
45
59
  dts: extractDtsSettings(configPath, properties.properties.get('dts'), exposes),
60
+ exposePaths,
46
61
  exposes,
47
62
  hostOnlyNoExposes
48
63
  };
@@ -1,3 +1,4 @@
1
1
  export { discoverModuleFederationConfigs } from "./mf-validation/discovery.js";
2
+ export { readModuleFederationExposePaths } from "./mf-validation/exposes.js";
2
3
  export { inspectModuleFederationConfigSource } from "./mf-validation/inspect.js";
3
4
  export { validateModuleFederationTypes } from "./mf-validation/validate.js";
@@ -78,8 +78,8 @@ const result = createBin
78
78
  });
79
79
  ${toolWrapperResultHandling}`;
80
80
  }
81
- function createPackagedWorkspaceValidationScript(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride) {
82
- const contract = createWorkspaceValidationContract(scope, enableTailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride);
81
+ function createPackagedWorkspaceValidationScript(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot) {
82
+ const contract = createWorkspaceValidationContract(scope, enableTailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot);
83
83
  return renderFileTemplate("workspace-scripts/validate-ultramodern-workspace.mjs", {
84
84
  workspaceValidationContractJson: JSON.stringify(contract, null, 2),
85
85
  workspaceScriptSegmentPattern: JSON.stringify(WORKSPACE_SCRIPT_SEGMENT_PATTERN.source)
@@ -4,6 +4,7 @@ import { createBackendFederationMetadata } from "./backend-federation.js";
4
4
  import { createDevelopmentOverlay, createOwnership, createTopology, createUltramodernConfig } from "./contracts.js";
5
5
  import { createDeliveryUnitRecord } from "./delivery-unit.js";
6
6
  import { appEmitsBrowserUi, appHasApi, appI18nNamespace, createShellHost, remoteDependencyAlias, resolveApiProtocol, resolveApiStem, sharedPackages, shellApp } from "./descriptors.js";
7
+ import { readModuleFederationExposePaths } from "./mf-validation.js";
7
8
  import { packageName, tailwindPrefixForApp } from "./naming.js";
8
9
  import { createCloudflareSecurityContract } from "./policy.js";
9
10
  import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
@@ -145,7 +146,14 @@ function createFederatedCompositionPolicy(scope, hosts, remotes) {
145
146
  }))
146
147
  };
147
148
  }
148
- function createWorkspaceValidationContract(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride) {
149
+ function federatedSurfacePaths(remote, workspaceRoot) {
150
+ const declared = void 0 === workspaceRoot ? void 0 : readModuleFederationExposePaths(workspaceRoot, remote.directory);
151
+ return Object.keys(remote.exposes ?? {}).map((expose)=>{
152
+ const source = declared?.[expose] ?? remote.exposes?.[expose];
153
+ return source ? `${remote.directory}/${source.replace(/^\.\//u, '')}` : void 0;
154
+ }).filter((componentPath)=>Boolean(componentPath));
155
+ }
156
+ function createWorkspaceValidationContract(scope, enableTailwind, remotes = [], releaseCohort, additionalShells = [], primaryShell, compactConfigOverride, ownershipOverride, developmentOverlayOverride, workspaceRoot) {
149
157
  const resolvedPrimaryShell = primaryShell ?? createShellHost(remotes);
150
158
  const workspaceApps = [
151
159
  resolvedPrimaryShell,
@@ -184,10 +192,7 @@ function createWorkspaceValidationContract(scope, enableTailwind, remotes = [],
184
192
  packageName: packageName(scope, remote.packageSuffix),
185
193
  deliveryUnit: createDeliveryUnitRecord(scope, remote),
186
194
  exposes: Object.keys(remote.exposes ?? {}),
187
- componentPaths: Object.keys(remote.exposes ?? {}).map((expose)=>{
188
- const source = remote.exposes?.[expose];
189
- return source ? `${remote.directory}/${source.replace(/^\.\//u, '')}` : void 0;
190
- }).filter((componentPath)=>Boolean(componentPath)),
195
+ componentPaths: federatedSurfacePaths(remote, workspaceRoot),
191
196
  namespace: appI18nNamespace(remote),
192
197
  routePagePaths: createRouteOwnedI18nPaths(remote).filter((route)=>'/' !== route.canonicalPath).map((route)=>createRoutePageFilePath(remote, route.canonicalPath)),
193
198
  routeMetaPaths: createRouteOwnedI18nPaths(remote).map((route)=>createRouteMetaFilePath(remote, route.canonicalPath)),
@@ -12,7 +12,7 @@ const resolveCloudflareOutputVerifyTargets = (args, context)=>{
12
12
  label: outputDirectory,
13
13
  outputDirectory: node_path.resolve(context.invocationCwd, outputDirectory)
14
14
  }
15
- ] : workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
15
+ ] : workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
16
16
  label: app.id,
17
17
  outputDirectory: node_path.join(context.workspaceRoot, app.directory, '.output')
18
18
  }));
@@ -5,7 +5,7 @@ import { runRenderedModule } from "./context.js";
5
5
  import { readOption } from "./options.js";
6
6
  const resolveRoutesGenerateTargets = (args, context)=>{
7
7
  const appId = readOption(args, '--app');
8
- const targets = workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot)).filter((app)=>!appId || app.id === appId).map((app)=>({
8
+ const targets = workspaceAppsFromToolingConfig(readUltramodernConfig(context.workspaceRoot), context.workspaceRoot).filter((app)=>!appId || app.id === appId).map((app)=>({
9
9
  label: app.id,
10
10
  appDirectory: node_path.join(context.workspaceRoot, app.directory)
11
11
  }));
@@ -11,7 +11,7 @@ function runValidate(context) {
11
11
  overlay: readJsonObject(node_path.join(context.workspaceRoot, 'topology/local-overlays/development.json'))
12
12
  });
13
13
  const { config, verticals: remotes, primaryShell, additionalShells } = workspace;
14
- const compactApps = workspaceAppsFromToolingConfig(config);
14
+ const compactApps = workspaceAppsFromToolingConfig(config, context.workspaceRoot);
15
15
  const compactPrimaryShell = compactApps.find((app)=>'shell' === app.kind) ?? createShellHost(remotes);
16
16
  const compactConfig = createUltramodernConfig(config.workspace.packageScope, 'workspace-validation-contract', {
17
17
  strategy: 'workspace',
@@ -28,7 +28,7 @@ function runValidate(context) {
28
28
  ])if (declared && Object.hasOwn(declared, key)) app.deploy.cloudflare[key] = declared[key];
29
29
  }
30
30
  const releaseCohort = config.packageSource?.strategy === 'install' ? readWorkspaceReleaseCohort(context.workspaceRoot) : void 0;
31
- const source = createPackagedWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, readJsonObject(node_path.join(context.workspaceRoot, 'topology/ownership.json')));
31
+ const source = createPackagedWorkspaceValidationScript(config.workspace.packageScope, config.features.tailwind, remotes, releaseCohort, additionalShells, primaryShell, compactConfig, readJsonObject(node_path.join(context.workspaceRoot, 'topology/ownership.json')), void 0, context.workspaceRoot);
32
32
  return runRenderedModule(source, context);
33
33
  }
34
34
  export { runValidate };