generated from polymech/site-template
config
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import { substitute } from "@polymech/commons/variables";
|
||||
import { appConfigSchema } from "./config.schema.js";
|
||||
import type { AppConfig } from "./config.schema.js";
|
||||
|
||||
import { I18N_SOURCE_LANGUAGE } from "./constants.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;
|
||||
}
|
||||
Vendored
+94
@@ -10,6 +10,52 @@ export interface AppConfig {
|
||||
metadata: Metadata;
|
||||
shopify: Shopify;
|
||||
pages: Pages;
|
||||
core: Core;
|
||||
i18n: I18N;
|
||||
products: Products;
|
||||
retail: Retail;
|
||||
rss: Rss;
|
||||
osrl: Osrl;
|
||||
features: { [key: string]: boolean };
|
||||
defaults: Defaults;
|
||||
cad: Cad;
|
||||
assets: Assets;
|
||||
optimization: Optimization;
|
||||
}
|
||||
|
||||
export interface Assets {
|
||||
cad_url: string;
|
||||
url: string;
|
||||
item_url_r: string;
|
||||
item_url: string;
|
||||
}
|
||||
|
||||
export interface Cad {
|
||||
cache: boolean;
|
||||
export_configurations: boolean;
|
||||
export_sub_components: boolean;
|
||||
renderer: string;
|
||||
renderer_view: string;
|
||||
renderer_quality: number;
|
||||
extensions: string[];
|
||||
model_ext: string;
|
||||
default_configuration: string;
|
||||
main_match: string;
|
||||
cam_main_match: string;
|
||||
}
|
||||
|
||||
export interface Core {
|
||||
logging_namespace: string;
|
||||
translate_content: boolean;
|
||||
languages: string[];
|
||||
languages_prod: string[];
|
||||
rtl_languages: string[];
|
||||
}
|
||||
|
||||
export interface Defaults {
|
||||
image_url: string;
|
||||
license: string;
|
||||
contact: string;
|
||||
}
|
||||
|
||||
export interface Ecommerce {
|
||||
@@ -23,6 +69,12 @@ export interface FooterLeft {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface I18N {
|
||||
store: string;
|
||||
cache: boolean;
|
||||
asset_path: string;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
country: string;
|
||||
city: string;
|
||||
@@ -44,6 +96,31 @@ export interface NavigationButton {
|
||||
link: string;
|
||||
}
|
||||
|
||||
export interface Optimization {
|
||||
image_settings: ImageSettings;
|
||||
}
|
||||
|
||||
export interface ImageSettings {
|
||||
gallery: Gallery;
|
||||
lightbox: Gallery;
|
||||
}
|
||||
|
||||
export interface Gallery {
|
||||
show_title: boolean;
|
||||
show_description: boolean;
|
||||
sizes_thumb: string;
|
||||
sizes_large: string;
|
||||
sizes_regular: string;
|
||||
}
|
||||
|
||||
export interface Osrl {
|
||||
env: string;
|
||||
env_dev: string;
|
||||
module_name: string;
|
||||
lang_flavor: string;
|
||||
product_profile: string;
|
||||
}
|
||||
|
||||
export interface Pages {
|
||||
home: Home;
|
||||
}
|
||||
@@ -62,6 +139,23 @@ export interface Params {
|
||||
copyright: string;
|
||||
}
|
||||
|
||||
export interface Products {
|
||||
root: string;
|
||||
howto_migration: string;
|
||||
glob: string;
|
||||
enabled: string;
|
||||
}
|
||||
|
||||
export interface Retail {
|
||||
library_branch: string;
|
||||
projects_branch: string;
|
||||
}
|
||||
|
||||
export interface Rss {
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
search: boolean;
|
||||
account: boolean;
|
||||
|
||||
@@ -46,6 +46,80 @@ export const metadataSchema = z.object({
|
||||
keywords: z.string()
|
||||
});
|
||||
|
||||
export const coreSchema = z.object({
|
||||
logging_namespace: z.string(),
|
||||
translate_content: z.boolean(),
|
||||
languages: z.array(z.string()),
|
||||
languages_prod: z.array(z.string()),
|
||||
rtl_languages: z.array(z.string())
|
||||
});
|
||||
|
||||
export const i18NSchema = z.object({
|
||||
store: z.string(),
|
||||
cache: z.boolean(),
|
||||
asset_path: z.string()
|
||||
});
|
||||
|
||||
export const productsSchema = z.object({
|
||||
root: z.string(),
|
||||
howto_migration: z.string(),
|
||||
glob: z.string(),
|
||||
enabled: z.string()
|
||||
});
|
||||
|
||||
export const retailSchema = z.object({
|
||||
library_branch: z.string(),
|
||||
projects_branch: z.string()
|
||||
});
|
||||
|
||||
export const rssSchema = z.object({
|
||||
title: z.string(),
|
||||
description: z.string()
|
||||
});
|
||||
|
||||
export const osrlSchema = z.object({
|
||||
env: z.string(),
|
||||
env_dev: z.string(),
|
||||
module_name: z.string(),
|
||||
lang_flavor: z.string(),
|
||||
product_profile: z.string()
|
||||
});
|
||||
|
||||
export const defaultsSchema = z.object({
|
||||
image_url: z.string(),
|
||||
license: z.string(),
|
||||
contact: z.string()
|
||||
});
|
||||
|
||||
export const cadSchema = z.object({
|
||||
cache: z.boolean(),
|
||||
export_configurations: z.boolean(),
|
||||
export_sub_components: z.boolean(),
|
||||
renderer: z.string(),
|
||||
renderer_view: z.string(),
|
||||
renderer_quality: z.number(),
|
||||
extensions: z.array(z.string()),
|
||||
model_ext: z.string(),
|
||||
default_configuration: z.string(),
|
||||
main_match: z.string(),
|
||||
cam_main_match: z.string()
|
||||
});
|
||||
|
||||
export const assetsSchema = z.object({
|
||||
cad_url: z.string(),
|
||||
url: z.string(),
|
||||
item_url_r: z.string(),
|
||||
item_url: z.string()
|
||||
});
|
||||
|
||||
export const gallerySchema = z.object({
|
||||
show_title: z.boolean(),
|
||||
show_description: z.boolean(),
|
||||
sizes_thumb: z.string(),
|
||||
sizes_large: z.string(),
|
||||
sizes_regular: z.string()
|
||||
});
|
||||
|
||||
export const blogSchema = z.object({
|
||||
store: z.string()
|
||||
});
|
||||
@@ -82,6 +156,11 @@ export const shopifySchema = z.object({
|
||||
collections: collectionsSchema
|
||||
});
|
||||
|
||||
export const imageSettingsSchema = z.object({
|
||||
gallery: gallerySchema,
|
||||
lightbox: gallerySchema
|
||||
});
|
||||
|
||||
export const homeSchema = z.object({
|
||||
hero: z.string(),
|
||||
_blog: blogSchema
|
||||
@@ -91,6 +170,10 @@ export const pagesSchema = z.object({
|
||||
home: homeSchema
|
||||
});
|
||||
|
||||
export const optimizationSchema = z.object({
|
||||
image_settings: imageSettingsSchema
|
||||
});
|
||||
|
||||
export const appConfigSchema = z.object({
|
||||
site: siteSchema,
|
||||
footer_left: z.array(footerLeftSchema),
|
||||
@@ -102,7 +185,18 @@ export const appConfigSchema = z.object({
|
||||
ecommerce: ecommerceSchema,
|
||||
metadata: metadataSchema,
|
||||
shopify: shopifySchema,
|
||||
pages: pagesSchema
|
||||
pages: pagesSchema,
|
||||
core: coreSchema,
|
||||
i18n: i18NSchema,
|
||||
products: productsSchema,
|
||||
retail: retailSchema,
|
||||
rss: rssSchema,
|
||||
osrl: osrlSchema,
|
||||
features: z.record(z.string(), z.boolean()),
|
||||
defaults: defaultsSchema,
|
||||
cad: cadSchema,
|
||||
assets: assetsSchema,
|
||||
optimization: optimizationSchema
|
||||
});
|
||||
|
||||
export type AppConfig = z.infer<typeof appConfigSchema>;
|
||||
|
||||
+58
-91
@@ -3,29 +3,35 @@ import { IMAGE_PRESET, E_BROADBAND_SPEED } from "./network.js"
|
||||
import { resolve, template } from '@polymech/commons'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sanitizeUri } from 'micromark-util-sanitize-uri'
|
||||
import { loadConfig } from './config-loader.js'
|
||||
import { I18N_SOURCE_LANGUAGE } from "./constants.js"
|
||||
|
||||
export { I18N_SOURCE_LANGUAGE }
|
||||
|
||||
// Load config
|
||||
const config = loadConfig(I18N_SOURCE_LANGUAGE)
|
||||
|
||||
export const OSR_ROOT = () => path.resolve(resolve("${OSR_ROOT}"))
|
||||
export const FILE_SERVER_DEV = 'localhost:5000'
|
||||
|
||||
export const LOGGING_NAMESPACE = 'polymech-site'
|
||||
export const TRANSLATE_CONTENT = true
|
||||
export const LANGUAGES = ['en', 'ar', 'de', 'ja', 'es', 'zh', 'fr']
|
||||
//export const LANGUAGES_PROD = ['en', 'es', 'ar', 'de', 'ja', 'zh', 'fr', 'nl', 'it', 'pt']
|
||||
export const LANGUAGES_PROD = ['en', 'es', 'fr']
|
||||
export const isRTL = (lang) => lang === 'ar'
|
||||
export const LOGGING_NAMESPACE = config.core.logging_namespace
|
||||
export const TRANSLATE_CONTENT = config.core.translate_content
|
||||
export const LANGUAGES = config.core.languages
|
||||
export const LANGUAGES_PROD = config.core.languages_prod
|
||||
export const isRTL = (lang) => config.core.rtl_languages.includes(lang)
|
||||
|
||||
// i18n constants
|
||||
export const I18N_STORE = (root, lang) => `${root}/i18n-store/store-${lang}.json`
|
||||
export const I18N_SOURCE_LANGUAGE = 'en'
|
||||
export const I18N_CACHE = true
|
||||
export const I18N_ASSET_PATH = "${SRC_DIR}/${SRC_NAME}-${DST_LANG}${SRC_EXT}"
|
||||
export const I18N_STORE = (root, lang) => template(config.i18n.store, { root, lang, LANG: lang, OSR_ROOT: root })
|
||||
export const I18N_CACHE = config.i18n.cache
|
||||
export const I18N_ASSET_PATH = config.i18n.asset_path
|
||||
|
||||
// Products
|
||||
export const HOWTO_MIGRATION = () => path.resolve(resolve("./data/last.json"))
|
||||
export const HOWTO_MIGRATION = () => path.resolve(resolve(config.products.howto_migration))
|
||||
|
||||
// Products
|
||||
export const PRODUCT_ROOT = () => path.resolve(resolve("${OSR_ROOT}/products"))
|
||||
export const PRODUCT_ROOT = () => path.resolve(resolve(config.products.root))
|
||||
export const PRODUCT_BRANCHES = read(path.join(PRODUCT_ROOT(), 'config/machines.json'), 'json')
|
||||
export const PRODUCT_GLOB = '**/config.json'
|
||||
export const PRODUCT_GLOB = config.products.glob
|
||||
|
||||
// Product compiler
|
||||
export const PRODUCT_CONFIG = (product) =>
|
||||
@@ -34,72 +40,52 @@ export const PRODUCT_CONFIG = (product) =>
|
||||
product
|
||||
}))
|
||||
export const PRODUCT_DIR = (product) => path.resolve(resolve(`${PRODUCT_ROOT()}/${product}`))
|
||||
export const PRODUCT_HUGO_TEMPLATE = './osr/hugo/root.html'
|
||||
export const PRODUCTS_TARGET_SRC = './src/content/en/retail'
|
||||
export const PRODUCTS_TARGET = (lang) => `./content/${lang}/products`
|
||||
|
||||
// OSRL - Language
|
||||
export const IS_DEV = true
|
||||
export const OSRL_ENV = 'astro-release'
|
||||
export const OSRL_ENV_DEV = 'astro-debug'
|
||||
export const OSRL_ENV = config.osrl.env
|
||||
export const OSRL_ENV_DEV = config.osrl.env_dev
|
||||
export const OSRL_ENVIRONMENT = IS_DEV ? OSRL_ENV_DEV : OSRL_ENV
|
||||
export const OSRL_MODULE_NAME = 'polymech.io'
|
||||
export const OSRL_PRODUCT_PROFILE = './src/app/profile.json'
|
||||
export const OSRL_LANG_FLAVOR = 'osr'
|
||||
export const OSRL_MODULE_NAME = config.osrl.module_name
|
||||
export const OSRL_PRODUCT_PROFILE = config.osrl.product_profile
|
||||
export const OSRL_LANG_FLAVOR = config.osrl.lang_flavor
|
||||
|
||||
// Products
|
||||
export const ENABLED_PRODUCTS = "${OSR_ROOT}/products/config/machines.json"
|
||||
export const ENABLED_PRODUCTS = resolve(config.products.enabled)
|
||||
export const PRODUCT_SPECS = (rel) => `${PRODUCT_ROOT()}/${rel}/specs.xlsx`
|
||||
|
||||
// Tasks
|
||||
export const TASK_CONFIG_LOG_DIRECTORY = './config/'
|
||||
|
||||
// Task: compile:content
|
||||
export const TASK_COMPILE_CONTENT = true
|
||||
export const TASK_COMPILE_CONTENT_CACHE = false
|
||||
|
||||
// Task - Logging
|
||||
export const TASK_LOG_DIRECTORY = './logs/'
|
||||
|
||||
// Task - Retail Config
|
||||
export const REGISTER_PRODUCT_TASKS = true
|
||||
export const LIBARY_BRANCH = 'site-prod'
|
||||
export const PROJECTS_BRANCH = 'projects'
|
||||
export const LIBARY_BRANCH = config.retail.library_branch
|
||||
export const PROJECTS_BRANCH = config.retail.projects_branch
|
||||
export const RETAIL_COMPILE_CACHE = false
|
||||
export const RETAIL_MEDIA_CACHE = true
|
||||
export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = 'info'
|
||||
|
||||
export const ConvertProductMedia = true
|
||||
export const TranslateProductAssets = false
|
||||
export const PopulateProductDefaults = true
|
||||
|
||||
// CAD
|
||||
export const CAD_MAIN_MATCH = (product) => `${product}/cad*/*Global*.+(SLDASM)`
|
||||
export const CAD_CAM_MAIN_MATCH = (product) => `${product}/cad*/*-CNC*.+(SLDASM)`
|
||||
export const CAD_MAIN_MATCH = (product) => template(config.cad.main_match, { product })
|
||||
export const CAD_CAM_MAIN_MATCH = (product) => template(config.cad.cam_main_match, { product })
|
||||
|
||||
export const CAD_CACHE = true
|
||||
export const CAD_EXPORT_CONFIGURATIONS = true
|
||||
export const CAD_EXPORT_SUB_COMPONENTS = true
|
||||
export const CAD_MODEL_FILE_PATH = (SOURCE, CONFIGURATION = '') =>
|
||||
SOURCE.replace('.json', `${CONFIGURATION ? '-' + CONFIGURATION : ''}.tree.json`)
|
||||
export const CAD_DEFAULT_CONFIGURATION = 'Default'
|
||||
export const CAD_RENDERER = 'solidworks'
|
||||
export const CAD_RENDERER_VIEW = 'Render'
|
||||
export const CAD_RENDERER_QUALITY = 1
|
||||
export const CAD_EXTENSIONS = ['.STEP', '.html']
|
||||
export const CAD_MODEL_EXT = '.tree.json'
|
||||
SOURCE.replace('.json', `${CONFIGURATION ? '-' + CONFIGURATION : ''}${config.cad.model_ext}`)
|
||||
|
||||
|
||||
export const CAD_URL = (file: string, variables: Record<string, string>) =>
|
||||
sanitizeUri(template("${OSR_MACHINES_ASSETS_URL}/${file}", { file, ...variables }))
|
||||
sanitizeUri(template(config.assets.cad_url, { file, ...variables }))
|
||||
|
||||
export const ASSET_URL = (file: string, variables: Record<string, string>) =>
|
||||
sanitizeUri(template("${OSR_MACHINES_ASSETS_URL}/products/${product_rel_min}/${file}", { file, ...variables }))
|
||||
sanitizeUri(template(config.assets.url, { file, ...variables }))
|
||||
|
||||
export const ITEM_ASSET_URL_R = (variables: Record<string, string>) =>
|
||||
template("${OSR_MACHINES_ASSETS_URL}/${ITEM_REL}/${assetPath}/${filePath}", variables)
|
||||
template(config.assets.item_url_r, variables)
|
||||
|
||||
export const ITEM_ASSET_URL = (variables: Record<string, string>) =>
|
||||
template("http://${FILE_SERVER_DEV}/${ITEM_REL}/${assetPath}/${filePath}", variables)
|
||||
template(config.assets.item_url, variables)
|
||||
|
||||
//back compat - osr-cad
|
||||
export const parseBoolean = (value: string): boolean => {
|
||||
@@ -108,41 +94,38 @@ export const parseBoolean = (value: string): boolean => {
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Rendering
|
||||
export const SHOW_DESCRIPTION = false
|
||||
export const SHOW_LICENSE = true
|
||||
export const SHOW_RENDERINGS = true
|
||||
export const SHOW_DESCRIPTION = config.features.show_description
|
||||
export const SHOW_LICENSE = config.features.show_license
|
||||
export const SHOW_RENDERINGS = config.features.show_renderings
|
||||
|
||||
export const SHOW_TABS = false
|
||||
export const SHOW_GALLERY = true
|
||||
export const SHOW_FILES = true
|
||||
export const SHOW_SPECS = true
|
||||
export const SHOW_CHECKOUT = true
|
||||
export const SHOW_CONTACT = true
|
||||
export const SHOW_3D_PREVIEW = true
|
||||
export const SHOW_RESOURCES = true
|
||||
export const SHOW_DEBUG = false
|
||||
export const SHOW_SAMPLES = true
|
||||
export const SHOW_README = false
|
||||
export const SHOW_RELATED = true
|
||||
export const SHOW_SHOWCASE = true
|
||||
export const SHOW_SCREENSHOTS = true
|
||||
export const SHOW_TABS = config.features.show_tabs
|
||||
export const SHOW_GALLERY = config.features.show_gallery
|
||||
export const SHOW_FILES = config.features.show_files
|
||||
export const SHOW_SPECS = config.features.show_specs
|
||||
export const SHOW_CHECKOUT = config.features.show_checkout
|
||||
export const SHOW_CONTACT = config.features.show_contact
|
||||
export const SHOW_3D_PREVIEW = config.features.show_3d_preview
|
||||
export const SHOW_RESOURCES = config.features.show_resources
|
||||
export const SHOW_DEBUG = config.features.show_debug
|
||||
export const SHOW_SAMPLES = config.features.show_samples
|
||||
export const SHOW_README = config.features.show_readme
|
||||
export const SHOW_RELATED = config.features.show_related
|
||||
export const SHOW_SHOWCASE = config.features.show_showcase
|
||||
export const SHOW_SCREENSHOTS = config.features.show_screenshots
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Plugins
|
||||
//
|
||||
|
||||
// RSS
|
||||
export const RSS_CONFIG =
|
||||
{
|
||||
title: 'Polymech RSS Feed',
|
||||
description: '',
|
||||
}
|
||||
export const RSS_CONFIG = config.rss
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Defaults
|
||||
|
||||
export const DEFAULT_IMAGE_URL = 'https://picsum.photos/640/640'
|
||||
export const DEFAULT_IMAGE_URL = config.defaults.image_url
|
||||
|
||||
export const default_image = () => {
|
||||
return {
|
||||
@@ -152,28 +135,12 @@ export const default_image = () => {
|
||||
}
|
||||
}
|
||||
|
||||
export const DEFAULT_LICENSE = `CERN Open Source Hardware License`
|
||||
export const DEFAULT_CONTACT = `sales@plastic-hub.com`
|
||||
export const DEFAULT_LICENSE = config.defaults.license
|
||||
export const DEFAULT_CONTACT = config.defaults.contact
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Optimization
|
||||
|
||||
export const O_IMAGE = IMAGE_PRESET[E_BROADBAND_SPEED.MEDIUM]
|
||||
export const IMAGE_SETTINGS =
|
||||
{
|
||||
GALLERY: {
|
||||
SHOW_TITLE: true,
|
||||
SHOW_DESCRIPTION: false,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
},
|
||||
LIGHTBOX: {
|
||||
SHOW_TITLE: true,
|
||||
SHOW_DESCRIPTION: true,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
}
|
||||
}
|
||||
export const IMAGE_SETTINGS = config.optimization.image_settings
|
||||
@@ -0,0 +1 @@
|
||||
export const I18N_SOURCE_LANGUAGE = 'en';
|
||||
Reference in New Issue
Block a user