or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-processing.mdcli.mdcore-configuration.mddebugging.mdfile-operations.mdfrontmatter.mdindex.mdplugin-system.mdutilities.md

file-operations.mddocs/

0

# File Operations

1

2

File reading and writing operations for handling individual files and file collections. These methods provide direct access to Metalsmith's file I/O system for custom processing workflows.

3

4

## Capabilities

5

6

### Read Directory

7

8

Read all files from a directory, parsing front-matter and creating file objects.

9

10

```javascript { .api }

11

/**

12

* Read files from directory (Promise version)

13

* @param directory - Directory to read (defaults to source directory)

14

* @returns Promise resolving to Files object

15

*/

16

read(directory?: string): Promise<Files>;

17

18

/**

19

* Read files from directory (callback version)

20

* @param directory - Directory to read (defaults to source directory)

21

* @param callback - Callback receiving error and files

22

*/

23

read(directory: string, callback: FileCallback): void;

24

25

type FileCallback = (error: Error | null, files: Files) => void;

26

```

27

28

**Usage Examples:**

29

30

```javascript

31

import Metalsmith from "metalsmith";

32

33

const metalsmith = Metalsmith(__dirname);

34

35

// Read from default source directory

36

const files = await metalsmith.read();

37

console.log(`Read ${Object.keys(files).length} files`);

38

39

// Read from specific directory

40

const templateFiles = await metalsmith.read('./templates');

41

42

// Callback version

43

metalsmith.read((error, files) => {

44

if (error) throw error;

45

Object.keys(files).forEach(filepath => {

46

console.log(`File: ${filepath}`);

47

console.log(`Size: ${files[filepath].contents.length} bytes`);

48

});

49

});

50

```

51

52

### Read Single File

53

54

Read a single file by path, parsing front-matter if enabled.

55

56

```javascript { .api }

57

/**

58

* Read single file by path (Promise version)

59

* @param filepath - File path (relative to source directory or absolute)

60

* @returns Promise resolving to File object

61

*/

62

readFile(filepath: string): Promise<File>;

63

64

/**

65

* Read single file by path (callback version)

66

* @param filepath - File path (relative to source directory or absolute)

67

* @param callback - Callback receiving error and file

68

*/

69

readFile(filepath: string, callback: SingleFileCallback): void;

70

71

type SingleFileCallback = (error: Error | null, file?: File) => void;

72

```

73

74

**Usage Examples:**

75

76

```javascript

77

// Read specific file

78

const indexFile = await metalsmith.readFile('index.md');

79

console.log('Title:', indexFile.title);

80

console.log('Content:', indexFile.contents.toString());

81

82

// Read with absolute path

83

const configFile = await metalsmith.readFile('/path/to/config.json');

84

85

// Callback version

86

metalsmith.readFile('about.md', (error, file) => {

87

if (error) {

88

console.error('Failed to read file:', error.message);

89

return;

90

}

91

92

console.log('File metadata:', {

93

title: file.title,

94

date: file.date,

95

size: file.contents.length

96

});

97

});

98

```

99

100

### Write Files

101

102

Write a collection of files to the destination directory.

103

104

```javascript { .api }

105

/**

106

* Write files to destination directory (Promise version)

107

* @param files - Files object to write

108

* @param directory - Target directory (defaults to destination directory)

109

* @returns Promise that resolves when writing is complete

110

*/

111

write(files: Files, directory?: string): Promise<void>;

112

113

/**

114

* Write files to directory (callback version)

115

* @param files - Files object to write

116

* @param directory - Target directory (defaults to destination directory)

117

* @param callback - Callback for completion

118

*/

119

write(files: Files, directory: string, callback: BuildCallback): void;

120

121

/**

122

* Write files with callback only

123

* @param files - Files object to write

124

* @param callback - Callback for completion

125

*/

126

write(files: Files, callback: BuildCallback): void;

127

```

128

129

**Usage Examples:**

130

131

```javascript

132

// Write processed files to default destination

133

const files = await metalsmith.read();

134

// ... process files with plugins

135

await metalsmith.write(files);

136

137

// Write to specific directory

138

await metalsmith.write(files, './output');

139

140

// Callback version

141

metalsmith.write(files, (error) => {

142

if (error) {

143

console.error('Write failed:', error.message);

144

return;

145

}

146

console.log('Files written successfully');

147

});

148

```

149

150

### Write Single File

151

152

Write a single file to the destination directory.

153

154

```javascript { .api }

155

/**

156

* Write single file (Promise version)

157

* @param filepath - Target file path (relative to destination or absolute)

158

* @param data - File object to write

159

* @returns Promise that resolves when writing is complete

160

*/

161

writeFile(filepath: string, data: File): Promise<void>;

162

163

/**

164

* Write single file (callback version)

165

* @param filepath - Target file path (relative to destination or absolute)

166

* @param data - File object to write

167

* @param callback - Callback for completion

168

*/

169

writeFile(filepath: string, data: File, callback: ErrorCallback): void;

170

171

type ErrorCallback = (error: Error | null) => void;

172

```

