90 lines
3.7 KiB
JavaScript
90 lines
3.7 KiB
JavaScript
//NOTE: This script is not perfect, it was quickly made to help with the migration to the new package system.
|
|
|
|
import chalk from 'chalk';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
//Get list of all dependencies in package.json
|
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
const dependencies = new Set(Object.keys(packageJson.dependencies).concat(Object.keys(packageJson.devDependencies)));
|
|
|
|
//Get target folder path
|
|
const targetPath = process.argv[2];
|
|
if (typeof targetPath !== 'string' || !targetPath.length) {
|
|
console.log('Invalid target package name');
|
|
process.exit(1);
|
|
}
|
|
console.clear();
|
|
console.log('Scanning for dependencies in:', chalk.blue(targetPath));
|
|
|
|
|
|
//NOTE: To generate this list, use `node -pe "require('repl')._builtinLibs"` in both node16 and 22, then merge them.
|
|
const builtInModules = [
|
|
'assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console', 'constants', 'crypto', 'dgram', 'diagnostics_channel', 'dns', 'dns/promises', 'domain', 'events', 'fs', 'fs/promises', 'http', 'http2', 'https', 'inspector', 'inspector/promises', 'module', 'net', 'os', 'path', 'path/posix', 'path/win32', 'perf_hooks', 'process', 'punycode', 'querystring', 'readline', 'readline/promises', 'repl', 'stream', 'stream/consumers', 'stream/promises', 'stream/web', 'string_decoder', 'sys', 'test/reporters', 'timers', 'timers/promises', 'tls', 'trace_events', 'tty', 'url', 'util', 'util/types', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'
|
|
];
|
|
|
|
|
|
//Process file and extract all dependencies
|
|
const allDependencies = new Set();
|
|
const ignoredPrefixes = [
|
|
'node:',
|
|
'./',
|
|
'../',
|
|
'@shared',
|
|
'@utils',
|
|
'@logic',
|
|
'@modules',
|
|
'@routes',
|
|
'@core',
|
|
'@locale/',
|
|
'@nui/',
|
|
'@shared/',
|
|
];
|
|
const importRegex = /import\s+.+\s+from\s+['"](.*)['"]/gm;
|
|
const processFile = (filePath) => {
|
|
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
const matches = [...fileContent.matchAll(importRegex)].map((match) => match[1]);
|
|
for (const importedModule of matches) {
|
|
if (ignoredPrefixes.some((prefix) => importedModule.startsWith(prefix))) continue;
|
|
if (!importedModule) {
|
|
console.log(chalk.red(`[ERROR] Invalid import in file: ${filePath}: ${importedModule}`));
|
|
continue;
|
|
}
|
|
if (builtInModules.includes(importedModule)) {
|
|
console.log(chalk.red(`[ERROR] builtin module '${importedModule}' without 'node:' from: ${filePath}`));
|
|
continue;
|
|
}
|
|
if (importedModule === '.') {
|
|
console.log(chalk.red(`[ERROR] Invalid import in file: ${filePath}: ${importedModule}`));
|
|
continue;
|
|
}
|
|
if (!dependencies.has(importedModule)) {
|
|
console.log(chalk.yellow(`[WARN] imported module '${importedModule}' not found in package.json`));
|
|
continue;
|
|
}
|
|
allDependencies.add(importedModule);
|
|
}
|
|
};
|
|
|
|
|
|
//Recursively read all files in the targetPath and its subfolders
|
|
const validExtensions = ['.cjs', '.js', '.ts', '.jsx', '.tsx'];
|
|
const processFolder = (dirPath) => {
|
|
const files = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
|
|
for (const file of files) {
|
|
const currFilePath = path.join(dirPath, file.name);
|
|
if (file.isDirectory()) {
|
|
processFolder(currFilePath);
|
|
} else if (!file.isFile()) {
|
|
console.log(chalk.red(`[ERROR] Invalid file: ${currFilePath}`));
|
|
} else if (!validExtensions.includes(path.extname(currFilePath))) {
|
|
console.log(chalk.grey(`[INFO] Ignoring file: ${currFilePath}`));
|
|
} else {
|
|
processFile(currFilePath);
|
|
}
|
|
}
|
|
};
|
|
processFolder(targetPath);
|
|
console.log(allDependencies);
|