Files
sass-mohfarawati/lib/site-settings.ts
T
2026-03-07 18:48:01 +01:00

153 lines
4.6 KiB
TypeScript

import type { AppLocale } from "./locale";
export const SITE_NAME_KEY = "siteName";
export const SITE_SETTINGS_KEY = "site_settings";
export const SITE_SETTINGS_ENTITY_TYPE = "site-settings";
export const SITE_SETTINGS_ENTITY_ID = "global";
export const SITE_SETTINGS_FAVICON_FIELD_KEY = "favicon";
export const SITE_SETTINGS_DEFAULT_OG_IMAGE_FIELD_KEY = "defaultOgImage";
export const PAGE_TITLE_TOKEN = "{pageTitle}";
export const SITE_NAME_TOKEN = "{siteName}";
export const DEFAULT_SITE_NAME = "moh-sass";
export const DEFAULT_SITE_DESCRIPTION = "Multilingual Next.js base project";
type SiteLocaleSettings = {
siteName: string;
titleTemplate: string;
siteDescription: string;
subhead: string;
};
export type SiteSettings = {
locales: Record<AppLocale, SiteLocaleSettings>;
};
export type SiteSettingsMediaBinding = {
assetId: string;
url: string;
};
export type SiteSettingsMediaBindings = {
favicon: SiteSettingsMediaBinding | null;
defaultOgImage: SiteSettingsMediaBinding | null;
};
function normalizeSiteLocaleSettings(
input: unknown,
fallbackName: string,
fallbackDescription: string,
): SiteLocaleSettings {
const value = input && typeof input === "object" ? (input as Record<string, unknown>) : {};
return {
siteName:
typeof value.siteName === "string" && value.siteName.trim()
? value.siteName.trim()
: fallbackName,
titleTemplate:
typeof value.titleTemplate === "string" &&
value.titleTemplate.trim() &&
value.titleTemplate.includes(PAGE_TITLE_TOKEN)
? value.titleTemplate.trim()
: `${PAGE_TITLE_TOKEN} | ${SITE_NAME_TOKEN}`,
siteDescription:
typeof value.siteDescription === "string"
? value.siteDescription.trim()
: fallbackDescription,
subhead: typeof value.subhead === "string" ? value.subhead.trim() : "",
};
}
export function getDefaultSiteSettingsMediaBindings(): SiteSettingsMediaBindings {
return {
favicon: null,
defaultOgImage: null,
};
}
export function buildDefaultSiteSettings(fallbackName = DEFAULT_SITE_NAME): SiteSettings {
return {
locales: {
ar: {
siteName: fallbackName,
titleTemplate: `${PAGE_TITLE_TOKEN} | ${SITE_NAME_TOKEN}`,
siteDescription: DEFAULT_SITE_DESCRIPTION,
subhead: "",
},
en: {
siteName: fallbackName,
titleTemplate: `${PAGE_TITLE_TOKEN} | ${SITE_NAME_TOKEN}`,
siteDescription: DEFAULT_SITE_DESCRIPTION,
subhead: "",
},
de: {
siteName: fallbackName,
titleTemplate: `${PAGE_TITLE_TOKEN} | ${SITE_NAME_TOKEN}`,
siteDescription: DEFAULT_SITE_DESCRIPTION,
subhead: "",
},
},
};
}
export function parseSiteSettingsValue(
rawValue: string | null | undefined,
fallbackName = DEFAULT_SITE_NAME,
): SiteSettings {
const defaults = buildDefaultSiteSettings(fallbackName);
if (!rawValue) {
return defaults;
}
try {
const parsed = JSON.parse(rawValue) as Record<string, unknown>;
const locales = parsed.locales && typeof parsed.locales === "object"
? (parsed.locales as Record<string, unknown>)
: {};
const siteSettings: SiteSettings = {
locales: {
ar: normalizeSiteLocaleSettings(
{
titleTemplate:
typeof parsed.titleTemplate === "string" && parsed.titleTemplate.trim()
? parsed.titleTemplate.trim()
: undefined,
...(locales.ar && typeof locales.ar === "object" ? (locales.ar as Record<string, unknown>) : {}),
},
defaults.locales.ar.siteName,
defaults.locales.ar.siteDescription,
),
en: normalizeSiteLocaleSettings(
{
titleTemplate:
typeof parsed.titleTemplate === "string" && parsed.titleTemplate.trim()
? parsed.titleTemplate.trim()
: undefined,
...(locales.en && typeof locales.en === "object" ? (locales.en as Record<string, unknown>) : {}),
},
defaults.locales.en.siteName,
defaults.locales.en.siteDescription,
),
de: normalizeSiteLocaleSettings(
{
titleTemplate:
typeof parsed.titleTemplate === "string" && parsed.titleTemplate.trim()
? parsed.titleTemplate.trim()
: undefined,
...(locales.de && typeof locales.de === "object" ? (locales.de as Record<string, unknown>) : {}),
},
defaults.locales.de.siteName,
defaults.locales.de.siteDescription,
),
},
};
return siteSettings;
} catch {
return defaults;
}
}