@zenfs/core 1.3.6 → 1.4.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/backends/memory.d.ts +4 -4
- package/dist/backends/memory.js +4 -4
- package/dist/backends/overlay.d.ts +5 -2
- package/dist/backends/overlay.js +7 -10
- package/dist/backends/port/fs.js +1 -4
- package/dist/config.js +4 -8
- package/dist/context.d.ts +32 -0
- package/dist/context.js +23 -0
- package/dist/credentials.d.ts +5 -5
- package/dist/credentials.js +10 -6
- package/dist/emulation/async.d.ts +90 -89
- package/dist/emulation/async.js +76 -75
- package/dist/emulation/dir.d.ts +3 -1
- package/dist/emulation/dir.js +6 -7
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/promises.d.ts +50 -48
- package/dist/emulation/promises.js +78 -77
- package/dist/emulation/shared.d.ts +35 -8
- package/dist/emulation/shared.js +37 -11
- package/dist/emulation/sync.d.ts +63 -62
- package/dist/emulation/sync.js +72 -73
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/stats.d.ts +2 -1
- package/dist/stats.js +5 -4
- package/package.json +3 -5
- package/scripts/test.js +78 -17
- package/tests/assignment.ts +1 -1
- package/tests/common/context.test.ts +19 -0
- package/tests/{devices.test.ts → common/devices.test.ts} +3 -3
- package/tests/{handle.test.ts → common/handle.test.ts} +1 -1
- package/tests/common/mounts.test.ts +36 -0
- package/tests/{mutex.test.ts → common/mutex.test.ts} +3 -3
- package/tests/common/path.test.ts +34 -0
- package/tests/common.ts +4 -3
- package/tests/fs/dir.test.ts +11 -11
- package/tests/fs/directory.test.ts +17 -17
- package/tests/fs/errors.test.ts +29 -39
- package/tests/fs/watch.test.ts +2 -2
- package/tests/setup/context.ts +9 -0
- package/tests/setup/cow+fetch.ts +1 -1
- package/tests/setup/memory.ts +1 -1
- package/tests/{setup/common.ts → setup.ts} +6 -5
- package/src/backends/backend.ts +0 -161
- package/src/backends/fetch.ts +0 -180
- package/src/backends/file_index.ts +0 -206
- package/src/backends/memory.ts +0 -45
- package/src/backends/overlay.ts +0 -560
- package/src/backends/port/fs.ts +0 -329
- package/src/backends/port/readme.md +0 -54
- package/src/backends/port/rpc.ts +0 -167
- package/src/backends/readme.md +0 -3
- package/src/backends/store/fs.ts +0 -667
- package/src/backends/store/readme.md +0 -9
- package/src/backends/store/simple.ts +0 -154
- package/src/backends/store/store.ts +0 -189
- package/src/config.ts +0 -227
- package/src/credentials.ts +0 -49
- package/src/devices.ts +0 -521
- package/src/emulation/async.ts +0 -834
- package/src/emulation/cache.ts +0 -86
- package/src/emulation/config.ts +0 -21
- package/src/emulation/constants.ts +0 -182
- package/src/emulation/dir.ts +0 -138
- package/src/emulation/index.ts +0 -8
- package/src/emulation/path.ts +0 -440
- package/src/emulation/promises.ts +0 -1140
- package/src/emulation/shared.ts +0 -172
- package/src/emulation/streams.ts +0 -34
- package/src/emulation/sync.ts +0 -863
- package/src/emulation/watchers.ts +0 -194
- package/src/error.ts +0 -307
- package/src/file.ts +0 -631
- package/src/filesystem.ts +0 -174
- package/src/index.ts +0 -35
- package/src/inode.ts +0 -128
- package/src/mixins/async.ts +0 -230
- package/src/mixins/index.ts +0 -5
- package/src/mixins/mutexed.ts +0 -257
- package/src/mixins/readonly.ts +0 -96
- package/src/mixins/shared.ts +0 -25
- package/src/mixins/sync.ts +0 -58
- package/src/polyfills.ts +0 -21
- package/src/stats.ts +0 -405
- package/src/utils.ts +0 -276
- package/tests/mounts.test.ts +0 -18
- package/tests/path.test.ts +0 -34
package/src/emulation/sync.ts
DELETED
|
@@ -1,863 +0,0 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
|
-
import type * as fs from 'node:fs';
|
|
3
|
-
import { Errno, ErrnoError } from '../error.js';
|
|
4
|
-
import type { File } from '../file.js';
|
|
5
|
-
import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js';
|
|
6
|
-
import type { FileContents } from '../filesystem.js';
|
|
7
|
-
import { BigIntStats, type Stats } from '../stats.js';
|
|
8
|
-
import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
9
|
-
import * as cache from './cache.js';
|
|
10
|
-
import { config } from './config.js';
|
|
11
|
-
import * as constants from './constants.js';
|
|
12
|
-
import { Dir, Dirent } from './dir.js';
|
|
13
|
-
import { dirname, join, parse, resolve } from './path.js';
|
|
14
|
-
import { _statfs, fd2file, fdMap, file2fd, fixError, resolveMount, type InternalOptions, type ReaddirOptions } from './shared.js';
|
|
15
|
-
import { emitChange } from './watchers.js';
|
|
16
|
-
|
|
17
|
-
export function renameSync(oldPath: fs.PathLike, newPath: fs.PathLike): void {
|
|
18
|
-
oldPath = normalizePath(oldPath);
|
|
19
|
-
newPath = normalizePath(newPath);
|
|
20
|
-
const oldMount = resolveMount(oldPath);
|
|
21
|
-
const newMount = resolveMount(newPath);
|
|
22
|
-
if (config.checkAccess && !statSync(dirname(oldPath)).hasAccess(constants.W_OK)) {
|
|
23
|
-
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
if (oldMount === newMount) {
|
|
27
|
-
oldMount.fs.renameSync(oldMount.path, newMount.path);
|
|
28
|
-
emitChange('rename', oldPath.toString());
|
|
29
|
-
emitChange('change', newPath.toString());
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
writeFileSync(newPath, readFileSync(oldPath));
|
|
34
|
-
unlinkSync(oldPath);
|
|
35
|
-
emitChange('rename', oldPath.toString());
|
|
36
|
-
} catch (e) {
|
|
37
|
-
throw fixError(e as ErrnoError, { [oldMount.path]: oldPath, [newMount.path]: newPath });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
renameSync satisfies typeof fs.renameSync;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Test whether or not `path` exists by checking with the file system.
|
|
44
|
-
*/
|
|
45
|
-
export function existsSync(path: fs.PathLike): boolean {
|
|
46
|
-
path = normalizePath(path);
|
|
47
|
-
try {
|
|
48
|
-
const { fs, path: resolvedPath } = resolveMount(realpathSync(path));
|
|
49
|
-
return fs.existsSync(resolvedPath);
|
|
50
|
-
} catch (e) {
|
|
51
|
-
if ((e as ErrnoError).errno == Errno.ENOENT) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
throw e;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
existsSync satisfies typeof fs.existsSync;
|
|
59
|
-
|
|
60
|
-
export function statSync(path: fs.PathLike, options?: { bigint?: boolean }): Stats;
|
|
61
|
-
export function statSync(path: fs.PathLike, options: { bigint: true }): BigIntStats;
|
|
62
|
-
export function statSync(path: fs.PathLike, options?: fs.StatOptions): Stats | BigIntStats {
|
|
63
|
-
path = normalizePath(path);
|
|
64
|
-
const { fs, path: resolved } = resolveMount(realpathSync(path));
|
|
65
|
-
try {
|
|
66
|
-
const stats = fs.statSync(resolved);
|
|
67
|
-
if (config.checkAccess && !stats.hasAccess(constants.R_OK)) {
|
|
68
|
-
throw ErrnoError.With('EACCES', resolved, 'stat');
|
|
69
|
-
}
|
|
70
|
-
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
71
|
-
} catch (e) {
|
|
72
|
-
throw fixError(e as ErrnoError, { [resolved]: path });
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
statSync satisfies typeof fs.statSync;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Synchronous `lstat`.
|
|
79
|
-
* `lstat()` is identical to `stat()`, except that if path is a symbolic link,
|
|
80
|
-
* then the link itself is stat-ed, not the file that it refers to.
|
|
81
|
-
*/
|
|
82
|
-
export function lstatSync(path: fs.PathLike, options?: { bigint?: boolean }): Stats;
|
|
83
|
-
export function lstatSync(path: fs.PathLike, options: { bigint: true }): BigIntStats;
|
|
84
|
-
export function lstatSync(path: fs.PathLike, options?: fs.StatOptions): Stats | BigIntStats {
|
|
85
|
-
path = normalizePath(path);
|
|
86
|
-
const { fs, path: resolved } = resolveMount(path);
|
|
87
|
-
try {
|
|
88
|
-
const stats = fs.statSync(resolved);
|
|
89
|
-
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
90
|
-
} catch (e) {
|
|
91
|
-
throw fixError(e as ErrnoError, { [resolved]: path });
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
lstatSync satisfies typeof fs.lstatSync;
|
|
95
|
-
|
|
96
|
-
export function truncateSync(path: fs.PathLike, len: number | null = 0): void {
|
|
97
|
-
using file = _openSync(path, 'r+');
|
|
98
|
-
len ||= 0;
|
|
99
|
-
if (len < 0) {
|
|
100
|
-
throw new ErrnoError(Errno.EINVAL);
|
|
101
|
-
}
|
|
102
|
-
file.truncateSync(len);
|
|
103
|
-
}
|
|
104
|
-
truncateSync satisfies typeof fs.truncateSync;
|
|
105
|
-
|
|
106
|
-
export function unlinkSync(path: fs.PathLike): void {
|
|
107
|
-
path = normalizePath(path);
|
|
108
|
-
const { fs, path: resolved } = resolveMount(path);
|
|
109
|
-
try {
|
|
110
|
-
if (config.checkAccess && !(cache.stats.get(path) || fs.statSync(resolved)).hasAccess(constants.W_OK)) {
|
|
111
|
-
throw ErrnoError.With('EACCES', resolved, 'unlink');
|
|
112
|
-
}
|
|
113
|
-
fs.unlinkSync(resolved);
|
|
114
|
-
emitChange('rename', path.toString());
|
|
115
|
-
} catch (e) {
|
|
116
|
-
throw fixError(e as ErrnoError, { [resolved]: path });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
unlinkSync satisfies typeof fs.unlinkSync;
|
|
120
|
-
|
|
121
|
-
function _openSync(path: fs.PathLike, _flag: fs.OpenMode, _mode?: fs.Mode | null, resolveSymlinks: boolean = true): File {
|
|
122
|
-
path = normalizePath(path);
|
|
123
|
-
const mode = normalizeMode(_mode, 0o644),
|
|
124
|
-
flag = parseFlag(_flag);
|
|
125
|
-
|
|
126
|
-
path = resolveSymlinks ? realpathSync(path) : path;
|
|
127
|
-
const { fs, path: resolved } = resolveMount(path);
|
|
128
|
-
|
|
129
|
-
let stats: Stats | undefined;
|
|
130
|
-
try {
|
|
131
|
-
stats = fs.statSync(resolved);
|
|
132
|
-
} catch {
|
|
133
|
-
// nothing
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!stats) {
|
|
137
|
-
if ((!isWriteable(flag) && !isAppendable(flag)) || flag == 'r+') {
|
|
138
|
-
throw ErrnoError.With('ENOENT', path, '_open');
|
|
139
|
-
}
|
|
140
|
-
// Create the file
|
|
141
|
-
const parentStats: Stats = fs.statSync(dirname(resolved));
|
|
142
|
-
if (config.checkAccess && !parentStats.hasAccess(constants.W_OK)) {
|
|
143
|
-
throw ErrnoError.With('EACCES', dirname(path), '_open');
|
|
144
|
-
}
|
|
145
|
-
if (!parentStats.isDirectory()) {
|
|
146
|
-
throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
|
|
147
|
-
}
|
|
148
|
-
return fs.createFileSync(resolved, flag, mode);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (config.checkAccess && (!stats.hasAccess(mode) || !stats.hasAccess(flagToMode(flag)))) {
|
|
152
|
-
throw ErrnoError.With('EACCES', path, '_open');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (isExclusive(flag)) {
|
|
156
|
-
throw ErrnoError.With('EEXIST', path, '_open');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const file = fs.openFileSync(resolved, flag);
|
|
160
|
-
|
|
161
|
-
if (isTruncating(flag)) {
|
|
162
|
-
file.truncateSync(0);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return file;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Synchronous file open.
|
|
170
|
-
* @see http://www.manpagez.com/man/2/open/
|
|
171
|
-
*/
|
|
172
|
-
export function openSync(path: fs.PathLike, flag: fs.OpenMode, mode: fs.Mode | null = constants.F_OK): number {
|
|
173
|
-
return file2fd(_openSync(path, flag, mode, true));
|
|
174
|
-
}
|
|
175
|
-
openSync satisfies typeof fs.openSync;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Opens a file or symlink
|
|
179
|
-
* @internal
|
|
180
|
-
*/
|
|
181
|
-
export function lopenSync(path: fs.PathLike, flag: string, mode?: fs.Mode | null): number {
|
|
182
|
-
return file2fd(_openSync(path, flag, mode, false));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function _readFileSync(fname: string, flag: string, resolveSymlinks: boolean): Uint8Array {
|
|
186
|
-
// Get file.
|
|
187
|
-
using file = _openSync(fname, flag, 0o644, resolveSymlinks);
|
|
188
|
-
const stat = file.statSync();
|
|
189
|
-
// Allocate buffer.
|
|
190
|
-
const data = new Uint8Array(stat.size);
|
|
191
|
-
file.readSync(data, 0, stat.size, 0);
|
|
192
|
-
return data;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Synchronously reads the entire contents of a file.
|
|
197
|
-
* @option encoding The string encoding for the file contents. Defaults to `null`.
|
|
198
|
-
* @option flag Defaults to `'r'`.
|
|
199
|
-
* @returns file contents
|
|
200
|
-
*/
|
|
201
|
-
export function readFileSync(path: fs.PathOrFileDescriptor, options?: { flag?: string } | null): Buffer;
|
|
202
|
-
export function readFileSync(path: fs.PathOrFileDescriptor, options?: (fs.EncodingOption & { flag?: string }) | BufferEncoding | null): string;
|
|
203
|
-
export function readFileSync(path: fs.PathOrFileDescriptor, _options: fs.WriteFileOptions | null = {}): FileContents {
|
|
204
|
-
const options = normalizeOptions(_options, null, 'r', 0o644);
|
|
205
|
-
const flag = parseFlag(options.flag);
|
|
206
|
-
if (!isReadable(flag)) {
|
|
207
|
-
throw new ErrnoError(Errno.EINVAL, 'Flag passed to readFile must allow for reading.');
|
|
208
|
-
}
|
|
209
|
-
const data: Buffer = Buffer.from(_readFileSync(typeof path == 'number' ? fd2file(path).path : path.toString(), options.flag, true));
|
|
210
|
-
return options.encoding ? data.toString(options.encoding) : data;
|
|
211
|
-
}
|
|
212
|
-
readFileSync satisfies typeof fs.readFileSync;
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Synchronously writes data to a file, replacing the file if it already exists.
|
|
216
|
-
*
|
|
217
|
-
* The encoding option is ignored if data is a buffer.
|
|
218
|
-
* @option encoding Defaults to `'utf8'`.
|
|
219
|
-
* @option mode Defaults to `0644`.
|
|
220
|
-
* @option flag Defaults to `'w'`.
|
|
221
|
-
*/
|
|
222
|
-
export function writeFileSync(path: fs.PathOrFileDescriptor, data: FileContents, options?: fs.WriteFileOptions): void;
|
|
223
|
-
export function writeFileSync(path: fs.PathOrFileDescriptor, data: FileContents, encoding?: BufferEncoding): void;
|
|
224
|
-
export function writeFileSync(path: fs.PathOrFileDescriptor, data: FileContents, _options: fs.WriteFileOptions | BufferEncoding = {}): void {
|
|
225
|
-
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
226
|
-
const flag = parseFlag(options.flag);
|
|
227
|
-
if (!isWriteable(flag)) {
|
|
228
|
-
throw new ErrnoError(Errno.EINVAL, 'Flag passed to writeFile must allow for writing.');
|
|
229
|
-
}
|
|
230
|
-
if (typeof data != 'string' && !options.encoding) {
|
|
231
|
-
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
232
|
-
}
|
|
233
|
-
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding!) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
234
|
-
if (!encodedData) {
|
|
235
|
-
throw new ErrnoError(Errno.EINVAL, 'Data not specified');
|
|
236
|
-
}
|
|
237
|
-
using file = _openSync(typeof path == 'number' ? fd2file(path).path : path.toString(), flag, options.mode, true);
|
|
238
|
-
file.writeSync(encodedData, 0, encodedData.byteLength, 0);
|
|
239
|
-
emitChange('change', path.toString());
|
|
240
|
-
}
|
|
241
|
-
writeFileSync satisfies typeof fs.writeFileSync;
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Asynchronously append data to a file, creating the file if it not yet exists.
|
|
245
|
-
* @option encoding Defaults to `'utf8'`.
|
|
246
|
-
* @option mode Defaults to `0644`.
|
|
247
|
-
* @option flag Defaults to `'a+'`.
|
|
248
|
-
*/
|
|
249
|
-
export function appendFileSync(filename: fs.PathOrFileDescriptor, data: FileContents, _options: fs.WriteFileOptions = {}): void {
|
|
250
|
-
const options = normalizeOptions(_options, 'utf8', 'a+', 0o644);
|
|
251
|
-
const flag = parseFlag(options.flag);
|
|
252
|
-
if (!isAppendable(flag)) {
|
|
253
|
-
throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending.');
|
|
254
|
-
}
|
|
255
|
-
if (typeof data != 'string' && !options.encoding) {
|
|
256
|
-
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
257
|
-
}
|
|
258
|
-
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding!) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
259
|
-
using file = _openSync(typeof filename == 'number' ? fd2file(filename).path : filename.toString(), flag, options.mode, true);
|
|
260
|
-
file.writeSync(encodedData, 0, encodedData.byteLength);
|
|
261
|
-
}
|
|
262
|
-
appendFileSync satisfies typeof fs.appendFileSync;
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Synchronous `fstat`.
|
|
266
|
-
* `fstat()` is identical to `stat()`, except that the file to be stat-ed is
|
|
267
|
-
* specified by the file descriptor `fd`.
|
|
268
|
-
*/
|
|
269
|
-
export function fstatSync(fd: number, options?: { bigint?: boolean }): Stats;
|
|
270
|
-
export function fstatSync(fd: number, options: { bigint: true }): BigIntStats;
|
|
271
|
-
export function fstatSync(fd: number, options?: fs.StatOptions): Stats | BigIntStats {
|
|
272
|
-
const stats: Stats = fd2file(fd).statSync();
|
|
273
|
-
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
274
|
-
}
|
|
275
|
-
fstatSync satisfies typeof fs.fstatSync;
|
|
276
|
-
|
|
277
|
-
export function closeSync(fd: number): void {
|
|
278
|
-
fd2file(fd).closeSync();
|
|
279
|
-
fdMap.delete(fd);
|
|
280
|
-
}
|
|
281
|
-
closeSync satisfies typeof fs.closeSync;
|
|
282
|
-
|
|
283
|
-
export function ftruncateSync(fd: number, len: number | null = 0): void {
|
|
284
|
-
len ||= 0;
|
|
285
|
-
if (len < 0) {
|
|
286
|
-
throw new ErrnoError(Errno.EINVAL);
|
|
287
|
-
}
|
|
288
|
-
fd2file(fd).truncateSync(len);
|
|
289
|
-
}
|
|
290
|
-
ftruncateSync satisfies typeof fs.ftruncateSync;
|
|
291
|
-
|
|
292
|
-
export function fsyncSync(fd: number): void {
|
|
293
|
-
fd2file(fd).syncSync();
|
|
294
|
-
}
|
|
295
|
-
fsyncSync satisfies typeof fs.fsyncSync;
|
|
296
|
-
|
|
297
|
-
export function fdatasyncSync(fd: number): void {
|
|
298
|
-
fd2file(fd).datasyncSync();
|
|
299
|
-
}
|
|
300
|
-
fdatasyncSync satisfies typeof fs.fdatasyncSync;
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Write buffer to the file specified by `fd`.
|
|
304
|
-
* @param data Uint8Array containing the data to write to the file.
|
|
305
|
-
* @param offset Offset in the buffer to start reading data from.
|
|
306
|
-
* @param length The amount of bytes to write to the file.
|
|
307
|
-
* @param position Offset from the beginning of the file where this data should be written.
|
|
308
|
-
* If position is null, the data will be written at the current position.
|
|
309
|
-
*/
|
|
310
|
-
export function writeSync(fd: number, data: ArrayBufferView, offset?: number | null, length?: number | null, position?: number | null): number;
|
|
311
|
-
export function writeSync(fd: number, data: string, position?: number | null, encoding?: BufferEncoding | null): number;
|
|
312
|
-
export function writeSync(fd: number, data: FileContents, posOrOff?: number | null, lenOrEnc?: BufferEncoding | number | null, pos?: number | null): number {
|
|
313
|
-
let buffer: Uint8Array, offset: number | undefined, length: number, position: number | null;
|
|
314
|
-
if (typeof data === 'string') {
|
|
315
|
-
// Signature 1: (fd, string, [position?, [encoding?]])
|
|
316
|
-
position = typeof posOrOff === 'number' ? posOrOff : null;
|
|
317
|
-
const encoding = typeof lenOrEnc === 'string' ? lenOrEnc : ('utf8' as BufferEncoding);
|
|
318
|
-
offset = 0;
|
|
319
|
-
buffer = Buffer.from(data, encoding);
|
|
320
|
-
length = buffer.byteLength;
|
|
321
|
-
} else {
|
|
322
|
-
// Signature 2: (fd, buffer, offset, length, position?)
|
|
323
|
-
buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
324
|
-
offset = posOrOff!;
|
|
325
|
-
length = lenOrEnc as number;
|
|
326
|
-
position = typeof pos === 'number' ? pos : null;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const file = fd2file(fd);
|
|
330
|
-
position ??= file.position;
|
|
331
|
-
const bytesWritten = file.writeSync(buffer, offset, length, position);
|
|
332
|
-
emitChange('change', file.path);
|
|
333
|
-
return bytesWritten;
|
|
334
|
-
}
|
|
335
|
-
writeSync satisfies typeof fs.writeSync;
|
|
336
|
-
|
|
337
|
-
export function readSync(fd: number, buffer: ArrayBufferView, options?: fs.ReadSyncOptions): number;
|
|
338
|
-
export function readSync(fd: number, buffer: ArrayBufferView, offset: number, length: number, position?: fs.ReadPosition | null): number;
|
|
339
|
-
/**
|
|
340
|
-
* Read data from the file specified by `fd`.
|
|
341
|
-
* @param buffer The buffer that the data will be written to.
|
|
342
|
-
* @param offset The offset within the buffer where writing will start.
|
|
343
|
-
* @param length An integer specifying the number of bytes to read.
|
|
344
|
-
* @param position An integer specifying where to begin reading from in the file.
|
|
345
|
-
* If position is null, data will be read from the current file position.
|
|
346
|
-
*/
|
|
347
|
-
export function readSync(fd: number, buffer: ArrayBufferView, options?: fs.ReadSyncOptions | number, length?: number, position?: fs.ReadPosition | null): number {
|
|
348
|
-
const file = fd2file(fd);
|
|
349
|
-
const offset = typeof options == 'object' ? options.offset : options;
|
|
350
|
-
if (typeof options == 'object') {
|
|
351
|
-
length = options.length;
|
|
352
|
-
position = options.position;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
position = Number(position);
|
|
356
|
-
if (isNaN(position)) {
|
|
357
|
-
position = file.position!;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return file.readSync(buffer, offset, length, position);
|
|
361
|
-
}
|
|
362
|
-
readSync satisfies typeof fs.readSync;
|
|
363
|
-
|
|
364
|
-
export function fchownSync(fd: number, uid: number, gid: number): void {
|
|
365
|
-
fd2file(fd).chownSync(uid, gid);
|
|
366
|
-
}
|
|
367
|
-
fchownSync satisfies typeof fs.fchownSync;
|
|
368
|
-
|
|
369
|
-
export function fchmodSync(fd: number, mode: number | string): void {
|
|
370
|
-
const numMode = normalizeMode(mode, -1);
|
|
371
|
-
if (numMode < 0) {
|
|
372
|
-
throw new ErrnoError(Errno.EINVAL, `Invalid mode.`);
|
|
373
|
-
}
|
|
374
|
-
fd2file(fd).chmodSync(numMode);
|
|
375
|
-
}
|
|
376
|
-
fchmodSync satisfies typeof fs.fchmodSync;
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Change the file timestamps of a file referenced by the supplied file descriptor.
|
|
380
|
-
*/
|
|
381
|
-
export function futimesSync(fd: number, atime: string | number | Date, mtime: string | number | Date): void {
|
|
382
|
-
fd2file(fd).utimesSync(normalizeTime(atime), normalizeTime(mtime));
|
|
383
|
-
}
|
|
384
|
-
futimesSync satisfies typeof fs.futimesSync;
|
|
385
|
-
|
|
386
|
-
export function rmdirSync(path: fs.PathLike): void {
|
|
387
|
-
path = normalizePath(path);
|
|
388
|
-
const { fs, path: resolved } = resolveMount(realpathSync(path));
|
|
389
|
-
try {
|
|
390
|
-
const stats = cache.stats.get(path) || fs.statSync(resolved);
|
|
391
|
-
if (!stats.isDirectory()) {
|
|
392
|
-
throw ErrnoError.With('ENOTDIR', resolved, 'rmdir');
|
|
393
|
-
}
|
|
394
|
-
if (config.checkAccess && !stats.hasAccess(constants.W_OK)) {
|
|
395
|
-
throw ErrnoError.With('EACCES', resolved, 'rmdir');
|
|
396
|
-
}
|
|
397
|
-
fs.rmdirSync(resolved);
|
|
398
|
-
emitChange('rename', path.toString());
|
|
399
|
-
} catch (e) {
|
|
400
|
-
throw fixError(e as ErrnoError, { [resolved]: path });
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
rmdirSync satisfies typeof fs.rmdirSync;
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Synchronous `mkdir`. Mode defaults to `o777`.
|
|
407
|
-
*/
|
|
408
|
-
export function mkdirSync(path: fs.PathLike, options: fs.MakeDirectoryOptions & { recursive: true }): string | undefined;
|
|
409
|
-
export function mkdirSync(path: fs.PathLike, options?: fs.Mode | (fs.MakeDirectoryOptions & { recursive?: false }) | null): void;
|
|
410
|
-
export function mkdirSync(path: fs.PathLike, options?: fs.Mode | fs.MakeDirectoryOptions | null): string | undefined;
|
|
411
|
-
export function mkdirSync(path: fs.PathLike, options?: fs.Mode | fs.MakeDirectoryOptions | null): string | undefined | void {
|
|
412
|
-
options = typeof options === 'object' ? options : { mode: options };
|
|
413
|
-
const mode = normalizeMode(options?.mode, 0o777);
|
|
414
|
-
|
|
415
|
-
path = realpathSync(path);
|
|
416
|
-
const { fs, path: resolved } = resolveMount(path);
|
|
417
|
-
const errorPaths: Record<string, string> = { [resolved]: path };
|
|
418
|
-
|
|
419
|
-
try {
|
|
420
|
-
if (!options?.recursive) {
|
|
421
|
-
if (config.checkAccess && !fs.statSync(dirname(resolved)).hasAccess(constants.W_OK)) {
|
|
422
|
-
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
423
|
-
}
|
|
424
|
-
return fs.mkdirSync(resolved, mode);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const dirs: string[] = [];
|
|
428
|
-
for (let dir = resolved, original = path; !fs.existsSync(dir); dir = dirname(dir), original = dirname(original)) {
|
|
429
|
-
dirs.unshift(dir);
|
|
430
|
-
errorPaths[dir] = original;
|
|
431
|
-
}
|
|
432
|
-
for (const dir of dirs) {
|
|
433
|
-
if (config.checkAccess && !fs.statSync(dirname(dir)).hasAccess(constants.W_OK)) {
|
|
434
|
-
throw ErrnoError.With('EACCES', dirname(dir), 'mkdir');
|
|
435
|
-
}
|
|
436
|
-
fs.mkdirSync(dir, mode);
|
|
437
|
-
emitChange('rename', dir);
|
|
438
|
-
}
|
|
439
|
-
return dirs[0];
|
|
440
|
-
} catch (e) {
|
|
441
|
-
throw fixError(e as ErrnoError, errorPaths);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
mkdirSync satisfies typeof fs.mkdirSync;
|
|
445
|
-
|
|
446
|
-
export function readdirSync(path: fs.PathLike, options?: (fs.ObjectEncodingOptions & ReaddirOptions & { withFileTypes?: false }) | BufferEncoding | null): string[];
|
|
447
|
-
export function readdirSync(path: fs.PathLike, options: fs.BufferEncodingOption & ReaddirOptions & { withFileTypes?: false }): Buffer[];
|
|
448
|
-
export function readdirSync(path: fs.PathLike, options?: (fs.ObjectEncodingOptions & ReaddirOptions & { withFileTypes?: false }) | BufferEncoding | null): string[] | Buffer[];
|
|
449
|
-
export function readdirSync(path: fs.PathLike, options: fs.ObjectEncodingOptions & ReaddirOptions & { withFileTypes: true }): Dirent[];
|
|
450
|
-
export function readdirSync(
|
|
451
|
-
path: fs.PathLike,
|
|
452
|
-
options?: (ReaddirOptions & (fs.ObjectEncodingOptions | fs.BufferEncodingOption)) | BufferEncoding | null
|
|
453
|
-
): string[] | Dirent[] | Buffer[];
|
|
454
|
-
export function readdirSync(
|
|
455
|
-
path: fs.PathLike,
|
|
456
|
-
options?: (ReaddirOptions & (fs.ObjectEncodingOptions | fs.BufferEncodingOption)) | BufferEncoding | null
|
|
457
|
-
): string[] | Dirent[] | Buffer[] {
|
|
458
|
-
options = typeof options === 'object' ? options : { encoding: options };
|
|
459
|
-
path = normalizePath(path);
|
|
460
|
-
const { fs, path: resolved } = resolveMount(realpathSync(path));
|
|
461
|
-
let entries: string[];
|
|
462
|
-
try {
|
|
463
|
-
const stats = cache.stats.get(path) || fs.statSync(resolved);
|
|
464
|
-
cache.stats.set(path, stats);
|
|
465
|
-
if (config.checkAccess && !stats.hasAccess(constants.R_OK)) {
|
|
466
|
-
throw ErrnoError.With('EACCES', resolved, 'readdir');
|
|
467
|
-
}
|
|
468
|
-
if (!stats.isDirectory()) {
|
|
469
|
-
throw ErrnoError.With('ENOTDIR', resolved, 'readdir');
|
|
470
|
-
}
|
|
471
|
-
entries = fs.readdirSync(resolved);
|
|
472
|
-
} catch (e) {
|
|
473
|
-
throw fixError(e as ErrnoError, { [resolved]: path });
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Iterate over entries and handle recursive case if needed
|
|
477
|
-
const values: (string | Dirent | Buffer)[] = [];
|
|
478
|
-
for (const entry of entries) {
|
|
479
|
-
const entryStat = cache.stats.get(join(path, entry)) || fs.statSync(join(resolved, entry));
|
|
480
|
-
cache.stats.set(join(path, entry), entryStat);
|
|
481
|
-
|
|
482
|
-
if (options?.withFileTypes) {
|
|
483
|
-
values.push(new Dirent(entry, entryStat));
|
|
484
|
-
} else if (options?.encoding == 'buffer') {
|
|
485
|
-
values.push(Buffer.from(entry));
|
|
486
|
-
} else {
|
|
487
|
-
values.push(entry);
|
|
488
|
-
}
|
|
489
|
-
if (!entryStat.isDirectory() || !options?.recursive) continue;
|
|
490
|
-
|
|
491
|
-
for (const subEntry of readdirSync(join(path, entry), { ...options, _isIndirect: true })) {
|
|
492
|
-
if (subEntry instanceof Dirent) {
|
|
493
|
-
subEntry.path = join(entry, subEntry.path);
|
|
494
|
-
values.push(subEntry);
|
|
495
|
-
} else if (Buffer.isBuffer(subEntry)) {
|
|
496
|
-
values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
|
|
497
|
-
} else {
|
|
498
|
-
values.push(join(entry, subEntry));
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
if (!options?._isIndirect) {
|
|
504
|
-
cache.stats.clear();
|
|
505
|
-
}
|
|
506
|
-
return values as string[] | Dirent[] | Buffer[];
|
|
507
|
-
}
|
|
508
|
-
readdirSync satisfies typeof fs.readdirSync;
|
|
509
|
-
|
|
510
|
-
// SYMLINK METHODS
|
|
511
|
-
|
|
512
|
-
export function linkSync(targetPath: fs.PathLike, linkPath: fs.PathLike): void {
|
|
513
|
-
targetPath = normalizePath(targetPath);
|
|
514
|
-
if (config.checkAccess && !statSync(dirname(targetPath)).hasAccess(constants.R_OK)) {
|
|
515
|
-
throw ErrnoError.With('EACCES', dirname(targetPath), 'link');
|
|
516
|
-
}
|
|
517
|
-
linkPath = normalizePath(linkPath);
|
|
518
|
-
if (config.checkAccess && !statSync(dirname(linkPath)).hasAccess(constants.W_OK)) {
|
|
519
|
-
throw ErrnoError.With('EACCES', dirname(linkPath), 'link');
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const { fs, path } = resolveMount(targetPath);
|
|
523
|
-
const link = resolveMount(linkPath);
|
|
524
|
-
if (fs != link.fs) {
|
|
525
|
-
throw ErrnoError.With('EXDEV', linkPath, 'link');
|
|
526
|
-
}
|
|
527
|
-
try {
|
|
528
|
-
if (config.checkAccess && !fs.statSync(path).hasAccess(constants.R_OK)) {
|
|
529
|
-
throw ErrnoError.With('EACCES', path, 'link');
|
|
530
|
-
}
|
|
531
|
-
return fs.linkSync(path, linkPath);
|
|
532
|
-
} catch (e) {
|
|
533
|
-
throw fixError(e as ErrnoError, { [path]: targetPath, [link.path]: linkPath });
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
linkSync satisfies typeof fs.linkSync;
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Synchronous `symlink`.
|
|
540
|
-
* @param target target path
|
|
541
|
-
* @param path link path
|
|
542
|
-
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
543
|
-
*/
|
|
544
|
-
export function symlinkSync(target: fs.PathLike, path: fs.PathLike, type: fs.symlink.Type | null = 'file'): void {
|
|
545
|
-
if (!['file', 'dir', 'junction'].includes(type!)) {
|
|
546
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid type: ' + type);
|
|
547
|
-
}
|
|
548
|
-
if (existsSync(path)) {
|
|
549
|
-
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
writeFileSync(path, target.toString());
|
|
553
|
-
const file = _openSync(path, 'r+', 0o644, false);
|
|
554
|
-
file.chmodSync(constants.S_IFLNK);
|
|
555
|
-
}
|
|
556
|
-
symlinkSync satisfies typeof fs.symlinkSync;
|
|
557
|
-
|
|
558
|
-
export function readlinkSync(path: fs.PathLike, options?: fs.BufferEncodingOption): Buffer;
|
|
559
|
-
export function readlinkSync(path: fs.PathLike, options: fs.EncodingOption | BufferEncoding): string;
|
|
560
|
-
export function readlinkSync(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding | fs.BufferEncodingOption): Buffer | string;
|
|
561
|
-
export function readlinkSync(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding | fs.BufferEncodingOption): Buffer | string {
|
|
562
|
-
const value: Buffer = Buffer.from(_readFileSync(path.toString(), 'r', false));
|
|
563
|
-
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
564
|
-
if (encoding == 'buffer') {
|
|
565
|
-
return value;
|
|
566
|
-
}
|
|
567
|
-
return value.toString(encoding!);
|
|
568
|
-
}
|
|
569
|
-
readlinkSync satisfies typeof fs.readlinkSync;
|
|
570
|
-
|
|
571
|
-
// PROPERTY OPERATIONS
|
|
572
|
-
|
|
573
|
-
export function chownSync(path: fs.PathLike, uid: number, gid: number): void {
|
|
574
|
-
const fd = openSync(path, 'r+');
|
|
575
|
-
fchownSync(fd, uid, gid);
|
|
576
|
-
closeSync(fd);
|
|
577
|
-
}
|
|
578
|
-
chownSync satisfies typeof fs.chownSync;
|
|
579
|
-
|
|
580
|
-
export function lchownSync(path: fs.PathLike, uid: number, gid: number): void {
|
|
581
|
-
const fd = lopenSync(path, 'r+');
|
|
582
|
-
fchownSync(fd, uid, gid);
|
|
583
|
-
closeSync(fd);
|
|
584
|
-
}
|
|
585
|
-
lchownSync satisfies typeof fs.lchownSync;
|
|
586
|
-
|
|
587
|
-
export function chmodSync(path: fs.PathLike, mode: fs.Mode): void {
|
|
588
|
-
const fd = openSync(path, 'r+');
|
|
589
|
-
fchmodSync(fd, mode);
|
|
590
|
-
closeSync(fd);
|
|
591
|
-
}
|
|
592
|
-
chmodSync satisfies typeof fs.chmodSync;
|
|
593
|
-
|
|
594
|
-
export function lchmodSync(path: fs.PathLike, mode: number | string): void {
|
|
595
|
-
const fd = lopenSync(path, 'r+');
|
|
596
|
-
fchmodSync(fd, mode);
|
|
597
|
-
closeSync(fd);
|
|
598
|
-
}
|
|
599
|
-
lchmodSync satisfies typeof fs.lchmodSync;
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Change file timestamps of the file referenced by the supplied path.
|
|
603
|
-
*/
|
|
604
|
-
export function utimesSync(path: fs.PathLike, atime: string | number | Date, mtime: string | number | Date): void {
|
|
605
|
-
const fd = openSync(path, 'r+');
|
|
606
|
-
futimesSync(fd, atime, mtime);
|
|
607
|
-
closeSync(fd);
|
|
608
|
-
}
|
|
609
|
-
utimesSync satisfies typeof fs.utimesSync;
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Change file timestamps of the file referenced by the supplied path.
|
|
613
|
-
*/
|
|
614
|
-
export function lutimesSync(path: fs.PathLike, atime: string | number | Date, mtime: string | number | Date): void {
|
|
615
|
-
const fd = lopenSync(path, 'r+');
|
|
616
|
-
futimesSync(fd, atime, mtime);
|
|
617
|
-
closeSync(fd);
|
|
618
|
-
}
|
|
619
|
-
lutimesSync satisfies typeof fs.lutimesSync;
|
|
620
|
-
|
|
621
|
-
export function realpathSync(path: fs.PathLike, options: fs.BufferEncodingOption): Buffer;
|
|
622
|
-
export function realpathSync(path: fs.PathLike, options?: fs.EncodingOption): string;
|
|
623
|
-
export function realpathSync(path: fs.PathLike, options?: fs.EncodingOption | fs.BufferEncodingOption): string | Buffer {
|
|
624
|
-
path = normalizePath(path);
|
|
625
|
-
if (cache.paths.has(path)) return cache.paths.get(path)!;
|
|
626
|
-
const { base, dir } = parse(path);
|
|
627
|
-
const realDir = dir == '/' ? '/' : cache.paths.get(dir) || realpathSync(dir);
|
|
628
|
-
const lpath = join(realDir, base);
|
|
629
|
-
const { fs, path: resolvedPath } = resolveMount(lpath);
|
|
630
|
-
|
|
631
|
-
try {
|
|
632
|
-
const stats = cache.stats.get(lpath) || fs.statSync(resolvedPath);
|
|
633
|
-
cache.stats.set(lpath, stats);
|
|
634
|
-
if (!stats.isSymbolicLink()) {
|
|
635
|
-
cache.paths.set(path, lpath);
|
|
636
|
-
return lpath;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
const target = resolve(realDir, readlinkSync(lpath, options).toString());
|
|
640
|
-
const real = cache.paths.get(target) || realpathSync(target);
|
|
641
|
-
cache.paths.set(path, real);
|
|
642
|
-
return real;
|
|
643
|
-
} catch (e) {
|
|
644
|
-
if ((e as ErrnoError).code == 'ENOENT') {
|
|
645
|
-
return path;
|
|
646
|
-
}
|
|
647
|
-
throw fixError(e as ErrnoError, { [resolvedPath]: lpath });
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
realpathSync satisfies Omit<typeof fs.realpathSync, 'native'>;
|
|
651
|
-
|
|
652
|
-
export function accessSync(path: fs.PathLike, mode: number = 0o600): void {
|
|
653
|
-
if (!config.checkAccess) return;
|
|
654
|
-
if (!statSync(path).hasAccess(mode)) {
|
|
655
|
-
throw new ErrnoError(Errno.EACCES);
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
accessSync satisfies typeof fs.accessSync;
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Synchronous `rm`. Removes files or directories (recursively).
|
|
662
|
-
* @param path The path to the file or directory to remove.
|
|
663
|
-
*/
|
|
664
|
-
export function rmSync(path: fs.PathLike, options?: fs.RmOptions & InternalOptions): void {
|
|
665
|
-
path = normalizePath(path);
|
|
666
|
-
|
|
667
|
-
let stats: Stats | undefined;
|
|
668
|
-
try {
|
|
669
|
-
stats = cache.stats.get(path) || statSync(path);
|
|
670
|
-
} catch (error) {
|
|
671
|
-
if ((error as ErrnoError).code != 'ENOENT' || !options?.force) throw error;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
if (!stats) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
cache.stats.set(path, stats);
|
|
679
|
-
|
|
680
|
-
switch (stats.mode & constants.S_IFMT) {
|
|
681
|
-
case constants.S_IFDIR:
|
|
682
|
-
if (options?.recursive) {
|
|
683
|
-
for (const entry of readdirSync(path, { _isIndirect: true })) {
|
|
684
|
-
rmSync(join(path, entry), { ...options, _isIndirect: true });
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
rmdirSync(path);
|
|
689
|
-
break;
|
|
690
|
-
case constants.S_IFREG:
|
|
691
|
-
case constants.S_IFLNK:
|
|
692
|
-
case constants.S_IFBLK:
|
|
693
|
-
case constants.S_IFCHR:
|
|
694
|
-
unlinkSync(path);
|
|
695
|
-
break;
|
|
696
|
-
case constants.S_IFIFO:
|
|
697
|
-
case constants.S_IFSOCK:
|
|
698
|
-
default:
|
|
699
|
-
cache.stats.clear();
|
|
700
|
-
throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
if (!options?._isIndirect) {
|
|
704
|
-
cache.stats.clear();
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
rmSync satisfies typeof fs.rmSync;
|
|
708
|
-
|
|
709
|
-
/**
|
|
710
|
-
* Synchronous `mkdtemp`. Creates a unique temporary directory.
|
|
711
|
-
* @param prefix The directory prefix.
|
|
712
|
-
* @param options The encoding (or an object including `encoding`).
|
|
713
|
-
* @returns The path to the created temporary directory, encoded as a string or buffer.
|
|
714
|
-
*/
|
|
715
|
-
export function mkdtempSync(prefix: string, options: fs.BufferEncodingOption): Buffer;
|
|
716
|
-
export function mkdtempSync(prefix: string, options?: fs.EncodingOption): string;
|
|
717
|
-
export function mkdtempSync(prefix: string, options?: fs.EncodingOption | fs.BufferEncodingOption): string | Buffer {
|
|
718
|
-
const encoding = typeof options === 'object' ? options?.encoding : options || 'utf8';
|
|
719
|
-
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
720
|
-
const resolvedPath = '/tmp/' + fsName;
|
|
721
|
-
|
|
722
|
-
mkdirSync(resolvedPath);
|
|
723
|
-
|
|
724
|
-
return encoding == 'buffer' ? Buffer.from(resolvedPath) : resolvedPath;
|
|
725
|
-
}
|
|
726
|
-
mkdtempSync satisfies typeof fs.mkdtempSync;
|
|
727
|
-
|
|
728
|
-
/**
|
|
729
|
-
* Synchronous `copyFile`. Copies a file.
|
|
730
|
-
* @param flags Optional flags for the copy operation. Currently supports these flags:
|
|
731
|
-
* - `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
732
|
-
*/
|
|
733
|
-
export function copyFileSync(source: fs.PathLike, destination: fs.PathLike, flags?: number): void {
|
|
734
|
-
source = normalizePath(source);
|
|
735
|
-
destination = normalizePath(destination);
|
|
736
|
-
|
|
737
|
-
if (flags && flags & constants.COPYFILE_EXCL && existsSync(destination)) {
|
|
738
|
-
throw new ErrnoError(Errno.EEXIST, 'Destination file already exists.', destination, 'copyFile');
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
writeFileSync(destination, readFileSync(source));
|
|
742
|
-
emitChange('rename', destination.toString());
|
|
743
|
-
}
|
|
744
|
-
copyFileSync satisfies typeof fs.copyFileSync;
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* Synchronous `readv`. Reads from a file descriptor into multiple buffers.
|
|
748
|
-
* @param fd The file descriptor.
|
|
749
|
-
* @param buffers An array of Uint8Array buffers.
|
|
750
|
-
* @param position The position in the file where to begin reading.
|
|
751
|
-
* @returns The number of bytes read.
|
|
752
|
-
*/
|
|
753
|
-
export function readvSync(fd: number, buffers: readonly NodeJS.ArrayBufferView[], position?: number): number {
|
|
754
|
-
const file = fd2file(fd);
|
|
755
|
-
let bytesRead = 0;
|
|
756
|
-
|
|
757
|
-
for (const buffer of buffers) {
|
|
758
|
-
bytesRead += file.readSync(buffer, 0, buffer.byteLength, position! + bytesRead);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
return bytesRead;
|
|
762
|
-
}
|
|
763
|
-
readvSync satisfies typeof fs.readvSync;
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Synchronous `writev`. Writes from multiple buffers into a file descriptor.
|
|
767
|
-
* @param fd The file descriptor.
|
|
768
|
-
* @param buffers An array of Uint8Array buffers.
|
|
769
|
-
* @param position The position in the file where to begin writing.
|
|
770
|
-
* @returns The number of bytes written.
|
|
771
|
-
*/
|
|
772
|
-
export function writevSync(fd: number, buffers: readonly ArrayBufferView[], position?: number): number {
|
|
773
|
-
const file = fd2file(fd);
|
|
774
|
-
let bytesWritten = 0;
|
|
775
|
-
|
|
776
|
-
for (const buffer of buffers) {
|
|
777
|
-
bytesWritten += file.writeSync(new Uint8Array(buffer.buffer), 0, buffer.byteLength, position! + bytesWritten);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
return bytesWritten;
|
|
781
|
-
}
|
|
782
|
-
writevSync satisfies typeof fs.writevSync;
|
|
783
|
-
|
|
784
|
-
/**
|
|
785
|
-
* Synchronous `opendir`. Opens a directory.
|
|
786
|
-
* @param path The path to the directory.
|
|
787
|
-
* @param options Options for opening the directory.
|
|
788
|
-
* @returns A `Dir` object representing the opened directory.
|
|
789
|
-
* @todo Handle options
|
|
790
|
-
*/
|
|
791
|
-
export function opendirSync(path: fs.PathLike, options?: fs.OpenDirOptions): Dir {
|
|
792
|
-
path = normalizePath(path);
|
|
793
|
-
return new Dir(path);
|
|
794
|
-
}
|
|
795
|
-
opendirSync satisfies typeof fs.opendirSync;
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Synchronous `cp`. Recursively copies a file or directory.
|
|
799
|
-
* @param source The source file or directory.
|
|
800
|
-
* @param destination The destination file or directory.
|
|
801
|
-
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
|
|
802
|
-
* - `dereference`: Dereference symbolic links. *(unconfirmed)*
|
|
803
|
-
* - `errorOnExist`: Throw an error if the destination file or directory already exists.
|
|
804
|
-
* - `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy `source` element.
|
|
805
|
-
* - `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files. *(unconfirmed)*
|
|
806
|
-
* - `preserveTimestamps`: Preserve file timestamps.
|
|
807
|
-
* - `recursive`: If `true`, copies directories recursively.
|
|
808
|
-
*/
|
|
809
|
-
export function cpSync(source: fs.PathLike, destination: fs.PathLike, opts?: fs.CopySyncOptions): void {
|
|
810
|
-
source = normalizePath(source);
|
|
811
|
-
destination = normalizePath(destination);
|
|
812
|
-
|
|
813
|
-
const srcStats = lstatSync(source); // Use lstat to follow symlinks if not dereferencing
|
|
814
|
-
|
|
815
|
-
if (opts?.errorOnExist && existsSync(destination)) {
|
|
816
|
-
throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
switch (srcStats.mode & constants.S_IFMT) {
|
|
820
|
-
case constants.S_IFDIR:
|
|
821
|
-
if (!opts?.recursive) {
|
|
822
|
-
throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
823
|
-
}
|
|
824
|
-
mkdirSync(destination, { recursive: true }); // Ensure the destination directory exists
|
|
825
|
-
for (const dirent of readdirSync(source, { withFileTypes: true })) {
|
|
826
|
-
if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
|
|
827
|
-
continue; // Skip if the filter returns false
|
|
828
|
-
}
|
|
829
|
-
cpSync(join(source, dirent.name), join(destination, dirent.name), opts);
|
|
830
|
-
}
|
|
831
|
-
break;
|
|
832
|
-
case constants.S_IFREG:
|
|
833
|
-
case constants.S_IFLNK:
|
|
834
|
-
copyFileSync(source, destination);
|
|
835
|
-
break;
|
|
836
|
-
case constants.S_IFBLK:
|
|
837
|
-
case constants.S_IFCHR:
|
|
838
|
-
case constants.S_IFIFO:
|
|
839
|
-
case constants.S_IFSOCK:
|
|
840
|
-
default:
|
|
841
|
-
throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
// Optionally preserve timestamps
|
|
845
|
-
if (opts?.preserveTimestamps) {
|
|
846
|
-
utimesSync(destination, srcStats.atime, srcStats.mtime);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
cpSync satisfies typeof fs.cpSync;
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* Synchronous statfs(2). Returns information about the mounted file system which contains path.
|
|
853
|
-
* In case of an error, the err.code will be one of Common System Errors.
|
|
854
|
-
* @param path A path to an existing file or directory on the file system to be queried.
|
|
855
|
-
*/
|
|
856
|
-
export function statfsSync(path: fs.PathLike, options?: fs.StatFsOptions & { bigint?: false }): fs.StatsFs;
|
|
857
|
-
export function statfsSync(path: fs.PathLike, options: fs.StatFsOptions & { bigint: true }): fs.BigIntStatsFs;
|
|
858
|
-
export function statfsSync(path: fs.PathLike, options?: fs.StatFsOptions): fs.StatsFs | fs.BigIntStatsFs;
|
|
859
|
-
export function statfsSync(path: fs.PathLike, options?: fs.StatFsOptions): fs.StatsFs | fs.BigIntStatsFs {
|
|
860
|
-
path = normalizePath(path);
|
|
861
|
-
const { fs } = resolveMount(path);
|
|
862
|
-
return _statfs(fs, options?.bigint);
|
|
863
|
-
}
|