@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.2 → 3.9.0-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 (93) hide show
  1. package/dist/cjs/ultramodern-package-source.cjs +2 -1
  2. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.cjs +5 -2
  3. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.cjs +5 -0
  4. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +1 -0
  5. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +30 -9
  6. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.cjs +9 -13
  7. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.cjs +30 -7
  8. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.cjs +99 -0
  9. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +14 -5
  10. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.cjs +215 -0
  11. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +72 -8
  12. package/dist/cjs/ultramodern-workspace/api/client.cjs +2 -2
  13. package/dist/cjs/ultramodern-workspace/api/service.cjs +45 -16
  14. package/dist/cjs/ultramodern-workspace/api/shared.cjs +26 -16
  15. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +6 -2
  16. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +18 -51
  17. package/dist/cjs/ultramodern-workspace/package-json.cjs +13 -1
  18. package/dist/cjs/ultramodern-workspace/policy.cjs +1 -0
  19. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +3 -0
  20. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +1 -1
  21. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +5 -0
  22. package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +2 -1
  23. package/dist/cjs/ultramodern-workspace/write-app.cjs +10 -4
  24. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +5 -3
  25. package/dist/esm/ultramodern-package-source.js +2 -1
  26. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  27. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  28. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  29. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +30 -9
  30. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  31. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  32. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +50 -0
  33. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +14 -5
  34. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +166 -0
  35. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +73 -9
  36. package/dist/esm/ultramodern-workspace/api/client.js +2 -2
  37. package/dist/esm/ultramodern-workspace/api/service.js +45 -16
  38. package/dist/esm/ultramodern-workspace/api/shared.js +27 -17
  39. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +6 -2
  40. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +18 -51
  41. package/dist/esm/ultramodern-workspace/package-json.js +13 -1
  42. package/dist/esm/ultramodern-workspace/policy.js +1 -0
  43. package/dist/esm/ultramodern-workspace/tsconfigs.js +3 -0
  44. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +1 -1
  45. package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -0
  46. package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +2 -1
  47. package/dist/esm/ultramodern-workspace/write-app.js +10 -4
  48. package/dist/esm/ultramodern-workspace/write-workspace.js +6 -4
  49. package/dist/esm-node/ultramodern-package-source.js +2 -1
  50. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  51. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  52. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  53. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +30 -9
  54. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  55. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  56. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +51 -0
  57. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +14 -5
  58. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +167 -0
  59. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +73 -9
  60. package/dist/esm-node/ultramodern-workspace/api/client.js +2 -2
  61. package/dist/esm-node/ultramodern-workspace/api/service.js +45 -16
  62. package/dist/esm-node/ultramodern-workspace/api/shared.js +27 -17
  63. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +6 -2
  64. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +18 -51
  65. package/dist/esm-node/ultramodern-workspace/package-json.js +13 -1
  66. package/dist/esm-node/ultramodern-workspace/policy.js +1 -0
  67. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +3 -0
  68. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +1 -1
  69. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -0
  70. package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +2 -1
  71. package/dist/esm-node/ultramodern-workspace/write-app.js +10 -4
  72. package/dist/esm-node/ultramodern-workspace/write-workspace.js +6 -4
  73. package/dist/types/ultramodern-package-source.d.ts +1 -1
  74. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.d.ts +3 -1
  75. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.d.ts +7 -0
  76. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts +4 -0
  77. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.d.ts +27 -0
  78. package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
  79. package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
  80. package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
  81. package/dist/types/ultramodern-workspace/module-federation/reexport-module.d.ts +2 -2
  82. package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
  83. package/dist/types/ultramodern-workspace/policy.d.ts +2 -0
  84. package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +1 -1
  85. package/package.json +5 -4
  86. package/template-workspace/.modernjs/release-cohort.json +40 -40
  87. package/template-workspace/scripts/bootstrap-agent-skills.mjs +4 -4
  88. package/templates/packages/effect-bff-runtime.ts +50 -0
  89. package/templates/packages/microvertical-api-baseline.ts +102 -0
  90. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +49 -28
  91. package/templates/workspace-scripts/microvertical-api-baseline-boundary.mts +944 -0
  92. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
  93. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +1 -1
@@ -34,6 +34,7 @@ __webpack_require__.d(__webpack_exports__, {
34
34
  });
35
35
  const universal_namespaceObject = require("@modern-js/utils/universal");
36
36
  const external_delivery_unit_cjs_namespaceObject = require("../delivery-unit.cjs");
37
+ const external_descriptors_cjs_namespaceObject = require("../descriptors.cjs");
37
38
  function deliveryUnitRecordFor(scope, app) {
38
39
  return app.deliveryUnit ? app.deliveryUnit : (0, external_delivery_unit_cjs_namespaceObject.createDeliveryUnitRecord)(scope, app);
39
40
  }
@@ -41,62 +42,28 @@ function createUltramodernBuildArtifactJson(scope, app) {
41
42
  const record = deliveryUnitRecordFor(scope, app);
42
43
  return `${JSON.stringify((0, universal_namespaceObject.createUltramodernBuildArtifact)(record), null, 2)}\n`;
43
44
  }
