Skip to content

Commit cc97726

Browse files
committed
feat: fs.stat working with tests
1 parent f273128 commit cc97726

8 files changed

Lines changed: 102 additions & 63 deletions

File tree

dist/phoenix-fs.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ const WS_COMMAND = {
8585
LARGE_DATA_SOCKET_ANNOUNCE: "largeDataSock",
8686
CONTROL_SOCKET_ANNOUNCE: "controlSock",
8787
GET_WINDOWS_DRIVES: "getWinDrives",
88-
READ_DIR: "readDir"
88+
READ_DIR: "readDir",
89+
STAT: "stat"
8990
};
9091

9192
const LARGE_DATA_THRESHOLD = 2*1024*1024; // 2MB
@@ -148,21 +149,21 @@ function _getStat(fullPath) {
148149
});
149150
}
150151

152+
function _reportError(ws, metadata, err, defaultMessage = "Operation failed! ") {
153+
metadata.error = {
154+
message: err.message || defaultMessage,
155+
code: err.code || "EIO",
156+
stack: err.stack
157+
};
158+
_sendResponse(ws, metadata);
159+
}
160+
151161
function _readDir(ws, metadata) {
152162
const fullPath = metadata.data.path,
153163
options = metadata.data.options || {};
154164
const withFileTypes = options.withFileTypes;
155165
options.withFileTypes = null;
156166

157-
function _reportError(err) {
158-
metadata.error = {
159-
message: err.message || "Cannot readdir "+ fullPath,
160-
code: err.code || "EIO",
161-
stack: err.stack
162-
};
163-
_sendResponse(ws, metadata);
164-
}
165-
166167
fs.readdir(fullPath, options)
167168
.then(contents=>{
168169
if(withFileTypes){
@@ -174,11 +175,19 @@ function _readDir(ws, metadata) {
174175
.then(contentStats =>{
175176
_sendResponse(ws, metadata, {contentStats});
176177
})
177-
.catch(_reportError);
178+
.catch((err)=>_reportError(ws, metadata, err, `Cannot readdir ${fullPath}`));
178179
} else {
179180
_sendResponse(ws, metadata, {contents});
180181
}
181-
}).catch(_reportError);
182+
}).catch((err)=>_reportError(ws, metadata, err, `Cannot readdir ${fullPath}`));
183+
}
184+
185+
function _stat(ws, metadata) {
186+
const fullPath = metadata.data.path;
187+
_getStat(fullPath)
188+
.then(stat=>{
189+
_sendResponse(ws, metadata, {stat});
190+
}).catch((err)=>_reportError(ws, metadata, err, `Failed to get stat for ${fullPath}`));
182191
}
183192

184193
function processWSCommand(ws, metadata, dataBuffer) {
@@ -196,6 +205,9 @@ function processWSCommand(ws, metadata, dataBuffer) {
196205
case WS_COMMAND.READ_DIR:
197206
_readDir(ws, metadata);
198207
return;
208+
case WS_COMMAND.STAT:
209+
_stat(ws, metadata);
210+
return;
199211
case WS_COMMAND.LARGE_DATA_SOCKET_ANNOUNCE:
200212
console.log("Large Data Transfer Socket established, socket Group: ", metadata.socketGroupID);
201213
ws.isLargeData = true;

dist/virtualfs.js

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/virtualfs.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/node-src/phoenix-fs.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ const WS_COMMAND = {
8585
LARGE_DATA_SOCKET_ANNOUNCE: "largeDataSock",
8686
CONTROL_SOCKET_ANNOUNCE: "controlSock",
8787
GET_WINDOWS_DRIVES: "getWinDrives",
88-
READ_DIR: "readDir"
88+
READ_DIR: "readDir",
89+
STAT: "stat"
8990
};
9091

9192
const LARGE_DATA_THRESHOLD = 2*1024*1024; // 2MB
@@ -148,21 +149,21 @@ function _getStat(fullPath) {
148149
});
149150
}
150151

