Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/publish-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,3 @@ jobs:

- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 2 additions & 0 deletions packages/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ npx envoic scan ~/projects
For full documentation, see the [main repository](https://github.com/mahimailabs/envoic).

Also available for Python: `uvx envoic scan .`

> Development note: local JS development (`npm ci`, `npm run lint`, `npm run build`) requires Node `>=20.19.0`.
2 changes: 1 addition & 1 deletion packages/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"directory": "packages/js"
},
"engines": {
"node": ">=18"
"node": ">=20.19.0"
},
"dependencies": {
"@inquirer/prompts": "^7.10.1",
Expand Down
24 changes: 22 additions & 2 deletions packages/js/src/detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ function countTopLevelPackages(nodeModulesPath: string): number {
}

function pathSizeBytes(targetPath: string): number {
const stat = fs.lstatSync(targetPath);
let stat: fs.Stats;
try {
stat = fs.lstatSync(targetPath);
} catch {
return 0;
}
if (stat.isSymbolicLink()) return stat.size;
if (stat.isFile()) return stat.size;
if (!stat.isDirectory()) return 0;
Expand Down Expand Up @@ -98,7 +103,22 @@ export function detectEnvironment(
if (hasPnpmMarker) signals.push("pnpm-marker");
if (hasPackageJson) signals.push("package.json");

const stat = fs.statSync(nodeModulesPath);
let stat: fs.Stats;
try {
stat = fs.statSync(nodeModulesPath);
} catch {
return {
path: nodeModulesPath,
packageManager: detectPackageManager(nodeModulesPath),
packageCount: deep ? countTopLevelPackages(nodeModulesPath) : null,
sizeBytes: deep ? pathSizeBytes(nodeModulesPath) : null,
created: null,
modified: null,
isStale: false,
isOutdated: false,
signals: [...signals, "stat-unavailable"],
};
}
const created = stat.birthtime ?? null;
const modified = stat.mtime ?? null;
const staleThreshold = Date.now() - staleDays * 86400000;
Expand Down
7 changes: 6 additions & 1 deletion packages/js/src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ export function formatInfo(env: EnvInfo, topPackages: Array<{ name: string; size
export function topLargestPackages(nodeModulesPath: string, limit = 10): Array<{ name: string; size: number }> {
const resolvedPath = path.resolve(nodeModulesPath);
const result: Array<{ name: string; size: number }> = [];
const direct = fs.readdirSync(resolvedPath, { withFileTypes: true });
let direct: fs.Dirent[];
try {
direct = fs.readdirSync(resolvedPath, { withFileTypes: true });
} catch {
return [];
}
for (const entry of direct) {
if (!entry.isDirectory()) continue;
if (entry.name.startsWith(".")) continue;
Expand Down