@poe-platform/safe-fs 0.1.511 → 0.1.513
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/safe-fs/bridge/stats.js +1 -1
- package/dist/safe-fs/contracts/errors.d.ts +1 -0
- package/dist/safe-fs/contracts/errors.js +1 -0
- package/dist/safe-fs/contracts/filesystem.d.ts +22 -2
- package/dist/safe-fs/fs/capabilities.d.ts +4 -2
- package/dist/safe-fs/fs/capabilities.js +80 -9
- package/dist/safe-fs/fs/devices/index.d.ts +4 -3
- package/dist/safe-fs/fs/devices/index.js +75 -16
- package/dist/safe-fs/fs/devices/path.d.ts +1 -1
- package/dist/safe-fs/fs/devices/path.js +111 -7
- package/dist/safe-fs/fs/memory/index.d.ts +5 -2
- package/dist/safe-fs/fs/memory/index.js +107 -10
- package/dist/safe-fs/fs/mount/index.d.ts +4 -3
- package/dist/safe-fs/fs/mount/index.js +66 -14
- package/dist/safe-fs/fs/overlay/index.d.ts +3 -3
- package/dist/safe-fs/fs/overlay/index.js +9 -3
- package/dist/safe-fs/fs/path-namespace.d.ts +4 -0
- package/dist/safe-fs/fs/path-namespace.js +63 -0
- package/dist/safe-fs/fs/quota/index.js +142 -6
- package/dist/safe-fs/fs/readonly/index.d.ts +4 -3
- package/dist/safe-fs/fs/readonly/index.js +14 -1
- package/dist/safe-fs/fs/real/index.d.ts +3 -2
- package/dist/safe-fs/fs/real/index.js +177 -8
- package/dist/safe-fs/fs/scoped.js +111 -13
- package/dist/safe-fs/native/fs-seek/linux-x64-glibc.node +0 -0
- package/dist/safe-fs/native/fs-seek/loader.d.ts +5 -0
- package/dist/safe-fs/native/fs-seek/loader.mjs +120 -0
- package/dist/safe-fs/native/fs-seek/manifest.json +46 -0
- package/dist/safe-fs/node/native-seek.d.ts +3 -0
- package/dist/safe-fs/node/native-seek.js +54 -0
- package/package.json +7 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { FsError } from "../contracts/errors.js";
|
|
2
2
|
import { finishCleanup } from "../contracts/cleanup.js";
|
|
3
3
|
import { registerEntryView } from "./mount/comparison.js";
|
|
4
|
+
import { openRetainedResizeFile, retainedResizeCapabilities } from "./capabilities.js";
|
|
4
5
|
const originals = new WeakMap();
|
|
5
6
|
const operations = new Set([
|
|
6
7
|
"access", "appendFile", "canonicalizeMissingTarget", "capabilitiesFor", "chmod", "compareEntry",
|
|
7
|
-
"copyFile", "link", "lstat", "mkdir", "openReadFile", "readFile", "readStream", "readdir",
|
|
8
|
+
"copyFile", "link", "lstat", "mkdir", "openReadFile", "openResizeFile", "readFile", "readStream", "readdir",
|
|
8
9
|
"readlink", "realpath", "rename", "rm", "rmdir", "stat", "symlink", "truncate", "utimes",
|
|
9
10
|
"writeFile", "writeStream",
|
|
10
11
|
]);
|
|
@@ -19,11 +20,98 @@ export function scopeFileSystem(filesystem, charge, signal) {
|
|
|
19
20
|
assertOpen(options);
|
|
20
21
|
charge();
|
|
21
22
|
};
|
|
22
|
-
const wrapHandle = (handle) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const wrapHandle = (handle) => {
|
|
24
|
+
let closed = false;
|
|
25
|
+
const close = handle.close.bind(handle);
|
|
26
|
+
return {
|
|
27
|
+
async stat(options) { admit(options); return handle.stat(options); },
|
|
28
|
+
async read(position, maxBytes, options) { admit(options); return handle.read(position, maxBytes, options); },
|
|
29
|
+
get seekEnd() {
|
|
30
|
+
const seek = handle.seekEnd;
|
|
31
|
+
if (typeof seek !== "function")
|
|
32
|
+
return undefined;
|
|
33
|
+
return async (options = {}) => {
|
|
34
|
+
assertOpen(options);
|
|
35
|
+
if (closed)
|
|
36
|
+
throw new FsError("EBADF");
|
|
37
|
+
admit(options);
|
|
38
|
+
assertOpen(options);
|
|
39
|
+
if (closed)
|
|
40
|
+
throw new FsError("EBADF");
|
|
41
|
+
try {
|
|
42
|
+
const result = await Reflect.apply(seek, handle, [resizeOptions(options)]);
|
|
43
|
+
assertOpen(options);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
assertOpen(options);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
close() { closed = true; return close(); },
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const resizeOptions = (options) => {
|
|
56
|
+
const scopedOptions = {
|
|
57
|
+
...options, signal: options.signal ? AbortSignal.any([signal, options.signal]) : signal,
|
|
58
|
+
};
|
|
59
|
+
scopedOptions.signal.throwIfAborted();
|
|
60
|
+
return scopedOptions;
|
|
61
|
+
};
|
|
62
|
+
const wrapResizeHandle = (handle) => {
|
|
63
|
+
let closing;
|
|
64
|
+
const admitOperation = (options) => {
|
|
65
|
+
assertOpen(options);
|
|
66
|
+
if (closing)
|
|
67
|
+
throw new FsError("EBADF");
|
|
68
|
+
admit(options);
|
|
69
|
+
assertOpen(options);
|
|
70
|
+
if (closing)
|
|
71
|
+
throw new FsError("EBADF");
|
|
72
|
+
return resizeOptions(options);
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
async stat(options = {}) {
|
|
76
|
+
try {
|
|
77
|
+
const result = await handle.stat(admitOperation(options));
|
|
78
|
+
assertOpen(options);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
assertOpen(options);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
async truncate(length, options = {}) {
|
|
87
|
+
try {
|
|
88
|
+
await handle.truncate(length, admitOperation(options));
|
|
89
|
+
assertOpen(options);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
assertOpen(options);
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
get seekEnd() {
|
|
97
|
+
const seek = handle.seekEnd;
|
|
98
|
+
if (typeof seek !== "function")
|
|
99
|
+
return undefined;
|
|
100
|
+
return async (options = {}) => {
|
|
101
|
+
try {
|
|
102
|
+
const result = await Reflect.apply(seek, handle, [admitOperation(options)]);
|
|
103
|
+
assertOpen(options);
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
assertOpen(options);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
close: () => closing ??= Promise.resolve().then(() => handle.close()),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
27
115
|
const wrapStream = (source, options) => ({
|
|
28
116
|
[Symbol.asyncIterator]() {
|
|
29
117
|
assertOpen(options);
|
|
@@ -62,6 +150,8 @@ export function scopeFileSystem(filesystem, charge, signal) {
|
|
|
62
150
|
return Reflect.set(original, property, value, original);
|
|
63
151
|
},
|
|
64
152
|
get(_target, property) {
|
|
153
|
+
if (property === "capabilities")
|
|
154
|
+
return retainedResizeCapabilities(original);
|
|
65
155
|
const method = Reflect.get(original, property, original);
|
|
66
156
|
if (typeof method !== "function")
|
|
67
157
|
return method;
|
|
@@ -90,13 +180,21 @@ export function scopeFileSystem(filesystem, charge, signal) {
|
|
|
90
180
|
})();
|
|
91
181
|
return Reflect.apply(method, original, args);
|
|
92
182
|
};
|
|
93
|
-
const scoped = property === "
|
|
94
|
-
? async (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
183
|
+
const scoped = property === "openResizeFile"
|
|
184
|
+
? async (path, options = {}) => {
|
|
185
|
+
admit(options);
|
|
186
|
+
assertOpen(options);
|
|
187
|
+
return wrapResizeHandle(await openRetainedResizeFile(original, path, resizeOptions(options)));
|
|
188
|
+
}
|
|
189
|
+
: property === "capabilitiesFor"
|
|
190
|
+
? async (...args) => retainedResizeCapabilities(original, await dispatch(...args))
|
|
191
|
+
: property === "openReadFile"
|
|
192
|
+
? async (...args) => wrapHandle(await dispatch(...args))
|
|
193
|
+
: property === "readStream"
|
|
194
|
+
? (...args) => wrapStream(dispatch(...args), args[1])
|
|
195
|
+
: operations.has(property) && property !== "canonicalizeMissingTarget"
|
|
196
|
+
? async (...args) => dispatch(...args)
|
|
197
|
+
: dispatch;
|
|
100
198
|
methods.set(property, { original: method, scoped });
|
|
101
199
|
return scoped;
|
|
102
200
|
},
|
|
Binary file
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { open } from "node:fs/promises";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
const maxManifestBytes = 16384;
|
|
10
|
+
const maxBinaryBytes = 1048576;
|
|
11
|
+
let loading;
|
|
12
|
+
|
|
13
|
+
function failure(code, message) {
|
|
14
|
+
return Object.assign(new Error(message), { code });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function identifier(value) {
|
|
18
|
+
return typeof value === "string" && value.length > 0 && value.length <= 32
|
|
19
|
+
&& [...value].every(character => "abcdefghijklmnopqrstuvwxyz0123456789_".includes(character));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function decimal(value) {
|
|
23
|
+
return typeof value === "string" && value.length > 0 && value.length <= 6
|
|
24
|
+
&& [...value].every(character => "0123456789".includes(character));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function libcVersion(value) {
|
|
28
|
+
if (typeof value !== "string") return undefined;
|
|
29
|
+
const parts = value.split(".");
|
|
30
|
+
return parts.length === 2 && parts.every(decimal) ? parts.map(Number) : undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function atLeast(version, minimum) {
|
|
34
|
+
return version[0] > minimum[0] || version[0] === minimum[0] && version[1] >= minimum[1];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function readAsset(filename, limit) {
|
|
38
|
+
const handle = await open(filename, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
39
|
+
let failed = false;
|
|
40
|
+
let primary;
|
|
41
|
+
let bytes;
|
|
42
|
+
try {
|
|
43
|
+
const stat = await handle.stat();
|
|
44
|
+
if (!stat.isFile()) throw failure("EINVAL", "Native asset must be a regular file");
|
|
45
|
+
if (!Number.isSafeInteger(stat.size) || stat.size <= 0) throw failure("EINVAL", "Invalid native asset size");
|
|
46
|
+
if (stat.size > limit) throw failure("EFBIG", "Native asset exceeds its byte limit");
|
|
47
|
+
bytes = Buffer.alloc(stat.size);
|
|
48
|
+
let offset = 0;
|
|
49
|
+
while (offset < bytes.length) {
|
|
50
|
+
const remaining = bytes.length - offset;
|
|
51
|
+
const { bytesRead } = await handle.read(bytes, offset, remaining, offset);
|
|
52
|
+
if (!Number.isSafeInteger(bytesRead) || bytesRead <= 0 || bytesRead > remaining) throw failure("EIO", "Incomplete native asset read");
|
|
53
|
+
offset += bytesRead;
|
|
54
|
+
}
|
|
55
|
+
const { bytesRead } = await handle.read(Buffer.alloc(1), 0, 1, offset);
|
|
56
|
+
if (bytesRead !== 0) throw failure("EIO", "Native asset changed while reading");
|
|
57
|
+
} catch (error) {
|
|
58
|
+
failed = true;
|
|
59
|
+
primary = error;
|
|
60
|
+
}
|
|
61
|
+
try { await handle.close(); }
|
|
62
|
+
catch (error) { if (!failed) throw error; }
|
|
63
|
+
if (failed) throw primary;
|
|
64
|
+
return bytes;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function validateManifest(value) {
|
|
68
|
+
const invalid = () => { throw failure("EINVAL", "Invalid native seek manifest"); };
|
|
69
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)
|
|
70
|
+
|| value.version !== 1 || value.napi !== 6 || value.maxBinaryBytes !== maxBinaryBytes
|
|
71
|
+
|| !Array.isArray(value.targets)) invalid();
|
|
72
|
+
const selected = new Set();
|
|
73
|
+
for (const target of value.targets) {
|
|
74
|
+
if (target === null || typeof target !== "object" || Array.isArray(target)
|
|
75
|
+
|| !identifier(target.platform) || !identifier(target.arch) || !identifier(target.libc)
|
|
76
|
+
|| !Number.isSafeInteger(target.size) || target.size <= 0 || target.size > maxBinaryBytes
|
|
77
|
+
|| typeof target.sha256 !== "string" || target.sha256.length !== 64
|
|
78
|
+
|| ![...target.sha256].every(character => "0123456789abcdef".includes(character))) invalid();
|
|
79
|
+
const minimum = libcVersion(target.minimumLibc);
|
|
80
|
+
if (!minimum || !atLeast(minimum, [2, 31])) invalid();
|
|
81
|
+
const key = `${target.platform}-${target.arch}-${target.libc}`;
|
|
82
|
+
if (selected.has(key)) invalid();
|
|
83
|
+
selected.add(key);
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function load() {
|
|
89
|
+
const platform = process.platform;
|
|
90
|
+
const arch = process.arch;
|
|
91
|
+
const napi = process.versions.napi;
|
|
92
|
+
if (platform !== "linux" || arch !== "x64" || !decimal(napi) || Number(napi) < 6) {
|
|
93
|
+
throw failure("ENOTSUP", "Native seek is unavailable for this runtime");
|
|
94
|
+
}
|
|
95
|
+
const report = process.report;
|
|
96
|
+
const getReport = report?.getReport;
|
|
97
|
+
if (typeof getReport !== "function") throw failure("ENOTSUP", "Native seek requires a known glibc runtime");
|
|
98
|
+
const version = libcVersion(Reflect.apply(getReport, report, [])?.header?.glibcVersionRuntime);
|
|
99
|
+
if (!version || !atLeast(version, [2, 31])) throw failure("ENOTSUP", "Native seek requires glibc 2.31 or newer");
|
|
100
|
+
const manifestPath = fileURLToPath(new URL("manifest.json", import.meta.url));
|
|
101
|
+
const manifest = validateManifest(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readAsset(manifestPath, maxManifestBytes))));
|
|
102
|
+
const target = manifest.targets.find(candidate => candidate.platform === platform && candidate.arch === arch && candidate.libc === "glibc");
|
|
103
|
+
if (!target || !atLeast(version, libcVersion(target.minimumLibc))) throw failure("ENOTSUP", "Native seek has no compatible asset");
|
|
104
|
+
const filename = fileURLToPath(new URL(`${target.platform}-${target.arch}-${target.libc}.node`, import.meta.url));
|
|
105
|
+
const bytes = await readAsset(filename, maxBinaryBytes);
|
|
106
|
+
if (bytes.length !== target.size || createHash("sha256").update(bytes).digest("hex") !== target.sha256) {
|
|
107
|
+
throw failure("EIO", "Native seek asset integrity check failed");
|
|
108
|
+
}
|
|
109
|
+
const require = createRequire(import.meta.url);
|
|
110
|
+
const binding = require(filename);
|
|
111
|
+
if (binding === null || typeof binding !== "object" || typeof binding.seekEnd !== "function") {
|
|
112
|
+
throw failure("EIO", "Invalid native seek binding");
|
|
113
|
+
}
|
|
114
|
+
return binding;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function loadBinding() {
|
|
118
|
+
loading ??= Promise.resolve().then(load);
|
|
119
|
+
return loading;
|
|
120
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"napi": 6,
|
|
4
|
+
"maxBinaryBytes": 1048576,
|
|
5
|
+
"targets": [
|
|
6
|
+
{
|
|
7
|
+
"platform": "linux",
|
|
8
|
+
"arch": "x64",
|
|
9
|
+
"libc": "glibc",
|
|
10
|
+
"minimumLibc": "2.31",
|
|
11
|
+
"size": 17064,
|
|
12
|
+
"sha256": "7e0b6e24f5e49a0a058e3d95c2aee8b438a753d4f36052537b91084a81ef0d53"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"build": {
|
|
16
|
+
"sourceSha256": "e689d83731bc7ce2ab9632d5927f7f6c8af05a5258b057efa9c1566a888ced6e",
|
|
17
|
+
"loaderSha256": "337c49bc6744b137633eeb1fd19c19568fdc6d5eb0dfdc34d6bf45dd02573e38",
|
|
18
|
+
"declarationSha256": "19105e59e4bcc7a1706f74d261a5b09d2404eccaa27cc0bbc9d2af0dc9ef3684",
|
|
19
|
+
"headers": {
|
|
20
|
+
"version": "1.9.0",
|
|
21
|
+
"files": {
|
|
22
|
+
"node_api.h": {
|
|
23
|
+
"size": 10370,
|
|
24
|
+
"sha256": "2d4560831e525b47b060ec8a0864ab73993df9e20215ce9f0fe7b24cd31af32a"
|
|
25
|
+
},
|
|
26
|
+
"node_api_types.h": {
|
|
27
|
+
"size": 1930,
|
|
28
|
+
"sha256": "a25356630d3058f0a0c8937d9f297e9471e037fda58c2696d8a505c2bd99cb00"
|
|
29
|
+
},
|
|
30
|
+
"js_native_api.h": {
|
|
31
|
+
"size": 31081,
|
|
32
|
+
"sha256": "0953395662ea63697cd7a77a9320d94aa2829f9c9569abf3a74272b7a2923ce8"
|
|
33
|
+
},
|
|
34
|
+
"js_native_api_types.h": {
|
|
35
|
+
"size": 6896,
|
|
36
|
+
"sha256": "e785c16a9ce200e801242275cfd59090b029b5dae309a1a258f48d1570bf35ab"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"compiler": {
|
|
41
|
+
"path": "/usr/bin/cc",
|
|
42
|
+
"sha256": "1b99826121ae6682a634e5efe09bd3e3df58ce58e0b28f849114ab5b89139c26",
|
|
43
|
+
"version": "x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0\nCopyright (C) 2023 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions. There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NativeSeekBinding } from "#safe-fs-native-seek";
|
|
2
|
+
export declare function loadNativeSeekBinding(signal?: AbortSignal): Promise<NativeSeekBinding>;
|
|
3
|
+
export declare function callNativeSeekEnd(binding: NativeSeekBinding, seek: NativeSeekBinding["seekEnd"], descriptor: number): Promise<bigint>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getSystemErrorName } from "node:util";
|
|
2
|
+
import { FsError, isErrnoCode } from "../contracts/errors.js";
|
|
3
|
+
export async function loadNativeSeekBinding(signal) {
|
|
4
|
+
signal?.throwIfAborted();
|
|
5
|
+
const initialization = (async () => {
|
|
6
|
+
const module = await import("#safe-fs-native-seek");
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
const load = module.loadBinding;
|
|
9
|
+
signal?.throwIfAborted();
|
|
10
|
+
if (typeof load !== "function")
|
|
11
|
+
throw new FsError("EIO");
|
|
12
|
+
const binding = await Reflect.apply(load, module, []);
|
|
13
|
+
signal?.throwIfAborted();
|
|
14
|
+
if (binding === null || typeof binding !== "object" || Array.isArray(binding))
|
|
15
|
+
throw new FsError("EIO");
|
|
16
|
+
return binding;
|
|
17
|
+
})();
|
|
18
|
+
if (!signal)
|
|
19
|
+
return initialization;
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const abort = () => { signal.removeEventListener("abort", abort); reject(signal.reason); };
|
|
22
|
+
initialization.then(binding => {
|
|
23
|
+
signal.removeEventListener("abort", abort);
|
|
24
|
+
if (signal.aborted)
|
|
25
|
+
reject(signal.reason);
|
|
26
|
+
else
|
|
27
|
+
resolve(binding);
|
|
28
|
+
}, error => {
|
|
29
|
+
signal.removeEventListener("abort", abort);
|
|
30
|
+
reject(signal.aborted ? signal.reason : error);
|
|
31
|
+
});
|
|
32
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
33
|
+
if (signal.aborted)
|
|
34
|
+
abort();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function callNativeSeekEnd(binding, seek, descriptor) {
|
|
38
|
+
const result = await Reflect.apply(seek, binding, [descriptor]);
|
|
39
|
+
if (result === null || typeof result !== "object" || Array.isArray(result))
|
|
40
|
+
throw new FsError("EIO");
|
|
41
|
+
const { offset, errno } = result;
|
|
42
|
+
if (typeof offset !== "bigint" || typeof errno !== "number" || !Number.isSafeInteger(errno)
|
|
43
|
+
|| errno < 0 || errno > 2147483647)
|
|
44
|
+
throw new FsError("EIO");
|
|
45
|
+
if (errno !== 0) {
|
|
46
|
+
if (offset !== -1n)
|
|
47
|
+
throw new FsError("EIO");
|
|
48
|
+
const code = getSystemErrorName(-errno);
|
|
49
|
+
throw new FsError(isErrnoCode(code) ? code : "EIO");
|
|
50
|
+
}
|
|
51
|
+
if (offset < 0n || offset > 9223372036854775807n)
|
|
52
|
+
throw new FsError("EIO");
|
|
53
|
+
return offset;
|
|
54
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poe-platform/safe-fs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.513",
|
|
4
4
|
"description": "Composable filesystem with a portable core and explicit Node adapters",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -107,6 +107,12 @@
|
|
|
107
107
|
},
|
|
108
108
|
"browser": "./dist/safe-fs/platform/browser.js",
|
|
109
109
|
"default": "./dist/safe-fs/platform/node.js"
|
|
110
|
+
},
|
|
111
|
+
"#safe-fs-native-seek": {
|
|
112
|
+
"types": "./dist/safe-fs/native/fs-seek/loader.d.ts",
|
|
113
|
+
"workerd": null,
|
|
114
|
+
"browser": null,
|
|
115
|
+
"default": "./dist/safe-fs/native/fs-seek/loader.mjs"
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
}
|