forked from angular/angular
/
translator.ts
87 lines (80 loc) · 3.63 KB
/
translator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AbsoluteFsPath, FileSystem, PathSegment} from '@angular/compiler-cli/src/ngtsc/file_system';
import {ɵMessageId, ɵParsedTranslation} from '@angular/localize';
import {Diagnostics} from '../diagnostics';
import {OutputPathFn} from './output_path';
/**
* An object that holds information to be used to translate files.
*/
export interface TranslationBundle {
locale: string;
translations: Record<ɵMessageId, ɵParsedTranslation>;
diagnostics?: Diagnostics;
}
/**
* Implement this interface to provide a class that can handle translation for the given resource in
* an appropriate manner.
*
* For example, source code files will need to be transformed if they contain `$localize` tagged
* template strings, while most static assets will just need to be copied.
*/
export interface TranslationHandler {
/**
* Returns true if the given file can be translated by this handler.
*
* @param relativeFilePath A relative path from the sourceRoot to the resource file to handle.
* @param contents The contents of the file to handle.
*/
canTranslate(relativeFilePath: PathSegment|AbsoluteFsPath, contents: Uint8Array): boolean;
/**
* Translate the file at `relativeFilePath` containing `contents`, using the given `translations`,
* and write the translated content to the path computed by calling `outputPathFn()`.
*
* @param diagnostics An object for collecting translation diagnostic messages.
* @param sourceRoot An absolute path to the root of the files being translated.
* @param relativeFilePath A relative path from the sourceRoot to the file to translate.
* @param contents The contents of the file to translate.
* @param outputPathFn A function that returns an absolute path where the output file should be
* written.
* @param translations A collection of translations to apply to this file.
* @param sourceLocale The locale of the original application source. If provided then an
* additional copy of the application is created under this locale just with the `$localize` calls
* stripped out.
*/
translate(
diagnostics: Diagnostics, sourceRoot: AbsoluteFsPath,
relativeFilePath: PathSegment|AbsoluteFsPath, contents: Uint8Array,
outputPathFn: OutputPathFn, translations: TranslationBundle[], sourceLocale?: string): void;
}
/**
* Translate each file (e.g. source file or static asset) using the given `TranslationHandler`s.
* The file will be translated by the first handler that returns true for `canTranslate()`.
*/
export class Translator {
constructor(
private fs: FileSystem, private resourceHandlers: TranslationHandler[],
private diagnostics: Diagnostics) {}
translateFiles(
inputPaths: PathSegment[], rootPath: AbsoluteFsPath, outputPathFn: OutputPathFn,
translations: TranslationBundle[], sourceLocale?: string): void {
inputPaths.forEach(inputPath => {
const absInputPath = this.fs.resolve(rootPath, inputPath);
const contents = this.fs.readFileBuffer(absInputPath);
const relativePath = this.fs.relative(rootPath, absInputPath);
for (const resourceHandler of this.resourceHandlers) {
if (resourceHandler.canTranslate(relativePath, contents)) {
return resourceHandler.translate(
this.diagnostics, rootPath, relativePath, contents, outputPathFn, translations,
sourceLocale);
}
}
this.diagnostics.error(`Unable to handle resource file: ${inputPath}`);
});
}
}