@bleedingdev/modern-js-ultramodern-create 3.8.3-ultramodern.2 → 3.8.3-ultramodern.4

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 (41) hide show
  1. package/dist/cjs/ultramodern-tooling/commands/mf-types.cjs +29 -3
  2. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.cjs +11 -3
  3. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +31 -3
  4. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +13 -1
  5. package/dist/cjs/ultramodern-workspace/demo-components.cjs +90 -6
  6. package/dist/cjs/ultramodern-workspace/mf-validation/constants.cjs +7 -4
  7. package/dist/cjs/ultramodern-workspace/mf-validation/validate.cjs +3 -3
  8. package/dist/cjs/ultramodern-workspace/routes.cjs +6 -9
  9. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +11 -3
  10. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +32 -2
  11. package/dist/esm/ultramodern-tooling/commands/mf-types.js +29 -3
  12. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +11 -3
  13. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +32 -4
  14. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +14 -2
  15. package/dist/esm/ultramodern-workspace/demo-components.js +88 -7
  16. package/dist/esm/ultramodern-workspace/mf-validation/constants.js +5 -2
  17. package/dist/esm/ultramodern-workspace/mf-validation/validate.js +4 -4
  18. package/dist/esm/ultramodern-workspace/routes.js +4 -10
  19. package/dist/esm/ultramodern-workspace/tsconfigs.js +11 -3
  20. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +33 -3
  21. package/dist/esm-node/ultramodern-tooling/commands/mf-types.js +29 -3
  22. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +11 -3
  23. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +32 -4
  24. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +14 -2
  25. package/dist/esm-node/ultramodern-workspace/demo-components.js +88 -7
  26. package/dist/esm-node/ultramodern-workspace/mf-validation/constants.js +5 -2
  27. package/dist/esm-node/ultramodern-workspace/mf-validation/validate.js +4 -4
  28. package/dist/esm-node/ultramodern-workspace/routes.js +4 -10
  29. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +11 -3
  30. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +33 -3
  31. package/dist/types/ultramodern-workspace/demo-components.d.ts +2 -1
  32. package/dist/types/ultramodern-workspace/mf-validation/constants.d.ts +4 -1
  33. package/dist/types/ultramodern-workspace/mf-validation/types.d.ts +2 -0
  34. package/dist/types/ultramodern-workspace/mf-validation/validate.d.ts +2 -2
  35. package/dist/types/ultramodern-workspace/mf-validation.d.ts +1 -1
  36. package/dist/types/ultramodern-workspace/routes.d.ts +1 -0
  37. package/dist/types/ultramodern-workspace/tsconfigs.d.ts +1 -0
  38. package/package.json +4 -4
  39. package/template-workspace/.modernjs/release-cohort.json +40 -40
  40. package/templates/workspace-scripts/ultramodern-typecheck.mjs +11 -1
  41. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +15 -0
@@ -31,18 +31,44 @@ __webpack_require__.d(__webpack_exports__, {
31
31
  runMfTypes: ()=>runMfTypes
32
32
  });
33
33
  const mf_validation_cjs_namespaceObject = require("../../ultramodern-workspace/mf-validation.cjs");
34
+ function parseMfTypesArgs(args) {
35
+ const appDirs = [];
36
+ let target = 'node';
37
+ for(let index = 0; index < args.length; index += 1){
38
+ const arg = args[index];
39
+ if (void 0 === arg || '--' === arg) continue;
40
+ let targetValue;
41
+ if ('--target' === arg) {
42
+ targetValue = args[index + 1];
43
+ if (void 0 === targetValue || targetValue.startsWith('-')) throw new Error('--target needs a value.');
44
+ index += 1;
45
+ } else if (arg.startsWith('--target=')) targetValue = arg.slice(9);
46
+ else if (arg.startsWith('-')) throw new Error(`Unknown mf-types option: ${arg}`);
47
+ else appDirs.push(arg);
48
+ if (void 0 !== targetValue) {
49
+ if ('node' !== targetValue && 'cloudflare' !== targetValue) throw new Error(`Invalid mf-types target "${targetValue}". Expected "node" or "cloudflare".`);
50
+ target = targetValue;
51
+ }
52
+ }
53
+ return {
54
+ appDirs,
55
+ target
56
+ };
57
+ }
34
58
  function runMfTypes(args, context) {
35
59
  if (args.includes('--help') || args.includes('-h')) {
36
60
  process.stdout.write(`Usage:
37
- ultramodern-create ultramodern mf-types [app-dir...]
61
+ ultramodern-create ultramodern mf-types [--target node|cloudflare] [app-dir...]
38
62
 
39
- Checks real Module Federation config files and DTS archives for exposed apps.
63
+ Checks real Module Federation config files and target-specific DTS archives for exposed apps.
40
64
  `);
41
65
  return 0;
42
66
  }
67
+ const { appDirs, target } = parseMfTypesArgs(args);
43
68
  (0, mf_validation_cjs_namespaceObject.validateModuleFederationTypes)({
44
69
  workspaceRoot: context.workspaceRoot,
45
- appDirs: args.length > 0 ? args : void 0
70
+ appDirs: appDirs.length > 0 ? appDirs : void 0,
71
+ target
46
72
  });
47
73
  return 0;
48
74
  }
