|
1 | | -#! /usr/bin/env node |
2 | | - |
3 | 1 | // to GET CONTENTS for folder at PATH (which may be a PACKAGE): |
4 | 2 | // - if PACKAGE, read path/package.json |
5 | 3 | // - if bins in ../node_modules/.bin, add those to result |
|
19 | 17 | // - add GET CONTENTS of bundled deps, PACKAGE=true, depth + 1 |
20 | 18 |
|
21 | 19 | const bundled = require('npm-bundled') |
22 | | -const { promisify } = require('util') |
23 | | -const fs = require('fs') |
24 | | -const readFile = promisify(fs.readFile) |
25 | | -const readdir = promisify(fs.readdir) |
26 | | -const stat = promisify(fs.stat) |
27 | | -const lstat = promisify(fs.lstat) |
28 | | -const { relative, resolve, basename, dirname } = require('path') |
| 20 | +const { readFile, readdir, stat } = require('fs/promises') |
| 21 | +const { resolve, basename, dirname } = require('path') |
29 | 22 | const normalizePackageBin = require('npm-normalize-package-bin') |
30 | 23 |
|
31 | | -const readPackage = ({ path, packageJsonCache }) => |
32 | | - packageJsonCache.has(path) ? Promise.resolve(packageJsonCache.get(path)) |
| 24 | +const readPackage = ({ path, packageJsonCache }) => packageJsonCache.has(path) |
| 25 | + ? Promise.resolve(packageJsonCache.get(path)) |
33 | 26 | : readFile(path).then(json => { |
34 | 27 | const pkg = normalizePackageBin(JSON.parse(json)) |
35 | 28 | packageJsonCache.set(path, pkg) |
36 | 29 | return pkg |
37 | | - }) |
38 | | - .catch(er => null) |
| 30 | + }).catch(() => null) |
39 | 31 |
|
40 | 32 | // just normalize bundle deps and bin, that's all we care about here. |
41 | 33 | const normalized = Symbol('package data has been normalized') |
42 | | -const rpj = ({ path, packageJsonCache }) => |
43 | | - readPackage({ path, packageJsonCache }) |
44 | | - .then(pkg => { |
45 | | - if (!pkg || pkg[normalized]) { |
46 | | - return pkg |
47 | | - } |
48 | | - if (pkg.bundledDependencies && !pkg.bundleDependencies) { |
49 | | - pkg.bundleDependencies = pkg.bundledDependencies |
50 | | - delete pkg.bundledDependencies |
51 | | - } |
52 | | - const bd = pkg.bundleDependencies |
53 | | - if (bd === true) { |
54 | | - pkg.bundleDependencies = [ |
55 | | - ...Object.keys(pkg.dependencies || {}), |
56 | | - ...Object.keys(pkg.optionalDependencies || {}), |
57 | | - ] |
58 | | - } |
59 | | - if (typeof bd === 'object' && !Array.isArray(bd)) { |
60 | | - pkg.bundleDependencies = Object.keys(bd) |
61 | | - } |
62 | | - pkg[normalized] = true |
| 34 | +const rpj = ({ path, packageJsonCache }) => readPackage({ path, packageJsonCache }) |
| 35 | + .then(pkg => { |
| 36 | + if (!pkg || pkg[normalized]) { |
63 | 37 | return pkg |
64 | | - }) |
| 38 | + } |
| 39 | + if (pkg.bundledDependencies && !pkg.bundleDependencies) { |
| 40 | + pkg.bundleDependencies = pkg.bundledDependencies |
| 41 | + delete pkg.bundledDependencies |
| 42 | + } |
| 43 | + const bd = pkg.bundleDependencies |
| 44 | + if (bd === true) { |
| 45 | + pkg.bundleDependencies = [ |
| 46 | + ...Object.keys(pkg.dependencies || {}), |
| 47 | + ...Object.keys(pkg.optionalDependencies || {}), |
| 48 | + ] |
| 49 | + } |
| 50 | + if (typeof bd === 'object' && !Array.isArray(bd)) { |
| 51 | + pkg.bundleDependencies = Object.keys(bd) |
| 52 | + } |
| 53 | + pkg[normalized] = true |
| 54 | + return pkg |
| 55 | + }) |
65 | 56 |
|
66 | 57 | const pkgContents = async ({ |
67 | 58 | path, |
68 | | - depth, |
| 59 | + depth = 1, |
69 | 60 | currentDepth = 0, |
70 | 61 | pkg = null, |
71 | 62 | result = null, |
@@ -105,7 +96,7 @@ const pkgContents = async ({ |
105 | 96 | }) |
106 | 97 |
|
107 | 98 | const bins = await Promise.all( |
108 | | - binFiles.map(b => stat(b).then(() => b).catch((er) => null)) |
| 99 | + binFiles.map(b => stat(b).then(() => b).catch(() => null)) |
109 | 100 | ) |
110 | 101 | bins.filter(b => b).forEach(b => result.add(b)) |
111 | 102 | } |
@@ -136,18 +127,6 @@ const pkgContents = async ({ |
136 | 127 |
|
137 | 128 | const recursePromises = [] |
138 | 129 |
|
139 | | - // if we didn't get withFileTypes support, tack that on |
140 | | - if (typeof dirEntries[0] === 'string') { |
141 | | - // use a map so we can return a promise, but we mutate dirEntries in place |
142 | | - // this is much slower than getting the entries from the readdir call, |
143 | | - // but polyfills support for node versions before 10.10 |
144 | | - await Promise.all(dirEntries.map(async (name, index) => { |
145 | | - const p = resolve(path, name) |
146 | | - const st = await lstat(p) |
147 | | - dirEntries[index] = Object.assign(st, { name }) |
148 | | - })) |
149 | | - } |
150 | | - |
151 | 130 | for (const entry of dirEntries) { |
152 | 131 | const p = resolve(path, entry.name) |
153 | 132 | if (entry.isDirectory() === false) { |
@@ -195,48 +174,8 @@ const pkgContents = async ({ |
195 | 174 | return result |
196 | 175 | } |
197 | 176 |
|
198 | | -module.exports = ({ path, depth = 1, packageJsonCache }) => pkgContents({ |
| 177 | +module.exports = ({ path, ...opts }) => pkgContents({ |
199 | 178 | path: resolve(path), |
200 | | - depth, |
| 179 | + ...opts, |
201 | 180 | pkg: true, |
202 | | - packageJsonCache, |
203 | 181 | }).then(results => [...results]) |
204 | | - |
205 | | -if (require.main === module) { |
206 | | - const options = { path: null, depth: 1 } |
207 | | - const usage = `Usage: |
208 | | - installed-package-contents <path> [-d<n> --depth=<n>] |
209 | | -
|
210 | | -Lists the files installed for a package specified by <path>. |
211 | | -
|
212 | | -Options: |
213 | | - -d<n> --depth=<n> Provide a numeric value ("Infinity" is allowed) |
214 | | - to specify how deep in the file tree to traverse. |
215 | | - Default=1 |
216 | | - -h --help Show this usage information` |
217 | | - |
218 | | - process.argv.slice(2).forEach(arg => { |
219 | | - let match |
220 | | - if ((match = arg.match(/^--depth=([0-9]+|Infinity)/)) || |
221 | | - (match = arg.match(/^-d([0-9]+|Infinity)/))) { |
222 | | - options.depth = +match[1] |
223 | | - } else if (arg === '-h' || arg === '--help') { |
224 | | - console.log(usage) |
225 | | - process.exit(0) |
226 | | - } else { |
227 | | - options.path = arg |
228 | | - } |
229 | | - }) |
230 | | - if (!options.path) { |
231 | | - console.error('ERROR: no path provided') |
232 | | - console.error(usage) |
233 | | - process.exit(1) |
234 | | - } |
235 | | - const cwd = process.cwd() |
236 | | - module.exports(options) |
237 | | - .then(list => list.sort().forEach(p => console.log(relative(cwd, p)))) |
238 | | - .catch(/* istanbul ignore next - pretty unusual */ er => { |
239 | | - console.error(er) |
240 | | - process.exit(1) |
241 | | - }) |
242 | | -} |
0 commit comments