0
# ncp
1
2
ncp (Node Copy) is an asynchronous recursive file and directory copying utility for Node.js that serves as a pure JavaScript alternative to the Unix `cp -r` command. It provides both programmatic API and command-line interface functionality with advanced features like concurrency control, file filtering, streaming transforms, and flexible error handling.
3
4
## Package Information
5
6
- **Package Name**: ncp
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install ncp`
10
11
## Core Imports
12
13
```javascript
14
const ncp = require('ncp').ncp;
15
```
16
17
Alternative import (equivalent):
18
19
```javascript
20
const ncp = require('ncp');
21
```
22
23
## Basic Usage
24
25
```javascript
26
const ncp = require('ncp').ncp;
27
28
// Basic file/directory copying
29
ncp('/path/to/source', '/path/to/destination', function (err) {
30
if (err) {
31
return console.error(err);
32
}
33
console.log('Copy completed successfully!');
34
});
35
36
// With options
37
ncp(source, destination, {
38
filter: /\.js$/, // Only copy .js files
39
limit: 32, // Higher concurrency
40
clobber: false, // Don't overwrite existing files
41
stopOnErr: true // Stop on first error
42
}, function (err) {
43
if (err) {
44
return console.error(err);
45
}
46
console.log('Copy completed with options!');
47
});
48
```
49
50
## Capabilities
51
52
### File Copying Function
53
54
Asynchronously copies files and directories from source to destination with comprehensive options for controlling the copy behavior.
55
56
```javascript { .api }
57
/**
58
* Copy files and directories asynchronously
59
* @param {string} source - Source file or directory path
60
* @param {string} dest - Destination file or directory path
61
* @param {function} callback - Completion callback function(err)
62
*/
63
function ncp(source, dest, callback);
64
65
/**
66
* Copy files and directories asynchronously with options
67
* @param {string} source - Source file or directory path
68
* @param {string} dest - Destination file or directory path
69
* @param {object} options - Copy options object
70
* @param {function} callback - Completion callback function(err)
71
*/
72
function ncp(source, dest, options, callback);
73
```
74
75
### Global Concurrency Control
76
77
Set global concurrency limit for all ncp operations.
78
79
```javascript { .api }
80
/**
81
* Global concurrency limit for file system operations
82
* @type {number}
83
* @default 16
84
*/
85
ncp.limit = 16;
86
```
87
88
### Alternative Access
89
90
Alternative way to access the ncp function.
91
92
```javascript { .api }
93
/**
94
* Alternative access to the main ncp function
95
* @type {function}
96
*/
97
ncp.ncp;
98
```
99
100
## Options
101
102
### File Filtering
103
104
Control which files get copied using regular expressions or custom functions.
105
106
```javascript { .api }
107
/**
108
* Filter files to be copied
109
* @typedef {RegExp|function} FilterOption
110
* @property {RegExp} filter - Regular expression to match file paths
111
* @property {function} filter - Function(filePath) returning boolean
112
*/
113
options.filter;
114
```
115
116
**Usage Examples:**
117
118
```javascript
119
// Regular expression filter - only copy .js files
120
const options = {
121
filter: /\.js$/
122
};
123
124
// Function filter - copy only files modified in last 24 hours
125
const options = {
126
filter: function(filePath) {
127
const stats = require('fs').statSync(filePath);
128
const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
129
return stats.mtime.getTime() > dayAgo;
130
}
131
};
132
```
133
134
### Stream Transforms
135
136
Apply streaming transformations during the copy process.
137
138
```javascript { .api }
139
/**
140
* Stream transformation function
141
* @typedef {function} TransformFunction
142
* @param {ReadableStream} readStream - Source file read stream
143
* @param {WritableStream} writeStream - Destination file write stream
144
* @param {object} file - File metadata object with name, mode, mtime, atime
145
*/
146
options.transform;
147
```
148
149
**Usage Example:**
150
151
```javascript
152
const options = {
153
transform: function(readStream, writeStream, file) {
154
if (file.name.endsWith('.txt')) {
155
// Transform text files to uppercase
156
readStream
157
.pipe(require('stream').Transform({
158
transform(chunk, encoding, callback) {
159
callback(null, chunk.toString().toUpperCase());
160
}
161
}))
162
.pipe(writeStream);
163
} else {
164
// Copy other files normally
165
readStream.pipe(writeStream);
166
}
167
}
168
};
169
```
170
171
### File Overwrite Control
172
173
Control whether to overwrite existing destination files.
174
175
```javascript { .api }
176
/**
177
* Whether to overwrite existing destination files
178
* @typedef {boolean} ClobberOption
179
* @default true
180
*/
181
options.clobber;
182
```
183
184
### Symbolic Link Handling
185
186
Control how symbolic links are processed during copying.
187
188
```javascript { .api }
189
/**
190
* Whether to follow symbolic links
191
* @typedef {boolean} DereferenceOption
192
* @default false
193
*/
194
options.dereference;
195
```
196
197
### Concurrency Control
198
199
Set the maximum number of concurrent file system operations.
200
201
```javascript { .api }
202
/**
203
* Concurrency limit for file system operations
204
* @typedef {number} LimitOption
205
* @default 16
206
* @min 1
207
* @max 512
208
*/
209
options.limit;
210
```
211
212
### Error Handling
213
214
Control error handling behavior and error output destination.
215
216
```javascript { .api }
217
/**
218
* Whether to stop on first error
219
* @typedef {boolean} StopOnErrOption
220
* @default false
221
*/
222
options.stopOnErr;
223
224
// Note: The CLI uses --stoponerr but the API uses stopOnErr
225
226
/**
227
* Error output destination
228
* @typedef {string|Stream} ErrorsOption
229
* @property {string} errs - File path for error logging
230
* @property {Stream} errs - Writable stream for error output
231
*/
232
options.errs;
233
```
234
235
### File Path Renaming
236
237
Transform destination file paths during copying.
238
239
```javascript { .api }
240
/**
241
* Function to rename destination paths
242
* @typedef {function} RenameFunction
243
* @param {string} targetPath - Original destination path
244
* @returns {string} - Modified destination path
245
*/
246
options.rename;
247
```
248
249
### Timestamp-based Copying
250
251
Only copy files if source is newer than destination.
252
253
```javascript { .api }
254
/**
255
* Only copy if source file is newer than destination
256
* @typedef {boolean} ModifiedOption
257
* @default false
258
*/
259
options.modified;
260
```
261
262
## Command Line Interface
263
264
The ncp package includes a command-line tool for file copying operations.
265
266
### CLI Usage
267
268
```bash
269
ncp [source] [destination] [--filter=pattern] [--limit=N] [--stoponerr]
270
```
271
272
### CLI Options
273
274
```bash { .api }
275
# Set concurrency limit
276
--limit=16
277
278
# Set filter pattern (RegExp)
279
--filter=\\.js$
280
281
# Stop on first error
282
--stoponerr
283
```
284
285
**CLI Examples:**
286
287
```bash
288
# Basic copy
289
ncp /source/path /dest/path
290
291
# Copy with concurrency limit
292
ncp /source/path /dest/path --limit=32
293
294
# Copy only JavaScript files
295
ncp /source/path /dest/path --filter=\\.js$
296
297
# Copy with error stopping
298
ncp /source/path /dest/path --stoponerr
299
```
300
301
## Error Handling
302
303
### Error Types
304
305
The callback function receives different error types based on the `stopOnError` option:
306
307
```javascript { .api }
308
/**
309
* Single error (when stopOnError is true)
310
* @typedef {Error} SingleError
311
* @property {string} message - Error description
312
* @property {string} stack - Error stack trace
313
*/
314
315
/**
316
* Multiple errors (when stopOnError is false)
317
* @typedef {Error[]} ErrorArray
318
* @property {Error[]} errors - Array of error objects
319
*/
320
```
321
322
### Error Scenarios
323
324
Common error conditions that may occur during copying:
325
326
- File system permission errors
327
- Non-existent source paths
328
- Broken symbolic links (when `dereference: true`)
329
- Destination write failures
330
- Network file system errors
331
332
**Error Handling Examples:**
333
334
```javascript
335
ncp(source, dest, { stopOnErr: false }, function(err) {
336
if (Array.isArray(err)) {
337
console.error('Multiple errors occurred:');
338
err.forEach(function(error) {
339
console.error('- ' + error.message);
340
});
341
} else if (err) {
342
console.error('Single error:', err.message);
343
} else {
344
console.log('Copy completed successfully');
345
}
346
});
347
348
// Error logging to file
349
ncp(source, dest, {
350
stopOnErr: false,
351
errs: './copy-errors.log'
352
}, function(err) {
353
// Errors are also written to copy-errors.log
354
if (err) {
355
console.error('Errors occurred, check copy-errors.log');
356
}
357
});
358
```
359
360
## Advanced Usage Patterns
361
362
### Conditional Copying
363
364
```javascript
365
// Copy only recently modified files
366
ncp(source, dest, {
367
filter: function(filePath) {
368
const stats = require('fs').statSync(filePath);
369
const hourAgo = Date.now() - (60 * 60 * 1000);
370
return stats.mtime.getTime() > hourAgo;
371
},
372
modified: true // Additional timestamp check
373
}, callback);
374
```
375
376
### High-Performance Copying
377
378
```javascript
379
// Optimize for large file operations
380
ncp(source, dest, {
381
limit: 64, // Higher concurrency
382
clobber: true, // Overwrite without checks
383
dereference: false // Don't resolve symlinks
384
}, callback);
385
```
386
387
### Safe Incremental Copying
388
389
```javascript
390
// Safe copying with comprehensive error handling
391
ncp(source, dest, {
392
clobber: false, // Don't overwrite existing files
393
modified: true, // Only copy if newer
394
stopOnErr: false, // Continue on errors
395
errs: process.stderr, // Log errors to stderr
396
filter: function(filePath) {
397
// Skip hidden files and directories
398
return !require('path').basename(filePath).startsWith('.');
399
}
400
}, function(err) {
401
if (Array.isArray(err)) {
402
console.log(`Copy completed with ${err.length} errors`);
403
} else if (err) {
404
console.error('Copy failed:', err.message);
405
} else {
406
console.log('Copy completed successfully');
407
}
408
});
409
```