libnpmpack 1.0.0 → 3.0.1

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/README.md CHANGED
@@ -27,15 +27,12 @@ const pack = require('libnpmpack')
27
27
 
28
28
  ### API
29
29
 
30
-
31
30
  #### <a name="pack"></a> `> pack(spec, [opts]) -> Promise`
32
31
 
33
- Packs a tarball from a local directory or from a registry or github spec and saves it on disk. Returns a Promise that resolves to an object containing the tarball contents.
32
+ Packs a tarball from a local directory or from a registry or github spec and returns a Promise that resolves to the tarball data Buffer, with from, resolved, and integrity fields attached.
34
33
 
35
34
  If no options are passed, the tarball file will be saved on the same directory from which `pack` was called in.
36
35
 
37
- If `opts.target` is passed in, it will save the tarball file on the location entered.
38
-
39
36
  `libnpmpack` uses [`pacote`](https://npm.im/pacote).
40
37
  Most options are passed through directly to that library, so please refer to
41
38
  [its own `opts`
@@ -45,74 +42,15 @@ for options that can be passed in.
45
42
  ##### Examples
46
43
 
47
44
  ```javascript
48
- // packs from local directory
49
- const localTar = await pack()
50
- console.log(localTar)
51
- /*
52
- {
53
- id: 'my-cool-pkg@1.0.0',
54
- name: 'my-cool-pkg',
55
- version: '1.0.0',
56
- size: 260,
57
- unpackedSize: 133,
58
- shasum: '535bdcc05fd4a1b7f2603c5527a7c63ba5b88cff',
59
- integrity: ssri.parse(integrity.sha512[0]),
60
- filename: 'my-cool-pkg-1.0.0.tgz',
61
- files: [
62
- { path: 'index.js', size: 5, mode: 420 },
63
- { path: 'node_modules/a/package.json', size: 39, mode: 420 },
64
- { path: 'package.json', size: 89, mode: 420 }
65
- ],
66
- entryCount: 3,
67
- bundled: ['a']
68
- }
69
- */
45
+ // packs from cwd
46
+ const tarball = await pack()
47
+
48
+ // packs from a local directory
49
+ const localTar = await pack('/Users/claudiahdz/projects/my-cool-pkg')
70
50
 
71
51
  // packs from a registry spec
72
52
  const registryTar = await pack('abbrev@1.0.3')
73
- console.log(registryTar)
74
- /*
75
- {
76
- id: abbrev@1.0.3,
77
- name: 'abbrev',
78
- version: '1.0.3',
79
- size: 1526,
80
- unpackedSize: 3358,
81
- shasum: 'aa049c967f999222aa42e14434f0c562ef468241',
82
- integrity: Integrity { sha512: [ [Hash] ] },
83
- filename: 'abbrev-1.0.3.tgz',
84
- files: [
85
- { path: 'package.json', size: 277, mode: 420 },
86
- { path: 'README.md', size: 499, mode: 420 },
87
- { path: 'lib/abbrev.js', size: 2582, mode: 420 }
88
- ],
89
- entryCount: 3,
90
- bundled: []
91
- }
92
- */
93
53
 
94
54
  // packs from a github spec
95
55
  const githubTar = await pack('isaacs/rimraf#PR-192')
96
- /*
97
- {
98
- id: 'rimraf@2.6.3',
99
- name: 'rimraf',
100
- version: '2.6.3',
101
- size: 5664,
102
- unpackedSize: 15463,
103
- shasum: '9f5edf99046b4096d610532f0ec279135a624b15',
104
- integrity: Integrity { sha512: [ [Hash] ] },
105
- filename: 'rimraf-2.6.3.tgz',
106
- files: [
107
- { path: 'LICENSE', size: 765, mode: 420 },
108
- { path: 'bin.js', size: 1196, mode: 493 },
109
- { path: 'rimraf.js', size: 9225, mode: 420 },
110
- { path: 'package.json', size: 677, mode: 420 },
111
- { path: 'README.md', size: 3600, mode: 420 }
112
- ],
113
- entryCount: 5,
114
- bundled: []
115
- }
116
- */
117
56
  ```
118
-
package/lib/index.js ADDED
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+
3
+ const pacote = require('pacote')
4
+ const npa = require('npm-package-arg')
5
+ const runScript = require('@npmcli/run-script')
6
+
7
+ module.exports = pack
8
+ async function pack (spec = 'file:.', opts = {}) {
9
+ // gets spec
10
+ spec = npa(spec)
11
+
12
+ const manifest = await pacote.manifest(spec, opts)
13
+
14
+ // Default to true if no log options passed, set to false if we're in silent
15
+ // mode
16
+ const banner = !opts.log || (opts.log.level !== 'silent')
17
+
18
+ if (spec.type === 'directory') {
19
+ // prepack
20
+ await runScript({
21
+ ...opts,
22
+ event: 'prepack',
23
+ path: spec.fetchSpec,
24
+ stdio: 'inherit',
25
+ pkg: manifest,
26
+ banner,
27
+ })
28
+ }
29
+
30
+ // packs tarball
31
+ const tarball = await pacote.tarball(manifest._resolved, {
32
+ ...opts,
33
+ integrity: manifest._integrity,
34
+ })
35
+
36
+ if (spec.type === 'directory') {
37
+ // postpack
38
+ await runScript({
39
+ ...opts,
40
+ event: 'postpack',
41
+ path: spec.fetchSpec,
42
+ stdio: 'inherit',
43
+ pkg: manifest,
44
+ banner,
45
+ env: {
46
+ npm_package_from: tarball.from,
47
+ npm_package_resolved: tarball.resolved,
48
+ npm_package_integrity: tarball.integrity,
49
+ },
50
+ })
51
+ }
52
+
53
+ return tarball
54
+ }
package/package.json CHANGED
@@ -1,32 +1,34 @@
1
1
  {
2
2
  "name": "libnpmpack",
3
- "version": "1.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Programmatic API for the bits behind npm pack",
5
- "author": "npm Inc. <support@npmjs.com>",
5
+ "author": "GitHub Inc.",
6
+ "main": "lib/index.js",
6
7
  "contributors": [
7
8
  "Claudia Hernández <claudia@npmjs.com>"
8
9
  ],
9
- "main": "index.js",
10
10
  "files": [
11
- "*.js",
12
- "utils"
11
+ "bin",
12
+ "lib"
13
13
  ],
14
14
  "license": "ISC",
15
15
  "scripts": {
16
16
  "preversion": "npm test",
17
17
  "postversion": "npm publish",
18
18
  "prepublishOnly": "git push origin --follow-tags",
19
- "lint": "standard",
19
+ "lint": "eslint '**/*.js'",
20
20
  "test": "tap",
21
- "posttest": "npm run lint"
21
+ "posttest": "npm run lint",
22
+ "postlint": "npm-template-check",
23
+ "lintfix": "npm run lint -- --fix",
24
+ "snap": "tap"
22
25
  },
23
26
  "tap": {
24
27
  "check-coverage": true
25
28
  },
26
29
  "devDependencies": {
27
- "nock": "^12.0.2",
28
- "standard": "^14.3.1",
29
- "tap": "^14.10.6"
30
+ "nock": "^13.0.7",
31
+ "tap": "^15.0.0"
30
32
  },
31
33
  "repository": {
32
34
  "type": "git",
@@ -35,17 +37,14 @@
35
37
  "bugs": "https://github.com/npm/libnpmpack/issues",
36
38
  "homepage": "https://npmjs.com/package/libnpmpack",
37
39
  "dependencies": {
38
- "@npmcli/run-script": "^1.3.0",
39
- "byte-size": "^6.2.0",
40
- "columnify": "^1.5.4",
41
- "move-concurrently": "^1.0.1",
42
- "npm-package-arg": "^8.0.0",
43
- "pacote": "^11.1.2",
44
- "rimraf": "^3.0.2",
45
- "ssri": "^8.0.0",
46
- "tar": "^6.0.1"
40
+ "@npmcli/run-script": "^2.0.0",
41
+ "npm-package-arg": "^8.1.0",
42
+ "pacote": "^12.0.0"
47
43
  },
48
44
  "engines": {
49
- "node": ">=10"
45
+ "node": "^12.13.0 || ^14.15.0 || >=16"
46
+ },
47
+ "templateOSS": {
48
+ "version": "2.4.1"
50
49
  }
51
50
  }
package/CHANGELOG.md DELETED
@@ -1,10 +0,0 @@
1
- # Change Log
2
-
3
- <a name="1.0.0"></a>
4
- # 1.0.0 (2020-03-26)
5
-
6
- ### Features
7
-
8
- * [`a35c590`](https://github.com/npm/libnpmpack/commit/a35c590) feat: pack tarballs from local dir or registry spec ([@claudiahdz](https://github.com/claudiahdz))
9
-
10
- * [`6d72149`](https://github.com/npm/libnpmpack/commit/6d72149) feat: sorted tarball contents ([@eridal](https://github.com/eridal))
package/index.js DELETED
@@ -1,75 +0,0 @@
1
- 'use strict'
2
-
3
- const os = require('os')
4
- const fs = require('fs')
5
- const path = require('path')
6
- const util = require('util')
7
- const pacote = require('pacote')
8
- const npa = require('npm-package-arg')
9
- const mv = require('move-concurrently')
10
- const runScript = require('@npmcli/run-script')
11
-
12
- const rimraf = util.promisify(require('rimraf'))
13
- const mkdtemp = util.promisify(fs.mkdtemp)
14
-
15
- const { getContents, logTar } = require('./utils/tar')
16
-
17
- async function pack (spec = 'file:.', opts = {}) {
18
- const { target = null } = opts
19
- // gets spec
20
- spec = npa(spec)
21
-
22
- const manifest = await pacote.manifest(spec, opts)
23
- const filename = path.basename(`${manifest.name}-${manifest.version}.tgz`)
24
- const dest = target || `${process.cwd()}/${filename}`
25
-
26
- if (spec.type === 'directory') {
27
- // prepack
28
- await runScript({
29
- ...opts,
30
- event: 'prepack',
31
- path: spec.fetchSpec,
32
- stdio: 'inherit',
33
- pkg: manifest,
34
- env: {
35
- npm_package_target: dest
36
- }
37
- })
38
- }
39
-
40
- const tmpDir = await mkdtemp(path.join(os.tmpdir(), 'libnpmpack-'))
41
- const tmpTarget = `${tmpDir}/${filename}`
42
-
43
- // packs tarball on tmp location
44
- const tarball = await pacote.tarball.file(manifest._resolved, tmpTarget, {
45
- ...opts,
46
- integrity: manifest._integrity
47
- })
48
-
49
- // moves tarball to dest
50
- await mv(tmpTarget, dest)
51
- await rimraf(tmpDir)
52
-
53
- if (spec.type === 'directory') {
54
- // postpack
55
- await runScript({
56
- ...opts,
57
- event: 'postpack',
58
- path: spec.fetchSpec,
59
- stdio: 'inherit',
60
- pkg: manifest,
61
- env: {
62
- npm_package_target: dest,
63
- npm_package_from: tarball.from,
64
- npm_package_resolved: tarball.resolved,
65
- npm_package_integrity: tarball.integrity
66
- }
67
- })
68
- }
69
-
70
- const contents = await getContents(manifest, dest)
71
- return contents
72
- }
73
-
74
- pack.logTar = logTar
75
- module.exports = pack
package/utils/tar.js DELETED
@@ -1,121 +0,0 @@
1
- 'use strict'
2
-
3
- const fs = require('fs')
4
- const tar = require('tar')
5
- const util = require('util')
6
- const ssri = require('ssri')
7
- const byteSize = require('byte-size')
8
- const columnify = require('columnify')
9
-
10
- const statAsync = util.promisify(require('fs').stat)
11
-
12
- module.exports.logTar = logTar
13
- /* istanbul ignore next */
14
- function logTar (tarball, opts = {}) {
15
- const { unicode, log = console.log } = opts
16
- log('')
17
- log('', `${unicode ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`)
18
- log('=== Tarball Contents ===')
19
- if (tarball.files.length) {
20
- log('', columnify(tarball.files.map((f) => {
21
- const bytes = byteSize(f.size)
22
- return { path: f.path, size: `${bytes.value}${bytes.unit}` }
23
- }), {
24
- include: ['size', 'path'],
25
- showHeaders: false
26
- }))
27
- }
28
- if (tarball.bundled.length) {
29
- log('=== Bundled Dependencies ===')
30
- tarball.bundled.forEach((name) => log.notice('', name))
31
- }
32
- log('=== Tarball Details ===')
33
- log('', columnify([
34
- { name: 'name:', value: tarball.name },
35
- { name: 'version:', value: tarball.version },
36
- tarball.filename && { name: 'filename:', value: tarball.filename },
37
- { name: 'package size:', value: byteSize(tarball.size) },
38
- { name: 'unpacked size:', value: byteSize(tarball.unpackedSize) },
39
- { name: 'shasum:', value: tarball.shasum },
40
- {
41
- name: 'integrity:',
42
- value: tarball.integrity.toString().substr(0, 20) + '[...]' + tarball.integrity.toString().substr(80)
43
- },
44
- tarball.bundled.length && { name: 'bundled deps:', value: tarball.bundled.length },
45
- tarball.bundled.length && { name: 'bundled files:', value: tarball.entryCount - tarball.files.length },
46
- tarball.bundled.length && { name: 'own files:', value: tarball.files.length },
47
- { name: 'total files:', value: tarball.entryCount }
48
- ].filter((x) => x), {
49
- include: ['name', 'value'],
50
- showHeaders: false
51
- }))
52
- log('', '')
53
- }
54
-
55
- module.exports.getContents = getContents
56
- async function getContents (manifest, target) {
57
- const files = []
58
- const bundled = new Set()
59
- let totalEntries = 0
60
- let totalEntrySize = 0
61
-
62
- // reads contents of tarball
63
- await tar.t({
64
- file: target,
65
- onentry (entry) {
66
- totalEntries++
67
- totalEntrySize += entry.size
68
- const p = entry.path
69
- if (p.startsWith('package/node_modules/')) {
70
- const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1]
71
- bundled.add(name)
72
- }
73
- files.push({
74
- path: entry.path.replace(/^package\//, ''),
75
- size: entry.size,
76
- mode: entry.mode
77
- })
78
- },
79
- strip: 1
80
- })
81
-
82
- const [stat, integrity] = await Promise.all([
83
- statAsync(target),
84
- ssri.fromStream(fs.createReadStream(target), {
85
- algorithms: ['sha1', 'sha512']
86
- })
87
- ])
88
-
89
- const comparator = (a, b) => {
90
- return a.path.localeCompare(b.path, undefined, {
91
- sensitivity: 'case',
92
- numeric: true
93
- })
94
- }
95
-
96
- const isUpper = (str) => {
97
- const ch = str.charAt(0)
98
- return ch >= 'A' && ch <= 'Z'
99
- }
100
-
101
- const uppers = files.filter(file => isUpper(file.path))
102
- const others = files.filter(file => !isUpper(file.path))
103
-
104
- uppers.sort(comparator)
105
- others.sort(comparator)
106
-
107
- const shasum = integrity.sha1[0].hexDigest()
108
- return {
109
- id: manifest._id || `${manifest.name}@${manifest.version}`,
110
- name: manifest.name,
111
- version: manifest.version,
112
- size: stat.size,
113
- unpackedSize: totalEntrySize,
114
- shasum,
115
- integrity: ssri.parse(integrity.sha512[0]),
116
- filename: `${manifest.name}-${manifest.version}.tgz`,
117
- files: uppers.concat(others),
118
- entryCount: totalEntries,
119
- bundled: Array.from(bundled)
120
- }
121
- }