selfish
10/25/2015 - 3:56 PM

List all NPM dependencies in project, recursively

List all NPM dependencies in project, recursively

var _ = require('lodash');
var j2csv = require('json2csv');
var cp = require("child_process");
var fs = require('fs');

/*     Consts:    */
var showErrors = false;                                     // Show errors in console flag
var listCmd = 'npm list --long --json';                     // npm list command
var maxBuffer = 1024 * 1000 * 10; // 10 MB.                 // cp maxBuffer
var cwd = require('path').dirname(require.main.filename);   // Current working directory
var execOpt = {cwd: cwd, maxBuffer: maxBuffer};             // Exec command options


function flatten(packs) {
    var res = [];
    _.each(packs, function (pack) {
        if (pack.repository) {
            pack.repository = pack.repository.url.replace(/^.*\+/, '')
                .replace('git://', 'https://')
                .replace('http://', 'https://');
        }

        if (pack.name || pack.version || pack.repository) res.push(pack);
        res = res.concat(flatten(pack.dependencies))
    });
    return res;
}

function mkFileName(filePath) {
    function fileExists(filePath) {
        try {
            fs.accessSync(filePath);
            return true;
        } catch (e) {
            return false;
        }
    }

    if (!fileExists(filePath)) return filePath;
    var idx = -1;
    filePath = filePath.replace('.', (idx + "."));
    while (fileExists(filePath)) {
        filePath = filePath.replace((idx + "."), ((--idx) + "."));
    }
    return filePath;
}

function openFile(filePath) {
    function getCommandLine() {
        switch (process.platform) {
            case 'darwin' :
                return 'open';
            case 'win32' :
                return 'start';
            case 'win64' :
                return 'start';
            default :
                return 'xdg-open';
        }
    }

    cp.exec(getCommandLine() + ' ' + filePath);
}

function fin(csv) {
    var resPath = mkFileName(cwd + "/npmDeps.csv");
    fs.writeFile(resPath, csv, function (err) {
        if (err) {
            return console.log(err);
        }
        openFile(resPath);
        console.log("Deps CSV created successfully @ " + resPath);
    });
}

function listDeps() {
    cp.exec(listCmd, execOpt, function (err, stdout) {
        // Spill errors to console, but don't halt:
        if (showErrors && err) {
            console.error(err);
        }

        j2csv({
            data: flatten(JSON.parse(stdout).dependencies),
            fields: ["name", "version", "license", "repository", "homepage"]
        }, function (err, csv) {
            if (err) console.log(err);
            fin(csv);
        });
    });
}

listDeps();