@utoo/web 1.3.0 → 1.3.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/esm/loaderWorker.js +1 -1
- package/esm/project/Project.d.ts +15 -0
- package/esm/project/Project.js +4 -0
- package/esm/project/checkCompatibility.d.ts +15 -0
- package/esm/project/checkCompatibility.js +31 -0
- package/esm/utoo/index.d.ts +32 -1
- package/esm/utoo/index.js +212 -58
- package/esm/utoo/index_bg.wasm +0 -0
- package/esm/webpackLoaders/cjs.js +107 -141
- package/esm/webpackLoaders/polyfills/{fsPolyfill.d.ts → fsPolyfill/index.d.ts} +3 -3
- package/esm/webpackLoaders/polyfills/fsPolyfill/index.js +384 -0
- package/esm/webpackLoaders/polyfills/{fsPromisesPolyfill.d.ts → fsPolyfill/promises.d.ts} +1 -1
- package/esm/webpackLoaders/polyfills/fsPolyfill/promises.js +159 -0
- package/esm/webpackLoaders/polyfills/fsPolyfill/utils.d.ts +3 -0
- package/esm/webpackLoaders/polyfills/fsPolyfill/utils.js +91 -0
- package/package.json +1 -1
- package/esm/webpackLoaders/polyfills/fsPolyfill.js +0 -291
- package/esm/webpackLoaders/polyfills/fsPromisesPolyfill.js +0 -113
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
import { Stats } from "../../../types";
|
|
3
|
+
import { promises } from "./promises";
|
|
4
|
+
import { getFs, resolvePath, translateError } from "./utils";
|
|
5
|
+
// --- Synchronous API (via WASM Project Sync APIs) ---
|
|
6
|
+
const textDecoder = new TextDecoder();
|
|
7
|
+
export function readFileSync(path, options) {
|
|
8
|
+
const fs = getFs();
|
|
9
|
+
const resolvedPath = resolvePath(path);
|
|
10
|
+
try {
|
|
11
|
+
const result = fs.readSync(resolvedPath);
|
|
12
|
+
if (options === "utf8" ||
|
|
13
|
+
options === "utf-8" ||
|
|
14
|
+
(options && (options.encoding === "utf8" || options.encoding === "utf-8"))) {
|
|
15
|
+
return textDecoder.decode(result);
|
|
16
|
+
}
|
|
17
|
+
return Buffer.from(result);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
throw translateError(e, path, "open");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function readdirSync(path, options) {
|
|
24
|
+
const fs = getFs();
|
|
25
|
+
const resolvedPath = resolvePath(path);
|
|
26
|
+
try {
|
|
27
|
+
const entries = fs.readDirSync(resolvedPath);
|
|
28
|
+
if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
|
|
29
|
+
return entries.map((e) => ({
|
|
30
|
+
name: e.name,
|
|
31
|
+
isFile: () => e.type === "file",
|
|
32
|
+
isDirectory: () => e.type === "directory",
|
|
33
|
+
isSymbolicLink: () => false,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
return entries.map((e) => e.name);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw translateError(e, path, "scandir");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function writeFileSync(path, data, options) {
|
|
43
|
+
const fs = getFs();
|
|
44
|
+
const resolvedPath = resolvePath(path);
|
|
45
|
+
try {
|
|
46
|
+
let content;
|
|
47
|
+
if (typeof data === "string") {
|
|
48
|
+
content = new TextEncoder().encode(data);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
content = data;
|
|
52
|
+
}
|
|
53
|
+
fs.writeSync(resolvedPath, content);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
throw translateError(e, path, "open");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function mkdirSync(path, options) {
|
|
60
|
+
const fs = getFs();
|
|
61
|
+
const resolvedPath = resolvePath(path);
|
|
62
|
+
try {
|
|
63
|
+
const recursive = (options === null || options === void 0 ? void 0 : options.recursive) || false;
|
|
64
|
+
if (recursive) {
|
|
65
|
+
fs.createDirAllSync(resolvedPath);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
fs.createDirSync(resolvedPath);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
throw translateError(e, path, "mkdir");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function rmSync(path, options) {
|
|
76
|
+
const fs = getFs();
|
|
77
|
+
const resolvedPath = resolvePath(path);
|
|
78
|
+
try {
|
|
79
|
+
const recursive = (options === null || options === void 0 ? void 0 : options.recursive) || false;
|
|
80
|
+
if (recursive) {
|
|
81
|
+
fs.removeDirSync(resolvedPath, true);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
fs.removeFileSync(resolvedPath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
throw translateError(e, path, "rm");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function rmdirSync(path, options) {
|
|
92
|
+
const fs = getFs();
|
|
93
|
+
const resolvedPath = resolvePath(path);
|
|
94
|
+
try {
|
|
95
|
+
const recursive = (options === null || options === void 0 ? void 0 : options.recursive) || false;
|
|
96
|
+
fs.removeDirSync(resolvedPath, recursive);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
throw translateError(e, path, "rmdir");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function copyFileSync(src, dst) {
|
|
103
|
+
const fs = getFs();
|
|
104
|
+
try {
|
|
105
|
+
fs.copyFileSync(resolvePath(src), resolvePath(dst));
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
throw translateError(e, src, "copyfile");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function statSync(p) {
|
|
112
|
+
const fs = getFs();
|
|
113
|
+
const resolvedPath = resolvePath(p);
|
|
114
|
+
try {
|
|
115
|
+
const metadata = fs.metadataSync(resolvedPath);
|
|
116
|
+
let type, size;
|
|
117
|
+
// @ts-ignore
|
|
118
|
+
if (typeof metadata.toJSON === "function") {
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
const json = metadata.toJSON();
|
|
121
|
+
type = json.type;
|
|
122
|
+
size = json.file_size;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
type = metadata.type;
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
size = metadata.file_size;
|
|
129
|
+
}
|
|
130
|
+
return new Stats({
|
|
131
|
+
type: type === "directory" ? "directory" : "file",
|
|
132
|
+
size: Number(size || 0),
|
|
133
|
+
atimeMs: Date.now(),
|
|
134
|
+
mtimeMs: Date.now(),
|
|
135
|
+
ctimeMs: Date.now(),
|
|
136
|
+
birthtimeMs: Date.now(),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
throw translateError(e, p, "stat");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function lstatSync(p) {
|
|
144
|
+
const fs = getFs();
|
|
145
|
+
const resolvedPath = resolvePath(p);
|
|
146
|
+
try {
|
|
147
|
+
const metadata = fs.metadataSync(resolvedPath);
|
|
148
|
+
let type, size;
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
if (typeof metadata.toJSON === "function") {
|
|
151
|
+
// @ts-ignore
|
|
152
|
+
const json = metadata.toJSON();
|
|
153
|
+
type = json.type;
|
|
154
|
+
size = json.file_size;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// @ts-ignore
|
|
158
|
+
type = metadata.type;
|
|
159
|
+
// @ts-ignore
|
|
160
|
+
size = metadata.file_size;
|
|
161
|
+
}
|
|
162
|
+
return new Stats({
|
|
163
|
+
type: type === "directory" ? "directory" : "file",
|
|
164
|
+
size: Number(size || 0),
|
|
165
|
+
atimeMs: Date.now(),
|
|
166
|
+
mtimeMs: Date.now(),
|
|
167
|
+
ctimeMs: Date.now(),
|
|
168
|
+
birthtimeMs: Date.now(),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
throw translateError(e, p, "lstat");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export function realpathSync(p) {
|
|
176
|
+
return p;
|
|
177
|
+
}
|
|
178
|
+
export function accessSync(p, mode) {
|
|
179
|
+
const fs = getFs();
|
|
180
|
+
const resolvedPath = resolvePath(p);
|
|
181
|
+
try {
|
|
182
|
+
fs.metadataSync(resolvedPath);
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
throw translateError(e, p, "access");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export function existsSync(path) {
|
|
189
|
+
try {
|
|
190
|
+
statSync(path);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// --- Asynchronous API (via WASM Project) ---
|
|
198
|
+
export function readFile(path, options, cb) {
|
|
199
|
+
if (typeof options === "function") {
|
|
200
|
+
cb = options;
|
|
201
|
+
options = {};
|
|
202
|
+
}
|
|
203
|
+
const encoding = options === "utf8" ||
|
|
204
|
+
options === "utf-8" ||
|
|
205
|
+
(options === null || options === void 0 ? void 0 : options.encoding) === "utf8" ||
|
|
206
|
+
(options === null || options === void 0 ? void 0 : options.encoding) === "utf-8"
|
|
207
|
+
? "utf8"
|
|
208
|
+
: undefined;
|
|
209
|
+
const resolvedPath = resolvePath(path);
|
|
210
|
+
const fs = getFs();
|
|
211
|
+
const promise = encoding
|
|
212
|
+
? fs.readToString(resolvedPath)
|
|
213
|
+
: fs.read(resolvedPath);
|
|
214
|
+
promise
|
|
215
|
+
.then((data) => {
|
|
216
|
+
cb(null, encoding ? data : Buffer.from(data));
|
|
217
|
+
})
|
|
218
|
+
.catch((e) => cb(translateError(e, path, "open")));
|
|
219
|
+
}
|
|
220
|
+
export function readdir(path, options, cb) {
|
|
221
|
+
if (typeof options === "function") {
|
|
222
|
+
cb = options;
|
|
223
|
+
options = {};
|
|
224
|
+
}
|
|
225
|
+
getFs()
|
|
226
|
+
.readDir(resolvePath(path))
|
|
227
|
+
.then((entries) => {
|
|
228
|
+
const result = entries.map((e) => {
|
|
229
|
+
const json = e.toJSON();
|
|
230
|
+
if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
|
|
231
|
+
return {
|
|
232
|
+
name: json.name,
|
|
233
|
+
isFile: () => json.type === "file",
|
|
234
|
+
isDirectory: () => json.type === "directory",
|
|
235
|
+
isSymbolicLink: () => false,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return json.name;
|
|
239
|
+
});
|
|
240
|
+
cb(null, result);
|
|
241
|
+
})
|
|
242
|
+
.catch((e) => cb(translateError(e, path, "scandir")));
|
|
243
|
+
}
|
|
244
|
+
export function writeFile(path, data, options, cb) {
|
|
245
|
+
if (typeof options === "function") {
|
|
246
|
+
cb = options;
|
|
247
|
+
options = {};
|
|
248
|
+
}
|
|
249
|
+
const resolvedPath = resolvePath(path);
|
|
250
|
+
const fs = getFs();
|
|
251
|
+
const promise = typeof data === "string"
|
|
252
|
+
? fs.writeString(resolvedPath, data)
|
|
253
|
+
: fs.write(resolvedPath, data);
|
|
254
|
+
promise
|
|
255
|
+
.then(() => cb(null))
|
|
256
|
+
.catch((e) => cb(translateError(e, path, "open")));
|
|
257
|
+
}
|
|
258
|
+
export function mkdir(path, options, cb) {
|
|
259
|
+
if (typeof options === "function") {
|
|
260
|
+
cb = options;
|
|
261
|
+
options = {};
|
|
262
|
+
}
|
|
263
|
+
const resolvedPath = resolvePath(path);
|
|
264
|
+
const fs = getFs();
|
|
265
|
+
const promise = (options === null || options === void 0 ? void 0 : options.recursive)
|
|
266
|
+
? fs.createDirAll(resolvedPath)
|
|
267
|
+
: fs.createDir(resolvedPath);
|
|
268
|
+
promise
|
|
269
|
+
.then(() => cb(null))
|
|
270
|
+
.catch((e) => cb(translateError(e, path, "mkdir")));
|
|
271
|
+
}
|
|
272
|
+
export function rm(path, options, cb) {
|
|
273
|
+
if (typeof options === "function") {
|
|
274
|
+
cb = options;
|
|
275
|
+
options = {};
|
|
276
|
+
}
|
|
277
|
+
const resolvedPath = resolvePath(path);
|
|
278
|
+
const fs = getFs();
|
|
279
|
+
fs.metadata(resolvedPath)
|
|
280
|
+
.then((metadata) => {
|
|
281
|
+
const type = metadata.toJSON().type;
|
|
282
|
+
if (type === "file") {
|
|
283
|
+
return fs.removeFile(resolvedPath);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
return fs.removeDir(resolvedPath, !!(options === null || options === void 0 ? void 0 : options.recursive));
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
.then(() => cb(null))
|
|
290
|
+
.catch((e) => cb(translateError(e, path, "rm")));
|
|
291
|
+
}
|
|
292
|
+
export function rmdir(path, options, cb) {
|
|
293
|
+
if (typeof options === "function") {
|
|
294
|
+
cb = options;
|
|
295
|
+
options = {};
|
|
296
|
+
}
|
|
297
|
+
getFs()
|
|
298
|
+
.removeDir(resolvePath(path), !!(options === null || options === void 0 ? void 0 : options.recursive))
|
|
299
|
+
.then(() => cb(null))
|
|
300
|
+
.catch((e) => cb(translateError(e, path, "rmdir")));
|
|
301
|
+
}
|
|
302
|
+
export function copyFile(src, dst, cb) {
|
|
303
|
+
getFs()
|
|
304
|
+
.copyFile(resolvePath(src), resolvePath(dst))
|
|
305
|
+
.then(() => cb(null))
|
|
306
|
+
.catch((e) => cb(translateError(e, src, "copyfile")));
|
|
307
|
+
}
|
|
308
|
+
export function stat(p, cb) {
|
|
309
|
+
getFs()
|
|
310
|
+
.metadata(resolvePath(p))
|
|
311
|
+
.then((metadata) => {
|
|
312
|
+
const json = metadata.toJSON();
|
|
313
|
+
cb(null, new Stats({
|
|
314
|
+
type: json.type,
|
|
315
|
+
size: Number(json.file_size || 0),
|
|
316
|
+
}));
|
|
317
|
+
})
|
|
318
|
+
.catch((e) => cb(translateError(e, p, "stat")));
|
|
319
|
+
}
|
|
320
|
+
export function lstat(p, cb) {
|
|
321
|
+
getFs()
|
|
322
|
+
.metadata(resolvePath(p))
|
|
323
|
+
.then((metadata) => {
|
|
324
|
+
const json = metadata.toJSON();
|
|
325
|
+
cb(null, new Stats({
|
|
326
|
+
type: json.type,
|
|
327
|
+
size: Number(json.file_size || 0),
|
|
328
|
+
}));
|
|
329
|
+
})
|
|
330
|
+
.catch((e) => cb(translateError(e, p, "lstat")));
|
|
331
|
+
}
|
|
332
|
+
export function realpath(p, cb) {
|
|
333
|
+
cb(null, p);
|
|
334
|
+
}
|
|
335
|
+
export function access(p, mode, cb) {
|
|
336
|
+
if (typeof mode === "function") {
|
|
337
|
+
cb = mode;
|
|
338
|
+
mode = 0;
|
|
339
|
+
}
|
|
340
|
+
getFs()
|
|
341
|
+
.metadata(resolvePath(p))
|
|
342
|
+
.then(() => {
|
|
343
|
+
if (cb)
|
|
344
|
+
cb(null);
|
|
345
|
+
})
|
|
346
|
+
.catch((e) => {
|
|
347
|
+
if (cb)
|
|
348
|
+
cb(translateError(e, p, "access"));
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
export const constants = {
|
|
352
|
+
F_OK: 0,
|
|
353
|
+
R_OK: 4,
|
|
354
|
+
W_OK: 2,
|
|
355
|
+
X_OK: 1,
|
|
356
|
+
};
|
|
357
|
+
export default {
|
|
358
|
+
readFile,
|
|
359
|
+
readFileSync,
|
|
360
|
+
readdir,
|
|
361
|
+
readdirSync,
|
|
362
|
+
writeFile,
|
|
363
|
+
writeFileSync,
|
|
364
|
+
mkdir,
|
|
365
|
+
mkdirSync,
|
|
366
|
+
rm,
|
|
367
|
+
rmSync,
|
|
368
|
+
rmdir,
|
|
369
|
+
rmdirSync,
|
|
370
|
+
copyFile,
|
|
371
|
+
copyFileSync,
|
|
372
|
+
stat,
|
|
373
|
+
statSync,
|
|
374
|
+
lstat,
|
|
375
|
+
lstatSync,
|
|
376
|
+
realpath,
|
|
377
|
+
realpathSync,
|
|
378
|
+
access,
|
|
379
|
+
accessSync,
|
|
380
|
+
existsSync,
|
|
381
|
+
promises,
|
|
382
|
+
constants,
|
|
383
|
+
};
|
|
384
|
+
export { promises };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
import { Stats } from "../../../types";
|
|
3
|
+
import { getFs, resolvePath, translateError } from "./utils";
|
|
4
|
+
export const promises = {
|
|
5
|
+
readFile: async (p, options) => {
|
|
6
|
+
const encoding = options === "utf8" ||
|
|
7
|
+
options === "utf-8" ||
|
|
8
|
+
(options === null || options === void 0 ? void 0 : options.encoding) === "utf8" ||
|
|
9
|
+
(options === null || options === void 0 ? void 0 : options.encoding) === "utf-8"
|
|
10
|
+
? "utf8"
|
|
11
|
+
: undefined;
|
|
12
|
+
const fs = getFs();
|
|
13
|
+
const resolvedPath = resolvePath(p);
|
|
14
|
+
try {
|
|
15
|
+
const data = await (encoding
|
|
16
|
+
? fs.readToString(resolvedPath)
|
|
17
|
+
: fs.read(resolvedPath));
|
|
18
|
+
return encoding ? data : Buffer.from(data);
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
throw translateError(e, p, "open");
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
writeFile: async (p, data, options) => {
|
|
25
|
+
const fs = getFs();
|
|
26
|
+
const resolvedPath = resolvePath(p);
|
|
27
|
+
try {
|
|
28
|
+
if (typeof data === "string") {
|
|
29
|
+
await fs.writeString(resolvedPath, data);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
await fs.write(resolvedPath, data);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
throw translateError(e, p, "open");
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
readdir: async (p, options) => {
|
|
40
|
+
const resolvedPath = resolvePath(p);
|
|
41
|
+
try {
|
|
42
|
+
const entries = await getFs().readDir(resolvedPath);
|
|
43
|
+
return entries.map((e) => {
|
|
44
|
+
const json = e.toJSON();
|
|
45
|
+
if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
|
|
46
|
+
return {
|
|
47
|
+
name: json.name,
|
|
48
|
+
isFile: () => json.type === "file",
|
|
49
|
+
isDirectory: () => json.type === "directory",
|
|
50
|
+
isSymbolicLink: () => false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return json.name;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
throw translateError(e, p, "scandir");
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
mkdir: async (p, options) => {
|
|
61
|
+
const fs = getFs();
|
|
62
|
+
const resolvedPath = resolvePath(p);
|
|
63
|
+
try {
|
|
64
|
+
if (options === null || options === void 0 ? void 0 : options.recursive) {
|
|
65
|
+
await fs.createDirAll(resolvedPath);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
await fs.createDir(resolvedPath);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
throw translateError(e, p, "mkdir");
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
rm: async (p, options) => {
|
|
76
|
+
const fs = getFs();
|
|
77
|
+
const resolvedPath = resolvePath(p);
|
|
78
|
+
try {
|
|
79
|
+
const metadata = await fs.metadata(resolvedPath);
|
|
80
|
+
const type = metadata.toJSON().type;
|
|
81
|
+
if (type === "file") {
|
|
82
|
+
await fs.removeFile(resolvedPath);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await fs.removeDir(resolvedPath, !!(options === null || options === void 0 ? void 0 : options.recursive));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
throw translateError(e, p, "rm");
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
rmdir: async (p, options) => {
|
|
93
|
+
const resolvedPath = resolvePath(p);
|
|
94
|
+
try {
|
|
95
|
+
return await getFs().removeDir(resolvedPath, !!(options === null || options === void 0 ? void 0 : options.recursive));
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
throw translateError(e, p, "rmdir");
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
copyFile: async (src, dst) => {
|
|
102
|
+
try {
|
|
103
|
+
return await getFs().copyFile(resolvePath(src), resolvePath(dst));
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
throw translateError(e, src, "copyfile");
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
stat: async (p) => {
|
|
110
|
+
const resolvedPath = resolvePath(p);
|
|
111
|
+
try {
|
|
112
|
+
const metadata = await getFs().metadata(resolvedPath);
|
|
113
|
+
const json = metadata.toJSON();
|
|
114
|
+
return new Stats({
|
|
115
|
+
type: json.type,
|
|
116
|
+
size: Number(json.file_size || 0),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
throw translateError(e, p, "stat");
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
lstat: async (p) => {
|
|
124
|
+
const resolvedPath = resolvePath(p);
|
|
125
|
+
try {
|
|
126
|
+
const metadata = await getFs().metadata(resolvedPath);
|
|
127
|
+
const json = metadata.toJSON();
|
|
128
|
+
return new Stats({
|
|
129
|
+
type: json.type,
|
|
130
|
+
size: Number(json.file_size || 0),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
throw translateError(e, p, "lstat");
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
realpath: async (p) => p,
|
|
138
|
+
access: async (p, mode) => {
|
|
139
|
+
const resolvedPath = resolvePath(p);
|
|
140
|
+
try {
|
|
141
|
+
await getFs().metadata(resolvedPath);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
throw translateError(e, p, "access");
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
export const readFile = promises.readFile;
|
|
149
|
+
export const writeFile = promises.writeFile;
|
|
150
|
+
export const readdir = promises.readdir;
|
|
151
|
+
export const mkdir = promises.mkdir;
|
|
152
|
+
export const rm = promises.rm;
|
|
153
|
+
export const rmdir = promises.rmdir;
|
|
154
|
+
export const copyFile = promises.copyFile;
|
|
155
|
+
export const stat = promises.stat;
|
|
156
|
+
export const lstat = promises.lstat;
|
|
157
|
+
export const realpath = promises.realpath;
|
|
158
|
+
export const access = promises.access;
|
|
159
|
+
export default promises;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { ERR_ABORT, ERR_INVALID_STATE, ERR_NO_MODIFICATION_ALLOWED, ERR_NOT_ALLOWED, ERR_NOT_FOUND, ERR_QUOTA_EXCEEDED, ERR_TYPE_MISMATCH, } from "../../../utoo";
|
|
3
|
+
import { workerData } from "../workerThreadsPolyfill";
|
|
4
|
+
export function resolvePath(p) {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
const cwd = ((_b = (_a = self.process) === null || _a === void 0 ? void 0 : _a.cwd) === null || _b === void 0 ? void 0 : _b.call(_a)) || (workerData === null || workerData === void 0 ? void 0 : workerData.cwd) || "/";
|
|
8
|
+
return path.resolve(cwd, p);
|
|
9
|
+
}
|
|
10
|
+
export function getFs() {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
const fs = workerData.fs;
|
|
13
|
+
if (!fs) {
|
|
14
|
+
throw new Error("FS not initialized");
|
|
15
|
+
}
|
|
16
|
+
return fs;
|
|
17
|
+
}
|
|
18
|
+
export function translateError(error, path, syscall) {
|
|
19
|
+
const message = error.message || String(error);
|
|
20
|
+
// 1. NotFound (ENOENT)
|
|
21
|
+
// Mapping "NotFoundError" from tokio-fs-ext
|
|
22
|
+
if (message.includes(ERR_NOT_FOUND())) {
|
|
23
|
+
const e = new Error(`ENOENT: no such file or directory, ${syscall} '${path}'`);
|
|
24
|
+
e.errno = -2;
|
|
25
|
+
e.code = "ENOENT";
|
|
26
|
+
e.syscall = syscall;
|
|
27
|
+
e.path = path;
|
|
28
|
+
return e;
|
|
29
|
+
}
|
|
30
|
+
// 2. Directory error (Mapped to EISDIR)
|
|
31
|
+
// Mapping "TypeMismatchError" or "type mismatch" from tokio-fs-ext
|
|
32
|
+
if (message.includes(ERR_TYPE_MISMATCH())) {
|
|
33
|
+
const e = new Error(`EISDIR: illegal operation on a directory, ${syscall} '${path}'`);
|
|
34
|
+
e.errno = -21;
|
|
35
|
+
e.code = "EISDIR";
|
|
36
|
+
e.syscall = syscall;
|
|
37
|
+
e.path = path;
|
|
38
|
+
return e;
|
|
39
|
+
}
|
|
40
|
+
// 3. Locking/Concurrency (Mapped to EAGAIN/EBUSY)
|
|
41
|
+
// Mapping "NoModificationAllowedError" from tokio-fs-ext
|
|
42
|
+
if (message.includes(ERR_NO_MODIFICATION_ALLOWED())) {
|
|
43
|
+
const e = new Error(`EAGAIN: resource temporarily unavailable, ${syscall} '${path}'`);
|
|
44
|
+
e.errno = -11;
|
|
45
|
+
e.code = "EAGAIN";
|
|
46
|
+
e.syscall = syscall;
|
|
47
|
+
e.path = path;
|
|
48
|
+
return e;
|
|
49
|
+
}
|
|
50
|
+
// 4. Permission Denied (EACCES)
|
|
51
|
+
// Mapping "NotAllowedError" from tokio-fs-ext
|
|
52
|
+
if (message.includes(ERR_NOT_ALLOWED())) {
|
|
53
|
+
const e = new Error(`EACCES: permission denied, ${syscall} '${path}'`);
|
|
54
|
+
e.errno = -13;
|
|
55
|
+
e.code = "EACCES";
|
|
56
|
+
e.syscall = syscall;
|
|
57
|
+
e.path = path;
|
|
58
|
+
return e;
|
|
59
|
+
}
|
|
60
|
+
// 5. Storage Full (ENOSPC)
|
|
61
|
+
// Mapping "QuotaExceededError" from tokio-fs-ext
|
|
62
|
+
if (message.includes(ERR_QUOTA_EXCEEDED())) {
|
|
63
|
+
const e = new Error(`ENOSPC: no space left on device, ${syscall} '${path}'`);
|
|
64
|
+
e.errno = -28;
|
|
65
|
+
e.code = "ENOSPC";
|
|
66
|
+
e.syscall = syscall;
|
|
67
|
+
e.path = path;
|
|
68
|
+
return e;
|
|
69
|
+
}
|
|
70
|
+
// 6. Invalid Argument (EINVAL)
|
|
71
|
+
// Mapping "InvalidStateError" from tokio-fs-ext
|
|
72
|
+
if (message.includes(ERR_INVALID_STATE())) {
|
|
73
|
+
const e = new Error(`EINVAL: invalid argument, ${syscall} '${path}'`);
|
|
74
|
+
e.errno = -22;
|
|
75
|
+
e.code = "EINVAL";
|
|
76
|
+
e.syscall = syscall;
|
|
77
|
+
e.path = path;
|
|
78
|
+
return e;
|
|
79
|
+
}
|
|
80
|
+
// 7. Interrupted (EINTR)
|
|
81
|
+
// Mapping "AbortError" from tokio-fs-ext
|
|
82
|
+
if (message.includes(ERR_ABORT())) {
|
|
83
|
+
const e = new Error(`EINTR: interrupted system call, ${syscall} '${path}'`);
|
|
84
|
+
e.errno = -4;
|
|
85
|
+
e.code = "EINTR";
|
|
86
|
+
e.syscall = syscall;
|
|
87
|
+
e.path = path;
|
|
88
|
+
return e;
|
|
89
|
+
}
|
|
90
|
+
return error;
|
|
91
|
+
}
|