Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cpy

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cpy - npm Package Compare versions

Comparing version 7.3.0 to 8.0.0

73

index.d.ts

@@ -25,8 +25,26 @@ import {GlobbyOptions} from 'globby';

```
cpy('foo.js', 'destination', {
rename: basename => `prefix-${basename}`
});
import cpy = require('cpy');
(async () => {
await cpy('foo.js', 'destination', {
rename: basename => `prefix-${basename}`
});
})();
```
*/
readonly rename?: string | ((basename: string) => string);
/**
Number of files being copied concurrently.
@default (os.cpus().length || 1) * 2
*/
readonly concurrency?: number;
/**
Ignore junk files.
@default true
*/
readonly ignoreJunk?: boolean;
}

@@ -64,36 +82,25 @@

declare const cpy: {
/**
Copy files.
/**
Copy files.
@param source - Files to copy.
@param destination - Destination directory.
@param options - Options are passed to [cp-file](https://github.com/sindresorhus/cp-file#options) and [globby](https://github.com/sindresorhus/globby#options).
@param source - Files to copy. If any of the files do not exist, an error will be thrown (does not apply to globs).
@param destination - Destination directory.
@param options - In addition to the options defined here, options are passed to [globby](https://github.com/sindresorhus/globby#options).
@example
```
import cpy = require('cpy');
@example
```
import cpy = require('cpy');
(async () => {
await cpy(['source/*.png', '!source/goat.png'], 'destination');
console.log('Files copied!');
})();
```
*/
(
source: string | ReadonlyArray<string>,
destination: string,
options?: cpy.Options
): Promise<string[]> & cpy.ProgressEmitter;
(async () => {
await cpy(['source/*.png', '!source/goat.png'], 'destination');
console.log('Files copied!');
})();
```
*/
declare function cpy(
source: string | ReadonlyArray<string>,
destination: string,
options?: cpy.Options
): Promise<string[]> & cpy.ProgressEmitter;
// TODO: Remove this for the next major release, refactor the whole definition to:
// declare function cpy(
// source: string | ReadonlyArray<string>,
// destination: string,
// options?: cpy.Options
// ): Promise<void> & cpy.ProgressEmitter;
// export = cpy;
default: typeof cpy;
};
export = cpy;
'use strict';
const EventEmitter = require('events');
const path = require('path');
const os = require('os');
const pAll = require('p-all');
const arrify = require('arrify');
const globby = require('globby');
const isGlob = require('is-glob');
const cpFile = require('cp-file');
const junk = require('junk');
const CpyError = require('./cpy-error');
const preprocessSrcPath = (srcPath, options) => options.cwd ? path.resolve(options.cwd, srcPath) : srcPath;
const defaultOptions = {
ignoreJunk: true
};
const preprocessDestPath = (srcPath, dest, options) => {
let basename = path.basename(srcPath);
const dirname = path.dirname(srcPath);
const preprocessSourcePath = (source, options) => options.cwd ? path.resolve(options.cwd, source) : source;
const preprocessDestinationPath = (source, destination, options) => {
let basename = path.basename(source);
const dirname = path.dirname(source);
if (typeof options.rename === 'string') {

@@ -22,80 +30,94 @@ basename = options.rename;

if (options.cwd) {
dest = path.resolve(options.cwd, dest);
destination = path.resolve(options.cwd, destination);
}
if (options.parents) {
return path.join(dest, dirname, basename);
return path.join(destination, dirname, basename);
}
return path.join(dest, basename);
return path.join(destination, basename);
};
const cpy = (src, dest, options = {}) => {
src = arrify(src);
module.exports = (source, destination, {
concurrency = (os.cpus().length || 1) * 2,
...options
} = {}) => {
const progressEmitter = new EventEmitter();
if (src.length === 0 || !dest) {
const promise = Promise.reject(new CpyError('`files` and `destination` required'));
promise.on = (...args) => {
progressEmitter.on(...args);
return promise;
};
options = {
...defaultOptions,
...options
};
return promise;
}
const promise = (async () => {
source = arrify(source);
const copyStatus = new Map();
let completedFiles = 0;
let completedSize = 0;
if (source.length === 0 || !destination) {
throw new CpyError('`source` and `destination` required');
}
const promise = globby(src, options)
.catch(error => {
throw new CpyError(`Cannot glob \`${src}\`: ${error.message}`, error);
})
.then(files => {
if (files.length === 0) {
progressEmitter.emit('progress', {
totalFiles: 0,
percent: 1,
completedFiles: 0,
completedSize: 0
});
const copyStatus = new Map();
let completedFiles = 0;
let completedSize = 0;
let files;
try {
files = await globby(source, options);
if (options.ignoreJunk) {
files = files.filter(file => junk.not(path.basename(file)));
}
} catch (error) {
throw new CpyError(`Cannot glob \`${source}\`: ${error.message}`, error);
}
return Promise.all(files.map(srcPath => {
const from = preprocessSrcPath(srcPath, options);
const to = preprocessDestPath(srcPath, dest, options);
const sourcePaths = source.filter(value => !isGlob(value));
return cpFile(from, to, options)
.on('progress', event => {
const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0};
if (files.length === 0 || (sourcePaths.length > 0 && !sourcePaths.every(value => files.includes(value)))) {
throw new CpyError(`Cannot copy \`${source}\`: the file doesn't exist`);
}
if (fileStatus.written !== event.written || fileStatus.percent !== event.percent) {
completedSize -= fileStatus.written;
completedSize += event.written;
const fileProgressHandler = event => {
const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0};
if (event.percent === 1 && fileStatus.percent !== 1) {
completedFiles++;
}
if (fileStatus.written !== event.written || fileStatus.percent !== event.percent) {
completedSize -= fileStatus.written;
completedSize += event.written;
copyStatus.set(event.src, {written: event.written, percent: event.percent});
if (event.percent === 1 && fileStatus.percent !== 1) {
completedFiles++;
}
progressEmitter.emit('progress', {
totalFiles: files.length,
percent: completedFiles / files.length,
completedFiles,
completedSize
});
}
})
.then(() => to)
.catch(error => {
throw new CpyError(`Cannot copy from \`${from}\` to \`${to}\`: ${error.message}`, error);
});
}));
});
copyStatus.set(event.src, {
written: event.written,
percent: event.percent
});
promise.on = (...args) => {
progressEmitter.on(...args);
progressEmitter.emit('progress', {
totalFiles: files.length,
percent: completedFiles / files.length,
completedFiles,
completedSize
});
}
};
return pAll(files.map(sourcePath => {
return async () => {
const from = preprocessSourcePath(sourcePath, options);
const to = preprocessDestinationPath(sourcePath, destination, options);
try {
await cpFile(from, to, options).on('progress', fileProgressHandler);
} catch (error) {
throw new CpyError(`Cannot copy from \`${from}\` to \`${to}\`: ${error.message}`, error);
}
return to;
};
}), {concurrency});
})();
promise.on = (...arguments_) => {
progressEmitter.on(...arguments_);
return promise;

@@ -106,5 +128,1 @@ };

};
module.exports = cpy;
// TODO: Remove this for the next major release
module.exports.default = cpy;
{
"name": "cpy",
"version": "7.3.0",
"version": "8.0.0",
"description": "Copy files",
"license": "MIT",
"repository": "sindresorhus/cpy",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {

@@ -13,3 +14,3 @@ "name": "Sindre Sorhus",

"engines": {
"node": ">=6"
"node": ">=8"
},

@@ -40,17 +41,23 @@ "scripts": {

"content",
"contents"
"contents",
"cpx",
"directory",
"directories"
],
"dependencies": {
"arrify": "^1.0.1",
"cp-file": "^6.1.0",
"arrify": "^2.0.1",
"cp-file": "^7.0.0",
"globby": "^9.2.0",
"nested-error-stacks": "^2.1.0"
"is-glob": "^4.0.1",
"junk": "^3.1.0",
"nested-error-stacks": "^2.1.0",
"p-all": "^2.1.0"
},
"devDependencies": {
"ava": "^1.4.1",
"rimraf": "^2.6.3",
"tempfile": "^2.0.0",
"tsd": "^0.7.2",
"xo": "^0.24.0"
"ava": "^2.1.0",
"rimraf": "^3.0.0",
"tempfile": "^3.0.0",
"tsd": "^0.11.0",
"xo": "^0.25.3"
}
}

@@ -5,3 +5,2 @@ # cpy [![Build Status](https://travis-ci.org/sindresorhus/cpy.svg?branch=master)](https://travis-ci.org/sindresorhus/cpy)

## Why

@@ -15,3 +14,2 @@

## Install

@@ -23,3 +21,2 @@

## Usage

@@ -36,3 +33,2 @@

## API

@@ -50,2 +46,4 @@

If any of the files do not exist, an error will be thrown (does not apply to globs).
#### destination

@@ -67,3 +65,3 @@

Type: `string`<br>
Type: `string`\
Default: `process.cwd()`

@@ -75,3 +73,3 @@

Type: `boolean`<br>
Type: `boolean`\
Default: `true`

@@ -83,3 +81,3 @@

Type: `boolean`<br>
Type: `boolean`\
Default: `false`

@@ -96,8 +94,25 @@

```js
cpy('foo.js', 'destination', {
rename: basename => `prefix-${basename}`
});
const cpy = require('cpy');
(async () => {
await cpy('foo.js', 'destination', {
rename: basename => `prefix-${basename}`
});
})();
```
##### concurrency
Type: `number`\
Default: `(os.cpus().length || 1) * 2`
Number of files being copied concurrently.
##### ignoreJunk
Type: `boolean`\
Default: `true`
Ignores [junk](https://github.com/sindresorhus/junk) files.
## Progress reporting

@@ -117,3 +132,4 @@

totalFiles: number,
completedSize: number
completedSize: number,
percent: number
}

@@ -135,3 +151,2 @@ ```

## Related

@@ -138,0 +153,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc