81 lines
1.7 KiB
TypeScript
81 lines
1.7 KiB
TypeScript
|
import { createHash } from "crypto";
|
||
|
import { Request, Response } from "express";
|
||
|
import { readdirSync, existsSync, mkdirSync, statSync, readFileSync } from "fs";
|
||
|
import path from "path";
|
||
|
|
||
|
class Sync {
|
||
|
constructor() {
|
||
|
this.root = path.join(process.cwd(), "public");
|
||
|
|
||
|
if (!existsSync(this.root)) {
|
||
|
mkdirSync(this.root);
|
||
|
}
|
||
|
|
||
|
this.update();
|
||
|
}
|
||
|
|
||
|
async update() {
|
||
|
return new Promise<void>((res, rej) => {
|
||
|
this.files = readdirSync(this.root).filter(async (v) => {
|
||
|
let f = path.join(this.root, v);
|
||
|
if (existsSync(f)) {
|
||
|
let s = statSync(f);
|
||
|
return s.isFile() && s.size > 1;
|
||
|
} else {
|
||
|
await this.update();
|
||
|
res();
|
||
|
}
|
||
|
})
|
||
|
|
||
|
let c = createHash("sha1");
|
||
|
|
||
|
this.files.forEach(async (v) => {
|
||
|
let f = path.join(this.root, v);
|
||
|
|
||
|
if (existsSync(f))
|
||
|
c.update(readFileSync(f))
|
||
|
else {
|
||
|
await this.update();
|
||
|
res();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
this.checksum = c.digest("hex");
|
||
|
res();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
root: string;
|
||
|
files: string[];
|
||
|
checksum: string;
|
||
|
}
|
||
|
|
||
|
const state: Sync = new Sync();
|
||
|
|
||
|
let sync = async (req: Request, res: Response) => {
|
||
|
switch (req.method) {
|
||
|
case "GET": { // "Update me"
|
||
|
await state.update();
|
||
|
res.write(JSON.stringify({
|
||
|
checksum: state.checksum,
|
||
|
files: state.files
|
||
|
}));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "POST": { // "Am I up to date?"
|
||
|
await state.update();
|
||
|
let checksum = req.body;
|
||
|
|
||
|
if (checksum == state.checksum)
|
||
|
res.write('{"valid": true}');
|
||
|
else
|
||
|
res.write('{"valid": false}');
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
res.end();
|
||
|
}
|
||
|
|
||
|
export default sync;
|