or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# tar-fs

1

2

tar-fs provides filesystem bindings for tar-stream, enabling developers to pack directories into tarballs and extract tarballs into directories with a simple streaming API. It offers comprehensive tar file manipulation capabilities including selective file packing/extraction, header modification, stream transformation, and permission control.

3

4

## Package Information

5

6

- **Package Name**: tar-fs

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install tar-fs`

10

11

## Core Imports

12

13

```javascript

14

const tar = require('tar-fs');

15

```

16

17

For ES modules:

18

19

```javascript

20

import tar from 'tar-fs';

21

```

22

23

## Basic Usage

24

25

```javascript

26

const tar = require('tar-fs');

27

const fs = require('fs');

28

29

// Pack a directory into a tarball

30

tar.pack('./my-directory').pipe(fs.createWriteStream('my-tarball.tar'));

31

32

// Extract a tarball into a directory

33

fs.createReadStream('my-other-tarball.tar').pipe(tar.extract('./my-other-directory'));

34

35

// Copy a directory (with permissions and timestamps intact)

36

tar.pack('source-directory').pipe(tar.extract('dest-directory'));

37

```

38

39

## Architecture

40

41

tar-fs is built around two core streaming functions that work with tar-stream instances:

42

43

- **Pack Function**: Creates readable streams from filesystem directories, converting files and folders into tar entries

44

- **Extract Function**: Creates writable streams that consume tar entries and recreate filesystem structures

45

- **Options System**: Extensive configuration for filtering, transforming, and controlling permissions

46

- **Stream Integration**: Direct compatibility with tar-stream instances for advanced use cases

47

- **Cross-platform Support**: Works on Windows, macOS, Linux with platform-specific handling

48

49

## Capabilities

50

51

### Directory Packing

52

53

Packs a directory into a tar stream with extensive filtering and transformation options.

54

55

```javascript { .api }

56

/**

57

* Packs a directory into a tar stream

58

* @param cwd - Directory to pack (defaults to '.')

59

* @param opts - Packing options

60

* @returns tar-stream pack instance (readable stream)

61

*/

62

function pack(cwd, opts);

63

```

64

65

**Options:**

66

67

```javascript { .api }

68

interface PackOptions {

69

/** Custom filesystem implementation */

70

fs?: object;

71

/** Function to ignore/filter files: (name) => boolean */

72

ignore?: (name: string) => boolean;

73

/** Alias for ignore */

74

filter?: (name: string) => boolean;

75

/** Function to transform file streams: (stream, header) => stream */

76

mapStream?: (stream: ReadableStream, header: object) => ReadableStream;

77

/** Dereference symlinks (pack contents instead of links) */

78

dereference?: boolean;

79

/** Array of specific entries to pack */

80

entries?: string[];

81

/** Sort entries alphabetically */

82

sort?: boolean;

83

/** Strict mode - fail on unsupported file types (default: true) */

84

strict?: boolean;

85

/** Permission umask */

86

umask?: number;

87

/** Existing pack stream to use */

88

pack?: object;

89

/** Callback function on completion */

90

finish?: (pack: object) => void;

91

/** Function to modify tar headers: (header) => header */

92

map?: (header: object) => object;

93

/** Directory mode permissions */

94

dmode?: number;

95

/** File mode permissions */

96

fmode?: number;

97

/** Number of path levels to strip */

98

strip?: number;

99

/** Make files readable (adds 444 to files, 555 to directories) */

100

readable?: boolean;

101

/** Make files writable (adds 222 to files, 333 to directories) */

102

writable?: boolean;

103

/** Finalize pack when done (default: true) */

104

finalize?: boolean;

105

}

106

```

107

108

**Usage Examples:**

109

110

```javascript

111

// Pack with file filtering

112

const pack = tar.pack('./my-directory', {

113

ignore(name) {

114

return path.extname(name) === '.bin'; // ignore .bin files

115

}

116

});

117

118

// Pack specific entries only

119

const pack = tar.pack('./my-directory', {

120

entries: ['file1.txt', 'subdir/file2.txt']

121

});

122

123

// Pack with header modification

124

const pack = tar.pack('./my-directory', {

125

map(header) {

126

header.name = 'prefixed/' + header.name;

127

return header;

128

}

129

});

130

131

// Pack with stream transformation

132

const pack = tar.pack('./my-directory', {

133

mapStream(fileStream, header) {

134

if (path.extname(header.name) === '.js') {

135

return fileStream.pipe(someTransform);

136

}

137

return fileStream;

138

}

139

});

140

141

// Pack with custom permissions

142

const pack = tar.pack('./my-directory', {

143

dmode: parseInt('755', 8), // directory permissions

144

fmode: parseInt('644', 8), // file permissions

145

readable: true,

146

writable: false

147

});

148

```

149

150

### Tar Extraction

151

152

Extracts a tar stream into a directory with extensive filtering and transformation options.

153

154

```javascript { .api }

155

/**

156

* Extracts a tar stream into a directory

157

* @param cwd - Directory to extract to (defaults to '.')

158

* @param opts - Extraction options

159

* @returns tar-stream extract instance (writable stream)

160

*/

