0
# Implementation Classes
1
2
Pluggable ZIP implementations providing different performance and compatibility characteristics for various environments and use cases. These classes implement the ZipImpl interface and can be used as custom ZIP backends.
3
4
## Capabilities
5
6
### LibZipImpl Class
7
8
WebAssembly-based ZIP implementation using the compiled libzip C library for full-featured ZIP archive manipulation.
9
10
```typescript { .api }
11
/**
12
* WebAssembly-based ZIP implementation using compiled libzip
13
* Provides full ZIP functionality with high performance
14
*/
15
class LibZipImpl implements ZipImpl {
16
constructor(opts: ZipImplInput);
17
18
readonly filesShouldBeCached: boolean; // true - files should be cached for performance
19
20
// Entry management
21
deleteEntry(index: number): void;
22
addDirectory(path: string): number;
23
24
// File content operations
25
getFileSource(index: number): {data: Buffer, compressionMethod: number};
26
setFileSource(target: PortablePath, compression: CompressionData, buffer: Buffer): number;
27
28
// Metadata operations
29
setMtime(index: number, mtime: number): void;
30
setExternalAttributes(index: number, opsys: number, attributes: number): void;
31
getExternalAttributes(index: number): [opsys: number, attributes: number];
32
33
// Archive information
34
getSymlinkCount(): number;
35
getListings(): Array<string>;
36
stat(entry: number): Stat;
37
locate(name: string): number;
38
39
// Archive finalization
40
getBufferAndClose(): Buffer;
41
discard(): void;
42
}
43
```
44
45
**Usage Examples:**
46
47
```typescript
48
import { LibZipImpl } from "@yarnpkg/libzip";
49
import { ppath } from "@yarnpkg/fslib";
50
51
// Create from file path
52
const zipImpl = new LibZipImpl({
53
path: "/path/to/archive.zip" as ppath.PortablePath,
54
baseFs: require("fs"),
55
readOnly: false,
56
size: 1024
57
});
58
59
// Add a directory
60
const dirIndex = zipImpl.addDirectory("docs/");
61
62
// Add a file with content
63
const fileData = Buffer.from("Hello, World!");
64
const fileIndex = zipImpl.setFileSource(
65
"docs/hello.txt" as ppath.PortablePath,
66
[8, 6], // Deflate compression, level 6
67
fileData
68
);
69
70
// Set file modification time
71
zipImpl.setMtime(fileIndex, Math.floor(Date.now() / 1000));
72
73
// Set Unix permissions (0644)
74
zipImpl.setExternalAttributes(fileIndex, 3, 0o644 << 16);
75
76
// Get file content back
77
const {data, compressionMethod} = zipImpl.getFileSource(fileIndex);
78
79
// Get archive as buffer
80
const archiveBuffer = zipImpl.getBufferAndClose();
81
```
82
83
### JsZipImpl Class
84
85
Pure JavaScript ZIP implementation for read-only operations, providing compatibility without WebAssembly dependencies.
86
87
```typescript { .api }
88
/**
89
* Pure JavaScript ZIP implementation (read-only)
90
* Provides compatibility without WebAssembly dependencies
91
*/
92
class JsZipImpl implements ZipImpl {
93
constructor(opts: ZipImplInput);
94
95
readonly filesShouldBeCached: boolean; // false - operates directly on file descriptors
96
97
// Entry management (read-only operations only)
98
deleteEntry(index: number): void; // Throws error - not supported
99
addDirectory(path: string): number; // Throws error - not supported
100
101
// File content operations
102
getFileSource(index: number): {data: Buffer, compressionMethod: number};
103
setFileSource(target: PortablePath, compression: CompressionData, buffer: Buffer): number; // Throws error
104
105
// Metadata operations (read-only)
106
setMtime(index: number, mtime: number): void; // Throws error - not supported
107
setExternalAttributes(index: number, opsys: number, attributes: number): void; // Throws error
108
getExternalAttributes(index: number): [opsys: number, attributes: number];
109
110
// Archive information
111
getSymlinkCount(): number;
112
getListings(): Array<string>;
113
stat(entry: number): Stat;
114
locate(name: string): number;
115
116
// Archive operations (read-only)
117
getBufferAndClose(): Buffer; // Throws error - not supported
118
discard(): void;
119
}
120
```
121
122
**Usage Examples:**
123
124
```typescript
125
import { JsZipImpl } from "@yarnpkg/libzip";
126
import { ppath } from "@yarnpkg/fslib";
127
128
// Create read-only implementation from file
129
const zipImpl = new JsZipImpl({
130
path: "/path/to/existing.zip" as ppath.PortablePath,
131
baseFs: require("fs"),
132
readOnly: true, // Must be true
133
size: 2048
134
});
135
136
// Read archive contents
137
const listings = zipImpl.getListings();
138
console.log("Archive contains:", listings);
139
140
// Get file index by name
141
const fileIndex = zipImpl.locate("readme.txt");
142
143
if (fileIndex >= 0) {
144
// Get file statistics
145
const stats = zipImpl.stat(fileIndex);
146
console.log(`File size: ${stats.size}, CRC: ${stats.crc}`);
147
148
// Get file content
149
const {data, compressionMethod} = zipImpl.getFileSource(fileIndex);
150
console.log("Content:", data.toString());
151
152
// Get file attributes
153
const [opsys, attributes] = zipImpl.getExternalAttributes(fileIndex);
154
console.log(`OS: ${opsys}, Attributes: ${attributes}`);
155
}
156
157
// Get symlink count
158
const symlinkCount = zipImpl.getSymlinkCount();
159
console.log(`Archive contains ${symlinkCount} symlinks`);
160
161
// Clean up
162
zipImpl.discard();
163
```
164
165
### LibzipError Class
166
167
Custom error class for libzip-specific errors with error codes.
168
169
```typescript { .api }
170
/**
171
* Custom error class for libzip operations
172
* Provides structured error information with error codes
173
*/
174
class LibzipError extends Error {
175
readonly code: string;
176
177
constructor(message: string, code: string);
178
}
179
```
180
181
**Usage Example:**
182
183
```typescript
184
import { LibZipImpl, LibzipError } from "@yarnpkg/libzip";
185
186
try {
187
const zipImpl = new LibZipImpl({
188
path: "/nonexistent/archive.zip" as ppath.PortablePath,
189
baseFs: require("fs"),
190
readOnly: false,
191
size: 0
192
});
193
} catch (error) {
194
if (error instanceof LibzipError) {
195
console.error(`Libzip error [${error.code}]: ${error.message}`);
196
} else {
197
console.error("Other error:", error);
198
}
199
}
200
```
201
202
### ZIP Entry Metadata
203
204
Interface for ZIP entry statistics and metadata.
205
206
```typescript { .api }
207
interface Stat {
208
/** File modification time as Unix timestamp */
209
mtime: number;
210
/** CRC32 checksum of file data */
211
crc: number;
212
/** Uncompressed file size in bytes */
213
size: number;
214
}
215
216
interface Entry {
217
/** Entry name/path within the archive */
218
name: string;
219
/** Compression method used (0 = store, 8 = deflate, etc.) */
220
compressionMethod: number;
221
/** Uncompressed size in bytes */
222
size: number;
223
/** Operating system that created the entry */
224
os: number;
225
/** Whether the entry is a symbolic link */
226
isSymbolicLink: boolean;
227
/** CRC32 checksum of the file data */
228
crc: number;
229
/** Compressed size in bytes */
230
compressedSize: number;
231
/** External file attributes (permissions, etc.) */
232
externalAttributes: number;
233
/** File modification time as Unix timestamp */
234
mtime: number;
235
/** Offset to local header in ZIP file */
236
localHeaderOffset: number;
237
}
238
```
239
240
## Core Interface Types
241
242
```typescript { .api }
243
interface ZipImpl {
244
/** Whether files should be cached in memory for performance */
245
readonly filesShouldBeCached: boolean;
246
247
// Entry management
248
deleteEntry(index: number): void;
249
addDirectory(path: string): number;
250
251
// File operations
252
getFileSource(index: number): {data: Buffer, compressionMethod: number};
253
setFileSource(target: PortablePath, compression: CompressionData, buffer: Buffer): number;
254
255
// Metadata operations
256
setMtime(index: number, mtime: number): void;
257
setExternalAttributes(index: number, opsys: number, attributes: number): void;
258
getExternalAttributes(index: number): [opsys: number, attributes: number];
259
260
// Archive information
261
getSymlinkCount(): number;
262
getListings(): Array<string>;
263
stat(entry: number): Stat;
264
locate(name: string): number;
265
266
// Archive operations
267
getBufferAndClose(): Buffer;
268
discard(): void;
269
}
270
271
type ZipImplInput =
272
| {path: PortablePath, baseFs: FakeFS<PortablePath>, readOnly: boolean, size: number}
273
| {buffer: Buffer, readOnly: boolean};
274
275
interface ZipImplementationClass {
276
new(input: ZipImplInput): ZipImpl;
277
}
278
```