mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
feat(archive): change API to constructor-based with S3 support (#25940)
## Summary
- Change Archive API from `Bun.Archive.from(data)` to `new
Bun.Archive(data, options?)`
- Change compression options from `{ gzip: true }` to `{ compress:
"gzip", level?: number }`
- Default to no compression when no options provided
- Use `{ compress: "gzip" }` to enable gzip compression (level 6 by
default)
- Add Archive support for S3 and local file writes via `Bun.write()`
## New API
```typescript
// Create archive - defaults to uncompressed tar
const archive = new Bun.Archive({
"hello.txt": "Hello, World!",
"data.json": JSON.stringify({ foo: "bar" }),
});
// Enable gzip compression
const compressed = new Bun.Archive(files, { compress: "gzip" });
// Gzip with custom level (1-12)
const maxCompression = new Bun.Archive(files, { compress: "gzip", level: 12 });
// Write to local file
await Bun.write("archive.tar", archive); // uncompressed by default
await Bun.write("archive.tar.gz", compressed); // gzipped
// Write to S3
await client.write("archive.tar.gz", compressed); // S3Client.write()
await Bun.write("s3://bucket/archive.tar.gz", compressed); // S3 URL
await s3File.write(compressed); // s3File.write()
// Get bytes/blob (uses compression setting from constructor)
const bytes = await archive.bytes();
const blob = await archive.blob();
```
## TypeScript Types
```typescript
type ArchiveCompression = "gzip";
type ArchiveOptions = {
compress?: "gzip";
level?: number; // 1-12, default 6 when gzip enabled
};
```
## Test plan
- [x] 98 archive tests pass
- [x] S3 integration tests updated to new API
- [x] TypeScript types updated
- [x] Documentation updated with new examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
This commit is contained in:
126
packages/bun-types/bun.d.ts
vendored
126
packages/bun-types/bun.d.ts
vendored
@@ -750,7 +750,7 @@ declare module "bun" {
|
||||
*/
|
||||
function write(
|
||||
destination: BunFile | S3File | PathLike,
|
||||
input: Blob | NodeJS.TypedArray | ArrayBufferLike | string | BlobPart[],
|
||||
input: Blob | NodeJS.TypedArray | ArrayBufferLike | string | BlobPart[] | Archive,
|
||||
options?: {
|
||||
/**
|
||||
* If writing to a PathLike, set the permissions of the file.
|
||||
@@ -6975,15 +6975,44 @@ declare module "bun" {
|
||||
|
||||
/**
|
||||
* Compression format for archive output.
|
||||
* - `"gzip"` - Compress with gzip
|
||||
* - `true` - Same as `"gzip"`
|
||||
* - `false` - Explicitly disable compression (no compression)
|
||||
* - `undefined` - No compression (default behavior when omitted)
|
||||
*
|
||||
* Both `false` and `undefined` result in no compression; `false` can be used
|
||||
* to explicitly indicate "no compression" in code where the intent should be clear.
|
||||
* Currently only `"gzip"` is supported.
|
||||
*/
|
||||
type ArchiveCompression = "gzip" | boolean;
|
||||
type ArchiveCompression = "gzip";
|
||||
|
||||
/**
|
||||
* Options for creating an Archive instance.
|
||||
*
|
||||
* By default, archives are not compressed. Use `{ compress: "gzip" }` to enable compression.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // No compression (default)
|
||||
* new Bun.Archive(data);
|
||||
*
|
||||
* // Enable gzip with default level (6)
|
||||
* new Bun.Archive(data, { compress: "gzip" });
|
||||
*
|
||||
* // Specify compression level
|
||||
* new Bun.Archive(data, { compress: "gzip", level: 9 });
|
||||
* ```
|
||||
*/
|
||||
interface ArchiveOptions {
|
||||
/**
|
||||
* Compression algorithm to use.
|
||||
* Currently only "gzip" is supported.
|
||||
* If not specified, no compression is applied.
|
||||
*/
|
||||
compress?: ArchiveCompression;
|
||||
/**
|
||||
* Compression level (1-12). Only applies when `compress` is set.
|
||||
* - 1: Fastest compression, lowest ratio
|
||||
* - 6: Default balance of speed and ratio
|
||||
* - 12: Best compression ratio, slowest
|
||||
*
|
||||
* @default 6
|
||||
*/
|
||||
level?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for extracting archive contents.
|
||||
@@ -7031,7 +7060,7 @@ declare module "bun" {
|
||||
* @example
|
||||
* **Create an archive from an object:**
|
||||
* ```ts
|
||||
* const archive = Bun.Archive.from({
|
||||
* const archive = new Bun.Archive({
|
||||
* "hello.txt": "Hello, World!",
|
||||
* "data.json": JSON.stringify({ foo: "bar" }),
|
||||
* "binary.bin": new Uint8Array([1, 2, 3, 4]),
|
||||
@@ -7039,9 +7068,20 @@ declare module "bun" {
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **Create a gzipped archive:**
|
||||
* ```ts
|
||||
* const archive = new Bun.Archive({
|
||||
* "hello.txt": "Hello, World!",
|
||||
* }, { compress: "gzip" });
|
||||
*
|
||||
* // Or with a specific compression level (1-12)
|
||||
* const archive = new Bun.Archive(data, { compress: "gzip", level: 9 });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **Extract an archive to disk:**
|
||||
* ```ts
|
||||
* const archive = Bun.Archive.from(tarballBytes);
|
||||
* const archive = new Bun.Archive(tarballBytes);
|
||||
* const entryCount = await archive.extract("./output");
|
||||
* console.log(`Extracted ${entryCount} entries`);
|
||||
* ```
|
||||
@@ -7049,7 +7089,7 @@ declare module "bun" {
|
||||
* @example
|
||||
* **Get archive contents as a Map of File objects:**
|
||||
* ```ts
|
||||
* const archive = Bun.Archive.from(tarballBytes);
|
||||
* const archive = new Bun.Archive(tarballBytes);
|
||||
* const entries = await archive.files();
|
||||
* for (const [path, file] of entries) {
|
||||
* console.log(path, await file.text());
|
||||
@@ -7062,36 +7102,50 @@ declare module "bun" {
|
||||
* await Bun.Archive.write("bundle.tar.gz", {
|
||||
* "src/index.ts": sourceCode,
|
||||
* "package.json": packageJson,
|
||||
* }, "gzip");
|
||||
* }, { compress: "gzip" });
|
||||
* ```
|
||||
*/
|
||||
export class Archive {
|
||||
/**
|
||||
* Create an `Archive` instance from input data.
|
||||
*
|
||||
* By default, archives are not compressed. Use `{ compress: "gzip" }` to enable compression.
|
||||
*
|
||||
* @param data - The input data for the archive:
|
||||
* - **Object**: Creates a new tarball with the object's keys as file paths and values as file contents
|
||||
* - **Blob/TypedArray/ArrayBuffer**: Wraps existing archive data (tar or tar.gz)
|
||||
*
|
||||
* @returns A new `Archive` instance
|
||||
* @param options - Optional archive options including compression settings.
|
||||
* Defaults to no compression if omitted.
|
||||
*
|
||||
* @example
|
||||
* **From an object (creates new tarball):**
|
||||
* **From an object (creates uncompressed tarball):**
|
||||
* ```ts
|
||||
* const archive = Bun.Archive.from({
|
||||
* const archive = new Bun.Archive({
|
||||
* "hello.txt": "Hello, World!",
|
||||
* "nested/file.txt": "Nested content",
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **With gzip compression:**
|
||||
* ```ts
|
||||
* const archive = new Bun.Archive(data, { compress: "gzip" });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **With explicit gzip compression level:**
|
||||
* ```ts
|
||||
* const archive = new Bun.Archive(data, { compress: "gzip", level: 12 });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **From existing archive data:**
|
||||
* ```ts
|
||||
* const response = await fetch("https://example.com/package.tar.gz");
|
||||
* const archive = Bun.Archive.from(await response.blob());
|
||||
* const archive = new Bun.Archive(await response.blob());
|
||||
* ```
|
||||
*/
|
||||
static from(data: ArchiveInput): Archive;
|
||||
constructor(data: ArchiveInput, options?: ArchiveOptions);
|
||||
|
||||
/**
|
||||
* Create and write an archive directly to disk in one operation.
|
||||
@@ -7100,8 +7154,8 @@ declare module "bun" {
|
||||
* as it streams the data directly to disk.
|
||||
*
|
||||
* @param path - The file path to write the archive to
|
||||
* @param data - The input data for the archive (same as `Archive.from()`)
|
||||
* @param compress - Optional compression: `"gzip"`, `true` for gzip, or `false`/`undefined` for none
|
||||
* @param data - The input data for the archive (same as `new Archive()`)
|
||||
* @param options - Optional archive options including compression settings
|
||||
*
|
||||
* @returns A promise that resolves when the write is complete
|
||||
*
|
||||
@@ -7117,10 +7171,10 @@ declare module "bun" {
|
||||
* @example
|
||||
* **Write gzipped tarball:**
|
||||
* ```ts
|
||||
* await Bun.Archive.write("output.tar.gz", files, "gzip");
|
||||
* await Bun.Archive.write("output.tar.gz", files, { compress: "gzip" });
|
||||
* ```
|
||||
*/
|
||||
static write(path: string, data: ArchiveInput | Archive, compress?: ArchiveCompression): Promise<void>;
|
||||
static write(path: string, data: ArchiveInput | Archive, options?: ArchiveOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Extract the archive contents to a directory on disk.
|
||||
@@ -7136,7 +7190,7 @@ declare module "bun" {
|
||||
* @example
|
||||
* **Extract all entries:**
|
||||
* ```ts
|
||||
* const archive = Bun.Archive.from(tarballBytes);
|
||||
* const archive = new Bun.Archive(tarballBytes);
|
||||
* const count = await archive.extract("./extracted");
|
||||
* console.log(`Extracted ${count} entries`);
|
||||
* ```
|
||||
@@ -7166,42 +7220,48 @@ declare module "bun" {
|
||||
/**
|
||||
* Get the archive contents as a `Blob`.
|
||||
*
|
||||
* @param compress - Optional compression: `"gzip"`, `true` for gzip, or `false`/`undefined` for none
|
||||
* Uses the compression settings specified when the Archive was created.
|
||||
*
|
||||
* @returns A promise that resolves with the archive data as a Blob
|
||||
*
|
||||
* @example
|
||||
* **Get uncompressed tarball:**
|
||||
* **Get tarball as Blob:**
|
||||
* ```ts
|
||||
* const archive = new Bun.Archive(data);
|
||||
* const blob = await archive.blob();
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **Get gzipped tarball:**
|
||||
* **Get gzipped tarball as Blob:**
|
||||
* ```ts
|
||||
* const gzippedBlob = await archive.blob("gzip");
|
||||
* const archive = new Bun.Archive(data, { compress: "gzip" });
|
||||
* const gzippedBlob = await archive.blob();
|
||||
* ```
|
||||
*/
|
||||
blob(compress?: ArchiveCompression): Promise<Blob>;
|
||||
blob(): Promise<Blob>;
|
||||
|
||||
/**
|
||||
* Get the archive contents as a `Uint8Array`.
|
||||
*
|
||||
* @param compress - Optional compression: `"gzip"`, `true` for gzip, or `false`/`undefined` for none
|
||||
* Uses the compression settings specified when the Archive was created.
|
||||
*
|
||||
* @returns A promise that resolves with the archive data as a Uint8Array
|
||||
*
|
||||
* @example
|
||||
* **Get uncompressed tarball bytes:**
|
||||
* **Get tarball bytes:**
|
||||
* ```ts
|
||||
* const archive = new Bun.Archive(data);
|
||||
* const bytes = await archive.bytes();
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* **Get gzipped tarball bytes:**
|
||||
* ```ts
|
||||
* const gzippedBytes = await archive.bytes("gzip");
|
||||
* const archive = new Bun.Archive(data, { compress: "gzip" });
|
||||
* const gzippedBytes = await archive.bytes();
|
||||
* ```
|
||||
*/
|
||||
bytes(compress?: ArchiveCompression): Promise<Uint8Array<ArrayBuffer>>;
|
||||
bytes(): Promise<Uint8Array<ArrayBuffer>>;
|
||||
|
||||
/**
|
||||
* Get the archive contents as a `Map` of `File` objects.
|
||||
|
||||
18
packages/bun-types/s3.d.ts
vendored
18
packages/bun-types/s3.d.ts
vendored
@@ -609,7 +609,17 @@ declare module "bun" {
|
||||
* });
|
||||
*/
|
||||
write(
|
||||
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer | Request | Response | BunFile | S3File | Blob,
|
||||
data:
|
||||
| string
|
||||
| ArrayBufferView
|
||||
| ArrayBuffer
|
||||
| SharedArrayBuffer
|
||||
| Request
|
||||
| Response
|
||||
| BunFile
|
||||
| S3File
|
||||
| Blob
|
||||
| Archive,
|
||||
options?: S3Options,
|
||||
): Promise<number>;
|
||||
|
||||
@@ -920,7 +930,8 @@ declare module "bun" {
|
||||
| BunFile
|
||||
| S3File
|
||||
| Blob
|
||||
| File,
|
||||
| File
|
||||
| Archive,
|
||||
options?: S3Options,
|
||||
): Promise<number>;
|
||||
|
||||
@@ -970,7 +981,8 @@ declare module "bun" {
|
||||
| BunFile
|
||||
| S3File
|
||||
| Blob
|
||||
| File,
|
||||
| File
|
||||
| Archive,
|
||||
options?: S3Options,
|
||||
): Promise<number>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user