parent
1780f57184
commit
30e3d7f4cd
@ -0,0 +1,2 @@ |
||||
#!/usr/bin/env node |
||||
export {}; |
@ -1,6 +0,0 @@ |
||||
#!/usr/bin/env node |
||||
declare const Router: any; |
||||
declare const servicesList: any; |
||||
declare const program: any; |
||||
declare const killCallBack: Array<Function>; |
||||
declare function kill(): void; |
@ -0,0 +1,8 @@ |
||||
'use strict'; |
||||
module.exports = { |
||||
Router: require('./router'), |
||||
utils: require('./utils'), |
||||
services: { |
||||
sharedFolder: require('./services/sharedFolder') |
||||
} |
||||
}; |
@ -0,0 +1,42 @@ |
||||
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; |
||||
} |
@ -0,0 +1,158 @@ |
||||
"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 utils = require('../utils'); |
||||
var isbinaryfile = require('isbinaryfile'); |
||||
var fs = require('fs-extra'); |
||||
var chokidar = require('chokidar'); |
||||
var plugin_1 = require("@remixproject/plugin"); |
||||
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 = utils.absolutePath(args.path, this.currentSharedFolder); |
||||
cb(null, utils.resolveDirectory(path, 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; |
||||
} |
@ -0,0 +1,20 @@ |
||||
/// <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; |
||||
connection: WS; |
||||
remixdClient: RemixdClient; |
||||
constructor(port: number, opt: { |
||||
[key: string]: string; |
||||
}, remixdClient: RemixdClient); |
||||
start(callback?: Function): void; |
||||
send(data: any): void; |
||||
close(): void; |
||||
} |
@ -0,0 +1,44 @@ |
||||
"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) { |
||||
obj.connection = ws; |
||||
var client = buildWebsocketClient(obj.connection, obj.remixdClient); |
||||
if (callback) |
||||
callback(client); |
||||
}); |
||||
}; |
||||
WebSocket.prototype.send = function (data) { |
||||
this.connection.send(data); |
||||
}; |
||||
WebSocket.prototype.close = function () { |
||||
if (this.connection) { |
||||
this.connection.close(); |
||||
} |
||||
if (this.server) { |
||||
this.server.close(); |
||||
} |
||||
}; |
||||
return WebSocket; |
||||
}()); |
||||
exports.default = WebSocket; |
@ -1,5 +1,5 @@ |
||||
{ |
||||
"watch": ["./src"], |
||||
"watch": ["./src", "./bin"], |
||||
"ext": "ts", |
||||
"exec": "npm run build" |
||||
"exec": "npm run build && npm run start" |
||||
} |
@ -1,24 +0,0 @@ |
||||
declare module '@remixproject/plugin-ws' { |
||||
import { PluginApi, ApiMap, ProfileMap, Api, RemixApi } from '../utils'; |
||||
import { PluginClient, PluginOptions } from '@remixproject/plugin/client'; |
||||
export interface WS { |
||||
send(data: string): void; |
||||
on(type: 'message', cb: (event: WSData) => any): this; |
||||
} |
||||
export interface WSData { |
||||
toString(): string; |
||||
} |
||||
export declare function connectWS(socket: WS, client: PluginClient): void; |
||||
/** |
||||
* Connect the client to the socket |
||||
* @param client A plugin client |
||||
*/ |
||||
export declare function buildWebsocketClient<T extends Api, App extends ApiMap = RemixApi>(socket: WS, client: PluginClient<T, App>): PluginApi<GetApi<typeof client.options.customApi>> & PluginClient<T, App>; |
||||
/** |
||||
* Create a plugin client that listen on socket messages |
||||
* @param options The options for the client |
||||
*/ |
||||
export declare function createWebsocketClient<T extends Api, App extends ApiMap = RemixApi>(socket: WS, options?: Partial<PluginOptions<App>>): PluginApi<GetApi<typeof options.customApi>> & PluginClient<T, App>; |
||||
declare type GetApi<T> = T extends ProfileMap<infer I> ? I : never; |
||||
export {}; |
||||
} |
Loading…
Reference in new issue