nav tabs on admin dashboard
This commit is contained in:
-8
@@ -1,8 +0,0 @@
|
||||
.nyc_output/
|
||||
coverage/
|
||||
test/
|
||||
.travis.yml
|
||||
appveyor.yml
|
||||
lib/**/__tests__/
|
||||
test/readme.md
|
||||
test.js
|
||||
+81
@@ -1,3 +1,84 @@
|
||||
7.0.1 / 2018-11-07
|
||||
------------------
|
||||
|
||||
- Fix `removeSync()` on Windows, in some cases, it would error out with `ENOTEMPTY` ([#646](https://github.com/jprichardson/node-fs-extra/pull/646))
|
||||
- Document `mode` option for `ensureDir*()` ([#587](https://github.com/jprichardson/node-fs-extra/pull/587))
|
||||
- Don't include documentation files in npm package tarball ([#642](https://github.com/jprichardson/node-fs-extra/issues/642), [#643](https://github.com/jprichardson/node-fs-extra/pull/643))
|
||||
|
||||
7.0.0 / 2018-07-16
|
||||
------------------
|
||||
|
||||
- **BREAKING:** Refine `copy*()` handling of symlinks to properly detect symlinks that point to the same file. ([#582](https://github.com/jprichardson/node-fs-extra/pull/582))
|
||||
- Fix bug with copying write-protected directories ([#600](https://github.com/jprichardson/node-fs-extra/pull/600))
|
||||
- Universalify `fs.lchmod()` ([#596](https://github.com/jprichardson/node-fs-extra/pull/596))
|
||||
- Add `engines` field to `package.json` ([#580](https://github.com/jprichardson/node-fs-extra/pull/580))
|
||||
|
||||
6.0.1 / 2018-05-09
|
||||
------------------
|
||||
|
||||
- Fix `fs.promises` `ExperimentalWarning` on Node v10.1.0 ([#578](https://github.com/jprichardson/node-fs-extra/pull/578))
|
||||
|
||||
6.0.0 / 2018-05-01
|
||||
------------------
|
||||
|
||||
- Drop support for Node.js versions 4, 5, & 7 ([#564](https://github.com/jprichardson/node-fs-extra/pull/564))
|
||||
- Rewrite `move` to use `fs.rename` where possible ([#549](https://github.com/jprichardson/node-fs-extra/pull/549))
|
||||
- Don't convert relative paths to absolute paths for `filter` ([#554](https://github.com/jprichardson/node-fs-extra/pull/554))
|
||||
- `copy*`'s behavior when `preserveTimestamps` is `false` has been OS-dependent since 5.0.0, but that's now explicitly noted in the docs ([#563](https://github.com/jprichardson/node-fs-extra/pull/563))
|
||||
- Fix subdirectory detection for `copy*` & `move*` ([#541](https://github.com/jprichardson/node-fs-extra/pull/541))
|
||||
- Handle case-insensitive paths correctly in `copy*` ([#568](https://github.com/jprichardson/node-fs-extra/pull/568))
|
||||
|
||||
5.0.0 / 2017-12-11
|
||||
------------------
|
||||
|
||||
Significant refactor of `copy()` & `copySync()`, including breaking changes. No changes to other functions in this release.
|
||||
|
||||
Huge thanks to **[@manidlou](https://github.com/manidlou)** for doing most of the work on this release.
|
||||
|
||||
- The `filter` option can no longer be a RegExp (must be a function). This was deprecated since fs-extra v1.0.0. [#512](https://github.com/jprichardson/node-fs-extra/pull/512)
|
||||
- `copy()`'s `filter` option can now be a function that returns a Promise. [#518](https://github.com/jprichardson/node-fs-extra/pull/518)
|
||||
- `copy()` & `copySync()` now use `fs.copyFile()`/`fs.copyFileSync()` in environments that support it (currently Node 8.5.0+). Older Node versions still get the old implementation. [#505](https://github.com/jprichardson/node-fs-extra/pull/505)
|
||||
- Don't allow copying a directory into itself. [#83](https://github.com/jprichardson/node-fs-extra/issues/83)
|
||||
- Handle copying between identical files. [#198](https://github.com/jprichardson/node-fs-extra/issues/198)
|
||||
- Error out when copying an empty folder to a path that already exists. [#464](https://github.com/jprichardson/node-fs-extra/issues/464)
|
||||
- Don't create `dest`'s parent if the `filter` function aborts the `copy()` operation. [#517](https://github.com/jprichardson/node-fs-extra/pull/517)
|
||||
- Fix `writeStream` not being closed if there was an error in `copy()`. [#516](https://github.com/jprichardson/node-fs-extra/pull/516)
|
||||
|
||||
4.0.3 / 2017-12-05
|
||||
------------------
|
||||
|
||||
- Fix wrong `chmod` values in `fs.remove()` [#501](https://github.com/jprichardson/node-fs-extra/pull/501)
|
||||
- Fix `TypeError` on systems that don't have some `fs` operations like `lchown` [#520](https://github.com/jprichardson/node-fs-extra/pull/520)
|
||||
|
||||
4.0.2 / 2017-09-12
|
||||
------------------
|
||||
|
||||
- Added `EOL` option to `writeJson*` & `outputJson*` (via upgrade to jsonfile v4)
|
||||
- Added promise support to [`fs.copyFile()`](https://nodejs.org/api/fs.html#fs_fs_copyfile_src_dest_flags_callback) in Node 8.5+
|
||||
- Added `.js` extension to `main` field in `package.json` for better tooling compatibility. [#485](https://github.com/jprichardson/node-fs-extra/pull/485)
|
||||
|
||||
4.0.1 / 2017-07-31
|
||||
------------------
|
||||
|
||||
### Fixed
|
||||
|
||||
- Previously, `ensureFile()` & `ensureFileSync()` would do nothing if the path was a directory. Now, they error out for consistency with `ensureDir()`. [#465](https://github.com/jprichardson/node-fs-extra/issues/465), [#466](https://github.com/jprichardson/node-fs-extra/pull/466), [#470](https://github.com/jprichardson/node-fs-extra/issues/470)
|
||||
|
||||
4.0.0 / 2017-07-14
|
||||
------------------
|
||||
|
||||
### Changed
|
||||
|
||||
- **BREAKING:** The promisified versions of `fs.read()` & `fs.write()` now return objects. See [the docs](docs/fs-read-write.md) for details. [#436](https://github.com/jprichardson/node-fs-extra/issues/436), [#449](https://github.com/jprichardson/node-fs-extra/pull/449)
|
||||
- `fs.move()` now errors out when destination is a subdirectory of source. [#458](https://github.com/jprichardson/node-fs-extra/pull/458)
|
||||
- Applied upstream fixes from `rimraf` to `fs.remove()` & `fs.removeSync()`. [#459](https://github.com/jprichardson/node-fs-extra/pull/459)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Got `fs.outputJSONSync()` working again; it was broken due to refactoring. [#428](https://github.com/jprichardson/node-fs-extra/pull/428)
|
||||
|
||||
Also clarified the docs in a few places.
|
||||
|
||||
3.0.1 / 2017-05-04
|
||||
------------------
|
||||
|
||||
|
||||
+29
-10
@@ -1,16 +1,15 @@
|
||||
Node.js: fs-extra
|
||||
=================
|
||||
|
||||
`fs-extra` adds file system methods that aren't included in the native `fs` module and adds promise support to the `fs` methods. It should be a drop in replacement for `fs`.
|
||||
`fs-extra` adds file system methods that aren't included in the native `fs` module and adds promise support to the `fs` methods. It also uses [`graceful-fs`](https://github.com/isaacs/node-graceful-fs) to prevent `EMFILE` errors. It should be a drop in replacement for `fs`.
|
||||
|
||||
[](https://www.npmjs.org/package/fs-extra)
|
||||
[](http://travis-ci.org/jprichardson/node-fs-extra)
|
||||
[](https://www.npmjs.org/package/fs-extra)
|
||||
[](https://github.com/jprichardson/node-fs-extra/blob/master/LICENSE)
|
||||
[](http://travis-ci.org/jprichardson/node-fs-extra)
|
||||
[](https://ci.appveyor.com/project/jprichardson/node-fs-extra/branch/master)
|
||||
[](https://www.npmjs.org/package/fs-extra)
|
||||
[](https://coveralls.io/r/jprichardson/node-fs-extra)
|
||||
|
||||
<a href="https://github.com/feross/standard"><img src="https://cdn.rawgit.com/feross/standard/master/sticker.svg" alt="Standard JavaScript" width="100"></a>
|
||||
|
||||
[](https://coveralls.io/github/jprichardson/node-fs-extra)
|
||||
[](https://standardjs.com)
|
||||
|
||||
Why?
|
||||
----
|
||||
@@ -58,12 +57,14 @@ const fs = require('fs')
|
||||
const fse = require('fs-extra')
|
||||
```
|
||||
|
||||
Sync vs Async
|
||||
Sync vs Async vs Async/Await
|
||||
-------------
|
||||
Most methods are async by default. All async methods will return a promise if the callback isn't passed.
|
||||
|
||||
Sync methods on the other hand will throw if an error occurs.
|
||||
|
||||
Also Async/Await will throw an error if one occurs.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
@@ -87,6 +88,18 @@ try {
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
// Async/Await:
|
||||
async function copyFiles () {
|
||||
try {
|
||||
await fs.copy('/tmp/myfile', '/tmp/mynewfile')
|
||||
console.log('success!')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
copyFiles()
|
||||
```
|
||||
|
||||
|
||||
@@ -101,6 +114,7 @@ Methods
|
||||
- [ensureDir](docs/ensureDir.md)
|
||||
- [ensureLink](docs/ensureLink.md)
|
||||
- [ensureSymlink](docs/ensureSymlink.md)
|
||||
- [mkdirp](docs/ensureDir.md)
|
||||
- [mkdirs](docs/ensureDir.md)
|
||||
- [move](docs/move.md)
|
||||
- [outputFile](docs/outputFile.md)
|
||||
@@ -118,6 +132,7 @@ Methods
|
||||
- [ensureDirSync](docs/ensureDir-sync.md)
|
||||
- [ensureLinkSync](docs/ensureLink-sync.md)
|
||||
- [ensureSymlinkSync](docs/ensureSymlink-sync.md)
|
||||
- [mkdirpSync](docs/ensureDir-sync.md)
|
||||
- [mkdirsSync](docs/ensureDir-sync.md)
|
||||
- [moveSync](docs/move-sync.md)
|
||||
- [outputFileSync](docs/outputFile-sync.md)
|
||||
@@ -128,7 +143,7 @@ Methods
|
||||
- [writeJsonSync](docs/writeJson-sync.md)
|
||||
|
||||
|
||||
**NOTE:** You can still use the native Node.js methods. They are promisified and copied over to `fs-extra`.
|
||||
**NOTE:** You can still use the native Node.js methods. They are promisified and copied over to `fs-extra`. See [notes on `fs.read()` & `fs.write()`](docs/fs-read-write.md)
|
||||
|
||||
### What happened to `walk()` and `walkSync()`?
|
||||
|
||||
@@ -141,16 +156,20 @@ Third Party
|
||||
|
||||
### TypeScript
|
||||
|
||||
If you like TypeScript, you can use `fs-extra` with it: https://github.com/borisyankov/DefinitelyTyped/tree/master/fs-extra
|
||||
If you like TypeScript, you can use `fs-extra` with it: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/fs-extra
|
||||
|
||||
|
||||
### File / Directory Watching
|
||||
|
||||
If you want to watch for changes to files or directories, then you should use [chokidar](https://github.com/paulmillr/chokidar).
|
||||
|
||||
### Obtain Filesystem (Devices, Partitions) Information
|
||||
|
||||
[fs-filesystem](https://github.com/arthurintelligence/node-fs-filesystem) allows you to read the state of the filesystem of the host on which it is run. It returns information about both the devices and the partitions (volumes) of the system.
|
||||
|
||||
### Misc.
|
||||
|
||||
- [fs-extra-debug](https://github.com/jdxcode/fs-extra-debug) - Send your fs-extra calls to [debug](https://npmjs.org/package/debug).
|
||||
- [mfs](https://github.com/cadorn/mfs) - Monitor your fs-extra calls.
|
||||
|
||||
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
# copySync(src, dest, [options])
|
||||
|
||||
Copy a file or directory. The directory can have contents. Like `cp -r`.
|
||||
|
||||
- `src` `<String>`
|
||||
- `dest` `<String>`
|
||||
- `options` `<Object>`
|
||||
- `overwrite` `<boolean>`: overwrite existing file or directory, default is `true`. _Note that the copy operation will silently fail if you set this to `false` and the destination exists._ Use the `errorOnExist` option to change this behavior.
|
||||
- `errorOnExist` `<boolean>`: when `overwrite` is `false` and the destination exists, throw an error. Default is `false`.
|
||||
- `dereference` `<boolean>`: dereference symlinks, default is `false`.
|
||||
- `preserveTimestamps` `<boolean>`: will set last modification and access times to the ones of the original source files, default is `false`.
|
||||
- `filter` `<Function>`: Function to filter copied files. Return `true` to include, `false` to exclude. This can also be a RegExp, however this is deprecated (See [issue #239](https://github.com/jprichardson/node-fs-extra/issues/239) for background).
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
// copy file
|
||||
fs.copySync('/tmp/myfile', '/tmp/mynewfile')
|
||||
|
||||
// copy directory, even if it has subdirectories or files
|
||||
fs.copySync('/tmp/mydir', '/tmp/mynewdir')
|
||||
```
|
||||
|
||||
**Using filter function**
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const filterFunc = (src, dest) => {
|
||||
// your logic here
|
||||
// it will be copied if return true
|
||||
}
|
||||
|
||||
fs.copySync('/tmp/mydir', '/tmp/mynewdir', { filter: filterFunc })
|
||||
```
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
# copy(src, dest, [options, callback])
|
||||
|
||||
Copy a file or directory. The directory can have contents. Like `cp -r`.
|
||||
|
||||
- `src` `<String>`
|
||||
- `dest` `<String>`
|
||||
- `options` `<Object>`
|
||||
- `overwrite` `<boolean>`: overwrite existing file or directory, default is `true`. _Note that the copy operation will silently fail if you set this to `false` and the destination exists._ Use the `errorOnExist` option to change this behavior.
|
||||
- `errorOnExist` `<boolean>`: when `overwrite` is `false` and the destination exists, throw an error. Default is `false`.
|
||||
- `dereference` `<boolean>`: dereference symlinks, default is `false`.
|
||||
- `preserveTimestamps` `<boolean>`: will set last modification and access times to the ones of the original source files, default is `false`.
|
||||
- `filter` `<Function>`: Function to filter copied files. Return `true` to include, `false` to exclude. This can also be a RegExp, however this is deprecated (See [issue #239](https://github.com/jprichardson/node-fs-extra/issues/239) for background).
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.copy('/tmp/myfile', '/tmp/mynewfile', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
}) // copies file
|
||||
|
||||
fs.copy('/tmp/mydir', '/tmp/mynewdir', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
}) // copies directory, even if it has subdirectories or files
|
||||
|
||||
// Promise usage:
|
||||
fs.copy('/tmp/myfile', '/tmp/mynewfile')
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
|
||||
**Using filter function**
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const filterFunc = (src, dest) => {
|
||||
// your logic here
|
||||
// it will be copied if return true
|
||||
}
|
||||
|
||||
fs.copy('/tmp/mydir', '/tmp/mynewdir', { filter: filterFunc }, err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
```
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
# emptyDirSync(dir)
|
||||
|
||||
Ensures that a directory is empty. Deletes directory contents if the directory is not empty. If the directory does not exist, it is created. The directory itself is not deleted.
|
||||
|
||||
**Alias:** `emptydirSync()`
|
||||
|
||||
- `dir` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
// assume this directory has a lot of files and folders
|
||||
fs.emptyDirSync('/tmp/some/dir')
|
||||
```
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
# emptyDir(dir, [callback])
|
||||
|
||||
Ensures that a directory is empty. Deletes directory contents if the directory is not empty. If the directory does not exist, it is created. The directory itself is not deleted.
|
||||
|
||||
**Alias:** `emptydir()`
|
||||
|
||||
- `dir` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
// assume this directory has a lot of files and folders
|
||||
fs.emptyDir('/tmp/some/dir', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
|
||||
// With promises
|
||||
fs.emptyDir('/tmp/some/dir')
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# ensureDirSync(dir)
|
||||
|
||||
Ensures that the directory exists. If the directory structure does not exist, it is created. Like `mkdir -p`.
|
||||
|
||||
**Aliases:** `mkdirsSync()`, `mkdirpSync()`
|
||||
|
||||
- `dir` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const dir = '/tmp/this/path/does/not/exist'
|
||||
fs.ensureDirSync(dir)
|
||||
// dir has now been created, including the directory it is to be placed in
|
||||
```
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
# ensureDir(dir, [callback])
|
||||
|
||||
Ensures that the directory exists. If the directory structure does not exist, it is created. Like `mkdir -p`.
|
||||
|
||||
**Aliases:** `mkdirs()`, `mkdirp()`
|
||||
|
||||
- `dir` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const dir = '/tmp/this/path/does/not/exist'
|
||||
fs.ensureDir(dir, err => {
|
||||
console.log(err) // => null
|
||||
// dir has now been created, including the directory it is to be placed in
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.ensureDir(dir)
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# ensureFileSync(file)
|
||||
|
||||
Ensures that the file exists. If the file that is requested to be created is in directories that do not exist, these directories are created. If the file already exists, it is **NOT MODIFIED**.
|
||||
|
||||
**Alias:** `createFileSync()`
|
||||
|
||||
- `file` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureFileSync(file)
|
||||
// file has now been created, including the directory it is to be placed in
|
||||
```
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
# ensureFile(file, [callback])
|
||||
|
||||
Ensures that the file exists. If the file that is requested to be created is in directories that do not exist, these directories are created. If the file already exists, it is **NOT MODIFIED**.
|
||||
|
||||
**Alias:** `createFile()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureFile(file, err => {
|
||||
console.log(err) // => null
|
||||
// file has now been created, including the directory it is to be placed in
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.ensureFile(file)
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# ensureLinkSync(srcpath, dstpath)
|
||||
|
||||
Ensures that the link exists. If the directory structure does not exist, it is created.
|
||||
|
||||
- `srcpath` `<String>`
|
||||
- `dstpath` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const srcpath = '/tmp/file.txt'
|
||||
const dstpath = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureLinkSync(srcpath, dstpath)
|
||||
// link has now been created, including the directory it is to be placed in
|
||||
```
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
# ensureLink(srcpath, dstpath, [callback])
|
||||
|
||||
Ensures that the link exists. If the directory structure does not exist, it is created.
|
||||
|
||||
- `srcpath` `<String>`
|
||||
- `dstpath` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const srcpath = '/tmp/file.txt'
|
||||
const dstpath = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureLink(srcpath, dstpath, err => {
|
||||
console.log(err) // => null
|
||||
// link has now been created, including the directory it is to be placed in
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.ensureLink(srcpath, dstpath)
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
# ensureSymlinkSync(srcpath, dstpath, [type])
|
||||
|
||||
Ensures that the symlink exists. If the directory structure does not exist, it is created.
|
||||
|
||||
- `srcpath` `<String>`
|
||||
- `dstpath` `<String>`
|
||||
- `type` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const srcpath = '/tmp/file.txt'
|
||||
const dstpath = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureSymlinkSync(srcpath, dstpath)
|
||||
// symlink has now been created, including the directory it is to be placed in
|
||||
```
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
# ensureSymlink(srcpath, dstpath, [type, callback])
|
||||
|
||||
Ensures that the symlink exists. If the directory structure does not exist, it is created.
|
||||
|
||||
- `srcpath` `<String>`
|
||||
- `dstpath` `<String>`
|
||||
- `type` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const srcpath = '/tmp/file.txt'
|
||||
const dstpath = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.ensureSymlink(srcpath, dstpath, err => {
|
||||
console.log(err) // => null
|
||||
// symlink has now been created, including the directory it is to be placed in
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.ensureSymlink(srcpath, dstpath)
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
# moveSync(src, dest, [options])
|
||||
|
||||
Moves a file or directory, even across devices.
|
||||
|
||||
- `src` `<String>`
|
||||
- `dest` `<String>`
|
||||
- `options` `<Object>`
|
||||
- `overwrite` `<boolean>`: overwrite existing file or directory, default is `false`.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.moveSync('/tmp/somefile', '/tmp/does/not/exist/yet/somefile')
|
||||
```
|
||||
|
||||
**Using `overwrite` option**
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.moveSync('/tmp/somedir', '/tmp/may/already/existed/somedir', { overwrite: true })
|
||||
```
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
# move(src, dest, [options, callback])
|
||||
|
||||
Moves a file or directory, even across devices.
|
||||
|
||||
- `src` `<String>`
|
||||
- `dest` `<String>`
|
||||
- `options` `<Object>`
|
||||
- `overwrite` `<boolean>`: overwrite existing file or directory, default is `false`.
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.move('/tmp/somefile', '/tmp/does/not/exist/yet/somefile', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
|
||||
fs.move('/tmp/somefile', '/tmp/does/not/exist/yet/somefile')
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
|
||||
**Using `overwrite` option**
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.move('/tmp/somedir', '/tmp/may/already/existed/somedir', { overwrite: true }, err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
```
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
# outputFileSync(file, data, [options])
|
||||
|
||||
Almost the same as `writeFileSync` (i.e. it [overwrites](http://pages.citebite.com/v2o5n8l2f5reb)), except that if the parent directory does not exist, it's created. `file` must be a file path (a buffer or a file descriptor is not allowed). `options` are what you'd pass to [`fs.writeFileSync()`](https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options).
|
||||
|
||||
- `file` `<String>`
|
||||
- `data` `<String> | <Buffer> | <Uint8Array>`
|
||||
- `options` `<Object> | <String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.outputFileSync(file, 'hello!')
|
||||
|
||||
const data = fs.readFileSync(file, 'utf8')
|
||||
console.log(data) // => hello!
|
||||
```
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
# outputFile(file, data, [options, callback])
|
||||
|
||||
Almost the same as `writeFile` (i.e. it [overwrites](http://pages.citebite.com/v2o5n8l2f5reb)), except that if the parent directory does not exist, it's created. `file` must be a file path (a buffer or a file descriptor is not allowed). `options` are what you'd pass to [`fs.writeFile()`](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback).
|
||||
|
||||
- `file` `<String>`
|
||||
- `data` `<String> | <Buffer> | <Uint8Array>`
|
||||
- `options` `<Object> | <String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
fs.outputFile(file, 'hello!', err => {
|
||||
console.log(err) // => null
|
||||
|
||||
fs.readFile(file, 'utf8', (err, data) => {
|
||||
if (err) return console.error(err)
|
||||
console.log(data) // => hello!
|
||||
})
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.outputFile(file, 'hello!')
|
||||
.then(() => fs.readFile(file, 'utf8'))
|
||||
.then(data => {
|
||||
console.log(data) // => hello!
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
# outputJsonSync(file, object, [options])
|
||||
|
||||
Almost the same as [`writeJsonSync`](writeJson-sync.md), except that if the directory does not exist, it's created.
|
||||
`options` are what you'd pass to [`jsonFile.writeFileSync()`](https://github.com/jprichardson/node-jsonfile#writefilesyncfilename-obj-options).
|
||||
|
||||
**Alias:** `outputJSONSync()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `object` `<Object>`
|
||||
- `options` `<Object>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.json'
|
||||
fs.outputJsonSync(file, {name: 'JP'})
|
||||
|
||||
const data = fs.readJsonSync(file)
|
||||
console.log(data.name) // => JP
|
||||
```
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
# outputJson(file, object, [options, callback])
|
||||
|
||||
Almost the same as [`writeJson`](writeJson.md), except that if the directory does not exist, it's created.
|
||||
`options` are what you'd pass to [`jsonFile.writeFile()`](https://github.com/jprichardson/node-jsonfile#writefilefilename-options-callback).
|
||||
|
||||
**Alias:** `outputJSON()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `object` `<Object>`
|
||||
- `options` `<Object>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.json'
|
||||
fs.outputJson(file, {name: 'JP'}, err => {
|
||||
console.log(err) // => null
|
||||
|
||||
fs.readJson(file, (err, data) => {
|
||||
if (err) return console.error(err)
|
||||
console.log(data.name) // => JP
|
||||
})
|
||||
})
|
||||
|
||||
// With Promises:
|
||||
fs.outputJson(file, {name: 'JP'})
|
||||
.then(() => fs.readJson(file))
|
||||
.then(data => {
|
||||
console.log(data.name) // => JP
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
# pathExistsSync(file)
|
||||
|
||||
An alias for [`fs.existsSync()`](https://nodejs.org/api/fs.html#fs_fs_existssync_path), created for consistency with [`pathExists()`](pathExists.md).
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
# pathExists(file[, callback])
|
||||
|
||||
Test whether or not the given path exists by checking with the file system. Like [`fs.exists`](https://nodejs.org/api/fs.html#fs_fs_exists_path_callback), but with a normal callback signature (err, exists). Uses `fs.access` under the hood.
|
||||
|
||||
- `file` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/this/path/does/not/exist/file.txt'
|
||||
// Promise usage:
|
||||
fs.pathExists(file)
|
||||
.then(exists => console.log(exists)) // => false
|
||||
// Callback usage:
|
||||
fs.pathExists(file, (err, exists) => {
|
||||
console.log(err) // => null
|
||||
console.log(exists) // => false
|
||||
})
|
||||
```
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
# readJsonSync(file, [options])
|
||||
|
||||
Reads a JSON file and then parses it into an object. `options` are the same
|
||||
that you'd pass to [`jsonFile.readFileSync`](https://github.com/jprichardson/node-jsonfile#readfilesyncfilename-options).
|
||||
|
||||
**Alias:** `readJSONSync()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `options` `<Object>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const packageObj = fs.readJsonSync('./package.json')
|
||||
console.log(packageObj.version) // => 2.0.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
`readJsonSync()` can take a `throws` option set to `false` and it won't throw if the JSON is invalid. Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/some-invalid.json'
|
||||
const data = '{not valid JSON'
|
||||
fs.writeFileSync(file, data)
|
||||
|
||||
const obj = fs.readJsonSync(file, { throws: false })
|
||||
console.log(obj) // => null
|
||||
```
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
# readJson(file, [options, callback])
|
||||
|
||||
Reads a JSON file and then parses it into an object. `options` are the same
|
||||
that you'd pass to [`jsonFile.readFile`](https://github.com/jprichardson/node-jsonfile#readfilefilename-options-callback).
|
||||
|
||||
**Alias:** `readJSON()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `options` `<Object>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.readJson('./package.json', (err, packageObj) => {
|
||||
if (err) console.error(err)
|
||||
|
||||
console.log(packageObj.version) // => 0.1.3
|
||||
})
|
||||
|
||||
// Promise Usage
|
||||
fs.readJson('./package.json')
|
||||
.then(packageObj => {
|
||||
console.log(packageObj.version) // => 0.1.3
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
`readJson()` can take a `throws` option set to `false` and it won't throw if the JSON is invalid. Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
const file = '/tmp/some-invalid.json'
|
||||
const data = '{not valid JSON'
|
||||
fs.writeFileSync(file, data)
|
||||
|
||||
fs.readJson(file, { throws: false }, (err, obj) => {
|
||||
if (err) console.error(err)
|
||||
|
||||
console.log(obj) // => null
|
||||
})
|
||||
|
||||
// Promise Usage
|
||||
fs.readJson(file, { throws: false })
|
||||
.then(obj => {
|
||||
console.log(obj) // => null
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err) // Not called
|
||||
})
|
||||
```
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
# removeSync(path)
|
||||
|
||||
Removes a file or directory. The directory can have contents. Like `rm -rf`.
|
||||
|
||||
- `path` `<String>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
// remove file
|
||||
fs.removeSync('/tmp/myfile')
|
||||
|
||||
fs.removeSync('/home/jprichardson') // I just deleted my entire HOME directory.
|
||||
```
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
# remove(path, [callback])
|
||||
|
||||
Removes a file or directory. The directory can have contents. Like `rm -rf`.
|
||||
|
||||
- `path` `<String>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
// remove file
|
||||
fs.remove('/tmp/myfile', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
|
||||
fs.remove('/home/jprichardson', err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!') // I just deleted my entire HOME directory.
|
||||
})
|
||||
|
||||
// Promise Usage
|
||||
fs.remove('/tmp/myfile')
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
# writeJsonSync(file, object, [options])
|
||||
|
||||
Writes an object to a JSON file. `options` are the same that
|
||||
you'd pass to [`jsonFile.writeFileSync()`](https://github.com/jprichardson/node-jsonfile#writefilesyncfilename-obj-options).
|
||||
|
||||
**Alias:** `writeJSONSync()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `object` `<Object>`
|
||||
- `options` `<Object>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.writeJsonSync('./package.json', {name: 'fs-extra'})
|
||||
```
|
||||
---
|
||||
|
||||
**See also:** [`outputJsonSync()`](outputJson-sync.md)
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
# writeJson(file, object, [options, callback])
|
||||
|
||||
Writes an object to a JSON file. `options` are the same that
|
||||
you'd pass to [`jsonFile.writeFile()`](https://github.com/jprichardson/node-jsonfile#writefilefilename-options-callback).
|
||||
|
||||
**Alias:** `writeJSON()`
|
||||
|
||||
- `file` `<String>`
|
||||
- `object` `<Object>`
|
||||
- `options` `<Object>`
|
||||
- `callback` `<Function>`
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
const fs = require('fs-extra')
|
||||
|
||||
fs.writeJson('./package.json', {name: 'fs-extra'}, err => {
|
||||
if (err) return console.error(err)
|
||||
|
||||
console.log('success!')
|
||||
})
|
||||
|
||||
// With Promises
|
||||
fs.writeJson('./package.json', {name: 'fs-extra'})
|
||||
.then(() => {
|
||||
console.log('success!')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**See also:** [`outputJson()`](outputJson.md)
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('graceful-fs')
|
||||
|
||||
const BUF_LENGTH = 64 * 1024
|
||||
const _buff = require('../util/buffer')(BUF_LENGTH)
|
||||
|
||||
function copyFileSync (srcFile, destFile, options) {
|
||||
const overwrite = options.overwrite
|
||||
const errorOnExist = options.errorOnExist
|
||||
const preserveTimestamps = options.preserveTimestamps
|
||||
|
||||
if (fs.existsSync(destFile)) {
|
||||
if (overwrite) {
|
||||
fs.unlinkSync(destFile)
|
||||
} else if (errorOnExist) {
|
||||
throw new Error(`${destFile} already exists`)
|
||||
} else return
|
||||
}
|
||||
|
||||
const fdr = fs.openSync(srcFile, 'r')
|
||||
const stat = fs.fstatSync(fdr)
|
||||
const fdw = fs.openSync(destFile, 'w', stat.mode)
|
||||
let bytesRead = 1
|
||||
let pos = 0
|
||||
|
||||
while (bytesRead > 0) {
|
||||
bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
|
||||
fs.writeSync(fdw, _buff, 0, bytesRead)
|
||||
pos += bytesRead
|
||||
}
|
||||
|
||||
if (preserveTimestamps) {
|
||||
fs.futimesSync(fdw, stat.atime, stat.mtime)
|
||||
}
|
||||
|
||||
fs.closeSync(fdr)
|
||||
fs.closeSync(fdw)
|
||||
}
|
||||
|
||||
module.exports = copyFileSync
|
||||
+175
-44
@@ -2,61 +2,192 @@
|
||||
|
||||
const fs = require('graceful-fs')
|
||||
const path = require('path')
|
||||
const copyFileSync = require('./copy-file-sync')
|
||||
const mkdir = require('../mkdirs')
|
||||
const mkdirpSync = require('../mkdirs').mkdirsSync
|
||||
const utimesSync = require('../util/utimes.js').utimesMillisSync
|
||||
|
||||
function copySync (src, dest, options) {
|
||||
if (typeof options === 'function' || options instanceof RegExp) {
|
||||
options = {filter: options}
|
||||
const notExist = Symbol('notExist')
|
||||
|
||||
function copySync (src, dest, opts) {
|
||||
if (typeof opts === 'function') {
|
||||
opts = {filter: opts}
|
||||
}
|
||||
|
||||
options = options || {}
|
||||
options.recursive = !!options.recursive
|
||||
opts = opts || {}
|
||||
opts.clobber = 'clobber' in opts ? !!opts.clobber : true // default to true for now
|
||||
opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber // overwrite falls back to clobber
|
||||
|
||||
// default to true for now
|
||||
options.clobber = 'clobber' in options ? !!options.clobber : true
|
||||
// overwrite falls back to clobber
|
||||
options.overwrite = 'overwrite' in options ? !!options.overwrite : options.clobber
|
||||
options.dereference = 'dereference' in options ? !!options.dereference : false
|
||||
options.preserveTimestamps = 'preserveTimestamps' in options ? !!options.preserveTimestamps : false
|
||||
|
||||
options.filter = options.filter || function () { return true }
|
||||
|
||||
// Warn about using preserveTimestamps on 32-bit node:
|
||||
if (options.preserveTimestamps && process.arch === 'ia32') {
|
||||
// Warn about using preserveTimestamps on 32-bit node
|
||||
if (opts.preserveTimestamps && process.arch === 'ia32') {
|
||||
console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n
|
||||
see https://github.com/jprichardson/node-fs-extra/issues/269`)
|
||||
}
|
||||
|
||||
const stats = (options.recursive && !options.dereference) ? fs.lstatSync(src) : fs.statSync(src)
|
||||
const destFolder = path.dirname(dest)
|
||||
const destFolderExists = fs.existsSync(destFolder)
|
||||
let performCopy = false
|
||||
const destStat = checkPaths(src, dest)
|
||||
|
||||
if (options.filter instanceof RegExp) {
|
||||
console.warn('Warning: fs-extra: Passing a RegExp filter is deprecated, use a function')
|
||||
performCopy = options.filter.test(src)
|
||||
} else if (typeof options.filter === 'function') performCopy = options.filter(src, dest)
|
||||
if (opts.filter && !opts.filter(src, dest)) return
|
||||
|
||||
if (stats.isFile() && performCopy) {
|
||||
if (!destFolderExists) mkdir.mkdirsSync(destFolder)
|
||||
copyFileSync(src, dest, {
|
||||
overwrite: options.overwrite,
|
||||
errorOnExist: options.errorOnExist,
|
||||
preserveTimestamps: options.preserveTimestamps
|
||||
})
|
||||
} else if (stats.isDirectory() && performCopy) {
|
||||
if (!fs.existsSync(dest)) mkdir.mkdirsSync(dest)
|
||||
const contents = fs.readdirSync(src)
|
||||
contents.forEach(content => {
|
||||
const opts = options
|
||||
opts.recursive = true
|
||||
copySync(path.join(src, content), path.join(dest, content), opts)
|
||||
})
|
||||
} else if (options.recursive && stats.isSymbolicLink() && performCopy) {
|
||||
const srcPath = fs.readlinkSync(src)
|
||||
fs.symlinkSync(srcPath, dest)
|
||||
const destParent = path.dirname(dest)
|
||||
if (!fs.existsSync(destParent)) mkdirpSync(destParent)
|
||||
return startCopy(destStat, src, dest, opts)
|
||||
}
|
||||
|
||||
function startCopy (destStat, src, dest, opts) {
|
||||
if (opts.filter && !opts.filter(src, dest)) return
|
||||
return getStats(destStat, src, dest, opts)
|
||||
}
|
||||
|
||||
function getStats (destStat, src, dest, opts) {
|
||||
const statSync = opts.dereference ? fs.statSync : fs.lstatSync
|
||||
const srcStat = statSync(src)
|
||||
|
||||
if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts)
|
||||
else if (srcStat.isFile() ||
|
||||
srcStat.isCharacterDevice() ||
|
||||
srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts)
|
||||
else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts)
|
||||
}
|
||||
|
||||
function onFile (srcStat, destStat, src, dest, opts) {
|
||||
if (destStat === notExist) return copyFile(srcStat, src, dest, opts)
|
||||
return mayCopyFile(srcStat, src, dest, opts)
|
||||
}
|
||||
|
||||
function mayCopyFile (srcStat, src, dest, opts) {
|
||||
if (opts.overwrite) {
|
||||
fs.unlinkSync(dest)
|
||||
return copyFile(srcStat, src, dest, opts)
|
||||
} else if (opts.errorOnExist) {
|
||||
throw new Error(`'${dest}' already exists`)
|
||||
}
|
||||
}
|
||||
|
||||
function copyFile (srcStat, src, dest, opts) {
|
||||
if (typeof fs.copyFileSync === 'function') {
|
||||
fs.copyFileSync(src, dest)
|
||||
fs.chmodSync(dest, srcStat.mode)
|
||||
if (opts.preserveTimestamps) {
|
||||
return utimesSync(dest, srcStat.atime, srcStat.mtime)
|
||||
}
|
||||
return
|
||||
}
|
||||
return copyFileFallback(srcStat, src, dest, opts)
|
||||
}
|
||||
|
||||
function copyFileFallback (srcStat, src, dest, opts) {
|
||||
const BUF_LENGTH = 64 * 1024
|
||||
const _buff = require('../util/buffer')(BUF_LENGTH)
|
||||
|
||||
const fdr = fs.openSync(src, 'r')
|
||||
const fdw = fs.openSync(dest, 'w', srcStat.mode)
|
||||
let pos = 0
|
||||
|
||||
while (pos < srcStat.size) {
|
||||
const bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
|
||||
fs.writeSync(fdw, _buff, 0, bytesRead)
|
||||
pos += bytesRead
|
||||
}
|
||||
|
||||
if (opts.preserveTimestamps) fs.futimesSync(fdw, srcStat.atime, srcStat.mtime)
|
||||
|
||||
fs.closeSync(fdr)
|
||||
fs.closeSync(fdw)
|
||||
}
|
||||
|
||||
function onDir (srcStat, destStat, src, dest, opts) {
|
||||
if (destStat === notExist) return mkDirAndCopy(srcStat, src, dest, opts)
|
||||
if (destStat && !destStat.isDirectory()) {
|
||||
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)
|
||||
}
|
||||
return copyDir(src, dest, opts)
|
||||
}
|
||||
|
||||
function mkDirAndCopy (srcStat, src, dest, opts) {
|
||||
fs.mkdirSync(dest)
|
||||
copyDir(src, dest, opts)
|
||||
return fs.chmodSync(dest, srcStat.mode)
|
||||
}
|
||||
|
||||
function copyDir (src, dest, opts) {
|
||||
fs.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts))
|
||||
}
|
||||
|
||||
function copyDirItem (item, src, dest, opts) {
|
||||
const srcItem = path.join(src, item)
|
||||
const destItem = path.join(dest, item)
|
||||
const destStat = checkPaths(srcItem, destItem)
|
||||
return startCopy(destStat, srcItem, destItem, opts)
|
||||
}
|
||||
|
||||
function onLink (destStat, src, dest, opts) {
|
||||
let resolvedSrc = fs.readlinkSync(src)
|
||||
|
||||
if (opts.dereference) {
|
||||
resolvedSrc = path.resolve(process.cwd(), resolvedSrc)
|
||||
}
|
||||
|
||||
if (destStat === notExist) {
|
||||
return fs.symlinkSync(resolvedSrc, dest)
|
||||
} else {
|
||||
let resolvedDest
|
||||
try {
|
||||
resolvedDest = fs.readlinkSync(dest)
|
||||
} catch (err) {
|
||||
// dest exists and is a regular file or directory,
|
||||
// Windows may throw UNKNOWN error. If dest already exists,
|
||||
// fs throws error anyway, so no need to guard against it here.
|
||||
if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs.symlinkSync(resolvedSrc, dest)
|
||||
throw err
|
||||
}
|
||||
if (opts.dereference) {
|
||||
resolvedDest = path.resolve(process.cwd(), resolvedDest)
|
||||
}
|
||||
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
|
||||
throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)
|
||||
}
|
||||
|
||||
// prevent copy if src is a subdir of dest since unlinking
|
||||
// dest in this case would result in removing src contents
|
||||
// and therefore a broken symlink would be created.
|
||||
if (fs.statSync(dest).isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
|
||||
throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
|
||||
}
|
||||
return copyLink(resolvedSrc, dest)
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink (resolvedSrc, dest) {
|
||||
fs.unlinkSync(dest)
|
||||
return fs.symlinkSync(resolvedSrc, dest)
|
||||
}
|
||||
|
||||
// return true if dest is a subdir of src, otherwise false.
|
||||
function isSrcSubdir (src, dest) {
|
||||
const srcArray = path.resolve(src).split(path.sep)
|
||||
const destArray = path.resolve(dest).split(path.sep)
|
||||
return srcArray.reduce((acc, current, i) => acc && destArray[i] === current, true)
|
||||
}
|
||||
|
||||
function checkStats (src, dest) {
|
||||
const srcStat = fs.statSync(src)
|
||||
let destStat
|
||||
try {
|
||||
destStat = fs.statSync(dest)
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') return {srcStat, destStat: notExist}
|
||||
throw err
|
||||
}
|
||||
return {srcStat, destStat}
|
||||
}
|
||||
|
||||
function checkPaths (src, dest) {
|
||||
const {srcStat, destStat} = checkStats(src, dest)
|
||||
if (destStat.ino && destStat.ino === srcStat.ino) {
|
||||
throw new Error('Source and destination must not be the same.')
|
||||
}
|
||||
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
|
||||
throw new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`)
|
||||
}
|
||||
return destStat
|
||||
}
|
||||
|
||||
module.exports = copySync
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
copySync: require('./copy-sync')
|
||||
}
|
||||
|
||||
+228
-36
@@ -2,53 +2,245 @@
|
||||
|
||||
const fs = require('graceful-fs')
|
||||
const path = require('path')
|
||||
const ncp = require('./ncp')
|
||||
const mkdir = require('../mkdirs')
|
||||
const mkdirp = require('../mkdirs').mkdirs
|
||||
const pathExists = require('../path-exists').pathExists
|
||||
const utimes = require('../util/utimes').utimesMillis
|
||||
|
||||
function copy (src, dest, options, callback) {
|
||||
if (typeof options === 'function' && !callback) {
|
||||
callback = options
|
||||
options = {}
|
||||
} else if (typeof options === 'function' || options instanceof RegExp) {
|
||||
options = {filter: options}
|
||||
const notExist = Symbol('notExist')
|
||||
|
||||
function copy (src, dest, opts, cb) {
|
||||
if (typeof opts === 'function' && !cb) {
|
||||
cb = opts
|
||||
opts = {}
|
||||
} else if (typeof opts === 'function') {
|
||||
opts = {filter: opts}
|
||||
}
|
||||
callback = callback || function () {}
|
||||
options = options || {}
|
||||
|
||||
// Warn about using preserveTimestamps on 32-bit node:
|
||||
if (options.preserveTimestamps && process.arch === 'ia32') {
|
||||
cb = cb || function () {}
|
||||
opts = opts || {}
|
||||
|
||||
opts.clobber = 'clobber' in opts ? !!opts.clobber : true // default to true for now
|
||||
opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber // overwrite falls back to clobber
|
||||
|
||||
// Warn about using preserveTimestamps on 32-bit node
|
||||
if (opts.preserveTimestamps && process.arch === 'ia32') {
|
||||
console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n
|
||||
see https://github.com/jprichardson/node-fs-extra/issues/269`)
|
||||
}
|
||||
|
||||
// don't allow src and dest to be the same
|
||||
const basePath = process.cwd()
|
||||
const currentPath = path.resolve(basePath, src)
|
||||
const targetPath = path.resolve(basePath, dest)
|
||||
if (currentPath === targetPath) return callback(new Error('Source and destination must not be the same.'))
|
||||
checkPaths(src, dest, (err, destStat) => {
|
||||
if (err) return cb(err)
|
||||
if (opts.filter) return handleFilter(checkParentDir, destStat, src, dest, opts, cb)
|
||||
return checkParentDir(destStat, src, dest, opts, cb)
|
||||
})
|
||||
}
|
||||
|
||||
fs.lstat(src, (err, stats) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
let dir = null
|
||||
if (stats.isDirectory()) {
|
||||
const parts = dest.split(path.sep)
|
||||
parts.pop()
|
||||
dir = parts.join(path.sep)
|
||||
} else {
|
||||
dir = path.dirname(dest)
|
||||
}
|
||||
|
||||
pathExists(dir, (err, dirExists) => {
|
||||
if (err) return callback(err)
|
||||
if (dirExists) return ncp(src, dest, options, callback)
|
||||
mkdir.mkdirs(dir, err => {
|
||||
if (err) return callback(err)
|
||||
ncp(src, dest, options, callback)
|
||||
})
|
||||
function checkParentDir (destStat, src, dest, opts, cb) {
|
||||
const destParent = path.dirname(dest)
|
||||
pathExists(destParent, (err, dirExists) => {
|
||||
if (err) return cb(err)
|
||||
if (dirExists) return startCopy(destStat, src, dest, opts, cb)
|
||||
mkdirp(destParent, err => {
|
||||
if (err) return cb(err)
|
||||
return startCopy(destStat, src, dest, opts, cb)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleFilter (onInclude, destStat, src, dest, opts, cb) {
|
||||
Promise.resolve(opts.filter(src, dest)).then(include => {
|
||||
if (include) {
|
||||
if (destStat) return onInclude(destStat, src, dest, opts, cb)
|
||||
return onInclude(src, dest, opts, cb)
|
||||
}
|
||||
return cb()
|
||||
}, error => cb(error))
|
||||
}
|
||||
|
||||
function startCopy (destStat, src, dest, opts, cb) {
|
||||
if (opts.filter) return handleFilter(getStats, destStat, src, dest, opts, cb)
|
||||
return getStats(destStat, src, dest, opts, cb)
|
||||
}
|
||||
|
||||
function getStats (destStat, src, dest, opts, cb) {
|
||||
const stat = opts.dereference ? fs.stat : fs.lstat
|
||||
stat(src, (err, srcStat) => {
|
||||
if (err) return cb(err)
|
||||
|
||||
if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts, cb)
|
||||
else if (srcStat.isFile() ||
|
||||
srcStat.isCharacterDevice() ||
|
||||
srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts, cb)
|
||||
else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function onFile (srcStat, destStat, src, dest, opts, cb) {
|
||||
if (destStat === notExist) return copyFile(srcStat, src, dest, opts, cb)
|
||||
return mayCopyFile(srcStat, src, dest, opts, cb)
|
||||
}
|
||||
|
||||
function mayCopyFile (srcStat, src, dest, opts, cb) {
|
||||
if (opts.overwrite) {
|
||||
fs.unlink(dest, err => {
|
||||
if (err) return cb(err)
|
||||
return copyFile(srcStat, src, dest, opts, cb)
|
||||
})
|
||||
} else if (opts.errorOnExist) {
|
||||
return cb(new Error(`'${dest}' already exists`))
|
||||
} else return cb()
|
||||
}
|
||||
|
||||
function copyFile (srcStat, src, dest, opts, cb) {
|
||||
if (typeof fs.copyFile === 'function') {
|
||||
return fs.copyFile(src, dest, err => {
|
||||
if (err) return cb(err)
|
||||
return setDestModeAndTimestamps(srcStat, dest, opts, cb)
|
||||
})
|
||||
}
|
||||
return copyFileFallback(srcStat, src, dest, opts, cb)
|
||||
}
|
||||
|
||||
function copyFileFallback (srcStat, src, dest, opts, cb) {
|
||||
const rs = fs.createReadStream(src)
|
||||
rs.on('error', err => cb(err)).once('open', () => {
|
||||
const ws = fs.createWriteStream(dest, { mode: srcStat.mode })
|
||||
ws.on('error', err => cb(err))
|
||||
.on('open', () => rs.pipe(ws))
|
||||
.once('close', () => setDestModeAndTimestamps(srcStat, dest, opts, cb))
|
||||
})
|
||||
}
|
||||
|
||||
function setDestModeAndTimestamps (srcStat, dest, opts, cb) {
|
||||
fs.chmod(dest, srcStat.mode, err => {
|
||||
if (err) return cb(err)
|
||||
if (opts.preserveTimestamps) {
|
||||
return utimes(dest, srcStat.atime, srcStat.mtime, cb)
|
||||
}
|
||||
return cb()
|
||||
})
|
||||
}
|
||||
|
||||
function onDir (srcStat, destStat, src, dest, opts, cb) {
|
||||
if (destStat === notExist) return mkDirAndCopy(srcStat, src, dest, opts, cb)
|
||||
if (destStat && !destStat.isDirectory()) {
|
||||
return cb(new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`))
|
||||
}
|
||||
return copyDir(src, dest, opts, cb)
|
||||
}
|
||||
|
||||
function mkDirAndCopy (srcStat, src, dest, opts, cb) {
|
||||
fs.mkdir(dest, err => {
|
||||
if (err) return cb(err)
|
||||
copyDir(src, dest, opts, err => {
|
||||
if (err) return cb(err)
|
||||
return fs.chmod(dest, srcStat.mode, cb)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function copyDir (src, dest, opts, cb) {
|
||||
fs.readdir(src, (err, items) => {
|
||||
if (err) return cb(err)
|
||||
return copyDirItems(items, src, dest, opts, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function copyDirItems (items, src, dest, opts, cb) {
|
||||
const item = items.pop()
|
||||
if (!item) return cb()
|
||||
return copyDirItem(items, item, src, dest, opts, cb)
|
||||
}
|
||||
|
||||
function copyDirItem (items, item, src, dest, opts, cb) {
|
||||
const srcItem = path.join(src, item)
|
||||
const destItem = path.join(dest, item)
|
||||
checkPaths(srcItem, destItem, (err, destStat) => {
|
||||
if (err) return cb(err)
|
||||
startCopy(destStat, srcItem, destItem, opts, err => {
|
||||
if (err) return cb(err)
|
||||
return copyDirItems(items, src, dest, opts, cb)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function onLink (destStat, src, dest, opts, cb) {
|
||||
fs.readlink(src, (err, resolvedSrc) => {
|
||||
if (err) return cb(err)
|
||||
|
||||
if (opts.dereference) {
|
||||
resolvedSrc = path.resolve(process.cwd(), resolvedSrc)
|
||||
}
|
||||
|
||||
if (destStat === notExist) {
|
||||
return fs.symlink(resolvedSrc, dest, cb)
|
||||
} else {
|
||||
fs.readlink(dest, (err, resolvedDest) => {
|
||||
if (err) {
|
||||
// dest exists and is a regular file or directory,
|
||||
// Windows may throw UNKNOWN error. If dest already exists,
|
||||
// fs throws error anyway, so no need to guard against it here.
|
||||
if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs.symlink(resolvedSrc, dest, cb)
|
||||
return cb(err)
|
||||
}
|
||||
if (opts.dereference) {
|
||||
resolvedDest = path.resolve(process.cwd(), resolvedDest)
|
||||
}
|
||||
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
|
||||
return cb(new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`))
|
||||
}
|
||||
|
||||
// do not copy if src is a subdir of dest since unlinking
|
||||
// dest in this case would result in removing src contents
|
||||
// and therefore a broken symlink would be created.
|
||||
if (destStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
|
||||
return cb(new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`))
|
||||
}
|
||||
return copyLink(resolvedSrc, dest, cb)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function copyLink (resolvedSrc, dest, cb) {
|
||||
fs.unlink(dest, err => {
|
||||
if (err) return cb(err)
|
||||
return fs.symlink(resolvedSrc, dest, cb)
|
||||
})
|
||||
}
|
||||
|
||||
// return true if dest is a subdir of src, otherwise false.
|
||||
function isSrcSubdir (src, dest) {
|
||||
const srcArray = path.resolve(src).split(path.sep)
|
||||
const destArray = path.resolve(dest).split(path.sep)
|
||||
return srcArray.reduce((acc, current, i) => acc && destArray[i] === current, true)
|
||||
}
|
||||
|
||||
function checkStats (src, dest, cb) {
|
||||
fs.stat(src, (err, srcStat) => {
|
||||
if (err) return cb(err)
|
||||
fs.stat(dest, (err, destStat) => {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') return cb(null, {srcStat, destStat: notExist})
|
||||
return cb(err)
|
||||
}
|
||||
return cb(null, {srcStat, destStat})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function checkPaths (src, dest, cb) {
|
||||
checkStats(src, dest, (err, stats) => {
|
||||
if (err) return cb(err)
|
||||
const {srcStat, destStat} = stats
|
||||
if (destStat.ino && destStat.ino === srcStat.ino) {
|
||||
return cb(new Error('Source and destination must not be the same.'))
|
||||
}
|
||||
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
|
||||
return cb(new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`))
|
||||
}
|
||||
return cb(null, destStat)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = copy
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
const u = require('universalify').fromCallback
|
||||
module.exports = {
|
||||
copy: u(require('./copy'))
|
||||
|
||||
-234
@@ -1,234 +0,0 @@
|
||||
// imported from ncp (this is temporary, will rewrite)
|
||||
|
||||
var fs = require('graceful-fs')
|
||||
var path = require('path')
|
||||
var utimes = require('../util/utimes')
|
||||
|
||||
function ncp (source, dest, options, callback) {
|
||||
if (!callback) {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
var basePath = process.cwd()
|
||||
var currentPath = path.resolve(basePath, source)
|
||||
var targetPath = path.resolve(basePath, dest)
|
||||
|
||||
var filter = options.filter
|
||||
var transform = options.transform
|
||||
var overwrite = options.overwrite
|
||||
// If overwrite is undefined, use clobber, otherwise default to true:
|
||||
if (overwrite === undefined) overwrite = options.clobber
|
||||
if (overwrite === undefined) overwrite = true
|
||||
var errorOnExist = options.errorOnExist
|
||||
var dereference = options.dereference
|
||||
var preserveTimestamps = options.preserveTimestamps === true
|
||||
|
||||
var started = 0
|
||||
var finished = 0
|
||||
var running = 0
|
||||
|
||||
var errored = false
|
||||
|
||||
startCopy(currentPath)
|
||||
|
||||
function startCopy (source) {
|
||||
started++
|
||||
if (filter) {
|
||||
if (filter instanceof RegExp) {
|
||||
console.warn('Warning: fs-extra: Passing a RegExp filter is deprecated, use a function')
|
||||
if (!filter.test(source)) {
|
||||
return doneOne(true)
|
||||
}
|
||||
} else if (typeof filter === 'function') {
|
||||
if (!filter(source, dest)) {
|
||||
return doneOne(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
return getStats(source)
|
||||
}
|
||||
|
||||
function getStats (source) {
|
||||
var stat = dereference ? fs.stat : fs.lstat
|
||||
running++
|
||||
stat(source, function (err, stats) {
|
||||
if (err) return onError(err)
|
||||
|
||||
// We need to get the mode from the stats object and preserve it.
|
||||
var item = {
|
||||
name: source,
|
||||
mode: stats.mode,
|
||||
mtime: stats.mtime, // modified time
|
||||
atime: stats.atime, // access time
|
||||
stats: stats // temporary
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return onDir(item)
|
||||
} else if (stats.isFile() || stats.isCharacterDevice() || stats.isBlockDevice()) {
|
||||
return onFile(item)
|
||||
} else if (stats.isSymbolicLink()) {
|
||||
// Symlinks don't really need to know about the mode.
|
||||
return onLink(source)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onFile (file) {
|
||||
var target = file.name.replace(currentPath, targetPath.replace('$', '$$$$')) // escapes '$' with '$$'
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
copyFile(file, target)
|
||||
} else {
|
||||
if (overwrite) {
|
||||
rmFile(target, function () {
|
||||
copyFile(file, target)
|
||||
})
|
||||
} else if (errorOnExist) {
|
||||
onError(new Error(target + ' already exists'))
|
||||
} else {
|
||||
doneOne()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function copyFile (file, target) {
|
||||
var readStream = fs.createReadStream(file.name)
|
||||
var writeStream = fs.createWriteStream(target, { mode: file.mode })
|
||||
|
||||
readStream.on('error', onError)
|
||||
writeStream.on('error', onError)
|
||||
|
||||
if (transform) {
|
||||
transform(readStream, writeStream, file)
|
||||
} else {
|
||||
writeStream.on('open', function () {
|
||||
readStream.pipe(writeStream)
|
||||
})
|
||||
}
|
||||
|
||||
writeStream.once('close', function () {
|
||||
fs.chmod(target, file.mode, function (err) {
|
||||
if (err) return onError(err)
|
||||
if (preserveTimestamps) {
|
||||
utimes.utimesMillis(target, file.atime, file.mtime, function (err) {
|
||||
if (err) return onError(err)
|
||||
return doneOne()
|
||||
})
|
||||
} else {
|
||||
doneOne()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function rmFile (file, done) {
|
||||
fs.unlink(file, function (err) {
|
||||
if (err) return onError(err)
|
||||
return done()
|
||||
})
|
||||
}
|
||||
|
||||
function onDir (dir) {
|
||||
var target = dir.name.replace(currentPath, targetPath.replace('$', '$$$$')) // escapes '$' with '$$'
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
return mkDir(dir, target)
|
||||
}
|
||||
copyDir(dir.name)
|
||||
})
|
||||
}
|
||||
|
||||
function mkDir (dir, target) {
|
||||
fs.mkdir(target, dir.mode, function (err) {
|
||||
if (err) return onError(err)
|
||||
// despite setting mode in fs.mkdir, doesn't seem to work
|
||||
// so we set it here.
|
||||
fs.chmod(target, dir.mode, function (err) {
|
||||
if (err) return onError(err)
|
||||
copyDir(dir.name)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function copyDir (dir) {
|
||||
fs.readdir(dir, function (err, items) {
|
||||
if (err) return onError(err)
|
||||
items.forEach(function (item) {
|
||||
startCopy(path.join(dir, item))
|
||||
})
|
||||
return doneOne()
|
||||
})
|
||||
}
|
||||
|
||||
function onLink (link) {
|
||||
var target = link.replace(currentPath, targetPath)
|
||||
fs.readlink(link, function (err, resolvedPath) {
|
||||
if (err) return onError(err)
|
||||
checkLink(resolvedPath, target)
|
||||
})
|
||||
}
|
||||
|
||||
function checkLink (resolvedPath, target) {
|
||||
if (dereference) {
|
||||
resolvedPath = path.resolve(basePath, resolvedPath)
|
||||
}
|
||||
isWritable(target, function (writable) {
|
||||
if (writable) {
|
||||
return makeLink(resolvedPath, target)
|
||||
}
|
||||
fs.readlink(target, function (err, targetDest) {
|
||||
if (err) return onError(err)
|
||||
|
||||
if (dereference) {
|
||||
targetDest = path.resolve(basePath, targetDest)
|
||||
}
|
||||
if (targetDest === resolvedPath) {
|
||||
return doneOne()
|
||||
}
|
||||
return rmFile(target, function () {
|
||||
makeLink(resolvedPath, target)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function makeLink (linkPath, target) {
|
||||
fs.symlink(linkPath, target, function (err) {
|
||||
if (err) return onError(err)
|
||||
return doneOne()
|
||||
})
|
||||
}
|
||||
|
||||
function isWritable (path, done) {
|
||||
fs.lstat(path, function (err) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') return done(true)
|
||||
return done(false)
|
||||
}
|
||||
return done(false)
|
||||
})
|
||||
}
|
||||
|
||||
function onError (err) {
|
||||
// ensure callback is defined & called only once:
|
||||
if (!errored && callback !== undefined) {
|
||||
errored = true
|
||||
return callback(err)
|
||||
}
|
||||
}
|
||||
|
||||
function doneOne (skipped) {
|
||||
if (!skipped) running--
|
||||
finished++
|
||||
if ((started === finished) && (running === 0)) {
|
||||
if (callback !== undefined) {
|
||||
return callback(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ncp
|
||||
+7
-4
@@ -14,9 +14,8 @@ function createFile (file, callback) {
|
||||
})
|
||||
}
|
||||
|
||||
pathExists(file, (err, fileExists) => {
|
||||
if (err) return callback(err)
|
||||
if (fileExists) return callback()
|
||||
fs.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err
|
||||
if (!err && stats.isFile()) return callback()
|
||||
const dir = path.dirname(file)
|
||||
pathExists(dir, (err, dirExists) => {
|
||||
if (err) return callback(err)
|
||||
@@ -30,7 +29,11 @@ function createFile (file, callback) {
|
||||
}
|
||||
|
||||
function createFileSync (file) {
|
||||
if (fs.existsSync(file)) return
|
||||
let stats
|
||||
try {
|
||||
stats = fs.statSync(file)
|
||||
} catch (e) {}
|
||||
if (stats && stats.isFile()) return
|
||||
|
||||
const dir = path.dirname(file)
|
||||
if (!fs.existsSync(dir)) {
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ function createLink (srcpath, dstpath, callback) {
|
||||
pathExists(dstpath, (err, destinationExists) => {
|
||||
if (err) return callback(err)
|
||||
if (destinationExists) return callback(null)
|
||||
fs.lstat(srcpath, (err, stat) => {
|
||||
fs.lstat(srcpath, (err) => {
|
||||
if (err) {
|
||||
err.message = err.message.replace('lstat', 'ensureLink')
|
||||
return callback(err)
|
||||
@@ -36,7 +36,7 @@ function createLink (srcpath, dstpath, callback) {
|
||||
})
|
||||
}
|
||||
|
||||
function createLinkSync (srcpath, dstpath, callback) {
|
||||
function createLinkSync (srcpath, dstpath) {
|
||||
const destinationExists = fs.existsSync(dstpath)
|
||||
if (destinationExists) return undefined
|
||||
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ const pathExists = require('../path-exists').pathExists
|
||||
|
||||
function symlinkPaths (srcpath, dstpath, callback) {
|
||||
if (path.isAbsolute(srcpath)) {
|
||||
return fs.lstat(srcpath, (err, stat) => {
|
||||
return fs.lstat(srcpath, (err) => {
|
||||
if (err) {
|
||||
err.message = err.message.replace('lstat', 'ensureSymlink')
|
||||
return callback(err)
|
||||
@@ -49,7 +49,7 @@ function symlinkPaths (srcpath, dstpath, callback) {
|
||||
'toDst': srcpath
|
||||
})
|
||||
} else {
|
||||
return fs.lstat(srcpath, (err, stat) => {
|
||||
return fs.lstat(srcpath, (err) => {
|
||||
if (err) {
|
||||
err.message = err.message.replace('lstat', 'ensureSymlink')
|
||||
return callback(err)
|
||||
|
||||
+1
-4
@@ -43,10 +43,7 @@ function createSymlink (srcpath, dstpath, type, callback) {
|
||||
})
|
||||
}
|
||||
|
||||
function createSymlinkSync (srcpath, dstpath, type, callback) {
|
||||
callback = (typeof type === 'function') ? type : callback
|
||||
type = (typeof type === 'function') ? false : type
|
||||
|
||||
function createSymlinkSync (srcpath, dstpath, type) {
|
||||
const destinationExists = fs.existsSync(dstpath)
|
||||
if (destinationExists) return undefined
|
||||
|
||||
|
||||
+48
-5
@@ -1,3 +1,4 @@
|
||||
'use strict'
|
||||
// This is adapted from https://github.com/normalize/mz
|
||||
// Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors
|
||||
const u = require('universalify').fromCallback
|
||||
@@ -9,6 +10,7 @@ const api = [
|
||||
'chmod',
|
||||
'chown',
|
||||
'close',
|
||||
'copyFile',
|
||||
'fchmod',
|
||||
'fchown',
|
||||
'fdatasync',
|
||||
@@ -17,11 +19,12 @@ const api = [
|
||||
'ftruncate',
|
||||
'futimes',
|
||||
'lchown',
|
||||
'lchmod',
|
||||
'link',
|
||||
'lstat',
|
||||
'mkdir',
|
||||
'mkdtemp',
|
||||
'open',
|
||||
'read',
|
||||
'readFile',
|
||||
'readdir',
|
||||
'readlink',
|
||||
@@ -33,14 +36,22 @@ const api = [
|
||||
'truncate',
|
||||
'unlink',
|
||||
'utimes',
|
||||
'write',
|
||||
'writeFile'
|
||||
]
|
||||
// fs.mkdtemp() was added in Node.js v5.10.0, so check if it exists
|
||||
typeof fs.mkdtemp === 'function' && api.push('mkdtemp')
|
||||
].filter(key => {
|
||||
// Some commands are not available on some systems. Ex:
|
||||
// fs.copyFile was added in Node.js v8.5.0
|
||||
// fs.mkdtemp was added in Node.js v5.10.0
|
||||
// fs.lchown is not available on at least some Linux
|
||||
return typeof fs[key] === 'function'
|
||||
})
|
||||
|
||||
// Export all keys:
|
||||
Object.keys(fs).forEach(key => {
|
||||
if (key === 'promises') {
|
||||
// fs.promises is a getter property that triggers ExperimentalWarning
|
||||
// Don't re-export it here, the getter is defined in "lib/index.js"
|
||||
return
|
||||
}
|
||||
exports[key] = fs[key]
|
||||
})
|
||||
|
||||
@@ -59,3 +70,35 @@ exports.exists = function (filename, callback) {
|
||||
return fs.exists(filename, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
// fs.read() & fs.write need special treatment due to multiple callback args
|
||||
|
||||
exports.read = function (fd, buffer, offset, length, position, callback) {
|
||||
if (typeof callback === 'function') {
|
||||
return fs.read(fd, buffer, offset, length, position, callback)
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => {
|
||||
if (err) return reject(err)
|
||||
resolve({ bytesRead, buffer })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Function signature can be
|
||||
// fs.write(fd, buffer[, offset[, length[, position]]], callback)
|
||||
// OR
|
||||
// fs.write(fd, string[, position[, encoding]], callback)
|
||||
// We need to handle both cases, so we use ...args
|
||||
exports.write = function (fd, buffer, ...args) {
|
||||
if (typeof args[args.length - 1] === 'function') {
|
||||
return fs.write(fd, buffer, ...args)
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => {
|
||||
if (err) return reject(err)
|
||||
resolve({ bytesWritten, buffer })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
+25
-19
@@ -1,22 +1,28 @@
|
||||
'use strict'
|
||||
|
||||
const assign = require('./util/assign')
|
||||
module.exports = Object.assign(
|
||||
{},
|
||||
// Export promiseified graceful-fs:
|
||||
require('./fs'),
|
||||
// Export extra methods:
|
||||
require('./copy-sync'),
|
||||
require('./copy'),
|
||||
require('./empty'),
|
||||
require('./ensure'),
|
||||
require('./json'),
|
||||
require('./mkdirs'),
|
||||
require('./move-sync'),
|
||||
require('./move'),
|
||||
require('./output'),
|
||||
require('./path-exists'),
|
||||
require('./remove')
|
||||
)
|
||||
|
||||
const fs = {}
|
||||
|
||||
// Export graceful-fs:
|
||||
assign(fs, require('./fs'))
|
||||
// Export extra methods:
|
||||
assign(fs, require('./copy'))
|
||||
assign(fs, require('./copy-sync'))
|
||||
assign(fs, require('./mkdirs'))
|
||||
assign(fs, require('./remove'))
|
||||
assign(fs, require('./json'))
|
||||
assign(fs, require('./move'))
|
||||
assign(fs, require('./move-sync'))
|
||||
assign(fs, require('./empty'))
|
||||
assign(fs, require('./ensure'))
|
||||
assign(fs, require('./output'))
|
||||
assign(fs, require('./path-exists'))
|
||||
|
||||
module.exports = fs
|
||||
// Export fs.promises as a getter property so that we don't trigger
|
||||
// ExperimentalWarning before fs.promises is actually accessed.
|
||||
const fs = require('fs')
|
||||
if (Object.getOwnPropertyDescriptor(fs, 'promises')) {
|
||||
Object.defineProperty(module.exports, 'promises', {
|
||||
get () { return fs.promises }
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
const u = require('universalify').fromCallback
|
||||
const jsonFile = require('./jsonfile')
|
||||
|
||||
jsonFile.outputJsonSync = require('./output-json-sync')
|
||||
jsonFile.outputJson = u(require('./output-json'))
|
||||
jsonFile.outputJsonSync = require('./output-json-sync')
|
||||
// aliases
|
||||
jsonFile.outputJSONSync = jsonFile.outputJSONSync
|
||||
jsonFile.outputJSON = jsonFile.outputJson
|
||||
jsonFile.outputJSONSync = jsonFile.outputJsonSync
|
||||
jsonFile.writeJSON = jsonFile.writeJson
|
||||
jsonFile.writeJSONSync = jsonFile.writeJsonSync
|
||||
jsonFile.readJSON = jsonFile.readJson
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ const mkdirs = u(require('./mkdirs'))
|
||||
const mkdirsSync = require('./mkdirs-sync')
|
||||
|
||||
module.exports = {
|
||||
mkdirs: mkdirs,
|
||||
mkdirsSync: mkdirsSync,
|
||||
mkdirs,
|
||||
mkdirsSync,
|
||||
// alias
|
||||
mkdirp: mkdirs,
|
||||
mkdirpSync: mkdirsSync,
|
||||
|
||||
+14
-19
@@ -31,25 +31,20 @@ function mkdirsSync (p, opts, made) {
|
||||
xfs.mkdirSync(p, mode)
|
||||
made = made || p
|
||||
} catch (err0) {
|
||||
switch (err0.code) {
|
||||
case 'ENOENT':
|
||||
if (path.dirname(p) === p) throw err0
|
||||
made = mkdirsSync(path.dirname(p), opts, made)
|
||||
mkdirsSync(p, opts, made)
|
||||
break
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
let stat
|
||||
try {
|
||||
stat = xfs.statSync(p)
|
||||
} catch (err1) {
|
||||
throw err0
|
||||
}
|
||||
if (!stat.isDirectory()) throw err0
|
||||
break
|
||||
if (err0.code === 'ENOENT') {
|
||||
if (path.dirname(p) === p) throw err0
|
||||
made = mkdirsSync(path.dirname(p), opts, made)
|
||||
mkdirsSync(p, opts, made)
|
||||
} else {
|
||||
// In the case of any other error, just see if there's a dir there
|
||||
// already. If so, then hooray! If not, then something is borked.
|
||||
let stat
|
||||
try {
|
||||
stat = xfs.statSync(p)
|
||||
} catch (err1) {
|
||||
throw err0
|
||||
}
|
||||
if (!stat.isDirectory()) throw err0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -68,11 +68,10 @@ function moveFileSyncAcrossDevice (src, dest, overwrite) {
|
||||
const fdr = fs.openSync(src, 'r')
|
||||
const stat = fs.fstatSync(fdr)
|
||||
const fdw = fs.openSync(dest, flags, stat.mode)
|
||||
let bytesRead = 1
|
||||
let pos = 0
|
||||
|
||||
while (bytesRead > 0) {
|
||||
bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
|
||||
while (pos < stat.size) {
|
||||
const bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos)
|
||||
fs.writeSync(fdw, _buff, 0, bytesRead)
|
||||
pos += bytesRead
|
||||
}
|
||||
|
||||
+57
-137
@@ -1,160 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
// most of this code was written by Andrew Kelley
|
||||
// licensed under the BSD license: see
|
||||
// https://github.com/andrewrk/node-mv/blob/master/package.json
|
||||
|
||||
// this needs a cleanup
|
||||
|
||||
const u = require('universalify').fromCallback
|
||||
const fs = require('graceful-fs')
|
||||
const ncp = require('../copy/ncp')
|
||||
const path = require('path')
|
||||
const copy = require('../copy').copy
|
||||
const remove = require('../remove').remove
|
||||
const mkdirp = require('../mkdirs').mkdirs
|
||||
const mkdirp = require('../mkdirs').mkdirp
|
||||
const pathExists = require('../path-exists').pathExists
|
||||
|
||||
function move (source, dest, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
function move (src, dest, opts, cb) {
|
||||
if (typeof opts === 'function') {
|
||||
cb = opts
|
||||
opts = {}
|
||||
}
|
||||
|
||||
const shouldMkdirp = ('mkdirp' in options) ? options.mkdirp : true
|
||||
const overwrite = options.overwrite || options.clobber || false
|
||||
const overwrite = opts.overwrite || opts.clobber || false
|
||||
|
||||
if (shouldMkdirp) {
|
||||
mkdirs()
|
||||
} else {
|
||||
doRename()
|
||||
}
|
||||
src = path.resolve(src)
|
||||
dest = path.resolve(dest)
|
||||
|
||||
function mkdirs () {
|
||||
if (src === dest) return fs.access(src, cb)
|
||||
|
||||
fs.stat(src, (err, st) => {
|
||||
if (err) return cb(err)
|
||||
|
||||
if (st.isDirectory() && isSrcSubdir(src, dest)) {
|
||||
return cb(new Error(`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`))
|
||||
}
|
||||
mkdirp(path.dirname(dest), err => {
|
||||
if (err) return callback(err)
|
||||
doRename()
|
||||
})
|
||||
}
|
||||
|
||||
function doRename () {
|
||||
if (path.resolve(source) === path.resolve(dest)) {
|
||||
fs.access(source, callback)
|
||||
} else if (overwrite) {
|
||||
fs.rename(source, dest, err => {
|
||||
if (!err) return callback()
|
||||
|
||||
if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') {
|
||||
remove(dest, err => {
|
||||
if (err) return callback(err)
|
||||
options.overwrite = false // just overwriteed it, no need to do it again
|
||||
move(source, dest, options, callback)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// weird Windows shit
|
||||
if (err.code === 'EPERM') {
|
||||
setTimeout(() => {
|
||||
remove(dest, err => {
|
||||
if (err) return callback(err)
|
||||
options.overwrite = false
|
||||
move(source, dest, options, callback)
|
||||
})
|
||||
}, 200)
|
||||
return
|
||||
}
|
||||
|
||||
if (err.code !== 'EXDEV') return callback(err)
|
||||
moveAcrossDevice(source, dest, overwrite, callback)
|
||||
})
|
||||
} else {
|
||||
fs.link(source, dest, err => {
|
||||
if (err) {
|
||||
if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') {
|
||||
moveAcrossDevice(source, dest, overwrite, callback)
|
||||
return
|
||||
}
|
||||
callback(err)
|
||||
return
|
||||
}
|
||||
fs.unlink(source, callback)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function moveAcrossDevice (source, dest, overwrite, callback) {
|
||||
fs.stat(source, (err, stat) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
return
|
||||
}
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
moveDirAcrossDevice(source, dest, overwrite, callback)
|
||||
} else {
|
||||
moveFileAcrossDevice(source, dest, overwrite, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function moveFileAcrossDevice (source, dest, overwrite, callback) {
|
||||
const flags = overwrite ? 'w' : 'wx'
|
||||
const ins = fs.createReadStream(source)
|
||||
const outs = fs.createWriteStream(dest, { flags })
|
||||
|
||||
ins.on('error', err => {
|
||||
ins.destroy()
|
||||
outs.destroy()
|
||||
outs.removeListener('close', onClose)
|
||||
|
||||
// may want to create a directory but `out` line above
|
||||
// creates an empty file for us: See #108
|
||||
// don't care about error here
|
||||
fs.unlink(dest, () => {
|
||||
// note: `err` here is from the input stream errror
|
||||
if (err.code === 'EISDIR' || err.code === 'EPERM') {
|
||||
moveDirAcrossDevice(source, dest, overwrite, callback)
|
||||
} else {
|
||||
callback(err)
|
||||
}
|
||||
if (err) return cb(err)
|
||||
return doRename(src, dest, overwrite, cb)
|
||||
})
|
||||
})
|
||||
|
||||
outs.on('error', err => {
|
||||
ins.destroy()
|
||||
outs.destroy()
|
||||
outs.removeListener('close', onClose)
|
||||
callback(err)
|
||||
})
|
||||
|
||||
outs.once('close', onClose)
|
||||
ins.pipe(outs)
|
||||
|
||||
function onClose () {
|
||||
fs.unlink(source, callback)
|
||||
}
|
||||
}
|
||||
|
||||
function moveDirAcrossDevice (source, dest, overwrite, callback) {
|
||||
const options = {
|
||||
overwrite: false
|
||||
}
|
||||
|
||||
function doRename (src, dest, overwrite, cb) {
|
||||
if (overwrite) {
|
||||
remove(dest, err => {
|
||||
if (err) return callback(err)
|
||||
startNcp()
|
||||
return remove(dest, err => {
|
||||
if (err) return cb(err)
|
||||
return rename(src, dest, overwrite, cb)
|
||||
})
|
||||
} else {
|
||||
startNcp()
|
||||
}
|
||||
pathExists(dest, (err, destExists) => {
|
||||
if (err) return cb(err)
|
||||
if (destExists) return cb(new Error('dest already exists.'))
|
||||
return rename(src, dest, overwrite, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function rename (src, dest, overwrite, cb) {
|
||||
fs.rename(src, dest, err => {
|
||||
if (!err) return cb()
|
||||
if (err.code !== 'EXDEV') return cb(err)
|
||||
return moveAcrossDevice(src, dest, overwrite, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function moveAcrossDevice (src, dest, overwrite, cb) {
|
||||
const opts = {
|
||||
overwrite,
|
||||
errorOnExist: true
|
||||
}
|
||||
|
||||
function startNcp () {
|
||||
ncp(source, dest, options, err => {
|
||||
if (err) return callback(err)
|
||||
remove(source, callback)
|
||||
})
|
||||
}
|
||||
copy(src, dest, opts, err => {
|
||||
if (err) return cb(err)
|
||||
return remove(src, cb)
|
||||
})
|
||||
}
|
||||
|
||||
function isSrcSubdir (src, dest) {
|
||||
const srcArray = src.split(path.sep)
|
||||
const destArray = dest.split(path.sep)
|
||||
|
||||
return srcArray.reduce((acc, current, i) => {
|
||||
return acc && destArray[i] === current
|
||||
}, true)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
+3
-3
@@ -25,13 +25,13 @@ function outputFile (file, data, encoding, callback) {
|
||||
})
|
||||
}
|
||||
|
||||
function outputFileSync (file, data, encoding) {
|
||||
function outputFileSync (file, ...args) {
|
||||
const dir = path.dirname(file)
|
||||
if (fs.existsSync(dir)) {
|
||||
return fs.writeFileSync.apply(fs, arguments)
|
||||
return fs.writeFileSync(file, ...args)
|
||||
}
|
||||
mkdir.mkdirsSync(dir)
|
||||
fs.writeFileSync.apply(fs, arguments)
|
||||
fs.writeFileSync(file, ...args)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
+28
-10
@@ -33,19 +33,19 @@ function rimraf (p, options, cb) {
|
||||
}
|
||||
|
||||
assert(p, 'rimraf: missing path')
|
||||
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert.equal(typeof cb, 'function', 'rimraf: callback function required')
|
||||
assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert.strictEqual(typeof cb, 'function', 'rimraf: callback function required')
|
||||
assert(options, 'rimraf: invalid options argument provided')
|
||||
assert.equal(typeof options, 'object', 'rimraf: options should be object')
|
||||
assert.strictEqual(typeof options, 'object', 'rimraf: options should be object')
|
||||
|
||||
defaults(options)
|
||||
|
||||
rimraf_(p, options, function CB (er) {
|
||||
if (er) {
|
||||
if (isWindows && (er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') &&
|
||||
if ((er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') &&
|
||||
busyTries < options.maxBusyTries) {
|
||||
busyTries++
|
||||
let time = busyTries * 100
|
||||
const time = busyTries * 100
|
||||
// try again, with the same exact callback as this one.
|
||||
return setTimeout(() => rimraf_(p, options, CB), time)
|
||||
}
|
||||
@@ -117,7 +117,7 @@ function fixWinEPERM (p, options, er, cb) {
|
||||
assert(er instanceof Error)
|
||||
}
|
||||
|
||||
options.chmod(p, 666, er2 => {
|
||||
options.chmod(p, 0o666, er2 => {
|
||||
if (er2) {
|
||||
cb(er2.code === 'ENOENT' ? null : er)
|
||||
} else {
|
||||
@@ -144,7 +144,7 @@ function fixWinEPERMSync (p, options, er) {
|
||||
}
|
||||
|
||||
try {
|
||||
options.chmodSync(p, 666)
|
||||
options.chmodSync(p, 0o666)
|
||||
} catch (er2) {
|
||||
if (er2.code === 'ENOENT') {
|
||||
return
|
||||
@@ -229,9 +229,9 @@ function rimrafSync (p, options) {
|
||||
defaults(options)
|
||||
|
||||
assert(p, 'rimraf: missing path')
|
||||
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string')
|
||||
assert(options, 'rimraf: missing options')
|
||||
assert.equal(typeof options, 'object', 'rimraf: options should be object')
|
||||
assert.strictEqual(typeof options, 'object', 'rimraf: options should be object')
|
||||
|
||||
try {
|
||||
st = options.lstatSync(p)
|
||||
@@ -289,7 +289,25 @@ function rmkidsSync (p, options) {
|
||||
assert(p)
|
||||
assert(options)
|
||||
options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options))
|
||||
options.rmdirSync(p, options)
|
||||
|
||||
if (isWindows) {
|
||||
// We only end up here once we got ENOTEMPTY at least once, and
|
||||
// at this point, we are guaranteed to have removed all the kids.
|
||||
// So, we know that it won't be ENOENT or ENOTDIR or anything else.
|
||||
// try really hard to delete stuff on windows, because it has a
|
||||
// PROFOUNDLY annoying habit of not closing handles promptly when
|
||||
// files are deleted, resulting in spurious ENOTEMPTY errors.
|
||||
const startTime = Date.now()
|
||||
do {
|
||||
try {
|
||||
const ret = options.rmdirSync(p, options)
|
||||
return ret
|
||||
} catch (er) { }
|
||||
} while (Date.now() - startTime < 500) // give up after 500ms
|
||||
} else {
|
||||
const ret = options.rmdirSync(p, options)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = rimraf
|
||||
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
// simple mutable assign
|
||||
function assign () {
|
||||
const args = [].slice.call(arguments).filter(i => i)
|
||||
const dest = args.shift()
|
||||
args.forEach(src => {
|
||||
Object.keys(src).forEach(key => {
|
||||
dest[key] = src[key]
|
||||
})
|
||||
})
|
||||
|
||||
return dest
|
||||
}
|
||||
|
||||
module.exports = assign
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
'use strict'
|
||||
/* eslint-disable node/no-deprecated-api */
|
||||
module.exports = function (size) {
|
||||
if (typeof Buffer.allocUnsafe === 'function') {
|
||||
|
||||
+8
-1
@@ -64,9 +64,16 @@ function utimesMillis (path, atime, mtime, callback) {
|
||||
})
|
||||
}
|
||||
|
||||
function utimesMillisSync (path, atime, mtime) {
|
||||
const fd = fs.openSync(path, 'r+')
|
||||
fs.futimesSync(fd, atime, mtime)
|
||||
return fs.closeSync(fd)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hasMillisRes,
|
||||
hasMillisResSync,
|
||||
timeRemoveMillis,
|
||||
utimesMillis
|
||||
utimesMillis,
|
||||
utimesMillisSync
|
||||
}
|
||||
|
||||
+26
-21
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"_from": "fs-extra@^3.0.1",
|
||||
"_id": "fs-extra@3.0.1",
|
||||
"_from": "fs-extra@^7.0.1",
|
||||
"_id": "fs-extra@7.0.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
|
||||
"_integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"_location": "/fs-extra",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "fs-extra@^3.0.1",
|
||||
"raw": "fs-extra@^7.0.1",
|
||||
"name": "fs-extra",
|
||||
"escapedName": "fs-extra",
|
||||
"rawSpec": "^3.0.1",
|
||||
"rawSpec": "^7.0.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.0.1"
|
||||
"fetchSpec": "^7.0.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/laravel-mix"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
|
||||
"_shasum": "3794f378c58b342ea7dbbb23095109c4b3b62291",
|
||||
"_spec": "fs-extra@^3.0.1",
|
||||
"_resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"_shasum": "4f189c44aa123b895f722804f55ea23eadc348e9",
|
||||
"_spec": "fs-extra@^7.0.1",
|
||||
"_where": "C:\\xampp\\htdocs\\w4rpservices\\node_modules\\laravel-mix",
|
||||
"author": {
|
||||
"name": "JP Richardson",
|
||||
@@ -32,24 +32,28 @@
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^3.0.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as mkdir -p, cp -r, and rm -rf.",
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.2",
|
||||
"coveralls": "^3.0.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"klaw": "^1.0.0",
|
||||
"klaw-sync": "^1.1.2",
|
||||
"klaw": "^2.1.1",
|
||||
"klaw-sync": "^3.0.2",
|
||||
"minimist": "^1.1.1",
|
||||
"mocha": "^3.1.2",
|
||||
"proxyquire": "^1.7.10",
|
||||
"mocha": "^5.0.5",
|
||||
"proxyquire": "^2.0.1",
|
||||
"read-dir-files": "^0.1.1",
|
||||
"rimraf": "^2.2.8",
|
||||
"secure-random": "^1.1.1",
|
||||
"standard": "^10.0.2",
|
||||
"standard-markdown": "^2.3.0"
|
||||
"semver": "^5.3.0",
|
||||
"standard": "^11.0.1",
|
||||
"standard-markdown": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
},
|
||||
"homepage": "https://github.com/jprichardson/node-fs-extra",
|
||||
"keywords": [
|
||||
@@ -76,7 +80,7 @@
|
||||
"move"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./lib/index",
|
||||
"main": "./lib/index.js",
|
||||
"name": "fs-extra",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -84,11 +88,12 @@
|
||||
},
|
||||
"scripts": {
|
||||
"coverage": "istanbul cover -i 'lib/**' -x '**/__tests__/**' test.js",
|
||||
"coveralls": "npm run coverage && coveralls < coverage/lcov.info",
|
||||
"lint": "standard && standard-markdown",
|
||||
"coveralls": "coveralls < coverage/lcov.info",
|
||||
"full-ci": "npm run lint && npm run coverage",
|
||||
"lint": "standard",
|
||||
"test": "npm run lint && npm run unit",
|
||||
"test-find": "find ./lib/**/__tests__ -name *.test.js | xargs mocha",
|
||||
"unit": "node test.js"
|
||||
},
|
||||
"version": "3.0.1"
|
||||
"version": "7.0.1"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user