Add config file support

This commit is contained in:
√(noham)²
2026-06-19 21:17:16 +02:00
parent 908ae04ddb
commit 93d24e5103
6 changed files with 102 additions and 10 deletions

View File

@@ -22,6 +22,7 @@ program
`Reader View theme (${VALID_THEMES.join(', ')})`
)
.option('-c, --css <path>', 'path to custom CSS file')
.option('--config <path>', 'path to config file (.pdfyrc, .pdfyrc.json, pdfy.config.js)')
.option('-p, --prefs <path>', 'path to extension preferences JSON')
.option(
'-o, --output <path>',
@@ -50,7 +51,8 @@ export function parseArgs () {
theme: opts.theme || null,
css: opts.css || null,
prefs: opts.prefs || null,
output: opts.output || null
output: opts.output || null,
config: opts.config || null
}
}
}

View File

@@ -1,7 +1,54 @@
import fs from 'node:fs'
import path from 'node:path'
import { pathToFileURL } from 'node:url'
import logger from './logger.js'
const CONFIG_FILE_NAMES = ['.pdfyrc', '.pdfyrc.json', 'pdfy.config.js']
function normalizeConfig (config) {
const result = {}
if (config.theme) result.theme = config.theme
if (config.css) result.css = config.css
if (config.prefs) result.prefs = config.prefs
if (config.output) result.output = config.output
if (config['log-level']) result.logLevel = config['log-level']
if (config.logLevel) result.logLevel = config.logLevel
return result
}
function findConfigFile () {
for (const name of CONFIG_FILE_NAMES) {
const fullPath = path.resolve(name)
if (fs.existsSync(fullPath)) return fullPath
}
return null
}
async function parseConfigFile (filePath) {
if (filePath.endsWith('.js')) {
const mod = await import(pathToFileURL(filePath).href)
return normalizeConfig(mod.default || {})
}
const raw = fs.readFileSync(filePath, 'utf-8')
return normalizeConfig(JSON.parse(raw))
}
export async function loadConfigFile (configPath) {
const target = configPath
? path.resolve(configPath)
: findConfigFile()
if (!target || !fs.existsSync(target)) return {}
logger.debug(`Config loaded from: "${target}"`)
try {
return await parseConfigFile(target)
} catch (err) {
logger.warn(`Could not parse config file "${target}": ${err.message}`)
return {}
}
}
export function loadPreferences (prefsPath) {
if (!prefsPath || !fs.existsSync(prefsPath)) return {}
try {

View File

@@ -3,7 +3,7 @@ import process from 'node:process'
import path from 'node:path'
import readline from 'node:readline/promises'
import { parseArgs, VALID_THEMES } from './cli.js'
import { loadPreferences, readCustomCss } from './config.js'
import { loadConfigFile, loadPreferences, readCustomCss } from './config.js'
import logger from './logger.js'
import {
checkExtension,
@@ -43,12 +43,18 @@ async function main () {
await checkExtension()
const config = await loadConfigFile(opts.config)
const prefsPath = opts.prefs || config.prefs || null
const cssPath = opts.css || config.css || null
const outputPath = opts.output || config.output || null
let preferences = {}
if (opts.prefs) {
preferences = loadPreferences(path.resolve(opts.prefs))
if (prefsPath) {
preferences = loadPreferences(path.resolve(prefsPath))
}
const theme = opts.theme || preferences.mode || 'light'
const theme = opts.theme || config.theme || preferences.mode || 'light'
if (!VALID_THEMES.includes(theme)) {
logger.error(
`Invalid theme "${theme}". Valid themes: ${VALID_THEMES.join(', ')}`
@@ -59,11 +65,11 @@ async function main () {
logger.info(`Theme: ${theme}`)
let customCss = null
if (opts.css) {
customCss = readCustomCss(path.resolve(opts.css))
if (cssPath) {
customCss = readCustomCss(path.resolve(cssPath))
if (customCss !== null) {
preferences['user-css'] = customCss
logger.info(`Custom CSS loaded: "${path.resolve(opts.css)}"`)
logger.info(`Custom CSS loaded: "${path.resolve(cssPath)}"`)
}
}
@@ -124,8 +130,8 @@ async function main () {
await new Promise((resolve) => setTimeout(resolve, 1000))
const title = await getArticleTitle(readerPage)
const outputFile = opts.output
? resolveOutputPath(opts.output)
const outputFile = outputPath
? resolveOutputPath(outputPath)
: getOutputFilename(title)
let contentHtml = await extractRenderedContent(readerPage)