@zenfs/core 2.4.1 → 2.4.2
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/COPYING.md +18 -0
- package/{readme.md → README.md} +16 -74
- package/dist/backends/fetch.js +1 -1
- package/dist/backends/memory.js +1 -1
- package/dist/backends/passthrough.d.ts +1 -2
- package/dist/backends/single_buffer.js +1 -1
- package/dist/backends/store/fs.js +4 -4
- package/dist/config.js +15 -15
- package/dist/context.js +3 -2
- package/dist/index.d.ts +9 -3
- package/dist/index.js +9 -4
- package/dist/internal/contexts.d.ts +5 -4
- package/dist/internal/devices.js +1 -1
- package/dist/internal/error.d.ts +11 -2
- package/dist/internal/error.js +38 -2
- package/dist/internal/file_index.js +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.js +2 -1
- package/dist/internal/index_fs.js +1 -1
- package/dist/internal/inode.d.ts +51 -2
- package/dist/internal/inode.js +18 -2
- package/dist/mixins/shared.js +1 -1
- package/dist/node/async.d.ts +278 -0
- package/dist/node/async.js +518 -0
- package/dist/node/compat.d.ts +4 -0
- package/dist/node/compat.js +6 -0
- package/dist/node/dir.d.ts +78 -0
- package/dist/node/dir.js +150 -0
- package/dist/node/index.d.ts +8 -0
- package/dist/node/index.js +8 -0
- package/dist/{vfs → node}/promises.d.ts +10 -66
- package/dist/{vfs → node}/promises.js +141 -478
- package/dist/{vfs → node}/stats.d.ts +0 -4
- package/dist/{vfs → node}/stats.js +1 -16
- package/dist/{vfs → node}/streams.js +2 -2
- package/dist/node/sync.d.ts +252 -0
- package/dist/node/sync.js +682 -0
- package/dist/node/types.d.ts +21 -0
- package/dist/utils.d.ts +1 -7
- package/dist/utils.js +0 -6
- package/dist/vfs/acl.js +1 -1
- package/dist/vfs/async.d.ts +22 -278
- package/dist/vfs/async.js +212 -501
- package/dist/vfs/dir.d.ts +5 -82
- package/dist/vfs/dir.js +5 -233
- package/dist/vfs/file.d.ts +52 -13
- package/dist/vfs/file.js +167 -25
- package/dist/vfs/flags.js +1 -1
- package/dist/vfs/index.d.ts +2 -5
- package/dist/vfs/index.js +2 -5
- package/dist/vfs/shared.d.ts +25 -1
- package/dist/vfs/shared.js +6 -4
- package/dist/vfs/sync.d.ts +17 -245
- package/dist/vfs/sync.js +129 -773
- package/dist/vfs/watchers.d.ts +1 -1
- package/dist/vfs/watchers.js +2 -2
- package/dist/vfs/xattr.js +1 -1
- package/eslint.shared.js +1 -0
- package/package.json +7 -5
- package/scripts/make-index.js +5 -29
- package/scripts/test.js +59 -51
- package/tests/backend/fetch.test.ts +2 -2
- package/tests/backend/port.test.ts +2 -3
- package/tests/backend/single-buffer.test.ts +1 -1
- package/tests/common/casefold.test.ts +1 -1
- package/tests/common/context.test.ts +11 -4
- package/tests/common/devices.test.ts +3 -3
- package/tests/common/handle.test.ts +4 -3
- package/tests/common/inode.test.ts +2 -2
- package/tests/common/mounts.test.ts +1 -3
- package/tests/common/mutex.test.ts +1 -3
- package/tests/common/path.test.ts +2 -2
- package/tests/common/readline.test.ts +1 -1
- package/tests/common.ts +5 -4
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/dir.test.ts +3 -43
- package/tests/fs/directory.test.ts +4 -4
- package/tests/fs/errors.test.ts +2 -2
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/permissions.test.ts +3 -3
- package/tests/fs/read.test.ts +1 -1
- package/tests/fs/scaling.test.ts +1 -1
- package/tests/fs/stat.test.ts +1 -2
- package/tests/fs/times.test.ts +1 -1
- package/tests/fs/watch.test.ts +3 -2
- package/tests/setup/context.ts +1 -2
- package/tests/setup/cow.ts +1 -1
- package/tests/setup/index.ts +2 -2
- package/tests/setup/port.ts +1 -1
- package/tests/setup/single-buffer.ts +1 -1
- package/tests/setup.ts +4 -3
- package/dist/vfs/types.d.ts +0 -24
- package/tests/assignment.ts +0 -21
- /package/dist/{vfs/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/{vfs/constants.js → constants.js} +0 -0
- /package/dist/{readline.d.ts → node/readline.d.ts} +0 -0
- /package/dist/{readline.js → node/readline.js} +0 -0
- /package/dist/{vfs → node}/streams.d.ts +0 -0
- /package/dist/{vfs → node}/types.js +0 -0
package/dist/vfs/watchers.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { EventEmitter as NodeEventEmitter } from 'node:events';
|
|
|
2
2
|
import type * as fs from 'node:fs';
|
|
3
3
|
import type { V_Context } from '../context.js';
|
|
4
4
|
import { EventEmitter } from 'eventemitter3';
|
|
5
|
-
import { type Stats } from '
|
|
5
|
+
import { type Stats } from '../node/stats.js';
|
|
6
6
|
/**
|
|
7
7
|
* Base class for file system watchers.
|
|
8
8
|
* Provides event handling capabilities for watching file system changes.
|
package/dist/vfs/watchers.js
CHANGED
|
@@ -2,8 +2,8 @@ import { EventEmitter } from 'eventemitter3';
|
|
|
2
2
|
import { UV } from 'kerium';
|
|
3
3
|
import { basename, dirname, join, relative } from '../path.js';
|
|
4
4
|
import { normalizePath } from '../utils.js';
|
|
5
|
-
import { isStatsEqual } from '
|
|
6
|
-
import { statSync } from '
|
|
5
|
+
import { isStatsEqual } from '../node/stats.js';
|
|
6
|
+
import { statSync } from '../node/sync.js';
|
|
7
7
|
/**
|
|
8
8
|
* Base class for file system watchers.
|
|
9
9
|
* Provides event handling capabilities for watching file system changes.
|
package/dist/vfs/xattr.js
CHANGED
|
@@ -4,7 +4,7 @@ import { rethrow, setUVMessage, UV } from 'kerium';
|
|
|
4
4
|
import { Attributes, hasAccess } from '../internal/inode.js';
|
|
5
5
|
import { normalizePath } from '../utils.js';
|
|
6
6
|
import { checkAccess } from './config.js';
|
|
7
|
-
import { R_OK, W_OK } from '
|
|
7
|
+
import { R_OK, W_OK } from '../constants.js';
|
|
8
8
|
import { resolveMount } from './shared.js';
|
|
9
9
|
const _allowedRestrictedNames = [];
|
|
10
10
|
/**
|
package/eslint.shared.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -45,8 +45,10 @@
|
|
|
45
45
|
"exports": {
|
|
46
46
|
".": "./dist/index.js",
|
|
47
47
|
"./*": "./dist/*",
|
|
48
|
-
"./emulation/*": "./dist/
|
|
49
|
-
"./promises": "./dist/
|
|
48
|
+
"./emulation/*": "./dist/node/*",
|
|
49
|
+
"./promises": "./dist/node/promises.js",
|
|
50
|
+
"./readline": "./dist/node/readline.js",
|
|
51
|
+
"./constants": "./dist/constants.js",
|
|
50
52
|
"./path": "./dist/path.js",
|
|
51
53
|
"./eslint": "./eslint.shared.js",
|
|
52
54
|
"./tests/*": "./tests/*",
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
"test": "npx zenfs-test --clean; npx zenfs-test -abcp; tests/fetch/run.sh; npx zenfs-test --report",
|
|
66
68
|
"build": "tsc -p tsconfig.json",
|
|
67
69
|
"build:docs": "typedoc",
|
|
68
|
-
"dev": "
|
|
70
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
69
71
|
"prepublishOnly": "npm run build"
|
|
70
72
|
},
|
|
71
73
|
"dependencies": {
|
|
@@ -73,7 +75,7 @@
|
|
|
73
75
|
"buffer": "^6.0.3",
|
|
74
76
|
"eventemitter3": "^5.0.1",
|
|
75
77
|
"kerium": "^1.3.4",
|
|
76
|
-
"memium": "^0.3.
|
|
78
|
+
"memium": "^0.3.10",
|
|
77
79
|
"readable-stream": "^4.5.2",
|
|
78
80
|
"utilium": "^2.5.0"
|
|
79
81
|
},
|
package/scripts/make-index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readdirSync, statSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { matchesGlob, relative, join, resolve } from 'node:path/posix';
|
|
4
|
-
import { parseArgs } from 'node:util';
|
|
4
|
+
import { parseArgs, styleText } from 'node:util';
|
|
5
5
|
|
|
6
6
|
const { values: options, positionals } = parseArgs({
|
|
7
7
|
options: {
|
|
@@ -42,36 +42,12 @@ function fixSlash(path) {
|
|
|
42
42
|
|
|
43
43
|
const resolvedRoot = root || '.';
|
|
44
44
|
|
|
45
|
-
const colors = {
|
|
46
|
-
reset: 0,
|
|
47
|
-
black: 30,
|
|
48
|
-
red: 31,
|
|
49
|
-
green: 32,
|
|
50
|
-
yellow: 33,
|
|
51
|
-
blue: 34,
|
|
52
|
-
magenta: 35,
|
|
53
|
-
cyan: 36,
|
|
54
|
-
white: 37,
|
|
55
|
-
bright_black: 90,
|
|
56
|
-
bright_red: 91,
|
|
57
|
-
bright_green: 92,
|
|
58
|
-
bright_yellow: 93,
|
|
59
|
-
bright_blue: 94,
|
|
60
|
-
bright_magenta: 95,
|
|
61
|
-
bright_cyan: 96,
|
|
62
|
-
bright_white: 97,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
function color(color, text) {
|
|
66
|
-
return `\x1b[${colors[color]}m${text}\x1b[0m`;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
45
|
const entries = new Map();
|
|
70
46
|
|
|
71
47
|
function computeEntries(path) {
|
|
72
48
|
try {
|
|
73
49
|
if (options.ignore.some(pattern => matchesGlob(path, pattern))) {
|
|
74
|
-
if (!options.quiet) console.log(`${
|
|
50
|
+
if (!options.quiet) console.log(`${styleText('yellow', 'skip')} ${path}`);
|
|
75
51
|
return;
|
|
76
52
|
}
|
|
77
53
|
|
|
@@ -80,7 +56,7 @@ function computeEntries(path) {
|
|
|
80
56
|
if (stats.isFile()) {
|
|
81
57
|
entries.set('/' + relative(resolvedRoot, path), stats);
|
|
82
58
|
if (options.verbose) {
|
|
83
|
-
console.log(`${
|
|
59
|
+
console.log(`${styleText('green', 'file')} ${path}`);
|
|
84
60
|
}
|
|
85
61
|
return;
|
|
86
62
|
}
|
|
@@ -90,11 +66,11 @@ function computeEntries(path) {
|
|
|
90
66
|
}
|
|
91
67
|
entries.set('/' + relative(resolvedRoot, path), stats);
|
|
92
68
|
if (options.verbose) {
|
|
93
|
-
console.log(`${
|
|
69
|
+
console.log(`${styleText('greenBright', ' dir')} ${path}`);
|
|
94
70
|
}
|
|
95
71
|
} catch (e) {
|
|
96
72
|
if (!options.quiet) {
|
|
97
|
-
console.log(`${
|
|
73
|
+
console.log(`${styleText('red', 'fail')} ${path}: ${e.message}`);
|
|
98
74
|
}
|
|
99
75
|
}
|
|
100
76
|
}
|
package/scripts/test.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
2
|
import { execSync } from 'node:child_process';
|
|
4
3
|
import { existsSync, globSync, mkdirSync, rmSync } from 'node:fs';
|
|
5
4
|
import { join, parse, basename } from 'node:path';
|
|
6
|
-
import { parseArgs } from 'node:util';
|
|
5
|
+
import { parseArgs, styleText } from 'node:util';
|
|
7
6
|
|
|
8
7
|
const { values: options, positionals } = parseArgs({
|
|
9
8
|
options: {
|
|
@@ -14,6 +13,7 @@ const { values: options, positionals } = parseArgs({
|
|
|
14
13
|
log: { short: 'l', type: 'string', default: '' },
|
|
15
14
|
'file-names': { short: 'N', type: 'boolean', default: false },
|
|
16
15
|
ci: { short: 'C', type: 'boolean', default: false },
|
|
16
|
+
debug: { short: 'd', type: 'boolean', default: false },
|
|
17
17
|
|
|
18
18
|
// Test behavior
|
|
19
19
|
test: { short: 't', type: 'string' },
|
|
@@ -25,15 +25,20 @@ const { values: options, positionals } = parseArgs({
|
|
|
25
25
|
skip: { short: 's', type: 'string', multiple: true, default: [] },
|
|
26
26
|
'exit-on-fail': { short: 'e', type: 'boolean' },
|
|
27
27
|
|
|
28
|
-
// Coverage
|
|
28
|
+
// Coverage and performance
|
|
29
29
|
coverage: { type: 'string', default: 'tests/.coverage' },
|
|
30
30
|
preserve: { short: 'p', type: 'boolean' },
|
|
31
31
|
report: { type: 'boolean', default: false },
|
|
32
32
|
clean: { type: 'boolean', default: false },
|
|
33
|
+
profile: { type: 'boolean', default: false },
|
|
33
34
|
},
|
|
34
35
|
allowPositionals: true,
|
|
35
36
|
});
|
|
36
37
|
|
|
38
|
+
function debug(...args) {
|
|
39
|
+
if (options.debug) console.debug(styleText('dim', '[debug]'), ...args.map(a => (typeof a === 'string' ? styleText('dim', a) : a)));
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
if (options.help) {
|
|
38
43
|
console.log(`zenfs-test [...options] <...paths>
|
|
39
44
|
|
|
@@ -47,22 +52,24 @@ Behavior:
|
|
|
47
52
|
-t, --test <glob> Which FS test suite(s) to run
|
|
48
53
|
-f, --force Whether to use --test-force-exit
|
|
49
54
|
-I, --inspect Use the inspector for debugging
|
|
50
|
-
|
|
55
|
+
-s, --skip <pattern> Skip tests with names matching the given pattern. Can be specified multiple times.
|
|
56
|
+
-d, --debug Output debug messages from the test runner
|
|
51
57
|
|
|
52
58
|
Output:
|
|
53
|
-
-h, --help
|
|
54
|
-
-v, --verbose
|
|
55
|
-
-q, --quiet
|
|
56
|
-
-l, --logs <level>
|
|
57
|
-
-N, --file-names
|
|
58
|
-
-C, --ci
|
|
59
|
-
|
|
59
|
+
-h, --help Outputs this help message
|
|
60
|
+
-v, --verbose Output verbose messages
|
|
61
|
+
-q, --quiet Don't output normal messages
|
|
62
|
+
-l, --logs <level> Change the default log level for test output. Level can be a number or string
|
|
63
|
+
-N, --file-names Use full file paths for tests from setup files instead of the base name
|
|
64
|
+
-C, --ci Continuous integration (CI) mode. This interacts with the Github
|
|
65
|
+
Checks API for better test status. Requires @octokit/action
|
|
60
66
|
|
|
61
67
|
Coverage:
|
|
62
|
-
--coverage <dir>
|
|
63
|
-
-p, --preserve
|
|
64
|
-
--report
|
|
65
|
-
--clean
|
|
68
|
+
--coverage <dir> Override the default coverage data directory
|
|
69
|
+
-p, --preserve Do not delete or report coverage data
|
|
70
|
+
--report ONLY report coverage
|
|
71
|
+
--clean ONLY clean up coverage directory
|
|
72
|
+
--profile Record performance profiles`);
|
|
66
73
|
process.exit();
|
|
67
74
|
}
|
|
68
75
|
|
|
@@ -73,6 +80,7 @@ if (options.quiet && options.verbose) {
|
|
|
73
80
|
|
|
74
81
|
process.env.NODE_V8_COVERAGE = options.coverage;
|
|
75
82
|
process.env.ZENFS_LOG_LEVEL = options.log;
|
|
83
|
+
if (options.verbose) process.env.VERBOSE = '1';
|
|
76
84
|
|
|
77
85
|
if (options.clean) {
|
|
78
86
|
rmSync(options.coverage, { recursive: true, force: true });
|
|
@@ -117,16 +125,6 @@ if (options.auto) {
|
|
|
117
125
|
!options.quiet && console.log(`Auto-detected ${sum} test setup files`);
|
|
118
126
|
}
|
|
119
127
|
|
|
120
|
-
/**
|
|
121
|
-
* Colorizes some text
|
|
122
|
-
* @param {string} text Text to color
|
|
123
|
-
* @param {string | number} code ANSI escape code
|
|
124
|
-
* @returns
|
|
125
|
-
*/
|
|
126
|
-
function color(text, code) {
|
|
127
|
-
return `\x1b[${code}m${text}\x1b[0m`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
128
|
async function status(name) {
|
|
131
129
|
const start = performance.now();
|
|
132
130
|
|
|
@@ -141,22 +139,22 @@ async function status(name) {
|
|
|
141
139
|
unit = 's';
|
|
142
140
|
}
|
|
143
141
|
|
|
144
|
-
return
|
|
142
|
+
return styleText('dim', `(${delta} ${unit})`);
|
|
145
143
|
};
|
|
146
144
|
|
|
147
145
|
const maybeName = options.verbose ? `: ${name}` : '';
|
|
148
146
|
|
|
149
147
|
return {
|
|
150
148
|
async pass() {
|
|
151
|
-
if (!options.quiet) console.log(`${
|
|
149
|
+
if (!options.quiet) console.log(`${styleText('green', 'passed')}${maybeName} ${time()}`);
|
|
152
150
|
if (options.ci) await ci.completeCheck(name, 'success');
|
|
153
151
|
},
|
|
154
152
|
async skip() {
|
|
155
|
-
if (!options.quiet) console.log(`${
|
|
153
|
+
if (!options.quiet) console.log(`${styleText('yellow', 'skipped')}${maybeName} ${time()}`);
|
|
156
154
|
if (options.ci) await ci.completeCheck(name, 'skipped');
|
|
157
155
|
},
|
|
158
156
|
async fail() {
|
|
159
|
-
console.error(`${
|
|
157
|
+
console.error(`${styleText(['red', 'bold'], 'failed')}${maybeName} ${time()}`);
|
|
160
158
|
if (options.ci) await ci.completeCheck(name, 'failure');
|
|
161
159
|
process.exitCode = 1;
|
|
162
160
|
if (options['exit-on-fail']) process.exit();
|
|
@@ -167,16 +165,36 @@ async function status(name) {
|
|
|
167
165
|
if (!options.preserve) rmSync(options.coverage, { force: true, recursive: true });
|
|
168
166
|
mkdirSync(options.coverage, { recursive: true });
|
|
169
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Generate the command used to run the tests
|
|
170
|
+
*/
|
|
171
|
+
function makeCommand(profileName, ...rest) {
|
|
172
|
+
const command = [
|
|
173
|
+
'tsx --trace-deprecation',
|
|
174
|
+
options.inspect ? '--inspect' : '',
|
|
175
|
+
'--test --experimental-test-coverage',
|
|
176
|
+
options.force ? '--test-force-exit' : '',
|
|
177
|
+
options.skip.length ? `--test-skip-pattern='${options.skip.join('|').replaceAll("'", "\\'")}'` : '',
|
|
178
|
+
!options.profile ? '' : `--cpu-prof --cpu-prof-dir=.profiles --cpu-prof-name=${profileName}.cpuprofile --cpu-prof-interval=500`,
|
|
179
|
+
...rest,
|
|
180
|
+
]
|
|
181
|
+
.filter(v => v)
|
|
182
|
+
.join(' ');
|
|
183
|
+
|
|
184
|
+
if (!options.quiet) debug('command:', command);
|
|
185
|
+
|
|
186
|
+
return command;
|
|
187
|
+
}
|
|
188
|
+
|
|
170
189
|
if (options.common) {
|
|
171
|
-
|
|
190
|
+
const command = makeCommand('common', `'tests/*.test.ts' 'tests/**/!(fs)/*.test.ts'`);
|
|
191
|
+
|
|
192
|
+
if (!options.quiet) process.stdout.write('Running common tests...' + (options.verbose ? '\n' : ' '));
|
|
172
193
|
const { pass, fail } = await status('Common tests');
|
|
173
194
|
try {
|
|
174
|
-
execSync(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
|
|
178
|
-
}
|
|
179
|
-
);
|
|
195
|
+
execSync(command, {
|
|
196
|
+
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
|
|
197
|
+
});
|
|
180
198
|
await pass();
|
|
181
199
|
} catch {
|
|
182
200
|
await fail();
|
|
@@ -192,10 +210,11 @@ for (const setupFile of positionals) {
|
|
|
192
210
|
}
|
|
193
211
|
|
|
194
212
|
process.env.SETUP = setupFile;
|
|
195
|
-
process.env.VERBOSE = +options.verbose;
|
|
196
213
|
|
|
197
214
|
const name = options['file-names'] && !options.ci ? setupFile : parse(setupFile).name;
|
|
198
215
|
|
|
216
|
+
const command = makeCommand(name, `'${testsGlob.replaceAll("'", "\\'")}'`, process.env.CMD);
|
|
217
|
+
|
|
199
218
|
if (!options.quiet) {
|
|
200
219
|
if (options.verbose) console.log('Running tests:', name);
|
|
201
220
|
else process.stdout.write(`Running tests: ${name}... `);
|
|
@@ -209,20 +228,9 @@ for (const setupFile of positionals) {
|
|
|
209
228
|
}
|
|
210
229
|
|
|
211
230
|
try {
|
|
212
|
-
execSync(
|
|
213
|
-
[
|
|
214
|
-
|
|
215
|
-
options.inspect ? '--inspect' : '',
|
|
216
|
-
'--test --experimental-test-coverage',
|
|
217
|
-
options.force ? '--test-force-exit' : '',
|
|
218
|
-
options.skip.length ? `--test-skip-pattern='${options.skip.join('|').replaceAll("'", "\\'")}'` : '',
|
|
219
|
-
`'${testsGlob.replaceAll("'", "\\'")}'`,
|
|
220
|
-
process.env.CMD,
|
|
221
|
-
].join(' '),
|
|
222
|
-
{
|
|
223
|
-
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
|
|
224
|
-
}
|
|
225
|
-
);
|
|
231
|
+
execSync(command, {
|
|
232
|
+
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
|
|
233
|
+
});
|
|
226
234
|
await pass();
|
|
227
235
|
} catch {
|
|
228
236
|
await fail();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { Fetch, configureSingle, fs, mounts, type FetchFS } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { join } from 'node:path';
|
|
4
5
|
import { after, suite, test } from 'node:test';
|
|
5
6
|
import { Worker } from 'node:worker_threads';
|
|
6
|
-
import { Fetch, configureSingle, fs, mounts, type FetchFS } from '../../dist/index.js';
|
|
7
7
|
import { baseUrl, defaultEntries, indexPath, whenServerReady } from '../fetch/config.js';
|
|
8
8
|
import { setupLogs } from '../logs.js';
|
|
9
9
|
|
|
@@ -42,7 +42,7 @@ suite('Fetch with `disableAsyncCache`', () => {
|
|
|
42
42
|
assert.deepEqual(entries, [...defaultEntries, 'example', 'duck']);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
test('Uncached synchronous operations throw',
|
|
45
|
+
test('Uncached synchronous operations throw', () => {
|
|
46
46
|
assert.throws(() => fs.readFileSync('/x.txt', 'utf8'), { code: 'EAGAIN' });
|
|
47
47
|
});
|
|
48
48
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import type { InMemoryStore, StoreFS } from '@zenfs/core';
|
|
3
|
+
import { InMemory, Port, attachFS, configure, configureSingle, fs, resolveMountConfig, waitOnline } from '@zenfs/core';
|
|
2
4
|
import assert from 'node:assert/strict';
|
|
3
5
|
import { after, suite, test } from 'node:test';
|
|
4
6
|
import { MessageChannel, Worker } from 'node:worker_threads';
|
|
5
|
-
import { Port, attachFS } from '../../dist/backends/port.js';
|
|
6
|
-
import type { InMemoryStore, StoreFS } from '../../dist/index.js';
|
|
7
|
-
import { InMemory, configure, configureSingle, fs, resolveMountConfig, waitOnline } from '../../dist/index.js';
|
|
8
7
|
import { setupLogs } from '../logs.js';
|
|
9
8
|
setupLogs();
|
|
10
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import assert from 'node:assert';
|
|
3
3
|
import { suite, test } from 'node:test';
|
|
4
4
|
import { Worker } from 'worker_threads';
|
|
5
|
-
import { fs, mount, resolveMountConfig, SingleBuffer } from '
|
|
5
|
+
import { fs, mount, resolveMountConfig, SingleBuffer } from '@zenfs/core';
|
|
6
6
|
import { setupLogs } from '../logs.js';
|
|
7
7
|
|
|
8
8
|
setupLogs();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { configure, fs, mounts } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { suite, test } from 'node:test';
|
|
4
|
-
import { mounts, configure, fs } from '../../dist/index.js';
|
|
5
5
|
|
|
6
6
|
suite('Case folding', () => {
|
|
7
7
|
test('Configuration', async () => {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { bindContext, configure, fs, InMemory } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { suite, test } from 'node:test';
|
|
4
5
|
import { canary } from 'utilium';
|
|
5
|
-
import { bindContext } from '../../dist/context.js';
|
|
6
|
-
import * as fs from '../../dist/vfs/index.js';
|
|
7
|
-
import { configure, InMemory } from '../../dist/index.js';
|
|
8
6
|
|
|
9
7
|
fs.mkdirSync('/ctx');
|
|
10
|
-
const
|
|
8
|
+
const context = bindContext({ root: '/ctx' });
|
|
9
|
+
const ctx = context.fs;
|
|
11
10
|
|
|
12
11
|
suite('Context', () => {
|
|
13
12
|
test('create a file', () => {
|
|
@@ -73,4 +72,12 @@ suite('Context', () => {
|
|
|
73
72
|
|
|
74
73
|
assert.deepEqual(bananas.fs.readdirSync('/'), ['yellow']);
|
|
75
74
|
});
|
|
75
|
+
|
|
76
|
+
test('Different working directory', { todo: true }, () => {
|
|
77
|
+
// @zenfs/core#263
|
|
78
|
+
ctx.mkdirSync('/test');
|
|
79
|
+
context.pwd = '/test';
|
|
80
|
+
|
|
81
|
+
assert.equal(ctx.realpathSync('.'), '/test');
|
|
82
|
+
});
|
|
76
83
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
2
|
import { suite, test } from 'node:test';
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
|
-
import { configure } from '
|
|
5
|
-
import
|
|
6
|
-
import { S_IFCHR, S_IFMT } from '
|
|
4
|
+
import { configure } from '@zenfs/core';
|
|
5
|
+
import { fs } from '@zenfs/core';
|
|
6
|
+
import { S_IFCHR, S_IFMT } from '@zenfs/core/constants';
|
|
7
7
|
|
|
8
8
|
await configure({
|
|
9
9
|
addDevices: true,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { constants, promises } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
4
|
+
import type { FileHandle } from 'node:fs/promises';
|
|
3
5
|
import { after, suite, test } from 'node:test';
|
|
4
6
|
import { wait } from 'utilium';
|
|
5
|
-
import { constants, type FileHandle, open } from '../../dist/vfs/promises.js';
|
|
6
7
|
|
|
7
8
|
const content = 'The cake is a lie',
|
|
8
9
|
appended = '\nAnother lie';
|
|
9
10
|
|
|
10
|
-
const handle: FileHandle = await open('./test.txt', 'ws+');
|
|
11
|
+
const handle: FileHandle = await promises.open('./test.txt', 'ws+');
|
|
11
12
|
|
|
12
13
|
suite('FileHandle', () => {
|
|
13
14
|
test('writeFile', async () => {
|
|
@@ -54,7 +55,7 @@ suite('FileHandle', () => {
|
|
|
54
55
|
test('readLines', async () => {
|
|
55
56
|
await handle.writeFile('first line\nsecond line\nthird line');
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
using rl = handle.readLines();
|
|
58
59
|
|
|
59
60
|
const lines: string[] = [];
|
|
60
61
|
rl.on('line', (line: string) => lines.push(line));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
-
import {
|
|
3
|
-
import { Inode } from '../../dist/internal/inode.js';
|
|
2
|
+
import { Inode } from '@zenfs/core';
|
|
4
3
|
import assert from 'node:assert';
|
|
4
|
+
import { suite, test } from 'node:test';
|
|
5
5
|
|
|
6
6
|
suite('Inode manipulation', () => {
|
|
7
7
|
const inode = new Inode();
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { configure, fs, InMemory, mounts } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { suite, test } from 'node:test';
|
|
4
|
-
import { configure } from '../../dist/config.js';
|
|
5
|
-
import * as fs from '../../dist/vfs/index.js';
|
|
6
|
-
import { InMemory, mounts } from '../../dist/index.js';
|
|
7
5
|
|
|
8
6
|
suite('Mounts', () => {
|
|
9
7
|
test('Mount in nested directory', async () => {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { InMemoryStore, Mutexed, StoreFS } from '@zenfs/core';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { suite, test } from 'node:test';
|
|
4
5
|
import { wait } from 'utilium';
|
|
5
|
-
import { InMemoryStore } from '../../dist/backends/memory.js';
|
|
6
|
-
import { StoreFS } from '../../dist/backends/store/fs.js';
|
|
7
|
-
import { Mutexed } from '../../dist/mixins/mutexed.js';
|
|
8
6
|
|
|
9
7
|
suite('Mutexed FS', () => {
|
|
10
8
|
const fs = new (Mutexed(StoreFS))(new InMemoryStore(0x10000, 'test'));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { suite, test } from 'node:test';
|
|
4
|
-
import { basename, dirname, extname, join, normalize, resolve } from '
|
|
5
|
-
import
|
|
4
|
+
import { basename, dirname, extname, join, normalize, resolve } from '@zenfs/core/path';
|
|
5
|
+
import { fs } from '@zenfs/core';
|
|
6
6
|
|
|
7
7
|
suite('Path emulation', () => {
|
|
8
8
|
test('resolve', () => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { createInterface, Interface } from '@zenfs/core/readline';
|
|
2
3
|
import assert from 'node:assert/strict';
|
|
3
4
|
import { PassThrough } from 'node:stream';
|
|
4
5
|
import { suite, test } from 'node:test';
|
|
5
6
|
import { wait } from 'utilium';
|
|
6
|
-
import { createInterface, Interface } from '../../dist/readline.js';
|
|
7
7
|
|
|
8
8
|
suite('Readline interface', { skip: true }, () => {
|
|
9
9
|
test('creates interface with readable stream', async () => {
|
package/tests/common.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { fs as defaultFS } from '@zenfs/core';
|
|
3
|
+
import type { NodeFS } from '@zenfs/core/node/types.js';
|
|
2
4
|
import { join, resolve } from 'node:path';
|
|
3
|
-
import { fs as defaultFS } from '../dist/index.js';
|
|
4
|
-
import { setupLogs } from './logs.js';
|
|
5
5
|
import { styleText } from 'node:util';
|
|
6
|
-
|
|
6
|
+
import { setupLogs } from './logs.js';
|
|
7
7
|
|
|
8
8
|
setupLogs();
|
|
9
9
|
|
|
@@ -18,4 +18,5 @@ const setup = await import(setupPath).catch(error => {
|
|
|
18
18
|
throw error;
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Satisfies is used to make sure that ZenFS is fully type compatible with Node.js
|
|
22
|
+
export const fs = (setup.fs || defaultFS) as typeof defaultFS satisfies NodeFS;
|
package/tests/fetch/fetch.ts
CHANGED
package/tests/fs/dir.test.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
2
|
+
import { sync, type Dirent } from '@zenfs/core';
|
|
2
3
|
import assert, { rejects } from 'node:assert/strict';
|
|
3
4
|
import { suite, test } from 'node:test';
|
|
4
|
-
import { fs
|
|
5
|
+
import { fs } from '../common.js';
|
|
5
6
|
|
|
6
7
|
const testFile = 'test-file.txt';
|
|
7
8
|
fs.writeFileSync(testFile, 'Sample content');
|
|
@@ -13,48 +14,7 @@ fs.mkdirSync(testDirPath);
|
|
|
13
14
|
for (const file of testFiles) {
|
|
14
15
|
fs.writeFileSync(`${testDirPath}/${file}`, 'Sample content');
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
-
suite('Dirent', () => {
|
|
18
|
-
test('name and parentPath getters', async () => {
|
|
19
|
-
const stats = await fs.promises.lstat(testFile);
|
|
20
|
-
const dirent = fs.Dirent.from(testFile, stats);
|
|
21
|
-
|
|
22
|
-
assert.equal(dirent.name, testFile);
|
|
23
|
-
assert.equal(dirent.parentPath, '.');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('isFile', async () => {
|
|
27
|
-
const fileStats = await fs.promises.lstat(testFile);
|
|
28
|
-
const fileDirent = fs.Dirent.from(testFile, fileStats);
|
|
29
|
-
|
|
30
|
-
assert(fileDirent.isFile());
|
|
31
|
-
assert(!fileDirent.isDirectory());
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('isDirectory', async () => {
|
|
35
|
-
const dirStats = await fs.promises.lstat('test-directory');
|
|
36
|
-
const dirDirent = fs.Dirent.from('test-directory', dirStats);
|
|
37
|
-
|
|
38
|
-
assert(!dirDirent.isFile());
|
|
39
|
-
assert(dirDirent.isDirectory());
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('isSymbolicLink', async () => {
|
|
43
|
-
const symlinkStats = await fs.promises.lstat('test-symlink');
|
|
44
|
-
const symlinkDirent = fs.Dirent.from('test-symlink', symlinkStats);
|
|
45
|
-
|
|
46
|
-
assert(symlinkDirent.isSymbolicLink());
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('other methods return false', async () => {
|
|
50
|
-
const fileStats = await fs.promises.lstat(testFile);
|
|
51
|
-
const fileDirent = fs.Dirent.from(testFile, fileStats);
|
|
52
|
-
|
|
53
|
-
assert(!fileDirent.isBlockDevice());
|
|
54
|
-
assert(!fileDirent.isCharacterDevice());
|
|
55
|
-
assert(!fileDirent.isSocket());
|
|
56
|
-
});
|
|
57
|
-
});
|
|
17
|
+
await sync();
|
|
58
18
|
|
|
59
19
|
suite('Dir', () => {
|
|
60
20
|
test('read()', async () => {
|
|
@@ -29,7 +29,7 @@ suite('Directories', () => {
|
|
|
29
29
|
test('mkdirSync', async () => await fs.promises.mkdir('/two', 0o000));
|
|
30
30
|
|
|
31
31
|
test('mkdir, nested', async () => {
|
|
32
|
-
await assert.rejects(fs.promises.mkdir('/nested/dir'), { code: 'ENOENT', path: '/nested' });
|
|
32
|
+
await assert.rejects(fs.promises.mkdir('/nested/dir'), { code: 'ENOENT', path: '/nested/dir' });
|
|
33
33
|
assert(!(await fs.promises.exists('/nested/dir')));
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -148,9 +148,9 @@ suite('Directories', () => {
|
|
|
148
148
|
entries.sort((a, b) => join(a.parentPath, a.name).localeCompare(join(b.parentPath, b.name)));
|
|
149
149
|
const values = entries.map(entry => [entry.parentPath, entry.name]);
|
|
150
150
|
|
|
151
|
-
assert.deepEqual(values[0], [
|
|
152
|
-
assert.deepEqual(values[4], [
|
|
153
|
-
assert.deepEqual(values[8], [
|
|
151
|
+
assert.deepEqual(values[0], ['.', 'file1.txt']);
|
|
152
|
+
assert.deepEqual(values[4], ['subdir1', 'file4.txt']);
|
|
153
|
+
assert.deepEqual(values[8], ['subdir2', 'file5.txt']);
|
|
154
154
|
});
|
|
155
155
|
|
|
156
156
|
test('readdirSync returns files recursively', () => {
|