diff options
| -rw-r--r-- | Dockerfile | 9 | ||||
| -rw-r--r-- | app/builder/pageDirectory.ts | 63 | ||||
| -rw-r--r-- | package-lock.json | 51 | ||||
| -rw-r--r-- | package.json | 10 | ||||
| -rw-r--r-- | tsconfig.json | 3 |
5 files changed, 82 insertions, 54 deletions
@@ -1,4 +1,4 @@ -FROM node:alpine AS build +FROM node:20-alpine AS build WORKDIR /app @@ -6,16 +6,15 @@ COPY --chown=node:node package*.json ./ COPY --chown=node:node tsconfig.json ./ -RUN npm i -g typescript\ - && npm i +RUN npm i COPY --chown=node:node app app -RUN tsc +RUN npx tsc -FROM node:alpine +FROM node:20-alpine LABEL org.opencontainers.image.source=https://github.com/LMBishop/panulat diff --git a/app/builder/pageDirectory.ts b/app/builder/pageDirectory.ts index 1aed94e..82c14fa 100644 --- a/app/builder/pageDirectory.ts +++ b/app/builder/pageDirectory.ts @@ -1,9 +1,10 @@ -import { readFileSync } from 'fs'; -import glob from 'glob'; -import { logger } from '../logger.js' -import { marked } from 'marked'; -import { gfmHeadingId } from 'marked-gfm-heading-id'; -import matter from 'gray-matter'; +import { readFileSync } from "fs"; +import glob from "glob"; +import { logger } from "../logger.js"; +import { marked } from "marked"; +import { gfmHeadingId } from "marked-gfm-heading-id"; +import markedFootnote from "marked-footnote"; +import matter from "gray-matter"; marked.use(gfmHeadingId()); @@ -11,19 +12,21 @@ export async function parsePage(page: Page) { try { const frontmatter = matter(page.raw); const config = frontmatter.data; - const html = marked.parse(frontmatter.content, { mangle: false }); + const html = marked + .use(markedFootnote()) + .parse(frontmatter.content, { mangle: false }); page.html = html; page.config = config; - page.view = config.view || 'index'; + page.view = config.view || "index"; page.buildTime = Date.now(); - } catch (e) { + } catch (e) { logger.error(`Failed to parse page ${page.originalPath}: ${e.message}`); } } function loadRaw(path: string): string { - return readFileSync(`${path}`, 'utf-8'); + return readFileSync(`${path}`, "utf-8"); } export class PageDirectory { @@ -31,7 +34,7 @@ export class PageDirectory { private pages: Record<string, Page> = {}; private lastFullBuild: number; - + constructor(pagesPath: string) { this.pagesPath = pagesPath; @@ -39,22 +42,22 @@ export class PageDirectory { delete this.pages[page]; } } - + public init = async (): Promise<void> => { - const localPages = glob.sync(`**/*.{md,html}`, { cwd: this.pagesPath }) + const localPages = glob.sync(`**/*.{md,html}`, { cwd: this.pagesPath }); for (const page in localPages) { await this.loadPage(localPages[page]); } this.lastFullBuild = Date.now(); - } - + }; + public loadPage = async (page: string): Promise<Page> => { - let route = `/${page.replace(/\.[^.]*$/,'')}`; + let route = `/${page.replace(/\.[^.]*$/, "")}`; let name = /[^/]*$/.exec(route)[0]; let originalPath = page; - let fullPath = `${this.pagesPath}/${page}` - let buildPath = `${process.env.OUTPUT_DIR}/${route}.html` - let view = `${route}` + let fullPath = `${this.pagesPath}/${page}`; + let buildPath = `${process.env.OUTPUT_DIR}/${route}.html`; + let view = `${route}`; let raw: string; try { raw = loadRaw(fullPath); @@ -72,18 +75,18 @@ export class PageDirectory { view: view, raw: raw, buildTime: 0, - config: {} - } - + config: {}, + }; + await parsePage(this.pages[route]); - + return this.pages[route]; - } - + }; + public removePage = (page: string): void => { - let route = page.replace(/\.[^.]*$/,'') + let route = page.replace(/\.[^.]*$/, ""); delete this.pages[route]; - } + }; public get(name: string): Page { const page = this.pages[name]; @@ -97,9 +100,11 @@ export class PageDirectory { public getPages(): Page[] { return Object.values(this.pages); } - + public getPagesBeginningWith(prefix: string): Page[] { - return Object.values(this.pages).filter(page => page.route.startsWith(prefix)); + return Object.values(this.pages).filter((page) => + page.route.startsWith(prefix) + ); } } diff --git a/package-lock.json b/package-lock.json index ced5197..8651bb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,6 @@ "name": "panulat", "version": "1.2", "dependencies": { - "@types/clean-css": "^4.2.6", - "@types/html-minifier-terser": "^7.0.0", "axios": "^1.4.0", "chokidar": "^3.5.3", "clean-css": "^5.3.2", @@ -21,7 +19,8 @@ "glob": "^7.2.0", "gray-matter": "^4.0.3", "html-minifier-terser": "^7.2.0", - "marked": "^6.0.0", + "marked": "^7.0.0", + "marked-footnote": "^1.2.4", "marked-gfm-heading-id": "^3.0.6", "sass": "^1.66.1", "uglify-js": "^3.17.4", @@ -29,15 +28,18 @@ "ws": "^8.13.0" }, "devDependencies": { + "@types/clean-css": "^4.2.6", "@types/dateformat": "^5.0.0", "@types/escape-html": "^1.0.1", "@types/express": "^4.17.13", "@types/glob": "^7.2.0", + "@types/html-minifier-terser": "^7.0.0", "@types/uglify-js": "^3.17.1", "@types/ws": "^8.5.4", "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", - "eslint": "^8.5.0" + "eslint": "^8.5.0", + "typescript": "5.5.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -257,6 +259,7 @@ "version": "4.2.6", "resolved": "https://registry.npmjs.org/@types/clean-css/-/clean-css-4.2.6.tgz", "integrity": "sha512-Ze1tf+LnGPmG6hBFMi0B4TEB0mhF7EiMM5oyjLDNPE9hxrPU0W+5+bHvO+eFPA+bt0iC1zkQMoU/iGdRVjcRbw==", + "dev": true, "dependencies": { "@types/node": "*", "source-map": "^0.6.0" @@ -320,7 +323,8 @@ "node_modules/@types/html-minifier-terser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-7.0.0.tgz", - "integrity": "sha512-hw3bhStrg5e3FQT8qZKCJTrzt/UbEaunU1xRWJ+aNOTmeBMvE3S4Ml2HiiNnZgL8izu0LFVkHUoPFXL1s5QNpQ==" + "integrity": "sha512-hw3bhStrg5e3FQT8qZKCJTrzt/UbEaunU1xRWJ+aNOTmeBMvE3S4Ml2HiiNnZgL8izu0LFVkHUoPFXL1s5QNpQ==", + "dev": true }, "node_modules/@types/http-errors": { "version": "2.0.1", @@ -347,9 +351,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", - "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/qs": { "version": "6.9.7", @@ -2194,9 +2202,9 @@ } }, "node_modules/marked": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-6.0.0.tgz", - "integrity": "sha512-7E3m/xIlymrFL5gWswIT4CheIE3fDeh51NV09M4x8iOc7NDYlyERcQMLAIHcSlrvwliwbPQ4OGD+MpPSYiQcqw==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-7.0.5.tgz", + "integrity": "sha512-lwNAFTfXgqpt/XvK17a/8wY9/q6fcSPZT1aP6QW0u74VwaJF/Z9KbRcX23sWE4tODM+AolJNcUtErTkgOeFP/Q==", "bin": { "marked": "bin/marked.js" }, @@ -2204,6 +2212,14 @@ "node": ">= 16" } }, + "node_modules/marked-footnote": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marked-footnote/-/marked-footnote-1.2.4.tgz", + "integrity": "sha512-DB2Kl+wFh6YwZd70qABMY6WUkG1UuyqoNTFoDfGyG79Pz24neYtLBkB+45a7o72V7gkfvbC3CGzIYFobxfMT1Q==", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, "node_modules/marked-gfm-heading-id": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/marked-gfm-heading-id/-/marked-gfm-heading-id-3.0.6.tgz", @@ -3108,11 +3124,10 @@ } }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3132,6 +3147,12 @@ "node": ">=0.8.0" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index a953c9c..286b2a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "panulat", - "version": "1.2", + "version": "1.3", "description": "", "main": "app/index.mjs", "scripts": { @@ -9,8 +9,6 @@ }, "author": "Leonardo Bishop", "dependencies": { - "@types/clean-css": "^4.2.6", - "@types/html-minifier-terser": "^7.0.0", "axios": "^1.4.0", "chokidar": "^3.5.3", "clean-css": "^5.3.2", @@ -22,7 +20,8 @@ "glob": "^7.2.0", "gray-matter": "^4.0.3", "html-minifier-terser": "^7.2.0", - "marked": "^6.0.0", + "marked": "^7.0.0", + "marked-footnote": "^1.2.4", "marked-gfm-heading-id": "^3.0.6", "sass": "^1.66.1", "uglify-js": "^3.17.4", @@ -31,6 +30,8 @@ }, "type": "module", "devDependencies": { + "@types/clean-css": "^4.2.6", + "@types/html-minifier-terser": "^7.0.0", "@types/dateformat": "^5.0.0", "@types/escape-html": "^1.0.1", "@types/express": "^4.17.13", @@ -39,6 +40,7 @@ "@types/ws": "^8.5.4", "@typescript-eslint/eslint-plugin": "^5.7.0", "@typescript-eslint/parser": "^5.7.0", + "typescript": "5.5.4", "eslint": "^8.5.0" } } diff --git a/tsconfig.json b/tsconfig.json index 90ae06b..996d9fd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "module": "es2022", "moduleResolution": "node", "allowSyntheticDefaultImports": true, - "strict": false + "strict": false, + "skipLibCheck": true }, "include": ["./app/**/*.ts"], } |
