<commit_before>fs-jetpack [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack) [![codecov](https://codecov.io/gh/szwacz/fs-jetpack/branch/master/graph/badge.svg)](https://codecov.io/gh/szwacz/fs-jetpack)
==========

Node's [fs library](http://nodejs.org/api/fs.html) is very low level and because of that often painful to use. *fs-jetpack* wants to fix that by giving you completely rethought, much more convenient API to work with file system.

Check out [EXAMPLES](EXAMPLES.md) to see few snippets what it can do.

# Table of Contents

[Installation](#installation)  
[Sync & Async](#sync--async)  
[Usage with TypeScript](#usage-with-typescript)

**API:**  
[append](#appendpath-data-options)  
[copy](#copyfrom-to-options)  
[createReadStream](#createreadstreampath-options)  
[createWriteStream](#createwritestreampath-options)  
[cwd](#cwdpath)  
[dir](#dirpath-criteria)  
[exists](#existspath)  
[file](#filepath-criteria)  
[find](#findpath-searchoptions)  
[inspect](#inspectpath-options)  
[inspectTree](#inspecttreepath-options)  
[list](#listpath)  
[move](#movefrom-to)  
[path](#pathparts)  
[read](#readpath-returnas)  
[remove](#removepath)  
[rename](#renamepath-newname)  
[symlink](#symlinksymlinkvalue-path)  
[write](#writepath-data-options)

# Installation
```
npm install fs-jetpack
```

## Usage
```javascript
const jetpack = require('fs-jetpack');
```

# Sync & Async

API has the same set of synchronous and asynchronous methods. All async methods are promise based (no callbacks).

Commonly used naming convention in Node world is reversed in this library (no 'method' and 'methodSync' naming). Asynchronous methods are those with 'Async' suffix, all methods without 'Async' in the name are synchronous. Reason behind this is that it gives very nice look to blocking API. And promise-based, non-blocking code is verbose anyway, so one more word is not much of a difference.

Also it's just convenient...

If you don't see the word "Async" in method name it returns value immediately.
```js
const data = jetpack.read('file.txt');
console.log(data);
```

When you see "Async" that method returns promise which when resolved returns value.
```js
jetpack.readAsync('file.txt')
.then((data) => {
  console.log(data);
});
```

# Usage with TypeScript

Starting from v2.1.0 fs-jetpack is TypeScript compatible. But for backwards compatibility purposes all types and interfaces are reachable through special path `fs-jetpack/types`.
```typescript
// Import fs-jetpack into TypeScript code (the jetpack typings will be loaded as well).
import * as jetpack from "fs-jetpack";

// Import one of jetpack's interfaces to cast it on a variable declaration.
import { InspectResult } from "fs-jetpack/types";
let result: InspectResult = jetpack.inspect("foo");
```

# API

## append(path, data, [options])
asynchronous: **appendAsync(path, data, [options])**

Appends given data to the end of file. If file or any parent directory doesn't exist it will be created.

**arguments:**  
`path` the path to file.  
`data` data to append (can be `String` or `Buffer`).  
`options` (optional) `Object` with possible fields:
* `mode` if the file doesn't exist yet, will be created with given mode. Value could be number (eg. `0o700`) or string (eg. `'700'`).

**returns:**  
Nothing.


## copy(from, to, [options])
asynchronous: **copyAsync(from, to, [options])**  

Copies given file or directory (with everything inside).

**arguments:**  
`from` path to location you want to copy.  
`to` path to destination location, where the copy should be placed.  
`options` (optional) additional options for customization. Is an `Object` with possible fields:  
* `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. Can be `Boolean` or `Function`. For directories, source directory is merged with destination directory. If function was provided, every time there is a file conflict while copying the function will be invoked with [inspect](#inspectpath-options) objects of both: source and destination file and overwrites the file only if `true` has been returned from the function (see example below). In async mode, the overwrite function can also return a promise, so you can perform multi step processes to determine if file should be overwritten or not (see example below).
* `matching` if defined will actually copy **only** items matching any of specified glob patterns and omit everything else ([all possible globs are described further in this readme](#matching-patterns)).
* `ignoreCase` (default `false`) whether or not case should be ignored when processing glob patterns passed through the `matching` option.

**returns:**  <commit_msg>docs(copy): clarify `overwrite` option<commit_after>fs-jetpack [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack) [![codecov](https://codecov.io/gh/szwacz/fs-jetpack/branch/master/graph/badge.svg)](https://codecov.io/gh/szwacz/fs-jetpack)
==========

Node's [fs library](http://nodejs.org/api/fs.html) is very low level and because of that often painful to use. *fs-jetpack* wants to fix that by giving you completely rethought, much more convenient API to work with file system.

Check out [EXAMPLES](EXAMPLES.md) to see few snippets what it can do.

# Table of Contents

[Installation](#installation)  
[Sync & Async](#sync--async)  
[Usage with TypeScript](#usage-with-typescript)

**API:**  
[append](#appendpath-data-options)  
[copy](#copyfrom-to-options)  
[createReadStream](#createreadstreampath-options)  
[createWriteStream](#createwritestreampath-options)  
[cwd](#cwdpath)  
[dir](#dirpath-criteria)  
[exists](#existspath)  
[file](#filepath-criteria)  
[find](#findpath-searchoptions)  
[inspect](#inspectpath-options)  
[inspectTree](#inspecttreepath-options)  
[list](#listpath)  
[move](#movefrom-to)  
[path](#pathparts)  
[read](#readpath-returnas)  
[remove](#removepath)  
[rename](#renamepath-newname)  
[symlink](#symlinksymlinkvalue-path)  
[write](#writepath-data-options)

# Installation
```
npm install fs-jetpack
```

## Usage
```javascript
const jetpack = require('fs-jetpack');
```

# Sync & Async

API has the same set of synchronous and asynchronous methods. All async methods are promise based (no callbacks).

Commonly used naming convention in Node world is reversed in this library (no 'method' and 'methodSync' naming). Asynchronous methods are those with 'Async' suffix, all methods without 'Async' in the name are synchronous. Reason behind this is that it gives very nice look to blocking API. And promise-based, non-blocking code is verbose anyway, so one more word is not much of a difference.

Also it's just convenient...

If you don't see the word "Async" in method name it returns value immediately.
```js
const data = jetpack.read('file.txt');
console.log(data);
```

When you see "Async" that method returns promise which when resolved returns value.
```js
jetpack.readAsync('file.txt')
.then((data) => {
  console.log(data);
});
```

# Usage with TypeScript

Starting from v2.1.0 fs-jetpack is TypeScript compatible. But for backwards compatibility purposes all types and interfaces are reachable through special path `fs-jetpack/types`.
```typescript
// Import fs-jetpack into TypeScript code (the jetpack typings will be loaded as well).
import * as jetpack from "fs-jetpack";

// Import one of jetpack's interfaces to cast it on a variable declaration.
import { InspectResult } from "fs-jetpack/types";
let result: InspectResult = jetpack.inspect("foo");
```

# API

## append(path, data, [options])
asynchronous: **appendAsync(path, data, [options])**

Appends given data to the end of file. If file or any parent directory doesn't exist it will be created.

**arguments:**  
`path` the path to file.  
`data` data to append (can be `String` or `Buffer`).  
`options` (optional) `Object` with possible fields:
* `mode` if the file doesn't exist yet, will be created with given mode. Value could be number (eg. `0o700`) or string (eg. `'700'`).

**returns:**  
Nothing.


## copy(from, to, [options])
asynchronous: **copyAsync(from, to, [options])**  

Copies given file or directory (with everything inside).

**arguments:**  
`from` path to location you want to copy.  
`to` path to destination location, where the copy should be placed.  
`options` (optional) additional options for customization. Is an `Object` with possible fields:  
* `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. Can be `Boolean` or `Function`. If `false`, an error will be thrown if it already exists. If `true`, the overwrite will be performed (for directories, this overwrite consists of a recursive merge - i.e. only files that already exist in the destination directory will be overwritten). If a function was provided, every time there is a file conflict while copying the function will be invoked with [inspect](#inspectpath-options) objects of both: source and destination file and overwrites the file only if `true` has been returned from the function (see example below). In async mode, the overwrite function can also return a promise, so you can perform multi step processes to determine if file should be overwritten or not (see example below).
* `matching` if defined will actually copy **only** items matching any of specified glob patterns and omit everything else ([all possible globs are described further in this readme](#matching-patterns)).
* `ignoreCase` (default `false`) whether or not case should be ignored when processing glob patterns passed through the `matching` option.

**returns:**  
{'fraction_non_alphanumeric': 0.12003203523876264, 'fraction_numerical': 0.003403744118530383, 'mean_word_length': 5.021699819168173, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '581840', 'n_tokens_mistral': 3019, 'n_tokens_neox': 2874, 'n_words': 1121}