Initial commit

This commit is contained in:
2024-11-03 17:41:45 +01:00
commit c1640c1754
8043 changed files with 775536 additions and 0 deletions

198
node_modules/@11ty/recursive-copy/README.md generated vendored Normal file
View File

@@ -0,0 +1,198 @@
# `@11ty/recursive-copy`
A temporary fork of [`timkendrick/recursive-copy`](https://github.com/timkendrick/recursive-copy) to satisfy https://github.com/11ty/eleventy/issues/3299 as Eleventy slowly [moves to use Node native API `fs.cp`](https://github.com/11ty/eleventy/issues/3360).
> Simple, flexible file copy utility
## Features
- Recursively copy whole directory hierarchies
- Choose which files are copied by passing a filter function, regular expression or glob
- Rename files dynamically, including changing the output path
- Transform file contents using streams
- Choose whether to overwrite existing files
- Choose whether to copy system files
- Filters out [junk](https://www.npmjs.com/package/junk) files by default
- Uses [graceful-fs](https://www.npmjs.com/package/graceful-fs) and [mkdirp](https://www.npmjs.com/package/mkdirp) to avoid filesystem errors
- Emits start, finish and error events for each file that is processed
- Optional promise-based interface
## Examples
#### Node-style callback interface
```javascript
var copy = require('@11ty/recursive-copy');
copy('src', 'dest', function(error, results) {
if (error) {
console.error('Copy failed: ' + error);
} else {
console.info('Copied ' + results.length + ' files');
}
});
```
#### Promise interface
```javascript
var copy = require('@11ty/recursive-copy');
copy('src', 'dest')
.then(function(results) {
console.info('Copied ' + results.length + ' files');
})
.catch(function(error) {
console.error('Copy failed: ' + error);
});
```
#### ES2015+ usage
```javascript
import copy from '@11ty/recursive-copy';
try {
const results = await copy('src', 'dest');
console.info('Copied ' + results.length + ' files');
} catch (error) {
console.error('Copy failed: ' + error);
}
```
#### Advanced options
```javascript
var copy = require('@11ty/recursive-copy');
var path = require('path');
var through = require('through2');
var options = {
overwrite: true,
expand: true,
dot: true,
junk: true,
filter: [
'**/*',
'!.htpasswd'
],
rename: function(filePath) {
return filePath + '.orig';
},
transform: function(src, dest, stats) {
if (path.extname(src) !== '.txt') { return null; }
return through(function(chunk, enc, done) {
var output = chunk.toString().toUpperCase();
done(null, output);
});
}
};
copy('src', 'dest', options)
.on(copy.events.COPY_FILE_START, function(copyOperation) {
console.info('Copying file ' + copyOperation.src + '...');
})
.on(copy.events.COPY_FILE_COMPLETE, function(copyOperation) {
console.info('Copied to ' + copyOperation.dest);
})
.on(copy.events.ERROR, function(error, copyOperation) {
console.error('Unable to copy ' + copyOperation.dest);
})
.then(function(results) {
console.info(results.length + ' file(s) copied');
})
.catch(function(error) {
return console.error('Copy failed: ' + error);
});
```
## Usage
### `copy(src, dest, [options], [callback])`
Recursively copy files and folders from `src` to `dest`
#### Arguments:
| Name | Type | Required | Default | Description |
| ---- | ---- | -------- | ------- | ----------- |
| `src` | `string` | Yes | N/A | Source file/folder path |
| `dest` | `string` | Yes | N/A | Destination file/folder path |
| `options.overwrite` | `boolean` | No | `false` | Whether to overwrite destination files |
| `options.expand` | `boolean` | No | `false` | Whether to expand symbolic links |
| `options.dot` | `boolean` | No | `false` | Whether to copy files beginning with a `.` |
| `options.junk` | `boolean` | No | `false` | Whether to copy OS junk files (e.g. `.DS_Store`, `Thumbs.db`) |
| `options.filter` | `function`, `RegExp`, `string`, `array` | No | `null` | Filter function / regular expression / glob that determines which files to copy (uses [maximatch](https://www.npmjs.com/package/maximatch)) |
| `options.rename` | `function` | No | `null` | Function that maps source paths to destination paths |
| `options.transform` | `function` | No | `null` | Function that returns a transform stream used to modify file contents |
| `options.results` | `boolean` | No | `true` | Whether to return an array of copy results |
| `options.concurrency` | `number` | No | `255` | Maximum number of simultaneous copy operations |
| `options.debug` | `boolean` | No | `false` | Whether to log debug information |
| `callback` | `function` | No | `null` | Callback, invoked on success/failure |
#### Returns:
`Promise<Array>` Promise, fulfilled with array of copy results:
```json
[
{
"src": "/path/to/src",
"dest": "/path/to/dest",
"stats": <Stats>
},
{
"src": "/path/to/src/file.txt",
"dest": "/path/to/dest/file.txt",
"stats": <Stats>
},
{
"src": "/path/to/src/subfolder",
"dest": "/path/to/dest/subfolder",
"stats": <Stats>
},
{
"src": "/path/to/src/subfolder/nested.txt",
"dest": "/path/to/dest/subfolder/nested.txt",
"stats": <Stats>
}
]
```
## Events
The value returned by the `copy` function implements the `EventEmitter` interface, and emits the following events:
| Event | Handler signature |
| ----- | ----------------- |
| `copy.events.ERROR` | `function(error, ErrorInfo)` |
| `copy.events.COMPLETE` | `function(Array<CopyOperation>)` |
| `copy.events.CREATE_DIRECTORY_START` | `function(CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_DIRECTORY_COMPLETE` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_START` | `function(CopyOperation)` |
| `copy.events.CREATE_SYMLINK_ERROR` | `function(error, CopyOperation)` |
| `copy.events.CREATE_SYMLINK_COMPLETE` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_START` | `function(CopyOperation)` |
| `copy.events.COPY_FILE_ERROR` | `function(error, CopyOperation)` |
| `copy.events.COPY_FILE_COMPLETE` | `function(CopyOperation)` |
...where the types referred to in the handler signature are as follows:
### `ErrorInfo`
| Property | Type | Description |
| -------- | ---- | ----------- |
| `src` | `string` | Source path of the file/folder/symlink that failed to copy |
| `dest` | `string` | Destination path of the file/folder/symlink that failed to copy |
### `CopyOperation`
| Property | Type | Description |
| -------- | ---- | ----------- |
| `src` | `string` | Source path of the relevant file/folder/symlink |
| `dest` | `string` | Destination path of the relevant file/folder/symlink |
| `stats ` | `fs.Stats` | Stats for the relevant file/folder/symlink |

117
node_modules/@11ty/recursive-copy/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,117 @@
import { Stats } from 'fs';
import { Stream } from 'stream';
interface Options {
/**
* Whether to overwrite destination files.
*/
overwrite?: boolean;
/**
* Whether to expand symbolic links.
*/
expand?: boolean;
/**
* Whether to copy files beginning with a `.`
*/
dot?: boolean;
/**
* Whether to copy OS junk files (e.g. `.DS_Store`, `Thumbs.db`).
*/
junk?: boolean;
/**
* Filter function / regular expression / glob that determines which files to copy (uses maximatch).
*/
filter?: string | string[] | RegExp | ((path: string) => boolean);
/**
* Function that maps source paths to destination paths.
*/
rename?: (path: string) => string;
/**
* Function that returns a transform stream used to modify file contents.
*/
transform?: (src: string, dest: string, stats: Stats) => Stream | null | undefined;
/**
* Whether to return an array of copy results.
*
* Defaults to true.
*/
results?: boolean;
/**
* Maximum number of simultaneous copy operations.
*
* Defaults to 255.
*/
concurrency?: number;
/**
* Whether to log debug information.
*/
debug?: boolean;
}
interface CopyFn {
(
source: string,
dest: string,
options?: Options,
): WithCopyEvents<Promise<Array<CopyOperation>>>;
(
source: string,
dest: string,
callback: (error: Error | null, results?: Array<CopyOperation>) => void,
): WithCopyEvents<{}>;
events: {
ERROR: CopyEventType.ERROR;
COMPLETE: CopyEventType.COMPLETE;
CREATE_DIRECTORY_START: CopyEventType.CREATE_DIRECTORY_START;
CREATE_DIRECTORY_ERROR: CopyEventType.CREATE_DIRECTORY_ERROR;
CREATE_DIRECTORY_COMPLETE: CopyEventType.CREATE_DIRECTORY_COMPLETE;
CREATE_SYMLINK_START: CopyEventType.CREATE_SYMLINK_START;
CREATE_SYMLINK_ERROR: CopyEventType.CREATE_SYMLINK_ERROR;
CREATE_SYMLINK_COMPLETE: CopyEventType.CREATE_SYMLINK_COMPLETE;
COPY_FILE_START: CopyEventType.COPY_FILE_START;
COPY_FILE_ERROR: CopyEventType.COPY_FILE_ERROR;
COPY_FILE_COMPLETE: CopyEventType.COPY_FILE_COMPLETE;
};
}
declare const copy: CopyFn;
export default copy;
export interface CopyErrorInfo {
src: string;
dest: string;
}
export interface CopyOperation {
src: string;
dest: string;
stats: Stats;
}
type WithCopyEvents<T> = T & {
on(event: CopyEventType.ERROR, callback: (error: Error, info: CopyErrorInfo) => void): WithCopyEvents<T>;
on(event: CopyEventType.COMPLETE, callback: (info: Array<CopyOperation>) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_DIRECTORY_START, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_DIRECTORY_ERROR, callback: (error: Error, info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_DIRECTORY_COMPLETE, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_SYMLINK_START, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_SYMLINK_ERROR, callback: (error: Error, info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.CREATE_SYMLINK_COMPLETE, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.COPY_FILE_START, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.COPY_FILE_ERROR, callback: (error: Error, info: CopyOperation) => void): WithCopyEvents<T>;
on(event: CopyEventType.COPY_FILE_COMPLETE, callback: (info: CopyOperation) => void): WithCopyEvents<T>;
}
export enum CopyEventType {
ERROR = 'error',
COMPLETE = 'complete',
CREATE_DIRECTORY_START = 'createDirectoryStart',
CREATE_DIRECTORY_ERROR = 'createDirectoryError',
CREATE_DIRECTORY_COMPLETE = 'createDirectoryComplete',
CREATE_SYMLINK_START = 'createSymlinkStart',
CREATE_SYMLINK_ERROR = 'createSymlinkError',
CREATE_SYMLINK_COMPLETE = 'createSymlinkComplete',
COPY_FILE_START = 'copyFileStart',
COPY_FILE_ERROR = 'copyFileError',
COPY_FILE_COMPLETE = 'copyFileComplete',
}

3
node_modules/@11ty/recursive-copy/index.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
'use strict';
module.exports = require('./lib/copy');

422
node_modules/@11ty/recursive-copy/lib/copy.js generated vendored Normal file
View File

@@ -0,0 +1,422 @@
'use strict';
var Promise = global.Promise || require('promise');
var fs = require('graceful-fs');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var pify = require('pify');
var mkdirp = require('mkdirp').mkdirp;
var rimraf = require('rimraf').rimraf;
var junk = require('junk');
var errno = require('errno');
var maximatch = require('maximatch');
var slash = require('slash');
var CopyError = errno.custom.createError('CopyError');
var EVENT_ERROR = 'error';
var EVENT_COMPLETE = 'complete';
var EVENT_CREATE_DIRECTORY_START = 'createDirectoryStart';
var EVENT_CREATE_DIRECTORY_ERROR = 'createDirectoryError';
var EVENT_CREATE_DIRECTORY_COMPLETE = 'createDirectoryComplete';
var EVENT_CREATE_SYMLINK_START = 'createSymlinkStart';
var EVENT_CREATE_SYMLINK_ERROR = 'createSymlinkError';
var EVENT_CREATE_SYMLINK_COMPLETE = 'createSymlinkComplete';
var EVENT_COPY_FILE_START = 'copyFileStart';
var EVENT_COPY_FILE_ERROR = 'copyFileError';
var EVENT_COPY_FILE_COMPLETE = 'copyFileComplete';
var mkdir = mkdirp;
var stat = pify(fs.stat, Promise);
var lstat = pify(fs.lstat, Promise);
var readlink = pify(fs.readlink, Promise);
var symlink = pify(fs.symlink, Promise);
var readdir = pify(fs.readdir, Promise);
var remove = rimraf;
module.exports = function(src, dest, options, callback) {
if ((arguments.length === 3) && (typeof options === 'function')) {
callback = options;
options = undefined;
}
options = options || {};
var parentDirectory = path.dirname(dest);
var shouldExpandSymlinks = Boolean(options.expand);
var emitter;
var hasFinished = false;
if (options.debug) { log('Ensuring output directory exists…'); }
var promise = ensureDirectoryExists(parentDirectory)
.then(function() {
if (options.debug) { log('Fetching source paths…'); }
return getFilePaths(src, shouldExpandSymlinks)
})
.then(function(filePaths) {
if (options.debug) { log('Filtering source paths…'); }
var relativePaths = filePaths.map(function(filePath) {
return path.relative(src, filePath);
});
var filteredPaths = getFilteredPaths(relativePaths, options.filter, {
dot: options.dot,
junk: options.junk
});
return filteredPaths.map(function(relativePath) {
var inputPath = relativePath;
var outputPath = options.rename ? options.rename(inputPath) : inputPath;
return {
src: path.join(src, inputPath),
dest: path.join(dest, outputPath)
};
})
})
.then(function(operations) {
if (options.debug) { log('Copying files…'); }
var hasFinishedGetter = function() { return hasFinished; };
var emitEvent = function() { emitter.emit.apply(emitter, arguments); };
return batch(operations, function(operation) {
return copy(operation.src, operation.dest, hasFinishedGetter, emitEvent, options);
}, {
results: options.results !== false,
concurrency: options.concurrency || 255
});
})
.catch(function(error) {
if (options.debug) { log('Copy failed'); }
if (error instanceof CopyError) {
emitter.emit(EVENT_ERROR, error.error, error.data);
throw error.error;
} else {
throw error;
}
})
.then(function(results) {
if (options.debug) { log('Copy complete'); }
emitter.emit(EVENT_COMPLETE, results);
return results;
})
.then(function(results) {
hasFinished = true;
return results;
})
.catch(function(error) {
hasFinished = true;
throw error;
});
if (typeof callback === 'function') {
promise.then(function(results) {
callback(null, results);
})
.catch(function(error) {
callback(error);
});
emitter = new EventEmitter();
} else {
emitter = withEventEmitter(promise);
}
return emitter;
};
function batch(inputs, iteratee, options) {
var results = options.results ? [] : undefined;
if (inputs.length === 0) { return Promise.resolve(results); }
return new Promise(function(resolve, reject) {
var currentIndex = -1;
var activeWorkers = 0;
while (currentIndex < Math.min(inputs.length, options.concurrency) - 1) {
startWorker(inputs[++currentIndex]);
}
function startWorker(input) {
++activeWorkers;
iteratee(input).then(function(result) {
--activeWorkers;
if (results) { results.push(result); }
if (currentIndex < inputs.length - 1) {
startWorker(inputs[++currentIndex]);
} else if (activeWorkers === 0) {
resolve(results);
}
}).catch(reject);
}
});
}
function getFilePaths(src, shouldExpandSymlinks) {
return (shouldExpandSymlinks ? stat : lstat)(src)
.then(function(stats) {
if (stats.isDirectory()) {
return getFileListing(src, shouldExpandSymlinks)
.then(function(filenames) {
return [src].concat(filenames);
});
} else {
return [src];
}
});
}
function getFilteredPaths(paths, filter, options) {
var useDotFilter = !options.dot;
var useJunkFilter = !options.junk;
if (!filter && !useDotFilter && !useJunkFilter) { return paths; }
return paths.filter(function(path) {
return (!useDotFilter || dotFilter(path)) && (!useJunkFilter || junkFilter(path)) && (!filter || (maximatch(slash(path), filter, options).length > 0));
});
}
function dotFilter(relativePath) {
var filename = path.basename(relativePath);
return filename.charAt(0) !== '.';
}
function junkFilter(relativePath) {
var filename = path.basename(relativePath);
return !junk.is(filename);
}
function ensureDirectoryExists(path) {
return mkdir(path);
}
function getFileListing(srcPath, shouldExpandSymlinks) {
return readdir(srcPath)
.then(function(filenames) {
return Promise.all(
filenames.map(function(filename) {
var filePath = path.join(srcPath, filename);
return (shouldExpandSymlinks ? stat : lstat)(filePath)
.then(function(stats) {
if (stats.isDirectory()) {
return getFileListing(filePath, shouldExpandSymlinks)
.then(function(childPaths) {
return [filePath].concat(childPaths);
});
} else {
return [filePath];
}
});
})
)
.then(function mergeArrays(arrays) {
return Array.prototype.concat.apply([], arrays);
});
});
}
function copy(srcPath, destPath, hasFinished, emitEvent, options) {
if (options.debug) { log('Preparing to copy ' + srcPath + '…'); }
return prepareForCopy(srcPath, destPath, options)
.then(function(stats) {
if (options.debug) { log('Copying ' + srcPath + '…'); }
var copyFunction = getCopyFunction(stats, hasFinished, emitEvent);
return copyFunction(srcPath, destPath, stats, options);
})
.catch(function(error) {
if (error instanceof CopyError) {
throw error;
}
var copyError = new CopyError(error.message);
copyError.error = error;
copyError.data = {
src: srcPath,
dest: destPath
};
throw copyError;
})
.then(function(result) {
if (options.debug) { log('Copied ' + srcPath); }
return result;
});
}
function prepareForCopy(srcPath, destPath, options) {
var shouldExpandSymlinks = Boolean(options.expand);
var shouldOverwriteExistingFiles = Boolean(options.overwrite);
return (shouldExpandSymlinks ? stat : lstat)(srcPath)
.then(function(stats) {
return ensureDestinationIsWritable(destPath, stats, shouldOverwriteExistingFiles)
.then(function() {
return stats;
});
});
}
function ensureDestinationIsWritable(destPath, srcStats, shouldOverwriteExistingFiles) {
return lstat(destPath)
.catch(function(error) {
var shouldIgnoreError = error.code === 'ENOENT';
if (shouldIgnoreError) { return null; }
throw error;
})
.then(function(destStats) {
var destExists = Boolean(destStats);
if (!destExists) { return true; }
var isMergePossible = srcStats.isDirectory() && destStats.isDirectory();
if (isMergePossible) { return true; }
if (shouldOverwriteExistingFiles) {
return remove(destPath).then(function(paths) {
return true;
});
} else {
throw fsError('EEXIST', destPath);
}
});
}
function getCopyFunction(stats, hasFinished, emitEvent) {
if (stats.isDirectory()) {
return createCopyFunction(copyDirectory, stats, hasFinished, emitEvent, {
startEvent: EVENT_CREATE_DIRECTORY_START,
completeEvent: EVENT_CREATE_DIRECTORY_COMPLETE,
errorEvent: EVENT_CREATE_DIRECTORY_ERROR
});
} else if (stats.isSymbolicLink()) {
return createCopyFunction(copySymlink, stats, hasFinished, emitEvent, {
startEvent: EVENT_CREATE_SYMLINK_START,
completeEvent: EVENT_CREATE_SYMLINK_COMPLETE,
errorEvent: EVENT_CREATE_SYMLINK_ERROR
});
} else {
return createCopyFunction(copyFile, stats, hasFinished, emitEvent, {
startEvent: EVENT_COPY_FILE_START,
completeEvent: EVENT_COPY_FILE_COMPLETE,
errorEvent: EVENT_COPY_FILE_ERROR
});
}
}
function createCopyFunction(fn, stats, hasFinished, emitEvent, events) {
var startEvent = events.startEvent;
var completeEvent = events.completeEvent;
var errorEvent = events.errorEvent;
return function(srcPath, destPath, stats, options) {
// Multiple chains of promises are fired in parallel,
// so when one fails we need to prevent any future
// copy operations
if (hasFinished()) { return Promise.reject(); }
var metadata = {
src: srcPath,
dest: destPath,
stats: stats
};
emitEvent(startEvent, metadata);
var parentDirectory = path.dirname(destPath);
return ensureDirectoryExists(parentDirectory)
.then(function() {
return fn(srcPath, destPath, stats, options);
})
.then(function() {
if (!hasFinished()) { emitEvent(completeEvent, metadata); }
return metadata;
})
.catch(function(error) {
if (!hasFinished()) { emitEvent(errorEvent, error, metadata); }
throw error;
});
};
}
function copyFile(srcPath, destPath, stats, options) {
return new Promise(function(resolve, reject) {
var hasFinished = false;
var read = fs.createReadStream(srcPath);
read.on('error', handleCopyFailed);
var write = fs.createWriteStream(destPath, {
flags: 'w',
mode: stats.mode
});
write.on('error', handleCopyFailed);
write.on('finish', function() {
fs.utimes(destPath, stats.atime, stats.mtime, function() {
hasFinished = true;
resolve();
});
});
var transformStream = null;
if (options.transform) {
transformStream = options.transform(srcPath, destPath, stats);
if (transformStream) {
transformStream.on('error', handleCopyFailed);
read.pipe(transformStream).pipe(write);
} else {
read.pipe(write);
}
} else {
read.pipe(write);
}
function handleCopyFailed(error) {
if (hasFinished) { return; }
hasFinished = true;
if (typeof read.close === 'function') {
read.close();
}
if (typeof write.close === 'function') {
write.close();
}
return reject(error);
}
});
}
function copySymlink(srcPath, destPath, stats, options) {
return readlink(srcPath)
.then(function(link) {
return symlink(link, destPath);
});
}
function copyDirectory(srcPath, destPath, stats, options) {
return mkdir(destPath)
.catch(function(error) {
var shouldIgnoreError = error.code === 'EEXIST';
if (shouldIgnoreError) { return; }
throw error;
});
}
function fsError(code, path) {
var errorType = errno.code[code];
var message = errorType.code + ', ' + errorType.description + ' ' + path;
var error = new Error(message);
error.errno = errorType.errno;
error.code = errorType.code;
error.path = path;
return error;
}
function log(message) {
process.stdout.write(message + '\n');
}
function withEventEmitter(target) {
for (var key in EventEmitter.prototype) {
target[key] = EventEmitter.prototype[key];
}
EventEmitter.call(target);
return target;
}
module.exports.events = {
ERROR: EVENT_ERROR,
COMPLETE: EVENT_COMPLETE,
CREATE_DIRECTORY_START: EVENT_CREATE_DIRECTORY_START,
CREATE_DIRECTORY_ERROR: EVENT_CREATE_DIRECTORY_ERROR,
CREATE_DIRECTORY_COMPLETE: EVENT_CREATE_DIRECTORY_COMPLETE,
CREATE_SYMLINK_START: EVENT_CREATE_SYMLINK_START,
CREATE_SYMLINK_ERROR: EVENT_CREATE_SYMLINK_ERROR,
CREATE_SYMLINK_COMPLETE: EVENT_CREATE_SYMLINK_COMPLETE,
COPY_FILE_START: EVENT_COPY_FILE_START,
COPY_FILE_ERROR: EVENT_COPY_FILE_ERROR,
COPY_FILE_COMPLETE: EVENT_COPY_FILE_COMPLETE
};

71
node_modules/@11ty/recursive-copy/package.json generated vendored Normal file
View File

@@ -0,0 +1,71 @@
{
"name": "@11ty/recursive-copy",
"version": "3.0.0",
"description": "A fork of `recursive-copy`: Simple, flexible file copy utility",
"main": "index.js",
"types": "index.d.ts",
"directories": {
"lib": "lib",
"test": "test"
},
"files": [
"index.js",
"index.d.ts",
"lib"
],
"scripts": {
"test": "npm run test:lint && npm run test:mocha && if-node-version '>=10' npm run test:typings",
"test:lint": "if-node-version '>=4' eslint index.js test",
"test:mocha": "mocha --reporter spec",
"test:typings": "tsd && echo 'TypeScript definitions are valid'",
"prepublishOnly": "npm run test"
},
"repository": {
"type": "git",
"url": "https://github.com/timkendrick/recursive-copy.git"
},
"keywords": [
"copy",
"recursive",
"file",
"directory",
"folder",
"symlink",
"fs",
"rename",
"filter",
"transform",
"glob",
"regex",
"regexp"
],
"author": "Tim Kendrick <timkendrick@gmail.com>",
"license": "ISC",
"bugs": {
"url": "https://github.com/timkendrick/recursive-copy/issues"
},
"homepage": "https://github.com/timkendrick/recursive-copy",
"dependencies": {
"errno": "^0.1.2",
"graceful-fs": "^4.2.11",
"junk": "^1.0.1",
"maximatch": "^0.1.0",
"mkdirp": "^3.0.1",
"pify": "^2.3.0",
"promise": "^7.0.1",
"rimraf": "^5.0.7",
"slash": "^1.0.0"
},
"devDependencies": {
"@types/node": "^14.6.0",
"chai": "^3.5.0",
"chai-as-promised": "^5.3.0",
"eslint": "^2.9.0",
"if-node-version": "^1.1.1",
"mocha": "^2.4.5",
"read-dir-files": "^0.1.1",
"rewire": "^2.3.3",
"through2": "^2.0.1",
"tsd": "0.12.1"
}
}