161

function extract(cwd, opts);

162

```

163

164

**Options:**

165

166

```javascript { .api }

167

interface ExtractOptions {

168

/** Custom filesystem implementation */

169

fs?: object;

170

/** Function to ignore/filter files: (name, header) => boolean */

171

ignore?: (name: string, header?: object) => boolean;

172

/** Alias for ignore */

173

filter?: (name: string, header?: object) => boolean;

174

/** Function to transform file streams: (stream, header) => stream */

175

mapStream?: (stream: ReadableStream, header: object) => ReadableStream;

176

/** Change file ownership (default: true on Unix as root) */

177

chown?: boolean;

178

/** Existing extract stream to use */

179

extract?: object;

180

/** Function to modify tar headers: (header) => header */

181

map?: (header: object) => object;

182

/** Directory mode permissions */

183

dmode?: number;

184

/** File mode permissions */

185

fmode?: number;

186

/** Number of path levels to strip */

187

strip?: number;

188

/** Make files readable (adds 444 to files, 555 to directories) */

189

readable?: boolean;

190

/** Make files writable (adds 222 to files, 333 to directories) */

191

writable?: boolean;

192

/** Strict mode - fail on unsupported entry types (default: true) */

193

strict?: boolean;

194

/** Validate symlinks are within extraction directory (default: true) */

195

validateSymlinks?: boolean;

196

/** Set file modification times (default: true) */

197

utimes?: boolean;

198

/** Permission umask */

199

umask?: number;

200

/** Callback function on completion */

201

finish?: () => void;

202

/** Fallback hard links as file copies on permission errors */

203

hardlinkAsFilesFallback?: boolean;

204

}

205

```

206

207

**Usage Examples:**

208

209

```javascript

210

// Extract with file filtering

211

const extract = tar.extract('./my-directory', {

212

ignore(name) {

213

return path.extname(name) === '.bin'; // ignore .bin files

214

}

215

});

216

217

// Extract with type filtering using header

218

const extract = tar.extract('./my-directory', {

219

ignore(name, header) {

220

// Only extract files and directories, ignore symlinks

221

return header.type !== 'file' && header.type !== 'directory';

222

}

223

});

224

225

// Extract with header modification

226

const extract = tar.extract('./my-directory', {

227

map(header) {

228

header.name = 'another-prefix/' + header.name;

229

return header;

230

}

231

});

232

233

// Extract with stream transformation

234

const extract = tar.extract('./my-directory', {

235

mapStream(fileStream, header) {

236

if (path.extname(header.name) === '.js') {

237

return fileStream.pipe(someTransform);

238

}

239

return fileStream;

240

}

241

});

242

243

// Extract with custom permissions

244

const extract = tar.extract('./my-directory', {

245

dmode: parseInt('755', 8), // directory permissions

246

fmode: parseInt('644', 8), // file permissions

247

readable: true,

248

writable: true

249

});

250

```

251

252

### Advanced tar-stream Integration

253

254

For advanced use cases, tar-fs integrates seamlessly with tar-stream instances.

255

256

```javascript { .api }

257

// Using custom pack stream

258

const mypack = tar.pack('./my-directory', {

259

finalize: false,

260

finish(pack) {

261

// Add custom entry

262

pack.entry({name: 'generated-file.txt'}, 'Hello World');

263

// Pack another directory into same stream

264

tar.pack('./other-directory', { pack: pack });

265

}

266

});

267

268

// Using custom extract stream

269

const tarStream = require('tar-stream');

270

const extract = tarStream.extract();

271

extract.on('entry', (header, stream, next) => {

272

// Custom entry processing

273

console.log('Extracting:', header.name);

274

stream.resume();

275

next();

276

});

277

278

tar.extract('./output', { extract: extract });

279

```

280

281

## Types

282

283

```javascript { .api }

284

interface TarHeader {

285

/** File/directory name */

286

name: string;

287

/** File mode/permissions */

288

mode: number;

289

/** User ID */

290

uid: number;

291

/** Group ID */

292

gid: number;

293

/** File size in bytes */

294

size: number;

295

/** Modification time */

296

mtime: Date;

297

/** Entry type: 'file', 'directory', 'symlink', 'link' */

298

type: string;

299

/** Link target for symlinks and hard links */

300

linkname?: string;

301

}

302

```

303

304

## Platform Considerations

305

306

- **Windows**: Symlinks and hard links are skipped due to platform limitations

307

- **Unix-like systems**: Full symlink and hard link support with security validation

308

- **Bare.js**: Alternative filesystem bindings through optional dependencies (bare-fs, bare-path)

309

- **Permissions**: Automatic umask handling and cross-platform permission management

310

311

## Error Handling

312

313

Common error scenarios:

314

315

- **ENOENT**: File not found during packing (ignored for dynamically deleted files)

316

- **EPERM**: Permission denied during extraction (handled with hardlinkAsFilesFallback)

317

- **Invalid symlinks**: Prevented by validateSymlinks option (default: true)

318

- **Unsupported file types**: Controlled by strict option (default: true)

319

- **Path traversal**: Prevented by built-in path validation