Files
sunrise/server/threads/config.ts
T

40 lines
1.7 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { THREADS } from '../../src/constants/threads.ts';
export interface ThreadsConfig {
accessToken: string;
siteUrl: string;
stateDir: string;
imageDir: string;
imageBaseUrl: string;
}
export function loadThreadsConfig(path: string | URL = new URL('../../.env.threads.json', import.meta.url), optional = false): ThreadsConfig {
const defaults: ThreadsConfig = {
accessToken: '', siteUrl: THREADS.siteUrl, stateDir: 'data/threads',
imageDir: 'dist/threads-captures', imageBaseUrl: `${THREADS.siteUrl}/threads-captures/`,
};
let contents: string;
try { contents = readFileSync(path, 'utf8'); }
catch (error) {
if (optional && (error as NodeJS.ErrnoException).code === 'ENOENT') return defaults;
throw new Error('Cannot read .env.threads.json; copy .env.threads.sample.json and configure it.');
}
let value: unknown;
try { value = JSON.parse(contents); }
catch { throw new Error('Invalid JSON in .env.threads.json'); }
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('Invalid .env.threads.json: expected an object');
const config = { ...defaults, ...value } as ThreadsConfig;
for (const field of Object.keys(defaults) as (keyof ThreadsConfig)[]) {
if (typeof config[field] !== 'string' || (field !== 'accessToken' && !config[field].trim())) {
throw new Error(`Invalid .env.threads.json field: ${field}`);
}
}
for (const field of ['siteUrl', 'imageBaseUrl'] as const) {
try {
if (!['http:', 'https:'].includes(new URL(config[field]).protocol)) throw new Error();
} catch { throw new Error(`Invalid .env.threads.json field: ${field}`); }
}
return config;
}