1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
10 | exports.execute = void 0;
|
11 | const architect_1 = require("@angular-devkit/architect");
|
12 | const build_webpack_1 = require("@angular-devkit/build-webpack");
|
13 | const fs = require("fs");
|
14 | const path = require("path");
|
15 | const webpack = require("webpack");
|
16 | const schema_1 = require("../browser/schema");
|
17 | const i18n_options_1 = require("../utils/i18n-options");
|
18 | const version_1 = require("../utils/version");
|
19 | const webpack_browser_config_1 = require("../utils/webpack-browser-config");
|
20 | const configs_1 = require("../webpack/configs");
|
21 | const stats_1 = require("../webpack/utils/stats");
|
22 | const schema_2 = require("./schema");
|
23 | function getI18nOutfile(format) {
|
24 | switch (format) {
|
25 | case 'xmb':
|
26 | return 'messages.xmb';
|
27 | case 'xlf':
|
28 | case 'xlif':
|
29 | case 'xliff':
|
30 | case 'xlf2':
|
31 | case 'xliff2':
|
32 | return 'messages.xlf';
|
33 | case 'json':
|
34 | case 'legacy-migrate':
|
35 | return 'messages.json';
|
36 | case 'arb':
|
37 | return 'messages.arb';
|
38 | default:
|
39 | throw new Error(`Unsupported format "${format}"`);
|
40 | }
|
41 | }
|
42 | async function getSerializer(format, sourceLocale, basePath, useLegacyIds, diagnostics) {
|
43 | switch (format) {
|
44 | case schema_2.Format.Xmb:
|
45 | const { XmbTranslationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/xmb_translation_serializer'));
|
46 |
|
47 | return new XmbTranslationSerializer(basePath, useLegacyIds);
|
48 | case schema_2.Format.Xlf:
|
49 | case schema_2.Format.Xlif:
|
50 | case schema_2.Format.Xliff:
|
51 | const { Xliff1TranslationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/xliff1_translation_serializer'));
|
52 |
|
53 | return new Xliff1TranslationSerializer(sourceLocale, basePath, useLegacyIds, {});
|
54 | case schema_2.Format.Xlf2:
|
55 | case schema_2.Format.Xliff2:
|
56 | const { Xliff2TranslationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/xliff2_translation_serializer'));
|
57 |
|
58 | return new Xliff2TranslationSerializer(sourceLocale, basePath, useLegacyIds, {});
|
59 | case schema_2.Format.Json:
|
60 | const { SimpleJsonTranslationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/json_translation_serializer'));
|
61 | return new SimpleJsonTranslationSerializer(sourceLocale);
|
62 | case schema_2.Format.LegacyMigrate:
|
63 | const { LegacyMessageIdMigrationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/legacy_message_id_migration_serializer'));
|
64 | return new LegacyMessageIdMigrationSerializer(diagnostics);
|
65 | case schema_2.Format.Arb:
|
66 | const { ArbTranslationSerializer } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/translation_files/arb_translation_serializer'));
|
67 | const fileSystem = {
|
68 | relative(from, to) {
|
69 | return path.relative(from, to);
|
70 | },
|
71 | };
|
72 |
|
73 | return new ArbTranslationSerializer(sourceLocale, basePath, fileSystem);
|
74 | }
|
75 | }
|
76 | function normalizeFormatOption(options) {
|
77 | let format = options.format;
|
78 | switch (format) {
|
79 | case schema_2.Format.Xlf:
|
80 | case schema_2.Format.Xlif:
|
81 | case schema_2.Format.Xliff:
|
82 | format = schema_2.Format.Xlf;
|
83 | break;
|
84 | case schema_2.Format.Xlf2:
|
85 | case schema_2.Format.Xliff2:
|
86 | format = schema_2.Format.Xlf2;
|
87 | break;
|
88 | }
|
89 |
|
90 | return format !== null && format !== void 0 ? format : schema_2.Format.Xlf;
|
91 | }
|
92 | class NoEmitPlugin {
|
93 | apply(compiler) {
|
94 | compiler.hooks.shouldEmit.tap('angular-no-emit', () => false);
|
95 | }
|
96 | }
|
97 |
|
98 |
|
99 |
|
100 | async function execute(options, context, transforms) {
|
101 | var _a;
|
102 |
|
103 | version_1.assertCompatibleAngularVersion(context.workspaceRoot, context.logger);
|
104 | const browserTarget = architect_1.targetFromTargetString(options.browserTarget);
|
105 | const browserOptions = await context.validateOptions(await context.getTargetOptions(browserTarget), await context.getBuilderNameForTarget(browserTarget));
|
106 | const format = normalizeFormatOption(options);
|
107 |
|
108 | let outFile = options.outFile || getI18nOutfile(format);
|
109 | if (options.outputPath) {
|
110 |
|
111 | outFile = path.join(options.outputPath, outFile);
|
112 | }
|
113 | outFile = path.resolve(context.workspaceRoot, outFile);
|
114 | if (!context.target || !context.target.project) {
|
115 | throw new Error('The builder requires a target.');
|
116 | }
|
117 | const metadata = await context.getProjectMetadata(context.target);
|
118 | const i18n = i18n_options_1.createI18nOptions(metadata);
|
119 | let useLegacyIds = true;
|
120 | const ivyMessages = [];
|
121 | const { config, projectRoot } = await webpack_browser_config_1.generateBrowserWebpackConfigFromContext({
|
122 | ...browserOptions,
|
123 | optimization: false,
|
124 | sourceMap: {
|
125 | scripts: true,
|
126 | styles: false,
|
127 | vendor: true,
|
128 | },
|
129 | buildOptimizer: false,
|
130 | aot: true,
|
131 | progress: options.progress,
|
132 | budgets: [],
|
133 | assets: [],
|
134 | scripts: [],
|
135 | styles: [],
|
136 | deleteOutputPath: false,
|
137 | extractLicenses: false,
|
138 | subresourceIntegrity: false,
|
139 | outputHashing: schema_1.OutputHashing.None,
|
140 | namedChunks: true,
|
141 | }, context, (wco) => {
|
142 | var _a;
|
143 | if (wco.tsConfig.options.enableIvy === false) {
|
144 | context.logger.warn('Ivy extraction enabled but application is not Ivy enabled. Extraction may fail.');
|
145 | }
|
146 |
|
147 | useLegacyIds = (_a = wco.tsConfig.options.enableI18nLegacyMessageIdFormat) !== null && _a !== void 0 ? _a : true;
|
148 | const partials = [
|
149 | { plugins: [new NoEmitPlugin()] },
|
150 | configs_1.getCommonConfig(wco),
|
151 | configs_1.getBrowserConfig(wco),
|
152 | configs_1.getTypeScriptConfig(wco),
|
153 | configs_1.getWorkerConfig(wco),
|
154 | configs_1.getStatsConfig(wco),
|
155 | ];
|
156 |
|
157 | partials.unshift({
|
158 | module: {
|
159 | rules: [
|
160 | {
|
161 | test: /\.[t|j]s$/,
|
162 | loader: require.resolve('./ivy-extract-loader'),
|
163 | options: {
|
164 | messageHandler: (messages) => ivyMessages.push(...messages),
|
165 | },
|
166 | },
|
167 | ],
|
168 | },
|
169 | });
|
170 |
|
171 | partials.push({
|
172 | plugins: [
|
173 | new webpack.NormalModuleReplacementPlugin(/\.(css|scss|sass|styl|less)$/, path.join(__dirname, 'empty-export-default.js')),
|
174 | new webpack.NormalModuleReplacementPlugin(/^angular-resource:style,/, path.join(__dirname, 'empty-export-default.js')),
|
175 | ],
|
176 | });
|
177 | return partials;
|
178 | });
|
179 | try {
|
180 | require.resolve('@angular/localize');
|
181 | }
|
182 | catch {
|
183 | return {
|
184 | success: false,
|
185 | error: `Ivy extraction requires the '@angular/localize' package.`,
|
186 | outputPath: outFile,
|
187 | };
|
188 | }
|
189 | const webpackResult = await build_webpack_1.runWebpack((await ((_a = transforms === null || transforms === void 0 ? void 0 : transforms.webpackConfiguration) === null || _a === void 0 ? void 0 : _a.call(transforms, config))) || config, context, {
|
190 | logging: stats_1.createWebpackLoggingCallback(false, context.logger),
|
191 | webpackFactory: webpack,
|
192 | }).toPromise();
|
193 |
|
194 | webpackResult.outputPath = outFile;
|
195 |
|
196 | if (!webpackResult.success) {
|
197 | return webpackResult;
|
198 | }
|
199 | const basePath = config.context || projectRoot;
|
200 | const { checkDuplicateMessages } = await Promise.resolve().then(() => require('@angular/localize/src/tools/src/extract/duplicates'));
|
201 |
|
202 |
|
203 | const checkFileSystem = {
|
204 | relative(from, to) {
|
205 | return path.relative(from, to);
|
206 | },
|
207 | };
|
208 | const diagnostics = checkDuplicateMessages(
|
209 |
|
210 | checkFileSystem, ivyMessages, 'warning',
|
211 |
|
212 | basePath);
|
213 | if (diagnostics.messages.length > 0) {
|
214 | context.logger.warn(diagnostics.formatDiagnostics(''));
|
215 | }
|
216 |
|
217 | const serializer = await getSerializer(format, i18n.sourceLocale, basePath, useLegacyIds, diagnostics);
|
218 | const content = serializer.serialize(ivyMessages);
|
219 |
|
220 | const outputPath = path.dirname(outFile);
|
221 | if (!fs.existsSync(outputPath)) {
|
222 | fs.mkdirSync(outputPath, { recursive: true });
|
223 | }
|
224 |
|
225 | fs.writeFileSync(outFile, content);
|
226 | return webpackResult;
|
227 | }
|
228 | exports.execute = execute;
|
229 | exports.default = architect_1.createBuilder(execute);
|