or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extraction.mdindex.mdpacking.md

packing.mddocs/

0

# Tar Packing

1

2

Streaming tar archive generator that creates tar data from entries without hitting the file system. The pack stream allows adding files, directories, and other entry types to create complete tar archives.

3

4

## Capabilities

5

6

### Pack Factory Function

7

8

Creates a new tar packing stream.

9

10

```javascript { .api }

11

/**

12

* Creates a new tar packing stream

13

* @param {PackOptions} [opts] - Optional configuration

14

* @returns {Pack} Pack stream instance

15

*/

16

function pack(opts?: PackOptions): Pack;

17

18

interface PackOptions {

19

// No specific options currently defined

20

}

21

```

22

23

### Pack Stream

24

25

Readable stream that generates tar data from added entries.

26

27

```javascript { .api }

28

class Pack extends Readable {

29

/**

30

* Add an entry to the tar archive

31

* @param {Header} header - Entry metadata

32

* @param {Buffer|string} [buffer] - Entry content (for files)

33

* @param {Function} [callback] - Called when entry is added

34

* @returns {EntryWritableStream} Stream for writing entry content

35

*/

36

entry(header: Header, buffer?: Buffer | string, callback?: (err?: Error) => void): EntryWritableStream;

37

38

/**

39

* Finalize the tar archive - must be called when done adding entries

40

*/

41

finalize(): void;

42

}

43

```

44

45

### Entry Writable Stream

46

47

Writable stream for adding content to a tar entry.

48

49

```javascript { .api }

50

class EntryWritableStream extends Writable {

51

/** Number of bytes written to this entry */

52

written: number;

53

/** Header for this entry */

54

header: Header;

55

}

56

```

57

58

## Usage Examples

59

60

### Basic Packing

61

62

```javascript

63

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

64

const fs = require('fs');

65

66

const pack = tar.pack();

67

68

// Add a simple text file

69

pack.entry({ name: 'hello.txt' }, 'Hello World!');

70

71

// Add a file with metadata

72

pack.entry({

73

name: 'readme.md',

74

size: 13,

75

mode: 0o644,

76

mtime: new Date(),

77

type: 'file'

78

}, 'Hello README!');

79

80

// Finalize the archive

81

pack.finalize();

82

83

// Save to file

84

pack.pipe(fs.createWriteStream('archive.tar'));

85

```

86

87

### Streaming Entry Content

88

89

```javascript

90

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

91

92

const pack = tar.pack();

93

94

// Add a file with streaming content

95

const entry = pack.entry({

96

name: 'large-file.txt',

97

size: 11 // must specify size for streaming

98

}, function(err) {

99

if (err) throw err;

100

console.log('Entry added');

101

pack.finalize();

102

});

103

104

// Write content to the entry stream

105

entry.write('Hello ');

106

entry.write('World!');

107

entry.end();

108

109

pack.pipe(process.stdout);

110

```

111

112

### Directory Entries

113

114

```javascript

115

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

116

117

const pack = tar.pack();

118

119

// Add a directory

120

pack.entry({

121

name: 'my-directory/',

122

type: 'directory',

123

mode: 0o755

124

});

125

126

// Add files within the directory

127

pack.entry({

128

name: 'my-directory/file1.txt'

129

}, 'File 1 content');

130

131

pack.entry({

132

name: 'my-directory/file2.txt'

133

}, 'File 2 content');

134

135

pack.finalize();

136

```

137

138

### Symbolic Links

139

140

```javascript

141

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

142

143

const pack = tar.pack();

144

145

// Add a symlink

146

pack.entry({

147

name: 'link-to-file.txt',

148

type: 'symlink',

149

linkname: 'original-file.txt'

150

});

151

152

// Add the target file

153

pack.entry({

154

name: 'original-file.txt'

155

}, 'This is the original file');

156

157

pack.finalize();

158

```

159

160

### Complex Metadata

161

162

```javascript

163

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

164

165

const pack = tar.pack();

166

167

pack.entry({

168

name: 'important-file.txt',

169

size: 0,

170

mode: 0o600, // read-write for owner only

171

uid: 1000,

172

gid: 1000,

173

uname: 'user',

174

gname: 'group',

175

mtime: new Date('2023-01-01'),

176

type: 'file'

177

}, 'Sensitive content');

178

179

pack.finalize();

180

```

181

182

### Modifying Existing Archives

183

184

```javascript

185

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

186

const fs = require('fs');

187

188

const extract = tar.extract();

189

const pack = tar.pack();

190

191

extract.on('entry', function(header, stream, callback) {

192

// Modify the path - add 'backup/' prefix

193

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

194

195

// Pipe the entry to the new archive

196

stream.pipe(pack.entry(header, callback));

197

});

198

199

extract.on('finish', function() {

200

pack.finalize();

201

});

202

203

// Pipe old archive through extractor to new packer

204

fs.createReadStream('old.tar').pipe(extract);

205

pack.pipe(fs.createWriteStream('new.tar'));

206

```

207

208

### Error Handling

209

210

```javascript

211

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

212

213

const pack = tar.pack();

214

215

pack.on('error', function(err) {

216

console.error('Pack error:', err.message);

217

});

218

219

// Add entry with error handling

220

const entry = pack.entry({

221

name: 'test.txt',

222

size: 5 // size must match actual content

223

}, function(err) {

224

if (err) {

225

console.error('Entry error:', err.message);

226

return;

227

}

228

console.log('Entry added successfully');

229

pack.finalize();

230

});

231

232

entry.on('error', function(err) {

233

console.error('Entry stream error:', err.message);

234

});

235

236

entry.write('Hello'); // exactly 5 bytes as specified

237

entry.end();

238

```

239

240

## Important Notes

241

242

- **Size Specification**: When streaming content to entries, you must specify the exact size in the header

243

- **Finalization**: Always call `finalize()` when done adding entries to properly close the archive

244

- **Sequential Processing**: Entries are processed sequentially - wait for the callback before adding the next entry

245

- **Content Matching**: The actual content size must match the size specified in the header, or an error will occur

246

- **Entry Types**: Support for all standard tar entry types including files, directories, symlinks, and device files

247

- **Header Auto-completion**: Missing header fields are automatically filled with sensible defaults