Asyncify everything so that we can do dependency injection
This commit is contained in:
parent
121cfc2418
commit
bd08aae1da
6 changed files with 131 additions and 91 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
example-message.json
|
example-message.json
|
||||||
|
*.sqlite
|
||||||
*.pcapng
|
*.pcapng
|
||||||
*.png
|
*.png
|
||||||
*.stl
|
*.stl
|
||||||
|
|
72
server/bootstrap/cli.mjs
Normal file
72
server/bootstrap/cli.mjs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import show_help from '../help.mjs';
|
||||||
|
import { decode_payload } from '../ttn-app-server/DecodePayload.mjs';
|
||||||
|
|
||||||
|
export default async function(c) {
|
||||||
|
let { ansi: a, log: l, settings } = c.cradle;
|
||||||
|
|
||||||
|
// 2: CLI Argument Parsing
|
||||||
|
let args = process.argv.slice(2); // Slice out the node binary name and the filename
|
||||||
|
let extras = [];
|
||||||
|
for(let i = 0; i < args.length; i++) {
|
||||||
|
if(!args[i].startsWith("-")) {
|
||||||
|
extras.push(args[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(args[i]) {
|
||||||
|
case "--help":
|
||||||
|
case "-h":
|
||||||
|
show_help(c.cradle);
|
||||||
|
process.exit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "--version":
|
||||||
|
case "-v":
|
||||||
|
console.log(program.version);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Add more arguments here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3: Environment Variable Parsing
|
||||||
|
|
||||||
|
// process.env.XYZ
|
||||||
|
|
||||||
|
// 4: Run
|
||||||
|
if(extras.length < 1) {
|
||||||
|
console.error(`${a.fred}${a.hicol}Error: No subcommand specified.${a.reset}`);
|
||||||
|
show_help(c.cradle);
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
l.log(`${a.fgreen}${a.hicol}*** LoRaWAN Signal Mapper ***${a.reset}`);
|
||||||
|
|
||||||
|
switch(extras[0]) {
|
||||||
|
case "ttn-app-server":
|
||||||
|
l.log(`${a.fgreen}${a.hicol}Starting The Things Network application server${a.reset}`);
|
||||||
|
|
||||||
|
let app_server = c.resolve("TTNAppServer");
|
||||||
|
await app_server.run();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "decode-test":
|
||||||
|
l.log(`${a.fgreen}${a.hicol}Decoding message${a.reset}`);
|
||||||
|
if(process.argv.length < 4) {
|
||||||
|
l.error("No message specified. Specify the message to decode in single quotes directly after 'decode-test'.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
l.log("Input: ", process.argv[3]);
|
||||||
|
l.log("Output: ", decode_payload(process.argv[3]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.error(`${a.fred}${a.hicol}Error: Subcommand '${extras[0]}' not recognised.${a.reset}`);
|
||||||
|
console.error( `${a.fred}Perhaps you mistyped it, or it hasn't been implemented yet?`);
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
import a from 'awilix';
|
import a from 'awilix';
|
||||||
|
|
||||||
import Ansi from '../Helpers/Ansi.mjs';
|
import Ansi from '../Helpers/Ansi.mjs';
|
||||||
|
@ -10,22 +14,47 @@ import MessageHandler from '../ttn-app-server/MessageHandler.mjs';
|
||||||
import settings from './settings.mjs';
|
import settings from './settings.mjs';
|
||||||
import database_init from '../bootstrap/database_init.mjs';
|
import database_init from '../bootstrap/database_init.mjs';
|
||||||
|
|
||||||
const c = a.createContainer({
|
const root_dir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
||||||
injectionMode: a.InjectionMode.PROXY
|
|
||||||
});
|
|
||||||
|
|
||||||
c.register({
|
export default async function setup() {
|
||||||
settings: a.asValue(settings),
|
const c = a.createContainer({
|
||||||
ansi: a.asClass(Ansi).singleton(),
|
injectionMode: a.InjectionMode.PROXY
|
||||||
log: a.asClass(Log).singleton(),
|
});
|
||||||
database: a.asFunction(database_init).singleton(),
|
|
||||||
TTNAppServer: a.asClass(TTNAppServer),
|
|
||||||
MessageHandler: a.asClass(MessageHandler)
|
|
||||||
});
|
|
||||||
|
|
||||||
c.loadModules("../Repos.SQLite/*.mjs", {
|
c.register({
|
||||||
register: a.asClass,
|
root_dir: a.asValue(root_dir),
|
||||||
lifetime: a.Lifetime.SINGLETON
|
settings: a.asValue(settings),
|
||||||
});
|
ansi: a.asClass(Ansi).singleton(),
|
||||||
|
log: a.asClass(Log).singleton(),
|
||||||
export default c;
|
database: a.asFunction(database_init).singleton(),
|
||||||
|
TTNAppServer: a.asClass(TTNAppServer),
|
||||||
|
MessageHandler: a.asClass(MessageHandler)
|
||||||
|
});
|
||||||
|
|
||||||
|
let repo_filenames = await fs.readdir(path.join(root_dir, "./Repos.SQLite"));
|
||||||
|
|
||||||
|
for(let repo_filename of repo_filenames) {
|
||||||
|
let class_root = await import(path.join(root_dir, `./Repos.SQLite/${repo_filename}`)),
|
||||||
|
class_name = class_root.default.prototype.constructor.name;
|
||||||
|
|
||||||
|
c.register(
|
||||||
|
class_name,
|
||||||
|
a.asClass(class_root.default).singleton(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(c.registrations);
|
||||||
|
|
||||||
|
// c.loadModules([
|
||||||
|
// "./Repos.SQLite/*.mjs"
|
||||||
|
// // "./Repos.SQLite/ReadingRepo.mjs"
|
||||||
|
// ], {
|
||||||
|
// cwd: root_dir,
|
||||||
|
// resolverOptions: {
|
||||||
|
// register: a.asClass,
|
||||||
|
// lifetime: a.Lifetime.SINGLETON
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import Database from 'better-sqlite3';
|
||||||
|
|
||||||
var db = null;
|
var db = null;
|
||||||
|
|
||||||
async function init({ settings: { database: { filename, options } } }) {
|
function init({ settings: { database: { filename, options } } }) {
|
||||||
db = new Database(filename, options);
|
db = new Database(filename, options);
|
||||||
db.exec(await fs.promises.readFile("../db_template.sql", "utf8"));
|
db.exec(fs.readFileSync("../db_template.sql", "utf8"));
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import c from './bootstrap/container.mjs';
|
export default function({ settings, ansi : a }) {
|
||||||
|
|
||||||
const a = c.resolve("ansi");
|
|
||||||
|
|
||||||
export default function(settings) {
|
|
||||||
|
|
||||||
console.log(`${settings.program_name}, ${settings.version}
|
console.log(`${settings.program_name}, ${settings.version}
|
||||||
${a.locol}By Starbeamrainbowlabs${a.reset}
|
${a.locol}By Starbeamrainbowlabs${a.reset}
|
||||||
|
|
|
@ -2,74 +2,16 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// 1: Setup & Imports
|
// 1: Setup & Imports
|
||||||
import c from './bootstrap/container.mjs';
|
import setup from './bootstrap/container.mjs';
|
||||||
|
import cli from './bootstrap/cli.mjs';
|
||||||
|
|
||||||
import show_help from './help.mjs';
|
async function run() {
|
||||||
import { decode_payload } from './ttn-app-server/DecodePayload.mjs';
|
try {
|
||||||
|
let c = await setup();
|
||||||
const settings = c.resolve("settings");
|
await cli(c);
|
||||||
const a = c.resolve("ansi");
|
} catch(error) {
|
||||||
const l = c.resolve("log");
|
console.error(error);
|
||||||
|
|
||||||
// 2: CLI Argument Parsing
|
|
||||||
let args = process.argv.slice(2); // Slice out the node binary name and the filename
|
|
||||||
let extras = [];
|
|
||||||
for(let i = 0; i < args.length; i++) {
|
|
||||||
if(!args[i].startsWith("-")) {
|
|
||||||
extras.push(args[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(args[i]) {
|
|
||||||
case "--help":
|
|
||||||
case "-h":
|
|
||||||
show_help(settings);
|
|
||||||
process.exit();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "--version":
|
|
||||||
case "-v":
|
|
||||||
console.log(program.version);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Add more arguments here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3: Environment Variable Parsing
|
run();
|
||||||
|
|
||||||
// process.env.XYZ
|
|
||||||
|
|
||||||
// 4: Run
|
|
||||||
if(extras.length < 1) {
|
|
||||||
console.error(`${a.fred}${a.hicol}Error: No subcommand specified.${a.reset}`);
|
|
||||||
show_help(settings);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
l.log(`${a.fgreen}${a.hicol}*** LoRaWAN Signal Mapper ***${a.reset}`);
|
|
||||||
|
|
||||||
switch(extras[0]) {
|
|
||||||
case "ttn-app-server":
|
|
||||||
l.log(`${a.fgreen}${a.hicol}Starting The Things Network application server${a.reset}`);
|
|
||||||
|
|
||||||
let app_server = c.resolve("TTNAppServer");
|
|
||||||
app_server.run();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "decode-test":
|
|
||||||
l.log(`${a.fgreen}${a.hicol}Decoding message${a.reset}`);
|
|
||||||
if(process.argv.length < 4) {
|
|
||||||
l.error("No message specified. Specify the message to decode in single quotes directly after 'decode-test'.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
l.log("Input: ", process.argv[3]);
|
|
||||||
l.log("Output: ", decode_payload(process.argv[3]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.error(`${a.fred}${a.hicol}Error: Subcommand '${extras[0]}' not recognised.${a.reset}`);
|
|
||||||
console.error( `${a.fred}Perhaps you mistyped it, or it hasn't been implemented yet?`);
|
|
||||||
process.exit(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue