foresthouse 1.0.0-dev.16 → 1.0.0-dev.18
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 +10 -1
- package/dist/cli.mjs +38 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +89 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{react-GNHqx2A-.mjs → react-B2on-FAy.mjs} +762 -20
- package/dist/react-B2on-FAy.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/react-GNHqx2A-.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# foresthouse
|
|
2
2
|
|
|
3
|
-
`foresthouse` is a modern TypeScript-first Node.js CLI that
|
|
3
|
+
`foresthouse` is a modern TypeScript-first Node.js CLI that can print source import trees, React usage trees, and package-manifest dependency trees.
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- Resolves local imports, re-exports, `require()`, and string-literal dynamic `import()`
|
|
20
20
|
- Honors the nearest `tsconfig.json` or `jsconfig.json`, including `baseUrl` and `paths`
|
|
21
21
|
- Expands sibling workspace packages by default, including their own `tsconfig` alias rules
|
|
22
|
+
- Reads `package.json` manifests to show package-level dependency trees for single packages and monorepos
|
|
22
23
|
- Prints a tree by default, or JSON with `--json`
|
|
23
24
|
- Colorizes ASCII output automatically when the terminal supports ANSI colors
|
|
24
25
|
|
|
@@ -29,6 +30,7 @@ corepack enable
|
|
|
29
30
|
pnpm install
|
|
30
31
|
pnpm run build
|
|
31
32
|
node dist/cli.mjs import src/index.ts
|
|
33
|
+
node dist/cli.mjs deps .
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
### Example
|
|
@@ -75,6 +77,13 @@ src/main.ts
|
|
|
75
77
|
- `--project-only`: restrict traversal to the active `tsconfig.json` or `jsconfig.json` project
|
|
76
78
|
- `--json`: print a JSON tree instead of ASCII output
|
|
77
79
|
|
|
80
|
+
`deps` command:
|
|
81
|
+
|
|
82
|
+
- `foresthouse deps <directory>`: analyze the nearest package rooted at the given directory
|
|
83
|
+
- `foresthouse deps .`: analyze the current package or repository root
|
|
84
|
+
- `foresthouse deps ./packages/a`: analyze a specific workspace package directory
|
|
85
|
+
- `--json`: print a JSON package tree instead of ASCII output
|
|
86
|
+
|
|
78
87
|
## Development
|
|
79
88
|
|
|
80
89
|
```bash
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as analyzeReactUsage, i as
|
|
2
|
+
import { a as printReactUsageTree, c as printPackageDependencyTree, f as analyzeReactUsage, g as analyzePackageDependencies, h as analyzePackageDependencyDiff, i as graphToSerializablePackageTree, m as isSourceCodeFile, n as graphToSerializableTree, o as printDependencyTree, p as analyzeDependencies, r as diffGraphToSerializablePackageTree, s as printPackageDependencyDiffTree, t as graphToSerializableReactTree } from "./react-B2on-FAy.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import path from "node:path";
|
|
5
4
|
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
6
|
import process$1 from "node:process";
|
|
7
7
|
import { cac } from "cac";
|
|
8
8
|
//#region src/commands/base.ts
|
|
@@ -31,6 +31,25 @@ var BaseCommand = class {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
//#endregion
|
|
34
|
+
//#region src/commands/deps.ts
|
|
35
|
+
var DepsCommand = class extends BaseCommand {
|
|
36
|
+
analyze() {
|
|
37
|
+
if (this.options.diff !== void 0) return analyzePackageDependencyDiff(this.options.directory, this.options.diff);
|
|
38
|
+
return analyzePackageDependencies(this.options.directory);
|
|
39
|
+
}
|
|
40
|
+
serialize(graph) {
|
|
41
|
+
if (isPackageDependencyDiffGraph(graph)) return diffGraphToSerializablePackageTree(graph);
|
|
42
|
+
return graphToSerializablePackageTree(graph);
|
|
43
|
+
}
|
|
44
|
+
render(graph) {
|
|
45
|
+
if (isPackageDependencyDiffGraph(graph)) return printPackageDependencyDiffTree(graph);
|
|
46
|
+
return printPackageDependencyTree(graph);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function isPackageDependencyDiffGraph(graph) {
|
|
50
|
+
return "root" in graph;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
34
53
|
//#region src/commands/import.ts
|
|
35
54
|
var ImportCommand = class extends BaseCommand {
|
|
36
55
|
analyze() {
|
|
@@ -146,6 +165,7 @@ var CliApplication = class {
|
|
|
146
165
|
this.createCommand().run();
|
|
147
166
|
}
|
|
148
167
|
createCommand() {
|
|
168
|
+
if (this.options.command === "deps") return new DepsCommand(this.options);
|
|
149
169
|
if (this.options.command === "react") return new ReactCommand(this.options);
|
|
150
170
|
return new ImportCommand(this.options);
|
|
151
171
|
}
|
|
@@ -177,6 +197,9 @@ var CliMain = class {
|
|
|
177
197
|
}
|
|
178
198
|
createCli() {
|
|
179
199
|
const cli = cac("foresthouse");
|
|
200
|
+
cli.command("deps <directory>", "Analyze package.json dependencies from a package directory.").usage("deps <directory> [options]").option("--diff <git-ref-or-range>", "Show only dependency-tree changes relative to a Git revision or range.").option("--json", "Print the package tree as JSON.").action((directory, rawOptions) => {
|
|
201
|
+
runCli(normalizeDepsCliOptions(directory, rawOptions));
|
|
202
|
+
});
|
|
180
203
|
cli.command("import [entry-file]", "Analyze an entry file and print its dependency tree.").usage("import <entry-file> [options]").option("--entry <path>", "Entry file to analyze.").option("--cwd <path>", "Working directory used for relative paths.").option("--config <path>", "Explicit tsconfig.json or jsconfig.json path.").option("--include-externals", "Include packages and Node built-ins in the tree.").option("--no-workspaces", "Do not expand sibling workspace packages into source subtrees.").option("--project-only", "Restrict traversal to the active tsconfig.json or jsconfig.json project.").option("--no-unused", "Omit imports that are never referenced.").option("--json", "Print the dependency tree as JSON.").action((entryFile, rawOptions) => {
|
|
181
204
|
runCli(normalizeImportCliOptions(entryFile, rawOptions));
|
|
182
205
|
});
|
|
@@ -193,7 +216,7 @@ var CliMain = class {
|
|
|
193
216
|
if (firstArgument === void 0) return;
|
|
194
217
|
if (firstArgument === "--react" || firstArgument.startsWith("--react=")) throw new Error("Unknown option `--react`");
|
|
195
218
|
if (firstArgument.startsWith("-")) return;
|
|
196
|
-
if (firstArgument === "import" || firstArgument === "react") return;
|
|
219
|
+
if (firstArgument === "deps" || firstArgument === "import" || firstArgument === "react") return;
|
|
197
220
|
throw new Error(`Unknown command \`${firstArgument}\``);
|
|
198
221
|
}
|
|
199
222
|
toProcessArgv() {
|
|
@@ -204,6 +227,18 @@ var CliMain = class {
|
|
|
204
227
|
];
|
|
205
228
|
}
|
|
206
229
|
};
|
|
230
|
+
function normalizeDepsCliOptions(directory, options) {
|
|
231
|
+
return {
|
|
232
|
+
command: "deps",
|
|
233
|
+
directory,
|
|
234
|
+
diff: options.diff,
|
|
235
|
+
cwd: void 0,
|
|
236
|
+
configPath: void 0,
|
|
237
|
+
expandWorkspaces: true,
|
|
238
|
+
projectOnly: false,
|
|
239
|
+
json: options.json === true
|
|
240
|
+
};
|
|
241
|
+
}
|
|
207
242
|
function normalizeImportCliOptions(entryFile, options) {
|
|
208
243
|
return {
|
|
209
244
|
command: "import",
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["process"],"sources":["../src/commands/base.ts","../src/commands/import.ts","../src/app/react-entry-files.ts","../src/commands/react.ts","../src/app/run.ts","../src/app/cli.ts","../src/cli.ts"],"sourcesContent":["import type { CliOptions } from '../app/args.js'\nimport type { AnalyzeOptions } from '../types/analyze-options.js'\n\nexport abstract class BaseCommand<\n TGraph,\n TOptions extends CliOptions = CliOptions,\n> {\n constructor(protected readonly options: TOptions) {}\n\n run(): void {\n const graph = this.analyze()\n\n if (this.isJsonMode()) {\n process.stdout.write(\n `${JSON.stringify(this.serialize(graph), null, 2)}\\n`,\n )\n return\n }\n\n process.stdout.write(`${this.render(graph)}\\n`)\n }\n\n protected isJsonMode(): boolean {\n return this.options.json\n }\n\n protected getAnalyzeOptions(): AnalyzeOptions {\n return {\n ...(this.options.cwd === undefined ? {} : { cwd: this.options.cwd }),\n ...(this.options.configPath === undefined\n ? {}\n : { configPath: this.options.configPath }),\n expandWorkspaces: this.options.expandWorkspaces,\n projectOnly: this.options.projectOnly,\n }\n }\n\n protected abstract analyze(): TGraph\n protected abstract serialize(graph: TGraph): object\n protected abstract render(graph: TGraph): string\n}\n","import { analyzeDependencies } from '../analyzers/import/index.js'\nimport type { ImportCliOptions } from '../app/args.js'\nimport { printDependencyTree } from '../output/ascii/import.js'\nimport { graphToSerializableTree } from '../output/json/import.js'\nimport type { DependencyGraph } from '../types/dependency-graph.js'\nimport { BaseCommand } from './base.js'\n\nexport class ImportCommand extends BaseCommand<\n DependencyGraph,\n ImportCliOptions\n> {\n protected analyze(): DependencyGraph {\n return analyzeDependencies(this.options.entryFile, this.getAnalyzeOptions())\n }\n\n protected serialize(graph: DependencyGraph): object {\n return graphToSerializableTree(graph, {\n omitUnused: this.options.omitUnused,\n })\n }\n\n protected render(graph: DependencyGraph): string {\n return printDependencyTree(graph, {\n cwd: this.options.cwd ?? graph.cwd,\n includeExternals: this.options.includeExternals,\n omitUnused: this.options.omitUnused,\n })\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { isSourceCodeFile } from '../utils/is-source-code-file.js'\nimport type { ReactCliOptions } from './args.js'\n\nconst NEXT_JS_ENTRY_ROOTS = [\n 'pages',\n 'app',\n path.join('src', 'pages'),\n path.join('src', 'app'),\n]\n\nexport function resolveReactEntryFiles(options: ReactCliOptions): string[] {\n if (options.entryFile !== undefined) {\n return [options.entryFile]\n }\n\n if (!options.nextjs) {\n throw new Error(\n 'Missing React entry file. Use `foresthouse react <entry-file>` or `foresthouse react --nextjs`.',\n )\n }\n\n return discoverNextJsPageEntries(options.cwd)\n}\n\nexport function discoverNextJsPageEntries(cwd?: string): string[] {\n const effectiveCwd = path.resolve(cwd ?? process.cwd())\n const entries = new Set<string>()\n\n collectPagesRouterEntries(\n path.join(effectiveCwd, 'pages'),\n effectiveCwd,\n entries,\n )\n collectAppRouterEntries(path.join(effectiveCwd, 'app'), effectiveCwd, entries)\n collectPagesRouterEntries(\n path.join(effectiveCwd, 'src', 'pages'),\n effectiveCwd,\n entries,\n )\n collectAppRouterEntries(\n path.join(effectiveCwd, 'src', 'app'),\n effectiveCwd,\n entries,\n )\n\n const resolvedEntries = [...entries].sort()\n if (resolvedEntries.length > 0) {\n return resolvedEntries\n }\n\n const searchedRoots = NEXT_JS_ENTRY_ROOTS.map((root) => `\\`${root}/\\``).join(\n ', ',\n )\n throw new Error(\n `No Next.js page entries found. Searched ${searchedRoots} relative to ${effectiveCwd}.`,\n )\n}\n\nfunction collectPagesRouterEntries(\n rootDirectory: string,\n cwd: string,\n entries: Set<string>,\n): void {\n walkDirectory(rootDirectory, (filePath, relativePath) => {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n return\n }\n\n const segments = relativePath.split(path.sep)\n if (segments[0] === 'api') {\n return\n }\n\n const baseName = path.basename(filePath)\n if (baseName.startsWith('_')) {\n return\n }\n\n entries.add(path.relative(cwd, filePath))\n })\n}\n\nfunction collectAppRouterEntries(\n rootDirectory: string,\n cwd: string,\n entries: Set<string>,\n): void {\n walkDirectory(rootDirectory, (filePath) => {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n return\n }\n\n const extension = path.extname(filePath)\n const baseName = path.basename(filePath, extension)\n if (baseName !== 'page') {\n return\n }\n\n entries.add(path.relative(cwd, filePath))\n })\n}\n\nfunction walkDirectory(\n rootDirectory: string,\n visitor: (filePath: string, relativePath: string) => void,\n): void {\n if (!fs.existsSync(rootDirectory)) {\n return\n }\n\n const stack = [rootDirectory]\n\n while (stack.length > 0) {\n const directory = stack.pop()\n if (directory === undefined) {\n continue\n }\n\n const directoryEntries = fs\n .readdirSync(directory, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name))\n\n for (let index = directoryEntries.length - 1; index >= 0; index -= 1) {\n const entry = directoryEntries[index]\n if (entry === undefined) {\n continue\n }\n\n const entryPath = path.join(directory, entry.name)\n if (entry.isDirectory()) {\n stack.push(entryPath)\n continue\n }\n\n if (!entry.isFile()) {\n continue\n }\n\n visitor(entryPath, path.relative(rootDirectory, entryPath))\n }\n }\n}\n","import { analyzeReactUsage } from '../analyzers/react/index.js'\nimport type { ReactCliOptions } from '../app/args.js'\nimport { resolveReactEntryFiles } from '../app/react-entry-files.js'\nimport { printReactUsageTree } from '../output/ascii/react.js'\nimport { graphToSerializableReactTree } from '../output/json/react.js'\nimport type { AnalyzeOptions } from '../types/analyze-options.js'\nimport type { ReactUsageFilter } from '../types/react-usage-filter.js'\nimport type { ReactUsageGraph } from '../types/react-usage-graph.js'\nimport { BaseCommand } from './base.js'\n\nexport class ReactCommand extends BaseCommand<\n ReactUsageGraph,\n ReactCliOptions\n> {\n protected analyze(): ReactUsageGraph {\n return analyzeReactUsage(\n resolveReactEntryFiles(this.options),\n this.getAnalyzeOptions(),\n )\n }\n\n protected serialize(graph: ReactUsageGraph): object {\n return graphToSerializableReactTree(graph, {\n filter: this.getFilter(),\n })\n }\n\n protected render(graph: ReactUsageGraph): string {\n return printReactUsageTree(graph, {\n cwd: this.options.cwd ?? graph.cwd,\n filter: this.getFilter(),\n })\n }\n\n protected getAnalyzeOptions(): AnalyzeOptions {\n return {\n ...super.getAnalyzeOptions(),\n includeBuiltins: this.options.includeBuiltins,\n }\n }\n\n private getFilter(): ReactUsageFilter {\n return this.options.filter\n }\n}\n","import { ImportCommand } from '../commands/import.js'\nimport { ReactCommand } from '../commands/react.js'\nimport type { CliOptions } from './args.js'\n\nexport function runCli(options: CliOptions): void {\n new CliApplication(options).run()\n}\n\nclass CliApplication {\n constructor(private readonly options: CliOptions) {}\n\n run(): void {\n this.createCommand().run()\n }\n\n private createCommand(): {\n run(): void\n } {\n if (this.options.command === 'react') {\n return new ReactCommand(this.options)\n }\n\n return new ImportCommand(this.options)\n }\n}\n","import process from 'node:process'\n\nimport { cac } from 'cac'\n\nimport type { ReactUsageFilter } from '../types/react-usage-filter.js'\nimport type { ImportCliOptions, ReactCliOptions } from './args.js'\nimport { runCli } from './run.js'\n\nexport function main(version: string, argv = process.argv.slice(2)): void {\n new CliMain(version, argv).run()\n}\n\nclass CliMain {\n constructor(\n private readonly version: string,\n private readonly argv: string[],\n ) {}\n\n run(): void {\n try {\n const cli = this.createCli()\n\n if (this.argv.length === 0) {\n cli.outputHelp()\n return\n }\n\n this.validateCommandSyntax()\n cli.parse(this.toProcessArgv())\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error occurred.'\n process.stderr.write(`foresthouse: ${message}\\n`)\n process.exitCode = 1\n }\n }\n\n private createCli() {\n const cli = cac('foresthouse')\n\n cli\n .command(\n 'import [entry-file]',\n 'Analyze an entry file and print its dependency tree.',\n )\n .usage('import <entry-file> [options]')\n .option('--entry <path>', 'Entry file to analyze.')\n .option('--cwd <path>', 'Working directory used for relative paths.')\n .option(\n '--config <path>',\n 'Explicit tsconfig.json or jsconfig.json path.',\n )\n .option(\n '--include-externals',\n 'Include packages and Node built-ins in the tree.',\n )\n .option(\n '--no-workspaces',\n 'Do not expand sibling workspace packages into source subtrees.',\n )\n .option(\n '--project-only',\n 'Restrict traversal to the active tsconfig.json or jsconfig.json project.',\n )\n .option('--no-unused', 'Omit imports that are never referenced.')\n .option('--json', 'Print the dependency tree as JSON.')\n .action(\n (entryFile: string | undefined, rawOptions: ParsedImportCliOptions) => {\n runCli(normalizeImportCliOptions(entryFile, rawOptions))\n },\n )\n\n cli\n .command('react [entry-file]', 'Analyze React usage from an entry file.')\n .usage('react [entry-file] [options]')\n .option('--cwd <path>', 'Working directory used for relative paths.')\n .option(\n '--config <path>',\n 'Explicit tsconfig.json or jsconfig.json path.',\n )\n .option(\n '--nextjs',\n 'Infer Next.js page entries from app/ and pages/ when no entry is provided.',\n )\n .option(\n '--filter <mode>',\n 'Limit output to `component`, `hook`, or `builtin` usages.',\n )\n .option('--builtin', 'Include built-in HTML nodes in the React tree.')\n .option(\n '--no-workspaces',\n 'Do not expand sibling workspace packages into source subtrees.',\n )\n .option(\n '--project-only',\n 'Restrict traversal to the active tsconfig.json or jsconfig.json project.',\n )\n .option('--json', 'Print the React usage tree as JSON.')\n .action(\n (entryFile: string | undefined, rawOptions: ParsedReactCliOptions) => {\n runCli(normalizeReactCliOptions(entryFile, rawOptions))\n },\n )\n\n cli.help()\n cli.version(this.version)\n\n return cli\n }\n\n private validateCommandSyntax(): void {\n if (this.argv.length === 0) {\n return\n }\n\n const firstArgument = this.argv[0]\n\n if (firstArgument === undefined) {\n return\n }\n\n if (firstArgument === '--react' || firstArgument.startsWith('--react=')) {\n throw new Error('Unknown option `--react`')\n }\n\n if (firstArgument.startsWith('-')) {\n return\n }\n\n if (firstArgument === 'import' || firstArgument === 'react') {\n return\n }\n\n throw new Error(`Unknown command \\`${firstArgument}\\``)\n }\n\n private toProcessArgv(): string[] {\n return ['node', 'foresthouse', ...this.argv]\n }\n}\n\ninterface ParsedBaseCliOptions {\n readonly cwd?: string\n readonly config?: string\n readonly workspaces?: boolean\n readonly projectOnly?: boolean\n readonly json?: boolean\n}\n\ninterface ParsedImportCliOptions extends ParsedBaseCliOptions {\n readonly entry?: string\n readonly includeExternals?: boolean\n readonly unused?: boolean\n}\n\ninterface ParsedReactCliOptions extends ParsedBaseCliOptions {\n readonly filter?: string\n readonly nextjs?: boolean\n readonly builtin?: boolean\n}\n\nfunction normalizeImportCliOptions(\n entryFile: string | undefined,\n options: ParsedImportCliOptions,\n): ImportCliOptions {\n return {\n command: 'import',\n entryFile: resolveImportEntryFile(entryFile, options.entry),\n cwd: options.cwd,\n configPath: options.config,\n expandWorkspaces: options.workspaces !== false,\n projectOnly: options.projectOnly === true,\n includeExternals: options.includeExternals === true,\n omitUnused: options.unused === false,\n json: options.json === true,\n }\n}\n\nfunction normalizeReactCliOptions(\n entryFile: string | undefined,\n options: ParsedReactCliOptions,\n): ReactCliOptions {\n return {\n command: 'react',\n entryFile: resolveReactEntryFile(entryFile, options.nextjs),\n cwd: options.cwd,\n configPath: options.config,\n expandWorkspaces: options.workspaces !== false,\n projectOnly: options.projectOnly === true,\n json: options.json === true,\n filter: normalizeReactFilter(options.filter),\n nextjs: options.nextjs === true,\n includeBuiltins: options.builtin === true,\n }\n}\n\nfunction resolveImportEntryFile(\n positionalEntryFile: string | undefined,\n optionEntryFile: string | undefined,\n): string {\n if (\n positionalEntryFile !== undefined &&\n optionEntryFile !== undefined &&\n positionalEntryFile !== optionEntryFile\n ) {\n throw new Error(\n 'Provide the import entry only once, either as `foresthouse import <entry-file>` or `foresthouse import --entry <path>`.',\n )\n }\n\n const resolvedEntryFile = positionalEntryFile ?? optionEntryFile\n\n if (resolvedEntryFile === undefined) {\n throw new Error(\n 'Missing import entry file. Use `foresthouse import <entry-file>` or `foresthouse import --entry <path>`.',\n )\n }\n\n return resolvedEntryFile\n}\n\nfunction normalizeReactFilter(\n filter: ParsedReactCliOptions['filter'],\n): ReactUsageFilter {\n if (filter === undefined) {\n return 'all'\n }\n\n if (filter === 'component' || filter === 'hook' || filter === 'builtin') {\n return filter\n }\n\n throw new Error(`Unknown React filter: ${filter}`)\n}\n\nfunction resolveReactEntryFile(\n entryFile: string | undefined,\n nextjs: boolean | undefined,\n): string | undefined {\n if (entryFile !== undefined) {\n return entryFile\n }\n\n if (nextjs === true) {\n return undefined\n }\n\n throw new Error(\n 'Missing React entry file. Use `foresthouse react <entry-file>` or `foresthouse react --nextjs`.',\n )\n}\n","#!/usr/bin/env node\n\nimport { createRequire } from 'node:module'\n\nimport { main } from './app/cli.js'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nmain(version)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["process"],"sources":["../src/commands/base.ts","../src/commands/deps.ts","../src/commands/import.ts","../src/app/react-entry-files.ts","../src/commands/react.ts","../src/app/run.ts","../src/app/cli.ts","../src/cli.ts"],"sourcesContent":["import type { CliOptions } from '../app/args.js'\nimport type { AnalyzeOptions } from '../types/analyze-options.js'\n\nexport abstract class BaseCommand<\n TGraph,\n TOptions extends CliOptions = CliOptions,\n> {\n constructor(protected readonly options: TOptions) {}\n\n run(): void {\n const graph = this.analyze()\n\n if (this.isJsonMode()) {\n process.stdout.write(\n `${JSON.stringify(this.serialize(graph), null, 2)}\\n`,\n )\n return\n }\n\n process.stdout.write(`${this.render(graph)}\\n`)\n }\n\n protected isJsonMode(): boolean {\n return this.options.json\n }\n\n protected getAnalyzeOptions(): AnalyzeOptions {\n return {\n ...(this.options.cwd === undefined ? {} : { cwd: this.options.cwd }),\n ...(this.options.configPath === undefined\n ? {}\n : { configPath: this.options.configPath }),\n expandWorkspaces: this.options.expandWorkspaces,\n projectOnly: this.options.projectOnly,\n }\n }\n\n protected abstract analyze(): TGraph\n protected abstract serialize(graph: TGraph): object\n protected abstract render(graph: TGraph): string\n}\n","import { analyzePackageDependencyDiff } from '../analyzers/deps/diff.js'\nimport { analyzePackageDependencies } from '../analyzers/deps/index.js'\nimport type { DepsCliOptions } from '../app/args.js'\nimport {\n printPackageDependencyDiffTree,\n printPackageDependencyTree,\n} from '../output/ascii/deps.js'\nimport {\n diffGraphToSerializablePackageTree,\n graphToSerializablePackageTree,\n} from '../output/json/deps.js'\nimport type { PackageDependencyDiffGraph } from '../types/package-dependency-diff-graph.js'\nimport type { PackageDependencyGraph } from '../types/package-dependency-graph.js'\nimport { BaseCommand } from './base.js'\n\nexport class DepsCommand extends BaseCommand<\n PackageDependencyGraph | PackageDependencyDiffGraph,\n DepsCliOptions\n> {\n protected analyze(): PackageDependencyGraph | PackageDependencyDiffGraph {\n if (this.options.diff !== undefined) {\n return analyzePackageDependencyDiff(\n this.options.directory,\n this.options.diff,\n )\n }\n\n return analyzePackageDependencies(this.options.directory)\n }\n\n protected serialize(\n graph: PackageDependencyGraph | PackageDependencyDiffGraph,\n ): object {\n if (isPackageDependencyDiffGraph(graph)) {\n return diffGraphToSerializablePackageTree(graph)\n }\n\n return graphToSerializablePackageTree(graph)\n }\n\n protected render(\n graph: PackageDependencyGraph | PackageDependencyDiffGraph,\n ): string {\n if (isPackageDependencyDiffGraph(graph)) {\n return printPackageDependencyDiffTree(graph)\n }\n\n return printPackageDependencyTree(graph)\n }\n}\n\nfunction isPackageDependencyDiffGraph(\n graph: PackageDependencyGraph | PackageDependencyDiffGraph,\n): graph is PackageDependencyDiffGraph {\n return 'root' in graph\n}\n","import { analyzeDependencies } from '../analyzers/import/index.js'\nimport type { ImportCliOptions } from '../app/args.js'\nimport { printDependencyTree } from '../output/ascii/import.js'\nimport { graphToSerializableTree } from '../output/json/import.js'\nimport type { DependencyGraph } from '../types/dependency-graph.js'\nimport { BaseCommand } from './base.js'\n\nexport class ImportCommand extends BaseCommand<\n DependencyGraph,\n ImportCliOptions\n> {\n protected analyze(): DependencyGraph {\n return analyzeDependencies(this.options.entryFile, this.getAnalyzeOptions())\n }\n\n protected serialize(graph: DependencyGraph): object {\n return graphToSerializableTree(graph, {\n omitUnused: this.options.omitUnused,\n })\n }\n\n protected render(graph: DependencyGraph): string {\n return printDependencyTree(graph, {\n cwd: this.options.cwd ?? graph.cwd,\n includeExternals: this.options.includeExternals,\n omitUnused: this.options.omitUnused,\n })\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { isSourceCodeFile } from '../utils/is-source-code-file.js'\nimport type { ReactCliOptions } from './args.js'\n\nconst NEXT_JS_ENTRY_ROOTS = [\n 'pages',\n 'app',\n path.join('src', 'pages'),\n path.join('src', 'app'),\n]\n\nexport function resolveReactEntryFiles(options: ReactCliOptions): string[] {\n if (options.entryFile !== undefined) {\n return [options.entryFile]\n }\n\n if (!options.nextjs) {\n throw new Error(\n 'Missing React entry file. Use `foresthouse react <entry-file>` or `foresthouse react --nextjs`.',\n )\n }\n\n return discoverNextJsPageEntries(options.cwd)\n}\n\nexport function discoverNextJsPageEntries(cwd?: string): string[] {\n const effectiveCwd = path.resolve(cwd ?? process.cwd())\n const entries = new Set<string>()\n\n collectPagesRouterEntries(\n path.join(effectiveCwd, 'pages'),\n effectiveCwd,\n entries,\n )\n collectAppRouterEntries(path.join(effectiveCwd, 'app'), effectiveCwd, entries)\n collectPagesRouterEntries(\n path.join(effectiveCwd, 'src', 'pages'),\n effectiveCwd,\n entries,\n )\n collectAppRouterEntries(\n path.join(effectiveCwd, 'src', 'app'),\n effectiveCwd,\n entries,\n )\n\n const resolvedEntries = [...entries].sort()\n if (resolvedEntries.length > 0) {\n return resolvedEntries\n }\n\n const searchedRoots = NEXT_JS_ENTRY_ROOTS.map((root) => `\\`${root}/\\``).join(\n ', ',\n )\n throw new Error(\n `No Next.js page entries found. Searched ${searchedRoots} relative to ${effectiveCwd}.`,\n )\n}\n\nfunction collectPagesRouterEntries(\n rootDirectory: string,\n cwd: string,\n entries: Set<string>,\n): void {\n walkDirectory(rootDirectory, (filePath, relativePath) => {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n return\n }\n\n const segments = relativePath.split(path.sep)\n if (segments[0] === 'api') {\n return\n }\n\n const baseName = path.basename(filePath)\n if (baseName.startsWith('_')) {\n return\n }\n\n entries.add(path.relative(cwd, filePath))\n })\n}\n\nfunction collectAppRouterEntries(\n rootDirectory: string,\n cwd: string,\n entries: Set<string>,\n): void {\n walkDirectory(rootDirectory, (filePath) => {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n return\n }\n\n const extension = path.extname(filePath)\n const baseName = path.basename(filePath, extension)\n if (baseName !== 'page') {\n return\n }\n\n entries.add(path.relative(cwd, filePath))\n })\n}\n\nfunction walkDirectory(\n rootDirectory: string,\n visitor: (filePath: string, relativePath: string) => void,\n): void {\n if (!fs.existsSync(rootDirectory)) {\n return\n }\n\n const stack = [rootDirectory]\n\n while (stack.length > 0) {\n const directory = stack.pop()\n if (directory === undefined) {\n continue\n }\n\n const directoryEntries = fs\n .readdirSync(directory, { withFileTypes: true })\n .sort((left, right) => left.name.localeCompare(right.name))\n\n for (let index = directoryEntries.length - 1; index >= 0; index -= 1) {\n const entry = directoryEntries[index]\n if (entry === undefined) {\n continue\n }\n\n const entryPath = path.join(directory, entry.name)\n if (entry.isDirectory()) {\n stack.push(entryPath)\n continue\n }\n\n if (!entry.isFile()) {\n continue\n }\n\n visitor(entryPath, path.relative(rootDirectory, entryPath))\n }\n }\n}\n","import { analyzeReactUsage } from '../analyzers/react/index.js'\nimport type { ReactCliOptions } from '../app/args.js'\nimport { resolveReactEntryFiles } from '../app/react-entry-files.js'\nimport { printReactUsageTree } from '../output/ascii/react.js'\nimport { graphToSerializableReactTree } from '../output/json/react.js'\nimport type { AnalyzeOptions } from '../types/analyze-options.js'\nimport type { ReactUsageFilter } from '../types/react-usage-filter.js'\nimport type { ReactUsageGraph } from '../types/react-usage-graph.js'\nimport { BaseCommand } from './base.js'\n\nexport class ReactCommand extends BaseCommand<\n ReactUsageGraph,\n ReactCliOptions\n> {\n protected analyze(): ReactUsageGraph {\n return analyzeReactUsage(\n resolveReactEntryFiles(this.options),\n this.getAnalyzeOptions(),\n )\n }\n\n protected serialize(graph: ReactUsageGraph): object {\n return graphToSerializableReactTree(graph, {\n filter: this.getFilter(),\n })\n }\n\n protected render(graph: ReactUsageGraph): string {\n return printReactUsageTree(graph, {\n cwd: this.options.cwd ?? graph.cwd,\n filter: this.getFilter(),\n })\n }\n\n protected getAnalyzeOptions(): AnalyzeOptions {\n return {\n ...super.getAnalyzeOptions(),\n includeBuiltins: this.options.includeBuiltins,\n }\n }\n\n private getFilter(): ReactUsageFilter {\n return this.options.filter\n }\n}\n","import { DepsCommand } from '../commands/deps.js'\nimport { ImportCommand } from '../commands/import.js'\nimport { ReactCommand } from '../commands/react.js'\nimport type { CliOptions } from './args.js'\n\nexport function runCli(options: CliOptions): void {\n new CliApplication(options).run()\n}\n\nclass CliApplication {\n constructor(private readonly options: CliOptions) {}\n\n run(): void {\n this.createCommand().run()\n }\n\n private createCommand(): {\n run(): void\n } {\n if (this.options.command === 'deps') {\n return new DepsCommand(this.options)\n }\n\n if (this.options.command === 'react') {\n return new ReactCommand(this.options)\n }\n\n return new ImportCommand(this.options)\n }\n}\n","import process from 'node:process'\n\nimport { cac } from 'cac'\n\nimport type { ReactUsageFilter } from '../types/react-usage-filter.js'\nimport type {\n DepsCliOptions,\n ImportCliOptions,\n ReactCliOptions,\n} from './args.js'\nimport { runCli } from './run.js'\n\nexport function main(version: string, argv = process.argv.slice(2)): void {\n new CliMain(version, argv).run()\n}\n\nclass CliMain {\n constructor(\n private readonly version: string,\n private readonly argv: string[],\n ) {}\n\n run(): void {\n try {\n const cli = this.createCli()\n\n if (this.argv.length === 0) {\n cli.outputHelp()\n return\n }\n\n this.validateCommandSyntax()\n cli.parse(this.toProcessArgv())\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error occurred.'\n process.stderr.write(`foresthouse: ${message}\\n`)\n process.exitCode = 1\n }\n }\n\n private createCli() {\n const cli = cac('foresthouse')\n\n cli\n .command(\n 'deps <directory>',\n 'Analyze package.json dependencies from a package directory.',\n )\n .usage('deps <directory> [options]')\n .option(\n '--diff <git-ref-or-range>',\n 'Show only dependency-tree changes relative to a Git revision or range.',\n )\n .option('--json', 'Print the package tree as JSON.')\n .action((directory: string, rawOptions: ParsedDepsCliOptions) => {\n runCli(normalizeDepsCliOptions(directory, rawOptions))\n })\n\n cli\n .command(\n 'import [entry-file]',\n 'Analyze an entry file and print its dependency tree.',\n )\n .usage('import <entry-file> [options]')\n .option('--entry <path>', 'Entry file to analyze.')\n .option('--cwd <path>', 'Working directory used for relative paths.')\n .option(\n '--config <path>',\n 'Explicit tsconfig.json or jsconfig.json path.',\n )\n .option(\n '--include-externals',\n 'Include packages and Node built-ins in the tree.',\n )\n .option(\n '--no-workspaces',\n 'Do not expand sibling workspace packages into source subtrees.',\n )\n .option(\n '--project-only',\n 'Restrict traversal to the active tsconfig.json or jsconfig.json project.',\n )\n .option('--no-unused', 'Omit imports that are never referenced.')\n .option('--json', 'Print the dependency tree as JSON.')\n .action(\n (entryFile: string | undefined, rawOptions: ParsedImportCliOptions) => {\n runCli(normalizeImportCliOptions(entryFile, rawOptions))\n },\n )\n\n cli\n .command('react [entry-file]', 'Analyze React usage from an entry file.')\n .usage('react [entry-file] [options]')\n .option('--cwd <path>', 'Working directory used for relative paths.')\n .option(\n '--config <path>',\n 'Explicit tsconfig.json or jsconfig.json path.',\n )\n .option(\n '--nextjs',\n 'Infer Next.js page entries from app/ and pages/ when no entry is provided.',\n )\n .option(\n '--filter <mode>',\n 'Limit output to `component`, `hook`, or `builtin` usages.',\n )\n .option('--builtin', 'Include built-in HTML nodes in the React tree.')\n .option(\n '--no-workspaces',\n 'Do not expand sibling workspace packages into source subtrees.',\n )\n .option(\n '--project-only',\n 'Restrict traversal to the active tsconfig.json or jsconfig.json project.',\n )\n .option('--json', 'Print the React usage tree as JSON.')\n .action(\n (entryFile: string | undefined, rawOptions: ParsedReactCliOptions) => {\n runCli(normalizeReactCliOptions(entryFile, rawOptions))\n },\n )\n\n cli.help()\n cli.version(this.version)\n\n return cli\n }\n\n private validateCommandSyntax(): void {\n if (this.argv.length === 0) {\n return\n }\n\n const firstArgument = this.argv[0]\n\n if (firstArgument === undefined) {\n return\n }\n\n if (firstArgument === '--react' || firstArgument.startsWith('--react=')) {\n throw new Error('Unknown option `--react`')\n }\n\n if (firstArgument.startsWith('-')) {\n return\n }\n\n if (\n firstArgument === 'deps' ||\n firstArgument === 'import' ||\n firstArgument === 'react'\n ) {\n return\n }\n\n throw new Error(`Unknown command \\`${firstArgument}\\``)\n }\n\n private toProcessArgv(): string[] {\n return ['node', 'foresthouse', ...this.argv]\n }\n}\n\ninterface ParsedBaseCliOptions {\n readonly cwd?: string\n readonly config?: string\n readonly workspaces?: boolean\n readonly projectOnly?: boolean\n readonly json?: boolean\n}\n\ninterface ParsedDepsCliOptions {\n readonly diff?: string\n readonly json?: boolean\n}\n\ninterface ParsedImportCliOptions extends ParsedBaseCliOptions {\n readonly entry?: string\n readonly includeExternals?: boolean\n readonly unused?: boolean\n}\n\ninterface ParsedReactCliOptions extends ParsedBaseCliOptions {\n readonly filter?: string\n readonly nextjs?: boolean\n readonly builtin?: boolean\n}\n\nfunction normalizeDepsCliOptions(\n directory: string,\n options: ParsedDepsCliOptions,\n): DepsCliOptions {\n return {\n command: 'deps',\n directory,\n diff: options.diff,\n cwd: undefined,\n configPath: undefined,\n expandWorkspaces: true,\n projectOnly: false,\n json: options.json === true,\n }\n}\n\nfunction normalizeImportCliOptions(\n entryFile: string | undefined,\n options: ParsedImportCliOptions,\n): ImportCliOptions {\n return {\n command: 'import',\n entryFile: resolveImportEntryFile(entryFile, options.entry),\n cwd: options.cwd,\n configPath: options.config,\n expandWorkspaces: options.workspaces !== false,\n projectOnly: options.projectOnly === true,\n includeExternals: options.includeExternals === true,\n omitUnused: options.unused === false,\n json: options.json === true,\n }\n}\n\nfunction normalizeReactCliOptions(\n entryFile: string | undefined,\n options: ParsedReactCliOptions,\n): ReactCliOptions {\n return {\n command: 'react',\n entryFile: resolveReactEntryFile(entryFile, options.nextjs),\n cwd: options.cwd,\n configPath: options.config,\n expandWorkspaces: options.workspaces !== false,\n projectOnly: options.projectOnly === true,\n json: options.json === true,\n filter: normalizeReactFilter(options.filter),\n nextjs: options.nextjs === true,\n includeBuiltins: options.builtin === true,\n }\n}\n\nfunction resolveImportEntryFile(\n positionalEntryFile: string | undefined,\n optionEntryFile: string | undefined,\n): string {\n if (\n positionalEntryFile !== undefined &&\n optionEntryFile !== undefined &&\n positionalEntryFile !== optionEntryFile\n ) {\n throw new Error(\n 'Provide the import entry only once, either as `foresthouse import <entry-file>` or `foresthouse import --entry <path>`.',\n )\n }\n\n const resolvedEntryFile = positionalEntryFile ?? optionEntryFile\n\n if (resolvedEntryFile === undefined) {\n throw new Error(\n 'Missing import entry file. Use `foresthouse import <entry-file>` or `foresthouse import --entry <path>`.',\n )\n }\n\n return resolvedEntryFile\n}\n\nfunction normalizeReactFilter(\n filter: ParsedReactCliOptions['filter'],\n): ReactUsageFilter {\n if (filter === undefined) {\n return 'all'\n }\n\n if (filter === 'component' || filter === 'hook' || filter === 'builtin') {\n return filter\n }\n\n throw new Error(`Unknown React filter: ${filter}`)\n}\n\nfunction resolveReactEntryFile(\n entryFile: string | undefined,\n nextjs: boolean | undefined,\n): string | undefined {\n if (entryFile !== undefined) {\n return entryFile\n }\n\n if (nextjs === true) {\n return undefined\n }\n\n throw new Error(\n 'Missing React entry file. Use `foresthouse react <entry-file>` or `foresthouse react --nextjs`.',\n )\n}\n","#!/usr/bin/env node\n\nimport { createRequire } from 'node:module'\n\nimport { main } from './app/cli.js'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nmain(version)\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,78 @@
|
|
|
1
|
+
//#region src/types/package-dependency-change-kind.d.ts
|
|
2
|
+
type PackageDependencyChangeKind = 'added' | 'removed' | 'changed' | 'unchanged';
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/types/package-dependency-diff-dependency.d.ts
|
|
5
|
+
interface PackageDependencyDiffState {
|
|
6
|
+
readonly target: string;
|
|
7
|
+
readonly specifier?: string;
|
|
8
|
+
}
|
|
9
|
+
interface BasePackageDependencyDiffDependency {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly change: PackageDependencyChangeKind;
|
|
12
|
+
readonly before?: PackageDependencyDiffState;
|
|
13
|
+
readonly after?: PackageDependencyDiffState;
|
|
14
|
+
}
|
|
15
|
+
interface ExternalPackageDependencyDiff extends BasePackageDependencyDiffDependency {
|
|
16
|
+
readonly kind: 'external';
|
|
17
|
+
}
|
|
18
|
+
interface WorkspacePackageDependencyDiff extends BasePackageDependencyDiffDependency {
|
|
19
|
+
readonly kind: 'workspace';
|
|
20
|
+
readonly node: PackageDependencyDiffNode;
|
|
21
|
+
}
|
|
22
|
+
type PackageDependencyDiffDependency = ExternalPackageDependencyDiff | WorkspacePackageDependencyDiff;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/types/package-dependency-diff-node.d.ts
|
|
25
|
+
interface PackageDependencyDiffNode {
|
|
26
|
+
readonly kind: 'root' | 'workspace' | 'circular';
|
|
27
|
+
readonly label: string;
|
|
28
|
+
readonly packageName: string;
|
|
29
|
+
readonly path: string;
|
|
30
|
+
readonly change: PackageDependencyChangeKind;
|
|
31
|
+
readonly beforePackageName?: string;
|
|
32
|
+
readonly afterPackageName?: string;
|
|
33
|
+
readonly dependencies: readonly PackageDependencyDiffDependency[];
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/types/package-dependency-diff-graph.d.ts
|
|
37
|
+
interface PackageDependencyDiffGraph {
|
|
38
|
+
readonly repositoryRoot: string;
|
|
39
|
+
readonly root: PackageDependencyDiffNode;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/analyzers/deps/diff.d.ts
|
|
43
|
+
declare function analyzePackageDependencyDiff(directory: string, diff: string): PackageDependencyDiffGraph;
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/types/package-manifest-dependency.d.ts
|
|
46
|
+
interface ExternalPackageManifestDependency {
|
|
47
|
+
readonly kind: 'external';
|
|
48
|
+
readonly name: string;
|
|
49
|
+
readonly specifier: string;
|
|
50
|
+
}
|
|
51
|
+
interface WorkspacePackageManifestDependency {
|
|
52
|
+
readonly kind: 'workspace';
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly specifier?: string;
|
|
55
|
+
readonly target: string;
|
|
56
|
+
}
|
|
57
|
+
type PackageManifestDependency = ExternalPackageManifestDependency | WorkspacePackageManifestDependency;
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/types/package-dependency-node.d.ts
|
|
60
|
+
interface PackageDependencyNode {
|
|
61
|
+
readonly packageDir: string;
|
|
62
|
+
readonly packageName: string;
|
|
63
|
+
readonly dependencies: readonly PackageManifestDependency[];
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/types/package-dependency-graph.d.ts
|
|
67
|
+
interface PackageDependencyGraph {
|
|
68
|
+
readonly repositoryRoot: string;
|
|
69
|
+
readonly rootId: string;
|
|
70
|
+
readonly nodes: ReadonlyMap<string, PackageDependencyNode>;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/analyzers/deps/index.d.ts
|
|
74
|
+
declare function analyzePackageDependencies(directory: string): PackageDependencyGraph;
|
|
75
|
+
//#endregion
|
|
1
76
|
//#region src/types/analyze-options.d.ts
|
|
2
77
|
interface AnalyzeOptions {
|
|
3
78
|
readonly cwd?: string;
|
|
@@ -101,6 +176,15 @@ declare function getFilteredUsages(node: ReactUsageNode, graph: ReactUsageGraph,
|
|
|
101
176
|
//#region src/types/color-mode.d.ts
|
|
102
177
|
type ColorMode = boolean | 'auto';
|
|
103
178
|
//#endregion
|
|
179
|
+
//#region src/types/print-package-tree-options.d.ts
|
|
180
|
+
interface PrintPackageTreeOptions {
|
|
181
|
+
readonly color?: ColorMode;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/output/ascii/deps.d.ts
|
|
185
|
+
declare function printPackageDependencyTree(graph: PackageDependencyGraph, _options?: PrintPackageTreeOptions): string;
|
|
186
|
+
declare function printPackageDependencyDiffTree(graph: PackageDependencyDiffGraph, options?: PrintPackageTreeOptions): string;
|
|
187
|
+
//#endregion
|
|
104
188
|
//#region src/types/print-tree-options.d.ts
|
|
105
189
|
interface PrintTreeOptions {
|
|
106
190
|
readonly cwd?: string;
|
|
@@ -122,6 +206,10 @@ interface PrintReactTreeOptions {
|
|
|
122
206
|
//#region src/output/ascii/react.d.ts
|
|
123
207
|
declare function printReactUsageTree(graph: ReactUsageGraph, options?: PrintReactTreeOptions): string;
|
|
124
208
|
//#endregion
|
|
209
|
+
//#region src/output/json/deps.d.ts
|
|
210
|
+
declare function graphToSerializablePackageTree(graph: PackageDependencyGraph): object;
|
|
211
|
+
declare function diffGraphToSerializablePackageTree(graph: PackageDependencyDiffGraph): object;
|
|
212
|
+
//#endregion
|
|
125
213
|
//#region src/output/json/import.d.ts
|
|
126
214
|
declare function graphToSerializableTree(graph: DependencyGraph, options?: {
|
|
127
215
|
readonly omitUnused?: boolean;
|
|
@@ -132,5 +220,5 @@ declare function graphToSerializableReactTree(graph: ReactUsageGraph, options?:
|
|
|
132
220
|
readonly filter?: ReactUsageFilter;
|
|
133
221
|
}): object;
|
|
134
222
|
//#endregion
|
|
135
|
-
export { type AnalyzeOptions, type ColorMode, type DependencyEdge, type DependencyGraph, type DependencyKind, type PrintReactTreeOptions, type PrintTreeOptions, type ReactSymbolKind, type ReactUsageEdge, type ReactUsageEdgeKind, type ReactUsageEntry, type ReactUsageFilter, type ReactUsageGraph, type ReactUsageLocation, type ReactUsageNode, type ReferenceKind, type SourceModuleNode, analyzeDependencies, analyzeReactUsage, getFilteredUsages, getReactUsageEntries, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
223
|
+
export { type AnalyzeOptions, type ColorMode, type DependencyEdge, type DependencyGraph, type DependencyKind, type PackageDependencyChangeKind, type PackageDependencyDiffDependency, type PackageDependencyDiffGraph, type PackageDependencyDiffNode, type PackageDependencyGraph, type PackageDependencyNode, type PackageManifestDependency, type PrintPackageTreeOptions, type PrintReactTreeOptions, type PrintTreeOptions, type ReactSymbolKind, type ReactUsageEdge, type ReactUsageEdgeKind, type ReactUsageEntry, type ReactUsageFilter, type ReactUsageGraph, type ReactUsageLocation, type ReactUsageNode, type ReferenceKind, type SourceModuleNode, analyzeDependencies, analyzePackageDependencies, analyzePackageDependencyDiff, analyzeReactUsage, diffGraphToSerializablePackageTree, getFilteredUsages, getReactUsageEntries, getReactUsageRoots, graphToSerializablePackageTree, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printPackageDependencyDiffTree, printPackageDependencyTree, printReactUsageTree };
|
|
136
224
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/analyze-options.ts","../src/types/dependency-kind.ts","../src/types/reference-kind.ts","../src/types/dependency-edge.ts","../src/types/source-module-node.ts","../src/types/dependency-graph.ts","../src/analyzers/import/index.ts","../src/types/react-usage-location.ts","../src/types/react-usage-entry.ts","../src/types/react-symbol-kind.ts","../src/types/react-usage-edge-kind.ts","../src/types/react-usage-edge.ts","../src/types/react-usage-node.ts","../src/types/react-usage-graph.ts","../src/analyzers/react/index.ts","../src/types/react-usage-filter.ts","../src/analyzers/react/queries.ts","../src/types/color-mode.ts","../src/types/print-tree-options.ts","../src/output/ascii/import.ts","../src/types/print-react-tree-options.ts","../src/output/ascii/react.ts","../src/output/json/import.ts","../src/output/json/react.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/package-dependency-change-kind.ts","../src/types/package-dependency-diff-dependency.ts","../src/types/package-dependency-diff-node.ts","../src/types/package-dependency-diff-graph.ts","../src/analyzers/deps/diff.ts","../src/types/package-manifest-dependency.ts","../src/types/package-dependency-node.ts","../src/types/package-dependency-graph.ts","../src/analyzers/deps/index.ts","../src/types/analyze-options.ts","../src/types/dependency-kind.ts","../src/types/reference-kind.ts","../src/types/dependency-edge.ts","../src/types/source-module-node.ts","../src/types/dependency-graph.ts","../src/analyzers/import/index.ts","../src/types/react-usage-location.ts","../src/types/react-usage-entry.ts","../src/types/react-symbol-kind.ts","../src/types/react-usage-edge-kind.ts","../src/types/react-usage-edge.ts","../src/types/react-usage-node.ts","../src/types/react-usage-graph.ts","../src/analyzers/react/index.ts","../src/types/react-usage-filter.ts","../src/analyzers/react/queries.ts","../src/types/color-mode.ts","../src/types/print-package-tree-options.ts","../src/output/ascii/deps.ts","../src/types/print-tree-options.ts","../src/output/ascii/import.ts","../src/types/print-react-tree-options.ts","../src/output/ascii/react.ts","../src/output/json/deps.ts","../src/output/json/import.ts","../src/output/json/react.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { analyzeDependencies, analyzeReactUsage, getFilteredUsages, getReactUsageEntries, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
1
|
+
import { a as printReactUsageTree, c as printPackageDependencyTree, d as getReactUsageRoots, f as analyzeReactUsage, g as analyzePackageDependencies, h as analyzePackageDependencyDiff, i as graphToSerializablePackageTree, l as getFilteredUsages, n as graphToSerializableTree, o as printDependencyTree, p as analyzeDependencies, r as diffGraphToSerializablePackageTree, s as printPackageDependencyDiffTree, t as graphToSerializableReactTree, u as getReactUsageEntries } from "./react-B2on-FAy.mjs";
|
|
2
|
+
export { analyzeDependencies, analyzePackageDependencies, analyzePackageDependencyDiff, analyzeReactUsage, diffGraphToSerializablePackageTree, getFilteredUsages, getReactUsageEntries, getReactUsageRoots, graphToSerializablePackageTree, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printPackageDependencyDiffTree, printPackageDependencyTree, printReactUsageTree };
|