@mnci/cli 4.2.4 → 4.3.1

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.
package/dist/cli.js CHANGED
@@ -859,8 +859,9 @@ var NPM_AUDIT_STEP = `node -e "const cp=require('node:child_process');const r=cp
859
859
  var VERIFY_TARGETS = "lint,typecheck,test,build";
860
860
  var AFFECTED_OR_ALL_GUARD = `node -e "const cp=require('node:child_process');const T='${VERIFY_TARGETS}';const all=()=>process.exit(cp.spawnSync('npx nx run-many -t '+T,{stdio:'inherit',shell:true}).status ?? 1);const ref=process.env.GITHUB_BASE_REF||process.env.SYSTEM_PULLREQUEST_TARGETBRANCH||'';if(!ref){console.log('Not a pull request - verifying EVERY project.');all()}const target=ref.replace('refs/heads/','');const mergeBase=r=>{const o=cp.spawnSync('git',['merge-base',r,'HEAD'],{encoding:'utf8'});return o.status===0?o.stdout.trim():''};let base=mergeBase('origin/'+target);if(!base){console.log('No origin/'+target+' ref - fetching it to resolve a merge-base.');cp.spawnSync('git',['fetch','--no-tags','origin',target],{stdio:'inherit'});base=mergeBase('FETCH_HEAD')}if(!base){console.log('Could not resolve a merge-base with '+target+' - verifying EVERY project.');all()}console.log('Pull request against '+target+' - verifying projects affected since '+base);process.exit(cp.spawnSync('npx nx affected -t '+T+' --base='+base,{stdio:'inherit',shell:true}).status ?? 1)"`;
861
861
  var PACK_APPS_GUARD = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const hasProjectJson=fs.globSync('apps/*/project.json').length>0;const hasInlineNx=fs.globSync('apps/*/package.json').some((f)=>{try{return Boolean(JSON.parse(fs.readFileSync(f,'utf8')).nx)}catch{return false}});const hasCsproj=fs.globSync('apps/*/*.csproj').length>0;if(!hasProjectJson&&!hasInlineNx&&!hasCsproj){console.log('No apps to pack - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('npx nx run-many -t package',{stdio:'inherit',shell:true}).status ?? 1)"`;
862
+ var SHALLOW_CLONE_GUARD = `node -e "const r=require('node:child_process').spawnSync('git',['rev-parse','--is-shallow-repository'],{encoding:'utf8'});if(r.status!==0){console.error('Could not determine whether this checkout has full history (git rev-parse --is-shallow-repository failed) - refusing to release. '+(r.stderr||'').trim());process.exit(1)}if(r.stdout.trim()==='true'){console.error('This checkout is a shallow clone. nx release resolves the current version of each package from its git tag, and silently falls back to the permanently-stale on-disk version when a tag cannot be found - which can propose, and publish, a version DOWNGRADE. Fetch full history before releasing - set fetchDepth (Azure) or fetch-depth (GitHub) to 0.');process.exit(1)}"`;
862
863
  function releaseGuard(pythonPublishEnv, nugetPublishEnv) {
863
- return `node -e "const fs=require('node:fs'),cp=require('node:child_process');const hasNpm=fs.globSync('packages/*/package.json').length>0;const hasPython=fs.globSync('python-packages/*/pyproject.toml').length>0;const hasCsharp=fs.globSync('packages/*/*.csproj').length>0;if(!hasNpm&&!hasPython&&!hasCsharp){console.log('Nothing to release - skipping.');process.exit(0)}const env={...process.env};${pythonPublishEnv}${nugetPublishEnv}process.exit(cp.spawnSync('npx nx release --yes',{stdio:'inherit',shell:true,env}).status ?? 1)"`;
864
+ return String.raw`node -e "const fs=require('node:fs'),cp=require('node:child_process');const npmCount=fs.globSync('packages/*/package.json').length;const csharpCount=fs.globSync('packages/*/*.csproj').length;const pythonCount=fs.globSync('python-packages/*/pyproject.toml').length;const hasNpm=npmCount>0;const hasPython=pythonCount>0;const hasCsharp=csharpCount>0;if(!hasNpm&&!hasPython&&!hasCsharp){console.log('Nothing to release - skipping.');process.exit(0)}const specifier=process.env.RELEASE_SPECIFIER||'';let releaseCmd='npx nx release --yes';if(specifier){if(!/^(major|minor|patch|\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?)$/.test(specifier)){console.error('RELEASE_SPECIFIER value \''+specifier+'\' is invalid - use major, minor, patch, or an exact version like 1.2.3.');process.exit(1)}const releaseProjectCount=npmCount+csharpCount+pythonCount;if(/^(major|minor|patch)$/.test(specifier)&&releaseProjectCount>1){console.error('RELEASE_SPECIFIER is a keyword (\''+specifier+'\') but this workspace has '+releaseProjectCount+' releasable packages - a keyword under-bumps interdependent packages, because nx computes the dependency-bump pass from a stale cached version. Set RELEASE_SPECIFIER to an exact version instead, or clear it.');process.exit(1)}releaseCmd='npx nx release '+specifier+' --yes'}const env={...process.env};${pythonPublishEnv}${nugetPublishEnv}process.exit(cp.spawnSync(releaseCmd,{stdio:'inherit',shell:true,env}).status ?? 1)"`;
864
865
  }
