Skip to content

Instantly share code, notes, and snippets.

@captbaritone
Created September 24, 2019 14:15
Show Gist options
  • Save captbaritone/797f01cce1e530ff68707c1f8c48e25d to your computer and use it in GitHub Desktop.
Save captbaritone/797f01cce1e530ff68707c1f8c48e25d to your computer and use it in GitHub Desktop.
maki compiler as a service
const express = require("express");
const path = require("path");
const fsExtra = require("fs-extra");
const os = require("os");
const app = express();
const port = 3000;
const { exec } = require("child_process");
const Busboy = require("busboy");
const tmpDir = os.tmpdir();
const INTERFACES_PATH = path.join(__dirname, "resources", "lib");
const COMPILERS_DIR = path.join(__dirname, "resources", "compilers");
const TMP_PREFIX = "maki";
function mkTempDir() {
return new Promise(async (resolve, reject) => {
fsExtra.mkdtemp(path.join(tmpDir, TMP_PREFIX), async (err, folder) => {
if (err != null) {
return reject(err);
}
resolve(folder);
});
});
}
function readFile(req) {
return new Promise((resolve, reject) => {
var busboy = new Busboy({ headers: req.headers });
busboy.on("file", (fieldname, file, fileName, encoding, mimetype) => {
file.on("data", buffer => {
resolve([fileName, buffer]);
});
file.on("end", data => {
// TODO: What happens here?
});
});
req.pipe(busboy);
});
}
function replaceExt(fileName, ext) {
return `${path.basename(fileName, path.extname(fileName))}.${ext}`;
}
async function compile(buffer, fileName) {
const tempDir = await mkTempDir();
fsExtra.copySync(INTERFACES_PATH, path.join(tempDir, "lib"));
const sourcePath = path.join(tempDir, fileName);
fsExtra.writeFileSync(sourcePath, buffer);
const destPath = replaceExt(sourcePath, "maki");
return new Promise((resolve, reject) => {
const options = { cwd: COMPILERS_DIR };
exec(`mc.exe ${sourcePath}`, options, (err, stdout, stderr) => {
console.err(stderr);
console.log(stdout);
if (err != null) {
return reject(err);
}
const result = fsExtra.readFileSync(destPath);
resolve(result);
});
});
}
app.post("/", async (req, res, next) => {
const [fileName, buffer] = await readFile(req);
try {
const compiled = await compile(buffer, fileName);
res.send(compiled);
} catch (e) {
next(e);
}
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment