1 | # async-file
|
2 | Adapts the Node.js File System API (fs) for use with TypeScript async/await
|
3 |
|
4 | This package makes it easier to access the Node.js file system using [TypeScript](http://www.typescriptlang.org/) and [async/await](https://blogs.msdn.microsoft.com/typescript/2015/11/03/what-about-asyncawait/).
|
5 | It wraps the [Node.js File System API](https://nodejs.org/api/fs.html), replacing callback functions with functions that return a Promise.
|
6 |
|
7 | Basically it lets you write your code like this...
|
8 | ```js
|
9 | await fs.unlink('/tmp/hello');
|
10 | console.log('successfully deleted /tmp/hello');
|
11 | ```
|
12 | instead of like this...
|
13 | ```js
|
14 | fs.unlink('/tmp/hello', err => {
|
15 | if (err) throw err;
|
16 | console.log('successfully deleted /tmp/hello');
|
17 | });
|
18 | ```
|
19 |
|
20 |
|
21 | Or like this...
|
22 | ```js
|
23 | await fs.rename('/tmp/hello', '/tmp/world');
|
24 | var stats = await fs.stat('/tmp/hello', '/tmp/world');
|
25 | console.log(`stats: ${JSON.stringify(stats)}`);
|
26 | ```
|
27 | instead of this...
|
28 | ```js
|
29 | fs.rename('/tmp/hello', '/tmp/world', (err) => {
|
30 | if (err) throw err;
|
31 | fs.stat('/tmp/world', (err, stats) => {
|
32 | if (err) throw err;
|
33 | console.log(`stats: ${JSON.stringify(stats)}`);
|
34 | });
|
35 | });
|
36 | ```
|
37 |
|
38 | This package is a drop-in replacement for ```fs``` typings in [node.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/node/node.d.ts)—simply import ```async-file``` instead of fs and call any method within an async function...
|
39 |
|
40 | ```js
|
41 | import * as fs from 'async-file';
|
42 | (async function () {
|
43 | var data = await fs.readFile('data.csv', 'utf8');
|
44 | await fs.rename('/tmp/hello', '/tmp/world');
|
45 | await fs.access('/etc/passd', fs.R_OK | fs.W_OK);
|
46 | await fs.appendFile('message.txt', 'data to append');
|
47 | await fs.unlink('/tmp/hello');
|
48 | })();
|
49 | ```
|
50 |
|
51 | In addition several convenience functions are introduced to simplify accessing text-files, testing for file existance, and creating or deleting files and directories recursively.
|
52 | Other than the modified async function signatures and added convenience functions, the interface of this wrapper is virtually identical to the native Node.js file system library.
|
53 |
|
54 |
|
55 | ## Getting Started
|
56 |
|
57 | Make sure you're running Node v4 and TypeScript 1.8 or higher...
|
58 | ```
|
59 | $ node -v
|
60 | v4.2.6
|
61 | $ npm install -g typescript
|
62 | $ npm install -g tsd
|
63 | $ tsc -v
|
64 | Version 1.8.9
|
65 | ```
|
66 |
|
67 | Install ```async-file``` package and required ```node.d.ts``` dependencies...
|
68 | ```
|
69 | $ npm install async-file
|
70 | $ tsd install node
|
71 | ```
|
72 |
|
73 | Write some code...
|
74 | ```js
|
75 | import * as fs from 'async-file';
|
76 | (async function () {
|
77 | var list = await fs.readdir('.');
|
78 | console.log(list);
|
79 | })();
|
80 | ```
|
81 |
|
82 | Save the above to a file (index.ts), build and run it!
|
83 | ```
|
84 | $ tsc index.ts typings/node/node.d.ts --target es6 --module commonjs
|
85 | $ node index.js
|
86 | [ 'index.js', 'index.ts', 'node_modules', 'typings' ]
|
87 | ```
|
88 |
|
89 | ## Wrapped Functions
|
90 | The following is a list of all wrapped functions...
|
91 |
|
92 | * [```fs.access(path[, mode]): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback)
|
93 | * [```fs.appendFile(file, data[, options]): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_appendfile_file_data_options_callback)
|
94 | * [```fs.chmod(path, mode): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_chmod_path_mode_callback)
|
95 | * [```fs.chown(path, uid, gid): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_chown_path_uid_gid_callback)
|
96 | * [```fs.close(fd): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_close_fd_callback)
|
97 | * [```fs.fchmod(fd, mode): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_fchmod_fd_mode_callback)
|
98 | * [```fs.fchown(fd, uid, gid): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_fchown_fd_uid_gid_callback)
|
99 | * [```fs.fstat(fd): Promise<Stats>```](https://nodejs.org/api/fs.html#fs_fs_fstat_fd_callback)
|
100 | * [```fs.fsync(fd): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_fsync_fd_callback)
|
101 | * [```fs.ftruncate(fd, len): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_ftruncate_fd_len_callback)
|
102 | * [```fs.futimes(fd, atime, mtime): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_futimes_fd_atime_mtime_callback)
|
103 | * [```fs.lchmod(path, mode): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_lchmod_path_mode_callback)
|
104 | * [```fs.lchown(path, uid, gid): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_lchown_path_uid_gid_callback)
|
105 | * [```fs.link(srcpath, dstpath): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_link_srcpath_dstpath_callback)
|
106 | * [```fs.lstat(path): Promise<Stats>```](https://nodejs.org/api/fs.html#fs_fs_lstat_path_callback)
|
107 | * [```fs.mkdir(path[, mode]): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_mkdir_path_mode_callback)
|
108 | * [```fs.mkdtemp(prefix): Promise<string>```](https://nodejs.org/api/fs.html#fs_fs_mkdtemp_prefix_callback)
|
109 | * [```fs.open(path, flags[, mode]): Promise<number>```](https://nodejs.org/api/fs.html#fs_fs_open_path_flags_mode_callback)
|
110 | * [```fs.read(fd, buffer, offset, length, position): Promise<ReadResult>```](https://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback)
|
111 | * [```fs.readdir(path): Promise<string[]>```](https://nodejs.org/api/fs.html#fs_fs_readdir_path_callback)
|
112 | * [```fs.readFile(file[, options]): Promise<any>```](https://nodejs.org/api/fs.html#fs_fs_readfile_file_options_callback)
|
113 | * [```fs.readlink(path): Promise<string>```](https://nodejs.org/api/fs.html#fs_fs_readlink_path_callback)
|
114 | * [```fs.realpath(path[, cache]): Promise<string>```](https://nodejs.org/api/fs.html#fs_fs_realpath_path_cache_callback)
|
115 | * [```fs.rename(oldPath, newPath): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback)
|
116 | * [```fs.rmdir(path): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_rmdir_path_callback)
|
117 | * [```fs.stat(path): Promise<Stats>```](https://nodejs.org/api/fs.html#fs_fs_stat_path_callback)
|
118 | * [```fs.symlink(target, path[, type]): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_symlink_target_path_type_callback)
|
119 | * [```fs.truncate(path, len): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_truncate_path_len_callback)
|
120 | * [```fs.unlink(path): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_unlink_path_callback)
|
121 | * [```fs.utimes(path, atime, mtime): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_utimes_path_atime_mtime_callback)
|
122 | * [```fs.write(fd, buffer, offset, length[, position]): Promise<WriteResult>```](https://nodejs.org/api/fs.html#fs_fs_write_fd_data_position_encoding_callback)
|
123 | * [```fs.write(fd, data[, position[, encoding]]): Promise<WriteResult>```](https://nodejs.org/api/fs.html#fs_fs_write_fd_data_position_encoding_callback)
|
124 | * [```fs.writeFile(file, data[, options]): Promise<void>```](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback)
|
125 |
|
126 | ## Convenience Functions
|
127 | In addition to the wrapped functions above, the following convenience functions are provided...
|
128 |
|
129 | * ```fs.createDirectory(path[, mode]): Promise<void>```
|
130 | * ```fs.delete(path): Promise<void>```
|
131 | * ```fs.exists(path): Promise<boolean>```
|
132 | * ```fs.readTextFile(file[, encoding, flags]): Promise<string>```
|
133 | * ```fs.writeTextFile(file, data[, encoding, mode]): Promise<void>```
|
134 | * ```fs.mkdirp(path): Promise<void>```
|
135 | * ```fs.rimraf(path): Promise<void>```
|
136 |
|
137 | ```fs.createDirectory``` creates a directory recursively *(like [mkdirp](https://www.npmjs.com/package/mkdirp))*.
|
138 |
|
139 | ```fs.delete``` deletes any file or directory, performing a deep delete on non-empty directories *(wraps [rimraf](https://www.npmjs.com/package/rimraf))*.
|
140 |
|
141 | ```fs.exists``` implements the recommended solution of opening the file and returning ```true``` when the ```ENOENT``` error results.
|
142 |
|
143 | ```fs.readTextFile``` and ```fs.writeTextFile``` are optimized for simple text-file access, dealing exclusively with strings not buffers or streaming.
|
144 |
|
145 | ```fs.mkdirp``` and ```fs.rimraf``` are aliases for ```fs.createDirectory``` and ```fs.delete``` respectively, for those prefering more esoteric nomenclature.
|
146 |
|
147 | ### Convenience Function Examples
|
148 |
|
149 | Read a series of three text files, one at a time...
|
150 | ```js
|
151 | var data1 = await fs.readTextFile('data1.csv');
|
152 | var data2 = await fs.readTextFile('data2.csv');
|
153 | var data3 = await fs.readTextFile('data3.csv');
|
154 | ```
|
155 |
|
156 | Append a line into an arbitrary series of text files...
|
157 | ```js
|
158 | var files = ['data1.log', 'data2.log', 'data3.log'];
|
159 | for (var file of files)
|
160 | await fs.writeTextFile(file, '\nPASSED!\n', null, 'a');
|
161 | ```
|
162 |
|
163 | Check for the existance of a file...
|
164 | ```js
|
165 | if (!(await fs.exists('config.json')))
|
166 | console.warn('Configuration file not found');
|
167 | ```
|
168 |
|
169 | Create a directory...
|
170 | ```js
|
171 | await fs.createDirectory('/tmp/path/to/file');
|
172 | ```
|
173 |
|
174 | Delete a file or or directory...
|
175 | ```js
|
176 | await fs.delete('/tmp/path/to/file');
|
177 | ```
|
178 |
|
179 |
|
180 | ## Additional Notes
|
181 |
|
182 | If access to both the native Node.js file system library and the wrapper is required at the same time *(e.g. to mix callbacks alongside async/await code)*, specify a different name in the import statement of the wrapper...
|
183 | ```js
|
184 | import * as fs from 'fs';
|
185 | import * as afs from 'async-file';
|
186 | await afs.rename('/tmp/hello', '/tmp/world');
|
187 | fs.unlink('/tmp/hello', err =>
|
188 | console.log('/tmp/hello deleted', err));
|
189 | });
|
190 | ```
|
191 |
|
192 | By design none of *"sync"* functions are exposed by the wrapper: fs.readFileSync, fs.writeFileSync, etc.
|
193 |
|
194 | ## Related Wrappers
|
195 | Here are some other TypeScript async/await wrappers you may find useful...
|
196 |
|
197 | * [**async-parallel**](https://www.npmjs.com/package/async-parallel) simplifies invoking tasks in parallel
|
198 | * [**web-request**](https://www.npmjs.com/package/web-request) simplifies making web requests
|
199 | * [**async-fx**](https://www.npmjs.com/package/async-fx) bundles async-file, web-request, and async-parallel together in a single package |
\ | No newline at end of file |