865
866
  function pythonPublishEnvFragment(pythonPublishUrl2) {
866
867
  return pythonPublishUrl2 ? `if(hasPython){env.TWINE_REPOSITORY_URL='${pythonPublishUrl2}';env.TWINE_USERNAME='AzureArtifacts';env.TWINE_PASSWORD=Buffer.from(process.env.PAT,'base64').toString()}` : "";
@@ -943,6 +944,18 @@ variables:
943
944
  # agent OS.
944
945
  - name: npm_config_cache
945
946
  value: $(Pipeline.Workspace)/.npm
947
+ # Overrides the bump nx would compute from conventional commits for one
948
+ # release run \u2014 'major', 'minor', 'patch', or an exact version ('1.2.3').
949
+ # Defined here (rather than left unset) so $(RELEASE_SPECIFIER) always
950
+ # expands: an Azure Pipelines macro that names an undefined variable is
951
+ # left as the literal, unexpanded text '$(RELEASE_SPECIFIER)' rather than
952
+ # empty, which would otherwise reach the release guard below as a bogus
953
+ # value. Override it per run in Pipelines -> Run pipeline -> Variables, or
954
+ # set a repo-level default in Pipeline -> Edit -> Variables. See the
955
+ # release step below for why a bare keyword is unreliable once more than
956
+ # one package is releasable.
957
+ - name: RELEASE_SPECIFIER
958
+ value: ''
946
959
 
947
960
  steps:
948
961
  - checkout: self
@@ -1100,17 +1113,41 @@ steps:
1100
1113
  displayName: Tag the run per app (type-name)
1101
1114
  condition: ${onMain}
1102
1115
 
1116
+ # nx release resolves each package's current version from its git tag, and
1117
+ # falls back to the (permanently stale, since git.commit is false) on-disk
1118
+ # version when a tag cannot be resolved \u2014 which happens whenever this
1119
+ # checkout lacks full history. This is currently guaranteed by fetchDepth 0
1120
+ # above plus the explicit fetch below, but neither is expressed as a
1121
+ # dependency anywhere else, so this makes it a hard, loud precondition
1122
+ # instead of a silently wrong version discovered after release.
1123
+ - script: ${SHALLOW_CLONE_GUARD}
1124
+ displayName: Verify this is a full checkout (nx release needs the real tag history)
1125
+ condition: ${onMain}
1126
+
1103
1127
  # Version + tag + publish, in one release, for npm (packages/*), Python
1104
1128
  # (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional commits,
1105
1129
  # tag-only push. Portable guard: nx release errors on an empty scope, so
1106
1130
  # skip cleanly when there is nothing to release. When there are Python or
1107
1131
  # C# packages and an Azure feed, twine/NuGet publish credentials are
1108
1132
  # exported (raw PAT, decoded from the base64 variable).
1133
+ #
1134
+ # RELEASE_SPECIFIER (the pipeline variable above) overrides the bump nx
1135
+ # would compute from conventional commits for THIS run. In a workspace with
1136
+ # more than one releasable package, a bare keyword ('major'/'minor'/'patch')
1137
+ # is unreliable \u2014 nx versions interdependent packages in two passes (a
1138
+ # dependency-bump pass, then the specifier pass), and the second pass
1139
+ # computes from a version cached before the first pass ran, silently
1140
+ # landing back on the same patch bump either way. An exact version ('1.2.3')
1141
+ # does not have this problem, since both passes apply it verbatim \u2014 prefer
1142
+ # it whenever more than one package is releasable. The guard below fails
1143
+ # the run rather than under-bumping silently: clear the variable back to
1144
+ # '' once the override is no longer needed.
1109
1145
  - script: ${releaseGuard(pythonPublishEnvFragment(pythonPublishUrl2), nugetPublishEnvFragment(nugetFeedUrl2))}
1110
1146
  displayName: Release \u2014 version, tag and publish (npm + Python + C#)
1111
1147
  condition: ${onMain}
1112
1148
  env:
1113
1149
  ${npmAuthName}: ${npmAuthValue}
1150
+ RELEASE_SPECIFIER: $(RELEASE_SPECIFIER)
1114
1151
 
1115
1152
  # nx release's own git push (release.git.push) is deliberately left off: it
1116
1153
  # only runs when a remote GitHub/GitLab Release is configured, which this
@@ -1301,12 +1338,38 @@ jobs:
1301
1338
  path: dist/drop
1302
1339
  if-no-files-found: ignore
1303
1340
 
1341
+ # nx release resolves each package's current version from its git tag,
1342
+ # and falls back to the (permanently stale, since git.commit is false)
1343
+ # on-disk version when a tag cannot be resolved \u2014 which happens
1344
+ # whenever this checkout lacks full history. This is currently
1345
+ # guaranteed by fetch-depth 0 above plus the explicit fetch below, but
1346
+ # neither is expressed as a dependency anywhere else, so this makes it
1347
+ # a hard, loud precondition instead of a silently wrong version
1348
+ # discovered after release.
1349
+ - run: ${SHALLOW_CLONE_GUARD}
1350
+ name: Verify this is a full checkout (nx release needs the real tag history)
1351
+ if: \${{ ${onMain} }}
1352
+
1304
1353
  # Version + tag + publish, in one release, for npm (packages/*), Python
1305
1354
  # (python-packages/*) AND C# (packages/*/*.csproj) \u2014 conventional
1306
1355
  # commits, tag-only push. Portable guard: nx release errors on an empty
1307
1356
  # scope, so skip cleanly when there is nothing to release. When there
1308
1357
  # are Python or C# packages and an Azure feed, twine/NuGet publish
1309
- # credentials are exported (raw PAT, decoded from the base64 secret).${githubReleases ? `
1358
+ # credentials are exported (raw PAT, decoded from the base64 secret).
1359
+ #
1360
+ # RELEASE_SPECIFIER (repository variable, Settings -> Secrets and
1361
+ # variables -> Actions -> Variables) overrides the bump nx would compute
1362
+ # from conventional commits for THIS run: 'major', 'minor', 'patch', or
1363
+ # an exact version ('1.2.3'). In a workspace with more than one
1364
+ # releasable package, a bare keyword is unreliable \u2014 nx versions
1365
+ # interdependent packages in two passes (a dependency-bump pass, then
1366
+ # the specifier pass), and the second pass computes from a version
1367
+ # cached before the first pass ran, silently landing back on the same
1368
+ # patch bump either way. An exact version does not have this problem,
1369
+ # since both passes apply it verbatim \u2014 prefer it whenever more than one
1370
+ # package is releasable. The guard below fails the run rather than
1371
+ # under-bumping silently: unset or clear the variable once the override
1372
+ # is no longer needed.${githubReleases ? `
1310
1373
  # This provider also creates a per-project GitHub Release (changelog
1311
1374
  # generated from conventional commits since that project's last tag),
1312
1375
  # which is why 'nx release' pushes the tag itself here \u2014 see
@@ -1316,7 +1379,8 @@ jobs:
1316
1379
  name: Release \u2014 version, tag${githubReleases ? ", publish and GitHub Release" : " and publish"} (npm + Python + C#)
1317
1380
  if: \${{ ${onMain} }}
1318
1381
  env:
1319
- ${npmAuthName}: ${npmAuthValue}${githubReleases ? `
1382
+ ${npmAuthName}: ${npmAuthValue}
1383
+ RELEASE_SPECIFIER: \${{ vars.RELEASE_SPECIFIER }}${githubReleases ? `
1320
1384
  GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}` : ""}
1321
1385
  ${githubReleases ? "" : `
1322
1386
  # nx release's own git push (release.git.push) is deliberately left off: it
@@ -1675,35 +1739,14 @@ var SOURCEMAP_PATH_TRANSFORM = [
1675
1739
  " },",
1676
1740
  ""
1677
1741
  ].join("\n");
1678
- var ROLLUP_CONFIG_WITH_DTS_FIX = [
1679
- " {",
1680
- " // Added by MoNecromanCI. @nx/rollup's dts-bundle plugin writes dist/index.d.ts",
1681
- " // as a stub re-exporting the real declarations, and builds that specifier with",
1682
- " // path.relative() - an OS-NATIVE path. On Windows it emits",
1683
- String.raw` // export * from "./src\\index";`,
1684
- " // which is not a valid module specifier on ANY platform: a specifier is",
1685
- " // URL-style, so / is correct everywhere and a backslash nowhere. It resolves on",
1686
- " // Windows only because the resolver normalises separators there, leaving the",
1687
- " // package untyped on Linux and macOS.",
1688
- " //",
1689
- " // mnci also points `types` past this stub, so nothing depends on it being",
1690
- " // correct; this makes the emitted file correct too. Remove once Nx fixes the",
1691
- " // plugin - its own devkit already exports normalizePath for exactly this.",
1692
- " //",
1693
- " // The second half fixes a separate defect in the REAL declarations `types`",
1694
- ' // points at: tsconfig.lib.json declares under moduleResolution "bundler",',
1695
- ' // where a bare relative specifier ("./lib/align") is valid, so every emitted',
1696
- " // .d.ts keeps the source's own extensionless imports verbatim. A consumer on",
1697
- ' // "moduleResolution": "nodenext" - the workspace root default - requires an',
1698
- " // explicit extension on every relative specifier and gets TS2834 (or,",
1699
- " // combined with skipLibCheck, a silent zero-export module) instead. Declared",
1700
- " // extensions are left untouched; only a bare relative specifier gets .js",
1701
- " // appended, matching what tsc itself emits under node16/nodenext.",
1702
- " plugins: [",
1742
+ var DECLARATION_SPECIFIER_PLUGIN_MARKER = "name: 'mnci-normalise-declaration-specifiers'";
1743
+ var DECLARATION_SPECIFIER_EXTENSION_MARKER = "bareRelativeSpecifier";
1744
+ var DECLARATION_SPECIFIER_DIRECTORY_MARKER = "resolveSpecifierSuffix";
1745
+ var DECLARATION_SPECIFIER_PLUGIN = [
1703
1746
  " {",
1704
1747
  " name: 'mnci-normalise-declaration-specifiers',",
1705
1748
  " writeBundle (outputOptions) {",
1706
- " const { readdirSync, readFileSync, writeFileSync } = require('node:fs')",
1749
+ " const { existsSync, readdirSync, readFileSync, writeFileSync } = require('node:fs')",
1707
1750
  " const { join } = require('node:path')",
1708
1751
  " const dir = outputOptions.dir ?? './dist'",
1709
1752
  " const stub = join(dir, 'index.d.ts')",
@@ -1721,7 +1764,7 @@ var ROLLUP_CONFIG_WITH_DTS_FIX = [
1721
1764
  " const normalised = source.replaceAll(separator, '/')",
1722
1765
  " if (normalised !== source) writeFileSync(stub, normalised)",
1723
1766
  "",
1724
- String.raw` const bareRelativeSpecifier = /from(\s+)(['"])(\.[^'"]+?)\2/g`,
1767
+ String.raw` const ${DECLARATION_SPECIFIER_EXTENSION_MARKER} = /from(\s+)(['"])(\.[^'"]+?)\2/g`,
1725
1768
  String.raw` const hasExtension = /\.(?:mjs|cjs|jsx?|json)$/`,
1726
1769
  " let entries",
1727
1770
  " try {",
@@ -1731,25 +1774,115 @@ var ROLLUP_CONFIG_WITH_DTS_FIX = [
1731
1774
  " }",
1732
1775
  " for (const entry of entries) {",
1733
1776
  " if (!entry.name.endsWith('.d.ts')) continue",
1734
- " const filePath = join(entry.parentPath ?? entry.path, entry.name)",
1777
+ " const from = entry.parentPath ?? entry.path",
1778
+ " const filePath = join(from, entry.name)",
1735
1779
  " let declaration",
1736
1780
  " try {",
1737
1781
  " declaration = readFileSync(filePath, 'utf8')",
1738
1782
  " } catch {",
1739
1783
  " continue",
1740
1784
  " }",
1785
+ " // A bare specifier may name a FILE or a DIRECTORY BARREL - resolved",
1786
+ " // against what rollup actually emitted next to this file, never",
1787
+ " // guessed. A directory needs /index.js, not .js (a file that was",
1788
+ " // never written); anything neither form matches is left alone rather",
1789
+ " // than rewritten to a specifier that cannot resolve.",
1790
+ ` const ${DECLARATION_SPECIFIER_DIRECTORY_MARKER} = (specifier) => {`,
1791
+ " if (hasExtension.test(specifier)) return null",
1792
+ " if (existsSync(join(from, specifier + '.d.ts'))) return specifier + '.js'",
1793
+ " if (existsSync(join(from, specifier, 'index.d.ts'))) return specifier + '/index.js'",
1794
+ " return null",
1795
+ " }",
1741
1796
  " const withExtensions = declaration.replace(",
1742
- " bareRelativeSpecifier,",
1743
- " (match, space, quote, specifier) =>",
1744
- " hasExtension.test(specifier) ? match : `from${space}${quote}${specifier}.js${quote}`,",
1797
+ ` ${DECLARATION_SPECIFIER_EXTENSION_MARKER},`,
1798
+ " (match, space, quote, specifier) => {",
1799
+ ` const resolved = ${DECLARATION_SPECIFIER_DIRECTORY_MARKER}(specifier)`,
1800
+ " return resolved === null ? match : `from${space}${quote}${resolved}${quote}`",
1801
+ " },",
1745
1802
  " )",
1746
1803
  " if (withExtensions !== declaration) writeFileSync(filePath, withExtensions)",
1747
1804
  " }",
1748
1805
  " }",
1749
- " }",
1806
+ " }"
1807
+ ].join("\n");
1808
+ var ROLLUP_CONFIG_WITH_DTS_FIX = [
1809
+ " {",
1810
+ " // Added by MoNecromanCI. @nx/rollup's dts-bundle plugin writes dist/index.d.ts",
1811
+ " // as a stub re-exporting the real declarations, and builds that specifier with",
1812
+ " // path.relative() - an OS-NATIVE path. On Windows it emits",
1813
+ String.raw` // export * from "./src\\index";`,
1814
+ " // which is not a valid module specifier on ANY platform: a specifier is",
1815
+ " // URL-style, so / is correct everywhere and a backslash nowhere. It resolves on",
1816
+ " // Windows only because the resolver normalises separators there, leaving the",
1817
+ " // package untyped on Linux and macOS.",
1818
+ " //",
1819
+ " // mnci also points `types` past this stub, so nothing depends on it being",
1820
+ " // correct; this makes the emitted file correct too. Remove once Nx fixes the",
1821
+ " // plugin - its own devkit already exports normalizePath for exactly this.",
1822
+ " //",
1823
+ " // The second half fixes a separate defect in the REAL declarations `types`",
1824
+ ' // points at: tsconfig.lib.json declares under moduleResolution "bundler",',
1825
+ ' // where a bare relative specifier ("./lib/align") is valid, so every emitted',
1826
+ " // .d.ts keeps the source's own extensionless imports verbatim. A consumer on",
1827
+ ' // "moduleResolution": "nodenext" - the workspace root default - requires an',
1828
+ " // explicit extension on every relative specifier and gets TS2834 (or,",
1829
+ " // combined with skipLibCheck, a silent zero-export module) instead. Declared",
1830
+ " // extensions are left untouched; only a bare relative specifier gets .js",
1831
+ " // appended, matching what tsc itself emits under node16/nodenext.",
1832
+ " plugins: [",
1833
+ DECLARATION_SPECIFIER_PLUGIN,
1750
1834
  " ]",
1751
1835
  " }"
1752
1836
  ].join("\n");
1837
+ function findEnclosingBraceSpan(text, needle) {
1838
+ const needleIndex = text.indexOf(needle);
1839
+ if (needleIndex === -1) {
1840
+ return void 0;
1841
+ }
1842
+ const start = text.lastIndexOf("{", needleIndex);
1843
+ if (start === -1) {
1844
+ return void 0;
1845
+ }
1846
+ let depth = 0;
1847
+ for (let index = start; index < text.length; index += 1) {
1848
+ if (text[index] === "{") {
1849
+ depth += 1;
1850
+ } else if (text[index] === "}") {
1851
+ depth -= 1;
1852
+ if (depth === 0) {
1853
+ return [start, index + 1];
1854
+ }
1855
+ }
1856
+ }
1857
+ return void 0;
1858
+ }
1859
+ function withUpgradedDeclarationSpecifierPlugin(config) {
1860
+ if (!config.includes(DECLARATION_SPECIFIER_PLUGIN_MARKER) || config.includes(DECLARATION_SPECIFIER_DIRECTORY_MARKER)) {
1861
+ return config;
1862
+ }
1863
+ const span = findEnclosingBraceSpan(config, DECLARATION_SPECIFIER_PLUGIN_MARKER);
1864
+ if (!span) {
1865
+ return config;
1866
+ }
1867
+ const [start, end] = span;
1868
+ return `${config.slice(0, start)}${DECLARATION_SPECIFIER_PLUGIN}${config.slice(end)}`;
1869
+ }
1870
+ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
1871
+ const changed = [];
1872
+ const configs = (0, import_node_fs3.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
1873
+ cwd: workspaceRoot
1874
+ });
1875
+ for (const relativePath of configs) {
1876
+ const configPath = (0, import_node_path3.join)(workspaceRoot, relativePath);
1877
+ const before = (0, import_node_fs3.readFileSync)(configPath, "utf8");
1878
+ const after = withUpgradedDeclarationSpecifierPlugin(before);
1879
+ if (after !== before) {
1880
+ writeFileEnsured(configPath, after);
1881
+ changed.push(relativePath.replaceAll("\\", "/"));
1882
+ }
1883
+ }
1884
+ return changed;
1885
+ }
1753
1886
  function repairDeclarationSpecifiers(projectRoot) {
1754
1887
  const configPath = (0, import_node_path3.join)(projectRoot, "rollup.config.cjs");
1755
1888
  if (!fileExists(configPath)) {
@@ -1812,6 +1945,22 @@ function repairPublishableManifest(manifestPath) {
1812
1945
  }
1813
1946
  writeFileEnsured(manifestPath, toJson(manifest));
1814
1947
  }
1948
+ function repairPublishableManifests(workspaceRoot) {
1949
+ const changed = [];
1950
+ const manifests = (0, import_node_fs3.globSync)(["packages/*/package.json", "libs/*/package.json"], {
1951
+ cwd: workspaceRoot
1952
+ });
1953
+ for (const relativePath of manifests) {
1954
+ const manifestPath = (0, import_node_path3.join)(workspaceRoot, relativePath);
1955
+ const before = (0, import_node_fs3.readFileSync)(manifestPath, "utf8");
1956
+ repairPublishableManifest(manifestPath);
1957
+ const after = (0, import_node_fs3.readFileSync)(manifestPath, "utf8");
1958
+ if (after !== before) {
1959
+ changed.push(relativePath.replaceAll("\\", "/"));
1960
+ }
1961
+ }
1962
+ return changed;
1963
+ }
1815
1964
  function ensureAdmZip(workspaceRoot) {
1816
1965
  if (hasPlugin(workspaceRoot, "adm-zip")) {
1817
1966
  return;
@@ -4318,6 +4467,20 @@ function runUpgrade(workspaceRoot, options) {
4318
4467
  logger.detail(`updated ${path}`);
4319
4468
  }
4320
4469
  }
4470
+ const repairedManifests = repairPublishableManifests(workspaceRoot);
4471
+ if (repairedManifests.length > 0) {
4472
+ logger.step("Repointing `types` at the real declaration file");
4473
+ for (const path of repairedManifests) {
4474
+ logger.detail(`updated ${path}`);
4475
+ }
4476
+ }
4477
+ const upgradedDtsPlugins = upgradeDeclarationSpecifierPlugins(workspaceRoot);
4478
+ if (upgradedDtsPlugins.length > 0) {
4479
+ logger.step("Upgrading declaration specifiers to resolve under nodenext");
4480
+ for (const path of upgradedDtsPlugins) {
4481
+ logger.detail(`updated ${path}`);
4482
+ }
4483
+ }
4321
4484
  logger.step(
4322
4485
  "Formatting the workspace (eslint --fix) \u2014 the slowest step, minutes on a large workspace"
4323
4486
  );