parent
71de0912a9
commit
3170920158
@ -1,2 +0,0 @@ |
|||||||
#!/usr/bin/env node |
|
||||||
export {}; |
|
@ -1,42 +0,0 @@ |
|||||||
#!/usr/bin/env node
|
|
||||||
"use strict"; |
|
||||||
Object.defineProperty(exports, "__esModule", { value: true }); |
|
||||||
var websocket_1 = require("../src/websocket"); |
|
||||||
var remixdClient_1 = require("../src/services/remixdClient"); |
|
||||||
var program = require('commander'); |
|
||||||
program |
|
||||||
.usage('-s <shared folder>') |
|
||||||
.description('Provide a two-way connection between the local computer and Remix IDE') |
|
||||||
.option('--remix-ide <url>', 'URL of remix instance allowed to connect to this web sockect connection') |
|
||||||
.option('-s, --shared-folder <path>', 'Folder to share with Remix IDE') |
|
||||||
.option('--read-only', 'Treat shared folder as read-only (experimental)') |
|
||||||
.on('--help', function () { |
|
||||||
console.log('\nExample:\n\n remixd -s ./ --remix-ide http://localhost:8080'); |
|
||||||
}).parse(process.argv); |
|
||||||
var killCallBack = []; |
|
||||||
if (!program.remixIde) { |
|
||||||
console.log('\x1b[31m%s\x1b[0m', '[ERR] URL Remix IDE instance has to be provided.'); |
|
||||||
} |
|
||||||
console.log('\x1b[33m%s\x1b[0m', '[WARN] You may now only use IDE at ' + program.remixIde + ' to connect to that instance'); |
|
||||||
if (program.sharedFolder) { |
|
||||||
console.log('\x1b[33m%s\x1b[0m', '[WARN] Any application that runs on your computer can potentially read from and write to all files in the directory.'); |
|
||||||
console.log('\x1b[33m%s\x1b[0m', '[WARN] Symbolic links are not forwarded to Remix IDE\n'); |
|
||||||
var remixdClient = new remixdClient_1.default(); |
|
||||||
var websocketHandler = new websocket_1.default(65520, { remixIdeUrl: program.remixIde }, remixdClient); |
|
||||||
websocketHandler.start(); |
|
||||||
killCallBack.push(websocketHandler.close); |
|
||||||
} |
|
||||||
// kill
|
|
||||||
function kill() { |
|
||||||
for (var k in killCallBack) { |
|
||||||
try { |
|
||||||
killCallBack[k](); |
|
||||||
} |
|
||||||
catch (e) { |
|
||||||
console.log(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
process.on('SIGINT', kill); // catch ctrl-c
|
|
||||||
process.on('SIGTERM', kill); // catch kill
|
|
||||||
process.on('exit', kill); |
|
@ -1,8 +0,0 @@ |
|||||||
'use strict'; |
|
||||||
module.exports = { |
|
||||||
Router: require('./router'), |
|
||||||
utils: require('./utils'), |
|
||||||
services: { |
|
||||||
sharedFolder: require('./services/sharedFolder') |
|
||||||
} |
|
||||||
}; |
|
@ -1,42 +0,0 @@ |
|||||||
import WebSocket from '../websocket'; |
|
||||||
import { PluginClient } from '@remixproject/plugin'; |
|
||||||
export default class RemixdClient extends PluginClient { |
|
||||||
trackDownStreamUpdate: { |
|
||||||
[key: string]: string; |
|
||||||
}; |
|
||||||
websocket: WebSocket | null; |
|
||||||
currentSharedFolder: string; |
|
||||||
readOnly: boolean; |
|
||||||
setWebSocket(websocket: WebSocket): void; |
|
||||||
sharedFolder(currentSharedFolder: string, readOnly: boolean): void; |
|
||||||
list(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): void; |
|
||||||
resolveDirectory(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): void; |
|
||||||
folderIsReadOnly(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): any; |
|
||||||
get(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): any; |
|
||||||
exists(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): void; |
|
||||||
set(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): any; |
|
||||||
rename(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): any; |
|
||||||
remove(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): any; |
|
||||||
isDirectory(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): void; |
|
||||||
isFile(args: { |
|
||||||
[key: string]: string; |
|
||||||
}, cb: Function): void; |
|
||||||
} |
|
@ -1,157 +0,0 @@ |
|||||||
"use strict"; |
|
||||||
var __extends = (this && this.__extends) || (function () { |
|
||||||
var extendStatics = function (d, b) { |
|
||||||
extendStatics = Object.setPrototypeOf || |
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || |
|
||||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; |
|
||||||
return extendStatics(d, b); |
|
||||||
}; |
|
||||||
return function (d, b) { |
|
||||||
extendStatics(d, b); |
|
||||||
function __() { this.constructor = d; } |
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); |
|
||||||
}; |
|
||||||
})(); |
|
||||||
Object.defineProperty(exports, "__esModule", { value: true }); |
|
||||||
var plugin_1 = require("@remixproject/plugin"); |
|
||||||
var utils = require('../utils'); |
|
||||||
var isbinaryfile = require('isbinaryfile'); |
|
||||||
var fs = require('fs-extra'); |
|
||||||
var RemixdClient = /** @class */ (function (_super) { |
|
||||||
__extends(RemixdClient, _super); |
|
||||||
function RemixdClient() { |
|
||||||
return _super !== null && _super.apply(this, arguments) || this; |
|
||||||
} |
|
||||||
RemixdClient.prototype.setWebSocket = function (websocket) { |
|
||||||
this.websocket = websocket; |
|
||||||
}; |
|
||||||
RemixdClient.prototype.sharedFolder = function (currentSharedFolder, readOnly) { |
|
||||||
this.currentSharedFolder = currentSharedFolder; |
|
||||||
this.readOnly = readOnly; |
|
||||||
}; |
|
||||||
RemixdClient.prototype.list = function (args, cb) { |
|
||||||
try { |
|
||||||
cb(null, utils.walkSync(this.currentSharedFolder, {}, this.currentSharedFolder)); |
|
||||||
} |
|
||||||
catch (e) { |
|
||||||
cb(e.message); |
|
||||||
} |
|
||||||
}; |
|
||||||
RemixdClient.prototype.resolveDirectory = function (args, cb) { |
|
||||||
try { |
|
||||||
var path_1 = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
cb(null, utils.resolveDirectory(path_1, this.currentSharedFolder)); |
|
||||||
} |
|
||||||
catch (e) { |
|
||||||
cb(e.message); |
|
||||||
} |
|
||||||
}; |
|
||||||
RemixdClient.prototype.folderIsReadOnly = function (args, cb) { |
|
||||||
return cb(null, this.readOnly); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.get = function (args, cb) { |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
if (!fs.existsSync(path)) { |
|
||||||
return cb('File not found ' + path); |
|
||||||
} |
|
||||||
if (!isRealPath(path, cb)) |
|
||||||
return; |
|
||||||
isbinaryfile(path, function (error, isBinary) { |
|
||||||
if (error) |
|
||||||
console.log(error); |
|
||||||
if (isBinary) { |
|
||||||
cb(null, { content: '<binary content not displayed>', readonly: true }); |
|
||||||
} |
|
||||||
else { |
|
||||||
fs.readFile(path, 'utf8', function (error, data) { |
|
||||||
if (error) |
|
||||||
console.log(error); |
|
||||||
cb(error, { content: data, readonly: false }); |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.exists = function (args, cb) { |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
cb(null, fs.existsSync(path)); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.set = function (args, cb) { |
|
||||||
if (this.readOnly) |
|
||||||
return cb('Cannot write file: read-only mode selected'); |
|
||||||
var isFolder = args.path.endsWith('/'); |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
if (fs.existsSync(path) && !isRealPath(path, cb)) |
|
||||||
return; |
|
||||||
if (args.content === 'undefined') { // no !!!!!
|
|
||||||
console.log('trying to write "undefined" ! stopping.'); |
|
||||||
return; |
|
||||||
} |
|
||||||
this.trackDownStreamUpdate[path] = path; |
|
||||||
if (isFolder) { |
|
||||||
fs.mkdirp(path).then(function () { return cb(); }).catch(function (e) { return cb(e); }); |
|
||||||
} |
|
||||||
else { |
|
||||||
fs.ensureFile(path).then(function () { |
|
||||||
fs.writeFile(path, args.content, 'utf8', function (error, data) { |
|
||||||
if (error) |
|
||||||
console.log(error); |
|
||||||
cb(error, data); |
|
||||||
}); |
|
||||||
}).catch(function (e) { return cb(e); }); |
|
||||||
} |
|
||||||
}; |
|
||||||
RemixdClient.prototype.rename = function (args, cb) { |
|
||||||
if (this.readOnly) |
|
||||||
return cb('Cannot rename file: read-only mode selected'); |
|
||||||
var oldpath = utils.absolutePath(args.oldPath, this.currentSharedFolder); |
|
||||||
if (!fs.existsSync(oldpath)) { |
|
||||||
return cb('File not found ' + oldpath); |
|
||||||
} |
|
||||||
var newpath = utils.absolutePath(args.newPath, this.currentSharedFolder); |
|
||||||
if (!isRealPath(oldpath, cb)) |
|
||||||
return; |
|
||||||
fs.move(oldpath, newpath, function (error, data) { |
|
||||||
if (error) |
|
||||||
console.log(error); |
|
||||||
cb(error, data); |
|
||||||
}); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.remove = function (args, cb) { |
|
||||||
if (this.readOnly) |
|
||||||
return cb('Cannot remove file: read-only mode selected'); |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
if (!fs.existsSync(path)) { |
|
||||||
return cb('File not found ' + path); |
|
||||||
} |
|
||||||
if (!isRealPath(path, cb)) |
|
||||||
return; |
|
||||||
fs.remove(path, function (error) { |
|
||||||
if (error) { |
|
||||||
console.log(error); |
|
||||||
return cb('Failed to remove file/directory: ' + error); |
|
||||||
} |
|
||||||
cb(error, true); |
|
||||||
}); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.isDirectory = function (args, cb) { |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
cb(null, fs.statSync(path).isDirectory()); |
|
||||||
}; |
|
||||||
RemixdClient.prototype.isFile = function (args, cb) { |
|
||||||
var path = utils.absolutePath(args.path, this.currentSharedFolder); |
|
||||||
cb(null, fs.statSync(path).isFile()); |
|
||||||
}; |
|
||||||
return RemixdClient; |
|
||||||
}(plugin_1.PluginClient)); |
|
||||||
exports.default = RemixdClient; |
|
||||||
function isRealPath(path, cb) { |
|
||||||
var realPath = fs.realpathSync(path); |
|
||||||
var isRealPath = path === realPath; |
|
||||||
var mes = '[WARN] Symbolic link modification not allowed : ' + path + ' | ' + realPath; |
|
||||||
if (!isRealPath) { |
|
||||||
console.log('\x1b[33m%s\x1b[0m', mes); |
|
||||||
} |
|
||||||
if (cb && !isRealPath) |
|
||||||
cb(mes); |
|
||||||
return isRealPath; |
|
||||||
} |
|
@ -1,18 +0,0 @@ |
|||||||
/// <reference types="node" />
|
|
||||||
import * as WS from 'ws'; |
|
||||||
import * as http from 'http'; |
|
||||||
import RemixdClient from './services/remixdClient'; |
|
||||||
export default class WebSocket { |
|
||||||
port: number; |
|
||||||
opt: { |
|
||||||
[key: string]: string; |
|
||||||
}; |
|
||||||
server: http.Server; |
|
||||||
wsServer: WS.Server; |
|
||||||
remixdClient: RemixdClient; |
|
||||||
constructor(port: number, opt: { |
|
||||||
[key: string]: string; |
|
||||||
}, remixdClient: RemixdClient); |
|
||||||
start(callback?: Function): void; |
|
||||||
close(): void; |
|
||||||
} |
|
@ -1,36 +0,0 @@ |
|||||||
"use strict"; |
|
||||||
Object.defineProperty(exports, "__esModule", { value: true }); |
|
||||||
var WS = require("ws"); |
|
||||||
var http = require("http"); |
|
||||||
var buildWebsocketClient = require('@remixproject/plugin-ws').buildWebsocketClient; |
|
||||||
var WebSocket = /** @class */ (function () { |
|
||||||
function WebSocket(port, opt, remixdClient) { |
|
||||||
this.port = port; |
|
||||||
this.opt = opt; |
|
||||||
this.remixdClient = remixdClient; |
|
||||||
} |
|
||||||
WebSocket.prototype.start = function (callback) { |
|
||||||
var obj = this; |
|
||||||
this.server = http.createServer(function (request, response) { |
|
||||||
console.log((new Date()) + ' Received request for ' + request.url); |
|
||||||
response.writeHead(404); |
|
||||||
response.end(); |
|
||||||
}); |
|
||||||
var loopback = '127.0.0.1'; |
|
||||||
this.server.listen(this.port, loopback, function () { |
|
||||||
console.log((new Date()) + ' Remixd is listening on ' + loopback + ':65520'); |
|
||||||
}); |
|
||||||
this.wsServer = new WS.Server({ server: this.server }); |
|
||||||
this.wsServer.on('connection', function connection(ws) { |
|
||||||
var client = buildWebsocketClient(ws, obj.remixdClient); |
|
||||||
if (callback) |
|
||||||
callback(client); |
|
||||||
}); |
|
||||||
}; |
|
||||||
WebSocket.prototype.close = function () { |
|
||||||
console.log('this.server: ', this.server); |
|
||||||
this.server.close(); |
|
||||||
}; |
|
||||||
return WebSocket; |
|
||||||
}()); |
|
||||||
exports.default = WebSocket; |
|
@ -0,0 +1,20 @@ |
|||||||
|
export type WebsocketOpt = { |
||||||
|
remixIdeUrl: string |
||||||
|
} |
||||||
|
|
||||||
|
export type SharedFolderArgs = { |
||||||
|
path: string, |
||||||
|
[key: string]: string | number | boolean |
||||||
|
} |
||||||
|
|
||||||
|
export type KeyPairString = { |
||||||
|
[key: string]: string |
||||||
|
} |
||||||
|
|
||||||
|
export type ResolveDirectory = { |
||||||
|
[key: string]: { |
||||||
|
isDirectory: boolean |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export type TrackDownStreamUpdate = KeyPairString |
Loading…
Reference in new issue