Skip to content

Commit

Permalink
Merge pull request #14 from matrix-org/t3chguy/localazy-lint
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy authored Oct 3, 2023
2 parents dac3d30 + 2fecaa6 commit 33abe66
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 3 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"bin": {
"matrix-gen-i18n": "scripts/gen-i18n.js",
"matrix-compare-i18n-files": "scripts/compare-file.js",
"matrix-i18n-rekey": "scripts/rekey.js"
"matrix-i18n-rekey": "scripts/rekey.js",
"matrix-i18n-lint": "scripts/lint.js"
},
"scripts": {
"build:ts": "tsc",
Expand Down
6 changes: 5 additions & 1 deletion scripts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import fs from "fs";
import { isBinaryExpression, isStringLiteral, isTemplateLiteral, Node } from "@babel/types";
import type { Translation, Translations } from "../src";
import type { PluralisedTranslation, Translation, Translations } from "../src";

export const NESTING_KEY = process.env["NESTING_KEY"] || "|";
export const INPUT_FILE = process.env["INPUT_FILE"] || 'src/i18n/strings/en_EN.json';
Expand Down Expand Up @@ -57,3 +57,7 @@ export function getTKey(arg: Node): string | null {
}
return null;
}

export function isPluralisedTranslation(translation: Translations[string]): translation is PluralisedTranslation {
return typeof translation === "object" && "other" in translation;
}
50 changes: 50 additions & 0 deletions scripts/lint-i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
* Applies the following lint rules to the src/i18n/strings/en_EN.json file:
* + ensures the translation key is not equal to its value
* + ensures the translation key contains only alphanumerics and underscores
*
* Usage: node scripts/lint-i18n.js
*/

import { getTranslations, isPluralisedTranslation } from "./common";

const input = getTranslations();

const filtered = Object.keys(input).filter(key => {
const value = input[key];

// Check for invalid characters in the translation key
if (!!key.replace(/[a-z0-9_]+/g, "")) {
console.log(`"${key}": key contains invalid characters`);
return true;
}

// Check that the translated string does not match the key.
if (key === input[key] || (isPluralisedTranslation(value) && (key === value.other || key === value.one))) {
console.log(`"${key}": key matches value`);
return true;
}

return false;
});

if (filtered.length > 0) {
console.log(`${filtered.length} invalid translation keys`);
process.exit(1);
}
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ type Join<K, P, S extends string = "."> = K extends string | number
*/
export type TranslationKey<T extends Translations> = Leaves<T, typeof KEY_SEPARATOR, string | { other: string }, 4>;

export type Translation = string | {
export type PluralisedTranslation = {
one?: string;
other: string;
};

export type Translation = string | PluralisedTranslation;

export interface Translations {
[key: string]: Translation | Translations;
}

0 comments on commit 33abe66

Please sign in to comment.