pwd-fs 2.4.2 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.travis.yml +2 -3
  2. package/appveyor.yml +2 -4
  3. package/lib/src/index.d.ts +4 -186
  4. package/lib/src/index.js +18 -294
  5. package/lib/src/powered-file-system.d.ts +156 -0
  6. package/lib/src/powered-file-system.js +264 -0
  7. package/lib/src/recurse-io-sync.d.ts +10 -5
  8. package/lib/src/recurse-io-sync.js +74 -69
  9. package/lib/src/recurse-io.d.ts +14 -6
  10. package/lib/src/recurse-io.js +164 -160
  11. package/lib/test/__fmock.d.ts +5 -0
  12. package/lib/test/__fmock.js +40 -0
  13. package/lib/test/append.spec.js +36 -77
  14. package/lib/test/bitmask.spec.js +14 -17
  15. package/lib/test/chmod.spec.js +42 -84
  16. package/lib/test/chown.spec.js +45 -71
  17. package/lib/test/constructor.spec.js +7 -10
  18. package/lib/test/copy.spec.js +53 -108
  19. package/lib/test/mkdir.spec.js +62 -119
  20. package/lib/test/read.spec.js +47 -78
  21. package/lib/test/readdir.spec.js +48 -90
  22. package/lib/test/remove.spec.js +44 -65
  23. package/lib/test/rename.spec.js +43 -75
  24. package/lib/test/stat.spec.js +50 -78
  25. package/lib/test/symlink.spec.js +51 -95
  26. package/lib/test/test.spec.js +37 -66
  27. package/lib/test/write.spec.js +52 -103
  28. package/package.json +8 -11
  29. package/readme.md +10 -21
  30. package/src/index.ts +4 -623
  31. package/src/powered-file-system.ts +527 -0
  32. package/src/recurse-io-sync.ts +77 -71
  33. package/src/recurse-io.ts +181 -176
  34. package/test/__fmock.ts +45 -0
  35. package/test/append.spec.ts +44 -98
  36. package/test/bitmask.spec.ts +14 -17
  37. package/test/chmod.spec.ts +45 -95
  38. package/test/chown.spec.ts +61 -93
  39. package/test/constructor.spec.ts +4 -7
  40. package/test/copy.spec.ts +72 -142
  41. package/test/mkdir.spec.ts +87 -153
  42. package/test/read.spec.ts +64 -103
  43. package/test/readdir.spec.ts +65 -113
  44. package/test/remove.spec.ts +58 -82
  45. package/test/rename.spec.ts +58 -96
  46. package/test/stat.spec.ts +68 -100
  47. package/test/symlink.spec.ts +74 -125
  48. package/test/test.spec.ts +51 -84
  49. package/test/write.spec.ts +68 -131
  50. package/tsconfig.json +14 -7
  51. package/lib/src/index.js.map +0 -1
  52. package/lib/src/recurse-io-sync.js.map +0 -1
  53. package/lib/src/recurse-io.js.map +0 -1
  54. package/lib/test/append.spec.js.map +0 -1
  55. package/lib/test/bitmask.spec.js.map +0 -1
  56. package/lib/test/chmod.spec.js.map +0 -1
  57. package/lib/test/chown.spec.js.map +0 -1
  58. package/lib/test/constructor.spec.js.map +0 -1
  59. package/lib/test/copy.spec.js.map +0 -1
  60. package/lib/test/mkdir.spec.js.map +0 -1
  61. package/lib/test/read.spec.js.map +0 -1
  62. package/lib/test/readdir.spec.js.map +0 -1
  63. package/lib/test/remove.spec.js.map +0 -1
  64. package/lib/test/rename.spec.js.map +0 -1
  65. package/lib/test/stat.spec.js.map +0 -1
  66. package/lib/test/symlink.spec.js.map +0 -1
  67. package/lib/test/test.spec.js.map +0 -1
  68. package/lib/test/write.spec.js.map +0 -1
package/src/recurse-io.ts CHANGED
@@ -1,234 +1,239 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
3
 
4
- type Files = Array<string>
4
+ export type Files = Array<string>;
5
+ export type NoParamCallback = fs.NoParamCallback;
5
6
 
6
- const {sep} = path;
7
+ const { sep } = path;
7
8
 
