From c0f1a3db7e672aa3cb0e8c3b4a167d6af74600e4 Mon Sep 17 00:00:00 2001
From: Christopher Hase
Date: Thu, 10 Apr 2025 14:36:39 +0200
Subject: [PATCH] add http-server part 6.2
---
Dockerfile | 17 ++--
backend/broker.js | 131 ++++++++++++++++++++++++++++++
backend/broker.mjs | 131 ++++++++++++++++++++++++++++++
backend/broker.test.js | 21 +++++
backend/server.js | 11 +++
backend/server.ts | 3 +-
dist/backend/broker.d.ts | 3 +
dist/backend/broker.d.ts.map | 1 +
dist/backend/broker.js | 131 ++++++++++++++++++++++++++++++
dist/backend/broker.test.d.ts | 2 +
dist/backend/broker.test.d.ts.map | 1 +
dist/backend/broker.test.js | 21 +++++
dist/backend/server.d.ts | 2 +
dist/backend/server.d.ts.map | 1 +
dist/backend/server.js | 11 +++
frontend/event.js | 15 ++++
jest.config.js | 6 ++
old.2.Dockerfile | 45 ++++++++++
tsconfig.backend.json | 20 +++--
19 files changed, 559 insertions(+), 14 deletions(-)
create mode 100644 backend/broker.js
create mode 100644 backend/broker.mjs
create mode 100644 backend/broker.test.js
create mode 100644 backend/server.js
create mode 100644 dist/backend/broker.d.ts
create mode 100644 dist/backend/broker.d.ts.map
create mode 100644 dist/backend/broker.js
create mode 100644 dist/backend/broker.test.d.ts
create mode 100644 dist/backend/broker.test.d.ts.map
create mode 100644 dist/backend/broker.test.js
create mode 100644 dist/backend/server.d.ts
create mode 100644 dist/backend/server.d.ts.map
create mode 100644 dist/backend/server.js
create mode 100644 frontend/event.js
create mode 100644 jest.config.js
create mode 100644 old.2.Dockerfile
diff --git a/Dockerfile b/Dockerfile
index d952065..bb8c4ef 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,15 +4,18 @@ FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/node:20.18.1 AS build
WORKDIR /app
COPY package*.json ./
-COPY . .
+COPY tsconfig.json ./
+COPY tsconfig.backend.json ./
+COPY . .
RUN npm install -g npm@11.2.0
RUN npm install
-#RUN npx tsc -p tsconfig.json
+# Kompiliere zuerst den Backend-Code, sodass broker.mjs und andere Dateien erzeugt werden
RUN npx tsc -p tsconfig.backend.json
-RUN npx tsc -p tsconfig.frontend.json
+# Danach können wir die Frontend-Dateien auch kompilieren
+RUN npx tsc -p tsconfig.frontend.json
# 2. Rust build-Stage
FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/rust:1.74.0 AS rust-build
@@ -23,19 +26,19 @@ FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/node:20.18.1
WORKDIR /app
-### NEW ###
+# Kopiere Node-Modules und alle generierten Dateien
COPY --from=build /app/node_modules ./node_modules
-
COPY --from=build /app/dist ./dist
-#COPY --from=build /app/index.html ./dist/
COPY --from=build /app/frontend/index.html ./dist/frontend/
COPY --from=rust-build /usr/local/cargo/bin/iching /usr/local/bin/iching
+# Falls notwendig: Umbenennen von .js zu .mjs
RUN find dist/backend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \;
RUN find dist/frontend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \;
+# Starte den Backend-Server
RUN node dist/backend/server.mjs &
-#CMD ["npx", "http-server", "dist", "-p", "8080", "--mime", "application/javascript=js"]
+# Starte den Frontend-Server
CMD ["npx", "http-server", "dist/frontend", "-p", "8080", "--mime", "application/javascript=js"]
\ No newline at end of file
diff --git a/backend/broker.js b/backend/broker.js
new file mode 100644
index 0000000..3c3b807
--- /dev/null
+++ b/backend/broker.js
@@ -0,0 +1,131 @@
+import { exec } from 'child_process';
+import * as fs from 'fs';
+var config;
+const nodemailer = require('nodemailer');
+export function executeCommand() {
+ exec('iching divine', (error, stdout, stderr) => {
+ console.log(`Begin`);
+ if (error) {
+ console.error(`Error: ${error.message}`);
+ return;
+ }
+ if (stderr) {
+ console.error(`Stderr: ${stderr}`);
+ return;
+ }
+ //Load config once
+ if (config == undefined) {
+ config = loadConfig();
+ }
+ console.log(`Send E-Mail`);
+ sendEmail(stdout);
+ });
+}
+// Run function once initially, called from Dockerfile
+executeCommand();
+// Load the Configuration
+function loadConfig() {
+ console.log(`Load Config`);
+ const data = fs.readFileSync('config.json', 'utf-8');
+ return JSON.parse(data);
+}
+// Send E-Mail
+async function sendEmail(content) {
+ // Create Transporter
+ const transporter = nodemailer.createTransport({
+ host: config.mailHost,
+ port: config.mailPort,
+ secure: false
+ });
+ try {
+ const info = await transporter.sendMail({
+ from: '"The Oracle" ',
+ to: config.emailReceiver,
+ subject: "Your Horoscope Is Ready",
+ text: content,
+ html: html(content)
+ });
+ console.log("E-Mail sent: ", info.messageId);
+ }
+ catch (error) {
+ console.error("Error Sending E-Mail:", error);
+ }
+}
+// Generate 1) Parse Tree and 2) HTML
+export function html(inputText) {
+ const parseTree = parse(inputText);
+ const htmlOutput = render(parseTree);
+ return htmlOutput;
+}
+// Generate the Parse Tree
+function parse(input) {
+ console.log("Parse input text");
+ const root = { type: "Root" };
+ var currentNode = root;
+ const lines = input.split("\n");
+ for (const line of lines) {
+ if (line.startsWith("Hexagram")) {
+ const hexagram = { type: "Hexagram" };
+ currentNode.child = hexagram;
+ currentNode = hexagram;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Judgement")) {
+ const judgement = { type: "Judgement" };
+ currentNode.child = judgement;
+ currentNode = judgement;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Images")) {
+ const images = { type: "Images" };
+ currentNode.child = images;
+ currentNode = images;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("~") && currentNode.type != "ChangingLines") {
+ const changingLines = { type: "ChangingLines" };
+ currentNode.child = changingLines;
+ currentNode = changingLines;
+ currentNode.value = line; // + "
"; TODO: try without this
+ }
+ else {
+ currentNode.value = currentNode.value + line + "
";
+ }
+ }
+ return root;
+}
+// Generate HTML from Parse Tree
+function render(node) {
+ if (node == undefined) {
+ console.log("Rendering of nodes finished!");
+ return "";
+ }
+ console.log("Render node" + node.type);
+ var outputHTML = "";
+ switch (node.type) {
+ case "Root":
+ return render(node.child);
+ case "Hexagram":
+ node.value = node.value?.replace("", "");
+ node.value = node.value?.replace("
", "
");
+ node.value = node.value?.replace("
", " - ");
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "Images":
+ outputHTML = "
" + node.value + "
"; //EXTRA closing div (was opened at beginning of hexagram)
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "ChangingLines":
+ const regex = new RegExp("~", "g");
+ node.value = node.value?.replace(regex, "");
+ //outputHTML = "
" + node.value + "
";
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ default:
+ outputHTML = "" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ }
+}
diff --git a/backend/broker.mjs b/backend/broker.mjs
new file mode 100644
index 0000000..3c3b807
--- /dev/null
+++ b/backend/broker.mjs
@@ -0,0 +1,131 @@
+import { exec } from 'child_process';
+import * as fs from 'fs';
+var config;
+const nodemailer = require('nodemailer');
+export function executeCommand() {
+ exec('iching divine', (error, stdout, stderr) => {
+ console.log(`Begin`);
+ if (error) {
+ console.error(`Error: ${error.message}`);
+ return;
+ }
+ if (stderr) {
+ console.error(`Stderr: ${stderr}`);
+ return;
+ }
+ //Load config once
+ if (config == undefined) {
+ config = loadConfig();
+ }
+ console.log(`Send E-Mail`);
+ sendEmail(stdout);
+ });
+}
+// Run function once initially, called from Dockerfile
+executeCommand();
+// Load the Configuration
+function loadConfig() {
+ console.log(`Load Config`);
+ const data = fs.readFileSync('config.json', 'utf-8');
+ return JSON.parse(data);
+}
+// Send E-Mail
+async function sendEmail(content) {
+ // Create Transporter
+ const transporter = nodemailer.createTransport({
+ host: config.mailHost,
+ port: config.mailPort,
+ secure: false
+ });
+ try {
+ const info = await transporter.sendMail({
+ from: '"The Oracle" ',
+ to: config.emailReceiver,
+ subject: "Your Horoscope Is Ready",
+ text: content,
+ html: html(content)
+ });
+ console.log("E-Mail sent: ", info.messageId);
+ }
+ catch (error) {
+ console.error("Error Sending E-Mail:", error);
+ }
+}
+// Generate 1) Parse Tree and 2) HTML
+export function html(inputText) {
+ const parseTree = parse(inputText);
+ const htmlOutput = render(parseTree);
+ return htmlOutput;
+}
+// Generate the Parse Tree
+function parse(input) {
+ console.log("Parse input text");
+ const root = { type: "Root" };
+ var currentNode = root;
+ const lines = input.split("\n");
+ for (const line of lines) {
+ if (line.startsWith("Hexagram")) {
+ const hexagram = { type: "Hexagram" };
+ currentNode.child = hexagram;
+ currentNode = hexagram;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Judgement")) {
+ const judgement = { type: "Judgement" };
+ currentNode.child = judgement;
+ currentNode = judgement;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Images")) {
+ const images = { type: "Images" };
+ currentNode.child = images;
+ currentNode = images;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("~") && currentNode.type != "ChangingLines") {
+ const changingLines = { type: "ChangingLines" };
+ currentNode.child = changingLines;
+ currentNode = changingLines;
+ currentNode.value = line; // + "
"; TODO: try without this
+ }
+ else {
+ currentNode.value = currentNode.value + line + "
";
+ }
+ }
+ return root;
+}
+// Generate HTML from Parse Tree
+function render(node) {
+ if (node == undefined) {
+ console.log("Rendering of nodes finished!");
+ return "";
+ }
+ console.log("Render node" + node.type);
+ var outputHTML = "";
+ switch (node.type) {
+ case "Root":
+ return render(node.child);
+ case "Hexagram":
+ node.value = node.value?.replace("", "");
+ node.value = node.value?.replace("
", "
");
+ node.value = node.value?.replace("
", " - ");
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "Images":
+ outputHTML = "
" + node.value + "
"; //EXTRA closing div (was opened at beginning of hexagram)
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "ChangingLines":
+ const regex = new RegExp("~", "g");
+ node.value = node.value?.replace(regex, "");
+ //outputHTML = "
" + node.value + "
";
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ default:
+ outputHTML = "" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ }
+}
diff --git a/backend/broker.test.js b/backend/broker.test.js
new file mode 100644
index 0000000..0ec4d2b
--- /dev/null
+++ b/backend/broker.test.js
@@ -0,0 +1,21 @@
+"use strict";
+/*import { html } from "./broker";
+import { test, beforeAll, afterAll } from "@jest/globals";
+
+jest.useFakeTimers();
+
+test("Generate HTML for hexagram", () => {
+ expect(html("Hexagram No. 45 ䷬\nGathering Together [Massing]\n萃 (cuì)"))
+ .toBe("
Hexagram No. 45 ䷬
Gathering Together [Massing] - 萃 (cuì)
");
+});
+
+test("Generate HTML for judgement", () => {
+ expect(html("Judgement:\nGathering Together. Success.\nThe king approaches his temple.\nIt furthers one to see the great man.\nThis brings success. Perseverance furthers.\nTo bring great offerings creates good fortune.\nIt furthers one to undertake something."))
+ .toBe("
Judgement:
Gathering Together. Success.
The king approaches his temple.
It furthers one to see the great man.
This brings success. Perseverance furthers.
To bring great offerings creates good fortune.
It furthers one to undertake something.
");
+});
+
+test("Generate HTML for images", () => {
+ expect(html("Images:\nOver the earth, the lake:\nThe image of Gathering Together.\nThus the superior man renews his weapons\nIn order to meet the unforseen."))
+ .toBe("
Images:
Over the earth, the lake:
The image of Gathering Together.
Thus the superior man renews his weapons
In order to meet the unforseen.
");
+});
+*/
diff --git a/backend/server.js b/backend/server.js
new file mode 100644
index 0000000..b3c2186
--- /dev/null
+++ b/backend/server.js
@@ -0,0 +1,11 @@
+import express from 'express';
+import { executeCommand } from './broker.mjs';
+const app = express();
+const port = 8080;
+app.post('/api/command', (req, res) => {
+ executeCommand();
+ res.status(200).send('Command executed');
+});
+app.listen(port, '0.0.0.0', () => {
+ console.log(`Server läuft auf http://0.0.0.0:${port}`);
+});
diff --git a/backend/server.ts b/backend/server.ts
index 3b2fdb6..1476ece 100644
--- a/backend/server.ts
+++ b/backend/server.ts
@@ -1,5 +1,6 @@
import express from 'express';
-import { executeCommand } from './broker.js';
+import { executeCommand } from './broker.ts';
+
const app = express();
const port = 8080;
diff --git a/dist/backend/broker.d.ts b/dist/backend/broker.d.ts
new file mode 100644
index 0000000..61adb3b
--- /dev/null
+++ b/dist/backend/broker.d.ts
@@ -0,0 +1,3 @@
+export declare function executeCommand(): void;
+export declare function html(inputText: string): string;
+//# sourceMappingURL=broker.d.ts.map
\ No newline at end of file
diff --git a/dist/backend/broker.d.ts.map b/dist/backend/broker.d.ts.map
new file mode 100644
index 0000000..c427dc0
--- /dev/null
+++ b/dist/backend/broker.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../backend/broker.ts"],"names":[],"mappings":"AAqBA,wBAAgB,cAAc,IAAI,IAAI,CAwBrC;AAwCD,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK9C"}
\ No newline at end of file
diff --git a/dist/backend/broker.js b/dist/backend/broker.js
new file mode 100644
index 0000000..3c3b807
--- /dev/null
+++ b/dist/backend/broker.js
@@ -0,0 +1,131 @@
+import { exec } from 'child_process';
+import * as fs from 'fs';
+var config;
+const nodemailer = require('nodemailer');
+export function executeCommand() {
+ exec('iching divine', (error, stdout, stderr) => {
+ console.log(`Begin`);
+ if (error) {
+ console.error(`Error: ${error.message}`);
+ return;
+ }
+ if (stderr) {
+ console.error(`Stderr: ${stderr}`);
+ return;
+ }
+ //Load config once
+ if (config == undefined) {
+ config = loadConfig();
+ }
+ console.log(`Send E-Mail`);
+ sendEmail(stdout);
+ });
+}
+// Run function once initially, called from Dockerfile
+executeCommand();
+// Load the Configuration
+function loadConfig() {
+ console.log(`Load Config`);
+ const data = fs.readFileSync('config.json', 'utf-8');
+ return JSON.parse(data);
+}
+// Send E-Mail
+async function sendEmail(content) {
+ // Create Transporter
+ const transporter = nodemailer.createTransport({
+ host: config.mailHost,
+ port: config.mailPort,
+ secure: false
+ });
+ try {
+ const info = await transporter.sendMail({
+ from: '"The Oracle" ',
+ to: config.emailReceiver,
+ subject: "Your Horoscope Is Ready",
+ text: content,
+ html: html(content)
+ });
+ console.log("E-Mail sent: ", info.messageId);
+ }
+ catch (error) {
+ console.error("Error Sending E-Mail:", error);
+ }
+}
+// Generate 1) Parse Tree and 2) HTML
+export function html(inputText) {
+ const parseTree = parse(inputText);
+ const htmlOutput = render(parseTree);
+ return htmlOutput;
+}
+// Generate the Parse Tree
+function parse(input) {
+ console.log("Parse input text");
+ const root = { type: "Root" };
+ var currentNode = root;
+ const lines = input.split("\n");
+ for (const line of lines) {
+ if (line.startsWith("Hexagram")) {
+ const hexagram = { type: "Hexagram" };
+ currentNode.child = hexagram;
+ currentNode = hexagram;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Judgement")) {
+ const judgement = { type: "Judgement" };
+ currentNode.child = judgement;
+ currentNode = judgement;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("Images")) {
+ const images = { type: "Images" };
+ currentNode.child = images;
+ currentNode = images;
+ currentNode.value = "" + line + "
";
+ }
+ else if (line.startsWith("~") && currentNode.type != "ChangingLines") {
+ const changingLines = { type: "ChangingLines" };
+ currentNode.child = changingLines;
+ currentNode = changingLines;
+ currentNode.value = line; // + "
"; TODO: try without this
+ }
+ else {
+ currentNode.value = currentNode.value + line + "
";
+ }
+ }
+ return root;
+}
+// Generate HTML from Parse Tree
+function render(node) {
+ if (node == undefined) {
+ console.log("Rendering of nodes finished!");
+ return "";
+ }
+ console.log("Render node" + node.type);
+ var outputHTML = "";
+ switch (node.type) {
+ case "Root":
+ return render(node.child);
+ case "Hexagram":
+ node.value = node.value?.replace("", "");
+ node.value = node.value?.replace("
", "
");
+ node.value = node.value?.replace("
", " - ");
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "Images":
+ outputHTML = "
" + node.value + "
"; //EXTRA closing div (was opened at beginning of hexagram)
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ case "ChangingLines":
+ const regex = new RegExp("~", "g");
+ node.value = node.value?.replace(regex, "");
+ //outputHTML = "
" + node.value + "
";
+ outputHTML = "
" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ default:
+ outputHTML = "" + node.value + "
";
+ outputHTML = outputHTML + render(node.child);
+ return outputHTML;
+ }
+}
diff --git a/dist/backend/broker.test.d.ts b/dist/backend/broker.test.d.ts
new file mode 100644
index 0000000..1be33f2
--- /dev/null
+++ b/dist/backend/broker.test.d.ts
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=broker.test.d.ts.map
\ No newline at end of file
diff --git a/dist/backend/broker.test.d.ts.map b/dist/backend/broker.test.d.ts.map
new file mode 100644
index 0000000..64ae74c
--- /dev/null
+++ b/dist/backend/broker.test.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"broker.test.d.ts","sourceRoot":"","sources":["../../backend/broker.test.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/backend/broker.test.js b/dist/backend/broker.test.js
new file mode 100644
index 0000000..e6acab6
--- /dev/null
+++ b/dist/backend/broker.test.js
@@ -0,0 +1,21 @@
+export {};
+/*import { html } from "./broker";
+import { test, beforeAll, afterAll } from "@jest/globals";
+
+jest.useFakeTimers();
+
+test("Generate HTML for hexagram", () => {
+ expect(html("Hexagram No. 45 ䷬\nGathering Together [Massing]\n萃 (cuì)"))
+ .toBe("
Hexagram No. 45 ䷬
Gathering Together [Massing] - 萃 (cuì)
");
+});
+
+test("Generate HTML for judgement", () => {
+ expect(html("Judgement:\nGathering Together. Success.\nThe king approaches his temple.\nIt furthers one to see the great man.\nThis brings success. Perseverance furthers.\nTo bring great offerings creates good fortune.\nIt furthers one to undertake something."))
+ .toBe("
Judgement:
Gathering Together. Success.
The king approaches his temple.
It furthers one to see the great man.
This brings success. Perseverance furthers.
To bring great offerings creates good fortune.
It furthers one to undertake something.
");
+});
+
+test("Generate HTML for images", () => {
+ expect(html("Images:\nOver the earth, the lake:\nThe image of Gathering Together.\nThus the superior man renews his weapons\nIn order to meet the unforseen."))
+ .toBe("
Images:
Over the earth, the lake:
The image of Gathering Together.
Thus the superior man renews his weapons
In order to meet the unforseen.
");
+});
+*/
diff --git a/dist/backend/server.d.ts b/dist/backend/server.d.ts
new file mode 100644
index 0000000..21e3405
--- /dev/null
+++ b/dist/backend/server.d.ts
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=server.d.ts.map
\ No newline at end of file
diff --git a/dist/backend/server.d.ts.map b/dist/backend/server.d.ts.map
new file mode 100644
index 0000000..aaf01ea
--- /dev/null
+++ b/dist/backend/server.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../backend/server.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/backend/server.js b/dist/backend/server.js
new file mode 100644
index 0000000..b3c2186
--- /dev/null
+++ b/dist/backend/server.js
@@ -0,0 +1,11 @@
+import express from 'express';
+import { executeCommand } from './broker.mjs';
+const app = express();
+const port = 8080;
+app.post('/api/command', (req, res) => {
+ executeCommand();
+ res.status(200).send('Command executed');
+});
+app.listen(port, '0.0.0.0', () => {
+ console.log(`Server läuft auf http://0.0.0.0:${port}`);
+});
diff --git a/frontend/event.js b/frontend/event.js
new file mode 100644
index 0000000..912bddd
--- /dev/null
+++ b/frontend/event.js
@@ -0,0 +1,15 @@
+"use strict";
+function handleClick() {
+ console.log("Der Button wurde geklickt!");
+ alert("Hallo von TypeScript!");
+ fetch("/api/command", { method: "POST" })
+ .then(res => res.text())
+ .then(text => console.log("Server sagt:", text));
+ /*fetch("https://192-168-197-2.c-one-infra.de/api/command", { method: "POST" })
+ .then(res => res.text())
+ .then(text => console.log("Server sagt:", text)); */
+}
+document.addEventListener("DOMContentLoaded", () => {
+ const button = document.getElementById("myButton");
+ button?.addEventListener("click", handleClick);
+});
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..7ee809b
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,6 @@
+"use strict";
+module.exports = {
+ transform: {
+ "^.+\\.tsx?$": "ts-jest"
+ }
+};
diff --git a/old.2.Dockerfile b/old.2.Dockerfile
new file mode 100644
index 0000000..fb7a8f1
--- /dev/null
+++ b/old.2.Dockerfile
@@ -0,0 +1,45 @@
+# 1. Node.js Build-Stage
+FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/node:20.18.1 AS build
+
+WORKDIR /app
+
+COPY package*.json ./
+COPY . .
+
+RUN npm install -g npm@11.2.0
+RUN npm install
+
+#RUN npx tsc -p tsconfig.json
+RUN npx tsc -p tsconfig.backend.json
+RUN npx tsc -p tsconfig.frontend.json
+
+
+### NEW # Danach:
+RUN find dist/backend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \;
+
+
+# 2. Rust build-Stage
+FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/rust:1.74.0 AS rust-build
+RUN cargo install iching
+
+# 3. Final runtime
+FROM forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/devfw-cicd/node:20.18.1
+
+WORKDIR /app
+
+### NEW ###
+COPY --from=build /app/node_modules ./node_modules
+
+COPY --from=build /app/dist ./dist
+#COPY --from=build /app/index.html ./dist/
+COPY --from=build /app/frontend/index.html ./dist/frontend/
+
+COPY --from=rust-build /usr/local/cargo/bin/iching /usr/local/bin/iching
+
+RUN find dist/backend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \;
+RUN find dist/frontend -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.mjs"' {} \;
+
+RUN node dist/backend/server.mjs &
+
+#CMD ["npx", "http-server", "dist", "-p", "8080", "--mime", "application/javascript=js"]
+CMD ["npx", "http-server", "dist/frontend", "-p", "8080", "--mime", "application/javascript=js"]
\ No newline at end of file
diff --git a/tsconfig.backend.json b/tsconfig.backend.json
index 890b5aa..0242d72 100644
--- a/tsconfig.backend.json
+++ b/tsconfig.backend.json
@@ -1,9 +1,17 @@
{
- "extends": "./tsconfig.json",
+ "extends": "./tsconfig.json", // Falls du eine allgemeine tsconfig hast
"compilerOptions": {
- "outDir": "./dist/backend",
- "module": "ESNext",
- "moduleResolution": "node"
+ "outDir": "./dist/backend", // Zielordner für die kompilierte Backend-Dateien
+ "module": "NodeNext", // Setze das Modul auf NodeNext
+ "moduleResolution": "NodeNext", // NodeNext für die Modulauflösung
+ "target": "ES2020", // Moderne JavaScript-Syntax verwenden
+ "esModuleInterop": true, // Interoperabilität mit CommonJS- und ES-Modulen
+ "allowSyntheticDefaultImports": true, // Synthetische Default-Imports erlauben
+ "allowImportingTsExtensions": true,
+ "skipLibCheck": true, // Bibliotheken werden nicht überprüft (Optional)
+ "noEmit": true
},
- "include": ["backend/**/*.ts"]
-}
\ No newline at end of file
+ "include": [
+ "backend/**/*.ts" // Nur Dateien im backend-Ordner kompilieren
+ ]
+ }
\ No newline at end of file