173

174

**Usage Examples:**

175

176

```javascript

177

// Create and write a new file

178

const newFile = {

179

contents: Buffer.from('# New Page\n\nThis is content.'),

180

title: 'New Page',

181

date: new Date()

182

};

183

184

await metalsmith.writeFile('new-page.html', newFile);

185

186

// Write to specific location

187

await metalsmith.writeFile('/absolute/path/file.txt', {

188

contents: Buffer.from('File content')

189

});

190

191

// Callback version

192

metalsmith.writeFile('output.json', {

193

contents: Buffer.from(JSON.stringify(data, null, 2))

194

}, (error) => {

195

if (error) throw error;

196

console.log('JSON file written');

197

});

198

```

199

200

### File Object Structure

201

202

Understanding the File object structure for reading and writing operations.

203

204

```javascript { .api }

205

interface File {

206

/** File contents as Buffer (always present) */

207

contents: Buffer;

208

/** Node.js fs.Stats object with file system metadata */

209

stats?: import('fs').Stats;

210

/** Octal file permission mode (e.g., "0644") */

211

mode?: string;

212

/** Front-matter properties and custom metadata */

213

[key: string]: any;

214

}

215

216

interface Files {

217

/** File path mapped to File object */

218

[filepath: string]: File;

219

}

220

```

221

222

**File Manipulation Examples:**

223

224

```javascript

225

// Reading and modifying file contents

226

const files = await metalsmith.read();

227

228

Object.keys(files).forEach(filepath => {

229

const file = files[filepath];

230

231

// Access file contents

232

const content = file.contents.toString();

233

234

// Access front-matter data

235

console.log('Title:', file.title);

236

console.log('Date:', file.date);

237

console.log('Tags:', file.tags);

238

239

// Modify contents

240

file.contents = Buffer.from(content.toUpperCase());

241

242

// Add custom metadata

243

file.processedAt = new Date();

244

file.wordCount = content.split(/\s+/).length;

245

246

// Preserve file stats and mode

247

console.log('File size:', file.stats?.size);

248

console.log('File mode:', file.mode);

249

});

250

251

await metalsmith.write(files);

252

```

253

254

### Custom File Processing Workflows

255

256

Examples of custom workflows using file operations directly.

257

258

```javascript

259

// Custom build pipeline

260

async function customBuild() {

261

const metalsmith = Metalsmith(__dirname);

262

263

// Read source files

264

const sourceFiles = await metalsmith.read();

265

console.log(`Read ${Object.keys(sourceFiles).length} source files`);

266

267

// Read template files separately

268

const templates = await metalsmith.read('./templates');

269

console.log(`Read ${Object.keys(templates).length} templates`);

270

271

// Process files through plugins

272

const processedFiles = await metalsmith.run(sourceFiles);

273

274

// Write to multiple locations

275

await metalsmith.write(processedFiles, './public');

276

await metalsmith.write(processedFiles, './backup');

277

278

console.log('Custom build complete');

279

}

280

281

// Selective file processing

282

async function processSpecificFiles() {

283

const metalsmith = Metalsmith(__dirname);

284

285

// Read only markdown files

286

const allFiles = await metalsmith.read();

287

const markdownFiles = {};

288

289

Object.keys(allFiles)

290

.filter(filepath => filepath.endsWith('.md'))

291

.forEach(filepath => {

292

markdownFiles[filepath] = allFiles[filepath];

293

});

294

295

// Process only markdown files

296

const processed = await metalsmith.run(markdownFiles);

297

298

// Write processed files

299

await metalsmith.write(processed);

300

}

301

```

302

303

### Error Handling for File Operations

304

305

Common error scenarios and handling patterns.

306

307

```javascript

308

try {

309

const files = await metalsmith.read();

310

} catch (error) {

311

if (error.code === 'ENOENT') {

312

console.error('Source directory not found');

313

} else if (error.code === 'EACCES') {

314

console.error('Permission denied reading files');

315

} else if (error.code === 'invalid_frontmatter') {

316

console.error('Invalid front-matter in file:', error.message);

317

} else {

318

console.error('Read error:', error.message);

319

}

320

}

321

322

// Write error handling

323

try {

324

await metalsmith.write(files);

325

} catch (error) {

326

if (error.code === 'failed_write') {

327

console.error('Failed to write file:', error.message);

328

} else if (error.code === 'EACCES') {

329

console.error('Permission denied writing files');

330

} else {

331

console.error('Write error:', error.message);

332

}

333

}

334

```