app config loader

This commit is contained in:
babayaga 2025-12-25 13:30:59 +01:00
parent 3263036e7d
commit 4d1b735c8e
3 changed files with 95 additions and 0 deletions

6
package-lock.json generated Normal file
View File

@ -0,0 +1,6 @@
{
"name": "polymech-astro",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@ -0,0 +1,44 @@
import { translate } from '@/base/i18n.js'
import { I18N_SOURCE_LANGUAGE } from './config.js'
import config from "./config.json" with { "type": "json" }
import pMap from 'p-map'
export const items = async (opts: { locale: string }) => {
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, opts.locale)
return [
{
"href": `/${opts.locale}`,
"title": _T("Home"),
"ariaLabel": "Home",
"class": "hover:text-orange-600"
},
{
"href": `/${opts.locale}/resources/home`,
"title": _T("Resources"),
"ariaLabel": "Resources",
"class": "hover:text-orange-600"
}
]
}
export const footer_left = async (locale: string) => {
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, locale)
return await pMap(config.footer_left, async (item: any) => {
return {
"href": `${item.href}`,
"title": await _T(item.text),
"ariaLabel": item.text,
"class": "hover:text-orange-600"
}
});
}
export const footer_right = async (locale: string) => {
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, locale)
return await pMap(config.footer_right, async (item: any) => {
return {
"href": `/${item.href}`,
"title": await _T(item.text),
"ariaLabel": item.text,
"class": "hover:text-orange-600"
}
});
}

View File

@ -0,0 +1,45 @@
import * as fs from "fs";
import * as path from "path";
import { substitute } from "@polymech/commons/variables";
import { appConfigSchema } from "@/app/config.schema.js";
import type { AppConfig } from "@/app/config.schema.js";
import { I18N_SOURCE_LANGUAGE } from "@/app/config.js"
const DEFAULT_CONFIG_PATH = path.resolve("./app-config.json");
export function loadConfig(
locale: string = I18N_SOURCE_LANGUAGE,
configPath: string = DEFAULT_CONFIG_PATH
): AppConfig {
let rawContent: string;
try {
rawContent = fs.readFileSync(configPath, 'utf-8');
} catch (error) {
throw new Error(`Failed to read config file at ${configPath}: ${error}`);
}
const variables = {
LANG: locale,
...process.env
};
const substitutedContent = substitute(false, rawContent, variables);
let parsedConfig: unknown;
try {
parsedConfig = JSON.parse(substitutedContent);
} catch (error) {
throw new Error(`Failed to parse config JSON after substitution: ${error}`);
}
const result = appConfigSchema.safeParse(parsedConfig);
if (!result.success) {
throw new Error(`Config validation failed: ${result.error.message}`);
}
return result.data;
}