npm-packlist 2.2.2 → 5.0.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.
package/bin/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ const packlist = require('../')
2
5
 
3
6
  const dirs = []
4
7
  let doSort = false
@@ -6,20 +9,31 @@ process.argv.slice(2).forEach(arg => {
6
9
  if (arg === '-h' || arg === '--help') {
7
10
  console.log('usage: npm-packlist [-s --sort] [directory, directory, ...]')
8
11
  process.exit(0)
9
- } else if (arg === '-s' || arg === '--sort')
12
+ } else if (arg === '-s' || arg === '--sort') {
10
13
  doSort = true
11
- else
14
+ } else {
12
15
  dirs.push(arg)
16
+ }
13
17
  })
14
18
 
15
19
  const sort = list => doSort ? list.sort((a, b) => a.localeCompare(b, 'en')) : list
16
20
 
17
- const packlist = require('../')
18
- if (!dirs.length)
19
- console.log(sort(packlist.sync({ path: process.cwd() })).join('\n'))
20
- else {
21
- dirs.forEach(path => {
22
- console.log(`> ${path}`)
23
- console.log(sort(packlist.sync({ path })).join('\n'))
24
- })
21
+ const main = async () => {
22
+ if (!dirs.length) {
23
+ const results = await packlist({ path: process.cwd() })
24
+ console.log(sort(results).join('\n'))
25
+ } else {
26
+ for (const dir of dirs) {
27
+ console.group(`> ${dir}`)
28
+ const results = await packlist({ path: dir })
29
+ console.log(sort(results).join('\n'))
30
+ console.groupEnd()
31
+ }
32
+ }
25
33
  }
34
+
35
+ // coverage disabled for catch handler because we don't need to test that
36
+ main().catch(/* istanbul ignore next */(err) => {
37
+ process.exitCode = 1
38
+ console.error(err.stack)
39
+ })
@@ -7,11 +7,9 @@
7
7
 
8
8
  const bundleWalk = require('npm-bundled')
9
9
  const BundleWalker = bundleWalk.BundleWalker
10
- const BundleWalkerSync = bundleWalk.BundleWalkerSync
11
10
 
12
11
  const ignoreWalk = require('ignore-walk')
13
12
  const IgnoreWalker = ignoreWalk.Walker
14
- const IgnoreWalkerSync = ignoreWalk.WalkerSync
15
13
 
16
14
  const rootBuiltinRules = Symbol('root-builtin-rules')
17
15
  const packageNecessaryRules = Symbol('package-necessary-rules')
@@ -34,6 +32,24 @@ const packageMustHavesRE = new RegExp(`^(${packageMustHaveFileNames})(\\..*[^~$]
34
32
  const fs = require('fs')
35
33
  const glob = require('glob')
36
34
 
35
+ const pathHasPkg = (input) => {
36
+ if (!input.startsWith('node_modules/')) {
37
+ return false
38
+ }
39
+
40
+ const segments = input.slice('node_modules/'.length).split('/', 2)
41
+ return segments[0].startsWith('@')
42
+ ? segments.length === 2
43
+ : true
44
+ }
45
+
46
+ const pkgFromPath = (input) => {
47
+ const segments = input.slice('node_modules/'.length).split('/', 2)
48
+ return segments[0].startsWith('@')
49
+ ? segments.join('/')
50
+ : segments[0]
51
+ }
52
+
37
53
  const defaultRules = [
38
54
  '.npmignore',
39
55
  '.gitignore',
@@ -58,14 +74,14 @@ const defaultRules = [
58
74
  '*.orig',
59
75
  '/package-lock.json',
60
76
  '/yarn.lock',
77
+ '/pnpm-lock.yaml',
61
78
  '/archived-packages/**',
62
79
  ]
63
80
 
64
81
  // There may be others, but :?|<> are handled by node-tar
65
82
  const nameIsBadForWindows = file => /\*/.test(file)
66
83
 
67
- // a decorator that applies our custom rules to an ignore walker
68
- const npmWalker = Class => class Walker extends Class {
84
+ class Walker extends IgnoreWalker {
69
85
  constructor (opt) {
70
86
  opt = opt || {}
71
87
 
@@ -89,7 +105,7 @@ const npmWalker = Class => class Walker extends Class {
89
105
  // hierarchy (ie, not in test/foo/node_modules/ or something).
90
106
  const followRe = /^(?:\/node_modules\/(?:@[^/]+\/[^/]+|[^/]+)\/)*\/node_modules(?:\/@[^/]+)?$/
91
107
  const rootPath = opt.parent ? opt.parent.root : opt.path
92
- const followTestPath = opt.path.replace(/\\/g, '/').substr(rootPath.length)
108
+ const followTestPath = opt.path.replace(/\\/g, '/').slice(rootPath.length)
93
109
  opt.follow = followRe.test(followTestPath)
94
110
 
95
111
  super(opt)
@@ -97,13 +113,14 @@ const npmWalker = Class => class Walker extends Class {
97
113
  // ignore a bunch of things by default at the root level.
98
114
  // also ignore anything in the main project node_modules hierarchy,
99
115
  // except bundled dependencies
100
- if (!this.parent) {
116
+ if (this.isProject) {
101
117
  this.bundled = opt.bundled || []
102
118
  this.bundledScopes = Array.from(new Set(
103
119
  this.bundled.filter(f => /^@/.test(f))
104
120
  .map(f => f.split('/')[0])))
105
121
  const rules = defaultRules.join('\n') + '\n'
106
- this.packageJsonCache = opt.packageJsonCache || new Map()
122
+ this.packageJsonCache = this.parent ? this.parent.packageJsonCache
123
+ : (opt.packageJsonCache || new Map())
107
124
  super.onReadIgnoreFile(rootBuiltinRules, rules, _ => _)
108
125
  } else {
109
126
  this.bundled = []
@@ -112,8 +129,12 @@ const npmWalker = Class => class Walker extends Class {
112
129
  }
113
130
  }
114
131
 
132
+ get isProject () {
133
+ return !this.parent || this.parent.follow && this.isSymbolicLink
134
+ }
135
+
115
136
  onReaddir (entries) {
116
- if (!this.parent) {
137
+ if (this.isProject) {
117
138
  entries = entries.filter(e =>
118
139
  e !== '.git' &&
119
140
  !(e === 'node_modules' && this.bundled.length === 0)
@@ -126,8 +147,9 @@ const npmWalker = Class => class Walker extends Class {
126
147
  // to be in the state the user wants to include them, and
127
148
  // a package.json somewhere else might be a template or
128
149
  // test or something else entirely.
129
- if (this.parent || !entries.includes('package.json'))
150
+ if (!this.isProject || !entries.includes('package.json')) {
130
151
  return super.onReaddir(entries)
152
+ }
131
153
 
132
154
  // when the cache has been seeded with the root manifest,
133
155
  // we must respect that (it may differ from the filesystem)
@@ -137,8 +159,9 @@ const npmWalker = Class => class Walker extends Class {
137
159
  const pkg = this.packageJsonCache.get(ig)
138
160
 
139
161
  // fall back to filesystem when seeded manifest is invalid
140
- if (!pkg || typeof pkg !== 'object')
162
+ if (!pkg || typeof pkg !== 'object') {
141
163
  return this.readPackageJson(entries)
164
+ }
142
165
 
143
166
  // feels wonky, but this ensures package bin is _always_
144
167
  // normalized, as well as guarding against invalid JSON
@@ -149,22 +172,26 @@ const npmWalker = Class => class Walker extends Class {
149
172
  }
150
173
 
151
174
  onReadPackageJson (entries, er, pkg) {
152
- if (er)
175
+ if (er) {
153
176
  this.emit('error', er)
154
- else
177
+ } else {
155
178
  this.getPackageFiles(entries, pkg)
179
+ }
156
180
  }
157
181
 
158
182
  mustHaveFilesFromPackage (pkg) {
159
183
  const files = []
160
- if (pkg.browser)
184
+ if (pkg.browser) {
161
185
  files.push('/' + pkg.browser)
162
- if (pkg.main)
186
+ }
187
+ if (pkg.main) {
163
188
  files.push('/' + pkg.main)
189
+ }
164
190
  if (pkg.bin) {
165
191
  // always an object because normalized already
166
- for (const key in pkg.bin)
192
+ for (const key in pkg.bin) {
167
193
  files.push('/' + pkg.bin[key])
194
+ }
168
195
  }
169
196
  files.push(
170
197
  '/package.json',
@@ -194,8 +221,9 @@ const npmWalker = Class => class Walker extends Class {
194
221
  this.packageJsonCache.set(ig, pkg)
195
222
 
196
223
  // no files list, just return the normal readdir() result
197
- if (!Array.isArray(pkg.files))
224
+ if (!Array.isArray(pkg.files)) {
198
225
  return super.onReaddir(entries)
226
+ }
199
227
 
200
228
  pkg.files.push(...this.mustHaveFilesFromPackage(pkg))
201
229
 
@@ -204,13 +232,15 @@ const npmWalker = Class => class Walker extends Class {
204
232
  // the files list as the effective readdir result, that means it
205
233
  // looks like we don't have a node_modules folder at all unless we
206
234
  // include it here.
207
- if ((pkg.bundleDependencies || pkg.bundledDependencies) && entries.includes('node_modules'))
235
+ if ((pkg.bundleDependencies || pkg.bundledDependencies) && entries.includes('node_modules')) {
208
236
  pkg.files.push('node_modules')
237
+ }
209
238
 
210
239
  const patterns = Array.from(new Set(pkg.files)).reduce((set, pattern) => {
211
240
  const excl = pattern.match(/^!+/)
212
- if (excl)
213
- pattern = pattern.substr(excl[0].length)
241
+ if (excl) {
242
+ pattern = pattern.slice(excl[0].length)
243
+ }
214
244
  // strip off any / from the start of the pattern. /foo => foo
215
245
  pattern = pattern.replace(/^\/+/, '')
216
246
  // an odd number of ! means a negated pattern. !!foo ==> foo
@@ -224,15 +254,17 @@ const npmWalker = Class => class Walker extends Class {
224
254
  const negates = new Set()
225
255
  const results = []
226
256
  const then = (pattern, negate, er, fileList, i) => {
227
- if (er)
257
+ if (er) {
228
258
  return this.emit('error', er)
259
+ }
229
260
 
230
261
  results[i] = { negate, fileList }
231
- if (--n === 0)
262
+ if (--n === 0) {
232
263
  processResults(results)
264
+ }
233
265
  }
234
- const processResults = results => {
235
- for (const {negate, fileList} of results) {
266
+ const processResults = processed => {
267
+ for (const { negate, fileList } of processed) {
236
268
  if (negate) {
237
269
  fileList.forEach(f => {
238
270
  f = f.replace(/\/+$/, '')
@@ -260,23 +292,23 @@ const npmWalker = Class => class Walker extends Class {
260
292
  // maintain the index so that we process them in-order only once all
261
293
  // are completed, otherwise the parallelism messes things up, since a
262
294
  // glob like **/*.js will always be slower than a subsequent !foo.js
263
- patterns.forEach(({pattern, negate}, i) =>
295
+ patterns.forEach(({ pattern, negate }, i) =>
264
296
  this.globFiles(pattern, (er, res) => then(pattern, negate, er, res, i)))
265
297
  }
266
298
 
267
299
  filterEntry (entry, partial) {
268
300
  // get the partial path from the root of the walk
269
- const p = this.path.substr(this.root.length + 1)
270
- const pkgre = /^node_modules\/(@[^/]+\/?[^/]+|[^/]+)(\/.*)?$/
271
- const isRoot = !this.parent
272
- const pkg = isRoot && pkgre.test(entry) ?
273
- entry.replace(pkgre, '$1') : null
274
- const rootNM = isRoot && entry === 'node_modules'
275
- const rootPJ = isRoot && entry === 'package.json'
301
+ const p = this.path.slice(this.root.length + 1)
302
+ const { isProject } = this
303
+ const pkg = isProject && pathHasPkg(entry)
304
+ ? pkgFromPath(entry)
305
+ : null
306
+ const rootNM = isProject && entry === 'node_modules'
307
+ const rootPJ = isProject && entry === 'package.json'
276
308
 
277
309
  return (
278
310
  // if we're in a bundled package, check with the parent.
279
- /^node_modules($|\/)/i.test(p) ? this.parent.filterEntry(
311
+ /^node_modules($|\/)/i.test(p) && !this.isProject ? this.parent.filterEntry(
280
312
  this.basename + '/' + entry, partial)
281
313
 
282
314
  // if package is bundled, all files included
@@ -298,11 +330,11 @@ const npmWalker = Class => class Walker extends Class {
298
330
  : packageMustHavesRE.test(entry) ? true
299
331
 
300
332
  // npm-shrinkwrap and package.json always included in the root pkg
301
- : isRoot && (entry === 'npm-shrinkwrap.json' || entry === 'package.json')
333
+ : isProject && (entry === 'npm-shrinkwrap.json' || entry === 'package.json')
302
334
  ? true
303
335
 
304
336
  // package-lock never included
305
- : isRoot && entry === 'package-lock.json' ? false
337
+ : isProject && entry === 'package-lock.json' ? false
306
338
 
307
339
  // otherwise, follow ignore-walk's logic
308
340
  : super.filterEntry(entry, partial)
@@ -310,20 +342,22 @@ const npmWalker = Class => class Walker extends Class {
310
342
  }
311
343
 
312
344
  filterEntries () {
313
- if (this.ignoreRules['.npmignore'])
345
+ if (this.ignoreRules['.npmignore']) {
314
346
  this.ignoreRules['.gitignore'] = null
347
+ }
315
348
  this.filterEntries = super.filterEntries
316
349
  super.filterEntries()
317
350
  }
318
351
 
319
352
  addIgnoreFile (file, then) {
320
353
  const ig = path.resolve(this.path, file)
321
- if (file === 'package.json' && this.parent)
354
+ if (file === 'package.json' && !this.isProject) {
322
355
  then()
323
- else if (this.packageJsonCache.has(ig))
356
+ } else if (this.packageJsonCache.has(ig)) {
324
357
  this.onPackageJson(ig, this.packageJsonCache.get(ig), then)
325
- else
358
+ } else {
326
359
  super.addIgnoreFile(file, then)
360
+ }
327
361
  }
328
362
 
329
363
  onPackageJson (ig, pkg, then) {
@@ -347,19 +381,22 @@ const npmWalker = Class => class Walker extends Class {
347
381
  // override parent stat function to completely skip any filenames
348
382
  // that will break windows entirely.
349
383
  // XXX(isaacs) Next major version should make this an error instead.
350
- stat (entry, file, dir, then) {
351
- if (nameIsBadForWindows(entry))
384
+ stat ({ entry, file, dir }, then) {
385
+ if (nameIsBadForWindows(entry)) {
352
386
  then()
353
- else
354
- super.stat(entry, file, dir, then)
387
+ } else {
388
+ super.stat({ entry, file, dir }, then)
389
+ }
355
390
  }
356
391
 
357
- // override parent onstat function to nix all symlinks
358
- onstat (st, entry, file, dir, then) {
359
- if (st.isSymbolicLink())
392
+ // override parent onstat function to nix all symlinks, other than
393
+ // those coming out of the followed bundled symlink deps
394
+ onstat ({ st, entry, file, dir, isSymbolicLink }, then) {
395
+ if (st.isSymbolicLink()) {
360
396
  then()
361
- else
362
- super.onstat(st, entry, file, dir, then)
397
+ } else {
398
+ super.onstat({ st, entry, file, dir, isSymbolicLink }, then)
399
+ }
363
400
  }
364
401
 
365
402
  onReadIgnoreFile (file, data, then) {
@@ -371,16 +408,25 @@ const npmWalker = Class => class Walker extends Class {
371
408
  // ignore package.json files that are not json
372
409
  then()
373
410
  }
374
- } else
411
+ } else {
375
412
  super.onReadIgnoreFile(file, data, then)
413
+ }
376
414
  }
377
415
 
378
416
  sort (a, b) {
379
- return sort(a, b)
417
+ // optimize for compressibility
418
+ // extname, then basename, then locale alphabetically
419
+ // https://twitter.com/isntitvacant/status/1131094910923231232
420
+ const exta = path.extname(a).toLowerCase()
421
+ const extb = path.extname(b).toLowerCase()
422
+ const basea = path.basename(a).toLowerCase()
423
+ const baseb = path.basename(b).toLowerCase()
424
+
425
+ return exta.localeCompare(extb, 'en') ||
426
+ basea.localeCompare(baseb, 'en') ||
427
+ a.localeCompare(b, 'en')
380
428
  }
381
- }
382
429
 
383
- class Walker extends npmWalker(IgnoreWalker) {
384
430
  globFiles (pattern, cb) {
385
431
  glob(pattern, { dot: true, cwd: this.path, nocase: true }, cb)
386
432
  }
@@ -390,28 +436,8 @@ class Walker extends npmWalker(IgnoreWalker) {
390
436
  this.onReadPackageJson(entries, er, pkg))
391
437
  }
392
438
 
393
- walker (entry, then) {
394
- new Walker(this.walkerOpt(entry)).on('done', then).start()
395
- }
396
- }
397
-
398
- class WalkerSync extends npmWalker(IgnoreWalkerSync) {
399
- globFiles (pattern, cb) {
400
- cb(null, glob.sync(pattern, { dot: true, cwd: this.path, nocase: true }))
401
- }
402
-
403
- readPackageJson (entries) {
404
- const p = this.path + '/package.json'
405
- try {
406
- this.onReadPackageJson(entries, null, fs.readFileSync(p))
407
- } catch (er) {
408
- this.onReadPackageJson(entries, er)
409
- }
410
- }
411
-
412
- walker (entry, then) {
413
- new WalkerSync(this.walkerOpt(entry)).start()
414
- then()
439
+ walker (entry, opt, then) {
440
+ new Walker(this.walkerOpt(entry, opt)).on('done', then).start()
415
441
  }
416
442
  }
417
443
 
@@ -429,31 +455,5 @@ const walk = (options, callback) => {
429
455
  return callback ? p.then(res => callback(null, res), callback) : p
430
456
  }
431
457
 
432
- const walkSync = options => {
433
- options = options || {}
434
- const bw = new BundleWalkerSync(options).start()
435
- options.bundled = bw.result
436
- options.packageJsonCache = bw.packageJsonCache
437
- const walker = new WalkerSync(options)
438
- walker.start()
439
- return walker.result
440
- }
441
-
442
- // optimize for compressibility
443
- // extname, then basename, then locale alphabetically
444
- // https://twitter.com/isntitvacant/status/1131094910923231232
445
- const sort = (a, b) => {
446
- const exta = path.extname(a).toLowerCase()
447
- const extb = path.extname(b).toLowerCase()
448
- const basea = path.basename(a).toLowerCase()
449
- const baseb = path.basename(b).toLowerCase()
450
-
451
- return exta.localeCompare(extb, 'en') ||
452
- basea.localeCompare(baseb, 'en') ||
453
- a.localeCompare(b, 'en')
454
- }
455
-
456
458
  module.exports = walk
457
- walk.sync = walkSync
458
459
  walk.Walker = Walker
459
- walk.WalkerSync = WalkerSync
package/package.json CHANGED
@@ -1,62 +1,61 @@
1
1
  {
2
2
  "name": "npm-packlist",
3
- "version": "2.2.2",
3
+ "version": "5.0.0",
4
4
  "description": "Get a list of the files to add from a folder into an npm package",
5
5
  "directories": {
6
6
  "test": "test"
7
7
  },
8
- "main": "index.js",
8
+ "main": "lib",
9
9
  "dependencies": {
10
- "glob": "^7.1.6",
11
- "ignore-walk": "^3.0.3",
12
- "npm-bundled": "^1.1.1",
10
+ "glob": "^7.2.0",
11
+ "ignore-walk": "^5.0.1",
12
+ "npm-bundled": "^1.1.2",
13
13
  "npm-normalize-package-bin": "^1.0.1"
14
14
  },
15
- "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
15
+ "author": "GitHub Inc.",
16
16
  "license": "ISC",
17
17
  "files": [
18
- "bin/index.js",
19
- "index.js"
18
+ "bin/",
19
+ "lib/"
20
20
  ],
21
21
  "devDependencies": {
22
- "eslint": "^7.25.0",
23
- "eslint-plugin-import": "^2.22.1",
24
- "eslint-plugin-node": "^11.1.0",
25
- "eslint-plugin-promise": "^5.1.0",
26
- "eslint-plugin-standard": "^5.0.0",
22
+ "@npmcli/eslint-config": "^3.0.1",
23
+ "@npmcli/template-oss": "3.2.2",
27
24
  "mutate-fs": "^2.1.1",
28
- "tap": "^15.0.6"
25
+ "tap": "^16.0.1"
29
26
  },
30
27
  "scripts": {
31
28
  "test": "tap",
32
29
  "posttest": "npm run lint",
33
30
  "snap": "tap",
34
- "postsnap": "npm run lintfix",
31
+ "postsnap": "npm run lintfix --",
35
32
  "preversion": "npm test",
36
33
  "postversion": "npm publish",
37
34
  "prepublishOnly": "git push origin --follow-tags",
38
35
  "eslint": "eslint",
39
- "lint": "npm run eslint -- index.js bin/index.js \"test/**/*.js\"",
40
- "lintfix": "npm run lint -- --fix"
36
+ "lint": "eslint \"**/*.js\"",
37
+ "lintfix": "npm run lint -- --fix",
38
+ "npmclilint": "npmcli-lint",
39
+ "postlint": "template-oss-check",
40
+ "template-oss-apply": "template-oss-apply --force"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",
44
- "url": "git+https://github.com/npm/npm-packlist.git"
44
+ "url": "https://github.com/npm/npm-packlist.git"
45
45
  },
46
46
  "tap": {
47
47
  "test-env": [
48
48
  "LC_ALL=sk"
49
- ],
50
- "check-coverage": true,
51
- "nyc-arg": [
52
- "--include=index.js",
53
- "--include=bin/index.js"
54
49
  ]
55
50
  },
56
51
  "bin": {
57
52
  "npm-packlist": "bin/index.js"
58
53
  },
59
54
  "engines": {
60
- "node": ">=10"
55
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
56
+ },
57
+ "templateOSS": {
58
+ "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
59
+ "version": "3.2.2"
61
60
  }
62
61
  }