Skip to content

Commit c3169ae

Browse files
alan-agius4mgechev
authored andcommitted
New i18n schema (#15760)
* feat(@angular-devkit/core): update schema to support new i18n options "projects": { "my-app": { "projectType": "application", "schematics": {}, "root": "", "i18n": { "sourceLocale": "en-US", "locales": { "fr": "src/locale/messages.fr.xlf" } }, "sourceRoot": "src", ... } } * feat(@angular-devkit/build-angular): add new i18n options to browser and server builders With this change we add `translateLocales` as new options for i18n in browser and server builders. We also deprecate the following options; * i18nLocale * i18nFormat * i18nFile * feat(@angular-devkit/build-angular): deprecate `i18nFormat` and `i18nLocale` options of `extract-i18n` builder Option `i18nFormat` has been deprecated in favor of `format` and `i18nLocale` option has been deprecated in favor of the `sourceLocale` sub option of the `i18n` project level option. * feat(@angular/cli): add alias of `i18n-extract` for `x18n` command * refactor: rename `translateLocales` to `localize`
1 parent 2dc8853 commit c3169ae

File tree

13 files changed

+256
-35
lines changed

13 files changed

+256
-35
lines changed

etc/api/angular_devkit/core/src/_golden-api.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,7 @@ export declare class WorkspaceNotYetLoadedException extends BaseException {
12511251
export interface WorkspaceProject {
12521252
architect?: WorkspaceTool;
12531253
cli?: WorkspaceTool;
1254+
i18n?: WorkspaceProjectI18n;
12541255
prefix: string;
12551256
projectType: "application" | "library";
12561257
root: string;
@@ -1259,6 +1260,11 @@ export interface WorkspaceProject {
12591260
targets?: WorkspaceTool;
12601261
}
12611262

1263+
export interface WorkspaceProjectI18n {
1264+
locales: Record<string, string>;
1265+
sourceLocale?: string;
1266+
}
1267+
12621268
export interface WorkspaceSchema {
12631269
$schema?: string;
12641270
architect?: WorkspaceTool;

packages/angular/cli/commands/xi18n.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Extracts i18n messages from source code.",
55
"$longDescription": "",
66

7-
"$aliases": [],
7+
"$aliases": ["i18n-extract"],
88
"$scope": "in",
99
"$type": "architect",
1010
"$impl": "./xi18n-impl#Xi18nCommand",

packages/angular/cli/lib/config/schema.json

+88-13
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@
342342
"type": "string",
343343
"description": "Root of the project files."
344344
},
345+
"i18n": {
346+
"$ref": "#/definitions/project/definitions/i18n"
347+
},
345348
"sourceRoot": {
346349
"type": "string",
347350
"description": "The root of the source files, assets and index.html file structure."
@@ -398,6 +401,28 @@
398401
"^[a-z]{1,3}-.*": {}
399402
},
400403
"definitions": {
404+
"i18n": {
405+
"description": "Project i18n options",
406+
"type": "object",
407+
"properties": {
408+
"sourceLocale": {
409+
"type": "string",
410+
"description": "Specifies the source language of the application.",
411+
"default": "en-US"
412+
},
413+
"locales": {
414+
"type": "object",
415+
"additionalProperties": false,
416+
"patternProperties": {
417+
"^[a-z]{2}(-[a-zA-Z]{2,})?$": {
418+
"type": "string",
419+
"description": "Localization file to use for i18n"
420+
}
421+
}
422+
}
423+
},
424+
"additionalProperties": false
425+
},
401426
"target": {
402427
"oneOf": [
403428
{
@@ -756,21 +781,26 @@
756781
"description": "Log progress to the console while building.",
757782
"default": true
758783
},
784+
"localize": {
785+
"$ref": "#/definitions/buildersOptions/localize"
786+
},
787+
"i18nMissingTranslation": {
788+
"$ref": "#/definitions/buildersOptions/missingTranslation"
789+
},
759790
"i18nFile": {
760791
"type": "string",
761-
"description": "Localization file to use for i18n."
792+
"description": "Localization file to use for i18n.",
793+
"x-deprecated": "Deprecated since 9.0"
762794
},
763795
"i18nFormat": {
764796
"type": "string",
765-
"description": "Format of the localization file specified with --i18n-file."
797+
"description": "Format of the localization file specified with --i18n-file.",
798+
"x-deprecated": "Deprecated since 9.0"
766799
},
767800
"i18nLocale": {
768801
"type": "string",
769-
"description": "Locale to use for i18n."
770-
},
771-
"i18nMissingTranslation": {
772-
"type": "string",
773-
"description": "How to handle missing translations for i18n."
802+
"description": "Locale to use for i18n.",
803+
"x-deprecated": "Deprecated since 9.0"
774804
},
775805
"extractCss": {
776806
"type": "boolean",
@@ -1281,10 +1311,24 @@
12811311
"type": "string",
12821312
"description": "Target to extract from."
12831313
},
1314+
"format": {
1315+
"type": "string",
1316+
"description": "Output format for the generated file.",
1317+
"default": "xlf",
1318+
"enum": [
1319+
"xmb",
1320+
"xlf",
1321+
"xlif",
1322+
"xliff",
1323+
"xlf2",
1324+
"xliff2"
1325+
]
1326+
},
12841327
"i18nFormat": {
12851328
"type": "string",
12861329
"description": "Output format for the generated file.",
12871330
"default": "xlf",
1331+
"x-deprecated": "Use 'format' option instead.",
12881332
"enum": [
12891333
"xmb",
12901334
"xlf",
@@ -1296,7 +1340,8 @@
12961340
},
12971341
"i18nLocale": {
12981342
"type": "string",
1299-
"description": "Specifies the source language of the application."
1343+
"description": "Specifies the source language of the application.",
1344+
"x-deprecated": "Use 'i18n' project level sub-option 'sourceLocale' instead."
13001345
},
13011346
"progress": {
13021347
"type": "boolean",
@@ -1761,21 +1806,26 @@
17611806
"description": "Log progress to the console while building.",
17621807
"default": true
17631808
},
1809+
"localize": {
1810+
"$ref": "#/definitions/buildersOptions/localize"
1811+
},
17641812
"i18nFile": {
17651813
"type": "string",
1766-
"description": "Localization file to use for i18n."
1814+
"description": "Localization file to use for i18n.",
1815+
"x-deprecated": "Deprecated since 9.0"
17671816
},
17681817
"i18nFormat": {
17691818
"type": "string",
1770-
"description": "Format of the localization file specified with --i18n-file."
1819+
"description": "Format of the localization file specified with --i18n-file.",
1820+
"x-deprecated": "Deprecated since 9.0"
17711821
},
17721822
"i18nLocale": {
17731823
"type": "string",
1774-
"description": "Locale to use for i18n."
1824+
"description": "Locale to use for i18n.",
1825+
"x-deprecated": "Deprecated since 9.0"
17751826
},
17761827
"i18nMissingTranslation": {
1777-
"type": "string",
1778-
"description": "How to handle missing translations for i18n."
1828+
"$ref": "#/definitions/buildersOptions/missingTranslation"
17791829
},
17801830
"outputHashing": {
17811831
"type": "string",
@@ -1965,6 +2015,31 @@
19652015
"additionalProperties": false
19662016
}
19672017
}
2018+
},
2019+
"buildersOptions": {
2020+
"missingTranslation": {
2021+
"type": "string",
2022+
"description": "How to handle missing translations for i18n.",
2023+
"enum": ["warning", "error", "ignore"],
2024+
"default": "warning"
2025+
},
2026+
"localize": {
2027+
"oneOf": [
2028+
{
2029+
"type": "boolean",
2030+
"description": "Translate all locales."
2031+
},
2032+
{
2033+
"type": "array",
2034+
"description": "List of locales ID's to translate.",
2035+
"minItems": 1,
2036+
"items": {
2037+
"type": "string",
2038+
"pattern": "^[a-z]{2}(-[a-zA-Z]{2,})?$"
2039+
}
2040+
}
2041+
]
2042+
}
19682043
}
19692044
}
19702045
}

packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
AssetPatternClass,
1616
Budget,
1717
ExtraEntryPoint,
18+
I18NMissingTranslation,
19+
Localize,
1820
OptimizationClass,
1921
SourceMapClass,
2022
} from '../../browser/schema';
@@ -27,26 +29,29 @@ export interface BuildOptions {
2729
resourcesOutputPath?: string;
2830
aot?: boolean;
2931
sourceMap: SourceMapClass;
30-
/** @deprecated use sourceMap instead */
32+
/** @deprecated since version 8. use sourceMap instead. */
3133
vendorSourceMap?: boolean;
32-
/** @deprecated */
34+
/** @deprecated since version 8 */
3335
evalSourceMap?: boolean;
3436
vendorChunk?: boolean;
3537
commonChunk?: boolean;
3638
baseHref?: string;
3739
deployUrl?: string;
3840
verbose?: boolean;
3941
progress?: boolean;
42+
/** @deprecated since version 9. Use 'locales' object in the project metadata instead.*/
4043
i18nFile?: string;
44+
/** @deprecated since version 9. No longer needed as the format will be determined automatically.*/
4145
i18nFormat?: string;
46+
/** @deprecated since version 9. Use 'localize' instead.*/
4247
i18nLocale?: string;
43-
i18nMissingTranslation?: string;
48+
localize?: Localize;
49+
i18nMissingTranslation?: I18NMissingTranslation;
4450
extractCss?: boolean;
4551
bundleDependencies?: 'none' | 'all';
4652
watch?: boolean;
4753
outputHashing?: string;
4854
poll?: number;
49-
app?: string;
5055
deleteOutputPath?: boolean;
5156
preserveSymlinks?: boolean;
5257
extractLicenses?: boolean;
@@ -56,10 +61,12 @@ export interface BuildOptions {
5661
subresourceIntegrity?: boolean;
5762
serviceWorker?: boolean;
5863
webWorkerTsConfig?: string;
64+
/** @deprecated since version 8 **/
5965
skipAppShell?: boolean;
6066
statsJson: boolean;
6167
forkTypeChecker: boolean;
6268
profile?: boolean;
69+
/** @deprecated since version 8 **/
6370
es5BrowserSupport?: boolean;
6471

6572
main: string;

packages/angular_devkit/build_angular/src/browser/schema.json

+26-4
Original file line numberDiff line numberDiff line change
@@ -180,19 +180,41 @@
180180
},
181181
"i18nFile": {
182182
"type": "string",
183-
"description": "Localization file to use for i18n."
183+
"description": "Localization file to use for i18n.",
184+
"x-deprecated": "Use 'locales' object in the project metadata instead."
184185
},
185186
"i18nFormat": {
186187
"type": "string",
187-
"description": "Format of the localization file specified with --i18n-file."
188+
"description": "Format of the localization file specified with --i18n-file.",
189+
"x-deprecated": "No longer needed as the format will be determined automatically."
188190
},
189191
"i18nLocale": {
190192
"type": "string",
191-
"description": "Locale to use for i18n."
193+
"description": "Locale to use for i18n.",
194+
"x-deprecated": "Use 'localize' instead."
192195
},
193196
"i18nMissingTranslation": {
194197
"type": "string",
195-
"description": "How to handle missing translations for i18n."
198+
"description": "How to handle missing translations for i18n.",
199+
"enum": ["warning", "error", "ignore"],
200+
"default": "warning"
201+
},
202+
"localize": {
203+
"oneOf": [
204+
{
205+
"type": "boolean",
206+
"description": "Translate all locales."
207+
},
208+
{
209+
"type": "array",
210+
"description": "List of locales ID's to translate.",
211+
"minItems": 1,
212+
"items": {
213+
"type": "string",
214+
"pattern": "^[a-z]{2}(-[a-zA-Z]{2,})?$"
215+
}
216+
}
217+
]
196218
},
197219
"extractCss": {
198220
"type": "boolean",

packages/angular_devkit/build_angular/src/extract-i18n/index.ts

+18-4
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ import {
2222
} from '../angular-cli-files/models/webpack-configs';
2323
import { statsErrorsToString, statsWarningsToString } from '../angular-cli-files/utilities/stats';
2424
import { Schema as BrowserBuilderOptions } from '../browser/schema';
25+
import { createI18nOptions } from '../utils/i18n-options';
2526
import { assertCompatibleAngularVersion } from '../utils/version';
2627
import { generateBrowserWebpackConfigFromContext } from '../utils/webpack-browser-config';
27-
import { Schema as ExtractI18nBuilderOptions } from './schema';
28+
import { Format, Schema as ExtractI18nBuilderOptions } from './schema';
2829

2930
function getI18nOutfile(format: string | undefined) {
3031
switch (format) {
@@ -58,13 +59,26 @@ async function execute(options: ExtractI18nBuilderOptions, context: BuilderConte
5859
await context.getBuilderNameForTarget(browserTarget),
5960
);
6061

62+
if (options.i18nFormat !== Format.Xlf) {
63+
options.format = options.i18nFormat;
64+
}
65+
6166
// We need to determine the outFile name so that AngularCompiler can retrieve it.
62-
let outFile = options.outFile || getI18nOutfile(options.i18nFormat);
67+
let outFile = options.outFile || getI18nOutfile(options.format);
6368
if (options.outputPath) {
6469
// AngularCompilerPlugin doesn't support genDir so we have to adjust outFile instead.
6570
outFile = path.join(options.outputPath, outFile);
6671
}
6772

73+
const projectName = context.target && context.target.project;
74+
if (!projectName) {
75+
throw new Error('The builder requires a target.');
76+
}
77+
// target is verified in the above call
78+
// tslint:disable-next-line: no-non-null-assertion
79+
const metadata = await context.getProjectMetadata(context.target!);
80+
const i18n = createI18nOptions(metadata);
81+
6882
const { config } = await generateBrowserWebpackConfigFromContext(
6983
{
7084
...browserOptions,
@@ -73,8 +87,8 @@ async function execute(options: ExtractI18nBuilderOptions, context: BuilderConte
7387
styles: false,
7488
},
7589
buildOptimizer: false,
76-
i18nLocale: options.i18nLocale,
77-
i18nFormat: options.i18nFormat,
90+
i18nLocale: options.i18nLocale || i18n.sourceLocale,
91+
i18nFormat: options.format,
7892
i18nFile: outFile,
7993
aot: true,
8094
progress: options.progress,

packages/angular_devkit/build_angular/src/extract-i18n/schema.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,24 @@
88
"type": "string",
99
"description": "Target to extract from."
1010
},
11+
"format": {
12+
"type": "string",
13+
"description": "Output format for the generated file.",
14+
"default": "xlf",
15+
"enum": [
16+
"xmb",
17+
"xlf",
18+
"xlif",
19+
"xliff",
20+
"xlf2",
21+
"xliff2"
22+
]
23+
},
1124
"i18nFormat": {
1225
"type": "string",
1326
"description": "Output format for the generated file.",
1427
"default": "xlf",
28+
"x-deprecated": "Use 'format' option instead.",
1529
"enum": [
1630
"xmb",
1731
"xlf",
@@ -23,7 +37,8 @@
2337
},
2438
"i18nLocale": {
2539
"type": "string",
26-
"description": "Specifies the source language of the application."
40+
"description": "Specifies the source language of the application.",
41+
"x-deprecated": "Use 'i18n' project level sub-option 'sourceLocale' instead."
2742
},
2843
"progress": {
2944
"type": "boolean",

0 commit comments

Comments
 (0)