44
- function createUltramodernBuildModule(scope, app) {
45
+ function createUltramodernBuildModule(scope, app, includeUiMarker = (0, external_descriptors_cjs_namespaceObject.appEmitsBrowserUi)(app)) {
45
46
  const record = deliveryUnitRecordFor(scope, app);
46
- return `declare const ULTRAMODERN_BUILD_MARKER: string;
47
- declare const ULTRAMODERN_SOURCE_REVISION: string;
47
+ return `import { resolveUltramodernBuildArtifact } from '@modern-js/runtime-extensions/build-identity';
48
48
 
49
- const ultramodernGeneratedBuildArtifact = ${JSON.stringify((0, universal_namespaceObject.createUltramodernBuildArtifact)(record), null, 2)} as const;
50
- const ultramodernBuildMarker =
51
- typeof ULTRAMODERN_BUILD_MARKER === 'string'
52
- ? ULTRAMODERN_BUILD_MARKER
53
- : ultramodernGeneratedBuildArtifact.deliveryUnit.buildMarker;
54
- const ultramodernSourceRevision =
55
- typeof ULTRAMODERN_SOURCE_REVISION === 'string'
56
- ? ULTRAMODERN_SOURCE_REVISION
57
- : ultramodernGeneratedBuildArtifact.deliveryUnit.sourceRevision;
58
- const ultramodernBuildArtifact = {
59
- ...ultramodernGeneratedBuildArtifact,
60
- deliveryUnit: {
61
- ...ultramodernGeneratedBuildArtifact.deliveryUnit,
62
- build: ultramodernBuildMarker,
63
- buildMarker: ultramodernBuildMarker,
64
- sourceRevision: ultramodernSourceRevision,
65
- },
66
- surfaces: {
67
- api: {
68
- ...ultramodernGeneratedBuildArtifact.surfaces.api,
69
- build: ultramodernBuildMarker,
70
- buildMarker: ultramodernBuildMarker,
71
- sourceRevision: ultramodernSourceRevision,
72
- },
73
- ui: {
74
- ...ultramodernGeneratedBuildArtifact.surfaces.ui,
75
- build: ultramodernBuildMarker,
76
- buildMarker: ultramodernBuildMarker,
77
- sourceRevision: ultramodernSourceRevision,
78
- },
79
- },
80
- } as const;
49
+ declare const ULTRAMODERN_BUILD_MARKER: string;
50
+ declare const ULTRAMODERN_SOURCE_REVISION: string;
81
51
 
82
- export { ultramodernBuildArtifact };
52
+ const ultramodernBuildArtifact = resolveUltramodernBuildArtifact(${JSON.stringify((0, universal_namespaceObject.createUltramodernBuildArtifact)(record), null, 2)} as const, {
53
+ buildMarker: () => ULTRAMODERN_BUILD_MARKER,
54
+ sourceRevision: () => ULTRAMODERN_SOURCE_REVISION,
55
+ });
83
56
 
84
- export const ultramodernDeliveryUnit =
85
- ultramodernBuildArtifact.deliveryUnit;
86
- export const ultramodernVerticalIdentity = ultramodernDeliveryUnit;
87
- export const ultramodernUiMarker = ultramodernBuildArtifact.surfaces.ui;
88
- export const ultramodernApiMarker = ultramodernBuildArtifact.surfaces.api;
89
- `;
57
+ export const ultramodernDeliveryUnit = ultramodernBuildArtifact.deliveryUnit;
58
+ ${includeUiMarker ? 'export const ultramodernUiMarker = ultramodernBuildArtifact.surfaces.ui;\n' : ''}${'shell' !== app.kind && (0, external_descriptors_cjs_namespaceObject.appHasApi)(app) ? 'export const ultramodernApiMarker = ultramodernBuildArtifact.surfaces.api;\n' : ''}`;
90
59
  }
91
- function createUltramodernBuildReexportModule() {
92
- return `export {
93
- ultramodernBuildArtifact,
94
- ultramodernApiMarker,
95
- ultramodernDeliveryUnit,
96
- ultramodernUiMarker,
97
- ultramodernVerticalIdentity,
98
- } from '../shared/ultramodern-build';
99
- `;
60
+ function createUltramodernBuildReexportModule(app, includeUiMarker = (0, external_descriptors_cjs_namespaceObject.appEmitsBrowserUi)(app)) {
61
+ const names = [
62
+ 'ultramodernDeliveryUnit'
63
+ ];
64
+ if (includeUiMarker) names.push('ultramodernUiMarker');
65
+ if ('shell' !== app.kind && (0, external_descriptors_cjs_namespaceObject.appHasApi)(app)) names.push('ultramodernApiMarker');
66
+ return `export { ${names.join(', ')} } from '../shared/ultramodern-build';\n`;
100
67
  }
101
68
  exports.createUltramodernBuildArtifactJson = __webpack_exports__.createUltramodernBuildArtifactJson;
102
69
  exports.createUltramodernBuildModule = __webpack_exports__.createUltramodernBuildModule;
@@ -51,6 +51,7 @@ function appDependencies(scope, packageSource, app, remotes = [], bridge) {
51
51
  const dependencies = {
52
52
  '@modern-js/plugin-tanstack': (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/plugin-tanstack', packageSource),
53
53
  '@modern-js/plugin-i18n': (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/plugin-i18n', packageSource),
54
+ '@modern-js/runtime-extensions': (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/runtime-extensions', packageSource),
54
55
  '@modern-js/runtime': (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/runtime', packageSource),
55
56
  ...external_policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.appDependencies,
56
57
  [(0, external_naming_cjs_namespaceObject.packageName)(scope, 'shared-contracts')]: external_ultramodern_package_source_cjs_namespaceObject.WORKSPACE_PACKAGE_VERSION,
@@ -214,7 +215,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
214
215
  if (Object.keys(packageExports).length > 0) packageJson.exports = packageExports;
215
216
  return packageJson;
216
217
  }
217
- function createSharedPackage(scope, id, description) {
218
+ function createSharedPackage(scope, id, description, packageSource) {
218
219
  const packageJson = {
219
220
  private: true,
220
221
  name: (0, external_naming_cjs_namespaceObject.packageName)(scope, id),
@@ -231,6 +232,17 @@ function createSharedPackage(scope, id, description) {
231
232
  '@effect/tsgo': external_policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.appDevDependencies["@effect/tsgo"]
232
233
  }
233
234
  };
235
+ if ('shared-contracts' === id) {
236
+ packageJson.exports = {
237
+ '.': './src/index.ts',
238
+ './microvertical-api-baseline': './src/microvertical-api-baseline.ts',
239
+ './server/effect-bff-runtime': './src/effect-bff-runtime.ts'
240
+ };
241
+ packageJson.dependencies = {
242
+ ...external_policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.bffEffectDependencies,
243
+ '@modern-js/plugin-bff': packageSource ? (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/plugin-bff', packageSource) : external_ultramodern_package_source_cjs_namespaceObject.WORKSPACE_PACKAGE_VERSION
244
+ };
245
+ }
234
246
  if ('shared-design-tokens' === id) packageJson.exports = {
235
247
  ...packageJson.exports,
236
248
  './tokens.css': './src/tokens.css'
@@ -290,6 +290,7 @@ const ULTRAMODERN_PACKAGE_PINS = {
290
290
  rootDevDependencies: {
291
291
  '@effect/tsgo': external_versions_cjs_namespaceObject.EFFECT_TSGO_VERSION,
292
292
  "@typescript/native": `npm:typescript@${external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION}`,
293
+ '@types/node': external_versions_cjs_namespaceObject.TYPES_NODE_VERSION,
293
294
  'cross-env': external_versions_cjs_namespaceObject.CROSS_ENV_VERSION,
294
295
  lefthook: external_versions_cjs_namespaceObject.LEFTHOOK_VERSION,
295
296
  miniflare: external_versions_cjs_namespaceObject.MINIFLARE_VERSION,
@@ -53,6 +53,9 @@ function createTsConfigBase() {
53
53
  return {
54
54
  compilerOptions: {
55
55
  target: 'ESNext',
56
+ types: [
57
+ 'node'
58
+ ],
56
59
  lib: [
57
60
  'ESNext',
58
61
  'DOM',
@@ -175,7 +175,7 @@ function createWorkspaceRootScriptPlan(remotes = [], options = {}) {
175
175
  migrateStrictEffect: rootToolingWrapperCommand('migrateStrictEffect'),
176
176
  zeropsMaterialize: "node ./scripts/materialize-zerops-runtime.mjs",
177
177
  contractCheck: rootToolingWrapperCommand('validate'),
178
- typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --project tsconfig.json`,
178
+ typecheck: options.typecheck ?? `${rootToolingWrapperCommand('typecheck')} --build tsconfig.json`,
179
179
  check: `pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm api:check && pnpm contract:check && pnpm performance:readiness${bridgeCheck}`
180
180
  };
181
181
  }
@@ -176,6 +176,7 @@ function writeGeneratedWorkspaceScripts(targetDir, scope, enableTailwind, remote
176
176
  const hasBackendSurface = remotes.some(external_descriptors_cjs_namespaceObject.appHasApi);
177
177
  writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-i18n-boundaries', createWorkspaceI18nBoundaryValidationScript());
178
178
  writeWorkspaceOwnedMtsScript(targetDir, 'check-ultramodern-api-boundaries', createWorkspaceApiBoundaryValidationScript());
179
+ writeWorkspaceOwnedMtsScript(targetDir, 'microvertical-api-baseline-boundary', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/microvertical-api-baseline-boundary.mts"));
179
180
  if (!shellOnly) {
180
181
  (0, external_fs_io_cjs_namespaceObject.writeFileReplacing)(targetDir, "scripts/materialize-zerops-runtime.mjs", createZeropsRuntimeMaterializationScript());
181
182
  writeWorkspaceOwnedMtsScript(targetDir, 'proof-workerd-ssr', createWorkerdSsrProofScript());
@@ -203,6 +204,10 @@ function migratedWorkspaceScriptArtifacts(options) {
203
204
  content: createWorkspaceI18nBoundaryValidationScript(),
204
205
  legacyPath: "scripts/check-ultramodern-i18n-boundaries.mjs"
205
206
  },
207
+ {
208
+ relativePath: "scripts/microvertical-api-baseline-boundary.mts",
209
+ content: (0, external_fs_io_cjs_namespaceObject.readFileTemplate)("workspace-scripts/microvertical-api-baseline-boundary.mts")
210
+ },
206
211
  {
207
212
  relativePath: "scripts/check-ultramodern-api-boundaries.mts",
208
213
  content: createWorkspaceApiBoundaryValidationScript(),
@@ -55,7 +55,8 @@ const modernPackageCohort = [
55
55
  '@modern-js/plugin-bff',
56
56
  '@modern-js/plugin-i18n',
57
57
  '@modern-js/plugin-tanstack',
58
- '@modern-js/runtime'
58
+ '@modern-js/runtime',
59
+ '@modern-js/runtime-extensions'
59
60
  ];
60
61
  const asJsonRecord = (value)=>value;
61
62
  function projectModuleFederationMetadata(value) {
@@ -78,7 +78,7 @@ function writeAppConfigFiles({ targetDir, scope, resolvedApp, packageSource, ena
78
78
  (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/tsconfig.json`, (0, external_package_json_cjs_namespaceObject.createAppTsConfig)(resolvedApp, remotes));
79
79
  (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${resolvedApp.directory}/tsconfig.mf-types.json`, (0, external_package_json_cjs_namespaceObject.createAppMfTypesTsConfig)(resolvedApp));
80
80
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/modern-app-env.d.ts`, (0, external_app_files_cjs_namespaceObject.createAppEnvDts)(resolvedApp, remotes, scope));
81
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildReexportModule)());
81
+ if ('api-only' !== resolvedApp.surfaceProfile) (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildReexportModule)(resolvedApp));
82
82
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/ultramodern-build.ts`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildModule)(scope, resolvedApp));
83
83
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/ultramodern-build.json`, (0, external_module_federation_cjs_namespaceObject.createUltramodernBuildArtifactJson)(scope, resolvedApp));
84
84
  if (emitsUi) {
@@ -122,12 +122,18 @@ function writeAppApiAndRemoteExposeFiles({ targetDir, scope, resolvedApp, emitsU
122
122
  if ((0, external_descriptors_cjs_namespaceObject.appHasApi)(resolvedApp)) {
123
123
  const rpcProtocol = 'rpc' === (0, external_descriptors_cjs_namespaceObject.resolveApiProtocol)(resolvedApp);
124
124
  if (rpcProtocol) (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/rpc.ts`, (0, rpc_cjs_namespaceObject.createRpcContractFile)(resolvedApp));
125
- else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_api_cjs_namespaceObject.createSharedApi)(resolvedApp));
126
- (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_api_cjs_namespaceObject.createApiServiceEntry)(resolvedApp, rpcProtocol ? '../shared/rpc.ts' : '../shared/api.ts'));
125
+ else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/shared/api.ts`, (0, external_api_cjs_namespaceObject.createSharedApi)(resolvedApp, {
126
+ scope
127
+ }));
128
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/index.ts`, (0, external_api_cjs_namespaceObject.createApiServiceEntry)(resolvedApp, rpcProtocol ? '../shared/rpc.ts' : '../shared/api.ts', {
129
+ scope
130
+ }));
127
131
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/backend-federation.ts`, (0, external_backend_federation_cjs_namespaceObject.createBackendFederationContractFile)(resolvedApp));
128
132
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/api/effect-api.ts`, (0, external_api_cjs_namespaceObject.createBackendEffectApiExpose)(scope, resolvedApp));
129
133
  if (rpcProtocol) (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-rpc-client.ts`, (0, rpc_cjs_namespaceObject.createRpcClientFile)(resolvedApp));
130
- else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, (0, external_api_cjs_namespaceObject.createApiClient)(resolvedApp, '../../shared/api'));
134
+ else (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, `${resolvedApp.directory}/src/api/${resolvedApp.api.stem}-client.ts`, (0, external_api_cjs_namespaceObject.createApiClient)(resolvedApp, '../../shared/api', {
135
+ scope
136
+ }));
131
137
  }
132
138
  if ('vertical' === resolvedApp.kind && emitsUi) {
133
139
  writeAppFile('src/federation-entry.tsx', (0, external_demo_components_cjs_namespaceObject.createRemoteEntry)(resolvedApp));
@@ -63,12 +63,14 @@ const external_zerops_cjs_namespaceObject = require("./zerops.cjs");
63
63
  function hasExplicitInstallRequest(options) {
64
64
  return void 0 !== options.packageSource && 'workspace' !== options.packageSource.strategy;
65
65
  }
66
- function writeSharedPackages(targetDir, scope) {
66
+ function writeSharedPackages(targetDir, scope, packageSource) {
67
67
  for (const sharedPackage of external_descriptors_cjs_namespaceObject.sharedPackages){
68
- (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackage)(scope, sharedPackage.id, sharedPackage.description));
68
+ (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/package.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackage)(scope, sharedPackage.id, sharedPackage.description, packageSource));
69
69
  (0, external_fs_io_cjs_namespaceObject.writeJson)(targetDir, `${sharedPackage.directory}/tsconfig.json`, (0, external_package_json_cjs_namespaceObject.createSharedPackageTsConfig)(sharedPackage.directory));
70
70
  }
71
71
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/index.ts', (0, external_package_json_cjs_namespaceObject.createSharedContractsIndex)());
72
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/microvertical-api-baseline.ts', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)('packages/microvertical-api-baseline.ts'));
73
+ (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-contracts/src/effect-bff-runtime.ts', (0, external_fs_io_cjs_namespaceObject.readFileTemplate)('packages/effect-bff-runtime.ts'));
72
74
  (0, external_fs_io_cjs_namespaceObject.writeFile)(targetDir, 'packages/shared-design-tokens/src/index.ts', `export const sharedDesignTokens = {
73
75
  color: {
74
76
  accent: '#2f8f68',
@@ -188,7 +190,7 @@ function generateUltramodernWorkspaceInPlace(options, logicalWorkspaceRoot = opt
188
190
  (0, external_fs_io_cjs_namespaceObject.writeJson)(options.targetDir, external_descriptors_cjs_namespaceObject.ULTRAMODERN_CONFIG_PATH, createCompactUltramodernConfig(scope, options.modernVersion, packageSource, createdApps, enableTailwind, bridge));
189
191
  (0, external_write_app_cjs_namespaceObject.writeApp)(options.targetDir, scope, external_descriptors_cjs_namespaceObject.shellApp, packageSource, enableTailwind, initialVerticals, bridge);
190
192
  for (const remote of initialVerticals)(0, external_write_app_cjs_namespaceObject.writeApp)(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals, bridge);
191
- writeSharedPackages(options.targetDir, scope);
193
+ writeSharedPackages(options.targetDir, scope, packageSource);
192
194
  (0, external_workspace_scripts_cjs_namespaceObject.writeGeneratedWorkspaceScripts)(options.targetDir, scope, enableTailwind, initialVerticals, releaseCohort);
193
195
  const preliminaryAfterFiles = (0, external_generation_result_cjs_namespaceObject.createFileSnapshot)(options.targetDir);
194
196
  const preliminaryDiff = (0, external_generation_result_cjs_namespaceObject.diffFileSnapshots)(beforeFiles, preliminaryAfterFiles);
@@ -24,7 +24,8 @@ const ULTRAMODERN_WORKSPACE_MODERN_PACKAGES = [
24
24
  '@modern-js/plugin-bff',
25
25
  '@modern-js/plugin-i18n',
26
26
  '@modern-js/plugin-tanstack',
27
- '@modern-js/runtime'
27
+ '@modern-js/runtime',
28
+ '@modern-js/runtime-extensions'
28
29
  ];
29
30
  function modernPackageVersion(packageSource) {
30
31
  return 'install' === packageSource.strategy ? packageSource.modernPackageVersion : WORKSPACE_PACKAGE_VERSION;
@@ -1,5 +1,6 @@
1
1
  import node_fs from "node:fs";
2
2
  import node_path from "node:path";
3
+ import { appEmitsBrowserUi } from "../../../ultramodern-workspace/descriptors.js";
3
4
  import { createUltramodernBuildArtifactJson, createUltramodernBuildModule, createUltramodernBuildReexportModule } from "../../../ultramodern-workspace/module-federation.js";
4
5
  import { allWorkspaceAppsFromToolingConfig } from "../../config.js";
5
6
  const legacyApiMarkerPattern = /export const ultramodernApiMarker\s*=\s*\{[\s\S]*?\}\s+as const;\n?/u;
@@ -39,8 +40,10 @@ function updateGeneratedBuildIdentityModules(io, config) {
39
40
  for (const app of allWorkspaceAppsFromToolingConfig(config)){
40
41
  const sharedApiPath = node_path.join(io.workspaceRoot, app.directory, 'shared/api.ts');
41
42
  if (app.api && node_fs.existsSync(sharedApiPath)) io.write(sharedApiPath, rewriteApiMarkerIdentitySchema(rewriteLegacyApiMarkerBinding(node_fs.readFileSync(sharedApiPath, 'utf-8'))));
42
- io.writeGenerated(node_path.join(io.workspaceRoot, app.directory, 'src/ultramodern-build.ts'), createUltramodernBuildReexportModule());
43
- io.writeGenerated(node_path.join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.ts'), createUltramodernBuildModule(config.workspace.packageScope, app));
43
+ const reexportPath = node_path.join(io.workspaceRoot, app.directory, 'src/ultramodern-build.ts');
44
+ const includeUiMarker = appEmitsBrowserUi(app) && ('shell' !== app.kind || node_fs.existsSync(reexportPath));
45
+ if (node_fs.existsSync(reexportPath)) io.writeGenerated(reexportPath, createUltramodernBuildReexportModule(app, includeUiMarker));
46
+ io.writeGenerated(node_path.join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.ts'), createUltramodernBuildModule(config.workspace.packageScope, app, includeUiMarker));
44
47
  io.write(node_path.join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.json'), createUltramodernBuildArtifactJson(config.workspace.packageScope, app));
45
48
  }
46
49
  }
@@ -117,6 +117,7 @@ function updateGeneratedModernConfigs(io, config) {
117
117
  generatedModuleFederationConfig,
118
118
  createGeneratedModuleFederationConfig(!enableBridgeRouter)
119
119
  ];
120
+ const ownsUiComposition = !node_fs.existsSync(moduleFederationConfigPath) || recognizedModuleFederationConfigs.includes(node_fs.readFileSync(moduleFederationConfigPath, 'utf8'));
120
121
  if (appEmitsBrowserUi(app)) writeOwnedTypeScriptConfig(io, moduleFederationConfigPath, generatedModuleFederationConfig, recognizedModuleFederationConfigs);
121
122
  else removeOwnedTypeScriptConfig(io, moduleFederationConfigPath, recognizedModuleFederationConfigs);
122
123
  const backendFederationConfigPath = node_path.join(io.workspaceRoot, app.directory, 'backend-federation.config.ts');
@@ -127,6 +128,10 @@ function updateGeneratedModernConfigs(io, config) {
127
128
  else removeOwnedTypeScriptConfig(io, backendFederationConfigPath, [
128
129
  generatedBackendFederationConfig
129
130
  ]);
131
+ if (!ownsUiComposition) {
132
+ io.log(`${app.directory} preserves its consumer-owned federation composition instead of regenerating routes from unproven metadata.`);
133
+ continue;
134
+ }
130
135
  if ('shell' === app.kind) {
131
136
  const shellUiRemotes = resolveRemoteRefs(app, remotes).filter(appEmitsBrowserUi);
132
137
  const componentsPath = node_path.join(io.workspaceRoot, app.directory, 'src/routes/vertical-components.tsx');
@@ -70,6 +70,7 @@ function mergeTypeScriptConfig(generated, existing) {
70
70
  ...existingCompilerOptions,
71
71
  ...generatedCompilerOptions
72
72
  };
73
+ if (Array.isArray(generatedCompilerOptions.types)) compilerOptions.types = mergeUniqueJsonValues(generatedCompilerOptions.types, existingCompilerOptions.types);
73
74
  if (Array.isArray(generatedCompilerOptions.plugins) || Array.isArray(existingCompilerOptions.plugins)) compilerOptions.plugins = mergeTypeScriptPlugins(generatedCompilerOptions.plugins, existingCompilerOptions.plugins);
74
75
  const merged = {
75
76
  ...existingConfig,
@@ -24,13 +24,20 @@ function updateDeclaredDependencies(packageJson, pins) {
24
24
  }
25
25
  return changed;
26
26
  }
27
- function updateModernDependencies(packageJson, packageSource) {
27
+ function updateModernDependencies(packageJson, packageSource, releaseCohort) {
28
28
  let changed = false;
29
29
  for (const section of [
30
30
  'dependencies',
31
31
  'devDependencies'
32
32
  ]){
33
33
  const dependencies = packageJson[section];
34
+ if (dependencies && Object.hasOwn(dependencies, '@modern-js/runtime')) {
35
+ const runtimeExtensions = modernPackageSpecifier('@modern-js/runtime-extensions', packageSource);
36
+ if (dependencies['@modern-js/runtime-extensions'] !== runtimeExtensions) {
37
+ dependencies['@modern-js/runtime-extensions'] = runtimeExtensions;
38
+ changed = true;
39
+ }
40
+ }
34
41
  if (dependencies && Object.hasOwn(dependencies, '@modern-js/create')) {
35
42
  dependencies[ULTRAMODERN_CREATE_PACKAGE] = modernPackageSpecifier(ULTRAMODERN_CREATE_PACKAGE, packageSource);
36
43
  delete dependencies['@modern-js/create'];
@@ -38,11 +45,23 @@ function updateModernDependencies(packageJson, packageSource) {
38
45
  }
39
46
  }
40
47
  return updateDeclaredDependencies(packageJson, new Map([
41
- ...modernPackageNames
42
- ].map((packageName)=>[
43
- packageName,
44
- modernPackageSpecifier(packageName, packageSource)
45
- ]))) || changed;
48
+ ...[
49
+ ...modernPackageNames
50
+ ].map((packageName)=>[
51
+ packageName,
52
+ modernPackageSpecifier(packageName, packageSource)
53
+ ]),
54
+ ...(releaseCohort?.packages ?? []).flatMap((item)=>[
55
+ [
56
+ item.sourceName,
57
+ modernPackageSpecifier(item.sourceName, packageSource)
58
+ ],
59
+ [
60
+ item.targetName,
61
+ item.version
62
+ ]
63
+ ])
64
+ ])) || changed;
46
65
  }
47
66
  const generatedToolingDependencyPins = new Map(Object.entries({
48
67
  ...ULTRAMODERN_PACKAGE_PINS.appDependencies,
@@ -135,6 +154,8 @@ function mergeGeneratedScript(consumer, framework, canRetireLegacyOxfmtCliExclus
135
154
  const frameworkSegmentSet = new Set(frameworkSegments);
136
155
  const canonicalFrameworkSegment = (segment)=>{
137
156
  if (frameworkSegmentSet.has(segment)) return segment;
157
+ const referenceBuild = segment.replace('--project tsconfig.json', '--build tsconfig.json');
158
+ if (frameworkSegmentSet.has(referenceBuild)) return referenceBuild;
138
159
  const portableEnvironmentSegment = `cross-env ${segment}`;
139
160
  if (frameworkSegmentSet.has(portableEnvironmentSegment)) return portableEnvironmentSegment;
140
161
  const portableOxfmtSegment = segment.replace(/ '!repos\/\*\*'$/u, '');
@@ -187,12 +208,12 @@ function mergeGeneratedScript(consumer, framework, canRetireLegacyOxfmtCliExclus
187
208
  preservedConsumerSegments: consumerExtras.length > 0
188
209
  };
189
210
  }
190
- function rewriteMigratedScriptReferences(scripts) {
211
+ function rewriteMigratedScriptReferences(scripts, preservedArtifacts) {
191
212
  let changed = false;
192
213
  const pattern = new RegExp(`(scripts/(?:${migratedWorkspaceScriptBasenames.join('|')}))\\.mjs`, 'gu');
193
214
  for (const [name, value] of Object.entries(scripts)){
194
215
  if ('string' != typeof value) continue;
195
- const next = value.replace(pattern, '$1.mts');
216
+ const next = value.replace(pattern, (original, basename)=>preservedArtifacts?.has(`${basename}.mjs`) ? original : `${basename}.mts`);
196
217
  if (next !== value) {
197
218
  scripts[name] = next;
198
219
  changed = true;
@@ -207,7 +228,7 @@ function updateGeneratedPackageScripts(packageJson, options = {}) {
207
228
  const apps = options.apps ?? [];
208
229
  const app = apps.find((candidate)=>`${candidate.directory}/package.json` === options.relativePackageFile);
209
230
  const isRootPackage = 'package.json' === options.relativePackageFile;
210
- if (rewriteMigratedScriptReferences(scripts)) changed = true;
231
+ if (rewriteMigratedScriptReferences(scripts, options.preservedArtifacts)) changed = true;
211
232
  if (isRootPackage) {
212
233
  for (const [name, [legacy, portable]] of legacyPortableRootScripts)if (true === options.canRetireLegacyOxfmtCliExclusion && scripts[name] === legacy) {
213
234
  scripts[name] = portable;
@@ -199,11 +199,7 @@ function reconcilePatchedDependencies(document, includeDrizzleOrmPatch) {
199
199
  patchKey(patch),
200
200
  patch
201
201
  ]));
202
- const ownedPackageNames = new Set([
203
- ...policy.required,
204
- ...policy.conditional,
205
- ...policy.stale
206
- ].map((patch)=>patch.packageName));
202
+ const ownedPackageNames = new Set(expectedPatches.map((patch)=>patch.packageName));
207
203
  const patchedDependencies = ensureMap(document, 'patchedDependencies');
208
204
  for (const [selector, patchPath] of Object.entries(patchedDependencies)){
209
205
  const stalePatch = stale.get(selector);
@@ -212,15 +208,13 @@ function reconcilePatchedDependencies(document, includeDrizzleOrmPatch) {
212
208
  delete patchedDependencies[selector];
213
209
  continue;
214
210
  }
215
- const parts = packageVersionParts(selector);
216
- if (parts && ownedPackageNames.has(parts.packageName) && !expected.has(selector)) {
217
- const conditionalPatch = policy.conditional.find((patch)=>patchKey(patch) === selector);
218
- if (conditionalPatch && !includeDrizzleOrmPatch && patchPath === conditionalPatch.path) {
219
- delete patchedDependencies[selector];
220
- continue;
221
- }
222
- throw new Error(`Framework-owned patch selector ${selector} has unknown provenance.`);
211
+ const conditionalPatch = policy.conditional.find((patch)=>patchKey(patch) === selector);
212
+ if (conditionalPatch && !includeDrizzleOrmPatch && patchPath === conditionalPatch.path) {
213
+ delete patchedDependencies[selector];
214
+ continue;
223
215
  }
216
+ const parts = packageVersionParts(selector);
217
+ if (parts && ownedPackageNames.has(parts.packageName) && !expected.has(selector)) throw new Error(`Framework-owned patch selector ${selector} has unknown provenance.`);
224
218
  }
225
219
  for (const [selector, patchPath] of expected)patchedDependencies[selector] = patchPath;
226
220
  }
@@ -511,6 +505,8 @@ async function validateGeneratedPnpmLockReleaseAgePolicy(workspaceRoot, packageS
511
505
  const firstPartyTargetNames = new Set(releaseCohort?.packages.map((item)=>item.targetName) ?? []);
512
506
  const { document: lockfile } = parsePnpmWorkspaceYaml(node_fs.readFileSync(lockfilePath, 'utf-8'), lockfilePath);
513
507
  const closure = discoverReachablePnpmLockReleaseAgeClosure(lockfile);
508
+ const firstPartySourceNames = new Set(releaseCohort?.packages.map((item)=>item.sourceName) ?? []);
509
+ for (const tarball of closure.tarballs)if (firstPartyTargetNames.has(tarball.packageName) || firstPartySourceNames.has(tarball.packageName)) throw new Error(`First-party lock candidate ${tarball.packageName} must resolve through the authenticated release cohort, not a tarball URL.`);
514
510
  if (closure.unresolved.length > 0) {
515
511
  const unresolved = closure.unresolved.slice(0, 20).map((candidate)=>{
516
512
  const packageName = candidate.package ?? 'unknown package';
@@ -9,6 +9,11 @@ const integrityPattern = /^sha512-[A-Za-z0-9+/]+={0,2}$/u;
9
9
  function isExactSemver(version) {
10
10
  return semver.valid(version) === version;
11
11
  }
12
+ function isHttpsTarballLocator(value) {
13
+ if (!value.startsWith('https://') || /[\s()]/u.test(value) || !URL.canParse(value)) return false;
14
+ const url = new URL(value);
15
+ return url.href === value && '' === url.username && '' === url.password && '' === url.hash;
16
+ }
12
17
  function isYamlRecord(value) {
13
18
  return Boolean(value) && 'object' == typeof value && !Array.isArray(value);
14
19
  }
@@ -62,7 +67,7 @@ function splitPeerContext(locator) {
62
67
  for (const segment of segments){
63
68
  if (/^patch_hash=[a-f0-9]{32,128}$/u.test(segment) || /^[a-f0-9]{32,128}$/u.test(segment)) continue;
64
69
  const peer = parsePackageKey(segment);
65
- if (!peer) return {
70
+ if (!peer || isHttpsTarballLocator(peer.version)) return {
66
71
  unresolved: locator
67
72
  };
68
73
  peers.push(peer);
@@ -74,11 +79,12 @@ function splitPeerContext(locator) {
74
79
  }
75
80
  function parsePackageLocator(rawLocator) {
76
81
  const locator = rawLocator.replace(/^\//u, '');
77
- const separator = locator.lastIndexOf('@');
82
+ const tarballSeparator = locator.indexOf('@https://');
83
+ const separator = tarballSeparator > 0 ? tarballSeparator : locator.lastIndexOf('@');
78
84
  if (separator <= 0) return;
79
85
  const packageName = locator.slice(0, separator);
80
86
  const version = locator.slice(separator + 1);
81
- if (!exactPackageNamePattern.test(packageName) || !isExactSemver(version)) return;
87
+ if (!exactPackageNamePattern.test(packageName) || !isExactSemver(version) && !isHttpsTarballLocator(version)) return;
82
88
  return {
83
89
  packageName,
84
90
  version,
@@ -122,6 +128,11 @@ function dependencyIdentity(dependencyName, rawValue) {
122
128
  const peerContext = splitPeerContext(value.startsWith('npm:') ? value.slice(4) : value);
123
129
  if ('unresolved' in peerContext) return peerContext;
124
130
  const { base, peers } = peerContext;
131
+ if (isHttpsTarballLocator(base) && exactPackageNamePattern.test(dependencyName)) return {
132
+ packageName: dependencyName,
133
+ version: base,
134
+ peers
135
+ };
125
136
  const full = parsePackageLocator(base);
126
137
  if (full) return {
127
138
  ...full,
@@ -264,13 +275,11 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
264
275
  const currentPath = shortestIdentityPaths.get(key);
265
276
  if (!currentPath || nodePath.length < currentPath.length) shortestIdentityPaths.set(key, nodePath);
266
277
  }
278
+ const tarballs = [];
267
279
  const candidates = [
268
280
  ...shortestIdentityPaths.entries()
269
281
  ].map(([key, path])=>{
270
- const [packageName, version] = [
271
- key.slice(0, key.lastIndexOf('@')),
272
- key.slice(key.lastIndexOf('@') + 1)
273
- ];
282
+ const { packageName, version } = nodes.get(nodeIdsByIdentity.get(key)[0]).identity;
274
283
  const packageRecordsForIdentity = packageRecordsByIdentity.get(key);
275
284
  if (!packageRecordsForIdentity?.length) return void recordUnresolved({
276
285
  packageName,
@@ -278,12 +287,25 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
278
287
  peers: []
279
288
  }, path, 'missing exact SHA-512 lock integrity');
280
289
  let integrity;
290
+ let tarballVersion;
281
291
  for (const [packageKey, packageRecord] of packageRecordsForIdentity){
282
292
  const resolution = requiredYamlRecord(requiredYamlRecord(packageRecord, `pnpm lockfile package ${packageKey}`).resolution, `pnpm lockfile package ${packageKey} resolution`);
283
293
  if ('string' != typeof resolution.integrity || !integrityPattern.test(resolution.integrity)) throw new Error(`pnpm lockfile package ${packageKey} has uncertain registry integrity.`);
284
294
  if (integrity && integrity !== resolution.integrity) throw new Error(`pnpm lockfile has conflicting registry integrity for ${key}.`);
285
295
  integrity = resolution.integrity;
296
+ if (isHttpsTarballLocator(version)) {
297
+ const metadata = requiredYamlRecord(packageRecord, `pnpm lockfile package ${packageKey}`);
298
+ if (resolution.tarball !== version || 'string' != typeof metadata.version || !isExactSemver(metadata.version) || void 0 !== tarballVersion && tarballVersion !== metadata.version) throw new Error(`pnpm lockfile package ${packageKey} has uncertain tarball identity.`);
299
+ tarballVersion = metadata.version;
300
+ }
286
301
  }
302
+ if (void 0 !== tarballVersion) return void tarballs.push({
303
+ packageName,
304
+ version: tarballVersion,
305
+ url: version,
306
+ integrity: integrity,
307
+ path
308
+ });
287
309
  return {
288
310
  packageName,
289
311
  version,
@@ -298,6 +320,7 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
298
320
  unresolved.sort((left, right)=>JSON.stringify(left).localeCompare(JSON.stringify(right)));
299
321
  return {
300
322
  candidates,
323
+ tarballs,
301
324
  unresolved
302
325
  };
303
326
  }
@@ -0,0 +1,50 @@
1
+ import node_fs from "node:fs";
2
+ import node_path from "node:path";
3
+ import { readFileTemplate } from "../../../ultramodern-workspace/fs-io.js";
4
+ import { createSharedPackage, createSharedPackageTsConfig } from "../../../ultramodern-workspace/package-json.js";
5
+ import { readJsonFile, writeJsonFile } from "./io.js";
6
+ const directory = 'packages/shared-contracts';
7
+ function record(value, label) {
8
+ if (null === value || 'object' != typeof value || Array.isArray(value)) throw new Error(`${label} must be an object; resolve it before migration.`);
9
+ return value;
10
+ }
11
+ function ensureSharedApiInfrastructure(io, scope, packageSource) {
12
+ for (const relativePath of [
13
+ 'packages',
14
+ directory,
15
+ `${directory}/package.json`,
16
+ `${directory}/src`,
17
+ `${directory}/src/index.ts`
18
+ ])if (node_fs.lstatSync(node_path.join(io.workspaceRoot, relativePath), {
19
+ throwIfNoEntry: false
20
+ })?.isSymbolicLink()) throw new Error(`Shared API migration cannot write through a symbolic link: ${relativePath}`);
21
+ const manifestPath = node_path.join(io.workspaceRoot, directory, 'package.json');
22
+ const defaults = createSharedPackage(scope, 'shared-contracts', 'Shared workspace contracts', packageSource);
23
+ const manifest = node_fs.existsSync(manifestPath) ? record(readJsonFile(manifestPath), `${directory}/package.json`) : defaults;
24
+ const exports = void 0 === manifest.exports ? {} : 'string' == typeof manifest.exports ? {
25
+ '.': manifest.exports
26
+ } : record(manifest.exports, `${directory}/package.json exports`);
27
+ if (Object.keys(exports).some((key)=>!key.startsWith('.')) || void 0 !== exports['.'] && './src/index.ts' !== exports['.']) throw new Error(`${directory}/package.json exports must expose ./src/index.ts at "." before adding shared API infrastructure; consumer exports were not overwritten.`);
28
+ for (const [subpath, target] of Object.entries(record(defaults.exports, 'Shared contract exports')))if (void 0 !== exports[subpath] && exports[subpath] !== target) throw new Error(`${directory}/package.json ${subpath} must expose ${String(target)}; consumer exports were not overwritten.`);
29
+ const dependencies = record(manifest.dependencies ?? {}, `${directory}/package.json dependencies`);
30
+ manifest.exports = {
31
+ ...record(defaults.exports, 'Shared contract exports'),
32
+ ...exports
33
+ };
34
+ manifest.dependencies = {
35
+ ...record(defaults.dependencies, 'Shared contract dependencies'),
36
+ ...dependencies
37
+ };
38
+ const writeMissing = (relativePath, content)=>{
39
+ const filePath = node_path.join(io.workspaceRoot, directory, relativePath);
40
+ if (void 0 === node_fs.lstatSync(filePath, {
41
+ throwIfNoEntry: false
42
+ })) io.writeGenerated(filePath, content);
43
+ };
44
+ writeMissing('src/effect-bff-runtime.ts', readFileTemplate('packages/effect-bff-runtime.ts'));
45
+ writeMissing('src/microvertical-api-baseline.ts', readFileTemplate('packages/microvertical-api-baseline.ts'));
46
+ writeMissing('tsconfig.json', `${JSON.stringify(createSharedPackageTsConfig(directory), null, 2)}\n`);
47
+ writeMissing('src/index.ts', readFileTemplate('packages/shared-contracts-index.ts'));
48
+ writeJsonFile(io, manifestPath, manifest);
49
+ }
50
+ export { ensureSharedApiInfrastructure };