@mf-toolkit/shared-inspector 0.3.1 → 0.4.0
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 +196 -130
- package/dist/cli/args.d.ts +5 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +98 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/colorize-report.d.ts +6 -0
- package/dist/cli/colorize-report.d.ts.map +1 -0
- package/dist/cli/colorize-report.js +71 -0
- package/dist/cli/colorize-report.js.map +1 -0
- package/dist/cli/colors.d.ts +14 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +26 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +30 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +62 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/interactive.d.ts +8 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +41 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/run-federation.d.ts +3 -0
- package/dist/cli/run-federation.d.ts.map +1 -0
- package/dist/cli/run-federation.js +41 -0
- package/dist/cli/run-federation.js.map +1 -0
- package/dist/cli/run-project.d.ts +5 -0
- package/dist/cli/run-project.d.ts.map +1 -0
- package/dist/cli/run-project.js +57 -0
- package/dist/cli/run-project.js.map +1 -0
- package/dist/cli/spinner.d.ts +10 -0
- package/dist/cli/spinner.d.ts.map +1 -0
- package/dist/cli/spinner.js +45 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/types.d.ts +17 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/reporter/diagnostics.d.ts +23 -0
- package/dist/reporter/diagnostics.d.ts.map +1 -0
- package/dist/reporter/diagnostics.js +138 -0
- package/dist/reporter/diagnostics.js.map +1 -0
- package/dist/reporter/format-federation-report.d.ts +11 -5
- package/dist/reporter/format-federation-report.d.ts.map +1 -1
- package/dist/reporter/format-federation-report.js +78 -37
- package/dist/reporter/format-federation-report.js.map +1 -1
- package/dist/reporter/format-report.d.ts +14 -7
- package/dist/reporter/format-report.d.ts.map +1 -1
- package/dist/reporter/format-report.js +67 -38
- package/dist/reporter/format-report.js.map +1 -1
- package/dist/reporter/scoring.d.ts +28 -0
- package/dist/reporter/scoring.d.ts.map +1 -0
- package/dist/reporter/scoring.js +74 -0
- package/dist/reporter/scoring.js.map +1 -0
- package/package.json +5 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const isTTY: boolean;
|
|
2
|
+
export declare const bold: (s: string) => string;
|
|
3
|
+
export declare const dim: (s: string) => string;
|
|
4
|
+
export declare const italic: (s: string) => string;
|
|
5
|
+
export declare const red: (s: string) => string;
|
|
6
|
+
export declare const yellow: (s: string) => string;
|
|
7
|
+
export declare const green: (s: string) => string;
|
|
8
|
+
export declare const cyan: (s: string) => string;
|
|
9
|
+
export declare const blue: (s: string) => string;
|
|
10
|
+
export declare const magenta: (s: string) => string;
|
|
11
|
+
export declare const gray: (s: string) => string;
|
|
12
|
+
/** Combine two color transforms. */
|
|
13
|
+
export declare function combine(...fns: Array<(s: string) => string>): (s: string) => string;
|
|
14
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/cli/colors.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK,EAAE,OAGY,CAAC;AAQjC,eAAO,MAAM,IAAI,MAHJ,MAAM,WAGoB,CAAC;AACxC,eAAO,MAAM,GAAG,MAJH,MAAM,WAIoB,CAAC;AACxC,eAAO,MAAM,MAAM,MALN,MAAM,WAKoB,CAAC;AACxC,eAAO,MAAM,GAAG,MANH,MAAM,WAMoB,CAAC;AACxC,eAAO,MAAM,MAAM,MAPN,MAAM,WAOoB,CAAC;AACxC,eAAO,MAAM,KAAK,MARL,MAAM,WAQoB,CAAC;AACxC,eAAO,MAAM,IAAI,MATJ,MAAM,WASoB,CAAC;AACxC,eAAO,MAAM,IAAI,MAVJ,MAAM,WAUoB,CAAC;AACxC,eAAO,MAAM,OAAO,MAXP,MAAM,WAWoB,CAAC;AACxC,eAAO,MAAM,IAAI,MAZJ,MAAM,WAYoB,CAAC;AAExC,oCAAoC;AACpC,wBAAgB,OAAO,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAEnF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// ─── ANSI color helpers ───────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// No external dependencies — plain escape codes.
|
|
4
|
+
// Auto-disabled when stdout is not a TTY or NO_COLOR env var is set.
|
|
5
|
+
export const isTTY = Boolean(process.stdout.isTTY) &&
|
|
6
|
+
!process.env['NO_COLOR'] &&
|
|
7
|
+
process.env['TERM'] !== 'dumb';
|
|
8
|
+
const ESC = '\x1b[';
|
|
9
|
+
function wrap(code, reset) {
|
|
10
|
+
return (s) => (isTTY ? `${ESC}${code}m${s}${ESC}${reset}m` : s);
|
|
11
|
+
}
|
|
12
|
+
export const bold = wrap('1', '22');
|
|
13
|
+
export const dim = wrap('2', '22');
|
|
14
|
+
export const italic = wrap('3', '23');
|
|
15
|
+
export const red = wrap('31', '39');
|
|
16
|
+
export const yellow = wrap('33', '39');
|
|
17
|
+
export const green = wrap('32', '39');
|
|
18
|
+
export const cyan = wrap('36', '39');
|
|
19
|
+
export const blue = wrap('34', '39');
|
|
20
|
+
export const magenta = wrap('35', '39');
|
|
21
|
+
export const gray = wrap('90', '39');
|
|
22
|
+
/** Combine two color transforms. */
|
|
23
|
+
export function combine(...fns) {
|
|
24
|
+
return (s) => fns.reduce((acc, fn) => fn(acc), s);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/cli/colors.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,iDAAiD;AACjD,qEAAqE;AAErE,MAAM,CAAC,MAAM,KAAK,GAChB,OAAO,CAAE,OAAO,CAAC,MAA6B,CAAC,KAAK,CAAC;IACrD,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;AAEjC,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB,SAAS,IAAI,CAAC,IAAY,EAAE,KAAa;IACvC,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAM,IAAI,CAAC,GAAG,EAAG,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,GAAG,GAAO,IAAI,CAAC,GAAG,EAAG,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,MAAM,GAAI,IAAI,CAAC,GAAG,EAAG,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,GAAG,GAAO,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,MAAM,GAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,KAAK,GAAK,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,IAAI,GAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,IAAI,GAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,IAAI,GAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAExC,oCAAoC;AACpC,MAAM,UAAU,OAAO,CAAC,GAAG,GAAiC;IAC1D,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const HELP = "Usage:\n mf-inspector [options] Analyse project shared config\n mf-inspector --interactive Step-by-step interactive wizard\n mf-inspector federation <manifest> ... Cross-MF federation analysis\n\nProject options:\n --source, -s <dirs> Source dirs to scan, comma-separated (default: ./src)\n --depth <depth> Scan depth: direct | local-graph (default: local-graph)\n --shared <packages|file> Comma-separated package names or path to .json config\n --tsconfig <path> tsconfig.json for path alias resolution\n --workspace-packages <pkgs> Comma-separated workspace packages to exclude\n --name <name> Project name (default: auto from package.json)\n --fail-on <rule> Exit 1 when findings match: mismatch | unused | any\n --write-manifest Write project-manifest.json to output dir\n --output-dir <dir> Output directory for manifest (default: .)\n --interactive, -i Launch step-by-step wizard instead of flags\n --version, -v Print version and exit\n --help, -h Show this help\n\nFederation:\n mf-inspector federation checkout.json catalog.json cart.json\n\nExamples:\n mf-inspector\n mf-inspector --interactive\n mf-inspector --source ./src --shared react,react-dom --fail-on mismatch\n mf-inspector --shared ./shared-config.json --write-manifest\n mf-inspector federation ./manifests/checkout.json ./manifests/catalog.json\n";
|
|
2
|
+
//# sourceMappingURL=help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,4+CA4BhB,CAAC"}
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const HELP = `Usage:
|
|
2
|
+
mf-inspector [options] Analyse project shared config
|
|
3
|
+
mf-inspector --interactive Step-by-step interactive wizard
|
|
4
|
+
mf-inspector federation <manifest> ... Cross-MF federation analysis
|
|
5
|
+
|
|
6
|
+
Project options:
|
|
7
|
+
--source, -s <dirs> Source dirs to scan, comma-separated (default: ./src)
|
|
8
|
+
--depth <depth> Scan depth: direct | local-graph (default: local-graph)
|
|
9
|
+
--shared <packages|file> Comma-separated package names or path to .json config
|
|
10
|
+
--tsconfig <path> tsconfig.json for path alias resolution
|
|
11
|
+
--workspace-packages <pkgs> Comma-separated workspace packages to exclude
|
|
12
|
+
--name <name> Project name (default: auto from package.json)
|
|
13
|
+
--fail-on <rule> Exit 1 when findings match: mismatch | unused | any
|
|
14
|
+
--write-manifest Write project-manifest.json to output dir
|
|
15
|
+
--output-dir <dir> Output directory for manifest (default: .)
|
|
16
|
+
--interactive, -i Launch step-by-step wizard instead of flags
|
|
17
|
+
--version, -v Print version and exit
|
|
18
|
+
--help, -h Show this help
|
|
19
|
+
|
|
20
|
+
Federation:
|
|
21
|
+
mf-inspector federation checkout.json catalog.json cart.json
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
mf-inspector
|
|
25
|
+
mf-inspector --interactive
|
|
26
|
+
mf-inspector --source ./src --shared react,react-dom --fail-on mismatch
|
|
27
|
+
mf-inspector --shared ./shared-config.json --write-manifest
|
|
28
|
+
mf-inspector federation ./manifests/checkout.json ./manifests/catalog.json
|
|
29
|
+
`;
|
|
30
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PromptFn } from './types.js';
|
|
2
|
+
export { parseArgs, parseSharedValue } from './args.js';
|
|
3
|
+
export { shouldFail } from './run-project.js';
|
|
4
|
+
export { runInteractive } from './interactive.js';
|
|
5
|
+
export { HELP } from './help.js';
|
|
6
|
+
export type { CliArgs, PromptFn } from './types.js';
|
|
7
|
+
export declare function main(argv: string[], write?: (s: string) => void, prompt?: PromptFn): Promise<number>;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkBpD,wBAAsB,IAAI,CACxB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAqC,EAC3D,MAAM,CAAC,EAAE,QAAQ,GAChB,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { parseArgs } from './args.js';
|
|
3
|
+
import { HELP } from './help.js';
|
|
4
|
+
import { runInteractive, makeReadlinePrompt } from './interactive.js';
|
|
5
|
+
import { runProject } from './run-project.js';
|
|
6
|
+
import { runFederation } from './run-federation.js';
|
|
7
|
+
import { bold, cyan, gray, red, isTTY } from './colors.js';
|
|
8
|
+
export { parseArgs, parseSharedValue } from './args.js';
|
|
9
|
+
export { shouldFail } from './run-project.js';
|
|
10
|
+
export { runInteractive } from './interactive.js';
|
|
11
|
+
export { HELP } from './help.js';
|
|
12
|
+
function getVersion() {
|
|
13
|
+
try {
|
|
14
|
+
const pkgUrl = new URL('../../package.json', import.meta.url);
|
|
15
|
+
const pkg = JSON.parse(readFileSync(pkgUrl, 'utf-8'));
|
|
16
|
+
return pkg.version;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return 'unknown';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function printBanner(write, version) {
|
|
23
|
+
if (!isTTY)
|
|
24
|
+
return;
|
|
25
|
+
const v = gray(`v${version}`);
|
|
26
|
+
write(`\n ${bold(cyan('mf-inspector'))} ${v}\n\n`);
|
|
27
|
+
}
|
|
28
|
+
export async function main(argv, write = (s) => process.stdout.write(s), prompt) {
|
|
29
|
+
let args;
|
|
30
|
+
try {
|
|
31
|
+
args = parseArgs(argv);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
write(`${red('Error:')} ${err.message}\n`);
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
if (args.command === 'help') {
|
|
38
|
+
write(HELP);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
const version = getVersion();
|
|
42
|
+
if (args.command === 'version') {
|
|
43
|
+
write(`@mf-toolkit/shared-inspector ${version}\n`);
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
printBanner(write, version);
|
|
47
|
+
if (args.command === 'federation') {
|
|
48
|
+
return runFederation(args, write);
|
|
49
|
+
}
|
|
50
|
+
if (args.interactive) {
|
|
51
|
+
let rl;
|
|
52
|
+
if (!prompt) {
|
|
53
|
+
const readline = await makeReadlinePrompt();
|
|
54
|
+
prompt = readline.prompt;
|
|
55
|
+
rl = readline;
|
|
56
|
+
}
|
|
57
|
+
args = await runInteractive(args, write, prompt);
|
|
58
|
+
rl?.close();
|
|
59
|
+
}
|
|
60
|
+
return runProject(args, write);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAwB,CAAC;QAC7E,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAA0B,EAAE,OAAe;IAC9D,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC;IAC9B,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,IAAc,EACd,QAA6B,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAC3D,MAAiB;IAEjB,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAK,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,gCAAgC,OAAO,IAAI,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE5B,IAAI,IAAI,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,IAAI,EAAqC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;YAC5C,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YACzB,EAAE,GAAG,QAAQ,CAAC;QAChB,CAAC;QACD,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACjD,EAAE,EAAE,KAAK,EAAE,CAAC;IACd,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CliArgs, PromptFn } from './types.js';
|
|
2
|
+
export declare function runInteractive(args: CliArgs, write: (s: string) => void, prompt: PromptFn): Promise<CliArgs>;
|
|
3
|
+
/** Creates a readline-based PromptFn using Node built-ins (no extra deps). */
|
|
4
|
+
export declare function makeReadlinePrompt(): Promise<{
|
|
5
|
+
prompt: PromptFn;
|
|
6
|
+
close: () => void;
|
|
7
|
+
}>;
|
|
8
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,wBAAsB,cAAc,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC1B,MAAM,EAAE,QAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CAsClB;AAED,8EAA8E;AAC9E,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAO3F"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { parseSharedValue } from './args.js';
|
|
2
|
+
export async function runInteractive(args, write, prompt) {
|
|
3
|
+
write('\n[MfSharedInspector] Interactive setup\n\n');
|
|
4
|
+
const sourceDirsRaw = await prompt('Source directories to scan (default: ./src): ');
|
|
5
|
+
args.sourceDirs = sourceDirsRaw.trim()
|
|
6
|
+
? sourceDirsRaw.split(',').map((s) => s.trim()).filter(Boolean)
|
|
7
|
+
: ['./src'];
|
|
8
|
+
const depthRaw = await prompt('Scan depth — direct or local-graph (default: local-graph): ');
|
|
9
|
+
args.depth = depthRaw.trim() === 'direct' ? 'direct' : 'local-graph';
|
|
10
|
+
const sharedRaw = await prompt('Shared packages — comma-separated names or path to .json (empty to skip): ');
|
|
11
|
+
args.sharedConfig = sharedRaw.trim() ? parseSharedValue(sharedRaw.trim()) : undefined;
|
|
12
|
+
const tsconfigRaw = await prompt('Path to tsconfig.json for alias resolution (empty to skip): ');
|
|
13
|
+
args.tsconfigPath = tsconfigRaw.trim() || undefined;
|
|
14
|
+
const wsRaw = await prompt('Workspace packages to exclude, comma-separated (empty to skip): ');
|
|
15
|
+
args.workspacePackages = wsRaw.trim()
|
|
16
|
+
? wsRaw.split(',').map((s) => s.trim()).filter(Boolean)
|
|
17
|
+
: [];
|
|
18
|
+
const failOnRaw = await prompt('Fail build on findings — mismatch / unused / any / none (default: none): ');
|
|
19
|
+
const failOnVal = failOnRaw.trim();
|
|
20
|
+
args.failOn = ['mismatch', 'unused', 'any'].includes(failOnVal)
|
|
21
|
+
? failOnVal
|
|
22
|
+
: undefined;
|
|
23
|
+
const writeManifestRaw = await prompt('Write project-manifest.json? (y/N): ');
|
|
24
|
+
args.writeManifest = writeManifestRaw.trim().toLowerCase() === 'y';
|
|
25
|
+
if (args.writeManifest) {
|
|
26
|
+
const outputDirRaw = await prompt('Output directory for manifest (default: .): ');
|
|
27
|
+
args.outputDir = outputDirRaw.trim() || '.';
|
|
28
|
+
}
|
|
29
|
+
write('\n');
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
/** Creates a readline-based PromptFn using Node built-ins (no extra deps). */
|
|
33
|
+
export async function makeReadlinePrompt() {
|
|
34
|
+
const { createInterface } = await import('node:readline/promises');
|
|
35
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
36
|
+
return {
|
|
37
|
+
prompt: (question) => rl.question(question),
|
|
38
|
+
close: () => rl.close(),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-federation.d.ts","sourceRoot":"","sources":["../../src/cli/run-federation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAsB,aAAa,CACjC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GACzB,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { analyzeFederation } from '../analyzer/analyze-federation.js';
|
|
4
|
+
import { formatFederationReport } from '../reporter/format-federation-report.js';
|
|
5
|
+
import { createSpinner } from './spinner.js';
|
|
6
|
+
import { colorizeReport } from './colorize-report.js';
|
|
7
|
+
export async function runFederation(args, write) {
|
|
8
|
+
if (args.manifestFiles.length === 0) {
|
|
9
|
+
write('Error: federation command requires at least one manifest file\n');
|
|
10
|
+
write('Usage: mf-inspector federation <manifest1.json> [manifest2.json...]\n');
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
const spinner = createSpinner();
|
|
14
|
+
spinner.start(`Loading ${args.manifestFiles.length} manifest${args.manifestFiles.length > 1 ? 's' : ''}`);
|
|
15
|
+
const manifests = [];
|
|
16
|
+
for (const file of args.manifestFiles) {
|
|
17
|
+
const filePath = resolve(process.cwd(), file);
|
|
18
|
+
let content;
|
|
19
|
+
try {
|
|
20
|
+
content = readFileSync(filePath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
spinner.stop();
|
|
24
|
+
write(`Error: cannot read file "${file}"\n`);
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
manifests.push(JSON.parse(content));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
spinner.stop();
|
|
32
|
+
write(`Error: "${file}" is not valid JSON\n`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
spinner.succeed(`Loaded ${manifests.length} manifest${manifests.length > 1 ? 's' : ''}`);
|
|
37
|
+
const report = analyzeFederation(manifests);
|
|
38
|
+
write(colorizeReport(formatFederationReport(report)));
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=run-federation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-federation.js","sourceRoot":"","sources":["../../src/cli/run-federation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAa,EACb,KAA0B;IAE1B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACzE,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC/E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,aAAa,CAAC,MAAM,YAAY,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1G,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,CAAC,4BAA4B,IAAI,KAAK,CAAC,CAAC;YAC7C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,CAAC,WAAW,IAAI,uBAAuB,CAAC,CAAC;YAC9C,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,UAAU,SAAS,CAAC,MAAM,YAAY,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEzF,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,cAAc,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProjectReport } from '../types.js';
|
|
2
|
+
import type { CliArgs } from './types.js';
|
|
3
|
+
export declare function shouldFail(report: ProjectReport, failOn: 'mismatch' | 'unused' | 'any'): boolean;
|
|
4
|
+
export declare function runProject(args: CliArgs, write: (s: string) => void): Promise<number>;
|
|
5
|
+
//# sourceMappingURL=run-project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-project.d.ts","sourceRoot":"","sources":["../../src/cli/run-project.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAUhG;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GACzB,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { buildProjectManifest } from '../collector/build-project-manifest.js';
|
|
4
|
+
import { analyzeProject } from '../analyzer/analyze-project.js';
|
|
5
|
+
import { formatReport } from '../reporter/format-report.js';
|
|
6
|
+
import { writeManifest } from '../reporter/write-report.js';
|
|
7
|
+
import { createSpinner } from './spinner.js';
|
|
8
|
+
import { colorizeReport } from './colorize-report.js';
|
|
9
|
+
export function shouldFail(report, failOn) {
|
|
10
|
+
if (failOn === 'mismatch')
|
|
11
|
+
return report.mismatched.length > 0;
|
|
12
|
+
if (failOn === 'unused')
|
|
13
|
+
return report.unused.length > 0;
|
|
14
|
+
return (report.mismatched.length > 0 ||
|
|
15
|
+
report.unused.length > 0 ||
|
|
16
|
+
report.candidates.length > 0 ||
|
|
17
|
+
report.singletonRisks.length > 0 ||
|
|
18
|
+
report.eagerRisks.length > 0);
|
|
19
|
+
}
|
|
20
|
+
export async function runProject(args, write) {
|
|
21
|
+
let name = args.name;
|
|
22
|
+
if (!name) {
|
|
23
|
+
try {
|
|
24
|
+
const pkg = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), 'utf-8'));
|
|
25
|
+
name = pkg.name ?? 'project';
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
name = 'project';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const spinner = createSpinner();
|
|
32
|
+
spinner.start(`Scanning ${args.sourceDirs.join(', ')}`);
|
|
33
|
+
const manifest = await buildProjectManifest({
|
|
34
|
+
name,
|
|
35
|
+
sourceDirs: args.sourceDirs,
|
|
36
|
+
depth: args.depth,
|
|
37
|
+
sharedConfig: args.sharedConfig,
|
|
38
|
+
tsconfigPath: args.tsconfigPath,
|
|
39
|
+
workspacePackages: args.workspacePackages,
|
|
40
|
+
});
|
|
41
|
+
spinner.succeed(`Scanned ${manifest.source.filesScanned} files`);
|
|
42
|
+
const report = analyzeProject(manifest);
|
|
43
|
+
write(colorizeReport(formatReport(report, {
|
|
44
|
+
name: manifest.project.name,
|
|
45
|
+
depth: manifest.source.depth,
|
|
46
|
+
filesScanned: manifest.source.filesScanned,
|
|
47
|
+
})));
|
|
48
|
+
if (args.writeManifest) {
|
|
49
|
+
const outPath = resolve(args.outputDir, 'project-manifest.json');
|
|
50
|
+
await writeManifest(manifest, outPath);
|
|
51
|
+
write(`\n Manifest written to ${outPath}\n`);
|
|
52
|
+
}
|
|
53
|
+
if (args.failOn && shouldFail(report, args.failOn))
|
|
54
|
+
return 1;
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=run-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-project.js","sourceRoot":"","sources":["../../src/cli/run-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface Spinner {
|
|
2
|
+
/** Start animating with a label. */
|
|
3
|
+
start(text: string): void;
|
|
4
|
+
/** Stop animation and print a success line. */
|
|
5
|
+
succeed(text: string): void;
|
|
6
|
+
/** Stop animation silently (clears the line). */
|
|
7
|
+
stop(): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createSpinner(): Spinner;
|
|
10
|
+
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,OAAO;IACtB,oCAAoC;IACpC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,aAAa,IAAI,OAAO,CAsCvC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// ─── Terminal spinner ─────────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Uses braille frames for TTY, plain text for non-TTY / CI environments.
|
|
4
|
+
// Does NOT use the injectable `write` — writes directly to process.stdout
|
|
5
|
+
// so it can overwrite lines in place without interfering with the report output.
|
|
6
|
+
import { isTTY, green, gray } from './colors.js';
|
|
7
|
+
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
8
|
+
const INTERVAL_MS = 80;
|
|
9
|
+
export function createSpinner() {
|
|
10
|
+
if (!isTTY) {
|
|
11
|
+
// Non-TTY (CI, piped): emit plain text lines via stdout
|
|
12
|
+
return {
|
|
13
|
+
start(text) { process.stdout.write(` ${text}...\n`); },
|
|
14
|
+
succeed(text) { process.stdout.write(` ✓ ${text}\n`); },
|
|
15
|
+
stop() { },
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
let frame = 0;
|
|
19
|
+
let timer;
|
|
20
|
+
function clearLine() {
|
|
21
|
+
process.stdout.write('\r\x1b[K'); // carriage return + erase to end of line
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
start(text) {
|
|
25
|
+
process.stdout.write('\x1b[?25l'); // hide cursor
|
|
26
|
+
timer = setInterval(() => {
|
|
27
|
+
clearLine();
|
|
28
|
+
process.stdout.write(gray(`${FRAMES[frame % FRAMES.length]} ${text}`));
|
|
29
|
+
frame++;
|
|
30
|
+
}, INTERVAL_MS);
|
|
31
|
+
},
|
|
32
|
+
succeed(text) {
|
|
33
|
+
clearInterval(timer);
|
|
34
|
+
clearLine();
|
|
35
|
+
process.stdout.write(`${green('✓')} ${text}\n`);
|
|
36
|
+
process.stdout.write('\x1b[?25h'); // show cursor
|
|
37
|
+
},
|
|
38
|
+
stop() {
|
|
39
|
+
clearInterval(timer);
|
|
40
|
+
clearLine();
|
|
41
|
+
process.stdout.write('\x1b[?25h');
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/cli/spinner.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,iFAAiF;AAEjF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAClE,MAAM,WAAW,GAAG,EAAE,CAAC;AAWvB,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,wDAAwD;QACxD,OAAO;YACL,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;YACxD,IAAI,KAAI,CAAC;SACV,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAiD,CAAC;IAEtD,SAAS,SAAS;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,yCAAyC;IAC7E,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;YACjD,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;gBACvB,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBACxE,KAAK,EAAE,CAAC;YACV,CAAC,EAAE,WAAW,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,IAAI;YACV,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;YACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;QACnD,CAAC;QACD,IAAI;YACF,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SharedDepConfig } from '../types.js';
|
|
2
|
+
export interface CliArgs {
|
|
3
|
+
command: 'project' | 'federation' | 'help' | 'version';
|
|
4
|
+
interactive: boolean;
|
|
5
|
+
sourceDirs: string[];
|
|
6
|
+
depth: 'direct' | 'local-graph';
|
|
7
|
+
sharedConfig?: Record<string, SharedDepConfig>;
|
|
8
|
+
tsconfigPath?: string;
|
|
9
|
+
workspacePackages: string[];
|
|
10
|
+
failOn?: 'mismatch' | 'unused' | 'any';
|
|
11
|
+
writeManifest: boolean;
|
|
12
|
+
outputDir: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
manifestFiles: string[];
|
|
15
|
+
}
|
|
16
|
+
export type PromptFn = (question: string) => Promise<string>;
|
|
17
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,WAAW,EAAE,OAAO,CAAC;IAErB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,QAAQ,GAAG,aAAa,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":""}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,cAAc,gBAAgB,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export * from './cli/index.js';
|
|
3
|
+
import { main } from './cli/index.js';
|
|
4
|
+
const moduleUrl = new URL(import.meta.url);
|
|
5
|
+
const scriptUrl = process.argv[1] ? new URL(process.argv[1], 'file://') : null;
|
|
6
|
+
if (scriptUrl && moduleUrl.href === scriptUrl.href) {
|
|
7
|
+
main(process.argv.slice(2)).then((code) => { if (code !== 0)
|
|
8
|
+
process.exit(code); }, (err) => {
|
|
9
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAE/E,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC9B,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EACjD,CAAC,GAAU,EAAE,EAAE;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ export { buildProjectManifest } from './collector/build-project-manifest.js';
|
|
|
2
2
|
export { analyzeProject } from './analyzer/analyze-project.js';
|
|
3
3
|
export { analyzeFederation } from './analyzer/analyze-federation.js';
|
|
4
4
|
export { inspect } from './inspect.js';
|
|
5
|
-
export { formatReport } from './reporter/format-report.js';
|
|
5
|
+
export { formatReport, type FormatReportContext } from './reporter/format-report.js';
|
|
6
6
|
export { formatFederationReport } from './reporter/format-federation-report.js';
|
|
7
7
|
export { writeReport, writeManifest } from './reporter/write-report.js';
|
|
8
|
+
export { scoreProjectReport, scoreFederationReport, type RiskScore } from './reporter/scoring.js';
|
|
8
9
|
export type { ProjectManifest, ProjectReport, CollectorOptions, AnalysisOptions, SharedDepConfig, PackageOccurrence, UnusedEntry, CandidateEntry, MismatchedEntry, SingletonRiskEntry, EagerRiskEntry, FederationAnalysisOptions, FederationReport, GhostShareEntry, HostGapEntry, VersionConflictEntry, SingletonMismatchEntry, } from './types.js';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlG,YAAY,EACV,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,4 +8,5 @@ export { inspect } from './inspect.js';
|
|
|
8
8
|
export { formatReport } from './reporter/format-report.js';
|
|
9
9
|
export { formatFederationReport } from './reporter/format-federation-report.js';
|
|
10
10
|
export { writeReport, writeManifest } from './reporter/write-report.js';
|
|
11
|
+
export { scoreProjectReport, scoreFederationReport } from './reporter/scoring.js';
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iFAAiF;AACjF,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAA4B,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAkB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface DiagnosticInfo {
|
|
2
|
+
/** One-line risk description shown after "→ Risk:" */
|
|
3
|
+
risk: string;
|
|
4
|
+
}
|
|
5
|
+
export type IssueKind = 'mismatch' | 'unused' | 'candidate' | 'singleton-risk' | 'eager-risk';
|
|
6
|
+
export declare function getDiagnostic(pkg: string, kind: IssueKind): DiagnosticInfo;
|
|
7
|
+
export interface FixConfig {
|
|
8
|
+
singleton?: boolean;
|
|
9
|
+
requiredVersion?: string;
|
|
10
|
+
eager?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns a ready-to-paste webpack/rspack shared config snippet.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* buildFixSnippet('react', { singleton: true, requiredVersion: '^18.2.0' })
|
|
17
|
+
* // →
|
|
18
|
+
* // shared: {
|
|
19
|
+
* // react: { singleton: true, requiredVersion: "^18.2.0" }
|
|
20
|
+
* // }
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildFixSnippet(pkg: string, cfg?: FixConfig): string;
|
|
23
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/reporter/diagnostics.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,QAAQ,GACR,WAAW,GACX,gBAAgB,GAChB,YAAY,CAAC;AAkHjB,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,cAAc,CAG1E;AAID,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,SAAc,GAAG,MAAM,CAQxE"}
|