@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.3 → 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 (48) 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/package-cohort.cjs +28 -9
  5. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.cjs +9 -13
  6. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.cjs +30 -7
  7. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +13 -5
  8. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.cjs +215 -0
  9. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +70 -8
  10. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +18 -46
  11. package/dist/cjs/ultramodern-workspace/package-json.cjs +1 -0
  12. package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +2 -1
  13. package/dist/cjs/ultramodern-workspace/write-app.cjs +1 -1
  14. package/dist/esm/ultramodern-package-source.js +2 -1
  15. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  16. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  17. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +28 -9
  18. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  19. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  20. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +13 -5
  21. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +166 -0
  22. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +71 -9
  23. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +18 -46
  24. package/dist/esm/ultramodern-workspace/package-json.js +1 -0
  25. package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +2 -1
  26. package/dist/esm/ultramodern-workspace/write-app.js +1 -1
  27. package/dist/esm-node/ultramodern-package-source.js +2 -1
  28. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  29. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  30. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +28 -9
  31. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  32. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  33. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +13 -5
  34. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +167 -0
  35. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +71 -9
  36. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +18 -46
  37. package/dist/esm-node/ultramodern-workspace/package-json.js +1 -0
  38. package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +2 -1
  39. package/dist/esm-node/ultramodern-workspace/write-app.js +1 -1
  40. package/dist/types/ultramodern-package-source.d.ts +1 -1
  41. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.d.ts +3 -1
  42. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.d.ts +7 -0
  43. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.d.ts +27 -0
  44. package/dist/types/ultramodern-workspace/module-federation/reexport-module.d.ts +2 -2
  45. package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +1 -1
  46. package/package.json +5 -4
  47. package/template-workspace/.modernjs/release-cohort.json +40 -40
  48. package/template-workspace/scripts/bootstrap-agent-skills.mjs +4 -4
@@ -53,7 +53,8 @@ const ULTRAMODERN_WORKSPACE_MODERN_PACKAGES = [
53
53
  '@modern-js/plugin-bff',
54
54
  '@modern-js/plugin-i18n',
55
55
  '@modern-js/plugin-tanstack',
56
- '@modern-js/runtime'
56
+ '@modern-js/runtime',
57
+ '@modern-js/runtime-extensions'
57
58
  ];
