fix(i18n): persist CMS translations and validate message catalogs
This commit is contained in:
1 parent
96234075f8
commit
ef94646d60
37 files changed
+1621
-463
No files matched your search
+25
-38
@@ -3,60 +3,47 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import * as JSONC from "jsonc-parser";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { z } from "zod";
|
||||
import { SUPPORTED_LOCALES } from "@/i18n/locales";
|
||||
import {
|
||||
CLIENT_TRANSLATION_FILES,
|
||||
getClientTranslationFile,
|
||||
} from "@/lib/client-translation-files";
|
||||
import {
|
||||
CmsTranslationError,
|
||||
saveCmsTranslation,
|
||||
} from "@/lib/cms-translations";
|
||||
import { patchJson5 } from "@/lib/json5-patch";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { adminAction } from "@/lib/safe-action";
|
||||
import { ActionError, actionOk } from "@/lib/safe-action-shared";
|
||||
|
||||
const saveTranslationsSchema = z.object({
|
||||
locale: z.enum([
|
||||
"en",
|
||||
"it",
|
||||
"nl",
|
||||
"de",
|
||||
"fr",
|
||||
"es",
|
||||
"pt",
|
||||
"pl",
|
||||
"sv",
|
||||
"tr",
|
||||
"ro",
|
||||
"hu",
|
||||
"cs",
|
||||
"sk",
|
||||
"da",
|
||||
"no",
|
||||
"el",
|
||||
"bg",
|
||||
"hr",
|
||||
"sr",
|
||||
"uk",
|
||||
"ru",
|
||||
]),
|
||||
data: z.record(z.string(), z.unknown()),
|
||||
locale: z.enum(SUPPORTED_LOCALES),
|
||||
revision: z.string().regex(/^[a-f0-9]{64}$/),
|
||||
changes: z
|
||||
.record(z.string().max(300), z.string().max(20000).nullable())
|
||||
.refine((value) => Object.keys(value).length <= 5000),
|
||||
});
|
||||
|
||||
export const saveTranslations = adminAction(
|
||||
{ permission: PERMS.SETTINGS_EDIT, schema: saveTranslationsSchema },
|
||||
async (ctx) => {
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"src",
|
||||
"messages",
|
||||
`${ctx.data.locale}.json`,
|
||||
);
|
||||
await fs.writeFile(
|
||||
filePath,
|
||||
JSON.stringify(ctx.data.data, null, 2),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
return actionOk();
|
||||
try {
|
||||
const snapshot = await saveCmsTranslation(
|
||||
ctx.data.locale,
|
||||
ctx.data.revision,
|
||||
ctx.data.changes,
|
||||
);
|
||||
revalidatePath("/", "layout");
|
||||
return actionOk({ snapshot });
|
||||
} catch (error) {
|
||||
if (!(error instanceof CmsTranslationError)) throw error;
|
||||
const t = await getTranslations("pages.admin.translations.cms");
|
||||
return { ok: false, error: t(error.code, { key: error.key }) };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in new issue
Block a user