Migrated to pacel and removed deno
This commit is contained in:
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"deno.enable": true,
|
||||
"deno.enable": false,
|
||||
"deno.unstable": true
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"source": "src/server.ts",
|
||||
"main": "dist/server.js",
|
||||
"scripts": {
|
||||
"build": "parcel build",
|
||||
"watch": "parcel watch",
|
||||
"start": "node dist/server.js",
|
||||
"nodemon": "nodemon dist/server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/express": "^4.17.13",
|
||||
"nodemon": "^2.0.15",
|
||||
"parcel": "^2.3.2"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls | entr -s 'deno run --allow-net --allow-read --allow-write server.ts'
|
||||
@@ -1,133 +0,0 @@
|
||||
import * as path from "https://deno.land/std@0.125.0/path/mod.ts";
|
||||
import FileInfo = Deno.FileInfo;
|
||||
|
||||
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
|
||||
import { oakCors } from "https://deno.land/x/cors@v1.2.0/mod.ts";
|
||||
import { readAll } from "https://deno.land/std@0.126.0/streams/mod.ts";
|
||||
import { exists } from "https://deno.land/std@0.126.0/fs/mod.ts";
|
||||
|
||||
import { recursiveReaddir } from "https://deno.land/x/recursive_readdir@v2.0.0/mod.ts";
|
||||
|
||||
type PageMeta = {
|
||||
name: string;
|
||||
lastModified: number;
|
||||
};
|
||||
|
||||
const fsPrefix = "/fs";
|
||||
const pagesPath = "../pages";
|
||||
|
||||
const fsRouter = new Router();
|
||||
|
||||
fsRouter.use(oakCors({ methods: ["OPTIONS", "GET", "PUT", "POST", "DELETE"] }));
|
||||
|
||||
fsRouter.get("/", async (context) => {
|
||||
const localPath = pagesPath;
|
||||
let fileNames: PageMeta[] = [];
|
||||
const markdownFiles = (await recursiveReaddir(localPath)).filter(
|
||||
(file: string) => path.extname(file) === ".md"
|
||||
);
|
||||
for (const p of markdownFiles) {
|
||||
const stat = await Deno.stat(p);
|
||||
fileNames.push({
|
||||
name: p.substring(
|
||||
localPath.length + 1,
|
||||
p.length - path.extname(p).length
|
||||
),
|
||||
lastModified: stat.mtime?.getTime()!,
|
||||
});
|
||||
}
|
||||
context.response.body = JSON.stringify(fileNames);
|
||||
});
|
||||
|
||||
fsRouter.get("/:page(.*)", async (context) => {
|
||||
const pageName = context.params.page;
|
||||
const localPath = `${pagesPath}/${pageName}.md`;
|
||||
try {
|
||||
const stat = await Deno.stat(localPath);
|
||||
const text = await Deno.readTextFile(localPath);
|
||||
context.response.headers.set("Last-Modified", "" + stat.mtime?.getTime());
|
||||
context.response.body = text;
|
||||
} catch (e) {
|
||||
context.response.status = 404;
|
||||
context.response.body = "";
|
||||
}
|
||||
});
|
||||
|
||||
fsRouter.options("/:page(.*)", async (context) => {
|
||||
const localPath = `${pagesPath}/${context.params.page}.md`;
|
||||
try {
|
||||
const stat = await Deno.stat(localPath);
|
||||
context.response.headers.set("Content-length", `${stat.size}`);
|
||||
context.response.headers.set("Last-Modified", "" + stat.mtime?.getTime());
|
||||
} catch (e) {
|
||||
// For CORS
|
||||
context.response.status = 200;
|
||||
context.response.body = "";
|
||||
}
|
||||
});
|
||||
|
||||
fsRouter.put("/:page(.*)", async (context) => {
|
||||
const pageName = context.params.page;
|
||||
const localPath = `${pagesPath}/${pageName}.md`;
|
||||
const existingPage = await exists(localPath);
|
||||
let dirName = path.dirname(localPath);
|
||||
if (!(await exists(dirName))) {
|
||||
await Deno.mkdir(dirName, {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
let file;
|
||||
try {
|
||||
file = await Deno.create(localPath);
|
||||
} catch (e) {
|
||||
console.error("Error opening file for writing", localPath, e);
|
||||
context.response.status = 500;
|
||||
context.response.body = e.message;
|
||||
return;
|
||||
}
|
||||
const result = context.request.body({ type: "reader" });
|
||||
const text = await readAll(result.value);
|
||||
file.write(text);
|
||||
file.close();
|
||||
console.log("Wrote to", localPath);
|
||||
const stat = await Deno.stat(localPath);
|
||||
context.response.status = existingPage ? 200 : 201;
|
||||
context.response.headers.set("Last-Modified", "" + stat.mtime?.getTime());
|
||||
context.response.body = "OK";
|
||||
});
|
||||
|
||||
fsRouter.delete("/:page(.*)", async (context) => {
|
||||
const pageName = context.params.page;
|
||||
const localPath = `${pagesPath}/${pageName}.md`;
|
||||
try {
|
||||
await Deno.remove(localPath);
|
||||
} catch (e) {
|
||||
console.error("Error deleting file", localPath, e);
|
||||
context.response.status = 500;
|
||||
context.response.body = e.message;
|
||||
return;
|
||||
}
|
||||
console.log("Deleted", localPath);
|
||||
|
||||
context.response.body = "OK";
|
||||
});
|
||||
|
||||
const app = new Application();
|
||||
app.use(
|
||||
new Router()
|
||||
.use(fsPrefix, fsRouter.routes(), fsRouter.allowedMethods())
|
||||
.routes()
|
||||
);
|
||||
app.use(async (context, next) => {
|
||||
try {
|
||||
await context.send({
|
||||
root: "../webapp/dist",
|
||||
index: "index.html",
|
||||
});
|
||||
} catch {
|
||||
await context.send({ root: "../webapp/dist", path: "index.html" });
|
||||
// next();
|
||||
}
|
||||
});
|
||||
|
||||
await app.listen({ port: 2222 });
|
||||
@@ -0,0 +1,136 @@
|
||||
import cors from "cors";
|
||||
import express from "express";
|
||||
import fs from "fs";
|
||||
import { readdir, readFile, stat, unlink } from "fs/promises";
|
||||
import path from "path";
|
||||
import stream from "stream";
|
||||
import {} from "stream/promises";
|
||||
import { promisify } from "util";
|
||||
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
const pipeline = promisify(stream.pipeline);
|
||||
const pagesPath = "../pages";
|
||||
const distDir = `${__dirname}/../../webapp/dist`;
|
||||
|
||||
type PageMeta = {
|
||||
name: string;
|
||||
lastModified: number;
|
||||
};
|
||||
|
||||
app.use("/", express.static(distDir));
|
||||
|
||||
let fsRouter = express.Router();
|
||||
|
||||
// Page list
|
||||
fsRouter.route("/").get(async (req, res) => {
|
||||
const localPath = pagesPath;
|
||||
let fileNames: PageMeta[] = [];
|
||||
|
||||
async function walkPath(dir: string) {
|
||||
let files = await readdir(dir);
|
||||
for (let file of files) {
|
||||
const fullPath = path.join(dir, file);
|
||||
let s = await stat(fullPath);
|
||||
if (s.isDirectory()) {
|
||||
await walkPath(fullPath);
|
||||
} else {
|
||||
if (path.extname(file) === ".md") {
|
||||
fileNames.push({
|
||||
name: fullPath.substring(pagesPath.length + 1, fullPath.length - 3),
|
||||
lastModified: s.mtime.getTime(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await walkPath(pagesPath);
|
||||
res.json(fileNames);
|
||||
});
|
||||
|
||||
fsRouter
|
||||
.route(/\/(.+)/)
|
||||
.get(async (req, res) => {
|
||||
let reqPath = req.params[0];
|
||||
console.log("Getting", reqPath);
|
||||
try {
|
||||
const localPath = path.join(pagesPath, reqPath + ".md");
|
||||
const s = await stat(localPath);
|
||||
let content = await readFile(localPath, "utf8");
|
||||
res.status(200);
|
||||
res.header("Last-Modified", "" + s.mtime.getTime());
|
||||
res.header("Content-Type", "text/markdown");
|
||||
res.send(content);
|
||||
} catch (e) {
|
||||
res.status(200);
|
||||
res.send("");
|
||||
}
|
||||
})
|
||||
.put(async (req, res) => {
|
||||
let reqPath = req.params[0];
|
||||
|
||||
let localPath = path.join(pagesPath, reqPath + ".md");
|
||||
|
||||
try {
|
||||
await pipeline(req, fs.createWriteStream(localPath));
|
||||
console.log(`Wrote to ${localPath}`);
|
||||
const s = await stat(localPath);
|
||||
res.status(200);
|
||||
res.header("Last-Modified", "" + s.mtime.getTime());
|
||||
res.send("OK");
|
||||
} catch (err) {
|
||||
res.status(500);
|
||||
res.send("Write failed");
|
||||
console.error("Pipeline failed", err);
|
||||
}
|
||||
})
|
||||
.options(async (req, res) => {
|
||||
let reqPath = req.params[0];
|
||||
try {
|
||||
const localPath = path.join(pagesPath, reqPath + ".md");
|
||||
const s = await stat(localPath);
|
||||
res.status(200);
|
||||
res.header("Last-Modified", "" + s.mtime.getTime());
|
||||
res.header("Content-length", "" + s.size);
|
||||
res.header("Content-Type", "text/markdown");
|
||||
res.send("");
|
||||
} catch (e) {
|
||||
res.status(200);
|
||||
res.send("");
|
||||
}
|
||||
})
|
||||
.delete(async (req, res) => {
|
||||
let reqPath = req.params[0];
|
||||
const localPath = path.join(pagesPath, reqPath + ".md");
|
||||
try {
|
||||
await unlink(localPath);
|
||||
res.status(200);
|
||||
res.send("OK");
|
||||
} catch (e) {
|
||||
console.error("Error deleting file", localPath, e);
|
||||
res.status(500);
|
||||
res.send("OK");
|
||||
}
|
||||
});
|
||||
|
||||
app.use(
|
||||
"/fs",
|
||||
cors({
|
||||
methods: "GET,HEAD,PUT,OPTIONS,POST,DELETE",
|
||||
preflightContinue: true,
|
||||
}),
|
||||
fsRouter
|
||||
);
|
||||
|
||||
// Fallback, serve index.html
|
||||
let cachedIndex: string | undefined = undefined;
|
||||
app.get("/*", async (req, res) => {
|
||||
if (!cachedIndex) {
|
||||
cachedIndex = await readFile(`${distDir}/index.html`, "utf8");
|
||||
}
|
||||
res.status(200).header("Content-Type", "text/html").send(cachedIndex);
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server istening on port ${port}`);
|
||||
});
|
||||
@@ -1,2 +0,0 @@
|
||||
import { parser } from "https://unpkg.com/@lezer/markdown?module";
|
||||
console.log(parser);
|
||||
+2650
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user