@@ -105,6 +105,9 @@ function removeTsCheckerBuildOverride(source) {
105
105
  },
106
106
  `, '');
107
107
  }
108
+ function removeReleaseEnvelopePlugin(source) {
109
+ return source.replace(' ultramodernReleaseEnvelopePlugin,\n', '').replace(' ultramodernReleaseEnvelopePlugin(),\n', '');
110
+ }
108
111
  function updateGeneratedModernConfigs(io, config) {
109
112
  const apps = (0, external_config_cjs_namespaceObject.allWorkspaceAppsFromToolingConfig)(config);
110
113
  const remotes = apps.filter((app)=>'shell' !== app.kind);
@@ -131,10 +134,15 @@ function updateGeneratedModernConfigs(io, config) {
131
134
  previousTailwindModernConfig,
132
135
  addLegacyGeneratedModernDefaults(previousTailwindModernConfig)
133
136
  ];
134
- const [generatedModernConfig, ...recognizedGeneratedModernConfigs] = formatGeneratedModernConfigCandidates(currentGeneratedModernConfigs.flatMap((source)=>[
137
+ const [generatedModernConfig, ...recognizedGeneratedModernConfigs] = formatGeneratedModernConfigCandidates(currentGeneratedModernConfigs.flatMap((source)=>{
138
+ const withoutReleaseEnvelope = removeReleaseEnvelopePlugin(source);
139
+ return [
135
140
  source,
136
- removeTsCheckerBuildOverride(source)
137
- ]));
141
+ removeTsCheckerBuildOverride(source),
142
+ withoutReleaseEnvelope,
143
+ removeTsCheckerBuildOverride(withoutReleaseEnvelope)
144
+ ];
145
+ }));
138
146
  if (external_node_fs_default().existsSync(modernConfigPath)) {
139
147
  const existingModernConfig = external_node_fs_default().readFileSync(modernConfigPath, 'utf-8');
140
148
  if (existingModernConfig === generatedModernConfig) io.writeGenerated(modernConfigPath, existingModernConfig);
@@ -145,10 +145,13 @@ function manifestApps(manifest) {
145
145
  function packageManifest(io, appDirectory) {
146
146
  return readJsonObject(external_node_path_default().join(io.workspaceRoot, appDirectory, 'package.json'));
147
147
  }
148
- function shellSurfaceIsOwned(io, app, manifestApp) {
148
+ function appSurfaceIsOwned(io, app, manifestApp) {
149
149
  const packageJson = packageManifest(io, app.directory);
150
+ return manifestApp.path === app.directory && manifestApp.kind === app.kind && 'string' == typeof manifestApp.package && packageJson?.name === manifestApp.package;
151
+ }
152
+ function shellSurfaceIsOwned(io, app, manifestApp) {
150
153
  const moduleFederation = jsonObject(manifestApp.moduleFederation);
151
- return 'shell' === manifestApp.kind && manifestApp.path === app.directory && moduleFederation?.role === 'host' && 'string' == typeof manifestApp.package && packageJson?.name === manifestApp.package;
154
+ return appSurfaceIsOwned(io, app, manifestApp) && 'shell' === app.kind && moduleFederation?.role === 'host';
152
155
  }
153
156
  function deliveryUnitSurfaceIsOwned(io, config, app, manifestApp, expose, sourcePath) {
154
157
  const deliveryUnit = jsonObject(manifestApp.deliveryUnit);
@@ -159,6 +162,30 @@ function deliveryUnitSurfaceIsOwned(io, config, app, manifestApp, expose, source
159
162
  const packageName = manifestApp.package;
160
163
  return 'vertical' === manifestApp.kind && manifestApp.path === app.directory && 'string' == typeof packageName && packageJson?.name === packageName && deliveryUnit?.kind === 'microvertical-delivery-unit' && deliveryUnit.packageName === packageName && deliveryUnit.unitId === `${config.workspace.packageScope}/${app.id}` && exposedSurfaces.includes(expose) && packageExports?.[expose] === sourcePath;
161
164
  }
165
+ function updateGeneratedProductRouteAdapters(io, config) {
166
+ const manifest = generatedManifest(io, config);
167
+ if (void 0 === manifest) return false;
168
+ const appsById = new Map(manifestApps(manifest).map((app)=>[
169
+ String(app.id ?? ''),
170
+ app
171
+ ]));
172
+ let changed = false;
173
+ for (const app of (0, external_config_cjs_namespaceObject.allWorkspaceAppsFromToolingConfig)(config)){
174
+ const manifestApp = appsById.get(app.id);
175
+ if ('decide' !== app.id && 'shell' !== app.kind || void 0 === manifestApp || !appSurfaceIsOwned(io, app, manifestApp)) continue;
176
+ const routeDirectory = external_node_path_default().join(io.workspaceRoot, app.directory, 'src/routes/[lang]/tractors/[slug]');
177
+ for (const fileName of [
178
+ 'page.search.ts',
179
+ 'page.tsx'
180
+ ]){
181
+ const filePath = external_node_path_default().join(routeDirectory, fileName);
182
+ if (!external_node_fs_default().existsSync(filePath)) continue;
183
+ const source = external_node_fs_default().readFileSync(filePath, 'utf-8');
184
+ changed = io.write(filePath, (0, demo_components_cjs_namespaceObject.regenerateGeneratedProductRouteAdapter)(source)) || changed;
185
+ }
186
+ }
187
+ return changed;
188
+ }
162
189
  function updateGeneratedNavigationSurfaces(io, config) {
163
190
  const manifest = generatedManifest(io, config);
164
191
  if (void 0 === manifest) return false;
@@ -187,7 +214,7 @@ function updateGeneratedNavigationSurfaces(io, config) {
187
214
  const filePath = external_node_path_default().join(io.workspaceRoot, relativePath);
188
215
  if (!external_node_fs_default().existsSync(filePath)) continue;
189
216
  const source = external_node_fs_default().readFileSync(filePath, 'utf-8');
190
- if (source.includes(`data-modern-boundary-id="${app.id}"`) && source.includes(`data-modern-mf-expose="${expose}"`)) changed = io.write(filePath, (0, demo_components_cjs_namespaceObject.regenerateGeneratedNavigationSurface)(source, 'demo-component')) || changed;
217
+ if (source.includes(`data-modern-boundary-id="${app.id}"`) && source.includes(`data-modern-mf-expose="${expose}"`)) changed = io.write(filePath, (0, demo_components_cjs_namespaceObject.regenerateGeneratedNavigationSurface)(source, './AddToCart' === expose ? 'checkout-add-to-cart' : 'checkout-page')) || changed;
191
218
  }
192
219
  }
193
220
  }
@@ -268,6 +295,7 @@ function updateGeneratedTypeScriptSurfaces(io, config) {
268
295
  }
269
296
  }
270
297
  updateGeneratedShellRuntimeSurfaces(io, config);
298
+ updateGeneratedProductRouteAdapters(io, config);
271
299
  updateGeneratedNavigationSurfaces(io, config);
272
300
  }
273
301
  exports.updateGeneratedTypeScriptSurfaces = __webpack_exports__.updateGeneratedTypeScriptSurfaces;
@@ -60,12 +60,24 @@ function updateDeclaredDependencies(packageJson, pins) {
60
60
  return changed;
61
61
  }
62
62
  function updateModernDependencies(packageJson, packageSource) {
63
+ let changed = false;
64
+ for (const section of [
65
+ 'dependencies',
66
+ 'devDependencies'
67
+ ]){
68
+ const dependencies = packageJson[section];
69
+ if (dependencies && Object.hasOwn(dependencies, '@modern-js/create')) {
70
+ dependencies[external_ultramodern_package_source_cjs_namespaceObject.ULTRAMODERN_CREATE_PACKAGE] = (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)(external_ultramodern_package_source_cjs_namespaceObject.ULTRAMODERN_CREATE_PACKAGE, packageSource);
71
+ delete dependencies['@modern-js/create'];
72
+ changed = true;
73
+ }
74
+ }
63
75
  return updateDeclaredDependencies(packageJson, new Map([
64
76
  ...modernPackageNames
65
77
  ].map((packageName)=>[
66
78
  packageName,
67
79
  (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)(packageName, packageSource)
68
- ])));
80
+ ]))) || changed;
69
81
  }
70
82
  const generatedToolingDependencyPins = new Map(Object.entries({
71
83
  ...policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.appDependencies,
@@ -38,6 +38,7 @@ __webpack_require__.d(__webpack_exports__, {
38
38
  createShellRemoteComponents: ()=>createShellRemoteComponents,
39
39
  createShellWorkerRemoteComponents: ()=>createShellWorkerRemoteComponents,
40
40
  regenerateGeneratedNavigationSurface: ()=>regenerateGeneratedNavigationSurface,
41
+ regenerateGeneratedProductRouteAdapter: ()=>regenerateGeneratedProductRouteAdapter,
41
42
  remoteComponentOutputPath: ()=>remoteComponentOutputPath
42
43
  });
43
44
  const external_descriptors_cjs_namespaceObject = require("./descriptors.cjs");
@@ -454,6 +455,21 @@ function ensureNamedImport(source, moduleName, names) {
454
455
  const importLine = `import { ${names.join(', ')} } from '${moduleName}';\n`;
455
456
  return firstImportEnd < 0 ? `${importLine}${source}` : `${source.slice(0, firstImportEnd + 1)}${importLine}${source.slice(firstImportEnd + 1)}`;
456
457
  }
458
+ function removeNamedImport(source, moduleName, name) {
459
+ const importEndMarker = `from '${moduleName}';`;
460
+ const importEnd = source.indexOf(importEndMarker);
461
+ if (importEnd < 0) return source;
462
+ const importStart = source.lastIndexOf('import ', importEnd);
463
+ const openBrace = source.indexOf('{', importStart);
464
+ const closeBrace = source.indexOf('}', openBrace);
465
+ if (openBrace < 0 || closeBrace < 0 || closeBrace > importEnd) return source;
466
+ const names = source.slice(openBrace + 1, closeBrace).split(',').map((importName)=>importName.trim()).filter((importName)=>'' !== importName && importName !== name);
467
+ if (0 === names.length) {
468
+ const lineEnd = source.indexOf('\n', importEnd + importEndMarker.length);
469
+ return `${source.slice(0, importStart)}${source.slice(lineEnd < 0 ? source.length : lineEnd + 1)}`;
470
+ }
471
+ return `${source.slice(0, openBrace + 1)} ${names.join(', ')} ${source.slice(closeBrace)}`;
472
+ }
457
473
  function ensureNavigateHook(source) {
458
474
  if (source.includes('const navigate = useNavigate();')) return source;
459
475
  const functionStart = source.indexOf('export default function ');
@@ -573,6 +589,43 @@ function removeSyntheticClickHandler(openingTag) {
573
589
  }
574
590
  return openingTag;
575
591
  }
592
+ function rewriteCheckoutCartLink(source) {
593
+ let changed = false;
594
+ const next = source.replace(/^(\s*)to=\{`\/\$\{language\}\/cart\?sku=\$\{sku\}`\},?$/gmu, (_match, indentation)=>{
595
+ changed = true;
596
+ return `${indentation}params={{ lang: language }}\n${indentation}search={{ sku }}\n${indentation}to="/$lang/cart"`;
597
+ });
598
+ return {
599
+ changed,
600
+ source: next
601
+ };
602
+ }
603
+ function rewriteCrossRemoteTractorsLink(source) {
604
+ let next = source;
605
+ let searchFrom = 0;
606
+ let changed = false;
607
+ while(true){
608
+ const openingTagStart = next.indexOf('<Link', searchFrom);
609
+ if (openingTagStart < 0) break;
610
+ const openingTagEnd = closingJsxTag(next, openingTagStart);
611
+ if (openingTagEnd < 0) break;
612
+ const openingTag = next.slice(openingTagStart, openingTagEnd + 1);
613
+ if (!openingTag.includes("to={`/${language}/tractors`}")) {
614
+ searchFrom = openingTagEnd + 1;
615
+ continue;
616
+ }
617
+ const closingTagStart = next.indexOf('</Link>', openingTagEnd + 1);
618
+ if (closingTagStart < 0) break;
619
+ const nativeOpeningTag = openingTag.replace('<Link', '<a').replace('to=', 'href=');
620
+ next = `${next.slice(0, openingTagStart)}${nativeOpeningTag}${next.slice(openingTagEnd + 1, closingTagStart)}</a>${next.slice(closingTagStart + 7)}`;
621
+ searchFrom = openingTagStart + nativeOpeningTag.length;
622
+ changed = true;
623
+ }
624
+ return {
625
+ changed,
626
+ source: next
627
+ };
628
+ }
576
629
  function rewriteInternalAnchors(source) {
577
630
  let next = source;
578
631
  let searchFrom = 0;
@@ -630,21 +683,49 @@ function rewriteJsxElementName(source, elementName, componentName) {
630
683
  source: next
631
684
  };
632
685
  }
686
+ function ensureNoPropsComponentContract(source) {
687
+ let changed = false;
688
+ let next = source.replace(/export default function ([A-Za-z_$][\w$]*)\(\) \{/u, (_match, componentName)=>{
689
+ changed = true;
690
+ return `export default function ${componentName}(\n props: Record<string, never>\n): JSX.Element {\n void props;`;
691
+ });
692
+ if (changed) next = ensureNamedImport(next, 'react', [
693
+ 'JSX'
694
+ ]);
695
+ return {
696
+ changed,
697
+ source: next
698
+ };
699
+ }
700
+ function regenerateGeneratedProductRouteAdapter(source) {
701
+ let next = source.replaceAll('search.sku', "search['sku']");
702
+ next = next.replace(/<(DecideProductPage|ProductPage) sku=\{sku\} slug=\{slug\} \/>/u, `<$1\n {...(sku === undefined ? {} : { sku })}\n {...(slug === undefined ? {} : { slug })}\n />`);
703
+ return next;
704
+ }
633
705
  function regenerateGeneratedNavigationSurface(source, kind) {
634
706
  const routerLocationSuffix = rewriteRouterLocationSuffix(source);
635
- const anchors = rewriteInternalAnchors(routerLocationSuffix.source);
636
- const locationAssignments = rewriteWindowLocationAssignments(anchors.source);
637
- const forms = 'demo-component' === kind ? rewriteJsxElementName(locationAssignments.source, 'form', 'Form') : {
707
+ const anchors = 'checkout-page' === kind ? rewriteCrossRemoteTractorsLink(routerLocationSuffix.source) : rewriteInternalAnchors(routerLocationSuffix.source);
708
+ const cartLink = 'checkout-add-to-cart' === kind ? rewriteCheckoutCartLink(anchors.source) : {
709
+ changed: false,
710
+ source: anchors.source
711
+ };
712
+ const locationAssignments = rewriteWindowLocationAssignments(cartLink.source);
713
+ const forms = 'demo-component' === kind || 'checkout-page' === kind ? rewriteJsxElementName(locationAssignments.source, 'form', 'Form') : {
638
714
  changed: false,
639
715
  source: locationAssignments.source
640
716
  };
641
- let next = forms.source;
642
- if (anchors.changed || locationAssignments.changed || forms.changed) {
717
+ const noProps = 'checkout-page' === kind ? ensureNoPropsComponentContract(forms.source) : {
718
+ changed: false,
719
+ source: forms.source
720
+ };
721
+ let next = noProps.source;
722
+ const usesLink = next.includes('<Link');
723
+ if (forms.changed || anchors.changed && usesLink || locationAssignments.changed) {
643
724
  const imports = [
644
725
  ...forms.changed ? [
645
726
  'Form'
646
727
  ] : [],
647
- ...anchors.changed ? [
728
+ ...anchors.changed && usesLink ? [
648
729
  'Link'
649
730
  ] : [],
650
731
  ...locationAssignments.changed ? [
@@ -653,6 +734,7 @@ function regenerateGeneratedNavigationSurface(source, kind) {
653
734
  ];
654
735
  next = ensureNamedImport(next, tanstackRuntimeModule, imports);
655
736
  }
737
+ if (!usesLink) next = removeNamedImport(next, tanstackRuntimeModule, 'Link');
656
738
  if (locationAssignments.changed) next = ensureNavigateHook(next);
657
739
  return next;
658
740
  }
@@ -666,6 +748,7 @@ exports.createShellPage = __webpack_exports__.createShellPage;
666
748
  exports.createShellRemoteComponents = __webpack_exports__.createShellRemoteComponents;
667
749
  exports.createShellWorkerRemoteComponents = __webpack_exports__.createShellWorkerRemoteComponents;
668
750
  exports.regenerateGeneratedNavigationSurface = __webpack_exports__.regenerateGeneratedNavigationSurface;
751
+ exports.regenerateGeneratedProductRouteAdapter = __webpack_exports__.regenerateGeneratedProductRouteAdapter;
669
752
  exports.remoteComponentOutputPath = __webpack_exports__.remoteComponentOutputPath;
670
753
  for(var __rspack_i in __webpack_exports__)if (-1 === [
671
754
  "createFederatedComponentsRegistry",
@@ -678,6 +761,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
678
761
  "createShellRemoteComponents",
679
762
  "createShellWorkerRemoteComponents",
680
763
  "regenerateGeneratedNavigationSurface",
764
+ "regenerateGeneratedProductRouteAdapter",
681
765
  "remoteComponentOutputPath"
682
766
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
683
767
  Object.defineProperty(exports, '__esModule', {
@@ -28,7 +28,10 @@ var __webpack_require__ = {};
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  const moduleFederationConfigFile = 'module-federation.config.ts';
31
- const mfTypesArchive = 'dist/@mf-types.zip';
31
+ const mfTypesArchives = {
32
+ cloudflare: 'dist-cloudflare/@mf-types.zip',
33
+ node: 'dist/@mf-types.zip'
34
+ };
32
35
  const generatedMetadataPaths = [
33
36
  '.modernjs/ultramodern.json'
34
37
  ];
@@ -48,19 +51,19 @@ const skippedScanDirs = new Set([
48
51
  __webpack_require__.d(__webpack_exports__, {}, {
49
52
  defaultAppRootDirs: defaultAppRootDirs,
50
53
  generatedMetadataPaths: generatedMetadataPaths,
51
- mfTypesArchive: mfTypesArchive,
54
+ mfTypesArchives: mfTypesArchives,
52
55
  moduleFederationConfigFile: moduleFederationConfigFile,
53
56
  skippedScanDirs: skippedScanDirs
54
57
  });
55
58
  exports.defaultAppRootDirs = __webpack_exports__.defaultAppRootDirs;
56
59
  exports.generatedMetadataPaths = __webpack_exports__.generatedMetadataPaths;
57
- exports.mfTypesArchive = __webpack_exports__.mfTypesArchive;
60
+ exports.mfTypesArchives = __webpack_exports__.mfTypesArchives;
58
61
  exports.moduleFederationConfigFile = __webpack_exports__.moduleFederationConfigFile;
59
62
  exports.skippedScanDirs = __webpack_exports__.skippedScanDirs;
60
63
  for(var __rspack_i in __webpack_exports__)if (-1 === [
61
64
  "defaultAppRootDirs",
62
65
  "generatedMetadataPaths",
63
- "mfTypesArchive",
66
+ "mfTypesArchives",
64
67
  "moduleFederationConfigFile",
65
68
  "skippedScanDirs"
66
69
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -53,8 +53,8 @@ function assertExposedAppDtsSettings(app) {
53
53
  if ('effect-tsgo' !== app.dts.compilerInstance) throw new Error(`Module Federation DTS compilerInstance must resolve "@effect/tsgo" for ${app.appDir}.`);
54
54
  if ('./tsconfig.mf-types.json' !== app.dts.tsConfigPath) throw new Error(`Module Federation DTS tsConfigPath must be "./tsconfig.mf-types.json" for ${app.appDir}.`);
55
55
  }
56
- function assertTypesArchive(workspaceRoot, appDir) {
57
- const typesArchivePath = external_node_path_default().join(workspaceRoot, appDir, external_constants_cjs_namespaceObject.mfTypesArchive);
56
+ function assertTypesArchive(workspaceRoot, appDir, target = 'node') {
57
+ const typesArchivePath = external_node_path_default().join(workspaceRoot, appDir, external_constants_cjs_namespaceObject.mfTypesArchives[target]);
58
58
  if (!external_node_fs_default().existsSync(typesArchivePath)) throw new Error(`Missing Module Federation DTS archive: ${(0, external_path_utils_cjs_namespaceObject.relativePath)(workspaceRoot, typesArchivePath)}`);
59
59
  if (0 === external_node_fs_default().statSync(typesArchivePath).size) throw new Error(`Empty Module Federation DTS archive: ${(0, external_path_utils_cjs_namespaceObject.relativePath)(workspaceRoot, typesArchivePath)}`);
60
60
  }
@@ -88,7 +88,7 @@ function validateModuleFederationTypes(options) {
88
88
  continue;
89
89
  }
90
90
  assertExposedAppDtsSettings(app);
91
- assertTypesArchive(workspaceRoot, app.appDir);
91
+ assertTypesArchive(workspaceRoot, app.appDir, options.target);
92
92
  exposedAppCount += 1;
93
93
  }
94
94
  if (apps.length > 0 && 0 === exposedAppCount && hostOnlyAppCount !== apps.length) throw new Error('Module Federation validation inspected configs but validated zero exposed apps. Declare host-only/no-exposes intent only for host apps without exposes.');
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  createJsonLdHelperModule: ()=>createJsonLdHelperModule,
32
32
  createLocalisedUrlsMap: ()=>createLocalisedUrlsMap,
33
+ createLocalisedUrlsMapFromRoutes: ()=>createLocalisedUrlsMapFromRoutes,
33
34
  createPublicRouteMetadata: ()=>createPublicRouteMetadata,
34
35
  createPublicRouteMetadataFromRoutes: ()=>createPublicRouteMetadataFromRoutes,
35
36
  createRouteAliasPage: ()=>createRouteAliasPage,
@@ -90,16 +91,10 @@ function isPublicIndexableRoute(route) {
90
91
  return route.public && route.indexable;
91
92
  }
92
93
  function createLocalisedUrlsMapFromRoutes(routes) {
93
- return Object.fromEntries(routes.flatMap((route)=>{
94
- if ('/' === route.canonicalPath) return [];
95
- return Array.from(new Set([
94
+ return Object.fromEntries(routes.filter((route)=>'/' !== route.canonicalPath).map((route)=>[
96
95
  route.canonicalPath,
97
- ...Object.values(route.localisedPaths)
98
- ])).map((pathname)=>[
99
- pathname,
100
- route.localisedPaths
101
- ]);
102
- }));
96
+ route.localisedPaths
97
+ ]));
103
98
  }
104
99
  function createLocalisedUrlsMap(app) {
105
100
  return createLocalisedUrlsMapFromRoutes(createRouteOwnedI18nPaths(app));
@@ -191,6 +186,7 @@ function createRouteAliasPage(canonicalPath) {
191
186
  }
192
187
  exports.createJsonLdHelperModule = __webpack_exports__.createJsonLdHelperModule;
193
188
  exports.createLocalisedUrlsMap = __webpack_exports__.createLocalisedUrlsMap;
189
+ exports.createLocalisedUrlsMapFromRoutes = __webpack_exports__.createLocalisedUrlsMapFromRoutes;
194
190
  exports.createPublicRouteMetadata = __webpack_exports__.createPublicRouteMetadata;
195
191
  exports.createPublicRouteMetadataFromRoutes = __webpack_exports__.createPublicRouteMetadataFromRoutes;
196
192
  exports.createRouteAliasPage = __webpack_exports__.createRouteAliasPage;
@@ -207,6 +203,7 @@ exports.splitPublicPathSegments = __webpack_exports__.splitPublicPathSegments;
207
203
  for(var __rspack_i in __webpack_exports__)if (-1 === [
208
204
  "createJsonLdHelperModule",
209
205
  "createLocalisedUrlsMap",
206
+ "createLocalisedUrlsMapFromRoutes",
210
207
  "createPublicRouteMetadata",
211
208
  "createPublicRouteMetadataFromRoutes",
212
209
  "createRouteAliasPage",
@@ -131,6 +131,9 @@ function createPackageTsConfig(packageDir, options = {}) {
131
131
  emitDeclarationOnly: true,
132
132
  incremental: true,
133
133
  noEmit: false,
134
+ ...resolvedOptions.skipLibCheck ? {
135
+ skipLibCheck: true
136
+ } : {},
134
137
  outDir: createTsDeclarationOutDir(packageDir),
135
138
  tsBuildInfoFile: createTsBuildInfoFile(packageDir)
136
139
  },
@@ -140,14 +143,16 @@ function createPackageTsConfig(packageDir, options = {}) {
140
143
  return tsconfig;
141
144
  }
142
145
  function createAppTsConfig(app, remotes = []) {
146
+ const remoteRefs = 'shell' === app.kind ? [] : (0, external_descriptors_cjs_namespaceObject.resolveRemoteRefs)(app, remotes);
143
147
  const references = [
144
148
  ...external_descriptors_cjs_namespaceObject.sharedPackages.map((sharedPackage)=>sharedPackage.directory),
145
- ...'shell' === app.kind ? [] : (0, external_descriptors_cjs_namespaceObject.resolveRemoteRefs)(app, remotes).map((remote)=>remote.directory)
149
+ ...remoteRefs.map((remote)=>remote.directory)
146
150
  ];
147
151
  return createPackageTsConfig(app.directory, {
148
152
  includeApi: (0, external_descriptors_cjs_namespaceObject.appHasApi)(app),
149
153
  includeServer: true,
150
- references
154
+ references,
155
+ skipLibCheck: remoteRefs.length > 0
151
156
  });
152
157
  }
153
158
  function createAppMfTypesTsConfig(app) {
@@ -159,7 +164,10 @@ function createAppMfTypesTsConfig(app) {
159
164
  ...exposedFiles,
160
165
  'src/modern-app-env.d.ts'
161
166
  ])
162
- ]
167
+ ],
168
+ compilerOptions: {
169
+ skipLibCheck: true
170
+ }
163
171
  };
164
172
  }
165
173
  function createSharedPackageTsConfig(packageDir) {
@@ -114,6 +114,29 @@ function createWorkspaceAppPackageScripts(app) {
114
114
  plan[planKey]
115
115
  ]));
116
116
  }
117
+ function createReferencedRemoteDeclarationBuilds(remotes) {
118
+ const remotesById = new Map(remotes.map((remote)=>[
119
+ remote.id,
120
+ remote
121
+ ]));
122
+ const referencedRemoteIds = new Set(remotes.flatMap((remote)=>remote.verticalRefs ?? []));
123
+ const orderedRemotes = [];
124
+ const visiting = new Set();
125
+ const visited = new Set();
126
+ const visit = (remote)=>{
127
+ if (visited.has(remote.id) || visiting.has(remote.id)) return;
128
+ visiting.add(remote.id);
129
+ for (const dependencyId of remote.verticalRefs ?? []){
130
+ const dependency = remotesById.get(dependencyId);
131
+ if (void 0 !== dependency) visit(dependency);
132
+ }
133
+ visiting.delete(remote.id);
134
+ visited.add(remote.id);
135
+ orderedRemotes.push(remote);
136
+ };
137
+ for (const remote of remotes)if (referencedRemoteIds.has(remote.id)) visit(remote);
138
+ return orderedRemotes.map((remote)=>`${rootToolingWrapperCommand('typecheck')} --emit --project ${remote.directory}/tsconfig.json --skipLibCheck`).join(' && ');
139
+ }
117
140
  function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
118
141
  const hasRemotes = remotes.length > 0;
119
142
  remotes.some(external_descriptors_cjs_namespaceObject.appHasApi);
@@ -127,13 +150,20 @@ function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
127
150
  const performanceReadinessScript = rootToolingScriptName('performanceReadiness');
128
151
  const cloudflareOutputVerifyScript = rootToolingScriptName('cloudflareOutputVerify');
129
152
  const bridgeCheck = options.bridgeCheck ?? '';
153
+ const sharedDeclarationsBuild = external_descriptors_cjs_namespaceObject.sharedPackages.map((sharedPackage)=>`${rootToolingWrapperCommand('typecheck')} --build ${sharedPackage.directory}/tsconfig.json`).join(' && ');
154
+ const referencedRemoteDeclarationsBuild = createReferencedRemoteDeclarationBuilds(remotes);
155
+ const declarationBuild = [
156
+ sharedDeclarationsBuild,
157
+ referencedRemoteDeclarationsBuild
158
+ ].filter(Boolean).join(' && ');
159
+ const buildPrefix = `${declarationBuild} && `;
130
160
  const remoteBuildPrefix = hasRemotes ? 'pnpm -r --filter "./verticals/*" run build && ' : '';
131
161
  const remoteCloudflareBuildPrefix = hasRemotes ? 'pnpm -r --filter "./verticals/*" run cloudflare:build && ' : '';
132
162
  const remoteCloudflareDeployPrefix = hasRemotes ? 'pnpm -r --filter "./verticals/*" run cloudflare:deploy && ' : '';
133
163
  const cloudflareSsrProofSuffix = hasRemotes ? ' && pnpm cloudflare:ssr-proof' : '';
134
164
  return {
135
- build: `${remoteBuildPrefix}${shellBuild} && pnpm ${mfTypesScript} && pnpm ${performanceReadinessScript}`,
136
- cloudflareBuild: `${remoteCloudflareBuildPrefix}${shellCloudflareBuild} && pnpm ${mfTypesScript} && pnpm ${cloudflareOutputVerifyScript}${cloudflareSsrProofSuffix}`,
165
+ build: `${buildPrefix}${remoteBuildPrefix}${shellBuild} && pnpm ${mfTypesScript} && pnpm ${performanceReadinessScript}`,
166
+ cloudflareBuild: `${buildPrefix}${remoteCloudflareBuildPrefix}${shellCloudflareBuild} && pnpm ${mfTypesScript} --target cloudflare && pnpm ${cloudflareOutputVerifyScript}${cloudflareSsrProofSuffix}`,
137
167
  cloudflareDeploy: `${remoteCloudflareDeployPrefix}${shellCloudflareDeploy}`,
138
168
  cloudflareProof: `${rootToolingWrapperCommand('cloudflareProof')} --out .codex/reports/cloudflare-version-proof/public-url-proof.json`,
139
169
  cloudflareSsrProof: "node ./scripts/proof-workerd-ssr.mts",
@@ -1,16 +1,42 @@
1
1
  import { validateModuleFederationTypes } from "../../ultramodern-workspace/mf-validation.js";
2
+ function parseMfTypesArgs(args) {
3
+ const appDirs = [];
4
+ let target = 'node';
5
+ for(let index = 0; index < args.length; index += 1){
6
+ const arg = args[index];
7
+ if (void 0 === arg || '--' === arg) continue;
8
+ let targetValue;
9
+ if ('--target' === arg) {
10
+ targetValue = args[index + 1];
11
+ if (void 0 === targetValue || targetValue.startsWith('-')) throw new Error('--target needs a value.');
12
+ index += 1;
13
+ } else if (arg.startsWith('--target=')) targetValue = arg.slice(9);
14
+ else if (arg.startsWith('-')) throw new Error(`Unknown mf-types option: ${arg}`);
15
+ else appDirs.push(arg);
16
+ if (void 0 !== targetValue) {
17
+ if ('node' !== targetValue && 'cloudflare' !== targetValue) throw new Error(`Invalid mf-types target "${targetValue}". Expected "node" or "cloudflare".`);
18
+ target = targetValue;
19
+ }
20
+ }
21
+ return {
22
+ appDirs,
23
+ target
24
+ };
25
+ }
2
26
  function runMfTypes(args, context) {
3
27
  if (args.includes('--help') || args.includes('-h')) {
4
28
  process.stdout.write(`Usage:
5
- ultramodern-create ultramodern mf-types [app-dir...]
29
+ ultramodern-create ultramodern mf-types [--target node|cloudflare] [app-dir...]
6
30
 
7
- Checks real Module Federation config files and DTS archives for exposed apps.
31
+ Checks real Module Federation config files and target-specific DTS archives for exposed apps.
8
32
  `);
9
33
  return 0;
10
34
  }
35
+ const { appDirs, target } = parseMfTypesArgs(args);
11
36
  validateModuleFederationTypes({
12
37
  workspaceRoot: context.workspaceRoot,
13
- appDirs: args.length > 0 ? args : void 0
38
+ appDirs: appDirs.length > 0 ? appDirs : void 0,
39
+ target
14
40
  });
15
41
  return 0;
16
42
  }
@@ -62,6 +62,9 @@ function removeTsCheckerBuildOverride(source) {
62
62
  },
63
63
  `, '');
