feat: init
This commit is contained in:
21
node_modules/nanotar/LICENSE
generated
vendored
Normal file
21
node_modules/nanotar/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Pooya Parsa <pooya@pi0.io>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
193
node_modules/nanotar/README.md
generated
vendored
Normal file
193
node_modules/nanotar/README.md
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
# 📼 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
|
||||
229
node_modules/nanotar/dist/index.cjs
generated
vendored
Normal file
229
node_modules/nanotar/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
'use strict';
|
||||
|
||||
const TAR_TYPE_FILE = 0;
|
||||
const TAR_TYPE_DIR = 5;
|
||||
function parseTar(data, opts) {
|
||||
const buffer = data.buffer || data;
|
||||
const files = [];
|
||||
let offset = 0;
|
||||
while (offset < buffer.byteLength - 512) {
|
||||
let name = _readString(buffer, offset, 100);
|
||||
if (name.length === 0) {
|
||||
break;
|
||||
}
|
||||
const mode = _readString(buffer, offset + 100, 8).trim();
|
||||
const uid = Number.parseInt(_readString(buffer, offset + 108, 8));
|
||||
const gid = Number.parseInt(_readString(buffer, offset + 116, 8));
|
||||
const size = _readNumber(buffer, offset + 124, 12);
|
||||
const seek = 512 + 512 * Math.trunc(size / 512) + (size % 512 ? 512 : 0);
|
||||
const mtime = _readNumber(buffer, offset + 136, 12);
|
||||
const _type = _readNumber(buffer, offset + 156, 1);
|
||||
const type = _type === TAR_TYPE_FILE ? "file" : _type === TAR_TYPE_DIR ? "directory" : _type;
|
||||
const user = _readString(buffer, offset + 265, 32);
|
||||
const group = _readString(buffer, offset + 297, 32);
|
||||
name = _sanitizePath(name);
|
||||
const meta = {
|
||||
name,
|
||||
type,
|
||||
size,
|
||||
attrs: {
|
||||
mode,
|
||||
uid,
|
||||
gid,
|
||||
mtime,
|
||||
user,
|
||||
group
|
||||
}
|
||||
};
|
||||
if (opts?.filter && !opts.filter(meta)) {
|
||||
offset += seek;
|
||||
continue;
|
||||
}
|
||||
if (opts?.metaOnly) {
|
||||
files.push(meta);
|
||||
offset += seek;
|
||||
continue;
|
||||
}
|
||||
const data2 = _type === TAR_TYPE_DIR ? undefined : new Uint8Array(buffer, offset + 512, size);
|
||||
files.push({
|
||||
...meta,
|
||||
data: data2,
|
||||
get text() {
|
||||
return new TextDecoder().decode(this.data);
|
||||
}
|
||||
});
|
||||
offset += seek;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
async function parseTarGzip(data, opts = {}) {
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(new Uint8Array(data));
|
||||
controller.close();
|
||||
}
|
||||
}).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
|
||||
const decompressedData = await new Response(stream).arrayBuffer();
|
||||
return parseTar(decompressedData, opts);
|
||||
}
|
||||
function _sanitizePath(path) {
|
||||
let normalized = path.replace(/\\/g, "/");
|
||||
normalized = normalized.replace(/^[a-zA-Z]:\//, "");
|
||||
normalized = normalized.replace(/^\/+/, "");
|
||||
const hasLeadingDotSlash = normalized.startsWith("./");
|
||||
const parts = normalized.split("/");
|
||||
const resolved = [];
|
||||
for (const part of parts) {
|
||||
if (part === "..") {
|
||||
resolved.pop();
|
||||
} else if (part !== "." && part !== "") {
|
||||
resolved.push(part);
|
||||
}
|
||||
}
|
||||
let result = resolved.join("/");
|
||||
if (hasLeadingDotSlash && !result.startsWith("./")) {
|
||||
result = "./" + result;
|
||||
}
|
||||
if (path.endsWith("/") && !result.endsWith("/")) {
|
||||
result += "/";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function _readString(buffer, offset, size) {
|
||||
const view = new Uint8Array(buffer, offset, size);
|
||||
const i = view.indexOf(0);
|
||||
const td = new TextDecoder();
|
||||
return td.decode(i === -1 ? view : view.slice(0, i));
|
||||
}
|
||||
function _readNumber(buffer, offset, size) {
|
||||
const view = new Uint8Array(buffer, offset, size);
|
||||
let str = "";
|
||||
for (let i = 0; i < size; i++) {
|
||||
str += String.fromCodePoint(view[i]);
|
||||
}
|
||||
return Number.parseInt(str, 8);
|
||||
}
|
||||
|
||||
function createTar(files, opts = {}) {
|
||||
const _files = files.map((file) => {
|
||||
const data = _normalizeData(file.data);
|
||||
return {
|
||||
...file,
|
||||
data,
|
||||
size: data?.length || 0
|
||||
};
|
||||
});
|
||||
let tarDataSize = 0;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const size = _files[i].data?.length ?? 0;
|
||||
tarDataSize += 512 + 512 * Math.trunc(size / 512);
|
||||
if (size % 512) {
|
||||
tarDataSize += 512;
|
||||
}
|
||||
}
|
||||
let bufSize = 10240 * Math.trunc(tarDataSize / 10240);
|
||||
if (tarDataSize % 10240) {
|
||||
bufSize += 10240;
|
||||
}
|
||||
const buffer = new ArrayBuffer(bufSize);
|
||||
let offset = 0;
|
||||
for (const file of _files) {
|
||||
const isDir = !file.data;
|
||||
_writeString(buffer, file.name, offset, 100);
|
||||
const mode = file.attrs?.mode ?? opts.attrs?.mode ?? (isDir ? "775" : "664");
|
||||
_writeString(buffer, _leftPad(mode, 7), offset + 100, 8);
|
||||
const uid = file.attrs?.uid ?? opts.attrs?.uid ?? 1e3;
|
||||
_writeString(buffer, _leftPad(uid.toString(8), 7), offset + 108, 8);
|
||||
const gid = file.attrs?.gid ?? opts.attrs?.gid ?? 1e3;
|
||||
_writeString(buffer, _leftPad(gid.toString(8), 7), offset + 116, 8);
|
||||
_writeString(buffer, _leftPad(file.size.toString(8), 11), offset + 124, 12);
|
||||
const mtime = file.attrs?.mtime ?? opts.attrs?.mtime ?? Date.now();
|
||||
_writeString(
|
||||
buffer,
|
||||
_leftPad(Math.trunc(mtime / 1e3).toString(8), 11),
|
||||
offset + 136,
|
||||
12
|
||||
);
|
||||
const type = isDir ? "5" : "0";
|
||||
_writeString(buffer, type, offset + 156, 1);
|
||||
_writeString(
|
||||
buffer,
|
||||
"ustar",
|
||||
offset + 257,
|
||||
6
|
||||
/* magic string */
|
||||
);
|
||||
_writeString(
|
||||
buffer,
|
||||
"00",
|
||||
offset + 263,
|
||||
2
|
||||
/* magic version */
|
||||
);
|
||||
const user = file.attrs?.user ?? opts.attrs?.user ?? "";
|
||||
_writeString(buffer, user, offset + 265, 32);
|
||||
const group = file.attrs?.group ?? opts.attrs?.group ?? "";
|
||||
_writeString(buffer, group, offset + 297, 32);
|
||||
_writeString(buffer, " ", offset + 148, 8);
|
||||
const header = new Uint8Array(buffer, offset, 512);
|
||||
let chksum = 0;
|
||||
for (let i = 0; i < 512; i++) {
|
||||
chksum += header[i];
|
||||
}
|
||||
_writeString(buffer, chksum.toString(8), offset + 148, 8);
|
||||
if (!isDir) {
|
||||
const destArray = new Uint8Array(buffer, offset + 512, file.size);
|
||||
for (let byteIdx = 0; byteIdx < file.size; byteIdx++) {
|
||||
destArray[byteIdx] = file.data[byteIdx];
|
||||
}
|
||||
offset += 512 * Math.trunc(file.size / 512);
|
||||
if (file.size % 512) {
|
||||
offset += 512;
|
||||
}
|
||||
}
|
||||
offset += 512;
|
||||
}
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
function createTarGzipStream(files, opts = {}) {
|
||||
const buffer = createTar(files, opts);
|
||||
return new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(buffer);
|
||||
controller.close();
|
||||
}
|
||||
}).pipeThrough(new CompressionStream(opts.compression ?? "gzip"));
|
||||
}
|
||||
async function createTarGzip(files, opts = {}) {
|
||||
const data = await new Response(createTarGzipStream(files, opts)).arrayBuffer().then((buffer) => new Uint8Array(buffer));
|
||||
return data;
|
||||
}
|
||||
function _writeString(buffer, str, offset, size) {
|
||||
const strView = new Uint8Array(buffer, offset, size);
|
||||
const te = new TextEncoder();
|
||||
const written = te.encodeInto(str, strView).written;
|
||||
for (let i = written; i < size; i++) {
|
||||
strView[i] = 0;
|
||||
}
|
||||
}
|
||||
function _leftPad(input, targetLength) {
|
||||
return String(input).padStart(targetLength, "0");
|
||||
}
|
||||
function _normalizeData(data) {
|
||||
if (data === null || data === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof data === "string") {
|
||||
return new TextEncoder().encode(data);
|
||||
}
|
||||
if (data instanceof ArrayBuffer) {
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
exports.createTar = createTar;
|
||||
exports.createTarGzip = createTarGzip;
|
||||
exports.createTarGzipStream = createTarGzipStream;
|
||||
exports.parseTar = parseTar;
|
||||
exports.parseTarGzip = parseTarGzip;
|
||||
133
node_modules/nanotar/dist/index.d.cts
generated
vendored
Normal file
133
node_modules/nanotar/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
type TarFileItem<DataT = Uint8Array> = {
|
||||
/**
|
||||
* File name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The data associated with the file. This field is usually omitted for directories.
|
||||
* @optional
|
||||
*/
|
||||
data?: DataT;
|
||||
/**
|
||||
* The attributes of the file. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
};
|
||||
interface ParsedTarFileItem extends TarFileItem {
|
||||
/**
|
||||
* The type of file system element. It can be `"file"`, `"directory"` or an operating system specific numeric code.
|
||||
*/
|
||||
type: "file" | "directory" | number;
|
||||
/**
|
||||
* The size of the file in bytes.
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* The textual representation of the file data. This property is read-only.
|
||||
*/
|
||||
readonly text: string;
|
||||
}
|
||||
type ParsedTarFileItemMeta = Omit<ParsedTarFileItem, "data" | "text">;
|
||||
interface TarFileAttrs {
|
||||
/**
|
||||
* File mode in octal (e.g., `664`) represents read, write, and execute permissions for the owner, group, and others.
|
||||
*/
|
||||
mode?: string;
|
||||
/**
|
||||
* The user ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
uid?: number;
|
||||
/**
|
||||
* The group ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
gid?: number;
|
||||
/**
|
||||
* The modification time of the file, expressed as the number of milliseconds since the UNIX epoch.
|
||||
* @default Date.now()
|
||||
*/
|
||||
mtime?: number;
|
||||
/**
|
||||
* The name of the user who owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
user?: string;
|
||||
/**
|
||||
* The name of the group that owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
group?: string;
|
||||
}
|
||||
|
||||
interface ParseTarOptions {
|
||||
/**
|
||||
* A filter function that determines whether a file entry should be skipped or not.
|
||||
*/
|
||||
filter?: (file: ParsedTarFileItemMeta) => boolean;
|
||||
/**
|
||||
* If `true`, only the metadata of the files will be parsed, and the file data will be omitted for listing purposes.
|
||||
*/
|
||||
metaOnly?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parses a TAR file from a binary buffer and returns an array of {@link TarFileItem} objects.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the TAR file.
|
||||
* @returns {ParsedTarFileItem[]} An array of file items contained in the TAR file.
|
||||
*/
|
||||
declare function parseTar<_ = never, _Opts extends ParseTarOptions = ParseTarOptions, _ItemType extends ParsedTarFileItem | ParsedTarFileItemMeta = _Opts["metaOnly"] extends true ? ParsedTarFileItemMeta : ParsedTarFileItem>(data: ArrayBuffer | Uint8Array, opts?: _Opts): _ItemType[];
|
||||
/**
|
||||
* Decompresses a gzipped TAR file and parses it to produce an array of file elements.
|
||||
* This function handles the decompression of the gzip format before parsing the contents of the TAR.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the gzipped TAR file.
|
||||
* @param {object} opts - Decompression options.
|
||||
* @param {CompressionFormat} [opts.compression="gzip"] - Specifies the compression format to use, defaults to `"gzip"`.
|
||||
* @returns {Promise<TarFileItem[]>} A promise that resolves to an array of file items as described by {@link TarFileItem}.
|
||||
*/
|
||||
declare function parseTarGzip(data: ArrayBuffer | Uint8Array, opts?: ParseTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<ParsedTarFileItem[]>;
|
||||
|
||||
interface CreateTarOptions {
|
||||
/**
|
||||
* Default attributes applied to all file unless overridden. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
}
|
||||
type TarFileInput = TarFileItem<string | Uint8Array | ArrayBuffer>;
|
||||
/**
|
||||
* Creates a TAR file from a list of file inputs and options, returning the TAR file as an `Uint8Array`.
|
||||
* This function takes care of normalising the file data, setting default attributes and calculating the TAR structure.
|
||||
*
|
||||
* @param {TarFileInput[]} files - An array of files to include in the TAR archive. Each file can contain different data types. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions} opts - File creation configuration options, including default file attributes. See {@link CreateTarOptions}.
|
||||
* @returns {Uint8Array} The TAR file encoded as an `Uint8Array`.
|
||||
*/
|
||||
declare function createTar(files: TarFileInput[], opts?: CreateTarOptions): Uint8Array;
|
||||
/**
|
||||
* Creates a gzipped TAR file stream from an array of file inputs, using optional compression settings.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression. See {@link CreateTarOptions}.
|
||||
* @returns {ReadableStream} A stream of the gzipped TAR file data.
|
||||
*/
|
||||
declare function createTarGzipStream(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): ReadableStream;
|
||||
/**
|
||||
* Asynchronously creates a gzipped TAR file from an array of file inputs.
|
||||
* This function is suitable for scenarios where a complete gzipped TAR file is required as a single `Uint8` array.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression.
|
||||
* @returns {Promise<Uint8Array>} A promise that resolves to the gzipped TAR file as an Uint8Array.
|
||||
*/
|
||||
declare function createTarGzip(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<Uint8Array>;
|
||||
|
||||
export { type CreateTarOptions, type ParseTarOptions, type ParsedTarFileItem, type ParsedTarFileItemMeta, type TarFileAttrs, type TarFileInput, type TarFileItem, createTar, createTarGzip, createTarGzipStream, parseTar, parseTarGzip };
|
||||
133
node_modules/nanotar/dist/index.d.mts
generated
vendored
Normal file
133
node_modules/nanotar/dist/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
type TarFileItem<DataT = Uint8Array> = {
|
||||
/**
|
||||
* File name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The data associated with the file. This field is usually omitted for directories.
|
||||
* @optional
|
||||
*/
|
||||
data?: DataT;
|
||||
/**
|
||||
* The attributes of the file. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
};
|
||||
interface ParsedTarFileItem extends TarFileItem {
|
||||
/**
|
||||
* The type of file system element. It can be `"file"`, `"directory"` or an operating system specific numeric code.
|
||||
*/
|
||||
type: "file" | "directory" | number;
|
||||
/**
|
||||
* The size of the file in bytes.
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* The textual representation of the file data. This property is read-only.
|
||||
*/
|
||||
readonly text: string;
|
||||
}
|
||||
type ParsedTarFileItemMeta = Omit<ParsedTarFileItem, "data" | "text">;
|
||||
interface TarFileAttrs {
|
||||
/**
|
||||
* File mode in octal (e.g., `664`) represents read, write, and execute permissions for the owner, group, and others.
|
||||
*/
|
||||
mode?: string;
|
||||
/**
|
||||
* The user ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
uid?: number;
|
||||
/**
|
||||
* The group ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
gid?: number;
|
||||
/**
|
||||
* The modification time of the file, expressed as the number of milliseconds since the UNIX epoch.
|
||||
* @default Date.now()
|
||||
*/
|
||||
mtime?: number;
|
||||
/**
|
||||
* The name of the user who owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
user?: string;
|
||||
/**
|
||||
* The name of the group that owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
group?: string;
|
||||
}
|
||||
|
||||
interface ParseTarOptions {
|
||||
/**
|
||||
* A filter function that determines whether a file entry should be skipped or not.
|
||||
*/
|
||||
filter?: (file: ParsedTarFileItemMeta) => boolean;
|
||||
/**
|
||||
* If `true`, only the metadata of the files will be parsed, and the file data will be omitted for listing purposes.
|
||||
*/
|
||||
metaOnly?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parses a TAR file from a binary buffer and returns an array of {@link TarFileItem} objects.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the TAR file.
|
||||
* @returns {ParsedTarFileItem[]} An array of file items contained in the TAR file.
|
||||
*/
|
||||
declare function parseTar<_ = never, _Opts extends ParseTarOptions = ParseTarOptions, _ItemType extends ParsedTarFileItem | ParsedTarFileItemMeta = _Opts["metaOnly"] extends true ? ParsedTarFileItemMeta : ParsedTarFileItem>(data: ArrayBuffer | Uint8Array, opts?: _Opts): _ItemType[];
|
||||
/**
|
||||
* Decompresses a gzipped TAR file and parses it to produce an array of file elements.
|
||||
* This function handles the decompression of the gzip format before parsing the contents of the TAR.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the gzipped TAR file.
|
||||
* @param {object} opts - Decompression options.
|
||||
* @param {CompressionFormat} [opts.compression="gzip"] - Specifies the compression format to use, defaults to `"gzip"`.
|
||||
* @returns {Promise<TarFileItem[]>} A promise that resolves to an array of file items as described by {@link TarFileItem}.
|
||||
*/
|
||||
declare function parseTarGzip(data: ArrayBuffer | Uint8Array, opts?: ParseTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<ParsedTarFileItem[]>;
|
||||
|
||||
interface CreateTarOptions {
|
||||
/**
|
||||
* Default attributes applied to all file unless overridden. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
}
|
||||
type TarFileInput = TarFileItem<string | Uint8Array | ArrayBuffer>;
|
||||
/**
|
||||
* Creates a TAR file from a list of file inputs and options, returning the TAR file as an `Uint8Array`.
|
||||
* This function takes care of normalising the file data, setting default attributes and calculating the TAR structure.
|
||||
*
|
||||
* @param {TarFileInput[]} files - An array of files to include in the TAR archive. Each file can contain different data types. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions} opts - File creation configuration options, including default file attributes. See {@link CreateTarOptions}.
|
||||
* @returns {Uint8Array} The TAR file encoded as an `Uint8Array`.
|
||||
*/
|
||||
declare function createTar(files: TarFileInput[], opts?: CreateTarOptions): Uint8Array;
|
||||
/**
|
||||
* Creates a gzipped TAR file stream from an array of file inputs, using optional compression settings.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression. See {@link CreateTarOptions}.
|
||||
* @returns {ReadableStream} A stream of the gzipped TAR file data.
|
||||
*/
|
||||
declare function createTarGzipStream(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): ReadableStream;
|
||||
/**
|
||||
* Asynchronously creates a gzipped TAR file from an array of file inputs.
|
||||
* This function is suitable for scenarios where a complete gzipped TAR file is required as a single `Uint8` array.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression.
|
||||
* @returns {Promise<Uint8Array>} A promise that resolves to the gzipped TAR file as an Uint8Array.
|
||||
*/
|
||||
declare function createTarGzip(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<Uint8Array>;
|
||||
|
||||
export { type CreateTarOptions, type ParseTarOptions, type ParsedTarFileItem, type ParsedTarFileItemMeta, type TarFileAttrs, type TarFileInput, type TarFileItem, createTar, createTarGzip, createTarGzipStream, parseTar, parseTarGzip };
|
||||
133
node_modules/nanotar/dist/index.d.ts
generated
vendored
Normal file
133
node_modules/nanotar/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
type TarFileItem<DataT = Uint8Array> = {
|
||||
/**
|
||||
* File name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The data associated with the file. This field is usually omitted for directories.
|
||||
* @optional
|
||||
*/
|
||||
data?: DataT;
|
||||
/**
|
||||
* The attributes of the file. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
};
|
||||
interface ParsedTarFileItem extends TarFileItem {
|
||||
/**
|
||||
* The type of file system element. It can be `"file"`, `"directory"` or an operating system specific numeric code.
|
||||
*/
|
||||
type: "file" | "directory" | number;
|
||||
/**
|
||||
* The size of the file in bytes.
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* The textual representation of the file data. This property is read-only.
|
||||
*/
|
||||
readonly text: string;
|
||||
}
|
||||
type ParsedTarFileItemMeta = Omit<ParsedTarFileItem, "data" | "text">;
|
||||
interface TarFileAttrs {
|
||||
/**
|
||||
* File mode in octal (e.g., `664`) represents read, write, and execute permissions for the owner, group, and others.
|
||||
*/
|
||||
mode?: string;
|
||||
/**
|
||||
* The user ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
uid?: number;
|
||||
/**
|
||||
* The group ID associated with the file.
|
||||
* @default 1000
|
||||
*/
|
||||
gid?: number;
|
||||
/**
|
||||
* The modification time of the file, expressed as the number of milliseconds since the UNIX epoch.
|
||||
* @default Date.now()
|
||||
*/
|
||||
mtime?: number;
|
||||
/**
|
||||
* The name of the user who owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
user?: string;
|
||||
/**
|
||||
* The name of the group that owns the file.
|
||||
* @default ""
|
||||
*/
|
||||
group?: string;
|
||||
}
|
||||
|
||||
interface ParseTarOptions {
|
||||
/**
|
||||
* A filter function that determines whether a file entry should be skipped or not.
|
||||
*/
|
||||
filter?: (file: ParsedTarFileItemMeta) => boolean;
|
||||
/**
|
||||
* If `true`, only the metadata of the files will be parsed, and the file data will be omitted for listing purposes.
|
||||
*/
|
||||
metaOnly?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parses a TAR file from a binary buffer and returns an array of {@link TarFileItem} objects.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the TAR file.
|
||||
* @returns {ParsedTarFileItem[]} An array of file items contained in the TAR file.
|
||||
*/
|
||||
declare function parseTar<_ = never, _Opts extends ParseTarOptions = ParseTarOptions, _ItemType extends ParsedTarFileItem | ParsedTarFileItemMeta = _Opts["metaOnly"] extends true ? ParsedTarFileItemMeta : ParsedTarFileItem>(data: ArrayBuffer | Uint8Array, opts?: _Opts): _ItemType[];
|
||||
/**
|
||||
* Decompresses a gzipped TAR file and parses it to produce an array of file elements.
|
||||
* This function handles the decompression of the gzip format before parsing the contents of the TAR.
|
||||
*
|
||||
* @param {ArrayBuffer | Uint8Array} data - The binary data of the gzipped TAR file.
|
||||
* @param {object} opts - Decompression options.
|
||||
* @param {CompressionFormat} [opts.compression="gzip"] - Specifies the compression format to use, defaults to `"gzip"`.
|
||||
* @returns {Promise<TarFileItem[]>} A promise that resolves to an array of file items as described by {@link TarFileItem}.
|
||||
*/
|
||||
declare function parseTarGzip(data: ArrayBuffer | Uint8Array, opts?: ParseTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<ParsedTarFileItem[]>;
|
||||
|
||||
interface CreateTarOptions {
|
||||
/**
|
||||
* Default attributes applied to all file unless overridden. See {@link TarFileAttrs}.
|
||||
* @optional
|
||||
*/
|
||||
attrs?: TarFileAttrs;
|
||||
}
|
||||
type TarFileInput = TarFileItem<string | Uint8Array | ArrayBuffer>;
|
||||
/**
|
||||
* Creates a TAR file from a list of file inputs and options, returning the TAR file as an `Uint8Array`.
|
||||
* This function takes care of normalising the file data, setting default attributes and calculating the TAR structure.
|
||||
*
|
||||
* @param {TarFileInput[]} files - An array of files to include in the TAR archive. Each file can contain different data types. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions} opts - File creation configuration options, including default file attributes. See {@link CreateTarOptions}.
|
||||
* @returns {Uint8Array} The TAR file encoded as an `Uint8Array`.
|
||||
*/
|
||||
declare function createTar(files: TarFileInput[], opts?: CreateTarOptions): Uint8Array;
|
||||
/**
|
||||
* Creates a gzipped TAR file stream from an array of file inputs, using optional compression settings.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive. See {@link TarFileInput}.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression. See {@link CreateTarOptions}.
|
||||
* @returns {ReadableStream} A stream of the gzipped TAR file data.
|
||||
*/
|
||||
declare function createTarGzipStream(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): ReadableStream;
|
||||
/**
|
||||
* Asynchronously creates a gzipped TAR file from an array of file inputs.
|
||||
* This function is suitable for scenarios where a complete gzipped TAR file is required as a single `Uint8` array.
|
||||
*
|
||||
* @param {TarFileInput[]} files - The files to include in the gzipped TAR archive.
|
||||
* @param {CreateTarOptions & { Compression? CompressionFormat }} opts - Options for TAR creation and gzip compression.
|
||||
* @returns {Promise<Uint8Array>} A promise that resolves to the gzipped TAR file as an Uint8Array.
|
||||
*/
|
||||
declare function createTarGzip(files: TarFileInput[], opts?: CreateTarOptions & {
|
||||
compression?: CompressionFormat;
|
||||
}): Promise<Uint8Array>;
|
||||
|
||||
export { type CreateTarOptions, type ParseTarOptions, type ParsedTarFileItem, type ParsedTarFileItemMeta, type TarFileAttrs, type TarFileInput, type TarFileItem, createTar, createTarGzip, createTarGzipStream, parseTar, parseTarGzip };
|
||||
223
node_modules/nanotar/dist/index.mjs
generated
vendored
Normal file
223
node_modules/nanotar/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
const TAR_TYPE_FILE = 0;
|
||||
const TAR_TYPE_DIR = 5;
|
||||
function parseTar(data, opts) {
|
||||
const buffer = data.buffer || data;
|
||||
const files = [];
|
||||
let offset = 0;
|
||||
while (offset < buffer.byteLength - 512) {
|
||||
let name = _readString(buffer, offset, 100);
|
||||
if (name.length === 0) {
|
||||
break;
|
||||
}
|
||||
const mode = _readString(buffer, offset + 100, 8).trim();
|
||||
const uid = Number.parseInt(_readString(buffer, offset + 108, 8));
|
||||
const gid = Number.parseInt(_readString(buffer, offset + 116, 8));
|
||||
const size = _readNumber(buffer, offset + 124, 12);
|
||||
const seek = 512 + 512 * Math.trunc(size / 512) + (size % 512 ? 512 : 0);
|
||||
const mtime = _readNumber(buffer, offset + 136, 12);
|
||||
const _type = _readNumber(buffer, offset + 156, 1);
|
||||
const type = _type === TAR_TYPE_FILE ? "file" : _type === TAR_TYPE_DIR ? "directory" : _type;
|
||||
const user = _readString(buffer, offset + 265, 32);
|
||||
const group = _readString(buffer, offset + 297, 32);
|
||||
name = _sanitizePath(name);
|
||||
const meta = {
|
||||
name,
|
||||
type,
|
||||
size,
|
||||
attrs: {
|
||||
mode,
|
||||
uid,
|
||||
gid,
|
||||
mtime,
|
||||
user,
|
||||
group
|
||||
}
|
||||
};
|
||||
if (opts?.filter && !opts.filter(meta)) {
|
||||
offset += seek;
|
||||
continue;
|
||||
}
|
||||
if (opts?.metaOnly) {
|
||||
files.push(meta);
|
||||
offset += seek;
|
||||
continue;
|
||||
}
|
||||
const data2 = _type === TAR_TYPE_DIR ? undefined : new Uint8Array(buffer, offset + 512, size);
|
||||
files.push({
|
||||
...meta,
|
||||
data: data2,
|
||||
get text() {
|
||||
return new TextDecoder().decode(this.data);
|
||||
}
|
||||
});
|
||||
offset += seek;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
async function parseTarGzip(data, opts = {}) {
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(new Uint8Array(data));
|
||||
controller.close();
|
||||
}
|
||||
}).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
|
||||
const decompressedData = await new Response(stream).arrayBuffer();
|
||||
return parseTar(decompressedData, opts);
|
||||
}
|
||||
function _sanitizePath(path) {
|
||||
let normalized = path.replace(/\\/g, "/");
|
||||
normalized = normalized.replace(/^[a-zA-Z]:\//, "");
|
||||
normalized = normalized.replace(/^\/+/, "");
|
||||
const hasLeadingDotSlash = normalized.startsWith("./");
|
||||
const parts = normalized.split("/");
|
||||
const resolved = [];
|
||||
for (const part of parts) {
|
||||
if (part === "..") {
|
||||
resolved.pop();
|
||||
} else if (part !== "." && part !== "") {
|
||||
resolved.push(part);
|
||||
}
|
||||
}
|
||||
let result = resolved.join("/");
|
||||
if (hasLeadingDotSlash && !result.startsWith("./")) {
|
||||
result = "./" + result;
|
||||
}
|
||||
if (path.endsWith("/") && !result.endsWith("/")) {
|
||||
result += "/";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function _readString(buffer, offset, size) {
|
||||
const view = new Uint8Array(buffer, offset, size);
|
||||
const i = view.indexOf(0);
|
||||
const td = new TextDecoder();
|
||||
return td.decode(i === -1 ? view : view.slice(0, i));
|
||||
}
|
||||
function _readNumber(buffer, offset, size) {
|
||||
const view = new Uint8Array(buffer, offset, size);
|
||||
let str = "";
|
||||
for (let i = 0; i < size; i++) {
|
||||
str += String.fromCodePoint(view[i]);
|
||||
}
|
||||
return Number.parseInt(str, 8);
|
||||
}
|
||||
|
||||
function createTar(files, opts = {}) {
|
||||
const _files = files.map((file) => {
|
||||
const data = _normalizeData(file.data);
|
||||
return {
|
||||
...file,
|
||||
data,
|
||||
size: data?.length || 0
|
||||
};
|
||||
});
|
||||
let tarDataSize = 0;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const size = _files[i].data?.length ?? 0;
|
||||
tarDataSize += 512 + 512 * Math.trunc(size / 512);
|
||||
if (size % 512) {
|
||||
tarDataSize += 512;
|
||||
}
|
||||
}
|
||||
let bufSize = 10240 * Math.trunc(tarDataSize / 10240);
|
||||
if (tarDataSize % 10240) {
|
||||
bufSize += 10240;
|
||||
}
|
||||
const buffer = new ArrayBuffer(bufSize);
|
||||
let offset = 0;
|
||||
for (const file of _files) {
|
||||
const isDir = !file.data;
|
||||
_writeString(buffer, file.name, offset, 100);
|
||||
const mode = file.attrs?.mode ?? opts.attrs?.mode ?? (isDir ? "775" : "664");
|
||||
_writeString(buffer, _leftPad(mode, 7), offset + 100, 8);
|
||||
const uid = file.attrs?.uid ?? opts.attrs?.uid ?? 1e3;
|
||||
_writeString(buffer, _leftPad(uid.toString(8), 7), offset + 108, 8);
|
||||
const gid = file.attrs?.gid ?? opts.attrs?.gid ?? 1e3;
|
||||
_writeString(buffer, _leftPad(gid.toString(8), 7), offset + 116, 8);
|
||||
_writeString(buffer, _leftPad(file.size.toString(8), 11), offset + 124, 12);
|
||||
const mtime = file.attrs?.mtime ?? opts.attrs?.mtime ?? Date.now();
|
||||
_writeString(
|
||||
buffer,
|
||||
_leftPad(Math.trunc(mtime / 1e3).toString(8), 11),
|
||||
offset + 136,
|
||||
12
|
||||
);
|
||||
const type = isDir ? "5" : "0";
|
||||
_writeString(buffer, type, offset + 156, 1);
|
||||
_writeString(
|
||||
buffer,
|
||||
"ustar",
|
||||
offset + 257,
|
||||
6
|
||||
/* magic string */
|
||||
);
|
||||
_writeString(
|
||||
buffer,
|
||||
"00",
|
||||
offset + 263,
|
||||
2
|
||||
/* magic version */
|
||||
);
|
||||
const user = file.attrs?.user ?? opts.attrs?.user ?? "";
|
||||
_writeString(buffer, user, offset + 265, 32);
|
||||
const group = file.attrs?.group ?? opts.attrs?.group ?? "";
|
||||
_writeString(buffer, group, offset + 297, 32);
|
||||
_writeString(buffer, " ", offset + 148, 8);
|
||||
const header = new Uint8Array(buffer, offset, 512);
|
||||
let chksum = 0;
|
||||
for (let i = 0; i < 512; i++) {
|
||||
chksum += header[i];
|
||||
}
|
||||
_writeString(buffer, chksum.toString(8), offset + 148, 8);
|
||||
if (!isDir) {
|
||||
const destArray = new Uint8Array(buffer, offset + 512, file.size);
|
||||
for (let byteIdx = 0; byteIdx < file.size; byteIdx++) {
|
||||
destArray[byteIdx] = file.data[byteIdx];
|
||||
}
|
||||
offset += 512 * Math.trunc(file.size / 512);
|
||||
if (file.size % 512) {
|
||||
offset += 512;
|
||||
}
|
||||
}
|
||||
offset += 512;
|
||||
}
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
function createTarGzipStream(files, opts = {}) {
|
||||
const buffer = createTar(files, opts);
|
||||
return new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(buffer);
|
||||
controller.close();
|
||||
}
|
||||
}).pipeThrough(new CompressionStream(opts.compression ?? "gzip"));
|
||||
}
|
||||
async function createTarGzip(files, opts = {}) {
|
||||
const data = await new Response(createTarGzipStream(files, opts)).arrayBuffer().then((buffer) => new Uint8Array(buffer));
|
||||
return data;
|
||||
}
|
||||
function _writeString(buffer, str, offset, size) {
|
||||
const strView = new Uint8Array(buffer, offset, size);
|
||||
const te = new TextEncoder();
|
||||
const written = te.encodeInto(str, strView).written;
|
||||
for (let i = written; i < size; i++) {
|
||||
strView[i] = 0;
|
||||
}
|
||||
}
|
||||
function _leftPad(input, targetLength) {
|
||||
return String(input).padStart(targetLength, "0");
|
||||
}
|
||||
function _normalizeData(data) {
|
||||
if (data === null || data === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof data === "string") {
|
||||
return new TextEncoder().encode(data);
|
||||
}
|
||||
if (data instanceof ArrayBuffer) {
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export { createTar, createTarGzip, createTarGzipStream, parseTar, parseTarGzip };
|
||||
51
node_modules/nanotar/package.json
generated
vendored
Normal file
51
node_modules/nanotar/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "nanotar",
|
||||
"version": "0.2.1",
|
||||
"description": "Tiny and fast Tar utils for any JavaScript runtime!",
|
||||
"repository": "unjs/nanotar",
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "unbuild",
|
||||
"dev": "vitest dev",
|
||||
"play": "jiti playground",
|
||||
"lint": "eslint --cache . && prettier -c src test",
|
||||
"lint:fix": "eslint --cache . --fix && prettier -c src test -w",
|
||||
"prepack": "pnpm run build",
|
||||
"release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
|
||||
"test": "pnpm lint && pnpm test:types && vitest run --coverage",
|
||||
"test:types": "tsc --noEmit --skipLibCheck"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.7",
|
||||
"@vitest/coverage-v8": "^3.0.2",
|
||||
"changelogen": "^0.5.7",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-unjs": "^0.4.2",
|
||||
"jiti": "^2.4.2",
|
||||
"prettier": "^3.4.2",
|
||||
"typescript": "^5.7.3",
|
||||
"unbuild": "^3.3.1",
|
||||
"vitest": "^3.0.2"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.4"
|
||||
}
|
||||
Reference in New Issue
Block a user