Create initial server layout (#11)
* Create initial server layout * Adjust command name to entry * Add @oclif/config as dependency * Implement build process for outputting single binary * Add init message * Remove unused import, add tsconfig.json to .gitignore * Accidently pushed wacky change to output host FS files * Add options to createApp
This commit is contained in:
parent
2ff34bc5e2
commit
05899b5edf
@ -41,5 +41,9 @@
|
|||||||
"webpack-cli": "^3.2.1",
|
"webpack-cli": "^3.2.1",
|
||||||
"webpack-dev-server": "^3.1.14",
|
"webpack-dev-server": "^3.1.14",
|
||||||
"write-file-webpack-plugin": "^4.5.0"
|
"write-file-webpack-plugin": "^4.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-loader": "^0.6.0",
|
||||||
|
"webpack-merge": "^4.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,8 @@ export abstract class Formatter {
|
|||||||
public abstract push(arg: string, color?: string, weight?: string): void;
|
public abstract push(arg: string, color?: string, weight?: string): void;
|
||||||
public abstract push(arg: any): void; // tslint:disable-line no-any
|
public abstract push(arg: any): void; // tslint:disable-line no-any
|
||||||
|
|
||||||
|
public abstract fields(fields: Array<Field<any>>): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush out the built arguments.
|
* Flush out the built arguments.
|
||||||
*/
|
*/
|
||||||
@ -149,12 +151,12 @@ export abstract class Formatter {
|
|||||||
*/
|
*/
|
||||||
export class BrowserFormatter extends Formatter {
|
export class BrowserFormatter extends Formatter {
|
||||||
|
|
||||||
public tag(name: string, color:string): void {
|
public tag(name: string, color: string): void {
|
||||||
this.format += `%c ${name} `;
|
this.format += `%c ${name} `;
|
||||||
this.args.push(
|
this.args.push(
|
||||||
`border: 1px solid #222; background-color: ${color}; padding-top: 1px;`
|
`border: 1px solid #222; background-color: ${color}; padding-top: 1px;`
|
||||||
+ " padding-bottom: 1px; font-size: 12px; font-weight: bold; color: white;"
|
+ " padding-bottom: 1px; font-size: 12px; font-weight: bold; color: white;"
|
||||||
+ (name.length === 4 ? "padding-left: 3px; padding-right: 4px;" : ""),
|
+ (name.length === 4 ? "padding-left: 3px; padding-right: 4px;" : ""),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +172,20 @@ export class BrowserFormatter extends Formatter {
|
|||||||
this.args.push(arg);
|
this.args.push(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fields(fields: Array<Field<any>>): void {
|
||||||
|
console.groupCollapsed(...this.flush());
|
||||||
|
fields.forEach((field) => {
|
||||||
|
this.push(field.identifier, "#3794ff", "bold");
|
||||||
|
if (typeof field.value !== "undefined" && field.value.constructor && field.value.constructor.name) {
|
||||||
|
this.push(` (${field.value.constructor.name})`);
|
||||||
|
}
|
||||||
|
this.push(": ");
|
||||||
|
this.push(field.value);
|
||||||
|
console.log(...this.flush());
|
||||||
|
});
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,8 +195,11 @@ export class ServerFormatter extends Formatter {
|
|||||||
|
|
||||||
public tag(name: string, color: string): void {
|
public tag(name: string, color: string): void {
|
||||||
const [r, g, b] = hexToRgb(color);
|
const [r, g, b] = hexToRgb(color);
|
||||||
|
while (name.length < 5) {
|
||||||
|
name += " ";
|
||||||
|
}
|
||||||
this.format += "\u001B[1m";
|
this.format += "\u001B[1m";
|
||||||
this.format += `\u001B[48;2;${r};${g};${b}m ${name} \u001B[0m`;
|
this.format += `\u001B[38;2;${r};${g};${b}m ${name} \u001B[0m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public push(arg: any, color?: string, weight?: string): void { // tslint:disable-line no-any
|
public push(arg: any, color?: string, weight?: string): void { // tslint:disable-line no-any
|
||||||
@ -198,6 +217,16 @@ export class ServerFormatter extends Formatter {
|
|||||||
this.args.push(arg);
|
this.args.push(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fields(fields: Array<Field<any>>): void {
|
||||||
|
const obj = {} as any;
|
||||||
|
this.format += "\u001B[38;2;140;140;140m"
|
||||||
|
fields.forEach((field) => {
|
||||||
|
obj[field.identifier] = field.value;
|
||||||
|
});
|
||||||
|
this.args.push(JSON.stringify(obj));
|
||||||
|
console.log(...this.flush());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,7 +279,7 @@ export class Logger {
|
|||||||
type: "warn",
|
type: "warn",
|
||||||
message: msg,
|
message: msg,
|
||||||
fields,
|
fields,
|
||||||
tagColor: "#919E00",
|
tagColor: "#FF9D00",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +354,7 @@ export class Logger {
|
|||||||
this._formatter.push(" ");
|
this._formatter.push(" ");
|
||||||
this._formatter.tag(this.name.toUpperCase(), this.nameColor);
|
this._formatter.tag(this.name.toUpperCase(), this.nameColor);
|
||||||
}
|
}
|
||||||
this._formatter.push(" " + options.message);
|
this._formatter.push(options.message);
|
||||||
if (times.length > 0) {
|
if (times.length > 0) {
|
||||||
times.forEach((time) => {
|
times.forEach((time) => {
|
||||||
const diff = now - time.value.ms;
|
const diff = now - time.value.ms;
|
||||||
@ -341,17 +370,7 @@ export class Logger {
|
|||||||
|
|
||||||
// tslint:disable no-console
|
// tslint:disable no-console
|
||||||
if (hasFields) {
|
if (hasFields) {
|
||||||
console.groupCollapsed(...this._formatter.flush());
|
this._formatter.fields(fields);
|
||||||
fields.forEach((field) => {
|
|
||||||
this._formatter.push(field.identifier, "#3794ff", "bold");
|
|
||||||
if (typeof field.value !== "undefined" && field.value.constructor && field.value.constructor.name) {
|
|
||||||
this._formatter.push(` (${field.value.constructor.name})`);
|
|
||||||
}
|
|
||||||
this._formatter.push(": ");
|
|
||||||
this._formatter.push(field.value);
|
|
||||||
console.log(...this._formatter.flush());
|
|
||||||
});
|
|
||||||
console.groupEnd();
|
|
||||||
} else {
|
} else {
|
||||||
console.log(...this._formatter.flush());
|
console.log(...this._formatter.flush());
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
|
"google-protobuf": "^3.6.1",
|
||||||
"node-pty": "^0.8.0",
|
"node-pty": "^0.8.0",
|
||||||
"ws": "^6.1.2"
|
"ws": "^6.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.16.0",
|
"@types/google-protobuf": "^3.2.7",
|
||||||
"@types/text-encoding": "^0.0.35",
|
"@types/text-encoding": "^0.0.35",
|
||||||
"@types/ws": "^6.0.1",
|
|
||||||
"text-encoding": "^0.7.0",
|
"text-encoding": "^0.7.0",
|
||||||
"ts-protoc-gen": "^0.8.0"
|
"ts-protoc-gen": "^0.8.0"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ReadWriteConnection } from "../common/connection";
|
import { ReadWriteConnection, InitData, OperatingSystem } from "../common/connection";
|
||||||
import { NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, TypedValue, ClientMessage, NewSessionMessage, TTYDimensions, SessionOutputMessage, CloseSessionInputMessage } from "../proto";
|
import { NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, TypedValue, ClientMessage, NewSessionMessage, TTYDimensions, SessionOutputMessage, CloseSessionInputMessage, InitMessage } from "../proto";
|
||||||
import { Emitter } from "@coder/events";
|
import { Emitter, Event } from "@coder/events";
|
||||||
import { logger, field } from "@coder/logger";
|
import { logger, field } from "@coder/logger";
|
||||||
import { ChildProcess, SpawnOptions, ServerProcess } from "./command";
|
import { ChildProcess, SpawnOptions, ServerProcess } from "./command";
|
||||||
|
|
||||||
@ -15,12 +15,17 @@ export class Client {
|
|||||||
private sessionId: number = 0;
|
private sessionId: number = 0;
|
||||||
private sessions: Map<number, ServerProcess> = new Map();
|
private sessions: Map<number, ServerProcess> = new Map();
|
||||||
|
|
||||||
|
private _initData: InitData | undefined;
|
||||||
|
private initDataEmitter: Emitter<InitData> = new Emitter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param connection Established connection to the server
|
* @param connection Established connection to the server
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly connection: ReadWriteConnection,
|
private readonly connection: ReadWriteConnection,
|
||||||
) {
|
) {
|
||||||
|
this.initDataEmitter = new Emitter();
|
||||||
|
|
||||||
connection.onMessage((data) => {
|
connection.onMessage((data) => {
|
||||||
try {
|
try {
|
||||||
this.handleMessage(ServerMessage.deserializeBinary(data));
|
this.handleMessage(ServerMessage.deserializeBinary(data));
|
||||||
@ -30,6 +35,14 @@ export class Client {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get onInitData(): Event<InitData> {
|
||||||
|
return this.initDataEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get initData(): InitData | undefined {
|
||||||
|
return this._initData;
|
||||||
|
}
|
||||||
|
|
||||||
public evaluate<R>(func: () => R | Promise<R>): Promise<R>;
|
public evaluate<R>(func: () => R | Promise<R>): Promise<R>;
|
||||||
public evaluate<R, T1>(func: (a1: T1) => R | Promise<R>, a1: T1): Promise<R>;
|
public evaluate<R, T1>(func: (a1: T1) => R | Promise<R>, a1: T1): Promise<R>;
|
||||||
public evaluate<R, T1, T2>(func: (a1: T1, a2: T2) => R | Promise<R>, a1: T1, a2: T2): Promise<R>;
|
public evaluate<R, T1, T2>(func: (a1: T1, a2: T2) => R | Promise<R>, a1: T1, a2: T2): Promise<R>;
|
||||||
@ -47,7 +60,7 @@ export class Client {
|
|||||||
* console.log(returned);
|
* console.log(returned);
|
||||||
* // output: "hi"
|
* // output: "hi"
|
||||||
* @param func Function to evaluate
|
* @param func Function to evaluate
|
||||||
* @returns {Promise} Promise rejected or resolved from the evaluated function
|
* @returns Promise rejected or resolved from the evaluated function
|
||||||
*/
|
*/
|
||||||
public evaluate<R, T1, T2, T3, T4, T5, T6>(func: (a1?: T1, a2?: T2, a3?: T3, a4?: T4, a5?: T5, a6?: T6) => R | Promise<R>, a1?: T1, a2?: T2, a3?: T3, a4?: T4, a5?: T5, a6?: T6): Promise<R> {
|
public evaluate<R, T1, T2, T3, T4, T5, T6>(func: (a1?: T1, a2?: T2, a3?: T3, a4?: T4, a5?: T5, a6?: T6) => R | Promise<R>, a1?: T1, a2?: T2, a3?: T3, a4?: T4, a5?: T5, a6?: T6): Promise<R> {
|
||||||
const newEval = new NewEvalMessage();
|
const newEval = new NewEvalMessage();
|
||||||
@ -61,8 +74,8 @@ export class Client {
|
|||||||
this.connection.send(clientMsg.serializeBinary());
|
this.connection.send(clientMsg.serializeBinary());
|
||||||
|
|
||||||
let res: (value?: R) => void;
|
let res: (value?: R) => void;
|
||||||
let rej: (err?: any) => void;
|
let rej: (err?: Error) => void;
|
||||||
const prom = new Promise<R>((r, e) => {
|
const prom = new Promise<R>((r, e): void => {
|
||||||
res = r;
|
res = r;
|
||||||
rej = e;
|
rej = e;
|
||||||
});
|
});
|
||||||
@ -80,6 +93,7 @@ export class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rt = resp.getType();
|
const rt = resp.getType();
|
||||||
|
// tslint:disable-next-line
|
||||||
let val: any;
|
let val: any;
|
||||||
switch (rt) {
|
switch (rt) {
|
||||||
case TypedValue.Type.BOOLEAN:
|
case TypedValue.Type.BOOLEAN:
|
||||||
@ -107,7 +121,7 @@ export class Client {
|
|||||||
d1.dispose();
|
d1.dispose();
|
||||||
d2.dispose();
|
d2.dispose();
|
||||||
|
|
||||||
rej(failedMsg.getMessage());
|
rej(new Error(failedMsg.getMessage()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,7 +134,6 @@ export class Client {
|
|||||||
* const cp = this.client.spawn("echo", ["test"]);
|
* const cp = this.client.spawn("echo", ["test"]);
|
||||||
* cp.stdout.on("data", (data) => console.log(data.toString()));
|
* cp.stdout.on("data", (data) => console.log(data.toString()));
|
||||||
* cp.on("exit", (code) => console.log("exited with", code));
|
* cp.on("exit", (code) => console.log("exited with", code));
|
||||||
* @param command
|
|
||||||
* @param args Arguments
|
* @param args Arguments
|
||||||
* @param options Options to execute for the command
|
* @param options Options to execute for the command
|
||||||
*/
|
*/
|
||||||
@ -167,7 +180,6 @@ export class Client {
|
|||||||
|
|
||||||
const serverProc = new ServerProcess(this.connection, id, options ? options.tty !== undefined : false);
|
const serverProc = new ServerProcess(this.connection, id, options ? options.tty !== undefined : false);
|
||||||
serverProc.stdin.on("close", () => {
|
serverProc.stdin.on("close", () => {
|
||||||
console.log("stdin closed");
|
|
||||||
const c = new CloseSessionInputMessage();
|
const c = new CloseSessionInputMessage();
|
||||||
c.setId(id);
|
c.setId(id);
|
||||||
const cm = new ClientMessage();
|
const cm = new ClientMessage();
|
||||||
@ -175,6 +187,7 @@ export class Client {
|
|||||||
this.connection.send(cm.serializeBinary());
|
this.connection.send(cm.serializeBinary());
|
||||||
});
|
});
|
||||||
this.sessions.set(id, serverProc);
|
this.sessions.set(id, serverProc);
|
||||||
|
|
||||||
return serverProc;
|
return serverProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +196,31 @@ export class Client {
|
|||||||
* routed through here.
|
* routed through here.
|
||||||
*/
|
*/
|
||||||
private handleMessage(message: ServerMessage): void {
|
private handleMessage(message: ServerMessage): void {
|
||||||
if (message.hasEvalDone()) {
|
if (message.hasInit()) {
|
||||||
|
const init = message.getInit()!;
|
||||||
|
let opSys: OperatingSystem;
|
||||||
|
switch (init.getOperatingSystem()) {
|
||||||
|
case InitMessage.OperatingSystem.WINDOWS:
|
||||||
|
opSys = OperatingSystem.Windows;
|
||||||
|
break;
|
||||||
|
case InitMessage.OperatingSystem.LINUX:
|
||||||
|
opSys = OperatingSystem.Linux;
|
||||||
|
break;
|
||||||
|
case InitMessage.OperatingSystem.MAC:
|
||||||
|
opSys = OperatingSystem.Mac;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`unsupported operating system ${init.getOperatingSystem()}`);
|
||||||
|
}
|
||||||
|
this._initData = {
|
||||||
|
dataDirectory: init.getDataDirectory(),
|
||||||
|
homeDirectory: init.getHomeDirectory(),
|
||||||
|
tmpDirectory: init.getTmpDirectory(),
|
||||||
|
workingDirectory: init.getWorkingDirectory(),
|
||||||
|
os: opSys,
|
||||||
|
};
|
||||||
|
this.initDataEmitter.emit(this._initData);
|
||||||
|
} else if (message.hasEvalDone()) {
|
||||||
this.evalDoneEmitter.emit(message.getEvalDone()!);
|
this.evalDoneEmitter.emit(message.getEvalDone()!);
|
||||||
} else if (message.hasEvalFailed()) {
|
} else if (message.hasEvalFailed()) {
|
||||||
this.evalFailedEmitter.emit(message.getEvalFailed()!);
|
this.evalFailedEmitter.emit(message.getEvalFailed()!);
|
||||||
|
@ -38,14 +38,18 @@ export class CP {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public fork = (modulePath: string): cp.ChildProcess => {
|
public fork(modulePath: string): cp.ChildProcess {
|
||||||
|
//@ts-ignore
|
||||||
return this.client.fork(modulePath);
|
return this.client.fork(modulePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public spawn = (command: string, args?: ReadonlyArray<string> | cp.SpawnOptions, _options?: cp.SpawnOptions): cp.ChildProcess => {
|
public spawn(command: string, args?: ReadonlyArray<string> | cp.SpawnOptions, _options?: cp.SpawnOptions): cp.ChildProcess {
|
||||||
|
// TODO: fix this ignore. Should check for args or options here
|
||||||
|
//@ts-ignore
|
||||||
return this.client.spawn(command, args, options);
|
return this.client.spawn(command, args, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,3 +7,17 @@ export interface ReadWriteConnection extends SendableConnection {
|
|||||||
onClose(cb: () => void): void;
|
onClose(cb: () => void): void;
|
||||||
close(): void;
|
close(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum OperatingSystem {
|
||||||
|
Windows,
|
||||||
|
Linux,
|
||||||
|
Mac,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InitData {
|
||||||
|
readonly os: OperatingSystem;
|
||||||
|
readonly dataDirectory: string;
|
||||||
|
readonly workingDirectory: string;
|
||||||
|
readonly homeDirectory: string;
|
||||||
|
readonly tmpDirectory: string;
|
||||||
|
}
|
@ -2,6 +2,7 @@ import * as vm from "vm";
|
|||||||
import { NewEvalMessage, TypedValue, EvalFailedMessage, EvalDoneMessage, ServerMessage } from "../proto";
|
import { NewEvalMessage, TypedValue, EvalFailedMessage, EvalDoneMessage, ServerMessage } from "../proto";
|
||||||
import { SendableConnection } from "../common/connection";
|
import { SendableConnection } from "../common/connection";
|
||||||
|
|
||||||
|
declare var __non_webpack_require__: typeof require;
|
||||||
export const evaluate = async (connection: SendableConnection, message: NewEvalMessage): Promise<void> => {
|
export const evaluate = async (connection: SendableConnection, message: NewEvalMessage): Promise<void> => {
|
||||||
const argStr: string[] = [];
|
const argStr: string[] = [];
|
||||||
message.getArgsList().forEach((value) => {
|
message.getArgsList().forEach((value) => {
|
||||||
@ -51,7 +52,7 @@ export const evaluate = async (connection: SendableConnection, message: NewEvalM
|
|||||||
connection.send(serverMsg.serializeBinary());
|
connection.send(serverMsg.serializeBinary());
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const value = vm.runInNewContext(`(${message.getFunction()})(${argStr.join(",")})`, { Buffer, require, setTimeout }, {
|
const value = vm.runInNewContext(`(${message.getFunction()})(${argStr.join(",")})`, { Buffer, require: typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require, setTimeout }, {
|
||||||
timeout: message.getTimeout() || 30000,
|
timeout: message.getTimeout() || 30000,
|
||||||
});
|
});
|
||||||
sendResp(await value);
|
sendResp(await value);
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
import { logger, field } from "@coder/logger";
|
import { logger, field } from "@coder/logger";
|
||||||
|
import * as os from "os";
|
||||||
import { TextDecoder } from "text-encoding";
|
import { TextDecoder } from "text-encoding";
|
||||||
import { ClientMessage } from "../proto";
|
import { ClientMessage, InitMessage, ServerMessage } from "../proto";
|
||||||
import { evaluate } from "./evaluate";
|
import { evaluate } from "./evaluate";
|
||||||
import { ReadWriteConnection } from "../common/connection";
|
import { ReadWriteConnection } from "../common/connection";
|
||||||
import { Process, handleNewSession } from "./command";
|
import { Process, handleNewSession } from "./command";
|
||||||
|
|
||||||
|
export interface ServerOptions {
|
||||||
|
readonly workingDirectory: string;
|
||||||
|
readonly dataDirectory: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class Server {
|
export class Server {
|
||||||
|
|
||||||
private readonly sessions: Map<number, Process>;
|
private readonly sessions: Map<number, Process>;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly connection: ReadWriteConnection,
|
private readonly connection: ReadWriteConnection,
|
||||||
|
options?: ServerOptions,
|
||||||
) {
|
) {
|
||||||
this.sessions = new Map();
|
this.sessions = new Map();
|
||||||
|
|
||||||
@ -21,6 +28,37 @@ export class Server {
|
|||||||
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", ex));
|
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", ex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!options) {
|
||||||
|
logger.warn("No server options provided. InitMessage will not be sent.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initMsg = new InitMessage();
|
||||||
|
initMsg.setDataDirectory(options.dataDirectory);
|
||||||
|
initMsg.setWorkingDirectory(options.workingDirectory);
|
||||||
|
initMsg.setHomeDirectory(os.homedir());
|
||||||
|
initMsg.setTmpDirectory(os.tmpdir());
|
||||||
|
const platform = os.platform();
|
||||||
|
let operatingSystem: InitMessage.OperatingSystem;
|
||||||
|
switch (platform) {
|
||||||
|
case "win32":
|
||||||
|
operatingSystem = InitMessage.OperatingSystem.WINDOWS;
|
||||||
|
break;
|
||||||
|
case "linux":
|
||||||
|
operatingSystem = InitMessage.OperatingSystem.LINUX;
|
||||||
|
break;
|
||||||
|
case "darwin":
|
||||||
|
operatingSystem = InitMessage.OperatingSystem.MAC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`unrecognized platform "${platform}"`);
|
||||||
|
}
|
||||||
|
initMsg.setOperatingSystem(operatingSystem);
|
||||||
|
const srvMsg = new ServerMessage();
|
||||||
|
srvMsg.setInit(initMsg);
|
||||||
|
connection.send(srvMsg.serializeBinary());
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleMessage(message: ClientMessage): void {
|
private handleMessage(message: ClientMessage): void {
|
||||||
|
@ -27,5 +27,20 @@ message ServerMessage {
|
|||||||
// node.proto
|
// node.proto
|
||||||
EvalFailedMessage eval_failed = 5;
|
EvalFailedMessage eval_failed = 5;
|
||||||
EvalDoneMessage eval_done = 6;
|
EvalDoneMessage eval_done = 6;
|
||||||
|
|
||||||
|
InitMessage init = 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message InitMessage {
|
||||||
|
string home_directory = 1;
|
||||||
|
string tmp_directory = 2;
|
||||||
|
string data_directory = 3;
|
||||||
|
string working_directory = 4;
|
||||||
|
enum OperatingSystem {
|
||||||
|
Windows = 0;
|
||||||
|
Linux = 1;
|
||||||
|
Mac = 2;
|
||||||
|
}
|
||||||
|
OperatingSystem operating_system = 5;
|
||||||
|
}
|
49
packages/protocol/src/proto/client_pb.d.ts
vendored
49
packages/protocol/src/proto/client_pb.d.ts
vendored
@ -99,6 +99,11 @@ export class ServerMessage extends jspb.Message {
|
|||||||
getEvalDone(): node_pb.EvalDoneMessage | undefined;
|
getEvalDone(): node_pb.EvalDoneMessage | undefined;
|
||||||
setEvalDone(value?: node_pb.EvalDoneMessage): void;
|
setEvalDone(value?: node_pb.EvalDoneMessage): void;
|
||||||
|
|
||||||
|
hasInit(): boolean;
|
||||||
|
clearInit(): void;
|
||||||
|
getInit(): InitMessage | undefined;
|
||||||
|
setInit(value?: InitMessage): void;
|
||||||
|
|
||||||
getMsgCase(): ServerMessage.MsgCase;
|
getMsgCase(): ServerMessage.MsgCase;
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): ServerMessage.AsObject;
|
toObject(includeInstance?: boolean): ServerMessage.AsObject;
|
||||||
@ -118,6 +123,7 @@ export namespace ServerMessage {
|
|||||||
identifySession?: command_pb.IdentifySessionMessage.AsObject,
|
identifySession?: command_pb.IdentifySessionMessage.AsObject,
|
||||||
evalFailed?: node_pb.EvalFailedMessage.AsObject,
|
evalFailed?: node_pb.EvalFailedMessage.AsObject,
|
||||||
evalDone?: node_pb.EvalDoneMessage.AsObject,
|
evalDone?: node_pb.EvalDoneMessage.AsObject,
|
||||||
|
init?: InitMessage.AsObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MsgCase {
|
export enum MsgCase {
|
||||||
@ -128,6 +134,49 @@ export namespace ServerMessage {
|
|||||||
IDENTIFY_SESSION = 4,
|
IDENTIFY_SESSION = 4,
|
||||||
EVAL_FAILED = 5,
|
EVAL_FAILED = 5,
|
||||||
EVAL_DONE = 6,
|
EVAL_DONE = 6,
|
||||||
|
INIT = 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class InitMessage extends jspb.Message {
|
||||||
|
getHomeDirectory(): string;
|
||||||
|
setHomeDirectory(value: string): void;
|
||||||
|
|
||||||
|
getTmpDirectory(): string;
|
||||||
|
setTmpDirectory(value: string): void;
|
||||||
|
|
||||||
|
getDataDirectory(): string;
|
||||||
|
setDataDirectory(value: string): void;
|
||||||
|
|
||||||
|
getWorkingDirectory(): string;
|
||||||
|
setWorkingDirectory(value: string): void;
|
||||||
|
|
||||||
|
getOperatingSystem(): InitMessage.OperatingSystem;
|
||||||
|
setOperatingSystem(value: InitMessage.OperatingSystem): void;
|
||||||
|
|
||||||
|
serializeBinary(): Uint8Array;
|
||||||
|
toObject(includeInstance?: boolean): InitMessage.AsObject;
|
||||||
|
static toObject(includeInstance: boolean, msg: InitMessage): InitMessage.AsObject;
|
||||||
|
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||||
|
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||||
|
static serializeBinaryToWriter(message: InitMessage, writer: jspb.BinaryWriter): void;
|
||||||
|
static deserializeBinary(bytes: Uint8Array): InitMessage;
|
||||||
|
static deserializeBinaryFromReader(message: InitMessage, reader: jspb.BinaryReader): InitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace InitMessage {
|
||||||
|
export type AsObject = {
|
||||||
|
homeDirectory: string,
|
||||||
|
tmpDirectory: string,
|
||||||
|
dataDirectory: string,
|
||||||
|
workingDirectory: string,
|
||||||
|
operatingSystem: InitMessage.OperatingSystem,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum OperatingSystem {
|
||||||
|
WINDOWS = 0,
|
||||||
|
LINUX = 1,
|
||||||
|
MAC = 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ var global = Function('return this')();
|
|||||||
var command_pb = require('./command_pb.js');
|
var command_pb = require('./command_pb.js');
|
||||||
var node_pb = require('./node_pb.js');
|
var node_pb = require('./node_pb.js');
|
||||||
goog.exportSymbol('proto.ClientMessage', null, global);
|
goog.exportSymbol('proto.ClientMessage', null, global);
|
||||||
|
goog.exportSymbol('proto.InitMessage', null, global);
|
||||||
|
goog.exportSymbol('proto.InitMessage.OperatingSystem', null, global);
|
||||||
goog.exportSymbol('proto.ServerMessage', null, global);
|
goog.exportSymbol('proto.ServerMessage', null, global);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -465,7 +467,7 @@ if (goog.DEBUG && !COMPILED) {
|
|||||||
* @private {!Array<!Array<number>>}
|
* @private {!Array<!Array<number>>}
|
||||||
* @const
|
* @const
|
||||||
*/
|
*/
|
||||||
proto.ServerMessage.oneofGroups_ = [[1,2,3,4,5,6]];
|
proto.ServerMessage.oneofGroups_ = [[1,2,3,4,5,6,7]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
@ -477,7 +479,8 @@ proto.ServerMessage.MsgCase = {
|
|||||||
SESSION_OUTPUT: 3,
|
SESSION_OUTPUT: 3,
|
||||||
IDENTIFY_SESSION: 4,
|
IDENTIFY_SESSION: 4,
|
||||||
EVAL_FAILED: 5,
|
EVAL_FAILED: 5,
|
||||||
EVAL_DONE: 6
|
EVAL_DONE: 6,
|
||||||
|
INIT: 7
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -520,7 +523,8 @@ proto.ServerMessage.toObject = function(includeInstance, msg) {
|
|||||||
sessionOutput: (f = msg.getSessionOutput()) && command_pb.SessionOutputMessage.toObject(includeInstance, f),
|
sessionOutput: (f = msg.getSessionOutput()) && command_pb.SessionOutputMessage.toObject(includeInstance, f),
|
||||||
identifySession: (f = msg.getIdentifySession()) && command_pb.IdentifySessionMessage.toObject(includeInstance, f),
|
identifySession: (f = msg.getIdentifySession()) && command_pb.IdentifySessionMessage.toObject(includeInstance, f),
|
||||||
evalFailed: (f = msg.getEvalFailed()) && node_pb.EvalFailedMessage.toObject(includeInstance, f),
|
evalFailed: (f = msg.getEvalFailed()) && node_pb.EvalFailedMessage.toObject(includeInstance, f),
|
||||||
evalDone: (f = msg.getEvalDone()) && node_pb.EvalDoneMessage.toObject(includeInstance, f)
|
evalDone: (f = msg.getEvalDone()) && node_pb.EvalDoneMessage.toObject(includeInstance, f),
|
||||||
|
init: (f = msg.getInit()) && proto.InitMessage.toObject(includeInstance, f)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeInstance) {
|
if (includeInstance) {
|
||||||
@ -587,6 +591,11 @@ proto.ServerMessage.deserializeBinaryFromReader = function(msg, reader) {
|
|||||||
reader.readMessage(value,node_pb.EvalDoneMessage.deserializeBinaryFromReader);
|
reader.readMessage(value,node_pb.EvalDoneMessage.deserializeBinaryFromReader);
|
||||||
msg.setEvalDone(value);
|
msg.setEvalDone(value);
|
||||||
break;
|
break;
|
||||||
|
case 7:
|
||||||
|
var value = new proto.InitMessage;
|
||||||
|
reader.readMessage(value,proto.InitMessage.deserializeBinaryFromReader);
|
||||||
|
msg.setInit(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
reader.skipField();
|
reader.skipField();
|
||||||
break;
|
break;
|
||||||
@ -673,6 +682,14 @@ proto.ServerMessage.prototype.serializeBinaryToWriter = function (writer) {
|
|||||||
node_pb.EvalDoneMessage.serializeBinaryToWriter
|
node_pb.EvalDoneMessage.serializeBinaryToWriter
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
f = this.getInit();
|
||||||
|
if (f != null) {
|
||||||
|
writer.writeMessage(
|
||||||
|
7,
|
||||||
|
f,
|
||||||
|
proto.InitMessage.serializeBinaryToWriter
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -865,4 +882,310 @@ proto.ServerMessage.prototype.hasEvalDone = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional InitMessage init = 7;
|
||||||
|
* @return {proto.InitMessage}
|
||||||
|
*/
|
||||||
|
proto.ServerMessage.prototype.getInit = function() {
|
||||||
|
return /** @type{proto.InitMessage} */ (
|
||||||
|
jspb.Message.getWrapperField(this, proto.InitMessage, 7));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {proto.InitMessage|undefined} value */
|
||||||
|
proto.ServerMessage.prototype.setInit = function(value) {
|
||||||
|
jspb.Message.setOneofWrapperField(this, 7, proto.ServerMessage.oneofGroups_[0], value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
proto.ServerMessage.prototype.clearInit = function() {
|
||||||
|
this.setInit(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this field is set.
|
||||||
|
* @return{!boolean}
|
||||||
|
*/
|
||||||
|
proto.ServerMessage.prototype.hasInit = function() {
|
||||||
|
return jspb.Message.getField(this, 7) != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated by JsPbCodeGenerator.
|
||||||
|
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||||
|
* server response, or constructed directly in Javascript. The array is used
|
||||||
|
* in place and becomes part of the constructed object. It is not cloned.
|
||||||
|
* If no data is provided, the constructed object will be empty, but still
|
||||||
|
* valid.
|
||||||
|
* @extends {jspb.Message}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
proto.InitMessage = function(opt_data) {
|
||||||
|
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||||
|
};
|
||||||
|
goog.inherits(proto.InitMessage, jspb.Message);
|
||||||
|
if (goog.DEBUG && !COMPILED) {
|
||||||
|
proto.InitMessage.displayName = 'proto.InitMessage';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||||
|
/**
|
||||||
|
* Creates an object representation of this proto suitable for use in Soy templates.
|
||||||
|
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||||
|
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||||
|
* For the list of reserved names please see:
|
||||||
|
* com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
|
||||||
|
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
|
||||||
|
* for transitional soy proto support: http://goto/soy-param-migration
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.toObject = function(opt_includeInstance) {
|
||||||
|
return proto.InitMessage.toObject(opt_includeInstance, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static version of the {@see toObject} method.
|
||||||
|
* @param {boolean|undefined} includeInstance Whether to include the JSPB
|
||||||
|
* instance for transitional soy proto support:
|
||||||
|
* http://goto/soy-param-migration
|
||||||
|
* @param {!proto.InitMessage} msg The msg instance to transform.
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.toObject = function(includeInstance, msg) {
|
||||||
|
var f, obj = {
|
||||||
|
homeDirectory: msg.getHomeDirectory(),
|
||||||
|
tmpDirectory: msg.getTmpDirectory(),
|
||||||
|
dataDirectory: msg.getDataDirectory(),
|
||||||
|
workingDirectory: msg.getWorkingDirectory(),
|
||||||
|
operatingSystem: msg.getOperatingSystem()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (includeInstance) {
|
||||||
|
obj.$jspbMessageInstance = msg;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format).
|
||||||
|
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||||
|
* @return {!proto.InitMessage}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.deserializeBinary = function(bytes) {
|
||||||
|
var reader = new jspb.BinaryReader(bytes);
|
||||||
|
var msg = new proto.InitMessage;
|
||||||
|
return proto.InitMessage.deserializeBinaryFromReader(msg, reader);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes binary data (in protobuf wire format) from the
|
||||||
|
* given reader into the given message object.
|
||||||
|
* @param {!proto.InitMessage} msg The message object to deserialize into.
|
||||||
|
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||||
|
* @return {!proto.InitMessage}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.deserializeBinaryFromReader = function(msg, reader) {
|
||||||
|
while (reader.nextField()) {
|
||||||
|
if (reader.isEndGroup()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var field = reader.getFieldNumber();
|
||||||
|
switch (field) {
|
||||||
|
case 1:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setHomeDirectory(value);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setTmpDirectory(value);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setDataDirectory(value);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setWorkingDirectory(value);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
var value = /** @type {!proto.InitMessage.OperatingSystem} */ (reader.readEnum());
|
||||||
|
msg.setOperatingSystem(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.skipField();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class method variant: serializes the given message to binary data
|
||||||
|
* (in protobuf wire format), writing to the given BinaryWriter.
|
||||||
|
* @param {!proto.InitMessage} message
|
||||||
|
* @param {!jspb.BinaryWriter} writer
|
||||||
|
*/
|
||||||
|
proto.InitMessage.serializeBinaryToWriter = function(message, writer) {
|
||||||
|
message.serializeBinaryToWriter(writer);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message to binary data (in protobuf wire format).
|
||||||
|
* @return {!Uint8Array}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.serializeBinary = function() {
|
||||||
|
var writer = new jspb.BinaryWriter();
|
||||||
|
this.serializeBinaryToWriter(writer);
|
||||||
|
return writer.getResultBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes the message to binary data (in protobuf wire format),
|
||||||
|
* writing to the given BinaryWriter.
|
||||||
|
* @param {!jspb.BinaryWriter} writer
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.serializeBinaryToWriter = function (writer) {
|
||||||
|
var f = undefined;
|
||||||
|
f = this.getHomeDirectory();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
1,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = this.getTmpDirectory();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
2,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = this.getDataDirectory();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
3,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = this.getWorkingDirectory();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
4,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f = this.getOperatingSystem();
|
||||||
|
if (f !== 0.0) {
|
||||||
|
writer.writeEnum(
|
||||||
|
5,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a deep clone of this proto. No data is shared with the original.
|
||||||
|
* @return {!proto.InitMessage} The clone.
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.cloneMessage = function() {
|
||||||
|
return /** @type {!proto.InitMessage} */ (jspb.Message.cloneMessage(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string home_directory = 1;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.getHomeDirectory = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
proto.InitMessage.prototype.setHomeDirectory = function(value) {
|
||||||
|
jspb.Message.setField(this, 1, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string tmp_directory = 2;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.getTmpDirectory = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
proto.InitMessage.prototype.setTmpDirectory = function(value) {
|
||||||
|
jspb.Message.setField(this, 2, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string data_directory = 3;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.getDataDirectory = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 3, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
proto.InitMessage.prototype.setDataDirectory = function(value) {
|
||||||
|
jspb.Message.setField(this, 3, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string working_directory = 4;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.getWorkingDirectory = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 4, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
proto.InitMessage.prototype.setWorkingDirectory = function(value) {
|
||||||
|
jspb.Message.setField(this, 4, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional OperatingSystem operating_system = 5;
|
||||||
|
* @return {!proto.InitMessage.OperatingSystem}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.prototype.getOperatingSystem = function() {
|
||||||
|
return /** @type {!proto.InitMessage.OperatingSystem} */ (jspb.Message.getFieldProto3(this, 5, 0));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {!proto.InitMessage.OperatingSystem} value */
|
||||||
|
proto.InitMessage.prototype.setOperatingSystem = function(value) {
|
||||||
|
jspb.Message.setField(this, 5, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
proto.InitMessage.OperatingSystem = {
|
||||||
|
WINDOWS: 0,
|
||||||
|
LINUX: 1,
|
||||||
|
MAC: 2
|
||||||
|
};
|
||||||
|
|
||||||
goog.object.extend(exports, proto);
|
goog.object.extend(exports, proto);
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Emitter } from "@coder/events";
|
import { Emitter } from "@coder/events";
|
||||||
import { Client } from "../src/browser/client";
|
import { Client } from "../src/browser/client";
|
||||||
import { Server } from "../src/node/server";
|
import { Server, ServerOptions } from "../src/node/server";
|
||||||
|
|
||||||
export const createClient = (): Client => {
|
export const createClient = (serverOptions?: ServerOptions): Client => {
|
||||||
const s2c = new Emitter<Uint8Array | Buffer>();
|
const s2c = new Emitter<Uint8Array | Buffer>();
|
||||||
const c2s = new Emitter<Uint8Array | Buffer>();
|
const c2s = new Emitter<Uint8Array | Buffer>();
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
new Server({
|
new Server({
|
||||||
close: () => undefined,
|
close: (): void => undefined,
|
||||||
onClose: () => undefined,
|
onClose: (): void => undefined,
|
||||||
onMessage: (cb) => {
|
onMessage: (cb): void => {
|
||||||
c2s.event((d) => cb(d));
|
c2s.event((d) => cb(d));
|
||||||
},
|
},
|
||||||
send: (data) => setTimeout(() => s2c.emit(data), 0),
|
send: (data): NodeJS.Timer => setTimeout(() => s2c.emit(data), 0),
|
||||||
});
|
}, serverOptions);
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
close: () => undefined,
|
close: (): void => undefined,
|
||||||
onClose: () => undefined,
|
onClose: (): void => undefined,
|
||||||
onMessage: (cb) => {
|
onMessage: (cb): void => {
|
||||||
s2c.event((d) => cb(d));
|
s2c.event((d) => cb(d));
|
||||||
},
|
},
|
||||||
send: (data) => setTimeout(() => c2s.emit(data), 0),
|
send: (data): NodeJS.Timer => setTimeout(() => c2s.emit(data), 0),
|
||||||
});
|
});
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
18
packages/protocol/test/server.test.ts
Normal file
18
packages/protocol/test/server.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { createClient } from "./helpers";
|
||||||
|
|
||||||
|
describe("Server", () => {
|
||||||
|
const dataDirectory = "/tmp/example";
|
||||||
|
const workingDirectory = "/working/dir";
|
||||||
|
const client = createClient({
|
||||||
|
dataDirectory,
|
||||||
|
workingDirectory,
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should get init msg", (done) => {
|
||||||
|
client.onInitData((data) => {
|
||||||
|
expect(data.dataDirectory).toEqual(dataDirectory);
|
||||||
|
expect(data.workingDirectory).toEqual(workingDirectory);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -2,80 +2,16 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@types/body-parser@*":
|
"@types/google-protobuf@^3.2.7":
|
||||||
version "1.17.0"
|
version "3.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c"
|
resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.2.7.tgz#9576ed5dd62cdb1c9f952522028a03b7cb2b69b5"
|
||||||
integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==
|
integrity sha512-Pb9wl5qDEwfnJeeu6Zpn5Y+waLrKETStqLZXHMGCTbkNuBBudPy4qOGN6veamyeoUBwTm2knOVeP/FlHHhhmzA==
|
||||||
dependencies:
|
|
||||||
"@types/connect" "*"
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/connect@*":
|
|
||||||
version "3.4.32"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28"
|
|
||||||
integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/events@*":
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
|
|
||||||
integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==
|
|
||||||
|
|
||||||
"@types/express-serve-static-core@*":
|
|
||||||
version "4.16.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz#fdfe777594ddc1fe8eb8eccce52e261b496e43e7"
|
|
||||||
integrity sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==
|
|
||||||
dependencies:
|
|
||||||
"@types/events" "*"
|
|
||||||
"@types/node" "*"
|
|
||||||
"@types/range-parser" "*"
|
|
||||||
|
|
||||||
"@types/express@^4.16.0":
|
|
||||||
version "4.16.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.0.tgz#6d8bc42ccaa6f35cf29a2b7c3333cb47b5a32a19"
|
|
||||||
integrity sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==
|
|
||||||
dependencies:
|
|
||||||
"@types/body-parser" "*"
|
|
||||||
"@types/express-serve-static-core" "*"
|
|
||||||
"@types/serve-static" "*"
|
|
||||||
|
|
||||||
"@types/mime@*":
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b"
|
|
||||||
integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==
|
|
||||||
|
|
||||||
"@types/node@*":
|
|
||||||
version "10.12.18"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
|
|
||||||
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
|
|
||||||
|
|
||||||
"@types/range-parser@*":
|
|
||||||
version "1.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
|
||||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
|
||||||
|
|
||||||
"@types/serve-static@*":
|
|
||||||
version "1.13.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48"
|
|
||||||
integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==
|
|
||||||
dependencies:
|
|
||||||
"@types/express-serve-static-core" "*"
|
|
||||||
"@types/mime" "*"
|
|
||||||
|
|
||||||
"@types/text-encoding@^0.0.35":
|
"@types/text-encoding@^0.0.35":
|
||||||
version "0.0.35"
|
version "0.0.35"
|
||||||
resolved "https://registry.yarnpkg.com/@types/text-encoding/-/text-encoding-0.0.35.tgz#6f14474e0b232bc70c59677aadc65dcc5a99c3a9"
|
resolved "https://registry.yarnpkg.com/@types/text-encoding/-/text-encoding-0.0.35.tgz#6f14474e0b232bc70c59677aadc65dcc5a99c3a9"
|
||||||
integrity sha512-jfo/A88XIiAweUa8np+1mPbm3h2w0s425YrI8t3wk5QxhH6UI7w517MboNVnGDeMSuoFwA8Rwmklno+FicvV4g==
|
integrity sha512-jfo/A88XIiAweUa8np+1mPbm3h2w0s425YrI8t3wk5QxhH6UI7w517MboNVnGDeMSuoFwA8Rwmklno+FicvV4g==
|
||||||
|
|
||||||
"@types/ws@^6.0.1":
|
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28"
|
|
||||||
integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q==
|
|
||||||
dependencies:
|
|
||||||
"@types/events" "*"
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
accepts@~1.3.5:
|
accepts@~1.3.5:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
|
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
|
||||||
|
6
packages/server/.gitignore
vendored
Normal file
6
packages/server/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
out
|
||||||
|
cli*
|
||||||
|
|
||||||
|
# This file is generated when the binary is created.
|
||||||
|
# We want to use the parent tsconfig so we can ignore it.
|
||||||
|
tsconfig.json
|
28
packages/server/package.json
Normal file
28
packages/server/package.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"main": "./out/cli.js",
|
||||||
|
"bin": "./out/cli.js",
|
||||||
|
"files": [],
|
||||||
|
"scripts": {
|
||||||
|
"start": "ts-node -r tsconfig-paths/register src/cli.ts",
|
||||||
|
"build:webpack": "rm -rf ./out && ../../node_modules/.bin/webpack --config ./webpack.config.js",
|
||||||
|
"build:nexe": "node scripts/nexe.js",
|
||||||
|
"build": "npm run build:webpack && npm run build:nexe"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@oclif/config": "^1.10.4",
|
||||||
|
"@oclif/errors": "^1.2.2",
|
||||||
|
"@oclif/plugin-help": "^2.1.4",
|
||||||
|
"express": "^4.16.4",
|
||||||
|
"nexe": "^2.0.0-rc.34",
|
||||||
|
"node-pty": "^0.8.0",
|
||||||
|
"ws": "^6.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/express": "^4.16.0",
|
||||||
|
"@types/ws": "^6.0.1",
|
||||||
|
"string-replace-webpack-plugin": "^0.1.3",
|
||||||
|
"ts-node": "^7.0.1",
|
||||||
|
"tsconfig-paths": "^3.7.0"
|
||||||
|
}
|
||||||
|
}
|
46
packages/server/scripts/nexe.js
Normal file
46
packages/server/scripts/nexe.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const os = require("os");
|
||||||
|
const path = require("path");
|
||||||
|
const nexe = require("nexe");
|
||||||
|
|
||||||
|
const nexeRoot = path.join(os.homedir(), ".nexe");
|
||||||
|
if (!fs.existsSync(nexeRoot)) {
|
||||||
|
throw new Error("run nexe manually on a binary to initialize it");
|
||||||
|
}
|
||||||
|
const listed = fs.readdirSync(nexeRoot);
|
||||||
|
listed.forEach((list) => {
|
||||||
|
if (list.startsWith("linux")) {
|
||||||
|
const stat = fs.statSync(path.join(nexeRoot, list));
|
||||||
|
if (stat.isFile()) {
|
||||||
|
if (stat.size > 20000000) {
|
||||||
|
throw new Error("must use upx to shrink node binary in ~/.nexe/" + list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
nexe.compile({
|
||||||
|
debugBundle: true,
|
||||||
|
input: path.join(__dirname, "../out/cli.js"),
|
||||||
|
output: 'cli',
|
||||||
|
native: {
|
||||||
|
"node-pty": {
|
||||||
|
additionalFiles: [
|
||||||
|
'./node_modules/node-pty/build/Release/pty',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
targets: ["linux"],
|
||||||
|
/**
|
||||||
|
* To include native extensions, do NOT install node_modules for each one. They
|
||||||
|
* are not required as each extension is built using webpack.
|
||||||
|
*/
|
||||||
|
resources: [path.join(__dirname, "../package.json")],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notes for tmrw
|
||||||
|
*
|
||||||
|
* `upx ~/.nexe/linux` <- node binary before compiling with nexe
|
||||||
|
* Use `testing.js` for bundling with nexe to build
|
||||||
|
*/
|
81
packages/server/src/cli.ts
Normal file
81
packages/server/src/cli.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { Command, flags } from "@oclif/command";
|
||||||
|
import { logger, field } from "@coder/logger";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import * as os from "os";
|
||||||
|
import * as path from "path";
|
||||||
|
import { createApp } from './server';
|
||||||
|
|
||||||
|
export class Entry extends Command {
|
||||||
|
|
||||||
|
public static description = "Start your own self-hosted browser-accessible VS Code";
|
||||||
|
public static flags = {
|
||||||
|
cert: flags.string(),
|
||||||
|
"cert-key": flags.string(),
|
||||||
|
"data-dir": flags.string({ char: "d" }),
|
||||||
|
help: flags.help(),
|
||||||
|
host: flags.string({ char: "h", default: "0.0.0.0" }),
|
||||||
|
open: flags.boolean({ char: "o", description: "Open in browser on startup" }),
|
||||||
|
port: flags.integer({ char: "p", default: 8080, description: "Port to bind on" }),
|
||||||
|
version: flags.version({ char: "v" }),
|
||||||
|
};
|
||||||
|
public static args = [{
|
||||||
|
name: "workdir",
|
||||||
|
description: "Specify working dir",
|
||||||
|
default: () => process.cwd(),
|
||||||
|
}];
|
||||||
|
|
||||||
|
public async run(): Promise<void> {
|
||||||
|
const { args, flags } = this.parse(Entry);
|
||||||
|
|
||||||
|
const dataDir = flags["data-dir"] || path.join(os.homedir(), `.vscode-online`);
|
||||||
|
const workingDir = args["workdir"];
|
||||||
|
|
||||||
|
logger.info("\u001B[1mvscode-remote v1.0.0");
|
||||||
|
// TODO: fill in appropriate doc url
|
||||||
|
logger.info("Additional documentation: https://coder.com/docs");
|
||||||
|
logger.info("Initializing", field("data-dir", dataDir), field("working-dir", workingDir));
|
||||||
|
|
||||||
|
const app = createApp((app) => {
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.on("finish", () => {
|
||||||
|
logger.info(`\u001B[1m${req.method} ${res.statusCode} \u001B[0m${req.url}`, field("host", req.hostname), field("ip", req.ip));
|
||||||
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
dataDirectory: dataDir,
|
||||||
|
workingDirectory: workingDir,
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info("Starting webserver...", field("host", flags.host), field("port", flags.port))
|
||||||
|
app.server.listen(flags.port, flags.host);
|
||||||
|
let clientId = 1;
|
||||||
|
app.wss.on("connection", (ws, req) => {
|
||||||
|
const id = clientId++;
|
||||||
|
logger.info(`WebSocket opened \u001B[0m${req.url}`, field("client", id), field("ip", req.socket.remoteAddress));
|
||||||
|
|
||||||
|
ws.on("close", (code) => {
|
||||||
|
logger.info(`WebSocket closed \u001B[0m${req.url}`, field("client", id), field("code", code));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!flags["cert-key"] && !flags.cert) {
|
||||||
|
logger.warn("No certificate specified. \u001B[1mThis could be insecure.");
|
||||||
|
// TODO: fill in appropriate doc url
|
||||||
|
logger.warn("Documentation on securing your setup: https://coder.com/docs");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(" ");
|
||||||
|
logger.info("Password:\u001B[1m 023450wf09");
|
||||||
|
logger.info(" ");
|
||||||
|
logger.info("Started (click the link below to open):");
|
||||||
|
logger.info(`http://localhost:${flags.port}/`);
|
||||||
|
logger.info(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry.run(undefined, {
|
||||||
|
root: process.env.BUILD_DIR as string,
|
||||||
|
//@ts-ignore
|
||||||
|
}).catch(require("@oclif/errors/handle"));
|
46
packages/server/src/server.ts
Normal file
46
packages/server/src/server.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { ReadWriteConnection } from "@coder/protocol";
|
||||||
|
import { Server, ServerOptions } from "@coder/protocol/src/node/server";
|
||||||
|
import * as express from "express";
|
||||||
|
import * as http from "http";
|
||||||
|
import * as ws from "ws";
|
||||||
|
|
||||||
|
export const createApp = (registerMiddleware?: (app: express.Application) => void, options?: ServerOptions): {
|
||||||
|
readonly express: express.Application;
|
||||||
|
readonly server: http.Server;
|
||||||
|
readonly wss: ws.Server;
|
||||||
|
} => {
|
||||||
|
const app = express();
|
||||||
|
if (registerMiddleware) {
|
||||||
|
registerMiddleware(app);
|
||||||
|
}
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const wss = new ws.Server({ server });
|
||||||
|
|
||||||
|
wss.on("connection", (ws: WebSocket) => {
|
||||||
|
const connection: ReadWriteConnection = {
|
||||||
|
onMessage: (cb) => {
|
||||||
|
ws.addEventListener("message", (event) => cb(event.data));
|
||||||
|
},
|
||||||
|
close: () => ws.close(),
|
||||||
|
send: (data) => ws.send(data),
|
||||||
|
onClose: (cb) => ws.addEventListener("close", () => cb()),
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = new Server(connection, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We should static-serve the `web` package at this point
|
||||||
|
*/
|
||||||
|
app.get("/", (req, res, next) => {
|
||||||
|
res.write("Example! :)");
|
||||||
|
res.status(200);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
express: app,
|
||||||
|
server,
|
||||||
|
wss,
|
||||||
|
};
|
||||||
|
};
|
48
packages/server/webpack.config.js
Normal file
48
packages/server/webpack.config.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const webpack = require("webpack");
|
||||||
|
const merge = require("webpack-merge");
|
||||||
|
const StringReplacePlugin = require("string-replace-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = merge({
|
||||||
|
devtool: 'none',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /@oclif\/command\/lib\/index\.js/,
|
||||||
|
loader: StringReplacePlugin.replace({
|
||||||
|
replacements: [
|
||||||
|
{
|
||||||
|
// This is required otherwise it attempts to require("package.json")
|
||||||
|
pattern: /checkNodeVersion\(\)\;/,
|
||||||
|
replacement: () => / /,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: "cli.js",
|
||||||
|
path: path.join(__dirname, "./out"),
|
||||||
|
libraryTarget: "commonjs",
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
console: false,
|
||||||
|
global: false,
|
||||||
|
process: false,
|
||||||
|
Buffer: false,
|
||||||
|
__filename: false,
|
||||||
|
__dirname: false,
|
||||||
|
setImmediate: false
|
||||||
|
},
|
||||||
|
externals: ["node-pty"],
|
||||||
|
entry: "./packages/server/src/cli.ts",
|
||||||
|
target: "node",
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
"process.env.BUILD_DIR": `"${__dirname}"`,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}, require("../../scripts/webpack.general.config"), {
|
||||||
|
mode: "development",
|
||||||
|
});
|
3694
packages/server/yarn.lock
Normal file
3694
packages/server/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@ function getNotificationService(): INotificationService {
|
|||||||
return workbench.workbenchParams.serviceCollection.get(INotificationService) as INotificationService;
|
return workbench.workbenchParams.serviceCollection.get(INotificationService) as INotificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialize = async (client: Client): Promise<void> {
|
export const initialize = async (client: Client): Promise<void> => {
|
||||||
window.addEventListener("contextmenu", (event) => {
|
window.addEventListener("contextmenu", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
104
scripts/webpack.general.config.js
Normal file
104
scripts/webpack.general.config.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const environment = process.env.NODE_ENV || "development";
|
||||||
|
const isCi = typeof process.env.CI !== "undefined";
|
||||||
|
const HappyPack = require("happypack");
|
||||||
|
const webpack = require("webpack");
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
|
||||||
|
const root = path.join(__dirname, "..");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
context: root,
|
||||||
|
devtool: "source-map",
|
||||||
|
// entry: "./packages/app/src/index.ts",
|
||||||
|
mode: isCi ? "production" : "development",
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: /\.(js)/,
|
||||||
|
exclude: /test/,
|
||||||
|
}, {
|
||||||
|
test: /\.(txt|d\.ts|test.ts|perf.data.js|jxs)/,
|
||||||
|
use: [{
|
||||||
|
loader: "ignore-loader",
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
test: /\.node$/,
|
||||||
|
use: "node-loader",
|
||||||
|
}, {
|
||||||
|
use: [{
|
||||||
|
loader: "happypack/loader?id=ts",
|
||||||
|
}],
|
||||||
|
test: /(^.?|\.[^d]|[^.]d|[^.][^d])\.tsx?$/,
|
||||||
|
}, {
|
||||||
|
exclude: /test/,
|
||||||
|
test: /\.s?css$/,
|
||||||
|
// This is required otherwise it'll fail to resolve CSS in common.
|
||||||
|
include: root,
|
||||||
|
use: [{
|
||||||
|
loader: MiniCssExtractPlugin.loader,
|
||||||
|
}, {
|
||||||
|
loader: "css-loader",
|
||||||
|
}, {
|
||||||
|
loader: "sass-loader",
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
test: /\.(svg|png|ttf|woff|eot)$/,
|
||||||
|
use: [{
|
||||||
|
loader: "file-loader",
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
test: /\.wasm$/,
|
||||||
|
type: "javascript/auto",
|
||||||
|
}],
|
||||||
|
noParse: /\.test\.(j|t)sx?/,
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@coder": path.join(root, "packages"),
|
||||||
|
},
|
||||||
|
extensions: [".js", ".jsx", ".ts", ".tsx", ".json", ".css"],
|
||||||
|
mainFiles: [
|
||||||
|
"index",
|
||||||
|
"src/index",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolveLoader: {
|
||||||
|
modules: [
|
||||||
|
path.join(root, "node_modules"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
hot: true,
|
||||||
|
port: 3000,
|
||||||
|
stats: {
|
||||||
|
all: false, // Fallback for options not defined.
|
||||||
|
errors: true,
|
||||||
|
warnings: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HappyPack({
|
||||||
|
id: "ts",
|
||||||
|
threads: 2,
|
||||||
|
loaders: [{
|
||||||
|
path: "ts-loader",
|
||||||
|
query: {
|
||||||
|
happyPackMode: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
"process.env.NODE_ENV": `"${environment}"`,
|
||||||
|
}),
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "[name].css",
|
||||||
|
chunkFilename: "[id].css",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
// target: "web",
|
||||||
|
stats: {
|
||||||
|
all: false, // Fallback for options not defined.
|
||||||
|
errors: true,
|
||||||
|
warnings: true,
|
||||||
|
},
|
||||||
|
};
|
@ -1,71 +1,22 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const environment = process.env.NODE_ENV || "development";
|
|
||||||
const isCi = typeof process.env.CI !== "undefined";
|
|
||||||
const minify = isCi;
|
|
||||||
const compatibility = isCi;
|
|
||||||
|
|
||||||
const HappyPack = require("happypack");
|
|
||||||
const webpack = require("webpack");
|
|
||||||
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
|
|
||||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||||
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
|
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
|
||||||
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
|
|
||||||
const WriteFilePlugin = require("write-file-webpack-plugin");
|
const WriteFilePlugin = require("write-file-webpack-plugin");
|
||||||
const PreloadWebpackPlugin = require("preload-webpack-plugin");
|
const PreloadWebpackPlugin = require("preload-webpack-plugin");
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
||||||
|
|
||||||
const root = __dirname;
|
const root = __dirname;
|
||||||
const fills = path.join(root, "packages", "ide", "src", "fill");
|
const fills = path.join(root, "packages", "ide", "src", "fill");
|
||||||
const vscodeFills = path.join(root, "packages", "vscode", "src", "fill");
|
const vscodeFills = path.join(root, "packages", "vscode", "src", "fill");
|
||||||
|
|
||||||
module.exports = {
|
const merge = require("webpack-merge");
|
||||||
context: root,
|
|
||||||
|
module.exports = merge({
|
||||||
devtool: "eval",
|
devtool: "eval",
|
||||||
entry: "./packages/web/src/index.ts",
|
entry: "./packages/web/src/index.ts",
|
||||||
mode: isCi ? "production" : "development",
|
|
||||||
output: {
|
output: {
|
||||||
chunkFilename: "[name]-[hash:6].bundle.js",
|
chunkFilename: "[name]-[hash:6].bundle.js",
|
||||||
path: path.join(root, "dist"),
|
path: path.join(root, "dist"),
|
||||||
filename: "[hash:6].bundle.js",
|
filename: "[hash:6].bundle.js",
|
||||||
},
|
},
|
||||||
module: {
|
|
||||||
rules: [{
|
|
||||||
test: /\.(js)/,
|
|
||||||
exclude: /test/,
|
|
||||||
}, {
|
|
||||||
test: /\.(node|txt|d\.ts|test.ts|perf.data.js|jxs)/,
|
|
||||||
use: [{
|
|
||||||
loader: "ignore-loader",
|
|
||||||
}],
|
|
||||||
}, {
|
|
||||||
use: [{
|
|
||||||
loader: "happypack/loader?id=ts",
|
|
||||||
}],
|
|
||||||
test: /(^.?|\.[^d]|[^.]d|[^.][^d])\.tsx?$/,
|
|
||||||
}, {
|
|
||||||
exclude: /test/,
|
|
||||||
test: /\.s?css$/,
|
|
||||||
// This is required otherwise it'll fail to resolve CSS in common.
|
|
||||||
include: root,
|
|
||||||
use: [{
|
|
||||||
loader: MiniCssExtractPlugin.loader,
|
|
||||||
}, {
|
|
||||||
loader: "css-loader",
|
|
||||||
}, {
|
|
||||||
loader: "sass-loader",
|
|
||||||
}],
|
|
||||||
}, {
|
|
||||||
test: /\.(svg|png|ttf|woff|eot)$/,
|
|
||||||
use: [{
|
|
||||||
loader: "file-loader",
|
|
||||||
}],
|
|
||||||
}, {
|
|
||||||
test: /\.wasm$/,
|
|
||||||
type: "javascript/auto",
|
|
||||||
}],
|
|
||||||
noParse: /\.test\.(j|t)sx?/,
|
|
||||||
},
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"native-keymap": path.join(vscodeFills, "native-keymap.ts"),
|
"native-keymap": path.join(vscodeFills, "native-keymap.ts"),
|
||||||
@ -91,76 +42,25 @@ module.exports = {
|
|||||||
|
|
||||||
"electron": path.join(fills, "electron.ts"),
|
"electron": path.join(fills, "electron.ts"),
|
||||||
|
|
||||||
"@coder": path.join(root, "packages"),
|
|
||||||
"vs": path.join(root, "lib", "vscode", "src", "vs"),
|
"vs": path.join(root, "lib", "vscode", "src", "vs"),
|
||||||
},
|
},
|
||||||
extensions: [".js", ".jsx", ".ts", ".tsx", ".json", ".css"],
|
|
||||||
mainFiles: [
|
|
||||||
"index",
|
|
||||||
"src/index",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
resolveLoader: {
|
resolveLoader: {
|
||||||
alias: {
|
alias: {
|
||||||
"vs/css": path.join(vscodeFills, "css.js"),
|
"vs/css": path.join(vscodeFills, "css.js"),
|
||||||
},
|
},
|
||||||
modules: [
|
|
||||||
path.join(root, "node_modules"),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
devServer: {
|
|
||||||
hot: true,
|
|
||||||
port: 3000,
|
|
||||||
disableHostCheck: true,
|
|
||||||
stats: {
|
|
||||||
all: false, // Fallback for options not defined.
|
|
||||||
errors: true,
|
|
||||||
warnings: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: "packages/web/src/index.html",
|
template: "packages/web/src/index.html",
|
||||||
}),
|
}),
|
||||||
new HappyPack({
|
|
||||||
id: "ts",
|
|
||||||
threads: 2,
|
|
||||||
loaders: [{
|
|
||||||
path: "ts-loader",
|
|
||||||
query: {
|
|
||||||
happyPackMode: true,
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
}),
|
|
||||||
// new BundleAnalyzerPlugin(),
|
|
||||||
new WriteFilePlugin({
|
|
||||||
exitOnErrors: false,
|
|
||||||
}),
|
|
||||||
new PreloadWebpackPlugin({
|
new PreloadWebpackPlugin({
|
||||||
rel: "preload",
|
rel: "preload",
|
||||||
as: "script",
|
as: "script",
|
||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin({
|
new WriteFilePlugin({
|
||||||
"process.env.NODE_ENV": `"${environment}"`,
|
exitOnErrors: false,
|
||||||
}),
|
}),
|
||||||
new MiniCssExtractPlugin({
|
|
||||||
filename: "[name].css",
|
|
||||||
chunkFilename: "[id].css",
|
|
||||||
}),
|
|
||||||
// minify ? new UglifyJsPlugin({
|
|
||||||
// cache: true,
|
|
||||||
// parallel: true,
|
|
||||||
// sourceMap: false,
|
|
||||||
// }) : undefined,
|
|
||||||
// new ForkTsCheckerWebpackPlugin({
|
|
||||||
// checkSyntacticErrors: true,
|
|
||||||
// tsconfig: path.join(root, "./src/tsconfig.json"),
|
|
||||||
// }),
|
|
||||||
],
|
],
|
||||||
target: "web",
|
target: "web",
|
||||||
stats: {
|
}, require("./scripts/webpack.general.config.js"));
|
||||||
all: false, // Fallback for options not defined.
|
|
||||||
errors: true,
|
|
||||||
warnings: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -3318,6 +3318,11 @@ node-libs-browser@^2.0.0:
|
|||||||
util "^0.10.3"
|
util "^0.10.3"
|
||||||
vm-browserify "0.0.4"
|
vm-browserify "0.0.4"
|
||||||
|
|
||||||
|
node-loader@^0.6.0:
|
||||||
|
version "0.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-loader/-/node-loader-0.6.0.tgz#c797ef51095ed5859902b157f6384f6361e05ae8"
|
||||||
|
integrity sha1-x5fvUQle1YWZArFX9jhPY2HgWug=
|
||||||
|
|
||||||
node-pre-gyp@^0.10.0:
|
node-pre-gyp@^0.10.0:
|
||||||
version "0.10.3"
|
version "0.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
|
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
|
||||||
@ -5381,6 +5386,13 @@ webpack-log@^2.0.0:
|
|||||||
ansi-colors "^3.0.0"
|
ansi-colors "^3.0.0"
|
||||||
uuid "^3.3.2"
|
uuid "^3.3.2"
|
||||||
|
|
||||||
|
webpack-merge@^4.2.1:
|
||||||
|
version "4.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4"
|
||||||
|
integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==
|
||||||
|
dependencies:
|
||||||
|
lodash "^4.17.5"
|
||||||
|
|
||||||
webpack-sources@^1.1.0, webpack-sources@^1.3.0:
|
webpack-sources@^1.1.0, webpack-sources@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
|
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
|
||||||
|
Loading…
Reference in New Issue
Block a user