Skip to content

Commit

Permalink
Merge pull request #136 from sensebox/chore/deps
Browse files Browse the repository at this point in the history
Update dependencies
  • Loading branch information
felixerdy authored Dec 20, 2024
2 parents 70ee113 + 222047c commit 8bdca90
Show file tree
Hide file tree
Showing 11 changed files with 1,124 additions and 547 deletions.
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@
"name": "blockly-remote-compiler",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"author": "Gerald Pape <[email protected]>",
"license": "MIT",
"scripts": {
"start": "node src/index.js",
"test": "mocha --exit --timeout 60000 --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporters.json"
},
"dependencies": {
"body-parser": "^1.18.2",
"body-parser": "^1.20.3",
"connect": "^3.6.6",
"morgan": "^1.9.1",
"response-time": "^2.3.2",
"rimraf": "^3.0.2",
"response-time": "^2.3.3",
"rimraf": "^6.0.1",
"spawn-promise": "^0.1.8",
"tempy": "^0.2.1"
"tempy": "^3.1.0"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-http": "^4.2.0",
"mocha": "^5.2.0",
"chai": "^5.1.2",
"chai-http": "^5.1.1",
"mocha": "^11.0.1",
"mocha-ctrf-json-reporter": "^0.0.6",
"mocha-multi-reporters": "^1.5.1"
}
Expand Down
39 changes: 17 additions & 22 deletions src/builder.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
const spawn = require("spawn-promise");
const tempy = require("tempy");
const path = require("path");
const { HTTPError, rimraf_promise } = require("./utils");
const fs = require("fs");
import { mkdirSync, writeFileSync } from "fs";
import { dirname as _dirname } from "path";
import { rimraf } from "rimraf";
import spawn from "spawn-promise";
import { temporaryDirectory } from "tempy";
import { HTTPError } from "./utils.js";

const boardFQBNs = {
"sensebox-mcu": "sensebox:samd:sb:power=on",
"sensebox": "arduino:avr:uno",
sensebox: "arduino:avr:uno",
"sensebox-esp32s2": "esp32:esp32:sensebox_mcu_esp32s2",
};

const validBoards = Object.keys(boardFQBNs);