152+
function _reportError(ws, metadata, err, defaultMessage = "Operation failed! ") {
153+
metadata.error = {
154+
message: err.message || defaultMessage,
155+
code: err.code || "EIO",
156+
stack: err.stack
157+
};
158+
_sendResponse(ws, metadata);
159+
}
160+
151161
function _readDir(ws, metadata) {
152162
const fullPath = metadata.data.path,
153163
options = metadata.data.options || {};
154164
const withFileTypes = options.withFileTypes;
155165
options.withFileTypes = null;
156166

157-
function _reportError(err) {
158-
metadata.error = {
159-
message: err.message || "Cannot readdir "+ fullPath,
160-
code: err.code || "EIO",
161-
stack: err.stack
162-
};
163-
_sendResponse(ws, metadata);
164-
}
165-
166167
fs.readdir(fullPath, options)
167168
.then(contents=>{
168169
if(withFileTypes){
@@ -174,11 +175,19 @@ function _readDir(ws, metadata) {
174175
.then(contentStats =>{
175176
_sendResponse(ws, metadata, {contentStats});
176177
})
177-
.catch(_reportError);
178+
.catch((err)=>_reportError(ws, metadata, err, `Cannot readdir ${fullPath}`));
178179
} else {
179180
_sendResponse(ws, metadata, {contents});
180181
}
181-
}).catch(_reportError);
182+
}).catch((err)=>_reportError(ws, metadata, err, `Cannot readdir ${fullPath}`));
183+
}
184+
185+
function _stat(ws, metadata) {
186+
const fullPath = metadata.data.path;
187+
_getStat(fullPath)
188+
.then(stat=>{
189+
_sendResponse(ws, metadata, {stat});
190+
}).catch((err)=>_reportError(ws, metadata, err, `Failed to get stat for ${fullPath}`));
182191
}
183192

184193
function processWSCommand(ws, metadata, dataBuffer) {
@@ -196,6 +205,9 @@ function processWSCommand(ws, metadata, dataBuffer) {
196205
case WS_COMMAND.READ_DIR:
197206
_readDir(ws, metadata);
198207
return;
208+
case WS_COMMAND.STAT:
209+
_stat(ws, metadata);
210+
return;
199211
case WS_COMMAND.LARGE_DATA_SOCKET_ANNOUNCE:
200212
console.log("Large Data Transfer Socket established, socket Group: ", metadata.socketGroupID);
201213
ws.isLargeData = true;

src/fslib_node_ws.js

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ const WS_COMMAND = {
3333
LARGE_DATA_SOCKET_ANNOUNCE: "largeDataSock",
3434
CONTROL_SOCKET_ANNOUNCE: "controlSock",
3535
GET_WINDOWS_DRIVES: "getWinDrives",
36-
READ_DIR: "readDir"
36+
READ_DIR: "readDir",
37+
STAT: "stat"
3738
};
3839

3940
// each browser context belongs to a single socket group. So multiple websocket connections can be pooled
@@ -49,18 +50,18 @@ const MAX_RECONNECT_BACKOFF_TIME_MS = 1000;
4950

5051
function mapNodeTauriErrorMessage(nodeError, path, userMessage= '') {
5152
switch (nodeError.code) {
52-
case 'ENOENT': return new Errors.ENOENT(userMessage + ` No such File or Directory: ` + path + nodeError.message, path);
53-
case 'EEXIST': return new Errors.EEXIST(userMessage + ` File exists: ` + path + nodeError.message, path);
54-
case '39': return new Errors.ENOTEMPTY(userMessage + ` Directory not empty: ` + path + nodeError.message, path);
55-
case '20': return new Errors.ENOTDIR(userMessage + ` Not a Directory: ` + path + nodeError.message, path);
56-
case '13': return new Errors.EACCES(userMessage + ` Permission denied: ` + path + nodeError.message, path);
57-
case '21': return new Errors.EISDIR(userMessage + ` Is a directory: ` + path + nodeError.message, path);
58-
case '9': return new Errors.EBADF(userMessage + ` Bad file number: ` + path + nodeError.message, path);
59-
case '30': return new Errors.EROFS(userMessage + ` Read-only file system: ` + path + nodeError.message, path);
60-
case '28': return new Errors.ENOSPC(userMessage + ` No space left on device: ` + path + nodeError.message, path);
61-
case '16': return new Errors.EBUSY(userMessage + ` Device or resource busy: ` + path + nodeError.message, path);
62-
case '22': return new Errors.EINVAL(userMessage + ` Invalid argument: ` + path + nodeError.message, path);
63-
default: return new Errors.EIO(userMessage + ` IO error on path: ` + path + nodeError.message + "\nNode Error stack: " + nodeError.stack, path);
53+
case 'ENOENT': return new Errors.ENOENT(userMessage + ` No such File or Directory: ${path} ` + nodeError.message, path);
54+
case 'EEXIST': return new Errors.EEXIST(userMessage + ` File exists: ${path} ` + nodeError.message, path);
55+
case '39': return new Errors.ENOTEMPTY(userMessage + ` Directory not empty: ${path} ` + nodeError.message, path);
56+
case '20': return new Errors.ENOTDIR(userMessage + ` Not a Directory: ${path} ` + nodeError.message, path);
57+
case '13': return new Errors.EACCES(userMessage + ` Permission denied: ${path} ` + nodeError.message, path);
58+
case '21': return new Errors.EISDIR(userMessage + ` Is a directory: ${path} ` + nodeError.message, path);
59+
case '9': return new Errors.EBADF(userMessage + ` Bad file number: ${path} ` + nodeError.message, path);
60+
case '30': return new Errors.EROFS(userMessage + ` Read-only file system: ${path} ` + nodeError.message, path);
61+
case '28': return new Errors.ENOSPC(userMessage + ` No space left on device: ${path} ` + nodeError.message, path);
62+
case '16': return new Errors.EBUSY(userMessage + ` Device or resource busy: ${path} ` + nodeError.message, path);
63+
case '22': return new Errors.EINVAL(userMessage + ` Invalid argument: ${path} ` + nodeError.message, path);
64+
default: return new Errors.EIO(userMessage + ` IO error on path: ${path} ` + nodeError.message + "\nNode Error stack: " + nodeError.stack, path);
6465
}
6566
}
6667

@@ -333,12 +334,24 @@ function readdir(path, options, callback) {
333334
});
334335
}
335336

