filepilot 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +307 -0
  2. package/package.json +119 -0
  3. package/readme.md +429 -0
package/index.js ADDED
@@ -0,0 +1,307 @@
1
+ // index.js
2
+ const fs = require("node:fs");
3
+ const path = require("node:path");
4
+ const { promisify } = require("node:util");
5
+
6
+ // Convert callback-based methods to Promise-based
7
+ const readFileAsync = promisify(fs.readFile);
8
+ const writeFileAsync = promisify(fs.writeFile);
9
+ const appendFileAsync = promisify(fs.appendFile);
10
+ const unlinkAsync = promisify(fs.unlink);
11
+ const mkdirAsync = promisify(fs.mkdir);
12
+ const readdirAsync = promisify(fs.readdir);
13
+
14
+ class FileHelper {
15
+ /**
16
+ * Read file synchronously
17
+ * @param {string} file - File path
18
+ * @param {string} encoding - File encoding (default: 'utf8')
19
+ * @returns {string|Buffer} File content
20
+ * @throws {Error} If file not found or other errors
21
+ */
22
+ static readSync(file, encoding = "utf8") {
23
+ try {
24
+ const content = fs.readFileSync(file, { encoding });
25
+ return content;
26
+ } catch (error) {
27
+ throw new Error(`Failed to read file ${file}: ${error.message}`);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Read file asynchronously with Promise
33
+ * @param {string} file - File path
34
+ * @param {string} encoding - File encoding (default: 'utf8')
35
+ * @returns {Promise<string|Buffer>} File content
36
+ */
37
+ static async read(file, encoding = "utf8") {
38
+ try {
39
+ const content = await readFileAsync(file, { encoding });
40
+ return content;
41
+ } catch (error) {
42
+ throw new Error(`Failed to read file ${file}: ${error.message}`);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Read file as stream
48
+ * @param {string} file - File path
49
+ * @param {Object} options - Stream options
50
+ * @returns {Promise<string>} File content as string
51
+ */
52
+ static async readStream(file, options = {}) {
53
+ return new Promise((resolve, reject) => {
54
+ let data = "";
55
+ const stream = fs.createReadStream(file, {
56
+ encoding: options.encoding || "utf8",
57
+ highWaterMark: options.highWaterMark || 64 * 1024,
58
+ ...options,
59
+ });
60
+
61
+ stream.on("data", (chunk) => {
62
+ data += chunk;
63
+ if (options.onChunk) options.onChunk(chunk);
64
+ });
65
+
66
+ stream.on("end", () => resolve(data));
67
+ stream.on("error", (err) => reject(new Error(`Stream error: ${err.message}`)));
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Read file line by line
73
+ * @param {string} file - File path
74
+ * @param {Function} lineHandler - Callback for each line
75
+ * @returns {Promise<number>} Number of lines read
76
+ */
77
+ static async readLines(file, lineHandler, encoding = "utf8") {
78
+ try {
79
+ const content = await this.read(file, encoding);
80
+ const lines = content.split(/\r?\n/);
81
+
82
+ for (let i = 0; i < lines.length; i++) {
83
+ if (lines[i]) {
84
+ await lineHandler(lines[i], i + 1);
85
+ }
86
+ }
87
+ return lines.filter(line => line).length;
88
+ } catch (error) {
89
+ throw new Error(`Failed to read lines from ${file}: ${error.message}`);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Write file synchronously
95
+ * @param {string} file - File path
96
+ * @param {string|Buffer} data - Data to write
97
+ * @param {Object} options - Write options
98
+ * @returns {boolean} Success status
99
+ */
100
+ static writeSync(file, data, options = {}) {
101
+ try {
102
+ fs.writeFileSync(file, data, {
103
+ encoding: options.encoding || "utf8",
104
+ mode: options.mode || 0o666,
105
+ ...options,
106
+ });
107
+ return true;
108
+ } catch (error) {
109
+ throw new Error(`Failed to write file ${file}: ${error.message}`);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Write file asynchronously
115
+ * @param {string} file - File path
116
+ * @param {string|Buffer} data - Data to write
117
+ * @param {Object} options - Write options
118
+ * @returns {Promise<boolean>} Success status
119
+ */
120
+ static async write(file, data, options = {}) {
121
+ try {
122
+ await writeFileAsync(file, data, {
123
+ encoding: options.encoding || "utf8",
124
+ mode: options.mode || 0o666,
125
+ ...options,
126
+ });
127
+ return true;
128
+ } catch (error) {
129
+ throw new Error(`Failed to write file ${file}: ${error.message}`);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Append content to file
135
+ * @param {string} file - File path
136
+ * @param {string|Buffer} data - Data to append
137
+ * @returns {Promise<boolean>} Success status
138
+ */
139
+ static async append(file, data, encoding = "utf8") {
140
+ try {
141
+ await appendFileAsync(file, data, { encoding });
142
+ return true;
143
+ } catch (error) {
144
+ throw new Error(`Failed to append to file ${file}: ${error.message}`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Check if file exists
150
+ * @param {string} file - File path
151
+ * @returns {boolean} File existence
152
+ */
153
+ static existsSync(file) {
154
+ try {
155
+ return fs.existsSync(file);
156
+ } catch {
157
+ return false;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Async file existence check
163
+ * @param {string} file - File path
164
+ * @returns {Promise<boolean>} File existence
165
+ */
166
+ static async exists(file) {
167
+ try {
168
+ await fs.promises.access(file, fs.constants.F_OK);
169
+ return true;
170
+ } catch {
171
+ return false;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Get file stats
177
+ * @param {string} file - File path
178
+ * @returns {Promise<fs.Stats>} File stats
179
+ */
180
+ static async stats(file) {
181
+ try {
182
+ return await fs.promises.stat(file);
183
+ } catch (error) {
184
+ throw new Error(`Failed to get stats for ${file}: ${error.message}`);
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Delete file
190
+ * @param {string} file - File path
191
+ * @returns {Promise<boolean>} Success status
192
+ */
193
+ static async delete(file) {
194
+ try {
195
+ await unlinkAsync(file);
196
+ return true;
197
+ } catch (error) {
198
+ throw new Error(`Failed to delete file ${file}: ${error.message}`);
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Copy file
204
+ * @param {string} source - Source file path
205
+ * @param {string} destination - Destination file path
206
+ * @returns {Promise<boolean>} Success status
207
+ */
208
+ static async copy(source, destination) {
209
+ try {
210
+ await fs.promises.copyFile(source, destination);
211
+ return true;
212
+ } catch (error) {
213
+ throw new Error(`Failed to copy from ${source} to ${destination}: ${error.message}`);
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Move/rename file
219
+ * @param {string} source - Source file path
220
+ * @param {string} destination - Destination file path
221
+ * @returns {Promise<boolean>} Success status
222
+ */
223
+ static async move(source, destination) {
224
+ try {
225
+ await fs.promises.rename(source, destination);
226
+ return true;
227
+ } catch (error) {
228
+ throw new Error(`Failed to move from ${source} to ${destination}: ${error.message}`);
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Create directory recursively
234
+ * @param {string} dir - Directory path
235
+ * @returns {Promise<boolean>} Success status
236
+ */
237
+ static async createDirectory(dir) {
238
+ try {
239
+ await mkdirAsync(dir, { recursive: true });
240
+ return true;
241
+ } catch (error) {
242
+ throw new Error(`Failed to create directory ${dir}: ${error.message}`);
243
+ }
244
+ }
245
+
246
+ /**
247
+ * List directory contents
248
+ * @param {string} dir - Directory path
249
+ * @param {Object} options - Options (withFileTypes, etc.)
250
+ * @returns {Promise<string[]|fs.Dirent[]>} Directory contents
251
+ */
252
+ static async listDirectory(dir, options = {}) {
253
+ try {
254
+ return await readdirAsync(dir, options);
255
+ } catch (error) {
256
+ throw new Error(`Failed to list directory ${dir}: ${error.message}`);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Watch file for changes
262
+ * @param {string} file - File path
263
+ * @param {Function} callback - Change handler
264
+ * @param {Object} options - Watch options
265
+ * @returns {fs.FSWatcher} Watcher instance
266
+ */
267
+ static watch(file, callback, options = {}) {
268
+ const watcher = fs.watch(file, options, (eventType, filename) => {
269
+ if (eventType === "change") {
270
+ callback(eventType, filename);
271
+ }
272
+ });
273
+ return watcher;
274
+ }
275
+ }
276
+
277
+ // For backward compatibility
278
+ function ReadFile(file) {
279
+ return FileHelper.readSync(file);
280
+ }
281
+
282
+ function ReadStream(file) {
283
+ return FileHelper.readStream(file);
284
+ }
285
+
286
+ module.exports = {
287
+ FileHelper,
288
+ readSync: FileHelper.readSync,
289
+ read: FileHelper.read,
290
+ readStream: FileHelper.readStream,
291
+ readLines: FileHelper.readLines,
292
+ writeSync: FileHelper.writeSync,
293
+ write: FileHelper.write,
294
+ append: FileHelper.append,
295
+ existsSync: FileHelper.existsSync,
296
+ exists: FileHelper.exists,
297
+ stats: FileHelper.stats,
298
+ delete: FileHelper.delete,
299
+ copy: FileHelper.copy,
300
+ move: FileHelper.move,
301
+ createDirectory: FileHelper.createDirectory,
302
+ listDirectory: FileHelper.listDirectory,
303
+ watch: FileHelper.watch,
304
+ // Legacy support
305
+ ReadFile,
306
+ ReadStream,
307
+ };
package/package.json ADDED
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "filepilot",
3
+ "version": "1.0.1",
4
+ "description": "A powerful, developer-friendly file system module for reading, writing, and managing files with ease",
5
+ "main": "index.js",
6
+ "files": [
7
+ "index.js",
8
+ "index.d.ts",
9
+ "README.md",
10
+ "LICENSE",
11
+ "CHANGELOG.md"
12
+ ],
13
+ "scripts": {
14
+ "test": "jest",
15
+ "test:watch": "jest --watch",
16
+ "test:coverage": "jest --coverage",
17
+ "lint": "eslint index.js",
18
+ "lint:fix": "eslint index.js --fix",
19
+ "docs": "jsdoc -c jsdoc.json",
20
+ "format": "prettier --write index.js"
21
+ },
22
+ "peerDependencies": {
23
+ "node": ">=14.0.0"
24
+ },
25
+ "engines": {
26
+ "node": ">=14.0.0"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/heroboyCloud/filepilot.git"
31
+ },
32
+ "homepage": "https://github.com/heroboyCloud/filepilot#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/heroboyCloud/filepilot/issues"
35
+ },
36
+ "keywords": [
37
+ "fs",
38
+ "file-system",
39
+ "read",
40
+ "write",
41
+ "file",
42
+ "simple",
43
+ "sync",
44
+ "async",
45
+ "stream",
46
+ "watch",
47
+ "copy",
48
+ "move",
49
+ "delete",
50
+ "directory",
51
+ "utility",
52
+ "files",
53
+ "io",
54
+ "file-manager"
55
+ ],
56
+ "author": {
57
+ "name": "Akindele Azeez",
58
+ "email": "shakiratakindel@gmail.com",
59
+ "url": "https://github.com/heroboyCloud"
60
+ },
61
+ "license": "MIT",
62
+ "funding": {
63
+ "type": "individual",
64
+ "url": "https://github.com/sponsors/heroboyCloud"
65
+ },
66
+ "private": false,
67
+ "publishConfig": {
68
+ "access": "public",
69
+ "registry": "https://registry.npmjs.org/"
70
+ },
71
+ "eslintConfig": {
72
+ "env": {
73
+ "node": true,
74
+ "es2021": true
75
+ },
76
+ "extends": [
77
+ "eslint:recommended",
78
+ "prettier"
79
+ ],
80
+ "parserOptions": {
81
+ "ecmaVersion": 2021,
82
+ "sourceType": "module"
83
+ },
84
+ "rules": {
85
+ "no-console": "off",
86
+ "no-unused-vars": [
87
+ "error",
88
+ {
89
+ "argsIgnorePattern": "^_"
90
+ }
91
+ ]
92
+ }
93
+ },
94
+ "jest": {
95
+ "testEnvironment": "node",
96
+ "coveragePathIgnorePatterns": [
97
+ "/node_modules/",
98
+ "/tests/"
99
+ ],
100
+ "collectCoverageFrom": [
101
+ "index.js"
102
+ ],
103
+ "coverageThreshold": {
104
+ "global": {
105
+ "branches": 80,
106
+ "functions": 80,
107
+ "lines": 80,
108
+ "statements": 80
109
+ }
110
+ }
111
+ },
112
+ "prettier": {
113
+ "semi": true,
114
+ "singleQuote": true,
115
+ "tabWidth": 2,
116
+ "trailingComma": "es5",
117
+ "printWidth": 100
118
+ }
119
+ }
package/readme.md ADDED
@@ -0,0 +1,429 @@
1
+ 📁 Easy File Reader
2
+
3
+ A powerful, developer-friendly Node.js module for seamless file operations with both synchronous and asynchronous support.
4
+
5
+ https://img.shields.io/npm/v/easy-file-reader.svg
6
+ https://img.shields.io/npm/dm/easy-file-reader.svg
7
+ https://img.shields.io/node/v/easy-file-reader.svg
8
+ https://img.shields.io/badge/License-MIT-yellow.svg
9
+
10
+ ✨ Features
11
+
12
+ · 🚀 Simple & Intuitive API - Easy to learn and use
13
+ · 📖 Multiple Reading Methods - Sync, Async, Stream, and Line-by-Line
14
+ · ✍️ Complete File Operations - Read, Write, Append, Copy, Move, Delete
15
+ · 📂 Directory Management - Create, list, and manage directories
16
+ · 🔄 Stream Support - Handle large files efficiently
17
+ · 👁️ File Watching - Monitor file changes in real-time
18
+ · 🛡️ Robust Error Handling - Descriptive error messages
19
+ · 🎯 Promise-based - Modern async/await support
20
+ · 🔧 Flexible Options - Custom encoding, permissions, and more
21
+ · 📦 Zero Dependencies - Uses only Node.js built-in modules
22
+
23
+ 📦 Installation
24
+
25
+ ```bash
26
+ npm install easy-file-reader
27
+ ```
28
+
29
+ or
30
+
31
+ ```bash
32
+ yarn add easy-file-reader
33
+ ```
34
+
35
+ 🚀 Quick Start
36
+
37
+ ```javascript
38
+ const { read, write, readLines, watch } = require('easy-file-reader');
39
+
40
+ // Async/Await - Modern approach
41
+ async function example() {
42
+ try {
43
+ // Read a file
44
+ const content = await read('example.txt');
45
+ console.log(content);
46
+
47
+ // Write a file
48
+ await write('output.txt', 'Hello World!');
49
+
50
+ // Read lines
51
+ await readLines('log.txt', (line, num) => {
52
+ console.log(`Line ${num}: ${line}`);
53
+ });
54
+
55
+ // Watch for changes
56
+ const watcher = watch('config.json', (event, filename) => {
57
+ console.log(`${filename} changed!`);
58
+ });
59
+
60
+ } catch (error) {
61
+ console.error('Error:', error.message);
62
+ }
63
+ }
64
+ ```
65
+
66
+ 📚 API Reference
67
+
68
+ Reading Files
69
+
70
+ read(filePath, encoding = 'utf8')
71
+
72
+ Asynchronously reads a file and returns its content.
73
+
74
+ ```javascript
75
+ const content = await read('data.txt');
76
+ const buffer = await read('image.png', null); // Returns Buffer
77
+ ```
78
+
79
+ readSync(filePath, encoding = 'utf8')
80
+
81
+ Synchronously reads a file.
82
+
83
+ ```javascript
84
+ const content = readSync('data.txt');
85
+ ```
86
+
87
+ readStream(filePath, options = {})
88
+
89
+ Reads a file as a stream, perfect for large files.
90
+
91
+ ```javascript
92
+ const content = await readStream('large-file.log', {
93
+ encoding: 'utf8',
94
+ highWaterMark: 1024 * 1024, // 1MB chunks
95
+ onChunk: (chunk) => console.log('Received chunk:', chunk.length)
96
+ });
97
+ ```
98
+
99
+ readLines(filePath, lineHandler, encoding = 'utf8')
100
+
101
+ Reads a file line by line with a callback.
102
+
103
+ ```javascript
104
+ const lineCount = await readLines('data.csv', (line, number) => {
105
+ const [name, email] = line.split(',');
106
+ console.log(`User ${number}: ${name} - ${email}`);
107
+ });
108
+ ```
109
+
110
+ Writing Files
111
+
112
+ write(filePath, data, options = {})
113
+
114
+ Asynchronously writes data to a file.
115
+
116
+ ```javascript
117
+ await write('output.txt', 'Hello World', {
118
+ encoding: 'utf8',
119
+ mode: 0o644 // File permissions
120
+ });
121
+ ```
122
+
123
+ writeSync(filePath, data, options = {})
124
+
125
+ Synchronously writes data to a file.
126
+
127
+ ```javascript
128
+ writeSync('output.txt', 'Hello World');
129
+ ```
130
+
131
+ append(filePath, data, encoding = 'utf8')
132
+
133
+ Appends data to an existing file.
134
+
135
+ ```javascript
136
+ await append('log.txt', 'New log entry\n');
137
+ ```
138
+
139
+ File Operations
140
+
141
+ copy(source, destination)
142
+
143
+ Copies a file from source to destination.
144
+
145
+ ```javascript
146
+ await copy('source.txt', 'backup.txt');
147
+ ```
148
+
149
+ move(source, destination)
150
+
151
+ Moves or renames a file.
152
+
153
+ ```javascript
154
+ await move('old-name.txt', 'new-name.txt');
155
+ ```
156
+
157
+ delete(filePath)
158
+
159
+ Deletes a file.
160
+
161
+ ```javascript
162
+ await delete('temp-file.txt');
163
+ ```
164
+
165
+ exists(filePath)
166
+
167
+ Checks if a file exists (async).
168
+
169
+ ```javascript
170
+ if (await exists('config.json')) {
171
+ // File exists
172
+ }
173
+ ```
174
+
175
+ existsSync(filePath)
176
+
177
+ Synchronously checks if a file exists.
178
+
179
+ ```javascript
180
+ if (existsSync('config.json')) {
181
+ // File exists
182
+ }
183
+ ```
184
+
185
+ stats(filePath)
186
+
187
+ Gets file statistics.
188
+
189
+ ```javascript
190
+ const stats = await stats('file.txt');
191
+ console.log(`Size: ${stats.size} bytes`);
192
+ console.log(`Modified: ${stats.mtime}`);
193
+ ```
194
+
195
+ Directory Operations
196
+
197
+ createDirectory(dirPath)
198
+
199
+ Creates a directory (recursively).
200
+
201
+ ```javascript
202
+ await createDirectory('project/src/components');
203
+ ```
204
+
205
+ listDirectory(dirPath, options = {})
206
+
207
+ Lists directory contents.
208
+
209
+ ```javascript
210
+ const files = await listDirectory('project');
211
+ console.log(files);
212
+
213
+ // With file types
214
+ const entries = await listDirectory('project', { withFileTypes: true });
215
+ entries.forEach(entry => {
216
+ console.log(`${entry.name} (${entry.isDirectory() ? 'dir' : 'file'})`);
217
+ });
218
+ ```
219
+
220
+ File Watching
221
+
222
+ watch(filePath, callback, options = {})
223
+
224
+ Watches a file for changes and executes callback.
225
+
226
+ ```javascript
227
+ const watcher = watch('config.json', (event, filename) => {
228
+ console.log(`${filename} changed!`);
229
+ // Reload configuration
230
+ }, { persistent: true });
231
+
232
+ // Stop watching
233
+ watcher.close();
234
+ ```
235
+
236
+ Legacy Support
237
+
238
+ For backward compatibility with your original API:
239
+
240
+ ```javascript
241
+ const { ReadFile, ReadStream } = require('easy-file-reader');
242
+
243
+ // Sync read
244
+ const content = ReadFile('file.txt');
245
+
246
+ // Stream read (returns string)
247
+ ReadStream('file.txt').then(content => console.log(content));
248
+ ```
249
+
250
+ 💡 Advanced Examples
251
+
252
+ Processing Large CSV Files
253
+
254
+ ```javascript
255
+ const { readLines } = require('easy-file-reader');
256
+
257
+ async function processLargeCSV() {
258
+ let total = 0;
259
+ await readLines('large-dataset.csv', (line, num) => {
260
+ // Skip header
261
+ if (num === 1) return;
262
+
263
+ const [id, name, value] = line.split(',');
264
+ total += parseFloat(value);
265
+
266
+ if (num % 1000 === 0) {
267
+ console.log(`Processed ${num} rows...`);
268
+ }
269
+ });
270
+ console.log(`Total: ${total}`);
271
+ }
272
+ ```
273
+
274
+ Config File with Watching
275
+
276
+ ```javascript
277
+ const { read, watch } = require('easy-file-reader');
278
+
279
+ class ConfigManager {
280
+ constructor(configPath) {
281
+ this.configPath = configPath;
282
+ this.config = null;
283
+ this.watcher = null;
284
+ this.listeners = [];
285
+ }
286
+
287
+ async load() {
288
+ try {
289
+ const data = await read(this.configPath);
290
+ this.config = JSON.parse(data);
291
+ this.notifyListeners();
292
+ return this.config;
293
+ } catch (error) {
294
+ console.error('Failed to load config:', error.message);
295
+ }
296
+ }
297
+
298
+ watch(autoReload = true) {
299
+ this.watcher = watch(this.configPath, async () => {
300
+ if (autoReload) {
301
+ console.log('Config changed, reloading...');
302
+ await this.load();
303
+ }
304
+ });
305
+ }
306
+
307
+ onReload(callback) {
308
+ this.listeners.push(callback);
309
+ }
310
+
311
+ notifyListeners() {
312
+ this.listeners.forEach(cb => cb(this.config));
313
+ }
314
+
315
+ stopWatching() {
316
+ if (this.watcher) {
317
+ this.watcher.close();
318
+ this.watcher = null;
319
+ }
320
+ }
321
+ }
322
+
323
+ // Usage
324
+ const config = new ConfigManager('app-config.json');
325
+ await config.load();
326
+ config.onReload((newConfig) => console.log('Config updated:', newConfig));
327
+ config.watch();
328
+ ```
329
+
330
+ Backup System
331
+
332
+ ```javascript
333
+ const { copy, read, write, stats, listDirectory } = require('easy-file-reader');
334
+
335
+ async function createBackup(sourceDir, backupDir) {
336
+ // Create backup directory with timestamp
337
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
338
+ const backupPath = `${backupDir}/backup-${timestamp}`;
339
+ await createDirectory(backupPath);
340
+
341
+ // Get all files
342
+ const files = await listDirectory(sourceDir);
343
+ const results = [];
344
+
345
+ for (const file of files) {
346
+ const sourceFile = `${sourceDir}/${file}`;
347
+ const destFile = `${backupPath}/${file}`;
348
+
349
+ // Get file stats
350
+ const fileStats = await stats(sourceFile);
351
+
352
+ // Copy file
353
+ await copy(sourceFile, destFile);
354
+ results.push({
355
+ file,
356
+ size: fileStats.size,
357
+ modified: fileStats.mtime
358
+ });
359
+ }
360
+
361
+ // Create manifest
362
+ await write(`${backupPath}/manifest.json`, JSON.stringify({
363
+ timestamp: new Date().toISOString(),
364
+ files: results,
365
+ totalFiles: results.length,
366
+ totalSize: results.reduce((sum, f) => sum + f.size, 0)
367
+ }, null, 2));
368
+
369
+ return results;
370
+ }
371
+ ```
372
+
373
+ 🛠️ Error Handling
374
+
375
+ All methods throw descriptive errors that you should catch:
376
+
377
+ ```javascript
378
+ try {
379
+ const content = await read('missing-file.txt');
380
+ } catch (error) {
381
+ console.error('Failed to read file:', error.message);
382
+ // Handle the error appropriately
383
+ }
384
+ ```
385
+
386
+ ⚡ Performance Tips
387
+
388
+ 1. Large Files: Use readStream() instead of read() for files > 100MB
389
+ 2. Line Processing: Use readLines() for processing large text files line by line
390
+ 3. Batch Operations: Use async/await with Promise.all() for multiple files
391
+ 4. Watch Mode: Use { persistent: false } for one-time change detection
392
+
393
+ 🔒 Security
394
+
395
+ · All file operations are subject to Node.js file system permissions
396
+ · Use mode option to set file permissions (default: 0o666)
397
+ · Validate user input before using in file paths
398
+
399
+ 🤝 Contributing
400
+
401
+ Contributions are welcome! Please follow these steps:
402
+
403
+ 1. Fork the repository
404
+ 2. Create a feature branch (git checkout -b feature/AmazingFeature)
405
+ 3. Commit your changes (git commit -m 'Add some AmazingFeature')
406
+ 4. Push to the branch (git push origin feature/AmazingFeature)
407
+ 5. Open a Pull Request
408
+
409
+ 📝 License
410
+
411
+ This project is licensed under the MIT License - see the LICENSE file for details.
412
+
413
+ 🙏 Acknowledgments
414
+
415
+ · Built with Node.js built-in fs module
416
+ · Inspired by simplicity and developer experience
417
+ · Community feedback and contributions
418
+
419
+ 📧 Support
420
+
421
+ · 📖 Documentation
422
+ · 🐛 Issue Tracker
423
+ · 💬 Discussions
424
+
425
+ ---
426
+
427
+ Made with ❤️ for developers who want simple, powerful file operations
428
+
429
+ Back to Top