@mnci/cli 4.2.2 → 4.2.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.
- package/README.md +26 -0
- package/dist/cli.js +127 -38
- package/dist/cli.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -135,6 +135,32 @@ chain breaks, and the map comes out valid-looking and **empty** — `sources: []
|
|
|
135
135
|
Measured on a real package: swc gave 0 sources, babel gave 9. Revert the swap
|
|
136
136
|
once Nx passes `sourceMaps` through; ROADMAP 7d has the one-line upstream fix.
|
|
137
137
|
|
|
138
|
+
Re-measured against the exact toolchain `mnci new` pins today (Nx 23.2.0,
|
|
139
|
+
`@swc/core` 1.15.8): `@nx/rollup`'s swc plugin still does **not** pass
|
|
140
|
+
`sourceMaps` to `transform()` — read straight from the installed package, not
|
|
141
|
+
assumed — yet a real build with `compiler: 'swc'` left unmodified now emits a
|
|
142
|
+
map with real `sources`/`sourcesContent`, and tracing a generated position
|
|
143
|
+
through it with `@jridgewell/trace-mapping` resolves to the correct original
|
|
144
|
+
line and column. So the empty-map failure this section exists to route around
|
|
145
|
+
did not reproduce on the current pinned versions, even though the documented
|
|
146
|
+
root cause (the plugin's own missing `sourceMaps` option) is still there
|
|
147
|
+
verbatim. That is not the revert condition stated above — nothing upstream
|
|
148
|
+
changed the call this section is about — so the swap stays in place as a
|
|
149
|
+
safety net rather than being removed on an unexplained, unpinned-by-upstream
|
|
150
|
+
behavior change that a future `@swc/core` patch could revert without notice.
|
|
151
|
+
**A real, separate bug in the swap itself was found and fixed**, independent
|
|
152
|
+
of the above: it matched `compiler: 'swc'` with a plain string, one space
|
|
153
|
+
after the colon. `@stylistic/key-spacing` (aligned on value) — which
|
|
154
|
+
`eslint --fix` applies to every mnci-generated file — pads that column out to
|
|
155
|
+
whatever the object's longest key is, so on any config reached after even one
|
|
156
|
+
lint pass (most concretely: `mnci upgrade` repairing a project whose `add`
|
|
157
|
+
partially failed) the literal silently stopped matching and the swap
|
|
158
|
+
silently no-op'd, while `sourceMap: true` and `sourcemapPathTransform` — added
|
|
159
|
+
by separate, whitespace-tolerant repairs — went in regardless. `mnci doctor`'s
|
|
160
|
+
check did not catch it either, since it only verifies the flag, not the
|
|
161
|
+
compiler. Confirmed end to end and fixed with the same whitespace-tolerant
|
|
162
|
+
approach `sourceMap: true`'s own guard already used.
|
|
163
|
+
|
|
138
164
|
**The paths are wrong twice over.** rollup hands `sourcemapPathTransform` a
|
|
139
165
|
path like `..\..\src\index.ts` for a map in `dist/` — one parent segment too
|
|
140
166
|
many, so it resolves above the project to a file that does not exist, and
|
package/dist/cli.js
CHANGED
|
@@ -1262,7 +1262,7 @@ jobs:
|
|
|
1262
1262
|
# directly rather than a hand-rolled 'node -e' guard \u2014 see
|
|
1263
1263
|
# DOTNET_DETECT_AZURE's remarks for the full reasoning. hashFiles()
|
|
1264
1264
|
# gates it inline, so a JS-only workspace pays nothing.
|
|
1265
|
-
- uses: actions/setup-dotnet@
|
|
1265
|
+
- uses: actions/setup-dotnet@v6
|
|
1266
1266
|
if: \${{ hashFiles('apps/*/*.csproj', 'packages/*/*.csproj', 'libs/*/*.csproj') != '' }}
|
|
1267
1267
|
with:
|
|
1268
1268
|
dotnet-version: ${DOTNET_SDK_VERSION}
|
|
@@ -1392,6 +1392,24 @@ function removeNxScaffolding(workspaceRoot) {
|
|
|
1392
1392
|
function removeIfPresent(path) {
|
|
1393
1393
|
(0, import_node_fs2.rmSync)(path, { recursive: true, force: true });
|
|
1394
1394
|
}
|
|
1395
|
+
function ensureEslintCacheIgnored(workspaceRoot) {
|
|
1396
|
+
const gitignorePath = (0, import_node_path2.join)(workspaceRoot, ".gitignore");
|
|
1397
|
+
if (!fileExists(gitignorePath)) {
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
const current = (0, import_node_fs2.readFileSync)(gitignorePath, "utf8");
|
|
1401
|
+
if (current.split("\n").some((line) => line.trim() === ".eslintcache")) {
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
const withoutTrailingBlankLines = current.replace(/\n+$/, "");
|
|
1405
|
+
const separator = withoutTrailingBlankLines.length > 0 ? "\n\n" : "";
|
|
1406
|
+
writeFileEnsured(
|
|
1407
|
+
gitignorePath,
|
|
1408
|
+
`${withoutTrailingBlankLines}${separator}# Added by MoNecromanCI: \`npm run format\`/\`lint\` run \`eslint --cache\`.
|
|
1409
|
+
.eslintcache
|
|
1410
|
+
`
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1395
1413
|
function removeProjectEslintConfigs(workspaceRoot) {
|
|
1396
1414
|
const matches = (0, import_node_fs2.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
|
|
1397
1415
|
cwd: workspaceRoot
|
|
@@ -1468,6 +1486,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
|
|
|
1468
1486
|
markExecutable(hookPath);
|
|
1469
1487
|
onProgress("eslint.config.mjs \u2014 the shared lint AND formatting opinion");
|
|
1470
1488
|
writeFileEnsured((0, import_node_path2.join)(workspaceRoot, "eslint.config.mjs"), ESLINT_CONFIG);
|
|
1489
|
+
ensureEslintCacheIgnored(workspaceRoot);
|
|
1471
1490
|
for (const retired of RETIRED_FORMATTER_FILES) {
|
|
1472
1491
|
removeIfPresent((0, import_node_path2.join)(workspaceRoot, retired));
|
|
1473
1492
|
}
|
|
@@ -1528,6 +1547,23 @@ function ensurePlugin(workspaceRoot, packageName) {
|
|
|
1528
1547
|
logger.step(`Installing Nx plugin ${packageName}`);
|
|
1529
1548
|
runNx(["add", packageName], workspaceRoot);
|
|
1530
1549
|
}
|
|
1550
|
+
function runGeneratorAndRepair(workspaceRoot, nxArguments, markerPath, repair) {
|
|
1551
|
+
let installFailure;
|
|
1552
|
+
try {
|
|
1553
|
+
runNx(nxArguments, workspaceRoot);
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
installFailure = error instanceof Error ? error : new Error(String(error));
|
|
1556
|
+
}
|
|
1557
|
+
if (!fileExists(markerPath)) {
|
|
1558
|
+
throw installFailure ?? new Error(`unreachable: runNx did not throw and ${markerPath} is missing`);
|
|
1559
|
+
}
|
|
1560
|
+
repair();
|
|
1561
|
+
if (installFailure) {
|
|
1562
|
+
throw new Error(
|
|
1563
|
+
`The project was generated and mnci's own repairs were applied, but the underlying Nx generator's install step still failed (${installFailure.message}). Fix the install error above (commonly resolved by 'npm install' with a newer npm major), then verify with 'mnci doctor'.`
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1531
1567
|
function markPrivate(manifestPath) {
|
|
1532
1568
|
const manifest = readJson(manifestPath);
|
|
1533
1569
|
writeFileEnsured(manifestPath, toJson({ ...manifest, private: true }));
|
|
@@ -1547,13 +1583,15 @@ var ROLLUP_CONFIG_PLACEHOLDER = [
|
|
|
1547
1583
|
" // output: { sourcemap: true },",
|
|
1548
1584
|
" }"
|
|
1549
1585
|
].join("\n");
|
|
1550
|
-
var
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1586
|
+
var GENERATED_COMPILER_PATTERN = /^( {4})compiler\s*:\s*'swc',$/m;
|
|
1587
|
+
function sourceMapCapableCompiler(indent) {
|
|
1588
|
+
return [
|
|
1589
|
+
`${indent}// Swapped from swc by MoNecromanCI. @nx/rollup runs swc without`,
|
|
1590
|
+
`${indent}// sourceMaps, so it returns no map and the bundle's map comes out empty -`,
|
|
1591
|
+
`${indent}// valid-looking, and useless for debugging. See ROADMAP.`,
|
|
1592
|
+
`${indent}compiler: 'babel',`
|
|
1593
|
+
].join("\n");
|
|
1594
|
+
}
|
|
1557
1595
|
var ROLLUP_ARG_ONE_BOUNDARY = [" },", " {", ""].join("\n");
|
|
1558
1596
|
var ROLLUP_ARG_ONE_WITH_SOURCE_MAPS = [
|
|
1559
1597
|
" // Added by MoNecromanCI: without this rollup emits no .js.map at all, so",
|
|
@@ -1573,7 +1611,10 @@ function withRollupSourceMaps(config) {
|
|
|
1573
1611
|
if (hasRollupSourceMaps(config) || !canRepairRollupConfig(config)) {
|
|
1574
1612
|
return config;
|
|
1575
1613
|
}
|
|
1576
|
-
const withCompiler = config.replace(
|
|
1614
|
+
const withCompiler = config.replace(
|
|
1615
|
+
GENERATED_COMPILER_PATTERN,
|
|
1616
|
+
(_match, indent) => sourceMapCapableCompiler(indent)
|
|
1617
|
+
);
|
|
1577
1618
|
const withFlag = withCompiler.replace(
|
|
1578
1619
|
ROLLUP_ARG_ONE_BOUNDARY,
|
|
1579
1620
|
() => ROLLUP_ARG_ONE_WITH_SOURCE_MAPS
|
|
@@ -1648,13 +1689,24 @@ var ROLLUP_CONFIG_WITH_DTS_FIX = [
|
|
|
1648
1689
|
" // mnci also points `types` past this stub, so nothing depends on it being",
|
|
1649
1690
|
" // correct; this makes the emitted file correct too. Remove once Nx fixes the",
|
|
1650
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.",
|
|
1651
1702
|
" plugins: [",
|
|
1652
1703
|
" {",
|
|
1653
1704
|
" name: 'mnci-normalise-declaration-specifiers',",
|
|
1654
1705
|
" writeBundle (outputOptions) {",
|
|
1655
|
-
" const { readFileSync, writeFileSync } = require('node:fs')",
|
|
1706
|
+
" const { readdirSync, readFileSync, writeFileSync } = require('node:fs')",
|
|
1656
1707
|
" const { join } = require('node:path')",
|
|
1657
|
-
" const
|
|
1708
|
+
" const dir = outputOptions.dir ?? './dist'",
|
|
1709
|
+
" const stub = join(dir, 'index.d.ts')",
|
|
1658
1710
|
" let source",
|
|
1659
1711
|
" try {",
|
|
1660
1712
|
" source = readFileSync(stub, 'utf8')",
|
|
@@ -1668,6 +1720,31 @@ var ROLLUP_CONFIG_WITH_DTS_FIX = [
|
|
|
1668
1720
|
" const separator = String.fromCodePoint(92, 92)",
|
|
1669
1721
|
" const normalised = source.replaceAll(separator, '/')",
|
|
1670
1722
|
" if (normalised !== source) writeFileSync(stub, normalised)",
|
|
1723
|
+
"",
|
|
1724
|
+
String.raw` const bareRelativeSpecifier = /from(\s+)(['"])(\.[^'"]+?)\2/g`,
|
|
1725
|
+
String.raw` const hasExtension = /\.(?:mjs|cjs|jsx?|json)$/`,
|
|
1726
|
+
" let entries",
|
|
1727
|
+
" try {",
|
|
1728
|
+
" entries = readdirSync(dir, { recursive: true, withFileTypes: true })",
|
|
1729
|
+
" } catch {",
|
|
1730
|
+
" return",
|
|
1731
|
+
" }",
|
|
1732
|
+
" for (const entry of entries) {",
|
|
1733
|
+
" if (!entry.name.endsWith('.d.ts')) continue",
|
|
1734
|
+
" const filePath = join(entry.parentPath ?? entry.path, entry.name)",
|
|
1735
|
+
" let declaration",
|
|
1736
|
+
" try {",
|
|
1737
|
+
" declaration = readFileSync(filePath, 'utf8')",
|
|
1738
|
+
" } catch {",
|
|
1739
|
+
" continue",
|
|
1740
|
+
" }",
|
|
1741
|
+
" const withExtensions = declaration.replace(",
|
|
1742
|
+
" bareRelativeSpecifier,",
|
|
1743
|
+
" (match, space, quote, specifier) =>",
|
|
1744
|
+
" hasExtension.test(specifier) ? match : `from${space}${quote}${specifier}.js${quote}`,",
|
|
1745
|
+
" )",
|
|
1746
|
+
" if (withExtensions !== declaration) writeFileSync(filePath, withExtensions)",
|
|
1747
|
+
" }",
|
|
1671
1748
|
" }",
|
|
1672
1749
|
" }",
|
|
1673
1750
|
" ]",
|
|
@@ -2538,7 +2615,10 @@ function addNodeFunctionApp(workspaceRoot, name, stack) {
|
|
|
2538
2615
|
var import_node_path8 = require("path");
|
|
2539
2616
|
async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
2540
2617
|
const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
|
|
2541
|
-
|
|
2618
|
+
const projectRoot = (0, import_node_path8.join)(workspaceRoot, "packages", name);
|
|
2619
|
+
const manifestPath = (0, import_node_path8.join)(projectRoot, "package.json");
|
|
2620
|
+
runGeneratorAndRepair(
|
|
2621
|
+
workspaceRoot,
|
|
2542
2622
|
[
|
|
2543
2623
|
"g",
|
|
2544
2624
|
"@nx/js:lib",
|
|
@@ -2550,15 +2630,16 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
2550
2630
|
"--linter=none",
|
|
2551
2631
|
"--no-interactive"
|
|
2552
2632
|
],
|
|
2553
|
-
|
|
2633
|
+
manifestPath,
|
|
2634
|
+
() => {
|
|
2635
|
+
markPublic(manifestPath);
|
|
2636
|
+
repairPublishableManifest(manifestPath);
|
|
2637
|
+
repairDeclarationSpecifiers(projectRoot);
|
|
2638
|
+
writeProjectReadme(projectRoot, `${scope}/${name}`, stack.testRunner);
|
|
2639
|
+
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
2640
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2641
|
+
}
|
|
2554
2642
|
);
|
|
2555
|
-
const manifestPath = (0, import_node_path8.join)(workspaceRoot, "packages", name, "package.json");
|
|
2556
|
-
markPublic(manifestPath);
|
|
2557
|
-
repairPublishableManifest(manifestPath);
|
|
2558
|
-
repairDeclarationSpecifiers((0, import_node_path8.join)(workspaceRoot, `packages/${name}`));
|
|
2559
|
-
writeProjectReadme((0, import_node_path8.join)(workspaceRoot, `packages/${name}`), `${scope}/${name}`, stack.testRunner);
|
|
2560
|
-
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
2561
|
-
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2562
2643
|
}
|
|
2563
2644
|
|
|
2564
2645
|
// src/commands/add/python.ts
|
|
@@ -2862,7 +2943,10 @@ var REACT_LIB_BUNDLER = "rollup";
|
|
|
2862
2943
|
async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
2863
2944
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
2864
2945
|
const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
|
|
2865
|
-
|
|
2946
|
+
const projectRoot = (0, import_node_path11.join)(workspaceRoot, "packages", name);
|
|
2947
|
+
const publishableManifest = (0, import_node_path11.join)(projectRoot, "package.json");
|
|
2948
|
+
runGeneratorAndRepair(
|
|
2949
|
+
workspaceRoot,
|
|
2866
2950
|
[
|
|
2867
2951
|
"g",
|
|
2868
2952
|
"@nx/react:library",
|
|
@@ -2875,19 +2959,23 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
2875
2959
|
"--linter=none",
|
|
2876
2960
|
"--no-interactive"
|
|
2877
2961
|
],
|
|
2878
|
-
|
|
2962
|
+
publishableManifest,
|
|
2963
|
+
() => {
|
|
2964
|
+
markPublic(publishableManifest);
|
|
2965
|
+
repairPublishableManifest(publishableManifest);
|
|
2966
|
+
repairDeclarationSpecifiers(projectRoot);
|
|
2967
|
+
writeProjectReadme(projectRoot, `${scope}/${name}`, stack.testRunner);
|
|
2968
|
+
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
2969
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2970
|
+
}
|
|
2879
2971
|
);
|
|
2880
|
-
const publishableManifest = (0, import_node_path11.join)(workspaceRoot, "packages", name, "package.json");
|
|
2881
|
-
markPublic(publishableManifest);
|
|
2882
|
-
repairPublishableManifest(publishableManifest);
|
|
2883
|
-
repairDeclarationSpecifiers((0, import_node_path11.join)(workspaceRoot, "packages", name));
|
|
2884
|
-
writeProjectReadme((0, import_node_path11.join)(workspaceRoot, "packages", name), `${scope}/${name}`, stack.testRunner);
|
|
2885
|
-
removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
|
|
2886
|
-
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2887
2972
|
}
|
|
2888
2973
|
function addReactInternalLib(workspaceRoot, name, stack) {
|
|
2889
2974
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
2890
|
-
|
|
2975
|
+
const projectRoot = (0, import_node_path11.join)(workspaceRoot, "libs", name);
|
|
2976
|
+
const privateManifest = (0, import_node_path11.join)(projectRoot, "package.json");
|
|
2977
|
+
runGeneratorAndRepair(
|
|
2978
|
+
workspaceRoot,
|
|
2891
2979
|
[
|
|
2892
2980
|
"g",
|
|
2893
2981
|
"@nx/react:library",
|
|
@@ -2898,15 +2986,16 @@ function addReactInternalLib(workspaceRoot, name, stack) {
|
|
|
2898
2986
|
"--linter=none",
|
|
2899
2987
|
"--no-interactive"
|
|
2900
2988
|
],
|
|
2901
|
-
|
|
2989
|
+
privateManifest,
|
|
2990
|
+
() => {
|
|
2991
|
+
markPrivate(privateManifest);
|
|
2992
|
+
repairPublishableManifest(privateManifest);
|
|
2993
|
+
repairDeclarationSpecifiers(projectRoot);
|
|
2994
|
+
writeProjectReadme(projectRoot, name, stack.testRunner);
|
|
2995
|
+
removeGeneratedEslintConfig(workspaceRoot, `libs/${name}`);
|
|
2996
|
+
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2997
|
+
}
|
|
2902
2998
|
);
|
|
2903
|
-
const privateManifest = (0, import_node_path11.join)(workspaceRoot, "libs", name, "package.json");
|
|
2904
|
-
markPrivate(privateManifest);
|
|
2905
|
-
repairPublishableManifest(privateManifest);
|
|
2906
|
-
repairDeclarationSpecifiers((0, import_node_path11.join)(workspaceRoot, "libs", name));
|
|
2907
|
-
writeProjectReadme((0, import_node_path11.join)(workspaceRoot, "libs", name), name, stack.testRunner);
|
|
2908
|
-
removeGeneratedEslintConfig(workspaceRoot, `libs/${name}`);
|
|
2909
|
-
registerProjectCommands(workspaceRoot, name, { build: true });
|
|
2910
2999
|
}
|
|
2911
3000
|
|
|
2912
3001
|
// src/commands/sync.ts
|