0
# File Copy Operations
1
2
Comprehensive file copying with glob pattern support, processing functions, and template integration for duplicating and transforming files during copy operations.
3
4
## Capabilities
5
6
### Basic File Copy
7
8
Copy files from source to destination with support for glob patterns and batch operations.
9
10
```typescript { .api }
11
/**
12
* Copy files with glob pattern support
13
* @param from - Source path(s) or glob pattern
14
* @param to - Destination path
15
* @param options - Copy configuration options
16
* @param context - Template context (if using templates)
17
* @param tplSettings - EJS template settings
18
*/
19
function copy(
20
from: string | string[],
21
to: string,
22
options?: CopyOptions,
23
context?: Record<string, any>,
24
tplSettings?: EJSOptions
25
): void;
26
27
interface CopyOptions {
28
/** Disable glob pattern matching (default: false) */
29
noGlob?: boolean;
30
/** Options passed to glob library */
31
globOptions?: GlobOptions;
32
/** Don't throw error if no files match pattern (default: false) */
33
ignoreNoMatch?: boolean;
34
/** Base path for relative source paths */
35
fromBasePath?: string;
36
/** Transform destination paths */
37
processDestinationPath?: (path: string) => string;
38
/** Append to destination files instead of overwriting */
39
append?: boolean;
40
/** Process file contents during copy */
41
process?: (contents: string | Buffer, filepath: string, destination: string) => string | Buffer;
42
}
43
44
interface GlobOptions {
45
/** Exclude directories from results */
46
nodir?: boolean;
47
/** Additional glob options */
48
[key: string]: any;
49
}
50
51
interface EJSOptions {
52
/** Template filename for error reporting */
53
filename?: string;
54
/** Enable template caching */
55
cache?: boolean;
56
/** Additional EJS options */
57
[key: string]: any;
58
}
59
60
interface CopySingleOptions {
61
/** Append to destination files instead of overwriting */
62
append?: boolean;
63
/** Process file contents during copy */
64
process?: (contents: string | Buffer, filepath: string, destination: string) => string | Buffer;
65
}
66
```
67
68
**Usage Examples:**
69
70
```typescript
71
import { create as createMemFs } from "mem-fs";
72
import { create as createEditor } from "mem-fs-editor";
73
74
const store = createMemFs();
75
const fs = createEditor(store);
76
77
// Copy single file
78
fs.copy("src/index.js", "dist/index.js");
79
80
// Copy with glob pattern
81
fs.copy("src/**/*.js", "dist/");
82
83
// Copy multiple specific files
84
fs.copy(["src/main.js", "src/utils.js"], "dist/");
85
86
// Copy all files from directory
87
fs.copy("templates/*", "output/");
88
89
// Copy with custom destination processing
90
fs.copy("src/**/*.ts", "dist/", {
91
processDestinationPath: (path) => path.replace(/\.ts$/, ".js")
92
});
93
```
94
95
### Async File Copy
96
97
Asynchronous file copying that reads directly from disk and supports background processing.
98
99
```typescript { .api }
100
/**
101
* Async version of copy with direct disk access
102
* @param from - Source path(s) or glob pattern
103
* @param to - Destination path
104
* @param options - Copy configuration options
105
* @param context - Template context (if using templates)
106
* @param tplSettings - EJS template settings
107
* @returns Promise that resolves when copy is complete
108
*/
109
function copyAsync(
110
from: string | string[],
111
to: string,
112
options?: CopyAsyncOptions,
113
context?: Record<string, any>,
114
tplSettings?: EJSOptions
115
): Promise<void>;
116
117
interface CopyAsyncOptions extends CopySingleAsyncOptions {
118
/** Options passed to glob library */
119
globOptions?: GlobOptions;
120
/** Transform destination paths */
121
processDestinationPath?: (path: string) => string;
122
/** Don't throw error if no files match pattern (default: false) */
123
ignoreNoMatch?: boolean;
124
}
125
126
interface CopySingleAsyncOptions extends AppendOptions, CopySingleOptions {
127
/** Append to destination files instead of overwriting */
128
append?: boolean;
129
/** Process individual file paths during async copy */
130
processFile?: (this: MemFsEditor, filepath: string) => string | Promise<string | Buffer>;
131
}
132
```
133
134
**Usage Examples:**
135
136
```typescript
137
// Async copy with await
138
await fs.copyAsync("src/**/*.js", "dist/");
139
140
// Async copy with file processing
141
await fs.copyAsync("images/**/*.jpg", "optimized/", {
142
processFile: async (file) => {
143
console.log(`Processing ${file}`);
144
// Could add image optimization here
145
}
146
});
147
148
// Async copy with content transformation
149
await fs.copyAsync("src/**/*.ts", "dist/", {
150
process: (contents, filepath) => {
151
// Transform TypeScript to JavaScript during copy
152
return contents.toString().replace(/: \w+/g, "");
153
}
154
});
155
```
156
157
### Content Processing During Copy
158
159
Transform file contents during copy operations using custom processing functions.
160
161
```typescript { .api }
162
/**
163
* Copy single file with processing options
164
* @param from - Source file path
165
* @param to - Destination path
166
* @param options - Copy options including processing function
167
*/
168
function _copySingle(from: string, to: string, options?: CopySingleOptions): void;
169
170
/**
171
* Async version of _copySingle for single file copy operations
172
* @param from - Source file path
173
* @param to - Destination path
174
* @param options - Copy options including processing function
175
* @returns Promise that resolves when copy is complete
176
*/
177
function _copySingleAsync(from: string, to: string, options?: CopySingleOptions): Promise<void>;
178
179
interface CopySingleOptions {
180
/** Append to destination instead of overwriting */
181
append?: boolean;
182
/** Process file contents during copy */
183
process?: (contents: string | Buffer, filepath: string, destination: string) => string | Buffer;
184
}
185
```
186
187
**Usage Examples:**
188
189
```typescript
190
// Copy with content transformation
191
fs.copy("src/config.template.js", "dist/config.js", {
192
process: (contents, filepath, destination) => {
193
return contents
194
.toString()
195
.replace("{{VERSION}}", "1.2.3")
196
.replace("{{ENV}}", "production");
197
}
198
});
199
200
// Copy and minify JavaScript
201
fs.copy("src/**/*.js", "dist/", {
202
process: (contents) => {
203
// Simple minification (remove comments and extra whitespace)
204
return contents
205
.toString()
206
.replace(/\/\*[\s\S]*?\*\//g, "")
207
.replace(/\/\/.*$/gm, "")
208
.replace(/^\s+/gm, "");
209
}
210
});
211
212
// Copy with file-specific processing
213
fs.copy("docs/**/*.md", "output/", {
214
process: (contents, filepath) => {
215
if (filepath.endsWith("README.md")) {
216
return `# Generated Documentation\n\n${contents}`;
217
}
218
return contents;
219
}
220
});
221
```
222
223
## Advanced Copy Patterns
224
225
### Directory Structure Copying
226
227
```typescript
228
// Maintain directory structure
229
fs.copy("src/**/*", "backup/", {
230
fromBasePath: "src"
231
});
232
233
// Flatten directory structure
234
fs.copy("src/**/*.js", "dist/js/", {
235
processDestinationPath: (path) => {
236
const filename = path.split("/").pop();
237
return `dist/js/${filename}`;
238
}
239
});
240
241
// Reorganize by file type
242
fs.copy("mixed/**/*", "organized/", {
243
processDestinationPath: (path) => {
244
const ext = path.split(".").pop();
245
const filename = path.split("/").pop();
246
return `organized/${ext}/${filename}`;
247
}
248
});
249
```
250
251
### Conditional Copying
252
253
```typescript
254
// Copy only specific file types
255
fs.copy("src/**/*", "dist/", {
256
globOptions: {
257
ignore: ["**/*.test.js", "**/*.spec.js"]
258
}
259
});
260
261
// Copy with size or date conditions
262
fs.copy("assets/**/*", "public/", {
263
process: (contents, filepath) => {
264
// Only copy files smaller than 1MB
265
if (contents.length > 1024 * 1024) {
266
console.log(`Skipping large file: ${filepath}`);
267
return null; // Skip this file
268
}
269
return contents;
270
}
271
});
272
```
273
274
### Batch Copy Operations
275
276
```typescript
277
// Copy multiple source patterns
278
const sources = [
279
"src/**/*.js",
280
"assets/**/*.css",
281
"public/**/*.html"
282
];
283
284
sources.forEach(pattern => {
285
fs.copy(pattern, "dist/");
286
});
287
288
// Copy with different destinations
289
const copyMap = {
290
"src/**/*.js": "dist/js/",
291
"styles/**/*.css": "dist/css/",
292
"images/**/*.{png,jpg}": "dist/images/"
293
};
294
295
Object.entries(copyMap).forEach(([from, to]) => {
296
fs.copy(from, to);
297
});
298
```
299
300
## Error Handling
301
302
```typescript
303
// Handle missing source files
304
fs.copy("optional/**/*", "dist/", {
305
ignoreNoMatch: true
306
});
307
308
// Copy with error handling
309
try {
310
fs.copy("src/**/*.js", "dist/");
311
} catch (error) {
312
if (error.message.includes("no files found")) {
313
console.log("No JavaScript files to copy");
314
} else {
315
throw error;
316
}
317
}
318
319
// Async copy with error handling
320
try {
321
await fs.copyAsync("large-files/**/*", "backup/");
322
} catch (error) {
323
console.error("Copy failed:", error.message);
324
}
325
```