@lexho111/plainblog 0.3.3 → 0.3.5
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 +17 -54
- package/blog.db +0 -0
- package/build-styles.js +81 -0
- package/gulp_frontend/package.json +1 -8
- package/package.json +2 -13
- package/test_1767117403635.db +0 -0
- package/test_1767117781437.db +0 -0
- package/test_1767117944836.db +0 -0
- package/test_1767119505118.db +0 -0
package/Blog.js
CHANGED
|
@@ -2,10 +2,7 @@ import http from "http";
|
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import { URLSearchParams } from "url";
|
|
5
|
-
import { Readable, Transform, Writable, pipeline } from "stream";
|
|
6
5
|
import { MapTransform } from "./streams.js";
|
|
7
|
-
import { fromEvent, firstValueFrom } from "rxjs";
|
|
8
|
-
import { map, scan, takeUntil, last, defaultIfEmpty } from "rxjs/operators";
|
|
9
6
|
import Article from "./Article.js";
|
|
10
7
|
import DatabaseModel from "./model/DatabaseModel.js";
|
|
11
8
|
import { fetchData, postData } from "./model/APIModel.js";
|
|
@@ -16,8 +13,7 @@ import path from "path";
|
|
|
16
13
|
import { fileURLToPath } from "url";
|
|
17
14
|
import { exec } from "child_process";
|
|
18
15
|
import { promisify } from "util";
|
|
19
|
-
import
|
|
20
|
-
import { compileStyles, compileScripts } from "./gulp_frontend/gulpfile.js";
|
|
16
|
+
import { compileStyles } from "./build-styles.js";
|
|
21
17
|
|
|
22
18
|
const execPromise = promisify(exec);
|
|
23
19
|
|
|
@@ -144,14 +140,12 @@ export default class Blog {
|
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
async handleLogin(req, res) {
|
|
147
|
-
const body
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
);
|
|
154
|
-
const body = await firstValueFrom(body$);
|
|
143
|
+
const body = await new Promise((resolve, reject) => {
|
|
144
|
+
let data = "";
|
|
145
|
+
req.on("data", (chunk) => (data += chunk.toString()));
|
|
146
|
+
req.on("end", () => resolve(data));
|
|
147
|
+
req.on("error", reject);
|
|
148
|
+
});
|
|
155
149
|
const params = new URLSearchParams(body);
|
|
156
150
|
|
|
157
151
|
if (params.get("password") === this.#password) {
|
|
@@ -219,22 +213,12 @@ export default class Blog {
|
|
|
219
213
|
|
|
220
214
|
/** post a blog article */
|
|
221
215
|
async postArticle(req, res) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
// Create a stream of the body string
|
|
229
|
-
const body$ = fromEvent(req, "data").pipe(
|
|
230
|
-
map((chunk) => chunk.toString()),
|
|
231
|
-
scan((acc, chunk) => acc + chunk, ""), // Accumulate chunks
|
|
232
|
-
takeUntil(fromEvent(req, "end")), // Stop when 'end' emits
|
|
233
|
-
last(), // Emit only the final full string
|
|
234
|
-
defaultIfEmpty("") // Handle empty bodies
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
const body = await firstValueFrom(body$);
|
|
216
|
+
const body = await new Promise((resolve, reject) => {
|
|
217
|
+
let data = "";
|
|
218
|
+
req.on("data", (chunk) => (data += chunk.toString()));
|
|
219
|
+
req.on("end", () => resolve(data));
|
|
220
|
+
req.on("error", reject);
|
|
221
|
+
});
|
|
238
222
|
|
|
239
223
|
//req.on("end", async () => {
|
|
240
224
|
const params = new URLSearchParams(body);
|
|
@@ -523,20 +507,10 @@ export default class Blog {
|
|
|
523
507
|
if (currentHash !== this.#stylesHash) {
|
|
524
508
|
console.log("Style assets have changed. Recompiling...");
|
|
525
509
|
this.#stylesHash = currentHash;
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
cwd: process.cwd(),
|
|
531
|
-
base: path.dirname(f.path),
|
|
532
|
-
path: f.path,
|
|
533
|
-
contents: f.content,
|
|
534
|
-
})
|
|
535
|
-
);
|
|
536
|
-
|
|
537
|
-
const stream = Readable.from(vinyls);
|
|
538
|
-
const outputStream = compileStyles(stream);
|
|
539
|
-
this.compiledStyles = await this.#streamToString(outputStream);
|
|
510
|
+
|
|
511
|
+
// Compile styles using the standalone script
|
|
512
|
+
this.compiledStyles = await compileStyles(fileData);
|
|
513
|
+
|
|
540
514
|
await fs.promises.writeFile(
|
|
541
515
|
path.join(__dirname, "styles.min.css"),
|
|
542
516
|
this.compiledStyles + `\n/* source-hash: ${currentHash} */`
|
|
@@ -547,17 +521,6 @@ export default class Blog {
|
|
|
547
521
|
}
|
|
548
522
|
}
|
|
549
523
|
|
|
550
|
-
#streamToString(stream) {
|
|
551
|
-
return new Promise((resolve, reject) => {
|
|
552
|
-
let data = "";
|
|
553
|
-
stream.on("data", (file) => {
|
|
554
|
-
if (file.contents) data += file.contents.toString();
|
|
555
|
-
});
|
|
556
|
-
stream.on("end", () => resolve(data));
|
|
557
|
-
stream.on("error", reject);
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
|
|
561
524
|
async #findAssetFiles() {
|
|
562
525
|
const __filename = fileURLToPath(import.meta.url);
|
|
563
526
|
const __dirname = path.dirname(__filename);
|
package/blog.db
ADDED
|
Binary file
|
package/build-styles.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
import * as sass from "sass";
|
|
5
|
+
import postcss from "postcss";
|
|
6
|
+
import autoprefixer from "autoprefixer";
|
|
7
|
+
import cssnano from "cssnano";
|
|
8
|
+
|
|
9
|
+
// Configuration
|
|
10
|
+
const srcDir = path.join("gulp_frontend", "src");
|
|
11
|
+
|
|
12
|
+
// Helper to find files recursively
|
|
13
|
+
async function getFiles(dir) {
|
|
14
|
+
const dirents = await fs.readdir(dir, { withFileTypes: true });
|
|
15
|
+
const files = await Promise.all(
|
|
16
|
+
dirents.map((dirent) => {
|
|
17
|
+
const res = path.resolve(dir, dirent.name);
|
|
18
|
+
return dirent.isDirectory() ? getFiles(res) : res;
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
return Array.prototype.concat(...files);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function compileStyles(fileData) {
|
|
25
|
+
try {
|
|
26
|
+
let combinedCss = "";
|
|
27
|
+
|
|
28
|
+
if (fileData) {
|
|
29
|
+
const scssFiles = fileData.filter(
|
|
30
|
+
(f) =>
|
|
31
|
+
f.path.endsWith(".scss") && !path.basename(f.path).startsWith("_")
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
for (const file of scssFiles) {
|
|
35
|
+
try {
|
|
36
|
+
const result = sass.compileString(file.content.toString(), {
|
|
37
|
+
loadPaths: [srcDir],
|
|
38
|
+
style: "expanded",
|
|
39
|
+
url: pathToFileURL(file.path),
|
|
40
|
+
});
|
|
41
|
+
combinedCss += result.css + "\n";
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(
|
|
44
|
+
`Error compiling ${path.basename(file.path)}:`,
|
|
45
|
+
err.message
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
const allFiles = await getFiles(srcDir);
|
|
51
|
+
const scssFiles = allFiles
|
|
52
|
+
.filter((f) => f.endsWith(".scss") && !path.basename(f).startsWith("_"))
|
|
53
|
+
.sort();
|
|
54
|
+
|
|
55
|
+
for (const file of scssFiles) {
|
|
56
|
+
try {
|
|
57
|
+
const result = sass.compile(file, {
|
|
58
|
+
loadPaths: [srcDir],
|
|
59
|
+
style: "expanded",
|
|
60
|
+
});
|
|
61
|
+
combinedCss += result.css + "\n";
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(`Error compiling ${path.basename(file)}:`, err.message);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 2. PostCSS (Autoprefixer + CSSNano)
|
|
69
|
+
if (combinedCss) {
|
|
70
|
+
const plugins = [autoprefixer(), cssnano()];
|
|
71
|
+
const result = await postcss(plugins).process(combinedCss, {
|
|
72
|
+
from: undefined,
|
|
73
|
+
});
|
|
74
|
+
return result.css;
|
|
75
|
+
}
|
|
76
|
+
return "";
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("Build failed:", error);
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -15,14 +15,7 @@
|
|
|
15
15
|
"@babel/preset-env": "^7.28.5",
|
|
16
16
|
"autoprefixer": "^10.4.23",
|
|
17
17
|
"cssnano": "^7.1.2",
|
|
18
|
-
"
|
|
19
|
-
"gulp-babel": "^8.0.0",
|
|
20
|
-
"gulp-concat": "^2.6.1",
|
|
21
|
-
"gulp-postcss": "^10.0.0",
|
|
22
|
-
"gulp-rename": "^2.1.0",
|
|
23
|
-
"gulp-sass": "^6.0.1",
|
|
24
|
-
"gulp-sourcemaps": "^3.0.0",
|
|
25
|
-
"gulp-uglify": "^3.0.2",
|
|
18
|
+
"postcss": "^8.4.35",
|
|
26
19
|
"sass": "^1.97.1"
|
|
27
20
|
}
|
|
28
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexho111/plainblog",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "A tool for creating and serving a minimalist, single-page blog.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -19,22 +19,11 @@
|
|
|
19
19
|
"node-fetch": "^3.3.2",
|
|
20
20
|
"pg": "^8.16.3",
|
|
21
21
|
"pg-hstore": "^2.3.4",
|
|
22
|
-
"rxjs": "^7.8.2",
|
|
23
22
|
"sequelize": "^6.37.7",
|
|
24
23
|
"sqlite3": "^5.1.7",
|
|
25
|
-
"vinyl": "^3.0.1",
|
|
26
|
-
"@babel/core": "^7.28.5",
|
|
27
|
-
"@babel/preset-env": "^7.28.5",
|
|
28
24
|
"autoprefixer": "^10.4.23",
|
|
29
25
|
"cssnano": "^7.1.2",
|
|
30
|
-
"
|
|
31
|
-
"gulp-babel": "^8.0.0",
|
|
32
|
-
"gulp-concat": "^2.6.1",
|
|
33
|
-
"gulp-postcss": "^10.0.0",
|
|
34
|
-
"gulp-rename": "^2.1.0",
|
|
35
|
-
"gulp-sass": "^6.0.1",
|
|
36
|
-
"gulp-sourcemaps": "^3.0.0",
|
|
37
|
-
"gulp-uglify": "^3.0.2",
|
|
26
|
+
"postcss": "^8.4.35",
|
|
38
27
|
"sass": "^1.97.1"
|
|
39
28
|
},
|
|
40
29
|
"devDependencies": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|