64
64
  }
65
+ function removeReleaseEnvelopePlugin(source) {
66
+ return source.replace(' ultramodernReleaseEnvelopePlugin,\n', '').replace(' ultramodernReleaseEnvelopePlugin(),\n', '');
67
+ }
65
68
  function updateGeneratedModernConfigs(io, config) {
66
69
  const apps = allWorkspaceAppsFromToolingConfig(config);
67
70
  const remotes = apps.filter((app)=>'shell' !== app.kind);
@@ -88,10 +91,15 @@ function updateGeneratedModernConfigs(io, config) {
88
91
  previousTailwindModernConfig,
89
92
  addLegacyGeneratedModernDefaults(previousTailwindModernConfig)
90
93
  ];
91
- const [generatedModernConfig, ...recognizedGeneratedModernConfigs] = formatGeneratedModernConfigCandidates(currentGeneratedModernConfigs.flatMap((source)=>[
94
+ const [generatedModernConfig, ...recognizedGeneratedModernConfigs] = formatGeneratedModernConfigCandidates(currentGeneratedModernConfigs.flatMap((source)=>{
95
+ const withoutReleaseEnvelope = removeReleaseEnvelopePlugin(source);
96
+ return [
92
97
  source,
93
- removeTsCheckerBuildOverride(source)
94
- ]));
98
+ removeTsCheckerBuildOverride(source),
99
+ withoutReleaseEnvelope,
100
+ removeTsCheckerBuildOverride(withoutReleaseEnvelope)
101
+ ];
102
+ }));
95
103
  if (node_fs.existsSync(modernConfigPath)) {
96
104
  const existingModernConfig = node_fs.readFileSync(modernConfigPath, 'utf-8');
97
105
  if (existingModernConfig === generatedModernConfig) io.writeGenerated(modernConfigPath, existingModernConfig);