forked from tools/josh
1
0
Fork 0

Update to TypeScript 3.7

And clear empty lines and consistify error usage.
This commit is contained in:
Florine W. Dekker 2019-11-06 14:47:14 +01:00
parent f5126065bf
commit 67898842ba
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
8 changed files with 81 additions and 98 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@ -30,7 +30,7 @@
"mocha": "^6.2.2",
"ts-loader": "^6.2.1",
"ts-node": "^8.4.1",
"typescript": "^3.6.4",
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}

View File

@ -2,7 +2,7 @@ import * as Cookies from "js-cookie";
import "./Extensions"
import {Environment} from "./Environment";
import {Directory, File, FileSystem, Path} from "./FileSystem"
import {IllegalStateError} from "./Shared";
import {IllegalArgumentError, IllegalStateError} from "./Shared";
import {InputArgs} from "./Shell";
import {EscapeCharacters} from "./Terminal";
import {UserList} from "./UserList";
@ -252,10 +252,9 @@ export class Commands {
private createUsageErrorOutput(commandName: string, errorMessage: string | undefined): string {
const command = this.commands[commandName];
if (command === undefined)
throw new Error(`Unknown command \`${commandName}\`.`);
throw new IllegalArgumentError(`Unknown command \`${commandName}\`.`);
return "" +
`Invalid usage of ${commandName}.${errorMessage === undefined ? "" : ` ${errorMessage}`}
return `Invalid usage of ${commandName}. ${errorMessage ?? ""}
<b>Usage</b>
${command.usage}`.trimLines();
@ -337,8 +336,7 @@ export class Commands {
const commandName = it.toLowerCase();
const command = this.commands[commandName];
return "" +
`<b>Name</b>
return `<b>Name</b>
${commandName}
<b>Summary</b>
@ -360,8 +358,7 @@ export class Commands {
const commandEntries = commandNames
.map((it, i) => `${commandLinks[i]}${this.commands[it].summary}`);
return "" +
`The source code of this website is <a href="https://git.fwdekker.com/FWDekker/fwdekker.com">available on git</a>.
return `The source code of this website is <a href="https://git.fwdekker.com/FWDekker/fwdekker.com">available on git</a>.
<b>List of commands</b>
${commandEntries.join("\n")}
@ -478,8 +475,7 @@ export class Commands {
});
setTimeout(() => location.reload(), 2000);
return "" +
`Shutdown NOW!
return `Shutdown NOW!
*** FINAL System shutdown message from ${userName}@fwdekker.com ***
@ -578,19 +574,19 @@ export class Commands {
// Move into directory
if (!(this.fileSystem.get(destination) instanceof Directory)) {
if (sources.length === 1)
throw new Error(`'${destination}' already exists.`);
throw new IllegalArgumentError(`'${destination}' already exists.`);
else
throw new Error(`'${destination}' is not a directory.`);
throw new IllegalArgumentError(`'${destination}' is not a directory.`);
}
mappings = sources.map(source => [source, destination.getChild(source.fileName)]);
} else {
// Move to exact location
if (sources.length !== 1)
throw new Error(`'${destination}' is not a directory.`);
throw new IllegalArgumentError(`'${destination}' is not a directory.`);
if (!(this.fileSystem.get(destination.parent) instanceof Directory))
throw new Error(`'${destination.parent}' is not a directory.`);
throw new IllegalArgumentError(`'${destination.parent}' is not a directory.`);
mappings = sources.map(path => [path, destination]);
}

View File

@ -94,10 +94,7 @@ export class Environment {
* @param def the default value to return in case there is no environment variable with the given key
*/
getOrDefault(key: string, def: string): string {
const value = this._variables[key];
if (value === undefined)
return def;
return value;
return this._variables[key] ?? def;
}
/**

View File

@ -7,7 +7,7 @@ interface String {
/**
* Returns this string with all leading and trailing whitespace removed from each line.
*/
String.prototype.trimLines = function (): string {
String.prototype.trimLines = function(): string {
return this.split("\n").map(it => it.trim()).join("\n");
};
@ -17,7 +17,7 @@ String.prototype.trimLines = function (): string {
* @param regex the regex to find matches with
* @param replacement the string to replace matches with
*/
String.prototype.replaceAll = function (regex: RegExp, replacement: string): string {
String.prototype.replaceAll = function(regex: RegExp, replacement: string): string {
let string = this.toString();
while (regex.test(string))
@ -37,7 +37,7 @@ interface Array<T> {
* @param transform transforms elements of the array into a string that is used for comparing
* @param caseSensitive `true` if and only if the comparator should be sensitive to the case of characters
*/
Array.prototype.sortAlphabetically = function (transform: (_: any) => string = (it) => it,
Array.prototype.sortAlphabetically = function(transform: (_: any) => string = (it) => it,
caseSensitive: boolean = true) {
return this.sort((a, b) => {
const aName = caseSensitive ? transform(a) : transform(a).toLowerCase();

View File

@ -56,14 +56,14 @@ export class FileSystem {
if (createParents)
this.add(target.parent, new Directory(), true);
else
throw new Error(`The directory '${target.parent}' does not exist.`);
throw new IllegalArgumentError(`The directory '${target.parent}' does not exist.`);
}
const parent = this.get(target.parent);
if (!(parent instanceof Directory))
throw new Error(`'${target.parent}' is not a directory.`);
throw new IllegalArgumentError(`'${target.parent}' is not a directory.`);
if (parent.hasNode(target.fileName))
throw new Error(`A file or directory already exists at '${target}'.`);
throw new IllegalArgumentError(`A file or directory already exists at '${target}'.`);
parent.addNode(target.fileName, node);
}
@ -79,13 +79,13 @@ export class FileSystem {
*/
copy(source: Path, destination: Path, isRecursive: boolean): void {
if (destination.ancestors.indexOf(source) >= 0)
throw new Error("Cannot move directory into itself.");
throw new IllegalArgumentError("Cannot move directory into itself.");
const sourceNode = this.get(source);
if (sourceNode === undefined)
throw new Error(`File or directory '${source}' does not exist.`);
throw new IllegalArgumentError(`File or directory '${source}' does not exist.`);
if (sourceNode instanceof Directory && !isRecursive)
throw new Error(`'${source}' is a directory.`);
throw new IllegalArgumentError(`'${source}' is a directory.`);
this.add(destination, sourceNode.copy(), false);
}
@ -116,7 +116,7 @@ export class FileSystem {
return true;
const parent = this.get(target.parent);
if (parent === undefined || !(parent instanceof Directory))
if (!(parent instanceof Directory))
return false;
return parent.hasNode(target.fileName);
@ -132,11 +132,11 @@ export class FileSystem {
*/
move(source: Path, destination: Path): void {
if (destination.ancestors.indexOf(source) >= 0)
throw new Error("Cannot move directory into itself.");
throw new IllegalArgumentError("Cannot move directory into itself.");
const sourceNode = this.get(source);
if (sourceNode === undefined)
throw new Error(`File or directory '${source}' does not exist.`);
throw new IllegalArgumentError(`File or directory '${source}' does not exist.`);
this.add(destination, sourceNode, false);
this.remove(source, true, true, false);
@ -157,7 +157,7 @@ export class FileSystem {
if (force)
return;
else
throw new Error(`The file or directory '${targetPath}' does not exist.`);
throw new IllegalArgumentError(`The file or directory '${targetPath}' does not exist.`);
}
const parent = this.get(targetPath.parent);
@ -166,9 +166,9 @@ export class FileSystem {
if (target instanceof Directory) {
if (targetPath.toString() === "/" && !noPreserveRoot)
throw new Error(`Cannot remove root directory.`);
throw new IllegalArgumentError(`Cannot remove root directory.`);
if (!recursive)
throw new Error(`'${targetPath}' is a directory.`);
throw new IllegalArgumentError(`'${targetPath}' is a directory.`);
}
parent.removeNode(targetPath.fileName);
@ -393,7 +393,7 @@ export class Directory extends Node {
*/
getNode(name: string): Node {
if (!this.hasNode(name))
throw new Error(`Directory does not have a node with name '${name}'.`);
throw new IllegalArgumentError(`Directory does not have a node with name '${name}'.`);
return this._nodes[name];
}

View File

@ -78,7 +78,7 @@ export function parseCssPixels(string: string | null): number {
return 0;
} else {
if (!string.endsWith("px"))
throw new Error("CSS string is not expressed in pixels.");
throw new IllegalArgumentError("CSS string is not expressed in pixels.");
return parseFloat(string);
}

View File

@ -2,7 +2,7 @@ import * as Cookies from "js-cookie";
import {Commands} from "./Commands";
import {Environment} from "./Environment";
import {Directory, File, FileSystem, Node, Path} from "./FileSystem";
import {asciiHeaderHtml, IllegalStateError, stripHtmlTags} from "./Shared";
import {asciiHeaderHtml, IllegalArgumentError, IllegalStateError, stripHtmlTags} from "./Shared";
import {EscapeCharacters, InputHistory} from "./Terminal";
import {UserList} from "./UserList";
@ -62,8 +62,7 @@ export class Shell {
if (this.environment.get("user") === "")
return "";
return "" +
`${asciiHeaderHtml}
return `${asciiHeaderHtml}
Student MSc Computer Science <span class="smallScreenOnly">
</span>@ <a href="https://www.tudelft.nl/en/">TU Delft</a>, the Netherlands
@ -80,24 +79,15 @@ export class Shell {
generatePrefix(): string {
const userName = this.environment.get("user");
if (userName === "") {
if (this.attemptUser === undefined)
return "login as: ";
else
return `Password for ${this.attemptUser}@fwdekker.com: `;
return this.attemptUser === undefined
? "login as: "
: `Password for ${this.attemptUser}@fwdekker.com: `;
}
const cwd = new Path(this.environment.get("cwd"));
const parts = cwd.ancestors.reverse();
parts.push(cwd);
const link = parts
.map(part => {
const node = this.fileSystem.get(part);
if (node === undefined)
throw new IllegalStateError(`Ancestor '${part}' of cwd does not exist.`);
return node.nameString(part.fileName + "/", part);
})
.join("");
const link = cwd.ancestors.reverse()
.concat(cwd)
.map(part => this.fileSystem.get(part)?.nameString(part.fileName + "/", part)).join("");
return `${userName}@fwdekker.com <span class="prefixPath">${link}</span>&gt; `;
}
@ -178,7 +168,7 @@ export class Shell {
const target = this.fileSystem.get(path);
if (!(target instanceof File))
throw new Error("File unexpectedly disappeared since last check.");
throw new IllegalStateError("File unexpectedly disappeared since last check.");
if (append)
target.contents += data;
@ -427,7 +417,7 @@ export class InputParser {
switch (char) {
case "\\":
if (i === input.length - 1)
throw new Error("Unexpected end of input. `\\` was used but there was nothing to escape.");
throw new IllegalArgumentError("Unexpected end of input. `\\` was used but there was nothing to escape.");
const nextChar = input[i + 1];
if (isInSingleQuotes || isInDoubleQuotes)
@ -485,7 +475,7 @@ export class InputParser {
}
if (isInSingleQuotes || isInDoubleQuotes)
throw new Error("Unexpected end of input. Missing closing quotation mark.");
throw new IllegalArgumentError("Unexpected end of input. Missing closing quotation mark.");
return [token, ""];
}
@ -544,7 +534,7 @@ export class InputParser {
const argsParts = arg.split(/=(.*)/, 2);
if (argsParts.length === 0 || argsParts.length > 2)
throw new Error("Unexpected number of parts.");
throw new IllegalArgumentError("Unexpected number of parts.");
if (argsParts[0].indexOf(' ') >= 0)
break;
@ -565,7 +555,7 @@ export class InputParser {
options[keys] = value;
} else {
if (value !== null)
throw new Error("Cannot assign value to multiple short options.");
throw new IllegalArgumentError("Cannot assign value to multiple short options.");
for (const key of keys)
options[key] = value;