8
- export default {
9
- chmod(src: string, mode: number, callback: fs.NoParamCallback): void {
10
- let reduce = 0;
11
-
12
- fs.stat(src, (err, stat) => {
13
- if (err) {
14
- return callback(err);
15
- }
16
-
17
- if (stat.isDirectory()) {
18
- fs.readdir(src, (err, list) => {
19
- if (err) {
20
- return callback(err);
21
- }
9
+ function chmod(src: string, mode: number, callback: NoParamCallback) {
10
+ let reduce = 0;
22
11
 
23
- if (list.length === 0) {
24
- return fs.chmod(src, mode, callback);
25
- }
12
+ fs.stat(src, (err, stat) => {
13
+ if (err) {
14
+ return callback(err);
15
+ }
26
16
 
27
- reduce += list.length;
17
+ if (stat.isDirectory()) {
18
+ fs.readdir(src, (err, list) => {
19
+ if (err) {
20
+ return callback(err);
21
+ }
28
22
 
29
- for (const loc of list) {
30
- this.chmod(`${src}${sep}${loc}`, mode, (err) => {
31
- if (err) {
32
- return callback(err);
33
- }
23
+ if (list.length === 0) {
24
+ return fs.chmod(src, mode, callback);
25
+ }
34
26
 
35
- if (--reduce === 0) {
36
- fs.chmod(src, mode, callback);
37
- }
38
- });
39
- }
40
- });
41
- }
42
- else {
43
- fs.chmod(src, mode, callback);
44
- }
45
- });
46
- },
47
-
48
- chown(src: string, uid: number, gid: number, callback: fs.NoParamCallback): void {
49
- let reduce = 0;
50
-
51
- fs.stat(src, (err, stats) => {
52
- if (err) {
53
- return callback(err);
54
- }
55
-
56
- if (stats.isDirectory()) {
57
- fs.readdir(src, (err, list) => {
58
- if (err) {
59
- return callback(err);
60
- }
27
+ reduce += list.length;
61
28
 
62
- if (list.length === 0) {
63
- return fs.chown(src, uid, gid, callback);
64
- }
29
+ for (const loc of list) {
30
+ chmod(`${src}${sep}${loc}`, mode, (err) => {
31
+ if (err) {
32
+ return callback(err);
33
+ }
65
34
 
66
- reduce += list.length;
35
+ if (--reduce === 0) {
36
+ fs.chmod(src, mode, callback);
37
+ }
38
+ });
39
+ }
40
+ });
41
+ }
42
+ else {
43
+ fs.chmod(src, mode, callback);
44
+ }
45
+ });
46
+ }
67
47
 
68
- for (const loc of list) {
69
- this.chown(`${src}${sep}${loc}`, uid, gid, (err) => {
70
- if (err) {
71
- return callback(err);
72
- }
48
+ function chown(src: string, uid: number, gid: number, callback: NoParamCallback) {
49
+ let reduce = 0;
73
50
 
74
- if (--reduce === 0) {
75
- fs.chown(src, uid, gid, callback);
76
- }
77
- });
78
- }
79
- });
80
- }
81
- else {
82
- fs.chown(src, uid, gid, callback);
83
- }
84
- });
85
- },
86
-
87
- copy(src: string, dir: string, umask: number, callback: fs.NoParamCallback): void {
88
- let reduce = 0;
89
-
90
- fs.stat(src, (err, stat) => {
91
- if (err) {
92
- return callback(err);
93
- }
94
-
95
- if (stat.isDirectory()) {
96
- fs.readdir(src, (err, list) => {
97
- if (err) {
98
- return callback(err);
99
- }
51
+ fs.stat(src, (err, stats) => {
52
+ if (err) {
53
+ return callback(err);
54
+ }
100
55
 
101
- reduce += list.length;
56
+ if (stats.isDirectory()) {
57
+ fs.readdir(src, (err, list) => {
58
+ if (err) {
59
+ return callback(err);
60
+ }
102
61
 
103
- const paths = src.split(sep);
104
- const loc = paths[paths.length - 1];
105
- const mode = 0o777 - umask;
62
+ if (list.length === 0) {
63
+ return fs.chown(src, uid, gid, callback);
64
+ }
106
65
 
107
- dir = `${dir}${sep}${loc}`;
66
+ reduce += list.length;
108
67
 
109
- fs.mkdir(dir, { mode }, (err) => {
68
+ for (const loc of list) {
69
+ chown(`${src}${sep}${loc}`, uid, gid, (err) => {
110
70
  if (err) {
111
71
  return callback(err);
112
72
  }
113
73
 
114
- if (reduce === 0) {
115
- return callback(null);
116
- }
117
-
118
- for (const loc of list) {
119
- this.copy(`${src}${sep}${loc}`, dir, umask, (err) => {
120
- if (err) {
121
- return callback(err);
122
- }
123
-
124
- if (--reduce === 0) {
125
- callback(null);
126
- }
127
- });
74
+ if (--reduce === 0) {
75
+ fs.chown(src, uid, gid, callback);
128
76
  }
129
77
  });
130
- });
131
- }
132
- else {
133
- const mode = 0o666 - umask;
134
- const loc = path.basename(src);
135
-
136
- const readStream = fs.createReadStream(src);
137
- const writeStream = fs.createWriteStream(`${dir}${sep}${loc}`, {
138
- mode
139
- });
78
+ }
79
+ });
80
+ }
81
+ else {
82
+ fs.chown(src, uid, gid, callback);
83
+ }
84
+ });
85
+ }
140
86
 
141
- readStream.on('error', callback);
142
- writeStream.on('error', callback);
87
+ function copy(src: string, dir: string, umask: number, callback: NoParamCallback) {
88
+ let reduce = 0;
143
89
 
144
- writeStream.on('close', () => {
145
- callback(null);
146
- });
90
+ fs.stat(src, (err, stat) => {
91
+ if (err) {
92
+ return callback(err);
93
+ }
147
94
 
148
- readStream.pipe(writeStream);
149
- }
150
- });
151
- },
95
+ if (stat.isDirectory()) {
96
+ fs.readdir(src, (err, list) => {
97
+ if (err) {
98
+ return callback(err);
99
+ }
152
100
 
153
- remove(src: string, callback: fs.NoParamCallback): void {
154
- let reduce = 0;
101
+ reduce += list.length;
155
102
 
156
- fs.stat(src, (err, stat) => {
157
- if (err) {
158
- return callback(err);
159
- }
103
+ const paths = src.split(sep);
104
+ const loc = paths[paths.length - 1];
105
+ const mode = 0o777 - umask;
160
106
 
161
- if (stat.isDirectory()) {
162
- fs.readdir(src, (err, list) => {
107
+ dir = `${dir}${sep}${loc}`;
108
+
109
+ fs.mkdir(dir, { mode }, (err) => {
163
110
  if (err) {
164
111
  return callback(err);
165
112
  }
166
113
 
167
- if (list.length === 0) {
168
- return fs.rmdir(src, callback);
114
+ if (reduce === 0) {
115
+ return callback(null);
169
116
  }
170
117
 
171
- reduce += list.length;
172
-
173
118
  for (const loc of list) {
174
- this.remove(`${src}${sep}${loc}`, (err) => {
119
+ copy(`${src}${sep}${loc}`, dir, umask, (err) => {
175
120
  if (err) {
176
121
  return callback(err);
177
122
  }
178
123
 
179
124
  if (--reduce === 0) {
180
- fs.rmdir(src, callback);
125
+ callback(null);
181
126
  }
182
127
  });
183
128
  }
184
129
  });
185
- }
186
- else {
187
- fs.unlink(src, callback);
188
- }
189
- });
190
- },
191
-
192
- mkdir(dir: string, umask: number, callback: fs.NoParamCallback): void {
193
- const cwd = process.cwd();
194
-
195
- if (dir === cwd) {
196
- return callback(null);
130
+ });
197
131
  }
132
+ else {
133
+ const mode = 0o666 - umask;
134
+ const loc = path.basename(src);
198
135
 
199
- const sequence = function* (dir: string, files: Files, mode: number): Generator<void, void, Generator> {
200
- const iter = yield;
136
+ const readStream = fs.createReadStream(src);
137
+ const writeStream = fs.createWriteStream(`${dir}${sep}${loc}`, {
138
+ mode
139
+ });
201
140
 
202
- for (const item of files) {
203
- dir += `${sep}${item}`;
141
+ readStream.on('error', callback);
142
+ writeStream.on('error', callback);
204
143
 
205
- fs.mkdir(dir, { mode }, (err) => {
206
- if (err && err.errno !== -17) {
207
- return callback(err);
208
- }
144
+ writeStream.on('close', () => {
145
+ callback(null);
146
+ });
209
147
 
210
- iter.next();
211
- });
148
+ readStream.pipe(writeStream);
149
+ }
150
+ });
151
+ }
152
+
153
+ function remove(src: string, callback: NoParamCallback) {
154
+ fs.stat(src, (err, stat) => {
155
+ if (err) {
156
+ return callback(err);
157
+ }
158
+
159
+ if (stat.isDirectory()) {
160
+ fs.readdir(src, (err, list) => {
161
+ if (err) {
162
+ return callback(err);
163
+ }
164
+
165
+ let reduce = list.length;
212
166
 
213
- yield;
214
- }
167
+ if (reduce === 0) {
168
+ return fs.rmdir(src, callback);
169
+ }
215
170
 
216
- callback(null);
217
- };
171
+ for (const loc of list) {
172
+ remove(`${src}${sep}${loc}`, (err) => {
173
+ if (err) {
174
+ return callback(err);
175
+ }
218
176
 
219
- let use = '';
177
+ if (--reduce === 0) {
178
+ fs.rmdir(src, callback);
179
+ }
180
+ });
181
+ }
182
+ });
183
+ }
184
+ else {
185
+ fs.unlink(src, callback);
186
+ }
187
+ });
188
+ }
189
+
190
+ function mkdir(dir: string, umask: number, callback: NoParamCallback) {
191
+ const cwd = process.cwd();
192
+
193
+ if (dir === cwd) {
194
+ return callback(null);
195
+ }
220
196
 
221
- if (dir.indexOf(cwd) === 0) {
222
- use = cwd;
223
- dir = dir.substr(cwd.length);
197
+ const sequence = function* (dir: string, files: Files, mode: number): Generator<void, void, Generator> {
198
+ const iter = yield;
199
+
200
+ for (const item of files) {
201
+ dir += `${sep}${item}`;
202
+
203
+ fs.mkdir(dir, { mode }, (err) => {
204
+ if (err && err.errno !== -17) {
205
+ return callback(err);
206
+ }
207
+
208
+ iter.next();
209
+ });
210
+
211
+ yield;
224
212
  }
225
213
 
226
- const files = dir.split(sep);
227
- const mode = 0o777 - umask;
214
+ callback(null);
215
+ };
228
216
 
229
- const iter = sequence(use, files, mode);
217
+ let use = '';
230
218
 
231
- iter.next();
232
- iter.next(iter);
219
+ if (dir.indexOf(cwd) === 0) {
220
+ use = cwd;
221
+ dir = dir.substr(cwd.length);
233
222
  }
223
+
224
+ const files = dir.split(sep);
225
+ const mode = 0o777 - umask;
226
+
227
+ const iter = sequence(use, files, mode);
228
+
229
+ iter.next();
230
+ iter.next(iter);
231
+ }
232
+
233
+ export default {
234
+ chmod,
235
+ chown,
236
+ copy,
237
+ remove,
238
+ mkdir
234
239
  }
@@ -0,0 +1,45 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export interface Iframe {
5
+ [key: string]: any
6
+ }
7
+
8
+ export function fmock(frame: Iframe) {
9
+ for (const src of Object.keys(frame)) {
10
+ const { dir } = path.parse(src);
11
+ const value = frame[src];
12
+
13
+ fs.mkdirSync(dir, { recursive: true });
14
+
15
+ if (value.type === 'directory') {
16
+ fs.mkdirSync(src);
17
+ }
18
+
19
+ if (value.type === 'file') {
20
+ fs.writeFileSync(src, value.data);
21
+ }
22
+
23
+ if (value.type === 'symlink') {
24
+ fs.symlinkSync(value.target, src);
25
+ }
26
+ }
27
+ }
28
+
29
+ export function restore(tmpDir: string) {
30
+ const removeRecursive = (src: string) => {
31
+ if (fs.existsSync(src)) {
32
+ fs.readdirSync(src).forEach((item) => {
33
+ const curl = `${src}/${item}`;
34
+
35
+ fs.lstatSync(curl).isDirectory()
36
+ ? removeRecursive(curl)
37
+ : fs.unlinkSync(curl);
38
+ });
39
+
40
+ fs.rmdirSync(src);
41
+ }
42
+ };
43
+
44
+ removeRecursive(tmpDir);
45
+ }
@@ -1,125 +1,71 @@
1
- import assert from 'assert';
2
- import { sep } from 'path';
3
- import mockFs from 'mock-fs';
1
+ import assert from 'node:assert';
2
+ import fs from 'node:fs';
4
3
  import Chance from 'chance';
5
- import PoweredFileSystem from '../src';
4
+ import { expect } from 'expect';
5
+ import { fmock, restore } from './__fmock';
6
+ import { pfs } from '../src';
6
7
 
7
8
  describe('append(src, data [, options])', () => {
8
- beforeEach(() => {
9
- const chance = new Chance();
9
+ const chance = new Chance();
10
10
 
11
- mockFs({
12
- 'tmpdir': {
13
- 'binapp': chance.string(),
14
- 'libxbase': mockFs.directory()
15
- },
16
- 'flexapp': mockFs.symlink({
17
- path: 'tmpdir/binapp'
18
- })
11
+ beforeEach(() => {
12
+ fmock({
13
+ './tmpdir/tings.txt': {
14
+ type: 'file',
15
+ data: 'hoodie'
16
+ }
19
17
  });
20
18
  });
19
+
20
+ afterEach(() => {
21
+ restore('./tmpdir');
22
+ });
21
23
 
22
- afterEach(mockFs.restore);
23
24
 
24
25
  it('Positive: Must append content to file', async () => {
25
- const pfs = new PoweredFileSystem();
26
- const chance = new Chance();
26
+ const payload = chance.paragraph();
27
27
 
28
- const before = await pfs.stat('./tmpdir/binapp');
28
+ await pfs.append('./tmpdir/tings.txt', payload);
29
+ const { size } = fs.statSync('./tmpdir/tings.txt');
29
30
 
30
- const payload = chance.string();
31
- await pfs.append('./tmpdir/binapp', payload);
32
-
33
- const after = await pfs.stat('./tmpdir/binapp');
34
-
35
- assert(after.size > before.size);
31
+ assert(payload.length + 6 === size);
36
32
  });
37
33
 
38
- it('Positive: Must append content to file when path is absolute', async () => {
39
- const pfs = new PoweredFileSystem();
40
- const chance = new Chance();
41
-
42
- const before = await pfs.stat('./tmpdir/binapp');
43
-
44
- const cwd = process.cwd();
45
- const payload = chance.string();
46
-
47
- await pfs.append(`${cwd}${sep}tmpdir${sep}binapp`, payload, {
48
- resolve: false
49
- });
50
-
51
- const after = await pfs.stat('./tmpdir/binapp');
52
-
53
- assert(after.size > before.size);
54
- });
55
34
 
56
35
  it(`Negative: Unexpected option 'flag' returns Error`, async () => {
57
- const pfs = new PoweredFileSystem();
58
- const chance = new Chance();
59
-
60
- try {
61
- const payload = chance.string();
62
-
63
- await pfs.append('./tmpdir/binapp', payload, {
36
+ const payload = chance.paragraph();
37
+
38
+ await expect(async () => {
39
+ await pfs.append('./tmpdir/tings.txt', payload, {
64
40
  flag: 'r'
65
41
  });
66
- }
67
- catch (err) {
68
- assert(err.errno === -9);
69
- }
42
+ })
43
+ .rejects
44
+ .toThrow();
70
45
  });
46
+
47
+
48
+ it(`[sync] Positive: Must append content to file`, () => {
49
+ const payload = chance.paragraph();
71
50
 
72
- describe('sync mode', () => {
73
- it(`Positive: Must append content to file`, async () => {
74
- const pfs = new PoweredFileSystem();
75
- const chance = new Chance();
76
-
77
- const before = await pfs.stat('./tmpdir/binapp');
78
- const payload = chance.string();
79
-
80
- pfs.append('./tmpdir/binapp', payload, {
81
- sync: true
82
- });
83
-
84
- const after = await pfs.stat('./tmpdir/binapp');
85
-
86
- assert(after.size > before.size);
51
+ pfs.append('./tmpdir/tings.txt', payload, {
52
+ sync: true
87
53
  });
88
54
 
89
- it('Positive: Must append content to file when path is absolute', async () => {
90
- const pfs = new PoweredFileSystem();
91
- const chance = new Chance();
55
+ const { size } = fs.statSync('./tmpdir/tings.txt');
92
56
 
93
- const before = await pfs.stat('./tmpdir/binapp');
94
-
95
- const cwd = process.cwd();
96
- const payload = chance.string();
97
-
98
- pfs.append(`${cwd}${sep}tmpdir${sep}binapp`, payload, {
57
+ assert(payload.length + 6 === size);
58
+ });
59
+
60
+
61
+ it(`[sync] Negative: Unexpected option 'flag' returns Error`, () => {
62
+ const payload = chance.paragraph();
63
+
64
+ assert.throws(() => {
65
+ pfs.append('./tmpdir/tings.txt', payload, {
99
66
  sync: true,
100
- resolve: false
67
+ flag: 'r'
101
68
  });
102
-
103
- const after = await pfs.stat('./tmpdir/binapp');
104
-
105
- assert(after.size > before.size);
106
- });
107
-
108
- it(`Negative: Unexpected option 'flag' returns Error`, async () => {
109
- const pfs = new PoweredFileSystem();
110
- const chance = new Chance();
111
-
112
- try {
113
- const payload = chance.string();
114
-
115
- pfs.append('./tmpdir/binapp', payload, {
116
- sync: true,
117
- flag: 'r'
118
- });
119
- }
120
- catch (err) {
121
- assert(err.errno === -9);
122
- }
123
69
  });
124
70
  });
125
71
  });
@@ -1,26 +1,23 @@
1
- import assert from 'assert';
2
- import PoweredFileSystem from '../src';
1
+ import assert from 'node:assert';
2
+ import { bitmask } from '../src';
3
3
 
4
4
  describe('static bitmask(mode: number)', () => {
5
5
  it('Positive: Calculate bitmask', () => {
6
- assert(PoweredFileSystem.bitmask(33024) === 0o400); // (r--------)
7
- assert(PoweredFileSystem.bitmask(33152) === 0o600); // (rw-------)
8
- assert(PoweredFileSystem.bitmask(33216) === 0o700); // (rwx------)
9
- assert(PoweredFileSystem.bitmask(32800) === 0o040); // (---r-----)
10
- assert(PoweredFileSystem.bitmask(32816) === 0o060); // (---rw----)
11
- assert(PoweredFileSystem.bitmask(32824) === 0o070); // (---rwx---)
12
- assert(PoweredFileSystem.bitmask(32772) === 0o004); // (------r--)
13
- assert(PoweredFileSystem.bitmask(32774) === 0o006); // (------rw-)
14
- assert(PoweredFileSystem.bitmask(32775) === 0o007); // (------rwx)
6
+ assert(bitmask(33024) === 0o400); // (r--------)
7
+ assert(bitmask(33152) === 0o600); // (rw-------)
8
+ assert(bitmask(33216) === 0o700); // (rwx------)
9
+ assert(bitmask(32800) === 0o040); // (---r-----)
10
+ assert(bitmask(32816) === 0o060); // (---rw----)
11
+ assert(bitmask(32824) === 0o070); // (---rwx---)
12
+ assert(bitmask(32772) === 0o004); // (------r--)
13
+ assert(bitmask(32774) === 0o006); // (------rw-)
14
+ assert(bitmask(32775) === 0o007); // (------rwx)
15
15
  });
16
16
 
17
17
  it(`Negative: Throw an exception if the argument is 'null' type`, () => {
18
- try {
18
+ assert.throws(() => {
19
19
  // @ts-ignore
20
- PoweredFileSystem.bitmask(null);
21
- }
22
- catch (err) {
23
- assert(err);
24
- }
20
+ bitmask(null);
21
+ });
25
22
  });
26
23
  });