@zenfs/core 2.3.2 → 2.3.3
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/single_buffer.js +1 -1
- package/dist/internal/inode.js +1 -1
- package/dist/vfs/dir.d.ts +48 -5
- package/dist/vfs/dir.js +177 -39
- package/dist/vfs/ioctl.js +1 -1
- package/dist/vfs/promises.js +10 -20
- package/dist/vfs/sync.js +19 -23
- package/package.json +1 -1
- package/scripts/test.js +1 -1
- package/tests/fs/dir.test.ts +6 -6
- package/tests/fs/directory.test.ts +7 -4
- package/tests/fs/links.test.ts +10 -0
|
@@ -102,7 +102,7 @@ const { format } = new Intl.NumberFormat('en-US', {
|
|
|
102
102
|
});
|
|
103
103
|
let MetadataEntry = (() => {
|
|
104
104
|
var _a, _b, _c, _d;
|
|
105
|
-
let _classDecorators = [struct(packed)];
|
|
105
|
+
let _classDecorators = [struct(packed, { name: 'MetadataEntry' })];
|
|
106
106
|
let _classDescriptor;
|
|
107
107
|
let _classExtraInitializers = [];
|
|
108
108
|
let _classThis;
|
package/dist/internal/inode.js
CHANGED
|
@@ -49,7 +49,7 @@ export const rootIno = 0;
|
|
|
49
49
|
const maxDynamicData = 3968;
|
|
50
50
|
let Attribute = (() => {
|
|
51
51
|
var _a, _b;
|
|
52
|
-
let _classDecorators = [struct(packed)];
|
|
52
|
+
let _classDecorators = [struct(packed, { name: 'Attribute' })];
|
|
53
53
|
let _classDescriptor;
|
|
54
54
|
let _classExtraInitializers = [];
|
|
55
55
|
let _classThis;
|
package/dist/vfs/dir.d.ts
CHANGED
|
@@ -2,13 +2,56 @@ import type { Dir as _Dir, Dirent as _Dirent } from 'node:fs';
|
|
|
2
2
|
import type { V_Context } from '../context.js';
|
|
3
3
|
import type { InodeLike } from '../internal/inode.js';
|
|
4
4
|
import type { Callback } from '../utils.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import { Buffer } from 'buffer';
|
|
6
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
7
|
+
/**
|
|
8
|
+
* @see `DT_*` in `dirent.h`
|
|
9
|
+
*/
|
|
10
|
+
export declare enum DirType {
|
|
11
|
+
UNKNOWN = 0,
|
|
12
|
+
FIFO = 1,
|
|
13
|
+
CHR = 2,
|
|
14
|
+
DIR = 4,
|
|
15
|
+
BLK = 6,
|
|
16
|
+
REG = 8,
|
|
17
|
+
LNK = 10,
|
|
18
|
+
SOCK = 12,
|
|
19
|
+
WHT = 14
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Converts a file mode to a directory type.
|
|
23
|
+
* @see `IFTODT` in `dirent.h`
|
|
24
|
+
*/
|
|
25
|
+
export declare function ifToDt(mode: number): DirType;
|
|
26
|
+
/**
|
|
27
|
+
* Converts a directory type to a file mode.
|
|
28
|
+
* @see `DTTOIF` in `dirent.h`
|
|
29
|
+
*/
|
|
30
|
+
export declare function dtToIf(dt: DirType): number;
|
|
31
|
+
export declare class Dirent<Name extends string | Buffer = string, TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> extends BufferView<TArrayBuffer> implements _Dirent<Name> {
|
|
32
|
+
protected accessor ino: number;
|
|
33
|
+
/** Reserved for 64-bit inodes */
|
|
34
|
+
private accessor _ino;
|
|
35
|
+
protected accessor type: DirType;
|
|
36
|
+
protected accessor _name: Uint8Array;
|
|
9
37
|
get name(): Name;
|
|
10
|
-
|
|
38
|
+
/**
|
|
39
|
+
* @internal @protected
|
|
40
|
+
*/
|
|
41
|
+
_encoding?: BufferEncoding | 'buffer' | null;
|
|
42
|
+
/**
|
|
43
|
+
* @internal @protected
|
|
44
|
+
*/
|
|
45
|
+
_parentPath: string;
|
|
11
46
|
get parentPath(): string;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Removed in Node v24, use `parentPath` instead.
|
|
49
|
+
*/
|
|
50
|
+
get path(): string;
|
|
51
|
+
/**
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
static from(path: string, stats: InodeLike, encoding?: BufferEncoding | 'buffer' | null): Dirent;
|
|
12
55
|
isFile(): boolean;
|
|
13
56
|
isDirectory(): boolean;
|
|
14
57
|
isBlockDevice(): boolean;
|
package/dist/vfs/dir.js
CHANGED
|
@@ -1,46 +1,184 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { Buffer } from 'buffer';
|
|
1
36
|
import { withErrno } from 'kerium';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
37
|
+
import { packed, sizeof, struct, types as t } from 'memium';
|
|
38
|
+
import { warn } from 'kerium/log';
|
|
39
|
+
import { encodeUTF8 } from 'utilium';
|
|
40
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
41
|
+
import { basename, dirname } from '../path.js';
|
|
4
42
|
import { readdir } from './promises.js';
|
|
5
43
|
import { readdirSync } from './sync.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
isSymbolicLink() {
|
|
35
|
-
return isSymbolicLink(this.stats);
|
|
36
|
-
}
|
|
37
|
-
isFIFO() {
|
|
38
|
-
return isFIFO(this.stats);
|
|
39
|
-
}
|
|
40
|
-
isSocket() {
|
|
41
|
-
return isSocket(this.stats);
|
|
42
|
-
}
|
|
44
|
+
/**
|
|
45
|
+
* @see `DT_*` in `dirent.h`
|
|
46
|
+
*/
|
|
47
|
+
export var DirType;
|
|
48
|
+
(function (DirType) {
|
|
49
|
+
DirType[DirType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
50
|
+
DirType[DirType["FIFO"] = 1] = "FIFO";
|
|
51
|
+
DirType[DirType["CHR"] = 2] = "CHR";
|
|
52
|
+
DirType[DirType["DIR"] = 4] = "DIR";
|
|
53
|
+
DirType[DirType["BLK"] = 6] = "BLK";
|
|
54
|
+
DirType[DirType["REG"] = 8] = "REG";
|
|
55
|
+
DirType[DirType["LNK"] = 10] = "LNK";
|
|
56
|
+
DirType[DirType["SOCK"] = 12] = "SOCK";
|
|
57
|
+
DirType[DirType["WHT"] = 14] = "WHT";
|
|
58
|
+
})(DirType || (DirType = {}));
|
|
59
|
+
/**
|
|
60
|
+
* Converts a file mode to a directory type.
|
|
61
|
+
* @see `IFTODT` in `dirent.h`
|
|
62
|
+
*/
|
|
63
|
+
export function ifToDt(mode) {
|
|
64
|
+
return ((mode & 0o170000) >> 12);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Converts a directory type to a file mode.
|
|
68
|
+
* @see `DTTOIF` in `dirent.h`
|
|
69
|
+
*/
|
|
70
|
+
export function dtToIf(dt) {
|
|
71
|
+
return dt << 12;
|
|
43
72
|
}
|
|
73
|
+
let Dirent = (() => {
|
|
74
|
+
var _a, _b, _c;
|
|
75
|
+
let _classDecorators = [struct(packed, { name: 'Dirent' })];
|
|
76
|
+
let _classDescriptor;
|
|
77
|
+
let _classExtraInitializers = [];
|
|
78
|
+
let _classThis;
|
|
79
|
+
let _classSuper = BufferView;
|
|
80
|
+
let _ino_decorators;
|
|
81
|
+
let _ino_initializers = [];
|
|
82
|
+
let _ino_extraInitializers = [];
|
|
83
|
+
let __ino_decorators;
|
|
84
|
+
let __ino_initializers = [];
|
|
85
|
+
let __ino_extraInitializers = [];
|
|
86
|
+
let _type_decorators;
|
|
87
|
+
let _type_initializers = [];
|
|
88
|
+
let _type_extraInitializers = [];
|
|
89
|
+
let __name_decorators;
|
|
90
|
+
let __name_initializers = [];
|
|
91
|
+
let __name_extraInitializers = [];
|
|
92
|
+
var Dirent = class extends _classSuper {
|
|
93
|
+
static { _classThis = this; }
|
|
94
|
+
static {
|
|
95
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
96
|
+
_ino_decorators = [(_a = t).uint32.bind(_a)];
|
|
97
|
+
__ino_decorators = [(_b = t).uint32.bind(_b)];
|
|
98
|
+
_type_decorators = [(_c = t).uint8.bind(_c)];
|
|
99
|
+
__name_decorators = [t.char(256)];
|
|
100
|
+
__esDecorate(this, null, _ino_decorators, { kind: "accessor", name: "ino", static: false, private: false, access: { has: obj => "ino" in obj, get: obj => obj.ino, set: (obj, value) => { obj.ino = value; } }, metadata: _metadata }, _ino_initializers, _ino_extraInitializers);
|
|
101
|
+
__esDecorate(this, null, __ino_decorators, { kind: "accessor", name: "_ino", static: false, private: false, access: { has: obj => "_ino" in obj, get: obj => obj._ino, set: (obj, value) => { obj._ino = value; } }, metadata: _metadata }, __ino_initializers, __ino_extraInitializers);
|
|
102
|
+
__esDecorate(this, null, _type_decorators, { kind: "accessor", name: "type", static: false, private: false, access: { has: obj => "type" in obj, get: obj => obj.type, set: (obj, value) => { obj.type = value; } }, metadata: _metadata }, _type_initializers, _type_extraInitializers);
|
|
103
|
+
__esDecorate(this, null, __name_decorators, { kind: "accessor", name: "_name", static: false, private: false, access: { has: obj => "_name" in obj, get: obj => obj._name, set: (obj, value) => { obj._name = value; } }, metadata: _metadata }, __name_initializers, __name_extraInitializers);
|
|
104
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
105
|
+
Dirent = _classThis = _classDescriptor.value;
|
|
106
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
107
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
108
|
+
}
|
|
109
|
+
#ino_accessor_storage = __runInitializers(this, _ino_initializers, void 0);
|
|
110
|
+
get ino() { return this.#ino_accessor_storage; }
|
|
111
|
+
set ino(value) { this.#ino_accessor_storage = value; }
|
|
112
|
+
#_ino_accessor_storage = (__runInitializers(this, _ino_extraInitializers), __runInitializers(this, __ino_initializers, void 0));
|
|
113
|
+
/** Reserved for 64-bit inodes */
|
|
114
|
+
get _ino() { return this.#_ino_accessor_storage; }
|
|
115
|
+
set _ino(value) { this.#_ino_accessor_storage = value; }
|
|
116
|
+
#type_accessor_storage = (__runInitializers(this, __ino_extraInitializers), __runInitializers(this, _type_initializers, void 0));
|
|
117
|
+
get type() { return this.#type_accessor_storage; }
|
|
118
|
+
set type(value) { this.#type_accessor_storage = value; }
|
|
119
|
+
#_name_accessor_storage = (__runInitializers(this, _type_extraInitializers), __runInitializers(this, __name_initializers, void 0));
|
|
120
|
+
get _name() { return this.#_name_accessor_storage; }
|
|
121
|
+
set _name(value) { this.#_name_accessor_storage = value; }
|
|
122
|
+
get name() {
|
|
123
|
+
const end = (this._name.indexOf(0) + 1 || 256) - 1;
|
|
124
|
+
const name = Buffer.from(this._name.subarray(0, end));
|
|
125
|
+
return (this._encoding == 'buffer' ? name : name.toString(this._encoding));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* @internal @protected
|
|
129
|
+
*/
|
|
130
|
+
_encoding = __runInitializers(this, __name_extraInitializers);
|
|
131
|
+
/**
|
|
132
|
+
* @internal @protected
|
|
133
|
+
*/
|
|
134
|
+
_parentPath;
|
|
135
|
+
get parentPath() {
|
|
136
|
+
return this._parentPath;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* @deprecated Removed in Node v24, use `parentPath` instead.
|
|
140
|
+
*/
|
|
141
|
+
get path() {
|
|
142
|
+
warn('Dirent.path was removed in Node v24, use parentPath instead');
|
|
143
|
+
return this._parentPath;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
static from(path, stats, encoding) {
|
|
149
|
+
const dirent = new Dirent(new ArrayBuffer(sizeof(Dirent) + 1));
|
|
150
|
+
dirent._parentPath = dirname(path);
|
|
151
|
+
dirent._name = encodeUTF8(basename(path));
|
|
152
|
+
dirent.ino = stats.ino;
|
|
153
|
+
dirent.type = ifToDt(stats.mode);
|
|
154
|
+
dirent._encoding = encoding;
|
|
155
|
+
return dirent;
|
|
156
|
+
}
|
|
157
|
+
isFile() {
|
|
158
|
+
return this.type === DirType.REG;
|
|
159
|
+
}
|
|
160
|
+
isDirectory() {
|
|
161
|
+
return this.type === DirType.DIR;
|
|
162
|
+
}
|
|
163
|
+
isBlockDevice() {
|
|
164
|
+
return this.type === DirType.BLK;
|
|
165
|
+
}
|
|
166
|
+
isCharacterDevice() {
|
|
167
|
+
return this.type === DirType.CHR;
|
|
168
|
+
}
|
|
169
|
+
isSymbolicLink() {
|
|
170
|
+
return this.type === DirType.LNK;
|
|
171
|
+
}
|
|
172
|
+
isFIFO() {
|
|
173
|
+
return this.type === DirType.FIFO;
|
|
174
|
+
}
|
|
175
|
+
isSocket() {
|
|
176
|
+
return this.type === DirType.SOCK;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
return Dirent = _classThis;
|
|
180
|
+
})();
|
|
181
|
+
export { Dirent };
|
|
44
182
|
/**
|
|
45
183
|
* A class representing a directory stream.
|
|
46
184
|
*/
|
package/dist/vfs/ioctl.js
CHANGED
|
@@ -87,7 +87,7 @@ var XFlag;
|
|
|
87
87
|
})(XFlag || (XFlag = {}));
|
|
88
88
|
let fsxattr = (() => {
|
|
89
89
|
var _a, _b, _c, _d, _e;
|
|
90
|
-
let _classDecorators = [struct()];
|
|
90
|
+
let _classDecorators = [struct({ name: 'fsxattr' })];
|
|
91
91
|
let _classDescriptor;
|
|
92
92
|
let _classExtraInitializers = [];
|
|
93
93
|
let _classThis;
|
package/dist/vfs/promises.js
CHANGED
|
@@ -52,10 +52,9 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
52
52
|
});
|
|
53
53
|
import { Buffer } from 'buffer';
|
|
54
54
|
import { Exception, rethrow, setUVMessage, UV } from 'kerium';
|
|
55
|
-
import { decodeUTF8 } from 'utilium';
|
|
56
55
|
import { defaultContext } from '../internal/contexts.js';
|
|
57
56
|
import { hasAccess, InodeFlags, isBlockDevice, isCharacterDevice, isDirectory, isSymbolicLink } from '../internal/inode.js';
|
|
58
|
-
import { dirname, join, matchesGlob, parse, resolve } from '../path.js';
|
|
57
|
+
import { basename, dirname, join, matchesGlob, parse, resolve } from '../path.js';
|
|
59
58
|
import '../polyfills.js';
|
|
60
59
|
import { createInterface } from '../readline.js';
|
|
61
60
|
import { __assertType, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
@@ -540,8 +539,9 @@ export async function stat(path, options) {
|
|
|
540
539
|
stat;
|
|
541
540
|
export async function lstat(path, options) {
|
|
542
541
|
path = normalizePath(path);
|
|
543
|
-
const { fs, path: resolved } = resolveMount(path, this);
|
|
544
542
|
const $ex = { syscall: 'lstat', path };
|
|
543
|
+
path = join(await realpath.call(this, dirname(path)), basename(path));
|
|
544
|
+
const { fs, path: resolved } = resolveMount(path, this);
|
|
545
545
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
546
546
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
547
547
|
throw UV('EACCES', $ex);
|
|
@@ -753,9 +753,9 @@ export async function mkdir(path, options) {
|
|
|
753
753
|
return dirs[0][0];
|
|
754
754
|
}
|
|
755
755
|
mkdir;
|
|
756
|
-
export async function readdir(
|
|
756
|
+
export async function readdir(_path, options) {
|
|
757
757
|
const opt = typeof options === 'object' && options != null ? options : { encoding: options, withFileTypes: false, recursive: false };
|
|
758
|
-
path = await realpath.call(this,
|
|
758
|
+
const path = await realpath.call(this, _path);
|
|
759
759
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
760
760
|
const $ex = { syscall: 'readdir', path };
|
|
761
761
|
const stats = await fs.stat(resolved).catch(rethrow({ syscall: 'stat', path }));
|
|
@@ -779,7 +779,7 @@ export async function readdir(path, options) {
|
|
|
779
779
|
return;
|
|
780
780
|
}
|
|
781
781
|
if (opt.withFileTypes) {
|
|
782
|
-
values.push(
|
|
782
|
+
values.push(Dirent.from(join(_path.toString(), entry), entryStats, opt.encoding));
|
|
783
783
|
}
|
|
784
784
|
else if (opt.encoding == 'buffer') {
|
|
785
785
|
values.push(Buffer.from(entry));
|
|
@@ -789,19 +789,9 @@ export async function readdir(path, options) {
|
|
|
789
789
|
}
|
|
790
790
|
if (!opt.recursive || !isDirectory(entryStats))
|
|
791
791
|
return;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
values.push(subEntry);
|
|
796
|
-
}
|
|
797
|
-
else if (Buffer.isBuffer(subEntry)) {
|
|
798
|
-
// Convert Buffer to string, prefix with the full path
|
|
799
|
-
values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
|
|
800
|
-
}
|
|
801
|
-
else {
|
|
802
|
-
values.push(join(entry, subEntry));
|
|
803
|
-
}
|
|
804
|
-
}
|
|
792
|
+
const children = await fs.readdir(join(resolved, entry)).catch(rethrow({ syscall: 'readdir', path: join(path, entry) }));
|
|
793
|
+
for (const child of children)
|
|
794
|
+
await addEntry(join(entry, child));
|
|
805
795
|
};
|
|
806
796
|
await Promise.all(entries.map(addEntry));
|
|
807
797
|
return values;
|
|
@@ -1238,7 +1228,7 @@ export function glob(pattern, opt) {
|
|
|
1238
1228
|
async function* recursiveList(dir) {
|
|
1239
1229
|
const entries = await readdir(dir, { withFileTypes, encoding: 'utf8' });
|
|
1240
1230
|
for (const entry of entries) {
|
|
1241
|
-
const fullPath = withFileTypes ? entry.
|
|
1231
|
+
const fullPath = withFileTypes ? join(entry.parentPath, entry.name) : dir + '/' + entry;
|
|
1242
1232
|
if (typeof exclude != 'function' ? exclude.some(p => matchesGlob(p, fullPath)) : exclude((withFileTypes ? entry : fullPath)))
|
|
1243
1233
|
continue;
|
|
1244
1234
|
/**
|
package/dist/vfs/sync.js
CHANGED
|
@@ -52,11 +52,11 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
52
52
|
});
|
|
53
53
|
import { Buffer } from 'buffer';
|
|
54
54
|
import { Errno, Exception, setUVMessage, UV } from 'kerium';
|
|
55
|
-
import {
|
|
55
|
+
import { encodeUTF8 } from 'utilium';
|
|
56
56
|
import { defaultContext } from '../internal/contexts.js';
|
|
57
57
|
import { wrap } from '../internal/error.js';
|
|
58
58
|
import { hasAccess, isDirectory, isSymbolicLink } from '../internal/inode.js';
|
|
59
|
-
import { dirname, join, matchesGlob, parse, resolve } from '../path.js';
|
|
59
|
+
import { basename, dirname, join, matchesGlob, parse, resolve } from '../path.js';
|
|
60
60
|
import { __assertType, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
61
61
|
import { checkAccess } from './config.js';
|
|
62
62
|
import * as constants from './constants.js';
|
|
@@ -139,7 +139,8 @@ export function statSync(path, options) {
|
|
|
139
139
|
statSync;
|
|
140
140
|
export function lstatSync(path, options) {
|
|
141
141
|
path = normalizePath(path);
|
|
142
|
-
const
|
|
142
|
+
const real = join(realpathSync.call(this, dirname(path)), basename(path));
|
|
143
|
+
const { fs, path: resolved } = resolveMount(real, this);
|
|
143
144
|
const stats = wrap(fs, 'statSync', path)(resolved);
|
|
144
145
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
145
146
|
throw UV('EACCES', { syscall: 'lstat', path });
|
|
@@ -485,16 +486,18 @@ export function readdirSync(path, options) {
|
|
|
485
486
|
const entries = wrap(fs, 'readdirSync', path)(resolved);
|
|
486
487
|
// Iterate over entries and handle recursive case if needed
|
|
487
488
|
const values = [];
|
|
488
|
-
|
|
489
|
+
const addEntry = (entry) => {
|
|
489
490
|
let entryStat;
|
|
490
491
|
try {
|
|
491
492
|
entryStat = fs.statSync(join(resolved, entry));
|
|
492
493
|
}
|
|
493
|
-
catch {
|
|
494
|
-
|
|
494
|
+
catch (e) {
|
|
495
|
+
if (e.code == 'ENOENT')
|
|
496
|
+
return;
|
|
497
|
+
throw setUVMessage(Object.assign(e, { syscall: 'stat', path: join(path, entry) }));
|
|
495
498
|
}
|
|
496
499
|
if (options?.withFileTypes) {
|
|
497
|
-
values.push(
|
|
500
|
+
values.push(Dirent.from(entry, entryStat, options.encoding));
|
|
498
501
|
}
|
|
499
502
|
else if (options?.encoding == 'buffer') {
|
|
500
503
|
values.push(Buffer.from(entry));
|
|
@@ -503,20 +506,13 @@ export function readdirSync(path, options) {
|
|
|
503
506
|
values.push(entry);
|
|
504
507
|
}
|
|
505
508
|
if (!isDirectory(entryStat) || !options?.recursive)
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
values.push(Buffer.from(join(entry, decodeUTF8(subEntry))));
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
values.push(join(entry, subEntry));
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
509
|
+
return;
|
|
510
|
+
const children = wrap(fs, 'readdirSync', join(path, entry))(join(resolved, entry));
|
|
511
|
+
for (const child of children)
|
|
512
|
+
addEntry(join(entry, child));
|
|
513
|
+
};
|
|
514
|
+
for (const entry of entries)
|
|
515
|
+
addEntry(entry);
|
|
520
516
|
return values;
|
|
521
517
|
}
|
|
522
518
|
readdirSync;
|
|
@@ -862,7 +858,7 @@ export function globSync(pattern, options = {}) {
|
|
|
862
858
|
function recursiveList(dir) {
|
|
863
859
|
const entries = readdirSync(dir, { withFileTypes, encoding: 'utf8' });
|
|
864
860
|
for (const entry of entries) {
|
|
865
|
-
const fullPath = withFileTypes ? entry.
|
|
861
|
+
const fullPath = withFileTypes ? join(entry.parentPath, entry.name) : dir + '/' + entry;
|
|
866
862
|
if (typeof exclude != 'function' ? exclude.some(p => matchesGlob(p, fullPath)) : exclude((withFileTypes ? entry : fullPath)))
|
|
867
863
|
continue;
|
|
868
864
|
/**
|
|
@@ -872,7 +868,7 @@ export function globSync(pattern, options = {}) {
|
|
|
872
868
|
recursiveList(fullPath);
|
|
873
869
|
}
|
|
874
870
|
if (regexPatterns.some(pattern => pattern.test(fullPath.replace(/^\/+/g, '')))) {
|
|
875
|
-
results.push(withFileTypes ? entry
|
|
871
|
+
results.push(withFileTypes ? entry : fullPath.replace(/^\/+/g, ''));
|
|
876
872
|
}
|
|
877
873
|
}
|
|
878
874
|
}
|
package/package.json
CHANGED
package/scripts/test.js
CHANGED
|
@@ -212,7 +212,7 @@ for (const setupFile of positionals) {
|
|
|
212
212
|
execSync(
|
|
213
213
|
[
|
|
214
214
|
'tsx --trace-deprecation',
|
|
215
|
-
options.inspect ? 'inspect' : '',
|
|
215
|
+
options.inspect ? '--inspect' : '',
|
|
216
216
|
'--test --experimental-test-coverage',
|
|
217
217
|
options.force ? '--test-force-exit' : '',
|
|
218
218
|
options.skip ? `--test-skip-pattern=${options.skip}` : '',
|
package/tests/fs/dir.test.ts
CHANGED
|
@@ -16,15 +16,15 @@ for (const file of testFiles) {
|
|
|
16
16
|
suite('Dirent', () => {
|
|
17
17
|
test('name and parentPath getters', async () => {
|
|
18
18
|
const stats = await fs.promises.lstat(testFile);
|
|
19
|
-
const dirent =
|
|
19
|
+
const dirent = fs.Dirent.from(testFile, stats);
|
|
20
20
|
|
|
21
21
|
assert.equal(dirent.name, testFile);
|
|
22
|
-
assert.equal(dirent.parentPath,
|
|
22
|
+
assert.equal(dirent.parentPath, '.');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
test('isFile', async () => {
|
|
26
26
|
const fileStats = await fs.promises.lstat(testFile);
|
|
27
|
-
const fileDirent =
|
|
27
|
+
const fileDirent = fs.Dirent.from(testFile, fileStats);
|
|
28
28
|
|
|
29
29
|
assert(fileDirent.isFile());
|
|
30
30
|
assert(!fileDirent.isDirectory());
|
|
@@ -32,7 +32,7 @@ suite('Dirent', () => {
|
|
|
32
32
|
|
|
33
33
|
test('isDirectory', async () => {
|
|
34
34
|
const dirStats = await fs.promises.lstat('test-directory');
|
|
35
|
-
const dirDirent =
|
|
35
|
+
const dirDirent = fs.Dirent.from('test-directory', dirStats);
|
|
36
36
|
|
|
37
37
|
assert(!dirDirent.isFile());
|
|
38
38
|
assert(dirDirent.isDirectory());
|
|
@@ -40,14 +40,14 @@ suite('Dirent', () => {
|
|
|
40
40
|
|
|
41
41
|
test('isSymbolicLink', async () => {
|
|
42
42
|
const symlinkStats = await fs.promises.lstat('test-symlink');
|
|
43
|
-
const symlinkDirent =
|
|
43
|
+
const symlinkDirent = fs.Dirent.from('test-symlink', symlinkStats);
|
|
44
44
|
|
|
45
45
|
assert(symlinkDirent.isSymbolicLink());
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
test('other methods return false', async () => {
|
|
49
49
|
const fileStats = await fs.promises.lstat(testFile);
|
|
50
|
-
const fileDirent =
|
|
50
|
+
const fileDirent = fs.Dirent.from(testFile, fileStats);
|
|
51
51
|
|
|
52
52
|
assert(!fileDirent.isBlockDevice());
|
|
53
53
|
assert(!fileDirent.isCharacterDevice());
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
|
+
import { join } from 'node:path/posix';
|
|
2
3
|
import { suite, test } from 'node:test';
|
|
3
4
|
import { fs } from '../common.js';
|
|
4
5
|
|
|
@@ -143,10 +144,12 @@ suite('Directories', () => {
|
|
|
143
144
|
|
|
144
145
|
test('readdir returns Dirent recursively', async () => {
|
|
145
146
|
const entries = await fs.promises.readdir(testDir, { recursive: true, withFileTypes: true });
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
assert.
|
|
147
|
+
entries.sort((a, b) => join(a.parentPath, a.name).localeCompare(join(b.parentPath, b.name)));
|
|
148
|
+
const values = entries.map(entry => [entry.parentPath, entry.name]);
|
|
149
|
+
|
|
150
|
+
assert.deepEqual(values[0], [testDir, 'file1.txt']);
|
|
151
|
+
assert.deepEqual(values[4], [join(testDir, 'subdir1'), 'file4.txt']);
|
|
152
|
+
assert.deepEqual(values[8], [join(testDir, 'subdir2'), 'file5.txt']);
|
|
150
153
|
});
|
|
151
154
|
|
|
152
155
|
test('readdirSync returns files recursively', () => {
|
package/tests/fs/links.test.ts
CHANGED
|
@@ -18,6 +18,16 @@ suite('Links', () => {
|
|
|
18
18
|
assert(stats.isSymbolicLink());
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
test('lstat file inside symlinked directory', async () => {
|
|
22
|
+
// @zenfs/core#241
|
|
23
|
+
await fs.promises.mkdir('/a');
|
|
24
|
+
await fs.promises.writeFile('/a/hello.txt', 'hello world');
|
|
25
|
+
await fs.promises.symlink('/a', '/b');
|
|
26
|
+
|
|
27
|
+
const stat = await fs.promises.lstat('/b/hello.txt');
|
|
28
|
+
assert(stat.isFile());
|
|
29
|
+
});
|
|
30
|
+
|
|
21
31
|
test('readlink', async () => {
|
|
22
32
|
const destination = await fs.promises.readlink(symlink);
|
|
23
33
|
assert.equal(destination, target);
|