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
@@ -0,0 +1,527 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import recurse, { Files, NoParamCallback } from './recurse-io';
4
+ import recurseSync from './recurse-io-sync';
5
+
6
+ export type Mode = keyof IConstants;
7
+ export type Flag = Mode | 'a';
8
+ export type Stats = fs.Stats;
9
+
10
+ export interface IConstants {
11
+ e: number,
12
+ r: number,
13
+ w: number,
14
+ x: number
15
+ }
16
+
17
+ const permissions: number[] = [
18
+ 0o400, // OWNER_READ
19
+ 0o200, // OWNER_WRITE
20
+ 0o100, // OWNER_EXECUTE
21
+ 0o040, // GROUP_READ
22
+ 0o020, // GROUP_WRITE
23
+ 0o010, // GROUP_EXECUTE
24
+ 0o004, // OTHERS_READ
25
+ 0o002, // OTHERS_WRITE
26
+ 0o001 // OTHERS_EXECUTE
27
+ ];
28
+
29
+ export function bitmask(mode: number) {
30
+ const type = typeof mode;
31
+
32
+ if (type !== 'number') {
33
+ throw new Error(
34
+ `Argument of type '${type}' is not assignable to parameter of type 'number'.`
35
+ );
36
+ }
37
+
38
+ let umask = 0o000;
39
+
40
+ for (const flag of permissions) {
41
+ if (mode & flag) {
42
+ umask += flag;
43
+ }
44
+ }
45
+
46
+ return umask;
47
+ }
48
+
49
+ export class PoweredFileSystem {
50
+ readonly pwd: string;
51
+
52
+ readonly constants: IConstants = {
53
+ e: fs.constants.F_OK,
54
+ r: fs.constants.R_OK,
55
+ w: fs.constants.W_OK,
56
+ x: fs.constants.X_OK
57
+ };
58
+
59
+ static bitmask = bitmask;
60
+
61
+ constructor(pwd?: string) {
62
+ this.pwd = pwd ? path.resolve(pwd) : process.cwd();
63
+ }
64
+
65
+ private resolve(src: string) {
66
+ return path.resolve(this.pwd, src);
67
+ }
68
+
69
+ test(src: string, options: {
70
+ sync: true,
71
+ flag?: Mode
72
+ }): boolean;
73
+
74
+ test(src: string, options?: {
75
+ sync?: false,
76
+ flag?: Mode
77
+ }): Promise<boolean>;
78
+
79
+ test(src: string, { sync = false, flag = 'e' }: {
80
+ sync?: boolean,
81
+ flag?: Mode
82
+ } = {}) {
83
+ const mode = this.constants[flag];
84
+
85
+ src = path.resolve(this.pwd, src);
86
+
87
+ if (sync) {
88
+ return fs.existsSync(src);
89
+ }
90
+
91
+ return new Promise((resolve) => {
92
+ fs.access(src, mode, (err) => {
93
+ if (err) {
94
+ return resolve(false);
95
+ }
96
+
97
+ resolve(true);
98
+ });
99
+ });
100
+ }
101
+
102
+ stat(src: string, options: { sync: true }): Stats;
103
+
104
+ stat(src: string, options?: { sync?: false }): Promise<Stats>;
105
+
106
+ stat(src: string, { sync = false }: { sync?: boolean } = {}) {
107
+ src = this.resolve(src);
108
+
109
+ if (sync) {
110
+ return fs.lstatSync(src);
111
+ }
112
+
113
+ return new Promise((resolve, reject) => {
114
+ fs.lstat(src, (err, stats) => {
115
+ if (err) {
116
+ return reject(err);
117
+ }
118
+
119
+ resolve(stats);
120
+ });
121
+ });
122
+ }
123
+
124
+ chmod(src: string, mode: number, options: {
125
+ sync: true
126
+ }): void;
127
+
128
+ chmod(src: string, mode: number, options?: {
129
+ sync?: false
130
+ }): Promise<void>;
131
+
132
+ chmod(src: string, mode: number, { sync = false }: { sync?: boolean } = {}) {
133
+ src = this.resolve(src);
134
+
135
+ if (sync) {
136
+ return recurseSync.chmod(src, mode);
137
+ }
138
+
139
+ return new Promise<void>((resolve, reject) => {
140
+ recurse.chmod(src, mode, (err) => {
141
+ if (err) {
142
+ return reject(err);
143
+ }
144
+
145
+ resolve();
146
+ });
147
+ });
148
+ }
149
+
150
+ chown(src: string, uid: number, gid: number, options: {
151
+ sync: true
152
+ }): void;
153
+
154
+ chown(src: string, uid: number, gid: number, options?: {
155
+ sync?: false
156
+ }): Promise<void>;
157
+
158
+ chown(src: string, uid: number, gid: number, { sync = false }: { sync?: boolean } = {}) {
159
+ src = this.resolve(src);
160
+
161
+ if (sync) {
162
+ return recurseSync.chown(src, uid, gid);
163
+ }
164
+
165
+ return new Promise<void>((resolve, reject) => {
166
+ recurse.chown(src, uid, gid, (err) => {
167
+ if (err) {
168
+ return reject(err);
169
+ }
170
+
171
+ resolve();
172
+ });
173
+ });
174
+ }
175
+
176
+ symlink(src: string, use: string, options: {
177
+ sync: true
178
+ }): void;
179
+
180
+ symlink(src: string, use: string, options?: {
181
+ sync?: false
182
+ }): Promise<void>;
183
+
184
+ symlink(src: string, use: string, { sync = false }: { sync?: boolean } = {}) {
185
+ src = this.resolve(src);
186
+ use = this.resolve(use);
187
+
188
+ if (sync) {
189
+ return fs.symlinkSync(src, use);
190
+ }
191
+
192
+ return new Promise<void>((resolve, reject) => {
193
+ fs.symlink(src, use, (err) => {
194
+ if (err) {
195
+ return reject(err);
196
+ }
197
+
198
+ resolve();
199
+ });
200
+ });
201
+ }
202
+
203
+ copy(src: string, dir: string, options: {
204
+ sync: true,
205
+ umask?: number
206
+ }): void;
207
+
208
+ copy(src: string, dir: string, options?: {
209
+ sync?: false,
210
+ umask?: number
211
+ }): Promise<void>;
212
+
213
+ copy(src: string, dir: string, { sync = false, umask = 0o000 }: {
214
+ sync?: boolean,
215
+ umask?: number
216
+ } = {}) {
217
+ src = this.resolve(src);
218
+ dir = this.resolve(dir);
219
+
220
+ if (sync) {
221
+ return recurseSync.copy(src, dir, umask);
222
+ }
223
+
224
+ return new Promise<void>((resolve, reject) => {
225
+ recurse.copy(src, dir, umask, (err) => {
226
+ if (err) {
227
+ return reject(err);
228
+ }
229
+
230
+ resolve();
231
+ });
232
+ });
233
+ }
234
+
235
+ rename(src: string, use: string, options: {
236
+ sync: true
237
+ }): void;
238
+
239
+ rename(src: string, use: string, options?: {
240
+ sync?: false
241
+ }): Promise<void>;
242
+
243
+ rename(src: string, use: string, { sync = false }: { sync?: boolean } = {}) {
244
+ src = this.resolve(src);
245
+ use = this.resolve(use);
246
+
247
+ if (sync) {
248
+ return fs.renameSync(src, use);
249
+ }
250
+
251
+ return new Promise<void>((resolve, reject) => {
252
+ fs.rename(src, use, (err) => {
253
+ if (err) {
254
+ return reject(err);
255
+ }
256
+
257
+ resolve();
258
+ });
259
+ });
260
+ }
261
+
262
+ remove(src: string, options: {
263
+ sync: true
264
+ }): void;
265
+
266
+ remove(src: string, options?: {
267
+ sync?: false
268
+ }): Promise<void>;
269
+
270
+ remove(src: string, { sync = false }: { sync?: boolean } = {}) {
271
+ src = this.resolve(src);
272
+
273
+ if (sync) {
274
+ return recurseSync.remove(src);
275
+ }
276
+
277
+ return new Promise<void>((resolve, reject) => {
278
+ recurse.remove(src, (err) => {
279
+ if (err) {
280
+ return reject(err);
281
+ }
282
+
283
+ resolve();
284
+ });
285
+ });
286
+ }
287
+
288
+ read(src: string, options: {
289
+ sync: true,
290
+ encoding?: BufferEncoding,
291
+ flag?: Flag
292
+ }): string;
293
+
294
+ read(src: string, options: {
295
+ sync: true,
296
+ encoding?: null,
297
+ flag?: Flag
298
+ }): Buffer;
299
+
300
+ read(src: string, options: {
301
+ sync?: false,
302
+ encoding: null,
303
+ flag?: Flag
304
+ }): Promise<Buffer>;
305
+
306
+ read(src: string, options?: {
307
+ sync?: false,
308
+ encoding?: BufferEncoding,
309
+ flag?: Flag
310
+ }): Promise<string>;
311
+
312
+ read(src: string, { sync = false, encoding = 'utf8', flag = 'r' }: {
313
+ sync?: boolean,
314
+ encoding?: BufferEncoding | null,
315
+ flag?: Flag
316
+ } = {}) {
317
+ src = this.resolve(src);
318
+
319
+ if (sync) {
320
+ return fs.readFileSync(src, {
321
+ encoding,
322
+ flag
323
+ });
324
+ }
325
+
326
+ return new Promise((resolve, reject) => {
327
+ fs.readFile(src, {
328
+ encoding,
329
+ flag
330
+ },
331
+ (err, raw) => {
332
+ if (err) {
333
+ return reject(err);
334
+ }
335
+
336
+ resolve(raw);
337
+ });
338
+ });
339
+ }
340
+
341
+ write(src: string, data: Buffer, options: {
342
+ sync: true,
343
+ encoding: null,
344
+ umask?: number,
345
+ flag?: Flag
346
+ }): void;
347
+
348
+ write(src: string, data: string, options: {
349
+ sync: true,
350
+ encoding?: BufferEncoding,
351
+ umask?: number,
352
+ flag?: Flag
353
+ }): void;
354
+
355
+ write(src: string, data: Buffer, options: {
356
+ sync?: false,
357
+ encoding: null,
358
+ umask?: number,
359
+ flag?: Flag
360
+ }): Promise<void>;
361
+
362
+ write(src: string, data: string, options?: {
363
+ sync?: false,
364
+ encoding?: BufferEncoding,
365
+ umask?: number,
366
+ flag?: Flag
367
+ }): Promise<void>;
368
+
369
+ write(src: string, data: Buffer | string, { sync = false, encoding = 'utf8', umask = 0o000, flag = 'w' }: {
370
+ sync?: boolean,
371
+ encoding?: BufferEncoding | null,
372
+ umask?: number,
373
+ flag?: Flag
374
+ } = {}) {
375
+ src = this.resolve(src);
376
+
377
+ const mode = 0o666 - umask;
378
+
379
+ if (sync) {
380
+ return fs.writeFileSync(src, data, {
381
+ encoding,
382
+ mode,
383
+ flag
384
+ });
385
+ }
386
+
387
+ return new Promise<void>((resolve, reject) => {
388
+ fs.writeFile(src, data, {
389
+ encoding,
390
+ mode,
391
+ flag
392
+ },
393
+ (err) => {
394
+ if (err) {
395
+ return reject(err);
396
+ }
397
+
398
+ resolve();
399
+ });
400
+ });
401
+ }
402
+
403
+ append(src: string, data: Buffer, options: {
404
+ sync: true,
405
+ encoding: null,
406
+ umask?: number,
407
+ flag?: Flag
408
+ }): void;
409
+
410
+ append(src: string, data: string, options: {
411
+ sync: true,
412
+ encoding?: BufferEncoding,
413
+ umask?: number,
414
+ flag?: Flag
415
+ }): void;
416
+
417
+ append(src: string, data: Buffer, options: {
418
+ sync?: false,
419
+ encoding: null,
420
+ umask?: number,
421
+ flag?: Flag
422
+ }): Promise<void>;
423
+
424
+ append(src: string, data: string, options?: {
425
+ sync?: false,
426
+ encoding?: BufferEncoding,
427
+ umask?: number,
428
+ flag?: Flag
429
+ }): Promise<void>;
430
+
431
+ append(src: string, data: Buffer | string, { sync = false, encoding = 'utf8', umask = 0o000, flag = 'a' }: {
432
+ sync?: boolean,
433
+ encoding?: BufferEncoding | null,
434
+ umask?: number,
435
+ flag?: Flag
436
+ } = {}) {
437
+ src = this.resolve(src);
438
+ const mode = 0o666 - umask;
439
+
440
+ if (sync) {
441
+ return fs.appendFileSync(src, data, {
442
+ encoding,
443
+ mode,
444
+ flag
445
+ });
446
+ }
447
+
448
+ return new Promise<void>((resolve, reject) => {
449
+ fs.appendFile(src, data, {
450
+ encoding,
451
+ mode,
452
+ flag
453
+ },
454
+ (err) => {
455
+ if (err) {
456
+ return reject(err);
457
+ }
458
+
459
+ resolve();
460
+ });
461
+ });
462
+ }
463
+
464
+ readdir(dir: string, options: {
465
+ sync: true,
466
+ encoding?: BufferEncoding | null
467
+ }): string[];
468
+
469
+ readdir(dir: string, options?: {
470
+ sync?: false,
471
+ encoding?: BufferEncoding | null
472
+ }): Promise<string[]>;
473
+
474
+ readdir(dir: string, { sync = false, encoding = 'utf8' }: {
475
+ sync?: boolean,
476
+ encoding?: BufferEncoding | null
477
+ } = {}) {
478
+ dir = this.resolve(dir);
479
+
480
+ if (sync) {
481
+ return fs.readdirSync(dir, {
482
+ encoding
483
+ });
484
+ }
485
+
486
+ return new Promise((resolve, reject) => {
487
+ fs.readdir(dir, { encoding }, (err, list) => {
488
+ if (err) {
489
+ return reject(err);
490
+ }
491
+
492
+ resolve(list);
493
+ });
494
+ });
495
+ }
496
+
497
+ mkdir(dir: string, options: {
498
+ sync: true,
499
+ umask?: number
500
+ }): void;
501
+
502
+ mkdir(dir: string, options?: {
503
+ sync?: false,
504
+ umask?: number
505
+ }): Promise<void>;
506
+
507
+ mkdir(dir: string, { umask = 0o000, sync = false }: {
508
+ umask?: number,
509
+ sync?: boolean
510
+ } = {}) {
511
+ dir = this.resolve(dir);
512
+
513
+ if (sync) {
514
+ return recurseSync.mkdir(dir, umask);
515
+ }
516
+
517
+ return new Promise<void>((resolve, reject) => {
518
+ recurse.mkdir(dir, umask, (err) => {
519
+ if (err) {
520
+ return reject(err);
521
+ }
522
+
523
+ resolve();
524
+ });
525
+ });
526
+ }
527
+ }
@@ -1,102 +1,108 @@
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
- const {sep} = path;
4
+ const { sep } = path;
5
5
 