58
59
  function modernPackageVersion(packageSource) {
59
60
  return 'install' === packageSource.strategy ? packageSource.modernPackageVersion : WORKSPACE_PACKAGE_VERSION;
@@ -45,6 +45,7 @@ const external_node_fs_namespaceObject = require("node:fs");
45
45
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
46
46
  const external_node_path_namespaceObject = require("node:path");
47
47
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
48
+ const descriptors_cjs_namespaceObject = require("../../../ultramodern-workspace/descriptors.cjs");
48
49
  const module_federation_cjs_namespaceObject = require("../../../ultramodern-workspace/module-federation.cjs");
49
50
  const external_config_cjs_namespaceObject = require("../../config.cjs");
50
51
  const legacyApiMarkerPattern = /export const ultramodernApiMarker\s*=\s*\{[\s\S]*?\}\s+as const;\n?/u;
@@ -84,8 +85,10 @@ function updateGeneratedBuildIdentityModules(io, config) {
84
85
  for (const app of (0, external_config_cjs_namespaceObject.allWorkspaceAppsFromToolingConfig)(config)){
85
86
  const sharedApiPath = external_node_path_default().join(io.workspaceRoot, app.directory, 'shared/api.ts');
86
87
  if (app.api && external_node_fs_default().existsSync(sharedApiPath)) io.write(sharedApiPath, rewriteApiMarkerIdentitySchema(rewriteLegacyApiMarkerBinding(external_node_fs_default().readFileSync(sharedApiPath, 'utf-8'))));
87
- io.writeGenerated(external_node_path_default().join(io.workspaceRoot, app.directory, 'src/ultramodern-build.ts'), (0, module_federation_cjs_namespaceObject.createUltramodernBuildReexportModule)());
88
- io.writeGenerated(external_node_path_default().join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.ts'), (0, module_federation_cjs_namespaceObject.createUltramodernBuildModule)(config.workspace.packageScope, app));
88
+ const reexportPath = external_node_path_default().join(io.workspaceRoot, app.directory, 'src/ultramodern-build.ts');
89
+ const includeUiMarker = (0, descriptors_cjs_namespaceObject.appEmitsBrowserUi)(app) && ('shell' !== app.kind || external_node_fs_default().existsSync(reexportPath));
90
+ if (external_node_fs_default().existsSync(reexportPath)) io.writeGenerated(reexportPath, (0, module_federation_cjs_namespaceObject.createUltramodernBuildReexportModule)(app, includeUiMarker));
91
+ io.writeGenerated(external_node_path_default().join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.ts'), (0, module_federation_cjs_namespaceObject.createUltramodernBuildModule)(config.workspace.packageScope, app, includeUiMarker));
89
92
  io.write(external_node_path_default().join(io.workspaceRoot, app.directory, 'shared/ultramodern-build.json'), (0, module_federation_cjs_namespaceObject.createUltramodernBuildArtifactJson)(config.workspace.packageScope, app));
90
93
  }
91
94
  }
@@ -160,6 +160,7 @@ function updateGeneratedModernConfigs(io, config) {
160
160
  generatedModuleFederationConfig,
161
161
  createGeneratedModuleFederationConfig(!enableBridgeRouter)
162
162
  ];
163
+ const ownsUiComposition = !external_node_fs_default().existsSync(moduleFederationConfigPath) || recognizedModuleFederationConfigs.includes(external_node_fs_default().readFileSync(moduleFederationConfigPath, 'utf8'));
163
164
  if ((0, descriptors_cjs_namespaceObject.appEmitsBrowserUi)(app)) writeOwnedTypeScriptConfig(io, moduleFederationConfigPath, generatedModuleFederationConfig, recognizedModuleFederationConfigs);
164
165
  else removeOwnedTypeScriptConfig(io, moduleFederationConfigPath, recognizedModuleFederationConfigs);
165
166
  const backendFederationConfigPath = external_node_path_default().join(io.workspaceRoot, app.directory, 'backend-federation.config.ts');
@@ -170,6 +171,10 @@ function updateGeneratedModernConfigs(io, config) {
170
171
  else removeOwnedTypeScriptConfig(io, backendFederationConfigPath, [
171
172
  generatedBackendFederationConfig
172
173
  ]);
174
+ if (!ownsUiComposition) {
175
+ io.log(`${app.directory} preserves its consumer-owned federation composition instead of regenerating routes from unproven metadata.`);
176
+ continue;
177
+ }
173
178
  if ('shell' === app.kind) {
174
179
  const shellUiRemotes = (0, descriptors_cjs_namespaceObject.resolveRemoteRefs)(app, remotes).filter(descriptors_cjs_namespaceObject.appEmitsBrowserUi);
175
180
  const componentsPath = external_node_path_default().join(io.workspaceRoot, app.directory, 'src/routes/vertical-components.tsx');
@@ -59,13 +59,20 @@ function updateDeclaredDependencies(packageJson, pins) {
59
59
  }
60
60
  return changed;
61
61
  }
62
- function updateModernDependencies(packageJson, packageSource) {
62
+ function updateModernDependencies(packageJson, packageSource, releaseCohort) {
63
63
  let changed = false;
64
64
  for (const section of [
65
65
  'dependencies',
66
66
  'devDependencies'
67
67
  ]){
68
68
  const dependencies = packageJson[section];
69
+ if (dependencies && Object.hasOwn(dependencies, '@modern-js/runtime')) {
70
+ const runtimeExtensions = (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)('@modern-js/runtime-extensions', packageSource);
71
+ if (dependencies['@modern-js/runtime-extensions'] !== runtimeExtensions) {
72
+ dependencies['@modern-js/runtime-extensions'] = runtimeExtensions;
73
+ changed = true;
74
+ }
75
+ }
69
76
  if (dependencies && Object.hasOwn(dependencies, '@modern-js/create')) {
70
77
  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
78
  delete dependencies['@modern-js/create'];
@@ -73,11 +80,23 @@ function updateModernDependencies(packageJson, packageSource) {
73
80
  }
74
81
  }
75
82
  return updateDeclaredDependencies(packageJson, new Map([
76
- ...modernPackageNames
77
- ].map((packageName)=>[
78
- packageName,
79
- (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)(packageName, packageSource)
80
- ]))) || changed;
83
+ ...[
84
+ ...modernPackageNames
85
+ ].map((packageName)=>[
86
+ packageName,
87
+ (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)(packageName, packageSource)
88
+ ]),
89
+ ...(releaseCohort?.packages ?? []).flatMap((item)=>[
90
+ [
91
+ item.sourceName,
92
+ (0, external_ultramodern_package_source_cjs_namespaceObject.modernPackageSpecifier)(item.sourceName, packageSource)
93
+ ],
94
+ [
95
+ item.targetName,
96
+ item.version
97
+ ]
98
+ ])
99
+ ])) || changed;
81
100
  }
82
101
  const generatedToolingDependencyPins = new Map(Object.entries({
83
102
  ...policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.appDependencies,
@@ -224,12 +243,12 @@ function mergeGeneratedScript(consumer, framework, canRetireLegacyOxfmtCliExclus
224
243
  preservedConsumerSegments: consumerExtras.length > 0
225
244
  };
226
245
  }
227
- function rewriteMigratedScriptReferences(scripts) {
246
+ function rewriteMigratedScriptReferences(scripts, preservedArtifacts) {
228
247
  let changed = false;
229
248
  const pattern = new RegExp(`(scripts/(?:${workspace_scripts_cjs_namespaceObject.migratedWorkspaceScriptBasenames.join('|')}))\\.mjs`, 'gu');
230
249
  for (const [name, value] of Object.entries(scripts)){
231
250
  if ('string' != typeof value) continue;
232
- const next = value.replace(pattern, '$1.mts');
251
+ const next = value.replace(pattern, (original, basename)=>preservedArtifacts?.has(`${basename}.mjs`) ? original : `${basename}.mts`);
233
252
  if (next !== value) {
234
253
  scripts[name] = next;
235
254
  changed = true;
@@ -244,7 +263,7 @@ function updateGeneratedPackageScripts(packageJson, options = {}) {
244
263
  const apps = options.apps ?? [];
245
264
  const app = apps.find((candidate)=>`${candidate.directory}/package.json` === options.relativePackageFile);
246
265
  const isRootPackage = 'package.json' === options.relativePackageFile;
247
- if (rewriteMigratedScriptReferences(scripts)) changed = true;
266
+ if (rewriteMigratedScriptReferences(scripts, options.preservedArtifacts)) changed = true;
248
267
  if (isRootPackage) {
249
268
  for (const [name, [legacy, portable]] of legacyPortableRootScripts)if (true === options.canRetireLegacyOxfmtCliExclusion && scripts[name] === legacy) {
250
269
  scripts[name] = portable;
@@ -244,11 +244,7 @@ function reconcilePatchedDependencies(document, includeDrizzleOrmPatch) {
244
244
  patchKey(patch),
245
245
  patch
246
246
  ]));
247
- const ownedPackageNames = new Set([
248
- ...policy.required,
249
- ...policy.conditional,
250
- ...policy.stale
251
- ].map((patch)=>patch.packageName));
247
+ const ownedPackageNames = new Set(expectedPatches.map((patch)=>patch.packageName));
252
248
  const patchedDependencies = ensureMap(document, 'patchedDependencies');
253
249
  for (const [selector, patchPath] of Object.entries(patchedDependencies)){
254
250
  const stalePatch = stale.get(selector);
@@ -257,15 +253,13 @@ function reconcilePatchedDependencies(document, includeDrizzleOrmPatch) {
257
253
  delete patchedDependencies[selector];
258
254
  continue;
259
255
  }
260
- const parts = packageVersionParts(selector);
261
- if (parts && ownedPackageNames.has(parts.packageName) && !expected.has(selector)) {
262
- const conditionalPatch = policy.conditional.find((patch)=>patchKey(patch) === selector);
263
- if (conditionalPatch && !includeDrizzleOrmPatch && patchPath === conditionalPatch.path) {
264
- delete patchedDependencies[selector];
265
- continue;
266
- }
267
- throw new Error(`Framework-owned patch selector ${selector} has unknown provenance.`);
256
+ const conditionalPatch = policy.conditional.find((patch)=>patchKey(patch) === selector);
257
+ if (conditionalPatch && !includeDrizzleOrmPatch && patchPath === conditionalPatch.path) {
258
+ delete patchedDependencies[selector];
259
+ continue;
268
260
  }
261
+ const parts = packageVersionParts(selector);
262
+ if (parts && ownedPackageNames.has(parts.packageName) && !expected.has(selector)) throw new Error(`Framework-owned patch selector ${selector} has unknown provenance.`);
269
263
  }
270
264
  for (const [selector, patchPath] of expected)patchedDependencies[selector] = patchPath;
271
265
  }
@@ -556,6 +550,8 @@ async function validateGeneratedPnpmLockReleaseAgePolicy(workspaceRoot, packageS
556
550
  const firstPartyTargetNames = new Set(releaseCohort?.packages.map((item)=>item.targetName) ?? []);
557
551
  const { document: lockfile } = (0, external_pnpm_yaml_cjs_namespaceObject.parsePnpmWorkspaceYaml)(external_node_fs_default().readFileSync(lockfilePath, 'utf-8'), lockfilePath);
558
552
  const closure = (0, external_pnpm_yaml_cjs_namespaceObject.discoverReachablePnpmLockReleaseAgeClosure)(lockfile);
553
+ const firstPartySourceNames = new Set(releaseCohort?.packages.map((item)=>item.sourceName) ?? []);
554
+ 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.`);
559
555
  if (closure.unresolved.length > 0) {
560
556
  const unresolved = closure.unresolved.slice(0, 20).map((candidate)=>{
561
557
  const packageName = candidate.package ?? 'unknown package';
@@ -44,6 +44,11 @@ const integrityPattern = /^sha512-[A-Za-z0-9+/]+={0,2}$/u;
44
44
  function isExactSemver(version) {
45
45
  return utils_namespaceObject.semver.valid(version) === version;
46
46
  }
47
+ function isHttpsTarballLocator(value) {
48
+ if (!value.startsWith('https://') || /[\s()]/u.test(value) || !URL.canParse(value)) return false;
49
+ const url = new URL(value);
50
+ return url.href === value && '' === url.username && '' === url.password && '' === url.hash;
51
+ }
47
52
  function isYamlRecord(value) {
48
53
  return Boolean(value) && 'object' == typeof value && !Array.isArray(value);
49
54
  }
@@ -97,7 +102,7 @@ function splitPeerContext(locator) {
97
102
  for (const segment of segments){
98
103
  if (/^patch_hash=[a-f0-9]{32,128}$/u.test(segment) || /^[a-f0-9]{32,128}$/u.test(segment)) continue;
99
104
  const peer = parsePackageKey(segment);
100
- if (!peer) return {
105
+ if (!peer || isHttpsTarballLocator(peer.version)) return {
101
106
  unresolved: locator
102
107
  };
103
108
  peers.push(peer);
@@ -109,11 +114,12 @@ function splitPeerContext(locator) {
109
114
  }
110
115
  function parsePackageLocator(rawLocator) {
111
116
  const locator = rawLocator.replace(/^\//u, '');
112
- const separator = locator.lastIndexOf('@');
117
+ const tarballSeparator = locator.indexOf('@https://');
118
+ const separator = tarballSeparator > 0 ? tarballSeparator : locator.lastIndexOf('@');
113
119
  if (separator <= 0) return;
114
120
  const packageName = locator.slice(0, separator);
115
121
  const version = locator.slice(separator + 1);
116
- if (!exactPackageNamePattern.test(packageName) || !isExactSemver(version)) return;
122
+ if (!exactPackageNamePattern.test(packageName) || !isExactSemver(version) && !isHttpsTarballLocator(version)) return;
117
123
  return {
118
124
  packageName,
119
125
  version,
@@ -157,6 +163,11 @@ function dependencyIdentity(dependencyName, rawValue) {
157
163
  const peerContext = splitPeerContext(value.startsWith('npm:') ? value.slice(4) : value);
158
164
  if ('unresolved' in peerContext) return peerContext;
159
165
  const { base, peers } = peerContext;
166
+ if (isHttpsTarballLocator(base) && exactPackageNamePattern.test(dependencyName)) return {
167
+ packageName: dependencyName,
168
+ version: base,
169
+ peers
170
+ };
160
171
  const full = parsePackageLocator(base);
161
172
  if (full) return {
162
173
  ...full,
@@ -299,13 +310,11 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
299
310
  const currentPath = shortestIdentityPaths.get(key);
300
311
  if (!currentPath || nodePath.length < currentPath.length) shortestIdentityPaths.set(key, nodePath);
301
312
  }
313
+ const tarballs = [];
302
314
  const candidates = [
303
315
  ...shortestIdentityPaths.entries()
304
316
  ].map(([key, path])=>{
305
- const [packageName, version] = [
306
- key.slice(0, key.lastIndexOf('@')),
307
- key.slice(key.lastIndexOf('@') + 1)
308
- ];
317
+ const { packageName, version } = nodes.get(nodeIdsByIdentity.get(key)[0]).identity;
309
318
  const packageRecordsForIdentity = packageRecordsByIdentity.get(key);
310
319
  if (!packageRecordsForIdentity?.length) return void recordUnresolved({
311
320
  packageName,
@@ -313,12 +322,25 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
313
322
  peers: []
314
323
  }, path, 'missing exact SHA-512 lock integrity');
315
324
  let integrity;
325
+ let tarballVersion;
316
326
  for (const [packageKey, packageRecord] of packageRecordsForIdentity){
317
327
  const resolution = requiredYamlRecord(requiredYamlRecord(packageRecord, `pnpm lockfile package ${packageKey}`).resolution, `pnpm lockfile package ${packageKey} resolution`);
318
328
  if ('string' != typeof resolution.integrity || !integrityPattern.test(resolution.integrity)) throw new Error(`pnpm lockfile package ${packageKey} has uncertain registry integrity.`);
319
329
  if (integrity && integrity !== resolution.integrity) throw new Error(`pnpm lockfile has conflicting registry integrity for ${key}.`);
320
330
  integrity = resolution.integrity;
331
+ if (isHttpsTarballLocator(version)) {
332
+ const metadata = requiredYamlRecord(packageRecord, `pnpm lockfile package ${packageKey}`);
333
+ 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.`);
334
+ tarballVersion = metadata.version;
335
+ }
321
336
  }
337
+ if (void 0 !== tarballVersion) return void tarballs.push({
338
+ packageName,
339
+ version: tarballVersion,
340
+ url: version,
341
+ integrity: integrity,
342
+ path
343
+ });
322
344
  return {
323
345
  packageName,
324
346
  version,
@@ -333,6 +355,7 @@ function discoverReachablePnpmLockReleaseAgeClosure(lockfile) {
333
355
  unresolved.sort((left, right)=>JSON.stringify(left).localeCompare(JSON.stringify(right)));
334
356
  return {
335
357
  candidates,
358
+ tarballs,
336
359
  unresolved
337
360
  };
338
361
  }
@@ -45,11 +45,16 @@ const external_node_fs_namespaceObject = require("node:fs");
45
45
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
46
46
  const external_node_path_namespaceObject = require("node:path");
47
47
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
48
+ const utils_namespaceObject = require("@modern-js/utils");
48
49
  const policy_cjs_namespaceObject = require("../../../ultramodern-workspace/policy.cjs");
49
50
  const { toolchain } = policy_cjs_namespaceObject.ULTRAMODERN_WORKSPACE_POLICY;
50
51
  const retiredRootToolingDependencies = [
51
52
  "@typescript/typescript6"
52
53
  ];
54
+ function migrationPnpmVersion(value) {
55
+ const baseline = toolchain.packageManager.version;
56
+ return 'string' == typeof value && utils_namespaceObject.semver.valid(value) && utils_namespaceObject.semver.major(value) === utils_namespaceObject.semver.major(baseline) && utils_namespaceObject.semver.gte(value, baseline) ? value : baseline;
57
+ }
53
58
  function isRecord(value) {
54
59
  return Boolean(value) && 'object' == typeof value && !Array.isArray(value);
55
60
  }
@@ -67,13 +72,14 @@ function updateUltramodernConfigToolchain(config) {
67
72
  const workspace = ensureRecord(config, 'workspace', 'workspace');
68
73
  const packageManager = ensureRecord(workspace, 'packageManager', 'workspace.packageManager');
69
74
  packageManager.name = toolchain.packageManager.name;
70
- packageManager.version = toolchain.packageManager.version;
75
+ packageManager.version = migrationPnpmVersion(packageManager.version);
71
76
  const node = ensureRecord(workspace, 'node', 'workspace.node');
72
77
  node.version = toolchain.node.version;
73
78
  node.engineRange = toolchain.node.engineRange;
74
79
  }
75
80
  function updateRootPackageToolchain(packageJson) {
76
- packageJson.packageManager = `${toolchain.packageManager.name}@${toolchain.packageManager.version}`;
81
+ const currentVersion = 'string' == typeof packageJson.packageManager ? packageJson.packageManager.match(/^pnpm@([^+]+)(?:\+.*)?$/u)?.[1] : void 0;
82
+ packageJson.packageManager = `${toolchain.packageManager.name}@${migrationPnpmVersion(currentVersion)}`;
77
83
  const engines = ensureRecord(packageJson, 'engines', 'package.json engines');
78
84
  engines.node = toolchain.node.engineRange;
79
85
  engines.pnpm = toolchain.packageManager.engineRange;
@@ -83,7 +89,7 @@ function updateRootPackageToolchain(packageJson) {
83
89
  devDependencies['@types/node'] = policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.rootDevDependencies["@types/node"];
84
90
  devDependencies.miniflare = policy_cjs_namespaceObject.ULTRAMODERN_PACKAGE_PINS.rootDevDependencies.miniflare;
85
91
  }
86
- function updateMiseTools(content) {
92
+ function updateMiseTools(content, pnpmVersion) {
87
93
  const lines = content.replace(/\r\n/gu, '\n').split('\n');
88
94
  if ('' === lines.at(-1)) lines.pop();
89
95
  let toolsStart = lines.findIndex((line)=>/^\s*\[tools\]\s*(?:#.*)?$/u.test(line));
@@ -110,13 +116,15 @@ function updateMiseTools(content) {
110
116
  lines[index] = line;
111
117
  };
112
118
  upsertTool('node', toolchain.node.version);
113
- upsertTool('pnpm', toolchain.packageManager.version);
119
+ upsertTool('pnpm', pnpmVersion);
114
120
  return `${lines.join('\n')}\n`;
115
121
  }
116
122
  function updateGeneratedToolchainFiles(io) {
117
123
  const misePath = external_node_path_default().join(io.workspaceRoot, '.mise.toml');
118
124
  const miseContent = external_node_fs_default().existsSync(misePath) ? external_node_fs_default().readFileSync(misePath, 'utf-8') : '';
119
- io.write(misePath, updateMiseTools(miseContent));
125
+ const packageJson = JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(io.workspaceRoot, 'package.json'), 'utf8'));
126
+ const pnpmVersion = migrationPnpmVersion(packageJson.packageManager?.match(/^pnpm@([^+]+)(?:\+.*)?$/u)?.[1]);
127
+ io.write(misePath, updateMiseTools(miseContent, pnpmVersion));
120
128
  const workflowPath = external_node_path_default().join(io.workspaceRoot, '.github/workflows/ultramodern-workspace-gates.yml');
121
129
  if (!external_node_fs_default().existsSync(workflowPath)) return;
122
130
  const workflow = external_node_fs_default().readFileSync(workflowPath, 'utf-8');
@@ -0,0 +1,215 @@
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
+ preserveConsumerWorkspaceArtifacts: ()=>preserveConsumerWorkspaceArtifacts
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 parser_namespaceObject = require("@babel/parser");
47
+ const fs_io_cjs_namespaceObject = require("../../../ultramodern-workspace/fs-io.cjs");
48
+ function isLiteralData(node, literalIdentifiers) {
49
+ if (!node) return false;
50
+ if ('Identifier' === node.type) return literalIdentifiers?.has(node.name) ?? false;
51
+ if ([
52
+ 'StringLiteral',
53
+ 'NumericLiteral',
54
+ 'BooleanLiteral',
55
+ 'NullLiteral'
56
+ ].includes(node.type)) return true;
57
+ if ('UnaryExpression' === node.type) return '-' === node.operator && 'NumericLiteral' === node.argument.type;
58
+ if ('ArrayExpression' === node.type) return node.elements.every((element)=>isLiteralData(element, literalIdentifiers));
59
+ return 'ObjectExpression' === node.type && node.properties.every((property)=>'ObjectProperty' === property.type && !property.computed && !property.shorthand && [
60
+ 'Identifier',
61
+ 'StringLiteral',
62
+ 'NumericLiteral'
63
+ ].includes(property.key.type) && isLiteralData(property.value, literalIdentifiers));
64
+ }
65
+ function withoutGeneratedData(source, binding) {
66
+ if (!binding) return source;
67
+ const parsed = (0, parser_namespaceObject.parse)(source, {
68
+ sourceType: 'module',
69
+ plugins: [
70
+ "typescript"
71
+ ]
72
+ });
73
+ for (const statement of parsed.program.body)if ('VariableDeclaration' === statement.type && 'const' === statement.kind) {
74
+ for (const declaration of statement.declarations)if ('Identifier' === declaration.id.type && declaration.id.name === binding && declaration.init && isLiteralData(declaration.init)) return source.slice(0, declaration.init.start) + '{}' + source.slice(declaration.init.end);
75
+ }
76
+ return source;
77
+ }
78
+ function staticPropertyValue(node, name) {
79
+ if (node?.type !== 'ObjectExpression') return;
80
+ const keys = new Set();
81
+ let value;
82
+ for (const property of node.properties){
83
+ if ('ObjectProperty' !== property.type || property.computed || property.shorthand || ![
84
+ 'Identifier',
85
+ 'StringLiteral'
86
+ ].includes(property.key.type)) return;
87
+ const key = property.key.name ?? property.key.value;
88
+ if (keys.has(key)) return;
89
+ keys.add(key);
90
+ if (key === name) value = property.value;
91
+ }
92
+ return value;
93
+ }
94
+ function refreshValidatorReleaseCohort(source, releaseCohort) {
95
+ try {
96
+ const parsed = (0, parser_namespaceObject.parse)(source, {
97
+ sourceType: 'module',
98
+ plugins: [
99
+ "typescript"
100
+ ],
101
+ tokens: true
102
+ });
103
+ const constants = parsed.program.body.flatMap((statement)=>'VariableDeclaration' === statement.type && 'const' === statement.kind ? statement.declarations : []);
104
+ const matches = [];
105
+ for (const statement of parsed.program.body)if ('VariableDeclaration' === statement.type && 'const' === statement.kind) for (const declaration of statement.declarations){
106
+ const kind = staticPropertyValue(declaration.init, 'kind');
107
+ if (kind?.type !== 'StringLiteral' || 'modernjs.ultramodern-workspace-validation-contract' !== kind.value) continue;
108
+ const cohort = staticPropertyValue(staticPropertyValue(declaration.init, 'cohort'), 'releaseCohort');
109
+ const schema = staticPropertyValue(cohort, 'schema');
110
+ const schemaVersion = staticPropertyValue(cohort, 'schemaVersion');
111
+ const version = staticPropertyValue(staticPropertyValue(cohort, 'release'), 'version');
112
+ const versionConstant = version?.type === 'Identifier' ? constants.find((declaration)=>'Identifier' === declaration.id.type && declaration.id.name === version.name && declaration.init?.type === 'StringLiteral') : void 0;
113
+ if (schema?.type === 'StringLiteral' && 'bleedingdev.ultramodern.release-cohort' === schema.value && schemaVersion?.type === 'NumericLiteral' && 1 === schemaVersion.value && isLiteralData(cohort, versionConstant ? new Set([
114
+ version.name
115
+ ]) : void 0)) matches.push({
116
+ cohort,
117
+ version,
118
+ versionConstant
119
+ });
120
+ }
121
+ if (1 !== matches.length) return source;
122
+ const { cohort, version, versionConstant } = matches[0];
123
+ let content = JSON.stringify(releaseCohort, null, 2);
124
+ const edits = [];
125
+ if (versionConstant && !parsed.tokens?.some((token)=>'name' === token.type.label && token.value === version.name && token.start !== versionConstant.id.start && (token.start < cohort.start || token.end > cohort.end))) {
126
+ content = content.replaceAll(`"version": ${JSON.stringify(releaseCohort.release.version)}`, `"version": ${version.name}`);
127
+ edits.push({
128
+ start: versionConstant.init.start,
129
+ end: versionConstant.init.end,
130
+ content: JSON.stringify(releaseCohort.release.version)
131
+ });
132
+ }
133
+ edits.push({
134
+ start: cohort.start,
135
+ end: cohort.end,
136
+ content
137
+ });
138
+ for (const edit of edits.toSorted((left, right)=>right.start - left.start))source = source.slice(0, edit.start) + edit.content + source.slice(edit.end);
139
+ return source;
140
+ } catch {
141
+ return source;
142
+ }
143
+ }
144
+ function preserveConsumerWorkspaceArtifacts(io, candidates) {
145
+ const preservedPaths = new Set();
146
+ const physicalRoot = external_node_fs_default().realpathSync(io.workspaceRoot);
147
+ const canonicalSources = (0, fs_io_cjs_namespaceObject.formatGeneratedSourceCandidates)(candidates.map((candidate, index)=>[
148
+ `canonical/${index}/${candidate.relativePath}`,
149
+ withoutGeneratedData(candidate.content, candidate.generatedDataBinding)
150
+ ]));
151
+ for (const [index, candidate] of candidates.entries()){
152
+ const paths = [
153
+ candidate.relativePath,
154
+ candidate.legacyPath
155
+ ].filter((value)=>void 0 !== value);
156
+ for (const relativePath of paths){
157
+ const filePath = external_node_path_default().join(io.workspaceRoot, relativePath);
158
+ if (!external_node_fs_default().existsSync(filePath)) continue;
159
+ const physicalRelative = external_node_path_default().relative(physicalRoot, external_node_fs_default().realpathSync(filePath));
160
+ if ('..' === physicalRelative || physicalRelative.startsWith(`..${external_node_path_default().sep}`) || external_node_path_default().isAbsolute(physicalRelative)) throw new Error(`Refusing to inspect an artifact outside the workspace: ${relativePath}`);
161
+ const source = external_node_fs_default().readFileSync(filePath, 'utf8');
162
+ let recognized = source === candidate.content;
163
+ if (!recognized) try {
164
+ const normalized = withoutGeneratedData(source, candidate.generatedDataBinding);
165
+ const canonical = canonicalSources[index];
166
+ recognized = normalized === canonical || (0, fs_io_cjs_namespaceObject.formatGeneratedSourceCandidates)([
167
+ [
168
+ relativePath,
169
+ normalized
170
+ ]
171
+ ])[0] === canonical;
172
+ } catch {}
173
+ if (!recognized) for (const pairedPath of paths)preservedPaths.add(pairedPath);
174
+ }
175
+ }
176
+ const reported = new Set();
177
+ const isPreserved = (filePath)=>{
178
+ const relativePath = external_node_path_default().relative(io.workspaceRoot, filePath).split(external_node_path_default().sep).join('/');
179
+ if (!preservedPaths.has(relativePath)) return false;
180
+ if (!reported.has(relativePath)) {
181
+ io.log(`${relativePath} preserved consumer-owned artifact: its canonical generated source does not match.`);
182
+ reported.add(relativePath);
183
+ }
184
+ return true;
185
+ };
186
+ return {
187
+ preservedPaths,
188
+ refreshReleaseCohort (releaseCohort) {
189
+ if (!releaseCohort) return;
190
+ for (const candidate of candidates)if ('workspaceValidationContract' === candidate.generatedDataBinding) for (const relativePath of [
191
+ candidate.relativePath,
192
+ candidate.legacyPath
193
+ ]){
194
+ if (!relativePath || !preservedPaths.has(relativePath)) continue;
195
+ const filePath = external_node_path_default().join(io.workspaceRoot, relativePath);
196
+ if (!external_node_fs_default().existsSync(filePath)) continue;
197
+ const source = external_node_fs_default().readFileSync(filePath, 'utf8');
198
+ io.write(filePath, refreshValidatorReleaseCohort(source, releaseCohort));
199
+ }
200
+ },
201
+ io: {
202
+ ...io,
203
+ write: (filePath, content)=>isPreserved(filePath) ? false : io.write(filePath, content),
204
+ writeGenerated: (filePath, content)=>isPreserved(filePath) ? false : io.writeGenerated(filePath, content),
205
+ remove: (filePath)=>isPreserved(filePath) ? false : io.remove(filePath)
206
+ }
207
+ };
208
+ }
209
+ exports.preserveConsumerWorkspaceArtifacts = __webpack_exports__.preserveConsumerWorkspaceArtifacts;
210
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
211
+ "preserveConsumerWorkspaceArtifacts"
212
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
213
+ Object.defineProperty(exports, '__esModule', {
214
+ value: true
215
+ });