diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0c8ded1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "polymech-astro", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/packages/polymech/src/app/_navigation.bak b/packages/polymech/src/app/_navigation.bak new file mode 100644 index 0000000..dc8fe1b --- /dev/null +++ b/packages/polymech/src/app/_navigation.bak @@ -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" + } + }); +} \ No newline at end of file diff --git a/packages/polymech/src/app/config-loader.ts b/packages/polymech/src/app/config-loader.ts new file mode 100644 index 0000000..60c74f4 --- /dev/null +++ b/packages/polymech/src/app/config-loader.ts @@ -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; +}