Files
Curse/packages/i18n/scripts/verify.ts
おさむのひと fe01a5a28f refactor: localesをworkspace管理下のパッケージに (#16895)
* refactor: localesをworkspace管理下のパッケージに

* fix copilot review

* move

* move

* rename

* fix ci

* revert unwanted indent changes

* fix

* fix

* fix

* fix

* 間違えてコミットしていたのを戻す

* 不要

* 追加漏れ

* ymlの場所だけ戻す

* localesの位置を戻したのでこの差分は不要

* 内容的にlocalesにある方が正しい

* i18nパッケージ用のREADME.mdを用意

* fix locale.yml

* fix locale.yml

---------

Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-11-30 13:27:44 +09:00

71 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
let valid = true;
interface LocaleRecord {
[key: string]: string | LocaleRecord;
}
interface ErrorData {
expected?: string;
actual?: string;
parameter?: string;
}
function writeError(type: string, lang: string, tree: string, data: ErrorData): void {
process.stderr.write(JSON.stringify({ type, lang, tree, data }));
process.stderr.write('\n');
valid = false;
}
function verify(expected: LocaleRecord, actual: LocaleRecord, lang: string, trace?: string): void {
for (const key in expected) {
if (!Object.prototype.hasOwnProperty.call(actual, key)) {
continue;
}
if (typeof expected[key] === 'object') {
if (typeof actual[key] !== 'object') {
writeError('mismatched_type', lang, trace ? `${trace}.${key}` : key, { expected: 'object', actual: typeof actual[key] });
continue;
}
verify(expected[key] as LocaleRecord, actual[key] as LocaleRecord, lang, trace ? `${trace}.${key}` : key);
} else if (typeof expected[key] === 'string') {
switch (typeof actual[key]) {
case 'object':
writeError('mismatched_type', lang, trace ? `${trace}.${key}` : key, { expected: 'string', actual: 'object' });
break;
case 'undefined':
continue;
case 'string': {
const expectedParameters = new Set((expected[key] as string).match(/\{[^}]+\}/g)?.map((s) => s.slice(1, -1)));
const actualParameters = new Set((actual[key] as string).match(/\{[^}]+\}/g)?.map((s) => s.slice(1, -1)));
for (const parameter of expectedParameters) {
if (!actualParameters.has(parameter)) {
writeError('missing_parameter', lang, trace ? `${trace}.${key}` : key, { parameter });
}
}
}
}
}
}
}
// index.tsはtsのまま動かすことを想定していないビルド成果物を外部に公開する.
// よってビルド後のものを検証する
const locales = await import('../built/index.js');
const { 'ja-JP': original, ...verifiees } = locales as unknown as Record<string, LocaleRecord>;
for (const lang in verifiees) {
if (!Object.prototype.hasOwnProperty.call(locales, lang)) {
continue;
}
verify(original, verifiees[lang], lang);
}
if (!valid) {
process.exit(1);
}