@hellpig/anarchy-legal 1.11.1 → 1.12.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoUtilsService.js","sources":["../../src/Services/RepoUtilsService.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport type { TCollected, TDependencyNode, TLicenseEntry, TRepoUtilsService, TRootInfo, TWorkspaceInfo } from '@Anarchy/Legal/Models';\n// eslint-disable-next-line spellcheck/spell-checker\nimport { globby } from 'globby';\n\nexport function RepoUtilsService(): TRepoUtilsService {\n let isDebug: boolean = false;\n\n const setDebugMode = (debug: boolean): void => void (isDebug = debug);\n\n const readJson = async <T extends Record<string, unknown>>(p: string): Promise<T> => JSON.parse(await fs.readFile(p, 'utf8')) as T;\n\n const isExist = async (p: string): Promise<boolean> => {\n try {\n await fs.access(p);\n return true;\n } catch {\n return false;\n }\n };\n\n function debugLog(isDebug: boolean, ...args: ReadonlyArray<unknown>): void {\n if (isDebug) console.log('[debug]', ...args);\n }\n\n function hasWorkspacesField(pkg: any): boolean {\n const ws = pkg?.workspaces;\n if (!ws) return false;\n if (Array.isArray(ws)) return ws.length > 0;\n if (typeof ws === 'object' && Array.isArray(ws.packages)) return ws.packages.length > 0;\n return false;\n }\n\n async function loadWorkspaces(rootDir: string): Promise<ReadonlyMap<string, TWorkspaceInfo>> {\n const rootPkg = await readJson<any>(path.join(rootDir, 'package.json'));\n const patterns: string[] = Array.isArray(rootPkg.workspaces) ? rootPkg.workspaces : (rootPkg.workspaces?.packages ?? []);\n if (!patterns.length) throw new Error(`No workspaces patterns in ${path.join(rootDir, 'package.json')}`);\n // eslint-disable-next-line spellcheck/spell-checker\n const dirs: string[] = await globby(patterns, {\n cwd: rootDir,\n absolute: true,\n onlyDirectories: true,\n gitignore: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/dist-*/**', '**/.*/**']\n });\n const entries = (\n await Promise.all(\n dirs.map(async (dir): Promise<[string, TWorkspaceInfo] | undefined> => {\n const pkgPath: string = path.join(dir, 'package.json');\n if (!(await isExist(pkgPath))) return undefined;\n const pkg = await readJson<{\n name: string;\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n }>(pkgPath);\n const name: string | undefined = typeof pkg.name === 'string' ? pkg.name : undefined;\n return name ? ([name, { name, dir, pkgPath, pkg }] as const) : undefined;\n })\n )\n ).filter(Boolean) as Array<[string, TWorkspaceInfo]>;\n return new Map(entries);\n }\n\n async function findMonorepoRoot(startDir: string): Promise<string> {\n const start: string = path.resolve(startDir);\n debugLog(isDebug, 'findMonorepoRoot: start at', start);\n\n const searchUp = async (dir: string, depth: number): Promise<string | undefined> => {\n if (depth > 50) return undefined;\n const pkgPath: string = path.join(dir, 'package.json');\n debugLog(isDebug, 'check', pkgPath);\n if (await isExist(pkgPath)) {\n try {\n const pkg = await readJson<any>(pkgPath);\n if (hasWorkspacesField(pkg)) {\n debugLog(isDebug, 'found workspaces at', pkgPath);\n return dir;\n }\n } catch (e) {\n debugLog(isDebug, ' ! failed to parse', pkgPath, '-', (e as Error).message);\n }\n }\n const parent: string = path.dirname(dir);\n if (parent === dir) return undefined;\n return searchUp(parent, depth + 1);\n };\n\n const found: string | undefined = await searchUp(start, 0);\n if (!found) throw new Error(`Monorepo root not found starting from \"${startDir}\". Provide --root explicitly pointing to a package.json with \"workspaces\".`);\n return found;\n }\n\n async function loadRoot(rootDir: string): Promise<TRootInfo> {\n const rootPkgPath: string = path.join(rootDir, 'package.json');\n if (!(await isExist(rootPkgPath))) throw new Error(`Root package.json not found at: ${rootPkgPath}`);\n\n const rootPkg: TRootInfo['rootPkg'] = await readJson<TRootInfo['rootPkg']>(rootPkgPath);\n const wsField = rootPkg.workspaces;\n if (!wsField) throw new Error(`\"workspaces\" not found in root package.json at ${rootPkgPath}`);\n\n const patterns: ReadonlyArray<string> = Array.isArray(wsField) ? wsField : ((wsField as any).packages ?? []);\n if (patterns.length === 0) throw new Error(`\"workspaces\" has no packages in ${rootPkgPath}`);\n\n debugLog(isDebug, 'workspaces patterns:', patterns);\n\n // eslint-disable-next-line spellcheck/spell-checker\n const dirs: ReadonlyArray<string> = await globby(patterns, {\n cwd: rootDir,\n onlyDirectories: true,\n absolute: true,\n expandDirectories: false,\n gitignore: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/dist-*/**', '**/.*/**']\n });\n\n debugLog(isDebug, 'workspace dirs found:', dirs.length);\n\n const entries: Array<[string, TWorkspaceInfo]> = (\n await Promise.all(\n dirs.map(async (dir: string): Promise<[string, TWorkspaceInfo] | undefined> => {\n const pkgPath: string = path.join(dir, 'package.json');\n if (!(await isExist(pkgPath))) return undefined;\n const pkg = await readJson<TWorkspaceInfo['pkg']>(pkgPath);\n if (!pkg.name) return undefined;\n return [\n pkg.name,\n {\n name: pkg.name,\n dir,\n pkgPath,\n pkg\n }\n ];\n })\n )\n ).filter(Boolean) as Array<[string, TWorkspaceInfo]>;\n\n debugLog(isDebug, 'workspace packages loaded:', entries.length);\n\n if (entries.length === 0) throw new Error(`No workspace package.json files found by patterns: ${patterns.join(', ')}`);\n\n return {\n rootDir,\n rootPkgPath,\n rootPkg,\n workspaces: new Map(entries)\n };\n }\n\n function buildWsGraph(ws: ReadonlyMap<string, TWorkspaceInfo>): ReadonlyMap<string, ReadonlySet<string>> {\n const names: Set<string> = new Set(ws.keys());\n const graph = Array.from(ws.entries()).reduce((acc, [name, info]) => {\n const deps: Record<string, string> = info.pkg.dependencies ?? {};\n const edges: Set<string> = new Set<string>(Object.keys(deps).filter((dependencyName) => names.has(dependencyName)));\n acc.set(name, edges);\n return acc;\n }, new Map<string, ReadonlySet<string>>());\n\n if (isDebug) {\n console.log('[debug] workspace graph:');\n graph.forEach((v: ReadonlySet<string>, k: string) => console.log(' ', k, '->', [...v].join(', ') || '∅'));\n }\n return graph;\n }\n\n function assertNoCycles(graph: ReadonlyMap<string, ReadonlySet<string>>, start: string): void {\n const temp: Set<string> = new Set<string>();\n const perm: Set<string> = new Set<string>();\n let pathStack: ReadonlyArray<string> = [];\n\n // eslint-disable-next-line spellcheck/spell-checker\n const dfs = (u: string): void => {\n if (perm.has(u)) return;\n if (temp.has(u)) {\n const idx: number = pathStack.lastIndexOf(u);\n const cyclePath: string = [...pathStack.slice(idx), u].join(' -> ');\n throw new Error(`Cycle detected between workspaces (prod deps): ${cyclePath}`);\n }\n temp.add(u);\n pathStack = [...pathStack];\n // eslint-disable-next-line spellcheck/spell-checker\n (graph.get(u) ?? new Set<string>()).forEach(dfs);\n pathStack = pathStack.slice(0, pathStack.length - 1);\n temp.delete(u);\n perm.add(u);\n };\n\n // eslint-disable-next-line spellcheck/spell-checker\n dfs(start);\n }\n\n function collectWorkspaceClosure(graph: ReadonlyMap<string, ReadonlySet<string>>, start: string): ReadonlySet<string> {\n const visited: Set<string> = new Set<string>();\n\n const visit = (u: string): void => {\n if (visited.has(u)) return;\n visited.add(u);\n (graph.get(u) ?? new Set<string>()).forEach(visit);\n };\n\n visit(start);\n return visited;\n }\n\n async function npmLsJson(rootDir: string, workspace: string): Promise<TDependencyNode | undefined> {\n return new Promise((resolve, reject): void => {\n const args: ReadonlyArray<string> = ['ls', '-w', workspace, '--json', '--omit=dev', '--all', '--long'];\n debugLog(isDebug, 'spawn:', 'npm', args.join(' '), 'cwd:', rootDir);\n const child = spawn('npm', args, { cwd: rootDir, stdio: ['ignore', 'pipe', 'pipe'] });\n let out: string = '';\n let err: string = '';\n child.stdout.on('data', (d) => (out += String(d)));\n child.stderr.on('data', (d) => (err += String(d)));\n child.on('close', (code: number | null): void => {\n if (code !== 0 && !out) return reject(new Error(`npm ls failed (code ${code}): ${err || 'unknown error'}`));\n\n try {\n const json = JSON.parse(out) as any;\n const normPath = (o: any): string | undefined =>\n // eslint-disable-next-line spellcheck/spell-checker\n typeof o?.path === 'string' ? o.path : typeof o?.realpath === 'string' ? o.realpath : typeof o?.location === 'string' ? (path.isAbsolute(o.location) ? o.location : undefined) : undefined;\n\n const toNode = (name: string, o: any): TDependencyNode => ({\n name,\n version: typeof o?.version === 'string' ? o.version : '0.0.0',\n path: normPath(o),\n license: o?.license,\n repository: o?.repository,\n dependencies: o?.dependencies ? Object.fromEntries(Object.entries(o.dependencies).map(([k, v]) => [k, toNode(k, v)])) : undefined\n });\n\n const rootNode: TDependencyNode = {\n name: json?.name ?? workspace,\n version: json?.version ?? '0.0.0',\n path: normPath(json),\n license: json?.license,\n repository: json?.repository,\n dependencies: json?.dependencies ? Object.fromEntries(Object.entries(json.dependencies).map(([k, v]) => [k, toNode(k, v)])) : undefined\n };\n debugLog(isDebug, 'npm ls parsed root:', rootNode.name, rootNode.version);\n return resolve(rootNode);\n } catch (e) {\n return reject(new Error(`Failed to parse npm ls JSON: ${(e as Error).message}\\nRaw: ${out.slice(0, 2000)}`));\n }\n });\n });\n }\n\n function collectExternalSeedNames(closure: ReadonlySet<string>, wsMap: ReadonlyMap<string, TWorkspaceInfo>, wsNames: ReadonlySet<string>): ReadonlySet<string> {\n const seeds: Set<string> = new Set<string>();\n [...closure].forEach((wsName: string): void => {\n const info: TWorkspaceInfo | undefined = wsMap.get(wsName);\n if (!info) return;\n const deps: Record<string, string> = info.pkg.dependencies ?? {};\n Object.keys(deps).forEach((dependencyName: string): void => {\n if (!wsNames.has(dependencyName)) seeds.add(dependencyName);\n });\n });\n return seeds;\n }\n\n function collectThirdPartyMap(root: TDependencyNode | undefined, wsNames: ReadonlySet<string>, seedNames: ReadonlySet<string>): ReadonlyMap<string, TCollected> {\n const acc: Map<string, TCollected> = new Map<string, TCollected>();\n if (!root || !root.dependencies) return acc;\n if (seedNames.size === 0) return acc;\n\n const visit = (node: TDependencyNode, inside: boolean): void => {\n const isWs: boolean = wsNames.has(node.name);\n const nowInside: boolean = inside || seedNames.has(node.name);\n\n if (nowInside && !isWs && node.version && node.version !== '0.0.0') {\n const id: string = `${node.name}@${node.version}`;\n const prev: TCollected | undefined = acc.get(id);\n const installPath: string | undefined = node.path;\n if (!prev) acc.set(id, { id, name: node.name, version: node.version, installPath });\n else if (!prev.installPath && installPath) acc.set(id, { ...prev, installPath });\n }\n if (node.dependencies) Object.values(node.dependencies).forEach((child) => visit(child, nowInside));\n };\n\n Object.values(root.dependencies).forEach((child: TDependencyNode) => visit(child, false));\n\n debugLog(isDebug, 'third-party collected (seed-filtered):', acc.size);\n return acc;\n }\n\n function resolvePackageDir(pkgName: string, fromDir: string): string | undefined {\n try {\n const req: NodeJS.Require = createRequire(path.join(fromDir, 'package.json'));\n const p: string = req.resolve(`${pkgName}/package.json`);\n return path.dirname(p);\n } catch {\n return undefined;\n }\n }\n\n function fillMissingInstallPaths(collected: Map<string, TCollected>, wsDir: string, rootDir: string): void {\n let filled: number = 0;\n Array.from(collected.entries()).forEach(([id, item]): void => {\n if (!item.installPath) {\n const p: string | undefined = resolvePackageDir(item.name, wsDir) ?? resolvePackageDir(item.name, rootDir);\n if (p) {\n collected.set(id, { ...item, installPath: p });\n filled++;\n }\n }\n });\n debugLog(isDebug, 'install paths filled via resolver:', filled);\n }\n\n async function findLicenseFile(dir: string): Promise<string | undefined> {\n try {\n const list: Array<string> = await fs.readdir(dir);\n const c: string | undefined = list.find((f: string) => {\n const base: string = f.toLowerCase();\n return /^(license|licence|copying|unlicense|notice)(\\..+)?$/.test(base);\n });\n return c ? path.join(dir, c) : undefined;\n } catch {\n return undefined;\n }\n }\n\n function parseSeeLicenseIn(licenseField: unknown): string | undefined {\n if (!licenseField) return undefined;\n const s = typeof licenseField === 'string' ? licenseField : typeof (licenseField as any)?.type === 'string' ? (licenseField as any).type : undefined;\n if (!s) return undefined;\n const m: RegExpExecArray | null = /see\\s+license\\s+in\\s+(.+)$/i.exec(s);\n return m?.[1]?.trim();\n }\n\n async function tryReadLicenseText(pkgDir: string, licenseField: unknown): Promise<string | undefined> {\n const see: string | undefined = parseSeeLicenseIn(licenseField);\n if (see) {\n const p: string = path.join(pkgDir, see);\n if (await isExist(p)) {\n try {\n return await fs.readFile(p, 'utf8');\n } catch {\n /* ignore */\n }\n }\n }\n const license: string | undefined = await findLicenseFile(pkgDir);\n if (license) {\n try {\n return await fs.readFile(license, 'utf8');\n } catch {\n /* ignore */\n }\n }\n return undefined;\n }\n\n const safeString = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined);\n\n function normalizeLicenseValue(licenseField: unknown): string | ReadonlyArray<string> {\n if (!licenseField) return 'UNKNOWN';\n if (typeof licenseField === 'string') return licenseField;\n if (Array.isArray(licenseField)) {\n const arr: any[] = (licenseField as any[]).map((x) => (typeof x === 'string' ? x : typeof (x as any)?.type === 'string' ? (x as any).type : 'UNKNOWN'));\n return arr.length > 0 ? arr : 'UNKNOWN';\n }\n if (typeof licenseField === 'object') {\n const t = (licenseField as any)?.type;\n if (typeof t === 'string') return t;\n }\n return 'UNKNOWN';\n }\n\n async function readPackageMeta(pkgDir: string): Promise<{\n licenseField?: unknown;\n repository?: string;\n publisher?: string;\n email?: string;\n url?: string;\n }> {\n try {\n const pkg = await readJson<any>(path.join(pkgDir, 'package.json'));\n const repo = typeof pkg.repository === 'string' ? pkg.repository : typeof pkg.repository?.url === 'string' ? pkg.repository.url : undefined;\n return {\n licenseField: pkg.license ?? pkg.licenses,\n repository: repo,\n publisher: safeString(pkg.author?.name) ?? safeString(pkg.author) ?? undefined,\n email: safeString(pkg.author?.email) ?? undefined,\n url: safeString(pkg.homepage) ?? undefined\n };\n } catch {\n return {};\n }\n }\n\n async function buildLicenseEntries(collected: ReadonlyMap<string, TCollected>): Promise<ReadonlyArray<TLicenseEntry>> {\n const list = await Promise.all(\n Array.from(collected.values()).map(async ({ id, name, version, installPath }) => {\n let licenseText: string | undefined;\n let licenseType: string | ReadonlyArray<string> | undefined = 'UNKNOWN';\n let repository: string | undefined;\n let publisher: string | undefined;\n let email: string | undefined;\n let url: string | undefined;\n\n if (installPath) {\n const meta = await readPackageMeta(installPath);\n licenseType = normalizeLicenseValue(meta.licenseField);\n repository = meta.repository;\n publisher = meta.publisher;\n email = meta.email;\n url = meta.url;\n\n licenseText = await tryReadLicenseText(installPath, meta.licenseField);\n }\n\n return {\n id,\n name,\n version,\n licenses: licenseType as any,\n licenseText,\n repository,\n publisher,\n email,\n url,\n path: installPath\n } satisfies TLicenseEntry;\n })\n );\n\n return [...list].sort((a, b): number => (a.name === b.name ? a.version.localeCompare(b.version) : a.name.localeCompare(b.name)));\n }\n\n async function buildWorkspaceLicenseEntries(names: ReadonlySet<string>, wsMap: ReadonlyMap<string, TWorkspaceInfo>, excludeName?: string): Promise<ReadonlyArray<TLicenseEntry>> {\n const filtered: any[] = [...names].filter((name) => !(excludeName && name === excludeName));\n const entries = await Promise.all(\n filtered\n .map((name: string) => wsMap.get(name))\n // eslint-disable-next-line functional/prefer-tacit\n .filter((info: TWorkspaceInfo | undefined): info is TWorkspaceInfo => Boolean(info))\n .map(async (info) => {\n const version: string = info.pkg.version ?? '0.0.0';\n const meta = await readPackageMeta(info.dir);\n const licenseType: string | ReadonlyArray<string> = normalizeLicenseValue(meta.licenseField);\n const licenseText: string | undefined = await tryReadLicenseText(info.dir, meta.licenseField);\n return {\n id: `${info.name}@${version}`,\n name: info.name,\n version,\n licenses: licenseType,\n licenseText,\n repository: meta.repository,\n publisher: meta.publisher,\n email: meta.email,\n url: meta.url,\n path: info.dir\n } satisfies TLicenseEntry;\n })\n );\n return [...entries].sort((a, b): number => (a.name === b.name ? a.version.localeCompare(b.version) : a.name.localeCompare(b.name)));\n }\n\n function renderMarkdown(workspaceLabel: string, items: ReadonlyArray<TLicenseEntry>, emptyNote?: string): string {\n const header: ReadonlyArray<string> = [`# Third-Party Licenses`, `## Application: ${workspaceLabel}`, `Production dependencies (including transition dependencies): ${items.length}`, ``];\n const note: ReadonlyArray<string> = items.length === 0 && emptyNote ? [`**Note:** ${emptyNote}`, ``] : [];\n\n const body: ReadonlyArray<string> = items.flatMap((it) => {\n const licenseStr: string = Array.isArray(it.licenses) ? it.licenses.join(', ') : String(it.licenses ?? 'UNKNOWN');\n return [\n `---`,\n ``,\n `## ${it.name}@${it.version}`,\n `**License:** ${licenseStr}\\n`,\n ...(it.repository ? [`**Repository:** ${it.repository}\\n`] : []),\n ...(it.url ? [`**URL:** ${it.url}\\n`] : []),\n ...(it.publisher ? [`**Publisher:** ${it.publisher}${it.email ? ` <${it.email}>` : ''}\\n`] : []),\n ``,\n ...(it.licenseText ? [it.licenseText.trim(), ``] : [`_No license text file found; relying on package metadata._`, ``])\n ];\n });\n\n return [...header, ...note, ...body].join('\\n');\n }\n\n async function resolveWorkspaceFromArg(arg: string, workspaces: ReadonlyMap<string, TWorkspaceInfo>, rootDir: string): Promise<TWorkspaceInfo> {\n const byName: TWorkspaceInfo | undefined = workspaces.get(arg);\n if (byName) return byName;\n\n // as path relative to monorepo root\n const asPath: string = path.isAbsolute(arg) ? arg : path.join(rootDir, arg);\n const norm: string = path.resolve(asPath);\n\n // match any known workspace by directory\n const found: TWorkspaceInfo | undefined = [...workspaces.values()].find((w: TWorkspaceInfo): boolean => path.resolve(w.dir) === norm);\n if (found) return found;\n\n // NEW: allow selecting the monorepo root itself\n const wantRoot: boolean = norm === path.resolve(rootDir) || arg === ':root' || arg === 'root' || arg === '.';\n\n if (wantRoot) {\n const pkgPath: string = path.join(rootDir, 'package.json');\n const pkg: Record<string, unknown> = await readJson(pkgPath);\n const name: string = typeof pkg.name === 'string' ? pkg.name : 'monorepo-root';\n return { name, dir: rootDir, pkgPath, pkg: pkg as any };\n }\n\n throw new Error(`Workspace \"${arg}\" not found by name or path. Tip: use \"--workspace .\" or \"--workspace :root\" to target the monorepo root.`);\n }\n\n return {\n assertNoCycles,\n buildLicenseEntries,\n buildWorkspaceLicenseEntries,\n buildWsGraph,\n collectExternalSeedNames,\n collectThirdPartyMap,\n collectWorkspaceClosure,\n debugLog,\n fillMissingInstallPaths,\n findMonorepoRoot,\n isDebug: (): boolean => isDebug,\n isExist,\n loadRoot,\n loadWorkspaces,\n npmLsJson,\n readJson,\n renderMarkdown,\n resolveWorkspaceFromArg,\n setDebugMode\n };\n}\n"],"names":["isDebug"],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import yargs from "yargs";
5
+ import { hideBin } from "yargs/helpers";
6
+ import { RepoUtilsService } from "./RepoUtilsService.js";
7
+ function ThirdPartyLicensesService() {
8
+ let isDebug = false;
9
+ const repoUtilsService = RepoUtilsService();
10
+ const {
11
+ assertNoCycles,
12
+ buildLicenseEntries,
13
+ buildWorkspaceLicenseEntries,
14
+ buildWsGraph,
15
+ collectExternalSeedNames,
16
+ collectThirdPartyMap,
17
+ collectWorkspaceClosure,
18
+ debugLog,
19
+ fillMissingInstallPaths,
20
+ findMonorepoRoot,
21
+ loadRoot,
22
+ npmLsJson,
23
+ renderMarkdown,
24
+ resolveWorkspaceFromArg
25
+ } = repoUtilsService;
26
+ function getStartCandidates(argv) {
27
+ const scriptDir = path.dirname(fileURLToPath(import.meta.url));
28
+ return [argv.root, process.env.INIT_CWD, process.cwd(), scriptDir].filter(Boolean);
29
+ }
30
+ function getMonorepoRoot(startCandidates) {
31
+ return startCandidates.reduce(async (prev, c) => {
32
+ const acc = await prev;
33
+ if (acc) return acc;
34
+ try {
35
+ const found = await findMonorepoRoot(c);
36
+ debugLog(isDebug, "monorepo root picked:", found, "(from", c + ")");
37
+ return found;
38
+ } catch (e) {
39
+ debugLog(isDebug, "no root from", c, ":", e.message);
40
+ return void 0;
41
+ }
42
+ }, Promise.resolve(void 0));
43
+ }
44
+ async function getWorkspaceEntries(argv, wsName, closure, root) {
45
+ let wsEntries = [];
46
+ if (argv["include-workspaces"] !== false) {
47
+ wsEntries = await buildWorkspaceLicenseEntries(
48
+ closure,
49
+ root.workspaces,
50
+ argv["include-workspace-self"] ? void 0 : wsName
51
+ // exclude self
52
+ );
53
+ }
54
+ return wsEntries;
55
+ }
56
+ function getEmptyNote(sorted, seedNames) {
57
+ if (sorted.length !== 0) return void 0;
58
+ const noSeeds = seedNames.size === 0;
59
+ return noSeeds ? "This workspace declares no production dependencies and has no reachable internal workspaces. Therefore, there are no third-party licenses to list." : "There are no third-party production dependencies reachable from this workspace. Therefore, there are no third-party licenses to list.";
60
+ }
61
+ async function writeResultFile(outPath, wsName, sorted, emptyNote) {
62
+ const resultFile = renderMarkdown(wsName, sorted, emptyNote);
63
+ await fs.mkdir(path.dirname(outPath), { recursive: true });
64
+ await fs.writeFile(outPath, resultFile, "utf8");
65
+ console.log(`The result file written to: ${outPath}`);
66
+ }
67
+ async function generate() {
68
+ const argv = await yargs(hideBin(process.argv)).usage("$0 --workspace <name|path> --out <file> [--root <dir>] [--debug] [--no-include-workspaces]").option("root", {
69
+ type: "string",
70
+ describe: "Starting directory to search for monorepo root. If omitted, uses INIT_CWD, then process.cwd(), then script dir."
71
+ }).option("workspace", {
72
+ type: "string",
73
+ demandOption: true,
74
+ describe: "Target workspace (name from package.json or folder path relative to monorepo root)"
75
+ }).option("out", {
76
+ type: "string",
77
+ demandOption: true,
78
+ describe: "Output path for the result file (relative to current working dir)"
79
+ }).option("debug", {
80
+ type: "boolean",
81
+ default: false,
82
+ describe: "Print verbose diagnostic information"
83
+ }).option("include-workspaces", {
84
+ type: "boolean",
85
+ default: true,
86
+ describe: "Also include licenses of reachable internal workspaces (excluding self by default)"
87
+ }).option("include-workspace-self", {
88
+ type: "boolean",
89
+ default: false,
90
+ describe: "Also include license of the target workspace itself"
91
+ }).help().parseAsync();
92
+ isDebug = Boolean(argv.debug);
93
+ repoUtilsService.setDebugMode(isDebug);
94
+ const startCandidates = getStartCandidates(argv);
95
+ debugLog(isDebug, "start candidates:", startCandidates);
96
+ const monorepoRoot = await getMonorepoRoot(startCandidates);
97
+ if (!monorepoRoot) throw new Error(`Failed to locate monorepo root from candidates: ${startCandidates.join(", ")}`);
98
+ const root = await loadRoot(monorepoRoot);
99
+ debugLog(isDebug, "rootDir:", root.rootDir);
100
+ const { name, dir } = await resolveWorkspaceFromArg(argv.workspace, root.workspaces, root.rootDir);
101
+ debugLog(isDebug, "target workspace:", name, "dir:", dir);
102
+ const graph = buildWsGraph(root.workspaces);
103
+ assertNoCycles(graph, name);
104
+ const closure = collectWorkspaceClosure(graph, name);
105
+ const wsNamesSet = new Set(root.workspaces.keys());
106
+ const seedNames = collectExternalSeedNames(closure, root.workspaces, wsNamesSet);
107
+ debugLog(isDebug, "workspace closure size:", closure.size, "seed external deps:", seedNames.size, "sample:", [...seedNames].slice(0, 10));
108
+ const tree = await npmLsJson(root.rootDir, name);
109
+ const thirdPartyMap = new Map(collectThirdPartyMap(tree, wsNamesSet, seedNames));
110
+ fillMissingInstallPaths(thirdPartyMap, name, root.rootDir);
111
+ if (thirdPartyMap.size === 0) debugLog(isDebug, `[info] No third-party prod deps reachable from seeds.`);
112
+ else if (isDebug) console.log("[debug] examples (third-party):", [...thirdPartyMap.values()].slice(0, 5));
113
+ const wsEntries = await getWorkspaceEntries(argv, name, closure, root);
114
+ debugLog(isDebug, "workspace license entries (after self-filter):", wsEntries.length);
115
+ const thirdEntries = await buildLicenseEntries(thirdPartyMap);
116
+ debugLog(isDebug, "third-party license entries:", thirdEntries.length);
117
+ const merged = [...wsEntries, ...thirdEntries];
118
+ const sorted = [...merged].sort((a, b) => a.name === b.name ? a.version.localeCompare(b.version) : a.name.localeCompare(b.name));
119
+ const outPath = path.isAbsolute(argv.out) ? argv.out : path.join(process.cwd(), argv.out);
120
+ const emptyNote = getEmptyNote(sorted, seedNames);
121
+ debugLog(isDebug, "write output to:", outPath, "total entries:", sorted.length);
122
+ await writeResultFile(outPath, name, sorted, emptyNote);
123
+ }
124
+ return { generate };
125
+ }
126
+ export {
127
+ ThirdPartyLicensesService
128
+ };
129
+ //# sourceMappingURL=ThirdPartyLicensesService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThirdPartyLicensesService.js","sources":["../../src/Services/ThirdPartyLicensesService.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { TCollected, TDependencyNode, TLicenseEntry, TRepoUtilsService, TRootInfo, TThirdPartyGeneratorArgs, TThirdPartyLicensesService } from '@Anarchy/Legal/Models';\n// eslint-disable-next-line spellcheck/spell-checker\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\n\nimport { RepoUtilsService } from './RepoUtilsService.ts';\n\nexport function ThirdPartyLicensesService(): TThirdPartyLicensesService {\n let isDebug: boolean = false;\n const repoUtilsService: TRepoUtilsService = RepoUtilsService();\n\n const {\n assertNoCycles,\n buildLicenseEntries,\n buildWorkspaceLicenseEntries,\n buildWsGraph,\n collectExternalSeedNames,\n collectThirdPartyMap,\n collectWorkspaceClosure,\n debugLog,\n fillMissingInstallPaths,\n findMonorepoRoot,\n loadRoot,\n npmLsJson,\n renderMarkdown,\n resolveWorkspaceFromArg\n } = repoUtilsService;\n\n function getStartCandidates(argv: TThirdPartyGeneratorArgs): ReadonlyArray<string> {\n const scriptDir: string = path.dirname(fileURLToPath(import.meta.url));\n return [argv.root as string | undefined, process.env.INIT_CWD, process.cwd(), scriptDir].filter(Boolean) as string[];\n }\n\n function getMonorepoRoot(startCandidates: ReadonlyArray<string>): Promise<string | undefined> {\n return startCandidates.reduce<Promise<string | undefined>>(async (prev, c) => {\n const acc: string | undefined = await prev;\n if (acc) return acc;\n try {\n const found: string = await findMonorepoRoot(c);\n debugLog(isDebug, 'monorepo root picked:', found, '(from', c + ')');\n return found;\n } catch (e) {\n debugLog(isDebug, 'no root from', c, ':', (e as Error).message);\n return undefined;\n }\n }, Promise.resolve<string | undefined>(undefined));\n }\n\n async function getWorkspaceEntries(argv: TThirdPartyGeneratorArgs, wsName: string, closure: ReadonlySet<string>, root: TRootInfo): Promise<ReadonlyArray<TLicenseEntry>> {\n let wsEntries: ReadonlyArray<TLicenseEntry> = [];\n if (argv['include-workspaces'] !== false) {\n wsEntries = await buildWorkspaceLicenseEntries(\n closure,\n root.workspaces,\n argv['include-workspace-self'] ? undefined : wsName // exclude self\n );\n }\n return wsEntries;\n }\n\n function getEmptyNote(sorted: ReadonlyArray<TLicenseEntry>, seedNames: ReadonlySet<string>): string | undefined {\n if (sorted.length !== 0) return undefined;\n const noSeeds: boolean = seedNames.size === 0;\n return noSeeds\n ? 'This workspace declares no production dependencies and has no reachable internal workspaces. Therefore, there are no third-party licenses to list.'\n : 'There are no third-party production dependencies reachable from this workspace. Therefore, there are no third-party licenses to list.';\n }\n\n async function writeResultFile(outPath: string, wsName: string, sorted: ReadonlyArray<TLicenseEntry>, emptyNote: string | undefined): Promise<void> {\n const resultFile: string = renderMarkdown(wsName, sorted, emptyNote);\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, resultFile, 'utf8');\n console.log(`The result file written to: ${outPath}`);\n }\n\n async function generate(): Promise<void> {\n // eslint-disable-next-line spellcheck/spell-checker\n const argv: TThirdPartyGeneratorArgs = await yargs(hideBin(process.argv))\n // .scriptName('anarchy-legal')\n .usage('$0 --workspace <name|path> --out <file> [--root <dir>] [--debug] [--no-include-workspaces]')\n .option('root', {\n type: 'string',\n describe: 'Starting directory to search for monorepo root. If omitted, uses INIT_CWD, then process.cwd(), then script dir.'\n })\n .option('workspace', {\n type: 'string',\n demandOption: true,\n describe: 'Target workspace (name from package.json or folder path relative to monorepo root)'\n })\n .option('out', {\n type: 'string',\n demandOption: true,\n describe: 'Output path for the result file (relative to current working dir)'\n })\n .option('debug', {\n type: 'boolean',\n default: false,\n describe: 'Print verbose diagnostic information'\n })\n .option('include-workspaces', {\n type: 'boolean',\n default: true,\n describe: 'Also include licenses of reachable internal workspaces (excluding self by default)'\n })\n .option('include-workspace-self', {\n type: 'boolean',\n default: false,\n describe: 'Also include license of the target workspace itself'\n })\n .help()\n .parseAsync();\n\n isDebug = Boolean(argv.debug);\n repoUtilsService.setDebugMode(isDebug);\n\n // 1) Determine start points\n const startCandidates: ReadonlyArray<string> = getStartCandidates(argv);\n debugLog(isDebug, 'start candidates:', startCandidates);\n\n // 2) Find monorepo root\n const monorepoRoot: string | undefined = await getMonorepoRoot(startCandidates);\n if (!monorepoRoot) throw new Error(`Failed to locate monorepo root from candidates: ${startCandidates.join(', ')}`);\n\n // 3) Load root + workspaces\n const root = await loadRoot(monorepoRoot);\n debugLog(isDebug, 'rootDir:', root.rootDir);\n\n // 4) Resolve workspace\n const { name, dir } = await resolveWorkspaceFromArg(argv.workspace as string, root.workspaces, root.rootDir);\n debugLog(isDebug, 'target workspace:', name, 'dir:', dir);\n\n // 5) Cycle check\n const graph: ReadonlyMap<string, ReadonlySet<string>> = buildWsGraph(root.workspaces);\n assertNoCycles(graph, name);\n\n // 6) Workspace closure and seeds\n const closure: ReadonlySet<string> = collectWorkspaceClosure(graph, name);\n const wsNamesSet: ReadonlySet<string> = new Set(root.workspaces.keys());\n const seedNames: ReadonlySet<string> = collectExternalSeedNames(closure, root.workspaces, wsNamesSet);\n debugLog(isDebug, 'workspace closure size:', closure.size, 'seed external deps:', seedNames.size, 'sample:', [...seedNames].slice(0, 10));\n\n // 7) Resolved prod tree\n const tree: TDependencyNode | undefined = await npmLsJson(root.rootDir, name);\n\n // 8) Collect external packages WITH paths (seed-filtered)\n const thirdPartyMap: Map<string, TCollected> = new Map(collectThirdPartyMap(tree, wsNamesSet, seedNames));\n fillMissingInstallPaths(thirdPartyMap, name, root.rootDir);\n\n if (thirdPartyMap.size === 0) debugLog(isDebug, `[info] No third-party prod deps reachable from seeds.`);\n else if (isDebug) console.log('[debug] examples (third-party):', [...thirdPartyMap.values()].slice(0, 5));\n\n // 9) Workspace licenses (excluding self by default)\n const wsEntries: ReadonlyArray<TLicenseEntry> = await getWorkspaceEntries(argv, name, closure, root);\n debugLog(isDebug, 'workspace license entries (after self-filter):', wsEntries.length);\n\n // 10) Third-party licenses\n const thirdEntries: ReadonlyArray<TLicenseEntry> = await buildLicenseEntries(thirdPartyMap);\n debugLog(isDebug, 'third-party license entries:', thirdEntries.length);\n\n // 11) Merge & write\n const merged: ReadonlyArray<TLicenseEntry> = [...wsEntries, ...thirdEntries];\n const sorted: ReadonlyArray<TLicenseEntry> = [...merged].sort((a, b) => (a.name === b.name ? a.version.localeCompare(b.version) : a.name.localeCompare(b.name)));\n\n const outPath: string = path.isAbsolute(argv.out as string) ? (argv.out as string) : path.join(process.cwd(), argv.out as string);\n\n const emptyNote: string | undefined = getEmptyNote(sorted, seedNames);\n\n debugLog(isDebug, 'write output to:', outPath, 'total entries:', sorted.length);\n\n await writeResultFile(outPath, name, sorted, emptyNote);\n }\n\n return { generate };\n}\n"],"names":[],"mappings":"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"}