forked from tools/josh
parent
ef49ed1c8f
commit
6901f5a02c
Binary file not shown.
10
package.json
10
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "fwdekker.com",
|
||||
"version": "0.37.5",
|
||||
"version": "0.38.0",
|
||||
"description": "The source code of [my personal website](https://fwdekker.com/).",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "dist/bundle.js",
|
||||
|
@ -36,12 +36,12 @@
|
|||
"grunt-webpack": "^4.0.2",
|
||||
"jsdom": "^16.4.0",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"mocha": "^8.1.1",
|
||||
"mocha": "^8.1.3",
|
||||
"nyc": "^15.1.0",
|
||||
"ts-loader": "^8.0.3",
|
||||
"ts-loader": "^8.0.4",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.0.2",
|
||||
"webpack": "^4.44.1",
|
||||
"typescript": "^4.0.3",
|
||||
"webpack": "^4.44.2",
|
||||
"webpack-cli": "^3.3.12"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,75 +8,89 @@ import {HashProvider, User} from "./UserList";
|
|||
* A file system.
|
||||
*/
|
||||
export class FileSystem {
|
||||
static navRoot: Directory;
|
||||
/**
|
||||
* The root directory.
|
||||
*/
|
||||
readonly root: Directory;
|
||||
|
||||
|
||||
/**
|
||||
* Loads the contents of my home directory based on the navigation API of fwdekker.com.
|
||||
*
|
||||
* @return an empty promise :'(
|
||||
*/
|
||||
static async loadNavApi(): Promise<any> {
|
||||
await fetch("https://fwdekker.com/api/nav/")
|
||||
.then(it => it.json())
|
||||
.then(json => this.navRoot = this.unpack(json)[1] as Directory)
|
||||
.catch(e => {
|
||||
console.error("Failed to fetch navigation elements", e);
|
||||
this.navRoot = new Directory();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks the given entry from the navigation API.
|
||||
*
|
||||
* @param entry the entry to unpack
|
||||
* @return the name and the (traversed and filled) node unpacked from the given entry
|
||||
* @private
|
||||
*/
|
||||
private static unpack(entry: any): [string, Node] {
|
||||
const name = entry.name?.toLowerCase()?.replace(/ /g, "-") ?? "";
|
||||
|
||||
if (entry.entries.length === 0)
|
||||
return [`${name}.lnk`, new File(entry.link)];
|
||||
|
||||
const dir = new Directory();
|
||||
entry.entries.forEach((child: any) => dir.add(...(this.unpack(child))))
|
||||
return [name, dir];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new file system.
|
||||
*
|
||||
* @param root the directory to set as the root
|
||||
*/
|
||||
constructor(root: Directory | undefined = undefined) {
|
||||
if (root === undefined)
|
||||
this.root =
|
||||
new Directory({
|
||||
"bin": Object.keys(commandBinaries)
|
||||
.reduce((acc, key) => {
|
||||
acc.add(key, new File(commandBinaries[key]));
|
||||
return acc;
|
||||
}, new Directory()),
|
||||
"dev": new Directory({
|
||||
"null": new NullFile()
|
||||
}),
|
||||
"etc": new Directory({
|
||||
"passwd": new File(
|
||||
[
|
||||
new User("root", HashProvider.default.hashPassword("g9PjKu"), "/root",
|
||||
"You're a hacker, Harry!"),
|
||||
new User("felix", HashProvider.default.hashPassword("password"), undefined,
|
||||
"Who are <i>you</i>?")
|
||||
].map(it => User.toString(it)).join("\n") + "\n"
|
||||
)
|
||||
}),
|
||||
"home": new Directory({
|
||||
"felix": new Directory({
|
||||
"personal": new Directory({
|
||||
"blog.lnk": new File("https://blog.fwdekker.com/"),
|
||||
"nukapedia.lnk": new File("https://fallout.wikia.com/wiki/User:FDekker"),
|
||||
"steam.lnk": new File("https://steamcommunity.com/id/Waflix"),
|
||||
}),
|
||||
"projects": new Directory({
|
||||
"converter.lnk": new File("https://fwdekker.com/tools/converter/"),
|
||||
"dice.lnk": new File("https://fwdekker.com/tools/dice/"),
|
||||
"doomsday.lnk": new File("https://fwdekker.com/tools/doomsday/"),
|
||||
"fo76-dumps.lnk": new File("https://github.com/FWDekker/fo76-dumps"),
|
||||
"josh.lnk": new File("https://git.fwdekker.com/FWDekker/fwdekker.com"),
|
||||
"random-fo76.lnk": new File("https://fwdekker.com/tools/random-fo76/"),
|
||||
"randomness.lnk": new File("https://github.com/FWDekker/intellij-randomness"),
|
||||
"schaapi.lnk": new File("https://cafejojo.org/schaapi"),
|
||||
"simplify-fractions.lnk": new File("https://fwdekker.com/tools/simplify-fractions/"),
|
||||
}),
|
||||
"social": new Directory({
|
||||
"gitea.lnk": new File("https://git.fwdekker.com/explore/"),
|
||||
"github.lnk": new File("https://github.com/FWDekker/"),
|
||||
"stackoverflow.lnk": new File("https://stackoverflow.com/u/3307872"),
|
||||
"linkedin.lnk": new File("https://www.linkedin.com/in/fwdekker/"),
|
||||
}),
|
||||
"me_irl.jpg": new File("https://static.fwdekker.com/img/avatar.jpg", "lnk"),
|
||||
"pgp.pub": new File("https://static.fwdekker.com/misc/pgp.pub.txt", "lnk"),
|
||||
"privacy-policy.html": new File("https://fwdekker.com/privacy/", "lnk"),
|
||||
"resume.pdf": new File("https://static.fwdekker.com/misc/resume.pdf", "lnk"),
|
||||
})
|
||||
}),
|
||||
"root": new Directory({
|
||||
"password.txt": new File("root: g9PjKu")
|
||||
})
|
||||
});
|
||||
else
|
||||
if (root !== undefined) {
|
||||
this.root = root;
|
||||
return;
|
||||
}
|
||||
|
||||
this.root = new Directory({
|
||||
"bin": Object.keys(commandBinaries)
|
||||
.reduce((acc, key) => {
|
||||
acc.add(key, new File(commandBinaries[key]));
|
||||
return acc;
|
||||
}, new Directory()),
|
||||
"dev": new Directory({
|
||||
"null": new NullFile(),
|
||||
}),
|
||||
"etc": new Directory({
|
||||
"passwd": new File(
|
||||
[
|
||||
new User("root", HashProvider.default.hashPassword("g9PjKu"), "/root",
|
||||
"You're a hacker, Harry!"),
|
||||
new User("felix", HashProvider.default.hashPassword("password"), undefined,
|
||||
"Who are <i>you</i>?")
|
||||
].map(it => User.toString(it)).join("\n") + "\n"
|
||||
),
|
||||
}),
|
||||
"home": new Directory({
|
||||
"felix": new Directory({
|
||||
"pgp.pub": new File("https://static.fwdekker.com/misc/pgp.pub.txt", "lnk"),
|
||||
"privacy-policy.html": new File("https://fwdekker.com/privacy/", "lnk"),
|
||||
"resume.pdf": new File("https://static.fwdekker.com/misc/resume.pdf", "lnk"),
|
||||
}),
|
||||
}),
|
||||
"root": new Directory({
|
||||
"password.txt": new File("root: g9PjKu"),
|
||||
}),
|
||||
});
|
||||
(this.get(new Path("home", "felix")) as Directory).addAll(FileSystem.navRoot);
|
||||
}
|
||||
|
||||
|
||||
|
@ -563,6 +577,15 @@ export class Directory extends Node {
|
|||
this._nodes[name] = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds (references to) all files in the given directory to this directory.
|
||||
*
|
||||
* @param directory the directory of which to add the children to this directory
|
||||
*/
|
||||
addAll(directory: Directory): void {
|
||||
Object.keys(directory.nodes).forEach(name => this.add(name, directory.get(name)!));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the node with the given name.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as semver from "semver";
|
||||
import {FileSystem} from "./FileSystem";
|
||||
import {Persistence} from "./Persistence";
|
||||
import {addOnLoad, ExpectedGoodbyeError, q} from "./Shared";
|
||||
import {Terminal} from "./Terminal";
|
||||
|
@ -58,7 +59,9 @@ addOnLoad(() => {
|
|||
/**
|
||||
* Initializes the application.
|
||||
*/
|
||||
addOnLoad(() => {
|
||||
addOnLoad(async () => {
|
||||
await FileSystem.loadNavApi();
|
||||
|
||||
window.terminal = new Terminal(
|
||||
q("#terminal"),
|
||||
q("#terminalInputField"),
|
||||
|
|
Loading…
Reference in New Issue