This commit is contained in:
commit
37047cee22
9 changed files with 489 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
node_modules
|
||||
config.juml
|
1
.npmignore
Normal file
1
.npmignore
Normal file
|
@ -0,0 +1 @@
|
|||
config.juml
|
23
.woodpecker.yml
Normal file
23
.woodpecker.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
# .woodpecker.yml
|
||||
platform: linux/arm64
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: node:18-alpine
|
||||
commands:
|
||||
- apk add git zip tar
|
||||
- npm install
|
||||
- npm install git+https://jusax.de/git/jusax23/gitea-release.git
|
||||
- mkdir build
|
||||
- mkdir juml
|
||||
- mkdir juml/dist
|
||||
- mkdir upload
|
||||
- npm run prepublish
|
||||
- cp dist/* juml/dist
|
||||
- cp package.json juml
|
||||
- cp package-lock.json juml
|
||||
- cp readme.md juml
|
||||
- zip -r upload/juml.zip juml/*
|
||||
- tar -czvf upload/juml.tar.gz juml/*
|
||||
- npx gitea-release "https://jusax.de/git/api/v1/" "$${GITEA_TOKEN}" "$${CI_REPO}" "$${CI_COMMIT_BRANCH}" "$${CI_COMMIT_TAG}" "upload" "$${CI_COMMIT_MESSAGE}"
|
||||
secrets: [ gitea_token ]
|
33
example.js
Normal file
33
example.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import juml from "./dist/juml.js";
|
||||
|
||||
const conf_struct = {
|
||||
System:{
|
||||
PORT:{type:"number",default:80},
|
||||
URL:{type:"string",default:"https://google.de/",comment:"The exposed URL:"}
|
||||
},
|
||||
ssl:{
|
||||
enable:{type:"boolean",default:true,env:"FMI_SSL_ENABELED"},
|
||||
privkey:{type:"string",default:"privkey.pem"},
|
||||
cert:{type:"string",default:"cert.pem"},
|
||||
chain:{type:"string",default:"chain.pem"}
|
||||
}
|
||||
};
|
||||
|
||||
console.log()
|
||||
|
||||
const mc = new juml(conf_struct);
|
||||
|
||||
mc.connect("./config.juml");
|
||||
|
||||
if(mc.get("ssl","enable")){
|
||||
console.log("SSL Enabled");
|
||||
mc.readPathes(mc.get("ssl","privkey"),mc.get("ssl","cert"),mc.get("ssl","chain"))
|
||||
.then(([privkey,cert,chain])=>{
|
||||
console.log("privkey: ",privkey,"\ncert: ",cert,"\nchain: ",chain);
|
||||
}).catch(err=>{
|
||||
console.error(err);
|
||||
process.exit();
|
||||
});
|
||||
}else{
|
||||
console.log("SSL Disabled");
|
||||
}
|
126
package-lock.json
generated
Normal file
126
package-lock.json
generated
Normal file
|
@ -0,0 +1,126 @@
|
|||
{
|
||||
"name": "juml",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "juml",
|
||||
"version": "1.0.0",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"node-fetch": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.1.tgz",
|
||||
"integrity": "sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20 || >= 14.13"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
|
||||
"integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
package.json
Normal file
30
package.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "juml",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "dist/juml.js",
|
||||
"types": "dist/juml.d.ts",
|
||||
"type": "module",
|
||||
"directories": {
|
||||
"dist": "dist"
|
||||
},
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"prepublish": "tsc"
|
||||
},
|
||||
"author": "jusax23",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"node-fetch": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
"typescript": "^4.9.4"
|
||||
}
|
||||
}
|
6
readme.md
Normal file
6
readme.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# nMan
|
||||
|
||||
A simple way of shutting down a Server.
|
||||
|
||||
## Example
|
||||
See example.mjs
|
247
src/juml.ts
Normal file
247
src/juml.ts
Normal file
|
@ -0,0 +1,247 @@
|
|||
import fs from "fs";
|
||||
import fetch from 'node-fetch';
|
||||
import path from "path";
|
||||
|
||||
export default class juml {
|
||||
#groups: { [key: string]: Group } = {};
|
||||
#pathfile: string | null = null;
|
||||
|
||||
constructor(struct: { [x: string]: { [x: string]: any; }; }) {
|
||||
for (let g in struct) {
|
||||
this.#groups[g] = new Group(struct[g]);
|
||||
}
|
||||
}
|
||||
connect(file: string, dir = process.cwd()) {
|
||||
var exists = true;
|
||||
this.#pathfile = jpath(dir, file);
|
||||
if (!fs.existsSync(this.#pathfile) || !fs.lstatSync(this.#pathfile).isFile()) {
|
||||
console.warn("Config does't exists. It will be created: " + this.#pathfile);
|
||||
exists = false;
|
||||
} else {
|
||||
this.fromJUML(fs.readFileSync(this.#pathfile).toString());
|
||||
}
|
||||
this.save();
|
||||
return exists;
|
||||
}
|
||||
|
||||
get(group: string, name: string, empty: any = null) {
|
||||
if ((this.#groups[group] ?? {})[name] == null) {
|
||||
return empty;
|
||||
}
|
||||
return this.#groups[group][name].valueOf();
|
||||
}
|
||||
set(group: string, name: string, value: any) {
|
||||
if ((this.#groups[group] ?? {})[name] == null) {
|
||||
return false;
|
||||
}
|
||||
this.#groups[group][name].set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
save() {
|
||||
if (this.#pathfile != null) fs.writeFileSync(this.#pathfile, this.toJUML());
|
||||
}
|
||||
|
||||
fromJUML(juml: string) {
|
||||
var comment: string[] = [];
|
||||
let nowGroup: Group | null = null;
|
||||
|
||||
juml.split("\n").map(s => s.trim()).forEach(now => {
|
||||
if (now.startsWith("#")) {
|
||||
comment.push(now.slice(1));
|
||||
} else if (now.startsWith("[") && now.endsWith("]")) {
|
||||
let groupName = now.slice(1, -1);
|
||||
nowGroup = this.#groups[groupName] || null;
|
||||
nowGroup.setComment(comment.join("\n"));
|
||||
comment = [];
|
||||
} else if (now.includes("=") && nowGroup != null) {
|
||||
let nows = now.split("=");
|
||||
let name = nows.splice(0, 1)[0].trim();
|
||||
let data = nows.join("=").trim();
|
||||
if (nowGroup[name] != null) {
|
||||
nowGroup[name].set = data;
|
||||
nowGroup[name].comment = comment.join("\n");
|
||||
comment = [];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
toJUML() {
|
||||
let json = this.#groups;
|
||||
var out = "";
|
||||
for (let group in json) {
|
||||
if (json[group].comment() != "") {
|
||||
out += "\n";
|
||||
out += json[group].comment().split("\n").map(d => "#" + d).join("\n");
|
||||
}
|
||||
out += `\n[${group}]\n`;
|
||||
for (let name in json[group]) {
|
||||
if (json[group][name].comment != "") {
|
||||
out += json[group][name].comment.split("\n").map((d: string) => "#" + d).join("\n");
|
||||
out += "\n";
|
||||
}
|
||||
out += name + "=" + json[group][name] + "\n";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
readPath(path: string, dir = process.cwd()) {
|
||||
return new Promise((res, rej) => {
|
||||
if (path.startsWith("http")) {
|
||||
fetch(path)
|
||||
.then(d => d.text())
|
||||
.then(d => res(d))
|
||||
.catch(() => {
|
||||
rej("Error occurred while fetching: " + path)
|
||||
})
|
||||
} else {
|
||||
const pathf = jpath(dir, path);
|
||||
if (!fs.existsSync(pathf) || !fs.statSync(pathf).isFile()) {
|
||||
rej("Coud not find File: " + pathf);
|
||||
} else {
|
||||
try {
|
||||
var content = fs.readFileSync(pathf).toString();
|
||||
res(content);
|
||||
} catch (e) {
|
||||
rej("Error occurred while reading: " + pathf);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
readPathes(...pathes: string[]) {
|
||||
return new Promise(async (res, rej) => {
|
||||
var out = [];
|
||||
for (var i = 0; i < pathes.length; i++) {
|
||||
try {
|
||||
out[i] = await this.readPath(pathes[i]);
|
||||
} catch (e) {
|
||||
rej(e);
|
||||
}
|
||||
}
|
||||
res(out);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
class Group extends Object {
|
||||
#comment = "";
|
||||
[key: string]: Field | any;
|
||||
constructor(struct: { [x: string]: any; }) {
|
||||
super({});
|
||||
for (let e in struct) {
|
||||
let elem = struct[e];
|
||||
switch (elem.type || "string") {
|
||||
case "number": {
|
||||
this[e] = new NField(elem.default ?? 0, elem.comment ?? "", elem.env ?? "");
|
||||
} break;
|
||||
case "boolean": {
|
||||
this[e] = new BField(elem.default ?? false, elem.comment ?? "", elem.env ?? "");
|
||||
} break;
|
||||
case "string": {
|
||||
this[e] = new SField(elem.default ?? "", elem.comment ?? "", elem.env ?? "");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
comment() {
|
||||
return this.#comment
|
||||
}
|
||||
setComment(c: string) {
|
||||
this.#comment = c;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Field {
|
||||
command = "";
|
||||
valueOf() { }
|
||||
set set(v: any) { }
|
||||
}
|
||||
|
||||
class NField extends Field {
|
||||
comment = "";
|
||||
#value = 0;
|
||||
|
||||
constructor(v: any, comment: string, env: string) {
|
||||
super();
|
||||
if (env != "" && process.env[env]) {
|
||||
this.#value = Number(createType(process.env[env]));
|
||||
} else {
|
||||
this.#value = Number(createType(v));
|
||||
}
|
||||
this.comment = comment;
|
||||
}
|
||||
set set(v: number) {
|
||||
this.#value = Number(createType(v));
|
||||
}
|
||||
valueOf() {
|
||||
return this.#value;
|
||||
}
|
||||
}
|
||||
class BField extends Field {
|
||||
comment = "";
|
||||
#value = false;
|
||||
|
||||
constructor(v: any, comment: string, env: string) {
|
||||
super();
|
||||
if (env != "" && process.env[env]) {
|
||||
this.#value = Boolean(createType(process.env[env]));
|
||||
} else {
|
||||
this.#value = Boolean(createType(v));
|
||||
}
|
||||
this.comment = comment;
|
||||
}
|
||||
set set(v: boolean) {
|
||||
this.#value = Boolean(createType(v));
|
||||
}
|
||||
valueOf() {
|
||||
return this.#value;
|
||||
}
|
||||
}
|
||||
class SField extends Field {
|
||||
comment = "";
|
||||
#value = "";
|
||||
|
||||
constructor(v: any, comment: string, env: string) {
|
||||
super();
|
||||
if (env != "" && process.env[env]) {
|
||||
this.#value = String(createType(process.env[env]));
|
||||
} else {
|
||||
this.#value = String(createType(v));
|
||||
}
|
||||
this.comment = comment;
|
||||
}
|
||||
set set(v: string) {
|
||||
this.#value = String(createType(v));
|
||||
}
|
||||
valueOf() {
|
||||
return this.#value;
|
||||
}
|
||||
}
|
||||
|
||||
function createType(data: any) {
|
||||
if (data == "true") {
|
||||
return true;
|
||||
}
|
||||
if (data == "false") {
|
||||
return false;
|
||||
}
|
||||
if (String(data).toLowerCase() == "infinity") {
|
||||
return Infinity;
|
||||
}
|
||||
if (String(data).toLowerCase() == "-infinity") {
|
||||
return -Infinity;
|
||||
}
|
||||
if (!isNaN(data)) {
|
||||
return Number(data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function jpath(a: string, b: string) {
|
||||
if (b.startsWith("/")) {
|
||||
return b;
|
||||
}
|
||||
return path.join(a, b);
|
||||
}
|
20
tsconfig.json
Normal file
20
tsconfig.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"files": [
|
||||
"src/juml.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue