Only use selectable languages

This commit is contained in:
DrMint 2024-06-30 13:33:54 +02:00
parent 2a505ebd7a
commit efb0f03be8
12 changed files with 39 additions and 27 deletions

View File

@ -8,7 +8,11 @@ PAYLOAD_USER=myemail@domain.com
PAYLOAD_PASSWORD=somepassword123 PAYLOAD_PASSWORD=somepassword123
WEB_HOOK_TOKEN=webhookd5e6ea45ef4e66eaa151612bdcb599df WEB_HOOK_TOKEN=webhookd5e6ea45ef4e66eaa151612bdcb599df
ENABLE_PRECACHING=true ## CACHING
DATA_CACHING=false
DATA_PRECACHING=false
PAGE_CACHING=false
PAGE_PRECACHING=false
## OPEN EXCHANGE RATE ## OPEN EXCHANGE RATE
OER_APP_ID=oerappid5e6ea45ef4e66eaa151612bdcb599df OER_APP_ID=oerappid5e6ea45ef4e66eaa151612bdcb599df

View File

@ -12,7 +12,8 @@ export class ContextCache {
constructor(private readonly payload: PayloadSDK) {} constructor(private readonly payload: PayloadSDK) {}
locales: Language[] = []; languages: Language[] = [];
locales: string[] = [];
currencies: string[] = []; currencies: string[] = [];
wordings: EndpointWording[] = []; wordings: EndpointWording[] = [];
config: EndpointWebsiteConfig = { config: EndpointWebsiteConfig = {
@ -45,7 +46,8 @@ export class ContextCache {
} }
async refreshLocales() { async refreshLocales() {
this.locales = (await this.payload.getLanguages()).data; this.languages = (await this.payload.getLanguages()).data;
this.locales = this.languages.filter(({ selectable }) => selectable).map(({ id }) => id);
this.logger.log("Locales refreshed"); this.logger.log("Locales refreshed");
} }

View File

@ -24,7 +24,7 @@ export class DataCache {
async init() { async init() {
if (this.initialized) return; if (this.initialized) return;
if (import.meta.env.ENABLE_PRECACHING === "true") { if (import.meta.env.DATA_PRECACHING === "true") {
await this.precache(); await this.precache();
} }
@ -67,6 +67,7 @@ export class DataCache {
} }
get(url: string) { get(url: string) {
if (import.meta.env.DATA_CACHING !== "true") return;
const cachedResponse = this.responseCache.get(url); const cachedResponse = this.responseCache.get(url);
if (cachedResponse) { if (cachedResponse) {
this.logger.log("Retrieved cached response for", url); this.logger.log("Retrieved cached response for", url);
@ -75,6 +76,7 @@ export class DataCache {
} }
set(url: string, response: any) { set(url: string, response: any) {
if (import.meta.env.DATA_CACHING !== "true") return;
const stringData = JSON.stringify(response); const stringData = JSON.stringify(response);
const regex = /[a-f0-9]{24}/g; const regex = /[a-f0-9]{24}/g;
const ids = [...stringData.matchAll(regex)].map((match) => match[0]); const ids = [...stringData.matchAll(regex)].map((match) => match[0]);
@ -97,6 +99,7 @@ export class DataCache {
} }
async invalidate(ids: string[], urls: string[]) { async invalidate(ids: string[], urls: string[]) {
if (import.meta.env.DATA_CACHING !== "true") return;
const urlsToInvalidate = new Set<string>(urls); const urlsToInvalidate = new Set<string>(urls);
ids.forEach((id) => { ids.forEach((id) => {

View File

@ -26,16 +26,17 @@ export class PageCache {
async init() { async init() {
if (this.initialized) return; if (this.initialized) return;
if (import.meta.env.ENABLE_PRECACHING === "true") { if (import.meta.env.PAGE_PRECACHING === "true") {
await this.precacheAll(); await this.precache();
} }
this.initialized = true; this.initialized = true;
} }
private async precacheAll() { private async precache() {
if (import.meta.env.DATA_CACHING !== "true") return;
const { data: languages } = await this.uncachedPayload.getLanguages(); const { data: languages } = await this.uncachedPayload.getLanguages();
const locales = languages.map(({ id }) => id); const locales = languages.filter(({ selectable }) => selectable).map(({ id }) => id);
// Get all pages urls from CMS // Get all pages urls from CMS
const allPagesUrls = [ const allPagesUrls = [
@ -99,6 +100,7 @@ export class PageCache {
} }
get(url: string): Response | undefined { get(url: string): Response | undefined {
if (import.meta.env.PAGE_CACHING !== "true") return;
const cachedPage = this.responseCache.get(url); const cachedPage = this.responseCache.get(url);
if (cachedPage) { if (cachedPage) {
this.logger.log("Retrieved cached page for", url); this.logger.log("Retrieved cached page for", url);
@ -108,6 +110,7 @@ export class PageCache {
} }
set(url: string, response: Response, sdkCalls: string[]) { set(url: string, response: Response, sdkCalls: string[]) {
if (import.meta.env.PAGE_CACHING !== "true") return;
sdkCalls.forEach((id) => { sdkCalls.forEach((id) => {
const current = this.invalidationMap.get(id); const current = this.invalidationMap.get(id);
if (current) { if (current) {
@ -125,6 +128,7 @@ export class PageCache {
} }
async invalidate(sdkUrls: string[]) { async invalidate(sdkUrls: string[]) {
if (import.meta.env.PAGE_CACHING !== "true") return;
const pagesToInvalidate = new Set<string>(); const pagesToInvalidate = new Set<string>();
sdkUrls.forEach((url) => { sdkUrls.forEach((url) => {

View File

@ -21,11 +21,11 @@ const { t } = await getI18n(currentLocale);
<Tooltip trigger="click" {...otherProps.class ? otherProps : {}}> <Tooltip trigger="click" {...otherProps.class ? otherProps : {}}>
<div id="content" slot="tooltip-content"> <div id="content" slot="tooltip-content">
{ {
contextCache.locales.map(({ id }) => ( contextCache.locales.map((locale) => (
<a <a
class:list={{ current: currentLocale === id, "pressable-link": true }} class:list={{ current: currentLocale === locale, "pressable-link": true }}
href={`?action-lang=${id}`}> href={`?action-lang=${locale}`}>
{formatLocale(id)} {formatLocale(locale)}
</a> </a>
)) ))
} }

View File

@ -12,7 +12,7 @@ export const addCommonHeadersMiddleware = defineMiddleware(async ({ url }, next)
// TODO: Remove when in production // TODO: Remove when in production
response.headers.set("X-Robots-Tag", "none"); response.headers.set("X-Robots-Tag", "none");
response.headers.set("Vary", "Cookie"); response.headers.set("Vary", "Cookie");
response.headers.set("Cache-Control", "max-age=3600, stale-while-revalidate=3600"); response.headers.set("Cache-Control", "max-age=86400, stale-while-revalidate=86400");
return response; return response;
}); });

View File

@ -17,8 +17,8 @@ export const redirect = (redirectURL: string, headers: Record<string, string> =
export const getCurrentLocale = (pathname: string): string | undefined => { export const getCurrentLocale = (pathname: string): string | undefined => {
for (const locale of contextCache.locales) { for (const locale of contextCache.locales) {
if (pathname.split("/")[1] === locale.id) { if (pathname.split("/")[1] === locale) {
return locale.id; return locale;
} }
} }
return undefined; return undefined;
@ -28,7 +28,7 @@ export const getBestAcceptedLanguage = (request: Request): string | undefined =>
const header = request.headers.get("Accept-Language"); const header = request.headers.get("Accept-Language");
if (!header || header === "*") return; if (!header || header === "*") return;
acceptLanguage.languages(contextCache.locales.map(({ id }) => id)); acceptLanguage.languages(contextCache.locales);
return acceptLanguage.get(request.headers.get("Accept-Language")) ?? undefined; return acceptLanguage.get(request.headers.get("Accept-Language")) ?? undefined;
}; };
@ -62,9 +62,7 @@ export const isValidCurrency = (currency: string | null | undefined): currency i
currency !== null && currency != undefined && contextCache.currencies.includes(currency); currency !== null && currency != undefined && contextCache.currencies.includes(currency);
export const isValidLocale = (locale: string | null | undefined): locale is string => export const isValidLocale = (locale: string | null | undefined): locale is string =>
locale !== null && locale !== null && locale != undefined && contextCache.locales.includes(locale);
locale != undefined &&
contextCache.locales.map(({ id }) => id).includes(locale);
export const isValidTheme = ( export const isValidTheme = (
theme: string | null | undefined theme: string | null | undefined

View File

@ -1,5 +1,5 @@
import type { APIRoute } from "astro"; import type { APIRoute } from "astro";
import { dataCache, pageCache } from "src/utils/payload"; import { dataCache, pageCache } from "src/utils/payload";
export const GET: APIRoute = async () => { export const GET: APIRoute = async () => {
await dataCache.init(); await dataCache.init();

View File

@ -21,11 +21,11 @@ const { t } = await getI18n(currentLocale);
<h2>{t("settings.language.title")}</h2> <h2>{t("settings.language.title")}</h2>
<p>{t("settings.language.description")}</p><br /> <p>{t("settings.language.description")}</p><br />
{ {
contextCache.locales.map(({ id }) => ( contextCache.locales.map((locale) => (
<a <a
class:list={{ current: currentLocale === id, "pressable-link": true }} class:list={{ current: currentLocale === locale, "pressable-link": true }}
href={`?action-lang=${id}`}> href={`?action-lang=${locale}`}>
{formatLocale(id)} {formatLocale(locale)}
</a> </a>
)) ))
} }

View File

@ -2,8 +2,8 @@ import { contextCache } from "src/utils/payload";
const getUnlocalizedPathname = (pathname: string): string => { const getUnlocalizedPathname = (pathname: string): string => {
for (const locale of contextCache.locales) { for (const locale of contextCache.locales) {
if (pathname.startsWith(`/${locale.id}`)) { if (pathname.startsWith(`/${locale}`)) {
return pathname.substring(`/${locale.id}`.length) || "/"; return pathname.substring(`/${locale}`.length) || "/";
} }
} }
return pathname; return pathname;

View File

@ -227,6 +227,7 @@ export interface Image {
export interface Language { export interface Language {
id: string; id: string;
name: string; name: string;
selectable: boolean;
} }
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema

View File

@ -9,7 +9,7 @@ import {
import { contextCache } from "src/utils/payload"; import { contextCache } from "src/utils/payload";
export const formatLocale = (code: string): string => export const formatLocale = (code: string): string =>
contextCache.locales.find(({ id }) => id === code)?.name ?? code; contextCache.languages.find(({ id }) => id === code)?.name ?? code;
export const formatInlineTitle = ({ export const formatInlineTitle = ({
pretitle, pretitle,