Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
Max J. Polster committed Dec 5, 2023
2 parents aa09728 + fa00c48 commit 8ffae4a
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 27 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ export default defineConfig({
// Default is an empty string.
prefix: "example.",

// The locale used in source files.
sourceLocale: "en",
// An array of locales.
// The first one is the locale used in source files.
// Default is `[en]`
locales: ["en", "de"],

// An array of rules to control what is not localized:
// By default, nothing is ignored.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netatwork/aurelia-i18n-tools",
"version": "4.0.2",
"version": "4.0.3",
"description": "A toolchain to help with localization in aurelia projects.",
"type": "module",
"main": "./dist/index.js",
Expand Down
18 changes: 10 additions & 8 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ export interface ConfigOptions {
prefix?: string;

/**
* An id for the locale that is used in source files.
* @default "en"
* An array of locales. The first one is the locale used in source files.
* @default ["en"]
*/
sourceLocale?: string;
locales?: string[];

/**
* A list of ignore rules.
Expand Down Expand Up @@ -116,8 +116,8 @@ export interface Config {
readonly getOutputFilename: (locale: string) => string;
/** A common prefix used for all keys */
readonly prefix: string;
/** An id for the locale that is used in source files. */
readonly sourceLocaleId: string;
/** An array of locales. The first one is the locale used in source files. */
readonly locales: string[];
/** A function that is called to check if an element and it's sub tree should be ignored. */
ignoreElement: (tagName: string) => boolean;
/** A function that is called to check text content should be ignored. */
Expand Down Expand Up @@ -321,8 +321,10 @@ export function createConfig(context: string, options: ConfigOptions = {}): Conf
if (options.prefix !== undefined && typeof options.prefix !== "string") {
throw new TypeError(`prefix must be a string.`);
}
if (options.sourceLocale !== undefined && typeof options.sourceLocale !== "string") {
throw new TypeError(`sourceLocale must be a string.`);

const locales = options.locales ?? ["en"];
if (!Array.isArray(locales) || !locales.every(l => typeof l === "string") || locales.length === 0) {
throw new TypeError(`locales must be an array of at least one string.`);
}

const diagnosticHandlingFallback = options.diagnostics?.all || Config.DiagnosticHandling.Warning;
Expand Down Expand Up @@ -351,7 +353,7 @@ export function createConfig(context: string, options: ConfigOptions = {}): Conf
getOutputFilename: locale => resolve(context, (options.output ?? "./dist/[locale]/translation.json").replace(/\[locale\]/g, locale)),
externalLocales: options.externalLocales ?? {},
prefix: options.prefix || "",
sourceLocaleId: options.sourceLocale || "en",
locales,
ignoreElement: createIgnoreFunction(ignoreElements),
ignoreTextContent: createIgnoreFunction(ignoreTextContent),
ignoreAttributeValue: createIgnoreFunction(ignoreAttributeValue),
Expand Down
10 changes: 7 additions & 3 deletions src/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export namespace Diagnostic {
OutdatedTranslation = "outdated-translation",
MissingTranslation = "missing-translation",
ModifiedSource = "modified-source",
ModifiedTranslation = "modified-translation"
ModifiedTranslation = "modified-translation",
UnknownLocale = "unknown-locale",
}

export type Details<T extends Type> = {
Expand All @@ -46,6 +47,7 @@ export namespace Diagnostic {
[Type.MissingTranslation]: { key: string, localeId: string };
[Type.ModifiedSource]: {};
[Type.ModifiedTranslation]: {};
[Type.UnknownLocale]: { key: string, localeId: string };
}[T];

export const TYPES = new Set<Type>([
Expand All @@ -63,7 +65,8 @@ export namespace Diagnostic {
Type.OutdatedTranslation,
Type.MissingTranslation,
Type.ModifiedSource,
Type.ModifiedTranslation
Type.ModifiedTranslation,
Type.UnknownLocale,
]);
}

Expand Down Expand Up @@ -127,7 +130,8 @@ export class DiagnosticFormatter {
[Diagnostic.Type.OutdatedTranslation]: d => `Translation of ${this.formatName(d.key)} for locale ${this.formatName(d.localeId)} is outdated.`,
[Diagnostic.Type.MissingTranslation]: d => `Translation of ${this.formatName(d.key)} for locale ${this.formatName(d.localeId)} is missing.`,
[Diagnostic.Type.ModifiedSource]: d => `Changes to the source should have been committed.`,
[Diagnostic.Type.ModifiedTranslation]: d => `Changes to translation data should have been committed.`
[Diagnostic.Type.ModifiedTranslation]: d => `Changes to translation data should have been committed.`,
[Diagnostic.Type.UnknownLocale]: d => `Key ${this.formatName(d.key)} has translations for ${this.formatName(d.localeId)}, but this locale is not configured.`,
};

public format<T extends Diagnostic.Type>(diagnostic: Diagnostic<T>) {
Expand Down
1 change: 1 addition & 0 deletions src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export class Project {
this.diagnostics.on("report", diagnostic => {
const handling = this.config.getDiagnosticHandling(diagnostic.type);
if (handling === Config.DiagnosticHandling.Error) {
console.log(this.diagnosticFormatter.format(diagnostic));
process.exitCode = 1;
} else if (handling !== Config.DiagnosticHandling.Ignore) {
console.log(this.diagnosticFormatter.format(diagnostic));
Expand Down
24 changes: 13 additions & 11 deletions src/translation-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,28 @@ export class TranslationData {
* @returns A map of locale ids to compiled locale data.
*/
public compile(config: Config, diagnostics: Diagnostics) {
const locales = new Map<string, LocaleData>();
const locales = new Map<string, LocaleData>(config.locales.map(locale => {
return [locale, LocaleData.createNew()];
}));
for (const [filename, file] of this.files) {
for (const [key, translationSet] of file.content) {
function setKey(localeId: string, content: string) {
let locale = locales.get(localeId);
const locale = locales.get(localeId);
if (!locale) {
locale = LocaleData.createNew();
locales.set(localeId, locale);
}
if (!LocaleData.set(locale, key, content)) {
diagnostics.report({
type: Diagnostic.Type.UnknownLocale,
details: { key, localeId },
filename,
});
} else if (!LocaleData.set(locales.get(localeId)!, key, content)) {
diagnostics.report({
type: Diagnostic.Type.DuplicateKey,
details: { key },
filename
});
}
}
setKey(config.sourceLocaleId, translationSet.source.content);
setKey(config.locales[0], translationSet.source.content);
for (const [localeId, translation] of translationSet.translations) {
if (translation.lastModified >= translationSet.source.lastModified) {
setKey(localeId, translation.content);
Expand All @@ -102,12 +106,10 @@ export class TranslationData {
}
}
}
const additionalLocales = new Set(locales.keys());
additionalLocales.delete(config.sourceLocaleId);
for (const [filename, file] of this.files) {
for (const [key, translationSet] of file.content) {
for (const localeId of additionalLocales) {
if (!translationSet.translations.has(localeId)) {
for (const localeId of config.locales) {
if (localeId !== config.locales[0] && !translationSet.translations.has(localeId)) {
diagnostics.report({
type: Diagnostic.Type.MissingTranslation,
details: { key, localeId },
Expand Down

0 comments on commit 8ffae4a

Please sign in to comment.