6
- export default {
7
- chmod(src: string, mode: number): void {
8
- const stat = fs.statSync(src);
6
+ function chmod(src: string, mode: number) {
7
+ const stat = fs.statSync(src);
9
8
 
10
- if (stat.isDirectory()) {
11
- const list = fs.readdirSync(src);
9
+ if (stat.isDirectory()) {
10
+ const list = fs.readdirSync(src);
12
11
 
13
- for (const loc of list) {
14
- this.chmod(`${src}${sep}${loc}`, mode);
15
- }
12
+ for (const loc of list) {
13
+ chmod(`${src}${sep}${loc}`, mode);
16
14
  }
15
+ }
17
16
 
18
- fs.chmodSync(src, mode);
19
- },
17
+ fs.chmodSync(src, mode);
18
+ }
20
19
 
21
- chown(src: string, uid: number, gid: number): void {
22
- const stat = fs.statSync(src);
20
+ function chown(src: string, uid: number, gid: number) {
21
+ const stat = fs.statSync(src);
23
22
 
24
- if (stat.isDirectory()) {
25
- const list = fs.readdirSync(src);
23
+ if (stat.isDirectory()) {
24
+ const list = fs.readdirSync(src);
26
25
 
27
- for (const loc of list) {
28
- this.chown(`${src}${sep}${loc}`, uid, gid);
29
- }
26
+ for (const loc of list) {
27
+ chown(`${src}${sep}${loc}`, uid, gid);
30
28
  }
29
+ }
31
30
 
32
- fs.chownSync(src, uid, gid);
33
- },
34
-
35
- copy(src: string, dir: string, umask: number): void {
36
- const stat = fs.statSync(src);
31
+ fs.chownSync(src, uid, gid);
32
+ }
37
33
 
38
- if (stat.isDirectory()) {
39
- const list = fs.readdirSync(src);
34
+ function copy(src: string, dir: string, umask: number) {
35
+ const stat = fs.statSync(src);
40
36
 
41
- const paths = src.split(sep);
42
- const loc = paths[paths.length - 1];
43
- const mode = 0o777 - umask;
37
+ if (stat.isDirectory()) {
38
+ const list = fs.readdirSync(src);
44
39
 
45
- dir = `${dir}${sep}${loc}`;
46
- fs.mkdirSync(dir, mode);
40
+ const paths = src.split(sep);
41
+ const loc = paths[paths.length - 1];
42
+ const mode = 0o777 - umask;
47
43
 
48
- for (const loc of list) {
49
- this.copy(`${src}${sep}${loc}`, dir, umask);
50
- }
51
- }
52
- else {
53
- const loc = path.basename(src);
54
- const use = `${dir}${sep}${loc}`;
44
+ dir = `${dir}${sep}${loc}`;
45
+ fs.mkdirSync(dir, mode);
55
46
 
56
- fs.copyFileSync(src, use);
47
+ for (const loc of list) {
48
+ copy(`${src}${sep}${loc}`, dir, umask);
57
49
  }
58
- },
50
+ }
51
+ else {
52
+ const loc = path.basename(src);
53
+ const use = `${dir}${sep}${loc}`;
59
54
 
60
- remove(src: string): void {
61
- const stat = fs.statSync(src);
55
+ fs.copyFileSync(src, use);
56
+ }
57
+ }
62
58
 
63
- if (stat.isDirectory()) {
64
- const list = fs.readdirSync(src);
59
+ function remove(src: string) {
60
+ const stat = fs.statSync(src);
65
61
 
66
- for (const loc of list) {
67
- this.remove(`${src}${sep}${loc}`);
68
- }
62
+ if (stat.isDirectory()) {
63
+ const list = fs.readdirSync(src);
69
64
 
70
- fs.rmdirSync(src);
71
- }
72
- else {
73
- fs.unlinkSync(src);
65
+ for (const loc of list) {
66
+ remove(`${src}${sep}${loc}`);
74
67
  }
75
- },
76
68
 
77
- mkdir(dir: string, umask: number): void {
78
- const mode = 0o777 - umask;
79
- const cwd = process.cwd();
80
- let use = '';
69
+ fs.rmdirSync(src);
70
+ }
71
+ else {
72
+ fs.unlinkSync(src);
73
+ }
74
+ }
81
75
 
82
- if (dir.indexOf(cwd) === 0) {
83
- use = cwd;
84
- dir = dir.substr(cwd.length);
85
- }
76
+ function mkdir(dir: string, umask: number) {
77
+ const mode = 0o777 - umask;
78
+ const cwd = process.cwd();
79
+ let use = '';
86
80
 
87
- const ways = dir.split(sep).slice(1);
81
+ if (dir.indexOf(cwd) === 0) {
82
+ use = cwd;
83
+ dir = dir.substr(cwd.length);
84
+ }
88
85
 
89
- for (const loc of ways) {
90
- use += `${sep}${loc}`;
86
+ const ways = dir.split(sep).slice(1);
91
87
 
92
- try {
93
- fs.mkdirSync(use, { mode });
94
- }
95
- catch (err) {
96
- if (err.errno !== -17) {
97
- throw err;
98
- }
88
+ for (const loc of ways) {
89
+ use += `${sep}${loc}`;
90
+
91
+ try {
92
+ fs.mkdirSync(use, { mode });
93
+ }
94
+ catch (err) {
95
+ if (err.errno !== -17) {
96
+ throw err;
99
97
  }
100
98
  }
101
99
  }
102
100
  }
101
+
102
+ export default {
103
+ chmod,
104
+ chown,
105
+ copy,
106
+ remove,
107
+ mkdir
108
+ }