Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions lib/dovecot_vitepress_init.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
import { dataFileList, publicDataDir } from './datafiles.js'
import { dovecotMdInit } from './markdown.js'
import { logger } from './logger.js'
import fs from 'fs'

let has_run = false

export default function dovecotVitepressInit() {
return {
name: 'dovecot-vitepress-init',
async configResolved(config) {
/*** Init Dovecot Markdown. ***/
return {
name: 'dovecot-vitepress-init',
async configResolved(config) {
/*** Init Dovecot Markdown. ***/

/* We need to synchronously initialize markdown,
* since we need to pre-populate various internal
* tables (e.g. links). */
await dovecotMdInit()
console.log('\n✅ Dovecot Markdown initialized.')
/* We need to synchronously initialize markdown,
* since we need to pre-populate various internal
* tables (e.g. links). */
await dovecotMdInit()
logger.success('Dovecot Markdown initialized', { once: true })

/*** Create static downloadable data files. ***/
/*** Create static downloadable data files. ***/

if (has_run) {
return
}
has_run = true
if (has_run) return
has_run = true

/* Clean old data files (if they exist) and prepare directory. */
fs.rmSync(publicDataDir, { force: true, recursive: true });
fs.mkdirSync(publicDataDir, { recursive: true });
console.log(`✅ Data files: Created ${publicDataDir}.`)
/* Clean old data files (if they exist) and prepare directory. */
fs.rmSync(publicDataDir, { force: true, recursive: true });
fs.mkdirSync(publicDataDir, { recursive: true });
logger.success(`Data files: Created ${publicDataDir}`)

/* Build the data files. */
for (const d of dataFileList) {
fs.writeFileSync(
d.json,
JSON.stringify(await d.data(), null, 2)
)
console.log(`✅ Data files: Generated ${d.json}.`)
}
}
}
/* Build the data files. */
for (const d of dataFileList) {
fs.writeFileSync(
d.json,
JSON.stringify(await d.data(), null, 2)
)
logger.success(`Data files: Generated ${d.json}`)
}
}
}
}
34 changes: 34 additions & 0 deletions lib/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* Standardized logging utility. */

if (!globalThis.__LOGGED_ONCE__) {
globalThis.__LOGGED_ONCE__ = new Set()
}

let logQueue = Promise.resolve()

export const logger = {
success(message, { once = false, newline = false } = {}) {
if (once) {
if (globalThis.__LOGGED_ONCE__.has(message)) return
globalThis.__LOGGED_ONCE__.add(message)
}

logQueue = logQueue.then(() => {
console.log(`${newline ? '\n' : ''}✅ ${message}.`)
})
},

fatal(message) {
const err = new Error(message)
const stack = err.stack.split('\n')

/* The first line of stack is 'Error: message'.
* The second line is the call to logger.fatal().
* The third line is the actual location of the error. */
const callSite = stack[2] ? stack[2].trim() : 'unknown location'

console.error(`\n❌ FATAL ERROR: ${message}`)
console.error(` at ${callSite}\n`)
process.exit(1)
}
}
5 changes: 3 additions & 2 deletions lib/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fg from 'fast-glob'
import deflistPlugin from 'markdown-it-deflist'
import path from 'path'
import { createMarkdownRenderer } from 'vitepress'
import { logger } from "./logger.js"
import { dovecotSetting, frontmatterIter, loadData } from './utility.js'

let md_conf = false
Expand All @@ -25,7 +26,7 @@ export async function dovecotMdInit() {

for (const [k, v] of Object.entries(data.dovecotlinks)) {
if (links[k]) {
throw new Error("Duplicate Dovecot Link key: " + k)
logger.fatal("Duplicate Dovecot Link key: " + k)
}

links[k] = {
Expand Down Expand Up @@ -404,7 +405,7 @@ function dovecot_markdown(md, opts) {

function handle_error(msg) {
if (process.env.NODE_ENV !== 'development') {
throw new Error(msg)
logger.fatal(msg)
}
console.error(msg)
}
Expand Down
7 changes: 4 additions & 3 deletions lib/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fs from 'fs'
import matter from 'gray-matter'
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { logger } from './logger.js'

const __filename = fileURLToPath(import.meta.url)
export const lib_dirname = dirname(__filename)
Expand Down Expand Up @@ -35,8 +36,8 @@ export async function loadData(id) {
try {
dataOb[id] = await import(lib_dirname + '/' + path)
} catch (e) {
throw new Error('Unable to import module (' + lib_dirname + '/' +
path + '):' + e)
logger.fatal('Unable to import module (' + lib_dirname + '/' +
path + '):' + e.message)
}
}

Expand All @@ -45,7 +46,7 @@ export async function loadData(id) {

function _dovecotSetting(name, setting) {
if (setting === undefined) {
throw new Error("Missing '" + name + "' setting")
logger.fatal("Missing '" + name + "' setting")
}

return setting
Expand Down
Loading