pwd-fs 3.4.0 → 3.5.0
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/powered-file-system/append.d.ts +9 -6
- package/dist/powered-file-system/append.js +4 -4
- package/dist/powered-file-system/chmod.d.ts +4 -4
- package/dist/powered-file-system/chmod.js +9 -10
- package/dist/powered-file-system/chown.d.ts +7 -4
- package/dist/powered-file-system/chown.js +18 -8
- package/dist/powered-file-system/copy.d.ts +10 -7
- package/dist/powered-file-system/copy.js +11 -12
- package/dist/powered-file-system/empty-dir.d.ts +4 -4
- package/dist/powered-file-system/empty-dir.js +9 -10
- package/dist/powered-file-system/mkdir.d.ts +9 -6
- package/dist/powered-file-system/mkdir.js +9 -10
- package/dist/powered-file-system/read.d.ts +10 -6
- package/dist/powered-file-system/read.js +9 -5
- package/dist/powered-file-system/readdir.d.ts +11 -6
- package/dist/powered-file-system/readdir.js +8 -6
- package/dist/powered-file-system/readlink.d.ts +9 -4
- package/dist/powered-file-system/readlink.js +8 -6
- package/dist/powered-file-system/realpath.d.ts +9 -4
- package/dist/powered-file-system/realpath.js +8 -6
- package/dist/powered-file-system/remove.d.ts +5 -5
- package/dist/powered-file-system/remove.js +11 -20
- package/dist/powered-file-system/rename.d.ts +5 -5
- package/dist/powered-file-system/rename.js +11 -7
- package/dist/powered-file-system/stat.d.ts +4 -4
- package/dist/powered-file-system/stat.js +8 -6
- package/dist/powered-file-system/symlink.d.ts +4 -4
- package/dist/powered-file-system/symlink.js +11 -4
- package/dist/powered-file-system/test.d.ts +10 -5
- package/dist/powered-file-system/test.js +8 -5
- package/dist/powered-file-system/write.d.ts +10 -7
- package/dist/powered-file-system/write.js +9 -6
- package/dist/powered-file-system.d.ts +103 -56
- package/dist/powered-file-system.js +5 -48
- package/dist/powered-file-system.test.js +25 -0
- package/dist/recurse-io-sync.d.ts +1 -1
- package/dist/recurse-io-sync.js +11 -25
- package/dist/recurse-io.d.ts +1 -1
- package/dist/recurse-io.js +31 -49
- package/dist/suite.test.js +1 -1
- package/package.json +11 -16
- package/readme.md +30 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { PoweredFileSystem, Stats } from '../powered-file-system';
|
|
1
|
+
import type { AsyncOption, MaybeSyncOption, PoweredFileSystem, Stats, SyncOption } from '../powered-file-system';
|
|
2
2
|
/**
|
|
3
3
|
* Returns `lstat` data so symlinks are reported as links instead of followed targets.
|
|
4
4
|
*/
|
|
5
|
-
export declare function stat
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export declare function stat(this: PoweredFileSystem, src: string, options: SyncOption): Stats;
|
|
6
|
+
export declare function stat(this: PoweredFileSystem, src: string, options?: AsyncOption): Promise<Stats>;
|
|
7
|
+
export declare function stat(this: PoweredFileSystem, src: string, options?: MaybeSyncOption): Stats | Promise<Stats>;
|
|
@@ -5,17 +5,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.stat = stat;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
/**
|
|
10
|
-
* Returns `lstat` data so symlinks are reported as links instead of followed targets.
|
|
11
|
-
*/
|
|
12
8
|
function stat(src, options) {
|
|
13
9
|
const { sync = false } = options ?? {};
|
|
14
|
-
src = node_path_1.default.resolve(this.pwd, src);
|
|
15
10
|
if (sync) {
|
|
16
|
-
return node_fs_1.default.lstatSync(src);
|
|
11
|
+
return node_fs_1.default.lstatSync(this.resolve(src));
|
|
17
12
|
}
|
|
18
13
|
return new Promise((resolve, reject) => {
|
|
14
|
+
try {
|
|
15
|
+
src = this.resolve(src);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
reject(err);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
19
21
|
node_fs_1.default.lstat(src, (err, stats) => {
|
|
20
22
|
if (err) {
|
|
21
23
|
return reject(err);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PoweredFileSystem } from '../powered-file-system';
|
|
2
|
-
export declare function symlink
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { AsyncOption, MaybeSyncOption, PoweredFileSystem, SyncOption } from '../powered-file-system';
|
|
2
|
+
export declare function symlink(this: PoweredFileSystem, src: string, dest: string, options: SyncOption): void;
|
|
3
|
+
export declare function symlink(this: PoweredFileSystem, src: string, dest: string, options?: AsyncOption): Promise<void>;
|
|
4
|
+
export declare function symlink(this: PoweredFileSystem, src: string, dest: string, options?: MaybeSyncOption): void | Promise<void>;
|
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.symlink = symlink;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
8
|
/**
|
|
10
9
|
* Windows requires an explicit link type. Non-Windows platforms infer it.
|
|
11
10
|
*/
|
|
@@ -17,15 +16,23 @@ function resolveSymlinkType(src) {
|
|
|
17
16
|
return stats.isDirectory() ? 'junction' : 'file';
|
|
18
17
|
}
|
|
19
18
|
function symlink(src, dest, options) {
|
|
20
|
-
src = node_path_1.default.resolve(this.pwd, src);
|
|
21
|
-
dest = node_path_1.default.resolve(this.pwd, dest);
|
|
22
19
|
const { sync = false } = options ?? {};
|
|
23
20
|
if (sync) {
|
|
21
|
+
src = this.resolve(src);
|
|
22
|
+
dest = this.resolve(dest);
|
|
24
23
|
const type = resolveSymlinkType(src);
|
|
25
24
|
node_fs_1.default.symlinkSync(src, dest, type);
|
|
26
|
-
return
|
|
25
|
+
return;
|
|
27
26
|
}
|
|
28
27
|
return new Promise((resolve, reject) => {
|
|
28
|
+
try {
|
|
29
|
+
src = this.resolve(src);
|
|
30
|
+
dest = this.resolve(dest);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
reject(err);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
29
36
|
if (process.platform === 'win32') {
|
|
30
37
|
node_fs_1.default.lstat(src, (err, stats) => {
|
|
31
38
|
if (err) {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import type { Mode, PoweredFileSystem } from '../powered-file-system';
|
|
1
|
+
import type { AsyncOption, MaybeSyncOption, Mode, PoweredFileSystem, SyncOption } from '../powered-file-system';
|
|
2
2
|
/**
|
|
3
|
-
* Thin wrapper around `fs.access` that resolves paths against the instance
|
|
3
|
+
* Thin wrapper around `fs.access` that resolves paths against the instance base path.
|
|
4
4
|
*/
|
|
5
|
-
export declare function test
|
|
6
|
-
sync?: T;
|
|
5
|
+
export declare function test(this: PoweredFileSystem, src: string, options: SyncOption & {
|
|
7
6
|
flag?: Mode;
|
|
8
|
-
}):
|
|
7
|
+
}): boolean;
|
|
8
|
+
export declare function test(this: PoweredFileSystem, src: string, options?: AsyncOption & {
|
|
9
|
+
flag?: Mode;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
export declare function test(this: PoweredFileSystem, src: string, options?: MaybeSyncOption & {
|
|
12
|
+
flag?: Mode;
|
|
13
|
+
}): boolean | Promise<boolean>;
|
|
@@ -5,16 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.test = test;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
/**
|
|
10
|
-
* Thin wrapper around `fs.access` that resolves paths against the instance root.
|
|
11
|
-
*/
|
|
12
8
|
function test(src, options) {
|
|
13
9
|
const { sync = false, flag = 'e' } = options ?? {};
|
|
14
10
|
const mode = this.constants[flag];
|
|
15
|
-
src = node_path_1.default.resolve(this.pwd, src);
|
|
16
11
|
if (sync) {
|
|
17
12
|
try {
|
|
13
|
+
src = this.resolve(src);
|
|
18
14
|
node_fs_1.default.accessSync(src, mode);
|
|
19
15
|
return true;
|
|
20
16
|
}
|
|
@@ -23,6 +19,13 @@ function test(src, options) {
|
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
return new Promise((resolve) => {
|
|
22
|
+
try {
|
|
23
|
+
src = this.resolve(src);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
resolve(false);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
26
29
|
node_fs_1.default.access(src, mode, (err) => {
|
|
27
30
|
resolve(!err);
|
|
28
31
|
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { Flag, PoweredFileSystem } from '../powered-file-system';
|
|
2
|
-
|
|
3
|
-
* Writes a file relative to `pwd` and then reapplies the computed permissions explicitly.
|
|
4
|
-
*/
|
|
5
|
-
export declare function write<T extends boolean = false>(this: PoweredFileSystem, src: string, data: Buffer | string, options?: {
|
|
6
|
-
sync?: T;
|
|
1
|
+
import type { AsyncOption, Flag, MaybeSyncOption, PoweredFileSystem, SyncOption } from '../powered-file-system';
|
|
2
|
+
type WriteOptions = {
|
|
7
3
|
encoding?: BufferEncoding | null;
|
|
8
4
|
umask?: number;
|
|
9
5
|
flag?: Flag;
|
|
10
|
-
}
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Writes a file relative to `pwd` and then reapplies the computed permissions explicitly.
|
|
9
|
+
*/
|
|
10
|
+
export declare function write(this: PoweredFileSystem, src: string, data: Buffer | string, options: SyncOption & WriteOptions): void;
|
|
11
|
+
export declare function write(this: PoweredFileSystem, src: string, data: Buffer | string, options?: AsyncOption & WriteOptions): Promise<void>;
|
|
12
|
+
export declare function write(this: PoweredFileSystem, src: string, data: Buffer | string, options?: MaybeSyncOption & WriteOptions): void | Promise<void>;
|
|
13
|
+
export {};
|
|
@@ -5,21 +5,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.write = write;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
/**
|
|
10
|
-
* Writes a file relative to `pwd` and then reapplies the computed permissions explicitly.
|
|
11
|
-
*/
|
|
12
8
|
function write(src, data, options) {
|
|
13
9
|
const { sync = false, encoding = 'utf8', umask = 0o000, flag = 'w', } = options ?? {};
|
|
14
|
-
src = node_path_1.default.resolve(this.pwd, src);
|
|
15
10
|
const mode = 0o666 & ~umask;
|
|
16
11
|
if (sync) {
|
|
12
|
+
src = this.resolve(src);
|
|
17
13
|
// Apply chmod explicitly so the final mode is deterministic across runtimes.
|
|
18
14
|
node_fs_1.default.writeFileSync(src, data, { encoding, mode, flag });
|
|
19
15
|
node_fs_1.default.chmodSync(src, mode);
|
|
20
|
-
return
|
|
16
|
+
return;
|
|
21
17
|
}
|
|
22
18
|
return new Promise((resolve, reject) => {
|
|
19
|
+
try {
|
|
20
|
+
src = this.resolve(src);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
reject(err);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
23
26
|
node_fs_1.default.writeFile(src, data, { encoding, mode, flag }, (err) => {
|
|
24
27
|
if (err) {
|
|
25
28
|
return reject(err);
|
|
@@ -7,6 +7,27 @@ export type Mode = keyof IConstants;
|
|
|
7
7
|
export type Flag = Extract<fs.OpenMode, string>;
|
|
8
8
|
export type Stats = fs.Stats;
|
|
9
9
|
export type CopyFilter = (src: string, dest: string) => boolean;
|
|
10
|
+
export type SyncResult<T extends boolean, TResult> = T extends true ? TResult : Promise<TResult>;
|
|
11
|
+
export type SyncOption = {
|
|
12
|
+
sync: true;
|
|
13
|
+
};
|
|
14
|
+
export type AsyncOption = {
|
|
15
|
+
sync?: false;
|
|
16
|
+
};
|
|
17
|
+
export type MaybeSyncOption = {
|
|
18
|
+
sync?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type ReadResult<TEncoding> = TEncoding extends null ? Buffer : string;
|
|
21
|
+
export type ReaddirResult<TEncoding> = TEncoding extends null ? Buffer[] : string[];
|
|
22
|
+
export type ReadOptions<TSync extends boolean = boolean, TEncoding extends BufferEncoding | null = BufferEncoding> = {
|
|
23
|
+
sync?: TSync;
|
|
24
|
+
encoding?: TEncoding;
|
|
25
|
+
flag?: Flag;
|
|
26
|
+
};
|
|
27
|
+
export type ReaddirOptions<TSync extends boolean = boolean, TEncoding extends BufferEncoding | null = BufferEncoding> = {
|
|
28
|
+
sync?: TSync;
|
|
29
|
+
encoding?: TEncoding;
|
|
30
|
+
};
|
|
10
31
|
export * from './bitmask';
|
|
11
32
|
export interface IConstants {
|
|
12
33
|
e: number;
|
|
@@ -17,8 +38,7 @@ export interface IConstants {
|
|
|
17
38
|
/**
|
|
18
39
|
* Path-aware wrapper around Node's file system APIs.
|
|
19
40
|
*
|
|
20
|
-
*
|
|
21
|
-
* suitable for sandboxed or virtual working-directory workflows.
|
|
41
|
+
* Relative paths are resolved against `pwd`; absolute paths are preserved.
|
|
22
42
|
*/
|
|
23
43
|
export declare class PoweredFileSystem {
|
|
24
44
|
readonly pwd: string;
|
|
@@ -34,117 +54,144 @@ export declare class PoweredFileSystem {
|
|
|
34
54
|
* @param pwd Base directory used to resolve all relative paths.
|
|
35
55
|
*/
|
|
36
56
|
constructor(pwd?: string);
|
|
57
|
+
/**
|
|
58
|
+
* Resolves relative paths against `pwd` while preserving absolute paths.
|
|
59
|
+
*/
|
|
60
|
+
resolve(src: string): string;
|
|
37
61
|
/**
|
|
38
62
|
* Checks whether the given path is accessible with the requested mode.
|
|
39
63
|
*/
|
|
40
|
-
test
|
|
41
|
-
|
|
64
|
+
test(src: string, options: SyncOption & {
|
|
65
|
+
flag?: Mode;
|
|
66
|
+
}): boolean;
|
|
67
|
+
test(src: string, options?: AsyncOption & {
|
|
42
68
|
flag?: Mode;
|
|
43
|
-
}):
|
|
69
|
+
}): Promise<boolean>;
|
|
44
70
|
/**
|
|
45
71
|
* Returns `lstat` information for a path.
|
|
46
72
|
*/
|
|
47
|
-
stat
|
|
48
|
-
|
|
49
|
-
}): T extends true ? Stats : Promise<Stats>;
|
|
73
|
+
stat(src: string, options: SyncOption): Stats;
|
|
74
|
+
stat(src: string, options?: AsyncOption): Promise<Stats>;
|
|
50
75
|
/**
|
|
51
76
|
* Applies a mode recursively to a file or directory tree.
|
|
52
77
|
*/
|
|
53
|
-
chmod
|
|
54
|
-
|
|
55
|
-
}): T extends true ? void : Promise<void>;
|
|
78
|
+
chmod(src: string, mode: number, options: SyncOption): void;
|
|
79
|
+
chmod(src: string, mode: number, options?: AsyncOption): Promise<void>;
|
|
56
80
|
/**
|
|
57
81
|
* Applies ownership recursively to a file or directory tree.
|
|
58
82
|
*/
|
|
59
|
-
chown
|
|
60
|
-
|
|
83
|
+
chown(src: string, options: SyncOption & {
|
|
84
|
+
uid?: number;
|
|
85
|
+
gid?: number;
|
|
86
|
+
}): void;
|
|
87
|
+
chown(src: string, options?: AsyncOption & {
|
|
61
88
|
uid?: number;
|
|
62
89
|
gid?: number;
|
|
63
|
-
}):
|
|
90
|
+
}): Promise<void>;
|
|
64
91
|
/**
|
|
65
92
|
* Creates a symbolic link from `dest` to `src`.
|
|
66
93
|
*/
|
|
67
|
-
symlink
|
|
68
|
-
|
|
69
|
-
}): T extends true ? void : Promise<void>;
|
|
94
|
+
symlink(src: string, dest: string, options: SyncOption): void;
|
|
95
|
+
symlink(src: string, dest: string, options?: AsyncOption): Promise<void>;
|
|
70
96
|
/**
|
|
71
97
|
* Copies `src` into the destination directory.
|
|
72
98
|
*/
|
|
73
|
-
copy
|
|
74
|
-
sync?: T;
|
|
99
|
+
copy(src: string, dest: string, options: SyncOption & {
|
|
75
100
|
umask?: number;
|
|
76
101
|
overwrite?: boolean;
|
|
77
102
|
filter?: CopyFilter;
|
|
78
|
-
}):
|
|
103
|
+
}): void;
|
|
104
|
+
copy(src: string, dest: string, options?: AsyncOption & {
|
|
105
|
+
umask?: number;
|
|
106
|
+
overwrite?: boolean;
|
|
107
|
+
filter?: CopyFilter;
|
|
108
|
+
}): Promise<void>;
|
|
79
109
|
/**
|
|
80
110
|
* Renames or moves a file system node.
|
|
81
111
|
*/
|
|
82
|
-
rename
|
|
83
|
-
|
|
84
|
-
}): T extends true ? void : Promise<void>;
|
|
112
|
+
rename(src: string, dest: string, options: SyncOption): void;
|
|
113
|
+
rename(src: string, dest: string, options?: AsyncOption): Promise<void>;
|
|
85
114
|
/**
|
|
86
115
|
* Removes a file system node recursively.
|
|
87
116
|
*/
|
|
88
|
-
remove
|
|
89
|
-
|
|
90
|
-
}): T extends true ? void : Promise<void>;
|
|
117
|
+
remove(src: string, options: SyncOption): void;
|
|
118
|
+
remove(src: string, options?: AsyncOption): Promise<void>;
|
|
91
119
|
/**
|
|
92
120
|
* Removes all directory entries while preserving the directory itself.
|
|
93
121
|
*/
|
|
94
|
-
emptyDir
|
|
95
|
-
|
|
96
|
-
}): T extends true ? void : Promise<void>;
|
|
122
|
+
emptyDir(src: string, options: SyncOption): void;
|
|
123
|
+
emptyDir(src: string, options?: AsyncOption): Promise<void>;
|
|
97
124
|
/**
|
|
98
|
-
* Reads a file relative to the current instance
|
|
125
|
+
* Reads a file relative to the current instance path.
|
|
99
126
|
*/
|
|
100
|
-
read
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
read(src: string, options: SyncOption & ReadOptions<true, null> & {
|
|
128
|
+
encoding: null;
|
|
129
|
+
}): Buffer;
|
|
130
|
+
read(src: string, options: SyncOption & ReadOptions<true, BufferEncoding>): string;
|
|
131
|
+
read(src: string, options: AsyncOption & ReadOptions<false, null> & {
|
|
132
|
+
encoding: null;
|
|
133
|
+
}): Promise<Buffer>;
|
|
134
|
+
read(src: string, options?: AsyncOption & ReadOptions<false, BufferEncoding>): Promise<string>;
|
|
105
135
|
/**
|
|
106
136
|
* Writes a file and applies the resulting permissions explicitly.
|
|
107
137
|
*/
|
|
108
|
-
write
|
|
109
|
-
sync?: T;
|
|
138
|
+
write(src: string, data: Buffer | string, options: SyncOption & {
|
|
110
139
|
encoding?: BufferEncoding | null;
|
|
111
140
|
umask?: number;
|
|
112
141
|
flag?: Flag;
|
|
113
|
-
}):
|
|
142
|
+
}): void;
|
|
143
|
+
write(src: string, data: Buffer | string, options?: AsyncOption & {
|
|
144
|
+
encoding?: BufferEncoding | null;
|
|
145
|
+
umask?: number;
|
|
146
|
+
flag?: Flag;
|
|
147
|
+
}): Promise<void>;
|
|
114
148
|
/**
|
|
115
149
|
* @deprecated Use `write(..., { flag: 'a' })` instead.
|
|
116
150
|
*/
|
|
117
|
-
append
|
|
118
|
-
|
|
151
|
+
append(src: string, data: Buffer | string, options: SyncOption & {
|
|
152
|
+
encoding?: BufferEncoding | null;
|
|
153
|
+
umask?: number;
|
|
154
|
+
}): void;
|
|
155
|
+
append(src: string, data: Buffer | string, options?: AsyncOption & {
|
|
119
156
|
encoding?: BufferEncoding | null;
|
|
120
157
|
umask?: number;
|
|
121
|
-
}):
|
|
158
|
+
}): Promise<void>;
|
|
122
159
|
/**
|
|
123
|
-
* Lists directory entries relative to the current instance
|
|
160
|
+
* Lists directory entries relative to the current instance path.
|
|
124
161
|
*/
|
|
125
|
-
readdir
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
162
|
+
readdir(dir: string, options: SyncOption & ReaddirOptions<true, null> & {
|
|
163
|
+
encoding: null;
|
|
164
|
+
}): Buffer[];
|
|
165
|
+
readdir(dir: string, options: SyncOption & ReaddirOptions<true, BufferEncoding>): string[];
|
|
166
|
+
readdir(dir: string, options: AsyncOption & ReaddirOptions<false, null> & {
|
|
167
|
+
encoding: null;
|
|
168
|
+
}): Promise<Buffer[]>;
|
|
169
|
+
readdir(dir: string, options?: AsyncOption & ReaddirOptions<false, BufferEncoding>): Promise<string[]>;
|
|
129
170
|
/**
|
|
130
171
|
* Resolves the target of a symbolic link.
|
|
131
172
|
*/
|
|
132
|
-
readlink
|
|
133
|
-
|
|
173
|
+
readlink(src: string, options: SyncOption & {
|
|
174
|
+
encoding?: BufferEncoding;
|
|
175
|
+
}): string;
|
|
176
|
+
readlink(src: string, options?: AsyncOption & {
|
|
134
177
|
encoding?: BufferEncoding;
|
|
135
|
-
}):
|
|
178
|
+
}): Promise<string>;
|
|
136
179
|
/**
|
|
137
180
|
* Resolves a path to its canonical absolute location.
|
|
138
181
|
*/
|
|
139
|
-
realpath
|
|
140
|
-
sync?: T;
|
|
182
|
+
realpath(src: string, options: SyncOption & {
|
|
141
183
|
encoding?: BufferEncoding;
|
|
142
|
-
}):
|
|
184
|
+
}): string;
|
|
185
|
+
realpath(src: string, options?: AsyncOption & {
|
|
186
|
+
encoding?: BufferEncoding;
|
|
187
|
+
}): Promise<string>;
|
|
143
188
|
/**
|
|
144
|
-
* Creates a directory tree relative to the current instance
|
|
189
|
+
* Creates a directory tree relative to the current instance path.
|
|
145
190
|
*/
|
|
146
|
-
mkdir
|
|
147
|
-
|
|
191
|
+
mkdir(dir: string, options: SyncOption & {
|
|
192
|
+
umask?: number;
|
|
193
|
+
}): void;
|
|
194
|
+
mkdir(dir: string, options?: AsyncOption & {
|
|
148
195
|
umask?: number;
|
|
149
|
-
}):
|
|
196
|
+
}): Promise<void>;
|
|
150
197
|
}
|
|
@@ -41,8 +41,7 @@ __exportStar(require("./bitmask"), exports);
|
|
|
41
41
|
/**
|
|
42
42
|
* Path-aware wrapper around Node's file system APIs.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
* suitable for sandboxed or virtual working-directory workflows.
|
|
44
|
+
* Relative paths are resolved against `pwd`; absolute paths are preserved.
|
|
46
45
|
*/
|
|
47
46
|
class PoweredFileSystem {
|
|
48
47
|
pwd;
|
|
@@ -66,98 +65,56 @@ class PoweredFileSystem {
|
|
|
66
65
|
this.pwd = pwd ? node_path_1.default.resolve(pwd) : process.cwd();
|
|
67
66
|
}
|
|
68
67
|
/**
|
|
69
|
-
*
|
|
68
|
+
* Resolves relative paths against `pwd` while preserving absolute paths.
|
|
70
69
|
*/
|
|
70
|
+
resolve(src) {
|
|
71
|
+
return node_path_1.default.resolve(this.pwd, src);
|
|
72
|
+
}
|
|
71
73
|
test(src, options) {
|
|
72
74
|
return test_1.test.call(this, src, options);
|
|
73
75
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Returns `lstat` information for a path.
|
|
76
|
-
*/
|
|
77
76
|
stat(src, options) {
|
|
78
77
|
return stat_1.stat.call(this, src, options);
|
|
79
78
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Applies a mode recursively to a file or directory tree.
|
|
82
|
-
*/
|
|
83
79
|
chmod(src, mode, options) {
|
|
84
80
|
return chmod_1.chmod.call(this, src, mode, options);
|
|
85
81
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Applies ownership recursively to a file or directory tree.
|
|
88
|
-
*/
|
|
89
82
|
chown(src, options) {
|
|
90
83
|
return chown_1.chown.call(this, src, options);
|
|
91
84
|
}
|
|
92
|
-
/**
|
|
93
|
-
* Creates a symbolic link from `dest` to `src`.
|
|
94
|
-
*/
|
|
95
85
|
symlink(src, dest, options) {
|
|
96
86
|
return symlink_1.symlink.call(this, src, dest, options);
|
|
97
87
|
}
|
|
98
|
-
/**
|
|
99
|
-
* Copies `src` into the destination directory.
|
|
100
|
-
*/
|
|
101
88
|
copy(src, dest, options) {
|
|
102
89
|
return copy_1.copy.call(this, src, dest, options);
|
|
103
90
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Renames or moves a file system node.
|
|
106
|
-
*/
|
|
107
91
|
rename(src, dest, options) {
|
|
108
92
|
return rename_1.rename.call(this, src, dest, options);
|
|
109
93
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Removes a file system node recursively.
|
|
112
|
-
*/
|
|
113
94
|
remove(src, options) {
|
|
114
95
|
return remove_1.remove.call(this, src, options);
|
|
115
96
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Removes all directory entries while preserving the directory itself.
|
|
118
|
-
*/
|
|
119
97
|
emptyDir(src, options) {
|
|
120
98
|
return empty_dir_1.emptyDir.call(this, src, options);
|
|
121
99
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Reads a file relative to the current instance root.
|
|
124
|
-
*/
|
|
125
100
|
read(src, options) {
|
|
126
101
|
return read_1.read.call(this, src, options);
|
|
127
102
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Writes a file and applies the resulting permissions explicitly.
|
|
130
|
-
*/
|
|
131
103
|
write(src, data, options) {
|
|
132
104
|
return write_1.write.call(this, src, data, options);
|
|
133
105
|
}
|
|
134
|
-
/**
|
|
135
|
-
* @deprecated Use `write(..., { flag: 'a' })` instead.
|
|
136
|
-
*/
|
|
137
106
|
append(src, data, options) {
|
|
138
107
|
return append_1.append.call(this, src, data, options);
|
|
139
108
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Lists directory entries relative to the current instance root.
|
|
142
|
-
*/
|
|
143
109
|
readdir(dir, options) {
|
|
144
110
|
return readdir_1.readdir.call(this, dir, options);
|
|
145
111
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Resolves the target of a symbolic link.
|
|
148
|
-
*/
|
|
149
112
|
readlink(src, options) {
|
|
150
113
|
return readlink_1.readlink.call(this, src, options);
|
|
151
114
|
}
|
|
152
|
-
/**
|
|
153
|
-
* Resolves a path to its canonical absolute location.
|
|
154
|
-
*/
|
|
155
115
|
realpath(src, options) {
|
|
156
116
|
return realpath_1.realpath.call(this, src, options);
|
|
157
117
|
}
|
|
158
|
-
/**
|
|
159
|
-
* Creates a directory tree relative to the current instance root.
|
|
160
|
-
*/
|
|
161
118
|
mkdir(dir, options) {
|
|
162
119
|
return mkdir_1.mkdir.call(this, dir, options);
|
|
163
120
|
}
|
|
@@ -4,8 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
8
|
const node_test_1 = require("node:test");
|
|
8
9
|
const index_1 = require("./index");
|
|
10
|
+
const test_utils_1 = require("./test-utils");
|
|
9
11
|
/**
|
|
10
12
|
* Verifies constructor path resolution semantics for the main API surface.
|
|
11
13
|
*/
|
|
@@ -18,4 +20,27 @@ const index_1 = require("./index");
|
|
|
18
20
|
const { pwd } = new index_1.PoweredFileSystem(__dirname);
|
|
19
21
|
(0, node_assert_1.default)(pwd === __dirname);
|
|
20
22
|
});
|
|
23
|
+
(0, node_test_1.it)('Positive: Resolve should accept paths inside the working directory', () => {
|
|
24
|
+
const tmpDir = (0, test_utils_1.createTmpDir)();
|
|
25
|
+
try {
|
|
26
|
+
const pfs = new index_1.PoweredFileSystem(tmpDir);
|
|
27
|
+
const resolved = pfs.resolve('./nested/file.txt');
|
|
28
|
+
(0, node_assert_1.default)(resolved === node_path_1.default.join(tmpDir, 'nested', 'file.txt'));
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
(0, test_utils_1.restore)(tmpDir);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
(0, node_test_1.it)('Positive: Resolve should preserve absolute paths outside the working directory', () => {
|
|
35
|
+
const tmpDir = (0, test_utils_1.createTmpDir)();
|
|
36
|
+
const outsidePath = node_path_1.default.resolve(node_path_1.default.dirname(tmpDir), 'outside.txt');
|
|
37
|
+
try {
|
|
38
|
+
const pfs = new index_1.PoweredFileSystem(tmpDir);
|
|
39
|
+
const resolved = pfs.resolve(outsidePath);
|
|
40
|
+
(0, node_assert_1.default)(resolved === outsidePath);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
(0, test_utils_1.restore)(tmpDir);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
21
46
|
});
|
|
@@ -6,7 +6,7 @@ export declare function chmodSync(src: string, mode: number): void;
|
|
|
6
6
|
/**
|
|
7
7
|
* Synchronous counterpart of the recursive chown implementation.
|
|
8
8
|
*/
|
|
9
|
-
export declare function chownSync(src: string, uid: number, gid: number): void;
|
|
9
|
+
export declare function chownSync(src: string, uid: number | undefined, gid: number | undefined): void;
|
|
10
10
|
/**
|
|
11
11
|
* Synchronously copies a file system node into the target directory.
|
|
12
12
|
*/
|
package/dist/recurse-io-sync.js
CHANGED
|
@@ -29,19 +29,16 @@ function chmodSync(src, mode) {
|
|
|
29
29
|
*/
|
|
30
30
|
function chownSync(src, uid, gid) {
|
|
31
31
|
const stats = node_fs_1.default.statSync(src);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (gid === 0) {
|
|
36
|
-
gid = stats.gid;
|
|
37
|
-
}
|
|
32
|
+
// `0` is a valid uid/gid, so only nullish values mean "preserve current owner".
|
|
33
|
+
const nextUid = uid ?? stats.uid;
|
|
34
|
+
const nextGid = gid ?? stats.gid;
|
|
38
35
|
if (stats.isDirectory()) {
|
|
39
36
|
const list = node_fs_1.default.readdirSync(src);
|
|
40
37
|
for (const loc of list) {
|
|
41
|
-
chownSync(node_path_1.default.join(src, loc),
|
|
38
|
+
chownSync(node_path_1.default.join(src, loc), nextUid, nextGid);
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
|
-
node_fs_1.default.chownSync(src,
|
|
41
|
+
node_fs_1.default.chownSync(src, nextUid, nextGid);
|
|
45
42
|
}
|
|
46
43
|
/**
|
|
47
44
|
* Synchronously copies a file system node into the target directory.
|
|
@@ -59,6 +56,7 @@ function copySync(src, dir, options) {
|
|
|
59
56
|
if (stat.isDirectory()) {
|
|
60
57
|
const list = node_fs_1.default.readdirSync(src);
|
|
61
58
|
const mode = 0o777 & ~options.umask;
|
|
59
|
+
// Overwrite is implemented as replace-before-copy to support directory targets.
|
|
62
60
|
if (options.overwrite && node_fs_1.default.existsSync(dest)) {
|
|
63
61
|
removeSync(dest);
|
|
64
62
|
}
|
|
@@ -68,10 +66,12 @@ function copySync(src, dir, options) {
|
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
else {
|
|
69
|
+
// Match directory behavior by replacing the existing target before writing.
|
|
71
70
|
if (options.overwrite && node_fs_1.default.existsSync(dest)) {
|
|
72
71
|
removeSync(dest);
|
|
73
72
|
}
|
|
74
|
-
node_fs_1.default.
|
|
73
|
+
const flags = options.overwrite ? 0 : node_fs_1.default.constants.COPYFILE_EXCL;
|
|
74
|
+
node_fs_1.default.copyFileSync(src, dest, flags);
|
|
75
75
|
node_fs_1.default.chmodSync(dest, 0o666 & ~options.umask);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -79,21 +79,7 @@ function copySync(src, dir, options) {
|
|
|
79
79
|
* Synchronously removes files, directories, and symlinks without following links.
|
|
80
80
|
*/
|
|
81
81
|
function removeSync(src) {
|
|
82
|
-
|
|
83
|
-
if (stats.isSymbolicLink()) {
|
|
84
|
-
node_fs_1.default.unlinkSync(src);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (stats.isDirectory()) {
|
|
88
|
-
const list = node_fs_1.default.readdirSync(src);
|
|
89
|
-
for (const loc of list) {
|
|
90
|
-
removeSync(node_path_1.default.join(src, loc));
|
|
91
|
-
}
|
|
92
|
-
node_fs_1.default.rmdirSync(src);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
node_fs_1.default.unlinkSync(src);
|
|
96
|
-
}
|
|
82
|
+
node_fs_1.default.rmSync(src, { recursive: true, force: false });
|
|
97
83
|
}
|
|
98
84
|
/**
|
|
99
85
|
* Synchronously removes all entries inside a directory while preserving it.
|
|
@@ -101,7 +87,7 @@ function removeSync(src) {
|
|
|
101
87
|
function emptyDirSync(src) {
|
|
102
88
|
const list = node_fs_1.default.readdirSync(src);
|
|
103
89
|
for (const loc of list) {
|
|
104
|
-
|
|
90
|
+
node_fs_1.default.rmSync(node_path_1.default.join(src, loc), { recursive: true, force: false });
|
|
105
91
|
}
|
|
106
92
|
}
|
|
107
93
|
/**
|