initial
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
jusax23 2023-02-25 18:35:59 +01:00
commit 37047cee22
9 changed files with 489 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
dist
node_modules
config.juml

1
.npmignore Normal file
View file

@ -0,0 +1 @@
config.juml

23
.woodpecker.yml Normal file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,6 @@
# nMan
A simple way of shutting down a Server.
## Example
See example.mjs

247
src/juml.ts Normal file
View 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
View 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"
]
}