check-npm-lockfile 0.0.2 → 0.1.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.
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
// src/parsers/yarn-lock.ts
|
|
2
2
|
import lockfile from "@yarnpkg/lockfile";
|
|
3
3
|
import { parse as parseYaml } from "yaml";
|
|
4
|
+
function extractRegistryNameFromResolved(resolved) {
|
|
5
|
+
if (!resolved || !resolved.startsWith("npm:")) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
const match = resolved.match(/^npm:(@?[^@]+)@/);
|
|
9
|
+
return match ? match[1] : void 0;
|
|
10
|
+
}
|
|
11
|
+
function extractRegistryNameFromKey(key) {
|
|
12
|
+
const npmMatch = key.match(/@npm:(@?[^@]+)@/);
|
|
13
|
+
return npmMatch ? npmMatch[1] : void 0;
|
|
14
|
+
}
|
|
4
15
|
function detectYarnVersion(content) {
|
|
5
16
|
if (content.includes("__metadata:")) {
|
|
6
17
|
return "yarn-berry";
|
|
@@ -22,11 +33,13 @@ function parseYarnLockV1(content) {
|
|
|
22
33
|
const uniqueKey = `${name}@${version}`;
|
|
23
34
|
if (seen.has(uniqueKey)) continue;
|
|
24
35
|
seen.add(uniqueKey);
|
|
36
|
+
const resolved = value.resolved;
|
|
25
37
|
packages.push({
|
|
26
38
|
name,
|
|
27
39
|
version,
|
|
28
|
-
resolved
|
|
29
|
-
integrity: value.integrity
|
|
40
|
+
resolved,
|
|
41
|
+
integrity: value.integrity,
|
|
42
|
+
registryName: extractRegistryNameFromKey(key) || extractRegistryNameFromResolved(resolved)
|
|
30
43
|
});
|
|
31
44
|
}
|
|
32
45
|
return packages;
|
|
@@ -46,11 +59,13 @@ function parseYarnLockBerry(content) {
|
|
|
46
59
|
const uniqueKey = `${name}@${version}`;
|
|
47
60
|
if (seen.has(uniqueKey)) continue;
|
|
48
61
|
seen.add(uniqueKey);
|
|
62
|
+
const resolved = value.resolution;
|
|
49
63
|
packages.push({
|
|
50
64
|
name,
|
|
51
65
|
version,
|
|
52
|
-
resolved
|
|
53
|
-
integrity: value.checksum
|
|
66
|
+
resolved,
|
|
67
|
+
integrity: value.checksum,
|
|
68
|
+
registryName: extractRegistryNameFromKey(descriptor) || extractRegistryNameFromResolved(resolved)
|
|
54
69
|
});
|
|
55
70
|
break;
|
|
56
71
|
}
|
|
@@ -64,6 +79,13 @@ function parseYarnLock(content) {
|
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
// src/parsers/package-lock.ts
|
|
82
|
+
function extractRegistryName(resolved) {
|
|
83
|
+
if (!resolved || !resolved.startsWith("npm:")) {
|
|
84
|
+
return void 0;
|
|
85
|
+
}
|
|
86
|
+
const match = resolved.match(/^npm:(@?[^@]+)@/);
|
|
87
|
+
return match ? match[1] : void 0;
|
|
88
|
+
}
|
|
67
89
|
function parsePackageLock(content) {
|
|
68
90
|
const parsed = JSON.parse(content);
|
|
69
91
|
const lockfileVersion = parsed.lockfileVersion || 1;
|
|
@@ -83,7 +105,8 @@ function parsePackageLockV2(data) {
|
|
|
83
105
|
name: packageName,
|
|
84
106
|
version: info.version,
|
|
85
107
|
resolved: info.resolved,
|
|
86
|
-
integrity: info.integrity
|
|
108
|
+
integrity: info.integrity,
|
|
109
|
+
registryName: extractRegistryName(info.resolved)
|
|
87
110
|
});
|
|
88
111
|
}
|
|
89
112
|
return deduplicatePackages(packages);
|
|
@@ -96,7 +119,8 @@ function parsePackageLockV1(data) {
|
|
|
96
119
|
name,
|
|
97
120
|
version: info.version,
|
|
98
121
|
resolved: info.resolved,
|
|
99
|
-
integrity: info.integrity
|
|
122
|
+
integrity: info.integrity,
|
|
123
|
+
registryName: extractRegistryName(info.resolved)
|
|
100
124
|
});
|
|
101
125
|
if (info.dependencies) {
|
|
102
126
|
traverse(info.dependencies);
|
|
@@ -221,7 +245,7 @@ async function analyzeLockfile(lockfilePath, options, onProgress) {
|
|
|
221
245
|
let processed = 0;
|
|
222
246
|
const checkPromises = filteredPackages.map(async (pkg) => {
|
|
223
247
|
try {
|
|
224
|
-
const timeInfo = await client.getPackageTime(pkg.name);
|
|
248
|
+
const timeInfo = await client.getPackageTime(pkg.registryName || pkg.name);
|
|
225
249
|
const publishedAt = new Date(timeInfo[pkg.version]);
|
|
226
250
|
if (isNaN(publishedAt.getTime())) {
|
|
227
251
|
throw new Error(`Invalid publish date for version ${pkg.version}`);
|
|
@@ -235,6 +259,7 @@ async function analyzeLockfile(lockfilePath, options, onProgress) {
|
|
|
235
259
|
recentPackages.push({
|
|
236
260
|
name: pkg.name,
|
|
237
261
|
version: pkg.version,
|
|
262
|
+
registryName: pkg.registryName,
|
|
238
263
|
publishedAt,
|
|
239
264
|
isNew,
|
|
240
265
|
daysAgo,
|
|
@@ -341,8 +366,9 @@ function formatConsole(result) {
|
|
|
341
366
|
for (const pkg of result.recentPackages) {
|
|
342
367
|
const newBadge = pkg.isNew ? chalk.bgRed.white(" NEW ") + " " : " ";
|
|
343
368
|
const daysLabel = pkg.daysAgo === 0 ? "today" : pkg.daysAgo === 1 ? "1 day ago" : `${pkg.daysAgo} days ago`;
|
|
369
|
+
const displayName = pkg.registryName ? `${pkg.name} ${chalk.gray("\u2192")} ${pkg.registryName}` : pkg.name;
|
|
344
370
|
console.log(
|
|
345
|
-
`${newBadge}${chalk.bold(
|
|
371
|
+
`${newBadge}${chalk.bold(displayName)}@${chalk.yellow(pkg.version)}`
|
|
346
372
|
);
|
|
347
373
|
console.log(
|
|
348
374
|
` Published: ${chalk.gray(pkg.publishedAt.toISOString())} (${chalk.yellow(daysLabel)})`
|
|
@@ -395,4 +421,4 @@ export {
|
|
|
395
421
|
formatJson,
|
|
396
422
|
formatOutput
|
|
397
423
|
};
|
|
398
|
-
//# sourceMappingURL=chunk-
|
|
424
|
+
//# sourceMappingURL=chunk-WYSKMPXQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/parsers/yarn-lock.ts","../src/parsers/package-lock.ts","../src/registry/npm-client.ts","../src/analyzer/index.ts","../src/output/console.ts","../src/output/json.ts","../src/output/index.ts"],"sourcesContent":["import lockfile from \"@yarnpkg/lockfile\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { ParsedPackage } from \"../types/index.js\";\n\nfunction extractRegistryNameFromResolved(\n resolved: string | undefined\n): string | undefined {\n if (!resolved || !resolved.startsWith(\"npm:\")) {\n return undefined;\n }\n // npm:string-width@4.2.3 → string-width\n // npm:@scope/package@1.0.0 → @scope/package\n const match = resolved.match(/^npm:(@?[^@]+)@/);\n return match ? match[1] : undefined;\n}\n\nfunction extractRegistryNameFromKey(key: string): string | undefined {\n // \"string-width-cjs@npm:string-width@^4.2.0\" → string-width\n // \"alias@npm:@scope/package@^1.0.0\" → @scope/package\n const npmMatch = key.match(/@npm:(@?[^@]+)@/);\n return npmMatch ? npmMatch[1] : undefined;\n}\n\nexport function detectYarnVersion(content: string): \"yarn-v1\" | \"yarn-berry\" {\n if (content.includes(\"__metadata:\")) {\n return \"yarn-berry\";\n }\n return \"yarn-v1\";\n}\n\nexport function parseYarnLockV1(content: string): ParsedPackage[] {\n const result = lockfile.parse(content);\n\n if (result.type !== \"success\") {\n throw new Error(\"Failed to parse yarn.lock file\");\n }\n\n const packages: ParsedPackage[] = [];\n const seen = new Set<string>();\n\n for (const [key, value] of Object.entries(result.object)) {\n const match = key.match(/^(@?[^@]+)@/);\n if (!match) continue;\n\n const name = match[1];\n const version = (value as { version: string }).version;\n const uniqueKey = `${name}@${version}`;\n\n if (seen.has(uniqueKey)) continue;\n seen.add(uniqueKey);\n\n const resolved = (value as { resolved?: string }).resolved;\n packages.push({\n name,\n version,\n resolved,\n integrity: (value as { integrity?: string }).integrity,\n registryName: extractRegistryNameFromKey(key) || extractRegistryNameFromResolved(resolved),\n });\n }\n\n return packages;\n}\n\nexport function parseYarnLockBerry(content: string): ParsedPackage[] {\n const parsed = parseYaml(content) as Record<string, unknown>;\n const packages: ParsedPackage[] = [];\n const seen = new Set<string>();\n\n for (const [key, value] of Object.entries(parsed)) {\n if (key === \"__metadata\") continue;\n\n const descriptors = key.split(\", \");\n\n for (const descriptor of descriptors) {\n const match = descriptor.match(/^(@?[^@]+)@/);\n if (!match) continue;\n\n const name = match[1];\n const version = (value as { version: string }).version;\n const uniqueKey = `${name}@${version}`;\n\n if (seen.has(uniqueKey)) continue;\n seen.add(uniqueKey);\n\n const resolved = (value as { resolution?: string }).resolution;\n packages.push({\n name,\n version,\n resolved,\n integrity: (value as { checksum?: string }).checksum,\n registryName: extractRegistryNameFromKey(descriptor) || extractRegistryNameFromResolved(resolved),\n });\n\n break;\n }\n }\n\n return packages;\n}\n\nexport function parseYarnLock(content: string): {\n packages: ParsedPackage[];\n version: \"yarn-v1\" | \"yarn-berry\";\n} {\n const version = detectYarnVersion(content);\n const packages =\n version === \"yarn-v1\"\n ? parseYarnLockV1(content)\n : parseYarnLockBerry(content);\n return { packages, version };\n}\n","import type { ParsedPackage } from \"../types/index.js\";\n\nfunction extractRegistryName(\n resolved: string | undefined\n): string | undefined {\n if (!resolved || !resolved.startsWith(\"npm:\")) {\n return undefined;\n }\n // npm:string-width@4.2.3 → string-width\n // npm:@scope/package@1.0.0 → @scope/package\n const match = resolved.match(/^npm:(@?[^@]+)@/);\n return match ? match[1] : undefined;\n}\n\ninterface PackageLockV2 {\n lockfileVersion: number;\n packages: Record<\n string,\n {\n version: string;\n resolved?: string;\n integrity?: string;\n }\n >;\n}\n\ninterface PackageLockV1 {\n lockfileVersion: 1;\n dependencies: Record<\n string,\n {\n version: string;\n resolved?: string;\n integrity?: string;\n dependencies?: Record<string, unknown>;\n }\n >;\n}\n\nexport function parsePackageLock(content: string): ParsedPackage[] {\n const parsed = JSON.parse(content) as { lockfileVersion?: number };\n const lockfileVersion = parsed.lockfileVersion || 1;\n\n if (lockfileVersion >= 2) {\n return parsePackageLockV2(parsed as PackageLockV2);\n }\n\n return parsePackageLockV1(parsed as PackageLockV1);\n}\n\nfunction parsePackageLockV2(data: PackageLockV2): ParsedPackage[] {\n const packages: ParsedPackage[] = [];\n\n for (const [path, info] of Object.entries(data.packages || {})) {\n if (path === \"\") continue;\n\n const segments = path.split(\"node_modules/\");\n const packageName = segments[segments.length - 1];\n\n if (!packageName || !info.version) continue;\n\n packages.push({\n name: packageName,\n version: info.version,\n resolved: info.resolved,\n integrity: info.integrity,\n registryName: extractRegistryName(info.resolved),\n });\n }\n\n return deduplicatePackages(packages);\n}\n\nfunction parsePackageLockV1(data: PackageLockV1): ParsedPackage[] {\n const packages: ParsedPackage[] = [];\n\n function traverse(deps: Record<string, { version: string; resolved?: string; integrity?: string; dependencies?: Record<string, unknown> }>) {\n for (const [name, info] of Object.entries(deps)) {\n packages.push({\n name,\n version: info.version,\n resolved: info.resolved,\n integrity: info.integrity,\n registryName: extractRegistryName(info.resolved),\n });\n\n if (info.dependencies) {\n traverse(info.dependencies as typeof deps);\n }\n }\n }\n\n traverse(data.dependencies || {});\n return deduplicatePackages(packages);\n}\n\nfunction deduplicatePackages(packages: ParsedPackage[]): ParsedPackage[] {\n const seen = new Map<string, ParsedPackage>();\n\n for (const pkg of packages) {\n const key = `${pkg.name}@${pkg.version}`;\n if (!seen.has(key)) {\n seen.set(key, pkg);\n }\n }\n\n return Array.from(seen.values());\n}\n","import pLimit from \"p-limit\";\nimport type { PackageTimeInfo } from \"../types/index.js\";\n\nconst NPM_REGISTRY = \"https://registry.npmjs.org\";\n\nexport class NpmRegistryClient {\n private cache: Map<string, PackageTimeInfo> = new Map();\n private limiter: ReturnType<typeof pLimit>;\n private retryDelay = 1000;\n private maxRetries = 3;\n\n constructor(concurrency = 10) {\n this.limiter = pLimit(concurrency);\n }\n\n async getPackageTime(name: string): Promise<PackageTimeInfo> {\n const cached = this.cache.get(name);\n if (cached) return cached;\n\n return this.limiter(async () => {\n const cachedAfterWait = this.cache.get(name);\n if (cachedAfterWait) return cachedAfterWait;\n\n const data = await this.fetchWithRetry(name);\n this.cache.set(name, data);\n return data;\n });\n }\n\n private async fetchWithRetry(\n name: string,\n attempt = 1\n ): Promise<PackageTimeInfo> {\n const url = `${NPM_REGISTRY}/${encodeURIComponent(name).replace(\"%40\", \"@\")}`;\n\n try {\n const response = await fetch(url, {\n headers: {\n Accept: \"application/json\",\n },\n });\n\n if (response.status === 429) {\n if (attempt <= this.maxRetries) {\n const delay = this.retryDelay * Math.pow(2, attempt - 1);\n await this.sleep(delay);\n return this.fetchWithRetry(name, attempt + 1);\n }\n throw new Error(`Rate limited after ${this.maxRetries} retries`);\n }\n\n if (response.status === 404) {\n throw new Error(`Package not found: ${name}`);\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const data = (await response.json()) as { time: PackageTimeInfo };\n return data.time;\n } catch (error) {\n if (attempt <= this.maxRetries && this.isRetryableError(error)) {\n const delay = this.retryDelay * Math.pow(2, attempt - 1);\n await this.sleep(delay);\n return this.fetchWithRetry(name, attempt + 1);\n }\n throw error;\n }\n }\n\n private isRetryableError(error: unknown): boolean {\n if (error instanceof Error) {\n return (\n error.message.includes(\"ECONNRESET\") ||\n error.message.includes(\"ETIMEDOUT\") ||\n error.message.includes(\"fetch failed\")\n );\n }\n return false;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { readFileSync, existsSync } from \"fs\";\nimport { resolve, basename } from \"path\";\nimport { parseYarnLock } from \"../parsers/yarn-lock.js\";\nimport { parsePackageLock } from \"../parsers/package-lock.js\";\nimport { NpmRegistryClient } from \"../registry/npm-client.js\";\nimport type {\n ParsedPackage,\n AnalysisResult,\n PackageCheckResult,\n PackageError,\n CLIOptions,\n LockfileType,\n PackageTimeInfo,\n} from \"../types/index.js\";\n\nexport function parseMinimumReleaseAge(value: string): number {\n const match = value.match(/^(\\d+)\\s*(days?|hours?|minutes?)?$/i);\n if (!match) {\n throw new Error(\n `Invalid minimumReleaseAge format: \"${value}\". Use format like \"3 days\", \"7 days\", or \"24 hours\"`\n );\n }\n\n const num = parseInt(match[1], 10);\n const unit = (match[2] || \"days\").toLowerCase();\n\n if (unit.startsWith(\"day\")) {\n return num;\n } else if (unit.startsWith(\"hour\")) {\n return num / 24;\n } else if (unit.startsWith(\"minute\")) {\n return num / (24 * 60);\n }\n\n return num;\n}\n\nexport async function analyzeLockfile(\n lockfilePath: string | undefined,\n options: CLIOptions,\n onProgress?: (current: number, total: number) => void\n): Promise<AnalysisResult> {\n const resolvedPath = resolveLockfilePath(lockfilePath);\n const content = readFileSync(resolvedPath, \"utf-8\");\n\n const { packages, lockfileType } = parseLockfile(resolvedPath, content);\n\n const filteredPackages = packages.filter(\n (pkg) => !options.exclude.includes(pkg.name)\n );\n\n const client = new NpmRegistryClient(options.concurrency);\n const thresholdDays = parseMinimumReleaseAge(options.minimumReleaseAge);\n const thresholdDate = new Date();\n thresholdDate.setDate(thresholdDate.getDate() - thresholdDays);\n\n const recentPackages: PackageCheckResult[] = [];\n const errors: PackageError[] = [];\n\n const total = filteredPackages.length;\n let processed = 0;\n\n const checkPromises = filteredPackages.map(async (pkg) => {\n try {\n const timeInfo = await client.getPackageTime(pkg.registryName || pkg.name);\n const publishedAt = new Date(timeInfo[pkg.version]);\n\n if (isNaN(publishedAt.getTime())) {\n throw new Error(`Invalid publish date for version ${pkg.version}`);\n }\n\n const daysAgo = Math.floor(\n (Date.now() - publishedAt.getTime()) / (1000 * 60 * 60 * 24)\n );\n\n const isWithinThreshold = publishedAt >= thresholdDate;\n const isNew = isFirstVersion(timeInfo, pkg.version);\n\n if (isWithinThreshold) {\n recentPackages.push({\n name: pkg.name,\n version: pkg.version,\n registryName: pkg.registryName,\n publishedAt,\n isNew,\n daysAgo,\n isWithinThreshold,\n });\n }\n } catch (error) {\n errors.push({\n name: pkg.name,\n version: pkg.version,\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n processed++;\n onProgress?.(processed, total);\n }\n });\n\n await Promise.all(checkPromises);\n\n recentPackages.sort(\n (a, b) => b.publishedAt.getTime() - a.publishedAt.getTime()\n );\n\n return {\n lockfileType,\n lockfilePath: resolvedPath,\n totalPackages: filteredPackages.length,\n checkedPackages: filteredPackages.length - errors.length,\n recentPackages,\n errors,\n analysisDate: new Date(),\n thresholdDays,\n };\n}\n\nfunction resolveLockfilePath(path?: string): string {\n if (path) {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n throw new Error(`Lockfile not found: ${resolved}`);\n }\n return resolved;\n }\n\n const candidates = [\"yarn.lock\", \"package-lock.json\"];\n\n for (const candidate of candidates) {\n const resolved = resolve(candidate);\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n\n throw new Error(\n \"No lockfile found. Please specify a path or run in a directory with yarn.lock or package-lock.json\"\n );\n}\n\nfunction parseLockfile(\n path: string,\n content: string\n): { packages: ParsedPackage[]; lockfileType: LockfileType } {\n const filename = basename(path);\n\n if (filename === \"yarn.lock\") {\n const { packages, version } = parseYarnLock(content);\n return { packages, lockfileType: version };\n }\n\n if (filename === \"package-lock.json\") {\n return {\n packages: parsePackageLock(content),\n lockfileType: \"npm\",\n };\n }\n\n throw new Error(`Unsupported lockfile: ${filename}`);\n}\n\nfunction isFirstVersion(\n timeInfo: PackageTimeInfo,\n version: string\n): boolean {\n const versions = Object.keys(timeInfo).filter(\n (k) => k !== \"created\" && k !== \"modified\"\n );\n\n if (versions.length === 0) return true;\n\n let earliestVersion = versions[0];\n let earliestDate = new Date(timeInfo[versions[0]]);\n\n for (const v of versions) {\n const date = new Date(timeInfo[v]);\n if (date < earliestDate) {\n earliestDate = date;\n earliestVersion = v;\n }\n }\n\n return version === earliestVersion;\n}\n","import chalk from \"chalk\";\nimport type { AnalysisResult } from \"../types/index.js\";\n\nexport function formatConsole(result: AnalysisResult): void {\n console.log();\n console.log(chalk.bold(\"Lockfile Analysis Report\"));\n console.log(chalk.gray(\"-\".repeat(50)));\n console.log(`File: ${chalk.cyan(result.lockfilePath)}`);\n console.log(`Type: ${chalk.cyan(result.lockfileType)}`);\n console.log(`Threshold: ${chalk.yellow(result.thresholdDays)} days`);\n console.log(`Total packages: ${result.totalPackages}`);\n console.log(`Checked: ${result.checkedPackages}`);\n console.log();\n\n if (result.recentPackages.length === 0) {\n console.log(chalk.green(\"No recently published packages found.\"));\n } else {\n console.log(\n chalk.red.bold(\n `Found ${result.recentPackages.length} package(s) published within ${result.thresholdDays} days:`\n )\n );\n console.log();\n\n for (const pkg of result.recentPackages) {\n const newBadge = pkg.isNew ? chalk.bgRed.white(\" NEW \") + \" \" : \" \";\n const daysLabel =\n pkg.daysAgo === 0\n ? \"today\"\n : pkg.daysAgo === 1\n ? \"1 day ago\"\n : `${pkg.daysAgo} days ago`;\n\n const displayName = pkg.registryName\n ? `${pkg.name} ${chalk.gray(\"→\")} ${pkg.registryName}`\n : pkg.name;\n console.log(\n `${newBadge}${chalk.bold(displayName)}@${chalk.yellow(pkg.version)}`\n );\n console.log(\n ` Published: ${chalk.gray(pkg.publishedAt.toISOString())} (${chalk.yellow(daysLabel)})`\n );\n }\n }\n\n if (result.errors.length > 0) {\n console.log();\n console.log(\n chalk.yellow(\n `Warnings: ${result.errors.length} package(s) could not be checked`\n )\n );\n\n for (const err of result.errors) {\n console.log(chalk.gray(` - ${err.name}@${err.version}: ${err.error}`));\n }\n }\n\n console.log();\n}\n","import type { AnalysisResult } from \"../types/index.js\";\n\nexport function formatJson(result: AnalysisResult): void {\n const output = {\n ...result,\n recentPackages: result.recentPackages.map((pkg) => ({\n ...pkg,\n publishedAt: pkg.publishedAt.toISOString(),\n })),\n analysisDate: result.analysisDate.toISOString(),\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n","import type { AnalysisResult } from \"../types/index.js\";\nimport { formatConsole } from \"./console.js\";\nimport { formatJson } from \"./json.js\";\n\nexport function formatOutput(\n result: AnalysisResult,\n format: \"console\" | \"json\"\n): void {\n if (format === \"json\") {\n formatJson(result);\n } else {\n formatConsole(result);\n }\n}\n\nexport { formatConsole } from \"./console.js\";\nexport { formatJson } from \"./json.js\";\n"],"mappings":"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","names":["resolve"]}
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ interface ParsedPackage {
|
|
|
6
6
|
version: string;
|
|
7
7
|
resolved?: string;
|
|
8
8
|
integrity?: string;
|
|
9
|
+
registryName?: string;
|
|
9
10
|
}
|
|
10
11
|
/** npm registry package time information */
|
|
11
12
|
interface PackageTimeInfo {
|
|
@@ -17,6 +18,7 @@ interface PackageTimeInfo {
|
|
|
17
18
|
interface PackageCheckResult {
|
|
18
19
|
name: string;
|
|
19
20
|
version: string;
|
|
21
|
+
registryName?: string;
|
|
20
22
|
publishedAt: Date;
|
|
21
23
|
isNew: boolean;
|
|
22
24
|
daysAgo: number;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parsers/yarn-lock.ts","../src/parsers/package-lock.ts","../src/registry/npm-client.ts","../src/analyzer/index.ts","../src/output/console.ts","../src/output/json.ts","../src/output/index.ts"],"sourcesContent":["import lockfile from \"@yarnpkg/lockfile\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { ParsedPackage } from \"../types/index.js\";\n\nexport function detectYarnVersion(content: string): \"yarn-v1\" | \"yarn-berry\" {\n if (content.includes(\"__metadata:\")) {\n return \"yarn-berry\";\n }\n return \"yarn-v1\";\n}\n\nexport function parseYarnLockV1(content: string): ParsedPackage[] {\n const result = lockfile.parse(content);\n\n if (result.type !== \"success\") {\n throw new Error(\"Failed to parse yarn.lock file\");\n }\n\n const packages: ParsedPackage[] = [];\n const seen = new Set<string>();\n\n for (const [key, value] of Object.entries(result.object)) {\n const match = key.match(/^(@?[^@]+)@/);\n if (!match) continue;\n\n const name = match[1];\n const version = (value as { version: string }).version;\n const uniqueKey = `${name}@${version}`;\n\n if (seen.has(uniqueKey)) continue;\n seen.add(uniqueKey);\n\n packages.push({\n name,\n version,\n resolved: (value as { resolved?: string }).resolved,\n integrity: (value as { integrity?: string }).integrity,\n });\n }\n\n return packages;\n}\n\nexport function parseYarnLockBerry(content: string): ParsedPackage[] {\n const parsed = parseYaml(content) as Record<string, unknown>;\n const packages: ParsedPackage[] = [];\n const seen = new Set<string>();\n\n for (const [key, value] of Object.entries(parsed)) {\n if (key === \"__metadata\") continue;\n\n const descriptors = key.split(\", \");\n\n for (const descriptor of descriptors) {\n const match = descriptor.match(/^(@?[^@]+)@/);\n if (!match) continue;\n\n const name = match[1];\n const version = (value as { version: string }).version;\n const uniqueKey = `${name}@${version}`;\n\n if (seen.has(uniqueKey)) continue;\n seen.add(uniqueKey);\n\n packages.push({\n name,\n version,\n resolved: (value as { resolution?: string }).resolution,\n integrity: (value as { checksum?: string }).checksum,\n });\n\n break;\n }\n }\n\n return packages;\n}\n\nexport function parseYarnLock(content: string): {\n packages: ParsedPackage[];\n version: \"yarn-v1\" | \"yarn-berry\";\n} {\n const version = detectYarnVersion(content);\n const packages =\n version === \"yarn-v1\"\n ? parseYarnLockV1(content)\n : parseYarnLockBerry(content);\n return { packages, version };\n}\n","import type { ParsedPackage } from \"../types/index.js\";\n\ninterface PackageLockV2 {\n lockfileVersion: number;\n packages: Record<\n string,\n {\n version: string;\n resolved?: string;\n integrity?: string;\n }\n >;\n}\n\ninterface PackageLockV1 {\n lockfileVersion: 1;\n dependencies: Record<\n string,\n {\n version: string;\n resolved?: string;\n integrity?: string;\n dependencies?: Record<string, unknown>;\n }\n >;\n}\n\nexport function parsePackageLock(content: string): ParsedPackage[] {\n const parsed = JSON.parse(content) as { lockfileVersion?: number };\n const lockfileVersion = parsed.lockfileVersion || 1;\n\n if (lockfileVersion >= 2) {\n return parsePackageLockV2(parsed as PackageLockV2);\n }\n\n return parsePackageLockV1(parsed as PackageLockV1);\n}\n\nfunction parsePackageLockV2(data: PackageLockV2): ParsedPackage[] {\n const packages: ParsedPackage[] = [];\n\n for (const [path, info] of Object.entries(data.packages || {})) {\n if (path === \"\") continue;\n\n const segments = path.split(\"node_modules/\");\n const packageName = segments[segments.length - 1];\n\n if (!packageName || !info.version) continue;\n\n packages.push({\n name: packageName,\n version: info.version,\n resolved: info.resolved,\n integrity: info.integrity,\n });\n }\n\n return deduplicatePackages(packages);\n}\n\nfunction parsePackageLockV1(data: PackageLockV1): ParsedPackage[] {\n const packages: ParsedPackage[] = [];\n\n function traverse(deps: Record<string, { version: string; resolved?: string; integrity?: string; dependencies?: Record<string, unknown> }>) {\n for (const [name, info] of Object.entries(deps)) {\n packages.push({\n name,\n version: info.version,\n resolved: info.resolved,\n integrity: info.integrity,\n });\n\n if (info.dependencies) {\n traverse(info.dependencies as typeof deps);\n }\n }\n }\n\n traverse(data.dependencies || {});\n return deduplicatePackages(packages);\n}\n\nfunction deduplicatePackages(packages: ParsedPackage[]): ParsedPackage[] {\n const seen = new Map<string, ParsedPackage>();\n\n for (const pkg of packages) {\n const key = `${pkg.name}@${pkg.version}`;\n if (!seen.has(key)) {\n seen.set(key, pkg);\n }\n }\n\n return Array.from(seen.values());\n}\n","import pLimit from \"p-limit\";\nimport type { PackageTimeInfo } from \"../types/index.js\";\n\nconst NPM_REGISTRY = \"https://registry.npmjs.org\";\n\nexport class NpmRegistryClient {\n private cache: Map<string, PackageTimeInfo> = new Map();\n private limiter: ReturnType<typeof pLimit>;\n private retryDelay = 1000;\n private maxRetries = 3;\n\n constructor(concurrency = 10) {\n this.limiter = pLimit(concurrency);\n }\n\n async getPackageTime(name: string): Promise<PackageTimeInfo> {\n const cached = this.cache.get(name);\n if (cached) return cached;\n\n return this.limiter(async () => {\n const cachedAfterWait = this.cache.get(name);\n if (cachedAfterWait) return cachedAfterWait;\n\n const data = await this.fetchWithRetry(name);\n this.cache.set(name, data);\n return data;\n });\n }\n\n private async fetchWithRetry(\n name: string,\n attempt = 1\n ): Promise<PackageTimeInfo> {\n const url = `${NPM_REGISTRY}/${encodeURIComponent(name).replace(\"%40\", \"@\")}`;\n\n try {\n const response = await fetch(url, {\n headers: {\n Accept: \"application/json\",\n },\n });\n\n if (response.status === 429) {\n if (attempt <= this.maxRetries) {\n const delay = this.retryDelay * Math.pow(2, attempt - 1);\n await this.sleep(delay);\n return this.fetchWithRetry(name, attempt + 1);\n }\n throw new Error(`Rate limited after ${this.maxRetries} retries`);\n }\n\n if (response.status === 404) {\n throw new Error(`Package not found: ${name}`);\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const data = (await response.json()) as { time: PackageTimeInfo };\n return data.time;\n } catch (error) {\n if (attempt <= this.maxRetries && this.isRetryableError(error)) {\n const delay = this.retryDelay * Math.pow(2, attempt - 1);\n await this.sleep(delay);\n return this.fetchWithRetry(name, attempt + 1);\n }\n throw error;\n }\n }\n\n private isRetryableError(error: unknown): boolean {\n if (error instanceof Error) {\n return (\n error.message.includes(\"ECONNRESET\") ||\n error.message.includes(\"ETIMEDOUT\") ||\n error.message.includes(\"fetch failed\")\n );\n }\n return false;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { readFileSync, existsSync } from \"fs\";\nimport { resolve, basename } from \"path\";\nimport { parseYarnLock } from \"../parsers/yarn-lock.js\";\nimport { parsePackageLock } from \"../parsers/package-lock.js\";\nimport { NpmRegistryClient } from \"../registry/npm-client.js\";\nimport type {\n ParsedPackage,\n AnalysisResult,\n PackageCheckResult,\n PackageError,\n CLIOptions,\n LockfileType,\n PackageTimeInfo,\n} from \"../types/index.js\";\n\nexport function parseMinimumReleaseAge(value: string): number {\n const match = value.match(/^(\\d+)\\s*(days?|hours?|minutes?)?$/i);\n if (!match) {\n throw new Error(\n `Invalid minimumReleaseAge format: \"${value}\". Use format like \"3 days\", \"7 days\", or \"24 hours\"`\n );\n }\n\n const num = parseInt(match[1], 10);\n const unit = (match[2] || \"days\").toLowerCase();\n\n if (unit.startsWith(\"day\")) {\n return num;\n } else if (unit.startsWith(\"hour\")) {\n return num / 24;\n } else if (unit.startsWith(\"minute\")) {\n return num / (24 * 60);\n }\n\n return num;\n}\n\nexport async function analyzeLockfile(\n lockfilePath: string | undefined,\n options: CLIOptions,\n onProgress?: (current: number, total: number) => void\n): Promise<AnalysisResult> {\n const resolvedPath = resolveLockfilePath(lockfilePath);\n const content = readFileSync(resolvedPath, \"utf-8\");\n\n const { packages, lockfileType } = parseLockfile(resolvedPath, content);\n\n const filteredPackages = packages.filter(\n (pkg) => !options.exclude.includes(pkg.name)\n );\n\n const client = new NpmRegistryClient(options.concurrency);\n const thresholdDays = parseMinimumReleaseAge(options.minimumReleaseAge);\n const thresholdDate = new Date();\n thresholdDate.setDate(thresholdDate.getDate() - thresholdDays);\n\n const recentPackages: PackageCheckResult[] = [];\n const errors: PackageError[] = [];\n\n const total = filteredPackages.length;\n let processed = 0;\n\n const checkPromises = filteredPackages.map(async (pkg) => {\n try {\n const timeInfo = await client.getPackageTime(pkg.name);\n const publishedAt = new Date(timeInfo[pkg.version]);\n\n if (isNaN(publishedAt.getTime())) {\n throw new Error(`Invalid publish date for version ${pkg.version}`);\n }\n\n const daysAgo = Math.floor(\n (Date.now() - publishedAt.getTime()) / (1000 * 60 * 60 * 24)\n );\n\n const isWithinThreshold = publishedAt >= thresholdDate;\n const isNew = isFirstVersion(timeInfo, pkg.version);\n\n if (isWithinThreshold) {\n recentPackages.push({\n name: pkg.name,\n version: pkg.version,\n publishedAt,\n isNew,\n daysAgo,\n isWithinThreshold,\n });\n }\n } catch (error) {\n errors.push({\n name: pkg.name,\n version: pkg.version,\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n processed++;\n onProgress?.(processed, total);\n }\n });\n\n await Promise.all(checkPromises);\n\n recentPackages.sort(\n (a, b) => b.publishedAt.getTime() - a.publishedAt.getTime()\n );\n\n return {\n lockfileType,\n lockfilePath: resolvedPath,\n totalPackages: filteredPackages.length,\n checkedPackages: filteredPackages.length - errors.length,\n recentPackages,\n errors,\n analysisDate: new Date(),\n thresholdDays,\n };\n}\n\nfunction resolveLockfilePath(path?: string): string {\n if (path) {\n const resolved = resolve(path);\n if (!existsSync(resolved)) {\n throw new Error(`Lockfile not found: ${resolved}`);\n }\n return resolved;\n }\n\n const candidates = [\"yarn.lock\", \"package-lock.json\"];\n\n for (const candidate of candidates) {\n const resolved = resolve(candidate);\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n\n throw new Error(\n \"No lockfile found. Please specify a path or run in a directory with yarn.lock or package-lock.json\"\n );\n}\n\nfunction parseLockfile(\n path: string,\n content: string\n): { packages: ParsedPackage[]; lockfileType: LockfileType } {\n const filename = basename(path);\n\n if (filename === \"yarn.lock\") {\n const { packages, version } = parseYarnLock(content);\n return { packages, lockfileType: version };\n }\n\n if (filename === \"package-lock.json\") {\n return {\n packages: parsePackageLock(content),\n lockfileType: \"npm\",\n };\n }\n\n throw new Error(`Unsupported lockfile: ${filename}`);\n}\n\nfunction isFirstVersion(\n timeInfo: PackageTimeInfo,\n version: string\n): boolean {\n const versions = Object.keys(timeInfo).filter(\n (k) => k !== \"created\" && k !== \"modified\"\n );\n\n if (versions.length === 0) return true;\n\n let earliestVersion = versions[0];\n let earliestDate = new Date(timeInfo[versions[0]]);\n\n for (const v of versions) {\n const date = new Date(timeInfo[v]);\n if (date < earliestDate) {\n earliestDate = date;\n earliestVersion = v;\n }\n }\n\n return version === earliestVersion;\n}\n","import chalk from \"chalk\";\nimport type { AnalysisResult } from \"../types/index.js\";\n\nexport function formatConsole(result: AnalysisResult): void {\n console.log();\n console.log(chalk.bold(\"Lockfile Analysis Report\"));\n console.log(chalk.gray(\"-\".repeat(50)));\n console.log(`File: ${chalk.cyan(result.lockfilePath)}`);\n console.log(`Type: ${chalk.cyan(result.lockfileType)}`);\n console.log(`Threshold: ${chalk.yellow(result.thresholdDays)} days`);\n console.log(`Total packages: ${result.totalPackages}`);\n console.log(`Checked: ${result.checkedPackages}`);\n console.log();\n\n if (result.recentPackages.length === 0) {\n console.log(chalk.green(\"No recently published packages found.\"));\n } else {\n console.log(\n chalk.red.bold(\n `Found ${result.recentPackages.length} package(s) published within ${result.thresholdDays} days:`\n )\n );\n console.log();\n\n for (const pkg of result.recentPackages) {\n const newBadge = pkg.isNew ? chalk.bgRed.white(\" NEW \") + \" \" : \" \";\n const daysLabel =\n pkg.daysAgo === 0\n ? \"today\"\n : pkg.daysAgo === 1\n ? \"1 day ago\"\n : `${pkg.daysAgo} days ago`;\n\n console.log(\n `${newBadge}${chalk.bold(pkg.name)}@${chalk.yellow(pkg.version)}`\n );\n console.log(\n ` Published: ${chalk.gray(pkg.publishedAt.toISOString())} (${chalk.yellow(daysLabel)})`\n );\n }\n }\n\n if (result.errors.length > 0) {\n console.log();\n console.log(\n chalk.yellow(\n `Warnings: ${result.errors.length} package(s) could not be checked`\n )\n );\n\n for (const err of result.errors) {\n console.log(chalk.gray(` - ${err.name}@${err.version}: ${err.error}`));\n }\n }\n\n console.log();\n}\n","import type { AnalysisResult } from \"../types/index.js\";\n\nexport function formatJson(result: AnalysisResult): void {\n const output = {\n ...result,\n recentPackages: result.recentPackages.map((pkg) => ({\n ...pkg,\n publishedAt: pkg.publishedAt.toISOString(),\n })),\n analysisDate: result.analysisDate.toISOString(),\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n","import type { AnalysisResult } from \"../types/index.js\";\nimport { formatConsole } from \"./console.js\";\nimport { formatJson } from \"./json.js\";\n\nexport function formatOutput(\n result: AnalysisResult,\n format: \"console\" | \"json\"\n): void {\n if (format === \"json\") {\n formatJson(result);\n } else {\n formatConsole(result);\n }\n}\n\nexport { formatConsole } from \"./console.js\";\nexport { formatJson } from \"./json.js\";\n"],"mappings":"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","names":["resolve"]}
|