const boardBinaryFileextensions = {
export const boardBinaryFileextensions = {
"sensebox-mcu": "bin",
"sensebox": "hex",
sensebox: "hex",
"sensebox-esp32s2": "bin",
};

const baseArgs = ["--build-cache-path", `/app/src/build-cache`];

const payloadValidator = function payloadValidator(req, res, next) {
export const payloadValidator = function payloadValidator(req, res, next) {
// reject all non application/json requests
if (
!req.headers["content-type"] ||
Expand Down Expand Up @@ -76,11 +77,11 @@ const payloadValidator = function payloadValidator(req, res, next) {

const execBuilder = async function execBuilder({ board, sketch, buildDir }) {
// const tmpSketchPath = await tempWrite(sketch);
const sketchDir = `${tempy.directory()}/sketch`;
fs.mkdirSync(sketchDir);
const sketchDir = `${temporaryDirectory()}/sketch`;
mkdirSync(sketchDir);

const tmpSketchPath = `${sketchDir}/sketch.ino`;
fs.writeFileSync(tmpSketchPath, sketch);
writeFileSync(tmpSketchPath, sketch);

await spawn(`arduino-cli`, [
"compile",
Expand All @@ -93,14 +94,14 @@ const execBuilder = async function execBuilder({ board, sketch, buildDir }) {
]);

try {
const dirname = path.dirname(tmpSketchPath);
await rimraf_promise(`${dirname}`);
const dirname = _dirname(tmpSketchPath);
await rimraf(`${dirname}`);
} catch (error) {
console.log(`Error deleting tmp sketch folder ${tmpSketchPath}: `, error);
}
};

const compileHandler = async function compileHandler(req, res, next) {
export const compileHandler = async function compileHandler(req, res, next) {
if (req.method !== "POST") {
return next(
new HTTPError({
Expand All @@ -110,7 +111,7 @@ const compileHandler = async function compileHandler(req, res, next) {
);
}

const buildDir = tempy.directory();
const buildDir = temporaryDirectory();
req._builderParams = { buildDir, ...req._builderParams };

// execute builder with parameters from user
Expand All @@ -131,9 +132,3 @@ const compileHandler = async function compileHandler(req, res, next) {
return next(new HTTPError({ error: err.message }));
}
};

module.exports = {
payloadValidator,
compileHandler,
boardBinaryFileextensions,
};
21 changes: 10 additions & 11 deletions src/download.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
const fs = require("fs");
const { boardBinaryFileextensions } = require("./builder");
const { HTTPError, rimraf_promise } = require("./utils");
import { createReadStream } from "fs";
import { rimraf } from "rimraf";
import { boardBinaryFileextensions } from "./builder.js";
import { HTTPError } from "./utils.js";

const readFile = async function readFile({ id, board }) {
return Promise.resolve(
fs.createReadStream(
createReadStream(
`/tmp/${id}/sketch.ino.${boardBinaryFileextensions[board]}`
)
);
};

const downloadHandler = async function downloadHandler(req, res, next) {
export const downloadHandler = async function downloadHandler(req, res, next) {
if (req.method !== "GET") {
return next(
new HTTPError({
Expand Down Expand Up @@ -40,7 +41,7 @@ const downloadHandler = async function downloadHandler(req, res, next) {
});
stream.on("end", async () => {
try {
await rimraf_promise(`/tmp/${req._url.query.id}`);
await rimraf(`/tmp/${req._url.query.id}`);
} catch (error) {
console.log(
`Error deleting compile sketch folder with ${req._url.query.id}: `,
Expand All @@ -52,14 +53,12 @@ const downloadHandler = async function downloadHandler(req, res, next) {
res.setHeader("Content-Type", "application/octet-stream");
res.setHeader(
"Content-Disposition",
`attachment; filename=${filename}.${boardBinaryFileextensions[req._url.query.board]}`
`attachment; filename=${filename}.${
boardBinaryFileextensions[req._url.query.board]
}`
);
stream.pipe(res);
} catch (err) {
return next(new HTTPError({ error: err.message }));
}
};

module.exports = {
downloadHandler,
};
75 changes: 39 additions & 36 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
const connect = require("connect");
const http = require("http");
const urlParser = require("url").parse;
const bodyParser = require("body-parser");
const app = connect();
const responseTime = require("response-time");
const morgan = require("morgan");
import bodyParser from "body-parser";
import { spawnSync } from "child_process";
import connect from "connect";
import { STATUS_CODES, createServer } from "http";
import morgan from "morgan";
import os from "os";
import responseTime from "response-time";
import { parse as urlParser } from "url";

import { compileHandler, payloadValidator } from "./builder.js";
import { downloadHandler } from "./download.js";
import { HTTPError } from "./utils.js";

const { compileHandler, payloadValidator } = require("./builder");
const { downloadHandler } = require("./download");
const { HTTPError } = require("./utils");
const { spawnSync } = require("child_process");
const app = connect();

const defaultHeaders = {
"Content-Type": "application/json",
Accept: "application/json",
Allow: "GET,POST",
"X-Backend-Server": require("os").hostname(),
"X-Backend-Server": os.hostname(),
};

const preflight = function preflight(req, res, next) {
Expand Down Expand Up @@ -77,12 +79,33 @@ const errorHandler = function errorHandler(err, req, res, next) {
res.setHeader("Content-Type", "application/json");
res.end(
JSON.stringify({
code: http.STATUS_CODES[res.statusCode],
code: STATUS_CODES[res.statusCode],
message: err.message,
})
);
};

const librariesHandler = function librariesHandler(req, res, next) {
const format = req._url.query.format;

if (format === "json") {
const child = spawnSync("arduino-cli", [
"lib",
"list",
"--all",
"--format",
"json",
]);
res.setHeader("Content-Type", "application/json");
res.end(child.stdout.toString());
return;
}

const child = spawnSync("arduino-cli", ["lib", "list", "--all"]);
res.setHeader("Content-Type", "text/plain");
res.end(child.stdout.toString());
};

const startServer = function startServer() {
app.use(
morgan(
Expand All @@ -97,33 +120,13 @@ const startServer = function startServer() {
app.use("/compile", payloadValidator);
app.use("/compile", compileHandler);
app.use("/download", downloadHandler);
app.use("/libraries", function (req, res) {
// read request parameter format (json or text)
const format = req._url.query.format;

if (format === "json") {
const child = spawnSync("arduino-cli", [
"lib",
"list",
"--all",
"--format",
"json",
]);
res.setHeader("Content-Type", "application/json");
res.end(child.stdout.toString());
return;
}

const child = spawnSync("arduino-cli", ["lib", "list", "--all"]);
res.setHeader("Content-Type", "text/plain");
res.end(child.stdout.toString());
});
app.use("/libraries", librariesHandler);
app.use(errorHandler);

http.createServer(app).listen(3000);
createServer(app).listen(3000);
console.log("Compiler started and listening on port 3000!");
};

startServer();

module.exports = app; // for testing
export default app; // for testing
13 changes: 2 additions & 11 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
const util = require("util");
const rimraf = require("rimraf");
const rimraf_promise = util.promisify(rimraf);

const HTTPError = function HTTPError({ code = 500, error = "" }) {
export function HTTPError({ code = 500, error = "" }) {
const err = new Error(error);
err.statusCode = code;

return err;
};

module.exports = {
HTTPError,
rimraf_promise,
};
}
26 changes: 8 additions & 18 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
const chai = require("chai");
const chaiHttp = require("chai-http");
const server = require("../src/index");
const should = chai.should();

chai.use(chaiHttp);
import server from "../src/index.js";
import request from "./setup.js";

describe("Compiler", () => {
describe("/GET index", () => {
it("it should get the index page and answer with a 404 ", (done) => {
chai
.request(server)
request(server)
.get("/")
.end((err, res) => {
res.should.have.status(404);
Expand All @@ -20,8 +15,7 @@ describe("Compiler", () => {

describe("/compile", () => {
it("should reject request without board parameter", (done) => {
chai
.request(server)
request(server)
.post("/compile")
.send({ sketch: "void setup() {} void loop() {}" })
.end((err, res) => {
Expand All @@ -34,8 +28,7 @@ describe("Compiler", () => {
});

it("should reject request without sketch parameter", (done) => {
chai
.request(server)
request(server)
.post("/compile")
.send({ board: "sensebox-mcu" })
.end((err, res) => {
Expand All @@ -48,8 +41,7 @@ describe("Compiler", () => {
});

it("should reject request with invalid board", (done) => {
chai
.request(server)
request(server)
.post("/compile")
.send({
board: "esp8266",
Expand All @@ -67,8 +59,7 @@ describe("Compiler", () => {
});

it("should reject request with wrong Content-Type", (done) => {
chai
.request(server)
request(server)
.post("/compile")
.set("Content-Type", "text/plain")
.send("")
Expand All @@ -84,8 +75,7 @@ describe("Compiler", () => {
});

it("should only accept POST request", (done) => {
chai
.request(server)
request(server)
.get("/compile")
.send({
board: "sensebox-mcu",
Expand Down
Loading

0 comments on commit 8bdca90

Please sign in to comment.