@zenfs/core 0.8.0 → 0.9.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/ApiError.d.ts +2 -0
- package/dist/ApiError.js +3 -0
- package/dist/backends/AsyncStore.d.ts +2 -8
- package/dist/{FileIndex.d.ts → backends/FileIndex.d.ts} +9 -9
- package/dist/{FileIndex.js → backends/FileIndex.js} +10 -10
- package/dist/backends/Overlay.js +8 -8
- package/dist/backends/SyncStore.js +11 -11
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/async.d.ts +45 -20
- package/dist/emulation/async.js +78 -16
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/promises.d.ts +62 -16
- package/dist/emulation/promises.js +201 -34
- package/dist/emulation/shared.d.ts +1 -46
- package/dist/emulation/shared.js +3 -95
- package/dist/emulation/sync.d.ts +38 -10
- package/dist/emulation/sync.js +123 -24
- package/dist/filesystem.d.ts +3 -0
- package/dist/filesystem.js +3 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils.d.ts +45 -0
- package/dist/utils.js +94 -1
- package/package.json +1 -1
package/dist/emulation/sync.js
CHANGED
|
@@ -2,9 +2,11 @@ import { Buffer } from 'buffer';
|
|
|
2
2
|
import { ApiError, ErrorCode } from '../ApiError.js';
|
|
3
3
|
import { ActionType, isAppendable, isReadable, isWriteable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
|
|
4
4
|
import { BigIntStats, FileType } from '../stats.js';
|
|
5
|
-
import {
|
|
5
|
+
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
6
|
+
import { COPYFILE_EXCL, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } from './constants.js';
|
|
7
|
+
import { Dir, Dirent } from './dir.js';
|
|
6
8
|
import { dirname, join, parse } from './path.js';
|
|
7
|
-
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts,
|
|
9
|
+
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, resolveMount } from './shared.js';
|
|
8
10
|
function doOp(...[name, resolveSymlinks, path, ...args]) {
|
|
9
11
|
path = normalizePath(path);
|
|
10
12
|
const { fs, path: resolvedPath } = resolveMount(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
|
|
@@ -104,22 +106,22 @@ function _openSync(_path, _flag, _mode, resolveSymlinks) {
|
|
|
104
106
|
// Ensure parent exists.
|
|
105
107
|
const parentStats = doOp('statSync', resolveSymlinks, dirname(path), cred);
|
|
106
108
|
if (!parentStats.isDirectory()) {
|
|
107
|
-
throw ApiError.With('ENOTDIR', dirname(path), '
|
|
109
|
+
throw ApiError.With('ENOTDIR', dirname(path), '_open');
|
|
108
110
|
}
|
|
109
111
|
return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
|
|
110
112
|
case ActionType.THROW:
|
|
111
|
-
throw ApiError.With('ENOENT', path, '
|
|
113
|
+
throw ApiError.With('ENOENT', path, '_open');
|
|
112
114
|
default:
|
|
113
115
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
if (!stats.hasAccess(mode, cred)) {
|
|
117
|
-
throw ApiError.With('EACCES', path, '
|
|
119
|
+
throw ApiError.With('EACCES', path, '_open');
|
|
118
120
|
}
|
|
119
121
|
// File exists.
|
|
120
122
|
switch (pathExistsAction(flag)) {
|
|
121
123
|
case ActionType.THROW:
|
|
122
|
-
throw ApiError.With('EEXIST', path, '
|
|
124
|
+
throw ApiError.With('EEXIST', path, '_open');
|
|
123
125
|
case ActionType.TRUNCATE:
|
|
124
126
|
// Delete file.
|
|
125
127
|
doOp('unlinkSync', resolveSymlinks, path, cred);
|
|
@@ -426,7 +428,7 @@ export function symlinkSync(target, path, type = 'file') {
|
|
|
426
428
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid type: ' + type);
|
|
427
429
|
}
|
|
428
430
|
if (existsSync(path)) {
|
|
429
|
-
throw ApiError.With('EEXIST', path, '
|
|
431
|
+
throw ApiError.With('EEXIST', path, 'symlink');
|
|
430
432
|
}
|
|
431
433
|
writeFileSync(path, target);
|
|
432
434
|
const file = _openSync(path, 'r+', 0o644, false);
|
|
@@ -542,54 +544,151 @@ export function accessSync(path, mode = 0o600) {
|
|
|
542
544
|
}
|
|
543
545
|
}
|
|
544
546
|
accessSync;
|
|
545
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
546
547
|
/**
|
|
547
|
-
*
|
|
548
|
+
* Synchronous `rm`. Removes files or directories (recursively).
|
|
549
|
+
* @param path The path to the file or directory to remove.
|
|
548
550
|
*/
|
|
549
|
-
export function rmSync(path) {
|
|
550
|
-
|
|
551
|
+
export function rmSync(path, options) {
|
|
552
|
+
path = normalizePath(path);
|
|
553
|
+
const stats = statSync(path);
|
|
554
|
+
switch (stats.mode & S_IFMT) {
|
|
555
|
+
case S_IFDIR:
|
|
556
|
+
if (options?.recursive) {
|
|
557
|
+
for (const entry of readdirSync(path)) {
|
|
558
|
+
rmSync(join(path, entry));
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
rmdirSync(path);
|
|
562
|
+
return;
|
|
563
|
+
case S_IFREG:
|
|
564
|
+
case S_IFLNK:
|
|
565
|
+
unlinkSync(path);
|
|
566
|
+
return;
|
|
567
|
+
case S_IFBLK:
|
|
568
|
+
case S_IFCHR:
|
|
569
|
+
case S_IFIFO:
|
|
570
|
+
case S_IFSOCK:
|
|
571
|
+
default:
|
|
572
|
+
throw new ApiError(ErrorCode.EPERM, 'File type not supported', path, 'rm');
|
|
573
|
+
}
|
|
551
574
|
}
|
|
552
575
|
rmSync;
|
|
553
576
|
export function mkdtempSync(prefix, options) {
|
|
554
|
-
|
|
577
|
+
const encoding = typeof options === 'object' ? options.encoding : options || 'utf8';
|
|
578
|
+
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
579
|
+
const resolvedPath = '/tmp/' + fsName;
|
|
580
|
+
mkdirSync(resolvedPath);
|
|
581
|
+
return encoding == 'buffer' ? Buffer.from(resolvedPath) : resolvedPath;
|
|
555
582
|
}
|
|
556
583
|
mkdtempSync;
|
|
557
584
|
/**
|
|
558
|
-
*
|
|
585
|
+
* Synchronous `copyFile`. Copies a file.
|
|
586
|
+
* @param src The source file.
|
|
587
|
+
* @param dest The destination file.
|
|
588
|
+
* @param flags Optional flags for the copy operation. Currently supports these flags:
|
|
589
|
+
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
559
590
|
*/
|
|
560
591
|
export function copyFileSync(src, dest, flags) {
|
|
561
|
-
|
|
592
|
+
src = normalizePath(src);
|
|
593
|
+
dest = normalizePath(dest);
|
|
594
|
+
if (flags && flags & COPYFILE_EXCL && existsSync(dest)) {
|
|
595
|
+
throw new ApiError(ErrorCode.EEXIST, 'Destination file already exists.', dest, 'copyFile');
|
|
596
|
+
}
|
|
597
|
+
writeFileSync(dest, readFileSync(src));
|
|
562
598
|
}
|
|
563
599
|
copyFileSync;
|
|
564
600
|
/**
|
|
565
|
-
*
|
|
601
|
+
* Synchronous `readv`. Reads from a file descriptor into multiple buffers.
|
|
602
|
+
* @param fd The file descriptor.
|
|
603
|
+
* @param buffers An array of Uint8Array buffers.
|
|
604
|
+
* @param position The position in the file where to begin reading.
|
|
605
|
+
* @returns The number of bytes read.
|
|
566
606
|
*/
|
|
567
607
|
export function readvSync(fd, buffers, position) {
|
|
568
|
-
|
|
608
|
+
const file = fd2file(fd);
|
|
609
|
+
let bytesRead = 0;
|
|
610
|
+
for (const buffer of buffers) {
|
|
611
|
+
bytesRead += file.readSync(buffer, 0, buffer.length, position + bytesRead);
|
|
612
|
+
}
|
|
613
|
+
return bytesRead;
|
|
569
614
|
}
|
|
570
615
|
readvSync;
|
|
571
616
|
/**
|
|
572
|
-
*
|
|
617
|
+
* Synchronous `writev`. Writes from multiple buffers into a file descriptor.
|
|
618
|
+
* @param fd The file descriptor.
|
|
619
|
+
* @param buffers An array of Uint8Array buffers.
|
|
620
|
+
* @param position The position in the file where to begin writing.
|
|
621
|
+
* @returns The number of bytes written.
|
|
573
622
|
*/
|
|
574
623
|
export function writevSync(fd, buffers, position) {
|
|
575
|
-
|
|
624
|
+
const file = fd2file(fd);
|
|
625
|
+
let bytesWritten = 0;
|
|
626
|
+
for (const buffer of buffers) {
|
|
627
|
+
bytesWritten += file.writeSync(buffer, 0, buffer.length, position + bytesWritten);
|
|
628
|
+
}
|
|
629
|
+
return bytesWritten;
|
|
576
630
|
}
|
|
577
631
|
writevSync;
|
|
578
632
|
/**
|
|
579
|
-
*
|
|
633
|
+
* Synchronous `opendir`. Opens a directory.
|
|
634
|
+
* @param path The path to the directory.
|
|
635
|
+
* @param options Options for opening the directory.
|
|
636
|
+
* @returns A `Dir` object representing the opened directory.
|
|
580
637
|
*/
|
|
581
638
|
export function opendirSync(path, options) {
|
|
582
|
-
|
|
639
|
+
path = normalizePath(path);
|
|
640
|
+
return new Dir(path); // Re-use existing `Dir` class
|
|
583
641
|
}
|
|
584
642
|
opendirSync;
|
|
585
643
|
/**
|
|
586
|
-
*
|
|
644
|
+
* Synchronous `cp`. Recursively copies a file or directory.
|
|
645
|
+
* @param source The source file or directory.
|
|
646
|
+
* @param destination The destination file or directory.
|
|
647
|
+
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
|
|
648
|
+
* * `dereference`: Dereference symbolic links.
|
|
649
|
+
* * `errorOnExist`: Throw an error if the destination file or directory already exists.
|
|
650
|
+
* * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
|
|
651
|
+
* * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
|
|
652
|
+
* * `preserveTimestamps`: Preserve file timestamps.
|
|
653
|
+
* * `recursive`: If `true`, copies directories recursively.
|
|
587
654
|
*/
|
|
588
655
|
export function cpSync(source, destination, opts) {
|
|
589
|
-
|
|
656
|
+
source = normalizePath(source);
|
|
657
|
+
destination = normalizePath(destination);
|
|
658
|
+
const srcStats = lstatSync(source); // Use lstat to follow symlinks if not dereferencing
|
|
659
|
+
if (opts?.errorOnExist && existsSync(destination)) {
|
|
660
|
+
throw new ApiError(ErrorCode.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
661
|
+
}
|
|
662
|
+
switch (srcStats.mode & S_IFMT) {
|
|
663
|
+
case S_IFDIR:
|
|
664
|
+
if (!opts?.recursive) {
|
|
665
|
+
throw new ApiError(ErrorCode.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
666
|
+
}
|
|
667
|
+
mkdirSync(destination, { recursive: true }); // Ensure the destination directory exists
|
|
668
|
+
for (const dirent of readdirSync(source, { withFileTypes: true })) {
|
|
669
|
+
if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
|
|
670
|
+
continue; // Skip if the filter returns false
|
|
671
|
+
}
|
|
672
|
+
cpSync(join(source, dirent.name), join(destination, dirent.name), opts);
|
|
673
|
+
}
|
|
674
|
+
break;
|
|
675
|
+
case S_IFREG:
|
|
676
|
+
case S_IFLNK:
|
|
677
|
+
copyFileSync(source, destination);
|
|
678
|
+
break;
|
|
679
|
+
case S_IFBLK:
|
|
680
|
+
case S_IFCHR:
|
|
681
|
+
case S_IFIFO:
|
|
682
|
+
case S_IFSOCK:
|
|
683
|
+
default:
|
|
684
|
+
throw new ApiError(ErrorCode.EPERM, 'File type not supported', source, 'rm');
|
|
685
|
+
}
|
|
686
|
+
// Optionally preserve timestamps
|
|
687
|
+
if (opts?.preserveTimestamps) {
|
|
688
|
+
utimesSync(destination, srcStats.atime, srcStats.mtime);
|
|
689
|
+
}
|
|
590
690
|
}
|
|
591
691
|
cpSync;
|
|
592
692
|
export function statfsSync(path, options) {
|
|
593
|
-
throw ApiError.With('
|
|
693
|
+
throw ApiError.With('ENOSYS', path, 'statfs');
|
|
594
694
|
}
|
|
595
|
-
/* eslint-enable @typescript-eslint/no-unused-vars */
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -220,5 +220,8 @@ declare abstract class ReadonlyFileSystem extends FileSystem {
|
|
|
220
220
|
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
221
221
|
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
222
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Implements the non-readonly methods to throw `EROFS`
|
|
225
|
+
*/
|
|
223
226
|
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFileSystem) & T;
|
|
224
227
|
export {};
|
package/dist/filesystem.js
CHANGED
|
@@ -24,7 +24,6 @@ export class FileSystem {
|
|
|
24
24
|
freeSpace: 0,
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
|
28
27
|
constructor(options) {
|
|
29
28
|
// unused
|
|
30
29
|
}
|
|
@@ -57,9 +56,6 @@ export class FileSystem {
|
|
|
57
56
|
* Implements the asynchronous API in terms of the synchronous API.
|
|
58
57
|
*/
|
|
59
58
|
export function Sync(FS) {
|
|
60
|
-
/**
|
|
61
|
-
* Implements the asynchronous API in terms of the synchronous API.
|
|
62
|
-
*/
|
|
63
59
|
class _SyncFileSystem extends FS {
|
|
64
60
|
async ready() {
|
|
65
61
|
return this;
|
|
@@ -239,6 +235,9 @@ export function Async(FS) {
|
|
|
239
235
|
}
|
|
240
236
|
return _AsyncFileSystem;
|
|
241
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Implements the non-readonly methods to throw `EROFS`
|
|
240
|
+
*/
|
|
242
241
|
export function Readonly(FS) {
|
|
243
242
|
class _ReadonlyFileSystem extends FS {
|
|
244
243
|
metadata() {
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export * from './config.js';
|
|
|
9
9
|
export * from './cred.js';
|
|
10
10
|
export * from './file.js';
|
|
11
11
|
export * from './filesystem.js';
|
|
12
|
-
export * from './FileIndex.js';
|
|
12
|
+
export * from './backends/FileIndex.js';
|
|
13
13
|
export * from './inode.js';
|
|
14
14
|
export * from './mutex.js';
|
|
15
15
|
export * from './stats.js';
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export * from './config.js';
|
|
|
9
9
|
export * from './cred.js';
|
|
10
10
|
export * from './file.js';
|
|
11
11
|
export * from './filesystem.js';
|
|
12
|
-
export * from './FileIndex.js';
|
|
12
|
+
export * from './backends/FileIndex.js';
|
|
13
13
|
export * from './inode.js';
|
|
14
14
|
export * from './mutex.js';
|
|
15
15
|
export * from './stats.js';
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
1
3
|
import type { OptionalTuple } from 'utilium';
|
|
2
4
|
import { ApiError } from './ApiError.js';
|
|
3
5
|
import { Cred } from './cred.js';
|
|
@@ -41,3 +43,46 @@ export declare function decodeDirListing(data: Uint8Array): Record<string, bigin
|
|
|
41
43
|
*/
|
|
42
44
|
export declare function encodeDirListing(data: Record<string, bigint>): Uint8Array;
|
|
43
45
|
export type Callback<Args extends unknown[] = []> = (e?: ApiError, ...args: OptionalTuple<Args>) => unknown;
|
|
46
|
+
import type { EncodingOption, OpenMode, WriteFileOptions } from 'node:fs';
|
|
47
|
+
/**
|
|
48
|
+
* converts Date or number to a integer UNIX timestamp
|
|
49
|
+
* Grabbed from NodeJS sources (lib/fs.js)
|
|
50
|
+
*
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
export declare function _toUnixTimestamp(time: Date | number): number;
|
|
54
|
+
/**
|
|
55
|
+
* Normalizes a mode
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export declare function normalizeMode(mode: string | number | unknown, def?: number): number;
|
|
59
|
+
/**
|
|
60
|
+
* Normalizes a time
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export declare function normalizeTime(time: string | number | Date): Date;
|
|
64
|
+
/**
|
|
65
|
+
* Normalizes a path
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
export declare function normalizePath(p: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Normalizes options
|
|
71
|
+
* @param options options to normalize
|
|
72
|
+
* @param encoding default encoding
|
|
73
|
+
* @param flag default flag
|
|
74
|
+
* @param mode default mode
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
export declare function normalizeOptions(options?: WriteFileOptions | (EncodingOption & {
|
|
78
|
+
flag?: OpenMode;
|
|
79
|
+
}), encoding?: BufferEncoding, flag?: string, mode?: number): {
|
|
80
|
+
encoding: BufferEncoding;
|
|
81
|
+
flag: string;
|
|
82
|
+
mode: number;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Do nothing
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export declare function nop(): void;
|
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApiError, ErrorCode } from './ApiError.js';
|
|
2
|
-
import { dirname } from './emulation/path.js';
|
|
2
|
+
import { dirname, resolve } from './emulation/path.js';
|
|
3
3
|
/**
|
|
4
4
|
* Synchronous recursive makedir.
|
|
5
5
|
* @hidden
|
|
@@ -133,3 +133,96 @@ export function encodeDirListing(data) {
|
|
|
133
133
|
return v.toString();
|
|
134
134
|
}));
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* converts Date or number to a integer UNIX timestamp
|
|
138
|
+
* Grabbed from NodeJS sources (lib/fs.js)
|
|
139
|
+
*
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
export function _toUnixTimestamp(time) {
|
|
143
|
+
if (typeof time === 'number') {
|
|
144
|
+
return Math.floor(time);
|
|
145
|
+
}
|
|
146
|
+
if (time instanceof Date) {
|
|
147
|
+
return Math.floor(time.getTime() / 1000);
|
|
148
|
+
}
|
|
149
|
+
throw new Error('Cannot parse time: ' + time);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Normalizes a mode
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
155
|
+
export function normalizeMode(mode, def) {
|
|
156
|
+
if (typeof mode == 'number') {
|
|
157
|
+
return mode;
|
|
158
|
+
}
|
|
159
|
+
if (typeof mode == 'string') {
|
|
160
|
+
const parsed = parseInt(mode, 8);
|
|
161
|
+
if (!isNaN(parsed)) {
|
|
162
|
+
return parsed;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (typeof def == 'number') {
|
|
166
|
+
return def;
|
|
167
|
+
}
|
|
168
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid mode: ' + mode?.toString());
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Normalizes a time
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export function normalizeTime(time) {
|
|
175
|
+
if (time instanceof Date) {
|
|
176
|
+
return time;
|
|
177
|
+
}
|
|
178
|
+
if (typeof time == 'number') {
|
|
179
|
+
return new Date(time * 1000);
|
|
180
|
+
}
|
|
181
|
+
if (typeof time == 'string') {
|
|
182
|
+
return new Date(time);
|
|
183
|
+
}
|
|
184
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid time.');
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Normalizes a path
|
|
188
|
+
* @internal
|
|
189
|
+
*/
|
|
190
|
+
export function normalizePath(p) {
|
|
191
|
+
// Node doesn't allow null characters in paths.
|
|
192
|
+
if (p.includes('\x00')) {
|
|
193
|
+
throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
|
|
194
|
+
}
|
|
195
|
+
if (p.length == 0) {
|
|
196
|
+
throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
|
|
197
|
+
}
|
|
198
|
+
return resolve(p.replaceAll(/[/\\]+/g, '/'));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Normalizes options
|
|
202
|
+
* @param options options to normalize
|
|
203
|
+
* @param encoding default encoding
|
|
204
|
+
* @param flag default flag
|
|
205
|
+
* @param mode default mode
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
|
|
209
|
+
if (typeof options != 'object' || options === null) {
|
|
210
|
+
return {
|
|
211
|
+
encoding: typeof options == 'string' ? options : encoding,
|
|
212
|
+
flag,
|
|
213
|
+
mode,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
|
|
218
|
+
flag: typeof options?.flag == 'string' ? options.flag : flag,
|
|
219
|
+
mode: normalizeMode('mode' in options ? options?.mode : null, mode),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Do nothing
|
|
224
|
+
* @internal
|
|
225
|
+
*/
|
|
226
|
+
export function nop() {
|
|
227
|
+
// do nothing
|
|
228
|
+
}
|