@lexho111/plainblog 0.0.11 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Blog.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import http from "http";
2
- import fetch from "node-fetch";
2
+ import fs from "fs";
3
3
  import { URLSearchParams } from "url";
4
4
  import { fromEvent, firstValueFrom } from "rxjs";
5
5
  import { map, scan, takeUntil, last, defaultIfEmpty } from "rxjs/operators";
@@ -8,12 +8,15 @@ import DatabaseModel from "./model/DatabaseModel.js";
8
8
  import { fetchData, postData } from "./model/APIModel.js";
9
9
  import { save as saveToFile, load as loadFromFile } from "./model/fileModel.js";
10
10
  import { formatHTML, formatMarkdown, validate } from "./Formatter.js";
11
+ import pkg from "./package.json" with { type: "json" };;
12
+ import path from "path";
13
+ import { fileURLToPath } from "url";
11
14
 
12
15
  export default class Blog {
13
16
  constructor() {
14
17
  this.title = "";
15
18
  this.articles = [];
16
- this.style = "body { font-family: Arial; }";
19
+ this.styles = "";
17
20
  this.filename = null;
18
21
  this.#server = null;
19
22
 
@@ -24,6 +27,42 @@ export default class Blog {
24
27
  host: "localhost",
25
28
  dbname: "blog",
26
29
  };
30
+
31
+ const version = pkg.version;
32
+ console.log(`version: ${version}`);
33
+
34
+ this.loadScripts();
35
+
36
+ if(this.styles.length == 0) { // no style override specified via index.js
37
+ this.styles = "body { font-family: Arial; }"; // apply default style
38
+ this.loadStyles();
39
+ }
40
+ //console.log(styles)
41
+ }
42
+
43
+ loadScripts() {
44
+ const __filename = fileURLToPath(import.meta.url);
45
+ const __dirname = path.dirname(__filename);
46
+ this.scripts = "";
47
+ try {
48
+ this.scripts = fs.readFileSync(
49
+ path.join(__dirname, "scripts.min.js"),
50
+ "utf-8"
51
+ );
52
+ } catch(err) {
53
+ console.error("no scripts.min.js file found")
54
+ }
55
+ }
56
+
57
+ loadStyles() {
58
+ const __filename = fileURLToPath(import.meta.url);
59
+ const __dirname = path.dirname(__filename);
60
+ try {
61
+ this.styles = fs.readFileSync(
62
+ path.join(__dirname, "styles.min.css"), "utf-8");
63
+ } catch(err) {
64
+ console.error("no styles.min.css file found")
65
+ }
27
66
  }
28
67
 
29
68
  // Private fields
@@ -41,7 +80,7 @@ export default class Blog {
41
80
  }
42
81
 
43
82
  setStyle(style) {
44
- this.style = style;
83
+ this.styles = style;
45
84
  }
46
85
 
47
86
  /** initializes database */
@@ -126,6 +165,8 @@ export default class Blog {
126
165
  } else if (req.method === "GET" && req.url === "/") {
127
166
  // load articles
128
167
 
168
+ //this.loadScripts(); this.loadStyles();
169
+
129
170
  const html = await this.toHTML(); // render this blog to HTML
130
171
  res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
131
172
  res.end(html);
@@ -199,8 +240,16 @@ export default class Blog {
199
240
  // controller
200
241
  /** everything that happens in /api */
201
242
  async #jsonAPI(req, res) {
243
+ if(req.method === "GET") {
244
+ if(req.url === "/api" || req.url === "/api/") {
245
+ res.writeHead(200, { "Content-Type": "application/json" });
246
+ const data = {
247
+ title: this.title
248
+ }
249
+ res.end(JSON.stringify(data));
250
+ }
202
251
  // GET all blog data
203
- if (req.method === "GET" && req.url === "/api") {
252
+ if (req.url === "/api/articles") {
204
253
  // controller
205
254
  res.writeHead(200, { "Content-Type": "application/json" });
206
255
  const dbArticles = await this.#databaseModel.findAll();
@@ -213,7 +262,7 @@ export default class Blog {
213
262
  }
214
263
 
215
264
  // POST a new article
216
- else if (req.method === "POST" && req.url === "/api/articles") {
265
+ } else if (req.method === "POST" && req.url === "/api/articles") {
217
266
  let body = "";
218
267
  req.on("data", (chunk) => (body += chunk.toString()));
219
268
  req.on("end", async () => {
@@ -249,10 +298,10 @@ export default class Blog {
249
298
  toHTML() {
250
299
  const data = {
251
300
  title: this.title,
252
- style: this.style,
253
301
  articles: this.articles,
254
302
  };
255
- const html = formatHTML(data);
303
+
304
+ const html = formatHTML(data, this.scripts, this.styles);
256
305
  if (validate(html)) return html;
257
306
  else throw new Error("Error. Invalid HTML!");
258
307
  }
package/Formatter.js CHANGED
@@ -1,28 +1,13 @@
1
1
  /** format content to html */
2
- export function formatHTML(data) {
3
- const script = `function generateRandomContent(length) {
4
- let str = "";
5
- const char = "A";
6
- for (let i = 0; i < length; i++) {
7
- const rnd = Math.random() * ("z".charCodeAt(0) - "A".charCodeAt(0)); // A z.charCodeAt(0)"
8
- const char1 = String.fromCharCode(char.charCodeAt(0) + rnd);
9
- str += char1;
10
- }
11
- return str;
12
- }
13
- function fillWithContent() {
14
- let title = document.getElementById("title");
15
- let cont = document.getElementById("content");
16
- cont.value = generateRandomContent(200);
17
- title.value = generateRandomContent(50);
18
- }`;
2
+ export function formatHTML(data, script, style) {
3
+ //export function formatHTML(data) {
19
4
  const button = `<button type="button" onClick="fillWithContent();" style="margin: 4px;">generate random text</button>`;
20
5
  return `<!DOCTYPE html>
21
6
  <html lang="de">
22
7
  <head>
23
8
  <meta charset="UTF-8">
24
9
  <title>${data.title}</title>
25
- <style>${data.style}</style>
10
+ <style>${style}</style>
26
11
  </head>
27
12
  <body>
28
13
  <h1>${data.title}</h1>
@@ -31,7 +16,7 @@ export function formatHTML(data) {
31
16
  <h3>Add a New Article</h3>
32
17
  <input type="text" id="title" name="title" placeholder="Article Title" required style="display: block; width: 300px; margin-bottom: 10px;">
33
18
  <textarea id="content" name="content" placeholder="Article Content" required style="display: block; width: 300px; height: 100px; margin-bottom: 10px;"></textarea>
34
- <button type="submit">Add Article</button>
19
+ <button type="submit">Add Article</button>${button}
35
20
  <script>
36
21
  ${script}
37
22
  </script>
package/README.md CHANGED
@@ -33,7 +33,7 @@ import Blog from "@lexho111/plainblog";
33
33
 
34
34
  const blog = new Blog();
35
35
  blog.database.type = "postgres";
36
- blog.database.user = "user";
36
+ blog.database.username = "user";
37
37
  blog.database.password = "password";
38
38
  blog.database.host = "localhost";
39
39
  blog.setStyle("body { font-family: Arial, sans-serif; } h1 { color: #333; }");
@@ -67,9 +67,9 @@ blog.setStyle("body { font-family: Arial, sans-serif; } h1 { color: #333; }");
67
67
  const article = new Article("hello", "hello world!");
68
68
  blog.addArticle(article);
69
69
 
70
- blog.save("blog.json");
70
+ blog.save("myblog.json");
71
71
 
72
- # load data from 'myblog.json'
72
+ // load data from 'myblog.json'
73
73
  await blog.load("myblog.json");
74
74
  ```
75
75
 
package/blog ADDED
Binary file
package/blog.db CHANGED
Binary file
@@ -14,9 +14,11 @@ export default class DatabaseModel {
14
14
  constructor(options) {
15
15
  const databasetype = options.type; // the database type defines
16
16
  if (databasetype === "sqlite") {
17
+ // Use the full path for the database file from the options.
18
+ if (options.dbname) this.#dbname = options.dbname;
17
19
  this.#sequelize = new Sequelize({
18
20
  dialect: "sqlite",
19
- storage: `./${this.#dbname}.db`,
21
+ storage: this.#dbname + ".db",
20
22
  logging: false,
21
23
  });
22
24
  } else if (databasetype === "postgres") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexho111/plainblog",
3
- "version": "0.0.11",
3
+ "version": "0.1.0",
4
4
  "description": "A tool for creating and serving a minimalist, single-page blog.",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/scripts.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! gruntproject 2025-12-21 */
2
+ function generateRandomContent(t){let n="";for(let e=0;e<t;e++){var o=Math.random()*("z".charCodeAt(0)-"A".charCodeAt(0)),o=String.fromCharCode("A".charCodeAt(0)+o);n+=o}return n}function fillWithContent(){var e=document.getElementById("title");document.getElementById("content").value=generateRandomContent(200),e.value=generateRandomContent(50)}
package/styles.min.css ADDED
@@ -0,0 +1 @@
1
+ body{font-family:Courier;background-color:#d3d3d3}div{color:#000;width:500px}h1,h2,h3{font-weight:700}
@@ -11,7 +11,7 @@ import Blog from "../Blog.js";
11
11
  * blog.startServer(8080);
12
12
  */
13
13
 
14
- const PORT = 8080;
14
+ const PORT = 8090;
15
15
  const apiBaseUrl = `http://localhost:${PORT}`;
16
16
 
17
17
  describe("server test", () => {
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file