337+
function stat(path, callback) {
338+
let platformPath = Utils.getTauriPlatformPath(path);
339+
_execCommand(WS_COMMAND.STAT, {path: platformPath})
340+
.then(({metadata})=>{
341+
callback(null, Utils.createFromNodeStat(`${path}/${metadata.data.stat.name}`,metadata.data.stat));
342+
})
343+
.catch((err)=>{
344+
callback(mapNodeTauriErrorMessage(err, path, 'Failed to get stat: '));
345+
});
346+
}
347+
336348
const NodeTauriFS = {
337349
testNodeWsEndpoint,
338350
setNodeWSEndpoint,
339351
stopNodeWSEndpoint,
340352
getNodeWSEndpoint,
341-
readdir
353+
readdir,
354+
stat
342355
};
343356

344357
module.exports = {

src/fslib_tauri.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -167,20 +167,20 @@ function extractErrorNumber(str) {
167167
function mapOSTauriErrorMessage(tauriErrorMessage, path, userMessage= '') {
168168
let errorNumber = extractErrorNumber(tauriErrorMessage);
169169
switch (errorNumber) {
170-
case '2': return new Errors.ENOENT(userMessage + ` No such File or Directory: ` + path + tauriErrorMessage, path);
171-
case '3': return new Errors.ENOENT(userMessage + ` System cannot find the path specified: ` + path + tauriErrorMessage, path); // windows
172-
case '17': return new Errors.EEXIST(userMessage + ` File exists: ` + path + tauriErrorMessage, path);
173-
case '183': return new Errors.EEXIST(userMessage + ` File exists: ` + path + tauriErrorMessage, path); // windows
174-
case '39': return new Errors.ENOTEMPTY(userMessage + ` Directory not empty: ` + path + tauriErrorMessage, path);
175-
case '20': return new Errors.ENOTDIR(userMessage + ` Not a Directory: ` + path + tauriErrorMessage, path);
176-
case '13': return new Errors.EACCES(userMessage + ` Permission denied: ` + path + tauriErrorMessage, path);
177-
case '21': return new Errors.EISDIR(userMessage + ` Is a directory: ` + path + tauriErrorMessage, path);
178-
case '9': return new Errors.EBADF(userMessage + ` Bad file number: ` + path + tauriErrorMessage, path);
179-
case '30': return new Errors.EROFS(userMessage + ` Read-only file system: ` + path + tauriErrorMessage, path);
180-
case '28': return new Errors.ENOSPC(userMessage + ` No space left on device: ` + path + tauriErrorMessage, path);
181-
case '16': return new Errors.EBUSY(userMessage + ` Device or resource busy: ` + path + tauriErrorMessage, path);
182-
case '22': return new Errors.EINVAL(userMessage + ` Invalid argument: ` + path + tauriErrorMessage, path);
183-
default: return new Errors.EIO(userMessage + ` IO error on path: ` + path + tauriErrorMessage, path);
170+
case '2': return new Errors.ENOENT(userMessage + ` No such File or Directory: ${path} ` + tauriErrorMessage, path);
171+
case '3': return new Errors.ENOENT(userMessage + ` System cannot find the path specified: ${path} ` + tauriErrorMessage, path); // windows
172+
case '17': return new Errors.EEXIST(userMessage + ` File exists: ${path} ` + tauriErrorMessage, path);
173+
case '183': return new Errors.EEXIST(userMessage + ` File exists: ${path} ` + tauriErrorMessage, path); // windows
174+
case '39': return new Errors.ENOTEMPTY(userMessage + ` Directory not empty: ${path} ` + tauriErrorMessage, path);
175+
case '20': return new Errors.ENOTDIR(userMessage + ` Not a Directory: ${path} ` + tauriErrorMessage, path);
176+
case '13': return new Errors.EACCES(userMessage + ` Permission denied: ${path} ` + tauriErrorMessage, path);
177+
case '21': return new Errors.EISDIR(userMessage + ` Is a directory: ${path} ` + tauriErrorMessage, path);
178+
case '9': return new Errors.EBADF(userMessage + ` Bad file number: ${path} ` + tauriErrorMessage, path);
179+
case '30': return new Errors.EROFS(userMessage + ` Read-only file system: ${path} ` + tauriErrorMessage, path);
180+
case '28': return new Errors.ENOSPC(userMessage + ` No space left on device: ${path} ` + tauriErrorMessage, path);
181+
case '16': return new Errors.EBUSY(userMessage + ` Device or resource busy: ${path} ` + tauriErrorMessage, path);
182+
case '22': return new Errors.EINVAL(userMessage + ` Invalid argument: ${path} ` + tauriErrorMessage, path);
183+
default: return new Errors.EIO(userMessage + ` IO error on path: ${path} ` + tauriErrorMessage, path);
184184
}
185185
}
186186

@@ -251,7 +251,7 @@ function readdir(path, options, callback) {
251251
options = {};
252252
}
253253

254-
if(!window.__TAURI__ || preferNodeWs || options.useNodeWSEndpoint) {
254+
if(!window.__TAURI__ || preferNodeWs) {
255255
return NodeTauriFS.readdir(path, options, callback);
256256
}
257257

@@ -365,8 +365,11 @@ function mkdirs(path, mode, recursive, callback) {
365365
*
366366
* @returns {void}
367367
*/
368-
function stat(path, callback) {
368+
function stat(path, callback, options= {}) {
369369
path = globalObject.path.normalize(path);
370+
if(!window.__TAURI__ || preferNodeWs) {
371+
return NodeTauriFS.stat(path, callback, options);
372+
}
370373
_getTauriStat(path)
371374
.then(stat =>{
372375
callback(null, stat);

test/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<title>Mocha Tests distribution</title>
66
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
77
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css"/>
8+
<script src="virtualfs.js"></script>
89
<script>
910
window.addEventListener('keydown', function(event) {
1011
if (event.key === 'F5') {
@@ -82,7 +83,6 @@
8283
mocha.checkLeaks();
8384
</script>
8485

85-
<script src="virtualfs.js"></script>
8686
<script src="testInit.js"></script>
8787
<script src="test-node.browser.js"></script>
8888
<script src="test-dir.browser.js"></script>

test/test-node.browser.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ describe(`node ws fs tests`, function () {
1313
expect(message.port).to.be.a('number');
1414
wssPort = message.port;
1515
wssEndpoint = `ws://localhost:${wssPort}/phoenixFS`;
16-
await fs.setNodeWSEndpoint(wssEndpoint);
1716
});
1817

1918
it(`Node be present and ping pong`, async function () {

0 commit comments

Comments
 (0)