UNPKG

28.3 kBMarkdownView Raw
1# fs-jetpack [![codecov](https://codecov.io/gh/szwacz/fs-jetpack/branch/master/graph/badge.svg)](https://codecov.io/gh/szwacz/fs-jetpack)
2
3API for your everyday file system manipulations, much more convenient than [fs](http://nodejs.org/api/fs.html) or [fs-extra](https://github.com/jprichardson/node-fs-extra). You will especially appreciate it as a scripting/tooling library and for your build pipelines.
4
5# Table of Contents
6
7[Key Concepts](#key-concepts)
8[Getting Started](#getting-started)
9
10**API:**
11[append](#appendpath-data-options)
12[copy](#copyfrom-to-options)
13[createReadStream](#createreadstreampath-options)
14[createWriteStream](#createwritestreampath-options)
15[cwd](#cwdpath)
16[dir](#dirpath-criteria)
17[exists](#existspath)
18[file](#filepath-criteria)
19[find](#findpath-searchoptions)
20[inspect](#inspectpath-options)
21[inspectTree](#inspecttreepath-options)
22[list](#listpath)
23[move](#movefrom-to-options)
24[path](#pathparts)
25[read](#readpath-returnas)
26[remove](#removepath)
27[rename](#renamepath-newname-options)
28[symlink](#symlinksymlinkvalue-path)
29[tmpDir](#tmpdiroptions)
30[write](#writepath-data-options)
31
32# Key Concepts
33
34### Why not use more than one CWD?
35
36You can create many fs-jetpack objects with different internal working directories (which are independent from `process.cwd()`) and work on directories in a little more object-oriented manner.
37
38```js
39const src = jetpack.cwd("path/to/source");
40const dest = jetpack.cwd("/some/different/path/to/destination");
41src.copy("foo.txt", dest.path("bar.txt"));
42```
43
44### JSON is a first class citizen
45
46You can write JavaScript object directly to disk and it will be transformed into JSON automatically.
47
48```js
49const obj = { greet: "Hello World!" };
50jetpack.write("file.json", obj);
51```
52
53Then you can get your object back just by telling `read` method that it's a JSON.
54
55```js
56const obj = jetpack.read("file.json", "json");
57```
58
59### Automatic handling of ENOENT errors
60
61Everyone who has a lot to do with file system probably is sick of seeing error _"ENOENT, no such file or directory"_. Fs-jetpack tries to recover from this.
62
63- For write/creation operations, if any of parent directories doesn't exist jetpack will just create them as well (like `mkdir -p` works).
64- For read/inspect operations, if file or directory doesn't exist `undefined` is returned instead of throwing.
65
66### Sync & async harmony
67
68API has the same set of synchronous and asynchronous methods. All async methods are promise based (no callbacks).
69
70Commonly used naming convention in node.js world has been flipped in this API, so no `method()` (async) and `methodSync()` naming. Here the convention is `methodAsync()` and `method()` (sync). I know this looks wrong to you, but bear with me. Thanks to that, you always know how fs-jetpack method behaves, just by looking at the name: **If you don't see the word "Async", this method returns value immediately, if you do, promise is returned.** Standard node.js naming can't give you this clarity.
71
72```js
73// Synchronous call
74const data = jetpack.read('file.txt');
75console.log(data);
76
77// Asynchronous call
78const data = await jetpack.readAsync('file.txt');
79console.log(data);
80```
81
82## All API methods cooperate nicely with each other
83
84Let's say you want to create folder structure as demonstrated in comment below. Piece of cake!
85
86```js
87// .
88// |- greets
89// |- greet.txt
90// |- greet.json
91// |- greets-i18n
92// |- polish.txt
93
94jetpack
95 .dir("greets")
96 .file("greet.txt", { content: "Hello world!" })
97 .file("greet.json", { content: { greet: "Hello world!" } })
98 .cwd("..")
99 .dir("greets-i18n")
100 .file("polish.txt", { content: "Witaj świecie!" });
101```
102
103Need to copy whole directory of files, but first perform some transformations on each file?
104
105```js
106const src = jetpack.cwd("path/to/source/folder");
107const dst = jetpack.cwd("path/to/destination");
108
109src.find({ matching: "*" }).forEach((path) => {
110 const content = src.read(path);
111 const transformedContent = transformTheFileHoweverYouWant(content);
112 dst.write(path, transformedContent);
113});
114```
115
116Need to delete all temporary and log files inside `my_folder` tree?
117
118```js
119jetpack.find("my_folder", { matching: ["*.tmp", "*.log"] }).forEach(jetpack.remove);
120```
121
122Need to perform temporary data transformations?
123
124```js
125const dir = jetpack.tmpDir();
126dir.write("data.txt", myData);
127// Perform some operations on the data and when you're done
128// and don't need the folder any longer just call...
129dir.remove();
130```
131
132# Getting Started
133
134## Installation
135
136```
137npm install fs-jetpack
138```
139
140Import to your code:
141
142```javascript
143const jetpack = require("fs-jetpack");
144```
145
146## Usage with TypeScript
147
148Starting 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`.
149
150```typescript
151// Import fs-jetpack into TypeScript code (the jetpack typings will be loaded as well).
152import * as jetpack from "fs-jetpack";
153
154// Import one of jetpack's interfaces to cast it on a variable declaration.
155import { InspectResult } from "fs-jetpack/types";
156let result: InspectResult = jetpack.inspect("foo");
157```
158
159## Upgrading to New Version
160
161This API is considered stable and all breaking changes to it are done as completely last resort. It also uses "better safe than sorry" approach to bumping major version number. So in 99.9% of cases you can upgrade to latest version with no worries, because all major version bumps so far, were due to edge case behaviour changes.
162
163# API
164
165## append(path, data, [options])
166
167asynchronous: **appendAsync(path, data, [options])**
168
169Appends given data to the end of file. If file or any parent directory doesn't exist it will be created.
170
171**arguments:**
172`path` the path to file.
173`data` data to append (can be `String` or `Buffer`).
174`options` (optional) `Object` with possible fields:
175
176- `mode` if the file doesn't exist yet, will be created with given mode. Value could be number (eg. `0o700`) or string (eg. `'700'`).
177
178**returns:**
179Nothing.
180
181## copy(from, to, [options])
182
183asynchronous: **copyAsync(from, to, [options])**
184
185Copies given file or directory (with everything inside).
186
187**arguments:**
188`from` path to location you want to copy.
189`to` path to destination location, where the copy should be placed.
190`options` (optional) additional options for customization. Is an `Object` with possible fields:
191
192- `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).
193- `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)).
194- `ignoreCase` (default `false`) whether or not case should be ignored when processing glob patterns passed through the `matching` option.
195
196**returns:**
197Nothing.
198
199**examples:**
200
201```javascript
202// Copies a file (and replaces it if one already exists in 'foo' directory)
203jetpack.copy("file.txt", "foo/file.txt", { overwrite: true });
204
205// Copies files from folder foo_1 to foo_final, but overwrites in
206// foo_final only files which are newer in foo_1.
207jetpack.copy("foo_1", "foo_final", {
208 overwrite: (srcInspectData, destInspectData) => {
209 return srcInspectData.modifyTime > destInspectData.modifyTime;
210 }
211});
212
213// Asynchronously copies files from folder foo_1 to foo_final,
214// but overwrites only files containing "John Doe" string.
215jetpack.copyAsync("foo_1", "foo_final", {
216 overwrite: (srcInspectData, destInspectData) => {
217 return jetpack.readAsync(srcInspectData.absolutePath).then(data => {
218 return data.includes("John Doe");
219 });
220 }
221});
222
223// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'.
224jetpack.copy("foo", "bar", { matching: "*.md" });
225// Copies only '.md' and '.txt' files from 'foo' (and subdirectories of 'foo') to 'bar'.
226jetpack.copy("foo", "bar", { matching: ["*.md", "*.txt"] });
227
228// You can filter previous matches by defining negated pattern further in the order:
229// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'
230// but will skip file '!top-secret.md'.
231jetpack.copy("foo", "bar", { matching: ["*.md", "!top-secret.md"] });
232// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'
233// but will skip all files in 'foo/top-secret' directory.
234jetpack.copy("foo", "bar", { matching: ["*.md", "!top-secret/**/*"] });
235
236// All patterns are anchored to directory you want to copy, not to CWD.
237// So in this example directory 'dir1/dir2/images' will be copied
238// to 'copied-dir2/images'
239jetpack.copy("dir1/dir2", "copied-dir2", {
240 matching: "images/**"
241});
242```
243
244## createReadStream(path, [options])
245
246Just an alias to vanilla [fs.createReadStream](http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options).
247
248## createWriteStream(path, [options])
249
250Just an alias to vanilla [fs.createWriteStream](http://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options).
251
252## cwd([path...])
253
254Returns Current Working Directory (CWD) for this instance of jetpack, or creates new jetpack object with given path as its internal CWD.
255
256**Note:** fs-jetpack never changes value of `process.cwd()`, the CWD we are talking about here is internal value inside every jetpack instance.
257
258**arguments:**
259`path...` (optional) path (or many path parts) to become new CWD. Could be absolute, or relative. If relative path given new CWD will be resolved basing on current CWD of this jetpack instance.
260
261**returns:**
262If `path` not specified, returns CWD path of this jetpack object. For main instance of fs-jetpack it is always `process.cwd()`.
263If `path` specified, returns new jetpack object (totally the same thing as main jetpack). The new object resolves paths according to its internal CWD, not the global one (`process.cwd()`).
264
265**examples:**
266
267```javascript
268// Let's assume that process.cwd() outputs...
269console.log(process.cwd()); // '/one/two/three'
270// jetpack.cwd() will always return the same value as process.cwd()
271console.log(jetpack.cwd()); // '/one/two/three'
272
273// Now let's create new CWD context...
274const jetParent = jetpack.cwd("..");
275console.log(jetParent.cwd()); // '/one/two'
276// ...and use this new context.
277jetParent.dir("four"); // we just created directory '/one/two/four'
278
279// One CWD context can be used to create next CWD context.
280const jetParentParent = jetParent.cwd("..");
281console.log(jetParentParent.cwd()); // '/one'
282
283// When many parameters specified they are treated as parts of path to resolve
284const sillyCwd = jetpack.cwd("a", "b", "c");
285console.log(sillyCwd.cwd()); // '/one/two/three/a/b/c'
286```
287
288## dir(path, [criteria])
289
290asynchronous: **dirAsync(path, [criteria])**
291
292Ensures that directory on given path exists and meets given criteria. If any criterium is not met it will be after this call. If any parent directory in `path` doesn't exist it will be created (like `mkdir -p`).
293
294If the given path already exists but is not a directory, an error will be thrown.
295
296**arguments:**
297`path` path to directory to examine.
298`criteria` (optional) criteria to be met by the directory. Is an `Object` with possible fields:
299
300- `empty` (default: `false`) whether directory should be empty (no other files or directories inside). If set to `true` and directory contains any files or subdirectories all of them will be deleted.
301- `mode` ensures directory has specified mode. If not set and directory already exists, current mode will be preserved. Value could be number (eg. `0o700`) or string (eg. `'700'`).
302
303**returns:**
304New CWD context with directory specified in `path` as CWD (see docs of `cwd()` method for explanation).
305
306**examples:**
307
308```javascript
309// Creates directory if doesn't exist
310jetpack.dir("new-dir");
311
312// Makes sure directory mode is 0700 and that it's empty
313jetpack.dir("empty-dir", { empty: true, mode: "700" });
314
315// Because dir returns new CWD context pointing to just
316// created directory you can create dir chains.
317jetpack
318 .dir("main-dir") // creates 'main-dir'
319 .dir("sub-dir"); // creates 'main-dir/sub-dir'
320```
321
322## exists(path)
323
324asynchronous: **existsAsync(path)**
325
326Checks whether something exists on given `path`. This method returns values more specific than `true/false` to protect from errors like "I was expecting directory, but it was a file".
327
328**returns:**
329
330- `false` if path doesn't exist.
331- `"dir"` if path is a directory.
332- `"file"` if path is a file.
333- `"other"` if none of the above.
334
335## file(path, [criteria])
336
337asynchronous: **fileAsync(path, [criteria])**
338
339Ensures that file exists and meets given criteria. If any criterium is not met it will be after this call. If any parent directory in `path` doesn't exist it will be created (like `mkdir -p`).
340
341**arguments:**
342`path` path to file to examine.
343`criteria` (optional) criteria to be met by the file. Is an `Object` with possible fields:
344
345- `content` sets file content. Can be `String`, `Buffer`, `Object` or `Array`. If `Object` or `Array` given to this parameter data will be written as JSON.
346- `jsonIndent` (defaults to 2) if writing JSON data this tells how many spaces should one indentation have.
347- `mode` ensures file has specified mode. If not set and file already exists, current mode will be preserved. Value could be number (eg. `0o700`) or string (eg. `'700'`).
348
349**returns:**
350Jetpack object you called this method on (self).
351
352**examples:**
353
354```javascript
355// Creates file if doesn't exist
356jetpack.file("something.txt");
357
358// Creates file with mode '777' and content 'Hello World!'
359jetpack.file("hello.txt", { mode: "777", content: "Hello World!" });
360```
361
362## find([path], searchOptions)
363
364asynchronous: **findAsync([path], searchOptions)**
365
366Finds in directory specified by `path` all files fulfilling `searchOptions`. Returned paths are relative to current CWD of jetpack instance.
367
368**arguments:**
369`path` (optional, defaults to `'.'`) path to start search in (all subdirectories will be searched).
370`searchOptions` is an `Object` with possible fields:
371
372- `matching` (default `"*"`) glob patterns of files you want to find ([all possible globs are described further in this readme](#matching-patterns)).
373- `filter` (default `undefined`) function that is called on each matched path with [inspect object](#inspectpath-options) of that path as an argument. Return `true` or `false` to indicate whether given path should stay on list or should be filtered out (see example below).
374- `files` (default `true`) whether or not should search for files.
375- `directories` (default `false`) whether or not should search for directories.
376- `recursive` (default `true`) whether the whole directory tree should be searched recursively, or only one-level of given directory (excluding it's subdirectories).
377- `ignoreCase` (`false` otherwise) whether or not case should be ignored when processing glob patterns passed through the `matching` option.
378
379**returns:**
380`Array` of found paths.
381
382**examples:**
383
384```javascript
385// Finds all files inside 'foo' directory and its subdirectories
386jetpack.find("foo");
387
388// Finds all files which has 2015 in the name
389jetpack.find("my-work", { matching: "*2015*" });
390
391// Finds all '.txt' files inside 'foo/bar' directory and its subdirectories
392jetpack.find("foo", { matching: "bar/**/*.txt" });
393// Finds all '.txt' files inside 'foo/bar' directory WITHOUT subdirectories
394jetpack.find("foo", { matching: "bar/*.txt" });
395
396// Finds all '.txt' files that were modified after 2019-01-01
397const borderDate = new Date("2019-01-01")
398jetpack.find("foo", {
399 matching: "*.txt",
400 filter: (inspectObj) => {
401 return inspectObj.modifyTime > borderDate
402 }
403});
404
405// Finds all '.js' files inside 'my-project' but excluding those in 'vendor' subtree.
406jetpack.find("my-project", { matching: ["*.js", "!vendor/**/*"] });
407
408// Looks for all directories named 'foo' (and will omit all files named 'foo').
409jetpack.find("my-work", { matching: ["foo"], files: false, directories: true });
410
411// Finds all '.txt' files inside 'foo' directory WITHOUT subdirectories
412jetpack.find("foo", { matching: "./*.txt" });
413// This line does the same as the above, but has better performance
414// (skips looking in subdirectories)
415jetpack.find("foo", { matching: "*.txt", recursive: false });
416
417// Path parameter might be omitted and CWD is used as path in that case.
418const myStuffDir = jetpack.cwd("my-stuff");
419myStuffDir.find({ matching: ["*.md"] });
420
421// You can chain find() with different jetpack methods for more power.
422// For example lets delete all `.tmp` files inside `foo` directory
423jetpack
424 .find("foo", {
425 matching: "*.tmp"
426 })
427 .forEach(jetpack.remove);
428```
429
430## inspect(path, [options])
431
432asynchronous: **inspectAsync(path, [options])**
433
434Inspects given path (replacement for `fs.stat`). Returned object by default contains only very basic, not platform-dependent properties (so you have something e.g. your unit tests can rely on), you can enable more properties through options object.
435
436**arguments:**
437`path` path to inspect.
438`options` (optional). Possible values:
439
440- `checksum` if specified will return checksum of inspected file. Possible values are strings `'md5'`, `'sha1'`, `'sha256'` or `'sha512'`. If given path is a directory this field is ignored.
441- `mode` (default `false`) if set to `true` will add file mode (unix file permissions) value.
442- `times` (default `false`) if set to `true` will add atime, mtime and ctime fields (here called `accessTime`, `modifyTime`, `changeTime` and `birthTime`).
443- `absolutePath` (default `false`) if set to `true` will add absolute path to this resource.
444- `symlinks` (default `'report'`) if a given path is a symlink by default `inspect` will report that symlink (not follow it). You can flip this behaviour by setting this option to `'follow'`.
445
446**returns:**
447`undefined` if given path doens't exist.
448Otherwise `Object` of structure:
449
450```javascript
451{
452 name: "my_dir",
453 type: "file", // possible values: "file", "dir", "symlink"
454 size: 123, // size in bytes, this is returned only for files
455 // if checksum option was specified:
456 md5: '900150983cd24fb0d6963f7d28e17f72',
457 // if mode option was set to true:
458 mode: 33204,
459 // if times option was set to true:
460 accessTime: [object Date],
461 modifyTime: [object Date],
462 changeTime: [object Date],
463 birthTime: [object Date]
464}
465```
466
467## inspectTree(path, [options])
468
469asynchronous: **inspectTreeAsync(path, [options])**
470
471Calls [inspect](#inspectpath-options) recursively on given path so it creates tree of all directories and sub-directories inside it.
472
473**arguments:**
474`path` the starting path to inspect.
475`options` (optional). Possible values:
476
477- `checksum` if specified will also calculate checksum of every item in the tree. Possible values are strings `'md5'`, `'sha1'`, `'sha256'` or `'sha512'`. Checksums for directories are calculated as checksum of all children' checksums plus their filenames (see example below).
478- `times` (default `false`) if set to `true` will add atime, mtime and ctime fields (here called `accessTime`, `modifyTime` and `changeTime`) to each tree node.
479- `relativePath` if set to `true` every tree node will have relative path anchored to root inspected folder.
480- `symlinks` (default `'report'`) if a given path is a symlink by default `inspectTree` will report that symlink (not follow it). You can flip this behaviour by setting this option to `'follow'`.
481
482**returns:**
483`undefined` if given path doesn't exist.
484Otherwise tree of inspect objects like:
485
486```javascript
487{
488 name: 'my_dir',
489 type: 'dir',
490 size: 123, // this is combined size of all items in this directory
491 relativePath: '.',
492 md5: '11c68d9ad988ff4d98768193ab66a646',
493 // checksum of this directory was calculated as:
494 // md5(child[0].name + child[0].md5 + child[1].name + child[1].md5)
495 children: [
496 {
497 name: 'empty',
498 type: 'dir',
499 size: 0,
500 relativePath: './dir',
501 md5: 'd41d8cd98f00b204e9800998ecf8427e',
502 children: []
503 },{
504 name: 'file.txt',
505 type: 'file',
506 size: 123,
507 relativePath: './file.txt',
508 md5: '900150983cd24fb0d6963f7d28e17f72'
509 }
510 ]
511}
512```
513
514## list([path])
515
516asynchronous: **listAsync(path)**
517
518Lists the contents of directory. Equivalent of `fs.readdir`.
519
520**arguments:**
521`path` (optional) path to directory you would like to list. If not specified defaults to CWD.
522
523**returns:**
524Array of file names inside given path, or `undefined` if given path doesn't exist.
525
526## move(from, to, [options])
527
528asynchronous: **moveAsync(from, to, [options])**
529
530Moves given path to new location.
531
532**arguments:**
533`from` path to directory or file you want to move.
534`to` path where the thing should be moved.
535`options` (optional) additional options for customization. Is an `Object` with possible fields:
536
537- `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. If `true`, the overwrite will be performed.
538
539**returns:**
540Nothing.
541
542## path(parts...)
543
544Returns path resolved to internal CWD of this jetpack object.
545
546**arguments:**
547`parts` strings to join and resolve as path (as many as you like).
548
549**returns:**
550Resolved path as string.
551
552**examples:**
553
554```javascript
555jetpack.cwd(); // if it returns '/one/two'
556jetpack.path(); // this will return the same '/one/two'
557jetpack.path("three"); // this will return '/one/two/three'
558jetpack.path("..", "four"); // this will return '/one/four'
559```
560
561## read(path, [returnAs])
562
563asynchronous: **readAsync(path, [returnAs])**
564
565Reads content of file.
566
567**arguments:**
568`path` path to file.
569`returnAs` (optional) how the content of file should be returned. Is a string with possible values:
570
571- `'utf8'` (default) content will be returned as UTF-8 String.
572- `'buffer'` content will be returned as a Buffer.
573- `'json'` content will be returned as parsed JSON object.
574- `'jsonWithDates'` content will be returned as parsed JSON object, and date strings in [ISO format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) will be automatically turned into Date objects.
575
576**returns:**
577File content in specified format, or `undefined` if file doesn't exist.
578
579## remove([path])
580
581asynchronous: **removeAsync([path])**
582
583Deletes given path, no matter what it is (file, directory or non-empty directory). If path already doesn't exist terminates gracefully without throwing, so you can use it as 'ensure path doesn't exist'.
584
585**arguments:**
586`path` (optional) path to file or directory you want to remove. If not specified the remove action will be performed on current working directory (CWD).
587
588**returns:**
589Nothing.
590
591**examples:**
592
593```javascript
594// Deletes file
595jetpack.remove("my_work/notes.txt");
596
597// Deletes directory "important_stuff" and everything inside
598jetpack.remove("my_work/important_stuff");
599
600// Remove can be called with no parameters and will default to CWD then.
601// In this example folder 'my_work' will cease to exist.
602const myStuffDir = jetpack.cwd("my_stuff");
603myStuffDir.remove();
604```
605
606## rename(path, newName, [options])
607
608asynchronous: **renameAsync(path, newName, [options])**
609
610Renames given file or directory.
611
612**arguments:**
613`path` path to thing you want to change name of.
614`newName` new name for this thing (not full path, just a name).
615`options` (optional) additional options for customization. Is an `Object` with possible fields:
616
617- `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. If `true`, the overwrite will be performed.
618
619**returns:**
620Nothing.
621
622**examples:**
623
624```javascript
625// The file "my_work/important.md" will be renamed to "my_work/very_important.md"
626jetpack.rename("my_work/important.txt", "very_important.md");
627```
628
629## symlink(symlinkValue, path)
630
631asynchronous: **symlinkAsync(symlinkValue, path)**
632
633Creates symbolic link.
634
635**arguments:**
636`symlinkValue` path where symbolic link should point.
637`path` path where symbolic link should be put.
638
639**returns:**
640Nothing.
641
642## tmpDir([options])
643
644asynchronous: **tmpDirAsync([options])**
645
646Creates temporary directory with random, unique name.
647
648**arguments:**
649`options` (optional) `Object` with possible fields:
650
651- `prefix` prefix to be added to created random directory name. Defaults to none.
652- `basePath` the path where temporary directory should be created. Defaults to [https://nodejs.org/api/os.html#os_os_tmpdir](os.tmpdir).
653
654**returns:**
655New CWD context with temporary directory specified in `path` as CWD (see docs of `cwd()` method for explanation).
656
657**examples:**
658
659```javascript
660// Creates temporary directory, e.g. /tmp/90ed0f0f4a0ba3b1433c5b51ad8fc76b
661// You can interact with this directory by returned CWD context.
662const dirContext = jetpack.tmpDir();
663
664// Creates temporary directory with a prefix, e.g. /tmp/foo_90ed0f0f4a0ba3b1433c5b51ad8fc76b
665jetpack.tmpDir({ prefix: "foo_" });
666
667// Creates temporary directory on given path, e.g. /some/other/path/90ed0f0f4a0ba3b1433c5b51ad8fc76b
668jetpack.tmpDir({ basePath: "/some/other/path" });
669
670// Creates temporary directory on jetpack.cwd() path
671jetpack.tmpDir({ basePath: "." });
672
673// The method returns new jetpack context, so you can easily clean your
674// temp files after you're done.
675const dir = jetpack.tmpDir();
676dir.write("foo.txt", data);
677// ...and when you're done using the dir...
678dir.remove();
679```
680
681## write(path, data, [options])
682
683asynchronous: **writeAsync(path, data, [options])**
684
685Writes data to file. If any parent directory in `path` doesn't exist it will be created (like `mkdir -p`).
686
687**arguments:**
688`path` path to file.
689`data` data to be written. This could be `String`, `Buffer`, `Object` or `Array` (if last two used, the data will be outputted into file as JSON).
690`options` (optional) `Object` with possible fields:
691
692- `mode` file will be created with given mode. Value could be number (eg. `0o700`) or string (eg. `'700'`).
693- `atomic` (default `false`) if set to `true` the file will be written using strategy which is much more resistant to data loss. The trick is very simple, [read this to get the concept](http://stackoverflow.com/questions/17047994/transactionally-writing-files-in-node-js).
694- `jsonIndent` (defaults to 2) if writing JSON data this tells how many spaces should one indentation have.
695
696**returns:**
697Nothing.
698
699# Matching patterns
700
701API methods [copy](#copyfrom-to-options) and [find](#findpath-searchoptions) have `matching` option. Those are all the possible tokens to use there:
702
703- `*` - Matches 0 or more characters in a single path portion.
704- `?` - Matches 1 character.
705- `!` - Used as the first character in pattern will invert the matching logic (match everything what **is not** matched by tokens further in this pattern).
706- `[...]` - Matches a range of characters, similar to a RegExp range. If the first character of the range is `!` or `^` then it matches any character not in the range.
707- `@(pattern|pat*|pat?ern)` - Matches exactly one of the patterns provided.
708- `+(pattern|pat*|pat?ern)` - Matches one or more occurrences of the patterns provided.
709- `?(pattern|pat*|pat?ern)` - Matches zero or one occurrence of the patterns provided.
710- `*(pattern|pat*|pat?ern)` - Matches zero or more occurrences of the patterns provided.
711- `!(pattern|pat*|pat?ern)` - Matches anything that does not match any of the patterns provided.
712- `**` - If a "globstar" is alone in a path portion, then it matches zero or more directories and subdirectories.
713
714_(explanation borrowed from [glob](https://github.com/isaacs/node-glob) which is using [the same matching library](https://github.com/isaacs/minimatch) as this project)_