2025-09-05 14:59:21 +08:00

194 lines
5.4 KiB
Markdown

# 📼 nanotar
[![npm version][npm-version-src]][npm-version-href]
[![bundle][bundle-src]][bundle-href]
<!-- [![npm downloads][npm-downloads-src]][npm-downloads-href] -->
<!-- [![Codecov][codecov-src]][codecov-href] -->
Tiny and fast [tar](<https://en.wikipedia.org/wiki/Tar_(computing)>) utils for any JavaScript runtime!
🌳 Tiny (~1KB minified + gzipped with all utils) and tree-shakable!
✨ Written with modern TypeScript and ESM format
✅ Works in any JavaScript runtime Node.js (18+), Bun, Deno, Browsers, and Edge Workers
🌐 Web Standard Compatible
🗜️ Built-in compression and decompression support
## Installation
Install package:
```sh
# npm
npm install nanotar
# yarn
yarn add nanotar
# pnpm
pnpm install nanotar
# bun
bun install nanotar
```
Import:
```js
// ESM
import {
createTar,
createTarGzip,
createTarGzipStream,
parseTar,
parseTarGzip,
} from "nanotar";
// CommonJS
const { createTar } = require("nanotar");
```
## Creating a tar archive
Easily create a new tar archive using the `createTar` utility.
The first argument is an array of files to archive:
- `name` field is required and you can use `/` to specify files within sub-directories.
- `data` field is optional for directories and can be either a [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) or [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).
- `attrs` field is optional for file attributes.
The second argument is for archive options. You can use `attrs` to set default attributes for all files (can still be overridden per file).
Possible attributes are:
- `mtime`: Last modification time. The default is `Date.now()`
- `uid`: Owner user id. The default is `1000`
- `gid`: Owner group id. The default is `1000`
- `user`: Owner user name. The default is `""`
- `group`: Owner user group. The default is `""`
- `mode`: file mode (permissions). Default is `664` (`-rw-rw-r--`) for files and `775` (`-rwxrwxr-x`) for directories
**Example:**
```ts
import { createTar } from "nanotar";
const data = createTar(
[
{ name: "README.md", data: "# Hello World!" },
{ name: "test", attrs: { mode: "777", mtime: 0 } },
{ name: "src/index.js", data: "console.log('wow!')" },
],
{ attrs: { user: "js", group: "js" } },
);
// Data is a Uint8Array view you can send or write to a file
```
### Compression
You can optionally use `createTarGzip` or `createTarGzipStream` to create a compressed tar data stream (returned value is a [`Promise<Uint8Array>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) or [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) piped to [`CompressionStream`](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream))
```js
import { createTarGzip, createTarGzipStream } from "nanotar";
createTarGzip([]); // Promise<Uint8Array>
createTarGzipStream([]); // ReadableStream
```
## Parsing a tar archive
Easily parse a tar archive using `parseTar` utility.
**Example:**
```ts
import { parseTar } from "nanotar";
// Read tar data from file or other sources into an ArrayBuffer or Uint8Array
const files = parseTar(data);
/**
[
{
"type": "file",
"name": "hello.txt",
"size": 12,
"data": Uint8Array [ ... ],
"text": "Hello World!",
"attrs": {
"gid": 1750,
"group": "",
"mode": "0000664",
"mtime": 1702076997,
"uid": 1750,
"user": "root",
},
},
...
]
*/
```
Parsed files array has two additional properties: `size` file size and `text`, a lazy getter that decodes `data` view as a string.
You can filter iterms to read using `filter` option:
```ts
const files = parseTar(data, {
filter: (file) => file.name.starsWith("dir/"),
});
```
Additionally, you can use `metaOnly` option to skip reading file data and listing purposes:
```ts
const fileMetas = parseTar(data, {
metaOnly: true,
});
```
### Decompression
If input is compressed, you can use `parseTarGzip` utility instead to parse it (it used [`DecompressionStream`](https://developer.mozilla.org/en-US/docs/Web/API/DecompressionStream) internally and return a `Promise<Uint8Array>` value)
```js
import { parseTarGzip } from "nanotar";
parseTarGzip(data); // Promise<Uint8Array>
```
## Development
- Clone this repository
- Install the latest LTS version of [Node.js](https://nodejs.org/en/)
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
- Install dependencies using `pnpm install`
- Run interactive tests using `pnpm dev`
## License
Made with 💛
Inspired by [ankitrohatgi/tarballjs](https://github.com/ankitrohatgi/tarballjs)
Published under the [MIT License](./LICENSE).
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/nanotar?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/nanotar
[npm-downloads-src]: https://img.shields.io/npm/dm/nanotar?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/nanotar
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/nanotar/main?style=flat&colorA=18181B&colorB=F0DB4F
[codecov-href]: https://codecov.io/gh/unjs/nanotar
[bundle-src]: https://img.shields.io/bundlephobia/minzip/nanotar?style=flat&colorA=18181B&colorB=F0DB4F
[bundle-href]: https://bundlephobia.com/result?p=nanotar