@publint/pack
Version:
Utilities for packing and unpacking npm packages
109 lines (69 loc) • 4.37 kB
Markdown
# /pack
Zero-dependencies utilities for packing and unpacking npm packages. Supports:
<!-- The list below should sync with the docs at /docs/index.md -->
- npm (v9, v10, v11)
- yarn (v3, v4)
- pnpm (v8, v9, v10)
- bun
Older versions of these package managers may still work, but they're not officially tested. Yarn 1 is also explicitly not supported.
## API
NOTE: All `pack*` APIs support passing `opts.packageManager` to specify the package manager to use for packing, and `opts.ignoreScripts` to skip running lifecycle scripts.
### `pack()`
- **Type**: `(dir: string, opts?: PackOptions): Promise<string>`
Packs the given directory and returns the packed tarball path. Pass `opts.destination` to change the output directory of the tarball.
```js
import { pack } from '@publint/pack'
const tarballPath = await pack(process.cwd())
console.log(tarballPath)
// => '/Users/bluwy/project/project-1.0.0.tgz'
```
### `packAsList()`
- **Type**: `(dir: string, opts?: PackAsListOptions): Promise<string>`
Packs the given directory and returns a list of relative file paths that were packed.
The relative file paths should be resolved via `getPackDirectory()` if a different packed directory was used.
> [!NOTE]
> Compared to [`npm-packlist`](https://github.com/npm/npm-packlist), this API works at a higher level by invoking the package manager `pack` command to retrieve the list of files packed. While `npm-packlist` is abstracted away from `npm` to expose a more direct API, unfortunately not all package managers pack files the same way, e.g. the patterns in `"files"` may be interpreted differently. Plus, since `npm-packlist` v7, it requires `@npmcli/arborist` to be used together, which is a much larger dependency to include altogether.
>
> This package provides an alternative API that works across package managers with a much smaller package size. However, as it executes commands in a child process, it's usually slightly slower (around 200-500ms minimum depending on package manager used and the project size).
```js
import { packAsList } from '/pack'
const files = await packAsList(process.cwd())
console.log(files)
// => ['src/index.js', 'package.json']
```
### `packAsJson()`
- **Type**: `(dir: string, opts?: PackAsJsonOptions): Promise<string>`
Packs the given directory with the `--json` flag and returns its stdout as JSON. You can run the `<pm> pack --json` command manually to inspect the output shape.
Relative file paths in the output can be resolved via `getPackDirectory()` if a different packed directory was used.
> [!NOTE]
> Does not work in pnpm <9.14.1 and bun as they don't support the `--json` flag.
```js
import { packAsJson } from '/pack'
const json = await packAsJson(process.cwd())
console.log(json)
// => [{ "id": "project@1.0.0", ... }]
```
### `getPackDirectory()`
- **Type**: `(dir: string, packageManager?: PackageManager): Promise<string>`
Gets the directory that is being packed by the package manager. Usually this is the same as the input `dir`, but some package managers (like pnpm) allows changing the packed directory via the `publishConfig.directory` field in `package.json`.
```js
import { getPackDirectory } from '/pack'
const packDir = await getPackDirectory(process.cwd(), 'pnpm')
console.log(packDir)
// => '<cwd>/dist' (if "publishConfig.directory" is set to "dist" in package.json)
```
### `unpack()`
- **Type**: `(tarball: ArrayBuffer | ReadableStream<Uint8Array>): Promise<UnpackResult>`
Unpacks the given tarball buffer (gzip-decompress + untar). It accepts either a `ReadableStream`, `ArrayBuffer`, or `Uint8Array`. In Node.js,`ArrayBuffer` and `Uint8Array` are faster, while in browsers, `ReadableStream` is faster.
For example, when using `fetch()` in Node.js, use `response.arrayBuffer()` or `response.bytes()`, while in browsers, use `response.body` directly.
It returns an object with `files`, which is the list of unpacked files, and `rootDir`, which is the shared root directory among all files. (See JSDoc for examples)
```js
import { unpack } from '/pack'
const response = await fetch('https://registry.npmjs.org/mylib/-/mylib-1.0.0.tgz')
if (!response.body) throw new Error('Failed to fetch tarball')
const result = await unpack(response.body)
console.log(result)
// => { files: [...], rootDir: 'package' }
```
## License
MIT