Drop privileges to respective uid
This commit is contained in:
parent
afad563d56
commit
91fe6ffd65
|
@ -2,6 +2,9 @@ FROM ubuntu:focal
|
|||
|
||||
ARG UID
|
||||
|
||||
COPY scripts/docker-install-phase0.bash /tmp/
|
||||
RUN /tmp/docker-install-phase0.bash
|
||||
|
||||
COPY scripts/docker-install-phase1.bash /tmp/
|
||||
RUN /tmp/docker-install-phase1.bash
|
||||
|
||||
|
@ -31,6 +34,7 @@ RUN /tmp/docker-install-phase6.bash "$UID"
|
|||
|
||||
USER docker
|
||||
WORKDIR /home/docker
|
||||
RUN chmod go-rwx /home/docker
|
||||
EXPOSE 6119
|
||||
EXPOSE 6120
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ FROM ubuntu:focal
|
|||
# prod, it's not actually read by anything.
|
||||
ARG UID
|
||||
|
||||
COPY scripts/docker-install-phase0.bash /tmp/
|
||||
RUN /tmp/docker-install-phase0.bash
|
||||
|
||||
COPY scripts/docker-install-phase1.bash /tmp/
|
||||
RUN /tmp/docker-install-phase1.bash
|
||||
|
||||
|
@ -33,6 +36,7 @@ RUN /tmp/docker-install-phase6.bash
|
|||
|
||||
USER docker
|
||||
WORKDIR /home/docker
|
||||
RUN chmod go-rwx /home/docker
|
||||
EXPOSE 6119
|
||||
EXPOSE 6120
|
||||
|
||||
|
@ -40,7 +44,7 @@ ENTRYPOINT ["/usr/local/bin/pid1.bash"]
|
|||
COPY scripts/pid1.bash /usr/local/bin/
|
||||
CMD ["yarn", "run", "server"]
|
||||
|
||||
RUN mkdir /tmp/riju
|
||||
RUN mkdir /tmp/riju /tmp/riju/scripts
|
||||
COPY --chown=docker:docker package.json yarn.lock /tmp/riju/
|
||||
RUN cd /tmp/riju && yarn install
|
||||
COPY --chown=docker:docker webpack.config.js tsconfig.json tsconfig-webpack.json /tmp/riju/
|
||||
|
@ -48,10 +52,11 @@ COPY --chown=docker:docker frontend /tmp/riju/frontend
|
|||
RUN cd /tmp/riju && yarn run frontend
|
||||
COPY --chown=docker:docker backend /tmp/riju/backend
|
||||
RUN cd /tmp/riju && yarn run backend
|
||||
COPY --chown=docker:docker scripts/compile-system.bash /tmp/riju/scripts
|
||||
COPY --chown=docker:docker system /tmp/riju/system
|
||||
RUN cd /tmp/riju && RIJU_PRIVILEGED=1 yarn run system
|
||||
COPY --chown=docker:docker . /home/docker/src
|
||||
RUN cp -R /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju
|
||||
RUN sudo cp -a /tmp/riju/* /home/docker/src/ && rm -rf /tmp/riju
|
||||
|
||||
WORKDIR /home/docker/src
|
||||
RUN sudo deluser docker sudo
|
||||
|
|
2
Makefile
2
Makefile
|
@ -18,7 +18,7 @@ image-prod: ## Build Docker image for production
|
|||
|
||||
.PHONY: docker
|
||||
docker: image-dev ## Run shell with source code and deps inside Docker
|
||||
scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 riju bash
|
||||
scripts/docker.bash run -it --rm -v "$(PWD):/home/docker/src" -p 6119:6119 -p 6120:6120 -h riju riju bash
|
||||
|
||||
.PHONY: deploy
|
||||
deploy: ## Deploy current master from GitHub to production
|
||||
|
|
14
README.md
14
README.md
|
@ -18,18 +18,18 @@ documenting it until it has reached feature-completeness.
|
|||
To run the webserver, all you need is Yarn. Just run `yarn install` as
|
||||
usual to install dependencies. For production, it's:
|
||||
|
||||
$ yarn backend
|
||||
$ yarn frontend
|
||||
$ yarn system
|
||||
$ yarn backend |- or run all three with 'yarn build'
|
||||
$ yarn frontend |
|
||||
$ yarn system |
|
||||
$ yarn server
|
||||
|
||||
For development with file watching and automatic server rebooting and
|
||||
all that, it's:
|
||||
|
||||
$ yarn backend-dev
|
||||
$ yarn frontend-dev
|
||||
$ yarn system-dev
|
||||
$ yarn server-dev
|
||||
$ yarn backend-dev |- or run all four with 'yarn dev'
|
||||
$ yarn frontend-dev |
|
||||
$ yarn system-dev |
|
||||
$ yarn server-dev |
|
||||
|
||||
The webserver listens on `localhost:6119`. Now, although the server
|
||||
itself will work, the only languages that will work are the ones that
|
||||
|
|
|
@ -1,49 +1,48 @@
|
|||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as WebSocket from "ws";
|
||||
|
||||
import * as mkdirp from "mkdirp";
|
||||
import * as nodeCleanup from "node-cleanup";
|
||||
import * as pty from "node-pty";
|
||||
import { IPty } from "node-pty";
|
||||
import * as tmp from "tmp";
|
||||
import { v4 as getUUID } from "uuid";
|
||||
|
||||
import { PRIVILEGED } from "./config";
|
||||
import { LangConfig, langs } from "./langs";
|
||||
import { borrowUser } from "./users";
|
||||
import { callPrivileged, getEnv, spawnPrivileged } from "./util";
|
||||
|
||||
export class Session {
|
||||
id: string;
|
||||
uuid: string;
|
||||
code: string;
|
||||
config: LangConfig;
|
||||
term: { pty: IPty | null; live: boolean };
|
||||
ws: WebSocket;
|
||||
tmpdir: string | null;
|
||||
tmpdirCleanup: (() => void) | null;
|
||||
homedir: string | null;
|
||||
uid: number | null;
|
||||
uidCleanup: (() => Promise<void>) | null;
|
||||
|
||||
log = (msg: string) => console.log(`[${this.id}] ${msg}`);
|
||||
log = (msg: string) => console.log(`[${this.uuid}] ${msg}`);
|
||||
|
||||
constructor(ws: WebSocket, lang: string) {
|
||||
this.id = getUUID();
|
||||
this.uuid = getUUID();
|
||||
this.log(`Creating session, language ${lang}`);
|
||||
this.ws = ws;
|
||||
this.config = langs[lang];
|
||||
this.term = { pty: null, live: false };
|
||||
this.code = "";
|
||||
this.tmpdir = null;
|
||||
this.tmpdirCleanup = null;
|
||||
this.homedir = null;
|
||||
this.uid = null;
|
||||
this.uidCleanup = null;
|
||||
ws.on("message", this.handleClientMessage);
|
||||
ws.on("close", () =>
|
||||
this.cleanup().catch((err) =>
|
||||
this.log(`Error during session cleanup: ${err}`)
|
||||
)
|
||||
this.cleanup().catch((err) => {
|
||||
this.log(`Error during session cleanup`);
|
||||
console.log(err);
|
||||
})
|
||||
);
|
||||
nodeCleanup();
|
||||
this.run().catch((err) => this.log(`Error while running: ${err}`));
|
||||
this.run().catch((err) => {
|
||||
this.log(`Error while setting up environment for pty`);
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
handleClientMessage = (event: string) => {
|
||||
let msg: any;
|
||||
|
@ -81,9 +80,18 @@ export class Session {
|
|||
({ uid: this.uid, cleanup: this.uidCleanup } = await borrowUser(
|
||||
this.log
|
||||
));
|
||||
this.log(`Borrowed uid ${this.uid}`);
|
||||
}
|
||||
this.log(`Borrowed uid ${this.uid}`);
|
||||
const { name, repl, main, suffix, compile, run, hacks } = this.config;
|
||||
const {
|
||||
name,
|
||||
repl,
|
||||
main,
|
||||
suffix,
|
||||
alwaysCreate,
|
||||
compile,
|
||||
run,
|
||||
hacks,
|
||||
} = this.config;
|
||||
if (this.term.pty) {
|
||||
this.term.pty.kill();
|
||||
this.term.live = false;
|
||||
|
@ -93,20 +101,9 @@ export class Session {
|
|||
} catch (err) {
|
||||
//
|
||||
}
|
||||
if (this.tmpdir == null) {
|
||||
({ path: this.tmpdir, cleanup: this.tmpdirCleanup } = await new Promise(
|
||||
(resolve, reject) =>
|
||||
tmp.dir(
|
||||
{ unsafeCleanup: true, dir: "riju" },
|
||||
(err, path, cleanup) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve({ path, cleanup });
|
||||
}
|
||||
}
|
||||
)
|
||||
));
|
||||
if (this.homedir == null) {
|
||||
this.homedir = `/tmp/riju/${this.uuid}`;
|
||||
await callPrivileged(["setup", `${this.uid}`, this.uuid], this.log);
|
||||
}
|
||||
let cmdline: string;
|
||||
if (!run) {
|
||||
|
@ -117,22 +114,33 @@ export class Session {
|
|||
code += suffix;
|
||||
}
|
||||
if (main.includes("/")) {
|
||||
await mkdirp(path.dirname(path.resolve(this.tmpdir!, main)));
|
||||
await spawnPrivileged(
|
||||
this.uid,
|
||||
this.uuid,
|
||||
["mkdir", "-p", path.dirname(path.resolve(this.homedir, main))],
|
||||
this.log
|
||||
);
|
||||
}
|
||||
await new Promise((resolve, reject) =>
|
||||
fs.writeFile(path.resolve(this.tmpdir!, main), code, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
await spawnPrivileged(
|
||||
this.uid,
|
||||
this.uuid,
|
||||
["sh", "-c", `cat > ${path.resolve(this.homedir, main)}`],
|
||||
this.log,
|
||||
{ input: code }
|
||||
);
|
||||
cmdline = run;
|
||||
if (compile) {
|
||||
cmdline = `( ${compile} ) && ( ${run} )`;
|
||||
}
|
||||
} else if (repl) {
|
||||
if (alwaysCreate) {
|
||||
await spawnPrivileged(
|
||||
this.uid,
|
||||
this.uuid,
|
||||
["touch", `${path.resolve(this.homedir, main)}`],
|
||||
this.log
|
||||
);
|
||||
}
|
||||
cmdline = repl;
|
||||
} else {
|
||||
cmdline = `echo '${name} has no REPL, press Run to see it in action'`;
|
||||
|
@ -140,32 +148,38 @@ export class Session {
|
|||
if (hacks && hacks.includes("ghci-config") && run) {
|
||||
if (this.code) {
|
||||
const contents = ":load Main\nmain\n";
|
||||
await new Promise((resolve, reject) => {
|
||||
fs.writeFile(path.resolve(this.tmpdir!, ".ghci"), contents, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
await spawnPrivileged(
|
||||
this.uid,
|
||||
this.uuid,
|
||||
["sh", "-c", `cat > ${path.resolve(this.homedir, ".ghci")}`],
|
||||
this.log,
|
||||
{ input: contents }
|
||||
);
|
||||
} else {
|
||||
await new Promise((resolve, reject) =>
|
||||
fs.unlink(path.resolve(this.tmpdir!, ".ghci"), (err) => {
|
||||
if (err && err.code !== "ENOENT") {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
await spawnPrivileged(
|
||||
this.uid,
|
||||
this.uuid,
|
||||
["rm", "-f", path.resolve(this.homedir, ".ghci")],
|
||||
this.log
|
||||
);
|
||||
}
|
||||
}
|
||||
const args = PRIVILEGED
|
||||
? [
|
||||
"/home/docker/src/system/out/riju-system-privileged",
|
||||
"spawn",
|
||||
`${this.uid}`,
|
||||
`${this.uuid}`,
|
||||
"bash",
|
||||
"-c",
|
||||
cmdline,
|
||||
]
|
||||
: ["bash", "-c", cmdline];
|
||||
const env = getEnv(this.uuid);
|
||||
const term = {
|
||||
pty: pty.spawn("bash", ["-c", cmdline], {
|
||||
pty: pty.spawn(args[0], args.slice(1), {
|
||||
name: "xterm-color",
|
||||
cwd: this.tmpdir!,
|
||||
env: process.env as { [key: string]: string },
|
||||
env,
|
||||
}),
|
||||
live: true,
|
||||
};
|
||||
|
@ -186,8 +200,8 @@ export class Session {
|
|||
};
|
||||
cleanup = async () => {
|
||||
this.log(`Cleaning up session`);
|
||||
if (this.tmpdirCleanup) {
|
||||
this.tmpdirCleanup();
|
||||
if (this.homedir) {
|
||||
await callPrivileged(["teardown", this.uuid], this.log);
|
||||
}
|
||||
if (this.uidCleanup) {
|
||||
await this.uidCleanup();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import * as process from "process";
|
||||
|
||||
export const PRIVILEGED = process.env.RIJU_PRIVILEGED ? true : false;
|
|
@ -6,6 +6,7 @@ export interface LangConfig {
|
|||
main: string;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
alwaysCreate?: boolean;
|
||||
compile?: string;
|
||||
run: string;
|
||||
template: string;
|
||||
|
@ -220,7 +221,7 @@ int main() {
|
|||
monacoLang: "csharp",
|
||||
main: "main.cs",
|
||||
compile: "mcs main.cs",
|
||||
run: "./main.exe",
|
||||
run: "mono main.exe",
|
||||
template: `class main {
|
||||
static void Main(string[] args) {
|
||||
System.Console.WriteLine("Hello, world!");
|
||||
|
@ -326,9 +327,9 @@ output = "Hello, world!"
|
|||
aliases: ["elv"],
|
||||
name: "Elvish",
|
||||
monacoLang: "plaintext",
|
||||
repl: "SHELL=/usr/bin/elvish HOME=. elvish",
|
||||
repl: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`,
|
||||
main: ".elvish/rc.elv",
|
||||
run: "SHELL=/usr/bin/elvish HOME=. elvish",
|
||||
run: `SHELL=/usr/bin/elvish HOME="$PWD" elvish`,
|
||||
template: `echo "Hello, world!"
|
||||
`,
|
||||
},
|
||||
|
@ -451,8 +452,8 @@ main = putStrLn "Hello, world!"
|
|||
repl: "ink",
|
||||
main: "main.ink",
|
||||
run: "ink main.ink; ink",
|
||||
template: `std := load('../../opt/ink/std')
|
||||
str := load('../../opt/ink/str')
|
||||
template: `std := load('../../../opt/ink/std')
|
||||
str := load('../../../opt/ink/str')
|
||||
|
||||
log := std.log
|
||||
|
||||
|
@ -535,9 +536,9 @@ PLEASE GIVE UP
|
|||
aliases: ["kshell"],
|
||||
name: "Ksh",
|
||||
monacoLang: "shell",
|
||||
repl: "SHELL=/usr/bin/ksh HOME=. ksh",
|
||||
repl: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`,
|
||||
main: ".kshrc",
|
||||
run: "SHELL=/usr/bin/ksh HOME=. ksh",
|
||||
run: `SHELL=/usr/bin/ksh HOME="$PWD" ksh`,
|
||||
template: `echo "Hello, world!"
|
||||
`,
|
||||
},
|
||||
|
@ -830,9 +831,9 @@ binding_irb.run(IRB.conf)
|
|||
aliases: ["shell", "posix", "posixsh", "ash", "dash", "posh"],
|
||||
name: "Sh",
|
||||
monacoLang: "shell",
|
||||
repl: "SHELL=/usr/bin/sh HOME=. posh -l",
|
||||
repl: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`,
|
||||
main: ".profile",
|
||||
run: "SHELL=/usr/bin/sh HOME=. posh -l",
|
||||
run: `SHELL=/usr/bin/sh HOME="$PWD" posh -l`,
|
||||
template: `echo "Hello, world!"
|
||||
`,
|
||||
},
|
||||
|
@ -992,7 +993,7 @@ END
|
|||
monacoLang: "tcl",
|
||||
repl: "tclsh",
|
||||
main: ".tclshrc",
|
||||
run: "HOME=. tclsh",
|
||||
run: `HOME="$PWD" tclsh`,
|
||||
template: `puts {Hello, world!}
|
||||
`,
|
||||
},
|
||||
|
@ -1000,9 +1001,9 @@ END
|
|||
aliases: ["tcshell", "tcshrc"],
|
||||
name: "Tcsh",
|
||||
monacoLang: "shell",
|
||||
repl: "SHELL=/usr/bin/tcsh HOME=. tcsh",
|
||||
repl: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`,
|
||||
main: ".tcshrc",
|
||||
run: "SHELL=/usr/bin/tcsh HOME=. tcsh",
|
||||
run: `SHELL=/usr/bin/tcsh HOME="$PWD" tcsh`,
|
||||
template: `echo "Hello, world!"
|
||||
`,
|
||||
},
|
||||
|
@ -1104,7 +1105,8 @@ message:
|
|||
monacoLang: "shell",
|
||||
repl: "SHELL=/usr/bin/zsh zsh",
|
||||
main: ".zshrc",
|
||||
run: "SHELL=/usr/bin/zsh ZDOTDIR=. zsh",
|
||||
alwaysCreate: true,
|
||||
run: `SHELL=/usr/bin/zsh ZDOTDIR="$PWD" zsh`,
|
||||
template: `echo "Hello, world!"
|
||||
`,
|
||||
},
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import { spawn } from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as process from "process";
|
||||
|
||||
import * as AsyncLock from "async-lock";
|
||||
import * as _ from "lodash";
|
||||
import * as parsePasswd from "parse-passwd";
|
||||
|
||||
import { PRIVILEGED } from "./config";
|
||||
import { callPrivileged } from "./util";
|
||||
|
||||
// Keep in sync with system/src/riju-system-privileged.c
|
||||
const MIN_UID = 2000;
|
||||
const MAX_UID = 65000;
|
||||
|
||||
const PRIVILEGED = process.env.RIJU_PRIVILEGED ? true : false;
|
||||
const CUR_UID = parseInt(process.env.UID || "") || null;
|
||||
|
||||
let availIds: number[] | null = null;
|
||||
|
@ -29,7 +30,7 @@ async function readExistingUsers(log: (msg: string) => void) {
|
|||
})
|
||||
)
|
||||
)
|
||||
.filter(({ username }) => username.startsWith("riju_user"))
|
||||
.filter(({ username }) => username.startsWith("riju"))
|
||||
.map(({ uid }) => parseInt(uid))
|
||||
.filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID);
|
||||
nextId = (_.max(availIds) || MIN_UID - 1) + 1;
|
||||
|
@ -40,33 +41,11 @@ async function createUser(log: (msg: string) => void): Promise<number> {
|
|||
if (nextId! >= MAX_UID) {
|
||||
throw new Error("too many users");
|
||||
}
|
||||
return await new Promise((resolve, reject) => {
|
||||
const uid = nextId!;
|
||||
const useradd = spawn("system/out/riju-system-privileged", [
|
||||
"useradd",
|
||||
`${uid}`,
|
||||
]);
|
||||
let output = "";
|
||||
useradd.stdout.on("data", (data) => {
|
||||
output += `${data}`;
|
||||
});
|
||||
useradd.stderr.on("data", (data) => {
|
||||
output += `${data}`;
|
||||
});
|
||||
useradd.on("close", (code) => {
|
||||
output = output.trim();
|
||||
if (output) {
|
||||
log("Output from useradd:\n" + output);
|
||||
}
|
||||
if (code === 0) {
|
||||
log(`Created new user with ID ${uid}`);
|
||||
nextId! += 1;
|
||||
resolve(uid);
|
||||
} else {
|
||||
reject(`useradd failed with error code ${code}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
const uid = nextId!;
|
||||
await callPrivileged(["useradd", `${uid}`], log);
|
||||
log(`Created new user with ID ${uid}`);
|
||||
nextId! += 1;
|
||||
return uid;
|
||||
}
|
||||
|
||||
export async function borrowUser(log: (msg: string) => void) {
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import { spawn, SpawnOptions } from "child_process";
|
||||
import * as process from "process";
|
||||
|
||||
interface Options extends SpawnOptions {
|
||||
input?: string;
|
||||
}
|
||||
|
||||
export function getEnv(uuid: string) {
|
||||
const cwd = `/tmp/riju/${uuid}`;
|
||||
return {
|
||||
HOME: cwd,
|
||||
HOSTNAME: "riju",
|
||||
LANG: "C.UTF-8",
|
||||
LC_ALL: "C.UTF-8",
|
||||
PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin",
|
||||
PWD: cwd,
|
||||
SHELL: "/usr/bin/bash",
|
||||
TERM: "xterm-color",
|
||||
};
|
||||
}
|
||||
|
||||
export async function call(
|
||||
args: string[],
|
||||
log: (msg: string) => void,
|
||||
options?: Options
|
||||
) {
|
||||
options = options || {};
|
||||
const input = options.input;
|
||||
delete options.input;
|
||||
const proc = spawn(args[0], args.slice(1), options);
|
||||
if (input) {
|
||||
proc.stdin!.end(input);
|
||||
}
|
||||
let output = "";
|
||||
proc.stdout!.on("data", (data: Buffer) => {
|
||||
output += `${data}`;
|
||||
});
|
||||
proc.stderr!.on("data", (data: Buffer) => {
|
||||
output += `${data}`;
|
||||
});
|
||||
await new Promise((resolve, reject) => {
|
||||
proc.on("error", reject);
|
||||
proc.on("close", (code: number) => {
|
||||
output = output.trim();
|
||||
if (output) {
|
||||
log(`Output from ${args[0]}:\n` + output);
|
||||
}
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(`command ${args[0]} failed with error code ${code}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function callPrivileged(
|
||||
args: string[],
|
||||
log: (msg: string) => void,
|
||||
options?: Options
|
||||
) {
|
||||
await call(
|
||||
["/home/docker/src/system/out/riju-system-privileged"].concat(args),
|
||||
log,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
export async function spawnPrivileged(
|
||||
uid: number,
|
||||
uuid: string,
|
||||
args: string[],
|
||||
log: (msg: string) => void,
|
||||
options?: Options
|
||||
) {
|
||||
options = options || {};
|
||||
options.env = getEnv(uuid);
|
||||
await callPrivileged(
|
||||
["spawn", `${uid}`, `${uuid}`].concat(args),
|
||||
log,
|
||||
options
|
||||
);
|
||||
}
|
|
@ -10,92 +10,98 @@ interface RijuConfig {
|
|||
template: string;
|
||||
}
|
||||
|
||||
const config: RijuConfig = (window as any).rijuConfig;
|
||||
async function main() {
|
||||
const config: RijuConfig = (window as any).rijuConfig;
|
||||
|
||||
const term = new Terminal();
|
||||
const fitAddon = new FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
term.open(document.getElementById("terminal")!);
|
||||
const term = new Terminal();
|
||||
const fitAddon = new FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
term.open(document.getElementById("terminal")!);
|
||||
|
||||
fitAddon.fit();
|
||||
window.addEventListener("resize", () => fitAddon.fit());
|
||||
fitAddon.fit();
|
||||
window.addEventListener("resize", () => fitAddon.fit());
|
||||
|
||||
term.write("Connecting to server...");
|
||||
|
||||
const initialRetryDelayMs = 200;
|
||||
let retryDelayMs = initialRetryDelayMs;
|
||||
|
||||
function tryConnect() {
|
||||
console.log("Connecting to server...");
|
||||
socket = new WebSocket(
|
||||
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
||||
document.location.host +
|
||||
`/api/v1/ws?lang=${encodeURIComponent(config.id)}`
|
||||
await new Promise((resolve) =>
|
||||
term.write("Connecting to server...", resolve)
|
||||
);
|
||||
socket.addEventListener("open", () => {
|
||||
console.log("Successfully connected to server");
|
||||
});
|
||||
socket.addEventListener("message", (event: MessageEvent) => {
|
||||
let message: any;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (err) {
|
||||
console.error("Malformed message from server:", event.data);
|
||||
return;
|
||||
}
|
||||
if (message?.event && message?.event !== "error") {
|
||||
retryDelayMs = initialRetryDelayMs;
|
||||
}
|
||||
switch (message?.event) {
|
||||
case "terminalClear":
|
||||
term.reset();
|
||||
|
||||
const initialRetryDelayMs = 200;
|
||||
let retryDelayMs = initialRetryDelayMs;
|
||||
|
||||
function tryConnect() {
|
||||
console.log("Connecting to server...");
|
||||
socket = new WebSocket(
|
||||
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
||||
document.location.host +
|
||||
`/api/v1/ws?lang=${encodeURIComponent(config.id)}`
|
||||
);
|
||||
socket.addEventListener("open", () => {
|
||||
console.log("Successfully connected to server");
|
||||
});
|
||||
socket.addEventListener("message", (event: MessageEvent) => {
|
||||
let message: any;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (err) {
|
||||
console.error("Malformed message from server:", event.data);
|
||||
return;
|
||||
case "terminalOutput":
|
||||
if (typeof message.output !== "string") {
|
||||
}
|
||||
if (message?.event && message?.event !== "error") {
|
||||
retryDelayMs = initialRetryDelayMs;
|
||||
}
|
||||
switch (message?.event) {
|
||||
case "terminalClear":
|
||||
term.reset();
|
||||
return;
|
||||
case "terminalOutput":
|
||||
if (typeof message.output !== "string") {
|
||||
console.error("Unexpected message from server:", message);
|
||||
return;
|
||||
}
|
||||
term.write(message.output);
|
||||
return;
|
||||
default:
|
||||
console.error("Unexpected message from server:", message);
|
||||
return;
|
||||
}
|
||||
term.write(message.output);
|
||||
return;
|
||||
default:
|
||||
console.error("Unexpected message from server:", message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
socket.addEventListener("close", (event: CloseEvent) => {
|
||||
if (event.wasClean) {
|
||||
console.log("Connection closed cleanly");
|
||||
} else {
|
||||
console.error("Connection died");
|
||||
}
|
||||
scheduleConnect();
|
||||
});
|
||||
}
|
||||
|
||||
function scheduleConnect() {
|
||||
const delay = retryDelayMs * Math.random();
|
||||
console.log(`Trying to reconnect in ${Math.floor(delay)}ms`);
|
||||
setTimeout(tryConnect, delay);
|
||||
retryDelayMs *= 2;
|
||||
}
|
||||
|
||||
let socket: WebSocket | null = null;
|
||||
tryConnect();
|
||||
|
||||
term.onData(
|
||||
(data) =>
|
||||
socket &&
|
||||
socket.send(JSON.stringify({ event: "terminalInput", input: data }))
|
||||
);
|
||||
|
||||
const editor = monaco.editor.create(document.getElementById("editor")!, {
|
||||
minimap: { enabled: false },
|
||||
scrollbar: { verticalScrollbarSize: 0 },
|
||||
});
|
||||
socket.addEventListener("close", (event: CloseEvent) => {
|
||||
if (event.wasClean) {
|
||||
console.log("Connection closed cleanly");
|
||||
} else {
|
||||
console.error("Connection died");
|
||||
}
|
||||
scheduleConnect();
|
||||
window.addEventListener("resize", () => editor.layout());
|
||||
editor.getModel()!.setValue(config.template);
|
||||
monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang);
|
||||
|
||||
document.getElementById("runButton")!.addEventListener("click", () => {
|
||||
socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() }));
|
||||
});
|
||||
}
|
||||
|
||||
function scheduleConnect() {
|
||||
const delay = retryDelayMs * Math.random();
|
||||
console.log(`Trying to reconnect in ${Math.floor(delay)}ms`);
|
||||
setTimeout(tryConnect, delay);
|
||||
retryDelayMs *= 2;
|
||||
}
|
||||
|
||||
let socket: WebSocket | null = null;
|
||||
tryConnect();
|
||||
|
||||
term.onData(
|
||||
(data) =>
|
||||
socket &&
|
||||
socket.send(JSON.stringify({ event: "terminalInput", input: data }))
|
||||
);
|
||||
|
||||
const editor = monaco.editor.create(document.getElementById("editor")!, {
|
||||
minimap: { enabled: false },
|
||||
scrollbar: { verticalScrollbarSize: 0 },
|
||||
});
|
||||
window.addEventListener("resize", () => editor.layout());
|
||||
editor.getModel()!.setValue(config.template);
|
||||
monaco.editor.setModelLanguage(editor.getModel()!, config.monacoLang);
|
||||
|
||||
document.getElementById("runButton")!.addEventListener("click", () => {
|
||||
socket?.send(JSON.stringify({ event: "runCode", code: editor.getValue() }));
|
||||
});
|
||||
main().catch(console.error);
|
||||
|
|
12
package.json
12
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "riju",
|
||||
"version": "0",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
@ -11,6 +11,7 @@
|
|||
"@types/lodash": "^4.14.155",
|
||||
"@types/mkdirp": "^1.0.1",
|
||||
"@types/parse-passwd": "^1.0.0",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"@types/tmp": "^0.2.0",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"app-root-path": "^3.0.0",
|
||||
|
@ -21,13 +22,12 @@
|
|||
"express-ws": "^4.0.0",
|
||||
"file-loader": "^6.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"mkdirp": "^1.0.4",
|
||||
"monaco-editor": "^0.20.0",
|
||||
"node-cleanup": "^2.1.2",
|
||||
"node-pty": "^0.9.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"parse-passwd": "^1.0.0",
|
||||
"style-loader": "^1.2.1",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.5",
|
||||
"uuid": "^8.1.0",
|
||||
|
@ -38,12 +38,14 @@
|
|||
},
|
||||
"scripts": {
|
||||
"backend": "tsc",
|
||||
"backend-dev": "tsc --watch",
|
||||
"backend-dev": "tsc --watch --preserveWatchOutput",
|
||||
"frontend": "webpack --production",
|
||||
"frontend-dev": "webpack --development --watch",
|
||||
"server": "scripts/setup.bash && node backend/out/server.js",
|
||||
"server-dev": "watchexec -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'",
|
||||
"system": "scripts/compile-system.bash",
|
||||
"system-dev": "watchexec -w system/src -n scripts/compile-system.bash"
|
||||
"system-dev": "watchexec -w system/src -n scripts/compile-system.bash",
|
||||
"build": "run-s backend frontend system",
|
||||
"dev": "run-p backend-dev frontend-dev system-dev server-dev"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
(yes || true) | unminimize
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
rm "$0"
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
dpkg --add-architecture i386
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
packages="
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
packages="
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
packages="
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
packages="
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
packages="
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
npm config set unsafe-perm true
|
||||
PERL_MM_USE_DEFAULT=1 cpan App::cpanminus
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
# Needed for project infrastructure
|
||||
cd /tmp
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -x
|
||||
|
||||
uid="$1"
|
||||
|
||||
rm -rf /tmp/hsperfdata_root
|
||||
|
||||
if [[ -n "$uid" ]] && (( "$uid" != 0 )); then
|
||||
useradd --uid="$uid" --create-home --groups sudo docker
|
||||
passwd -d docker
|
||||
useradd --uid="$uid" --password "!" --create-home --groups sudo docker
|
||||
else
|
||||
useradd --create-home --groups sudo docker
|
||||
passwd -d docker
|
||||
useradd --password "!" --create-home --groups sudo docker
|
||||
fi
|
||||
|
||||
tee /etc/sudoers.d/99-passwordless >/dev/null <<"EOF"
|
||||
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
|
||||
EOF
|
||||
|
||||
touch /home/docker/.zshrc
|
||||
chown docker:docker /home/docker/.zshrc
|
||||
|
||||
|
|
|
@ -18,4 +18,4 @@ else
|
|||
fi
|
||||
|
||||
docker run ${it} -e TLS -e TLS_PRIVATE_KEY -e TLS_CERTIFICATE \
|
||||
--rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 riju:prod
|
||||
--rm -p 0.0.0.0:80:6119 -p 0.0.0.0:443:6120 -h riju riju:prod
|
||||
|
|
|
@ -4,4 +4,7 @@ set -e
|
|||
set -o pipefail
|
||||
|
||||
mkdir -p /tmp/riju
|
||||
rm -rf /tmp/riju/*
|
||||
if [[ -x system/out/riju-system-privileged ]]; then
|
||||
system/out/riju-system-privileged teardown "*"
|
||||
fi
|
||||
chmod a=x,u=rwx /tmp/riju
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Keep in sync with backend/src/users.ts
|
||||
const int MIN_UID = 2000;
|
||||
const int MAX_UID = 65000;
|
||||
|
||||
void die(const char *msg)
|
||||
void die(char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(1);
|
||||
|
@ -17,19 +21,84 @@ void die(const char *msg)
|
|||
void die_with_usage()
|
||||
{
|
||||
die("usage:\n"
|
||||
" riju-system-privileged useradd UID");
|
||||
" riju-system-privileged useradd UID\n"
|
||||
" riju-system-privileged spawn UID CMDLINE...\n"
|
||||
" riju-system-privileged setup UID UUID\n"
|
||||
" riju-system-privileged teardown UUID");
|
||||
}
|
||||
|
||||
int parseUID(char *str)
|
||||
{
|
||||
char *endptr;
|
||||
long uid = strtol(str, &endptr, 10);
|
||||
if (!*str || *endptr)
|
||||
die("uid must be an integer");
|
||||
if (uid < MIN_UID || uid >= MAX_UID)
|
||||
die("uid is out of range");
|
||||
return uid;
|
||||
}
|
||||
|
||||
char *parseUUID(char *uuid)
|
||||
{
|
||||
if (!*uuid)
|
||||
die("illegal uuid");
|
||||
for (char *ptr = uuid; *ptr; ++ptr)
|
||||
if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') || *ptr == '-'))
|
||||
die("illegal uuid");
|
||||
return uuid;
|
||||
}
|
||||
|
||||
void useradd(int uid)
|
||||
{
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d riju_user%1$d", uid) < 0) {
|
||||
if (asprintf(&cmdline, "groupadd -g %1$d riju%1$d", uid) < 0)
|
||||
die("asprintf failed");
|
||||
}
|
||||
int status = system(cmdline);
|
||||
if (status) {
|
||||
if (status)
|
||||
die("groupadd failed");
|
||||
if (asprintf(&cmdline, "useradd -M -N -l -r -u %1$d -g %1$d -p '!' riju%1$d", uid) < 0)
|
||||
die("asprintf failed");
|
||||
status = system(cmdline);
|
||||
if (status)
|
||||
die("useradd failed");
|
||||
}
|
||||
}
|
||||
|
||||
void spawn(int uid, char *uuid, char **cmdline)
|
||||
{
|
||||
char *cwd;
|
||||
if (asprintf(&cwd, "/tmp/riju/%s", uuid) < 0)
|
||||
die("asprintf failed");
|
||||
if (chdir(cwd) < 0)
|
||||
die("chdir failed");
|
||||
if (setgid(uid) < 0)
|
||||
die("setgid failed");
|
||||
if (setgroups(0, NULL) < 0)
|
||||
die("setgroups failed");
|
||||
if (setuid(uid) < 0)
|
||||
die("setuid failed");
|
||||
umask(077);
|
||||
execvp(cmdline[0], cmdline);
|
||||
die("execvp failed");
|
||||
}
|
||||
|
||||
void setup(int uid, char *uuid)
|
||||
{
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s", uid, uuid) < 0)
|
||||
die("asprintf failed");
|
||||
int status = system(cmdline);
|
||||
if (status)
|
||||
die("install failed");
|
||||
}
|
||||
|
||||
void teardown(char *uuid)
|
||||
{
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "rm -rf /tmp/riju/%s", uuid) < 0)
|
||||
die("asprintf failed");
|
||||
int status = system(cmdline);
|
||||
if (status)
|
||||
die("rm failed");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -40,15 +109,28 @@ int main(int argc, char **argv)
|
|||
if (!strcmp(argv[1], "useradd")) {
|
||||
if (argc != 3)
|
||||
die_with_usage();
|
||||
char *endptr;
|
||||
long uid = strtol(argv[2], &endptr, 10);
|
||||
if (!argv[2] || *endptr) {
|
||||
die("uid must be an integer");
|
||||
}
|
||||
if (uid < MIN_UID || uid >= MAX_UID) {
|
||||
die("uid is out of range");
|
||||
}
|
||||
useradd(uid);
|
||||
useradd(parseUID(argv[2]));
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "spawn")) {
|
||||
if (argc < 5)
|
||||
die_with_usage();
|
||||
spawn(parseUID(argv[2]), parseUUID(argv[3]), &argv[4]);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "setup")) {
|
||||
if (argc != 4)
|
||||
die_with_usage();
|
||||
int uid = parseUID(argv[2]);
|
||||
char *uuid = parseUUID(argv[3]);
|
||||
setup(uid, uuid);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "teardown")) {
|
||||
if (argc != 3)
|
||||
die_with_usage();
|
||||
char *uuid = strcmp(argv[2], "*") ? parseUUID(argv[2]) : "*";
|
||||
teardown(uuid);
|
||||
return 0;
|
||||
}
|
||||
die_with_usage();
|
||||
|
|
313
yarn.lock
313
yarn.lock
|
@ -55,6 +55,14 @@
|
|||
"@types/qs" "*"
|
||||
"@types/serve-static" "*"
|
||||
|
||||
"@types/glob@*":
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987"
|
||||
integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==
|
||||
dependencies:
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/json-schema@^7.0.4":
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
|
||||
|
@ -70,6 +78,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5"
|
||||
integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/mkdirp@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.1.tgz#0930b948914a78587de35458b86c907b6e98bbf6"
|
||||
|
@ -97,6 +110,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||
|
||||
"@types/rimraf@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f"
|
||||
integrity sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==
|
||||
dependencies:
|
||||
"@types/glob" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/serve-static@*":
|
||||
version "1.13.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c"
|
||||
|
@ -663,7 +684,7 @@ camelcase@^5.0.0, camelcase@^5.3.1:
|
|||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.2:
|
||||
chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
|
@ -880,7 +901,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
|
|||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
cross-spawn@6.0.5, cross-spawn@^6.0.0:
|
||||
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
|
@ -954,6 +975,13 @@ decode-uri-component@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
||||
|
||||
define-properties@^1.1.2, define-properties@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
|
||||
dependencies:
|
||||
object-keys "^1.0.12"
|
||||
|
||||
define-property@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
|
||||
|
@ -1100,6 +1128,39 @@ errno@^0.1.3, errno@~0.1.7:
|
|||
dependencies:
|
||||
prr "~1.0.1"
|
||||
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.17.5:
|
||||
version "1.17.6"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a"
|
||||
integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==
|
||||
dependencies:
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
is-callable "^1.2.0"
|
||||
is-regex "^1.1.0"
|
||||
object-inspect "^1.7.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.0"
|
||||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.1"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
|
||||
dependencies:
|
||||
is-callable "^1.1.4"
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
|
@ -1410,6 +1471,11 @@ fsevents@~2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
|
||||
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
get-caller-file@^2.0.1:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
|
@ -1500,6 +1566,11 @@ has-flag@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-symbols@^1.0.0, has-symbols@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
||||
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
|
||||
|
||||
has-value@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
|
||||
|
@ -1531,6 +1602,13 @@ has-values@^1.0.0:
|
|||
is-number "^3.0.0"
|
||||
kind-of "^4.0.0"
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hash-base@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
|
||||
|
@ -1564,6 +1642,11 @@ homedir-polyfill@^1.0.1:
|
|||
dependencies:
|
||||
parse-passwd "^1.0.0"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
http-errors@1.7.2:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
|
||||
|
@ -1695,6 +1778,11 @@ is-accessor-descriptor@^1.0.0:
|
|||
dependencies:
|
||||
kind-of "^6.0.0"
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
|
||||
|
||||
is-binary-path@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
|
||||
|
@ -1714,6 +1802,11 @@ is-buffer@^1.1.5:
|
|||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-callable@^1.1.4, is-callable@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
|
||||
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
|
||||
|
||||
is-data-descriptor@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
|
||||
|
@ -1728,6 +1821,11 @@ is-data-descriptor@^1.0.0:
|
|||
dependencies:
|
||||
kind-of "^6.0.0"
|
||||
|
||||
is-date-object@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
|
||||
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
|
||||
|
||||
is-descriptor@^0.1.0:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
|
||||
|
@ -1801,11 +1899,25 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
|||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
is-regex@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
|
||||
integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==
|
||||
dependencies:
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
is-symbol@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
|
||||
integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
|
||||
dependencies:
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-windows@^1.0.1, is-windows@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||
|
@ -1848,7 +1960,7 @@ jake@^10.6.1:
|
|||
filelist "^1.0.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
json-parse-better-errors@^1.0.2:
|
||||
json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
|
||||
|
@ -1903,6 +2015,16 @@ lcid@^2.0.0:
|
|||
dependencies:
|
||||
invert-kv "^2.0.0"
|
||||
|
||||
load-json-file@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
|
||||
integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
parse-json "^4.0.0"
|
||||
pify "^3.0.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
loader-runner@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
|
||||
|
@ -2021,6 +2143,11 @@ memory-fs@^0.5.0:
|
|||
errno "^0.1.3"
|
||||
readable-stream "^2.0.1"
|
||||
|
||||
memorystream@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
|
||||
integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
|
||||
|
||||
merge-descriptors@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
|
@ -2141,11 +2268,6 @@ mkdirp@^0.5.1, mkdirp@^0.5.3:
|
|||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
mkdirp@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
monaco-editor@^0.20.0:
|
||||
version "0.20.0"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea"
|
||||
|
@ -2251,6 +2373,16 @@ node-pty@^0.9.0:
|
|||
dependencies:
|
||||
nan "^2.14.0"
|
||||
|
||||
normalize-package-data@^2.3.2:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
|
||||
dependencies:
|
||||
hosted-git-info "^2.1.4"
|
||||
resolve "^1.10.0"
|
||||
semver "2 || 3 || 4 || 5"
|
||||
validate-npm-package-license "^3.0.1"
|
||||
|
||||
normalize-path@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
|
||||
|
@ -2263,6 +2395,21 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
npm-run-all@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
|
||||
integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
chalk "^2.4.1"
|
||||
cross-spawn "^6.0.5"
|
||||
memorystream "^0.3.1"
|
||||
minimatch "^3.0.4"
|
||||
pidtree "^0.3.0"
|
||||
read-pkg "^3.0.0"
|
||||
shell-quote "^1.6.1"
|
||||
string.prototype.padend "^3.0.0"
|
||||
|
||||
npm-run-path@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
|
||||
|
@ -2284,6 +2431,16 @@ object-copy@^0.1.0:
|
|||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-inspect@^1.7.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
||||
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
||||
|
||||
object-visit@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
|
||||
|
@ -2291,6 +2448,16 @@ object-visit@^1.0.0:
|
|||
dependencies:
|
||||
isobject "^3.0.0"
|
||||
|
||||
object.assign@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
|
||||
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.1.1"
|
||||
has-symbols "^1.0.0"
|
||||
object-keys "^1.0.11"
|
||||
|
||||
object.pick@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
|
||||
|
@ -2386,6 +2553,14 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
|
|||
pbkdf2 "^3.0.3"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
parse-json@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
|
||||
integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
|
||||
dependencies:
|
||||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
parse-passwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
|
||||
|
@ -2426,11 +2601,23 @@ path-key@^2.0.0, path-key@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
|
||||
|
||||
path-type@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
|
||||
integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
|
||||
dependencies:
|
||||
pify "^3.0.0"
|
||||
|
||||
pbkdf2@^3.0.3:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94"
|
||||
|
@ -2447,6 +2634,16 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
|
|||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||
|
||||
pidtree@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a"
|
||||
integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==
|
||||
|
||||
pify@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
|
||||
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
|
||||
|
||||
pify@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
||||
|
@ -2645,6 +2842,15 @@ raw-body@2.4.0:
|
|||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
read-pkg@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
|
||||
integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
|
||||
dependencies:
|
||||
load-json-file "^4.0.0"
|
||||
normalize-package-data "^2.3.2"
|
||||
path-type "^3.0.0"
|
||||
|
||||
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
|
@ -2741,6 +2947,13 @@ resolve-url@^0.2.1:
|
|||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||
|
||||
resolve@^1.10.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
ret@~0.1.10:
|
||||
version "0.1.15"
|
||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||
|
@ -2753,13 +2966,6 @@ rimraf@^2.5.4, rimraf@^2.6.3:
|
|||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rimraf@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
|
||||
|
@ -2815,7 +3021,7 @@ schema-utils@^2.6.5, schema-utils@^2.6.6:
|
|||
ajv "^6.12.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
semver@^5.5.0, semver@^5.6.0:
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
@ -2906,6 +3112,11 @@ shebang-regex@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
|
||||
shell-quote@^1.6.1:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
|
||||
integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
|
@ -2980,6 +3191,32 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
|
|||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
|
||||
dependencies:
|
||||
spdx-expression-parse "^3.0.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-exceptions@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
|
||||
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
|
||||
|
||||
spdx-expression-parse@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
|
||||
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
|
||||
dependencies:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-license-ids@^3.0.0:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654"
|
||||
integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
|
||||
|
||||
split-string@^3.0.1, split-string@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
|
||||
|
@ -3048,6 +3285,30 @@ string-width@^3.0.0, string-width@^3.1.0:
|
|||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^5.1.0"
|
||||
|
||||
string.prototype.padend@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz#dc08f57a8010dc5c153550318f67e13adbb72ac3"
|
||||
integrity sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.0-next.1"
|
||||
|
||||
string.prototype.trimend@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
|
||||
integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.5"
|
||||
|
||||
string.prototype.trimstart@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
|
||||
integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.5"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
|
@ -3069,6 +3330,11 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
|
|||
dependencies:
|
||||
ansi-regex "^4.1.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
|
@ -3140,13 +3406,6 @@ timers-browserify@^2.0.4:
|
|||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
tmp@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
|
||||
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
|
||||
dependencies:
|
||||
rimraf "^3.0.0"
|
||||
|
||||
to-arraybuffer@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||
|
@ -3334,6 +3593,14 @@ v8-compile-cache@2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
|
||||
integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
|
||||
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
|
||||
dependencies:
|
||||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
vary@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
|
|
Loading…
Reference in New Issue